Skip to main content

Header

Struct Header 

Source
#[non_exhaustive]
pub struct Header {
Show 20 fields pub is_nes2: bool, pub mapper_id: u16, pub submapper: u8, pub prg_size: usize, pub chr_size: usize, pub mirroring: Mirroring, pub region: Region, pub console_type: ConsoleType, pub vs_ppu_type: VsPpuType, pub vs_hardware_type: Option<VsHardwareType>, pub extended_console_type: Option<ExtendedConsoleType>, pub misc_rom_count: u8, pub default_expansion_device: ExpansionDevice, pub prg_ram_size: u32, pub prg_nvram_size: u32, pub chr_ram_size: u32, pub chr_nvram_size: u32, pub has_battery: bool, pub has_trainer: bool, pub four_screen: bool,
}
Expand description

Parsed header view, format-detected.

Every field a 16-byte iNES / NES 2.0 header defines is modelled (since v2.9.8): what is left over are the reserved bits (byte 12 bits 2-7, byte 13 for console types 0 and 2, byte 13 bits 4-7 for console type 3, byte 14 bits 2-7, byte 15 bit 7) and, on an iNES 1.0 header, bytes 8-15, which are not part of that format. serialize_header_preserving keeps all of those.

iNES 1.0. The NES 2.0-only fields hold a fixed value on an iNES 1.0 header, whatever its bytes 8-15 contain (old dumpers wrote signatures there): submapper 0, region NTSC, console_type NES, vs_hardware_type / extended_console_type None, vs_ppu_type VsPpuType::None, misc_rom_count 0, default_expansion_device ExpansionDevice::Unspecified, both NVRAM sizes 0, and the two RAM sizes the nominal values described on each field.

#[non_exhaustive]: outside this crate, build one with Header::default and field assignment (or parse_header), so a field added later is not an API break.

The 5 boolean flags directly mirror the iNES / NES 2.0 wire format and so are not refactorable into an enum without losing parser fidelity.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§is_nes2: bool

True if the file is NES 2.0 (header byte 7 bits 2-3 == 10).

§mapper_id: u16

12-bit mapper id (iNES 1.0 fills only the low 8 bits).

§submapper: u8

4-bit submapper id (NES 2.0 only; 0 on iNES 1.0).

§prg_size: usize

PRG-ROM size in bytes.

§chr_size: usize

CHR-ROM size in bytes (0 if cart uses CHR-RAM).

§mirroring: Mirroring

Effective initial mirroring.

§region: Region

Region from NES 2.0 byte 12; defaults to NTSC for iNES 1.0.

§console_type: ConsoleType

Console type from NES 2.0 byte 7; always ConsoleType::Nes for iNES 1.0.

§vs_ppu_type: VsPpuType

Vs. System PPU type from NES 2.0 byte 13 low nibble, valid only when console_type == ConsoleType::VsSystem (otherwise VsPpuType::None). Resolves to the output palette + 2C05 quirks via VsPpuType::ppu_palette / VsPpuType::is_2c05. The reserved nibbles ($1, $6, $7, $C-$F) decode as VsPpuType::Rp2C03, so they do not survive a canonical re-encode; serialize_header_preserving keeps them.

§vs_hardware_type: Option<VsHardwareType>

Vs. hardware type from NES 2.0 byte 13 high nibble: Some exactly when the header is NES 2.0 and console_type == ConsoleType::VsSystem. Types 5 and 6 are the Vs. DualSystem boards; see Header::is_vs_dual_system.

§extended_console_type: Option<ExtendedConsoleType>

Extended console type from NES 2.0 byte 13 low nibble: Some exactly when the header is NES 2.0 and console_type == ConsoleType::Extended.

§misc_rom_count: u8

Number of miscellaneous ROMs present (NES 2.0 byte 14 bits 0-1, so 0..=3; 0 on iNES 1.0). The miscellaneous ROM area itself is whatever follows CHR-ROM in the file.

§default_expansion_device: ExpansionDevice

Default expansion device (NES 2.0 byte 15 bits 0-6; ExpansionDevice::Unspecified on iNES 1.0).

§prg_ram_size: u32

Volatile PRG-RAM size in bytes: NES 2.0 byte 10 low nibble. iNES 1.0 has no size field, so it reports a nominal 8 KiB.

Until v2.9.8 this field held the volatile and non-volatile sizes summed; that total is now Header::prg_ram_window.

§prg_nvram_size: u32

Non-volatile (battery-backed) PRG-RAM / EEPROM size in bytes: NES 2.0 byte 10 high nibble. 0 on iNES 1.0, which has no NVRAM split (whether its nominal RAM is battery-backed is Header::has_battery).

§chr_ram_size: u32

Volatile CHR-RAM size in bytes: NES 2.0 byte 11 low nibble. iNES 1.0 reports a nominal 8 KiB when there is no CHR-ROM, otherwise 0.

§chr_nvram_size: u32

Non-volatile CHR-RAM size in bytes: NES 2.0 byte 11 high nibble. 0 on iNES 1.0. No board in this crate allocates CHR-NVRAM from it.

§has_battery: bool

True when battery-backed PRG-RAM is present (header[6] bit 1).

§has_trainer: bool

True when a 512-byte trainer follows the header (header[6] bit 2).

§four_screen: bool

True when bit 3 of header[6] forces four-screen mode.

Implementations§

Source§

impl Header

Source

pub const fn prg_ram_window(&self) -> u32

The whole PRG-RAM window a board allocates at $6000-$7FFF: the volatile and non-volatile sizes together. Some carts (StarTropics / MMC6) declare their save RAM only in the NVRAM nibble, so reading the volatile size alone would leave them with none.

Source

pub const fn is_vs_dual_system(&self) -> bool

True when the header names a Vs. DualSystem board (Vs. hardware type 5 or 6). Drives DUAL-system detection; see docs/cartridge-format.md.

Trait Implementations§

Source§

impl Clone for Header

Source§

fn clone(&self) -> Header

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Header

Source§

impl Debug for Header

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Header

Source§

fn default() -> Self

An iNES 1.0 header for mapper 0 with no ROM, horizontal mirroring, and every other field at the value parse_header gives an iNES 1.0 file with all-zero bytes 4-15, so parse_header(&canonical(default)) is the default again.

Source§

impl Eq for Header

Source§

impl PartialEq for Header

Source§

fn eq(&self, other: &Header) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Header

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.