Raster Splits

“Raster split” is the umbrella term for changing CRTC or Video ULA state mid-frame, in sync with the beam position, to make different parts of the screen behave differently. The BBC has no hardware sprite, no scrolling layers, no per-pixel attributes — but a 2 MHz CPU racing a 50 Hz raster can substitute for all of those, given precise enough timing.

This page is an index of the specific raster-split families documented on the wiki. Each family is its own technique page; this page exists so readers entering with “I want to do a raster split” land somewhere useful.

The split levers

Five things can be changed mid-frame, each with its own latency and visible cost:

LeverWhere to writeLatencyVisible costTypical use
Palette colourVideo ULA &FE214c (stretched)1 entry per write; in MODE 1 you must write 4 entries to fully change a colour (video-ula)Per-raster hue rotation, copper bars
ULA flash bit&FE20 bit 04c (stretched)1 cyclePer-raster colour inversion of all flash-coded palette entries — see checkerboard-zoom
ULA mode bits&FE20 bits 2-44c (stretched)One char of horizontal smear at the transitionMid-frame MODE width change (rarely worth it on real hardware)
CRTC screen start&FE00/&FE01 R12/R138c per bytePre-latched, applies to next CRTC cycleHardware-scroll position, per-cycle screen-address selection in single-rasterline-rupture
CRTC cycle shape&FE00/&FE01 R4/R6/R7/R54c eachRead on the cycle they govern (R4/R6/R7) or applied at cycle end (R5)Vertical rupture, smooth vertical scroll
ACCCON video source&FE34 bit D4c (stretched)Immediate — affects the next CRTC fetchMid-frame main↔SHADOW swap in parallax-bars

The CRTC’s R12/R13 latch and R4/R6/R7 sample timing are documented on crtc-6845-advanced.

Split families

Per-frame splits (rupture)

Split the frame into N CRTC cycles, each with its own screen-start address. Foundation for everything below.

  • vertical-rupture — the 2-3-cycles-per-frame case used for status panels and game playfields.
  • single-rasterline-rupture — the 64-256 cycles per frame extreme, each cycle 1-4 scanlines tall. Foundation for modern Beeb demos.
  • smooth-vertical-scroll — two-cycle rupture + R5 trick for 1-scanline vertical motion.

Per-raster palette changes

Cycle-counted writes to &FE21 inside horizontal blanking, looping per scanline.

  • twisted-brain Part 3 (Text Screens) — MODE 1 palette swap per raster, ~26c per colour, ~128c/raster budget. Cheapest possible raster split.
  • copper-bars — palette change per CRTC cycle (4-scanline granularity), in horizontal blanking, only when solid colour is on screen (avoids partial-palette artefacts).
  • checkerboard-zoom — per-raster flash-bit toggle instead of palette write. 4 cycles vs ~26 cycles for the equivalent palette change.

Per-cycle screen-start changes

R12/R13 latched once per CRTC cycle, picking a different screen address each time.

  • copper-bars + parallax-bars — pre-rendered buffer, per-cycle address selection by sine-table lookup.
  • twister — narrow-screen variant via R1=20, packing 128 ribbon rotations into a standard MODE 1 buffer.

Beam-raced buffer mutation

R12/R13 stays fixed; CPU rewrites the buffer between scanlines so each visible strip is freshly drawn.

  • vertical-blinds — 2-scanline-per-cycle, double-buffered 160-byte mini-frame.
  • kefrens-bars — 1-scanline-per-cycle, additive 80-byte buffer mutation (4 bytes per scanline budget).

Mid-frame video-source switches

ACCCON D bit toggle on the boundary between CRTC cycles.

  • parallax-bars — main↔SHADOW swap to access a 64-row pre-rendered buffer larger than one MODE 1 screen.
  • twister — alternate-scanline main↔SHADOW swap for a fourth-colour stipple.

Prerequisites

All raster splits depend on knowing what raster the beam is on, accurate to within a few cycles. Three approaches:

  1. System VIA T1 free-run in continuous mode, polled with BIT &FE4D (~8c jitter due to cycle stretching). Used by fx-framework / Twisted Brain.
  2. CRTC vsync interrupt via IRQ1V — same jitter problem as 1, plus IRQ entry latency variability.
  3. hexwab’s stable raster — initial narrowing-loop sync + T1 free-run + per-IRQ jitter compensation via latch read. 2-cycle precision. See hexwab-stable-raster.

For most effects, (1) is good enough. (3) is for sub-pixel-precise effects where the residual 8c jitter would be visible.

Why the BBC is well-suited to this

The CRTC’s R12/R13 latch-once-per-cycle behaviour (crtc-6845-advanced) is the lever. The Video ULA’s separation of “byte fetch” (CRTC) from “byte→pixel decoding” (ULA mode setting) is the second lever. The System VIA’s free-run timer + cycle stretching that aligns reads to 1 MHz boundaries is the third.

Other 8-bit machines have some of these (the C64’s VIC-II is generally more raster-friendly out of the box; the Spectrum’s ULA is more rigid). The BBC’s discrete-logic implementation means more of the chip state is poke-able mid-frame and the timing is more deterministic. That’s why the BBC demo scene is what it is.

Builds on


This wiki is curated by Claude following the LLM-Wiki methodology — a human curates source documents, the LLM compiles structured cross-linked markdown. Content may contain errors, omissions, or stale claims. For authoritative information refer to the original source documents in the bbc-documents GitHub archive.