mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
Get value from address mode
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use crate::bus::Bus;
|
||||
/// NOTE: These functions only return the `address` in BUS of where the actual value is stored.
|
||||
|
||||
/// OPCODE #const
|
||||
pub fn immediate(pc_addr: u32) -> u32 {
|
||||
@@ -87,6 +86,55 @@ pub fn stack_relative_indirect_indexed(bus: &Bus, pc_addr: u32, stack_pointer: u
|
||||
absolute_indexed(bus, pc_addr, stack_pointer) + (xy as u32)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum AddressingMode {
|
||||
Immediate,
|
||||
Absolute,
|
||||
AbsoluteLong,
|
||||
DirectPage,
|
||||
DirectPageIndirect,
|
||||
DirectPageIndirectLong,
|
||||
AbsoluteIndexed,
|
||||
AbsoluteLongIndexed,
|
||||
DirectPageIndexed,
|
||||
DirectPageIndexedIndirect,
|
||||
DirectPageIndirectIndexed,
|
||||
DirectPageIndirectLongIndexed,
|
||||
StackRelative,
|
||||
StackRelativeIndirectIndexed,
|
||||
}
|
||||
|
||||
impl AddressingMode {
|
||||
pub fn effective_address(self, bus: &Bus, pc_addr: u32, direct_page_register: u16, stack_pointer: u16, xy: u16) -> u32 {
|
||||
match self {
|
||||
AddressingMode::Immediate => immediate(pc_addr),
|
||||
AddressingMode::Absolute => absolute(bus, pc_addr),
|
||||
AddressingMode::AbsoluteLong => absolute_long(bus, pc_addr),
|
||||
AddressingMode::DirectPage => direct_page(bus, pc_addr, direct_page_register),
|
||||
AddressingMode::DirectPageIndirect => direct_page_indirect(bus, pc_addr, direct_page_register),
|
||||
AddressingMode::DirectPageIndirectLong => direct_page_indirect_long(bus, pc_addr, direct_page_register),
|
||||
AddressingMode::AbsoluteIndexed => absolute_indexed(bus, pc_addr, xy),
|
||||
AddressingMode::AbsoluteLongIndexed => absolute_long_indexed(bus, pc_addr, xy),
|
||||
AddressingMode::DirectPageIndexed => direct_page_indexed(bus, pc_addr, direct_page_register, xy),
|
||||
AddressingMode::DirectPageIndexedIndirect => direct_page_indexed_indirect(bus, pc_addr, direct_page_register, xy),
|
||||
AddressingMode::DirectPageIndirectIndexed => direct_page_indirect_indexed(bus, pc_addr, direct_page_register, xy),
|
||||
AddressingMode::DirectPageIndirectLongIndexed => direct_page_indirect_long_indexed(bus, pc_addr, direct_page_register, xy),
|
||||
AddressingMode::StackRelative => stack_relative(bus, pc_addr, stack_pointer),
|
||||
AddressingMode::StackRelativeIndirectIndexed => stack_relative_indirect_indexed(bus, pc_addr, stack_pointer, xy),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value_8bit(self, bus: &Bus, pc_addr: u32, direct_page_register: u16, stack_pointer: u16, xy: u16) -> u8 {
|
||||
let address = self.effective_address(bus, pc_addr, direct_page_register, stack_pointer, xy);
|
||||
return bus.read(address);
|
||||
}
|
||||
|
||||
pub fn value_16bit(self, bus: &Bus, pc_addr: u32, direct_page_register: u16, stack_pointer: u16, xy: u16) -> u16 {
|
||||
let address = self.effective_address(bus, pc_addr, direct_page_register, stack_pointer, xy);
|
||||
return (bus.read(address) as u16) | ((bus.read(address + 1) as u16) << 8);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod addressing_modes_tests {
|
||||
use super::*;
|
||||
@@ -333,4 +381,24 @@ mod addressing_modes_tests {
|
||||
bus.write(pc_addr + 2, 0x02);
|
||||
assert_eq!(stack_relative_indirect_indexed(&bus, pc_addr, 0x02, 0x02), 0x7F0205);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_address_value() {
|
||||
let mut bus = Bus::new();
|
||||
let pc_addr = 0x000000;
|
||||
bus.write(pc_addr + 1, 0x20);
|
||||
bus.write(pc_addr + 2, 0x10);
|
||||
bus.write(0x001020, 0xFE);
|
||||
let val = AddressingMode::Absolute.value_8bit(&bus, pc_addr, 0x00, 0x00, 0x00);
|
||||
assert_eq!(val, 0xFE);
|
||||
|
||||
let mut bus = Bus::new();
|
||||
let pc_addr = 0x000000;
|
||||
bus.write(pc_addr + 1, 0x20);
|
||||
bus.write(pc_addr + 2, 0x10);
|
||||
bus.write(0x001020, 0xFF);
|
||||
bus.write(0x001021, 0xEE);
|
||||
let val = AddressingMode::Absolute.value_16bit(&bus, pc_addr, 0x00, 0x00, 0x00);
|
||||
assert_eq!(val, 0xEEFF);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user