From 000f53350cb0d6540310d8c4b02eb034c9662f0d Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 9 Sep 2009 16:00:42 +0000 Subject: [PATCH] protection and more mapper support for new mem code git-svn-id: file:///home/notaz/opt/svn/PicoDrive@771 be3aeb3a-fb24-0410-a615-afba39da0efa --- pico/cart.c | 92 +++++++++-- pico/carthw.cfg | 128 ++++++++++++++- pico/carthw/carthw.c | 304 ++++++++++++++++++++++++++++++++++- pico/carthw/carthw.h | 7 + pico/memory.c | 87 ---------- pico/pico.h | 1 - platform/linux/port_config.h | 2 +- 7 files changed, 512 insertions(+), 109 deletions(-) diff --git a/pico/cart.c b/pico/cart.c index 5eb89c9..067b422 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -379,7 +379,7 @@ int pm_close(pm_file *fp) } -void Byteswap(unsigned char *data,int len) +static void Byteswap(unsigned char *data,int len) { int i=0; @@ -612,6 +612,18 @@ void PicoCartUnload(void) } } +static unsigned int rom_crc32(void) +{ + unsigned int crc; + elprintf(EL_STATUS, "caclulating CRC32.."); + + // have to unbyteswap for calculation.. + Byteswap(Pico.rom, Pico.romsize); + crc = crc32(0, Pico.rom, Pico.romsize); + Byteswap(Pico.rom, Pico.romsize); + return crc; +} + static int rom_strcmp(int rom_offset, const char *s1) { int i, len = strlen(s1); @@ -643,6 +655,30 @@ static void rstrip(char *s) *p = 0; } +static int parse_3_vals(char *p, int *val0, int *val1, int *val2) +{ + char *r; + *val0 = strtoul(p, &r, 0); + if (r == p) + goto bad; + p = sskip(r); + if (*p++ != ',') + goto bad; + *val1 = strtoul(p, &r, 0); + if (r == p) + goto bad; + p = sskip(r); + if (*p++ != ',') + goto bad; + *val2 = strtoul(p, &r, 0); + if (r == p) + goto bad; + + return 1; +bad: + return 0; +} + static int is_expr(const char *expr, char **pr) { int len = strlen(expr); @@ -661,6 +697,7 @@ static int is_expr(const char *expr, char **pr) static void parse_carthw(int *fill_sram) { int line = 0, any_checks_passed = 0, skip_sect = 0; + int tmp, rom_crc = 0; char buff[256], *p, *r; FILE *f; @@ -739,6 +776,21 @@ static void parse_carthw(int *fill_sram) skip_sect = 1; continue; } + else if (is_expr("check_crc32", &p)) + { + unsigned int crc; + crc = strtoul(p, &r, 0); + if (r == p) + goto bad; + + if (rom_crc == 0) + rom_crc = rom_crc32(); + if (crc == rom_crc) + any_checks_passed = 1; + else + skip_sect = 1; + continue; + } /* now time for actions */ if (is_expr("hw", &p)) { @@ -750,12 +802,18 @@ static void parse_carthw(int *fill_sram) PicoSVPStartup(); else if (strcmp(p, "pico") == 0) PicoInitPico(); + else if (strcmp(p, "prot") == 0) + carthw_sprot_startup(); + else if (strcmp(p, "ssf2_mapper") == 0) + carthw_ssf2_startup(); else if (strcmp(p, "x_in_1_mapper") == 0) carthw_Xin1_startup(); else if (strcmp(p, "realtec_mapper") == 0) carthw_realtec_startup(); else if (strcmp(p, "radica_mapper") == 0) carthw_radica_startup(); + else if (strcmp(p, "prot_lk3") == 0) + carthw_prot_lk3_startup(); else { elprintf(EL_STATUS, "carthw:%d: unsupported mapper: %s", line, p); skip_sect = 1; @@ -823,20 +881,10 @@ static void parse_carthw(int *fill_sram) goto no_checks; rstrip(p); - scl = strtoul(p, &r, 0); - if (r == p || scl < 0 || scl > 15) - goto bad; - p = sskip(r); - if (*p++ != ',') + if (!parse_3_vals(p, &scl, &sda_in, &sda_out)) goto bad; - sda_in = strtoul(p, &r, 0); - if (r == p || sda_in < 0 || sda_in > 15) - goto bad; - p = sskip(r); - if (*p++ != ',') - goto bad; - sda_out = strtoul(p, &r, 0); - if (r == p || sda_out < 0 || sda_out > 15) + if (scl < 0 || scl > 15 || sda_in < 0 || sda_in > 15 || + sda_out < 0 || sda_out > 15) goto bad; SRam.eeprom_bit_cl = scl; @@ -844,6 +892,18 @@ static void parse_carthw(int *fill_sram) SRam.eeprom_bit_out= sda_out; continue; } + else if ((tmp = is_expr("prot_ro_value16", &p)) || is_expr("prot_rw_value16", &p)) { + int addr, mask, val; + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + if (!parse_3_vals(p, &addr, &mask, &val)) + goto bad; + + carthw_sprot_new_location(addr, mask, val, tmp ? 1 : 0); + continue; + } bad: @@ -865,9 +925,7 @@ no_checks: */ static void PicoCartDetect(void) { - int fill_sram = 0, csum; - - csum = rom_read32(0x18c) & 0xffff; + int fill_sram = 0; memset(&SRam, 0, sizeof(SRam)); if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A') diff --git a/pico/carthw.cfg b/pico/carthw.cfg index 140cb0a..36c8cf8 100644 --- a/pico/carthw.cfg +++ b/pico/carthw.cfg @@ -1,6 +1,8 @@ # hardware (hw = ...): -# svp - Sega Virtua Processor -# pico - Sega Pico (not really cart hw, but convenient to support here) +# 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. # # cartridge properties (prop = ...): # no_sram - don't emulate sram/EEPROM even if ROM headers tell it's there @@ -8,6 +10,7 @@ # filled_sram - save storage needs to be initialized with FFh instead of 00h # # mappers (hw = ...): +# ssf2_mapper - used in Super Street Fighter2 # x_in_1_mapper - used in many *-in-1 pirate carts # realtec_mapper # radica_mapper - similar to x_in_1_mapper @@ -21,6 +24,10 @@ # eeprom_lines = # - select data bus pins that are connected to EEPROM # SCL, SDA_IN and SDA_OUT pins (0-15 for D0-D15). +# hw = prot: +# prot_ro_value16 = - return constant on reads at location +# ( & ), ignore writes. +# prot_rw_value16 = - same as above, but writeable [Virtua Racing - SVP] check_str = 0x150, "Virtua Racing" @@ -52,6 +59,12 @@ prop = filled_sram check_str = 0x150, "MICRO MACHINES II" prop = filled_sram +# The SSF2 mapper +[Super Street Fighter II - The New Challengers (U)] +check_str = 0x150, "SUPER STREET FIGHTER2 The New Challengers" +hw = ssf2_mapper +prop = no_sram + # detect *_in_1 based on first game and if it's larger than it should be, # as some dumps look like to be incomplete. # This will also pick overdumps, but those should still work with the mapper applied. @@ -178,3 +191,114 @@ sram_range = 0x200000,0x200001 eeprom_type = 1 eeprom_lines = 6,7,7 +# Unlicensed games with simple protections +# some of these come from Haze, some from myself (notaz). +[Bug's Life, A (Unl)] +check_str = 0x104, " " +check_crc32 = 0x10458e09 +hw = prot +prot_ro_value16 = 0xa13000,0xffff00,0x28 + +[Elf Wor (Unl)] +check_str = 0x172, "GAME : ELF WOR" +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 + +[King of Fighters '98, The (Unl)] +check_str = 0x104, " " +check_crc32 = 0xcbc38eea +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 + +[Lion King II, The (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0xaff46765 +hw = prot +prot_rw_value16 = 0x400000,0xc00004,0 +prot_rw_value16 = 0x400004,0xc00004,0 + +[Mahjong Lover (Unl)] +check_str = 0x118, "CREATON. " +check_crc32 = 0xddd02ba4 +hw = prot +prot_ro_value16 = 0x400000,-2,0x9000 +prot_ro_value16 = 0x401000,-2,0xd300 + +[Pocket Monsters (Unl)] +check_str = 0x104, " " +check_crc32 = 0xf68f6367 +hw = prot +prot_ro_value16 = 0xa13002,-2,0x01 +prot_ro_value16 = 0xa1303e,-2,0x1f + +[Pocket Monsters (Unl) [a1]] +check_str = 0x104, " " +check_crc32 = 0xfb176667 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x14 +prot_ro_value16 = 0xa13002,-2,0x01 +prot_ro_value16 = 0xa1303e,-2,0x1f + +[Rockman X3 (Unl)] +check_csum = 0 +check_crc32 = 0x3ee639f0 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x0c + +[Smart Mouse (Unl)] +check_csum = 0 +check_crc32 = 0xdecdf740 +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 + +[Soul Blade (Unl)] +check_str = 0x104, " " +check_crc32 = 0xf26f88d1 +hw = prot +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 +hw = prot +prot_ro_value16 = 0x400000,-2,0x5500 +prot_ro_value16 = 0x400002,-2,0x0f00 + +[Super King Kong 99 (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0x413dfee2 +hw = prot_lk3 + +[Super Mario Bros. (Unl)] +check_str = 0x140, "SUPER MARIO BROS " +hw = prot +prot_ro_value16 = 0xa13000,-2,0x0c + +[Super Mario 2 1998 (Unl)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0xf7e1b3e1 +hw = prot +prot_ro_value16 = 0xa13000,-2,0x0a + +[Squirrel King (R)] +check_str = 0x104, " are Registered Trademarks" +check_crc32 = 0xb8261ff5 +hw = prot +prot_rw_value16 = 0x400000,0xc00000,0 + diff --git a/pico/carthw/carthw.c b/pico/carthw/carthw.c index 6424f1e..9d81f8e 100644 --- a/pico/carthw/carthw.c +++ b/pico/carthw/carthw.c @@ -1,5 +1,5 @@ /* - * Support for a few cart mappers. + * Support for a few cart mappers and some protection. * * (c) Copyright 2008-2009, Grazvydas "notaz" Ignotas * Free for non-commercial use. @@ -10,6 +10,68 @@ #include "../memory.h" +/* The SSFII mapper */ +unsigned char ssf2_banks[8]; + +static carthw_state_chunk carthw_ssf2_state[] = +{ + { CHUNK_CARTHW, sizeof(ssf2_banks), &ssf2_banks }, + { 0, 0, NULL } +}; + +static void carthw_ssf2_write8(u32 a, u32 d) +{ + u32 target, base; + + if ((a & 0xfffff0) != 0xa130f0) { + PicoWrite8_io(a, d); + return; + } + + a &= 0x0e; + if (a == 0) + return; + + ssf2_banks[a >> 1] = d; + base = d << 19; + target = a << 18; + if (base + 0x80000 > Pico.romsize) { + elprintf(EL_ANOMALY|EL_STATUS, "ssf2: missing bank @ %06x", base); + return; + } + + cpu68k_map_set(m68k_read8_map, target, target + 0x80000 - 1, Pico.rom + base, 0); + cpu68k_map_set(m68k_read16_map, target, target + 0x80000 - 1, Pico.rom + base, 0); +} + +static void carthw_ssf2_mem_setup(void) +{ + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, carthw_ssf2_write8, 1); +} + +static void carthw_ssf2_statef(void) +{ + int i; + for (i = 1; i < 8; i++) + carthw_ssf2_write8(0xa130f0 | (i << 1), ssf2_banks[i]); +} + +void carthw_ssf2_startup(void) +{ + int i; + + elprintf(EL_STATUS, "SSF2 mapper startup"); + + // default map + for (i = 0; i < 8; i++) + ssf2_banks[i] = i; + + PicoCartMemSetup = carthw_ssf2_mem_setup; + PicoLoadStateHook = carthw_ssf2_statef; + carthw_chunks = carthw_ssf2_state; +} + + /* Common *-in-1 pirate mapper. * Switches banks based on addr lines when /TIME is set. * TODO: verify @@ -202,3 +264,243 @@ void carthw_radica_startup(void) carthw_chunks = carthw_Xin1_state; } +/* Simple unlicensed ROM protection emulation */ +static struct { + u32 addr; + u32 mask; + u16 val; + u16 readonly; +} *sprot_items; +static int sprot_item_alloc; +static int sprot_item_count; + +static u16 *carthw_sprot_get_val(u32 a, int rw_only) +{ + int i; + + for (i = 0; i < sprot_item_count; i++) + if ((a & sprot_items[i].mask) == sprot_items[i].addr) + if (!rw_only || !sprot_items[i].readonly) + return &sprot_items[i].val; + return NULL; +} + +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; + if (!(a & 1)) + d >>= 8; + 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; + } +} + +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; + } +} + +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) + *val = (*val & 0xff00) | (d | 0xff); + else + *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); +} + +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); +} + +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; + } + + sprot_items[sprot_item_count].addr = a; + sprot_items[sprot_item_count].mask = mask; + sprot_items[sprot_item_count].val = val; + sprot_items[sprot_item_count].readonly = is_ro; + sprot_item_count++; +} + +static void carthw_sprot_unload(void) +{ + free(sprot_items); + sprot_items = NULL; + sprot_item_count = sprot_item_alloc = 0; +} + +static void carthw_sprot_mem_setup(void) +{ + int start; + + // map ROM - 0x7fffff, /TIME areas (which are tipically used) + start = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK; + 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); + cpu68k_map_set(m68k_write16_map, start, 0x7fffff, PicoWrite16_sprot, 1); + + cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_sprot, 1); + cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_sprot, 1); + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_sprot, 1); + cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_sprot, 1); +} + +void carthw_sprot_startup(void) +{ + elprintf(EL_STATUS, "Prot emu startup"); + + PicoCartMemSetup = carthw_sprot_mem_setup; + PicoCartUnloadHook = carthw_sprot_unload; +} + +/* Protection emulation for Lion King 3. Credits go to Haze */ +static u8 prot_lk3_cmd, prot_lk3_data; + +static u32 PicoRead8_plk3(u32 a) +{ + u32 d = 0; + switch (prot_lk3_cmd) { + case 1: d = prot_lk3_data >> 1; break; + case 2: // nibble rotate + d = ((prot_lk3_data >> 4) | (prot_lk3_data << 4)) & 0xff; + break; + case 3: // bit rotate + d = prot_lk3_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); + break; + } + + elprintf(EL_UIO, "prot r8 [%06x] %02x @%06x", a, d, SekPc); + return d; +} + +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; + else + prot_lk3_data = d; +} + +static void PicoWrite8_plk3b(u32 a, u32 d) +{ + int 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); + return; + } + if (addr == 0) + memcpy(Pico.rom, Pico.rom + Pico.romsize, 0x8000); + else + memcpy(Pico.rom, Pico.rom + addr, 0x8000); +} + +static void carthw_prot_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); +} + +void carthw_prot_lk3_startup(void) +{ + void *tmp; + + elprintf(EL_STATUS, "lk3 prot emu startup"); + + // allocate space for bank0 backup + tmp = realloc(Pico.rom, Pico.romsize + 0x8000); + if (tmp == NULL) + { + elprintf(EL_STATUS, "OOM"); + return; + } + Pico.rom = tmp; + memcpy(Pico.rom + Pico.romsize, Pico.rom, 0x8000); + + PicoCartMemSetup = carthw_prot_lk3_mem_setup; +} + diff --git a/pico/carthw/carthw.h b/pico/carthw/carthw.h index 7ca0c3d..382e1e2 100644 --- a/pico/carthw/carthw.h +++ b/pico/carthw/carthw.h @@ -15,6 +15,13 @@ void PicoSVPStartup(void); void PicoSVPMemSetup(void); /* misc */ +void carthw_ssf2_startup(void); void carthw_Xin1_startup(void); void carthw_realtec_startup(void); void carthw_radica_startup(void); + +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); diff --git a/pico/memory.c b/pico/memory.c index 2eaac2a..da73961 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -317,93 +317,6 @@ static void ctl_write_z80reset(u32 d) } } - -// for nonstandard reads -// TODO: mv to carthw -u32 OtherRead16End(u32 a, int realsize) -{ - u32 d=0; - - // 32x test -/* - if (a == 0xa130ec) { d = 0x4d41; goto end; } // MA - else if (a == 0xa130ee) { d = 0x5253; goto end; } // RS - else if (a == 0xa15100) { d = 0x0080; goto end; } - else -*/ - - // for games with simple protection devices, discovered by Haze - // some dumb detection is used, but that should be enough to make things work - if ((a>>22) == 1 && Pico.romsize >= 512*1024) { - if (*(int *)(Pico.rom+0x123e4) == 0x00550c39 && *(int *)(Pico.rom+0x123e8) == 0x00000040) { // Super Bubble Bobble (Unl) [!] - if (a == 0x400000) { d=0x55<<8; goto end; } - else if (a == 0x400002) { d=0x0f<<8; goto end; } - } - else if (*(int *)(Pico.rom+0x008c4) == 0x66240055 && *(int *)(Pico.rom+0x008c8) == 0x00404df9) { // Smart Mouse (Unl) - if (a == 0x400000) { d=0x55<<8; goto end; } - else if (a == 0x400002) { d=0x0f<<8; goto end; } - else if (a == 0x400004) { d=0xaa<<8; goto end; } - else if (a == 0x400006) { d=0xf0<<8; goto end; } - } - else if (*(int *)(Pico.rom+0x00404) == 0x00a90600 && *(int *)(Pico.rom+0x00408) == 0x6708b013) { // King of Fighters '98, The (Unl) [!] - if (a == 0x480000 || a == 0x4800e0 || a == 0x4824a0 || a == 0x488880) { d=0xaa<<8; goto end; } - else if (a == 0x4a8820) { d=0x0a<<8; goto end; } - // there is also a read @ 0x4F8820 which needs 0, but that is returned in default case - } - else if (*(int *)(Pico.rom+0x01b24) == 0x004013f9 && *(int *)(Pico.rom+0x01b28) == 0x00ff0000) { // Mahjong Lover (Unl) [!] - if (a == 0x400000) { d=0x90<<8; goto end; } - else if (a == 0x401000) { d=0xd3<<8; goto end; } // this one doesn't seem to be needed, the code does 2 comparisons and only then - // checks the result, which is of the above one. Left it just in case. - } - else if (*(int *)(Pico.rom+0x05254) == 0x0c3962d0 && *(int *)(Pico.rom+0x05258) == 0x00400055) { // Elf Wor (Unl) - if (a == 0x400000) { d=0x55<<8; goto end; } - else if (a == 0x400004) { d=0xc9<<8; goto end; } // this check is done if the above one fails - else if (a == 0x400002) { d=0x0f<<8; goto end; } - else if (a == 0x400006) { d=0x18<<8; goto end; } // similar to above - } - // our default behaviour is to return whatever was last written a 0x400000-0x7fffff range (used by Squirrel King (R) [!]) - // Lion King II, The (Unl) [!] writes @ 400000 and wants to get that val @ 400002 and wites another val - // @ 400004 which is expected @ 400006, so we really remember 2 values here -/// d = Pico.m.prot_bytes[(a>>2)&1]<<8; - } - else if (a == 0xa13000 && Pico.romsize >= 1024*1024) { - if (*(int *)(Pico.rom+0xc8af0) == 0x30133013 && *(int *)(Pico.rom+0xc8af4) == 0x000f0240) { // Rockman X3 (Unl) [!] - d=0x0c; goto end; - } - else if (*(int *)(Pico.rom+0x28888) == 0x07fc0000 && *(int *)(Pico.rom+0x2888c) == 0x4eb94e75) { // Bug's Life, A (Unl) [!] - d=0x28; goto end; // does the check from RAM - } - else if (*(int *)(Pico.rom+0xc8778) == 0x30133013 && *(int *)(Pico.rom+0xc877c) == 0x000f0240) { // Super Mario Bros. (Unl) [!] - d=0x0c; goto end; // seems to be the same code as in Rockman X3 (Unl) [!] - } - else if (*(int *)(Pico.rom+0xf20ec) == 0x30143013 && *(int *)(Pico.rom+0xf20f0) == 0x000f0200) { // Super Mario 2 1998 (Unl) [!] - d=0x0a; goto end; - } - } - else if (a == 0xa13002) { // Pocket Monsters (Unl) - d=0x01; goto end; - } - else if (a == 0xa1303E) { // Pocket Monsters (Unl) - d=0x1f; goto end; - } - else if (a == 0x30fe02) { - // Virtua Racing - just for fun - // this seems to be some flag that SVP is ready or something similar - d=1; goto end; - } - -end: - elprintf(EL_UIO, "strange r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); - return d; -} - -void OtherWrite8End(u32 a,u32 d,int realsize) -{ - // for games with simple protection devices, discovered by Haze - if ((a>>22) == 1) -;/// Pico.m.prot_bytes[(a>>2)&1] = (u8)d; -} - // ----------------------------------------------------------------- // cart (save) RAM area (usually 0x200000 - ...) diff --git a/pico/pico.h b/pico/pico.h index 92ba9cf..45e948f 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -140,7 +140,6 @@ int pm_seek(pm_file *stream, long offset, int whence); int pm_close(pm_file *fp); int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms); int PicoCartInsert(unsigned char *rom,unsigned int romsize); -void Byteswap(unsigned char *data,int len); void PicoCartUnload(void); extern void (*PicoCartLoadProgressCB)(int percent); extern void (*PicoCDLoadProgressCB)(const char *fname, int percent); diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index 05a903c..fc2e118 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -26,7 +26,7 @@ #define SIMPLE_WRITE_SOUND 0 #define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo -#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE|EL_SRAMIO|EL_EEPROM)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) +#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) // EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK) //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) -- 2.39.2