1//============================================================================
2//
3// MM MM 6666 555555 0000 2222
4// MMMM MMMM 66 66 55 00 00 22 22
5// MM MMM MM 66 55 00 00 22
6// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator"
7// MM MM 66 66 55 00 00 22
8// MM MM 66 66 55 55 00 00 22
9// MM MM 6666 5555 0000 222222
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18/**
19 Code and cases to emulate each of the 6502 instructions.
20
21 Recompile with the following:
22 'm4 M6502.m4 > M6502.ins'
23
24 @author Bradford W. Mott and Stephen Anthony
25*/
26
27#ifndef NOTSAMEPAGE
28 #define NOTSAMEPAGE(_addr1, _addr2) (((_addr1) ^ (_addr2)) & 0xff00)
29#endif
30
31#ifndef SET_LAST_PEEK
32 #ifdef DEBUGGER_SUPPORT
33 #define SET_LAST_PEEK(_addr1, _addr2) _addr1 = _addr2;
34 #else
35 #define SET_LAST_PEEK(_addr1, _addr2)
36 #endif
37#endif
38
39#ifndef CLEAR_LAST_PEEK
40 #ifdef DEBUGGER_SUPPORT
41 #define CLEAR_LAST_PEEK(_addr) _addr = -1;
42 #else
43 #define CLEAR_LAST_PEEK(_addr)
44 #endif
45#endif
46
47#ifndef SET_LAST_POKE
48 #ifdef DEBUGGER_SUPPORT
49 #define SET_LAST_POKE(_addr) myDataAddressForPoke = _addr;
50 #else
51 #define SET_LAST_POKE(_addr)
52 #endif
53#endif
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269//////////////////////////////////////////////////
270// ADC
271case 0x69:
272{
273 operand = peek(PC++, DISASM_CODE);
274}
275{
276 if(!D)
277 {
278 Int32 sum = A + operand + (C ? 1 : 0);
279 N = sum & 0x80;
280 V = ~(A ^ operand) & (A ^ sum) & 0x80;
281 notZ = sum & 0xff;
282 C = sum & 0xff00;
283
284 A = uInt8(sum);
285 }
286 else
287 {
288 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
289 Int32 hi = (A & 0xf0) + (operand & 0xf0);
290 notZ = (lo+hi) & 0xff;
291 if(lo > 0x09)
292 {
293 hi += 0x10;
294 lo += 0x06;
295 }
296 N = hi & 0x80;
297 V = ~(A ^ operand) & (A ^ hi) & 0x80;
298 if(hi > 0x90)
299 hi += 0x60;
300 C = hi & 0xff00;
301
302 A = (lo & 0x0f) + (hi & 0xf0);
303 }
304}
305break;
306
307case 0x65:
308{
309 intermediateAddress = peek(PC++, DISASM_CODE);
310 operand = peek(intermediateAddress, DISASM_DATA);
311}
312{
313 if(!D)
314 {
315 Int32 sum = A + operand + (C ? 1 : 0);
316 N = sum & 0x80;
317 V = ~(A ^ operand) & (A ^ sum) & 0x80;
318 notZ = sum & 0xff;
319 C = sum & 0xff00;
320
321 A = uInt8(sum);
322 }
323 else
324 {
325 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
326 Int32 hi = (A & 0xf0) + (operand & 0xf0);
327 notZ = (lo+hi) & 0xff;
328 if(lo > 0x09)
329 {
330 hi += 0x10;
331 lo += 0x06;
332 }
333 N = hi & 0x80;
334 V = ~(A ^ operand) & (A ^ hi) & 0x80;
335 if(hi > 0x90)
336 hi += 0x60;
337 C = hi & 0xff00;
338
339 A = (lo & 0x0f) + (hi & 0xf0);
340 }
341}
342break;
343
344case 0x75:
345{
346 intermediateAddress = peek(PC++, DISASM_CODE);
347 peek(intermediateAddress, DISASM_NONE);
348 intermediateAddress += X;
349 operand = peek(intermediateAddress, DISASM_DATA);
350}
351{
352 if(!D)
353 {
354 Int32 sum = A + operand + (C ? 1 : 0);
355 N = sum & 0x80;
356 V = ~(A ^ operand) & (A ^ sum) & 0x80;
357 notZ = sum & 0xff;
358 C = sum & 0xff00;
359
360 A = uInt8(sum);
361 }
362 else
363 {
364 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
365 Int32 hi = (A & 0xf0) + (operand & 0xf0);
366 notZ = (lo+hi) & 0xff;
367 if(lo > 0x09)
368 {
369 hi += 0x10;
370 lo += 0x06;
371 }
372 N = hi & 0x80;
373 V = ~(A ^ operand) & (A ^ hi) & 0x80;
374 if(hi > 0x90)
375 hi += 0x60;
376 C = hi & 0xff00;
377
378 A = (lo & 0x0f) + (hi & 0xf0);
379 }
380}
381break;
382
383case 0x6d:
384{
385 intermediateAddress = peek(PC++, DISASM_CODE);
386 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
387 operand = peek(intermediateAddress, DISASM_DATA);
388}
389{
390 if(!D)
391 {
392 Int32 sum = A + operand + (C ? 1 : 0);
393 N = sum & 0x80;
394 V = ~(A ^ operand) & (A ^ sum) & 0x80;
395 notZ = sum & 0xff;
396 C = sum & 0xff00;
397
398 A = uInt8(sum);
399 }
400 else
401 {
402 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
403 Int32 hi = (A & 0xf0) + (operand & 0xf0);
404 notZ = (lo+hi) & 0xff;
405 if(lo > 0x09)
406 {
407 hi += 0x10;
408 lo += 0x06;
409 }
410 N = hi & 0x80;
411 V = ~(A ^ operand) & (A ^ hi) & 0x80;
412 if(hi > 0x90)
413 hi += 0x60;
414 C = hi & 0xff00;
415
416 A = (lo & 0x0f) + (hi & 0xf0);
417 }
418}
419break;
420
421case 0x7d:
422{
423 uInt16 low = peek(PC++, DISASM_CODE);
424 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
425 intermediateAddress = high | uInt8(low + X);
426 if((low + X) > 0xFF)
427 {
428 operand = peek(intermediateAddress, DISASM_NONE);
429 intermediateAddress = (high | low) + X;
430 operand = peek(intermediateAddress, DISASM_DATA);
431 }
432 else
433 {
434 operand = peek(intermediateAddress, DISASM_DATA);
435 }
436}
437{
438 if(!D)
439 {
440 Int32 sum = A + operand + (C ? 1 : 0);
441 N = sum & 0x80;
442 V = ~(A ^ operand) & (A ^ sum) & 0x80;
443 notZ = sum & 0xff;
444 C = sum & 0xff00;
445
446 A = uInt8(sum);
447 }
448 else
449 {
450 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
451 Int32 hi = (A & 0xf0) + (operand & 0xf0);
452 notZ = (lo+hi) & 0xff;
453 if(lo > 0x09)
454 {
455 hi += 0x10;
456 lo += 0x06;
457 }
458 N = hi & 0x80;
459 V = ~(A ^ operand) & (A ^ hi) & 0x80;
460 if(hi > 0x90)
461 hi += 0x60;
462 C = hi & 0xff00;
463
464 A = (lo & 0x0f) + (hi & 0xf0);
465 }
466}
467break;
468
469case 0x79:
470{
471 uInt16 low = peek(PC++, DISASM_CODE);
472 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
473 intermediateAddress = high | uInt8(low + Y);
474 if((low + Y) > 0xFF)
475 {
476 operand = peek(intermediateAddress, DISASM_NONE);
477 intermediateAddress = (high | low) + Y;
478 operand = peek(intermediateAddress, DISASM_DATA);
479 }
480 else
481 {
482 operand = peek(intermediateAddress, DISASM_DATA);
483 }
484}
485{
486 if(!D)
487 {
488 Int32 sum = A + operand + (C ? 1 : 0);
489 N = sum & 0x80;
490 V = ~(A ^ operand) & (A ^ sum) & 0x80;
491 notZ = sum & 0xff;
492 C = sum & 0xff00;
493
494 A = uInt8(sum);
495 }
496 else
497 {
498 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
499 Int32 hi = (A & 0xf0) + (operand & 0xf0);
500 notZ = (lo+hi) & 0xff;
501 if(lo > 0x09)
502 {
503 hi += 0x10;
504 lo += 0x06;
505 }
506 N = hi & 0x80;
507 V = ~(A ^ operand) & (A ^ hi) & 0x80;
508 if(hi > 0x90)
509 hi += 0x60;
510 C = hi & 0xff00;
511
512 A = (lo & 0x0f) + (hi & 0xf0);
513 }
514}
515break;
516
517case 0x61:
518{
519 uInt8 pointer = peek(PC++, DISASM_CODE);
520 peek(pointer, DISASM_NONE);
521 pointer += X;
522 intermediateAddress = peek(pointer++, DISASM_DATA);
523 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
524 operand = peek(intermediateAddress, DISASM_DATA);
525}
526{
527 if(!D)
528 {
529 Int32 sum = A + operand + (C ? 1 : 0);
530 N = sum & 0x80;
531 V = ~(A ^ operand) & (A ^ sum) & 0x80;
532 notZ = sum & 0xff;
533 C = sum & 0xff00;
534
535 A = uInt8(sum);
536 }
537 else
538 {
539 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
540 Int32 hi = (A & 0xf0) + (operand & 0xf0);
541 notZ = (lo+hi) & 0xff;
542 if(lo > 0x09)
543 {
544 hi += 0x10;
545 lo += 0x06;
546 }
547 N = hi & 0x80;
548 V = ~(A ^ operand) & (A ^ hi) & 0x80;
549 if(hi > 0x90)
550 hi += 0x60;
551 C = hi & 0xff00;
552
553 A = (lo & 0x0f) + (hi & 0xf0);
554 }
555}
556break;
557
558case 0x71:
559{
560 uInt8 pointer = peek(PC++, DISASM_CODE);
561 uInt16 low = peek(pointer++, DISASM_DATA);
562 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
563 intermediateAddress = high | uInt8(low + Y);
564 if((low + Y) > 0xFF)
565 {
566 operand = peek(intermediateAddress, DISASM_NONE);
567 intermediateAddress = (high | low) + Y;
568 operand = peek(intermediateAddress, DISASM_DATA);
569 }
570 else
571 {
572 operand = peek(intermediateAddress, DISASM_DATA);
573 }
574}
575{
576 if(!D)
577 {
578 Int32 sum = A + operand + (C ? 1 : 0);
579 N = sum & 0x80;
580 V = ~(A ^ operand) & (A ^ sum) & 0x80;
581 notZ = sum & 0xff;
582 C = sum & 0xff00;
583
584 A = uInt8(sum);
585 }
586 else
587 {
588 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
589 Int32 hi = (A & 0xf0) + (operand & 0xf0);
590 notZ = (lo+hi) & 0xff;
591 if(lo > 0x09)
592 {
593 hi += 0x10;
594 lo += 0x06;
595 }
596 N = hi & 0x80;
597 V = ~(A ^ operand) & (A ^ hi) & 0x80;
598 if(hi > 0x90)
599 hi += 0x60;
600 C = hi & 0xff00;
601
602 A = (lo & 0x0f) + (hi & 0xf0);
603 }
604}
605break;
606
607//////////////////////////////////////////////////
608// ASR
609case 0x4b:
610{
611 operand = peek(PC++, DISASM_CODE);
612}
613{
614 A &= operand;
615
616 // Set carry flag according to the right-most bit
617 C = A & 0x01;
618
619 A >>= 1;
620
621 notZ = A;
622 N = false;
623}
624break;
625
626//////////////////////////////////////////////////
627// ANC
628case 0x0b:
629case 0x2b:
630{
631 operand = peek(PC++, DISASM_CODE);
632}
633{
634 A &= operand;
635 notZ = A;
636 N = A & 0x80;
637 C = N;
638}
639break;
640
641//////////////////////////////////////////////////
642// AND
643case 0x29:
644{
645 operand = peek(PC++, DISASM_CODE);
646}
647{
648 A &= operand;
649 notZ = A;
650 N = A & 0x80;
651}
652break;
653
654case 0x25:
655{
656 intermediateAddress = peek(PC++, DISASM_CODE);
657 operand = peek(intermediateAddress, DISASM_DATA);
658}
659{
660 A &= operand;
661 notZ = A;
662 N = A & 0x80;
663}
664break;
665
666case 0x35:
667{
668 intermediateAddress = peek(PC++, DISASM_CODE);
669 peek(intermediateAddress, DISASM_NONE);
670 intermediateAddress += X;
671 operand = peek(intermediateAddress, DISASM_DATA);
672}
673{
674 A &= operand;
675 notZ = A;
676 N = A & 0x80;
677}
678break;
679
680case 0x2d:
681{
682 intermediateAddress = peek(PC++, DISASM_CODE);
683 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
684 operand = peek(intermediateAddress, DISASM_DATA);
685}
686{
687 A &= operand;
688 notZ = A;
689 N = A & 0x80;
690}
691break;
692
693case 0x3d:
694{
695 uInt16 low = peek(PC++, DISASM_CODE);
696 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
697 intermediateAddress = high | uInt8(low + X);
698 if((low + X) > 0xFF)
699 {
700 operand = peek(intermediateAddress, DISASM_NONE);
701 intermediateAddress = (high | low) + X;
702 operand = peek(intermediateAddress, DISASM_DATA);
703 }
704 else
705 {
706 operand = peek(intermediateAddress, DISASM_DATA);
707 }
708}
709{
710 A &= operand;
711 notZ = A;
712 N = A & 0x80;
713}
714break;
715
716case 0x39:
717{
718 uInt16 low = peek(PC++, DISASM_CODE);
719 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
720 intermediateAddress = high | uInt8(low + Y);
721 if((low + Y) > 0xFF)
722 {
723 operand = peek(intermediateAddress, DISASM_NONE);
724 intermediateAddress = (high | low) + Y;
725 operand = peek(intermediateAddress, DISASM_DATA);
726 }
727 else
728 {
729 operand = peek(intermediateAddress, DISASM_DATA);
730 }
731}
732{
733 A &= operand;
734 notZ = A;
735 N = A & 0x80;
736}
737break;
738
739case 0x21:
740{
741 uInt8 pointer = peek(PC++, DISASM_CODE);
742 peek(pointer, DISASM_NONE);
743 pointer += X;
744 intermediateAddress = peek(pointer++, DISASM_DATA);
745 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
746 operand = peek(intermediateAddress, DISASM_DATA);
747}
748{
749 A &= operand;
750 notZ = A;
751 N = A & 0x80;
752}
753break;
754
755case 0x31:
756{
757 uInt8 pointer = peek(PC++, DISASM_CODE);
758 uInt16 low = peek(pointer++, DISASM_DATA);
759 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
760 intermediateAddress = high | uInt8(low + Y);
761 if((low + Y) > 0xFF)
762 {
763 operand = peek(intermediateAddress, DISASM_NONE);
764 intermediateAddress = (high | low) + Y;
765 operand = peek(intermediateAddress, DISASM_DATA);
766 }
767 else
768 {
769 operand = peek(intermediateAddress, DISASM_DATA);
770 }
771}
772{
773 A &= operand;
774 notZ = A;
775 N = A & 0x80;
776}
777break;
778
779//////////////////////////////////////////////////
780// ANE
781case 0x8b:
782{
783 operand = peek(PC++, DISASM_CODE);
784}
785{
786 // NOTE: The implementation of this instruction is based on
787 // information from the 64doc.txt file. This instruction is
788 // reported to be unstable!
789 A = (A | 0xee) & X & operand;
790 notZ = A;
791 N = A & 0x80;
792}
793break;
794
795//////////////////////////////////////////////////
796// ARR
797case 0x6b:
798{
799 operand = peek(PC++, DISASM_CODE);
800}
801{
802 // NOTE: The implementation of this instruction is based on
803 // information from the 64doc.txt file. There are mixed
804 // reports on its operation!
805 if(!D)
806 {
807 A &= operand;
808 A = ((A >> 1) & 0x7f) | (C ? 0x80 : 0x00);
809
810 C = A & 0x40;
811 V = (A & 0x40) ^ ((A & 0x20) << 1);
812
813 notZ = A;
814 N = A & 0x80;
815 }
816 else
817 {
818 uInt8 value = A & operand;
819
820 A = ((value >> 1) & 0x7f) | (C ? 0x80 : 0x00);
821 N = C;
822 notZ = A;
823 V = (value ^ A) & 0x40;
824
825 if(((value & 0x0f) + (value & 0x01)) > 0x05)
826 {
827 A = (A & 0xf0) | ((A + 0x06) & 0x0f);
828 }
829
830 if(((value & 0xf0) + (value & 0x10)) > 0x50)
831 {
832 A += 0x60;
833 C = true;
834 }
835 else
836 {
837 C = false;
838 }
839 }
840}
841break;
842
843//////////////////////////////////////////////////
844// ASL
845case 0x0a:
846{
847 peek(PC, DISASM_NONE);
848}
849{
850 // Set carry flag according to the left-most bit in A
851 C = A & 0x80;
852
853 A <<= 1;
854
855 notZ = A;
856 N = A & 0x80;
857}
858break;
859
860case 0x06:
861{
862 operandAddress = peek(PC++, DISASM_CODE);
863 operand = peek(operandAddress, DISASM_DATA);
864 poke(operandAddress, operand, DISASM_WRITE);
865}
866{
867 // Set carry flag according to the left-most bit in value
868 C = operand & 0x80;
869
870 operand <<= 1;
871 poke(operandAddress, operand, DISASM_WRITE);
872
873 notZ = operand;
874 N = operand & 0x80;
875}
876break;
877
878case 0x16:
879{
880 operandAddress = peek(PC++, DISASM_CODE);
881 peek(operandAddress, DISASM_NONE);
882 operandAddress = (operandAddress + X) & 0xFF;
883 operand = peek(operandAddress, DISASM_DATA);
884 poke(operandAddress, operand, DISASM_WRITE);
885}
886{
887 // Set carry flag according to the left-most bit in value
888 C = operand & 0x80;
889
890 operand <<= 1;
891 poke(operandAddress, operand, DISASM_WRITE);
892
893 notZ = operand;
894 N = operand & 0x80;
895}
896break;
897
898case 0x0e:
899{
900 operandAddress = peek(PC++, DISASM_CODE);
901 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
902 operand = peek(operandAddress, DISASM_DATA);
903 poke(operandAddress, operand, DISASM_WRITE);
904}
905{
906 // Set carry flag according to the left-most bit in value
907 C = operand & 0x80;
908
909 operand <<= 1;
910 poke(operandAddress, operand, DISASM_WRITE);
911
912 notZ = operand;
913 N = operand & 0x80;
914}
915break;
916
917case 0x1e:
918{
919 uInt16 low = peek(PC++, DISASM_CODE);
920 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
921 peek(high | uInt8(low + X), DISASM_NONE);
922 operandAddress = (high | low) + X;
923 operand = peek(operandAddress, DISASM_DATA);
924 poke(operandAddress, operand, DISASM_WRITE);
925}
926{
927 // Set carry flag according to the left-most bit in value
928 C = operand & 0x80;
929
930 operand <<= 1;
931 poke(operandAddress, operand, DISASM_WRITE);
932
933 notZ = operand;
934 N = operand & 0x80;
935}
936break;
937
938//////////////////////////////////////////////////
939// BIT
940case 0x24:
941{
942 intermediateAddress = peek(PC++, DISASM_CODE);
943 operand = peek(intermediateAddress, DISASM_DATA);
944}
945{
946 notZ = (A & operand);
947 N = operand & 0x80;
948 V = operand & 0x40;
949}
950break;
951
952case 0x2C:
953{
954 intermediateAddress = peek(PC++, DISASM_CODE);
955 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
956 operand = peek(intermediateAddress, DISASM_DATA);
957}
958{
959 notZ = (A & operand);
960 N = operand & 0x80;
961 V = operand & 0x40;
962}
963break;
964
965//////////////////////////////////////////////////
966// Branches
967case 0x90:
968{
969 operand = peek(PC++, DISASM_CODE);
970}
971{
972 if(!C)
973 {
974 peek(PC, DISASM_NONE);
975 uInt16 address = PC + Int8(operand);
976 if(NOTSAMEPAGE(PC, address))
977 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
978 PC = address;
979 }
980}
981break;
982
983
984case 0xb0:
985{
986 operand = peek(PC++, DISASM_CODE);
987}
988{
989 if(C)
990 {
991 peek(PC, DISASM_NONE);
992 uInt16 address = PC + Int8(operand);
993 if(NOTSAMEPAGE(PC, address))
994 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
995 PC = address;
996 }
997}
998break;
999
1000
1001case 0xf0:
1002{
1003 operand = peek(PC++, DISASM_CODE);
1004}
1005{
1006 if(!notZ)
1007 {
1008 peek(PC, DISASM_NONE);
1009 uInt16 address = PC + Int8(operand);
1010 if(NOTSAMEPAGE(PC, address))
1011 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
1012 PC = address;
1013 }
1014}
1015break;
1016
1017
1018case 0x30:
1019{
1020 operand = peek(PC++, DISASM_CODE);
1021}
1022{
1023 if(N)
1024 {
1025 peek(PC, DISASM_NONE);
1026 uInt16 address = PC + Int8(operand);
1027 if(NOTSAMEPAGE(PC, address))
1028 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
1029 PC = address;
1030 }
1031}
1032break;
1033
1034
1035case 0xD0:
1036{
1037 operand = peek(PC++, DISASM_CODE);
1038}
1039{
1040 if(notZ)
1041 {
1042 peek(PC, DISASM_NONE);
1043 uInt16 address = PC + Int8(operand);
1044 if(NOTSAMEPAGE(PC, address))
1045 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
1046 PC = address;
1047 }
1048}
1049break;
1050
1051
1052case 0x10:
1053{
1054 operand = peek(PC++, DISASM_CODE);
1055}
1056{
1057 if(!N)
1058 {
1059 peek(PC, DISASM_NONE);
1060 uInt16 address = PC + Int8(operand);
1061 if(NOTSAMEPAGE(PC, address))
1062 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
1063 PC = address;
1064 }
1065}
1066break;
1067
1068
1069case 0x50:
1070{
1071 operand = peek(PC++, DISASM_CODE);
1072}
1073{
1074 if(!V)
1075 {
1076 peek(PC, DISASM_NONE);
1077 uInt16 address = PC + Int8(operand);
1078 if(NOTSAMEPAGE(PC, address))
1079 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
1080 PC = address;
1081 }
1082}
1083break;
1084
1085
1086case 0x70:
1087{
1088 operand = peek(PC++, DISASM_CODE);
1089}
1090{
1091 if(V)
1092 {
1093 peek(PC, DISASM_NONE);
1094 uInt16 address = PC + Int8(operand);
1095 if(NOTSAMEPAGE(PC, address))
1096 peek((PC & 0xFF00) | (address & 0x00FF), DISASM_NONE);
1097 PC = address;
1098 }
1099}
1100break;
1101
1102//////////////////////////////////////////////////
1103// BRK
1104case 0x00:
1105{
1106 peek(PC++, DISASM_NONE);
1107
1108 B = true;
1109
1110 poke(0x0100 + SP--, PC >> 8, DISASM_WRITE);
1111 poke(0x0100 + SP--, PC & 0x00ff, DISASM_WRITE);
1112 poke(0x0100 + SP--, PS(), DISASM_WRITE);
1113
1114 I = true;
1115
1116 PC = peek(0xfffe, DISASM_DATA);
1117 PC |= (uInt16(peek(0xffff, DISASM_DATA)) << 8);
1118}
1119break;
1120
1121//////////////////////////////////////////////////
1122// CLC
1123case 0x18:
1124{
1125 peek(PC, DISASM_NONE);
1126}
1127{
1128 C = false;
1129}
1130break;
1131
1132//////////////////////////////////////////////////
1133// CLD
1134case 0xd8:
1135{
1136 peek(PC, DISASM_NONE);
1137}
1138{
1139 D = false;
1140}
1141break;
1142
1143//////////////////////////////////////////////////
1144// CLI
1145case 0x58:
1146{
1147 peek(PC, DISASM_NONE);
1148}
1149{
1150 I = false;
1151}
1152break;
1153
1154//////////////////////////////////////////////////
1155// CLV
1156case 0xb8:
1157{
1158 peek(PC, DISASM_NONE);
1159}
1160{
1161 V = false;
1162}
1163break;
1164
1165//////////////////////////////////////////////////
1166// CMP
1167case 0xc9:
1168{
1169 operand = peek(PC++, DISASM_CODE);
1170}
1171{
1172 uInt16 value = uInt16(A) - uInt16(operand);
1173
1174 notZ = value;
1175 N = value & 0x0080;
1176 C = !(value & 0x0100);
1177}
1178break;
1179
1180case 0xc5:
1181{
1182 intermediateAddress = peek(PC++, DISASM_CODE);
1183 operand = peek(intermediateAddress, DISASM_DATA);
1184}
1185{
1186 uInt16 value = uInt16(A) - uInt16(operand);
1187
1188 notZ = value;
1189 N = value & 0x0080;
1190 C = !(value & 0x0100);
1191}
1192break;
1193
1194case 0xd5:
1195{
1196 intermediateAddress = peek(PC++, DISASM_CODE);
1197 peek(intermediateAddress, DISASM_NONE);
1198 intermediateAddress += X;
1199 operand = peek(intermediateAddress, DISASM_DATA);
1200}
1201{
1202 uInt16 value = uInt16(A) - uInt16(operand);
1203
1204 notZ = value;
1205 N = value & 0x0080;
1206 C = !(value & 0x0100);
1207}
1208break;
1209
1210case 0xcd:
1211{
1212 intermediateAddress = peek(PC++, DISASM_CODE);
1213 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1214 operand = peek(intermediateAddress, DISASM_DATA);
1215}
1216{
1217 uInt16 value = uInt16(A) - uInt16(operand);
1218
1219 notZ = value;
1220 N = value & 0x0080;
1221 C = !(value & 0x0100);
1222}
1223break;
1224
1225case 0xdd:
1226{
1227 uInt16 low = peek(PC++, DISASM_CODE);
1228 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1229 intermediateAddress = high | uInt8(low + X);
1230 if((low + X) > 0xFF)
1231 {
1232 operand = peek(intermediateAddress, DISASM_NONE);
1233 intermediateAddress = (high | low) + X;
1234 operand = peek(intermediateAddress, DISASM_DATA);
1235 }
1236 else
1237 {
1238 operand = peek(intermediateAddress, DISASM_DATA);
1239 }
1240}
1241{
1242 uInt16 value = uInt16(A) - uInt16(operand);
1243
1244 notZ = value;
1245 N = value & 0x0080;
1246 C = !(value & 0x0100);
1247}
1248break;
1249
1250case 0xd9:
1251{
1252 uInt16 low = peek(PC++, DISASM_CODE);
1253 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1254 intermediateAddress = high | uInt8(low + Y);
1255 if((low + Y) > 0xFF)
1256 {
1257 operand = peek(intermediateAddress, DISASM_NONE);
1258 intermediateAddress = (high | low) + Y;
1259 operand = peek(intermediateAddress, DISASM_DATA);
1260 }
1261 else
1262 {
1263 operand = peek(intermediateAddress, DISASM_DATA);
1264 }
1265}
1266{
1267 uInt16 value = uInt16(A) - uInt16(operand);
1268
1269 notZ = value;
1270 N = value & 0x0080;
1271 C = !(value & 0x0100);
1272}
1273break;
1274
1275case 0xc1:
1276{
1277 uInt8 pointer = peek(PC++, DISASM_CODE);
1278 peek(pointer, DISASM_NONE);
1279 pointer += X;
1280 intermediateAddress = peek(pointer++, DISASM_DATA);
1281 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
1282 operand = peek(intermediateAddress, DISASM_DATA);
1283}
1284{
1285 uInt16 value = uInt16(A) - uInt16(operand);
1286
1287 notZ = value;
1288 N = value & 0x0080;
1289 C = !(value & 0x0100);
1290}
1291break;
1292
1293case 0xd1:
1294{
1295 uInt8 pointer = peek(PC++, DISASM_CODE);
1296 uInt16 low = peek(pointer++, DISASM_DATA);
1297 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
1298 intermediateAddress = high | uInt8(low + Y);
1299 if((low + Y) > 0xFF)
1300 {
1301 operand = peek(intermediateAddress, DISASM_NONE);
1302 intermediateAddress = (high | low) + Y;
1303 operand = peek(intermediateAddress, DISASM_DATA);
1304 }
1305 else
1306 {
1307 operand = peek(intermediateAddress, DISASM_DATA);
1308 }
1309}
1310{
1311 uInt16 value = uInt16(A) - uInt16(operand);
1312
1313 notZ = value;
1314 N = value & 0x0080;
1315 C = !(value & 0x0100);
1316}
1317break;
1318
1319//////////////////////////////////////////////////
1320// CPX
1321case 0xe0:
1322{
1323 operand = peek(PC++, DISASM_CODE);
1324}
1325{
1326 uInt16 value = uInt16(X) - uInt16(operand);
1327
1328 notZ = value;
1329 N = value & 0x0080;
1330 C = !(value & 0x0100);
1331}
1332break;
1333
1334case 0xe4:
1335{
1336 intermediateAddress = peek(PC++, DISASM_CODE);
1337 operand = peek(intermediateAddress, DISASM_DATA);
1338}
1339{
1340 uInt16 value = uInt16(X) - uInt16(operand);
1341
1342 notZ = value;
1343 N = value & 0x0080;
1344 C = !(value & 0x0100);
1345}
1346break;
1347
1348case 0xec:
1349{
1350 intermediateAddress = peek(PC++, DISASM_CODE);
1351 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1352 operand = peek(intermediateAddress, DISASM_DATA);
1353}
1354{
1355 uInt16 value = uInt16(X) - uInt16(operand);
1356
1357 notZ = value;
1358 N = value & 0x0080;
1359 C = !(value & 0x0100);
1360}
1361break;
1362
1363//////////////////////////////////////////////////
1364// CPY
1365case 0xc0:
1366{
1367 operand = peek(PC++, DISASM_CODE);
1368}
1369{
1370 uInt16 value = uInt16(Y) - uInt16(operand);
1371
1372 notZ = value;
1373 N = value & 0x0080;
1374 C = !(value & 0x0100);
1375}
1376break;
1377
1378case 0xc4:
1379{
1380 intermediateAddress = peek(PC++, DISASM_CODE);
1381 operand = peek(intermediateAddress, DISASM_DATA);
1382}
1383{
1384 uInt16 value = uInt16(Y) - uInt16(operand);
1385
1386 notZ = value;
1387 N = value & 0x0080;
1388 C = !(value & 0x0100);
1389}
1390break;
1391
1392case 0xcc:
1393{
1394 intermediateAddress = peek(PC++, DISASM_CODE);
1395 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1396 operand = peek(intermediateAddress, DISASM_DATA);
1397}
1398{
1399 uInt16 value = uInt16(Y) - uInt16(operand);
1400
1401 notZ = value;
1402 N = value & 0x0080;
1403 C = !(value & 0x0100);
1404}
1405break;
1406
1407//////////////////////////////////////////////////
1408// DCP
1409case 0xcf:
1410{
1411 operandAddress = peek(PC++, DISASM_CODE);
1412 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1413 operand = peek(operandAddress, DISASM_DATA);
1414 poke(operandAddress, operand, DISASM_WRITE);
1415}
1416{
1417 uInt8 value = operand - 1;
1418 poke(operandAddress, value, DISASM_WRITE);
1419
1420 uInt16 value2 = uInt16(A) - uInt16(value);
1421 notZ = value2;
1422 N = value2 & 0x0080;
1423 C = !(value2 & 0x0100);
1424}
1425break;
1426
1427case 0xdf:
1428{
1429 uInt16 low = peek(PC++, DISASM_CODE);
1430 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1431 peek(high | uInt8(low + X), DISASM_NONE);
1432 operandAddress = (high | low) + X;
1433 operand = peek(operandAddress, DISASM_DATA);
1434 poke(operandAddress, operand, DISASM_WRITE);
1435}
1436{
1437 uInt8 value = operand - 1;
1438 poke(operandAddress, value, DISASM_WRITE);
1439
1440 uInt16 value2 = uInt16(A) - uInt16(value);
1441 notZ = value2;
1442 N = value2 & 0x0080;
1443 C = !(value2 & 0x0100);
1444}
1445break;
1446
1447case 0xdb:
1448{
1449 uInt16 low = peek(PC++, DISASM_CODE);
1450 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1451 peek(high | uInt8(low + Y), DISASM_NONE);
1452 operandAddress = (high | low) + Y;
1453 operand = peek(operandAddress, DISASM_DATA);
1454 poke(operandAddress, operand, DISASM_WRITE);
1455}
1456{
1457 uInt8 value = operand - 1;
1458 poke(operandAddress, value, DISASM_WRITE);
1459
1460 uInt16 value2 = uInt16(A) - uInt16(value);
1461 notZ = value2;
1462 N = value2 & 0x0080;
1463 C = !(value2 & 0x0100);
1464}
1465break;
1466
1467case 0xc7:
1468{
1469 operandAddress = peek(PC++, DISASM_CODE);
1470 operand = peek(operandAddress, DISASM_DATA);
1471 poke(operandAddress, operand, DISASM_WRITE);
1472}
1473{
1474 uInt8 value = operand - 1;
1475 poke(operandAddress, value, DISASM_WRITE);
1476
1477 uInt16 value2 = uInt16(A) - uInt16(value);
1478 notZ = value2;
1479 N = value2 & 0x0080;
1480 C = !(value2 & 0x0100);
1481}
1482break;
1483
1484case 0xd7:
1485{
1486 operandAddress = peek(PC++, DISASM_CODE);
1487 peek(operandAddress, DISASM_NONE);
1488 operandAddress = (operandAddress + X) & 0xFF;
1489 operand = peek(operandAddress, DISASM_DATA);
1490 poke(operandAddress, operand, DISASM_WRITE);
1491}
1492{
1493 uInt8 value = operand - 1;
1494 poke(operandAddress, value, DISASM_WRITE);
1495
1496 uInt16 value2 = uInt16(A) - uInt16(value);
1497 notZ = value2;
1498 N = value2 & 0x0080;
1499 C = !(value2 & 0x0100);
1500}
1501break;
1502
1503case 0xc3:
1504{
1505 uInt8 pointer = peek(PC++, DISASM_CODE);
1506 peek(pointer, DISASM_NONE);
1507 pointer += X;
1508 operandAddress = peek(pointer++, DISASM_DATA);
1509 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
1510 operand = peek(operandAddress, DISASM_DATA);
1511 poke(operandAddress, operand, DISASM_WRITE);
1512}
1513{
1514 uInt8 value = operand - 1;
1515 poke(operandAddress, value, DISASM_WRITE);
1516
1517 uInt16 value2 = uInt16(A) - uInt16(value);
1518 notZ = value2;
1519 N = value2 & 0x0080;
1520 C = !(value2 & 0x0100);
1521}
1522break;
1523
1524case 0xd3:
1525{
1526 uInt8 pointer = peek(PC++, DISASM_CODE);
1527 uInt16 low = peek(pointer++, DISASM_DATA);
1528 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
1529 peek(high | uInt8(low + Y), DISASM_NONE);
1530 operandAddress = (high | low) + Y;
1531 operand = peek(operandAddress, DISASM_DATA);
1532 poke(operandAddress, operand, DISASM_WRITE);
1533}
1534{
1535 uInt8 value = operand - 1;
1536 poke(operandAddress, value, DISASM_WRITE);
1537
1538 uInt16 value2 = uInt16(A) - uInt16(value);
1539 notZ = value2;
1540 N = value2 & 0x0080;
1541 C = !(value2 & 0x0100);
1542}
1543break;
1544
1545//////////////////////////////////////////////////
1546// DEC
1547case 0xc6:
1548{
1549 operandAddress = peek(PC++, DISASM_CODE);
1550 operand = peek(operandAddress, DISASM_DATA);
1551 poke(operandAddress, operand, DISASM_WRITE);
1552}
1553{
1554 uInt8 value = operand - 1;
1555 poke(operandAddress, value, DISASM_WRITE);
1556
1557 notZ = value;
1558 N = value & 0x80;
1559}
1560break;
1561
1562case 0xd6:
1563{
1564 operandAddress = peek(PC++, DISASM_CODE);
1565 peek(operandAddress, DISASM_NONE);
1566 operandAddress = (operandAddress + X) & 0xFF;
1567 operand = peek(operandAddress, DISASM_DATA);
1568 poke(operandAddress, operand, DISASM_WRITE);
1569}
1570{
1571 uInt8 value = operand - 1;
1572 poke(operandAddress, value, DISASM_WRITE);
1573
1574 notZ = value;
1575 N = value & 0x80;
1576}
1577break;
1578
1579case 0xce:
1580{
1581 operandAddress = peek(PC++, DISASM_CODE);
1582 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1583 operand = peek(operandAddress, DISASM_DATA);
1584 poke(operandAddress, operand, DISASM_WRITE);
1585}
1586{
1587 uInt8 value = operand - 1;
1588 poke(operandAddress, value, DISASM_WRITE);
1589
1590 notZ = value;
1591 N = value & 0x80;
1592}
1593break;
1594
1595case 0xde:
1596{
1597 uInt16 low = peek(PC++, DISASM_CODE);
1598 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1599 peek(high | uInt8(low + X), DISASM_NONE);
1600 operandAddress = (high | low) + X;
1601 operand = peek(operandAddress, DISASM_DATA);
1602 poke(operandAddress, operand, DISASM_WRITE);
1603}
1604{
1605 uInt8 value = operand - 1;
1606 poke(operandAddress, value, DISASM_WRITE);
1607
1608 notZ = value;
1609 N = value & 0x80;
1610}
1611break;
1612
1613//////////////////////////////////////////////////
1614// DEX
1615case 0xca:
1616{
1617 peek(PC, DISASM_NONE);
1618}
1619{
1620 X--;
1621
1622 notZ = X;
1623 N = X & 0x80;
1624}
1625break;
1626
1627//////////////////////////////////////////////////
1628// DEY
1629case 0x88:
1630{
1631 peek(PC, DISASM_NONE);
1632}
1633{
1634 Y--;
1635
1636 notZ = Y;
1637 N = Y & 0x80;
1638}
1639break;
1640
1641//////////////////////////////////////////////////
1642// EOR
1643case 0x49:
1644{
1645 operand = peek(PC++, DISASM_CODE);
1646}
1647{
1648 A ^= operand;
1649 notZ = A;
1650 N = A & 0x80;
1651}
1652break;
1653
1654case 0x45:
1655{
1656 intermediateAddress = peek(PC++, DISASM_CODE);
1657 operand = peek(intermediateAddress, DISASM_DATA);
1658}
1659{
1660 A ^= operand;
1661 notZ = A;
1662 N = A & 0x80;
1663}
1664break;
1665
1666case 0x55:
1667{
1668 intermediateAddress = peek(PC++, DISASM_CODE);
1669 peek(intermediateAddress, DISASM_NONE);
1670 intermediateAddress += X;
1671 operand = peek(intermediateAddress, DISASM_DATA);
1672}
1673{
1674 A ^= operand;
1675 notZ = A;
1676 N = A & 0x80;
1677}
1678break;
1679
1680case 0x4d:
1681{
1682 intermediateAddress = peek(PC++, DISASM_CODE);
1683 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1684 operand = peek(intermediateAddress, DISASM_DATA);
1685}
1686{
1687 A ^= operand;
1688 notZ = A;
1689 N = A & 0x80;
1690}
1691break;
1692
1693case 0x5d:
1694{
1695 uInt16 low = peek(PC++, DISASM_CODE);
1696 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1697 intermediateAddress = high | uInt8(low + X);
1698 if((low + X) > 0xFF)
1699 {
1700 operand = peek(intermediateAddress, DISASM_NONE);
1701 intermediateAddress = (high | low) + X;
1702 operand = peek(intermediateAddress, DISASM_DATA);
1703 }
1704 else
1705 {
1706 operand = peek(intermediateAddress, DISASM_DATA);
1707 }
1708}
1709{
1710 A ^= operand;
1711 notZ = A;
1712 N = A & 0x80;
1713}
1714break;
1715
1716case 0x59:
1717{
1718 uInt16 low = peek(PC++, DISASM_CODE);
1719 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1720 intermediateAddress = high | uInt8(low + Y);
1721 if((low + Y) > 0xFF)
1722 {
1723 operand = peek(intermediateAddress, DISASM_NONE);
1724 intermediateAddress = (high | low) + Y;
1725 operand = peek(intermediateAddress, DISASM_DATA);
1726 }
1727 else
1728 {
1729 operand = peek(intermediateAddress, DISASM_DATA);
1730 }
1731}
1732{
1733 A ^= operand;
1734 notZ = A;
1735 N = A & 0x80;
1736}
1737break;
1738
1739case 0x41:
1740{
1741 uInt8 pointer = peek(PC++, DISASM_CODE);
1742 peek(pointer, DISASM_NONE);
1743 pointer += X;
1744 intermediateAddress = peek(pointer++, DISASM_DATA);
1745 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
1746 operand = peek(intermediateAddress, DISASM_DATA);
1747}
1748{
1749 A ^= operand;
1750 notZ = A;
1751 N = A & 0x80;
1752}
1753break;
1754
1755case 0x51:
1756{
1757 uInt8 pointer = peek(PC++, DISASM_CODE);
1758 uInt16 low = peek(pointer++, DISASM_DATA);
1759 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
1760 intermediateAddress = high | uInt8(low + Y);
1761 if((low + Y) > 0xFF)
1762 {
1763 operand = peek(intermediateAddress, DISASM_NONE);
1764 intermediateAddress = (high | low) + Y;
1765 operand = peek(intermediateAddress, DISASM_DATA);
1766 }
1767 else
1768 {
1769 operand = peek(intermediateAddress, DISASM_DATA);
1770 }
1771}
1772{
1773 A ^= operand;
1774 notZ = A;
1775 N = A & 0x80;
1776}
1777break;
1778
1779//////////////////////////////////////////////////
1780// INC
1781case 0xe6:
1782{
1783 operandAddress = peek(PC++, DISASM_CODE);
1784 operand = peek(operandAddress, DISASM_DATA);
1785 poke(operandAddress, operand, DISASM_WRITE);
1786}
1787{
1788 uInt8 value = operand + 1;
1789 poke(operandAddress, value, DISASM_WRITE);
1790
1791 notZ = value;
1792 N = value & 0x80;
1793}
1794break;
1795
1796case 0xf6:
1797{
1798 operandAddress = peek(PC++, DISASM_CODE);
1799 peek(operandAddress, DISASM_NONE);
1800 operandAddress = (operandAddress + X) & 0xFF;
1801 operand = peek(operandAddress, DISASM_DATA);
1802 poke(operandAddress, operand, DISASM_WRITE);
1803}
1804{
1805 uInt8 value = operand + 1;
1806 poke(operandAddress, value, DISASM_WRITE);
1807
1808 notZ = value;
1809 N = value & 0x80;
1810}
1811break;
1812
1813case 0xee:
1814{
1815 operandAddress = peek(PC++, DISASM_CODE);
1816 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1817 operand = peek(operandAddress, DISASM_DATA);
1818 poke(operandAddress, operand, DISASM_WRITE);
1819}
1820{
1821 uInt8 value = operand + 1;
1822 poke(operandAddress, value, DISASM_WRITE);
1823
1824 notZ = value;
1825 N = value & 0x80;
1826}
1827break;
1828
1829case 0xfe:
1830{
1831 uInt16 low = peek(PC++, DISASM_CODE);
1832 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1833 peek(high | uInt8(low + X), DISASM_NONE);
1834 operandAddress = (high | low) + X;
1835 operand = peek(operandAddress, DISASM_DATA);
1836 poke(operandAddress, operand, DISASM_WRITE);
1837}
1838{
1839 uInt8 value = operand + 1;
1840 poke(operandAddress, value, DISASM_WRITE);
1841
1842 notZ = value;
1843 N = value & 0x80;
1844}
1845break;
1846
1847//////////////////////////////////////////////////
1848// INX
1849case 0xe8:
1850{
1851 peek(PC, DISASM_NONE);
1852}
1853{
1854 X++;
1855 notZ = X;
1856 N = X & 0x80;
1857}
1858break;
1859
1860//////////////////////////////////////////////////
1861// INY
1862case 0xc8:
1863{
1864 peek(PC, DISASM_NONE);
1865}
1866{
1867 Y++;
1868 notZ = Y;
1869 N = Y & 0x80;
1870}
1871break;
1872
1873//////////////////////////////////////////////////
1874// ISB
1875case 0xef:
1876{
1877 operandAddress = peek(PC++, DISASM_CODE);
1878 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
1879 operand = peek(operandAddress, DISASM_DATA);
1880 poke(operandAddress, operand, DISASM_WRITE);
1881}
1882{
1883 operand = operand + 1;
1884 poke(operandAddress, operand, DISASM_WRITE);
1885
1886 // N, V, Z, C flags are the same in either mode (C calculated at the end)
1887 Int32 sum = A - operand - (C ? 0 : 1);
1888 N = sum & 0x80;
1889 V = (A ^ operand) & (A ^ sum) & 0x80;
1890 notZ = sum & 0xff;
1891
1892 if(!D)
1893 {
1894 A = uInt8(sum);
1895 }
1896 else
1897 {
1898 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
1899 Int32 hi = (A & 0xf0) - (operand & 0xf0);
1900 if(lo & 0x10)
1901 {
1902 lo -= 6;
1903 hi--;
1904 }
1905 if(hi & 0x0100)
1906 hi -= 0x60;
1907
1908 A = (lo & 0x0f) | (hi & 0xf0);
1909 }
1910 C = (sum & 0xff00) == 0;
1911}
1912break;
1913
1914case 0xff:
1915{
1916 uInt16 low = peek(PC++, DISASM_CODE);
1917 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1918 peek(high | uInt8(low + X), DISASM_NONE);
1919 operandAddress = (high | low) + X;
1920 operand = peek(operandAddress, DISASM_DATA);
1921 poke(operandAddress, operand, DISASM_WRITE);
1922}
1923{
1924 operand = operand + 1;
1925 poke(operandAddress, operand, DISASM_WRITE);
1926
1927 // N, V, Z, C flags are the same in either mode (C calculated at the end)
1928 Int32 sum = A - operand - (C ? 0 : 1);
1929 N = sum & 0x80;
1930 V = (A ^ operand) & (A ^ sum) & 0x80;
1931 notZ = sum & 0xff;
1932
1933 if(!D)
1934 {
1935 A = uInt8(sum);
1936 }
1937 else
1938 {
1939 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
1940 Int32 hi = (A & 0xf0) - (operand & 0xf0);
1941 if(lo & 0x10)
1942 {
1943 lo -= 6;
1944 hi--;
1945 }
1946 if(hi & 0x0100)
1947 hi -= 0x60;
1948
1949 A = (lo & 0x0f) | (hi & 0xf0);
1950 }
1951 C = (sum & 0xff00) == 0;
1952}
1953break;
1954
1955case 0xfb:
1956{
1957 uInt16 low = peek(PC++, DISASM_CODE);
1958 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
1959 peek(high | uInt8(low + Y), DISASM_NONE);
1960 operandAddress = (high | low) + Y;
1961 operand = peek(operandAddress, DISASM_DATA);
1962 poke(operandAddress, operand, DISASM_WRITE);
1963}
1964{
1965 operand = operand + 1;
1966 poke(operandAddress, operand, DISASM_WRITE);
1967
1968 // N, V, Z, C flags are the same in either mode (C calculated at the end)
1969 Int32 sum = A - operand - (C ? 0 : 1);
1970 N = sum & 0x80;
1971 V = (A ^ operand) & (A ^ sum) & 0x80;
1972 notZ = sum & 0xff;
1973
1974 if(!D)
1975 {
1976 A = uInt8(sum);
1977 }
1978 else
1979 {
1980 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
1981 Int32 hi = (A & 0xf0) - (operand & 0xf0);
1982 if(lo & 0x10)
1983 {
1984 lo -= 6;
1985 hi--;
1986 }
1987 if(hi & 0x0100)
1988 hi -= 0x60;
1989
1990 A = (lo & 0x0f) | (hi & 0xf0);
1991 }
1992 C = (sum & 0xff00) == 0;
1993}
1994break;
1995
1996case 0xe7:
1997{
1998 operandAddress = peek(PC++, DISASM_CODE);
1999 operand = peek(operandAddress, DISASM_DATA);
2000 poke(operandAddress, operand, DISASM_WRITE);
2001}
2002{
2003 operand = operand + 1;
2004 poke(operandAddress, operand, DISASM_WRITE);
2005
2006 // N, V, Z, C flags are the same in either mode (C calculated at the end)
2007 Int32 sum = A - operand - (C ? 0 : 1);
2008 N = sum & 0x80;
2009 V = (A ^ operand) & (A ^ sum) & 0x80;
2010 notZ = sum & 0xff;
2011
2012 if(!D)
2013 {
2014 A = uInt8(sum);
2015 }
2016 else
2017 {
2018 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
2019 Int32 hi = (A & 0xf0) - (operand & 0xf0);
2020 if(lo & 0x10)
2021 {
2022 lo -= 6;
2023 hi--;
2024 }
2025 if(hi & 0x0100)
2026 hi -= 0x60;
2027
2028 A = (lo & 0x0f) | (hi & 0xf0);
2029 }
2030 C = (sum & 0xff00) == 0;
2031}
2032break;
2033
2034case 0xf7:
2035{
2036 operandAddress = peek(PC++, DISASM_CODE);
2037 peek(operandAddress, DISASM_NONE);
2038 operandAddress = (operandAddress + X) & 0xFF;
2039 operand = peek(operandAddress, DISASM_DATA);
2040 poke(operandAddress, operand, DISASM_WRITE);
2041}
2042{
2043 operand = operand + 1;
2044 poke(operandAddress, operand, DISASM_WRITE);
2045
2046 // N, V, Z, C flags are the same in either mode (C calculated at the end)
2047 Int32 sum = A - operand - (C ? 0 : 1);
2048 N = sum & 0x80;
2049 V = (A ^ operand) & (A ^ sum) & 0x80;
2050 notZ = sum & 0xff;
2051
2052 if(!D)
2053 {
2054 A = uInt8(sum);
2055 }
2056 else
2057 {
2058 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
2059 Int32 hi = (A & 0xf0) - (operand & 0xf0);
2060 if(lo & 0x10)
2061 {
2062 lo -= 6;
2063 hi--;
2064 }
2065 if(hi & 0x0100)
2066 hi -= 0x60;
2067
2068 A = (lo & 0x0f) | (hi & 0xf0);
2069 }
2070 C = (sum & 0xff00) == 0;
2071}
2072break;
2073
2074case 0xe3:
2075{
2076 uInt8 pointer = peek(PC++, DISASM_CODE);
2077 peek(pointer, DISASM_NONE);
2078 pointer += X;
2079 operandAddress = peek(pointer++, DISASM_DATA);
2080 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
2081 operand = peek(operandAddress, DISASM_DATA);
2082 poke(operandAddress, operand, DISASM_WRITE);
2083}
2084{
2085 operand = operand + 1;
2086 poke(operandAddress, operand, DISASM_WRITE);
2087
2088 // N, V, Z, C flags are the same in either mode (C calculated at the end)
2089 Int32 sum = A - operand - (C ? 0 : 1);
2090 N = sum & 0x80;
2091 V = (A ^ operand) & (A ^ sum) & 0x80;
2092 notZ = sum & 0xff;
2093
2094 if(!D)
2095 {
2096 A = uInt8(sum);
2097 }
2098 else
2099 {
2100 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
2101 Int32 hi = (A & 0xf0) - (operand & 0xf0);
2102 if(lo & 0x10)
2103 {
2104 lo -= 6;
2105 hi--;
2106 }
2107 if(hi & 0x0100)
2108 hi -= 0x60;
2109
2110 A = (lo & 0x0f) | (hi & 0xf0);
2111 }
2112 C = (sum & 0xff00) == 0;
2113}
2114break;
2115
2116case 0xf3:
2117{
2118 uInt8 pointer = peek(PC++, DISASM_CODE);
2119 uInt16 low = peek(pointer++, DISASM_DATA);
2120 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
2121 peek(high | uInt8(low + Y), DISASM_NONE);
2122 operandAddress = (high | low) + Y;
2123 operand = peek(operandAddress, DISASM_DATA);
2124 poke(operandAddress, operand, DISASM_WRITE);
2125}
2126{
2127 operand = operand + 1;
2128 poke(operandAddress, operand, DISASM_WRITE);
2129
2130 // N, V, Z, C flags are the same in either mode (C calculated at the end)
2131 Int32 sum = A - operand - (C ? 0 : 1);
2132 N = sum & 0x80;
2133 V = (A ^ operand) & (A ^ sum) & 0x80;
2134 notZ = sum & 0xff;
2135
2136 if(!D)
2137 {
2138 A = uInt8(sum);
2139 }
2140 else
2141 {
2142 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
2143 Int32 hi = (A & 0xf0) - (operand & 0xf0);
2144 if(lo & 0x10)
2145 {
2146 lo -= 6;
2147 hi--;
2148 }
2149 if(hi & 0x0100)
2150 hi -= 0x60;
2151
2152 A = (lo & 0x0f) | (hi & 0xf0);
2153 }
2154 C = (sum & 0xff00) == 0;
2155}
2156break;
2157
2158//////////////////////////////////////////////////
2159// JMP
2160case 0x4c:
2161{
2162 operandAddress = peek(PC++, DISASM_CODE);
2163 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2164}
2165{
2166 PC = operandAddress;
2167}
2168break;
2169
2170case 0x6c:
2171{
2172 uInt16 addr = peek(PC++, DISASM_CODE);
2173 addr |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2174
2175 // Simulate the error in the indirect addressing mode!
2176 uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1);
2177
2178 operandAddress = peek(addr, DISASM_DATA);
2179 operandAddress |= (uInt16(peek(high, DISASM_DATA)) << 8);
2180}
2181{
2182 PC = operandAddress;
2183}
2184break;
2185
2186//////////////////////////////////////////////////
2187// JSR
2188case 0x20:
2189{
2190 uInt8 low = peek(PC++, DISASM_CODE);
2191 peek(0x0100 + SP, DISASM_NONE);
2192
2193 // It seems that the 650x does not push the address of the next instruction
2194 // on the stack it actually pushes the address of the next instruction
2195 // minus one. This is compensated for in the RTS instruction
2196 poke(0x0100 + SP--, PC >> 8, DISASM_WRITE);
2197 poke(0x0100 + SP--, PC & 0xff, DISASM_WRITE);
2198
2199 PC = (low | (uInt16(peek(PC, DISASM_CODE)) << 8));
2200}
2201break;
2202
2203//////////////////////////////////////////////////
2204// LAS
2205case 0xbb:
2206{
2207 uInt16 low = peek(PC++, DISASM_CODE);
2208 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2209 intermediateAddress = high | uInt8(low + Y);
2210 if((low + Y) > 0xFF)
2211 {
2212 operand = peek(intermediateAddress, DISASM_NONE);
2213 intermediateAddress = (high | low) + Y;
2214 operand = peek(intermediateAddress, DISASM_DATA);
2215 }
2216 else
2217 {
2218 operand = peek(intermediateAddress, DISASM_DATA);
2219 }
2220}
2221{
2222 A = X = SP = SP & operand;
2223 notZ = A;
2224 N = A & 0x80;
2225}
2226break;
2227
2228
2229//////////////////////////////////////////////////
2230// LAX
2231case 0xaf:
2232{
2233 intermediateAddress = peek(PC++, DISASM_CODE);
2234 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2235 operand = peek(intermediateAddress, DISASM_DATA);
2236}
2237SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2238SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2239{
2240 A = operand;
2241 X = operand;
2242 notZ = A;
2243 N = A & 0x80;
2244}
2245break;
2246
2247case 0xbf:
2248{
2249 uInt16 low = peek(PC++, DISASM_CODE);
2250 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2251 intermediateAddress = high | uInt8(low + Y);
2252 if((low + Y) > 0xFF)
2253 {
2254 operand = peek(intermediateAddress, DISASM_NONE);
2255 intermediateAddress = (high | low) + Y;
2256 operand = peek(intermediateAddress, DISASM_DATA);
2257 }
2258 else
2259 {
2260 operand = peek(intermediateAddress, DISASM_DATA);
2261 }
2262}
2263SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2264SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2265{
2266 A = operand;
2267 X = operand;
2268 notZ = A;
2269 N = A & 0x80;
2270}
2271break;
2272
2273case 0xa7:
2274{
2275 intermediateAddress = peek(PC++, DISASM_CODE);
2276 operand = peek(intermediateAddress, DISASM_DATA);
2277}
2278SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2279SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2280{
2281 A = operand;
2282 X = operand;
2283 notZ = A;
2284 N = A & 0x80;
2285}
2286break;
2287
2288case 0xb7:
2289{
2290 intermediateAddress = peek(PC++, DISASM_CODE);
2291 peek(intermediateAddress, DISASM_NONE);
2292 intermediateAddress += Y;
2293 operand = peek(intermediateAddress, DISASM_DATA);
2294}
2295SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress) // TODO - check this
2296SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2297{
2298 A = operand;
2299 X = operand;
2300 notZ = A;
2301 N = A & 0x80;
2302}
2303break;
2304
2305case 0xa3:
2306{
2307 uInt8 pointer = peek(PC++, DISASM_CODE);
2308 peek(pointer, DISASM_NONE);
2309 pointer += X;
2310 intermediateAddress = peek(pointer++, DISASM_DATA);
2311 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
2312 operand = peek(intermediateAddress, DISASM_DATA);
2313}
2314SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2315SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) // TODO - check this
2316{
2317 A = operand;
2318 X = operand;
2319 notZ = A;
2320 N = A & 0x80;
2321}
2322break;
2323
2324case 0xb3:
2325{
2326 uInt8 pointer = peek(PC++, DISASM_CODE);
2327 uInt16 low = peek(pointer++, DISASM_DATA);
2328 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
2329 intermediateAddress = high | uInt8(low + Y);
2330 if((low + Y) > 0xFF)
2331 {
2332 operand = peek(intermediateAddress, DISASM_NONE);
2333 intermediateAddress = (high | low) + Y;
2334 operand = peek(intermediateAddress, DISASM_DATA);
2335 }
2336 else
2337 {
2338 operand = peek(intermediateAddress, DISASM_DATA);
2339 }
2340}
2341SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2342SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress) // TODO - check this
2343{
2344 A = operand;
2345 X = operand;
2346 notZ = A;
2347 N = A & 0x80;
2348}
2349break;
2350//////////////////////////////////////////////////
2351
2352
2353//////////////////////////////////////////////////
2354// LDA
2355case 0xa9:
2356{
2357 operand = peek(PC++, DISASM_CODE);
2358}
2359CLEAR_LAST_PEEK(myLastSrcAddressA)
2360{
2361 A = operand;
2362 notZ = A;
2363 N = A & 0x80;
2364}
2365break;
2366
2367case 0xa5:
2368{
2369 intermediateAddress = peek(PC++, DISASM_CODE);
2370 operand = peek(intermediateAddress, DISASM_DATA);
2371}
2372SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2373{
2374 A = operand;
2375 notZ = A;
2376 N = A & 0x80;
2377}
2378break;
2379
2380case 0xb5:
2381{
2382 intermediateAddress = peek(PC++, DISASM_CODE);
2383 peek(intermediateAddress, DISASM_NONE);
2384 intermediateAddress += X;
2385 operand = peek(intermediateAddress, DISASM_DATA);
2386}
2387SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2388{
2389 A = operand;
2390 notZ = A;
2391 N = A & 0x80;
2392}
2393break;
2394
2395case 0xad:
2396{
2397 intermediateAddress = peek(PC++, DISASM_CODE);
2398 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2399 operand = peek(intermediateAddress, DISASM_DATA);
2400}
2401SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2402{
2403 A = operand;
2404 notZ = A;
2405 N = A & 0x80;
2406}
2407break;
2408
2409case 0xbd:
2410{
2411 uInt16 low = peek(PC++, DISASM_CODE);
2412 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2413 intermediateAddress = high | uInt8(low + X);
2414 if((low + X) > 0xFF)
2415 {
2416 operand = peek(intermediateAddress, DISASM_NONE);
2417 intermediateAddress = (high | low) + X;
2418 operand = peek(intermediateAddress, DISASM_DATA);
2419 }
2420 else
2421 {
2422 operand = peek(intermediateAddress, DISASM_DATA);
2423 }
2424}
2425SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2426{
2427 A = operand;
2428 notZ = A;
2429 N = A & 0x80;
2430}
2431break;
2432
2433case 0xb9:
2434{
2435 uInt16 low = peek(PC++, DISASM_CODE);
2436 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2437 intermediateAddress = high | uInt8(low + Y);
2438 if((low + Y) > 0xFF)
2439 {
2440 operand = peek(intermediateAddress, DISASM_NONE);
2441 intermediateAddress = (high | low) + Y;
2442 operand = peek(intermediateAddress, DISASM_DATA);
2443 }
2444 else
2445 {
2446 operand = peek(intermediateAddress, DISASM_DATA);
2447 }
2448}
2449SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2450{
2451 A = operand;
2452 notZ = A;
2453 N = A & 0x80;
2454}
2455break;
2456
2457case 0xa1:
2458{
2459 uInt8 pointer = peek(PC++, DISASM_CODE);
2460 peek(pointer, DISASM_NONE);
2461 pointer += X;
2462 intermediateAddress = peek(pointer++, DISASM_DATA);
2463 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
2464 operand = peek(intermediateAddress, DISASM_DATA);
2465}
2466SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2467{
2468 A = operand;
2469 notZ = A;
2470 N = A & 0x80;
2471}
2472break;
2473
2474case 0xb1:
2475{
2476 uInt8 pointer = peek(PC++, DISASM_CODE);
2477 uInt16 low = peek(pointer++, DISASM_DATA);
2478 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
2479 intermediateAddress = high | uInt8(low + Y);
2480 if((low + Y) > 0xFF)
2481 {
2482 operand = peek(intermediateAddress, DISASM_NONE);
2483 intermediateAddress = (high | low) + Y;
2484 operand = peek(intermediateAddress, DISASM_DATA);
2485 }
2486 else
2487 {
2488 operand = peek(intermediateAddress, DISASM_DATA);
2489 }
2490}
2491SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2492{
2493 A = operand;
2494 notZ = A;
2495 N = A & 0x80;
2496}
2497break;
2498//////////////////////////////////////////////////
2499
2500
2501//////////////////////////////////////////////////
2502// LDX
2503case 0xa2:
2504{
2505 operand = peek(PC++, DISASM_CODE);
2506}
2507CLEAR_LAST_PEEK(myLastSrcAddressX)
2508{
2509 X = operand;
2510 notZ = X;
2511 N = X & 0x80;
2512}
2513break;
2514
2515case 0xa6:
2516{
2517 intermediateAddress = peek(PC++, DISASM_CODE);
2518 operand = peek(intermediateAddress, DISASM_DATA);
2519}
2520SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2521{
2522 X = operand;
2523 notZ = X;
2524 N = X & 0x80;
2525}
2526break;
2527
2528case 0xb6:
2529{
2530 intermediateAddress = peek(PC++, DISASM_CODE);
2531 peek(intermediateAddress, DISASM_NONE);
2532 intermediateAddress += Y;
2533 operand = peek(intermediateAddress, DISASM_DATA);
2534}
2535SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2536{
2537 X = operand;
2538 notZ = X;
2539 N = X & 0x80;
2540}
2541break;
2542
2543case 0xae:
2544{
2545 intermediateAddress = peek(PC++, DISASM_CODE);
2546 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2547 operand = peek(intermediateAddress, DISASM_DATA);
2548}
2549SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2550{
2551 X = operand;
2552 notZ = X;
2553 N = X & 0x80;
2554}
2555break;
2556
2557case 0xbe:
2558{
2559 uInt16 low = peek(PC++, DISASM_CODE);
2560 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2561 intermediateAddress = high | uInt8(low + Y);
2562 if((low + Y) > 0xFF)
2563 {
2564 operand = peek(intermediateAddress, DISASM_NONE);
2565 intermediateAddress = (high | low) + Y;
2566 operand = peek(intermediateAddress, DISASM_DATA);
2567 }
2568 else
2569 {
2570 operand = peek(intermediateAddress, DISASM_DATA);
2571 }
2572}
2573SET_LAST_PEEK(myLastSrcAddressX, intermediateAddress)
2574{
2575 X = operand;
2576 notZ = X;
2577 N = X & 0x80;
2578}
2579break;
2580//////////////////////////////////////////////////
2581
2582
2583//////////////////////////////////////////////////
2584// LDY
2585case 0xa0:
2586{
2587 operand = peek(PC++, DISASM_CODE);
2588}
2589CLEAR_LAST_PEEK(myLastSrcAddressY)
2590{
2591 Y = operand;
2592 notZ = Y;
2593 N = Y & 0x80;
2594}
2595break;
2596
2597case 0xa4:
2598{
2599 intermediateAddress = peek(PC++, DISASM_CODE);
2600 operand = peek(intermediateAddress, DISASM_DATA);
2601}
2602SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress)
2603{
2604 Y = operand;
2605 notZ = Y;
2606 N = Y & 0x80;
2607}
2608break;
2609
2610case 0xb4:
2611{
2612 intermediateAddress = peek(PC++, DISASM_CODE);
2613 peek(intermediateAddress, DISASM_NONE);
2614 intermediateAddress += X;
2615 operand = peek(intermediateAddress, DISASM_DATA);
2616}
2617SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress)
2618{
2619 Y = operand;
2620 notZ = Y;
2621 N = Y & 0x80;
2622}
2623break;
2624
2625case 0xac:
2626{
2627 intermediateAddress = peek(PC++, DISASM_CODE);
2628 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2629 operand = peek(intermediateAddress, DISASM_DATA);
2630}
2631SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress)
2632{
2633 Y = operand;
2634 notZ = Y;
2635 N = Y & 0x80;
2636}
2637break;
2638
2639case 0xbc:
2640{
2641 uInt16 low = peek(PC++, DISASM_CODE);
2642 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2643 intermediateAddress = high | uInt8(low + X);
2644 if((low + X) > 0xFF)
2645 {
2646 operand = peek(intermediateAddress, DISASM_NONE);
2647 intermediateAddress = (high | low) + X;
2648 operand = peek(intermediateAddress, DISASM_DATA);
2649 }
2650 else
2651 {
2652 operand = peek(intermediateAddress, DISASM_DATA);
2653 }
2654}
2655SET_LAST_PEEK(myLastSrcAddressY, intermediateAddress)
2656{
2657 Y = operand;
2658 notZ = Y;
2659 N = Y & 0x80;
2660}
2661break;
2662//////////////////////////////////////////////////
2663
2664//////////////////////////////////////////////////
2665// LSR
2666case 0x4a:
2667{
2668 peek(PC, DISASM_NONE);
2669}
2670{
2671 // Set carry flag according to the right-most bit
2672 C = A & 0x01;
2673
2674 A >>= 1;
2675
2676 notZ = A;
2677 N = false;
2678}
2679break;
2680
2681
2682case 0x46:
2683{
2684 operandAddress = peek(PC++, DISASM_CODE);
2685 operand = peek(operandAddress, DISASM_DATA);
2686 poke(operandAddress, operand, DISASM_WRITE);
2687}
2688{
2689 // Set carry flag according to the right-most bit in value
2690 C = operand & 0x01;
2691
2692 operand >>= 1;
2693 poke(operandAddress, operand, DISASM_WRITE);
2694
2695 notZ = operand;
2696 N = false;
2697}
2698break;
2699
2700case 0x56:
2701{
2702 operandAddress = peek(PC++, DISASM_CODE);
2703 peek(operandAddress, DISASM_NONE);
2704 operandAddress = (operandAddress + X) & 0xFF;
2705 operand = peek(operandAddress, DISASM_DATA);
2706 poke(operandAddress, operand, DISASM_WRITE);
2707}
2708{
2709 // Set carry flag according to the right-most bit in value
2710 C = operand & 0x01;
2711
2712 operand >>= 1;
2713 poke(operandAddress, operand, DISASM_WRITE);
2714
2715 notZ = operand;
2716 N = false;
2717}
2718break;
2719
2720case 0x4e:
2721{
2722 operandAddress = peek(PC++, DISASM_CODE);
2723 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2724 operand = peek(operandAddress, DISASM_DATA);
2725 poke(operandAddress, operand, DISASM_WRITE);
2726}
2727{
2728 // Set carry flag according to the right-most bit in value
2729 C = operand & 0x01;
2730
2731 operand >>= 1;
2732 poke(operandAddress, operand, DISASM_WRITE);
2733
2734 notZ = operand;
2735 N = false;
2736}
2737break;
2738
2739case 0x5e:
2740{
2741 uInt16 low = peek(PC++, DISASM_CODE);
2742 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2743 peek(high | uInt8(low + X), DISASM_NONE);
2744 operandAddress = (high | low) + X;
2745 operand = peek(operandAddress, DISASM_DATA);
2746 poke(operandAddress, operand, DISASM_WRITE);
2747}
2748{
2749 // Set carry flag according to the right-most bit in value
2750 C = operand & 0x01;
2751
2752 operand >>= 1;
2753 poke(operandAddress, operand, DISASM_WRITE);
2754
2755 notZ = operand;
2756 N = false;
2757}
2758break;
2759
2760//////////////////////////////////////////////////
2761// LXA
2762case 0xab:
2763{
2764 operand = peek(PC++, DISASM_CODE);
2765}
2766{
2767 // NOTE: The implementation of this instruction is based on
2768 // information from the 64doc.txt file. This instruction is
2769 // reported to be very unstable!
2770 A = X = (A | 0xee) & operand;
2771 notZ = A;
2772 N = A & 0x80;
2773}
2774break;
2775
2776//////////////////////////////////////////////////
2777// NOP
2778case 0x1a:
2779case 0x3a:
2780case 0x5a:
2781case 0x7a:
2782case 0xda:
2783case 0xea:
2784case 0xfa:
2785{
2786 peek(PC, DISASM_NONE);
2787}
2788{
2789}
2790break;
2791
2792case 0x80:
2793case 0x82:
2794case 0x89:
2795case 0xc2:
2796case 0xe2:
2797{
2798 operand = peek(PC++, DISASM_CODE);
2799}
2800{
2801}
2802break;
2803
2804case 0x04:
2805case 0x44:
2806case 0x64:
2807{
2808 intermediateAddress = peek(PC++, DISASM_CODE);
2809 operand = peek(intermediateAddress, DISASM_DATA);
2810}
2811{
2812}
2813break;
2814
2815case 0x14:
2816case 0x34:
2817case 0x54:
2818case 0x74:
2819case 0xd4:
2820case 0xf4:
2821{
2822 intermediateAddress = peek(PC++, DISASM_CODE);
2823 peek(intermediateAddress, DISASM_NONE);
2824 intermediateAddress += X;
2825 operand = peek(intermediateAddress, DISASM_DATA);
2826}
2827{
2828}
2829break;
2830
2831case 0x0c:
2832{
2833 intermediateAddress = peek(PC++, DISASM_CODE);
2834 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2835 operand = peek(intermediateAddress, DISASM_DATA);
2836}
2837{
2838}
2839break;
2840
2841case 0x1c:
2842case 0x3c:
2843case 0x5c:
2844case 0x7c:
2845case 0xdc:
2846case 0xfc:
2847{
2848 uInt16 low = peek(PC++, DISASM_CODE);
2849 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2850 intermediateAddress = high | uInt8(low + X);
2851 if((low + X) > 0xFF)
2852 {
2853 operand = peek(intermediateAddress, DISASM_NONE);
2854 intermediateAddress = (high | low) + X;
2855 operand = peek(intermediateAddress, DISASM_DATA);
2856 }
2857 else
2858 {
2859 operand = peek(intermediateAddress, DISASM_DATA);
2860 }
2861}
2862{
2863}
2864break;
2865
2866
2867//////////////////////////////////////////////////
2868// ORA
2869case 0x09:
2870{
2871 operand = peek(PC++, DISASM_CODE);
2872}
2873CLEAR_LAST_PEEK(myLastSrcAddressA)
2874{
2875 A |= operand;
2876 notZ = A;
2877 N = A & 0x80;
2878}
2879break;
2880
2881case 0x05:
2882{
2883 intermediateAddress = peek(PC++, DISASM_CODE);
2884 operand = peek(intermediateAddress, DISASM_DATA);
2885}
2886SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2887{
2888 A |= operand;
2889 notZ = A;
2890 N = A & 0x80;
2891}
2892break;
2893
2894case 0x15:
2895{
2896 intermediateAddress = peek(PC++, DISASM_CODE);
2897 peek(intermediateAddress, DISASM_NONE);
2898 intermediateAddress += X;
2899 operand = peek(intermediateAddress, DISASM_DATA);
2900}
2901SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2902{
2903 A |= operand;
2904 notZ = A;
2905 N = A & 0x80;
2906}
2907break;
2908
2909case 0x0d:
2910{
2911 intermediateAddress = peek(PC++, DISASM_CODE);
2912 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
2913 operand = peek(intermediateAddress, DISASM_DATA);
2914}
2915SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2916{
2917 A |= operand;
2918 notZ = A;
2919 N = A & 0x80;
2920}
2921break;
2922
2923case 0x1d:
2924{
2925 uInt16 low = peek(PC++, DISASM_CODE);
2926 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2927 intermediateAddress = high | uInt8(low + X);
2928 if((low + X) > 0xFF)
2929 {
2930 operand = peek(intermediateAddress, DISASM_NONE);
2931 intermediateAddress = (high | low) + X;
2932 operand = peek(intermediateAddress, DISASM_DATA);
2933 }
2934 else
2935 {
2936 operand = peek(intermediateAddress, DISASM_DATA);
2937 }
2938}
2939SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2940{
2941 A |= operand;
2942 notZ = A;
2943 N = A & 0x80;
2944}
2945break;
2946
2947case 0x19:
2948{
2949 uInt16 low = peek(PC++, DISASM_CODE);
2950 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
2951 intermediateAddress = high | uInt8(low + Y);
2952 if((low + Y) > 0xFF)
2953 {
2954 operand = peek(intermediateAddress, DISASM_NONE);
2955 intermediateAddress = (high | low) + Y;
2956 operand = peek(intermediateAddress, DISASM_DATA);
2957 }
2958 else
2959 {
2960 operand = peek(intermediateAddress, DISASM_DATA);
2961 }
2962}
2963SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2964{
2965 A |= operand;
2966 notZ = A;
2967 N = A & 0x80;
2968}
2969break;
2970
2971case 0x01:
2972{
2973 uInt8 pointer = peek(PC++, DISASM_CODE);
2974 peek(pointer, DISASM_NONE);
2975 pointer += X;
2976 intermediateAddress = peek(pointer++, DISASM_DATA);
2977 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
2978 operand = peek(intermediateAddress, DISASM_DATA);
2979}
2980SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
2981{
2982 A |= operand;
2983 notZ = A;
2984 N = A & 0x80;
2985}
2986break;
2987
2988case 0x11:
2989{
2990 uInt8 pointer = peek(PC++, DISASM_CODE);
2991 uInt16 low = peek(pointer++, DISASM_DATA);
2992 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
2993 intermediateAddress = high | uInt8(low + Y);
2994 if((low + Y) > 0xFF)
2995 {
2996 operand = peek(intermediateAddress, DISASM_NONE);
2997 intermediateAddress = (high | low) + Y;
2998 operand = peek(intermediateAddress, DISASM_DATA);
2999 }
3000 else
3001 {
3002 operand = peek(intermediateAddress, DISASM_DATA);
3003 }
3004}
3005SET_LAST_PEEK(myLastSrcAddressA, intermediateAddress)
3006{
3007 A |= operand;
3008 notZ = A;
3009 N = A & 0x80;
3010}
3011break;
3012//////////////////////////////////////////////////
3013
3014//////////////////////////////////////////////////
3015// PHA
3016case 0x48:
3017{
3018 peek(PC, DISASM_NONE);
3019}
3020SET_LAST_POKE(myLastSrcAddressA)
3021{
3022 poke(0x0100 + SP--, A, DISASM_WRITE);
3023}
3024break;
3025
3026//////////////////////////////////////////////////
3027// PHP
3028case 0x08:
3029{
3030 peek(PC, DISASM_NONE);
3031}
3032// TODO - add tracking for this opcode
3033{
3034 poke(0x0100 + SP--, PS(), DISASM_WRITE);
3035}
3036break;
3037
3038//////////////////////////////////////////////////
3039// PLA
3040case 0x68:
3041{
3042 peek(PC, DISASM_NONE);
3043}
3044// TODO - add tracking for this opcode
3045{
3046 peek(0x0100 + SP++, DISASM_NONE);
3047 A = peek(0x0100 + SP, DISASM_DATA);
3048 notZ = A;
3049 N = A & 0x80;
3050}
3051break;
3052
3053//////////////////////////////////////////////////
3054// PLP
3055case 0x28:
3056{
3057 peek(PC, DISASM_NONE);
3058}
3059// TODO - add tracking for this opcode
3060{
3061 peek(0x0100 + SP++, DISASM_NONE);
3062 PS(peek(0x0100 + SP, DISASM_DATA));
3063}
3064break;
3065
3066//////////////////////////////////////////////////
3067// RLA
3068case 0x2f:
3069{
3070 operandAddress = peek(PC++, DISASM_CODE);
3071 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
3072 operand = peek(operandAddress, DISASM_DATA);
3073 poke(operandAddress, operand, DISASM_WRITE);
3074}
3075{
3076 uInt8 value = (operand << 1) | (C ? 1 : 0);
3077 poke(operandAddress, value, DISASM_WRITE);
3078
3079 A &= value;
3080 C = operand & 0x80;
3081 notZ = A;
3082 N = A & 0x80;
3083}
3084break;
3085
3086case 0x3f:
3087{
3088 uInt16 low = peek(PC++, DISASM_CODE);
3089 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3090 peek(high | uInt8(low + X), DISASM_NONE);
3091 operandAddress = (high | low) + X;
3092 operand = peek(operandAddress, DISASM_DATA);
3093 poke(operandAddress, operand, DISASM_WRITE);
3094}
3095{
3096 uInt8 value = (operand << 1) | (C ? 1 : 0);
3097 poke(operandAddress, value, DISASM_WRITE);
3098
3099 A &= value;
3100 C = operand & 0x80;
3101 notZ = A;
3102 N = A & 0x80;
3103}
3104break;
3105
3106case 0x3b:
3107{
3108 uInt16 low = peek(PC++, DISASM_CODE);
3109 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3110 peek(high | uInt8(low + Y), DISASM_NONE);
3111 operandAddress = (high | low) + Y;
3112 operand = peek(operandAddress, DISASM_DATA);
3113 poke(operandAddress, operand, DISASM_WRITE);
3114}
3115{
3116 uInt8 value = (operand << 1) | (C ? 1 : 0);
3117 poke(operandAddress, value, DISASM_WRITE);
3118
3119 A &= value;
3120 C = operand & 0x80;
3121 notZ = A;
3122 N = A & 0x80;
3123}
3124break;
3125
3126case 0x27:
3127{
3128 operandAddress = peek(PC++, DISASM_CODE);
3129 operand = peek(operandAddress, DISASM_DATA);
3130 poke(operandAddress, operand, DISASM_WRITE);
3131}
3132{
3133 uInt8 value = (operand << 1) | (C ? 1 : 0);
3134 poke(operandAddress, value, DISASM_WRITE);
3135
3136 A &= value;
3137 C = operand & 0x80;
3138 notZ = A;
3139 N = A & 0x80;
3140}
3141break;
3142
3143case 0x37:
3144{
3145 operandAddress = peek(PC++, DISASM_CODE);
3146 peek(operandAddress, DISASM_NONE);
3147 operandAddress = (operandAddress + X) & 0xFF;
3148 operand = peek(operandAddress, DISASM_DATA);
3149 poke(operandAddress, operand, DISASM_WRITE);
3150}
3151{
3152 uInt8 value = (operand << 1) | (C ? 1 : 0);
3153 poke(operandAddress, value, DISASM_WRITE);
3154
3155 A &= value;
3156 C = operand & 0x80;
3157 notZ = A;
3158 N = A & 0x80;
3159}
3160break;
3161
3162case 0x23:
3163{
3164 uInt8 pointer = peek(PC++, DISASM_CODE);
3165 peek(pointer, DISASM_NONE);
3166 pointer += X;
3167 operandAddress = peek(pointer++, DISASM_DATA);
3168 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
3169 operand = peek(operandAddress, DISASM_DATA);
3170 poke(operandAddress, operand, DISASM_WRITE);
3171}
3172{
3173 uInt8 value = (operand << 1) | (C ? 1 : 0);
3174 poke(operandAddress, value, DISASM_WRITE);
3175
3176 A &= value;
3177 C = operand & 0x80;
3178 notZ = A;
3179 N = A & 0x80;
3180}
3181break;
3182
3183case 0x33:
3184{
3185 uInt8 pointer = peek(PC++, DISASM_CODE);
3186 uInt16 low = peek(pointer++, DISASM_DATA);
3187 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
3188 peek(high | uInt8(low + Y), DISASM_NONE);
3189 operandAddress = (high | low) + Y;
3190 operand = peek(operandAddress, DISASM_DATA);
3191 poke(operandAddress, operand, DISASM_WRITE);
3192}
3193{
3194 uInt8 value = (operand << 1) | (C ? 1 : 0);
3195 poke(operandAddress, value, DISASM_WRITE);
3196
3197 A &= value;
3198 C = operand & 0x80;
3199 notZ = A;
3200 N = A & 0x80;
3201}
3202break;
3203
3204//////////////////////////////////////////////////
3205// ROL
3206case 0x2a:
3207{
3208 peek(PC, DISASM_NONE);
3209}
3210{
3211 bool oldC = C;
3212
3213 // Set carry flag according to the left-most bit
3214 C = A & 0x80;
3215
3216 A = (A << 1) | (oldC ? 1 : 0);
3217
3218 notZ = A;
3219 N = A & 0x80;
3220}
3221break;
3222
3223case 0x26:
3224{
3225 operandAddress = peek(PC++, DISASM_CODE);
3226 operand = peek(operandAddress, DISASM_DATA);
3227 poke(operandAddress, operand, DISASM_WRITE);
3228}
3229{
3230 bool oldC = C;
3231
3232 // Set carry flag according to the left-most bit in operand
3233 C = operand & 0x80;
3234
3235 operand = (operand << 1) | (oldC ? 1 : 0);
3236 poke(operandAddress, operand, DISASM_WRITE);
3237
3238 notZ = operand;
3239 N = operand & 0x80;
3240}
3241break;
3242
3243case 0x36:
3244{
3245 operandAddress = peek(PC++, DISASM_CODE);
3246 peek(operandAddress, DISASM_NONE);
3247 operandAddress = (operandAddress + X) & 0xFF;
3248 operand = peek(operandAddress, DISASM_DATA);
3249 poke(operandAddress, operand, DISASM_WRITE);
3250}
3251{
3252 bool oldC = C;
3253
3254 // Set carry flag according to the left-most bit in operand
3255 C = operand & 0x80;
3256
3257 operand = (operand << 1) | (oldC ? 1 : 0);
3258 poke(operandAddress, operand, DISASM_WRITE);
3259
3260 notZ = operand;
3261 N = operand & 0x80;
3262}
3263break;
3264
3265case 0x2e:
3266{
3267 operandAddress = peek(PC++, DISASM_CODE);
3268 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
3269 operand = peek(operandAddress, DISASM_DATA);
3270 poke(operandAddress, operand, DISASM_WRITE);
3271}
3272{
3273 bool oldC = C;
3274
3275 // Set carry flag according to the left-most bit in operand
3276 C = operand & 0x80;
3277
3278 operand = (operand << 1) | (oldC ? 1 : 0);
3279 poke(operandAddress, operand, DISASM_WRITE);
3280
3281 notZ = operand;
3282 N = operand & 0x80;
3283}
3284break;
3285
3286case 0x3e:
3287{
3288 uInt16 low = peek(PC++, DISASM_CODE);
3289 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3290 peek(high | uInt8(low + X), DISASM_NONE);
3291 operandAddress = (high | low) + X;
3292 operand = peek(operandAddress, DISASM_DATA);
3293 poke(operandAddress, operand, DISASM_WRITE);
3294}
3295{
3296 bool oldC = C;
3297
3298 // Set carry flag according to the left-most bit in operand
3299 C = operand & 0x80;
3300
3301 operand = (operand << 1) | (oldC ? 1 : 0);
3302 poke(operandAddress, operand, DISASM_WRITE);
3303
3304 notZ = operand;
3305 N = operand & 0x80;
3306}
3307break;
3308
3309//////////////////////////////////////////////////
3310// ROR
3311case 0x6a:
3312{
3313 peek(PC, DISASM_NONE);
3314}
3315{
3316 bool oldC = C;
3317
3318 // Set carry flag according to the right-most bit
3319 C = A & 0x01;
3320
3321 A = ((A >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3322
3323 notZ = A;
3324 N = A & 0x80;
3325}
3326break;
3327
3328case 0x66:
3329{
3330 operandAddress = peek(PC++, DISASM_CODE);
3331 operand = peek(operandAddress, DISASM_DATA);
3332 poke(operandAddress, operand, DISASM_WRITE);
3333}
3334{
3335 bool oldC = C;
3336
3337 // Set carry flag according to the right-most bit
3338 C = operand & 0x01;
3339
3340 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3341 poke(operandAddress, operand, DISASM_WRITE);
3342
3343 notZ = operand;
3344 N = operand & 0x80;
3345}
3346break;
3347
3348case 0x76:
3349{
3350 operandAddress = peek(PC++, DISASM_CODE);
3351 peek(operandAddress, DISASM_NONE);
3352 operandAddress = (operandAddress + X) & 0xFF;
3353 operand = peek(operandAddress, DISASM_DATA);
3354 poke(operandAddress, operand, DISASM_WRITE);
3355}
3356{
3357 bool oldC = C;
3358
3359 // Set carry flag according to the right-most bit
3360 C = operand & 0x01;
3361
3362 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3363 poke(operandAddress, operand, DISASM_WRITE);
3364
3365 notZ = operand;
3366 N = operand & 0x80;
3367}
3368break;
3369
3370case 0x6e:
3371{
3372 operandAddress = peek(PC++, DISASM_CODE);
3373 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
3374 operand = peek(operandAddress, DISASM_DATA);
3375 poke(operandAddress, operand, DISASM_WRITE);
3376}
3377{
3378 bool oldC = C;
3379
3380 // Set carry flag according to the right-most bit
3381 C = operand & 0x01;
3382
3383 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3384 poke(operandAddress, operand, DISASM_WRITE);
3385
3386 notZ = operand;
3387 N = operand & 0x80;
3388}
3389break;
3390
3391case 0x7e:
3392{
3393 uInt16 low = peek(PC++, DISASM_CODE);
3394 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3395 peek(high | uInt8(low + X), DISASM_NONE);
3396 operandAddress = (high | low) + X;
3397 operand = peek(operandAddress, DISASM_DATA);
3398 poke(operandAddress, operand, DISASM_WRITE);
3399}
3400{
3401 bool oldC = C;
3402
3403 // Set carry flag according to the right-most bit
3404 C = operand & 0x01;
3405
3406 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3407 poke(operandAddress, operand, DISASM_WRITE);
3408
3409 notZ = operand;
3410 N = operand & 0x80;
3411}
3412break;
3413
3414//////////////////////////////////////////////////
3415// RRA
3416case 0x6f:
3417{
3418 operandAddress = peek(PC++, DISASM_CODE);
3419 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
3420 operand = peek(operandAddress, DISASM_DATA);
3421 poke(operandAddress, operand, DISASM_WRITE);
3422}
3423{
3424 bool oldC = C;
3425
3426 // Set carry flag according to the right-most bit
3427 C = operand & 0x01;
3428
3429 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3430 poke(operandAddress, operand, DISASM_WRITE);
3431
3432 if(!D)
3433 {
3434 Int32 sum = A + operand + (C ? 1 : 0);
3435 N = sum & 0x80;
3436 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3437 notZ = sum & 0xff;
3438 C = sum & 0xff00;
3439
3440 A = uInt8(sum);
3441 }
3442 else
3443 {
3444 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3445 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3446 notZ = (lo+hi) & 0xff;
3447 if(lo > 0x09)
3448 {
3449 hi += 0x10;
3450 lo += 0x06;
3451 }
3452 N = hi & 0x80;
3453 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3454 if(hi > 0x90)
3455 hi += 0x60;
3456 C = hi & 0xff00;
3457
3458 A = (lo & 0x0f) + (hi & 0xf0);
3459 }
3460}
3461break;
3462
3463case 0x7f:
3464{
3465 uInt16 low = peek(PC++, DISASM_CODE);
3466 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3467 peek(high | uInt8(low + X), DISASM_NONE);
3468 operandAddress = (high | low) + X;
3469 operand = peek(operandAddress, DISASM_DATA);
3470 poke(operandAddress, operand, DISASM_WRITE);
3471}
3472{
3473 bool oldC = C;
3474
3475 // Set carry flag according to the right-most bit
3476 C = operand & 0x01;
3477
3478 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3479 poke(operandAddress, operand, DISASM_WRITE);
3480
3481 if(!D)
3482 {
3483 Int32 sum = A + operand + (C ? 1 : 0);
3484 N = sum & 0x80;
3485 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3486 notZ = sum & 0xff;
3487 C = sum & 0xff00;
3488
3489 A = uInt8(sum);
3490 }
3491 else
3492 {
3493 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3494 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3495 notZ = (lo+hi) & 0xff;
3496 if(lo > 0x09)
3497 {
3498 hi += 0x10;
3499 lo += 0x06;
3500 }
3501 N = hi & 0x80;
3502 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3503 if(hi > 0x90)
3504 hi += 0x60;
3505 C = hi & 0xff00;
3506
3507 A = (lo & 0x0f) + (hi & 0xf0);
3508 }
3509}
3510break;
3511
3512case 0x7b:
3513{
3514 uInt16 low = peek(PC++, DISASM_CODE);
3515 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3516 peek(high | uInt8(low + Y), DISASM_NONE);
3517 operandAddress = (high | low) + Y;
3518 operand = peek(operandAddress, DISASM_DATA);
3519 poke(operandAddress, operand, DISASM_WRITE);
3520}
3521{
3522 bool oldC = C;
3523
3524 // Set carry flag according to the right-most bit
3525 C = operand & 0x01;
3526
3527 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3528 poke(operandAddress, operand, DISASM_WRITE);
3529
3530 if(!D)
3531 {
3532 Int32 sum = A + operand + (C ? 1 : 0);
3533 N = sum & 0x80;
3534 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3535 notZ = sum & 0xff;
3536 C = sum & 0xff00;
3537
3538 A = uInt8(sum);
3539 }
3540 else
3541 {
3542 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3543 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3544 notZ = (lo+hi) & 0xff;
3545 if(lo > 0x09)
3546 {
3547 hi += 0x10;
3548 lo += 0x06;
3549 }
3550 N = hi & 0x80;
3551 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3552 if(hi > 0x90)
3553 hi += 0x60;
3554 C = hi & 0xff00;
3555
3556 A = (lo & 0x0f) + (hi & 0xf0);
3557 }
3558}
3559break;
3560
3561case 0x67:
3562{
3563 operandAddress = peek(PC++, DISASM_CODE);
3564 operand = peek(operandAddress, DISASM_DATA);
3565 poke(operandAddress, operand, DISASM_WRITE);
3566}
3567{
3568 bool oldC = C;
3569
3570 // Set carry flag according to the right-most bit
3571 C = operand & 0x01;
3572
3573 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3574 poke(operandAddress, operand, DISASM_WRITE);
3575
3576 if(!D)
3577 {
3578 Int32 sum = A + operand + (C ? 1 : 0);
3579 N = sum & 0x80;
3580 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3581 notZ = sum & 0xff;
3582 C = sum & 0xff00;
3583
3584 A = uInt8(sum);
3585 }
3586 else
3587 {
3588 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3589 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3590 notZ = (lo+hi) & 0xff;
3591 if(lo > 0x09)
3592 {
3593 hi += 0x10;
3594 lo += 0x06;
3595 }
3596 N = hi & 0x80;
3597 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3598 if(hi > 0x90)
3599 hi += 0x60;
3600 C = hi & 0xff00;
3601
3602 A = (lo & 0x0f) + (hi & 0xf0);
3603 }
3604}
3605break;
3606
3607case 0x77:
3608{
3609 operandAddress = peek(PC++, DISASM_CODE);
3610 peek(operandAddress, DISASM_NONE);
3611 operandAddress = (operandAddress + X) & 0xFF;
3612 operand = peek(operandAddress, DISASM_DATA);
3613 poke(operandAddress, operand, DISASM_WRITE);
3614}
3615{
3616 bool oldC = C;
3617
3618 // Set carry flag according to the right-most bit
3619 C = operand & 0x01;
3620
3621 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3622 poke(operandAddress, operand, DISASM_WRITE);
3623
3624 if(!D)
3625 {
3626 Int32 sum = A + operand + (C ? 1 : 0);
3627 N = sum & 0x80;
3628 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3629 notZ = sum & 0xff;
3630 C = sum & 0xff00;
3631
3632 A = uInt8(sum);
3633 }
3634 else
3635 {
3636 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3637 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3638 notZ = (lo+hi) & 0xff;
3639 if(lo > 0x09)
3640 {
3641 hi += 0x10;
3642 lo += 0x06;
3643 }
3644 N = hi & 0x80;
3645 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3646 if(hi > 0x90)
3647 hi += 0x60;
3648 C = hi & 0xff00;
3649
3650 A = (lo & 0x0f) + (hi & 0xf0);
3651 }
3652}
3653break;
3654
3655case 0x63:
3656{
3657 uInt8 pointer = peek(PC++, DISASM_CODE);
3658 peek(pointer, DISASM_NONE);
3659 pointer += X;
3660 operandAddress = peek(pointer++, DISASM_DATA);
3661 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
3662 operand = peek(operandAddress, DISASM_DATA);
3663 poke(operandAddress, operand, DISASM_WRITE);
3664}
3665{
3666 bool oldC = C;
3667
3668 // Set carry flag according to the right-most bit
3669 C = operand & 0x01;
3670
3671 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3672 poke(operandAddress, operand, DISASM_WRITE);
3673
3674 if(!D)
3675 {
3676 Int32 sum = A + operand + (C ? 1 : 0);
3677 N = sum & 0x80;
3678 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3679 notZ = sum & 0xff;
3680 C = sum & 0xff00;
3681
3682 A = uInt8(sum);
3683 }
3684 else
3685 {
3686 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3687 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3688 notZ = (lo+hi) & 0xff;
3689 if(lo > 0x09)
3690 {
3691 hi += 0x10;
3692 lo += 0x06;
3693 }
3694 N = hi & 0x80;
3695 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3696 if(hi > 0x90)
3697 hi += 0x60;
3698 C = hi & 0xff00;
3699
3700 A = (lo & 0x0f) + (hi & 0xf0);
3701 }
3702}
3703break;
3704
3705case 0x73:
3706{
3707 uInt8 pointer = peek(PC++, DISASM_CODE);
3708 uInt16 low = peek(pointer++, DISASM_DATA);
3709 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
3710 peek(high | uInt8(low + Y), DISASM_NONE);
3711 operandAddress = (high | low) + Y;
3712 operand = peek(operandAddress, DISASM_DATA);
3713 poke(operandAddress, operand, DISASM_WRITE);
3714}
3715{
3716 bool oldC = C;
3717
3718 // Set carry flag according to the right-most bit
3719 C = operand & 0x01;
3720
3721 operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
3722 poke(operandAddress, operand, DISASM_WRITE);
3723
3724 if(!D)
3725 {
3726 Int32 sum = A + operand + (C ? 1 : 0);
3727 N = sum & 0x80;
3728 V = ~(A ^ operand) & (A ^ sum) & 0x80;
3729 notZ = sum & 0xff;
3730 C = sum & 0xff00;
3731
3732 A = uInt8(sum);
3733 }
3734 else
3735 {
3736 Int32 lo = (A & 0x0f) + (operand & 0x0f) + (C ? 1 : 0);
3737 Int32 hi = (A & 0xf0) + (operand & 0xf0);
3738 notZ = (lo+hi) & 0xff;
3739 if(lo > 0x09)
3740 {
3741 hi += 0x10;
3742 lo += 0x06;
3743 }
3744 N = hi & 0x80;
3745 V = ~(A ^ operand) & (A ^ hi) & 0x80;
3746 if(hi > 0x90)
3747 hi += 0x60;
3748 C = hi & 0xff00;
3749
3750 A = (lo & 0x0f) + (hi & 0xf0);
3751 }
3752}
3753break;
3754
3755//////////////////////////////////////////////////
3756// RTI
3757case 0x40:
3758{
3759 peek(PC, DISASM_NONE);
3760}
3761{
3762 peek(0x0100 + SP++, DISASM_NONE);
3763 PS(peek(0x0100 + SP++, DISASM_NONE));
3764 PC = peek(0x0100 + SP++, DISASM_NONE);
3765 PC |= (uInt16(peek(0x0100 + SP, DISASM_NONE)) << 8);
3766}
3767break;
3768
3769//////////////////////////////////////////////////
3770// RTS
3771case 0x60:
3772{
3773 peek(PC, DISASM_NONE);
3774}
3775{
3776 peek(0x0100 + SP++, DISASM_NONE);
3777 PC = peek(0x0100 + SP++, DISASM_NONE);
3778 PC |= (uInt16(peek(0x0100 + SP, DISASM_NONE)) << 8);
3779 peek(PC++, DISASM_NONE);
3780}
3781break;
3782
3783//////////////////////////////////////////////////
3784// SAX
3785case 0x8f:
3786{
3787 operandAddress = peek(PC++, DISASM_CODE);
3788 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
3789}
3790{
3791 poke(operandAddress, A & X, DISASM_WRITE);
3792}
3793break;
3794
3795case 0x87:
3796{
3797 operandAddress = peek(PC++, DISASM_CODE);
3798}
3799{
3800 poke(operandAddress, A & X, DISASM_WRITE);
3801}
3802break;
3803
3804case 0x97:
3805{
3806 operandAddress = peek(PC++, DISASM_CODE);
3807 peek(operandAddress, DISASM_NONE);
3808 operandAddress = (operandAddress + Y) & 0xFF;
3809}
3810{
3811 poke(operandAddress, A & X, DISASM_WRITE);
3812}
3813break;
3814
3815case 0x83:
3816{
3817 uInt8 pointer = peek(PC++, DISASM_CODE);
3818 peek(pointer, DISASM_NONE);
3819 pointer += X;
3820 operandAddress = peek(pointer++, DISASM_DATA);
3821 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
3822}
3823{
3824 poke(operandAddress, A & X, DISASM_WRITE);
3825}
3826break;
3827
3828//////////////////////////////////////////////////
3829// SBC
3830case 0xe9:
3831case 0xeb:
3832{
3833 operand = peek(PC++, DISASM_CODE);
3834}
3835{
3836 // N, V, Z, C flags are the same in either mode (C calculated at the end)
3837 Int32 sum = A - operand - (C ? 0 : 1);
3838 N = sum & 0x80;
3839 V = (A ^ operand) & (A ^ sum) & 0x80;
3840 notZ = sum & 0xff;
3841
3842 if(!D)
3843 {
3844 A = uInt8(sum);
3845 }
3846 else
3847 {
3848 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
3849 Int32 hi = (A & 0xf0) - (operand & 0xf0);
3850 if(lo & 0x10)
3851 {
3852 lo -= 6;
3853 hi--;
3854 }
3855 if(hi & 0x0100)
3856 hi -= 0x60;
3857
3858 A = (lo & 0x0f) | (hi & 0xf0);
3859 }
3860 C = (sum & 0xff00) == 0;
3861}
3862break;
3863
3864case 0xe5:
3865{
3866 intermediateAddress = peek(PC++, DISASM_CODE);
3867 operand = peek(intermediateAddress, DISASM_DATA);
3868}
3869{
3870 // N, V, Z, C flags are the same in either mode (C calculated at the end)
3871 Int32 sum = A - operand - (C ? 0 : 1);
3872 N = sum & 0x80;
3873 V = (A ^ operand) & (A ^ sum) & 0x80;
3874 notZ = sum & 0xff;
3875
3876 if(!D)
3877 {
3878 A = uInt8(sum);
3879 }
3880 else
3881 {
3882 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
3883 Int32 hi = (A & 0xf0) - (operand & 0xf0);
3884 if(lo & 0x10)
3885 {
3886 lo -= 6;
3887 hi--;
3888 }
3889 if(hi & 0x0100)
3890 hi -= 0x60;
3891
3892 A = (lo & 0x0f) | (hi & 0xf0);
3893 }
3894 C = (sum & 0xff00) == 0;
3895}
3896break;
3897
3898case 0xf5:
3899{
3900 intermediateAddress = peek(PC++, DISASM_CODE);
3901 peek(intermediateAddress, DISASM_NONE);
3902 intermediateAddress += X;
3903 operand = peek(intermediateAddress, DISASM_DATA);
3904}
3905{
3906 // N, V, Z, C flags are the same in either mode (C calculated at the end)
3907 Int32 sum = A - operand - (C ? 0 : 1);
3908 N = sum & 0x80;
3909 V = (A ^ operand) & (A ^ sum) & 0x80;
3910 notZ = sum & 0xff;
3911
3912 if(!D)
3913 {
3914 A = uInt8(sum);
3915 }
3916 else
3917 {
3918 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
3919 Int32 hi = (A & 0xf0) - (operand & 0xf0);
3920 if(lo & 0x10)
3921 {
3922 lo -= 6;
3923 hi--;
3924 }
3925 if(hi & 0x0100)
3926 hi -= 0x60;
3927
3928 A = (lo & 0x0f) | (hi & 0xf0);
3929 }
3930 C = (sum & 0xff00) == 0;
3931}
3932break;
3933
3934case 0xed:
3935{
3936 intermediateAddress = peek(PC++, DISASM_CODE);
3937 intermediateAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
3938 operand = peek(intermediateAddress, DISASM_DATA);
3939}
3940{
3941 // N, V, Z, C flags are the same in either mode (C calculated at the end)
3942 Int32 sum = A - operand - (C ? 0 : 1);
3943 N = sum & 0x80;
3944 V = (A ^ operand) & (A ^ sum) & 0x80;
3945 notZ = sum & 0xff;
3946
3947 if(!D)
3948 {
3949 A = uInt8(sum);
3950 }
3951 else
3952 {
3953 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
3954 Int32 hi = (A & 0xf0) - (operand & 0xf0);
3955 if(lo & 0x10)
3956 {
3957 lo -= 6;
3958 hi--;
3959 }
3960 if(hi & 0x0100)
3961 hi -= 0x60;
3962
3963 A = (lo & 0x0f) | (hi & 0xf0);
3964 }
3965 C = (sum & 0xff00) == 0;
3966}
3967break;
3968
3969case 0xfd:
3970{
3971 uInt16 low = peek(PC++, DISASM_CODE);
3972 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
3973 intermediateAddress = high | uInt8(low + X);
3974 if((low + X) > 0xFF)
3975 {
3976 operand = peek(intermediateAddress, DISASM_NONE);
3977 intermediateAddress = (high | low) + X;
3978 operand = peek(intermediateAddress, DISASM_DATA);
3979 }
3980 else
3981 {
3982 operand = peek(intermediateAddress, DISASM_DATA);
3983 }
3984}
3985{
3986 // N, V, Z, C flags are the same in either mode (C calculated at the end)
3987 Int32 sum = A - operand - (C ? 0 : 1);
3988 N = sum & 0x80;
3989 V = (A ^ operand) & (A ^ sum) & 0x80;
3990 notZ = sum & 0xff;
3991
3992 if(!D)
3993 {
3994 A = uInt8(sum);
3995 }
3996 else
3997 {
3998 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
3999 Int32 hi = (A & 0xf0) - (operand & 0xf0);
4000 if(lo & 0x10)
4001 {
4002 lo -= 6;
4003 hi--;
4004 }
4005 if(hi & 0x0100)
4006 hi -= 0x60;
4007
4008 A = (lo & 0x0f) | (hi & 0xf0);
4009 }
4010 C = (sum & 0xff00) == 0;
4011}
4012break;
4013
4014case 0xf9:
4015{
4016 uInt16 low = peek(PC++, DISASM_CODE);
4017 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4018 intermediateAddress = high | uInt8(low + Y);
4019 if((low + Y) > 0xFF)
4020 {
4021 operand = peek(intermediateAddress, DISASM_NONE);
4022 intermediateAddress = (high | low) + Y;
4023 operand = peek(intermediateAddress, DISASM_DATA);
4024 }
4025 else
4026 {
4027 operand = peek(intermediateAddress, DISASM_DATA);
4028 }
4029}
4030{
4031 // N, V, Z, C flags are the same in either mode (C calculated at the end)
4032 Int32 sum = A - operand - (C ? 0 : 1);
4033 N = sum & 0x80;
4034 V = (A ^ operand) & (A ^ sum) & 0x80;
4035 notZ = sum & 0xff;
4036
4037 if(!D)
4038 {
4039 A = uInt8(sum);
4040 }
4041 else
4042 {
4043 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
4044 Int32 hi = (A & 0xf0) - (operand & 0xf0);
4045 if(lo & 0x10)
4046 {
4047 lo -= 6;
4048 hi--;
4049 }
4050 if(hi & 0x0100)
4051 hi -= 0x60;
4052
4053 A = (lo & 0x0f) | (hi & 0xf0);
4054 }
4055 C = (sum & 0xff00) == 0;
4056}
4057break;
4058
4059case 0xe1:
4060{
4061 uInt8 pointer = peek(PC++, DISASM_CODE);
4062 peek(pointer, DISASM_NONE);
4063 pointer += X;
4064 intermediateAddress = peek(pointer++, DISASM_DATA);
4065 intermediateAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
4066 operand = peek(intermediateAddress, DISASM_DATA);
4067}
4068{
4069 // N, V, Z, C flags are the same in either mode (C calculated at the end)
4070 Int32 sum = A - operand - (C ? 0 : 1);
4071 N = sum & 0x80;
4072 V = (A ^ operand) & (A ^ sum) & 0x80;
4073 notZ = sum & 0xff;
4074
4075 if(!D)
4076 {
4077 A = uInt8(sum);
4078 }
4079 else
4080 {
4081 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
4082 Int32 hi = (A & 0xf0) - (operand & 0xf0);
4083 if(lo & 0x10)
4084 {
4085 lo -= 6;
4086 hi--;
4087 }
4088 if(hi & 0x0100)
4089 hi -= 0x60;
4090
4091 A = (lo & 0x0f) | (hi & 0xf0);
4092 }
4093 C = (sum & 0xff00) == 0;
4094}
4095break;
4096
4097case 0xf1:
4098{
4099 uInt8 pointer = peek(PC++, DISASM_CODE);
4100 uInt16 low = peek(pointer++, DISASM_DATA);
4101 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
4102 intermediateAddress = high | uInt8(low + Y);
4103 if((low + Y) > 0xFF)
4104 {
4105 operand = peek(intermediateAddress, DISASM_NONE);
4106 intermediateAddress = (high | low) + Y;
4107 operand = peek(intermediateAddress, DISASM_DATA);
4108 }
4109 else
4110 {
4111 operand = peek(intermediateAddress, DISASM_DATA);
4112 }
4113}
4114{
4115 // N, V, Z, C flags are the same in either mode (C calculated at the end)
4116 Int32 sum = A - operand - (C ? 0 : 1);
4117 N = sum & 0x80;
4118 V = (A ^ operand) & (A ^ sum) & 0x80;
4119 notZ = sum & 0xff;
4120
4121 if(!D)
4122 {
4123 A = uInt8(sum);
4124 }
4125 else
4126 {
4127 Int32 lo = (A & 0x0f) - (operand & 0x0f) - (C ? 0 : 1);
4128 Int32 hi = (A & 0xf0) - (operand & 0xf0);
4129 if(lo & 0x10)
4130 {
4131 lo -= 6;
4132 hi--;
4133 }
4134 if(hi & 0x0100)
4135 hi -= 0x60;
4136
4137 A = (lo & 0x0f) | (hi & 0xf0);
4138 }
4139 C = (sum & 0xff00) == 0;
4140}
4141break;
4142
4143//////////////////////////////////////////////////
4144// SBX
4145case 0xcb:
4146{
4147 operand = peek(PC++, DISASM_CODE);
4148}
4149{
4150 uInt16 value = uInt16(X & A) - uInt16(operand);
4151 X = (value & 0xff);
4152
4153 notZ = X;
4154 N = X & 0x80;
4155 C = !(value & 0x0100);
4156}
4157break;
4158
4159//////////////////////////////////////////////////
4160// SEC
4161case 0x38:
4162{
4163 peek(PC, DISASM_NONE);
4164}
4165{
4166 C = true;
4167}
4168break;
4169
4170//////////////////////////////////////////////////
4171// SED
4172case 0xf8:
4173{
4174 peek(PC, DISASM_NONE);
4175}
4176{
4177 D = true;
4178}
4179break;
4180
4181//////////////////////////////////////////////////
4182// SEI
4183case 0x78:
4184{
4185 peek(PC, DISASM_NONE);
4186}
4187{
4188 I = true;
4189}
4190break;
4191
4192//////////////////////////////////////////////////
4193// SHA
4194case 0x9f:
4195{
4196 uInt16 low = peek(PC++, DISASM_CODE);
4197 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4198 peek(high | uInt8(low + Y), DISASM_NONE);
4199 operandAddress = (high | low) + Y;
4200}
4201{
4202 // NOTE: There are mixed reports on the actual operation
4203 // of this instruction!
4204 poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE);
4205}
4206break;
4207
4208case 0x93:
4209{
4210 uInt8 pointer = peek(PC++, DISASM_CODE);
4211 uInt16 low = peek(pointer++, DISASM_DATA);
4212 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
4213 peek(high | uInt8(low + Y), DISASM_NONE);
4214 operandAddress = (high | low) + Y;
4215}
4216{
4217 // NOTE: There are mixed reports on the actual operation
4218 // of this instruction!
4219 poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE);
4220}
4221break;
4222
4223//////////////////////////////////////////////////
4224// SHS
4225case 0x9b:
4226{
4227 uInt16 low = peek(PC++, DISASM_CODE);
4228 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4229 peek(high | uInt8(low + Y), DISASM_NONE);
4230 operandAddress = (high | low) + Y;
4231}
4232{
4233 // NOTE: There are mixed reports on the actual operation
4234 // of this instruction!
4235 SP = A & X;
4236 poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE);
4237}
4238break;
4239
4240//////////////////////////////////////////////////
4241// SHX
4242case 0x9e:
4243{
4244 uInt16 low = peek(PC++, DISASM_CODE);
4245 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4246 peek(high | uInt8(low + Y), DISASM_NONE);
4247 operandAddress = (high | low) + Y;
4248}
4249{
4250 // NOTE: There are mixed reports on the actual operation
4251 // of this instruction!
4252 poke(operandAddress, X & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE);
4253}
4254break;
4255
4256//////////////////////////////////////////////////
4257// SHY
4258case 0x9c:
4259{
4260 uInt16 low = peek(PC++, DISASM_CODE);
4261 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4262 peek(high | uInt8(low + X), DISASM_NONE);
4263 operandAddress = (high | low) + X;
4264}
4265{
4266 // NOTE: There are mixed reports on the actual operation
4267 // of this instruction!
4268 poke(operandAddress, Y & (((operandAddress >> 8) & 0xff) + 1), DISASM_WRITE);
4269}
4270break;
4271
4272//////////////////////////////////////////////////
4273// SLO
4274case 0x0f:
4275{
4276 operandAddress = peek(PC++, DISASM_CODE);
4277 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
4278 operand = peek(operandAddress, DISASM_DATA);
4279 poke(operandAddress, operand, DISASM_WRITE);
4280}
4281{
4282 // Set carry flag according to the left-most bit in value
4283 C = operand & 0x80;
4284
4285 operand <<= 1;
4286 poke(operandAddress, operand, DISASM_WRITE);
4287
4288 A |= operand;
4289 notZ = A;
4290 N = A & 0x80;
4291}
4292break;
4293
4294case 0x1f:
4295{
4296 uInt16 low = peek(PC++, DISASM_CODE);
4297 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4298 peek(high | uInt8(low + X), DISASM_NONE);
4299 operandAddress = (high | low) + X;
4300 operand = peek(operandAddress, DISASM_DATA);
4301 poke(operandAddress, operand, DISASM_WRITE);
4302}
4303{
4304 // Set carry flag according to the left-most bit in value
4305 C = operand & 0x80;
4306
4307 operand <<= 1;
4308 poke(operandAddress, operand, DISASM_WRITE);
4309
4310 A |= operand;
4311 notZ = A;
4312 N = A & 0x80;
4313}
4314break;
4315
4316case 0x1b:
4317{
4318 uInt16 low = peek(PC++, DISASM_CODE);
4319 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4320 peek(high | uInt8(low + Y), DISASM_NONE);
4321 operandAddress = (high | low) + Y;
4322 operand = peek(operandAddress, DISASM_DATA);
4323 poke(operandAddress, operand, DISASM_WRITE);
4324}
4325{
4326 // Set carry flag according to the left-most bit in value
4327 C = operand & 0x80;
4328
4329 operand <<= 1;
4330 poke(operandAddress, operand, DISASM_WRITE);
4331
4332 A |= operand;
4333 notZ = A;
4334 N = A & 0x80;
4335}
4336break;
4337
4338case 0x07:
4339{
4340 operandAddress = peek(PC++, DISASM_CODE);
4341 operand = peek(operandAddress, DISASM_DATA);
4342 poke(operandAddress, operand, DISASM_WRITE);
4343}
4344{
4345 // Set carry flag according to the left-most bit in value
4346 C = operand & 0x80;
4347
4348 operand <<= 1;
4349 poke(operandAddress, operand, DISASM_WRITE);
4350
4351 A |= operand;
4352 notZ = A;
4353 N = A & 0x80;
4354}
4355break;
4356
4357case 0x17:
4358{
4359 operandAddress = peek(PC++, DISASM_CODE);
4360 peek(operandAddress, DISASM_NONE);
4361 operandAddress = (operandAddress + X) & 0xFF;
4362 operand = peek(operandAddress, DISASM_DATA);
4363 poke(operandAddress, operand, DISASM_WRITE);
4364}
4365{
4366 // Set carry flag according to the left-most bit in value
4367 C = operand & 0x80;
4368
4369 operand <<= 1;
4370 poke(operandAddress, operand, DISASM_WRITE);
4371
4372 A |= operand;
4373 notZ = A;
4374 N = A & 0x80;
4375}
4376break;
4377
4378case 0x03:
4379{
4380 uInt8 pointer = peek(PC++, DISASM_CODE);
4381 peek(pointer, DISASM_NONE);
4382 pointer += X;
4383 operandAddress = peek(pointer++, DISASM_DATA);
4384 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
4385 operand = peek(operandAddress, DISASM_DATA);
4386 poke(operandAddress, operand, DISASM_WRITE);
4387}
4388{
4389 // Set carry flag according to the left-most bit in value
4390 C = operand & 0x80;
4391
4392 operand <<= 1;
4393 poke(operandAddress, operand, DISASM_WRITE);
4394
4395 A |= operand;
4396 notZ = A;
4397 N = A & 0x80;
4398}
4399break;
4400
4401case 0x13:
4402{
4403 uInt8 pointer = peek(PC++, DISASM_CODE);
4404 uInt16 low = peek(pointer++, DISASM_DATA);
4405 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
4406 peek(high | uInt8(low + Y), DISASM_NONE);
4407 operandAddress = (high | low) + Y;
4408 operand = peek(operandAddress, DISASM_DATA);
4409 poke(operandAddress, operand, DISASM_WRITE);
4410}
4411{
4412 // Set carry flag according to the left-most bit in value
4413 C = operand & 0x80;
4414
4415 operand <<= 1;
4416 poke(operandAddress, operand, DISASM_WRITE);
4417
4418 A |= operand;
4419 notZ = A;
4420 N = A & 0x80;
4421}
4422break;
4423
4424//////////////////////////////////////////////////
4425// SRE
4426case 0x4f:
4427{
4428 operandAddress = peek(PC++, DISASM_CODE);
4429 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
4430 operand = peek(operandAddress, DISASM_DATA);
4431 poke(operandAddress, operand, DISASM_WRITE);
4432}
4433{
4434 // Set carry flag according to the right-most bit in value
4435 C = operand & 0x01;
4436
4437 operand = (operand >> 1) & 0x7f;
4438 poke(operandAddress, operand, DISASM_WRITE);
4439
4440 A ^= operand;
4441 notZ = A;
4442 N = A & 0x80;
4443}
4444break;
4445
4446case 0x5f:
4447{
4448 uInt16 low = peek(PC++, DISASM_CODE);
4449 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4450 peek(high | uInt8(low + X), DISASM_NONE);
4451 operandAddress = (high | low) + X;
4452 operand = peek(operandAddress, DISASM_DATA);
4453 poke(operandAddress, operand, DISASM_WRITE);
4454}
4455{
4456 // Set carry flag according to the right-most bit in value
4457 C = operand & 0x01;
4458
4459 operand = (operand >> 1) & 0x7f;
4460 poke(operandAddress, operand, DISASM_WRITE);
4461
4462 A ^= operand;
4463 notZ = A;
4464 N = A & 0x80;
4465}
4466break;
4467
4468case 0x5b:
4469{
4470 uInt16 low = peek(PC++, DISASM_CODE);
4471 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4472 peek(high | uInt8(low + Y), DISASM_NONE);
4473 operandAddress = (high | low) + Y;
4474 operand = peek(operandAddress, DISASM_DATA);
4475 poke(operandAddress, operand, DISASM_WRITE);
4476}
4477{
4478 // Set carry flag according to the right-most bit in value
4479 C = operand & 0x01;
4480
4481 operand = (operand >> 1) & 0x7f;
4482 poke(operandAddress, operand, DISASM_WRITE);
4483
4484 A ^= operand;
4485 notZ = A;
4486 N = A & 0x80;
4487}
4488break;
4489
4490case 0x47:
4491{
4492 operandAddress = peek(PC++, DISASM_CODE);
4493 operand = peek(operandAddress, DISASM_DATA);
4494 poke(operandAddress, operand, DISASM_WRITE);
4495}
4496{
4497 // Set carry flag according to the right-most bit in value
4498 C = operand & 0x01;
4499
4500 operand = (operand >> 1) & 0x7f;
4501 poke(operandAddress, operand, DISASM_WRITE);
4502
4503 A ^= operand;
4504 notZ = A;
4505 N = A & 0x80;
4506}
4507break;
4508
4509case 0x57:
4510{
4511 operandAddress = peek(PC++, DISASM_CODE);
4512 peek(operandAddress, DISASM_NONE);
4513 operandAddress = (operandAddress + X) & 0xFF;
4514 operand = peek(operandAddress, DISASM_DATA);
4515 poke(operandAddress, operand, DISASM_WRITE);
4516}
4517{
4518 // Set carry flag according to the right-most bit in value
4519 C = operand & 0x01;
4520
4521 operand = (operand >> 1) & 0x7f;
4522 poke(operandAddress, operand, DISASM_WRITE);
4523
4524 A ^= operand;
4525 notZ = A;
4526 N = A & 0x80;
4527}
4528break;
4529
4530case 0x43:
4531{
4532 uInt8 pointer = peek(PC++, DISASM_CODE);
4533 peek(pointer, DISASM_NONE);
4534 pointer += X;
4535 operandAddress = peek(pointer++, DISASM_DATA);
4536 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
4537 operand = peek(operandAddress, DISASM_DATA);
4538 poke(operandAddress, operand, DISASM_WRITE);
4539}
4540{
4541 // Set carry flag according to the right-most bit in value
4542 C = operand & 0x01;
4543
4544 operand = (operand >> 1) & 0x7f;
4545 poke(operandAddress, operand, DISASM_WRITE);
4546
4547 A ^= operand;
4548 notZ = A;
4549 N = A & 0x80;
4550}
4551break;
4552
4553case 0x53:
4554{
4555 uInt8 pointer = peek(PC++, DISASM_CODE);
4556 uInt16 low = peek(pointer++, DISASM_DATA);
4557 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
4558 peek(high | uInt8(low + Y), DISASM_NONE);
4559 operandAddress = (high | low) + Y;
4560 operand = peek(operandAddress, DISASM_DATA);
4561 poke(operandAddress, operand, DISASM_WRITE);
4562}
4563{
4564 // Set carry flag according to the right-most bit in value
4565 C = operand & 0x01;
4566
4567 operand = (operand >> 1) & 0x7f;
4568 poke(operandAddress, operand, DISASM_WRITE);
4569
4570 A ^= operand;
4571 notZ = A;
4572 N = A & 0x80;
4573}
4574break;
4575
4576
4577//////////////////////////////////////////////////
4578// STA
4579case 0x85:
4580{
4581 operandAddress = peek(PC++, DISASM_CODE);
4582}
4583SET_LAST_POKE(myLastSrcAddressA)
4584{
4585 poke(operandAddress, A, DISASM_WRITE);
4586}
4587break;
4588
4589case 0x95:
4590{
4591 operandAddress = peek(PC++, DISASM_CODE);
4592 peek(operandAddress, DISASM_NONE);
4593 operandAddress = (operandAddress + X) & 0xFF;
4594}
4595{
4596 poke(operandAddress, A, DISASM_WRITE);
4597}
4598break;
4599
4600case 0x8d:
4601{
4602 operandAddress = peek(PC++, DISASM_CODE);
4603 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
4604}
4605SET_LAST_POKE(myLastSrcAddressA)
4606{
4607 poke(operandAddress, A, DISASM_WRITE);
4608}
4609break;
4610
4611case 0x9d:
4612{
4613 uInt16 low = peek(PC++, DISASM_CODE);
4614 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4615 peek(high | uInt8(low + X), DISASM_NONE);
4616 operandAddress = (high | low) + X;
4617}
4618{
4619 poke(operandAddress, A, DISASM_WRITE);
4620}
4621break;
4622
4623case 0x99:
4624{
4625 uInt16 low = peek(PC++, DISASM_CODE);
4626 uInt16 high = (uInt16(peek(PC++, DISASM_CODE)) << 8);
4627 peek(high | uInt8(low + Y), DISASM_NONE);
4628 operandAddress = (high | low) + Y;
4629}
4630{
4631 poke(operandAddress, A, DISASM_WRITE);
4632}
4633break;
4634
4635case 0x81:
4636{
4637 uInt8 pointer = peek(PC++, DISASM_CODE);
4638 peek(pointer, DISASM_NONE);
4639 pointer += X;
4640 operandAddress = peek(pointer++, DISASM_DATA);
4641 operandAddress |= (uInt16(peek(pointer, DISASM_DATA)) << 8);
4642}
4643{
4644 poke(operandAddress, A, DISASM_WRITE);
4645}
4646break;
4647
4648case 0x91:
4649{
4650 uInt8 pointer = peek(PC++, DISASM_CODE);
4651 uInt16 low = peek(pointer++, DISASM_DATA);
4652 uInt16 high = (uInt16(peek(pointer, DISASM_DATA)) << 8);
4653 peek(high | uInt8(low + Y), DISASM_NONE);
4654 operandAddress = (high | low) + Y;
4655}
4656{
4657 poke(operandAddress, A, DISASM_WRITE);
4658}
4659break;
4660//////////////////////////////////////////////////
4661
4662
4663//////////////////////////////////////////////////
4664// STX
4665case 0x86:
4666{
4667 operandAddress = peek(PC++, DISASM_CODE);
4668}
4669SET_LAST_POKE(myLastSrcAddressX)
4670{
4671 poke(operandAddress, X, DISASM_WRITE);
4672}
4673break;
4674
4675case 0x96:
4676{
4677 operandAddress = peek(PC++, DISASM_CODE);
4678 peek(operandAddress, DISASM_NONE);
4679 operandAddress = (operandAddress + Y) & 0xFF;
4680}
4681{
4682 poke(operandAddress, X, DISASM_WRITE);
4683}
4684break;
4685
4686case 0x8e:
4687{
4688 operandAddress = peek(PC++, DISASM_CODE);
4689 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
4690}
4691SET_LAST_POKE(myLastSrcAddressX)
4692{
4693 poke(operandAddress, X, DISASM_WRITE);
4694}
4695break;
4696//////////////////////////////////////////////////
4697
4698
4699//////////////////////////////////////////////////
4700// STY
4701case 0x84:
4702{
4703 operandAddress = peek(PC++, DISASM_CODE);
4704}
4705SET_LAST_POKE(myLastSrcAddressY)
4706{
4707 poke(operandAddress, Y, DISASM_WRITE);
4708}
4709break;
4710
4711case 0x94:
4712{
4713 operandAddress = peek(PC++, DISASM_CODE);
4714 peek(operandAddress, DISASM_NONE);
4715 operandAddress = (operandAddress + X) & 0xFF;
4716}
4717{
4718 poke(operandAddress, Y, DISASM_WRITE);
4719}
4720break;
4721
4722case 0x8c:
4723{
4724 operandAddress = peek(PC++, DISASM_CODE);
4725 operandAddress |= (uInt16(peek(PC++, DISASM_CODE)) << 8);
4726}
4727SET_LAST_POKE(myLastSrcAddressY)
4728{
4729 poke(operandAddress, Y, DISASM_WRITE);
4730}
4731break;
4732//////////////////////////////////////////////////
4733
4734
4735//////////////////////////////////////////////////
4736// Remaining MOVE opcodes
4737case 0xaa:
4738{
4739 peek(PC, DISASM_NONE);
4740}
4741SET_LAST_PEEK(myLastSrcAddressX, myLastSrcAddressA)
4742{
4743 X = A;
4744 notZ = X;
4745 N = X & 0x80;
4746}
4747break;
4748
4749
4750case 0xa8:
4751{
4752 peek(PC, DISASM_NONE);
4753}
4754SET_LAST_PEEK(myLastSrcAddressY, myLastSrcAddressA)
4755{
4756 Y = A;
4757 notZ = Y;
4758 N = Y & 0x80;
4759}
4760break;
4761
4762
4763case 0xba:
4764{
4765 peek(PC, DISASM_NONE);
4766}
4767SET_LAST_PEEK(myLastSrcAddressX, myLastSrcAddressS)
4768{
4769 X = SP;
4770 notZ = X;
4771 N = X & 0x80;
4772}
4773break;
4774
4775
4776case 0x8a:
4777{
4778 peek(PC, DISASM_NONE);
4779}
4780SET_LAST_PEEK(myLastSrcAddressA, myLastSrcAddressX)
4781{
4782 A = X;
4783 notZ = A;
4784 N = A & 0x80;
4785}
4786break;
4787
4788
4789case 0x9a:
4790{
4791 peek(PC, DISASM_NONE);
4792}
4793SET_LAST_PEEK(myLastSrcAddressS, myLastSrcAddressX)
4794{
4795 SP = X;
4796}
4797break;
4798
4799
4800case 0x98:
4801{
4802 peek(PC, DISASM_NONE);
4803}
4804SET_LAST_PEEK(myLastSrcAddressA, myLastSrcAddressY)
4805{
4806 A = Y;
4807 notZ = A;
4808 N = A & 0x80;
4809}
4810break;
4811//////////////////////////////////////////////////
4812