mvn and mvp

This commit is contained in:
2023-12-28 23:02:32 -05:00
parent 561207a299
commit a71999ab68
5 changed files with 98 additions and 0 deletions
@@ -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 { pub fn mnemonic_single_byte_instr(opcode: u8, instr_name: &str) -> String {
format!("{:02X} __ __ __ | {}", opcode, instr_name) 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 ldx;
pub mod ldy; pub mod ldy;
pub mod lsr; pub mod lsr;
pub mod mvn;
pub mod mvp;
pub mod bit_common; pub mod bit_common;
pub mod dec_common; pub mod dec_common;
pub mod decoder_common; pub mod decoder_common;
pub mod branch_common; pub mod branch_common;
pub mod push_common; pub mod push_common;
pub mod comp_common; pub mod comp_common;
pub mod move_common;
pub trait CPUInstruction { pub trait CPUInstruction {
fn execute(&self, registers: &mut Registers, bus: &mut Bus); 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;
}
+30
View File
@@ -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() {
}
}
+30
View File
@@ -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() {
}
}