runs code in 1M wram, cell arrange, decode (untested)
authornotaz <notasas@gmail.com>
Wed, 21 Feb 2007 22:23:37 +0000 (22:23 +0000)
committernotaz <notasas@gmail.com>
Wed, 21 Feb 2007 22:23:37 +0000 (22:23 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@54 be3aeb3a-fb24-0410-a615-afba39da0efa

16 files changed:
Pico/Memory.c
Pico/MemoryCmn.c [new file with mode: 0644]
Pico/PicoInt.h
Pico/VideoPort.c
Pico/cd/Area.c
Pico/cd/LC89510.c
Pico/cd/Memory.c
Pico/cd/Misc.c
Pico/cd/Pico.c
Pico/cd/cell_map.c [new file with mode: 0644]
Pico/cd/gfx_cd.c
Pico/cd/gfx_cd.h
Pico/misc.s [new file with mode: 0644]
Pico/sound/sound.c
platform/gp2x/emu.c
platform/gp2x/version.h

index 509fead..c9c9a02 100644 (file)
@@ -107,71 +107,12 @@ static int SRAMRead(u32 a)
 }\r
 #endif\r
 \r
-static int PadRead(int i)\r
-{\r
-  int pad=0,value=0,TH;\r
-  pad=~PicoPad[i]; // Get inverse of pad MXYZ SACB RLDU\r
-  TH=Pico.ioports[i+1]&0x40;\r
-\r
-  if(PicoOpt & 0x20) { // 6 button gamepad enabled\r
-    int phase = Pico.m.padTHPhase[i];\r
-\r
-    if(phase == 2 && !TH) {\r
-      value=(pad&0xc0)>>2;              // ?0SA 0000\r
-      goto end;\r
-    } else if(phase == 3 && TH) {\r
-      value=(pad&0x30)|((pad>>8)&0xf);  // ?1CB MXYZ\r
-      goto end;\r
-    } else if(phase == 3 && !TH) {\r
-      value=((pad&0xc0)>>2)|0x0f;       // ?0SA 1111\r
-      goto end;\r
-    }\r
-  }\r
-\r
-  if(TH) value=(pad&0x3f);              // ?1CB RLDU\r
-  else   value=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU\r
-\r
-  end:\r
-\r
-  // orr the bits, which are set as output\r
-  value |= Pico.ioports[i+1]&Pico.ioports[i+4];\r
-\r
-  return value; // will mirror later\r
-}\r
-\r
-u8 z80Read8(u32 a)\r
-{\r
-  if(Pico.m.z80Run&1) return 0;\r
-\r
-  a&=0x1fff;\r
-\r
-  if(!(PicoOpt&4)) {\r
-    // Z80 disabled, do some faking\r
-    static u8 zerosent = 0;\r
-    if(a == Pico.m.z80_lastaddr) { // probably polling something\r
-      u8 d = Pico.m.z80_fakeval;\r
-      if((d & 0xf) == 0xf && !zerosent) {\r
-        d = 0; zerosent = 1;\r
-      } else {\r
-        Pico.m.z80_fakeval++;\r
-        zerosent = 0;\r
-      }\r
-      return d;\r
-    } else {\r
-      Pico.m.z80_fakeval = 0;\r
-    }\r
-  }\r
-\r
-  Pico.m.z80_lastaddr = (u16) a;\r
-  return Pico.zram[a];\r
-}\r
-\r
 \r
 // for nonstandard reads\r
 #ifndef _ASM_MEMORY_C\r
 static\r
 #endif\r
-u32 UnusualRead16(u32 a, int realsize)\r
+u32 OtherRead16End(u32 a, int realsize)\r
 {\r
   u32 d=0;\r
 \r
@@ -242,109 +183,11 @@ end:
   return d;\r
 }\r
 \r
-#ifndef _ASM_MEMORY_C\r
-static\r
-#endif\r
-u32 OtherRead16(u32 a, int realsize)\r
-{\r
-  u32 d=0;\r
-\r
-  if ((a&0xff0000)==0xa00000) {\r
-    if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped)\r
-    if ((a&0x6000)==0x4000) { if(PicoOpt&1) d=YM2612Read(); else d=Pico.m.rotate++&3; dprintf("read ym2612: %04x", d); goto end; } // 0x4000-0x5fff, Fudge if disabled\r
-    d=0xffff; goto end;\r
-  }\r
-  if ((a&0xffffe0)==0xa10000) { // I/O ports\r
-    a=(a>>1)&0xf;\r
-    switch(a) {\r
-      case 0:  d=Pico.m.hardware; break; // Hardware value (Version register)\r
-      case 1:  d=PadRead(0); d|=Pico.ioports[1]&0x80; break;\r
-      case 2:  d=PadRead(1); d|=Pico.ioports[2]&0x80; break;\r
-      default: d=Pico.ioports[a]; break; // IO ports can be used as RAM\r
-    }\r
-    d|=d<<8;\r
-    goto end;\r
-  }\r
-  // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers\r
-  if (a==0xa11100) {\r
-    d=Pico.m.z80Run&1;\r
-#if 0\r
-    if (!d) {\r
-      // do we need this?\r
-      extern int z80stopCycle; // TODO: tidy\r
-      int stop_before = SekCyclesDone() - z80stopCycle;\r
-      if (stop_before > 0 && stop_before <= 16) // Gens uses 16 here\r
-        d = 1; // bus not yet available\r
-    }\r
-#endif\r
-    d=(d<<8)|0x8000|Pico.m.rotate++;\r
-    dprintf("get_zrun: %04x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), SekPc);\r
-    goto end; }\r
-\r
-#ifndef _ASM_MEMORY_C\r
-  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }\r
-#endif\r
-\r
-  d = UnusualRead16(a, realsize);\r
-\r
-end:\r
-  return d;\r
-}\r
 \r
 //extern UINT32 mz80GetRegisterValue(void *, UINT32);\r
 \r
-static void OtherWrite8(u32 a,u32 d,int realsize)\r
+static void OtherWrite8End(u32 a,u32 d,int realsize)\r
 {\r
-  if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound\r
-  if ((a&0xff4000)==0xa00000)  { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)d; return; } // Z80 ram\r
-  if ((a&0xff6000)==0xa04000)  { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d); return; } // FM Sound\r
-  if ((a&0xffffe0)==0xa10000)  { // I/O ports\r
-    a=(a>>1)&0xf;\r
-    // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
-    if(PicoOpt&0x20) {\r
-      if(a==1) {\r
-        Pico.m.padDelay[0] = 0;\r
-        if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;\r
-      }\r
-      else if(a==2) {\r
-        Pico.m.padDelay[1] = 0;\r
-        if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;\r
-      }\r
-    }\r
-    Pico.ioports[a]=(u8)d; // IO ports can be used as RAM\r
-    return;\r
-  }\r
-  if (a==0xa11100) {\r
-    extern int z80startCycle, z80stopCycle;\r
-    //int lineCycles=(488-SekCyclesLeft)&0x1ff;\r
-    d&=1; d^=1;\r
-    if(!d) {\r
-      // this is for a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)\r
-      if (Pico.m.z80Run) {\r
-        int lineCycles=(488-SekCyclesLeft)&0x1ff;\r
-        z80stopCycle = SekCyclesDone();\r
-        lineCycles=(lineCycles>>1)-(lineCycles>>5);\r
-        z80_run(lineCycles);\r
-      }\r
-    } else {\r
-      z80startCycle = SekCyclesDone();\r
-      //if(Pico.m.scanline != -1)\r
-    }\r
-    dprintf("set_zrun: %02x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), /*mz80GetRegisterValue(NULL, 0),*/ SekPc);\r
-    Pico.m.z80Run=(u8)d; return;\r
-  }\r
-  if (a==0xa11200) { dprintf("write z80Reset: %02x", d); if(!(d&1)) z80_reset(); return; }\r
-\r
-  if ((a&0xff7f00)==0xa06000) // Z80 BANK register\r
-  {\r
-    Pico.m.z80_bank68k>>=1;\r
-    Pico.m.z80_bank68k|=(d&1)<<8;\r
-    Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one\r
-    return;\r
-  }\r
-\r
-  if ((a&0xe700e0)==0xc00000)  { PicoVideoWrite(a,(u16)(d|(d<<8))); return; } // Byte access gets mirrored\r
-\r
   // sram\r
   //if(a==0x200000) dprintf("cc : %02x @ %06x [%i|%i]", d, SekPc, SekCyclesDoneT(), SekCyclesDone());\r
   //if(a==0x200001) dprintf("w8 : %02x @ %06x [%i]", d, SekPc, SekCyclesDoneT());\r
@@ -408,33 +251,9 @@ static void OtherWrite8(u32 a,u32 d,int realsize)
     Pico.m.prot_bytes[(a>>2)&1] = (u8)d;\r
 }\r
 \r
