Phosphoric — full feature list
Cycle-accurate ORIC-1 / Atmos emulator · written in C11 · MIT license
This page lists every Phosphoric feature, with an explanation of each and the matching command-line options. The GitHub repository is the authoritative, up-to-date source; the technical documentation covers each subsystem in depth.
Contents
- 1. Emulation core
- 2. Peripherals & cards
- 3. ORIC-1 & Atmos models
- 4. Joystick, printer, plotter
- 5. Save states
- 6. Interactive debugger
- 7. Control & automation
- 8. Chromecast / Google Cast streaming
- 9. Display & capture
- 10. ULA-NG (next-gen)
- 11. Trace, profiling, ROM analysis
- 12. Operating systems
- 13. Convenience & ports
- 14. Serial: chips × transports
- 15. Key bindings
- 16. Building
1. Emulation core
The core reproduces the machine cycle by cycle: every chip advances at the same pace as the original silicon — a must for demos and raster-sensitive code.
MOS 6502 CPU
Cycle-accurate emulation of the 151 official opcodes, 13 addressing modes, decimal arithmetic (BCD) and level-triggered IRQs. The test suite also covers illegal NMOS opcodes.
64 KB memory
RAM $0000-$BFFF, ROM $C000-$FFFF, banking and I/O routing faithful to
the Oric's memory map.
VIA 6522
16 registers, Timers 1 and 2, IFR/IER interrupts, keyboard matrix, shift register (8 modes), T2 pulse counting, complete CA2/CB2 PCR modes (input edges, independent interrupts, handshake — CB2 write-only like the silicon —, one-cycle pulse, manual) and IRA/IRB input latching (ACR bits 0-1).
ULA video
Text mode (40×28) and HIRES (240×200), serial attributes, PAL timing (312 lines × 64 cycles).
AY-3-8910 PSG
3 tone channels, noise, 16 envelope shapes, SDL2 audio output.
2. Peripherals & cards
Microdisc (WD1793 controller)
WD1793 FDC, 4 drives (A-D), overlay ROM, Sedoric boot. Real mechanical timing by default (step rates 6/12/20/30 ms, 300 RPM rotational latency, Record-Not-Found after 5 index pulses, live Type I index pulse). Bad-sector fault injection to test robustness: the damage follows the media across drive selects and is persisted in save states.
- --disk-rom FILE · --disk / --disk1/2/3 drives A to D
- --fdc-timing real (default) | fast · --disk-writeback · --bad-sector [D:]S:T:N
Cassette (TAP format)
CLOAD/CSAVE via ROM patching, fast load, multi-block, post-CLOAD rechain, and
signal-level playback (--tape-signal: real VIA CB1 waveform read by the
ROM, for custom or protected loaders).
- --tape FILE · --fast-load · --tape-signal
ACIA 6551 (serial)
Serial controller at $031C-$031F ($0380 under LOCI). Loopback / TCP / PTY
/ COM / file transports, plus protocol backends (Hayes AT modem, PicoWiFiModemUSB), V23 mode (Minitel
/ Digitelec). See the chips × transports matrix.
Digitelec DTL 2000
Faithful PIA 6821 + ACIA 6850 modem card at $03F8-$03FD (OCR-verified registers from
period documentation), V23 75/1200 and symmetric 1200, line/carrier control, wired IRQ. Validated
against the period OTRM terminal.
- --dtl2000 TRANSPORT · --dtl2000-addr XXXX
Mageco / ORICON MIDI
MC6850 ACIA driving the MIDI DIN sockets (31250 baud, 8-N-1). Two designs from the Oric forum: the
original Mageco card at $03FE-$03FF (--mageco) and the modern
ORICON reboot at $031C-$031D + clock generator, LOCI-compatible
(--oricon). Capture/replay the raw MIDI stream, play a Standard MIDI File into the
Oric (at tempo), or — in a MIDI=1 build — open a live host MIDI port (ALSA / CoreMIDI /
WinMM) to drive FluidSynth or a DAW.
- --mageco file:in[:out] | smf:FILE[:loop] | midi[:TARGET] | loopback | tcp | pty · --oricon TRANSPORT
PicoWiFiModemUSB
Emulation of sodiumlb's WiFi modem (Pico W, USB CDC ↔ WiFi) exposed by LOCI as an ACIA at
$0380. Full AT command set v0.1.0; simulated WiFi, real TCP data connections.
- --serial picowifi[:SSID[:PASS]]
LOCI — Lovely Oric Computer Interface
sodiumlb's interface (2024): MIA bus $03A0-$03BF, 36/36 API ops (firmware-conforming ABI),
USB HID, cycle-accurate WD1793, FAT16/32 SD image, runtime ROM swap. Action button (F8):
short press → session snapshot + LOCI menu; long press (≥ 2 s) → Mike Brown's diagnostic ROM. Serves
real host USB keys to the Oric, tunable MIA bus timing. Boots a full Sedoric V4 master via the LOCI
firmware.
- --loci · --loci-flash DIR · --loci-sdimg PATH · --loci-usb DIR|none
- --loci-mia-window LO-HI · --loci-irq-latency US
3. ORIC-1 & Atmos models
Automatic model detection
Detects BASIC 1.0 (ORIC-1) vs 1.1 (Atmos) from the ROM header, with the correct cassette patch addresses for each version. The model can also be forced.
- --model oric1 | atmos | 1.0 | 1.1
4. Joystick, printer, plotter
IJK joystick
IJK interface (the most common adapter, active-low on PSG Port A), in keyboard mode (arrows + RCtrl/RAlt for fire) or SDL2 gamepad (D-pad, analog stick, A/B/X buttons), with hot-plug. Joystick and keyboard signals blend on Port A.
- --joystick keys | gamepad
Centronics printer & MCP-40 plotter
Capture LPRINT/LLIST to a text file, or emulate the 4-colour MCP-40 pen plotter (commands H/D/M/J/P/L, 480×400 framebuffer, Bresenham line drawing, 5×7 font, BMP export). Centronics protocol via VIA Port A + CA2 (STROBE) edge.
- --printer FILE · --printer-type text (default) | mcp40
5. Save states
.ost format
Full binary state with a CRC32 integrity check, split into 13 sections (CPU, MEM, VIA, PSG, VID, KBD, FDC, MDC, DSK, BAD, TAP, SER, META). Unknown sections are ignored: the format is backward- and forward-compatible.
- --save-state FILE · --load-state FILE · keys F2 (save) / F4 (load)
6. Interactive debugger
Breakpoints & watchpoints
Up to 16 PC breakpoints, conditional (b ADDR if EXPR), 8 raster-line breakpoints, 8 memory
write watchpoints.
Execution & inspection
step, next, step-out, continue, undo (rewind 16 CPU+RAM snapshots),
registers, paginated disassembly with symbol-resolved operands, memory dump/edit, inline
assembler (a ADDR MNEMONIC [operand]), memory search
(find bytes or text), stack. Live peripheral introspection (via, psg,
disk, acia, tape, loci).
Symbols, TUI & GDB
Load symbol tables (.sym/.lab/EQU/VICE), an ncurses TUI with 6
panes (TUI=1 build), and above all a remote GDB stub to debug the 6502 from
gdb, lldb or an IDE (VS Code, CLion) over the RSP protocol — no other Oric emulator offers
this.
- --debug · --break ADDR · --symbols FILE · --tui · --gdb[=PORT]
7. Control & automation
IPC control mode OricForge
With --control, Phosphoric speaks a text protocol over stdin/stdout (logs on stderr): 30
commands (hello, regs, read, write, peek,
break, step, load-tap, load-rom, load-disk…)
and 3 event types. Async pause while running, capability negotiation. Designed for the OricForge IDE.
HTTP API (REST)
The same command set over HTTP/JSON (HTTPAPI=1 build, port 8888 by default) for scripting,
browser dashboards and end-to-end tests. Endpoints GET /hello /regs /mem /peek/… and
POST /reset /mem /keys /tape /disk /exec/…. You can type at the keyboard remotely
(POST /keys with text=…). Binds 127.0.0.1 by default, file ops bounded
to a sandbox root.
- --http-api[=PORT] · --http-api-bind ADDR · --http-api-root DIR
Deterministic record / replay (“TAS movie”)
Record keyboard input and replay it bit-deterministically: tool-assisted runs, bug repro, CI regressions. No other Oric emulator offers this.
- --record FILE · --replay FILE
Keyboard automation
Simulated typing with escapes (\n Return, \e Esc, arrows, \Cx
Ctrl+x, \Fx Funct+x…). Pacing is synced on the real keyboard scanner (VIA PB3
matrix sweep): no dropped keys. Can be armed on a memory state instead of a guessed cycle.
- --type-keys N:TEXT · --type-keys-when A:V:TEXT
8. Chromecast / Google Cast streaming
Stream to a Google Cast TV
Phosphoric can stream the Oric's screen and sound to a Chromecast / Google Cast device.
An HTTP MJPEG server (video stream /stream, 720×672, 3× upscale), real-time
PSG WAV audio (/audio), native CASTV2 control (the Google Cast
protocol) and mDNS discovery of devices on the network. Requires a CAST=1
build.
- --cast-server[=PORT] MJPEG server (8080 by default)
- --cast-to[=DEVICE] cast to a Chromecast · --cast-discover list devices
9. Display & capture
Scaling
Integer scaling ×1 (240×224) to ×4 (960×896), nearest-neighbour (pixel-perfect, no blur), toggled live with F3.
- --scale 1 | 2 | 3 (default) | 4 · --keyboard qwerty | azerty · --fullscreen (F11)
Screenshots & video
PPM / BMP / PNG screenshots — at exit, at a given cycle, or triggered by a memory state
(RAM[A]==V). Screen text dump (ASCII) or ANSI true-colour framebuffer. Motion-JPEG AVI
video recording (audio track included in GUI mode). PSG WAV audio capture, testable in CI without a display.
- --screenshot[-at/-text/-ansi/-when] · --dump-ram-when A:V:FILE
- --video FILE · --video-fps N · --video-quality N · --audio-wav FILE
10. ULA-NG (next-gen)
Software reference for an FPGA ULA
A reference model for a future Verilog/FPGA ULA (Sipeed Tang Primer 20K / GW2A-18). Register window
$0340-$035F, locked at reset → bit-for-bit identical to a stock HCS 10017 until
a program unlocks it ('N','G' on $0340). 8 features: palette indirection (16×12-bit
LUT), raster IRQ, start-address (double-buffer / scroll), per-scanline copper, fine X/Y scroll,
parallel attributes (per-cell ink+paper, no colour clash), 16 hardware
sprites 16×16 with priority + collision, and chunky 4bpp (320×224, 16 colours) /
80-column text modes. One demo per feature is provided.
- --ula-ng-poke "340=4E,340=47,341=05,…" (startup injection)
11. Trace, profiling, ROM analysis
CPU instruction trace
Logs every instruction with disassembly and register state
(CYCLES PC BYTES DISASM A= X= Y= SP= P=).
- --trace FILE · --trace-max N
Performance profiler
Per-address hit and cycle counts across the 64 KB, histogram of all 256 opcodes, top-20 hotspot report.
- --profile FILE
ROM analysis
Extracts vectors (RESET, NMI, IRQ), subroutine map (JSR/JMP targets with reference counts), ASCII string detection, usage statistics (code / data / fill), pattern search.
- --rom-info [FILE]
12. Supported operating systems
Phosphoric runs natively on the three major desktop systems, in the browser, and in headless mode for automation. The same code produces identical output everywhere.
| System | How | Notes |
|---|---|---|
| Linux | native SDL2 build (make SDL2=1) | Primary development platform. All features: ALSA MIDI, Cast, GDB stub, TCP/PTY/COM serial. |
| Windows 11 (native) | .exe (CI or MinGW-w64, make WIN=1 SDL2=1) | v1 limits: serial tcp/pty/modem/com/picowifi, --gdb, --control (async pause), Cast and host MIDI are Linux-only. |
| Windows 11 (WSL2) | Linux build under WSLg | Full Linux build, all features. |
| macOS | native SDL2 build | Host MIDI via CoreMIDI. |
| Browser | WebAssembly (make wasm) | Cross-platform (Chrome, Firefox, Safari, Edge), zero install. Native sockets/threads are no-ops; core, video, audio, keyboard, cassette and disk all work. See the browser guide. |
| CI / server | headless mode (make SDL2=0, --headless) | No display: tests, automation, screenshots, CI-testable WAV audio. |
13. Convenience & ports
Cross-platform
Native SDL2 build on Linux, Windows and macOS; on Windows 11: browser (WebAssembly, zero install), native .exe (CI or MinGW-w64) or WSL2 (full Linux build under WSLg). Details in the Operating systems section above.
WebAssembly build
The full machine runs in a tab on a <canvas> (Web Audio, .tap/.dsk
drag-drop, ROM selector, CRT filter, .ost save states, tape/disk activity LEDs, on-screen
ORIC-1/Atmos keyboard). Byte-for-byte identical output to native. This is the build that powers the site's
“Run online” button.
Conversion tools & misc
bas2tap, bin2tap, tap2sedoric (Sedoric file injection),
sedoric-info (disk inspector). QWERTY/AZERTY layouts, headless mode
(CI/automation), host filesystem sharing (--hostfs).
- --headless · --hostfs DIR · --cycles N · make tools
14. Serial: chips × transports
Phosphoric separates the UART the Oric program drives (a memory-mapped chip) from the transport that carries the bytes on the host. Pick one chip and give it a transport.
Chips (where the program reads/writes):
| Option | Chip | Address | Real hardware |
|---|---|---|---|
--serial | ACIA 6551 (MOS) | $031C ($0380 under --loci) | Oric V23 modem, Telestrat |
--dtl2000 | PIA 6821 + ACIA 6850 | $03F8 | Digitelec DTL 2000 card |
--mageco | ACIA 6850 | $03FE | Mageco MIDI interface (31250 baud) |
--oricon | ACIA 6850 + clock gen | $031C | ORICON MIDI (LOCI-compatible) |
--loci | LOCI MIA | $03A0-$03BF | LOCI interface (sodiumlb) |
Transports (where the bytes go). Transparent = raw byte pipe; protocol = injects its own command/UART layer:
| Transport | Kind | Notes |
|---|---|---|
loopback | transparent | TX feeds back to RX (tests) |
tcp:H:P | transparent | BBS / Minitel / telnet / MIDI router over TCP |
pty | transparent | POSIX pseudo-terminal (minicom, screen) |
com:B,D,P,S,DEV | transparent | real serial device (termios) |
file:IN[:OUT] | transparent | deterministic replay (RX) / capture (TX); MIDI capture |
midi[:TARGET] | transparent | live host MIDI port (MIDI=1) |
smf:FILE[:loop] | transparent | Standard MIDI File → timed MIDI IN |
modem[:H:P] | protocol | Hayes AT interpreter (--serial only) |
digitelec:H:P | protocol | Deprecated → use --dtl2000 |
picowifi[:…] | protocol | PicoWiFiModemUSB WiFi modem (--serial only) |
--serial tuning options: --serial-v23 (asymmetric 1200/75 Minitel),
--serial-buffer N, --serial-baud N, --serial-irq-on-rdrf (WDC 65C51 IRQ
mode), --serial-trace, --serial-tcp-backpressure, --acia-addr.
15. Key bindings
| Key | Function |
|---|---|
| F2 | Quick save state |
| F3 | Cycle display scale (×1→×2→×3→×4) |
| F4 | Quick load state |
| F5 | Warm reset |
| F6 | OSD — hot-swap tape/disk media |
| F7 | Memory dump (64 KB RAM to a timestamped .bin) |
| F8 | LOCI Action button — short: snapshot + menu; hold ≥ 2 s: diag ROM |
| F9 | Enter debugger |
| F10 | Quit |
| F11 | Fullscreen |
| F12 | PNG screenshot (timestamped if one already exists) |
16. Building
make # standard build with SDL2 (default)
make SDL2=0 # headless build (no SDL2, for CI/automation)
make DEBUG=1 # debug build (-g -O0)
make CAST=1 # with Chromecast / Google Cast support
make MIDI=1 # with real-time host MIDI (ALSA/CoreMIDI/WinMM)
make wasm # WebAssembly / browser build (needs Emscripten)
make tools # conversion tools (bas2tap, bin2tap, tap2sedoric, sedoric-info)
sudo make install # install to /usr/local
Prerequisites (Debian/Ubuntu): sudo apt install build-essential libsdl2-dev
(and libssl-dev for Chromecast). See the documentation for
per-platform details.