wai and wdm instructions

This commit is contained in:
2023-05-22 23:16:21 -05:00
parent 95397a6275
commit 93cc597c10
3 changed files with 57 additions and 9 deletions
+2
View File
@@ -4,6 +4,7 @@ pub struct CPU {
pub registers: Registers, pub registers: Registers,
pub cycles: usize, pub cycles: usize,
pub is_stopped: bool, pub is_stopped: bool,
pub is_waiting_interrupt: bool,
} }
impl CPU { impl CPU {
@@ -12,6 +13,7 @@ impl CPU {
registers: Registers::new(), registers: Registers::new(),
cycles: 0, cycles: 0,
is_stopped: false, is_stopped: false,
is_waiting_interrupt: false,
} }
} }
} }
+4
View File
@@ -223,6 +223,10 @@ impl CPU {
self.registers.increment_pc(1); self.cycles += 2; self.registers.increment_pc(1); self.cycles += 2;
} }
pub fn increment_cycles_wdm(&mut self) {
self.registers.increment_pc(2); self.cycles += 2;
}
pub fn increment_cycles_jmp(&mut self, addressing_mode: AddressingMode) { pub fn increment_cycles_jmp(&mut self, addressing_mode: AddressingMode) {
let (_, cycles) = match addressing_mode { let (_, cycles) = match addressing_mode {
A::Absolute => (3, 3), A::Absolute => (3, 3),
+51 -9
View File
@@ -875,8 +875,8 @@ impl CPU {
self.increment_cycles_st_index(addressing_mode); self.increment_cycles_st_index(addressing_mode);
} }
fn stp(&mut self, bus: &Bus) { fn stp(&mut self) {
self.reset_vector(bus); self.is_stopped = true;
self.increment_cycles_stp(); self.increment_cycles_stp();
} }
@@ -1103,14 +1103,37 @@ impl CPU {
self.increment_cycles_test(addressing_mode); self.increment_cycles_test(addressing_mode);
} }
fn wai(&mut self) {
self.is_waiting_interrupt = true;
self.increment_cycles_stp();
}
fn wdm(&mut self) {
self.increment_cycles_wdm();
}
fn xce(&mut self) { fn xce(&mut self) {
self.registers.exchange_carry_and_emulation(); self.registers.exchange_carry_and_emulation();
self.increment_cycles_exchange(); self.increment_cycles_exchange();
} }
pub fn tick(&mut self, bus: &mut Bus) { fn check_running_state(&mut self) -> bool {
if self.is_stopped { if self.is_stopped {
self.increment_cycles_while_stopped(); self.increment_cycles_while_stopped();
return false;
}
if self.is_waiting_interrupt {
// TODO: check for interrupts here
self.increment_cycles_while_stopped();
return false;
}
return true;
}
pub fn tick(&mut self, bus: &mut Bus) {
if !self.check_running_state() {
return; return;
} }
let opcode = bus.read(self.registers.get_pc_address()); let opcode = bus.read(self.registers.get_pc_address());
@@ -1415,7 +1438,7 @@ impl CPU {
0x83 => self.sta(bus, A::StackRelative), 0x83 => self.sta(bus, A::StackRelative),
0x93 => self.sta(bus, A::StackRelativeIndirectIndexed(I::Y)), 0x93 => self.sta(bus, A::StackRelativeIndirectIndexed(I::Y)),
// STP // STP
0xDB => self.stp(bus), 0xDB => self.stp(),
// STX // STX
0x8E => self.stx(bus, A::Absolute), 0x8E => self.stx(bus, A::Absolute),
0x86 => self.stx(bus, A::DirectPage), 0x86 => self.stx(bus, A::DirectPage),
@@ -1460,9 +1483,9 @@ impl CPU {
// TYX // TYX
0xBB => self.tyx(), 0xBB => self.tyx(),
// WAI // WAI
0xCB => unimplemented!("WAI instruction not implemented yet"), 0xCB => self.wai(),
// WDM // WDM
0x42 => unimplemented!("WDM instruction not implemented yet"), 0x42 => self.wdm(),
// XBA // XBA
0xEB => self.xba(), 0xEB => self.xba(),
// XCE // XCE
@@ -2688,11 +2711,10 @@ mod cpu_instructions_tests {
#[test] #[test]
fn test_stp() { fn test_stp() {
let mut cpu = CPU::new(); let mut cpu = CPU::new();
let bus = Bus::new();
cpu.is_stopped = false; cpu.is_stopped = false;
cpu.registers.pc = 0x0000; cpu.registers.pc = 0x0000;
cpu.stp(&bus); cpu.stp();
assert_eq!(cpu.registers.pc, 0x0003); assert_eq!(cpu.registers.pc, 0x0001);
assert_eq!(cpu.is_stopped, true); assert_eq!(cpu.is_stopped, true);
assert_eq!(cpu.cycles, 3); assert_eq!(cpu.cycles, 3);
} }
@@ -2900,6 +2922,26 @@ mod cpu_instructions_tests {
assert_eq!(cpu.cycles, 2); assert_eq!(cpu.cycles, 2);
} }
#[test]
fn test_wai() {
let mut cpu = CPU::new();
cpu.is_waiting_interrupt = false;
cpu.registers.pc = 0x0000;
cpu.wai();
assert_eq!(cpu.registers.pc, 0x0001);
assert_eq!(cpu.is_waiting_interrupt, true);
assert_eq!(cpu.cycles, 3);
}
#[test]
fn test_wdm() {
let mut cpu = CPU::new();
cpu.registers.pc = 0x0000;
cpu.wdm();
assert_eq!(cpu.registers.pc, 0x0002);
assert_eq!(cpu.cycles, 2);
}
#[test] #[test]
fn test_xba() { fn test_xba() {
let mut cpu = CPU::new(); let mut cpu = CPU::new();