-static void OtherWrite16(u32 a,u32 d)\r
-{\r
-  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }\r
-  if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)(d>>8); return; } // Z80 ram (MSB only)\r
-\r
-  if ((a&0xffffe0)==0xa10000) { // I/O ports\r
-    a=(a>>1)&0xf;\r
-    // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
-    if(PicoOpt&0x20) {\r
-      if(a==1) {\r
-        Pico.m.padDelay[0] = 0;\r
-        if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;\r
-      }\r
-      else if(a==2) {\r
-        Pico.m.padDelay[1] = 0;\r
-        if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;\r
-      }\r
-    }\r
-    Pico.ioports[a]=(u8)d; // IO ports can be used as RAM\r
-    return;\r
-  }\r
-  if (a==0xa11100) { OtherWrite8(a, d>>8, 16); return; }\r
-  if (a==0xa11200) { dprintf("write z80reset: %04x", d); if(!(d&0x100)) z80_reset(); return; }\r
 \r
-  OtherWrite8(a,  d>>8, 16);\r
-  OtherWrite8(a+1,d&0xff, 16);\r
-}\r
+#include "MemoryCmn.c"\r
+\r
 \r
 // -----------------------------------------------------------------\r
 //                     Read Rom and read Ram\r
diff --git a/Pico/MemoryCmn.c b/Pico/MemoryCmn.c
new file mode 100644 (file)
index 0000000..5c7ef84
--- /dev/null
@@ -0,0 +1,219 @@
+/* common code for Memory.c and cd/Memory.c */
+
+static int PadRead(int i)
+{
+  int pad=0,value=0,TH;
+  pad=~PicoPad[i]; // Get inverse of pad MXYZ SACB RLDU
+  TH=Pico.ioports[i+1]&0x40;
+
+  if(PicoOpt & 0x20) { // 6 button gamepad enabled
+    int phase = Pico.m.padTHPhase[i];
+
+    if(phase == 2 && !TH) {
+      value=(pad&0xc0)>>2;              // ?0SA 0000
+      goto end;
+    } else if(phase == 3 && TH) {
+      value=(pad&0x30)|((pad>>8)&0xf);  // ?1CB MXYZ
+      goto end;
+    } else if(phase == 3 && !TH) {
+      value=((pad&0xc0)>>2)|0x0f;       // ?0SA 1111
+      goto end;
+    }
+  }
+
+  if(TH) value=(pad&0x3f);              // ?1CB RLDU
+  else   value=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU
+
+  end:
+
+  // orr the bits, which are set as output
+  value |= Pico.ioports[i+1]&Pico.ioports[i+4];
+
+  return value; // will mirror later
+}
+
+
+#ifndef _ASM_MEMORY_C
+static
+#endif
+u8 z80Read8(u32 a)
+{
+  if(Pico.m.z80Run&1) return 0;
+
+  a&=0x1fff;
+
+  if(!(PicoOpt&4)) {
+    // Z80 disabled, do some faking
+    static u8 zerosent = 0;
+    if(a == Pico.m.z80_lastaddr) { // probably polling something
+      u8 d = Pico.m.z80_fakeval;
+      if((d & 0xf) == 0xf && !zerosent) {
+        d = 0; zerosent = 1;
+      } else {
+        Pico.m.z80_fakeval++;
+        zerosent = 0;
+      }
+      return d;
+    } else {
+      Pico.m.z80_fakeval = 0;
+    }
+  }
+
+  Pico.m.z80_lastaddr = (u16) a;
+  return Pico.zram[a];
+}
+
+
+#ifndef _ASM_MEMORY_C
+static
+#endif
+u32 OtherRead16(u32 a, int realsize)
+{
+  u32 d=0;
+
+  if ((a&0xff0000)==0xa00000) {
+    if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped)
+    if ((a&0x6000)==0x4000) { // 0x4000-0x5fff, Fudge if disabled
+      if(PicoOpt&1) d=YM2612Read();
+      else d=Pico.m.rotate++&3;
+      dprintf("read ym2612: %04x", d);
+      goto end;
+    }
+    d=0xffff;
+    goto end;
+  }
+
+  if ((a&0xffffe0)==0xa10000) { // I/O ports
+    a=(a>>1)&0xf;
+    switch(a) {
+      case 0:  d=Pico.m.hardware; break; // Hardware value (Version register)
+      case 1:  d=PadRead(0); d|=Pico.ioports[1]&0x80; break;
+      case 2:  d=PadRead(1); d|=Pico.ioports[2]&0x80; break;
+      default: d=Pico.ioports[a]; break; // IO ports can be used as RAM
+    }
+    d|=d<<8;
+    goto end;
+  }
+
+  // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers
+  if (a==0xa11100) { // z80 busreq
+    d=Pico.m.z80Run&1;
+#if 0
+    if (!d) {
+      // do we need this?
+      extern int z80stopCycle;
+      int stop_before = SekCyclesDone() - z80stopCycle;
+      if (stop_before > 0 && stop_before <= 16) // Gens uses 16 here
+        d = 1; // bus not yet available
+    }
+#endif
+    d=(d<<8)|0x8000|Pico.m.rotate++;
+    dprintf("get_zrun: %04x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), SekPc);
+    goto end;
+  }
+
+#ifndef _ASM_MEMORY_C
+  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }
+#endif
+
+  d = OtherRead16End(a, realsize);
+
+end:
+  return d;
+}
+
+
+//extern UINT32 mz80GetRegisterValue(void *, UINT32);
+
+static void OtherWrite8(u32 a,u32 d,int realsize)
+{
+  if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound
+  if ((a&0xff4000)==0xa00000)  { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)d; return; } // Z80 ram
+  if ((a&0xff6000)==0xa04000)  { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d); return; } // FM Sound
+  if ((a&0xffffe0)==0xa10000)  { // I/O ports
+    a=(a>>1)&0xf;
+    // 6 button gamepad: if TH went from 0 to 1, gamepad changes state
+    if(PicoOpt&0x20) {
+      if(a==1) {
+        Pico.m.padDelay[0] = 0;
+        if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;
+      }
+      else if(a==2) {
+        Pico.m.padDelay[1] = 0;
+        if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;
+      }
+    }
+    Pico.ioports[a]=(u8)d; // IO ports can be used as RAM
+    return;
+  }
+  if (a==0xa11100) {
+    extern int z80startCycle, z80stopCycle;
+    //int lineCycles=(488-SekCyclesLeft)&0x1ff;
+    d&=1; d^=1;
+    if(!d) {
+      // this is for a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)
+      if (Pico.m.z80Run) {
+        int lineCycles=(488-SekCyclesLeft)&0x1ff;
+        z80stopCycle = SekCyclesDone();
+        lineCycles=(lineCycles>>1)-(lineCycles>>5);
+        z80_run(lineCycles);
+      }
+    } else {
+      z80startCycle = SekCyclesDone();
+      //if(Pico.m.scanline != -1)
+    }
+    dprintf("set_zrun: %02x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), /*mz80GetRegisterValue(NULL, 0),*/ SekPc);
+    Pico.m.z80Run=(u8)d; return;
+  }
+  if (a==0xa11200) {
+    dprintf("write z80Reset: %02x", d);
+    if(!(d&1)) z80_reset();
+    return;
+  }
+
+  if ((a&0xff7f00)==0xa06000) // Z80 BANK register
+  {
+    Pico.m.z80_bank68k>>=1;
+    Pico.m.z80_bank68k|=(d&1)<<8;
+    Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one
+    return;
+  }
+
+  if ((a&0xe700e0)==0xc00000) {
+    PicoVideoWrite(a,(u16)(d|(d<<8))); // Byte access gets mirrored
+    return;
+  }
+
+  OtherWrite8End(a, d, realsize);
+}
+
+
+static void OtherWrite16(u32 a,u32 d)
+{
+  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }
+  if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)(d>>8); return; } // Z80 ram (MSB only)
+
+  if ((a&0xffffe0)==0xa10000) { // I/O ports
+    a=(a>>1)&0xf;
+    // 6 button gamepad: if TH went from 0 to 1, gamepad changes state
+    if(PicoOpt&0x20) {
+      if(a==1) {
+        Pico.m.padDelay[0] = 0;
+        if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;
+      }
+      else if(a==2) {
+        Pico.m.padDelay[1] = 0;
+        if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;
+      }
+    }
+    Pico.ioports[a]=(u8)d; // IO ports can be used as RAM
+    return;
+  }
+  if (a==0xa11100) { OtherWrite8(a, d>>8, 16); return; }
+  if (a==0xa11200) { dprintf("write z80reset: %04x", d); if(!(d&0x100)) z80_reset(); return; }
+
+  OtherWrite8(a,  d>>8, 16);
+  OtherWrite8(a+1,d&0xff, 16);
+}
+
+
index 6168a7b..0cbeb80 100644 (file)
@@ -198,13 +198,22 @@ struct mcd_misc
 typedef struct\r
 {\r
        unsigned char bios[0x20000];                    // 128K\r
-       union {\r
-               unsigned char prg_ram[0x80000];         // 512K\r
+       union {                                         // 512K\r
+               unsigned char prg_ram[0x80000];\r
                unsigned char prg_ram_b[4][0x20000];\r
        };\r
-       unsigned char word_ram[0x40000];                // 256K\r
-       union {\r
-               unsigned char pcm_ram[0x10000];         // 64K\r
+       union {                                         // 256K\r
+               struct {\r
+                       unsigned char word_ram2M[0x40000];\r
+                       unsigned char unused[0x20000];\r
+               };\r
+               struct {\r
+                       unsigned char unused[0x20000];\r
+                       unsigned char word_ram1M[2][0x20000];\r
+               };\r
+       };\r
+       union {                                         // 64K\r
+               unsigned char pcm_ram[0x10000];\r
                unsigned char pcm_ram_b[0x10][0x1000];\r
        };\r
        unsigned char bram[0x2000];                     // 8K\r
@@ -293,6 +302,10 @@ void memcpy16(unsigned short *dest, unsigned short *src, int count);
 void memcpy32(int *dest, int *src, int count);\r
 void memset32(int *dest, int c, int count);\r
 \r
+// cd/Misc.c\r
+void wram_2M_to_1M(unsigned char *m);\r
+void wram_1M_to_2M(unsigned char *m);\r
+\r
 \r
 #ifdef __cplusplus\r
 } // End of extern "C"\r
index e3643df..bb5fe4a 100644 (file)
@@ -8,6 +8,7 @@
 \r
 \r
 #include "PicoInt.h"\r
+#include "cd/gfx_cd.h"\r
 \r
 extern const unsigned char  hcounts_32[];\r
 extern const unsigned char  hcounts_40[];\r
@@ -98,25 +99,31 @@ static void DmaSlow(int len)
     pd=(u16 *)(Pico.ram+(source&0xfffe));\r
     pdend=(u16 *)(Pico.ram+0x10000);\r
   } else if(PicoMCD & 1) {\r
-    dprintf("DmaSlow CD");\r
+    dprintf("DmaSlow CD, r3=%02x", Pico_mcd->s68k_regs[3]);\r
     if(source<0x20000) { // Bios area\r
       pd=(u16 *)(Pico_mcd->bios+(source&~1));\r
       pdend=(u16 *)(Pico_mcd->bios+0x20000);\r
-    } else if ((source&0xfc0000)==0x200000 && (!(Pico_mcd->s68k_regs[3]&4))) { // Word Ram\r
+    } else if ((source&0xfc0000)==0x200000) { // Word Ram\r
+      source -= 2;\r
       if (!(Pico_mcd->s68k_regs[3]&4)) { // 2M mode\r
-        source -= 2;\r
-        pd=(u16 *)(Pico_mcd->word_ram+(source&0x3fffe));\r
-        pdend=(u16 *)(Pico_mcd->word_ram+0x40000);\r
+        pd=(u16 *)(Pico_mcd->word_ram2M+(source&0x3fffe));\r
+        pdend=(u16 *)(Pico_mcd->word_ram2M+0x40000);\r
       } else {\r
-        dprintf("DmaSlow: unsupported src");\r
-       return;\r
+        if (source < 0x220000) { // 1M mode\r
+          int bank = Pico_mcd->s68k_regs[3]&1;\r
+          pd=(u16 *)(Pico_mcd->word_ram1M[bank]+(source&0x1fffe));\r
+          pdend=(u16 *)(Pico_mcd->word_ram1M[bank]+0x20000);\r
+       } else {\r
+          DmaSlowCell(source, a, len, inc);\r
+          return;\r
+       }\r
       }\r
     } else if ((source&0xfe0000)==0x020000) { // Prg Ram\r
       u8 *prg_ram = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
       pd=(u16 *)(prg_ram+(source&0x1fffe));\r
       pdend=(u16 *)(prg_ram+0x20000);\r
     } else {\r
-      dprintf("DmaSlow: unsupported src");\r
+      dprintf("DmaSlow FIXME: unsupported src");\r
       return;\r
     }\r
   } else {\r
@@ -142,8 +149,8 @@ static void DmaSlow(int len)
       if (inc == 2 && !(a&1) && a+len*2 < 0x10000)\r
       {\r
         // most used DMA mode\r
-       memcpy16(r + (a>>1), pd, len);\r
-       a += len*2;\r
+        memcpy16(r + (a>>1), pd, len);\r
+        a += len*2;\r
       }\r
       else\r
       {\r
index 82e7b1f..073033f 100644 (file)
@@ -125,10 +125,13 @@ int PicoCdSaveState(void *file)
                Pico_mcd->m.audio_offset = mp3_get_offset();
                memset(buff, 0, sizeof(buff));
                PicoAreaPackCpu(buff, 1);
+               if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
+                       wram_1M_to_2M(Pico_mcd->word_ram2M);
+               Pico_mcd->m.hint_vector = *(unsigned short *)(Pico_mcd->bios + 0x72);
 
                CHECKED_WRITE_BUFF(CHUNK_S68K,     buff);
                CHECKED_WRITE_BUFF(CHUNK_PRG_RAM,  Pico_mcd->prg_ram);
-               CHECKED_WRITE_BUFF(CHUNK_WORD_RAM, Pico_mcd->word_ram); // in 2M format
+               CHECKED_WRITE_BUFF(CHUNK_WORD_RAM, Pico_mcd->word_ram2M); // in 2M format
                CHECKED_WRITE_BUFF(CHUNK_PCM_RAM,  Pico_mcd->pcm_ram);
                CHECKED_WRITE_BUFF(CHUNK_BRAM,     Pico_mcd->bram);
                CHECKED_WRITE_BUFF(CHUNK_GA_REGS,  Pico_mcd->s68k_regs); // GA regs, not CPU regs
@@ -138,6 +141,9 @@ int PicoCdSaveState(void *file)
                CHECKED_WRITE_BUFF(CHUNK_SCD,      Pico_mcd->scd);
                CHECKED_WRITE_BUFF(CHUNK_RC,       Pico_mcd->rot_comp);
                CHECKED_WRITE_BUFF(CHUNK_MISC_CD,  Pico_mcd->m);
+
+               if (Pico_mcd->s68k_regs[3]&4) // convert back
+                       wram_2M_to_1M(Pico_mcd->word_ram2M);
        }
 
        return 0;
@@ -216,7 +222,7 @@ int PicoCdLoadState(void *file)
                                break;
 
                        case CHUNK_PRG_RAM:     CHECKED_READ_BUFF(Pico_mcd->prg_ram); break;
-                       case CHUNK_WORD_RAM:    CHECKED_READ_BUFF(Pico_mcd->word_ram); break;
+                       case CHUNK_WORD_RAM:    CHECKED_READ_BUFF(Pico_mcd->word_ram2M); break;
                        case CHUNK_PCM_RAM:     CHECKED_READ_BUFF(Pico_mcd->pcm_ram); break;
                        case CHUNK_BRAM:        CHECKED_READ_BUFF(Pico_mcd->bram); break;
                        case CHUNK_GA_REGS:     CHECKED_READ_BUFF(Pico_mcd->s68k_regs); break;
@@ -225,19 +231,22 @@ int PicoCdLoadState(void *file)
                        case CHUNK_CDC:         CHECKED_READ_BUFF(Pico_mcd->cdc); break;
                        case CHUNK_SCD:         CHECKED_READ_BUFF(Pico_mcd->scd); break;
                        case CHUNK_RC:          CHECKED_READ_BUFF(Pico_mcd->rot_comp); break;
-
-                       case CHUNK_MISC_CD:
-                               CHECKED_READ_BUFF(Pico_mcd->m);
-                               mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
-                               break;
+                       case CHUNK_MISC_CD:     CHECKED_READ_BUFF(Pico_mcd->m); break;
 
                        default:
-                               printf("skipping unknown chunk %i of size %i\n", buff[0], len);
+                               printf("PicoCdLoadState: skipping unknown chunk %i of size %i\n", buff[0], len);
                                areaSeek(file, len, SEEK_CUR);
                                break;
                }
        }
 
