Files in directory /voyem from the latest check-in of branch trunk
- .containerignore
- .sccignore
- examples
- samples
- src
- tests
- tools
- AGENTS.md
- build.rs
- Cargo.lock
- Cargo.toml
- ChangeLog.md
- Containerfile
- LICENSE.md
- Makefile
- README.md
- Taskfile.yml
- TODO.md
CLI-Only HP Voyager Emulator
This is an HP-12C CE / HP-15C CE / HP-16C CE firmware emulator1 meant for testing behavior in automated workflows such as hypothesis-testing in LLM based coding agents. When run in this manner, it is pure in a mathematical sense: starting from a freshly reset calculator state, it loads your test program in, runs it, and then reports the resulting calculator state. One used to dealing with functional purity on desktop computers might view the changed contents of RAM and the LCD as “side effects,” but in this context, they are part of the program’s output, available for inspection inside that same hypothesis testing loop.
This project began as a Rust port of José González Divassón’s Python emulator, but it has since evolved beyond that. The primary differences are that it…
…drops the “whole calculator” simulation features to refocus it on running programs and keyboard entry scripts under pure CPU emulation of the firmware’s execution.
…adds the HP-15c CE and HP-12C program runners.
This emulator gets nearly all its power from the Unicorn CPU emulator, providing a virtual ARM Cortex-M4. This allows voyem to produce results identical to the hardware by running the firmware pulled from it. For the same reason, it is not meaningfully faster than the Divassón emulator despite being written in a much more efficient language.
That is not to say that we get nothing from the rewrite. The main benefit is that it compiles to a single static binary, rather than requiring all that horrid Python venv stuff. I will grant that Rust is horrid in its own special ways 😈 but the thing is, that all lands on the developers, not the users, as is proper.
This emulator is not a product of Hewlett-Packard or Moravia Consulting, nor is it endorsed by them. If it breaks, you get to keep both pieces. Caveat hacker.
Download
We build binary releases for a 3×2 matrix of {macOS,Linux,Windows} and 64-bit {ARM,Intel}. These are also available via Quay as OCI container images, which are especially useful in automated testing setups.
You may find the change log of interest.
Build
Any Rust toolchain compatible with language edition 2021 should be able to build this. There are additional dependencies; on Fedora, for example:
sudo dnf install rust cargo cmake clang-devel ninja-build
cargo build --release
If you add go-task to that package list, the lovely Task build system allows shorter commands:
task # create debug build
task run -- --help # run debug build; pass voyem options
task install # create and install release build
A Makefile wrapper exists for those like me, who’ve got make grooved bone-deep into their finger memory. 🤓
If you want to create a release build but not install it, use “task release-native”. Do not use the broader release target; it is for tagging and distributing the public builds, and it depends on local details of my development system.
Firmware
This software requires calculator firmware for one of the ARMv2 class (2015+) HP Voyager machines. Firmware images may be pulled from physical hardware or downloaded from various sources online, including The Calculator Store’s test firmware page. Memory layouts for both the factory-stock machines and the "extended" aftermarket firmware images are supported.
Testing has been done with the latest available releases in each class. To check that an arbitrary version is supported:
task run -- --firmware /path/to/firmware.bin --info
For make test to run to completion, place a hp16c*.bin firmware file alongside this README.md. These tests presume HP-16c CE firmware and use that glob to ensure it finds a suitable *.bin file among potentially many.
Examples
Think of voyem as a “program runner” for various HP Voyager series machines; give it an input, and see what the machine produces as a result.
Each run starts with fresh state, as if you issued the minus-ON sequence on a physical calculator, then pressed a key to get past the Pr Error notification.
HP-12C
Compute `3+4`, with the result reported under the default FIX 2 display mode:
task run -- --firmware hp12c-ce-e6e6.bin --keys "3 ENTER 4 +"
HP-15c CE
Same, but under the 15C’s default FIX 4 mode, with the resulting calculator RAM state saved to a memory dump for further inspection:
task run -- --firmware hp15c-ce-c8c8.bin \
--keys "3 ENTER 4 +" --save result.15cmem
HP-16c CE
Run a test script:
task run -- --firmware hp16c-ce-b7b7.bin \
--test examples/first-session.txt
Run the Miller-Rabin algorithm on a much bigger prime than would be convenient during a “task test” run:
task run -- --firmware hp16c-ce-b7b7.bin \
--load samples/miller-rabin-ext-ready.16cmem --fmem \
--keys "2147483647 GSB A" --show
Options
| Option | Meaning |
|---|---|
--firmware FILE |
Your firmware file (required, except for --help and --version) |
--version |
Print the version from Cargo.toml and exit |
--info |
Identify the firmware and exit |
--load FILE.16cmem\|.15cmem |
Restore a 2,048-byte VoyagerSave memory dump first |
--fmem |
Show f MEM (after --load, before the keys) |
--keys "..." |
Keys to press, separated by spaces (may be repeated) |
--show |
Print the display after the keys |
--trace |
Print the display after every key |
--save FILE.16cmem\|.15cmem |
Save a memory dump at the end; never overwrites |
--test FILE.txt |
Run a test / key script (exit code 1 if a check fails) |
--count |
Print how many Nut (Voyager CPU) instructions ran |
--max-steps N |
Stop a key after N Nut instructions (Ctrl+C also stops) |
Key names
HP-16C: A B C D E F 0-9 . + − × ÷ GSB GTO HEX DEC OCT BIN R/S SST R↓ x<>y BSP ENTER ON f g STO RCL CHS. Plain-keyboard spellings also work: - * / RDN XY.
HP-15C: √x e^x 10^x y^x 1/x CHS 0-9 . + − × ÷ SST GTO SIN COS TAN EEX R/S GSB R↓ x<>y ← ENTER ON f g STO RCL Σ+. Aliases: SQRT EX/E^X 10X YX/Y^X 1/X BSP/<- → ←.
HP-12C: n i PV PMT FV CHS 0-9 . + − × ÷ y^x 1/x %T Δ% % EEX R/S SST R↓ x<>y CLx ENTER ON f g STO RCL Σ+. Aliases: * / - YX/Y^X 1/X <-/BSP/←/CLX → CLx, XY RDN.
Name the keys, not the functions: g P/R is g R/S, g LBL A is g GTO A, g RTN is g GSB. A multi-digit number such as 2147483647 is typed digit by digit.
Limits
- Speed and battery life cannot be judged from the emulator.
- Not emulated: USB, writing to flash, LCD contrast, real battery behavior, key bounce or scan timing.
- Timer-driven firmware behaviour (e.g. PSE while a program runs) is unsupported.
- Loading a
.16cmem/.15cmemcopies bytes straight into memory. - Display decoding covers digits, Voyager decimal/comma punctuation, and the letters the calculators use. Annunciators (f, g, C, …) are not decoded.
Licence
GPL-2.0-or-later (see LICENSE.md). The license covers only this package. HP firmware and ROM code are not included and are not covered by it.