Retrochallenge 2018/04 (Now in COLOR)
Refraction for the Atari 2600

Episode 1: Preliminary Considerations

Before we begin to specify our game, we may want to have a closer look at the platform we are targeting, what it can do and what it can't. The Atari VCS is capable of some impressing feats, like producing a palette of 128 colors, when 8 of them where considered a luxury on expensive systems, or running a 6502-family microprocessor at about 1.2 MHz, when 1 MHz was the top of the range for “serious” computers, but it's also an example of severe limitations. The whole point of having platform studies may be for the sake of better understanding Atari VCS games. So we may want to include these specifica into our considerations, right from the beginning, much like Pitfall, probably the most famous game on the Atari 2600, has been famously sketched out on a sheet of paper, condsidering, what can be done on the system. However, Pitfall still took one and a half years to complete, so we may want to pick something less fancy for a game which we expect to be done in a month.

The Atari Video Computer System (VCS)

We had already a cursory look at the Atari VCS last year, when we investigated the workings of pure-TTL, signal generator type arcade video games and Computer Space in particular. I highly recommend to have a look at this for some background on how video signals are generated and how first generation arcade video related to the VCS. Because, generating games like Pong and Tank is what the Atari VCS is all about, anything exceeding these capabilities was considered a bonus. However, we're having a closer look at the VCS here again, but this time in exclusiveness.

September 11, 1977 saw the realease of the Atari Video Computer System™, better known by the acronym VCS, later renamed Atari 2600 (following to the introduction of the Atari 5200 in late 1982). Developed under the code name “Stella” by Atari's external R&D division Cyan Engineering in the Northern California Sierra Nevada foothills, Grass Valley, the VCS was Atari's master plan to make video games a common home appliance. In fact, Atari gambled its very existence on the success of the system with Nolan Bushnell having to sell Atari out to Warner Communications in order to finance the project. As we'll see, the system was all about cost reduction, in order to undercut the competition in price, namely Fairchild's Video Entertainment System™ (or VES, renamed Channel F in a reaction to Atari's quite similarly named product), a cartridge based video game system released in 1976. However, the VCS wasn't a roaring success right from the beginning: 250.000 units sold at a price of just below $200 in 1977 and only 550.000 of a production run of 800.000 were sold in 1978, as the video arcade industry had lost some of its novelty. The following year, 1979, brought a turn around by the even more cost reduced Model A, now produced in Hong Kong, and Taito's Space Invaders, which revitalized the languishing arcade industry. The VCS became the favorite Christmas gift of the year with sales accounting to a million units and, when Space Invaders became a licensed title on the VCS early next year, sales doubled to even 2 millions. (We may note that this sucess came not without irony, since a game like Space Invaders is already out of the specs of the VCS, which was beginning to show its age, right at its heyday.)
The rest is history, with a slice of wood grain: By 1982 the Atari VCS/2600 had sold about 10 million units, before the industry plunged into the Great North American Video Game Crisis (AKA Video Game Crash).

Atari 2600A

The Atari Video Computer System™ or short VCS, also known as the Atari 2600.
Here the four-switch "wood veneer" version as produced between 1980 and 1982.
(Image: joho345 / Wikimedia, public domain; edited N.L.)

As mentioned above, the VCS was all about generating first generation video games, like Pong, Tank, or Gotcha.* Simple two-player games, where two human opponents could encounter each other in and through the virtual realms of a raster-scan CRT screen, without any physical contact, in a refined match previously available only to accomplished players of racket sports, but now brought to the masses in a pure environment, where players could match regardless of age, state of intoxination, or bodily fitness. (We may contemplate the cultural relapse into physical barbarism which had been introduced by later fighting games and “beat'm'ups.”) Typically, there were two simple representations of the players, a single ball, or a single projectile for each of the two players, and a simple, mostly symmetrical background to represent the playfield. The VCS had all on board required to generate a game of this kind, as in the so-called player-missile graphics.

*) Note: While admittedly not one of the best games ever, Gotcha may be one of the most underrated games in gaming history, since it was the first game to be staged in an all-virtual environment, without any similarities to real-life objects. However, it wasn't much of a success, as the general public seemed to prefer games which could be related to in terms of real world knowledge. As a consequence, there was never an official release of Gotcha for the VCS and the arcade game is best remembered for its unique, breast-like controllers (as in “the boob game”).

