Преглед на файлове

new memory handling, but asm and mappers need update.
Some cleanup and magic bit removal as a bonus.


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

notaz преди 14 години
родител
ревизия
af37bca858
променени са 20 файла, в които са добавени 908 реда и са изтрити 1416 реда
  1. 16 14
      pico/cart.c
  2. 3 3
      pico/cd/area.c
  3. 188 843
      pico/cd/memory.c
  4. 2 2
      pico/cd/pico.c
  5. 2 2
      pico/debug.c
  6. 521 235
      pico/memory.c
  7. 116 0
      pico/memory.h
  8. 0 237
      pico/memory_cmn.c
  9. 10 10
      pico/misc.c
  10. 3 4
      pico/patch.c
  11. 15 12
      pico/pico.c
  12. 19 16
      pico/pico_int.h
  13. 1 0
      pico/sms.c
  14. 2 7
      pico/sound/sound.c
  15. 0 26
      pico/z80if.c
  16. 1 1
      platform/common/common_arm.mak
  17. 2 1
      platform/common/emu.c
  18. 4 0
      platform/common/revision.mak
  19. 2 2
      platform/gp2x/Makefile
  20. 1 1
      platform/linux/Makefile

+ 16 - 14
pico/cart.c

@@ -572,13 +572,10 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
   PicoLoadStateHook = NULL;
   carthw_chunks = NULL;
 
-  PicoMemReset();
-
   if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))
     PicoCartDetect();
 
   // setup correct memory map for loaded ROM
-  // call PicoMemReset again due to possible memmap change
   switch (PicoAHW) {
     default:
       elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoAHW);
@@ -588,7 +585,6 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
     case PAHW_PICO: PicoMemSetupPico(); break;
     case PAHW_SMS:  PicoMemSetupMS(); break;
   }
-  PicoMemReset();
 
   if (PicoAHW & PAHW_SMS)
     PicoPowerMS();
@@ -627,6 +623,12 @@ static int name_cmp(const char *name)
   return rom_strcmp(0x150, name);
 }
 
