Implement Instructions and rename enums

This commit is contained in:
Rekai Nyangadzayi Musuka 2020-09-02 17:26:46 -05:00
parent 0be0030ed7
commit cb365fd932
2 changed files with 179 additions and 114 deletions

View File

@ -57,7 +57,7 @@ impl Cpu {
Register::E => self.reg.e = value, Register::E => self.reg.e = value,
Register::H => self.reg.h = value, Register::H => self.reg.h = value,
Register::L => self.reg.l = value, Register::L => self.reg.l = value,
Register::Flags => self.reg.a = value.into(), Register::Flag => self.reg.a = value.into(),
} }
} }
@ -70,7 +70,7 @@ impl Cpu {
Register::E => self.reg.e, Register::E => self.reg.e,
Register::H => self.reg.h, Register::H => self.reg.h,
Register::L => self.reg.l, Register::L => self.reg.l,
Register::Flags => self.flags.into(), Register::Flag => self.flags.into(),
} }
} }
@ -120,7 +120,7 @@ pub enum Register {
E, E,
H, H,
L, L,
Flags, Flag,
} }
pub enum RegisterPair { pub enum RegisterPair {

View File

@ -5,8 +5,8 @@ pub enum Instruction {
STOP, STOP,
JR(JumpCondition, i8), JR(JumpCondition, i8),
ADD(MATHTarget, MATHTarget), ADD(MATHTarget, MATHTarget),
INC(AllRegisters), INC(Registers),
DEC(AllRegisters), DEC(Registers),
RLCA, RLCA,
RRCA, RRCA,
RLA, RLA,
@ -58,28 +58,28 @@ impl Instruction {
} }
Cycles(12) Cycles(12)
} }
(LDTarget::IndirectRegister(pair), LDTarget::Register(InstrRegisters::A)) => { (LDTarget::IndirectRegister(pair), LDTarget::Register(InstrRegister::A)) => {
let a = cpu.register(Register::A); let a = cpu.register(Register::A);
match pair { match pair {
InstrRegisterPairs::BC => { InstrRegisterPair::BC => {
// LD (BC), A | Put A into memory address BC // LD (BC), A | Put A into memory address BC
let addr = cpu.register_pair(RegisterPair::BC); let addr = cpu.register_pair(RegisterPair::BC);
cpu.write_byte(addr, a); cpu.write_byte(addr, a);
} }
InstrRegisterPairs::DE => { InstrRegisterPair::DE => {
// LD (DE), A | Put A into memory address DE // LD (DE), A | Put A into memory address DE
let addr = cpu.register_pair(RegisterPair::DE); let addr = cpu.register_pair(RegisterPair::DE);
cpu.write_byte(addr, a); cpu.write_byte(addr, a);
} }
InstrRegisterPairs::IncrementHL => { InstrRegisterPair::IncrementHL => {
// LD (HL+), A | Put A into memory address HL, then increment HL // LD (HL+), A | Put A into memory address HL, then increment HL
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.write_byte(addr, a); cpu.write_byte(addr, a);
cpu.set_register_pair(RegisterPair::HL, addr + 1); cpu.set_register_pair(RegisterPair::HL, addr + 1);
} }
InstrRegisterPairs::DecrementHL => { InstrRegisterPair::DecrementHL => {
// LD (HL-), A | Put A into memory address HL, then decrement HL // LD (HL-), A | Put A into memory address HL, then decrement HL
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.write_byte(addr, a); cpu.write_byte(addr, a);
@ -90,26 +90,26 @@ impl Instruction {
} }
Cycles(8) Cycles(8)
} }
(LDTarget::Register(InstrRegisters::A), LDTarget::IndirectRegister(pair)) => { (LDTarget::Register(InstrRegister::A), LDTarget::IndirectRegister(pair)) => {
match pair { match pair {
InstrRegisterPairs::BC => { InstrRegisterPair::BC => {
// LD A, (BC) | Put value at address BC into A // LD A, (BC) | Put value at address BC into A
let addr = cpu.register_pair(RegisterPair::BC); let addr = cpu.register_pair(RegisterPair::BC);
cpu.set_register(Register::A, cpu.read_byte(addr)); cpu.set_register(Register::A, cpu.read_byte(addr));
} }
InstrRegisterPairs::DE => { InstrRegisterPair::DE => {
// LD A, (DE) | Put value at address DE into A // LD A, (DE) | Put value at address DE into A
let addr = cpu.register_pair(RegisterPair::DE); let addr = cpu.register_pair(RegisterPair::DE);
cpu.set_register(Register::A, cpu.read_byte(addr)); cpu.set_register(Register::A, cpu.read_byte(addr));
} }
InstrRegisterPairs::IncrementHL => { InstrRegisterPair::IncrementHL => {
// LD A, (HL+) | Put value at address HL into A, then increment HL // LD A, (HL+) | Put value at address HL into A, then increment HL
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.set_register(Register::A, cpu.read_byte(addr)); cpu.set_register(Register::A, cpu.read_byte(addr));
cpu.set_register_pair(RegisterPair::HL, addr + 1); cpu.set_register_pair(RegisterPair::HL, addr + 1);
} }
InstrRegisterPairs::DecrementHL => { InstrRegisterPair::DecrementHL => {
// LD A, (HL-) | Put value at address HL into A, then increment HL // LD A, (HL-) | Put value at address HL into A, then increment HL
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.set_register(Register::A, cpu.read_byte(addr)); cpu.set_register(Register::A, cpu.read_byte(addr));
@ -125,40 +125,40 @@ impl Instruction {
let cycles: Cycles; let cycles: Cycles;
match reg { match reg {
InstrRegisters::B => { InstrRegister::B => {
cpu.set_register(Register::B, n); cpu.set_register(Register::B, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::C => { InstrRegister::C => {
cpu.set_register(Register::C, n); cpu.set_register(Register::C, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::D => { InstrRegister::D => {
cpu.set_register(Register::D, n); cpu.set_register(Register::D, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::E => { InstrRegister::E => {
cpu.set_register(Register::E, n); cpu.set_register(Register::E, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::H => { InstrRegister::H => {
cpu.set_register(Register::H, n); cpu.set_register(Register::H, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::L => { InstrRegister::L => {
cpu.set_register(Register::L, n); cpu.set_register(Register::L, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::IndirectHL => { InstrRegister::IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.write_byte(addr, n); cpu.write_byte(addr, n);
cycles = Cycles(12); cycles = Cycles(12);
} }
InstrRegisters::A => { InstrRegister::A => {
cpu.set_register(Register::A, n); cpu.set_register(Register::A, n);
cycles = Cycles(8); cycles = Cycles(8);
} }
InstrRegisters::IndirectC => unreachable!(), InstrRegister::IndirectC => unreachable!(),
} }
cycles cycles
} }
@ -169,7 +169,7 @@ impl Instruction {
// JR cc[y - 4], d | If condition is true, then add d to current address and jump // JR cc[y - 4], d | If condition is true, then add d to current address and jump
// JR d | Add d to current address and jump // JR d | Add d to current address and jump
let prev = cpu.register_pair(RegisterPair::PC); let prev = cpu.register_pair(RegisterPair::PC);
let flags: Flags = cpu.register(Register::Flags).into(); let flags: Flags = cpu.register(Register::Flag).into();
let new_address = (prev as i16 + offset as i16) as u16; let new_address = (prev as i16 + offset as i16) as u16;
match cond { match cond {
@ -212,7 +212,7 @@ impl Instruction {
(MATHTarget::RegisterPair(RegisterPair::HL), MATHTarget::RegisterPair(pair)) => { (MATHTarget::RegisterPair(RegisterPair::HL), MATHTarget::RegisterPair(pair)) => {
// ADD HL, rp[p] | add register pair to HL. // ADD HL, rp[p] | add register pair to HL.
let hl = cpu.register_pair(RegisterPair::HL); let hl = cpu.register_pair(RegisterPair::HL);
let mut flags: Flags = cpu.register(Register::Flags).into(); let mut flags: Flags = cpu.register(Register::Flag).into();
let sum; let sum;
match pair { match pair {
@ -233,13 +233,13 @@ impl Instruction {
} }
_ => unreachable!(), _ => unreachable!(),
} }
cpu.set_register(Register::Flags, flags.into()); cpu.set_register(Register::Flag, flags.into());
cpu.set_register_pair(RegisterPair::HL, sum); cpu.set_register_pair(RegisterPair::HL, sum);
Cycles(8) Cycles(8)
} }
_ => unimplemented!(), _ => unimplemented!(),
}, },
Instruction::INC(AllRegisters::Word(pair)) => { Instruction::INC(Registers::Word(pair)) => {
// INC rp[p] | Increment Register Pair // INC rp[p] | Increment Register Pair
match pair { match pair {
RegisterPair::BC => { RegisterPair::BC => {
@ -262,58 +262,58 @@ impl Instruction {
} }
Cycles(8) Cycles(8)
} }
Instruction::INC(AllRegisters::Byte(reg)) => { Instruction::INC(Registers::Byte(reg)) => {
// INC r[y] | Increment Register // INC r[y] | Increment Register
let mut flags: Flags = cpu.register(Register::Flags).into(); let mut flags: Flags = cpu.register(Register::Flag).into();
let cycles: Cycles; let cycles: Cycles;
match reg { match reg {
InstrRegisters::B => { InstrRegister::B => {
let b = cpu.register(Register::B); let b = cpu.register(Register::B);
cpu.set_register(Register::B, Self::inc_register(b, &mut flags)); cpu.set_register(Register::B, Self::inc_register(b, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::C => { InstrRegister::C => {
let c = cpu.register(Register::C); let c = cpu.register(Register::C);
cpu.set_register(Register::C, Self::inc_register(c, &mut flags)); cpu.set_register(Register::C, Self::inc_register(c, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::D => { InstrRegister::D => {
let d = cpu.register(Register::D); let d = cpu.register(Register::D);
cpu.set_register(Register::D, Self::inc_register(d, &mut flags)); cpu.set_register(Register::D, Self::inc_register(d, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::E => { InstrRegister::E => {
let e = cpu.register(Register::E); let e = cpu.register(Register::E);
cpu.set_register(Register::E, Self::inc_register(e, &mut flags)); cpu.set_register(Register::E, Self::inc_register(e, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::H => { InstrRegister::H => {
let h = cpu.register(Register::H); let h = cpu.register(Register::H);
cpu.set_register(Register::H, Self::inc_register(h, &mut flags)); cpu.set_register(Register::H, Self::inc_register(h, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::L => { InstrRegister::L => {
let l = cpu.register(Register::L); let l = cpu.register(Register::L);
cpu.set_register(Register::L, Self::inc_register(l, &mut flags)); cpu.set_register(Register::L, Self::inc_register(l, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::IndirectHL => { InstrRegister::IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.write_byte(addr, Self::inc_register(cpu.read_byte(addr), &mut flags)); cpu.write_byte(addr, Self::inc_register(cpu.read_byte(addr), &mut flags));
cycles = Cycles(12); cycles = Cycles(12);
} }
InstrRegisters::A => { InstrRegister::A => {
let a = cpu.register(Register::A); let a = cpu.register(Register::A);
cpu.set_register(Register::A, Self::inc_register(a, &mut flags)); cpu.set_register(Register::A, Self::inc_register(a, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::IndirectC => unreachable!(), InstrRegister::IndirectC => unreachable!(),
} }
cpu.set_register(Register::Flags, flags.into()); cpu.set_register(Register::Flag, flags.into());
cycles cycles
} }
Instruction::DEC(AllRegisters::Word(pair)) => { Instruction::DEC(Registers::Word(pair)) => {
// DEC rp[p] | Decrement Register Pair // DEC rp[p] | Decrement Register Pair
match pair { match pair {
RegisterPair::BC => { RegisterPair::BC => {
@ -336,89 +336,154 @@ impl Instruction {
} }
Cycles(8) Cycles(8)
} }
Instruction::DEC(AllRegisters::Byte(reg)) => { Instruction::DEC(Registers::Byte(reg)) => {
// DEC r[y] | Decrement Register // DEC r[y] | Decrement Register
let mut flags: Flags = cpu.register(Register::Flags).into(); let mut flags: Flags = cpu.register(Register::Flag).into();
let cycles: Cycles; let cycles: Cycles;
match reg { match reg {
InstrRegisters::B => { InstrRegister::B => {
let b = cpu.register(Register::B); let b = cpu.register(Register::B);
cpu.set_register(Register::B, Self::dec_register(b, &mut flags)); cpu.set_register(Register::B, Self::dec_register(b, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::C => { InstrRegister::C => {
let c = cpu.register(Register::C); let c = cpu.register(Register::C);
cpu.set_register(Register::C, Self::dec_register(c, &mut flags)); cpu.set_register(Register::C, Self::dec_register(c, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::D => { InstrRegister::D => {
let d = cpu.register(Register::D); let d = cpu.register(Register::D);
cpu.set_register(Register::D, Self::dec_register(d, &mut flags)); cpu.set_register(Register::D, Self::dec_register(d, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::E => { InstrRegister::E => {
let e = cpu.register(Register::E); let e = cpu.register(Register::E);
cpu.set_register(Register::E, Self::dec_register(e, &mut flags)); cpu.set_register(Register::E, Self::dec_register(e, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::H => { InstrRegister::H => {
let h = cpu.register(Register::H); let h = cpu.register(Register::H);
cpu.set_register(Register::H, Self::dec_register(h, &mut flags)); cpu.set_register(Register::H, Self::dec_register(h, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::L => { InstrRegister::L => {
let l = cpu.register(Register::L); let l = cpu.register(Register::L);
cpu.set_register(Register::L, Self::dec_register(l, &mut flags)); cpu.set_register(Register::L, Self::dec_register(l, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::IndirectHL => { InstrRegister::IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL); let addr = cpu.register_pair(RegisterPair::HL);
cpu.write_byte(addr, Self::dec_register(cpu.read_byte(addr), &mut flags)); cpu.write_byte(addr, Self::dec_register(cpu.read_byte(addr), &mut flags));
cycles = Cycles(12); cycles = Cycles(12);
} }
InstrRegisters::A => { InstrRegister::A => {
let a = cpu.register(Register::A); let a = cpu.register(Register::A);
cpu.set_register(Register::A, Self::dec_register(a, &mut flags)); cpu.set_register(Register::A, Self::dec_register(a, &mut flags));
cycles = Cycles(4); cycles = Cycles(4);
} }
InstrRegisters::IndirectC => unreachable!(), InstrRegister::IndirectC => unreachable!(),
} }
cpu.set_register(Register::Flags, flags.into()); cpu.set_register(Register::Flag, flags.into());
cycles cycles
} }
Instruction::RLCA => { Instruction::RLCA => {
// FIXME: Pretty sure this is an incorrect implementation let mut flags: Flags = cpu.register(Register::Flag).into();
let mut flags: Flags = cpu.register(Register::Flags).into();
let a = cpu.register(Register::A); let a = cpu.register(Register::A);
let carry_bit = (a & 0x80) >> 7; let cache = a >> 7; // get the 7th bit (this will be the carry bit + the one that is wrapped around)
let new_a = a << 1; let rot_a = (a << 1) | (cache << 0); // (rotate a left), then set the first bit (which will be a 0 by default)
flags.z = 0 == new_a; flags.z = false;
flags.n = false; flags.n = false;
flags.h = false; flags.h = false;
flags.c = carry_bit == 0x01; flags.c = cache == 0x01;
cpu.set_register(Register::A, new_a); cpu.set_register(Register::Flag, flags.into());
cpu.set_register(Register::A, rot_a);
Cycles(4) Cycles(4)
} }
Instruction::RRCA => { Instruction::RRCA => {
// FIXME: Pretty sure this is an incorrect implementation let mut flags: Flags = cpu.register(Register::Flag).into();
let mut flags: Flags = cpu.register(Register::Flags).into();
let a = cpu.register(Register::A); let a = cpu.register(Register::A);
let carry_bit = a & 0x01; let cache = a & 0x01; // RLCA but the other way around
let new_a = a >> 1; let rot_a = (a >> 1) | (cache << 7);
flags.z = new_a == 0; flags.z = false;
flags.n = false; flags.n = false;
flags.h = false; flags.h = false;
flags.c = carry_bit == 0x01; flags.c = cache == 0x01;
cpu.set_register(Register::A, new_a); cpu.set_register(Register::Flag, flags.into());
cpu.set_register(Register::A, rot_a);
Cycles(4) Cycles(4)
} }
Instruction::RLA => {
let mut flags: Flags = cpu.register(Register::Flag).into();
let a = cpu.register(Register::A);
let cache = a >> 7;
let rot_a = (a << 1) | ((flags.c as u8) << 0);
flags.z = false;
flags.n = false;
flags.h = false;
flags.c = cache == 0x01;
cpu.set_register(Register::Flag, flags.into());
cpu.set_register(Register::A, rot_a);
Cycles(4)
}
Instruction::RRA => {
let mut flags: Flags = cpu.register(Register::Flag).into();
let a = cpu.register(Register::A);
let cache = a & 0x01;
let rot_a = (a >> 1) | ((flags.c as u8) << 7);
flags.z = false;
flags.n = false;
flags.h = false;
flags.c = cache == 0x01;
cpu.set_register(Register::Flag, flags.into());
cpu.set_register(Register::A, rot_a);
Cycles(4)
}
Instruction::DAA => unimplemented!(),
Instruction::CPL => {
let mut flags: Flags = cpu.register(Register::Flag).into();
let a = cpu.register(Register::A);
flags.n = true;
flags.h = true;
cpu.set_register(Register::Flag, flags.into());
cpu.set_register(Register::A, !a); // Bitwise not is ! instead of ~
Cycles(4)
}
Instruction::SCF => {
let mut flags: Flags = cpu.register(Register::Flag).into();
flags.n = false;
flags.h = false;
flags.c = true;
cpu.set_register(Register::Flag, flags.into());
Cycles(4)
}
Instruction::CCF => {
let mut flags: Flags = cpu.register(Register::Flag).into();
flags.n = false;
flags.h = false;
flags.c = !flags.c;
cpu.set_register(Register::Flag, flags.into());
Cycles(4)
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -503,59 +568,59 @@ impl Instruction {
), ),
(0, 2, 0, _, 0) => Instruction::LD( (0, 2, 0, _, 0) => Instruction::LD(
// LD (BC), A // LD (BC), A
LDTarget::IndirectRegister(InstrRegisterPairs::BC), LDTarget::IndirectRegister(InstrRegisterPair::BC),
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(0, 2, 0, _, 1) => Instruction::LD( (0, 2, 0, _, 1) => Instruction::LD(
// LD (DE), A // LD (DE), A
LDTarget::IndirectRegister(InstrRegisterPairs::DE), LDTarget::IndirectRegister(InstrRegisterPair::DE),
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(0, 2, 1, _, 0) => Instruction::LD( (0, 2, 1, _, 0) => Instruction::LD(
// LD A, (BC) // LD A, (BC)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::IndirectRegister(InstrRegisterPairs::BC), LDTarget::IndirectRegister(InstrRegisterPair::BC),
), ),
(0, 2, 1, _, 1) => Instruction::LD( (0, 2, 1, _, 1) => Instruction::LD(
// LD A, (DE) // LD A, (DE)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::IndirectRegister(InstrRegisterPairs::DE), LDTarget::IndirectRegister(InstrRegisterPair::DE),
), ),
(0, 2, 0, _, 2) => Instruction::LD( (0, 2, 0, _, 2) => Instruction::LD(
// LD (HL+), A // LD (HL+), A
LDTarget::IndirectRegister(InstrRegisterPairs::IncrementHL), LDTarget::IndirectRegister(InstrRegisterPair::IncrementHL),
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(0, 2, 0, _, 3) => Instruction::LD( (0, 2, 0, _, 3) => Instruction::LD(
// LD (HL-), A // LD (HL-), A
LDTarget::IndirectRegister(InstrRegisterPairs::DecrementHL), LDTarget::IndirectRegister(InstrRegisterPair::DecrementHL),
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(0, 2, 1, _, 2) => Instruction::LD( (0, 2, 1, _, 2) => Instruction::LD(
// LD A, (HL+) // LD A, (HL+)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::IndirectRegister(InstrRegisterPairs::IncrementHL), LDTarget::IndirectRegister(InstrRegisterPair::IncrementHL),
), ),
(0, 2, 1, _, 3) => Instruction::LD( (0, 2, 1, _, 3) => Instruction::LD(
// LD A, (HL-) // LD A, (HL-)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::IndirectRegister(InstrRegisterPairs::DecrementHL), LDTarget::IndirectRegister(InstrRegisterPair::DecrementHL),
), ),
(0, 3, 0, _, _) => Instruction::INC( (0, 3, 0, _, _) => Instruction::INC(
// INC rp[p] // INC rp[p]
AllRegisters::Word(Table::rp(p)), Registers::Word(Table::rp(p)),
), ),
(0, 3, 1, _, _) => Instruction::DEC( (0, 3, 1, _, _) => Instruction::DEC(
// DEC rp[p] // DEC rp[p]
AllRegisters::Word(Table::rp(p)), Registers::Word(Table::rp(p)),
), ),
(0, 4, _, _, _) => Instruction::INC( (0, 4, _, _, _) => Instruction::INC(
// INC r[y] // INC r[y]
AllRegisters::Byte(Table::r(y)), Registers::Byte(Table::r(y)),
), ),
(0, 5, _, _, _) => Instruction::DEC( (0, 5, _, _, _) => Instruction::DEC(
// DEC r[y] // DEC r[y]
AllRegisters::Byte(Table::r(y)), Registers::Byte(Table::r(y)),
), ),
(0, 6, _, _, _) => Instruction::LD( (0, 6, _, _, _) => Instruction::LD(
// LD r[y], n // LD r[y], n
@ -581,7 +646,7 @@ impl Instruction {
(3, 0, _, 4, _) => Instruction::LD( (3, 0, _, 4, _) => Instruction::LD(
// LD (0xFF00 + n), A // LD (0xFF00 + n), A
LDTarget::ByteAtAddress(0xFF00 + (n as u16)), // TODO: Do we want to do any calculations here? LDTarget::ByteAtAddress(0xFF00 + (n as u16)), // TODO: Do we want to do any calculations here?
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(3, 0, _, 5, _) => Instruction::ADD( (3, 0, _, 5, _) => Instruction::ADD(
// ADD SP, d // ADD SP, d
@ -590,7 +655,7 @@ impl Instruction {
), ),
(3, 0, _, 6, _) => Instruction::LD( (3, 0, _, 6, _) => Instruction::LD(
// LD A, (0xFF00 + n) // LD A, (0xFF00 + n)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::ByteAtAddress(0xFF00 + (n as u16)), // TODO: DO we want to do any calculations here? LDTarget::ByteAtAddress(0xFF00 + (n as u16)), // TODO: DO we want to do any calculations here?
), ),
(3, 0, _, 7, _) => Instruction::LDHL(n as i8), // LD HL, SP + d (3, 0, _, 7, _) => Instruction::LDHL(n as i8), // LD HL, SP + d
@ -614,22 +679,22 @@ impl Instruction {
), ),
(3, 2, _, 4, _) => Instruction::LD( (3, 2, _, 4, _) => Instruction::LD(
// LD (0xFF00 + C) ,A // LD (0xFF00 + C) ,A
LDTarget::Register(InstrRegisters::IndirectC), LDTarget::Register(InstrRegister::IndirectC),
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(3, 2, _, 5, _) => Instruction::LD( (3, 2, _, 5, _) => Instruction::LD(
// LD (nn), A // LD (nn), A
LDTarget::ByteAtAddress(nn), LDTarget::ByteAtAddress(nn),
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
), ),
(3, 2, _, 6, _) => Instruction::LD( (3, 2, _, 6, _) => Instruction::LD(
// LD A, (0xFF00 + C) // LD A, (0xFF00 + C)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::Register(InstrRegisters::IndirectC), LDTarget::Register(InstrRegister::IndirectC),
), ),
(3, 2, _, 7, _) => Instruction::LD( (3, 2, _, 7, _) => Instruction::LD(
// LD A, (nn) // LD A, (nn)
LDTarget::Register(InstrRegisters::A), LDTarget::Register(InstrRegister::A),
LDTarget::ByteAtAddress(nn), LDTarget::ByteAtAddress(nn),
), ),
(3, 3, _, 0, _) => Instruction::JP( (3, 3, _, 0, _) => Instruction::JP(
@ -672,29 +737,29 @@ pub enum JPTarget {
ImmediateWord(u16), ImmediateWord(u16),
} }
pub enum AllRegisters { pub enum Registers {
Byte(InstrRegisters), Byte(InstrRegister),
Word(RegisterPair), Word(RegisterPair),
} }
pub enum MATHTarget { pub enum MATHTarget {
HL, HL,
SP, SP,
Register(InstrRegisters), Register(InstrRegister),
RegisterPair(RegisterPair), RegisterPair(RegisterPair),
ImmediateByte(u8), ImmediateByte(u8),
} }
pub enum LDTarget { pub enum LDTarget {
Register(InstrRegisters), Register(InstrRegister),
IndirectRegister(InstrRegisterPairs), IndirectRegister(InstrRegisterPair),
ByteAtAddress(u16), ByteAtAddress(u16),
ImmediateWord(u16), ImmediateWord(u16),
ImmediateByte(u8), ImmediateByte(u8),
RegisterPair(RegisterPair), RegisterPair(RegisterPair),
} }
enum InstrRegisterPairs { enum InstrRegisterPair {
AF, AF,
BC, BC,
DE, DE,
@ -705,7 +770,7 @@ enum InstrRegisterPairs {
DecrementHL, DecrementHL,
} }
enum InstrRegisters { enum InstrRegister {
A, A,
B, B,
C, C,
@ -728,16 +793,16 @@ pub enum JumpCondition {
struct Table; struct Table;
impl Table { impl Table {
pub fn r(index: u8) -> InstrRegisters { pub fn r(index: u8) -> InstrRegister {
match index { match index {
0 => InstrRegisters::B, 0 => InstrRegister::B,
1 => InstrRegisters::C, 1 => InstrRegister::C,
2 => InstrRegisters::D, 2 => InstrRegister::D,
3 => InstrRegisters::E, 3 => InstrRegister::E,
4 => InstrRegisters::H, 4 => InstrRegister::H,
5 => InstrRegisters::L, 5 => InstrRegister::L,
6 => InstrRegisters::IndirectHL, 6 => InstrRegister::IndirectHL,
7 => InstrRegisters::A, 7 => InstrRegister::A,
_ => unreachable!("Index {} is out of bounds in r[]", index), _ => unreachable!("Index {} is out of bounds in r[]", index),
} }
} }
@ -776,18 +841,18 @@ impl Table {
match fn_index { match fn_index {
0 => Instruction::ADD( 0 => Instruction::ADD(
// ADD A, r[z] // ADD A, r[z]
MATHTarget::Register(InstrRegisters::A), MATHTarget::Register(InstrRegister::A),
MATHTarget::Register(Self::r(r_index)), MATHTarget::Register(Self::r(r_index)),
), ),
1 => Instruction::ADC( 1 => Instruction::ADC(
// ADC A, r[z] // ADC A, r[z]
MATHTarget::Register(InstrRegisters::A), MATHTarget::Register(InstrRegister::A),
MATHTarget::Register(Self::r(r_index)), MATHTarget::Register(Self::r(r_index)),
), ),
2 => Instruction::SUB(MATHTarget::Register(Self::r(r_index))), // SUB r[z] 2 => Instruction::SUB(MATHTarget::Register(Self::r(r_index))), // SUB r[z]
3 => Instruction::SBC( 3 => Instruction::SBC(
// SBC A, r[z] // SBC A, r[z]
MATHTarget::Register(InstrRegisters::A), MATHTarget::Register(InstrRegister::A),
MATHTarget::Register(Self::r(r_index)), MATHTarget::Register(Self::r(r_index)),
), ),
4 => Instruction::AND(MATHTarget::Register(Self::r(r_index))), // AND r[z] 4 => Instruction::AND(MATHTarget::Register(Self::r(r_index))), // AND r[z]