Claim set · data/claims/space-invaders.yaml

Space Invaders (Computer Archeology's annotated disassembly)

Game: Space Invaders.

Space Invaders moves its rack of aliens one alien per frame. The interrupt at scanline 96 calls CursorNextAlien, which skips dead aliens to the next live one and waits until the end-of-screen interrupt's DrawAlien has drawn it. Only when the cursor passes the last of the 55 slots does MoveRefAlien step the reference alien, from which every other alien is drawn. A step of the rack therefore takes one 60 Hz frame per live alien: 55 frames at the start, 1 for the last alien. The listing reads MAME's invaders set, Midway's release. space-invaders/march

About: Space Invaders Remaining-enemy speed-up

Value
[
 55,
 1
]
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L7>>> binary 0000:roms/invaders.h + roms/invaders.g + roms/invaders.f.diag + roms/invaders.eComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Hardware.md#L28-L33If I understand this right then the system gets RST 8 when the beam is *near* the middle of the screen and RST 10 … The raster resolution is 256x224 at 60Hz.Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L120-L124; Main game-play timing loop … 0078: CD 00 01 CALL $0100 ; {code.DrawAlien} Draw the current alien (or exploding alien)Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L138-L155; Continues here at scanline 96 … 00AB: CD 41 01 CALL $0141 ; {code.CursorNextAlien} Advance cursor to next alien (move the alien if it is last one)Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L248-L273CursorNextAlien: … 0146: 3A 00 20 LD A,($2000) ; {ram.waitOnDraw} Still waiting on ... 0149: A7 AND A ; ... this alien to be drawn? 014A: C0 RET NZ ; Yes ... leave cursor in place … 0154: 3C INC A ; Have we drawn all aliens ... 0155: FE 37 CP $37 ; ... at last position? 0157: CC A1 01 CALL Z,$01A1 ; {code.MoveRefAlien} Yes ... move the bottom/right alien and reset index to 0 015A: 6F LD L,A ; HL now points to alien flag 015B: 46 LD B,(HL) ; Is alien ... 015C: 05 DEC B ; ... alive? …Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L319-L331MoveRefAlien: ; The "reference alien" is the bottom left. All other aliens are drawn relative to this ; reference. This routine moves the reference alien (the delta is set elsewhere) and toggles … 01A5: 21 06 20 LD HL,$2006 ; Set current alien ... 01A8: 36 00 LD (HL),$00 ; ... index to 0 … 01AE: CD D9 01 CALL $01D9 ; {code.AddDelta} Move alienComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3909-L3911; The game starts with 55 aliens. The aliens are move/drawn one per interrupt which means it ; takes 55 interrupts.Checked by claude, 2026-10-25 — read the ISR at 0078 and 008C, CursorNextAlien (0141-0179) and MoveRefAlien (01A1-01BE); the cursor loop at 0154-015D skips dead aliens within one call, the waitOnDraw flag at 2000 holds the cursor until DrawAlien clears it, and the move happens when the index reaches $37 (55); GetAlienCoords (017A-019E) starts each alien's position from the reference alien's at 2009-200A and steps it by row and column

The frame count leaves out frames when the rack stands still, such as while the player's ship explodes (CursorNextAlien returns at once).

Cited by: Enemy formation, Remaining-enemy speed-up, Space Invaders

When the rack bumps an edge, RackBump reverses it and drops it 8 px: it sets the next step's drop from $200E, which the game's RAM copy fills with $F8 (-8), and MoveRefAlien clears the drop after one step. Its step to the right is 2 px, or 3 px when one alien is left; its step to the left is always 2 px. space-invaders/last-alien

About: Space Invaders Remaining-enemy speed-up

Value
{
 "right": 2,
 "rightLastAlien": 3,
 "left": 2
}
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3163-L31851597: 3A 0D 20 LD A,($200D) ; {ram.rackDirection} Get rack direction 159A: A7 AND A ; Moving right? 159B: C2 B7 15 JP NZ,$15B7 ; {} No ... handle moving left … 15A5: 06 FE LD B,$FE ; Delta X of -2 15A7: 3E 01 LD A,$01 ; Rack now moving right … 15A9: 32 0D 20 LD ($200D),A ; {ram.rackDirection} Set new rack direction 15AC: 78 LD A,B ; B has delta X 15AD: 32 08 20 LD ($2008),A ; {ram.refAlienDXr} Set new delta X 15B0: 3A 0E 20 LD A,($200E) ; {ram.rackDownDelta} Set delta Y ... 15B3: 32 07 20 LD ($2007),A ; {ram.refAlienDYr} ... to drop rack by 8 …Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3684-L368918F1: 06 02 LD B,$02 ; Rack moving right delta X 18F3: 3A 82 20 LD A,($2082) ; {ram.numAliens} Number of aliens on screen 18F6: 3D DEC A ; Just one left? 18F7: C0 RET NZ ; No ... use right delta X of 2 18F8: 04 INC B ; Just one alien ... move right at 3 instead of 2Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L393-L396 — CopyRAMMirror, called at each game start (07F3)01E4: 06 C0 LD B,$C0 ; Number of bytes 01E6: 11 00 1B LD DE,$1B00 ; RAM mirror in ROM 01E9: 21 00 20 LD HL,$2000 ; Start of RAM 01EC: C3 32 1A JP $1A32 ; {code.BlockCopy} Copy [DE]->[HL] and returnComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4072 — the byte at $1B0E, copied to $200E, is $F81B00: 01 00 00 10 00 00 00 00 02 78 38 78 38 00 F8 00Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L326-L33101A5: 21 06 20 LD HL,$2006 ; Set current alien ... … 01AA: 23 INC HL ; Point to DeltaX 01AB: 4E LD C,(HL) ; Load DX into C 01AC: 36 00 LD (HL),$00 ; Set DX to 0 01AE: CD D9 01 CALL $01D9 ; {code.AddDelta} Move alienChecked by claude, 2026-10-25 — read RackBump at 1597-15C2: rackDirection 0 takes the right-edge branch, which loads B = $FE and A = 1; the left-edge branch calls 18F1 (B = 2, or 3 when numAliens is 1) and loads A = 0; both store B in $2008 and $200E's value in $2007. Read $1B0E = $F8 in the RAM mirror copied by 01E4, and MoveRefAlien zeroing $2007 after adding it once.

Two comments in RackBump have the direction backwards: L3171 says "Rack now moving right" where the code stores 1, which the branch at L3164-L3165 (and RAMUse.md) reads as moving left, and L3184 says "Rack now moving left" where it stores 0. MoveRefAlien's comments (L328-L330) call $2007 "DeltaX"; RackBump fills it with the drop.

Cited by: Space Invaders

Each pass of the game loop, SpeedShots checks the number of aliens left; below 9 it sets the alien shots' step ($207E, added to a shot's Y each move) to $FB, -5 px, in place of the $FC (-4 px) that the game's RAM copy puts there, so the aliens' shots fall faster. space-invaders/shot-speed

