The ULA-NG
What if the Oric’s ULA had had a sequel? The ULA-NG is the software reference of an extended video chip, designed to be rebuilt one day on an FPGA. At start-up, nothing tells it apart from the original.
On this page
A dormant chip
The ULA-NG (next generation) is a layer added to Phosphoric’s ULA. At start-up it is locked:
it behaves exactly, bit for bit, like the original ULA (HCS 10017). Its register window,
$0340-$035F, then falls through to the VIA. No existing program sees a difference, and there is no
option to pass.
It is the software reference of a future FPGA chip (a Sipeed Tang Primer 20K, with a Gowin GW2A-18). Every choice must therefore be wireable: no floating point in the video path, structures with an obvious hardware equivalent (register, small RAM, table, FIFO), and registers sampled deterministically.
Unlocking
Write 'N' ($4E) then 'G' ($47) to $0340, with no other write to the window in between. A
reset locks everything again.
LDA #$4E : STA $0340 ; 'N'
LDA #$47 : STA $0340 ; 'G'
LDA $0340 : CMP #$1E : BNE no_ng ; NG_ID = version 1.0?
LDA $034F : EOR $0340 : CMP #$FF : BNE no_ng ; NG_IDCHK = complement?
In BASIC: POKE#340,78:POKE#340,71.
Eight features
| Feature | What it does | Registers |
|---|---|---|
| Palette | colours become indexes into a table of 16 entries of 12 bits (4,096 shades) | $0348-$034A |
| Raster IRQ | an interrupt on a chosen line (0 to 255) | $0346, $0347 |
| Start address | the screen is read from another address: double buffer, coarse scrolling | $0342-$0343 |
| Copper | a list of 64 palette changes, applied line by line | $034B, $034C |
| Fine scrolling | 0 to 5 pixels in X, 0 to 7 in Y | $0344, $0345 |
| Parallel attributes | ink and paper per cell, in a separate plane: no more colour clash | $034D, $034E |
| Sprites | 16 sprites of 16 × 16 pixels, priority by number, collisions | $0350-$0356 |
| Chunky and 80 columns | 320 × 224 in 16 colours; or text across 480 pixels | $0341 |
NG_MODE ($0341) carries the essentials: bit 0 enables the extensions, bit 1 the parallel
attributes, bits 2 and 3 the video mode (00 standard, 01 chunky, 10 80-column text). Sprites have
their own switch ($0350). Writing 0 to NG_MODE and to $0350 returns to the normal picture
without a reset.


When a register acts
General rule: a register that changes the picture acts on the next line, taken into account during the horizontal retrace. That is what allows the raster split through the palette. Immediate exceptions: unlocking and interrupt acknowledgement. The start address acts on the next frame, for a clean double buffer; chunky and 80-column modes are frozen for a whole frame.
The ULA-NG’s memory
The attribute plane (8 KB), the sprite patterns and the VDU’s picture are not in the 6502’s 64 KB. They live in a memory carried by the ULA-NG, filled through auto-increment ports. On the future FPGA, this memory will be the board’s DDR3; the FPGA’s smaller internal memory will hold the line buffers, the palette and the character set.
The built-in VDU
Rather than writing registers one by one, you can send a command stream to NG_VDU ($0357), in
the manner of the BBC Micro’s VDU. The interpreter lives in the ULA-NG: the 6502 carries no driver,
it sends bytes.
| Command | Effect |
|---|---|
20 | reset |
22 n | mode: 0 standard, 1 chunky, 2 80 columns |
19 l r g b | set a palette colour |
18 a | background colour per cell |
31 col row a | colour one cell, without colour clash |
CLG, DRAW (v0.2) | clear and draw lines in the picture carried by the ULA-NG |
23, 24 (v0.3) | define a sprite through a 256-byte stream, then place it |
Versions 0.1 to 0.3 of the VDU are done and checked. On an FPGA, this interpreter would run as software on a small embedded processor, while the real-time video path would stay wired.

CLG and DRAW, without a single line of 6502 driver.Trying it
There is no BASIC keyword: BASIC has been frozen in ROM since 1983. The ULA-NG is driven by POKE, by
STA in machine code, or from the emulator:
# Palette: colour 7 (white) becomes green
oric1-emu -r roms/basic11b.rom --ula-ng-poke "340=4E,340=47,341=01,348=07,349=00,34A=F0"
# 80-column text
oric1-emu -r roms/basic11b.rom --ula-ng-poke "340=4E,340=47,341=09"
# The demos, with their menu
demos/ula-ng/menu.sh
All the demos are in the gallery.
What remains to do
- Sprite priority relative to the background: for now they are always in front.
- Compact sprite storage (3 bits per pixel) and the extended palette, planned on the FPGA side.
- Character sets and pictures sent to the VDU, and an extended
PLOT.