6845 CRTC

Motorola 6845-family Cathode-Ray-Tube Controller. Drives the raster scan: produces hsync/vsync, fetches video data addresses, drives the cursor signal, and reads the light-pen latch. The other half of the video pipeline is the video-ula, which receives video data and serialises it into RGB.

Not present on the Electron — Electron uses a single combined ULA that subsumes both jobs.

Programming interface

SheilaDirectionPurpose
&FE00writeAddress register — selects which internal register (5 bits) the next &FE01 access targets
&FE01dependsData — read/write the selected register (most are write-only)

Preferred access pattern: use VDU 23,0,R,V,0,0,0,0,0,0 which is Tube-safe. Direct &FE00/&FE01 writes are faster but bypass the OS — fine on the I/O processor, fails over Tube. See naug-ch13-video §13.3.3.

Register map (18 registers, R0-R17)

RegWidthAccessFunction
R08WHorizontal total (chars-per-line-1)
R18WHorizontal displayed (chars per line)
R28WHorizontal sync position
R38WSync widths (bits 0-3: hsync width in chars; bits 4-7: vsync width in scan lines)
R47WVertical total (char rows - 1)
R55WVertical total adjust (extra scan lines)
R67WVertical displayed (displayed char rows)
R77WVertical sync position
R86WInterlace + display/cursor delays (see below)
R95WScan lines per character − 1 (− 2 in Interlace Sync & Video mode — MODE 7 only)
R107WCursor start scan line + blink/enable bits
R115WCursor end scan line
R12,R1314WScreen start address (DIV 8 for modes 0-6)
R14,R1514R/WCursor position
R16,R1714RLight pen position (latched on LPSTB pulse)

Per-mode register values (NAUG §13.3.3 p196; cross-checked against master-arm Ch 6)

RegMode 01234567
R0 Horizontal total12712712712763636363
R1 Characters per line8080808040404040
R2 Horizontal sync pos9898989849494951
R3 Sync widths&28&28&28&28&24&24&24&24
R4 Vertical total3838383038383030
R5 Vertical total adjust00020022
R6 Vertical displayed3232322532322525
R7 Vertical sync pos3434342734342727
R8 Interlace mode11111113
R8 Display delay (bits 4-5)00000001
R8 Cursor delay (bits 6-7)00000002
R9 Scan lines per char-1777977918
R10 Cursor start777777718
R11 Cursor end888988919

R8 hex values shown reflect bits 0-1 (interlace), 4-5 (display delay), 6-7 (cursor delay) combined.

R8 — Interlace + delays

BitsField
0-1Interlace mode: 00/10=non-interlaced, 01=interlace sync, 11=interlace sync+video (MODE 7 only)
4-5Display blanking delay: 00 none / 01 one char / 10 two chars / 11 disable video. MODE 7 needs 01 for saa5050
6-7Cursor blanking delay: same encoding; MODE 7 uses 10

Practical screen blank/unblank (used by raster splits and smooth-vertical-scroll): write &F0 to R8 to blank (display skew = 11 = non-display), &C0 to unblank with cursor off (display skew = 00, cursor skew = 11). The chip’s own DISPTMG gate is toggled, giving a clean transition with no mid-byte serialiser artefact. Mid-frame R8 skew rewrites are safe on the HD6845S despite the datasheet’s blanket “R8 prohibited” verdict — see crtc-6845-advanced.

BitsField
0-4Cursor start scan line (CSL)
6B — blink enable
5P — blink period (or steady on/off when B=0)

BP encoding (per Hitachi HD6845S datasheet Table 7 — hd6845sp-hitachi-datasheet):

BPEffect
00Cursor steady on (non-blink)
01Cursor off (non-display)
10Blink with 16-field period (~3 Hz at 50 Hz — faster of the two)
11Blink with 32-field period (~1.5 Hz — slower of the two)

MOS default: BP = 10 (B-bit set, P-bit clear) → R10 = &47 in graphics modes (CSL=7), &52 in MODE 7 (CSL=18). This produces the BBC’s visible flashing underline cursor at ~3 Hz. The COPY (screen-edit) cursor uses BP = 11 for the slower blink.

⚠️ Contradicts BeebWiki’s CRTC page which describes the encoding as off/steady/slow/fast in a different order. Empirics (default flashing cursor) match the Hitachi datasheet, which is the primary source. See hd6845sp-hitachi-datasheet contradiction section.

Screen start (R12, R13) — the scrolling lever

R12 holds bits 8-13, R13 holds bits 0-7 of screen_address / 8. The divisor of 8 is because the address is in character-cell units of 8 scan lines.

Writing this register pair is the basis of all hardware scrolling — see hardware-scrolling.

Note: R12, R13 are write-only. To read the current screen start, use OSBYTE &A0 with X=&50 (returns &350/&351 from the OS workspace), not the chip.

MODE 7 — XOR &54 quirk

In MODE 7 the address translator interprets MA differently (Teletext path, with MA11=1, MA12=0 flagging Teletext addressing — see address-translation). To produce the right MA for screen RAM at &3C00-&3FFF or &7C00-&7FFF, MOS XORs the desired address with &54 before writing R12/R13. The address-translation page documents the full MODE 7 formula phys = ((MA & 0x800) << 3) | 0x3C00 | (MA & 0x3FF).

Practical conversion (for direct R12/R13 writes in MODE 7):

R12 = (high_byte_of_addr - &74) EOR &20
R13 =  low_byte_of_addr

