Andrew Braybrook worked hard on the scrolling in his C64 games and did not expect anyone to thank him for it. “If you do something really well people don’t notice it — like the smooth scroll,” he told ZZAP!64 in March 1986. “I spent a lot of time getting that really smooth, but so what?” Looking back on Uridium (1986), his partner Steve Turner told Edge that Braybrook “wanted to achieve full framerate scrolling like arcade machines”, and it was the thing that made the Commodore 64 stand out, “as, with no graphics chips, the Spectrum was clearly inferior”.
Scrolling is how a game shows a world bigger than the screen: the picture slides, new scenery comes in at one edge and old scenery leaves by the other. Machines with scrolling hardware do it in two parts. A fine scroll moves the picture by a few pixels, less than one character or tile, and a coarse scroll moves it by whole characters or tiles when the fine scroll runs out. How much the coarse step costs depends on the hardware, and it decided which machines could scroll smoothly at full speed.
Fine and coarse
The fine part is cheap wherever the video chip has a scroll register: the chip starts drawing a few pixels later, and the program changes one number. The coarse part is where machines differ.
- If the video chip can be told to start reading the picture from a different address, or already has a map bigger than the screen, a coarse scroll is also one number. The program then only has to draw the strip of new scenery about to come into view. The Amiga and the consoles work this way.
- If the video chip always reads the screen from the same place, the program has to move the screen data itself. The C64 has fine-scroll registers but no way of offsetting the screen, so every eight pixels it copies the whole character screen along by one character.
- If there is no scroll register at all, the program moves every pixel. That is the ZX Spectrum.
In every case the new edge has to be drawn somewhere the player cannot see it yet, so machines with scrolling hardware also have a way of hiding the edge of the picture.
Commodore 64: registers for the pixels, the processor for the rest
The C64’s VIC-II can place the screen in any of eight horizontal and eight vertical positions, set by bits 0–2 of $D016 (53270) for X and of $D011 (53265) for Y. Commodore’s Programmer’s Reference Guide is plain about what it does not do: “the actual scrolling must be done by a machine language program”. Its recipe is:
- Shrink the screen to 38 columns (clear bit 3 of
$D016) or 24 rows (clear bit 3 of$D011). The border widens to cover a column or row that the program can fill without it being seen. - Set the scroll register to one end of its range.
- Put the new data in the covered column or row.
- Step the register one pixel at a time to the other end.
- Shift the whole screen one character in the direction of the scroll, and go back to step 2.
Step 5 is the expensive one. Lasse Öörni, who wrote C64 games as Cadaver, put the cost of “shifting 1000 bytes (the whole screen)” at “more than half of the rastertime of a frame”, and the 1000 bytes of colour memory often need moving as well. Games spread the copy over two or more frames. Doing that on the visible screen would show the half-moved picture, so they build the shifted copy in a second screen and switch the VIC-II over to it when it is ready: double buffering. Colour memory cannot be double-buffered, because it never moves from $D800 (see screen memory), so it has to be shifted while the beam is not drawing the part being changed.
Splitting the copy over frames limits how the scroll can move. Öörni noticed that Turrican and Navy Seals “only scroll one char-length at a time, never less”, and suggested they were probably parking the scroll register in the middle of a character when idle, at 3 or 4, so that there is always time to finish the copy before the register runs out of range. At two pixels a frame, the register steps 4, 2, 0, 6, 4, with the copy done in the first two frames and the screens swapped at the third.
Some games avoided copying altogether. Achim’s Codebase64 article on “map dumps” names Uridium, Paradroid and Ghosts’n Goblins as games that decode the whole level map into memory, one row of up to 256 characters per 256-byte page, and draw the visible window straight from it each time the screen moves a character. It costs a lot of memory; it saves working out what each new strip should contain.
Demo coders found ways to move the C64’s screen without copying anything. Christian Bauer’s description of the VIC-II explains how starting a badline partway through a raster line, called DMA delay or VSP, shifts “the complete screen sideways by large distances”, and how combined with FLD and linecrunch it can scroll whole graphics screens “without using much computing time”. Öörni left these tricks out of his guide to game scrolling because “they’re usually too limiting for games, at least for scrolling in all directions”.
ZX Spectrum: every byte by hand
The Spectrum has no scroll register. Its picture is 6,144 bytes of bitmap starting at 16384, followed by 768 bytes of colour attributes, one for each 8×8 character square. The bitmap is not stored in screen order: the manual explains that the rows of pixels are interleaved in three blocks of eight character lines, so that “first come the top scans of lines 0 to 7, then the next scans of lines 0 to 7, and so on”. Moving the picture means moving those bytes with the Z80, which runs 69,888 T-states (clock cycles) in each 50th-of-a-second frame.
The numbers are unforgiving. The Z80’s block copy, LDIR, takes 21 T-states for every byte it moves, so copying the bitmap once takes about 129,000 T-states, nearly two frames. A pixel scroll is slower still. John Hardman and Andrew Hewson’s 40 Best Machine Code Routines for the ZX Spectrum (1982) gives a 17-byte routine that shifts the whole display one pixel to the left:
ld hl,22527 ; last byte of the bitmap
ld c,192 ; 192 rows of pixels
nextln ld b,32 ; 32 bytes in each row
or a ; clear the carry flag
nextby rl (hl) ; shift one byte left; the carry takes its
; left-hand pixel into the next byte
dec hl
djnz nextby
dec c
jr nz,nextln
retIt works despite the interleaving, because each run of 32 bytes is one complete row of pixels, whatever order the rows come in. Working from the right-hand end of each row, RL (HL) shifts a byte one bit left, pushes its leftmost pixel into the carry flag and takes the pixel carried out of the byte to its right. At 34 T-states a byte, the whole screen takes about 213,000 T-states, just over three frames, and the book warns that “eight calls are required to move the display by one full character”. That is before the ULA, the chip that draws the picture, holds the processor back whenever it reaches into the 16K of RAM that holds the screen while the picture is being drawn.
So Spectrum games that scrolled had to spend their time carefully: a smaller playing area, bigger steps, or code unrolled and tuned for one job. Colour made it harder, because attributes cover whole 8×8 squares and cannot follow a pixel scroll. Cobra (1986) managed scrolling that CRASH found “very smooth and fast”. When Sinclair User previewed the Spectrum R-Type in 1988, it reported that the game could “boast full-colour scrolling graphics” and that, though the method was “completely top secret”, “some extremely clever attribute handling is the secret”. Plenty of games did not scroll at all. Raffaele Cecco’s Cybernoid (1988), for example, is played one fixed screen at a time; CRASH called it “flick-screen”.
Amiga: move the pointers
The Amiga’s display is a set of bitplanes that the chipset reads from memory through a pointer for each plane. Commodore’s Amiga Hardware Reference Manual explains that for vertical scrolling “all you need do” is change those pointers by the length of one line each time the picture moves a line. No data is copied at all.
Horizontal scrolling takes a little more setting up. The chipset fetches pixels 16 at a time, a word per plane, so the program fetches one word more than the visible width on each line, starting the fetch 16 pixels early (data-fetch start $30 instead of $38, which the manual notes disables sprite 7), and reduces the modulo, the number of bytes skipped at the end of each line, by two. It then sets the delay in BPLCON1, 0 to 15 pixels, and moves the pointers on by a word for each 16 pixels. The two playfields of dual-playfield mode have separate delays, in bits 0–3 and 4–7 of BPLCON1, so they can scroll at different speeds. The manual adds that the pointer changes “can be handled by the Copper during the vertical blanking interval”: the Copper, the display co-processor, rewrites the registers on its own while the program gets on with the game. Parallax scrolling describes what Shadow of the Beast built on this.
Consoles: maps bigger than the screen
The consoles store the background as a map of tile numbers larger than the visible screen, and the scroll registers choose where the window sits in the map. The program writes a row or column of new tiles into the part of the map just out of view, and the hardware does the rest.
- NES: the PPU addresses four nametables of 32×30 tiles, arranged as a 2×2 block, but the console has video memory for only two. The cartridge’s wiring decides whether the two real ones sit side by side, for games that scroll sideways such as Super Mario Bros., or one above the other. The scroll is written to
$2005, X then Y, and bits 0–1 of$2000choose the starting nametable. The PPU has a single background, so a still status bar needs a scroll change partway down the screen. Super Mario Bros. times it with the sprite 0 hit flag. Nintendo’s MMC3 mapper added an interval timer clocked once per line that interrupts the processor at a chosen line. - Master System: one background with X and Y scroll registers (
$08and$09). Control bits can hold the top two rows still during horizontal scrolling, or the right-hand eight columns during vertical scrolling, for a status display, and can blank the leftmost column to hide new tiles as they scroll in. - Mega Drive: Sega’s Genesis Software Manual describes two scroll planes, A and B, which “separately can scroll vertically and horizontally on a basis of a one-dot unit”. Horizontal scroll can be set for the whole screen, for each 8-line cell or for each line; vertical scroll for the whole screen or for each two-cell column. A fixed window can replace part of plane A for a status panel.
- Super Nintendo: up to four backgrounds, each with its own horizontal and vertical offset registers (BG1HOFS, BG1VOFS and so on). Only mode 0 has all four, at four colours each; mode 1, the most commonly used, has two 16-colour layers and one 4-colour layer.
- Game Boy: Nintendo’s programming manual gives the background scroll as two registers, SCY at
$FF42and SCX at$FF43.
See also
- Hardware Scroll
- Software Scroll
- Parallax Scrolling
- Multidirectional Scrolling
- Double Buffering
- Tile Maps
- Raster Interrupts
- VSP
Sources
- ZZAP!64 issue 11, March 1986, pp. 55–56: interview with Andrew Braybrook (“If you do something really well people don’t notice it — like the smooth scroll”).
- “The making of… Uridium”, Edge issue 124, June 2003, pp. 109–111: Steve Turner on “full framerate scrolling like arcade machines”.
- Commodore, Commodore 64 Programmer’s Reference Guide (1983), pp. 128–129: smooth scrolling, the scroll bits of
$D016and$D011, and the 38-column and 24-row modes. - Lasse Öörni (Cadaver), “Multidirectional scrolling and the ‘game world’”, Codebase64 (web, secondary): the cost of shifting the screen, double buffering, colour memory, Turrican and Navy Seals, and VIC-II tricks.
- Achim, “Freedirectional scrolling using map dumps”, Codebase64 (web, secondary): games using decoded maps.
- Christian Bauer, The MOS 6567/6569 video controller (VIC-II) and its application in the Commodore 64 (1996), section 3.14.6, “DMA delay”.
- Steven Vickers, Sinclair ZX Spectrum BASIC Programming (Sinclair Research, 2nd edn 1983), chapter 24, p. 164: the display file and attributes.
- Chris Smith, The ZX Spectrum ULA: How to Design a Microcomputer (ZX Design and Media, 2010): 69,888 T-states per frame (p. 225); the ULA holding the Z80’s clock during screen fetches (p. 190).
- Zilog, Z80 CPU User Manual (UM008011-0816): T-states for
LDIR(21 per byte, 16 for the last),RL (HL)(15),DEC HL(6) andDJNZ(13). - John Hardman and Andrew Hewson, 40 Best Machine Code Routines for the ZX Spectrum (Hewson Consultants, 1982), section 5, “Scroll Routines”, pp. 39–54: “Left Scroll by One Pixel”.
- CRASH issue 35, December 1986, p. 141: Cobra review.
- Sinclair User issue 79, October 1988, pp. 86–87: the Spectrum R-Type.
- CRASH issue 51, April 1988, p. 13: Cybernoid review.
- Commodore-Amiga, Amiga Hardware Reference Manual (1985), “Moving (Scrolling) Playfields”, pp. 75–80.
- NESdev Wiki, “PPU scrolling”, “Mirroring” and “PPU OAM” (web, secondary): nametables, the scroll registers and the sprite 0 hit.
- Nintendo, MMC3 Specification, third edition (24 May 1988): the interval timer clocked once per line.
- SMS Power!, “VDP registers” (web, secondary): the Master System’s scroll registers, scroll locks and left-column blanking.
- Sega, Genesis Software Manual (1989–1992), “Scrolling Screen”, pp. 35–42, and the window (p. 46).
- SNESdev Wiki, “PPU registers” and “Backgrounds” (web, secondary): BG offset registers and background modes.
- Nintendo, Game Boy Programming Manual, version 1.1 (1999): the SCY and SCX registers.