openMSX
RomInfo.cc
Go to the documentation of this file.
2#include "RomInfo.hh"
3#include "StringOp.hh"
4#include "ranges.hh"
5#include "stl.hh"
6#include "unreachable.hh"
7#include "view.hh"
8#include <array>
9#include <cassert>
10
11namespace openmsx {
12
13using enum RomType;
14
15static constexpr auto romTypeInfoArray = [] {
17
18 // Generic ROM types that don't exist in real ROMs
19 // (should not occur in any database!)
20 r[GENERIC_8KB] = {0x2000, "8kB", "Generic 8kB"};
21 r[GENERIC_16KB] = {0x4000, "16kB", "Generic 16kB"};
22
23 // ROM mapper types for normal software (mainly games)
24 r[KONAMI] = {0x2000, "Konami", "Konami MegaROM"};
25 r[KONAMI_SCC] = {0x2000, "KonamiSCC", "Konami with SCC"};
26 r[KBDMASTER] = {0x4000, "KeyboardMaster", "Konami Keyboard Master with VLM5030"}; // officially plain 16K
27 r[ASCII8] = {0x2000, "ASCII8", "ASCII 8kB"};
28 r[ASCII16] = {0x4000, "ASCII16", "ASCII 16kB"};
29 r[ASCII16X] = {0x4000, "ASCII16-X", "ASCII-X 16kB"};
30 r[R_TYPE] = {0x4000, "R-Type", "R-Type"};
31 r[CROSS_BLAIM] = {0x4000, "CrossBlaim", "Cross Blaim"};
32 r[HARRY_FOX] = {0x4000, "HarryFox", "Harry Fox"};
33 r[HALNOTE] = {0x2000, "Halnote", "Halnote"};
34 r[ZEMINA25IN1] = {0x2000, "Zemina25in1", "Zemina 25 in 1"};
35 r[ZEMINA80IN1] = {0x2000, "Zemina80in1", "Zemina 80 in 1"};
36 r[ZEMINA90IN1] = {0x2000, "Zemina90in1", "Zemina 90 in 1"};
37 r[ZEMINA126IN1] = {0x2000, "Zemina126in1", "Zemina 126 in 1"};
38 r[ASCII16_2] = {0x4000, "ASCII16SRAM2", "ASCII 16kB with 2kB SRAM"};
39 r[ASCII16_8] = {0x4000, "ASCII16SRAM8", "ASCII 16kB with 8kB SRAM"};
40 r[ASCII8_8] = {0x2000, "ASCII8SRAM8", "ASCII 8kB with 8kB SRAM"};
41 r[ASCII8_32] = {0x2000, "ASCII8SRAM32", "ASCII 8kB with 32kB SRAM"};
42 r[ASCII8_2] = {0x2000, "ASCII8SRAM2", "ASCII 8kB with 2kB SRAM"};
43 r[KOEI_8] = {0x2000, "KoeiSRAM8", "Koei with 8kB SRAM"};
44 r[KOEI_32] = {0x2000, "KoeiSRAM32", "Koei with 32kB SRAM"};
45 r[WIZARDRY] = {0x2000, "Wizardry", "Wizardry"};
46 r[GAME_MASTER2] = {0x1000, "GameMaster2", "Konami's Game Master 2"};
47 r[MAJUTSUSHI] = {0x2000, "Majutsushi", "Hai no Majutsushi"};
48 r[SYNTHESIZER] = {0 , "Synthesizer", "Konami's Synthesizer"}; // plain 32K
49 r[PLAYBALL] = {0 , "PlayBall", "Sony's PlayBall"}; // plain 32K
50 r[NETTOU_YAKYUU] = {0x2000, "NettouYakyuu", "Nettou Yakuu"};
51 r[HOLY_QURAN] = {0x2000, "AlQuranDecoded", "Holy Qu'ran (pre-decrypted)"};
52 r[HOLY_QURAN2] = {0x2000, "AlQuran", "Holy Qu'ran"};
53 r[PADIAL8] = {0x2000, "Padial8", "Padial 8kB"};
54 r[PADIAL16] = {0x4000, "Padial16", "Padial 16kB"};
55 r[SUPERLODERUNNER] = {0x4000, "SuperLodeRunner", "Super Lode Runner"};
56 r[SUPERSWANGI] = {0x4000, "SuperSwangi", "Super Swangi"};
57 r[MSXDOS2] = {0x4000, "MSXDOS2", "MSX-DOS2"};
58 r[MITSUBISHIMLTS2] = {0x2000, "MitsubishiMLTS2", "Mitsubishi ML-TS2 firmware"};
59 r[MANBOW2] = {0x2000, "Manbow2", "Manbow2"};
60 r[MANBOW2_2] = {0x2000, "Manbow2_2", "Manbow2 - Second Release"};
61 r[RBSC_FLASH_KONAMI_SCC]={0x2000,"RBSC_Flash_KonamiSCC","RBSC 2MB flash, Konami SCC mapper"};
62 r[HAMARAJANIGHT] = {0x2000, "HamarajaNight", "Best of Hamaraja Night"};
63 r[MEGAFLASHROMSCC] = {0x2000, "MegaFlashRomScc", "Mega Flash ROM SCC"};
64 r[MATRAINK] = {0 , "MatraInk", "Matra Ink"};
65 r[MATRACOMPILATION]= {0x2000, "MatraCompilation","Matra Compilation"};
66 r[ARC] = {0 , "Arc", "Parallax' ARC"}; // plain 32K
67 r[ROMHUNTERMK2] = {0x2000, "ROMHunterMk2", "ROM Hunter Mk2"}; // variable block size, 8kB smallest
68 r[DOOLY] = {0x4000, "Dooly", "Baby Dinosaur Dooly"}; // officially 32K blocksize, but spread over 2 pages
69 r[MSXTRA] = {0 , "MSXtra", "PTC MSXtra"};
70 r[MSXWRITE] = {0x4000, "MSXWrite", "Japanese MSX Write"};
71 r[MULTIROM] = {0x4000, "MultiRom", "MultiRom Collection"};
72 r[RAMFILE] = {0 , "RAMFILE", "Tecall MSX RAMFILE"};
73 r[RETROHARD31IN1] = {0x2000, "RetroHardMultiCart31in1", "RetroHard MultiCart 31 in 1"};
74 r[ALALAMIAH30IN1] = {0x8000, "AlAlamiah30-in-1", "Al Alamiah 30-in-1"};
75 r[COLECOMEGACART] = {0x4000, "ColecoMegaCart", "ColecoVision MegaCart"};
76 r[MEGAFLASHROMSCCPLUS]={0 ,"MegaFlashRomSccPlus","Mega Flash ROM SCC Plus"}; // variable block size
77 r[REPRO_CARTRIDGE1]= {0x2000, "ReproCartridgeV1","Repro Cartridge V1"};
78 r[REPRO_CARTRIDGE2]= {0x2000, "ReproCartridgeV2","Repro Cartridge V2"};
79 r[KONAMI_ULTIMATE_COLLECTION]={0x2000,"KonamiUltimateCollection","Konami Ultimate Collection"};
80 r[NEO8] = {0x2000, "NEO-8", "NEO-8 mapper"};
81 r[NEO16] = {0x4000, "NEO-16", "NEO-16 mapper"};
82
83 // ROM mapper types used for system ROMs in machines
84 r[PANASONIC] = {0x2000, "Panasonic", "Panasonic internal mapper"};
85 r[NATIONAL] = {0x4000, "National", "National internal mapper"};
86 r[FSA1FM1] = {0 , "FSA1FM1", "Panasonic FS-A1FM internal mapper 1"}; // TODO: romblocks debuggable?
87 r[FSA1FM2] = {0x2000, "FSA1FM2", "Panasonic FS-A1FM internal mapper 2"};
88 r[DRAM] = {0x2000, "DRAM", "MSXturboR DRAM"};
89
90 // Non-mapper ROM types
91 r[MIRRORED] = {0, "Mirrored", "Plain rom, mirrored (any size)"};
92 r[MIRRORED0000] = {0, "Mirrored0000", "Plain rom, mirrored start at 0x0000"};
93 r[MIRRORED4000] = {0, "Mirrored4000", "Plain rom, mirrored start at 0x4000"};
94 r[MIRRORED8000] = {0, "Mirrored8000", "Plain rom, mirrored start at 0x8000"};
95 r[MIRROREDC000] = {0, "MirroredC000", "Plain rom, mirrored start at 0xC000"};
96 r[NORMAL] = {0, "Normal", "Plain rom (any size)"};
97 r[NORMAL0000] = {0, "Normal0000", "Plain rom start at 0x0000"};
98 r[NORMAL4000] = {0, "Normal4000", "Plain rom start at 0x4000"};
99 r[NORMAL8000] = {0, "Normal8000", "Plain rom start at 0x8000"};
100 r[NORMALC000] = {0, "NormalC000", "Plain rom start at 0xC000"};
101 r[PAGE0] = {0, "Page0", "Plain 16kB page 0"};
102 r[PAGE1] = {0, "Page1", "Plain 16kB page 1"};
103 r[PAGE2] = {0, "Page2", "Plain 16kB page 2 (BASIC)"};
104 r[PAGE3] = {0, "Page3", "Plain 16kB page 3"};
105 r[PAGE01] = {0, "Page01", "Plain 32kB page 0-1"};
106 r[PAGE12] = {0, "Page12", "Plain 32kB page 1-2"};
107 r[PAGE23] = {0, "Page23", "Plain 32kB page 2-3"};
108 r[PAGE012] = {0, "Page012", "Plain 48kB page 0-2"};
109 r[PAGE123] = {0, "Page123", "Plain 48kB page 1-3"};
110 r[PAGE0123] = {0, "Page0123", "Plain 64kB"};
111 return r;
112}();
117
120 std::string_view name;
121};
122static constexpr std::array aliasTable = {
124 RomTypeAndName{GENERIC_8KB, "GenericKonami"}, // probably actually used in a Zemina Box
125 RomTypeAndName{GENERIC_16KB,"1"},
126 RomTypeAndName{KONAMI_SCC, "2"},
127 RomTypeAndName{KONAMI_SCC, "SCC"},
128 RomTypeAndName{KONAMI_SCC, "KONAMI5"},
129 RomTypeAndName{KONAMI, "KONAMI4"},
130 RomTypeAndName{KONAMI, "3"},
131 RomTypeAndName{ASCII8, "4"},
132 RomTypeAndName{ASCII16, "5"},
133 RomTypeAndName{MIRRORED, "64kB"},
134 RomTypeAndName{MIRRORED, "Plain"},
135 RomTypeAndName{NORMAL0000, "0x0000"},
136 RomTypeAndName{NORMAL4000, "0x4000"},
137 RomTypeAndName{NORMAL8000, "0x8000"},
138 RomTypeAndName{NORMALC000, "0xC000"},
139 RomTypeAndName{ASCII16_2, "HYDLIDE2"},
140 RomTypeAndName{GAME_MASTER2,"RC755"},
141 RomTypeAndName{NORMAL8000, "ROMBAS"},
142 RomTypeAndName{R_TYPE, "RTYPE"},
143 RomTypeAndName{ZEMINA80IN1, "KOREAN80IN1"},
144 RomTypeAndName{ZEMINA90IN1, "KOREAN90IN1"},
145 RomTypeAndName{ZEMINA126IN1,"KOREAN126IN1"},
146 RomTypeAndName{HOLY_QURAN, "HolyQuran"},
147};
148
149static constexpr auto combinedRomTable = [] {
150 constexpr auto N = std::size(romTypeInfoArray) + std::size(aliasTable);
151 std::array<RomTypeAndName, N> result = {};
152 size_t i = 0;
153 for (const auto& e : romTypeInfoArray) {
154 result[i].romType = static_cast<RomType>(i);
155 result[i].name = e.name;
156 ++i;
157 }
158 for (const auto& e : aliasTable) {
159 result[i++] = e;
160 }
161 return result;
162}();
163
165 [[nodiscard]] constexpr uint32_t operator()(std::string_view str) const {
166 constexpr auto MASK = uint8_t(~('a' - 'A')); // case insensitive
167 uint32_t d = 0;
168 for (char c : str) {
169 d = (d ^ (c & MASK)) * 0x01000193;
170 }
171 return d;
172 }
173};
174
175// Construct perfect hash function to lookup RomType by name.
176static constexpr auto pmh = [] {
177 auto getKey = [](size_t i) { return combinedRomTable[i].name; };
178 return PerfectMinimalHash::create<std::size(combinedRomTable)>(RomTypeNameHash{}, getKey);
179}();
180
181RomType RomInfo::nameToRomType(std::string_view name)
182{
183 auto idx = pmh.lookupIndex(name);
184 assert(idx < std::size(combinedRomTable));
185 if (StringOp::casecmp cmp; cmp(combinedRomTable[idx].name, name)) {
186 return combinedRomTable[idx].romType;
187 }
188 return RomType::UNKNOWN;
189}
190
192{
193 return romTypeInfoArray[type].name;
194}
195
196std::string_view RomInfo::getDescription(RomType type)
197{
198 return romTypeInfoArray[type].description;
199}
200
202{
203 return romTypeInfoArray[type].blockSize;
204}
205
206} // namespace openmsx
static const array_with_enum_index< RomType, RomInfo::RomTypeInfo > & getRomTypeInfo()
Definition RomInfo.cc:113
static unsigned getBlockSize(RomType type)
Definition RomInfo.cc:201
static std::string_view getDescription(RomType type)
Definition RomInfo.cc:196
static zstring_view romTypeToName(RomType type)
Definition RomInfo.cc:191
static RomType nameToRomType(std::string_view name)
Definition RomInfo.cc:181
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr double e
Definition Math.hh:21
This file implemented 3 utility functions:
Definition Autofire.cc:11
std::string_view name
Definition RomInfo.cc:120
constexpr uint32_t operator()(std::string_view str) const
Definition RomInfo.cc:165