diff --git a/src/emulator/instructions/transfer.rs b/src/emulator/instructions/transfer.rs index 4075ac6..2c1f8a1 100644 --- a/src/emulator/instructions/transfer.rs +++ b/src/emulator/instructions/transfer.rs @@ -38,12 +38,38 @@ pub fn lhld(address: u16, state: &mut EmulatorState) { 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 */ /// Push a 16-bit value from a register pair onto the stack pub fn push_reg(register: Register, state: &mut EmulatorState) { push(get_register_pair(register, state), state); } +/// Push a 16-bit value onto the stack pub fn push(value: u16, state: &mut EmulatorState) { (state.sp, ..) = state.sp.overflowing_sub(2); 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); } +/// Pop a 16-bit value from the stack pub fn pop(state: &mut EmulatorState) -> u16 { let value = state.read_word(state.sp); (state.sp, ..) = state.sp.overflowing_add(2); diff --git a/src/emulator/main.rs b/src/emulator/main.rs index d2aa2b9..001fff0 100644 --- a/src/emulator/main.rs +++ b/src/emulator/main.rs @@ -80,6 +80,10 @@ fn tick(state: &mut EmulatorState) { 0x22 => transfer::shld(state.next_word(), state), // SHLD 0x2a => transfer::lhld(state.next_word(), state), // LHLD + 0xe3 => transfer::xthl(state), + 0xeb => transfer::xchg(state), + 0xf9 => transfer::sphl(state), + // Stack instructions 0xc1 => transfer::pop_reg(Register::B, state), // POP B 0xc5 => transfer::push_reg(Register::B, state), // PUSH B