From f03fa6fa77a68bff80b65ee69765042076a306c2 Mon Sep 17 00:00:00 2001 From: Samuel Perrouault Date: Wed, 23 Jul 2025 00:05:12 +0200 Subject: exploring a fully static path --- src/main.rs | 130 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 103 insertions(+), 27 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index bb0ae71..5f977ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,107 @@ -use std::{ - fs::File, - io::BufReader, - time::{Duration, Instant}, -}; - -const SECOND: u64 = 1_000_000_000; -const REFRESH_RATE: u64 = 60; -const FRAME_DURATION: Duration = Duration::from_nanos(SECOND / REFRESH_RATE); - -fn main() -> std::io::Result<()> { - if let Some(arg) = std::env::args().nth(1) { - let mut chip8 = chip8::Chip8::new(); - { - let file = File::open(arg)?; - let buf_reader = BufReader::new(file); - chip8.load_rom(buf_reader)?; +#![no_std] +#![no_main] + +use core::fmt::Write; + +#[cfg(target_arch = "x86_64")] +core::arch::global_asm!( + ".text", + ".global _start", + ".type _start,@function", + "_start:", + "xor rbp,rbp", + "mov rdi, rsp", + ".weak _DYNAMIC", + ".hidden _DYNAMIC", + "lea rsi, [rip + _DYNAMIC]", + "and rsp,-16", + "call __proxy_main" +); + +struct Printer { + buf: [u8; 512], + pos: usize, +} + +impl Printer { + fn new() -> Self { + Self { + buf: [0; 512], + pos: 0, } - loop { - let start = Instant::now(); - for _ in 0..8 { - chip8.cycle(); - } - chip8.display()?; - std::thread::sleep(FRAME_DURATION - start.elapsed()); + } + + fn bytes(&self) -> &[u8] { + &self.buf[..self.pos] + } +} + +impl core::fmt::Write for Printer { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + let remaining_buf = &mut self.buf[self.pos..]; + let raw_s = s.as_bytes(); + let write_num = raw_s.len().min(remaining_buf.len()); + remaining_buf[..write_num].copy_from_slice(&raw_s[..write_num]); + self.pos += raw_s.len(); + if write_num < raw_s.len() { + Err(core::fmt::Error) + } else { + Ok(()) } - } else { - println!("usage: chip8 rompath") } - Ok(()) } + +#[panic_handler] +fn panic(info: &core::panic::PanicInfo) -> ! { + let mut p = Printer::new(); + let _ = write!(&mut p, "Fatal error: {}\n", info); + let stderr = unsafe { rustix::stdio::stderr() }; + let _ = rustix::io::write(stderr, p.bytes()); + rustix::runtime::exit_group(1) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn __proxy_main(_stack_ptr: *const u8, _dynv: *const usize) { + let code = main(); + rustix::runtime::exit_group(code); +} + +fn main() -> i32 { + let mut p = Printer::new(); + write!(&mut p, "Hello {}, you are worth {} tons of gold\n", "Jacques", 10_000).expect("Could not format this"); + let stdout = unsafe { rustix::stdio::stdout() }; + let _ = rustix::io::write(stdout, p.bytes()); + 0 +} + +// use std::{ +// fs::File, +// io::BufReader, +// time::{Duration, Instant}, +// }; + +// const SECOND: u64 = 1_000_000_000; +// const REFRESH_RATE: u64 = 60; +// const FRAME_DURATION: Duration = Duration::from_nanos(SECOND / REFRESH_RATE); + +// fn main() -> std::io::Result<()> { +// if let Some(arg) = std::env::args().nth(1) { +// let mut chip8 = chip8::Chip8::new(); +// { +// let file = File::open(arg)?; +// let buf_reader = BufReader::new(file); +// chip8.load_rom(buf_reader)?; +// } +// loop { +// let start = Instant::now(); +// for _ in 0..8 { +// chip8.cycle(); +// } +// chip8.display()?; +// std::thread::sleep(FRAME_DURATION - start.elapsed()); +// } +// } else { +// println!("usage: chip8 rompath") +// } +// Ok(()) +// } -- cgit v1.2.3