mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
mvn and mvp
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user