Added ADDX/SUBX instructions to m68k

This commit is contained in:
transistor 2021-12-01 15:40:41 -08:00
parent 0f2f989775
commit b165e18fac
2 changed files with 71 additions and 4 deletions

View File

@ -184,8 +184,17 @@ impl M68k {
let (result, _) = overflowing_add_sized(existing, value, Size::Long);
*self.get_a_reg_mut(dest) = result;
},
//Instruction::ADDX(Target) => {
//},
Instruction::ADDX(src, dest, size) => {
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let extend = self.get_flag(Flags::Extend) as u32;
let (result1, carry1) = overflowing_add_sized(existing, value, size);
let (result2, carry2) = overflowing_add_sized(result1, extend, size);
let overflow = get_add_overflow(existing, value, result2, size);
self.set_compare_flags(result2, size, carry1 || carry2, overflow);
self.set_flag(Flags::Extend, carry1 || carry2);
self.set_target_value(dest, result2, size)?;
},
Instruction::AND(src, dest, size) => {
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
@ -689,8 +698,17 @@ impl M68k {
let (result, _) = overflowing_sub_sized(existing, value, Size::Long);
*self.get_a_reg_mut(dest) = result;
},
//Instruction::SUBX(Target) => {
//},
Instruction::SUBX(src, dest, size) => {
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let extend = self.get_flag(Flags::Extend) as u32;
let (result1, carry1) = overflowing_sub_sized(existing, value, size);
let (result2, carry2) = overflowing_sub_sized(result1, extend, size);
let overflow = get_sub_overflow(existing, value, result2, size);
self.set_compare_flags(result2, size, carry1 || carry2, overflow);
self.set_flag(Flags::Extend, carry1 || carry2);
self.set_target_value(dest, result2, size)?;
},
Instruction::SWAP(reg) => {
let value = self.state.d_reg[reg as usize];
self.state.d_reg[reg as usize] = ((value & 0x0000FFFF) << 16) | ((value & 0xFFFF0000) >> 16);

View File

@ -518,6 +518,30 @@ mod execute_tests {
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x0000F800, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x27FF, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x0000F800, d1: 0x00000000, a0: 0xFFFFF800, a1: 0x00000000, sr: 0x27FF, mem: 0x00000000 },
},
TestCase {
name: "addx",
ins: Instruction::ADDX(Target::DirectDReg(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xD101 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x0000007F, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x000000FE, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x270A, mem: 0x00000000 },
},
TestCase {
name: "addx with extend",
ins: Instruction::ADDX(Target::DirectDReg(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xD101 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x0000007F, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2710, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x000000FF, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x270A, mem: 0x00000000 },
},
TestCase {
name: "addx with extend and carry",
ins: Instruction::ADDX(Target::DirectDReg(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xD101 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2710, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000000, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2715, mem: 0x00000000 },
},
TestCase {
name: "andi with sr",
ins: Instruction::ANDtoSR(0xF8FF),
@ -933,6 +957,31 @@ mod execute_tests {
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2708, mem: 0x00000000 },
},
TestCase {
name: "subx",
ins: Instruction::SUBX(Target::DirectDReg(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0x9101 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x000000FF, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2708, mem: 0x00000000 },
},
TestCase {
name: "subx with extend",
ins: Instruction::SUBX(Target::DirectDReg(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0x9101 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x000000FF, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2710, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x0000007F, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2702, mem: 0x00000000 },
},
TestCase {
name: "subx with extend and carry",
ins: Instruction::SUBX(Target::DirectDReg(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0x9101 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000000, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2710, mem: 0x00000000 },
fini: TestState { pc: 0x00000002, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x0000007F, a0: 0x00000000, a1: 0x00000000, sr: 0x2719, mem: 0x00000000 },
},
];