Hardware

The Atari VCS / 2600 is rather simplistic in terms of hardware: It consists of merely 3 integrated chips, namely the Television Interface Adapter (TIA) for producing video and sound signals, a MOS Technology 6507 MPU, and a 6532 PIA (in Atari terms the RAM-I/O-Timer chip or short RIOT). Also, there are 7 user operable switches and 2 control ports, but only the power switch and the TV channel selector are defined by hardware, leaving the rest to the software to cope with (hence, the naming of these switches is rather convention than anything else.) The output signal produced by the TIA is composite video and two channels of mono sound, transformed by an RF modulator ready to be plugged into a TV set.

Atari 2600 hardware annotated

Atari VCS / 2600 hardware (four-switcher).
Image: iFixit — Atari 2600 Teardown (annotations by me, N.L.)

Atari 2600 block diagram

Atari VCS / 2600 block diagram.
(Numbers in parentheses give bus widths in bits.)
Image: N.L. after the TIA-1A Manual (Jay Miner, 1976)
and the “Reconstructed” Stella Programmer's Guide.

The Television Interface Adaptor (TIA)

The Television Interface Adaptor, commonly known by its acronym TIA, is the heart of the VCS: A custom designed chip incorporating all the principal workings of an early video game in an integrated 40-pin DIP package. But it comes with an handicapt, as there's no notion of a 2-dimensional screen image. That's right, the TIA is a serial offender, just repeatedly clocking out a scan line according to the settings in its registers. Anything related to the vertical dimension of the picture has to be controlled and set up properly in time by software. As for the hardware, there's only a single dimension, namely time, translating to intensifications of pixels as the video signal progresses along the scan line.

The TIA is clocked at 3.58MHz, thus dividing a TV scan line into 228 clock counts. A scan line starts with 68 clock counts of the horizontal blank interval (HBLANK), leaving 160 clock counts or visible pixels for the rest of the line, which is then terminated by the horizontal sync signal (HSYNC), which starts the next phase of HBLANK. This is also all what the TIA is arranging for. In order to populate the visible portion of a scan line, there are a few entities, which make up the player-missile graphics:

(Object priorities are as follows: player 0 & missile 0, player 1 & missile 1, ball & playfield, background. The stacking order may be changed by a special control bit, putting ball and playfield before the other objects.)

In order to compose these entities into a single line, there are several counters implemented in the TIA, accounting for the position, the strech or replication (by delays) of the various objects. However, the TIA doesn't implement this by normal, digital counters as may be expected, but by more cost effective polynomial counters. These are guaranteed to produce a unique, repeating sequence, but the iterative values are out of sequence. Thus, we can't simply instruct the TIA to display an object A at position X. Rather, we have to reset the appropriate counter by writing to a strobe register, just at the right clock cycle, as the electron beam is swiping ower the particular position in the scan line. — But more on this later.

While all this is controlled by writing to registers, there are also registers for read access, namely collision registers, reporting any overlap of the major objects (15 collision states in total). Moreover, the TIA is also responsible for sound (rather crude sound that is) and providing paddle input data, but we'll cover this later, when we'll need any of this.

The MOS 6507 MPU

The 6507 is your customary 6502 processor, but it has only 13 of the normal 16 address lines connected and no interrupt pins in order to fit into a more cost effective 28-pin DIP package. Otherwise, it's the the same as the 6502, but it can only “see” 8K of address space. (Since the missing pins are those for the most significant address lines, this 8K space is mirrored 8 times over the internal 64K / 16-bit address space.) In programing term, it's common to refer to the 6507 as 6502, because it's essentially the same chip, especially for the instruction set (including the “illegal” opcodes.)

