mirror of
https://github.com/FranLMSP/rmg-001.git
synced 2025-02-23 11:41:33 +00:00
ADD instruction bug
This commit is contained in:
parent
ac91f8f50d
commit
eeeba76ebd
158
src/cpu.rs
158
src/cpu.rs
@ -233,8 +233,8 @@ pub enum Opcode {
|
|||||||
OR(OpcodeParameter),
|
OR(OpcodeParameter),
|
||||||
XOR(OpcodeParameter),
|
XOR(OpcodeParameter),
|
||||||
CP(OpcodeParameter),
|
CP(OpcodeParameter),
|
||||||
INC(bool, Register),
|
INC(bool, bool, Register),
|
||||||
DEC(bool, Register),
|
DEC(bool, bool, Register),
|
||||||
DAA,
|
DAA,
|
||||||
CPL,
|
CPL,
|
||||||
CCF,
|
CCF,
|
||||||
@ -528,6 +528,7 @@ impl CPU {
|
|||||||
if reg1.is_8bit() && reg2.is_8bit() {
|
if reg1.is_8bit() && reg2.is_8bit() {
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(self.registers.get_8bit(reg1), self.registers.get_8bit(reg2)));
|
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(self.registers.get_8bit(reg1), self.registers.get_8bit(reg2)));
|
||||||
self.registers.set(reg1, self.registers.get(reg1) + self.registers.get(reg2));
|
self.registers.set(reg1, self.registers.get(reg1) + self.registers.get(reg2));
|
||||||
|
self.registers.set_flag(FlagRegister::Zero, self.registers.get(reg1) == 0);
|
||||||
} else if reg1.is_16bit() && reg2.is_16bit() {
|
} else if reg1.is_16bit() && reg2.is_16bit() {
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry_16bit(self.registers.get(reg1), self.registers.get(reg2)));
|
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry_16bit(self.registers.get(reg1), self.registers.get(reg2)));
|
||||||
self.registers.set(reg1, self.registers.get(reg1) + self.registers.get(reg2));
|
self.registers.set(reg1, self.registers.get(reg1) + self.registers.get(reg2));
|
||||||
@ -536,8 +537,8 @@ impl CPU {
|
|||||||
let val2 = bus.read(self.registers.get(reg2)) as u16;
|
let val2 = bus.read(self.registers.get(reg2)) as u16;
|
||||||
self.registers.set(reg1, val1 + val2);
|
self.registers.set(reg1, val1 + val2);
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(val1.to_be_bytes()[1], val2.to_be_bytes()[1]));
|
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(val1.to_be_bytes()[1], val2.to_be_bytes()[1]));
|
||||||
|
self.registers.set_flag(FlagRegister::Zero, self.registers.get(reg1) == 0);
|
||||||
}
|
}
|
||||||
self.registers.set_flag(FlagRegister::Zero, self.registers.get(reg1) == 0);
|
|
||||||
self.registers.set_flag(FlagRegister::Carry, self.registers.get(reg1) == 0);
|
self.registers.set_flag(FlagRegister::Carry, self.registers.get(reg1) == 0);
|
||||||
},
|
},
|
||||||
OpcodeParameter::Register_U8(reg1, val) => {
|
OpcodeParameter::Register_U8(reg1, val) => {
|
||||||
@ -638,45 +639,59 @@ impl CPU {
|
|||||||
_ => {},
|
_ => {},
|
||||||
},
|
},
|
||||||
// Increment by 1
|
// Increment by 1
|
||||||
Opcode::INC(affect_flags, register) => {
|
Opcode::INC(affect_flags, on_address, register) => {
|
||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
let mut prev_value = 0;
|
if on_address {
|
||||||
let mut result = 0;
|
|
||||||
if register.is_8bit() {
|
|
||||||
prev_value = self.registers.get_8bit(register);
|
|
||||||
self.registers.increment(register, 1);
|
|
||||||
result = self.registers.get_8bit(register);
|
|
||||||
} else {
|
|
||||||
let addr = self.registers.get(register);
|
let addr = self.registers.get(register);
|
||||||
prev_value = bus.read(addr);
|
let prev_value = bus.read(addr);
|
||||||
bus.write(addr, prev_value + 1);
|
bus.write(addr, prev_value + 1);
|
||||||
result = bus.read(addr);
|
if affect_flags {
|
||||||
}
|
self.registers.set_flag(FlagRegister::Substract, false);
|
||||||
if affect_flags {
|
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(prev_value, 1));
|
||||||
self.registers.set_flag(FlagRegister::Substract, false);
|
self.registers.set_flag(FlagRegister::Zero, bus.read(addr) == 0);
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(prev_value, 1));
|
}
|
||||||
self.registers.set_flag(FlagRegister::Zero, result == 0);
|
} else {
|
||||||
|
let prev_value = self.registers.get(register);
|
||||||
|
self.registers.increment(register, 1);
|
||||||
|
if affect_flags {
|
||||||
|
let mut byte_compare = 0;
|
||||||
|
match register.is_8bit() {
|
||||||
|
true => byte_compare = prev_value.to_be_bytes()[1],
|
||||||
|
false => byte_compare = prev_value.to_be_bytes()[0],
|
||||||
|
}
|
||||||
|
let result = self.registers.get(register);
|
||||||
|
self.registers.set_flag(FlagRegister::Substract, false);
|
||||||
|
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(byte_compare, 1));
|
||||||
|
self.registers.set_flag(FlagRegister::Zero, result == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Decrement by 1
|
// Decrement by 1
|
||||||
Opcode::DEC(affect_flags, register) => {
|
Opcode::DEC(affect_flags, on_address, register) => {
|
||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
let mut prev_value = 0;
|
if on_address {
|
||||||
let mut result = 0;
|
|
||||||
if register.is_8bit() {
|
|
||||||
prev_value = self.registers.get_8bit(register);
|
|
||||||
self.registers.decrement(register, 1);
|
|
||||||
result = self.registers.get_8bit(register);
|
|
||||||
} else {
|
|
||||||
let addr = self.registers.get(register);
|
let addr = self.registers.get(register);
|
||||||
prev_value = bus.read(addr);
|
let prev_value = bus.read(addr);
|
||||||
bus.write(addr, prev_value - 1);
|
bus.write(addr, prev_value - 1);
|
||||||
result = bus.read(addr);
|
if affect_flags {
|
||||||
}
|
self.registers.set_flag(FlagRegister::Substract, true);
|
||||||
if affect_flags {
|
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(prev_value, 1));
|
||||||
self.registers.set_flag(FlagRegister::Substract, true);
|
self.registers.set_flag(FlagRegister::Zero, bus.read(addr) == 0);
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(prev_value, 1));
|
}
|
||||||
self.registers.set_flag(FlagRegister::Zero, result == 0);
|
} else {
|
||||||
|
let prev_value = self.registers.get(register);
|
||||||
|
self.registers.decrement(register, 1);
|
||||||
|
if affect_flags {
|
||||||
|
let mut byte_compare = 0;
|
||||||
|
match register.is_8bit() {
|
||||||
|
true => byte_compare = prev_value.to_be_bytes()[1],
|
||||||
|
false => byte_compare = prev_value.to_be_bytes()[0],
|
||||||
|
}
|
||||||
|
let result = self.registers.get(register);
|
||||||
|
self.registers.set_flag(FlagRegister::Substract, true);
|
||||||
|
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(byte_compare, 1));
|
||||||
|
self.registers.set_flag(FlagRegister::Zero, result == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Jump to address
|
// Jump to address
|
||||||
@ -1119,30 +1134,30 @@ impl CPU {
|
|||||||
0xBD => Opcode::CP(OpcodeParameter::Register_Register(Register::A, Register::L)),
|
0xBD => Opcode::CP(OpcodeParameter::Register_Register(Register::A, Register::L)),
|
||||||
0xBE => Opcode::CP(OpcodeParameter::Register_Register(Register::A, Register::HL)),
|
0xBE => Opcode::CP(OpcodeParameter::Register_Register(Register::A, Register::HL)),
|
||||||
0xFE => Opcode::CP(OpcodeParameter::Register_U8(Register::A, params.1)),
|
0xFE => Opcode::CP(OpcodeParameter::Register_U8(Register::A, params.1)),
|
||||||
0x3C => Opcode::INC(true, Register::A),
|
0x3C => Opcode::INC(true, false, Register::A),
|
||||||
0x04 => Opcode::INC(true, Register::B),
|
0x04 => Opcode::INC(true, false, Register::B),
|
||||||
0x0C => Opcode::INC(true, Register::C),
|
0x0C => Opcode::INC(true, false, Register::C),
|
||||||
0x14 => Opcode::INC(true, Register::D),
|
0x14 => Opcode::INC(true, false, Register::D),
|
||||||
0x1C => Opcode::INC(true, Register::E),
|
0x1C => Opcode::INC(true, false, Register::E),
|
||||||
0x24 => Opcode::INC(true, Register::H),
|
0x24 => Opcode::INC(true, false, Register::H),
|
||||||
0x2C => Opcode::INC(true, Register::L),
|
0x2C => Opcode::INC(true, false, Register::L),
|
||||||
0x34 => Opcode::INC(true, Register::HL),
|
0x34 => Opcode::INC(true, true, Register::HL),
|
||||||
0x03 => Opcode::INC(false, Register::BC),
|
0x03 => Opcode::INC(false, false, Register::BC),
|
||||||
0x13 => Opcode::INC(false, Register::DE),
|
0x13 => Opcode::INC(false, false, Register::DE),
|
||||||
0x23 => Opcode::INC(false, Register::HL),
|
0x23 => Opcode::INC(false, false, Register::HL),
|
||||||
0x33 => Opcode::INC(false, Register::SP),
|
0x33 => Opcode::INC(false, false, Register::SP),
|
||||||
0x3D => Opcode::DEC(true, Register::A),
|
0x3D => Opcode::DEC(true, false, Register::A),
|
||||||
0x05 => Opcode::DEC(true, Register::B),
|
0x05 => Opcode::DEC(true, false, Register::B),
|
||||||
0x0D => Opcode::DEC(true, Register::C),
|
0x0D => Opcode::DEC(true, false, Register::C),
|
||||||
0x15 => Opcode::DEC(true, Register::D),
|
0x15 => Opcode::DEC(true, false, Register::D),
|
||||||
0x1D => Opcode::DEC(true, Register::E),
|
0x1D => Opcode::DEC(true, false, Register::E),
|
||||||
0x25 => Opcode::DEC(true, Register::H),
|
0x25 => Opcode::DEC(true, false, Register::H),
|
||||||
0x2D => Opcode::DEC(true, Register::L),
|
0x2D => Opcode::DEC(true, false, Register::L),
|
||||||
0x35 => Opcode::DEC(true, Register::HL),
|
0x35 => Opcode::DEC(true, true, Register::HL),
|
||||||
0x0B => Opcode::DEC(false, Register::BC),
|
0x0B => Opcode::DEC(false, false, Register::BC),
|
||||||
0x1B => Opcode::DEC(false, Register::DE),
|
0x1B => Opcode::DEC(false, false, Register::DE),
|
||||||
0x2B => Opcode::DEC(false, Register::HL),
|
0x2B => Opcode::DEC(false, false, Register::HL),
|
||||||
0x3B => Opcode::DEC(false, Register::SP),
|
0x3B => Opcode::DEC(false, false, Register::SP),
|
||||||
0x27 => Opcode::DAA,
|
0x27 => Opcode::DAA,
|
||||||
0x2F => Opcode::CPL,
|
0x2F => Opcode::CPL,
|
||||||
0x3F => Opcode::CCF,
|
0x3F => Opcode::CCF,
|
||||||
@ -2273,7 +2288,6 @@ mod tests {
|
|||||||
cpu.registers.set(Register::BC, 0b0000100000000000);
|
cpu.registers.set(Register::BC, 0b0000100000000000);
|
||||||
cpu.registers.set(Register::HL, 0b0000100000000000);
|
cpu.registers.set(Register::HL, 0b0000100000000000);
|
||||||
cpu.exec(Opcode::ADD(OpcodeParameter::Register_Register(Register::BC, Register::HL)), &mut bus);
|
cpu.exec(Opcode::ADD(OpcodeParameter::Register_Register(Register::BC, Register::HL)), &mut bus);
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);
|
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||||
assert_eq!(cpu.registers.get(Register::BC), 0b0001000000000000);
|
assert_eq!(cpu.registers.get(Register::BC), 0b0001000000000000);
|
||||||
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||||
@ -2330,14 +2344,14 @@ mod tests {
|
|||||||
let mut bus = Bus::new();
|
let mut bus = Bus::new();
|
||||||
let mut cpu = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
cpu.registers.set(Register::A, 0);
|
cpu.registers.set(Register::A, 0);
|
||||||
cpu.exec(Opcode::INC(true, Register::A), &mut bus);
|
cpu.exec(Opcode::INC(true, false, 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(Register::A, 0b00001111);
|
cpu.registers.set(Register::A, 0b00001111);
|
||||||
cpu.exec(Opcode::INC(true, Register::A), &mut bus);
|
cpu.exec(Opcode::INC(true, false, 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), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||||
@ -2346,12 +2360,20 @@ mod tests {
|
|||||||
let addr = 0xC000;
|
let addr = 0xC000;
|
||||||
cpu.registers.set(Register::HL, addr);
|
cpu.registers.set(Register::HL, addr);
|
||||||
bus.write(addr, 0b00001111);
|
bus.write(addr, 0b00001111);
|
||||||
cpu.exec(Opcode::INC(true, Register::HL), &mut bus);
|
cpu.exec(Opcode::INC(true, true, Register::HL), &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), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||||
assert_eq!(bus.read(addr), 0b00010000);
|
assert_eq!(bus.read(addr), 0b00010000);
|
||||||
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||||
|
let mut cpu = CPU::new();
|
||||||
|
cpu.registers.set(Register::BC, 0b0000111111111111);
|
||||||
|
cpu.exec(Opcode::INC(true, false, Register::BC), &mut bus);
|
||||||
|
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::HalfCarry), true);
|
||||||
|
assert_eq!(cpu.registers.get(Register::BC), 0b0001000000000000);
|
||||||
|
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -2359,7 +2381,7 @@ mod tests {
|
|||||||
let mut bus = Bus::new();
|
let mut bus = Bus::new();
|
||||||
let mut cpu = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
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, false, Register::A), &mut bus);
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), true);
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), true);
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false);
|
||||||
@ -2367,7 +2389,7 @@ mod tests {
|
|||||||
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(Register::A, 0b00010000);
|
cpu.registers.set(Register::A, 0b00010000);
|
||||||
cpu.exec(Opcode::DEC(true, Register::A), &mut bus);
|
cpu.exec(Opcode::DEC(true, false, 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), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), true);
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||||
@ -2377,12 +2399,20 @@ mod tests {
|
|||||||
let addr = 0xC000;
|
let addr = 0xC000;
|
||||||
cpu.registers.set(Register::HL, addr);
|
cpu.registers.set(Register::HL, addr);
|
||||||
bus.write(addr, 0b00010000);
|
bus.write(addr, 0b00010000);
|
||||||
cpu.exec(Opcode::DEC(true, Register::HL), &mut bus);
|
cpu.exec(Opcode::DEC(true, true, Register::HL), &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), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), true);
|
||||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||||
assert_eq!(bus.read(addr), 0b00001111);
|
assert_eq!(bus.read(addr), 0b00001111);
|
||||||
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||||
|
let mut cpu = CPU::new();
|
||||||
|
cpu.registers.set(Register::BC, 0b0001000000000000);
|
||||||
|
cpu.exec(Opcode::DEC(true, false, Register::BC), &mut bus);
|
||||||
|
assert_eq!(cpu.registers.get_flag(FlagRegister::Zero), false);
|
||||||
|
assert_eq!(cpu.registers.get_flag(FlagRegister::Substract), true);
|
||||||
|
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||||
|
assert_eq!(cpu.registers.get(Register::BC), 0b0000111111111111);
|
||||||
|
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user