This is an old revision of the document!


Space Invaders Bunker

The following (edited) code snippet is from Richard Degler's disassembly [.zip] of the Bally Arcade Space Invaders prototype. The LOOP section demonstrates writing a single pattern (the bunker graphic) to the screen multiple times using the WRITP UPI routine. The BUNKER section shows the referenced pattern block.

; [...]
 
; Write Four Player "Protective Bunkers"
; ---------------------------------------
;   The Four Bunker's X,Y Coordinate's are:
;      Bunker 1 (Left-Most):    10, 65
;      Bunker 2 (Middle-Left):  50, 65
;      Bunker 3 (Middle-Right): 90, 65
;      Bunker 4 (Right-Most):  130, 65
;
        LD      B,$04           ; 4 for 4 writes
        LD      E,$0A           ; 10 for LEFTmost X
LOOP:   LD      HL,BUNKER       ; point at Player's BUNKER
        XOR     A               ; Magic Register = 0 for PLOP
        LD      D,$41           ; 65 for all Y Coordinate's
        PUSH    DE              ; store DE for X Coordinate
        PUSH    BC
        SYSTEM  WRITP           ; UPI WRITe with Pattern size lookup
        ;
        POP     BC
        POP     DE              ; restore DE for X Coordinate
        LD      A,E             ; old X + 40
        ADD     A,$28
        LD      E,A             ; X Coordinate for Next Bunker
        DJNZ    LOOP            ; (-$12) to run 4 times
 
; [...]
 
; Player's BUNKER color Pattern
BUNKER: DB      $05             ; WIDTH = 5 Bytes
        DB      $0D             ; HEIGHT = 13 Rows
        ;
        DB      $03,$FF,$FF,$FF,$C0 ; . . . 3 3 3 3 3 3 3 3 3 3 3 3 3 3 . . .
        DB      $0F,$FF,$FF,$FF,$F0 ; . . 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 . .
        DB      $3F,$FF,$FF,$FF,$FC ; . 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 .
        DB      $FF,$FF,$FF,$FF,$FF ; 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        DB      $FF,$FF,$FF,$FF,$FF ; 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        DB      $FF,$FF,$FF,$FF,$FF ; 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        DB      $FF,$FF,$FF,$FF,$FF ; 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        DB      $FF,$FF,$FF,$FF,$FF ; 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        DB      $FF,$FF,$FF,$FF,$FF ; 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        DB      $FF,$F0,$00,$0F,$FF ; 3 3 3 3 3 3 . . . . . . . . 3 3 3 3 3 3
        DB      $FF,$C0,$00,$03,$FF ; 3 3 3 3 3 . . . . . . . . . . 3 3 3 3 3
        DB      $FF,$00,$00,$00,$FF ; 3 3 3 3 . . . . . . . . . . . . 3 3 3 3
        DB      $FF,$00,$00,$00,$FF ; 3 3 3 3 . . . . . . . . . . . . 3 3 3 3
 
; [...]

Code Discussion

The first line loads register B with 4 for use as the loop counter. We want to draw the same bunker image four times along the bottom of the screen. Each will have identical y-coordinates, but increasing x-coordinates (as we draw left to right), so the second line sets the initial value of register E to 10. As we'll see below, E will serve as storage for the x-coordinate when we call the pattern drawing routine.

The third line marks the LOOP label, which is where the program will return again and again until B reaches 0. This also marks the point where we begin 'pre-loading' our registers with the arguments for our WRITP call. WRITP is squarely in the middle of the screen writing routine hierarchy, meaning that it requires some housecleaning before we call it.

Line 3 loads the address of the BUNKER pattern block in HL. WRITP assumes that the pattern size is stored with the pattern block, so the first two bytes at label BUNKER ($05, $0D) define the bunker graphic's width (5) and heigh (13) in bytes.

Line 4 'loads' the accumulator with the Magic Register settings for our pattern write. XOR A is a more efficient way to perform LD A,0 (though the former does change flags). In other words, we're sending a 0 to the Magic Register, indicating that we want to simply 'PLOP' the pattern onto the screen with no transformations.

Line 5 load the y-coordinate that we'll use for for every bunker (65) in the D register, as required by WRITP.

Lines 6 and 7 push the contents of DE and BC onto the stack to preserve their contents during the WRITP call.

Line 8 finally invokes WRITP now that all the necessary pattern information is in place: the pattern's size, contents, position, and (lack of) transformations.

Lines 10 and 11 pop the contents of BC and DE off the stack.

Line 12 loads the value of the current x-coordinate from E to A, the following line adds 40 to that value, then line 14 puts the sum back into E. As a result, on the next iteration through the loop, the bunker's x-coordinate will be 40 pixels to the right of its previous location.

The final line of the LOOP checks to see if B is zero. If not, the program proceeds to the beginning of LOOP; if so, program execution proceeds.

[why choose WRITP vs. others]

Result

[screenshot]