From bc16c64e48b567f32b20bbf311d9559e81e9abe4 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Mon, 29 Aug 2022 22:59:45 +0200 Subject: [PATCH] should be all legal opcodes --- src/addressing.rs | 28 ++++++++- src/cpu.rs | 7 ++- src/instructions.rs | 148 +++++++++++++++++++++++--------------------- 3 files changed, 106 insertions(+), 77 deletions(-) diff --git a/src/addressing.rs b/src/addressing.rs index 3f8acd3..347340f 100644 --- a/src/addressing.rs +++ b/src/addressing.rs @@ -33,6 +33,7 @@ macro_rules! abs_indexed_addr let fetched_addr = (hi << 8) | lo; self.absolute_addr = fetched_addr.wrapping_add(self.$register as u16); + self.additional_cycles = ((fetched_addr & 0xFF00) != (self.absolute_addr & 0xFF00)) as u8; self.fetch_type = FetchType::Mem; @@ -41,6 +42,25 @@ macro_rules! abs_indexed_addr } } +macro_rules! zpg_indexed_addr +{ + ($name: ident, $register: ident) => + { + pub fn $name(&mut self) + { + let bus = self.bus.upgrade().unwrap(); + + let fetched_addr = bus.borrow().read_cpu(self.pc); + self.absolute_addr = fetched_addr.wrapping_add(self.$register) as u16; + self.pc += instr_size!($name) - 1; + + self.fetch_type = FetchType::Mem; + + print!("{: <40}", format!("${:02X},{} @ ${:04X}", fetched_addr, stringify!($register).to_uppercase(), self.absolute_addr)); + } + } +} + pub type AddrFn = fn(&mut CPU); impl CPU @@ -100,9 +120,7 @@ impl CPU let target_addr = (hi << 8) | lo; self.absolute_addr = target_addr.wrapping_add(self.y as u16); - if (target_addr & 0xFF00) != (self.absolute_addr & 0xFF00) { - self.cycle += 1; - } + self.additional_cycles = ((target_addr & 0xFF00) != (self.absolute_addr & 0xFF00)) as u8; self.fetch_type = FetchType::Mem; @@ -168,4 +186,8 @@ impl CPU print!("{: <40}", format!("${:02X} = {:02X}", self.absolute_addr, bus.borrow().read_cpu(self.absolute_addr))) } + + zpg_indexed_addr!(zpx, x); + zpg_indexed_addr!(zpy, y); + } \ No newline at end of file diff --git a/src/cpu.rs b/src/cpu.rs index d30c5da..3828b48 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -12,7 +12,8 @@ pub enum FetchType pub struct CPU { - pub cycle: u8, + cycle: u8, + pub additional_cycles: u8, total_cycles: u64, pub absolute_addr: u16, @@ -35,6 +36,7 @@ impl CPU { CPU { cycle: 0, + additional_cycles: 0, total_cycles: 0, absolute_addr: 0, @@ -110,7 +112,8 @@ impl CPU (instr.addressing)(self); (instr.action)(self); - self.cycle += instr.cycles; + self.cycle += instr.cycles + self.additional_cycles; + self.additional_cycles = 0; println!("A:{:02X} X:{:02X} Y:{:02X} P:{:02X} SP:{:02X} CYC:{}", self.acc, self.x, self.y, self.p, self.sp, self.total_cycles); } diff --git a/src/instructions.rs b/src/instructions.rs index 28c4313..22834f6 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -20,7 +20,7 @@ pub struct Instruction macro_rules! instr { - ($instr: ident, $addr: ident, $cyc: literal) => + ($instr: ident, $addr: ident, $cyc: literal, $illegal: literal) => { Option::Some(Instruction { @@ -29,9 +29,11 @@ macro_rules! instr cycles: $cyc, length: instr_size!($addr), - name: Mnemonic::new(stringify!($instr), false) + name: Mnemonic::new(stringify!($instr), $illegal) }) - } + }; + + ($instr: ident, $addr: ident, $cyc: literal) => { instr!($instr, $addr, $cyc, false) }; } #[allow(dead_code)] @@ -99,10 +101,10 @@ macro_rules! branch { let branch_target = $self.pc.wrapping_add($self.relative_addr as u16); - $self.cycle += 1; + $self.additional_cycles += 1; if (branch_target & 0xFF00) != ($self.pc & 0xFF00) // Branched to different page { - $self.cycle += 1; + $self.additional_cycles += 1; } $self.pc = branch_target; @@ -160,6 +162,8 @@ macro_rules! store_fn { let bus = self.bus.upgrade().unwrap(); bus.borrow_mut().write_cpu(self.absolute_addr, self.$register); + + self.additional_cycles = 0; } }; } @@ -519,7 +523,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 01 */ instr!(ora, idx, 6), /* 02 */ Option::None, /* 03 */ Option::None, - /* 04 */ Option::None, + /* 04 */ instr!(nop, zpg, 3, true), /* 05 */ instr!(ora, zpg, 3), /* 06 */ instr!(asl, zpg, 5), /* 07 */ Option::None, @@ -527,7 +531,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 09 */ instr!(ora, imm, 2), /* 0A */ instr!(asl, acc, 2), /* 0B */ Option::None, - /* 0C */ Option::None, + /* 0C */ instr!(nop, abs, 4, true), /* 0D */ instr!(ora, abs, 4), /* 0E */ instr!(asl, abs, 6), /* 0F */ Option::None, @@ -536,17 +540,17 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 11 */ instr!(ora, idy, 5), /* 12 */ Option::None, /* 13 */ Option::None, - /* 14 */ Option::None, - /* 15 */ Option::None, - /* 16 */ Option::None, + /* 14 */ instr!(nop, zpx, 4, true), + /* 15 */ instr!(ora, zpx, 4), + /* 16 */ instr!(asl, zpx, 6), /* 17 */ Option::None, /* 18 */ instr!(clc, imp, 2), /* 19 */ instr!(ora, aby, 4), - /* 1A */ Option::None, + /* 1A */ instr!(nop, imp, 2, true), /* 1B */ Option::None, - /* 1C */ Option::None, - /* 1D */ Option::None, - /* 1E */ Option::None, + /* 1C */ instr!(nop, abx, 4, true), + /* 1D */ instr!(ora, abx, 4), + /* 1E */ instr!(asl, abx, 7), /* 1F */ Option::None, /* 20 */ instr!(jsr, abs, 6), @@ -570,24 +574,24 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 31 */ instr!(and, idy, 5), /* 32 */ Option::None, /* 33 */ Option::None, - /* 34 */ Option::None, - /* 35 */ Option::None, - /* 36 */ Option::None, + /* 34 */ instr!(nop, zpx, 4, true), + /* 35 */ instr!(and, zpx, 4), + /* 36 */ instr!(rol, zpx, 6), /* 37 */ Option::None, /* 38 */ instr!(sec, imp, 2), - /* 39 */ Option::None, - /* 3A */ Option::None, + /* 39 */ instr!(and, aby, 4), + /* 3A */ instr!(nop, imp, 2, true), /* 3B */ Option::None, - /* 3C */ Option::None, - /* 3D */ Option::None, - /* 3E */ Option::None, + /* 3C */ instr!(nop, abx, 4, true), + /* 3D */ instr!(and, abx, 4), + /* 3E */ instr!(rol, abx, 7), /* 3F */ Option::None, /* 40 */ instr!(rti, imp, 6), /* 41 */ instr!(eor, idx, 6), /* 42 */ Option::None, /* 43 */ Option::None, - /* 44 */ Option::None, + /* 44 */ instr!(nop, zpg, 3, true), /* 45 */ instr!(eor, zpg, 3), /* 46 */ instr!(lsr, zpg, 5), /* 47 */ Option::None, @@ -604,24 +608,24 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 51 */ instr!(eor, idy, 5), /* 52 */ Option::None, /* 53 */ Option::None, - /* 54 */ Option::None, - /* 55 */ Option::None, - /* 56 */ Option::None, + /* 54 */ instr!(nop, zpx, 4, true), + /* 55 */ instr!(eor, zpx, 4), + /* 56 */ instr!(lsr, zpx, 6), /* 57 */ Option::None, /* 58 */ Option::None, - /* 59 */ Option::None, - /* 5A */ Option::None, + /* 59 */ instr!(eor, aby, 4), + /* 5A */ instr!(nop, imp, 2, true), /* 5B */ Option::None, - /* 5C */ Option::None, - /* 5D */ Option::None, - /* 5E */ Option::None, + /* 5C */ instr!(nop, abx, 4, true), + /* 5D */ instr!(eor, abx, 4), + /* 5E */ instr!(lsr, abx, 7), /* 5F */ Option::None, /* 60 */ instr!(rts, imp, 6), /* 61 */ instr!(adc, idx, 6), /* 62 */ Option::None, /* 63 */ Option::None, - /* 64 */ Option::None, + /* 64 */ instr!(nop, zpg, 3, true), /* 65 */ instr!(adc, zpg, 3), /* 66 */ instr!(ror, zpg, 5), /* 67 */ Option::None, @@ -638,29 +642,29 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 71 */ instr!(adc, idy, 5), /* 72 */ Option::None, /* 73 */ Option::None, - /* 74 */ Option::None, - /* 75 */ Option::None, - /* 76 */ Option::None, + /* 74 */ instr!(nop, zpx, 4, true), + /* 75 */ instr!(adc, zpx, 4), + /* 76 */ instr!(ror, zpx, 6), /* 77 */ Option::None, /* 78 */ instr!(sei, imp, 2), - /* 79 */ Option::None, - /* 7A */ Option::None, + /* 79 */ instr!(adc, aby, 4), + /* 7A */ instr!(nop, imp, 2, true), /* 7B */ Option::None, - /* 7C */ Option::None, - /* 7D */ Option::None, - /* 7E */ Option::None, + /* 7C */ instr!(nop, abx, 4, true), + /* 7D */ instr!(adc, abx, 4), + /* 7E */ instr!(ror, abx, 7), /* 7F */ Option::None, - /* 80 */ Option::None, + /* 80 */ instr!(nop, imm, 2, true), /* 81 */ instr!(sta, idx, 6), - /* 82 */ Option::None, + /* 82 */ instr!(nop, imm, 2, true), /* 83 */ Option::None, /* 84 */ instr!(sty, zpg, 3), /* 85 */ instr!(sta, zpg, 3), /* 86 */ instr!(stx, zpg, 3), /* 87 */ Option::None, /* 88 */ instr!(dey, imp, 2), - /* 89 */ Option::None, + /* 89 */ instr!(nop, imm, 2, true), /* 8A */ instr!(txa, imp, 2), /* 8B */ Option::None, /* 8C */ instr!(sty, abs, 4), @@ -672,16 +676,16 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 91 */ instr!(sta, idy, 6), /* 92 */ Option::None, /* 93 */ Option::None, - /* 94 */ Option::None, - /* 95 */ Option::None, - /* 96 */ Option::None, + /* 94 */ instr!(sty, zpx, 4), + /* 95 */ instr!(sta, zpx, 4), + /* 96 */ instr!(stx, zpy, 4), /* 97 */ Option::None, /* 98 */ instr!(tya, imp, 2), - /* 99 */ Option::None, + /* 99 */ instr!(sta, aby, 5), /* 9A */ instr!(txs, imp, 2), /* 9B */ Option::None, /* 9C */ Option::None, - /* 9D */ Option::None, + /* 9D */ instr!(sta, abx, 5), /* 9E */ Option::None, /* 9F */ Option::None, @@ -706,22 +710,22 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* B1 */ instr!(lda, idy, 5), /* B2 */ Option::None, /* B3 */ Option::None, - /* B4 */ Option::None, - /* B5 */ Option::None, - /* B6 */ Option::None, + /* B4 */ instr!(ldy, zpx, 4), + /* B5 */ instr!(lda, zpx, 4), + /* B6 */ instr!(ldx, zpy, 4), /* B7 */ Option::None, /* B8 */ instr!(clv, imp, 2), /* B9 */ instr!(lda, aby, 4), /* BA */ instr!(tsx, imp, 2), /* BB */ Option::None, - /* BC */ Option::None, - /* BD */ Option::None, - /* BE */ Option::None, + /* BC */ instr!(ldy, abx, 4), + /* BD */ instr!(lda, abx, 4), + /* BE */ instr!(ldx, aby, 4), /* BF */ Option::None, /* C0 */ instr!(cpy, imm, 2), /* C1 */ instr!(cmp, idx, 6), - /* C2 */ Option::None, + /* C2 */ instr!(nop, imm, 2, true), /* C3 */ Option::None, /* C4 */ instr!(cpy, zpg, 3), /* C5 */ instr!(cmp, zpg, 3), @@ -740,22 +744,22 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* D1 */ instr!(cmp, idy, 5), /* D2 */ Option::None, /* D3 */ Option::None, - /* D4 */ Option::None, - /* D5 */ Option::None, - /* D6 */ Option::None, + /* D4 */ instr!(nop, zpx, 4, true), + /* D5 */ instr!(cmp, zpx, 4), + /* D6 */ instr!(dec, zpx, 6), /* D7 */ Option::None, /* D8 */ instr!(cld, imp, 2), - /* D9 */ Option::None, - /* DA */ Option::None, + /* D9 */ instr!(cmp, aby, 4), + /* DA */ instr!(nop, imp, 2, true), /* DB */ Option::None, - /* DC */ Option::None, - /* DD */ Option::None, - /* DE */ Option::None, + /* DC */ instr!(nop, abx, 4, true), + /* DD */ instr!(cmp, abx, 4), + /* DE */ instr!(dec, abx, 7), /* DF */ Option::None, /* E0 */ instr!(cpx, imm, 2), /* E1 */ instr!(sbc, idx, 6), - /* E2 */ Option::None, + /* E2 */ instr!(nop, imm, 2, true), /* E3 */ Option::None, /* E4 */ instr!(cpx, zpg, 3), /* E5 */ instr!(sbc, zpg, 3), @@ -774,16 +778,16 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* F1 */ instr!(sbc, idy, 5), /* F2 */ Option::None, /* F3 */ Option::None, - /* F4 */ Option::None, - /* F5 */ Option::None, - /* F6 */ Option::None, + /* F4 */ instr!(nop, zpx, 4, true), + /* F5 */ instr!(sbc, zpx, 4), + /* F6 */ instr!(inc, zpx, 6), /* F7 */ Option::None, /* F8 */ instr!(sed, imp, 2), - /* F9 */ Option::None, - /* FA */ Option::None, + /* F9 */ instr!(sbc, aby, 4), + /* FA */ instr!(nop, imp, 2, true), /* FB */ Option::None, - /* FC */ Option::None, - /* FD */ Option::None, - /* FE */ Option::None, + /* FC */ instr!(nop, abx, 4, true), + /* FD */ instr!(sbc, abx, 4), + /* FE */ instr!(inc, abx, 7), /* FF */ Option::None ]; \ No newline at end of file