use crate::ipl3::IPL3;
pub(crate) const HEADER_SIZE: usize = 0x40;
#[derive(Debug, Clone, Copy)]
pub(crate) struct N64Header {
device_latency: u8, device_rw_pulse_width: u8, device_page_size: u8, device_rw_release_duration: u8, clock_rate: u32, entry_point: u32, release: u32,
crc1: u32,
crc2: u32,
_reserved_1: [u8; 8],
name: [u8; 20],
_reserved_2: [u8; 7],
manufacturer: u8,
cart_id: [u8; 2],
region_code: u8,
_reserved_3: u8,
}
impl N64Header {
pub(crate) fn new(
entry_point: u32,
name_str: &str,
program: &[u8],
fs: &[u8],
ipl3: &IPL3,
) -> N64Header {
let (crc1, crc2) = ipl3.compute_crcs(program, fs);
let entry_point = ipl3.offset(entry_point);
let name_str = format!("{:20}", name_str);
let mut name = [0; 20];
name.copy_from_slice(name_str.as_bytes());
let name = name;
let cart_id_str = b"KW"; let mut cart_id = [0; 2];
cart_id.copy_from_slice(cart_id_str);
let cart_id = cart_id;
N64Header {
device_latency: 128,
device_rw_pulse_width: 55,
device_page_size: 18,
device_rw_release_duration: 64,
clock_rate: 15,
entry_point,
release: 0,
crc1,
crc2,
_reserved_1: [0; 8],
name,
_reserved_2: [0; 7],
manufacturer: b'N', cart_id,
region_code: b'E', _reserved_3: 0,
}
}
pub(crate) fn to_vec(self) -> Vec<u8> {
let mut buffer = vec![
self.device_latency,
self.device_rw_pulse_width,
self.device_page_size,
self.device_rw_release_duration,
];
buffer.extend_from_slice(&self.clock_rate.to_be_bytes());
buffer.extend_from_slice(&self.entry_point.to_be_bytes());
buffer.extend_from_slice(&self.release.to_be_bytes());
buffer.extend_from_slice(&self.crc1.to_be_bytes());
buffer.extend_from_slice(&self.crc2.to_be_bytes());
buffer.extend_from_slice(&self._reserved_1);
buffer.extend_from_slice(&self.name);
buffer.extend_from_slice(&self._reserved_2);
buffer.push(self.manufacturer);
buffer.extend_from_slice(&self.cart_id);
buffer.push(self.region_code);
buffer.push(self._reserved_3);
buffer
}
}