The options
Phosphoneo is used from its command line: phosphoneo [program] [options]. The options are grouped below by family, according to what they do around the emulated machine. Each family has its page, with each option’s syntax, what it does, a real example (the quoted output is the emulator’s) and its pitfalls.
Every option at a glance
| Option | What it does | Page |
|---|---|---|
fichier.neo | Loads a .neo executable (the firmware’s format: a series of blocks, each with its address, and an execution address). | Loading a program |
fichier.bas | Loads an already tokenised NeoBASIC program (what SAVE produces) onto the BASIC page and runs it (same as exec, $0806). | Loading a program |
fichier@ADRESSE | Loads a raw file at an address, in hexadecimal. | Loading a program |
cold warm exec run@ADRESSE | Where the 65C02 starts once the files are loaded: cold = $0800, warm = $0803, exec = $0806 (the kernel’s three entry points), run@HEX = any address. | Loading a program |
--storage | Host folder seen by the firmware as the SD card or USB stick (default: storage). | Loading a program |
--load-at | Loads a .neo or .bas after N cycles and restarts the 65C02 on it: what the web page does when you pick a program. | Loading a program |
--floppy | Replaces the storage folder with a real floppy drive (or any block device), served by the firmware’s FatFs: the 65C02’s calls go through the same stack as on the board, down to the last link. | Loading a program |
--cycles | Stops after N cycles and prints the tally: elapsed cycles and number of API calls. | Duration and pace |
--headless | No display. | Duration and pace |
--realtime | Real-time pace without a window: one emulated frame lasts 1/60 s of wall-clock time. | Duration and pace |
--stop-on-self-jmp | Stops when the program executes a JMP to its own address (the “JMP *” that ends a test program) and says where and when. | Duration and pace |
--version | Prints the version and what is built in. | Duration and pace |
--sdl | Opens an SDL2 window: the current video mode’s picture (4:3, resizable), keyboard and mouse passed to the firmware, sound, gamepad. | Window, sound and video |
--scale | Initial window size: N times 320 × 240 (default 3). | Window, sound and video |
--fullscreen | 4:3 full screen with black bars; implies –sdl. | Window, sound and video |
--no-sound | Mutes the window’s audio output. | Window, sound and video |
--wav | Writes the firmware’s sound to a WAV file. | Window, sound and video |
--record | Records picture and sound into an MJPEG AVI video at 60 frames per second. | Window, sound and video |
--screenshot | Saves the screen at the end of the run. | Screenshots and memory dumps |
--screenshot-at | Saves the screen after N cycles, during the run (64 captures at most, with the variants below). | Screenshots and memory dumps |
--screenshot-when | Saves the screen when the 16-bit word stored in memory at ADDRESS (hexadecimal) equals VALUE (decimal). | Screenshots and memory dumps |
--screenshot-text | Writes the console (the 53 × 30 text grid) to a file at the end. | Screenshots and memory dumps |
--screenshot-text-at | Like –screenshot-at, for the text console. | Screenshots and memory dumps |
--screenshot-cursor | Adds the mouse cursor to the screenshot, drawn as the board does (16 × 16, $FF transparent, nothing in monochrome). | Screenshots and memory dumps |
--dump-ram-when | Copies the 64 KB of RAM to a file when RAM[ADDRESS] equals VALUE (hexadecimal; above FF it is the 16-bit word RAM[ADDRESS..ADDRESS+1]). | Screenshots and memory dumps |
--type-keys | Types the TEXT on the keyboard from the given cycle, key by key (press, release), on a US layout. | Keyboard, gamepad, mouse and memory |
--gamepad-at | Sets the gamepad state after N cycles: BITS is a hexadecimal number, one bit per button. | Keyboard, gamepad, mouse and memory |
--mouse-at | Sets the mouse position (in pixels) and button state (bit 0 left, bit 1 right, bit 2 middle) after N cycles. | Keyboard, gamepad, mouse and memory |
--mouse-when | Like –mouse-at, but triggered when the 16-bit word in memory at ADDRESS (hexadecimal) equals VALUE (decimal): click “at frame 120” without working out a cycle. | Keyboard, gamepad, mouse and memory |
--poke-at | Writes a byte to memory (ADDRESS and VALUE in hexadecimal) after N cycles. | Keyboard, gamepad, mouse and memory |
--poke-when | Like –poke-at, but triggered when the 16-bit word at ADDRESS equals VALUE (decimal). | Keyboard, gamepad, mouse and memory |
--trace | Writes every executed instruction: address, code byte, disassembly, registers A X Y S P, cycle, and ea= the operand’s effective address (- when none). | Logs, breaks and debugging |
--trace-from | Only traces from the given cycle: to understand a late hang without producing a giant file. | Logs, breaks and debugging |
--api-log | Logs every API call as it is handled: cycle, instruction address, group, function, parameters before and after, error code. | Logs, breaks and debugging |
--symbols | Loads a symbol file: al ADDRESS .name lines (VICE format, produced by 64tass and cc65), name = $ADDRESS, or exports from an ld65 .map. | Logs, breaks and debugging |
--break-at | Stops execution when the 65C02 reaches this address (hexadecimal or symbol). | Logs, breaks and debugging |
--watch | Watches a memory address: stops at the first write (:w, default), read (:r) or either (:rw). | Logs, breaks and debugging |
--break-api | Stops before the requested API call (every call in the group if the function is omitted), to look at its parameters as the program set them. | Logs, breaks and debugging |
--break-dump | With –break-at, –watch or –break-api: copies the 64 KB of RAM to the file at the moment of the stop, to examine later at leisure. | Logs, breaks and debugging |
--tui | Opens an ncurses monitor: stops at reset, single-stepping (s instruction, n without entering JSRs, c continue), breakpoints and watchpoints, memory, console. | Logs, breaks and debugging |
--gdb | Starts a gdb server (RSP protocol) on 127.0.0.1:PORT (default 1234) and waits for the debugger; execution stops at reset. | Logs, breaks and debugging |
--save-state-at | Saves the state after N cycles; emulation then continues normally. | Save states |
--load-state | Resumes a save before the first instruction. | Save states |
--neo-emu | Instead of the linked behaviour (the API code compiled into Phosphoneo), runs the firmware’s real ELF file on the RP2040 emulator: the PIO program that serves the bus serves the 65C02’s, as on the board. | Co-simulation and latencies |
--api-latency | Freezes the 65C02 during each API call for the number of cycles in the table (per function), instead of 0 by default. | Co-simulation and latencies |
--api-latency-out | In co-simulation, writes the measured latency table at the end of the run (this is how tools/apilat_table.py builds the table for –api-latency). | Co-simulation and latencies |
--cdc-tty | Connects the firmware’s USB serial port (group 14) to a host terminal or pseudo-terminal: the program thinks it talks to a USB modem. | Co-simulation and latencies |
--multiboot --slot-bin --slot-elf | The firmware’s multi-boot selector: –multiboot starts from neoboot.elf, –slot-bin N:FILE puts a binary in slot N of the emulated flash (repeatable), –slot-elf N:ELF names the “reload” firmware of slot N (BBC Micro, Oric), which takes the bus in bit-bang mode after call 1,14 and draws in MODE 7. | Co-simulation and latencies |
--bb-disc --type-keys-bb --shots-bb | For reload firmwares: –bb-disc presents a floppy image (.ssd/.dsd for the BBC) as the USB stick; –type-keys-bb types text N cycles after the switch to the bit-bang bus; –shots-bb sets the capture delay after that switch (default 4,000,000 cycles, stop at +2,000,000). | Co-simulation and latencies |
The tools that come with the emulator (mkneo.py, fake_modem.py, golden.sh…) are described in the reference.
- Loading a programHow to give Phosphoneo a program: .neo, .bas, a binary at an address, start point, storage folder, loading mid-run, and a real floppy drive.
- Duration and paceHow long Phosphoneo runs and how fast: cycle count, headless mode, real time without a window, stopping on an infinite loop, and the version.
- Window, sound and videoPlaying in an SDL window at 60 frames per second with sound and gamepad, or recording picture and sound: --sdl, --scale, --fullscreen, --wav, --record.
- Screenshots and memory dumpsSaving what the program sees: a PPM image, the console as text, the mouse cursor, a capture triggered by a value in memory, and a copy of the whole RAM.
- Keyboard, gamepad, mouse and memoryDriving a program with nobody at the keyboard: automatic typing and its special sequences, gamepad, mouse, and memory writes at a given cycle or on a condition.
- Logs, breaks and debuggingUnderstanding a program that misbehaves: instruction trace, API call log, symbols, breakpoints, watchpoints, a terminal monitor and gdb, with real outputs.
- Save statesFreezing the emulation at a given cycle and resuming later, exactly: --save-state-at and --load-state, what is saved, the limits, and a compared example.
- Co-simulation and latenciesThe options of the second backend, which runs the real ARM firmware on an RP2040 emulator: --neo-emu, --api-latency, USB modem, multi-boot and reload firmwares.