113 lines
2.7 KiB
Rust
113 lines
2.7 KiB
Rust
//! `Psexe` manipulation
|
|
|
|
// Features
|
|
#![feature(never_type)]
|
|
|
|
// Imports
|
|
use {
|
|
byteorder::{ByteOrder, LittleEndian},
|
|
ddw3_bytes::Bytes,
|
|
std::fmt,
|
|
};
|
|
|
|
/// Psx header
|
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
|
pub struct Header {
|
|
/// Start address
|
|
pub pc0: u32,
|
|
|
|
/// Text base
|
|
pub text_base: u32,
|
|
|
|
/// Text size
|
|
pub text_size: u32,
|
|
|
|
/// Stack pointer
|
|
pub sp: u32,
|
|
|
|
/// License
|
|
pub license: [u8; Self::LICENSE_SIZE],
|
|
}
|
|
|
|
impl fmt::Debug for Header {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let license_end_idx = self.license.iter().position(|&b| b == 0).unwrap_or(self.license.len());
|
|
|
|
f.debug_struct("Header")
|
|
.field("pc0", &format_args!("{:#010x}", self.pc0))
|
|
.field("text_base", &format_args!("{:#010x}", self.text_base))
|
|
.field("text_size", &format_args!("{:#010x}", self.text_size))
|
|
.field("sp", &format_args!("{:#010x}", self.sp))
|
|
.field("license", &String::from_utf8(self.license[..license_end_idx].to_vec()))
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl Header {
|
|
/// License size
|
|
pub const LICENSE_SIZE: usize = 0x800 - 0x4c;
|
|
/// Magic
|
|
pub const MAGIC: [u8; 8] = *b"PS-X EXE";
|
|
}
|
|
|
|
impl Bytes for Header {
|
|
type ByteArray = [u8; 0x800];
|
|
type DeserializeError = anyhow::Error;
|
|
type SerializeError = !;
|
|
|
|
fn deserialize_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::DeserializeError> {
|
|
let bytes = ddw3_bytes::array_split!(bytes,
|
|
magic : [0x8],
|
|
_unknown0: [0x8],
|
|
pc0 : [0x4],
|
|
_unknown1: [0x4],
|
|
text_base: [0x4],
|
|
text_size: [0x4],
|
|
_unknown2: [0x10],
|
|
sp : [0x4],
|
|
_unknown3: [0x18],
|
|
license : [Header::LICENSE_SIZE],
|
|
);
|
|
|
|
anyhow::ensure!(
|
|
*bytes.magic == Self::MAGIC,
|
|
"Found wrong magic ({:?}/{:?}), expected {:?}",
|
|
bytes.magic,
|
|
String::from_utf8_lossy(bytes.magic),
|
|
Self::MAGIC
|
|
);
|
|
|
|
Ok(Self {
|
|
pc0: LittleEndian::read_u32(bytes.pc0),
|
|
text_base: LittleEndian::read_u32(bytes.text_base),
|
|
text_size: LittleEndian::read_u32(bytes.text_size),
|
|
sp: LittleEndian::read_u32(bytes.sp),
|
|
license: *bytes.license,
|
|
})
|
|
}
|
|
|
|
fn serialize_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::SerializeError> {
|
|
let bytes = ddw3_bytes::array_split_mut!(bytes,
|
|
magic : [0x8],
|
|
_unknown0: [0x8],
|
|
pc0 : [0x4],
|
|
_unknown1: [0x4],
|
|
text_base: [0x4],
|
|
text_size: [0x4],
|
|
_unknown2: [0x10],
|
|
sp : [0x4],
|
|
_unknown3: [0x18],
|
|
license : [Header::LICENSE_SIZE],
|
|
);
|
|
|
|
*bytes.magic = Self::MAGIC;
|
|
LittleEndian::write_u32(bytes.pc0, self.pc0);
|
|
LittleEndian::write_u32(bytes.text_base, self.text_base);
|
|
LittleEndian::write_u32(bytes.text_size, self.text_size);
|
|
LittleEndian::write_u32(bytes.sp, self.sp);
|
|
*bytes.license = self.license;
|
|
|
|
Ok(())
|
|
}
|
|
}
|