protection and more mapper support for new mem code
authornotaz <notasas@gmail.com>
Wed, 9 Sep 2009 16:00:42 +0000 (16:00 +0000)
committernotaz <notasas@gmail.com>
Wed, 9 Sep 2009 16:00:42 +0000 (16:00 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@771 be3aeb3a-fb24-0410-a615-afba39da0efa

pico/cart.c
pico/carthw.cfg
pico/carthw/carthw.c
pico/carthw/carthw.h
pico/memory.c
pico/pico.h
platform/linux/port_config.h

index 5eb89c9..067b422 100644 (file)
@@ -379,7 +379,7 @@ int pm_close(pm_file *fp)
 }\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
@@ -612,6 +612,18 @@ void PicoCartUnload(void)
   }\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
@@ -643,6 +655,30 @@ static void rstrip(char *s)
       *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
@@ -661,6 +697,7 @@ static int is_expr(const char *expr, char **pr)
 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
@@ -739,6 +776,21 @@ static void parse_carthw(int *fill_sram)
         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
@@ -750,12 +802,18 @@ static void parse_carthw(int *fill_sram)
         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
@@ -823,20 +881,10 @@ static void parse_carthw(int *fill_sram)
         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
@@ -844,6 +892,18 @@ static void parse_carthw(int *fill_sram)
       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
@@ -865,9 +925,7 @@ no_checks:
  */\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
index 140cb0a..36c8cf8 100644 (file)
@@ -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
 #  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"
@@ -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
+
index 6424f1e..9d81f8e 100644 (file)
@@ -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.
 #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;
+}
+
index 7ca0c3d..382e1e2 100644 (file)
@@ -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);
index 2eaac2a..da73961 100644 (file)
@@ -317,93 +317,6 @@ static void ctl_write_z80reset(u32 d)
   }\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
index 92ba9cf..45e948f 100644 (file)
@@ -140,7 +140,6 @@ int      pm_seek(pm_file *stream, long offset, int whence);
 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
index 05a903c..fc2e118 100644 (file)
@@ -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__)