implement "and", "xor"

This commit is contained in:
45Tatami 2024-04-12 17:53:28 +02:00
parent a6e7572f72
commit 003daaf7a1
2 changed files with 29 additions and 7 deletions

View File

@ -288,7 +288,7 @@ impl GameBoy {
LdDec(src) => { LdDec(src) => {
self.op_ld(ValSrc::Reg(Register::A), src, -1) self.op_ld(ValSrc::Reg(Register::A), src, -1)
} }
Or(src) => { Bit(bit_op, src) => {
let v = match src { let v = match src {
ValSrc::Reg(r) => self.reg[r], ValSrc::Reg(r) => self.reg[r],
ValSrc::Mem(ref src) => { ValSrc::Mem(ref src) => {
@ -302,8 +302,12 @@ impl GameBoy {
ValSrc::Direct => self.mem[pc+1], ValSrc::Direct => self.mem[pc+1],
_ => panic!("invalid command") _ => panic!("invalid command")
}; };
self.reg[Register::A] |= v; match bit_op {
println!("Or {src:?}"); BitOp::Or => self.reg[Register::A] |= v,
BitOp::And => self.reg[Register::A] &= v,
BitOp::Xor => self.reg[Register::A] ^= v,
}
println!("{bit_op:?} {src:?}");
} }
Di => println!("FIXME Di instruction not implemented"), Di => println!("FIXME Di instruction not implemented"),
} }

View File

@ -30,7 +30,7 @@ pub enum Instr {
// 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(ValSrc), // TODO all bit can probably be done with this one Bit(BitOp, ValSrc),
// CPU ctl // CPU ctl
Di, Di,
@ -169,6 +169,13 @@ impl TryFrom<u8> for Register {
} }
} }
#[derive(Debug)]
pub enum BitOp {
Or,
And,
Xor
}
fn payload(v: u8) -> u8 { fn payload(v: u8) -> u8 {
(v & 0b110_000) >> 4 (v & 0b110_000) >> 4
} }
@ -180,6 +187,7 @@ impl TryFrom<u8> for Operation {
use Instr::*; use Instr::*;
use ValSrc::*; use ValSrc::*;
use Register::*; use Register::*;
use BitOp::*;
let (inst, cycl, offs) = match value { let (inst, cycl, offs) = match value {
0b00_000_000 => (Nop, 1, 1), 0b00_000_000 => (Nop, 1, 1),
@ -192,10 +200,20 @@ impl TryFrom<u8> for Operation {
0b11_100_000 => (Ld(HMem(AddrLoc::Direct), Reg(A)), 3, 2), 0b11_100_000 => (Ld(HMem(AddrLoc::Direct), Reg(A)), 3, 2),
0b00_101_010 => (LdInc(Mem(AddrLoc::Reg(HL))), 2, 1), 0b00_101_010 => (LdInc(Mem(AddrLoc::Reg(HL))), 2, 1),
0b00_111_010 => (LdDec(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), 0b10_110_110 => (Bit(Or, Mem(AddrLoc::Reg(HL))), 2, 1),
0b11_110_110 => (Or(Direct), 2, 1), 0b10_101_110 => (Bit(Xor, Mem(AddrLoc::Reg(HL))), 2, 1),
0b10_100_110 => (Bit(And, Mem(AddrLoc::Reg(HL))), 2, 1),
0b11_110_110 => (Bit(Or, Direct), 2, 2), // TODO can bit be grouped via HD & T2?
0b11_101_110 => (Bit(Xor, Direct), 2, 2),
0b11_100_110 => (Bit(And, Direct), 2, 2),
_ if (value & (HD_MSK | T1_MSK) == 0b10_110_000) => { _ if (value & (HD_MSK | T1_MSK) == 0b10_110_000) => {
(Or(Reg(Register::try_from(value & 0b111)?)), 1, 1) (Bit(Or, Reg(Register::try_from(value & 0b111)?)), 1, 1)
}
_ if (value & (HD_MSK | T1_MSK) == 0b10_101_000) => {
(Bit(Xor, Reg(Register::try_from(value & 0b111)?)), 1, 1)
}
_ if (value & (HD_MSK | T1_MSK) == 0b10_100_000) => {
(Bit(And, 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)