added the STx family of instructions

This commit is contained in:
2026-08-08 20:10:45 -05:00
parent e1f62408ca
commit a2ceb1dea8
3 changed files with 114 additions and 21 deletions
+108 -17
View File
@@ -131,15 +131,27 @@ impl Cpu {
0xB9 => self.lda_aby(bus),
0xA1 => self.lda_izx(bus),
0xB1 => self.lda_izy(bus),
0xA6 => self.ldx_zp(bus), // LDX zp
0xB6 => self.ldx_zpy(bus), // LDX zpy
0xAE => self.ldx_abs(bus), // LDX abs
0xBE => self.ldx_aby(bus), // LDX aby
0xA0 => self.ldy_imm(bus), // LDY imm
0xA4 => self.ldy_zp(bus), // LDY zp
0xB4 => self.ldy_zpx(bus), // LDY zpx
0xAC => self.ldy_abs(bus), // LDY abs
0xBC => self.ldy_abx(bus), // LDY abx
0xA6 => self.ldx_zp(bus),
0xB6 => self.ldx_zpy(bus),
0xAE => self.ldx_abs(bus),
0xBE => self.ldx_aby(bus),
0xA0 => self.ldy_imm(bus),
0xA4 => self.ldy_zp(bus),
0xB4 => self.ldy_zpx(bus),
0xAC => self.ldy_abs(bus),
0xBC => self.ldy_abx(bus),
0x85 => self.sta_zp(bus),
0x95 => self.sta_zpx(bus),
0x8D => self.sta_abs(bus),
0x9D => self.sta_abx(bus),
0x99 => self.sta_aby(bus),
0x81 => self.sta_izx(bus),
0x91 => self.sta_izy(bus),
0x96 => self.stx_zpy(bus),
0x8E => self.stx_abs(bus),
0x84 => self.sty_zp(bus),
0x94 => self.sty_zpx(bus),
0x8C => self.sty_abs(bus),
_ => panic!("illegal/unkown opcode {opcode:#04X} at {:#06X}", self.pc.wrapping_sub(1)),
};
self.cycles += cycles as u64;
@@ -256,16 +268,26 @@ impl Cpu {
base + extra
}
// Shared cores for STx instructions
fn sta(&mut self, bus: &mut impl Bus, (address, extra): (u16, u8), base: u8) -> u8 {
self.write(bus, address, self.a);
base + extra
}
fn stx(&mut self, bus: &mut impl Bus, (address, extra): (u16, u8), base: u8) -> u8 {
self.write(bus, address, self.x);
base + extra
}
fn sty(&mut self, bus: &mut impl Bus, (address, extra): (u16, u8), base: u8) -> u8 {
self.write(bus, address, self.y);
base + extra
}
// NES 6502 opcode -> functions
fn jmp_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x4C, 3 bytes, 3 cycles
self.pc = self.fetch16(bus);
3
}
fn stx_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x86, 2 bytes, 3 cycles
let (addr, _) = self.address_zp(bus);
self.write(bus, addr, self.x);
3
}
fn jsr_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x20, 3 bytes, 6 cycles
@@ -427,7 +449,7 @@ impl Cpu {
self.ldy(bus, (addr, extra), 4)
}
// imm variants
// imm variants for LDx
fn lda_imm(&mut self, bus: &mut impl Bus) -> u8 { // 0xA9, 2 bytes, 2 cycles
self.a = self.fetch(bus);
self.set_zp_flags(self.a);
@@ -446,6 +468,63 @@ impl Cpu {
2
}
// STA variants
fn sta_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x85, 2 bytes, 3 cycles
let (address, extra) = self.address_zp(bus);
self.sta(bus, (address, extra), 3)
}
fn sta_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0x95, 2 bytes, 4 cycles
let (address, extra) = self.address_zpx(bus);
self.sta(bus, (address, extra), 4)
}
fn sta_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x8D, 3 bytes, 4 cycles
let (address, extra) = self.address_abs(bus);
self.sta(bus, (address, extra), 4)
}
fn sta_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0x9D, 3 bytes, 4 cycles
let (address, extra) = self.address_abx(bus);
self.sta(bus, (address, extra), 4)
}
fn sta_aby(&mut self, bus: &mut impl Bus) -> u8 { // 0x99, 3 bytes, 4 cycles
let (address, extra) = self.address_aby(bus);
self.sta(bus, (address, extra), 4)
}
fn sta_izx(&mut self, bus: &mut impl Bus) -> u8 { // 0x81, 2 bytes, 6 cycles
let (address, extra) = self.address_izx(bus);
self.sta(bus, (address, extra), 6)
}
fn sta_izy(&mut self, bus: &mut impl Bus) -> u8 { // 0x91, 2 bytes, 5 cycles
let (address, extra) = self.address_izy(bus);
self.sta(bus, (address, extra), 5)
}
// STX variants
fn stx_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x86, 2 bytes, 3 cycles
let (address, extra) = self.address_zp(bus);
self.stx(bus, (address, extra), 3)
}
fn stx_zpy(&mut self, bus: &mut impl Bus) -> u8 { // 0x96, 2 bytes, 4 cycles
let (address, extra) = self.address_zpy(bus);
self.stx(bus, (address, extra), 4)
}
fn stx_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x8E, 3 bytes, 4 cycles
let (address, extra) = self.address_abs(bus);
self.stx(bus, (address, extra), 4)
}
// STY variants
fn sty_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x84, 2 bytes, 3 cycles
let (addr, extra) = self.address_zp(bus);
self.sty(bus, (addr, extra), 3)
}
fn sty_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0x94, 2 bytes, 4 cycles
let (addr, extra) = self.address_zpx(bus);
self.sty(bus, (addr, extra), 4)
}
fn sty_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x8C, 3 bytes, 4 cycles
let (addr, extra) = self.address_abs(bus);
self.sty(bus, (addr, extra), 4)
}
// all branching alternatives here all 1 bytes
fn bcs_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_CARRY)) } // 0xB0
fn bcc_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, !self.flag(FLAG_CARRY)) } // 0x90
@@ -457,7 +536,7 @@ impl Cpu {
fn bvs_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_OVERFLOW)) } //0x70
// NES 6502 opcode length table/matcher
fn opcode_len(opcode: u8) -> u8 {
pub fn opcode_len(opcode: u8) -> u8 {
match opcode {
0x4C => 3, // JMP abs
0xA2 => 2, // LDX imm
@@ -503,6 +582,18 @@ impl Cpu {
0xB4 => 2, // LDY zpx
0xAC => 3, // LDY abs
0xBC => 3, // LDY abx
0x85 => 2, // STA zp
0x95 => 2, // STA zpx
0x8D => 3, // STA abs
0x9D => 3, // STA abx
0x99 => 3, // STA aby
0x81 => 2, // STA izx
0x91 => 2, // STA izy
0x96 => 2, // STX zpy
0x8E => 3, // STX abs
0x84 => 2, // STY zp
0x94 => 2, // STY zpx
0x8C => 3, // STY abs
_ => 1, // fallback, would show the invalid/unknown opcode only not its parameters
}
}