Skip to content
Phosphoricwiki
Contents

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

FeatureWhat it doesRegisters
Palettecolours become indexes into a table of 16 entries of 12 bits (4,096 shades)$0348-$034A
Raster IRQan interrupt on a chosen line (0 to 255)$0346, $0347
Start addressthe screen is read from another address: double buffer, coarse scrolling$0342-$0343
Coppera list of 64 palette changes, applied line by line$034B, $034C
Fine scrolling0 to 5 pixels in X, 0 to 7 in Y$0344, $0345
Parallel attributesink and paper per cell, in a separate plane: no more colour clash$034D, $034E
Sprites16 sprites of 16 × 16 pixels, priority by number, collisions$0350-$0356
Chunky and 80 columns320 × 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.

Mosaic of colour cells in a diagonal gradient
Parallel attributes: each cell has its own background, with no cell lost.
Coloured horizontal bars behind a repeated text
Copper: the palette changes on every line.

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.

CommandEffect
20reset
22 nmode: 0 standard, 1 chunky, 2 80 columns
19 l r g bset a palette colour
18 abackground colour per cell
31 col row acolour 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.

Coloured rays leaving a point
A sunburst drawn by 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.

Sources in the repository : docs/ula-ng/README-ULA-NG.md, docs/ula-ng/ULA-NG-SPEC.md, docs/ula-ng/VDU.md, docs/ula-ng/AUDIT.md.