Fix direct page addressing modes

This commit is contained in:
2024-01-28 19:01:39 -05:00
parent b9699e6276
commit 22b537546c
+21 -22
View File
@@ -49,22 +49,21 @@ pub fn absolute_indirect_long(bus: &mut Bus, pc_addr: u32, dbr: u8) -> u32 {
/// OPCODE dp /// OPCODE dp
pub fn direct_page(bus: &mut Bus, pc_addr: u32, direct_page_register: u16) -> u32 { pub fn direct_page(bus: &mut Bus, pc_addr: u32, direct_page_register: u16) -> u32 {
(bus.read(pc_addr + 1) as u32) + direct_page_register as u32 (bus.read(pc_addr + 1) as u16).wrapping_add(direct_page_register) as u32
} }
/// OPCODE (dp) /// OPCODE (dp)
pub fn direct_page_indirect(bus: &mut Bus, pc_addr: u32, direct_page_register: u16) -> u32 { pub fn direct_page_indirect(bus: &mut Bus, pc_addr: u32, direct_page_register: u16, dbr: u8) -> u32 {
let addr = direct_page(bus, pc_addr, direct_page_register); let addr = direct_page(bus, pc_addr, direct_page_register);
let dbr = pc_addr & 0xFF0000; ((dbr as u32) << 16) | (bus.read(addr) as u32) | ((bus.read(addr + 1) as u32) << 8)
dbr | ((bus.read(addr) as u32) << 8) | (bus.read(addr + 1) as u32)
} }
/// OPCODE [dp] /// OPCODE [dp]
pub fn direct_page_indirect_long(bus: &mut Bus, pc_addr: u32, direct_page_register: u16) -> u32 { pub fn direct_page_indirect_long(bus: &mut Bus, pc_addr: u32, direct_page_register: u16) -> u32 {
let addr = direct_page(bus, pc_addr, direct_page_register); let addr = direct_page(bus, pc_addr, direct_page_register);
((bus.read(addr) as u32) << 16) | (bus.read(addr) as u32) |
((bus.read(addr + 1) as u32) << 8) | ((bus.read(addr + 1) as u32) << 8) |
(bus.read(addr + 2) as u32) ((bus.read(addr + 2) as u32) << 16)
} }
/// OPCODE addr,X /// OPCODE addr,X
@@ -95,14 +94,14 @@ pub fn direct_page_indexed(bus: &mut Bus, pc_addr: u32, direct_page_register: u1
/// OPCODE (dp,X) /// OPCODE (dp,X)
/// OPCODE (dp,Y) /// OPCODE (dp,Y)
pub fn direct_page_indexed_indirect(bus: &mut Bus, pc_addr: u32, direct_page_register: u16, xy: u16) -> u32 { pub fn direct_page_indexed_indirect(bus: &mut Bus, pc_addr: u32, direct_page_register: u16, xy: u16, dbr: u8) -> u32 {
direct_page_indirect(bus, pc_addr, direct_page_register.wrapping_add(xy)) direct_page_indirect(bus, pc_addr, direct_page_register.wrapping_add(xy), dbr)
} }
/// OPCODE (dp),X /// OPCODE (dp),X
/// OPCODE (dp),Y /// OPCODE (dp),Y
pub fn direct_page_indirect_indexed(bus: &mut Bus, pc_addr: u32, direct_page_register: u16, xy: u16) -> u32 { pub fn direct_page_indirect_indexed(bus: &mut Bus, pc_addr: u32, direct_page_register: u16, xy: u16, dbr: u8) -> u32 {
direct_page_indirect(bus, pc_addr, direct_page_register) + (xy as u32) direct_page_indirect(bus, pc_addr, direct_page_register, dbr) + (xy as u32)
} }
/// OPCODE [dp],X /// OPCODE [dp],X
@@ -172,14 +171,14 @@ impl AddressingMode {
Self::AbsoluteIndirectLong => absolute_indirect_long(bus, p.pc_addr, p.dbr), Self::AbsoluteIndirectLong => absolute_indirect_long(bus, p.pc_addr, p.dbr),
Self::AbsoluteLong => absolute_long(bus, p.pc_addr), Self::AbsoluteLong => absolute_long(bus, p.pc_addr),
Self::DirectPage => direct_page(bus, p.pc_addr, p.direct_page_register), Self::DirectPage => direct_page(bus, p.pc_addr, p.direct_page_register),
Self::DirectPageIndirect => direct_page_indirect(bus, p.pc_addr, p.direct_page_register), Self::DirectPageIndirect => direct_page_indirect(bus, p.pc_addr, p.direct_page_register, p.dbr),
Self::DirectPageIndirectLong => direct_page_indirect_long(bus, p.pc_addr, p.direct_page_register), Self::DirectPageIndirectLong => direct_page_indirect_long(bus, p.pc_addr, p.direct_page_register),
Self::AbsoluteIndexed(idx) => absolute_indexed(bus, p.pc_addr, if idx == X {p.x} else {p.y}, p.dbr), Self::AbsoluteIndexed(idx) => absolute_indexed(bus, p.pc_addr, if idx == X {p.x} else {p.y}, p.dbr),
Self::AbsoluteIndexedIndirect(idx) => absolute_indexed_indirect(bus, p.pc_addr, if idx == X {p.x} else {p.y}, p.dbr), Self::AbsoluteIndexedIndirect(idx) => absolute_indexed_indirect(bus, p.pc_addr, if idx == X {p.x} else {p.y}, p.dbr),
Self::AbsoluteLongIndexed(idx) => absolute_long_indexed(bus, p.pc_addr, if idx == X {p.x} else {p.y}), Self::AbsoluteLongIndexed(idx) => absolute_long_indexed(bus, p.pc_addr, if idx == X {p.x} else {p.y}),
Self::DirectPageIndexed(idx) => direct_page_indexed(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}), Self::DirectPageIndexed(idx) => direct_page_indexed(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}),
Self::DirectPageIndexedIndirect(idx) => direct_page_indexed_indirect(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}), Self::DirectPageIndexedIndirect(idx) => direct_page_indexed_indirect(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}, p.dbr),
Self::DirectPageIndirectIndexed(idx) => direct_page_indirect_indexed(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}), Self::DirectPageIndirectIndexed(idx) => direct_page_indirect_indexed(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}, p.dbr),
Self::DirectPageIndirectLongIndexed(idx) => direct_page_indirect_long_indexed(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}), Self::DirectPageIndirectLongIndexed(idx) => direct_page_indirect_long_indexed(bus, p.pc_addr, p.direct_page_register, if idx == X {p.x} else {p.y}),
Self::StackRelative => stack_relative(bus, p.pc_addr, p.stack_pointer, p.dbr), Self::StackRelative => stack_relative(bus, p.pc_addr, p.stack_pointer, p.dbr),
Self::StackRelativeIndirectIndexed(idx) => stack_relative_indirect_indexed(bus, p.pc_addr, p.stack_pointer, if idx == X {p.x} else {p.y}, p.dbr), Self::StackRelativeIndirectIndexed(idx) => stack_relative_indirect_indexed(bus, p.pc_addr, p.stack_pointer, if idx == X {p.x} else {p.y}, p.dbr),
@@ -309,21 +308,21 @@ mod addressing_modes_tests {
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write(dp as u32, 0x02); bus.write(dp as u32, 0x02);
bus.write((dp + 1) as u32, 0x01); bus.write((dp + 1) as u32, 0x01);
assert_eq!(direct_page_indirect(&mut bus, pc_addr, 0x00), 0x000201); assert_eq!(direct_page_indirect(&mut bus, pc_addr, 0x00, 0x00), 0x000201);
let pc_addr = 0x7E0010; let pc_addr = 0x7E0010;
let dp = 0x55; let dp = 0x55;
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write(dp as u32, 0x02); bus.write(dp as u32, 0x02);
bus.write((dp + 1) as u32, 0x01); bus.write((dp + 1) as u32, 0x01);
assert_eq!(direct_page_indirect(&mut bus, pc_addr, 0x00), 0x7E0201); assert_eq!(direct_page_indirect(&mut bus, pc_addr, 0x00, 0x7E), 0x7E0201);
let pc_addr = 0x7E0010; let pc_addr = 0x7E0010;
let dp = 0x55; let dp = 0x55;
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write((dp + 1) as u32, 0x02); bus.write((dp + 1) as u32, 0x02);
bus.write((dp + 2) as u32, 0x01); bus.write((dp + 2) as u32, 0x01);
assert_eq!(direct_page_indirect(&mut bus, pc_addr, 0x01), 0x7E0201); assert_eq!(direct_page_indirect(&mut bus, pc_addr, 0x01, 0x7E), 0x7E0201);
} }
#[test] #[test]
@@ -411,21 +410,21 @@ mod addressing_modes_tests {
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write((dp + 1) as u32, 0x02); bus.write((dp + 1) as u32, 0x02);
bus.write((dp + 2) as u32, 0x01); bus.write((dp + 2) as u32, 0x01);
assert_eq!(direct_page_indexed_indirect(&mut bus, pc_addr, 0x00, 0x01), 0x000201); assert_eq!(direct_page_indexed_indirect(&mut bus, pc_addr, 0x00, 0x01, 0x00), 0x000201);
let pc_addr = 0x7E0010; let pc_addr = 0x7E0010;
let dp = 0x55; let dp = 0x55;
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write((dp + 1) as u32, 0x02); bus.write((dp + 1) as u32, 0x02);
bus.write((dp + 2) as u32, 0x01); bus.write((dp + 2) as u32, 0x01);
assert_eq!(direct_page_indexed_indirect(&mut bus, pc_addr, 0x00, 0x01), 0x7E0201); assert_eq!(direct_page_indexed_indirect(&mut bus, pc_addr, 0x00, 0x01, 0x7E), 0x7E0201);
let pc_addr = 0x7E0010; let pc_addr = 0x7E0010;
let dp = 0x55; let dp = 0x55;
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write((dp + 2) as u32, 0x02); bus.write((dp + 2) as u32, 0x02);
bus.write((dp + 3) as u32, 0x01); bus.write((dp + 3) as u32, 0x01);
assert_eq!(direct_page_indexed_indirect(&mut bus, pc_addr, 0x01, 0x01), 0x7E0201); assert_eq!(direct_page_indexed_indirect(&mut bus, pc_addr, 0x01, 0x01, 0x7E), 0x7E0201);
} }
#[test] #[test]
@@ -436,21 +435,21 @@ mod addressing_modes_tests {
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write(dp as u32, 0x02); bus.write(dp as u32, 0x02);
bus.write((dp + 1) as u32, 0x01); bus.write((dp + 1) as u32, 0x01);
assert_eq!(direct_page_indirect_indexed(&mut bus, pc_addr, 0x00, 0x01), 0x000202); assert_eq!(direct_page_indirect_indexed(&mut bus, pc_addr, 0x00, 0x01, 0x00), 0x000202);
let pc_addr = 0x7E0010; let pc_addr = 0x7E0010;
let dp = 0x55; let dp = 0x55;
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write(dp as u32, 0x02); bus.write(dp as u32, 0x02);
bus.write((dp + 1) as u32, 0x01); bus.write((dp + 1) as u32, 0x01);
assert_eq!(direct_page_indirect_indexed(&mut bus, pc_addr, 0x00, 0x01), 0x7E0202); assert_eq!(direct_page_indirect_indexed(&mut bus, pc_addr, 0x00, 0x01, 0x7E), 0x7E0202);
let pc_addr = 0x7E0010; let pc_addr = 0x7E0010;
let dp = 0x55; let dp = 0x55;
bus.write(pc_addr + 1, dp); bus.write(pc_addr + 1, dp);
bus.write((dp + 1) as u32, 0x02); bus.write((dp + 1) as u32, 0x02);
bus.write((dp + 2) as u32, 0x01); bus.write((dp + 2) as u32, 0x01);
assert_eq!(direct_page_indirect_indexed(&mut bus, pc_addr, 0x01, 0x01), 0x7E0202); assert_eq!(direct_page_indirect_indexed(&mut bus, pc_addr, 0x01, 0x01, 0x7E), 0x7E0202);
} }
#[test] #[test]