1
0
mirror of https://github.com/mre/mos6502.git synced 2024-11-30 20:51:21 +00:00

First stab at implementing decimal mode for ADC

This commit is contained in:
Sam M W 2021-01-25 22:57:28 +00:00
parent 2deb0658fd
commit 85dd92615d

View File

@ -515,45 +515,51 @@ impl CPU {
); );
} }
fn add_with_carry(&mut self, value: i8) { fn add_with_carry(&mut self, value: i8) {
if self.registers.status.contains(Status::PS_DECIMAL_MODE) { let a_before: i8 = self.registers.accumulator;
// TODO akeeton: Implement binary-coded decimal. let c_before: i8 = if self.registers.status.contains(Status::PS_CARRY) {
debug!("binary-coded decimal not implemented for add_with_carry"); 1
} else { } else {
let a_before: i8 = self.registers.accumulator; 0
let c_before: i8 = if self.registers.status.contains(Status::PS_CARRY) { };
1 let a_after: i8 = a_before.wrapping_add(c_before).wrapping_add(value);
} else {
0
};
let a_after: i8 = a_before.wrapping_add(c_before).wrapping_add(value);
debug_assert_eq!( debug_assert_eq!(
a_after as u8, a_after as u8,
a_before.wrapping_add(c_before).wrapping_add(value) as u8 a_before.wrapping_add(c_before).wrapping_add(value) as u8
); );
let did_carry = (a_after as u8) < (a_before as u8); let bcd1: i8 = if (a_after & 0x0f) as u8 > 0x09 {
0x06
} else {
0x00
};
let did_overflow = (a_before < 0 && value < 0 && a_after >= 0) let bcd2: i8 = if (a_after.wrapping_add(bcd1) as u8 & 0xf0) as u8 > 0x90 {
|| (a_before > 0 && value > 0 && a_after <= 0); 0x60
} else {
0x00
};
let mask = Status::PS_CARRY | Status::PS_OVERFLOW; let result: i8 = if self.registers.status.contains(Status::PS_DECIMAL_MODE) {
a_after.wrapping_add(bcd1).wrapping_add(bcd2)
} else {
a_after
};
self.registers.status.set_with_mask( let did_carry = (result as u8) < (a_before as u8);
mask,
Status::new(StatusArgs {
carry: did_carry,
overflow: did_overflow,
..StatusArgs::none()
}),
);
self.load_accumulator(a_after); let did_overflow = (a_before < 0 && value < 0 && a_after >= 0)
|| (a_before > 0 && value > 0 && a_after <= 0);
debug!("accumulator: {}", self.registers.accumulator); let mask = Status::PS_CARRY | Status::PS_OVERFLOW;
}
} self.registers.status.set_with_mask( mask, Status::new(StatusArgs { carry: did_carry, overflow: did_overflow, ..StatusArgs::none() }),);
self.load_accumulator(result);
debug!("accumulator: {}", self.registers.accumulator);
}
fn and(&mut self, value: i8) { fn and(&mut self, value: i8) {
let a_after = self.registers.accumulator & value; let a_after = self.registers.accumulator & value;