From 75e4a760eb8993fada3760b6d2e126df7febb77e Mon Sep 17 00:00:00 2001 From: transistor Date: Fri, 3 Dec 2021 15:32:17 -0800 Subject: [PATCH] Added ABCD, SBCD, and TAS instructions to m68k --- src/cpus/m68k/decode.rs | 4 ++-- src/cpus/m68k/execute.rs | 41 ++++++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/cpus/m68k/decode.rs b/src/cpus/m68k/decode.rs index 2cb0083..5122abf 100644 --- a/src/cpus/m68k/decode.rs +++ b/src/cpus/m68k/decode.rs @@ -405,7 +405,7 @@ impl M68kDecoder { let regx = get_high_reg(ins); let regy = get_low_reg(ins); - match (ins & 0x08) == 0 { + match (ins & 0x08) != 0 { false => Ok(Instruction::SBCD(Target::DirectDReg(regy), Target::DirectDReg(regx))), true => Ok(Instruction::SBCD(Target::IndirectARegDec(regy), Target::IndirectARegDec(regx))), } @@ -477,7 +477,7 @@ impl M68kDecoder { let regx = get_high_reg(ins); let regy = get_low_reg(ins); - match (ins & 0x08) == 0 { + match (ins & 0x08) != 0 { false => Ok(Instruction::ABCD(Target::DirectDReg(regy), Target::DirectDReg(regx))), true => Ok(Instruction::ABCD(Target::IndirectARegDec(regy), Target::IndirectARegDec(regx))), } diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 0d0def9..071a0be 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -167,8 +167,16 @@ impl M68k { pub fn execute_current(&mut self) -> Result<(), Error> { self.timer.execute.start(); match self.decoder.instruction { - //Instruction::ABCD(Target) => { - //}, + Instruction::ABCD(src, dest) => { + let value = convert_from_bcd(self.get_target_value(src, Size::Byte)? as u8); + let existing = convert_from_bcd(self.get_target_value(dest, Size::Byte)? as u8); + let result = existing.wrapping_add(value).wrapping_add(self.get_flag(Flags::Extend) as u8); + let carry = result > 99; + self.set_target_value(dest, convert_to_bcd(result) as u32, Size::Byte)?; + self.set_flag(Flags::Zero, result == 0); + self.set_flag(Flags::Carry, carry); + self.set_flag(Flags::Extend, carry); + }, Instruction::ADD(src, dest, size) => { let value = self.get_target_value(src, size)?; let existing = self.get_target_value(dest, size)?; @@ -681,8 +689,16 @@ impl M68k { self.state.sr = flags; self.state.status = Status::Stopped; }, - //Instruction::SBCD(Target) => { - //}, + Instruction::SBCD(src, dest) => { + let value = convert_from_bcd(self.get_target_value(src, Size::Byte)? as u8); + let existing = convert_from_bcd(self.get_target_value(dest, Size::Byte)? as u8); + let result = existing.wrapping_sub(value).wrapping_sub(self.get_flag(Flags::Extend) as u8); + let borrow = existing < value; + self.set_target_value(dest, convert_to_bcd(result) as u32, Size::Byte)?; + self.set_flag(Flags::Zero, result == 0); + self.set_flag(Flags::Carry, borrow); + self.set_flag(Flags::Extend, borrow); + }, Instruction::SUB(src, dest, size) => { let value = self.get_target_value(src, size)?; let existing = self.get_target_value(dest, size)?; @@ -713,8 +729,14 @@ impl M68k { let value = self.state.d_reg[reg as usize]; self.state.d_reg[reg as usize] = ((value & 0x0000FFFF) << 16) | ((value & 0xFFFF0000) >> 16); }, - //Instruction::TAS(Target) => { - //}, + Instruction::TAS(target) => { + let value = self.get_target_value(target, Size::Byte)?; + self.set_flag(Flags::Negative, (value & 0x80) != 0); + self.set_flag(Flags::Zero, value == 0); + self.set_flag(Flags::Overflow, false); + self.set_flag(Flags::Carry, false); + self.set_target_value(target, value | 0x80, Size::Byte)?; + }, Instruction::TST(target, size) => { let value = self.get_target_value(target, size)?; self.set_logic_flags(value, size); @@ -1255,6 +1277,13 @@ fn rotate_operation(value: u32, size: Size, dir: ShiftDirection, use_extend: Opt } } +fn convert_from_bcd(value: u8) -> u8 { + (value >> 4) * 10 + (value & 0x0F) +} + +fn convert_to_bcd(value: u8) -> u8 { + (((value / 10) & 0x0F) << 4) | ((value % 10) & 0x0F) +} fn get_value_sized(value: u32, size: Size) -> u32 { match size {