Skip to content
Phosphoricwiki
Contents

The LOCI

The LOCI is a modern cartridge for the Oric, built on an RP2040. Phosphoric emulates it in three ways: with a built-in model, by running its real firmware, or by talking to a real board over USB.

On this page

What the LOCI is

The LOCI (Lovely Oric Computer Interface, 2024) is a cartridge that plugs into the Oric’s expansion port. Its heart is an RP2040 microcontroller, which reads the 6502’s bus with its PIOs and answers in its place. It brings:

  • mass storage: its internal flash, a USB key, an SD card;
  • USB peripherals: keyboard, mouse, gamepads;
  • a Wi-Fi modem (PicoWiFiModemUSB), seen by the Oric as an ACIA at $0380;
  • a built-in menu, and hot swapping of the Oric’s ROM;
  • emulation of a floppy controller, to boot Sedoric without a Microdisc.

The emulation follows the firmware’s source code (reference version 0.3.1) and was checked on a real board. Known differences are listed at the end of the page.

Three modes

ModeOptionWhat runs
built-in--locia model written in Phosphoric
firmware--loci-emu ELFthe LOCI’s real firmware, run by an RP2040 emulator
usb--loci-hw PORTa real LOCI-USB plugged into the host

A single binary holds all three, and the F1 menu only offers those that were available at build time.

The LOCI-USB

A LOCI-USB is a LOCI without the Oric interface, with a second USB port. Today it is an Adafruit Feather RP2040 USB Host board running the LOCI firmware. It is not a bridge to a LOCI cartridge: it is the LOCI itself. Phosphoric plays the Oric: its emulated 6502 sends its page 3 and ROM accesses over USB, and the firmware replays them in its usual bus path. The board’s USB-A port serves as the LOCI’s USB ports (key, keyboard, modem).

Launched without a disk card, Phosphoric uses a plugged-in LOCI-USB automatically, after three checks:

  1. the hardware: a USB product whose name starts with “LOCI-USB” (read from /sys, without opening the port);
  2. the protocol: the board answers PING;
  3. the firmware: address $0319 reads 'L'.

The port is not taken if another program already has it open. Never with no display, nor under make tests. --no-auto-loci turns this off.

The memory map

WindowContents
$0310-$031Fthe LOCI’s WD1793 floppy controller; $0319 reads 'L'
$0315-$0317low-level tape protocol
$0380-$0383the Wi-Fi modem’s ACIA 6551
$03A0-$03BFthe MIA: console, API registers, exchange stack ($03AC), operation ($03AF), wait loop ($03B0)

The API has 36 operations out of 36: system, clock, files, directories, mounting, tape, boot and bus tuning. Its conventions are those of the firmware, checked against its source: file errors are 32 + FRESULT from FatFS, file descriptors run from 3 to 18 and directory ones from 64, the exchange stack is 512 bytes.

Storage

On the real boardIn Phosphoric
the internal flasha folder: --loci-flash FOLDER (by default, the current folder)
a USB key--loci-usb FOLDER (up to 4), or the media mounted in /media/$USER, detected at launch
an SD carda raw FAT16 or FAT32 image: --loci-sdimg IMAGE

The LOCI menu’s selector lists the devices as the real firmware does: “0: Internal storage”, then one line per USB device.

The Action button (F8)

  • Short press: the session is saved, then the LOCI menu starts. Like the real firmware, Phosphoric writes the firmware version and the bus settings into the menu ROM. The menu’s resume entry puts back the previous ROM and restores the session.
  • Long press (2 seconds or more): a diagnostic ROM starts and tests the processor, the ULA, the memory, the VIA and the PSG step by step.
  • On a keyboard where F8 is a media key, Ctrl+Alt+M and Ctrl+Alt+D make the short and long presses.

The diagnostic ROM waits for a press on the NMI button to continue: that is Shift+F5 since version 2.29.

The race against the 6502

The LOCI cartridge's race against the 6502, in nanosecondsOn the Oric, PHI2 is high only during the last third of the one-microsecond cycle. A read served by the LOCI cartridge must put its data on the bus before the moment the 6502 latches it: 900 ns after the start of the cycle (period minus 100 ns of setup). With the default settings, the data is on the bus at 708 ns as long as the firmware answers in under 58 cycles; on the real cartridge, 23 cycles were measured, a margin of about 190 ns.A read served by the LOCI, in a 1 µs cyclePHI2PHI2 low: two thirds of the cyclePHI2 high0 ns250 ns500 ns750 ns1000 nsdata on the bus708 ns (default settings)the 6502 latches it900 ns = period − 100 nsmarginMeasured on the real cartridge: the firmware answers in 23 cycles, a margin of about 190 ns.Beyond 81 cycles, the data would arrive too late: the 6502 would read a bus nobody drives.It is the only place in Phosphoric modelled below the cycle (partial level N4).
A read served by the LOCI: the data must be on the bus before the 6502 latches it.

The Oric’s expansion port has no RDY line: a peripheral cannot ask the 6502 to wait. The LOCI must read the address with its PIOs, process it in software, then put the data on the bus, all before the instant the 6502 latches it. If it is late, nobody drives the bus, and the 6502 reads anything.

At the scale of a whole cycle, this phenomenon is invisible. So for this one place, Phosphoric has a nanosecond time base (include/io/bus_timing.h):

StepInstant
the Oric’s PHI2low during the first two thirds of the cycle, high during the last
data on the bus708 ns with the default settings, as long as the firmware answers within 58 cycles
the 6502 latches it900 ns: the period minus 100 ns of setup
the limit81 to 82 cycles of firmware response

Measured on the Feather board: the firmware answers in 23 cycles, the data is on the bus around 708 ns, the margin is about 190 ns.

Two reliability models coexist: WINDOW (the default), where a read is reliable if the firmware’s tior setting falls within a range, like the real firmware’s per-board calibration; and PHASE (--loci-serve-timing), which follows the timeline above, with optional jitter. It is the only place in Phosphoric that reaches, in part, level N4.

Faster over USB

With a LOCI-USB, each page 3 access is a USB round trip during which the emulated 6502 is frozen. Version 2.29.3 groups the writes (in packets of 256), 2.30.0 reads ahead in 256-byte blocks when the firmware allows it. Measured on the board: saving then returning to the menu went from one or two minutes to about 4 seconds, and returning to BASIC from 12 to 4 seconds.

In the browser

The web version can start the LOCI menu (?loci=1, or the LOCI button), with an internal flash kept in the browser (IndexedDB). The Wi-Fi modem, USB keys and SD images are not available there. See In the browser.

Known differences

  • The real board’s internal flash (a LittleFS file system) is not emulated as such: a folder plays that role, with the logic of a FAT file system.
  • USB keys are detected at launch only: no hot-plugging.
  • The LOCI’s floppy controller keeps short delays. That is faithful: on the real board, its “drive” is the RP2040 and an SD card, with no mechanics.

Sources in the repository : docs/loci.md, docs/architecture/phi2-bus-timing.md, docs/architecture/loci-glue.md, docs/ACCURACY.md.