diff --git a/src/emu/cpu/z80/z80.c b/src/emu/cpu/z80/z80.c index ecc21b67fe0..4c6d23c7bcc 100644 --- a/src/emu/cpu/z80/z80.c +++ b/src/emu/cpu/z80/z80.c @@ -1,7 +1,7 @@ /***************************************************************************** * * z80.c - * Portable Z80 emulator V3.5 + * Portable Z80 emulator V3.8 * * Copyright Juergen Buchmueller, all rights reserved. * @@ -17,6 +17,11 @@ * terms of its usage and license at any time, including retroactively * - This entire notice must remain in the source code. * + * Changes in 3.8 [Miodrag Milanovic] + * - Added MEMPTR register (according to informations provided + * by Vladimir Kladov + * - BIT n,(HL) now return valid values due to use of MEMPTR + * - Fixed BIT 6,(XY+o) undocumented instructions * Changes in 3.7 [Aaron Giles] * - Changed NMI handling. NMIs are now latched in set_irq_state * but are not taken there. Instead they are taken at the start of the @@ -121,7 +126,7 @@ /****************************************************************************/ typedef struct { - PAIR prvpc,pc,sp,af,bc,de,hl,ix,iy; + PAIR prvpc,pc,sp,af,bc,de,hl,ix,iy,memptr; PAIR af2,bc2,de2,hl2; UINT8 r,r2,iff1,iff2,halt,im,i; UINT8 nmi_state; /* nmi line state */ @@ -183,6 +188,11 @@ typedef struct #define HY Z80.iy.b.h #define LY Z80.iy.b.l +#define MEMPTR Z80.memptr.w.l +#define MEMPTR_H Z80.memptr.b.h +#define MEMPTR_L Z80.memptr.b.l + + #define I Z80.i #define R Z80.r #define R2 Z80.r2 @@ -637,8 +647,8 @@ INLINE UINT32 ARG16(void) * Calculate the effective address EA of an opcode using * IX+offset resp. IY+offset addressing. ***************************************************************/ -#define EAX EA = (UINT32)(UINT16)(IX + (INT8)ARG()) -#define EAY EA = (UINT32)(UINT16)(IY + (INT8)ARG()) +#define EAX EA = (UINT32)(UINT16)(IX + (INT8)ARG()); MEMPTR = EA +#define EAY EA = (UINT32)(UINT16)(IY + (INT8)ARG()); MEMPTR = EA /*************************************************************** * POP @@ -657,6 +667,7 @@ INLINE UINT32 ARG16(void) #define JP { \ unsigned oldpc = PCD-1; \ PCD = ARG16(); \ + MEMPTR = PCD; \ change_pc(PCD); \ /* speed up busy loop */ \ if( PCD == oldpc ) \ @@ -690,6 +701,7 @@ INLINE UINT32 ARG16(void) #else #define JP { \ PCD = ARG16(); \ + MEMPTR = PCD; \ change_pc(PCD); \ } #endif @@ -702,11 +714,12 @@ INLINE UINT32 ARG16(void) if( cond ) \ { \ PCD = ARG16(); \ + MEMPTR = PCD; \ change_pc(PCD); \ } \ else \ { \ - PC += 2; \ + MEMPTR = ARG16(); /* implicit do PC += 2 */ \ } /*************************************************************** @@ -717,6 +730,7 @@ INLINE UINT32 ARG16(void) unsigned oldpc = PCD-1; \ INT8 arg = (INT8)ARG(); /* ARG() also increments PC */ \ PC += arg; /* so don't do PC += ARG() */ \ + MEMPTR = PC; \ change_pc(PCD); \ /* speed up busy loop */ \ if( PCD == oldpc ) \ @@ -756,6 +770,7 @@ INLINE UINT32 ARG16(void) { \ INT8 arg = (INT8)ARG(); /* ARG() also increments PC */ \ PC += arg; /* so don't do PC += ARG() */ \ + MEMPTR=PC; \ CC(ex,opcode); \ change_pc(PCD); \ } \ @@ -766,6 +781,7 @@ INLINE UINT32 ARG16(void) ***************************************************************/ #define CALL() \ EA = ARG16(); \ + MEMPTR = EA; \ PUSH( pc ); \ PCD = EA; \ change_pc(PCD) @@ -777,6 +793,7 @@ INLINE UINT32 ARG16(void) if( cond ) \ { \ EA = ARG16(); \ + MEMPTR = EA; \ PUSH( pc ); \ PCD = EA; \ CC(ex,opcode); \ @@ -784,7 +801,7 @@ INLINE UINT32 ARG16(void) } \ else \ { \ - PC+=2; \ + MEMPTR = ARG16(); /* implicit call PC+=2; */ \ } /*************************************************************** @@ -794,6 +811,7 @@ INLINE UINT32 ARG16(void) if( cond ) \ { \ POP( pc ); \ + MEMPTR = PC; \ change_pc(PCD); \ CC(ex,opcode); \ } @@ -804,6 +822,7 @@ INLINE UINT32 ARG16(void) #define RETN { \ LOG(("Z80 #%d RETN IFF1:%d IFF2:%d\n", cpu_getactivecpu(), IFF1, IFF2)); \ POP( pc ); \ + MEMPTR = PC; \ change_pc(PCD); \ IFF1 = IFF2; \ } @@ -813,6 +832,7 @@ INLINE UINT32 ARG16(void) ***************************************************************/ #define RETI { \ POP( pc ); \ + MEMPTR = PC; \ change_pc(PCD); \ /* according to http://www.msxnet.org/tech/z80-documented.pdf */\ IFF1 = IFF2; \ @@ -857,7 +877,8 @@ INLINE UINT32 ARG16(void) #define RST(addr) \ PUSH( pc ); \ PCD = addr; \ - change_pc(PCD) + MEMPTR = PC; \ + change_pc(PCD); /*************************************************************** * INC r8 @@ -919,6 +940,7 @@ INLINE UINT8 DEC(UINT8 value) ***************************************************************/ #define RRD { \ UINT8 n = RM(HL); \ + MEMPTR = HL+1; \ WM( HL, (n >> 4) | (A << 4) ); \ A = (A & 0xf0) | (n & 0x0f); \ F = (F & CF) | SZP[A]; \ @@ -929,6 +951,7 @@ INLINE UINT8 DEC(UINT8 value) ***************************************************************/ #define RLD { \ UINT8 n = RM(HL); \ + MEMPTR = HL+1; \ WM( HL, (n << 4) | (A & 0x0f) ); \ A = (A & 0xf0) | (n >> 4); \ F = (F & CF) | SZP[A]; \ @@ -1156,6 +1179,7 @@ INLINE UINT8 DEC(UINT8 value) RM16( SPD, &tmp ); \ WM16( SPD, &Z80.DR ); \ Z80.DR = tmp; \ + MEMPTR = Z80.DR.d; \ } @@ -1165,6 +1189,7 @@ INLINE UINT8 DEC(UINT8 value) #define ADD16(DR,SR) \ { \ UINT32 res = Z80.DR.d + Z80.SR.d; \ + MEMPTR = Z80.DR.d + 1; \ F = (F & (SF | ZF | VF)) | \ (((Z80.DR.d ^ res ^ Z80.SR.d) >> 8) & HF) | \ ((res >> 16) & CF) | ((res >> 8) & (YF | XF)); \ @@ -1177,6 +1202,7 @@ INLINE UINT8 DEC(UINT8 value) #define ADC16(Reg) \ { \ UINT32 res = HLD + Z80.Reg.d + (F & CF); \ + MEMPTR = HL + 1; \ F = (((HLD ^ res ^ Z80.Reg.d) >> 8) & HF) | \ ((res >> 16) & CF) | \ ((res >> 8) & (SF | YF | XF)) | \ @@ -1191,6 +1217,7 @@ INLINE UINT8 DEC(UINT8 value) #define SBC16(Reg) \ { \ UINT32 res = HLD - Z80.Reg.d - (F & CF); \ + MEMPTR = HL + 1; \ F = (((HLD ^ res ^ Z80.Reg.d) >> 8) & HF) | NF | \ ((res >> 16) & CF) | \ ((res >> 8) & (SF | YF | XF)) | \ @@ -1302,6 +1329,12 @@ INLINE UINT8 SRL(UINT8 value) #define BIT(bit,reg) \ F = (F & CF) | HF | SZ_BIT[reg & (1<i; break; case CPUINFO_INT_REGISTER + Z80_IX: Z80.ix.w.l = info->i; break; case CPUINFO_INT_REGISTER + Z80_IY: Z80.iy.w.l = info->i; break; + case CPUINFO_INT_REGISTER + Z80_MEMPTR: Z80.memptr.w.l = info->i; break; case CPUINFO_INT_REGISTER + Z80_R: Z80.r = info->i; Z80.r2 = info->i & 0x80; break; case CPUINFO_INT_REGISTER + Z80_I: Z80.i = info->i; break; case CPUINFO_INT_REGISTER + Z80_AF2: Z80.af2.w.l = info->i; break; @@ -3738,6 +3786,7 @@ void z80_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_REGISTER + Z80_HL: info->i = Z80.hl.w.l; break; case CPUINFO_INT_REGISTER + Z80_IX: info->i = Z80.ix.w.l; break; case CPUINFO_INT_REGISTER + Z80_IY: info->i = Z80.iy.w.l; break; + case CPUINFO_INT_REGISTER + Z80_MEMPTR: info->i = Z80.memptr.w.l; break; case CPUINFO_INT_REGISTER + Z80_R: info->i = (Z80.r & 0x7f) | (Z80.r2 & 0x80); break; case CPUINFO_INT_REGISTER + Z80_I: info->i = Z80.i; break; case CPUINFO_INT_REGISTER + Z80_AF2: info->i = Z80.af2.w.l; break; @@ -3770,7 +3819,7 @@ void z80_get_info(UINT32 state, cpuinfo *info) /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "Z80"); break; case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Zilog Z80"); break; - case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "3.7"); break; + case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "3.8"); break; case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller, all rights reserved."); break; @@ -3800,8 +3849,8 @@ void z80_get_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + Z80_DE: sprintf(info->s, "DE:%04X", Z80.de.w.l); break; case CPUINFO_STR_REGISTER + Z80_HL: sprintf(info->s, "HL:%04X", Z80.hl.w.l); break; case CPUINFO_STR_REGISTER + Z80_IX: sprintf(info->s, "IX:%04X", Z80.ix.w.l); break; - case CPUINFO_STR_REGISTER + Z80_IY: sprintf(info->s, "IY:%04X", Z80.iy.w.l); - break; + case CPUINFO_STR_REGISTER + Z80_IY: sprintf(info->s, "IY:%04X", Z80.iy.w.l); break; + case CPUINFO_STR_REGISTER + Z80_MEMPTR: sprintf(info->s, "MEMPTR:%04X", Z80.memptr.w.l); break; case CPUINFO_STR_REGISTER + Z80_R: sprintf(info->s, "R:%02X", (Z80.r & 0x7f) | (Z80.r2 & 0x80)); break; case CPUINFO_STR_REGISTER + Z80_I: sprintf(info->s, "I:%02X", Z80.i); break; case CPUINFO_STR_REGISTER + Z80_AF2: sprintf(info->s, "AF2:%04X", Z80.af2.w.l); break; diff --git a/src/emu/cpu/z80/z80.h b/src/emu/cpu/z80/z80.h index c4b165032e1..4ebd916bab3 100644 --- a/src/emu/cpu/z80/z80.h +++ b/src/emu/cpu/z80/z80.h @@ -12,7 +12,7 @@ enum Z80_AF, Z80_BC, Z80_DE, Z80_HL, Z80_IX, Z80_IY, Z80_AF2, Z80_BC2, Z80_DE2, Z80_HL2, Z80_R, Z80_I, Z80_IM, Z80_IFF1, Z80_IFF2, Z80_HALT, - Z80_DC0, Z80_DC1, Z80_DC2, Z80_DC3 + Z80_DC0, Z80_DC1, Z80_DC2, Z80_DC3, Z80_MEMPTR }; enum