From 33b852d8d41456e6f8a5bbc9d25ca2014904ccbb Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Sat, 30 Dec 2023 11:35:20 -0500 Subject: [PATCH] last instructions --- snes-core/src/cpu/instructionstemp/mod.rs | 4 +++ snes-core/src/cpu/instructionstemp/wai.rs | 42 ++++++++++++++++++++++ snes-core/src/cpu/instructionstemp/wdm.rs | 39 ++++++++++++++++++++ snes-core/src/cpu/instructionstemp/xba.rs | 44 +++++++++++++++++++++++ snes-core/src/cpu/instructionstemp/xce.rs | 40 +++++++++++++++++++++ snes-core/src/cpu/registers.rs | 2 ++ 6 files changed, 171 insertions(+) create mode 100644 snes-core/src/cpu/instructionstemp/wai.rs create mode 100644 snes-core/src/cpu/instructionstemp/wdm.rs create mode 100644 snes-core/src/cpu/instructionstemp/xba.rs create mode 100644 snes-core/src/cpu/instructionstemp/xce.rs diff --git a/snes-core/src/cpu/instructionstemp/mod.rs b/snes-core/src/cpu/instructionstemp/mod.rs index 348c3ad..fd541e6 100644 --- a/snes-core/src/cpu/instructionstemp/mod.rs +++ b/snes-core/src/cpu/instructionstemp/mod.rs @@ -88,6 +88,10 @@ pub mod txs; pub mod txy; pub mod tya; pub mod tyx; +pub mod wai; +pub mod wdm; +pub mod xba; +pub mod xce; pub mod bit_common; pub mod dec_common; pub mod decoder_common; diff --git a/snes-core/src/cpu/instructionstemp/wai.rs b/snes-core/src/cpu/instructionstemp/wai.rs new file mode 100644 index 0000000..335743f --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/wai.rs @@ -0,0 +1,42 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use crate::cpu::cycles; +use super::{CPUInstruction, Decode}; +use super::decoder_common; + +static INSTR_NAME: &'static str = "WAI"; + +pub struct WAI {} + +impl CPUInstruction for WAI { + fn execute(&self, registers: &mut Registers, _bus: &mut Bus) { + registers.is_cpu_waiting_interrupt = true; + let (bytes, cycles) = cycles::increment_cycles_stp(); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for WAI { + fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.is_cpu_waiting_interrupt = false; + registers.pc = 0x0000; + let instruction = WAI{}; + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x0001); + assert_eq!(registers.is_cpu_waiting_interrupt, true); + assert_eq!(registers.cycles, 3); + } +} diff --git a/snes-core/src/cpu/instructionstemp/wdm.rs b/snes-core/src/cpu/instructionstemp/wdm.rs new file mode 100644 index 0000000..d107dea --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/wdm.rs @@ -0,0 +1,39 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use crate::cpu::cycles; +use super::{CPUInstruction, Decode}; +use super::decoder_common; + +static INSTR_NAME: &'static str = "WDM"; + +pub struct WDM {} + +impl CPUInstruction for WDM { + fn execute(&self, registers: &mut Registers, _bus: &mut Bus) { + let (bytes, cycles) = cycles::increment_cycles_wdm(); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for WDM { + fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + let instruction = WDM{}; + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x0002); + assert_eq!(registers.cycles, 2); + } +} diff --git a/snes-core/src/cpu/instructionstemp/xba.rs b/snes-core/src/cpu/instructionstemp/xba.rs new file mode 100644 index 0000000..b1ea006 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/xba.rs @@ -0,0 +1,44 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use crate::cpu::cycles; +use super::{CPUInstruction, Decode}; +use super::decoder_common; + +static INSTR_NAME: &'static str = "XBA"; + +pub struct XBA {} + +impl CPUInstruction for XBA { + fn execute(&self, registers: &mut Registers, _bus: &mut Bus) { + registers.a = (registers.a << 8) | (registers.a >> 8); + registers.set_negative_flag(((registers.a as u8) >> 7) == 1); + registers.set_zero_flag((registers.a as u8) == 0); + let (bytes, cycles) = cycles::increment_cycles_xba(); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for XBA { + fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + registers.a = 0x11FF; + let instruction = XBA{}; + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.a, 0xFF11); + assert_eq!(registers.pc, 0x0001); + assert_eq!(registers.cycles, 3); + } +} diff --git a/snes-core/src/cpu/instructionstemp/xce.rs b/snes-core/src/cpu/instructionstemp/xce.rs new file mode 100644 index 0000000..ab2d07d --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/xce.rs @@ -0,0 +1,40 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use crate::cpu::cycles; +use super::{CPUInstruction, Decode}; +use super::decoder_common; + +static INSTR_NAME: &'static str = "XCE"; + +pub struct XCE {} + +impl CPUInstruction for XCE { + fn execute(&self, registers: &mut Registers, _bus: &mut Bus) { + registers.exchange_carry_and_emulation(); + let (bytes, cycles) = cycles::increment_cycles_exchange(); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for XCE { + fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + let instruction = XCE{}; + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x0001); + assert_eq!(registers.cycles, 2); + } +} diff --git a/snes-core/src/cpu/registers.rs b/snes-core/src/cpu/registers.rs index f7d96cd..22c608e 100644 --- a/snes-core/src/cpu/registers.rs +++ b/snes-core/src/cpu/registers.rs @@ -12,6 +12,7 @@ pub struct Registers { pub pc: u16, // Program counter pub emulation_mode: bool, pub is_cpu_stopped: bool, + pub is_cpu_waiting_interrupt: bool, pub cycles: usize, } @@ -29,6 +30,7 @@ impl Registers { pc: 0, emulation_mode: true, is_cpu_stopped: false, + is_cpu_waiting_interrupt: false, cycles: 0, } }