new memory handling, but asm and mappers need update.
authornotaz <notasas@gmail.com>
Wed, 2 Sep 2009 16:05:54 +0000 (16:05 +0000)
committernotaz <notasas@gmail.com>
Wed, 2 Sep 2009 16:05:54 +0000 (16:05 +0000)
Some cleanup and magic bit removal as a bonus.

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@768 be3aeb3a-fb24-0410-a615-afba39da0efa

20 files changed:
pico/cart.c
pico/cd/area.c
pico/cd/memory.c
pico/cd/pico.c
pico/debug.c
pico/memory.c
pico/memory.h [new file with mode: 0644]
pico/memory_cmn.c [deleted file]
pico/misc.c
pico/patch.c
pico/pico.c
pico/pico_int.h
pico/sms.c
pico/sound/sound.c
pico/z80if.c
platform/common/common_arm.mak
platform/common/emu.c
platform/common/revision.mak
platform/gp2x/Makefile
platform/linux/Makefile

index 8614a16..5c04fa4 100644 (file)
@@ -572,13 +572,10 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
   PicoLoadStateHook = NULL;\r
   carthw_chunks = NULL;\r
 \r
-  PicoMemReset();\r
-\r
   if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))\r
     PicoCartDetect();\r
 \r
   // setup correct memory map for loaded ROM\r
-  // call PicoMemReset again due to possible memmap change\r
   switch (PicoAHW) {\r
     default:\r
       elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoAHW);\r
@@ -588,7 +585,6 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
     case PAHW_PICO: PicoMemSetupPico(); break;\r
     case PAHW_SMS:  PicoMemSetupMS(); break;\r
   }\r
-  PicoMemReset();\r
 \r
   if (PicoAHW & PAHW_SMS)\r
     PicoPowerMS();\r
@@ -627,6 +623,12 @@ static int name_cmp(const char *name)
   return rom_strcmp(0x150, name);\r
 }\r
 \r
+static unsigned int rom_read32(int addr)\r
+{\r
+  unsigned short *m = (unsigned short *)(Pico.rom + addr);\r
+  return (m[0] << 16) | m[1];\r
+}\r
+\r
 /*\r
  * various cart-specific things, which can't be handled by generic code\r
  * (maybe I should start using CRC for this stuff?)\r
@@ -634,28 +636,28 @@ static int name_cmp(const char *name)
 static void PicoCartDetect(void)\r
 {\r
   int sram_size = 0, csum;\r
-  Pico.m.sram_reg = 0;\r
+  Pico.m.sram_status = 0;\r
 \r
-  csum = PicoRead32(0x18c) & 0xffff;\r
+  csum = rom_read32(0x18c) & 0xffff;\r
 \r
   if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A')\r
   {\r
     if (Pico.rom[0x1B2] & 0x40)\r
     {\r
       // EEPROM\r
-      SRam.start = PicoRead32(0x1B4) & ~1; // zero address is used for clock by some games\r
-      SRam.end   = PicoRead32(0x1B8);\r
+      SRam.start = rom_read32(0x1B4) & ~1; // zero address is used for clock by some games\r
+      SRam.end   = rom_read32(0x1B8);\r
       sram_size  = 0x2000;\r
-      Pico.m.sram_reg |= 4;\r
+      Pico.m.sram_status |= SRS_EEPROM;\r
     } else {\r
       // normal SRAM\r
-      SRam.start = PicoRead32(0x1B4) & ~0xff;\r
-      SRam.end   = PicoRead32(0x1B8) | 1;\r
+      SRam.start = rom_read32(0x1B4) & ~0xff;\r
+      SRam.end   = rom_read32(0x1B8) | 1;\r
       sram_size  = SRam.end - SRam.start + 1;\r
     }\r
     SRam.start &= ~0xff000000;\r
     SRam.end   &= ~0xff000000;\r
-    Pico.m.sram_reg |= 0x10; // SRAM was detected\r
+    Pico.m.sram_status |= SRS_DETECTED;\r
   }\r
   if (sram_size <= 0)\r
   {\r
@@ -713,7 +715,7 @@ static void PicoCartDetect(void)
            name_cmp("RINGS OF POWER") == 0)\r
   {\r
     SRam.start = SRam.end = 0x200000;\r
-    Pico.m.sram_reg = 0x14;\r
+    Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM;\r
     SRam.eeprom_abits = 0;\r
     SRam.eeprom_bit_cl = 6;\r
     SRam.eeprom_bit_in = 7;\r
@@ -725,7 +727,7 @@ static void PicoCartDetect(void)
   {\r
     SRam.start = 0x300000;\r
     SRam.end   = 0x380001;\r
-    Pico.m.sram_reg = 0x14;\r
+    Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM;\r
     SRam.eeprom_type = 2;\r
     SRam.eeprom_abits = 0;\r
     SRam.eeprom_bit_cl = 1;\r
index 88fe882..757d8fb 100644 (file)
@@ -273,11 +273,11 @@ readend:
        if (PicoAHW & PAHW_MCD)
        {
                /* after load events */
-               if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
+               if (Pico_mcd->s68k_regs[3] & 4) // 1M mode?
                        wram_2M_to_1M(Pico_mcd->word_ram2M);
-               PicoMemResetCD(Pico_mcd->s68k_regs[3]);
+               PicoMemRemapCD(Pico_mcd->s68k_regs[3]);
 #ifdef _ASM_CD_MEMORY_C
-               if (Pico_mcd->s68k_regs[3]&4)
+               if (Pico_mcd->s68k_regs[3] & 4)
                        PicoMemResetCDdecode(Pico_mcd->s68k_regs[3]);
 #endif
                if (!(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))
index 8110a2e..a26cac7 100644 (file)
@@ -1,48 +1,29 @@
 // Memory I/O handlers for Sega/Mega CD.\r
-// Loosely based on Gens code.\r
-// (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
-\r
+// (c) Copyright 2007-2009, Grazvydas "notaz" Ignotas\r
 \r
 #include "../pico_int.h"\r
-\r
-#include "../sound/ym2612.h"\r
-#include "../sound/sn76496.h"\r
+#include "../memory.h"\r
 \r
 #include "gfx_cd.h"\r
 #include "pcm.h"\r
 \r
-#ifndef UTYPES_DEFINED\r
-typedef unsigned char  u8;\r
-typedef unsigned short u16;\r
-typedef unsigned int   u32;\r
-#define UTYPES_DEFINED\r
-#endif\r
-\r
-#ifdef _MSC_VER\r
-#define rdprintf\r
-#define wrdprintf\r
-#define r3printf\r
-#else\r
-//#define rdprintf dprintf\r
-#define rdprintf(...)\r
-//#define wrdprintf dprintf\r
-#define wrdprintf(...)\r
-//#define r3printf elprintf\r
-#define r3printf(...)\r
-#endif\r
+unsigned long s68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];\r
+unsigned long s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];\r
+unsigned long s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];\r
+unsigned long s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];\r
 \r
-#ifdef EMU_CORE_DEBUG\r
-extern u32 lastread_a, lastread_d[16], lastwrite_cyc_d[16];\r
-extern int lrp_cyc, lwp_cyc;\r
-#undef USE_POLL_DETECT\r
-#endif\r
+MAKE_68K_READ8(s68k_read8, s68k_read8_map)\r
+MAKE_68K_READ16(s68k_read16, s68k_read16_map)\r
+MAKE_68K_READ32(s68k_read32, s68k_read16_map)\r
+MAKE_68K_WRITE8(s68k_write8, s68k_write8_map)\r
+MAKE_68K_WRITE16(s68k_write16, s68k_write16_map)\r
+MAKE_68K_WRITE32(s68k_write32, s68k_write16_map)\r
 \r
 // -----------------------------------------------------------------\r
 \r
 // poller detection\r
 #define POLL_LIMIT 16\r
 #define POLL_CYCLES 124\r
-// int m68k_poll_addr, m68k_poll_cnt;\r
 unsigned int s68k_poll_adclk, s68k_poll_cnt;\r
 \r
 #ifndef _ASM_CD_MEMORY_C\r
