more transfer instructions

This commit is contained in:
2023-12-30 11:18:41 -05:00
parent 09a649c631
commit 19eeff1291
10 changed files with 670 additions and 0 deletions
@@ -79,6 +79,15 @@ pub mod tay;
pub mod tcd;
pub mod tcs;
pub mod tdc;
pub mod trb;
pub mod tsb;
pub mod tsc;
pub mod tsx;
pub mod txa;
pub mod txs;
pub mod txy;
pub mod tya;
pub mod tyx;
pub mod bit_common;
pub mod dec_common;
pub mod decoder_common;
+60
View File
@@ -0,0 +1,60 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use crate::utils::addressing::AddressingMode;
use super::{CPUInstruction, Decode, read_8bit_from_address, write_8bit_to_address, read_16bit_from_address, write_16bit_to_address};
use super::decoder_common;
static INSTR_NAME: &'static str = "TRB";
pub struct TRB8 {
addressing_mode: AddressingMode,
}
impl CPUInstruction for TRB8 {
fn execute(&self, registers: &mut Registers, bus: &mut Bus) {
let value = read_8bit_from_address(registers, bus, self.addressing_mode);
let result = (registers.a as u8) & value;
write_8bit_to_address(registers, bus, self.addressing_mode, result);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_test(registers, self.addressing_mode);
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TRB8 {
fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_arithmetic(false, opcode, INSTR_NAME, self.addressing_mode, registers, bus)
}
}
pub struct TRB16 {
addressing_mode: AddressingMode,
}
impl CPUInstruction for TRB16 {
fn execute(&self, registers: &mut Registers, bus: &mut Bus) {
let value = read_16bit_from_address(registers, bus, self.addressing_mode);
let result = (registers.a) & value;
write_16bit_to_address(registers, bus, self.addressing_mode, result);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_test(registers, self.addressing_mode);
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TRB16 {
fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_arithmetic(true, opcode, INSTR_NAME, self.addressing_mode, registers, bus)
}
}
#[cfg(test)]
mod cpu_instructions_tests {
use super::*;
#[test]
fn test() {
}
}
+58
View File
@@ -0,0 +1,58 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use crate::utils::addressing::AddressingMode;
use super::{CPUInstruction, Decode, read_8bit_from_address, write_8bit_to_address, read_16bit_from_address, write_16bit_to_address};
use super::decoder_common;
static INSTR_NAME: &'static str = "TSB";
pub struct TSB8 {
addressing_mode: AddressingMode,
}
impl CPUInstruction for TSB8 {
fn execute(&self, registers: &mut Registers, bus: &mut Bus) {
let value = read_8bit_from_address(registers, bus, self.addressing_mode);
let result = (registers.a as u8) | value;
write_8bit_to_address(registers, bus, self.addressing_mode, result);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_test(registers, self.addressing_mode);
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TSB8 {
fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_arithmetic(false, opcode, INSTR_NAME, self.addressing_mode, registers, bus)
}
}
pub struct TSB16 {
addressing_mode: AddressingMode,
}
impl CPUInstruction for TSB16 {
fn execute(&self, registers: &mut Registers, bus: &mut Bus) {
let value = read_16bit_from_address(registers, bus, self.addressing_mode);
let result = registers.a & value;
write_16bit_to_address(registers, bus, self.addressing_mode, result);
registers.set_zero_flag(result == 0);
}
}
impl Decode for TSB16 {
fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_arithmetic(true, opcode, INSTR_NAME, self.addressing_mode, registers, bus)
}
}
#[cfg(test)]
mod cpu_instructions_tests {
use super::*;
#[test]
fn test() {
}
}
+46
View File
@@ -0,0 +1,46 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TSC";
pub struct TSC {}
impl CPUInstruction for TSC {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.sp;
registers.a = result;
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TSC {
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 = 0x0000;
registers.sp = 0xF0F0;
let instruction = TSC{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TSX";
pub struct TSX8 {}
impl CPUInstruction for TSX8 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.sp as u8;
registers.set_low_x(result);
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TSX8 {
fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME)
}
}
pub struct TSX16 {}
impl CPUInstruction for TSX16 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.sp;
registers.x = result;
registers.set_negative_flag((result >> 15) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TSX16 {
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_8bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.x = 0x0000;
registers.sp = 0xF0F0;
registers.set_16bit_index(false);
let instruction = TSX8{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.x, 0x00F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
#[test]
fn test_16bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.x = 0x0000;
registers.sp = 0xF0F0;
registers.set_16bit_index(true);
let instruction = TSX16{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.x, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TXA";
pub struct TXA8 {}
impl CPUInstruction for TXA8 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.x as u8;
registers.set_low_a(result);
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TXA8 {
fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME)
}
}
pub struct TXA16 {}
impl CPUInstruction for TXA16 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.x;
registers.a = result;
registers.set_negative_flag((result >> 15) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TXA16 {
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_8bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.a = 0x0000;
registers.x = 0xF0F0;
registers.set_16bit_mode(false);
let instruction = TXA8{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0x00F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
#[test]
fn test_16bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.a = 0x0000;
registers.x = 0xF0F0;
registers.set_16bit_mode(true);
let instruction = TXA16{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TXS";
pub struct TXS8 {}
impl CPUInstruction for TXS8 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.x as u8;
registers.set_low_sp(result);
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TXS8 {
fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME)
}
}
pub struct TXS16 {}
impl CPUInstruction for TXS16 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.x;
registers.sp = result;
registers.set_negative_flag((result >> 15) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TXS16 {
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_8bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.sp = 0x0000;
registers.x = 0xF0F0;
registers.set_16bit_index(false);
let instruction = TXS8{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.sp, 0x00F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
#[test]
fn test_16bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.sp = 0x0000;
registers.x = 0xF0F0;
registers.set_16bit_index(true);
let instruction = TXS16{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.sp, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TXY";
pub struct TXY8 {}
impl CPUInstruction for TXY8 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.x as u8;
registers.set_low_y(result);
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TXY8 {
fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME)
}
}
pub struct TXY16 {}
impl CPUInstruction for TXY16 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.x;
registers.y = result;
registers.set_negative_flag((result >> 15) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TXY16 {
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_8bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.y = 0x0000;
registers.x = 0xF0F0;
registers.set_16bit_index(false);
let instruction = TXY8{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.y, 0x00F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
#[test]
fn test_16bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.y = 0x0000;
registers.x = 0xF0F0;
registers.set_16bit_index(true);
let instruction = TXY16{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.y, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}
+82
View File
@@ -0,0 +1,82 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TYA";
pub struct TYA8 {}
impl CPUInstruction for TYA8 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.y as u8;
registers.set_low_a(result);
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TYA8 {
fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME)
}
}
pub struct TYA16 {}
impl CPUInstruction for TYA16 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
registers.a = registers.y;
registers.set_negative_flag((registers.a >> 15) == 1);
registers.set_zero_flag(registers.a == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TYA16 {
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_8bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.a = 0x0000;
registers.y = 0xF0F0;
registers.set_16bit_mode(false);
let instruction = TYA8{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0x00F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
#[test]
fn test_16bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.a = 0x0000;
registers.y = 0xF0F0;
registers.set_16bit_mode(true);
let instruction = TYA16{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.a, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::cpu::cycles;
use crate::cpu::{bus::Bus, registers::Registers};
use super::{CPUInstruction, Decode};
use super::decoder_common;
static INSTR_NAME: &'static str = "TYX";
pub struct TYX8 {}
impl CPUInstruction for TYX8 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.y as u8;
registers.set_low_x(result);
registers.set_negative_flag((result >> 7) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TYX8 {
fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String {
decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME)
}
}
pub struct TYX16 {}
impl CPUInstruction for TYX16 {
fn execute(&self, registers: &mut Registers, _bus: &mut Bus) {
let result = registers.y;
registers.x = result;
registers.set_negative_flag((result >> 15) == 1);
registers.set_zero_flag(result == 0);
let (bytes, cycles) = cycles::increment_cycles_transfer();
registers.increment_pc(bytes); registers.cycles += cycles;
}
}
impl Decode for TYX16 {
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_8bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.x = 0x0000;
registers.y = 0xF0F0;
registers.set_16bit_index(false);
let instruction = TYX8{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.x, 0x00F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
#[test]
fn test_16bit() {
let mut registers = Registers::new();
let mut bus = Bus::new();
registers.emulation_mode = false;
registers.pc = 0x0000;
registers.x = 0x0000;
registers.y = 0xF0F0;
registers.set_16bit_index(true);
let instruction = TYX16{};
instruction.execute(&mut registers, &mut bus);
assert_eq!(registers.x, 0xF0F0);
assert_eq!(registers.pc, 0x0001);
assert_eq!(registers.cycles, 2);
}
}