From b93267c56565582b9a85e7a1255568e16abcafd2 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Thu, 28 Aug 2025 08:39:08 +0200 Subject: nasm: Error out when using WRAM when not available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces the ability to inspect the temptative header before producing the actual output, and with that it checks whether the Working RAM is being advertised or not. If it is not being advertised but the assembler detected memory accesses to that region, then we are in trouble and we should error out. Signed-off-by: Miquel Sabaté Solà --- crates/nasm/Cargo.toml | 1 + crates/nasm/src/main.rs | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/nasm/Cargo.toml b/crates/nasm/Cargo.toml index f0f11db..f1294f7 100644 --- a/crates/nasm/Cargo.toml +++ b/crates/nasm/Cargo.toml @@ -6,3 +6,4 @@ authors = ["Miquel Sabaté Solà "] [dependencies] xixanta.workspace = true +header.workspace = true diff --git a/crates/nasm/src/main.rs b/crates/nasm/src/main.rs index 3864587..6ca6d27 100644 --- a/crates/nasm/src/main.rs +++ b/crates/nasm/src/main.rs @@ -1,3 +1,4 @@ +use header::Header; use std::fs::File; use std::io::{self, Write}; use std::path::Path; @@ -205,8 +206,36 @@ fn main() { error_count += 1; } - // If everything was right, just deliver the bundles. + // Deliver the bundles unless the header is borked. if error_count == 0 { + // Fetch the header first. + let mut temptative_header = vec![]; + for b in &res.bundles { + for i in 0..b.size { + temptative_header.push(b.bytes[i as usize]); + } + if temptative_header.len() >= 0x10 { + break; + } + } + + // Validate the resulting header. + match Header::try_from(temptative_header.as_slice()) { + Ok(header) => { + if res.accessing_working_ram && !header.has_persistent_memory { + die( + "requires Working RAM but the ROM header does not advertise it".to_string(), + ); + } + } + Err(e) => { + die(format!( + "output would produce a malformed NES/Famicom ROM: {e}" + )); + } + }; + + // And now deliver the bundles. for b in res.bundles { for i in 0..b.size { if let Err(e) = output.write_all(&[b.bytes[i as usize]]) { -- cgit v1.2.3