The 6507 is clocked by the TIA at a third of its own clock rate, providing a clock pulse on every third of its own. This results in a clock rate of 1.19MHz for the 6507, which is pretty high as compared to most home computers of the time. However, the electron beam of the CRT progresses over three pixels for every clock cycle of the 6507 — and the minimal cycle count for a simple NOP is two cycles. For a simple store instruction, like "STA $00", 9 pixels are passing under the beam!

The basic means of synchronizing the 6507 with the TIA is by strobing (meaning, writing any value to) the WSYNC (wait for sync) register of the TIA, by this instructing it to supply no further clock pulses to the 6507 until the next scan line is reached. Thus, the 6507 is effectively put to sleep, without any notion of what's going on around it, to be raised again at the start of the next phase of HBLANK.

The RAM-I/O-Timer (RIOT)

A 6532 PIA provides not only timers and ports for reading various console switches and the state of the two joysticks, but also provides a whopping 128 bytes of memory (0.125 K). However, so we're not going to crace out over this lush supply of resources, this is also to be used for the CPU stack of the 6507, growing down from the top of the RAM.

(For the purpose of the stack, the address range $0000-$00FF, which includes the primary image of the RIOT, is also mapped to $0100-$01FF, where RAM is expected by the CPU.)

Address Space

To complete the image, we're just lacking the ROM cartridges, which came in two sizes, 2K and 4K, and map to the top 4K of the 8K address space. (In the later times of the Atari 2600, special cartridges included even larger ROMs, implemented by bank switching operated by read access on special address latches.)

The entire address map of the VCS, as seen from the 6507, looks like this:

$0000 - $007F	128 bytes    TIA registers
$0080 - $00FF	128 bytes    RAM / CPU stack
$0200 - $02FF	256 bytes    RIOT registers
$1000 - $1FFF	4k           ROM

$0100-$01FF map to $0000-$00FF.

Or, if curious what's “living” in the “holes”, here in more detail:

$0000 - $002F                      TIA Primary Image
$0030 - $005F       [shadow]       TIA
$0060 - $007F   [shadow-partial]   TIA
$0080 - $00FF                      RAM Primary Image (zero page image)
$0100 - $002F       [shadow]       TIA
$0130 - $005F       [shadow]       TIA
$0160 - $017F   [shadow-partial]   TIA
$0180 - $01FF       [shadow]       RAM (CPU stack image)
$0200 - $022F       [shadow]       TIA
$0230 - $025F       [shadow]       TIA
$0260 - $027F   [shadow-partial]   TIA
$0280 - $029F                      RIOT registers Primary image
$02A0 - $02BF       [shadow]       RIOT registers
$02C0 - $02DF       [shadow]       RIOT registers
$02D0 - $02FF       [shadow]       RIOT registers
$0300 - $032F       [shadow]       TIA
$0330 - $035F       [shadow]       TIA
$0360 - $037F   [shadow-partial]   TIA
$0380 - $039F       [shadow]       RIOT registers
$03A0 - $03BF       [shadow]       RIOT registers
$03C0 - $03DF       [shadow]       RIOT registers
$03E0 - $03FF       [shadow]       RIOT registers

$0400 - $07FF   Mirror of $0000 - $03FF
$0800 - $0BFF   Mirror of $0000 - $03FF
$0C00 - $0FFF   Mirror of $0000 - $03FF

$1000 - $17FF   Lower 2K Cartridge ROM (4K cartridge)
$1800 - $1FFF   Upper 2K Cartridge ROM (2K cartridge)

-------

$2000 - $3FFF   Mirror of $0000 - $1FFF
$4000 - $5FFF   Mirror of $0000 - $1FFF
$6000 - $7FFF   Mirror of $0000 - $1FFF
$8000 - $9FFF   Mirror of $0000 - $1FFF
$A000 - $BFFF   Mirror of $0000 - $1FFF
$C000 - $DFFF   Mirror of $0000 - $1FFF
$E000 - $FFFF   Mirror of $0000 - $1FFF