+       /* after load events */
+       if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
+               wram_2M_to_1M(Pico_mcd->word_ram2M);
+       mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
+       // restore hint vector
+        *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;
+
        return 0;
 }
 
index 2549fa8..1f00607 100644 (file)
@@ -104,19 +104,20 @@ void Update_CDC_TRansfer(int which)
        {\r
                if (Pico_mcd->s68k_regs[3] & 4)\r
                {\r
+                       // test: Final Fight\r
+                       int bank = !(Pico_mcd->s68k_regs[3]&1);\r
                        dep = ((DMA_Adr & 0x3FFF) << 3);\r
                        cdprintf("CD DMA # %04x -> word_ram1M # %06x, len=%i",\r
                                        Pico_mcd->cdc.DAC.N, dep, length);\r
 \r
-                       dep = ((DMA_Adr & 0x3FFF) << 4);\r
-                       if (!(Pico_mcd->s68k_regs[3]&1)) dep += 2;\r
-                       dest = (unsigned short *) (Pico_mcd->word_ram + dep);\r
+                       dest = (unsigned short *) (Pico_mcd->word_ram1M[bank] + dep);\r
 \r
-                       for (len = length; len > 0; len--, src+=2, dest+=2)\r
+                       // TODO: bswapcpy\r
+                       for (len = length; len > 0; len--, src+=2, dest++)\r
                                *dest = (src[0]<<8) | src[1];\r
 \r
                        { // debug\r
-                               unsigned char *b1 = Pico_mcd->word_ram + dep;\r
+                               unsigned char *b1 = Pico_mcd->word_ram1M[bank] + dep;\r
                                unsigned char *b2 = (unsigned char *)dest - 8;\r
                                dprintf("%02x %02x %02x %02x .. %02x %02x %02x %02x",\r
                                        b1[0], b1[1], b1[4], b1[5], b2[0], b2[1], b2[4], b2[5]);\r
@@ -127,13 +128,13 @@ void Update_CDC_TRansfer(int which)
                        dep = ((DMA_Adr & 0x7FFF) << 3);\r
                        cdprintf("CD DMA # %04x -> word_ram2M # %06x, len=%i",\r
                                        Pico_mcd->cdc.DAC.N, dep, length);\r
-                       dest = (unsigned short *) (Pico_mcd->word_ram + dep);\r
+                       dest = (unsigned short *) (Pico_mcd->word_ram2M + dep);\r
 \r
                        for (len = length; len > 0; len--, src+=2, dest++)\r
                                *dest = (src[0]<<8) | src[1];\r
 \r
                        { // debug\r
-                               unsigned char *b1 = Pico_mcd->word_ram + dep;\r
+                               unsigned char *b1 = Pico_mcd->word_ram2M + dep;\r
                                unsigned char *b2 = (unsigned char *)dest - 4;\r
                                dprintf("%02x %02x %02x %02x .. %02x %02x %02x %02x",\r
                                        b1[0], b1[1], b1[2], b1[3], b2[0], b2[1], b2[2], b2[3]);\r
@@ -146,7 +147,7 @@ void Update_CDC_TRansfer(int which)
                        dest = (unsigned char *) Ram_PCM;\r
                        dep = ((DMA_Adr & 0x03FF) << 2) + PCM_Chip.Bank;\r
 #else\r
-                       cdprintf("CD DMA # %04x -> PCM TODO", Pico_mcd->cdc.DAC.N);\r
+                       dprintf("FIXME: CD DMA # %04x -> PCM", Pico_mcd->cdc.DAC.N);\r
 #endif\r
        }\r
        else if (which == 5) // PRG RAM\r
@@ -188,7 +189,7 @@ unsigned short Read_CDC_Host(int is_sub)
        if (!(Pico_mcd->scd.Status_CDC & 0x08))\r
        {\r
                // Transfer data disabled\r
-               cdprintf("Read_CDC_Host: Transfer data disabled");\r
+               cdprintf("Read_CDC_Host FIXME: Transfer data disabled");\r
                return 0;\r
        }\r
 \r
@@ -196,7 +197,7 @@ unsigned short Read_CDC_Host(int is_sub)
                (!is_sub && (Pico_mcd->s68k_regs[4] & 7) != 2))\r
        {\r
                // Wrong setting\r
-               cdprintf("Read_CDC_Host: Wrong setting");\r
+               cdprintf("Read_CDC_Host FIXME: Wrong setting");\r
                return 0;\r
        }\r
 \r
index c941806..890af0a 100644 (file)
@@ -19,6 +19,8 @@
 #include "gfx_cd.h"\r
 #include "pcm.h"\r
 \r
+#include "cell_map.c"\r
+\r
 typedef unsigned char  u8;\r
 typedef unsigned short u16;\r
 typedef unsigned int   u32;\r
@@ -55,7 +57,7 @@ static u32 m68k_reg_read16(u32 a)
       d = Read_CDC_Host(0);\r
       goto end;\r
     case 0xA:\r
-      dprintf("m68k reserved read");\r
+      dprintf("m68k FIXME: reserved read");\r
       goto end;\r
     case 0xC:\r
       dprintf("m68k stopwatch timer read");\r
@@ -69,7 +71,7 @@ static u32 m68k_reg_read16(u32 a)
     goto end;\r
   }\r
 \r
-  dprintf("m68k_regs invalid read @ %02x", a);\r
+  dprintf("m68k_regs FIXME invalid read @ %02x", a);\r
 \r
 end:\r
 \r
@@ -115,12 +117,13 @@ static void m68k_reg_write8(u32 a, u32 d)
       Pico_mcd->s68k_regs[3] = d; // really use s68k side register\r
       return;\r
     case 6:\r
-      *((char *)&Pico_mcd->m.hint_vector+1) = d;\r
+      dprintf("FIXME hint[2]: %02x @%06x", (u8)d, SekPc);\r
       Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
       return;\r
     case 7:\r
-      *(char *)&Pico_mcd->m.hint_vector = d;\r
+      dprintf("FIXME hint[3]: %02x @%06x", (u8)d, SekPc);\r
       Pico_mcd->bios[0x72] = d;\r
+      dprintf("vector is now %08x", PicoRead32(0x70));\r
       return;\r
     case 0xe:\r
       //dprintf("m68k: comm flag: %02x", d);\r
@@ -133,7 +136,7 @@ static void m68k_reg_write8(u32 a, u32 d)
       return;\r
   }\r
 \r
