32x: famec support
[picodrive.git] / pico / cart.c
index 5eb89c9..26fb59b 100644 (file)
@@ -378,23 +378,21 @@ int pm_close(pm_file *fp)
   return ret;\r
 }\r
 \r
-\r
-void Byteswap(unsigned char *data,int len)\r
+// byteswap, data needs to be int aligned, src can match dst\r
+void Byteswap(void *dst, const void *src, int len)\r
 {\r
-  int i=0;\r
-\r
-  if (len<2) return; // Too short\r
+  const unsigned int *ps = src;\r
+  unsigned int *pd = dst;\r
+  int i, m;\r
 \r
-  do\r
-  {\r
-    unsigned short *pd=(unsigned short *)(data+i);\r
-    int value=*pd; // Get 2 bytes\r
+  if (len < 2)\r
+    return;\r
 \r
-    value=(value<<8)|(value>>8); // Byteswap it\r
-    *pd=(unsigned short)value; // Put 2b ytes\r
-    i+=2;\r
+  m = 0x00ff00ff;\r
+  for (i = 0; i < len / 4; i++) {\r
+    unsigned int t = ps[i];\r
+    pd[i] = ((t & m) << 8) | ((t & ~m) >> 8);\r
   }\r
-  while (i+2<=len);\r
 }\r
 \r
 // Interleve a 16k block and byteswap\r
@@ -524,7 +522,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)
       elprintf(EL_STATUS, "SMD format detected.");\r
       DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD\r
     }\r
-    else Byteswap(rom,size); // Just byteswap\r
+    else Byteswap(rom, rom, size); // Just byteswap\r
   }\r
   else\r
   {\r
@@ -605,6 +603,9 @@ void PicoCartUnload(void)
     PicoCartUnloadHook = NULL;\r
   }\r
 \r
+  if (PicoAHW & PAHW_32X)\r
+    PicoUnload32x();\r
+\r
   if (Pico.rom != NULL) {\r
     SekFinishIdleDet();\r
     free(Pico.rom);\r
@@ -612,6 +613,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.rom, Pico.romsize);\r
+  crc = crc32(0, Pico.rom, Pico.romsize);\r
+  Byteswap(Pico.rom, 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 +656,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 +698,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 +777,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 +803,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 +882,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
-        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
+      if (!parse_3_vals(p, &scl, &sda_in, &sda_out))\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 +893,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 +926,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