Skip to content

Navigation Menu

Sign in
Sign up
DoubleGate edited this page Jul 8, 2026 · 1 revision

TIA (Television Interface Adaptor)

This is Rusty2600's single combined page for both video and audio. Unlike consoles built around a separate video chip and sound chip, the Atari 2600's TIA is one chip that does both — there is no separate audio processor at all, and the RIOT (see RIOT) has no sound hardware whatsoever. Audio synthesis lives in the rusty2600-tia crate, right alongside video. This is a genuine, load-bearing structural difference worth understanding before anything else on this page.

What the TIA is

The TIA has no framebuffer: it renders one pixel of luminance/color per color clock directly from its object registers as the electron beam sweeps, and the CPU program rewrites those registers mid-scanline ("racing the beam") to compose a picture. This is the architectural crux of the whole emulator — see Lockstep-Scheduler for how the scheduler keeps the CPU and the beam in lockstep.

Horizontal timing

  • A scanline is 228 color clocks: 68 HBLANK (not displayed) + 160 visible (1 color clock = 1 pixel).
  • One CPU machine cycle spans 3 color clocks, so a line is 76 CPU cycles (228 / 3).

Vertical timing and the VSYNC/VBLANK protocol

The program itself manually generates vertical sync — there is no hardware vertical-blank interrupt. An NTSC frame is 3 VSYNC + 37 VBLANK + 192 visible + 30 overscan = 262 lines; PAL is 312 lines. Region line budgets are data, driven by the same core, never a build-time fork.

WSYNC: CPU-halt synchronization

Writing WSYNC (02ドル) drives RDY low and halts the CPU until the next HBLANK starts — the color clock keeps running, only the CPU freezes. This is how software locks to the beam: do all per-line register setup, STA WSYNC, and the CPU stalls precisely to line start. See Lockstep-Scheduler for the exact scheduler mechanics, including the line-boundary edge case that was the root cause of a real Frogger timing bug found during development.

Object positioning by write timing (RESPx)

Five movable objects — player 0, player 1, missile 0, missile 1, ball — are each positioned by when the program writes its strobe register (RESP0/RESP1/RESM0/RESM1/RESBL). The horizontal position is set to wherever the beam happens to be at the write, with a real hardware 9-color-clock reset-to-visible pipeline delay. Getting this pipeline and the per-pixel position exactly right is the single most error-prone part of a 2600 emulator.

HMOVE and the "comb" quirk

Each object has a 4-bit signed motion register (HMP0/HMP1/HMM0/HMM1/HMBL, range +7 to −8). Strobing HMOVE (2ドルA) applies the motion by clock-stuffing extra pulses into each object's position counter during HBLANK. An HMOVE strobed at the start of a line extends HBLANK by 8 color clocks, producing the classic "comb" / black-left-edge-bar artifact many games and demos deliberately exploit. Reproducing this exactly is a known accuracy test case, faithfully modeled in Rusty2600.

Playfield, players, missiles, ball

PF0/PF1/PF2 form a 20-bit playfield across the left half of the screen, with CTRLPF controlling reflect, score-color, priority, and ball size. GRP0/GRP1 are 8-bit player graphics with NUSIZ0/NUSIZ1 controlling copy count and size (re-read every graphics clock, so it can change mid-object); VDELP0/VDELP1/VDELBL select between the "new" and "old" graphics register copy — the classic alternating-line sprite trick.

Collisions

15 collision pairs are detected in hardware per pixel and latched, readable through CXM0P/CXM1P/CXP0FB/CXP1FB/CXM0FB/CXM1FB/CXBLPF/CXPPMM, cleared by CXCLR. Rusty2600 re-evaluates per-pixel object overlap on every visible color clock, not just once when an object is first enabled.

Color

COLUP0/COLUP1/COLUPF/COLUBK hold 7-bit hue+luma values. The hue-to-RGB mapping differs by region — the same value is yellowish on NTSC, gray on PAL, aqua on SECAM — so the palette is treated as region data, not code.

Object-ID mask (hd-pack feature)

Behind the off-by-default hd-pack Cargo feature, the TIA records a second, parallel per-pixel output tagging which object (and — for players — the exact GRPx/NUSIZx register state) won color-priority resolution at that dot. This is a read-only tap that doesn't alter normal rendering and compiles out entirely when the feature is off; it's the prerequisite that makes the frontend's HD replacement-art live-rendering splice possible. See Frontend-Architecture.

Audio (lives here, not in the RIOT)

Two fully independent channels, three registers each: AUDC0/AUDC1 (4-bit distortion/waveform select), AUDF0/AUDF1 (5-bit frequency divider), AUDV0/AUDV1 (4-bit volume). The audio clock is the system color clock divided by 114 — approximately 31.4 kHz — except for the four AUDC distortion modes (12–15) that instead derive from the CPU clock. Each channel is a clock divider feeding a polynomial shift register whose tap length is selected by AUDC, producing everything from pure tones to white noise.

See also

Architecture-Overview · Lockstep-Scheduler · RIOT · Frontend-Architecture · Testing-Strategy

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /