16-bit exchange instructions

This commit is contained in:
Martin Löffler 2023-01-28 06:26:37 +01:00
parent 8b86db359e
commit 01b87ade6d
Signed by: FatalErrorCoded
GPG key ID: FFEF368AC076566A
2 changed files with 31 additions and 0 deletions

View file

@ -38,12 +38,38 @@ pub fn lhld(address: u16, state: &mut EmulatorState) {
state.h = state.memory[address as usize + 1]; state.h = state.memory[address as usize + 1];
} }
/// Exchange the HL register pair with the value at the top of the stack
pub fn xthl(state: &mut EmulatorState) {
let at_hl = get_register_pair(Register::H, state);
let at_stack = state.read_word(state.sp);
// Set HL to the 16-bit value currently on top of the stack
set_register_pair(Register::H, at_stack, state);
// Set the 16-bit word at the current stack position to what HL was
state.write_word(state.sp, at_hl);
}
/// Load the stack pointer from the HL register pair
pub fn sphl(state: &mut EmulatorState) {
state.sp = get_register_pair(Register::H, state);
}
/// Exchange the HL and DE register pairs
pub fn xchg(state: &mut EmulatorState) {
let at_hl = get_register_pair(Register::H, state);
let at_de = get_register_pair(Register::D, state);
// Set HL to DE
set_register_pair(Register::H, at_de, state);
// Set DE to previous value of HL
set_register_pair(Register::D, at_hl, state);
}
/* STACK */ /* STACK */
/// Push a 16-bit value from a register pair onto the stack /// Push a 16-bit value from a register pair onto the stack
pub fn push_reg(register: Register, state: &mut EmulatorState) { pub fn push_reg(register: Register, state: &mut EmulatorState) {
push(get_register_pair(register, state), state); push(get_register_pair(register, state), state);
} }
/// Push a 16-bit value onto the stack
pub fn push(value: u16, state: &mut EmulatorState) { pub fn push(value: u16, state: &mut EmulatorState) {
(state.sp, ..) = state.sp.overflowing_sub(2); (state.sp, ..) = state.sp.overflowing_sub(2);
state.write_word(state.sp, value); state.write_word(state.sp, value);
@ -54,6 +80,7 @@ pub fn pop_reg(register: Register, state: &mut EmulatorState) {
set_register_pair(register, pop(state), state); set_register_pair(register, pop(state), state);
} }
/// Pop a 16-bit value from the stack
pub fn pop(state: &mut EmulatorState) -> u16 { pub fn pop(state: &mut EmulatorState) -> u16 {
let value = state.read_word(state.sp); let value = state.read_word(state.sp);
(state.sp, ..) = state.sp.overflowing_add(2); (state.sp, ..) = state.sp.overflowing_add(2);

View file

@ -80,6 +80,10 @@ fn tick(state: &mut EmulatorState) {
0x22 => transfer::shld(state.next_word(), state), // SHLD 0x22 => transfer::shld(state.next_word(), state), // SHLD
0x2a => transfer::lhld(state.next_word(), state), // LHLD 0x2a => transfer::lhld(state.next_word(), state), // LHLD
0xe3 => transfer::xthl(state),
0xeb => transfer::xchg(state),
0xf9 => transfer::sphl(state),
// Stack instructions // Stack instructions
0xc1 => transfer::pop_reg(Register::B, state), // POP B 0xc1 => transfer::pop_reg(Register::B, state), // POP B
0xc5 => transfer::push_reg(Register::B, state), // PUSH B 0xc5 => transfer::push_reg(Register::B, state), // PUSH B