home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / gbuk.lha / src / Z80.C < prev    next >
C/C++ Source or Header  |  1996-09-17  |  15KB  |  428 lines

  1. /*** VGB: portable GameBoy emulator ***************************/
  2. /**                                                         **/
  3. /**                           Z80.c                         **/
  4. /**                                                         **/
  5. /** This file contains implementation for the GameBoy CPU.  **/
  6. /** See Z80.h for the relevant definitions. Please, note    **/
  7. /** that this code can not be used to emulate a generic Z80 **/
  8. /** because the GameBoy version of it differs from Z80 in   **/
  9. /** many ways.                                              **/
  10. /**                                                         **/
  11. /** Copyright (C) Marat Fayzullin 1994,1995,1996            **/
  12. /**               Marcel de Kogel 1996                      **/
  13. /**     You are not allowed to distribute this software     **/
  14. /**     commercially. Please, notify me, if you make any    **/
  15. /**     changes to this file.                               **/
  16. /*************************************************************/
  17.  
  18. #include "GB.h"
  19. #include <stdio.h>
  20.  
  21.  
  22. /*** Registers ***********************************************/
  23. /*** Z80 registers and running flag.                       ***/
  24. /*************************************************************/
  25. reg R;
  26. byte CPURunning;
  27.  
  28. /*** Interrupts **********************************************/
  29. /*** Interrupt-related variables.                          ***/
  30. /*************************************************************/
  31. int  IPeriod = 10000; /* Number of cmds between int. intrpts */
  32. byte IntSync = 1;     /* 1 to generate internal interrupts   */
  33. byte IFlag = 0;       /* If IFlag==1, gen. int. and set to 0 */
  34. int  ICount;          /* Variable used to count CPU cycles   */
  35.  
  36. /*** Trace and Trap ******************************************/
  37. /*** Switches to turn tracing on and off in DEBUG mode.    ***/
  38. /*************************************************************/
  39. #ifdef DEBUG
  40. byte Trace=0;       /* Tracing is on if Trace==1  */
  41. word Trap=0xFFFF;   /* When PC==Trap, set Trace=1 */
  42. #endif
  43.  
  44. /*** TrapBadOps **********************************************/
  45. /*** When 1, print warnings of illegal Z80 instructions.   ***/
  46. /*************************************************************/
  47. byte TrapBadOps=0;
  48.  
  49.  
  50. #define S(Fl)        R.AF.B.l|=Fl
  51. #define R(Fl)        R.AF.B.l&=~(Fl)
  52. #define FLAGS(Rg,Fl) R.AF.B.l=Fl|(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  53.  
  54. #define M_RLC(Rg)      \
  55.   R.AF.B.l=Rg&0x80? C_FLAG:0;Rg=(Rg<<1)|R.AF.B.l; \
  56.   R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  57. #define M_RRC(Rg)      \
  58.   R.AF.B.l=Rg&0x01;Rg=(Rg>>1)|(R.AF.B.l? 0x80:0); \
  59.   R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  60. #define M_RL(Rg)       \
  61.   if(Rg&0x80)          \
  62.   {                    \
  63.     Rg=(Rg<<1)|(R.AF.B.l&C_FLAG);               \
  64.     R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|C_FLAG; \
  65.   }                    \
  66.   else                 \
  67.   {                    \
  68.     Rg=(Rg<<1)|(R.AF.B.l&C_FLAG);               \
  69.     R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG);        \
  70.   }
  71. #define M_RR(Rg)       \
  72.   if(Rg&0x01)          \
  73.   {                    \
  74.     Rg=(Rg>>1)|(R.AF.B.l&C_FLAG? 0x80:0);       \
  75.     R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)|C_FLAG; \
  76.   }                    \
  77.   else                 \
  78.   {                    \
  79.     Rg=(Rg>>1)|(R.AF.B.l&C_FLAG? 0x80:0);       \
  80.     R.AF.B.l=(Rg? 0:Z_FLAG)|(Rg&S_FLAG);        \
  81.   }
  82.   
  83. #define M_SLA(Rg)      \
  84.   R.AF.B.l=Rg&0x80? C_FLAG:0;Rg<<=1;              \
  85.   R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  86. #define M_SRA(Rg)      \
  87.   R.AF.B.l=Rg&C_FLAG;Rg=(Rg>>1)|(Rg&0x80);        \
  88.   R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  89.  
  90. #define M_SLL(Rg)      \
  91.   R.AF.B.l=Rg&0x80? C_FLAG:0;Rg=(Rg<<1)|0x01;     \
  92.   R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  93. #define M_SRL(Rg)      \
  94.   R.AF.B.l=Rg&0x01;Rg>>=1;                        \
  95.   R.AF.B.l|=(Rg? 0:Z_FLAG)|(Rg&S_FLAG)
  96.  
  97. #define M_BIT(Bit,Rg)  \
  98.   R.AF.B.l=(R.AF.B.l&~(N_FLAG|Z_FLAG))|H_FLAG|(Rg&(1<<Bit)? 0:Z_FLAG)
  99.  
  100. #define M_SET(Bit,Rg) Rg|=1<<Bit
  101. #define M_RES(Bit,Rg) Rg&=~(1<<Bit)
  102.  
  103. #define M_POP(Rg)      \
  104.   R.Rg.B.l=M_RDMEM(R.SP.W++);R.Rg.B.h=M_RDMEM(R.SP.W++);
  105. #define M_PUSH(Rg)     \
  106.   M_WRMEM(--R.SP.W,R.Rg.B.h);M_WRMEM(--R.SP.W,R.Rg.B.l)
  107.  
  108. #define M_CALL         \
  109.   J.B.l=M_RDMEM(R.PC.W++);J.B.h=M_RDMEM(R.PC.W++);       \
  110.   M_WRMEM(--R.SP.W,R.PC.B.h);M_WRMEM(--R.SP.W,R.PC.B.l); \
  111.   R.PC.W=J.W
  112.  
  113. #define M_JP   J.B.l=M_RDMEM(R.PC.W++);J.B.h=M_RDMEM(R.PC.W);R.PC.W=J.W
  114. #define M_JR   R.PC.W+=(offset)M_RDMEM(R.PC.W)+1
  115. #define M_RET  R.PC.B.l=M_RDMEM(R.SP.W++);R.PC.B.h=M_RDMEM(R.SP.W++)
  116.  
  117. #define M_RST(Ad)      \
  118.   M_WRMEM(--R.SP.W,R.PC.B.h);M_WRMEM(--R.SP.W,R.PC.B.l);R.PC.W=Ad
  119.  
  120. #define M_LDWORD(Rg)   \
  121.   R.Rg.B.l=M_RDMEM(R.PC.W++);R.Rg.B.h=M_RDMEM(R.PC.W++)
  122.  
  123. #define M_ADD(Rg)      \
  124.   J.W=R.AF.B.h+Rg;     \
  125.   R.AF.B.l=            \
  126.     J.B.h|(J.B.l? 0:Z_FLAG)|(J.B.l&S_FLAG)|     \
  127.     ((R.AF.B.h^Rg^J.B.l)&H_FLAG);               \
  128.   R.AF.B.h=J.B.l       
  129.  
  130. #define M_SUB(Rg)      \
  131.   J.W=R.AF.B.h-Rg;     \
  132.   R.AF.B.l=            \
  133.     N_FLAG|-J.B.h|(J.B.l? 0:Z_FLAG)|(J.B.l&S_FLAG)|  \
  134.     ((R.AF.B.h^Rg^J.B.l)&H_FLAG);                    \
  135.   R.AF.B.h=J.B.l
  136.  
  137. #define M_ADC(Rg)      \
  138.   J.W=R.AF.B.h+Rg+(R.AF.B.l&C_FLAG);      \
  139.   R.AF.B.l=                               \
  140.     J.B.h|(J.B.l? 0:Z_FLAG)|(J.B.l&S_FLAG)|     \
  141.     ((R.AF.B.h^Rg^J.B.l)&H_FLAG);         \
  142.   R.AF.B.h=J.B.l
  143.  
  144. #define M_SBC(Rg)      \
  145.   J.W=R.AF.B.h-Rg-(R.AF.B.l&C_FLAG); \
  146.   R.AF.B.l=                          \
  147.     N_FLAG|-J.B.h|(J.B.l? 0:Z_FLAG)|(J.B.l&S_FLAG)|  \
  148.     ((R.AF.B.h^Rg^J.B.l)&H_FLAG);    \
  149.   R.AF.B.h=J.B.l
  150.  
  151. #define M_CP(Rg)       \
  152.   J.W=R.AF.B.h-Rg;     \
  153.   R.AF.B.l=            \
  154.     N_FLAG|-J.B.h|(J.B.l? 0:Z_FLAG)|(J.B.l&S_FLAG)|  \
  155.     ((R.AF.B.h^Rg^J.B.l)&H_FLAG)
  156.  
  157. #define M_AND(Rg)       \
  158.   R.AF.B.h&=Rg;         \
  159.   R.AF.B.l=H_FLAG|(R.AF.B.h&S_FLAG)|(R.AF.B.h? 0:Z_FLAG)
  160.  
  161. #define M_OR(Rg)        \
  162.   R.AF.B.h|=Rg;         \
  163.   R.AF.B.l=(R.AF.B.h&S_FLAG)|(R.AF.B.h? 0:Z_FLAG)
  164.  
  165. #define M_XOR(Rg)       \
  166.   R.AF.B.h^=Rg;         \
  167.   R.AF.B.l=(R.AF.B.h&S_FLAG)|(R.AF.B.h? 0:Z_FLAG)
  168.  
  169. #define M_INC(Rg)       \
  170.   Rg++;                 \
  171.   R.AF.B.l=             \
  172.     (R.AF.B.l&C_FLAG)|(Rg&S_FLAG)|     \
  173.     (Rg? 0:Z_FLAG)|(Rg&0x0F? 0:H_FLAG)
  174.  
  175. #define M_DEC(Rg)       \
  176.   Rg--;                 \
  177.   R.AF.B.l=             \
  178.     N_FLAG|(R.AF.B.l&C_FLAG)|(Rg&S_FLAG)|      \
  179.     (Rg? 0:Z_FLAG)|((Rg&0x0F)==0x0F? H_FLAG:0)
  180.  
  181. #define M_ADDW(Rg1,Rg2) \
  182.   R.AF.B.l=                                            \
  183.     (R.AF.B.l&~(N_FLAG|C_FLAG))|                       \
  184.     (((long)R.Rg1.W+(long)R.Rg2.W)&0x10000? C_FLAG:0); \
  185.   R.Rg1.W=(R.Rg1.W+R.Rg2.W)&0xFFFF;
  186.  
  187. #define M_ADCW(Rg)      \
  188.   I=R.AF.B.l&C_FLAG;J.W=(R.HL.W+R.Rg.W+I)&0xFFFF;            \
  189.   R.AF.B.l=                                                  \
  190.     (((long)R.HL.W+(long)R.Rg.W+(long)I)&0x10000? C_FLAG:0)| \
  191.     (J.W? 0:Z_FLAG)|(J.B.h&S_FLAG);                          \
  192.   R.HL.W=J.W
  193.    
  194. #define M_SBCW(Rg)      \
  195.   I=R.AF.B.l&C_FLAG;J.W=(R.HL.W-R.Rg.W-I)&0xFFFF;            \
  196.   R.AF.B.l=                                                  \
  197.     N_FLAG|                                                  \
  198.     (((long)R.HL.W-(long)R.Rg.W-(long)I)&0x10000? C_FLAG:0)| \
  199.     (J.W? 0:Z_FLAG)|(J.B.h&S_FLAG);                          \
  200.   R.HL.W=J.W
  201.  
  202. #define M_IN(Rg)        \
  203.   Rg=DoIn(R.BC.B.l);    \
  204.   R.AF.B.l=(R.AF.B.l&C_FLAG)|(Rg&S_FLAG)|(Rg? 0:Z_FLAG)
  205.  
  206.  
  207. enum Codes
  208. {
  209.   NOP,LD_BC_WORD,LD_xBC_A,INC_BC,INC_B,DEC_B,LD_B_BYTE,RLCA,
  210.   EX_AF_AF,ADD_HL_BC,LD_A_xBC,DEC_BC,INC_C,DEC_C,LD_C_BYTE,RRCA,
  211.   DJNZ,LD_DE_WORD,LD_xDE_A,INC_DE,INC_D,DEC_D,LD_D_BYTE,RLA,
  212.   JR,ADD_HL_DE,LD_A_xDE,DEC_DE,INC_E,DEC_E,LD_E_BYTE,RRA,
  213.   JR_NZ,LD_HL_WORD,LD_xWORD_HL,INC_HL,INC_H,DEC_H,LD_H_BYTE,DAA,
  214.   JR_Z,ADD_HL_HL,LD_HL_xWORD,DEC_HL,INC_L,DEC_L,LD_L_BYTE,CPL,
  215.   JR_NC,LD_SP_WORD,LD_xWORD_A,INC_SP,INC_xHL,DEC_xHL,LD_xHL_BYTE,SCF,
  216.   JR_C,ADD_HL_SP,LD_A_xWORD,DEC_SP,INC_A,DEC_A,LD_A_BYTE,CCF,
  217.   LD_B_B,LD_B_C,LD_B_D,LD_B_E,LD_B_H,LD_B_L,LD_B_xHL,LD_B_A,
  218.   LD_C_B,LD_C_C,LD_C_D,LD_C_E,LD_C_H,LD_C_L,LD_C_xHL,LD_C_A,
  219.   LD_D_B,LD_D_C,LD_D_D,LD_D_E,LD_D_H,LD_D_L,LD_D_xHL,LD_D_A,
  220.   LD_E_B,LD_E_C,LD_E_D,LD_E_E,LD_E_H,LD_E_L,LD_E_xHL,LD_E_A,
  221.   LD_H_B,LD_H_C,LD_H_D,LD_H_E,LD_H_H,LD_H_L,LD_H_xHL,LD_H_A,
  222.   LD_L_B,LD_L_C,LD_L_D,LD_L_E,LD_L_H,LD_L_L,LD_L_xHL,LD_L_A,
  223.   LD_xHL_B,LD_xHL_C,LD_xHL_D,LD_xHL_E,LD_xHL_H,LD_xHL_L,HALT,LD_xHL_A,
  224.   LD_A_B,LD_A_C,LD_A_D,LD_A_E,LD_A_H,LD_A_L,LD_A_xHL,LD_A_A,
  225.   ADD_B,ADD_C,ADD_D,ADD_E,ADD_H,ADD_L,ADD_xHL,ADD_A,
  226.   ADC_B,ADC_C,ADC_D,ADC_E,ADC_H,ADC_L,ADC_xHL,ADC_A,
  227.   SUB_B,SUB_C,SUB_D,SUB_E,SUB_H,SUB_L,SUB_xHL,SUB_A,
  228.   SBC_B,SBC_C,SBC_D,SBC_E,SBC_H,SBC_L,SBC_xHL,SBC_A,
  229.   AND_B,AND_C,AND_D,AND_E,AND_H,AND_L,AND_xHL,AND_A,
  230.   XOR_B,XOR_C,XOR_D,XOR_E,XOR_H,XOR_L,XOR_xHL,XOR_A,
  231.   OR_B,OR_C,OR_D,OR_E,OR_H,OR_L,OR_xHL,OR_A,
  232.   CP_B,CP_C,CP_D,CP_E,CP_H,CP_L,CP_xHL,CP_A,
  233.   RET_NZ,POP_BC,JP_NZ,JP,CALL_NZ,PUSH_BC,ADD_BYTE,RST00,
  234.   RET_Z,RET,JP_Z,PFX_CB,CALL_Z,CALL,ADC_BYTE,RST08,
  235.   RET_NC,POP_DE,JP_NC,OUTA,CALL_NC,PUSH_DE,SUB_BYTE,RST10,
  236.   RET_C,EXX,JP_C,INA,CALL_C,PFX_DD,SBC_BYTE,RST18,
  237.   RET_PO,POP_HL,JP_PO,EX_HL_xSP,CALL_PO,PUSH_HL,AND_BYTE,RST20,
  238.   RET_PE,LD_PC_HL,JP_PE,EX_DE_HL,CALL_PE,PFX_ED,XOR_BYTE,RST28,
  239.   RET_P,POP_AF,JP_P,DI,CALL_P,PUSH_AF,OR_BYTE,RST30,
  240.   RET_M,LD_SP_HL,JP_M,EI,CALL_M,PFX_FD,CP_BYTE,RST38
  241. };
  242.  
  243. enum CodesCB
  244. {
  245.   RLC_B,RLC_C,RLC_D,RLC_E,RLC_H,RLC_L,RLC_xHL,RLC_A,
  246.   RRC_B,RRC_C,RRC_D,RRC_E,RRC_H,RRC_L,RRC_xHL,RRC_A,
  247.   RL_B,RL_C,RL_D,RL_E,RL_H,RL_L,RL_xHL,RL_A,
  248.   RR_B,RR_C,RR_D,RR_E,RR_H,RR_L,RR_xHL,RR_A,
  249.   SLA_B,SLA_C,SLA_D,SLA_E,SLA_H,SLA_L,SLA_xHL,SLA_A,
  250.   SRA_B,SRA_C,SRA_D,SRA_E,SRA_H,SRA_L,SRA_xHL,SRA_A,
  251.   SLL_B,SLL_C,SLL_D,SLL_E,SLL_H,SLL_L,SLL_xHL,SLL_A,
  252.   SRL_B,SRL_C,SRL_D,SRL_E,SRL_H,SRL_L,SRL_xHL,SRL_A,
  253.   BIT0_B,BIT0_C,BIT0_D,BIT0_E,BIT0_H,BIT0_L,BIT0_xHL,BIT0_A,
  254.   BIT1_B,BIT1_C,BIT1_D,BIT1_E,BIT1_H,BIT1_L,BIT1_xHL,BIT1_A,
  255.   BIT2_B,BIT2_C,BIT2_D,BIT2_E,BIT2_H,BIT2_L,BIT2_xHL,BIT2_A,
  256.   BIT3_B,BIT3_C,BIT3_D,BIT3_E,BIT3_H,BIT3_L,BIT3_xHL,BIT3_A,
  257.   BIT4_B,BIT4_C,BIT4_D,BIT4_E,BIT4_H,BIT4_L,BIT4_xHL,BIT4_A,
  258.   BIT5_B,BIT5_C,BIT5_D,BIT5_E,BIT5_H,BIT5_L,BIT5_xHL,BIT5_A,
  259.   BIT6_B,BIT6_C,BIT6_D,BIT6_E,BIT6_H,BIT6_L,BIT6_xHL,BIT6_A,
  260.   BIT7_B,BIT7_C,BIT7_D,BIT7_E,BIT7_H,BIT7_L,BIT7_xHL,BIT7_A,
  261.   RES0_B,RES0_C,RES0_D,RES0_E,RES0_H,RES0_L,RES0_xHL,RES0_A,
  262.   RES1_B,RES1_C,RES1_D,RES1_E,RES1_H,RES1_L,RES1_xHL,RES1_A,
  263.   RES2_B,RES2_C,RES2_D,RES2_E,RES2_H,RES2_L,RES2_xHL,RES2_A,
  264.   RES3_B,RES3_C,RES3_D,RES3_E,RES3_H,RES3_L,RES3_xHL,RES3_A,
  265.   RES4_B,RES4_C,RES4_D,RES4_E,RES4_H,RES4_L,RES4_xHL,RES4_A,
  266.   RES5_B,RES5_C,RES5_D,RES5_E,RES5_H,RES5_L,RES5_xHL,RES5_A,
  267.   RES6_B,RES6_C,RES6_D,RES6_E,RES6_H,RES6_L,RES6_xHL,RES6_A,
  268.   RES7_B,RES7_C,RES7_D,RES7_E,RES7_H,RES7_L,RES7_xHL,RES7_A,  
  269.   SET0_B,SET0_C,SET0_D,SET0_E,SET0_H,SET0_L,SET0_xHL,SET0_A,
  270.   SET1_B,SET1_C,SET1_D,SET1_E,SET1_H,SET1_L,SET1_xHL,SET1_A,
  271.   SET2_B,SET2_C,SET2_D,SET2_E,SET2_H,SET2_L,SET2_xHL,SET2_A,
  272.   SET3_B,SET3_C,SET3_D,SET3_E,SET3_H,SET3_L,SET3_xHL,SET3_A,
  273.   SET4_B,SET4_C,SET4_D,SET4_E,SET4_H,SET4_L,SET4_xHL,SET4_A,
  274.   SET5_B,SET5_C,SET5_D,SET5_E,SET5_H,SET5_L,SET5_xHL,SET5_A,
  275.   SET6_B,SET6_C,SET6_D,SET6_E,SET6_H,SET6_L,SET6_xHL,SET6_A,
  276.   SET7_B,SET7_C,SET7_D,SET7_E,SET7_H,SET7_L,SET7_xHL,SET7_A
  277. };
  278.   
  279. enum CodesED
  280. {
  281.   DB_00,DB_01,DB_02,DB_03,DB_04,DB_05,DB_06,DB_07,
  282.   DB_08,DB_09,DB_0A,DB_0B,DB_0C,DB_0D,DB_0E,DB_0F,
  283.   DB_10,DB_11,DB_12,DB_13,DB_14,DB_15,DB_16,DB_17,
  284.   DB_18,DB_19,DB_1A,DB_1B,DB_1C,DB_1D,DB_1E,DB_1F,
  285.   DB_20,DB_21,DB_22,DB_23,DB_24,DB_25,DB_26,DB_27,
  286.   DB_28,DB_29,DB_2A,DB_2B,DB_2C,DB_2D,DB_2E,DB_2F,
  287.   DB_30,DB_31,DB_32,DB_33,DB_34,DB_35,DB_36,DB_37,
  288.   DB_38,DB_39,DB_3A,DB_3B,DB_3C,DB_3D,DB_3E,DB_3F,
  289.   IN_B_xC,OUT_xC_B,SBC_HL_BC,LD_xWORDe_BC,NEG,RETN,IM_0,LD_I_A,
  290.   IN_C_xC,OUT_xC_C,ADC_HL_BC,LD_BC_xWORDe,DB_4C,RETI,DB_,LD_R_A,
  291.   IN_D_xC,OUT_xC_D,SBC_HL_DE,LD_xWORDe_DE,DB_54,DB_55,IM_1,LD_A_I,
  292.   IN_E_xC,OUT_xC_E,ADC_HL_DE,LD_DE_xWORDe,DB_5C,DB_5D,IM_2,LD_A_R,
  293.   IN_H_xC,OUT_xC_H,SBC_HL_HL,LD_xWORDe_HL,DB_64,DB_65,DB_66,RRD,
  294.   IN_L_xC,OUT_xC_L,ADC_HL_HL,LD_HL_xWORDe,DB_6C,DB_6D,DB_6E,RLD,
  295.   IN_F_xC,DB_71,SBC_HL_SP,LD_xWORDe_SP,DB_74,DB_75,DB_76,DB_77,
  296.   IN_A_xC,OUT_xC_A,ADC_HL_SP,LD_SP_xWORDe,DB_7C,DB_7D,DB_7E,DB_7F,
  297.   DB_80,DB_81,DB_82,DB_83,DB_84,DB_85,DB_86,DB_87,
  298.   DB_88,DB_89,DB_8A,DB_8B,DB_8C,DB_8D,DB_8E,DB_8F,
  299.   DB_90,DB_91,DB_92,DB_93,DB_94,DB_95,DB_96,DB_97,
  300.   DB_98,DB_99,DB_9A,DB_9B,DB_9C,DB_9D,DB_9E,DB_9F,
  301.   LDI,CPI,INI,OUTI,DB_A4,DB_A5,DB_A6,DB_A7,
  302.   LDD,CPD,IND,OUTD,DB_AC,DB_AD,DB_AE,DB_AF,
  303.   LDIR,CPIR,INIR,OTIR,DB_B4,DB_B5,DB_B6,DB_B7,
  304.   LDDR,CPDR,INDR,OTDR,DB_BC,DB_BD,DB_BE,DB_BF,
  305.   DB_C0,DB_C1,DB_C2,DB_C3,DB_C4,DB_C5,DB_C6,DB_C7,
  306.   DB_C8,DB_C9,DB_CA,DB_CB,DB_CC,DB_CD,DB_CE,DB_CF,
  307.   DB_D0,DB_D1,DB_D2,DB_D3,DB_D4,DB_D5,DB_D6,DB_D7,
  308.   DB_D8,DB_D9,DB_DA,DB_DB,DB_DC,DB_DD,DB_DE,DB_DF,
  309.   DB_E0,DB_E1,DB_E2,DB_E3,DB_E4,DB_E5,DB_E6,DB_E7,
  310.   DB_E8,DB_E9,DB_EA,DB_EB,DB_EC,DB_ED,DB_EE,DB_EF,
  311.   DB_F0,DB_F1,DB_F2,DB_F3,DB_F4,DB_F5,DB_F6,DB_F7,
  312.   DB_F8,DB_F9,DB_FA,DB_FB,DB_FC,DB_FD,DB_FE,DB_FF
  313. };
  314.  
  315.  
  316. void CodesCB(void)
  317. {
  318.   register byte I;
  319.  
  320.   switch(M_RDMEM(R.PC.W++))
  321.   {
  322. #include "CodesCB.h"
  323.     default:
  324.       if(TrapBadOps)
  325.         printf
  326.         (   
  327.           "Unrecognized instruction: CB %X at PC=%hX\n",
  328.           M_RDMEM(R.PC.W-1),R.PC.W-2
  329.         );
  330.   }
  331. }
  332.  
  333. void CodesED(void)
  334. {
  335.   register byte I;
  336.   register pair J;
  337.  
  338.   switch(M_RDMEM(R.PC.W++))
  339.   {
  340. #include "CodesED.h"
  341.     case PFX_ED:
  342. #ifdef INTERRUPTS
  343.       ICount++;
  344. #endif
  345.       R.PC.W--;break;
  346.     default:
  347.       if(TrapBadOps)
  348.         printf
  349.         (
  350.           "Unrecognized instruction: ED %X at PC=%hX\n",
  351.           M_RDMEM(R.PC.W-1),R.PC.W-2
  352.         );
  353.   }
  354. }
  355.  
  356. /*** Reset Z80 registers: *********************************/
  357. /*** This function can be used to reset the register    ***/
  358. /*** file before starting execution with Z80(). It sets ***/
  359. /*** the registers to their initial values.             ***/
  360. /**********************************************************/
  361. void ResetZ80(reg *Regs)
  362. {
  363.   Regs->PC.W=0x0100;Regs->SP.W=0xF000;
  364.   Regs->AF.W=Regs->BC.W=Regs->DE.W=Regs->HL.W=0x0000;
  365.   Regs->I=0x00;Regs->IFF=0x00;
  366. }
  367.  
  368. /*** Interpret Z80 code: **********************************/
  369. /*** Registers have initial values from Regs. PC value  ***/
  370. /*** at which emulation stopped is returned by this     ***/
  371. /*** function.                                          ***/
  372. /**********************************************************/
  373. word Z80(reg Regs)
  374. {
  375.   register byte I;
  376.   register pair J;
  377.  
  378.   R=Regs;ICount=IPeriod;CPURunning=1;
  379.  
  380.   while (1)
  381.   {
  382.     LCDSTAT=(LCDSTAT&0xFC)|((ICount>>4)&0x03);
  383.  
  384. #ifdef DEBUG
  385.     if(R.PC.W==Trap) Trace=1;  /*** Turn tracing on if trapped ***/
  386.     if(Trace) Debug(&R);       /*** Call single-step debugger  ***/
  387. #endif
  388.  
  389.     switch(M_RDMEM(R.PC.W++))
  390.     {
  391. #include "Codes.h"
  392.       case PFX_CB: CodesCB();break;
  393.       case PFX_ED: CodesED();break;
  394.       case 0x10:
  395.       case HALT:
  396.         R.PC.W--;R.IFF|=0x80;break;
  397.       default:
  398.         if(TrapBadOps)
  399.           printf
  400.           (
  401.             "Unrecognized instruction: %X at PC=%hX\n",
  402.             M_RDMEM(R.PC.W-1),R.PC.W-1
  403.           );
  404.     }
  405.  
  406.     if(!ICount--) 
  407.     {
  408.       if(!CPURunning) break;
  409.       ICount=IPeriod;
  410. /*
  411.       if(IntSync) IFlag=1;
  412.     }
  413.     if(IFlag)
  414.     {
  415.       IFlag=0;
  416. */
  417.       J.W=Interrupt();
  418.       if((J.W!=0xFFFF)&&(R.IFF&0x81))
  419.       {
  420.         if(R.IFF&0x80) R.PC.W++;
  421.         IFLAGS&=~IMask;R.IFF&=0x7E;
  422.         M_PUSH(PC);R.PC.W=J.W;
  423.       }
  424.     }  
  425.   }
  426.   return(R.PC.W);
  427. }
  428.