From 1a53f1d782226977dbb42e207929c476c015df0d Mon Sep 17 00:00:00 2001 From: Trevor Merritt Date: Tue, 1 Jul 2025 16:58:59 -0400 Subject: [PATCH] more instructions and tests passing. --- core/src/instruction.rs | 1 - core/src/mos6502cpu.rs | 73 ++++++++++++++++--- core/src/periph/at28c256/default.rs | 22 ++++++ .../periph/{at28c256.rs => at28c256/mod.rs} | 28 +------ core/src/periph/at28c256/rom_chip.rs | 27 +++++++ core/src/periph/hm62256.rs | 11 +-- core/src/periph/mod.rs | 2 +- 7 files changed, 120 insertions(+), 44 deletions(-) create mode 100644 core/src/periph/at28c256/default.rs rename core/src/periph/{at28c256.rs => at28c256/mod.rs} (52%) create mode 100644 core/src/periph/at28c256/rom_chip.rs diff --git a/core/src/instruction.rs b/core/src/instruction.rs index 38b8a9d..978d1be 100644 --- a/core/src/instruction.rs +++ b/core/src/instruction.rs @@ -42,7 +42,6 @@ impl Instruction { } } - #[cfg(test)] mod test { use crate::address_mode::AddressMode::*; diff --git a/core/src/mos6502cpu.rs b/core/src/mos6502cpu.rs index af3646d..3c281ee 100644 --- a/core/src/mos6502cpu.rs +++ b/core/src/mos6502cpu.rs @@ -102,6 +102,7 @@ impl Mos6502Cpu { // read the value at 0xfffe 0xffff for our int vector self.pc = self.read_word(&OFFSET_RESET_VECTOR); self.iv = self.read_word(&OFFSET_INT_VECTOR); + println!("PC and IV are now set from ROM addresses"); } fn read_word(&self, offset: &u16) -> u16 { @@ -137,6 +138,7 @@ impl Mos6502Cpu { } pub fn poke_x(&mut self, new_x: u8) { + println!("Updating register X from [{}] to [{}]", self.x, new_x); self.x = new_x } @@ -174,7 +176,7 @@ impl Mos6502Cpu { // set the counter to the number of steps left } else { // run 1 microcode step - println!("Microstep {}", self.microcode_step); + println!("Microstep {} for {:?}", self.microcode_step, self.ir.op); match self.ir.op { Operation::ADC => { } @@ -207,19 +209,32 @@ impl Mos6502Cpu { Operation::CPY => {} Operation::DEC => {} Operation::DEX => { - (self.x, _) = self.x.overflowing_sub(1) ; + if self.microcode_step == 1 { + let (new_x, new_carry) = self.x.overflowing_sub(1); + self.poke_x(new_x); + self.poke_flag(Carry, new_carry); + } } Operation::DEY => { - (self.y, _) = self.y.overflowing_sub(1); + if self.microcode_step == 1 { + (self.y, _) = self.y.overflowing_sub(1); + } } Operation::EOR => { } Operation::INC => { } Operation::INX => { - self.x += 1; + if self.microcode_step == 1 { + let (new_x, new_carry) = self.x.overflowing_add(1); + self.poke_x(new_x); + self.poke_flag(Carry, new_carry); + } } Operation::INY => { - self.y += 1; - } + if self.microcode_step == 1 { + let (new_y, new_carry) = self.y.overflowing_add(1); + self.poke_y(new_y); + self.poke_flag(Carry, new_carry); + } } Operation::JMP => { match self.ir.operand { Operand::Word(offset) => { @@ -274,11 +289,15 @@ impl Mos6502Cpu { Operation::PLA => {} Operation::PLP => {} Operation::ROL => { - self.a = self.a.rotate_left(1); + if self.microcode_step == 1 { + self.a = self.a.rotate_left(1); + } } Operation::ROR => { // rotate A - self.a = self.a.rotate_right(1); + if self.microcode_step == 1 { + self.a = self.a.rotate_right(1); + } } Operation::RTI => {} Operation::RTS => {} @@ -470,14 +489,44 @@ mod test { } #[test] - fn dex() { + fn dex_inx() { let mut cpu = Mos6502Cpu::default(); - cpu.a = 0xab; + cpu.x = 0xab; cpu.memory[0x6000] = ISA_OP_DEX; + cpu.memory[0x6001] = ISA_OP_INX; cpu.pc = 0x6000; - for _ in 0..INSTRUCTION_TABLE[ISA_OP_DEX as usize].unwrap().cycles { cpu.tick(); } + for _ in 0..=INSTRUCTION_TABLE[ISA_OP_DEX as usize].unwrap().cycles { cpu.tick(); } + assert_eq!(0xaa, cpu.x); + for _ in 0..=INSTRUCTION_TABLE[ISA_OP_INX as usize].unwrap().cycles { cpu.tick(); } + assert_eq!(0xab, cpu.x); + } - assert_eq!(0xaa, cpu.a); + #[test] + fn dey_iny() { + let mut cpu = Mos6502Cpu::default(); + cpu.poke_y(0xab); + cpu.memory[0x6000] = ISA_OP_DEY; + cpu.memory[0x6001] = ISA_OP_INY; + cpu.pc = 0x6000; + + for _ in 0..=INSTRUCTION_TABLE[ISA_OP_DEY as usize].unwrap().cycles { cpu.tick(); } + assert_eq!(0xaa, cpu.peek_y()); + for _ in 0..=INSTRUCTION_TABLE[ISA_OP_INY as usize].unwrap().cycles { cpu.tick(); } + assert_eq!(0xab, cpu.peek_y()); + } + + #[test] + fn rol_a_ror_a() { + let mut cpu = Mos6502Cpu::default(); + cpu.poke_a(0b1010_1010); // 0xaa + cpu.memory[0x6000] = ISA_OP_ROL_A; + cpu.memory[0x6001] = ISA_OP_ROR_A; + cpu.pc = 0x6000; + + for _ in 0..=INSTRUCTION_TABLE[ISA_OP_ROL_A as usize].unwrap().cycles { cpu.tick(); } + assert_eq!(cpu.peek_a(), 0b0101_0101); + for _ in 0..=INSTRUCTION_TABLE[ISA_OP_ROR_A as usize].unwrap().cycles { cpu.tick(); } + assert_eq!(cpu.peek_a(), 0b1010_1010); } } \ No newline at end of file diff --git a/core/src/periph/at28c256/default.rs b/core/src/periph/at28c256/default.rs new file mode 100644 index 0000000..29548d6 --- /dev/null +++ b/core/src/periph/at28c256/default.rs @@ -0,0 +1,22 @@ +use crate::constants::constants_system::SIZE_32KB; +use crate::periph::at28c256::At28C256; +use crate::periph::hm62256::Hm62256; + +impl Default for At28C256 { + fn default() -> Self { + let vec = vec![0xea; SIZE_32KB]; + let boxed_slice: Box<[u8]> = vec.into_boxed_slice(); + let boxed_array: Box<[u8; SIZE_32KB]> = boxed_slice.try_into().expect("Failed to convert Vec to boxed array"); + At28C256 { + data: boxed_array, + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn smoke() { assert!(true); } +} diff --git a/core/src/periph/at28c256.rs b/core/src/periph/at28c256/mod.rs similarity index 52% rename from core/src/periph/at28c256.rs rename to core/src/periph/at28c256/mod.rs index 927a7d3..d097864 100644 --- a/core/src/periph/at28c256.rs +++ b/core/src/periph/at28c256/mod.rs @@ -1,3 +1,6 @@ +mod default; +mod rom_chip; + use crate::constants::constants_system::SIZE_32KB; use crate::periph::rom_chip::RomChip; @@ -11,31 +14,6 @@ pub struct At28C256 { data: Box<[u8; SIZE_32KB]>, } -impl Default for At28C256 { - fn default() -> Self { - let vec = vec![0x00; SIZE_32KB]; - let boxed_slice: Box<[u8]> = vec.into_boxed_slice(); - let boxed_array: Box<[u8; SIZE_32KB]> = boxed_slice.try_into().expect("Failed to convert Vec to boxed array"); - At28C256 { - data: boxed_array, - } - } -} - -impl RomChip for At28C256 { - - fn read(&self, offset: &u16) -> u8 { - self.data[*offset as usize] - } - - fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box { - println!("Writing new chip."); - let mut working = At28C256::default(); - working.data = Box::new(*new_data); - working.into() - } -} - #[cfg(test)] mod test { use crate::constants::constants_system::SIZE_1KB; diff --git a/core/src/periph/at28c256/rom_chip.rs b/core/src/periph/at28c256/rom_chip.rs new file mode 100644 index 0000000..3de9161 --- /dev/null +++ b/core/src/periph/at28c256/rom_chip.rs @@ -0,0 +1,27 @@ +use crate::constants::constants_system::SIZE_32KB; +use crate::periph::at28c256::At28C256; +use crate::periph::rom_chip::RomChip; + +impl RomChip for At28C256 { + + fn read(&self, offset: &u16) -> u8 { + self.data[*offset as usize] + } + + fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box { + println!("Writing new chip."); + let mut working = At28C256::default(); + working.data = Box::new(*new_data); + working.into() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn smoke() { assert!(true); } + + +} \ No newline at end of file diff --git a/core/src/periph/hm62256.rs b/core/src/periph/hm62256.rs index 6d6ba64..65cc5d3 100644 --- a/core/src/periph/hm62256.rs +++ b/core/src/periph/hm62256.rs @@ -5,9 +5,9 @@ use crate::constants::constants_system::SIZE_32KB; use crate::periph::ram_chip::RamChip; use crate::periph::rom_chip::RomChip; -struct Hm62256 { - base_offset: u16, - data: Box<[u8]> +pub struct Hm62256 { + pub(crate) base_offset: u16, + pub(crate) data: Box<[u8]> } impl Default for Hm62256 { @@ -24,8 +24,9 @@ impl Default for Hm62256 { impl RomChip for Hm62256 { fn read(&self, offset: &u16) -> u8 { - //println!("READING FROM RAM AT [{offset:04x}]"); - self.data[*offset as usize] + // loops memory around past 32k + let effective = *offset as i32 % SIZE_32KB as i32; + self.data[effective as usize] } fn program(_: Box<[u8; SIZE_32KB]>) -> Box { diff --git a/core/src/periph/mod.rs b/core/src/periph/mod.rs index 8fc0050..a507e5a 100644 --- a/core/src/periph/mod.rs +++ b/core/src/periph/mod.rs @@ -2,5 +2,5 @@ pub mod rom_chip; pub mod at28c256; pub mod ram_chip; -mod hm62256; +pub mod hm62256;