fix substraction issue

This commit is contained in:
2024-01-21 22:29:07 -05:00
parent bdc24dcf24
commit 0b5b24050f
7 changed files with 57 additions and 17 deletions
+19
View File
@@ -147,6 +147,25 @@ mod cpu_instructions_tests {
assert_eq!(registers.pc, 0x02); assert_eq!(registers.pc, 0x02);
assert_eq!(registers.cycles, 2); assert_eq!(registers.cycles, 2);
assert!(!registers.get_carry_flag()); assert!(!registers.get_carry_flag());
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.a = 0x007F;
registers.pbr = 0x00;
registers.pc = 0x0000;
registers.set_16bit_mode(false);
registers.set_carry_flag(true);
bus.write(0x000001, 0x7F);
let instruction = ADC8BIN{addressing_mode: AddressingMode::Immediate};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0xFF);
assert_eq!(registers.pc, 0x02);
assert_eq!(registers.cycles, 2);
assert!(registers.get_negative_flag());
assert!(registers.get_overflow_flag());
assert!(!registers.get_zero_flag());
assert!(!registers.get_carry_flag());
} }
#[test] #[test]
+1
View File
@@ -106,6 +106,7 @@ mod cpu_instructions_tests {
registers.pc = 0x0000; registers.pc = 0x0000;
registers.set_16bit_mode(false); registers.set_16bit_mode(false);
registers.set_overflow_flag(false); registers.set_overflow_flag(false);
registers.set_carry_flag(true);
bus.write(0x000001, 0xB0); bus.write(0x000001, 0xB0);
let instruction = CMP16{addressing_mode: AddressingMode::Immediate}; let instruction = CMP16{addressing_mode: AddressingMode::Immediate};
instruction.execute(&mut registers, &mut bus); instruction.execute(&mut registers, &mut bus);
@@ -2,11 +2,13 @@ use crate::{cpu::registers::Registers, utils::{num_trait::SnesNum, alu}, common:
pub fn do_comp<T: SnesNum>(registers: &mut Registers, target: T, value: T) { pub fn do_comp<T: SnesNum>(registers: &mut Registers, target: T, value: T) {
let (_, affected_flags) = alu::sbc_bin(target, value, false); let (_, affected_flags) = alu::sbc_bin(target, value, true);
for flag in affected_flags { for flag in affected_flags {
match flag { match flag {
Flags::Overflow(_) => {}, Flags::Negative(_) |
_ => registers.set_flags(&[flag]), Flags::Zero(_) |
Flags::Carry(_) => registers.set_flags(&[flag]),
_ => {},
} }
} }
} }
+1 -1
View File
@@ -1,7 +1,7 @@
use crate::{cpu::registers::Registers, utils::{num_trait::SnesNum, alu}, common::flags::Flags}; use crate::{cpu::registers::Registers, utils::{num_trait::SnesNum, alu}, common::flags::Flags};
pub fn do_dec<T: SnesNum>(registers: &mut Registers, target: T) -> T { pub fn do_dec<T: SnesNum>(registers: &mut Registers, target: T) -> T {
let (result, affected_flags) = alu::sbc_bin(target, T::from_u32(1), false); let (result, affected_flags) = alu::sbc_bin(target, T::from_u32(1), true);
for flag in affected_flags { for flag in affected_flags {
match flag { match flag {
Flags::Negative(_) | Flags::Zero(_) => registers.set_flags(&[flag]), Flags::Negative(_) | Flags::Zero(_) => registers.set_flags(&[flag]),
+22 -1
View File
@@ -139,7 +139,8 @@ mod cpu_instructions_tests {
registers.a = 0x0040; registers.a = 0x0040;
registers.pbr = 0x00; registers.pbr = 0x00;
registers.pc = 0x0000; registers.pc = 0x0000;
registers.set_memory_select_flag(true); registers.set_16bit_mode(false);
registers.set_carry_flag(true);
bus.write(0x000001, 0x40); bus.write(0x000001, 0x40);
let instruction = SBC8BIN{addressing_mode: AddressingMode::Immediate}; let instruction = SBC8BIN{addressing_mode: AddressingMode::Immediate};
instruction.execute(&mut registers, &mut bus); instruction.execute(&mut registers, &mut bus);
@@ -148,6 +149,25 @@ mod cpu_instructions_tests {
assert_eq!(registers.cycles, 2); assert_eq!(registers.cycles, 2);
assert!(registers.get_zero_flag()); assert!(registers.get_zero_flag());
assert!(!registers.get_carry_flag()); assert!(!registers.get_carry_flag());
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.a = 0x007F;
registers.pbr = 0x00;
registers.pc = 0x0000;
registers.set_16bit_mode(false);
registers.set_carry_flag(false);
bus.write(0x000001, 0x7E);
let instruction = SBC8BIN{addressing_mode: AddressingMode::Immediate};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0x00);
assert_eq!(registers.pc, 0x02);
assert_eq!(registers.cycles, 2);
assert!(!registers.get_negative_flag());
assert!(!registers.get_overflow_flag());
assert!(registers.get_zero_flag());
assert!(registers.get_carry_flag());
} }
#[test] #[test]
@@ -159,6 +179,7 @@ mod cpu_instructions_tests {
registers.pbr = 0x00; registers.pbr = 0x00;
registers.pc = 0x0000; registers.pc = 0x0000;
registers.set_memory_select_flag(false); registers.set_memory_select_flag(false);
registers.set_carry_flag(true);
bus.write(0x000001, 0x00); bus.write(0x000001, 0x00);
bus.write(0x000002, 0x40); bus.write(0x000002, 0x40);
let instruction = SBC16BIN{addressing_mode: AddressingMode::Immediate}; let instruction = SBC16BIN{addressing_mode: AddressingMode::Immediate};
-3
View File
@@ -58,9 +58,6 @@ impl InternalRegisters {
fn read_vblank_nmi_mut(&self, ppu_registers: &mut PPURegisters) -> u8 { fn read_vblank_nmi_mut(&self, ppu_registers: &mut PPURegisters) -> u8 {
let result = self.read_vblank_nmi(ppu_registers); let result = self.read_vblank_nmi(ppu_registers);
if result == 0x80 {
println!("nmi set");
}
// When register is read, bit 7 is cleared // When register is read, bit 7 is cleared
ppu_registers.vblank_nmi = false; ppu_registers.vblank_nmi = false;
result result
+9 -9
View File
@@ -49,12 +49,12 @@ pub fn adc_bcd<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4])
} }
pub fn sbc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4]) { pub fn sbc_bin<T: SnesNum>(target: T, value: T, carry: bool) -> (T, [Flags; 4]) {
let result = target.sbc_snes(value, carry); let result = target.sbc_snes(value, !carry);
(result, [ (result, [
Negative(result.is_negative()), Negative(result.is_negative()),
Overflow(target.is_overflow(value, result)), Overflow(target.is_overflow(value, result)),
Zero(result.is_zero()), Zero(result.is_zero()),
Carry(target.sbc_will_carry(value, carry)), Carry(!carry),
]) ])
} }
@@ -274,33 +274,33 @@ mod alu_tests {
#[test] #[test]
fn test_dec_bin() { fn test_dec_bin() {
// 8 bit // 8 bit
let (result, affected_flags) = sbc_bin(1_u8, 1_u8, false); let (result, affected_flags) = sbc_bin(1_u8, 1_u8, true);
assert_eq!(result, 0); assert_eq!(result, 0);
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]); assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
let (result, affected_flags) = sbc_bin(0_u8, 1_u8, false); let (result, affected_flags) = sbc_bin(0_u8, 1_u8, true);
assert_eq!(result, 0b11111111); assert_eq!(result, 0b11111111);
assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]); assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]);
let (result, affected_flags) = sbc_bin(0_u8, 1_u8, true); let (result, affected_flags) = sbc_bin(0_u8, 1_u8, false);
assert_eq!(result, 0b11111110); assert_eq!(result, 0b11111110);
assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]); assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]);
// overflow // overflow
let (result, affected_flags) = sbc_bin(0x50_u8, 0xB0_u8, false); let (result, affected_flags) = sbc_bin(0x50_u8, 0xB0_u8, true);
assert_eq!(result, 0xA0); assert_eq!(result, 0xA0);
assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]); assert_eq!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]);
// 16 bit // 16 bit
let (result, affected_flags) = sbc_bin(1_u16, 1_u16, false); let (result, affected_flags) = sbc_bin(1_u16, 1_u16, true);
assert_eq!(result, 0); assert_eq!(result, 0);
assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]); assert_eq!(affected_flags, [Negative(false), Overflow(false), Zero(true), Carry(false)]);
let (result, affected_flags) = sbc_bin(0_u16, 1_u16, false); let (result, affected_flags) = sbc_bin(0_u16, 1_u16, true);
assert_eq!(result, 0b11111111_11111111); assert_eq!(result, 0b11111111_11111111);
assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]); assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]);
let (result, affected_flags) = sbc_bin(0_u16, 1_u16, true); let (result, affected_flags) = sbc_bin(0_u16, 1_u16, false);
assert_eq!(result, 0b11111111_11111110); assert_eq!(result, 0b11111111_11111110);
assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]); assert_eq!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]);
} }