implement LdInc, LdDec and Or
/ build (push) Successful in 23s Details

This commit is contained in:
45Tatami 2024-04-10 21:52:21 +02:00
parent 3e6d21a56c
commit 24c3880224
2 changed files with 48 additions and 8 deletions

View File

@ -108,13 +108,20 @@ impl GameBoy {
} }
} }
fn op_ld(&mut self, dst: Loc, src: Loc) { fn op_ld(&mut self, dst: Loc, src: Loc, modifier: i8) {
let pc = self.pc as usize; let pc = self.pc as usize;
let (val, src_adr) = match src { let (val, src_adr) = match src {
Loc::Reg(i) => (self.reg[i as usize], i as usize), Loc::Reg(i) => (self.reg[i as usize], i as usize),
Loc::Val => (self.mem[pc + 1], 0), Loc::Val => (self.mem[pc + 1], 0),
Loc::Mem(_) => todo!(), Loc::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!(),
}
Loc::HMem(_) => todo!(), Loc::HMem(_) => todo!(),
}; };
@ -139,9 +146,9 @@ impl GameBoy {
let dst_str = dst.repr(dst_adr, *dst_ref); let dst_str = dst.repr(dst_adr, *dst_ref);
let src_str = src.repr(src_adr, val); let src_str = src.repr(src_adr, val);
println!("ld {dst_str} <- {src_str}"); println!("ld {dst_str} <- {src_str} + {modifier}");
*dst_ref = val; *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: Loc, src: Loc) {
@ -274,8 +281,31 @@ impl GameBoy {
self.reg[reg as usize] -= 1; self.reg[reg as usize] -= 1;
println!("Dec Reg({reg:#04b})"); println!("Dec Reg({reg:#04b})");
} }
Ld(dst, src) => self.op_ld(dst, src), Ld(dst, src) => self.op_ld(dst, src, 0),
Ld16(dst, src) => self.op_ld16(dst, src), Ld16(dst, src) => self.op_ld16(dst, src),
LdInc(src) => {
self.op_ld(Loc::Reg(Register::A), src, 1)
}
LdDec(src) => {
self.op_ld(Loc::Reg(Register::A), src, -1)
}
Or(src) => {
let v = match src {
Loc::Reg(r) => self.reg[r],
Loc::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}");
};
assert!(src == &Register::HL, "{err_text}");
self.mem[self.reg[*src] as usize]
},
Loc::Val => self.mem[pc+1],
_ => panic!("invalid command")
};
self.reg[Register::A] |= v;
println!("Or {src:?}");
}
Di => println!("FIXME Di instruction not implemented"), Di => println!("FIXME Di instruction not implemented"),
} }

View File

@ -23,11 +23,14 @@ pub enum Instr {
// Load // Load
Ld(Loc, Loc), Ld(Loc, Loc),
Ld16(Loc, Loc), Ld16(Loc, Loc),
LdInc(Loc), // loads into A
LdDec(Loc), // loads into A
// Arith // Arith
// TODO can we do Inc16/Inc8 with one via Register::WIDE // TODO can we do Inc16/Inc8 with one via Register::WIDE
Inc(Register), Inc(Register),
Dec(Register), Dec(Register),
Or(Loc), // TODO all bit can probably be done with this one
// CPU ctl // CPU ctl
Di, Di,
@ -47,14 +50,14 @@ pub enum AddrLoc {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Loc { pub enum Loc { // TODO this should probably be called ValSrc or similar
Reg(Register), // direct Reg(Register), // direct
Mem(AddrLoc), Mem(AddrLoc),
HMem(AddrLoc), HMem(AddrLoc),
Val, Val, // TODO and then this Direct
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum Register { pub enum Register {
A, A,
F, F,
@ -187,6 +190,13 @@ impl TryFrom<u8> for Operation {
0b11_110_011 => (Di, 1, 1), 0b11_110_011 => (Di, 1, 1),
0b11_101_010 => (Ld(Mem(AddrLoc::Val), Reg(Register::A)), 4, 3), 0b11_101_010 => (Ld(Mem(AddrLoc::Val), Reg(Register::A)), 4, 3),
0b11_100_000 => (Ld(HMem(AddrLoc::Val), Reg(Register::A)), 3, 2), 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),
_ if (value & (HD_MSK | T1_MSK) == 0b10_110_000) => {
(Or(Reg(Register::try_from(value & 0b111)?)), 1, 1)
}
_ if (value & (HD_MSK | 0b1_000 | T2_MSK) == 0b00_000_011) => { _ if (value & (HD_MSK | 0b1_000 | T2_MSK) == 0b00_000_011) => {
(Inc(Register::from16_rep(payload(value))), 2, 1) (Inc(Register::from16_rep(payload(value))), 2, 1)
} }