+static unsigned int rom_read32(int addr)
+{
+  unsigned short *m = (unsigned short *)(Pico.rom + addr);
+  return (m[0] << 16) | m[1];
+}
+
 /*
  * various cart-specific things, which can't be handled by generic code
  * (maybe I should start using CRC for this stuff?)
@@ -634,28 +636,28 @@ static int name_cmp(const char *name)
 static void PicoCartDetect(void)
 {
   int sram_size = 0, csum;
-  Pico.m.sram_reg = 0;
+  Pico.m.sram_status = 0;
 
-  csum = PicoRead32(0x18c) & 0xffff;
+  csum = rom_read32(0x18c) & 0xffff;
 
   if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A')
   {
     if (Pico.rom[0x1B2] & 0x40)
     {
       // EEPROM
-      SRam.start = PicoRead32(0x1B4) & ~1; // zero address is used for clock by some games
-      SRam.end   = PicoRead32(0x1B8);
+      SRam.start = rom_read32(0x1B4) & ~1; // zero address is used for clock by some games
+      SRam.end   = rom_read32(0x1B8);
       sram_size  = 0x2000;
-      Pico.m.sram_reg |= 4;
+      Pico.m.sram_status |= SRS_EEPROM;
     } else {
       // normal SRAM
-      SRam.start = PicoRead32(0x1B4) & ~0xff;
-      SRam.end   = PicoRead32(0x1B8) | 1;
+      SRam.start = rom_read32(0x1B4) & ~0xff;
+      SRam.end   = rom_read32(0x1B8) | 1;
       sram_size  = SRam.end - SRam.start + 1;
     }
     SRam.start &= ~0xff000000;
     SRam.end   &= ~0xff000000;
-    Pico.m.sram_reg |= 0x10; // SRAM was detected
+    Pico.m.sram_status |= SRS_DETECTED;
   }
   if (sram_size <= 0)
   {
@@ -713,7 +715,7 @@ static void PicoCartDetect(void)
            name_cmp("RINGS OF POWER") == 0)
   {
     SRam.start = SRam.end = 0x200000;
-    Pico.m.sram_reg = 0x14;
+    Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM;
     SRam.eeprom_abits = 0;
     SRam.eeprom_bit_cl = 6;
     SRam.eeprom_bit_in = 7;
@@ -725,7 +727,7 @@ static void PicoCartDetect(void)
   {
     SRam.start = 0x300000;
     SRam.end   = 0x380001;
-    Pico.m.sram_reg = 0x14;
+    Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM;
     SRam.eeprom_type = 2;
     SRam.eeprom_abits = 0;
     SRam.eeprom_bit_cl = 1;

+ 3 - 3
pico/cd/area.c

@@ -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))

Файловите разлики са ограничени, защото са твърде много
+ 188 - 843
pico/cd/memory.c


+ 2 - 2
pico/cd/pico.c

@@ -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);
   }

+ 2 - 2
pico/debug.c

@@ -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)

+ 521 - 235
pico/memory.c

@@ -1,32 +1,148 @@
 // This is part of Pico Library
 
 // (c) Copyright 2004 Dave, All rights reserved.
-// (c) Copyright 2006,2007 notaz, All rights reserved.
+// (c) Copyright 2006-2009 notaz, All rights reserved.
 // Free for non-commercial use.
 
 // For commercial use, separate licencing terms must be obtained.
 
 
 #include "pico_int.h"
+#include "memory.h"
 
 #include "sound/ym2612.h"
 #include "sound/sn76496.h"
 
-#ifndef UTYPES_DEFINED
-typedef unsigned char  u8;
-typedef unsigned short u16;
-typedef unsigned int   u32;
-#define UTYPES_DEFINED
-#endif
-
 extern unsigned int lastSSRamWrite; // used by serial eeprom code
 
-#ifdef _ASM_MEMORY_C
-u32  PicoRead8(u32 a);
-u32  PicoRead16(u32 a);
-void PicoWrite8(u32 a,u8 d);
-void PicoWriteRomHW_SSF2(u32 a,u32 d);
-#endif
+unsigned long m68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
+unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
+unsigned long m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
+unsigned long m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
+
+static void xmap_set(unsigned long *map, int shift, int start_addr, int end_addr,
+    void *func_or_mh, int is_func)
+{
+  unsigned long addr = (unsigned long)func_or_mh;
+  int mask = (1 << shift) - 1;
+  int i;
+
+  if ((start_addr & mask) != 0 || (end_addr & mask) != mask) {
+    elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: tried to map bad range: %06x-%06x",
+      start_addr, end_addr);
+    return;
+  }
+
+  if (addr & 1) {
+    elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: ptr is not aligned: %08lx", addr);
+    return;
+  }
+
+  if (!is_func)
+    addr -= start_addr;
+
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++) {
+    map[i] = addr >> 1;
+    if (is_func)
+      map[i] |= 1 << (sizeof(addr) * 8 - 1);
+  }
+}
+
+void z80_map_set(unsigned long *map, int start_addr, int end_addr,
+    void *func_or_mh, int is_func)
+{
+  xmap_set(map, Z80_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func);
+}
+
+void cpu68k_map_set(unsigned long *map, int start_addr, int end_addr,
+    void *func_or_mh, int is_func)
+{
+  xmap_set(map, M68K_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func);
+}
+
+// more specialized/optimized function (does same as above)
+void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub)
+{
+  unsigned long *r8map, *r16map, *w8map, *w16map;
+  unsigned long addr = (unsigned long)ptr;
+  int shift = M68K_MEM_SHIFT;
+  int i;
+
+  if (!is_sub) {
+    r8map = m68k_read8_map;
+    r16map = m68k_read16_map;
+    w8map = m68k_write8_map;
+    w16map = m68k_write16_map;
+  } else {
+    r8map = s68k_read8_map;
+    r16map = s68k_read16_map;
+    w8map = s68k_write8_map;
+    w16map = s68k_write16_map;
+  }
+
+  addr -= start_addr;
+  addr >>= 1;
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)
+    r8map[i] = r16map[i] = w8map[i] = w16map[i] = addr;
+}
+
+static u32 m68k_unmapped_read8(u32 a)
+{
+  elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);
+  return 0; // assume pulldown, as if MegaCD2 was attached
+}
+
+static u32 m68k_unmapped_read16(u32 a)
+{
+  elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
+  return 0;
+}
+
+static void m68k_unmapped_write8(u32 a, u32 d)
+{
+  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
+}
+
+static void m68k_unmapped_write16(u32 a, u32 d)
+{
+  elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+}
+
+void m68k_map_unmap(int start_addr, int end_addr)
+{
+  unsigned long addr;
+  int shift = M68K_MEM_SHIFT;
+  int i;
+
+  addr = (unsigned long)m68k_unmapped_read8;
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)
+    m68k_read8_map[i] = (addr >> 1) | (1 << 31);
+
+  addr = (unsigned long)m68k_unmapped_read16;
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)
+    m68k_read16_map[i] = (addr >> 1) | (1 << 31);
+
+  addr = (unsigned long)m68k_unmapped_write8;
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)
+    m68k_write8_map[i] = (addr >> 1) | (1 << 31);
+
+  addr = (unsigned long)m68k_unmapped_write16;
+  for (i = start_addr >> shift; i <= end_addr >> shift; i++)
+    m68k_write16_map[i] = (addr >> 1) | (1 << 31);
+}
+
+MAKE_68K_READ8(m68k_read8, m68k_read8_map)
+MAKE_68K_READ16(m68k_read16, m68k_read16_map)
+MAKE_68K_READ32(m68k_read32, m68k_read16_map)
+MAKE_68K_WRITE8(m68k_write8, m68k_write8_map)
+MAKE_68K_WRITE16(m68k_write16, m68k_write16_map)
+MAKE_68K_WRITE32(m68k_write32, m68k_write16_map)
+
+// -----------------------------------------------------------------
+
+static u32 ym2612_read_local_68k(void);
+static int ym2612_write_local(u32 a, u32 d, int is_from_z80);
+static void z80_mem_setup(void);
 
 
 #ifdef EMU_CORE_DEBUG
@@ -95,15 +211,10 @@ PICO_INTERNAL void PicoInitPc(u32 pc)
   PicoCheckPc(pc);
 }
 
-#ifndef _ASM_MEMORY_C
-PICO_INTERNAL_ASM void PicoMemReset(void)
-{
-}
-#endif
-
 // -----------------------------------------------------------------
+// memmap helpers
 
-int PadRead(int i)
+static int PadRead(int i)
 {
   int pad,value,data_reg;
   pad=~PicoPadInt[i]; // Get inverse of pad MXYZ SACB RLDU
@@ -135,77 +246,80 @@ int PadRead(int i)
   return value; // will mirror later
 }
 
-
-#ifndef _ASM_MEMORY_C
-static
-#endif
-u32 SRAMRead(u32 a)
+static u32 io_ports_read(u32 a)
 {
-  unsigned int sreg = Pico.m.sram_reg;
-  if (!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM
-    elprintf(EL_SRAMIO, "normal sram detected.");
-    Pico.m.sram_reg|=0x10; // should be normal SRAM
+  u32 d;
+  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
   }
-  if (sreg & 4) // EEPROM read
-    return SRAMReadEEPROM();
-  else // if(sreg & 1) // (sreg&5) is one of prerequisites
-    return *(u8 *)(SRam.data-SRam.start+a);
+  return d;
 }
 
-#ifndef _ASM_MEMORY_C
-static
-#endif
-u32 SRAMRead16(u32 a)
+static void io_ports_write(u32 a, u32 d)
 {
-  u32 d;
-  if (Pico.m.sram_reg & 4) {
-    d = SRAMReadEEPROM();
-    d |= d << 8;
-  } else {
-    u8 *pm=(u8 *)(SRam.data-SRam.start+a);
-    d =*pm++ << 8;
-    d|=*pm++;
+  a = (a>>1) & 0xf;
+
+  // 6 button gamepad: if TH went from 0 to 1, gamepad changes state
+  if (1 <= a && a <= 2 && (PicoOpt & POPT_6BTN_PAD))
+  {
+    Pico.m.padDelay[a - 1] = 0;
+    if (!(Pico.ioports[a] & 0x40) && (d & 0x40))
+      Pico.m.padTHPhase[a - 1]++;
   }
-  return d;
+
+  // cartain IO ports can be used as RAM
+  Pico.ioports[a] = d;
 }
 
-static void SRAMWrite(u32 a, u32 d)
+static void ctl_write_z80busreq(u32 d)
 {
-  unsigned int sreg = Pico.m.sram_reg;
-  if(!(sreg & 0x10)) {
-    // not detected SRAM
-    if((a&~1)==0x200000) {
-      elprintf(EL_SRAMIO, "eeprom detected.");
-      sreg|=4; // this should be a game with EEPROM (like NBA Jam)
-      SRam.start=0x200000; SRam.end=SRam.start+1;
-    } else
-      elprintf(EL_SRAMIO, "normal sram detected.");
-    sreg|=0x10;
-    Pico.m.sram_reg=sreg;
+  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;
   }
-  if(sreg & 4) { // EEPROM write
-    // this diff must be at most 16 for NBA Jam to work
-    if(SekCyclesDoneT()-lastSSRamWrite < 16) {
-      // just update pending state
-      elprintf(EL_EEPROM, "eeprom: skip because cycles=%i", SekCyclesDoneT()-lastSSRamWrite);
-      SRAMUpdPending(a, d);
-    } else {
-      int old=sreg;
-      SRAMWriteEEPROM(sreg>>6); // execute pending
-      SRAMUpdPending(a, d);
-      if ((old^Pico.m.sram_reg)&0xc0) // update time only if SDA/SCL changed
-        lastSSRamWrite = SekCyclesDoneT();
+}
+
+static void ctl_write_z80reset(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());
+      YM2612ResetChip();
+      timers_reset();
     }
-  } else if(!(sreg & 2)) {
-    u8 *pm=(u8 *)(SRam.data-SRam.start+a);
-    if(*pm != (u8)d) {
-      SRam.changed = 1;
-      *pm=(u8)d;
+    else
+    {
+      z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone());
+      z80_reset();
     }
+    Pico.m.z80_reset = d;
   }
 }
 
+
 // for nonstandard reads
+// TODO: mv to carthw
 static u32 OtherRead16End(u32 a, int realsize)
 {
   u32 d=0;
@@ -283,18 +397,8 @@ end:
   return d;
 }
 
-
-//extern UINT32 mz80GetRegisterValue(void *, UINT32);
-
 static void OtherWrite8End(u32 a,u32 d,int realsize)
 {
-  // sram
-  if(a >= SRam.start && a <= SRam.end) {
-    elprintf(EL_SRAMIO, "sram w8  [%06x] %02x @ %06x", a, d, SekPc);
-    SRAMWrite(a, d);
-    return;
-  }
-
 #ifdef _ASM_MEMORY_C
   // special ROM hardware (currently only banking and sram reg supported)
   if((a&0xfffff1) == 0xA130F1) {
@@ -305,8 +409,8 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
   // sram access register
   if(a == 0xA130F1) {
     elprintf(EL_SRAMIO, "sram reg=%02x", d);
-    Pico.m.sram_reg &= ~3;
-    Pico.m.sram_reg |= (u8)(d&3);
+    Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY);
+    Pico.m.sram_status |= (u8)(d&3);
     return;
   }
 #endif
@@ -317,185 +421,314 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
     Pico.m.prot_bytes[(a>>2)&1] = (u8)d;
 }
 
-#include "memory_cmn.c"
+// -----------------------------------------------------------------
 
+// cart (save) RAM area (usually 0x200000 - ...)
+static u32 PicoRead8_sram(u32 a)
+{
+  int srs = Pico.m.sram_status;
+  u32 d;
+  if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM)))
+  {
+    if (srs & SRS_EEPROM)
+      d = EEPROM_read();
+    else
+      d = *(u8 *)(SRam.data - SRam.start + a);
+    elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);
+    return d;
+  }
 
-// -----------------------------------------------------------------
-//                     Read Rom and read Ram
+  if (a < Pico.romsize)
+    return Pico.rom[a ^ 1];
+  
+  return m68k_unmapped_read8(a);
+}
 
-#ifndef _ASM_MEMORY_C
-PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
+static u32 PicoRead16_sram(u32 a)
 {
-  u32 d=0;
+  int srs = Pico.m.sram_status;
+  u32 d;
+  if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM)))
+  {
+    if (srs & SRS_EEPROM) {
+      d = EEPROM_read();
+      d |= d << 8;
+    } else {
+      u8 *pm = (u8 *)(SRam.data - SRam.start + a);
+      d  = pm[0] << 8;
+      d |= pm[1];
+    }
+    elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);
+    return d;
+  }
 
-  if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram
+  if (a < Pico.romsize)
+    return *(u16 *)(Pico.rom + a);
 
-  a&=0xffffff;
+  return m68k_unmapped_read16(a);
+}
 
-#ifndef EMU_CORE_DEBUG
-  // sram
-  if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
-    d = SRAMRead(a);
-    elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);
-    goto end;
+static void PicoWrite8_sram(u32 a, u32 d)
+{
+  unsigned int srs = Pico.m.sram_status;
+  elprintf(EL_SRAMIO, "sram wX  [%06x] %02x @ %06x", a, d & 0xffff, SekPc);
+  if (srs & SRS_EEPROM) // EEPROM write
+  {
+    // this diff must be at most 16 for NBA Jam to work
+    if (SekCyclesDoneT() - lastSSRamWrite < 16) {
+      // just update pending state
+      elprintf(EL_EEPROM, "eeprom: skip because cycles=%i",
+          SekCyclesDoneT() - lastSSRamWrite);
+      EEPROM_upd_pending(a, d);
+    } else {
+      EEPROM_write(srs >> 6); // execute pending
+      EEPROM_upd_pending(a, d);
+      if ((srs ^ Pico.m.sram_status) & 0xc0) // update time only if SDA/SCL changed
+        lastSSRamWrite = SekCyclesDoneT();
+    }
   }
-#endif
+  else if (!(srs & SRS_READONLY)) {
+    u8 *pm=(u8 *)(SRam.data - SRam.start + a);
+    if (*pm != (u8)d) {
+      SRam.changed = 1;
+      *pm = (u8)d;
+    }
+  }
+}
 
-  if (a<Pico.romsize) { d = *(u8 *)(Pico.rom+(a^1)); goto end; } // Rom
-  log_io(a, 8, 0);
-  if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
+static void PicoWrite16_sram(u32 a, u32 d)
+{
+  // XXX: hardware could easily use MSB too..
+  PicoWrite8_sram(a + 1, d);
+}
 
-  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP
+// z80 area (0xa00000 - 0xa0ffff)
+// TODO: verify mirrors VDP and bank reg (bank area mirroring verified)
+static u32 PicoRead8_z80(u32 a)
+{
+  u32 d = 0xff;
+  if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {
+    elprintf(EL_ANOMALY, "68k z80 read with no bus! [%06x] @ %06x", a, SekPc);
+    // open bus. Pulled down if MegaCD2 is attached.
+    return 0;
+  }
 
-  d=OtherRead16(a&~1, 8);
-  if ((a&1)==0) d>>=8;
+  if ((a & 0x4000) == 0x0000)
+    d = Pico.zram[a & 0x1fff];
+  else if ((a & 0x6000) == 0x4000) // 0x4000-0x5fff
+    d = ym2612_read_local_68k(); 
+  else
+    elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
+  return d;
+}
 
-end:
-  elprintf(EL_IO, "r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPc);
-#ifdef EMU_CORE_DEBUG
-  if (a>=Pico.romsize) {
-    lastread_a = a;
-    lastread_d[lrp_cyc++&15] = (u8)d;
+static u32 PicoRead16_z80(u32 a)
+{
+  u32 d = PicoRead8_z80(a);
+  return d | (d << 8);
+}
+
+static void PicoWrite8_z80(u32 a, u32 d)
+{
+  if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {
+    // verified on real hw
+    elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %02x @ %06x", a, d&0xff, SekPc);
+    return;
+  }
+
+  if ((a & 0x4000) == 0x0000) { // z80 RAM
+    SekCyclesBurn(2); // hack
+    Pico.zram[a & 0x1fff] = (u8)d;
+    return;
+  }
+  if ((a & 0x6000) == 0x4000) { // FM Sound
+    if (PicoOpt & POPT_EN_FM)
+      emustatus |= ym2612_write_local(a&3, d&0xff, 0)&1;
+    return;
+  }
+  // TODO: probably other VDP access too? Maybe more mirrors?
+  if ((a & 0x7ff9) == 0x7f11) { // PSG Sound
+    if (PicoOpt & POPT_EN_PSG)
+      SN76496Write(d);
+    return;
+  }
+#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)
+  if ((a & 0x7f00) == 0x6000) // Z80 BANK register
+  {
+    Pico.m.z80_bank68k >>= 1;
+    Pico.m.z80_bank68k |= d << 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
-  return d;
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @ %06x", a, d&0xff, SekPc);
 }
 
-PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
+static void PicoWrite16_z80(u32 a, u32 d)
 {
-  u32 d=0;
-
-  if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram
+  // for RAM, only most significant byte is sent
+  // TODO: verify remaining accesses
+  PicoWrite8_z80(a, d >> 8);
+}
 
-  a&=0xfffffe;
+// IO/control area (0xa10000 - 0xa1ffff)
+u32 PicoRead8_io(u32 a)
+{
+  u32 d;
 
-#ifndef EMU_CORE_DEBUG
-  // sram
-  if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
-    d = SRAMRead16(a);
-    elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);
+  if ((a & 0xffe0) == 0x0000) { // I/O ports
+    d = io_ports_read(a);
     goto end;
   }
-#endif
 
-  if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
-  log_io(a, 16, 0);
+  // faking open bus (MegaCD pulldowns don't work here curiously)
+  d = Pico.m.rotate++;
+  d ^= d << 6;
 
-  if ((a&0xe700e0)==0xc00000)
-       d = PicoVideoRead(a);
-  else d = OtherRead16(a, 16);
+  // bit8 seems to be readable in this range
+  if ((a & 0xfc01) == 0x1000)
+    d &= ~0x01;
 
-end:
-  elprintf(EL_IO, "r16: %06x, %04x  @%06x", a&0xffffff, d, SekPc);
-#ifdef EMU_CORE_DEBUG
-  if (a>=Pico.romsize) {
-    lastread_a = a;
-    lastread_d[lrp_cyc++&15] = d;
+  if ((a & 0xff01) == 0x1100) { // z80 busreq (verified)
+    d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1;
+    elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc);
+    goto end;
   }
-#endif
+
+  d = m68k_unmapped_read8(a);
+end:
   return d;
 }
 
-PICO_INTERNAL_ASM u32 PicoRead32(u32 a)
+u32 PicoRead16_io(u32 a)
 {
-  u32 d=0;
-
-  if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram
-
-  a&=0xfffffe;
+  u32 d;
 
-  // sram
-  if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
-    d = (SRAMRead16(a)<<16)|SRAMRead16(a+2);
-    elprintf(EL_SRAMIO, "sram r32 [%06x] %08x @ %06x", a, d, SekPc);
+  if ((a & 0xffe0) == 0x0000) { // I/O ports
+    d = io_ports_read(a);
     goto end;
   }
 
-  if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
-  log_io(a, 32, 0);
+  // faking open bus
+  d = (Pico.m.rotate += 0x41);
+  d ^= (d << 5) ^ (d << 8);
 
-  if ((a&0xe700e0)==0xc00000)
-       d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
-  else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
+  // bit8 seems to be readable in this range
+  if ((a & 0xfc00) == 0x1000)
+    d &= ~0x0100;
 
-end:
-  elprintf(EL_IO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
-#ifdef EMU_CORE_DEBUG
-  if (a>=Pico.romsize) {
-    lastread_a = a;
-    lastread_d[lrp_cyc++&15] = d;
+  if ((a & 0xff00) == 0x1100) { // z80 busreq
+    d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8;
+    elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc);
+    goto end;
   }
-#endif
+
+  d = m68k_unmapped_read16(a);
+end:
   return d;
 }
-#endif
 
-// -----------------------------------------------------------------
-//                            Write Ram
+void PicoWrite8_io(u32 a, u32 d)
+{
+  if ((a & 0xffe1) == 0x0001) { // I/O ports (verified: only LSB!)
+    io_ports_write(a, d);
+    return;
+  }
+  if ((a & 0xff01) == 0x1100) { // z80 busreq
+    ctl_write_z80busreq(d);
+    return;
+  }
+  if ((a & 0xff01) == 0x1200) { // z80 reset
+    ctl_write_z80reset(d);
+    return;
+  }
+  if (a == 0xa130f1) { // sram access register
+    elprintf(EL_SRAMIO, "sram reg=%02x", d);
+    Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY);
+    Pico.m.sram_status |= (u8)(d & 3);
+    return;
+  }
+  m68k_unmapped_write8(a, d);
+}
 
-#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS)
-PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)
+void PicoWrite16_io(u32 a, u32 d)
 {
-  elprintf(EL_IO, "w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPc);
-#ifdef EMU_CORE_DEBUG
-  lastwrite_cyc_d[lwp_cyc++&15] = d;
-#endif
+  if ((a & 0xffe0) == 0x0000) { // I/O ports (verified: only LSB!)
+    io_ports_write(a, d);
+    return;
+  }
+  if ((a & 0xff00) == 0x1100) { // z80 busreq
+    ctl_write_z80busreq(d >> 8);
+    return;
+  }
+  if ((a & 0xff00) == 0x1200) { // z80 reset
+    ctl_write_z80reset(d >> 8);
+    return;
+  }
+  if (a == 0xa130f0) { // sram access register
+    elprintf(EL_SRAMIO, "sram reg=%02x", d);
+    Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY);
+    Pico.m.sram_status |= (u8)(d & 3);
+    return;
+  }
+  m68k_unmapped_write16(a, d);
+}
 
-  if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram
-  log_io(a, 8, 1);
+// VDP area (0xc00000 - 0xdfffff)
+// TODO: verify if lower byte goes to PSG on word writes
+static u32 PicoRead8_vdp(u32 a)
+{
+  if ((a & 0x00e0) == 0x0000)
+    return PicoVideoRead8(a);
 
-  a&=0xffffff;
-  OtherWrite8(a,d);
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
+  return 0;
 }
-#endif
 
-void PicoWrite16(u32 a,u16 d)
+static u32 PicoRead16_vdp(u32 a)
 {
-  elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d);
-#ifdef EMU_CORE_DEBUG
-  lastwrite_cyc_d[lwp_cyc++&15] = d;
-#endif
-
-  if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram
-  log_io(a, 16, 1);
+  if ((a & 0x00e0) == 0x0000)
+    return PicoVideoRead(a);
 
-  a&=0xfffffe;
-  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
-  OtherWrite16(a,d);
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
+  return 0;
 }
 
-static void PicoWrite32(u32 a,u32 d)
+static void PicoWrite8_vdp(u32 a, u32 d)
 {
-  elprintf(EL_IO, "w32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
-#ifdef EMU_CORE_DEBUG
-  lastwrite_cyc_d[lwp_cyc++&15] = d;
-#endif
-
-  if ((a&0xe00000)==0xe00000)
-  {
-    // Ram:
-    u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));
-    pm[0]=(u16)(d>>16); pm[1]=(u16)d;
+  if ((a & 0x00f9) == 0x0011) { // PSG Sound
+    if (PicoOpt & POPT_EN_PSG)
+      SN76496Write(d);
     return;
   }
-  log_io(a, 32, 1);
-
-  a&=0xfffffe;
-  if ((a&0xe700e0)==0xc00000)
-  {
-    // VDP:
-    PicoVideoWrite(a,  (u16)(d>>16));
-    PicoVideoWrite(a+2,(u16)d);
+  if ((a & 0x00e0) == 0x0000) {
+    d &= 0xff;
+    PicoVideoWrite(a, d | (d << 8));
     return;
   }
 
-  OtherWrite16(a,  (u16)(d>>16));
-  OtherWrite16(a+2,(u16)d);
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @%06x", a, d & 0xff, SekPc);
 }
 
+static void PicoWrite16_vdp(u32 a, u32 d)
+{
+  if ((a & 0x00f9) == 0x0010) { // PSG Sound
+    if (PicoOpt & POPT_EN_PSG)
+      SN76496Write(d);
+    return;
+  }
+  if ((a & 0x00e0) == 0x0000) {
+    PicoVideoWrite(a, d);
+    return;
+  }
+
+  elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+}
 
 // -----------------------------------------------------------------
 
+// TODO: rm
 static void OtherWrite16End(u32 a,u32 d,int realsize)
 {
   PicoWrite8Hook(a,  d>>8, realsize);
@@ -520,23 +753,80 @@ static void m68k_mem_setup(void);
 
 PICO_INTERNAL void PicoMemSetup(void)
 {
+  int mask, rs, a;
+
+  // setup the memory map
+  cpu68k_map_set(m68k_read8_map,   0x000000, 0xffffff, m68k_unmapped_read8, 1);
+  cpu68k_map_set(m68k_read16_map,  0x000000, 0xffffff, m68k_unmapped_read16, 1);
+  cpu68k_map_set(m68k_write8_map,  0x000000, 0xffffff, m68k_unmapped_write8, 1);
+  cpu68k_map_set(m68k_write16_map, 0x000000, 0xffffff, m68k_unmapped_write16, 1);
+
+  // ROM
+  // align to bank size. We know ROM loader allocated enough for this
+  mask = (1 << M68K_MEM_SHIFT) - 1;
+  rs = (Pico.romsize + mask) & ~mask;
+  cpu68k_map_set(m68k_read8_map,  0x000000, rs - 1, Pico.rom, 0);
+  cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico.rom, 0);
+
+  // Common case of on-cart (save) RAM, usually at 0x200000-...
+  rs = SRam.end - SRam.start;
+  if (rs > 0 && SRam.data != NULL) {
+    rs = (rs + mask) & ~mask;
+    if (SRam.start + rs >= 0x1000000)
+      rs = 0x1000000 - SRam.start;
+    cpu68k_map_set(m68k_read8_map,   SRam.start, SRam.start + rs - 1, PicoRead8_sram, 1);
+    cpu68k_map_set(m68k_read16_map,  SRam.start, SRam.start + rs - 1, PicoRead16_sram, 1);
+    cpu68k_map_set(m68k_write8_map,  SRam.start, SRam.start + rs - 1, PicoWrite8_sram, 1);
+    cpu68k_map_set(m68k_write16_map, SRam.start, SRam.start + rs - 1, PicoWrite16_sram, 1);
+  }
+
+  // Z80 region
+  cpu68k_map_set(m68k_read8_map,   0xa00000, 0xa0ffff, PicoRead8_z80, 1);
+  cpu68k_map_set(m68k_read16_map,  0xa00000, 0xa0ffff, PicoRead16_z80, 1);
+  cpu68k_map_set(m68k_write8_map,  0xa00000, 0xa0ffff, PicoWrite8_z80, 1);
+  cpu68k_map_set(m68k_write16_map, 0xa00000, 0xa0ffff, PicoWrite16_z80, 1);
+
+  // IO/control region
+  cpu68k_map_set(m68k_read8_map,   0xa10000, 0xa1ffff, PicoRead8_io, 1);
+  cpu68k_map_set(m68k_read16_map,  0xa10000, 0xa1ffff, PicoRead16_io, 1);
+  cpu68k_map_set(m68k_write8_map,  0xa10000, 0xa1ffff, PicoWrite8_io, 1);
+  cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_io, 1);
+
+  // VDP region
+  for (a = 0xc00000; a < 0xe00000; a += 0x010000) {
+    if ((a & 0xe700e0) != 0xc00000)
+      continue;
+    cpu68k_map_set(m68k_read8_map,   a, a + 0xffff, PicoRead8_vdp, 1);
+    cpu68k_map_set(m68k_read16_map,  a, a + 0xffff, PicoRead16_vdp, 1);
+    cpu68k_map_set(m68k_write8_map,  a, a + 0xffff, PicoWrite8_vdp, 1);
+    cpu68k_map_set(m68k_write16_map, a, a + 0xffff, PicoWrite16_vdp, 1);
+  }
+
+  // RAM and it's mirrors
+  for (a = 0xe00000; a < 0x1000000; a += 0x010000) {
+    cpu68k_map_set(m68k_read8_map,   a, a + 0xffff, Pico.ram, 0);
+    cpu68k_map_set(m68k_read16_map,  a, a + 0xffff, Pico.ram, 0);
+    cpu68k_map_set(m68k_write8_map,  a, a + 0xffff, Pico.ram, 0);
+    cpu68k_map_set(m68k_write16_map, a, a + 0xffff, Pico.ram, 0);
+  }
+
   // Setup memory callbacks:
 #ifdef EMU_C68K
-  PicoCpuCM68k.checkpc=PicoCheckPc;
-  PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoRead8;
-  PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoRead16;
-  PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoRead32;
-  PicoCpuCM68k.write8 =PicoWrite8;
-  PicoCpuCM68k.write16=PicoWrite16;
-  PicoCpuCM68k.write32=PicoWrite32;
+  PicoCpuCM68k.checkpc = PicoCheckPc;
+  PicoCpuCM68k.fetch8  = PicoCpuCM68k.read8  = m68k_read8;
+  PicoCpuCM68k.fetch16 = PicoCpuCM68k.read16 = m68k_read16;
+  PicoCpuCM68k.fetch32 = PicoCpuCM68k.read32 = m68k_read32;
+  PicoCpuCM68k.write8  = m68k_write8;
+  PicoCpuCM68k.write16 = m68k_write16;
+  PicoCpuCM68k.write32 = m68k_write32;
 #endif
 #ifdef EMU_F68K
-  PicoCpuFM68k.read_byte =PicoRead8;
-  PicoCpuFM68k.read_word =PicoRead16;
-  PicoCpuFM68k.read_long =PicoRead32;
-  PicoCpuFM68k.write_byte=PicoWrite8;
-  PicoCpuFM68k.write_word=PicoWrite16;
-  PicoCpuFM68k.write_long=PicoWrite32;
+  PicoCpuFM68k.read_byte  = m68k_read8;
+  PicoCpuFM68k.read_word  = m68k_read16;
+  PicoCpuFM68k.read_long  = m68k_read32;
+  PicoCpuFM68k.write_byte = m68k_write8;
+  PicoCpuFM68k.write_word = m68k_write16;
+  PicoCpuFM68k.write_long = m68k_write32;
 
   // setup FAME fetchmap
   {
@@ -676,12 +966,12 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) { pm68k_writ
 
 static void m68k_mem_setup(void)
 {
-  pm68k_read_memory_8  = PicoRead8;
-  pm68k_read_memory_16 = PicoRead16;
-  pm68k_read_memory_32 = PicoRead32;
-  pm68k_write_memory_8  = PicoWrite8;
-  pm68k_write_memory_16 = PicoWrite16;
-  pm68k_write_memory_32 = PicoWrite32;
+  pm68k_read_memory_8  = m68k_read8;
+  pm68k_read_memory_16 = m68k_read16;
+  pm68k_read_memory_32 = m68k_read32;
+  pm68k_write_memory_8  = m68k_write8;
+  pm68k_write_memory_16 = m68k_write16;
+  pm68k_write_memory_32 = m68k_write32;
   pm68k_read_memory_pcr_8  = m68k_read_memory_pcr_8;
   pm68k_read_memory_pcr_16 = m68k_read_memory_pcr_16;
   pm68k_read_memory_pcr_32 = m68k_read_memory_pcr_32;
@@ -747,7 +1037,7 @@ void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new)
 }
 
 // ym2612 DAC and timer I/O handlers for z80
-int ym2612_write_local(u32 a, u32 d, int is_from_z80)
+static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
 {
   int addr;
 
@@ -893,7 +1183,7 @@ static u32 MEMH_FUNC ym2612_read_local_z80(void)
   return ym2612.OPN.ST.status;
 }
 
-u32 ym2612_read_local_68k(void)
+static u32 ym2612_read_local_68k(void)
 {
   int xcycles = cycles_68k_to_z80(SekCyclesDone()) << 8;
 
@@ -1001,10 +1291,8 @@ static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a)
     goto out;
   }
 
+  ret = m68k_read8(addr68k);
   elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret);
-  if (PicoAHW & PAHW_MCD)
-       ret = PicoReadM68k8(addr68k);
-  else ret = PicoRead8(addr68k);
 
 out:
   elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret);
@@ -1047,9 +1335,7 @@ static void MEMH_FUNC z80_md_bank_write(unsigned int a, unsigned char data)
   addr68k += a & 0x7fff;
 
   elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data);
-  if (PicoAHW & PAHW_MCD)
-       PicoWriteM68k8(addr68k, data);
-  else PicoWrite8(addr68k, data);
+  m68k_write8(addr68k, data);
 }
 
 // -----------------------------------------------------------------
@@ -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);
 }
 
-void z80_mem_setup(void)
+static void z80_mem_setup(void)
 {
   z80_map_set(z80_read_map, 0x0000, 0x1fff, Pico.zram, 0);
   z80_map_set(z80_read_map, 0x2000, 0x3fff, Pico.zram, 0);

+ 116 - 0
pico/memory.h

@@ -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;                                   \
+  }                                             \
+}
+

+ 0 - 237
pico/memory_cmn.c

@@ -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);
-}
-

+ 10 - 10
pico/misc.c

@@ -95,11 +95,11 @@ const unsigned char hcounts_32[] = {
 
 unsigned int lastSSRamWrite = 0xffff0000;
 
-// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),
+// sram_status: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),
 //                      d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)
-PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
+PICO_INTERNAL void EEPROM_write(unsigned int d) // ???? ??la (l=SCL, a=SDA)
 {
-  unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;
+  unsigned int sreg = Pico.m.sram_status, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;
 
   elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1,
     (d&2)>>1, d&1, SekCyclesDoneT()-lastSSRamWrite);
@@ -197,21 +197,21 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
   }
 
   sreg &= ~3; sreg |= d&3; // remember SCL and SDA
-  Pico.m.sram_reg    = (unsigned char) sreg;
+  Pico.m.sram_status    = (unsigned char) sreg;
   Pico.m.eeprom_cycle= (unsigned char) scyc;
   Pico.m.eeprom_slave= (unsigned char) ssa;
   Pico.m.eeprom_addr = (unsigned short)saddr;
 }
 
-PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)
+PICO_INTERNAL_ASM unsigned int EEPROM_read(void)
 {
   unsigned int shift, d;
   unsigned int sreg, saddr, scyc, ssa, interval;
 
   // flush last pending write
-  SRAMWriteEEPROM(Pico.m.sram_reg>>6);
+  EEPROM_write(Pico.m.sram_status>>6);
 
-  sreg = Pico.m.sram_reg; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;
+  sreg = Pico.m.sram_status; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;
   interval = SekCyclesDoneT()-lastSSRamWrite;
   d = (sreg>>6)&1; // use SDA as "open bus"
 
@@ -250,9 +250,9 @@ PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)
   return (d << SRam.eeprom_bit_out);
 }
 
-PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)
+PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d)
 {
-  unsigned int d1, sreg = Pico.m.sram_reg;
+  unsigned int d1, sreg = Pico.m.sram_status;
 
   if (!((SRam.eeprom_abits^a)&1))
   {
@@ -269,7 +269,7 @@ PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)
     sreg |= d1<<6;
   }
 
-  Pico.m.sram_reg = (unsigned char) sreg;
+  Pico.m.sram_status = (unsigned char) sreg;
 }
 
 

+ 3 - 4
pico/patch.c

@@ -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? */
 		}
 	}
 }

