From: notaz Date: Fri, 14 Aug 2009 15:02:54 +0000 (+0000) Subject: refactoring z80 if code for sms preparation X-Git-Tag: v1.85~297 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8d1e9b66255c00a3bef7ca27ae019e3523d7a4b;p=picodrive.git refactoring z80 if code for sms preparation git-svn-id: file:///home/notaz/opt/svn/PicoDrive@752 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/cpu/cz80/cz80.c b/cpu/cz80/cz80.c index 374325e2..091e2a5f 100644 --- a/cpu/cz80/cz80.c +++ b/cpu/cz80/cz80.c @@ -219,7 +219,10 @@ void Cz80_Reset(cz80_struc *CPU) #if PICODRIVE_HACKS static inline unsigned char picodrive_read(unsigned short a) { - return (a < 0x4000) ? Pico.zram[a&0x1fff] : z80_read(a); + unsigned long v = z80_read_map[a >> Z80_MEM_SHIFT]; + if (v & 0x80000000) + return ((z80_read_f *)(v << 1))(a); + return *(unsigned char *)((v << 1) + a); } #endif diff --git a/cpu/cz80/cz80macro.h b/cpu/cz80/cz80macro.h index 7118dccd..16f3a709 100644 --- a/cpu/cz80/cz80macro.h +++ b/cpu/cz80/cz80macro.h @@ -73,8 +73,11 @@ #define WRITE_MEM8(A, D) { \ unsigned short a = A; \ unsigned char d = D; \ - if (a < 0x4000) Pico.zram[a&0x1fff] = d; \ - else z80_write(a, d); \ + unsigned long v = z80_write_map[a >> Z80_MEM_SHIFT]; \ + if (v & 0x80000000) \ + ((z80_write_f *)(v << 1))(a, d); \ + else \ + *(unsigned char *)((v << 1) + a) = d; \ } #else #define WRITE_MEM8(A, D) CPU->Write_Byte(A, D); diff --git a/pico/memory.c b/pico/memory.c index 074af246..e8b65e48 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -19,7 +19,7 @@ typedef unsigned int u32; #define UTYPES_DEFINED #endif -extern unsigned int lastSSRamWrite; // used by serial SRAM code +extern unsigned int lastSSRamWrite; // used by serial eeprom code #ifdef _ASM_MEMORY_C u32 PicoRead8(u32 a); @@ -514,6 +514,7 @@ PICO_INTERNAL void PicoMemResetHooks(void) PicoWrite16Hook = OtherWrite16End; } +static void z80_mem_setup(void); #ifdef EMU_M68K static void m68k_mem_setup(void); #endif @@ -555,6 +556,8 @@ PICO_INTERNAL void PicoMemSetup(void) #ifdef EMU_M68K m68k_mem_setup(); #endif + + z80_mem_setup(); } /* some nasty things below :( */ @@ -880,7 +883,7 @@ int ym2612_write_local(u32 a, u32 d, int is_from_z80) if (xcycles >= timer_b_next_oflow) \ ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 2 -u32 ym2612_read_local_z80(void) +static u32 MEMH_FUNC ym2612_read_local_z80(void) { int xcycles = z80_cyclesDone() << 8; @@ -978,94 +981,114 @@ void ym2612_unpack_state(void) // ----------------------------------------------------------------- // z80 memhandlers -PICO_INTERNAL unsigned char z80_read(unsigned short a) +static unsigned char MEMH_FUNC z80_md_vdp_read(unsigned short a) { - u8 ret = 0; + // TODO? + elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, 0xff); + return 0xff; +} - if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald) - { - return ym2612_read_local_z80(); - } +static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a) +{ + extern unsigned int PicoReadM68k8(unsigned int a); + unsigned int addr68k; + unsigned char ret; - if (a>=0x8000) - { - extern u32 PicoReadM68k8(u32 a); - u32 addr68k; - addr68k=Pico.m.z80_bank68k<<15; - addr68k+=a&0x7fff; - - if (addr68k < Pico.romsize) { ret = Pico.rom[addr68k^1]; goto bnkend; } - elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret); - if (PicoAHW & PAHW_MCD) - ret = PicoReadM68k8(addr68k); - else ret = PicoRead8(addr68k); -bnkend: - elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); - return ret; + addr68k = Pico.m.z80_bank68k<<15; + addr68k += a & 0x7fff; + + if (addr68k < Pico.romsize) { + ret = Pico.rom[addr68k^1]; + goto out; } - // should not be needed, cores should be able to access RAM themselves - if (a<0x4000) return Pico.zram[a&0x1fff]; + elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret); + if (PicoAHW & PAHW_MCD) + ret = PicoReadM68k8(addr68k); + else ret = PicoRead8(addr68k); - elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret); +out: + elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); return ret; } -#ifndef _USE_CZ80 -PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a) -#else -PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data) -#endif +static void MEMH_FUNC z80_md_ym2612_write(unsigned int a, unsigned char data) { - if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald) - { - if(PicoOpt&POPT_EN_FM) emustatus|=ym2612_write_local(a, data, 1) & 1; - return; - } + if (PicoOpt & POPT_EN_FM) + emustatus |= ym2612_write_local(a, data, 1) & 1; +} - if ((a&0xfff9)==0x7f11) // 7f11 7f13 7f15 7f17 +static void MEMH_FUNC z80_md_vdp_br_write(unsigned int a, unsigned char data) +{ + // TODO: allow full VDP access + if ((a&0xfff9) == 0x7f11) // 7f11 7f13 7f15 7f17 { - if(PicoOpt&POPT_EN_PSG) SN76496Write(data); + if (PicoOpt & POPT_EN_PSG) + SN76496Write(data); return; } - if ((a>>8)==0x60) + if ((a>>8) == 0x60) { - Pico.m.z80_bank68k>>=1; - Pico.m.z80_bank68k|=(data&1)<<8; - Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one + Pico.m.z80_bank68k >>= 1; + Pico.m.z80_bank68k |= data << 8; + Pico.m.z80_bank68k &= 0x1ff; // 9 bits and filled in the new top one return; } - if (a>=0x8000) - { - extern void PicoWriteM68k8(u32 a,u8 d); - u32 addr68k; - addr68k=Pico.m.z80_bank68k<<15; - addr68k+=a&0x7fff; - elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data); - if (PicoAHW & PAHW_MCD) - PicoWriteM68k8(addr68k, data); - else PicoWrite8(addr68k, data); - return; - } + elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data); +} - // should not be needed - if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; } +static void MEMH_FUNC z80_md_bank_write(unsigned int a, unsigned char data) +{ + extern void PicoWriteM68k8(unsigned int a, unsigned char d); + unsigned int addr68k; - elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data); + addr68k = Pico.m.z80_bank68k << 15; + addr68k += a & 0x7fff; + + elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data); + if (PicoAHW & PAHW_MCD) + PicoWriteM68k8(addr68k, data); + else PicoWrite8(addr68k, data); } -#ifndef _USE_CZ80 -PICO_INTERNAL unsigned short z80_read16(unsigned short a) +// ----------------------------------------------------------------- + +static unsigned char z80_md_in(unsigned short p) { - return (u16) ( (u16)z80_read(a) | ((u16)z80_read((u16)(a+1))<<8) ); + elprintf(EL_ANOMALY, "Z80 port %04x read", p); + return 0xff; } -PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a) +static void z80_md_out(unsigned short p, unsigned char d) { - z80_write((unsigned char) data,a); - z80_write((unsigned char)(data>>8),(u16)(a+1)); + elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d); } + +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); + z80_map_set(z80_read_map, 0x4000, 0x5fff, ym2612_read_local_z80, 1); + z80_map_set(z80_read_map, 0x6000, 0x7fff, z80_md_vdp_read, 1); + z80_map_set(z80_read_map, 0x8000, 0xffff, z80_md_bank_read, 1); + + z80_map_set(z80_write_map, 0x0000, 0x1fff, Pico.zram, 0); + z80_map_set(z80_write_map, 0x2000, 0x3fff, Pico.zram, 0); + z80_map_set(z80_write_map, 0x4000, 0x5fff, z80_md_ym2612_write, 1); + z80_map_set(z80_write_map, 0x6000, 0x7fff, z80_md_vdp_br_write, 1); + z80_map_set(z80_write_map, 0x8000, 0xffff, z80_md_bank_write, 1); + +#ifdef _USE_DRZ80 + drZ80.z80_in = z80_md_in; + drZ80.z80_out = z80_md_out; +#endif +#ifdef _USE_CZ80 + Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM + Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram); // mirror + Cz80_Set_INPort(&CZ80, z80_md_in); + Cz80_Set_OUTPort(&CZ80, z80_md_out); #endif +} diff --git a/pico/pico_int.h b/pico/pico_int.h index e5bbffdb..1339c264 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -218,11 +218,16 @@ extern int z80_scanline_cycles; /* cycles done until z80_scanline */ #define cycles_68k_to_z80(x) ((x)*957 >> 11) +#define Z80_MEM_SHIFT 13 +extern unsigned long z80_read_map [0x10000 >> Z80_MEM_SHIFT]; +extern unsigned long z80_write_map[0x10000 >> Z80_MEM_SHIFT]; +typedef unsigned char (z80_read_f)(unsigned short a); +typedef void (z80_write_f)(unsigned int a, unsigned char data); + // --------------------------------------------------------- // main oscillator clock which controls timing #define OSC_NTSC 53693100 -// seems to be accurate, see scans from http://www.hot.ee/tmeeco/ #define OSC_PAL 53203424 struct PicoVideo @@ -369,12 +374,12 @@ typedef struct #define Pico_mcd ((mcd_state *)Pico.rom) -// Area.c +// area.c PICO_INTERNAL void PicoAreaPackCpu(unsigned char *cpu, int is_sub); PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub); extern void (*PicoLoadStateHook)(void); -// cd/Area.c +// cd/area.c PICO_INTERNAL int PicoCdSaveState(void *file); PICO_INTERNAL int PicoCdLoadState(void *file); @@ -397,23 +402,23 @@ extern areaeof *areaEof; extern areaseek *areaSeek; extern areaclose *areaClose; -// Cart.c +// cart.c extern void (*PicoCartUnloadHook)(void); -// Debug.c +// debug.c int CM_compareRun(int cyc, int is_sub); -// Draw.c +// draw.c PICO_INTERNAL void PicoFrameStart(void); void PicoDrawSync(int to, int blank_last_line); extern int DrawScanline; #define MAX_LINE_SPRITES 29 extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; -// Draw2.c +// draw2.c PICO_INTERNAL void PicoFrameFull(); -// Memory.c +// 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); @@ -421,29 +426,21 @@ PICO_INTERNAL void PicoMemSetup(void); PICO_INTERNAL_ASM void PicoMemReset(void); PICO_INTERNAL void PicoMemResetHooks(void); PICO_INTERNAL int PadRead(int i); -PICO_INTERNAL unsigned char z80_read(unsigned short a); -#ifndef _USE_CZ80 -PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a); -PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a); -PICO_INTERNAL unsigned short z80_read16(unsigned short a); -#else -PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data); -#endif PICO_INTERNAL int ym2612_write_local(unsigned int a, unsigned int d, int is_from_z80); 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); -// cd/Memory.c +// cd/memory.c PICO_INTERNAL void PicoMemSetupCD(void); PICO_INTERNAL_ASM void PicoMemResetCD(int r3); PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3); -// Pico/Memory.c +// pico/memory.c PICO_INTERNAL void PicoMemSetupPico(void); PICO_INTERNAL unsigned int ym2612_read_local_68k(void); -// Pico.c +// pico.c extern struct Pico Pico; extern struct PicoSRAM SRam; extern int PicoPadInt[2]; @@ -454,23 +451,23 @@ PICO_INTERNAL int CheckDMA(void); PICO_INTERNAL void PicoDetectRegion(void); PICO_INTERNAL void PicoSyncZ80(int m68k_cycles_done); -// cd/Pico.c +// cd/pico.c PICO_INTERNAL void PicoInitMCD(void); PICO_INTERNAL void PicoExitMCD(void); PICO_INTERNAL void PicoPowerMCD(void); PICO_INTERNAL int PicoResetMCD(void); PICO_INTERNAL void PicoFrameMCD(void); -// Pico/Pico.c +// pico/pico.c PICO_INTERNAL void PicoInitPico(void); PICO_INTERNAL void PicoReratePico(void); -// Pico/xpcm.c +// pico/xpcm.c PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo); PICO_INTERNAL void PicoPicoPCMReset(void); PICO_INTERNAL void PicoPicoPCMRerate(int xpcm_rate); -// Sek.c +// sek.c PICO_INTERNAL void SekInit(void); PICO_INTERNAL int SekReset(void); PICO_INTERNAL void SekState(int *data); @@ -479,7 +476,7 @@ void SekStepM68k(void); void SekInitIdleDet(void); void SekFinishIdleDet(void); -// cd/Sek.c +// cd/sek.c PICO_INTERNAL void SekInitS68k(void); PICO_INTERNAL int SekResetS68k(void); PICO_INTERNAL int SekInterruptS68k(int irq); @@ -515,13 +512,13 @@ void ym2612_unpack_state(void); timer_b_step = TIMER_B_TICK_ZCYCLES * 256; -// VideoPort.c +// videoport.c PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d); PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a); 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 +// 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); @@ -530,7 +527,16 @@ 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 PICO_INTERNAL_ASM void memset32(int *dest, int c, int count); -// cd/Misc.c +// z80 functionality wrappers +PICO_INTERNAL void z80_init(void); +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); PICO_INTERNAL_ASM void wram_1M_to_2M(unsigned char *m); @@ -542,12 +548,6 @@ PICO_INTERNAL void PsndReset(void); PICO_INTERNAL void PsndDoDAC(int line_to); PICO_INTERNAL void PsndClear(void); PICO_INTERNAL void PsndGetSamples(int y); -// z80 functionality wrappers -PICO_INTERNAL void z80_init(void); -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); extern int PsndDacLine; // emulation event logging @@ -595,6 +595,12 @@ extern void lprintf(const char *fmt, ...); #define cdprintf(x...) #endif +#if defined(__GNUC__) && !defined(ARM) +#define MEMH_FUNC __attribute__((aligned(4))) +#else +#define MEMH_FUNC +#endif + #ifdef __cplusplus } // End of extern "C" #endif diff --git a/pico/sound/sound.c b/pico/sound/sound.c index a73ebd99..e1e0408c 100644 --- a/pico/sound/sound.c +++ b/pico/sound/sound.c @@ -396,271 +396,3 @@ PICO_INTERNAL void PsndGetSamples(int y) #endif } - -// ----------------------------------------------------------------- -// z80 stuff - -#ifdef _USE_MZ80 - -// memhandlers for mz80 core -unsigned char mz80_read(UINT32 a, struct MemoryReadByte *w) { return z80_read(a); } -void mz80_write(UINT32 a, UINT8 d, struct MemoryWriteByte *w) { z80_write(d, a); } - -// structures for mz80 core -static struct MemoryReadByte mz80_mem_read[]= -{ - {0x0000,0xffff,mz80_read}, - {(UINT32) -1,(UINT32) -1,NULL} -}; -static struct MemoryWriteByte mz80_mem_write[]= -{ - {0x0000,0xffff,mz80_write}, - {(UINT32) -1,(UINT32) -1,NULL} -}; -static struct z80PortRead mz80_io_read[] ={ - {(UINT16) -1,(UINT16) -1,NULL} -}; -static struct z80PortWrite mz80_io_write[]={ - {(UINT16) -1,(UINT16) -1,NULL} -}; - -int mz80_run(int cycles) -{ - int ticks_pre = mz80GetElapsedTicks(0); - mz80exec(cycles); - return mz80GetElapsedTicks(0) - ticks_pre; -} - -#endif - -#ifdef _USE_DRZ80 - -struct DrZ80 drZ80; - -static unsigned int DrZ80_rebasePC(unsigned short a) -{ - drZ80.Z80PC_BASE = (unsigned int) Pico.zram; - return drZ80.Z80PC_BASE + a; -} - -static unsigned int DrZ80_rebaseSP(unsigned short a) -{ - drZ80.Z80SP_BASE = (unsigned int) Pico.zram; - return drZ80.Z80SP_BASE + a; -} -#endif - -#if defined(_USE_DRZ80) || defined(_USE_CZ80) -static unsigned char z80_in(unsigned short p) -{ - elprintf(EL_ANOMALY, "Z80 port %04x read", p); - return 0xff; -} - -static void z80_out(unsigned short p,unsigned char d) -{ - elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d); -} -#endif - - -// z80 functionality wrappers -PICO_INTERNAL void z80_init(void) -{ -#ifdef _USE_MZ80 - struct mz80context z80; - - // z80 - mz80init(); - // Modify the default context - mz80GetContext(&z80); - - // point mz80 stuff - z80.z80Base=Pico.zram; - z80.z80MemRead=mz80_mem_read; - z80.z80MemWrite=mz80_mem_write; - z80.z80IoRead=mz80_io_read; - z80.z80IoWrite=mz80_io_write; - - mz80SetContext(&z80); -#endif -#ifdef _USE_DRZ80 - memset(&drZ80, 0, sizeof(struct DrZ80)); - drZ80.z80_rebasePC=DrZ80_rebasePC; - drZ80.z80_rebaseSP=DrZ80_rebaseSP; - drZ80.z80_read8 =z80_read; - drZ80.z80_read16 =NULL; - drZ80.z80_write8 =z80_write; - drZ80.z80_write16 =NULL; - drZ80.z80_in =z80_in; - drZ80.z80_out =z80_out; - drZ80.z80_irq_callback=NULL; -#endif -#ifdef _USE_CZ80 - memset(&CZ80, 0, sizeof(CZ80)); - Cz80_Init(&CZ80); - Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM - Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram); // mirror - Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read); // unused (hacked in) - Cz80_Set_WriteB(&CZ80, z80_write); - Cz80_Set_INPort(&CZ80, z80_in); - Cz80_Set_OUTPort(&CZ80, z80_out); -#endif -} - -PICO_INTERNAL void z80_reset(void) -{ -#ifdef _USE_MZ80 - mz80reset(); -#endif -#ifdef _USE_DRZ80 - memset(&drZ80, 0, 0x54); - drZ80.Z80F = (1<<2); // set ZFlag - drZ80.Z80F2 = (1<<2); // set ZFlag - drZ80.Z80IX = 0xFFFF << 16; - drZ80.Z80IY = 0xFFFF << 16; - drZ80.Z80IM = 0; // 1? - drZ80.z80irqvector = 0xff0000; // RST 38h - drZ80.Z80PC = drZ80.z80_rebasePC(0); - drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ? -#endif -#ifdef _USE_CZ80 - Cz80_Reset(&CZ80); - Cz80_Set_Reg(&CZ80, CZ80_IX, 0xffff); - Cz80_Set_Reg(&CZ80, CZ80_IY, 0xffff); - Cz80_Set_Reg(&CZ80, CZ80_SP, 0x2000); -#endif - Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled -} - -#if 0 -static int had_irq = 0, z80_ppc, z80_ops_done = 0; -int z80_cycles_left = 0; - -void z80_int(void) -{ - had_irq = 1; -} - -static void xfail(void) -{ - printf("PC: %04x, %04x\n", Cz80_Get_Reg(&CZ80, CZ80_PC), z80_ppc); - printf("z80_ops_done done: %i\n", z80_ops_done); - exit(1); -} - -int z80_run(int cycles) -{ - int fail = 0; - int cdrz, ccz; - - z80_cycles_left = cycles; - z80_ppc = Cz80_Get_Reg(&CZ80, CZ80_PC); - - if (had_irq) { - printf("irq @ %04x\n", Cz80_Get_Reg(&CZ80, CZ80_PC)); - Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE); - drZ80.Z80_IRQ = 1; - had_irq = 0; - } - - while (z80_cycles_left > 0) - { - ccz = Cz80_Exec(&CZ80, 1); - cdrz = 1 - DrZ80Run(&drZ80, 1); - - if (drZ80.Z80_IRQ && (drZ80.Z80IF&1)) - cdrz += 1 - DrZ80Run(&drZ80, 1); // cz80 processes IRQ after EI, DrZ80 does not - - if (cdrz != ccz) { - printf("cycles: %i vs %i\n", cdrz, ccz); - fail = 1; - } - - if (drZ80.Z80PC - drZ80.Z80PC_BASE != Cz80_Get_Reg(&CZ80, CZ80_PC)) { - printf("PC: %04x vs %04x\n", drZ80.Z80PC - drZ80.Z80PC_BASE, Cz80_Get_Reg(&CZ80, CZ80_PC)); - fail = 1; - } - - if (fail) xfail(); - - z80_ops_done++; - z80_cycles_left -= ccz; - z80_ppc = Cz80_Get_Reg(&CZ80, CZ80_PC); - } - - return co - z80_cycles_left; -} -#endif - - -PICO_INTERNAL void z80_pack(unsigned char *data) -{ -#if defined(_USE_MZ80) - struct mz80context mz80; - *(int *)data = 0x00005A6D; // "mZ" - mz80GetContext(&mz80); - memcpy(data+4, &mz80.z80clockticks, sizeof(mz80)-5*4); // don't save base&memhandlers -#elif defined(_USE_DRZ80) - *(int *)data = 0x015A7244; // "DrZ" v1 - drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE); - drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE); - memcpy(data+4, &drZ80, 0x54); -#elif defined(_USE_CZ80) - *(int *)data = 0x00007a43; // "Cz" - *(int *)(data+4) = Cz80_Get_Reg(&CZ80, CZ80_PC); - memcpy(data+8, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80); -#endif -} - -PICO_INTERNAL void z80_unpack(unsigned char *data) -{ -#if defined(_USE_MZ80) - if (*(int *)data == 0x00005A6D) { // "mZ" save? - struct mz80context mz80; - mz80GetContext(&mz80); - memcpy(&mz80.z80clockticks, data+4, sizeof(mz80)-5*4); - mz80SetContext(&mz80); - } else { - z80_reset(); - z80_int(); - } -#elif defined(_USE_DRZ80) - if (*(int *)data == 0x015A7244) { // "DrZ" v1 save? - memcpy(&drZ80, data+4, 0x54); - // update bases - drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE); - drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE); - } else { - z80_reset(); - drZ80.Z80IM = 1; - z80_int(); // try to goto int handler, maybe we won't execute trash there? - } -#elif defined(_USE_CZ80) - if (*(int *)data == 0x00007a43) { // "Cz" save? - memcpy(&CZ80, data+8, (INT32)&CZ80.BasePC - (INT32)&CZ80); - Cz80_Set_Reg(&CZ80, CZ80_PC, *(int *)(data+4)); - } else { - z80_reset(); - z80_int(); - } -#endif -} - -PICO_INTERNAL void z80_exit(void) -{ -#if defined(_USE_MZ80) - mz80shutdown(); -#endif -} - -#if 1 // defined(__DEBUG_PRINT) || defined(__GP2X__) || defined(__GIZ__) -PICO_INTERNAL void z80_debug(char *dstr) -{ -#if defined(_USE_DRZ80) - sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", drZ80.Z80PC-drZ80.Z80PC_BASE, drZ80.Z80SP-drZ80.Z80SP_BASE); -#elif defined(_USE_CZ80) - sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", CZ80.PC - CZ80.BasePC, CZ80.SP.W); -#endif -} -#endif diff --git a/pico/z80if.c b/pico/z80if.c new file mode 100644 index 00000000..5ce951e4 --- /dev/null +++ b/pico/z80if.c @@ -0,0 +1,212 @@ +#include "pico_int.h" +#include "sound/sn76496.h" + +#define Z80_MEM_SHIFT 13 + +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; + } + + for (i = start_addr >> Z80_MEM_SHIFT; i <= end_addr >> Z80_MEM_SHIFT; i++) + if (is_func) + map[i] = (addr >> 1) | (1 << (sizeof(addr) * 8 - 1)); + else + map[i] = (addr - (i << Z80_MEM_SHIFT)) >> 1; +} + +#ifdef _USE_MZ80 + +// memhandlers for mz80 core +unsigned char mz80_read(UINT32 a, struct MemoryReadByte *w) { return z80_read(a); } +void mz80_write(UINT32 a, UINT8 d, struct MemoryWriteByte *w) { z80_write(d, a); } + +// structures for mz80 core +static struct MemoryReadByte mz80_mem_read[]= +{ + {0x0000,0xffff,mz80_read}, + {(UINT32) -1,(UINT32) -1,NULL} +}; +static struct MemoryWriteByte mz80_mem_write[]= +{ + {0x0000,0xffff,mz80_write}, + {(UINT32) -1,(UINT32) -1,NULL} +}; +static struct z80PortRead mz80_io_read[] ={ + {(UINT16) -1,(UINT16) -1,NULL} +}; +static struct z80PortWrite mz80_io_write[]={ + {(UINT16) -1,(UINT16) -1,NULL} +}; + +int mz80_run(int cycles) +{ + int ticks_pre = mz80GetElapsedTicks(0); + mz80exec(cycles); + return mz80GetElapsedTicks(0) - ticks_pre; +} + +#endif + +#ifdef _USE_DRZ80 + +struct DrZ80 drZ80; + +static unsigned int DrZ80_rebasePC(unsigned short a) +{ + drZ80.Z80PC_BASE = (unsigned int) Pico.zram; + return drZ80.Z80PC_BASE + a; +} + +static unsigned int DrZ80_rebaseSP(unsigned short a) +{ + drZ80.Z80SP_BASE = (unsigned int) Pico.zram; + return drZ80.Z80SP_BASE + a; +} +#endif + + +PICO_INTERNAL void z80_init(void) +{ +#ifdef _USE_MZ80 + struct mz80context z80; + + // z80 + mz80init(); + // Modify the default context + mz80GetContext(&z80); + + // point mz80 stuff + z80.z80Base=Pico.zram; + z80.z80MemRead=mz80_mem_read; + z80.z80MemWrite=mz80_mem_write; + z80.z80IoRead=mz80_io_read; + z80.z80IoWrite=mz80_io_write; + + mz80SetContext(&z80); +#endif +#ifdef _USE_DRZ80 + memset(&drZ80, 0, sizeof(drZ80)); + drZ80.z80_rebasePC=DrZ80_rebasePC; + drZ80.z80_rebaseSP=DrZ80_rebaseSP; + drZ80.z80_read8 =(void *)z80_read_map; + drZ80.z80_read16 =NULL; + drZ80.z80_write8 =(void *)z80_write_map; + drZ80.z80_write16 =NULL; + drZ80.z80_irq_callback=NULL; +#endif +#ifdef _USE_CZ80 + memset(&CZ80, 0, sizeof(CZ80)); + Cz80_Init(&CZ80); + Cz80_Set_ReadB(&CZ80, NULL); // unused (hacked in) + Cz80_Set_WriteB(&CZ80, NULL); +#endif +} + +PICO_INTERNAL void z80_reset(void) +{ +#ifdef _USE_MZ80 + mz80reset(); +#endif +#ifdef _USE_DRZ80 + memset(&drZ80, 0, 0x54); + drZ80.Z80F = (1<<2); // set ZFlag + drZ80.Z80F2 = (1<<2); // set ZFlag + drZ80.Z80IX = 0xFFFF << 16; + drZ80.Z80IY = 0xFFFF << 16; + drZ80.Z80IM = 0; // 1? + drZ80.z80irqvector = 0xff0000; // RST 38h + drZ80.Z80PC = drZ80.z80_rebasePC(0); + drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ? +#endif +#ifdef _USE_CZ80 + Cz80_Reset(&CZ80); + Cz80_Set_Reg(&CZ80, CZ80_IX, 0xffff); + Cz80_Set_Reg(&CZ80, CZ80_IY, 0xffff); + Cz80_Set_Reg(&CZ80, CZ80_SP, 0x2000); +#endif + Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled +} + +PICO_INTERNAL void z80_pack(unsigned char *data) +{ +#if defined(_USE_MZ80) + struct mz80context mz80; + *(int *)data = 0x00005A6D; // "mZ" + mz80GetContext(&mz80); + memcpy(data+4, &mz80.z80clockticks, sizeof(mz80)-5*4); // don't save base&memhandlers +#elif defined(_USE_DRZ80) + *(int *)data = 0x015A7244; // "DrZ" v1 + drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE); + drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE); + memcpy(data+4, &drZ80, 0x54); +#elif defined(_USE_CZ80) + *(int *)data = 0x00007a43; // "Cz" + *(int *)(data+4) = Cz80_Get_Reg(&CZ80, CZ80_PC); + memcpy(data+8, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80); +#endif +} + +PICO_INTERNAL void z80_unpack(unsigned char *data) +{ +#if defined(_USE_MZ80) + if (*(int *)data == 0x00005A6D) { // "mZ" save? + struct mz80context mz80; + mz80GetContext(&mz80); + memcpy(&mz80.z80clockticks, data+4, sizeof(mz80)-5*4); + mz80SetContext(&mz80); + } else { + z80_reset(); + z80_int(); + } +#elif defined(_USE_DRZ80) + if (*(int *)data == 0x015A7244) { // "DrZ" v1 save? + memcpy(&drZ80, data+4, 0x54); + // update bases + drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE); + drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE); + } else { + z80_reset(); + drZ80.Z80IM = 1; + z80_int(); // try to goto int handler, maybe we won't execute trash there? + } +#elif defined(_USE_CZ80) + if (*(int *)data == 0x00007a43) { // "Cz" save? + memcpy(&CZ80, data+8, (INT32)&CZ80.BasePC - (INT32)&CZ80); + Cz80_Set_Reg(&CZ80, CZ80_PC, *(int *)(data+4)); + } else { + z80_reset(); + z80_int(); + } +#endif +} + +PICO_INTERNAL void z80_exit(void) +{ +#if defined(_USE_MZ80) + mz80shutdown(); +#endif +} + +PICO_INTERNAL void z80_debug(char *dstr) +{ +#if defined(_USE_DRZ80) + sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", drZ80.Z80PC-drZ80.Z80PC_BASE, drZ80.Z80SP-drZ80.Z80SP_BASE); +#elif defined(_USE_CZ80) + sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", CZ80.PC - CZ80.BasePC, CZ80.SP.W); +#endif +} diff --git a/platform/gizmondo/Makefile b/platform/gizmondo/Makefile index 1a2c63ac..d7aab76a 100644 --- a/platform/gizmondo/Makefile +++ b/platform/gizmondo/Makefile @@ -47,7 +47,7 @@ ifeq "$(amalgamate)" "1" OBJS += picoAll.o else OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \ - pico/videoport.o pico/draw2.o pico/draw.o pico/patch.o pico/debug.o + pico/videoport.o pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o pico/debug.o # Pico - CD OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/gfx_cd.o pico/cd/cue.o \ diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 682a6526..ac79354f 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -64,7 +64,7 @@ OBJS += platform/common/emu.o platform/common/menu.o platform/common/fonts.o pla ifeq "$(amalgamate)" "1" OBJS += ../../picoAll.o else -OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \ +OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o pico/z80if.o \ pico/videoport.o pico/draw2.o pico/draw.o pico/patch.o pico/debug.o # Pico - CD OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 9a6d8f50..4aa44d8b 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -38,7 +38,7 @@ endif # Pico OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \ - pico/videoport.o pico/draw2.o pico/draw.o pico/patch.o pico/debug.o + pico/videoport.o pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o pico/debug.o # Pico - CD OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \ diff --git a/platform/psp/Makefile b/platform/psp/Makefile index 1d6b6738..026249e1 100644 --- a/platform/psp/Makefile +++ b/platform/psp/Makefile @@ -35,8 +35,8 @@ ifeq "$(amalgamate)" "1" OBJS += ../../picoAll.o else OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o pico/videoport.o \ - pico/draw2.o pico/draw.o pico/patch.o pico/draw_amips.o pico/memory_amips.o \ - pico/misc_amips.o pico/debug.o + pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o pico/draw_amips.o pico/memory_amips.o \ + pico/misc_amips.o pico/debug.o # Pico - CD OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \