;
;	Disassembled by:
;		DASMx object code disassembler
;		(c) Copyright 1996-1999   Conquest Consultants
;		Version 1.30 (Oct  6 1999)
;
;       File:           sattackc.bin
;	CPU:		Signetics 2650 (2650 family)

;$VER: 1.0 (1.9.2006)
;Disassembled by Amigan Software in January-February 2003 and September
; 2006.
;URL:   http://www.deadwoodinc.net/amigan/
;EMail: jrj76@optusnet.com.au

;The sprite flickering is an inherent drawback of the sprite multiplexing
; techniques used by the game to achieve 6 apparent sprites.

;Starfield twinkling can be disabled by replacing the TWINKLING code with
; the NOTWINKLING code.

;2650 Equates-------------------------------------------------------------
z     equ  0
eq    equ  z
p     equ  1
gt    equ  p
n     equ  2
lt    equ  n
un    equ  3
;Hardware Equates/Memory Map----------------------------------------------
;                $0000..$0FFF can be ROM (first 4K of cartridge)
;                $1000..$17FF are unmapped
;                $1800..$18CF are upper screen display
;                $18D0..$18EF are user RAM
SPRITE0Y      equ 18F0h
SPRITE0X      equ 18F1h
SPRITE1Y      equ 18F2h
SPRITE1X      equ 18F3h
SPRITE2Y      equ 18F4h
SPRITE2X      equ 18F5h
SPRITE3Y      equ 18F6h
SPRITE3X      equ 18F7h
;                $18F8..$18FB are user RAM
CRTCVPR       equ 18FCh ;crtc vertical position register
PITCH         equ 18FDh ;also other uses
VOLUME        equ 18FEh ;also other uses
CHARLINE      equ 18FFh ;current character line
P1LEFTKEYS    equ 1900h ;unused
P1MIDDLEKEYS  equ 1901h ;unused
P1RIGHTKEYS   equ 1902h ;unused
P1PALLADIUM   equ 1903h ;unused
P2LEFTKEYS    equ 1904h ;unused
P2MIDDLEKEYS  equ 1905h
P2RIGHTKEYS   equ 1906h ;unused
P2PALLADIUM   equ 1907h ;unused
CONSOLE       equ 1908h
;$1909..$197F are unmapped
;$1980..$19BF are user-defined characters
;$19C0..$19F7 are unmapped
RESOLUTION    equ 19F8h ;also other uses
BGCOLOUR      equ 19F9h ;also other uses
SPRITES23CTRL equ 19FAh
SPRITES01CTRL equ 19FBh
BGCOLLIDE     equ 19FCh
SPRITECOLLIDE equ 19FDh
P2PADDLE      equ 19FEh
P1PADDLE      equ 19FFh ;unused
;                $1A00..$1ACF are lower screen display
;                $1AD0..$1AFF are user RAM
;                $1B00..$1FFF are unmapped
;                $2000..$7FFF can be ROM (last 24K of cartridge)
;Variable Equates---------------------------------------------------------
PARALYZED     equ 18D0h ;how long player must wait before getting control
                        ;(eg. when ship blowing up, or at start of level)
;                $18D1/$18D2: unknown
P2KEYSCOPY    equ 18D3h
;                $18D4/$18D5: alien bullets X-positions
;                $18D6/$18D7: unknown
;                $18D8/$18D9: diving aliens X-positions
;                $18DA/$18DB: unknown
;                $18DC/$18DD: diving aliens Y-positions
;                $18DE..$18E2: unknown
;                $18E3/$18E4: alien bullets Y-positions
SWARMX        equ 18E5h ;range of $01..$39
                ;$18E6: unknown
VOLUMECOPY    equ 18E7h
LIVES         equ 18E8h
FRAMECOUNT    equ 18E9h
;                $18EA..$18EC is player's score (one digit per nybble)
;                $18ED..$18EF is high score (likewise)
;                $18F8..$18FB are unused
P2PADDLECOPY  equ 1AD0h
GAME          equ 1AD1h ;selected game (0 = A, 1 = B)
OUTERTEMP     equ 1AD2h
INNERTEMP     equ 1AD3h ;used to preserve/restore r1
SWARMDELTAX   equ 1AD4h ;(-1 = going left, +1 = going right)
BONUSGIVEN    equ 1AD5h ;nonzero if bonus life (at 5000 points) has been given
;                $1AD6..$1AFF are unused
;-------------------------------------------------------------------------
        org     0000H
;
        eorz    r0           ;r0 = 0;
        bctr,un BOOT         ;goto BOOT;
;
	db	017H
;
BOOT:
        lpsu
        ppsu    020H         ;PSU |= %00100000;
	lpsl
        ppsl    002H         ;PSL |= %00000010;

        strz    r1           ;r1 = r0 [0]; // loop iterator
;clear memory
BOOT_1:
        stra,r0 1800h,r1     ;*(1800 + r1) = 0; // upper screen and RAM
        stra,r0 1900h,r1     ;*(1900 + r1) = 0; // hardware registers
        stra,r0 1A00h,r1     ;*(1A00 + r1) = 0; // lower screen and RAM
        birr,r1 BOOT_1       ;if (++r1 != 0) goto BOOT_1;
;end of loop

;set some hardware registers
        lodi,r0 0EFH         ;r0 = $EF;
        stra,r0 CRTCVPR      ;CRTCVPR = r0 [$EF];
        lodi,r0 040H         ;r0 = $40;
        stra,r0 RESOLUTION   ;RESOLUTION = r0 [$40];
        lodi,r0 0CFH         ;r0 = $CF;
        stra,r0 BGCOLOUR     ;BGCOLOUR = r0 [$CF];
        lodi,r0 0C2H         ;r0 = $C2;
        stra,r0 SPRITES23CTRL;SPRITES23CTRL = r0 [$C2];
        lodi,r0 044H         ;r0 = $44; // useless!
        nop
        nop
        nop

        lodi,r3 020H         ;r3 = $20; // loop iterator