About: Space Invaders Remaining-enemy speed-up

Value: 9 aliens (threshold)

CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1503-L150708D8: 3A 82 20 LD A,($2082) ; {ram.numAliens} Number of aliens on screen 08DB: FE 09 CP $09 ; More than 8? 08DD: D0 RET NC ; Yes ... leave shot speed alone 08DE: 3E FB LD A,$FB ; Normally FF (-4) ... now FB (-5) 08E0: 32 7E 20 LD ($207E),A ; {ram.alienShotDelta} Speed up alien shotsComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1404-L14120825: CD F3 15 CALL $15F3 ; {code.CountAliens} Count aliens (count to 2082) … 0838: CD D8 08 CALL $08D8 ; {code.SpeedShots} Adjust alien shot speedComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1093-L109705E5: 3A 7B 20 LD A,($207B) ; {ram.alienShotYr} Get shot's Y coordinate 05E8: 47 LD B,A ; Hold it 05E9: 3A 7E 20 LD A,($207E) ; {ram.alienShotDelta} Get alien shot delta 05EC: 80 ADD A,B ; Add to shots coordinate 05ED: 32 7B 20 LD ($207B),A ; {ram.alienShotYr} New shot Y coordinateComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L393-L396 — CopyRAMMirror copies $C0 bytes, $1B00-$1BBF to $2000-$20BF, at each game start (07F3)01E4: 06 C0 LD B,$C0 ; Number of bytes 01E6: 11 00 1B LD DE,$1B00 ; RAM mirror in ROM 01E9: 21 00 20 LD HL,$2000 ; Start of RAMComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4083 — the byte at $1B7E, copied to $207E, is $FC1B70: 0F 0B 00 18 26 0F 0B 00 18 04 11 24 1B 25 FCChecked by claude, 2026-10-25 — read SpeedShots at 08D8-08E3 and its call at 0838; the shot mover at 05E5-05ED adds $207E to the shot's Y; CopyRAMMirror (01E4) copies $C0 bytes from $1B00, so $207E starts as the byte at $1B7E, $FC

