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.lst — assembler listing with addresses and symbol table
(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.
-+- and body O-+ or +-O). Moves in 4 directions via configurable keys (default: cursor codes). Cockpit O is the collision point.O is directly above a person I/Y. The person attaches below as a hanging I character.=. The person is deposited inside.J/L alternating). At zero, they fall and die.+ chars. If lava reaches a person’s ledge, they die.*) launched from the volcano peak with random trajectories. Parabolic arcs via 16-bit fixed-point physics with gravity. Hitting the helicopter destroys it.- horizontally from the cockpit. Bullets destroy stones (replacing * with +). Bullets also kill people if they hit I/Y.() 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.. dots). Spare helicopters are visible inside the station.saved_people (higher is better) and used_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 + row
Two 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 = backspaceThis 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:
0x0000-0x1FFF) to read a byte for entropy[0..max]The lava_levels table (offset 0D8Fh) has 16 entries of 5 bytes each:
count, row, column, human_row, human_col
Each 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 overThe initial screen layout is RLE-compressed (offset 0D9Fh):
N, char — repeat char N timesN, 0 — end of row (advance to next screen line)0xFF, ...0 — literal string until null terminator0 — end of dataThe 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 binary
The 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
uv run python python/volcano.pyPlay VOLCANO online in the emulator or the remake in JavaScript.
Original game for BBC Micro - https://bbcmicro.co.uk/game.php?id=143