implement LdInc, LdDec and Or
/ build (push) Successful in 23s
Details
/ build (push) Successful in 23s
Details
This commit is contained in:
parent
3e6d21a56c
commit
24c3880224
40
src/emu.rs
40
src/emu.rs
|
|
@ -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"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
16
src/op.rs
16
src/op.rs
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue