/* z80 - Z80 emulation 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 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$ Private macros for Z80 */ #ifndef Z80_PRIVATE_H #define Z80_PRIVATE_H "$Id$" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define MAX_PER_CALLBACK 10 /* ---------------------------------------- TYPES */ typedef union { Z80Word w; Z80Byte b[2]; } Z80Reg; struct Z80 { 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; int raise; Z80Byte devbyte; int nmi; Z80Byte *memory; int *memctrl; Z80ReadPort pread; Z80WritePort pwrite; Z80Callback callback[eZ80_NO_CALLBACK][MAX_PER_CALLBACK]; int last_cb; }; /* ---------------------------------------- MACROS */ /* NOTE: A lot of these macros assume you have a variable called 'cpu' which is a pointer to Z80 */ /* HI/LO */ #define SET_HI(reg,v) reg = (reg & 0x00ff) | ((v) << 8) #define SET_LO(reg,v) reg = (reg & 0xff00) | ((v) & 0xff) #define GET_HI(reg,v) ((reg & 0xff00) >> 8) #define GET_LO(reg,v) (reg & 0xff) /* Invoke a callback class */ #define CALLBACK(r,d) do \ { \ int f; \ \ for(f=0;fcallback[r][f]) \ cpu->callback[r][f](cpu,d); \ } while(0) /* Flag register */ #define C_Z80 0x01 #define N_Z80 0x02 #define P_Z80 0x04 #define V_Z80 P_Z80 #define H_Z80 0x10 #define Z_Z80 0x40 #define S_Z80 0x80 #define B3_Z80 0x08 #define B5_Z80 0x20 #define SET(v,b) (v)|=b #define CLR(v,b) (v)&=~(b) #define SETFLAG(f) SET(cpu->AF.b[LO],f) #define CLRFLAG(f) CLR(cpu->AF.b[LO],f) #define PEEK(addr) (cpu->memory[addr]) #define PEEKW(addr) FPEEKW(cpu,addr) #define POKE(addr,val) do \ { \ Z80Word ba=addr; \ Z80Word bv=val; \ if (cpu->memctrl[(ba)/256]) \ { \ cpu->memory[ba]=bv; \ } \ } 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 (cpu->memory[cpu->PC++]) #define FETCH_WORD (cpu->PC+=2, \ cpu->memory[cpu->PC-2]| \ ((Z80Word)cpu->memory[cpu->PC-1]<<8)) #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) #define IS_H (cpu->AF.b[LO]&H_Z80) #define IS_Z (cpu->AF.b[LO]&Z_Z80) #define IS_S (cpu->AF.b[LO]&S_Z80) #define CARRY IS_C #define IS_IX_IY (cpu->shift==0xdd || cpu->shift==0xfd) #define OFFSET(off) off=(IS_IX_IY ? (Z80Relative)FETCH_BYTE:0) #define TSTATE(n) cpu->cycle+=n #define ADD_R(v) cpu->R=((cpu->R&0x80)|((cpu->R+(v))&0x7f)) #define INC_R ADD_R(1) #define PUSH(REG) do \ { \ cpu->SP-=2; \ POKEW(cpu->SP,REG); \ } while(0) #define POP(REG) do \ { \ REG=PEEKW(cpu->SP); \ cpu->SP+=2; \ } while(0) #define SETHIDDEN(res) cpu->AF.b[LO]=(cpu->AF.b[LO]&~(B3_Z80|B5_Z80))|\ ((res)&(B3_Z80|B5_Z80)) #define CALL do \ { \ PUSH(cpu->PC+2); \ cpu->PC=PEEKW(cpu->PC); \ } while(0) #define NOCALL cpu->PC+=2 #define JP cpu->PC=PEEKW(cpu->PC) #define NOJP cpu->PC+=2 #define JR cpu->PC+=(Z80Relative)PEEK(cpu->PC)+1 #define NOJR cpu->PC++ #define OUT(P,V) do \ { \ if (cpu->pwrite) \ cpu->pwrite(cpu,P,V); \ } while(0) #define IN(P) (cpu->pread?cpu->pread(cpu,P):0) /* ---------------------------------------- LABELS */ extern Z80Label *z80_labels; /* ---------------------------------------- FLAG TABLES */ extern Z80Byte PSZtable[512]; extern Z80Byte SZtable[512]; extern Z80Byte Ptable[512]; extern Z80Byte Stable[512]; extern Z80Byte Ztable[512]; /* ---------------------------------------- GLOBAL GENERAL OPCODES/ROUTINES */ void Z80_Decode(Z80 *cpu, Z80Byte opcode); void Z80_InitialiseInternals(void); /* ---------------------------------------- DISASSEMBLY */ #ifdef ENABLE_DISASSEM typedef void (*DIS_OP_CALLBACK)(Z80 *z80, Z80Byte op, Z80Word *pc); extern DIS_OP_CALLBACK dis_CB_opcode[]; extern DIS_OP_CALLBACK dis_DD_opcode[]; extern DIS_OP_CALLBACK dis_DD_CB_opcode[]; extern DIS_OP_CALLBACK dis_ED_opcode[]; extern DIS_OP_CALLBACK dis_FD_opcode[]; extern DIS_OP_CALLBACK dis_FD_CB_opcode[]; extern DIS_OP_CALLBACK dis_opcode_z80[]; const char *Z80_Dis_Printf(const char *format, ...); Z80Byte Z80_Dis_FetchByte(Z80 *cpu, Z80Word *pc); Z80Word Z80_Dis_FetchWord(Z80 *cpu, Z80Word *pc); void Z80_Dis_Set(const char *op, const char *arg); const char *Z80_Dis_GetOp(void); const char *Z80_Dis_GetArg(void); #endif /* ENABLE_DISASSEM */ #endif /* Z80_PRIVATE_H */ /* END OF FILE */