32x: implement standard/ssf2 mapper
[picodrive.git] / pico / cart.c
index bb452c0..9fcb01a 100644 (file)
@@ -49,7 +49,7 @@ typedef struct _cso_struct
 }\r
 cso_struct;\r
 \r
-static int uncompress2(void *dest, int destLen, void *source, int sourceLen)\r
+static int uncompress_buf(void *dest, int destLen, void *source, int sourceLen)\r
 {\r
     z_stream stream;\r
     int err;\r
@@ -326,7 +326,7 @@ size_t pm_read(void *ptr, size_t bytes, pm_file *stream)
           }\r
           cso->block_in_buff = block;\r
         }\r
-        rret = uncompress2(tmp_dst, 2048, cso->in_buff, read_len);\r
+        rret = uncompress_buf(tmp_dst, 2048, cso->in_buff, read_len);\r
         if (rret != 0) {\r
           elprintf(EL_STATUS, "cso: uncompress failed @ %08x with %i", read_pos, rret);\r
           break;\r
@@ -391,8 +391,8 @@ int pm_seek(pm_file *stream, long offset, int whence)
       offset = pos;\r
     }\r
 \r
-    if (PicoMessage != NULL && offset > 4 * 1024 * 1024)\r
-      PicoMessage("Decompressing data...");\r
+    if (PicoIn.osdMessage != NULL && offset > 4 * 1024 * 1024)\r
+      PicoIn.osdMessage("Decompressing data...");\r
 \r
     while (offset > 0) {\r
       char buf[16 * 1024];\r
@@ -569,16 +569,16 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)
     bytes_read = pm_read(rom,size,f); // Load up the rom\r
   if (bytes_read <= 0) {\r
     elprintf(EL_STATUS, "read failed");\r
-    free(rom);\r
+    plat_munmap(rom, rom_alloc_size);\r
     return 3;\r
   }\r
 \r
   if (!is_sms)\r
   {\r
     // maybe we are loading MegaCD BIOS?\r
-    if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||\r
+    if (!(PicoIn.AHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||\r
          !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
-      PicoAHW |= PAHW_MCD;\r
+      PicoIn.AHW |= PAHW_MCD;\r
     }\r
 \r
     // Check for SMD:\r
@@ -617,9 +617,9 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_
   Pico.rom=rom;\r
   Pico.romsize=romsize;\r
 \r
-  if (SRam.data) {\r
-    free(SRam.data);\r
-    SRam.data = NULL;\r
+  if (Pico.sv.data) {\r
+    free(Pico.sv.data);\r
+    Pico.sv.data = NULL;\r
   }\r
 \r
   if (PicoCartUnloadHook != NULL) {\r
@@ -628,7 +628,7 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_
   }\r
   pdb_cleanup();\r
 \r
-  PicoAHW &= PAHW_MCD|PAHW_SMS;\r
+  PicoIn.AHW &= PAHW_MCD|PAHW_SMS;\r
 \r
   PicoCartMemSetup = NULL;\r
   PicoDmaHook = NULL;\r
@@ -637,13 +637,13 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_
   PicoLoadStateHook = NULL;\r
   carthw_chunks = NULL;\r
 \r
-  if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))\r
+  if (!(PicoIn.AHW & (PAHW_MCD|PAHW_SMS)))\r
     PicoCartDetect(carthw_cfg);\r
 \r
   // setup correct memory map for loaded ROM\r
-  switch (PicoAHW) {\r
+  switch (PicoIn.AHW) {\r
     default:\r
-      elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoAHW);\r
+      elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoIn.AHW);\r
     case 0:\r
     case PAHW_SVP:  PicoMemSetup(); break;\r
     case PAHW_MCD:  PicoMemSetupCD(); break;\r
@@ -654,7 +654,7 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_
   if (PicoCartMemSetup != NULL)\r
     PicoCartMemSetup();\r
 \r
-  if (PicoAHW & PAHW_SMS)\r
+  if (PicoIn.AHW & PAHW_SMS)\r
     PicoPowerMS();\r
   else\r
     PicoPower();\r
@@ -681,7 +681,7 @@ void PicoCartUnload(void)
     PicoCartUnloadHook = NULL;\r
   }\r
 \r