It's common usuage to use the highest mirror image for a program to go in ROM (start address $F000) and to use the lowest image for the system addresses. The common programmer's weapon of choice in the Atari homebrew communities is the DASM cross-assembler, comming for all sorts of systems and with header files for the various system addresses of the Atari VCS / 2600. In order to blend in, we'll use this as well.

The go-to source for detailed information on the TIA and RIOT registers is the “Stella Programmer's Guide” by Steve Wright (1979, updated by Darryl May in 1988), availble as scans from the original (PDF), as a “reconstructed,” newly type-set version (PDF) and in HTML.

Composing TV Images

By this, we should have all the provisions required for composing a 2-dimensional TV image. Here, we'll go for NTSC, non-interlaced (we can't do interlaced), 60 frames per second, and provide the data for PAL later.

In NTSC, a field or non-interlaced frame consists of 262 horizontal lines.
These are made up by:

Combining this with what we already know about the horizontal composition of a line (68 TIA cycles of HBLANK and 160 cycles of visible image, followed by HSYNC), we arrive at the following picture (or, rather, diagram):

Atari VCS playfield timing

Atari VCS playfield timing, TIA clock counts and 6507 cycles (at the bottom).
(Image: AtariAge, based on the "Stella Guide" VCS developer documentation.)

Here is the relevant data for implementing both NTSC and PAL (notably, the horizontal timing is the same):

NTSCPAL
scanlinesmicrosecondsscanlinesmicroseconds
VBLANK (including 3 VSYNCs)402.548483.085
KERNEL19212.22822814.656
OVERSCAN301.910362.314
FRAME26216.68631220.055

In order to provide for a proper 2-dimensional image, we have to

Here's a basic playfield routine, implementing just a simple effect, namely iterating the background color per scan line. Since all TIA registers are set to zero at the start of the program, all of the 5 moveable objects are off (the corresponding registers conatining only 0 bits). Color is generally defined as a byte value, where the high-nible (D7-D4) contains the code of any of the 16 base colors and the three higher bits of the low-nible (D3-D1) represent a level of luminance. Therefor we'll have to increment the color value (in X) twice per scan line. Scan lines are counted down in Y, AC contains zero after the VBLANK routine. (The TIA register for the background color is, by the way, commonly known by the name COLUBK, which is also defined as a symbol in the header file for the assembler.)

; a simple playfield
; source for DASM, 6502 instruction set, importing standard headers
    processor 6502
    include vcs.h

; start at $F000
    org $F000

Start ; standard prelimanaries...
    sei  ; disable interrupts (are there any?)
    cld  ; clear BCD mode.

; initialize stack
    ldx  #$FF
    txs

; reset RAM and TIA registers (X is set to $FF, we spare $00, which is VSYNC)
    lda #0
ClearMem 
    sta 0,X
    dex
    bne ClearMem

Frame
; start with a sequence of 3 lines of VSYNC
    lda  #2
    sta  VSYNC  ; write 2 to VSYNC to start VSYNC sequence
    sta  WSYNC  ; off until next line by strobing WSYNC register
    sta  WSYNC  ; second line
    sta  WSYNC  ; third line

; set up a timer to tick out after 37 lines @ 76 cycles = 2812
; we'll use a PIA timer ticking down every 64 cycles
; and there'll be some cycles used for setting it and some inaccuracy
; so we'll set it to a value of 43 (decimal)

    lda #43
    sta TIM64T

; and end vertical sync time
    lda #0
    sta VSYNC  ; write 0 to VSYNC

; business logic
; just set X to zero (used for a bit of effect)
    ldx #0
; not much to do, so wait for the timer to tick down

WaitForTimer
    lda INTIM
    bne WaitForTimer


; setup number of scan-lines for count down in Y
    ldy #191

; and end VBLANK by writing 0 to the VBLANK register at the next line
    sta WSYNC
    sta VBLANK  ; enable image (AC is still 0)

