-
-
Notifications
You must be signed in to change notification settings - Fork 26
PICO9918 Programmers Reference
This page documents programming features that are specific to the PICO9918 and are not present on the original F18A hardware. All features on this page require the F18A unlock sequence to be active.
For the full F18A-compatible register set, see F18A Programmers Reference.
The PICO9918 extends the F18A's row-30 mode with additional row counts, allowing 48-row and 60-row displays.
Set R49 bit 6 (ROW30) to enable 30-row mode (240 active lines). The sprite Y terminator changes from 0xD0 (208) to 0xF0 (240).
These extended modes use R0 bit 3 (IE1) together with R49 bit 6 (ROW30) to select the row count:
| R0 bit 3 (IE1) | R49 bit 6 (ROW30) | Rows | Active Lines | Vertical Scaling |
|---|---|---|---|---|
| 0 | 0 | 24 | 192 | 2x |
| 0 | 1 | 30 | 240 | 2x |
| 1 | 0 | 48 | 384 | 1x (no doubling) |
| 1 | 1 | 60 | 480 | 1x (no doubling) |
In 48-row and 60-row modes, vertical scaling is disabled — each scanline is rendered once, not doubled. This gives access to the full 480 lines of the VGA output.
Note: In 48 and 60-row modes, R0 bit 3 is repurposed for row selection and is not available as a horizontal interrupt enable.
In standard TMS9918A and F18A sprite rendering, color 0 pixels within a sprite pattern are transparent. The PICO9918 adds an opaque sprite flag that causes color 0 pixels to be rendered using palette entry 0 instead.
The opaque flag is bit 4 of sprite attribute byte 3 (the color byte), and only applies in 16x16 sprite mode:
| Bit | Description |
|---|---|
| 7 | Early clock (EC) |
| 6 | Flip X |
| 5 | Flip Y |
| 4 | Opaque (PICO9918, 16x16 mode only) |
| 3-0 | Color / ECM palette select |
When set, transparent pixels within the sprite are drawn as the background color from palette entry 0, making the sprite fully opaque.
The PICO9918 exposes its configuration settings through two F18A extended registers (R58 and R59) and a status register (SR12), allowing software to read and modify configuration at runtime.
Writing to R58 selects which configuration option to access. The current value of the selected option is immediately available in status register 12.
Writing to R59 sets the value of the configuration option currently selected by R58. Only writable for option indices >= 8 (hardware info options 0-6 are read-only).
Returns the current value of the configuration option selected by R58. Updated whenever R58 or R59 is written.
Read-only hardware info (indices 0-6):
| Index | Name | Values |
|---|---|---|
| 0 | Pico model | 1 = RP2040, 2 = RP2350 |
| 1 | Hardware version | 0x03 = V0.3, 0x10 = V1.0+, 0x20 = V2.0+ |
| 2 | Firmware version (major.minor) | Upper nibble = major, lower = minor |
| 3 | Firmware patch version | Patch number |
| 4 | Last tested clock preset | 0-2 |
| 5 | Display driver | 0 = VGA, 1 = NTSC SCART, 2 = PAL SCART |
| 6 | Flash status | Reserved |
User-configurable (indices 8+):
| Index | Name | Range | Default |
|---|---|---|---|
| 8 | CRT scanlines | 0-1 | 0 (off) |
| 9 | Scanline sprite limit | 0-3 | 0 (no limit) |
| 10 | Clock preset | 0-2 | 0 (252 MHz) |
| 16 | Diagnostic overlays master | 0-1 | 0 (off) |
| 17 | Diagnostic overlay: registers | 0-1 | 0 |
| 18 | Diagnostic overlay: performance | 0-1 | 0 |
| 19 | Diagnostic overlay: palette | 0-1 | 0 |
| 20 | Diagnostic overlay: address | 0-1 | 0 |
| 128-159 | Palette entries 0-15 | 16 x 2 bytes | Default TMS9918A palette |
| 255 | Save to flash | Write 1 to trigger | 0 |
Configuration changes made via R59 take effect immediately but are not automatically persisted to flash. To save the current configuration permanently:
- Select option index 255 by writing
0xFFto R58 - Write
0x01to R59 to trigger a flash save
The configuration is stored at the top of flash memory (address 0x1FF000) and survives firmware updates.
To read a configuration value:
- Write the option index to R58
- Read status register 12 (select SR12 via R15, then read the status port)
; Assumes F18A is unlocked
; Read current scanline setting
write 0x08 to R58 ; select option 8 (CRT scanlines)
write 0x0C to R15 ; select status register 12
value = read status port ; current value (0 or 1)
write 0x00 to R15 ; restore S0 selection
; Toggle and write back
new_value = value XOR 1
write 0x08 to R58 ; select option 8
write new_value to R59 ; apply new value
; Save to flash
write 0xFF to R58 ; select option 255 (save trigger)
write 0x01 to R59 ; trigger flash save
The PICO9918 supports firmware updates through the VDP register interface, used by the Configurator on platforms with ROM banking support.
| Bit | Description |
|---|---|
| 7 | Execute firmware update operation |
| 6 | Operation type (0 = verify, 1 = write) |
| 5-0 | Address for 256-byte page access |
Writing to R63 reads one UF2 frame (512 bytes) from the data previously written to VRAM. The operation will not execute if the GPU is currently running.
During firmware operations, SR2 reports progress:
| Bits | Field | Values |
|---|---|---|
| 7 | Running | Operation in progress |
| 6-5 | Retry count | 0-3 |
| 4-2 | Error code | 0=OK, 1=Header, 2=Sequence, 3=Size, 4=Verify, 5=Busy |
| 1-0 | Status | 0=Idle, 1=Validating, 2=Erasing, 3=Writing |
Contains the RP2040/RP2350 core temperature encoded as (tempC * 4 + 0.5) as a uint8_t. Updated every 64 frames.
To decode: tempC = value / 4.0
On the original F18A, the GPU address space has defined regions with gaps between them. On the PICO9918, the full 64KB address space is backed by RAM, making the gaps usable as additional GPU RAM:
| Address Range | Size | Contents |
|---|---|---|
0x6040-0x6FFF
|
~4 KB | GRAM2 |
0x7002-0xAFFF
|
~16 KB | GRAM3 |
0xB010-0xFFFF
|
~20 KB | GRAM4 |
See F18A Programmers Reference#Memory Map (F18A Mode) for the full address space layout.
Hardware
- Hardware
- Hardware Setup
- Digital AV (HDMI) Dongle
- SCART AV Dongle
- TI-99 4A No-Cut Mod
- F18A to PICO9918 Dongle Adapter
Supported Devices
Firmware
Configurator
Programming
Reference