-  dprintf("m68k: invalid write? [%02x] %02x", a, d);\r
+  dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);\r
 }\r
 \r
 \r
@@ -187,17 +190,27 @@ static void s68k_reg_write8(u32 a, u32 d)
   switch (a) {\r
     case 2:\r
       return; // only m68k can change WP\r
-    case 3:\r
+    case 3: {\r
+      int dold = Pico_mcd->s68k_regs[3];\r
       dprintf("s68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
       d &= 0x1d;\r
       if (d&4) {\r
-        d |= Pico_mcd->s68k_regs[3]&0xc2;\r
-        if ((d ^ Pico_mcd->s68k_regs[3]) & 5) d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
+        d |= dold&0xc2;\r
+        if ((d ^ dold) & 5) d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
+        if (!(dold & 4)) {\r
+          dprintf("wram mode 2M->1M");\r
+          wram_2M_to_1M(Pico_mcd->word_ram2M);\r
+       }\r
       } else {\r
         d |= Pico_mcd->s68k_regs[3]&0xc3;\r
         if (d&1) d &= ~2; // return word RAM to m68k in 2M mode\r
+        if (dold & 4) {\r
+          dprintf("wram mode 1M->2M");\r
+          wram_1M_to_2M(Pico_mcd->word_ram2M);\r
+       }\r
       }\r
       break;\r
+    }\r
     case 4:\r
       dprintf("s68k CDC dest: %x", d&7);\r
       Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode\r
@@ -251,7 +264,7 @@ static void s68k_reg_write8(u32 a, u32 d)
 \r
   if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
   {\r
-    dprintf("s68k: invalid write @ %02x?", a);\r
+    dprintf("s68k FIXME: invalid write @ %02x?", a);\r
     return;\r
   }\r
 \r
@@ -260,200 +273,33 @@ static void s68k_reg_write8(u32 a, u32 d)
 \r
 \r
 \r
-\r
-\r
-static int PadRead(int i)\r
-{\r
-  int pad=0,value=0,TH;\r
-  pad=~PicoPad[i]; // Get inverse of pad MXYZ SACB RLDU\r
-  TH=Pico.ioports[i+1]&0x40;\r
-\r
-  if(PicoOpt & 0x20) { // 6 button gamepad enabled\r
-    int phase = Pico.m.padTHPhase[i];\r
-\r
-    if(phase == 2 && !TH) {\r
-      value=(pad&0xc0)>>2;              // ?0SA 0000\r
-      goto end;\r
-    } else if(phase == 3 && TH) {\r
-      value=(pad&0x30)|((pad>>8)&0xf);  // ?1CB MXYZ\r
-      goto end;\r
-    } else if(phase == 3 && !TH) {\r
-      value=((pad&0xc0)>>2)|0x0f;       // ?0SA 1111\r
-      goto end;\r
-    }\r
-  }\r
-\r
-  if(TH) value=(pad&0x3f);              // ?1CB RLDU\r
-  else   value=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU\r
-\r
-  end:\r
-\r
-  // orr the bits, which are set as output\r
-  value |= Pico.ioports[i+1]&Pico.ioports[i+4];\r
-\r
-  return value; // will mirror later\r
-}\r
-\r
-static u8 z80Read8(u32 a)\r
-{\r
-  if(Pico.m.z80Run&1) return 0;\r
-\r
-  a&=0x1fff;\r
-\r
-  if(!(PicoOpt&4)) {\r
-    // Z80 disabled, do some faking\r
-    static u8 zerosent = 0;\r
-    if(a == Pico.m.z80_lastaddr) { // probably polling something\r
-      u8 d = Pico.m.z80_fakeval;\r
-      if((d & 0xf) == 0xf && !zerosent) {\r
-        d = 0; zerosent = 1;\r
-      } else {\r
-        Pico.m.z80_fakeval++;\r
-        zerosent = 0;\r
-      }\r
-      return d;\r
-    } else {\r
-      Pico.m.z80_fakeval = 0;\r
-    }\r
-  }\r
-\r
-  Pico.m.z80_lastaddr = (u16) a;\r
-  return Pico.zram[a];\r
-}\r
-\r
-\r
-// for nonstandard reads\r
-static u32 UnusualRead16(u32 a, int realsize)\r
-{\r
-  u32 d=0;\r
-\r
-  dprintf("unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
-\r
-\r
-  dprintf("ret = %04x", d);\r
-  return d;\r
-}\r
-\r
-static u32 OtherRead16(u32 a, int realsize)\r
+static u32 OtherRead16End(u32 a, int realsize)\r
 {\r
   u32 d=0;\r
 \r
-  if ((a&0xff0000)==0xa00000) {\r
-    if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped)\r
-    if ((a&0x6000)==0x4000) { if(PicoOpt&1) d=YM2612Read(); else d=Pico.m.rotate++&3; goto end; } // 0x4000-0x5fff, Fudge if disabled\r
-       d=0xffff; goto end;\r
-  }\r
-  if ((a&0xffffe0)==0xa10000) { // I/O ports\r
-    a=(a>>1)&0xf;\r
-    switch(a) {\r
-      case 0:  d=Pico.m.hardware; break; // Hardware value (Version register)\r
-      case 1:  d=PadRead(0); d|=Pico.ioports[1]&0x80; break;\r
-      case 2:  d=PadRead(1); d|=Pico.ioports[2]&0x80; break;\r
-      default: d=Pico.ioports[a]; break; // IO ports can be used as RAM\r
-    }\r
-    d|=d<<8;\r
-    goto end;\r
-  }\r
-  // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers\r
-  if (a==0xa11100) { d=((Pico.m.z80Run&1)<<8)|0x8000|Pico.m.rotate++; goto end; }\r
-\r
-  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }\r
-\r
   if ((a&0xffffc0)==0xa12000) {\r
     d=m68k_reg_read16(a);\r
     goto end;\r
   }\r
 \r
-  d = UnusualRead16(a, realsize);\r
+  dprintf("m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
 \r
 end:\r
   return d;\r
 }\r
 \r
-//extern UINT32 mz80GetRegisterValue(void *, UINT32);\r
 \r
-static void OtherWrite8(u32 a,u32 d,int realsize)\r
+static void OtherWrite8End(u32 a, u32 d, int realsize)\r
 {\r
-  if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound\r
-  if ((a&0xff4000)==0xa00000)  { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)d; return; } // Z80 ram\r
-  if ((a&0xff6000)==0xa04000)  { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d); return; } // FM Sound\r
-  if ((a&0xffffe0)==0xa10000)  { // I/O ports\r
-    a=(a>>1)&0xf;\r
-    // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
-    if(PicoOpt&0x20) {\r
-      if(a==1) {\r
-        Pico.m.padDelay[0] = 0;\r
-        if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;\r
-      }\r
-      else if(a==2) {\r
-        Pico.m.padDelay[1] = 0;\r
-        if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;\r
-      }\r
-    }\r
-    Pico.ioports[a]=(u8)d; // IO ports can be used as RAM\r
-    return;\r
-  }\r
-  if (a==0xa11100) {\r
-    extern int z80startCycle, z80stopCycle;\r
-    //int lineCycles=(488-SekCyclesLeft)&0x1ff;\r
-    d&=1; d^=1;\r
-       if(!d) {\r
-         // hack: detect a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)\r
-      if((PicoOpt&4) && Pico.m.z80Run==1) z80_run(20);\r
-         z80stopCycle = SekCyclesDone();\r
-         //z80ExtraCycles += (lineCycles>>1)-(lineCycles>>5); // only meaningful in PicoFrameHints()\r
-       } else {\r
-         z80startCycle = SekCyclesDone();\r
-         //if(Pico.m.scanline != -1)\r
-         //z80ExtraCycles -= (lineCycles>>1)-(lineCycles>>5)+16;\r
-       }\r
-    //dprintf("set_zrun: %i [%i|%i] zPC=%04x @%06x", d, Pico.m.scanline, SekCyclesDone(), mz80GetRegisterValue(NULL, 0), SekPc);\r
-       Pico.m.z80Run=(u8)d; return;\r
-  }\r
-  if (a==0xa11200) { if(!(d&1)) z80_reset(); return; }\r
-\r
-  if ((a&0xff7f00)==0xa06000) // Z80 BANK register\r
-  {\r
-    Pico.m.z80_bank68k>>=1;\r
-    Pico.m.z80_bank68k|=(d&1)<<8;\r
-    Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one\r
-    return;\r
-  }\r
-\r
-  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)(d|(d<<8))); return; } // Byte access gets mirrored\r
-\r
   if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
 \r