-  if (PicoAHW & PAHW_32X)\r
+  if (PicoIn.AHW & PAHW_32X)\r
     PicoUnload32x();\r
 \r
   if (Pico.rom != NULL) {\r
@@ -778,7 +778,8 @@ static int is_expr(const char *expr, char **pr)
 \r
 #include "carthw_cfg.c"\r
 \r
-static void parse_carthw(const char *carthw_cfg, int *fill_sram)\r
+static void parse_carthw(const char *carthw_cfg, int *fill_sram,\r
+  int *hw_detected)\r
 {\r
   int line = 0, any_checks_passed = 0, skip_sect = 0;\r
   const char *s, *builtin = builtin_carthw_cfg;\r
@@ -902,6 +903,7 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram)
     if (is_expr("hw", &p)) {\r
       if (!any_checks_passed)\r
         goto no_checks;\r
+      *hw_detected = 1;\r
       rstrip(p);\r
 \r
       if      (strcmp(p, "svp") == 0)\r
@@ -925,6 +927,7 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram)
       else {\r
         elprintf(EL_STATUS, "carthw:%d: unsupported mapper: %s", line, p);\r
         skip_sect = 1;\r
+        *hw_detected = 0;\r
       }\r
       continue;\r
     }\r
@@ -949,8 +952,8 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram)
         elprintf(EL_STATUS, "carthw:%d: bad sram_range: %08x - %08x", line, start, end);\r
         goto bad_nomsg;\r
       }\r
-      SRam.start = start;\r
-      SRam.end = end;\r
+      Pico.sv.start = start;\r
+      Pico.sv.end = end;\r
       continue;\r
     }\r
     else if (is_expr("prop", &p)) {\r
@@ -959,13 +962,13 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram)
       rstrip(p);\r
 \r
       if      (strcmp(p, "no_sram") == 0)\r
-        SRam.flags &= ~SRF_ENABLED;\r
+        Pico.sv.flags &= ~SRF_ENABLED;\r
       else if (strcmp(p, "no_eeprom") == 0)\r
-        SRam.flags &= ~SRF_EEPROM;\r
+        Pico.sv.flags &= ~SRF_EEPROM;\r
       else if (strcmp(p, "filled_sram") == 0)\r
         *fill_sram = 1;\r
       else if (strcmp(p, "force_6btn") == 0)\r
-        PicoQuirks |= PQUIRK_FORCE_6BTN;\r
+        PicoIn.quirks |= PQUIRK_FORCE_6BTN;\r
       else {\r
         elprintf(EL_STATUS, "carthw:%d: unsupported prop: %s", line, p);\r
         goto bad_nomsg;\r
@@ -982,8 +985,8 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram)
       type = strtoul(p, &r, 0);\r
       if (r == p || type < 0)\r
         goto bad;\r
-      SRam.eeprom_type = type;\r
-      SRam.flags |= SRF_EEPROM;\r
+      Pico.sv.eeprom_type = type;\r
+      Pico.sv.flags |= SRF_EEPROM;\r
       continue;\r
     }\r
     else if (is_expr("eeprom_lines", &p)) {\r
@@ -998,9 +1001,9 @@ static void parse_carthw(const char *carthw_cfg, int *fill_sram)
           sda_out < 0 || sda_out > 15)\r
         goto bad;\r
 \r
-      SRam.eeprom_bit_cl = scl;\r
-      SRam.eeprom_bit_in = sda_in;\r
-      SRam.eeprom_bit_out= sda_out;\r
+      Pico.sv.eeprom_bit_cl = scl;\r
+      Pico.sv.eeprom_bit_in = sda_in;\r
+      Pico.sv.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
@@ -1038,56 +1041,61 @@ no_checks:
  */\r
 static void PicoCartDetect(const char *carthw_cfg)\r
 {\r
+  int carthw_detected = 0;\r
   int fill_sram = 0;\r
 \r
-  memset(&SRam, 0, sizeof(SRam));\r
+  memset(&Pico.sv, 0, sizeof(Pico.sv));\r
   if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A')\r
   {\r
-    SRam.start =  rom_read32(0x1B4) & ~0xff000001; // align\r
-    SRam.end   = (rom_read32(0x1B8) & ~0xff000000) | 1;\r
+    Pico.sv.start =  rom_read32(0x1B4) & ~0xff000001; // align\r
+    Pico.sv.end   = (rom_read32(0x1B8) & ~0xff000000) | 1;\r
     if (Pico.rom[0x1B2] & 0x40)\r
       // EEPROM\r
-      SRam.flags |= SRF_EEPROM;\r
-    SRam.flags |= SRF_ENABLED;\r
+      Pico.sv.flags |= SRF_EEPROM;\r
+    Pico.sv.flags |= SRF_ENABLED;\r
   }\r
-  if (SRam.end == 0 || SRam.start > SRam.end)\r
+  if (Pico.sv.end == 0 || Pico.sv.start > Pico.sv.end)\r
   {\r
     // some games may have bad headers, like S&K and Sonic3\r
     // note: majority games use 0x200000 as starting address, but there are some which\r
     // use something else (0x300000 by HardBall '95). Luckily they have good headers.\r
-    SRam.start = 0x200000;\r
-    SRam.end   = 0x203FFF;\r
-    SRam.flags |= SRF_ENABLED;\r
+    Pico.sv.start = 0x200000;\r
+    Pico.sv.end   = 0x203FFF;\r
+    Pico.sv.flags |= SRF_ENABLED;\r
   }\r
 \r
   // set EEPROM defaults, in case it gets detected\r
-  SRam.eeprom_type   = 0; // 7bit (24C01)\r
-  SRam.eeprom_bit_cl = 1;\r
-  SRam.eeprom_bit_in = 0;\r
-  SRam.eeprom_bit_out= 0;\r
+  Pico.sv.eeprom_type   = 0; // 7bit (24C01)\r
+  Pico.sv.eeprom_bit_cl = 1;\r
+  Pico.sv.eeprom_bit_in = 0;\r
+  Pico.sv.eeprom_bit_out= 0;\r
 \r
   if (carthw_cfg != NULL)\r
-    parse_carthw(carthw_cfg, &fill_sram);\r
+    parse_carthw(carthw_cfg, &fill_sram, &carthw_detected);\r
 \r
-  if (SRam.flags & SRF_ENABLED)\r
+  // assume the standard mapper for large roms\r
+  if (!carthw_detected && Pico.romsize > 0x400000)\r
+    carthw_ssf2_startup();\r
+\r
+  if (Pico.sv.flags & SRF_ENABLED)\r
   {\r
-    if (SRam.flags & SRF_EEPROM)\r
-      SRam.size = 0x2000;\r
+    if (Pico.sv.flags & SRF_EEPROM)\r
+      Pico.sv.size = 0x2000;\r
     else\r
-      SRam.size = SRam.end - SRam.start + 1;\r
+      Pico.sv.size = Pico.sv.end - Pico.sv.start + 1;\r
 \r
-    SRam.data = calloc(SRam.size, 1);\r
-    if (SRam.data == NULL)\r
-      SRam.flags &= ~SRF_ENABLED;\r
+    Pico.sv.data = calloc(Pico.sv.size, 1);\r
+    if (Pico.sv.data == NULL)\r
+      Pico.sv.flags &= ~SRF_ENABLED;\r
 \r
-    if (SRam.eeprom_type == 1) // 1 == 0 in PD EEPROM code\r
-      SRam.eeprom_type = 0;\r
+    if (Pico.sv.eeprom_type == 1)      // 1 == 0 in PD EEPROM code\r
+      Pico.sv.eeprom_type = 0;\r
   }\r
 \r
-  if ((SRam.flags & SRF_ENABLED) && fill_sram)\r
+  if ((Pico.sv.flags & SRF_ENABLED) && fill_sram)\r
   {\r
     elprintf(EL_STATUS, "SRAM fill");\r
-    memset(SRam.data, 0xff, SRam.size);\r
+    memset(Pico.sv.data, 0xff, Pico.sv.size);\r
   }\r
 \r
   // Unusual region 'code'\r