1#![no_std]
2
3pub struct CentralProcessingUnit {
4 pub a: u8,
5 pub x: u8,
6 pub y: u8,
7 pub sp: u8,
8 pub pc: u16,
9 pub status: u8,
10 pub memory: [u8; 0x10000],
11}
12
13#[allow(clippy::new_without_default)]
15impl CentralProcessingUnit {
16 pub const fn new() -> Self {
17 static ZEROED_MEMORY: [u8; 0x10000] = [0; 0x10000];
18
19 Self {
20 a: 0,
21 x: 0,
22 y: 0,
23 sp: 0xFD,
24 pc: 0,
25 status: Self::STATUS_FLAG_U | Self::STATUS_FLAG_I,
26 memory: ZEROED_MEMORY,
27 }
28 }
29
30 pub const fn new_with_memory(memory: [u8; 0x10000]) -> Self {
31 Self {
32 a: 0,
33 x: 0,
34 y: 0,
35 sp: 0xFD,
36 pc: ((memory[0xFFFD] as u16) << 8) | (memory[0xFFFC] as u16),
37 status: Self::STATUS_FLAG_U | Self::STATUS_FLAG_I,
38 memory,
39 }
40 }
41
42 pub const fn reset(&mut self) {
43 self.a = 0;
44 self.x = 0;
45 self.y = 0;
46 self.sp = 0xFD;
47 self.pc = self.read_word(0xFFFC);
48 self.status = Self::STATUS_FLAG_U | Self::STATUS_FLAG_I;
49 }
50}
51
52impl CentralProcessingUnit {
54 #[inline(always)]
55 const fn read_byte(&self, addr: u16) -> u8 {
56 self.memory[addr as usize]
57 }
58
59 #[inline(always)]
60 const fn write_byte(&mut self, addr: u16, value: u8) {
61 self.memory[addr as usize] = value;
62 }
63
64 #[inline(always)]
65 const fn read_word(&self, addr: u16) -> u16 {
66 ((self.read_byte(addr.wrapping_add(1)) as u16) << 8) | (self.read_byte(addr) as u16)
67 }
68
69 #[inline(always)]
70 const fn push(&mut self, value: u8) {
71 self.write_byte(0x0100 + self.sp as u16, value);
72 self.sp = self.sp.wrapping_sub(1);
73 }
74
75 #[inline(always)]
76 const fn pop(&mut self) -> u8 {
77 self.sp = self.sp.wrapping_add(1);
78 self.read_byte(0x0100 + self.sp as u16)
79 }
80}
81
82impl CentralProcessingUnit {
84 const STATUS_FLAG_C: u8 = 1 << 0;
85 const STATUS_FLAG_Z: u8 = 1 << 1;
86 const STATUS_FLAG_I: u8 = 1 << 2;
87 const STATUS_FLAG_D: u8 = 1 << 3;
88 const STATUS_FLAG_B: u8 = 1 << 4;
89 const STATUS_FLAG_U: u8 = 1 << 5;
90 const STATUS_FLAG_V: u8 = 1 << 6;
91 const STATUS_FLAG_N: u8 = 1 << 7;
92
93 #[inline(always)]
94 const fn set_flag(&mut self, flag: u8, state: bool) {
95 self.status ^= (self.status ^ (-(state as i8) as u8)) & flag;
96 }
97
98 #[inline(always)]
99 const fn get_flag(&self, flag: u8) -> bool {
100 self.status & flag != 0
101 }
102
103 #[inline(always)]
104 const fn update_zn(&mut self, result: u8) {
105 self.status ^= (self.status
106 ^ ((-((result == 0) as i8) as u8) & Self::STATUS_FLAG_Z
107 | (-(((result & 0x80) != 0) as i8) as u8) & Self::STATUS_FLAG_N))
108 & (Self::STATUS_FLAG_Z | Self::STATUS_FLAG_N);
109 }
110}
111
112impl CentralProcessingUnit {
114 const fn immediate(&mut self) -> u16 {
115 let addr = self.pc;
116 self.pc = self.pc.wrapping_add(1);
117
118 addr
119 }
120
121 const fn zeropage(&mut self) -> u16 {
122 let addr = self.read_byte(self.pc) as u16;
123 self.pc = self.pc.wrapping_add(1);
124
125 addr
126 }
127
128 const fn zeropage_x(&mut self) -> u16 {
129 let addr = self.read_byte(self.pc);
130 self.pc = self.pc.wrapping_add(1);
131
132 addr.wrapping_add(self.x) as u16
133 }
134
135 const fn zeropage_y(&mut self) -> u16 {
136 let addr = self.read_byte(self.pc);
137 self.pc = self.pc.wrapping_add(1);
138
139 addr.wrapping_add(self.y) as u16
140 }
141
142 const fn absolute(&mut self) -> u16 {
143 let addr = self.read_word(self.pc);
144 self.pc = self.pc.wrapping_add(2);
145
146 addr
147 }
148
149 const fn absolute_x(&mut self) -> u16 {
150 let addr = self.read_word(self.pc);
151 self.pc = self.pc.wrapping_add(2);
152
153 addr.wrapping_add(self.x as u16)
154 }
155
156 const fn absolute_y(&mut self) -> u16 {
157 let addr = self.read_word(self.pc);
158 self.pc = self.pc.wrapping_add(2);
159
160 addr.wrapping_add(self.y as u16)
161 }
162
163 const fn indirect(&mut self) -> u16 {
164 let addr = self.read_word(self.pc);
165 self.pc = self.pc.wrapping_add(2);
166
167 (self.read_byte((addr & 0xFF00) | ((addr.wrapping_add(1)) & 0xFF)) as u16) << 8
169 | (self.read_byte(addr) as u16)
170 }
171
172 const fn indexed_indirect(&mut self) -> u16 {
173 let addr = self.read_byte(self.pc).wrapping_add(self.x) as u16;
174 self.pc = self.pc.wrapping_add(1);
175
176 ((self.read_byte(addr.wrapping_add(1)) as u16) << 8) | (self.read_byte(addr) as u16)
177 }
178
179 const fn indirect_indexed(&mut self) -> u16 {
180 let addr = self.read_byte(self.pc) as u16;
181 self.pc = self.pc.wrapping_add(1);
182
183 (((self.read_byte(addr.wrapping_add(1)) as u16) << 8) | (self.read_byte(addr) as u16))
184 .wrapping_add(self.y as u16)
185 }
186}
187
188impl CentralProcessingUnit {
190 const fn adc(&mut self, value: u8) {
191 let sum = self.a as u16 + value as u16 + (self.status & Self::STATUS_FLAG_C) as u16;
192 let mut result = sum as u8;
193
194 if self.get_flag(Self::STATUS_FLAG_D) {
195 result =
196 result.wrapping_add(((result & 0x0F) > 9) as u8 * 0x06 + (sum > 0x99) as u8 * 0x60);
197
198 self.set_flag(Self::STATUS_FLAG_C, sum > 0x99);
199 self.set_flag(Self::STATUS_FLAG_V, false);
200 } else {
201 self.set_flag(Self::STATUS_FLAG_C, sum > 0xFF);
202 self.set_flag(
203 Self::STATUS_FLAG_V,
204 (!(self.a ^ value) & (self.a ^ result) & 0x80) != 0,
205 );
206 }
207
208 self.a = result;
209 self.update_zn(result);
210 }
211
212 const fn sbc(&mut self, value: u8) {
213 let original_carry = self.get_flag(Self::STATUS_FLAG_C);
214 self.set_flag(Self::STATUS_FLAG_C, true);
215 self.adc(value ^ 0xFF);
216 if !original_carry {
217 let (result, _) = self.a.overflowing_sub(1);
218 self.a = result;
219 self.update_zn(result);
220 }
221 }
222
223 const fn ora(&mut self, value: u8) {
224 self.a |= value;
225 self.update_zn(self.a);
226 }
227
228 const fn and(&mut self, value: u8) {
229 self.a &= value;
230 self.update_zn(self.a);
231 }
232
233 const fn eor(&mut self, value: u8) {
234 self.a ^= value;
235 self.update_zn(self.a);
236 }
237
238 const fn cmp(&mut self, reg: u8, value: u8) {
239 let result = reg.wrapping_sub(value);
240 self.set_flag(Self::STATUS_FLAG_C, reg >= value);
241 self.update_zn(result);
242 }
243
244 const fn bit(&mut self, value: u8) {
245 self.set_flag(Self::STATUS_FLAG_Z, (self.a & value) == 0);
246 self.set_flag(Self::STATUS_FLAG_N, value & 0x80 != 0);
247 self.set_flag(Self::STATUS_FLAG_V, value & 0x40 != 0);
248 }
249
250 const fn inc(&mut self, addr: u16) {
251 let result = self.read_byte(addr).wrapping_add(1);
252 self.write_byte(addr, result);
253 self.update_zn(result);
254 }
255
256 const fn dec(&mut self, addr: u16) {
257 let result = self.read_byte(addr).wrapping_sub(1);
258 self.write_byte(addr, result);
259 self.update_zn(result);
260 }
261}
262
263impl CentralProcessingUnit {
265 const fn asl_acc(&mut self) {
266 self.set_flag(Self::STATUS_FLAG_C, self.a & 0x80 != 0);
267 self.a <<= 1;
268 self.update_zn(self.a);
269 }
270
271 const fn asl_mem(&mut self, addr: u16) {
272 let value = self.read_byte(addr);
273 self.set_flag(Self::STATUS_FLAG_C, value & 0x80 != 0);
274 let result = value << 1;
275 self.write_byte(addr, result);
276 self.update_zn(result);
277 }
278
279 const fn lsr_acc(&mut self) {
280 self.set_flag(Self::STATUS_FLAG_C, self.a & 0x01 != 0);
281 self.a >>= 1;
282 self.update_zn(self.a);
283 }
284
285 const fn lsr_mem(&mut self, addr: u16) {
286 let value = self.read_byte(addr);
287 self.set_flag(Self::STATUS_FLAG_C, value & 0x01 != 0);
288 let result = value >> 1;
289 self.write_byte(addr, result);
290 self.update_zn(result);
291 }
292
293 const fn rol_acc(&mut self) {
294 let old = self.a;
295 let new_carry = old & 0x80 != 0;
296 self.a = (old << 1)
297 | if self.get_flag(Self::STATUS_FLAG_C) {
298 1
299 } else {
300 0
301 };
302 self.set_flag(Self::STATUS_FLAG_C, new_carry);
303 self.update_zn(self.a);
304 }
305
306 const fn rol_mem(&mut self, addr: u16) {
307 let value = self.read_byte(addr);
308 let new_carry = value & 0x80 != 0;
309 let result = (value << 1)
310 | if self.get_flag(Self::STATUS_FLAG_C) {
311 1
312 } else {
313 0
314 };
315 self.write_byte(addr, result);
316 self.set_flag(Self::STATUS_FLAG_C, new_carry);
317 self.update_zn(result);
318 }
319
320 const fn ror_acc(&mut self) {
321 let old = self.a;
322 let old_carry = if self.get_flag(Self::STATUS_FLAG_C) {
323 0x80
324 } else {
325 0
326 };
327 let new_carry = old & 0x01 != 0;
328 let result = (old >> 1) | old_carry;
329 self.a = result;
330 self.set_flag(Self::STATUS_FLAG_C, new_carry);
331 self.update_zn(result);
332 }
333
334 const fn ror_mem(&mut self, addr: u16) {
335 let value = self.read_byte(addr);
336 let old_carry = if self.get_flag(Self::STATUS_FLAG_C) {
337 0x80
338 } else {
339 0
340 };
341 let new_carry = value & 0x01 != 0;
342 let result = (value >> 1) | old_carry;
343 self.write_byte(addr, result);
344 self.set_flag(Self::STATUS_FLAG_C, new_carry);
345 self.update_zn(result);
346 }
347}
348
349impl CentralProcessingUnit {
351 const fn branch(&mut self, condition: bool) {
352 let offset = self.read_byte(self.pc) as i8;
353 self.pc = self.pc.wrapping_add(1);
354 if condition {
355 self.pc = self.pc.wrapping_add(offset as u16);
356 }
357 }
358}
359
360impl CentralProcessingUnit {
362 #[inline(always)]
381 pub const fn step(&mut self) {
382 let opcode = self.read_byte(self.pc);
383 self.pc = self.pc.wrapping_add(1);
384
385 match opcode {
387 0x00 => {
389 self.pc = self.pc.wrapping_add(1);
390 self.push((self.pc >> 8) as u8);
391 self.push((self.pc & 0xFF) as u8);
392 self.set_flag(Self::STATUS_FLAG_B, true);
393 self.push(self.status);
394 self.set_flag(Self::STATUS_FLAG_I, true);
395 self.pc = self.read_word(0xFFFE);
396 }
397
398 0x40 => {
400 self.status = self.pop();
401 self.status &= !(Self::STATUS_FLAG_B | Self::STATUS_FLAG_I);
402 self.status |= Self::STATUS_FLAG_U;
403 let lo = self.pop() as u16;
404 let hi = self.pop() as u16;
405 self.pc = (hi << 8) | lo;
406 }
407
408 0x60 => {
410 let lo = self.pop() as u16;
411 let hi = self.pop() as u16;
412 self.pc = ((hi << 8) | lo).wrapping_add(1);
413 }
414
415 0x20 => {
417 let addr = self.read_word(self.pc);
418 self.pc = self.pc.wrapping_add(2);
419 let ret = self.pc.wrapping_sub(1);
420 self.push((ret >> 8) as u8);
421 self.push((ret & 0xFF) as u8);
422 self.pc = addr;
423 }
424
425 0x4C => self.pc = self.absolute(),
427
428 0x6C => self.pc = self.indirect(),
430
431 0x10 => self.branch(!self.get_flag(Self::STATUS_FLAG_N)),
433
434 0x30 => self.branch(self.get_flag(Self::STATUS_FLAG_N)),
436
437 0x50 => self.branch(!self.get_flag(Self::STATUS_FLAG_V)),
439
440 0x70 => self.branch(self.get_flag(Self::STATUS_FLAG_V)),
442
443 0x90 => self.branch(!self.get_flag(Self::STATUS_FLAG_C)),
445
446 0xB0 => self.branch(self.get_flag(Self::STATUS_FLAG_C)),
448
449 0xD0 => self.branch(!self.get_flag(Self::STATUS_FLAG_Z)),
451
452 0xF0 => self.branch(self.get_flag(Self::STATUS_FLAG_Z)),
454
455 0x18 => self.set_flag(Self::STATUS_FLAG_C, false),
457
458 0x38 => self.set_flag(Self::STATUS_FLAG_C, true),
460
461 0x58 => self.set_flag(Self::STATUS_FLAG_I, false),
463
464 0x78 => self.set_flag(Self::STATUS_FLAG_I, true),
466
467 0xB8 => self.set_flag(Self::STATUS_FLAG_V, false),
469
470 0xD8 => self.set_flag(Self::STATUS_FLAG_D, false),
472
473 0xF8 => self.set_flag(Self::STATUS_FLAG_D, true),
475
476 0x09 => {
478 let addr = self.immediate();
479 let v = self.read_byte(addr);
480
481 self.ora(v)
482 }
483
484 0x05 => {
486 let addr = self.zeropage();
487 let v = self.read_byte(addr);
488
489 self.ora(v)
490 }
491
492 0x15 => {
494 let addr = self.zeropage_x();
495 let v = self.read_byte(addr);
496
497 self.ora(v)
498 }
499
500 0x0D => {
502 let addr = self.absolute();
503 let v = self.read_byte(addr);
504
505 self.ora(v)
506 }
507
508 0x1D => {
510 let addr = self.absolute_x();
511 let v = self.read_byte(addr);
512
513 self.ora(v)
514 }
515
516 0x19 => {
518 let addr = self.absolute_y();
519 let v = self.read_byte(addr);
520
521 self.ora(v)
522 }
523
524 0x01 => {
526 let addr = self.indexed_indirect();
527 let v = self.read_byte(addr);
528 self.ora(v)
529 }
530
531 0x11 => {
533 let addr = self.indirect_indexed();
534 let v = self.read_byte(addr);
535 self.ora(v)
536 }
537
538 0x29 => {
540 let addr = self.immediate();
541 let v = self.read_byte(addr);
542 self.and(v)
543 }
544
545 0x25 => {
547 let addr = self.zeropage();
548 let v = self.read_byte(addr);
549 self.and(v)
550 }
551
552 0x35 => {
554 let addr = self.zeropage_x();
555 let v = self.read_byte(addr);
556 self.and(v)
557 }
558
559 0x2D => {
561 let addr = self.absolute();
562 let v = self.read_byte(addr);
563 self.and(v)
564 }
565
566 0x3D => {
568 let addr = self.absolute_x();
569 let v = self.read_byte(addr);
570 self.and(v)
571 }
572
573 0x39 => {
575 let addr = self.absolute_y();
576 let v = self.read_byte(addr);
577 self.and(v)
578 }
579
580 0x21 => {
582 let addr = self.indexed_indirect();
583 let v = self.read_byte(addr);
584 self.and(v)
585 }
586
587 0x31 => {
589 let addr = self.indirect_indexed();
590 let v = self.read_byte(addr);
591 self.and(v)
592 }
593
594 0x49 => {
596 let addr = self.immediate();
597 let v = self.read_byte(addr);
598 self.eor(v)
599 }
600
601 0x45 => {
603 let addr = self.zeropage();
604 let v = self.read_byte(addr);
605 self.eor(v)
606 }
607
608 0x55 => {
610 let addr = self.zeropage_x();
611 let v = self.read_byte(addr);
612 self.eor(v)
613 }
614
615 0x4D => {
617 let addr = self.absolute();
618 let v = self.read_byte(addr);
619 self.eor(v)
620 }
621
622 0x5D => {
624 let addr = self.absolute_x();
625 let v = self.read_byte(addr);
626 self.eor(v)
627 }
628
629 0x59 => {
631 let addr = self.absolute_y();
632 let v = self.read_byte(addr);
633 self.eor(v)
634 }
635
636 0x41 => {
638 let addr = self.indexed_indirect();
639 let v = self.read_byte(addr);
640 self.eor(v)
641 }
642
643 0x51 => {
645 let addr = self.indirect_indexed();
646 let v = self.read_byte(addr);
647 self.eor(v)
648 }
649
650 0x24 => {
652 let addr = self.zeropage();
653 let v = self.read_byte(addr);
654 self.bit(v)
655 }
656
657 0x2C => {
659 let addr = self.absolute();
660 let v = self.read_byte(addr);
661 self.bit(v)
662 }
663
664 0x69 => {
666 let addr = self.immediate();
667 let v = self.read_byte(addr);
668 self.adc(v)
669 }
670
671 0x65 => {
673 let addr = self.zeropage();
674 let v = self.read_byte(addr);
675 self.adc(v)
676 }
677
678 0x75 => {
680 let addr = self.zeropage_x();
681 let v = self.read_byte(addr);
682 self.adc(v)
683 }
684
685 0x6D => {
687 let addr = self.absolute();
688 let v = self.read_byte(addr);
689 self.adc(v)
690 }
691
692 0x7D => {
694 let addr = self.absolute_x();
695 let v = self.read_byte(addr);
696 self.adc(v)
697 }
698
699 0x79 => {
701 let addr = self.absolute_y();
702 let v = self.read_byte(addr);
703 self.adc(v)
704 }
705
706 0x61 => {
708 let addr = self.indexed_indirect();
709 let v = self.read_byte(addr);
710 self.adc(v)
711 }
712
713 0x71 => {
715 let addr = self.indirect_indexed();
716 let v = self.read_byte(addr);
717 self.adc(v)
718 }
719
720 0xE9 => {
722 let addr = self.immediate();
723 let v = self.read_byte(addr);
724 self.sbc(v)
725 }
726
727 0xE5 => {
729 let addr = self.zeropage();
730 let v = self.read_byte(addr);
731 self.sbc(v)
732 }
733
734 0xF5 => {
736 let addr = self.zeropage_x();
737 let v = self.read_byte(addr);
738 self.sbc(v)
739 }
740
741 0xED => {
743 let addr = self.absolute();
744 let v = self.read_byte(addr);
745 self.sbc(v)
746 }
747
748 0xFD => {
750 let addr = self.absolute_x();
751 let v = self.read_byte(addr);
752 self.sbc(v)
753 }
754
755 0xF9 => {
757 let addr = self.absolute_y();
758 let v = self.read_byte(addr);
759 self.sbc(v)
760 }
761
762 0xE1 => {
764 let addr = self.indexed_indirect();
765 let v = self.read_byte(addr);
766 self.sbc(v)
767 }
768
769 0xF1 => {
771 let addr = self.indirect_indexed();
772 let v = self.read_byte(addr);
773 self.sbc(v)
774 }
775
776 0xE6 => {
778 let addr = self.zeropage();
779 self.inc(addr)
780 }
781
782 0xF6 => {
784 let addr = self.zeropage_x();
785 self.inc(addr)
786 }
787
788 0xEE => {
790 let addr = self.absolute();
791 self.inc(addr)
792 }
793
794 0xFE => {
796 let addr = self.absolute_x();
797 self.inc(addr)
798 }
799
800 0xC6 => {
802 let addr = self.zeropage();
803 self.dec(addr)
804 }
805
806 0xD6 => {
808 let addr = self.zeropage_x();
809 self.dec(addr)
810 }
811
812 0xCE => {
814 let addr = self.absolute();
815 self.dec(addr)
816 }
817
818 0xDE => {
820 let addr = self.absolute_x();
821 self.dec(addr)
822 }
823
824 0xC9 => {
826 let addr = self.immediate();
827 self.cmp(self.a, self.read_byte(addr))
828 }
829
830 0xC5 => {
832 let addr = self.zeropage();
833 self.cmp(self.a, self.read_byte(addr))
834 }
835
836 0xD5 => {
838 let addr = self.zeropage_x();
839 self.cmp(self.a, self.read_byte(addr))
840 }
841
842 0xCD => {
844 let addr = self.absolute();
845 self.cmp(self.a, self.read_byte(addr))
846 }
847
848 0xDD => {
850 let addr = self.absolute_x();
851 self.cmp(self.a, self.read_byte(addr))
852 }
853
854 0xD9 => {
856 let addr = self.absolute_y();
857 self.cmp(self.a, self.read_byte(addr))
858 }
859
860 0xC1 => {
862 let addr = self.indexed_indirect();
863 self.cmp(self.a, self.read_byte(addr))
864 }
865
866 0xD1 => {
868 let addr = self.indirect_indexed();
869 self.cmp(self.a, self.read_byte(addr))
870 }
871
872 0xE0 => {
874 let addr = self.immediate();
875 self.cmp(self.x, self.read_byte(addr))
876 }
877
878 0xE4 => {
880 let addr = self.zeropage();
881 self.cmp(self.x, self.read_byte(addr))
882 }
883
884 0xEC => {
886 let addr = self.absolute();
887 self.cmp(self.x, self.read_byte(addr))
888 }
889
890 0xC0 => {
892 let addr = self.immediate();
893 self.cmp(self.y, self.read_byte(addr))
894 }
895
896 0xC4 => {
898 let addr = self.zeropage();
899 self.cmp(self.y, self.read_byte(addr))
900 }
901
902 0xCC => {
904 let addr = self.absolute();
905 self.cmp(self.y, self.read_byte(addr))
906 }
907
908 0xA9 => {
910 let addr = self.immediate();
911 let v = self.read_byte(addr);
912 self.a = v;
913 self.update_zn(v)
914 }
915
916 0xA5 => {
918 let addr = self.zeropage();
919 let v = self.read_byte(addr);
920 self.a = v;
921 self.update_zn(v)
922 }
923
924 0xB5 => {
926 let addr = self.zeropage_x();
927 let v = self.read_byte(addr);
928 self.a = v;
929 self.update_zn(v)
930 }
931
932 0xAD => {
934 let addr = self.absolute();
935 let v = self.read_byte(addr);
936 self.a = v;
937 self.update_zn(v)
938 }
939
940 0xBD => {
942 let addr = self.absolute_x();
943 let v = self.read_byte(addr);
944 self.a = v;
945 self.update_zn(v)
946 }
947
948 0xB9 => {
950 let addr = self.absolute_y();
951 let v = self.read_byte(addr);
952 self.a = v;
953 self.update_zn(v)
954 }
955
956 0xA1 => {
958 let addr = self.indexed_indirect();
959 let v = self.read_byte(addr);
960 self.a = v;
961 self.update_zn(v)
962 }
963
964 0xB1 => {
966 let addr = self.indirect_indexed();
967 let v = self.read_byte(addr);
968 self.a = v;
969 self.update_zn(v)
970 }
971
972 0xA2 => {
974 let addr = self.immediate();
975 let v = self.read_byte(addr);
976 self.x = v;
977 self.update_zn(v)
978 }
979
980 0xA6 => {
982 let addr = self.zeropage();
983 let v = self.read_byte(addr);
984 self.x = v;
985 self.update_zn(v)
986 }
987
988 0xB6 => {
990 let addr = self.zeropage_y();
991 let v = self.read_byte(addr);
992 self.x = v;
993 self.update_zn(v)
994 }
995
996 0xAE => {
998 let addr = self.absolute();
999 let v = self.read_byte(addr);
1000 self.x = v;
1001 self.update_zn(v)
1002 }
1003
1004 0xBE => {
1006 let addr = self.absolute_y();
1007 let v = self.read_byte(addr);
1008 self.x = v;
1009 self.update_zn(v)
1010 }
1011
1012 0xA0 => {
1014 let addr = self.immediate();
1015 let v = self.read_byte(addr);
1016 self.y = v;
1017 self.update_zn(v)
1018 }
1019
1020 0xA4 => {
1022 let addr = self.zeropage();
1023 let v = self.read_byte(addr);
1024 self.y = v;
1025 self.update_zn(v)
1026 }
1027
1028 0xB4 => {
1030 let addr = self.zeropage_x();
1031 let v = self.read_byte(addr);
1032 self.y = v;
1033 self.update_zn(v)
1034 }
1035
1036 0xAC => {
1038 let addr = self.absolute();
1039 let v = self.read_byte(addr);
1040 self.y = v;
1041 self.update_zn(v)
1042 }
1043
1044 0xBC => {
1046 let addr = self.absolute_x();
1047 let v = self.read_byte(addr);
1048 self.y = v;
1049 self.update_zn(v)
1050 }
1051
1052 0x85 => {
1054 let addr = self.zeropage();
1055 self.write_byte(addr, self.a)
1056 }
1057
1058 0x95 => {
1060 let addr = self.zeropage_x();
1061 self.write_byte(addr, self.a)
1062 }
1063
1064 0x8D => {
1066 let addr = self.absolute();
1067 self.write_byte(addr, self.a)
1068 }
1069
1070 0x9D => {
1072 let addr = self.absolute_x();
1073 self.write_byte(addr, self.a)
1074 }
1075
1076 0x99 => {
1078 let addr = self.absolute_y();
1079 self.write_byte(addr, self.a)
1080 }
1081
1082 0x81 => {
1084 let addr = self.indexed_indirect();
1085 self.write_byte(addr, self.a)
1086 }
1087
1088 0x91 => {
1090 let addr = self.indirect_indexed();
1091 self.write_byte(addr, self.a)
1092 }
1093
1094 0x86 => {
1096 let addr = self.zeropage();
1097 self.write_byte(addr, self.x)
1098 }
1099
1100 0x96 => {
1102 let addr = self.zeropage_y();
1103 self.write_byte(addr, self.x)
1104 }
1105
1106 0x8E => {
1108 let addr = self.absolute();
1109 self.write_byte(addr, self.x)
1110 }
1111
1112 0x84 => {
1114 let addr = self.zeropage();
1115 self.write_byte(addr, self.y)
1116 }
1117
1118 0x94 => {
1120 let addr = self.zeropage_x();
1121 self.write_byte(addr, self.y)
1122 }
1123
1124 0x8C => {
1126 let addr = self.absolute();
1127 self.write_byte(addr, self.y)
1128 }
1129
1130 0xAA => {
1132 self.x = self.a;
1133 self.update_zn(self.x)
1134 }
1135
1136 0xA8 => {
1138 self.y = self.a;
1139 self.update_zn(self.y)
1140 }
1141
1142 0x8A => {
1144 self.a = self.x;
1145 self.update_zn(self.a)
1146 }
1147
1148 0x98 => {
1150 self.a = self.y;
1151 self.update_zn(self.a)
1152 }
1153
1154 0xBA => {
1156 self.x = self.sp;
1157 self.update_zn(self.x)
1158 }
1159
1160 0x9A => self.sp = self.x,
1162
1163 0x48 => self.push(self.a),
1165
1166 0x68 => {
1168 let v = self.pop();
1169 self.a = v;
1170 self.update_zn(v)
1171 }
1172
1173 0x08 => self.push(self.status | Self::STATUS_FLAG_B | Self::STATUS_FLAG_U),
1175
1176 0x28 => {
1178 self.status = self.pop();
1179 self.status |= Self::STATUS_FLAG_U
1180 }
1181
1182 0x0A => self.asl_acc(),
1184
1185 0x06 => {
1187 let addr = self.zeropage();
1188 self.asl_mem(addr)
1189 }
1190
1191 0x16 => {
1193 let addr = self.zeropage_x();
1194 self.asl_mem(addr)
1195 }
1196
1197 0x0E => {
1199 let addr = self.absolute();
1200 self.asl_mem(addr)
1201 }
1202
1203 0x1E => {
1205 let addr = self.absolute_x();
1206 self.asl_mem(addr)
1207 }
1208
1209 0x4A => self.lsr_acc(),
1211
1212 0x46 => {
1214 let addr = self.zeropage();
1215 self.lsr_mem(addr)
1216 }
1217
1218 0x56 => {
1220 let addr = self.zeropage_x();
1221 self.lsr_mem(addr)
1222 }
1223
1224 0x4E => {
1226 let addr = self.absolute();
1227 self.lsr_mem(addr)
1228 }
1229
1230 0x5E => {
1232 let addr = self.absolute_x();
1233 self.lsr_mem(addr)
1234 }
1235
1236 0x2A => self.rol_acc(),
1238
1239 0x26 => {
1241 let addr = self.zeropage();
1242 self.rol_mem(addr)
1243 }
1244
1245 0x36 => {
1247 let addr = self.zeropage_x();
1248 self.rol_mem(addr)
1249 }
1250
1251 0x2E => {
1253 let addr = self.absolute();
1254 self.rol_mem(addr)
1255 }
1256
1257 0x3E => {
1259 let addr = self.absolute_x();
1260 self.rol_mem(addr)
1261 }
1262
1263 0x6A => self.ror_acc(),
1265
1266 0x66 => {
1268 let addr = self.zeropage();
1269 self.ror_mem(addr)
1270 }
1271
1272 0x76 => {
1274 let addr = self.zeropage_x();
1275 self.ror_mem(addr)
1276 }
1277
1278 0x6E => {
1280 let addr = self.absolute();
1281 self.ror_mem(addr)
1282 }
1283
1284 0x7E => {
1286 let addr = self.absolute_x();
1287 self.ror_mem(addr)
1288 }
1289
1290 0xEA => {}
1292
1293 _op => {}
1295 }
1296 }
1297}
1298
1299impl core::fmt::Debug for CentralProcessingUnit {
1300 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1301 writeln!(f, "6502 CPU State:")?;
1302 writeln!(f, " PC : {:#06X}", self.pc)?;
1303 writeln!(f, " A : {:#04X}", self.a)?;
1304 writeln!(f, " X : {:#04X}", self.x)?;
1305 writeln!(f, " Y : {:#04X}", self.y)?;
1306 writeln!(f, " SP : {:#04X}", self.sp)?;
1307 writeln!(f, " STATUS : {:#04X}", self.status)?;
1308
1309 Ok(())
1310 }
1311}
1312
1313impl core::fmt::Display for CentralProcessingUnit {
1314 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1315 writeln!(f, "6502 CPU State:")?;
1316 writeln!(f, " PC : {:#06X}", self.pc)?;
1317 writeln!(f, " A : {:#04X}", self.a)?;
1318 writeln!(f, " X : {:#04X}", self.x)?;
1319 writeln!(f, " Y : {:#04X}", self.y)?;
1320 writeln!(f, " SP : {:#04X}", self.sp)?;
1321 writeln!(f, " STATUS : {:#04X}", self.status)?;
1322
1323 Ok(())
1324 }
1325}