Cite as
Computer Archeology, Asteroids
Original
https://computerarcheology.com/Arcade/Asteroids/
Pinned
topherCantrell/computerarcheology @ 1adc2a7f3ae30f9efceed3f6b22bf5541c1f584c
Accessed
2026-10-22
Licence
none stated
Credit
Hosted on Christopher Cantrell's Computer Archeology. Its README says Lonnie Howell started the comments and Mark McDougall carried them on; the listing's header credits the disassembly to Lonnie Howell. Labels and comments quoted in asteroids claims are theirs.
Notes
content/Arcade/Asteroids/Code.md disassembles 035145.02, 035144.02, and 035143.02 (its `binary` line; the header says "Rev 2"), Atari's revision 2 program ROMs. RAMUse.md names the RAM, Hardware.md gives the 250 Hz interrupt, and VectorROM.md lists the vector ROM, which holds the sine table. The repo also holds ROM images under each game's roms/ folder; the atlas reads only the markdown.

Cited on

Claims (14)

Asteroids paces its main loop by its 250 Hz NMI: every fourth NMI increments a counter, and the main loop waits on that counter before each pass, so the loop runs at most 62.5 times a second (computed: 250 / 4). The atlas calls one pass a frame. The listing reads Atari's revision 2 program ROMs.content/Arcade/Asteroids/Code.md L7–23content/Arcade/Asteroids/Hardware.md L9content/Arcade/Asteroids/Code.md L2556–2563content/Arcade/Asteroids/Code.md L35–36Code
While the ship is in play, a held rotate button turns it 3 of its 256 directions per frame. On every other frame (when the fast timer's low bit is clear), a held thrust button adds twice the cosine of the direction to the horizontal velocity and twice the sine to the vertical, read from a 65-entry sine table for a quarter turn, 0 to 127, which the lookup folds for the other quarters. Velocities carry 8 fraction bits, so one thrust step adds at most 254/256 of a position unit per frame to an axis's speed (computed).content/Arcade/Asteroids/Code.md L1054–1099content/Arcade/Asteroids/Code.md L1992–2004content/Arcade/Asteroids/VectorROM.md L1158–1178content/Arcade/Asteroids/Code.md L1030–1053Code
On the same every-other frames, when thrust isn't held, each axis of the ship's velocity loses 2/256 of its whole-unit part (and 1/256 more when moving right or up), about 1/128 of itself per step, until it reaches zero. With the thrust off, the ship's speed so halves in about 88 steps, 176 frames, about 2.8 seconds at 62.5 frames a second (computed).content/Arcade/Asteroids/Code.md L1100–1134content/Arcade/Asteroids/RAMUse.md L105Code
Thrust holds each axis of the ship's velocity to its own limit: at most 63 255/256 position units per frame right or up, and 63 255/256 left or down (computed from $3F.FF and $C0.01). Because the axes are clamped apart, a diagonal can reach about 1.41 times the top speed along one axis (computed).content/Arcade/Asteroids/Code.md L1135–1145content/Arcade/Asteroids/Code.md L1076–1084Code
Each frame, Asteroids adds the velocity of every object that isn't exploding (rocks, ship, saucer, and shots) to its position, on a playfield of 32 by 24 units of 256 (8,192 by 6,144 position units, computed). An object that crosses the left or right edge comes back on the other side, except the saucer, which is removed instead; one that crosses the top or bottom comes back at the other edge, the saucer included.content/Arcade/Asteroids/Code.md L67content/Arcade/Asteroids/Code.md L915–921content/Arcade/Asteroids/Code.md L968–1016content/Arcade/Asteroids/Code.md L1015–1021content/Arcade/Asteroids/RAMUse.md L99–101content/Arcade/Asteroids/RAMUse.md L129–141Code
Hyperspace works while the ship is in play (not exploding and not waiting to return): it removes the ship, zeroes the whole parts of its velocity (the fractions in $64 and $65 stay), and sets a 48-frame return timer. The new horizontal position is a random whole unit from 3 to 28. A further random number r from 0 to 31 decides the jump: it fails when r is 24 or more and 2 × (r − 24) + 4 is at least the current rock count, so with 4 or fewer rocks 8 of the 32 values fail, and with 19 or more none do (computed). The vertical position is r below 24 and 2 × (r − 24) + 4 (4 to 18) from 24, held to 3 to 20. When the timer runs out the ship returns, or, if the jump failed, explodes and costs a ship.content/Arcade/Asteroids/Code.md L812–857content/Arcade/Asteroids/Code.md L1022–1052content/Arcade/Asteroids/RAMUse.md L177Code
Each player's saucer reload value starts at 146 when a game starts and drops by 6 each time a saucer appears, as long as the result stays 32 or more. While it is 128 or more, every saucer is the large one. Below 128, a player with 30,000 points or more always gets the small saucer; under 30,000 a random byte decides, giving the small saucer when the byte is more than half the reload value: about 3 in 4 at the first chance (122) and about 15 in 16 at the floor of 32 (computed, for evenly spread bytes).content/Arcade/Asteroids/Code.md L136–140content/Arcade/Asteroids/Code.md L483–488content/Arcade/Asteroids/Code.md L512–527Code
Between shots, a live saucer counts down 10 runs of its routine, which runs every fourth frame (40 frames, computed), and the count pauses while the player's ship is waiting to return. The large saucer fires in a random direction, any of 256. The small saucer aims: it takes the ship's position minus its own on each axis, subtracts half the saucer's velocity, turns the pair into a direction with an arctangent routine, and adds a random error of −16 to +15 directions while the player has under 35,000 points, and −7 to +8 from 35,000.content/Arcade/Asteroids/Code.md L457–460content/Arcade/Asteroids/Code.md L536–604content/Arcade/Asteroids/Code.md L1867–1898Code
A rock that is hit, by the ship, the saucer, or either's shots, halves its size code (large 4, medium 2, small 1): a large rock leaves two medium rocks, a medium rock two small ones, and a small rock none. Each piece takes its parent's position and velocity, adds a random −16 to +15 to each axis, and holds each axis to a speed of 6 to 31. The first piece's horizontal position and the second's vertical one are changed by XOR with twice the low five bits of that piece's velocity. The hit rock becomes an explosion. A piece needs a free slot of the 27, so a full field gives fewer. During a game, a hit by the ship or its shots scores 20 for a large rock, 50 for a medium one, and 100 for a small one.content/Arcade/Asteroids/Code.md L421–435content/Arcade/Asteroids/Code.md L1740–1788content/Arcade/Asteroids/Code.md L1236–1270content/Arcade/Asteroids/Code.md L1531–1536Code
A new wave starts once no rocks are left and a 127-frame wave timer, set when the last rock goes, has run out. Each wave has two more large rocks than the one before, up to 11; the count starts at 2 when a game starts, so the waves run 4, 6, 8, 10, 11, 11 (computed).content/Arcade/Asteroids/Code.md L29–31content/Arcade/Asteroids/Code.md L54–55content/Arcade/Asteroids/Code.md L150–152content/Arcade/Asteroids/Code.md L858–859content/Arcade/Asteroids/Code.md L76–81content/Arcade/Asteroids/Code.md L939–942content/Arcade/Asteroids/Code.md L1182–1197Code
Asteroids gives a ship each time a player's score passes a multiple of 10,000: the score is two BCD bytes, and when an addition carries into the thousands byte and leaves its low digit 0, the player gains a ship.content/Arcade/Asteroids/Code.md L1430–1444Code
Asteroids keeps a table of ten high scores, two BCD bytes each, with three initials apiece (computed from the 20-byte and 30-byte tables), and tells a player who makes it "YOUR SCORE IS ONE OF THE TEN BEST".content/Arcade/Asteroids/RAMUse.md L38–42content/Arcade/Asteroids/Code.md L721–723Code
Asteroids' random routine (77B5) shifts a 16-bit register left one bit and sets the new low bit to the old bit 14 exclusive-or the old bit 0, turning an all-zero register into 1; it returns the low byte.content/Arcade/Asteroids/Code.md L1977–1991Code
inertial_thrust caps the speed itself, not each axis: after adding a thrust step it compares the sum of the squared components with MAX_THRUST squared, so a ship is no faster on a diagonal. Asteroids clamps each axis of its ship's velocity apart, so its diagonal is faster (asteroids/top-speed). A step that would pass the cap still applies if the result is slower than the current speed. At the cap, a step along the line of travel sets the velocity to exactly MAX_THRUST along the facing (if the ship isn't above the cap); a step off the line instead adds half a thrust step along the facing and takes a whole step off along the line of travel, kept if that ends within the cap or slower than before, so the course swings toward the facing. While the ship is flagged in a gravity well, a thrust step may take it past the cap up to MAX_ALLOWED_SPEED, 18 display units per frame.content/Arcade/Asteroids/Code.md L1135–1145Code