saturnus 0.1.0

Headless, clean-room emulator of the HP Saturn calculators (core library)
Documentation

saturnus

Core library of saturnus, a headless emulator of the HP Saturn calculators: HP 48SX, 48GX, 49G, 38G, 39G, 40G and 42S. It models the Saturn CPU, the bus with its memory-mapped modules, the display, keyboard, timers and serial port, and the per-model machine wiring. No I/O and no threads: the crate builds for wasm32-unknown-unknown and has no dependencies.

It is a clean-room implementation, written from public hardware documentation and observed behaviour, not from the source code of other emulators. No ROM is included: you supply the ROM image of a calculator you own, or one HP allows to be downloaded for emulator use (the saturnus command-line tool from the saturnus-cli crate fetches those from hpcalc.org and verifies them).

Usage

use saturnus::io::Key;
use saturnus::{Machine, Model};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let rom = std::fs::read("gxrom-r")?;
    let mut m = Machine::new(Model::Hp48gx, &rom)?;

    // Run two seconds of machine time (the 48GX runs at 4 MHz).
    m.run_cycles(8_000_000).map_err(|h| format!("halted: {h:?}"))?;

    // Press and release a key.
    m.key_down(Key::Enter)?;
    m.run_cycles(200_000).map_err(|h| format!("halted: {h:?}"))?;
    m.key_up(Key::Enter)?;

    // The screen as text (one character per pixel)...
    println!("{}", m.lcd().to_text());

    // ...and the serial port, byte by byte.
    m.serial_push(b"\x01");
    let reply: Vec<u8> = m.serial_drain();
    println!("{} bytes from the calculator", reply.len());
    Ok(())
}

Related crates: saturnus-objects reads RPL objects and the user memory of a paused machine; saturnus-drive drives a machine from a native host (key scripts, idle waits, screen dumps).

Licence

MIT. Parts of the code were generated by AI systems under human supervision; see the repository's AI_NOTICE.