From 0e4326673b5302299f2206f3ee3ae91502c6d403 Mon Sep 17 00:00:00 2001 From: EliseZeroTwo Date: Sun, 28 Nov 2021 16:28:26 +0100 Subject: [PATCH] feat: impl ld imm u8 opcodes --- src/gameboy/cpu.rs | 10 ++- src/gameboy/cpu/load_store_move.rs | 118 ++++++++++++++++------------- 2 files changed, 73 insertions(+), 55 deletions(-) diff --git a/src/gameboy/cpu.rs b/src/gameboy/cpu.rs index 2e4cd35..4f7a4ca 100644 --- a/src/gameboy/cpu.rs +++ b/src/gameboy/cpu.rs @@ -120,21 +120,29 @@ pub fn tick_cpu(state: &mut Gameboy) { let instruction_result: CycleResult = match opcode { 0x01 => load_store_move::ld_bc_imm_u16, + 0x06 => load_store_move::ld_b_imm_u8, 0x08 => load_store_move::ld_deref_imm_u16_sp, 0x0a => load_store_move::ld_a_deref_bc, + 0x0e => load_store_move::ld_c_imm_u8, 0x11 => load_store_move::ld_de_imm_u16, + 0x16 => load_store_move::ld_d_imm_u8, 0x18 => flow::jr_i8, 0x1a => load_store_move::ld_a_deref_de, + 0x1e => load_store_move::ld_e_imm_u8, 0x20 => flow::jr_nz_i8, 0x21 => load_store_move::ld_hl_imm_u16, 0x22 => load_store_move::ld_hl_plus_a, + 0x26 => load_store_move::ld_h_imm_u8, 0x28 => flow::jr_z_i8, 0x2a => load_store_move::ld_a_hl_plus, + 0x2e => load_store_move::ld_l_imm_u8, 0x30 => flow::jr_nc_i8, + 0x31 => load_store_move::ld_sp_imm_u16, 0x32 => load_store_move::ld_hl_minus_a, + 0x36 => load_store_move::ld_deref_hl_imm_u8, 0x38 => flow::jr_c_i8, 0x3a => load_store_move::ld_a_hl_minus, - 0x31 => load_store_move::ld_sp_imm_u16, + 0x3e => load_store_move::ld_a_imm_u8, 0x40 => load_store_move::ld_b_b, 0x41 => load_store_move::ld_b_c, 0x42 => load_store_move::ld_b_d, diff --git a/src/gameboy/cpu/load_store_move.rs b/src/gameboy/cpu/load_store_move.rs index 4ef504b..c1e4d17 100644 --- a/src/gameboy/cpu/load_store_move.rs +++ b/src/gameboy/cpu/load_store_move.rs @@ -100,61 +100,25 @@ macro_rules! define_ld_reg_reg { }; } -define_ld_reg_reg!(b, b); -define_ld_reg_reg!(b, c); -define_ld_reg_reg!(b, d); -define_ld_reg_reg!(b, e); -define_ld_reg_reg!(b, h); -define_ld_reg_reg!(b, l); -define_ld_reg_reg!(b, a); +macro_rules! define_ld_reg_regs { + ($lreg:ident) => { + define_ld_reg_reg!($lreg, b); + define_ld_reg_reg!($lreg, c); + define_ld_reg_reg!($lreg, d); + define_ld_reg_reg!($lreg, e); + define_ld_reg_reg!($lreg, h); + define_ld_reg_reg!($lreg, l); + define_ld_reg_reg!($lreg, a); + }; +} -define_ld_reg_reg!(c, b); -define_ld_reg_reg!(c, c); -define_ld_reg_reg!(c, d); -define_ld_reg_reg!(c, e); -define_ld_reg_reg!(c, h); -define_ld_reg_reg!(c, l); -define_ld_reg_reg!(c, a); - -define_ld_reg_reg!(d, b); -define_ld_reg_reg!(d, c); -define_ld_reg_reg!(d, d); -define_ld_reg_reg!(d, e); -define_ld_reg_reg!(d, h); -define_ld_reg_reg!(d, l); -define_ld_reg_reg!(d, a); - -define_ld_reg_reg!(e, b); -define_ld_reg_reg!(e, c); -define_ld_reg_reg!(e, d); -define_ld_reg_reg!(e, e); -define_ld_reg_reg!(e, h); -define_ld_reg_reg!(e, l); -define_ld_reg_reg!(e, a); - -define_ld_reg_reg!(h, b); -define_ld_reg_reg!(h, c); -define_ld_reg_reg!(h, d); -define_ld_reg_reg!(h, e); -define_ld_reg_reg!(h, h); -define_ld_reg_reg!(h, l); -define_ld_reg_reg!(h, a); - -define_ld_reg_reg!(l, b); -define_ld_reg_reg!(l, c); -define_ld_reg_reg!(l, d); -define_ld_reg_reg!(l, e); -define_ld_reg_reg!(l, h); -define_ld_reg_reg!(l, l); -define_ld_reg_reg!(l, a); - -define_ld_reg_reg!(a, b); -define_ld_reg_reg!(a, c); -define_ld_reg_reg!(a, d); -define_ld_reg_reg!(a, e); -define_ld_reg_reg!(a, h); -define_ld_reg_reg!(a, l); -define_ld_reg_reg!(a, a); +define_ld_reg_regs!(b); +define_ld_reg_regs!(c); +define_ld_reg_regs!(d); +define_ld_reg_regs!(e); +define_ld_reg_regs!(h); +define_ld_reg_regs!(l); +define_ld_reg_regs!(a); macro_rules! define_ld_reg_deref { ($lreg:ident, $rreg:ident) => { @@ -252,3 +216,49 @@ pub fn ld_a_hl_plus(state: &mut Gameboy) -> CycleResult { _ => unreachable!(), } } + +macro_rules! define_ld_reg_imm_u8 { + ($lreg:ident) => { + paste::paste! { + pub fn [](state: &mut Gameboy) -> CycleResult { + match state.registers.cycle { + 0 => { + state.cpu_read_u8(state.registers.pc.overflowing_add(1).0); + CycleResult::NeedsMore + }, + 1 => { + state.registers.$lreg = state.registers.take_mem(); + state.registers.opcode_bytecount = Some(2); + CycleResult::Finished + }, + _ => unreachable!(), + } + } + } + }; +} + +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); + +pub fn ld_deref_hl_imm_u8(state: &mut Gameboy) -> CycleResult { + match state.registers.cycle { + 0 => { + state.cpu_read_u8(state.registers.pc.overflowing_add(1).0); + CycleResult::NeedsMore + } + 1 => { + let imm = state.registers.take_mem(); + state.cpu_write_u8(state.registers.get_hl(), imm); + state.registers.opcode_bytecount = Some(2); + CycleResult::NeedsMore + } + 2 => CycleResult::Finished, + _ => unreachable!(), + } +}