/* z80 - Z80 Emulator Copyright (C) 2006 Ian Cowburn Some of the opcode routines are based on the Z80 emulation from YAZE, Copyright (c) 1995 Frank D. Cringle. 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$ Z80 */ #include "z80.h" #include "z80_private.h" static const char ident[]="$Id$"; /* ---------------------------------------- LIBRARY VARIABLES */ static Z80Byte PSZtable[512]; static Z80Byte SZtable[512]; static Z80Byte Ptable[512]; static Z80Byte Stable[512]; static Z80Byte Ztable[512]; /* ---------------------------------------- PRIVATE FUNCTIONS */ static void InitTables() { static int init=FALSE; Z80Reg r; Z80Word f; if (init) return; init=TRUE; /* 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<raise) { if (cpu->nmi) { if (cpu->halt) { cpu->halt=FALSE; CALLBACK(eZ80_Halt,0); cpu->PC++; } TSTATE(2); cpu->IFF1=0; cpu->nmi=FALSE; PUSH(PC); cpu->PC=0x66; } else if (cpu->IFF1) { if (cpu->halt) { cpu->halt=FALSE; CALLBACK(eZ80_Halt,0); cpu->PC++; } TSTATE(2); switch(cpu->IM) { default: case 0: INC_R; Z80_Decode(cpu,cpu->devbyte); return; break; case 1: PUSH(PC); cpu->PC=0x38; break; case 2: PUSH(PC); cpu->PC=(Z80Word)cpu->I*256+cpu->devbyte; break; } } cpu->raise=FALSE; } } /* ---------------------------------------- INTERFACES */ Z80 *Z80Init(Z80Memory memory, Z80MemoryControl memcontrol, Z80WritePort write_port, Z80ReadPort read_port) { Z80 *cpu; int f; int r; InitTables(); if (!write_byte || !read_byte || !write_word || !read_word) return NULL; cpu=malloc(sizeof *cpu); if (cpu) { cpu->memory=memory; cpu->memctrl=memcontrol; cpu->pread=read_port; cpu->pwrite=write_port; for(f=0;fcallback[f][r]=NULL; Z80Reset(cpu); } return cpu; } void Z80Reset(Z80 *cpu) { cpu->cycle=0; cpu->PC=0; cpu->A=0xff; cpu->F=0xff; cpu->BC=0xffff; cpu->DE=0xffff; cpu->HL=0xffff; cpu->AF_=0xffff; cpu->BC_=0xffff; cpu->DE_=0xffff; cpu->HL_=0xffff; cpu->IX=0xffff; cpu->IY=0xffff; cpu->SP=0xffff; cpu->IFF1=0; cpu->IFF2=0; cpu->IM=0; cpu->I=0; cpu->R=0; cpu->halt=0; cpu->raise=FALSE; cpu->nmi=FALSE; } void Z80ResetCycles(Z80 *cpu, Z80Val cycles) { cpu->cycle=cycles; } int Z80LodgeCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback) { int f; for(f=0;fcallback[reason][f]) { cpu->callback[reason][f]=callback; return TRUE; } return FALSE; } void Z80RemoveCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback) { int f; for(f=0;fcallback[reason][f]==callback) cpu->callback[reason][f]=NULL; } void Z80Interrupt(Z80 *cpu, Z80Byte devbyte) { cpu->raise=TRUE; cpu->devbyte=devbyte; cpu->nmi=FALSE; } void Z80NMI(Z80 *cpu) { cpu->raise=TRUE; cpu->nmi=TRUE; } int Z80SingleStep(Z80 *cpu) { cpu->last_cb=TRUE; cpu->shift=0; cpu->use_cb_off=FALSE; cpu->cb_off=0; Z80_CheckInterrupt(cpu); CALLBACK(eZ80_Instruction,cpu->cycle); INC_R; Z80_Decode(cpu,cpu->memory[cpu->PC++]); return cpu->last_cb; } void Z80Exec(Z80 *cpu) { while (Z80SingleStep(cpu)); } void Z80GetState(Z80 *cpu, Z80State *state) { #define COPY(a) state->a=cpu->a COPY(cycle); SET_HI(state->AF,cpu->A); SET_LO(state->AF,cpu->F); COPY(BC); COPY(DE); COPY(HL); COPY(AF_); COPY(BC_); COPY(DE_); COPY(HL_); COPY(IX); COPY(IY); COPY(SP); COPY(PC); COPY(IFF1); COPY(IFF2); COPY(IM); COPY(I); COPY(R); #undef COPY } void Z80SetState(Z80 *cpu, Z80State *state) { #define COPY(a) cpu->a=state->a COPY(cycle); cpu->A=GET_HI(state->AF); cpu->F=GET_LO(state->AF); COPY(AF); COPY(BC); COPY(DE); COPY(HL); COPY(AF_); COPY(BC_); COPY(DE_); COPY(HL_); COPY(IX); COPY(IY); COPY(SP); COPY(PC); COPY(IFF1); COPY(IFF2); COPY(IM); COPY(I); COPY(R); #undef COPY } Z80Val Z80Cycles(Z80 *cpu) { return cpu->cycle; } /* END OF FILE */