-  dprintf("strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
+  dprintf("m68k FIXME: strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
 }\r
 \r
-static void OtherWrite16(u32 a,u32 d)\r
-{\r
-  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }\r
-  if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)(d>>8); return; } // Z80 ram (MSB only)\r
-\r
-  if ((a&0xffffe0)==0xa10000) { // I/O ports\r
-    a=(a>>1)&0xf;\r
-    // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
-    if(PicoOpt&0x20) {\r
-      if(a==1) {\r
-        Pico.m.padDelay[0] = 0;\r
-        if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;\r
-      }\r
-      else if(a==2) {\r
-        Pico.m.padDelay[1] = 0;\r
-        if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;\r
-      }\r
-    }\r
-    Pico.ioports[a]=(u8)d; // IO ports can be used as RAM\r
-    return;\r
-  }\r
-  if (a==0xa11100) { OtherWrite8(a, d>>8, 16); return; }\r
-  if (a==0xa11200) { if(!(d&0x100)) z80_reset(); return; }\r
 \r
-  OtherWrite8(a,  d>>8, 16);\r
-  OtherWrite8(a+1,d&0xff, 16);\r
-}\r
+#undef _ASM_MEMORY_C\r
+#include "../MemoryCmn.c"\r
+\r
 \r
 // -----------------------------------------------------------------\r
 //                     Read Rom and read Ram\r
@@ -495,16 +341,14 @@ u8 PicoReadM68k8(u32 a)
   if ((a&0xfc0000)==0x200000) {\r
     dprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
     if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      if (a >= 0x220000) {\r
-        dprintf("cell");\r
-      } else {\r
-        a=((a&0x1fffe)<<1)|(a&1);\r
-       if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
-        d = Pico_mcd->word_ram[a^1];\r
-      }\r
+      int bank = Pico_mcd->s68k_regs[3]&1;\r
+      if (a >= 0x220000)\r
+           a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
+      else a &= 0x1ffff;\r
+      d = Pico_mcd->word_ram1M[bank][a^1];\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      d = Pico_mcd->word_ram[(a^1)&0x3ffff];\r
+      d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
     }\r
     dprintf("ret = %02x", (u8)d);\r
     goto end;\r
@@ -550,16 +394,14 @@ u16 PicoReadM68k16(u32 a)
   if ((a&0xfc0000)==0x200000) {\r
     dprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
     if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      if (a >= 0x220000) {\r
-        dprintf("cell");\r
-      } else {\r
-        a=((a&0x1fffe)<<1);\r
-       if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
-        d = *(u16 *)(Pico_mcd->word_ram+a);\r
-      }\r
+      int bank = Pico_mcd->s68k_regs[3]&1;\r
+      if (a >= 0x220000)\r
+           a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
+      else a &= 0x1fffe;\r
+      d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      d = *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
+      d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
     }\r
     dprintf("ret = %04x", d);\r
     goto end;\r
@@ -604,17 +446,20 @@ u32 PicoReadM68k32(u32 a)
   if ((a&0xfc0000)==0x200000) {\r
     dprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
     if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      if (a >= 0x220000) {\r
-        dprintf("cell");\r
+      int bank = Pico_mcd->s68k_regs[3]&1;\r
+      if (a >= 0x220000) { // cell arranged\r
+        u32 a1, a2;\r
+        a1 = (a&2) | (cell_map(a >> 2) << 2);\r
+       if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
+       else     a2 = a1 + 2;\r
+       d  = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;\r
+       d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);\r
       } else {\r
-        a=((a&0x1fffe)<<1);\r
-       if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
-        d  = *(u16 *)(Pico_mcd->word_ram+a) << 16;\r
-        d |= *(u16 *)(Pico_mcd->word_ram+a+4);\r
+        u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
       }\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
+      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
     }\r
     dprintf("ret = %08x", d);\r
     goto end;\r
