}\r
\r
\r
-void Byteswap(unsigned char *data,int len)\r
+static void Byteswap(unsigned char *data,int len)\r
{\r
int i=0;\r
\r
}\r
}\r
\r
+static unsigned int rom_crc32(void)\r
+{\r
+ unsigned int crc;\r
+ elprintf(EL_STATUS, "caclulating CRC32..");\r
+\r
+ // have to unbyteswap for calculation..\r
+ Byteswap(Pico.rom, Pico.romsize);\r
+ crc = crc32(0, Pico.rom, Pico.romsize);\r
+ Byteswap(Pico.rom, Pico.romsize);\r
+ return crc;\r
+}\r
+\r
static int rom_strcmp(int rom_offset, const char *s1)\r
{\r
int i, len = strlen(s1);\r
*p = 0;\r
}\r
\r
+static int parse_3_vals(char *p, int *val0, int *val1, int *val2)\r
+{\r
+ char *r;\r
+ *val0 = strtoul(p, &r, 0);\r
+ if (r == p)\r
+ goto bad;\r
+ p = sskip(r);\r
+ if (*p++ != ',')\r
+ goto bad;\r
+ *val1 = strtoul(p, &r, 0);\r
+ if (r == p)\r
+ goto bad;\r
+ p = sskip(r);\r
+ if (*p++ != ',')\r
+ goto bad;\r
+ *val2 = strtoul(p, &r, 0);\r
+ if (r == p)\r
+ goto bad;\r
+\r
+ return 1;\r
+bad:\r
+ return 0;\r
+}\r
+\r
static int is_expr(const char *expr, char **pr)\r
{\r
int len = strlen(expr);\r
static void parse_carthw(int *fill_sram)\r
{\r
int line = 0, any_checks_passed = 0, skip_sect = 0;\r
+ int tmp, rom_crc = 0;\r
char buff[256], *p, *r;\r
FILE *f;\r
\r
skip_sect = 1;\r
continue;\r
}\r
+ else if (is_expr("check_crc32", &p))\r
+ {\r
+ unsigned int crc;\r
+ crc = strtoul(p, &r, 0);\r
+ if (r == p)\r
+ goto bad;\r
+\r
+ if (rom_crc == 0)\r
+ rom_crc = rom_crc32();\r
+ if (crc == rom_crc)\r
+ any_checks_passed = 1;\r
+ else\r
+ skip_sect = 1;\r
+ continue;\r
+ }\r
\r
/* now time for actions */\r
if (is_expr("hw", &p)) {\r
PicoSVPStartup();\r
else if (strcmp(p, "pico") == 0)\r
PicoInitPico();\r
+ else if (strcmp(p, "prot") == 0)\r
+ carthw_sprot_startup();\r
+ else if (strcmp(p, "ssf2_mapper") == 0)\r
+ carthw_ssf2_startup();\r
else if (strcmp(p, "x_in_1_mapper") == 0)\r
carthw_Xin1_startup();\r
else if (strcmp(p, "realtec_mapper") == 0)\r
carthw_realtec_startup();\r
else if (strcmp(p, "radica_mapper") == 0)\r
carthw_radica_startup();\r
+ else if (strcmp(p, "prot_lk3") == 0)\r
+ carthw_prot_lk3_startup();\r
else {\r
elprintf(EL_STATUS, "carthw:%d: unsupported mapper: %s", line, p);\r
skip_sect = 1;\r
goto no_checks;\r
rstrip(p);\r
\r
- scl = strtoul(p, &r, 0);\r
- if (r == p || scl < 0 || scl > 15)\r
- goto bad;\r
- p = sskip(r);\r
- if (*p++ != ',')\r
+ if (!parse_3_vals(p, &scl, &sda_in, &sda_out))\r
goto bad;\r
- sda_in = strtoul(p, &r, 0);\r
- if (r == p || sda_in < 0 || sda_in > 15)\r
- goto bad;\r
- p = sskip(r);\r
- if (*p++ != ',')\r
- goto bad;\r
- sda_out = strtoul(p, &r, 0);\r
- if (r == p || sda_out < 0 || sda_out > 15)\r
+ if (scl < 0 || scl > 15 || sda_in < 0 || sda_in > 15 ||\r
+ sda_out < 0 || sda_out > 15)\r
goto bad;\r
\r
SRam.eeprom_bit_cl = scl;\r
SRam.eeprom_bit_out= sda_out;\r
continue;\r
}\r
+ else if ((tmp = is_expr("prot_ro_value16", &p)) || is_expr("prot_rw_value16", &p)) {\r
+ int addr, mask, val;\r
+ if (!any_checks_passed)\r
+ goto no_checks;\r
+ rstrip(p);\r
+\r
+ if (!parse_3_vals(p, &addr, &mask, &val))\r
+ goto bad;\r
+\r
+ carthw_sprot_new_location(addr, mask, val, tmp ? 1 : 0);\r
+ continue;\r
+ }\r
\r
\r
bad:\r
*/\r
static void PicoCartDetect(void)\r
{\r
- int fill_sram = 0, csum;\r
-\r
- csum = rom_read32(0x18c) & 0xffff;\r
+ int fill_sram = 0;\r
\r
memset(&SRam, 0, sizeof(SRam));\r
if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A')\r
# 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
# 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
# eeprom_lines = <SCL,SDA_IN,SDA_OUT>
# - 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 = <addr, mask, val> - return constant <val> on reads at location
+# (<addr> & <mask>), ignore writes.
+# prot_rw_value16 = <addr, mask, val> - same as above, but writeable
[Virtua Racing - SVP]
check_str = 0x150, "Virtua Racing"
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.
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
+
/*
- * 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.
#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
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;
+}
+
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);
}\r
}\r
\r
-\r
-// for nonstandard reads\r
-// TODO: mv to carthw\r
-u32 OtherRead16End(u32 a, int realsize)\r
-{\r
- u32 d=0;\r
-\r
- // 32x test\r
-/*\r
- if (a == 0xa130ec) { d = 0x4d41; goto end; } // MA\r
- else if (a == 0xa130ee) { d = 0x5253; goto end; } // RS\r
- else if (a == 0xa15100) { d = 0x0080; goto end; }\r
- else\r
-*/\r
-\r
- // for games with simple protection devices, discovered by Haze\r
- // some dumb detection is used, but that should be enough to make things work\r
- if ((a>>22) == 1 && Pico.romsize >= 512*1024) {\r
- if (*(int *)(Pico.rom+0x123e4) == 0x00550c39 && *(int *)(Pico.rom+0x123e8) == 0x00000040) { // Super Bubble Bobble (Unl) [!]\r
- if (a == 0x400000) { d=0x55<<8; goto end; }\r
- else if (a == 0x400002) { d=0x0f<<8; goto end; }\r
- }\r
- else if (*(int *)(Pico.rom+0x008c4) == 0x66240055 && *(int *)(Pico.rom+0x008c8) == 0x00404df9) { // Smart Mouse (Unl)\r
- if (a == 0x400000) { d=0x55<<8; goto end; }\r
- else if (a == 0x400002) { d=0x0f<<8; goto end; }\r
- else if (a == 0x400004) { d=0xaa<<8; goto end; }\r
- else if (a == 0x400006) { d=0xf0<<8; goto end; }\r
- }\r
- else if (*(int *)(Pico.rom+0x00404) == 0x00a90600 && *(int *)(Pico.rom+0x00408) == 0x6708b013) { // King of Fighters '98, The (Unl) [!]\r
- if (a == 0x480000 || a == 0x4800e0 || a == 0x4824a0 || a == 0x488880) { d=0xaa<<8; goto end; }\r
- else if (a == 0x4a8820) { d=0x0a<<8; goto end; }\r
- // there is also a read @ 0x4F8820 which needs 0, but that is returned in default case\r
- }\r
- else if (*(int *)(Pico.rom+0x01b24) == 0x004013f9 && *(int *)(Pico.rom+0x01b28) == 0x00ff0000) { // Mahjong Lover (Unl) [!]\r
- if (a == 0x400000) { d=0x90<<8; goto end; }\r
- 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\r
- // checks the result, which is of the above one. Left it just in case.\r
- }\r
- else if (*(int *)(Pico.rom+0x05254) == 0x0c3962d0 && *(int *)(Pico.rom+0x05258) == 0x00400055) { // Elf Wor (Unl)\r
- if (a == 0x400000) { d=0x55<<8; goto end; }\r
- else if (a == 0x400004) { d=0xc9<<8; goto end; } // this check is done if the above one fails\r
- else if (a == 0x400002) { d=0x0f<<8; goto end; }\r
- else if (a == 0x400006) { d=0x18<<8; goto end; } // similar to above\r
- }\r
- // our default behaviour is to return whatever was last written a 0x400000-0x7fffff range (used by Squirrel King (R) [!])\r
- // Lion King II, The (Unl) [!] writes @ 400000 and wants to get that val @ 400002 and wites another val\r
- // @ 400004 which is expected @ 400006, so we really remember 2 values here\r
-/// d = Pico.m.prot_bytes[(a>>2)&1]<<8;\r
- }\r
- else if (a == 0xa13000 && Pico.romsize >= 1024*1024) {\r
- if (*(int *)(Pico.rom+0xc8af0) == 0x30133013 && *(int *)(Pico.rom+0xc8af4) == 0x000f0240) { // Rockman X3 (Unl) [!]\r
- d=0x0c; goto end;\r
- }\r
- else if (*(int *)(Pico.rom+0x28888) == 0x07fc0000 && *(int *)(Pico.rom+0x2888c) == 0x4eb94e75) { // Bug's Life, A (Unl) [!]\r
- d=0x28; goto end; // does the check from RAM\r
- }\r
- else if (*(int *)(Pico.rom+0xc8778) == 0x30133013 && *(int *)(Pico.rom+0xc877c) == 0x000f0240) { // Super Mario Bros. (Unl) [!]\r
- d=0x0c; goto end; // seems to be the same code as in Rockman X3 (Unl) [!]\r
- }\r
- else if (*(int *)(Pico.rom+0xf20ec) == 0x30143013 && *(int *)(Pico.rom+0xf20f0) == 0x000f0200) { // Super Mario 2 1998 (Unl) [!]\r
- d=0x0a; goto end;\r
- }\r
- }\r
- else if (a == 0xa13002) { // Pocket Monsters (Unl)\r
- d=0x01; goto end;\r
- }\r
- else if (a == 0xa1303E) { // Pocket Monsters (Unl)\r
- d=0x1f; goto end;\r
- }\r
- else if (a == 0x30fe02) {\r
- // Virtua Racing - just for fun\r
- // this seems to be some flag that SVP is ready or something similar\r
- d=1; goto end;\r
- }\r
-\r
-end:\r
- elprintf(EL_UIO, "strange r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc);\r
- return d;\r
-}\r
-\r
-void OtherWrite8End(u32 a,u32 d,int realsize)\r
-{\r
- // for games with simple protection devices, discovered by Haze\r
- if ((a>>22) == 1)\r
-;/// Pico.m.prot_bytes[(a>>2)&1] = (u8)d;\r
-}\r
-\r
// -----------------------------------------------------------------\r
\r
// cart (save) RAM area (usually 0x200000 - ...)\r
int pm_close(pm_file *fp);\r
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);\r
int PicoCartInsert(unsigned char *rom,unsigned int romsize);\r
-void Byteswap(unsigned char *data,int len);\r
void PicoCartUnload(void);\r
extern void (*PicoCartLoadProgressCB)(int percent);\r
extern void (*PicoCDLoadProgressCB)(const char *fname, int percent);\r
#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__)