@@ -50,7 +31,6 @@ static u32 m68k_reg_read16(u32 a)
 {\r
   u32 d=0;\r
   a &= 0x3e;\r
-  // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc);\r
 \r
   switch (a) {\r
     case 0:\r
@@ -58,7 +38,7 @@ static u32 m68k_reg_read16(u32 a)
       goto end;\r
     case 2:\r
       d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
-      r3printf(EL_STATUS, "m68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
+      elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
       goto end;\r
     case 4:\r
       d = Pico_mcd->s68k_regs[4]<<8;\r
@@ -74,7 +54,7 @@ static u32 m68k_reg_read16(u32 a)
       goto end;\r
     case 0xC:\r
       d = Pico_mcd->m.timer_stopwatch >> 16;\r
-      dprintf("m68k stopwatch timer read (%04x)", d);\r
+      elprintf(EL_CDREGS, "m68k stopwatch timer read (%04x)", d);\r
       goto end;\r
   }\r
 \r
@@ -97,8 +77,8 @@ static
 #endif\r
 void m68k_reg_write8(u32 a, u32 d)\r
 {\r
+  u32 dold;\r
   a &= 0x3f;\r
-  // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc);\r
 \r
   switch (a) {\r
     case 0:\r
@@ -113,20 +93,21 @@ void m68k_reg_write8(u32 a, u32 d)
       if ((Pico_mcd->m.state_flags&1) && (d&3)==1) {\r
         SekResetS68k(); // S68k comes out of RESET or BRQ state\r
         Pico_mcd->m.state_flags&=~1;\r
-        dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
+        elprintf(EL_CDREGS, "m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
       }\r
+      if (!(d & 1))\r
+        d |= 2; // verified: reset also gives bus\r
+      if ((d ^ Pico_mcd->m.busreq) & 2)\r
+        PicoMemRemapCD(Pico_mcd->s68k_regs[3]);\r
       Pico_mcd->m.busreq = d;\r
       return;\r
     case 2:\r
-      dprintf("m68k: prg wp=%02x", d);\r
+      elprintf(EL_CDREGS, "m68k: prg wp=%02x", d);\r
       Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
       return;\r
-    case 3: {\r
-      u32 dold = Pico_mcd->s68k_regs[3]&0x1f;\r
-      r3printf(EL_STATUS, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
-      d &= 0xc2;\r
-      if ((dold>>6) != ((d>>6)&3))\r
-        dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
+    case 3:\r
+      dold = Pico_mcd->s68k_regs[3];\r
+      elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
       //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2);\r
       //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") :\r
       //                                             ((d&2) ? "word ram to s68k" : "word ram to m68k"));\r
@@ -139,7 +120,11 @@ void m68k_reg_write8(u32 a, u32 d)
           SekEndRun(20+16+10+12+16);\r
         }\r
       }\r
-      Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register\r
+      Pico_mcd->s68k_regs[3] = (d & 0xc2) | (dold & 0x1f);\r
+      if ((d ^ dold) & 0xc0) {\r
+        elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
+        PicoMemRemapCD(Pico_mcd->s68k_regs[3]);\r
+      }\r
 #ifdef USE_POLL_DETECT\r
       if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {\r
         SekSetStopS68k(0); s68k_poll_adclk = 0;\r
@@ -147,13 +132,13 @@ void m68k_reg_write8(u32 a, u32 d)
       }\r
 #endif\r
       return;\r
-    }\r
     case 6:\r
       Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
       return;\r
     case 7:\r
       Pico_mcd->bios[0x72] = d;\r
-      dprintf("hint vector set to %08x", PicoRead32(0x70));\r
+      elprintf(EL_CDREGS, "hint vector set to %04x%04x",\r
+        ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);\r
       return;\r
     case 0xf:\r
       d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
@@ -229,14 +214,12 @@ u32 s68k_reg_read16(u32 a)
 {\r
   u32 d=0;\r
 \r
-  // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k);\r
-\r
   switch (a) {\r
     case 0:\r
       return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
     case 2:\r
       d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);\r
-      r3printf(EL_STATUS, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
+      elprintf(EL_CDREG3, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
       return s68k_poll_detect(a, d);\r
     case 6:\r
       return CDC_Read_Reg();\r
@@ -244,10 +227,10 @@ u32 s68k_reg_read16(u32 a)
       return Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
     case 0xC:\r
       d = Pico_mcd->m.timer_stopwatch >> 16;\r
-      dprintf("s68k stopwatch timer read (%04x)", d);\r
+      elprintf(EL_CDREGS, "s68k stopwatch timer read (%04x)", d);\r
       return d;\r
     case 0x30:\r
-      dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
+      elprintf(EL_CDREGS, "s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
       return Pico_mcd->s68k_regs[31];\r
     case 0x34: // fader\r
       return 0; // no busy bit\r
@@ -278,42 +261,40 @@ static
 #endif\r
 void s68k_reg_write8(u32 a, u32 d)\r
 {\r
-  //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k);\r
-\r
   // Warning: d might have upper bits set\r
   switch (a) {\r
     case 2:\r
       return; // only m68k can change WP\r
     case 3: {\r
       int dold = Pico_mcd->s68k_regs[3];\r
-      r3printf(EL_STATUS, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);\r
+      elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);\r
       d &= 0x1d;\r
-      d |= dold&0xc2;\r
-      if (d&4)\r
+      d |= dold & 0xc2;\r
+      if (d & 4)\r
       {\r
         if ((d ^ dold) & 5) {\r
           d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
-          PicoMemResetCD(d);\r
+          PicoMemRemapCD(d);\r
         }\r
 #ifdef _ASM_CD_MEMORY_C\r
         if ((d ^ dold) & 0x1d)\r
           PicoMemResetCDdecode(d);\r
 #endif\r
         if (!(dold & 4)) {\r
-          r3printf(EL_STATUS, "wram mode 2M->1M");\r
+          elprintf(EL_CDREG3, "wram mode 2M->1M");\r
           wram_2M_to_1M(Pico_mcd->word_ram2M);\r
         }\r
       }\r
       else\r
       {\r
         if (dold & 4) {\r
-          r3printf(EL_STATUS, "wram mode 1M->2M");\r
+          elprintf(EL_CDREG3, "wram mode 1M->2M");\r
           if (!(d&1)) { // it didn't set the ret bit, which means it doesn't want to give WRAM to m68k\r
             d &= ~3;\r
             d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode\r
           }\r
           wram_1M_to_2M(Pico_mcd->word_ram2M);\r
-          PicoMemResetCD(d);\r
+          PicoMemRemapCD(d);\r
         }\r
         // s68k can only set RET, writing 0 has no effect\r
         else if ((dold ^ d) & d & 1) {   // RET being set\r
@@ -326,7 +307,7 @@ void s68k_reg_write8(u32 a, u32 d)
       break;\r
     }\r
     case 4:\r
-      dprintf("s68k CDC dest: %x", d&7);\r
+      elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7);\r
       Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode\r
       return;\r
     case 5:\r
@@ -336,22 +317,22 @@ void s68k_reg_write8(u32 a, u32 d)
       CDC_Write_Reg(d);\r
       return;\r
     case 0xa:\r
-      dprintf("s68k set CDC dma addr");\r
+      elprintf(EL_CDREGS, "s68k set CDC dma addr");\r
       break;\r
     case 0xc:\r
     case 0xd:\r
-      dprintf("s68k set stopwatch timer");\r
+      elprintf(EL_CDREGS, "s68k set stopwatch timer");\r
       Pico_mcd->m.timer_stopwatch = 0;\r
       return;\r
     case 0xe:\r
       Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
       return;\r
     case 0x31:\r
-      dprintf("s68k set int3 timer: %02x", d);\r
+      elprintf(EL_CDREGS, "s68k set int3 timer: %02x", d);\r
       Pico_mcd->m.timer_int3 = (d & 0xff) << 16;\r
       break;\r
     case 0x33: // IRQ mask\r
-      dprintf("s68k irq mask: %02x", d);\r
+      elprintf(EL_CDREGS, "s68k irq mask: %02x", d);\r
       if ((d&(1<<4)) && (Pico_mcd->s68k_regs[0x37]&4) && !(Pico_mcd->s68k_regs[0x33]&(1<<4))) {\r
         CDD_Export_Status();\r
       }\r
@@ -384,438 +365,141 @@ void s68k_reg_write8(u32 a, u32 d)
   Pico_mcd->s68k_regs[a] = (u8) d;\r
 }\r
 \r
+// -----------------------------------------------------------------\r
+//                          Main 68k\r
+// -----------------------------------------------------------------\r
+\r
+#ifndef _ASM_CD_MEMORY_C\r
+#include "cell_map.c"\r
+#endif\r
 \r
-static u32 OtherRead16End(u32 a, int realsize)\r
+// WORD RAM, cell aranged area (220000 - 23ffff)\r
+static u32 PicoReadM68k8_cell(u32 a)\r
 {\r
-  u32 d=0;\r
+  int bank = Pico_mcd->s68k_regs[3] & 1;\r
+  a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
+  return Pico_mcd->word_ram1M[bank][a ^ 1];\r
+}\r
 \r
-#ifndef _ASM_CD_MEMORY_C\r
-  if ((a&0xffffc0)==0xa12000) {\r
-    d=m68k_reg_read16(a);\r
-    goto end;\r
-  }\r
+static u32 PicoReadM68k16_cell(u32 a)\r
+{\r
+  int bank = Pico_mcd->s68k_regs[3] & 1;\r
+  a = (a&2) | (cell_map(a >> 2) << 2);\r
+  return *(u16 *)(Pico_mcd->word_ram1M[bank] + a);\r
+}\r
 \r
-  if (a==0x400000) {\r
-    if (SRam.data != NULL) d=3; // 64k cart\r
-    goto end;\r
-  }\r
+static void PicoWriteM68k8_cell(u32 a, u32 d)\r
+{\r
+  int bank = Pico_mcd->s68k_regs[3] & 1;\r
+  a = (a&3) | (cell_map(a >> 2) << 2);\r
+  Pico_mcd->word_ram1M[bank][a ^ 1] = d;\r
+}\r
 \r
-  if ((a&0xfe0000)==0x600000) {\r
-    if (SRam.data != NULL) {\r
-      d=SRam.data[((a>>1)&0xffff)+0x2000];\r
-      if (realsize == 8) d|=d<<8;\r
-    }\r
-    goto end;\r
+static void PicoWriteM68k16_cell(u32 a, u32 d)\r
+{\r
+  int bank = Pico_mcd->s68k_regs[3] & 1;\r
+  a = (a&3) | (cell_map(a >> 2) << 2);\r
+  *(u16 *)(Pico_mcd->word_ram1M[bank] + a) = d;\r
+}\r
+\r
+// RAM cart (40000 - 7fffff, optional)\r
+static u32 PicoReadM68k8_ramc(u32 a)\r
+{\r
+  u32 d = 0;\r
+  if (a == 0x400001) {\r
+    if (SRam.data != NULL)\r
+      d = 3; // 64k cart\r
+    return d;\r
   }\r
 \r
-  if (a==0x7ffffe) {\r
-    d=Pico_mcd->m.bcram_reg;\r
-    goto end;\r
+  if ((a & 0xfe0000) == 0x600000) {\r
+    if (SRam.data != NULL)\r
+      d = SRam.data[((a >> 1) & 0xffff) + 0x2000];\r
+    return d;\r
   }\r
-#endif\r
 \r
-  elprintf(EL_UIO, "m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
+  if (a == 0x7fffff)\r
+    return Pico_mcd->m.bcram_reg;\r
 \r
-#ifndef _ASM_CD_MEMORY_C\r
-end:\r
-#endif\r
+  elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);\r
   return d;\r
 }\r
 \r
-\r
-static void OtherWrite8End(u32 a, u32 d, int realsize)\r
+static u32 PicoReadM68k16_ramc(u32 a)\r
 {\r
-#ifndef _ASM_CD_MEMORY_C\r
-  if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
+  elprintf(EL_ANOMALY, "ramcart r16: [%06x] @%06x", a, SekPcS68k);\r
+  return PicoReadM68k8_ramc(a + 1);\r
+}\r
 \r
-  if ((a&0xfe0000)==0x600000) {\r
-    if (SRam.data != NULL && (Pico_mcd->m.bcram_reg&1)) {\r
-      SRam.data[((a>>1)&0xffff)+0x2000]=d;\r
+static void PicoWriteM68k8_ramc(u32 a, u32 d)\r
+{\r
+  if ((a & 0xfe0000) == 0x600000) {\r
+    if (SRam.data != NULL && (Pico_mcd->m.bcram_reg & 1)) {\r
+      SRam.data[((a>>1) & 0xffff) + 0x2000] = d;\r
       SRam.changed = 1;\r
     }\r
     return;\r
   }\r
 \r
-  if (a==0x7fffff) {\r
-    Pico_mcd->m.bcram_reg=d;\r
+  if (a == 0x7fffff) {\r
+    Pico_mcd->m.bcram_reg = d;\r
     return;\r
   }\r
-#endif\r
 \r
-  elprintf(EL_UIO, "m68k FIXME: strange w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
+  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);\r
 }\r
 \r
-#ifndef _ASM_CD_MEMORY_C\r
-#define _CD_MEMORY_C\r
-#undef _ASM_MEMORY_C\r
-#include "../memory_cmn.c"\r
-#include "cell_map.c"\r
-#endif\r
-\r
-\r
-// -----------------------------------------------------------------\r
-//                     Read Rom and read Ram\r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-u32 PicoReadM68k8(u32 a);\r
-#else\r
-u32 PicoReadM68k8(u32 a)\r
+static void PicoWriteM68k16_ramc(u32 a, u32 d)\r
 {\r
-  u32 d=0;\r
-\r
-  a&=0xffffff;\r
-\r
-  switch (a >> 17)\r
-  {\r
-    case 0x00>>1: // BIOS: 000000 - 020000\r
-      d = *(u8 *)(Pico_mcd->bios+(a^1));\r
-      break;\r
-    case 0x02>>1: // prg RAM\r
-      if ((Pico_mcd->m.busreq&3)!=1) {\r
-        u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-        d = *(prg_bank+((a^1)&0x1ffff));\r
-      }\r
-      break;\r
-    case 0x20>>1: // word RAM: 200000 - 220000\r
-      wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
-      a &= 0x1ffff;\r
-      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-        int bank = Pico_mcd->s68k_regs[3]&1;\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_ram2M[a^1];\r
-      }\r
-      wrdprintf("ret = %02x", (u8)d);\r
-      break;\r
-    case 0x22>>1: // word RAM: 220000 - 240000\r
-      wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
-      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-        int bank = Pico_mcd->s68k_regs[3]&1;\r
-        a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\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_ram2M[(a^1)&0x3ffff];\r
-      }\r
-      wrdprintf("ret = %02x", (u8)d);\r
-      break;\r
-    case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
-    case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
-    case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
-    case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
-      // VDP\r
-      if ((a&0xe700e0)==0xc00000)\r
-        d=PicoVideoRead8(a);\r
-      break;\r
-    case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
-    case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
-    case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
-    case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:\r
-      // RAM:\r
-      d = *(u8 *)(Pico.ram+((a^1)&0xffff));\r
-      break;\r
-    default:\r
-      if ((a&0xff4000)==0xa00000) { d=z80Read8(a); break; } // Z80 Ram\r
-      if ((a&0xffffc0)==0xa12000)\r
-        rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
-      d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
-\r
-      if ((a&0xffffc0)==0xa12000)\r
-        rdprintf("ret = %02x", (u8)d);\r
-      break;\r
-  }\r
-\r
-\r
-  elprintf(EL_IO, "r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (a>=Pico.romsize) {\r
-    lastread_a = a;\r
-    lastread_d[lrp_cyc++&15] = d;\r
-  }\r
-#endif\r
-  return d;\r
+  elprintf(EL_ANOMALY, "ramcart w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
+  PicoWriteM68k8_ramc(a + 1, d);\r
 }\r
-#endif\r
-\r
 \r
-#ifdef _ASM_CD_MEMORY_C\r
-u32 PicoReadM68k16(u32 a);\r
-#else\r
-static u32 PicoReadM68k16(u32 a)\r
+// IO/control/cd registers (a10000 - ...)\r
+static u32 PicoReadM68k8_io(u32 a)\r
 {\r
-  u32 d=0;\r
-\r
-  a&=0xfffffe;\r
-\r
-  switch (a >> 17)\r
-  {\r
-    case 0x00>>1: // BIOS: 000000 - 020000\r
-      d = *(u16 *)(Pico_mcd->bios+a);\r
-      break;\r
-    case 0x02>>1: // prg RAM\r
-      if ((Pico_mcd->m.busreq&3)!=1) {\r
-        u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-        wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
-        d = *(u16 *)(prg_bank+(a&0x1fffe));\r
-        wrdprintf("ret = %04x", d);\r
-      }\r
-      break;\r
-    case 0x20>>1: // word RAM: 200000 - 220000\r
-      wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
-      a &= 0x1fffe;\r
-      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-        int bank = Pico_mcd->s68k_regs[3]&1;\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_ram2M+a);\r
-      }\r
-      wrdprintf("ret = %04x", d);\r
-      break;\r
-    case 0x22>>1: // word RAM: 220000 - 240000\r
-      wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
-      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-        int bank = Pico_mcd->s68k_regs[3]&1;\r
-        a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\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_ram2M+(a&0x3fffe));\r
-      }\r
-      wrdprintf("ret = %04x", d);\r
-      break;\r
-    case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
-    case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
-    case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
-    case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
-      // VDP\r
-      if ((a&0xe700e0)==0xc00000)\r
-        d=PicoVideoRead(a);\r
-      break;\r
-    case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
-    case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
-    case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
-    case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:\r
-      // RAM:\r
-      d=*(u16 *)(Pico.ram+(a&0xfffe));\r
-      break;\r
-    default:\r
-      if ((a&0xffffc0)==0xa12000)\r
-        rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
-      d = OtherRead16(a, 16);\r
-\r
-      if ((a&0xffffc0)==0xa12000)\r
-        rdprintf("ret = %04x", d);\r
-      break;\r
-  }\r
-\r
-\r
-  elprintf(EL_IO, "r16: %06x, %04x  @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (a>=Pico.romsize) {\r
-    lastread_a = a;\r
-    lastread_d[lrp_cyc++&15] = d;\r
-  }\r
-#endif\r
-  return d;\r
+  u32 d;\r
+  if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
+    d = m68k_reg_read16(a); // TODO: m68k_reg_read8\r
+    if (!(a & 1))\r
+      d >>= 8;\r
+    d &= 0xff;\r
+    elprintf(EL_CDREGS, "m68k_regs r8:  [%02x]   %02x @%06x", a & 0x3f, d, SekPc);\r
+    return d;\r
+  }\r
+\r
+  // fallback to default MD handler\r
+  return PicoRead8_io(a);\r
 }\r
-#endif\r
 \r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-u32 PicoReadM68k32(u32 a);\r
-#else\r
-static u32 PicoReadM68k32(u32 a)\r
+static u32 PicoReadM68k16_io(u32 a)\r
 {\r
-  u32 d=0;\r
-\r
-  a&=0xfffffe;\r
-\r
-  switch (a >> 17)\r
-  {\r
-    case 0x00>>1: { // BIOS: 000000 - 020000\r
-      u16 *pm=(u16 *)(Pico_mcd->bios+a);\r
-      d = (pm[0]<<16)|pm[1];\r
-      break;\r
-    }\r
-    case 0x02>>1: // prg RAM\r
-      if ((Pico_mcd->m.busreq&3)!=1) {\r
-        u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-        u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
-        d = (pm[0]<<16)|pm[1];\r
-      }\r
-      break;\r
-    case 0x20>>1: // word RAM: 200000 - 220000\r
-      wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
-      a&=0x1fffe;\r
-      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-        int bank = Pico_mcd->s68k_regs[3]&1;\r
-        u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
-       d = (pm[0]<<16)|pm[1];\r
-      } else {\r
-        // allow access in any mode, like Gens does\r
-        u16 *pm=(u16 *)(Pico_mcd->word_ram2M+a);\r
-       d = (pm[0]<<16)|pm[1];\r
-      }\r
-      wrdprintf("ret = %08x", d);\r
-      break;\r
-    case 0x22>>1: // word RAM: 220000 - 240000\r
-      wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
-      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode, cell arranged?\r
-        u32 a1, a2;\r
-        int bank = Pico_mcd->s68k_regs[3]&1;\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
-        // allow access in any mode, like Gens does\r
-        u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
-       d = (pm[0]<<16)|pm[1];\r
-      }\r
-      wrdprintf("ret = %08x", d);\r
-      break;\r
-    case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
-    case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
-    case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
-    case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
-      // VDP\r
-      d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);\r
-      break;\r
-    case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
-    case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
-    case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
-    case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: {\r
-      // RAM:\r
-      u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
-      d = (pm[0]<<16)|pm[1];\r
-      break;\r
-    }\r
-    default:\r
-      if ((a&0xffffc0)==0xa12000)\r
-        rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
-      d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
-\r
-      if ((a&0xffffc0)==0xa12000)\r
-        rdprintf("ret = %08x", d);\r
-      break;\r
+  u32 d;\r
+  if ((a & 0xff00) == 0x2000) {\r
+    d = m68k_reg_read16(a);\r
+    elprintf(EL_CDREGS, "m68k_regs r16: [%02x] %04x @%06x", a & 0x3f, d, SekPc);\r
+    return d;\r
   }\r
 \r
-\r
-  elprintf(EL_IO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (a>=Pico.romsize) {\r
-    lastread_a = a;\r
-    lastread_d[lrp_cyc++&15] = d;\r
-  }\r
-#endif\r
-  return d;\r
+  return PicoRead16_io(a);\r
 }\r
-#endif\r
-\r
 \r
-// -----------------------------------------------------------------\r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-void PicoWriteM68k8(u32 a,u8 d);\r
-#else\r
-void PicoWriteM68k8(u32 a,u8 d)\r
+static void PicoWriteM68k8_io(u32 a, u32 d)\r
 {\r
-  elprintf(EL_IO, "w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  if ((a&0xe00000)==0xe00000) { // Ram\r
-    *(u8 *)(Pico.ram+((a^1)&0xffff)) = d;\r
-    return;\r
-  }\r
-\r
-  // prg RAM\r
-  if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
-    u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-    *(u8 *)(prg_bank+((a^1)&0x1ffff))=d;\r
-    return;\r
-  }\r
-\r
-  a&=0xffffff;\r
-\r
-  // word RAM\r
-  if ((a&0xfc0000)==0x200000) {\r
-    wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\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_ram2M+((a^1)&0x3ffff))=d;\r
-    }\r
-    return;\r
-  }\r
-\r
-  if ((a&0xffffc0)==0xa12000) {\r
-    rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
+  if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
+    elprintf(EL_CDREGS, "m68k_regs w8:  [%02x]   %02x @%06x", a&0x3f, d, SekPc);\r
     m68k_reg_write8(a, d);\r
     return;\r
   }\r
 \r
-  OtherWrite8(a,d);\r
+  PicoWrite16_io(a, d);\r
 }\r
-#endif\r
 \r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-void PicoWriteM68k16(u32 a,u16 d);\r
-#else\r
-static void PicoWriteM68k16(u32 a,u16 d)\r
+static void PicoWriteM68k16_io(u32 a, u32 d)\r
 {\r
-  elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  if ((a&0xe00000)==0xe00000) { // Ram\r
-    *(u16 *)(Pico.ram+(a&0xfffe))=d;\r
-    return;\r
-  }\r
-\r
-  // prg RAM\r
-  if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
-    u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-    wrdprintf("m68k_prgram w16: [%i,%06x] %04x @%06x", Pico_mcd->s68k_regs[3]>>6, a, d, SekPc);\r
-    *(u16 *)(prg_bank+(a&0x1fffe))=d;\r
-    return;\r
-  }\r
-\r
-  a&=0xfffffe;\r
-\r
-  // word RAM\r
-  if ((a&0xfc0000)==0x200000) {\r
-    wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\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_ram2M+(a&0x3fffe))=d;\r
-    }\r
-    return;\r
-  }\r
-\r
-  // regs\r
-  if ((a&0xffffc0)==0xa12000) {\r
-    rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
+  if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
+    elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
+/* TODO FIXME?\r
     if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
       Pico_mcd->s68k_regs[0xe] = d >> 8;\r
 #ifdef USE_POLL_DETECT\r
@@ -826,434 +510,95 @@ static void PicoWriteM68k16(u32 a,u16 d)
 #endif\r
       return;\r
     }\r
-    m68k_reg_write8(a,  d>>8);\r
-    m68k_reg_write8(a+1,d&0xff);\r
-    return;\r
-  }\r
-\r
-  // VDP\r
-  if ((a&0xe700e0)==0xc00000) {\r
-    PicoVideoWrite(a,(u16)d);\r
-    return;\r
-  }\r
-\r
-  OtherWrite16(a,d);\r
-}\r
-#endif\r
-\r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-void PicoWriteM68k32(u32 a,u32 d);\r
-#else\r
-static void PicoWriteM68k32(u32 a,u32 d)\r
-{\r
-  elprintf(EL_IO, "w32: %06x, %08x", a&0xffffff, d);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  if ((a&0xe00000)==0xe00000)\r
-  {\r
-    // Ram:\r
-    u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
-    pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
-    return;\r
-  }\r
-\r
-  // prg RAM\r
-  if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
-    u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-    u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
-    pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
-    return;\r
-  }\r
-\r
-  a&=0xfffffe;\r
-\r
-  // word RAM\r
-  if ((a&0xfc0000)==0x200000) {\r
-    if (d != 0) // don't log clears\r
-      wrdprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\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
-        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_ram2M+(a&0x3fffe));\r
-      pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
-    }\r
+*/\r
+    m68k_reg_write8(a,     d >> 8);\r
+    m68k_reg_write8(a + 1, d & 0xff);\r
     return;\r
   }\r
 \r
-  if ((a&0xffffc0)==0xa12000) {\r
-    rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
-    if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);\r
-  }\r
-\r
-  // VDP\r
-  if ((a&0xe700e0)==0xc00000)\r
-  {\r
-    PicoVideoWrite(a,  (u16)(d>>16));\r
-    PicoVideoWrite(a+2,(u16)d);\r
-    return;\r
-  }\r
-\r
-  OtherWrite16(a,  (u16)(d>>16));\r
-  OtherWrite16(a+2,(u16)d);\r
+  PicoWrite16_io(a, d);\r
 }\r
-#endif\r
-\r
 \r
 // -----------------------------------------------------------------\r
-//                            S68k\r
+//                           Sub 68k\r
 // -----------------------------------------------------------------\r
 \r
-#ifdef _ASM_CD_MEMORY_C\r
-u32 PicoReadS68k8(u32 a);\r
-#else\r
-static u32 PicoReadS68k8(u32 a)\r
+static u32 s68k_unmapped_read8(u32 a)\r
 {\r
-  u32 d=0;\r
-\r
-#ifdef EMU_CORE_DEBUG\r
-  u32 ab=a&0xfffffe;\r
-#endif\r
-  a&=0xffffff;\r
-\r
-  // prg RAM\r
-  if (a < 0x80000) {\r
-    d = *(Pico_mcd->prg_ram+(a^1));\r
-    goto end;\r
-  }\r
-\r
-  // regs\r
-  if ((a&0xfffe00) == 0xff8000) {\r
-    a &= 0x1ff;\r
-    rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
-    if (a >= 0x0e && a < 0x30) {\r
-      d = Pico_mcd->s68k_regs[a];\r
-      s68k_poll_detect(a, d);\r
-      rdprintf("ret = %02x", (u8)d);\r
-      goto end;\r
-    }\r
-    else if (a >= 0x58 && a < 0x68)\r
-         d = gfx_cd_read(a&~1);\r
-    else d = s68k_reg_read16(a&~1);\r
-    if ((a&1)==0) d>>=8;\r
-    rdprintf("ret = %02x", (u8)d);\r
-    goto end;\r
-  }\r
-\r
-  // word RAM (2M area)\r
-  if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
-    // test: batman returns\r
-    wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
-      int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-      d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
-      if (a&1) d &= 0x0f;\r
-      else d >>= 4;\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
-    }\r
-    wrdprintf("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
-    int bank;\r
-    wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);\r
-//    if (!(Pico_mcd->s68k_regs[3]&4))\r
-//      dprintf("s68k_wram1M FIXME: wrong mode");\r
-    bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-    d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];\r
-    wrdprintf("ret = %02x", (u8)d);\r
-    goto end;\r
-  }\r
-\r
-  // PCM\r
-  if ((a&0xff8000)==0xff0000) {\r
-    elprintf(EL_IO, "s68k_pcm r8: [%06x] @%06x", a, SekPcS68k);\r
-    a &= 0x7fff;\r
-    if (a >= 0x2000)\r
-      d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
-    else if (a >= 0x20) {\r
-      a &= 0x1e;\r
-      d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
-      if (a & 2) d >>= 8;\r
-    }\r
-    elprintf(EL_IO, "ret = %02x", (u8)d);\r
-    goto end;\r
-  }\r
-\r
-  // bram\r
-  if ((a&0xff0000)==0xfe0000) {\r
-    d = Pico_mcd->bram[(a>>1)&0x1fff];\r
-    goto end;\r
-  }\r
-\r
-  elprintf(EL_UIO, "s68k r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
-\r
-  end:\r
-\r
-  elprintf(EL_IO, "s68k r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastread_a = ab;\r
-  lastread_d[lrp_cyc++&15] = d;\r
-#endif\r
-  return d;\r
+  elprintf(EL_UIO, "s68k unmapped r8  [%06x] @%06x", a, SekPc);\r
+  return 0;\r
 }\r
-#endif\r
-\r
 \r
-#ifdef _ASM_CD_MEMORY_C\r
-u32 PicoReadS68k16(u32 a);\r
-#else\r
-static u32 PicoReadS68k16(u32 a)\r
+static u32 s68k_unmapped_read16(u32 a)\r
 {\r
-  u32 d=0;\r
-\r
-#ifdef EMU_CORE_DEBUG\r
-  u32 ab=a&0xfffffe;\r
-#endif\r
-  a&=0xfffffe;\r
-\r
-  // prg RAM\r
-  if (a < 0x80000) {\r
-    wrdprintf("s68k_prgram r16: [%06x] @%06x", a, SekPcS68k);\r
-    d = *(u16 *)(Pico_mcd->prg_ram+a);\r
-    wrdprintf("ret = %04x", d);\r
-    goto end;\r
-  }\r
-\r
-  // regs\r
-  if ((a&0xfffe00) == 0xff8000) {\r
-    a &= 0x1fe;\r
-    rdprintf("s68k_regs r16: [%02x] @ %06x", a, SekPcS68k);\r
-    if (a >= 0x58 && a < 0x68)\r
-         d = gfx_cd_read(a);\r
-    else d = s68k_reg_read16(a);\r
-    rdprintf("ret = %04x", d);\r
-    goto end;\r
-  }\r
-\r
-  // word RAM (2M area)\r
-  if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
-    wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
-      int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-      d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
-      d |= d << 4; d &= ~0xf0;\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
-    }\r
-    wrdprintf("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
-    int bank;\r
-    wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);\r
-//    if (!(Pico_mcd->s68k_regs[3]&4))\r
-//      dprintf("s68k_wram1M FIXME: wrong mode");\r
-    bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-    d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
-    wrdprintf("ret = %04x", d);\r
-    goto end;\r
-  }\r
-\r
-  // bram\r
-  if ((a&0xff0000)==0xfe0000) {\r
-    dprintf("FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
-    a = (a>>1)&0x1fff;\r
-    d = Pico_mcd->bram[a++];           // Gens does little endian here, and so do we..\r
-    d|= Pico_mcd->bram[a++] << 8;      // This is most likely wrong\r
-    dprintf("ret = %04x", d);\r
-    goto end;\r
-  }\r
-\r
-  // PCM\r
-  if ((a&0xff8000)==0xff0000) {\r
-    dprintf("FIXME: s68k_pcm r16: [%06x] @%06x", a, SekPcS68k);\r
-    a &= 0x7fff;\r
-    if (a >= 0x2000)\r
-      d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
-    else if (a >= 0x20) {\r
-      a &= 0x1e;\r
-      d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
-      if (a & 2) d >>= 8;\r
-    }\r
-    dprintf("ret = %04x", d);\r
-    goto end;\r
-  }\r
+  elprintf(EL_UIO, "s68k unmapped r16 [%06x] @%06x", a, SekPc);\r
+  return 0;\r
+}\r
 \r
-  elprintf(EL_UIO, "s68k r16: %06x, %04x  @%06x", a&0xffffff, d, SekPcS68k);\r
+static void s68k_unmapped_write8(u32 a, u32 d)\r
+{\r
+  elprintf(EL_UIO, "s68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);\r
+}\r
 \r
-  end:\r
+static void s68k_unmapped_write16(u32 a, u32 d)\r
+{\r
+  elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);\r
+}\r
 \r
-  elprintf(EL_IO, "s68k r16: %06x, %04x  @%06x", a&0xffffff, d, SekPcS68k);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastread_a = ab;\r
-  lastread_d[lrp_cyc++&15] = d;\r
-#endif\r
+// decode (080000 - 0bffff, in 1M mode)\r
+static u32 PicoReadS68k8_dec(u32 a)\r
+{\r
+  u32 d, bank;\r
+  bank = (Pico_mcd->s68k_regs[3] & 1) ^ 1;\r
+  d = Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff];\r
+  if (a & 1)\r
+    d &= 0x0f;\r
+  else\r
+    d >>= 4;\r
   return d;\r
 }\r
-#endif\r
-\r
 \r
-#ifdef _ASM_CD_MEMORY_C\r
-u32 PicoReadS68k32(u32 a);\r
-#else\r
-static u32 PicoReadS68k32(u32 a)\r
+static u32 PicoReadS68k16_dec(u32 a)\r
 {\r
-  u32 d=0;\r
-\r
-#ifdef EMU_CORE_DEBUG\r
-  u32 ab=a&0xfffffe;\r
-#endif\r
-  a&=0xfffffe;\r
-\r
-  // prg RAM\r
-  if (a < 0x80000) {\r
-    u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
-    d = (pm[0]<<16)|pm[1];\r
-    goto end;\r
-  }\r
-\r
-  // regs\r
-  if ((a&0xfffe00) == 0xff8000) {\r
-    a &= 0x1fe;\r
-    rdprintf("s68k_regs r32: [%02x] @ %06x", a, SekPcS68k);\r
-    if (a >= 0x58 && a < 0x68)\r
-         d = (gfx_cd_read(a)<<16)|gfx_cd_read(a+2);\r
-    else d = (s68k_reg_read16(a)<<16)|s68k_reg_read16(a+2);\r
-    rdprintf("ret = %08x", d);\r
-    goto end;\r
-  }\r
-\r
-  // word RAM (2M area)\r
-  if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
-    wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
-      int bank = (Pico_mcd->s68k_regs[3]&1)^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
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
-    }\r
-    wrdprintf("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
-    int bank;\r
-    u16 *pm;\r
-    wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);\r
-//    if (!(Pico_mcd->s68k_regs[3]&4))\r
-//      dprintf("s68k_wram1M FIXME: wrong mode");\r
-    bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-    pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
-    wrdprintf("ret = %08x", d);\r
-    goto end;\r
-  }\r
-\r
-  // PCM\r
-  if ((a&0xff8000)==0xff0000) {\r
-    dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
-    a &= 0x7fff;\r
-    if (a >= 0x2000) {\r
-      a >>= 1;\r
-      d  = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] << 16;\r
-      d |= Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff];\r
-    } else if (a >= 0x20) {\r
-      a &= 0x1e;\r
-      if (a & 2) {\r
-        a >>= 2;\r
-        d  = (Pico_mcd->pcm.ch[a].addr >> (PCM_STEP_SHIFT-8)) & 0xff0000;\r
-        d |= (Pico_mcd->pcm.ch[(a+1)&7].addr >> PCM_STEP_SHIFT)   & 0xff;\r
-      } else {\r
-        d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
-        d = ((d<<16)&0xff0000) | ((d>>8)&0xff); // PCM chip is LE\r
-      }\r
-    }\r
-    dprintf("ret = %08x", d);\r
-    goto end;\r
-  }\r
-\r
-  // bram\r
-  if ((a&0xff0000)==0xfe0000) {\r
-    dprintf("FIXME: s68k_bram r32: [%06x] @%06x", a, SekPcS68k);\r
-    a = (a>>1)&0x1fff;\r
-    d = Pico_mcd->bram[a++] << 16;             // middle endian? TODO: verify against Fusion..\r
-    d|= Pico_mcd->bram[a++] << 24;\r
-    d|= Pico_mcd->bram[a++];\r
-    d|= Pico_mcd->bram[a++] << 8;\r
-    dprintf("ret = %08x", d);\r
-    goto end;\r
-  }\r
-\r
-  elprintf(EL_UIO, "s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
-\r
-  end:\r
-\r
-  elprintf(EL_IO, "s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (ab > 0x78) { // not vectors and stuff\r
-    lastread_a = ab;\r
-    lastread_d[lrp_cyc++&15] = d;\r
-  }\r
-#endif\r
+  u32 d, bank;\r
+  bank = (Pico_mcd->s68k_regs[3] & 1) ^ 1;\r
+  d = Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff];\r
+  d |= d << 4;\r
+  d &= ~0xf0;\r
   return d;\r
 }\r
-#endif\r
 \r
-\r
-#ifndef _ASM_CD_MEMORY_C\r
 /* check: jaguar xj 220 (draws entire world using decode) */\r
-static void decode_write8(u32 a, u8 d, int r3)\r
+static void PicoWriteS68k8_dec(u32 a, u32 d)\r
 {\r
-  u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff);\r
-  u8 oldmask = (a&1) ? 0xf0 : 0x0f;\r
+  u8 r3 = Pico_mcd->s68k_regs[3];\r
+  u8 *pd = &Pico_mcd->word_ram1M[(r3 & 1) ^ 1][((a >> 1) ^ 1) & 0x1ffff];\r
+  u8 oldmask = (a & 1) ? 0xf0 : 0x0f;\r
 \r
   r3 &= 0x18;\r
   d  &= 0x0f;\r
-  if (!(a&1)) d <<= 4;\r
+  if (!(a & 1))\r
+    d <<= 4;\r
 \r
   if (r3 == 8) {\r
-    if ((!(*pd & (~oldmask))) && d) goto do_it;\r
+    if ((!(*pd & (~oldmask))) && d)\r
+      goto do_it;\r
   } else if (r3 > 8) {\r
-    if (d) goto do_it;\r
-  } else {\r
+    if (d)\r
+      goto do_it;\r
+  } else\r
     goto do_it;\r
-  }\r
 \r
   return;\r
+\r
 do_it:\r
   *pd = d | (*pd & oldmask);\r
 }\r
 \r
-\r
-static void decode_write16(u32 a, u16 d, int r3)\r
+static void PicoWriteS68k16_dec(u32 a, u32 d)\r
 {\r
-  u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff);\r
+  u8 r3 = Pico_mcd->s68k_regs[3];\r
+  u8 *pd = &Pico_mcd->word_ram1M[(r3 & 1) ^ 1][((a >> 1) ^ 1) & 0x1ffff];\r
 \r
   //if ((a & 0x3ffff) < 0x28000) return;\r
 \r
@@ -1275,279 +620,173 @@ static void decode_write16(u32 a, u16 d, int r3)
     *pd = d;\r
   }\r
 }\r
-#endif\r
 \r
-// -----------------------------------------------------------------\r
+// backup RAM (fe0000 - feffff)\r
+static u32 PicoReadS68k8_bram(u32 a)\r
+{\r
+  return Pico_mcd->bram[(a>>1)&0x1fff];\r
+}\r
 \r