Same correction must be applied to R14/R15 (cursor position) in MODE 7. See hardware-scrolling.

Hardware wrap-around

When the 6845 fetches a video address ≥ &8000 (i.e. into ROM space), dedicated hardware subtracts a mode-dependent amount to bring the address back into screen RAM. The subtract amount is chosen by 2 bits on the System VIA addressable latch (IC 32) — see address-translation for the full mechanism (subtract amounts: &4000/&2000/&5000/&2800 for MODES 3/6/0-2/4-5) and system-via for the latch.

Chip variant — HD6845S required

The BBC uses the Hitachi HD68B45S specifically (2 MHz bus, 3.7 MHz CRT). Per hd6845sp-hitachi-datasheet the S variant adds six features over the R variant; the BBC exercises three of them critically:

  1. Programmable vertical sync pulse width (R3 high nibble) — HD6845R is fixed at 16 raster periods; HD6845S supports 1-16. BBC MOS uses VSW=2.
  2. Odd vertical character counts — HD6845R counts vertical chars in 2-line units (even-only); HD6845S counts in 1-line units. Required for R6 = 25 (MODES 3/6/7).
  3. SKEW function in R8 (bits 4-7) — DISPTMG and CUDISP delay bits. Absent on HD6845R. Required for MODE 7 to align with the SAA 5050 character generator’s pipeline.

Plus three additional differences (less critical for BBC but worth knowing):

  1. R12/R13 readable on S (write-only on R).
  2. Cursor in Interlace Sync & Video mode: R shows in both fields; S shows in either even or odd field only.
  3. Reset signal: S releases MA/RA outputs asynchronously when /RES asserts; R waits for CLK low.

Programming restrictions

From the Hitachi datasheet — violations produce undefined behaviour, not errors:

  • 0 < Nhd < Nht + 1 ≤ 256 (horizontal displayed < horizontal total)
  • 0 < Nvd < Nvt + 1 ≤ 128 (vertical displayed < vertical total)
  • 0 ≤ Nhsp ≤ Nht (hsync position within line)
  • 0 ≤ Nvsp ≤ Nvt (vsync position within frame)
  • 0 ≤ Ncstart ≤ Ncend ≤ Nr (cursor start ≤ end ≤ max raster) — except in Interlace Sync & Video mode where Ncend ≤ Nr + 1
  • 2 ≤ Nr ≤ 30 (Interlace Sync & Video only — MODE 7’s R9=18 fits)
  • 3 ≤ Nht minimum (5 in non-interlace mode)
  • In interlace modes, R0 must be even (Nht odd, so R0 = Nht − 1 is even). MODE 7 (R8=3) has R0 = 63 — non-even — ⚠️ technically outside spec; works because HD6845S is forgiving.
  • R3 HSW low nibble = 0 is prohibited (undefined). VSW = 0 means 16 raster periods (special-case wraparound).

Light pen (R16, R17)

Latched on rising edge of LPSTB (pin from the analogue port). 14-bit value = address-at-time-of-strobe (in character units). Software must subtract a mode-dependent correction factor (§13.3.9 p197-198) — given for each mode:

ModeCorrection
0, 1, 2&0606
3&0806
4, 5&0B04
6&0C04
7&2808

Then y = (R16R17 - correction) DIV chars_per_line, x = (R16R17 - correction) MOD chars_per_line, scaled by displayed-vs-6845-chars ratio.

Worked light-pen IRQ handler is given on §13.3.9 p199 — hooked via IRQ2V at &206/&207, with the System VIA Interrupt Flag at &FE4D masked with &88 (light-pen bit + master IRQ bit).

Register latching (and which registers tolerate mid-frame writes)

The 6845 does not uniformly latch registers at frame boundaries — different registers behave differently when rewritten during display. Per the Hitachi datasheet’s “Anomalous Operations” table:

  • R12/R13 (start address) are sampled during the last raster period of the field. Rewrites outside that window are safe. Writes during the last raster period give a “split start address” for one frame.
  • R8 (interlace + skew) dynamic rewrite is prohibited by the datasheet — scan-mode bits and skew bits cannot be changed safely during display. Schedule R8 changes during reset or full reprogramming.
  • R0, R2, R7, R9 rewrites during display WILL disturb the picture (NG per datasheet).
  • R1, R6 rewrites are safe.
  • R3, R4, R5, R10, R11 are conditional (safe in most of the line/raster; specific phase windows cause artefacts).
  • R14/R15 (cursor position) should be rewritten during retrace; mid-display writes cause one frame of temporary glitch.

Full table on crtc-6845-advanced. The takeaway for raster-tight code: R12/R13 is the only major timing register you can freely rewrite mid-frame — fortunately the most useful one for hardware scrolling.

NAUG §13.3.12 p203 attributes flicker in BASIC hardware-scroll examples to mid-frame writes; the underlying mechanism is the two-write R12-then-R13 protocol straddling the last-raster sample window. If the sample happens between your two writes, the chip uses (new R12, old R13) for one frame.

Reset behaviour

/RES (active-low) clears all internal counters and forces all outputs low. Control registers are NOT affected by reset.

Quirks of the HD6845S reset:

  • /RES only works while LPSTB is at logic-low. (BBC ties LPSTB to the analogue-port light-pen line — normally low.)
  • HD6845S starts display immediately after /RES release.
  • First field after reset is anomalous: DISPTMG and CUDISP are not output (display inhibited), and the Start Address Register is ignored — MA and RA start at 0. From the second field onward, R12/R13 take effect.

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.