From: kub Date: Sat, 30 Apr 2022 12:07:58 +0000 (+0200) Subject: md, reworked cart protection handling, added some unlicensed X-Git-Tag: v2.00~307 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1e8ca17be7f96320119e7793881da84e2cf9321;p=picodrive.git md, reworked cart protection handling, added some unlicensed --- diff --git a/pico/cart.c b/pico/cart.c index 3e578dd9..2ffe7b5e 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -917,15 +917,16 @@ void PicoCartUnload(void) PicoGameLoaded = 0; } -static unsigned int rom_crc32(void) +static unsigned int rom_crc32(int size) { unsigned int crc; elprintf(EL_STATUS, "caclulating CRC32.."); + if (size <= 0 || size > Pico.romsize) size = Pico.romsize; // have to unbyteswap for calculation.. - Byteswap(Pico.rom, Pico.rom, Pico.romsize); - crc = crc32(0, Pico.rom, Pico.romsize); - Byteswap(Pico.rom, Pico.rom, Pico.romsize); + Byteswap(Pico.rom, Pico.rom, size); + crc = crc32(0, Pico.rom, size); + Byteswap(Pico.rom, Pico.rom, size); return crc; } @@ -1116,7 +1117,7 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram, goto bad; if (rom_crc == 0) - rom_crc = rom_crc32(); + rom_crc = rom_crc32(64*1024); if (crc == rom_crc) any_checks_passed = 1; else @@ -1153,8 +1154,10 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram, carthw_sf002_startup(); else if (strcmp(p, "sf004_mapper") == 0) carthw_sf004_startup(); - else if (strcmp(p, "prot_lk3") == 0) - carthw_prot_lk3_startup(); + else if (strcmp(p, "lk3_mapper") == 0) + carthw_lk3_startup(); + else if (strcmp(p, "smw64_mapper") == 0) + carthw_smw64_startup(); else { elprintf(EL_STATUS, "carthw:%d: unsupported mapper: %s", line, p); skip_sect = 1; diff --git a/pico/carthw.cfg b/pico/carthw.cfg index b9c8db9c..964efb47 100644 --- a/pico/carthw.cfg +++ b/pico/carthw.cfg @@ -1,8 +1,7 @@ # hardware (hw = ...): # svp - Sega Virtua Processor # pico - Sega Pico (not really cart hw, but convenient to support here) -# prot - siple copy protection devices in unlicensed cartridges (see prot. below) -# prot_lk3 - Lion King 3 / Super King Kong 99 protection. +# prot - simple copy protection devices in unlicensed cartridges (see prot. below) # # cartridge properties (prop = ...): # no_sram - don't emulate sram/EEPROM even if ROM headers tell it's there @@ -17,6 +16,8 @@ # radica_mapper - similar to x_in_1_mapper # piersolar_mapper - used in Pier Solar # sf00x_mapper - versions x=1,2,4 used by superfighter team +# lk3_mapper - mapper for Lion King 3 / Super King Kong 99 and some more +# smw64_mapper - mapper for Super Mario World 64 # # save storage memory range (inclusive, overrides ROM header): # sram_range = @@ -237,72 +238,204 @@ eeprom_lines = 6,7,7 # Unlicensed games with simple protections # some of these come from Haze, some from myself (notaz). +# more added by irixxxx from Mame and G+GX +# check_crc32 calculation for 1st 64 KB only to allow for overdumps + +# lk3, mapper + bitswapping hardware +[Lion King 3 (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0xc9706e25 +hw = lk3_mapper + +[Super King Kong 99 (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0x4c98cc30 +hw = lk3_mapper + +[Pocket Monsters II (Unl)] +check_str = 0x104, " " +check_crc32 = 0x0d097f5c +hw = lk3_mapper + +[Pokemon Stadium (Unl)] +check_str = 0x104, " " +check_crc32 = 0xbf7219df +hw = lk3_mapper + +[Mulan (Unl)] +check_str = 0x104, " " +check_crc32 = 0xb5b7606e +hw = lk3_mapper + +[Final Samurai V (Unl)] # aka Soul Edge +check_str = 0x104, " " +check_crc32 = 0xab3ae5e9 +hw = lk3_mapper + +[Top Fighter 2000 (Unl)] +check_str = 0x104, " " +check_crc32 = 0x802f53f9 +hw = lk3_mapper + +# smw64 mapper + prot +[Super Mario World 64 (Unl)] +check_csum = 0 +check_crc32 = 0xf63b7bdc +hw = smw64_mapper + +# cart I/O area [Bug's Life, A (Unl)] check_str = 0x104, " " -check_crc32 = 0x10458e09 +check_crc32 = 0x50aa5a9b hw = prot prot_ro_value16 = 0xa13000,0xffff00,0x28 -[Elf Wor (Unl)] -check_str = 0x172, "GAME : ELF WOR" +[Rockman X3 (Unl)] +check_csum = 0 +check_crc32 = 0xee20be2c hw = prot -prot_ro_value16 = 0x400000,-2,0x5500 -prot_ro_value16 = 0x400002,-2,0xc900 # check is done if the above one fails -prot_ro_value16 = 0x400004,-2,0x0f00 -prot_ro_value16 = 0x400006,-2,0x1800 # similar to above +prot_ro_value16 = 0xa13000,-2,0x0c + +[Super Mario World (Unl)] +check_str = 0x104, "SEGASEGASEGA" +check_crc32 = 0xc3616596 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x1c + +[Super Mario Bros. 2 (Unl)] # aka Super Mario 2 1998 +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0x7861fb28 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x0a + +[Pocket Monsters (Unl)] +check_str = 0x104, " " +check_crc32 = 0xf4cb9b37 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x00 +prot_ro_value16 = 0xa13002,-2,0x01 +prot_ro_value16 = 0xa1303e,-2,0x1f -[King of Fighters '98, The (Unl)] +[King of Fighters '99, The (Unl)] check_str = 0x104, " " -check_crc32 = 0xcbc38eea +check_crc32 = 0x7bdfb390 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x00 +prot_ro_value16 = 0xa13002,-2,0x01 +prot_ro_value16 = 0xa1303e,-2,0x1f + +# cart upper 4MB +[King of Fighters '98+2000, The (Unl)] +check_str = 0x104, " " +check_crc32 = 0x8fb8b29e hw = prot prot_ro_value16 = 0x480000,0xff0000,0xaa00 prot_ro_value16 = 0x4a0000,0xff0000,0x0a00 prot_ro_value16 = 0x4c0000,0xff0000,0xf000 prot_ro_value16 = 0x400000,0xc00000,0x0000 # default for 400000-7f0000 -[Lion King 3 (Unl)] -check_str = 0x104, " are Registered Trademarks" -check_crc32 = 0xc004219d -hw = prot_lk3 +[Mahjong Lover (Unl), Super Majon Club (Unl), Insane Paradise (Unl)] +# Majiang qingren, Chaoji majiang Club, Fengkuang taohuayuan (Crazy Utopia) +check_str = 0x104, " MEGA DRIVE (C)" +check_str = 0x118, "CREATON." +check_str = 0x180, "MDGM-000" +hw = prot +prot_ro_value16 = 0x400000,-2,0x9000 +prot_ro_value16 = 0x401000,-2,0xd300 + +[Rook Mann (Unl)] # aka Rock Heaven +check_csum = 0x6cca +check_crc32 = 0xab5d5d9e +hw = prot +prot_ro_value16 = 0x500008,-2,0x5000 + +[Rock World (Unl)] +check_str = 0x113, "KANKO 91-92" +check_crc32 = 0x79423515 +hw = prot +prot_ro_value16 = 0x500008,-2,0x5000 +prot_ro_value16 = 0x500208,-2,0xa000 [Lion King II, The (Unl)] check_str = 0x104, " are Registered Trademarks" -check_crc32 = 0xaff46765 +check_crc32 = 0x7009cac3 hw = prot prot_rw_value16 = 0x400000,0xc00004,0 prot_rw_value16 = 0x400004,0xc00004,0 -[Mahjong Lover (Unl)] -check_str = 0x118, "CREATON. " -check_crc32 = 0xddd02ba4 +[Squirrel King (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0x1c602dd4 hw = prot -prot_ro_value16 = 0x400000,-2,0x9000 -prot_ro_value16 = 0x401000,-2,0xd300 +prot_rw_value16 = 0x400000,0xc00000,0 +prot_rw_value16 = 0x400004,0xc00004,0 -[Pocket Monsters (Unl)] -check_str = 0x104, " " -check_crc32 = 0xf68f6367 +[Tiny Toon Adventures 3 (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0xc31cfcca hw = prot -prot_ro_value16 = 0xa13002,-2,0x01 -prot_ro_value16 = 0xa1303e,-2,0x1f +prot_rw_value16 = 0x400000,0xc00000,0 +prot_rw_value16 = 0x400004,0xc00004,0 -[Pocket Monsters (Unl) [a1]] -check_str = 0x104, " " -check_crc32 = 0xfb176667 +[Barver Battle Saga (Unl)] # Taikong zhanshi +check_csum = 0x30b9 +check_crc32 = 0x35e0ff17 hw = prot -prot_ro_value16 = 0xa13000,-2,0x14 -prot_ro_value16 = 0xa13002,-2,0x01 -prot_ro_value16 = 0xa1303e,-2,0x1f +prot_rw_value16 = 0x400000,0xc00000,0 +prot_rw_value16 = 0x400004,0xc00004,0 -[Rockman X3 (Unl)] -check_csum = 0 -check_crc32 = 0x3ee639f0 +[Water Margin (Unl)] # Shuihu Zhuan +check_csum = 0x6001 +check_crc32 = 0xfa80956a hw = prot -prot_ro_value16 = 0xa13000,-2,0x0c +prot_rw_value16 = 0x400000,0xc00000,0 +prot_rw_value16 = 0x400004,0xc00004,0 + +[Legend of Fengshen Yingjie, The (Unl)] # Fengshen yingjie chuan (Canon) +check_csum = 0xffff +check_crc32 = 0x91865ea4 +hw = prot +prot_rw_value16 = 0x400000,0xc00000,0 +prot_rw_value16 = 0x400004,0xc00004,0 + +[Legend of Arthur, The (Unl)] # Ya se chuanshuo +check_csum = 0xffff +check_crc32 = 0x8e83dbfa +hw = prot +prot_ro_value16 = 0x400000,-2,0x6300 +prot_ro_value16 = 0x400002,-2,0x9800 +prot_ro_value16 = 0x400004,-2,0xc900 +prot_ro_value16 = 0x400006,-2,0x1800 + +[Wucom Legend (Unl)] # Wukong waizhuan +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0xf838aa3b +hw = prot +prot_ro_value16 = 0x400000,-2,0x6300 +prot_ro_value16 = 0x400002,-2,0x9800 +prot_ro_value16 = 0x400004,-2,0xc900 +prot_ro_value16 = 0x400006,-2,0x1800 + +[Super Magician (Unl)] # Ling huan daoshi +check_str = 0x172, "GAME : ELF WOR" +hw = prot +prot_ro_value16 = 0x400000,-2,0x5500 +prot_ro_value16 = 0x400002,-2,0x0f00 # check is done if the above one fails +prot_ro_value16 = 0x400004,-2,0xc900 +prot_ro_value16 = 0x400006,-2,0x1800 # similar to above + +[Mighty Morphin Power Rangers (Unl)] +check_str = 0x104, " " +check_crc32 = 0x5fdeb37b +hw = prot +prot_ro_value16 = 0x400000,-2,0x5500 +prot_ro_value16 = 0x400002,-2,0x0f00 +prot_ro_value16 = 0x400004,-2,0xc900 +prot_ro_value16 = 0x400006,-2,0x1800 -[Smart Mouse (Unl)] +[Smart Mouse (Unl)] # Huanle taoqi shu check_csum = 0 -check_crc32 = 0xdecdf740 +check_crc32 = 0xc9539fce hw = prot prot_ro_value16 = 0x400000,-2,0x5500 prot_ro_value16 = 0x400002,-2,0x0f00 @@ -311,38 +444,57 @@ prot_ro_value16 = 0x400006,-2,0xf000 [Soul Blade (Unl)] check_str = 0x104, " " -check_crc32 = 0xf26f88d1 +check_crc32 = 0x6a95f766 hw = prot +prot_ro_value16 = 0x400000,-2,0x6300 prot_ro_value16 = 0x400002,-2,0x9800 prot_ro_value16 = 0x400004,-2,0xaa00 # or 0xc900 prot_ro_value16 = 0x400006,-2,0xf000 [Super Bubble Bobble (Unl)] check_str = 0x104, " are Registered Trademarks" -check_crc32 = 0x4820a161 +check_crc32 = 0xf93f3d0b hw = prot prot_ro_value16 = 0x400000,-2,0x5500 prot_ro_value16 = 0x400002,-2,0x0f00 -[Super King Kong 99 (Unl)] +[Battle of Red Cliffs, The (Unl)] # Sanguo yanyi (Romance of the 3 Kingdoms) check_str = 0x104, " are Registered Trademarks" -check_crc32 = 0x413dfee2 -hw = prot_lk3 +check_crc32 = 0x66165305 +hw = prot +prot_ro_value16 = 0x400000,-2,0x5500 +prot_ro_value16 = 0x400002,-2,0x0f00 +prot_ro_value16 = 0x400004,-2,0xaa00 +prot_ro_value16 = 0x400006,-2,0xf000 -[Super Mario Bros. (Unl)] -check_str = 0x140, "SUPER MARIO BROS " +[Tunderbolt II (Unl)] # Leidian +check_str = 0xfe, "WISEGAME" +check_crc32 = 0x6f01bd65 hw = prot -prot_ro_value16 = 0xa13000,-2,0x0c +prot_ro_value16 = 0x400000,-2,0x5500 +prot_ro_value16 = 0x400002,-2,0x0f00 +prot_ro_value16 = 0x400004,-2,0xaa00 +prot_ro_value16 = 0x400006,-2,0xf000 -[Super Mario 2 1998 (Unl)] -check_str = 0x104, " are Registered Trademarks" -check_crc32 = 0xf7e1b3e1 +[16 Tiles Mahjong 1+2 (Unl)] # Zhang majiang +check_str = 0xfe, "WISEGAME IS TRADE MARKER" hw = prot -prot_ro_value16 = 0xa13000,-2,0x0a +prot_ro_value16 = 0x400002,-2,0xaa00 +prot_ro_value16 = 0x400004,-2,0xc900 +prot_ro_value16 = 0x400006,-2,0xf000 -[Squirrel King (R)] -check_str = 0x104, " are Registered Trademarks" -check_crc32 = 0xb8261ff5 +[Super Poker (Unl)] # Chaoji puke +check_csum = 0xffff +check_crc32 = 0xdd02797c hw = prot -prot_rw_value16 = 0x400000,0xc00000,0 +prot_ro_value16 = 0x400000,-2,0x5500 +prot_ro_value16 = 0x400002,-2,0x0f00 +prot_ro_value16 = 0x400004,-2,0xaa00 +prot_ro_value16 = 0x400006,-2,0xf000 + +[777 Casino (Unl)] # Menghuan shuiguo pan +check_csum = 0 +check_crc32 = 0xee9fc429 +hw = prot +prot_ro_value16 = 0x400000,-2,0x6300 diff --git a/pico/carthw/carthw.c b/pico/carthw/carthw.c index 0cee14b1..e00843df 100644 --- a/pico/carthw/carthw.c +++ b/pico/carthw/carthw.c @@ -731,10 +731,15 @@ static struct { u32 mask; u16 val; u16 readonly; -} *sprot_items; -static int sprot_item_alloc; +} sprot_items[8]; static int sprot_item_count; +static carthw_state_chunk carthw_sprot_state[] = +{ + { CHUNK_CARTHW, sizeof(sprot_items), &sprot_items }, + { 0, 0, NULL } +}; + static u16 *carthw_sprot_get_val(u32 a, int rw_only) { int i; @@ -752,9 +757,6 @@ static u32 PicoRead8_sprot(u32 a) u16 *val; u32 d; - if (0xa10000 <= a && a < 0xa12000) - return PicoRead8_io(a); - val = carthw_sprot_get_val(a, 0); if (val != NULL) { d = *val; @@ -763,39 +765,33 @@ static u32 PicoRead8_sprot(u32 a) elprintf(EL_UIO, "prot r8 [%06x] %02x @%06x", a, d, SekPc); return d; } - else { - elprintf(EL_UIO, "prot r8 [%06x] MISS @%06x", a, SekPc); - return 0; - } + else if (0xa10000 <= a && a <= 0xa1ffff) + return PicoRead8_io(a); + + elprintf(EL_UIO, "prot r8 [%06x] MISS @%06x", a, SekPc); + return 0; } static u32 PicoRead16_sprot(u32 a) { u16 *val; - if (0xa10000 <= a && a < 0xa12000) - return PicoRead16_io(a); - val = carthw_sprot_get_val(a, 0); if (val != NULL) { elprintf(EL_UIO, "prot r16 [%06x] %04x @%06x", a, *val, SekPc); return *val; } - else { - elprintf(EL_UIO, "prot r16 [%06x] MISS @%06x", a, SekPc); - return 0; - } + else if (0xa10000 <= a && a <= 0xa1ffff) + return PicoRead16_io(a); + + elprintf(EL_UIO, "prot r16 [%06x] MISS @%06x", a, SekPc); + return 0; } static void PicoWrite8_sprot(u32 a, u32 d) { u16 *val; - if (0xa10000 <= a && a < 0xa12000) { - PicoWrite8_io(a, d); - return; - } - val = carthw_sprot_get_val(a, 1); if (val != NULL) { if (a & 1) @@ -804,45 +800,33 @@ static void PicoWrite8_sprot(u32 a, u32 d) *val = (*val & 0x00ff) | (d << 8); elprintf(EL_UIO, "prot w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); } - else - elprintf(EL_UIO, "prot w8 [%06x] %02x MISS @%06x", a, d & 0xff, SekPc); + else if (0xa10000 <= a && a <= 0xa1ffff) + return PicoWrite8_io(a, d); + + elprintf(EL_UIO, "prot w8 [%06x] %02x MISS @%06x", a, d & 0xff, SekPc); } static void PicoWrite16_sprot(u32 a, u32 d) { u16 *val; - if (0xa10000 <= a && a < 0xa12000) { - PicoWrite16_io(a, d); - return; - } - val = carthw_sprot_get_val(a, 1); if (val != NULL) { *val = d; elprintf(EL_UIO, "prot w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); } - else - elprintf(EL_UIO, "prot w16 [%06x] %04x MISS @%06x", a, d & 0xffff, SekPc); + else if (0xa10000 <= a && a <= 0xa1ffff) + return PicoWrite16_io(a, d); + + elprintf(EL_UIO, "prot w16 [%06x] %04x MISS @%06x", a, d & 0xffff, SekPc); } void carthw_sprot_new_location(unsigned int a, unsigned int mask, unsigned short val, int is_ro) { - if (sprot_items == NULL) { - sprot_items = calloc(8, sizeof(sprot_items[0])); - sprot_item_alloc = 8; - sprot_item_count = 0; - } - - if (sprot_item_count == sprot_item_alloc) { - void *tmp; - sprot_item_alloc *= 2; - tmp = realloc(sprot_items, sprot_item_alloc); - if (tmp == NULL) { - elprintf(EL_STATUS, "OOM"); - return; - } - sprot_items = tmp; + int sprot_elems = sizeof(sprot_items)/sizeof(sprot_items[0]); + if (sprot_item_count == sprot_elems) { + elprintf(EL_STATUS, "too many sprot items"); + return; } sprot_items[sprot_item_count].addr = a; @@ -854,17 +838,17 @@ void carthw_sprot_new_location(unsigned int a, unsigned int mask, unsigned short static void carthw_sprot_unload(void) { - free(sprot_items); - sprot_items = NULL; - sprot_item_count = sprot_item_alloc = 0; + sprot_item_count = 0; } static void carthw_sprot_mem_setup(void) { int start; - // map ROM - 0x7fffff, /TIME areas (which are tipically used) + // map 0x400000 - 0x7fffff, /TIME areas (which are tipically used) start = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK; + if (start < 0x400000) start = 0x400000; + cpu68k_map_set(m68k_read8_map, start, 0x7fffff, PicoRead8_sprot, 1); cpu68k_map_set(m68k_read16_map, start, 0x7fffff, PicoRead16_sprot, 1); cpu68k_map_set(m68k_write8_map, start, 0x7fffff, PicoWrite8_sprot, 1); @@ -882,32 +866,41 @@ void carthw_sprot_startup(void) PicoCartMemSetup = carthw_sprot_mem_setup; PicoCartUnloadHook = carthw_sprot_unload; + carthw_chunks = carthw_sprot_state; } /* Protection emulation for Lion King 3. Credits go to Haze */ -static u8 prot_lk3_cmd, prot_lk3_data; +static struct { + u32 bank; + u8 cmd, data; +} carthw_lk3_regs; + +static carthw_state_chunk carthw_lk3_state[] = +{ + { CHUNK_CARTHW, sizeof(carthw_lk3_regs), &carthw_lk3_regs }, + { 0, 0, NULL } +}; + +static u8 *carthw_lk3_mem; // shadow copy memory +static u32 carthw_lk3_madr[0x100000/M68K_BANK_SIZE]; static u32 PicoRead8_plk3(u32 a) { u32 d = 0; - switch (prot_lk3_cmd) { - case 1: d = prot_lk3_data >> 1; break; + switch (carthw_lk3_regs.cmd) { + case 0: d = carthw_lk3_regs.data << 1; break; + case 1: d = carthw_lk3_regs.data >> 1; break; case 2: // nibble rotate - d = ((prot_lk3_data >> 4) | (prot_lk3_data << 4)) & 0xff; + d = ((carthw_lk3_regs.data >> 4) | (carthw_lk3_regs.data << 4)) & 0xff; break; case 3: // bit rotate - d = prot_lk3_data; + d = carthw_lk3_regs.data; d = (d >> 4) | (d << 4); d = ((d & 0xcc) >> 2) | ((d & 0x33) << 2); d = ((d & 0xaa) >> 1) | ((d & 0x55) << 1); break; -/* Top Fighter 2000 MK VIII (Unl) - case 0x98: d = 0x50; break; // prot_lk3_data == a8 here - case 0x67: d = 0xde; break; // prot_lk3_data == 7b here (rot!) - case 0xb5: d = 0x9f; break; // prot_lk3_data == 4a -*/ default: - elprintf(EL_UIO, "unhandled prot cmd %02x @%06x", prot_lk3_cmd, SekPc); + elprintf(EL_UIO, "unhandled prot cmd %02x @%06x", carthw_lk3_regs.cmd, SekPc); break; } @@ -919,49 +912,207 @@ static void PicoWrite8_plk3p(u32 a, u32 d) { elprintf(EL_UIO, "prot w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); if (a & 2) - prot_lk3_cmd = d; + carthw_lk3_regs.cmd = d & 0x3; else - prot_lk3_data = d; + carthw_lk3_regs.data = d; } static void PicoWrite8_plk3b(u32 a, u32 d) { - int addr; + u32 addr; elprintf(EL_UIO, "prot w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); addr = d << 15; - if (addr + 0x8000 > Pico.romsize) { - elprintf(EL_UIO|EL_ANOMALY, "prot_lk3: bank too large: %02x", d); + if (addr+0x10000 >= Pico.romsize) { + elprintf(EL_UIO|EL_ANOMALY, "lk3_mapper: bank too large: %02x", d); return; } - if (addr == 0) - memcpy(Pico.rom, Pico.rom + Pico.romsize, 0x8000); - else - memcpy(Pico.rom, Pico.rom + addr, 0x8000); + + if (addr != carthw_lk3_regs.bank) { + // banking is by or'ing the bank address in the 1st megabyte, not adding. + // only do linear mapping if map addresses aren't overlapping bank address + u32 len = M68K_BANK_SIZE; + u32 a, b; + for (b = 0x000000; b < 0x0100000; b += len) { + if (!((b + (len-1)) & addr)) { + cpu68k_map_set(m68k_read8_map, b, b + (len-1), Pico.rom+addr + b, 0); + cpu68k_map_set(m68k_read16_map, b, b + (len-1), Pico.rom+addr + b, 0); + } else { + // overlap. ugh, need a shadow copy since banks can contain code and + // 68K cpu emulator cores need mapped access to code memory + if (carthw_lk3_madr[b/len] != addr) // only if shadow isn't the same + for (a = b; a < b+M68K_BANK_SIZE; a += 0x8000) + memcpy(carthw_lk3_mem + a, Pico.rom + (addr|a), 0x8000); + carthw_lk3_madr[b/len] = addr; + cpu68k_map_set(m68k_read8_map, b, b + (len-1), carthw_lk3_mem + b, 0); + cpu68k_map_set(m68k_read16_map, b, b + (len-1), carthw_lk3_mem + b, 0); + } + } + } + carthw_lk3_regs.bank = addr; } -static void carthw_prot_lk3_mem_setup(void) +static void carthw_lk3_mem_setup(void) { cpu68k_map_set(m68k_read8_map, 0x600000, 0x7fffff, PicoRead8_plk3, 1); cpu68k_map_set(m68k_write8_map, 0x600000, 0x6fffff, PicoWrite8_plk3p, 1); cpu68k_map_set(m68k_write8_map, 0x700000, 0x7fffff, PicoWrite8_plk3b, 1); + carthw_lk3_regs.bank = 0; } -void carthw_prot_lk3_startup(void) +static void carthw_lk3_statef(void) { - int ret; + PicoWrite8_plk3b(0x700000, carthw_lk3_regs.bank >> 15); +} + +static void carthw_lk3_unload(void) +{ + free(carthw_lk3_mem); + carthw_lk3_mem = NULL; + memset(carthw_lk3_madr, 0, sizeof(carthw_lk3_madr)); +} +void carthw_lk3_startup(void) +{ elprintf(EL_STATUS, "lk3 prot emu startup"); - // allocate space for bank0 backup - ret = PicoCartResize(Pico.romsize + 0x8000); - if (ret != 0) { + // allocate space for shadow copy + if (carthw_lk3_mem == NULL) + carthw_lk3_mem = malloc(0x100000); + if (carthw_lk3_mem == NULL) { elprintf(EL_STATUS, "OOM"); return; } - memcpy(Pico.rom + Pico.romsize, Pico.rom, 0x8000); - PicoCartMemSetup = carthw_prot_lk3_mem_setup; + PicoCartMemSetup = carthw_lk3_mem_setup; + PicoLoadStateHook = carthw_lk3_statef; + PicoCartUnloadHook = carthw_lk3_unload; + carthw_chunks = carthw_lk3_state; +} + +/* SMW64 mapper, based on mame source */ +static struct { + u32 bank60, bank61; + u16 data[8], ctrl[4]; +} carthw_smw64_regs; + +static carthw_state_chunk carthw_smw64_state[] = +{ + { CHUNK_CARTHW, sizeof(carthw_smw64_regs), &carthw_smw64_regs }, + { 0, 0, NULL } +}; + +static u32 PicoRead8_smw64(u32 a) +{ + u16 *data = carthw_smw64_regs.data, *ctrl = carthw_smw64_regs.ctrl; + u32 d = 0; + + if (a & 1) { + if (a>>16 == 0x66) switch ((a>>1) & 7) { + case 0: d = carthw_smw64_regs.data[0] ; break; + case 1: d = carthw_smw64_regs.data[0]+1; break; + case 2: d = carthw_smw64_regs.data[1] ; break; + case 3: d = carthw_smw64_regs.data[1]+1; break; + case 4: d = carthw_smw64_regs.data[2] ; break; + case 5: d = carthw_smw64_regs.data[2]+1; break; + case 6: d = carthw_smw64_regs.data[2]+2; break; + case 7: d = carthw_smw64_regs.data[2]+3; break; + } else /*0x67*/ { // :-O + if (ctrl[1] & 0x80) + d = ctrl[2] & 0x40 ? data[4]&data[5] : data[4]^0xff; + if (a & 2) + d &= 0x7f; + else if (ctrl[2] & 0x80) { + if (ctrl[2] & 0x20) + data[2] = (data[5] << 2) & 0xfc; + else + data[0] = ((data[4] << 1) ^ data[3]) & 0xfe; + } + } + } + + elprintf(EL_UIO, "prot r8 [%06x] %02x @%06x", a, d, SekPc); + return d; +} + +static u32 PicoRead16_smw64(u32 a) +{ + return PicoRead8_smw64(a+1); +} + +static void PicoWrite8_smw64(u32 a, u32 d) +{ + u16 *data = carthw_smw64_regs.data, *ctrl = carthw_smw64_regs.ctrl; + + if ((a & 3) == 1) { + switch (a >> 16) { + case 0x60: ctrl[0] = d; break; + case 0x64: data[4] = d; break; + case 0x67: + if (ctrl[1] & 0x80) { + carthw_smw64_regs.bank60 = 0x80000 + ((d<<14) & 0x70000); + cpu68k_map_set(m68k_read8_map, 0x600000, 0x60ffff, Pico.rom + carthw_smw64_regs.bank60, 0); + cpu68k_map_set(m68k_read16_map, 0x600000, 0x60ffff, Pico.rom + carthw_smw64_regs.bank60, 0); + } + ctrl[2] = d; + } + } else if ((a & 3) == 3) { + switch (a >> 16) { + case 0x61: ctrl[1] = d; break; + case 0x64: data[5] = d; break; + case 0x60: + switch (ctrl[0] & 7) { // :-O + case 0: data[0] = (data[0]^data[3] ^ d) & 0xfe; break; + case 1: data[1] = ( d) & 0xfe; break; + case 7: + carthw_smw64_regs.bank61 = 0x80000 + ((d<<14) & 0x70000); + cpu68k_map_set(m68k_read8_map, 0x610000, 0x61ffff, Pico.rom + carthw_smw64_regs.bank61, 0); + cpu68k_map_set(m68k_read16_map, 0x610000, 0x61ffff, Pico.rom + carthw_smw64_regs.bank61, 0); + break; + } + data[3] = d; + } + } +} + +static void PicoWrite16_smw64(u32 a, u32 d) +{ + PicoWrite8_smw64(a+1, d); +} + +static void carthw_smw64_mem_setup(void) +{ + // 1st 512 KB mirrored + cpu68k_map_set(m68k_read8_map, 0x080000, 0x0fffff, Pico.rom, 0); + cpu68k_map_set(m68k_read16_map, 0x080000, 0x0fffff, Pico.rom, 0); + + cpu68k_map_set(m68k_read8_map, 0x660000, 0x67ffff, PicoRead8_smw64, 1); + cpu68k_map_set(m68k_read16_map, 0x660000, 0x67ffff, PicoRead16_smw64, 1); + cpu68k_map_set(m68k_write8_map, 0x600000, 0x67ffff, PicoWrite8_smw64, 1); + cpu68k_map_set(m68k_write16_map, 0x600000, 0x67ffff, PicoWrite16_smw64, 1); +} + +static void carthw_smw64_statef(void) +{ + cpu68k_map_set(m68k_read8_map, 0x600000, 0x60ffff, Pico.rom + carthw_smw64_regs.bank60, 0); + cpu68k_map_set(m68k_read16_map, 0x600000, 0x60ffff, Pico.rom + carthw_smw64_regs.bank60, 0); + cpu68k_map_set(m68k_read8_map, 0x610000, 0x61ffff, Pico.rom + carthw_smw64_regs.bank61, 0); + cpu68k_map_set(m68k_read16_map, 0x610000, 0x61ffff, Pico.rom + carthw_smw64_regs.bank61, 0); +} + +static void carthw_smw64_reset(void) +{ + memset(&carthw_smw64_regs, 0, sizeof(carthw_smw64_regs)); +} + +void carthw_smw64_startup(void) +{ + elprintf(EL_STATUS, "SMW64 mapper startup"); + + PicoCartMemSetup = carthw_smw64_mem_setup; + PicoResetHook = carthw_smw64_reset; + PicoLoadStateHook = carthw_smw64_statef; + carthw_chunks = carthw_smw64_state; } // vim:ts=2:sw=2:expandtab diff --git a/pico/carthw/carthw.h b/pico/carthw/carthw.h index bea69f0d..bcf91da3 100644 --- a/pico/carthw/carthw.h +++ b/pico/carthw/carthw.h @@ -34,4 +34,5 @@ void carthw_sprot_startup(void); void carthw_sprot_new_location(unsigned int a, unsigned int mask, unsigned short val, int is_ro); -void carthw_prot_lk3_startup(void); +void carthw_lk3_startup(void); +void carthw_smw64_startup(void); diff --git a/pico/carthw_cfg.c b/pico/carthw_cfg.c index 76de4a00..0de53f7b 100644 --- a/pico/carthw_cfg.c +++ b/pico/carthw_cfg.c @@ -152,62 +152,167 @@ static const char builtin_carthw_cfg[] = "eeprom_type=1\n" "eeprom_lines=6,7,7\n" "[]\n" + "check_str=0x104,\" are Registered Trademarks\"\n" + "check_crc32=0xc9706e25\n" + "hw=lk3_mapper\n" + "[]\n" + "check_str=0x104,\" are Registered Trademarks\"\n" + "check_crc32=0x4c98cc30\n" + "hw=lk3_mapper\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0x0d097f5c\n" + "hw=lk3_mapper\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0xbf7219df\n" + "hw=lk3_mapper\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0xb5b7606e\n" + "hw=lk3_mapper\n" + "[]\n" "check_str=0x104,\" \"\n" - "check_crc32=0x10458e09\n" + "check_crc32=0xab3ae5e9\n" + "hw=lk3_mapper\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0x802f53f9\n" + "hw=lk3_mapper\n" + "[]\n" + "check_csum=0\n" + "check_crc32=0xf63b7bdc\n" + "hw=smw64_mapper\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0x50aa5a9b\n" "hw=prot\n" "prot_ro_value16=0xa13000,0xffff00,0x28\n" "[]\n" - "check_str=0x172,\"GAME : ELF WOR\"\n" + "check_csum=0\n" + "check_crc32=0xee20be2c\n" "hw=prot\n" - "prot_ro_value16=0x400000,-2,0x5500\n" - "prot_ro_value16=0x400002,-2,0xc900#checkisdoneiftheaboveonefails\n" - "prot_ro_value16=0x400004,-2,0x0f00\n" - "prot_ro_value16=0x400006,-2,0x1800#similartoabove\n" + "prot_ro_value16=0xa13000,-2,0x0c\n" + "[]\n" + "check_str=0x104,\"SEGASEGASEGA\"\n" + "check_crc32=0xc3616596\n" + "hw=prot\n" + "prot_ro_value16=0xa13000,-2,0x1c\n" + "[]\n" + "check_str=0x104,\" are Registered Trademarks\"\n" + "check_crc32=0x7861fb28\n" + "hw=prot\n" + "prot_ro_value16=0xa13000,-2,0x0a\n" "[]\n" "check_str=0x104,\" \"\n" - "check_crc32=0xcbc38eea\n" + "check_crc32=0xf4cb9b37\n" + "hw=prot\n" + "prot_ro_value16=0xa13000,-2,0x00\n" + "prot_ro_value16=0xa13002,-2,0x01\n" + "prot_ro_value16=0xa1303e,-2,0x1f\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0x7bdfb390\n" + "hw=prot\n" + "prot_ro_value16=0xa13000,-2,0x00\n" + "prot_ro_value16=0xa13002,-2,0x01\n" + "prot_ro_value16=0xa1303e,-2,0x1f\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0x8fb8b29e\n" "hw=prot\n" "prot_ro_value16=0x480000,0xff0000,0xaa00\n" "prot_ro_value16=0x4a0000,0xff0000,0x0a00\n" "prot_ro_value16=0x4c0000,0xff0000,0xf000\n" "prot_ro_value16=0x400000,0xc00000,0x0000#defaultfor400000-7f0000\n" "[]\n" - "check_str=0x104,\" are Registered Trademarks\"\n" - "check_crc32=0xc004219d\n" - "hw=prot_lk3\n" + "check_str=0x104,\" MEGA DRIVE (C)\"\n" + "check_str=0x118,\"CREATON.\"\n" + "check_str=0x180,\"MDGM-000\"\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x9000\n" + "prot_ro_value16=0x401000,-2,0xd300\n" + "[]\n" + "check_csum=0x6cca\n" + "check_crc32=0xab5d5d9e\n" + "hw=prot\n" + "prot_ro_value16=0x500008,-2,0x5000\n" + "[]\n" + "check_str=0x113,\"KANKO 91-92\"\n" + "check_crc32=0x79423515\n" + "hw=prot\n" + "prot_ro_value16=0x500008,-2,0x5000\n" + "prot_ro_value16=0x500208,-2,0xa000\n" "[]\n" "check_str=0x104,\" are Registered Trademarks\"\n" - "check_crc32=0xaff46765\n" + "check_crc32=0x7009cac3\n" "hw=prot\n" "prot_rw_value16=0x400000,0xc00004,0\n" "prot_rw_value16=0x400004,0xc00004,0\n" "[]\n" - "check_str=0x118,\"CREATON. \"\n" - "check_crc32=0xddd02ba4\n" + "check_str=0x104,\" are Registered Trademarks\"\n" + "check_crc32=0x1c602dd4\n" "hw=prot\n" - "prot_ro_value16=0x400000,-2,0x9000\n" - "prot_ro_value16=0x401000,-2,0xd300\n" + "prot_rw_value16=0x400000,0xc00000,0\n" + "prot_rw_value16=0x400004,0xc00004,0\n" "[]\n" - "check_str=0x104,\" \"\n" - "check_crc32=0xf68f6367\n" + "check_str=0x104,\" are Registered Trademarks\"\n" + "check_crc32=0xc31cfcca\n" "hw=prot\n" - "prot_ro_value16=0xa13002,-2,0x01\n" - "prot_ro_value16=0xa1303e,-2,0x1f\n" + "prot_rw_value16=0x400000,0xc00000,0\n" + "prot_rw_value16=0x400004,0xc00004,0\n" "[]\n" - "check_str=0x104,\" \"\n" - "check_crc32=0xfb176667\n" + "check_csum=0x30b9\n" + "check_crc32=0x35e0ff17\n" "hw=prot\n" - "prot_ro_value16=0xa13000,-2,0x14\n" - "prot_ro_value16=0xa13002,-2,0x01\n" - "prot_ro_value16=0xa1303e,-2,0x1f\n" + "prot_rw_value16=0x400000,0xc00000,0\n" + "prot_rw_value16=0x400004,0xc00004,0\n" "[]\n" - "check_csum=0\n" - "check_crc32=0x3ee639f0\n" + "check_csum=0x6001\n" + "check_crc32=0xfa80956a\n" "hw=prot\n" - "prot_ro_value16=0xa13000,-2,0x0c\n" + "prot_rw_value16=0x400000,0xc00000,0\n" + "prot_rw_value16=0x400004,0xc00004,0\n" + "[]\n" + "check_csum=0xffff\n" + "check_crc32=0x91865ea4\n" + "hw=prot\n" + "prot_rw_value16=0x400000,0xc00000,0\n" + "prot_rw_value16=0x400004,0xc00004,0\n" + "[]\n" + "check_csum=0xffff\n" + "check_crc32=0x8e83dbfa\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x6300\n" + "prot_ro_value16=0x400002,-2,0x9800\n" + "prot_ro_value16=0x400004,-2,0xc900\n" + "prot_ro_value16=0x400006,-2,0x1800\n" + "[]\n" + "check_str=0x104,\" are Registered Trademarks\"\n" + "check_crc32=0xf838aa3b\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x6300\n" + "prot_ro_value16=0x400002,-2,0x9800\n" + "prot_ro_value16=0x400004,-2,0xc900\n" + "prot_ro_value16=0x400006,-2,0x1800\n" + "[]\n" + "check_str=0x172,\"GAME : ELF WOR\"\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x5500\n" + "prot_ro_value16=0x400002,-2,0x0f00#checkisdoneiftheaboveonefails\n" + "prot_ro_value16=0x400004,-2,0xc900\n" + "prot_ro_value16=0x400006,-2,0x1800#similartoabove\n" + "[]\n" + "check_str=0x104,\" \"\n" + "check_crc32=0x5fdeb37b\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x5500\n" + "prot_ro_value16=0x400002,-2,0x0f00\n" + "prot_ro_value16=0x400004,-2,0xc900\n" + "prot_ro_value16=0x400006,-2,0x1800\n" "[]\n" "check_csum=0\n" - "check_crc32=0xdecdf740\n" + "check_crc32=0xc9539fce\n" "hw=prot\n" "prot_ro_value16=0x400000,-2,0x5500\n" "prot_ro_value16=0x400002,-2,0x0f00\n" @@ -215,33 +320,51 @@ static const char builtin_carthw_cfg[] = "prot_ro_value16=0x400006,-2,0xf000\n" "[]\n" "check_str=0x104,\" \"\n" - "check_crc32=0xf26f88d1\n" + "check_crc32=0x6a95f766\n" "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x6300\n" "prot_ro_value16=0x400002,-2,0x9800\n" "prot_ro_value16=0x400004,-2,0xaa00#or0xc900\n" "prot_ro_value16=0x400006,-2,0xf000\n" "[]\n" "check_str=0x104,\" are Registered Trademarks\"\n" - "check_crc32=0x4820a161\n" + "check_crc32=0xf93f3d0b\n" "hw=prot\n" "prot_ro_value16=0x400000,-2,0x5500\n" "prot_ro_value16=0x400002,-2,0x0f00\n" "[]\n" "check_str=0x104,\" are Registered Trademarks\"\n" - "check_crc32=0x413dfee2\n" - "hw=prot_lk3\n" + "check_crc32=0x66165305\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x5500\n" + "prot_ro_value16=0x400002,-2,0x0f00\n" + "prot_ro_value16=0x400004,-2,0xaa00\n" + "prot_ro_value16=0x400006,-2,0xf000\n" "[]\n" - "check_str=0x140,\"SUPER MARIO BROS \"\n" + "check_str=0xfe,\"WISEGAME\"\n" + "check_crc32=0x6f01bd65\n" "hw=prot\n" - "prot_ro_value16=0xa13000,-2,0x0c\n" + "prot_ro_value16=0x400000,-2,0x5500\n" + "prot_ro_value16=0x400002,-2,0x0f00\n" + "prot_ro_value16=0x400004,-2,0xaa00\n" + "prot_ro_value16=0x400006,-2,0xf000\n" "[]\n" - "check_str=0x104,\" are Registered Trademarks\"\n" - "check_crc32=0xf7e1b3e1\n" + "check_str=0xfe,\"WISEGAME IS TRADE MARKER\"\n" "hw=prot\n" - "prot_ro_value16=0xa13000,-2,0x0a\n" + "prot_ro_value16=0x400002,-2,0xaa00\n" + "prot_ro_value16=0x400004,-2,0xc900\n" + "prot_ro_value16=0x400006,-2,0xf000\n" "[]\n" - "check_str=0x104,\" are Registered Trademarks\"\n" - "check_crc32=0xb8261ff5\n" + "check_csum=0xffff\n" + "check_crc32=0xdd02797c\n" "hw=prot\n" - "prot_rw_value16=0x400000,0xc00000,0\n" + "prot_ro_value16=0x400000,-2,0x5500\n" + "prot_ro_value16=0x400002,-2,0x0f00\n" + "prot_ro_value16=0x400004,-2,0xaa00\n" + "prot_ro_value16=0x400006,-2,0xf000\n" + "[]\n" + "check_csum=0\n" + "check_crc32=0xee9fc429\n" + "hw=prot\n" + "prot_ro_value16=0x400000,-2,0x6300\n" ; diff --git a/pico/memory.c b/pico/memory.c index 89093932..1fbb47b8 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -833,7 +833,7 @@ PICO_INTERNAL void PicoMemSetup(void) // align to bank size. We know ROM loader allocated enough for this mask = (1 << M68K_MEM_SHIFT) - 1; rs = (Pico.romsize + mask) & ~mask; - if (rs > 0x400000) rs = 0x400000; // max cartridge area + if (rs > 0xa00000) rs = 0xa00000; // max cartridge area cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico.rom, 0); cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico.rom, 0);