From 34de965cd504c81b09c9138819c85e3f3369b920 Mon Sep 17 00:00:00 2001 From: 45Tatami Date: Sat, 13 Apr 2024 22:20:42 +0200 Subject: [PATCH] ld from hmem and basic cmp --- src/emu.rs | 32 +++++++++++++++++++++++++++++--- src/op.rs | 8 ++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/emu.rs b/src/emu.rs index 1a7fb5b..362ba01 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -21,13 +21,16 @@ pub struct GameBoy { bp_manager: BreakPointManager, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] enum Flag { Z, N, H ,CY } fn flag_set(f: Flag, v: u8) -> bool { use Flag::*; + if f == CY || f == H || f == N { + println!("FIXME reading unimplemented flag {f:?}"); + } match f { Z => v << 0 >> 7 == 1, N => v << 1 >> 7 == 1, @@ -120,6 +123,15 @@ impl GameBoy { // no checks for special registers } + fn get_value(&mut self, src: ValSrc) -> u8 { + match src { + ValSrc::Direct => self.mem[self.pc as usize + 1], + ValSrc::Reg(_) => todo!(), + ValSrc::Mem(_) => todo!(), + ValSrc::HMem(_) => todo!() + } + } + pub fn load(&mut self, mut src: T) { let mut buf = Vec::::new(); let _ = src.read_to_end(&mut buf); @@ -199,7 +211,14 @@ impl GameBoy { } AddrLoc::Direct => todo!(), } - ValSrc::HMem(_) => todo!(), + ValSrc::HMem(ref src) => match src { + AddrLoc::Direct => { + println!("FIXME reading from hmem, possibly using an unimplemented feature"); + let offs = self.mem[pc + 1]; + (&mut self.mem[0xFF00 + offs as usize], 0) + } + AddrLoc::Reg(_) => todo!() + } }; let val = *src_ref; @@ -306,7 +325,7 @@ impl GameBoy { }; let regs = &self.reg[..8]; - println!("\u{1B}[1;31mpc:{pc:#08x}:{win:02x?} {op:?} {regs:?}\u{1B}[0m"); + println!("\u{1B}[1;31mpc:{pc:#08x}\u{1B}[0m:{win:02x?} {op:?} {regs:?}"); match op.inst { Unimpl(instr) => { @@ -397,6 +416,13 @@ impl GameBoy { } println!("Dec {dst:?}"); } + Cmp(src) => { + let a = self.reg[Register::A]; + let b = self.get_value(src); + self.set_flag(Flag::N, true); + if a == b { + } + } Ld(dst, src, post_op) => self.op_ld(dst, src, post_op), Ld16(dst, src) => self.op_ld16(dst, src), Bit(bit_op, src) => { diff --git a/src/op.rs b/src/op.rs index cf99894..f68382b 100644 --- a/src/op.rs +++ b/src/op.rs @@ -29,6 +29,7 @@ pub enum Instr { Inc(ValSrc), Dec(ValSrc), Bit(BitOp, ValSrc), + Cmp(ValSrc), // CPU ctl Di, @@ -209,6 +210,8 @@ impl TryFrom for Operation { (Ld(Mem(AddrLoc::Direct), Reg(A), PostOp::None), 4, 3), 0b11_100_000 => (Ld(HMem(AddrLoc::Direct), Reg(A), PostOp::None), 3, 2), + 0b11_110_000 => + (Ld(Reg(A), HMem(AddrLoc::Direct), PostOp::None), 3, 2), 0b00_100_010 => (Ld(Mem(AddrLoc::Reg(HL)), Reg(A), PostOp::Inc(HL)), 2, 1), 0b00_101_010 => @@ -217,6 +220,8 @@ impl TryFrom for Operation { (Ld(Mem(AddrLoc::Reg(HL)), Reg(A), PostOp::Dec(HL)), 2, 1), 0b00_111_010 => (Ld(Reg(A), Mem(AddrLoc::Reg(HL)), PostOp::Dec(HL)), 2, 1), + 0b10_111_110 => (Cmp(Mem(AddrLoc::Reg(HL))), 2, 1), + 0b11_111_110 => (Cmp(Direct), 2, 2), 0b10_110_110 => (Bit(Or, Mem(AddrLoc::Reg(HL))), 2, 1), 0b10_101_110 => (Bit(Xor, Mem(AddrLoc::Reg(HL))), 2, 1), 0b10_100_110 => (Bit(And, Mem(AddrLoc::Reg(HL))), 2, 1), @@ -251,6 +256,8 @@ impl TryFrom for Operation { (Dec(Reg(Register::try_from((value & T1_MSK) >> 3)?)), 1, 1) } } + _ if (value & (HD_MSK | T1_MSK) == 0b10_111_000) => + (Cmp(Reg(Register::try_from(value & T2_MSK)?)), 1, 1), _ if (value & (HD_MSK | 0b1_000 | T2_MSK) == 0b11_000_101) => (Psh(Register::repr_psh(payload(value))), 4, 1), _ if (value & (HD_MSK | 0b1_000 | T2_MSK) == 0b11_000_001) => @@ -274,6 +281,7 @@ impl TryFrom for Operation { }; (Ld16(Reg(reg), Direct), 3, 3) } + _ => (Unimpl(value), 0, 0), };