1 //---------------------------------------------------------------------------
2 // NEOPOP : Emulator as in Dreamland
3 //
4 // Copyright (c) 2001-2002 by neopop_uk
5 //---------------------------------------------------------------------------
6
7 //---------------------------------------------------------------------------
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version. See also the license.txt file for
12 // additional informations.
13 //---------------------------------------------------------------------------
14
15 /*
16 //---------------------------------------------------------------------------
17 //=========================================================================
18
19 TLCS900h_interpret_src.c
20
21 //=========================================================================
22 //---------------------------------------------------------------------------
23
24 History of changes:
25 ===================
26
27 20 JUL 2002 - neopop_uk
28 =======================================
29 - Cleaned and tidied up for the source release
30
31 24 JUL 2002 - neopop_uk
32 =======================================
33 - Fixed S flag in "RRC (mem)"
34
35 25 JUL 2002 - neopop_uk
36 =======================================
37 - Removed unneeded Long mode from EX.
38
39 28 JUL 2002 - neopop_uk
40 =======================================
41 - Improved the LDIR/LDDR/CPIR/CPDR instructions so that they
42 finish with the correct register settings, even if there is
43 a memory error.
44 - Converted DIV/DIVS to use the generic function
45
46 16 AUG 2002 - neopop_uk
47 =======================================
48 - Replaced 'second & 7' with 'R', clearer, faster - and for some reason
49 more accurate... oh well!
50 - Fixed V flag emulation of INC/DEC, fixes "Cotton" menus
51
52 21 AUG 2002 - neopop_uk
53 =======================================
54 - Fixed "RR (mem)" - It was actually the [REG] version that hadn't been
55 changed to use memory accesses!
56
57 30 AUG 2002 - neopop_uk
58 =======================================
59 - Fixed "DIV RR,(mem)" in long mode, wrong operand size.
60
61 04 SEP 2002 - neopop_uk
62 =======================================
63 - Fixed GCC compatibility.
64
65 //---------------------------------------------------------------------------
66 */
67
68 #include "TLCS900h_interpret.h"
69 #include "TLCS900h_registers.h"
70 #include "../mem.h"
71
72 //=========================================================================
73
74 //===== PUSH (mem)
srcPUSH(void)75 void srcPUSH(void)
76 {
77 switch(size)
78 {
79 case 0:
80 push8(loadB(mem));
81 break;
82 case 1:
83 push16(loadW(mem));
84 break;
85 }
86 cycles = 7;
87 }
88
89 //===== RLD A,(mem)
srcRLD(void)90 void srcRLD(void)
91 {
92 uint8 al = REGA & 0xF, m, mh, ml;
93
94 m = loadB(mem);
95 mh = (m & 0xF0) >> 4;
96 ml = (m & 0x0F) << 4;
97
98 REGA = (REGA & 0xF0) | mh;
99 storeB(mem, ml | al);
100
101 SETFLAG_S(REGA & 0x80);
102 SETFLAG_Z(REGA == 0);
103 SETFLAG_H0
104 SETFLAG_N0
105 parityB(REGA);
106
107 cycles = 12;
108 }
109
110 //===== RRD A,(mem)
srcRRD(void)111 void srcRRD(void)
112 {
113 uint8 al = (REGA & 0xF) << 4, m, mh, ml;
114
115 m = loadB(mem);
116 mh = (m & 0xF0) >> 4;
117 ml = m & 0x0F;
118
119 REGA = (REGA & 0xF0) | ml;
120 storeB(mem, al | mh);
121
122 SETFLAG_S(REGA & 0x80);
123 SETFLAG_Z(REGA == 0);
124 SETFLAG_H0
125 SETFLAG_N0
126 parityB(REGA);
127
128 cycles = 12;
129 }
130
131 //===== LDI
srcLDI(void)132 void srcLDI(void)
133 {
134 uint8 dst = 2/*XDE*/, src = 3/*XHL*/;
135 if ((first & 0xF) == 5)
136 {
137 dst = 4/*XIX*/;
138 src = 5/*XIY*/;
139 }
140
141 switch(size)
142 {
143 case 0:
144 storeB(regL(dst), loadB(regL(src)));
145 regL(dst) += 1;
146 regL(src) += 1;
147 break;
148
149 case 1:
150 storeW(regL(dst), loadW(regL(src)));
151 regL(dst) += 2;
152 regL(src) += 2;
153 break;
154 }
155
156 REGBC --;
157 SETFLAG_V(REGBC);
158
159 SETFLAG_H0;
160 SETFLAG_N0;
161 cycles = 10;
162 }
163
164 //===== LDIR
srcLDIR(void)165 void srcLDIR(void)
166 {
167 uint8 dst = 2/*XDE*/, src = 3/*XHL*/;
168 if ((first & 0xF) == 5)
169 {
170 dst = 4/*XIX*/;
171 src = 5/*XIY*/;
172 }
173
174 cycles = 10;
175
176 do
177 {
178 switch(size)
179 {
180 case 0:
181 if (debug_abort_memory == false)
182 storeB(regL(dst), loadB(regL(src)));
183 regL(dst) += 1;
184 regL(src) += 1;
185 break;
186 case 1:
187 if (debug_abort_memory == false)
188 storeW(regL(dst), loadW(regL(src)));
189 regL(dst) += 2;
190 regL(src) += 2;
191 break;
192 }
193
194 REGBC --;
195 SETFLAG_V(REGBC);
196
197 cycles += 14;
198 }
199 while (FLAG_V);
200
201 SETFLAG_H0;
202 SETFLAG_N0;
203 }
204
205 //===== LDD
srcLDD(void)206 void srcLDD(void)
207 {
208 uint8 dst = 2/*XDE*/, src = 3/*XHL*/;
209 if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; }
210
211 switch(size)
212 {
213 case 0:
214 storeB(regL(dst), loadB(regL(src)));
215 regL(dst) -= 1;
216 regL(src) -= 1;
217 break;
218
219 case 1:
220 storeW(regL(dst), loadW(regL(src)));
221 regL(dst) -= 2;
222 regL(src) -= 2;
223 break;
224 }
225
226 REGBC --;
227 SETFLAG_V(REGBC);
228
229 SETFLAG_H0;
230 SETFLAG_N0;
231 cycles = 10;
232 }
233
234 //===== LDDR
srcLDDR(void)235 void srcLDDR(void)
236 {
237 uint8 dst = 2/*XDE*/, src = 3/*XHL*/;
238 if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; }
239
240 cycles = 10;
241
242 do
243 {
244 switch(size)
245 {
246 case 0:
247 if (debug_abort_memory == false)
248 storeB(regL(dst), loadB(regL(src)));
249 regL(dst) -= 1;
250 regL(src) -= 1;
251 break;
252
253 case 1:
254 if (debug_abort_memory == false)
255 storeW(regL(dst), loadW(regL(src)));
256 regL(dst) -= 2;
257 regL(src) -= 2;
258 break;
259 }
260
261 REGBC --;
262 SETFLAG_V(REGBC);
263
264 cycles += 14;
265 }
266 while (FLAG_V);
267
268 SETFLAG_H0;
269 SETFLAG_N0;
270 }
271
272 //===== CPI
srcCPI(void)273 void srcCPI(void)
274 {
275 uint8 R = first & 7;
276
277 switch(size)
278 {
279 case 0: generic_SUB_B(REGA, loadB(regL(R)));
280 regL(R) ++; break;
281
282 case 1: generic_SUB_W(REGWA, loadW(regL(R)));
283 regL(R) += 2; break;
284 }
285
286 REGBC --;
287 SETFLAG_V(REGBC);
288
289 cycles = 8;
290 }
291
292 //===== CPIR
srcCPIR(void)293 void srcCPIR(void)
294 {
295 uint8 R = first & 7;
296
297 cycles = 10;
298
299 do
300 {
301 switch(size)
302 {
303 case 0: if (debug_abort_memory == false)
304 generic_SUB_B(REGA, loadB(regL(R)));
305 regL(R) ++; break;
306
307 case 1: if (debug_abort_memory == false)
308 generic_SUB_W(REGWA, loadW(regL(R)));
309 regL(R) += 2; break;
310 }
311
312 REGBC --;
313 SETFLAG_V(REGBC);
314
315 cycles += 14;
316 }
317 while (FLAG_V && (FLAG_Z == false));
318 }
319
320 //===== CPD
srcCPD(void)321 void srcCPD(void)
322 {
323 uint8 R = first & 7;
324
325 switch(size)
326 {
327 case 0: generic_SUB_B(REGA, loadB(regL(R)));
328 regL(R) --; break;
329
330 case 1: generic_SUB_W(REGWA, loadW(regL(R)));
331 regL(R) -= 2; break;
332 }
333
334 REGBC --;
335 SETFLAG_V(REGBC);
336
337 cycles = 8;
338 }
339
340 //===== CPDR
srcCPDR(void)341 void srcCPDR(void)
342 {
343 uint8 R = first & 7;
344
345 cycles = 10;
346
347 do
348 {
349 switch(size)
350 {
351 case 0: if (debug_abort_memory == false)
352 generic_SUB_B(REGA, loadB(regL(R)));
353 regL(R) -= 1; break;
354
355 case 1: if (debug_abort_memory == false)
356 generic_SUB_W(REGWA, loadW(regL(R)));
357 regL(R) -= 2; break;
358 }
359
360 REGBC --;
361 SETFLAG_V(REGBC);
362
363 cycles += 14;
364 }
365 while (FLAG_V && (FLAG_Z == false));
366 }
367
368 //===== LD (nn),(mem)
srcLD16m(void)369 void srcLD16m(void)
370 {
371 switch(size)
372 {
373 case 0: storeB(fetch16(), loadB(mem)); break;
374 case 1: storeW(fetch16(), loadW(mem)); break;
375 }
376
377 cycles = 8;
378 }
379
380 //===== LD R,(mem)
srcLD(void)381 void srcLD(void)
382 {
383 switch(size)
384 {
385 case 0: regB(R) = loadB(mem); cycles = 4; break;
386 case 1: regW(R) = loadW(mem); cycles = 4; break;
387 case 2: regL(R) = loadL(mem); cycles = 6; break;
388 }
389 }
390
391 //===== EX (mem),R
srcEX(void)392 void srcEX(void)
393 {
394 switch(size)
395 {
396 case 0: { uint8 temp = regB(R);
397 regB(R) = loadB(mem);
398 storeB(mem, temp); break; }
399
400 case 1: { uint16 temp = regW(R);
401 regW(R) = loadW(mem);
402 storeW(mem, temp); break; }
403 }
404
405 cycles = 6;
406 }
407
408 //===== ADD (mem),#
srcADDi(void)409 void srcADDi(void)
410 {
411 switch(size)
412 {
413 case 0: storeB(mem, generic_ADD_B(loadB(mem), FETCH8)); cycles = 7;break;
414 case 1: storeW(mem, generic_ADD_W(loadW(mem), fetch16())); cycles = 8;break;
415 }
416 }
417
418 //===== ADC (mem),#
srcADCi(void)419 void srcADCi(void)
420 {
421 switch(size)
422 {
423 case 0: storeB(mem, generic_ADC_B(loadB(mem), FETCH8)); cycles = 7;break;
424 case 1: storeW(mem, generic_ADC_W(loadW(mem), fetch16())); cycles = 8;break;
425 }
426 }
427
428 //===== SUB (mem),#
srcSUBi(void)429 void srcSUBi(void)
430 {
431 switch(size)
432 {
433 case 0: storeB(mem, generic_SUB_B(loadB(mem), FETCH8)); cycles = 7;break;
434 case 1: storeW(mem, generic_SUB_W(loadW(mem), fetch16())); cycles = 8;break;
435 }
436 }
437
438 //===== SBC (mem),#
srcSBCi(void)439 void srcSBCi(void)
440 {
441 switch(size)
442 {
443 case 0: storeB(mem, generic_SBC_B(loadB(mem), FETCH8)); cycles = 7;break;
444 case 1: storeW(mem, generic_SBC_W(loadW(mem), fetch16())); cycles = 8;break;
445 }
446 }
447
448 //===== AND (mem),#
srcANDi(void)449 void srcANDi(void)
450 {
451 switch(size)
452 {
453 case 0: { uint8 result = loadB(mem) & FETCH8;
454 storeB(mem, result);
455 SETFLAG_S(result & 0x80);
456 SETFLAG_Z(result == 0);
457 parityB(result);
458 cycles = 7;
459 break; }
460
461 case 1: { uint16 result = loadW(mem) & fetch16();
462 storeW(mem, result);
463 SETFLAG_S(result & 0x8000);
464 SETFLAG_Z(result == 0);
465 parityW(result);
466 cycles = 8;
467 break; }
468 }
469
470 SETFLAG_H1;
471 SETFLAG_N0;
472 SETFLAG_C0;
473 }
474
475 //===== OR (mem),#
srcORi(void)476 void srcORi(void)
477 {
478 switch(size)
479 {
480 case 0: { uint8 result = loadB(mem) | FETCH8;
481 storeB(mem, result);
482 SETFLAG_S(result & 0x80);
483 SETFLAG_Z(result == 0);
484 parityB(result);
485 cycles = 7;
486 break; }
487
488 case 1: { uint16 result = loadW(mem) | fetch16();
489 storeW(mem, result);
490 SETFLAG_S(result & 0x8000);
491 SETFLAG_Z(result == 0);
492 parityW(result);
493 cycles = 8;
494 break; }
495 }
496
497 SETFLAG_H0;
498 SETFLAG_N0;
499 SETFLAG_C0;
500 }
501
502 //===== XOR (mem),#
srcXORi(void)503 void srcXORi(void)
504 {
505 switch(size)
506 {
507 case 0: { uint8 result = loadB(mem) ^ FETCH8;
508 storeB(mem, result);
509 SETFLAG_S(result & 0x80);
510 SETFLAG_Z(result == 0);
511 parityB(result);
512 cycles = 7;
513 break; }
514
515 case 1: { uint16 result = loadW(mem) ^ fetch16();
516 storeW(mem, result);
517 SETFLAG_S(result & 0x8000);
518 SETFLAG_Z(result == 0);
519 parityW(result);
520 cycles = 8;
521 break; }
522 }
523
524 SETFLAG_H0;
525 SETFLAG_N0;
526 SETFLAG_C0;
527 }
528
529 //===== CP (mem),#
srcCPi(void)530 void srcCPi(void)
531 {
532 switch(size)
533 {
534 case 0: generic_SUB_B(loadB(mem), FETCH8); break;
535 case 1: generic_SUB_W(loadW(mem), fetch16()); break;
536 }
537
538 cycles = 6;
539 }
540
541 //===== MUL RR,(mem)
srcMUL(void)542 void srcMUL(void)
543 {
544 uint8 target = get_RR_Target();
545 if (target == 0x80)
546 {
547 #ifdef TLCS_ERRORS
548 instruction_error("src: MUL bad \'RR\' dst code");
549 #endif
550 return;
551 }
552
553 switch(size)
554 {
555 case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * loadB(mem);
556 cycles = 18; break;
557 case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * loadW(mem);
558 cycles = 26; break;
559 }
560 }
561
562 //===== MULS RR,(mem)
srcMULS(void)563 void srcMULS(void)
564 {
565 uint8 target = get_RR_Target();
566 if (target == 0x80)
567 {
568 #ifdef TLCS_ERRORS
569 instruction_error("src: MUL bad \'RR\' dst code");
570 #endif
571 return;
572 }
573
574 switch(size)
575 {
576 case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)loadB(mem);
577 cycles = 18; break;
578 case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)loadW(mem);
579 cycles = 26; break;
580 }
581 }
582
583 //===== DIV RR,(mem)
srcDIV(void)584 void srcDIV(void)
585 {
586 uint8 target = get_RR_Target();
587 if (target == 0x80)
588 {
589 #ifdef TLCS_ERRORS
590 instruction_error("src: DIV bad \'RR\' dst code");
591 #endif
592 return;
593 }
594
595 switch(size)
596 {
597 case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), loadB(mem));
598 cycles = 22;
599 break; }
600
601 case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), loadW(mem));
602 cycles = 30;
603 break; }
604 }
605 }
606
607 //===== DIVS RR,(mem)
srcDIVS(void)608 void srcDIVS(void)
609 {
610 uint8 target = get_RR_Target();
611 if (target == 0x80)
612 {
613 #ifdef TLCS_ERRORS
614 instruction_error("src: DIVS bad \'RR\' dst code");
615 #endif
616 return;
617 }
618
619 switch(size)
620 {
621 case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), loadB(mem));
622 cycles = 24;
623 break; }
624
625 case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), loadW(mem));
626 cycles = 32;
627 break; }
628 }
629 }
630
631 //===== INC #3,(mem)
srcINC(void)632 void srcINC(void)
633 {
634 uint8 val = R;
635 if (val == 0)
636 val = 8;
637
638 switch(size)
639 {
640 case 0: { uint8 dst = loadB(mem);
641 uint32 resultC = dst + val;
642 uint8 half = (dst & 0xF) + val;
643 uint8 result = (uint8)(resultC & 0xFF);
644 SETFLAG_Z(result == 0);
645 SETFLAG_H(half > 0xF);
646 SETFLAG_S(result & 0x80);
647 SETFLAG_N0;
648
649 if (((int8)dst >= 0) && ((int8)result < 0))
650 {SETFLAG_V1} else {SETFLAG_V0}
651
652 storeB(mem, result);
653 break; }
654
655 case 1: { uint16 dst = loadW(mem);
656 uint32 resultC = dst + val;
657 uint8 half = (dst & 0xF) + val;
658 uint16 result = (uint16)(resultC & 0xFFFF);
659 SETFLAG_Z(result == 0);
660 SETFLAG_H(half > 0xF);
661 SETFLAG_S(result & 0x8000);
662 SETFLAG_N0;
663
664 if (((int16)dst >= 0) && ((int16)result < 0))
665 {SETFLAG_V1} else {SETFLAG_V0}
666
667 storeW(mem, result);
668 break; }
669 }
670
671 cycles = 6;
672 }
673
674 //===== DEC #3,(mem)
srcDEC(void)675 void srcDEC(void)
676 {
677 uint8 val = R;
678 if (val == 0)
679 val = 8;
680
681 switch(size)
682 {
683 case 0: { uint8 dst = loadB(mem);
684 uint32 resultC = dst - val;
685 uint8 half = (dst & 0xF) - val;
686 uint8 result = (uint8)(resultC & 0xFF);
687 SETFLAG_Z(result == 0);
688 SETFLAG_H(half > 0xF);
689 SETFLAG_S(result & 0x80);
690 SETFLAG_N1;
691
692 if (((int8)dst < 0) && ((int8)result >= 0))
693 {SETFLAG_V1} else {SETFLAG_V0}
694
695 storeB(mem, result);
696 break; }
697
698 case 1: { uint16 dst = loadW(mem);
699 uint32 resultC = dst - val;
700 uint8 half = (dst & 0xF) - val;
701 uint16 result = (uint16)(resultC & 0xFFFF);
702 SETFLAG_Z(result == 0);
703 SETFLAG_H(half > 0xF);
704 SETFLAG_S(result & 0x8000);
705 SETFLAG_N1;
706
707 if (((int16)dst < 0) && ((int16)result >= 0))
708 {SETFLAG_V1} else {SETFLAG_V0}
709
710 storeW(mem, result);
711 break; }
712 }
713
714 cycles = 6;
715 }
716
717 //===== RLC (mem)
srcRLC(void)718 void srcRLC(void)
719 {
720 switch(size)
721 {
722 case 0: { uint8 result = loadB(mem);
723 SETFLAG_C(result & 0x80);
724 result <<= 1;
725 if (FLAG_C) result |= 1;
726 storeB(mem, result);
727 SETFLAG_S(result & 0x80);
728 SETFLAG_Z(result == 0);
729 parityB(result);
730 break; }
731
732 case 1: { uint16 result = loadW(mem);
733 SETFLAG_C(result & 0x8000);
734 result <<= 1;
735 if (FLAG_C) result |= 1;
736 storeW(mem, result);
737 SETFLAG_S(result & 0x8000);
738 SETFLAG_Z(result == 0);
739 parityW(result);
740 break; }
741 }
742
743 SETFLAG_H0;
744 SETFLAG_N0;
745
746 cycles = 8;
747 }
748
749 //===== RRC (mem)
srcRRC(void)750 void srcRRC(void)
751 {
752 switch(size)
753 {
754 case 0: { uint8 data = loadB(mem), result;
755 SETFLAG_C(data & 1);
756 result = data >> 1;
757 if (FLAG_C) result |= 0x80;
758 storeB(mem, result);
759 SETFLAG_S(result & 0x80);
760 SETFLAG_Z(result == 0);
761 parityB(result);
762 break; }
763
764 case 1: { uint16 data = loadW(mem), result;
765 SETFLAG_C(data & 1);
766 result = data >> 1;
767 if (FLAG_C) result |= 0x8000;
768 storeW(mem, result);
769 SETFLAG_S(result & 0x8000);
770 SETFLAG_Z(result == 0);
771 parityW(result);
772 break; }
773 }
774
775 SETFLAG_H0;
776 SETFLAG_N0;
777
778 cycles = 8;
779 }
780
781 //===== RL (mem)
srcRL(void)782 void srcRL(void)
783 {
784 bool tempC;
785
786 switch(size)
787 {
788 case 0: { uint8 result = loadB(mem);
789 tempC = FLAG_C;
790 SETFLAG_C(result & 0x80);
791 result <<= 1;
792 if (tempC) result |= 1;
793 storeB(mem, result);
794 SETFLAG_S(result & 0x80);
795 SETFLAG_Z(result == 0);
796 parityB(result);
797 break; }
798
799 case 1: { uint16 result = loadW(mem);
800 tempC = FLAG_C;
801 SETFLAG_C(result & 0x8000);
802 result <<= 1;
803 if (tempC) result |= 1;
804 storeW(mem, result);
805 SETFLAG_S(result & 0x8000);
806 SETFLAG_Z(result == 0);
807 parityW(result);
808 break; }
809 }
810
811 cycles = 8;
812 }
813
814 //===== RR (mem)
srcRR(void)815 void srcRR(void)
816 {
817 bool tempC;
818
819 switch(size)
820 {
821 case 0: { uint8 result = loadB(mem);
822 tempC = FLAG_C;
823 SETFLAG_C(result & 1);
824 result >>= 1;
825 if (tempC) result |= 0x80;
826 storeB(mem, result);
827 SETFLAG_S(result & 0x80);
828 SETFLAG_Z(result == 0);
829 parityB(result);
830 break; }
831
832 case 1: { uint16 result = loadW(mem);
833 tempC = FLAG_C;
834 SETFLAG_C(result & 1);
835 result >>= 1;
836 if (tempC) result |= 0x8000;
837 storeW(mem, result);
838 SETFLAG_S(result & 0x8000);
839 SETFLAG_Z(result == 0);
840 parityW(result);
841 break; }
842 }
843
844 cycles = 8;
845 }
846
847 //===== SLA (mem)
srcSLA(void)848 void srcSLA(void)
849 {
850 switch(size)
851 {
852 case 0: { uint8 result, data = loadB(mem);
853 SETFLAG_C(data & 0x80);
854 result = ((int8)data << 1);
855 SETFLAG_S(result & 0x80);
856 storeB(mem, result);
857 SETFLAG_Z(result == 0);
858 parityB(result);
859 break; }
860
861 case 1: { uint16 result, data = loadW(mem);
862 SETFLAG_C(data & 0x8000);
863 result = ((int16)data << 1);
864 SETFLAG_S(result & 0x8000);
865 storeW(mem, result);
866 SETFLAG_Z(result == 0);
867 parityW(result);
868 break; }
869 }
870
871 SETFLAG_H0;
872 SETFLAG_N0;
873
874 cycles = 8;
875 }
876
877 //===== SRA (mem)
srcSRA(void)878 void srcSRA(void)
879 {
880 switch(size)
881 {
882 case 0: { uint8 result, data = loadB(mem);
883 SETFLAG_C(data & 0x1);
884 result = ((int8)data >> 1);
885 SETFLAG_S(result & 0x80);
886 storeB(mem, result);
887 SETFLAG_Z(result == 0);
888 parityB(result);
889 break; }
890
891 case 1: { uint16 result, data = loadW(mem);
892 SETFLAG_C(data & 0x1);
893 result = ((int16)data >> 1);
894 SETFLAG_S(result & 0x8000);
895 storeW(mem, result);
896 SETFLAG_Z(result == 0);
897 parityW(result);
898 break; }
899 }
900
901 SETFLAG_H0;
902 SETFLAG_N0;
903
904 cycles = 8;
905 }
906
907 //===== SLL (mem)
srcSLL(void)908 void srcSLL(void)
909 {
910 switch(size)
911 {
912 case 0: { uint8 result, data = loadB(mem);
913 SETFLAG_C(data & 0x80);
914 result = (data << 1);
915 SETFLAG_S(result & 0x80);
916 storeB(mem, result);
917 SETFLAG_Z(result == 0);
918 parityB(result);
919 break; }
920
921 case 1: { uint16 result, data = loadW(mem);
922 SETFLAG_C(data & 0x8000);
923 result = (data << 1);
924 SETFLAG_S(result & 0x8000);
925 storeW(mem, result);
926 SETFLAG_Z(result == 0);
927 parityW(result);
928 break; }
929 }
930
931 SETFLAG_H0;
932 SETFLAG_N0;
933
934 cycles = 8;
935 }
936
937 //===== SRL (mem)
srcSRL(void)938 void srcSRL(void)
939 {
940 switch(size)
941 {
942 case 0: { uint8 result, data = loadB(mem);
943 SETFLAG_C(data & 0x01);
944 result = (data >> 1);
945 SETFLAG_S(result & 0x80);
946 storeB(mem, result);
947 SETFLAG_Z(result == 0);
948 parityB(result);
949 break; }
950
951 case 1: { uint16 result, data = loadW(mem);
952 SETFLAG_C(data & 0x0001);
953 result = (data >> 1);
954 SETFLAG_S(result & 0x8000);
955 storeW(mem, result);
956 SETFLAG_Z(result == 0);
957 parityW(result);
958 break; }
959 }
960
961 SETFLAG_H0;
962 SETFLAG_N0;
963
964 cycles = 8;
965 }
966
967 //===== ADD R,(mem)
srcADDRm(void)968 void srcADDRm(void)
969 {
970 switch(size)
971 {
972 case 0: regB(R) = generic_ADD_B(regB(R), loadB(mem)); cycles = 4;break;
973 case 1: regW(R) = generic_ADD_W(regW(R), loadW(mem)); cycles = 4;break;
974 case 2: regL(R) = generic_ADD_L(regL(R), loadL(mem)); cycles = 6;break;
975 }
976 }
977
978 //===== ADD (mem),R
srcADDmR(void)979 void srcADDmR(void)
980 {
981 switch(size)
982 {
983 case 0: storeB(mem, generic_ADD_B(loadB(mem), regB(R))); cycles = 6;break;
984 case 1: storeW(mem, generic_ADD_W(loadW(mem), regW(R))); cycles = 6;break;
985 case 2: storeL(mem, generic_ADD_L(loadL(mem), regL(R))); cycles = 10;break;
986 }
987 }
988
989 //===== ADC R,(mem)
srcADCRm(void)990 void srcADCRm(void)
991 {
992 switch(size)
993 {
994 case 0: regB(R) = generic_ADC_B(regB(R), loadB(mem)); cycles = 4;break;
995 case 1: regW(R) = generic_ADC_W(regW(R), loadW(mem)); cycles = 4;break;
996 case 2: regL(R) = generic_ADC_L(regL(R), loadL(mem)); cycles = 6;break;
997 }
998 }
999
1000 //===== ADC (mem),R
srcADCmR(void)1001 void srcADCmR(void)
1002 {
1003 switch(size)
1004 {
1005 case 0: storeB(mem, generic_ADC_B(loadB(mem), regB(R))); cycles = 6;break;
1006 case 1: storeW(mem, generic_ADC_W(loadW(mem), regW(R))); cycles = 6;break;
1007 case 2: storeL(mem, generic_ADC_L(loadL(mem), regL(R))); cycles = 10;break;
1008 }
1009 }
1010
1011 //===== SUB R,(mem)
srcSUBRm(void)1012 void srcSUBRm(void)
1013 {
1014 switch(size)
1015 {
1016 case 0: regB(R) = generic_SUB_B(regB(R), loadB(mem)); cycles = 4;break;
1017 case 1: regW(R) = generic_SUB_W(regW(R), loadW(mem)); cycles = 4;break;
1018 case 2: regL(R) = generic_SUB_L(regL(R), loadL(mem)); cycles = 6;break;
1019 }
1020 }
1021
1022 //===== SUB (mem),R
srcSUBmR(void)1023 void srcSUBmR(void)
1024 {
1025 switch(size)
1026 {
1027 case 0: storeB(mem, generic_SUB_B(loadB(mem), regB(R))); cycles = 6;break;
1028 case 1: storeW(mem, generic_SUB_W(loadW(mem), regW(R))); cycles = 6;break;
1029 case 2: storeL(mem, generic_SUB_L(loadL(mem), regL(R))); cycles = 10;break;
1030 }
1031 }
1032
1033 //===== SBC R,(mem)
srcSBCRm(void)1034 void srcSBCRm(void)
1035 {
1036 switch(size)
1037 {
1038 case 0: regB(R) = generic_SBC_B(regB(R), loadB(mem)); cycles = 4;break;
1039 case 1: regW(R) = generic_SBC_W(regW(R), loadW(mem)); cycles = 4;break;
1040 case 2: regL(R) = generic_SBC_L(regL(R), loadL(mem)); cycles = 6;break;
1041 }
1042 }
1043
1044 //===== SBC (mem),R
srcSBCmR(void)1045 void srcSBCmR(void)
1046 {
1047 switch(size)
1048 {
1049 case 0: storeB(mem, generic_SBC_B(loadB(mem), regB(R))); cycles = 6;break;
1050 case 1: storeW(mem, generic_SBC_W(loadW(mem), regW(R))); cycles = 6;break;
1051 case 2: storeL(mem, generic_SBC_L(loadL(mem), regL(R))); cycles = 10;break;
1052 }
1053 }
1054
1055 //===== AND R,(mem)
srcANDRm(void)1056 void srcANDRm(void)
1057 {
1058 switch(size)
1059 {
1060 case 0: { uint8 result = regB(R) & loadB(mem);
1061 regB(R) = result;
1062 SETFLAG_Z(result == 0);
1063 SETFLAG_S(result & 0x80);
1064 parityB(result);
1065 cycles = 4;
1066 break; }
1067
1068 case 1: { uint16 result = regW(R) & loadW(mem);
1069 regW(R) = result;
1070 SETFLAG_Z(result == 0);
1071 SETFLAG_S(result & 0x8000);
1072 parityW(result);
1073 cycles = 4;
1074 break; }
1075
1076 case 2: { uint32 result = regL(R) & loadL(mem);
1077 regL(R) = result;
1078 SETFLAG_Z(result == 0);
1079 SETFLAG_S(result & 0x80000000);
1080 cycles = 6;
1081 break; }
1082 }
1083
1084 SETFLAG_H1;
1085 SETFLAG_N0;
1086 SETFLAG_C0;
1087 }
1088
1089 //===== AND (mem),R
srcANDmR(void)1090 void srcANDmR(void)
1091 {
1092 switch(size)
1093 {
1094 case 0: { uint8 result = regB(R) & loadB(mem);
1095 storeB(mem, result);
1096 SETFLAG_Z(result == 0);
1097 SETFLAG_S(result & 0x80);
1098 parityB(result);
1099 cycles = 6;
1100 break; }
1101
1102 case 1: { uint16 result = regW(R) & loadW(mem);
1103 storeW(mem, result);
1104 SETFLAG_Z(result == 0);
1105 SETFLAG_S(result & 0x8000);
1106 parityW(result);
1107 cycles = 6;
1108 break; }
1109
1110 case 2: { uint32 result = regL(R) & loadL(mem);
1111 storeL(mem, result);
1112 SETFLAG_Z(result == 0);
1113 SETFLAG_S(result & 0x80000000);
1114 cycles = 10;
1115 break; }
1116 }
1117
1118 SETFLAG_H1;
1119 SETFLAG_N0;
1120 SETFLAG_C0;
1121 }
1122
1123 //===== XOR R,(mem)
srcXORRm(void)1124 void srcXORRm(void)
1125 {
1126 switch(size)
1127 {
1128 case 0: { uint8 result = regB(R) ^ loadB(mem);
1129 regB(R) = result;
1130 SETFLAG_Z(result == 0);
1131 SETFLAG_S(result & 0x80);
1132 parityB(result);
1133 cycles = 4;
1134 break; }
1135
1136 case 1: { uint16 result = regW(R) ^ loadW(mem);
1137 regW(R) = result;
1138 SETFLAG_Z(result == 0);
1139 SETFLAG_S(result & 0x8000);
1140 parityW(result);
1141 cycles = 4;
1142 break; }
1143
1144 case 2: { uint32 result = regL(R) ^ loadL(mem);
1145 regL(R) = result;
1146 SETFLAG_Z(result == 0);
1147 SETFLAG_S(result & 0x80000000);
1148 cycles = 6;
1149 break; }
1150 }
1151
1152 SETFLAG_H0;
1153 SETFLAG_N0;
1154 SETFLAG_C0;
1155 }
1156
1157 //===== XOR (mem),R
srcXORmR(void)1158 void srcXORmR(void)
1159 {
1160 switch(size)
1161 {
1162 case 0: { uint8 result = regB(R) ^ loadB(mem);
1163 storeB(mem, result);
1164 SETFLAG_Z(result == 0);
1165 SETFLAG_S(result & 0x80);
1166 parityB(result);
1167 cycles = 6;
1168 break; }
1169
1170 case 1: { uint16 result = regW(R) ^ loadW(mem);
1171 storeW(mem, result);
1172 SETFLAG_Z(result == 0);
1173 SETFLAG_S(result & 0x8000);
1174 parityW(result);
1175 cycles = 6;
1176 break; }
1177
1178 case 2: { uint32 result = regL(R) ^ loadL(mem);
1179 storeL(mem, result);
1180 SETFLAG_Z(result == 0);
1181 SETFLAG_S(result & 0x80000000);
1182 cycles = 10;
1183 break; }
1184 }
1185
1186 SETFLAG_H0;
1187 SETFLAG_N0;
1188 SETFLAG_C0;
1189 }
1190
1191 //===== OR R,(mem)
srcORRm(void)1192 void srcORRm(void)
1193 {
1194 switch(size)
1195 {
1196 case 0: { uint8 result = regB(R) | loadB(mem);
1197 regB(R) = result;
1198 SETFLAG_Z(result == 0);
1199 SETFLAG_S(result & 0x80);
1200 parityB(result);
1201 cycles = 4;
1202 break; }
1203
1204 case 1: { uint16 result = regW(R) | loadW(mem);
1205 regW(R) = result;
1206 SETFLAG_Z(result == 0);
1207 SETFLAG_S(result & 0x8000);
1208 parityW(result);
1209 cycles = 4;
1210 break; }
1211
1212 case 2: { uint32 result = regL(R) | loadL(mem);
1213 regL(R) = result;
1214 SETFLAG_Z(result == 0);
1215 SETFLAG_S(result & 0x80000000);
1216 cycles = 6;
1217 break; }
1218 }
1219
1220 SETFLAG_H0;
1221 SETFLAG_N0;
1222 SETFLAG_C0;
1223 }
1224
1225 //===== OR (mem),R
srcORmR(void)1226 void srcORmR(void)
1227 {
1228 switch(size)
1229 {
1230 case 0: { uint8 result = regB(R) | loadB(mem);
1231 storeB(mem, result);
1232 SETFLAG_Z(result == 0);
1233 SETFLAG_S(result & 0x80);
1234 parityB(result);
1235 cycles = 6;
1236 break; }
1237
1238 case 1: { uint16 result = regW(R) | loadW(mem);
1239 storeW(mem, result);
1240 SETFLAG_Z(result == 0);
1241 SETFLAG_S(result & 0x8000);
1242 parityW(result);
1243 cycles = 6;
1244 break; }
1245
1246 case 2: { uint32 result = regL(R) | loadL(mem);
1247 storeL(mem, result);
1248 SETFLAG_Z(result == 0);
1249 SETFLAG_S(result & 0x80000000);
1250 cycles = 10;
1251 break; }
1252 }
1253
1254 SETFLAG_H0;
1255 SETFLAG_N0;
1256 SETFLAG_C0;
1257 }
1258
1259 //===== CP R,(mem)
srcCPRm(void)1260 void srcCPRm(void)
1261 {
1262 switch(size)
1263 {
1264 case 0:
1265 generic_SUB_B(regB(R), loadB(mem));
1266 cycles = 4;
1267 break;
1268 case 1:
1269 generic_SUB_W(regW(R), loadW(mem));
1270 cycles = 4;
1271 break;
1272 case 2:
1273 generic_SUB_L(regL(R), loadL(mem));
1274 cycles = 6;
1275 break;
1276 }
1277 }
1278
1279 //===== CP (mem),R
srcCPmR(void)1280 void srcCPmR(void)
1281 {
1282 switch(size)
1283 {
1284 case 0:
1285 generic_SUB_B(loadB(mem), regB(R));
1286 break;
1287 case 1:
1288 generic_SUB_W(loadW(mem), regW(R));
1289 break;
1290 case 2:
1291 generic_SUB_L(loadL(mem), regL(R));
1292 break;
1293 }
1294
1295 cycles = 6;
1296 }
1297
1298 //=============================================================================
1299