@@ -666,16 +511,14 @@ void PicoWriteM68k8(u32 a,u8 d)
   if ((a&0xfc0000)==0x200000) {\r
     dprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
     if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      if (a >= 0x220000) {\r
-        dprintf("cell");\r
-      } else {\r
-        a=((a&0x1fffe)<<1)|(a&1);\r
-       if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
-        *(u8 *)(Pico_mcd->word_ram+(a^1))=d;\r
-      }\r
+      int bank = Pico_mcd->s68k_regs[3]&1;\r
+      if (a >= 0x220000)\r
+           a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
+      else a &= 0x1ffff;\r
+      *(u8 *)(Pico_mcd->word_ram1M[bank]+(a^1))=d;\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      *(u8 *)(Pico_mcd->word_ram+((a^1)&0x3ffff))=d;\r
+      *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
     }\r
     return;\r
   }\r
@@ -712,16 +555,14 @@ void PicoWriteM68k16(u32 a,u16 d)
   if ((a&0xfc0000)==0x200000) {\r
     dprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
     if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      if (a >= 0x220000) {\r
-        dprintf("cell");\r
-      } else {\r
-        a=((a&0x1fffe)<<1);\r
-       if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
-        *(u16 *)(Pico_mcd->word_ram+a)=d;\r
-      }\r
+      int bank = Pico_mcd->s68k_regs[3]&1;\r
+      if (a >= 0x220000)\r
+           a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
+      else a &= 0x1fffe;\r
+      *(u16 *)(Pico_mcd->word_ram1M[bank]+a)=d;\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe))=d;\r
+      *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
     }\r
     return;\r
   }\r
@@ -762,17 +603,21 @@ void PicoWriteM68k32(u32 a,u32 d)
     if (d != 0) // don't log clears\r
       dprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc);\r
     if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      if (a >= 0x220000) {\r
-        dprintf("cell");\r
+      int bank = Pico_mcd->s68k_regs[3]&1;\r
+      if (a >= 0x220000) { // cell arranged\r
+        u32 a1, a2;\r
+        a1 = (a&2) | (cell_map(a >> 2) << 2);\r
+       if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
+       else     a2 = a1 + 2;\r
+       *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) = d >> 16;\r
+       *(u16 *)(Pico_mcd->word_ram1M[bank]+a2) = d;\r
       } else {\r
-        a=((a&0x1fffe)<<1);\r
-       if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
-        *(u16 *)(Pico_mcd->word_ram+a) = d>>16;\r
-        *(u16 *)(Pico_mcd->word_ram+a+4) = d;\r
+        u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
+        pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
       }\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
+      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
       pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
     }\r
     return;\r
@@ -815,24 +660,30 @@ u8 PicoReadS68k8(u32 a)
 \r
   // word RAM (2M area)\r
   if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
+    // test: batman returns\r
     dprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      // TODO (decode)\r
-      dprintf("(decode)");\r
+    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
+      if (a&1) d &= 0x0f;\r
+      else d >>= 4;\r
+      dprintf("FIXME: decode");\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      d = Pico_mcd->word_ram[(a^1)&0x3ffff];\r
+      d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
     }\r
     dprintf("ret = %02x", (u8)d);\r
     goto end;\r
   }\r
 \r
   // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
+  if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
+    int bank;\r
     dprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);\r
-    a=((a&0x1fffe)<<1)|(a&1);\r
-    if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
-    d = Pico_mcd->word_ram[a^1];\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      dprintf("s68k_wram1M FIXME: wrong mode");\r
+    bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];\r
     dprintf("ret = %02x", (u8)d);\r
     goto end;\r
   }\r
@@ -895,23 +746,27 @@ u16 PicoReadS68k16(u32 a)
   // word RAM (2M area)\r
   if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
     dprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      // TODO (decode)\r
-      dprintf("(decode)");\r
+    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
+      d |= d << 4; d &= ~0xf0;\r
+      dprintf("FIXME: decode");\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      d = *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
+      d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
     }\r
     dprintf("ret = %04x", d);\r
     goto end;\r
   }\r
 \r
   // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
+  if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
+    int bank;\r
     dprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);\r
-    a=((a&0x1fffe)<<1);\r
-    if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
-    d = *(u16 *)(Pico_mcd->word_ram+a);\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      dprintf("s68k_wram1M FIXME: wrong mode");\r
+    bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
     dprintf("ret = %04x", d);\r
     goto end;\r
   }\r
@@ -979,24 +834,29 @@ u32 PicoReadS68k32(u32 a)
   // word RAM (2M area)\r
   if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
     dprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      // TODO (decode)\r
-      dprintf("(decode)");\r
+    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      a >>= 1;\r
+      d  = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;\r
+      d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff];\r
+      d |= d << 4; d &= 0x0f0f0f0f;\r
+      dprintf("FIXME: decode");\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
+      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
     }\r
     dprintf("ret = %08x", d);\r
     goto end;\r
   }\r
 \r
   // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
+  if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
+    int bank;\r
     dprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);\r
-    a=((a&0x1fffe)<<1);\r
-    if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
-    d  = *(u16 *)(Pico_mcd->word_ram+a) << 16;\r
-    d |= *(u16 *)(Pico_mcd->word_ram+a+4);\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      dprintf("s68k_wram1M FIXME: wrong mode");\r
+    bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
     dprintf("ret = %08x", d);\r
     goto end;\r
   }\r
@@ -1077,23 +937,28 @@ void PicoWriteS68k8(u32 a,u8 d)
   // word RAM (2M area)\r
   if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
     dprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      // TODO (decode)\r
-      dprintf("(decode)");\r
+    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      if (a&1) d &= 0x0f;\r
+      else d >>= 4;\r
+      Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff]=d;\r
+      dprintf("FIXME: decode");\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      *(u8 *)(Pico_mcd->word_ram+((a^1)&0x3ffff))=d;\r
+      *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
     }\r
     return;\r
   }\r
 \r
   // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
+  if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
+    int bank;\r
     if (d)\r
       dprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
-    a=((a&0x1fffe)<<1)|(a&1);\r
-    if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
-    *(u8 *)(Pico_mcd->word_ram+(a^1))=d;\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      dprintf("s68k_wram1M FIXME: wrong mode");\r
+    bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;\r
     return;\r
   }\r
 \r
@@ -1152,23 +1017,27 @@ void PicoWriteS68k16(u32 a,u16 d)
   // word RAM (2M area)\r
   if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
     dprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      // TODO (decode)\r
-      dprintf("(decode)");\r
+    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      d &= ~0xf0; d |= d >> 8;\r
+      Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff] = d;\r
+      dprintf("FIXME: decode");\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe))=d;\r
+      *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
     }\r
     return;\r
   }\r
 \r
   // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
+  if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
+    int bank;\r
     if (d)\r
       dprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
-    a=((a&0x1fffe)<<1);\r
-    if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
-    *(u16 *)(Pico_mcd->word_ram+a)=d;\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      dprintf("s68k_wram1M FIXME: wrong mode");\r
+    bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;\r
     return;\r
   }\r
 \r
@@ -1230,25 +1099,32 @@ void PicoWriteS68k32(u32 a,u32 d)
   // word RAM (2M area)\r
   if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
     dprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      // TODO (decode)\r
-      dprintf("(decode)");\r
+    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      a >>= 1;\r
+      d &= 0x0f0f0f0f; d |= d >> 4;\r
+      Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] = d >> 16;\r
+      Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff] = d;\r
+      dprintf("FIXME: decode");\r
     } else {\r
       // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
+      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
       pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
     }\r
     return;\r
   }\r
 \r
   // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
+  if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
+    int bank;\r
+    u16 *pm;\r
     if (d)\r
       dprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
-    a=((a&0x1fffe)<<1);\r
-    if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
-    *(u16 *)(Pico_mcd->word_ram+a) = d>>16;\r
-    *(u16 *)(Pico_mcd->word_ram+a+4) = d;\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      dprintf("s68k_wram1M FIXME: wrong mode");\r
+    bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
+    pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
     return;\r
   }\r
 \r
