sms, autodetection for sg-1000 ram extension
authorkub <derkub@gmail.com>
Sun, 27 Feb 2022 09:40:04 +0000 (09:40 +0000)
committerkub <derkub@gmail.com>
Sun, 27 Feb 2022 09:57:50 +0000 (09:57 +0000)
pico/mode4.c
pico/pico.h
pico/pico_int.h
pico/sms.c

index 49541c8..6cabd38 100644 (file)
@@ -831,14 +831,16 @@ norender:
 
 /* Palette for TMS9918 mode, see https://www.smspower.org/Development/Palette */
 // RGB values: #000000 #000000 #21c842 #5edc78 #5455ed #7d76fc #d4524d #42ebf5
-//             #fc5554 #ff7978 #d4c154 #e6ce80 #21b03b #c95b5a #cccccc #ffffff
+//             #fc5554 #ff7978 #d4c154 #e6ce80 #21b03b #c95bba #cccccc #ffffff
+// 00   11   22   33   44   55   66   77   88   99   aa   bb   cc   dd   ee   ff
+// 0007 0818 1929 2a3a 3b4b 4c5c 5d6d 6e7e 7f8f 90a0 a1b1 b2c2 c3d3 d4e4 e5f5 f6
 static u16 tmspal[32] = {
   // SMS palette
 //  0x0000, 0x0000, 0x00a0, 0x00f0, 0x0a00, 0x0f00, 0x0005, 0x0ff0,
 //  0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff,
   // GG palette
-  0x0000, 0x0000, 0x04c2, 0x07d5, 0x0e55, 0x0f77, 0x045d, 0x0fe4,
-  0x055f, 0x077f, 0x05cd, 0x08ce, 0x03b2, 0x0b5c, 0x0ccc, 0x0fff,
+  0x0000, 0x0000, 0x04c2, 0x07d6, 0x0e55, 0x0f77, 0x055d, 0x0ee4,
+  0x055f, 0x077f, 0x05bd, 0x08ce, 0x04a2, 0x0b5c, 0x0ccc, 0x0fff,
 };
 
 void PicoDoHighPal555SMS(void)
index c7e4aa2..162a9bf 100644 (file)
@@ -77,15 +77,16 @@ extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s;
 #define POPT_DIS_FM_SSGEG   (1<<23)\r
 #define POPT_EN_FM_DAC      (1<<24) //x00 0000\r
 \r
-#define PAHW_MCD  (1<<0)\r
-#define PAHW_32X  (1<<1)\r
-#define PAHW_SVP  (1<<2)\r
-#define PAHW_PICO (1<<3)\r
-#define PAHW_SMS  (1<<4)\r
-\r
-#define PHWS_AUTO 0\r
-#define PHWS_GG   1\r
-#define PHWS_SMS  2\r
+#define PAHW_MCD    (1<<0)\r
+#define PAHW_32X    (1<<1)\r
+#define PAHW_SVP    (1<<2)\r
+#define PAHW_PICO   (1<<3)\r
+#define PAHW_SMS    (1<<4)\r
+\r
+#define PHWS_AUTO   0\r
+#define PHWS_GG     1\r
+#define PHWS_SMS    2\r
+#define PHWS_SG1000 3\r
 \r
 #define PQUIRK_FORCE_6BTN   (1<<0)\r
 \r
index f56ee55..15d3516 100644 (file)
@@ -342,6 +342,11 @@ 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
+\r
 #define PMS_MAP_AUTO   0\r
 #define PMS_MAP_SEGA   1\r
 #define PMS_MAP_CODEM  2\r
