openMSX
RomInfo.cc
Go to the documentation of this file.
1 #include "RomInfo.hh"
2 #include "StringOp.hh"
3 #include "hash_map.hh"
4 #include "stl.hh"
5 #include "unreachable.hh"
6 #include "xxhash.hh"
7 #include <algorithm>
8 #include <cassert>
9 
10 using std::vector;
11 using std::string;
12 
13 namespace openmsx {
14 
15 static inline RomType makeAlias(RomType type)
16 {
17  return static_cast<RomType>(ROM_ALIAS | type);
18 }
19 static inline RomType removeAlias(RomType type)
20 {
21  return static_cast<RomType>(type & ~ROM_ALIAS);
22 }
23 static inline bool isAlias(RomType type)
24 {
25  return (type & ROM_ALIAS) != 0;
26 }
27 
28 
29 static bool isInit = false;
30 
31 // This maps a name to a RomType. There can be multiple names (aliases) for the
32 // same type.
34 static RomTypeMap romTypeMap(256); // initial hashtable size
35  // (big enough so that no rehash is needed)
36 
37 // This contains extra information for each RomType. This structure only
38 // contains the primary (non-alias) romtypes.
39 using RomTypeInfo = std::tuple<
40  RomType, // rom type
41  string_ref, // description
42  unsigned>; // blockSize
43 using RomTypeInfoMap = vector<RomTypeInfo>;
45 static RomTypeInfoMap romTypeInfoMap;
46 
47 static void init(RomType type, string_ref name,
48  unsigned blockSize, string_ref description)
49 {
50  romTypeMap.emplace_noCapacityCheck_noDuplicateCheck(name, type);
51  romTypeInfoMap.emplace_back(type, description, blockSize);
52 }
53 static void initAlias(RomType type, string_ref name)
54 {
55  romTypeMap.emplace_noCapacityCheck_noDuplicateCheck(name, makeAlias(type));
56 }
57 static void init()
58 {
59  if (isInit) return;
60  isInit = true;
61 
62  // Generic ROM types that don't exist in real ROMs
63  // (should not occur in any database!)
64  init(ROM_GENERIC_8KB, "8kB", 0x2000, "Generic 8kB");
65  init(ROM_GENERIC_16KB, "16kB", 0x4000, "Generic 16kB");
66 
67  // ROM mapper types for normal software (mainly games)
68  init(ROM_KONAMI, "Konami", 0x2000, "Konami MegaROM");
69  init(ROM_KONAMI_SCC, "KonamiSCC", 0x2000, "Konami with SCC");
70  init(ROM_KBDMASTER, "KeyboardMaster", 0x4000, "Konami Keyboard Master with VLM5030"); // officially plain 16K
71  init(ROM_ASCII8, "ASCII8", 0x2000, "ASCII 8kB");
72  init(ROM_ASCII16, "ASCII16", 0x4000, "ASCII 16kB");
73  init(ROM_R_TYPE, "R-Type", 0x4000, "R-Type");
74  init(ROM_CROSS_BLAIM, "CrossBlaim", 0x4000, "Cross Blaim");
75  init(ROM_HARRY_FOX, "HarryFox", 0x4000, "Harry Fox");
76  init(ROM_HALNOTE, "Halnote", 0x2000, "Halnote");
77  init(ROM_ZEMINA80IN1, "Zemina80in1", 0x2000, "Zemina 80 in 1");
78  init(ROM_ZEMINA90IN1, "Zemina90in1", 0x2000, "Zemina 90 in 1");
79  init(ROM_ZEMINA126IN1, "Zemina126in1", 0x2000, "Zemina 126 in 1");
80  init(ROM_ASCII16_2, "ASCII16SRAM2", 0x4000, "ASCII 16kB with 2kB SRAM");
81  init(ROM_ASCII16_8, "ASCII16SRAM8", 0x4000, "ASCII 16kB with 8kB SRAM");
82  init(ROM_ASCII8_8, "ASCII8SRAM8", 0x2000, "ASCII 8kB with 8kB SRAM");
83  init(ROM_ASCII8_32, "ASCII8SRAM32", 0x2000, "ASCII 8kB with 32kB SRAM");
84  init(ROM_ASCII8_2, "ASCII8SRAM2", 0x2000, "ASCII 8kB with 2kB SRAM");
85  init(ROM_KOEI_8, "KoeiSRAM8", 0x2000, "Koei with 8kB SRAM");
86  init(ROM_KOEI_32, "KoeiSRAM32", 0x2000, "Koei with 32kB SRAM");
87  init(ROM_WIZARDRY, "Wizardry", 0x2000, "Wizardry");
88  init(ROM_GAME_MASTER2, "GameMaster2", 0x1000, "Konami's Game Master 2");
89  init(ROM_MAJUTSUSHI, "Majutsushi", 0x2000, "Hai no Majutsushi");
90  init(ROM_SYNTHESIZER, "Synthesizer", 0x4000, "Konami's Synthesizer"); // officially plain 32K
91  init(ROM_PLAYBALL, "PlayBall", 0x4000, "Sony's PlayBall"); // officially plain 32K
92  init(ROM_NETTOU_YAKYUU, "NettouYakyuu", 0x2000, "Nettou Yakuu");
93  init(ROM_HOLY_QURAN, "AlQuranDecoded", 0x2000, "Holy Qu'ran (pre-decrypted)");
94  init(ROM_HOLY_QURAN2, "AlQuran", 0x2000, "Holy Qu'ran");
95  init(ROM_PADIAL8, "Padial8", 0x2000, "Padial 8kB");
96  init(ROM_PADIAL16, "Padial16", 0x4000, "Padial 16kB");
97  init(ROM_SUPERLODERUNNER,"SuperLodeRunner",0x4000, "Super Lode Runner");
98  init(ROM_SUPERSWANGI, "SuperSwangi" ,0x4000, "Super Swangi");
99  init(ROM_MSXDOS2, "MSXDOS2", 0x4000, "MSX-DOS2");
100  init(ROM_MITSUBISHIMLTS2,"MitsubishiMLTS2",0x2000, "Mitsubishi ML-TS2 firmware");
101  init(ROM_MANBOW2, "Manbow2", 0x2000, "Manbow2");
102  init(ROM_MANBOW2_2, "Manbow2_2", 0x2000, "Manbow2 - Second Release");
103  init(ROM_HAMARAJANIGHT, "HamarajaNight", 0x2000, "Best of Hamaraja Night");
104  init(ROM_MEGAFLASHROMSCC,"MegaFlashRomScc",0x2000, "Mega Flash ROM SCC");
105  init(ROM_MATRAINK, "MatraInk", 0x0000, "Matra Ink");
106  init(ROM_ARC, "Arc", 0x4000, "Parallax' ARC"); // officially plain 32K
107  init(ROM_DOOLY, "Dooly", 0x4000, "Baby Dinosaur Dooly"); // officially 32K blocksize, but spread over 2 pages
108  init(ROM_MSXTRA, "MSXtra", 0x0000, "PTC MSXtra");
109  init(ROM_MSXWRITE, "MSXWrite", 0x4000, "Japanese MSX Write");
110  init(ROM_MULTIROM, "MultiRom", 0x0000, "MultiRom Collection");
111  init(ROM_MEGAFLASHROMSCCPLUS,"MegaFlashRomSccPlus",0x0000, "Mega Flash ROM SCC Plus");
112  init(ROM_MEGAFLASHROMSCCPLUSSD,"MegaFlashRomSccPlusSD",0x0000, "Mega Flash ROM SCC Plus SD"); // ****
113  init(ROM_KONAMI_ULTIMATE_COLLECTION,"KonamiUltimateCollection",0x0000, "Konami Ultimate Collection");
114 
115  // ROM mapper types used for system ROMs in machines
116  init(ROM_PANASONIC, "Panasonic", 0x2000, "Panasonic internal mapper");
117  init(ROM_NATIONAL, "National", 0x4000, "National internal mapper");
118  init(ROM_FSA1FM1, "FSA1FM1", 0x0000, "Panasonic FS-A1FM internal mapper 1"); // TODO: romblocks debuggable?
119  init(ROM_FSA1FM2, "FSA1FM2", 0x2000, "Panasonic FS-A1FM internal mapper 2");
120  init(ROM_DRAM, "DRAM", 0x2000, "MSXturboR DRAM");
121 
122  // Non-mapper ROM types
123  init(ROM_MIRRORED, "Mirrored", 0x2000, "Plain rom, mirrored (any size)");
124  init(ROM_MIRRORED0000,"Mirrored0000",0x2000, "Plain rom, mirrored start at 0x0000");
125  init(ROM_MIRRORED4000,"Mirrored4000",0x2000, "Plain rom, mirrored start at 0x4000");
126  init(ROM_MIRRORED8000,"Mirrored8000",0x2000, "Plain rom, mirrored start at 0x8000");
127  init(ROM_MIRROREDC000,"MirroredC000",0x2000, "Plain rom, mirrored start at 0xC000");
128  init(ROM_NORMAL, "Normal", 0x2000, "Plain rom (any size)");
129  init(ROM_NORMAL0000, "Normal0000", 0x2000, "Plain rom start at 0x0000");
130  init(ROM_NORMAL4000, "Normal4000", 0x2000, "Plain rom start at 0x4000");
131  init(ROM_NORMAL8000, "Normal8000", 0x2000, "Plain rom start at 0x8000");
132  init(ROM_NORMALC000, "NormalC000", 0x2000, "Plain rom start at 0xC000");
133  init(ROM_PAGE0, "Page0", 0x2000, "Plain 16kB page 0");
134  init(ROM_PAGE1, "Page1", 0x2000, "Plain 16kB page 1");
135  init(ROM_PAGE2, "Page2", 0x2000, "Plain 16kB page 2 (BASIC)");
136  init(ROM_PAGE3, "Page3", 0x2000, "Plain 16kB page 3");
137  init(ROM_PAGE01, "Page01", 0x2000, "Plain 32kB page 0-1");
138  init(ROM_PAGE12, "Page12", 0x2000, "Plain 32kB page 1-2");
139  init(ROM_PAGE23, "Page23", 0x2000, "Plain 32kB page 2-3");
140  init(ROM_PAGE012, "Page012", 0x2000, "Plain 48kB page 0-2");
141  init(ROM_PAGE123, "Page123", 0x2000, "Plain 48kB page 1-3");
142  init(ROM_PAGE0123, "Page0123", 0x2000, "Plain 64kB");
143 
144  // Alternative names for rom types, mainly for backwards compatibility
145  initAlias(ROM_GENERIC_8KB, "0");
146  initAlias(ROM_GENERIC_8KB, "GenericKonami"); // probably actually used in a Zemina Box
147  initAlias(ROM_GENERIC_16KB,"1");
148  initAlias(ROM_KONAMI_SCC, "2");
149  initAlias(ROM_KONAMI_SCC, "SCC");
150  initAlias(ROM_KONAMI_SCC, "KONAMI5");
151  initAlias(ROM_KONAMI, "KONAMI4");
152  initAlias(ROM_KONAMI, "3");
153  initAlias(ROM_ASCII8, "4");
154  initAlias(ROM_ASCII16, "5");
155  initAlias(ROM_MIRRORED, "64kB");
156  initAlias(ROM_MIRRORED, "Plain");
157  initAlias(ROM_NORMAL0000, "0x0000");
158  initAlias(ROM_NORMAL4000, "0x4000");
159  initAlias(ROM_NORMAL8000, "0x8000");
160  initAlias(ROM_NORMALC000, "0xC000");
161  initAlias(ROM_ASCII16_2, "HYDLIDE2");
162  initAlias(ROM_GAME_MASTER2,"RC755");
163  initAlias(ROM_NORMAL8000, "ROMBAS");
164  initAlias(ROM_R_TYPE, "RTYPE");
165  initAlias(ROM_ZEMINA80IN1, "KOREAN80IN1");
166  initAlias(ROM_ZEMINA90IN1, "KOREAN90IN1");
167  initAlias(ROM_ZEMINA126IN1,"KOREAN126IN1");
168  initAlias(ROM_HOLY_QURAN, "HolyQuran");
169 
170  sort(begin(romTypeInfoMap), end(romTypeInfoMap), RomTypeInfoMapLess());
171 }
172 static const RomTypeMap& getRomTypeMap()
173 {
174  init();
175  return romTypeMap;
176 }
177 static const RomTypeInfoMap& getRomTypeInfoMap()
178 {
179  init();
180  return romTypeInfoMap;
181 }
182 
183 RomType RomInfo::nameToRomType(string_ref name)
184 {
185  auto& m = getRomTypeMap();
186  auto it = m.find(name);
187  return (it != end(m)) ? removeAlias(it->second) : ROM_UNKNOWN;
188 }
189 
190 string_ref RomInfo::romTypeToName(RomType type)
191 {
192  assert(!isAlias(type));
193  for (auto& p : getRomTypeMap()) {
194  if (p.second == type) {
195  return p.first;
196  }
197  }
198  UNREACHABLE; return "";
199 }
200 
201 vector<string_ref> RomInfo::getAllRomTypes()
202 {
203  vector<string_ref> result;
204  for (auto& p : getRomTypeMap()) {
205  if (!isAlias(p.second)) {
206  result.push_back(p.first);
207  }
208  }
209  return result;
210 }
211 
212 string_ref RomInfo::getDescription(RomType type)
213 {
214  auto& m = getRomTypeInfoMap();
215  auto it = lower_bound(begin(m), end(m), type, RomTypeInfoMapLess());
216  assert(it != end(m));
217  assert(std::get<0>(*it) == type);
218  return std::get<1>(*it);
219 }
220 
221 unsigned RomInfo::getBlockSize(RomType type)
222 {
223  auto& m = getRomTypeInfoMap();
224  auto it = lower_bound(begin(m), end(m), type, RomTypeInfoMapLess());
225  assert(it != end(m));
226  assert(std::get<0>(*it) == type);
227  return std::get<2>(*it);
228 }
229 
230 } // namespace openmsx
iterator emplace_noCapacityCheck_noDuplicateCheck(Args &&... args)
Definition: hash_set.hh:485
static string_ref getDescription(RomType type)
Definition: RomInfo.cc:212
string_ref::const_iterator end(const string_ref &x)
Definition: string_ref.hh:167
std::tuple< RomType, string_ref, unsigned > RomTypeInfo
Definition: RomInfo.cc:42
vector< RomTypeInfo > RomTypeInfoMap
Definition: RomInfo.cc:43
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
static unsigned getBlockSize(RomType type)
Definition: RomInfo.cc:221
static std::vector< string_ref > getAllRomTypes()
Definition: RomInfo.cc:201
LessTupleElement< 0 > RomTypeInfoMapLess
Definition: RomInfo.cc:44
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
string_ref::const_iterator begin(const string_ref &x)
Definition: string_ref.hh:166
static string_ref romTypeToName(RomType type)
Definition: RomInfo.cc:190
static RomType nameToRomType(string_ref name)
Definition: RomInfo.cc:183
#define UNREACHABLE
Definition: unreachable.hh:35