windows Pico stuff wip
[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                         }\r
716                         if (CPU->ICount <= 0)\r
717                         {\r
718                                 CPU->ICount = 1;\r
719                         }\r
720                 }\r
721                 else zIFF2 = (1 << 2);\r
722                 goto Cz80_Exec;\r
723 \r
724 /*-----------------------------------------\r
725  INC r16\r
726 -----------------------------------------*/\r
727 \r
728         OP(0x03):   // INC  BC\r
729 OP_INC_BC:\r
730                 zBC++;\r
731                 RET(6)\r
732 \r
733         OP(0x13):   // INC  DE\r
734 OP_INC_DE:\r
735                 zDE++;\r
736                 RET(6)\r
737 \r
738         OP(0x23):   // INC  HL\r
739 OP_INC_xx:\r
740                 data->W++;\r
741                 RET(6)\r
742 \r
743         OP(0x33):   // INC  SP\r
744 OP_INC_SP:\r
745                 zSP++;\r
746                 RET(6)\r
747 \r
748 /*-----------------------------------------\r
749  DEC r16\r
750 -----------------------------------------*/\r
751 \r
752         OP(0x0b):   // DEC  BC\r
753 OP_DEC_BC:\r
754                 zBC--;\r
755                 RET(6)\r
756 \r
757         OP(0x1b):   // DEC  DE\r
758 OP_DEC_DE:\r
759                 zDE--;\r
760                 RET(6)\r
761 \r
762         OP(0x2b):   // DEC  HL\r
763 OP_DEC_xx:\r
764                 data->W--;\r
765                 RET(6)\r
766 \r
767         OP(0x3b):   // DEC  SP\r
768 OP_DEC_SP:\r
769                 zSP--;\r
770                 RET(6)\r
771 \r
772 /*-----------------------------------------\r
773  ADD r16\r
774 -----------------------------------------*/\r
775 \r
776         OP(0x39):   // ADD  xx,SP\r
777 OP_ADD16_xx_SP:\r
778                 val = zSP;\r
779                 goto OP_ADD16;\r
780 \r
781         OP(0x29):   // ADD  xx,xx\r
782 OP_ADD16_xx_xx:\r
783                 val = data->W;\r
784                 goto OP_ADD16;\r
785 \r
786         OP(0x09):   // ADD  xx,BC\r
787 OP_ADD16_xx_BC:\r
788                 val = zBC;\r
789                 goto OP_ADD16;\r
790 \r
791         OP(0x19):   // ADD  xx,DE\r
792 OP_ADD16_xx_DE:\r
793                 val = zDE;\r
794 \r
795 OP_ADD16:\r
796                 res = data->W + val;\r
797                 zF = (zF & (SF | ZF | VF)) |\r
798                         (((data->W ^ res ^ val) >> 8) & HF) |\r
799                         ((res >> 16) & CF) | ((res >> 8) & (YF | XF));\r
800                 data->W = (UINT16)res;\r
801                 RET(11)\r
802 \r
803 /*-----------------------------------------\r
804  ROTATE\r
805 -----------------------------------------*/\r
806 \r
807         {\r
808                 UINT8 A;\r
809                 UINT8 F;\r
810 \r
811         OP(0x07):   // RLCA\r
812 OP_RLCA:\r
813                 A = zA;\r
814                 zA = (A << 1) | (A >> 7);\r
815                 zF = (zF & (SF | ZF | PF)) | (zA & (YF | XF | CF));\r
816                 RET(4)\r
817 \r
818         OP(0x0f):   // RRCA\r
819 OP_RRCA:\r
820                 A = zA;\r
821                 F = zF;\r
822                 F = (F & (SF | ZF | PF)) | (A & CF);\r
823                 zA = (A >> 1) | (A << 7);\r
824                 zF = F | (zA & (YF | XF));\r
825                 RET(4)\r
826 \r
827         OP(0x17):   // RLA\r
828 OP_RLA:\r
829                 A = zA;\r
830                 F = zF;\r
831                 zA = (A << 1) | (F & CF);\r
832                 zF = (F & (SF | ZF | PF)) | (A >> 7) | (zA & (YF | XF));\r
833                 RET(4)\r
834 \r
835         OP(0x1f):   // RRA\r
836 OP_RRA:\r
837                 A = zA;\r
838                 F = zF;\r
839                 zA = (A >> 1) | (F << 7);\r
840                 zF = (F & (SF | ZF | PF)) | (A & CF) | (zA & (YF | XF));\r
841                 RET(4)\r
842         }\r
843 \r
844 /*-----------------------------------------\r
845  JP\r
846 -----------------------------------------*/\r
847 \r
848         OP(0xc3):   // JP   nn\r
849 OP_JP:\r
850                 res = READ_ARG16();\r
851                 SET_PC(res);\r
852                 RET(10)\r
853 \r
854         OP(0xc2):   // JP   NZ,nn\r
855 OP_JP_NZ:\r
856                 if (!(zF & ZF)) goto OP_JP;\r
857                 PC += 2;\r
858                 RET(10)\r
859 \r
860         OP(0xca):   // JP   Z,nn\r
861 OP_JP_Z:\r
862                 if (zF & ZF) goto OP_JP;\r
863                 PC += 2;\r
864                 RET(10)\r
865 \r
866         OP(0xd2):   // JP   NC,nn\r
867 OP_JP_NC:\r
868                 if (!(zF & CF)) goto OP_JP;\r
869                 PC += 2;\r
870                 RET(10)\r
871 \r
872         OP(0xda):   // JP   C,nn\r
873 OP_JP_C:\r
874                 if (zF & CF) goto OP_JP;\r
875                 PC += 2;\r
876                 RET(10)\r
877 \r
878         OP(0xe2):   // JP   PO,nn\r
879 OP_JP_PO:\r
880                 if (!(zF & VF)) goto OP_JP;\r
881                 PC += 2;\r
882                 RET(10)\r
883 \r
884         OP(0xea):   // JP   PE,nn\r
885 OP_JP_PE:\r
886                 if (zF & VF) goto OP_JP;\r
887                 PC += 2;\r
888                 RET(10)\r
889 \r
890         OP(0xf2):   // JP   P,nn\r
891 OP_JP_P:\r
892                 if (!(zF & SF)) goto OP_JP;\r
893                 PC += 2;\r
894                 RET(10)\r
895 \r
896         OP(0xfa):   // JP   M,nn\r
897 OP_JP_M:\r
898                 if (zF & SF) goto OP_JP;\r
899                 PC += 2;\r
900                 RET(10)\r
901 \r
902         OP(0xe9):   // JP   (xx)\r
903 OP_JP_xx:\r
904                 res = data->W;\r
905                 SET_PC(res);\r
906                 RET(4)\r
907 \r
908 /*-----------------------------------------\r
909  JR\r
910 -----------------------------------------*/\r
911 \r
912         OP(0x10):   // DJNZ n\r
913 OP_DJNZ:\r
914                 USE_CYCLES(1)\r
915                 if (--zB) goto OP_JR;\r
916                 PC++;\r
917                 RET(7)\r
918 \r
919         OP(0x18):   // JR   n\r
920 OP_JR:\r
921                 adr = (INT8)READ_ARG();\r
922                 PC += adr;\r
923                 RET(12)\r
924 \r
925         OP(0x20):   // JR   NZ,n\r
926 OP_JR_NZ:\r
927                 if (!(zF & ZF)) goto OP_JR;\r
928                 PC++;\r
929                 RET(7)\r
930 \r
931         OP(0x28):   // JR   Z,n\r
932 OP_JR_Z:\r
933                 if (zF & ZF) goto OP_JR;\r
934                 PC++;\r
935                 RET(7)\r
936 \r
937         OP(0x38):   // JR   C,n\r
938 OP_JR_C:\r
939                 if (zF & CF) goto OP_JR;\r
940                 PC++;\r
941                 RET(7)\r
942 \r
943         OP(0x30):   // JR   NC,n\r
944 OP_JR_NC:\r
945                 if (!(zF & CF)) goto OP_JR;\r
946                 PC++;\r
947                 RET(7)\r
948 \r
949 /*-----------------------------------------\r
950  CALL\r
951 -----------------------------------------*/\r
952 \r
953         OP(0xcd):   // CALL nn\r
954 OP_CALL:\r
955                 res = READ_ARG16();\r
956                 val = zRealPC;\r
957                 PUSH_16(val);\r
958                 SET_PC(res);\r
959                 RET(17)\r
960 \r
961         OP(0xc4):   // CALL NZ,nn\r
962 OP_CALL_NZ:\r
963                 if (!(zF & ZF)) goto OP_CALL;\r
964                 PC += 2;\r
965                 RET(10)\r
966 \r
967         OP(0xcc):   // CALL Z,nn\r
968 OP_CALL_Z:\r
969                 if (zF & ZF) goto OP_CALL;\r
970                 PC += 2;\r
971                 RET(10)\r
972 \r
973         OP(0xd4):   // CALL NC,nn\r
974 OP_CALL_NC:\r
975                 if (!(zF & CF)) goto OP_CALL;\r
976                 PC += 2;\r
977                 RET(10)\r
978 \r
979         OP(0xdc):   // CALL C,nn\r
980 OP_CALL_C:\r
981                 if (zF & CF) goto OP_CALL;\r
982                 PC += 2;\r
983                 RET(10)\r
984 \r
985         OP(0xe4):   // CALL PO,nn\r
986 OP_CALL_PO:\r
987                 if (!(zF & VF)) goto OP_CALL;\r
988                 PC += 2;\r
989                 RET(10)\r
990 \r
991         OP(0xec):   // CALL PE,nn\r
992 OP_CALL_PE:\r
993                 if (zF & VF) goto OP_CALL;\r
994                 PC += 2;\r
995                 RET(10)\r
996 \r
997         OP(0xf4):   // CALL P,nn\r
998 OP_CALL_P:\r
999                 if (!(zF & SF)) goto OP_CALL;\r
1000                 PC += 2;\r
1001                 RET(10)\r
1002 \r
1003         OP(0xfc):   // CALL M,nn\r
1004 OP_CALL_M:\r
1005                 if (zF & SF) goto OP_CALL;\r
1006                 PC += 2;\r
1007                 RET(10)\r
1008 \r
1009 /*-----------------------------------------\r
1010  RET\r
1011 -----------------------------------------*/\r
1012 \r
1013 OP_RET_COND:\r
1014                 USE_CYCLES(1)\r
1015 \r
1016         OP(0xc9):   // RET\r
1017 OP_RET:\r
1018                 POP_16(res);\r
1019                 SET_PC(res);\r
1020                 RET(10)\r
1021 \r
1022         OP(0xc0):   // RET  NZ\r
1023 OP_RET_NZ:\r
1024                 if (!(zF & ZF)) goto OP_RET_COND;\r
1025                 RET(5)\r
1026 \r
1027         OP(0xc8):   // RET  Z\r
1028 OP_RET_Z:\r
1029                 if (zF & ZF) goto OP_RET_COND;\r
1030                 RET(5)\r
1031 \r
1032         OP(0xd0):   // RET  NC\r
1033 OP_RET_NC:\r
1034                 if (!(zF & CF)) goto OP_RET_COND;\r
1035                 RET(5)\r
1036 \r
1037         OP(0xd8):   // RET  C\r
1038 OP_RET_C:\r
1039                 if (zF & CF) goto OP_RET_COND;\r
1040                 RET(5)\r
1041 \r
1042         OP(0xe0):   // RET  PO\r
1043 OP_RET_PO:\r
1044                 if (!(zF & VF)) goto OP_RET_COND;\r
1045                 RET(5)\r
1046 \r
1047         OP(0xe8):   // RET  PE\r
1048 OP_RET_PE:\r
1049                 if (zF & VF) goto OP_RET_COND;\r
1050                 RET(5)\r
1051 \r
1052         OP(0xf0):   // RET  P\r
1053 OP_RET_P:\r
1054                 if (!(zF & SF)) goto OP_RET_COND;\r
1055                 RET(5)\r
1056 \r
1057         OP(0xf8):   // RET  M\r
1058 OP_RET_M:\r
1059                 if (zF & SF) goto OP_RET_COND;\r
1060                 RET(5)\r
1061 \r
1062 /*-----------------------------------------\r
1063  RST\r
1064 -----------------------------------------*/\r
1065 \r
1066         OP(0xc7):   // RST  0\r
1067         OP(0xcf):   // RST  1\r
1068         OP(0xd7):   // RST  2\r
1069         OP(0xdf):   // RST  3\r
1070         OP(0xe7):   // RST  4\r
1071         OP(0xef):   // RST  5\r
1072         OP(0xf7):   // RST  6\r
1073         OP(0xff):   // RST  7\r
1074 OP_RST:\r
1075                 res = zRealPC;\r
1076                 PUSH_16(res);\r
1077                 res = Opcode & 0x38;\r
1078                 SET_PC(res);\r
1079                 RET(11)\r
1080 \r
1081 /*-----------------------------------------\r
1082  OUT\r
1083 -----------------------------------------*/\r
1084 \r
1085         OP(0xd3):   // OUT  (n),A\r
1086 OP_OUT_mN_A:\r
1087                 adr = (zA << 8) | READ_ARG();\r
1088                 OUT(adr, zA);\r
1089                 RET(11)\r
1090 \r
1091 /*-----------------------------------------\r
1092  IN\r
1093 -----------------------------------------*/\r
1094 \r
1095         OP(0xdb):   // IN   A,(n)\r
1096 OP_IN_A_mN:\r
1097                 adr = (zA << 8) | READ_ARG();\r
1098                 zA = IN(adr);\r
1099                 RET(11)\r
1100 \r
1101 /*-----------------------------------------\r
1102  PREFIX\r
1103 -----------------------------------------*/\r
1104 \r
1105         OP(0xcb):   // CB prefix (BIT & SHIFT INSTRUCTIONS)\r
1106         {\r
1107                 UINT8 src;\r
1108                 UINT8 res;\r
1109 \r
1110                 Opcode = READ_OP();\r
1111 #if CZ80_EMULATE_R_EXACTLY\r
1112                 zR++;\r
1113 #endif\r
1114                 #include "cz80_opCB.c"\r
1115         }\r
1116 \r
1117         OP(0xed):   // ED prefix\r
1118 ED_PREFIX:\r
1119                 USE_CYCLES(4)\r
1120                 Opcode = READ_OP();\r
1121 #if CZ80_EMULATE_R_EXACTLY\r
1122                 zR++;\r
1123 #endif\r
1124                 #include "cz80_opED.c"\r
1125 \r
1126         OP(0xdd):   // DD prefix (IX)\r
1127 DD_PREFIX:\r
1128                 data = pzIX;\r
1129                 goto XY_PREFIX;\r
1130 \r
1131         OP(0xfd):   // FD prefix (IY)\r
1132 FD_PREFIX:\r
1133                 data = pzIY;\r
1134 \r
1135 XY_PREFIX:\r
1136                 USE_CYCLES(4)\r
1137                 Opcode = READ_OP();\r
1138 #if CZ80_EMULATE_R_EXACTLY\r
1139                 zR++;\r
1140 #endif\r
1141                 #include "cz80_opXY.c"\r
1142 \r
1143 #if !CZ80_USE_JUMPTABLE\r
1144 }\r
1145 #endif\r