From a71999ab681bce2d9ca82716954e036754f038fd Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Thu, 28 Dec 2023 23:02:32 -0500 Subject: [PATCH] mvn and mvp --- .../cpu/instructionstemp/decoder_common.rs | 6 ++++ snes-core/src/cpu/instructionstemp/mod.rs | 3 ++ .../src/cpu/instructionstemp/move_common.rs | 29 ++++++++++++++++++ snes-core/src/cpu/instructionstemp/mvn.rs | 30 +++++++++++++++++++ snes-core/src/cpu/instructionstemp/mvp.rs | 30 +++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 snes-core/src/cpu/instructionstemp/move_common.rs create mode 100644 snes-core/src/cpu/instructionstemp/mvn.rs create mode 100644 snes-core/src/cpu/instructionstemp/mvp.rs diff --git a/snes-core/src/cpu/instructionstemp/decoder_common.rs b/snes-core/src/cpu/instructionstemp/decoder_common.rs index 5038139..1838eea 100644 --- a/snes-core/src/cpu/instructionstemp/decoder_common.rs +++ b/snes-core/src/cpu/instructionstemp/decoder_common.rs @@ -120,3 +120,9 @@ pub fn mnemonic_branch_nearlabel(opcode: u8, instr_name: &str, registers: &Regis pub fn mnemonic_single_byte_instr(opcode: u8, instr_name: &str) -> String { format!("{:02X} __ __ __ | {}", opcode, instr_name) } + +pub fn mnemonic_move(opcode: u8, instr_name: &str, registers: &Registers, bus: &Bus) -> String { + let next_byte = bus.read_external(registers.get_pc_address() + 1); + let next_second_byte = bus.read_external(registers.get_pc_address() + 2); + format!("{:02X} {:02X} {:02X} __ | {} {:02X},{:02X}", opcode, next_byte, next_second_byte, instr_name, next_second_byte, next_byte) +} diff --git a/snes-core/src/cpu/instructionstemp/mod.rs b/snes-core/src/cpu/instructionstemp/mod.rs index 4bf1d7f..90ee04a 100644 --- a/snes-core/src/cpu/instructionstemp/mod.rs +++ b/snes-core/src/cpu/instructionstemp/mod.rs @@ -38,12 +38,15 @@ pub mod lda; pub mod ldx; pub mod ldy; pub mod lsr; +pub mod mvn; +pub mod mvp; pub mod bit_common; pub mod dec_common; pub mod decoder_common; pub mod branch_common; pub mod push_common; pub mod comp_common; +pub mod move_common; pub trait CPUInstruction { fn execute(&self, registers: &mut Registers, bus: &mut Bus); diff --git a/snes-core/src/cpu/instructionstemp/move_common.rs b/snes-core/src/cpu/instructionstemp/move_common.rs new file mode 100644 index 0000000..ad81847 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/move_common.rs @@ -0,0 +1,29 @@ +use crate::cpu::{registers::Registers, bus::Bus, cycles}; + +pub fn do_move(registers: &mut Registers, bus: &mut Bus, is_next: bool) { + let pc = registers.get_pc_address(); + let source_bank = bus.read(pc + 2); + let dest_bank = bus.read(pc + 1); + let mut count = 0; + while registers.a != 0xFFFF { + let (x, y) = match registers.is_16bit_index() { + true => (registers.x, registers.y), + false => (registers.x & 0x00FF, registers.y & 0x00FF), + }; + let source_address = ((source_bank as u32) << 16) | (x as u32); + let dest_address = ((dest_bank as u32) << 16) | (y as u32); + let byte = bus.read(source_address); + bus.write(dest_address, byte); + registers.a = registers.a.wrapping_sub(1); + if is_next { + registers.x = registers.x.wrapping_add(1); + registers.y = registers.y.wrapping_add(1); + } else { + registers.x = registers.x.wrapping_sub(1); + registers.y = registers.y.wrapping_sub(1); + } + count += 1; + } + let (bytes, cycles) = cycles::increment_cycles_move(count); + registers.increment_pc(bytes); registers.cycles += cycles; +} diff --git a/snes-core/src/cpu/instructionstemp/mvn.rs b/snes-core/src/cpu/instructionstemp/mvn.rs new file mode 100644 index 0000000..dff6328 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/mvn.rs @@ -0,0 +1,30 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode, move_common}; +use super::decoder_common; + +static INSTR_NAME: &'static str = "MVN"; + +pub struct MVN {} + +impl CPUInstruction for MVN { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + move_common::do_move(registers, bus, true); + } +} + +impl Decode for MVN { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_move(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + } +} diff --git a/snes-core/src/cpu/instructionstemp/mvp.rs b/snes-core/src/cpu/instructionstemp/mvp.rs new file mode 100644 index 0000000..360f548 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/mvp.rs @@ -0,0 +1,30 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode, move_common}; +use super::decoder_common; + +static INSTR_NAME: &'static str = "MVP"; + +pub struct MVP {} + +impl CPUInstruction for MVP { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + move_common::do_move(registers, bus, false); + } +} + +impl Decode for MVP { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_move(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + } +}