mirror of
https://github.com/FranLMSP/rmg-001.git
synced 2024-11-23 10:12:11 +00:00
Prevent panic on adding or sub with overflow on CPU
This commit is contained in:
parent
f928207a8d
commit
6b1d50ba76
@ -43,7 +43,7 @@ pub struct Bus {
|
|||||||
|
|
||||||
impl Bus {
|
impl Bus {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let game_rom = match ROM::load_file("roms/cpu_instrs_individual/02-interrupts.gb".to_string()) {
|
let game_rom = match ROM::load_file("roms/cpu_instrs_individual/03-op sp,hl.gb".to_string()) {
|
||||||
Ok(rom) => rom,
|
Ok(rom) => rom,
|
||||||
_ => ROM::from_bytes(&[0; 0xFFFF])
|
_ => ROM::from_bytes(&[0; 0xFFFF])
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ impl Console {
|
|||||||
self.cpu.run(&mut self.bus);
|
self.cpu.run(&mut self.bus);
|
||||||
|
|
||||||
// thread::sleep(time::Duration::from_millis(100));
|
// thread::sleep(time::Duration::from_millis(100));
|
||||||
exit = self.cpu.get_exec_calls_count() >= 1258895;
|
exit = self.cpu.get_exec_calls_count() >= 1068422;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
src/cpu.rs
36
src/cpu.rs
@ -163,12 +163,14 @@ impl Registers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn increment(&mut self, register: Register, times: u8) {
|
pub fn increment(&mut self, register: Register, times: u16) {
|
||||||
self.set(register, self.get(register) + (times as u16));
|
let val = self.get(register);
|
||||||
|
self.set(register, val.wrapping_add(times));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrement(&mut self, register: Register, times: u8) {
|
pub fn decrement(&mut self, register: Register, times: u16) {
|
||||||
self.set(register, self.get(register) - (times as u16));
|
let val = self.get(register);
|
||||||
|
self.set(register, val.wrapping_sub(times));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +325,7 @@ impl CPU {
|
|||||||
OpcodeParameter::Register_Register(reg1, reg2) => {
|
OpcodeParameter::Register_Register(reg1, reg2) => {
|
||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
if reg1.is_16bit() && reg2.is_8bit() {
|
if reg1.is_16bit() && reg2.is_8bit() {
|
||||||
let val = self.registers.get(reg2).to_be_bytes()[1];
|
let val = self.registers.get_8bit(reg2);
|
||||||
let addr = self.registers.get(reg1);
|
let addr = self.registers.get(reg1);
|
||||||
bus.write(addr, val);
|
bus.write(addr, val);
|
||||||
} else if reg1.is_8bit() && reg2.is_16bit() {
|
} else if reg1.is_8bit() && reg2.is_16bit() {
|
||||||
@ -360,13 +362,13 @@ impl CPU {
|
|||||||
OpcodeParameter::FF00plusU8_Register(val, register) => {
|
OpcodeParameter::FF00plusU8_Register(val, register) => {
|
||||||
self.registers.increment(Register::PC, 2);
|
self.registers.increment(Register::PC, 2);
|
||||||
match register.is_8bit() {
|
match register.is_8bit() {
|
||||||
true => bus.write(0xFF00 + (val as u16), self.registers.get(register).to_be_bytes()[1]),
|
true => bus.write(0xFF00 + (val as u16), self.registers.get_8bit(register)),
|
||||||
false => bus.write_16bit(0xFF00 + (val as u16), self.registers.get(register)),
|
false => bus.write_16bit(0xFF00 + (val as u16), self.registers.get(register)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
OpcodeParameter::Register_RegisterPlusI8(reg1, reg2, val) => {
|
OpcodeParameter::Register_RegisterPlusI8(reg1, reg2, val) => {
|
||||||
self.registers.increment(Register::PC, 2);
|
self.registers.increment(Register::PC, 2);
|
||||||
let res = (self.registers.get(reg2) as i16) + (val as i16);
|
let res = (self.registers.get(reg2) as i16).wrapping_add(val as i16);
|
||||||
self.registers.set(reg1, res as u16);
|
self.registers.set(reg1, res as u16);
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
@ -406,7 +408,7 @@ impl CPU {
|
|||||||
},
|
},
|
||||||
OpcodeParameter::RegisterIncrement_Register(reg1, reg2) => {
|
OpcodeParameter::RegisterIncrement_Register(reg1, reg2) => {
|
||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
let val = self.registers.get(reg2).to_be_bytes()[1];
|
let val = self.registers.get_8bit(reg2);
|
||||||
bus.write(self.registers.get(reg1), val);
|
bus.write(self.registers.get(reg1), val);
|
||||||
self.registers.increment(reg1, 1);
|
self.registers.increment(reg1, 1);
|
||||||
},
|
},
|
||||||
@ -422,7 +424,7 @@ impl CPU {
|
|||||||
},
|
},
|
||||||
OpcodeParameter::RegisterDecrement_Register(reg1, reg2) => {
|
OpcodeParameter::RegisterDecrement_Register(reg1, reg2) => {
|
||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
let val = self.registers.get(reg2).to_be_bytes()[1];
|
let val = self.registers.get_8bit(reg2);
|
||||||
bus.write(self.registers.get(reg1), val);
|
bus.write(self.registers.get(reg1), val);
|
||||||
self.registers.decrement(reg1, 1);
|
self.registers.decrement(reg1, 1);
|
||||||
},
|
},
|
||||||
@ -532,15 +534,15 @@ impl CPU {
|
|||||||
OpcodeParameter::Register_Register(reg1, reg2) => {
|
OpcodeParameter::Register_Register(reg1, reg2) => {
|
||||||
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.increment(reg1, self.registers.get(reg2));
|
||||||
self.registers.set_flag(FlagRegister::Zero, self.registers.get(reg1) == 0);
|
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.increment(reg1, self.registers.get(reg2));
|
||||||
} else if reg1.is_8bit() && reg2.is_16bit() {
|
} else if reg1.is_8bit() && reg2.is_16bit() {
|
||||||
let val1 = self.registers.get(reg1);
|
let val1 = self.registers.get(reg1);
|
||||||
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.increment(reg1, 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);
|
||||||
}
|
}
|
||||||
@ -550,7 +552,7 @@ impl CPU {
|
|||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
let val1 = self.registers.get(reg1);
|
let val1 = self.registers.get(reg1);
|
||||||
let val2 = val as u16;
|
let val2 = val as u16;
|
||||||
self.registers.set(reg1, val1 + val2);
|
self.registers.increment(reg1, 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);
|
||||||
@ -559,7 +561,7 @@ impl CPU {
|
|||||||
self.registers.increment(Register::PC, 1);
|
self.registers.increment(Register::PC, 1);
|
||||||
let val1 = self.registers.get(reg1) as i16;
|
let val1 = self.registers.get(reg1) as i16;
|
||||||
let val2 = value as i16;
|
let val2 = value as i16;
|
||||||
self.registers.set(reg1, (val1 + val2) as u16);
|
self.registers.increment(reg1, val2 as u16);
|
||||||
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);
|
||||||
@ -615,7 +617,7 @@ impl CPU {
|
|||||||
if carry {
|
if carry {
|
||||||
val1 = val1 | 0x100;
|
val1 = val1 | 0x100;
|
||||||
}
|
}
|
||||||
let result = val1 - val2;
|
let result = val1.wrapping_sub(val2);
|
||||||
self.registers.set(register, result);
|
self.registers.set(register, result);
|
||||||
self.registers.set_flag(FlagRegister::Zero, self.registers.get(register) == 0);
|
self.registers.set_flag(FlagRegister::Zero, self.registers.get(register) == 0);
|
||||||
self.registers.set_flag(FlagRegister::Substract, true);
|
self.registers.set_flag(FlagRegister::Substract, true);
|
||||||
@ -649,7 +651,7 @@ impl CPU {
|
|||||||
if on_address {
|
if on_address {
|
||||||
let addr = self.registers.get(register);
|
let addr = self.registers.get(register);
|
||||||
let prev_value = bus.read(addr);
|
let prev_value = bus.read(addr);
|
||||||
bus.write(addr, prev_value + 1);
|
bus.write(addr, prev_value.wrapping_add(1));
|
||||||
if affect_flags {
|
if affect_flags {
|
||||||
self.registers.set_flag(FlagRegister::Substract, false);
|
self.registers.set_flag(FlagRegister::Substract, false);
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(prev_value, 1));
|
self.registers.set_flag(FlagRegister::HalfCarry, add_half_carry(prev_value, 1));
|
||||||
@ -677,7 +679,7 @@ impl CPU {
|
|||||||
if on_address {
|
if on_address {
|
||||||
let addr = self.registers.get(register);
|
let addr = self.registers.get(register);
|
||||||
let prev_value = bus.read(addr);
|
let prev_value = bus.read(addr);
|
||||||
bus.write(addr, prev_value - 1);
|
bus.write(addr, prev_value.wrapping_sub(1));
|
||||||
if affect_flags {
|
if affect_flags {
|
||||||
self.registers.set_flag(FlagRegister::Substract, true);
|
self.registers.set_flag(FlagRegister::Substract, true);
|
||||||
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(prev_value, 1));
|
self.registers.set_flag(FlagRegister::HalfCarry, sub_half_carry(prev_value, 1));
|
||||||
|
Loading…
Reference in New Issue
Block a user