mirror of
https://github.com/FranLMSP/snes.git
synced 2026-10-03 16:05:18 -04:00
condition for adding cycle to indexed addressing modes
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
use super::cpu::CPU;
|
use super::cpu::CPU;
|
||||||
use crate::utils::addressing::{AddressingMode};
|
use crate::utils::addressing::{AddressingMode, IndexRegister};
|
||||||
|
|
||||||
|
|
||||||
impl CPU {
|
impl CPU {
|
||||||
pub fn increment_cycles_adc_sbc(&mut self, addressing_mode: AddressingMode) {
|
pub fn increment_cycles_adc_sbc(&mut self, addressing_mode: AddressingMode) {
|
||||||
type A = AddressingMode;
|
type A = AddressingMode;
|
||||||
|
type I = IndexRegister;
|
||||||
let (mut bytes, mut cycles) = match addressing_mode {
|
let (mut bytes, mut cycles) = match addressing_mode {
|
||||||
A::Immediate => (2, 2),
|
A::Immediate => (2, 2),
|
||||||
A::Absolute => (3, 4),
|
A::Absolute => (3, 4),
|
||||||
@@ -41,9 +42,16 @@ impl CPU {
|
|||||||
|
|
||||||
// condition 3: Add 1 cycle if adding index crosses a page boundary
|
// condition 3: Add 1 cycle if adding index crosses a page boundary
|
||||||
match addressing_mode {
|
match addressing_mode {
|
||||||
A::AbsoluteIndexed(_) | A::DirectPageIndirectIndexed(_) => {
|
A::AbsoluteIndexed(index) | A::DirectPageIndirectIndexed(index) => {
|
||||||
todo!("Check if index crosses a page boundary")
|
let page = (self.registers.get_pc_address() - (bytes as u32)) & 0xFF;
|
||||||
}
|
let index = match index {
|
||||||
|
I::X => self.registers.x,
|
||||||
|
I::Y => self.registers.y,
|
||||||
|
};
|
||||||
|
if (page + index as u32) > 0xFF {
|
||||||
|
cycles += 1
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,6 +72,8 @@ mod cpu_instructions_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_increment_cycles_adc_sbc() {
|
fn test_increment_cycles_adc_sbc() {
|
||||||
let mut cpu = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
|
// 16-bit Memory/accumulator flag condition
|
||||||
cpu.registers.pc = 0;
|
cpu.registers.pc = 0;
|
||||||
cpu.cycles = 0;
|
cpu.cycles = 0;
|
||||||
cpu.registers.set_decimal_mode_flag(false);
|
cpu.registers.set_decimal_mode_flag(false);
|
||||||
@@ -79,6 +89,7 @@ mod cpu_instructions_tests {
|
|||||||
assert_eq!(cpu.registers.pc, 3);
|
assert_eq!(cpu.registers.pc, 3);
|
||||||
assert_eq!(cpu.cycles, 3);
|
assert_eq!(cpu.cycles, 3);
|
||||||
|
|
||||||
|
// Decimal flag condition
|
||||||
cpu.registers.pc = 0;
|
cpu.registers.pc = 0;
|
||||||
cpu.cycles = 0;
|
cpu.cycles = 0;
|
||||||
cpu.registers.set_16bit_mode(true);
|
cpu.registers.set_16bit_mode(true);
|
||||||
@@ -87,10 +98,12 @@ mod cpu_instructions_tests {
|
|||||||
assert_eq!(cpu.registers.pc, 3);
|
assert_eq!(cpu.registers.pc, 3);
|
||||||
assert_eq!(cpu.cycles, 4);
|
assert_eq!(cpu.cycles, 4);
|
||||||
|
|
||||||
|
// Low byte of direct page register other than zero condition
|
||||||
cpu.registers.pc = 0;
|
cpu.registers.pc = 0;
|
||||||
cpu.cycles = 0;
|
cpu.cycles = 0;
|
||||||
cpu.registers.set_16bit_mode(false);
|
cpu.registers.set_16bit_mode(false);
|
||||||
cpu.registers.set_decimal_mode_flag(false);
|
cpu.registers.set_decimal_mode_flag(false);
|
||||||
|
cpu.registers.d = 0x0000;
|
||||||
cpu.increment_cycles_adc_sbc(AddressingMode::DirectPage);
|
cpu.increment_cycles_adc_sbc(AddressingMode::DirectPage);
|
||||||
assert_eq!(cpu.registers.pc, 2);
|
assert_eq!(cpu.registers.pc, 2);
|
||||||
assert_eq!(cpu.cycles, 3);
|
assert_eq!(cpu.cycles, 3);
|
||||||
@@ -103,5 +116,24 @@ mod cpu_instructions_tests {
|
|||||||
cpu.increment_cycles_adc_sbc(AddressingMode::DirectPage);
|
cpu.increment_cycles_adc_sbc(AddressingMode::DirectPage);
|
||||||
assert_eq!(cpu.registers.pc, 2);
|
assert_eq!(cpu.registers.pc, 2);
|
||||||
assert_eq!(cpu.cycles, 4);
|
assert_eq!(cpu.cycles, 4);
|
||||||
|
|
||||||
|
// Adding index crosses a page boundary condition
|
||||||
|
cpu.registers.pc = 0xFE;
|
||||||
|
cpu.registers.x = 0x0001;
|
||||||
|
cpu.cycles = 0;
|
||||||
|
cpu.registers.set_16bit_mode(false);
|
||||||
|
cpu.registers.set_decimal_mode_flag(false);
|
||||||
|
cpu.increment_cycles_adc_sbc(AddressingMode::AbsoluteIndexed(IndexRegister::X));
|
||||||
|
assert_eq!(cpu.registers.pc, 0xFE + 3);
|
||||||
|
assert_eq!(cpu.cycles, 4);
|
||||||
|
|
||||||
|
cpu.registers.pc = 0xFE;
|
||||||
|
cpu.registers.x = 0x0010;
|
||||||
|
cpu.cycles = 0;
|
||||||
|
cpu.registers.set_16bit_mode(false);
|
||||||
|
cpu.registers.set_decimal_mode_flag(false);
|
||||||
|
cpu.increment_cycles_adc_sbc(AddressingMode::AbsoluteIndexed(IndexRegister::X));
|
||||||
|
assert_eq!(cpu.registers.pc, 0xFE + 3);
|
||||||
|
assert_eq!(cpu.cycles, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user