ScanLoop
    sta WSYNC   ; wait for end of previous line
    inx         ; fancy effect: increment X twice
    inx 
    stx COLUBK  ; and store it as the background-color
    dey         ; count down scan-lines...
    bne ScanLoop

OverScan
    ldx #0
    lda #2      ; prepare to set VBLANK
    sta WSYNC   ; wait for end of line
    stx COLUBK  ; reset background to black (AC is still 0)
    sta VBLANK  ; disable the video signal

; now bide some time (30 lines)
    ldy #30
OverScanWait
    sta WSYNC
    dey
    bne OverScanWait

    jmp Frame


; finally, set start and interrupt vectors

    org $FFFC
    .word Start
    .word Start

Saving this as "t1.asm" and starting DASM by

$ dasm t1.asm -f3 -ot1.bin

(the -f3 flag sets the required file format), the Stella emulator provides us all the colors, there are on the VCS, on a single screen:

Atari 2600 sample kernel

Our simple kernel running in Stella.

For a real game, our scan line routine would look a bit differnt: We would have to read and write the appropriate value of the playfield, if it differed from the line, we did before, manage any movable objects, meaning, checking, if they are displayed at the respective scan line, if so, write the appropriate bit-patterns to the respective registers, maybe change colors, otherwise, make sure, the sprites are off (set to zero)…

Pretty much to do, considering there are just 68 TIA cycles of HBLANK, translating to just 22 cycles for the 6507, before the visible part of a scan line starts. This is also, why many games decide for a 2-lines kernel, meaning, the image changes only each second line, resulting in double the vertical pixel size or half the vertical resolution. The TIA even adjusts for this, by providing shadow registers for the player and ball graphics, into which the contents of the respective main registers is shifted. If we decided to go with an interleaved approach, we could refer to these shadow registers by setting a control bit in the respective vertical delay registers (VDELP0, VDELP1, VDELBL) every second line. Hopefully, we can manage without this.

Any business logic, like checking the player ports and console switches and managing the state / progress of the game has to be done while the beam is off, during VBLANK and overscan, maybe we can squeece some of it even into the VSYNC lines. (This is also, why we rather used a timer than counting lines to time VBLANK in our example.) The Stella Programmer's Guide does the math (for NTSC):

In general, the remaining 70 scan lines (3 for VSYNC, 37 for VBLANK, and 30 for overscan) will provides 5,320 machine cycles (70 lines x 76 machine cycles) for housekeeping and game logic. Such activities as calculating the new position of a player, updating the score, and checking for new inputs are typically done during this time.

Horizontal Positioning

We still don't know how to manage horizontal positions. Put simply, we have to tell the TIA, when to reset the respective counters, by strobing registers. Only problem: There are 3 TIA clocks per 6507 cycle and the iteration of a minimal delay loop (like Loop dex — bne Loop) is 5 cycles (dex: 2, bne: 3), resulting in an accuracy of 15 pixels!

However, there are provisions to make up for this: For any of the moveable objects there are also horizontal movement registers for a fine adjustment of up to 15 pixels (-7 … +7). We're expected to determine, how many iterations of a delay loop, we'll have to wait, get the remainder, and use this for the movement registers. Sounds rather horrible, but there are several patterns to accomplish this, by just math, or by using look-up tables or any combinations of these (most prominently the rediscovered Battlezone positioning routine). Having setup all motion registers appropriately, we'll have to strobe the HMOVE register to apply all these offsets at once. (Each time, we strobe this registers, the objects will be repositiones according to these horizontal movement offsets.) We're expected to do this during VBLANK, before the visible part of the kernel starts, and we'll have to spend a scan line on each object, since any positing will have to start with the HSYNC.

If curious, here's the Battlezone subroutine :-)


; Battlezone style exact horizontal repositioning
; subroutine as rediscovered by R. Mundschau and explained by Andrew Davie,
; set A = desired horizontal position, then X to object
; to be positioned (0->4 = P0->BALL)

