Adds IZY address mode - Only tested with the LDA instruction however

master
Joey Pollack 2 years ago
parent 93e16f0d02
commit cccc23f2e6

@ -199,9 +199,39 @@ impl AddressingModes
ModeID::IZX
}
// Indirect Indexed Addressing (IND), Y
// In indirect indexed addressing, the second byte of the instruction points to
// a memory location in page zero. The contents of this memory location are added to
// the contents of the Y register. The result is the low order byte of the effective address.
// The carry from this addition is added to the contents of the next page zero memory
// location, to form the high order byte of the effective address.
//
// Info from:
// https://web.archive.org/web/20221112231348if_/http://archive.6502.org/datasheets/rockwell_r650x_r651x.pdf
pub fn IZY(cpu: &mut R6502, bus: &mut dyn Bus) -> ModeID
{
// zp_pointer points to a location in zero page
let zp_pointer = bus.read(cpu.pc) as u16;
cpu.pc += 1;
// The value at zp_pointer is added to the Y register
let zp_value = bus.read(zp_pointer) as u16;
let sum = zp_value + cpu.y as u16;
// The sum with the carry discarded is the lo byte
let lo_byte = sum & 0x00FF;
// The carry plus the value at the next zero page address is the hi byte
let zp_next = bus.read(zp_pointer + 1) as u16;
let temp = (sum & 0xFF00) >> 0x08;
let temp2 = temp + zp_next;
let hi_byte: u8 = (((sum & 0xFF00) >> 0x08) + zp_next) as u8;
// Store the final address and read the data
cpu.working_addr = ((hi_byte as u16) << 0x08) | lo_byte;
cpu.working_data = bus.read(cpu.working_addr) as u16;
ModeID::IZY
}
}

@ -226,6 +226,44 @@ fn IZX()
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x08 in the A register?
assert_eq!(0x08, cpu.debug_get_reg(Registers::A));
}
#[test]
fn IZY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x08 into memory
bus.write(0x020B, 0x08);
// Manuall put 0x01FC into the Zero page at 0x000A
// This will be added to the Y register (which will store 0x0F)
bus.write(0x000A, 0xFC); // Pointer lo byte
bus.write(0x000B, 0x01); // Pointer hi byte
// Program to load 0x08 into the accumulator
bus.write(addr, 0xB1); // LDA - Indirect, Y mode
bus.write(addr + 1, 0x0A); // Argument - Pointer into the Zero Page
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x0F); // Offset of the value at the zero page address
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x08 in the A register?
assert_eq!(0x08, cpu.debug_get_reg(Registers::A));
}
Loading…
Cancel
Save