From 2fff8d2448de0e493614b7425240c35cb93a59f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20L=C3=B6ffler?= Date: Thu, 26 Jan 2023 06:02:11 +0100 Subject: [PATCH] accumulator transfer instructions --- src/emulator/instructions/transfer.rs | 16 +++++++++++++- src/emulator/main.rs | 31 +++++++++++++++------------ src/emulator/structs.rs | 17 +++++++++++++++ 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/emulator/instructions/transfer.rs b/src/emulator/instructions/transfer.rs index e39251c..9af545d 100644 --- a/src/emulator/instructions/transfer.rs +++ b/src/emulator/instructions/transfer.rs @@ -1,10 +1,24 @@ -use crate::{get_register, set_register, EmulatorState, Register}; +use crate::{get_register, set_register, structs::get_register_pair, EmulatorState, Register}; +/// Move (copy) value from source to destination register pub fn mov(src: Register, dest: Register, state: &mut EmulatorState) { let data = get_register(src, state); set_register(dest, data, state); } +/// Move immediate into destination register pub fn mvi(byte: u8, dest: Register, state: &mut EmulatorState) { set_register(dest, byte, state); } + +/// Store accumulator using the BC or DE register pair +pub fn stax(register: Register, state: &mut EmulatorState) { + let address = get_register_pair(register, state); + state.memory[address as usize] = state.a; +} + +/// Load accumulator using the BC or DE register pair +pub fn ldax(register: Register, state: &mut EmulatorState) { + let address = get_register_pair(register, state); + state.a = state.memory[address as usize]; +} diff --git a/src/emulator/main.rs b/src/emulator/main.rs index 6f6bf3c..abfe264 100644 --- a/src/emulator/main.rs +++ b/src/emulator/main.rs @@ -50,11 +50,6 @@ fn main() { fn tick(state: &mut EmulatorState) { let instruction = state.memory[state.pc as usize]; - let mut next_byte = || { - state.pc += 1; - state.memory[state.pc as usize] - }; - match instruction { 0x00 => {} // NOP @@ -75,7 +70,7 @@ fn tick(state: &mut EmulatorState) { /* Data Transfer */ // MVI 0x06 | 0x0e | 0x16 | 0x1e | 0x26 | 0x2e | 0x36 | 0x3e => transfer::mvi( - next_byte(), + state.next_byte(), register_from_num((instruction & 0x38) >> 3), state, ), @@ -87,6 +82,14 @@ fn tick(state: &mut EmulatorState) { state, ), + // Accumulator transfer instructions + 0x02 => transfer::stax(Register::B, state), // STAX B + 0x0a => transfer::ldax(Register::B, state), // LDAX B + 0x12 => transfer::stax(Register::D, state), // STAX D + 0x1a => transfer::ldax(Register::D, state), // LDAX D + 0x32 => state.memory[state.next_word() as usize] = state.a, // STA + 0x3a => state.a = state.memory[state.next_word() as usize], // LDA + /* Maths */ // INR 0x04 => arithmetic::inr(Register::B, state), @@ -140,22 +143,22 @@ fn tick(state: &mut EmulatorState) { 0x80..=0x87 => arithmetic::add_reg(register_from_num(instruction & 0x7), false, state), // ADD 0x88..=0x8f => arithmetic::add_reg(register_from_num(instruction & 0x7), state.cc.c, state), // ADC - 0xc6 => arithmetic::add(next_byte(), false, state), // ADI - 0xce => arithmetic::add(next_byte(), state.cc.c, state), // ACI + 0xc6 => arithmetic::add(state.next_byte(), false, state), // ADI + 0xce => arithmetic::add(state.next_byte(), state.cc.c, state), // ACI 0x90..=0x97 => arithmetic::sub_reg(register_from_num(instruction & 0x7), false, state), // SUB 0x98..=0x9f => arithmetic::sub_reg(register_from_num(instruction & 0x7), state.cc.c, state), // SBB - 0xd6 => arithmetic::sub(next_byte(), false, state), // SUI - 0xde => arithmetic::sub(next_byte(), state.cc.c, state), // SBI + 0xd6 => arithmetic::sub(state.next_byte(), false, state), // SUI + 0xde => arithmetic::sub(state.next_byte(), state.cc.c, state), // SBI 0xa0..=0xa7 => arithmetic::and_reg(register_from_num(instruction & 0x7), state), // ANA 0xa8..=0xaf => arithmetic::xor_reg(register_from_num(instruction & 0x7), state), // XRA 0xb0..=0xb7 => arithmetic::or_reg(register_from_num(instruction & 0x7), state), // ORA 0xb8..=0xbf => arithmetic::cmp_reg(register_from_num(instruction & 0x7), state), // CMP - 0xe6 => arithmetic::and(next_byte(), state), // ANI - 0xee => arithmetic::xor(next_byte(), state), // XRI - 0xf6 => arithmetic::or(next_byte(), state), // ORI - 0xfe => arithmetic::cmp(next_byte(), state), // CPI + 0xe6 => arithmetic::and(state.next_byte(), state), // ANI + 0xee => arithmetic::xor(state.next_byte(), state), // XRI + 0xf6 => arithmetic::or(state.next_byte(), state), // ORI + 0xfe => arithmetic::cmp(state.next_byte(), state), // CPI _ => not_implemented(state), } diff --git a/src/emulator/structs.rs b/src/emulator/structs.rs index 7248023..df195c2 100644 --- a/src/emulator/structs.rs +++ b/src/emulator/structs.rs @@ -22,6 +22,23 @@ pub struct EmulatorState { pub memory: [u8; MEMORY_SIZE], } +impl EmulatorState { + // Get the next byte from memory + pub fn next_byte(&mut self) -> u8 { + self.pc += 1; + self.memory[self.pc as usize] + } + + // Get the next 16-bit word from memory, in little endian order + pub fn next_word(&mut self) -> u16 { + self.pc += 2; + u16::from_le_bytes([ + self.memory[self.pc as usize - 1], + self.memory[self.pc as usize], + ]) + } +} + #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ConditionCodes { /// Zero (Z), set if the result is zero.