diff --git a/src/emu.rs b/src/emu.rs index e39f5b1..b0aaaf5 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -108,40 +108,39 @@ impl GameBoy { } } - fn op_ld(&mut self, dst: Loc, src: Loc, modifier: i8) { + fn op_ld(&mut self, dst: ValSrc, src: ValSrc, modifier: i8) { let pc = self.pc as usize; let (val, src_adr) = match src { - Loc::Reg(i) => (self.reg[i as usize], i as usize), - Loc::Val => (self.mem[pc + 1], 0), - Loc::Mem(ref src) => match src { + ValSrc::Reg(i) => (self.reg[i as usize], i as usize), + ValSrc::Direct => (self.mem[pc + 1], 0), + ValSrc::Mem(ref src) => match src { AddrLoc::Reg(reg) => { let mem_loc = self.reg[*reg] as usize; (self.mem[mem_loc], mem_loc) } - AddrLoc::Mem => todo!(), - AddrLoc::Val => todo!(), + AddrLoc::Direct => todo!(), } - Loc::HMem(_) => todo!(), + ValSrc::HMem(_) => todo!(), }; let (dst_ref, dst_adr) = match dst { - Loc::Mem(ref src) => match src { - AddrLoc::Val => { + ValSrc::Mem(ref src) => match src { + AddrLoc::Direct => { let adr = self.read16(pc) as usize; (&mut self.mem[adr], adr) } _ => todo!(), }, - Loc::HMem(ref src) => match src { - AddrLoc::Val => { + ValSrc::HMem(ref src) => match src { + AddrLoc::Direct => { let adr = self.mem[pc + 1] as usize + 0xFF00; (&mut self.mem[adr], adr) } _ => todo!(), }, - Loc::Reg(r) => (&mut self.reg[r as usize], r as usize), - Loc::Val => panic!("val as destination should not be possible"), + ValSrc::Reg(r) => (&mut self.reg[r as usize], r as usize), + ValSrc::Direct => panic!("val as destination should not be possible"), }; let dst_str = dst.repr(dst_adr, *dst_ref); @@ -151,26 +150,26 @@ impl GameBoy { *dst_ref = (val as i16 + modifier as i16) as u8; } - fn op_ld16(&mut self, dst: Loc, src: Loc) { + fn op_ld16(&mut self, dst: ValSrc, src: ValSrc) { let pc = self.pc as usize; let (l, h) = match src { - Loc::Val => (self.mem[pc + 1], self.mem[pc + 2]), + ValSrc::Direct => (self.mem[pc + 1], self.mem[pc + 2]), _ => todo!(), }; let dst_ref = match dst { - Loc::Reg(reg) => { + ValSrc::Reg(reg) => { // FIXME assuming DD is a typo for DE... let reg_loc = reg.into(); &mut self.reg[reg_loc..=reg_loc + 1] } - Loc::Val => panic!("value as dst is not allowed!"), + ValSrc::Direct => panic!("value as dst is not allowed!"), _ => todo!(), }; match dst { - Loc::Reg(_) => println!("ld16 {dst:6?} <- 0x{h:02x}{l:02x}"), + ValSrc::Reg(_) => println!("ld16 {dst:6?} <- 0x{h:02x}{l:02x}"), _ => panic!("print address"), } @@ -185,9 +184,9 @@ impl GameBoy { (hadr << 8) + ladr } - fn store16(&mut self, loc: Loc, _loc_val: u8, h: u8, l: u8) { + fn store16(&mut self, loc: ValSrc, _loc_val: u8, h: u8, l: u8) { match loc { - Loc::Reg(dst_reg) => { + ValSrc::Reg(dst_reg) => { let dst_reg: usize = dst_reg.into(); self.reg[dst_reg] = h; self.reg[dst_reg + 1] = l; @@ -284,15 +283,15 @@ impl GameBoy { Ld(dst, src) => self.op_ld(dst, src, 0), Ld16(dst, src) => self.op_ld16(dst, src), LdInc(src) => { - self.op_ld(Loc::Reg(Register::A), src, 1) + self.op_ld(ValSrc::Reg(Register::A), src, 1) } LdDec(src) => { - self.op_ld(Loc::Reg(Register::A), src, -1) + self.op_ld(ValSrc::Reg(Register::A), src, -1) } Or(src) => { let v = match src { - Loc::Reg(r) => self.reg[r], - Loc::Mem(ref src) => { + ValSrc::Reg(r) => self.reg[r], + ValSrc::Mem(ref src) => { let err_text = "Or Mem(Reg) only defined for register HR)"; let AddrLoc::Reg(src) = src else { panic!("Invalid op: {err_text}"); @@ -300,7 +299,7 @@ impl GameBoy { assert!(src == &Register::HL, "{err_text}"); self.mem[self.reg[*src] as usize] }, - Loc::Val => self.mem[pc+1], + ValSrc::Direct => self.mem[pc+1], _ => panic!("invalid command") }; self.reg[Register::A] |= v; diff --git a/src/op.rs b/src/op.rs index be2d94c..84fdf41 100644 --- a/src/op.rs +++ b/src/op.rs @@ -21,16 +21,16 @@ pub enum Instr { Pop(Register), // Load - Ld(Loc, Loc), - Ld16(Loc, Loc), - LdInc(Loc), // loads into A - LdDec(Loc), // loads into A + Ld(ValSrc, ValSrc), + Ld16(ValSrc, ValSrc), + LdInc(ValSrc), // loads into A + LdDec(ValSrc), // loads into A // Arith // TODO can we do Inc16/Inc8 with one via Register::WIDE Inc(Register), Dec(Register), - Or(Loc), // TODO all bit can probably be done with this one + Or(ValSrc), // TODO all bit can probably be done with this one // CPU ctl Di, @@ -45,16 +45,15 @@ pub enum Instr { #[derive(Debug)] pub enum AddrLoc { Reg(Register), - Mem, - Val, + Direct, } #[derive(Debug)] -pub enum Loc { // TODO this should probably be called ValSrc or similar +pub enum ValSrc { Reg(Register), // direct Mem(AddrLoc), HMem(AddrLoc), - Val, // TODO and then this Direct + Direct, } #[derive(Debug, Copy, Clone, PartialEq)] @@ -140,12 +139,12 @@ impl fmt::Binary for Register { } } -impl Loc { +impl ValSrc { pub fn repr(&self, adr: usize, val: u8) -> String { match self { - Loc::Reg(_) => format!("{self:6?}"), - Loc::Mem(_) | Loc::HMem(_) => format!("({adr:#06x})"), - Loc::Val => format!("{val:#04x}"), + ValSrc::Reg(_) => format!("{self:6?}"), + ValSrc::Mem(_) | ValSrc::HMem(_) => format!("({adr:#06x})"), + ValSrc::Direct => format!("{val:#04x}"), } } } @@ -179,7 +178,8 @@ impl TryFrom for Operation { fn try_from(value: u8) -> Result { use Instr::*; - use Loc::*; + use ValSrc::*; + use Register::*; let (inst, cycl, offs) = match value { 0b00_000_000 => (Nop, 1, 1), @@ -188,12 +188,12 @@ impl TryFrom for Operation { 0b11_001_101 => (Call, 6, 3), 0b11_001_001 => (Ret, 4, 1), 0b11_110_011 => (Di, 1, 1), - 0b11_101_010 => (Ld(Mem(AddrLoc::Val), Reg(Register::A)), 4, 3), - 0b11_100_000 => (Ld(HMem(AddrLoc::Val), Reg(Register::A)), 3, 2), - 0b00_101_010 => (LdInc(Mem(AddrLoc::Reg(Register::HL))), 2, 1), - 0b00_111_010 => (LdDec(Mem(AddrLoc::Reg(Register::HL))), 2, 1), - 0b10_110_110 => (Or(Mem(AddrLoc::Reg(Register::HL))), 2, 1), - 0b11_110_110 => (Or(Val), 2, 1), + 0b11_101_010 => (Ld(Mem(AddrLoc::Direct), Reg(A)), 4, 3), + 0b11_100_000 => (Ld(HMem(AddrLoc::Direct), Reg(A)), 3, 2), + 0b00_101_010 => (LdInc(Mem(AddrLoc::Reg(HL))), 2, 1), + 0b00_111_010 => (LdDec(Mem(AddrLoc::Reg(HL))), 2, 1), + 0b10_110_110 => (Or(Mem(AddrLoc::Reg(HL))), 2, 1), + 0b11_110_110 => (Or(Direct), 2, 1), _ if (value & (HD_MSK | T1_MSK) == 0b10_110_000) => { (Or(Reg(Register::try_from(value & 0b111)?)), 1, 1) } @@ -211,7 +211,7 @@ impl TryFrom for Operation { } _ if (value & (HD_MSK | T2_MSK)) == 0b00_000_110 => { let reg = Register::try_from((value & T1_MSK) >> 3)?; - (Ld(Reg(reg), Val), 2, 2) + (Ld(Reg(reg), Direct), 2, 2) } _ if (value & HD_MSK) == 0b01_000_000 => { let dst = Register::try_from((value & T1_MSK) >> 3)?; @@ -220,13 +220,13 @@ impl TryFrom for Operation { } _ if (value & (HD_MSK | 0b1_000 | T2_MSK)) == 0b00_000_001 => { let reg = match payload(value) { - 0b00 => Register::B, - 0b01 => Register::D, - 0b10 => Register::H, - 0b11 => Register::SP, + 0b00 => B, + 0b01 => D, + 0b10 => H, + 0b11 => SP, val => return Err(format!("invalid register {val}")), }; - (Ld16(Reg(reg), Val), 3, 3) + (Ld16(Reg(reg), Direct), 3, 3) } _ => (Unimpl(value), 0, 0), };