diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index dc50b3a..7d70afc 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -158,7 +158,7 @@ impl MC68010 { Ok(value) } - fn decode_next(&mut self, space: &mut AddressSpace) -> Result<(), Error> { + pub(crate) fn decode_next(&mut self, space: &mut AddressSpace) -> Result<(), Error> { self.current_instruction_addr = self.pc; self.current_instruction = self.decode_one(space)?; @@ -195,7 +195,7 @@ impl MC68010 { } } - fn execute_current(&mut self, space: &mut AddressSpace) -> Result<(), Error> { + pub(crate) fn execute_current(&mut self, space: &mut AddressSpace) -> Result<(), Error> { match self.current_instruction { Instruction::ADD(src, dest, size) => { let value = self.get_target_value(space, src, size)?; diff --git a/src/cpus/m68k/mod.rs b/src/cpus/m68k/mod.rs index 5aa921f..d601809 100644 --- a/src/cpus/m68k/mod.rs +++ b/src/cpus/m68k/mod.rs @@ -2,6 +2,7 @@ mod decode; mod execute; //mod debugger; +mod tests; pub use self::execute::MC68010; diff --git a/src/cpus/m68k/tests.rs b/src/cpus/m68k/tests.rs new file mode 100644 index 0000000..5138816 --- /dev/null +++ b/src/cpus/m68k/tests.rs @@ -0,0 +1,57 @@ + +use crate::memory::{Address, AddressSpace, MemoryBlock}; + +use super::execute::MC68010; +use super::decode::{Instruction, Target, Size}; + +const INIT_STACK: Address = 0x00002000; +const INIT_ADDR: Address = 0x00000010; + +fn init_test() -> (MC68010, AddressSpace) { + let mut space = AddressSpace::new(); + + // Insert basic initialization + let mut data = vec![0; 0x00100000]; + let mem = MemoryBlock::new(data); + space.insert(0x00000000, Box::new(mem)); + space.write_beu32(0, INIT_STACK as u32).unwrap(); + space.write_beu32(4, INIT_ADDR as u32).unwrap(); + + let mut cpu = MC68010::new(); + cpu.step(&mut space).unwrap(); + assert_eq!(cpu.pc, INIT_ADDR as u32); + assert_eq!(cpu.msp, INIT_STACK as u32); + assert_eq!(cpu.current_instruction, Instruction::NOP); + (cpu, space) +} + +#[cfg(test)] +mod tests { + use super::{init_test, INIT_ADDR}; + use super::{Instruction, Target, Size}; + + #[test] + fn instruction_nop() { + let (mut cpu, mut space) = init_test(); + + space.write_beu16(INIT_ADDR, 0x4e71).unwrap(); + cpu.decode_next(&mut space).unwrap(); + assert_eq!(cpu.current_instruction, Instruction::NOP); + cpu.execute_current(&mut space).unwrap(); + // TODO you need a way to easily check the entire state (you maybe need to make a special struct for the state) + } + + + #[test] + fn instruction_ori() { + let (mut cpu, mut space) = init_test(); + + space.write_beu16(INIT_ADDR, 0x0008).unwrap(); + space.write_beu16(INIT_ADDR + 2, 0x00FF).unwrap(); + cpu.decode_next(&mut space).unwrap(); + assert_eq!(cpu.current_instruction, Instruction::OR(Target::Immediate(0xFF), Target::DirectAReg(0), Size::Byte)); + cpu.execute_current(&mut space).unwrap(); + assert_eq!(cpu.a_reg[0], 0x000000FF); + } +} + diff --git a/src/main.rs b/src/main.rs index d09c7c6..1c627f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ fn main() { space.insert(0x00700000, Box::new(serial)); let mut cpu = MC68010::new(); - //cpu.set_breakpoint(0x0224); + cpu.set_breakpoint(0x0ea0); cpu.use_tracing = true; while cpu.is_running() { match cpu.step(&mut space) {