feat: push pop opcodes
This commit is contained in:
parent
c7fefe86ca
commit
c2ff461ae8
2 changed files with 66 additions and 8 deletions
|
@ -239,9 +239,11 @@ pub fn tick_cpu(state: &mut Gameboy) {
|
|||
0xAE => alu::xor_a_deref_hl,
|
||||
0xAF => alu::xor_a_a,
|
||||
0xC0 => flow::ret_nz,
|
||||
0xC1 => load_store_move::pop_bc,
|
||||
0xC2 => flow::jp_nz_u16,
|
||||
0xC3 => flow::jp_u16,
|
||||
0xC4 => flow::call_nz_u16,
|
||||
0xC5 => load_store_move::push_bc,
|
||||
0xC8 => flow::ret_z,
|
||||
0xC9 => flow::ret,
|
||||
0xCA => flow::jp_z_u16,
|
||||
|
@ -249,20 +251,26 @@ pub fn tick_cpu(state: &mut Gameboy) {
|
|||
0xCC => flow::call_z_u16,
|
||||
0xCD => flow::call_u16,
|
||||
0xD0 => flow::ret_nc,
|
||||
0xD1 => load_store_move::pop_de,
|
||||
0xD2 => flow::jp_nc_u16,
|
||||
0xD4 => flow::call_nc_u16,
|
||||
0xD5 => load_store_move::push_de,
|
||||
0xD8 => flow::ret_c,
|
||||
0xD9 => flow::reti,
|
||||
0xDA => flow::jp_c_u16,
|
||||
0xDC => flow::call_c_u16,
|
||||
0xDE => alu::sbc_a_imm_u8,
|
||||
0xE0 => load_store_move::ldh_imm_u8_a,
|
||||
0xE1 => load_store_move::pop_hl,
|
||||
0xE2 => load_store_move::ldh_deref_c_a,
|
||||
0xE5 => load_store_move::push_hl,
|
||||
0xE9 => flow::jp_hl,
|
||||
0xEA => load_store_move::ld_deref_imm_u16_a,
|
||||
0xEE => alu::xor_a_imm_u8,
|
||||
0xF0 => load_store_move::ldh_a_imm_u8,
|
||||
0xF1 => load_store_move::pop_af,
|
||||
0xF2 => load_store_move::ldh_a_deref_c,
|
||||
0xF5 => load_store_move::push_af,
|
||||
0xF9 => load_store_move::ld_sp_hl,
|
||||
0xFA => load_store_move::ld_a_deref_imm_u16,
|
||||
unknown => panic!("Unrecognized opcode: {:#X}\nRegisters: {:#?}", unknown, state.registers),
|
||||
|
|
|
@ -381,7 +381,7 @@ pub fn ld_deref_imm_u16_a(state: &mut Gameboy) -> CycleResult {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! define_ld_reg_imm_u8 {
|
||||
macro_rules! define_ld_deref_hl_reg {
|
||||
($lreg:ident) => {
|
||||
paste::paste! {
|
||||
pub fn [<ld_deref_hl_ $lreg>](state: &mut Gameboy) -> CycleResult {
|
||||
|
@ -399,10 +399,60 @@ macro_rules! define_ld_reg_imm_u8 {
|
|||
};
|
||||
}
|
||||
|
||||
define_ld_reg_imm_u8!(b);
|
||||
define_ld_reg_imm_u8!(c);
|
||||
define_ld_reg_imm_u8!(d);
|
||||
define_ld_reg_imm_u8!(e);
|
||||
define_ld_reg_imm_u8!(h);
|
||||
define_ld_reg_imm_u8!(l);
|
||||
define_ld_reg_imm_u8!(a);
|
||||
define_ld_deref_hl_reg!(b);
|
||||
define_ld_deref_hl_reg!(c);
|
||||
define_ld_deref_hl_reg!(d);
|
||||
define_ld_deref_hl_reg!(e);
|
||||
define_ld_deref_hl_reg!(h);
|
||||
define_ld_deref_hl_reg!(l);
|
||||
define_ld_deref_hl_reg!(a);
|
||||
|
||||
macro_rules! define_push_pop_reg {
|
||||
($reg:ident) => {
|
||||
paste::paste! {
|
||||
pub fn [<push_ $reg>](state: &mut Gameboy) -> CycleResult {
|
||||
match state.registers.cycle {
|
||||
0 => CycleResult::NeedsMore,
|
||||
1 => {
|
||||
state.cpu_push_stack((state.registers.[<get_ $reg>]() >> 8) as u8);
|
||||
CycleResult::NeedsMore
|
||||
},
|
||||
2 => {
|
||||
state.cpu_push_stack(state.registers.[<get_ $reg>]() as u8);
|
||||
state.registers.opcode_bytecount = Some(1);
|
||||
CycleResult::NeedsMore
|
||||
},
|
||||
3 => CycleResult::Finished,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn [<pop_ $reg>](state: &mut Gameboy) -> CycleResult {
|
||||
match state.registers.cycle {
|
||||
0 => {
|
||||
state.cpu_pop_stack();
|
||||
CycleResult::NeedsMore
|
||||
},
|
||||
1 => {
|
||||
let lsb = state.registers.take_mem() as u16;
|
||||
state.registers.set_hold(lsb);
|
||||
state.cpu_pop_stack();
|
||||
CycleResult::NeedsMore
|
||||
},
|
||||
2 => {
|
||||
let val = (state.registers.take_mem() as u16) << 8 | state.registers.take_hold();
|
||||
state.registers.[<set_ $reg>](val);
|
||||
state.registers.opcode_bytecount = Some(1);
|
||||
CycleResult::Finished
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_push_pop_reg!(bc);
|
||||
define_push_pop_reg!(de);
|
||||
define_push_pop_reg!(hl);
|
||||
define_push_pop_reg!(af);
|
Loading…
Reference in a new issue