From 46cbe781eb83688707a8ce9eb7c0b974a8d5508e Mon Sep 17 00:00:00 2001 From: kub Date: Wed, 4 May 2022 19:17:33 +0200 Subject: [PATCH] z80, improve cz80+drz80 compatibility --- cpu/DrZ80/drz80.S | 5568 ++++++++++++++++++++++-------------------- cpu/cz80/cz80_opCB.c | 2 + pico/z80if.c | 40 +- 3 files changed, 2931 insertions(+), 2679 deletions(-) diff --git a/cpu/DrZ80/drz80.S b/cpu/DrZ80/drz80.S index 47778aa2..518bb729 100644 --- a/cpu/DrZ80/drz80.S +++ b/cpu/DrZ80/drz80.S @@ -5,6 +5,10 @@ ;@ For commercial use, separate licencing terms must be obtained. +;@ version 0.002: +;@ modified for support of undefined F register bits by irixxxx, passes ZEXALL with a hack for +;@ BIT n,(HL), which is the only instruction needing support for the internal WZ register. + #include .data @@ -12,6 +16,8 @@ .global DrZ80Run .global DrZ80Ver + .global DrZ80_ARM ;@ need these externally to convert flags in Z80F which + .global DrARM_Z80 ;@ is in internal representation to its Z80 form .equiv INTERRUPT_MODE, 0 ;@0 = Use internal int handler, 1 = Use Mames int handler .equiv FAST_Z80SP, 0 ;@0 = Use mem functions for stack pointer, 1 = Use direct mem pointer @@ -27,7 +33,7 @@ .extern Interrupt .endif -DrZ80Ver: .long 0x0001 +DrZ80Ver: .long 0x0002 ;@ --------------------------- Defines ---------------------------- ;@ Make sure that regs/pointers for z80pc to z80sp match up! @@ -84,8 +90,8 @@ DrZ80Ver: .long 0x0001 .equ ZFlag, 2 .equ SFlag, 3 .equ HFlag, 4 - .equ NFlag, 5 - .equ Flag3, 6 + .equ Flag3, 5 ;@ NB (Flag5-Flag3) must be (Z80_Flag5-Z80_Flag3) + .equ NFlag, 6 .equ Flag5, 7 .equ Z80_CFlag, 0 @@ -102,6 +108,39 @@ DrZ80Ver: .long 0x0001 .equ Z80_HALT, 1<<2 .equ Z80_NMI, 1<<3 +;@--------------------------------------- + + .equ VBit, 1<> 3) & 7))]; + zF = (zF & ~(XF | YF)) | (zR8(Opcode & 7) & (XF | YF)); RET(8) OPCB(0x46): // BIT 0,(HL) @@ -295,6 +296,7 @@ switch (Opcode) OPCB(0x7e): // BIT 7,(HL) src = READ_MEM8(zHL); zF = (zF & CF) | HF | SZ_BIT[src & (1 << ((Opcode >> 3) & 7))]; + zF = (zF & ~(XF | YF)) | (0xc0 & (XF | YF)); // TODO ZEXALL hack, need WZ... RET(12) /*----------------------------------------- diff --git a/pico/z80if.c b/pico/z80if.c index 419d061f..aa7d99fa 100644 --- a/pico/z80if.c +++ b/pico/z80if.c @@ -13,12 +13,27 @@ uptr z80_read_map [0x10000 >> Z80_MEM_SHIFT]; uptr z80_write_map[0x10000 >> Z80_MEM_SHIFT]; +u32 z80_read(u32 a) +{ + uptr v; + a &= 0x00ffff; + v = z80_read_map[a >> Z80_MEM_SHIFT]; + if (map_flag_set(v)) + return ((z80_read_f *)(v << 1))(a); + else + return *(u8 *)((v << 1) + a); +} + + #ifdef _USE_DRZ80 // this causes trouble in some cases, like doukutsu putting sp in bank area // no perf difference for most, upto 1-2% for some others //#define FAST_Z80SP struct DrZ80 drZ80; +// import flag conversion from DrZ80 +extern u8 DrZ80_ARM[]; +extern u8 DrARM_Z80[]; static void drz80_load_pcsp(u32 pc, u32 sp) { @@ -153,17 +168,17 @@ void z80_pack(void *data) { struct z80_state *s = data; memset(data, 0, Z80_STATE_SIZE); - strcpy(s->magic, "Z80"); + memcpy(s->magic, "Z80a", 4); #if defined(_USE_DRZ80) #define DRR8(n) (drZ80.Z80##n >> 24) #define DRR16(n) (drZ80.Z80##n >> 16) #define DRR16H(n) (drZ80.Z80##n >> 24) #define DRR16L(n) ((drZ80.Z80##n >> 16) & 0xff) - s->m.a = DRR8(A); s->m.f = drZ80.Z80F; + s->m.a = DRR8(A); s->m.f = DrARM_Z80[drZ80.Z80F]; s->m.b = DRR16H(BC); s->m.c = DRR16L(BC); s->m.d = DRR16H(DE); s->m.e = DRR16L(DE); s->m.h = DRR16H(HL); s->m.l = DRR16L(HL); - s->a.a = DRR8(A2); s->a.f = drZ80.Z80F2; + s->a.a = DRR8(A2); s->a.f = DrARM_Z80[drZ80.Z80F2]; s->a.b = DRR16H(BC2); s->a.c = DRR16L(BC2); s->a.d = DRR16H(DE2); s->a.e = DRR16L(DE2); s->a.h = DRR16H(HL2); s->a.l = DRR16L(HL2); @@ -179,6 +194,9 @@ void z80_pack(void *data) s->irq_vector[0] = drZ80.z80irqvector >> 16; s->irq_vector[1] = drZ80.z80irqvector >> 8; s->irq_vector[2] = drZ80.z80irqvector; + // NB hack, swap Flag3 and NFlag for save file compatibility + s->m.f = (s->m.f & 0x9f)|((s->m.f & 0x40)>>1)|((s->m.f & 0x20)<<1); + s->a.f = (s->a.f & 0x9f)|((s->a.f & 0x40)>>1)|((s->a.f & 0x20)<<1); #elif defined(_USE_CZ80) { const cz80_struc *CPU = &CZ80; @@ -207,7 +225,7 @@ void z80_pack(void *data) int z80_unpack(const void *data) { const struct z80_state *s = data; - if (strcmp(s->magic, "Z80") != 0) { + if (memcmp(s->magic, "Z80", 3) != 0) { elprintf(EL_STATUS, "legacy z80 state - ignored"); return 0; } @@ -216,11 +234,21 @@ int z80_unpack(const void *data) #define DRW8(n, v) drZ80.Z80##n = (u32)(v) << 24 #define DRW16(n, v) drZ80.Z80##n = (u32)(v) << 16 #define DRW16HL(n, h, l) drZ80.Z80##n = ((u32)(h) << 24) | ((u32)(l) << 16) - DRW8(A, s->m.a); drZ80.Z80F = s->m.f; + u8 mf, af; + if (s->magic[3] == 'a') { + // new save: flags always in Z80 format + mf = DrZ80_ARM[s->m.f]; + af = DrZ80_ARM[s->a.f]; + } else { + // NB hack, swap Flag3 and NFlag for save file compatibility + mf = (s->m.f & 0x9f)|((s->m.f & 0x40)>>1)|((s->m.f & 0x20)<<1); + af = (s->a.f & 0x9f)|((s->a.f & 0x40)>>1)|((s->a.f & 0x20)<<1); + } + DRW8(A, s->m.a); drZ80.Z80F = mf; DRW16HL(BC, s->m.b, s->m.c); DRW16HL(DE, s->m.d, s->m.e); DRW16HL(HL, s->m.h, s->m.l); - DRW8(A2, s->a.a); drZ80.Z80F2 = s->a.f; + DRW8(A2, s->a.a); drZ80.Z80F2 = af; DRW16HL(BC2, s->a.b, s->a.c); DRW16HL(DE2, s->a.d, s->a.e); DRW16HL(HL2, s->a.h, s->a.l); -- 2.39.2