feat: push pop opcodes

This commit is contained in:
EliseZeroTwo 2021-11-28 19:26:30 +01:00
parent c7fefe86ca
commit c2ff461ae8
No known key found for this signature in database
GPG key ID: E6D56A6F7B7991DE
2 changed files with 66 additions and 8 deletions

View file

@ -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),

View file

@ -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);