mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
set overflow flag for adc and sbc
This commit is contained in:
@@ -34,7 +34,7 @@ impl CPU {
|
||||
match is_8bit {
|
||||
true => {
|
||||
let value = self.get_8bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero) = match is_decimal_mode {
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
true => alu::adc8bcd(target as u8, value, carry_flag),
|
||||
false => alu::adc_bin(target as u8, value, carry_flag),
|
||||
};
|
||||
@@ -42,10 +42,11 @@ impl CPU {
|
||||
self.registers.set_carry_flag(is_carry);
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_overflow_flag(is_overflow);
|
||||
},
|
||||
false => {
|
||||
let value = self.get_16bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero) = match is_decimal_mode {
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
true => alu::adc16bcd(target, value, carry_flag),
|
||||
false => alu::adc_bin(target, value, carry_flag),
|
||||
};
|
||||
@@ -53,6 +54,7 @@ impl CPU {
|
||||
self.registers.set_carry_flag(is_carry);
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_overflow_flag(is_overflow);
|
||||
}
|
||||
};
|
||||
self.increment_cycles_arithmetic(addressing_mode);
|
||||
@@ -68,7 +70,7 @@ impl CPU {
|
||||
match is_8bit {
|
||||
true => {
|
||||
let value = self.get_8bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero) = match is_decimal_mode {
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
true => alu::sbc8bcd(target as u8, value, carry_flag),
|
||||
false => alu::sbc_bin(target as u8, value, carry_flag),
|
||||
};
|
||||
@@ -76,10 +78,11 @@ impl CPU {
|
||||
self.registers.set_carry_flag(is_carry);
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_overflow_flag(is_overflow);
|
||||
},
|
||||
false => {
|
||||
let value = self.get_16bit_from_address(bus, addressing_mode);
|
||||
let (result, is_carry, is_negative, is_zero) = match is_decimal_mode {
|
||||
let (result, is_carry, is_negative, is_zero, is_overflow) = match is_decimal_mode {
|
||||
true => alu::sbc16bcd(target, value, carry_flag),
|
||||
false => alu::sbc_bin(target, value, carry_flag),
|
||||
};
|
||||
@@ -87,6 +90,7 @@ impl CPU {
|
||||
self.registers.set_carry_flag(is_carry);
|
||||
self.registers.set_negative_flag(is_negative);
|
||||
self.registers.set_zero_flag(is_zero);
|
||||
self.registers.set_overflow_flag(is_overflow);
|
||||
}
|
||||
};
|
||||
self.increment_cycles_arithmetic(addressing_mode);
|
||||
|
||||
+85
-48
@@ -1,14 +1,15 @@
|
||||
use super::num_trait::SnesNum;
|
||||
|
||||
pub fn adc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool, bool) {
|
||||
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);
|
||||
let result = target.add_snes(value, carry);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
(result, is_carry, is_negative, is_zero)
|
||||
let is_overflow = target.is_overflow(value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
}
|
||||
|
||||
pub fn adc8bcd(target: u8, value: u8, carry: bool) -> (u8, bool, bool, bool) {
|
||||
pub fn adc8bcd(target: u8, value: u8, carry: bool) -> (u8, bool, bool, bool, bool) {
|
||||
let mut is_carry = carry;
|
||||
let mut result = (target & 0xF) + (value & 0xF) + (is_carry as u8);
|
||||
if result > 9 {
|
||||
@@ -21,10 +22,11 @@ pub fn adc8bcd(target: u8, value: u8, carry: bool) -> (u8, bool, bool, bool) {
|
||||
is_carry = result > 0x9F;
|
||||
let is_negative = (result >> 7) == 1;
|
||||
let is_zero = result == 0;
|
||||
(result, is_carry, is_negative, is_zero)
|
||||
let is_overflow = target.is_overflow(value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
}
|
||||
|
||||
pub fn adc16bcd(target: u16, value: u16, carry: bool) -> (u16, bool, bool, bool) {
|
||||
pub fn adc16bcd(target: u16, value: u16, carry: bool) -> (u16, bool, bool, bool, bool) {
|
||||
let mut is_carry = carry;
|
||||
let mut result = (target & 0xF) + (value & 0xF) + (is_carry as u16);
|
||||
if result > 9 {
|
||||
@@ -41,18 +43,19 @@ pub fn adc16bcd(target: u16, value: u16, carry: bool) -> (u16, bool, bool, bool)
|
||||
is_carry = result > 0x9FFF;
|
||||
let is_negative = (result >> 15) == 1;
|
||||
let is_zero = result == 0;
|
||||
(result, is_carry, is_negative, is_zero)
|
||||
(result, is_carry, is_negative, is_zero, false) // TODO: return overflow
|
||||
}
|
||||
|
||||
pub fn sbc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, bool, bool, bool) {
|
||||
let is_carry = target.sub_will_carry(value, carry);
|
||||
let result = target.sub_snes(value, 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);
|
||||
let result = target.sbc_snes(value, carry);
|
||||
let is_negative = result.is_negative();
|
||||
let is_zero = result.is_zero();
|
||||
(result, is_carry, is_negative, is_zero)
|
||||
let is_overflow = target.is_overflow(value, result);
|
||||
(result, is_carry, is_negative, is_zero, is_overflow)
|
||||
}
|
||||
|
||||
pub fn sbc8bcd(target: u8, value: u8, carry: bool) -> (u8, bool, bool, bool) {
|
||||
pub fn sbc8bcd(target: u8, value: u8, carry: bool) -> (u8, bool, bool, bool, bool) {
|
||||
let mut is_carry = carry;
|
||||
let target = target as u16;
|
||||
let value = !(value as u16);
|
||||
@@ -69,10 +72,10 @@ pub fn sbc8bcd(target: u8, value: u8, carry: bool) -> (u8, bool, bool, bool) {
|
||||
let result = result as u8;
|
||||
let is_negative = (result >> 7) == 1;
|
||||
let is_zero = result == 0;
|
||||
(result, is_carry, is_negative, is_zero)
|
||||
(result, is_carry, is_negative, is_zero, false) // TODO: return overflow
|
||||
}
|
||||
|
||||
pub fn sbc16bcd(target: u16, value: u16, carry: bool) -> (u16, bool, bool, bool) {
|
||||
pub fn sbc16bcd(target: u16, value: u16, carry: bool) -> (u16, bool, bool, bool, bool) {
|
||||
let mut is_carry = carry;
|
||||
let target = target as u32;
|
||||
let value = !(value as u32);
|
||||
@@ -100,7 +103,7 @@ pub fn sbc16bcd(target: u16, value: u16, carry: bool) -> (u16, bool, bool, bool)
|
||||
let result = result as u16;
|
||||
let is_negative = (result >> 15) == 1;
|
||||
let is_zero = result == 0;
|
||||
(result, is_carry, is_negative, is_zero)
|
||||
(result, is_carry, is_negative, is_zero, false) // TODO: return overflow
|
||||
}
|
||||
|
||||
pub fn and<T: SnesNum>(target: T, value: T) -> (T, bool, bool) {
|
||||
@@ -125,225 +128,259 @@ mod alu_tests {
|
||||
#[test]
|
||||
fn test_adc_bin() {
|
||||
// 8 bits
|
||||
let (result, carry, negative, zero) = adc_bin(0_u8, 0_u8, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(0_u8, 50_u8, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(200_u8, 155_u8, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(200_u8, 155_u8, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(200_u8, 54_u8, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(200_u8, 54_u8, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
// 16 bits
|
||||
let (result, carry, negative, zero) = adc_bin(0_u16, 0_u16, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(0_u16, 50_u16, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(65530_u16, 10_u16, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(65530_u16, 10_u16, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = adc_bin(65530_u16, 4_u16, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_adc_bcd() {
|
||||
// 8 bits
|
||||
let (result, carry, negative, zero) = adc8bcd(5, 5, false);
|
||||
let (result, carry, negative, zero, overflow) = adc8bcd(5, 5, false);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc8bcd(7, 9, false);
|
||||
let (result, carry, negative, zero, overflow) = adc8bcd(7, 9, false);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc8bcd(5, 4, true);
|
||||
let (result, carry, negative, zero, overflow) = adc8bcd(5, 4, true);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc8bcd(7, 8, true);
|
||||
let (result, carry, negative, zero, overflow) = adc8bcd(7, 8, true);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc8bcd(0, 0, false);
|
||||
let (result, carry, negative, zero, overflow) = adc8bcd(0, 0, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc8bcd(0b0001_1001, 0b0010_1000, false);
|
||||
let (result, carry, negative, zero, overflow) = adc8bcd(0b0001_1001, 0b0010_1000, false);
|
||||
assert_eq!(result, 0b0100_0111);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
// 16 bits
|
||||
let (result, carry, negative, zero) = adc16bcd(5, 5, false);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(5, 5, false);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc16bcd(7, 9, false);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(7, 9, false);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc16bcd(5, 4, true);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(5, 4, true);
|
||||
assert_eq!(result, 0b0001_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc16bcd(7, 8, true);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(7, 8, true);
|
||||
assert_eq!(result, 0b0001_0110);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc16bcd(0, 0, false);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(0, 0, false);
|
||||
assert_eq!(result, 0);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc16bcd(0x0500, 0x0500, false);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(0x0500, 0x0500, false);
|
||||
assert_eq!(result, 0b0001_0000_0000_0000);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = adc16bcd(0b0001_1001, 0b0010_1000, false);
|
||||
let (result, carry, negative, zero, overflow) = adc16bcd(0b0001_1001, 0b0010_1000, false);
|
||||
assert_eq!(result, 0b0100_0111);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dec_bin() {
|
||||
// 8 bit
|
||||
let (result, carry, negative, zero) = sbc_bin(1_u8, 1_u8, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = sbc_bin(0_u8, 1_u8, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = sbc_bin(0_u8, 1_u8, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
// 16 bit
|
||||
let (result, carry, negative, zero) = sbc_bin(1_u16, 1_u16, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = sbc_bin(0_u16, 1_u16, false);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
|
||||
let (result, carry, negative, zero) = sbc_bin(0_u16, 1_u16, true);
|
||||
let (result, carry, negative, zero, overflow) = 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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dec_bcd() {
|
||||
// 8 bit
|
||||
let (result, carry, negative, zero) = sbc8bcd(0x49, 0x48, false);
|
||||
let (result, carry, negative, zero, overflow) = sbc8bcd(0x49, 0x48, false);
|
||||
assert_eq!(result, 0x00);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = sbc8bcd(0x49, 0x50, true);
|
||||
let (result, carry, negative, zero, overflow) = sbc8bcd(0x49, 0x50, true);
|
||||
assert_eq!(result, 0x99);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
// 16 bit
|
||||
let (result, carry, negative, zero) = sbc16bcd(0x4999, 0x4998, false);
|
||||
let (result, carry, negative, zero, overflow) = sbc16bcd(0x4999, 0x4998, false);
|
||||
assert_eq!(result, 0x0000);
|
||||
assert_eq!(carry, true);
|
||||
assert_eq!(negative, false);
|
||||
assert_eq!(zero, true);
|
||||
assert_eq!(overflow, false);
|
||||
|
||||
let (result, carry, negative, zero) = sbc16bcd(0x4999, 0x5000, true);
|
||||
let (result, carry, negative, zero, overflow) = sbc16bcd(0x4999, 0x5000, true);
|
||||
assert_eq!(result, 0x9999);
|
||||
assert_eq!(carry, false);
|
||||
assert_eq!(negative, true);
|
||||
assert_eq!(zero, false);
|
||||
assert_eq!(overflow, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
pub trait SnesNum: Copy + Clone + Sized + Eq + PartialEq {
|
||||
fn add_will_carry(&self, v: Self, carry: bool) -> bool;
|
||||
fn sub_will_carry(&self, v: Self, carry: bool) -> bool;
|
||||
fn sbc_will_carry(&self, v: Self, carry: bool) -> bool;
|
||||
fn is_overflow(&self, v: Self, r: Self) -> bool;
|
||||
fn add_snes(&self, v: Self, carry: bool) -> Self;
|
||||
fn sub_snes(&self, v: Self, carry: bool) -> Self;
|
||||
fn sbc_snes(&self, v: Self, carry: bool) -> Self;
|
||||
fn and(&self, v: Self) -> Self;
|
||||
fn asl(&self) -> Self;
|
||||
fn is_negative(&self) -> bool;
|
||||
@@ -31,14 +32,27 @@ macro_rules! define_operation {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_is_overflow {
|
||||
($t:ty) => {
|
||||
fn is_overflow(&self, v: $t, r: $t) -> bool {
|
||||
let target = (*self).is_negative();
|
||||
let value = v.is_negative();
|
||||
let result = r.is_negative();
|
||||
(target ^ result) && (target ^ value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_impl {
|
||||
($t:ty) => {
|
||||
impl SnesNum for $t {
|
||||
define_will_carry!($t, add_will_carry, checked_add);
|
||||
define_will_carry!($t, sub_will_carry, checked_sub);
|
||||
define_will_carry!($t, sbc_will_carry, checked_sub);
|
||||
|
||||
define_operation!($t, add_snes, wrapping_add);
|
||||
define_operation!($t, sub_snes, wrapping_sub);
|
||||
define_operation!($t, sbc_snes, wrapping_sub);
|
||||
|
||||
define_is_overflow!($t);
|
||||
|
||||
fn and(&self, v: $t) -> $t {
|
||||
(* self) & v
|
||||
|
||||
Reference in New Issue
Block a user