The comment at L1506 says "Normally FF (-4)": the usual value is $FC, and $FF (-1) is what the splash animation at 18AE stores. RAMUse.md L135 says the delta is "Normally -1 but set to -4 with less than 9 aliens"; in play the code starts it at -4 and sets -5. The $FC sits after the "PLAY PLAYER<1>" message, in the part of the mirror whose comment (L4080, L4089-L4092) calls its copy to RAM a harmless mistake; the shot step depends on it.

Space Invaders awards one extra ship per player when the upper two digits of the score reach 15, or 10 with DIP switch bit 3 set: at 1,500 or 1,000 points. It then clears the player's award flag, so no second ship follows. space-invaders/extra-ship

About: Space Invaders Extra life

Value
[
 1500,
 1000
]
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1574-L1592; Award extra ship if score has reached ceiling 0935: CD 10 19 CALL $1910 ; {code.CurPlyAlive} Get descriptor of sorts 0938: 2B DEC HL ; Back up ... 0939: 2B DEC HL ; ... two bytes 093A: 7E LD A,(HL) ; Has extra ship ... 093B: A7 AND A ; already been awarded? 093C: C8 RET Z ; Yes ... ignore 093D: 06 15 LD B,$15 ; Default 1500 093F: DB 02 IN A,($02) ; {hard.INP2} Read DIP settings 0941: E6 08 AND $08 ; Extra ship at 1000 or 1500 0943: CA 48 09 JP Z,$0948 ; {} 0=1500 0946: 06 10 LD B,$10 ; Awarded at 1000 …Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1606-L1609096B: CD 10 19 CALL $1910 ; {code.CurPlyAlive} Get descriptor for active player of some sort 096E: 2B DEC HL ; Back up ... 096F: 2B DEC HL ; ... two bytes 0970: 36 00 LD (HL),$00 ; Flag extra ship has been awardedChecked by claude, 2026-10-25 — read 0935-0979: the flag two bytes below the player's descriptor must be nonzero; B is $15, or $10 when IN 2 bit 3 is set; the score's high byte is compared with B and a ship added when it isn't lower; 0970 then zeroes the same flag

Cited by: Extra life

Each new rack starts lower on the screen. The first rack's bottom row starts at Y $78. When a rack is cleared, the count of racks beaten (taken mod 8, plus 1) picks the next start from an 8-entry table, $60, $50, $48, $48, $48, $40, $40, $40, so the 10th rack starts where the 2nd did. space-invaders/rack-start

About: Space Invaders Difficulty ramp

Value
[
 120,
 96,
 80,
 72,
 72,
 72,
 64,
 64,
 64
]
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1717-L17310A09: 2E FE LD L,$FE ; 2xFE ... rack count 0A0B: 7E LD A,(HL) ; Get the number of racks the player has beaten 0A0C: E6 07 AND $07 ; 0-7 0A0E: 3C INC A ; Now 1-8 0A0F: 77 LD (HL),A ; Update count since player just beat a rack 0A10: 21 A2 1D LD HL,$1DA2 ; Starting coordinate of alien table 0A13: 23 INC HL ; Find the ... 0A14: 3D DEC A ; ... right entry ... 0A15: C2 13 0A JP NZ,$0A13 ; {} ... in the table 0A18: 7E LD A,(HL) ; Get the starting Y coordiante 0A19: E1 POP HL ; Restore player's pointer 0A1A: 2E FC LD L,$FC ; 2xFC ... …Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4685-L4696AlienStartTable: ; Starting Y coordinates for aliens at beginning of rounds. The first round is initialized to $78 at 07EA. ; After that this table is used for 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, and 9th. The 10th starts over at ; 1DA3 (60). 1DA3: 60 1DA4: 50 1DA5: 48 1DA6: 48 1DA7: 48 1DA8: 40 1DA9: 40 1DAA: 40Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1378-L137907EA: 21 78 38 LD HL,$3878 ; Screen coordinates for lower-left alien 07ED: 22 FC 21 LD ($21FC),HL ; {ram.p1RefAlienY} Initialize reference alien for player 1Checked by claude, 2026-10-25 — read 0A09-0A1E, where the count is ANDed with 7 and incremented, then HL steps from 1DA2 that many times, so a count of 1 reads 1DA3; read the table at 1DA3-1DAA, and the first rack's $3878 at 07EA, stored at 21FC (Y $78) and 21FD (X $38), the two bytes 0A1A-0A1E sets for later racks