-#ifdef _ASM_CD_MEMORY_C\r
-void PicoWriteS68k8(u32 a,u8 d);\r
-#else\r
-static void PicoWriteS68k8(u32 a,u8 d)\r
+static u32 PicoReadS68k16_bram(u32 a)\r
 {\r
-  elprintf(EL_IO, "s68k w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPcS68k);\r
+  u32 d;\r
+  elprintf(EL_ANOMALY, "FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
+  a = (a >> 1) & 0x1fff;\r
+  d = Pico_mcd->bram[a++];\r
+  d|= Pico_mcd->bram[a++] << 8; // probably wrong, TODO: verify\r
+  return d;\r
+}\r
 \r
-  a&=0xffffff;\r
+static void PicoWriteS68k8_bram(u32 a, u32 d)\r
+{\r
+  Pico_mcd->bram[(a >> 1) & 0x1fff] = d;\r
+  SRam.changed = 1;\r
+}\r
 \r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
+static void PicoWriteS68k16_bram(u32 a, u32 d)\r
+{\r
+  elprintf(EL_ANOMALY, "s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
+  a = (a >> 1) & 0x1fff;\r
+  Pico_mcd->bram[a++] = d;\r
+  Pico_mcd->bram[a++] = d >> 8; // TODO: verify..\r
+  SRam.changed = 1;\r
+}\r
 \r
-  // prg RAM\r
-  if (a < 0x80000) {\r
-    u8 *pm=(u8 *)(Pico_mcd->prg_ram+(a^1));\r
-    if (a >= (Pico_mcd->s68k_regs[2]<<8)) *pm=d;\r
-    return;\r
-  }\r
+// PCM and registers (ff0000 - ffffff)\r
+static u32 PicoReadS68k8_pr(u32 a)\r
+{\r
+  u32 d = 0;\r
 \r
   // regs\r
-  if ((a&0xfffe00) == 0xff8000) {\r
+  if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1ff;\r
-    rdprintf("s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k);\r
-    if (a >= 0x58 && a < 0x68)\r
-         gfx_cd_write16(a&~1, (d<<8)|d);\r
-    else s68k_reg_write8(a,d);\r
-    return;\r
-  }\r
-\r
-  // word RAM (2M area)\r
-  if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
-    int r3 = Pico_mcd->s68k_regs[3];\r
-    wrdprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
-    if (r3 & 4) { // 1M decode mode?\r
-      decode_write8(a, d, r3);\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
+    elprintf(EL_CDREGS, "s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
+    if (a >= 0x0e && a < 0x30) {\r
+      d = Pico_mcd->s68k_regs[a];\r
+      s68k_poll_detect(a, d);\r
+      elprintf(EL_CDREGS, "ret = %02x", (u8)d);\r
+      return 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
-    // Wing Commander tries to write here in wrong mode\r
-    int bank;\r
-    if (d)\r
-      wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
-//    if (!(Pico_mcd->s68k_regs[3]&4))\r
-//      dprintf("s68k_wram1M FIXME: wrong mode");\r
-    bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-    *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;\r
-    return;\r
+    else if (a >= 0x58 && a < 0x68)\r
+         d = gfx_cd_read(a & ~1);\r
+    else d = s68k_reg_read16(a & ~1);\r
+    if (!(a & 1))\r
+      d >>= 8;\r
+    elprintf(EL_CDREGS, "ret = %02x", (u8)d);\r
+    return d & 0xff;\r
   }\r
 \r
   // PCM\r
-  if ((a&0xff8000)==0xff0000) {\r
+  if ((a & 0x8000) == 0x0000) {\r
     a &= 0x7fff;\r
     if (a >= 0x2000)\r
-      Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
-    else if (a < 0x12)\r
-      pcm_write(a>>1, d);\r
-    return;\r
-  }\r
-\r
-  // bram\r
-  if ((a&0xff0000)==0xfe0000) {\r
-    Pico_mcd->bram[(a>>1)&0x1fff] = d;\r
-    SRam.changed = 1;\r
-    return;\r
+      d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a >> 1) & 0xfff];\r
+    else if (a >= 0x20) {\r
+      a &= 0x1e;\r
+      d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
+      if (a & 2)\r
+        d >>= 8;\r
+    }\r
+    return d & 0xff;\r
   }\r
 \r
-  elprintf(EL_UIO, "s68k w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPcS68k);\r
+  return s68k_unmapped_read8(a);\r
 }\r
-#endif\r
 \r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-void PicoWriteS68k16(u32 a,u16 d);\r
-#else\r
-static void PicoWriteS68k16(u32 a,u16 d)\r
+static u32 PicoReadS68k16_pr(u32 a)\r
 {\r
-  elprintf(EL_IO, "s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
-\r
-  a&=0xfffffe;\r
-\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  // prg RAM\r
-  if (a < 0x80000) {\r
-    wrdprintf("s68k_prgram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
-    if (a >= (Pico_mcd->s68k_regs[2]<<8)) // needed for Dungeon Explorer\r
-      *(u16 *)(Pico_mcd->prg_ram+a)=d;\r
-    return;\r
-  }\r
+  u32 d = 0;\r
 \r
   // regs\r
-  if ((a&0xfffe00) == 0xff8000) {\r
+  if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1fe;\r
-    rdprintf("s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k);\r
-    if (a >= 0x58 && a < 0x68)\r
-      gfx_cd_write16(a, d);\r
-    else {\r
-      if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
-        Pico_mcd->s68k_regs[0xf] = d;\r
-        return;\r
-      }\r
-      s68k_reg_write8(a,  d>>8);\r
-      s68k_reg_write8(a+1,d&0xff);\r
-    }\r
-    return;\r
+    elprintf(EL_CDREGS, "s68k_regs r16: [%02x] @ %06x", a, SekPcS68k);\r
+    if (0x58 <= a && a < 0x68)\r
+         d = gfx_cd_read(a);\r
+    else d = s68k_reg_read16(a);\r
+    elprintf(EL_CDREGS, "ret = %04x", d);\r
+    return d;\r
   }\r
 \r
-  // word RAM (2M area)\r
-  if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
-    int r3 = Pico_mcd->s68k_regs[3];\r
-    wrdprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
-    if (r3 & 4) { // 1M decode mode?\r
-      decode_write16(a, d, r3);\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
+  // PCM\r
+  if ((a & 0x8000) == 0x0000) {\r
+    //elprintf(EL_ANOMALY, "FIXME: s68k_pcm r16: [%06x] @%06x", a, SekPcS68k);\r
+    a &= 0x7fff;\r
+    if (a >= 0x2000)\r
+      d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
+    else if (a >= 0x20) {\r
+      a &= 0x1e;\r
+      d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
+      if (a & 2) d >>= 8;\r
     }\r
-    return;\r
+    elprintf(EL_CDREGS, "ret = %04x", d);\r
+    return d;\r
   }\r
 \r
-  // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
-    int bank;\r
-    if (d)\r
-      wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
-//    if (!(Pico_mcd->s68k_regs[3]&4))\r
-//      dprintf("s68k_wram1M FIXME: wrong mode");\r
-    bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
-    *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;\r
+  return s68k_unmapped_read16(a);\r
+}\r
+\r
+static void PicoWriteS68k8_pr(u32 a, u32 d)\r
+{\r
+  // regs\r
+  if ((a & 0xfe00) == 0x8000) {\r
+    a &= 0x1ff;\r
+    elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k);\r
+    if (0x58 <= a && a < 0x68)\r
+         gfx_cd_write16(a&~1, (d<<8)|d);\r
+    else s68k_reg_write8(a,d);\r
     return;\r
   }\r
 \r
   // PCM\r
-  if ((a&0xff8000)==0xff0000) {\r
+  if ((a & 0x8000) == 0x0000) {\r
     a &= 0x7fff;\r
     if (a >= 0x2000)\r
       Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
     else if (a < 0x12)\r
-      pcm_write(a>>1, d & 0xff);\r
-    return;\r
-  }\r
-\r
-  // bram\r
-  if ((a&0xff0000)==0xfe0000) {\r
-    dprintf("s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
-    a = (a>>1)&0x1fff;\r
-    Pico_mcd->bram[a++] = d;           // Gens does little endian here, an so do we..\r
-    Pico_mcd->bram[a++] = d >> 8;\r
-    SRam.changed = 1;\r
+      pcm_write(a>>1, d);\r
     return;\r
   }\r
 \r
-  elprintf(EL_UIO, "s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
+  s68k_unmapped_write8(a, d);\r
 }\r
-#endif\r
 \r
-\r
-#ifdef _ASM_CD_MEMORY_C\r
-void PicoWriteS68k32(u32 a,u32 d);\r
-#else\r
-static void PicoWriteS68k32(u32 a,u32 d)\r
+static void PicoWriteS68k16_pr(u32 a, u32 d)\r
 {\r
-  elprintf(EL_IO, "s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
-\r
-  a&=0xfffffe;\r
-\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  // prg RAM\r
-  if (a < 0x80000) {\r
-    if (a >= (Pico_mcd->s68k_regs[2]<<8)) {\r
-      u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
-      pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
-    }\r
-    return;\r
-  }\r
-\r
   // regs\r
-  if ((a&0xfffe00) == 0xff8000) {\r
+  if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1fe;\r
-    rdprintf("s68k_regs w32: [%02x] %08x @ %06x", a, d, SekPcS68k);\r
-    if (a >= 0x58 && a < 0x68) {\r
-      gfx_cd_write16(a,   d>>16);\r
-      gfx_cd_write16(a+2, d&0xffff);\r
-    } else {\r
-      if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f);\r
-      s68k_reg_write8(a,   d>>24);\r
-      s68k_reg_write8(a+1,(d>>16)&0xff);\r
-      s68k_reg_write8(a+2,(d>>8) &0xff);\r
-      s68k_reg_write8(a+3, d     &0xff);\r
-    }\r
-    return;\r
-  }\r
-\r
-  // word RAM (2M area)\r
-  if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
-    int r3 = Pico_mcd->s68k_regs[3];\r
-    wrdprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
-    if (r3 & 4) { // 1M decode mode?\r
-      decode_write16(a  , d >> 16, r3);\r
-      decode_write16(a+2, d      , r3);\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
-      pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
+    elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k);\r
+    if (a >= 0x58 && a < 0x68)\r
+      gfx_cd_write16(a, d);\r
+    else {\r
+      if (a == 0xe) {\r
+        // special case, 2 byte writes would be handled differently\r
+        // TODO: verify\r
+        Pico_mcd->s68k_regs[0xf] = d;\r
+        return;\r
+      }\r
+      s68k_reg_write8(a,     d >> 8);\r
+      s68k_reg_write8(a + 1, d & 0xff);\r
     }\r
     return;\r
   }\r
 \r
-  // word RAM (1M area)\r
-  if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
-    int bank;\r
-    u16 *pm;\r
-    if (d)\r
-      wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
-//    if (!(Pico_mcd->s68k_regs[3]&4))\r
-//      dprintf("s68k_wram1M FIXME: wrong mode");\r
-    bank = (Pico_mcd->s68k_regs[3]&1)^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
   // PCM\r
-  if ((a&0xff8000)==0xff0000) {\r
+  if ((a & 0x8000) == 0x0000) {\r
     a &= 0x7fff;\r
-    if (a >= 0x2000) {\r
-      a >>= 1;\r
-      Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] = (d >> 16);\r
-      Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff] = d;\r
-    } else if (a < 0x12) {\r
-      a >>= 1;\r
-      pcm_write(a,  (d>>16) & 0xff);\r
-      pcm_write(a+1, d & 0xff);\r
-    }\r
-    return;\r
-  }\r
-\r
-  // bram\r
-  if ((a&0xff0000)==0xfe0000) {\r
-    dprintf("s68k_bram w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
-    a = (a>>1)&0x1fff;\r
-    Pico_mcd->bram[a++] = d >> 16;             // middle endian? verify?\r
-    Pico_mcd->bram[a++] = d >> 24;\r
-    Pico_mcd->bram[a++] = d;\r
-    Pico_mcd->bram[a++] = d >> 8;\r
-    SRam.changed = 1;\r
+    if (a >= 0x2000)\r
+      Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
+    else if (a < 0x12)\r
+      pcm_write(a>>1, d & 0xff);\r
     return;\r
   }\r
 \r
-  elprintf(EL_UIO, "s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
+  s68k_unmapped_write16(a, d);\r
 }\r
-#endif\r
-\r
 \r
 // -----------------------------------------------------------------\r
 \r
-\r
 #ifdef EMU_C68K\r
 static __inline int PicoMemBaseM68k(u32 pc)\r
 {\r
@@ -1616,9 +855,45 @@ static u32 PicoCheckPcS68k(u32 pc)
 }\r
 #endif\r
 \r
-#ifndef _ASM_CD_MEMORY_C\r
-void PicoMemResetCD(int r3)\r
+// TODO: probably split\r
+void PicoMemRemapCD(int r3)\r
 {\r
+  void *bank;\r
+\r
+  // PRG RAM\r
+  if (Pico_mcd->m.busreq & 2) {\r
+    bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3] >> 6];\r
+    cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0);\r
+  }\r
+  else {\r
+    m68k_map_unmap(0x020000, 0x03ffff);\r
+  }\r
+\r
+  // WORD RAM\r
+  if (!(r3 & 4)) {\r
+    // 2M mode. XXX: allowing access in all cases for simplicity\r
+    bank = Pico_mcd->word_ram2M;\r
+    cpu68k_map_all_ram(0x200000, 0x23ffff, bank, 0);\r
+    cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1);\r
+    // TODO: handle 0x0c0000\r
+  }\r
+  else {\r
+    bank = Pico_mcd->word_ram1M[r3 & 1];\r
+    cpu68k_map_all_ram(0x200000, 0x21ffff, bank, 0);\r
+    bank = Pico_mcd->word_ram1M[(r3 & 1) ^ 1];\r
+    cpu68k_map_all_ram(0x0c0000, 0x0effff, bank, 1);\r
+    // "cell arrange" on m68k\r
+    cpu68k_map_set(m68k_read8_map,   0x220000, 0x23ffff, PicoReadM68k8_cell, 1);\r
+    cpu68k_map_set(m68k_read16_map,  0x220000, 0x23ffff, PicoReadM68k16_cell, 1);\r
+    cpu68k_map_set(m68k_write8_map,  0x220000, 0x23ffff, PicoWriteM68k8_cell, 1);\r
+    cpu68k_map_set(m68k_write16_map, 0x220000, 0x23ffff, PicoWriteM68k16_cell, 1);\r
+    // "decode format" on s68k\r
+    cpu68k_map_set(s68k_read8_map,   0x080000, 0x0bffff, PicoReadS68k8_dec, 1);\r
+    cpu68k_map_set(s68k_read16_map,  0x080000, 0x0bffff, PicoReadS68k16_dec, 1);\r
+    cpu68k_map_set(s68k_write8_map,  0x080000, 0x0bffff, PicoWriteS68k8_dec, 1);\r
+    cpu68k_map_set(s68k_write16_map, 0x080000, 0x0bffff, PicoWriteS68k16_dec, 1);\r
+  }\r
+\r
 #ifdef EMU_F68K\r
   // update fetchmap..\r
   int i;\r
@@ -1636,7 +911,6 @@ void PicoMemResetCD(int r3)
   }\r
 #endif\r
 }\r
-#endif\r
 \r
 #ifdef EMU_M68K\r
 static void m68k_mem_setup_cd(void);\r
@@ -1644,43 +918,69 @@ static void m68k_mem_setup_cd(void);
 \r
 PICO_INTERNAL void PicoMemSetupCD(void)\r
 {\r
-  // additional handlers for common code\r
-  PicoRead16Hook = OtherRead16End;\r
-  PicoWrite8Hook = OtherWrite8End;\r
+  // setup default main68k map\r
+  PicoMemSetup();\r
+\r
+  // PicoMemRemapCD() will set up RAMs, so not done here\r
+\r
+  // main68k map (BIOS mapped by PicoMemSetup()):\r
+  // RAM cart\r
+  if (PicoOpt & POPT_EN_MCD_RAMCART) {\r
+    cpu68k_map_set(m68k_read8_map,   0x400000, 0x7fffff, PicoReadM68k8_ramc, 1);\r
+    cpu68k_map_set(m68k_read16_map,  0x400000, 0x7fffff, PicoReadM68k16_ramc, 1);\r
+    cpu68k_map_set(m68k_write8_map,  0x400000, 0x7fffff, PicoWriteM68k8_ramc, 1);\r
+    cpu68k_map_set(m68k_write16_map, 0x400000, 0x7fffff, PicoWriteM68k16_ramc, 1);\r
+  }\r
+\r
+  // registers/IO:\r
+  cpu68k_map_set(m68k_read8_map,   0xa10000, 0xa1ffff, PicoReadM68k8_io, 1);\r
+  cpu68k_map_set(m68k_read16_map,  0xa10000, 0xa1ffff, PicoReadM68k16_io, 1);\r
+  cpu68k_map_set(m68k_write8_map,  0xa10000, 0xa1ffff, PicoWriteM68k8_io, 1);\r
+  cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWriteM68k16_io, 1);\r
+\r
+  // sub68k map\r
+  cpu68k_map_set(s68k_read8_map,   0x000000, 0xffffff, s68k_unmapped_read8, 1);\r
+  cpu68k_map_set(s68k_read16_map,  0x000000, 0xffffff, s68k_unmapped_read16, 1);\r
+  cpu68k_map_set(s68k_write8_map,  0x000000, 0xffffff, s68k_unmapped_write8, 1);\r
+  cpu68k_map_set(s68k_write16_map, 0x000000, 0xffffff, s68k_unmapped_write16, 1);\r
+\r
+  // PRG RAM\r
+  cpu68k_map_set(s68k_read8_map,   0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
+  cpu68k_map_set(s68k_read16_map,  0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
+  cpu68k_map_set(s68k_write8_map,  0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
+  cpu68k_map_set(s68k_write16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0);\r
+\r
+  // BRAM\r
+  cpu68k_map_set(s68k_read8_map,   0xfe0000, 0xfeffff, PicoReadS68k8_bram, 1);\r
+  cpu68k_map_set(s68k_read16_map,  0xfe0000, 0xfeffff, PicoReadS68k16_bram, 1);\r
+  cpu68k_map_set(s68k_write8_map,  0xfe0000, 0xfeffff, PicoWriteS68k8_bram, 1);\r
+  cpu68k_map_set(s68k_write16_map, 0xfe0000, 0xfeffff, PicoWriteS68k16_bram, 1);\r
+\r
+  // PCM, regs\r
+  cpu68k_map_set(s68k_read8_map,   0xff0000, 0xffffff, PicoReadS68k8_pr, 1);\r
+  cpu68k_map_set(s68k_read16_map,  0xff0000, 0xffffff, PicoReadS68k16_pr, 1);\r
+  cpu68k_map_set(s68k_write8_map,  0xff0000, 0xffffff, PicoWriteS68k8_pr, 1);\r
+  cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 1);\r
 \r
 #ifdef EMU_C68K\r
-  // Setup m68k memory callbacks:\r
-  PicoCpuCM68k.checkpc=PicoCheckPcM68k;\r
-  PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoReadM68k8;\r
-  PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoReadM68k16;\r
-  PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoReadM68k32;\r
-  PicoCpuCM68k.write8 =PicoWriteM68k8;\r
-  PicoCpuCM68k.write16=PicoWriteM68k16;\r
-  PicoCpuCM68k.write32=PicoWriteM68k32;\r
+  PicoCpuCM68k.checkpc = PicoCheckPcM68k;\r
   // s68k\r
-  PicoCpuCS68k.checkpc=PicoCheckPcS68k;\r
-  PicoCpuCS68k.fetch8 =PicoCpuCS68k.read8 =PicoReadS68k8;\r
-  PicoCpuCS68k.fetch16=PicoCpuCS68k.read16=PicoReadS68k16;\r
-  PicoCpuCS68k.fetch32=PicoCpuCS68k.read32=PicoReadS68k32;\r
-  PicoCpuCS68k.write8 =PicoWriteS68k8;\r
-  PicoCpuCS68k.write16=PicoWriteS68k16;\r
-  PicoCpuCS68k.write32=PicoWriteS68k32;\r
+  PicoCpuCS68k.checkpc = PicoCheckPcS68k;\r
+  PicoCpuCS68k.fetch8  = PicoCpuCS68k.read8  = s68k_read8;\r
+  PicoCpuCS68k.fetch16 = PicoCpuCS68k.read16 = s68k_read16;\r
+  PicoCpuCS68k.fetch32 = PicoCpuCS68k.read32 = s68k_read32;\r
+  PicoCpuCS68k.write8  = s68k_write8;\r
+  PicoCpuCS68k.write16 = s68k_write16;\r
+  PicoCpuCS68k.write32 = s68k_write32;\r
 #endif\r
 #ifdef EMU_F68K\r
-  // m68k\r
-  PicoCpuFM68k.read_byte =PicoReadM68k8;\r
-  PicoCpuFM68k.read_word =PicoReadM68k16;\r
-  PicoCpuFM68k.read_long =PicoReadM68k32;\r
-  PicoCpuFM68k.write_byte=PicoWriteM68k8;\r
-  PicoCpuFM68k.write_word=PicoWriteM68k16;\r
-  PicoCpuFM68k.write_long=PicoWriteM68k32;\r
   // s68k\r
-  PicoCpuFS68k.read_byte =PicoReadS68k8;\r
-  PicoCpuFS68k.read_word =PicoReadS68k16;\r
-  PicoCpuFS68k.read_long =PicoReadS68k32;\r
-  PicoCpuFS68k.write_byte=PicoWriteS68k8;\r
-  PicoCpuFS68k.write_word=PicoWriteS68k16;\r
-  PicoCpuFS68k.write_long=PicoWriteS68k32;\r
+  PicoCpuFS68k.read_byte  = s68k_read8;\r
+  PicoCpuFS68k.read_word  = s68k_read16;\r
+  PicoCpuFS68k.read_long  = s68k_read32;\r
+  PicoCpuFS68k.write_byte = s68k_write8;\r
+  PicoCpuFS68k.write_word = s68k_write16;\r
+  PicoCpuFS68k.write_long = s68k_write32;\r
 \r
   // setup FAME fetchmap\r
   {\r
@@ -1705,13 +1005,12 @@ PICO_INTERNAL void PicoMemSetupCD(void)
     // WORD RAM 2M area\r
     for (i = M68K_FETCHBANK1*0x08/0x100; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0xc0000; i++)\r
       PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram2M - 0x80000;\r
-    // PicoMemResetCD() will setup word ram for both\r
+    // PicoMemRemapCD() will setup word ram for both\r
   }\r
 #endif\r
 #ifdef EMU_M68K\r
   m68k_mem_setup_cd();\r
 #endif\r
-  z80_mem_setup();\r
 \r
   // m68k_poll_addr = m68k_poll_cnt = 0;\r
   s68k_poll_adclk = s68k_poll_cnt = 0;\r
@@ -1719,23 +1018,30 @@ PICO_INTERNAL void PicoMemSetupCD(void)
 \r
 \r
 #ifdef EMU_M68K\r
+u32  m68k_read8(u32 a);\r
+u32  m68k_read16(u32 a);\r
+u32  m68k_read32(u32 a);\r
+void m68k_write8(u32 a, u8 d);\r
+void m68k_write16(u32 a, u16 d);\r
+void m68k_write32(u32 a, u32 d);\r
+\r
 static unsigned int PicoReadCD8w (unsigned int a) {\r
-       return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k8(a) : PicoReadM68k8(a);\r
+       return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read8(a) : m68k_read8(a);\r
 }\r
 static unsigned int PicoReadCD16w(unsigned int a) {\r
-       return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(a);\r
+       return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read16(a) : m68k_read16(a);\r
 }\r
 static unsigned int PicoReadCD32w(unsigned int a) {\r
-       return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k32(a) : PicoReadM68k32(a);\r
+       return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read32(a) : m68k_read32(a);\r
 }\r
 static void PicoWriteCD8w (unsigned int a, unsigned char d) {\r
-       if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);\r
+       if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write8(a, d); else m68k_write8(a, d);\r
 }\r
 static void PicoWriteCD16w(unsigned int a, unsigned short d) {\r
-       if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);\r
+       if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write16(a, d); else m68k_write16(a, d);\r
 }\r
 static void PicoWriteCD32w(unsigned int a, unsigned int d) {\r
-       if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);\r
+       if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write32(a, d); else m68k_write32(a, d);\r
 }\r
 \r
 // these are allowed to access RAM\r
index 7335158..8c0bf25 100644 (file)
@@ -30,6 +30,7 @@ PICO_INTERNAL void PicoPowerMCD(void)
   memset(Pico_mcd->pcm_ram,    0, sizeof(Pico_mcd->pcm_ram));
   memset(Pico_mcd->bram, 0, sizeof(Pico_mcd->bram));
   memcpy(Pico_mcd->bram + sizeof(Pico_mcd->bram) - fmt_size, formatted_bram, fmt_size);
+  PicoMemRemapCD(1);
 }
 
 PICO_INTERNAL int PicoResetMCD(void)
@@ -45,13 +46,12 @@ PICO_INTERNAL int PicoResetMCD(void)
   Reset_CD();
   LC89510_Reset();
   gfx_cd_reset();
-  PicoMemResetCD(1);
 #ifdef _ASM_CD_MEMORY_C
   //PicoMemResetCDdecode(1); // don't have to call this in 2M mode
 #endif
 
   // use SRam.data for RAM cart
-  if (PicoOpt&POPT_EN_MCD_RAMCART) {
+  if (PicoOpt & POPT_EN_MCD_RAMCART) {
     if (SRam.data == NULL)
       SRam.data = calloc(1, 0x12000);
   }
index d6b91bd..89bdde3 100644 (file)
@@ -35,8 +35,8 @@ char *PDebugMain(void)
   sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); MVP;
   sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); MVP;
   sprintf(dstrp, "scroll size: w: %i, h: %i  SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4,
-       bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2), SRam.eeprom_type); MVP;
-  sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); MVP;
+       bit(Pico.m.sram_status, 4), bit(Pico.m.sram_status, 2), SRam.eeprom_type); MVP;
+  sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_status); MVP;
   sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP;
   sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count); MVP;
 #if defined(EMU_C68K)
