1  /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * ROM file management
5   *
6   * (c) 1995 Bernd Schmidt
7   */
8 
9 #include "sysconfig.h"
10 #include "sysdeps.h"
11 
12 #include "options.h"
13 #include "uae.h"
14 #include "memory.h"
15 #include "romlist.h"
16 #include "zfile.h"
17 #include "gui.h"
18 #include "crc32.h"
19 
is_encrypted_rom(uae_u8 * data,int size)20 static int is_encrypted_rom (uae_u8 *data, int size)
21 {
22     return size > 11 && !memcmp (data, "AMIROMTYPE1", 11);
23 }
24 
25 static struct romlist *list_of_roms;
26 static int romlist_cnt;
27 
romlist_add(char * path,struct romdata * rd,int loc)28 void romlist_add (char *path, struct romdata *rd, int loc)
29 {
30     struct romlist *rl2;
31 
32     romlist_cnt++;
33     list_of_roms = realloc (list_of_roms, sizeof (struct romlist) * romlist_cnt);
34     rl2 = list_of_roms + romlist_cnt - 1;
35     rl2->path = my_strdup (path);
36     rl2->rd = rd;
37     rl2->loc = loc;
38 }
39 
romlist_get(struct romdata * rd)40 char *romlist_get (struct romdata *rd)
41 {
42     int i;
43 
44     if (!rd)
45 	return 0;
46     for (i = 0; i < romlist_cnt; i++) {
47 	if (list_of_roms[i].rd == rd)
48 	    return list_of_roms[i].path;
49     }
50     return 0;
51 }
52 
romlist_from_idx(int idx,int type,int need_crc32)53 struct romlist *romlist_from_idx (int idx, int type, int need_crc32)
54 {
55     int i;
56     for (i = 0; i < romlist_cnt; i++) {
57 	if (!list_of_roms[i].rd)
58 	    continue;
59 
60 	if (list_of_roms[i].rd->type != type || (!list_of_roms[i].rd->crc32 && need_crc32))
61 	    continue;
62 
63 	if (idx == 0)
64 	    return list_of_roms + i;
65 	idx--;
66     }
67     return 0;
68 }
69 
sort_romlist(void)70 static void sort_romlist (void)
71 {
72     int i, j;
73     for (i = 0; i < romlist_cnt; i++) {
74 	int k = i;
75 
76 	if (list_of_roms[i].rd == 0)
77 	    continue;
78 
79 	for (j = i + 1; j < romlist_cnt; j++) {
80 	    if (list_of_roms[j].rd == 0)
81 		continue;
82 	    if (list_of_roms[j].rd == list_of_roms[k].rd
83 		&& list_of_roms[j].loc == ROMLOC_USER)
84 		k = j;
85 	    else if (strcmp (list_of_roms[j].rd->name, list_of_roms[k].rd->name) < 0)
86 		k = j;
87 	}
88 	if (k != i) {
89 	    struct romlist t;
90 	    t = list_of_roms[k];
91 	    list_of_roms[k] = list_of_roms[i];
92 	    list_of_roms[i] = t;
93 	}
94     }
95     /* Delete duplicates from the user directory.  */
96     for (i = j = 0; i < romlist_cnt; i++) {
97 	if (!list_of_roms[i].rd
98 	    || i + 1 > romlist_cnt
99 	    || list_of_roms[i].rd != list_of_roms[i + 1].rd
100 	    || list_of_roms[i].loc == ROMLOC_SYSTEM)
101 	{
102 	    if (i != j)
103 		list_of_roms[j] = list_of_roms[i];
104 	    j++;
105 	}
106     }
107     romlist_cnt = j;
108 }
109 
romlist_clear(int mask)110 void romlist_clear (int mask)
111 {
112     int i, j;
113     for (i = j = 0; i < romlist_cnt; i++) {
114 	if ((list_of_roms[i].loc & mask) == 0) {
115 	    if (i != j)
116 		list_of_roms[j] = list_of_roms[i];
117 	    j++;
118 	}
119     }
120     romlist_cnt = j;
121     list_of_roms = realloc (list_of_roms, sizeof (struct romlist) * j);
122 }
123 
124 #if 0
125 struct romdata *getromdatabypath(char *path)
126 {
127     int i;
128     for (i = 0; i < romlist_cnt; i++) {
129 	struct romdata *rd = list_of_roms[i].rd;
130 	if (rd->configname && path[0] == ':') {
131 	    if (!strcmp(path + 1, rd->configname))
132 		return rd;
133 	}
134 	if (!strcmp(list_of_roms[i].path, path))
135 	    return list_of_roms[i].rd;
136     }
137     return NULL;
138 }
139 #endif
140 
141 #define NEXT_ROM_ID 68
142 
143 static struct romheader romheaders[] = {
144     { "Freezer Cartridges", 1 },
145     { "Arcadia Games", 2 },
146     { NULL, 0 }
147 };
148 
149 static struct romdata roms[] = {
150     { "Cloanto Amiga Forever ROM key", 0, 0, 0, 0, 0, 2069, 0, 0, 1, ROMTYPE_KEY, 0,
151       0x869ae1b1, 0x801bbab3,0x2e3d3738,0x6dd1636d,0x4f1d6fa7,0xe21d5874, NULL },
152     { "Cloanto Amiga Forever 2006 ROM key", 0, 0, 0, 0, 0, 750, 48, 0, 1, ROMTYPE_KEY, 0,
153 	0xb01c4b56, 0xbba8e5cd,0x118b8d92,0xafed5693,0x5eeb9770,0x2a662d8f, NULL },
154 
155     { "KS ROM v1.0 (A1000)(NTSC)", 1, 0, 1, 0, "A1000\0", 262144, 1, 0, 0, ROMTYPE_KICK, 0,
156 	0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79, NULL },
157     { "KS ROM v1.1 (A1000)(NTSC)", 1, 1, 31, 34, "A1000\0", 262144, 2, 0, 0, ROMTYPE_KICK, 0,
158 	0xd060572a, 0x4192C505,0xD130F446,0xB2ADA6BD,0xC91DAE73,0x0ACAFB4C, NULL },
159     { "KS ROM v1.1 (A1000)(PAL)", 1, 1, 31, 34, "A1000\0", 262144, 3, 0, 0, ROMTYPE_KICK, 0,
160 	0xec86dae2, 0x16DF8B5F,0xD524C5A1,0xC7584B24,0x57AC15AF,0xF9E3AD6D, NULL },
161     { "KS ROM v1.2 (A1000)", 1, 2, 33, 166, "A1000\0", 262144, 4, 0, 0, ROMTYPE_KICK, 0,
162 	0x9ed783d0, 0x6A7BFB5D,0xBD6B8F17,0x9F03DA84,0xD8D95282,0x67B6273B, NULL },
163     { "KS ROM v1.2 (A500,A1000,A2000)", 1, 2, 33, 180, "A500\0A1000\0A2000\0", 262144, 5, 0, 0, ROMTYPE_KICK, 0,
164 	0xa6ce1636, 0x11F9E62C,0xF299F721,0x84835B7B,0x2A70A163,0x33FC0D88, NULL },
165     { "KS ROM v1.3 (A500,A1000,A2000)", 1, 3, 34, 5, "A500\0A1000\0A2000\0", 262144, 6, 0, 0, ROMTYPE_KICK, 0,
166 	0xc4f0f55f, 0x891E9A54,0x7772FE0C,0x6C19B610,0xBAF8BC4E,0xA7FCB785, NULL },
167     { "KS ROM v1.3 (A3000)(SK)", 1, 3, 34, 5, "A3000\0", 262144, 32, 0, 0, ROMTYPE_KICK, 0,
168 	0xe0f37258, 0xC39BD909,0x4D4E5F4E,0x28C1411F,0x30869504,0x06062E87, NULL },
169     { "KS ROM v1.4 (A3000)", 1, 4, 36, 16, "A3000\0", 524288, 59, ROMREQ_68030, 0, ROMTYPE_KICK, 0,
170 	0xbc0ec13f, 0xF76316BF,0x36DFF14B,0x20FA349E,0xD02E4B11,0xDD932B07, NULL },
171 
172     { "KS ROM v2.04 (A500+)", 2, 4, 37, 175, "A500+\0", 524288, 7, 0, 0, ROMTYPE_KICK, 0,
173 	0xc3bdb240, 0xC5839F5C,0xB98A7A89,0x47065C3E,0xD2F14F5F,0x42E334A1, NULL },
174     { "KS ROM v2.05 (A600)", 2, 5, 37, 299, "A600\0", 524288, 8, 0, 0, ROMTYPE_KICK, 0,
175 	0x83028fb5, 0x87508DE8,0x34DC7EB4,0x7359CEDE,0x72D2E3C8,0xA2E5D8DB, NULL },
176     { "KS ROM v2.05 (A600HD)", 2, 5, 37, 300, "A600HD\0A600\0", 524288, 9, 0, 0, ROMTYPE_KICK, 0,
177 	0x64466c2a, 0xF72D8914,0x8DAC39C6,0x96E30B10,0x859EBC85,0x9226637B, NULL },
178     { "KS ROM v2.05 (A600HD)", 2, 5, 37, 350, "A600HD\0A600\0", 524288, 10, 0, 0, ROMTYPE_KICK, 0,
179 	0x43b0df7b, 0x02843C42,0x53BBD29A,0xBA535B0A,0xA3BD9A85,0x034ECDE4, NULL },
180 
181     { "KS ROM v3.0 (A1200)", 3, 0, 39, 106, "A1200\0", 524288, 11, 0, 0, ROMTYPE_KICK, 0,
182 	0x6c9b07d2, 0x70033828,0x182FFFC7,0xED106E53,0x73A8B89D,0xDA76FAA5, NULL },
183     { "KS ROM v3.0 (A4000)", 3, 0, 39, 106, "A4000\0", 524288, 12, ROMREQ_A4000, 0, ROMTYPE_KICK, 0,
184 	0x9e6ac152, 0xF0B4E9E2,0x9E12218C,0x2D5BD702,0x0E4E7852,0x97D91FD7, NULL },
185     { "KS ROM v3.1 (A4000)", 3, 1, 40, 70, "A4000\0", 524288, 13, ROMREQ_A4000, 0, ROMTYPE_KICK, 0,
186 	0x2b4566f1, 0x81c631dd,0x096bbb31,0xd2af9029,0x9c76b774,0xdb74076c, NULL },
187     { "KS ROM v3.1 (A500,A600,A2000)", 3, 1, 40, 63, "A500\0A600\0A2000\0", 524288, 14, 0, 0, ROMTYPE_KICK, 0,
188 	0xfc24ae0d, 0x3B7F1493,0xB27E2128,0x30F989F2,0x6CA76C02,0x049F09CA, NULL },
189     { "KS ROM v3.1 (A1200)", 3, 1, 40, 68, "A1200\0", 524288, 15, ROMREQ_68EC020, 0, ROMTYPE_KICK, 0,
190 	0x1483a091, 0xE2154572,0x3FE8374E,0x91342617,0x604F1B3D,0x703094F1, NULL },
191     { "KS ROM v3.1 (A3000)", 3, 1, 40, 68, "A3000\0", 524288, 61, ROMREQ_68020, 0, ROMTYPE_KICK, 0,
192 	0xefb239cc, 0xF8E210D7,0x2B4C4853,0xE0C9B85D,0x223BA20E,0x3D1B36EE, NULL },
193     { "KS ROM v3.1 (A4000)(Cloanto)", 3, 1, 40, 68, "A4000\0", 524288, 31, ROMREQ_A4000, 1, ROMTYPE_KICK, 0,
194 	0x43b6dd22, 0xC3C48116,0x0866E60D,0x085E436A,0x24DB3617,0xFF60B5F9, NULL },
195     { "KS ROM v3.1 (A4000)", 3, 1, 40, 68, "A4000\0", 524288, 16, ROMREQ_A4000, 0, ROMTYPE_KICK, 0,
196 	0xd6bae334, 0x5FE04842,0xD04A4897,0x20F0F4BB,0x0E469481,0x99406F49, NULL },
197     { "KS ROM v3.1 (A4000T)", 3, 1, 40, 70, "A4000T\0", 524288, 17, ROMREQ_A4000, 0, ROMTYPE_KICK, 0,
198 	0x75932c3a, 0xB0EC8B84,0xD6768321,0xE01209F1,0x1E6248F2,0xF5281A21, NULL },
199     { "KS ROM v3.X (A4000)(Cloanto)", 3, 10, 45, 57, "A4000\0", 524288, 46, ROMREQ_A4000, 0, ROMTYPE_KICK, 0,
200 	0x08b69382, 0x81D3AEA3,0x0DB7FBBB,0x4AFEE41C,0x21C5ED66,0x2B70CA53, NULL },
201 
202     { "CD32 KS ROM v3.1", 3, 1, 40, 60, "CD32\0", 524288, 18, ROMREQ_68EC020, 0, ROMTYPE_KICKCD32, 0,
203 	0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D, NULL },
204     { "CD32 extended ROM", 3, 1, 40, 60, "CD32\0", 524288, 19, ROMREQ_68EC020, 0, ROMTYPE_EXTCD32, 0,
205 	0x87746be2, 0x5BEF3D62,0x8CE59CC0,0x2A66E6E4,0xAE0DA48F,0x60E78F7F, NULL },
206     { "CD32 ROM (KS + extended)", 3, 1, 40, 60, "CD32\0", 2 * 524288, 64, ROMREQ_68EC020, 0, ROMTYPE_KICKCD32, 0,
207 	0xd3837ae4, 0x06807db3,0x18163745,0x5f4d4658,0x2d9972af,0xec8956d9, NULL },
208 
209     { "CDTV extended ROM v1.00", 1, 0, 1, 0, "CDTV\0", 262144, 20, 0, 0, ROMTYPE_EXTCDTV, 0,
210 	0x42baa124, 0x7BA40FFA,0x17E500ED,0x9FED041F,0x3424BD81,0xD9C907BE, NULL },
211     { "CDTV extended ROM v2.07", 2, 7, 2, 7, "CDTV\0", 262144, 22, 0, 0, ROMTYPE_EXTCDTV, 0,
212 	0xceae68d2, 0x5BC114BB,0xA29F60A6,0x14A31174,0x5B3E2464,0xBFA06846, NULL },
213     { "CDTV extended ROM v2.30", 2, 30, 2, 30, "CDTV\0", 262144, 21, 0, 0, ROMTYPE_EXTCDTV, 0,
214 	0x30b54232, 0xED7E461D,0x1FFF3CDA,0x321631AE,0x42B80E3C,0xD4FA5EBB, NULL },
215 
216     { "A1000 bootstrap ROM", 0, 0, 0, 0, "A1000\0", 8192, 23, ROMREQ_A1000, 0, ROMTYPE_KICK, 0,
217 	0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6, NULL },
218     { "A1000 bootstrap ROM", 0, 0, 0, 0, "A1000\0", 65536, 24, ROMREQ_A1000, 0, ROMTYPE_KICK, 0,
219 	0x0b1ad2d0, 0xBA93B8B8,0x5CA0D83A,0x68225CC3,0x3B95050D,0x72D2FDD7, NULL },
220 
221     { "Freezer: Action Replay Mk I v1.00", 1, 0, 1, 0, "AR\0", 65536, 52, 0, 0, ROMTYPE_AR, 1,
222 	0x2d921771, 0x1EAD9DDA,0x2DAD2914,0x6441F5EF,0x72183750,0x22E01248, NULL },
223     { "Freezer: Action Replay Mk I v1.50", 1, 50, 1, 50, "AR\0", 65536, 25, 0, 0, ROMTYPE_AR, 1,
224 	0xd4ce0675, 0x843B433B,0x2C56640E,0x045D5FDC,0x854DC6B1,0xA4964E7C, NULL },
225     { "Freezer: Action Replay Mk II v2.05", 2, 5, 2, 5, "AR\0", 131072, 26, 0, 0, ROMTYPE_AR, 1,
226 	0x1287301f, 0xF6601DE8,0x888F0050,0x72BF562B,0x9F533BBC,0xAF1B0074, NULL },
227     { "Freezer: Action Replay Mk II v2.12", 2, 12, 2, 12, "AR\0", 131072, 27, 0, 0, ROMTYPE_AR, 1,
228 	0x804d0361, 0x3194A07A,0x0A82D8B5,0xF2B6AEFA,0x3CA581D6,0x8BA8762B, NULL },
229     { "Freezer: Action Replay Mk II v2.14", 2, 14, 2, 14, "AR\0", 131072, 28, 0, 0, ROMTYPE_AR, 1,
230 	0x49650e4f, 0x255D6DF6,0x3A4EAB0A,0x838EB1A1,0x6A267B09,0x59DFF634, NULL },
231     { "Freezer: Action Replay Mk III v3.09", 3, 9, 3, 9, "AR\0", 262144, 29, 0, 0, ROMTYPE_AR, 1,
232 	0x0ed9b5aa, 0x0FF3170A,0xBBF0CA64,0xC9DD93D6,0xEC0C7A01,0xB5436824, NULL },
233     { "Freezer: Action Replay Mk III v3.17", 3, 17, 3, 17, "AR\0", 262144, 30, 0, 0, ROMTYPE_AR, 1,
234 	0xc8a16406, 0x5D4987C2,0xE3FFEA8B,0x1B02E314,0x30EF190F,0x2DB76542, NULL },
235     { "Freezer: Action Replay 1200", 0, 0, 0, 0, "AR\0", 262144, 47, 0, 0, ROMTYPE_AR, 1,
236 	0x8d760101, 0x0F6AB834,0x2810094A,0xC0642F62,0xBA42F78B,0xC0B07E6A, NULL },
237 
238     { "Freezer: Action Cartridge Super IV Professional", 0, 0, 0, 0, "SUPERIV\0", 0, 62, 0, 0, ROMTYPE_SUPERIV, 1,
239 	0xffffffff, 0, 0, 0, 0, 0, "SuperIV" },
240     { "Freezer: Action Cart. Super IV Pro (+ROM v4.3)", 4, 3, 4, 3, "SUPERIV\0", 170368, 60, 0, 0, ROMTYPE_SUPERIV, 1,
241 	0xe668a0be, 0x633A6E65,0xA93580B8,0xDDB0BE9C,0x9A64D4A1,0x7D4B4801, NULL },
242     { "Freezer: X-Power Professional 500 v1.2", 1, 2, 1, 2, "XPOWER\0", 131072, 65, 0, 0, ROMTYPE_SUPERIV, 1,
243 	0x9e70c231, 0xa2977a1c,0x41a8ca7d,0x4af4a168,0x726da542,0x179d5963, NULL },
244     /* v1.0 is bad dump */
245     { "Freezer: Nordic Power v1.0", 0, 0, 0, 0, "NPOWER\0", 65536, 66, 0, 0, ROMTYPE_SUPERIV, 1, },
246 	//0xdd16cdec, 0xfd882967,0x87e2da5f,0x4ef6be32,0x5f7c9324,0xb5bd8e64 },
247     { "Freezer: Nordic Power v2.0", 2, 0, 2, 0, "NPOWER\0", 65536, 67, 0, 0, ROMTYPE_SUPERIV, 1,
248 	0xa4db2906, 0x0aec68f7,0x25470c89,0x6b699ff4,0x6623dec5,0xc777466e },
249 
250     { "Freezer: HRTMon v2.30 (built-in)", 0, 0, 0, 0, "HRTMON\0", 0, 63, 0, 0, ROMTYPE_HRTMON, 1,
251 	0xffffffff, 0, 0, 0, 0, 0, "HRTMon" },
252 
253     { "A590/A2091 SCSI boot ROM", 0, 0, 6, 0, "A590\0A2091\0", 16384, 53, 0, 0, ROMTYPE_A2091BOOT, 0,
254 	0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2, NULL },
255     { "A590/A2091 SCSI boot ROM", 0, 0, 6, 6, "A590\0A2091\0", 16384, 54, 0, 0, ROMTYPE_A2091BOOT, 0,
256 	0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66, NULL },
257     { "A590/A2091 SCSI boot ROM", 0, 0, 7, 0, "A590\0A2091\0", 16384, 55, 0, 0, ROMTYPE_A2091BOOT, 0,
258 	0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E, NULL },
259     { "A590/A2091 SCSI Guru boot ROM", 0, 0, 6, 14, "A590\0A2091\0", 32768, 56, 0, 0, ROMTYPE_A2091BOOT, 0,
260 	0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B, NULL },
261     { "A4091 SCSI boot ROM", 0, 0, 40, 9, "A4091\0", 32768, 57, 0, 0, ROMTYPE_A4091BOOT, 0,
262 	0x00000000, 0, 0, 0, 0, 0, NULL },
263     { "A4091 SCSI boot ROM", 0, 0, 40, 13, "A4091\0", 32768, 58, 0, 0, ROMTYPE_A4091BOOT, 0,
264 	0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA, NULL },
265 
266     { "Arcadia OnePlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 49, 0, 0, ROMTYPE_ARCADIABIOS, 0 },
267     { "Arcadia TenPlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 50, 0, 0, ROMTYPE_ARCADIABIOS, 0 },
268     { "Arcadia OnePlay 3.00", 0, 0, 0, 0, "ARCADIA\0", 0, 51, 0, 0, ROMTYPE_ARCADIABIOS, 0 },
269 
270     { "Arcadia SportTime Table Hockey", 0, 0, 0, 0, "ARCADIA\0", 0, 33, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
271     { "Arcadia SportTime Bowling", 0, 0, 0, 0, "ARCADIA\0", 0, 34, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
272     { "Arcadia World Darts", 0, 0, 0, 0, "ARCADIA\0", 0, 35, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
273     { "Arcadia Magic Johnson's Fast Break", 0, 0, 0, 0, "ARCADIA\0", 0, 36, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
274     { "Arcadia Leader Board Golf", 0, 0, 0, 0, "ARCADIA\0", 0, 37, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
275     { "Arcadia Leader Board Golf (alt)", 0, 0, 0, 0, "ARCADIA\0", 0, 38, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
276     { "Arcadia Ninja Mission", 0, 0, 0, 0, "ARCADIA\0", 0, 39, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
277     { "Arcadia Road Wars", 0, 0, 0, 0, "ARCADIA\0", 0, 40, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
278     { "Arcadia Sidewinder", 0, 0, 0, 0, "ARCADIA\0", 0, 41, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
279     { "Arcadia Spot", 0, 0, 0, 0, "ARCADIA\0", 0, 42, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
280     { "Arcadia Space Ranger", 0, 0, 0, 0, "ARCADIA\0", 0, 43, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
281     { "Arcadia Xenon", 0, 0, 0, 0, "ARCADIA\0", 0, 44, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
282     { "Arcadia World Trophy Soccer", 0, 0, 0, 0, "ARCADIA\0", 0, 45, 0, 0, ROMTYPE_ARCADIAGAME, 2 },
283 
284     { NULL }
285 
286 };
287 
getarcadiarombyname(char * name)288 struct romdata *getarcadiarombyname (char *name)
289 {
290     int i;
291     for (i = 0; roms[i].name; i++) {
292 	if (roms[i].type == ROMTYPE_ARCADIAGAME || roms[i].type == ROMTYPE_ARCADIAGAME) {
293 	    char *p = roms[i].name;
294 	    p = p + strlen (p) + 1;
295 	    if (strlen (name) >= strlen (p) + 4) {
296 		char *p2 = name + strlen (name) - strlen (p) - 4;
297 		if (!memcmp (p, p2, strlen (p)) && !memcmp (p2 + strlen (p2) - 4, ".zip", 4))
298 		    return &roms[i];
299 	    }
300 	}
301     }
302     return NULL;
303 }
304 
getarcadiaroms(void)305 struct romlist **getarcadiaroms(void)
306 {
307     int i, out, max;
308     void *buf;
309     struct romlist **rdout, *rltmp;
310 
311     max = 0;
312     for (i = 0; roms[i].name; i++) {
313 	if (roms[i].type == ROMTYPE_ARCADIABIOS || roms[i].type == ROMTYPE_ARCADIAGAME)
314 	    max++;
315     }
316     buf = xmalloc((sizeof (struct romlist*) + sizeof (struct romlist)) * (max + 1));
317     rdout = (struct romlist**)buf;
318     rltmp = (struct romlist*)((uae_u8*)buf + (max + 1) * sizeof (struct romlist*));
319     out = 0;
320     for (i = 0; roms[i].name; i++) {
321 	if (roms[i].type == ROMTYPE_ARCADIABIOS || roms[i].type == ROMTYPE_ARCADIAGAME) {
322 	    rdout[out++] = rltmp;
323 	    rltmp->path = NULL;
324 	    rltmp->rd = &roms[i];
325 	    rltmp++;
326 	}
327     }
328     rdout[out] = NULL;
329     return rdout;
330 }
331 
kickstart_checksum_do(uae_u8 * mem,int size)332 static int kickstart_checksum_do (uae_u8 *mem, int size)
333 {
334     uae_u32 cksum = 0, prevck = 0;
335     int i;
336     for (i = 0; i < size; i+=4) {
337 	uae_u32 data = mem[i]*65536*256 + mem[i+1]*65536 + mem[i+2]*256 + mem[i+3];
338 	cksum += data;
339 	if (cksum < prevck)
340 	    cksum++;
341 	prevck = cksum;
342     }
343     return cksum == 0xffffffff;
344 }
345 
346 #define ROM_KEY_NUM 3
347 struct rom_key {
348     uae_u8 *key;
349     int size;
350 };
351 
352 static struct rom_key keyring[ROM_KEY_NUM];
353 int nr_keys;
354 
addkey(uae_u8 * key,int size,const char * name)355 static int addkey (uae_u8 *key, int size, const char *name)
356 {
357     int i;
358 
359     if (nr_keys == ROM_KEY_NUM)
360 	return 0;
361 
362     for (i = 0; i < nr_keys; i++) {
363 	if (keyring[i].size == size && !memcmp (keyring[i].key, key, size))
364 	    return 0;
365     }
366     keyring[nr_keys].key = malloc (size);
367     if (!keyring[nr_keys].key)
368 	return 0;
369     memcpy (keyring[nr_keys].key, key, size);
370     keyring[nr_keys].size = size;
371     write_log ("ROM KEY '%s' %d bytes loaded\n", name, size);
372     nr_keys++;
373     return 1;
374 }
375 
decode_cloanto_rom_do(uae_u8 * mem,int size,int real_size,uae_u8 * key,int keysize)376 static void decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size, uae_u8 *key, int keysize)
377 {
378     int cnt, t;
379     for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize)  {
380 	mem[cnt] ^= key[t];
381 	if (real_size == cnt + 1)
382 	    t = keysize - 1;
383     }
384 }
385 
decode_cloanto_rom(uae_u8 * mem,int size,int real_size,int quiet)386 int decode_cloanto_rom (uae_u8 *mem, int size, int real_size, int quiet)
387 {
388     struct zfile *keyf;
389     uae_u8 *p;
390     int keysize;
391     int i;
392 
393     /* Try keyring entries first.  */
394     for (i = ROM_KEY_NUM - 1; i >= 0; i--) {
395 	uae_u8 *key = keyring[i].key;
396 	keysize = keyring[i].size;
397 	if (!key)
398 	    continue;
399 	decode_cloanto_rom_do (mem, size, real_size, key, keysize);
400 
401 	if ((mem[2] == 0x4e && mem[3] == 0xf9)
402 	    || (mem[0] == 0x11 && (mem[1] == 0x11 || mem[1] == 0x14)))
403 	    return 1;
404 	/* Undo the decode.  */
405 	decode_cloanto_rom_do (mem, size, real_size, key, keysize);
406     }
407 
408     if (strlen (currprefs.keyfile) == 0) {
409 	if (!quiet)
410 	    gui_message ("No filename given for ROM key file and ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
411 	return 0;
412     }
413     keyf = zfile_open (currprefs.keyfile, "rb");
414     if (keyf == 0) {
415 	if (!quiet)
416 	    gui_message ("Could not find specified ROM key-file.\n");
417 	return 0;
418     }
419 
420     p = (uae_u8 *) xmalloc (524288);
421     keysize = zfile_fread (p, 1, 524288, keyf);
422     decode_cloanto_rom_do (mem, size, real_size, p, keysize);
423     zfile_fclose (keyf);
424     free (p);
425     return 1;
426 }
427 
428 #if 0
429 struct romdata *getromdatabyname (char *name)
430 {
431     char tmp[MAX_PATH];
432     int i = 0;
433     while (roms[i].name) {
434 	getromname (&roms[i], tmp);
435 	if (!strcmp (tmp, name) || !strcmp (roms[i].name, name))
436 	    return &roms[i];
437 	i++;
438     }
439     return 0;
440 }
441 #endif
442 
getromdatabyid(int id)443 struct romdata *getromdatabyid (int id)
444 {
445     int i = 0;
446     while (roms[i].name) {
447 	if (id == roms[i].id)
448 	    return &roms[i];
449 	i++;
450     }
451     return 0;
452 }
453 
notcrc32(uae_u32 crc32)454 STATIC_INLINE int notcrc32(uae_u32 crc32)
455 {
456     if (crc32 == 0xffffffff || crc32 == 0x00000000)
457 	return 1;
458     return 0;
459 }
460 
getromdatabycrc(uae_u32 crc32)461 struct romdata *getromdatabycrc (uae_u32 crc32)
462 {
463     int i = 0;
464     while (roms[i].name) {
465 	if (crc32 == roms[i].crc32 && !notcrc32(crc32))
466 	    return &roms[i];
467 	i++;
468     }
469     return 0;
470 }
471 
cmpsha1(uae_u8 * s1,struct romdata * rd)472 static int cmpsha1(uae_u8 *s1, struct romdata *rd)
473 {
474     int i;
475 
476     for (i = 0; i < SHA1_SIZE / 4; i++) {
477 	uae_u32 v1 = (s1[0] << 24) | (s1[1] << 16) | (s1[2] << 8) | (s1[3] << 0);
478 	uae_u32 v2 = rd->sha1[i];
479 	if (v1 != v2)
480 	    return -1;
481 	s1 += 4;
482     }
483     return 0;
484 }
485 
checkromdata(uae_u8 * sha1,int size,uae_u32 mask)486 static struct romdata *checkromdata (uae_u8 *sha1, int size, uae_u32 mask)
487 {
488     int i = 0;
489     while (roms[i].name) {
490 	if (!notcrc32 (roms[i].crc32) && roms[i].size >= size) {
491 	    if (roms[i].type & mask) {
492 		if (!cmpsha1 (sha1, &roms[i]))
493 		    return &roms[i];
494 	    }
495 	}
496 	i++;
497     }
498     return NULL;
499 }
500 
getromdatabydata(uae_u8 * rom,int size)501 struct romdata *getromdatabydata (uae_u8 *rom, int size)
502 {
503     uae_u8 sha1[SHA1_SIZE];
504     uae_u8 tmp[4];
505     uae_u8 *tmpbuf = NULL;
506     struct romdata *ret = NULL;
507 
508     if (is_encrypted_rom (rom, size)) {
509 	uae_u8 *tmpbuf = (uae_u8*)xmalloc (size);
510 	int tmpsize = size - 11;
511 	memcpy (tmpbuf, rom + 11, tmpsize);
512 	if (!decode_cloanto_rom (tmpbuf, tmpsize, tmpsize, 1))
513 	    return 0;
514 	rom = tmpbuf;
515 	size = tmpsize;
516     }
517     get_sha1 (rom, size, sha1);
518     ret = checkromdata(sha1, size, -1);
519     if (!ret) {
520 	get_sha1 (rom, size / 2, sha1);
521 	ret = checkromdata (sha1, size / 2, -1);
522 	if (!ret) {
523 	    /* ignore AR IO-port range until we have full dump */
524 	    memcpy (tmp, rom, 4);
525 	    memset (rom, 0, 4);
526 	    get_sha1 (rom, size, sha1);
527 	    ret = checkromdata (sha1, size, ROMTYPE_AR);
528 	    memcpy (rom, tmp, 4);
529 	}
530     }
531     free (tmpbuf);
532     return ret;
533 }
534 
getromdatabyzfile(struct zfile * f)535 static struct romdata *getromdatabyzfile (struct zfile *f)
536 {
537     int pos, size;
538     uae_u8 *p;
539     struct romdata *rd;
540 
541     pos = zfile_ftell (f);
542     zfile_fseek (f, 0, SEEK_END);
543     size = zfile_ftell (f);
544 
545     /* Weed out too-large files to save time.  */
546     if (size > 1024 * 1024)
547 	return 0;
548 
549     p = (uae_u8*)xmalloc (size);
550     if (!p)
551 	return 0;
552     memset (p, 0, size);
553     zfile_fseek (f, 0, SEEK_SET);
554     zfile_fread (p, 1, size, f);
555     zfile_fseek (f, pos, SEEK_SET);
556     rd = getromdatabydata (p, size);
557     free (p);
558     return rd;
559 }
560 
getromname(struct romdata * rd,char * name)561 void getromname	(struct romdata *rd, char *name)
562 {
563     name[0] = 0;
564     if (!rd)
565 	return;
566     strcat (name, rd->name);
567     if ((rd->subrev || rd->subver) && rd->subver != rd->ver)
568 	sprintf (name + strlen (name), " rev %d.%d", rd->subver, rd->subrev);
569     if (rd->size > 0)
570 	sprintf (name + strlen (name), " (%dk)", (rd->size + 1023) / 1024);
571 }
572 
getromlistbyids(int * ids)573 struct romlist *getromlistbyids(int *ids)
574 {
575     struct romdata *rd;
576     int i, j;
577 
578     i = 0;
579     while (ids[i] >= 0) {
580 	rd = getromdatabyid (ids[i]);
581 	if (rd) {
582 	    for (j = 0; j < romlist_cnt; j++) {
583 		if (list_of_roms[j].rd == rd)
584 		    return list_of_roms + j;
585 	    }
586 	}
587 	i++;
588     }
589     return NULL;
590 }
591 
getromlistbyromdata(struct romdata * rd)592 static struct romlist *getromlistbyromdata(struct romdata *rd)
593 {
594     int ids[2];
595 
596     ids[0] = rd->id;
597     ids[1] = 0;
598     return getromlistbyids(ids);
599 }
600 
601 #if 0
602 void romwarning(int *ids)
603 {
604     int i, exp;
605     char tmp1[MAX_DPATH], tmp2[MAX_DPATH];
606     char tmp3[MAX_DPATH];
607 
608     exp = 0;
609     tmp2[0] = 0;
610     i = 0;
611     while (ids[i] >= 0) {
612 	struct romdata *rd = getromdatabyid (ids[i]);
613 	getromname (rd, tmp1);
614 	strcat (tmp2, "- ");
615 	strcat (tmp2, tmp1);
616 	strcat (tmp2, "\n");
617 	if (rd->type & (ROMTYPE_A2091BOOT | ROMTYPE_A4091BOOT))
618 	    exp++;
619 	i++;
620     }
621     translate_message (exp ? NUMSG_EXPROMNEED : NUMSG_ROMNEED, tmp3);
622     gui_message (tmp3, tmp2);
623 }
624 #endif
625 
scan_roms(const char * path,int loc)626 void scan_roms (const char *path, int loc)
627 {
628     DIR *dir;
629     int pathlen = strlen (path);
630     int bufsz = pathlen + 256;
631     char *buffer;
632     uae_u8 *data;
633     int keys_added = 0;
634 
635     dir = opendir (path);
636     if (!dir)
637 	return;
638 
639     buffer = malloc (bufsz);
640     if (!buffer)
641 	goto out;
642     data = malloc (1024 * 1024);
643     if (!data)
644 	goto out1;
645     romlist_clear (loc);
646 
647     strcpy (buffer, path);
648     buffer[pathlen++] = '/';
649     buffer[pathlen] = '\0';
650     for (;;) {
651 	struct zfile *f;
652 	struct dirent *ent = readdir (dir);
653 	int len;
654 	struct romdata *rd;
655 	long size;
656 
657 	if (!ent)
658 	    break;
659 
660 	len = strlen (ent->d_name);
661 	if (len + pathlen + 1 >= bufsz) {
662 	    bufsz = len + pathlen + 200;
663 	    buffer = realloc (buffer, bufsz);
664 	    if (!buffer) {
665 		goto out;
666 	    }
667 	}
668 	strcpy (buffer + pathlen, ent->d_name);
669 	f = zfile_open (buffer, "rb");
670 	if (!f)
671 	    continue;
672 
673 	zfile_fseek (f, 0, SEEK_END);
674 	size = zfile_ftell (f);
675 
676 	/* Weed out too-large files to save time.  */
677 	if (size > 1024 * 1024) {
678 	    zfile_fclose (f);
679 	    continue;
680 	}
681 	zfile_fseek (f, 0, SEEK_SET);
682 	zfile_fread (data, 1, size, f);
683 
684 	rd = getromdatabydata (data, size);
685 	zfile_fclose (f);
686 
687 	/* Add encrypted ROMs even if we don't have the key yet.  */
688 	if (!rd && !is_encrypted_rom (data, size))
689 	    continue;
690 
691 	if (rd && rd->type == ROMTYPE_KEY) {
692 	    if (addkey (data, size, ent->d_name))
693 		keys_added = 1;
694 	} else
695 	    romlist_add (buffer, rd, loc);
696     }
697     /* Now, if we added any keys, reexamine all encrypted ROMs.  */
698     if (keys_added) {
699 	int i;
700 	for (i = 0; i < romlist_cnt; i++) {
701 	    struct romlist *rl = list_of_roms + i;
702 	    if (rl->rd)
703 		continue;
704 	    struct zfile *f = zfile_open (rl->path, "rb");
705 	    if (!f)
706 		continue;
707 	    rl->rd = getromdatabyzfile (f);
708 	    zfile_fclose (f);
709 	}
710     }
711     sort_romlist ();
712     gui_romlist_changed ();
713 
714     free (data);
715   out1:
716     free (buffer);
717   out:
718     closedir (dir);
719 }
720