Y grows upward on the rotated screen, and CursorNextAlien ends the player's turn when an alien's Y falls below $28, so a lower start leaves fewer drops before the aliens land.

Cited by: Difficulty ramp

Space Invaders keeps one high score, four BCD digits at $20F4–$20F5. When a player's game ends, it compares that player's score with it, upper digits first, and copies the score over it if the score is higher. space-invaders/high-score

About: Space Invaders High score

CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3303-L3327166E: CD 8B 1A CALL $1A8B ; {} Print ZERO ships remain 1671: CD 10 19 CALL $1910 ; {code.CurPlyAlive} Get active-flag ptr for current player 1674: 36 00 LD (HL),$00 ; Flag player is dead 1676: CD CA 09 CALL $09CA ; {} Get score descriptor for current player 1679: 23 INC HL ; Point to high two digits 167A: 11 F5 20 LD DE,$20F5 ; Current high score upper two digits 167D: 1A LD A,(DE) ; Is player score greater ... 167E: BE CP (HL) ; ... than high score? 167F: 1B DEC DE ; Point to LSB 1680: 2B DEC HL ; Point to LSB 1681: 1A LD A,(DE) ; Go ahead and fetch high score lower two digits 1682: CA 8B 16 JP Z,$168B ; {} Upper two are the same ... have to check lower two …Checked by claude, 2026-10-25 — read 166E-1695: after printing zero ships and clearing the player's active flag, DE walks $20F5 then $20F4, the only high-score bytes the routine touches; a tie in the upper byte falls to the lower byte, and the copy runs only when the high score is below the player's

Cited by: High score

Computer Archeology credits Mikael Agren with patching the original Space Invaders ROMs to add a high-score table. space-invaders/high-score-hack

About: Space Invaders High score

Code notesComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/README.md#L31-L35Mikael Agren patched the original ROMs to add a [high-score table]

The patch's own blog post is linked from the README; the atlas hasn't archived it.

Cited by: High score

The shields are pixels in the 1-bit screen bitmap, not objects. Each player has a RAM buffer of four copies of the 44-byte ShieldImage, 22 rows of 2 bytes, a 22 × 16 px shape of 294 lit pixels (computed); RestoreShields ORs the buffer onto the screen, the four shields with 23 rows between them (45 from start to start), and in a two-player game RememberShields copies them from the screen back into the player's buffer, so each player keeps their own damage. The buffers are redrawn from the image at the start of a game and with each new rack. space-invaders/shields-bitmap

About: Space Invaders Destructible terrain

