new memory handling, but asm and mappers need update.
[picodrive.git] / cpu / cz80 / cz80_op.c
1 /******************************************************************************\r
2  *\r
3  * CZ80 opcode include source file\r
4  * CZ80 emulator version 0.9\r
5  * Copyright 2004-2005 Stéphane Dallongeville\r
6  *\r
7  * (Modified by NJ)\r
8  *\r
9  *****************************************************************************/\r
10 \r
11 #if CZ80_USE_JUMPTABLE\r
12         goto *JumpTable[Opcode];\r
13 #else\r
14 switch (Opcode)\r
15 {\r
16 #endif\r
17 \r
18 /*-----------------------------------------\r
19  NOP\r
20 -----------------------------------------*/\r
21 \r
22         OP(0x00):   // NOP\r
23 \r
24 /*-----------------------------------------\r
25  LD r8 (same register)\r
26 -----------------------------------------*/\r
27 \r
28         OP(0x40):   // LD   B,B\r
29         OP(0x49):   // LD   C,C\r
30         OP(0x52):   // LD   D,D\r
31         OP(0x5b):   // LD   E,E\r
32         OP(0x64):   // LD   H,H\r
33         OP(0x6d):   // LD   L,L\r
34         OP(0x7f):   // LD   A,A\r
35                 RET(4)\r
36 \r
37 /*-----------------------------------------\r
38  LD r8\r
39 -----------------------------------------*/\r
40 \r
41         OP(0x41):   // LD   B,C\r
42         OP(0x42):   // LD   B,D\r
43         OP(0x43):   // LD   B,E\r
44         OP(0x44):   // LD   B,H\r
45         OP(0x45):   // LD   B,L\r
46         OP(0x47):   // LD   B,A\r
47 \r
48         OP(0x48):   // LD   C,B\r
49         OP(0x4a):   // LD   C,D\r
50         OP(0x4b):   // LD   C,E\r
51         OP(0x4c):   // LD   C,H\r
52         OP(0x4d):   // LD   C,L\r
53         OP(0x4f):   // LD   C,A\r
54 \r
55         OP(0x50):   // LD   D,B\r
56         OP(0x51):   // LD   D,C\r
57         OP(0x53):   // LD   D,E\r
58         OP(0x54):   // LD   D,H\r
59         OP(0x55):   // LD   D,L\r
60         OP(0x57):   // LD   D,A\r
61 \r
62         OP(0x58):   // LD   E,B\r
63         OP(0x59):   // LD   E,C\r
64         OP(0x5a):   // LD   E,D\r
65         OP(0x5c):   // LD   E,H\r
66         OP(0x5d):   // LD   E,L\r
67         OP(0x5f):   // LD   E,A\r
68 \r
69         OP(0x60):   // LD   H,B\r
70         OP(0x61):   // LD   H,C\r
71         OP(0x62):   // LD   H,D\r
72         OP(0x63):   // LD   H,E\r
73         OP(0x65):   // LD   H,L\r
74         OP(0x67):   // LD   H,A\r
75 \r
76         OP(0x68):   // LD   L,B\r
77         OP(0x69):   // LD   L,C\r
78         OP(0x6a):   // LD   L,D\r
79         OP(0x6b):   // LD   L,E\r
80         OP(0x6c):   // LD   L,H\r
81         OP(0x6f):   // LD   L,A\r
82 \r
83         OP(0x78):   // LD   A,B\r
84         OP(0x79):   // LD   A,C\r
85         OP(0x7a):   // LD   A,D\r
86         OP(0x7b):   // LD   A,E\r
87         OP(0x7c):   // LD   A,H\r
88         OP(0x7d):   // LD   A,L\r
89 OP_LD_R_R:\r
90                 zR8((Opcode >> 3) & 7) = zR8(Opcode & 7);\r
91                 RET(4)\r
92 \r
93         OP(0x06):   // LD   B,#imm\r
94         OP(0x0e):   // LD   C,#imm\r
95         OP(0x16):   // LD   D,#imm\r
96         OP(0x1e):   // LD   E,#imm\r
97         OP(0x26):   // LD   H,#imm\r
98         OP(0x2e):   // LD   L,#imm\r
99         OP(0x3e):   // LD   A,#imm\r
100 OP_LD_R_imm:\r
101                 zR8(Opcode >> 3) = READ_ARG();\r
102                 RET(7)\r
103 \r
104         OP(0x46):   // LD   B,(HL)\r
105         OP(0x4e):   // LD   C,(HL)\r
106         OP(0x56):   // LD   D,(HL)\r
107         OP(0x5e):   // LD   E,(HL)\r
108         OP(0x66):   // LD   H,(HL)\r
109         OP(0x6e):   // LD   L,(HL)\r
110         OP(0x7e):   // LD   A,(HL)\r
111                 zR8((Opcode >> 3) & 7) = READ_MEM8(zHL);\r
112                 RET(7)\r
113 \r
114         OP(0x70):   // LD   (HL),B\r
115         OP(0x71):   // LD   (HL),C\r
116         OP(0x72):   // LD   (HL),D\r
117         OP(0x73):   // LD   (HL),E\r
118         OP(0x74):   // LD   (HL),H\r
119         OP(0x75):   // LD   (HL),L\r
120         OP(0x77):   // LD   (HL),A\r
121                 WRITE_MEM8(zHL, zR8(Opcode & 7));\r
122                 RET(7)\r
123 \r
124         OP(0x36):   // LD (HL), #imm\r
125                 WRITE_MEM8(zHL, READ_ARG());\r
126                 RET(10)\r
127 \r
128         OP(0x0a):   // LD   A,(BC)\r
129 OP_LOAD_A_mBC:\r
130                 adr = zBC;\r
131                 goto OP_LOAD_A_mxx;\r
132 \r
133         OP(0x1a):   // LD   A,(DE)\r
134 OP_LOAD_A_mDE:\r
135                 adr = zDE;\r
136 \r
137 OP_LOAD_A_mxx:\r
138                 zA = READ_MEM8(adr);\r
139                 RET(7)\r
140 \r
141         OP(0x3a):   // LD   A,(nn)\r
142 OP_LOAD_A_mNN:\r
143                 adr = READ_ARG16();\r
144                 zA = READ_MEM8(adr);\r
145                 RET(13)\r
146 \r
147         OP(0x02):   // LD   (BC),A\r
148 OP_LOAD_mBC_A:\r
149                 adr = zBC;\r
150                 goto OP_LOAD_mxx_A;\r
151 \r
152         OP(0x12):   // LD   (DE),A\r
153 OP_LOAD_mDE_A:\r
154                 adr = zDE;\r
155 \r
156 OP_LOAD_mxx_A:\r
157                 WRITE_MEM8(adr, zA);\r
158                 RET(7)\r
159 \r
160         OP(0x32):   // LD   (nn),A\r
161 OP_LOAD_mNN_A:\r
162                 adr = READ_ARG16();\r
163                 WRITE_MEM8(adr, zA);\r
164                 RET(13)\r
165 \r
166 /*-----------------------------------------\r
167  LD r16\r
168 -----------------------------------------*/\r
169 \r
170         OP(0x01):   // LD   BC,nn\r
171         OP(0x11):   // LD   DE,nn\r
172         OP(0x21):   // LD   HL,nn\r
173 OP_LOAD_RR_imm16:\r
174                 zR16(Opcode >> 4) = READ_ARG16();\r
175                 RET(10)\r
176 \r
177         OP(0x31):   // LD   SP,nn\r
178 OP_LOAD_SP_imm16:\r
179                 zSP = READ_ARG16();\r
180                 RET(10)\r
181 \r
182         OP(0xf9):   // LD   SP,HL\r
183 OP_LD_SP_xx:\r
184                 zSP = data->W;\r
185                 RET(6)\r
186 \r
187         OP(0x2a):   // LD   HL,(nn)\r
188 OP_LD_xx_mNN:\r
189                 adr = READ_ARG16();\r
190                 data->W = READ_MEM16(adr);\r
191                 RET(16)\r
192 \r
193         OP(0x22):   // LD   (nn),HL\r
194 OP_LD_mNN_xx:\r
195                 adr = READ_ARG16();\r
196                 WRITE_MEM16(adr, data->W);\r
197                 RET(16)\r
198 \r
199 /*-----------------------------------------\r
200  POP\r
201 -----------------------------------------*/\r
202 \r
203         OP(0xc1):   // POP  BC\r
204         OP(0xd1):   // POP  DE\r
205         OP(0xf1):   // POP  AF\r
206 OP_POP_RR:\r
207                 data = CPU->pzR16[(Opcode >> 4) & 3];\r
208 \r
209         OP(0xe1):   // POP  HL\r
210 OP_POP:\r
211                 POP_16(data->W)\r
212                 RET(10)\r
213 \r
214 /*-----------------------------------------\r
215  PUSH\r
216 -----------------------------------------*/\r
217 \r
218         OP(0xc5):   // PUSH BC\r
219         OP(0xd5):   // PUSH DE\r
220         OP(0xf5):   // PUSH AF\r
221 OP_PUSH_RR:\r
222                 data = CPU->pzR16[(Opcode >> 4) & 3];\r
223 \r
224         OP(0xe5):   // PUSH HL\r
225 OP_PUSH:\r
226                 PUSH_16(data->W);\r
227                 RET(11)\r
228 \r
229 /*-----------------------------------------\r
230  EX\r
231 -----------------------------------------*/\r
232 \r
233         OP(0x08):   // EX   AF,AF'\r
234 OP_EX_AF_AF2:\r
235                 res = zAF;\r
236                 zAF = zAF2;\r
237                 zAF2 = res;\r
238                 RET(4)\r
239 \r
240         OP(0xeb):   // EX   DE,HL\r
241 OP_EX_DE_HL:\r
242                 res = zDE;\r
243                 zDE = zHL;\r
244                 zHL = res;\r
245                 RET(4)\r
246 \r
247         OP(0xd9):   // EXX\r
248 OP_EXX:\r
249                 res = zBC;\r
250                 zBC = zBC2;\r
251                 zBC2 = res;\r
252                 res = zDE;\r
253                 zDE = zDE2;\r
254                 zDE2 = res;\r
255                 res = zHL;\r
256                 zHL = zHL2;\r
257                 zHL2 = res;\r
258                 RET(4)\r
259 \r
260         OP(0xe3):   // EX   HL,(SP)\r
261 OP_EX_xx_mSP:\r
262                 adr = zSP;\r
263                 res = data->W;\r
264                 data->W = READ_MEM16(adr);\r
265                 WRITE_MEM16(adr, res);\r
266                 RET(19)\r
267 \r
268 /*-----------------------------------------\r
269  INC r8\r
270 -----------------------------------------*/\r
271 \r
272         OP(0x04):   // INC  B\r
273         OP(0x0c):   // INC  C\r
274         OP(0x14):   // INC  D\r
275         OP(0x1c):   // INC  E\r
276         OP(0x24):   // INC  H\r
277         OP(0x2c):   // INC  L\r
278         OP(0x3c):   // INC  A\r
279 OP_INC_R:\r
280                 zR8(Opcode >> 3)++;\r
281                 zF = (zF & CF) | SZHV_inc[zR8(Opcode >> 3)];\r
282                 RET(4)\r
283 \r
284         OP(0x34):   // INC  (HL)\r
285                 adr = zHL;\r
286 \r
287 OP_INC_m:\r
288                 res = READ_MEM8(adr);\r
289                 res = (res + 1) & 0xff;\r
290                 zF = (zF & CF) | SZHV_inc[res];\r
291                 WRITE_MEM8(adr, res);\r
292                 RET(11)\r
293 \r
294 /*-----------------------------------------\r
295  DEC r8\r
296 -----------------------------------------*/\r
297 \r
298         OP(0x05):   // DEC  B\r
299         OP(0x0d):   // DEC  C\r
300         OP(0x15):   // DEC  D\r
301         OP(0x1d):   // DEC  E\r
302         OP(0x25):   // DEC  H\r
303         OP(0x2d):   // DEC  L\r
304         OP(0x3d):   // DEC  A\r
305 OP_DEC_R:\r
306                 zR8(Opcode >> 3)--;\r
307                 zF = (zF & CF) | SZHV_dec[zR8(Opcode >> 3)];\r
308                 RET(4)\r
309 \r
310         OP(0x35):   // DEC  (HL)\r
311                 adr = zHL;\r
312 \r
313 OP_DEC_m:\r
314                 res = READ_MEM8(adr);\r
315                 res = (res - 1) & 0xff;\r
316                 zF = (zF & CF) | SZHV_dec[res];\r
317                 WRITE_MEM8(adr, res);\r
318                 RET(11)\r
319 \r
320 /*-----------------------------------------\r
321  ADD r8\r
322 -----------------------------------------*/\r
323 \r
324         OP(0x86):   // ADD  A,(HL)\r
325                 val = READ_MEM8(zHL);\r
326                 USE_CYCLES(3)\r
327                 goto OP_ADD;\r
328 \r
329         OP(0xc6):   // ADD  A,n\r
330 OP_ADD_imm:\r
331                 val = READ_ARG();\r
332                 USE_CYCLES(3)\r
333                 goto OP_ADD;\r
334 \r
335         OP(0x80):   // ADD  A,B\r
336         OP(0x81):   // ADD  A,C\r
337         OP(0x82):   // ADD  A,D\r
338         OP(0x83):   // ADD  A,E\r
339         OP(0x84):   // ADD  A,H\r
340         OP(0x85):   // ADD  A,L\r
341         OP(0x87):   // ADD  A,A\r
342 OP_ADD_R:\r
343                 val = zR8(Opcode & 7);\r
344 \r
345 OP_ADD:\r
346 #if CZ80_BIG_FLAGS_ARRAY\r
347                 {\r
348                         UINT16 A = zA;\r
349                         res = (UINT8)(A + val);\r
350                         zF = SZHVC_add[(A << 8) | res];\r
351                         zA = res;\r
352                 }\r
353 #else\r
354                 res = zA + val;\r
355                 zF = SZ[(UINT8)res] | ((res >> 8) & CF) |\r
356                         ((zA ^ res ^ val) & HF) |\r
357                         (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5);\r
358                 zA = res;\r
359 #endif\r
360                 RET(4)\r
361 \r
362 /*-----------------------------------------\r
363  ADC r8\r
364 -----------------------------------------*/\r
365 \r
366         OP(0x8e):   // ADC  A,(HL)\r
367                 val = READ_MEM8(zHL);\r
368                 USE_CYCLES(3)\r
369                 goto OP_ADC;\r
370 \r
371         OP(0xce):   // ADC  A,n\r
372 OP_ADC_imm:\r
373                 val = READ_ARG();\r
374                 USE_CYCLES(3)\r
375                 goto OP_ADC;\r
376 \r
377         OP(0x88):   // ADC  A,B\r
378         OP(0x89):   // ADC  A,C\r
379         OP(0x8a):   // ADC  A,D\r
380         OP(0x8b):   // ADC  A,E\r
381         OP(0x8c):   // ADC  A,H\r
382         OP(0x8d):   // ADC  A,L\r
383         OP(0x8f):   // ADC  A,A\r
384 OP_ADC_R:\r
385                 val = zR8(Opcode & 7);\r
386 \r
387 OP_ADC:\r
388 #if CZ80_BIG_FLAGS_ARRAY\r
389                 {\r
390                         UINT8 A = zA;\r
391                         UINT8 c = zF & CF;\r
392                         res = (UINT8)(A + val + c);\r
393                         zF = SZHVC_add[(c << 16) | (A << 8) | res];\r
394                         zA = res;\r
395                 }\r
396 #else\r
397                 res = zA + val + (zF & CF);\r
398                 zF = SZ[res & 0xff] | ((res >> 8) & CF) |\r
399                         ((zA ^ res ^ val) & HF) |\r
400                         (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5);\r
401                 zA = res;\r
402 #endif\r
403                 RET(4)\r
404 \r
405 /*-----------------------------------------\r
406  SUB r8\r
407 -----------------------------------------*/\r
408 \r
409         OP(0x96):   // SUB  (HL)\r
410                 val = READ_MEM8(zHL);\r
411                 USE_CYCLES(3)\r
412                 goto OP_SUB;\r
413 \r
414         OP(0xd6):   // SUB  A,n\r
415 OP_SUB_imm:\r
416                 val = READ_ARG();\r
417                 USE_CYCLES(3)\r
418                 goto OP_SUB;\r
419 \r
420         OP(0x90):   // SUB  B\r
421         OP(0x91):   // SUB  C\r
422         OP(0x92):   // SUB  D\r
423         OP(0x93):   // SUB  E\r
424         OP(0x94):   // SUB  H\r
425         OP(0x95):   // SUB  L\r
426         OP(0x97):   // SUB  A\r
427 OP_SUB_R:\r
428                 val = zR8(Opcode & 7);\r
429 \r
430 OP_SUB:\r
431 #if CZ80_BIG_FLAGS_ARRAY\r
432                 {\r
433                         UINT8 A = zA;\r
434                         res = (UINT8)(A - val);\r
435                         zF = SZHVC_sub[(A << 8) | res];\r
436                         zA = res;\r
437                 }\r
438 #else\r
439                 res = zA - val;\r
440                 zF = SZ[res & 0xff] | ((res >> 8) & CF) | NF |\r
441                         ((zA ^ res ^ val) & HF) |\r
442                         (((val ^ zA) & (zA ^ res) & 0x80) >> 5);\r
443                 zA = res;\r
444 #endif\r
445                 RET(4)\r
446 \r
447 /*-----------------------------------------\r
448  SBC r8\r
449 -----------------------------------------*/\r
450 \r
451         OP(0x9e):   // SBC  A,(HL)\r
452                 val = READ_MEM8(zHL);\r
453                 USE_CYCLES(3)\r
454                 goto OP_SBC;\r
455 \r
456         OP(0xde):   // SBC  A,n\r
457 OP_SBC_imm:\r
458                 val = READ_ARG();\r
459                 USE_CYCLES(3)\r
460                 goto OP_SBC;\r
461 \r
462         OP(0x98):   // SBC  A,B\r
463         OP(0x99):   // SBC  A,C\r
464         OP(0x9a):   // SBC  A,D\r
465         OP(0x9b):   // SBC  A,E\r
466         OP(0x9c):   // SBC  A,H\r
467         OP(0x9d):   // SBC  A,L\r
468         OP(0x9f):   // SBC  A,A\r
469 OP_SBC_R:\r
470                 val = zR8(Opcode & 7);\r
471 \r
472 OP_SBC:\r
473 #if CZ80_BIG_FLAGS_ARRAY\r
474                 {\r
475                         UINT8 A = zA;\r
476                         UINT8 c = zF & CF;\r
477                         res = (UINT8)(A - val - c);\r
478                         zF = SZHVC_sub[(c << 16) | (A << 8) | res];\r
479                         zA = res;\r
480                 }\r
481 #else\r
482                 res = zA - val - (zF & CF);\r
483                 zF = SZ[res & 0xff] | ((res >> 8) & CF) | NF |\r
484                         ((zA ^ res ^ val) & HF) |\r
485                         (((val ^ zA) & (zA ^ res) & 0x80) >> 5);\r
486                 zA = res;\r
487 #endif\r
488                 RET(4)\r
489 \r
490 /*-----------------------------------------\r
491  CP r8\r
492 -----------------------------------------*/\r
493 \r
494         OP(0xbe):   // CP   (HL)\r
495                 val = READ_MEM8(zHL);\r
496                 USE_CYCLES(3)\r
497                 goto OP_CP;\r
498 \r
499         OP(0xfe):   // CP   n\r
500 OP_CP_imm:\r
501                 val = READ_ARG();\r
502                 USE_CYCLES(3)\r
503                 goto OP_CP;\r
504 \r
505         OP(0xb8):   // CP   B\r
506         OP(0xb9):   // CP   C\r
507         OP(0xba):   // CP   D\r
508         OP(0xbb):   // CP   E\r
509         OP(0xbc):   // CP   H\r
510         OP(0xbd):   // CP   L\r
511         OP(0xbf):   // CP   A\r
512 OP_CP_R:\r
513                 val = zR8(Opcode & 7);\r
514 \r
515 OP_CP:\r
516 #if CZ80_BIG_FLAGS_ARRAY\r
517                 {\r
518                         UINT8 A = zA;\r
519                         res = (UINT8)(A - val);\r
520                         zF = (SZHVC_sub[(A << 8) | res] & ~(YF | XF)) |\r
521                                  (val & (YF | XF));\r
522                 }\r
523 #else\r
524                 res = zA - val;\r
525                 zF = (SZ[res & 0xff] & (SF | ZF)) |\r
526                         (val & (YF | XF)) | ((res >> 8) & CF) | NF |\r
527                         ((zA ^ res ^ val) & HF) |\r
528                         (((val ^ zA) & (zA ^ res) >> 5) & VF);\r
529 #endif\r
530                 RET(4)\r
531 \r
532 /*-----------------------------------------\r
533  AND r8\r
534 -----------------------------------------*/\r
535 \r
536         OP(0xa6):   // AND  (HL)\r
537                 val = READ_MEM8(zHL);\r
538                 USE_CYCLES(3)\r
539                 goto OP_AND;\r
540 \r
541         OP(0xe6):   // AND  A,n\r
542 OP_AND_imm:\r
543                 val = READ_ARG();\r
544                 USE_CYCLES(3)\r
545                 goto OP_AND;\r
546 \r
547         OP(0xa0):   // AND  B\r
548         OP(0xa1):   // AND  C\r
549         OP(0xa2):   // AND  D\r
550         OP(0xa3):   // AND  E\r
551         OP(0xa4):   // AND  H\r
552         OP(0xa5):   // AND  L\r
553         OP(0xa7):   // AND  A\r
554 OP_AND_R:\r
555                 val = zR8(Opcode & 7);\r
556 \r
557 OP_AND:\r
558                 zA &= val;\r
559                 zF = SZP[zA] | HF;\r
560                 RET(4)\r
561 \r
562 /*-----------------------------------------\r
563  XOR r8\r
564 -----------------------------------------*/\r
565 \r
566         OP(0xae):   // XOR  (HL)\r
567                 val = READ_MEM8(zHL);\r
568                 USE_CYCLES(3)\r
569                 goto OP_XOR;\r
570 \r
571         OP(0xee):   // XOR  A,n\r
572 OP_XOR_imm:\r
573                 val = READ_ARG();\r
574                 USE_CYCLES(3)\r
575                 goto OP_XOR;\r
576 \r
577         OP(0xa8):   // XOR  B\r
578         OP(0xa9):   // XOR  C\r
579         OP(0xaa):   // XOR  D\r
580         OP(0xab):   // XOR  E\r
581         OP(0xac):   // XOR  H\r
582         OP(0xad):   // XOR  L\r
583         OP(0xaf):   // XOR  A\r
584 OP_XOR_R:\r
585                 val = zR8(Opcode & 7);\r
586 \r
587 OP_XOR:\r
588                 zA ^= val;\r
589                 zF = SZP[zA];\r
590                 RET(4)\r
591 \r
592 /*-----------------------------------------\r
593  OR r8\r
594 -----------------------------------------*/\r
595 \r
596         OP(0xb6):   // OR   (HL)\r
597                 val = READ_MEM8(zHL);\r
598                 USE_CYCLES(3)\r
599                 goto OP_OR;\r
600 \r
601         OP(0xf6):   // OR   A,n\r
602 OP_OR_imm:\r
603                 val = READ_ARG();\r
604                 USE_CYCLES(3)\r
605                 goto OP_OR;\r
606 \r
607         OP(0xb0):   // OR   B\r
608         OP(0xb1):   // OR   C\r
609         OP(0xb2):   // OR   D\r
610         OP(0xb3):   // OR   E\r
611         OP(0xb4):   // OR   H\r
612         OP(0xb5):   // OR   L\r
613         OP(0xb7):   // OR   A\r
614 OP_OR_R:\r
615                 val = zR8(Opcode & 7);\r
616 \r
617 OP_OR:\r
618                 zA |= val;\r
619                 zF = SZP[zA];\r
620                 RET(4)\r
621 \r
622 /*-----------------------------------------\r
623  MISC ARITHMETIC & CPU CONTROL\r
624 -----------------------------------------*/\r
625 \r
626         OP(0x27):   // DAA\r
627 OP_DAA:\r
628         {\r
629                 UINT8 F;\r
630                 UINT8 cf, nf, hf, lo, hi, diff;\r
631 \r
632                 F = zF;\r
633                 cf = F & CF;\r
634                 nf = F & NF;\r
635                 hf = F & HF;\r
636                 lo = zA & 0x0f;\r
637                 hi = zA >> 4;\r
638 \r
639                 if (cf)\r
640                 {\r
641                         diff = (lo <= 9 && !hf) ? 0x60 : 0x66;\r
642                 }\r
643                 else\r
644                 {\r
645                         if (lo >= 10)\r
646                         {\r
647                                 diff = hi <= 8 ? 0x06 : 0x66;\r
648                         }\r
649                         else\r
650                         {\r
651                                 if (hi >= 10)\r
652                                 {\r
653                                         diff = hf ? 0x66 : 0x60;\r
654                                 }\r
655                                 else\r
656                                 {\r
657                                         diff = hf ? 0x06 : 0x00;\r
658                                 }\r
659                         }\r
660                 }\r
661                 if (nf) zA -= diff;\r
662                 else zA += diff;\r
663 \r
664                 F = SZP[zA] | (F & NF);\r
665                 if (cf || (lo <= 9 ? hi >= 10 : hi >= 9)) F |= CF;\r
666                 if (nf ? hf && lo <= 5 : lo >= 10) F |= HF;\r
667                 zF = F;\r
668                 RET(4)\r
669         }\r
670 \r
671         OP(0x2f):   // CPL\r
672 OP_CPL:\r
673                 zA ^= 0xff;\r
674                 zF = (zF & (SF | ZF | PF | CF)) | HF | NF | (zA & (YF | XF));\r
675                 RET(4)\r
676 \r
677         OP(0x37):   // SCF\r
678 OP_SCF:\r
679                 zF = (zF & (SF | ZF | PF)) | CF | (zA & (YF | XF));\r
680                 RET(4)\r
681 \r
682         OP(0x3f):   // CCF\r
683 OP_CCF:\r
684                 zF = ((zF & (SF | ZF | PF | CF)) | ((zF & CF) << 4) | (zA & (YF | XF))) ^ CF;\r
685                 RET(4)\r
686 \r
687         OP(0x76):   // HALT\r
688 OP_HALT:\r
689                 CPU->HaltState = 1;\r
690                 CPU->ICount = 0;\r
691                 goto Cz80_Check_Interrupt;\r
692 \r
693         OP(0xf3):   // DI\r
694 OP_DI:\r
695                 zIFF = 0;\r
696                 RET(4)\r
697 \r
698         OP(0xfb):   // EI\r
699 OP_EI:\r
700                 USE_CYCLES(4)\r
701                 if (!zIFF1)\r
702                 {\r
703                         zIFF1 = zIFF2 = (1 << 2);\r
704                         while (GET_OP() == 0xfb)\r
705                         {\r
706                                 USE_CYCLES(4)\r
707                                 PC++;\r
708 #if CZ80_EMULATE_R_EXACTLY\r
709                                 zR++;\r
710 #endif\r
711                         }\r
712                         if (CPU->IRQState)\r
713                         {\r
714                                 afterEI = 1;\r
715                                 CPU->ExtraCycles += 1 - CPU->ICount;\r
716                                 CPU->ICount = 1;\r
717                         }\r
718                 }\r
719                 else zIFF2 = (1 << 2);\r
720                 goto Cz80_Exec_nocheck;\r
721 \r
722 /*-----------------------------------------\r
723  INC r16\r
724 -----------------------------------------*/\r
725 \r
726         OP(0x03):   // INC  BC\r
727 OP_INC_BC:\r
728                 zBC++;\r
729                 RET(6)\r
730 \r
731         OP(0x13):   // INC  DE\r
732 OP_INC_DE:\r
733                 zDE++;\r
734                 RET(6)\r
735 \r
736         OP(0x23):   // INC  HL\r
737 OP_INC_xx:\r
738                 data->W++;\r
739                 RET(6)\r
740 \r
741         OP(0x33):   // INC  SP\r
742 OP_INC_SP:\r
743                 zSP++;\r
744                 RET(6)\r
745 \r
746 /*-----------------------------------------\r
747  DEC r16\r
748 -----------------------------------------*/\r
749 \r
750         OP(0x0b):   // DEC  BC\r
751 OP_DEC_BC:\r
752                 zBC--;\r
753                 RET(6)\r
754 \r
755         OP(0x1b):   // DEC  DE\r
756 OP_DEC_DE:\r
757                 zDE--;\r
758                 RET(6)\r
759 \r
760         OP(0x2b):   // DEC  HL\r
761 OP_DEC_xx:\r
762                 data->W--;\r
763                 RET(6)\r
764 \r
765         OP(0x3b):   // DEC  SP\r
766 OP_DEC_SP:\r
767                 zSP--;\r
768                 RET(6)\r
769 \r
770 /*-----------------------------------------\r
771  ADD r16\r
772 -----------------------------------------*/\r
773 \r
774         OP(0x39):   // ADD  xx,SP\r
775 OP_ADD16_xx_SP:\r
776                 val = zSP;\r
777                 goto OP_ADD16;\r
778 \r
779         OP(0x29):   // ADD  xx,xx\r
780 OP_ADD16_xx_xx:\r
781                 val = data->W;\r
782                 goto OP_ADD16;\r
783 \r
784         OP(0x09):   // ADD  xx,BC\r
785 OP_ADD16_xx_BC:\r
786                 val = zBC;\r
787                 goto OP_ADD16;\r
788 \r
789         OP(0x19):   // ADD  xx,DE\r
790 OP_ADD16_xx_DE:\r
791                 val = zDE;\r
792 \r
793 OP_ADD16:\r
794                 res = data->W + val;\r
795                 zF = (zF & (SF | ZF | VF)) |\r
796                         (((data->W ^ res ^ val) >> 8) & HF) |\r
797                         ((res >> 16) & CF) | ((res >> 8) & (YF | XF));\r
798                 data->W = (UINT16)res;\r
799                 RET(11)\r
800 \r
801 /*-----------------------------------------\r
802  ROTATE\r
803 -----------------------------------------*/\r
804 \r
805         {\r
806                 UINT8 A;\r
807                 UINT8 F;\r
808 \r
809         OP(0x07):   // RLCA\r
810 OP_RLCA:\r
811                 A = zA;\r
812                 zA = (A << 1) | (A >> 7);\r
813                 zF = (zF & (SF | ZF | PF)) | (zA & (YF | XF | CF));\r
814                 RET(4)\r
815 \r
816         OP(0x0f):   // RRCA\r
817 OP_RRCA:\r
818                 A = zA;\r
819                 F = zF;\r
820                 F = (F & (SF | ZF | PF)) | (A & CF);\r
821                 zA = (A >> 1) | (A << 7);\r
822                 zF = F | (zA & (YF | XF));\r
823                 RET(4)\r
824 \r
825         OP(0x17):   // RLA\r
826 OP_RLA:\r
827                 A = zA;\r
828                 F = zF;\r
829                 zA = (A << 1) | (F & CF);\r
830                 zF = (F & (SF | ZF | PF)) | (A >> 7) | (zA & (YF | XF));\r
831                 RET(4)\r
832 \r
833         OP(0x1f):   // RRA\r
834 OP_RRA:\r
835                 A = zA;\r
836                 F = zF;\r
837                 zA = (A >> 1) | (F << 7);\r
838                 zF = (F & (SF | ZF | PF)) | (A & CF) | (zA & (YF | XF));\r
839                 RET(4)\r
840         }\r
841 \r
842 /*-----------------------------------------\r
843  JP\r
844 -----------------------------------------*/\r
845 \r
846         OP(0xc3):   // JP   nn\r
847 OP_JP:\r
848                 res = READ_ARG16();\r
849                 SET_PC(res);\r
850                 RET(10)\r
851 \r
852         OP(0xc2):   // JP   NZ,nn\r
853 OP_JP_NZ:\r
854                 if (!(zF & ZF)) goto OP_JP;\r
855                 PC += 2;\r
856                 RET(10)\r
857 \r
858         OP(0xca):   // JP   Z,nn\r
859 OP_JP_Z:\r
860                 if (zF & ZF) goto OP_JP;\r
861                 PC += 2;\r
862                 RET(10)\r
863 \r
864         OP(0xd2):   // JP   NC,nn\r
865 OP_JP_NC:\r
866                 if (!(zF & CF)) goto OP_JP;\r
867                 PC += 2;\r
868                 RET(10)\r
869 \r
870         OP(0xda):   // JP   C,nn\r
871 OP_JP_C:\r
872                 if (zF & CF) goto OP_JP;\r
873                 PC += 2;\r
874                 RET(10)\r
875 \r
876         OP(0xe2):   // JP   PO,nn\r
877 OP_JP_PO:\r
878                 if (!(zF & VF)) goto OP_JP;\r
879                 PC += 2;\r
880                 RET(10)\r
881 \r
882         OP(0xea):   // JP   PE,nn\r
883 OP_JP_PE:\r
884                 if (zF & VF) goto OP_JP;\r
885                 PC += 2;\r
886                 RET(10)\r
887 \r
888         OP(0xf2):   // JP   P,nn\r
889 OP_JP_P:\r
890                 if (!(zF & SF)) goto OP_JP;\r
891                 PC += 2;\r
892                 RET(10)\r
893 \r
894         OP(0xfa):   // JP   M,nn\r
895 OP_JP_M:\r
896                 if (zF & SF) goto OP_JP;\r
897                 PC += 2;\r
898                 RET(10)\r
899 \r
900         OP(0xe9):   // JP   (xx)\r
901 OP_JP_xx:\r
902                 res = data->W;\r
903                 SET_PC(res);\r
904                 RET(4)\r
905 \r
906 /*-----------------------------------------\r
907  JR\r
908 -----------------------------------------*/\r
909 \r
910         OP(0x10):   // DJNZ n\r
911 OP_DJNZ:\r
912                 USE_CYCLES(1)\r
913                 if (--zB) goto OP_JR;\r
914                 PC++;\r
915                 RET(7)\r
916 \r
917         OP(0x18):   // JR   n\r
918 OP_JR:\r
919                 adr = (INT8)READ_ARG();\r
920                 PC += adr;\r
921                 RET(12)\r
922 \r
923         OP(0x20):   // JR   NZ,n\r
924 OP_JR_NZ:\r
925                 if (!(zF & ZF)) goto OP_JR;\r
926                 PC++;\r
927                 RET(7)\r
928 \r
929         OP(0x28):   // JR   Z,n\r
930 OP_JR_Z:\r
931                 if (zF & ZF) goto OP_JR;\r
932                 PC++;\r
933                 RET(7)\r
934 \r
935         OP(0x38):   // JR   C,n\r
936 OP_JR_C:\r
937                 if (zF & CF) goto OP_JR;\r
938                 PC++;\r
939                 RET(7)\r
940 \r
941         OP(0x30):   // JR   NC,n\r
942 OP_JR_NC:\r
943                 if (!(zF & CF)) goto OP_JR;\r
944                 PC++;\r
945                 RET(7)\r
946 \r
947 /*-----------------------------------------\r
948  CALL\r
949 -----------------------------------------*/\r
950 \r
951         OP(0xcd):   // CALL nn\r
952 OP_CALL:\r
953                 res = READ_ARG16();\r
954                 val = zRealPC;\r
955                 PUSH_16(val);\r
956                 SET_PC(res);\r
957                 RET(17)\r
958 \r
959         OP(0xc4):   // CALL NZ,nn\r
960 OP_CALL_NZ:\r
961                 if (!(zF & ZF)) goto OP_CALL;\r
962                 PC += 2;\r
963                 RET(10)\r
964 \r
965         OP(0xcc):   // CALL Z,nn\r
966 OP_CALL_Z:\r
967                 if (zF & ZF) goto OP_CALL;\r
968                 PC += 2;\r
969                 RET(10)\r
970 \r
971         OP(0xd4):   // CALL NC,nn\r
972 OP_CALL_NC:\r
973                 if (!(zF & CF)) goto OP_CALL;\r
974                 PC += 2;\r
975                 RET(10)\r
976 \r
977         OP(0xdc):   // CALL C,nn\r
978 OP_CALL_C:\r
979                 if (zF & CF) goto OP_CALL;\r
980                 PC += 2;\r
981                 RET(10)\r
982 \r
983         OP(0xe4):   // CALL PO,nn\r
984 OP_CALL_PO:\r
985                 if (!(zF & VF)) goto OP_CALL;\r
986                 PC += 2;\r
987                 RET(10)\r
988 \r
989         OP(0xec):   // CALL PE,nn\r
990 OP_CALL_PE:\r
991                 if (zF & VF) goto OP_CALL;\r
992                 PC += 2;\r
993                 RET(10)\r
994 \r
995         OP(0xf4):   // CALL P,nn\r
996 OP_CALL_P:\r
997                 if (!(zF & SF)) goto OP_CALL;\r
998                 PC += 2;\r
999                 RET(10)\r
1000 \r
1001         OP(0xfc):   // CALL M,nn\r
1002 OP_CALL_M:\r
1003                 if (zF & SF) goto OP_CALL;\r
1004                 PC += 2;\r
1005                 RET(10)\r
1006 \r
1007 /*-----------------------------------------\r
1008  RET\r
1009 -----------------------------------------*/\r
1010 \r
1011 OP_RET_COND:\r
1012                 USE_CYCLES(1)\r
1013 \r
1014         OP(0xc9):   // RET\r
1015 OP_RET:\r
1016                 POP_16(res);\r
1017                 SET_PC(res);\r
1018                 RET(10)\r
1019 \r
1020         OP(0xc0):   // RET  NZ\r
1021 OP_RET_NZ:\r
1022                 if (!(zF & ZF)) goto OP_RET_COND;\r
1023                 RET(5)\r
1024 \r
1025         OP(0xc8):   // RET  Z\r
1026 OP_RET_Z:\r
1027                 if (zF & ZF) goto OP_RET_COND;\r
1028                 RET(5)\r
1029 \r
1030         OP(0xd0):   // RET  NC\r
1031 OP_RET_NC:\r
1032                 if (!(zF & CF)) goto OP_RET_COND;\r
1033                 RET(5)\r
1034 \r
1035         OP(0xd8):   // RET  C\r
1036 OP_RET_C:\r
1037                 if (zF & CF) goto OP_RET_COND;\r
1038                 RET(5)\r
1039 \r
1040         OP(0xe0):   // RET  PO\r
1041 OP_RET_PO:\r
1042                 if (!(zF & VF)) goto OP_RET_COND;\r
1043                 RET(5)\r
1044 \r
1045         OP(0xe8):   // RET  PE\r
1046 OP_RET_PE:\r
1047                 if (zF & VF) goto OP_RET_COND;\r
1048                 RET(5)\r
1049 \r
1050         OP(0xf0):   // RET  P\r
1051 OP_RET_P:\r
1052                 if (!(zF & SF)) goto OP_RET_COND;\r
1053                 RET(5)\r
1054 \r
1055         OP(0xf8):   // RET  M\r
1056 OP_RET_M:\r
1057                 if (zF & SF) goto OP_RET_COND;\r
1058                 RET(5)\r
1059 \r
1060 /*-----------------------------------------\r
1061  RST\r
1062 -----------------------------------------*/\r
1063 \r
1064         OP(0xc7):   // RST  0\r
1065         OP(0xcf):   // RST  1\r
1066         OP(0xd7):   // RST  2\r
1067         OP(0xdf):   // RST  3\r
1068         OP(0xe7):   // RST  4\r
1069         OP(0xef):   // RST  5\r
1070         OP(0xf7):   // RST  6\r
1071         OP(0xff):   // RST  7\r
1072 OP_RST:\r
1073                 res = zRealPC;\r
1074                 PUSH_16(res);\r
1075                 res = Opcode & 0x38;\r
1076                 SET_PC(res);\r
1077                 RET(11)\r
1078 \r
1079 /*-----------------------------------------\r
1080  OUT\r
1081 -----------------------------------------*/\r
1082 \r
1083         OP(0xd3):   // OUT  (n),A\r
1084 OP_OUT_mN_A:\r
1085                 adr = (zA << 8) | READ_ARG();\r
1086                 OUT(adr, zA);\r
1087                 RET(11)\r
1088 \r
1089 /*-----------------------------------------\r
1090  IN\r
1091 -----------------------------------------*/\r
1092 \r
1093         OP(0xdb):   // IN   A,(n)\r
1094 OP_IN_A_mN:\r
1095                 adr = (zA << 8) | READ_ARG();\r
1096                 zA = IN(adr);\r
1097                 RET(11)\r
1098 \r
1099 /*-----------------------------------------\r
1100  PREFIX\r
1101 -----------------------------------------*/\r
1102 \r
1103         OP(0xcb):   // CB prefix (BIT & SHIFT INSTRUCTIONS)\r
1104         {\r
1105                 UINT8 src;\r
1106                 UINT8 res;\r
1107 \r
1108                 Opcode = READ_OP();\r
1109 #if CZ80_EMULATE_R_EXACTLY\r
1110                 zR++;\r
1111 #endif\r
1112                 #include "cz80_opCB.c"\r
1113         }\r
1114 \r
1115         OP(0xed):   // ED prefix\r
1116 ED_PREFIX:\r
1117                 USE_CYCLES(4)\r
1118                 Opcode = READ_OP();\r
1119 #if CZ80_EMULATE_R_EXACTLY\r
1120                 zR++;\r
1121 #endif\r
1122                 #include "cz80_opED.c"\r
1123 \r
1124         OP(0xdd):   // DD prefix (IX)\r
1125 DD_PREFIX:\r
1126                 data = pzIX;\r
1127                 goto XY_PREFIX;\r
1128 \r
1129         OP(0xfd):   // FD prefix (IY)\r
1130 FD_PREFIX:\r
1131                 data = pzIY;\r
1132 \r
1133 XY_PREFIX:\r
1134                 USE_CYCLES(4)\r
1135                 Opcode = READ_OP();\r
1136 #if CZ80_EMULATE_R_EXACTLY\r
1137                 zR++;\r
1138 #endif\r
1139                 #include "cz80_opXY.c"\r
1140 \r
1141 #if !CZ80_USE_JUMPTABLE\r
1142 }\r
1143 #endif\r