index dd301f9..1829276 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 & 0x1) { // GG, same layout as MD
+    if (Pico.m.hardware & PMS_HW_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 & 0x1) && a < 0x8) { // GG I/O area
+        if ((Pico.m.hardware & PMS_HW_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;
@@ -232,11 +232,11 @@ static void z80_sms_out(unsigned short a, unsigned char d)
     switch (a & 0xc1)
     {
       case 0x00:
-        if ((Pico.m.hardware & 0x1) && a < 0x8)   // GG I/O area
+        if ((Pico.m.hardware & PMS_HW_GG) && a < 0x8)   // GG I/O area
           Pico.ms.io_gg[a] = d;
         break;
       case 0x01:
-        if ((Pico.m.hardware & 0x1) && a < 0x8) { // GG I/O area
+        if ((Pico.m.hardware & PMS_HW_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
@@ -454,13 +454,15 @@ static void write_bank_jang(unsigned short a, unsigned char d)
   }
 }
 
+// SG-1000 8KB RAM Adaptor mapper. 8KB RAM at address 0x2000
 static void write_bank_x8k(unsigned short a, unsigned char d)
 {
   // 8KB address range @ 0x2000
   if ((a&0xe000) != 0x2000) return;
-  // never autodetected, selectable only via config
-  if (Pico.ms.mapper != PMS_MAP_8KBRAM) return;
+  // this is only available on SG-1000
+  if (Pico.ms.mapper != PMS_MAP_8KBRAM && (Pico.ms.mapper || !(Pico.m.hardware & PMS_HW_SG))) return;
   elprintf(EL_Z80BNK, "bank x8k %04x %02x @ %04x", a, d, z80_pc());
+  Pico.ms.mapper = PMS_MAP_8KBRAM;
 
   ((unsigned char *)PicoMem.vram)[a+0x6000] = d;
   z80_map_set(z80_read_map,  0x2000, 0x3fff, PicoMem.vram+0x4000, 0);
@@ -488,6 +490,7 @@ static void xwrite(unsigned int a, unsigned char d)
 
   case PMS_MAP_AUTO:
         // NB the sequence of mappers is crucial for the auto detection
+        write_bank_x8k(a, d);
         write_bank_n32k(a, d);
         write_bank_sega(a, d);
         write_bank_msx(a, d);
@@ -517,27 +520,29 @@ void PicoResetMS(void)
   // set preselected hw/mapper from config
   if (PicoIn.hwSelect) {
     switch (PicoIn.hwSelect) {
-    case PHWS_GG:  Pico.m.hardware |=  0x1; break;
-    default:       Pico.m.hardware &= ~0x1; break;
+    case PHWS_GG:  Pico.m.hardware |=  PMS_HW_GG; break;
+    default:       Pico.m.hardware &= ~PMS_HW_GG; break;
     }
   }
   if (PicoIn.mapper)
     Pico.ms.mapper = PicoIn.mapper;
-  Pico.m.hardware |= 0x4; // default region Japan if no TMR header
+  Pico.m.hardware |= PMS_HW_JAP; // default region Japan if no TMR header
+  Pico.m.hardware |= PMS_HW_SG;  // default to SG-1000 if no TMR header
 
   // check if the ROM header contains more system information
   for (tmr = 0x2000; tmr < 0xbfff && tmr <= Pico.romsize; tmr *= 2) {
     if (!memcmp(Pico.rom + tmr-16, "TMR SEGA", 8)) {
+      Pico.m.hardware &= ~PMS_HW_SG; // not SG-1000
       hw = Pico.rom[tmr-1] >> 4;
       if (!PicoIn.hwSelect) {
-        Pico.m.hardware &= ~0x1;
+        Pico.m.hardware &= ~PMS_HW_GG;
         if (hw >= 0x5 && hw < 0x8)
-          Pico.m.hardware |= 0x1; // GG cartridge detected
+          Pico.m.hardware |= PMS_HW_GG; // GG cartridge detected
       }
       if (!PicoIn.regionOverride) {
-        Pico.m.hardware &= ~0x4;
+        Pico.m.hardware &= ~PMS_HW_JAP;
         if (hw == 0x5 || hw == 0x3)
-          Pico.m.hardware |= 0x4; // region Japan
+          Pico.m.hardware |= PMS_HW_JAP; // region Japan
       }
       id = CPU_LE4(*(u32 *)&Pico.rom[tmr-4]) & 0xf0f0ffff;
       for (i = 0; i < sizeof(region_pal)/sizeof(*region_pal); i++)
@@ -571,7 +576,8 @@ void PicoResetMS(void)
   Pico.video.reg[10] = 0xff;
 
   // BIOS, clear zram (unitialized on Mark-III, cf src/mame/drivers/sms.cpp)
-  memset(PicoMem.zram, (Pico.m.hardware&5) == 4 ? 0xf0:0, sizeof(PicoMem.zram));
+  i = (Pico.m.hardware & (PMS_HW_JAP|PMS_HW_GG)) == PMS_HW_JAP ? 0xf0 : 0x00;
+  memset(PicoMem.zram, i, sizeof(PicoMem.zram));
 }
 
 void PicoPowerMS(void)
@@ -698,7 +704,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 & 0x1) && !Pico.ms.nmi_state && nmi)
+  if (!(Pico.m.hardware & PMS_HW_GG) && !Pico.ms.nmi_state && nmi)
     z80_nmi();
   Pico.ms.nmi_state = nmi;