@@ -1290,28 +1166,26 @@ void PicoWriteS68k32(u32 a,u32 d)
 #if defined(EMU_C68K)\r
 static __inline int PicoMemBaseM68k(u32 pc)\r
 {\r
-  int membase=0;\r
+  if ((pc&0xe00000)==0xe00000)\r
+    return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
 \r
   if (pc < 0x20000)\r
+    return (int)Pico_mcd->bios; // Program Counter in BIOS\r
+\r
+  if ((pc&0xfc0000)==0x200000)\r
   {\r
-    membase=(int)Pico_mcd->bios; // Program Counter in BIOS\r
-  }\r
-  else if ((pc&0xe00000)==0xe00000)\r
-  {\r
-    membase=(int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
-  }\r
-  else if ((pc&0xfc0000)==0x200000 && !(Pico_mcd->s68k_regs[3]&4))\r
-  {\r
-    membase=(int)Pico_mcd->word_ram-0x200000; // Program Counter in Word Ram\r
-  }\r
-  else\r
-  {\r
-    // Error - Program Counter is invalid\r
-    dprintf("m68k: unhandled jump to %06x", pc);\r
-    membase=(int)Pico.rom;\r
+    if (!(Pico_mcd->s68k_regs[3]&4))\r
+      return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram\r
+    if (pc < 0x220000) {\r
+      int bank = (Pico_mcd->s68k_regs[3]&1);\r
+      return (int)Pico_mcd->word_ram1M[bank] - 0x200000;\r
+    }\r
   }\r
 \r
-  return membase;\r
+  // Error - Program Counter is invalid\r
+  dprintf("m68k FIXME: unhandled jump to %06x", pc);\r
+\r
+  return (int)Pico_mcd->bios;\r
 }\r
 \r
 \r
@@ -1328,16 +1202,21 @@ static u32 PicoCheckPcM68k(u32 pc)
 \r
 static __inline int PicoMemBaseS68k(u32 pc)\r
 {\r
-  int membase;\r
+  if (pc < 0x80000)                     // PRG RAM\r
+    return (int)Pico_mcd->prg_ram;\r
 \r
-  membase=(int)Pico_mcd->prg_ram; // Program Counter in Prg RAM\r
-  if (pc >= 0x80000)\r
-  {\r
-    // Error - Program Counter is invalid\r
-    dprintf("s68k: unhandled jump to %06x", pc);\r
+  if ((pc&0xfc0000)==0x080000)          // WORD RAM 2M area (assume we are in the right mode..)\r
+    return (int)Pico_mcd->word_ram2M - 0x080000;\r
+\r
+  if ((pc&0xfe0000)==0x0c0000) {        // word RAM 1M area\r
+    int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+    return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;\r
   }\r
 \r
-  return membase;\r
+  // Error - Program Counter is invalid\r
+  dprintf("s68k FIXME: unhandled jump to %06x", pc);\r
+\r
+  return (int)Pico_mcd->prg_ram;\r
 }\r
 \r
 \r
@@ -1402,13 +1281,25 @@ unsigned int  m68k_read_pcrelative_CD8 (unsigned int a) {
   a&=0xffffff;\r
   if(m68ki_cpu_p == &PicoS68kCPU) {\r
     if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram\r
-    dprintf("s68k_read_pcrelative_CD8: can't handle %06x", a);\r
+    if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
+      return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));\r
+    if ((a&0xfe0000)==0x0c0000 &&  (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));\r
+    }\r
+    dprintf("s68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);\r
   } else {\r
-    if(a<0x20000)              return *(u8 *)(Pico.rom+(a^1)); // Bios\r
     if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
-    if(!(Pico_mcd->s68k_regs[3]&4) && (a&0xfc0000)==0x200000)\r
-      return Pico_mcd->word_ram[(a^1)&0x3fffe];\r
-    dprintf("m68k_read_pcrelative_CD8: can't handle %06x", a);\r
+    if(a<0x20000)              return *(u8 *)(Pico.rom+(a^1)); // Bios\r
+    if((a&0xfc0000)==0x200000) { // word RAM\r
+      if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
+        return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));\r
+      else if (a < 0x220000) {\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));\r
+      }\r
+    }\r
+    dprintf("m68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);\r
   }\r
   return 0;//(u8)  lastread_d;\r
 }\r