bzoneRepos
    sta WSYNC                   ; 00     Sync to start of scanline.
    sec                         ; 02     Set the carry flag so no borrow will be applied
                                ;        during the division.
divideby15
    sbc #15                     ; 04     Waste the necessary amount of time dividing X-pos by 15!
    bcs divideby15              ; 06/07  11/16/21/26/31/36/41/46/51/56/61/66

    tay
    lda fineAdjustTable,y       ; 13 -> Consume 5 cycles by guaranteeing we cross a page boundary
    sta HMP0,x

    sta RESP0,x                 ; 21/ 26/31/36/41/46/51/56/61/66/71 - Set the rough position.
    rts

;-----------------------------
; This table converts the "remainder" of the division by 15 (-1 to -15) to the correct
; fine adjustment value. This table is on a page boundary to guarantee the processor
; will cross a page boundary and waste a cycle in order to be at the precise position
; for a RESP0,x write

    org $FE00
fineAdjustBegin

    .byte %01110000 ; Left 7
    .byte %01100000 ; Left 6
    .byte %01010000 ; Left 5
    .byte %01000000 ; Left 4
    .byte %00110000 ; Left 3
    .byte %00100000 ; Left 2
    .byte %00010000 ; Left 1
    .byte %00000000 ; No movement.
    .byte %11110000 ; Right 1
    .byte %11100000 ; Right 2
    .byte %11010000 ; Right 3
    .byte %11000000 ; Right 4
    .byte %10110000 ; Right 5
    .byte %10100000 ; Right 6
    .byte %10010000 ; Right 7

fineAdjustTable EQU fineAdjustBegin - %11110001 ; NOTE: %11110001 = -15

Racing the Beam & Common Tricks

So we do know, how to put something like Pong on the screen. (How may we do scores? Use the background graphics for blocky, 7-segment style numbers!) But how may we accomplish something a bit fancier?

Just in Time

It's good to know that we may change any of the values on the fly. But we have to do it just in time. E.g., if we're using the background graphics to display the score of player 1 on the left side and the score of player 2 on the right side, we have to write the new bit-pattern to the appriopriate byte after it has been used for the left side, but before it has been used on the right side. This accords to almost any registers, including the background-color. — This is, where counting clock cycles and racing the beam begins. However, the resolution of 6507 cycles and timing versus TIA clocks / pixels is just that good.

Timing diagram for switching playfield graphics (TIA registers PFO, PF1, PF2) mid-screen on the VCS.
(Image: Andrew Davie, AtariAge.)

Interlacing

A common trick to exceed the limitation of just two sprites concurrently displayed on the screen is by interlacing them between frames. For 4 sprites, switching sprites between alternating frames at 30Hz, this works good enough on a real CRT, but there may be some flicker visible on an LCD display. Some games take this to the extreme, like the original Atari Pac-Man, infamous for the flickery display of the ghosts.

Horizontal Banding

But we can do more than 2 player sprites without flicker, if we design our game accordingly. Nothing prohibits us from resetting sprite positions while the image scan is in progress, thus reusing sprites in various zones or bands stacked vertically. Save The Whales (1982) gives a good example for this (see below): Various characters populate clearly distincted zones in the game, but never are there more than 2 in a single zone or band, other than replicated copies. However, the trick comes with a price: First, we have to reserve a few screen lines for resetting horizontal positions and we won't have time to change any of the background graphics or color. Second, there's a bug (or feature) in the TIA, causing the TIA to not produce any background graphics for the next 8 pixels, when the HMOVE register is strobed for the fine adjustments. (This is connected to the up to 7 pixels of horizontal offset provided by the movement registers. Reportedly, there had been a design fix for this, but it was never pushed into a new dye design for the TIA.) The result of this is the tell-tale black combing on the left edge of the screen, made up of strips of 8 black pixels, whenever the sprites are repositioned. (Compare the image below.)

