mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
fix substraction issue
This commit is contained in:
@@ -147,6 +147,25 @@ mod cpu_instructions_tests {
|
||||
assert_eq!(registers.pc, 0x02);
|
||||
assert_eq!(registers.cycles, 2);
|
||||
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]
|
||||
|
||||
@@ -106,6 +106,7 @@ mod cpu_instructions_tests {
|
||||
registers.pc = 0x0000;
|
||||
registers.set_16bit_mode(false);
|
||||
registers.set_overflow_flag(false);
|
||||
registers.set_carry_flag(true);
|
||||
bus.write(0x000001, 0xB0);
|
||||
let instruction = CMP16{addressing_mode: AddressingMode::Immediate};
|
||||
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) {
|
||||
let (_, affected_flags) = alu::sbc_bin(target, value, false);
|
||||
let (_, affected_flags) = alu::sbc_bin(target, value, true);
|
||||
for flag in affected_flags {
|
||||
match flag {
|
||||
Flags::Overflow(_) => {},
|
||||
_ => registers.set_flags(&[flag]),
|
||||
Flags::Negative(_) |
|
||||
Flags::Zero(_) |
|
||||
Flags::Carry(_) => registers.set_flags(&[flag]),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
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 {
|
||||
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 {
|
||||
match flag {
|
||||
Flags::Negative(_) | Flags::Zero(_) => registers.set_flags(&[flag]),
|
||||
|
||||
@@ -139,7 +139,8 @@ mod cpu_instructions_tests {
|
||||
registers.a = 0x0040;
|
||||
registers.pbr = 0x00;
|
||||
registers.pc = 0x0000;
|
||||
registers.set_memory_select_flag(true);
|
||||
registers.set_16bit_mode(false);
|
||||
registers.set_carry_flag(true);
|
||||
bus.write(0x000001, 0x40);
|
||||
let instruction = SBC8BIN{addressing_mode: AddressingMode::Immediate};
|
||||
instruction.execute(&mut registers, &mut bus);
|
||||
@@ -148,6 +149,25 @@ mod cpu_instructions_tests {
|
||||
assert_eq!(registers.cycles, 2);
|
||||
assert!(registers.get_zero_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]
|
||||
@@ -159,6 +179,7 @@ mod cpu_instructions_tests {
|
||||
registers.pbr = 0x00;
|
||||
registers.pc = 0x0000;
|
||||
registers.set_memory_select_flag(false);
|
||||
registers.set_carry_flag(true);
|
||||
bus.write(0x000001, 0x00);
|
||||
bus.write(0x000002, 0x40);
|
||||
let instruction = SBC16BIN{addressing_mode: AddressingMode::Immediate};
|
||||
|
||||
@@ -58,9 +58,6 @@ impl InternalRegisters {
|
||||
|
||||
fn read_vblank_nmi_mut(&self, ppu_registers: &mut PPURegisters) -> u8 {
|
||||
let result = self.read_vblank_nmi(ppu_registers);
|
||||
if result == 0x80 {
|
||||
println!("nmi set");
|
||||
}
|
||||
// When register is read, bit 7 is cleared
|
||||
ppu_registers.vblank_nmi = false;
|
||||
result
|
||||
|
||||
@@ -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]) {
|
||||
let result = target.sbc_snes(value, carry);
|
||||
let result = target.sbc_snes(value, !carry);
|
||||
(result, [
|
||||
Negative(result.is_negative()),
|
||||
Overflow(target.is_overflow(value, result)),
|
||||
Zero(result.is_zero()),
|
||||
Carry(target.sbc_will_carry(value, carry)),
|
||||
Carry(!carry),
|
||||
])
|
||||
}
|
||||
|
||||
@@ -274,33 +274,33 @@ mod alu_tests {
|
||||
#[test]
|
||||
fn test_dec_bin() {
|
||||
// 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!(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!(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!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]);
|
||||
|
||||
// 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!(affected_flags, [Negative(true), Overflow(false), Zero(false), Carry(true)]);
|
||||
|
||||
// 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!(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!(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!(affected_flags, [Negative(true), Overflow(true), Zero(false), Carry(true)]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user