built in bootroms!!

This commit is contained in:
Alex Janka 2023-04-26 12:42:42 +10:00
parent b3b0d94522
commit e738419d4d
4 changed files with 41 additions and 116 deletions

View file

@ -76,16 +76,8 @@ where
RomFile::Raw(data) => Rom::load(data, None, camera.clone()), RomFile::Raw(data) => Rom::load(data, None, camera.clone()),
}; };
let bootrom_enabled = if options.bootrom.is_some() { let (bootrom_enabled, bootrom, cgb) = if let Some(b) = options.bootrom {
if options.skip_bootrom { let bootrom = match b {
RunBootrom::Skip
} else {
RunBootrom::Yes
}
} else {
RunBootrom::No
};
let bootrom: Option<Vec<u8>> = options.bootrom.map(|v| match v {
RomFile::Path(path) => match fs::read(path) { RomFile::Path(path) => match fs::read(path) {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
@ -94,11 +86,27 @@ where
} }
}, },
RomFile::Raw(data) => data, RomFile::Raw(data) => data,
}); };
let cgb =
let cgb = rom.rom_type == CgbRomType::CgbOnly rom.rom_type == CgbRomType::CgbOnly || options.cgb_mode || bootrom.len() > 256;
|| options.cgb_mode (
|| bootrom.as_ref().map_or(false, |v| v.len() > 256); if options.skip_bootrom {
RunBootrom::Skip
} else {
RunBootrom::Yes
},
bootrom,
cgb,
)
} else {
let cgb = rom.rom_type == CgbRomType::CgbOnly || options.cgb_mode;
let bootrom = if cgb {
include_bytes!("../../sameboy-bootroms/cgb_boot.bin").to_vec()
} else {
include_bytes!("../../sameboy-bootroms/dmg_boot.bin").to_vec()
};
(RunBootrom::Skip, bootrom, cgb)
};
options.window.prepare(WIDTH, HEIGHT); options.window.prepare(WIDTH, HEIGHT);
options.window.set_title(format!( options.window.set_title(format!(

View file

@ -208,12 +208,12 @@ where
{ {
pub(crate) fn init( pub(crate) fn init(
cgb: bool, cgb: bool,
bootrom: Option<Vec<u8>>, bootrom: Vec<u8>,
rom: Rom<C>, rom: Rom<C>,
output: OutputTargets<ColourFormat, R, C>, output: OutputTargets<ColourFormat, R, C>,
) -> Self { ) -> Self {
Self { Self {
bootrom, bootrom: Some(bootrom),
rom, rom,
ram: Wram::new(cgb), ram: Wram::new(cgb),
cpu_ram: [0x0; 128], cpu_ram: [0x0; 128],
@ -450,32 +450,6 @@ where
self.joypad.update_pressed_keys(latest_state) self.joypad.update_pressed_keys(latest_state)
} }
pub(super) fn cpu_ram_init(&mut self) {
self.set(0xFF04, 0xAD);
// self.set(0xFF10, 0x80);
// self.set(0xFF11, 0xBF);
// self.set(0xFF12, 0xF3);
// self.set(0xFF14, 0xBF);
// self.set(0xFF16, 0x3F);
// self.set(0xFF19, 0xBF);
// self.set(0xFF1A, 0x7F);
// self.set(0xFF1B, 0xFF);
// self.set(0xFF1C, 0x9F);
// self.set(0xFF1E, 0xBF);
// self.set(0xFF20, 0xFF);
// self.set(0xFF23, 0xBF);
// self.set(0xFF24, 0x77);
// self.set(0xFF25, 0xF3);
// self.set(0xFF26, 0xF1);
self.set(0xFF40, 0x91);
self.set(0xFF47, 0xFC);
self.set(0xFF48, 0xFF);
self.set(0xFF49, 0xFF);
for i in 0xC000..0xE000 {
self.set(i, if rand::random() { 0xFF } else { 0x00 });
}
}
pub fn flush_rom(&mut self) { pub fn flush_rom(&mut self) {
self.rom.flush(); self.rom.flush();
} }

View file

@ -298,44 +298,3 @@ fn get_cgb_rom_type(data: u8) -> CgbRomType {
_ => CgbRomType::Dmg, _ => CgbRomType::Dmg,
} }
} }
const CHECKSUM_TABLE: [u8; 79] = [
0x00, 0x88, 0x16, 0x36, 0xD1, 0xDB, 0xF2, 0x3C, 0x8C, 0x92, 0x3D, 0x5C, 0x58, 0xC9, 0x3E, 0x70,
0x1D, 0x59, 0x69, 0x19, 0x35, 0xA8, 0x14, 0xAA, 0x75, 0x95, 0x99, 0x34, 0x6F, 0x15, 0xFF, 0x97,
0x4B, 0x90, 0x17, 0x10, 0x39, 0xF7, 0xF6, 0xA2, 0x49, 0x4E, 0x43, 0x68, 0xE0, 0x8B, 0xF0, 0xCE,
0x0C, 0x29, 0xE8, 0xB7, 0x86, 0x9A, 0x52, 0x01, 0x9D, 0x71, 0x9C, 0xBD, 0x5D, 0x6D, 0x67, 0x3F,
0x6B, 0xB3, 0x46, 0x28, 0xA5, 0xC6, 0xD3, 0x27, 0x61, 0x18, 0x66, 0x6A, 0xBF, 0x0D, 0xF4,
];
const TIEBREAKER_TABLE: [u8; 29] = [
0x42, 0x45, 0x46, 0x41, 0x41, 0x52, 0x42, 0x45, 0x4B, 0x45, 0x4B, 0x20, 0x52, 0x2D, 0x55, 0x52,
0x41, 0x52, 0x20, 0x49, 0x4E, 0x41, 0x49, 0x4C, 0x49, 0x43, 0x45, 0x20, 0x52,
];
#[allow(dead_code)]
fn get_cgb_compat_palette(data: &[u8]) {
if data[0x14B] == 0x01 || (data[0x14B] == 0x33 && data[0x144] == 0x30 && data[0x145] == 0x31) {
let checksum = data
.iter()
.take(0x143)
.skip(0x134)
.fold(0_u8, |acc, val| acc.wrapping_add(*val));
let index = CHECKSUM_TABLE
.iter()
.position(|v| *v == checksum)
.unwrap_or(0);
if index <= 64 {
println!("checksum: {checksum:#X}, index: {index:#X}");
} else {
let fourth = data[0x137];
let tiebreaker = TIEBREAKER_TABLE
.iter()
.position(|v| *v == fourth)
.unwrap_or(0);
println!("checksum: {checksum:#X}, index: {index:#X}, fourth: {fourth:#X}, tiebreaker: {tiebreaker:#X}");
}
} else {
// zero
}
}

View file

@ -22,7 +22,6 @@ pub(crate) enum Direction {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum RunBootrom { pub(crate) enum RunBootrom {
No,
Yes, Yes,
Skip, Skip,
} }
@ -82,14 +81,10 @@ where
R: Renderer<ColourFormat>, R: Renderer<ColourFormat>,
C: PocketCamera + Send + 'static, C: PocketCamera + Send + 'static,
{ {
pub(crate) fn new(mut memory: Memory<ColourFormat, R, C>, run_bootrom: RunBootrom) -> Self { pub(crate) fn new(memory: Memory<ColourFormat, R, C>, run_bootrom: RunBootrom) -> Self {
let is_running_bootrom = run_bootrom != RunBootrom::No;
if !is_running_bootrom {
memory.cpu_ram_init();
}
Self { Self {
memory, memory,
reg: Registers::init(is_running_bootrom), reg: Registers::init(),
last_instruction: 0x0, last_instruction: 0x0,
last_instruction_addr: 0x0, last_instruction_addr: 0x0,
halted: false, halted: false,
@ -240,8 +235,7 @@ pub struct Registers {
} }
impl Registers { impl Registers {
fn init(run_bootrom: bool) -> Self { fn init() -> Self {
if run_bootrom {
Self { Self {
af: 0, af: 0,
bc: 0, bc: 0,
@ -250,16 +244,6 @@ impl Registers {
sp: 0xFFFE, sp: 0xFFFE,
pc: 0, pc: 0,
} }
} else {
Self {
af: 0x01B0,
bc: 0x0013,
de: 0x00D8,
hl: 0x014D,
sp: 0xFFFE,
pc: 0x0100,
}
}
} }
} }