core, revisit Sega 8 bit hardware handling
authorkub <derkub@gmail.com>
Wed, 22 Feb 2023 23:22:45 +0000 (23:22 +0000)
committerkub <derkub@gmail.com>
Wed, 22 Feb 2023 23:22:45 +0000 (23:22 +0000)
pico/cart.c
pico/draw.c
pico/media.c
pico/mode4.c
pico/pico.h
pico/pico_int.h
pico/sms.c
platform/common/emu.c
platform/psp/emu.c

index dad850b..86cab1d 100644 (file)
@@ -847,7 +847,7 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_
   }\r
   pdb_cleanup();\r
 \r
-  PicoIn.AHW &= PAHW_MCD|PAHW_SMS|PAHW_PICO;\r
+  PicoIn.AHW &= ~(PAHW_32X|PAHW_SVP);\r
 \r
   PicoCartMemSetup = NULL;\r
   PicoDmaHook = NULL;\r
@@ -866,7 +866,7 @@ int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_
     PicoInitPico();\r
 \r
   // setup correct memory map for loaded ROM\r
-  switch (PicoIn.AHW) {\r
+  switch (PicoIn.AHW & ~(PAHW_GG|PAHW_SG|PAHW_SC)) {\r
     default:\r
       elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoIn.AHW);\r
     case 0:\r
@@ -1353,7 +1353,7 @@ static void PicoCartDetect(const char *carthw_cfg)
     for (i = 0; i < Pico.romsize; i += 4) {\r
       unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i));\r
       if (a && v == a + 0x400) { // patch if 2 pointers with offset 0x400 are found\r
-        printf("auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100);\r
+        elprintf(EL_STATUS, "auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100);\r
         *(u32 *) (Pico.rom + i) = CPU_BE2(v - 0x100);\r
       }\r
       // detect a pointer into the incriminating area\r
@@ -1374,7 +1374,7 @@ static void PicoCartDetect(const char *carthw_cfg)
     for (i = 0; i < Pico.romsize; i += 4) {\r
       unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i));\r
       if (a == 0xffffff8c && v == 0x5ee1) { // patch if 4-long xfer written to CHCR\r
-        printf("auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800);\r
+        elprintf(EL_STATUS, "auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800);\r
         *(u32 *) (Pico.rom + i) = CPU_BE2(v & ~0x800); // change to half-sized xfer\r
       }\r
       a = v;\r
index 38820e8..c1e8c4d 100644 (file)
@@ -1647,7 +1647,7 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est)
   PicoDrawUpdateHighPal();\r
 \r
   len = 256;\r
-  if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD))\r
+  if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
     len = 160;\r
   else if (!(PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[12]&1))\r
     len = 320;\r
@@ -1711,7 +1711,7 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
   }\r
 \r
   len = 256;\r
-  if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD))\r
+  if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
     len = 160;\r
   else if (!(PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[12]&1))\r
     len = 320;\r
index 7e1dd69..ce0c24e 100644 (file)
@@ -345,12 +345,6 @@ enum media_type_e PicoLoadMedia(const char *filename,
       do_region_override(filename);
   }
 
-  if (PicoCartInsert(rom_data, rom_size, carthw_cfg_fname)) {
-    media_type = PM_ERROR;
-    goto out;
-  }
-  rom_data = NULL; // now belongs to PicoCart
-
   // simple test for GG. Do this here since m.hardware is nulled in Insert
   if ((PicoIn.AHW & PAHW_SMS) && !PicoIn.hwSelect) {
     const char *ext = NULL;
@@ -363,18 +357,24 @@ enum media_type_e PicoLoadMedia(const char *filename,
       }
     }
     if (ext && !strcmp(ext,"gg") && !PicoIn.hwSelect) {
-      Pico.m.hardware |= PMS_HW_GG;
+      PicoIn.AHW |= PAHW_GG;
       lprintf("detected GG ROM\n");
     } else if (ext && !strcmp(ext,"sg")) {
-      Pico.m.hardware |= PMS_HW_SG;
+      PicoIn.AHW |= PAHW_SG;
       lprintf("detected SG-1000 ROM\n");
     } else if (ext && !strcmp(ext,"sc")) {
-      Pico.m.hardware |= PMS_HW_SC;
+      PicoIn.AHW |= PAHW_SC;
       lprintf("detected SC-3000 ROM\n");
     } else
       lprintf("detected SMS ROM\n");
   }
 
