From c0c523954ee89be4730f655753a5e4cb38ca2f16 Mon Sep 17 00:00:00 2001 From: luckasRanarison Date: Fri, 27 Dec 2024 19:21:59 +0300 Subject: [PATCH] wip: refactor rom module --- crates/mes-core/src/bus/ppu.rs | 2 +- crates/mes-core/src/features/json.rs | 2 +- crates/mes-core/src/lib.rs | 2 +- crates/mes-core/src/mappers/mapper_000.rs | 5 +- crates/mes-core/src/mappers/mapper_001.rs | 7 +- crates/mes-core/src/mappers/mapper_002.rs | 5 +- crates/mes-core/src/mappers/mapper_003.rs | 5 +- crates/mes-core/src/mappers/mod.rs | 6 +- .../{cartridge/mod.rs => rom/cartridge.rs} | 90 +++---------------- crates/mes-core/src/rom/fds.rs | 0 crates/mes-core/src/rom/ines.rs | 62 +++++++++++++ crates/mes-core/src/rom/mod.rs | 17 ++++ 12 files changed, 113 insertions(+), 90 deletions(-) rename crates/mes-core/src/{cartridge/mod.rs => rom/cartridge.rs} (61%) create mode 100644 crates/mes-core/src/rom/fds.rs create mode 100644 crates/mes-core/src/rom/ines.rs create mode 100644 crates/mes-core/src/rom/mod.rs diff --git a/crates/mes-core/src/bus/ppu.rs b/crates/mes-core/src/bus/ppu.rs index 7519042..3adff79 100644 --- a/crates/mes-core/src/bus/ppu.rs +++ b/crates/mes-core/src/bus/ppu.rs @@ -1,7 +1,7 @@ use crate::{ bus::Bus, - cartridge::Mirroring, mappers::{Mapper, MapperChip}, + rom::Mirroring, utils::{Clock, Reset}, }; diff --git a/crates/mes-core/src/features/json.rs b/crates/mes-core/src/features/json.rs index be19c85..697159b 100644 --- a/crates/mes-core/src/features/json.rs +++ b/crates/mes-core/src/features/json.rs @@ -1,4 +1,4 @@ -use crate::{cartridge::Header, error::Error}; +use crate::{error::Error, rom::ines::Header}; pub fn serialize_rom_header(bytes: &[u8]) -> Result { let header = Header::try_from_bytes(bytes)?; diff --git a/crates/mes-core/src/lib.rs b/crates/mes-core/src/lib.rs index 222ea4c..3df3c43 100644 --- a/crates/mes-core/src/lib.rs +++ b/crates/mes-core/src/lib.rs @@ -1,11 +1,11 @@ pub mod apu; pub mod bus; -pub mod cartridge; pub mod controller; pub mod cpu; pub mod error; pub mod mappers; pub mod ppu; +pub mod rom; pub mod utils; mod features; diff --git a/crates/mes-core/src/mappers/mapper_000.rs b/crates/mes-core/src/mappers/mapper_000.rs index f303144..b629235 100644 --- a/crates/mes-core/src/mappers/mapper_000.rs +++ b/crates/mes-core/src/mappers/mapper_000.rs @@ -2,7 +2,10 @@ use super::Mapper; use crate::{ - cartridge::{Cartridge, ChrPage, Mirroring, PrgPage}, + rom::{ + cartridge::{Cartridge, ChrPage, PrgPage}, + Mirroring, + }, utils::Reset, }; diff --git a/crates/mes-core/src/mappers/mapper_001.rs b/crates/mes-core/src/mappers/mapper_001.rs index 28fc0a4..b7ba3dd 100644 --- a/crates/mes-core/src/mappers/mapper_001.rs +++ b/crates/mes-core/src/mappers/mapper_001.rs @@ -2,7 +2,10 @@ use super::Mapper; use crate::{ - cartridge::{Cartridge, ChrPage, Mirroring, PrgPage}, + rom::{ + cartridge::{Cartridge, ChrPage, PrgPage}, + Mirroring, + }, utils::{BitFlag, Reset}, }; @@ -102,7 +105,7 @@ impl Mapper for SxRom { } } - fn get_mirroring(&self) -> crate::cartridge::Mirroring { + fn get_mirroring(&self) -> crate::rom::Mirroring { match self.control & 0b11 { 2 => Mirroring::Vertical, 3 => Mirroring::Horizontal, diff --git a/crates/mes-core/src/mappers/mapper_002.rs b/crates/mes-core/src/mappers/mapper_002.rs index fceef81..c278946 100644 --- a/crates/mes-core/src/mappers/mapper_002.rs +++ b/crates/mes-core/src/mappers/mapper_002.rs @@ -2,7 +2,10 @@ use super::Mapper; use crate::{ - cartridge::{Cartridge, ChrPage, Mirroring, PrgPage}, + rom::{ + cartridge::{Cartridge, ChrPage, PrgPage}, + Mirroring, + }, utils::Reset, }; diff --git a/crates/mes-core/src/mappers/mapper_003.rs b/crates/mes-core/src/mappers/mapper_003.rs index ea2d6e6..5af4962 100644 --- a/crates/mes-core/src/mappers/mapper_003.rs +++ b/crates/mes-core/src/mappers/mapper_003.rs @@ -2,7 +2,10 @@ use super::Mapper; use crate::{ - cartridge::{Cartridge, ChrPage, Mirroring, PrgPage}, + rom::{ + cartridge::{Cartridge, ChrPage, PrgPage}, + Mirroring, + }, utils::Reset, }; diff --git a/crates/mes-core/src/mappers/mod.rs b/crates/mes-core/src/mappers/mod.rs index bfbf7ee..a35955a 100644 --- a/crates/mes-core/src/mappers/mod.rs +++ b/crates/mes-core/src/mappers/mod.rs @@ -6,8 +6,8 @@ mod mapper_003; use self::{mapper_000::NRom, mapper_001::SxRom, mapper_002::UxRom, mapper_003::CnRom}; use crate::{ - cartridge::{Cartridge, Mirroring}, error::Error, + rom::{cartridge::Cartridge, Mirroring}, utils::{MemoryObserver, Reset}, }; @@ -26,7 +26,7 @@ pub struct MapperBuilder { impl MapperBuilder { pub fn new(cartridge: &[u8]) -> Result { Ok(Self { - cartridge: Cartridge::try_from_bytes(cartridge)?, + cartridge: Cartridge::try_from_ines(cartridge)?, }) } @@ -58,7 +58,7 @@ impl MapperChip { } pub fn try_from_bytes(bytes: &[u8]) -> Result { - Cartridge::try_from_bytes(bytes).and_then(MapperChip::try_from) + Cartridge::try_from_ines(bytes).and_then(MapperChip::try_from) } } diff --git a/crates/mes-core/src/cartridge/mod.rs b/crates/mes-core/src/rom/cartridge.rs similarity index 61% rename from crates/mes-core/src/cartridge/mod.rs rename to crates/mes-core/src/rom/cartridge.rs index 057fa08..bdae6c2 100644 --- a/crates/mes-core/src/cartridge/mod.rs +++ b/crates/mes-core/src/rom/cartridge.rs @@ -1,81 +1,14 @@ -// https://www.nesdev.org/wiki/INES +use crate::{error::Error, utils::MemoryObserver}; -use crate::{ - error::Error, - utils::{BitFlag, MemoryObserver}, +use super::{ + ines::{Header, INES_HEADER_SIZE, TRAINER_SIZE}, + Mirroring, }; -#[cfg(feature = "json")] -use serde::Serialize; - -const INES_ASCII: [u8; 4] = [0x4E, 0x45, 0x53, 0x1A]; -const INES_HEADER_SIZE: usize = 16; -const TRAINER_SIZE: usize = 512; -const PRG_ROM_PAGE_SIZE: usize = 16384; -const PRG_RAM_SIZE: usize = 8192; -const CHR_ROM_PAGE_SIZE: usize = 8192; -const CHR_RAM_PAGE_SIZE: usize = 8192; - -pub fn is_ines_file(bytes: &[u8]) -> bool { - bytes[0..4] == INES_ASCII -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "json", derive(Serialize))] -pub enum Mirroring { - Vertical, - Horizontal, - OneScreen, - FourScreen, -} - -#[derive(Debug)] -#[cfg_attr(feature = "json", derive(Serialize))] -pub struct Header { - pub prg_rom_pages: u8, - pub chr_rom_pages: u8, - pub prg_ram_pages: u8, - pub mirroring: Mirroring, - pub battery: bool, - pub trainer: bool, - pub mapper: u8, -} - -impl Header { - pub fn try_from_bytes(bytes: &[u8]) -> Result { - if !is_ines_file(bytes) { - return Err(Error::UnsupportedFileFormat); - } - - let prg_rom_pages = *bytes.get(4).ok_or(Error::eof("PRG ROM pages", 1))?; - let chr_rom_pages = *bytes.get(5).ok_or(Error::eof("CHR ROM pages", 1))?; - let flags_6 = bytes.get(6).ok_or(Error::eof("Flags 6", 1))?; - let flags_7 = bytes.get(7).ok_or(Error::eof("Flags 7", 1))?; - let prg_ram_pages = *bytes.get(8).ok_or(Error::eof("PRG RAM pages", 1))?; - - let battery = flags_6.contains(1); - let trainer = flags_6.contains(2); - let mapper = (flags_7 & 0xF0) | (flags_6 >> 4); - let is_vertical_mirroring = flags_6.contains(0); - let is_four_screen = flags_6.contains(3); - - let mirroring = match (is_four_screen, is_vertical_mirroring) { - (true, _) => Mirroring::FourScreen, - (false, true) => Mirroring::Vertical, - (false, false) => Mirroring::Horizontal, - }; - - Ok(Self { - prg_rom_pages, - prg_ram_pages, - chr_rom_pages, - mirroring, - battery, - trainer, - mapper, - }) - } -} +pub const PRG_ROM_PAGE_SIZE: usize = 16384; +pub const PRG_RAM_SIZE: usize = 8192; +pub const CHR_ROM_PAGE_SIZE: usize = 8192; +pub const CHR_RAM_PAGE_SIZE: usize = 8192; pub enum ChrPage { Index4(u8), @@ -104,7 +37,7 @@ impl std::fmt::Debug for Cartridge { } impl Cartridge { - pub fn try_from_bytes(bytes: &[u8]) -> Result { + pub fn try_from_ines(bytes: &[u8]) -> Result { let header = Header::try_from_bytes(bytes)?; let prg_rom_size = header.prg_rom_pages as usize * PRG_ROM_PAGE_SIZE; @@ -113,8 +46,7 @@ impl Cartridge { let chr_rom_start = prg_rom_start + prg_rom_size; let prg_rom = bytes[prg_rom_start..prg_rom_start + prg_rom_size].to_vec(); let chr_rom = bytes[chr_rom_start..chr_rom_start + chr_rom_size].to_vec(); - let prg_ram_size = PRG_RAM_SIZE; - let prg_ram = vec![0_u8; prg_ram_size]; + let prg_ram = vec![0_u8; PRG_RAM_SIZE]; let chr_ram_size = (header.chr_rom_pages == 0) as usize * CHR_RAM_PAGE_SIZE; let chr_ram = vec![0_u8; chr_ram_size]; @@ -207,7 +139,7 @@ mod tests { #[test] fn test_load_rom() { - let rom = Cartridge::try_from_bytes(&NESTEST_ROM); + let rom = Cartridge::try_from_ines(&NESTEST_ROM); assert!(rom.is_ok()); } diff --git a/crates/mes-core/src/rom/fds.rs b/crates/mes-core/src/rom/fds.rs new file mode 100644 index 0000000..e69de29 diff --git a/crates/mes-core/src/rom/ines.rs b/crates/mes-core/src/rom/ines.rs new file mode 100644 index 0000000..31bf6e8 --- /dev/null +++ b/crates/mes-core/src/rom/ines.rs @@ -0,0 +1,62 @@ +#[cfg(feature = "json")] +use serde::Serialize; + +use crate::{error::Error, utils::BitFlag}; + +use super::Mirroring; + +pub const INES_ASCII: [u8; 4] = [0x4E, 0x45, 0x53, 0x1A]; +pub const INES_HEADER_SIZE: usize = 16; +pub const TRAINER_SIZE: usize = 512; + +pub fn is_ines_file(bytes: &[u8]) -> bool { + bytes[0..4] == INES_ASCII +} + +#[derive(Debug)] +#[cfg_attr(feature = "json", derive(Serialize))] +pub struct Header { + pub prg_rom_pages: u8, + pub chr_rom_pages: u8, + pub prg_ram_pages: u8, + pub mirroring: Mirroring, + pub battery: bool, + pub trainer: bool, + pub mapper: u8, +} + +impl Header { + pub fn try_from_bytes(bytes: &[u8]) -> Result { + if !is_ines_file(bytes) { + return Err(Error::UnsupportedFileFormat); + } + + let prg_rom_pages = *bytes.get(4).ok_or(Error::eof("PRG ROM pages", 1))?; + let chr_rom_pages = *bytes.get(5).ok_or(Error::eof("CHR ROM pages", 1))?; + let flags_6 = bytes.get(6).ok_or(Error::eof("Flags 6", 1))?; + let flags_7 = bytes.get(7).ok_or(Error::eof("Flags 7", 1))?; + let prg_ram_pages = *bytes.get(8).ok_or(Error::eof("PRG RAM pages", 1))?; + + let battery = flags_6.contains(1); + let trainer = flags_6.contains(2); + let mapper = (flags_7 & 0xF0) | (flags_6 >> 4); + let is_vertical_mirroring = flags_6.contains(0); + let is_four_screen = flags_6.contains(3); + + let mirroring = match (is_four_screen, is_vertical_mirroring) { + (true, _) => Mirroring::FourScreen, + (false, true) => Mirroring::Vertical, + (false, false) => Mirroring::Horizontal, + }; + + Ok(Self { + prg_rom_pages, + prg_ram_pages, + chr_rom_pages, + mirroring, + battery, + trainer, + mapper, + }) + } +} diff --git a/crates/mes-core/src/rom/mod.rs b/crates/mes-core/src/rom/mod.rs new file mode 100644 index 0000000..2e4cbb4 --- /dev/null +++ b/crates/mes-core/src/rom/mod.rs @@ -0,0 +1,17 @@ +// https://www.nesdev.org/wiki/INES + +pub mod cartridge; +pub mod fds; +pub mod ines; + +#[cfg(feature = "json")] +use serde::Serialize; + +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "json", derive(Serialize))] +pub enum Mirroring { + Vertical, + Horizontal, + OneScreen, + FourScreen, +}