diff --git a/binaries/kernel.bin b/binaries/kernel.bin new file mode 100755 index 0000000..fc35300 Binary files /dev/null and b/binaries/kernel.bin differ diff --git a/binaries/monitor.bin b/binaries/monitor.bin new file mode 100755 index 0000000..c81cdfe Binary files /dev/null and b/binaries/monitor.bin differ diff --git a/src/cpus/m68k/decode.rs b/src/cpus/m68k/decode.rs index 73dbaac..bc53897 100644 --- a/src/cpus/m68k/decode.rs +++ b/src/cpus/m68k/decode.rs @@ -222,7 +222,7 @@ impl M68kDecoder { let data = self.read_instruction_word(space)?; match optype { 0b0000 => Ok(Instruction::ORtoSR(data)), - 0b0001 => Ok(Instruction::ANDtoSR(data)), + 0b0010 => Ok(Instruction::ANDtoSR(data)), 0b1010 => Ok(Instruction::EORtoSR(data)), _ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)), } @@ -532,7 +532,7 @@ impl M68kDecoder { if size.is_none() { let sign = if (ins & 0x0100) == 0 { Sign::Unsigned } else { Sign::Signed }; let data_reg = Target::DirectDReg(get_high_reg(ins)); - let effective_addr = self.decode_lower_effective_address(space, ins, size)?; + let effective_addr = self.decode_lower_effective_address(space, ins, Some(Size::Word))?; Ok(Instruction::MUL(effective_addr, data_reg, Size::Word, sign)) } else if (ins & 0b000111110000) == 0b000100000000 { // TODO ABCD or EXG diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 3642edb..78d6f76 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -523,7 +523,7 @@ impl MC68010 { let addr = self.get_a_reg_mut(reg); *addr = new_value; }, - _ => { panic!("Unsupported instruction"); }, + _ => { return Err(Error::new("Unsupported instruction")); }, } Ok(()) diff --git a/src/cpus/m68k/tests.rs b/src/cpus/m68k/tests.rs index d9a0835..7475547 100644 --- a/src/cpus/m68k/tests.rs +++ b/src/cpus/m68k/tests.rs @@ -2,7 +2,7 @@ use crate::memory::{Address, AddressSpace, MemoryBlock}; use super::execute::MC68010; -use super::decode::{Instruction, Target, Size}; +use super::decode::{Instruction, Target, Size, Sign}; const INIT_STACK: Address = 0x00002000; const INIT_ADDR: Address = 0x00000010; @@ -28,7 +28,7 @@ fn init_test() -> (MC68010, AddressSpace) { #[cfg(test)] mod tests { use super::{init_test, INIT_ADDR}; - use super::{Instruction, Target, Size}; + use super::{Instruction, Target, Size, Sign}; #[test] fn instruction_nop() { @@ -97,13 +97,25 @@ mod tests { } #[test] - fn instruction_movel() { + fn instruction_andi_sr() { let (mut cpu, mut space) = init_test(); - space.write_beu16(INIT_ADDR, 0x2F49).unwrap(); - space.write_beu16(INIT_ADDR + 2, 0x0034).unwrap(); + space.write_beu16(INIT_ADDR, 0x027C).unwrap(); + space.write_beu16(INIT_ADDR + 2, 0xF8FF).unwrap(); cpu.decode_next(&mut space).unwrap(); - assert_eq!(cpu.decoder.instruction, Instruction::MOVE(Target::DirectAReg(0x01), Target::IndirectARegOffset(7, 52), Size::Long)); + assert_eq!(cpu.decoder.instruction, Instruction::ANDtoSR(0xF8FF)); + //cpu.execute_current(&mut space).unwrap(); + //assert_eq!(cpu.state.sr & 0x0F, 0x00); + } + + #[test] + fn instruction_muls() { + let (mut cpu, mut space) = init_test(); + + space.write_beu16(INIT_ADDR, 0xC1FC).unwrap(); + space.write_beu16(INIT_ADDR + 2, 0x0276).unwrap(); + cpu.decode_next(&mut space).unwrap(); + assert_eq!(cpu.decoder.instruction, Instruction::MUL(Target::Immediate(0x276), Target::DirectDReg(0), Size::Word, Sign::Signed)); //cpu.execute_current(&mut space).unwrap(); //assert_eq!(cpu.state.sr & 0x0F, 0x00); } diff --git a/src/main.rs b/src/main.rs index 193bcea..b631a51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,13 +11,14 @@ use crate::devices::mc68681::MC68681; fn main() { let mut space = AddressSpace::new(); - let monitor = MemoryBlock::load("monitor.bin").unwrap(); + let monitor = MemoryBlock::load("binaries/monitor.bin").unwrap(); for byte in monitor.contents.iter() { print!("{:02x} ", byte); } space.insert(0x00000000, Box::new(monitor)); - let ram = MemoryBlock::new(vec![0; 0x00100000]); + let mut ram = MemoryBlock::new(vec![0; 0x00100000]); + ram.load_at(0, "binaries/kernel.bin").unwrap(); space.insert(0x00100000, Box::new(ram)); let mut serial = MC68681::new(); @@ -25,7 +26,7 @@ fn main() { space.insert(0x00700000, Box::new(serial)); let mut cpu = MC68010::new(); - //cpu.enable_tracing(); + cpu.enable_tracing(); //cpu.add_breakpoint(0x0c94); //cpu.add_breakpoint(0x0cf2); @@ -44,9 +45,16 @@ fn main() { /* // TODO I need to add a way to decode and dump the assembly for a section of code, in debugger - cpu.state.pc = 0x0db4; + cpu.state.pc = 0x00100000; + cpu.state.pc = 0x0010c270; while cpu.is_running() { - cpu.decode_next(&mut space).unwrap(); + match cpu.decode_next(&mut space) { + Ok(()) => { }, + Err(err) => { + cpu.dump_state(&mut space); + panic!("{:?}", err); + }, + } } */ } diff --git a/src/memory.rs b/src/memory.rs index 8aefe7a..25c31f0 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -31,6 +31,19 @@ impl MemoryBlock { Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))), } } + + pub fn load_at(&mut self, mut addr: Address, filename: &str) -> Result<(), Error> { + match fs::read(filename) { + Ok(contents) => { + for byte in contents { + self.contents[addr as usize] = byte; + addr += 1; + } + Ok(()) + }, + Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))), + } + } } impl Addressable for MemoryBlock { diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..1887d2a --- /dev/null +++ b/todo.txt @@ -0,0 +1,9 @@ + +* there's probably a problem with the shift operations flags, they look more complex than what's being done atm + + +* check all instructions in the docs + +* make tests for each instruction + +