Migitation strategies for this combing effect are either to have the first 8 pixels black on every line (e.g., by strobing HMOVE at the start of each line anyway, but with all movement registers set to zero at an ordinary line, where we do not want to change positions), or to mask the left edge by the ball graphics stretched to 8 pixels width, or just having a black background.

Atari 2600 Space Invaders

Save The Whales, 20the Century Fox (1983)
(Image: The Video Game Critic.)

The Multi-Sprite Trick

Some games seem to simply defy the limitations of the Atari console, by displaying 7 sprites and more free of any flicker in a single row. How can this be done? The trick ist to set up a sprite for replication and strobe a register just before the next copy will be displayed, causing the TIA to reset its respective replication counter. (The registers in question are RESP0 for the first player sprite and RESP1 for the second one, which are meant to center the missile on top of the respective player sprite, but also reset the replication counter as a side-effect.) See Galaxian for an example of this (displaying 7 copies of a streched sprite at medium distance on a line):

Atari 2600 Galaxian

Galaxian, Atari (1983).
(Image: AtariAge.)

The 48 Pixel Sprite / 6 Digits Score Trick

Another trick commonly found in VCS games is frequently used to display scores in high resolution, rather than by blocky background graphics. For this, two player sprites are aligned next to each other and then replicated as often as needed (up to 3 times, providing 8 × 2 × 3 = 48 pixels of drawing space.) The trick is now to store the appropriate bit patterns in rapid succession in the respective player sprite registers, as in STA GRP0 — STX GRP1 — STY GRPR0 …. But at this point we run out of registers! And, while storing a byte in zero page takes 3 cycles at least, or 9 pixels, we have no time to spare! How can this be done? How can a game like Pitfall (by David Crane / Activision, 1982) even exist?

Remember the vertical delay registers and the “shadow registers” for the player sprite graphics? We can use these to preload half the graphics and then update the remaining sprite graphics just in time. However, values propagate through the registers in a rather unexpeted way, but there are approved code patterns for this. (See also Episode 10.)

Atari 2600 Pitfall

The famous score graphics of Pitfall (Activision, 1982).
(Image: AtariAge.)

Can you make out the “ingredients”?
The white scores on the top are clearly made using the 48-pixel sprite trick on dark green background color representing the top of the trees. The bottom edge of the trees are made of playfield graphics in dark green, while the background switches to medium green, branches are made of (replicated) player sprites. (Apparently, the stacking order / object priority is changed for this, so that the playfield graphics are masking the branches.) Below, the playfield graphics change to dark brown to represent the tree trunks. The liana (or rope) is made of the ball (mind how it uses the dark green playfield colors for a few pixels on the top and then changes color with the tree trunks.) While made of just a single pixel, it is drawn at an angle by use of the movement registers. Pitfall Harry is clearly a player sprite, changing color over scan lines. The beige path is made by another switch of the background color, while the pit is made of playfield graphics. The rolling logs are player sprites (as are the crocodiles, if any, coming in three copies.) If Harry happens to fall into a pit or pond, he “submerges” simply by not being rendered below a certain scan-line, about just below the middle of the path. Then there are another few horizontal bands of background color, and another band of player sprites for the subterranean path. Finally, the Activision logo is yet another case for the 48-pixel sprite trick. And yes, HMOVE is apparently set on each visible scan line in order to prevent the tell-tale comb of sprite reprositioning from showing (compare the 8-pixel wide strip of black on the left edge of the screen.) — Figuring out VCS games is fun!

*****

Most of these tricks and more can be found here, including code examples: http://www.qotile.net/minidig/tricks.html.

*****

Now, that we have spent more than enough over our preliminary platform studies, it's high time to come to an end with this episode. However, we know what we're going to deal with. We may use some of the tricks listed above, but we're going to keep it simple and rather focus on a fun gameplay, rather than technical accomplishments. Notably, Pitfall took about one and a half years to make — and we have less than a month!

 

 

Next:  Episode 2: Sketching the Game / First Playfield

Back to the index.

— This series is part of Retrochallenge 2018/04. —