From cf4565c36bb6cc81391be637f30e18fecbb00ae8 Mon Sep 17 00:00:00 2001 From: Lea Date: Wed, 25 Jan 2023 16:24:39 +0100 Subject: [PATCH] Add ACI, DAD --- src/emulator/instructions/arithmetic.rs | 23 +++++++++++++++++++++++ src/emulator/main.rs | 14 ++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/emulator/instructions/arithmetic.rs b/src/emulator/instructions/arithmetic.rs index aa2df4e..2baf4dd 100644 --- a/src/emulator/instructions/arithmetic.rs +++ b/src/emulator/instructions/arithmetic.rs @@ -30,3 +30,26 @@ pub fn adc(register: Register, state: &mut EmulatorState) { set_cc(state, result, 0b1111); state.a = (result & 0xff) as u8; } + +/// Add values of input byte and `A` and add +1 if carry bit is set +pub fn aci(byte: u8, state: &mut EmulatorState) { + let result = state.a as u16 + byte as u16 + if state.cc.c { 1 } else { 0 }; + set_cc(state, result, 0b1111); + state.a = result as u8; +} + +/// Double precision add - Add B&C, D&E or H&L to H&L +pub fn dad(register: Register, state: &mut EmulatorState) { + let num = match register { + Register::B => (state.b as u16) << 8 | state.c as u16, + Register::D => (state.d as u16) << 8 | state.e as u16, + Register::H => get_register(Register::M, state), + Register::SP => state.sp, + _ => panic!("Cannot perform DAD on register {:?}", register), + }; + + let result = num as u32 + get_register(Register::M, state) as u32; + state.cc.c = result > 0xffff; + state.h = (result >> 8) as u8; + state.l = result as u8; +} diff --git a/src/emulator/main.rs b/src/emulator/main.rs index eed3021..e3b3e43 100644 --- a/src/emulator/main.rs +++ b/src/emulator/main.rs @@ -36,9 +36,11 @@ pub struct ConditionCodes { } #[derive(PartialEq)] +#[derive(Debug)] pub enum Register { B, C, D, E, H, L, M, A, + SP, } /// Returns a Register enum based on the input number 0..7 in the order B,C,D,E,H,L,M,A @@ -66,6 +68,7 @@ fn get_register(register: Register, state: &EmulatorState) -> u16 { Register::L => state.l as u16, Register::A => state.a as u16, Register::M => (state.memory[(state.h as usize)] as u16) << 8 | (state.memory[state.l as usize] as u16), + Register::SP => state.sp, } } @@ -79,6 +82,7 @@ fn set_register(register: Register, value: u8, state: &mut EmulatorState) { Register::L => state.l = value, Register::A => state.a = value, Register::M => panic!("Cannot set pseudoregister 'M'"), + Register::SP => panic!("Cannot set 'SP' through set_register()"), }; } @@ -123,9 +127,19 @@ fn tick(state: &mut EmulatorState) { match instruction { 0x00 => {} // NOP + + /* ADD */ + + // DAD + 0x09 => arithmetic::dad(Register::B, state), + 0x19 => arithmetic::dad(Register::D, state), + 0x29 => arithmetic::dad(Register::H, state), + 0x39 => arithmetic::dad(Register::SP, state), + 0x80..=0x87 => arithmetic::add(register_from_num(instruction & 0xf), state), // ADD 0x88..=0x8f => arithmetic::adc(register_from_num(instruction & 0xf), state), // ADC 0xc6 => arithmetic::adi(next_byte(), state), // ADI + 0xce => arithmetic::aci(next_byte(), state), // ACI _ => not_implemented(state), }