1  /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * ROM file management
5   *
6   */
7 
8 #include "sysconfig.h"
9 #include "sysdeps.h"
10 
11 #include "options.h"
12 #include "uae.h"
13 #include "gui.h"
14 #include "uae/memory.h"
15 #include "rommgr.h"
16 #include "zfile.h"
17 #include "crc32.h"
18 #include "fsdb.h"
19 #include "autoconf.h"
20 #include "filesys.h"
21 
22 #ifdef FSUAE // NL
23 #include "uae/fs.h"
24 #endif
25 
26 #define SAVE_ROM 0
27 
28 static struct romlist *rl;
29 static int romlist_cnt;
30 
romlist_getit(void)31 struct romlist *romlist_getit (void)
32 {
33 	return rl;
34 }
35 
romlist_count(void)36 int romlist_count (void)
37 {
38 	return romlist_cnt;
39 }
40 
romlist_get(const struct romdata * rd)41 TCHAR *romlist_get (const struct romdata *rd)
42 {
43 	int i;
44 
45 	if (!rd)
46 		return 0;
47 	for (i = 0; i < romlist_cnt; i++) {
48 		if (rl[i].rd->id == rd->id)
49 			return rl[i].path;
50 	}
51 	return 0;
52 }
53 
romlist_getrl(const struct romdata * rd)54 static struct romlist *romlist_getrl (const struct romdata *rd)
55 {
56 	int i;
57 
58 	if (!rd)
59 		return 0;
60 	for (i = 0; i < romlist_cnt; i++) {
61 		if (rl[i].rd == rd)
62 			return &rl[i];
63 	}
64 	return 0;
65 }
66 
67 static void romlist_cleanup (void);
romlist_add(const TCHAR * path,struct romdata * rd)68 void romlist_add (const TCHAR *path, struct romdata *rd)
69 {
70 	struct romlist *rl2;
71 
72 	if (path == NULL || rd == NULL) {
73 		romlist_cleanup ();
74 		return;
75 	}
76 	romlist_cnt++;
77 	rl = xrealloc (struct romlist, rl, romlist_cnt);
78 	rl2 = rl + romlist_cnt - 1;
79 	rl2->path = my_strdup (path);
80 	rl2->rd = rd;
81 	struct romdata *rd2 = getromdatabyid (rd->id);
82 	if (rd2 != rd && rd2) // replace "X" with parent name
83 		rd->name = rd2->name;
84 }
85 
86 
getromdatabypath(const TCHAR * path)87 struct romdata *getromdatabypath (const TCHAR *path)
88 {
89 	int i;
90 	for (i = 0; i < romlist_cnt; i++) {
91 		struct romdata *rd = rl[i].rd;
92 		if (rd->configname && path[0] == ':') {
93 			if (!_tcscmp(path + 1, rd->configname))
94 				return rd;
95 		}
96 		if (my_issamepath(rl[i].path, path))
97 			return rl[i].rd;
98 	}
99 	return NULL;
100 }
101 
102 #define NEXT_ROM_ID 161
103 
104 #define ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) \
105 { _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, NULL, crc32, a, b, c, d, e },
106 #define ALTROMPN(id,grp,num,size,flags,pn,crc32,a,b,c,d,e) \
107 { _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, pn, crc32, a, b, c, d, e },
108 
109 static struct romdata roms[] = {
110 	{ _T(" AROS KS ROM (built-in)"), 0, 0, 0, 0, _T("AROS\0"), 524288 * 2, 66, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
111 	0xffffffff, 0, 0, 0, 0, 0, _T("AROS") },
112 	{ _T(" ROM Disabled"), 0, 0, 0, 0, _T("NOROM\0"), 0, 87, 0, 0, ROMTYPE_NONE, 0, 0, NULL,
113 	0xffffffff, 0, 0, 0, 0, 0, _T("NOROM") },
114 	{ _T(" Enabled"), 0, 0, 0, 0, _T("ENABLED\0"), 0, 142, 0, 0, ROMTYPE_NOT, 0, 0, NULL,
115 	0xffffffff, 0, 0, 0, 0, 0, _T("ENABLED") },
116 
117 	{ _T("Cloanto Amiga Forever ROM key"), 0, 0, 0, 0, 0, 2069, 0, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
118 	0x869ae1b1, 0x801bbab3,0x2e3d3738,0x6dd1636d,0x4f1d6fa7,0xe21d5874 },
119 	{ _T("Cloanto Amiga Forever 2006 ROM key"), 0, 0, 0, 0, 0, 750, 48, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
120 	0xb01c4b56, 0xbba8e5cd,0x118b8d92,0xafed5693,0x5eeb9770,0x2a662d8f },
121 	{ _T("Cloanto Amiga Forever 2010 ROM key"), 0, 0, 0, 0, 0, 1544, 73, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
122 	0x8c4dd05c, 0x05034f62,0x0b5bb7b2,0x86954ea9,0x164fdb90,0xfb2897a4 },
123 
124 	{ _T("KS ROM Velvet 23.93"), 23, 93, 23, 93, _T("VELVET\0"), 131072, 125, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
125 	0xadcb44c9, 0x7c36b2ba,0x298da3da,0xce60d0ba,0x8511d470,0x76a40d5c, NULL, NULL },
126 	ALTROMPN(125, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x1d988ab8, 0xee3988a2, 0xb2693334, 0x0239d1d9, 0xf50d4fb3, 0xe0daf3bc)
127 	ALTROMPN(125, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe466b28f, 0x3e197d69, 0xcffa3e1a, 0x0c291d57, 0xb53f7d1f, 0xcb858cf7)
128 	ALTROMPN(125, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x715988a9, 0x08c36600, 0x3948c4c5, 0x4216ef8c, 0x17ebe16c, 0xc91d3b7a)
129 	ALTROMPN(125, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc4dc7e6a, 0x66b231d0, 0x8425c858, 0xdfcd36d2, 0xd38a0df8, 0x518e06a4)
130 
131 	{ _T("KS ROM v1.0 (A1000)(NTSC)"), 1, 0, 1, 0, _T("A1000\0"), 262144, 1, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
132 	0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79 },
133 	{ _T("KS ROM v1.1 (A1000)(NTSC)"), 1, 1, 31, 34, _T("A1000\0"), 262144, 2, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
134 	0xd060572a, 0x4192C505,0xD130F446,0xB2ADA6BD,0xC91DAE73,0x0ACAFB4C},
135 	{ _T("KS ROM v1.1 (A1000)(PAL)"), 1, 1, 31, 34, _T("A1000\0"), 262144, 3, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
136 	0xec86dae2, 0x16DF8B5F,0xD524C5A1,0xC7584B24,0x57AC15AF,0xF9E3AD6D },
137 	{ _T("KS ROM v1.2 (A1000)"), 1, 2, 33, 166, _T("A1000\0"), 262144, 4, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
138 	0x9ed783d0, 0x6A7BFB5D,0xBD6B8F17,0x9F03DA84,0xD8D95282,0x67B6273B },
139 	{ _T("KS ROM v1.2 (A500,A1000,A2000)"), 1, 2, 33, 180, _T("A500\0A1000\0A2000\0"), 262144, 5, 0, 0, ROMTYPE_KICK, 0, 0, _T("315093-01"),
140 	0xa6ce1636, 0x11F9E62C,0xF299F721,0x84835B7B,0x2A70A163,0x33FC0D88 },
141 	{ _T("KS ROM v1.3 (A500,A1000,A2000)"), 1, 3, 34, 5, _T("A500\0A1000\0A2000\0"), 262144, 6, 0, 0, ROMTYPE_KICK, 0, 0, _T("315093-02"),
142 	0xc4f0f55f, 0x891E9A54,0x7772FE0C,0x6C19B610,0xBAF8BC4E,0xA7FCB785 },
143 	{ _T("KS ROM v1.3 (A3000)(SK)"), 1, 3, 34, 5, _T("A3000\0"), 262144, 32, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
144 	0xe0f37258, 0xC39BD909,0x4D4E5F4E,0x28C1411F,0x30869504,0x06062E87 },
145 	{ _T("KS ROM v1.4 (A3000)"), 1, 4, 36, 16, _T("A3000\0"), 524288, 59, 3, 0, ROMTYPE_KICK, 0, 0, NULL,
146 	0xbc0ec13f, 0xF76316BF,0x36DFF14B,0x20FA349E,0xD02E4B11,0xDD932B07 },
147 	ALTROMPN(59, 1, 1, 262144, ROMTYPE_EVEN, _T("390629-02"), 0x58327536,0xd1713d7f,0x31474a59,0x48e6d488,0xe3368606,0x1cf3d1e2)
148 	ALTROMPN(59, 1, 2, 262144, ROMTYPE_ODD , _T("390630-02"), 0xfe2f7fb9,0xc05c9c52,0xd014c66f,0x9019152b,0x3f2a2adc,0x2c678794)
149 	{ _T("KS ROM v2.04 (A500+)"), 2, 4, 37, 175, _T("A500+\0"), 524288, 7, 0, 0, ROMTYPE_KICK, 0, 0, _T("390979-01"),
150 	0xc3bdb240, 0xC5839F5C,0xB98A7A89,0x47065C3E,0xD2F14F5F,0x42E334A1 },
151 	{ _T("KS ROM v2.05 (A600)"), 2, 5, 37, 299, _T("A600\0"), 524288, 8, 0, 0, ROMTYPE_KICK, 0, 0, _T("391388-01"),
152 	0x83028fb5, 0x87508DE8,0x34DC7EB4,0x7359CEDE,0x72D2E3C8,0xA2E5D8DB },
153 	{ _T("KS ROM v2.05 (A600HD)"), 2, 5, 37, 300, _T("A600HD\0A600\0"), 524288, 9, 0, 0, ROMTYPE_KICK, 0, 0, _T("391304-01"),
154 	0x64466c2a, 0xF72D8914,0x8DAC39C6,0x96E30B10,0x859EBC85,0x9226637B },
155 	{ _T("KS ROM v2.05 (A600HD)"), 2, 5, 37, 350, _T("A600HD\0A600\0"), 524288, 10, 0, 0, ROMTYPE_KICK, 0, 0, _T("391304-02"),
156 	0x43b0df7b, 0x02843C42,0x53BBD29A,0xBA535B0A,0xA3BD9A85,0x034ECDE4 },
157 	{ _T("KS ROM v2.04 (A3000)"), 2, 4, 37, 175, _T("A3000\0"), 524288, 71, 8, 0, ROMTYPE_KICK, 0, 0, NULL,
158 	0x234a7233, 0xd82ebb59,0xafc53540,0xddf2d718,0x7ecf239b,0x7ea91590 },
159 	ALTROMPN(71, 1, 1, 262144, ROMTYPE_EVEN, _T("390629-03"), 0xa245dbdf,0x83bab8e9,0x5d378b55,0xb0c6ae65,0x61385a96,0xf638598f)
160 	ALTROMPN(71, 1, 2, 262144, ROMTYPE_ODD , _T("390630-03"), 0x7db1332b,0x48f14b31,0x279da675,0x7848df6f,0xeb531881,0x8f8f576c)
161 
162 	{ _T("KS ROM v3.0 (A1200)"), 3, 0, 39, 106, _T("A1200\0"), 524288, 11, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
163 	0x6c9b07d2, 0x70033828,0x182FFFC7,0xED106E53,0x73A8B89D,0xDA76FAA5 },
164 	ALTROMPN(11, 1, 1, 262144, ROMTYPE_EVEN, _T("391523-01"), 0xc742a412,0x999eb81c,0x65dfd07a,0x71ee1931,0x5d99c7eb,0x858ab186)
165 	ALTROMPN(11, 1, 2, 262144, ROMTYPE_ODD , _T("391524-01"), 0xd55c6ec6,0x3341108d,0x3a402882,0xb5ef9d3b,0x242cbf3c,0x8ab1a3e9)
166 	{ _T("KS ROM v3.0 (A4000)"), 3, 0, 39, 106, _T("A4000\0"), 524288, 12, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
167 	0x9e6ac152, 0xF0B4E9E2,0x9E12218C,0x2D5BD702,0x0E4E7852,0x97D91FD7 },
168 	ALTROMPN(12, 1, 1, 262144, ROMTYPE_EVEN, _T("391513-02"), 0x36f64dd0,0x196e9f3f,0x9cad934e,0x181c07da,0x33083b1f,0x0a3c702f)
169 	ALTROMPN(12, 1, 2, 262144, ROMTYPE_ODD , _T("391514-02"), 0x17266a55,0x42fbed34,0x53d1f11c,0xcbde89a9,0x826f2d11,0x75cca5cc)
170 	{ _T("KS ROM v3.1 (A4000)"), 3, 1, 40, 70, _T("A4000\0"), 524288, 13, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
171 	0x2b4566f1, 0x81c631dd,0x096bbb31,0xd2af9029,0x9c76b774,0xdb74076c },
172 	ALTROM(13, 1, 1, 262144, ROMTYPE_EVEN, 0xf9cbecc9,0x138d8cb4,0x3b8312fe,0x16d69070,0xde607469,0xb3d4078e)
173 	ALTROM(13, 1, 2, 262144, ROMTYPE_ODD , 0xf8248355,0xc2379547,0x9fae3910,0xc185512c,0xa268b82f,0x1ae4fe05)
174 	{ _T("KS ROM v3.1 (A500,A600,A2000)"), 3, 1, 40, 63, _T("A500\0A600\0A2000\0"), 524288, 14, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
175 	0xfc24ae0d, 0x3B7F1493,0xB27E2128,0x30F989F2,0x6CA76C02,0x049F09CA },
176 	{ _T("KS ROM v3.1 (A1200)"), 3, 1, 40, 68, _T("A1200\0"), 524288, 15, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
177 	0x1483a091, 0xE2154572,0x3FE8374E,0x91342617,0x604F1B3D,0x703094F1 },
178 	ALTROMPN(15, 1, 1, 262144, ROMTYPE_EVEN, _T("391773-01"), 0x08dbf275,0xb8800f5f,0x90929810,0x9ea69690,0xb1b8523f,0xa22ddb37)
179 	ALTROMPN(15, 1, 2, 262144, ROMTYPE_ODD , _T("391774-01"), 0x16c07bf8,0x90e331be,0x1970b0e5,0x3f53a9b0,0x390b51b5,0x9b3869c2)
180 	{ _T("KS ROM v3.1 (A3000)"), 3, 1, 40, 68, _T("A3000\0"), 524288, 61, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
181 	0xefb239cc, 0xF8E210D7,0x2B4C4853,0xE0C9B85D,0x223BA20E,0x3D1B36EE },
182 	ALTROM(61, 1, 1, 262144, ROMTYPE_EVEN, 0x286b9a0d,0x6763a225,0x8ec493f7,0x408cf663,0x110dae9a,0x17803ad1)
183 	ALTROM(61, 1, 2, 262144, ROMTYPE_ODD , 0x0b8cde6a,0x5f02e97b,0x48ebbba8,0x7d516a56,0xb0400c6f,0xc3434d8d)
184 	{ _T("KS ROM v3.1 (A4000)(Cloanto)"), 3, 1, 40, 68, _T("A4000\0"), 524288, 31, 2 | 4, 1, ROMTYPE_KICK, 0, 0, NULL,
185 	0x43b6dd22, 0xC3C48116,0x0866E60D,0x085E436A,0x24DB3617,0xFF60B5F9 },
186 	{ _T("KS ROM v3.1 (A4000)"), 3, 1, 40, 68, _T("A4000\0"), 524288, 16, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
187 	0xd6bae334, 0x5FE04842,0xD04A4897,0x20F0F4BB,0x0E469481,0x99406F49 },
188 	ALTROM(16, 1, 1, 262144, ROMTYPE_EVEN, 0xb2af34f8,0x24e52b5e,0xfc020495,0x17387ab7,0xb1a1475f,0xc540350e)
189 	ALTROM(16, 1, 2, 262144, ROMTYPE_ODD , 0xe65636a3,0x313c7cbd,0xa5779e56,0xf19a41d3,0x4e760f51,0x7626d882)
190 	{ _T("KS ROM v3.1 (A4000T)"), 3, 1, 40, 70, _T("A4000T\0"), 524288, 17, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
191 	0x75932c3a, 0xB0EC8B84,0xD6768321,0xE01209F1,0x1E6248F2,0xF5281A21 },
192 	ALTROMPN(17, 1, 1, 262144, ROMTYPE_EVEN, _T("391657-01"), 0x0ca94f70,0xb3806eda,0xcb3362fc,0x16a154ce,0x1eeec5bf,0x5bc24789)
193 	ALTROMPN(17, 1, 2, 262144, ROMTYPE_ODD , _T("391658-01"), 0xdfe03120,0xcd7a706c,0x431b04d8,0x7814d3a2,0xd8b39710,0x0cf44c0c)
194 	{ _T("KS ROM v3.X (A4000)(Cloanto)"), 3, 10, 45, 57, _T("A4000\0"), 524288, 46, 2 | 4, 1, ROMTYPE_KICK, 0, 0, NULL,
195 	0x3ac99edc, 0x3cbfc9e1,0xfe396360,0x157bd161,0xde74fc90,0x1abee7ec },
196 
197 	{ _T("CD32 KS ROM v3.1"), 3, 1, 40, 60, _T("CD32\0"), 524288, 18, 1, 0, ROMTYPE_KICKCD32, 0, 0, NULL,
198 	0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D },
199 	{ _T("CD32 extended ROM"), 3, 1, 40, 60, _T("CD32\0"), 524288, 19, 1, 0, ROMTYPE_EXTCD32, 0, 0, NULL,
200 	0x87746be2, 0x5BEF3D62,0x8CE59CC0,0x2A66E6E4,0xAE0DA48F,0x60E78F7F },
201 
202 	/* plain CD32 rom */
203 	{ _T("CD32 ROM (KS + extended)"), 3, 1, 40, 60, _T("CD32\0"), 2 * 524288, 64, 1, 0, ROMTYPE_KICKCD32 | ROMTYPE_EXTCD32 | ROMTYPE_CD32, 0, 0, NULL,
204 	0xf5d4f3c8, 0x9fa14825,0xc40a2475,0xa2eba5cf,0x325bd483,0xc447e7c1 },
205 	/* real CD32 rom dump 391640-03 */
206 	ALTROMPN(64, 1, 1, 2 * 524288, ROMTYPE_CD32, _T("391640-03"), 0xa4fbc94a, 0x816ce6c5,0x07787585,0x0c7d4345,0x2230a9ba,0x3a2902db )
207 
208 	{ _T("CD32 Full Motion Video Cartridge ROM"), 3, 1, 40, 30, _T("CD32FMV\0"), 262144, 23, 1, 0, ROMTYPE_CD32CART, 0, 0, NULL,
209 	0xc35c37bf, 0x03ca81c7,0xa7b259cf,0x64bc9582,0x863eca0f,0x6529f435 },
210 	{ _T("CD32 Full Motion Video Cartridge ROM"), 3, 1, 40, 22, _T("CD32FMV\0"), 262144, 74, 1, 0, ROMTYPE_CD32CART, 0, 0, _T("391777-01"),
211 	0xf11158eb, 0x94e469a7,0x6030dcb2,0x99ebc752,0x0aaeef9d,0xb54284cf },
212 
213 	{ _T("CDTV extended ROM v1.00"), 1, 0, 1, 0, _T("CDTV\0"), 262144, 20, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
214 	0x42baa124, 0x7BA40FFA,0x17E500ED,0x9FED041F,0x3424BD81,0xD9C907BE },
215 	ALTROMPN(20, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("252606-01"), 0x791cb14b,0x277a1778,0x92449635,0x3ffe56be,0x68063d2a,0x334360e4)
216 	ALTROMPN(20, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("252607-01"), 0xaccbbc2e,0x41b06d16,0x79c6e693,0x3c3378b7,0x626025f7,0x641ebc5c)
217 	{ _T("CDTV extended ROM v2.07"), 2, 7, 2, 7, _T("CDTV\0"), 262144, 22, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
218 	0xceae68d2, 0x5BC114BB,0xA29F60A6,0x14A31174,0x5B3E2464,0xBFA06846 },
219 	ALTROM(22, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x36d73cb8,0x9574e546,0x4b390697,0xf28f9a43,0x4e604e5e,0xf5e5490a)
220 	ALTROM(22, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x6e84dce7,0x01a0679e,0x895a1a0f,0x559c7253,0xf539606b,0xd447b54f)
221 	{ _T("CDTV/A570 extended ROM v2.30"), 2, 30, 2, 30, _T("CDTV\0"), 262144, 21, 0, 0, ROMTYPE_EXTCDTV, 0, 0, _T("391298-01"),
222 	0x30b54232, 0xED7E461D,0x1FFF3CDA,0x321631AE,0x42B80E3C,0xD4FA5EBB },
223 	ALTROM(21, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x48e4d74f,0x54946054,0x2269e410,0x36018402,0xe1f6b855,0xfd89092b)
224 	ALTROM(21, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x8a54f362,0x03df800f,0x032046fd,0x892f6e7e,0xec08b76d,0x33981e8c)
225 	{ _T("CDTV-CR extended ROM v3.32"), 3, 32, 3, 32, _T("CDTVCR\0"), 262144, 107, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
226 	0x581a85cf, 0xd6b8d3f2,0x854eba9b,0x2d514579,0x9529e8b3,0x3b85e0b4 },
227 	{ _T("CDTV-CR extended ROM v3.44"), 3, 44, 3, 44, _T("CDTVCR\0"), 262144, 108, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
228 	0x0b7bd64f, 0x3b160c5a,0xbe79f10a,0xe6924332,0x8004bb9e,0x3162b648 },
229 
230 	{ _T("A1000 bootstrap ROM"), 0, 0, 0, 0, _T("A1000\0"), 65536, 24, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
231 	0x0b1ad2d0, 0xBA93B8B8,0x5CA0D83A,0x68225CC3,0x3B95050D,0x72D2FDD7 },
232 	ALTROM(24, 1, 1, 8192,           0, 0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6)
233 	ALTROMPN(24, 2, 1, 4096, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("252179-01"), 0x42553bc4,0x8855a97f,0x7a44e3f6,0x2d1c88d9,0x38fee1f4,0xc606af5b)
234 	ALTROMPN(24, 2, 2, 4096, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("252180-01"), 0x8e5b9a37,0xd10f1564,0xb99f5ffe,0x108fa042,0x362e877f,0x569de2c3)
235 
236 	{ _T("The Diagnostic 2.0 (Logica)"), 2, 0, 2, 0, _T("LOGICA\0"), 524288, 72, 0, 0, ROMTYPE_KICK | ROMTYPE_SPECIALKICK, 0, 0, NULL,
237 	0x8484f426, 0xba10d161,0x66b2e2d6,0x177c979c,0x99edf846,0x2b21651e },
238 
239 	{ _T("Freezer: Action Replay Mk I v1.00"), 1, 0, 1, 0, _T("AR\0"), 65536, 52, 0, 0, ROMTYPE_AR, 0, 1, NULL,
240 	0x2d921771, 0x1EAD9DDA,0x2DAD2914,0x6441F5EF,0x72183750,0x22E01248 },
241 	ALTROM(52, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x82d6eb87, 0x7c9bac11,0x28666017,0xeee6f019,0x63fb3890,0x7fbea355)
242 	ALTROM(52, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x40ae490c, 0x81d8e432,0x01b73fd9,0x2e204ebd,0x68af8602,0xb62ce397)
243 	{ _T("Freezer: Action Replay Mk I v1.50"), 1, 50, 1, 50, _T("AR\0"), 65536, 25, 0, 0, ROMTYPE_AR, 0, 1, NULL,
244 	0xf82c4258, 0x843B433B,0x2C56640E,0x045D5FDC,0x854DC6B1,0xA4964E7C },
245 	ALTROM(25, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x7fbd6de2, 0xb5f71a5c,0x09d65ecc,0xa8a3bc93,0x93558461,0xca190228)
246 	ALTROM(25, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x43018069, 0xad8ff242,0xb2cbf125,0x1fc53a73,0x581cf57a,0xb69cee00)
247 	{ _T("Freezer: Action Replay Mk II v2.05"), 2, 5, 2, 5, _T("AR\0"), 131072, 26, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
248 	0x1287301f, 0xF6601DE8,0x888F0050,0x72BF562B,0x9F533BBC,0xAF1B0074 },
249 	{ _T("Freezer: Action Replay Mk II v2.12"), 2, 12, 2, 12, _T("AR\0"), 131072, 27, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
250 	0x804d0361, 0x3194A07A,0x0A82D8B5,0xF2B6AEFA,0x3CA581D6,0x8BA8762B },
251 	{ _T("Freezer: Action Replay Mk II v2.14"), 2, 14, 2, 14, _T("AR\0"), 131072, 28, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
252 	0x49650e4f, 0x255D6DF6,0x3A4EAB0A,0x838EB1A1,0x6A267B09,0x59DFF634 },
253 	{ _T("Freezer: Action Replay Mk III v3.09"), 3, 9, 3, 9, _T("AR\0"), 262144, 29, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
254 	0x0ed9b5aa, 0x0FF3170A,0xBBF0CA64,0xC9DD93D6,0xEC0C7A01,0xB5436824 },
255 	ALTROM(29, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x2b84519f, 0x7841873b,0xf009d834,0x1dfa2794,0xb3751bac,0xf86adcc8)
256 	ALTROM(29, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x1d35bd56, 0x6464be16,0x26b51949,0x9e76e4e3,0x409e8016,0x515d48b6)
257 	{ _T("Freezer: Action Replay Mk III v3.17"), 3, 17, 3, 17, _T("AR\0"), 262144, 30, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
258 	0xc8a16406, 0x5D4987C2,0xE3FFEA8B,0x1B02E314,0x30EF190F,0x2DB76542 },
259 	{ _T("Freezer: Action Replay 1200"), 0, 0, 0, 0, _T("AR\0"), 262144, 47, 0, 0, ROMTYPE_AR, 0, 1, NULL,
260 	0x8d760101, 0x0F6AB834,0x2810094A,0xC0642F62,0xBA42F78B,0xC0B07E6A },
261 
262 	{ _T("Freezer: Action Cartridge Super IV Professional"), 0, 0, 0, 0, _T("SUPERIV\0"), 0, 62, 0, 0, ROMTYPE_SUPERIV, 0, 1, NULL,
263 	0xffffffff, 0, 0, 0, 0, 0, _T("SuperIV") },
264 	{ _T("Freezer: Action Cart. Super IV Pro (+ROM v4.3)"), 4, 3, 4, 3, _T("SUPERIV\0"), 170368, 60, 0, 0, ROMTYPE_SUPERIV, 0, 1, NULL,
265 	0xe668a0be, 0x633A6E65,0xA93580B8,0xDDB0BE9C,0x9A64D4A1,0x7D4B4801 },
266 	{ _T("Freezer: X-Power Professional 500 v1.2"), 1, 2, 1, 2, _T("XPOWER\0"), 131072, 65, 0, 0, ROMTYPE_XPOWER, 0, 1, NULL,
267 	0x9e70c231, 0xa2977a1c,0x41a8ca7d,0x4af4a168,0x726da542,0x179d5963 },
268 	ALTROM(65, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf98742e4,0xe8e683ba,0xd8b38d1f,0x79f3ad83,0xa9e67c6f,0xa91dc96c)
269 	ALTROM(65, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdfb9984b,0x8d6bdd49,0x469ec8e2,0x0143fbb3,0x72e92500,0x99f07910)
270 	{ _T("Freezer: X-Power Professional 500 v1.3"), 1, 3, 1, 3, _T("XPOWER\0"), 131072, 68, 0, 0, ROMTYPE_XPOWER, 0, 1, NULL,
271 	0x31e057f0, 0x84650266,0x465d1859,0x7fd71dee,0x00775930,0xb7e450ee },
272 	ALTROM(68, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x0b2ce0c7,0x45ad5456,0x89192404,0x956f47ce,0xf66a5274,0x57ace33b)
273 	ALTROM(68, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x34580c35,0x8ad42566,0x7364f238,0x978f4381,0x08f8d5ec,0x470e72ea)
274 	{ _T("Freezer: Nordic Power v1.5"), 1, 5, 1, 5, _T("NPOWER\0"), 65536, 69, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
275 	0x83b4b21c, 0xc56ced25,0x506a5aab,0x3fa13813,0x4fc9e5ae,0x0f9d3709 },
276 	ALTROM(69, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdd207174,0xae67652d,0x64f5db20,0x0f4b2110,0xee59567f,0xfbd90a1b)
277 	ALTROM(69, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x8f93d85d,0x73c62d21,0x40c0c092,0x6315b702,0xdd5d0f05,0x3dad7fab)
278 	{ _T("Freezer: Nordic Power v2.0"), 2, 0, 2, 0, _T("NPOWER\0"), 65536, 67, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
279 	0xa4db2906, 0x0aec68f7,0x25470c89,0x6b699ff4,0x6623dec5,0xc777466e },
280 	ALTROM(67, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xb21be46c,0x50dc607c,0xce976bbd,0x3841eaf0,0x591ddc7e,0xa1939ad2)
281 	ALTROM(67, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x96057aed,0xdd9209e2,0x1d5edfc1,0xcdb52abe,0x93de0f35,0xc43da696)
282 	{ _T("Freezer: Nordic Power v3.0"), 3, 0, 3, 0, _T("NPOWER\0"), 65536, 70, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
283 	0x72850aef, 0x59c91d1f,0xa8f118f9,0x0bdba05a,0x9ae788d7,0x7a6cc7c9 },
284 	ALTROM(70, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf3330e1f,0x3a597db2,0xb7d11b6c,0xb8e13496,0xc215f223,0x88c4ca3c)
285 	ALTROM(70, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xee58e0f9,0x4148f4cb,0xb42cec33,0x8ca144de,0xd4f54118,0xe0f185dd)
286 	{ _T("Freezer: Nordic Power v3.2"), 3, 2, 3, 2, _T("NPOWER\0"), 65536, 115, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
287 	0x46158b6e, 0xd8c3f5af,0x5f109c61,0x5f6acb38,0x68fe6c06,0x580041b5 },
288 	ALTROM(115, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x4bfc71de,0x51914de0,0xdc0f055a,0x29ca188d,0xa7f61914,0xfdecbd07)
289 	ALTROM(115, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x923ec443,0x9f1e5334,0xaa620745,0xf4d0c50e,0x8736543b,0x6d4366c5)
290 	{ _T("Freezer: Pro Access v2.17"), 2, 17, 2, 17, _T("PROACCESS\0"), 65536, 116, 0, 0, ROMTYPE_AR, 0, 1, NULL,
291 	0xc4c265cd, 0x6a5c0d99,0x69a624dc,0x1b437aec,0x5dbcd4c7,0x2ce9064a },
292 	ALTROM(116, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x1909f7e9, 0x5abe9b9d,0xaae328c8,0x134e2b62,0x7b33b698,0xe342afc2)
293 	ALTROM(116, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0xa3927c72, 0x7adc9352,0x2d112ae9,0x23b9a70d,0x951b1e7a,0xba800ea6)
294 
295 	{ _T("Freezer: HRTMon v2.36 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL,
296 	0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon") },
297 
298 	{ _T("A2090a"), 0, 0, 0, 0, _T("A2090A\0"), 16384, 122, 0, 0, ROMTYPE_A2090, 0, 0, NULL,
299 	0x73fe45a7, 0x77ce9091,0x4be5a3bf,0x6f26b343,0x062b5bd8,0xc63c3754 },
300 	ALTROMPN(122, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("315097-01"), 0x150b116c,0x8011d873,0x3be53db0,0x79dfe319,0x7ffb8634,0x1baa6dbd)
301 	ALTROMPN(122, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("315098-01"), 0xbe422e3b,0x64ad1646,0x030db10f,0x54f13f64,0x7d449e4d,0x17f9ab5c)
302 	{ _T("A590/A2091 6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
303 	0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2 },
304 	ALTROMPN(53, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390389-03"), 0xb0b8cf24,0xfcf40175,0x05f4d441,0x814b45d5,0x59c19eab,0x43816b30)
305 	ALTROMPN(53, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-03"), 0x2e77bbff,0x8a098845,0x068f32cf,0xa4d34a27,0x8cd290f6,0x1d35a52c)
306 	{ _T("A590/A2091 6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
307 	0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66 },
308 	ALTROMPN(54, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-02"), 0xe536bbb2,0xfd7f8a6d,0xa18c1b02,0xd07eb990,0xc2467a24,0x183ede12)
309 	ALTROMPN(54, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-02"), 0xc0871d25,0xe155f18a,0xbb90cf82,0x0589c15e,0x70559d3b,0x6b391af8)
310 	{ _T("A590/A2091 7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
311 	0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E },
312 	ALTROMPN(55, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-03"), 0xa9ccffed,0x149f5bd5,0x2e2d2990,0x4e3de483,0xb9ad7724,0x48e9278e)
313 	ALTROMPN(55, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-03"), 0x2942747a,0xdbd7648e,0x79c75333,0x7ff3e4f4,0x91de224b,0xf05e6bb6)
314 	{ _T("A590/A2091 Guru ROM 6.14"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
315 	0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B },
316 	{ _T("A4091 40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091, 0, 0, NULL,
317 	0x00000000, 0, 0, 0, 0, 0 },
318 	{ _T("A4091 40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091, 0, 0, _T("391592-02"),
319 	0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA },
320 	{ _T("SupraDrive AMAB6"), 3, 8, 3, 8, _T("SUPRA\0"), 16384, 121, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB6"),
321 	0xf40bd349, 0x82168556,0x07525067,0xe9263431,0x1fb9c347,0xe737f247 },
322 	{ _T("SupraDrive AMAB5"), 3, 0, 3, 0, _T("SUPRA\0"), 16384, 134, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB5"),
323 	0x75e1b343, 0xf15de74b,0x4e2a9c99,0xa6dc4f6c,0x33f64c76,0x8c043d1c },
324 	{ _T("SupraDrive AMAB4"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 135, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB4"),
325 	0xde7f3f1c, 0xc0acbfc8,0x6641a6c1,0x024870cc,0x519f8c4c,0xbdfe8c64 },
326 	{ _T("SupraDrive AMAB3"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 136, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB3"),
327 	0x3ead39aa, 0x02fe79ee,0xef423098,0xec6add8c,0xb92f849f,0xc64bcd41 },
328 
329 	{ _T("Blizzard 1230-IV"), 0, 0, 0, 0, _T("B1230\0"), 32768, 89, 0, 0, ROMTYPE_CB_BLIZ1230, 0, 0, NULL,
330 	0x3078dbdc, 0x4d3e7fd0,0xa1a4c3ae,0xe17c5de3,0xcbe1af03,0x447aff92 },
331 	{ _T("Blizzard 1240/1260"), 0, 0, 0, 0, _T("B1240\0B1260\0"), 32768, 90, 0, 0, ROMTYPE_CB_BLIZ1260, 0, 0, NULL,
332 	0xf88ae0f1, 0xf69aca4b,0xb13e3389,0x04676f0c,0x8616f8db,0x074c313d },
333 	{ _T("Blizzard 2060"), 8, 5, 8, 5, _T("B2060\0"), 65536, 92, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL,
334 	0xce270bc0, 0xe043c1aa,0x3bb06e06,0xd4dabff3,0x0a8c6317,0xabfef2bb },
335 	ALTROMPN(92, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa6023f20, 0xdfb048d6, 0xbdc03587, 0x241e8121, 0x26aba603, 0xd69b0238)
336 	ALTROMPN(92, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x9635a9cd, 0x47578b27, 0xc4ba6e54, 0x891930dd, 0xcb4b6a45, 0x5d6b31b2)
337 	{ _T("Blizzard SCSI Kit IV"), 8, 5, 8, 5, _T("BSCSIIV\0"), 32768, 94, 0, 0, ROMTYPE_BLIZKIT4, 0, 0, NULL,
338 	0xf53a0fca, 0xefe17ca5,0x88c44a7f,0x0f8c62be,0x20f23278,0xcfe06727, NULL, _T("blizzard_scsi_kit_iv.rom") },
339 	{ _T("Fastlane"), 8, 5, 8, 5, _T("FASTLANE\0"), 20788, 102, 0, 0, ROMTYPE_FASTLANE, 0, 0, NULL,
340 	0xe4f485a5, 0x20bf7de5,0x05e45d0a,0xc411cfd2,0x806d0fd8,0xe46276de, NULL, _T("fastlanez3.rom") },
341 	{ _T("Oktagon 2008"), 6, 12, 6, 12, _T("OKTAGON\0"), 32768, 103, 0, 0, ROMTYPE_OKTAGON, 0, 0, NULL,
342 	0xbb0d2f6a, 0x56c441fa,0x37d19339,0x3081b2e8,0xceae823b,0xc7e97e49, NULL, _T("oktagon2008.rom") },
343 	{ _T("Warp Engine A4000"), 0, 0, 0, 0, _T("WARPENGINE\0WARPENGINEA4000\0"), 32768, 93, 0, 0, ROMTYPE_CB_WENGINE, 0, 0, NULL,
344 	0x4deb574a, 0x6e6c95ff,0xe8448391,0xd36c5b68,0xc9065cb0,0x702a7d27 },
345 	{ _T("TekMagic 2040/2060"), 1, 0, 1, 0, _T("TEKMAGIC\0TEKMAGIC2040\0TEKMAGIC2060\0"), 65536, 104, 0, 0, ROMTYPE_CB_TEKMAGIC, 0, 0, NULL,
346 	0x9e9781d5, 0xf65b60d1,0x4300c50f,0x2ed17cf4,0x4dcfdef9,0x16697bc9, NULL,  _T("tekmagic2060.rom") },
347 	ALTROMPN(104, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x888da4cf, 0x6ae85f3a, 0x65331ba4, 0xaaba67ae, 0x34763d70, 0x2bde0495)
348 	ALTROMPN(104, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaf1f47db, 0x28d5bed0, 0xbc517d46, 0x500e8159, 0x723e0b64, 0x4733c26a)
349 	{ _T("A2620/A2630 -07"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"),
350 	0x169d80e9, 0x41f518cb,0x41c1dc1f,0xcc636383,0x20676af5,0x4969010c, NULL, NULL },
351 	ALTROMPN(105, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-07"), 0xf2904058, 0x33695119, 0x5fdf5d56, 0x095a696b, 0x0ba2641d, 0x334845df)
352 	ALTROMPN(105, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-07"), 0xf697d458, 0x09fe260b, 0x03784e87, 0x3351dbec, 0x5146a455, 0x814383d1)
353 	{ _T("A2620/A2630 -06"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 106, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-06/390283-06"),
354 	0xeb31fd9e, 0x2d6a5c68,0x1040f98d,0x7e63ad08,0x90da9e83,0x2b5c704d, NULL, NULL },
355 	ALTROMPN(106, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-06"), 0xd6ae582c, 0x47b3dea3, 0x31db76e6, 0x1380a3d6, 0x9f191657, 0xdd1cd4b3)
356 	ALTROMPN(106, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-06"), 0xcd379634, 0x65e251e2, 0xf6961c8e, 0x33a86c3d, 0x01248f70, 0xa159823b)
357 	{ _T("DKB 12x0"), 1, 23, 1, 23, _T("DKB\0"), 32768, 112, 0, 0, ROMTYPE_CB_DKB12x0, 0, 0, NULL,
358 	0xf3b2b0b3, 0x1d539593,0xb1d7514e,0xeb214ab3,0x433a97fc,0x8a010366, NULL, NULL },
359 	{ _T("Fusion Forty"), 0, 0, 0, 0, _T("FUSIONFORTY\0"), 131072, 113, 0, 0, ROMTYPE_CB_FUSION, 0, 0, NULL,
360 	0x48fcb5fd, 0x15674dac,0x90b6d8db,0xdda3a175,0x997184c2,0xa423d733, NULL, NULL },
361 	ALTROMPN(113, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U28"), 0x434a21a8, 0x472c1623, 0x02babd00, 0x7c1a77ff, 0x40dd12ab, 0x39c97f82)
362 	ALTROMPN(113, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, _T("U27"), 0x38373cf6, 0xfe8aa931, 0xada6b6f3, 0x6b48ca3c, 0x9b86677d, 0xbee4da59)
363 	ALTROMPN(113, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U25"), 0xc9e990d3, 0xb251ef73, 0x1374e796, 0xa87cbc7e, 0x9263320a, 0x28a71d2b)
364 	ALTROMPN(113, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, _T("U26"), 0x2e117fe0, 0xbb2de2da, 0x6db4e92c, 0x636fefe6, 0x13a32699, 0xcea31011)
365 	{ _T("Apollo 1240/1260"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CB_APOLLO, 0, 0, NULL,
366 	0xcd009ad9, 0x1c3b4851,0xc5a221e3,0xa7ca24fc,0xc1df4a5b,0x9f2343ad },
367 	{ _T("GVP A3001 Series I"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CB_A3001S1, 0, 0, NULL,
368 	0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
369 	{ _T("Kupke Golem 030"), 0, 0, 0, 0, _T("GOLEM030\0"), 8192, 126, 0, 0, ROMTYPE_CB_GOLEM030, 0, 0, NULL,
370 	0x05d473f4, 0x574ec567, 0xcc67e06f, 0x91dcecb9, 0x8c204399, 0x5fe2a09f, NULL, NULL },
371 	{ _T("DKB WildFire"), 1, 1, 1, 1, _T("WILDFIRE\0"), 18352, 143, 0, 0, ROMTYPE_CB_DBK_WF, 0, 0, NULL,
372 	0xb2dae8c4, 0xcdfe2d96, 0xe44d4f8d, 0x3833a5e8, 0xb6c832fd, 0xc7b341a9, NULL, NULL },
373 	{ _T("M-Tec E-Matrix 530"), 0, 0, 0, 0, _T("EMATRIX530\0"), 65536, 144, 0, 0, ROMTYPE_CB_EMATRIX, 0, 0, NULL,
374 	0x3942d827, 0x5aaf118f, 0x61fc3083, 0x1435b87c, 0x8bdab6a4, 0x59b4ee22, NULL, NULL },
375 	{ _T("SX32 Pro"), 0, 0, 0, 0, _T("SX32PRO\0"), 65536, 160, 0, 0, ROMTYPE_CB_SX32PRO, 0, 0, NULL,
376 	0xbfd68a88, 0x84a50880, 0x76917549, 0xadf33b16, 0x8a869adb, 0x9e5a6fac, NULL, NULL },
377 
378 	{ _T("Preferred Technologies Nexus"), 1, 0, 1, 0, _T("PTNEXUS\0"), 8192, 139, 0, 0, ROMTYPE_PTNEXUS, 0, 0, NULL,
379 	0xf495879a, 0xa3bd0202, 0xe14aa5b6, 0x49d3ce88, 0x22975950, 0x6500dbc2, NULL, NULL },
380 	{ _T("ICD AdSCSI 2000"), 1, 6, 1, 6, _T("ADSCSI\0"), 32768, 133, 0, 0, ROMTYPE_ADSCSI, 0, 0, NULL,
381 	0x7dba3e1f, 0x1e05f284, 0xd59a1e5d, 0x4e4de44e, 0x6f075175, 0x625cd6c0, NULL, NULL },
382 	{ _T("Archos ADD-500"), 1, 21, 1, 21, _T("ADD\0"), 16384, 132, 0, 0, ROMTYPE_ADD500, 0, 0, NULL,
383 	0x3f4e4a74, 0x9ed96fc0,0xd6381dc3,0x3192b0af,0xdfae4b74,0x576c3a69, NULL, NULL },
384 	{ _T("Protar A500HD"), 1, 193, 1, 193, _T("PROTAR\0"), 32768, 131, 0, 0, ROMTYPE_PROTAR, 0, 0, NULL,
385 	0x10c1b22c, 0x2b800cde,0x79fd559e,0xebd5e432,0xd711af3d,0x0b8ea7e9, NULL, NULL },
386 	{ _T("M-Tec AT500"), 1, 33, 1, 33, _T("MTECAT\0"), 32768, 130, 0, 0, ROMTYPE_MTEC, 0, 0, NULL,
387 	0x38b6b6b0, 0x8bb1093a,0xd592e7df,0x99c48f83,0xb9f842b2,0xb1a6e618, NULL, NULL },
388 	{ _T("AdIDE 40/44 v33"), 33, 0, 33, 0, _T("ADIDE\0"), 16384, 141, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL,
389 	0x330254ce, 0xc91dd3b5,0x3f1986bd,0x94fba150,0xe753c2da,0x4dee78e7, NULL, NULL },
390 	{ _T("AdIDE 40/44 v34"), 34, 0, 34, 0, _T("ADIDE\0"), 16384, 129, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL,
391 	0xedf84cbe, 0xabdbc01d,0xaa0b3aae,0xe4401ad7,0xe65525a9,0x6bfa2b27, NULL, NULL },
392 	{ _T("Vector Falcon 8000"), 7, 1, 7, 1, _T("VECTOR\0"), 32768, 128, 0, 0, ROMTYPE_VECTOR, 0, 0, NULL,
393 	0xa8120c55, 0x248935ab,0xf4d74036,0xefdafdbb,0x7817e232,0xfc13e0fa, NULL, NULL },
394 	{ _T("Kommos A500/A2000 v1.8"), 1, 8, 1, 8, _T("KOMMOS\0"), 32768, 127, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL,
395 	0xc1a5c848, 0x291310f1, 0x25455f2d, 0x8e114bcd, 0xe104ca4c, 0x9db51747, NULL, NULL },
396 	ALTROMPN(127, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x1b86d2ed, 0x969995a1, 0x2ebf8c15, 0xab87e8d0, 0xddc837a1, 0xb90fbfa8)
397 	ALTROMPN(127, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x65b4c3a0, 0x60e904d4, 0xe45bb6ba, 0x3e253ffa, 0xda4ee2e5, 0xc8548da1)
398 	{ _T("Kommos A500/A2000 v1.7"), 1, 7, 1, 7, _T("KOMMOS\0"), 32768, 140, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL,
399 	0x025d7835, 0x8205ad6e, 0x08dbf5a6, 0x9ba17956, 0xb5237ffe, 0x768de5a4, NULL, NULL },
400 	ALTROMPN(140, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x3d982391, 0xbe26e141, 0x1e16cab4, 0xeab8af33, 0x1476ef8e, 0x21fcb2af)
401 	ALTROMPN(140, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x68adc0ad, 0xb5eef088, 0xed8a9439, 0xb0302907, 0xcb3cb207, 0x62f28da7)
402 	{ _T("Kupke Golem v3.9"), 3, 9, 3, 9, _T("GOLEM\0"), 16384, 124, 0, 0, ROMTYPE_GOLEM, 0, 0, NULL,
403 	0x49157dd0, 0x03b615c9,0x2befa474,0xa37303ca,0xdc3e830d,0x3c0d9a9f, NULL, NULL },
404 	ALTROMPN(124, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x88cf2ec5, 0x59680f8d, 0xae520893, 0xff9ada35, 0xac9a1146, 0x4f87453c)
405 	ALTROMPN(124, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x713298ad, 0x2ad7d6f3, 0xd696fd2c, 0x51a256ee, 0xea185c47, 0x52906e04)
406 	{ _T("GVP Series I v1.0"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 123, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL,
407 	0x1a4c20aa, 0xb9a3377e,0x2d9b5163,0x28693c63,0x19ffb65b,0x40ae3618, NULL, NULL },
408 	ALTROMPN(123, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x27f15785, 0x1a71a78d, 0xdd4e9559, 0x0f133bba, 0x4a71122f, 0x44caef78)
409 	ALTROMPN(123, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa723193e, 0x05b4a072, 0x785c7824, 0x54e003c3, 0x6d88bd9b, 0xf5f561b9)
410 	{ _T("GVP Series I/II v3.15"), 3, 15, 3, 15, _T("GVPII\0GVPI\0"), 16384, 111, 0, 0, ROMTYPE_GVPS12, 0, 0, NULL,
411 	0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL },
412 	{ _T("GVP Series II v4.15"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
413 	0xf89f44d6, 0xbf10c12c,0xc72dd040,0x549ea17c,0x24947633,0xe3773297, NULL, NULL },
414 	{ _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
415 	0x756103b1, 0x7f1335ea,0xf5b7ce73,0xc5231173,0x261da5aa,0xe7249645, NULL, NULL },
416 	{ _T("AlfaPower v6.10"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL,
417 	0x1cfb0a0b, 0xc7275eda,0x547d6664,0x5c4eb7a0,0x3b5cef37,0xa498365a, NULL, NULL },
418 	{ _T("AlfaPower v8.3"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL,
419 	0xe8201bad, 0xdefea015,0x596fce32,0x11e84397,0x23046a31,0x5a7726dc, NULL, NULL },
420 	{ _T("Masoboshi MC-702"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
421 	0xcd99b98a, 0x3897e46a,0x66d5833f,0x849b8e81,0x30acb3cb,0x319a2fa0, NULL, NULL },
422 	{ _T("Roctec RocHard RH800C v1"), 1, 0, 1, 0, _T("ROCHARD\0"), 16384, 138, 0, 0, ROMTYPE_ROCHARD, 0, 0, NULL,
423 	0x0e980aec, 0xbcafa14d,0xe80576cb,0xe3e0c638,0x1ca90379,0xe078a8bd, NULL, NULL },
424 	ALTROMPN(138, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xde3a855b, 0xda2fe069, 0xd78c9ccc, 0xc221711f, 0x1e598298, 0x2bdabffd)
425 	ALTROMPN(138, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xb0ed3006, 0x0a88d84e, 0x2094f9e5, 0x18d37f90, 0x34764f22, 0x9696c3d9)
426 	{ _T("Roctec RocHard RH800C v2"), 2, 0, 2, 0, _T("ROCHARD\0"), 16384, 146, 0, 0, ROMTYPE_ROCHARD, 0, 0, NULL,
427 	0x5c27be3f, 0xacdb8bc7,0x64493f65,0x9da4c1e8,0x3005ceeb,0xced73dbc, NULL, NULL },
428 	ALTROMPN(146, 1, 1, 8192, ROMTYPE_ODD |  ROMTYPE_8BIT, NULL, 0xc5b8f068, 0x6ada1205, 0x44d284d0, 0x326d68cb, 0x7a2d9fb4, 0x77f35852)
429 	ALTROMPN(146, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xc88843cb, 0x3d7eb1b6, 0x8139b81b, 0x0665684c, 0x536ab3d0, 0x52a5dd9d)
430 	{ _T("Apollo 500/2000"), 0, 0, 0, 0, _T("APOLLOHD\0"), 16384, 145, 0, 0, ROMTYPE_APOLLOHD, 0, 0, NULL,
431 	0x931bad25, 0x24b4ee4c,0x129c7a93,0xf83ad570,0x66afd80c,0x4179f39c, NULL, NULL },
432 	{ _T("Multi Evolution 500/200"), 3, 0, 3, 0, _T("MULTIEVOLUTION\0"), 65536, 156, 0, 0, ROMTYPE_MEVOLUTION, 0, 0, NULL,
433 	0xd13a2c89, 0xf9e38c4b,0xf5c6499d,0x486946ba,0x7b7636b8,0x0845265b, NULL, NULL },
434 	ALTROMPN(156, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x339b3549, 0x74de857b, 0x42f9a8e0, 0xc1f3c29e, 0x06982622, 0x853d08fe)
435 	ALTROMPN(156, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x3aca5d1f, 0x786f2197, 0xc614be91, 0xae7e87da, 0xb42c3290, 0xd7997763)
436 	{ _T("Kupke Golem v4.2"), 4, 2, 4, 2, _T("GOLEMFAST\0"), 16384, 157, 0, 0, ROMTYPE_GOLEMFAST, 0, 0, NULL,
437 	0x5e94ee56, 0xf83dae55, 0x49f9b735, 0x52d5c6e0, 0x41da4c6c, 0x995a7f47, NULL, NULL },
438 	ALTROMPN(157, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xec13fda0, 0x6af1447c, 0x4363c46d, 0x05697458, 0x01daa30c, 0x03c01c9f)
439 	ALTROMPN(157, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x39b0075e, 0xf6644ea0, 0x6c3ed349, 0xfb0fb6b4, 0xa9f07655, 0x0b104179)
440 	{ _T("Phoenix Board SCSI v.J"), 3, 1, 3, 1, _T("PBSCSI\0"), 32768, 159, 0, 0, ROMTYPE_PHOENIXB, 0, 0, NULL,
441 	0x1f672e4b, 0xb20d50b8, 0x31ec9823, 0xfa732fc6, 0x522ecc6a, 0xae36ec33, NULL, NULL },
442 
443 	{ _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL,
444 	  0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") },
445 	{ _T("CyberStorm MK I 68060"), 0, 0, 0, 0, _T("CSMKI\0"), 65536, 101, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL,
446 	  0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_060.rom") },
447 	{ _T("CyberStorm MK II"), 0, 0, 0, 0, _T("CSMKII\0"), 131072, 96, 0, 0, ROMTYPE_CB_CSMK2, 0, 0, NULL,
448 	  0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk2.rom") },
449 	{ _T("CyberStorm MK III"), 0, 0, 0, 0, _T("CSMKIII\0"), 131072, 97, 0, 0, ROMTYPE_CB_CSMK3, 0, 0, NULL,
450 	  0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk3.rom") },
451 	{ _T("CyberStorm PPC"), 0, 0, 0, 0, _T("CSPPC\0"), 131072, 98, 0, 0, ROMTYPE_CB_CSPPC, 0, 0, NULL,
452 	  0, 0, 0, 0, 0, 0, NULL, _T("cyberstormppc.rom") },
453 	{ _T("Blizzard PPC 68040"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 99, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
454 	  0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_040.rom") },
455 	{ _T("Blizzard PPC 68060"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 100, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
456 	  0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_060.rom") },
457 	{ _T("ACA 500"), 0, 0, 0, 0, _T("ACA500\0"), 524288, 137, 0, 0, ROMTYPE_CB_ACA500, 0, 0, NULL,
458 	  0, 0, 0, 0, 0, 0, NULL, _T("menu500.aca") },
459 
460 	{ _T("Picasso IV"), 7, 4, 7, 4, _T("PIV\0"), 131072, 91, 0, 0, ROMTYPE_PICASSOIV, 0, 0, NULL,
461 	0xa8133e7e, 0xcafafb91,0x6f16b9f3,0xec9b49aa,0x4b40eb4e,0xeceb5b5b },
462 
463 	{ _T("A1060 BIOS 2.06"), 2, 6, 2, 6, _T("A1060\0"), 16384, 147, 0, 0, ROMTYPE_A1060, 0, 0, _T("380619-03"),
464 	0x185f2bbd, 0xeba74ad1,0x000a5351,0xa5d99179,0xbf75f831,0xac2d2402, NULL, NULL },
465 	{ _T("A2088 BIOS 3.4"), 3, 4, 3, 4, _T("A2088\0"), 16384, 148, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-04"),
466 	0x05552160, 0xd1defdee, 0x1c0eae41, 0x07d81e26, 0x74915cd2, 0x9d352f2e, NULL, NULL },
467 	{ _T("A2088 BIOS 3.5"), 3, 5, 3, 5, _T("A2088\0"), 16384, 158, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-04"),
468 	0xf8e1ad83, 0x45a2b7db,0x6e86fe80,0x5cfef63c,0x65c331a7,0x16a6e9e8, NULL, NULL },
469 	{ _T("A2088 BIOS 3.6.1"), 3, 61, 3, 61, _T("A2088\0"), 16384, 149, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-06"),
470 	0x5fd93e56, 0xc1b707a8,0xa62907d7,0x5299f10a,0xa60efd1f,0x44514b26, NULL, NULL },
471 	{ _T("A2088T BIOS 4.10"), 4, 10, 4, 11, _T("A2088T\0"), 32768, 150, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390657-02"),
472 	0x20c5d1a9, 0x08e3fbb7,0x28dfc514,0x24083313,0x373ea7a5,0xa2c3e965, NULL, NULL },
473 	{ _T("A2088T BIOS 4.11"), 4, 11, 4, 11, _T("A2088T\0"), 32768, 151, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390547-02"),
474 	0x074bc9b0, 0x2a3f56bc,0xe395f203,0x46eb68c4,0xade7153e,0x3e69f892, NULL, NULL },
475 	{ _T("A2088T BIOS 4.12"), 4, 12, 4, 12, _T("A2088T\0"), 32768, 152, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390547-03"),
476 	0x92447176, 0x582fa254,0x73aa2679,0xefcd41a5,0xbdadf1a2,0x6a87a75f, NULL, NULL },
477 	{ _T("A2286 BIOS 3.6"), 3, 6, 3, 6, _T("A2286\0"), 32768, 153, 0, 0, ROMTYPE_A2286, 0, 0, NULL,
478 	0x63d75f70, 0x9f5d6c78,0x656d2fe7,0x36608644,0x771b6d30,0x31083264, NULL, NULL },
479 	ALTROMPN(153, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("380682-03"), 0xb3f76402, 0xef9ba5f2, 0x2714ad6d, 0xfa5e0aef, 0x2d09ce83, 0x578ee26d)
480 	ALTROMPN(153, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("380683-03"), 0xab053693, 0x75229d80, 0x443fad78, 0xa298d04b, 0x37c8e6c3, 0x2c1b6df0)
481 	{ _T("A2286 BIOS 4.2"), 4, 2, 4, 2, _T("A2286\0"), 32768, 154, 0, 0, ROMTYPE_A2286, 0, 0, NULL,
482 	0xd572e205, 0x74fdf0f8,0x325fbc41,0x2b98c72d,0xf5095804,0x831c46b5, NULL, NULL },
483 	ALTROMPN(154, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("380682-04"), 0xc23dcd55, 0x38dc24b7, 0x14427b15, 0xd5214cc9, 0xb9be0de7, 0x20bd6a34)
484 	ALTROMPN(154, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("380683-04"), 0xdad80c0b, 0x12fe2916, 0x64f8c412, 0x3877a24e, 0x05837091, 0x44d8acd0)
485 	{ _T("A2386SX BIOS 1.0"), 1, 0, 1, 0, _T("A2386SX\0"), 65536, 155, 0, 0, ROMTYPE_A2386, 0, 0, NULL,
486 	0x37003e0c, 0x2e127e9c,0x8581d30c,0x2e46404b,0x21608e3c,0xe935fa27, NULL, NULL },
487 
488 	{ _T("Arcadia OnePlay 2.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 49, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
489 	{ _T("Arcadia TenPlay 2.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 50, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
490 	{ _T("Arcadia TenPlay 2.20"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 75, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
491 	{ _T("Arcadia OnePlay 3.00"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 51, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
492 	{ _T("Arcadia TenPlay 3.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 76, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
493 	{ _T("Arcadia TenPlay 4.00"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 77, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
494 
495 	{ _T("Arcadia SportTime Table Hockey v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 33, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
496 	{ _T("Arcadia SportTime Bowling v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 34, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
497 	{ _T("Arcadia World Darts v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 35, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
498 	{ _T("Arcadia Magic Johnson's Fast Break v2.8"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 36, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
499 	{ _T("Arcadia Leader Board Golf v2.4"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 37, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
500 	{ _T("Arcadia Leader Board Golf"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 38, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
501 	{ _T("Arcadia Ninja Mission v2.5"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 39, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
502 	{ _T("Arcadia Road Wars v2.3"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 40, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
503 	{ _T("Arcadia Sidewinder v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 41, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
504 	{ _T("Arcadia Spot v2.0"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 42, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
505 	{ _T("Arcadia Space Ranger v2.0"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 43, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
506 	{ _T("Arcadia Xenon v2.3"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 44, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
507 	{ _T("Arcadia World Trophy Soccer v3.0"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 45, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
508 	{ _T("Arcadia Blastaball v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 78, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
509 	{ _T("Arcadia Delta Command"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 79, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
510 	{ _T("Arcadia Pharaohs Match"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 80, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
511 	{ _T("Arcadia SportTime Table Hockey"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 81, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
512 	{ _T("Arcadia World Darts (bad)"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 82, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
513 	{ _T("Arcadia Magic Johnson's Fast Break v2.7"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 83, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
514 	{ _T("Arcadia Ninja Mission"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 84, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
515 	{ _T("Arcadia Sidewinder"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 85, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
516 	{ _T("Arcadia Leader Board Golf v2.5"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 86, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
517 	{ _T("Arcadia Aaargh"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 88, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2 },
518 
519 	{ NULL }
520 
521 };
522 
romlist_clear(void)523 void romlist_clear (void)
524 {
525 	int i;
526 	int mask = 0;
527 	struct romdata *parent;
528 	const TCHAR *pn;
529 
530 	xfree (rl);
531 	rl = 0;
532 	romlist_cnt = 0;
533 	parent = 0;
534 	pn = NULL;
535 	for (i = 0; roms[i].name; i++) {
536 		struct romdata *rd = &roms[i];
537 		if (rd->group == 0) {
538 			parent = rd;
539 			mask = rd->type;
540 			pn = parent->partnumber;
541 		} else {
542 			rd->type &= ~ROMTYPE_MASK;
543 			rd->type |= mask & ROMTYPE_MASK;
544 			if (rd->partnumber && !pn) {
545 				TCHAR *newpn;
546 				if (parent->partnumber == NULL)
547 					parent->partnumber = my_strdup (_T(""));
548 				newpn = xcalloc (TCHAR, _tcslen (parent->partnumber) + 1 + _tcslen (rd->partnumber) + 1);
549 				if (_tcslen (parent->partnumber) > 0) {
550 					_tcscpy (newpn, parent->partnumber);
551 					_tcscat (newpn, _T("/"));
552 				}
553 				_tcscat (newpn, rd->partnumber);
554 				xfree ((char *) parent->partnumber);
555 				parent->partnumber = newpn;
556 			}
557 		}
558 	}
559 }
560 
561 /* remove rom entries that need 2 or more roms but not everything required is present */
romlist_cleanup(void)562 static void romlist_cleanup (void)
563 {
564 	int i = 0;
565 	while (roms[i].name) {
566 		struct romdata *rd = &roms[i];
567 		int grp = rd->group >> 16;
568 		int ok = 1;
569 		int j = i;
570 		int k = i;
571 		while (rd->name && (rd->group >> 16) == grp && grp > 0) {
572 			struct romlist *rl = romlist_getrl (rd);
573 			if (!rl)
574 				ok = 0;
575 			rd++;
576 			j++;
577 		}
578 		if (ok == 0) {
579 			while (i < j) {
580 				struct romlist *rl2 = romlist_getrl (&roms[i]);
581 				if (rl2) {
582 					int cnt = romlist_cnt - (rl2 - rl) - 1;
583 					write_log (_T("%s '%s' removed from romlist\n"), roms[k].name, rl2->path);
584 					xfree (rl2->path);
585 					if (cnt > 0)
586 						memmove (rl2, rl2 + 1, cnt * sizeof (struct romlist));
587 					romlist_cnt--;
588 				}
589 				i++;
590 			}
591 		}
592 		i++;
593 	}
594 #if 0
595 	for (i = 0; i < romlist_cnt; i++) {
596 		struct romlist *rll = &rl[i];
597 		write_log (_T("%d: %08x %s (%s)\n"), rll->rd->id, rll->rd->group, rll->rd->name, rll->path);
598 	}
599 #endif
600 }
601 
getromlistbyident(int ver,int rev,int subver,int subrev,const TCHAR * model,int romflags,bool all)602 struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all)
603 {
604 	int i, j, ok, out, max;
605 	struct romdata *rd;
606 	struct romlist **rdout, *rltmp;
607 	void *buf;
608 
609 	for (i = 0; roms[i].name; i++);
610 	if (all)
611 		max = i;
612 	else
613 		max = romlist_cnt;
614 	buf = xmalloc (uae_u8, (sizeof (struct romlist*) + sizeof (struct romlist)) * (i + 1));
615 	rdout = (struct romlist**)buf;
616 	rltmp = (struct romlist*)((uae_u8*)buf + (i + 1) * sizeof (struct romlist*));
617 	out = 0;
618 	for (i = 0; i < max; i++) {
619 		ok = 0;
620 		if (!all)
621 			rd = rl[i].rd;
622 		else
623 			rd = &roms[i];
624 		if (rd->group)
625 			continue;
626 		if (model && !_tcsicmp (model, rd->name))
627 			ok = 2;
628 #ifdef FSUAE
629 		/* If we get an exact match by model name, we do not want to downgrade
630 		 * the match, otherwise we will fail the second model check below. */
631 		// FIXME: Should probably send this else fix upstream.
632 		else
633 #endif
634 		if ((ver < 0 || rd->ver == ver) && (rev < 0 || rd->rev == rev)) {
635 			if (subver >= 0) {
636 				if (rd->subver == subver && (subrev < 0 || rd->subrev == subrev) && rd->subver > 0)
637 					ok = 1;
638 			} else {
639 				ok = 1;
640 			}
641 		}
642 		if (!ok)
643 			continue;
644 		if (model && ok < 2) {
645 			const TCHAR *p = rd->model;
646 			ok = 0;
647 			while (p && *p) {
648 				if (!_tcscmp(rd->model, model)) {
649 					ok = 1;
650 					break;
651 				}
652 				p = p + _tcslen(p) + 1;
653 			}
654 		}
655 		if (romflags && (rd->type & romflags) == 0)
656 			ok = 0;
657 		if (ok) {
658 			if (all) {
659 				rdout[out++] = rltmp;
660 				rltmp->path = NULL;
661 				rltmp->rd = rd;
662 				rltmp++;
663 			} else {
664 				rdout[out++] = &rl[i];
665 			}
666 		}
667 	}
668 	if (out == 0) {
669 		xfree (rdout);
670 		return NULL;
671 	}
672 	for (i = 0; i < out; i++) {
673 		int v1 = rdout[i]->rd->subver * 1000 + rdout[i]->rd->subrev;
674 		for (j = i + 1; j < out; j++) {
675 			int v2 = rdout[j]->rd->subver * 1000 + rdout[j]->rd->subrev;
676 			if (v1 < v2) {
677 				struct romlist *rltmp = rdout[j];
678 				rdout[j] = rdout[i];
679 				rdout[i] = rltmp;
680 			}
681 		}
682 	}
683 	rdout[out] = NULL;
684 	return rdout;
685 }
686 
getarcadiarombyname(const TCHAR * name)687 struct romdata *getarcadiarombyname (const TCHAR *name)
688 {
689 	int i;
690 	for (i = 0; roms[i].name; i++) {
691 		if (roms[i].group == 0 && (roms[i].type == ROMTYPE_ARCADIAGAME || roms[i].type == ROMTYPE_ARCADIAGAME)) {
692 			const TCHAR *p = roms[i].name;
693 			p = p + _tcslen (p) + 1;
694 			if (_tcslen (name) >= _tcslen (p) + 4) {
695 				const TCHAR *p2 = name + _tcslen (name) - _tcslen (p) - 4;
696 				if (!memcmp (p, p2, _tcslen (p)) && !memcmp (p2 + _tcslen (p2) - 4, ".zip", 4))
697 					return &roms[i];
698 			}
699 		}
700 	}
701 	return NULL;
702 }
703 
getarcadiaroms(void)704 struct romlist **getarcadiaroms (void)
705 {
706 	int i, out, max;
707 	void *buf;
708 	struct romlist **rdout, *rltmp;
709 
710 	max = 0;
711 	for (i = 0; roms[i].name; i++) {
712 		if (roms[i].group == 0 && (roms[i].type == ROMTYPE_ARCADIABIOS || roms[i].type == ROMTYPE_ARCADIAGAME))
713 			max++;
714 	}
715 	buf = xmalloc (uae_u8, (sizeof (struct romlist*) + sizeof (struct romlist)) * (max + 1));
716 	rdout = (struct romlist**)buf;
717 	rltmp = (struct romlist*)((uae_u8*)buf + (max + 1) * sizeof (struct romlist*));
718 	out = 0;
719 	for (i = 0; roms[i].name; i++) {
720 		if (roms[i].group == 0 && (roms[i].type == ROMTYPE_ARCADIABIOS || roms[i].type == ROMTYPE_ARCADIAGAME)) {
721 			rdout[out++] = rltmp;
722 			rltmp->path = NULL;
723 			rltmp->rd = &roms[i];
724 			rltmp++;
725 		}
726 	}
727 	rdout[out] = NULL;
728 	return rdout;
729 }
730 
731 
kickstart_checksum_do(uae_u8 * mem,int size)732 static int kickstart_checksum_do (uae_u8 *mem, int size)
733 {
734 	uae_u32 cksum = 0, prevck = 0;
735 	int i;
736 	for (i = 0; i < size; i+=4) {
737 		uae_u32 data = mem[i]*65536*256 + mem[i+1]*65536 + mem[i+2]*256 + mem[i+3];
738 		cksum += data;
739 		if (cksum < prevck)
740 			cksum++;
741 		prevck = cksum;
742 	}
743 	return cksum == 0xffffffff;
744 }
745 
746 #define ROM_KEY_NUM 4
747 struct rom_key {
748 	uae_u8 *key;
749 	int size;
750 };
751 
752 static struct rom_key keyring[ROM_KEY_NUM];
753 
addkey(uae_u8 * key,int size,const TCHAR * name)754 static void addkey (uae_u8 *key, int size, const TCHAR *name)
755 {
756 	int i;
757 
758 	//write_log (_T("addkey(%08x,%d,'%s')\n"), key, size, name);
759 	if (key == NULL || size == 0) {
760 		xfree (key);
761 		return;
762 	}
763 	for (i = 0; i < ROM_KEY_NUM; i++) {
764 		if (keyring[i].key && keyring[i].size == size && !memcmp (keyring[i].key, key, size)) {
765 			xfree (key);
766 			//write_log (_T("key already in keyring\n"));
767 			return;
768 		}
769 	}
770 	for (i = 0; i < ROM_KEY_NUM; i++) {
771 		if (keyring[i].key == NULL)
772 			break;
773 	}
774 	if (i == ROM_KEY_NUM) {
775 		xfree (key);
776 		//write_log (_T("keyring full\n"));
777 		return;
778 	}
779 	keyring[i].key = key;
780 	keyring[i].size = size;
781 }
782 
addkeyfile(const TCHAR * path)783 void addkeyfile (const TCHAR *path)
784 {
785 	struct zfile *f;
786 	int keysize;
787 	uae_u8 *keybuf;
788 
789 	f = zfile_fopen (path, _T("rb"), ZFD_NORMAL);
790 	if (!f)
791 		return;
792 	zfile_fseek (f, 0, SEEK_END);
793 	keysize = zfile_ftell (f);
794 	if (keysize > 0) {
795 		zfile_fseek (f, 0, SEEK_SET);
796 		keybuf = xmalloc (uae_u8, keysize);
797 		zfile_fread (keybuf, 1, keysize, f);
798 		addkey (keybuf, keysize, path);
799 	}
800 	zfile_fclose (f);
801 }
802 
addkeydir(const TCHAR * path)803 void addkeydir (const TCHAR *path)
804 {
805 	TCHAR tmp[MAX_DPATH];
806 
807 	_tcscpy (tmp, path);
808 	if (zfile_exists (tmp)) {
809 		int i;
810 		for (i = _tcslen (tmp) - 1; i > 0; i--) {
811 			if (tmp[i] == '\\' || tmp[i] == '/')
812 				break;
813 		}
814 		tmp[i] = 0;
815 	}
816 	_tcscat (tmp, _T("/"));
817 	_tcscat (tmp, _T("rom.key"));
818 	addkeyfile (tmp);
819 }
820 
get_keyring(void)821 int get_keyring (void)
822 {
823 	int i, num = 0;
824 	for (i = 0; i < ROM_KEY_NUM; i++) {
825 		if (keyring[i].key)
826 			num++;
827 	}
828 	return num;
829 }
830 
load_keyring(struct uae_prefs * p,const TCHAR * path)831 int load_keyring (struct uae_prefs *p, const TCHAR *path)
832 {
833 	uae_u8 *keybuf;
834 	int keysize;
835 	TCHAR tmp[MAX_PATH], *d;
836 	int keyids[] = { 0, 48, 73, -1 };
837 	int cnt, i;
838 
839 	free_keyring ();
840 	keybuf = target_load_keyfile (p, path, &keysize, tmp);
841 	addkey (keybuf, keysize, tmp);
842 	for (i = 0; keyids[i] >= 0; i++) {
843 		struct romdata *rd = getromdatabyid (keyids[i]);
844 		TCHAR *s;
845 		if (rd) {
846 			s = romlist_get (rd);
847 			if (s)
848 				addkeyfile (s);
849 		}
850 	}
851 
852 	cnt = 0;
853 	for (;;) {
854 		keybuf = NULL;
855 		keysize = 0;
856 		tmp[0] = 0;
857 		switch (cnt)
858 		{
859 		case 0:
860 			if (path)
861 				_tcscpy (tmp, path);
862 			break;
863 		case 1:
864 			_tcscat (tmp, _T("rom.key"));
865 			break;
866 		case 2:
867 			if (p) {
868 				_tcscpy (tmp, p->path_rom.path[0]);
869 				_tcscat (tmp, _T("rom.key"));
870 			}
871 			break;
872 		case 3:
873 			_tcscpy (tmp, _T("roms/rom.key"));
874 			break;
875 		case 4:
876 			_tcscpy (tmp, start_path_data);
877 			_tcscat (tmp, _T("rom.key"));
878 			break;
879 		case 5:
880 			_stprintf (tmp, _T("%s../shared/rom/rom.key"), start_path_data);
881 			break;
882 		case 6:
883 			if (p) {
884 				for (i = 0; uae_archive_extensions[i]; i++) {
885 					if (_tcsstr (p->romfile, uae_archive_extensions[i]))
886 						break;
887 				}
888 				if (!uae_archive_extensions[i]) {
889 					_tcscpy (tmp, p->romfile);
890 					d = _tcsrchr (tmp, '/');
891 					if (!d)
892 						d = _tcsrchr (tmp, '\\');
893 					if (d)
894 						_tcscpy (d + 1, _T("rom.key"));
895 				}
896 			}
897 			break;
898 		case 7:
899 			return get_keyring ();
900 		}
901 		cnt++;
902 		if (!tmp[0])
903 			continue;
904 		addkeyfile (tmp);
905 	}
906 }
free_keyring(void)907 void free_keyring (void)
908 {
909 	int i;
910 	for (i = 0; i < ROM_KEY_NUM; i++)
911 		xfree (keyring[i].key);
912 	memset (keyring, 0, sizeof (struct rom_key) * ROM_KEY_NUM);
913 }
914 
getromdatabyname(const TCHAR * name)915 struct romdata *getromdatabyname (const TCHAR *name)
916 {
917 	TCHAR tmp[MAX_PATH];
918 	int i = 0;
919 	while (roms[i].name) {
920 		if (!roms[i].group) {
921 			getromname (&roms[i], tmp);
922 			if (!_tcscmp (tmp, name) || !_tcscmp (roms[i].name, name))
923 				return &roms[i];
924 		}
925 		i++;
926 	}
927 	return 0;
928 }
929 
getromdatabyid(int id)930 struct romdata *getromdatabyid (int id)
931 {
932 	int i = 0;
933 	while (roms[i].name) {
934 		if (id == roms[i].id && roms[i].group == 0)
935 			return &roms[i];
936 		i++;
937 	}
938 	return 0;
939 }
940 
getromdatabyidgroup(int id,int group,int subitem)941 struct romdata *getromdatabyidgroup (int id, int group, int subitem)
942 {
943 	int i = 0;
944 	group = (group << 16) | subitem;
945 	while (roms[i].name) {
946 		if (id == roms[i].id && roms[i].group == group)
947 			return &roms[i];
948 		i++;
949 	}
950 	return 0;
951 }
952 
notcrc32(uae_u32 crc32)953 STATIC_INLINE int notcrc32 (uae_u32 crc32)
954 {
955 	if (crc32 == 0xffffffff || crc32 == 0x00000000)
956 		return 1;
957 	return 0;
958 }
959 
getromdatabycrc(uae_u32 crc32,bool allowgroup)960 struct romdata *getromdatabycrc (uae_u32 crc32, bool allowgroup)
961 {
962 	int i = 0;
963 	while (roms[i].name) {
964 		if (roms[i].group == 0 && crc32 == roms[i].crc32 && !notcrc32(crc32))
965 			return &roms[i];
966 		i++;
967 	}
968 	if (allowgroup) {
969 		i = 0;
970 		while (roms[i].name) {
971 			if (roms[i].group && crc32 == roms[i].crc32 && !notcrc32(crc32))
972 				return &roms[i];
973 			i++;
974 		}
975 	}
976 	return 0;
977 }
getromdatabycrc(uae_u32 crc32)978 struct romdata *getromdatabycrc (uae_u32 crc32)
979 {
980 	return getromdatabycrc (crc32, false);
981 }
982 
cmpsha1(const uae_u8 * s1,const struct romdata * rd)983 static int cmpsha1 (const uae_u8 *s1, const struct romdata *rd)
984 {
985 	int i;
986 
987 	for (i = 0; i < SHA1_SIZE / 4; i++) {
988 		uae_u32 v1 = (s1[0] << 24) | (s1[1] << 16) | (s1[2] << 8) | (s1[3] << 0);
989 		uae_u32 v2 = rd->sha1[i];
990 		if (v1 != v2)
991 			return -1;
992 		s1 += 4;
993 	}
994 	return 0;
995 }
996 
getfrombydefaultname(const TCHAR * name,int size)997 struct romdata *getfrombydefaultname(const TCHAR *name, int size)
998 {
999 	int i = 0;
1000 	while (roms[i].name) {
1001 		if (notcrc32(roms[i].crc32) && size >= roms[i].size && roms[i].defaultfilename && !_tcsicmp(roms[i].defaultfilename, name)) {
1002 			return &roms[i];
1003 		}
1004 		i++;
1005 	}
1006 	return NULL;
1007 }
1008 
checkromdata(const uae_u8 * sha1,int size,uae_u32 mask)1009 static struct romdata *checkromdata (const uae_u8 *sha1, int size, uae_u32 mask)
1010 {
1011 	int i = 0;
1012 	while (roms[i].name) {
1013 		if (!notcrc32(roms[i].crc32) && roms[i].size >= size) {
1014 			if (roms[i].type & mask) {
1015 				if (!cmpsha1 (sha1, &roms[i]))
1016 					return &roms[i];
1017 			}
1018 		}
1019 		i++;
1020 	}
1021 	return NULL;
1022 }
1023 
decode_cloanto_rom_do(uae_u8 * mem,int size,int real_size)1024 int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size)
1025 {
1026 	int cnt, t, i;
1027 
1028 	for (i = ROM_KEY_NUM - 1; i >= 0; i--) {
1029 		uae_u8 sha1[SHA1_SIZE];
1030 		struct romdata *rd;
1031 		int keysize = keyring[i].size;
1032 		uae_u8 *key = keyring[i].key;
1033 		if (!key)
1034 			continue;
1035 		for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize)  {
1036 			mem[cnt] ^= key[t];
1037 			if (real_size == cnt + 1)
1038 				t = keysize - 1;
1039 		}
1040 		if ((mem[2] == 0x4e && mem[3] == 0xf9) || (mem[0] == 0x11 && (mem[1] == 0x11 || mem[1] == 0x14))) {
1041 			cloanto_rom = 1;
1042 			return 1;
1043 		}
1044 		get_sha1 (mem, size, sha1);
1045 		rd = checkromdata (sha1, size, -1);
1046 		if (rd) {
1047 			if (rd->cloanto)
1048 				cloanto_rom = 1;
1049 			return 1;
1050 		}
1051 		if (i == 0)
1052 			break;
1053 		for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize)  {
1054 			mem[cnt] ^= key[t];
1055 			if (real_size == cnt + 1)
1056 				t = keysize - 1;
1057 		}
1058 	}
1059 	return 0;
1060 }
1061 
decode_rekick_rom_do(uae_u8 * mem,int size,int real_size)1062 static int decode_rekick_rom_do (uae_u8 *mem, int size, int real_size)
1063 {
1064 	uae_u32 d1 = 0xdeadfeed, d0;
1065 	int i;
1066 
1067 	for (i = 0; i < size / 8; i++) {
1068 		d0 = ((mem[i * 8 + 0] << 24) | (mem[i * 8 + 1] << 16) | (mem[i * 8 + 2] << 8) | mem[i * 8 + 3]);
1069 		d1 = d1 ^ d0;
1070 		mem[i * 8 + 0] = d1 >> 24;
1071 		mem[i * 8 + 1] = d1 >> 16;
1072 		mem[i * 8 + 2] = d1 >> 8;
1073 		mem[i * 8 + 3] = d1;
1074 		d1 = ((mem[i * 8 + 4] << 24) | (mem[i * 8 + 5] << 16) | (mem[i * 8 + 6] << 8) | mem[i * 8 + 7]);
1075 		d0 = d0 ^ d1;
1076 		mem[i * 8 + 4] = d0 >> 24;
1077 		mem[i * 8 + 5] = d0 >> 16;
1078 		mem[i * 8 + 6] = d0 >> 8;
1079 		mem[i * 8 + 7] = d0;
1080 	}
1081 	return 1;
1082 }
1083 
decode_rom(uae_u8 * mem,int size,int mode,int real_size)1084 int decode_rom (uae_u8 *mem, int size, int mode, int real_size)
1085 {
1086 	if (mode == 1) {
1087 		if (!decode_cloanto_rom_do (mem, size, real_size)) {
1088 #ifndef SINGLEFILE
1089 			notify_user (NUMSG_NOROMKEY);
1090 #endif
1091 			return 0;
1092 		}
1093 		return 1;
1094 	} else if (mode == 2) {
1095 		decode_rekick_rom_do (mem, size, real_size);
1096 		return 1;
1097 	}
1098 	return 0;
1099 }
1100 
getromdatabydata(uae_u8 * rom,int size)1101 struct romdata *getromdatabydata (uae_u8 *rom, int size)
1102 {
1103 	uae_u8 sha1[SHA1_SIZE];
1104 	uae_u8 tmp[4];
1105 	uae_u8 *tmpbuf = NULL;
1106 	struct romdata *ret = NULL;
1107 
1108 	if (size > 11 && !memcmp (rom, "AMIROMTYPE1", 11)) {
1109 		uae_u8 *tmpbuf = xmalloc (uae_u8, size);
1110 		int tmpsize = size - 11;
1111 		memcpy (tmpbuf, rom + 11, tmpsize);
1112 		decode_rom (tmpbuf, tmpsize, 1, tmpsize);
1113 		rom = tmpbuf;
1114 		size = tmpsize;
1115 	}
1116 #if 0
1117 	if (size > 0x6c + 524288 && !memcmp (rom, "AMIG", 4)) {
1118 		uae_u8 *tmpbuf = (uae_u8*)xmalloc (uae_u8, size);
1119 		int tmpsize = size - 0x6c;
1120 		memcpy (tmpbuf, rom + 0x6c, tmpsize);
1121 		decode_rom (tmpbuf, tmpsize, 2, tmpsize);
1122 		rom = tmpbuf;
1123 		size = tmpsize;
1124 	}
1125 #endif
1126 	get_sha1 (rom, size, sha1);
1127 	ret = checkromdata(sha1, size, -1);
1128 	if (!ret) {
1129 		get_sha1 (rom, size / 2, sha1);
1130 		ret = checkromdata (sha1, size / 2, -1);
1131 		if (!ret) {
1132 			/* ignore AR2/3 IO-port range until we have full dump */
1133 			memcpy (tmp, rom, 4);
1134 			memset (rom, 0, 4);
1135 			get_sha1 (rom, size, sha1);
1136 			ret = checkromdata (sha1, size, ROMTYPE_AR2);
1137 			memcpy (rom, tmp, 4);
1138 		}
1139 	}//9
1140 	xfree (tmpbuf);
1141 	return ret;
1142 }
1143 
getromdatabyzfile(struct zfile * f)1144 struct romdata *getromdatabyzfile (struct zfile *f)
1145 {
1146 	int pos, size;
1147 	uae_u8 *p;
1148 	struct romdata *rd;
1149 
1150 	pos = zfile_ftell (f);
1151 	zfile_fseek (f, 0, SEEK_END);
1152 	size = zfile_ftell (f);
1153 	if (size > 2048 * 1024)
1154 		return NULL;
1155 	p = xmalloc (uae_u8, size);
1156 	if (!p)
1157 		return NULL;
1158 	memset (p, 0, size);
1159 	zfile_fseek (f, 0, SEEK_SET);
1160 	zfile_fread (p, 1, size, f);
1161 	zfile_fseek (f, pos, SEEK_SET);
1162 	rd = getromdatabydata (p, size);
1163 	xfree (p);
1164 	return rd;
1165 }
1166 
getromname(const struct romdata * rd,TCHAR * name)1167 void getromname	(const struct romdata *rd, TCHAR *name)
1168 {
1169 	name[0] = 0;
1170 	if (!rd)
1171 		return;
1172 	while (rd->group)
1173 		rd--;
1174 	_tcscat (name, rd->name);
1175 	if ((rd->subrev || rd->subver) && rd->subver != rd->ver)
1176 		_stprintf (name + _tcslen (name), _T(" rev %d.%d"), rd->subver, rd->subrev);
1177 	if (rd->size > 0)
1178 		_stprintf (name + _tcslen (name), _T(" (%dk)"), (rd->size + 1023) / 1024);
1179 	if (rd->partnumber && _tcslen (rd->partnumber) > 0)
1180 		_stprintf (name + _tcslen (name), _T(" [%s]"), rd->partnumber);
1181 }
1182 
getromlistbyromdata(const struct romdata * rd)1183 struct romlist *getromlistbyromdata (const struct romdata *rd)
1184 {
1185 	int ids[2];
1186 
1187 	ids[0] = rd->id;
1188 	ids[1] = -1;
1189 	return getromlistbyids(ids, NULL);
1190 }
1191 
getromlistbyromtype(uae_u32 romtype)1192 struct romlist *getromlistbyromtype(uae_u32 romtype)
1193 {
1194 	int i = 0;
1195 	while (roms[i].name) {
1196 		if (roms[i].type == romtype) {
1197 			struct romdata *rd = &roms[i];
1198 			for (int j = 0; j < romlist_cnt; j++) {
1199 				if (rl[j].rd->id == rd->id)
1200 					return &rl[j];
1201 			}
1202 		}
1203 		i++;
1204 	}
1205 	return NULL;
1206 }
1207 
getromlistbyids(const int * ids,const TCHAR * romname)1208 struct romlist *getromlistbyids (const int *ids, const TCHAR *romname)
1209 {
1210 	struct romdata *rd;
1211 	int i, j;
1212 
1213 	i = 0;
1214 	if (romname) {
1215 		while (ids[i] >= 0) {
1216 			rd = getromdatabyid (ids[i]);
1217 			if (rd) {
1218 				for (j = 0; j < romlist_cnt; j++) {
1219 					if (rl[j].rd->id == rd->id) {
1220 						if (my_issamepath(rl[j].path, romname))
1221 							return &rl[j];
1222 					}
1223 				}
1224 			}
1225 			i++;
1226 		}
1227 	}
1228 	i = 0;
1229 	while (ids[i] >= 0) {
1230 		rd = getromdatabyid (ids[i]);
1231 		if (rd) {
1232 			for (j = 0; j < romlist_cnt; j++) {
1233 				if (rl[j].rd->id == rd->id)
1234 					return &rl[j];
1235 			}
1236 		}
1237 		i++;
1238 	}
1239 	return NULL;
1240 }
1241 
getromdatabyids(const int * ids)1242 struct romdata *getromdatabyids (const int *ids)
1243 {
1244 	struct romdata *rd;
1245 	int i;
1246 
1247 	i = 0;
1248 	while (ids[i] >= 0) {
1249 		rd = getromdatabyid (ids[i]);
1250 		if (rd)
1251 			return rd;
1252 		i++;
1253 	}
1254 	return NULL;
1255 }
1256 
romwarning(const int * ids)1257 void romwarning (const int *ids)
1258 {
1259 	int i, exp;
1260 	TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
1261 	TCHAR tmp3[MAX_DPATH];
1262 
1263 	if (ids[0] == -1)
1264 		return;
1265 	exp = 0;
1266 	tmp2[0] = 0;
1267 	i = 0;
1268 	while (ids[i] >= 0) {
1269 		struct romdata *rd = getromdatabyid (ids[i]);
1270 		if (!(rd->type & ROMTYPE_NONE)) {
1271 			getromname (rd, tmp1);
1272 			_tcscat (tmp2, _T("- "));
1273 			_tcscat (tmp2, tmp1);
1274 			_tcscat (tmp2, _T("\n"));
1275 			if (rd->type & (ROMTYPE_SCSI | ROMTYPE_CPUBOARD | ROMTYPE_CD32CART))
1276 				exp++;
1277 		}
1278 		i++;
1279 	}
1280 	translate_message (exp ? NUMSG_EXPROMNEED : NUMSG_ROMNEED, tmp3);
1281 	gui_message (tmp3, tmp2);
1282 }
1283 
1284 
byteswap(uae_u8 * buf,int size)1285 static void byteswap (uae_u8 *buf, int size)
1286 {
1287 	int i;
1288 	for (i = 0; i < size; i += 2) {
1289 		uae_u8 t = buf[i];
1290 		buf[i] = buf[i + 1];
1291 		buf[i + 1] = t;
1292 	}
1293 }
wordbyteswap(uae_u8 * buf,int size)1294 static void wordbyteswap (uae_u8 *buf, int size)
1295 {
1296 	int i;
1297 	for (i = 0; i < size; i += 4) {
1298 		uae_u8 t;
1299 		t = buf[i + 0];
1300 		buf[i + 0] = buf[i + 2];
1301 		buf[i + 2] = t;
1302 		t = buf[i + 1];
1303 		buf[i + 1] = buf[i + 3];
1304 		buf[i + 3] = t;
1305 	}
1306 }
1307 
mergecd32(uae_u8 * dst,uae_u8 * src,int size)1308 static void mergecd32 (uae_u8 *dst, uae_u8 *src, int size)
1309 {
1310 	int i, k;
1311 	k = 0;
1312 	for (i = 0; i < size / 2; i += 2) {
1313 		int j = i + size / 2;
1314 		dst[k + 1] = src[i + 0];
1315 		dst[k + 0] = src[i + 1];
1316 		dst[k + 3] = src[j + 0];
1317 		dst[k + 2] = src[j + 1];
1318 		k += 4;
1319 	}
1320 #if 0
1321 	{
1322 		struct zfile *f;
1323 		f = zfile_fopen ("c:\\d\\1.rom","wb", ZFD_NORMAL);
1324 		zfile_fwrite (dst, 1, size, f);
1325 		zfile_fclose(f);
1326 	}
1327 #endif
1328 }
1329 
descramble(const struct romdata * rd,uae_u8 * data,int size,int odd)1330 static void descramble (const struct romdata *rd, uae_u8 *data, int size, int odd)
1331 {
1332 	int flags = rd->type;
1333 
1334 	if (flags & (ROMTYPE_NORDIC | ROMTYPE_XPOWER))
1335 		descramble_nordicpro (data, size, odd);
1336 }
1337 
read_rom_file(uae_u8 * buf,const struct romdata * rd)1338 static int read_rom_file (uae_u8 *buf, const struct romdata *rd)
1339 {
1340 	struct zfile *zf;
1341 	struct romlist *rl = romlist_getrl (rd);
1342 	uae_char tmp[11];
1343 #ifdef FSUAE
1344 	write_log("read_rom_file\n");
1345 #endif
1346 
1347 	if (!rl || _tcslen (rl->path) == 0)
1348 		return 0;
1349 #ifdef FSUAE
1350 	write_log("read_rom_file (rl->path: '%s')\n", rl->path);
1351 #endif
1352 	zf = zfile_fopen (rl->path, _T("rb"), ZFD_NORMAL);
1353 	if (!zf)
1354 		return 0;
1355 	addkeydir (rl->path);
1356 	zfile_fread (tmp, sizeof tmp, 1, zf);
1357 	if (!memcmp (tmp, "AMIROMTYPE1", sizeof tmp)) {
1358 		zfile_fread (buf, rd->size, 1, zf);
1359 		decode_cloanto_rom_do (buf, rd->size, rd->size);
1360 	} else {
1361 		memcpy (buf, tmp, sizeof tmp);
1362 		zfile_fread (buf + sizeof tmp, rd->size - sizeof (tmp), 1, zf);
1363 	}
1364 #ifdef FSUAE
1365 	romlist_patch_rom(buf, rd->size);
1366 #endif
1367 	zfile_fclose (zf);
1368 	return 1;
1369 }
1370 
1371 #if SAVE_ROM
save_rom(uae_u8 * rom,int size)1372 static void save_rom(uae_u8 *rom, int size)
1373 {
1374 	struct zfile *f;
1375 	f = zfile_fopen (_T("c:\\temp\\1.rom"), _T("wb"));
1376 	zfile_fwrite (rom, 1, size, f);
1377 	zfile_fclose(f);
1378 }
1379 #endif
1380 
read_rom(struct romdata * prd)1381 struct zfile *read_rom (struct romdata *prd)
1382 {
1383 	struct romdata *rd2 = prd;
1384 	struct romdata *rd = prd;
1385 	struct romdata *rdpair = NULL;
1386 	const TCHAR *name;
1387 	int id = rd->id;
1388 	uae_u32 crc32;
1389 	int size;
1390 	uae_u8 *buf, *buf2;
1391 #ifdef FSUAE
1392 	write_log("read_rom '%s'\n", prd->name);
1393 #endif
1394 
1395 	/* find parent node */
1396 	for (;;) {
1397 		if (rd2 == &roms[0])
1398 			break;
1399 		if (rd2[-1].id != id)
1400 			break;
1401 		rd2--;
1402 	}
1403 
1404 	size = rd2->size;
1405 	crc32 = rd2->crc32;
1406 	name = rd->name;
1407 	buf = xmalloc (uae_u8, size * 2);
1408 	memset (buf, 0xff, size * 2);
1409 	if (!buf)
1410 		return NULL;
1411 	buf2 = buf + size;
1412 	while (rd->id == id) {
1413 		int i, j, add;
1414 		int ok = 0;
1415 		uae_u32 flags = rd->type;
1416 		int odd = (flags & ROMTYPE_ODD) ? 1 : 0;
1417 
1418 		add = 0;
1419 		for (i = 0; i < 2; i++) {
1420 			memset (buf, 0, size);
1421 			if (!(flags & (ROMTYPE_EVEN | ROMTYPE_ODD))) {
1422 				read_rom_file (buf, rd);
1423 				if (flags & ROMTYPE_CD32) {
1424 					memcpy (buf2, buf, size);
1425 					mergecd32 (buf, buf2, size);
1426 				}
1427 				add = 1;
1428 				i++;
1429 			} else if (flags & ROMTYPE_QUAD) {
1430 				if (i == 0) {
1431 					for (int k = 0; k < 4; k++) {
1432 						read_rom_file (buf2, rd2 + k + 1);
1433 						for (j = 0; j < size; j += 4)
1434 							buf[j + k] = buf2[j / 4];
1435 					}
1436 				} else {
1437 					for (int kk = 0; kk < 2; kk++) {
1438 						for (int k = 0; k < 2; k++) {
1439 							read_rom_file (buf2, rd2 + k + kk * 2 + 1);
1440 							for (j = 0; j < size / 2; j += 2) {
1441 								buf[j + k + kk * (rd2->size / 2)] = buf2[j / 2];
1442 							}
1443 						}
1444 					}
1445 				}
1446 				add = 4;
1447 			} else {
1448 				int romsize = size / 2;
1449 				if (i)
1450 					odd = !odd;
1451 				if (rd->id == rd[1].id)
1452 					rdpair = &rd[1];
1453 				else if (rd != roms)
1454 					rdpair = &rd[-1];
1455 				else
1456 					rdpair = rd;
1457 				if (flags & ROMTYPE_8BIT) {
1458 					read_rom_file (buf2, rd);
1459 					if (flags & ROMTYPE_BYTESWAP)
1460 						byteswap (buf2, romsize);
1461 					if (flags & ROMTYPE_SCRAMBLED)
1462 						descramble (rd, buf2, romsize, odd);
1463 					for (j = 0; j < size; j += 2)
1464 						buf[j + odd] = buf2[j / 2];
1465 					read_rom_file (buf2, rdpair);
1466 					if (flags & ROMTYPE_BYTESWAP)
1467 						byteswap (buf2, romsize);
1468 					if (flags & ROMTYPE_SCRAMBLED)
1469 						descramble (rd + 1, buf2, romsize, !odd);
1470 					for (j = 0; j < size; j += 2)
1471 						buf[j + (1 - odd)] = buf2[j / 2];
1472 				} else {
1473 					read_rom_file (buf2, rd);
1474 					if (flags & ROMTYPE_BYTESWAP)
1475 						byteswap (buf2, romsize);
1476 					if (flags & ROMTYPE_SCRAMBLED)
1477 						descramble (rd, buf2, romsize, odd);
1478 					for (j = 0; j < size; j += 4) {
1479 						buf[j + 2 * odd + 0] = buf2[j / 2 + 0];
1480 						buf[j + 2 * odd + 1] = buf2[j / 2 + 1];
1481 					}
1482 					read_rom_file (buf2, rdpair);
1483 					if (flags & ROMTYPE_BYTESWAP)
1484 						byteswap (buf2, romsize);
1485 					if (flags & ROMTYPE_SCRAMBLED)
1486 						descramble (rd + 1, buf2, romsize, !odd);
1487 					for (j = 0; j < size; j += 4) {
1488 						buf[j + 2 * (1 - odd) + 0] = buf2[j / 2 + 0];
1489 						buf[j + 2 * (1 - odd) + 1] = buf2[j / 2 + 1];
1490 					}
1491 				}
1492 				add = 2;
1493 			}
1494 
1495 #if SAVE_ROM
1496 			save_rom(buf, size);
1497 #endif
1498 
1499 			if (notcrc32(crc32) || get_crc32(buf, size) == crc32) {
1500 				ok = 1;
1501 			}
1502 			if (!ok && (rd->type & ROMTYPE_AR)) {
1503 				uae_u8 tmp[2];
1504 				tmp[0] = buf[0];
1505 				tmp[1] = buf[1];
1506 				buf[0] = buf[1] = 0;
1507 				if (get_crc32 (buf, size) == crc32)
1508 					ok = 1;
1509 				buf[0] = tmp[0];
1510 				buf[1] = tmp[1];
1511 			}
1512 			if (!ok) {
1513 				/* perhaps it is byteswapped without byteswap entry? */
1514 				byteswap (buf, size);
1515 				if (get_crc32 (buf, size) == crc32)
1516 					ok = 1;
1517 				if (!ok)
1518 					byteswap(buf, size);
1519 			}
1520 			if (ok) {
1521 				struct zfile *zf = zfile_fopen_empty (NULL, name, size);
1522 				if (zf) {
1523 					zfile_fwrite (buf, size, 1, zf);
1524 					zfile_fseek (zf, 0, SEEK_SET);
1525 				}
1526 				xfree (buf);
1527 				return zf;
1528 			}
1529 		}
1530 		rd += add;
1531 
1532 	}
1533 	xfree (buf);
1534 	return NULL;
1535 }
1536 
rom_fopen(const TCHAR * name,const TCHAR * mode,int mask)1537 struct zfile *rom_fopen (const TCHAR *name, const TCHAR *mode, int mask)
1538 {
1539 	struct zfile *f;
1540 	//write_log (_T("attempting to load '%s'\n"), name);
1541 	f = zfile_fopen (name, mode, mask);
1542 	//write_log (_T("=%p\n"), f);
1543 	return f;
1544 }
1545 
read_rom_name(const TCHAR * filename)1546 struct zfile *read_rom_name (const TCHAR *filename)
1547 {
1548 	int i;
1549 	struct zfile *f;
1550 #ifdef FSUAE
1551 		write_log("read_rom_name %s\n", filename);
1552 #endif
1553 
1554 	for (i = 0; i < romlist_cnt; i++) {
1555 #ifdef FSUAE
1556 		// FIXME: implement my_issamepath
1557 #endif
1558 		if (my_issamepath(filename, rl[i].path)) {
1559 			struct romdata *rd = rl[i].rd;
1560 			f = read_rom (rd);
1561 			if (f)
1562 				return f;
1563 		}
1564 	}
1565 	f = rom_fopen (filename, _T("rb"), ZFD_NORMAL);
1566 	if (f) {
1567 		uae_u8 tmp[11];
1568 		zfile_fread (tmp, sizeof tmp, 1, f);
1569 		if (!memcmp (tmp, "AMIROMTYPE1", sizeof tmp)) {
1570 			struct zfile *df;
1571 			int size;
1572 			uae_u8 *buf;
1573 			addkeydir (filename);
1574 			zfile_fseek (f, 0, SEEK_END);
1575 			size = zfile_ftell (f) - sizeof tmp;
1576 			zfile_fseek (f, sizeof tmp, SEEK_SET);
1577 			buf = xmalloc (uae_u8, size);
1578 			zfile_fread (buf, size, 1, f);
1579 			df = zfile_fopen_empty (f, _T("tmp.rom"), size);
1580 			decode_cloanto_rom_do (buf, size, size);
1581 #ifdef FSUAE
1582 			romlist_patch_rom(buf, size);
1583 #endif
1584 			zfile_fwrite (buf, size, 1, df);
1585 			zfile_fclose (f);
1586 			xfree (buf);
1587 			zfile_fseek (df, 0, SEEK_SET);
1588 			f = df;
1589 		} else {
1590 			zfile_fseek (f, -((int)sizeof tmp), SEEK_CUR);
1591 		}
1592 	}
1593 	return f;
1594 }
1595 
read_rom_name_guess(const TCHAR * filename)1596 struct zfile *read_rom_name_guess (const TCHAR *filename)
1597 {
1598 	int i, j;
1599 	struct zfile *f;
1600 	const TCHAR *name;
1601 
1602 	for (i = _tcslen (filename) - 1; i >= 0; i--) {
1603 		if (filename[i] == '/' || filename[i] == '\\')
1604 			break;
1605 	}
1606 	if (i < 0)
1607 		return NULL;
1608 	name = &filename[i];
1609 
1610 	for (i = 0; i < romlist_cnt; i++) {
1611 		TCHAR *n = rl[i].path;
1612 		for (j = _tcslen (n) - 1; j >= 0; j--) {
1613 			if (n[j] == '/' || n[j] == '\\')
1614 				break;
1615 		}
1616 		if (j < 0)
1617 			continue;
1618 		if (!_tcsicmp (name, n + j)) {
1619 			struct romdata *rd = rl[i].rd;
1620 			f = read_rom (rd);
1621 			if (f) {
1622 				write_log (_T("ROM %s not found, using %s\n"), filename, rl[i].path);
1623 				return f;
1624 			}
1625 		}
1626 	}
1627 	return NULL;
1628 }
1629 
kickstart_fix_checksum(uae_u8 * mem,int size)1630 void kickstart_fix_checksum (uae_u8 *mem, int size)
1631 {
1632 	uae_u32 cksum = 0, prevck = 0;
1633 	int i, ch = size == 524288 ? 0x7ffe8 : (size == 262144 ? 0x3ffe8 : 0x3e);
1634 
1635 	mem[ch] = 0;
1636 	mem[ch + 1] = 0;
1637 	mem[ch + 2] = 0;
1638 	mem[ch + 3] = 0;
1639 	for (i = 0; i < size; i+=4) {
1640 		uae_u32 data = (mem[i] << 24) | (mem[i + 1] << 16) | (mem[i + 2] << 8) | mem[i + 3];
1641 		cksum += data;
1642 		if (cksum < prevck)
1643 			cksum++;
1644 		prevck = cksum;
1645 	}
1646 	cksum ^= 0xffffffff;
1647 	mem[ch++] = cksum >> 24;
1648 	mem[ch++] = cksum >> 16;
1649 	mem[ch++] = cksum >> 8;
1650 	mem[ch++] = cksum >> 0;
1651 }
1652 
kickstart_checksum(uae_u8 * mem,int size)1653 int kickstart_checksum (uae_u8 *mem, int size)
1654 {
1655 	if (!kickstart_checksum_do (mem, size)) {
1656 #ifndef	SINGLEFILE
1657 		notify_user (NUMSG_KSROMCRCERROR);
1658 #endif
1659 		return 0;
1660 	}
1661 	return 1;
1662 }
1663 
configure_rom(struct uae_prefs * p,const int * rom,int msg)1664 int configure_rom (struct uae_prefs *p, const int *rom, int msg)
1665 {
1666 	struct romdata *rd;
1667 	TCHAR *path = 0;
1668 	int i;
1669 
1670 	if (rom[0] < 0)
1671 		return 1;
1672 	i = 0;
1673 	while (rom[i] >= 0) {
1674 		rd = getromdatabyid (rom[i]);
1675 		if (!rd) {
1676 			i++;
1677 			continue;
1678 		}
1679 		path = romlist_get (rd);
1680 		if (path)
1681 			break;
1682 		i++;
1683 	}
1684 	if (!path) {
1685 		if (msg)
1686 			romwarning(rom);
1687 		return 0;
1688 	}
1689 	if (rd->type & (ROMTYPE_KICK | ROMTYPE_KICKCD32))
1690 		_tcscpy (p->romfile, path);
1691 	if (rd->type & (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS))
1692 		_tcscpy (p->romextfile, path);
1693 	if (rd->type & (ROMTYPE_CD32CART | ROMTYPE_ARCADIAGAME) ||
1694 		rd->type == ROMTYPE_HRTMON || rd->type == ROMTYPE_XPOWER || rd->type ==  ROMTYPE_NORDIC || rd->type == ROMTYPE_AR || rd->type ==  ROMTYPE_SUPERIV)
1695 		_tcscpy (p->cartfile, path);
1696 	if (rd->type & ROMTYPE_CPUBOARD)
1697 		set_device_rom(p, path, ROMTYPE_CPUBOARD, 0);
1698 	return 1;
1699 }
1700 
set_device_rom(struct uae_prefs * p,const TCHAR * path,int romtype,int devnum)1701 void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype, int devnum)
1702 {
1703 	int idx;
1704 #ifdef FSUAE
1705 	write_log("set_device_rom path=%s romtype=%d devnum=%d\n", path ? path : "(null)", romtype, devnum);
1706 #endif
1707 	const struct expansionromtype *ert = get_device_expansion_rom(romtype);
1708 	if (path == NULL) {
1709 		struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
1710 #ifdef FSUAE
1711 		write_log("boardromconfig %p\n", brc);
1712 #endif
1713 		if (brc) {
1714 			brc->roms[idx].romfile[0] = 0;
1715 			brc->roms[idx].romident[0] = 0;
1716 		}
1717 	} else {
1718 		struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, &idx);
1719 		_tcscpy(brc->roms[idx].romfile, path);
1720 	}
1721 }
1722 
get_unit_expansion_rom(int hdunit)1723 const struct expansionromtype *get_unit_expansion_rom(int hdunit)
1724 {
1725 	if (hdunit >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_SCSI_LAST)
1726 		return &expansionroms[hdunit - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST];
1727 	if (hdunit >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_IDE_LAST)
1728 		return &expansionroms[hdunit - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST];
1729 	return NULL;
1730 }
1731 
get_device_expansion_rom(int romtype)1732 const struct expansionromtype *get_device_expansion_rom(int romtype)
1733 {
1734 	for (int i = 0; expansionroms[i].name; i++) {
1735 		const struct expansionromtype *ert = &expansionroms[i];
1736 		if ((ert->romtype & ROMTYPE_MASK) == (romtype & ROMTYPE_MASK))
1737 			return ert;
1738 	}
1739 	return NULL;
1740 }
1741 
device_rom_defaults(struct boardromconfig * brc,int romtype,int devnum)1742 static void device_rom_defaults(struct boardromconfig *brc, int romtype, int devnum)
1743 {
1744 	memset(brc, 0, sizeof(boardromconfig));
1745 	brc->device_type = romtype;
1746 	brc->device_num = devnum;
1747 	for (int i = 0; i < MAX_BOARD_ROMS; i++) {
1748 		brc->roms[i].device_id = 7;
1749 	}
1750 }
1751 
get_device_rom_new(struct uae_prefs * p,int romtype,int devnum,int * index)1752 struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index)
1753 {
1754 	int idx2;
1755 	static struct boardromconfig fake;
1756 	const struct expansionromtype *ert = get_device_expansion_rom(romtype);
1757 #ifdef FSUAE
1758 	write_log("get_device_rom_new romtype=%d devnum=%d\n", romtype, devnum);
1759 #endif
1760 	if (!ert) {
1761 		*index = 0;
1762 #ifdef FSUAE
1763 	write_log("- return &fake\n");
1764 #endif
1765 		return &fake;
1766 	}
1767 	*index = ert->parentromtype ? 1 : 0;
1768 	struct boardromconfig *brc = get_device_rom(p, ert->parentromtype ? ert->parentromtype : romtype, devnum, &idx2);
1769 	if (!brc) {
1770 		for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
1771 			brc = &p->expansionboard[i];
1772 			if (brc->device_type == 0)
1773 				continue;
1774 			int ok = 0;
1775 			for (int j = 0; j < MAX_BOARD_ROMS; j++) {
1776 				if (!brc->roms[j].romfile[0] && !brc->roms[j].romident[0] && !brc->roms[j].board_ram_size)
1777 					ok++;
1778 			}
1779 			if (ok == MAX_BOARD_ROMS)
1780 				memset(brc, 0, sizeof(boardromconfig));
1781 		}
1782 		for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
1783 			brc = &p->expansionboard[i];
1784 			if (brc->device_type == 0) {
1785 				device_rom_defaults(brc, romtype, devnum);
1786 #ifdef FSUAE
1787 	write_log("- return brc ()\n");
1788 #endif
1789 				return brc;
1790 			}
1791 		}
1792 #ifdef FSUAE
1793 	write_log("- return &fake (2)\n");
1794 #endif
1795 		return &fake;
1796 	}
1797 #ifdef FSUAE
1798 	write_log("- return brc (2)\n");
1799 #endif
1800 	return brc;
1801 }
1802 
clear_device_rom(struct uae_prefs * p,int romtype,int devnum)1803 void clear_device_rom(struct uae_prefs *p, int romtype, int devnum)
1804 {
1805 	int index;
1806 	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &index);
1807 	if (!brc)
1808 		return;
1809 	memset(&brc->roms[index], 0, sizeof(struct romconfig));
1810 }
1811 
get_device_rom(struct uae_prefs * p,int romtype,int devnum,int * index)1812 struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devnum, int *index)
1813 {
1814 	const struct expansionromtype *ert = get_device_expansion_rom(romtype);
1815 	if (!ert) {
1816 		*index = 0;
1817 		return NULL;
1818 	}
1819 	int parentrom = ert->parentromtype ? ert->parentromtype : romtype;
1820 	if (index)
1821 		*index = ert->parentromtype ? 1 : 0;
1822 	for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
1823 		struct boardromconfig *brc = &p->expansionboard[i];
1824 		if (!brc->device_type)
1825 			continue;
1826 		if ((brc->device_type & ROMTYPE_MASK) == (parentrom & ROMTYPE_MASK) && brc->device_num == devnum)
1827 			return brc;
1828 	}
1829 	return NULL;
1830 }
1831 
get_device_romconfig(struct uae_prefs * p,int romtype,int devnum)1832 struct romconfig *get_device_romconfig(struct uae_prefs *p, int romtype, int devnum)
1833 {
1834 	int idx;
1835 	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
1836 	if (brc)
1837 		return &brc->roms[idx];
1838 	return NULL;
1839 }
1840 
isspecialrom(const TCHAR * name)1841 static bool isspecialrom(const TCHAR *name)
1842 {
1843 	if (!_tcsicmp(name, _T(":NOROM")))
1844 		return true;
1845 	if (!_tcsicmp(name, _T(":ENABLED")))
1846 		return true;
1847 	return false;
1848 }
1849 
read_device_from_romconfig(struct romconfig * rc,uae_u32 romtype)1850 struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype)
1851 {
1852 	struct zfile *z = NULL;
1853 	if (isspecialrom(rc->romfile))
1854 		return z;
1855 	z = read_rom_name (rc->romfile);
1856 	if (z)
1857 		return z;
1858 	if (romtype) {
1859 		struct romlist *rl = getromlistbyromtype(romtype);
1860 		if (rl) {
1861 			struct romdata *rd = rl->rd;
1862 			z = read_rom(rd);
1863 		}
1864 	}
1865 	return z;
1866 }
1867 
read_device_rom(struct uae_prefs * p,int romtype,int devnum,int * roms)1868 struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int *roms)
1869 {
1870 	int idx;
1871 #ifdef FSUAE
1872 	write_log("read_device_rom romtype=%d devnum=%d\n", romtype, devnum);
1873 #endif
1874 	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
1875 	if (brc) {
1876 		const TCHAR *romname = brc->roms[idx].romfile;
1877 		if (isspecialrom(romname))
1878 			return NULL;
1879 		struct zfile *z = read_rom_name (romname);
1880 		if (!z && roms) {
1881 			struct romlist *rl = getromlistbyids(roms, romname);
1882 			if (rl) {
1883 				struct romdata *rd = rl->rd;
1884 				z = read_rom (rd);
1885 			}
1886 		}
1887 		return z;
1888 	}
1889 	return NULL;
1890 }
1891 
is_device_rom(struct uae_prefs * p,int romtype,int devnum)1892 int is_device_rom(struct uae_prefs *p, int romtype, int devnum)
1893 {
1894 	int idx;
1895 	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
1896 	if (brc) {
1897 		const TCHAR *romname = brc->roms[idx].romfile;
1898 		if (_tcslen(romname) == 0)
1899 			return -1;
1900 		if (isspecialrom(romname))
1901 			return 0;
1902 		return 1;
1903 	}
1904 	return -1;
1905 }
1906 
get_boardromconfig(struct uae_prefs * p,int romtype,int * index)1907 struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index)
1908 {
1909 	for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
1910 		struct boardromconfig *brc = &p->expansionboard[i];
1911 		if (!brc->device_type)
1912 			continue;
1913 		if ((brc->device_type & ROMTYPE_MASK) == (romtype & ROMTYPE_MASK)) {
1914 			for (int j = 0; j < MAX_BOARD_ROMS; j++) {
1915 				if (brc->roms[j].romfile[0]) {
1916 					if (index)
1917 						*index = j;
1918 					return brc;
1919 				}
1920 			}
1921 		}
1922 	}
1923 	return NULL;
1924 }
1925 
load_rom_rc(struct romconfig * rc,uae_u32 romtype,int maxfilesize,int fileoffset,uae_u8 * rom,int maxromsize,int flags)1926 bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags)
1927 {
1928 	if (flags & LOADROM_ONEFILL)
1929 		memset(rom, 0xff, maxromsize);
1930 	if (flags & LOADROM_ZEROFILL)
1931 		memset(rom, 0x00, maxromsize);
1932 	struct zfile *f = read_device_from_romconfig(rc, romtype);
1933 	if (!f)
1934 		return false;
1935 	zfile_fseek(f, fileoffset, SEEK_SET);
1936 	int cnt = 0;
1937 	int pos = 0;
1938 	int bytes = 0;
1939 	bool eof = false;
1940 	while (cnt < maxromsize && cnt < maxfilesize && pos < maxromsize) {
1941 		uae_u8 b = 0xff;
1942 		if (!eof) {
1943 			if (!zfile_fread(&b, 1, 1, f))
1944 				eof = true;
1945 			else
1946 				bytes++;
1947 		}
1948 		if (eof) {
1949 			int bitcnt = 0;
1950 			for (int i = 1; i < maxromsize; i <<= 1) {
1951 				if (cnt & i)
1952 					bitcnt++;
1953 			}
1954 			if (bitcnt == 1)
1955 				break;
1956 		}
1957 
1958 		rom[pos] = b;
1959 		if (flags & LOADROM_EVENONLY) {
1960 			rom[pos + 1] = (flags >> 16) & 0xff;
1961 			pos += 2;
1962 		} else {
1963 			pos += 1;
1964 		}
1965 		cnt++;
1966 	}
1967 	if (f)
1968 		write_log(_T("ROM '%s' loaded, %d bytes.\n"), zfile_getname(f), bytes);
1969 	zfile_fclose(f);
1970 	int posend = pos;
1971 	if (!(flags & LOADROM_FILL))
1972 		return true;
1973 	int oldpos = 0;
1974 	while (pos < maxromsize) {
1975 		rom[pos] = rom[oldpos];
1976 		oldpos++;
1977 		pos++;
1978 		if (oldpos >= posend)
1979 			oldpos = 0;
1980 	}
1981 	return true;
1982 }
1983