+ 15 - 12
pico/pico.c

@@ -57,7 +57,7 @@ void PicoExit(void)
 
 void PicoPower(void)
 {
-  unsigned char sram_reg=Pico.m.sram_reg; // must be preserved
+  unsigned char sram_status = Pico.m.sram_status; // must be preserved
 
   Pico.m.frame_count = 0;
 
@@ -78,7 +78,7 @@ void PicoPower(void)
   if (PicoAHW & PAHW_MCD)
     PicoPowerMCD();
 
-  Pico.m.sram_reg=sram_reg;
+  Pico.m.sram_status = sram_status;
   PicoReset();
 }
 
@@ -94,14 +94,16 @@ PICO_INTERNAL void PicoDetectRegion(void)
   else
   {
     // Read cartridge region data:
-    int region=PicoRead32(0x1f0);
+    unsigned short *rd = (unsigned short *)(Pico.rom + 0x1f0);
+    int region = (rd[0] << 16) | rd[1];
 
-    for (i=0;i<4;i++)
+    for (i = 0; i < 4; i++)
     {
-      int c=0;
+      int c;
 
-      c=region>>(i<<3); c&=0xff;
-      if (c<=' ') continue;
+      c = region >> (i<<3);
+      c &= 0xff;
+      if (c <= ' ') continue;
 
            if (c=='J')  support|=1;
       else if (c=='U')  support|=4;
@@ -139,7 +141,7 @@ PICO_INTERNAL void PicoDetectRegion(void)
 
 int PicoReset(void)
 {
-  unsigned char sram_reg=Pico.m.sram_reg; // must be preserved
+  unsigned char sram_status = Pico.m.sram_status; // must be preserved
 
   if (Pico.romsize <= 0)
     return 1;
@@ -148,7 +150,6 @@ int PicoReset(void)
   if (PicoResetHook)
     PicoResetHook();
 
-  PicoMemReset();
   memset(&PicoPadInt,0,sizeof(PicoPadInt));
   emustatus = 0;
 
@@ -169,6 +170,7 @@ int PicoReset(void)
   Pico.m.dirtyPal = 1;
 
   Pico.m.z80_bank68k = 0;
+  Pico.m.z80_reset = 1;
   memset(Pico.zram, 0, sizeof(Pico.zram)); // ??
 
   PicoDetectRegion();
@@ -192,11 +194,12 @@ int PicoReset(void)
     SekInitIdleDet();
 
   // reset sram state; enable sram access by default if it doesn't overlap with ROM
-  Pico.m.sram_reg=sram_reg&0x14;
-  if (!(Pico.m.sram_reg&4) && Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1;
+  Pico.m.sram_status = sram_status & (SRS_DETECTED|SRS_EEPROM);
+  if (!(Pico.m.sram_status & SRS_EEPROM) && Pico.romsize <= SRam.start)
+    Pico.m.sram_status |= SRS_MAPPED;
 
   elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x",
-    (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end);
+    !!(sram_status & SRS_DETECTED), !!(sram_status & SRS_EEPROM), SRam.start, SRam.end);
 
   return 0;
 }

+ 19 - 16
pico/pico_int.h

@@ -255,7 +255,7 @@ struct PicoMisc
   char dirtyPal;               // 06 Is the palette dirty (1 - change @ this frame, 2 - some time before)
   unsigned char hardware;      // 07 Hardware value for country
   unsigned char pal;           // 08 1=PAL 0=NTSC
-  unsigned char sram_reg;      // SRAM mode register. bit0: allow read? bit1: deny write? bit2: EEPROM? bit4: detected? (header or by access)
+  unsigned char sram_status;   // 09 SRAM status. See SRS_* below
   unsigned short z80_bank68k;  // 0a
   unsigned short z80_lastaddr; // this is for Z80 faking
   unsigned char  z80_fakeval;
@@ -293,6 +293,11 @@ struct Pico
 };
 
 // sram
+#define SRS_MAPPED   (1 << 0)
+#define SRS_READONLY (1 << 1)
+#define SRS_EEPROM   (1 << 2)
+#define SRS_DETECTED (1 << 4)
+
 struct PicoSRAM
 {
   unsigned char *data;		// actual data
@@ -435,26 +440,24 @@ void PicoDrawSetColorFormatMode4(int which);
 // memory.c
 PICO_INTERNAL void PicoInitPc(unsigned int pc);
 PICO_INTERNAL unsigned int PicoCheckPc(unsigned int pc);
-PICO_INTERNAL_ASM unsigned int PicoRead32(unsigned int a);
 PICO_INTERNAL void PicoMemSetup(void);
-PICO_INTERNAL_ASM void PicoMemReset(void);
 PICO_INTERNAL void PicoMemResetHooks(void);
-PICO_INTERNAL int PadRead(int i);
-PICO_INTERNAL int ym2612_write_local(unsigned int a, unsigned int d, int is_from_z80);
-void z80_mem_setup(void);
 extern unsigned int (*PicoRead16Hook)(unsigned int a, int realsize);
 extern void (*PicoWrite8Hook) (unsigned int a,unsigned int d,int realsize);
 extern void (*PicoWrite16Hook)(unsigned int a,unsigned int d,int realsize);
+unsigned int PicoRead8_io(unsigned int a);
+unsigned int PicoRead16_io(unsigned int a);
+void PicoWrite8_io(unsigned int a, unsigned int d);
+void PicoWrite16_io(unsigned int a, unsigned int d);
+
+// pico/memory.c
+PICO_INTERNAL void PicoMemSetupPico(void);
 
 // cd/memory.c
 PICO_INTERNAL void PicoMemSetupCD(void);
-PICO_INTERNAL_ASM void PicoMemResetCD(int r3);
+PICO_INTERNAL_ASM void PicoMemRemapCD(int r3);
 PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3);
 
-// pico/memory.c
-PICO_INTERNAL void PicoMemSetupPico(void);
-PICO_INTERNAL unsigned int ym2612_read_local_68k(void);
-
 // pico.c
 extern struct Pico Pico;
 extern struct PicoSRAM SRam;
@@ -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);
 
 // misc.c
-PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d);
-PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d);
-PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void);
+PICO_INTERNAL void EEPROM_write(unsigned int d);
+PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d);
+PICO_INTERNAL_ASM unsigned int EEPROM_read(void);
 PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count);
 PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count);
 PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count); // 32bit word count
@@ -548,8 +551,6 @@ PICO_INTERNAL void z80_pack(unsigned char *data);
 PICO_INTERNAL void z80_unpack(unsigned char *data);
 PICO_INTERNAL void z80_reset(void);
 PICO_INTERNAL void z80_exit(void);
-void z80_map_set(unsigned long *map, int start_addr,
-  int end_addr, void *func_or_mh, int is_func);
 
 // cd/misc.c
 PICO_INTERNAL_ASM void wram_2M_to_1M(unsigned char *m);
@@ -595,6 +596,8 @@ void PicoFrameDrawOnlyMS(void);
 #define EL_SVP     0x00004000 /* SVP stuff */
 #define EL_PICOHW  0x00008000 /* Pico stuff */
 #define EL_IDLE    0x00010000 /* idle loop det. */
+#define EL_CDREGS  0x00020000 /* MCD: register access */
+#define EL_CDREG3  0x00040000 /* MCD: register 3 only */
 
 #define EL_STATUS  0x40000000 /* status messages */
 #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */

+ 1 - 0
pico/sms.c

@@ -9,6 +9,7 @@
  * - H counter
  */
 #include "pico_int.h"
+#include "memory.h"
 #include "sound/sn76496.h"
 
 static unsigned char vdp_data_read(void)

+ 2 - 7
pico/sound/sound.c

@@ -107,14 +107,9 @@ static void dac_recalculate(void)
 
 PICO_INTERNAL void PsndReset(void)
 {
-  void *ym2612_regs;
-
-  // also clear the internal registers+addr line
-  ym2612_regs = YM2612GetRegs();
-  memset(ym2612_regs, 0, 0x200+4);
-  timers_reset();
-
+  // PsndRerate calls YM2612Init, which also resets
   PsndRerate(0);
+  timers_reset();
 }
 
 

+ 0 - 26
pico/z80if.c

@@ -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

+ 1 - 1
platform/common/common_arm.mak

@@ -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:

+ 2 - 1
platform/common/emu.c

@@ -989,7 +989,8 @@ int emu_save_load_game(int load, int sram)
 			}
 		} else {
 			sram_size = SRam.end-SRam.start+1;
-			if(Pico.m.sram_reg & 4) sram_size=0x2000;
+			if (Pico.m.sram_status & SRS_EEPROM)
+				sram_size = 0x2000;
 			sram_data = SRam.data;
 		}
 		if (!sram_data) return 0; // SRam forcefully disabled for this game

+ 4 - 0
platform/common/revision.mak

@@ -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:

+ 2 - 2
platform/gp2x/Makefile

@@ -3,12 +3,12 @@ export CROSS = arm-linux-
 # settings
 #mz80 = 1
 #debug_cyclone = 1
-asm_memory = 1
+#asm_memory = 1 # TODO
 asm_render = 1
 asm_ym2612 = 1
 asm_misc = 1
 asm_cdpico = 1
-asm_cdmemory = 1
+#asm_cdmemory = 1 # TODO
 amalgamate = 0
 #profile = 1
 #use_musashi = 1

+ 1 - 1
platform/linux/Makefile

@@ -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

Някои файлове не бяха показани, защото твърде много файлове са промени