diff --git a/Cargo.lock b/Cargo.lock index 46ae751..921a7e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "copystr" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "547ed93b8f3c851afaaf05fe51e49c31a735c098e9fd8d3fbcf572262bdc0d43" - [[package]] name = "rusty-nes" version = "0.1.0" -dependencies = [ - "copystr", -] diff --git a/Cargo.toml b/Cargo.toml index 97520b5..0abcef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,3 @@ version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -copystr = "0.0.5" \ No newline at end of file diff --git a/src/addressing.rs b/src/addressing.rs index 5c23c82..3f8acd3 100644 --- a/src/addressing.rs +++ b/src/addressing.rs @@ -7,17 +7,40 @@ macro_rules! instr_size (abs) => { 3 }; (abx) => { 3 }; (aby) => { 3 }; - (imm) => { 1 }; + (imm) => { 2 }; (imp) => { 1 }; (ind) => { 3 }; - (idx) => { 3 }; - (idy) => { 3 }; + (idx) => { 2 }; + (idy) => { 2 }; (rel) => { 2 }; (zpg) => { 2 }; (zpx) => { 2 }; (zpy) => { 2 }; } +macro_rules! abs_indexed_addr +{ + ($name: ident, $register: ident) => + { + pub fn $name(&mut self) + { + let bus = self.bus.upgrade().unwrap(); + + let lo = bus.borrow().read_cpu(self.pc) as u16; + let hi = bus.borrow().read_cpu(self.pc + 1) as u16; + self.pc += instr_size!($name) - 1; + + let fetched_addr = (hi << 8) | lo; + self.absolute_addr = fetched_addr.wrapping_add(self.$register as u16); + + + self.fetch_type = FetchType::Mem; + + print!("{: <40}", format!("${:04X},{} @ ${:04X}", fetched_addr, stringify!($register).to_uppercase(), self.absolute_addr)); + } + } +} + pub type AddrFn = fn(&mut CPU); impl CPU @@ -29,7 +52,7 @@ impl CPU let lo = bus.borrow().read_cpu(self.pc) as u16; let hi = bus.borrow().read_cpu(self.pc + 1) as u16; - self.pc += 2; + self.pc += instr_size!(abs) - 1; self.absolute_addr = (hi << 8) | lo; self.fetch_type = FetchType::Mem; @@ -37,6 +60,9 @@ impl CPU print!("{: <40}", format!("${:04X}", self.absolute_addr)); } + abs_indexed_addr!(abx, x); + abs_indexed_addr!(aby, y); + pub fn acc(&mut self) { self.fetch_type = FetchType::Acc; @@ -49,7 +75,7 @@ impl CPU let bus = self.bus.upgrade().unwrap(); let mut zpg_addr = bus.borrow().read_cpu(self.pc); - self.pc += 1; + self.pc += instr_size!(idx) - 1; zpg_addr = zpg_addr.wrapping_add(self.x); let lo = bus.borrow().read_cpu(zpg_addr as u16) as u16; @@ -66,13 +92,18 @@ impl CPU let bus = self.bus.upgrade().unwrap(); let zpg_addr = bus.borrow().read_cpu(self.pc); - self.pc += 1; + self.pc += instr_size!(idy) - 1; let lo = bus.borrow().read_cpu(zpg_addr as u16) as u16; let hi = bus.borrow().read_cpu(zpg_addr.wrapping_add(1) as u16) as u16; 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.fetch_type = FetchType::Mem; print!("{: <40}", format!("(${:02X}),Y @ [${:04X} + Y] = ${:04X} = {:02X}", zpg_addr, target_addr, self.absolute_addr, bus.borrow().read_cpu(self.absolute_addr))); @@ -83,7 +114,7 @@ impl CPU let bus = self.bus.upgrade().unwrap(); self.absolute_addr = self.pc; - self.pc += 1; + self.pc += instr_size!(imm) - 1; self.fetch_type = FetchType::Mem; @@ -95,12 +126,33 @@ impl CPU print!("{: <40}", ""); } + pub fn ind(&mut self) + { + let bus = self.bus.upgrade().unwrap(); + + let mut lo = bus.borrow().read_cpu(self.pc) as u16; + let mut hi = bus.borrow().read_cpu(self.pc + 1) as u16; + self.pc += instr_size!(ind) - 1; + + let indirect_addr = (hi << 8) | lo; + lo = bus.borrow().read_cpu(indirect_addr) as u16; + hi = bus.borrow().read_cpu((indirect_addr & 0xFF00) | ((indirect_addr + 1) & 0x00FF)) as u16; + + self.absolute_addr = (hi << 8) | lo; + + self.fetch_type = FetchType::Mem; + + print!("{: <40}", format!("(${:04X}) = ${:04X}", indirect_addr, self.absolute_addr)); + } + pub fn rel(&mut self) { let bus = self.bus.upgrade().unwrap(); self.relative_addr = bus.borrow().read_cpu(self.pc) as i8; - self.pc += 1; + self.pc += instr_size!(rel) - 1; + + self.fetch_type = FetchType::Mem; print!("{: <40}", format!("${:02X}", self.relative_addr)); } @@ -110,7 +162,7 @@ impl CPU let bus = self.bus.upgrade().unwrap(); self.absolute_addr = bus.borrow().read_cpu(self.pc) as u16; - self.pc += 1; + self.pc += instr_size!(zpg) - 1; self.fetch_type = FetchType::Mem; diff --git a/src/instructions.rs b/src/instructions.rs index 7d4fc15..28c4313 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -392,6 +392,24 @@ impl CPU set_flag_to!(self.p, Bit::Zero, self.acc == 0); } + fn eor(&mut self) + { + let val = self.fetch(); + + self.acc ^= val; + set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0); + set_flag_to!(self.p, Bit::Zero, self.acc == 0); + } + + fn ora(&mut self) + { + let val = self.fetch(); + + self.acc |= val; + set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0); + set_flag_to!(self.p, Bit::Zero, self.acc == 0); + } + fn bit(&mut self) { let bus = self.bus.upgrade().unwrap(); @@ -402,14 +420,6 @@ impl CPU set_flag_to!(self.p, Bit::Zero, (self.acc & value) == 0); } - fn eor(&mut self) - { - let val = self.fetch(); - - self.acc ^= val; - set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0); - set_flag_to!(self.p, Bit::Zero, self.acc == 0); - } fn jmp(&mut self) { @@ -432,15 +442,6 @@ impl CPU } - fn ora(&mut self) - { - let val = self.fetch(); - - self.acc |= val; - set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0); - set_flag_to!(self.p, Bit::Zero, self.acc == 0); - } - fn pha(&mut self) { let bus = self.bus.upgrade().unwrap(); @@ -505,11 +506,16 @@ impl CPU self.pc = (hi << 8) | lo; self.pc += 1; } + + fn brk(&mut self) + { + let bus = self.bus.upgrade().unwrap(); + } } pub static INSTRUCTION_SET: [Option; 256] = [ - /* 00 */ Option::None, + /* 00 */ Option::None, //instr!(brk, imp, 7), /* 01 */ instr!(ora, idx, 6), /* 02 */ Option::None, /* 03 */ Option::None, @@ -527,7 +533,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 0F */ Option::None, /* 10 */ instr!(bpl, rel, 2), - /* 11 */ Option::None, + /* 11 */ instr!(ora, idy, 5), /* 12 */ Option::None, /* 13 */ Option::None, /* 14 */ Option::None, @@ -535,13 +541,13 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 16 */ Option::None, /* 17 */ Option::None, /* 18 */ instr!(clc, imp, 2), - /* 09 */ Option::None, - /* 0A */ Option::None, - /* 0B */ Option::None, - /* 0C */ Option::None, - /* 0D */ Option::None, - /* 0E */ Option::None, - /* 0F */ Option::None, + /* 19 */ instr!(ora, aby, 4), + /* 1A */ Option::None, + /* 1B */ Option::None, + /* 1C */ Option::None, + /* 1D */ Option::None, + /* 1E */ Option::None, + /* 1F */ Option::None, /* 20 */ instr!(jsr, abs, 6), /* 21 */ instr!(and, idx, 6), @@ -561,7 +567,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 2F */ Option::None, /* 30 */ instr!(bmi, rel, 2), - /* 31 */ Option::None, + /* 31 */ instr!(and, idy, 5), /* 32 */ Option::None, /* 33 */ Option::None, /* 34 */ Option::None, @@ -595,7 +601,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 4F */ Option::None, /* 50 */ instr!(bvc, rel, 2), - /* 51 */ Option::None, + /* 51 */ instr!(eor, idy, 5), /* 52 */ Option::None, /* 53 */ Option::None, /* 54 */ Option::None, @@ -623,13 +629,13 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 69 */ instr!(adc, imm, 2), /* 6A */ instr!(ror, acc, 2), /* 6B */ Option::None, - /* 6C */ Option::None, + /* 6C */ instr!(jmp, ind, 5), /* 6D */ instr!(adc, abs, 4), /* 6E */ instr!(ror, abs, 6), /* 6F */ Option::None, /* 70 */ instr!(bvs, rel, 2), - /* 71 */ Option::None, + /* 71 */ instr!(adc, idy, 5), /* 72 */ Option::None, /* 73 */ Option::None, /* 74 */ Option::None, @@ -663,7 +669,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* 8F */ Option::None, /* 90 */ instr!(bcc, rel, 2), - /* 91 */ Option::None, + /* 91 */ instr!(sta, idy, 6), /* 92 */ Option::None, /* 93 */ Option::None, /* 94 */ Option::None, @@ -705,7 +711,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* B6 */ Option::None, /* B7 */ Option::None, /* B8 */ instr!(clv, imp, 2), - /* B9 */ Option::None, + /* B9 */ instr!(lda, aby, 4), /* BA */ instr!(tsx, imp, 2), /* BB */ Option::None, /* BC */ Option::None, @@ -731,7 +737,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* CF */ Option::None, /* D0 */ instr!(bne, rel, 2), - /* D1 */ Option::None, + /* D1 */ instr!(cmp, idy, 5), /* D2 */ Option::None, /* D3 */ Option::None, /* D4 */ Option::None, @@ -765,7 +771,7 @@ pub static INSTRUCTION_SET: [Option; 256] = [ /* EF */ Option::None, /* F0 */ instr!(beq, rel, 2), - /* F1 */ Option::None, + /* F1 */ instr!(sbc, idy, 5), /* F2 */ Option::None, /* F3 */ Option::None, /* F4 */ Option::None,