index 819ead8..aa2a54e 100644 (file)
 // This is part of Pico Library\r
 \r
 // (c) Copyright 2004 Dave, All rights reserved.\r
-// (c) Copyright 2006,2007 notaz, All rights reserved.\r
+// (c) Copyright 2006-2009 notaz, All rights reserved.\r
 // Free for non-commercial use.\r
 \r
 // For commercial use, separate licencing terms must be obtained.\r
 \r
 \r
 #include "pico_int.h"\r
+#include "memory.h"\r
 \r
 #include "sound/ym2612.h"\r
 #include "sound/sn76496.h"\r
 \r
-#ifndef UTYPES_DEFINED\r
-typedef unsigned char  u8;\r
-typedef unsigned short u16;\r
-typedef unsigned int   u32;\r
-#define UTYPES_DEFINED\r
-#endif\r
-\r
 extern unsigned int lastSSRamWrite; // used by serial eeprom code\r
 \r
-#ifdef _ASM_MEMORY_C\r
-u32  PicoRead8(u32 a);\r
-u32  PicoRead16(u32 a);\r
-void PicoWrite8(u32 a,u8 d);\r
-void PicoWriteRomHW_SSF2(u32 a,u32 d);\r
-#endif\r
+unsigned long m68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];\r
+unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];\r
+unsigned long m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];\r
+unsigned long m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];\r
+\r
+static void xmap_set(unsigned long *map, int shift, int start_addr, int end_addr,\r
+    void *func_or_mh, int is_func)\r
+{\r
+  unsigned long addr = (unsigned long)func_or_mh;\r
+  int mask = (1 << shift) - 1;\r
+  int i;\r
+\r
+  if ((start_addr & mask) != 0 || (end_addr & mask) != mask) {\r
+    elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: tried to map bad range: %06x-%06x",\r
+      start_addr, end_addr);\r
+    return;\r
+  }\r
+\r
+  if (addr & 1) {\r
+    elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: ptr is not aligned: %08lx", addr);\r
+    return;\r
+  }\r
+\r
+  if (!is_func)\r
+    addr -= start_addr;\r
+\r
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++) {\r
+    map[i] = addr >> 1;\r
+    if (is_func)\r
+      map[i] |= 1 << (sizeof(addr) * 8 - 1);\r
+  }\r
+}\r
+\r
+void z80_map_set(unsigned long *map, int start_addr, int end_addr,\r
+    void *func_or_mh, int is_func)\r
+{\r
+  xmap_set(map, Z80_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func);\r
+}\r
+\r
+void cpu68k_map_set(unsigned long *map, int start_addr, int end_addr,\r
+    void *func_or_mh, int is_func)\r
+{\r
+  xmap_set(map, M68K_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func);\r
+}\r
+\r
+// more specialized/optimized function (does same as above)\r
+void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub)\r
+{\r
+  unsigned long *r8map, *r16map, *w8map, *w16map;\r
+  unsigned long addr = (unsigned long)ptr;\r
+  int shift = M68K_MEM_SHIFT;\r
+  int i;\r
+\r
+  if (!is_sub) {\r
+    r8map = m68k_read8_map;\r
+    r16map = m68k_read16_map;\r
+    w8map = m68k_write8_map;\r
+    w16map = m68k_write16_map;\r
+  } else {\r
+    r8map = s68k_read8_map;\r
+    r16map = s68k_read16_map;\r
+    w8map = s68k_write8_map;\r
+    w16map = s68k_write16_map;\r
+  }\r
+\r
+  addr -= start_addr;\r
+  addr >>= 1;\r
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)\r
+    r8map[i] = r16map[i] = w8map[i] = w16map[i] = addr;\r
+}\r
+\r
+static u32 m68k_unmapped_read8(u32 a)\r
+{\r
+  elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);\r
+  return 0; // assume pulldown, as if MegaCD2 was attached\r
+}\r
+\r
+static u32 m68k_unmapped_read16(u32 a)\r
+{\r
+  elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);\r
+  return 0;\r
+}\r
+\r
+static void m68k_unmapped_write8(u32 a, u32 d)\r
+{\r
+  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);\r
+}\r
+\r
+static void m68k_unmapped_write16(u32 a, u32 d)\r
+{\r
+  elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);\r
+}\r
+\r
+void m68k_map_unmap(int start_addr, int end_addr)\r
+{\r
+  unsigned long addr;\r
+  int shift = M68K_MEM_SHIFT;\r
+  int i;\r
+\r
+  addr = (unsigned long)m68k_unmapped_read8;\r
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)\r
+    m68k_read8_map[i] = (addr >> 1) | (1 << 31);\r
+\r
+  addr = (unsigned long)m68k_unmapped_read16;\r
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)\r
+    m68k_read16_map[i] = (addr >> 1) | (1 << 31);\r
+\r
+  addr = (unsigned long)m68k_unmapped_write8;\r
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)\r
+    m68k_write8_map[i] = (addr >> 1) | (1 << 31);\r
+\r
+  addr = (unsigned long)m68k_unmapped_write16;\r
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)\r
+    m68k_write16_map[i] = (addr >> 1) | (1 << 31);\r
+}\r
+\r
+MAKE_68K_READ8(m68k_read8, m68k_read8_map)\r
+MAKE_68K_READ16(m68k_read16, m68k_read16_map)\r
+MAKE_68K_READ32(m68k_read32, m68k_read16_map)\r
+MAKE_68K_WRITE8(m68k_write8, m68k_write8_map)\r
+MAKE_68K_WRITE16(m68k_write16, m68k_write16_map)\r
+MAKE_68K_WRITE32(m68k_write32, m68k_write16_map)\r
+\r
+// -----------------------------------------------------------------\r
+\r
+static u32 ym2612_read_local_68k(void);\r
+static int ym2612_write_local(u32 a, u32 d, int is_from_z80);\r
+static void z80_mem_setup(void);\r
 \r
 \r
 #ifdef EMU_CORE_DEBUG\r
@@ -95,15 +211,10 @@ PICO_INTERNAL void PicoInitPc(u32 pc)
   PicoCheckPc(pc);\r
 }\r
 \r
-#ifndef _ASM_MEMORY_C\r
-PICO_INTERNAL_ASM void PicoMemReset(void)\r
-{\r
-}\r
-#endif\r
-\r
 // -----------------------------------------------------------------\r
+// memmap helpers\r
 \r
-int PadRead(int i)\r
+static int PadRead(int i)\r
 {\r
   int pad,value,data_reg;\r
   pad=~PicoPadInt[i]; // Get inverse of pad MXYZ SACB RLDU\r
@@ -135,77 +246,80 @@ int PadRead(int i)
   return value; // will mirror later\r
 }\r
 \r
-\r
-#ifndef _ASM_MEMORY_C\r
-static\r
-#endif\r
-u32 SRAMRead(u32 a)\r
+static u32 io_ports_read(u32 a)\r
 {\r
-  unsigned int sreg = Pico.m.sram_reg;\r
-  if (!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM\r
-    elprintf(EL_SRAMIO, "normal sram detected.");\r
-    Pico.m.sram_reg|=0x10; // should be normal SRAM\r
+  u32 d;\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); break;\r
+    case 2:  d = PadRead(1); break;\r
+    default: d = Pico.ioports[a]; break; // IO ports can be used as RAM\r
   }\r
-  if (sreg & 4) // EEPROM read\r
-    return SRAMReadEEPROM();\r
-  else // if(sreg & 1) // (sreg&5) is one of prerequisites\r
-    return *(u8 *)(SRam.data-SRam.start+a);\r
+  return d;\r
 }\r
 \r
-#ifndef _ASM_MEMORY_C\r
-static\r
-#endif\r
-u32 SRAMRead16(u32 a)\r
+static void io_ports_write(u32 a, u32 d)\r
 {\r
-  u32 d;\r
-  if (Pico.m.sram_reg & 4) {\r
-    d = SRAMReadEEPROM();\r
-    d |= d << 8;\r
-  } else {\r
-    u8 *pm=(u8 *)(SRam.data-SRam.start+a);\r
-    d =*pm++ << 8;\r
-    d|=*pm++;\r
+  a = (a>>1) & 0xf;\r
+\r
+  // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
+  if (1 <= a && a <= 2 && (PicoOpt & POPT_6BTN_PAD))\r
+  {\r
+    Pico.m.padDelay[a - 1] = 0;\r
+    if (!(Pico.ioports[a] & 0x40) && (d & 0x40))\r
+      Pico.m.padTHPhase[a - 1]++;\r
   }\r
-  return d;\r
+\r
+  // cartain IO ports can be used as RAM\r
+  Pico.ioports[a] = d;\r
 }\r
 \r
-static void SRAMWrite(u32 a, u32 d)\r
+static void ctl_write_z80busreq(u32 d)\r
 {\r
-  unsigned int sreg = Pico.m.sram_reg;\r
-  if(!(sreg & 0x10)) {\r
-    // not detected SRAM\r
-    if((a&~1)==0x200000) {\r
-      elprintf(EL_SRAMIO, "eeprom detected.");\r
-      sreg|=4; // this should be a game with EEPROM (like NBA Jam)\r
-      SRam.start=0x200000; SRam.end=SRam.start+1;\r
-    } else\r
-      elprintf(EL_SRAMIO, "normal sram detected.");\r
-    sreg|=0x10;\r
-    Pico.m.sram_reg=sreg;\r
+  d&=1; d^=1;\r
+  elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc);\r
+  if (d ^ Pico.m.z80Run)\r
+  {\r
+    if (d)\r
+    {\r
+      z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());\r
+    }\r
+    else\r
+    {\r
+      z80stopCycle = SekCyclesDone();\r
+      if ((PicoOpt&POPT_EN_Z80) && !Pico.m.z80_reset)\r
+        PicoSyncZ80(z80stopCycle);\r
+    }\r
+    Pico.m.z80Run = d;\r
   }\r
-  if(sreg & 4) { // EEPROM write\r
-    // this diff must be at most 16 for NBA Jam to work\r
-    if(SekCyclesDoneT()-lastSSRamWrite < 16) {\r
-      // just update pending state\r
-      elprintf(EL_EEPROM, "eeprom: skip because cycles=%i", SekCyclesDoneT()-lastSSRamWrite);\r
-      SRAMUpdPending(a, d);\r
-    } else {\r
-      int old=sreg;\r
-      SRAMWriteEEPROM(sreg>>6); // execute pending\r
-      SRAMUpdPending(a, d);\r
-      if ((old^Pico.m.sram_reg)&0xc0) // update time only if SDA/SCL changed\r
-        lastSSRamWrite = SekCyclesDoneT();\r
+}\r
+\r
+static void ctl_write_z80reset(u32 d)\r
+{\r
+  d&=1; d^=1;\r
+  elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc);\r
+  if (d ^ Pico.m.z80_reset)\r
+  {\r
+    if (d)\r
+    {\r
+      if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run)\r
+        PicoSyncZ80(SekCyclesDone());\r
+      YM2612ResetChip();\r
+      timers_reset();\r
     }\r
-  } else if(!(sreg & 2)) {\r
-    u8 *pm=(u8 *)(SRam.data-SRam.start+a);\r
-    if(*pm != (u8)d) {\r
-      SRam.changed = 1;\r
-      *pm=(u8)d;\r
+    else\r
+    {\r
+      z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());\r
+      z80_reset();\r
     }\r
+    Pico.m.z80_reset = d;\r
   }\r
 }\r
 \r
+\r
 // for nonstandard reads\r
+// TODO: mv to carthw\r
 static u32 OtherRead16End(u32 a, int realsize)\r
 {\r
   u32 d=0;\r
@@ -283,18 +397,8 @@ end:
   return d;\r
 }\r
 \r
-\r
-//extern UINT32 mz80GetRegisterValue(void *, UINT32);\r
-\r
 static void OtherWrite8End(u32 a,u32 d,int realsize)\r
 {\r
-  // sram\r
-  if(a >= SRam.start && a <= SRam.end) {\r
-    elprintf(EL_SRAMIO, "sram w8  [%06x] %02x @ %06x", a, d, SekPc);\r
-    SRAMWrite(a, d);\r
-    return;\r
-  }\r
-\r
 #ifdef _ASM_MEMORY_C\r
   // special ROM hardware (currently only banking and sram reg supported)\r
   if((a&0xfffff1) == 0xA130F1) {\r
@@ -305,8 +409,8 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
   // sram access register\r
   if(a == 0xA130F1) {\r
     elprintf(EL_SRAMIO, "sram reg=%02x", d);\r
-    Pico.m.sram_reg &= ~3;\r
-    Pico.m.sram_reg |= (u8)(d&3);\r
+    Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY);\r
+    Pico.m.sram_status |= (u8)(d&3);\r
     return;\r
   }\r
 #endif\r
@@ -317,185 +421,314 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
     Pico.m.prot_bytes[(a>>2)&1] = (u8)d;\r
 }\r
 \r
