SAA5050 Teletext Generator

Mullard (Philips) SAA5050 — character generator for World System Teletext Level 1. The BBC uses it as the entire pixel-generation pipeline for MODE 7 (replacing the in-chip serialiser of the video-ula for that mode). Fed by the 6845 CRTC’s MA address bus through the address-translation Teletext path; output RGB+Y replaces the Video ULA’s pixel stream when bit 1 of the Video ULA control register (&FE20) is set.

Not present on the Electron — Electron’s MODE 7 is software-emulated by the ULA, with significant visual differences.

What it is and isn’t

  • Is: a 7-bit-in, RGB-out character generator with a built-in attribute state machine. Handles its own colour latching, hold-graphics, double-height, flash, and contiguous/separated graphics state on a per-line basis.
  • Is not: a teletext decoder. The BBC writes character bytes directly to MODE 7 screen RAM (&7C00-&7FF7 by default); the chip just renders them. (Some other applications used the SAA5040/41 decoder chips upstream — not the BBC.)

Display geometry

ParameterValue
Display40 × 25 character grid
Character cell12 × 20 pixels
Internal character ROM5 × 9 pixels per glyph
InterpolationDiagonal smoothing → 10 × 18 pixels rendered
Full screen resolution480 × 500 (480 × 250 displayed lines × 2 fields)
Border2 pixels top, 2 pixels left, surrounding the glyph
Block graphics2 × 3 mosaic per cell

Character ROM derived from the Signetics 2513 (a 1970s 5×7 generator), extended for teletext use. The diagonal-smoothing interpolation produces the angular “teletext typeface” that defines MODE 7’s look.

Interface signals (per BeebFpga VHDL model)

Pin / signalDirectionFunction
DI[6:0]in7-bit character data (from screen RAM, via address translator) — top bit ignored
DEWinData Entry Window — VSYNC-synced; falling edge resets line + flash counters
LOSEinLoad Output Shift register Enable — active during visible video
CRSinCharacter Rounding Select — tied to field (even/odd) for interlace smoothing
GLRinGeneral Line Reset — not used by BBC
CLKin6 MHz dot clock
R, G, BoutSingle-bit colour outputs (drive to Video ULA RGB pads)
YoutMonochrome luminance (for B&W displays / cassette)
/SI(BBC: tied)Text-mode enable. BBC ties this so TEXT mode is permanently on

Why MODE 7 is hardware-special

  1. The address-translation MODE 7 path (TTX VDU mode) reads two bytes per microsecond — IC 15 routes one to the SAA5050 and discards the other, providing DRAM refresh.
  2. The CRTC’s R8 must be &03 (interlace sync & video) to align the SAA5050’s 20-scanline character cell with the 6845’s row count.
  3. CRTC R8 display delay = 1, cursor delay = 2 — compensates for the SAA5050’s 1-character pipeline (DI input → RGB output takes one character clock); the cursor must arrive 2 character clocks later so it visually overlays the right cell.
  4. The Video ULA’s bit 1 of &FE20 is set (= &4B in MODE 7’s default control register value) — routes RGB from the SAA5050 instead of the in-chip serialiser.
  5. The CRTC R12/R13 XOR &54 quirk routes the start address into the &2000-&2FFF range that the address translator interprets as Teletext-mode addressing. See crtc-6845 MODE 7 section.

Character codes & control codes

The SAA5050 takes a 7-bit character code. The BBC stores screen bytes with bit 7 set for control codes so &00-&7F are not control codes in MODE 7 screen RAM — they’re either displayable characters or undefined. Codes &80-&9F are the teletext control codes. Codes &20-&7F are the displayable character set (ASCII subset + a few mosaic graphics).

Control code table

Per saa5050-references (mdfs.net):

CodeFunctionTypeLine-start default?
&80Alpha black (text)Set-After(see “no black text” note below)
&81Alpha redSet-After
&82Alpha greenSet-After
&83Alpha yellowSet-After
&84Alpha blueSet-After
&85Alpha magentaSet-After
&86Alpha cyanSet-After
&87Alpha whiteSet-Afteryes
&88Flash onSet-After
&89Flash off (steady)Set-Atyes
&8AEnd boxSet-After
&8BStart boxSet-After
&8CNormal height 1×1Set-Afteryes
&8DDouble height 1×2Set-After
&8EDouble width 2×1Set-After
&8FDouble size 2×2Set-After
&90-&97Mosaic (graphics) black … whiteSet-After
&98Conceal displaySet-At
&99Contiguous graphicsSet-After
&9ASeparated graphicsSet-After
&9BToggle G0 character setsSet-After
&9CBlack backgroundSet-Atyes
&9DNew background (= current fg → bg)Set-At
&9EHold graphicsSet-At
&9FRelease graphicsSet-Afteryes

Set-After vs Set-At semantics:

  • Set-After: the control character’s own cell is rendered as a background-coloured space; the new attribute takes effect from the next character cell.
  • Set-At: the control character’s own cell is also affected by the new attribute. Useful for Conceal, Hold Graphics, and New Background where immediate effect is wanted.

