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-&7FF7by default); the chip just renders them. (Some other applications used the SAA5040/41 decoder chips upstream — not the BBC.)
Display geometry
| Parameter | Value |
|---|---|
| Display | 40 × 25 character grid |
| Character cell | 12 × 20 pixels |
| Internal character ROM | 5 × 9 pixels per glyph |
| Interpolation | Diagonal smoothing → 10 × 18 pixels rendered |
| Full screen resolution | 480 × 500 (480 × 250 displayed lines × 2 fields) |
| Border | 2 pixels top, 2 pixels left, surrounding the glyph |
| Block graphics | 2 × 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 / signal | Direction | Function |
|---|---|---|
DI[6:0] | in | 7-bit character data (from screen RAM, via address translator) — top bit ignored |
DEW | in | Data Entry Window — VSYNC-synced; falling edge resets line + flash counters |
LOSE | in | Load Output Shift register Enable — active during visible video |
CRS | in | Character Rounding Select — tied to field (even/odd) for interlace smoothing |
GLR | in | General Line Reset — not used by BBC |
CLK | in | 6 MHz dot clock |
R, G, B | out | Single-bit colour outputs (drive to Video ULA RGB pads) |
Y | out | Monochrome 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
- 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.
- 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. - 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.
- The Video ULA’s bit 1 of
&FE20is set (=&4Bin MODE 7’s default control register value) — routes RGB from the SAA5050 instead of the in-chip serialiser. - The CRTC R12/R13 XOR
&54quirk routes the start address into the&2000-&2FFFrange 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):
| Code | Function | Type | Line-start default? |
|---|---|---|---|
&80 | Alpha black (text) | Set-After | — (see “no black text” note below) |
&81 | Alpha red | Set-After | — |
&82 | Alpha green | Set-After | — |
&83 | Alpha yellow | Set-After | — |
&84 | Alpha blue | Set-After | — |
&85 | Alpha magenta | Set-After | — |
&86 | Alpha cyan | Set-After | — |
&87 | Alpha white | Set-After | yes |
&88 | Flash on | Set-After | — |
&89 | Flash off (steady) | Set-At | yes |
&8A | End box | Set-After | — |
&8B | Start box | Set-After | — |
&8C | Normal height 1×1 | Set-After | yes |
&8D | Double height 1×2 | Set-After | — |
&8E | Double width 2×1 | Set-After | — |
&8F | Double size 2×2 | Set-After | — |
&90-&97 | Mosaic (graphics) black … white | Set-After | — |
&98 | Conceal display | Set-At | — |
&99 | Contiguous graphics | Set-After | — |
&9A | Separated graphics | Set-After | — |
&9B | Toggle G0 character sets | Set-After | — |
&9C | Black background | Set-At | yes |
&9D | New background (= current fg → bg) | Set-At | — |
&9E | Hold graphics | Set-At | — |
&9F | Release graphics | Set-After | yes |
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, andNew Backgroundwhere 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&9Dafter 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
&9Eitself 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/&8Fbecomes 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 (
&FE20bit 0) — SAA5050 has its own flash counter, reset every field byDEW. - 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-&7FFFhas 24 spare bytes that some demos repurpose as scratch. R12/R13in MODE 7 must be XORed with&54before writing (see crtc-6845). Default value puts displayed area at&7C00.- Alternate
&3C00-&3FFFblock — 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-&3FFFor&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&2400even gives a 2K linear stream&3C00 → &7C00). On the Master the memory-management ULA does not replicate this quirk — MODE 7 screen lives at&7C00only; for shadow MODE 7, use ACCCON D/E/X bits to switch which physical bank&7C00refers 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 ASCII | Stored 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).
| VDU | Function | VDU | Function |
|---|---|---|---|
| 0 | null | 14, 15 | paged mode on/off |
| 1, 2, 3 | printer control | 21, 22 | disable VDU / select mode |
| 6 | enable VDU driver | 23,0 | control 6845 directly |
| 7 | BELL | 23,1 | turn cursor off |
| 8-11 | cursor moves | 23,7 | direct window scroll |
| 12, 13 | clear screen / CR | 23,8 | clear text block |
| 23,16 | cursor movement control | 23,28-31 | user PLOT calls |
| 27 | null | 30, 31 | home / tab cursor |
| 127 | backspace + 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
&FE20selects 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.