-#include "memory_cmn.c"\r
+// -----------------------------------------------------------------\r
 \r
+// cart (save) RAM area (usually 0x200000 - ...)\r
+static u32 PicoRead8_sram(u32 a)\r
+{\r
+  int srs = Pico.m.sram_status;\r
+  u32 d;\r
+  if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM)))\r
+  {\r
+    if (srs & SRS_EEPROM)\r
+      d = EEPROM_read();\r
+    else\r
+      d = *(u8 *)(SRam.data - SRam.start + a);\r
+    elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);\r
+    return d;\r
+  }\r
 \r
-// -----------------------------------------------------------------\r
-//                     Read Rom and read Ram\r
+  if (a < Pico.romsize)\r
+    return Pico.rom[a ^ 1];\r
+  \r
+  return m68k_unmapped_read8(a);\r
+}\r
 \r
-#ifndef _ASM_MEMORY_C\r
-PICO_INTERNAL_ASM u32 PicoRead8(u32 a)\r
+static u32 PicoRead16_sram(u32 a)\r
 {\r
-  u32 d=0;\r
+  int srs = Pico.m.sram_status;\r
+  u32 d;\r
+  if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM)))\r
+  {\r
+    if (srs & SRS_EEPROM) {\r
+      d = EEPROM_read();\r
+      d |= d << 8;\r
+    } else {\r
+      u8 *pm = (u8 *)(SRam.data - SRam.start + a);\r
+      d  = pm[0] << 8;\r
+      d |= pm[1];\r
+    }\r
+    elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);\r
+    return d;\r
+  }\r
 \r
-  if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram\r
+  if (a < Pico.romsize)\r
+    return *(u16 *)(Pico.rom + a);\r
 \r
-  a&=0xffffff;\r
+  return m68k_unmapped_read16(a);\r
+}\r
 \r
-#ifndef EMU_CORE_DEBUG\r
-  // sram\r
-  if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {\r
-    d = SRAMRead(a);\r
-    elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);\r
-    goto end;\r
+static void PicoWrite8_sram(u32 a, u32 d)\r
+{\r
+  unsigned int srs = Pico.m.sram_status;\r
+  elprintf(EL_SRAMIO, "sram wX  [%06x] %02x @ %06x", a, d & 0xffff, SekPc);\r
+  if (srs & SRS_EEPROM) // EEPROM write\r
+  {\r
+    // this diff must be at most 16 for NBA Jam to work\r
+    if (SekCyclesDoneT() - lastSSRamWrite < 16) {\r
+      // just update pending state\r
+      elprintf(EL_EEPROM, "eeprom: skip because cycles=%i",\r
+          SekCyclesDoneT() - lastSSRamWrite);\r
+      EEPROM_upd_pending(a, d);\r
+    } else {\r
+      EEPROM_write(srs >> 6); // execute pending\r
+      EEPROM_upd_pending(a, d);\r
+      if ((srs ^ Pico.m.sram_status) & 0xc0) // update time only if SDA/SCL changed\r
+        lastSSRamWrite = SekCyclesDoneT();\r
+    }\r
   }\r
-#endif\r
+  else if (!(srs & SRS_READONLY)) {\r
+    u8 *pm=(u8 *)(SRam.data - SRam.start + a);\r
+    if (*pm != (u8)d) {\r
+      SRam.changed = 1;\r
+      *pm = (u8)d;\r
+    }\r
+  }\r
+}\r
 \r
-  if (a<Pico.romsize) { d = *(u8 *)(Pico.rom+(a^1)); goto end; } // Rom\r
-  log_io(a, 8, 0);\r
-  if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
+static void PicoWrite16_sram(u32 a, u32 d)\r
+{\r
+  // XXX: hardware could easily use MSB too..\r
+  PicoWrite8_sram(a + 1, d);\r
+}\r
 \r
-  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP\r
+// z80 area (0xa00000 - 0xa0ffff)\r
+// TODO: verify mirrors VDP and bank reg (bank area mirroring verified)\r
+static u32 PicoRead8_z80(u32 a)\r
+{\r
+  u32 d = 0xff;\r
+  if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {\r
+    elprintf(EL_ANOMALY, "68k z80 read with no bus! [%06x] @ %06x", a, SekPc);\r
+    // open bus. Pulled down if MegaCD2 is attached.\r
+    return 0;\r
+  }\r
 \r
-  d=OtherRead16(a&~1, 8);\r
-  if ((a&1)==0) d>>=8;\r
+  if ((a & 0x4000) == 0x0000)\r
+    d = Pico.zram[a & 0x1fff];\r
+  else if ((a & 0x6000) == 0x4000) // 0x4000-0x5fff\r
+    d = ym2612_read_local_68k(); \r
+  else\r
+    elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);\r
+  return d;\r
+}\r
 \r
-end:\r
-  elprintf(EL_IO, "r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (a>=Pico.romsize) {\r
-    lastread_a = a;\r
-    lastread_d[lrp_cyc++&15] = (u8)d;\r
+static u32 PicoRead16_z80(u32 a)\r
+{\r
+  u32 d = PicoRead8_z80(a);\r
+  return d | (d << 8);\r
+}\r
+\r
+static void PicoWrite8_z80(u32 a, u32 d)\r
+{\r
+  if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {\r
+    // verified on real hw\r
+    elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %02x @ %06x", a, d&0xff, SekPc);\r
+    return;\r
+  }\r
+\r
+  if ((a & 0x4000) == 0x0000) { // z80 RAM\r
+    SekCyclesBurn(2); // hack\r
+    Pico.zram[a & 0x1fff] = (u8)d;\r
+    return;\r
+  }\r
+  if ((a & 0x6000) == 0x4000) { // FM Sound\r
+    if (PicoOpt & POPT_EN_FM)\r
+      emustatus |= ym2612_write_local(a&3, d&0xff, 0)&1;\r
+    return;\r
+  }\r
+  // TODO: probably other VDP access too? Maybe more mirrors?\r
+  if ((a & 0x7ff9) == 0x7f11) { // PSG Sound\r
+    if (PicoOpt & POPT_EN_PSG)\r
+      SN76496Write(d);\r
+    return;\r
+  }\r
+#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)\r
+  if ((a & 0x7f00) == 0x6000) // Z80 BANK register\r
+  {\r
+    Pico.m.z80_bank68k >>= 1;\r
+    Pico.m.z80_bank68k |= d << 8;\r
+    Pico.m.z80_bank68k &= 0x1ff; // 9 bits and filled in the new top one\r
+    elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k << 15);\r
+    return;\r
   }\r
 #endif\r
-  return d;\r
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @ %06x", a, d&0xff, SekPc);\r
 }\r
 \r
-PICO_INTERNAL_ASM u32 PicoRead16(u32 a)\r
+static void PicoWrite16_z80(u32 a, u32 d)\r
 {\r
-  u32 d=0;\r
-\r
-  if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram\r
+  // for RAM, only most significant byte is sent\r
+  // TODO: verify remaining accesses\r
+  PicoWrite8_z80(a, d >> 8);\r
+}\r
 \r
-  a&=0xfffffe;\r
+// IO/control area (0xa10000 - 0xa1ffff)\r
+u32 PicoRead8_io(u32 a)\r
+{\r
+  u32 d;\r
 \r
-#ifndef EMU_CORE_DEBUG\r
-  // sram\r
-  if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {\r
-    d = SRAMRead16(a);\r
-    elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);\r
+  if ((a & 0xffe0) == 0x0000) { // I/O ports\r
+    d = io_ports_read(a);\r
     goto end;\r
   }\r
-#endif\r
 \r
-  if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom\r
-  log_io(a, 16, 0);\r
+  // faking open bus (MegaCD pulldowns don't work here curiously)\r
+  d = Pico.m.rotate++;\r
+  d ^= d << 6;\r
 \r
-  if ((a&0xe700e0)==0xc00000)\r
-       d = PicoVideoRead(a);\r
-  else d = OtherRead16(a, 16);\r
+  // bit8 seems to be readable in this range\r
+  if ((a & 0xfc01) == 0x1000)\r
+    d &= ~0x01;\r
 \r
-end:\r
-  elprintf(EL_IO, "r16: %06x, %04x  @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (a>=Pico.romsize) {\r
-    lastread_a = a;\r
-    lastread_d[lrp_cyc++&15] = d;\r
+  if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)\r
+    d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;\r
+    elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);\r
+    goto end;\r
   }\r
-#endif\r
+\r
+  d = m68k_unmapped_read8(a);\r
+end:\r
   return d;\r
 }\r
 \r
-PICO_INTERNAL_ASM u32 PicoRead32(u32 a)\r
+u32 PicoRead16_io(u32 a)\r
 {\r
-  u32 d=0;\r
-\r
-  if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram\r
-\r
-  a&=0xfffffe;\r
+  u32 d;\r
 \r
-  // sram\r
-  if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {\r
-    d = (SRAMRead16(a)<<16)|SRAMRead16(a+2);\r
-    elprintf(EL_SRAMIO, "sram r32 [%06x] %08x @ %06x", a, d, SekPc);\r
+  if ((a & 0xffe0) == 0x0000) { // I/O ports\r
+    d = io_ports_read(a);\r
     goto end;\r
   }\r
 \r
-  if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom\r
-  log_io(a, 32, 0);\r
+  // faking open bus\r
+  d = (Pico.m.rotate += 0x41);\r
+  d ^= (d << 5) ^ (d << 8);\r
 \r
-  if ((a&0xe700e0)==0xc00000)\r
-       d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);\r
-  else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
+  // bit8 seems to be readable in this range\r
+  if ((a & 0xfc00) == 0x1000)\r
+    d &= ~0x0100;\r
 \r
-end:\r
-  elprintf(EL_IO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  if (a>=Pico.romsize) {\r
-    lastread_a = a;\r
-    lastread_d[lrp_cyc++&15] = d;\r
+  if ((a & 0xff00) == 0x1100) { // z80 busreq\r
+    d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;\r
+    elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);\r
+    goto end;\r
   }\r
-#endif\r
+\r
+  d = m68k_unmapped_read16(a);\r
+end:\r
   return d;\r
 }\r
-#endif\r
 \r
-// -----------------------------------------------------------------\r
-//                            Write Ram\r
+void PicoWrite8_io(u32 a, u32 d)\r
+{\r
+  if ((a & 0xffe1) == 0x0001) { // I/O ports (verified: only LSB!)\r
+    io_ports_write(a, d);\r
+    return;\r
+  }\r
+  if ((a & 0xff01) == 0x1100) { // z80 busreq\r
+    ctl_write_z80busreq(d);\r
+    return;\r
+  }\r
+  if ((a & 0xff01) == 0x1200) { // z80 reset\r
+    ctl_write_z80reset(d);\r
+    return;\r
+  }\r
+  if (a == 0xa130f1) { // sram access register\r
+    elprintf(EL_SRAMIO, "sram reg=%02x", d);\r
+    Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY);\r
+    Pico.m.sram_status |= (u8)(d & 3);\r
+    return;\r
+  }\r
+  m68k_unmapped_write8(a, d);\r
+}\r
 \r
-#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)\r
-PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)\r
+void PicoWrite16_io(u32 a, u32 d)\r
 {\r
-  elprintf(EL_IO, "w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
+  if ((a & 0xffe0) == 0x0000) { // I/O ports (verified: only LSB!)\r
+    io_ports_write(a, d);\r
+    return;\r
+  }\r
+  if ((a & 0xff00) == 0x1100) { // z80 busreq\r
+    ctl_write_z80busreq(d >> 8);\r
+    return;\r
+  }\r
+  if ((a & 0xff00) == 0x1200) { // z80 reset\r
+    ctl_write_z80reset(d >> 8);\r
+    return;\r
+  }\r
+  if (a == 0xa130f0) { // sram access register\r
+    elprintf(EL_SRAMIO, "sram reg=%02x", d);\r
+    Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY);\r
+    Pico.m.sram_status |= (u8)(d & 3);\r
+    return;\r
+  }\r
+  m68k_unmapped_write16(a, d);\r
+}\r
 \r
-  if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram\r
-  log_io(a, 8, 1);\r
+// VDP area (0xc00000 - 0xdfffff)\r
+// TODO: verify if lower byte goes to PSG on word writes\r
+static u32 PicoRead8_vdp(u32 a)\r
+{\r
+  if ((a & 0x00e0) == 0x0000)\r
+    return PicoVideoRead8(a);\r
 \r
-  a&=0xffffff;\r
-  OtherWrite8(a,d);\r
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);\r
+  return 0;\r
 }\r
-#endif\r
 \r
-void PicoWrite16(u32 a,u16 d)\r
+static u32 PicoRead16_vdp(u32 a)\r
 {\r
-  elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram\r
-  log_io(a, 16, 1);\r
+  if ((a & 0x00e0) == 0x0000)\r
+    return PicoVideoRead(a);\r
 \r
-  a&=0xfffffe;\r
-  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP\r
-  OtherWrite16(a,d);\r
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);\r
+  return 0;\r
 }\r
 \r
