From fdb324686ae09be81bfaa62a762825b5808a9663 Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Sat, 26 Nov 2022 22:02:08 -0500 Subject: [PATCH] alu XOR --- snes-core/src/utils/alu.rs | 30 ++++++++++++++++++++++++++++++ snes-core/src/utils/num_trait.rs | 5 +++++ 2 files changed, 35 insertions(+) diff --git a/snes-core/src/utils/alu.rs b/snes-core/src/utils/alu.rs index a761210..4ecd2b4 100644 --- a/snes-core/src/utils/alu.rs +++ b/snes-core/src/utils/alu.rs @@ -109,6 +109,15 @@ pub fn asl(target: T) -> (T, [Flags; 3]) { ]) } +pub fn xor(target: T, value: T) -> (T, [Flags; 2]) { + let result = target.xor(value); + (result, [ + Negative(result.is_negative()), + Zero(result.is_zero()), + ]) +} + + #[cfg(test)] mod alu_tests { use super::*; @@ -315,4 +324,25 @@ mod alu_tests { assert_eq!(result, 0b00000000_00000000); assert_eq!(affected_flags, [Negative(false), Zero(true), Carry(true)]); } + + #[test] + fn test_xor() { + // 8 bit + let (result, affected_flags) = xor(0b0101_0101_u8, 0b0101_0101_u8); + assert_eq!(result, 0); + assert_eq!(affected_flags, [Negative(false), Zero(true)]); + + let (result, affected_flags) = xor(0b1000_0000_u8, 0b0000_0000_u8); + assert_eq!(result, 0b1000_0000); + assert_eq!(affected_flags, [Negative(true), Zero(false)]); + + // 16 bit + let (result, affected_flags) = xor(0b01010101_00000000_u16, 0b01010101_00000000_u16); + assert_eq!(result, 0); + assert_eq!(affected_flags, [Negative(false), Zero(true)]); + + let (result, affected_flags) = xor(0b10000000_00000000_u16, 0b00000000_00000000_u16); + assert_eq!(result, 0b10000000_00000000); + assert_eq!(affected_flags, [Negative(true), Zero(false)]); + } } diff --git a/snes-core/src/utils/num_trait.rs b/snes-core/src/utils/num_trait.rs index 6e5c05e..f8dfa51 100644 --- a/snes-core/src/utils/num_trait.rs +++ b/snes-core/src/utils/num_trait.rs @@ -6,6 +6,7 @@ pub trait SnesNum: Copy + Clone + Sized + Eq + PartialEq { fn sbc_snes(&self, v: Self, carry: bool) -> Self; fn and(&self, v: Self) -> Self; fn asl(&self) -> Self; + fn xor(&self, v: Self) -> Self; fn is_negative(&self) -> bool; fn is_zero(&self) -> bool; fn next_to_highest_bit(&self) -> bool; @@ -67,6 +68,10 @@ macro_rules! define_impl { (* self) << 1 } + fn xor(&self, v: $t) -> $t { + (* self) ^ v + } + fn is_negative(&self) -> bool { (*self) & !(<$t>::MAX >> 1) != 0 }