Add ACI, DAD
This commit is contained in:
parent
45b4ea8dea
commit
cf4565c36b
|
@ -30,3 +30,26 @@ pub fn adc(register: Register, state: &mut EmulatorState) {
|
||||||
set_cc(state, result, 0b1111);
|
set_cc(state, result, 0b1111);
|
||||||
state.a = (result & 0xff) as u8;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -36,9 +36,11 @@ pub struct ConditionCodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Register {
|
pub enum Register {
|
||||||
B, C, D, E,
|
B, C, D, E,
|
||||||
H, L, M, A,
|
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
|
/// 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::L => state.l as u16,
|
||||||
Register::A => state.a 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::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::L => state.l = value,
|
||||||
Register::A => state.a = value,
|
Register::A => state.a = value,
|
||||||
Register::M => panic!("Cannot set pseudoregister 'M'"),
|
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 {
|
match instruction {
|
||||||
0x00 => {} // NOP
|
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
|
0x80..=0x87 => arithmetic::add(register_from_num(instruction & 0xf), state), // ADD
|
||||||
0x88..=0x8f => arithmetic::adc(register_from_num(instruction & 0xf), state), // ADC
|
0x88..=0x8f => arithmetic::adc(register_from_num(instruction & 0xf), state), // ADC
|
||||||
0xc6 => arithmetic::adi(next_byte(), state), // ADI
|
0xc6 => arithmetic::adi(next_byte(), state), // ADI
|
||||||
|
0xce => arithmetic::aci(next_byte(), state), // ACI
|
||||||
_ => not_implemented(state),
|
_ => not_implemented(state),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue