From 0f2f9897754b853b5bb02e1d9b7cf4828e59001b Mon Sep 17 00:00:00 2001 From: transistor Date: Wed, 1 Dec 2021 10:45:24 -0800 Subject: [PATCH] Fixed bug in m68k with Extend flag in shift instructions --- src/cpus/m68k/execute.rs | 18 ++++++++++++++---- src/cpus/m68k/tests.rs | 26 ++++++++++++++++++++++++++ src/debugger.rs | 7 ++++--- src/peripherals/genesis/ym7101.rs | 8 +++----- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 170e9fc..93aca9d 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -207,6 +207,10 @@ impl M68k { for _ in 0..count { pair = shift_operation(pair.0, size, shift_dir, true); } + self.set_target_value(target, pair.0, size)?; + + // Adjust flags + self.set_flag(Flags::Extend, false); self.set_logic_flags(pair.0, size); if pair.1 { self.set_flag(Flags::Carry, true); @@ -215,7 +219,6 @@ impl M68k { if get_msb(pair.0, size) != get_msb(original, size) { self.set_flag(Flags::Overflow, true); } - self.set_target_value(target, pair.0, size)?; }, Instruction::Bcc(cond, offset) => { let should_branch = self.get_current_condition(cond); @@ -459,12 +462,15 @@ impl M68k { for _ in 0..count { pair = shift_operation(pair.0, size, shift_dir, false); } + self.set_target_value(target, pair.0, size)?; + + // Adjust flags + self.set_flag(Flags::Extend, false); self.set_logic_flags(pair.0, size); if pair.1 { self.set_flag(Flags::Carry, true); self.set_flag(Flags::Extend, true); } - self.set_target_value(target, pair.0, size)?; }, Instruction::MOVE(src, dest, size) => { let value = self.get_target_value(src, size)?; @@ -614,11 +620,13 @@ impl M68k { for _ in 0..count { pair = rotate_operation(pair.0, size, shift_dir, None); } + self.set_target_value(target, pair.0, size)?; + + // Adjust flags self.set_logic_flags(pair.0, size); if pair.1 { self.set_flag(Flags::Carry, true); } - self.set_target_value(target, pair.0, size)?; }, Instruction::ROXd(count, target, size, shift_dir) => { let count = self.get_target_value(count, size)? % 64; @@ -627,11 +635,13 @@ impl M68k { pair = rotate_operation(pair.0, size, shift_dir, Some(self.get_flag(Flags::Extend))); self.set_flag(Flags::Extend, pair.1); } + self.set_target_value(target, pair.0, size)?; + + // Adjust flags self.set_logic_flags(pair.0, size); if pair.1 { self.set_flag(Flags::Carry, true); } - self.set_target_value(target, pair.0, size)?; }, Instruction::RTE => { self.require_supervisor()?; diff --git a/src/cpus/m68k/tests.rs b/src/cpus/m68k/tests.rs index 7c5e35e..5dafb25 100644 --- a/src/cpus/m68k/tests.rs +++ b/src/cpus/m68k/tests.rs @@ -694,6 +694,32 @@ mod execute_tests { init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x000000CB, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x27FF, mem: 0x00000000 }, fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x000000CB, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x27F0, mem: 0x00000000 }, }, + + TestCase { + name: "lsl", + ins: Instruction::LSd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left), + data: &[ 0xE308 ], + cputype: M68kType::MC68010, + init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x271F, mem: 0x00000000 }, + fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000002, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 }, + }, + TestCase { + name: "lsl with bit out", + ins: Instruction::LSd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left), + data: &[ 0xE308 ], + cputype: M68kType::MC68010, + init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000081, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 }, + fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000002, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2711, mem: 0x00000000 }, + }, + TestCase { + name: "lsr", + ins: Instruction::LSd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right), + data: &[ 0xE208 ], + cputype: M68kType::MC68010, + init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000081, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 }, + fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000040, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2711, mem: 0x00000000 }, + }, + TestCase { name: "muls", ins: Instruction::MULW(Target::Immediate(0x0276), 0, Sign::Signed), diff --git a/src/debugger.rs b/src/debugger.rs index 6d29933..c81ba20 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -92,14 +92,15 @@ impl Debugger { //self.port.dump_memory(self.state.ssp as Address, 0x40 as Address); } }, - "dp" | "dump_peripheral" => { + "i" | "inspect" => { if args.len() < 2 { - println!("Usage: dp []"); + println!("Usage: inspect []"); } else { let device = system.devices.get(args[1]).ok_or_else(|| Error::new(&format!("No device named {}", args[1])))?; + let subargs = if args.len() > 2 { &args[2..] } else { &[""] }; device.borrow_mut().as_inspectable() .ok_or_else(|| Error::new("That device is not inspectable"))? - .inspect(system, &args[2..])?; + .inspect(system, subargs)?; } }, "dis" | "disassemble" => { diff --git a/src/peripherals/genesis/ym7101.rs b/src/peripherals/genesis/ym7101.rs index c7f3f7f..be87426 100644 --- a/src/peripherals/genesis/ym7101.rs +++ b/src/peripherals/genesis/ym7101.rs @@ -649,7 +649,7 @@ impl Addressable for Ym7101 { self.state.transfer_fill = if data.len() >= 2 { read_beu16(data) } else { data[0] as u16 }; self.state.set_dma_mode(DmaType::Fill); } else { - info!("{}: data port write {} bytes to {:?}:{:x} with {:?}", DEV_NAME, data.len(), self.state.transfer_target, self.state.transfer_addr, data); + debug!("{}: data port write {} bytes to {:?}:{:x} with {:?}", DEV_NAME, data.len(), self.state.transfer_target, self.state.transfer_addr, data); { let addr = self.state.transfer_addr as usize; @@ -664,7 +664,7 @@ impl Addressable for Ym7101 { // Write to Control Port 0x04 | 0x06 => { - info!("{}: write {} bytes to port {:x} with data {:?}", DEV_NAME, data.len(), addr, data); + debug!("{}: write {} bytes to port {:x} with data {:?}", DEV_NAME, data.len(), addr, data); let value = read_beu16(data); if (value & 0xC000) == 0x8000 { @@ -695,9 +695,7 @@ impl Addressable for Ym7101 { impl Inspectable for Ym7101 { fn inspect(&mut self, system: &System, args: &[&str]) -> Result<(), Error> { - let cmd = if args.len() > 0 { args[0] } else { "state" }; - - match cmd { + match args[0] { "" | "state" => { self.state.dump_state(); },