diff --git a/snes-core/src/cpu/cycles.rs b/snes-core/src/cpu/cycles.rs index 2e41b86..6fd9fe6 100644 --- a/snes-core/src/cpu/cycles.rs +++ b/snes-core/src/cpu/cycles.rs @@ -96,7 +96,7 @@ fn common_conditions(cpu_registers: &Registers, addressing_mode: AddressingMode, }, // Add 1 byte if = 0 (16-bit index registers) Condition::IndexIs16Bit => { - if cpu_registers.is_16bit_index() { + if addressing_mode == AddressingMode::Immediate && cpu_registers.is_16bit_index() { bytes += 1; cycles += 1; } }, diff --git a/snes-core/src/cpu/instructions/lda.rs b/snes-core/src/cpu/instructions/lda.rs index ed1a55a..86c9f7a 100644 --- a/snes-core/src/cpu/instructions/lda.rs +++ b/snes-core/src/cpu/instructions/lda.rs @@ -4,7 +4,7 @@ use crate::cpu::{bus::Bus, registers::Registers}; use crate::utils::addressing::AddressingMode; use super::read_write_common::{read_8bit_from_address, read_16bit_from_address}; -use super::{CPUInstruction, bit_common}; +use super::CPUInstruction; use super::decoder_common; static INSTR_NAME: &str = "LDA"; @@ -41,12 +41,11 @@ pub struct LDA8 { impl CPUInstruction for LDA8 { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { let value = read_8bit_from_address(registers, bus, self.addressing_mode); + registers.set_low_a(value); registers.set_flags(&[ Flags::Negative(value >> 7 == 1), Flags::Zero(value == 0), ]); - registers.set_low_a(value); - bit_common::do_bit(registers, registers.a as u8, value, self.addressing_mode); let (bytes, cycles) = cycles::increment_cycles_lda(registers, self.addressing_mode); registers.increment_pc(bytes); registers.cycles += cycles; } diff --git a/snes-core/src/cpu/instructions/ldx.rs b/snes-core/src/cpu/instructions/ldx.rs index 6365315..0955a78 100644 --- a/snes-core/src/cpu/instructions/ldx.rs +++ b/snes-core/src/cpu/instructions/ldx.rs @@ -4,7 +4,7 @@ use crate::cpu::{bus::Bus, registers::Registers}; use crate::utils::addressing::AddressingMode; use super::read_write_common::{read_8bit_from_address, read_16bit_from_address}; -use super::{CPUInstruction, bit_common}; +use super::CPUInstruction; use super::decoder_common; static INSTR_NAME: &str = "LDX"; @@ -41,12 +41,11 @@ pub struct LDX8 { impl CPUInstruction for LDX8 { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { let value = read_8bit_from_address(registers, bus, self.addressing_mode); + registers.set_low_x(value); registers.set_flags(&[ Flags::Negative(value >> 7 == 1), Flags::Zero(value == 0), ]); - registers.set_low_x(value); - bit_common::do_bit(registers, registers.x as u8, value, self.addressing_mode); let (bytes, cycles) = cycles::increment_cycles_ld_index(registers, self.addressing_mode); registers.increment_pc(bytes); registers.cycles += cycles; } diff --git a/snes-core/src/cpu/instructions/ldy.rs b/snes-core/src/cpu/instructions/ldy.rs index a5365a7..8414997 100644 --- a/snes-core/src/cpu/instructions/ldy.rs +++ b/snes-core/src/cpu/instructions/ldy.rs @@ -4,7 +4,7 @@ use crate::cpu::{bus::Bus, registers::Registers}; use crate::utils::addressing::AddressingMode; use super::read_write_common::{read_8bit_from_address, read_16bit_from_address}; -use super::{CPUInstruction, bit_common}; +use super::CPUInstruction; use super::decoder_common; static INSTR_NAME: &str = "LDY"; @@ -41,12 +41,11 @@ pub struct LDY8 { impl CPUInstruction for LDY8 { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { let value = read_8bit_from_address(registers, bus, self.addressing_mode); + registers.set_low_y(value); registers.set_flags(&[ Flags::Negative(value >> 7 == 1), Flags::Zero(value == 0), ]); - registers.set_low_y(value); - bit_common::do_bit(registers, registers.y as u8, value, self.addressing_mode); let (bytes, cycles) = cycles::increment_cycles_ld_index(registers, self.addressing_mode); registers.increment_pc(bytes); registers.cycles += cycles; } diff --git a/snes-core/src/cpu/instructions/mapper.rs b/snes-core/src/cpu/instructions/mapper.rs index 89ed58f..0c3a895 100644 --- a/snes-core/src/cpu/instructions/mapper.rs +++ b/snes-core/src/cpu/instructions/mapper.rs @@ -178,8 +178,8 @@ pub fn map_opcode_to_instruction(opcode: u8) -> Box { 0xA0 => Box::new(LDY{addressing_mode: A::Immediate}), 0xAC => Box::new(LDY{addressing_mode: A::Absolute}), 0xA4 => Box::new(LDY{addressing_mode: A::DirectPage}), - 0xB4 => Box::new(LDY{addressing_mode: A::AbsoluteIndexed(I::Y)}), - 0xBC => Box::new(LDY{addressing_mode: A::DirectPageIndexed(I::Y)}), + 0xBC => Box::new(LDY{addressing_mode: A::AbsoluteIndexed(I::X)}), + 0xB4 => Box::new(LDY{addressing_mode: A::DirectPageIndexed(I::X)}), // LSR 0x4A => Box::new(LSR{addressing_mode: A::Accumulator}), 0x4E => Box::new(LSR{addressing_mode: A::Absolute}), diff --git a/snes-core/src/rom/special_ram_cart.rs b/snes-core/src/rom/special_ram_cart.rs index 8b42ed9..d526e33 100644 --- a/snes-core/src/rom/special_ram_cart.rs +++ b/snes-core/src/rom/special_ram_cart.rs @@ -7,7 +7,7 @@ pub struct SpecialRAMCart { impl SpecialRAMCart { pub fn new() -> Self { Self { - data: vec![0x00; 0x1000000], + data: vec![0x00; 0x100000000], } } } diff --git a/snes-core/src/utils/addressing.rs b/snes-core/src/utils/addressing.rs index 905793e..c1b0aeb 100644 --- a/snes-core/src/utils/addressing.rs +++ b/snes-core/src/utils/addressing.rs @@ -21,7 +21,12 @@ pub fn immediate(pc_addr: u32) -> u32 { /// OPCODE addr pub fn absolute(bus: &mut Bus, pc_addr: u32, dbr: u8) -> u32 { - let addr = (bus.read(pc_addr + 1) as u32) | ((bus.read(pc_addr + 2) as u32) << 8); + let pbr = pc_addr & 0xFF0000; + let bus_addr_1 = pbr | ((pc_addr as u16).wrapping_add(1) as u32); + let bus_addr_2 = pbr | ((pc_addr as u16).wrapping_add(2) as u32); + let addr = + (bus.read(bus_addr_1) as u32) | + ((bus.read(bus_addr_2) as u32) << 8); ((dbr as u32) << 16) | addr } @@ -49,7 +54,9 @@ pub fn absolute_indirect_long(bus: &mut Bus, pc_addr: u32, dbr: u8) -> u32 { /// OPCODE dp pub fn direct_page(bus: &mut Bus, pc_addr: u32, direct_page_register: u16) -> u32 { - (bus.read(pc_addr + 1) as u16).wrapping_add(direct_page_register) as u32 + let pbr = pc_addr & 0xFF0000; + let bus_addr = pbr | ((pc_addr as u16).wrapping_add(1) as u32); + (bus.read(bus_addr) as u16).wrapping_add(direct_page_register) as u32 } /// OPCODE (dp) @@ -142,7 +149,7 @@ impl Display for IndexRegister { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] pub enum AddressingMode { Accumulator, Immediate,