1 /** Z80: portable Z80 emulator *******************************/
2 /**                                                         **/
3 /**                          Codes.h                        **/
4 /**                                                         **/
5 /** This file contains implementation for the main table of **/
6 /** Z80 commands. It is included from Z80.c.                **/
7 /**                                                         **/
8 /** Copyright (C) Marat Fayzullin 1994-2009                 **/
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 case JR_NZ:   if(R->AF.B.l&Z_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
15 case JR_NC:   if(R->AF.B.l&C_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
16 case JR_Z:    if(R->AF.B.l&Z_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
17 case JR_C:    if(R->AF.B.l&C_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
18 
19 case JP_NZ:   if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
20 case JP_NC:   if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
21 case JP_PO:   if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
22 case JP_P:    if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
23 case JP_Z:    if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
24 case JP_C:    if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
25 case JP_PE:   if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
26 case JP_M:    if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
27 
28 case RET_NZ:  if(!(R->AF.B.l&Z_FLAG)) { R->ICount-=6;M_RET; } break;
29 case RET_NC:  if(!(R->AF.B.l&C_FLAG)) { R->ICount-=6;M_RET; } break;
30 case RET_PO:  if(!(R->AF.B.l&P_FLAG)) { R->ICount-=6;M_RET; } break;
31 case RET_P:   if(!(R->AF.B.l&S_FLAG)) { R->ICount-=6;M_RET; } break;
32 case RET_Z:   if(R->AF.B.l&Z_FLAG)    { R->ICount-=6;M_RET; } break;
33 case RET_C:   if(R->AF.B.l&C_FLAG)    { R->ICount-=6;M_RET; } break;
34 case RET_PE:  if(R->AF.B.l&P_FLAG)    { R->ICount-=6;M_RET; } break;
35 case RET_M:   if(R->AF.B.l&S_FLAG)    { R->ICount-=6;M_RET; } break;
36 
37 case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
38 case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
39 case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
40 case CALL_P:  if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
41 case CALL_Z:  if(R->AF.B.l&Z_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
42 case CALL_C:  if(R->AF.B.l&C_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
43 case CALL_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
44 case CALL_M:  if(R->AF.B.l&S_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
45 
46 case ADD_B:    M_ADD(R->BC.B.h);break;
47 case ADD_C:    M_ADD(R->BC.B.l);break;
48 case ADD_D:    M_ADD(R->DE.B.h);break;
49 case ADD_E:    M_ADD(R->DE.B.l);break;
50 case ADD_H:    M_ADD(R->HL.B.h);break;
51 case ADD_L:    M_ADD(R->HL.B.l);break;
52 case ADD_A:    M_ADD(R->AF.B.h);break;
53 case ADD_xHL:  I=RdZ80(R->HL.W);M_ADD(I);break;
54 case ADD_BYTE: I=OpZ80(R->PC.W++);M_ADD(I);break;
55 
56 case SUB_B:    M_SUB(R->BC.B.h);break;
57 case SUB_C:    M_SUB(R->BC.B.l);break;
58 case SUB_D:    M_SUB(R->DE.B.h);break;
59 case SUB_E:    M_SUB(R->DE.B.l);break;
60 case SUB_H:    M_SUB(R->HL.B.h);break;
61 case SUB_L:    M_SUB(R->HL.B.l);break;
62 case SUB_A:    R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
63 case SUB_xHL:  I=RdZ80(R->HL.W);M_SUB(I);break;
64 case SUB_BYTE: I=OpZ80(R->PC.W++);M_SUB(I);break;
65 
66 case AND_B:    M_AND(R->BC.B.h);break;
67 case AND_C:    M_AND(R->BC.B.l);break;
68 case AND_D:    M_AND(R->DE.B.h);break;
69 case AND_E:    M_AND(R->DE.B.l);break;
70 case AND_H:    M_AND(R->HL.B.h);break;
71 case AND_L:    M_AND(R->HL.B.l);break;
72 case AND_A:    M_AND(R->AF.B.h);break;
73 case AND_xHL:  I=RdZ80(R->HL.W);M_AND(I);break;
74 case AND_BYTE: I=OpZ80(R->PC.W++);M_AND(I);break;
75 
76 case OR_B:     M_OR(R->BC.B.h);break;
77 case OR_C:     M_OR(R->BC.B.l);break;
78 case OR_D:     M_OR(R->DE.B.h);break;
79 case OR_E:     M_OR(R->DE.B.l);break;
80 case OR_H:     M_OR(R->HL.B.h);break;
81 case OR_L:     M_OR(R->HL.B.l);break;
82 case OR_A:     M_OR(R->AF.B.h);break;
83 case OR_xHL:   I=RdZ80(R->HL.W);M_OR(I);break;
84 case OR_BYTE:  I=OpZ80(R->PC.W++);M_OR(I);break;
85 
86 case ADC_B:    M_ADC(R->BC.B.h);break;
87 case ADC_C:    M_ADC(R->BC.B.l);break;
88 case ADC_D:    M_ADC(R->DE.B.h);break;
89 case ADC_E:    M_ADC(R->DE.B.l);break;
90 case ADC_H:    M_ADC(R->HL.B.h);break;
91 case ADC_L:    M_ADC(R->HL.B.l);break;
92 case ADC_A:    M_ADC(R->AF.B.h);break;
93 case ADC_xHL:  I=RdZ80(R->HL.W);M_ADC(I);break;
94 case ADC_BYTE: I=OpZ80(R->PC.W++);M_ADC(I);break;
95 
96 case SBC_B:    M_SBC(R->BC.B.h);break;
97 case SBC_C:    M_SBC(R->BC.B.l);break;
98 case SBC_D:    M_SBC(R->DE.B.h);break;
99 case SBC_E:    M_SBC(R->DE.B.l);break;
100 case SBC_H:    M_SBC(R->HL.B.h);break;
101 case SBC_L:    M_SBC(R->HL.B.l);break;
102 case SBC_A:    M_SBC(R->AF.B.h);break;
103 case SBC_xHL:  I=RdZ80(R->HL.W);M_SBC(I);break;
104 case SBC_BYTE: I=OpZ80(R->PC.W++);M_SBC(I);break;
105 
106 case XOR_B:    M_XOR(R->BC.B.h);break;
107 case XOR_C:    M_XOR(R->BC.B.l);break;
108 case XOR_D:    M_XOR(R->DE.B.h);break;
109 case XOR_E:    M_XOR(R->DE.B.l);break;
110 case XOR_H:    M_XOR(R->HL.B.h);break;
111 case XOR_L:    M_XOR(R->HL.B.l);break;
112 case XOR_A:    R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
113 case XOR_xHL:  I=RdZ80(R->HL.W);M_XOR(I);break;
114 case XOR_BYTE: I=OpZ80(R->PC.W++);M_XOR(I);break;
115 
116 case CP_B:     M_CP(R->BC.B.h);break;
117 case CP_C:     M_CP(R->BC.B.l);break;
118 case CP_D:     M_CP(R->DE.B.h);break;
119 case CP_E:     M_CP(R->DE.B.l);break;
120 case CP_H:     M_CP(R->HL.B.h);break;
121 case CP_L:     M_CP(R->HL.B.l);break;
122 case CP_A:     R->AF.B.l=N_FLAG|Z_FLAG;break;
123 case CP_xHL:   I=RdZ80(R->HL.W);M_CP(I);break;
124 case CP_BYTE:  I=OpZ80(R->PC.W++);M_CP(I);break;
125 
126 case LD_BC_WORD: M_LDWORD(BC);break;
127 case LD_DE_WORD: M_LDWORD(DE);break;
128 case LD_HL_WORD: M_LDWORD(HL);break;
129 case LD_SP_WORD: M_LDWORD(SP);break;
130 
131 case LD_PC_HL: R->PC.W=R->HL.W;JumpZ80(R->PC.W);break;
132 case LD_SP_HL: R->SP.W=R->HL.W;break;
133 case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
134 case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
135 
136 case ADD_HL_BC:  M_ADDW(HL,BC);break;
137 case ADD_HL_DE:  M_ADDW(HL,DE);break;
138 case ADD_HL_HL:  M_ADDW(HL,HL);break;
139 case ADD_HL_SP:  M_ADDW(HL,SP);break;
140 
141 case DEC_BC:   R->BC.W--;break;
142 case DEC_DE:   R->DE.W--;break;
143 case DEC_HL:   R->HL.W--;break;
144 case DEC_SP:   R->SP.W--;break;
145 
146 case INC_BC:   R->BC.W++;break;
147 case INC_DE:   R->DE.W++;break;
148 case INC_HL:   R->HL.W++;break;
149 case INC_SP:   R->SP.W++;break;
150 
151 case DEC_B:    M_DEC(R->BC.B.h);break;
152 case DEC_C:    M_DEC(R->BC.B.l);break;
153 case DEC_D:    M_DEC(R->DE.B.h);break;
154 case DEC_E:    M_DEC(R->DE.B.l);break;
155 case DEC_H:    M_DEC(R->HL.B.h);break;
156 case DEC_L:    M_DEC(R->HL.B.l);break;
157 case DEC_A:    M_DEC(R->AF.B.h);break;
158 case DEC_xHL:  I=RdZ80(R->HL.W);M_DEC(I);WrZ80(R->HL.W,I);break;
159 
160 case INC_B:    M_INC(R->BC.B.h);break;
161 case INC_C:    M_INC(R->BC.B.l);break;
162 case INC_D:    M_INC(R->DE.B.h);break;
163 case INC_E:    M_INC(R->DE.B.l);break;
164 case INC_H:    M_INC(R->HL.B.h);break;
165 case INC_L:    M_INC(R->HL.B.l);break;
166 case INC_A:    M_INC(R->AF.B.h);break;
167 case INC_xHL:  I=RdZ80(R->HL.W);M_INC(I);WrZ80(R->HL.W,I);break;
168 
169 case RLCA:
170   I=R->AF.B.h&0x80? C_FLAG:0;
171   R->AF.B.h=(R->AF.B.h<<1)|I;
172   R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
173   break;
174 case RLA:
175   I=R->AF.B.h&0x80? C_FLAG:0;
176   R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
177   R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
178   break;
179 case RRCA:
180   I=R->AF.B.h&0x01;
181   R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
182   R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
183   break;
184 case RRA:
185   I=R->AF.B.h&0x01;
186   R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
187   R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
188   break;
189 
190 case RST00:    M_RST(0x0000);break;
191 case RST08:    M_RST(0x0008);break;
192 case RST10:    M_RST(0x0010);break;
193 case RST18:    M_RST(0x0018);break;
194 case RST20:    M_RST(0x0020);break;
195 case RST28:    M_RST(0x0028);break;
196 case RST30:    M_RST(0x0030);break;
197 case RST38:    M_RST(0x0038);break;
198 
199 case PUSH_BC:  M_PUSH(BC);break;
200 case PUSH_DE:  M_PUSH(DE);break;
201 case PUSH_HL:  M_PUSH(HL);break;
202 case PUSH_AF:  M_PUSH(AF);break;
203 
204 case POP_BC:   M_POP(BC);break;
205 case POP_DE:   M_POP(DE);break;
206 case POP_HL:   M_POP(HL);break;
207 case POP_AF:   M_POP(AF);break;
208 
209 case DJNZ: if(--R->BC.B.h) { R->ICount-=5;M_JR; } else R->PC.W++;break;
210 case JP:   M_JP;break;
211 case JR:   M_JR;break;
212 case CALL: M_CALL;break;
213 case RET:  M_RET;break;
214 case SCF:  S(C_FLAG);R(N_FLAG|H_FLAG);break;
215 case CPL:  R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
216 case NOP:  break;
217 case OUTA: I=OpZ80(R->PC.W++);OutZ80(I|(R->AF.W&0xFF00),R->AF.B.h);break;
218 case INA:  I=OpZ80(R->PC.W++);R->AF.B.h=InZ80(I|(R->AF.W&0xFF00));break;
219 
220 case HALT:
221   R->PC.W--;
222   R->IFF|=IFF_HALT;
223   R->IBackup=0;
224   R->ICount=0;
225   break;
226 
227 case DI:
228   if(R->IFF&IFF_EI) R->ICount+=R->IBackup-1;
229   R->IFF&=~(IFF_1|IFF_2|IFF_EI);
230   break;
231 
232 case EI:
233   if(!(R->IFF&(IFF_1|IFF_EI)))
234   {
235     R->IFF|=IFF_2|IFF_EI;
236     R->IBackup=R->ICount;
237     R->ICount=1;
238   }
239   break;
240 
241 case CCF:
242   R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
243   R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
244   break;
245 
246 case EXX:
247   J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
248   J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
249   J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
250   break;
251 
252 case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
253 case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
254 
255 case LD_B_B:   R->BC.B.h=R->BC.B.h;break;
256 case LD_C_B:   R->BC.B.l=R->BC.B.h;break;
257 case LD_D_B:   R->DE.B.h=R->BC.B.h;break;
258 case LD_E_B:   R->DE.B.l=R->BC.B.h;break;
259 case LD_H_B:   R->HL.B.h=R->BC.B.h;break;
260 case LD_L_B:   R->HL.B.l=R->BC.B.h;break;
261 case LD_A_B:   R->AF.B.h=R->BC.B.h;break;
262 case LD_xHL_B: WrZ80(R->HL.W,R->BC.B.h);break;
263 
264 case LD_B_C:   R->BC.B.h=R->BC.B.l;break;
265 case LD_C_C:   R->BC.B.l=R->BC.B.l;break;
266 case LD_D_C:   R->DE.B.h=R->BC.B.l;break;
267 case LD_E_C:   R->DE.B.l=R->BC.B.l;break;
268 case LD_H_C:   R->HL.B.h=R->BC.B.l;break;
269 case LD_L_C:   R->HL.B.l=R->BC.B.l;break;
270 case LD_A_C:   R->AF.B.h=R->BC.B.l;break;
271 case LD_xHL_C: WrZ80(R->HL.W,R->BC.B.l);break;
272 
273 case LD_B_D:   R->BC.B.h=R->DE.B.h;break;
274 case LD_C_D:   R->BC.B.l=R->DE.B.h;break;
275 case LD_D_D:   R->DE.B.h=R->DE.B.h;break;
276 case LD_E_D:   R->DE.B.l=R->DE.B.h;break;
277 case LD_H_D:   R->HL.B.h=R->DE.B.h;break;
278 case LD_L_D:   R->HL.B.l=R->DE.B.h;break;
279 case LD_A_D:   R->AF.B.h=R->DE.B.h;break;
280 case LD_xHL_D: WrZ80(R->HL.W,R->DE.B.h);break;
281 
282 case LD_B_E:   R->BC.B.h=R->DE.B.l;break;
283 case LD_C_E:   R->BC.B.l=R->DE.B.l;break;
284 case LD_D_E:   R->DE.B.h=R->DE.B.l;break;
285 case LD_E_E:   R->DE.B.l=R->DE.B.l;break;
286 case LD_H_E:   R->HL.B.h=R->DE.B.l;break;
287 case LD_L_E:   R->HL.B.l=R->DE.B.l;break;
288 case LD_A_E:   R->AF.B.h=R->DE.B.l;break;
289 case LD_xHL_E: WrZ80(R->HL.W,R->DE.B.l);break;
290 
291 case LD_B_H:   R->BC.B.h=R->HL.B.h;break;
292 case LD_C_H:   R->BC.B.l=R->HL.B.h;break;
293 case LD_D_H:   R->DE.B.h=R->HL.B.h;break;
294 case LD_E_H:   R->DE.B.l=R->HL.B.h;break;
295 case LD_H_H:   R->HL.B.h=R->HL.B.h;break;
296 case LD_L_H:   R->HL.B.l=R->HL.B.h;break;
297 case LD_A_H:   R->AF.B.h=R->HL.B.h;break;
298 case LD_xHL_H: WrZ80(R->HL.W,R->HL.B.h);break;
299 
300 case LD_B_L:   R->BC.B.h=R->HL.B.l;break;
301 case LD_C_L:   R->BC.B.l=R->HL.B.l;break;
302 case LD_D_L:   R->DE.B.h=R->HL.B.l;break;
303 case LD_E_L:   R->DE.B.l=R->HL.B.l;break;
304 case LD_H_L:   R->HL.B.h=R->HL.B.l;break;
305 case LD_L_L:   R->HL.B.l=R->HL.B.l;break;
306 case LD_A_L:   R->AF.B.h=R->HL.B.l;break;
307 case LD_xHL_L: WrZ80(R->HL.W,R->HL.B.l);break;
308 
309 case LD_B_A:   R->BC.B.h=R->AF.B.h;break;
310 case LD_C_A:   R->BC.B.l=R->AF.B.h;break;
311 case LD_D_A:   R->DE.B.h=R->AF.B.h;break;
312 case LD_E_A:   R->DE.B.l=R->AF.B.h;break;
313 case LD_H_A:   R->HL.B.h=R->AF.B.h;break;
314 case LD_L_A:   R->HL.B.l=R->AF.B.h;break;
315 case LD_A_A:   R->AF.B.h=R->AF.B.h;break;
316 case LD_xHL_A: WrZ80(R->HL.W,R->AF.B.h);break;
317 
318 case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
319 case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
320 
321 case LD_B_xHL:    R->BC.B.h=RdZ80(R->HL.W);break;
322 case LD_C_xHL:    R->BC.B.l=RdZ80(R->HL.W);break;
323 case LD_D_xHL:    R->DE.B.h=RdZ80(R->HL.W);break;
324 case LD_E_xHL:    R->DE.B.l=RdZ80(R->HL.W);break;
325 case LD_H_xHL:    R->HL.B.h=RdZ80(R->HL.W);break;
326 case LD_L_xHL:    R->HL.B.l=RdZ80(R->HL.W);break;
327 case LD_A_xHL:    R->AF.B.h=RdZ80(R->HL.W);break;
328 
329 case LD_B_BYTE:   R->BC.B.h=OpZ80(R->PC.W++);break;
330 case LD_C_BYTE:   R->BC.B.l=OpZ80(R->PC.W++);break;
331 case LD_D_BYTE:   R->DE.B.h=OpZ80(R->PC.W++);break;
332 case LD_E_BYTE:   R->DE.B.l=OpZ80(R->PC.W++);break;
333 case LD_H_BYTE:   R->HL.B.h=OpZ80(R->PC.W++);break;
334 case LD_L_BYTE:   R->HL.B.l=OpZ80(R->PC.W++);break;
335 case LD_A_BYTE:   R->AF.B.h=OpZ80(R->PC.W++);break;
336 case LD_xHL_BYTE: WrZ80(R->HL.W,OpZ80(R->PC.W++));break;
337 
338 case LD_xWORD_HL:
339   J.B.l=OpZ80(R->PC.W++);
340   J.B.h=OpZ80(R->PC.W++);
341   WrZ80(J.W++,R->HL.B.l);
342   WrZ80(J.W,R->HL.B.h);
343   break;
344 
345 case LD_HL_xWORD:
346   J.B.l=OpZ80(R->PC.W++);
347   J.B.h=OpZ80(R->PC.W++);
348   R->HL.B.l=RdZ80(J.W++);
349   R->HL.B.h=RdZ80(J.W);
350   break;
351 
352 case LD_A_xWORD:
353   J.B.l=OpZ80(R->PC.W++);
354   J.B.h=OpZ80(R->PC.W++);
355   R->AF.B.h=RdZ80(J.W);
356   break;
357 
358 case LD_xWORD_A:
359   J.B.l=OpZ80(R->PC.W++);
360   J.B.h=OpZ80(R->PC.W++);
361   WrZ80(J.W,R->AF.B.h);
362   break;
363 
364 case EX_HL_xSP:
365   J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->HL.B.l);
366   J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->HL.B.h);
367   R->HL.W=J.W;
368   break;
369 
370 case DAA:
371   J.W=R->AF.B.h;
372   if(R->AF.B.l&C_FLAG) J.W|=256;
373   if(R->AF.B.l&H_FLAG) J.W|=512;
374   if(R->AF.B.l&N_FLAG) J.W|=1024;
375   R->AF.W=DAATable[J.W];
376   break;
377 
378 default:
379   if(R->TrapBadOps)
380     printf
381     (
382       "[Z80 %lX] Unrecognized instruction: %02X at PC=%04X\n",
383       (long)R->User,OpZ80(R->PC.W-1),R->PC.W-1
384     );
385   break;
386