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