invadeez/src/emulator/instructions/branch.rs
2023-01-28 23:43:16 +01:00

54 lines
1.6 KiB
Rust

use crate::mapper::MemoryMapper;
use crate::transfer::{pop, push};
use crate::{get_register_pair, EmulatorState, Register};
/// Jump (set PC) to specified address
pub fn jump<M: MemoryMapper>(address: u16, state: &mut EmulatorState<M>) {
state.pc = address;
}
/// Jump to a specified address only if `cond` is true
pub fn jump_cond<M: MemoryMapper>(address: u16, cond: bool, state: &mut EmulatorState<M>) {
if cond {
jump(address, state);
}
}
/// Push the current PC to the stack and jump to the specified address
pub fn call<M: MemoryMapper>(address: u16, state: &mut EmulatorState<M>) {
push(state.pc, state);
jump(address, state);
}
// Push the current PC to the stack and jump to the specified address if `cond` is true
pub fn call_cond<M: MemoryMapper>(address: u16, cond: bool, state: &mut EmulatorState<M>) {
if cond {
call(address, state);
}
}
// Pop a value from the stack and jump to it
pub fn ret<M: MemoryMapper>(state: &mut EmulatorState<M>) {
jump(pop(state), state);
}
// Pop a value from the stack and jump to it if `cond` is true
pub fn ret_cond<M: MemoryMapper>(cond: bool, state: &mut EmulatorState<M>) {
if cond {
ret(state)
}
}
/// "Restart" at (call) a specific interrupt vector
///
/// Panics if `vector` is 8 or above
pub fn restart<M: MemoryMapper>(vector: u8, state: &mut EmulatorState<M>) {
assert!(vector < 8, "Illegal restart vector");
call((vector * 8) as u16, state);
}
/// Load a new program counter from the HL register pair
pub fn pchl<M: MemoryMapper>(state: &mut EmulatorState<M>) {
state.pc = get_register_pair(Register::H, state);
}