Skip to content
Snippets Groups Projects
Verified Commit 399d03e3 authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

chore: DMG compat support

parent be6739a2
No related branches found
No related tags found
1 merge request!16Support for Game Boy Color (CGB) 😎🖍️
Pipeline #2635 passed
...@@ -127,6 +127,12 @@ pub struct GameBoyConfig { ...@@ -127,6 +127,12 @@ pub struct GameBoyConfig {
/// CPU frequency, PPU frequency, Boot rome size, etc. /// CPU frequency, PPU frequency, Boot rome size, etc.
mode: GameBoyMode, mode: GameBoyMode,
/// Flag that controls if the DMG compatibility mode is
/// enabled meaning that some of the PPU decisions will
/// be made differently to address this special situation
/// (CGB only).
dmg_compat: bool,
/// If the PPU is enabled, it will be clocked. /// If the PPU is enabled, it will be clocked.
ppu_enabled: bool, ppu_enabled: bool,
...@@ -170,6 +176,14 @@ impl GameBoyConfig { ...@@ -170,6 +176,14 @@ impl GameBoyConfig {
self.mode = value; self.mode = value;
} }
pub fn dmg_compat(&self) -> bool {
self.dmg_compat
}
pub fn set_dmg_compat(&mut self, value: bool) {
self.dmg_compat = value;
}
pub fn ppu_enabled(&self) -> bool { pub fn ppu_enabled(&self) -> bool {
self.ppu_enabled self.ppu_enabled
} }
...@@ -215,6 +229,7 @@ impl Default for GameBoyConfig { ...@@ -215,6 +229,7 @@ impl Default for GameBoyConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
mode: GameBoyMode::Dmg, mode: GameBoyMode::Dmg,
dmg_compat: false,
ppu_enabled: true, ppu_enabled: true,
apu_enabled: true, apu_enabled: true,
timer_enabled: true, timer_enabled: true,
...@@ -236,6 +251,12 @@ pub struct GameBoy { ...@@ -236,6 +251,12 @@ pub struct GameBoy {
/// kept for performance reasons. /// kept for performance reasons.
mode: GameBoyMode, mode: GameBoyMode,
/// Flag that controls if the DMG compatibility mode is
/// enabled meaning that some of the PPU decisions will
/// be made differently to address this special situation
/// (CGB only).
dmg_compat: bool,
/// If the PPU is enabled, it will be clocked. /// If the PPU is enabled, it will be clocked.
/// This is a clone of the configuration value /// This is a clone of the configuration value
/// kept for performance reasons. /// kept for performance reasons.
...@@ -312,6 +333,7 @@ impl GameBoy { ...@@ -312,6 +333,7 @@ impl GameBoy {
pub fn new(mode: GameBoyMode) -> Self { pub fn new(mode: GameBoyMode) -> Self {
let gbc = Rc::new(RefCell::new(GameBoyConfig { let gbc = Rc::new(RefCell::new(GameBoyConfig {
mode, mode,
dmg_compat: false,
ppu_enabled: true, ppu_enabled: true,
apu_enabled: true, apu_enabled: true,
timer_enabled: true, timer_enabled: true,
...@@ -329,6 +351,7 @@ impl GameBoy { ...@@ -329,6 +351,7 @@ impl GameBoy {
Self { Self {
mode, mode,
dmg_compat: false,
ppu_enabled: true, ppu_enabled: true,
apu_enabled: true, apu_enabled: true,
timer_enabled: true, timer_enabled: true,
...@@ -574,6 +597,18 @@ impl GameBoy { ...@@ -574,6 +597,18 @@ impl GameBoy {
String::from(COMPILATION_TIME) String::from(COMPILATION_TIME)
} }
pub fn is_dmg(&self) -> bool {
self.mode == GameBoyMode::Dmg
}
pub fn is_cgb(&self) -> bool {
self.mode == GameBoyMode::Cgb
}
pub fn is_sgb(&self) -> bool {
self.mode == GameBoyMode::Sgb
}
pub fn mode(&self) -> GameBoyMode { pub fn mode(&self) -> GameBoyMode {
self.mode self.mode
} }
...@@ -585,6 +620,15 @@ impl GameBoy { ...@@ -585,6 +620,15 @@ impl GameBoy {
self.ppu().set_gb_mode(value); self.ppu().set_gb_mode(value);
} }
pub fn dmg_compat(&self) -> bool {
self.dmg_compat
}
pub fn set_dmg_compat(&mut self, value: bool) {
self.dmg_compat = value;
(*self.gbc).borrow_mut().set_dmg_compat(value);
}
pub fn ppu_enabled(&self) -> bool { pub fn ppu_enabled(&self) -> bool {
self.ppu_enabled self.ppu_enabled
} }
...@@ -784,6 +828,7 @@ impl GameBoy { ...@@ -784,6 +828,7 @@ impl GameBoy {
pub fn load_rom(&mut self, data: &[u8]) -> &Cartridge { pub fn load_rom(&mut self, data: &[u8]) -> &Cartridge {
let rom = Cartridge::from_data(data); let rom = Cartridge::from_data(data);
self.set_dmg_compat(self.is_cgb() && rom.is_legacy());
self.mmu().set_rom(rom); self.mmu().set_rom(rom);
self.mmu().rom() self.mmu().rom()
} }
......
...@@ -404,6 +404,14 @@ impl Cartridge { ...@@ -404,6 +404,14 @@ impl Cartridge {
} }
} }
/// A cartridge is considered legacy if it does
/// not have a CGB flag bit (bit 7 of 0x0143) set.
/// These are the monochromatic only Cartridges built
/// for the original DMG Game Boy.
pub fn is_legacy(&self) -> bool {
self.rom_data[0x0143] & 0x80 == 0x00
}
pub fn rom_type(&self) -> RomType { pub fn rom_type(&self) -> RomType {
match self.rom_data[0x0147] { match self.rom_data[0x0147] {
0x00 => RomType::RomOnly, 0x00 => RomType::RomOnly,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment