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,
|
0xAE => alu::xor_a_deref_hl,
|
||||||
0xAF => alu::xor_a_a,
|
0xAF => alu::xor_a_a,
|
||||||
0xC0 => flow::ret_nz,
|
0xC0 => flow::ret_nz,
|
||||||
|
0xC1 => load_store_move::pop_bc,
|
||||||
0xC2 => flow::jp_nz_u16,
|
0xC2 => flow::jp_nz_u16,
|
||||||
0xC3 => flow::jp_u16,
|
0xC3 => flow::jp_u16,
|
||||||
0xC4 => flow::call_nz_u16,
|
0xC4 => flow::call_nz_u16,
|
||||||
|
0xC5 => load_store_move::push_bc,
|
||||||
0xC8 => flow::ret_z,
|
0xC8 => flow::ret_z,
|
||||||
0xC9 => flow::ret,
|
0xC9 => flow::ret,
|
||||||
0xCA => flow::jp_z_u16,
|
0xCA => flow::jp_z_u16,
|
||||||
|
@ -249,20 +251,26 @@ pub fn tick_cpu(state: &mut Gameboy) {
|
||||||
0xCC => flow::call_z_u16,
|
0xCC => flow::call_z_u16,
|
||||||
0xCD => flow::call_u16,
|
0xCD => flow::call_u16,
|
||||||
0xD0 => flow::ret_nc,
|
0xD0 => flow::ret_nc,
|
||||||
|
0xD1 => load_store_move::pop_de,
|
||||||
0xD2 => flow::jp_nc_u16,
|
0xD2 => flow::jp_nc_u16,
|
||||||
0xD4 => flow::call_nc_u16,
|
0xD4 => flow::call_nc_u16,
|
||||||
|
0xD5 => load_store_move::push_de,
|
||||||
0xD8 => flow::ret_c,
|
0xD8 => flow::ret_c,
|
||||||
0xD9 => flow::reti,
|
0xD9 => flow::reti,
|
||||||
0xDA => flow::jp_c_u16,
|
0xDA => flow::jp_c_u16,
|
||||||
0xDC => flow::call_c_u16,
|
0xDC => flow::call_c_u16,
|
||||||
0xDE => alu::sbc_a_imm_u8,
|
0xDE => alu::sbc_a_imm_u8,
|
||||||
0xE0 => load_store_move::ldh_imm_u8_a,
|
0xE0 => load_store_move::ldh_imm_u8_a,
|
||||||
|
0xE1 => load_store_move::pop_hl,
|
||||||
0xE2 => load_store_move::ldh_deref_c_a,
|
0xE2 => load_store_move::ldh_deref_c_a,
|
||||||
|
0xE5 => load_store_move::push_hl,
|
||||||
0xE9 => flow::jp_hl,
|
0xE9 => flow::jp_hl,
|
||||||
0xEA => load_store_move::ld_deref_imm_u16_a,
|
0xEA => load_store_move::ld_deref_imm_u16_a,
|
||||||
0xEE => alu::xor_a_imm_u8,
|
0xEE => alu::xor_a_imm_u8,
|
||||||
0xF0 => load_store_move::ldh_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,
|
0xF2 => load_store_move::ldh_a_deref_c,
|
||||||
|
0xF5 => load_store_move::push_af,
|
||||||
0xF9 => load_store_move::ld_sp_hl,
|
0xF9 => load_store_move::ld_sp_hl,
|
||||||
0xFA => load_store_move::ld_a_deref_imm_u16,
|
0xFA => load_store_move::ld_a_deref_imm_u16,
|
||||||
unknown => panic!("Unrecognized opcode: {:#X}\nRegisters: {:#?}", unknown, state.registers),
|
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) => {
|
($lreg:ident) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
pub fn [<ld_deref_hl_ $lreg>](state: &mut Gameboy) -> CycleResult {
|
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_deref_hl_reg!(b);
|
||||||
define_ld_reg_imm_u8!(c);
|
define_ld_deref_hl_reg!(c);
|
||||||
define_ld_reg_imm_u8!(d);
|
define_ld_deref_hl_reg!(d);
|
||||||
define_ld_reg_imm_u8!(e);
|
define_ld_deref_hl_reg!(e);
|
||||||
define_ld_reg_imm_u8!(h);
|
define_ld_deref_hl_reg!(h);
|
||||||
define_ld_reg_imm_u8!(l);
|
define_ld_deref_hl_reg!(l);
|
||||||
define_ld_reg_imm_u8!(a);
|
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