diff --git a/gb-emu/src/main.rs b/gb-emu/src/main.rs index c5476c8..dcec1c9 100644 --- a/gb-emu/src/main.rs +++ b/gb-emu/src/main.rs @@ -40,7 +40,7 @@ struct Args { bootrom: Option, /// Connect the serial port output to stdout - #[arg(short, long)] + #[arg(long)] connect_serial: bool, /// Show cycle count @@ -62,6 +62,10 @@ struct Args { /// Run debug console #[arg(short, long)] debug: bool, + + /// Force CGB mode + #[arg(short, long)] + cgb: bool, } fn main() { @@ -109,7 +113,8 @@ fn main() { }) .with_bootrom(args.bootrom.map(RomFile::Path)) .with_no_save(args.no_save) - .with_tile_window(tile_window); + .with_tile_window(tile_window) + .with_cgb_mode(args.cgb); let mut core = EmulatorCore::init(receiver, options); diff --git a/lib/src/connect/mod.rs b/lib/src/connect/mod.rs index 7c48c4e..e76b7fc 100644 --- a/lib/src/connect/mod.rs +++ b/lib/src/connect/mod.rs @@ -166,6 +166,7 @@ where pub(crate) no_save: bool, pub(crate) bootrom: Option, pub(crate) serial_target: SerialTarget, + pub(crate) cgb_mode: bool, spooky: PhantomData, } @@ -185,6 +186,7 @@ where no_save: false, bootrom: None, serial_target: SerialTarget::None, + cgb_mode: false, spooky: PhantomData, } } @@ -207,6 +209,7 @@ where no_save: false, bootrom: None, serial_target: SerialTarget::None, + cgb_mode: false, spooky: PhantomData, } } @@ -245,4 +248,9 @@ where self.tile_window = window; self } + + pub fn with_cgb_mode(mut self, cgb_mode: bool) -> Self { + self.cgb_mode = cgb_mode; + self + } } diff --git a/lib/src/constants.rs b/lib/src/constants.rs index 6b29e1d..3c4d28d 100644 --- a/lib/src/constants.rs +++ b/lib/src/constants.rs @@ -1,7 +1,10 @@ -use crate::processor::memory::rom::CgbRomType; use once_cell::sync::OnceCell; // Hz pub const CLOCK_SPEED: usize = 4194304; -pub(crate) static IS_CGB: OnceCell = OnceCell::new(); +pub(crate) static STATIC_IS_CGB: OnceCell = OnceCell::new(); + +pub(crate) fn is_cgb() -> bool { + STATIC_IS_CGB.get().copied().unwrap_or(false) +} diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 3b94f9f..fa01c19 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -8,8 +8,9 @@ use connect::{ AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorMessage, EmulatorOptions, NoCamera, PocketCamera, Renderer, RomFile, SerialTarget, }; +use constants::{is_cgb, STATIC_IS_CGB}; use processor::{ - memory::{mmio::gpu::Colour, Rom}, + memory::{mmio::gpu::Colour, rom::CgbRomType, Rom}, Cpu, CpuSaveState, }; use std::{ @@ -76,10 +77,15 @@ where RomFile::Raw(data) => Rom::load(data, None, camera.clone()), }; + let _ = STATIC_IS_CGB.set(rom.rom_type == CgbRomType::CgbOnly || options.cgb_mode); + options.window.prepare(WIDTH, HEIGHT); - options - .window - .set_title(format!("{} on {}", rom.get_title(), rom.mbc_type())); + options.window.set_title(format!( + "{} on {} on {}", + rom.get_title(), + rom.mbc_type(), + if is_cgb() { "CGB" } else { "DMG" } + )); let bootrom_enabled = options.bootrom.is_some(); let bootrom: Option> = options.bootrom.map(|v| match v { diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index ee4fb14..365d9c7 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -11,6 +11,7 @@ use self::{ }; use crate::{ connect::{AudioOutput, CameraWrapperRef, JoypadState, PocketCamera, Renderer, SerialTarget}, + constants::is_cgb, Cpu, }; @@ -243,7 +244,13 @@ where 0xFF4B => self.gpu.get_wx(), 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, - IoAddress::Cgb(_) => todo!(), + IoAddress::Cgb(_) => { + if is_cgb() { + todo!(); + } else { + 0xFF + } + } IoAddress::Unused(_) => 0xFF, } } @@ -283,7 +290,11 @@ where 0xFF4B => self.gpu.update_wx(data), 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, - IoAddress::Cgb(_) => todo!(), + IoAddress::Cgb(_) => { + if is_cgb() { + todo!() + } + } IoAddress::Unused(_) => {} } } diff --git a/lib/src/processor/memory/rom.rs b/lib/src/processor/memory/rom.rs index b9284a9..44e50c5 100644 --- a/lib/src/processor/memory/rom.rs +++ b/lib/src/processor/memory/rom.rs @@ -1,9 +1,5 @@ +use crate::connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait}; use serde::{Deserialize, Serialize}; - -use crate::{ - connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait}, - constants::IS_CGB, -}; use std::{ fs::{File, OpenOptions}, io::{Read, Seek, SeekFrom, Write}, @@ -127,7 +123,7 @@ impl Drop for MaybeBufferedSram { } } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug, PartialEq)] pub(crate) enum CgbRomType { Dmg, CgbOptional, @@ -140,6 +136,7 @@ where { title: String, mbc: Box, + pub(crate) rom_type: CgbRomType, spooky: PhantomData, } @@ -207,7 +204,7 @@ where .expect("Error parsing title") .to_string(); - let _ = IS_CGB.set(get_cgb_rom_type(data[0x143])); + let rom_type = get_cgb_rom_type(data[0x143]); let _sgb_flag = data[0x146]; let rom_size = data[0x148]; @@ -238,6 +235,7 @@ where Self { title, mbc, + rom_type, spooky: PhantomData, } } @@ -247,10 +245,11 @@ where data: Vec, camera: CameraWrapperRef, ) -> Self { - let _ = IS_CGB.set(get_cgb_rom_type(data[0x143])); + let rom_type = get_cgb_rom_type(data[0x143]); Self { title: state.title, mbc: state.mbc.get_mbc(data, camera), + rom_type, spooky: PhantomData, } }