Value
{
 "width": 22,
 "height": 16,
 "pixels": 294,
 "shields": 4,
 "gap": 23,
 "pitch": 45
}
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L413-L42001F8: 0E 04 LD C,$04 ; Going to draw 4 shields 01FA: 11 20 1D LD DE,$1D20 ; Shield pixel pattern 01FD: D5 PUSH DE ; Hold the start for the next shield 01FE: 06 2C LD B,$2C ; 44 bytes to copyComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L448-L455CopyShields: ; A is 1 for screen-to-buffer, 0 for to buffer-to-screen ; HL is screen coordinates of first shield. There are 23 rows between shields. … 0221: 01 02 16 LD BC,$1602 ; 22 rows, 2 bytes/row (for 1 shield pattern) 0224: 21 06 28 LD HL,$2806 ; Screen coordinatesComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3977-L3986RestoreShields: ; Logically OR the player's shields back onto the playfield … 1A6C: B6 OR (HL) ; OR with screenComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L2906-L2907RememberShields: ; In a multi-player game the player's shields are block-copied to and from RAM between turns.Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4563-L4590ShieldImage: ; Shield image pattern. 2 x 22 = 44 bytes.Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1737-L17420A2A: CD F5 01 CALL $01F5 ; {code.DrawShieldPl2} Draw shields for player 2 0A2D: CD 04 19 CALL $1904 ; {code.InitAliensP2} Initalize aliens for player 2 … 0A33: CD EF 01 CALL $01EF ; {code.DrawShieldPl1} Draw shields for player 1 0A36: CD C0 01 CALL $01C0 ; {code.InitAliens} Initialize aliens for player 1Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1367-L136807CB: CD EF 01 CALL $01EF ; {code.DrawShieldPl1} Draw shields for player-1 07CE: CD F5 01 CALL $01F5 ; {code.DrawShieldPl2} Draw shields for player-2Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Hardware.md#L33-L35The raster resolution is 256x224 at 60Hz. The monitor is rotated in the cabinet 90 degrees counter-clockwise. … The screens pixels are on/off (1 bit each). 256*224/8 = 7168 (7K) bytes.Checked by claude, 2026-10-22 — read DrawShieldPl1/2, CopyShields, RestoreShields, RememberShields, the shield image, and the calls at a new game (07CB-07CE) and a new rack (0A2A-0A36) at the pinned commit. On the rotated screen a memory row of 32 bytes is one 256 px column, so 22 rows of 2 bytes are 22 px across and 16 px tall. RestoreShields leaves HL 22 rows on, and CopyShields adds 23 more, so the shields start 45 columns apart with 23 empty columns between. The pixel count is the set bits of the 44 bytes at 1D20

gap is the empty columns between two shields (23) and pitch the distance from one shield's first column to the next one's (45). The shields sit at screen address $2806 on: memory rows 32 on, bytes 6 and 7, which is 48 to 63 px up from the bottom of the 256 px column. RememberShields' comments note its load and store run the other way from its own comment ("should be DE"); it copies screen to buffer.

Cited by: Destructible terrain

Nothing tests for shields as such. Every shot is drawn with DrawSprCollision, which ANDs each byte of the shifted sprite with the screen before ORing it in and sets the collision flag if any pixel was already lit, so a shot hits a shield when its newly drawn sprite overlaps a lit shield pixel. The player's shot is 1 px wide and 4 px long and moves 4 px a step, so it is tested against every pixel row on its path (computed). A player's shot that collides below the rack takes status 3, the code for a hit on something other than an alien. space-invaders/shield-hit-test

About: Space Invaders Destructible terrain

Value
{
 "shotWidth": 1,
 "shotLength": 4,
 "shotStep": 4
}
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L2928-L2954DrawSprCollision: … 14A0: A6 AND (HL) ; Any bits from pixel collide with bits on screen? 14A1: CA A9 14 JP Z,$14A9 ; {} No ... leave flag alone 14A4: 3E 01 LD A,$01 ; Yes ... set ... 14A6: 32 61 20 LD ($2061),A ; {ram.collision} ... collision flag 14A9: F1 POP AF ; Restore the pixel pattern 14AA: B6 OR (HL) ; OR it onto the screenComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L805-L826MovePlyShot: … 0410: CD 52 14 CALL $1452 ; {code.EraseShifted} Erase the sprite from the screen … 0416: 3A 2C 20 LD A,($202C) ; {ram.shotDeltaX} DeltaX for shot 0419: 85 ADD A,L ; Move the shot ... … 041E: CD 91 14 CALL $1491 ; {code.DrawSprCollision} Draw sprite with collision detectionComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4319-L4320PlayerShotSpr: 1C90: 0F ; ++++....Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L40741B20: 00 00 00 BB 03 00 10 90 1C 28 30 01 04 00 FF FFComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3008-L30091500: B8 CP B ; Compare to shot's coordinate 1501: D2 30 15 JP NC,$1530 ; {} Outside the rack-square ... do miss explosionComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3057-L3060; Player shot leaving playfield, hitting shield, or hitting an alien shot 1530: 3E 03 LD A,$03 ; Mark ... 1532: 32 25 20 LD ($2025),A ; {ram.plyrShotStatus} ... player shot hit something other than alienChecked by claude, 2026-10-22 — read DrawSprCollision, MovePlyShot, PlayerShotHit (14D8-1535), the shot sprite, and the player-shot structure's ROM mirror at the pinned commit. In the mirror line 1B25 is the status (0), 1B26 the blow-up timer ($10), 1B27-1B28 the sprite (1C90), 1B2B the size (1 row), 1B2C the step (4). One sprite row is one screen column, and 0F lights 4 bits of it