Quirks worth noting

  • No black text in practice: &80 (Alpha black) writes a control character but produces no visible text because background defaults to black. To get visible black-on-X text, change background first with &9D after another colour. This is a chip-level limitation, not a workaround on the BBC’s side.
  • Hold graphics bug: when in hold-graphics state, ANY control code other than &9E itself clears the held character — even though the cell still occupies space. Documented in the BeebFpga VHDL model as “SAA5050 hold bug”.
  • Double-height pair rule: any character in the second row of a double-height pair that is not also marked &8D/&8F becomes invisible. You cannot mix single- and double-height vertically within a paired row.
  • Flash rate: ~0.78 Hz, 3:1 on/off duty cycle. Independent of the Video ULA’s flash bit (&FE20 bit 0) — SAA5050 has its own flash counter, reset every field by DEW.
  • Toggle G0 character sets (&9B): switches to alternate G0 set (graphics-substitution mode). Rarely used on the BBC.

BBC MODE 7 screen RAM layout

  • Default location: &7C00-&7FE7 (1000 bytes = 40 × 25); 2 KB region &7C00-&7FFF has 24 spare bytes that some demos repurpose as scratch.
  • R12/R13 in MODE 7 must be XORed with &54 before writing (see crtc-6845). Default value puts displayed area at &7C00.
  • Alternate &3C00-&3FFF block — Model B / B+ only. Because the address-translation Teletext path takes ((MA & 0x800) << 3) as the top address bit, the SAA5050 can be pointed at either &3C00-&3FFF or &7C00-&7FFF. The Model B / B+ address translator implements both; you can switch by toggling MA11 (i.e. write a different R12). Useful for double-buffered teletext (programming start address &2400 even gives a 2K linear stream &3C00 → &7C00). On the Master the memory-management ULA does not replicate this quirk — MODE 7 screen lives at &7C00 only; for shadow MODE 7, use ACCCON D/E/X bits to switch which physical bank &7C00 refers to (see shadow-ram). On the Electron MODE 7 is software-emulated and the dual-address quirk does not exist.

Address translator formula (from address-translation):

phys_addr = ((MA & 0x800) << 3) | 0x3C00 | (MA & 0x3FF)

RA (raster address) is ignored for memory fetch — the same character byte is held across all 20 scanlines of the cell.

VDU driver substitutions before display

Per master-rm Ch E.5, the MOS VDU driver substitutes 3 ASCII codes before writing to MODE 7 screen RAM, so the teletext character generator displays them consistently with non-teletext modes:

Input ASCIIStored as
35 (#)95 (Teletext hash glyph)
95 (_)96 (Teletext underline glyph)
96 (`)35 (Teletext £ pound sign)

This is why typing # from BASIC in MODE 7 visually produces a hash even though the SAA5050’s native ASCII 35 glyph is £. Code that writes directly to &7C00+ (bypassing the VDU driver) sees the raw SAA5050 glyph table, so direct-poke MODE 7 work needs to translate manually if it wants to match what PRINT produces.

VDU commands that work in MODE 7

Per MRM Ch E.5, the following VDU commands behave normally in MODE 7 and 135. All others are parsed and ignored (except VDU 25 PLOT codes and unknown VDU 23 codes, which are routed to the unknown PLOT codes vector — see vdu-internals).

VDUFunctionVDUFunction
0null14, 15paged mode on/off
1, 2, 3printer control21, 22disable VDU / select mode
6enable VDU driver23,0control 6845 directly
7BELL23,1turn cursor off
8-11cursor moves23,7direct window scroll
12, 13clear screen / CR23,8clear text block
23,16cursor movement control23,28-31user PLOT calls
27null30, 31home / tab cursor
127backspace + delete

Colour selection (VDU 17/18/19/20) and graphics (VDU 24/25/29) do not apply — colours come from teletext control codes (alphanumeric colour 129-135, graphics colour 145-151) instead.

Performance notes

  • MODE 7 has the lowest screen-RAM footprint (1 KB) and the lowest CPU/DRAM bandwidth cost of any BBC mode — but you cannot use it for graphics work in the conventional sense. Each byte is a 7-bit character or control code, not pixels.
  • DRAM refresh in MODE 7 is by far the most aggressive (88 µs worst-case interval) thanks to the MA6 ⊕ 1MHz trick — see address-translation. As a side effect, MODE 7 puts more bus traffic into the 4 MHz video cycle than any other mode.
  • The SAA5050 is itself the bottleneck for mid-frame attribute changes. Set-after codes mean each control occupies a cell, so palette/colour splits within a teletext row cost visible character cells.
  • Cursor in MODE 7 has a 2-character delay (R8 bits 6-7 = 10) — the hardware cursor signal trails the address generator by 2 character clocks. Account for this if computing cursor position from R14/R15.

See also

  • crtc-6845 — the address generator that feeds SAA5050.
  • crtc-6845-advanced — what you can/can’t rewrite mid-frame.
  • video-ula — partner chip; bit 1 of &FE20 selects SAA5050 over the in-chip serialiser.
  • address-translation — the TTX VDU translation path that feeds the SAA5050.
  • memory-map — where MODE 7 screen RAM lives.
  • modes — MODE 7 in the mode table.
  • saa5050-references — combined references list (Wikipedia, HandWiki, mdfs.net, BeebFpga).

Outstanding TODO

The primary Mullard SAA5050 datasheet (raw/manuals/SAA5050.pdf, 1982) remains image-only. When OCR’d, revisit this page to fill in: full pinout (28 pins), electrical specs, timing diagrams, and the formal set-after / set-at table for all control codes.


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.