Salmon Run

Atari 800 / APX (1982)
by Bill Williams

An experimental Atari 800 game disassembly using Claude Code and Opus 4.5 conducted by Benj Edwards

Salmon Run is a 1982 Atari 800 game where you play as a salmon swimming upstream to spawn. You dodge rocks, waterfalls, and predators like bears and fishermen while controlling your speed and leaping from the water. The game features distinctive water sound effects generated by the POKEY chip that go beyond what seems like it should be possible on this relatively primitive machine.

For more background on the game and its creator, see this Ars Technica article.

Screenshots

Salmon Run Title Screen Salmon Run Gameplay Salmon Run - Swimming Upstream Salmon Run - Rapids

The Sound-Graphics Linkage

After completely disassembling Salmon Run (4,443 lines of 6502 assembly), the disassembly revealed something interesting: you can run the sound code without the graphics, but it's not exactly the same.

How It Works

The Display List Interrupt (DLI) - the code that runs during screen drawing - also handles:

The code path through the DLI varies based on game state, which means the time between sound updates changes dynamically. When you move the fish, the sound texture shifts. When waves splash, the timing changes.

Technical Analysis

POKEY Sound Chip Configuration

RegisterValueDescription
AUDCTL$00Standard 64kHz poly clock
AUDC1$A4Pure tone (distortion $A), volume 4
AUDF1RANDOM & $1FRandom 0-31, updated via DLI
AUDC2$A0Silent (volume 0) during idle

The DLI Code (Excerpt)

; SOUND UPDATE (lines 2615-2622 of disassembly) LDA RANDOM ; Get hardware random number AND #$1F ; Mask to 0-31 STA AUDF1 ; <-- This creates the stream texture! CMP #$0E ; If frequency >= 14... BCS L5026 ; ...skip channel 2 LDA RANDOM AND #$3F STA AUDF2 ; Channel 2 (silent during idle) ; After sound update: 400+ lines of game logic that ; affect timing between the next AUDF1 update! ; CHECK FISH STATE LDA L06A2 ; Fish movement flag BEQ L505C ; If zero, skip fish code JMP L5406 ; DIFFERENT CODE PATH = DIFFERENT TIMING! ; CHECK WAVE/SPLASH LDA L3FF2 ; Wave counter BNE L5066 LDA L3FF3 ; Splash counter BEQ L5069 JMP L5110 ; SPLASH PATH = DIFFERENT TIMING!

Key Findings

  1. Memory Efficiency: No separate sound driver needed
  2. CPU Efficiency: Sound updates happen "for free" during display processing
  3. Organic Feel: Sound subtly varies with gameplay
  4. Possible to imitate but perfect replication requires the original graphics: You can't just "rip" the sound - you'd have to rip the entire game

Downloads