1 /*** Z80Em: Portable Z80 emulator *******************************************/
2 /*** ***/
3 /*** Z80.c ***/
4 /*** ***/
5 /*** This file contains the emulation code ***/
6 /*** ***/
7 /*** Copyright (C) Marcel de Kogel 1996,1997,1998 ***/
8 /*** You are not allowed to distribute this software commercially ***/
9 /*** Please, notify me, if you make any changes to this file ***/
10 /****************************************************************************/
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15
16 #include "Z80.h"
17
18 #define M_RDMEM(A) Z80_RDMEM(A)
19 #define M_WRMEM(A,V) Z80_WRMEM(A,V)
20 #define M_RDOP(A) Z80_RDOP(A)
21 #define M_RDOP_ARG(A) Z80_RDOP_ARG(A)
22 #define M_RDSTACK(A) Z80_RDSTACK(A)
23 #define M_WRSTACK(A,V) Z80_WRSTACK(A,V)
24
25 #define DoIn(lo,hi) Z80_In((lo)+(((unsigned)(hi))<<8))
26 #define DoOut(lo,hi,v) Z80_Out((lo)+(((unsigned)(hi))<<8),v)
27
28 static void Interrupt(int j);
29 static void ei(void);
30
31 #define S_FLAG 0x80
32 #define Z_FLAG 0x40
33 #define H_FLAG 0x10
34 #define V_FLAG 0x04
35 #define N_FLAG 0x02
36 #define C_FLAG 0x01
37
38 #define M_SKIP_CALL R.PC.W.l+=2
39 #define M_SKIP_JP R.PC.W.l+=2
40 #define M_SKIP_JR R.PC.W.l+=1
41 #define M_SKIP_RET
42
43 static Z80_Regs R;
44 int Z80_Running=1;
45 int Z80_IPeriod=50000;
46 int Z80_ICount=50000;
47 #ifdef DEBUG
48 int Z80_Trace=0;
49 int Z80_Trap=-1;
50 #endif
51 #ifdef TRACE
52 static unsigned pc_trace[256];
53 static unsigned pc_count=0;
54 #endif
55
56 static byte PTable[512];
57 static byte ZSTable[512];
58 static byte ZSPTable[512];
59 #include "Z80DAA.h"
60
61 typedef void (*opcode_fn) (void);
62
63 #define M_C (R.AF.B.l&C_FLAG)
64 #define M_NC (!M_C)
65 #define M_Z (R.AF.B.l&Z_FLAG)
66 #define M_NZ (!M_Z)
67 #define M_M (R.AF.B.l&S_FLAG)
68 #define M_P (!M_M)
69 #define M_PE (R.AF.B.l&V_FLAG)
70 #define M_PO (!M_PE)
71
72 /* Get next opcode argument and increment program counter */
M_RDMEM_OPCODE(void)73 INLINE unsigned M_RDMEM_OPCODE (void)
74 {
75 unsigned retval;
76 retval=M_RDOP_ARG(R.PC.D);
77 R.PC.W.l++;
78 return retval;
79 }
80
M_RDMEM_WORD(dword A)81 INLINE unsigned M_RDMEM_WORD (dword A)
82 {
83 int i;
84 i=M_RDMEM(A);
85 i+=M_RDMEM(((A)+1)&0xFFFF)<<8;
86 return i;
87 }
88
M_WRMEM_WORD(dword A,word V)89 INLINE void M_WRMEM_WORD (dword A,word V)
90 {
91 M_WRMEM (A,V&255);
92 M_WRMEM (((A)+1)&0xFFFF,V>>8);
93 }
94
M_RDMEM_OPCODE_WORD(void)95 INLINE unsigned M_RDMEM_OPCODE_WORD (void)
96 {
97 int i;
98 i=M_RDMEM_OPCODE();
99 i+=M_RDMEM_OPCODE()<<8;
100 return i;
101 }
102
103 #define M_XIX ((R.IX.D+(offset)M_RDMEM_OPCODE())&0xFFFF)
104 #define M_XIY ((R.IY.D+(offset)M_RDMEM_OPCODE())&0xFFFF)
105 #define M_RD_XHL M_RDMEM(R.HL.D)
M_RD_XIX(void)106 INLINE unsigned M_RD_XIX(void)
107 {
108 int i;
109 i=M_XIX;
110 return M_RDMEM(i);
111 }
M_RD_XIY(void)112 INLINE unsigned M_RD_XIY(void)
113 {
114 int i;
115 i=M_XIY;
116 return M_RDMEM(i);
117 }
M_WR_XIX(byte a)118 INLINE void M_WR_XIX(byte a)
119 {
120 int i;
121 i=M_XIX;
122 M_WRMEM(i,a);
123 }
M_WR_XIY(byte a)124 INLINE void M_WR_XIY(byte a)
125 {
126 int i;
127 i=M_XIY;
128 M_WRMEM(i,a);
129 }
130
131 #ifdef X86_ASM
132 #include "Z80CDx86.h"
133 #else
134 #include "Z80Codes.h"
135 #endif
136
adc_a_xhl(void)137 static void adc_a_xhl(void) { byte i=M_RD_XHL; M_ADC(i); }
adc_a_xix(void)138 static void adc_a_xix(void) { byte i=M_RD_XIX(); M_ADC(i); }
adc_a_xiy(void)139 static void adc_a_xiy(void) { byte i=M_RD_XIY(); M_ADC(i); }
adc_a_a(void)140 static void adc_a_a(void) { M_ADC(R.AF.B.h); }
adc_a_b(void)141 static void adc_a_b(void) { M_ADC(R.BC.B.h); }
adc_a_c(void)142 static void adc_a_c(void) { M_ADC(R.BC.B.l); }
adc_a_d(void)143 static void adc_a_d(void) { M_ADC(R.DE.B.h); }
adc_a_e(void)144 static void adc_a_e(void) { M_ADC(R.DE.B.l); }
adc_a_h(void)145 static void adc_a_h(void) { M_ADC(R.HL.B.h); }
adc_a_l(void)146 static void adc_a_l(void) { M_ADC(R.HL.B.l); }
adc_a_ixl(void)147 static void adc_a_ixl(void) { M_ADC(R.IX.B.l); }
adc_a_ixh(void)148 static void adc_a_ixh(void) { M_ADC(R.IX.B.h); }
adc_a_iyl(void)149 static void adc_a_iyl(void) { M_ADC(R.IY.B.l); }
adc_a_iyh(void)150 static void adc_a_iyh(void) { M_ADC(R.IY.B.h); }
adc_a_byte(void)151 static void adc_a_byte(void) { byte i=M_RDMEM_OPCODE(); M_ADC(i); }
152
adc_hl_bc(void)153 static void adc_hl_bc(void) { M_ADCW(BC); }
adc_hl_de(void)154 static void adc_hl_de(void) { M_ADCW(DE); }
adc_hl_hl(void)155 static void adc_hl_hl(void) { M_ADCW(HL); }
adc_hl_sp(void)156 static void adc_hl_sp(void) { M_ADCW(SP); }
157
add_a_xhl(void)158 static void add_a_xhl(void) { byte i=M_RD_XHL; M_ADD(i); }
add_a_xix(void)159 static void add_a_xix(void) { byte i=M_RD_XIX(); M_ADD(i); }
add_a_xiy(void)160 static void add_a_xiy(void) { byte i=M_RD_XIY(); M_ADD(i); }
add_a_a(void)161 static void add_a_a(void) { M_ADD(R.AF.B.h); }
add_a_b(void)162 static void add_a_b(void) { M_ADD(R.BC.B.h); }
add_a_c(void)163 static void add_a_c(void) { M_ADD(R.BC.B.l); }
add_a_d(void)164 static void add_a_d(void) { M_ADD(R.DE.B.h); }
add_a_e(void)165 static void add_a_e(void) { M_ADD(R.DE.B.l); }
add_a_h(void)166 static void add_a_h(void) { M_ADD(R.HL.B.h); }
add_a_l(void)167 static void add_a_l(void) { M_ADD(R.HL.B.l); }
add_a_ixl(void)168 static void add_a_ixl(void) { M_ADD(R.IX.B.l); }
add_a_ixh(void)169 static void add_a_ixh(void) { M_ADD(R.IX.B.h); }
add_a_iyl(void)170 static void add_a_iyl(void) { M_ADD(R.IY.B.l); }
add_a_iyh(void)171 static void add_a_iyh(void) { M_ADD(R.IY.B.h); }
add_a_byte(void)172 static void add_a_byte(void) { byte i=M_RDMEM_OPCODE(); M_ADD(i); }
173
add_hl_bc(void)174 static void add_hl_bc(void) { M_ADDW(HL,BC); }
add_hl_de(void)175 static void add_hl_de(void) { M_ADDW(HL,DE); }
add_hl_hl(void)176 static void add_hl_hl(void) { M_ADDW(HL,HL); }
add_hl_sp(void)177 static void add_hl_sp(void) { M_ADDW(HL,SP); }
add_ix_bc(void)178 static void add_ix_bc(void) { M_ADDW(IX,BC); }
add_ix_de(void)179 static void add_ix_de(void) { M_ADDW(IX,DE); }
add_ix_ix(void)180 static void add_ix_ix(void) { M_ADDW(IX,IX); }
add_ix_sp(void)181 static void add_ix_sp(void) { M_ADDW(IX,SP); }
add_iy_bc(void)182 static void add_iy_bc(void) { M_ADDW(IY,BC); }
add_iy_de(void)183 static void add_iy_de(void) { M_ADDW(IY,DE); }
add_iy_iy(void)184 static void add_iy_iy(void) { M_ADDW(IY,IY); }
add_iy_sp(void)185 static void add_iy_sp(void) { M_ADDW(IY,SP); }
186
and_xhl(void)187 static void and_xhl(void) { byte i=M_RD_XHL; M_AND(i); }
and_xix(void)188 static void and_xix(void) { byte i=M_RD_XIX(); M_AND(i); }
and_xiy(void)189 static void and_xiy(void) { byte i=M_RD_XIY(); M_AND(i); }
and_a(void)190 static void and_a(void) { R.AF.B.l=ZSPTable[R.AF.B.h]|H_FLAG; }
and_b(void)191 static void and_b(void) { M_AND(R.BC.B.h); }
and_c(void)192 static void and_c(void) { M_AND(R.BC.B.l); }
and_d(void)193 static void and_d(void) { M_AND(R.DE.B.h); }
and_e(void)194 static void and_e(void) { M_AND(R.DE.B.l); }
and_h(void)195 static void and_h(void) { M_AND(R.HL.B.h); }
and_l(void)196 static void and_l(void) { M_AND(R.HL.B.l); }
and_ixh(void)197 static void and_ixh(void) { M_AND(R.IX.B.h); }
and_ixl(void)198 static void and_ixl(void) { M_AND(R.IX.B.l); }
and_iyh(void)199 static void and_iyh(void) { M_AND(R.IY.B.h); }
and_iyl(void)200 static void and_iyl(void) { M_AND(R.IY.B.l); }
and_byte(void)201 static void and_byte(void) { byte i=M_RDMEM_OPCODE(); M_AND(i); }
202
bit_0_xhl(void)203 static void bit_0_xhl(void) { byte i=M_RD_XHL; M_BIT(0,i); }
bit_0_xix(void)204 static void bit_0_xix(void) { byte i=M_RD_XIX(); M_BIT(0,i); }
bit_0_xiy(void)205 static void bit_0_xiy(void) { byte i=M_RD_XIY(); M_BIT(0,i); }
bit_0_a(void)206 static void bit_0_a(void) { M_BIT(0,R.AF.B.h); }
bit_0_b(void)207 static void bit_0_b(void) { M_BIT(0,R.BC.B.h); }
bit_0_c(void)208 static void bit_0_c(void) { M_BIT(0,R.BC.B.l); }
bit_0_d(void)209 static void bit_0_d(void) { M_BIT(0,R.DE.B.h); }
bit_0_e(void)210 static void bit_0_e(void) { M_BIT(0,R.DE.B.l); }
bit_0_h(void)211 static void bit_0_h(void) { M_BIT(0,R.HL.B.h); }
bit_0_l(void)212 static void bit_0_l(void) { M_BIT(0,R.HL.B.l); }
213
bit_1_xhl(void)214 static void bit_1_xhl(void) { byte i=M_RD_XHL; M_BIT(1,i); }
bit_1_xix(void)215 static void bit_1_xix(void) { byte i=M_RD_XIX(); M_BIT(1,i); }
bit_1_xiy(void)216 static void bit_1_xiy(void) { byte i=M_RD_XIY(); M_BIT(1,i); }
bit_1_a(void)217 static void bit_1_a(void) { M_BIT(1,R.AF.B.h); }
bit_1_b(void)218 static void bit_1_b(void) { M_BIT(1,R.BC.B.h); }
bit_1_c(void)219 static void bit_1_c(void) { M_BIT(1,R.BC.B.l); }
bit_1_d(void)220 static void bit_1_d(void) { M_BIT(1,R.DE.B.h); }
bit_1_e(void)221 static void bit_1_e(void) { M_BIT(1,R.DE.B.l); }
bit_1_h(void)222 static void bit_1_h(void) { M_BIT(1,R.HL.B.h); }
bit_1_l(void)223 static void bit_1_l(void) { M_BIT(1,R.HL.B.l); }
224
bit_2_xhl(void)225 static void bit_2_xhl(void) { byte i=M_RD_XHL; M_BIT(2,i); }
bit_2_xix(void)226 static void bit_2_xix(void) { byte i=M_RD_XIX(); M_BIT(2,i); }
bit_2_xiy(void)227 static void bit_2_xiy(void) { byte i=M_RD_XIY(); M_BIT(2,i); }
bit_2_a(void)228 static void bit_2_a(void) { M_BIT(2,R.AF.B.h); }
bit_2_b(void)229 static void bit_2_b(void) { M_BIT(2,R.BC.B.h); }
bit_2_c(void)230 static void bit_2_c(void) { M_BIT(2,R.BC.B.l); }
bit_2_d(void)231 static void bit_2_d(void) { M_BIT(2,R.DE.B.h); }
bit_2_e(void)232 static void bit_2_e(void) { M_BIT(2,R.DE.B.l); }
bit_2_h(void)233 static void bit_2_h(void) { M_BIT(2,R.HL.B.h); }
bit_2_l(void)234 static void bit_2_l(void) { M_BIT(2,R.HL.B.l); }
235
bit_3_xhl(void)236 static void bit_3_xhl(void) { byte i=M_RD_XHL; M_BIT(3,i); }
bit_3_xix(void)237 static void bit_3_xix(void) { byte i=M_RD_XIX(); M_BIT(3,i); }
bit_3_xiy(void)238 static void bit_3_xiy(void) { byte i=M_RD_XIY(); M_BIT(3,i); }
bit_3_a(void)239 static void bit_3_a(void) { M_BIT(3,R.AF.B.h); }
bit_3_b(void)240 static void bit_3_b(void) { M_BIT(3,R.BC.B.h); }
bit_3_c(void)241 static void bit_3_c(void) { M_BIT(3,R.BC.B.l); }
bit_3_d(void)242 static void bit_3_d(void) { M_BIT(3,R.DE.B.h); }
bit_3_e(void)243 static void bit_3_e(void) { M_BIT(3,R.DE.B.l); }
bit_3_h(void)244 static void bit_3_h(void) { M_BIT(3,R.HL.B.h); }
bit_3_l(void)245 static void bit_3_l(void) { M_BIT(3,R.HL.B.l); }
246
bit_4_xhl(void)247 static void bit_4_xhl(void) { byte i=M_RD_XHL; M_BIT(4,i); }
bit_4_xix(void)248 static void bit_4_xix(void) { byte i=M_RD_XIX(); M_BIT(4,i); }
bit_4_xiy(void)249 static void bit_4_xiy(void) { byte i=M_RD_XIY(); M_BIT(4,i); }
bit_4_a(void)250 static void bit_4_a(void) { M_BIT(4,R.AF.B.h); }
bit_4_b(void)251 static void bit_4_b(void) { M_BIT(4,R.BC.B.h); }
bit_4_c(void)252 static void bit_4_c(void) { M_BIT(4,R.BC.B.l); }
bit_4_d(void)253 static void bit_4_d(void) { M_BIT(4,R.DE.B.h); }
bit_4_e(void)254 static void bit_4_e(void) { M_BIT(4,R.DE.B.l); }
bit_4_h(void)255 static void bit_4_h(void) { M_BIT(4,R.HL.B.h); }
bit_4_l(void)256 static void bit_4_l(void) { M_BIT(4,R.HL.B.l); }
257
bit_5_xhl(void)258 static void bit_5_xhl(void) { byte i=M_RD_XHL; M_BIT(5,i); }
bit_5_xix(void)259 static void bit_5_xix(void) { byte i=M_RD_XIX(); M_BIT(5,i); }
bit_5_xiy(void)260 static void bit_5_xiy(void) { byte i=M_RD_XIY(); M_BIT(5,i); }
bit_5_a(void)261 static void bit_5_a(void) { M_BIT(5,R.AF.B.h); }
bit_5_b(void)262 static void bit_5_b(void) { M_BIT(5,R.BC.B.h); }
bit_5_c(void)263 static void bit_5_c(void) { M_BIT(5,R.BC.B.l); }
bit_5_d(void)264 static void bit_5_d(void) { M_BIT(5,R.DE.B.h); }
bit_5_e(void)265 static void bit_5_e(void) { M_BIT(5,R.DE.B.l); }
bit_5_h(void)266 static void bit_5_h(void) { M_BIT(5,R.HL.B.h); }
bit_5_l(void)267 static void bit_5_l(void) { M_BIT(5,R.HL.B.l); }
268
bit_6_xhl(void)269 static void bit_6_xhl(void) { byte i=M_RD_XHL; M_BIT(6,i); }
bit_6_xix(void)270 static void bit_6_xix(void) { byte i=M_RD_XIX(); M_BIT(6,i); }
bit_6_xiy(void)271 static void bit_6_xiy(void) { byte i=M_RD_XIY(); M_BIT(6,i); }
bit_6_a(void)272 static void bit_6_a(void) { M_BIT(6,R.AF.B.h); }
bit_6_b(void)273 static void bit_6_b(void) { M_BIT(6,R.BC.B.h); }
bit_6_c(void)274 static void bit_6_c(void) { M_BIT(6,R.BC.B.l); }
bit_6_d(void)275 static void bit_6_d(void) { M_BIT(6,R.DE.B.h); }
bit_6_e(void)276 static void bit_6_e(void) { M_BIT(6,R.DE.B.l); }
bit_6_h(void)277 static void bit_6_h(void) { M_BIT(6,R.HL.B.h); }
bit_6_l(void)278 static void bit_6_l(void) { M_BIT(6,R.HL.B.l); }
279
bit_7_xhl(void)280 static void bit_7_xhl(void) { byte i=M_RD_XHL; M_BIT(7,i); }
bit_7_xix(void)281 static void bit_7_xix(void) { byte i=M_RD_XIX(); M_BIT(7,i); }
bit_7_xiy(void)282 static void bit_7_xiy(void) { byte i=M_RD_XIY(); M_BIT(7,i); }
bit_7_a(void)283 static void bit_7_a(void) { M_BIT(7,R.AF.B.h); }
bit_7_b(void)284 static void bit_7_b(void) { M_BIT(7,R.BC.B.h); }
bit_7_c(void)285 static void bit_7_c(void) { M_BIT(7,R.BC.B.l); }
bit_7_d(void)286 static void bit_7_d(void) { M_BIT(7,R.DE.B.h); }
bit_7_e(void)287 static void bit_7_e(void) { M_BIT(7,R.DE.B.l); }
bit_7_h(void)288 static void bit_7_h(void) { M_BIT(7,R.HL.B.h); }
bit_7_l(void)289 static void bit_7_l(void) { M_BIT(7,R.HL.B.l); }
290
call_c(void)291 static void call_c(void) { if (M_C) { M_CALL; } else { M_SKIP_CALL; } }
call_m(void)292 static void call_m(void) { if (M_M) { M_CALL; } else { M_SKIP_CALL; } }
call_nc(void)293 static void call_nc(void) { if (M_NC) { M_CALL; } else { M_SKIP_CALL; } }
call_nz(void)294 static void call_nz(void) { if (M_NZ) { M_CALL; } else { M_SKIP_CALL; } }
call_p(void)295 static void call_p(void) { if (M_P) { M_CALL; } else { M_SKIP_CALL; } }
call_pe(void)296 static void call_pe(void) { if (M_PE) { M_CALL; } else { M_SKIP_CALL; } }
call_po(void)297 static void call_po(void) { if (M_PO) { M_CALL; } else { M_SKIP_CALL; } }
call_z(void)298 static void call_z(void) { if (M_Z) { M_CALL; } else { M_SKIP_CALL; } }
call(void)299 static void call(void) { M_CALL; }
300
ccf(void)301 static void ccf(void) { R.AF.B.l=((R.AF.B.l&0xED)|((R.AF.B.l&1)<<4))^1; }
302
cp_xhl(void)303 static void cp_xhl(void) { byte i=M_RD_XHL; M_CP(i); }
cp_xix(void)304 static void cp_xix(void) { byte i=M_RD_XIX(); M_CP(i); }
cp_xiy(void)305 static void cp_xiy(void) { byte i=M_RD_XIY(); M_CP(i); }
cp_a(void)306 static void cp_a(void) { M_CP(R.AF.B.h); }
cp_b(void)307 static void cp_b(void) { M_CP(R.BC.B.h); }
cp_c(void)308 static void cp_c(void) { M_CP(R.BC.B.l); }
cp_d(void)309 static void cp_d(void) { M_CP(R.DE.B.h); }
cp_e(void)310 static void cp_e(void) { M_CP(R.DE.B.l); }
cp_h(void)311 static void cp_h(void) { M_CP(R.HL.B.h); }
cp_l(void)312 static void cp_l(void) { M_CP(R.HL.B.l); }
cp_ixh(void)313 static void cp_ixh(void) { M_CP(R.IX.B.h); }
cp_ixl(void)314 static void cp_ixl(void) { M_CP(R.IX.B.l); }
cp_iyh(void)315 static void cp_iyh(void) { M_CP(R.IY.B.h); }
cp_iyl(void)316 static void cp_iyl(void) { M_CP(R.IY.B.l); }
cp_byte(void)317 static void cp_byte(void) { byte i=M_RDMEM_OPCODE(); M_CP(i); }
318
cpd(void)319 static void cpd(void)
320 {
321 byte i,j;
322 i=M_RDMEM(R.HL.D);
323 j=R.AF.B.h-i;
324 --R.HL.W.l;
325 --R.BC.W.l;
326 R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[j]|
327 ((R.AF.B.h^i^j)&H_FLAG)|(R.BC.D? V_FLAG:0)|N_FLAG;
328 }
329
cpdr(void)330 static void cpdr(void)
331 {
332 cpd ();
333 if (R.BC.D && !(R.AF.B.l&Z_FLAG)) { Z80_ICount-=5; R.PC.W.l-=2; }
334 }
335
cpi(void)336 static void cpi(void)
337 {
338 byte i,j;
339 i=M_RDMEM(R.HL.D);
340 j=R.AF.B.h-i;
341 ++R.HL.W.l;
342 --R.BC.W.l;
343 R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[j]|
344 ((R.AF.B.h^i^j)&H_FLAG)|(R.BC.D? V_FLAG:0)|N_FLAG;
345 }
346
cpir(void)347 static void cpir(void)
348 {
349 cpi ();
350 if (R.BC.D && !(R.AF.B.l&Z_FLAG)) { Z80_ICount-=5; R.PC.W.l-=2; }
351 }
352
cpl(void)353 static void cpl(void) { R.AF.B.h^=0xFF; R.AF.B.l|=(H_FLAG|N_FLAG); }
354
daa(void)355 static void daa(void)
356 {
357 int i;
358 i=R.AF.B.h;
359 if (R.AF.B.l&C_FLAG) i|=256;
360 if (R.AF.B.l&H_FLAG) i|=512;
361 if (R.AF.B.l&N_FLAG) i|=1024;
362 R.AF.W.l=DAATable[i];
363 }
364
dec_xhl(void)365 static void dec_xhl(void)
366 {
367 byte i;
368 i=M_RDMEM(R.HL.D);
369 M_DEC(i);
370 M_WRMEM(R.HL.D,i);
371 }
dec_xix(void)372 static void dec_xix(void)
373 {
374 byte i;
375 int j;
376 j=M_XIX;
377 i=M_RDMEM(j);
378 M_DEC(i);
379 M_WRMEM(j,i);
380 }
dec_xiy(void)381 static void dec_xiy(void)
382 {
383 byte i;
384 int j;
385 j=M_XIY;
386 i=M_RDMEM(j);
387 M_DEC(i);
388 M_WRMEM(j,i);
389 }
dec_a(void)390 static void dec_a(void) { M_DEC(R.AF.B.h); }
dec_b(void)391 static void dec_b(void) { M_DEC(R.BC.B.h); }
dec_c(void)392 static void dec_c(void) { M_DEC(R.BC.B.l); }
dec_d(void)393 static void dec_d(void) { M_DEC(R.DE.B.h); }
dec_e(void)394 static void dec_e(void) { M_DEC(R.DE.B.l); }
dec_h(void)395 static void dec_h(void) { M_DEC(R.HL.B.h); }
dec_l(void)396 static void dec_l(void) { M_DEC(R.HL.B.l); }
dec_ixh(void)397 static void dec_ixh(void) { M_DEC(R.IX.B.h); }
dec_ixl(void)398 static void dec_ixl(void) { M_DEC(R.IX.B.l); }
dec_iyh(void)399 static void dec_iyh(void) { M_DEC(R.IY.B.h); }
dec_iyl(void)400 static void dec_iyl(void) { M_DEC(R.IY.B.l); }
401
dec_bc(void)402 static void dec_bc(void) { --R.BC.W.l; }
dec_de(void)403 static void dec_de(void) { --R.DE.W.l; }
dec_hl(void)404 static void dec_hl(void) { --R.HL.W.l; }
dec_ix(void)405 static void dec_ix(void) { --R.IX.W.l; }
dec_iy(void)406 static void dec_iy(void) { --R.IY.W.l; }
dec_sp(void)407 static void dec_sp(void) { --R.SP.W.l; }
408
di(void)409 static void di(void) { R.IFF1=R.IFF2=0; }
410
djnz(void)411 static void djnz(void) { if (--R.BC.B.h) { M_JR; } else { M_SKIP_JR; } }
412
ex_xsp_hl(void)413 static void ex_xsp_hl(void)
414 {
415 int i;
416 i=M_RDMEM_WORD(R.SP.D);
417 M_WRMEM_WORD(R.SP.D,R.HL.D);
418 R.HL.D=i;
419 }
420
ex_xsp_ix(void)421 static void ex_xsp_ix(void)
422 {
423 int i;
424 i=M_RDMEM_WORD(R.SP.D);
425 M_WRMEM_WORD(R.SP.D,R.IX.D);
426 R.IX.D=i;
427 }
428
ex_xsp_iy(void)429 static void ex_xsp_iy(void)
430 {
431 int i;
432 i=M_RDMEM_WORD(R.SP.D);
433 M_WRMEM_WORD(R.SP.D,R.IY.D);
434 R.IY.D=i;
435 }
436
ex_af_af(void)437 static void ex_af_af(void)
438 {
439 int i;
440 i=R.AF.D;
441 R.AF.D=R.AF2.D;
442 R.AF2.D=i;
443 }
444
ex_de_hl(void)445 static void ex_de_hl(void)
446 {
447 int i;
448 i=R.DE.D;
449 R.DE.D=R.HL.D;
450 R.HL.D=i;
451 }
452
exx(void)453 static void exx(void)
454 {
455 int i;
456 i=R.BC.D;
457 R.BC.D=R.BC2.D;
458 R.BC2.D=i;
459 i=R.DE.D;
460 R.DE.D=R.DE2.D;
461 R.DE2.D=i;
462 i=R.HL.D;
463 R.HL.D=R.HL2.D;
464 R.HL2.D=i;
465 }
466
halt(void)467 static void halt(void)
468 {
469 --R.PC.W.l;
470 R.HALT=1;
471 if (Z80_ICount>0) Z80_ICount=0;
472 }
473
im_0(void)474 static void im_0(void) { R.IM=0; }
im_1(void)475 static void im_1(void) { R.IM=1; }
im_2(void)476 static void im_2(void) { R.IM=2; }
477
in_a_c(void)478 static void in_a_c(void) { M_IN(R.AF.B.h); }
in_b_c(void)479 static void in_b_c(void) { M_IN(R.BC.B.h); }
in_c_c(void)480 static void in_c_c(void) { M_IN(R.BC.B.l); }
in_d_c(void)481 static void in_d_c(void) { M_IN(R.DE.B.h); }
in_e_c(void)482 static void in_e_c(void) { M_IN(R.DE.B.l); }
in_h_c(void)483 static void in_h_c(void) { M_IN(R.HL.B.h); }
in_l_c(void)484 static void in_l_c(void) { M_IN(R.HL.B.l); }
in_0_c(void)485 static void in_0_c(void) { byte i; M_IN(i); }
486
in_a_byte(void)487 static void in_a_byte(void)
488 {
489 byte i=M_RDMEM_OPCODE();
490 R.AF.B.h=DoIn(i,R.AF.B.h);
491 }
492
inc_xhl(void)493 static void inc_xhl(void)
494 {
495 byte i;
496 i=M_RDMEM(R.HL.D);
497 M_INC(i);
498 M_WRMEM(R.HL.D,i);
499 }
inc_xix(void)500 static void inc_xix(void)
501 {
502 byte i;
503 int j;
504 j=M_XIX;
505 i=M_RDMEM(j);
506 M_INC(i);
507 M_WRMEM(j,i);
508 }
inc_xiy(void)509 static void inc_xiy(void)
510 {
511 byte i;
512 int j;
513 j=M_XIY;
514 i=M_RDMEM(j);
515 M_INC(i);
516 M_WRMEM(j,i);
517 }
inc_a(void)518 static void inc_a(void) { M_INC(R.AF.B.h); }
inc_b(void)519 static void inc_b(void) { M_INC(R.BC.B.h); }
inc_c(void)520 static void inc_c(void) { M_INC(R.BC.B.l); }
inc_d(void)521 static void inc_d(void) { M_INC(R.DE.B.h); }
inc_e(void)522 static void inc_e(void) { M_INC(R.DE.B.l); }
inc_h(void)523 static void inc_h(void) { M_INC(R.HL.B.h); }
inc_l(void)524 static void inc_l(void) { M_INC(R.HL.B.l); }
inc_ixh(void)525 static void inc_ixh(void) { M_INC(R.IX.B.h); }
inc_ixl(void)526 static void inc_ixl(void) { M_INC(R.IX.B.l); }
inc_iyh(void)527 static void inc_iyh(void) { M_INC(R.IY.B.h); }
inc_iyl(void)528 static void inc_iyl(void) { M_INC(R.IY.B.l); }
529
inc_bc(void)530 static void inc_bc(void) { ++R.BC.W.l; }
inc_de(void)531 static void inc_de(void) { ++R.DE.W.l; }
inc_hl(void)532 static void inc_hl(void) { ++R.HL.W.l; }
inc_ix(void)533 static void inc_ix(void) { ++R.IX.W.l; }
inc_iy(void)534 static void inc_iy(void) { ++R.IY.W.l; }
inc_sp(void)535 static void inc_sp(void) { ++R.SP.W.l; }
536
ind(void)537 static void ind(void)
538 {
539 --R.BC.B.h;
540 M_WRMEM(R.HL.D,DoIn(R.BC.B.l,R.BC.B.h));
541 --R.HL.W.l;
542 R.AF.B.l=(R.BC.B.h)? N_FLAG:(N_FLAG|Z_FLAG);
543 }
544
indr(void)545 static void indr(void)
546 {
547 ind ();
548 if (R.BC.B.h) { Z80_ICount-=5; R.PC.W.l-=2; }
549 }
550
ini(void)551 static void ini(void)
552 {
553 --R.BC.B.h;
554 M_WRMEM(R.HL.D,DoIn(R.BC.B.l,R.BC.B.h));
555 ++R.HL.W.l;
556 R.AF.B.l=(R.BC.B.h)? N_FLAG:(N_FLAG|Z_FLAG);
557 }
558
inir(void)559 static void inir(void)
560 {
561 ini ();
562 if (R.BC.B.h) { Z80_ICount-=5; R.PC.W.l-=2; }
563 }
564
jp(void)565 static void jp(void) { M_JP; }
jp_hl(void)566 static void jp_hl(void) { R.PC.D=R.HL.D; }
jp_ix(void)567 static void jp_ix(void) { R.PC.D=R.IX.D; }
jp_iy(void)568 static void jp_iy(void) { R.PC.D=R.IY.D; }
jp_c(void)569 static void jp_c(void) { if (M_C) { M_JP; } else { M_SKIP_JP; } }
jp_m(void)570 static void jp_m(void) { if (M_M) { M_JP; } else { M_SKIP_JP; } }
jp_nc(void)571 static void jp_nc(void) { if (M_NC) { M_JP; } else { M_SKIP_JP; } }
jp_nz(void)572 static void jp_nz(void) { if (M_NZ) { M_JP; } else { M_SKIP_JP; } }
jp_p(void)573 static void jp_p(void) { if (M_P) { M_JP; } else { M_SKIP_JP; } }
jp_pe(void)574 static void jp_pe(void) { if (M_PE) { M_JP; } else { M_SKIP_JP; } }
jp_po(void)575 static void jp_po(void) { if (M_PO) { M_JP; } else { M_SKIP_JP; } }
jp_z(void)576 static void jp_z(void) { if (M_Z) { M_JP; } else { M_SKIP_JP; } }
577
jr(void)578 static void jr(void) { M_JR; }
jr_c(void)579 static void jr_c(void) { if (M_C) { M_JR; } else { M_SKIP_JR; } }
jr_nc(void)580 static void jr_nc(void) { if (M_NC) { M_JR; } else { M_SKIP_JR; } }
jr_nz(void)581 static void jr_nz(void) { if (M_NZ) { M_JR; } else { M_SKIP_JR; } }
jr_z(void)582 static void jr_z(void) { if (M_Z) { M_JR; } else { M_SKIP_JR; } }
583
ld_xbc_a(void)584 static void ld_xbc_a(void) { M_WRMEM(R.BC.D,R.AF.B.h); }
ld_xde_a(void)585 static void ld_xde_a(void) { M_WRMEM(R.DE.D,R.AF.B.h); }
ld_xhl_a(void)586 static void ld_xhl_a(void) { M_WRMEM(R.HL.D,R.AF.B.h); }
ld_xhl_b(void)587 static void ld_xhl_b(void) { M_WRMEM(R.HL.D,R.BC.B.h); }
ld_xhl_c(void)588 static void ld_xhl_c(void) { M_WRMEM(R.HL.D,R.BC.B.l); }
ld_xhl_d(void)589 static void ld_xhl_d(void) { M_WRMEM(R.HL.D,R.DE.B.h); }
ld_xhl_e(void)590 static void ld_xhl_e(void) { M_WRMEM(R.HL.D,R.DE.B.l); }
ld_xhl_h(void)591 static void ld_xhl_h(void) { M_WRMEM(R.HL.D,R.HL.B.h); }
ld_xhl_l(void)592 static void ld_xhl_l(void) { M_WRMEM(R.HL.D,R.HL.B.l); }
ld_xhl_byte(void)593 static void ld_xhl_byte(void) { byte i=M_RDMEM_OPCODE(); M_WRMEM(R.HL.D,i); }
ld_xix_a(void)594 static void ld_xix_a(void) { M_WR_XIX(R.AF.B.h); }
ld_xix_b(void)595 static void ld_xix_b(void) { M_WR_XIX(R.BC.B.h); }
ld_xix_c(void)596 static void ld_xix_c(void) { M_WR_XIX(R.BC.B.l); }
ld_xix_d(void)597 static void ld_xix_d(void) { M_WR_XIX(R.DE.B.h); }
ld_xix_e(void)598 static void ld_xix_e(void) { M_WR_XIX(R.DE.B.l); }
ld_xix_h(void)599 static void ld_xix_h(void) { M_WR_XIX(R.HL.B.h); }
ld_xix_l(void)600 static void ld_xix_l(void) { M_WR_XIX(R.HL.B.l); }
ld_xix_byte(void)601 static void ld_xix_byte(void)
602 {
603 int i,j;
604 i=M_XIX;
605 j=M_RDMEM_OPCODE();
606 M_WRMEM(i,j);
607 }
ld_xiy_a(void)608 static void ld_xiy_a(void) { M_WR_XIY(R.AF.B.h); }
ld_xiy_b(void)609 static void ld_xiy_b(void) { M_WR_XIY(R.BC.B.h); }
ld_xiy_c(void)610 static void ld_xiy_c(void) { M_WR_XIY(R.BC.B.l); }
ld_xiy_d(void)611 static void ld_xiy_d(void) { M_WR_XIY(R.DE.B.h); }
ld_xiy_e(void)612 static void ld_xiy_e(void) { M_WR_XIY(R.DE.B.l); }
ld_xiy_h(void)613 static void ld_xiy_h(void) { M_WR_XIY(R.HL.B.h); }
ld_xiy_l(void)614 static void ld_xiy_l(void) { M_WR_XIY(R.HL.B.l); }
ld_xiy_byte(void)615 static void ld_xiy_byte(void)
616 {
617 int i,j;
618 i=M_XIY;
619 j=M_RDMEM_OPCODE();
620 M_WRMEM(i,j);
621 }
ld_xbyte_a(void)622 static void ld_xbyte_a(void)
623 { int i=M_RDMEM_OPCODE_WORD(); M_WRMEM(i,R.AF.B.h); }
ld_xword_bc(void)624 static void ld_xword_bc(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.BC.D); }
ld_xword_de(void)625 static void ld_xword_de(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.DE.D); }
ld_xword_hl(void)626 static void ld_xword_hl(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.HL.D); }
ld_xword_ix(void)627 static void ld_xword_ix(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.IX.D); }
ld_xword_iy(void)628 static void ld_xword_iy(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.IY.D); }
ld_xword_sp(void)629 static void ld_xword_sp(void) { M_WRMEM_WORD(M_RDMEM_OPCODE_WORD(),R.SP.D); }
ld_a_xbc(void)630 static void ld_a_xbc(void) { R.AF.B.h=M_RDMEM(R.BC.D); }
ld_a_xde(void)631 static void ld_a_xde(void) { R.AF.B.h=M_RDMEM(R.DE.D); }
ld_a_xhl(void)632 static void ld_a_xhl(void) { R.AF.B.h=M_RD_XHL; }
ld_a_xix(void)633