SearchA-ZH › HP-48SX

HP-48SX

1990 Open source · GPL-2.0 Online

An in-browser HP-48SX that boots the authentic 1990 HP-48SX system ROM to the RPL stack. The HP-48SX is the first HP-48 — the "Scientific eXpandable" model, with two plug-in card ports — and it runs the same machine as the later HP-48GX: the HP Saturn, a 4-bit-nibble CPU with 64-bit working registers. Type on the on-screen HP-48 keyboard or your physical keyboard; the calculator's ROM, RAM, timers and 131×64 LCD are all emulated.

This emulator reuses the base HP-48 emulator's shared hpemu Saturn core, loading the WebAssembly core, the saturn decoder and the debugger plug-in from /emulator/hp48/src/ rather than duplicating them; only the SX ROM is its own. Because the shared build bakes in the GX ROM, the boot swaps the SX ROM into the core's in-memory filesystem before power-on and answers the "Try To Recover Memory?" prompt, landing on the SX stack.

The Saturn is driven through a small set of on-demand hooks rather than its own run loop, so it plugs into the shared debugger: single-step the processor, read and write the A/B/C/D field registers and nibble memory, disassemble Saturn code, and set breakpoints and write watchpoints. The HP-48SX system ROM is © Hewlett-Packard and is self-hosted here for emulation.

Runs on: Web browser

HP-48SX Online Emulator

Play HP-48SX using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
HP-48SX RPL stackHP-48SXHP-48SXgreyOpen ⛶

Machines emulated

Chips

Notes

Embedding

The HP-48SX runs the same machine as the base HP-48 emulator: Daniel Nilsson's portable-C hpemu HP Saturn core (GPL v2), compiled to WebAssembly with its SDL/GUI loop dropped and the processor driven by hand so the shared debugger can pause and step it. This emulator ships only its own embed.js and its authentic HP-48SX ROM; the wasm core, the saturn decoder and the machine plug-in all load from /emulator/hp48/src/, so no code is duplicated.

Swapping in the SX ROM. The shared Emscripten build preloads the HP-48GX ROM into its in-memory filesystem. Rather than rebuild the core, the boot replaces that file with the SX ROM before the core reads it, using the two file hooks the build exposes, then clears RAM and answers the power-on recovery prompt:

var rom = new Uint8Array(await (await fetch('/emulator/hp48sx/src/roms/hp48sx.rom')).arrayBuffer());
M.FS_unlink('/assets/hpemu.rom');                     // drop the baked GX ROM
M.FS_createDataFile('/assets', 'hpemu.rom', rom, true, true, true);  // install the SX ROM
M.FS_unlink('/assets/hpemu.ram');
M.FS_createDataFile('/assets', 'hpemu.ram', new Uint8Array(262144), true, true, true);
hp_init(); hp_boot();                                // rom_init reads the SX ROM; power-on -> "Try To Recover Memory?"
hp_key_down(8,0); hp_run(...); hp_key_up(8,0);       // press NO (rightmost softkey) -> Memory Clear -> SX stack

The 256 KB SX ROM is stored packed (two nibbles per byte); hpemu's rom_init unpacks it to the 512 K-nibble Saturn ROM space. The core is otherwise reached through the same flat on-demand hooks the base HP-48 documents.

Debugger integration

The debugger is driven by the shared hp48-debug.js plug-in loaded from /emulator/hp48/src/: it reads the live core from window.EMU_BOOT (published by the boot script below) and calls EmuKit.defineMachine with a transport, the Saturn register set and the 1M-nibble memory, using the saturn disassembler at /debugger/src/cpus/saturn.js.

Single-step is hp_step() (one executed Saturn instruction). Breakpoints are a host-side Set of 20-bit PC values: when any are set the JavaScript loop runs one instruction at a time and compares the PC before each. Write watchpoints sample the watched nibble addresses after each stepped instruction and halt on a change. The A/B/C/D working registers are 64 bits, so the registers window shows each as a low and a high 32-bit half; every register is writable back into the live core. The SX runs the identical Saturn machine as the GX, so the whole debugger applies unchanged — only the ROM differs.

Architecture

The HP-48SX (1990) is the first HP-48 — the "Scientific eXpandable" model — built on the HP Saturn, a 4-bit-nibble CPU that presents nibble-addressed memory (a 20-bit, 1M-nibble space) and works on 64-bit working registers a field at a time. It is the same processor and system architecture as the later HP-48GX; the differences are the ROM revision and the smaller built-in RAM.

  • Saturn core — four 64-bit working registers A B C D (sixteen nibbles each), five scratch registers R0..R4, two 20-bit data pointers D0/D1, a 4-bit field pointer P, the 16-bit program status ST, the hardware status HST, an 8-level return stack and a carry. Arithmetic runs in hex or BCD decimal mode.
  • Memory — a nibble bus configured at boot by the ROM's CONFIG sequence: 256 KB system ROM, 32 KB built-in RAM and two plug-in card ports for RAM or application cards, plus the memory-mapped hardware registers.
  • Display — a 131×64 monochrome LCD scanned directly out of video RAM at a base address the ROM programs; a short pixel-history gives the familiar 4-level grayscale.
  • Keyboard — a 9-row matrix read through the IN/OUT registers; each key is a (row, col) pair, with ON wired to wake the CPU from its low-power SHUTDN state.
  • ROM — the authentic HP-48SX operating system, © Hewlett-Packard, swapped into the ROM space at boot in place of the shared build's GX ROM.

Every part is reached from JavaScript through the small hp48hooks.c shim in the shared build, which turns an otherwise SDL-bound emulator into a live, steppable Saturn debugging target in the browser.