Liber VII · Capitulum III

The modes

Four ways to paint 128 pixels with a chip that has no video memory.

The problem

The original's room is 256 × 160 pixels. On the 2600 that is equivalent to 128 × 160, but the TIA has no video memory: it draws with two 8-pixel players (up to three copies each), two missiles, the ball and a playfield of pixels 4 wide. The classic 48-pixel trick (the two players with three copies side by side and VDEL, to preload data) is the maximum without flicker. Beyond that you have to reposition the players with RESP in mid-line, and each RESP cancels the pending copies. The way out is interlacing: each field paints half.

The four modes in the menu share everything else: the ARM always composes the whole room and each mode only decides which part is shown and how. The captures in this chapter were taken in Stella with the debug colours, which paint each TIA object a different colour, on two consecutive fields.

STRIP: 48 pixels, no flicker

The two players at x = 56 and 64 with NUSIZ = 3 (three copies side by side) and VDEL: six consecutive bytes, 48 pixels at 60 Hz. Each line writes GRP0, GRP1, GRP0, loads A, X and Y with the next three bytes and dumps them with four 3-cycle writes. The window follows William and shows 37 % of the width of the room. It does not need bus stuffing.

STRIP in Stella with debug colours, fields 0 and 1
STRIP. The 48-pixel window: three copies of player 0 interleaved with three of player 1. Both fields are identical.
Stella debug colours: player 0, missile 0, player 1, missile 1, playfield, ball and background. Field 0 on the left and field 1 on the right.

STRIP+: the window and the rest in playfield

The same window, plus the rest of the room hinted at in an asymmetric playfield in a blue slightly lighter than the paper: the same hue with 4 more points of luminance, just enough for the drawing to stand out without competing with the window. Each playfield pixel summarises four of the room (it lights up if at least two of them are on), and it switches off under the window. So that the change from playfield to window is clean, the window moves in steps of 4 pixels: that way both of its edges coincide with those of a playfield pixel, and none is left half playfield and half sprite. That is 14 writes per line plus the jmp: the six of PF0, PF1 and PF2 for each half, those of the window and the sound sample. With bus stuffing, no flicker.

STRIP+ in Stella with debug colours, fields 0 and 1
STRIP+. The 48-pixel window over the room in playfield (purple in the debug view).
Stella debug colours: player 0, missile 0, player 1, missile 1, playfield, ball and background. Field 0 on the left and field 1 on the right.

DOUBLE: 96 pixels in a checkerboard

The players at x = 32 and 48 with NUSIZ = 6 (three copies 32 pixels apart) and no VDEL. Each line paints six 8-pixel blocks with 8-pixel gaps. There are two kinds of line: on A lines, an HMOVE on cycle 3 moves the players 8 pixels to the right and another on cycle 73 brings them back; B lines stay where they are. The lines go A, B, A, B and on the next frame B, A, B, A, so each block appears on one line in two and changes line on every frame, like the squares of a checkerboard. PF0 in black covers the "comb" the HMOVE leaves on the left. Seven graphics writes per line, without bus stuffing.

DOUBLE in Stella with debug colours, fields 0 and 1
DOUBLE. On each line, six blocks; on the next, the other six, 8 pixels further on. In the other field, the other way round.
Stella debug colours: player 0, missile 0, player 1, missile 1, playfield, ball and background. Field 0 on the left and field 1 on the right.

FULL: the whole room in a checkerboard

The same checkerboard, at 128 pixels. The room, at x = 16 to 143, is 16 blocks of 8 pixels, and each line paints 8 of them with the two players alone: A lines, blocks 1, 3, 5, 7, 9, 10, 13 and 14; B lines, the rest. Player 0 is repositioned with RESP0 on cycle 76 of every line and twice mid-line; player 1 only moves back and forth with the HMOVEs, 8 pixels to the right with the one at the start of each A line and 8 to the left with a late one on its cycle 73. As in DOUBLE, the lines go A, B, A, B and on the next frame the other way round: each pixel appears one frame in two and the eye blends both. The blocks are whole bytes of the room, so there are no seams and neither the missiles nor the ball are needed. The black borders (x = 0 to 15 and 144 to 159) are mirrored PF0.

The writes of each pair of lines, each on its cycle (the graphics, the RESP0s, the HMOVEs, the sound sample, the jump and, in the scoreboard, its colour and playfield changes), are solved by a tool outside the ROM, and the ROM carries them in a table: on the ARM they took seconds. It costs about 43 MIPS in Stella, against 39 for the other modes.

The idea for 128-pixel-wide graphics comes from the bus stuffing demos that Darrell Spice Jr. (SpiceWare) shared on AtariAge.

FULL in Stella with debug colours, fields 0 and 1
FULL. Eight blocks per line, from players 0 (red) and 1 (yellow); on the next line, the other eight. In the other field, the other way round.
Stella debug colours: player 0, missile 0, player 1, missile 1, playfield, ball and background. Field 0 on the left and field 1 on the right.