Disclaimer: This project is for educational and archival purposes only. All rights to the original game implementation belong to their respective authors. No copyright infringement is intended.
The accuracy of the disassembly is verified in CI by assembling the annotated source and comparing the output byte-for-byte against the original "golden" binary.
Annotated Intel 8080 disassembly of "Volcano", a rescue helicopter game for the Радио-86РК (Radio-86RK) computer.
-
volcano.asm — annotated source
-
volcano.lst — assembler listing with addresses and symbol table
-
VOLCANO.GAM — the tape binary without the E6 header and trailer
-
tape/VOLCANO.GAM — tape version of the binary with the E6 header and trailer
(C) 1987 BONY
390008 Рязань, Братиславская 27
Радиотехнический институт, СКБ "DESIGN"A volcano is erupting. Four people are stranded on ledges along its slopes. You pilot a helicopter to rescue them — pick each person up, fly them back to the station, and drop them off before the rising lava reaches them.
- Helicopter: 2-line sprite (rotor
-+-and bodyO-+or+-O). Moves in 4 directions via configurable keys (default: cursor codes). CockpitOis the collision point. - Pickup: hover so cockpit
Ois directly above a personI/Y. The person attaches below as a hangingIcharacter. - Drop-off: fly over the station roof
=. The person is deposited inside. - Carry timer: a person can only hang for 0x28 (40) game ticks. In the last 10 ticks, they swing (
J/Lalternating). At zero, they fall and die. - Lava: advances one row every 10 game ticks. Each step fills a row with
+chars. If lava reaches a person's ledge, they die. - Stones/ash: 20 particles (
*) launched from the volcano peak with random trajectories. Parabolic arcs via 16-bit fixed-point physics with gravity. Hitting the helicopter destroys it. - Bullets: pressing fire shoots
-horizontally from the cockpit. Bullets destroy stones (replacing*with+). Bullets also kill people if they hitI/Y. - Souls: when a person dies (lava, falling, bullet), a soul
()appears and drifts around. Souls are partially attracted toward the helicopter (1/3 vertical seek, 1/2 horizontal seek). Touching a soul destroys the helicopter. - Lives: 3 helicopters total. Crash triggers a fast explosion (32-step expanding ring of
.dots). Spare helicopters are visible inside the station. - Scoring: the high score table tracks
saved_people(higher is better) andused_helicopters(lower is better). Top 5 scores are stored in RAM with player names (persisted as long as the game stays loaded).
| Address | Contents |
|---|---|
0x0000-0x1FFF |
ROM monitor (also used as entropy source by PRNG) |
0x0100-0x0FFF |
Game code and data (3840 bytes) |
0x0F00-0x0FFF |
Game variables, high score table, runtime buffers |
0x117F-0x17BF |
Screen buffer (64x25 = 1600 bytes, mirrors video RAM) |
The stack pointer is set to 0x117F (top of screen buffer), growing downward into the variable area.
The RK86 uses an interleaved bank layout for its 64-column x 25-row display. The screen_area_address routine (offset 05A0h) converts (column, row) to a buffer address:
address = screen_area + (col >> 2) * 256 + (col & 3) * 64 + rowTwo RRC instructions rotate the column value to split it into bank (high 6 bits) and offset (low 2 bits shifted to bits 6-7). The game maintains a shadow buffer at 0x117F that mirrors the screen contents, enabling collision detection by reading characters from the buffer.
The helicopter is drawn/erased via null-terminated strings containing VT52 cursor escape codes:
0x19= cursor up0x1A= cursor down0x08= backspace
This allows drawing the 2-line sprite (body row + rotor row) with a single print_str call, without explicit cursor repositioning. Four strings handle the combinations of left/right facing and draw/erase.
Each of the 20 stones is an 8-byte structure with 16-bit fixed-point (8.8) positions and velocities:
| Byte | Field | Description |
|---|---|---|
| 0 | x_vel_lo | X velocity fraction (constant) |
| 1 | x_pos_lo | X position fraction |
| 2 | x_vel_hi | X velocity integer (signed, constant) |
| 3 | x_pos_hi | X position = column (0-63) |
| 4 | y_vel_lo | Y velocity fraction (+1 each frame = gravity) |
| 5 | y_vel_hi | Y velocity integer (starts -1 = upward) |
| 6 | y_pos_lo | Y position fraction |
| 7 | y_pos_hi | Y position = row (0-24) |
Each frame: x_pos += x_vel (constant drift), y_vel += 1 (gravity), y_pos += y_vel (acceleration). This produces parabolic arcs — stones launch upward from the crater peak (columns 37-40, row 8) and curve back down. Stones that leave the screen are re-initialized with new random trajectories.
The random number generator (random, offset 05F7h) uses:
- A 16-bit seed as a pointer into ROM (addresses
0x0000-0x1FFF) to read a byte for entropy - An accumulator that mixes in the ROM byte and the requested range
- Rejection sampling with a narrowing bitmask to produce unbiased results in
[0..max]
The lava_levels table (offset 0D8Fh) has 16 entries of 5 bytes each:
count, row, column, human_row, human_colEach lava step draws count copies of + starting at (row, column). If human_row != 0, the routine checks whether a person is still alive at that position and kills them if so.
The game uses character-based collision. Before moving the helicopter, it checks 3 consecutive bytes in the screen buffer (for the rotor line and body line). If any cell is not a space (0x20), the move is blocked or triggers a crash. Special cases:
=(station roof) — blocks movement, or triggers person deposit if carryingI/Y(person) — triggers pickup if directly below cockpitO(own cockpit, during bullet processing) — skip over
The initial screen layout is RLE-compressed (offset 0D9Fh):
N, char— repeatcharN timesN, 0— end of row (advance to next screen line)0xFF, ...0— literal string until null terminator0— end of data
The title screen displays "VOLCANO" in large pixel-art letters. The data is 7 character bytes (V, O, L, C, A, N, O) followed by a 7x7 bitmap. Each bit in the bitmap selects whether to print the corresponding column's letter or a space:
V.....V. .OOOOO.. L....... .CCCCC.. ......A. N.....N. .OOOOO..
V....V.. O.....O. L....... C.....C. .....AA. NN....N. O.....O.
V...V... O.....O. L....... C....... ....A.A. N.N...N. O.....O.
V..V.... O.....O. L....... C....... ...A..A. N..N..N. O.....O.
V.V..... O.....O. L....... C....... ..A...A. N...N.N. O.....O.
VV...... O.....O. L....... C.....C. .AAAAAA. N....NN. O.....O.
V....... .OOOOO.. LLLLLLL. .CCCCC.. A.....A. N.....N. .OOOOO..just ci # assemble + verify against golden binaryThe assembler is asm8080. The golden binary VOLCANO.GAM is the original game dump. Every assembled output must match it byte-for-byte.
0517: C5 -> C9 ; turn off ashes
082F: 3A -> C9 ; turn off lava
- A JavaScript remake is at html/volcano.js. It uses 8.8 fixed-point stone physics and tick-based timers from the original assembly. Supports keyboard and game controllers (joysticks, D-pad, triggers to fire).
- A Python reimplementation with nearly identical gameplay is at python/volcano.py. Run it with
uv run python python/volcano.py - The RK86 ROM monitor provides keyboard input, screen output, and cursor positioning via subroutines.
Play VOLCANO online in the emulator or the remake in JavaScript.
Original game for BBC Micro - https://bbcmicro.co.uk/game.php?id=143

