Emulator for ONCE UTT Sonobraille
  • DIGITAL Command Language 55.8%
  • Python 17.1%
  • B (Formal Method) 16.2%
  • TeX 4.4%
  • Shell 2.5%
  • Other 4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
guilevi a9cb2b2aa1 A root README, docs caught up, and .DS_Store kept out of the image
The owner confirmed the chords work on the real guest, so the notes now say so
rather than "needs a by-ear pass", and the status table gains the app, the
chords and the platform position.

Adds a README at the root. llm-docs/ is the working notes -- what was measured
and why -- and was doing double duty as the front door; this is the front door,
and it says what the project is, how to run it, and the two things that are
worth knowing before reading anything else.

Also answers, in 10, the owner's question about Windows: the launcher command is
the same shape, but the app stops at the first line of audio_args(), and the
real blocker underneath is that the patched QEMU exists only as a macOS binary.

build_image.sh: prune .DS_Store from the working copy before copying. The
top-level skip list never applied inside directories, because `mcopy -s`
recurses -- and one had reached C:\TEXTO in the guest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 11:52:25 +02:00
app The desktop app, with ONCE-CIDAT's own Braille chord decoding 2026-08-15 11:28:11 +02:00
c Sonobraille emulation: device drive, emulator harness, and findings 2026-08-14 22:10:17 +02:00
llm-docs A root README, docs caught up, and .DS_Store kept out of the image 2026-08-15 11:52:25 +02:00
run A root README, docs caught up, and .DS_Store kept out of the image 2026-08-15 11:52:25 +02:00
.gitattributes Stop git rewriting line endings in the guest's files 2026-08-14 22:10:46 +02:00
.gitignore The desktop app, with ONCE-CIDAT's own Braille chord decoding 2026-08-15 11:28:11 +02:00
README.md A root README, docs caught up, and .DS_Store kept out of the image 2026-08-15 11:52:25 +02:00

Sonobraille

The Sonobraille is an early-2000s MS-DOS Braille notetaker built by AYZ Ingeniería Industrial for ONCE-CIDAT in Spain: an AMD Élan SC4xx board, a CS4239 codec, eleven Braille keys, a speech synthesizer, and no screen at all. Its software has never run anywhere but on the machine itself.

This repository runs it — the device's own MS-DOS, its own SONO.EXE, its own "parla" speech engine — under QEMU on a desktop, and puts a Braille keyboard in front of it.

It works. The machine boots, the TTS installs past its hardware locks and speaks through the host's speakers, and Braille chords typed on an ordinary keyboard are decoded with ONCE-CIDAT's own chord table and delivered to the guest. Confirmed by the owner, by ear, on the real software.

What is here

app/ the desktop app — a wxPython window that owns the emulator and the keyboard. This is how you use the machine. macOS today; see below for Windows.
run/ the emulator harness: boot scripts, the runtime unlock, QMP keyboard, the disk-image builder, and a shelf of measurement and tracing tools built during the reverse engineering.
c/ the device's C: drive, verbatim — the software it shipped with. Read-only by convention; never modify it.
llm-docs/ the working notes. Everything that was measured, every bug found, every dead end. Start at llm-docs/README.md.

run/c/ is a working copy of c/ that the image builder reads from, and run/emu/ holds emulation-only replacements (CONFIG.SYS, AUTOEXEC.BAT, a few helper .COM tools) so the device's own files stay untouched.

Running it

Prerequisites: mtools (brew install mtools) to build the disk image, and the patched QEMU in run/qemu-build/ — see llm-docs/05-qemu-patches.md if you need to rebuild it.

cd run && ./build_image.sh          # once, and after any change under run/c
cd ../app
python3 -m venv .venv && ./.venv/bin/pip install -r requirements.txt   # once
./.venv/bin/python sono-app

Press Start, wait about 23 seconds — booting and unlocking are each spoken — then F12 to capture the keyboard and F11 to switch between passthrough and Braille input. app/README.md has the key map and what each chord does.

There is no window to look at: SONO.EXE never paints VGA, so the emulator runs headless and the machine is entirely a voice. That is how the real unit works too.

For driving it from a terminal instead — useful for measurement — run/sono.sh boots it, unlocks it and forwards what you type, with -record f.wav to capture what it says. ./run/sono.sh -h for the rest.

Two things worth knowing

The speech only works because of runtime patches. TTSE2SO.EXE verifies itself — change one byte on disk and it takes the machine down — so run/unlock.py attaches over QEMU's gdbstub every boot instead: it steers execution past four hardware locks (a CPUID check demanding an Élan SC4xx, and three probes that halt the engine), then applies three memory patches.

Those three are all the same shape, and it is the lesson of the whole project: the engine reads a piece of Élan-era hardware QEMU does not implement, gets nothing back, and computes an address or a length from it — then degrades silently instead of failing. 51.3% of played samples were wrong before this was found; it is 0.0% now. When the engine behaves wrongly, ask first which I/O port it just read — that is four for four, counting the Braille driver. llm-docs/08-elan-halving-bug.md is the nine-round account.

The Braille decoding is the device's own, not a reconstruction. EMUKBBRA.SYS will not install under emulation — it reads its eleven keys from an Élan GPIO port that does not exist here — but its V4.4d chord table is static data, and run/extract_braille.py lifts all 631 entries out of the binary. Each entry is the keystroke sequence the driver would have injected, so it goes straight to the guest. llm-docs/11-braille-chord-table.md.

Platforms

macOS only, today. wxPython, Prism, the chord table and the QMP keyboard are all portable already; what is not is the audio backend, the unix sockets, and above all the patched QEMU, which exists only as a macOS binary. Linux additionally has no wxPython wheel. The full audit, and what breaks first on Windows, is in llm-docs/10-desktop-app.md.

Provenance

SONO.EXE, TTSE2SO.EXE, EMUKBBRA.SYS and the rest of the C: drive are ONCE-CIDAT / AYZ Ingeniería software, included here because this repository is for the owner of the device it came from. The tree holds the software the device shipped with and nothing else — the owner's own files were removed. Nothing here is a redistribution licence.