implemented the INC and DEC family of instructions
This commit is contained in:
+92
@@ -148,6 +148,12 @@ impl Cpu {
|
||||
0x49 => self.eor_imm(bus), 0x45 => self.eor_zp(bus), 0x55 => self.eor_zpx(bus),
|
||||
0x4D => self.eor_abs(bus), 0x5D => self.eor_abx(bus), 0x59 => self.eor_aby(bus),
|
||||
0x41 => self.eor_izx(bus), 0x51 => self.eor_izy(bus),
|
||||
// Increments
|
||||
0xE6 => self.inc_zp(bus), 0xF6 => self.inc_zpx(bus), 0xEE => self.inc_abs(bus),
|
||||
0xFE => self.inc_abx(bus), 0xE8 => self.inx_imp(bus), 0xC8 => self.iny_imp(bus),
|
||||
// Decrements
|
||||
0xC6 => self.dec_zp(bus), 0xD6 => self.dec_zpx(bus), 0xCE => self.dec_abs(bus),
|
||||
0xDE => self.dec_abx(bus), 0xCA => self.dex_imp(bus), 0x88 => self.dey_imp(bus),
|
||||
_ => panic!("illegal/unkown opcode {opcode:#04X} at {:#06X}", self.pc.wrapping_sub(1)),
|
||||
};
|
||||
self.cycles += cycles as u64;
|
||||
@@ -185,6 +191,9 @@ impl Cpu {
|
||||
0x1D => 3, /* ORA abx */ 0x19 => 3, /* ORA aby */ 0x01 => 2, /* ORA izx */ 0x11 => 2, /* ORA izy */
|
||||
0x49 => 2, /* EOR imm */ 0x45 => 2, /* EOR zp */ 0x55 => 2, /* EOR zpx */ 0x4D => 3, /* EOR abs */
|
||||
0x5D => 3, /* EOR abx */ 0x59 => 3, /* EOR aby */ 0x41 => 2, /* EOR izx */ 0x51 => 2, /* EOR izy */
|
||||
0xE6 => 2, /* INC zp */ 0xF6 => 2, /* INC zpx */ 0xEE => 3, /* INC abs */ 0xFE => 3, /* INC abx */
|
||||
0xE8 => 1, /* INX imp */ 0xC8 => 1, /* INY imp */ 0xC6 => 2, /* DEC zp */ 0xD6 => 2, /* DEC zpx */
|
||||
0xCE => 3, /* DEC abs */ 0xDE => 3, /* DEC abx */ 0xCA => 1, /* DEX imp */ 0x88 => 1, /* DEY imp */
|
||||
_ => 1, // fallback, would show the invalid/unknown opcode only not its parameters
|
||||
}
|
||||
}
|
||||
@@ -405,6 +414,22 @@ impl Cpu {
|
||||
base + extra
|
||||
}
|
||||
|
||||
// INC core
|
||||
fn inc(&mut self, bus: &mut impl Bus, (address, _extra): (u16, u8), base: u8) -> u8 {
|
||||
let value = self.read(bus, address).wrapping_add(1);
|
||||
self.write(bus, address, value);
|
||||
self.set_zp_flags(value);
|
||||
base // NO + extra — RMW cycles are fixed
|
||||
}
|
||||
|
||||
// DEC core
|
||||
fn dec(&mut self, bus: &mut impl Bus, (address, _extra): (u16, u8), base: u8) -> u8 {
|
||||
let value = self.read(bus, address).wrapping_sub(1);
|
||||
self.write(bus, address, value);
|
||||
self.set_zp_flags(value);
|
||||
base // NO + extra — RMW cycles are fixed
|
||||
}
|
||||
|
||||
// NES 6502 opcode -> functions
|
||||
fn jmp_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x4C, 3 bytes, 3 cycles
|
||||
self.pc = self.fetch16(bus);
|
||||
@@ -968,6 +993,73 @@ impl Cpu {
|
||||
2
|
||||
}
|
||||
|
||||
// INC variants
|
||||
fn inc_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0xE6, 2 bytes, 5 cycles
|
||||
let (address, extra) = self.address_zp(bus);
|
||||
self.inc(bus, (address, extra), 5)
|
||||
}
|
||||
|
||||
fn inc_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0xF6, 2 bytes, 6 cycles
|
||||
let (address, extra) = self.address_zpx(bus);
|
||||
self.inc(bus, (address, extra), 6)
|
||||
}
|
||||
|
||||
fn inc_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0xEE, 3 bytes, 6 cycles
|
||||
let (address, extra) = self.address_abs(bus);
|
||||
self.inc(bus, (address, extra), 6)
|
||||
}
|
||||
|
||||
fn inc_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0xFE, 3 bytes, 7 cycles
|
||||
let (address, extra) = self.address_abx(bus);
|
||||
self.inc(bus, (address, extra), 7)
|
||||
}
|
||||
|
||||
// DEC variants
|
||||
fn dec_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0xC6, 2 bytes, 5 cycles
|
||||
let (address, extra) = self.address_zp(bus);
|
||||
self.dec(bus, (address, extra), 5)
|
||||
}
|
||||
|
||||
fn dec_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0xD6, 2 bytes, 6 cycles
|
||||
let (address, extra) = self.address_zpx(bus);
|
||||
self.dec(bus, (address, extra), 6)
|
||||
}
|
||||
|
||||
fn dec_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0xCE, 3 bytes, 6 cycles
|
||||
let (address, extra) = self.address_abs(bus);
|
||||
self.dec(bus, (address, extra), 6)
|
||||
}
|
||||
|
||||
fn dec_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0xDE, 3 bytes, 7 cycles
|
||||
let (address, extra) = self.address_abx(bus);
|
||||
self.dec(bus, (address, extra), 7)
|
||||
}
|
||||
|
||||
// INC register variants
|
||||
fn inx_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0xE8, 1 byte, 2 cycles
|
||||
self.x = self.x.wrapping_add(1);
|
||||
self.set_zp_flags(self.x);
|
||||
2
|
||||
}
|
||||
|
||||
fn iny_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0xC8, 1 byte, 2 cycles
|
||||
self.y = self.y.wrapping_add(1);
|
||||
self.set_zp_flags(self.y);
|
||||
2
|
||||
}
|
||||
|
||||
// DEC register variants
|
||||
fn dex_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0xCA, 1 byte, 2 cycles
|
||||
self.x = self.x.wrapping_sub(1);
|
||||
self.set_zp_flags(self.x);
|
||||
2
|
||||
}
|
||||
|
||||
fn dey_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0x88, 1 byte, 2 cycles
|
||||
self.y = self.y.wrapping_sub(1);
|
||||
self.set_zp_flags(self.y);
|
||||
2
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user