Add system-specific boot symbols and CPU instruction tests

Introduced symbol files for various Game Boy systems (CGB, AGB, MGB, SGB) to define boot sequences and functionalities. Included CPU instruction behavior tests, with detailed coverage of standard operations and interrupt handling. Added documentation for test execution and internal framework operations.
This commit is contained in:
2025-05-02 17:33:07 +01:00
parent ae44d43175
commit 918c9020b5
74 changed files with 5037 additions and 7 deletions

View File

@@ -9,6 +9,8 @@ struct CPU {
pc: u16,
bus: MemoryBus,
sp: u16,
boot_rom: Vec<u8>,
game_rom: Vec<u8>,
}
const VRAM_BEGIN: usize = 0x8000;
const VRAM_END: usize = 0x9FFF;
@@ -117,14 +119,14 @@ impl MemoryBus {
self.write_byte(address.wrapping_add(1), high);
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
enum Target {
U8Register(TargetRegister),
U16Register(TargetU16Register),
Address(u16),
Immediate(u8)
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
enum Condition {
NZ, // Not Zero
Z, // Zero
@@ -133,7 +135,7 @@ enum Condition {
None
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
enum LoadTarget{
CopyR8R8(TargetRegister, TargetRegister),
CopyR8N8(TargetRegister, u8),
@@ -162,6 +164,7 @@ enum LoadTarget{
}
#[derive(Debug)]
enum Instruction {
ADC(Target),
ADD(Target),
@@ -208,11 +211,28 @@ enum Instruction {
SWAP(Target),
XOR(Target),
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
enum TargetRegister { A, B, C, D, E, H, L, }
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
enum TargetU16Register {AF, BC, DE, HL, SP, PC}
impl CPU {
fn init(&mut self) {
let l = self.bus.memory.len();
println!("{l}");
println!("CPU init");
// println!("Boot ROM: {:02X?}", self.boot_rom);
for (address, byte) in self.boot_rom.iter().enumerate() {
self.bus.write_byte(address as u16, *byte);
}
// println!("Game ROM: {:02X?}", self.game_rom);
for (address, byte) in self.game_rom.iter().enumerate() {
if address < 0x100 { continue; }
if address >= 0x4000 { break; }
self.bus.write_byte(address as u16, *byte);
}
}
fn check_condition(&self, condition: Condition) -> bool {
match condition {
Condition::NZ => !self.registers.f.zero,
@@ -1264,11 +1284,23 @@ impl CPU {
fn main() {
let boot_rom = std::fs::read("boot/dmg.bin").unwrap();
let game_rom = std::fs::read("cpu_instrs/cpu_instrs.gb").unwrap();
let gameboy = CPU{
let mut gameboy = CPU{
registers:Registers{a:0,b:0,c:0,d:0,e:0,f:FlagsRegister::from(0),h:0,l:0},
pc:0,
bus:MemoryBus{ memory: [0xFFu8; 0xFFFF], gpu:GPU{ vram: Vec::with_capacity(VRAM_END-VRAM_BEGIN), tile_set: [[[TilePixelValue::Zero; 8]; 8]; 384] }},
sp: 0
sp: 0,
boot_rom,
game_rom,
};
gameboy.init();
let sp = gameboy.sp;
println!("{sp:?}");
let f = gameboy.next_instruction();
println!("{f:?}");
gameboy.execute(f);
let sp = gameboy.sp;
println!("{sp:?}");
}