mirror of
https://github.com/FranLMSP/rmg-001.git
synced 2024-11-23 10:12:11 +00:00
Fix some tests, add a couple of new instructions and fix LD instruction bug
This commit is contained in:
parent
9d8d05c660
commit
afaecf597f
96
src/cpu.rs
96
src/cpu.rs
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user