+  if (PicoCartInsert(rom_data, rom_size, carthw_cfg_fname)) {
+    media_type = PM_ERROR;
+    goto out;
+  }
+  rom_data = NULL; // now belongs to PicoCart
+
   // insert CD if it was detected
   Pico.m.ncart_in = 0;
   if (cd_img_type != CT_UNKNOWN) {
index ff54c14..9c1cff9 100644 (file)
@@ -162,7 +162,7 @@ static void ParseSpritesM4(int scanline)
 
   if (pv->reg[0] & 8)
     xoff -= 8;  // sprite shift
-  if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD))
+  if (Pico.m.hardware & PMS_HW_LCD)
     xoff -= 48; // GG LCD, adjust to center 160 px
 
   sat = (u8 *)PicoMem.vram + ((pv->reg[5] & 0x7e) << 7);
@@ -237,7 +237,7 @@ static void DrawStripM4(const u16 *nametab, int cells_dx, int tilex_ty)
   int addr = 0, pal = 0;
 
   // Draw tiles across screen:
-  for (; cells_dx > 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
+  for (; cells_dx >= 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
   {
     unsigned int pack;
     unsigned code;
@@ -294,7 +294,7 @@ static void DrawDisplayM4(int scanline)
 
   tilex = (32 - (dx >> 3) + cellskip) & 0x1f;
   ty = (line & 7) << 1; // Y-Offset into tile
-  cells = maxcells - cellskip;
+  cells = maxcells - cellskip - 1;
 
   dx = (dx & 7);
   dx += cellskip << 3;
@@ -302,7 +302,7 @@ static void DrawDisplayM4(int scanline)
 
   // tiles
   if (!(pv->debug_p & PVD_KILL_B)) {
-    if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD)) {
+    if (Pico.m.hardware & PMS_HW_LCD) {
       // on GG render only the center 160 px, but mind hscroll
       DrawStripM4(nametab , (dx-8) | ((cells-11)<< 16),(tilex+5) | (ty  << 16));
     } else if (pv->reg[0] & 0x80) {
@@ -318,7 +318,7 @@ static void DrawDisplayM4(int scanline)
   if (!(pv->debug_p & PVD_KILL_S_LO))
     DrawSpritesM4();
 
-  if ((pv->reg[0] & 0x20) && (Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) != (PMS_HW_GG|PMS_HW_LCD)) {
+  if ((pv->reg[0] & 0x20) && !(Pico.m.hardware & PMS_HW_LCD)) {
     // first column masked with background, caculate offset to start of line
     dx = line_offset / 4;
     ty = ((pv->reg[7]&0x0f)|0x10) * 0x01010101;
@@ -742,7 +742,7 @@ void PicoFrameStartSMS(void)
 
   // Copy LCD enable flag for easier handling
   Pico.m.hardware &= ~PMS_HW_LCD;
-  if ((PicoIn.opt & POPT_EN_GG_LCD) && (Pico.m.hardware & PMS_HW_GG))
+  if ((PicoIn.opt & POPT_EN_GG_LCD) && (PicoIn.AHW & PAHW_GG))
     Pico.m.hardware |= PMS_HW_LCD;
 
   if (!(Pico.m.hardware & PMS_HW_LCD) && (mode & 4) && (Pico.video.reg[0] & 0x20)) {
@@ -750,7 +750,7 @@ void PicoFrameStartSMS(void)
     columns = 248;
     Pico.est.rendstatus |= PDRAW_SMS_BLANK_1;
   }
-  if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD)) {
+  if (Pico.m.hardware & PMS_HW_LCD) {
     // GG LCD always has 160x144 regardless of settings
     screen_offset = 24; // nonetheless the vdp timing has 224 lines
     loffs = 48;
@@ -811,7 +811,7 @@ void PicoLineSMS(int line)
   unsigned bgcolor;
 
   // GG LCD, render only visible part of screen
-  if ((Pico.m.hardware & (PMS_HW_GG|PMS_HW_LCD)) == (PMS_HW_GG|PMS_HW_LCD) && (line < 24 || line >= 24+144))
+  if ((Pico.m.hardware & PMS_HW_LCD) && (line < 24 || line >= 24+144))
     goto norender;
 
   if (PicoScanBegin != NULL && skip == 0)
@@ -878,7 +878,7 @@ void PicoDoHighPal555SMS(void)
    * hence GG/SMS/TMS can all be handled the same here */
   for (j = cnt; j > 0; j--) {
     if (!(Pico.video.reg[0] & 0x4)) // fixed palette in TMS modes
-      spal = (u32 *)tmspal + (Pico.m.hardware & (PMS_HW_SG|PMS_HW_SC) ? 16/2:0);
+      spal = (u32 *)tmspal + (PicoIn.AHW & (PAHW_SG|PAHW_SC) ? 16/2:0);
     for (i = 0x20/2; i > 0; i--, spal++, dpal++) { 
       t = *spal;
 #if defined(USE_BGR555)
index db92f30..a15a01a 100644 (file)
@@ -83,6 +83,9 @@ extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s;
 #define PAHW_SVP    (1<<2)\r
 #define PAHW_PICO   (1<<3)\r
 #define PAHW_SMS    (1<<4)\r
+#define PAHW_GG     (1<<5)\r
+#define PAHW_SG     (1<<6)\r
+#define PAHW_SC     (1<<7)\r
 \r
 #define PHWS_AUTO   0\r
 #define PHWS_GG     1\r
index 1131376..1bb7b25 100644 (file)
@@ -342,11 +342,8 @@ struct PicoMisc
   unsigned int  frame_count;   // 1c for movies and idle det\r
 };\r
 \r
-#define PMS_HW_GG      0x1   // Game Gear\r
 #define PMS_HW_LCD     0x2   // GG LCD\r
 #define PMS_HW_JAP     0x4   // japanese system\r
-#define PMS_HW_SG      0x8   // SG-1000\r
-#define PMS_HW_SC      0x10  // SC-3000\r
 \r
 #define PMS_MAP_AUTO   0\r
 #define PMS_MAP_SEGA   1\r
index df99e92..f102cf4 100644 (file)
@@ -57,7 +57,7 @@ static void vdp_data_write(unsigned char d)
 
   if (pv->type == 3) {
     // cram. 32 on SMS, but 64 on MD. Fill 2nd half of cram for prio bit mirror
-    if (Pico.m.hardware & PMS_HW_GG) { // GG, same layout as MD
+    if (PicoIn.AHW & PAHW_GG) { // GG, same layout as MD
       unsigned a = pv->addr & 0x3f;
       if (a & 0x1) { // write complete color on high byte write
         u16 c = ((d&0x0f) << 8) | Pico.ms.vdp_buffer;
@@ -160,7 +160,7 @@ static unsigned char z80_sms_in(unsigned short a)
     {
       case 0x00:
       case 0x01:
-        if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) { // GG I/O area
+        if ((PicoIn.AHW & PAHW_GG) && a < 0x8) { // GG I/O area
           switch (a) {
           case 0: d = 0xff & ~(PicoIn.pad[0] & 0x80);               break;
           case 1: d = Pico.ms.io_gg[1] | (Pico.ms.io_gg[2] & 0x7f); break;
@@ -189,14 +189,14 @@ static unsigned char z80_sms_in(unsigned short a)
         break;
 
       case 0xc0: /* I/O port A and B */
-        if (! (Pico.m.hardware & PMS_HW_SC) || (Pico.ms.io_sg & 7) == 7)
+        if (! (PicoIn.AHW & PAHW_SC) || (Pico.ms.io_sg & 7) == 7)
           d = ~((PicoIn.pad[0] & 0x3f) | (PicoIn.pad[1] << 6));
         else
           ; // read kbd 8 bits
         break;
 
       case 0xc1: /* I/O port B and miscellaneous */
-        if (! (Pico.m.hardware & PMS_HW_SC) || (Pico.ms.io_sg & 7) == 7) {
+        if (! (PicoIn.AHW & PAHW_SC) || (Pico.ms.io_sg & 7) == 7) {
           d = (Pico.ms.io_ctl & 0x80) | ((Pico.ms.io_ctl << 1) & 0x40) | 0x30;
           d |= ~(PicoIn.pad[1] >> 2) & 0x0f;
           if (Pico.ms.io_ctl & 0x08) d |= 0x80; // TH as input is unconnected
@@ -238,11 +238,11 @@ static void z80_sms_out(unsigned short a, unsigned char d)
     switch (a & 0xc1)
     {
       case 0x00:
-        if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8)   // GG I/O area
+        if ((PicoIn.AHW & PAHW_GG) && a < 0x8)   // GG I/O area
           Pico.ms.io_gg[a] = d;
         break;
       case 0x01:
-        if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8) { // GG I/O area
+        if ((PicoIn.AHW & PAHW_GG) && a < 0x8) { // GG I/O area
           Pico.ms.io_gg[a] = d;
         } else {
           // pad. latch hcounter if one of the TH lines is switched to 1
@@ -267,7 +267,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
         break;
 
       case 0xc0:
-        if ((Pico.m.hardware & PMS_HW_SC) && (a & 0x2))
+        if ((PicoIn.AHW & PAHW_SC) && (a & 0x2))
           Pico.ms.io_sg = d; // 0xc2 = kbd/pad select
     }
   }
@@ -535,9 +535,11 @@ char *mappers[] = {
 // Before adding more mappers this should be revised.
 static void xwrite(unsigned int a, unsigned char d)
 {
+  int sz = (PicoIn.AHW & (PAHW_SG|PAHW_SC) ? 2 : 8) * 1024;
+
   elprintf(EL_IO, "z80 write [%04x] %02x", a, d);
   if (a >= 0xc000)
-    PicoMem.zram[a & 0x1fff] = d;
+    PicoMem.zram[a & (sz-1)] = d;
 
   switch (Pico.ms.mapper) { // via config, or auto detected
   case PMS_MAP_SEGA:    write_bank_sega(a, d);  break;
@@ -556,9 +558,9 @@ static void xwrite(unsigned int a, unsigned char d)
         // disable autodetection after some time
         if ((a >= 0xc000 && a < 0xfff8) || Pico.ms.mapcnt > 20) break;
         // NB the sequence of mappers is crucial for the auto detection
-        if (Pico.m.hardware & PMS_HW_SC) {
+        if (PicoIn.AHW & PAHW_SC) {
           write_bank_x32k(a,d);
-        } else if (Pico.m.hardware & PMS_HW_SG) {
+        } else if (PicoIn.AHW & PAHW_SG) {
           write_bank_x8k(a, d);
         } else {
           write_bank_n32k(a, d);
@@ -595,11 +597,11 @@ void PicoResetMS(void)
 
   // set preselected hw/mapper from config
   if (PicoIn.hwSelect) {
-    Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG|PMS_HW_SC);
+    PicoIn.AHW &= ~(PAHW_GG|PAHW_SG|PAHW_SC);
     switch (PicoIn.hwSelect) {
-    case PHWS_GG:  Pico.m.hardware |=  PMS_HW_GG; break;
-    case PHWS_SG:  Pico.m.hardware |=  PMS_HW_SG; break;
-    case PHWS_SC:  Pico.m.hardware |=  PMS_HW_SC; break;
+    case PHWS_GG:  PicoIn.AHW |= PAHW_GG; break;
+    case PHWS_SG:  PicoIn.AHW |= PAHW_SG; break;
+    case PHWS_SC:  PicoIn.AHW |= PAHW_SC; break;
     }
   }
   Pico.ms.mapcnt = Pico.ms.mapper = 0;
@@ -614,9 +616,9 @@ void PicoResetMS(void)
     if (!memcmp(Pico.rom + tmr-16, "TMR SEGA", 8)) {
       hw = Pico.rom[tmr-1] >> 4;
       if (!PicoIn.hwSelect) {
-        Pico.m.hardware &= ~(PMS_HW_GG|PMS_HW_SG|PMS_HW_SC);
+        PicoIn.AHW &= ~(PAHW_GG|PAHW_SG|PAHW_SC);
         if (hw >= 0x5 && hw < 0x8)
-          Pico.m.hardware |= PMS_HW_GG; // GG cartridge detected
+          PicoIn.AHW |= PAHW_GG; // GG cartridge detected
       }
       if (!PicoIn.regionOverride) {
         Pico.m.hardware &= ~PMS_HW_JAP;
@@ -655,7 +657,7 @@ void PicoResetMS(void)
   Pico.video.reg[10] = 0xff;
 
   // BIOS, clear zram (unitialized on Mark-III, cf src/mame/drivers/sms.cpp)
-  i = (Pico.m.hardware & (PMS_HW_JAP|PMS_HW_GG)) == PMS_HW_JAP ? 0xf0 : 0x00;
+  i = !(PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_JAP) ? 0xf0 : 0x00;
   memset(PicoMem.zram, i, sizeof(PicoMem.zram));
 }
 
@@ -666,7 +668,6 @@ void PicoPowerMS(void)
   memset(&PicoMem,0,sizeof(PicoMem));
   memset(&Pico.video,0,sizeof(Pico.video));
   memset(&Pico.m,0,sizeof(Pico.m));
-  Pico.m.pal = 0;
 
   // calculate a mask for bank writes.
   // ROM loader has aligned the size for us, so this is safe.
@@ -686,16 +687,20 @@ void PicoPowerMS(void)
 void PicoMemSetupMS(void)
 {
   u8 mapper = Pico.ms.mapper;
+  int sz = (PicoIn.AHW & (PAHW_SG|PAHW_SC) ? 2 : 8) * 1024;
+  u32 a;
 
-  z80_map_set(z80_read_map, 0x0000, 0xbfff, Pico.rom, 0);
-
-  z80_map_set(z80_read_map, 0xc000, 0xdfff, PicoMem.zram, 0);
-  z80_map_set(z80_read_map, 0xe000, 0xffff, PicoMem.zram, 0);
-  z80_map_set(z80_write_map, 0xc000, 0xdfff, PicoMem.zram, 0);
-  z80_map_set(z80_write_map, 0xe000, 0xffff, PicoMem.zram, 0);
+  // RAM and its mirrors
+  for (a = 0xc000; a < 0x10000; a += sz) {
+    z80_map_set(z80_read_map, a, a + sz-1, PicoMem.zram, 0);
+    z80_map_set(z80_write_map, a, a + sz-1, PicoMem.zram, 0);
+  }
+  a = 0x10000 - (1<<Z80_MEM_SHIFT);
+  z80_map_set(z80_write_map, a, 0xffff, xwrite, 1); // mapper detection
 
-  z80_map_set(z80_write_map, 0x0000, 0xbfff, xwrite, 1);
-  z80_map_set(z80_write_map, 0xfc00, 0xffff, xwrite, 1);
+  // ROM
+  z80_map_set(z80_read_map, 0x0000, 0xbfff, Pico.rom, 0);
+  z80_map_set(z80_write_map, 0x0000, 0xbfff, xwrite, 1); // mapper detection
 
   // Nemesis mapper maps last 8KB rom bank #15 to adress 0
   if (mapper == PMS_MAP_NEMESIS && Pico.romsize > 0x1e000)
@@ -800,7 +805,7 @@ void PicoFrameMS(void)
 
   // for SMS the pause button generates an NMI, for GG ths is not the case
   nmi = (PicoIn.pad[0] >> 7) & 1;
-  if (!(Pico.m.hardware & PMS_HW_GG) && !Pico.ms.nmi_state && nmi)
+  if (!(PicoIn.AHW & PAHW_GG) && !Pico.ms.nmi_state && nmi)
     z80_nmi();
   Pico.ms.nmi_state = nmi;
 
index a2dbf4a..e0803ce 100644 (file)
@@ -332,11 +332,11 @@ static void system_announce(void)
 \r
        if (PicoIn.AHW & PAHW_SMS) {\r
                sys_name = "Master System";\r
-               if (Pico.m.hardware & PMS_HW_GG)\r
+               if (PicoIn.AHW & PAHW_GG)\r
                        sys_name = "Game Gear";\r
-               else if (Pico.m.hardware & PMS_HW_SG)\r
+               else if (PicoIn.AHW & PAHW_SG)\r
                        sys_name = "SG-1000";\r
-               else if (Pico.m.hardware & PMS_HW_SC)\r
+               else if (PicoIn.AHW & PAHW_SC)\r
                        sys_name = "SC-3000";\r
                else if (Pico.m.hardware & PMS_HW_JAP)\r
                        sys_name = "Mark III";\r
index 24b39c6..18eb388 100644 (file)
@@ -217,7 +217,7 @@ static void do_pal_update_sms(void)
        int i;
        
        if (!(Pico.video.reg[0] & 0x4)) {
-               int sg = !!(Pico.m.hardware & (PMS_HW_SG|PMS_HW_SC));
+               int sg = !!(PicoIn.AHW & (PAHW_SG|PAHW_SC));
                for (i = Pico.est.SonicPalCount; i >= 0; i--)
                        do_pal_convert(localPal+i*0x40, tmspal+sg*0x10, currentConfig.gamma, currentConfig.gamma2);
        } else {