@@ -1416,27 +1307,54 @@ unsigned int  m68k_read_pcrelative_CD16(unsigned int a) {
   a&=0xffffff;\r
   if(m68ki_cpu_p == &PicoS68kCPU) {\r
     if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram\r
-    dprintf("s68k_read_pcrelative_CD16: can't handle %06x", a);\r
+    if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
+      return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
+    if ((a&0xfe0000)==0x0c0000 &&  (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
+    }\r
+    dprintf("s68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);\r
   } else {\r
-    if(a<0x20000)              return *(u16 *)(Pico.rom+(a&~1)); // Bios\r
     if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram\r
-    if(!(Pico_mcd->s68k_regs[3]&4) && (a&0xfc0000)==0x200000)\r
-      return *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
-    dprintf("m68k_read_pcrelative_CD16: can't handle %06x", a);\r
+    if(a<0x20000)              return *(u16 *)(Pico.rom+(a&~1)); // Bios\r
+    if((a&0xfc0000)==0x200000) { // word RAM\r
+      if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
+        return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
+      else if (a < 0x220000) {\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
+      }\r
+    }\r
+    dprintf("m68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);\r
   }\r
   return 0;\r
 }\r
 unsigned int  m68k_read_pcrelative_CD32(unsigned int a) {\r
+  u16 *pm;\r
   a&=0xffffff;\r
   if(m68ki_cpu_p == &PicoS68kCPU) {\r
     if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram\r
-    dprintf("s68k_read_pcrelative_CD32: can't handle %06x", a);\r
+    if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
+      { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
+    if ((a&0xfe0000)==0x0c0000 &&  (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
+      int bank = !(Pico_mcd->s68k_regs[3]&1);\r
+      pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
+      return (pm[0]<<16)|pm[1];\r
+    }\r
+    dprintf("s68k_read_pcrelative_CD32 FIXME: can't handle %06x", a);\r
   } else {\r
-    if(a<0x20000)              { u16 *pm=(u16 *)(Pico.rom+(a&~1));     return (pm[0]<<16)|pm[1]; }\r
     if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram\r
-    if(!(Pico_mcd->s68k_regs[3]&4) && (a&0xfc0000)==0x200000)\r
-      { u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
-    dprintf("m68k_read_pcrelative_CD32: can't handle %06x", a);\r
+    if(a<0x20000)              { u16 *pm=(u16 *)(Pico.rom+(a&~1));     return (pm[0]<<16)|pm[1]; }\r
+    if((a&0xfc0000)==0x200000) { // word RAM\r
+      if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
+        { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
+      else if (a < 0x220000) {\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
+        return (pm[0]<<16)|pm[1];\r
+      }\r
+    }\r
+    dprintf("m68k_read_pcrelative_CD32 FIXME: can't handle %06x", a);\r
   }\r
   return 0;\r
 }\r
index 981e71a..905e919 100644 (file)
@@ -16,3 +16,41 @@ unsigned char formatted_bram[4*0x10] =
 };
 
 
+// offs | 2Mbit  | 1Mbit  |
+//   0  | [ 2M   | unused |
+// 128K |  bit ] | bank0  |
+// 256K | unused | bank1  |
+
+void wram_2M_to_1M(unsigned char *m)
+{
+       unsigned short *m1M_b0, *m1M_b1;
+       unsigned int i, tmp, *m2M;
+
+       m2M = (unsigned int *) (m + 0x40000);
+       m1M_b0 = (unsigned short *) m2M;
+       m1M_b1 = (unsigned short *) (m + 0x60000);
+
+       for (i = 0x40000/4; i; i--)
+       {
+               tmp = *(--m2M);
+               *(--m1M_b0) = tmp;
+               *(--m1M_b1) = tmp >> 16;
+       }
+}
+
+void wram_1M_to_2M(unsigned char *m)
+{
+       unsigned short *m1M_b0, *m1M_b1;
+       unsigned int i, tmp, *m2M;
+
+       m2M = (unsigned int *) m;
+       m1M_b0 = (unsigned short *) (m + 0x20000);
+       m1M_b1 = (unsigned short *) (m + 0x40000);
+
+       for (i = 0x40000/4; i; i--)
+       {
+               tmp = *m1M_b0++ | (*m1M_b1++ << 16);
+               *m2M++ = tmp;
+       }
+}
+
index 770eddb..eddd878 100644 (file)
@@ -30,9 +30,9 @@ void PicoExitMCD(void)
 
 int PicoResetMCD(int hard)
 {
-  memset(Pico_mcd->prg_ram,  0, sizeof(Pico_mcd->prg_ram));
-  memset(Pico_mcd->word_ram, 0, sizeof(Pico_mcd->word_ram));
-  memset(Pico_mcd->pcm_ram, 0, sizeof(Pico_mcd->pcm_ram));
+  memset(Pico_mcd->prg_ram,    0, sizeof(Pico_mcd->prg_ram));
+  memset(Pico_mcd->word_ram2M, 0, sizeof(Pico_mcd->word_ram2M));
+  memset(Pico_mcd->pcm_ram,    0, sizeof(Pico_mcd->pcm_ram));
   if (hard) {
          int fmt_size = sizeof(formatted_bram);
          memset(Pico_mcd->bram, 0, sizeof(Pico_mcd->bram));
diff --git a/Pico/cd/cell_map.c b/Pico/cd/cell_map.c
new file mode 100644 (file)
index 0000000..5358a09
--- /dev/null
@@ -0,0 +1,38 @@
+
+// 64 x32 x16 x8 x4 x4
+static unsigned int cell_map(int celln)
+{
+  int col, row;
+
+  switch ((celln >> 12) & 7) { // 0-0x8000
+    case 0: // x32 cells
+    case 1:
+    case 2:
+    case 3:
+      col = celln >> 8;
+      row = celln & 0xff;
+      break;
+    case 4: // x16
+    case 5:
+      col  = celln >> 7;
+      row  = celln & 0x7f;
+      row |= 0x10000 >> 8;
+      break;
+    case 6: // x8
+      col  = celln >> 6;
+      row  = celln & 0x3f;
+      row |= 0x18000 >> 8;
+      break;
+    case 7: // x4
+      col  = celln >> 5;
+      row  = celln & 0x1f;
+      row |= (celln & 0x7800) >> 6;
+      break;
+    default: // just to make compiler happy
+      col = row = 0;
+      break;
+  }
+
+  return (col & 0x3f) + row*64;
+}
+
index 06fa53c..ba1c5a7 100644 (file)
@@ -146,7 +146,7 @@ unsigned int gfx_cd_read(unsigned int a)
                case 0x62: d = rot_comp.Reg_62; break;
                case 0x64: d = rot_comp.Reg_64; break;
                case 0x66: break;
-               default: dprintf("gfx_cd_read: unexpected address: %02x", a); break;
+               default: dprintf("gfx_cd_read FIXME: unexpected address: %02x", a); break;
        }
 
        dprintf("gfx_cd_read(%02x) = %04x", a, d);
@@ -193,13 +193,82 @@ void gfx_cd_write(unsigned int a, unsigned int d)
                        gfx_cd_start();
                        return;
 
-               default: dprintf("gfx_cd_write: unexpected address: %02x", a); return;
+               default: dprintf("gfx_cd_write FIXME: unexpected address: %02x", a); return;
        }
 }
 
 
 void gfx_cd_reset(void)
 {
-       memset(&rot_comp.Reg_58, 0, 0/*sizeof(Pico_mcd->rot_comp)*/);
+       memset(&rot_comp.Reg_58, 0, sizeof(rot_comp));
+}
+
+
+// --------------------------------
+
+#include "cell_map.c"
+
+typedef unsigned short u16;
+
+void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc)
+{
+  unsigned char *base;
+  unsigned int asrc, a2;
+  u16 *r;
+
+  base = Pico_mcd->word_ram1M[Pico_mcd->s68k_regs[3]&1];
+
+  switch (Pico.video.type)
+  {
+    case 1: // vram
+      r = Pico.vram;
+      for(; len; len--)
+      {
+        asrc = cell_map(source >> 2) << 2;
+        asrc |= source & 2;
+        // if(a&1) d=(d<<8)|(d>>8); // ??
+        r[a>>1] = *(u16 *)(base + asrc);
+       source += 2;
+        // AutoIncrement
+        a=(u16)(a+inc);
+      }
+      rendstatus|=0x10;
+      break;
+
+    case 3: // cram
+      Pico.m.dirtyPal = 1;
+      r = Pico.cram;
+      for(a2=a&0x7f; len; len--)
+      {
+        asrc = cell_map(source >> 2) << 2;
+        asrc |= source & 2;
+        r[a2>>1] = *(u16 *)(base + asrc);
+       source += 2;
+        // AutoIncrement
+        a2+=inc;
+        // good dest?
+        if(a2 >= 0x80) break;
+      }
+      a=(a&0xff00)|a2;
+      break;
+
+    case 5: // vsram[a&0x003f]=d;
+      r = Pico.vsram;
+      for(a2=a&0x7f; len; len--)
+      {
+        asrc = cell_map(source >> 2) << 2;
+        asrc |= source & 2;
+        r[a2>>1] = *(u16 *)(base + asrc);
+       source += 2;
+        // AutoIncrement
+        a2+=inc;
+        // good dest?
+        if(a2 >= 0x80) break;
+      }
+      a=(a&0xff00)|a2;
+      break;
+  }
+  // remember addr
+  Pico.video.addr=(u16)a;
 }
 
index 519f95e..c610f9d 100644 (file)
@@ -40,5 +40,7 @@ void gfx_cd_write(unsigned int a, unsigned int d);
 
 void gfx_cd_reset(void);
 
+void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc);
+
 #endif // _GFX_CD_H
 
diff --git a/Pico/misc.s b/Pico/misc.s
new file mode 100644 (file)
index 0000000..541e81b
--- /dev/null
@@ -0,0 +1,101 @@
+
+@ vim:filetype=armasm
+
+
+.global memcpy16 @ unsigned short *dest, unsigned short *src, int count
+
+memcpy16:
+    eor     r3, r0, r1
+    tst     r3, #2
+    bne     mcp16_cant_align
+
+    tst     r0, #2
+    ldrneh  r3, [r1], #2
+    subne   r2, r2, #1
+    strneh  r3, [r0], #2
+
+    subs    r2, r2, #4
+    bmi     mcp16_fin
+
+mcp16_loop:
+    ldmia   r1!, {r3,r12}
+    subs    r2, r2, #4
+    stmia   r0!, {r3,r12}
+    bpl     mcp16_loop
+
+mcp16_fin:
+    tst     r2, #2
+    ldrne   r3, [r1], #4
+    strne   r3, [r0], #4
+    ands    r2, r2, #1
+    bxeq    lr
+
+mcp16_cant_align:
+    ldrh    r3, [r1], #2
+    subs    r2, r2, #1
+    strh    r3, [r0], #2
+    bne     mcp16_cant_align
+
+    bx      lr
+
+
+
+.global memcpy32 @ int *dest, int *src, int count
+
+memcpy32:
+    stmfd   sp!, {r4,lr}
+
+    subs    r2, r2, #4
+    bmi     mcp32_fin
+
+mcp32_loop:
+    ldmia   r1!, {r3,r4,r12,lr}
+    subs    r2, r2, #4
+    stmia   r0!, {r3,r4,r12,lr}
+    bpl     mcp32_loop
+
+mcp32_fin:
+    tst     r2, #3
+    ldmeqfd sp!, {r4,pc}
+    tst     r2, #1
+    ldrne   r3, [r1], #4
+    strne   r3, [r0], #4
+
+mcp32_no_unal1:
+    tst     r2, #2
+    ldmneia r1!, {r3,r12}
+    ldmfd   sp!, {r4,lr}
+    stmneia r0!, {r3,r12}
+    bx      lr
+
+
+
+.global memset32 @ int *dest, int c, int count
+
+memset32:
+    stmfd   sp!, {lr}
+
+    mov     r3, r1
+    subs    r2, r2, #4
+    bmi     mst32_fin
+
+    mov     r12,r1
+    mov     lr, r1
+
+mst32_loop:
+    subs    r2, r2, #4
+    stmia   r0!, {r1,r3,r12,lr}
+    bpl     mst32_loop
+
+mst32_fin:
+    tst     r2, #1
+    strne   r1, [r0], #4
+
+    tst     r2, #2
+    stmneia r0!, {r1,r3}
+
+    ldmfd   sp!, {lr}
+    bx      lr
+
+
+
index 28e6dc4..cc36a44 100644 (file)
@@ -248,8 +248,10 @@ int sound_render(int offset, int length)
     SN76496Update(PsndOut+offset, length, stereo);\r
 \r
   // Add in the stereo FM buffer\r
-  if (PicoOpt & 1)\r
+  if (PicoOpt & 1) {\r
     buf32_updated = YM2612UpdateOne(buf32, length, stereo, 1);\r
+  } else\r
+    memset32(buf32, 0, length<<stereo);\r
 \r
 //printf("active_chs: %02x\n", buf32_updated);\r
 \r
index 56c83ff..24496fd 100644 (file)
@@ -764,6 +764,12 @@ static int check_save_file(void)
        return 0;\r
 }\r
 \r
+static void emu_state_cb(const char *str)\r
+{\r
+       clearArea(0);\r
+       blit("", str);\r
+}\r
+\r
 static void RunEvents(unsigned int which)\r
 {\r
        if(which & 0x1800) { // save or load (but not both)\r
@@ -778,7 +784,10 @@ static void RunEvents(unsigned int which)
                }\r
                if (do_it) {\r
                        osd_text(4, 232, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME");\r
+                       PicoStateProgressCB = emu_state_cb;\r
+                       gp2x_memcpy_all_buffers(gp2x_screen, 0, 320*240*2);\r
                        emu_SaveLoadGame((which & 0x1000) >> 12, 0);\r
+                       PicoStateProgressCB = NULL;\r
                }\r
 \r
                reset_timing = 1;\r
@@ -1263,20 +1272,11 @@ size_t gzWrite2(void *p, size_t _size, size_t _n, void *file)
 }\r
 \r
 \r
-static void emu_state_cb(const char *str)\r
-{\r
-       clearArea(0);\r
-       blit("", str);\r
-}\r
-\r
 int emu_SaveLoadGame(int load, int sram)\r
 {\r
        int ret = 0;\r
        char saveFname[512];\r
 \r
-       PicoStateProgressCB = emu_state_cb;\r
-       gp2x_memcpy_all_buffers(gp2x_screen, 0, 320*240*2);\r
-\r
        // make save filename\r
        romfname_ext(saveFname, "");\r
        if(sram) strcat(saveFname, (PicoMCD&1) ? ".brm" : ".srm");\r
index a4d411f..0645b77 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.14"\r
+#define VERSION "1.15"\r
 \r