Rack and saucer hits come from the same flag: MovePlyShot copies it to alienIsExploding ($2002), and PlayerShotHit sorts the hit by the shot's height (saucer from Yr $CE, the top from $D8, the rack from the reference alien's row up). Alien shots, the player's ship, and the bottom line are lit pixels too, so the same test hits them.

Cited by: Destructible terrain

A player's shot that hits a shield erases itself, then ORs the 8 × 8 px ShotExploding pattern onto the screen around the point of impact; after the blow-up timer counts down from 16, EndOfBlowup erases that pattern with an inverted AND. The erase clears every pixel under the pattern's 38 set bits (computed), shield pixels included, and the first erase had already cleared the shield pixels under the shot itself, so the hole is the explosion's shape plus the shot's last 4 px. space-invaders/shot-crater

About: Space Invaders Destructible terrain

Value
{
 "pattern": [
  8,
  8
 ],
 "pixels": 38,
 "timer": 16
}
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L770-L794; Shot blowing up because it left the playfield, hit a shield, or hit another bullet 03D7: 35 DEC (HL) ; Decrement the timer 03D8: CA 36 04 JP Z,$0436 ; {code.EndOfBlowup} If done then 03DB: 7E LD A,(HL) ; Get timer value 03DC: FE 0F CP $0F ; Starts at 10 ... first decrement brings us here … 03E3: CD 52 14 CALL $1452 ; {code.EraseShifted} Erase the sprite … 03E8: 34 INC (HL) ; Change 1C90 to 1C91 … 03F2: 36 08 LD (HL),$08 ; 202B 8 bytes in size of sprite 03F4: CD 30 04 CALL $0430 ; {code.ReadPlyShot} Read player shot structure …Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L836-L839EndOfBlowup: 0436: CD 30 04 CALL $0430 ; {code.ReadPlyShot} Read the shot structure 0439: CD 52 14 CALL $1452 ; {code.EraseShifted} Erase the player's shotComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L2870-L2879EraseShifted: ; Erases a shifted sprite from screen (like for player's explosion) … 145C: 2F CPL ; Reverse it (erasing bits) 145D: A6 AND (HL) ; Erase the bits from the screenComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4336-L4345ShotExploding: ; *..**..* ; ..****.. ; .******. ; *.****.. ; ..****.* ; .*****.. ; ..*****. ; *..**..* 1C91: 99 3C 7E 3D BC 3E 7C 99Checked by claude, 2026-10-22 — read GameObj1's status-3 branch (03D7-03F7), EndOfBlowup, EraseShifted, and DrawShiftedSprite (which ORs) at the pinned commit; the timer at $2026 starts at $10 (ROM mirror 1B26), the first decrement to $0F draws the explosion, and the one that reaches 0 erases it. 38 is the set bits of 1C91-1C98

The explosion is placed 2 px back along the shot's path (Yr − 2) and 3 px across (Xr − 3), which centers the 8 px wide pattern on the 1 px shot. The same explosion ends a shot that hits an alien shot or leaves the top of the playfield. The disassembly's picture of the pattern is in memory order, rotated from the screen.

Cited by: Destructible terrain

An alien shot ends when its newly drawn sprite collides with any lit pixel, or when it falls below the playfield; a collision at the player's height kills the player instead. Its blow-up timer starts at 4: on the first tick ShotBlowingUp erases the shot and draws the 6 × 8 px AShotExplo pattern, and on the tick that reaches 0 it erases that pattern with an inverted AND, so a shield loses the pattern's 26 pixels (computed) plus those under the shot itself. space-invaders/bomb-crater

About: Space Invaders Destructible terrain

