1 |
/** Z80: portable Z80 emulator *******************************/ |
2 |
/** **/ |
3 |
/** CodesED.h **/ |
4 |
/** **/ |
5 |
/** This file contains implementation for the ED table of **/ |
6 |
/** Z80 commands. It is included from Z80.c. **/ |
7 |
/** **/ |
8 |
/** Copyright (C) Marat Fayzullin 1994-2007 **/ |
9 |
/** You are not allowed to distribute this software **/ |
10 |
/** commercially. Please, notify me, if you make any **/ |
11 |
/** changes to this file. **/ |
12 |
/*************************************************************/ |
13 |
|
14 |
/** This is a special patch for emulating BIOS calls: ********/ |
15 |
case DB_FE: PatchZ80(R);break; |
16 |
/*************************************************************/ |
17 |
|
18 |
case ADC_HL_BC: M_ADCW(BC);break; |
19 |
case ADC_HL_DE: M_ADCW(DE);break; |
20 |
case ADC_HL_HL: M_ADCW(HL);break; |
21 |
case ADC_HL_SP: M_ADCW(SP);break; |
22 |
|
23 |
case SBC_HL_BC: M_SBCW(BC);break; |
24 |
case SBC_HL_DE: M_SBCW(DE);break; |
25 |
case SBC_HL_HL: M_SBCW(HL);break; |
26 |
case SBC_HL_SP: M_SBCW(SP);break; |
27 |
|
28 |
case LD_xWORDe_HL: |
29 |
J.B.l=RdZ80(R->PC.W++); |
30 |
J.B.h=RdZ80(R->PC.W++); |
31 |
WrZ80(J.W++,R->HL.B.l); |
32 |
WrZ80(J.W,R->HL.B.h); |
33 |
break; |
34 |
case LD_xWORDe_DE: |
35 |
J.B.l=RdZ80(R->PC.W++); |
36 |
J.B.h=RdZ80(R->PC.W++); |
37 |
WrZ80(J.W++,R->DE.B.l); |
38 |
WrZ80(J.W,R->DE.B.h); |
39 |
break; |
40 |
case LD_xWORDe_BC: |
41 |
J.B.l=RdZ80(R->PC.W++); |
42 |
J.B.h=RdZ80(R->PC.W++); |
43 |
WrZ80(J.W++,R->BC.B.l); |
44 |
WrZ80(J.W,R->BC.B.h); |
45 |
break; |
46 |
case LD_xWORDe_SP: |
47 |
J.B.l=RdZ80(R->PC.W++); |
48 |
J.B.h=RdZ80(R->PC.W++); |
49 |
WrZ80(J.W++,R->SP.B.l); |
50 |
WrZ80(J.W,R->SP.B.h); |
51 |
break; |
52 |
|
53 |
case LD_HL_xWORDe: |
54 |
J.B.l=RdZ80(R->PC.W++); |
55 |
J.B.h=RdZ80(R->PC.W++); |
56 |
R->HL.B.l=RdZ80(J.W++); |
57 |
R->HL.B.h=RdZ80(J.W); |
58 |
break; |
59 |
case LD_DE_xWORDe: |
60 |
J.B.l=RdZ80(R->PC.W++); |
61 |
J.B.h=RdZ80(R->PC.W++); |
62 |
R->DE.B.l=RdZ80(J.W++); |
63 |
R->DE.B.h=RdZ80(J.W); |
64 |
break; |
65 |
case LD_BC_xWORDe: |
66 |
J.B.l=RdZ80(R->PC.W++); |
67 |
J.B.h=RdZ80(R->PC.W++); |
68 |
R->BC.B.l=RdZ80(J.W++); |
69 |
R->BC.B.h=RdZ80(J.W); |
70 |
break; |
71 |
case LD_SP_xWORDe: |
72 |
J.B.l=RdZ80(R->PC.W++); |
73 |
J.B.h=RdZ80(R->PC.W++); |
74 |
R->SP.B.l=RdZ80(J.W++); |
75 |
R->SP.B.h=RdZ80(J.W); |
76 |
break; |
77 |
|
78 |
case RRD: |
79 |
I=RdZ80(R->HL.W); |
80 |
J.B.l=(I>>4)|(R->AF.B.h<<4); |
81 |
WrZ80(R->HL.W,J.B.l); |
82 |
R->AF.B.h=(I&0x0F)|(R->AF.B.h&0xF0); |
83 |
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG); |
84 |
break; |
85 |
case RLD: |
86 |
I=RdZ80(R->HL.W); |
87 |
J.B.l=(I<<4)|(R->AF.B.h&0x0F); |
88 |
WrZ80(R->HL.W,J.B.l); |
89 |
R->AF.B.h=(I>>4)|(R->AF.B.h&0xF0); |
90 |
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG); |
91 |
break; |
92 |
|
93 |
case LD_A_I: |
94 |
R->AF.B.h=R->I; |
95 |
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&IFF_2? P_FLAG:0)|ZSTable[R->AF.B.h]; |
96 |
break; |
97 |
|
98 |
case LD_A_R: |
99 |
R->R++; |
100 |
R->AF.B.h=(byte)(R->R-R->ICount); |
101 |
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&IFF_2? P_FLAG:0)|ZSTable[R->AF.B.h]; |
102 |
break; |
103 |
|
104 |
case LD_I_A: R->I=R->AF.B.h;break; |
105 |
case LD_R_A: break; |
106 |
|
107 |
case IM_0: R->IFF&=~(IFF_IM1|IFF_IM2);break; |
108 |
case IM_1: R->IFF=(R->IFF&~IFF_IM2)|IFF_IM1;break; |
109 |
case IM_2: R->IFF=(R->IFF&~IFF_IM1)|IFF_IM2;break; |
110 |
|
111 |
case RETI: |
112 |
case RETN: if(R->IFF&IFF_2) R->IFF|=IFF_1; else R->IFF&=~IFF_1; |
113 |
M_RET;break; |
114 |
|
115 |
case NEG: I=R->AF.B.h;R->AF.B.h=0;M_SUB(I);break; |
116 |
|
117 |
case IN_B_xC: M_IN(R->BC.B.h);break; |
118 |
case IN_C_xC: M_IN(R->BC.B.l);break; |
119 |
case IN_D_xC: M_IN(R->DE.B.h);break; |
120 |
case IN_E_xC: M_IN(R->DE.B.l);break; |
121 |
case IN_H_xC: M_IN(R->HL.B.h);break; |
122 |
case IN_L_xC: M_IN(R->HL.B.l);break; |
123 |
case IN_A_xC: M_IN(R->AF.B.h);break; |
124 |
case IN_F_xC: M_IN(J.B.l);break; |
125 |
|
126 |
case OUT_xC_B: OutZ80(R->BC.W,R->BC.B.h);break; |
127 |
case OUT_xC_C: OutZ80(R->BC.W,R->BC.B.l);break; |
128 |
case OUT_xC_D: OutZ80(R->BC.W,R->DE.B.h);break; |
129 |
case OUT_xC_E: OutZ80(R->BC.W,R->DE.B.l);break; |
130 |
case OUT_xC_H: OutZ80(R->BC.W,R->HL.B.h);break; |
131 |
case OUT_xC_L: OutZ80(R->BC.W,R->HL.B.l);break; |
132 |
case OUT_xC_A: OutZ80(R->BC.W,R->AF.B.h);break; |
133 |
|
134 |
case INI: |
135 |
WrZ80(R->HL.W++,InZ80(R->BC.W)); |
136 |
R->BC.B.h--; |
137 |
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG); |
138 |
break; |
139 |
|
140 |
case INIR: |
141 |
do |
142 |
{ |
143 |
WrZ80(R->HL.W++,InZ80(R->BC.W)); |
144 |
R->BC.B.h--;R->ICount-=21; |
145 |
} |
146 |
while(R->BC.B.h&&(R->ICount>0)); |
147 |
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; } |
148 |
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; } |
149 |
break; |
150 |
|
151 |
case IND: |
152 |
WrZ80(R->HL.W--,InZ80(R->BC.W)); |
153 |
R->BC.B.h--; |
154 |
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG); |
155 |
break; |
156 |
|
157 |
case INDR: |
158 |
do |
159 |
{ |
160 |
WrZ80(R->HL.W--,InZ80(R->BC.W)); |
161 |
R->BC.B.h--;R->ICount-=21; |
162 |
} |
163 |
while(R->BC.B.h&&(R->ICount>0)); |
164 |
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; } |
165 |
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; } |
166 |
break; |
167 |
|
168 |
case OUTI: |
169 |
I=RdZ80(R->HL.W++); |
170 |
OutZ80(R->BC.W,I); |
171 |
R->BC.B.h--; |
172 |
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG)|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0); |
173 |
break; |
174 |
|
175 |
case OTIR: |
176 |
do |
177 |
{ |
178 |
I=RdZ80(R->HL.W++); |
179 |
OutZ80(R->BC.W,I); |
180 |
R->BC.B.h--; |
181 |
R->ICount-=21; |
182 |
} |
183 |
while(R->BC.B.h&&(R->ICount>0)); |
184 |
if(R->BC.B.h) |
185 |
{ |
186 |
R->AF.B.l=N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0); |
187 |
R->PC.W-=2; |
188 |
} |
189 |
else |
190 |
{ |
191 |
R->AF.B.l=Z_FLAG|N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0); |
192 |
R->ICount+=5; |
193 |
} |
194 |
break; |
195 |
|
196 |
case OUTD: |
197 |
I=RdZ80(R->HL.W--); |
198 |
OutZ80(R->BC.W,I); |
199 |
R->BC.B.h--; |
200 |
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG)|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0); |
201 |
break; |
202 |
|
203 |
case OTDR: |
204 |
do |
205 |
{ |
206 |
I=RdZ80(R->HL.W--); |
207 |
OutZ80(R->BC.W,I); |
208 |
R->BC.B.h--; |
209 |
R->ICount-=21; |
210 |
} |
211 |
while(R->BC.B.h&&(R->ICount>0)); |
212 |
if(R->BC.B.h) |
213 |
{ |
214 |
R->AF.B.l=N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0); |
215 |
R->PC.W-=2; |
216 |
} |
217 |
else |
218 |
{ |
219 |
R->AF.B.l=Z_FLAG|N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0); |
220 |
R->ICount+=5; |
221 |
} |
222 |
break; |
223 |
|
224 |
case LDI: |
225 |
WrZ80(R->DE.W++,RdZ80(R->HL.W++)); |
226 |
R->BC.W--; |
227 |
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0); |
228 |
break; |
229 |
|
230 |
case LDIR: |
231 |
do |
232 |
{ |
233 |
WrZ80(R->DE.W++,RdZ80(R->HL.W++)); |
234 |
R->BC.W--;R->ICount-=21; |
235 |
} |
236 |
while(R->BC.W&&(R->ICount>0)); |
237 |
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG); |
238 |
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; } |
239 |
else R->ICount+=5; |
240 |
break; |
241 |
|
242 |
case LDD: |
243 |
WrZ80(R->DE.W--,RdZ80(R->HL.W--)); |
244 |
R->BC.W--; |
245 |
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0); |
246 |
break; |
247 |
|
248 |
case LDDR: |
249 |
do |
250 |
{ |
251 |
WrZ80(R->DE.W--,RdZ80(R->HL.W--)); |
252 |
R->BC.W--;R->ICount-=21; |
253 |
} |
254 |
while(R->BC.W&&(R->ICount>0)); |
255 |
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG); |
256 |
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; } |
257 |
else R->ICount+=5; |
258 |
break; |
259 |
|
260 |
case CPI: |
261 |
I=RdZ80(R->HL.W++); |
262 |
J.B.l=R->AF.B.h-I; |
263 |
R->BC.W--; |
264 |
R->AF.B.l = |
265 |
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| |
266 |
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); |
267 |
break; |
268 |
|
269 |
case CPIR: |
270 |
do |
271 |
{ |
272 |
I=RdZ80(R->HL.W++); |
273 |
J.B.l=R->AF.B.h-I; |
274 |
R->BC.W--;R->ICount-=21; |
275 |
} |
276 |
while(R->BC.W&&J.B.l&&(R->ICount>0)); |
277 |
R->AF.B.l = |
278 |
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| |
279 |
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); |
280 |
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5; |
281 |
break; |
282 |
|
283 |
case CPD: |
284 |
I=RdZ80(R->HL.W--); |
285 |
J.B.l=R->AF.B.h-I; |
286 |
R->BC.W--; |
287 |
R->AF.B.l = |
288 |
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| |
289 |
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); |
290 |
break; |
291 |
|
292 |
case CPDR: |
293 |
do |
294 |
{ |
295 |
I=RdZ80(R->HL.W--); |
296 |
J.B.l=R->AF.B.h-I; |
297 |
R->BC.W--;R->ICount-=21; |
298 |
} |
299 |
while(R->BC.W&&J.B.l); |
300 |
R->AF.B.l = |
301 |
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]| |
302 |
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0); |
303 |
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5; |
304 |
break; |