heheheh
This commit is contained in:
parent
02812aa458
commit
1d09a2500a
|
@ -39,10 +39,6 @@ struct Args {
|
|||
#[arg(short, long)]
|
||||
bootrom: Option<String>,
|
||||
|
||||
/// 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);
|
||||
|
|
|
@ -166,7 +166,6 @@ where
|
|||
pub(crate) no_save: bool,
|
||||
pub(crate) bootrom: Option<RomFile>,
|
||||
pub(crate) serial_target: SerialTarget,
|
||||
pub(crate) verbose: bool,
|
||||
spooky: PhantomData<ColourFormat>,
|
||||
}
|
||||
|
||||
|
@ -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<RomFile>) -> 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<CgbRomType> = OnceCell::new();
|
||||
|
|
|
@ -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<bool> = OnceCell::new();
|
||||
|
||||
pub const WIDTH: usize = 160;
|
||||
pub const HEIGHT: usize = 144;
|
||||
|
||||
|
@ -54,10 +51,6 @@ where
|
|||
receiver: Receiver<EmulatorMessage>,
|
||||
mut options: EmulatorOptions<ColourFormat, R, C>,
|
||||
) -> Self {
|
||||
if options.verbose {
|
||||
VERBOSE.set(true).unwrap();
|
||||
}
|
||||
|
||||
let camera: CameraWrapperRef<C> = Arc::new(Mutex::new(CameraWrapper::new(options.camera)));
|
||||
|
||||
let rom = match options.rom {
|
||||
|
|
|
@ -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(_) => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<RomAddress> for u16 {
|
||||
type Error = AddressError;
|
||||
|
||||
fn try_into(self) -> Result<RomAddress, Self::Error> {
|
||||
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<u16> for Address {
|
||||
fn from(value: u16) -> Self {
|
||||
match value {
|
||||
|
@ -92,6 +74,24 @@ impl From<u16> for Address {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Address> for u16 {
|
||||
fn from(value: Address) -> Self {
|
||||
value.inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<RomAddress> for u16 {
|
||||
type Error = AddressError;
|
||||
|
||||
fn try_into(self) -> Result<RomAddress, Self::Error> {
|
||||
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<IoAddress> for u16 {
|
||||
type Error = AddressError;
|
||||
|
||||
|
@ -104,6 +104,7 @@ impl TryInto<IoAddress> 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<IoAddress> for u16 {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryInto<CgbIoAddress> for u16 {
|
||||
type Error = AddressError;
|
||||
|
||||
fn try_into(self) -> Result<CgbIoAddress, Self::Error> {
|
||||
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<Address> for u16 {
|
||||
fn from(value: Address) -> Self {
|
||||
value.inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Address {
|
||||
type Output = Address;
|
||||
|
||||
|
|
|
@ -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<C>
|
||||
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<u8>,
|
||||
camera: CameraWrapperRef<C>,
|
||||
) -> 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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue