virt_ic/chip/cpu/
nes6502.rs

1pub mod assembler;
2pub mod opcodes;
3
4pub use assembler::Assembler;
5pub use opcodes::{AddressingMode, Opcode};
6
7use crate::{
8    chip::{ChipBuilder, ChipRunner, ChipSet, Pin, PinType},
9    generate_chip, State,
10};
11
12use bitflags::bitflags;
13
14use super::Reg;
15
16bitflags! {
17    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19    pub struct StatusRegister: u8 {
20        /// Negative
21        const N = 0b10000000;
22        /// Overflow
23        const V = 0b01000000;
24        /// Break
25        const B = 0b00010000;
26        /// Decimal
27        const D = 0b00001000;
28        /// Interrupt Disable
29        const I = 0b00000100;
30        /// Zero
31        const Z = 0b00000010;
32        /// Carry
33        const C = 0b00000001;
34    }
35}
36
37#[derive(Debug, Clone, Copy)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub enum CpuState {
40    Reset,
41    ResetCollectHighByte,
42    ResetCollectLowByte,
43    NmiCollectHighByte,
44    NmiCollectLowByte,
45    IrqCollectHighByte,
46    IrqCollectLowByte,
47    Fetch,
48    Arg1(Opcode),
49    Arg2(Opcode),
50    Execute(Opcode, usize),
51    Halted,
52}
53
54#[derive(Debug, Clone, Copy, Default)]
55#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56pub struct Registers {
57    pub a: Reg<u8>,
58    pub x: Reg<u8>,
59    pub y: Reg<u8>,
60    pub pc: Reg<u16>,
61    pub s: Reg<u8>,
62    pub p: StatusRegister,
63}
64
65impl ToString for Registers {
66    fn to_string(&self) -> std::string::String {
67        format!(
68            "A={:0X}\tX={:0X}\tY={:0X}\tS={:0X}\tPC={:0X}\tP={}{}{}{}{}{}{}{}",
69            *self.a,
70            *self.x,
71            *self.y,
72            *self.s,
73            *self.pc,
74            if self.p.contains(StatusRegister::N) {
75                "N"
76            } else {
77                "-"
78            },
79            if self.p.contains(StatusRegister::V) {
80                "V"
81            } else {
82                "-"
83            },
84            "-",
85            if self.p.contains(StatusRegister::B) {
86                "B"
87            } else {
88                "-"
89            },
90            if self.p.contains(StatusRegister::D) {
91                "D"
92            } else {
93                "-"
94            },
95            if self.p.contains(StatusRegister::I) {
96                "I"
97            } else {
98                "-"
99            },
100            if self.p.contains(StatusRegister::Z) {
101                "Z"
102            } else {
103                "-"
104            },
105            if self.p.contains(StatusRegister::C) {
106                "C"
107            } else {
108                "-"
109            },
110        )
111    }
112}
113
114/// <https://www.nesdev.org/wiki/CPU_pinout>
115/// Without the APU part yet  
116/// Neither the interrupt handling and decimal mode  
117/// WARNING: Not cycle accurate yet!
118///
119/// ```txt
120///         .--\/--.
121///  AD1 <- |01  40| -- +5V
122///  AD2 <- |02  39| -> OUT0
123/// /RST -> |03  38| -> OUT1
124///  A00 <- |04  37| -> OUT2
125///  A01 <- |05  36| -> /OE1
126///  A02 <- |06  35| -> /OE2
127///  A03 <- |07  34| -> R/W
128///  A04 <- |08  33| <- /NMI
129///  A05 <- |09  32| <- /IRQ
130///  A06 <- |10  31| -> M2
131///  A07 <- |11  30| <- TST (usually GND)
132///  A08 <- |12  29| <- CLK
133///  A09 <- |13  28| <> D0
134///  A10 <- |14  27| <> D1
135///  A11 <- |15  26| <> D2
136///  A12 <- |16  25| <> D3
137///  A13 <- |17  24| <> D4
138///  A14 <- |18  23| <> D5
139///  A15 <- |19  22| <> D6
140///  GND -- |20  21| <> D7
141///         `------'
142/// ```
143#[derive(Debug, Clone)]
144#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
145pub struct Nes6502 {
146    powered: bool,
147    clock: bool,
148    state: CpuState,
149    registers: Registers,
150    buffer: u16,
151    pub vcc: Pin,
152    pub gnd: Pin,
153    pub rst: Pin,
154    pub out0: Pin,
155    pub out1: Pin,
156    pub out2: Pin,
157    pub oe1: Pin,
158    pub oe2: Pin,
159    pub rw: Pin,
160    pub nmi: Pin,
161    pub irq: Pin,
162    pub m2: Pin,
163    pub tst: Pin,
164    pub clk: Pin,
165    pub ad1: Pin,
166    pub ad2: Pin,
167    pub a0: Pin,
168    pub a1: Pin,
169    pub a2: Pin,
170    pub a3: Pin,
171    pub a4: Pin,
172    pub a5: Pin,
173    pub a6: Pin,
174    pub a7: Pin,
175    pub a8: Pin,
176    pub a9: Pin,
177    pub a10: Pin,
178    pub a11: Pin,
179    pub a12: Pin,
180    pub a13: Pin,
181    pub a14: Pin,
182    pub a15: Pin,
183    pub d0: Pin,
184    pub d1: Pin,
185    pub d2: Pin,
186    pub d3: Pin,
187    pub d4: Pin,
188    pub d5: Pin,
189    pub d6: Pin,
190    pub d7: Pin,
191}
192
193impl Nes6502 {
194    pub const VCC: usize = 40;
195    pub const GND: usize = 20;
196    pub const RST: usize = 3;
197    pub const OUT0: usize = 39;
198    pub const OUT1: usize = 38;
199    pub const OUT2: usize = 37;
200    pub const OE1: usize = 36;
201    pub const OE2: usize = 35;
202    /// Read/write signal, which is used to indicate operations of the same names. Low is write. R/W stays high/low during the entire read/write cycle.
203    pub const RW: usize = 34;
204    /// Non-maskable interrupt pin. See the 6502 manual and CPU interrupts for more details.
205    pub const NMI: usize = 33;
206    /// Interrupt pin. See the 6502 manual and CPU interrupts for more details
207    pub const IRQ: usize = 32;
208    pub const M2: usize = 31;
209    pub const TST: usize = 30;
210    pub const CLK: usize = 29;
211    pub const AD1: usize = 1;
212    pub const AD2: usize = 2;
213    pub const A0: usize = 4;
214    pub const A1: usize = 5;
215    pub const A2: usize = 6;
216    pub const A3: usize = 7;
217    pub const A4: usize = 8;
218    pub const A5: usize = 9;
219    pub const A6: usize = 10;
220    pub const A7: usize = 11;
221    pub const A8: usize = 12;
222    pub const A9: usize = 13;
223    pub const A10: usize = 14;
224    pub const A11: usize = 15;
225    pub const A12: usize = 16;
226    pub const A13: usize = 17;
227    pub const A14: usize = 18;
228    pub const A15: usize = 19;
229    pub const D0: usize = 28;
230    pub const D1: usize = 27;
231    pub const D2: usize = 26;
232    pub const D3: usize = 25;
233    pub const D4: usize = 24;
234    pub const D5: usize = 23;
235    pub const D6: usize = 22;
236    pub const D7: usize = 21;
237}
238
239generate_chip!(
240    Nes6502,
241    vcc: Nes6502::VCC,
242    gnd: Nes6502::GND,
243    rst: Nes6502::RST,
244    out0: Nes6502::OUT0,
245    out1: Nes6502::OUT1,
246    out2: Nes6502::OUT2,
247    oe1: Nes6502::OE1,
248    oe2: Nes6502::OE2,
249    rw: Nes6502::RW,
250    nmi: Nes6502::NMI,
251    irq: Nes6502::IRQ,
252    m2: Nes6502::M2,
253    tst: Nes6502::TST,
254    clk: Nes6502::CLK,
255    ad1: Nes6502::AD1,
256    ad2: Nes6502::AD2,
257    a0: Nes6502::A0,
258    a1: Nes6502::A1,
259    a2: Nes6502::A2,
260    a3: Nes6502::A3,
261    a4: Nes6502::A4,
262    a5: Nes6502::A5,
263    a6: Nes6502::A6,
264    a7: Nes6502::A7,
265    a8: Nes6502::A8,
266    a9: Nes6502::A9,
267    a10: Nes6502::A10,
268    a11: Nes6502::A11,
269    a12: Nes6502::A12,
270    a13: Nes6502::A13,
271    a14: Nes6502::A14,
272    a15: Nes6502::A15,
273    d0: Nes6502::D0,
274    d1: Nes6502::D1,
275    d2: Nes6502::D2,
276    d3: Nes6502::D3,
277    d4: Nes6502::D4,
278    d5: Nes6502::D5,
279    d6: Nes6502::D6,
280    d7: Nes6502::D7
281);
282
283impl ChipBuilder<ChipSet> for Nes6502 {
284    fn build() -> ChipSet {
285        ChipSet::Nes6502(Box::new(Nes6502 {
286            powered: false,
287            clock: false,
288            state: CpuState::Reset,
289            registers: Registers::default(),
290            buffer: 0,
291            vcc: Pin::from(PinType::Input),
292            gnd: Pin::from(PinType::Output),
293            rst: Pin::from(PinType::Input),
294            out0: Pin::from(PinType::Output),
295            out1: Pin::from(PinType::Output),
296            out2: Pin::from(PinType::Output),
297            oe1: Pin::from(PinType::Output),
298            oe2: Pin::from(PinType::Output),
299            rw: Pin::from(PinType::Output),
300            nmi: Pin::from(PinType::Input),
301            irq: Pin::from(PinType::Input),
302            m2: Pin::from(PinType::Output),
303            tst: Pin::from(PinType::Input),
304            clk: Pin::from(PinType::Input),
305            ad1: Pin::from(PinType::Output),
306            ad2: Pin::from(PinType::Output),
307            a0: Pin::from(PinType::Output),
308            a1: Pin::from(PinType::Output),
309            a2: Pin::from(PinType::Output),
310            a3: Pin::from(PinType::Output),
311            a4: Pin::from(PinType::Output),
312            a5: Pin::from(PinType::Output),
313            a6: Pin::from(PinType::Output),
314            a7: Pin::from(PinType::Output),
315            a8: Pin::from(PinType::Output),
316            a9: Pin::from(PinType::Output),
317            a10: Pin::from(PinType::Output),
318            a11: Pin::from(PinType::Output),
319            a12: Pin::from(PinType::Output),
320            a13: Pin::from(PinType::Output),
321            a14: Pin::from(PinType::Output),
322            a15: Pin::from(PinType::Output),
323            d0: Pin::from(PinType::Floating),
324            d1: Pin::from(PinType::Floating),
325            d2: Pin::from(PinType::Floating),
326            d3: Pin::from(PinType::Floating),
327            d4: Pin::from(PinType::Floating),
328            d5: Pin::from(PinType::Floating),
329            d6: Pin::from(PinType::Floating),
330            d7: Pin::from(PinType::Floating),
331        }))
332    }
333}
334
335impl Nes6502 {
336    pub fn set_addr(&mut self, addr: u16) {
337        Pin::write(
338            &mut [
339                &mut self.a0,
340                &mut self.a1,
341                &mut self.a2,
342                &mut self.a3,
343                &mut self.a4,
344                &mut self.a5,
345                &mut self.a6,
346                &mut self.a7,
347                &mut self.a8,
348                &mut self.a9,
349                &mut self.a10,
350                &mut self.a11,
351                &mut self.a12,
352                &mut self.a13,
353                &mut self.a14,
354                &mut self.a15,
355            ],
356            addr as usize,
357        );
358    }
359
360    fn set_data_type(&mut self, pin_type: PinType) {
361        match pin_type {
362            PinType::Input => self.rw.state = State::High,
363            PinType::Output => self.rw.state = State::Low,
364            PinType::Floating => {}
365        }
366        self.d0.pin_type = pin_type;
367        self.d1.pin_type = pin_type;
368        self.d2.pin_type = pin_type;
369        self.d3.pin_type = pin_type;
370        self.d4.pin_type = pin_type;
371        self.d5.pin_type = pin_type;
372        self.d6.pin_type = pin_type;
373        self.d7.pin_type = pin_type;
374    }
375
376    pub fn set_data(&mut self, data: u8) {
377        Pin::write(
378            &mut [
379                &mut self.d0,
380                &mut self.d1,
381                &mut self.d2,
382                &mut self.d3,
383                &mut self.d4,
384                &mut self.d5,
385                &mut self.d6,
386                &mut self.d7,
387            ],
388            data as usize,
389        );
390    }
391
392    pub fn get_data(&self) -> u8 {
393        Pin::read_threshold(
394            &[
395                &self.d0, &self.d1, &self.d2, &self.d3, &self.d4, &self.d5, &self.d6, &self.d7,
396            ],
397            3.3,
398        ) as u8
399    }
400}
401
402impl ChipRunner for Nes6502 {
403    fn run(&mut self, _: std::time::Duration) {
404        if self.vcc.state.as_logic(3.3) == State::High {
405            if !self.powered {
406                self.state = CpuState::Reset;
407                self.registers.p = StatusRegister::from_bits_retain(0x34);
408                self.registers.a = 0.into();
409                self.registers.x = 0.into();
410                self.registers.y = 0.into();
411                self.registers.s = 0xFD.into();
412                self.registers.pc = 0xFFFC.into();
413
414                self.powered = true;
415            }
416
417            if self.clock != self.clk.state.as_logic(3.3).into() {
418                self.clock = self.clk.state.as_logic(3.3).into();
419                self.m2.state = State::from(self.clock);
420                if self.clock {
421                    match self.state {
422                        CpuState::Reset
423                        | CpuState::ResetCollectHighByte
424                        | CpuState::ResetCollectLowByte
425                        | CpuState::NmiCollectHighByte
426                        | CpuState::NmiCollectLowByte
427                        | CpuState::IrqCollectHighByte
428                        | CpuState::IrqCollectLowByte
429                        | CpuState::Fetch
430                        | CpuState::Arg1(_)
431                        | CpuState::Arg2(_) => {
432                            self.set_data_type(PinType::Input);
433                        }
434                        CpuState::Execute(_, _) => {}
435                        CpuState::Halted => self.set_data_type(PinType::Floating),
436                    }
437                } else {
438                    match self.state {
439                        CpuState::Reset => {
440                            self.set_addr(*self.registers.pc);
441                            self.registers.pc.inc();
442                            self.state = CpuState::ResetCollectHighByte;
443                        }
444                        CpuState::ResetCollectHighByte => {
445                            self.buffer = (self.get_data() as u16) << 8;
446                            self.set_addr(*self.registers.pc);
447                            self.registers.pc.inc();
448                            self.state = CpuState::ResetCollectLowByte;
449                        }
450                        CpuState::ResetCollectLowByte => {
451                            self.buffer = self.buffer.wrapping_add(self.get_data() as u16);
452                            self.registers.pc = self.buffer.into();
453                            self.set_addr(*self.registers.pc);
454                            self.registers.pc.inc();
455                            self.state = CpuState::Fetch;
456                        }
457                        CpuState::NmiCollectHighByte => todo!(),
458                        CpuState::NmiCollectLowByte => todo!(),
459                        CpuState::IrqCollectHighByte => todo!(),
460                        CpuState::IrqCollectLowByte => todo!(),
461                        CpuState::Fetch => {
462                            let opcode = Opcode::from(self.get_data());
463                            if opcode.require_arg1() {
464                                self.set_addr(*self.registers.pc);
465                                self.registers.pc.inc();
466                                self.state = CpuState::Arg1(opcode);
467                            } else {
468                                self.state = CpuState::Execute(opcode, 0);
469                            }
470                        }
471                        CpuState::Arg1(mut opcode) => {
472                            opcode.set_arg1(self.get_data());
473                            if opcode.require_arg2() {
474                                self.set_addr(*self.registers.pc);
475                                self.registers.pc.inc();
476                                self.state = CpuState::Arg2(opcode);
477                            } else {
478                                self.state = CpuState::Execute(opcode, 0);
479                            }
480                        }
481                        CpuState::Arg2(mut opcode) => {
482                            opcode.set_arg2(self.get_data());
483                            self.state = CpuState::Execute(opcode, 0);
484                        }
485                        CpuState::Execute(mut opcode, mut step) => {
486                            if opcode.need_compute() {
487                                opcode.compute(self, step);
488                                if !opcode.need_compute() {
489                                    step = 0;
490                                } else {
491                                    step += 1;
492                                }
493                            } else {
494                                match opcode {
495                                    Opcode::ADC(a) => match a {
496                                        AddressingMode::Immediate(i) => self.run_adc(i),
497                                        AddressingMode::ZeroPage(z) => {
498                                            if step == 0 {
499                                                self.set_addr(z as u16);
500                                                self.set_data_type(PinType::Input);
501                                                step += 1;
502                                            } else {
503                                                self.run_adc(self.get_data());
504                                            }
505                                        }
506                                        AddressingMode::Absolute(a) => {
507                                            if step == 0 {
508                                                self.set_addr(a);
509                                                self.set_data_type(PinType::Input);
510                                                step += 1;
511                                            } else {
512                                                self.run_adc(self.get_data());
513                                            }
514                                        }
515                                        _ => unreachable!(),
516                                    },
517                                    Opcode::AND(a) => match a {
518                                        AddressingMode::Immediate(i) => self.run_and(i),
519                                        AddressingMode::ZeroPage(z) => {
520                                            if step == 0 {
521                                                self.set_addr(z as u16);
522                                                self.set_data_type(PinType::Input);
523                                                step += 1;
524                                            } else {
525                                                self.run_and(self.get_data());
526                                            }
527                                        }
528                                        AddressingMode::Absolute(a) => {
529                                            if step == 0 {
530                                                self.set_addr(a);
531                                                self.set_data_type(PinType::Input);
532                                                step += 1;
533                                            } else {
534                                                self.run_and(self.get_data());
535                                            }
536                                        }
537                                        _ => unreachable!(),
538                                    },
539                                    Opcode::ASL(a) => match a {
540                                        AddressingMode::Implicit => {
541                                            self.registers.p.set(
542                                                StatusRegister::C,
543                                                (self.registers.a & 0x80) > 0,
544                                            );
545                                            self.registers.a <<= 1;
546                                            self.set_flags_nz(*self.registers.a);
547                                            self.state = CpuState::Fetch;
548                                        }
549                                        AddressingMode::ZeroPage(z) => {
550                                            if step == 0 {
551                                                self.set_addr(z as u16);
552                                                self.set_data_type(PinType::Input);
553                                                step += 1;
554                                            } else if step == 1 {
555                                                let mut data = self.get_data();
556                                                self.registers
557                                                    .p
558                                                    .set(StatusRegister::C, (data & 0x80) > 0);
559                                                data <<= 1;
560                                                self.set_data(data);
561                                                self.set_data_type(PinType::Output);
562                                                self.set_flags_nz(data);
563                                                step += 1;
564                                            } else {
565                                                self.state = CpuState::Fetch
566                                            }
567                                        }
568                                        AddressingMode::Absolute(a) => {
569                                            if step == 0 {
570                                                self.set_addr(a);
571                                                self.set_data_type(PinType::Input);
572                                                step += 1;
573                                            } else if step == 1 {
574                                                let mut data = self.get_data();
575                                                self.registers
576                                                    .p
577                                                    .set(StatusRegister::C, (data & 0x80) > 0);
578                                                data <<= 1;
579                                                self.set_data(data);
580                                                self.set_data_type(PinType::Output);
581                                                self.set_flags_nz(data);
582                                                step += 1;
583                                            } else {
584                                                self.state = CpuState::Fetch
585                                            }
586                                        }
587                                        _ => unreachable!(),
588                                    },
589                                    Opcode::BIT(a) => match a {
590                                        AddressingMode::ZeroPage(z) => {
591                                            if step == 0 {
592                                                self.set_addr(z as u16);
593                                                self.set_data_type(PinType::Input);
594                                                step += 1;
595                                            } else {
596                                                self.run_bit(self.get_data());
597                                            }
598                                        }
599                                        AddressingMode::Absolute(a) => {
600                                            if step == 0 {
601                                                self.set_addr(a);
602                                                self.set_data_type(PinType::Input);
603                                                step += 1;
604                                            } else {
605                                                self.run_bit(self.get_data());
606                                            }
607                                        }
608                                        _ => unreachable!(),
609                                    },
610                                    Opcode::BPL(ra) => {
611                                        if !self.registers.p.contains(StatusRegister::N) {
612                                            self.jump_relative(ra);
613                                        }
614                                        self.state = CpuState::Fetch;
615                                    }
616                                    Opcode::BMI(ra) => {
617                                        if self.registers.p.contains(StatusRegister::N) {
618                                            self.jump_relative(ra);
619                                        }
620                                        self.state = CpuState::Fetch;
621                                    }
622                                    Opcode::BVC(ra) => {
623                                        if !self.registers.p.contains(StatusRegister::V) {
624                                            self.jump_relative(ra);
625                                        }
626                                        self.state = CpuState::Fetch;
627                                    }
628                                    Opcode::BVS(ra) => {
629                                        if self.registers.p.contains(StatusRegister::V) {
630                                            self.jump_relative(ra);
631                                        }
632                                        self.state = CpuState::Fetch;
633                                    }
634                                    Opcode::BCC(ra) => {
635                                        if !self.registers.p.contains(StatusRegister::C) {
636                                            self.jump_relative(ra);
637                                        }
638                                        self.state = CpuState::Fetch;
639                                    }
640                                    Opcode::BCS(ra) => {
641                                        if self.registers.p.contains(StatusRegister::C) {
642                                            self.jump_relative(ra);
643                                        }
644                                        self.state = CpuState::Fetch;
645                                    }
646                                    Opcode::BNE(ra) => {
647                                        if !self.registers.p.contains(StatusRegister::Z) {
648                                            self.jump_relative(ra);
649                                        }
650                                        self.state = CpuState::Fetch;
651                                    }
652                                    Opcode::BEQ(ra) => {
653                                        if self.registers.p.contains(StatusRegister::Z) {
654                                            self.jump_relative(ra);
655                                        }
656                                        self.state = CpuState::Fetch;
657                                    }
658                                    Opcode::BRK => todo!(),
659                                    Opcode::CMP(a) => match a {
660                                        AddressingMode::Immediate(i) => {
661                                            self.run_cmp(self.registers.a, i);
662                                        }
663                                        AddressingMode::ZeroPage(z) => {
664                                            if step == 0 {
665                                                self.set_addr(z as u16);
666                                                self.set_data_type(PinType::Input);
667                                                step += 1;
668                                            } else {
669                                                self.run_cmp(self.registers.a, self.get_data());
670                                            }
671                                        }
672                                        AddressingMode::Absolute(a) => {
673                                            if step == 0 {
674                                                self.set_addr(a);
675                                                self.set_data_type(PinType::Input);
676                                                step += 1;
677                                            } else {
678                                                self.run_cmp(self.registers.a, self.get_data());
679                                            }
680                                        }
681                                        _ => unreachable!(),
682                                    },
683                                    Opcode::CPX(a) => match a {
684                                        AddressingMode::Immediate(i) => {
685                                            self.run_cmp(self.registers.x, i);
686                                        }
687                                        AddressingMode::ZeroPage(z) => {
688                                            if step == 0 {
689                                                self.set_addr(z as u16);
690                                                self.set_data_type(PinType::Input);
691                                                step += 1;
692                                            } else {
693                                                self.run_cmp(self.registers.x, self.get_data());
694                                            }
695                                        }
696                                        AddressingMode::Absolute(a) => {
697                                            if step == 0 {
698                                                self.set_addr(a);
699                                                self.set_data_type(PinType::Input);
700                                                step += 1;
701                                            } else {
702                                                self.run_cmp(self.registers.x, self.get_data());
703                                            }
704                                        }
705                                        _ => unreachable!(),
706                                    },
707                                    Opcode::CPY(a) => match a {
708                                        AddressingMode::Immediate(i) => {
709                                            self.run_cmp(self.registers.y, i);
710                                        }
711                                        AddressingMode::ZeroPage(z) => {
712                                            if step == 0 {
713                                                self.set_addr(z as u16);
714                                                self.set_data_type(PinType::Input);
715                                                step += 1;
716                                            } else {
717                                                self.run_cmp(self.registers.y, self.get_data());
718                                            }
719                                        }
720                                        AddressingMode::Absolute(a) => {
721                                            if step == 0 {
722                                                self.set_addr(a);
723                                                self.set_data_type(PinType::Input);
724                                                step += 1;
725                                            } else {
726                                                self.run_cmp(self.registers.y, self.get_data());
727                                            }
728                                        }
729                                        _ => unreachable!(),
730                                    },
731                                    Opcode::DEC(a) => match a {
732                                        AddressingMode::ZeroPage(z) => {
733                                            if step == 0 {
734                                                self.set_addr(z as u16);
735                                                self.set_data_type(PinType::Input);
736                                                step += 1;
737                                            } else if step == 1 {
738                                                let data = self.get_data().wrapping_sub(1);
739                                                self.set_flags_nz(data);
740                                                self.set_data(data);
741                                                self.set_data_type(PinType::Output);
742                                                step += 1;
743                                            } else {
744                                                self.state = CpuState::Fetch;
745                                            }
746                                        }
747                                        AddressingMode::Absolute(a) => {
748                                            if step == 0 {
749                                                self.set_addr(a);
750                                                self.set_data_type(PinType::Input);
751                                                step += 1;
752                                            } else if step == 1 {
753                                                let data = self.get_data().wrapping_sub(1);
754                                                self.set_flags_nz(data);
755                                                self.set_data(data);
756                                                self.set_data_type(PinType::Output);
757                                                step += 1;
758                                            } else {
759                                                self.state = CpuState::Fetch;
760                                            }
761                                        }
762                                        _ => unreachable!(),
763                                    },
764                                    Opcode::EOR(a) => match a {
765                                        AddressingMode::Immediate(i) => self.run_eor(i),
766                                        AddressingMode::ZeroPage(z) => {
767                                            if step == 0 {
768                                                self.set_addr(z as u16);
769                                                self.set_data_type(PinType::Input);
770                                                step += 1;
771                                            } else {
772                                                self.run_eor(self.get_data());
773                                            }
774                                        }
775                                        AddressingMode::Absolute(a) => {
776                                            if step == 0 {
777                                                self.set_addr(a);
778                                                self.set_data_type(PinType::Input);
779                                                step += 1;
780                                            } else {
781                                                self.run_eor(self.get_data());
782                                            }
783                                        }
784                                        _ => unreachable!(),
785                                    },
786                                    Opcode::CLC => {
787                                        self.registers.p.set(StatusRegister::C, false);
788                                        self.state = CpuState::Fetch
789                                    }
790                                    Opcode::SEC => {
791                                        self.registers.p.set(StatusRegister::C, true);
792                                        self.state = CpuState::Fetch
793                                    }
794                                    Opcode::CLI => {
795                                        self.registers.p.set(StatusRegister::I, false);
796                                        self.state = CpuState::Fetch
797                                    }
798                                    Opcode::SEI => {
799                                        self.registers.p.set(StatusRegister::I, true);
800                                        self.state = CpuState::Fetch
801                                    }
802                                    Opcode::CLV => {
803                                        self.registers.p.set(StatusRegister::V, false);
804                                        self.state = CpuState::Fetch
805                                    }
806                                    Opcode::INC(a) => match a {
807                                        AddressingMode::ZeroPage(z) => {
808                                            if step == 0 {
809                                                self.set_addr(z as u16);
810                                                self.set_data_type(PinType::Input);
811                                                step += 1;
812                                            } else if step == 1 {
813                                                let data = self.get_data().wrapping_add(1);
814                                                self.set_flags_nz(data);
815                                                self.set_data(data);
816                                                self.set_data_type(PinType::Output);
817                                                step += 1;
818                                            } else {
819                                                self.state = CpuState::Fetch;
820                                            }
821                                        }
822                                        AddressingMode::Absolute(a) => {
823                                            if step == 0 {
824                                                self.set_addr(a);
825                                                self.set_data_type(PinType::Input);
826                                                step += 1;
827                                            } else if step == 1 {
828                                                let data = self.get_data().wrapping_add(1);
829                                                self.set_flags_nz(data);
830                                                self.set_data(data);
831                                                self.set_data_type(PinType::Output);
832                                                step += 1;
833                                            } else {
834                                                self.state = CpuState::Fetch;
835                                            }
836                                        }
837                                        _ => unreachable!(),
838                                    },
839                                    Opcode::JMP(AddressingMode::Absolute(a)) => {
840                                        self.registers.pc = a.into();
841                                        self.state = CpuState::Fetch;
842                                    }
843                                    Opcode::JMP(_) => unreachable!(),
844                                    Opcode::JSR(AddressingMode::Absolute(a)) => {
845                                        if step == 0 {
846                                            let alt_pc = (*self.registers.pc).wrapping_sub(1);
847                                            self.push_stack((alt_pc >> 8) as u8);
848                                            step += 1;
849                                        } else if step == 1 {
850                                            let alt_pc = (*self.registers.pc).wrapping_sub(1);
851                                            self.push_stack(alt_pc as u8);
852                                            step += 1;
853                                        } else {
854                                            self.registers.pc = a.into();
855                                            self.state = CpuState::Fetch;
856                                        }
857                                    }
858                                    Opcode::JSR(_) => unreachable!(),
859                                    Opcode::LDA(a) => match a {
860                                        AddressingMode::Immediate(i) => {
861                                            self.run_lda(i);
862                                        }
863                                        AddressingMode::ZeroPage(z) => {
864                                            if step == 0 {
865                                                self.set_addr(z as u16);
866                                                self.set_data_type(PinType::Input);
867                                                step += 1;
868                                            } else {
869                                                self.run_lda(self.get_data());
870                                            }
871                                        }
872                                        AddressingMode::Absolute(a) => {
873                                            if step == 0 {
874                                                self.set_addr(a);
875                                                self.set_data_type(PinType::Input);
876                                                step += 1;
877                                            } else {
878                                                self.run_lda(self.get_data());
879                                            }
880                                        }
881                                        _ => unreachable!(),
882                                    },
883                                    Opcode::LDX(a) => match a {
884                                        AddressingMode::Immediate(i) => {
885                                            self.run_ldx(i);
886                                        }
887                                        AddressingMode::ZeroPage(z) => {
888                                            if step == 0 {
889                                                self.set_addr(z as u16);
890                                                self.set_data_type(PinType::Input);
891                                                step += 1;
892                                            } else {
893                                                self.run_ldx(self.get_data());
894                                            }
895                                        }
896                                        AddressingMode::Absolute(a) => {
897                                            if step == 0 {
898                                                self.set_addr(a);
899                                                self.set_data_type(PinType::Input);
900                                                step += 1;
901                                            } else {
902                                                self.run_ldx(self.get_data());
903                                            }
904                                        }
905                                        _ => unreachable!(),
906                                    },
907                                    Opcode::LDY(a) => match a {
908                                        AddressingMode::Immediate(i) => {
909                                            self.run_ldy(i);
910                                        }
911                                        AddressingMode::ZeroPage(z) => {
912                                            if step == 0 {
913                                                self.set_addr(z as u16);
914                                                self.set_data_type(PinType::Input);
915                                                step += 1;
916                                            } else {
917                                                self.run_ldy(self.get_data());
918                                            }
919                                        }
920                                        AddressingMode::Absolute(a) => {
921                                            if step == 0 {
922                                                self.set_addr(a);
923                                                self.set_data_type(PinType::Input);
924                                                step += 1;
925                                            } else {
926                                                self.run_ldy(self.get_data());
927                                            }
928                                        }
929                                        _ => unreachable!(),
930                                    },
931                                    Opcode::LSR(a) => match a {
932                                        AddressingMode::Implicit => {
933                                            self.registers.p.set(
934                                                StatusRegister::C,
935                                                (self.registers.a & 0x01) > 0,
936                                            );
937                                            self.registers.a >>= 1;
938                                            self.set_flags_nz(*self.registers.a);
939                                            self.state = CpuState::Fetch;
940                                        }
941                                        AddressingMode::ZeroPage(z) => {
942                                            if step == 0 {
943                                                self.set_addr(z as u16);
944                                                self.set_data_type(PinType::Input);
945                                                step += 1;
946                                            } else if step == 1 {
947                                                let mut data = self.get_data();
948                                                self.registers
949                                                    .p
950                                                    .set(StatusRegister::C, (data & 0x01) > 0);
951                                                data >>= 1;
952                                                self.set_data(data);
953                                                self.set_data_type(PinType::Output);
954                                                self.set_flags_nz(data);
955                                                step += 1;
956                                            } else {
957                                                self.state = CpuState::Fetch
958                                            }
959                                        }
960                                        AddressingMode::Absolute(a) => {
961                                            if step == 0 {
962                                                self.set_addr(a);
963                                                self.set_data_type(PinType::Input);
964                                                step += 1;
965                                            } else if step == 1 {
966                                                let mut data = self.get_data();
967                                                self.registers
968                                                    .p
969                                                    .set(StatusRegister::C, (data & 0x01) > 0);
970                                                data >>= 1;
971                                                self.set_data(data);
972                                                self.set_data_type(PinType::Output);
973                                                self.set_flags_nz(data);
974                                                step += 1;
975                                            } else {
976                                                self.state = CpuState::Fetch
977                                            }
978                                        }
979                                        _ => unreachable!(),
980                                    },
981                                    Opcode::NOP => self.state = CpuState::Fetch,
982                                    Opcode::ORA(a) => match a {
983                                        AddressingMode::Immediate(i) => self.run_ora(i),
984                                        AddressingMode::ZeroPage(z) => {
985                                            if step == 0 {
986                                                self.set_addr(z as u16);
987                                                self.set_data_type(PinType::Input);
988                                                step += 1;
989                                            } else {
990                                                self.run_ora(self.get_data());
991                                            }
992                                        }
993                                        AddressingMode::Absolute(a) => {
994                                            if step == 0 {
995                                                self.set_addr(a);
996                                                self.set_data_type(PinType::Input);
997                                                step += 1;
998                                            } else {
999                                                self.run_ora(self.get_data());
1000                                            }
1001                                        }
1002                                        _ => unreachable!(),
1003                                    },
1004                                    Opcode::TAX => {
1005                                        self.registers.x = self.registers.a;
1006                                        self.set_flags_nz(*self.registers.x);
1007                                        self.state = CpuState::Fetch
1008                                    }
1009                                    Opcode::TXA => {
1010                                        self.registers.a = self.registers.x;
1011                                        self.set_flags_nz(*self.registers.a);
1012                                        self.state = CpuState::Fetch
1013                                    }
1014                                    Opcode::DEX => {
1015                                        self.registers.x.dec();
1016                                        self.set_flags_nz(*self.registers.x);
1017                                        self.state = CpuState::Fetch
1018                                    }
1019                                    Opcode::INX => {
1020                                        self.registers.x.inc();
1021                                        self.set_flags_nz(*self.registers.x);
1022                                        self.state = CpuState::Fetch
1023                                    }
1024                                    Opcode::TAY => {
1025                                        self.registers.y = self.registers.a;
1026                                        self.set_flags_nz(*self.registers.y);
1027                                        self.state = CpuState::Fetch
1028                                    }
1029                                    Opcode::TYA => {
1030                                        self.registers.a = self.registers.y;
1031                                        self.set_flags_nz(*self.registers.a);
1032                                        self.state = CpuState::Fetch
1033                                    }
1034                                    Opcode::DEY => {
1035                                        self.registers.y.dec();
1036                                        self.set_flags_nz(*self.registers.y);
1037                                        self.state = CpuState::Fetch
1038                                    }
1039                                    Opcode::INY => {
1040                                        self.registers.y.inc();
1041                                        self.set_flags_nz(*self.registers.y);
1042                                        self.state = CpuState::Fetch
1043                                    }
1044                                    Opcode::ROL(a) => match a {
1045                                        AddressingMode::Implicit => {
1046                                            let old_carry =
1047                                                self.registers.p.contains(StatusRegister::C) as u8;
1048                                            self.registers.p.set(
1049                                                StatusRegister::C,
1050                                                (self.registers.a & 0x80) > 0,
1051                                            );
1052                                            self.registers.a <<= 1;
1053                                            self.registers.a += old_carry;
1054                                            self.set_flags_nz(*self.registers.a);
1055                                            self.state = CpuState::Fetch;
1056                                        }
1057                                        AddressingMode::ZeroPage(z) => {
1058                                            if step == 0 {
1059                                                self.set_addr(z as u16);
1060                                                self.set_data_type(PinType::Input);
1061                                                step += 1;
1062                                            } else if step == 1 {
1063                                                let mut data = self.get_data();
1064                                                let old_carry =
1065                                                    self.registers.p.contains(StatusRegister::C)
1066                                                        as u8;
1067                                                self.registers
1068                                                    .p
1069                                                    .set(StatusRegister::C, (data & 0x80) > 0);
1070                                                data <<= 1;
1071                                                data += old_carry;
1072                                                self.set_data(data);
1073                                                self.set_data_type(PinType::Output);
1074                                                self.set_flags_nz(data);
1075                                                step += 1;
1076                                            } else {
1077                                                self.state = CpuState::Fetch;
1078                                            }
1079                                        }
1080                                        AddressingMode::Absolute(a) => {
1081                                            if step == 0 {
1082                                                self.set_addr(a);
1083                                                self.set_data_type(PinType::Input);
1084                                                step += 1;
1085                                            } else if step == 1 {
1086                                                let mut data = self.get_data();
1087                                                let old_carry =
1088                                                    self.registers.p.contains(StatusRegister::C)
1089                                                        as u8;
1090                                                self.registers
1091                                                    .p
1092                                                    .set(StatusRegister::C, (data & 0x80) > 0);
1093                                                data <<= 1;
1094                                                data += old_carry;
1095                                                self.set_data(data);
1096                                                self.set_data_type(PinType::Output);
1097                                                self.set_flags_nz(data);
1098                                                step += 1;
1099                                            } else {
1100                                                self.state = CpuState::Fetch;
1101                                            }
1102                                        }
1103                                        _ => unreachable!(),
1104                                    },
1105                                    Opcode::ROR(a) => match a {
1106                                        AddressingMode::Implicit => {
1107                                            let old_carry =
1108                                                self.registers.p.contains(StatusRegister::C) as u8;
1109                                            self.registers.p.set(
1110                                                StatusRegister::C,
1111                                                (self.registers.a & 0x01) > 0,
1112                                            );
1113                                            self.registers.a >>= 1;
1114                                            self.registers.a += old_carry << 7;
1115                                            self.set_flags_nz(*self.registers.a);
1116                                            self.state = CpuState::Fetch;
1117                                        }
1118                                        AddressingMode::ZeroPage(z) => {
1119                                            if step == 0 {
1120                                                self.set_addr(z as u16);
1121                                                self.set_data_type(PinType::Input);
1122                                                step += 1;
1123                                            } else if step == 1 {
1124                                                let mut data = self.get_data();
1125                                                let old_carry =
1126                                                    self.registers.p.contains(StatusRegister::C)
1127                                                        as u8;
1128                                                self.registers
1129                                                    .p
1130                                                    .set(StatusRegister::C, (data & 0x01) > 0);
1131                                                data >>= 1;
1132                                                data += old_carry << 7;
1133                                                self.set_data(data);
1134                                                self.set_data_type(PinType::Output);
1135                                                self.set_flags_nz(data);
1136                                                step += 1;
1137                                            } else {
1138                                                self.state = CpuState::Fetch;
1139                                            }
1140                                        }
1141                                        AddressingMode::Absolute(a) => {
1142                                            if step == 0 {
1143                                                self.set_addr(a);
1144                                                self.set_data_type(PinType::Input);
1145                                                step += 1;
1146                                            } else if step == 1 {
1147                                                let mut data = self.get_data();
1148                                                let old_carry =
1149                                                    self.registers.p.contains(StatusRegister::C)
1150                                                        as u8;
1151                                                self.registers
1152                                                    .p
1153                                                    .set(StatusRegister::C, (data & 0x01) > 0);
1154                                                data <<= 1;
1155                                                data += old_carry << 7;
1156                                                self.set_data(data);
1157                                                self.set_data_type(PinType::Output);
1158                                                self.set_flags_nz(data);
1159                                                step += 1;
1160                                            } else {
1161                                                self.state = CpuState::Fetch;
1162                                            }
1163                                        }
1164                                        _ => unreachable!(),
1165                                    },
1166                                    Opcode::RTI => todo!(),
1167                                    Opcode::RTS => {
1168                                        if step == 0 {
1169                                            self.buffer = 0;
1170                                            self.pop_stack_prepare();
1171                                            step += 1;
1172                                        } else if step == 1 {
1173                                            self.buffer = self.get_data() as u16;
1174                                            self.pop_stack_prepare();
1175                                            step += 1;
1176                                        } else {
1177                                            self.buffer += (self.get_data() as u16) << 8;
1178                                            self.registers.pc = self.buffer.wrapping_add(1).into();
1179                                            self.state = CpuState::Fetch;
1180                                        }
1181                                    }
1182                                    Opcode::SBC(a) => match a {
1183                                        AddressingMode::Immediate(i) => self.run_sbc(i),
1184                                        AddressingMode::ZeroPage(z) => {
1185                                            if step == 0 {
1186                                                self.set_addr(z as u16);
1187                                                self.set_data_type(PinType::Input);
1188                                                step += 1;
1189                                            } else {
1190                                                self.run_sbc(self.get_data());
1191                                            }
1192                                        }
1193                                        AddressingMode::Absolute(a) => {
1194                                            if step == 0 {
1195                                                self.set_addr(a);
1196                                                self.set_data_type(PinType::Input);
1197                                                step += 1;
1198                                            } else {
1199                                                self.run_sbc(self.get_data());
1200                                            }
1201                                        }
1202                                        _ => unreachable!(),
1203                                    },
1204
1205                                    Opcode::TXS => {
1206                                        self.registers.s = self.registers.x;
1207                                        self.state = CpuState::Fetch
1208                                    }
1209                                    Opcode::TSX => {
1210                                        self.registers.x = self.registers.s;
1211                                        self.state = CpuState::Fetch
1212                                    }
1213                                    Opcode::PHA => {
1214                                        if step == 0 {
1215                                            self.push_stack(*self.registers.a);
1216                                            step += 1;
1217                                        } else {
1218                                            self.state = CpuState::Fetch;
1219                                        }
1220                                    }
1221                                    Opcode::PLA => {
1222                                        if step == 0 {
1223                                            self.pop_stack_prepare();
1224                                            step += 1;
1225                                        } else {
1226                                            self.registers.a = self.get_data().into();
1227                                        }
1228                                    }
1229                                    Opcode::PHP => {
1230                                        if step == 0 {
1231                                            self.push_stack(self.registers.p.bits());
1232                                            step += 1;
1233                                        } else {
1234                                            self.state = CpuState::Fetch;
1235                                        }
1236                                    }
1237                                    Opcode::PLP => {
1238                                        if step == 0 {
1239                                            self.pop_stack_prepare();
1240                                            step += 1;
1241                                        } else {
1242                                            self.registers.p =
1243                                                StatusRegister::from_bits_retain(self.get_data());
1244                                        }
1245                                    }
1246                                    Opcode::STA(a) => match a {
1247                                        AddressingMode::ZeroPage(z) => {
1248                                            if step == 0 {
1249                                                self.run_st(*self.registers.a, z as u16);
1250                                                step += 1;
1251                                            } else {
1252                                                self.state = CpuState::Fetch;
1253                                            }
1254                                        }
1255                                        AddressingMode::Absolute(a) => {
1256                                            if step == 0 {
1257                                                step += 1;
1258                                            } else if step == 1 {
1259                                                self.run_st(*self.registers.a, a);
1260                                                step += 1;
1261                                            } else {
1262                                                self.state = CpuState::Fetch;
1263                                            }
1264                                        }
1265                                        _ => unreachable!(),
1266                                    },
1267                                    Opcode::STX(a) => match a {
1268                                        AddressingMode::ZeroPage(z) => {
1269                                            if step == 0 {
1270                                                self.run_st(*self.registers.x, z as u16);
1271                                                step += 1;
1272                                            } else {
1273                                                self.state = CpuState::Fetch;
1274                                            }
1275                                        }
1276                                        AddressingMode::Absolute(a) => {
1277                                            if step == 0 {
1278                                                step += 1;
1279                                            } else if step == 1 {
1280                                                self.run_st(*self.registers.x, a);
1281                                                step += 1;
1282                                            } else {
1283                                                self.state = CpuState::Fetch;
1284                                            }
1285                                        }
1286                                        _ => unreachable!(),
1287                                    },
1288                                    Opcode::STY(a) => match a {
1289                                        AddressingMode::ZeroPage(z) => {
1290                                            if step == 0 {
1291                                                self.run_st(*self.registers.y, z as u16);
1292                                                step += 1;
1293                                            } else {
1294                                                self.state = CpuState::Fetch;
1295                                            }
1296                                        }
1297                                        AddressingMode::Absolute(a) => {
1298                                            if step == 0 {
1299                                                step += 1;
1300                                            } else if step == 1 {
1301                                                self.run_st(*self.registers.y, a);
1302                                                step += 1;
1303                                            } else {
1304                                                self.state = CpuState::Fetch;
1305                                            }
1306                                        }
1307                                        _ => unreachable!(),
1308                                    },
1309                                }
1310                            }
1311                            if matches!(self.state, CpuState::Execute(_, _)) {
1312                                self.state = CpuState::Execute(opcode, step);
1313                            }
1314                            if matches!(self.state, CpuState::Fetch) {
1315                                self.set_addr(*self.registers.pc);
1316                                self.registers.pc.inc();
1317                            }
1318                        }
1319                        CpuState::Halted => {}
1320                    }
1321                }
1322            }
1323        } else if self.powered {
1324            self.state = CpuState::Halted;
1325            self.powered = false;
1326        }
1327    }
1328}
1329
1330impl Nes6502 {
1331    fn set_flags_nz(&mut self, val: u8) {
1332        self.registers.p.set(StatusRegister::Z, val == 0);
1333        self.registers.p.set(StatusRegister::N, (val & 0x80) > 0);
1334    }
1335
1336    fn jump_relative(&mut self, val: i8) {
1337        self.registers.pc = ((*self.registers.pc as i32 + val as i32) as u16).into()
1338    }
1339
1340    fn push_stack(&mut self, val: u8) {
1341        self.run_st(val, 0x100 + *self.registers.s as u16);
1342        self.registers.s.dec();
1343    }
1344
1345    fn pop_stack_prepare(&mut self) {
1346        self.registers.s.inc();
1347        self.set_addr(0x100 + *self.registers.s as u16);
1348        self.set_data_type(PinType::Input);
1349    }
1350
1351    fn run_adc(&mut self, val: u8) {
1352        let rhs = val.wrapping_add(self.registers.p.contains(StatusRegister::C) as u8);
1353        let sum = *self.registers.a as u16 + rhs as u16;
1354
1355        self.registers.p.set(StatusRegister::C, sum > 0xFF);
1356        let sum: Reg<u8> = (sum as u8).into();
1357
1358        self.set_flags_nz(*sum);
1359        self.registers.p.set(
1360            StatusRegister::V,
1361            (!(*self.registers.a ^ val) & (*self.registers.a ^ *sum) & 0x80) > 0,
1362        );
1363        self.registers.a = sum;
1364        self.state = CpuState::Fetch;
1365    }
1366
1367    fn run_and(&mut self, val: u8) {
1368        self.registers.a &= val;
1369
1370        self.set_flags_nz(*self.registers.a);
1371
1372        self.state = CpuState::Fetch;
1373    }
1374
1375    fn run_bit(&mut self, val: u8) {
1376        self.registers
1377            .p
1378            .set(StatusRegister::Z, (*self.registers.a & val) == 0);
1379        self.registers.p.set(StatusRegister::N, (val & 0x80) > 0);
1380        self.registers.p.set(StatusRegister::V, (val & 0x40) > 0);
1381
1382        self.state = CpuState::Fetch;
1383    }
1384
1385    fn run_cmp(&mut self, base: Reg<u8>, val: u8) {
1386        let val = !val;
1387        let rhs = val.wrapping_add(self.registers.p.contains(StatusRegister::C) as u8);
1388        let sum = *base as u16 + rhs as u16;
1389
1390        self.registers.p.set(StatusRegister::C, sum > 0xFF);
1391        let sum: Reg<u8> = (sum as u8).into();
1392
1393        self.set_flags_nz(*sum);
1394        self.registers.p.set(
1395            StatusRegister::V,
1396            (!(*base ^ val) & (*base ^ *sum) & 0x80) > 0,
1397        );
1398        self.state = CpuState::Fetch;
1399    }
1400
1401    fn run_eor(&mut self, val: u8) {
1402        self.registers.a ^= val;
1403
1404        self.set_flags_nz(*self.registers.a);
1405
1406        self.state = CpuState::Fetch;
1407    }
1408
1409    fn run_lda(&mut self, val: u8) {
1410        self.registers.a = val.into();
1411        self.set_flags_nz(*self.registers.a);
1412        self.state = CpuState::Fetch;
1413    }
1414    fn run_ldx(&mut self, val: u8) {
1415        self.registers.x = val.into();
1416        self.set_flags_nz(*self.registers.x);
1417        self.state = CpuState::Fetch;
1418    }
1419    fn run_ldy(&mut self, val: u8) {
1420        self.registers.y = val.into();
1421        self.set_flags_nz(*self.registers.y);
1422        self.state = CpuState::Fetch;
1423    }
1424
1425    fn run_ora(&mut self, val: u8) {
1426        self.registers.a |= val;
1427
1428        self.set_flags_nz(*self.registers.a);
1429
1430        self.state = CpuState::Fetch;
1431    }
1432
1433    fn run_sbc(&mut self, val: u8) {
1434        self.run_adc(!val)
1435    }
1436
1437    fn run_st(&mut self, val: u8, addr: u16) {
1438        self.set_addr(addr);
1439        self.set_data(val);
1440        self.set_data_type(PinType::Output);
1441    }
1442}
1443
1444impl ToString for Nes6502 {
1445    fn to_string(&self) -> std::string::String {
1446        format!("state={:?}\n{}", self.state, self.registers.to_string())
1447    }
1448}