mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
Refactor affected flags on alu function
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/// CPU Status flags for both the 65XX and SPC700 processors
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Flags {
|
||||
Negative(bool),
|
||||
Overflow(bool),
|
||||
|
||||
@@ -3,8 +3,6 @@ use crate::bus::Bus;
|
||||
use crate::utils::addressing::{AddressingMode, IndexRegister};
|
||||
use crate::utils::alu;
|
||||
|
||||
type F = crate::common::flags::Flags;
|
||||
|
||||
impl CPU {
|
||||
fn get_8bit_from_address(&self, bus: &Bus, addressing_mode: AddressingMode) -> u8 {
|
||||
addressing_mode.value_8bit(
|
||||
@@ -35,26 +33,20 @@ impl CPU {
|
||||
let target = self.registers.a;
|
||||
if is_16bit {
|
||||
let value = self.get_16bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
let (result, affected_flags) = match is_decimal_mode {
|
||||
true => alu::adc_bcd(target, value, carry_flag),
|
||||
false => alu::adc_bin(target, value, carry_flag),
|
||||
};
|
||||
self.registers.a = result;
|
||||
self.registers.set_flags(&[
|
||||
F::Carry(is_carry), F::Negative(is_negative),
|
||||
F::Zero(is_zero), F::Overflow(is_overflow),
|
||||
]);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
} else {
|
||||
let value = self.get_8bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
let (result, affected_flags) = match is_decimal_mode {
|
||||
true => alu::adc_bcd(target as u8, value, carry_flag),
|
||||
false => alu::adc_bin(target as u8, value, carry_flag),
|
||||
};
|
||||
self.registers.set_low_a(result as u8);
|
||||
self.registers.set_flags(&[
|
||||
F::Carry(is_carry), F::Negative(is_negative),
|
||||
F::Zero(is_zero), F::Overflow(is_overflow),
|
||||
]);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
}
|
||||
self.increment_cycles_arithmetic(addressing_mode);
|
||||
}
|
||||
@@ -68,26 +60,20 @@ impl CPU {
|
||||
let target = self.registers.a;
|
||||
if is_16bit {
|
||||
let value = self.get_16bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
let (result, affected_flags) = match is_decimal_mode {
|
||||
true => alu::sbc_bcd(target, value, carry_flag),
|
||||
false => alu::sbc_bin(target, value, carry_flag),
|
||||
};
|
||||
self.registers.a = result;
|
||||
self.registers.set_flags(&[
|
||||
F::Carry(is_carry), F::Negative(is_negative),
|
||||
F::Zero(is_zero), F::Overflow(is_overflow),
|
||||
]);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
} else {
|
||||
let value = self.get_8bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
let (result, affected_flags) = match is_decimal_mode {
|
||||
true => alu::sbc_bcd(target as u8, value, carry_flag),
|
||||
false => alu::sbc_bin(target as u8, value, carry_flag),
|
||||
};
|
||||
self.registers.set_low_a(result as u8);
|
||||
self.registers.set_flags(&[
|
||||
F::Carry(is_carry), F::Negative(is_negative),
|
||||
F::Zero(is_zero), F::Overflow(is_overflow),
|
||||
]);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
}
|
||||
self.increment_cycles_arithmetic(addressing_mode);
|
||||
}
|
||||
@@ -98,16 +84,14 @@ impl CPU {
|
||||
let target = self.registers.a;
|
||||
if self.registers.is_16bit_mode() {
|
||||
let value = self.get_16bit_from_address(bus, addressing_mode);
|
||||
let (result, is_negative, is_zero) = alu::and(target, value);
|
||||
let (result, affected_flags) = alu::and(target, value);
|
||||
self.registers.a = result;
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
} else {
|
||||
let value = self.get_8bit_from_address(bus, addressing_mode);
|
||||
let (result, is_negative, is_zero) = alu::and(target as u8, value);
|
||||
let (result, affected_flags) = alu::and(target as u8, value);
|
||||
self.registers.set_low_a(result);
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
|
||||
}
|
||||
self.increment_cycles_bitwise(addressing_mode);
|
||||
@@ -124,17 +108,13 @@ impl CPU {
|
||||
}
|
||||
};
|
||||
if self.registers.is_16bit_mode() {
|
||||
let (result, is_negative, is_zero, is_carry) = alu::asl(target);
|
||||
let (result, affected_flags) = alu::asl(target);
|
||||
self.registers.a = result;
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_carry_flag(is_carry);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
} else {
|
||||
let (result, is_negative, is_zero, is_carry) = alu::asl(target as u8);
|
||||
let (result, affected_flags) = alu::asl(target as u8);
|
||||
self.registers.set_low_a(result);
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_carry_flag(is_carry);
|
||||
self.registers.set_flags(&affected_flags);
|
||||
}
|
||||
self.increment_cycles_shift(addressing_mode);
|
||||
}
|
||||
|
||||
+122
-230
@@ -1,15 +1,17 @@
|
||||
use super::num_trait::SnesNum;
|
||||
use crate::utils::num_trait::SnesNum;
|
||||
use crate::common::flags::{Flags, Flags::*};
|
||||
|
||||
pub fn adc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool, bool, bool) {
|
||||
let is_carry = target.add_will_carry(value, carry);
|
||||
pub fn adc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4]) {
|
||||
let result = target.add_snes(value, carry);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
let is_overflow = target.is_overflow(value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
(result, [
|
||||
Negative(result.is_negative()),
|
||||
Overflow(target.is_overflow(value, result)),
|
||||
Zero(result.is_zero()),
|
||||
Carry(target.add_will_carry(value, carry)),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn adc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool, bool, bool) {
|
||||
pub fn adc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4]) {
|
||||
let original_target = value;
|
||||
let original_value = value;
|
||||
let nibble_bytes = target.bytes() * 2;
|
||||
@@ -38,22 +40,25 @@ pub fn adc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool,
|
||||
}
|
||||
|
||||
let result = T::from_u32(result);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
let is_overflow = original_target.is_overflow(original_value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
(result, [
|
||||
Negative(result.is_negative()),
|
||||
Overflow(original_target.is_overflow(original_value, result)),
|
||||
Zero(result.is_zero()),
|
||||
Carry(is_carry),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn sbc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool, bool, bool) {
|
||||
let is_carry = target.sbc_will_carry(value, carry);
|
||||
pub fn sbc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4]) {
|
||||
let result = target.sbc_snes(value, carry);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
let is_overflow = target.is_overflow(value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
(result, [
|
||||
Negative(result.is_negative()),
|
||||
Overflow(target.is_overflow(value, result)),
|
||||
Zero(result.is_zero()),
|
||||
Carry(target.sbc_will_carry(value, carry)),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn sbc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool, bool, bool) {
|
||||
pub fn sbc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4]) {
|
||||
let original_target = value;
|
||||
let original_value = value;
|
||||
let nibble_bytes = target.bytes() * 2;
|
||||
@@ -82,25 +87,26 @@ pub fn sbc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool,
|
||||
}
|
||||
|
||||
let result = T::from_u32(result);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
let is_overflow = original_target.is_overflow(original_value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
(result, [
|
||||
Negative(result.is_negative()),
|
||||
Overflow(original_target.is_overflow(original_value, result)),
|
||||
Zero(result.is_zero()),
|
||||
Carry(is_carry),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn and<T: SnesNum>(target: T, value: T) -> (T, bool, bool) {
|
||||
pub fn and<T: SnesNum>(target: T, value: T) -> (T, [Flags; 2]) {
|
||||
let result = target.and(value);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
(result, is_negative, is_zero)
|
||||
(result, [Negative(result.is_negative()), Zero(result.is_zero())])
|
||||
}
|
||||
|
||||
pub fn asl<T: SnesNum>(target: T) -> (T, bool, bool, bool) {
|
||||
pub fn asl<T: SnesNum>(target: T) -> (T, [Flags; 3]) {
|
||||
let result = target.asl();
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
let is_carry = target.is_negative();
|
||||
(result, is_negative, is_zero, is_carry)
|
||||
(result, [
|
||||
Negative(result.is_negative()),
|
||||
Zero(result.is_zero()),
|
||||
Carry(target.is_negative()), // High bit becomes carry
|
||||
])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -110,312 +116,198 @@ mod alu_tests {
|
||||
#[test]
|
||||
fn test_adc_bin() {
|
||||
// 8 bits
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(0_u8, 0_u8, false);
|
||||
let (result, affected_flags) = adc_bin(0_u8, 0_u8, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(0_u8, 50_u8, false);
|
||||
let (result, affected_flags) = adc_bin(0_u8, 50_u8, false);
|
||||
assert_eq!(result, 50);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(200_u8, 155_u8, false);
|
||||
let (result, affected_flags) = adc_bin(200_u8, 155_u8, false);
|
||||
assert_eq!(result, 99);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(200_u8, 155_u8, true);
|
||||
let (result, affected_flags) = adc_bin(200_u8, 155_u8, true);
|
||||
assert_eq!(result, 100);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(200_u8, 54_u8, true);
|
||||
let (result, affected_flags) = adc_bin(200_u8, 54_u8, true);
|
||||
assert_eq!(result, 255);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(200_u8, 54_u8, true);
|
||||
let (result, affected_flags) = adc_bin(200_u8, 54_u8, true);
|
||||
assert_eq!(result, 255);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
// 16 bits
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(0_u16, 0_u16, false);
|
||||
let (result, affected_flags) = adc_bin(0_u16, 0_u16, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(0_u16, 50_u16, false);
|
||||
let (result, affected_flags) = adc_bin(0_u16, 50_u16, false);
|
||||
assert_eq!(result, 50);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(65530_u16, 10_u16, false);
|
||||
let (result, affected_flags) = adc_bin(65530_u16, 10_u16, false);
|
||||
assert_eq!(result, 4);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, true);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(true), Zero(false), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(65530_u16, 10_u16, true);
|
||||
let (result, affected_flags) = adc_bin(65530_u16, 10_u16, true);
|
||||
assert_eq!(result, 5);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, true);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(true), Zero(false), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bin(65530_u16, 4_u16, true);
|
||||
let (result, affected_flags) = adc_bin(65530_u16, 4_u16, true);
|
||||
assert_eq!(result, 65535);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(false)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_adc_bcd() {
|
||||
// 8 bits
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(5_u8, 5_u8, false);
|
||||
let (result, affected_flags) = adc_bcd(5_u8, 5_u8, false);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(7_u8, 9_u8, false);
|
||||
let (result, affected_flags) = adc_bcd(7_u8, 9_u8, false);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(5_u8, 4_u8, true);
|
||||
let (result, affected_flags) = adc_bcd(5_u8, 4_u8, true);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(7_u8, 8_u8, true);
|
||||
let (result, affected_flags) = adc_bcd(7_u8, 8_u8, true);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(0_u8, 0_u8, false);
|
||||
let (result, affected_flags) = adc_bcd(0_u8, 0_u8, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(0b0001_1001_u8, 0b0010_1000_u8, false);
|
||||
let (result, affected_flags) = adc_bcd(0b0001_1001_u8, 0b0010_1000_u8, false);
|
||||
assert_eq!(result, 0b0100_0111);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
// 16 bits
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(5_u16, 5_u16, false);
|
||||
let (result, affected_flags) = adc_bcd(5_u16, 5_u16, false);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(7_u16, 9_u16, false);
|
||||
let (result, affected_flags) = adc_bcd(7_u16, 9_u16, false);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(5_u16, 4_u16, true);
|
||||
let (result, affected_flags) = adc_bcd(5_u16, 4_u16, true);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(7_u16, 8_u16, true);
|
||||
let (result, affected_flags) = adc_bcd(7_u16, 8_u16, true);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(0_u16, 0_u16, false);
|
||||
let (result, affected_flags) = adc_bcd(0_u16, 0_u16, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(0x0500_u16, 0x0500_u16, false);
|
||||
let (result, affected_flags) = adc_bcd(0x0500_u16, 0x0500_u16, false);
|
||||
assert_eq!(result, 0b0001_0000_0000_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = adc_bcd(0b0001_1001_u16, 0b0010_1000_u16, false);
|
||||
let (result, affected_flags) = adc_bcd(0b0001_1001_u16, 0b0010_1000_u16, false);
|
||||
assert_eq!(result, 0b0100_0111);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(false), Carry(false)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dec_bin() {
|
||||
// 8 bit
|
||||
let (result, carry, negative, zero, overflow) = sbc_bin(1_u8, 1_u8, false);
|
||||
let (result, affected_flags) = sbc_bin(1_u8, 1_u8, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = sbc_bin(0_u8, 1_u8, false);
|
||||
let (result, affected_flags) = sbc_bin(0_u8, 1_u8, false);
|
||||
assert_eq!(result, 0b11111111);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = sbc_bin(0_u8, 1_u8, true);
|
||||
let (result, affected_flags) = sbc_bin(0_u8, 1_u8, true);
|
||||
assert_eq!(result, 0b11111110);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]);
|
||||
|
||||
// 16 bit
|
||||
let (result, carry, negative, zero, overflow) = sbc_bin(1_u16, 1_u16, false);
|
||||
let (result, affected_flags) = sbc_bin(1_u16, 1_u16, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = sbc_bin(0_u16, 1_u16, false);
|
||||
let (result, affected_flags) = sbc_bin(0_u16, 1_u16, false);
|
||||
assert_eq!(result, 0b11111111_11111111);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = sbc_bin(0_u16, 1_u16, true);
|
||||
let (result, affected_flags) = sbc_bin(0_u16, 1_u16, true);
|
||||
assert_eq!(result, 0b11111111_11111110);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dec_bcd() {
|
||||
// 8 bit
|
||||
let (result, carry, negative, zero, overflow) = sbc_bcd(0x49_u8, 0x48_u8, false);
|
||||
let (result, affected_flags) = sbc_bcd(0x49_u8, 0x48_u8, false);
|
||||
assert_eq!(result, 0x00);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = sbc_bcd(0x49_u8, 0x50_u8, true);
|
||||
let (result, affected_flags) = sbc_bcd(0x49_u8, 0x50_u8, true);
|
||||
assert_eq!(result, 0x99);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(false)]);
|
||||
|
||||
// 16 bit
|
||||
let (result, carry, negative, zero, overflow) = sbc_bcd(0x4999_u16, 0x4998_u16, false);
|
||||
let (result, affected_flags) = sbc_bcd(0x4999_u16, 0x4998_u16, false);
|
||||
assert_eq!(result, 0x0000);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(true)]);
|
||||
|
||||
let (result, carry, negative, zero, overflow) = sbc_bcd(0x4999_u16, 0x5000_u16, true);
|
||||
let (result, affected_flags) = sbc_bcd(0x4999_u16, 0x5000_u16, true);
|
||||
assert_eq!(result, 0x9999);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(false)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
// 8 bit
|
||||
let (result, is_negative, is_zero) = and(0b0101_0101_u8, 0b0101_0101_u8);
|
||||
let (result, affected_flags) = and(0b0101_0101_u8, 0b0101_0101_u8);
|
||||
assert_eq!(result, 0b0101_0101);
|
||||
assert_eq!(is_negative, false);
|
||||
assert_eq!(is_zero, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Zero(false)]);
|
||||
|
||||
let (result, is_negative, is_zero) = and(0b0101_0101_u8, 0b1010_1010_u8);
|
||||
let (result, affected_flags) = and(0b0101_0101_u8, 0b1010_1010_u8);
|
||||
assert_eq!(result, 0x00);
|
||||
assert_eq!(is_negative, false);
|
||||
assert_eq!(is_zero, true);
|
||||
assert_eq!(affected_flags, [Negative(false), Zero(true)]);
|
||||
|
||||
// 16 bit
|
||||
let (result, is_negative, is_zero) = and(0b01010101_01010101_u16, 0b01010101_01010101_u16);
|
||||
let (result, affected_flags) = and(0b01010101_01010101_u16, 0b01010101_01010101_u16);
|
||||
assert_eq!(result, 0b01010101_01010101);
|
||||
assert_eq!(is_negative, false);
|
||||
assert_eq!(is_zero, false);
|
||||
assert_eq!(affected_flags, [Negative(false), Zero(false)]);
|
||||
|
||||
let (result, is_negative, is_zero) = and(0b01010101_01010101_u16, 0b10101010_10101010_u16);
|
||||
let (result, affected_flags) = and(0b01010101_01010101_u16, 0b10101010_10101010_u16);
|
||||
assert_eq!(result, 0x0000);
|
||||
assert_eq!(is_negative, false);
|
||||
assert_eq!(is_zero, true);
|
||||
assert_eq!(affected_flags, [Negative(false), Zero(true)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_asl() {
|
||||
// 8 bit
|
||||
let (result, is_negative, is_zero, is_carry) = asl(0b0101_0101_u8);
|
||||
let (result, affected_flags) = asl(0b0101_0101_u8);
|
||||
assert_eq!(result, 0b1010_1010);
|
||||
assert_eq!(is_negative, true);
|
||||
assert_eq!(is_zero, false);
|
||||
assert_eq!(is_carry, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, is_negative, is_zero, is_carry) = asl(0b1000_0000_u8);
|
||||
let (result, affected_flags) = asl(0b1000_0000_u8);
|
||||
assert_eq!(result, 0b0000_0000);
|
||||
assert_eq!(is_negative, false);
|
||||
assert_eq!(is_zero, true);
|
||||
assert_eq!(is_carry, true);
|
||||
assert_eq!(affected_flags, [Negative(false), Zero(true), Carry(true)]);
|
||||
|
||||
// 16 bit
|
||||
let (result, is_negative, is_zero, is_carry) = asl(0b01000000_00000000_u16);
|
||||
let (result, affected_flags) = asl(0b01000000_00000000_u16);
|
||||
assert_eq!(result, 0b10000000_00000000);
|
||||
assert_eq!(is_negative, true);
|
||||
assert_eq!(is_zero, false);
|
||||
assert_eq!(is_carry, false);
|
||||
assert_eq!(affected_flags, [Negative(true), Zero(false), Carry(false)]);
|
||||
|
||||
let (result, is_negative, is_zero, is_carry) = asl(0b10000000_00000000_u16);
|
||||
let (result, affected_flags) = asl(0b10000000_00000000_u16);
|
||||
assert_eq!(result, 0b00000000_00000000);
|
||||
assert_eq!(is_negative, false);
|
||||
assert_eq!(is_zero, true);
|
||||
assert_eq!(is_carry, true);
|
||||
assert_eq!(affected_flags, [Negative(false), Zero(true), Carry(true)]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user