X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Pico%2FMemory.c;h=2b253d80e0322f141587eb77ea0458daae995c2c;hb=a4f0cc8647c019f149541df380a2d30e14aeb75c;hp=3104eb414aa92123ddcee6fadd317833fa8c10ed;hpb=312e9ce192d49b4bea2f8a7e3cd2eb91a860564f;p=picodrive.git diff --git a/Pico/Memory.c b/Pico/Memory.c index 3104eb4..2b253d8 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -7,7 +7,7 @@ // For commercial use, separate licencing terms must be obtained. -//#define __debug_io +#define __debug_io #include "PicoInt.h" @@ -22,8 +22,8 @@ typedef unsigned int u32; extern unsigned int lastSSRamWrite; // used by serial SRAM code #ifdef _ASM_MEMORY_C -u8 PicoRead8(u32 a); -u16 PicoRead16(u32 a); +u32 PicoRead8(u32 a); +u32 PicoRead16(u32 a); void PicoWriteRomHW_SSF2(u32 a,u32 d); void PicoWriteRomHW_in1 (u32 a,u32 d); #endif @@ -69,9 +69,13 @@ static u32 CPU_CALL PicoCheckPc(u32 pc) u32 ret=0; #if defined(EMU_C68K) pc-=PicoCpu.membase; // Get real pc - pc&=0xfffffe; +// pc&=0xfffffe; + pc&=~1; + if ((pc<<8) == 0) + return (int)Pico.rom + Pico.romsize; // common crash condition, can happen if acc timing is off - PicoCpu.membase=PicoMemBase(pc); + PicoCpu.membase=PicoMemBase(pc&0x00ffffff); + PicoCpu.membase-=pc&0xff000000; ret = PicoCpu.membase+pc; #elif defined(EMU_A68K) @@ -107,71 +111,12 @@ static int SRAMRead(u32 a) } #endif -static int PadRead(int i) -{ - int pad=0,value=0,TH; - pad=~PicoPad[i]; // Get inverse of pad MXYZ SACB RLDU - TH=Pico.ioports[i+1]&0x40; - - if(PicoOpt & 0x20) { // 6 button gamepad enabled - int phase = Pico.m.padTHPhase[i]; - - if(phase == 2 && !TH) { - value=(pad&0xc0)>>2; // ?0SA 0000 - goto end; - } else if(phase == 3 && TH) { - value=(pad&0x30)|((pad>>8)&0xf); // ?1CB MXYZ - goto end; - } else if(phase == 3 && !TH) { - value=((pad&0xc0)>>2)|0x0f; // ?0SA 1111 - goto end; - } - } - - if(TH) value=(pad&0x3f); // ?1CB RLDU - else value=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU - - end: - - // orr the bits, which are set as output - value |= Pico.ioports[i+1]&Pico.ioports[i+4]; - - return value; // will mirror later -} - -u8 z80Read8(u32 a) -{ - if(Pico.m.z80Run&1) return 0; - - a&=0x1fff; - - if(!(PicoOpt&4)) { - // Z80 disabled, do some faking - static u8 zerosent = 0; - if(a == Pico.m.z80_lastaddr) { // probably polling something - u8 d = Pico.m.z80_fakeval; - if((d & 0xf) == 0xf && !zerosent) { - d = 0; zerosent = 1; - } else { - Pico.m.z80_fakeval++; - zerosent = 0; - } - return d; - } else { - Pico.m.z80_fakeval = 0; - } - } - - Pico.m.z80_lastaddr = (u16) a; - return Pico.zram[a]; -} - // for nonstandard reads #ifndef _ASM_MEMORY_C static #endif -u32 UnusualRead16(u32 a, int realsize) +u32 OtherRead16End(u32 a, int realsize) { u32 d=0; @@ -242,111 +187,16 @@ end: return d; } -#ifndef _ASM_MEMORY_C -static -#endif -u32 OtherRead16(u32 a, int realsize) -{ - u32 d=0; - - if ((a&0xff0000)==0xa00000) { - if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped) - if ((a&0x6000)==0x4000) { if(PicoOpt&1) d=YM2612Read(); else d=Pico.m.rotate++&3; dprintf("read ym2612: %04x", d); goto end; } // 0x4000-0x5fff, Fudge if disabled - d=0xffff; goto end; - } - if ((a&0xffffe0)==0xa10000) { // I/O ports - a=(a>>1)&0xf; - switch(a) { - case 0: d=Pico.m.hardware; break; // Hardware value (Version register) - case 1: d=PadRead(0); d|=Pico.ioports[1]&0x80; break; - case 2: d=PadRead(1); d|=Pico.ioports[2]&0x80; break; - default: d=Pico.ioports[a]; break; // IO ports can be used as RAM - } - d|=d<<8; - goto end; - } - // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers - if (a==0xa11100) { - d=Pico.m.z80Run&1; -#if 0 - if (!d) { - // do we need this? - extern int z80stopCycle; // TODO: tidy - int stop_before = SekCyclesDone() - z80stopCycle; - if (stop_before > 0 && stop_before <= 16) // Gens uses 16 here - d = 1; // bus not yet available - } -#endif - d=(d<<8)|0x8000|Pico.m.rotate++; - dprintf("get_zrun: %04x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), SekPc); - goto end; } - -#ifndef _ASM_MEMORY_C - if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; } -#endif - - d = UnusualRead16(a, realsize); - -end: - return d; -} //extern UINT32 mz80GetRegisterValue(void *, UINT32); -static void OtherWrite8(u32 a,u32 d,int realsize) +static void OtherWrite8End(u32 a,u32 d,int realsize) { - if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound - if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)d; return; } // Z80 ram - if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d); return; } // FM Sound - if ((a&0xffffe0)==0xa10000) { // I/O ports - a=(a>>1)&0xf; - // 6 button gamepad: if TH went from 0 to 1, gamepad changes state - if(PicoOpt&0x20) { - if(a==1) { - Pico.m.padDelay[0] = 0; - if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++; - } - else if(a==2) { - Pico.m.padDelay[1] = 0; - if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++; - } - } - Pico.ioports[a]=(u8)d; // IO ports can be used as RAM - return; - } - if (a==0xa11100) { - extern int z80startCycle, z80stopCycle; - //int lineCycles=(488-SekCyclesLeft)&0x1ff; - d&=1; d^=1; - if(!d) { - // hack: detect a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III) - // if((PicoOpt&4) && Pico.m.z80Run==1) z80_run(20); // FIXME: movies - z80stopCycle = SekCyclesDone(); - //z80ExtraCycles += (lineCycles>>1)-(lineCycles>>5); // only meaningful in PicoFrameHints() - } else { - z80startCycle = SekCyclesDone(); - //if(Pico.m.scanline != -1) - //z80ExtraCycles -= (lineCycles>>1)-(lineCycles>>5)+16; - } - dprintf("set_zrun: %02x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), /*mz80GetRegisterValue(NULL, 0),*/ SekPc); - Pico.m.z80Run=(u8)d; return; - } - if (a==0xa11200) { dprintf("write z80Reset: %02x", d); if(!(d&1)) z80_reset(); return; } - - if ((a&0xff7f00)==0xa06000) // Z80 BANK register - { - Pico.m.z80_bank68k>>=1; - Pico.m.z80_bank68k|=(d&1)<<8; - Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one - return; - } - - if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)(d|(d<<8))); return; } // Byte access gets mirrored - // sram //if(a==0x200000) dprintf("cc : %02x @ %06x [%i|%i]", d, SekPc, SekCyclesDoneT(), SekCyclesDone()); //if(a==0x200001) dprintf("w8 : %02x @ %06x [%i]", d, SekPc, SekCyclesDoneT()); if(a >= SRam.start && a <= SRam.end) { + dprintf("sram w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc); unsigned int sreg = Pico.m.sram_reg; if(!(sreg & 0x10)) { // not detected SRAM @@ -384,7 +234,9 @@ static void OtherWrite8(u32 a,u32 d,int realsize) #else // sram access register if(a == 0xA130F1) { - Pico.m.sram_reg = (u8)(d&3); + dprintf("sram reg=%02x", d); + Pico.m.sram_reg &= ~3; + Pico.m.sram_reg |= (u8)(d&3); return; } #endif @@ -406,39 +258,15 @@ static void OtherWrite8(u32 a,u32 d,int realsize) Pico.m.prot_bytes[(a>>2)&1] = (u8)d; } -static void OtherWrite16(u32 a,u32 d) -{ - if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } - if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)(d>>8); return; } // Z80 ram (MSB only) - - if ((a&0xffffe0)==0xa10000) { // I/O ports - a=(a>>1)&0xf; - // 6 button gamepad: if TH went from 0 to 1, gamepad changes state - if(PicoOpt&0x20) { - if(a==1) { - Pico.m.padDelay[0] = 0; - if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++; - } - else if(a==2) { - Pico.m.padDelay[1] = 0; - if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++; - } - } - Pico.ioports[a]=(u8)d; // IO ports can be used as RAM - return; - } - if (a==0xa11100) { OtherWrite8(a, d>>8, 16); return; } - if (a==0xa11200) { dprintf("write z80reset: %04x", d); if(!(d&0x100)) z80_reset(); return; } - OtherWrite8(a, d>>8, 16); - OtherWrite8(a+1,d&0xff, 16); -} +#include "MemoryCmn.c" + // ----------------------------------------------------------------- // Read Rom and read Ram #ifndef _ASM_MEMORY_C -u8 CPU_CALL PicoRead8(u32 a) +u32 CPU_CALL PicoRead8(u32 a) { u32 d=0; @@ -481,17 +309,17 @@ u8 CPU_CALL PicoRead8(u32 a) dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); #endif #if defined(EMU_C68K) && defined(EMU_M68K) - if(a>=Pico.romsize&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b) { + if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) { lastread_a = a; lastread_d[lrp_cyc++&15] = (u8)d; } #endif - return (u8)d; + return d; } -u16 CPU_CALL PicoRead16(u32 a) +u32 CPU_CALL PicoRead16(u32 a) { - u16 d=0; + u32 d=0; if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram @@ -500,14 +328,14 @@ u16 CPU_CALL PicoRead16(u32 a) #if !(defined(EMU_C68K) && defined(EMU_M68K)) // sram if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg & 1)) { - d = (u16) SRAMRead(a); + d = SRAMRead(a); goto end; } #endif if (a=Pico.romsize&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b) { + if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) { lastread_a = a; lastread_d[lrp_cyc++&15] = d; } @@ -548,7 +376,7 @@ u32 CPU_CALL PicoRead32(u32 a) dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc); #endif #if defined(EMU_C68K) && defined(EMU_M68K) - if(a>=Pico.romsize&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b) { + if(a>=Pico.romsize/*&&(ppop&0x3f)!=0x3a&&(ppop&0x3f)!=0x3b*/) { lastread_a = a; lastread_d[lrp_cyc++&15] = d; } @@ -571,16 +399,13 @@ static void CPU_CALL PicoWrite8(u32 a,u8 d) //if ((a&0xe0ffff)==0xe0a9ba+0x69c) // dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); - - if ((a&0xe00000)==0xe00000) { - if((a&0xffff)==0xf62a) dprintf("(f62a) = %02x [%i|%i] @ %x", d, Pico.m.scanline, SekCyclesDone(), SekPc); - u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram + if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram a&=0xffffff; OtherWrite8(a,d,8); } -static void CPU_CALL PicoWrite16(u32 a,u16 d) +void CPU_CALL PicoWrite16(u32 a,u16 d) { #ifdef __debug_io dprintf("w16: %06x, %04x", a&0xffffff, d); @@ -621,7 +446,7 @@ static void CPU_CALL PicoWrite32(u32 a,u32 d) // ----------------------------------------------------------------- -int PicoMemInit() +void PicoMemSetup() { #ifdef EMU_C68K // Setup memory callbacks: @@ -633,7 +458,6 @@ int PicoMemInit() PicoCpu.write16=PicoWrite16; PicoCpu.write32=PicoWrite32; #endif - return 0; } #ifdef EMU_A68K @@ -678,39 +502,78 @@ unsigned int m68k_read_pcrelative_CD16(unsigned int a); unsigned int m68k_read_pcrelative_CD32(unsigned int a); // these are allowed to access RAM -unsigned int m68k_read_pcrelative_8 (unsigned int a) { +static unsigned int m68k_read_8 (unsigned int a, int do_fake) { a&=0xffffff; if(PicoMCD&1) return m68k_read_pcrelative_CD8(a); if(a