/** fMSX: portable MSX emulator ******************************/ /** **/ /** Z80.c **/ /** **/ /** This file contains implementation for Z80 CPU. It can **/ /** be used separately to emulate a Z80-based machine which **/ /** is not MSX. In this case you will need: Z80.c, Z80.h, **/ /** PTable.h, Codes.h, CodesED.h, CodesCB.h, CodesXX.h, **/ /** CodesXCB.h. Don't forget to remove all MSX-dependent **/ /** parts of the code [M_WRMEM, interrupts, etc.] **/ /** **/ /** Copyright (C) Marat Fayzullin 1994,1995 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ /*************************************************************/ #include "ti85.h" #include "PTable.h" #include /*** Interrupts **********************************************/ /*** Interrupt-related variables. ***/ /*************************************************************/ #ifdef INTERRUPTS word IPeriod = 10000; /* Number of cmds between int. intrpts */ byte IntSync = 1; /* 1 to generate internal interrupts */ byte IFlag = 0; /* If IFlag==1, gen. int. and set to 0 */ #endif /*** Trace and Trap ******************************************/ /*** Switches to turn tracing on and off in DEBUG mode. ***/ /*************************************************************/ #ifdef DEBUG byte Trace=0; /* Tracing is on if Trace==1 */ word Trap=0xffff; /* When PC==Trap, set Trace=1 */ #endif /****************************************************************/ /*** This macro is called when write to RAM occurs and checks ***/ /*** for access to (FFFFh). Replace with *(Addr+A)=V for no ***/ /*** checks. M_WRMEM is defined in Lame.h if LAME is #defined ***/ /****************************************************************/ #ifndef LAME #define M_WRMEM(A,V) \ if (!(A&0x8000)) \ { printf("wrote to rom"); TI85Exit();} \ else \ {*(Addr+A)=V;} #endif #define S(Fl) R.AF.B.l|=Fl #define R(Fl) R.AF.B.l&=~(Fl) #define FLAGS(Rg,Fl) R.AF.B.l=Fl|(Rg? 0:Z_FLAG)|(Rg&S_FLAG) #define M_RLC(Rg) \ R.AF.B.l=Rg&0x80? C_FLAG:0;Rg=(Rg<<1)|R.AF.B.l; \ R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg] #define M_RRC(Rg) \ R.AF.B.l=Rg&0x01;Rg=(Rg>>1)|(R.AF.B.l? 0x80:0); \ R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg] #define M_RL(Rg) \ if(Rg&0x80) \ { \ Rg=(Rg<<1)|(R.AF.B.l&C_FLAG); \ R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg]|C_FLAG; \ } \ else \ { \ Rg=(Rg<<1)|(R.AF.B.l&C_FLAG); \ R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg]; \ } #define M_RR(Rg) \ if(Rg&0x01) \ { \ Rg=(Rg>>1)|(R.AF.B.l&C_FLAG? 0x80:0); \ R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg]|C_FLAG; \ } \ else \ { \ Rg=(Rg>>1)|(R.AF.B.l&C_FLAG? 0x80:0); \ R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg]; \ } #define M_SLA(Rg) \ R.AF.B.l=Rg&0x80? C_FLAG:0;Rg<<=1; \ R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg] #define M_SRA(Rg) \ R.AF.B.l=Rg&C_FLAG;Rg=(Rg>>1)|(Rg&0x80); \ R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg] #define M_SLL(Rg) \ R.AF.B.l=Rg&0x80? C_FLAG:0;Rg=(Rg<<1)|0x01; \ R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg] #define M_SRL(Rg) \ R.AF.B.l=Rg&0x01;Rg>>=1; \ R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|PTable[Rg] #define M_BIT(Bit,Rg) \ R.AF.B.l=(R.AF.B.l&~(N_FLAG|Z_FLAG))|H_FLAG|(Rg&(1<