Value
{
 "pattern": [
  6,
  8
 ],
 "pixels": 26,
 "timer": 4
}
CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1098-L111605F0: CD 6C 06 CALL $066C ; {} Draw the alien shot 05F3: 3A 7B 20 LD A,($207B) ; {ram.alienShotYr} Shot's Y coordinate 05F6: FE 15 CP $15 ; Still in the active playfield? 05F8: DA 12 06 JP C,$0612 ; {} No ... end it 05FB: 3A 61 20 LD A,($2061) ; {ram.collision} Did shot collide ... … 060E: 97 SUB A ; Flag that player ... 060F: 32 15 20 LD ($2015),A ; {ram.playerAlive} ... has been struck … 0615: F6 01 OR $01 ; ... start shot ...Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L1149-L1179ShotBlowingUp: ; Alien shot is blowing up … 0649: FE 03 CP $03 ; First tick, 4, we draw the explosion 064B: C2 67 06 JP NZ,$0667 ; {} After that just wait 064E: CD 75 06 CALL $0675 ; {} Erase the shot 0651: 21 DC 1C LD HL,$1CDC ; Alien shot ... … 065F: 3E 06 LD A,$06 ; Alien shot descriptor ... 0661: 32 7D 20 LD ($207D),A ; {ram.alienShotSize} ... size 6 0664: C3 6C 06 JP $066C ; {} Draw alien shot explosion … …Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L4454-L4461AShotExplo: ; .*.*..*. ; *.*.*... ; .*****.* ; ******.. ; .****.*. ; *.*..*.. 1CDC: 4A 15 BE 3F 5E 25Computer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L40751B30: 00 00 02 76 04 00 00 00 00 00 04 EE 1C 00 00 03Checked by claude, 2026-10-22 — read HandleAlienShot's move and collision tail (05E9-061A), ShotBlowingUp, and the draw and erase stubs at 066C and 0675 at the pinned commit. The blow-up counter $2078 is byte 5 of the 11-byte active shot structure copied from $2035, $2045, or $2055; in the ROM mirror byte 1B3A (rolling shot) is 04, as are 1B4A and 1B5A for the other two. 26 is the set bits of 1CDC-1CE1

The three alien shots take turns, one per interrupt tick (GameObj2's comment), so the explosion lasts three of that shot's own updates, not three frames. A collision with the player's shot or the bottom line blows the shot up the same way; at the player's height (Yr $1E to $26) it also clears playerAlive.

Cited by: Destructible terrain

Aliens that reach the shields erase them. DrawSprite, which draws each alien, stores the shifted sprite bytes over the screen instead of ORing them in, both bytes of each of its 16 rows, so wherever an alien is drawn the shield pixels in those bytes are replaced by the alien's image and its blank pixels. The disassembly's comment on CodeBug1 describes a lone alien that "enters the players shields on the lower left where it begins to eat them". space-invaders/aliens-erase-shields

About: Space Invaders Destructible terrain

CodeComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3198-L3215DrawSprite: ; Draw sprite at [DE] to screen at pixel position in HL … 15DC: DB 03 IN A,($03) ; {hard.SHFT_IN} Read back shifted amount 15DE: 77 LD (HL),A ; Shifted sprite to screen … 15E4: DB 03 IN A,($03) ; {hard.SHFT_IN} Read back remainder of previous 15E6: 77 LD (HL),A ; Write remainder to adjacentComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L235-L237012E: 2A 0B 20 LD HL,($200B) ; {ram.alienPosLSB} Pixel position 0131: 06 10 LD B,$10 ; 16 rows in alien sprites 0133: CD D3 15 CALL $15D3 ; {code.DrawSprite} Draw shifted spriteComputer Archeology: Space Invaders · content/Arcade/SpaceInvaders/Code.md#L3023-L3026; The entire rack of aliens is based on the lower left alien. Imagine all aliens are dead except the ; upper left. It wiggles down the screen and enters the players shields on the lower left where it begins ; to eat them.Checked by claude, 2026-10-22 — read DrawAlien (0100-0137) and DrawSprite (15D3-15F2) at the pinned commit; each row writes two whole bytes with LD, against the OR in DrawShiftedSprite and DrawSprCollision. The quote on CodeBug1 is the annotator's comment

A shot alien's explosion is erased by EraseSimpleSprite, which zeroes two whole bytes per row, so an alien shot down inside a shield clears that patch too. Nothing restores a shield before the next rack.

Cited by: Destructible terrain