00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef Z80_H
00021 #define Z80_H
00022
00023 #include "types.h"
00024 #include "register.h"
00025
00026 #define MF2_ACTIVE 1
00027 #define MF2_RUNNING 2
00028 #define MF2_INVISIBLE 4
00029
00030 class Cpc;
00031 extern Cpc cpc;
00032
00033 #define z80_IN_handler (cpc.*IN_handler)
00034 #define z80_OUT_handler (cpc.*OUT_handler)
00035 #define z80_wait_states (cpc.*WS_handler)(); iCycleCountSum += iCycleCount;
00036
00037
00039 class Z80
00040 {
00041 typedef UBYTE (Cpc::*Z80_IN_Handler) (REGPAIR port);
00042 typedef void (Cpc::*Z80_OUT_Handler)(REGPAIR port, UBYTE value);
00043 typedef void (Cpc::*Z80_WS_Handler) (void);
00044
00045 public:
00046 Z80();
00047 ~Z80() {}
00048
00049
00050
00051
00052 enum Flags
00053 {
00054 Sflag = 0x80,
00055 Zflag = 0x40,
00056 Hflag = 0x10,
00057 Pflag = 0x04,
00058 Vflag = 0x04,
00059 Nflag = 0x02,
00060 Cflag = 0x01,
00061 Xflags = 0x28
00062 };
00063
00064 enum Flags2
00065 {
00066 CF = 0x01,
00067 NF = 0x02,
00068 PF = 0x04,
00069 VF = PF,
00070 XF = 0x08,
00071 HF = 0x10,
00072 YF = 0x20,
00073 ZF = 0x40,
00074 SF = 0x80
00075 };
00076
00077
00078 enum ExitCode
00079 {
00080 EC_BREAKPOINT = 10,
00081 EC_TRACE = 20,
00082 EC_FRAME_COMPLETE = 30,
00083 EC_CYCLE_COUNT = 40,
00084 EC_SOUND_BUFFER = 50
00085 };
00086
00087
00088 enum opcodes
00089 {
00090 nop, ld_bc_word, ld_mbc_a, inc_bc, inc_b, dec_b, ld_b_byte, rlca,
00091 ex_af_af, add_hl_bc, ld_a_mbc, dec_bc, inc_c, dec_c, ld_c_byte, rrca,
00092 djnz, ld_de_word, ld_mde_a, inc_de, inc_d, dec_d, ld_d_byte, rla,
00093 jr, add_hl_de, ld_a_mde, dec_de, inc_e, dec_e, ld_e_byte, rra,
00094 jr_nz, ld_hl_word, ld_mword_hl, inc_hl, inc_h, dec_h, ld_h_byte, daa,
00095 jr_z, add_hl_hl, ld_hl_mword, dec_hl, inc_l, dec_l, ld_l_byte, cpl,
00096 jr_nc, ld_sp_word, ld_mword_a, inc_sp, inc_mhl, dec_mhl, ld_mhl_byte, scf,
00097 jr_c, add_hl_sp, ld_a_mword, dec_sp, inc_a, dec_a, ld_a_byte, ccf,
00098 ld_b_b, ld_b_c, ld_b_d, ld_b_e, ld_b_h, ld_b_l, ld_b_mhl, ld_b_a,
00099 ld_c_b, ld_c_c, ld_c_d, ld_c_e, ld_c_h, ld_c_l, ld_c_mhl, ld_c_a,
00100 ld_d_b, ld_d_c, ld_d_d, ld_d_e, ld_d_h, ld_d_l, ld_d_mhl, ld_d_a,
00101 ld_e_b, ld_e_c, ld_e_d, ld_e_e, ld_e_h, ld_e_l, ld_e_mhl, ld_e_a,
00102 ld_h_b, ld_h_c, ld_h_d, ld_h_e, ld_h_h, ld_h_l, ld_h_mhl, ld_h_a,
00103 ld_l_b, ld_l_c, ld_l_d, ld_l_e, ld_l_h, ld_l_l, ld_l_mhl, ld_l_a,
00104 ld_mhl_b, ld_mhl_c, ld_mhl_d, ld_mhl_e, ld_mhl_h, ld_mhl_l, halt, ld_mhl_a,
00105 ld_a_b, ld_a_c, ld_a_d, ld_a_e, ld_a_h, ld_a_l, ld_a_mhl, ld_a_a,
00106 add_b, add_c, add_d, add_e, add_h, add_l, add_mhl, add_a,
00107 adc_b, adc_c, adc_d, adc_e, adc_h, adc_l, adc_mhl, adc_a,
00108 sub_b, sub_c, sub_d, sub_e, sub_h, sub_l, sub_mhl, sub_a,
00109 sbc_b, sbc_c, sbc_d, sbc_e, sbc_h, sbc_l, sbc_mhl, sbc_a,
00110 and_b, and_c, and_d, and_e, and_h, and_l, and_mhl, and_a,
00111 xor_b, xor_c, xor_d, xor_e, xor_h, xor_l, xor_mhl, xor_a,
00112 or_b, or_c, or_d, or_e, or_h, or_l, or_mhl, or_a,
00113 cp_b, cp_c, cp_d, cp_e, cp_h, cp_l, cp_mhl, cp_a,
00114 ret_nz, pop_bc, jp_nz, jp, call_nz, push_bc, add_byte, rst00,
00115 ret_z, ret, jp_z, pfx_cb, call_z, call, adc_byte, rst08,
00116 ret_nc, pop_de, jp_nc, outa, call_nc, push_de, sub_byte, rst10,
00117 ret_c, exx, jp_c, ina, call_c, pfx_dd, sbc_byte, rst18,
00118 ret_po, pop_hl, jp_po, ex_msp_hl, call_po, push_hl, and_byte, rst20,
00119 ret_pe, ld_pc_hl, jp_pe, ex_de_hl, call_pe, pfx_ed, xor_byte, rst28,
00120 ret_p, pop_af, jp_p, di, call_p, push_af, or_byte, rst30,
00121 ret_m, ld_sp_hl, jp_m, ei, call_m, pfx_fd, cp_byte, rst38
00122 };
00123
00124 enum CBcodes
00125 {
00126 rlc_b, rlc_c, rlc_d, rlc_e, rlc_h, rlc_l, rlc_mhl, rlc_a,
00127 rrc_b, rrc_c, rrc_d, rrc_e, rrc_h, rrc_l, rrc_mhl, rrc_a,
00128 rl_b, rl_c, rl_d, rl_e, rl_h, rl_l, rl_mhl, rl_a,
00129 rr_b, rr_c, rr_d, rr_e, rr_h, rr_l, rr_mhl, rr_a,
00130 sla_b, sla_c, sla_d, sla_e, sla_h, sla_l, sla_mhl, sla_a,
00131 sra_b, sra_c, sra_d, sra_e, sra_h, sra_l, sra_mhl, sra_a,
00132 sll_b, sll_c, sll_d, sll_e, sll_h, sll_l, sll_mhl, sll_a,
00133 srl_b, srl_c, srl_d, srl_e, srl_h, srl_l, srl_mhl, srl_a,
00134 bit0_b, bit0_c, bit0_d, bit0_e, bit0_h, bit0_l, bit0_mhl, bit0_a,
00135 bit1_b, bit1_c, bit1_d, bit1_e, bit1_h, bit1_l, bit1_mhl, bit1_a,
00136 bit2_b, bit2_c, bit2_d, bit2_e, bit2_h, bit2_l, bit2_mhl, bit2_a,
00137 bit3_b, bit3_c, bit3_d, bit3_e, bit3_h, bit3_l, bit3_mhl, bit3_a,
00138 bit4_b, bit4_c, bit4_d, bit4_e, bit4_h, bit4_l, bit4_mhl, bit4_a,
00139 bit5_b, bit5_c, bit5_d, bit5_e, bit5_h, bit5_l, bit5_mhl, bit5_a,
00140 bit6_b, bit6_c, bit6_d, bit6_e, bit6_h, bit6_l, bit6_mhl, bit6_a,
00141 bit7_b, bit7_c, bit7_d, bit7_e, bit7_h, bit7_l, bit7_mhl, bit7_a,
00142 res0_b, res0_c, res0_d, res0_e, res0_h, res0_l, res0_mhl, res0_a,
00143 res1_b, res1_c, res1_d, res1_e, res1_h, res1_l, res1_mhl, res1_a,
00144 res2_b, res2_c, res2_d, res2_e, res2_h, res2_l, res2_mhl, res2_a,
00145 res3_b, res3_c, res3_d, res3_e, res3_h, res3_l, res3_mhl, res3_a,
00146 res4_b, res4_c, res4_d, res4_e, res4_h, res4_l, res4_mhl, res4_a,
00147 res5_b, res5_c, res5_d, res5_e, res5_h, res5_l, res5_mhl, res5_a,
00148 res6_b, res6_c, res6_d, res6_e, res6_h, res6_l, res6_mhl, res6_a,
00149 res7_b, res7_c, res7_d, res7_e, res7_h, res7_l, res7_mhl, res7_a,
00150 set0_b, set0_c, set0_d, set0_e, set0_h, set0_l, set0_mhl, set0_a,
00151 set1_b, set1_c, set1_d, set1_e, set1_h, set1_l, set1_mhl, set1_a,
00152 set2_b, set2_c, set2_d, set2_e, set2_h, set2_l, set2_mhl, set2_a,
00153 set3_b, set3_c, set3_d, set3_e, set3_h, set3_l, set3_mhl, set3_a,
00154 set4_b, set4_c, set4_d, set4_e, set4_h, set4_l, set4_mhl, set4_a,
00155 set5_b, set5_c, set5_d, set5_e, set5_h, set5_l, set5_mhl, set5_a,
00156 set6_b, set6_c, set6_d, set6_e, set6_h, set6_l, set6_mhl, set6_a,
00157 set7_b, set7_c, set7_d, set7_e, set7_h, set7_l, set7_mhl, set7_a
00158 };
00159
00160 enum EDcodes
00161 {
00162 ed_00, ed_01, ed_02, ed_03, ed_04, ed_05, ed_06, ed_07,
00163 ed_08, ed_09, ed_0a, ed_0b, ed_0c, ed_0d, ed_0e, ed_0f,
00164 ed_10, ed_11, ed_12, ed_13, ed_14, ed_15, ed_16, ed_17,
00165 ed_18, ed_19, ed_1a, ed_1b, ed_1c, ed_1d, ed_1e, ed_1f,
00166 ed_20, ed_21, ed_22, ed_23, ed_24, ed_25, ed_26, ed_27,
00167 ed_28, ed_29, ed_2a, ed_2b, ed_2c, ed_2d, ed_2e, ed_2f,
00168 ed_30, ed_31, ed_32, ed_33, ed_34, ed_35, ed_36, ed_37,
00169 ed_38, ed_39, ed_3a, ed_3b, ed_3c, ed_3d, ed_3e, ed_3f,
00170 in_b_c, out_c_b, sbc_hl_bc, ld_EDmword_bc, neg, retn, im_0, ld_i_a,
00171 in_c_c, out_c_c, adc_hl_bc, ld_EDbc_mword, neg_1, reti, im_0_1, ld_r_a,
00172 in_d_c, out_c_d, sbc_hl_de, ld_EDmword_de, neg_2, retn_1, im_1, ld_a_i,
00173 in_e_c, out_c_e, adc_hl_de, ld_EDde_mword, neg_3, reti_1, im_2, ld_a_r,
00174 in_h_c, out_c_h, sbc_hl_hl, ld_EDmword_hl, neg_4, retn_2, im_0_2, rrd,
00175 in_l_c, out_c_l, adc_hl_hl, ld_EDhl_mword, neg_5, reti_2, im_0_3, rld,
00176 in_0_c, out_c_0, sbc_hl_sp, ld_EDmword_sp, neg_6, retn_3, im_1_1, ed_77,
00177 in_a_c, out_c_a, adc_hl_sp, ld_EDsp_mword, neg_7, reti_3, im_2_1, ed_7f,
00178 ed_80, ed_81, ed_82, ed_83, ed_84, ed_85, ed_86, ed_87,
00179 ed_88, ed_89, ed_8a, ed_8b, ed_8c, ed_8d, ed_8e, ed_8f,
00180 ed_90, ed_91, ed_92, ed_93, ed_94, ed_95, ed_96, ed_97,
00181 ed_98, ed_99, ed_9a, ed_9b, ed_9c, ed_9d, ed_9e, ed_9f,
00182 ldi, cpi, ini, outi, ed_a4, ed_a5, ed_a6, ed_a7,
00183 ldd, cpd, ind, outd, ed_ac, ed_ad, ed_ae, ed_af,
00184 ldir, cpir, inir, otir, ed_b4, ed_b5, ed_b6, ed_b7,
00185 lddr, cpdr, indr, otdr, ed_bc, ed_bd, ed_be, ed_bf,
00186 ed_c0, ed_c1, ed_c2, ed_c3, ed_c4, ed_c5, ed_c6, ed_c7,
00187 ed_c8, ed_c9, ed_ca, ed_cb, ed_cc, ed_cd, ed_ce, ed_cf,
00188 ed_d0, ed_d1, ed_d2, ed_d3, ed_d4, ed_d5, ed_d6, ed_d7,
00189 ed_d8, ed_d9, ed_da, ed_db, ed_dc, ed_dd, ed_de, ed_df,
00190 ed_e0, ed_e1, ed_e2, ed_e3, ed_e4, ed_e5, ed_e6, ed_e7,
00191 ed_e8, ed_e9, ed_ea, ed_eb, ed_ec, ed_ed, ed_ee, ed_ef,
00192 ed_f0, ed_f1, ed_f2, ed_f3, ed_f4, ed_f5, ed_f6, ed_f7,
00193 ed_f8, ed_f9, ed_fa, ed_fb, ed_fc, ed_fd, ed_fe, ed_ff
00194 };
00195
00196
00197
00198 UBYTE read_mem (UWORD addr)
00199 {return (*(membank_read[addr >> 14] + (addr & 0x3fff)));}
00200
00201 void write_mem (UWORD addr, UBYTE val)
00202 {*(membank_write[addr >> 14] + (addr & 0x3fff)) = val;}
00203
00204 void setMembank_read (UBYTE bank, UBYTE* ptr) {membank_read [bank]=ptr;}
00205 void setMembank_write(UBYTE bank, UBYTE* ptr) {membank_write[bank]=ptr;}
00206
00207 void setInHandler (Z80_IN_Handler handler) {IN_handler=handler;}
00208 void setOutHandler(Z80_OUT_Handler handler) {OUT_handler=handler;}
00209 void setWsHandler (Z80_WS_Handler handler) {WS_handler=handler;}
00210
00211
00212 Register & reg() {return z80;}
00213
00214 void init();
00215 int execute(int cc);
00216 void stop() {mStop=true;}
00217 void init_tables();
00218
00219 int cycleCount() {return iCycleCount;}
00220
00221 void mf2stop();
00222 void setMF2ExitAddr(UDWORD addr) {dwMF2ExitAddr=addr;}
00223
00224
00225
00226 void setIntPending(UBYTE ip) {z80.int_pending=ip;}
00227 UBYTE intPending () {return z80.int_pending;}
00228
00229 void initMemMap() {}
00230 void endMemMap() {}
00231
00232 void z80_pfx_cb();
00233 void z80_pfx_dd();
00234 void z80_pfx_ddcb();
00235 void z80_pfx_ed();
00236 void z80_pfx_fd();
00237 void z80_pfx_fdcb();
00238
00239 inline UBYTE RES(UBYTE bit, UBYTE val);
00240 inline UBYTE RLC(UBYTE val);
00241 inline UBYTE RL (UBYTE val);
00242 inline UBYTE RRC(UBYTE val);
00243 inline UBYTE RR (UBYTE val);
00244 inline UBYTE SET(UBYTE bit, UBYTE val);
00245 inline UBYTE SLA(UBYTE val);
00246 inline UBYTE SLL(UBYTE val);
00247 inline UBYTE SRA(UBYTE val);
00248 inline UBYTE SRL(UBYTE val);
00249
00250 private:
00251 Register z80;
00252
00253 UBYTE* membank_read [4];
00254 UBYTE* membank_write[4];
00255
00256 Z80_IN_Handler IN_handler;
00257 Z80_OUT_Handler OUT_handler;
00258 Z80_WS_Handler WS_handler;
00259
00260 DWORD dwMF2ExitAddr;
00261 DWORD dwMF2Flags;
00262
00263 int iCycleCountSum;
00264 int iCycleCount;
00265 int iCycleCountInit;
00266 int iWSAdjust;
00267
00268 bool mStop;
00269
00270 static UBYTE irep_tmp1[4][4];
00271 static UBYTE drep_tmp1[4][4];
00272 static UBYTE breg_tmp2[256];
00273 static UBYTE cc_op[256];
00274 static UBYTE cc_cb[256];
00275 static UBYTE cc_ed[256];
00276 static UBYTE cc_xy[256];
00277 static UBYTE cc_ex[256];
00278 static UBYTE cc_xycb[256];
00279 static UWORD DAATable[2048];
00280
00281 UBYTE SZ[256];
00282 UBYTE SZ_BIT[256];
00283 UBYTE SZP[256];
00284 UBYTE SZHV_inc[256];
00285 UBYTE SZHV_dec[256];
00286
00287 };
00288
00289 #endif