-static void PicoWrite32(u32 a,u32 d)\r
+static void PicoWrite8_vdp(u32 a, u32 d)\r
 {\r
-  elprintf(EL_IO, "w32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
-#ifdef EMU_CORE_DEBUG\r
-  lastwrite_cyc_d[lwp_cyc++&15] = d;\r
-#endif\r
-\r
-  if ((a&0xe00000)==0xe00000)\r
-  {\r
-    // Ram:\r
-    u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
-    pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
+  if ((a & 0x00f9) == 0x0011) { // PSG Sound\r
+    if (PicoOpt & POPT_EN_PSG)\r
+      SN76496Write(d);\r
     return;\r
   }\r
-  log_io(a, 32, 1);\r
-\r
-  a&=0xfffffe;\r
-  if ((a&0xe700e0)==0xc00000)\r
-  {\r
-    // VDP:\r
-    PicoVideoWrite(a,  (u16)(d>>16));\r
-    PicoVideoWrite(a+2,(u16)d);\r
+  if ((a & 0x00e0) == 0x0000) {\r
+    d &= 0xff;\r
+    PicoVideoWrite(a, d | (d << 8));\r
     return;\r
   }\r
 \r
-  OtherWrite16(a,  (u16)(d>>16));\r
-  OtherWrite16(a+2,(u16)d);\r
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @%06x", a, d & 0xff, SekPc);\r
 }\r
 \r
+static void PicoWrite16_vdp(u32 a, u32 d)\r
+{\r
+  if ((a & 0x00f9) == 0x0010) { // PSG Sound\r
+    if (PicoOpt & POPT_EN_PSG)\r
+      SN76496Write(d);\r
+    return;\r
+  }\r
+  if ((a & 0x00e0) == 0x0000) {\r
+    PicoVideoWrite(a, d);\r
+    return;\r
+  }\r
+\r
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %04x @%06x", a, d & 0xffff, SekPc);\r
+}\r
 \r
 // -----------------------------------------------------------------\r
 \r
+// TODO: rm\r
 static void OtherWrite16End(u32 a,u32 d,int realsize)\r
 {\r
   PicoWrite8Hook(a,  d>>8, realsize);\r
@@ -520,23 +753,80 @@ static void m68k_mem_setup(void);
 \r
 PICO_INTERNAL void PicoMemSetup(void)\r
 {\r
+  int mask, rs, a;\r
+\r
+  // setup the memory map\r
+  cpu68k_map_set(m68k_read8_map,   0x000000, 0xffffff, m68k_unmapped_read8, 1);\r
+  cpu68k_map_set(m68k_read16_map,  0x000000, 0xffffff, m68k_unmapped_read16, 1);\r
+  cpu68k_map_set(m68k_write8_map,  0x000000, 0xffffff, m68k_unmapped_write8, 1);\r
+  cpu68k_map_set(m68k_write16_map, 0x000000, 0xffffff, m68k_unmapped_write16, 1);\r
+\r
+  // ROM\r
+  // align to bank size. We know ROM loader allocated enough for this\r
+  mask = (1 << M68K_MEM_SHIFT) - 1;\r
+  rs = (Pico.romsize + mask) & ~mask;\r
+  cpu68k_map_set(m68k_read8_map,  0x000000, rs - 1, Pico.rom, 0);\r
+  cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico.rom, 0);\r
+\r
+  // Common case of on-cart (save) RAM, usually at 0x200000-...\r
+  rs = SRam.end - SRam.start;\r
+  if (rs > 0 && SRam.data != NULL) {\r
+    rs = (rs + mask) & ~mask;\r
+    if (SRam.start + rs >= 0x1000000)\r
+      rs = 0x1000000 - SRam.start;\r
+    cpu68k_map_set(m68k_read8_map,   SRam.start, SRam.start + rs - 1, PicoRead8_sram, 1);\r
+    cpu68k_map_set(m68k_read16_map,  SRam.start, SRam.start + rs - 1, PicoRead16_sram, 1);\r
+    cpu68k_map_set(m68k_write8_map,  SRam.start, SRam.start + rs - 1, PicoWrite8_sram, 1);\r
+    cpu68k_map_set(m68k_write16_map, SRam.start, SRam.start + rs - 1, PicoWrite16_sram, 1);\r
+  }\r
+\r
+  // Z80 region\r
+  cpu68k_map_set(m68k_read8_map,   0xa00000, 0xa0ffff, PicoRead8_z80, 1);\r
+  cpu68k_map_set(m68k_read16_map,  0xa00000, 0xa0ffff, PicoRead16_z80, 1);\r
+  cpu68k_map_set(m68k_write8_map,  0xa00000, 0xa0ffff, PicoWrite8_z80, 1);\r
+  cpu68k_map_set(m68k_write16_map, 0xa00000, 0xa0ffff, PicoWrite16_z80, 1);\r
+\r
+  // IO/control region\r
+  cpu68k_map_set(m68k_read8_map,   0xa10000, 0xa1ffff, PicoRead8_io, 1);\r
+  cpu68k_map_set(m68k_read16_map,  0xa10000, 0xa1ffff, PicoRead16_io, 1);\r
+  cpu68k_map_set(m68k_write8_map,  0xa10000, 0xa1ffff, PicoWrite8_io, 1);\r
+  cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_io, 1);\r
+\r
+  // VDP region\r
+  for (a = 0xc00000; a < 0xe00000; a += 0x010000) {\r
+    if ((a & 0xe700e0) != 0xc00000)\r
+      continue;\r
+    cpu68k_map_set(m68k_read8_map,   a, a + 0xffff, PicoRead8_vdp, 1);\r
+    cpu68k_map_set(m68k_read16_map,  a, a + 0xffff, PicoRead16_vdp, 1);\r
+    cpu68k_map_set(m68k_write8_map,  a, a + 0xffff, PicoWrite8_vdp, 1);\r
+    cpu68k_map_set(m68k_write16_map, a, a + 0xffff, PicoWrite16_vdp, 1);\r
+  }\r
+\r
+  // RAM and it's mirrors\r
+  for (a = 0xe00000; a < 0x1000000; a += 0x010000) {\r
+    cpu68k_map_set(m68k_read8_map,   a, a + 0xffff, Pico.ram, 0);\r
+    cpu68k_map_set(m68k_read16_map,  a, a + 0xffff, Pico.ram, 0);\r
+    cpu68k_map_set(m68k_write8_map,  a, a + 0xffff, Pico.ram, 0);\r
+    cpu68k_map_set(m68k_write16_map, a, a + 0xffff, Pico.ram, 0);\r
+  }\r
+\r
   // Setup memory callbacks:\r
 #ifdef EMU_C68K\r
-  PicoCpuCM68k.checkpc=PicoCheckPc;\r
-  PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoRead8;\r
-  PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoRead16;\r
-  PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoRead32;\r
-  PicoCpuCM68k.write8 =PicoWrite8;\r
-  PicoCpuCM68k.write16=PicoWrite16;\r
-  PicoCpuCM68k.write32=PicoWrite32;\r
+  PicoCpuCM68k.checkpc = PicoCheckPc;\r
+  PicoCpuCM68k.fetch8  = PicoCpuCM68k.read8  = m68k_read8;\r
+  PicoCpuCM68k.fetch16 = PicoCpuCM68k.read16 = m68k_read16;\r
+  PicoCpuCM68k.fetch32 = PicoCpuCM68k.read32 = m68k_read32;\r
+  PicoCpuCM68k.write8  = m68k_write8;\r
+  PicoCpuCM68k.write16 = m68k_write16;\r
+  PicoCpuCM68k.write32 = m68k_write32;\r
 #endif\r
 #ifdef EMU_F68K\r
-  PicoCpuFM68k.read_byte =PicoRead8;\r
-  PicoCpuFM68k.read_word =PicoRead16;\r
-  PicoCpuFM68k.read_long =PicoRead32;\r
-  PicoCpuFM68k.write_byte=PicoWrite8;\r
-  PicoCpuFM68k.write_word=PicoWrite16;\r
-  PicoCpuFM68k.write_long=PicoWrite32;\r
+  PicoCpuFM68k.read_byte  = m68k_read8;\r
+  PicoCpuFM68k.read_word  = m68k_read16;\r
+  PicoCpuFM68k.read_long  = m68k_read32;\r
+  PicoCpuFM68k.write_byte = m68k_write8;\r
+  PicoCpuFM68k.write_word = m68k_write16;\r
+  PicoCpuFM68k.write_long = m68k_write32;\r
 \r
   // setup FAME fetchmap\r
   {\r
@@ -676,12 +966,12 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) { pm68k_writ
 \r
 static void m68k_mem_setup(void)\r
 {\r
-  pm68k_read_memory_8  = PicoRead8;\r
-  pm68k_read_memory_16 = PicoRead16;\r
-  pm68k_read_memory_32 = PicoRead32;\r
-  pm68k_write_memory_8  = PicoWrite8;\r
-  pm68k_write_memory_16 = PicoWrite16;\r
-  pm68k_write_memory_32 = PicoWrite32;\r
+  pm68k_read_memory_8  = m68k_read8;\r
+  pm68k_read_memory_16 = m68k_read16;\r
+  pm68k_read_memory_32 = m68k_read32;\r
+  pm68k_write_memory_8  = m68k_write8;\r
+  pm68k_write_memory_16 = m68k_write16;\r
+  pm68k_write_memory_32 = m68k_write32;\r
   pm68k_read_memory_pcr_8  = m68k_read_memory_pcr_8;\r
   pm68k_read_memory_pcr_16 = m68k_read_memory_pcr_16;\r
   pm68k_read_memory_pcr_32 = m68k_read_memory_pcr_32;\r
@@ -747,7 +1037,7 @@ void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new)
 }\r
 \r
 // ym2612 DAC and timer I/O handlers for z80\r
-int ym2612_write_local(u32 a, u32 d, int is_from_z80)\r
+static int ym2612_write_local(u32 a, u32 d, int is_from_z80)\r
 {\r
   int addr;\r
 \r
@@ -893,7 +1183,7 @@ static u32 MEMH_FUNC ym2612_read_local_z80(void)
   return ym2612.OPN.ST.status;\r
 }\r
 \r
-u32 ym2612_read_local_68k(void)\r
+static u32 ym2612_read_local_68k(void)\r
 {\r
   int xcycles = cycles_68k_to_z80(SekCyclesDone()) << 8;\r
 \r
@@ -1001,10 +1291,8 @@ static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a)
     goto out;\r
   }\r
 \r
+  ret = m68k_read8(addr68k);\r
   elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret);\r
-  if (PicoAHW & PAHW_MCD)\r
-       ret = PicoReadM68k8(addr68k);\r
-  else ret = PicoRead8(addr68k);\r
 \r
 out:\r
   elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret);\r
@@ -1047,9 +1335,7 @@ static void MEMH_FUNC z80_md_bank_write(unsigned int a, unsigned char data)
   addr68k += a & 0x7fff;\r
 \r
   elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data);\r
-  if (PicoAHW & PAHW_MCD)\r
-       PicoWriteM68k8(addr68k, data);\r
-  else PicoWrite8(addr68k, data);\r
+  m68k_write8(addr68k, data);\r
 }\r
 \r
 // -----------------------------------------------------------------\r
@@ -1065,7 +1351,7 @@ static void z80_md_out(unsigned short p, unsigned char d)
   elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d);\r
 }\r
 \r
-void z80_mem_setup(void)\r
+static void z80_mem_setup(void)\r
 {\r
   z80_map_set(z80_read_map, 0x0000, 0x1fff, Pico.zram, 0);\r
   z80_map_set(z80_read_map, 0x2000, 0x3fff, Pico.zram, 0);\r
diff --git a/pico/memory.h b/pico/memory.h
new file mode 100644 (file)
index 0000000..63c5163
--- /dev/null
@@ -0,0 +1,116 @@
+// memory map related stuff
+
+typedef unsigned char  u8;
+typedef unsigned short u16;
+typedef unsigned int   u32;
+
+#define M68K_MEM_SHIFT 16
+
+extern unsigned long m68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
+extern unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
+extern unsigned long m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
+extern unsigned long m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
+
+extern unsigned long s68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
+extern unsigned long s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
+extern unsigned long s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
+extern unsigned long s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
+
+void z80_map_set(unsigned long *map, int start_addr, int end_addr,
+    void *func_or_mh, int is_func);
+void cpu68k_map_set(unsigned long *map, int start_addr, int end_addr,
+    void *func_or_mh, int is_func);
+void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub);
+void m68k_map_unmap(int start_addr, int end_addr);
+
+// top-level handlers that cores can use
+// (or alternatively build them into themselves)
+// XXX: unhandled: *16 and *32 might cross the bank boundaries
+typedef u32  (cpu68k_read_f)(u32 a);
+typedef void (cpu68k_write_f)(u32 a, u32 d);
+
+#define MAKE_68K_READ8(name, map)               \
+u32 name(u32 a)                                 \
+{                                               \
+  unsigned long v;                              \
+  a &= 0x00ffffff;                              \
+  v = map[a >> M68K_MEM_SHIFT];                 \
+  if (v & 0x80000000)                           \
+    return ((cpu68k_read_f *)(v << 1))(a);      \
+  else                                          \
+    return *(u8 *)((v << 1) + (a ^ 1));         \
+}
+
+#define MAKE_68K_READ16(name, map)              \
+u32 name(u32 a)                                 \
+{                                               \
+  unsigned long v;                              \
+  a &= 0x00fffffe;                              \
+  v = map[a >> M68K_MEM_SHIFT];                 \
+  if (v & 0x80000000)                           \
+    return ((cpu68k_read_f *)(v << 1))(a);      \
+  else                                          \
+    return *(u16 *)((v << 1) + a);              \
+}
+
+#define MAKE_68K_READ32(name, map)              \
+u32 name(u32 a)                                 \
+{                                               \
+  unsigned long v, vs;                          \
+  u32 d;                                        \
+  a &= 0x00fffffe;                              \
+  v = map[a >> M68K_MEM_SHIFT];                 \
+  vs = v << 1;                                  \
+  if (v & 0x80000000) {                         \
+    d  = ((cpu68k_read_f *)vs)(a) << 16;        \
+    d |= ((cpu68k_read_f *)vs)(a + 2);          \
+  }                                             \
+  else {                                        \
+    u16 *m = (u16 *)(vs + a);                   \
+    d = (m[0] << 16) | m[1];                    \
+  }                                             \
+  return d;                                     \
+}
+
+#define MAKE_68K_WRITE8(name, map)              \
+void name(u32 a, u8 d)                          \
+{                                               \
+  unsigned long v;                              \
+  a &= 0x00ffffff;                              \
+  v = map[a >> M68K_MEM_SHIFT];                 \
+  if (v & 0x80000000)                           \
+    ((cpu68k_write_f *)(v << 1))(a, d);         \
+  else                                          \
+    *(u8 *)((v << 1) + (a ^ 1)) = d;            \
+}
+
+#define MAKE_68K_WRITE16(name, map)             \
+void name(u32 a, u16 d)                         \
+{                                               \
+  unsigned long v;                              \
+  a &= 0x00fffffe;                              \
+  v = map[a >> M68K_MEM_SHIFT];                 \
+  if (v & 0x80000000)                           \
+    ((cpu68k_write_f *)(v << 1))(a, d);         \
+  else                                          \
+    *(u16 *)((v << 1) + a) = d;                 \
+}
+
+#define MAKE_68K_WRITE32(name, map)             \
+void name(u32 a, u32 d)                         \
+{                                               \
+  unsigned long v, vs;                          \
+  a &= 0x00fffffe;                              \
+  v = map[a >> M68K_MEM_SHIFT];                 \
+  vs = v << 1;                                  \
+  if (v & 0x80000000) {                         \
+    ((cpu68k_write_f *)vs)(a, d >> 16);         \
+    ((cpu68k_write_f *)vs)(a + 2, d);           \
+  }                                             \
+  else {                                        \
+    u16 *m = (u16 *)(vs + a);                   \
+    m[0] = d >> 16;                             \
+    m[1] = d;                                   \
+  }                                             \
+}
+
diff --git a/pico/memory_cmn.c b/pico/memory_cmn.c
deleted file mode 100644 (file)
index 266f807..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-// common code for Memory.c and cd/Memory.c
-// (c) Copyright 2006-2007, Grazvydas "notaz" Ignotas
-
-#ifndef UTYPES_DEFINED
-typedef unsigned char  u8;
-typedef unsigned short u16;
-typedef unsigned int   u32;
-#define UTYPES_DEFINED
-#endif
-
-
-#ifndef _ASM_MEMORY_C
-static
-#endif
-u8 z80Read8(u32 a)
-{
-  if(Pico.m.z80Run&1) return 0;
-
-  a&=0x1fff;
-
-  if (!(PicoOpt&POPT_EN_Z80))
-  {
-    // 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 z80ReadBusReq(void)
-{
-  u32 d = (Pico.m.z80Run | Pico.m.z80_reset) & 1;
-  elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d|0x80, SekCyclesDone(), SekPc);
-  return d|0x80;
-}
-
-static void z80WriteBusReq(u32 d)
-{
-  d&=1; d^=1;
-  elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc);
-  if (d ^ Pico.m.z80Run)
-  {
-    if (d)
-    {
-      z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());
-    }
-    else
-    {
-      z80stopCycle = SekCyclesDone();
-      if ((PicoOpt&POPT_EN_Z80) && !Pico.m.z80_reset)
-        PicoSyncZ80(z80stopCycle);
-    }
-    Pico.m.z80Run=d;
-  }
-}
-
-static void z80WriteReset(u32 d)
-{
-  d&=1; d^=1;
-  elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc);
-  if (d ^ Pico.m.z80_reset)
-  {
-    if (d)
-    {
-      if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run)
-        PicoSyncZ80(SekCyclesDone());
-    }
-    else
-    {
-      z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());
-      z80_reset();
-    }
-    YM2612ResetChip();
-    timers_reset();
-    Pico.m.z80_reset=d;
-  }
-}
-
-#ifndef _ASM_MEMORY_C
-static
-#endif
-u32 OtherRead16(u32 a, int realsize)
-{
-  u32 d=0;
-
-  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); break;
-      case 2:  d=PadRead(1); break;
-      default: d=Pico.ioports[a]; break; // IO ports can be used as RAM
-    }
-    d|=d<<8;
-    goto end;
-  }
-
-  // rotate fakes next fetched instruction for Time Killers
-  if (a==0xa11100) { // z80 busreq
-    d=(z80ReadBusReq()<<8)|Pico.m.rotate++;
-    goto end;
-  }
-
-  if ((a&0xff0000)==0xa00000)
-  {
-    if (Pico.m.z80Run&1)
-      elprintf(EL_ANOMALY, "68k z80 read with no bus! [%06x] @ %06x", a, SekPc);
-    if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped)
-    if ((a&0x6000)==0x4000) { d=ym2612_read_local_68k(); goto end; } // 0x4000-0x5fff
-
-    elprintf(EL_ANOMALY, "68k bad read [%06x]", a);
-    d=0xffff;
-    goto end;
-  }
-
-  d = PicoRead16Hook(a, realsize);
-
-end:
-  return d;
-}
-
-static void IoWrite8(u32 a, u32 d)
-{
-  a=(a>>1)&0xf;
-  // 6 button gamepad: if TH went from 0 to 1, gamepad changes state
-  if (PicoOpt&POPT_6BTN_PAD)
-  {
-    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
-}
-
-#ifndef _ASM_CD_MEMORY_C
-static
-#endif
-void OtherWrite8(u32 a,u32 d)
-{
-#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)
-  if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound
-  if ((a&0xff4000)==0xa00000) { // z80 RAM
-    SekCyclesBurn(2); // hack
-    if (!(Pico.m.z80Run&1) && !Pico.m.z80_reset) Pico.zram[a&0x1fff]=(u8)d;
-    else elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %02x @ %06x", a, d&0xff, SekPc);
-    return;
-  }
-  if ((a&0xff6000)==0xa04000)  { if(PicoOpt&1) emustatus|=ym2612_write_local(a&3, d&0xff, 0)&1; return; } // FM Sound
-  if ((a&0xffffe0)==0xa10000)  { IoWrite8(a, d); return; } // I/O ports
-#endif
-  if (a==0xa11100)             { z80WriteBusReq(d); return; }
-  if (a==0xa11200)             { z80WriteReset(d);  return; }
-
-#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)
-  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
-    elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k<<15);
-    return;
-  }
-#endif
-  if ((a&0xe700e0)==0xc00000) {
-    d&=0xff;
-    PicoVideoWrite(a,(u16)(d|(d<<8))); // Byte access gets mirrored
-    return;
-  }
-
-  PicoWrite8Hook(a, d&0xff, 8);
-}
-
-
-#ifndef _ASM_CD_MEMORY_C
-static
-#endif
-void OtherWrite16(u32 a,u32 d)
-{
-  if (a==0xa11100)            { z80WriteBusReq(d>>8); return; }
-  if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports
-  if ((a&0xe700f8)==0xc00010||(a&0xff7ff8)==0xa07f10) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound
-  if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=ym2612_write_local(a&3, d&0xff, 0)&1; return; } // FM Sound
-  if ((a&0xff4000)==0xa00000) { // Z80 ram (MSB only)
-    if (!(Pico.m.z80Run&1) && !Pico.m.z80_reset) Pico.zram[a&0x1fff]=(u8)(d>>8);
-    else elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %04x @ %06x", a, d&0xffff, SekPc);
-    return;
-  }
-  if (a==0xa11200)             { z80WriteReset(d>>8); 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
-    elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k<<15);
-    return;
-  }
-
-#ifndef _CD_MEMORY_C
-  if (a >= SRam.start && a <= SRam.end) {
-    elprintf(EL_SRAMIO, "sram w16 [%06x] %04x @ %06x", a, d, SekPc);
-    if ((Pico.m.sram_reg&0x16)==0x10) { // detected, not EEPROM, write not disabled
-      u8 *pm=(u8 *)(SRam.data-SRam.start+a);
-      *pm++=d>>8;
-      *pm++=d;
-      SRam.changed = 1;
-    }
-    else
-      SRAMWrite(a, d);
-    return;
-  }
-#endif
-
-  PicoWrite16Hook(a, d&0xffff, 16);
-}
-
index 014ffa1..0ce1489 100644 (file)
@@ -95,11 +95,11 @@ const unsigned char hcounts_32[] = {
 \r
 unsigned int lastSSRamWrite = 0xffff0000;\r
 \r
-// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),\r
+// sram_status: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),\r
 //                      d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)\r
-PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
+PICO_INTERNAL void EEPROM_write(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
 {\r
-  unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;\r
+  unsigned int sreg = Pico.m.sram_status, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;\r
 \r
   elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1,\r
     (d&2)>>1, d&1, SekCyclesDoneT()-lastSSRamWrite);\r
@@ -197,21 +197,21 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
   }\r
 \r
   sreg &= ~3; sreg |= d&3; // remember SCL and SDA\r
-  Pico.m.sram_reg    = (unsigned char) sreg;\r
+  Pico.m.sram_status    = (unsigned char) sreg;\r
   Pico.m.eeprom_cycle= (unsigned char) scyc;\r
   Pico.m.eeprom_slave= (unsigned char) ssa;\r
   Pico.m.eeprom_addr = (unsigned short)saddr;\r
 }\r
 \r
-PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)\r
+PICO_INTERNAL_ASM unsigned int EEPROM_read(void)\r
 {\r
   unsigned int shift, d;\r
   unsigned int sreg, saddr, scyc, ssa, interval;\r
 \r
   // flush last pending write\r
-  SRAMWriteEEPROM(Pico.m.sram_reg>>6);\r
+  EEPROM_write(Pico.m.sram_status>>6);\r
 \r
-  sreg = Pico.m.sram_reg; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;\r
+  sreg = Pico.m.sram_status; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;\r
   interval = SekCyclesDoneT()-lastSSRamWrite;\r
   d = (sreg>>6)&1; // use SDA as "open bus"\r
 \r
@@ -250,9 +250,9 @@ PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)
   return (d << SRam.eeprom_bit_out);\r
 }\r
 \r
-PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)\r
+PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d)\r
 {\r
-  unsigned int d1, sreg = Pico.m.sram_reg;\r
+  unsigned int d1, sreg = Pico.m.sram_status;\r
 \r
   if (!((SRam.eeprom_abits^a)&1))\r
   {\r
@@ -269,7 +269,7 @@ PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)
     sreg |= d1<<6;\r
   }\r
 \r
-  Pico.m.sram_reg = (unsigned char) sreg;\r
+  Pico.m.sram_status = (unsigned char) sreg;\r
 }\r
 \r
 \r
index dc5c91f..99632dd 100644 (file)
@@ -303,7 +303,8 @@ void PicoPatchPrepare(void)
        for (i = 0; i < PicoPatchCount; i++)
        {
                PicoPatches[i].addr &= ~1;
-               PicoPatches[i].data_old = PicoRead16(PicoPatches[i].addr);
+               if (PicoPatches[i].addr < Pico.romsize)
+                       PicoPatches[i].data_old = *(unsigned short *)(Pico.rom + PicoPatches[i].addr);
                if (strstr(PicoPatches[i].name, "AUTO"))
                        PicoPatches[i].active = 1;
        }
@@ -333,9 +334,7 @@ void PicoPatchApply(void)
                }
                else
                {
-                       /* RAM or some other weird patch */
-                       if (PicoPatches[i].active)
-                               PicoWrite16(addr, PicoPatches[i].data);
+                       /* TODO? */
                }
        }
 }
index 9b390c7..ab2302e 100644 (file)
@@ -57,7 +57,7 @@ void PicoExit(void)
 \r
 void PicoPower(void)\r
 {\r
-  unsigned char sram_reg=Pico.m.sram_reg; // must be preserved\r
+  unsigned char sram_status = Pico.m.sram_status; // must be preserved\r
 \r
   Pico.m.frame_count = 0;\r
 \r
@@ -78,7 +78,7 @@ void PicoPower(void)
   if (PicoAHW & PAHW_MCD)\r
     PicoPowerMCD();\r
 \r
-  Pico.m.sram_reg=sram_reg;\r
+  Pico.m.sram_status = sram_status;\r
   PicoReset();\r
 }\r
 \r
@@ -94,14 +94,16 @@ PICO_INTERNAL void PicoDetectRegion(void)
   else\r
   {\r
     // Read cartridge region data:\r
-    int region=PicoRead32(0x1f0);\r
+    unsigned short *rd = (unsigned short *)(Pico.rom + 0x1f0);\r
+    int region = (rd[0] << 16) | rd[1];\r
 \r
-    for (i=0;i<4;i++)\r
+    for (i = 0; i < 4; i++)\r
     {\r
-      int c=0;\r
+      int c;\r
 \r
-      c=region>>(i<<3); c&=0xff;\r
-      if (c<=' ') continue;\r
+      c = region >> (i<<3);\r
+      c &= 0xff;\r
+      if (c <= ' ') continue;\r
 \r
            if (c=='J')  support|=1;\r
       else if (c=='U')  support|=4;\r
@@ -139,7 +141,7 @@ PICO_INTERNAL void PicoDetectRegion(void)
 \r
 int PicoReset(void)\r
 {\r
-  unsigned char sram_reg=Pico.m.sram_reg; // must be preserved\r
+  unsigned char sram_status = Pico.m.sram_status; // must be preserved\r
 \r
   if (Pico.romsize <= 0)\r
     return 1;\r
@@ -148,7 +150,6 @@ int PicoReset(void)
   if (PicoResetHook)\r
     PicoResetHook();\r
 \r
-  PicoMemReset();\r
   memset(&PicoPadInt,0,sizeof(PicoPadInt));\r
   emustatus = 0;\r
 \r
@@ -169,6 +170,7 @@ int PicoReset(void)
   Pico.m.dirtyPal = 1;\r
 \r
   Pico.m.z80_bank68k = 0;\r
+  Pico.m.z80_reset = 1;\r
   memset(Pico.zram, 0, sizeof(Pico.zram)); // ??\r
 \r
   PicoDetectRegion();\r
@@ -192,11 +194,12 @@ int PicoReset(void)
     SekInitIdleDet();\r
 \r
   // reset sram state; enable sram access by default if it doesn't overlap with ROM\r
-  Pico.m.sram_reg=sram_reg&0x14;\r
-  if (!(Pico.m.sram_reg&4) && Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1;\r
+  Pico.m.sram_status = sram_status & (SRS_DETECTED|SRS_EEPROM);\r
+  if (!(Pico.m.sram_status & SRS_EEPROM) && Pico.romsize <= SRam.start)\r
+    Pico.m.sram_status |= SRS_MAPPED;\r
 \r
   elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x",\r
-    (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end);\r
+    !!(sram_status & SRS_DETECTED), !!(sram_status & SRS_EEPROM), SRam.start, SRam.end);\r
 \r
   return 0;\r
 }\r
index b5f4a95..8c72bba 100644 (file)
@@ -255,7 +255,7 @@ struct PicoMisc
   char dirtyPal;               // 06 Is the palette dirty (1 - change @ this frame, 2 - some time before)\r
   unsigned char hardware;      // 07 Hardware value for country\r
   unsigned char pal;           // 08 1=PAL 0=NTSC\r
-  unsigned char sram_reg;      // SRAM mode register. bit0: allow read? bit1: deny write? bit2: EEPROM? bit4: detected? (header or by access)\r
+  unsigned char sram_status;   // 09 SRAM status. See SRS_* below\r
   unsigned short z80_bank68k;  // 0a\r
   unsigned short z80_lastaddr; // this is for Z80 faking\r
   unsigned char  z80_fakeval;\r
@@ -293,6 +293,11 @@ struct Pico
 };\r
 \r
 // sram\r
+#define SRS_MAPPED   (1 << 0)\r
+#define SRS_READONLY (1 << 1)\r
+#define SRS_EEPROM   (1 << 2)\r
+#define SRS_DETECTED (1 << 4)\r
+\r
 struct PicoSRAM\r
 {\r
   unsigned char *data;         // actual data\r
@@ -435,26 +440,24 @@ void PicoDrawSetColorFormatMode4(int which);
 // memory.c\r
 PICO_INTERNAL void PicoInitPc(unsigned int pc);\r
 PICO_INTERNAL unsigned int PicoCheckPc(unsigned int pc);\r
-PICO_INTERNAL_ASM unsigned int PicoRead32(unsigned int a);\r
 PICO_INTERNAL void PicoMemSetup(void);\r
-PICO_INTERNAL_ASM void PicoMemReset(void);\r
 PICO_INTERNAL void PicoMemResetHooks(void);\r
-PICO_INTERNAL int PadRead(int i);\r
-PICO_INTERNAL int ym2612_write_local(unsigned int a, unsigned int d, int is_from_z80);\r
-void z80_mem_setup(void);\r
 extern unsigned int (*PicoRead16Hook)(unsigned int a, int realsize);\r
 extern void (*PicoWrite8Hook) (unsigned int a,unsigned int d,int realsize);\r
 extern void (*PicoWrite16Hook)(unsigned int a,unsigned int d,int realsize);\r
+unsigned int PicoRead8_io(unsigned int a);\r
+unsigned int PicoRead16_io(unsigned int a);\r
+void PicoWrite8_io(unsigned int a, unsigned int d);\r
+void PicoWrite16_io(unsigned int a, unsigned int d);\r
+\r
+// pico/memory.c\r
+PICO_INTERNAL void PicoMemSetupPico(void);\r
 \r
 // cd/memory.c\r
 PICO_INTERNAL void PicoMemSetupCD(void);\r
-PICO_INTERNAL_ASM void PicoMemResetCD(int r3);\r
+PICO_INTERNAL_ASM void PicoMemRemapCD(int r3);\r
 PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3);\r
 \r
-// pico/memory.c\r
-PICO_INTERNAL void PicoMemSetupPico(void);\r
-PICO_INTERNAL unsigned int ym2612_read_local_68k(void);\r
-\r
 // pico.c\r
 extern struct Pico Pico;\r
 extern struct PicoSRAM SRam;\r
@@ -534,9 +537,9 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead8(unsigned int a);
 extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp);\r
 \r
 // misc.c\r
-PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d);\r
-PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d);\r
-PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void);\r
+PICO_INTERNAL void EEPROM_write(unsigned int d);\r
+PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d);\r
+PICO_INTERNAL_ASM unsigned int EEPROM_read(void);\r
 PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count);\r
 PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count);\r
 PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count); // 32bit word count\r
@@ -548,8 +551,6 @@ PICO_INTERNAL void z80_pack(unsigned char *data);
 PICO_INTERNAL void z80_unpack(unsigned char *data);\r
 PICO_INTERNAL void z80_reset(void);\r
 PICO_INTERNAL void z80_exit(void);\r
-void z80_map_set(unsigned long *map, int start_addr,\r
-  int end_addr, void *func_or_mh, int is_func);\r
 \r
 // cd/misc.c\r
 PICO_INTERNAL_ASM void wram_2M_to_1M(unsigned char *m);\r
@@ -595,6 +596,8 @@ void PicoFrameDrawOnlyMS(void);
 #define EL_SVP     0x00004000 /* SVP stuff */\r
 #define EL_PICOHW  0x00008000 /* Pico stuff */\r
 #define EL_IDLE    0x00010000 /* idle loop det. */\r
+#define EL_CDREGS  0x00020000 /* MCD: register access */\r
+#define EL_CDREG3  0x00040000 /* MCD: register 3 only */\r
 \r
 #define EL_STATUS  0x40000000 /* status messages */\r
 #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */\r
index e483291..dfe7769 100644 (file)
@@ -9,6 +9,7 @@
  * - H counter
  */
 #include "pico_int.h"
+#include "memory.h"
 #include "sound/sn76496.h"
 
 static unsigned char vdp_data_read(void)
index b1204e2..6e0db26 100644 (file)
@@ -107,14 +107,9 @@ static void dac_recalculate(void)
 \r
 PICO_INTERNAL void PsndReset(void)\r
 {\r
-  void *ym2612_regs;\r
-\r
-  // also clear the internal registers+addr line\r
-  ym2612_regs = YM2612GetRegs();\r
-  memset(ym2612_regs, 0, 0x200+4);\r
-  timers_reset();\r
-\r
+  // PsndRerate calls YM2612Init, which also resets\r
   PsndRerate(0);\r
+  timers_reset();\r
 }\r
 \r
 \r
index 1b35e50..63b79da 100644 (file)
@@ -6,32 +6,6 @@
 unsigned long z80_read_map [0x10000 >> Z80_MEM_SHIFT];
 unsigned long z80_write_map[0x10000 >> Z80_MEM_SHIFT];
 
-void MEMH_FUNC z80_map_set(unsigned long *map, int start_addr, int end_addr,
-    void *func_or_mh, int is_func)
-{
-  unsigned long addr = (unsigned long)func_or_mh;
-  int mask = (1 << Z80_MEM_SHIFT) - 1;
-  int i;
-
-  if ((start_addr & mask) != 0 || (end_addr & mask) != mask)
-    elprintf(EL_STATUS|EL_ANOMALY, "z80_map_set: tried to map bad range: %04x-%04x",
-      start_addr, end_addr);
-
-  if (addr & 1) {
-    elprintf(EL_STATUS|EL_ANOMALY, "z80_map_set: ptr is not aligned: %08lx", addr);
-    return;
-  }
-
-  if (!is_func)
-    addr -= (start_addr >> Z80_MEM_SHIFT) << Z80_MEM_SHIFT;
-
-  for (i = start_addr >> Z80_MEM_SHIFT; i <= end_addr >> Z80_MEM_SHIFT; i++) {
-    map[i] = addr >> 1;
-    if (is_func)
-      map[i] |= 1 << (sizeof(addr) * 8 - 1);
-  }
-}
-
 #ifdef _USE_MZ80
 
 // memhandlers for mz80 core
index 79b61fb..397e713 100644 (file)
@@ -48,7 +48,7 @@ mkdirs:
 # deps
 pico/carthw/svp/compiler.o : ../../pico/carthw/svp/ssp16.o ../../pico/carthw/svp/gen_arm.c
 pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
-pico/memory.o pico/cd/memory.o : ../../pico/memory_cmn.c ../../pico/pico_int.h
+pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
 
 # build Cyclone
 ../../cpu/Cyclone/proj/Cyclone.s:
index 4a95a3f..4fcb792 100644 (file)
@@ -989,7 +989,8 @@ int emu_save_load_game(int load, int sram)
                        }\r
                } else {\r
                        sram_size = SRam.end-SRam.start+1;\r
-                       if(Pico.m.sram_reg & 4) sram_size=0x2000;\r
+                       if (Pico.m.sram_status & SRS_EEPROM)\r
+                               sram_size = 0x2000;\r
                        sram_data = SRam.data;\r
                }\r
                if (!sram_data) return 0; // SRam forcefully disabled for this game\r
index 03093e3..2e92875 100644 (file)
@@ -1,7 +1,11 @@
 platform/common/menu.o : revision.h
 
 revision.h: FORCE
+ifndef NOREVISION
        @echo "#define REVISION \"`svn info -r HEAD | grep Revision | cut -c 11-`\"" > /tmp/r.tmp
+else
+       @echo "#define REVISION \"0\"" > /tmp/r.tmp
+endif
        @diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@
 
 FORCE:
index 92e5d97..ef63199 100644 (file)
@@ -3,12 +3,12 @@ export CROSS = arm-linux-
 # settings\r
 #mz80 = 1\r
 #debug_cyclone = 1\r
-asm_memory = 1\r
+#asm_memory = 1 # TODO\r
 asm_render = 1\r
 asm_ym2612 = 1\r
 asm_misc = 1\r
 asm_cdpico = 1\r
-asm_cdmemory = 1\r
+#asm_cdmemory = 1 # TODO\r
 amalgamate = 0\r
 #profile = 1\r
 #use_musashi = 1\r
index 033d3bd..2202db2 100644 (file)
@@ -103,7 +103,7 @@ include ../common/revision.mak
 
 pico/carthw/svp/compiler.o : ../../pico/carthw/svp/gen_arm.c
 pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
-pico/memory.o pico/cd/memory.o : ../../pico/memory_cmn.c ../../pico/pico_int.h
+pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
 
 ../../cpu/musashi/m68kops.c :
        @make -C ../../cpu/musashi