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),
|
||||
XOR(OpcodeParameter),
|
||||
CP(OpcodeParameter),
|
||||
INC(bool, Register),
|
||||
DEC(bool, Register),
|
||||
INC(bool, bool, Register),
|
||||
DEC(bool, bool, Register),
|
||||
DAA,
|
||||
CPL,
|
||||
CCF,
|
||||
@ -528,6 +528,7 @@ impl CPU {
|
||||
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(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() {
|
||||
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));
|
||||
@ -536,8 +537,8 @@ impl CPU {
|
||||
let val2 = bus.read(self.registers.get(reg2)) as u16;
|
||||
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::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);
|
||||
},
|
||||
OpcodeParameter::Register_U8(reg1, val) => {
|
||||
@ -638,45 +639,59 @@ impl CPU {
|
||||
_ => {},
|
||||
},
|
||||
// Increment by 1
|
||||
Opcode::INC(affect_flags, register) => {
|
||||
Opcode::INC(affect_flags, on_address, register) => {
|
||||
self.registers.increment(Register::PC, 1);
|
||||
let mut prev_value = 0;
|
||||
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 {
|
||||
if on_address {
|
||||
let addr = self.registers.get(register);
|
||||
prev_value = bus.read(addr);
|
||||
let prev_value = bus.read(addr);
|
||||
bus.write(addr, prev_value + 1);
|
||||
result = bus.read(addr);
|
||||
}
|
||||
if affect_flags {
|
||||
self.registers.set_flag(FlagRegister::Substract, false);
|
||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(prev_value, 1));
|
||||
self.registers.set_flag(FlagRegister::Zero, result == 0);
|
||||
if affect_flags {
|
||||
self.registers.set_flag(FlagRegister::Substract, false);
|
||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(prev_value, 1));
|
||||
self.registers.set_flag(FlagRegister::Zero, bus.read(addr) == 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
|
||||
Opcode::DEC(affect_flags, register) => {
|
||||
Opcode::DEC(affect_flags, on_address, register) => {
|
||||
self.registers.increment(Register::PC, 1);
|
||||
let mut prev_value = 0;
|
||||
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 {
|
||||
if on_address {
|
||||
let addr = self.registers.get(register);
|
||||
prev_value = bus.read(addr);
|
||||
let prev_value = bus.read(addr);
|
||||
bus.write(addr, prev_value - 1);
|
||||
result = bus.read(addr);
|
||||
}
|
||||
if affect_flags {
|
||||
self.registers.set_flag(FlagRegister::Substract, true);
|
||||
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(prev_value, 1));
|
||||
self.registers.set_flag(FlagRegister::Zero, result == 0);
|
||||
if affect_flags {
|
||||
self.registers.set_flag(FlagRegister::Substract, true);
|
||||
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(prev_value, 1));
|
||||
self.registers.set_flag(FlagRegister::Zero, bus.read(addr) == 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
|
||||
@ -1119,30 +1134,30 @@ impl CPU {
|
||||
0xBD => Opcode::CP(OpcodeParameter::Register_Register(Register::A, Register::L)),
|
||||
0xBE => Opcode::CP(OpcodeParameter::Register_Register(Register::A, Register::HL)),
|
||||
0xFE => Opcode::CP(OpcodeParameter::Register_U8(Register::A, params.1)),
|
||||
0x3C => Opcode::INC(true, Register::A),
|
||||
0x04 => Opcode::INC(true, Register::B),
|
||||
0x0C => Opcode::INC(true, Register::C),
|
||||
0x14 => Opcode::INC(true, Register::D),
|
||||
0x1C => Opcode::INC(true, Register::E),
|
||||
0x24 => Opcode::INC(true, Register::H),
|
||||
0x2C => Opcode::INC(true, Register::L),
|
||||
0x34 => Opcode::INC(true, Register::HL),
|
||||
0x03 => Opcode::INC(false, Register::BC),
|
||||
0x13 => Opcode::INC(false, Register::DE),
|
||||
0x23 => Opcode::INC(false, Register::HL),
|
||||
0x33 => Opcode::INC(false, Register::SP),
|
||||
0x3D => Opcode::DEC(true, Register::A),
|
||||
0x05 => Opcode::DEC(true, Register::B),
|
||||
0x0D => Opcode::DEC(true, Register::C),
|
||||
0x15 => Opcode::DEC(true, Register::D),
|
||||
0x1D => Opcode::DEC(true, Register::E),
|
||||
0x25 => Opcode::DEC(true, Register::H),
|
||||
0x2D => Opcode::DEC(true, Register::L),
|
||||
0x35 => Opcode::DEC(true, Register::HL),
|
||||
0x0B => Opcode::DEC(false, Register::BC),
|
||||
0x1B => Opcode::DEC(false, Register::DE),
|
||||
0x2B => Opcode::DEC(false, Register::HL),
|
||||
0x3B => Opcode::DEC(false, Register::SP),
|
||||
0x3C => Opcode::INC(true, false, Register::A),
|
||||
0x04 => Opcode::INC(true, false, Register::B),
|
||||
0x0C => Opcode::INC(true, false, Register::C),
|
||||
0x14 => Opcode::INC(true, false, Register::D),
|
||||
0x1C => Opcode::INC(true, false, Register::E),
|
||||
0x24 => Opcode::INC(true, false, Register::H),
|
||||
0x2C => Opcode::INC(true, false, Register::L),
|
||||
0x34 => Opcode::INC(true, true, Register::HL),
|
||||
0x03 => Opcode::INC(false, false, Register::BC),
|
||||
0x13 => Opcode::INC(false, false, Register::DE),
|
||||
0x23 => Opcode::INC(false, false, Register::HL),
|
||||
0x33 => Opcode::INC(false, false, Register::SP),
|
||||
0x3D => Opcode::DEC(true, false, Register::A),
|
||||
0x05 => Opcode::DEC(true, false, Register::B),
|
||||
0x0D => Opcode::DEC(true, false, Register::C),
|
||||
0x15 => Opcode::DEC(true, false, Register::D),
|
||||
0x1D => Opcode::DEC(true, false, Register::E),
|
||||
0x25 => Opcode::DEC(true, false, Register::H),
|
||||
0x2D => Opcode::DEC(true, false, Register::L),
|
||||
0x35 => Opcode::DEC(true, true, Register::HL),
|
||||
0x0B => Opcode::DEC(false, false, Register::BC),
|
||||
0x1B => Opcode::DEC(false, false, Register::DE),
|
||||
0x2B => Opcode::DEC(false, false, Register::HL),
|
||||
0x3B => Opcode::DEC(false, false, Register::SP),
|
||||
0x27 => Opcode::DAA,
|
||||
0x2F => Opcode::CPL,
|
||||
0x3F => Opcode::CCF,
|
||||
@ -2273,7 +2288,6 @@ mod tests {
|
||||
cpu.registers.set(Register::BC, 0b0000100000000000);
|
||||
cpu.registers.set(Register::HL, 0b0000100000000000);
|
||||
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(Register::BC), 0b0001000000000000);
|
||||
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||
@ -2330,14 +2344,14 @@ mod tests {
|
||||
let mut bus = Bus::new();
|
||||
let mut cpu = CPU::new();
|
||||
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::Substract), false);
|
||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false);
|
||||
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||
let mut cpu = CPU::new();
|
||||
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::Substract), false);
|
||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||
@ -2346,12 +2360,20 @@ mod tests {
|
||||
let addr = 0xC000;
|
||||
cpu.registers.set(Register::HL, addr);
|
||||
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::Substract), false);
|
||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||
assert_eq!(bus.read(addr), 0b00010000);
|
||||
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]
|
||||
@ -2359,7 +2381,7 @@ mod tests {
|
||||
let mut bus = Bus::new();
|
||||
let mut cpu = CPU::new();
|
||||
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::Substract), true);
|
||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), false);
|
||||
@ -2367,7 +2389,7 @@ mod tests {
|
||||
assert_eq!(cpu.registers.get(Register::PC), 0x101);
|
||||
let mut cpu = CPU::new();
|
||||
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::Substract), true);
|
||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||
@ -2377,12 +2399,20 @@ mod tests {
|
||||
let addr = 0xC000;
|
||||
cpu.registers.set(Register::HL, addr);
|
||||
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::Substract), true);
|
||||
assert_eq!(cpu.registers.get_flag(FlagRegister::HalfCarry), true);
|
||||
assert_eq!(bus.read(addr), 0b00001111);
|
||||
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]
|
||||
|
Loading…
x
Reference in New Issue
Block a user