Fix some tests, add a couple of new instructions and fix LD instruction bug

This commit is contained in:
Franco Colmenarez 2021-10-15 20:59:35 -05:00
parent 9d8d05c660
commit afaecf597f

View File

@ -296,10 +296,27 @@ impl CPU {
match opcode { match opcode {
// Load // Load
Opcode::LD(params) => match params { Opcode::LD(params) => match params {
OpcodeParameter::Register_Register(reg1, reg2) => {
if reg1.is_16bit() && reg2.is_8bit() {
let val = self.registers.get(reg2).to_be_bytes()[1];
let addr = self.registers.get(reg1);
bus.write(addr, val);
} else if reg1.is_8bit() && reg2.is_16bit() {
let val = bus.read(self.registers.get(reg2)) as u16;
self.registers.set(reg1, val);
} else {
self.registers.set(reg1, self.registers.get(reg2));
}
self.registers.increment(Register::PC, 1);
},
OpcodeParameter::Register_U16(register, val) => { OpcodeParameter::Register_U16(register, val) => {
self.registers.set(register, val); self.registers.set(register, val);
self.registers.increment(Register::PC, 3); self.registers.increment(Register::PC, 3);
}, },
OpcodeParameter::Register_U8(register, val) => {
self.registers.set(register, val as u16);
self.registers.increment(Register::PC, 2);
},
OpcodeParameter::U16_Register(address, register) => { OpcodeParameter::U16_Register(address, register) => {
let value = self.registers.get(register); let value = self.registers.get(register);
let bytes = value.to_be_bytes(); let bytes = value.to_be_bytes();
@ -310,7 +327,17 @@ impl CPU {
self.registers.increment(Register::PC, 3); self.registers.increment(Register::PC, 3);
}, },
_ => {}, _ => {},
} },
// Load and increment
Opcode::LDI(params) => match params {
OpcodeParameter::Register_RegisterIncrement(reg1, reg2) => {
let val = bus.read(self.registers.get(reg2));
self.registers.set(reg1, val as u16);
self.registers.increment(reg2, 1);
self.registers.increment(Register::PC, 1);
},
_ => {},
},
// Increment by 1 // Increment by 1
Opcode::INC(affect_flags, register) => { Opcode::INC(affect_flags, register) => {
let prev_value = self.registers.get(register); let prev_value = self.registers.get(register);
@ -381,12 +408,10 @@ impl CPU {
} }
}, },
// RET, same as POP PC when no parameter is specified // RET, same as POP PC when no parameter is specified
Opcode::RET(params) => { Opcode::RET(params) => match params {
match params {
OpcodeParameter::NoParam => self.exec(Opcode::POP(Register::PC), bus), OpcodeParameter::NoParam => self.exec(Opcode::POP(Register::PC), bus),
_ => {}, _ => {},
} }
}
// Rotate A Left // Rotate A Left
Opcode::RLCA => { Opcode::RLCA => {
let val = self.registers.get(Register::A).to_be_bytes()[1]; let val = self.registers.get(Register::A).to_be_bytes()[1];
@ -749,11 +774,25 @@ mod tests {
#[test] #[test]
fn test_cpu_instructions() { fn test_cpu_instructions() {
// LD // LD
let mut bus = Bus::new();
let mut cpu = CPU::new();
cpu.registers.set(Register::A, 0xFF);
cpu.exec(Opcode::LD(OpcodeParameter::Register_Register(Register::B, Register::A)), &mut bus);
assert_eq!(cpu.registers.get(Register::B), 0xFF);
assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
let mut bus = Bus::new(); let mut bus = Bus::new();
cpu.exec(Opcode::LD(OpcodeParameter::Register_U16(Register::SP, 0xF1F1)), &mut bus); cpu.exec(Opcode::LD(OpcodeParameter::Register_U16(Register::SP, 0xF1F1)), &mut bus);
assert_eq!(cpu.registers.get(Register::SP), 0xF1F1); assert_eq!(cpu.registers.get(Register::SP), 0xF1F1);
assert_eq!(cpu.registers.get(Register::PC), 0x103); assert_eq!(cpu.registers.get(Register::PC), 0x103);
let mut cpu = CPU::new();
let mut bus = Bus::new();
cpu.exec(Opcode::LD(OpcodeParameter::Register_U8(Register::B, 0xF1)), &mut bus);
assert_eq!(cpu.registers.get(Register::B), 0xF1);
assert_eq!(cpu.registers.get(Register::PC), 0x102);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
let mut bus = Bus::new(); let mut bus = Bus::new();
cpu.registers.set(Register::SP, 0x1234); cpu.registers.set(Register::SP, 0x1234);
@ -761,6 +800,39 @@ mod tests {
assert_eq!(bus.read_16bit(0xF0F0), 0x1234); assert_eq!(bus.read_16bit(0xF0F0), 0x1234);
assert_eq!(cpu.registers.get(Register::PC), 0x103); assert_eq!(cpu.registers.get(Register::PC), 0x103);
let mut cpu = CPU::new();
let mut bus = Bus::new();
let addr = 0xC000;
cpu.registers.set(Register::A, 0xFF);
cpu.registers.set(Register::HL, addr);
bus.write(addr, 0x00);
cpu.exec(Opcode::LD(OpcodeParameter::Register_Register(Register::HL, Register::A)), &mut bus);
assert_eq!(bus.read(addr), 0xFF);
assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new();
let mut bus = Bus::new();
let addr = 0xC000;
cpu.registers.set(Register::A, 0x00);
cpu.registers.set(Register::HL, addr);
bus.write(addr, 0xFF);
cpu.exec(Opcode::LD(OpcodeParameter::Register_Register(Register::A, Register::HL)), &mut bus);
assert_eq!(cpu.registers.get(Register::A), 0xFF);
assert_eq!(cpu.registers.get(Register::PC), 0x101);
// LDI
let mut bus = Bus::new();
let mut cpu = CPU::new();
let addr = 0xC000;
cpu.registers.set(Register::A, 0x00);
cpu.registers.set(Register::HL, addr);
bus.write(addr, 0xF1);
cpu.exec(Opcode::LDI(OpcodeParameter::Register_RegisterIncrement(Register::A, Register::HL)), &mut bus);
assert_eq!(bus.read(addr), 0xF1);
assert_eq!(cpu.registers.get(Register::A), 0xF1);
assert_eq!(cpu.registers.get(Register::HL), addr + 1);
assert_eq!(cpu.registers.get(Register::PC), 0x101);
// JP // JP
let mut cpu = CPU::new(); let mut cpu = CPU::new();
let mut bus = Bus::new(); let mut bus = Bus::new();
@ -777,12 +849,14 @@ mod tests {
// RLCA // RLCA
let mut cpu = CPU::new(); let mut cpu = CPU::new();
let mut bus = Bus::new(); let mut bus = Bus::new();
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.registers.set(Register::A, 0b00000010); cpu.registers.set(Register::A, 0b00000010);
cpu.exec(Opcode::RLCA, &mut bus); cpu.exec(Opcode::RLCA, &mut bus);
assert_eq!(cpu.registers.get(Register::A), 0b00000010); assert_eq!(cpu.registers.get(Register::A), 0b00000010);
assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), false);
assert_eq!(cpu.registers.get(Register::PC), 0x101); assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.registers.set(Register::A, 0b00000001); cpu.registers.set(Register::A, 0b00000001);
cpu.exec(Opcode::RLCA, &mut bus); cpu.exec(Opcode::RLCA, &mut bus);
assert_eq!(cpu.registers.get(Register::A), 0b00000001); assert_eq!(cpu.registers.get(Register::A), 0b00000001);
@ -792,11 +866,13 @@ mod tests {
// RRCA // RRCA
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set(Register::A, 0b01000000); cpu.registers.set(Register::A, 0b01000000);
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.exec(Opcode::RRCA, &mut bus); cpu.exec(Opcode::RRCA, &mut bus);
assert_eq!(cpu.registers.get(Register::A), 0b01000000); assert_eq!(cpu.registers.get(Register::A), 0b01000000);
assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Carry), false);
assert_eq!(cpu.registers.get(Register::PC), 0x101); assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.registers.set(Register::A, 0b10000000); cpu.registers.set(Register::A, 0b10000000);
cpu.exec(Opcode::RRCA, &mut bus); cpu.exec(Opcode::RRCA, &mut bus);
assert_eq!(cpu.registers.get(Register::A), 0b10000000); assert_eq!(cpu.registers.get(Register::A), 0b10000000);
@ -844,12 +920,16 @@ mod tests {
// INC // INC
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set(Register::A, 0); cpu.registers.set(Register::A, 0);
cpu.registers.set_flag(FlagRegister::Zero, false);
cpu.registers.set_flag(FlagRegister::HalfCarry, false);
cpu.exec(Opcode::INC(true, Register::A), &mut bus); cpu.exec(Opcode::INC(true, Register::A), &mut bus);
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);
assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), false);
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false); assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false);
assert_eq!(cpu.registers.get(Register::PC), 0x101); assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Zero, false);
cpu.registers.set_flag(FlagRegister::HalfCarry, false);
cpu.registers.set(Register::A, 0b00001111); cpu.registers.set(Register::A, 0b00001111);
cpu.exec(Opcode::INC(true, Register::A), &mut bus); cpu.exec(Opcode::INC(true, Register::A), &mut bus);
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);
@ -857,6 +937,8 @@ mod tests {
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true); assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
assert_eq!(cpu.registers.get(Register::PC), 0x101); assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Zero, false);
cpu.registers.set_flag(FlagRegister::HalfCarry, false);
cpu.registers.set(Register::HL, 0b0000111111111111); cpu.registers.set(Register::HL, 0b0000111111111111);
cpu.exec(Opcode::INC(true, Register::HL), &mut bus); cpu.exec(Opcode::INC(true, Register::HL), &mut bus);
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);
@ -867,6 +949,8 @@ mod tests {
// DEC // DEC
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.registers.set_flag(FlagRegister::HalfCarry, false);
cpu.registers.set(Register::A, 1); cpu.registers.set(Register::A, 1);
cpu.exec(Opcode::DEC(true, Register::A), &mut bus); cpu.exec(Opcode::DEC(true, Register::A), &mut bus);
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), true); assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), true);
@ -875,6 +959,8 @@ mod tests {
assert_eq!(cpu.registers.get(Register::A), 0); assert_eq!(cpu.registers.get(Register::A), 0);
assert_eq!(cpu.registers.get(Register::PC), 0x101); assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Zero, false);
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.registers.set(Register::A, 0b00010000); cpu.registers.set(Register::A, 0b00010000);
cpu.exec(Opcode::DEC(true, Register::A), &mut bus); cpu.exec(Opcode::DEC(true, Register::A), &mut bus);
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);
@ -883,6 +969,8 @@ mod tests {
assert_eq!(cpu.registers.get(Register::A), 0b00001111); assert_eq!(cpu.registers.get(Register::A), 0b00001111);
assert_eq!(cpu.registers.get(Register::PC), 0x101); assert_eq!(cpu.registers.get(Register::PC), 0x101);
let mut cpu = CPU::new(); let mut cpu = CPU::new();
cpu.registers.set_flag(FlagRegister::Zero, false);
cpu.registers.set_flag(FlagRegister::Carry, false);
cpu.registers.set(Register::HL, 0b0001000000000000); cpu.registers.set(Register::HL, 0b0001000000000000);
cpu.exec(Opcode::DEC(true, Register::HL), &mut bus); cpu.exec(Opcode::DEC(true, Register::HL), &mut bus);
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false); assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);