diff --git a/gb-emu/src/main.rs b/gb-emu/src/main.rs index c06f8a7..c5476c8 100644 --- a/gb-emu/src/main.rs +++ b/gb-emu/src/main.rs @@ -39,10 +39,6 @@ struct Args { #[arg(short, long)] bootrom: Option, - /// Verbose print - #[arg(short, long)] - verbose: bool, - /// Connect the serial port output to stdout #[arg(short, long)] connect_serial: bool, @@ -113,7 +109,6 @@ fn main() { }) .with_bootrom(args.bootrom.map(RomFile::Path)) .with_no_save(args.no_save) - .with_verbose(args.verbose) .with_tile_window(tile_window); let mut core = EmulatorCore::init(receiver, options); diff --git a/lib/src/connect/mod.rs b/lib/src/connect/mod.rs index 5f17769..7c48c4e 100644 --- a/lib/src/connect/mod.rs +++ b/lib/src/connect/mod.rs @@ -166,7 +166,6 @@ where pub(crate) no_save: bool, pub(crate) bootrom: Option, pub(crate) serial_target: SerialTarget, - pub(crate) verbose: bool, spooky: PhantomData, } @@ -186,7 +185,6 @@ where no_save: false, bootrom: None, serial_target: SerialTarget::None, - verbose: false, spooky: PhantomData, } } @@ -209,7 +207,6 @@ where no_save: false, bootrom: None, serial_target: SerialTarget::None, - verbose: false, spooky: PhantomData, } } @@ -229,11 +226,6 @@ where self } - pub fn with_verbose(mut self, verbose: bool) -> Self { - self.verbose = verbose; - self - } - pub fn with_bootrom(mut self, bootrom: Option) -> Self { self.bootrom = bootrom; self @@ -253,9 +245,4 @@ where self.tile_window = window; self } - - pub fn verbose(mut self) -> Self { - self.verbose = true; - self - } } diff --git a/lib/src/constants.rs b/lib/src/constants.rs index c7d16e5..6b29e1d 100644 --- a/lib/src/constants.rs +++ b/lib/src/constants.rs @@ -1,2 +1,7 @@ +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(); diff --git a/lib/src/lib.rs b/lib/src/lib.rs index a65a3e0..3b94f9f 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -8,7 +8,6 @@ use connect::{ AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorMessage, EmulatorOptions, NoCamera, PocketCamera, Renderer, RomFile, SerialTarget, }; -use once_cell::sync::OnceCell; use processor::{ memory::{mmio::gpu::Colour, Rom}, Cpu, CpuSaveState, @@ -28,8 +27,6 @@ mod constants; mod processor; pub mod util; -static VERBOSE: OnceCell = OnceCell::new(); - pub const WIDTH: usize = 160; pub const HEIGHT: usize = 144; @@ -54,10 +51,6 @@ where receiver: Receiver, mut options: EmulatorOptions, ) -> Self { - if options.verbose { - VERBOSE.set(true).unwrap(); - } - let camera: CameraWrapperRef = Arc::new(Mutex::new(CameraWrapper::new(options.camera))); let rom = match options.rom { diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index da43f23..ee4fb14 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -243,6 +243,7 @@ where 0xFF4B => self.gpu.get_wx(), 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, + IoAddress::Cgb(_) => todo!(), IoAddress::Unused(_) => 0xFF, } } @@ -282,6 +283,7 @@ where 0xFF4B => self.gpu.update_wx(data), 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, + IoAddress::Cgb(_) => todo!(), IoAddress::Unused(_) => {} } } diff --git a/lib/src/processor/memory/addresses.rs b/lib/src/processor/memory/addresses.rs index 0da8ea7..3a932ff 100644 --- a/lib/src/processor/memory/addresses.rs +++ b/lib/src/processor/memory/addresses.rs @@ -36,9 +36,12 @@ pub(crate) enum IoAddress { Audio(AudioAddress), WaveRam(WaveRamAddress), Video(VideoAddress), + Cgb(CgbIoAddress), Unused(u16), } +pub(crate) enum CgbIoAddress {} + pub(crate) enum Address { Rom(RomAddress), Vram(VramAddress), @@ -53,27 +56,6 @@ pub(crate) enum Address { InterruptEnable(InterruptEnable), } -impl TryInto for u16 { - type Error = AddressError; - - fn try_into(self) -> Result { - match self { - 0x0..0x4000 => Ok(RomAddress::Bank0(self.try_into().unwrap())), - 0x4000..0x8000 => Ok(RomAddress::MappedBank(self.try_into().unwrap())), - _ => Err(AddressError::OutOfBounds), - } - } -} - -impl AddressMarker for RomAddress { - fn inner(&self) -> u16 { - match self { - RomAddress::Bank0(v) => v.inner(), - RomAddress::MappedBank(v) => v.inner(), - } - } -} - impl From for Address { fn from(value: u16) -> Self { match value { @@ -92,6 +74,24 @@ impl From for Address { } } +impl From
for u16 { + fn from(value: Address) -> Self { + value.inner() + } +} + +impl TryInto for u16 { + type Error = AddressError; + + fn try_into(self) -> Result { + match self { + 0x0..0x4000 => Ok(RomAddress::Bank0(self.try_into().unwrap())), + 0x4000..0x8000 => Ok(RomAddress::MappedBank(self.try_into().unwrap())), + _ => Err(AddressError::OutOfBounds), + } + } +} + impl TryInto for u16 { type Error = AddressError; @@ -104,6 +104,7 @@ impl TryInto for u16 { 0xFF10..0xFF27 => Ok(IoAddress::Audio(self.try_into().unwrap())), 0xFF30..0xFF40 => Ok(IoAddress::WaveRam(self.try_into().unwrap())), 0xFF40..0xFF4C => Ok(IoAddress::Video(self.try_into().unwrap())), + 0xFF4D..0xFF78 => Ok(IoAddress::Cgb(self.try_into().unwrap())), 0x0..0xFF00 => Err(AddressError::OutOfBounds), 0xFFFF => Err(AddressError::OutOfBounds), _ => Ok(IoAddress::Unused(self)), @@ -111,6 +112,23 @@ impl TryInto for u16 { } } +impl TryInto for u16 { + type Error = AddressError; + + fn try_into(self) -> Result { + todo!() + } +} + +impl AddressMarker for RomAddress { + fn inner(&self) -> u16 { + match self { + RomAddress::Bank0(v) => v.inner(), + RomAddress::MappedBank(v) => v.inner(), + } + } +} + impl AddressMarker for IoAddress { fn inner(&self) -> u16 { match self { @@ -122,10 +140,17 @@ impl AddressMarker for IoAddress { IoAddress::WaveRam(v) => v.inner(), IoAddress::Video(v) => v.inner(), IoAddress::Unused(v) => *v, + IoAddress::Cgb(v) => v.inner(), } } } +impl AddressMarker for CgbIoAddress { + fn inner(&self) -> u16 { + todo!() + } +} + impl AddressMarker for Address { fn inner(&self) -> u16 { match self { @@ -144,12 +169,6 @@ impl AddressMarker for Address { } } -impl From
for u16 { - fn from(value: Address) -> Self { - value.inner() - } -} - impl Add for Address { type Output = Address; diff --git a/lib/src/processor/memory/rom.rs b/lib/src/processor/memory/rom.rs index 922a490..b9284a9 100644 --- a/lib/src/processor/memory/rom.rs +++ b/lib/src/processor/memory/rom.rs @@ -1,6 +1,9 @@ use serde::{Deserialize, Serialize}; -use crate::connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait}; +use crate::{ + connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait}, + constants::IS_CGB, +}; use std::{ fs::{File, OpenOptions}, io::{Read, Seek, SeekFrom, Write}, @@ -124,6 +127,13 @@ impl Drop for MaybeBufferedSram { } } +#[derive(Serialize, Deserialize)] +pub(crate) enum CgbRomType { + Dmg, + CgbOptional, + CgbOnly, +} + pub struct Rom where C: PocketCameraTrait, @@ -197,7 +207,7 @@ where .expect("Error parsing title") .to_string(); - let _gbc_flag = data[0x143]; + let _ = IS_CGB.set(get_cgb_rom_type(data[0x143])); let _sgb_flag = data[0x146]; let rom_size = data[0x148]; @@ -237,6 +247,7 @@ where data: Vec, camera: CameraWrapperRef, ) -> Self { + let _ = IS_CGB.set(get_cgb_rom_type(data[0x143])); Self { title: state.title, mbc: state.mbc.get_mbc(data, camera), @@ -281,6 +292,14 @@ where } } +fn get_cgb_rom_type(data: u8) -> CgbRomType { + match data { + 0x80 => CgbRomType::CgbOptional, + 0xC0 => CgbRomType::CgbOnly, + _ => 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, diff --git a/lib/src/processor/mod.rs b/lib/src/processor/mod.rs index 163d1fb..ef45b1d 100644 --- a/lib/src/processor/mod.rs +++ b/lib/src/processor/mod.rs @@ -1,10 +1,7 @@ use serde::{Deserialize, Serialize}; use self::memory::{mmio::gpu::Colour, Interrupt, Memory, MemorySaveState}; -use crate::{ - connect::{AudioOutput, CameraWrapperRef, PocketCamera, Renderer, SerialTarget}, - verbose_println, -}; +use crate::connect::{AudioOutput, CameraWrapperRef, PocketCamera, Renderer, SerialTarget}; mod instructions; pub mod memory; @@ -118,12 +115,6 @@ where } self.last_instruction = opcode; - verbose_println!( - "exec {:#4X} from pc: {:#X}", - opcode, - self.last_instruction_addr - ); - let cycles = self.run_opcode(opcode); self.memory.user_mode = false; self.increment_timers(cycles); diff --git a/lib/src/util.rs b/lib/src/util.rs index 796054a..0503ac2 100644 --- a/lib/src/util.rs +++ b/lib/src/util.rs @@ -1,27 +1,6 @@ -use crate::{ - processor::{memory::mmio::gpu::Colour, Direction}, - VERBOSE, -}; +use crate::processor::{memory::mmio::gpu::Colour, Direction}; use std::{io, mem::transmute}; -#[macro_export] -macro_rules! verbose_println { - ($($tts:tt)*) => { - if $crate::util::is_verbose() { - println!($($tts)*); - } - }; -} - -#[macro_export] -macro_rules! verbose_print { - ($($tts:tt)*) => { - if $crate::util::is_verbose() { - print!($($tts)*); - } - }; -} - pub(crate) fn pause() -> String { let mut line = String::new(); match io::stdin().read_line(&mut line) { @@ -30,13 +9,6 @@ pub(crate) fn pause() -> String { } } -pub(crate) fn is_verbose() -> bool { - match VERBOSE.get() { - Some(v) => *v, - None => false, - } -} - pub(crate) fn as_signed(unsigned: u8) -> i8 { unsafe { transmute(unsigned) } }