Refactor boot process and instruction execution

Introduce clearer boot ROM handling and streamline `execute_next_instruction` for better readability and accuracy. Add program counter (`pc`) updates within each instruction, improving program flow consistency.
This commit is contained in:
2025-05-06 16:20:23 +01:00
parent 74e86f1ab7
commit 9be93f4aa9

View File

@@ -119,12 +119,14 @@ struct CPU {
pc: u16, pc: u16,
bus: MemoryBus, bus: MemoryBus,
sp: u16, sp: u16,
boot_rom: Vec<u8>,
} }
const BOOT_BEGIN: usize = 0x0000;
const BOOT_END: usize = 0x00FF;
const CART_BEGIN: usize = 0x0100;
const CART_END: usize = 0x7FFF;
const VRAM_BEGIN: usize = 0x8000; const VRAM_BEGIN: usize = 0x8000;
const VRAM_END: usize = 0x9FFF; const VRAM_END: usize = 0x9FFF;
const CART_BEGIN: usize = 0x0000;
const CART_END: usize = 0x7FFF;
struct GPU { vram: Vec<u8>, tile_set: [[[TilePixelValue; 8]; 8]; 384] } struct GPU { vram: Vec<u8>, tile_set: [[[TilePixelValue; 8]; 8]; 384] }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum TilePixelValue { Three, Two, One, Zero } enum TilePixelValue { Three, Two, One, Zero }
@@ -134,7 +136,7 @@ impl GPU {
self.vram[address] self.vram[address]
} }
fn write_vram(&mut self, index: usize, value: u8) { fn write_vram(&mut self, index: usize, value: u8) {
self.vram[index] = value; // self.vram[index] = value;
// If our index is greater than 0x1800, we're not writing to the tile set storage // If our index is greater than 0x1800, we're not writing to the tile set storage
// so we can just return. // so we can just return.
if index >= 0x1800 { return } if index >= 0x1800 { return }
@@ -199,6 +201,7 @@ struct MemoryBus {
memory: [u8; 0xFFFF], memory: [u8; 0xFFFF],
gpu: GPU, gpu: GPU,
rom: GameRom, rom: GameRom,
boot: Vec<u8>,
} }
impl MemoryBus { impl MemoryBus {
fn read_byte(&self, address: u16) -> u8 { fn read_byte(&self, address: u16) -> u8 {
@@ -207,8 +210,15 @@ impl MemoryBus {
VRAM_BEGIN ..= VRAM_END => { VRAM_BEGIN ..= VRAM_END => {
self.gpu.read_vram(address - VRAM_BEGIN) self.gpu.read_vram(address - VRAM_BEGIN)
} }
BOOT_BEGIN..=BOOT_END => {
if self.memory[0xFF50] == 0x00 {
self.boot[address]
}else {
self.rom.read_byte(address)
}
}
CART_BEGIN ..= CART_END => {self.rom.read_byte(address)} CART_BEGIN ..= CART_END => {self.rom.read_byte(address)}
_ => self.memory[address as usize] _ => self.memory[address]
} }
} }
fn write_byte(&mut self, address: u16, value: u8) { fn write_byte(&mut self, address: u16, value: u8) {
@@ -334,12 +344,7 @@ impl CPU {
let l = self.bus.memory.len(); let l = self.bus.memory.len();
println!("{l}"); println!("{l}");
println!("CPU init"); println!("CPU init");
// println!("Boot ROM: {:02X?}", self.boot_rom); self.bus.write_byte(0xFF50, 0x00);
for (address, byte) in self.boot_rom.iter().enumerate() {
self.bus.write_byte(address as u16, *byte);
}
// println!("Game ROM: {:02X?}", self.game_rom);
} }
fn check_condition(&self, condition: Condition) -> bool { fn check_condition(&self, condition: Condition) -> bool {
match condition { match condition {
@@ -942,6 +947,14 @@ impl CPU {
_ => { panic!("Invalid u16 opcode: {:02X}", opcode); } _ => { panic!("Invalid u16 opcode: {:02X}", opcode); }
} }
} }
fn execute_next_instruction(&mut self) {
if self.pc >= 0x100 {
println!("Boot Complete");
}
let inst = self.next_instruction();
println!("{} {:?}", self.pc, inst);
self.execute(inst);
}
fn execute(&mut self, instruction: Instruction) { fn execute(&mut self, instruction: Instruction) {
match instruction { match instruction {
Instruction::ADC(target) => { Instruction::ADC(target) => {
@@ -953,6 +966,10 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::ADD(target) => { Instruction::ADD(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -962,6 +979,10 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::ADDHL(target) => { Instruction::ADDHL(target) => {
let value = self.get_u16_reg_value(target); let value = self.get_u16_reg_value(target);
@@ -971,6 +992,7 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (new_value & 0xFF) + (value & 0xFF) > 0xFF; self.registers.f.half_carry = (new_value & 0xFF) + (value & 0xFF) > 0xFF;
self.pc += 1;
} }
Instruction::ADDSP(value) => { Instruction::ADDSP(value) => {
let offset = (value as i16) as u16; let offset = (value as i16) as u16;
@@ -980,6 +1002,7 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (new_value & 0xFF) + (offset & 0xFF) > 0xFF; self.registers.f.half_carry = (new_value & 0xFF) + (offset & 0xFF) > 0xFF;
self.pc += 2;
} }
Instruction::AND(target) => { Instruction::AND(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -988,17 +1011,22 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = false; self.registers.f.carry = false;
self.registers.f.half_carry = true; self.registers.f.half_carry = true;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::BIT(bit, target) => { Instruction::BIT(bit, target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
self.registers.f.zero = value >> bit & 0x1 == 0; self.registers.f.zero = value >> bit & 0x1 == 0;
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = true; self.registers.f.half_carry = true;
self.pc += 2;
} }
Instruction::CALL(condition, address) => { Instruction::CALL(condition, address) => {
if self.check_condition(condition) { if self.check_condition(condition) {
self.sp = self.sp.wrapping_sub(2); self.sp = self.sp.wrapping_sub(2);
let pc = self.pc; let pc = self.pc+3;
self.bus.write_byte(self.sp + 1, ((pc >> 8) & 0xFF) as u8); self.bus.write_byte(self.sp + 1, ((pc >> 8) & 0xFF) as u8);
self.bus.write_byte(self.sp, (pc & 0xFF) as u8); self.bus.write_byte(self.sp, (pc & 0xFF) as u8);
self.pc = address; self.pc = address;
@@ -1008,6 +1036,7 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.registers.f.carry = !self.registers.f.carry; self.registers.f.carry = !self.registers.f.carry;
self.pc += 1;
} }
Instruction::CP(target) => { Instruction::CP(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1016,11 +1045,16 @@ impl CPU {
self.registers.f.subtract = true; self.registers.f.subtract = true;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::CPL => { Instruction::CPL => {
self.registers.a = !self.registers.a; self.registers.a = !self.registers.a;
self.registers.f.subtract = true; self.registers.f.subtract = true;
self.registers.f.half_carry = true; self.registers.f.half_carry = true;
self.pc += 1;
} }
Instruction::DAA => { Instruction::DAA => {
let new_value; let new_value;
@@ -1047,6 +1081,7 @@ impl CPU {
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.zero = new_value == 0; self.registers.f.zero = new_value == 0;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += 1;
} }
Instruction::DEC(target) => { Instruction::DEC(target) => {
match target { match target {
@@ -1066,6 +1101,7 @@ impl CPU {
Target::Address(_) => {} Target::Address(_) => {}
Target::Immediate(_) => {} Target::Immediate(_) => {}
} }
self.pc += 1;
} }
Instruction::DECHL(register) => { Instruction::DECHL(register) => {
let target = Target::U16Register(register); let target = Target::U16Register(register);
@@ -1075,10 +1111,17 @@ impl CPU {
self.registers.f.zero = new_value == 0; self.registers.f.zero = new_value == 0;
self.registers.f.subtract = true; self.registers.f.subtract = true;
self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
self.pc += 1;
}
Instruction::DI => {
self.pc += 1;
}
Instruction::EI => {
self.pc += 1;
}
Instruction::HALT => {
self.pc += 1;
} }
Instruction::DI => {}
Instruction::EI => {}
Instruction::HALT => {todo!();}
Instruction::INC(target) => { Instruction::INC(target) => {
match target { match target {
@@ -1098,6 +1141,7 @@ impl CPU {
Target::Address(_) => {} Target::Address(_) => {}
Target::Immediate(_) => {} Target::Immediate(_) => {}
} }
self.pc += 1;
} }
Instruction::INCHL(register) => { Instruction::INCHL(register) => {
let target = Target::U16Register(register); let target = Target::U16Register(register);
@@ -1107,6 +1151,7 @@ impl CPU {
self.registers.f.zero = new_value == 0; self.registers.f.zero = new_value == 0;
self.registers.f.subtract = true; self.registers.f.subtract = true;
self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (new_value & 0xF) + (value & 0xF) > 0xF;
self.pc += 1;
} }
Instruction::JP(condition, address) => { Instruction::JP(condition, address) => {
if self.check_condition(condition) { if self.check_condition(condition) {
@@ -1119,7 +1164,7 @@ impl CPU {
Instruction::JR(condition, offset) => { Instruction::JR(condition, offset) => {
if self.check_condition(condition) { if self.check_condition(condition) {
self.pc = if offset.is_negative() { self.pc = if offset.is_negative() {
self.pc.wrapping_sub(offset.abs() as u16) self.pc.wrapping_sub(offset.abs() as u16 - 1)
} else { } else {
self.pc.wrapping_add(offset as u16) self.pc.wrapping_add(offset as u16)
} }
@@ -1130,94 +1175,116 @@ impl CPU {
LoadTarget::CopyR8R8(dest_register, source_register) => { LoadTarget::CopyR8R8(dest_register, source_register) => {
let value = self.get_u8_reg_value(source_register); let value = self.get_u8_reg_value(source_register);
self.set_u8_reg_value(dest_register, value); self.set_u8_reg_value(dest_register, value);
self.pc += 1;
} }
LoadTarget::CopyR8N8(dest_register, value) => { LoadTarget::CopyR8N8(dest_register, value) => {
self.set_u8_reg_value(dest_register, value); self.set_u8_reg_value(dest_register, value);
self.pc += 2;
} }
LoadTarget::CopyR16N16(dest_register, value) => { LoadTarget::CopyR16N16(dest_register, value) => {
self.set_u16_reg_value(dest_register, value); self.set_u16_reg_value(dest_register, value);
self.pc += 3;
} }
LoadTarget::CopyHLR8(source_register) => { LoadTarget::CopyHLR8(source_register) => {
let value = self.get_u8_reg_value(source_register); let value = self.get_u8_reg_value(source_register);
let address = self.registers.get_hl(); let address = self.registers.get_hl();
self.bus.write_byte(address, value); self.bus.write_byte(address, value);
self.pc += 1;
} }
LoadTarget::CopyHLN8(value) => { LoadTarget::CopyHLN8(value) => {
let address = self.registers.get_hl(); let address = self.registers.get_hl();
self.bus.write_byte(address, value); self.bus.write_byte(address, value);
self.pc += 2;
} }
LoadTarget::CopyR8HL(dest_register) => { LoadTarget::CopyR8HL(dest_register) => {
let address = self.registers.get_hl(); let address = self.registers.get_hl();
let value = self.bus.read_byte(address); let value = self.bus.read_byte(address);
self.set_u8_reg_value(dest_register, value); self.set_u8_reg_value(dest_register, value);
self.pc += 1;
} }
LoadTarget::CopyR16A(dest_register) => { LoadTarget::CopyR16A(dest_register) => {
let address = self.get_u16_reg_value(dest_register); let address = self.get_u16_reg_value(dest_register);
self.bus.write_byte(address, self.registers.a); self.bus.write_byte(address, self.registers.a);
self.pc += 1;
} }
LoadTarget::CopyN16A(address) => { LoadTarget::CopyN16A(address) => {
self.bus.write_byte(address, self.registers.a); self.bus.write_byte(address, self.registers.a);
self.pc += 3;
} }
LoadTarget::CopyPortA(target) => { LoadTarget::CopyPortA(target) => {
let offset = self.get_target_value(target); let offset = self.get_target_value(target);
let address = 0xFF00 | offset as u16; let address = 0xFF00 | offset as u16;
self.bus.write_byte(address, self.registers.a); self.bus.write_byte(address, self.registers.a);
self.pc += 2;
} }
LoadTarget::CopyAPort(target) => { LoadTarget::CopyAPort(target) => {
let offset = self.get_target_value(target); let offset = self.get_target_value(target);
let address = 0xFF00 | offset as u16; let address = 0xFF00 | offset as u16;
self.registers.a = self.bus.read_byte(address); self.registers.a = self.bus.read_byte(address);
self.pc += 2;
} }
LoadTarget::CopyHN16A(address) => { LoadTarget::CopyHN16A(address) => {
if address >= 0xFF00 { if address >= 0xFF00 {
self.bus.write_byte(address, self.registers.a) self.bus.write_byte(address, self.registers.a)
} }
self.pc += 2;
} }
LoadTarget::CopyHCA => { LoadTarget::CopyHCA => {
let address = 0xFF00 + self.registers.c as u16; let address = 0xFF00 + self.registers.c as u16;
self.bus.write_byte(address, self.registers.a) self.bus.write_byte(address, self.registers.a);
self.pc += 1;
} }
LoadTarget::CopyAR16(source_register) => { LoadTarget::CopyAR16(source_register) => {
let address = self.get_u16_reg_value(source_register); let address = self.get_u16_reg_value(source_register);
self.registers.a = self.bus.read_byte(address); self.registers.a = self.bus.read_byte(address);
self.pc += 1;
} }
LoadTarget::CopyAN16(address) => { LoadTarget::CopyAN16(address) => {
self.registers.a = self.bus.read_byte(address); self.registers.a = self.bus.read_byte(address);
self.pc += 3;
} }
LoadTarget::CopyHAN16(address) => { LoadTarget::CopyHAN16(address) => {
if address >= 0xFF00 { if address >= 0xFF00 {
self.registers.a = self.bus.read_byte(address) self.registers.a = self.bus.read_byte(address);
} }
self.pc += 2;
} }
LoadTarget::CopyHAC => { LoadTarget::CopyHAC => {
self.registers.a = self.bus.read_byte(0xFF00+self.registers.c as u16) self.registers.a = self.bus.read_byte(0xFF00+self.registers.c as u16);
self.pc += 1;
} }
LoadTarget::CopyHLIA => { LoadTarget::CopyHLIA => {
let address = self.registers.get_hl(); let address = self.registers.get_hl();
self.bus.write_byte(address, self.registers.a); self.bus.write_byte(address, self.registers.a);
self.registers.set_hl(address.wrapping_add(1)); self.registers.set_hl(address.wrapping_add(1));
self.pc += 1;
} }
LoadTarget::CopyHLDA => { LoadTarget::CopyHLDA => {
let address = self.registers.get_hl(); let address = self.registers.get_hl();
self.bus.write_byte(address, self.registers.a); self.bus.write_byte(address, self.registers.a);
self.registers.set_hl(address.wrapping_sub(1)); self.registers.set_hl(address.wrapping_sub(1));
self.pc += 1;
} }
LoadTarget::CopyAHLI => { LoadTarget::CopyAHLI => {
let address = self.registers.get_hl(); let address = self.registers.get_hl();
self.registers.a = self.bus.read_byte(address); self.registers.a = self.bus.read_byte(address);
self.registers.set_hl(address.wrapping_add(1)); self.registers.set_hl(address.wrapping_add(1));
self.pc += 1;
} }
LoadTarget::CopyAHLD => { LoadTarget::CopyAHLD => {
let address = self.registers.get_hl(); let address = self.registers.get_hl();
self.registers.a = self.bus.read_byte(address); self.registers.a = self.bus.read_byte(address);
self.registers.set_hl(address.wrapping_sub(1)); self.registers.set_hl(address.wrapping_sub(1));
self.pc += 1;
} }
LoadTarget::CopySPN16(value) => { LoadTarget::CopySPN16(value) => {
self.sp = value; self.sp = value;
self.pc += 3;
} }
LoadTarget::CopyN16SP(address) => { LoadTarget::CopyN16SP(address) => {
self.bus.write_byte(address, (0xF & self.sp) as u8); self.bus.write_byte(address, (0xF & self.sp) as u8);
self.bus.write_byte(address + 1, (self.sp >> 8) as u8); self.bus.write_byte(address + 1, (self.sp >> 8) as u8);
self.pc += 3;
} }
LoadTarget::CopyHLSPE8(value) => { LoadTarget::CopyHLSPE8(value) => {
@@ -1230,14 +1297,17 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = (new_value & 0xFF) + (self.sp & 0xFF) > 0xFF; self.registers.f.carry = (new_value & 0xFF) + (self.sp & 0xFF) > 0xFF;
self.registers.f.half_carry = (new_value & 0xF) + (self.sp & 0xF) > 0xF; self.registers.f.half_carry = (new_value & 0xF) + (self.sp & 0xF) > 0xF;
self.pc += 2;
} }
LoadTarget::CopySPHL => { LoadTarget::CopySPHL => {
self.sp = self.registers.get_hl(); self.sp = self.registers.get_hl();
self.pc += 1;
} }
} }
} }
Instruction::NOP => {} Instruction::NOP => {
self.pc += 1;
}
Instruction::OR(target) => { Instruction::OR(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
self.registers.a = value | self.registers.a; self.registers.a = value | self.registers.a;
@@ -1245,23 +1315,32 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = false; self.registers.f.carry = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::POP(target) => { Instruction::POP(target) => {
let value = self.pop_stack(); let value = self.pop_stack();
self.set_u16_reg_value(target, value); self.set_u16_reg_value(target, value);
self.pc += 1;
} }
Instruction::PUSH(target) => { Instruction::PUSH(target) => {
let value = self.get_u16_reg_value(target); let value = self.get_u16_reg_value(target);
self.push_stack(value); self.push_stack(value);
self.pc += 1;
} }
Instruction::RES(bit, target) => { Instruction::RES(bit, target) => {
let mut value = self.get_target_value(target); let mut value = self.get_target_value(target);
value &= !(1 << bit); value &= !(1 << bit);
self.set_target_value(target, value); self.set_target_value(target, value);
self.pc += 2;
} }
Instruction::RET(condition) => { Instruction::RET(condition) => {
if self.check_condition(condition) { if self.check_condition(condition) {
self.pc = self.pop_stack(); self.pc = self.pop_stack();
} else {
self.pc += 1;
} }
} }
Instruction::RETI => { Instruction::RETI => {
@@ -1276,6 +1355,10 @@ impl CPU {
self.registers.f.zero = false; self.registers.f.zero = false;
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += match self.bus.read_byte(self.pc) {
0x17 => {1}
_ => {2}
}
} }
Instruction::RLC(target) => { Instruction::RLC(target) => {
let old_value = self.get_target_value(target); let old_value = self.get_target_value(target);
@@ -1285,6 +1368,10 @@ impl CPU {
self.registers.f.zero = false; self.registers.f.zero = false;
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += match self.bus.read_byte(self.pc) {
0x07 => {1}
_ => {2}
}
} }
Instruction::RR(target) => { Instruction::RR(target) => {
let old_value = self.get_target_value(target); let old_value = self.get_target_value(target);
@@ -1295,6 +1382,10 @@ impl CPU {
self.registers.f.zero = false; self.registers.f.zero = false;
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += match self.bus.read_byte(self.pc) {
0x1F => {1}
_ => {2}
}
} }
Instruction::RRC(target) => { Instruction::RRC(target) => {
let old_value = self.get_target_value(target); let old_value = self.get_target_value(target);
@@ -1304,6 +1395,10 @@ impl CPU {
self.registers.f.zero = false; self.registers.f.zero = false;
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += match self.bus.read_byte(self.pc) {
0x0F => {1}
_ => {2}
}
} }
Instruction::RST(idx) => { Instruction::RST(idx) => {
self.push_stack(self.pc); self.push_stack(self.pc);
@@ -1319,16 +1414,22 @@ impl CPU {
self.registers.f.subtract = true; self.registers.f.subtract = true;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::SCF => { Instruction::SCF => {
self.registers.f.carry = true; self.registers.f.carry = true;
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += 1;
} }
Instruction::SET(bit, target) => { Instruction::SET(bit, target) => {
let mut value = self.get_target_value(target); let mut value = self.get_target_value(target);
value |= 1 << bit; value |= 1 << bit;
self.set_target_value(target, value); self.set_target_value(target, value);
self.pc += 2;
} }
Instruction::SLA(target) => { Instruction::SLA(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1338,6 +1439,7 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = value & 0x80 == 0x80; self.registers.f.carry = value & 0x80 == 0x80;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += 2;
} }
Instruction::SRA(target) => { Instruction::SRA(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1347,6 +1449,7 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = value & 0x80 == 0x80; self.registers.f.carry = value & 0x80 == 0x80;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += 2;
} }
Instruction::SRL(target) => { Instruction::SRL(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1356,9 +1459,10 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = value & 0x1 == 0x1; self.registers.f.carry = value & 0x1 == 0x1;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += 2;
} }
Instruction::STOP(_) => { Instruction::STOP(_) => {
self.pc += 2;
} }
Instruction::SUB(target) => { Instruction::SUB(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1368,6 +1472,10 @@ impl CPU {
self.registers.f.subtract = true; self.registers.f.subtract = true;
self.registers.f.carry = did_overflow; self.registers.f.carry = did_overflow;
self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF; self.registers.f.half_carry = (self.registers.a & 0xF) + (value & 0xF) > 0xF;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
Instruction::SWAP(target) => { Instruction::SWAP(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1377,6 +1485,7 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = false; self.registers.f.carry = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += 2;
} }
Instruction::XOR(target) => { Instruction::XOR(target) => {
let value = self.get_target_value(target); let value = self.get_target_value(target);
@@ -1385,6 +1494,10 @@ impl CPU {
self.registers.f.subtract = false; self.registers.f.subtract = false;
self.registers.f.carry = false; self.registers.f.carry = false;
self.registers.f.half_carry = false; self.registers.f.half_carry = false;
self.pc += match target {
Target::Immediate(_) => {2}
_ => {1}
};
} }
} }
} }
@@ -1402,18 +1515,14 @@ fn main() {
pc:0, pc:0,
bus:MemoryBus{ bus:MemoryBus{
memory: [0xFFu8; 0xFFFF], memory: [0xFFu8; 0xFFFF],
gpu:GPU{ vram: Vec::with_capacity(VRAM_END-VRAM_BEGIN), tile_set: [[[TilePixelValue::Zero; 8]; 8]; 384] }, gpu:GPU{ vram: vec![0xFFu8;VRAM_END-VRAM_BEGIN+1], tile_set: [[[TilePixelValue::Zero; 8]; 8]; 384] },
rom: game_rom, rom: game_rom,
boot: boot_rom,
}, },
sp: 0, sp: 0,
boot_rom,
}; };
gameboy.init(); gameboy.init();
let sp = gameboy.sp; loop {
println!("{sp:?}"); gameboy.execute_next_instruction()
let f = gameboy.next_instruction(); }
println!("{f:?}");
gameboy.execute(f);
let sp = gameboy.sp;
println!("{sp:?}");
} }