;copy from $638..$657 (ROM data) to $19A0..$19BF (user-defined characters #0..#3)
BOOT_2:
        loda,r0 0637h,r3     ;r0 = *(637 + r3);
        stra,r0 199Fh,r3     ;*(199F + r3) = r0;
        bdrr,r3 BOOT_2       ;if (--r3 != 0) goto BOOT_2;
;end of loop

        lodi,r3 008H         ;r3 = 8; // loop iterator
;copy from $67A..$681 (ROM data) to $1990..$1997 (sprite #2)
BOOT_3:
        loda,r0 0679h,r3     ;r0 = *(679 + r3);
        stra,r0 198Fh,r3     ;*(198F + r3) = r0;
        bdrr,r3 BOOT_3       ;if (--r3 != 0) goto BOOT_3;
;end of loop

        bsta,un NEWSWARM     ;gosub NEWSWARM;
        bsta,un INITSHIP     ;gosub INITSHIP;

        lodi,r3 00AH         ;r3 = 10; // loop iterator
;copy from $660..$669 (ROM data) to $1AC0..$1AC9 (lower screen)
;print "UAL  GAME "
BOOT_4:
        loda,r0 065Fh,r3     ;r0 = *(65F + r3);
        stra,r0 1ABFh,r3     ;*(1ABF + r3) = r0;
        bdrr,r3 BOOT_4       ;if (--r3 != 0) goto BOOT_4;
;end of loop

;VOLUMECOPY = 15;
        lodi,r0 00FH         ;r0 = 15;
        stra,r0 VOLUMECOPY   ;VOLUMECOPY = r0 [15];

MAINLOOP:
        bstr,un L0068        ;calls READCONSOLE and TWINKLE
        bsta,un L02C2
	bsta,un	L0489
        bsta,un MOVESHIP

        bsta,un COLLDETECT                                              ;3

        bctr,un MAINLOOP
;end of loop
;Subroutine---------------------------------------------------------------
;diving aliens are done on even-numbered frames
;alien bullets are done on odd-numbered frames

L0068:
;once for each sprite
        lodi,r3 002H         ;r3 = 2; // outer loop iterator
L006A:
        strr,r3 *008Eh       ;*(*(8E)) = r3;
                             ;OUTERTEMP = r3; // user RAM
        lodi,r1 009H         ;r1 = 9; // yellow alien image
;look at *(18DC) or *(18DD), depending on which sprite
        loda,r0 18DBh,r3     ;r0 = *(18DB + r3); // user RAM
        andi,r0 003H         ;r0 &= %00000011;
        bctr,eq L0077        ;if (==) goto L0077;
;*(18DC) or *(18DD) is not evenly divisible by 4
        lodi,r1 011H         ;r1 = 17; // alien '2' image
L0077:
        lodr,r0 *0093h       ;r0 = *(*(93));
                             ;r0 = FRAMECOUNT; // user RAM
        andi,r0 001H         ;r0 &= %00000001;
        bctr,eq L007F        ;if (==) goto L007F;
;if an odd-numbered frame (alien bullets frame)
        lodi,r1 019H         ;r1 = 25; // alien bullet image
L007F:
;r1 is 9, 17 or 25
        loda,r0 0687h,r3     ;r0 = *(687 + r3);
        strz    r2           ;r2 = r0;

        lodi,r3 008H         ;r3 = 8; // inner loop iterator
L0085:
        loda,r0 0669h,r1-    ;r0 = *(669 + --r1); // ROM data
;source is $66A..$671 (yellow alien), $672..$679 (alien '2') or
;$67A..$681 (alien bullet), depending on r1
;destination is $1980..$1987 (sprite #0) or $1988.$198F (sprite #1),
;depending on r3
;note that the alien '2' image is always used for diving green/red aliens:
;the alien '1' image is only ever used for swarming aliens.
        stra,r0 1980h,r2-    ;*(1980 + --r2) = r0; // UDCs
        bdrr,r3 L0085        ;if (--r3 != 0) goto L0085;
;end of inner loop

        loda,r3 OUTERTEMP    ;r3 = OUTERTEMP; // user RAM
        lodi,r1 000H         ;r1 = 0;
        loda,r0 FRAMECOUNT   ;r0 = FRAMECOUNT; // user RAM
        andi,r0 001H         ;r0 &= %00000001;
        bctr,eq L009B        ;if (==) goto L009B;
        lodi,r1 004H         ;r1 = 4;
L009B:
        lodz    r1           ;r0 = r1;
        addz    r3           ;r0 += r3;
        loda,r0 18D3h,r0     ;r0 = *(18D3 + r0);
        rrl,r3               ;rotate r3 to the left once
        stra,r0 18EFh,r3     ;*(18EF + r3) = r0;
        rrr,r3               ;rotate r3 to the right once
        lodz    r1           ;r0 = r1;
        addz    r3           ;r0 += r3;
        loda,r0 18D5h,r0     ;r0 = *(18D5 + r0);
        eori,r0 0FFH         ;Exclusive OR r0 with %11111111 (flip all bits)
        rrl,r3               ;rotate r3 to the left once
        stra,r0 18EEh,r3     ;*(18EE + r3) = r0;
        rrr,r3               ;rotate r3 to the right once
        bdra,r3 L006A        ;if (--r3 != 0) goto L006A;
;end of outer loop

        lodi,r0 0C0H         ;r0 = %11000000;
        lodr,r1 *0093h       ;r1 = *(*(93));
                             ;r1 = FRAMECOUNT; // user RAM
        andi,r1 001H         ;r1 &= %00000001;
        bcfr,eq L00D3        ;if (!=) goto L00D3;
        loda,r0 18DCh        ;r0 = *(18DC); // user RAM
        andi,r0 003H         ;r0 &= %00000011;
        loda,r0 0682h,r0     ;r0 = *(682 + r0);
        strz    r1           ;r1 = r0;
        loda,r0 18DDh        ;r0 = *(18DD); // user RAM
        andi,r0 003H         ;r0 &= %00000011;
        loda,r0 0682h,r0     ;r0 = *(682 + r0); // ROM data
        rrl,r1               ;rotate r1 to the left thrice
	rrl,r1
	rrl,r1
        iorz    r1           ;r0 |= r1;
        iori,r0 0C0H         ;r0 |= $11000000;
L00D3:
        stra,r0 SPRITES01CTRL;SPRITES01CTRL = r0;

;wait for vertical blank
L00D6:
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bcfr,eq L00D6        ;if (!=) goto L00D6;
;end of loop

;P2PADDLECOPY = P2PADDLE;
        loda,r0 P2PADDLE     ;r0 = P2PADDLE;
        stra,r0 P2PADDLECOPY ;P2PADDLECOPY = r0;

;VOLUME = VOLUMECOPY;
        loda,r0 VOLUMECOPY   ;r0 = VOLUMECOPY;
        stra,r0 VOLUME       ;VOLUME = r0;
;zero offset for printing score line

;wait for lower nybble of CHARLINE to become 1
L00E6:
        loda,r0 CHARLINE     ;r0 = CHARLINE;
        andi,r0 00FH         ;r0 &= %00001111;
        comi,r0 001H         ;compare r0 against %00000001
        bcfr,eq L00E6        ;if (!=) goto L00E6;
;end of loop

;we want to look at the lower 3 bits of SWARMX
;(ie. the pixel offset from the character position)
        loda,r0 SWARMX       ;r0 = SWARMX; // user RAM
        rrr,r0               ;rotate r0 to the right thrice
	rrr,r0
	rrr,r0
        andi,r0 0E0H         ;r0 &= %11100000;
        iorr,r0 *00E1h       ;r0 |= *(*(E1));
                             ;r0 |= VOLUMECOPY; // user RAM

;swarm offset for drawing swarm aliens
        strr,r0 *00E4h       ;*(*(E4)) = r0;
                             ;VOLUME = r0;

        bsta,un READCONSOLE  ;gosub READCONSOLE;
        bsta,un TWINKLE      ;gosub TWINKLE;

;wait for lower nybble of CHARLINE to become 7
L0101:
        lodr,r0 *00E7h       ;r0 = *(*(E7));
                             ;r0 = CHARLINE;
        andi,r0 00FH         ;r0 &= %00001111;
        comi,r0 007H         ;compare r0 against %00000111
        bctr,lt L0101        ;if (<) goto L0101;
;end of loop

;zero offset for starfield, etc.
;this prevents the lower part of the screen from moving
;VOLUME = VOLUMECOPY;
        lodr,r0 *00E1h       ;r0 = *(*(E1));
                             ;r0 = VOLUMECOPY; // user RAM
        strr,r0 *00E4h       ;*(*(E4)) = r0;
                             ;VOLUME = r0;

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
READCONSOLE:
        loda,r0 LIVES        ;r0 = LIVES; // user RAM
        bcfa,eq READCONSOLE_5;if (!=) goto READCONSOLE_5;
        loda,r0 CONSOLE      ;r0 = CONSOLE;
        tmi,r0  001H         ;test mask %00000001 of r0
        bcfr,eq READCONSOLE_2;if (!=) goto READCONSOLE_2;

;START has been pressed
        lodi,r0 003H         ;r0 = 3;
        strr,r0 *010Fh       ;*(*(10F)) = r0 [3];
                             ;LIVES = r0 [3]; // user RAM
        bsta,un NEWSWARM     ;gosub NEWSWARM;
        bsta,un INITSHIP     ;gosub INITSHIP;
        lodi,r0 001H         ;r0 = 1;
        stra,r0 18E6h        ;*(18E6) = r0 [1]; // user RAM
        eorz    r0           ;r0 = 0;
        stra,r0 BONUSGIVEN   ;BONUSGIVEN = r0 [0]; // user RAM
        lodi,r0 00FH         ;r0 = 15;
        stra,r0 VOLUMECOPY   ;VOLUMECOPY = r0 [15]; // user RAM
        lodi,r0 003H         ;r0 = 3;
        stra,r0 PARALYZED    ;PARALYZED = r0 [3]; // user RAM

        lodi,r3 003H         ;r3 = 3; // loop iterator
        eorz    r0           ;r0 = 0;
;clear user RAM in range $18EA..$18EC (player's score)
READCONSOLE_1:
        stra,r0 18E9h,r3     ;*(18E9 + r3) = r0 [0]; // user RAM
        bdrr,r3 READCONSOLE_1;if (--r3 != 0) goto READCONSOLE_1;
;end of loop

        bctr,un READCONSOLE_5;goto READCONSOLE_5;

READCONSOLE_2:
;START has not been pressed
        lodi,r1 000H         ;r1 = 0; // game 'A'
        tmi,r0  002H         ;test mask %00000010 of r0
        bctr,eq READCONSOLE_3;if (==) goto READCONSOLE_3;
;OPTION has not been pressed
        lodi,r1 001H         ;r1 = 1; // game 'B'
        andi,r0 004H         ;r0 &= %00000100;
        bctr,eq READCONSOLE_5;if (==) goto READCONSOLE_5;
;DIFFICULTY has been pressed
READCONSOLE_3:
;OPTION or DIFFICULTY has been pressed
        stra,r1 GAME         ;GAME = r1; // user RAM

        eorz    r0           ;r0 = 0;
        lodi,r3 003H         ;r3 = 3; // loop iterator
;clear user RAM in range $18ED..$18EF
READCONSOLE_4:
        stra,r0 18ECh,r3     ;*(18EC + r3) = r0 [0]; // user RAM
        bdrr,r3 READCONSOLE_4;if (--r3 != 0) goto READCONSOLE_4;
;end of loop

READCONSOLE_5:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
COLLDETECT:

;if (LIVES == 0) return;
        loda,r0 LIVES        ;r0 = LIVES;
        bcta,eq COLLDETECT_16;if (==) goto COLLDETECT_16;

;if (PARALYZED != 0) return;
        loda,r0 PARALYZED    ;r0 = PARALYZED; // user RAM
        bcfa,eq COLLDETECT_16;if (!=) goto COLLDETECT_16;

        loda,r0 BGCOLLIDE    ;r0 = BGCOLLIDE;
;test sprite #2 (player's bullet) for background collision
        tmi,r0  004H         ;test mask %00000100 of r0 (sprite #2-background collisions)
        bcta,eq COLLDETECT_1 ;if (==) goto COLLDETECT_1;

;we have a collision
        loda,r1 SPRITE2Y     ;r1 = SPRITE2Y;
        eori,r1 0FFH         ;Exclusive OR r1 with %11111111 (flip all bits)
        comi,r1 050H         ;compare r1 against $50
        bcta,gt COLLDETECT_1 ;if (>) goto COLLDETECT_1;
        subi,r1 01CH         ;r1 -= $1C;
        rrr,r1               ;rotate r1 to the right thrice
	rrr,r1
	rrr,r1
        andi,r1 00FH         ;r1 &= %00001111;

;ascertain which alien was hit
        loda,r0 068Ah,r1     ;r0 = *(68A + r1);
        bsta,un HANDLESCORE  ;gosub HANDLESCORE;
        loda,r0 SPRITE2X     ;r0 = SPRITE2X;
        suba,r0 SWARMX       ;r0 -= SWARMX;
        subi,r0 02AH         ;r0 -= $2A;
        rrr,r0               ;rotate r0 to the right thrice
	rrr,r0
	rrr,r0
;now we have 'how many characters to the right of the left edge of the swarm the bullet is'
        andi,r0 00FH         ;r0 &= %00001111;
        rrl,r1               ;rotate r1 to the left quarce
	rrl,r1
	rrl,r1
	rrl,r1
        addz    r1           ;r0 += r1;
        loda,r1 SWARMX       ;r1 = SWARMX; // user RAM
        rrr,r1               ;rotate r1 to the right thrice
	rrr,r1
	rrr,r1
        andi,r1 00FH         ;r1 &= %00001111;
        addz    r1           ;r0 += r1;
        strz    r1           ;r1 = r0;
;destroy the swarm alien
;r1 is the character offset of the alien from $1820
        eorz    r0           ;r0 = 0;
        stra,r0 1820h,r1     ;*(1820 + r1) = r0 [0];

;SPRITE2X = $E4;
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 SPRITE2X     ;SPRITE2X = r0 [$E4];

;*(18E1) = 8;
        lodi,r0 008H         ;r0 = 8;
        stra,r0 18E1h        ;*(18E1) = r0 [8];

COLLDETECT_1:
        loda,r2 SPRITECOLLIDE;r2 = SPRITECOLLIDE;
        lodi,r3 000H         ;r3 = 0;
;test for sprite #0/#2 collision (alien/alien bullet vs. player's bullet)
        tmi,r2  002H         ;test mask %00000010 of r2 (sprite #0-#2 collisions)
        bcfr,eq COLLDETECT_2 ;if (!=) goto COLLDETECT_3;

;we have a collision
        lodi,r3 001H         ;r3 = 1;
;test for sprite #1/#2 collision (alien/alien bullet vs. player's bullet)
        tmi,r2  008H         ;test mask %00001000 of r2 (sprite #1-#2 collision)
        bcta,eq COLLDETECT_7 ;if (==) goto COLLDETECT_7;
COLLDETECT_2:
;r3 is 0 or 1, for sprite #0 or #1 respectively
        loda,r0 FRAMECOUNT   ;r0 = FRAMECOUNT; // user RAM
        andi,r0 001H         ;r0 &= %00000001;
        bctr,eq COLLDETECT_5 ;if (==) goto COLLDETECT_5;

;this is an odd-numbered frame (alien bullets frame)
;player bullet-alien bullet collision (destroy alien bullet)
;$E4 is the X-value used for offscreen sprites
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D4h,r3     ;*(18D4 + r3) = r0 [$E4]; // user RAM

        lodi,r0 032H         ;r0 = $32;
        stra,r0 18E3h,r3     ;*(18E3 + r3) = r0 [$32]; // user RAM

        loda,r0 18DCh,r3     ;r0 = *(18DC + r3); // user RAM
        andi,r0 003H         ;r0 &= %00000011;
        bctr,eq COLLDETECT_3 ;if (==) goto COLLDETECT_3;
        loda,r0 068Ah,r0     ;r0 = *(68A + r0); // ROM data
        bctr,un COLLDETECT_4 ;goto COLLDETECT_4;
;
COLLDETECT_3:
        lodi,r0 0A0H         ;r0 = $A0;
COLLDETECT_4:
        strz    r1           ;r1 = r0;
        bsta,un HANDLESCORE  ;gosub HANDLESCORE;
        lodz    r1           ;r0 = r1;
        bstr,un *01E0h       ;INFO: indirect jump
                             ;gosub *(01E0);
                             ;gosub HANDLESCORE;

;*(18E1) = 8;
        lodi,r0 008H         ;r0 = 8;
        stra,r0 18E1h        ;*(18E1) = r0 [8]; // user RAM

        bctr,un COLLDETECT_6 ;goto COLLDETECT_6;
;
COLLDETECT_5:
;this is an even-numbered frame (aliens frame)
;player bullet-alien collision (destroy alien)
;destroy alien
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D8h,r3     ;*(18D8 + r3) = r0 [$E4];

COLLDETECT_6:
;destroy player's bullet
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 SPRITE2X     ;SPRITE2X = r0 [$E4];
COLLDETECT_7:
        lodi,r3 000H         ;r3 = 0;
;test for sprite #0/#3 collision (alien or alien bullet vs. player's ship)
        tmi,r2  004H         ;test mask %00000100 of r2
        bcfr,eq COLLDETECT_8 ;if (!=) goto COLLDETECT_8;
        lodi,r3 001H         ;r3 = 1;
;test for sprite #1/#3 collision (alien or alien bullet vs. player's ship)
        tmi,r2  010H         ;test mask %00010000 of r2
        bcta,eq COLLDETECT_16;if (==) goto COLLDETECT_16;

COLLDETECT_8:
;alien or alien bullet has collided with player's ship
        loda,r0 FRAMECOUNT   ;r0 = FRAMECOUNT; // user RAM
        andi,r0 001H         ;r0 &= %00000001;
        bctr,eq COLLDETECT_9 ;if (==) goto COLLDETECT_9;

;this is an odd-numbered frame (alien bullets)
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D4h,r3     ;*(18D4 + r3) = r0 [$E4];
        bctr,un COLLDETECT_10 ;goto COLLDETECT_10;

COLLDETECT_9:
;this is an even-numbered frame (aliens)
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D8h,r3     ;*(18D8 + r3) = r0 [$E4];

COLLDETECT_10:
;player has been blown up
;LIVES--;
        loda,r0 LIVES        ;r0 = LIVES;
        subi,r0 001H         ;r0--;
        strr,r0 *0217h       ;*(*(217)) = r0;
                             ;LIVES = r0;

        bcfr,eq COLLDETECT_15;if (!=) goto COLLDETECT_15;

        lodi,r3 009H         ;r3 = 9; // loop iterator
;print "GAME OVER"
COLLDETECT_11:
        loda,r0 068Fh,r3     ;r0 = *(68F + r3); // ROM data
        stra,r0 1A13h,r3     ;*(1A13 + r3) = r0; // lower screen
        bdrr,r3 COLLDETECT_11;if (--r3 != 0) goto COLLDETECT_11;
;end of loop

        lodi,r3 000H         ;r3 = 0; // loop iterator
COLLDETECT_12:
        loda,r0 18EAh,r3     ;r0 = *(18EA + r3); // user RAM
        coma,r0 18EDh,r3     ;compare r0 against *(18ED + r3) // user RAM
        bctr,gt COLLDETECT_13;if (>) goto COLLDETECT_13;
        bcfr,eq COLLDETECT_15;if (!=) goto COLLDETECT_15;
;scores are equal so far, need to compare less significant pairs of digits
        addi,r3 001H         ;r3++;
        comi,r3 003H         ;compare r3 against 3
        bctr,lt COLLDETECT_12;if (<) goto COLLDETECT_12;
;end of loop

COLLDETECT_13:
        lodi,r3 003H         ;r3 = 3; // loop iterator
;copy player's score to high score
COLLDETECT_14:
        loda,r0 18E9h,r3     ;r0 = *(18E9 + r3);
        stra,r0 18ECh,r3     ;*(18EC + r3) = r0;
        bdrr,r3 COLLDETECT_14;if (--r3 != 0) goto COLLDETECT_14;
;end of loop

COLLDETECT_15:
;PARALYZED = 5;
        lodi,r0 005H         ;r0 = 5;
        stra,r0 PARALYZED    ;PARALYZED = r0 [5]; // user RAM

;VOLUMECOPY = 23;
        lodi,r0 017H         ;r0 = 23;
        stra,r0 VOLUMECOPY   ;VOLUMECOPY = r0 [23]; // user RAM

COLLDETECT_16:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
MOVESHIP:
;moves the player's ship and creates/moves player's bullets

;if (LIVES == 0) return;
        loda,r0 LIVES        ;r0 = LIVES;
        bcta,eq MOVESHIP_5   ;if (==) goto MOVESHIP_5;

;if (PARALYZED != 0) return;
        loda,r0 PARALYZED    ;r0 = PARALYZED;
        bcfa,eq MOVESHIP_5   ;if (!=) goto MOVESHIP_5;

        loda,r0 P2PADDLECOPY ;r0 = P2PADDLECOPY;
        lodi,r1 0FFH         ;r1 = $FF;
        lodi,r1 0FFH         ;r1 = $FF; // useless!
        comi,r0 050H         ;compare r0 against $50
        bctr,lt MOVESHIP_1   ;if (<) goto MOVESHIP_1;
        lodi,r1 000H         ;r1 = 0;
        comi,r0 0A0H         ;compare r0 against $A
        bctr,lt MOVESHIP_1   ;if (<) goto MOVESHIP_1;
        lodi,r1 001H         ;r1 = 1;
MOVESHIP_1:
        loda,r0 SPRITE3X     ;r0 = SPRITE3X;
        addz    r1           ;r0 += r1;
        comi,r0 02BH         ;compare r0 against $2B
        bctr,lt MOVESHIP_2   ;if (<) goto MOVESHIP_2;
        comi,r0 02CH         ;compare r0 against $2C
        bctr,gt MOVESHIP_2   ;if (>) goto MOVESHIP_2;
        lodi,r0 02CH         ;r0 = $2C;
MOVESHIP_2:
        comi,r0 0A4H         ;compare r0 against $A4
        bctr,lt MOVESHIP_3   ;if (<) goto MOVESHIP_3;
        lodi,r0 0A4H         ;r0 = $A4;
MOVESHIP_3:
        strr,r0 *0270h       ;*(*(270)) = r0;
                             ;SPRITE3X = r0;
        loda,r1 P2MIDDLEKEYS ;r1 = P2MIDDLEKEYS;
        andi,r1 00FH         ;r1 &= %00001111;
        loda,r0 P2KEYSCOPY   ;r0 = P2KEYSCOPY; // user RAM
        bcfr,eq MOVESHIP_4   ;if (!=) goto MOVESHIP_4;
        lodr,r0 *029Fh       ;r0 = *(*(29F));
                             ;r0 = SPRITE2X; // user RAM
        comi,r0 0E3H         ;compare r0 against $E3
;if player's bullet is onscreen, skip ahead
        bctr,lt MOVESHIP_4   ;if (<) goto MOVESHIP_4;
;if player has not just pressed fire, skip ahead
        andi,r1 00FH         ;r1 &= %00001111;
        bctr,eq MOVESHIP_4   ;if (==) goto MOVESHIP_4;

;create new bullet
;SPRITE2X = SPRITE3X + 3;
        loda,r0 SPRITE3X     ;r0 = SPRITE3X;
        addi,r0 003H         ;r0 += 3;
        stra,r0 SPRITE2X     ;SPRITE2X = r0;

;SPRITE2Y = $3F;
        lodi,r0 03FH         ;r0 = $3F;
        stra,r0 SPRITE2Y     ;SPRITE2Y = r0 [$3F];

;*(18E1) = $18;
        lodi,r0 018H         ;r0 = $18;
        stra,r0 18E1h        ;*(18E1) = r0; // user RAM

MOVESHIP_4:
;bullet moving routine
        strr,r1 *028Bh       ;*(*(28B)) = r1;
                             ;P2KEYSCOPY = r1; // user RAM
MOVESHIP_5:
        lodr,r0 *029Fh       ;r0 = *(*(29F));
                             ;r0 = SPRITE2X;
        comi,r0 0E3H         ;compare r0 against $E3
;if no bullet onscreen, return to caller
        bctr,gt MOVESHIP_7   ;if (>) goto MOVESHIP_7;

        lodr,r0 *02A4h       ;r0 = *(*(2A4));
                             ;r0 = SPRITE2Y;
;move bullet upwards
        addi,r0 004H         ;r0 += 4;
        comi,r0 0E7H         ;compare r0 against $E7
        bctr,lt MOVESHIP_6   ;if (<) goto MOVESHIP_6;

;bullet has reached top of screen (and missed everything)
        lodi,r1 0E4H         ;r1 = $E4;
        strr,r1 *029Fh       ;*(*(29F)) = r1 [$E4];
                             ;SPRITE2X = r1 [$E4];

MOVESHIP_6:
        strr,r0 *02A4h       ;*(*(2A4)) = r0;
                             ;SPRITE2Y = r0;
MOVESHIP_7:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L02C2:
        loda,r0 18E2h        ;r0 = *(18E2); // user RAM
        bcfa,eq L030A        ;if (!=) goto L030A;
        lodi,r0 019H         ;r0 = 25;
        strr,r0 *02C3h       ;*(*(2C3)) = r0 [25];
                             ;*(18E2) = r0 [25]; // user RAM

        loda,r0 SWARMX       ;r0 = SWARMX; // user RAM
        lodr,r1 *02E1h       ;r1 = *(*(2E1);
                             ;r1 = SWARMDELTAX; // user RAM
        addz    r1           ;r0 += r1;

;decide whether the swarm is at the extreme left or right of the screen
        comi,r0 039H         ;compare r0 against $39
        bctr,lt L02D8        ;if (<) goto L02D8;
        lodi,r1 0FFH         ;r1 = -1;
L02D8:
        comi,r0 001H         ;compare r0 against 1
        bctr,gt L02DE        ;if (>) goto L02DE;
        lodi,r1 001H         ;r1 = 1;
L02DE:
        strr,r0 *02CDh       ;*(*(2CD)) = r0;
                             ;SWARMX = r0; // user RAM
        stra,r1 1AD4h        ;SWARMDELTAX = r1; // user RAM
        comi,r1 001H         ;compare r1 against 1
        bcfr,eq L02F7        ;if (!=) goto L02F7;
;we are going right
;extract pixel offset of SWARMX
        andi,r0 007H         ;r0 &= %00000111;
;if nonzero, branch
        bcfr,eq L030A        ;if (!=) goto L030A;

;pixel offset of SWARMX is 0
        lodi,r2 060H         ;r2 = $60; // loop iterator
;move alien swarm to the right
L02ED:
        loda,r0 181Eh,r2     ;r0 = *(181E + r2); // upper screen
        stra,r0 181Fh,r2     ;*(181F + r2) = r0; // upper screen
        bdrr,r2 L02ED        ;if (--r2 != 0) goto L02ED;
;end of loop

        bctr,un L0307        ;goto L0307; // inefficient! (double jump)
;
L02F7:
;we are going left
;extract pixel offset of SWARMX
        andi,r0 007H         ;r0 &= %00000111;
;if not 7, branch
        comi,r0 007H         ;compare r0 against 7
        bcfr,eq L0307        ;if (!=) goto L0307; // inefficient! (double jump)

;pixel offset of SWARMX is 7
        lodi,r2 0A3H         ;r2 = $A3; // loop iterator
;move alien swarm to the left
L02FF:
        loda,r0 1781h,r2     ;r0 = *(1781 + r2); // upper screen
        stra,r0 1780h,r2     ;*(1780 + r2) = r0; // upper screen
        birr,r2 L02FF        ;if (++r2 != 0) goto L02FF;
;end of loop

L0307:
        bcta,un L0488        ;goto L0488;

L030A:
        loda,r3 FRAMECOUNT   ;r3 = FRAMECOUNT; // user RAM
        andi,r3 001H         ;r3 &= %00000001;
        loda,r0 18D4h,r3     ;r0 = *(18D4 + r3); // user RAM
        comi,r0 0E3H         ;compare r0 against $E3
        bcta,lt L03CD        ;if (<) goto L03CD;

;if (LIVES == 0) goto L044C;
        loda,r0 LIVES        ;r0 = LIVES; // user RAM
        bcta,eq L044C        ;if (==) goto L044C;

;if (PARALYZED != 0) goto L044C;
        loda,r0 PARALYZED    ;r0 = PARALYZED; // user RAM
        bcfa,eq L044C        ;if (!=) goto L044C;

        loda,r0 18E3h,r3     ;r0 = *(18E3 + r3); // user RAM
        bcfa,eq L044C        ;if (!=) goto L044C;

        lodi,r1 006H         ;r1 = 6; // outer loop iterator
L032B:
        stra,r1 OUTERTEMP    ;OUTERTEMP = r1; // user RAM
        loda,r0 0698h,r1     ;r0 = *(698 + r1); // ROM data
;r0 is 0, 1, 2, 5, 4 or 3 for values of r1 from 1..6 respectively
        loda,r2 18D1h        ;r2 = *(18D1); // user RAM
        bcfr,eq L0344        ;if (!=) goto L0344;
        lodi,r0 00AH         ;r0 = 10;
        strr,r0 *0332h       ;*(*(332)) = r0 [10];
                             ;*(18D1) = r0 [10]; // user RAM
;r0 is 0, 5, 4, 3, 2 or 1 for values of r1 from 1..6 respectively
        loda,r0 069Eh,r1     ;r0 = *(69E + r1); // ROM data
        comi,r3 000H         ;compare r3 against 0
        bcfr,eq L0344        ;if (!=) goto L0344;
;this is an even-numbered frame
        loda,r0 06A4h,r1     ;r0 = *(6A4 + r1);
;r0 is 5, 4, 3, 2, 1 or 0 for values of r1 from 1..6 respectively
L0344:
;store r0 in *(18D6) or *(18D7) depending on whether even or odd frame
        stra,r0 18D6h,r3     ;*(18D6 + r3) = r0; // user RAM

        lodi,r1 009H         ;r1 = 9; // inner loop iterator
L0349:
        stra,r1 INNERTEMP    ;INNERTEMP = r1; // user RAM
        loda,r0 06AAh,r1     ;r0 = *(6AA + r1); // ROM data
        comi,r2 000H         ;compare r2 against 0
        bcfr,eq L035D        ;if (!=) goto L035D;
        loda,r0 06B3h,r1     ;r0 = *(6B3 + r1); // ROM data
        comi,r3 000H         ;compare r3 against 0
        bcfr,eq L035D        ;if (!=) goto L035D;
        loda,r0 06BCh,r1     ;r0 = *(6BC + r1); // ROM data
L035D:
        stra,r0 18D2h        ;*(18D2) = r0; // user RAM

;r3 is either 0 or 1 at this point
;r0 = *(18D6) or *(18D7);
        loda,r0 18D6h,r3     ;r0 = *(18D6 + r3); // user RAM
        rrl,r0               ;rotate r0 to the left quarce
	rrl,r0
	rrl,r0
	rrl,r0

        adda,r0 18D2h        ;r0 += *(18D2); // user RAM

;*(18DE) or *(18DF) = r0;
        stra,r0 18DEh,r3     ;*(18DE + r3) = r0; // user RAM

        loda,r1 SWARMX       ;r1 = SWARMX; // user RAM
        rrr,r1               ;rotate r1 to the right thrice
	rrr,r1
	rrr,r1
        andi,r1 00FH         ;r1 &= %00000001;
        addz    r1           ;r0 += r1;
        strz    r1           ;r1 = r0;

        loda,r0 1820h,r1     ;r0 = *(1820 + r1); // upper screen
        bctr,eq L03A6        ;if (==) goto L03A6;

        eorz    r0           ;r0 = 0;
        stra,r0 1820h,r1     ;*(1820 + r1) = r0 [0]; // upper screen

        loda,r0 18D2h        ;r0 = *(18D2); // user RAM
        strz    r1           ;r1 = r0;
        rrl,r0               ;rotate r0 to the left thrice
	rrl,r0
	rrl,r0
        addi,r0 02CH         ;r0 += $2C;
        addr,r0 *036Eh       ;r0 += *(*(36E));
                             ;r0 += SWARMX; // user RAM
        stra,r0 18D4h,r3     ;*(18D4 + r3) = r0; // user RAM
        loda,r0 18D6h,r3     ;r0 = *(18D6 + r3); // user RAM
        strz    r2           ;r2 = r0;
        rrl,r0               ;rotate r0 to the left thrice
	rrl,r0
	rrl,r0
        addi,r0 020H         ;r0 += $20;
        stra,r0 18D6h,r3     ;*(18D6 + r3) = r0; // user RAM
        loda,r0 06FCh,r2     ;r0 = *(6FC + r2); // ROM data
        iora,r0 06C6h,r1     ;r0 |= *(6C6 + r1); // ROM data
        stra,r0 18DCh,r3     ;*(18DC + r3) = r0; // user RAM
        bcta,un L0307        ;goto L0307;
;
L03A6:
        loda,r1 INNERTEMP    ;r1 = INNERTEMP; // user RAM
        bdra,r1 L0349        ;if (--r1 != 0) goto L0349;
;end of inner loop

        loda,r1 OUTERTEMP    ;r1 = OUTERTEMP; // user RAM
        bdra,r1 L032B        ;if (--r1 != 0) goto L032B;
;end of outer loop

        loda,r0 18D4h        ;r0 = *(18D4); // user RAM
        comi,r0 0E3H         ;compare r0 against $E3
        bcta,lt L0307        ;if (<) goto L0307;
        loda,r0 18D5h        ;r0 = *(18D5); // user RAM
        comi,r0 0E3H         ;compare r0 against $E3
        bcta,lt L0307        ;if (<) goto L0307;

;new level
        bsta,un NEWSWARM     ;gosub NEWSWARM;

;PARALYZED = 3;
        lodi,r0 003H         ;r0 = 3;
        stra,r0 PARALYZED    ;PARALYZED = r0 [3]; // user RAM

        bcta,un L0307        ;goto L0307;
;
L03CD:
        loda,r2 FRAMECOUNT   ;r2 = FRAMECOUNT; // user RAM
        comi,r2 001H         ;compare r2 against 1
        bctr,gt L03F0        ;if (>) goto L03F0;
        loda,r0 18D6h,r3     ;r0 = *(18D6 + r3); // user RAM
        comi,r0 090H         ;compare r0 against $90
        bctr,gt L03F0        ;if (>) goto L03F0;
        lodi,r1 000H         ;r1 = 0;
        loda,r0 SPRITE3X     ;r0 = SPRITE3X;
        coma,r0 18D4h,r3     ;compare r0 against *(18D4 + r3); // user RAM
        bctr,gt L03E7        ;if (>) goto L03E7;
        lodi,r1 080H         ;r1 = $80;
L03E7:
        loda,r0 18DCh,r3     ;r0 = *(18DC + r3); // user RAM
        andi,r0 003H         ;r0 &= %00000011;
        iorz    r1           ;r0 |= r1;
        stra,r0 18DCh,r3     ;*(18DC + r3) = r0; // user RAM
L03F0:
        loda,r0 18DCh,r3     ;r0 = *(18DC + r3); // user RAM
        strz    r1           ;r1 = r0;
        loda,r0 18DCh,r3     ;r0 = *(18DC + r3); // user RAM
        rrl,r0               ;rotate r0 to the left once
        andi,r0 001H         ;r0 &= %00000001;
        loda,r2 GAME         ;r2 = GAME; // user RAM
        rrl,r2               ;rotate r2 to the left once
        addz    r2           ;r0 += r2;
        loda,r0 06CFh,r0     ;r0 = *(6CF + r0); // ROM data
        adda,r0 18D4h,r3     ;r0 += *(18D4 + r3); // user RAM
        comi,r0 02CH         ;compare r0 against $2C
        bctr,gt L040D        ;if (>) goto L040D;
        eori,r1 080H         ;Exclusive OR r1 with %10000000 (flip bit 7)
        lodi,r0 02CH         ;r0 = $2C;
L040D:
        comi,r0 0A4H         ;compare r0 against $A4
        bctr,lt L0415        ;if (<) goto L0415;
        eori,r1 080H         ;Exclusive OR r1 with %10000000 (flip bit 7)
        lodi,r0 0A4H         ;r0 = $A4;
L0415:
        stra,r0 18D4h,r3     ;*(18D4 + r3) = r0; // user RAM
        lodz    r1           ;r0 = r1;
        stra,r0 18DCh,r3     ;*(18DC + r3) = r0; // user RAM
        lodr,r0 *03FBh       ;r0 = *(*(3FB));
                             ;r0 = GAME; // user RAM
        loda,r0 06D3h,r0     ;r0 = *(6D3 + r0); // ROM data
        adda,r0 18D6h,r3     ;r0 += *(18D6 + r3); // user RAM
        stra,r0 18D6h,r3     ;*(18D6 + r3) = r0; // user RAM
        comi,r0 0D0H         ;compare r0 against $D0
        bctr,lt L044C        ;if (<) goto L044C;
        loda,r0 SWARMX       ;r0 = SWARMX; // user RAM
        rrr,r0               ;rotate r0 to the right thrice
	rrr,r0
	rrr,r0
        andi,r0 00FH         ;r0 &= %00001111;
        adda,r0 18DEh,r3     ;r0 += *(18DE + r3); // user RAM
        strz    r2           ;r2 = r0;
        loda,r0 18DCh,r3     ;r0 = *(18DC + r3); // user RAM
        andi,r0 003H         ;r0 &= %00000011;
        loda,r0 0702h,r0     ;r0 = *(702 + r0); // ROM data
        stra,r0 1820h,r2     ;*(1820 + r2) = r0; // upper screen
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D4h,r3     ;*(18D4 + r3) = r0 [$E4]; // user RAM
        lodi,r0 032H         ;r0 = $32;
        stra,r0 18E3h,r3     ;*(18E3 + r3) = r0 [$32]; // user RAM
L044C:
        loda,r0 LIVES        ;r0 = LIVES; // user RAM
        bctr,eq L0477        ;if (==) goto L0477;
        loda,r0 18D0h        ;r0 = *(18D0); // user RAM
        bcfr,eq L0477        ;if (!=) goto L0477;
        loda,r0 18D8h,r3     ;r0 = *(18D8 + r3); // user RAM
        comi,r0 0E4H         ;compare r0 against $E4
        bctr,lt L0477        ;if (<) goto L0477;
        loda,r0 18D6h,r3     ;r0 = *(18D6 + r3); // user RAM
        comi,r0 050H         ;compare r0 against $50
        bctr,lt L0488        ;if (<) goto L0488;
        comi,r0 0D0H         ;compare r0 against $D0
        bctr,gt L0488        ;if (>) goto L0488;
        addi,r0 008H         ;r0 += 8;
        stra,r0 18DAh,r3     ;*(18DA + r3) = r0; // user RAM
        loda,r0 18D4h,r3     ;r0 = *(18D4 + r3); // user RAM
        addi,r0 003H         ;r0 += 3;
        stra,r0 18D8h,r3     ;*(18D8 + r3) = r0; // user RAM
        bctr,un L0488        ;goto L0488;
;
L0477:
        loda,r0 18DAh,r3     ;r0 = *(18DA + r3); // user RAM
        addi,r0 004H         ;r0 += 4;
        stra,r0 18DAh,r3     ;*(18DA + r3) = r0; // user RAM
        comi,r0 0D0H         ;compare r0 against $D0
        bctr,lt L0488        ;if (<) goto L0488;
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D8h,r3     ;*(18D8 + r3) = r0 [$E4]; // user RAM
L0488:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0489:
        loda,r2 FRAMECOUNT   ;r2 = FRAMECOUNT; // user RAM
        addi,r2 001H         ;r2++;
        comi,r2 032H         ;compare r2 against 50
        bctr,lt L04A2        ;if (<) goto L04A2;

        lodi,r3 002H         ;r3 = 2; // loop iterator
L0494:
;this deals with PARALYZED and *(18D1)
        loda,r0 18CFh,r3     ;r0 = *(18CF + r3); // user RAM
        bctr,eq L049E        ;if (==) goto L049E;
        subi,r0 001H         ;r0--;
        stra,r0 18CFh,r3     ;*(18CF + r3) = r0;
L049E:
        bdrr,r3 L0494        ;if (--r3 != 0) goto L0494;
;end of loop

        lodi,r2 000H         ;r2 = 0;
L04A2:
        strr,r2 *048Ah       ;*(*(48A)) = r2;
                             ;FRAMECOUNT = r2; // user RAM
        lodi,r2 008H         ;r2 = 8;
        loda,r0 VOLUMECOPY   ;r0 = VOLUMECOPY; // user RAM
        comi,r0 017H         ;compare r0 against $17
        bcta,eq L04F8        ;if (==) goto L04F8;
        lodi,r2 000H         ;r2 = 0;
        loda,r0 LIVES        ;r0 = LIVES;
        bctr,eq L04D5        ;if (==) goto L04D5;
        loda,r0 18D0h        ;r0 = *(18D0); // user RAM
        bcfr,eq L04D5        ;if (!=) goto L04D5;
        loda,r2 18D6h        ;r2 = *(18D6); // user RAM
        loda,r0 18D4h        ;r0 = *(18D4); // user RAM
        comi,r0 0E3H         ;compare r0 against $E3
        bctr,lt L04D3        ;if (<) goto L04D3;
        loda,r2 18D7h        ;r2 = *(18D7); // user RAM
        loda,r0 18D5h        ;r0 = *(18D5); // user RAM
        comi,r0 0E3H         ;compare r0 against $E3
        bctr,lt L04D3        ;if (<) goto L04D3;
        loda,r2 FRAMECOUNT   ;r2 = FRAMECOUNT; // user RAM
        addi,r2 032H         ;r2 += $32;
L04D3:
        andi,r2 07FH         ;r2 &= %01111111;
L04D5:
        loda,r0 18E1h        ;r0 = *(18E1); // user RAM
        bctr,eq L04DF        ;if (==) goto L04DF;
        eori,r0 0FFH         ;Exlusive OR r0 with %11111111 (flip all bits)
        andi,r0 00FH         ;r0 &= %00001111;
        strz    r2           ;r2 = r0;
L04DF:
        loda,r1 18E6h        ;r1 = *(18E6); // user RAM
        loda,r0 06DBh,r1     ;r0 = *(6DB + r1); // ROM data
        bctr,eq L04F8        ;if (==) goto L04F8;
        loda,r0 18E0h        ;r0 = *(18E0); // user RAM
        bcfr,eq L04FB        ;if (!=) goto L04FB;
        addi,r1 001H         ;r1++;
        strr,r1 *04E0h       ;*(*(4E0)) = r1;
                             ;*(18E6) = r1;
        loda,r0 06DBh,r1     ;r0 = *(6DB + r1); // ROM data
        strz    r2           ;r2 = r0;
        lodi,r0 007H         ;r0 = 7;
        strr,r0 *04E8h       ;*(*(4E8)) = r0;
                             ;*(18E0) = r0;
L04F8:
        stra,r2 PITCH        ;PITCH = r2;

L04FB:
        lodi,r3 006H         ;r3 = 6; // loop iterator
;print score
L04FD:
        loda,r0 06D4h,r3     ;r0 = *(6D4 + r3); // ROM data
        strz    r2           ;r2 = r0;
;$18EA..$18EC is player's score
;$18ED..$18EF is high score
        loda,r0 18E9h,r3     ;r0 = *(18E9 + r3); // user RAM
        strz    r1           ;r1 = r0;
        rrr,r0               ;rotate r0 to the right quarce
	rrr,r0
	rrr,r0
	rrr,r0
        andi,r0 00FH         ;r0 &= %00001111;
;set text colour
        iori,r0 010H         ;r0 |= %00010000;
;print digit
        stra,r0 1800h,r2     ;*(1800 + r2) = r0; // upper display
        lodz    r1           ;r0 = r1;
        andi,r0 00FH         ;r0 &= %00001111;
        iori,r0 010H         ;r0 |= %00010000;
        stra,r0 1801h,r2     ;*(1801 + r2) = r0; // upper display
        bdrr,r3 L04FD        ;if (--r3 != 0) goto L04FD;
;end of loop

        lodi,r3 005H         ;r3 = 5; // loop iterator
L051C:
        loda,r0 18DFh,r3     ;r0 = *(18DF + r3); // user RAM
        bctr,eq L0526        ;if (==) goto L0526;
        subi,r0 001H         ;r0--;
        stra,r0 18DFh,r3     ;*(18DF + r3) = r0;
L0526:
        bdrr,r3 L051C        ;if (--r3 != 0) goto L051C;
;end of loop

        loda,r0 18D0h        ;r0 = *(18D0); // user RAM
        comi,r0 003H         ;compare r0 against 3
        bctr,gt L0534        ;if (>) goto L0534;
        lodi,r1 00FH         ;r1 = 15;
        stra,r1 VOLUMECOPY   ;VOLUMECOPY = r1 [15]; // user RAM
L0534:
        lodi,r2 009H         ;r2 = 9;
        comi,r0 001H         ;compare r0 against 1
        bcfr,eq L0544        ;if (!=) goto L0544;
        loda,r0 SPRITE3X     ;r0 = SPRITE3X;
        bctr,eq L054A        ;if (==) goto L054A;
        bsta,un INITSHIP     ;gosub INITSHIP;
        bctr,un L054A        ;goto L054A;
;
L0544:
        lodi,r2 011H         ;r2 = 17;
        comi,r0 004H         ;compare r0 against 4
        bctr,lt L0554        ;if (<) goto L0554;

L054A:
        lodi,r3 008H         ;r3 = 8; // loop iterator
L054C:
        loda,r0 064Fh,r2-    ;r0 = *(64F + --r2); // ROM data (player's ship)
        stra,r0 1997h,r3     ;*(1997 + r3) = r0; // sprite #3
        bdrr,r3 L054C        ;if (--r3 != 0) goto L054C;
;end of loop

L0554:
        lodi,r3 004H         ;r3 = 4; // loop iterator
        eorz    r0           ;r0 = 0;
;clear lower screen from $1ACC..$1ACF
L0557:
        stra,r0 1ACBh,r3     ;*(1ACB + r3) = r0; // lower screen
        bdrr,r3 L0557        ;if (--r3 != 0) goto L0557;
;end of loop

        loda,r3 LIVES        ;r3 = LIVES; // loop iterator
        bctr,eq L056A        ;if (==) goto L056A;
        lodi,r0 07FH         ;r0 = $7F;
        lodi,r1 005H         ;r1 = 5;
;draw spare ships
L0565:
        stra,r0 1ACBh,r1-    ;*(1ACB + --r1) = r0; // lower screen
        bdrr,r3 L0565        ;if (--r3 != 0) goto L0565;
;end of loop

L056A:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
TWINKLE:
        lodi,r2 034H         ;r2 = $34; // '.' character
        loda,r0 FRAMECOUNT   ;r0 = FRAMECOUNT; // user RAM
        andi,r0 002H         ;r0 &= %00000010;
        bctr,eq TWINKLE_1    ;if (==) goto TWINKLE_1;

;NOTWINKLING:
;       nop                                                             ;1
;       nop                                                             ;1
;TWINKLING:
        lodi,r2 000H         ;r2 = 0; // ' ' (space) character          ;2

TWINKLE_1:
        lodi,r3 00AH         ;r3 = 10; // loop iterator
TWINKLE_2:
        loda,r0 0707h,r3     ;r0 = *(707 + r3);
        strz    r1           ;r1 = r0;
        lodz    r2           ;r0 = r2 [0 or $34];
        stra,r0 1800h,r1     ;*(1800 + r1) = r0 [0 or $34]; // upper screen
        bdrr,r3 TWINKLE_2    ;if (--r3 != 0) goto TWINKLE_2;
;end of loop

        lodi,r3 014H         ;r3 = 20; // loop iterator
TWINKLE_3:
        loda,r0 0711h,r3     ;r0 = *(711 + r3);
        strz    r1           ;r1 = r0;
        lodz    r2           ;r0 = r2 [0 or $34];
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0 [0 or $34]; // lower screen
        bdrr,r3 TWINKLE_3    ;if (--r3 != 0) goto TWINKLE_3;
;end of loop

;print selected game ('A' or 'B')
        loda,r0 GAME         ;r0 = GAME; // user RAM
        loda,r0 0726h,r0     ;r0 = *(726 + r0); // ROM data
        stra,r0 1ACAh        ;*(1ACA) = r0; // user RAM
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
NEWSWARM:
;This routine is very inefficient. A direct copy from a 9x6
;ROM data array to the upper screen would be faster, require less memory
;and be more readable.

        eorz    r0           ;r0 = 0;
        lodi,r3 060H         ;r3 = $60; // loop iterator
;clear screen at $1820..$187F (rows 2..7)
NEWSWARM_1:
        stra,r0 181Fh,r3     ;*(181F + r3) = r0 [0]; // upper screen
        bdrr,r3 NEWSWARM_1   ;if (--r3 != 0) goto NEWSWARM_1;
;end of loop

        lodi,r3 009H         ;r3 = 9; // loop iterator
;clear screen at $1A14..$1A1C ("GAME OVER" region)
NEWSWARM_2:
        stra,r0 1A13h,r3     ;*(1A13 + r3) = r0 [0];
        bdrr,r3 NEWSWARM_2   ;if (--r3 != 0) goto NEWSWARM_2;
;end of loop

        lodi,r3 006H         ;r3 = 6; // loop iterator
;r3 is the row number (6..1)
NEWSWARM_3:
        loda,r0 06EFh,r3     ;r0 = *(6EF + r3);
        strz    r2           ;r2 = r0;
;r2 is the offset to the leftmost alien of the row

;for each alien
NEWSWARM_4:
        lodz    r3           ;r0 = r3;
        rrl,r0               ;rotate r0 to the left quarce
	rrl,r0
	rrl,r0
	rrl,r0
        addz    r2           ;r0 += r2;
        strz    r1           ;r1 = r0;

;instead of the next 2 lines, we could more efficiently use:
;       loda,r0 0701h,r3
        loda,r0 06FBh,r3     ;r0 = *(6FB + r3);
        loda,r0 0702h,r0     ;r0 = *(702 + r0);

;r0 is $3C, $BD, $7D, $BD, $BD or $BD for values of r3 from 1..6 respectively
;different for odd and even aliens though (one higher)
        tmi,r2  001H         ;test mask %00000001 of r2
        bctr,eq NEWSWARM_5   ;if (==) goto NEWSWARM_5;
        addi,r0 001H         ;r0++;
NEWSWARM_5:
        stra,r0 1814h,r1     ;*(1814 + r1) = r0; // upper screen
;r2 is the number of aliens drawn so far for this row
        addi,r2 001H         ;r2++;
        lodz    r2           ;r0 = r2;
        coma,r0 06F5h,r3     ;compare r0 against *(6F5 + r3)
;if we need to do more aliens for this row
        bctr,lt NEWSWARM_4   ;if (<) goto NEWSWARM_4;
;this row is done, do next row
        bdrr,r3 NEWSWARM_3   ;if (--r3 != 0) goto NEWSWARM_3;
;end of loop

;clear the central yellow alien
;*(1828) = 0;
        stra,r3 1828h        ;*(1828) = r3 [0]; // upper screen

;SWARMX = $20; // central swarm position
        lodi,r0 020H         ;r0 = $20;
        stra,r0 SWARMX       ;SWARMX = r0 [$20]; // user RAM

;*(1AD4) = 1;
        lodi,r0 001H         ;r0 = 1;
        stra,r0 1AD4h        ;*(1AD4) = r0 [1]; // user RAM

;*(18D4) = *(18D5) = *(18D8) = *(18D9) = $E4;
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 18D4h        ;*(18D4) = r0 [$E4]; // user RAM
        stra,r0 18D5h        ;*(18D5) = r0 [$E4]; // user RAM
        stra,r0 18D8h        ;*(18D8) = r0 [$E4]; // user RAM
        stra,r0 18D9h        ;*(18D9) = r0 [$E4]; // user RAM

;*(18E3) = r0 [$64];
        lodi,r0 064H         ;r0 = $64;
        stra,r0 18E3h        ;*(18E3) = r0 [$64]; // user RAM

;*(18E4) = r0 [$C8];
        lodi,r0 0C8H         ;r0 = $C8;
        stra,r0 18E4h        ;*(18E4) = r0 [$C8]; // user RAM

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
INITSHIP:

;SPRITE3X = 0;
        eorz    r0           ;r0 = 0;
        stra,r0 SPRITE3X     ;SPRITE3X = r0 [0];

;SPRITE3Y = $37;
        lodi,r0 037H         ;r0 = $37;
        stra,r0 SPRITE3Y     ;SPRITE3Y = r0 [$37];

;SPRITE2X = $E4;
        lodi,r0 0E4H         ;r0 = $E4;
        stra,r0 SPRITE2X     ;SPRITE2X = r0 [$E4];

;*(18D1) = 10;
        lodi,r0 00AH         ;r0 = 10;
        stra,r0 18D1h        ;*(18D1) = 10; // user RAM

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
HANDLESCORE:

;Scoring is as follows:
;                         in swarm...     diving...
;1st Row        XX         60 points      200 points
;2nd Row       XXXXX       50 points      100 points
;3rd Row      XXXXXXX      40 points       80 points
;4th Row     XXXXXXXXX     30 points       60 points
;5th Row     XXXXXXXXX     30 points       60 points
;6th Row     XXXXXXXXX     30 points       60 points

        adda,r0 18ECh        ;r0 += *(18EC); // user RAM
        addi,r0 066H         ;r0 += $66;
        dar,r0               ;decimal adjust r0
        strr,r0 *0608h       ;*(*(608)) = r0;
                             ;*(18EC) = r0; // user RAM

        ppsl    008H         ;PSL |= %00001000; // set With Carry bit

        loda,r0 18EBh        ;r0 = *(18EB); // user RAM
        addi,r0 066H         ;r0 += $66;
        dar,r0               ;decimal adjust r0
        strr,r0 *0612h       ;*(*(612)) = r0;
                             ;*(18EB) = r0; // user RAM

        loda,r0 18EAh        ;r0 = *(18EA); // user RAM
        addi,r0 066H         ;r0 += $66;
        dar,r0               ;decimal adjust r0
        strr,r0 *061Ah       ;*(*(61A)) = r0;
                             ;*(18EA) = r0; // user RAM

        cpsl    008H         ;PSL &= %11110111; // clear With Carry bit

;skip this if bonus life has already been awarded
        loda,r0 BONUSGIVEN   ;r0 = BONUSGIVEN; // user RAM
        bcfr,eq HANDLESCORE_1;if (!=) goto HANDLESCORE_1;

;skip this if score is less than 5000
        lodr,r0 *0612h       ;r0 = *(*(612));
                             ;r0 = *(18EB); // user RAM
        comi,r0 050H         ;compare r0 against $50
        bctr,lt HANDLESCORE_1;if (<) goto HANDLESCORE_1;

;award an extra life to the player at 5000 points
;LIVES++;
        loda,r0 LIVES        ;r0 = LIVES;
        addi,r0 001H         ;r0++;
        strr,r0 *062Fh       ;*(*(62F)) = r0;
                             ;LIVES = r0; // user RAM

;note that bonus life has now already been awarded
        strr,r0 *0624h       ;*(*(624)) = r0;
                             ;BONUSGIVEN = r0; // user RAM

HANDLESCORE_1:
        retc,un              ;return;
;Data---------------------------------------------------------------------
        db      092H ;#..#..#. UDC #0 (alien)
        db      0BAH ;#.###.#.
        db      0FEH ;#######.
        db      054H ;.#.#.#..
        db      07CH ;.#####..
        db      038H ;..###...
        db      010H ;...#....
        db      000H ;........

        db      0AAH ;#.#.#.#. UDC #1 (alien)
        db      07CH ;.#####..
        db      054H ;.#.#.#..
        db      07CH ;.#####..
        db      038H ;..###...
        db      054H ;.#.#.#..
        db      082H ;#.....#.
        db      000H ;........

        db      028H ;..#.#... UDC #2 (alien)
        db      0FEH ;#######.
        db      054H ;.#.#.#..
        db      07CH ;.#####..
        db      038H ;..###...
        db      044H ;.#...#..
        db      028H ;..#.#...
X064F:
        db      000H ;........

        db      010H ;...#.... UDC #3 (player's ship)
        db      038H ;..###...
        db      07CH ;.#####..
        db      010H ;...#....
        db      092H ;#..#..#.
        db      0FEH ;#######.
        db      0FEH ;#######.
        db      082H ;#.....#.

        db      008H ;#....... explosion
        db      042H ;.#....#.
        db      024H ;..#..#..
        db      098H ;#..##...
        db      019H ;...##..#
        db      024H ;..#..#..
        db      041H ;.#.....#
X065F:
        db      010H ;...#....

        db      02EH, 05AH, 0A5H, 000H, 000H, 020H, 01AH, 026H, 01EH ;"UAL  GAME "
X0669:
        db      000H

        db      010H ;...#.... yellow alien
        db      038H ;..###...
        db      07CH ;.#####..
        db      054H ;.#.#.#..
        db      0FEH ;#######.
        db      0BAH ;#.###.#.
        db      092H ;#..#..#.
        db      000H ;........

        db      082H ;#.....#. red/green alien '2'
        db      054H ;.#.#.#..
        db      038H ;..###...
        db      07CH ;.#####..
        db      054H ;.#.#.#..
        db      07CH ;.#####..
        db      0AAH ;#.#.#.#.
X0679:
        db      000H ;........

        db      080H ;....#... sprite #2 (bullet, either alien or player)
        db      080H ;....#...
        db      080H ;....#...
        db      080H ;....#...
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

X0682:
	db	001H

        db      005H
        db      003H
        db      005H
	db	005H

X0687:
	db	005H

        db      008H ;sprite #0
        db      010H ;sprite #1

;scores for aliens
X068A:
        db      060H ;yellow
        db      050H ;red
        db      040H ;green
        db      030H ;red
        db      030H ;red
X068F:
        db      030H ;red

        db      020H, 01AH, 026H, 01EH, 000H, 028H, 02FH, 01EH ;"GAME OVER"
X0698:
	db	02BH

        db      000H
        db      001H
        db      002H
        db      005H
        db      004H
X069E:
        db      003H

        db      000H
        db      005H
        db      004H
        db      003H
        db      002H
X06A4:
        db      001H

        db      005H
        db      004H
        db      003H
        db      002H
        db      001H
X06AA:
	db	000H

        db      004H, 005H, 003H
	db	006H, 002H, 007H, 001H
	db	008H
X06B3:
	db	000H, 008H, 000H, 007H
	db	001H, 006H, 002H, 004H
	db	005H
X06BC:
	db	003H

        db      004H, 008H, 000H, 007H, 001H, 006H, 002H, 005H, 003H

X06C6:
	db	080H, 080H, 080H, 080H
	db	080H, 000H, 000H, 000H
	db	000H
X06CF:
	db	001H, 0FFH, 002H, 0FEH
X06D3:
	db	001H
X06D4:
	db	002H

;(upper) screen offsets, for scoring
;starting offset for each pair of digits
        db      000H, 002H, 004H, 00AH, 00CH, 00EH

X06DB:
	db	000H, 00EH, 00EH, 00FH
	db	011H, 013H, 016H, 016H
	db	00EH, 00FH, 011H, 013H
	db	016H, 016H, 00EH, 016H
	db	011H, 016H, 016H, 016H
X06EF:
	db	000H

        db      003H ;1st row start offset   ...Y.Y...
        db      002H ;2nd row start offset   ..12121..
        db      001H ;3rd row start offset   .2121212.
        db      000H ;4th row start offset   121212121
        db      000H ;5th row start offset   121212121
X06F5:
        db      000H ;6th row start offset   121212121

        db      006H ;1st row (number of 'aliens' for this row)
        db      007H ;2nd row (number of 'aliens' for this row)
        db      008H ;3rd row (number of 'aliens' for this row)
        db      009H ;4th row (number of 'aliens' for this row)
        db      009H ;5th row (number of 'aliens' for this row)
X06FB:
        db      009H ;6th row (number of 'aliens' for this row)

X06FC:
        db      000H ;1st row
        db      001H ;2nd row
        db      002H ;3rd row
        db      003H ;4th row
        db      003H ;5th row
        db      003H ;6th row

X0702:
        db      03CH ;1st (yellow) row character (yellow UDC #4)
        db      0BDH ;2nd (red)    row character (red    UDC #5)
        db      07DH ;3rd (green)  row character (green  UDC #5)
        db      0BDH ;4th (red)    row character (red    UDC #5)
        db      0BDH ;5th (red)    row character (red    UDC #5)

X0707:
        db      0BDH ;6th (red)    row character (red    UDC #5)

;upper screen offsets (stars)
;    --0- --1- --2- --3- --4- --5- --6- --7- --8- --9- -10- -11- -12- -13- -14- -15-
; 0: 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 180A 180B 180C 180D 180E 180F
; 1: 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 181A 181B 181C 181D 181E 181F
; 2: 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 182A 182B 182C 182D 182E 182F
; 3: 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 183A 183B 183C 183D 183E 183F
; 4: 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 184A 184B 184C 184D 184E 184F
; 5: 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 185A 185B 185C 185D 185E 185F
; 6: 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 186A 186B 186C 186D 186E 186F
; 7: 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 187A 187B 187C 187D 187E 187F
; 8: 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 188A 188B 188C 188D 188E 188F
; 9: 1890 1891   *  1893 1894 1895 1896   *  1898 1899 189A 189B 189C 189D 189E   * 
;10: 18A0 18A1 18A2 18A3 18A4 18A5   *  18A7 18A8 18A9   *  18AB 18AC 18AD   *  18AF
;11: 18B0 18B1 18B2 18B3   *  18B5 18B6 18B7 18B8   *  18BA 18BB 18BC 18BD 18BE 18BF
;12: 18C0   *  18C2 18C3 18C4 18C5 18C6 18C7 18C8 18C9 18CA 18CB   *  18CD 18CE 18CF

;upper screen offsets (stars)
        db      097H, 092H, 09FH, 0A6H, 0AAH, 0AEH, 0B4H, 0B9H, 0C1H
X0711:
	db	0CCH

;lower screen offsets (stars)
;    --0- --1- --2- --3- --4- --5- --6- --7- --8- --9- -10- -11- -12- -13- -14- -15-
; 0: 1A00 1A01 1A02   *  1A04 1A05 1A06   *  1A08 1A09 1A0A 1A0B 1A0C 1A0D 1A0E 1A0F
; 1: 1A10 1A11 1A12 1A13 1A14 1A15 1A16 1A17 1A1A 1A19 1A1A 1A1B 1A1C   *  1A1E 1A1F
; 2: 1A20 1A21 1A22   *  1A24 1A25 1A26 1A27 1A28   *  1A2A 1A2B 1A2C 1A2D 1A2E   *
; 3: 1A30 1A31 1A32 1A33 1A34 1A35   *  1A37 1A38 1A39 1A3A   *  1A3C 1A3D 1A3E 1A3F
; 4: 1A40 1A41 1A42 1A43   *  1A45 1A46 1A47 1A48 1A49 1A4A 1A4B 1A4C 1A4D 1A4E 1A4F
; 5: 1A50   *  1A52 1A53 1A54 1A55 1A56 1A57   *  1A59 1A5A 1A5B   *  1A5D 1A5E 1A5F
; 6: 1A60 1A61 1A62 1A63   *  1A65 1A66 1A67 1A68 1A69 1A6A   *  1A6C 1A6D 1A6E 1A6F
; 7: 1A70 1A71 1A72 1A73 1A74 1A75 1A76 1A77 1A78 1A79 1A7A 1A7B 1A7C 1A7D 1A7E   *
; 8: 1A80   *  1A82 1A83 1A84 1A85 1A86   *  1A88 1A89 1A8A 1A8B 1A8C   *  1A8E 1A8F
; 9: 1A90 1A91 1A92   *  1A94 1A95 1A96 1A97 1A98   *  1A9A 1A9B 1A9C 1A9D 1A9E 1A9F
;10: 1AA0 1AA1 1AA2 1AA3 1AA4 1AA5 1AA6 1AA7 1AA8 1AA9 1AAA 1AAB 1AAC 1AAD 1AAE 1AAF
;11: 1AB0 1AB1 1AB2 1AB3 1AB4 1AB5 1AB6 1AB7 1AB8 1AB9 1ABA 1ABB 1ABC 1ABD 1ABE 1ABF
;12: 1AC0 1AC1 1AC2 1AC3 1AC4 1AC5 1AC6 1AC7 1AC8 1AC9 1ACA 1ACB 1ACC 1ACD 1ACE 1ACF

;lower screen offsets (stars)
        db      003H, 007H, 01DH, 023H, 029H, 02FH, 036H, 03BH, 044H, 051H
        db      058H, 05CH, 064H, 06BH, 07FH, 081H, 087H, 08DH, 093H, 099H

;game modes
X0726:
        db      09AH ;"A"
        db      09BH ;"B"
;Junk---------------------------------------------------------------------
        db      0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH
        db      0FFH

        db      0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH, 0FFH, 0FFH
	db	0FFH, 0FFH
        end

PSU: SP:  Stack Pointer     bits 0..2
     II:  Interrupt Inhibit bit  5
     F:   Flag              bit  6
     S:   Sense             bit  7
PSL: C:   Carry             bit  0
     COM: Compare           bit  1
     OVF: Overflow          bit  2
     WC:  With Carry        bit  3
     RS:  Register Select   bit  4
     IDC: Inter Digit Carry bit  5
     CC:  Condition Code    bits 6..7

sprites #0/#1: diving aliens on even-numbered frames
               alien bullets on odd-numbered frames
sprite #2:     player's bullet
sprite #3:     player's ship

