forked from Lea/invadeez
accumulator transfer instructions
This commit is contained in:
parent
6abdd5dff3
commit
2fff8d2448
|
@ -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) {
|
pub fn mov(src: Register, dest: Register, state: &mut EmulatorState) {
|
||||||
let data = get_register(src, state);
|
let data = get_register(src, state);
|
||||||
set_register(dest, data, state);
|
set_register(dest, data, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Move immediate into destination register
|
||||||
pub fn mvi(byte: u8, dest: Register, state: &mut EmulatorState) {
|
pub fn mvi(byte: u8, dest: Register, state: &mut EmulatorState) {
|
||||||
set_register(dest, byte, state);
|
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];
|
||||||
|
}
|
||||||
|
|
|
@ -50,11 +50,6 @@ fn main() {
|
||||||
fn tick(state: &mut EmulatorState) {
|
fn tick(state: &mut EmulatorState) {
|
||||||
let instruction = state.memory[state.pc as usize];
|
let instruction = state.memory[state.pc as usize];
|
||||||
|
|
||||||
let mut next_byte = || {
|
|
||||||
state.pc += 1;
|
|
||||||
state.memory[state.pc as usize]
|
|
||||||
};
|
|
||||||
|
|
||||||
match instruction {
|
match instruction {
|
||||||
0x00 => {} // NOP
|
0x00 => {} // NOP
|
||||||
|
|
||||||
|
@ -75,7 +70,7 @@ fn tick(state: &mut EmulatorState) {
|
||||||
/* Data Transfer */
|
/* Data Transfer */
|
||||||
// MVI
|
// MVI
|
||||||
0x06 | 0x0e | 0x16 | 0x1e | 0x26 | 0x2e | 0x36 | 0x3e => transfer::mvi(
|
0x06 | 0x0e | 0x16 | 0x1e | 0x26 | 0x2e | 0x36 | 0x3e => transfer::mvi(
|
||||||
next_byte(),
|
state.next_byte(),
|
||||||
register_from_num((instruction & 0x38) >> 3),
|
register_from_num((instruction & 0x38) >> 3),
|
||||||
state,
|
state,
|
||||||
),
|
),
|
||||||
|
@ -87,6 +82,14 @@ fn tick(state: &mut EmulatorState) {
|
||||||
state,
|
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 */
|
/* Maths */
|
||||||
// INR
|
// INR
|
||||||
0x04 => arithmetic::inr(Register::B, state),
|
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
|
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
|
0x88..=0x8f => arithmetic::add_reg(register_from_num(instruction & 0x7), state.cc.c, state), // ADC
|
||||||
0xc6 => arithmetic::add(next_byte(), false, state), // ADI
|
0xc6 => arithmetic::add(state.next_byte(), false, state), // ADI
|
||||||
0xce => arithmetic::add(next_byte(), state.cc.c, state), // ACI
|
0xce => arithmetic::add(state.next_byte(), state.cc.c, state), // ACI
|
||||||
|
|
||||||
0x90..=0x97 => arithmetic::sub_reg(register_from_num(instruction & 0x7), false, state), // SUB
|
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
|
0x98..=0x9f => arithmetic::sub_reg(register_from_num(instruction & 0x7), state.cc.c, state), // SBB
|
||||||
0xd6 => arithmetic::sub(next_byte(), false, state), // SUI
|
0xd6 => arithmetic::sub(state.next_byte(), false, state), // SUI
|
||||||
0xde => arithmetic::sub(next_byte(), state.cc.c, state), // SBI
|
0xde => arithmetic::sub(state.next_byte(), state.cc.c, state), // SBI
|
||||||
|
|
||||||
0xa0..=0xa7 => arithmetic::and_reg(register_from_num(instruction & 0x7), state), // ANA
|
0xa0..=0xa7 => arithmetic::and_reg(register_from_num(instruction & 0x7), state), // ANA
|
||||||
0xa8..=0xaf => arithmetic::xor_reg(register_from_num(instruction & 0x7), state), // XRA
|
0xa8..=0xaf => arithmetic::xor_reg(register_from_num(instruction & 0x7), state), // XRA
|
||||||
0xb0..=0xb7 => arithmetic::or_reg(register_from_num(instruction & 0x7), state), // ORA
|
0xb0..=0xb7 => arithmetic::or_reg(register_from_num(instruction & 0x7), state), // ORA
|
||||||
0xb8..=0xbf => arithmetic::cmp_reg(register_from_num(instruction & 0x7), state), // CMP
|
0xb8..=0xbf => arithmetic::cmp_reg(register_from_num(instruction & 0x7), state), // CMP
|
||||||
0xe6 => arithmetic::and(next_byte(), state), // ANI
|
0xe6 => arithmetic::and(state.next_byte(), state), // ANI
|
||||||
0xee => arithmetic::xor(next_byte(), state), // XRI
|
0xee => arithmetic::xor(state.next_byte(), state), // XRI
|
||||||
0xf6 => arithmetic::or(next_byte(), state), // ORI
|
0xf6 => arithmetic::or(state.next_byte(), state), // ORI
|
||||||
0xfe => arithmetic::cmp(next_byte(), state), // CPI
|
0xfe => arithmetic::cmp(state.next_byte(), state), // CPI
|
||||||
|
|
||||||
_ => not_implemented(state),
|
_ => not_implemented(state),
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,23 @@ pub struct EmulatorState {
|
||||||
pub memory: [u8; MEMORY_SIZE],
|
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)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub struct ConditionCodes {
|
pub struct ConditionCodes {
|
||||||
/// Zero (Z), set if the result is zero.
|
/// Zero (Z), set if the result is zero.
|
||||||
|
|
Loading…
Reference in a new issue