From d1591dc8440a5a896f22875b519e94cf177d8855 Mon Sep 17 00:00:00 2001 From: Ian C Date: Mon, 7 May 2007 02:01:56 +0000 Subject: Display not yet working; emulation too slow. --- include/spec.h | 2 +- include/z80.h | 115 +-- include/z80_decode.c | 2522 ------------------------------------------------- include/z80_private.h | 122 ++- source/keyboard.c | 2 +- source/main.c | 2 +- source/spec.c | 22 +- source/z80.c | 191 ++-- source/z80_decode.c | 125 +-- source/z80_dis.c | 26 +- 10 files changed, 319 insertions(+), 2810 deletions(-) delete mode 100644 include/z80_decode.c diff --git a/include/spec.h b/include/spec.h index bcb587c..35ed5ed 100644 --- a/include/spec.h +++ b/include/spec.h @@ -2,7 +2,7 @@ dsspec - Nintendo DS Sinclair Spectrum 48K emulator. - Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + Copyright (C) 2006 Ian Cowburn (ianc@noddybox.demon.co.uk) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/include/z80.h b/include/z80.h index 0b7424b..000b950 100644 --- a/include/z80.h +++ b/include/z80.h @@ -27,14 +27,13 @@ #ifndef Z80_H #define Z80_H "$Id$" -/* ---------------------------------------- TYPES +/* Configuration */ +#include "z80_config.h" -/* The processor -*/ -struct Z80; -typedef struct Z80 Z80; +/* ---------------------------------------- TYPES +*/ /* Large unsigned type */ @@ -56,6 +55,53 @@ typedef signed char Z80Relative; typedef unsigned short Z80Word; +/* A Z80 16-bit register. To access the HI/LO component use the indexes + Z80_HI_WORD and Z80_LO_WORD which will be initialised once Z80Init has been + called. +*/ +typedef union +{ + Z80Word w; + Z80Byte b[2]; +} Z80Reg; + +extern int Z80_HI_WORD; +extern int Z80_LO_WORD; + + +/* The processor +*/ +struct Z80Private; + +typedef struct +{ + Z80Word PC; + + Z80Reg AF; + Z80Reg BC; + Z80Reg DE; + Z80Reg HL; + + Z80Word AF_; + Z80Word BC_; + Z80Word DE_; + Z80Word HL_; + + Z80Reg IX; + Z80Reg IY; + + Z80Word SP; + + Z80Byte IFF1; + Z80Byte IFF2; + Z80Byte IM; + Z80Byte I; + Z80Byte R; + + struct Z80Private *priv; +} Z80; + + /* Interfaces used to handle memory */ typedef Z80Byte (*Z80ReadMemory)(Z80 *cpu, Z80Word address); @@ -95,36 +141,6 @@ typedef enum } Z80CallbackReason; -/* Get/settable state of the Z80 -*/ -typedef struct -{ - Z80Word PC; - Z80Word SP; - - Z80Val cycle; - - Z80Word AF; - Z80Word BC; - Z80Word DE; - Z80Word HL; - - Z80Word AF_; /* Alternate registers */ - Z80Word BC_; - Z80Word DE_; - Z80Word HL_; - - Z80Word IX; - Z80Word IY; - - Z80Byte IFF1; - Z80Byte IFF2; - Z80Byte IM; - Z80Byte I; - Z80Byte R; -} Z80State; - - /* Flags in the F register */ typedef enum @@ -157,11 +173,16 @@ typedef struct /* Initialises the processor. */ +#ifdef ENABLE_ARRAY_MEMORY +Z80 *Z80Init(Z80ReadPort read_port, + Z80WritePort write_port); +#else Z80 *Z80Init(Z80ReadMemory read_memory, Z80WriteMemory write_memory, Z80ReadPort read_port, Z80WritePort write_port, Z80ReadMemory read_for_disassem); +#endif /* Resets the processor. @@ -169,21 +190,6 @@ Z80 *Z80Init(Z80ReadMemory read_memory, void Z80Reset(Z80 *cpu); -/* Sets the PC -*/ -void Z80SetPC(Z80 *cpu, Z80Word PC); - - -/* Gets the PC -*/ -Z80Word Z80GetPC(Z80 *cpu); - - -/* Sets the cycle count to the specified count -*/ -void Z80ResetCycles(Z80 *cpu, Z80Val cycles); - - /* Lodge a callback to be invoked after special events. Returns FALSE if the callback couldn't be lodged (there is a max of 10 callbacks per reason). @@ -223,11 +229,10 @@ int Z80SingleStep(Z80 *cpu); void Z80Exec(Z80 *cpu); -/* Interrogate the state of the Z80 +/* Manipulate the cylce count of the Z80 */ Z80Val Z80Cycles(Z80 *cpu); -void Z80GetState(Z80 *cpu, Z80State *state); -void Z80SetState(Z80 *cpu, const Z80State *state); +void Z80ResetCycles(Z80 *cpu, Z80Val cycles); /* Set address to label mappings for the disassembler @@ -235,8 +240,8 @@ void Z80SetState(Z80 *cpu, const Z80State *state); void Z80SetLabels(Z80Label labels[]); -/* Simple disassembly of memory accessed through read_for_disassem. - addr is updated on exit. +/* Simple disassembly of memory accessed through read_for_disassem, or + Z80_MEMORY as appropriate. addr is updated on exit. */ const char *Z80Disassemble(Z80 *cpu, Z80Word *addr); diff --git a/include/z80_decode.c b/include/z80_decode.c deleted file mode 100644 index ced7fbd..0000000 --- a/include/z80_decode.c +++ /dev/null @@ -1,2522 +0,0 @@ -/* - - z80 - Z80 Emulator - - Copyright (C) 2006 Ian Cowburn - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - ------------------------------------------------------------------------- - - $Id$ - -*/ -#include -#include - -#include "z80.h" -#include "z80_private.h" - -static const char ident[]="$Id$"; - -/* ---------------------------------------- TABLES AND INIT -*/ -static Z80Byte PSZtable[512]; -static Z80Byte SZtable[512]; -static Z80Byte Ptable[512]; -static Z80Byte Stable[512]; -static Z80Byte Ztable[512]; - - -static int HI; -static int LO; - -/* ---------------------------------------- MISC FUNCTIONS -*/ -void Z80_InitialiseInternals(void) -{ - Z80Word f; - Z80Reg r; - - /* Check endianness - */ - r.w=0x1234; - - if (r.b[0] == 0x12) - { - HI=0; - LO=1; - } - else if (r.b[1] == 0x12) - { - HI=1; - LO=0; - } - else - { - exit(1); - } - - /* Check variable sizes - */ - if (CHAR_BIT!=8 || sizeof(Z80Word)!=2) - { - exit(2); - } - - /* Initialise flag tables - */ - for(f=0;f<256;f++) - { - Z80Byte p,z,s; - int b; - - p=0; - - for(b=0;b<8;b++) - if (f&(1<mwrite(cpu,addr,val); - cpu->mwrite(cpu,addr+1,val>>8); -} - - -/* ---------------------------------------- GENERAL MACROS -*/ -#define SWAP(A,B) \ -do { \ - unsigned swap_tmp; \ - swap_tmp=A; \ - A=B; \ - B=swap_tmp; \ -} while(0) - - -/* ---------------------------------------- ARITHMETIC OPS -*/ -#define ADD8(ONCE) \ -do { \ - Z80Byte VAL=ONCE; \ - unsigned w; \ - w=cpu->AF.b[HI]+(unsigned)VAL; \ - cpu->AF.b[LO]=SZtable[w]; \ - if ((cpu->AF.b[HI]^w^VAL)&H_Z80) cpu->AF.b[LO]|=H_Z80; \ - if ((VAL^cpu->AF.b[HI]^0x80)&(VAL^w)&0x80) cpu->AF.b[LO]|=P_Z80; \ - SETHIDDEN(w); \ - cpu->AF.b[HI]=w; \ -} while(0) - - -#define ADC8(ONCE) \ -do { \ - Z80Byte VAL=ONCE; \ - unsigned w; \ - w=(cpu->AF.b[HI]+(unsigned)VAL+CARRY)&0x1ff; \ - cpu->AF.b[LO]=SZtable[w]; \ - if ((cpu->AF.b[HI]^w^VAL)&H_Z80) cpu->AF.b[LO]|=H_Z80; \ - if ((VAL^cpu->AF.b[HI]^0x80)&(VAL^w)&0x80) cpu->AF.b[LO]|=P_Z80; \ - SETHIDDEN(w); \ - cpu->AF.b[HI]=w; \ -} while(0) - - -#define SUB8(ONCE) \ -do { \ - Z80Byte VAL=ONCE; \ - unsigned w; \ - w=(cpu->AF.b[HI]-(unsigned)VAL)&0x1ff; \ - cpu->AF.b[LO]=SZtable[w]|N_Z80; \ - if ((cpu->AF.b[HI]^w^VAL)&H_Z80) cpu->AF.b[LO]|=H_Z80; \ - if ((VAL^cpu->AF.b[HI])&(cpu->AF.b[HI]^w)&0x80) cpu->AF.b[LO]|=P_Z80; \ - SETHIDDEN(w); \ - cpu->AF.b[HI]=w; \ -} while(0) - - -#define CMP8(ONCE) \ -do { \ - Z80Byte VAL=ONCE; \ - unsigned w; \ - w=(cpu->AF.b[HI]-(unsigned)VAL)&0x1ff; \ - cpu->AF.b[LO]=SZtable[w]|N_Z80; \ - if ((cpu->AF.b[HI]^w^VAL)&H_Z80) cpu->AF.b[LO]|=H_Z80; \ - if ((VAL^cpu->AF.b[HI])&(cpu->AF.b[HI]^w)&0x80) cpu->AF.b[LO]|=P_Z80; \ - SETHIDDEN(VAL); \ -} while(0) - - -#define SBC8(ONCE) \ -do { \ - Z80Byte VAL=ONCE; \ - unsigned w; \ - w=(cpu->AF.b[HI]-(unsigned)VAL-CARRY)&0x1ff; \ - cpu->AF.b[LO]=SZtable[w]|N_Z80; \ - if ((cpu->AF.b[HI]^w^VAL)&H_Z80) cpu->AF.b[LO]|=H_Z80; \ - if ((VAL^cpu->AF.b[HI])&(cpu->AF.b[HI]^w)&0x80) cpu->AF.b[LO]|=P_Z80; \ - SETHIDDEN(w); \ - cpu->AF.b[HI]=w; \ -} while(0) - - -#define ADD16(REG,ONCE) \ -do { \ - Z80Word VAL=ONCE; \ - Z80Val w; \ - w=(REG)+(Z80Val)VAL; \ - cpu->AF.b[LO]&=(S_Z80|Z_Z80|V_Z80); \ - if (w>0xffff) cpu->AF.b[LO]|=C_Z80; \ - if (((REG)^w^VAL)&0x1000) cpu->AF.b[LO]|=H_Z80; \ - SETHIDDEN(w>>8); \ - (REG)=w; \ -} while(0) - - -#define ADC16(REG, ONCE) \ -do { \ - Z80Word VAL=ONCE; \ - Z80Val w; \ - w=(REG)+(Z80Val)VAL+CARRY; \ - cpu->AF.b[LO]=0; \ - if ((w&0xffff)==0) cpu->AF.b[LO]=Z_Z80; \ - if (w&0x8000) cpu->AF.b[LO]|=S_Z80; \ - if (w>0xffff) cpu->AF.b[LO]|=C_Z80; \ - if ((VAL^(REG)^0x8000)&((REG)^w)&0x8000) cpu->AF.b[LO]|=P_Z80; \ - if (((REG)^w^VAL)&0x1000) cpu->AF.b[LO]|=H_Z80; \ - SETHIDDEN(w>>8); \ - (REG)=w; \ -} while(0) - - -#define SBC16(REG, ONCE) \ -do { \ - Z80Word VAL=ONCE; \ - Z80Val w; \ - w=(REG)-(Z80Val)VAL-CARRY; \ - cpu->AF.b[LO]=N_Z80; \ - if (w&0x8000) cpu->AF.b[LO]|=S_Z80; \ - if ((w&0xffff)==0) cpu->AF.b[LO]|=Z_Z80; \ - if (w>0xffff) cpu->AF.b[LO]|=C_Z80; \ - if ((VAL^(REG))&((REG)^w)&0x8000) cpu->AF.b[LO]|=P_Z80; \ - if (((REG)^w^VAL)&0x1000) cpu->AF.b[LO]|=H_Z80; \ - SETHIDDEN(w>>8); \ - (REG)=w; \ -} while(0) - - -#define INC8(REG) \ -do { \ - (REG)++; \ - cpu->AF.b[LO]=CARRY|SZtable[(REG)]; \ - if ((REG)==0x80) cpu->AF.b[LO]|=P_Z80; \ - if (((REG)&0x0f)==0) cpu->AF.b[LO]|=H_Z80; \ -} while(0) - - -#define DEC8(REG) \ -do { \ - (REG)--; \ - cpu->AF.b[LO]=N_Z80|CARRY; \ - if ((REG)==0x7f) cpu->AF.b[LO]|=P_Z80; \ - if (((REG)&0x0f)==0x0f) cpu->AF.b[LO]|=H_Z80; \ - cpu->AF.b[LO]|=SZtable[(REG)]; \ -} while(0) - - -#define OP_ON_MEM(OP,addr) \ -do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ - OP(memop); \ - cpu->mwrite(cpu,addr,memop); \ -} while(0) - - -#define OP_ON_MEM_WITH_ARG(OP,addr,arg) \ -do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ - OP(memop,arg); \ - cpu->mwrite(cpu,addr,memop); \ -} while(0) - - -#define OP_ON_MEM_WITH_COPY(OP,addr,copy) \ -do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ - OP(memop); \ - copy=memop; \ - cpu->mwrite(cpu,addr,memop); \ -} while(0) - - -#define OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,arg,copy) \ -do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ - OP(memop,arg); \ - copy=memop; \ - cpu->mwrite(cpu,addr,memop); \ -} while(0) - - -/* ---------------------------------------- ROTATE AND SHIFT OPS -*/ -#define RRCA \ -do { \ - cpu->AF.b[LO]=(cpu->AF.b[LO]&(S_Z80|Z_Z80|P_Z80))|(cpu->AF.b[HI]&C_Z80); \ - cpu->AF.b[HI]=(cpu->AF.b[HI]>>1)|(cpu->AF.b[HI]<<7); \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define RRA \ -do { \ - Z80Byte c; \ - c=CARRY; \ - cpu->AF.b[LO]=(cpu->AF.b[LO]&(S_Z80|Z_Z80|P_Z80))|(cpu->AF.b[HI]&C_Z80); \ - cpu->AF.b[HI]=(cpu->AF.b[HI]>>1)|(c<<7); \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define RRC(REG) \ -do { \ - Z80Byte c; \ - c=(REG)&C_Z80; \ - (REG)=((REG)>>1)|((REG)<<7); \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define RR(REG) \ -do { \ - Z80Byte c; \ - c=(REG)&C_Z80; \ - (REG)=((REG)>>1)|(CARRY<<7); \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define RLCA \ -do { \ - cpu->AF.b[LO]=(cpu->AF.b[LO]&(S_Z80|Z_Z80|P_Z80))|(cpu->AF.b[HI]>>7); \ - cpu->AF.b[HI]=(cpu->AF.b[HI]<<1)|(cpu->AF.b[HI]>>7); \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define RLA \ -do { \ - Z80Byte c; \ - c=CARRY; \ - cpu->AF.b[LO]=(cpu->AF.b[LO]&(S_Z80|Z_Z80|P_Z80))|(cpu->AF.b[HI]>>7); \ - cpu->AF.b[HI]=(cpu->AF.b[HI]<<1)|c; \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define RLC(REG) \ -do { \ - Z80Byte c; \ - c=(REG)>>7; \ - (REG)=((REG)<<1)|c; \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define RL(REG) \ -do { \ - Z80Byte c; \ - c=(REG)>>7; \ - (REG)=((REG)<<1)|CARRY; \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define SRL(REG) \ -do { \ - Z80Byte c; \ - c=(REG)&C_Z80; \ - (REG)>>=1; \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define SRA(REG) \ -do { \ - Z80Byte c; \ - c=(REG)&C_Z80; \ - (REG)=((REG)>>1)|((REG)&0x80); \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define SLL(REG) \ -do { \ - Z80Byte c; \ - c=(REG)>>7; \ - (REG)=((REG)<<1)|1; \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -#define SLA(REG) \ -do { \ - Z80Byte c; \ - c=(REG)>>7; \ - (REG)=(REG)<<1; \ - cpu->AF.b[LO]=PSZtable[(REG)]|c; \ - SETHIDDEN(REG); \ -} while(0) - - -/* ---------------------------------------- BOOLEAN OPS -*/ -#define AND(VAL) \ -do { \ - cpu->AF.b[HI]&=VAL; \ - cpu->AF.b[LO]=PSZtable[cpu->AF.b[HI]]|H_Z80; \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define OR(VAL) \ -do { \ - cpu->AF.b[HI]|=VAL; \ - cpu->AF.b[LO]=PSZtable[cpu->AF.b[HI]]; \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define XOR(VAL) \ -do { \ - cpu->AF.b[HI]^=VAL; \ - cpu->AF.b[LO]=PSZtable[cpu->AF.b[HI]]; \ - SETHIDDEN(cpu->AF.b[HI]); \ -} while(0) - - -#define BIT(REG,B) \ -do { \ - cpu->AF.b[LO]=CARRY|H_Z80; \ - if ((REG)&(1<AF.b[LO]|=S_Z80; \ - if (B==5 && (REG&B5_Z80)) cpu->AF.b[LO]|=B5_Z80; \ - if (B==3 && (REG&B3_Z80)) cpu->AF.b[LO]|=B3_Z80; \ - } \ - else \ - { \ - cpu->AF.b[LO]|=Z_Z80; \ - cpu->AF.b[LO]|=P_Z80; \ - } \ -} while(0) - -#define BIT_SET(REG,B) (REG)|=(1<PC); \ - } \ - else \ - { \ - TSTATE(5); \ - } \ -} while(0) - - -#define RST(ADDR) \ - TSTATE(11); \ - PUSH(cpu->PC); \ - cpu->PC=ADDR - -/* ---------------------------------------- BLOCK OPERATIONS -*/ -#define LDI \ -do { \ - Z80Byte b; \ - \ - b=PEEK(cpu->HL.w); \ - POKE(cpu->DE.w,b); \ - cpu->DE.w++; \ - cpu->HL.w++; \ - cpu->BC.w--; \ - \ - CLRFLAG(H_Z80); \ - CLRFLAG(N_Z80); \ - \ - if (cpu->BC.w) \ - SETFLAG(P_Z80); \ - else \ - CLRFLAG(P_Z80); \ - \ - SETHIDDEN(cpu->AF.b[HI]+b); \ -} while(0) - -#define LDD \ -do { \ - Z80Byte b; \ - \ - b=PEEK(cpu->HL.w); \ - POKE(cpu->DE.w,b); \ - cpu->DE.w--; \ - cpu->HL.w--; \ - cpu->BC.w--; \ - \ - CLRFLAG(H_Z80); \ - CLRFLAG(N_Z80); \ - \ - if (cpu->BC.w) \ - SETFLAG(P_Z80); \ - else \ - CLRFLAG(P_Z80); \ - \ - SETHIDDEN(cpu->AF.b[HI]+b); \ -} while(0) - -#define CPI \ -do { \ - Z80Byte c,b; \ - \ - c=CARRY; \ - b=PEEK(cpu->HL.w); \ - \ - CMP8(b); \ - \ - if (c) \ - SETFLAG(C_Z80); \ - else \ - CLRFLAG(C_Z80); \ - \ - cpu->HL.w++; \ - cpu->BC.w--; \ - \ - if (cpu->BC.w) \ - SETFLAG(P_Z80); \ - else \ - CLRFLAG(P_Z80); \ -} while(0) - -#define CPD \ -do { \ - Z80Byte c,b; \ - \ - c=CARRY; \ - b=PEEK(cpu->HL.w); \ - \ - CMP8(b); \ - \ - if (c) \ - SETFLAG(C_Z80); \ - else \ - CLRFLAG(C_Z80); \ - \ - cpu->HL.w--; \ - cpu->BC.w--; \ - \ - if (cpu->BC.w) \ - SETFLAG(P_Z80); \ - else \ - CLRFLAG(P_Z80); \ -} while(0) - -#define INI \ -do { \ - Z80Word w; \ - Z80Byte b; \ - \ - b=IN(cpu->BC.w); \ - POKE(cpu->HL.w,b); \ - \ - cpu->BC.b[HI]--; \ - cpu->HL.w++; \ - \ - cpu->AF.b[LO]=SZtable[cpu->BC.b[HI]]; \ - SETHIDDEN(cpu->BC.b[HI]); \ - \ - w=(((Z80Word)cpu->BC.b[LO])&0xff)+b; \ - \ - if (b&0x80) \ - SETFLAG(N_Z80); \ - \ - if (w&0x100) \ - { \ - SETFLAG(C_Z80); \ - SETFLAG(H_Z80); \ - } \ - else \ - { \ - CLRFLAG(C_Z80); \ - CLRFLAG(H_Z80); \ - } \ -} while(0) - -#define IND \ -do { \ - Z80Word w; \ - Z80Byte b; \ - \ - b=IN(cpu->BC.w); \ - POKE(cpu->HL.w,b); \ - \ - cpu->BC.b[HI]--; \ - cpu->HL.w--; \ - \ - cpu->AF.b[LO]=SZtable[cpu->BC.b[HI]]; \ - SETHIDDEN(cpu->BC.b[HI]); \ - \ - w=(((Z80Word)cpu->BC.b[LO])&0xff)+b; \ - \ - if (b&0x80) \ - SETFLAG(N_Z80); \ - \ - if (w&0x100) \ - { \ - SETFLAG(C_Z80); \ - SETFLAG(H_Z80); \ - } \ - else \ - { \ - CLRFLAG(C_Z80); \ - CLRFLAG(H_Z80); \ - } \ -} while(0) \ - -#define OUTI \ -do { \ - OUT(cpu->BC.w,PEEK(cpu->HL.w)); \ - \ - cpu->HL.w++; \ - cpu->BC.b[HI]--; \ - \ - cpu->AF.b[LO]=SZtable[cpu->BC.b[HI]]; \ - SETHIDDEN(cpu->BC.b[HI]); \ -} while(0) - -#define OUTD \ -do { \ - OUT(cpu->BC.w,PEEK(cpu->HL.w)); \ - \ - cpu->HL.w--; \ - cpu->BC.b[HI]--; \ - \ - cpu->AF.b[LO]=SZtable[cpu->BC.b[HI]]; \ - SETFLAG(N_Z80); \ - SETHIDDEN(cpu->BC.b[HI]); \ -} while(0) - - -/* ---------------------------------------- BASE OPCODE SHORT-HAND BLOCKS -*/ - -#define LD_BLOCK(BASE,DEST,DEST2) \ - case BASE: /* LD DEST,B */ \ - TSTATE(4); \ - DEST=cpu->BC.b[HI]; \ - break; \ - \ - case BASE+1: /* LD DEST,C */ \ - TSTATE(4); \ - DEST=cpu->BC.b[LO]; \ - break; \ - \ - case BASE+2: /* LD DEST,D */ \ - TSTATE(4); \ - DEST=cpu->DE.b[HI]; \ - break; \ - \ - case BASE+3: /* LD DEST,E */ \ - TSTATE(4); \ - DEST=cpu->DE.b[LO]; \ - break; \ - \ - case BASE+4: /* LD DEST,H */ \ - TSTATE(4); \ - DEST=*H; \ - break; \ - \ - case BASE+5: /* LD DEST,L */ \ - TSTATE(4); \ - DEST=*L; \ - break; \ - \ - case BASE+6: /* LD DEST,(HL) */ \ - TSTATE(7); \ - OFFSET(off); \ - DEST2=cpu->mread(cpu,*HL+off); \ - break; \ - \ - case BASE+7: /* LD DEST,A */ \ - TSTATE(4); \ - DEST=cpu->AF.b[HI]; \ - break; - -#define ALU_BLOCK(BASE,OP) \ - case BASE: /* OP A,B */ \ - TSTATE(4); \ - OP(cpu->BC.b[HI]); \ - break; \ - \ - case BASE+1: /* OP A,C */ \ - TSTATE(4); \ - OP(cpu->BC.b[LO]); \ - break; \ - \ - case BASE+2: /* OP A,D */ \ - TSTATE(4); \ - OP(cpu->DE.b[HI]); \ - break; \ - \ - case BASE+3: /* OP A,E */ \ - TSTATE(4); \ - OP(cpu->DE.b[LO]); \ - break; \ - \ - case BASE+4: /* OP A,H */ \ - TSTATE(4); \ - OP(*H); \ - break; \ - \ - case BASE+5: /* OP A,L */ \ - TSTATE(4); \ - OP(*L); \ - break; \ - \ - case BASE+6: /* OP A,(HL) */ \ - TSTATE(7); \ - OFFSET(off); \ - OP_ON_MEM(OP,*HL+off); \ - break; \ - \ - case BASE+7: /* OP A,A */ \ - TSTATE(4); \ - OP(cpu->AF.b[HI]); \ - break; - - -/* ---------------------------------------- CB OPCODE SHORT-HAND BLOCKS -*/ - -#define CB_ALU_BLOCK(BASE,OP) \ - case BASE: /* OP B */ \ - TSTATE(8); \ - OP(cpu->BC.b[HI]); \ - break; \ - \ - case BASE+1: /* OP C */ \ - TSTATE(8); \ - OP(cpu->BC.b[LO]); \ - break; \ - \ - case BASE+2: /* OP D */ \ - TSTATE(8); \ - OP(cpu->DE.b[HI]); \ - break; \ - \ - case BASE+3: /* OP E */ \ - TSTATE(8); \ - OP(cpu->DE.b[LO]); \ - break; \ - \ - case BASE+4: /* OP H */ \ - TSTATE(8); \ - OP(cpu->HL.b[HI]); \ - break; \ - \ - case BASE+5: /* OP L */ \ - TSTATE(8); \ - OP(cpu->HL.b[LO]); \ - break; \ - \ - case BASE+6: /* OP (HL) */ \ - TSTATE(15); \ - OP_ON_MEM(OP,cpu->HL.w); \ - break; \ - \ - case BASE+7: /* OP A */ \ - TSTATE(8); \ - OP(cpu->AF.b[HI]); \ - break; - -#define CB_BITMANIP_BLOCK(BASE,OP,BIT_NO) \ - case BASE: /* OP B */ \ - TSTATE(8); \ - OP(cpu->BC.b[HI],BIT_NO); \ - break; \ - \ - case BASE+1: /* OP C */ \ - TSTATE(8); \ - OP(cpu->BC.b[LO],BIT_NO); \ - break; \ - \ - case BASE+2: /* OP D */ \ - TSTATE(8); \ - OP(cpu->DE.b[HI],BIT_NO); \ - break; \ - \ - case BASE+3: /* OP E */ \ - TSTATE(8); \ - OP(cpu->DE.b[LO],BIT_NO); \ - break; \ - \ - case BASE+4: /* OP H */ \ - TSTATE(8); \ - OP(cpu->HL.b[HI],BIT_NO); \ - break; \ - \ - case BASE+5: /* OP L */ \ - TSTATE(8); \ - OP(cpu->HL.b[LO],BIT_NO); \ - break; \ - \ - case BASE+6: /* OP (HL) */ \ - TSTATE(12); \ - OP_ON_MEM_WITH_ARG(OP,cpu->HL.w,BIT_NO); \ - break; \ - \ - case BASE+7: /* OP A */ \ - TSTATE(8); \ - OP(cpu->AF.b[HI],BIT_NO); \ - break; - -/* ---------------------------------------- SHIFTED CB OPCODE SHORT-HAND BLOCKS -*/ - -#define SHIFTED_CB_ALU_BLOCK(BASE,OP) \ - case BASE: /* OP B */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->BC.b[HI]); \ - break; \ - \ - case BASE+1: /* OP C */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->BC.b[LO]); \ - break; \ - \ - case BASE+2: /* OP D */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->DE.b[HI]); \ - break; \ - \ - case BASE+3: /* OP E */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->DE.b[LO]); \ - break; \ - \ - case BASE+4: /* OP H */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->HL.b[HI]); \ - break; \ - \ - case BASE+5: /* OP L */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->HL.b[LO]); \ - break; \ - \ - case BASE+6: /* OP (HL) */ \ - TSTATE(15); \ - OP_ON_MEM(OP,addr); \ - break; \ - \ - case BASE+7: /* OP A */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_COPY(OP,addr,cpu->AF.b[HI]); \ - break; - -#define SHIFTED_CB_BITMANIP_BLOCK(BASE,OP,BIT_NO) \ - case BASE: /* OP B */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->BC.b[HI]); \ - break; \ - \ - case BASE+1: /* OP C */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->BC.b[LO]); \ - break; \ - \ - case BASE+2: /* OP D */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->DE.b[HI]); \ - break; \ - \ - case BASE+3: /* OP E */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->DE.b[LO]); \ - break; \ - \ - case BASE+4: /* OP H */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->HL.b[HI]); \ - break; \ - \ - case BASE+5: /* OP L */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->HL.b[LO]); \ - break; \ - \ - case BASE+6: /* OP (HL) */ \ - TSTATE(12); \ - OP_ON_MEM_WITH_ARG(OP,addr,BIT_NO); \ - break; \ - \ - case BASE+7: /* OP A */ \ - TSTATE(8); \ - OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,BIT_NO,cpu->AF.b[HI]); \ - break; - -/* ---------------------------------------- DAA -*/ - -/* This alogrithm is based on info from - http://www.worldofspectrum.org/faq/reference/z80reference.htm -*/ -static void DAA (Z80 *cpu) -{ - Z80Byte add=0; - Z80Byte carry=0; - Z80Byte nf=cpu->AF.b[LO]&N_Z80; - Z80Byte acc=cpu->AF.b[HI]; - - if (acc>0x99 || IS_C) - { - add|=0x60; - carry=C_Z80; - } - - if ((acc&0xf)>0x9 || IS_H) - { - add|=0x06; - } - - if (nf) - { - cpu->AF.b[HI]-=add; - } - else - { - cpu->AF.b[HI]+=add; - } - - cpu->AF.b[LO]=PSZtable[cpu->AF.b[HI]] - | carry - | nf - | ((acc^cpu->AF.b[HI])&H_Z80) - | (cpu->AF.b[HI]&(B3_Z80|B5_Z80)); -} - -/* ---------------------------------------- HANDLERS FOR ED OPCODES -*/ -static void DecodeED(Z80 *cpu, Z80Byte opcode) -{ - switch(opcode) - { - case 0x40: /* IN B,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->BC.b[HI]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->BC.b[HI]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->BC.b[HI]]; - SETHIDDEN(cpu->BC.b[HI]); - break; - - case 0x41: /* OUT (C),B */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->BC.b[HI]); - break; - - case 0x42: /* SBC HL,BC */ - TSTATE(15); - SBC16(cpu->HL.w,cpu->BC.w); - break; - - case 0x43: /* LD (nnnn),BC */ - TSTATE(20); - POKEW(FETCH_WORD,cpu->BC.w); - break; - - case 0x44: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x45: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x46: /* IM 0 */ - TSTATE(8); - cpu->IM=0; - break; - - case 0x47: /* LD I,A */ - TSTATE(9); - cpu->I=cpu->AF.b[HI]; - break; - - case 0x48: /* IN C,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->BC.b[LO]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->BC.b[LO]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->BC.b[LO]]; - SETHIDDEN(cpu->BC.b[LO]); - break; - - case 0x49: /* OUT (C),C */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->BC.b[LO]); - break; - - case 0x4a: /* ADC HL,BC */ - TSTATE(15); - ADC16(cpu->HL.w,cpu->BC.w); - break; - - case 0x4b: /* LD BC,(nnnn) */ - TSTATE(20); - cpu->BC.w=PEEKW(FETCH_WORD); - break; - - case 0x4c: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x4d: /* RETI */ - TSTATE(14); - CALLBACK(eZ80_RETI,0); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x4e: /* IM 0/1 */ - TSTATE(8); - cpu->IM=0; - break; - - case 0x4f: /* LD R,A */ - TSTATE(9); - cpu->R=cpu->AF.b[HI]; - break; - - case 0x50: /* IN D,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->DE.b[HI]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->DE.b[HI]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->DE.b[HI]]; - SETHIDDEN(cpu->BC.b[HI]); - break; - - case 0x51: /* OUT (C),D */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->DE.b[HI]); - break; - - case 0x52: /* SBC HL,DE */ - TSTATE(15); - SBC16(cpu->HL.w,cpu->DE.w); - break; - - case 0x53: /* LD (nnnn),DE */ - TSTATE(20); - POKEW(FETCH_WORD,cpu->DE.w); - break; - - case 0x54: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x55: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x56: /* IM 1 */ - TSTATE(8); - cpu->IM=1; - break; - - case 0x57: /* LD A,I */ - TSTATE(9); - cpu->AF.b[HI]=cpu->I; - break; - - case 0x58: /* IN E,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->DE.b[LO]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->BC.b[LO]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->DE.b[LO]]; - SETHIDDEN(cpu->DE.b[LO]); - break; - - case 0x59: /* OUT (C),E */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->DE.b[LO]); - break; - - case 0x5a: /* ADC HL,DE */ - TSTATE(15); - ADC16(cpu->HL.w,cpu->DE.w); - break; - - case 0x5b: /* LD DE,(nnnn) */ - TSTATE(20); - cpu->DE.w=PEEKW(FETCH_WORD); - break; - - case 0x5c: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x5d: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x5e: /* IM 2 */ - TSTATE(8); - cpu->IM=2; - break; - - case 0x5f: /* LD A,R */ - TSTATE(9); - cpu->AF.b[HI]=cpu->R; - break; - - case 0x60: /* IN H,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->HL.b[HI]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->HL.b[HI]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->HL.b[HI]]; - SETHIDDEN(cpu->HL.b[HI]); - break; - - case 0x61: /* OUT (C),H */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->HL.b[HI]); - break; - - case 0x62: /* SBC HL,HL */ - TSTATE(15); - SBC16(cpu->HL.w,cpu->HL.w); - break; - - case 0x63: /* LD (nnnn),HL */ - TSTATE(20); - POKEW(FETCH_WORD,cpu->HL.w); - break; - - case 0x64: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x65: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x66: /* IM 0 */ - TSTATE(8); - cpu->IM=0; - break; - - case 0x67: /* RRD */ - { - Z80Byte b; - - TSTATE(18); - - b=PEEK(cpu->HL.w); - - POKE(cpu->HL.w,(b>>4)|(cpu->AF.b[HI]<<4)); - cpu->AF.b[HI]=(cpu->AF.b[HI]&0xf0)|(b&0x0f); - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->AF.b[HI]]; - SETHIDDEN(cpu->AF.b[HI]); - break; - } - - case 0x68: /* IN L,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->HL.b[LO]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->HL.b[LO]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->HL.b[LO]]; - SETHIDDEN(cpu->HL.b[LO]); - break; - - case 0x69: /* OUT (C),L */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->HL.b[LO]); - break; - - case 0x6a: /* ADC HL,HL */ - TSTATE(15); - ADC16(cpu->HL.w,cpu->HL.w); - break; - - case 0x6b: /* LD HL,(nnnn) */ - TSTATE(20); - cpu->HL.w=PEEKW(FETCH_WORD); - break; - - case 0x6c: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x6d: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x6e: /* IM 0/1 */ - TSTATE(8); - cpu->IM=0; - break; - - case 0x6f: /* RLD */ - { - Z80Byte b; - - TSTATE(18); - - b=PEEK(cpu->HL.w); - - POKE(cpu->HL.w,(b<<4)|(cpu->AF.b[HI]&0x0f)); - cpu->AF.b[HI]=(cpu->AF.b[HI]&0xf0)|(b>>4); - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->AF.b[HI]]; - SETHIDDEN(cpu->AF.b[HI]); - break; - } - - case 0x70: /* IN (C) */ - { - Z80Byte b; - - TSTATE(12); - - if (cpu->pread) - { - b=cpu->pread(cpu,cpu->BC.w); - } - else - { - b=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[b]; - SETHIDDEN(b); - break; - } - - case 0x71: /* OUT (C) */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,0); - break; - - case 0x72: /* SBC HL,SP */ - TSTATE(15); - SBC16(cpu->HL.w,cpu->SP); - break; - - case 0x73: /* LD (nnnn),SP */ - TSTATE(20); - POKEW(FETCH_WORD,cpu->SP); - break; - - case 0x74: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x75: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x76: /* IM 1 */ - TSTATE(8); - cpu->IM=1; - break; - - case 0x77: /* NOP */ - TSTATE(8); - CALLBACK(eZ80_EDHook,opcode); - break; - - case 0x78: /* IN A,(C) */ - TSTATE(12); - - if (cpu->pread) - { - cpu->AF.b[HI]=cpu->pread(cpu,cpu->BC.w); - } - else - { - cpu->AF.b[HI]=0; - } - - cpu->AF.b[LO]=CARRY|PSZtable[cpu->AF.b[HI]]; - SETHIDDEN(cpu->AF.b[HI]); - break; - - case 0x79: /* OUT (C),A */ - TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->AF.b[HI]); - break; - - case 0x7a: /* ADC HL,SP */ - TSTATE(15); - ADC16(cpu->HL.w,cpu->SP); - break; - - case 0x7b: /* LD SP,(nnnn) */ - TSTATE(20); - cpu->SP=PEEKW(FETCH_WORD); - break; - - case 0x7c: /* NEG */ - { - Z80Byte b; - - TSTATE(8); - - b=cpu->AF.b[HI]; - cpu->AF.b[HI]=0; - SUB8(b); - break; - } - - case 0x7d: /* RETN */ - TSTATE(14); - cpu->IFF1=cpu->IFF2; - POP(cpu->PC); - break; - - case 0x7e: /* IM 2 */ - TSTATE(8); - cpu->IM=2; - break; - - case 0x7f: /* NOP */ - TSTATE(8); - CALLBACK(eZ80_EDHook,opcode); - break; - - case 0xa0: /* LDI */ - TSTATE(16); - LDI; - break; - - case 0xa1: /* CPI */ - TSTATE(16); - CPI; - break; - - case 0xa2: /* INI */ - TSTATE(16); - INI; - break; - - case 0xa3: /* OUTI */ - TSTATE(16); - OUTI; - break; - - case 0xa8: /* LDD */ - TSTATE(16); - LDD; - break; - - case 0xa9: /* CPD */ - TSTATE(16); - CPD; - break; - - case 0xaa: /* IND */ - TSTATE(16); - IND; - break; - - case 0xab: /* OUTD */ - TSTATE(16); - OUTD; - break; - - case 0xb0: /* LDIR */ - TSTATE(16); - LDI; - if (cpu->BC.w) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xb1: /* CPIR */ - TSTATE(16); - CPI; - if (cpu->BC.w && !IS_Z) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xb2: /* INIR */ - TSTATE(16); - INI; - if (cpu->BC.w) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xb3: /* OTIR */ - TSTATE(16); - OUTI; - if (cpu->BC.w) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xb8: /* LDDR */ - TSTATE(16); - LDD; - if (cpu->BC.w) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xb9: /* CPDR */ - TSTATE(16); - CPD; - if (cpu->BC.w && !IS_Z) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xba: /* INDR */ - TSTATE(16); - IND; - if (cpu->BC.w) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - case 0xbb: /* OTDR */ - TSTATE(16); - OUTD; - if (cpu->BC.w) - { - TSTATE(5); - cpu->PC-=2; - } - break; - - /* All the rest are NOP/invalid - */ - default: - TSTATE(8); - CALLBACK(eZ80_EDHook,opcode); - break; - } -} - - -/* ---------------------------------------- HANDLERS FOR CB OPCODES -*/ -static void DecodeCB(Z80 *cpu, Z80Byte opcode) -{ - switch(opcode) - { - CB_ALU_BLOCK(0x00,RLC) - CB_ALU_BLOCK(0x08,RRC) - CB_ALU_BLOCK(0x10,RL) - CB_ALU_BLOCK(0x18,RR) - CB_ALU_BLOCK(0x20,SLA) - CB_ALU_BLOCK(0x28,SRA) - CB_ALU_BLOCK(0x30,SLL) - CB_ALU_BLOCK(0x38,SRL) - - CB_BITMANIP_BLOCK(0x40,BIT,0) - CB_BITMANIP_BLOCK(0x48,BIT,1) - CB_BITMANIP_BLOCK(0x50,BIT,2) - CB_BITMANIP_BLOCK(0x58,BIT,3) - CB_BITMANIP_BLOCK(0x60,BIT,4) - CB_BITMANIP_BLOCK(0x68,BIT,5) - CB_BITMANIP_BLOCK(0x70,BIT,6) - CB_BITMANIP_BLOCK(0x78,BIT,7) - - CB_BITMANIP_BLOCK(0x80,BIT_RES,0) - CB_BITMANIP_BLOCK(0x88,BIT_RES,1) - CB_BITMANIP_BLOCK(0x90,BIT_RES,2) - CB_BITMANIP_BLOCK(0x98,BIT_RES,3) - CB_BITMANIP_BLOCK(0xa0,BIT_RES,4) - CB_BITMANIP_BLOCK(0xa8,BIT_RES,5) - CB_BITMANIP_BLOCK(0xb0,BIT_RES,6) - CB_BITMANIP_BLOCK(0xb8,BIT_RES,7) - - CB_BITMANIP_BLOCK(0xc0,BIT_SET,0) - CB_BITMANIP_BLOCK(0xc8,BIT_SET,1) - CB_BITMANIP_BLOCK(0xd0,BIT_SET,2) - CB_BITMANIP_BLOCK(0xd8,BIT_SET,3) - CB_BITMANIP_BLOCK(0xe0,BIT_SET,4) - CB_BITMANIP_BLOCK(0xe8,BIT_SET,5) - CB_BITMANIP_BLOCK(0xf0,BIT_SET,6) - CB_BITMANIP_BLOCK(0xf8,BIT_SET,7) - } -} - - -static void ShiftedDecodeCB(Z80 *cpu, Z80Byte opcode, Z80Relative offset) -{ - Z80Word addr; - - /* See if we've come here from a IX/IY shift. - */ - switch (cpu->shift) - { - case 0xdd: - addr=cpu->IX.w+offset; - break; - case 0xfd: - addr=cpu->IY.w+offset; - break; - default: - addr=cpu->HL.w; /* Play safe... */ - break; - } - - switch(opcode) - { - SHIFTED_CB_ALU_BLOCK(0x00,RLC) - SHIFTED_CB_ALU_BLOCK(0x08,RRC) - SHIFTED_CB_ALU_BLOCK(0x10,RL) - SHIFTED_CB_ALU_BLOCK(0x18,RR) - SHIFTED_CB_ALU_BLOCK(0x20,SLA) - SHIFTED_CB_ALU_BLOCK(0x28,SRA) - SHIFTED_CB_ALU_BLOCK(0x30,SLL) - SHIFTED_CB_ALU_BLOCK(0x38,SRL) - - SHIFTED_CB_BITMANIP_BLOCK(0x40,BIT,0) - SHIFTED_CB_BITMANIP_BLOCK(0x48,BIT,1) - SHIFTED_CB_BITMANIP_BLOCK(0x50,BIT,2) - SHIFTED_CB_BITMANIP_BLOCK(0x58,BIT,3) - SHIFTED_CB_BITMANIP_BLOCK(0x60,BIT,4) - SHIFTED_CB_BITMANIP_BLOCK(0x68,BIT,5) - SHIFTED_CB_BITMANIP_BLOCK(0x70,BIT,6) - SHIFTED_CB_BITMANIP_BLOCK(0x78,BIT,7) - - SHIFTED_CB_BITMANIP_BLOCK(0x80,BIT_RES,0) - SHIFTED_CB_BITMANIP_BLOCK(0x88,BIT_RES,1) - SHIFTED_CB_BITMANIP_BLOCK(0x90,BIT_RES,2) - SHIFTED_CB_BITMANIP_BLOCK(0x98,BIT_RES,3) - SHIFTED_CB_BITMANIP_BLOCK(0xa0,BIT_RES,4) - SHIFTED_CB_BITMANIP_BLOCK(0xa8,BIT_RES,5) - SHIFTED_CB_BITMANIP_BLOCK(0xb0,BIT_RES,6) - SHIFTED_CB_BITMANIP_BLOCK(0xb8,BIT_RES,7) - - SHIFTED_CB_BITMANIP_BLOCK(0xc0,BIT_SET,0) - SHIFTED_CB_BITMANIP_BLOCK(0xc8,BIT_SET,1) - SHIFTED_CB_BITMANIP_BLOCK(0xd0,BIT_SET,2) - SHIFTED_CB_BITMANIP_BLOCK(0xd8,BIT_SET,3) - SHIFTED_CB_BITMANIP_BLOCK(0xe0,BIT_SET,4) - SHIFTED_CB_BITMANIP_BLOCK(0xe8,BIT_SET,5) - SHIFTED_CB_BITMANIP_BLOCK(0xf0,BIT_SET,6) - SHIFTED_CB_BITMANIP_BLOCK(0xf8,BIT_SET,7) - } -} - - -/* ---------------------------------------- NORMAL OPCODE DECODER -*/ -void Z80_Decode(Z80 *cpu, Z80Byte opcode) -{ - Z80Word *HL; - Z80Byte *H; - Z80Byte *L; - Z80Relative off; - - /* See if we've come here from a IX/IY shift - */ - switch (cpu->shift) - { - case 0xdd: - HL=&(cpu->IX.w); - L=cpu->IX.b+LO; - H=cpu->IX.b+HI; - break; - case 0xfd: - HL=&(cpu->IY.w); - L=cpu->IY.b+LO; - H=cpu->IY.b+HI; - break; - default: - HL=&(cpu->HL.w); - L=cpu->HL.b+LO; - H=cpu->HL.b+HI; - break; - } - - switch(opcode) - { - case 0x00: /* NOP */ - TSTATE(4); - break; - - case 0x01: /* LD BC,nnnn */ - TSTATE(10); - cpu->BC.w=FETCH_WORD; - break; - - case 0x02: /* LD (BC),A */ - TSTATE(7); - POKE(cpu->BC.w,cpu->AF.b[HI]); - break; - - case 0x03: /* INC BC */ - TSTATE(6); - cpu->BC.w++; - break; - - case 0x04: /* INC B */ - TSTATE(4); - INC8(cpu->BC.b[HI]); - break; - - case 0x05: /* DEC B */ - TSTATE(4); - DEC8(cpu->BC.b[HI]); - break; - - case 0x06: /* LD B,n */ - TSTATE(7); - cpu->BC.b[HI]=FETCH_BYTE; - break; - - case 0x07: /* RLCA */ - TSTATE(4); - RLCA; - break; - - case 0x08: /* EX AF,AF' */ - TSTATE(4); - SWAP(cpu->AF.w,cpu->AF_); - break; - - case 0x09: /* ADD HL,BC */ - TSTATE(11); - ADD16(*HL,cpu->BC.w); - break; - - case 0x0a: /* LD A,(BC) */ - TSTATE(7); - cpu->AF.b[HI]=PEEK(cpu->BC.w); - break; - - case 0x0b: /* DEC BC */ - TSTATE(6); - cpu->BC.w--; - break; - - case 0x0c: /* INC C */ - TSTATE(4); - INC8(cpu->BC.b[LO]); - break; - - case 0x0d: /* DEC C */ - TSTATE(4); - DEC8(cpu->BC.b[LO]); - break; - - case 0x0e: /* LD C,n */ - TSTATE(7); - cpu->BC.b[LO]=FETCH_BYTE; - break; - - case 0x0f: /* RRCA */ - TSTATE(4); - RRCA; - break; - - case 0x10: /* DJNZ */ - if (--(cpu->BC.b[HI])) - { - TSTATE(13); - JR; - } - else - { - TSTATE(8); - NOJR; - } - break; - - case 0x11: /* LD DE,nnnn */ - TSTATE(10); - cpu->DE.w=FETCH_WORD; - break; - - case 0x12: /* LD (DE),A */ - TSTATE(7); - POKE(cpu->DE.w,cpu->AF.b[HI]); - break; - - case 0x13: /* INC DE */ - TSTATE(6); - cpu->DE.w++; - break; - - case 0x14: /* INC D */ - TSTATE(4); - INC8(cpu->DE.b[HI]); - break; - - case 0x15: /* DEC D */ - TSTATE(4); - DEC8(cpu->DE.b[HI]); - break; - - case 0x16: /* LD D,n */ - TSTATE(7); - cpu->DE.b[HI]=FETCH_BYTE; - break; - - case 0x17: /* RLA */ - TSTATE(4); - RLA; - break; - - case 0x18: /* JR d */ - TSTATE(12); - JR; - break; - - case 0x19: /* ADD HL,DE */ - TSTATE(11); - ADD16(*HL,cpu->DE.w); - break; - - case 0x1a: /* LD A,(DE) */ - TSTATE(7); - cpu->AF.b[HI]=PEEK(cpu->DE.w); - break; - - case 0x1b: /* DEC DE */ - TSTATE(6); - cpu->DE.w--; - break; - - case 0x1c: /* INC E */ - TSTATE(4); - INC8(cpu->DE.b[LO]); - break; - - case 0x1d: /* DEC E */ - TSTATE(4); - DEC8(cpu->DE.b[LO]); - break; - - case 0x1e: /* LD E,n */ - TSTATE(7); - cpu->DE.b[LO]=FETCH_BYTE; - break; - - case 0x1f: /* RRA */ - TSTATE(4); - RRA; - break; - - case 0x20: /* JR NZ,e */ - JR_COND(!IS_Z); - break; - - case 0x21: /* LD HL,nnnn */ - TSTATE(10); - *HL=FETCH_WORD; - break; - - case 0x22: /* LD (nnnn),HL */ - TSTATE(16); - POKEW(FETCH_WORD,*HL); - break; - - case 0x23: /* INC HL */ - TSTATE(6); - (*HL)++; - break; - - case 0x24: /* INC H */ - TSTATE(4); - INC8(*H); - break; - - case 0x25: /* DEC H */ - TSTATE(4); - DEC8(*H); - break; - - case 0x26: /* LD H,n */ - TSTATE(7); - *H=FETCH_BYTE; - break; - - case 0x27: /* DAA */ - TSTATE(4); - DAA(cpu); - break; - - case 0x28: /* JR Z,d */ - JR_COND(IS_Z); - break; - - case 0x29: /* ADD HL,HL */ - TSTATE(11); - ADD16(*HL,*HL); - break; - - case 0x2a: /* LD HL,(nnnn) */ - TSTATE(7); - *HL=PEEKW(FETCH_WORD); - break; - - case 0x2b: /* DEC HL */ - TSTATE(6); - (*HL)--; - break; - - case 0x2c: /* INC L */ - TSTATE(4); - INC8(*L); - break; - - case 0x2d: /* DEC L */ - TSTATE(4); - DEC8(*L); - break; - - case 0x2e: /* LD L,n */ - TSTATE(7); - *L=FETCH_BYTE; - break; - - case 0x2f: /* CPL */ - TSTATE(4); - cpu->AF.b[HI]^=0xff; - SETFLAG(H_Z80); - SETFLAG(N_Z80); - SETHIDDEN(cpu->AF.b[HI]); - break; - - case 0x30: /* JR NC,d */ - JR_COND(!IS_C); - break; - - case 0x31: /* LD SP,nnnn */ - TSTATE(10); - cpu->SP=FETCH_WORD; - break; - - case 0x32: /* LD (nnnn),A */ - TSTATE(13); - POKE(FETCH_WORD,cpu->AF.b[HI]); - break; - - case 0x33: /* INC SP */ - TSTATE(6); - cpu->SP++; - break; - - case 0x34: /* INC (HL) */ - TSTATE(11); - OFFSET(off); - OP_ON_MEM(INC8,*HL+off); - break; - - case 0x35: /* DEC (HL) */ - TSTATE(11); - OFFSET(off); - OP_ON_MEM(DEC8,*HL+off); - break; - - case 0x36: /* LD (HL),n */ - TSTATE(10); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,FETCH_BYTE); - break; - - case 0x37: /* SCF */ - TSTATE(4); - cpu->AF.b[LO]=(cpu->AF.b[LO]&(S_Z80|Z_Z80|P_Z80)) - | C_Z80 - | (cpu->AF.b[HI]&(B3_Z80|B5_Z80)); - break; - - case 0x38: /* JR C,d */ - JR_COND(IS_C); - break; - - case 0x39: /* ADD HL,SP */ - TSTATE(11); - ADD16(*HL,cpu->SP); - break; - - case 0x3a: /* LD A,(nnnn) */ - TSTATE(13); - cpu->AF.b[HI]=cpu->mread(cpu,FETCH_WORD); - break; - - case 0x3b: /* DEC SP */ - TSTATE(6); - cpu->SP--; - break; - - case 0x3c: /* INC A */ - TSTATE(4); - INC8(cpu->AF.b[HI]); - break; - - case 0x3d: /* DEC A */ - TSTATE(4); - DEC8(cpu->AF.b[HI]); - break; - - case 0x3e: /* LD A,n */ - TSTATE(7); - cpu->AF.b[HI]=FETCH_BYTE; - break; - - case 0x3f: /* CCF */ - TSTATE(4); - - if (CARRY) - SETFLAG(H_Z80); - else - CLRFLAG(H_Z80); - - cpu->AF.b[LO]^=C_Z80; - SETHIDDEN(cpu->AF.b[HI]); - break; - - LD_BLOCK(0x40,cpu->BC.b[HI],cpu->BC.b[HI]) - LD_BLOCK(0x48,cpu->BC.b[LO],cpu->BC.b[LO]) - LD_BLOCK(0x50,cpu->DE.b[HI],cpu->DE.b[HI]) - LD_BLOCK(0x58,cpu->DE.b[LO],cpu->DE.b[LO]) - LD_BLOCK(0x60,*H,cpu->HL.b[HI]) - LD_BLOCK(0x68,*L,cpu->HL.b[LO]) - - case 0x70: /* LD (HL),B */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->BC.b[HI]); - break; - - case 0x71: /* LD (HL),C */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->BC.b[LO]); - break; - - case 0x72: /* LD (HL),D */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->DE.b[HI]); - break; - - case 0x73: /* LD (HL),E */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->DE.b[LO]); - break; - - case 0x74: /* LD (HL),H */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->HL.b[HI]); - break; - - case 0x75: /* LD (HL),L */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->HL.b[LO]); - break; - - case 0x76: /* HALT */ - TSTATE(4); - cpu->PC--; - - if (!cpu->halt) - CALLBACK(eZ80_Halt,1); - - cpu->halt=TRUE; - break; - - case 0x77: /* LD (HL),A */ - TSTATE(7); - OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->AF.b[HI]); - break; - - LD_BLOCK(0x78,cpu->AF.b[HI],cpu->AF.b[HI]) - - ALU_BLOCK(0x80,ADD8) - ALU_BLOCK(0x88,ADC8) - ALU_BLOCK(0x90,SUB8) - ALU_BLOCK(0x98,SBC8) - ALU_BLOCK(0xa0,AND) - ALU_BLOCK(0xa8,XOR) - ALU_BLOCK(0xb0,OR) - ALU_BLOCK(0xb8,CMP8) - - case 0xc0: /* RET NZ */ - RET_COND(!IS_Z); - break; - - case 0xc1: /* POP BC */ - TSTATE(10); - POP(cpu->BC.w); - break; - - case 0xc2: /* JP NZ,nnnn */ - JP_COND(!IS_Z); - break; - - case 0xc3: /* JP nnnn */ - JP_COND(1); - break; - - case 0xc4: /* CALL NZ,nnnn */ - CALL_COND(!IS_Z); - break; - - case 0xc5: /* PUSH BC */ - TSTATE(10); - PUSH(cpu->BC.w); - break; - - case 0xc6: /* ADD A,n */ - TSTATE(7); - ADD8(FETCH_BYTE); - break; - - case 0xc7: /* RST 0 */ - RST(0); - break; - - case 0xc8: /* RET Z */ - RET_COND(IS_Z); - break; - - case 0xc9: /* RET */ - TSTATE(10); - POP(cpu->PC); - break; - - case 0xca: /* JP Z,nnnn */ - JP_COND(IS_Z); - break; - - case 0xcb: /* CB PREFIX */ - INC_R; - - /* Check for previous IX/IY shift. - */ - if (cpu->shift!=0) - { - Z80Relative cb_offset; - - TSTATE(4); /* Wild stab in the dark! */ - cb_offset=FETCH_BYTE; - ShiftedDecodeCB(cpu,FETCH_BYTE,cb_offset); - } - else - { - DecodeCB(cpu,FETCH_BYTE); - } - break; - - case 0xcc: /* CALL Z,nnnn */ - CALL_COND(IS_Z); - break; - - case 0xcd: /* CALL nnnn */ - CALL_COND(1); - break; - - case 0xce: /* ADC A,n */ - ADC8(FETCH_BYTE); - break; - - case 0xcf: /* RST 8 */ - RST(8); - break; - - case 0xd0: /* RET NC */ - RET_COND(!IS_C); - break; - - case 0xd1: /* POP DE */ - TSTATE(10); - POP(cpu->DE.w); - break; - - case 0xd2: /* JP NC,nnnn */ - JP_COND(!IS_C); - break; - - case 0xd3: /* OUT (n),A */ - TSTATE(11); - if (cpu->pwrite) - cpu->pwrite(cpu,FETCH_BYTE,cpu->AF.b[HI]); - else - cpu->PC++; - break; - - case 0xd4: /* CALL NC,nnnn */ - CALL_COND(!IS_C); - break; - - case 0xd5: /* PUSH DE */ - TSTATE(11); - PUSH(cpu->DE.w); - break; - - case 0xd6: /* SUB A,n */ - TSTATE(7); - SUB8(FETCH_BYTE); - break; - - case 0xd7: /* RST 10 */ - RST(0x10); - break; - - case 0xd8: /* RET C */ - RET_COND(IS_C); - break; - - case 0xd9: /* EXX */ - TSTATE(4); - SWAP(cpu->BC.w,cpu->BC_); - SWAP(cpu->DE.w,cpu->DE_); - SWAP(cpu->HL.w,cpu->HL_); - break; - - case 0xda: /* JP C,nnnn */ - JP_COND(IS_C); - break; - - case 0xdb: /* IN A,(n) */ - TSTATE(11); - if (cpu->pread) - { - Z80Word port; - - port=FETCH_BYTE; - port|=(Z80Word)cpu->AF.b[HI]<<8; - cpu->AF.b[HI]=cpu->pread(cpu,port); - } - else - cpu->PC++; - break; - - case 0xdc: /* CALL C,nnnn */ - CALL_COND(IS_C); - break; - - case 0xdd: /* DD PREFIX */ - TSTATE(4); - INC_R; - - cpu->shift=opcode; - Z80_Decode(cpu,FETCH_BYTE); - break; - - case 0xde: /* SBC A,n */ - TSTATE(7); - SBC8(FETCH_BYTE); - break; - - case 0xdf: /* RST 18 */ - RST(0x18); - break; - - case 0xe0: /* RET PO */ - RET_COND(!IS_P); - break; - - case 0xe1: /* POP HL */ - TSTATE(10); - POP(*HL); - break; - - case 0xe2: /* JP PO,nnnn */ - JP_COND(!IS_P); - break; - - case 0xe3: /* EX (SP),HL */ - { - Z80Word tmp; - TSTATE(19); - POP(tmp); - PUSH(*HL); - *HL=tmp; - } - break; - - case 0xe4: /* CALL PO,nnnn */ - CALL_COND(!IS_P); - break; - - case 0xe5: /* PUSH HL */ - TSTATE(10); - PUSH(*HL); - break; - - case 0xe6: /* AND A,n */ - TSTATE(7); - AND(FETCH_BYTE); - break; - - case 0xe7: /* RST 20 */ - RST(0x20); - break; - - case 0xe8: /* RET PE */ - RET_COND(IS_P); - break; - - case 0xe9: /* JP (HL) */ - TSTATE(4); - cpu->PC=*HL; - break; - - case 0xea: /* JP PE,nnnn */ - JP_COND(IS_P); - break; - - case 0xeb: /* EX DE,HL */ - TSTATE(4); - SWAP(cpu->DE.w,*HL); - break; - - case 0xec: /* CALL PE,nnnn */ - CALL_COND(IS_P); - break; - - case 0xed: /* ED PREFIX */ - INC_R; - DecodeED(cpu,FETCH_BYTE); - break; - - case 0xee: /* XOR A,n */ - TSTATE(7); - XOR(FETCH_BYTE); - break; - - case 0xef: /* RST 28 */ - RST(0x28); - break; - - case 0xf0: /* RET P */ - RET_COND(!IS_S); - break; - - case 0xf1: /* POP AF */ - TSTATE(10); - POP(cpu->AF.w); - break; - - case 0xf2: /* JP P,nnnn */ - JP_COND(!IS_S); - break; - - case 0xf3: /* DI */ - TSTATE(4); - cpu->IFF1=0; - cpu->IFF2=0; - break; - - case 0xf4: /* CALL P,nnnn */ - CALL_COND(!IS_S); - break; - - case 0xf5: /* PUSH AF */ - TSTATE(10); - PUSH(cpu->AF.w); - break; - - case 0xf6: /* OR A,n */ - TSTATE(7); - OR(FETCH_BYTE); - break; - - case 0xf7: /* RST 30 */ - RST(0x30); - break; - - case 0xf8: /* RET M */ - RET_COND(IS_S); - break; - - case 0xf9: /* LD SP,HL */ - TSTATE(6); - cpu->SP=*HL; - break; - - case 0xfa: /* JP M,nnnn */ - JP_COND(IS_S); - break; - - case 0xfb: /* EI */ - TSTATE(4); - cpu->IFF1=1; - cpu->IFF2=1; - break; - - case 0xfc: /* CALL M,nnnn */ - CALL_COND(IS_S); - break; - - case 0xfd: /* FD PREFIX */ - TSTATE(4); - INC_R; - - cpu->shift=opcode; - Z80_Decode(cpu,FETCH_BYTE); - break; - - case 0xfe: /* CP A,n */ - TSTATE(7); - CMP8(FETCH_BYTE); - break; - - case 0xff: /* RST 38 */ - RST(0x38); - break; - - } -} - - -/* END OF FILE */ diff --git a/include/z80_private.h b/include/z80_private.h index 4a19324..dc4f6b9 100644 --- a/include/z80_private.h +++ b/include/z80_private.h @@ -2,7 +2,7 @@ z80 - Z80 emulation - Copyright (C) 2006 Ian Cowburn (ianc@noddybox.demon.co.uk) + Copyright (C) 2006 Ian Cowburn (ianc@noddybox.co.uk) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +29,8 @@ #ifndef Z80_PRIVATE_H #define Z80_PRIVATE_H "$Id$" +#include "z80_config.h" + #ifndef TRUE #define TRUE 1 #endif @@ -43,40 +45,10 @@ /* ---------------------------------------- TYPES */ -typedef signed short sword; - -typedef union -{ - Z80Word w; - Z80Byte b[2]; -} Z80Reg; - -struct Z80 +struct Z80Private { Z80Val cycle; - Z80Word PC; - - Z80Reg AF; - Z80Reg BC; - Z80Reg DE; - Z80Reg HL; - - Z80Word AF_; - Z80Word BC_; - Z80Word DE_; - Z80Word HL_; - - Z80Reg IX; - Z80Reg IY; - - Z80Word SP; - - Z80Byte IFF1; - Z80Byte IFF2; - Z80Byte IM; - Z80Byte I; - Z80Byte R; int halt; Z80Byte shift; @@ -85,10 +57,12 @@ struct Z80 Z80Byte devbyte; int nmi; +#ifndef ENABLE_ARRAY_MEMORY Z80ReadMemory disread; Z80ReadMemory mread; Z80WriteMemory mwrite; +#endif Z80ReadPort pread; Z80WritePort pwrite; @@ -98,6 +72,16 @@ struct Z80 int last_cb; }; +#define PRIV cpu->priv + + +/* ---------------------------------------- ARRAY MEMORY +*/ + +#ifdef ENABLE_ARRAY_MEMORY +extern Z80Byte Z80_MEMORY[]; +#endif + /* ---------------------------------------- MACROS */ @@ -114,9 +98,9 @@ struct Z80 int f; \ \ for(f=0;fcallback[r][f]) \ - cpu->last_cb &= \ - cpu->callback[r][f](cpu,d); \ + if (PRIV->callback[r][f]) \ + PRIV->last_cb &= \ + PRIV->callback[r][f](cpu,d);\ } while(0) /* Flag register @@ -139,15 +123,50 @@ struct Z80 #define SETFLAG(f) SET(cpu->AF.b[LO],f) #define CLRFLAG(f) CLR(cpu->AF.b[LO],f) -#define PEEK(addr) (cpu->mread(cpu,addr)) +#ifdef ENABLE_ARRAY_MEMORY + +#define PEEK(addr) Z80_MEMORY[addr] + +static inline Z80Word PEEKW(Z80Word addr) +{ + return (PEEK(addr) | (Z80Word)PEEK(addr+1)<<8); +} + +#define POKE(addr,val) do \ + { \ + Z80Word ba=addr; \ + if (ba>=RAMBOT && ba<=RAMTOP) \ + Z80_MEMORY[ba]=val; \ + } while(0) + +#define POKEW(addr,val) do \ + { \ + Z80Word wa=addr; \ + Z80Word wv=val; \ + POKE(wa,wv); \ + POKE(wa+1,wv>>8); \ + } while(0) + + +#define FETCH_BYTE (Z80_MEMORY[cpu->PC++]) +#define FETCH_WORD (cpu->PC+=2, \ + Z80_MEMORY[cpu->PC-2]| \ + ((Z80Word)Z80_MEMORY[cpu->PC-1]<<8)) + +#else + +#define PEEK(addr) (PRIV->mread(cpu,addr)) #define PEEKW(addr) FPEEKW(cpu,addr) -#define POKE(addr,val) cpu->mwrite(cpu,addr,val) +#define POKE(addr,val) PRIV->mwrite(cpu,addr,val) #define POKEW(addr,val) FPOKEW(cpu,addr,val) -#define FETCH_BYTE (cpu->mread(cpu,cpu->PC++)) +#define FETCH_BYTE (PRIV->mread(cpu,cpu->PC++)) #define FETCH_WORD (cpu->PC+=2,FPEEKW(cpu,cpu->PC-2)) +#endif + + #define IS_C (cpu->AF.b[LO]&C_Z80) #define IS_N (cpu->AF.b[LO]&N_Z80) #define IS_P (cpu->AF.b[LO]&P_Z80) @@ -157,21 +176,34 @@ struct Z80 #define CARRY IS_C -#define IS_IX_IY (cpu->shift==0xdd || cpu->shift==0xfd) +#define IS_IX_IY (PRIV->shift==0xdd || PRIV->shift==0xfd) #define OFFSET(off) off=(IS_IX_IY ? (Z80Relative)FETCH_BYTE:0) -#define TSTATE(n) cpu->cycle+=n +#define TSTATE(n) PRIV->cycle+=n #define ADD_R(v) cpu->R=((cpu->R&0x80)|((cpu->R+(v))&0x7f)) #define INC_R ADD_R(1) +#ifdef ENABLE_ARRAY_MEMORY + +#define PUSH(REG) do \ + { \ + Z80Word pv=REG; \ + cpu->SP-=2; \ + POKE(cpu->SP,pv); \ + POKE(cpu->SP+1,pv>>8); \ + } while(0) + +#else + #define PUSH(REG) do \ { \ Z80Word pushv=REG; \ cpu->SP-=2; \ - cpu->mwrite(cpu,cpu->SP,pushv); \ - cpu->mwrite(cpu,cpu->SP+1,pushv>>8);\ + PRIV->mwrite(cpu,cpu->SP,pushv); \ + PRIV->mwrite(cpu,cpu->SP+1,pushv>>8);\ } while(0) +#endif #define POP(REG) do \ { \ @@ -197,11 +229,11 @@ struct Z80 #define OUT(P,V) do \ { \ - if (cpu->pwrite) \ - cpu->pwrite(cpu,P,V); \ + if (PRIV->pwrite) \ + PRIV->pwrite(cpu,P,V); \ } while(0) -#define IN(P) (cpu->pread?cpu->pread(cpu,P):0) +#define IN(P) (PRIV->pread?PRIV->pread(cpu,P):0) diff --git a/source/keyboard.c b/source/keyboard.c index 2c4d63f..2dab4f7 100644 --- a/source/keyboard.c +++ b/source/keyboard.c @@ -97,7 +97,7 @@ void SK_DisplayKeyboard(uint16 *vram) loadPCX(keyb_bin,&img); image8to16(&img); - dmaCopy(img.data8,vram,SCREEN_WIDTH*SCREEN_HEIGHT*2); + dmaCopy(img.image.data8,vram,SCREEN_WIDTH*SCREEN_HEIGHT*2); } diff --git a/source/main.c b/source/main.c index e8b4c6b..d4ac2ee 100644 --- a/source/main.c +++ b/source/main.c @@ -221,7 +221,7 @@ int main(int argc, char *argv[]) /* Initialise processor and the Spectrum */ - z80=Z80Init(SPECPeek,SPECPoke,SPECReadPort,SPECWritePort,SPECDisPeek); + z80=Z80Init(SPECReadPort,SPECWritePort); if (!z80) { diff --git a/source/spec.c b/source/spec.c index 10a5d0a..0e569b5 100644 --- a/source/spec.c +++ b/source/spec.c @@ -62,9 +62,9 @@ static const int ROM_LOAD=0x562; #define SCRDATA 0x4000 #define ATTR 0x5800 -#define ATTR_AT(x,y) mem[ATTR+(x)+((y)/8)*32] +#define ATTR_AT(x,y) Z80_MEMORY[ATTR+(x)+((y)/8)*32] -static Z80Byte mem[0x10000]; +Z80Byte Z80_MEMORY[0x10000]; /* Number of cycles per frame */ @@ -169,7 +169,7 @@ static void DrawScreen(void) vr=vram; - swiWaitForVBlank(); + /* swiWaitForVBlank(); */ for(y=0;y=ROMLEN) - mem[addr]=val; + Z80_MEMORY[addr]=val; } void SnapPoke(Z80Word addr, Z80Byte val) { if (addr>=ROMLEN) - mem[addr]=val; + Z80_MEMORY[addr]=val; } @@ -365,7 +365,7 @@ void SPECInit(uint16 *v, Z80 *z80) { vram=v; - memcpy(mem,spec48_bin,ROMLEN); + memcpy(Z80_MEMORY,spec48_bin,ROMLEN); /* Patch the ROM */ @@ -491,7 +491,7 @@ void SPECReset(Z80 *z80) r=0; for(f=0;fraise) + if (PRIV->raise) { - if (cpu->nmi) + if (PRIV->nmi) { - if (cpu->halt) + if (PRIV->halt) { - cpu->halt=FALSE; + PRIV->halt=FALSE; CALLBACK(eZ80_Halt,0); cpu->PC++; } TSTATE(2); cpu->IFF1=0; - cpu->nmi=FALSE; + PRIV->nmi=FALSE; PUSH(cpu->PC); cpu->PC=0x66; } else if (cpu->IFF1) { - if (cpu->halt) + if (PRIV->halt) { - cpu->halt=FALSE; + PRIV->halt=FALSE; CALLBACK(eZ80_Halt,0); cpu->PC++; } TSTATE(2); + cpu->IFF1=0; + cpu->IFF2=0; + switch(cpu->IM) { default: case 0: INC_R; - Z80_Decode(cpu,cpu->devbyte); + Z80_Decode(cpu,PRIV->devbyte); return; break; @@ -99,12 +102,12 @@ static void Z80_CheckInterrupt(Z80 *cpu) case 2: PUSH(cpu->PC); - cpu->PC=(Z80Word)cpu->I*256+cpu->devbyte; + cpu->PC=(Z80Word)cpu->I*256+PRIV->devbyte; break; } } - cpu->raise=FALSE; + PRIV->raise=FALSE; } } @@ -112,11 +115,16 @@ static void Z80_CheckInterrupt(Z80 *cpu) /* ---------------------------------------- INTERFACES */ -Z80 *Z80Init(Z80ReadMemory read_memory, - Z80WriteMemory write_memory, - Z80ReadPort read_port, - Z80WritePort write_port, - Z80ReadMemory read_disassem) +#ifdef ENABLE_ARRAY_MEMORY +Z80 *Z80Init(Z80ReadPort read_port, + Z80WritePort write_port) +#else +Z80 *Z80Init(Z80ReadMemory read_memory, + Z80WriteMemory write_memory, + Z80ReadPort read_port, + Z80WritePort write_port, + Z80ReadMemory read_for_disassem) +#endif { Z80 *cpu; int f; @@ -124,24 +132,38 @@ Z80 *Z80Init(Z80ReadMemory read_memory, InitTables(); +#ifndef ENABLE_ARRAY_MEMORY if (!read_memory || !write_memory) return NULL; +#endif cpu=malloc(sizeof *cpu); if (cpu) { - cpu->mread=read_memory; - cpu->mwrite=write_memory; - cpu->pread=read_port; - cpu->pwrite=write_port; - cpu->disread=read_disassem; + cpu->priv=malloc(sizeof *cpu->priv); + + if (cpu->priv) + { +#ifndef ENABLE_ARRAY_MEMORY + PRIV->mread=read_memory; + PRIV->mwrite=write_memory; + PRIV->disread=read_for_disassem; +#endif + PRIV->pread=read_port; + PRIV->pwrite=write_port; - for(f=0;fcallback[f][r]=NULL; + for(f=0;fcallback[f][r]=NULL; - Z80Reset(cpu); + Z80Reset(cpu); + } + else + { + free(cpu); + cpu=NULL; + } } return cpu; @@ -150,7 +172,7 @@ Z80 *Z80Init(Z80ReadMemory read_memory, void Z80Reset(Z80 *cpu) { - cpu->cycle=0; + PRIV->cycle=0; cpu->PC=0; cpu->AF.w=0xffff; @@ -171,28 +193,22 @@ void Z80Reset(Z80 *cpu) cpu->IM=0; cpu->I=0; cpu->R=0; - cpu->halt=0; - - cpu->raise=FALSE; - cpu->nmi=FALSE; -} - + PRIV->halt=0; -void Z80SetPC(Z80 *cpu,Z80Word PC) -{ - cpu->PC=PC; + PRIV->raise=FALSE; + PRIV->nmi=FALSE; } -Z80Word Z80GetPC(Z80 *cpu) +Z80Val Z80Cycles(Z80 *cpu) { - return cpu->PC; + return PRIV->cycle; } void Z80ResetCycles(Z80 *cpu, Z80Val cycles) { - cpu->cycle=cycles; + PRIV->cycle=cycles; } @@ -202,9 +218,9 @@ int Z80LodgeCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback) for(f=0;fcallback[reason][f]) + if (!PRIV->callback[reason][f]) { - cpu->callback[reason][f]=callback; + PRIV->callback[reason][f]=callback; return TRUE; } } @@ -218,23 +234,27 @@ void Z80RemoveCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback) int f; for(f=0;fcallback[reason][f]==callback) - cpu->callback[reason][f]=NULL; + { + if (PRIV->callback[reason][f]==callback) + { + PRIV->callback[reason][f]=NULL; + } + } } void Z80Interrupt(Z80 *cpu, Z80Byte devbyte) { - cpu->raise=TRUE; - cpu->devbyte=devbyte; - cpu->nmi=FALSE; + PRIV->raise=TRUE; + PRIV->devbyte=devbyte; + PRIV->nmi=FALSE; } void Z80NMI(Z80 *cpu) { - cpu->raise=TRUE; - cpu->nmi=TRUE; + PRIV->raise=TRUE; + PRIV->nmi=TRUE; } @@ -242,12 +262,12 @@ int Z80SingleStep(Z80 *cpu) { Z80Byte opcode; - cpu->last_cb=TRUE; - cpu->shift=0; + PRIV->last_cb=TRUE; + PRIV->shift=0; Z80_CheckInterrupt(cpu); - CALLBACK(eZ80_Instruction,cpu->cycle); + CALLBACK(eZ80_Instruction,PRIV->cycle); INC_R; @@ -255,7 +275,7 @@ int Z80SingleStep(Z80 *cpu) Z80_Decode(cpu,opcode); - return cpu->last_cb; + return PRIV->last_cb; } @@ -265,68 +285,6 @@ void Z80Exec(Z80 *cpu) } -void Z80GetState(Z80 *cpu, Z80State *state) -{ - state->cycle= cpu->cycle; - - state->AF = cpu->AF.w; - state->BC = cpu->BC.w; - state->DE = cpu->DE.w; - state->HL = cpu->HL.w; - - state->AF_ = cpu->AF_; - state->BC_ = cpu->BC_; - state->DE_ = cpu->DE_; - state->HL_ = cpu->HL_; - - state->IX = cpu->IX.w; - state->IY = cpu->IY.w; - - state->SP = cpu->SP; - state->PC = cpu->PC; - - state->IFF1 = cpu->IFF1; - state->IFF2 = cpu->IFF2; - state->IM = cpu->IM; - state->I = cpu->I; - state->R = cpu->R; -} - - -void Z80SetState(Z80 *cpu, const Z80State *state) -{ - cpu->cycle = state->cycle; - - cpu->AF.w = state->AF; - cpu->BC.w = state->BC; - cpu->DE.w = state->DE; - cpu->HL.w = state->HL; - - cpu->AF_ = state->AF_; - cpu->BC_ = state->BC_; - cpu->DE_ = state->DE_; - cpu->HL_ = state->HL_; - - cpu->IX.w = state->IX; - cpu->IY.w = state->IY; - - cpu->SP = state->SP; - cpu->PC = state->PC; - - cpu->IFF1 = state->IFF1; - cpu->IFF2 = state->IFF2; - cpu->IM = state->IM; - cpu->I = state->I; - cpu->R = state->R; -} - - -Z80Val Z80Cycles(Z80 *cpu) -{ - return cpu->cycle; -} - - void Z80SetLabels(Z80Label labels[]) { z80_labels=labels; @@ -336,6 +294,7 @@ void Z80SetLabels(Z80Label labels[]) const char *Z80Disassemble(Z80 *cpu, Z80Word *pc) { #ifdef ENABLE_DISASSEM + Z80Byte Z80_Dis_FetchByte(Z80 *cpu, Z80Word *pc); static char s[80]; Z80Word opc,npc; Z80Byte op; @@ -350,7 +309,13 @@ const char *Z80Disassemble(Z80 *cpu, Z80Word *pc) strcat(s,Z80_Dis_Printf("%-40s ;",Z80_Dis_GetArg())); for(f=0;f<5 && opc!=npc;f++) - strcat(s,Z80_Dis_Printf(" %.2x",(int)cpu->disread(cpu,opc++))); + { +#ifdef ENABLE_ARRAY_MEMORY + strcat(s,Z80_Dis_Printf(" %.2x",(int)Z80_MEMORY[opc++])); +#else + strcat(s,Z80_Dis_Printf(" %.2x",(int)PRIV->disread(cpu,opc++))); +#endif + } if (opc!=npc) for(f=1;f<3;f++) diff --git a/source/z80_decode.c b/source/z80_decode.c index ced7fbd..a8f66ca 100644 --- a/source/z80_decode.c +++ b/source/z80_decode.c @@ -40,8 +40,11 @@ static Z80Byte Stable[512]; static Z80Byte Ztable[512]; -static int HI; -static int LO; +int Z80_HI_WORD; +int Z80_LO_WORD; + +#define HI Z80_HI_WORD +#define LO Z80_LO_WORD /* ---------------------------------------- MISC FUNCTIONS */ @@ -118,6 +121,7 @@ void Z80_InitialiseInternals(void) } } +#ifndef ENABLE_ARRAY_MEMORY static Z80Word FPEEKW(Z80 *cpu, Z80Word addr) { return (PEEK(addr) | (Z80Word)PEEK(addr+1)<<8); @@ -126,9 +130,10 @@ static Z80Word FPEEKW(Z80 *cpu, Z80Word addr) static void FPOKEW(Z80 *cpu, Z80Word addr, Z80Word val) { - cpu->mwrite(cpu,addr,val); - cpu->mwrite(cpu,addr+1,val>>8); + PRIV->mwrite(cpu,addr,val); + PRIV->mwrite(cpu,addr+1,val>>8); } +#endif /* ---------------------------------------- GENERAL MACROS @@ -274,35 +279,35 @@ do { \ #define OP_ON_MEM(OP,addr) \ do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ + Z80Byte memop=PEEK(addr); \ OP(memop); \ - cpu->mwrite(cpu,addr,memop); \ + POKE(addr,memop); \ } while(0) #define OP_ON_MEM_WITH_ARG(OP,addr,arg) \ do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ + Z80Byte memop=PEEK(addr); \ OP(memop,arg); \ - cpu->mwrite(cpu,addr,memop); \ + POKE(addr,memop); \ } while(0) #define OP_ON_MEM_WITH_COPY(OP,addr,copy) \ do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ + Z80Byte memop=PEEK(addr); \ OP(memop); \ copy=memop; \ - cpu->mwrite(cpu,addr,memop); \ + POKE(addr,memop); \ } while(0) #define OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,arg,copy) \ do { \ - Z80Byte memop=cpu->mread(cpu,addr); \ + Z80Byte memop=PEEK(addr); \ OP(memop,arg); \ copy=memop; \ - cpu->mwrite(cpu,addr,memop); \ + POKE(addr,memop); \ } while(0) @@ -748,7 +753,7 @@ do { \ case BASE+6: /* LD DEST,(HL) */ \ TSTATE(7); \ OFFSET(off); \ - DEST2=cpu->mread(cpu,*HL+off); \ + DEST2=PEEK(*HL+off); \ break; \ \ case BASE+7: /* LD DEST,A */ \ @@ -1018,9 +1023,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x40: /* IN B,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->BC.b[HI]=cpu->pread(cpu,cpu->BC.w); + cpu->BC.b[HI]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1033,7 +1038,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x41: /* OUT (C),B */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->BC.b[HI]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->BC.b[HI]); break; case 0x42: /* SBC HL,BC */ @@ -1077,9 +1082,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x48: /* IN C,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->BC.b[LO]=cpu->pread(cpu,cpu->BC.w); + cpu->BC.b[LO]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1092,7 +1097,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x49: /* OUT (C),C */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->BC.b[LO]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->BC.b[LO]); break; case 0x4a: /* ADC HL,BC */ @@ -1137,9 +1142,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x50: /* IN D,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->DE.b[HI]=cpu->pread(cpu,cpu->BC.w); + cpu->DE.b[HI]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1152,7 +1157,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x51: /* OUT (C),D */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->DE.b[HI]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->DE.b[HI]); break; case 0x52: /* SBC HL,DE */ @@ -1196,9 +1201,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x58: /* IN E,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->DE.b[LO]=cpu->pread(cpu,cpu->BC.w); + cpu->DE.b[LO]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1211,7 +1216,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x59: /* OUT (C),E */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->DE.b[LO]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->DE.b[LO]); break; case 0x5a: /* ADC HL,DE */ @@ -1255,9 +1260,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x60: /* IN H,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->HL.b[HI]=cpu->pread(cpu,cpu->BC.w); + cpu->HL.b[HI]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1270,7 +1275,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x61: /* OUT (C),H */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->HL.b[HI]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->HL.b[HI]); break; case 0x62: /* SBC HL,HL */ @@ -1325,9 +1330,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x68: /* IN L,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->HL.b[LO]=cpu->pread(cpu,cpu->BC.w); + cpu->HL.b[LO]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1340,7 +1345,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x69: /* OUT (C),L */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->HL.b[LO]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->HL.b[LO]); break; case 0x6a: /* ADC HL,HL */ @@ -1398,9 +1403,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - b=cpu->pread(cpu,cpu->BC.w); + b=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1414,7 +1419,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x71: /* OUT (C) */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,0); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,0); break; case 0x72: /* SBC HL,SP */ @@ -1458,9 +1463,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x78: /* IN A,(C) */ TSTATE(12); - if (cpu->pread) + if (PRIV->pread) { - cpu->AF.b[HI]=cpu->pread(cpu,cpu->BC.w); + cpu->AF.b[HI]=PRIV->pread(cpu,cpu->BC.w); } else { @@ -1473,7 +1478,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode) case 0x79: /* OUT (C),A */ TSTATE(12); - if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->AF.b[HI]); + if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->AF.b[HI]); break; case 0x7a: /* ADC HL,SP */ @@ -1695,7 +1700,7 @@ static void ShiftedDecodeCB(Z80 *cpu, Z80Byte opcode, Z80Relative offset) /* See if we've come here from a IX/IY shift. */ - switch (cpu->shift) + switch (PRIV->shift) { case 0xdd: addr=cpu->IX.w+offset; @@ -1760,7 +1765,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) /* See if we've come here from a IX/IY shift */ - switch (cpu->shift) + switch (PRIV->shift) { case 0xdd: HL=&(cpu->IX.w); @@ -2063,7 +2068,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) case 0x36: /* LD (HL),n */ TSTATE(10); OFFSET(off); - cpu->mwrite(cpu,*HL+off,FETCH_BYTE); + POKE(*HL+off,FETCH_BYTE); break; case 0x37: /* SCF */ @@ -2084,7 +2089,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) case 0x3a: /* LD A,(nnnn) */ TSTATE(13); - cpu->AF.b[HI]=cpu->mread(cpu,FETCH_WORD); + cpu->AF.b[HI]=PEEK(FETCH_WORD); break; case 0x3b: /* DEC SP */ @@ -2129,53 +2134,53 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) case 0x70: /* LD (HL),B */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->BC.b[HI]); + POKE(*HL+off,cpu->BC.b[HI]); break; case 0x71: /* LD (HL),C */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->BC.b[LO]); + POKE(*HL+off,cpu->BC.b[LO]); break; case 0x72: /* LD (HL),D */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->DE.b[HI]); + POKE(*HL+off,cpu->DE.b[HI]); break; case 0x73: /* LD (HL),E */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->DE.b[LO]); + POKE(*HL+off,cpu->DE.b[LO]); break; case 0x74: /* LD (HL),H */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->HL.b[HI]); + POKE(*HL+off,cpu->HL.b[HI]); break; case 0x75: /* LD (HL),L */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->HL.b[LO]); + POKE(*HL+off,cpu->HL.b[LO]); break; case 0x76: /* HALT */ TSTATE(4); cpu->PC--; - if (!cpu->halt) + if (!PRIV->halt) CALLBACK(eZ80_Halt,1); - cpu->halt=TRUE; + PRIV->halt=TRUE; break; case 0x77: /* LD (HL),A */ TSTATE(7); OFFSET(off); - cpu->mwrite(cpu,*HL+off,cpu->AF.b[HI]); + POKE(*HL+off,cpu->AF.b[HI]); break; LD_BLOCK(0x78,cpu->AF.b[HI],cpu->AF.b[HI]) @@ -2242,7 +2247,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) /* Check for previous IX/IY shift. */ - if (cpu->shift!=0) + if (PRIV->shift!=0) { Z80Relative cb_offset; @@ -2287,8 +2292,14 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) case 0xd3: /* OUT (n),A */ TSTATE(11); - if (cpu->pwrite) - cpu->pwrite(cpu,FETCH_BYTE,cpu->AF.b[HI]); + if (PRIV->pwrite) + { + Z80Word port; + + port=FETCH_BYTE; + port|=(Z80Word)cpu->AF.b[HI]<<8; + PRIV->pwrite(cpu,port,cpu->AF.b[HI]); + } else cpu->PC++; break; @@ -2328,13 +2339,13 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) case 0xdb: /* IN A,(n) */ TSTATE(11); - if (cpu->pread) + if (PRIV->pread) { Z80Word port; port=FETCH_BYTE; port|=(Z80Word)cpu->AF.b[HI]<<8; - cpu->AF.b[HI]=cpu->pread(cpu,port); + cpu->AF.b[HI]=PRIV->pread(cpu,port); } else cpu->PC++; @@ -2348,7 +2359,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) TSTATE(4); INC_R; - cpu->shift=opcode; + PRIV->shift=opcode; Z80_Decode(cpu,FETCH_BYTE); break; @@ -2502,7 +2513,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode) TSTATE(4); INC_R; - cpu->shift=opcode; + PRIV->shift=opcode; Z80_Decode(cpu,FETCH_BYTE); break; diff --git a/source/z80_dis.c b/source/z80_dis.c index 9d42829..8a8ade8 100644 --- a/source/z80_dis.c +++ b/source/z80_dis.c @@ -25,6 +25,8 @@ */ static const char ident[]="$Id$"; +#include "z80_config.h" + #ifdef ENABLE_DISASSEM #include @@ -62,7 +64,11 @@ const char *Z80_Dis_Printf(const char *format, ...) Z80Byte Z80_Dis_FetchByte(Z80 *cpu, Z80Word *pc) { - return cpu->disread(cpu,(*pc)++); +#ifdef ENABLE_ARRAY_MEMORY + return Z80_MEMORY[(*pc)++]; +#else + return cpu->priv->disread(cpu,(*pc)++); +#endif } @@ -1454,7 +1460,11 @@ static void DIS_DJNZ (Z80 *z80, Z80Byte op, Z80Word *pc) { Z80Word new; - new=*pc+(Z80Relative)z80->disread(z80,*pc)+1; +#ifdef ENABLE_ARRAY_MEMORY + new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1; +#else + new=*pc+(Z80Relative)z80->priv->disread(z80,*pc)+1; +#endif (*pc)++; Z80_Dis_Set("djnz",Z80_Dis_Printf("$%.4x",new)); } @@ -1469,7 +1479,11 @@ static void DIS_JR (Z80 *z80, Z80Byte op, Z80Word *pc) Z80Word new; const char *p; - new=*pc+(Z80Relative)z80->disread(z80,*pc)+1; +#ifdef ENABLE_ARRAY_MEMORY + new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1; +#else + new=*pc+(Z80Relative)z80->priv->disread(z80,*pc)+1; +#endif (*pc)++; if ((p=GetLabel(new))) @@ -1490,7 +1504,11 @@ static void DIS_JR_CO (Z80 *z80, Z80Byte op, Z80Word *pc) const char *p; con=z80_dis_condition[(op-0x20)/8]; - new=*pc+(Z80Relative)z80->disread(z80,*pc)+1; +#ifdef ENABLE_ARRAY_MEMORY + new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1; +#else + new=*pc+(Z80Relative)z80->priv->disread(z80,*pc)+1; +#endif (*pc)++; if ((p=GetLabel(new))) -- cgit v1.2.3