Tachibana
Language: English

The Neo6502 API

Everything the 65C02 asks of the RP2040 — screen, sound, files, keyboard, clock — goes through a small mailbox at $FF00. Here is how to use it, function by function, for the official firmware and for Trinity, with examples that were run and verified.

Download the specification (YAML)

Two processors, one mailbox

Olimex's Neo6502 pairs a real W65C02S, which runs the programs, with an RP2040, which does everything else: DVI video, sound, USB keyboard and mouse, files on a USB stick, clock. The 65C02 has 64 KB of RAM; to get a service from the RP2040, it writes a request into a 16-byte area at $FF00, the mailbox. The RP2040 firmware reads it, performs the service, then leaves the answer there.

AddressMeaning
$FF00function group; writing it last starts the call; the firmware sets it back to 0 when done
$FF01function number within the group
$FF02error: 0 if the call succeeded
$FF03status: bit 7 is set when Escape is pressed
$FF04–$FF0Bparameters P0 to P7, in and out

A call, in four steps

  1. Wait until $FF00 is 0 (the mailbox is free).
  2. Write the parameters at $FF04 onwards.
  3. Write the function at $FF01, then the group at $FF00: the call starts.
  4. Wait until $FF00 is back to 0, then read $FF02 (error) and the results.

This is exactly what the kernel routine WaitMessage ($FFF4), the llvm-mos C library and the Mad Pascal neo6502 unit do. The kernel also offers a few ready-made entry points: WriteCharacter ($FFF1), ReadCharacter ($FFEE), ReadLine ($FFEB), SendMessage ($FFF7)… Trinity adds tasks and semaphores ($FFC1 to $FFDC).

Conventions

In each language

Official firmware and Trinity

The official firmware is Paul Robson's; Trinity is the collective's alternative firmware, built on it. Each function carries a label: Official (identical in both), Changed by Trinity or Trinity (only exists in Trinity). Function 1,11 gives the running firmware version.

How the examples are verified

Every published example was compiled then run in the Phosphoneo emulator, with the Trinity firmware. A test bench checks in the call log that the program does call the documented function, without error, then compares what it prints with what is expected; the observed output is shown under each example, except when it depends on hardware plugged into the board (UEXT I/O): the emulator only returns dummy values there. An example that did not pass this bench is not published. Code comments and messages in the examples are in French.

What we do not claim: the examples run under Trinity; those of the official functions were not replayed on the official firmware. On the board, a few functions behave differently than in the emulator (serial port, modem, flash): their entry says so.

The groups

GroupNameOriginFunctionsverified examples
Group 1SystemOfficial25 functions97
Group 2ConsoleOfficial24 functions96
Group 3File I/OOfficial30 functions120
Group 4MathematicsOfficial27 functions108
Group 5GraphicsOfficial27 functions108
Group 6SpritesOfficial5 functions20
Group 7ControllerOfficial3 functions12
Group 8SoundOfficial16 functions64
Group 9Turtle GraphicsOfficial6 functions24
Group 10UExt I/OOfficial19 functions76
Group 11MouseOfficial5 functions20
Group 12BlitterOfficial4 functions16
Group 13EditorOfficial2 functions8
Group 14USB Serial (CDC)Trinity6 functions24
Group 32QuickDrawTrinity19 functions76
Group 33Event ManagerTrinity6 functions24
Group 34Window ManagerTrinity12 functions48
Group 35Menu ManagerTrinity10 functions40
Group 36Control ManagerTrinity10 functions40
Group 37Dialog ManagerTrinity6 functions24
Group 38Resource ManagerTrinity8 functions32