;
;       Disassembled by:
;               DASMx object code disassembler
;               (c) Copyright 1996-1999   Conquest Consultants
;               Version 1.30 (Oct  6 1999)
;       Commented by:
;               Annotate 1.14a (26 Dec 2005) by Amigan Software
;               (and by hand)
;
;       File:           redclash.bin
;       CPU:            Signetics 2650 (2650 family)
;
;Disassembled by Amigan Software in December 2002, May-June 2006 and
; September 2006.
;Please inform us of any errors found...
;URL:   http://members.optusnet.com.au/jrjacobs76/
;EMail: jrj76@optusnet.com.au

;The flickering is an inherent drawback of the sprite multiplexing
; techniques used by the game.

;Four harmless BUGs were found - FIXes for each are shown but not
; implemented by default.

;The trainer can be enabled by replacing the NORMAL code with the
; TRAINER code.

;Alternative enemy graphics can be enabled by replacing the REDCLASH data
; with the ALIENINVADERS data.
;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: (R/-) ROM (first 4K of cartridge)
;                   $1000..$17FF: (-/-) unmapped
;                   $1800..$18CF: (R/W) upper screen
;                   $18D0..$18EF: (R/W) user RAM
SPRITE0Y        equ $18F0        ;(R/W)
SPRITE0X        equ $18F1        ;(R/W)
SPRITE1Y        equ $18F2        ;(R/W)
SPRITE1X        equ $18F3        ;(R/W)
SPRITE2Y        equ $18F4        ;(R/W)
SPRITE2X        equ $18F5        ;(R/W)
SPRITE3Y        equ $18F6        ;(R/W)
SPRITE3X        equ $18F7        ;(R/W)
;                   $18F8..$18FB: (R/W) user RAM
VSCROLL         equ $18FC        ;(R/-) CRTC vertical position register
PITCH           equ $18FD        ;(R/W) also other uses
;    bit  7:                            0 = normal mode
;                                       1 = alternate character mode colour 2x2
;    bits 6..0:                         pitch
VOLUME          equ $18FE        ;(R/W) also other uses
;    bits 7..5:                         horizontal scanline scrolling (0..7)
;    bit  4:                            noise on/off
;    bit  3:                            tones on/off
;    bits 2..0:                         volume (0..7)
CHARLINE        equ $18FF        ;(R/-) current character line
P1LEFTKEYS      equ $1900        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p1 (left) '1' button
;    bit  2:                            p1 (left) '4' button
;    bit  1:                            p1 (left) '7' button
;    bit  0:                            p1 (left) 'E' button (Enter)
P1MIDDLEKEYS    equ $1901        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p1 (left) '2' button
;    bit  2:                            p1 (left) '5' button
;    bit  1:                            p1 (left) '8' button
;    bit  0:                            p1 (left) '0' button
P1RIGHTKEYS     equ $1902        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p1 (left) '3' button
;    bit  2:                            p1 (left) '6' button
;    bit  1:                            p1 (left) '9' button
;    bit  0:                            p1 (left) 'C' button (Clear)
P1PALLADIUM     equ $1903        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p1 (right) Palladium button #1
;    bit  2:                            p1 (right) Palladium button #2
;    bit  1:                            p1 (right) Palladium button #3
;    bit  0:                            p1 (right) Palladium button #4
P2LEFTKEYS      equ $1904        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p2 (right) '1' button
;    bit  2:                            p2 (right) '4' button
;    bit  1:                            p2 (right) '7' button
;    bit  0:                            p2 (right) 'E' button (Enter)
P2MIDDLEKEYS    equ $1905        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p2 (right) '2' button
;    bit  2:                            p2 (right) '5' button
;    bit  1:                            p2 (right) '8' button
;    bit  0:                            p2 (right) '0' button
P2RIGHTKEYS     equ $1906        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p2 (right) '3' button
;    bit  2:                            p2 (right) '6' button
;    bit  1:                            p2 (right) '9' button
;    bit  0:                            p2 (right) 'C' button (Clear)
P2PALLADIUM     equ $1907        ;(R/-)
;    bits 7..4:                         unknown
;    bit  3:                            p2 (right) Palladium button #1
;    bit  2:                            p2 (right) Palladium button #2
;    bit  1:                            p2 (right) Palladium button #3
;    bit  0:                            p2 (right) Palladium button #4
CONSOLE         equ $1908        ;(R/-)
;    bits 7..3:                         unknown
;    bit  2:                            B button
;    bit  1:                            A button
;    bit  0:                            START button
;                   $1909..$197F: (-/-) unmapped
;                   $1980..$1987: (R/W) sprite #0
;                   $1988..$198F: (R/W) sprite #1
;                   $1990..$1997: (R/W) sprite #2
;                   $1998..$199F: (R/W) sprite #3
UDC0            equ $19A0
;                   $19A0..$19A7: (R/W) user-defined character #0
UDC1            equ $19A8
;                   $19A8..$19AF: (R/W) user-defined character #1
UDC2            equ $19B0
;                   $19B0..$19B7: (R/W) user-defined character #2
UDC3            equ $19B8
;                   $19B8..$19BF: (R/W) user-defined character #3
;                   $19C0..$19F7: (-/-) unmapped
RESOLUTION      equ $19F8        ;(R/W) also other uses
;    bit  7:                            0 = normal mode
;                                       1 = block graphics mode
;    bit  6:                            0 = 13 character rows
;                                       1 = 26 character rows
;    bits 5..0:                         rectangle descriptions in block graphics mode
BGCOLOUR        equ $19F9        ;(R/W) also other uses
;    bit  7:                            0 = low-res mode
;                                       1 = high-res mode
;    bit  6:                            paddle interpolation (switches between axes of analog sticks)
;    bits 5..3:                         colours of tile set 0
;    bits 2..0:                         background colour
SPRITES23CTRL   equ $19FA        ;(R/W)
;    bit  7:                            0 = sprite #2 double-height
;                                       1 = sprite #2 normal
;    bit  6:                            0 = sprite #3 double-height
;                                       1 = sprite #3 normal
;    bits 5..3:                         colours of sprite #2
;    bits 2..0:                         colours of sprite #3
SPRITES01CTRL   equ $19FB        ;(R/W)
;    bit  7:                            0 = sprite #0 double-height
;                                       1 = sprite #0 normal
;    bit  6:                            0 = sprite #1 double-height
;                                       1 = sprite #1 normal
;    bits 5..3:                         colours of sprite #0
;    bits 2..0:                         colours of sprite #2
BGCOLLIDE       equ $19FC        ;(R/-)
;    bits 7..4:                         unknown
;    bits 3..0:                         collision between sprites #3..#0 (respectively) and background
SPRITECOLLIDE   equ $19FD        ;(R/-)
;    bits 7..6:                         unknown
;    bit 5:                             sprites #2/#3 collision
;    bit 4:                             sprites #1/#3 collision
;    bit 3:                             sprites #1/#2 collision
;    bit 2:                             sprites #0/#3 collision
;    bit 1:                             sprites #0/#2 collision
;    bit 0:                             sprites #0/#1 collision
P2PADDLE        equ $19FE        ;(R/-)
P1PADDLE        equ $19FF        ;(R/-)
;                   $1A00..$1ACF: (R/W) lower screen
;                   $1AD0..$1AFF: (R/W) user RAM
;                   $1B00..$1FFF: (-/-) unmapped
;                   $2000..$7FFF: (R/-) ROM (last 24K of cartridge)
;Variable Equates---------------------------------------------------------
SPRITES01COPY equ 18D1h
;                $18D4..$18D7 is the high score
UFODELTAX     equ 18DAh
;$18DC..$18DD is a pointer
SPRITES23COPY equ 1ADAh
MONOTONIC     equ 1ADBh ;monotonic incrementor for random numbers, etc.
GREENY        equ 1ADCh
GREENX        equ 1ADDh
REDY          equ 1ADEh
REDX          equ 1ADFh
CYANY         equ 1AE0h
CYANX         equ 1AE1h
YELLOWY       equ 1AE2h
YELLOWX       equ 1AE3h
UFOY          equ 1AE4h
UFOX          equ 1AE5h
ALIENY        equ 1AE6h
ALIENX        equ 1AE7h
SHIPY         equ 1AE8h
SHIPX         equ 1AE9h
BULLETY       equ 1AEAh
BULLETX       equ 1AEBh
DEAD          equ 1AECh
BALLSCROLL    equ $1AF0 ;horizontal scrolling delta of "balls"
SPRITESET     equ 1AF1h
ENEMIESKILLED equ 1AF4h
SOUNDVAR      equ 1AF5h
INTERPOLATION equ 1AF6h ;flip-flops between %00000000 and %00000001
PADDLEY       equ 1AF7h
PADDLEX       equ 1AF8h
BGCOLOURCOPY  equ 1AF9h
BULLETRANGE   equ 1AFAh ;where the bullet will fizzle out (SHIPY + 85)
SCORELSB      equ 1AFBh ;least significant byte of score
SCOREMSB      equ 1AFCh ;most significant byte of score
ROUND         equ 1AFDh
TEMP          equ 1AFFh
;-------------------------------------------------------------------------
        org     0000H
;
        eorz    r0           ;r0 = 0;
        eorz    r0           ;r0 = 0;
        bctr,un BOOT         ;goto BOOT;
;
	db	017H
;
BOOT:
        lpsu
	lpsl
        ppsu    020H         ;PSU |= %00100000;
        ppsl    002H         ;PSL |= %00010000;
;wait for end of vertical blank
BOOT_1:
        tpsu    080H         ;test PSU against %10000000 (Sense bit)
        bctr,eq BOOT_1       ;if (==) goto BOOT_1;
BOOT_2:
;wait for start of vertical blank
        tpsu    080H         ;test PSU against %10000000 (Sense bit)
        bcfr,eq BOOT_2       ;if (!=) goto BOOT_2;
        strz    r1           ;r1 = r0;
;loop 256 times
;clear screen, variables, hardware registers
BOOT_3:
        stra,r0 1800h,r1     ;*(1800 + r1) = r0 [0];
        stra,r0 1900h,r1     ;*(1900 + r1) = r0 [0];
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0 [0];
        bdrr,r1 BOOT_3       ;if (--r1 != 0) goto BOOT_3;
;end of loop
        lodi,r0 071H         ;r0 = %01110001;
        stra,r0 RESOLUTION   ;RESOLUTION = r0;
TITLESCREEN:
        eorz    r0           ;r0 = 0;
TITLESCREEN_1:
        stra,r0 1AD1h        ;*(1AD1) = r0; // user RAM
        lodi,r0 050H         ;r0 = 80;
        lodi,r1 060H         ;r1 = 96;
        lodi,r2 070H         ;r2 = 112;
        lodi,r3 080H         ;r3 = 128;
        stra,r0 GREENX       ;GREENX = r0 [80]; // user RAM
        stra,r0 REDX         ;REDX = r0 [80]; // user RAM
        stra,r0 CYANX        ;CYANX = r0 [80]; // user RAM
        stra,r0 YELLOWX      ;YELLOWX = r0 [80]; // user RAM
L003C:
        eorz    r0           ;r0 = 0;
        stra,r0 ENEMIESKILLED;ENEMIESKILLED = r0 [0]; // user RAM
        stra,r0 INTERPOLATION;INTERPOLATION = r0 [0]; // user RAM
        stra,r0 BALLSCROLL   ;BALLSCROLL = r0 [0]; // user RAM
        stra,r0 SPRITESET    ;SPRITESET = r0 [0]; // user RAM
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [0]; // user RAM
        lodi,r0 0FFH         ;r0 = 255;
        stra,r0 BGCOLOURCOPY ;BGCOLOURCOPY = r0 [0]; // user RAM
        lodi,r0 001H         ;r0 = 1;
        lodi,r1 002H         ;r1 = 2;
        lodi,r2 003H         ;r2 = 3;
        lodi,r3 004H         ;r3 = 4;
        stra,r0 1AD2h        ;*(1AD2) = r0 [1]; // user RAM
        stra,r1 1AD3h        ;*(1AD3) = r1 [2]; // user RAM
        stra,r2 1AD4h        ;*(1AD4) = r2 [3]; // user RAM
        stra,r3 1AD5h        ;*(1AD5) = r3 [4]; // user RAM
        lodi,r0 0FFH         ;r0 = 255;
        stra,r0 1AD6h        ;*(1AD6) = r0 [255]; // user RAM
        stra,r0 1AD8h        ;*(1AD8) = r0 [255]; // user RAM
        lodi,r0 001H         ;r0 = 1;
        stra,r0 1AD7h        ;*(1AD7) = r0 [1]; // user RAM
        stra,r0 1AD9h        ;*(1AD9) = r0 [1]; // user RAM
        bsta,un SETVARS      ;gosub SETVARS;
        lodi,r0 045H         ;r0 = 69;
        lodi,r1 06CH         ;r1 = 108;
        stra,r0 SHIPY        ;SHIPY = r0 [69]; // user RAM
        stra,r1 SHIPX        ;SHIPX = r1 [108]; // user RAM
        lodi,r0 0DAH         ;r0 = %11011010;
        stra,r0 SPRITES23COPY;SPRITES23COPY = r0 [%11011010]; // user RAM
        lodi,r0 00CH         ;r0 = %00010010;
        stra,r0 SPRITES01COPY;SPRITES01COPY = r0 [%00010010]; // user RAM
;wait for end of vertical blank
L008C:
        tpsu    080H         ;test mask %00010000 of PSU (Sense bit)
        bctr,eq L008C        ;if (==) goto L008C;
;end of loop
;wait for start of vertical blank
L0090:
        tpsu    080H         ;test mask %00010000 of PSU (Sense bit)
        bcfr,eq L0090        ;if (!=) goto L0090;
;end of loop

;BUG:
        lodi,r0 040H         ;r0 = 64; // useless!
;FIX:
;       lodi,r1 040H         ;r1 = 64;

;copies from $85E..$89D (ROM data area) to $1980..$19BF (sprites/UDCs area)
;BUGgy version also (unintentionally) copies from $89E..$8DD (ROM data
; area) to $19C0..$19FF (unmapped area and hardware registers)
L0096:
        loda,r0 085Dh,r1     ;r0 = *(85D + r1);
        stra,r0 197Fh,r1     ;*(197F + r1) = r0;
        bdrr,r1 L0096        ;if (--r1 != 0) goto L0096;
;end of loop

        lodi,r0 0EEH         ;r0 = $EE;
        stra,r0 VSCROLL      ;VSCROLL = r0 [$EE];
        bsta,un DRAWSIDES    ;gosub DRAWSIDES;
        lodi,r1 000H         ;r1 = 0;
        stra,r1 1AF2h        ;*(1AF2) = r1 [0]; // user RAM
;execution flows into TITLELOOP
;-------------------------------------------------------------------------
TITLELOOP:
        loda,r0 MONOTONIC    ;r0 = MONOTONIC;
        addi,r0 001H         ;r0++;
        stra,r0 MONOTONIC    ;MONOTONIC = r0;
        loda,r0 CONSOLE      ;r0 = CONSOLE;
        andi,r0 002H         ;r0 &= %00000010; // extract OPTION bit
        bcta,gt L0827        ;if (>) goto L0827;
        loda,r0 1AD1h        ;r0 = *(1AD1);
        bcta,gt TITLELOOP_4  ;if (>) goto TITLELOOP_4;
        bsta,un L0FE0        ;gosub L0FE0;
        andi,r0 001H         ;r0 &= %00000001;
        bcfa,gt TITLELOOP_4  ;if (!(>)) goto TITLELOOP_4;
        lodi,r0 030H         ;r0 = 48;
        stra,r0 1AD1h        ;*(1AD1) = r0 [48]; // user RAM
        eorz    r0           ;r0 = 0;
        stra,r0 SCORELSB     ;SCORELSB = r0 [0]; // user RAM
        stra,r0 SCOREMSB     ;SCOREMSB = r0 [0]; // user RAM
        stra,r0 ENEMIESKILLED;ENEMIESKILLED = r0 [0]; // user RAM
        stra,r0 18D9h        ;*(18D9) = r0 [0]; // user RAM
        stra,r0 18EEh        ;*(18EE) = r0 [0]; // user RAM
        stra,r0 18EFh        ;*(18EF) = r0 [0]; // user RAM
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [0]; // user RAM
        stra,r0 ROUND        ;*(1AFD) = r0 [0]; // user RAM
TITLELOOP_1:               
        lodi,r1 077H         ;r1 = $77;
        stra,r1 18D8h        ;*(18D8) = r1 [$77];
        bsta,un L079B        ;gosub L079B;

        lodi,r3 01FH         ;r3 = 31; // loop iterator
TITLELOOP_2:
;clear title text
        loda,r0 090Bh,r3     ;r0 = *(90B + r3);
        strz    r1           ;r1 = r0;
        eorz    r0           ;r0 = 0;
        stra,r0 1800h,r1     ;*(1800 + r1) = r0 [0];
        bdrr,r3 TITLELOOP_2  ;if (--r3 != 0) goto TITLELOOP_2;
;end of loop
        lodi,r3 026H         ;r3 = 38; // loop iterator

;clear credits
TITLELOOP_3:
        loda,r0 0947h,r3     ;r0 = *(947 + r3);
        strz    r1           ;r1 = r0;
        eorz    r0           ;r0 = 0;
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0 [0];
        bdrr,r3 TITLELOOP_3  ;if (--r3 != 0) goto TITLELOOP_3;
;end of loop

        lodi,r0 005H         ;r0 = 5;
        stra,r0 1AD0h        ;*(1AD0) = r0; // user RAM
        lodi,r0 001H         ;r0 = 1;
        stra,r0 ROUND        ;ROUND = r0 [1];
        bsta,un NEWROUND     ;gosub NEWROUND;

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

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

        loda,r3 INTERPOLATION;r3 = INTERPOLATION;
        loda,r0 P2PADDLE     ;r0 = P2PADDLE;
;update PADDLEX or PADDLEY
        stra,r0 1AF7h,r3     ;*(1AF7 + r3) = r0;
        loda,r1 BGCOLOURCOPY ;r1 = BGCOLOURCOPY;
        stra,r1 BGCOLOUR     ;BGCOLOUR = r1;
;update SPRITESnnCTRL from RAM
        loda,r0 SPRITES23COPY;r0 = SPRITES23COPY; // user RAM
        stra,r0 SPRITES23CTRL;SPRITES23CTRL = r0;
        loda,r0 SPRITES01COPY;r0 = SPRITES01COPY; // user RAM
        stra,r0 SPRITES01CTRL;SPRITES01CTRL = r0;
        lodi,r3 000H         ;r3 = 0;
        loda,r0 DEAD         ;r0 = DEAD; // user RAM
        bctr,eq TITLELOOP_6  ;if (==) goto TITLELOOP_6;

;now we change the sprite image data
;the ship IS drawn when the yellow and red balls are drawn
;the ship is NOT drawn when the cyan and green balls are drawn
        lodi,r3 00CH         ;r3 = 12;
TITLELOOP_6:
;r3 is either 0 or 12, depending on DEAD
        loda,r0 SPRITESET    ;r0 = SPRITESET;
;only interested in the lowest bit (bit 0)
        andi,r0 001H         ;r0 &= %00000001;

        bctr,eq TITLELOOP_7  ;if (==) goto TITLELOOP_7;

        addi,r3 006H         ;r3 += 6;

TITLELOOP_7:
;r3 is either 0, 6, 12 or 18, depending on DEAD and SPRITESET
        lodi,r2 006H         ;r2 = 6; // loop iterator
TITLELOOP_8:
        lodz    r3           ;r0 = r3;
        addz    r2           ;r0 += r2;
        strz    r1           ;r1 = r0;
;r2 goes backwards from 6..1
;*(1981 + r2) = *(845 + r3 + r2);
        loda,r0 0845h,r1     ;r0 = *(845 + r1);
;adjust $1982..$1987 (rows 2..7 of sprite #0)
        stra,r0 1981h,r2     ;*(1981 + r2) = r0;
        bdrr,r2 TITLELOOP_8  ;if (--r2 != 0) goto TITLELOOP_8;
;end of loop

;r0 = r2 = r3 = BALLSCROLL;
        loda,r0 BALLSCROLL   ;r0 = BALLSCROLL;
        strz    r2           ;r2 = r0;
        strz    r3           ;r3 = r0;

        subi,r3 001H         ;r3--;
        andi,r3 007H         ;r3 &= %00000111;
        eorz    r0           ;r0 = 0;
        stra,r0 19A0h,r3     ;*(19A0 + r3) = r0 [0];
        lodi,r0 010H         ;r0 = %00010000;
        stra,r0 19A0h,r2     ;*(19A0 + r2) = r0 [%00010000];

;increment SPRITESET by one
        loda,r0 SPRITESET    ;r0 = SPRITESET;
        addi,r0 001H         ;r0++;
        stra,r0 SPRITESET    ;SPRITESET = r0;

        rrr,r0               ;rotate r0 to the right twice
	rrr,r0
        andi,r0 007H         ;r0 &= %00000111;
        stra,r0 BALLSCROLL   ;BALLSCROLL = r0;
        bsta,un SCROLLSTARS  ;gosub SCROLLSTARS;
        lodi,r1 000H         ;r1 = 0;
        bsta,un ADDSCORE     ;gosub ADDSCORE;
        bsta,un TITLETEXT    ;gosub TITLETEXT;
        bsta,un MOVESPRITES  ;gosub MOVESPRITES;
        bsta,un CHECKPAUSE   ;gosub CHECKPAUSE;
        bsta,un L067D
        bsta,un L0735
        bsta,un PLAYNOTE     ;gosub PLAYNOTE;
        bsta,un L0718
        bsta,un L0537        ;gosub L0537;
        bsta,un UFO          ;gosub UFO;
        bsta,un SAYENEMIES   ;gosub SAYENEMIES;
        loda,r0 1AD1h        ;r0 = *(1AD1);
        andi,r0 0F0H         ;r0 &= %11110000;
        bsta,gt L047C        ;if (>) gosub L047C;
        bcta,eq TITLELOOP    ;if (==) goto TITLELOOP;
        loda,r0 1AD1h        ;r0 = *(1AD1);
        comi,r0 015H         ;compare r0 against %00010101
        bctr,lt TITLELOOP_12 ;if (<) goto TITLELOOP_12;
        bsta,gt SAYROUND     ;if (>) gosub SAYROUND;
        loda,r0 1AD1h        ;r0 = *(1AD1);
        comi,r0 020H         ;compare r0 against $20
        bctr,lt TITLELOOP_9  ;if (<) goto TITLELOOP_9;
        subi,r0 001H         ;r0--;
        stra,r0 1AD1h        ;*(1AD1) = r0;
        bcta,un TITLELOOP    ;gosub TITLELOOP;
TITLELOOP_9:
        loda,r0 18D9h        ;r0 = *(18D9); // user RAM
        bctr,gt TITLELOOP_10 ;if (>) goto TITLELOOP_10;
        loda,r1 P2MIDDLEKEYS ;r1 = P2MIDDLEKEYS;
        andi,r1 00FH         ;r1 &= %00001111;
        bcta,eq TITLELOOP    ;if (==) goto TITLELOOP;
TITLELOOP_10:
;user has pressed firebutton to start the round
        lodi,r0 012H         ;r0 = 18;
        stra,r0 1AD1h        ;*(1AD1) = r0 [18]; // user RAM
        lodi,r1 00AH         ;r1 = 10; // loop iterator
        eorz    r0           ;r0 = 0;
;clear screen coords (4..13,12)
TITLELOOP_11:
        stra,r0 18C3h,r1     ;*(18C3 + r1) = r0 [0]; // upper screen
        bdrr,r1 TITLELOOP_11 ;if (--r1 != 0) goto TITLELOOP_11;
;end of loop
        bcta,un TITLELOOP    ;goto TITLELOOP;
TITLELOOP_12:
        bsta,un FIREBUTTON   ;gosub FIREBUTTON;
        bsta,un L0505        ;gosub L0505;
        loda,r0 DEAD         ;r0 = DEAD;
        bcta,gt TITLELOOP_13 ;if (>) goto TITLELOOP_13;

        lodi,r3 000H         ;r3 = 0;
        loda,r1 GREENX       ;r1 = GREENX;
        loda,r2 GREENY       ;r2 = GREENY;
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	002H
        loda,r1 REDX
        loda,r2 REDY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	004H
        loda,r1 CYANX
        loda,r2 CYANY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	006H
        loda,r1 YELLOWX
        loda,r2 YELLOWY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

        loda,r1 UFOX
        loda,r2 UFOY       
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
TITLELOOP_13:
        bsta,un L0351        ;gosub L0351;
        bcta,un TITLELOOP_4  ;goto TITLELOOP_4;
;Subroutine---------------------------------------------------------------
CHECKPAUSE:
        loda,r0 P1LEFTKEYS   ;r0 = P1LEFTKEYS;
        andi,r0 00FH         ;r0 &= %00001111;
        retc,eq              ;if (==) return;
;if pause is pressed
        lodi,r0 0FFH         ;r0 = 255;
        stra,r0 SPRITE0X     ;SPRITEX = r0 [255];
        eorz    r0           ;r0 = 0;
        stra,r0 VOLUME       ;VOLUME = r0 [0];
;wait for unpause
CHECKPAUSE_1:
        loda,r0 P1RIGHTKEYS  ;r0 = P1RIGHTKEYS;
        andi,r0 00FH         ;r0 &= %00001111;
        bctr,eq CHECKPAUSE_1 ;if (==) goto CHECKPAUSE_1;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
DRAWSIDES:
;4 per row by 13 rows
        lodi,r3 034H         ;r3 = 52; // loop iterator
DRAWSIDES_1:
;get offset of this '+'
        loda,r0 08A5h,r3     ;r0 = *(8A5 + r3);
        strz    r1           ;r1 = r0;
        lodi,r0 036H         ;r0 = $36;
        stra,r0 1800h,r1     ;*(1800 + r1) = r0 [$36]; // character '+'
        lodi,r0 036H         ;r0 = $36; // useless!
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0 [$36]; // character '+'
        bdrr,r3 DRAWSIDES_1  ;if (--r3 != 0) goto DRAWSIDES_1;
;end of loop
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
SAYROUND:
        lodi,r1 006H         ;r1 = 6; // loop iterator
;print "ROUND " at coords 4..9,12
SAYROUND_1:
        loda,r0 0280h,r1     ;r0 = *(280 + r1);
        stra,r0 18C3h,r1     ;*(18C3 + r1) = r0;
        bdrr,r1 SAYROUND_1   ;if (--r1 != 0) goto SAYROUND_1;
;end of loop
        loda,r0 ROUND        ;r0 = ROUND;
        iori,r0 010H         ;r0 |= %00010000; // set colour
;print round number at coords (11,12)
        stra,r0 18CBh        ;*(18CB = r0); // upper screen
;kill bullet
        lodi,r0 0FFH         ;r0 = -1;
        stra,r0 BULLETX      ;BULLETX = r0 [-1]; // user RAM
        eorz    r0           ;r0 = 0;
        stra,r0 1AEDh        ;*(1AED) = r0 [0]; // user RAM
        lodi,r0 050H         ;r0 = 80;
        lodi,r1 06AH         ;r1 = 106;
        stra,r0 SHIPY        ;SHIPY = r0 [80]; // user RAM
        stra,r1 SHIPX        ;SHIPX = r1 [106]; // user RAM
X0280:
        retc,un              ;return;
;Data---------------------------------------------------------------------
        db      02BH, 028H, 02EH, 027H, 01DH, 000H ;"ROUND "
;-------------------------------------------------------------------------
NEWROUND:
;registers accessed: r0, r1, r3
;hardware registers accessed: none
;variables read:
; MONOTONIC
; ROUND
;variables written:
; $18D2
; $1AD2
; $1AD3
; GREENX
; REDX
; CYANX
; YELLOWX
; UFOX
        lodi,r1 0FAH         ;r1 = $FA;
        loda,r3 MONOTONIC    ;r3 = MONOTONIC; // user RAM
        andi,r3 0DFH         ;r3 &= %11011111;
        loda,r0 ROUND        ;r0 = ROUND;
        comi,r0 001H         ;compare r0 against 1
        bcta,eq ROUND1       ;if (==) goto ROUND1;
        comi,r0 002H         ;compare r0 against 2
        bcta,eq ROUND2       ;if (==) goto ROUND2;
        comi,r0 003H         ;compare r0 against 3
        bcta,eq ROUND3       ;if (==) goto ROUND3;
        comi,r0 004H         ;compare r0 against 4
        bcta,eq ROUND4       ;if (==) goto ROUND4;
        bcta,un ROUND5       ;goto ROUND5;
ROUND1:
        stra,r1 GREENX       ;GREENX = r1 [$FA];
        stra,r3 REDX         ;REDX = r3;
        stra,r1 CYANX        ;CYANX = r1 [$FA];
        stra,r3 YELLOWX      ;YELLOWX = r3;
        stra,r1 18D2h        ;*(18D2) = r1 [$FA];
        stra,r1 UFOX         ;UFOX = r1 [$FA];
        retc,un              ;return;
ROUND2:
;note that bonus rounds are not considered to be true rounds
        stra,r1 GREENX       ;GREENX = r1 [$FA];
        stra,r3 REDX         ;REDX = r3;
        stra,r3 CYANX        ;CYANX = r3;
        stra,r3 YELLOWX      ;YELLOWX = r3;
        retc,un              ;return;
ROUND3:
        stra,r1 GREENX       ;GREENX = r1 [$FA];
        stra,r3 REDX         ;REDX = r3;
        stra,r3 CYANX        ;CYANX = r3;
        stra,r3 YELLOWX      ;YELLOWX = r3;
        eorz    r0           ;r0 = 0;
        stra,r0 18D2h        ;*(18D2) = r0 [0];
        retc,un              ;return;
ROUND4:
        stra,r3 GREENX       ;GREENX = r3;
        stra,r3 REDX         ;REDX = r3;
        stra,r3 CYANX        ;CYANX = r3;
        stra,r3 YELLOWX      ;YELLOWX = r3;
        retc,un              ;return;
ROUND5:
        stra,r3 GREENX       ;GREENX = r3;
        stra,r3 REDX         ;REDX = r3;
        stra,r3 CYANX        ;CYANX = r3;
        stra,r3 YELLOWX      ;YELLOWX = r3;
        lodi,r0 003H         ;r0 = 3;
        stra,r0 1AD2h        ;*(1AD2) = r0 [3];
        stra,r0 1AD3h        ;*(1AD3) = r0 [3];
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
ADDSCORE:
;arguments: r1 is the amount to add to score
        cpsl    001H         ;PSL &= %11111110;
        ppsl    008H         ;PSL |= %00001000;
;translate to decimal
        addi,r1 066H         ;r1 += $66;
        adda,r1 SCORELSB     ;r1 += SCORELSB; // user RAM
        dar,r1               ;convert r1 to decimal
        stra,r1 SCORELSB     ;SCORELSB = r1; // user RAM
        loda,r0 SCOREMSB     ;r0 = SCOREMSB; // user RAM
;translate to decimal
        addi,r0 066H         ;r0 += $66;
        dar,r0               ;convert r0 to decimal
        stra,r0 SCOREMSB     ;SCOREMSB = r0; // user RAM

        cpsl    008H         ;PSL &= %11110111;
        lodz    r1           ;r0 = r1;
        andi,r1 0F0H         ;r1 &= %11110000;
        rrr,r1               ;rotate r1 to the right quarce
	rrr,r1
	rrr,r1
	rrr,r1
        andi,r0 00FH         ;r0 &= %00001111;
        iori,r0 090H         ;r0 |= %10010000;
        stra,r0 1805h        ;*(1805) = r0; // upper screen
        iori,r1 090H         ;r1 |= %10010000;
        stra,r1 1804h        ;*(1804) = r1; // upper screen
        loda,r0 SCOREMSB     ;r0 = SCOREMSB; // user RAM
        strz    r1           ;r1 = r0;
        andi,r1 0F0H         ;r1 &= %11110000;
        rrr,r1               ;rotate r1 to the right quarce
	rrr,r1
	rrr,r1
	rrr,r1
        iori,r1 090H         ;r1 |= %10010000;
        stra,r1 1802h        ;*(1802) = r1;
        andi,r0 00FH         ;r0 &= %00001111;
        iori,r0 090H         ;r0 |= %10010000;
        stra,r0 1803h        ;*(1803) = r1;
        lodi,r0 090H         ;r0 = %10010000;
        stra,r0 1806h        ;*(1806) = r0;
        stra,r0 180Dh        ;*(180D) = r0;
        lodi,r1 004H         ;r1 = 4; // loop iterator
;*(1809..180C) = *(18D4..18D7);
ADDSCORE_1:
        loda,r0 18D3h,r1     ;r0 = *(18D3 + r1); // user RAM
        iori,r0 090H         ;r0 |= %10010000;
        stra,r0 1808h,r1     ;*(1808 + r1) = r0; // upper screen
        bdrr,r1 ADDSCORE_1   ;if (--r1 != 0) goto ADDSCORE_1;
;end of loop
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0351:
;variables accessed: *(1AED), *(1AEE), *(1AEF)
;registers accessed: r0..r3 (all)
;hardware registers accessed: none
        loda,r0 1AEDh        ;r0 = *(1AED);
        retc,eq              ;if (==) return;
;only if *(1AED) is nonzero do we proceed with this subroutine
;decrement *(1AED) by one
        subi,r0 001H         ;r0--;
        stra,r0 1AEDh        ;*(1AED) = r0;
        lodi,r3 03DH         ;r3 = $3D;
        comi,r0 000H         ;compare r0 against 0
;if *(1AED) is nonzero, r3 will remain $3D
        bcfr,eq L0362        ;if (!=) goto L0362;
L0360:
;if *(1AED) is zero, r3 will become 0
        lodi,r3 000H         ;r3 = 0;
L0362:
        loda,r1 1AEFh        ;r1 = *(1AEF); // user RAM
        loda,r0 1AEEh        ;r0 = *(1AEE); // user RAM
        bsta,un L04C5        ;gosub L04C5;
        lodz    r3           ;r0 = r3;
        comi,r2 0FFH         ;compare r2 against $FF
        bctr,eq L0375        ;if (==) goto L0375;
        stra,r0 1800h,r2     ;*(1800 + r2) = r0; // upper screen
        bctr,un L0378        ;goto L0378;
L0375:
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0; // lower screen
L0378:
        retc,un              ;return;
;-------------------------------------------------------------------------
CHECKCOLLIDEA:
;arguments: r1, r2, r3
;r3 can be 0, 2, 4, 6, 8 or 10
;there is a fixed relationship between the arguments, as shown below
;r1 =  GREENX, r2 =  GREENY, r3 =  0, or
;r1 =    REDX, r2 =    REDY, r3 =  2, or
;r1 =   CYANX, r2 =   CYANY, r3 =  4, or
;r1 = YELLOWX, r2 = YELLOWY, r3 =  6, or
;r1 =    UFOX, r2 =    UFOY, r3 =  8, or
;r1 =  ALIENX, r2 =  ALIENY, r3 = 10

;return to caller if BULLETX is more than 4 more or less than r1
        loda,r0 BULLETX      ;r0 = BULLETX;
        subi,r0 004H         ;r0 -= 4;
        comz    r1           ;compare r0 against r1
        retc,gt              ;if (>) return;
        addi,r0 008H         ;r0 += 8;
        comz    r1           ;compare r0 against r1
        retc,lt              ;if (<) return;

;return to caller if BULLETY is more than 8 more or less than r2
        loda,r0 BULLETY      ;r0 = BULLETY;
        subi,r0 008H         ;r0 -= 8;
        comz    r2           ;compare r0 against r2
        retc,gt              ;if (>) return;
        addi,r0 016H         ;r0 += 16;
        comz    r2           ;compare r0 against r2
        retc,lt              ;if (<) return;

;bullet-alien collision
        lodz    r3           ;r0 = r3;
;halve r0 (bring it into the range 0..5)
        rrr,r0               ;rotate r0 to the right once
;increment r0 by one (bring it into the range 1..6)
        addi,r0 001H         ;r0++;
        strz    r1           ;r1 = r0;
        bsta,un ADDSCORE     ;gosub ADDSCORE;
        lodi,r0 0FFH         ;r0 = $FF;
;kill the alien
        stra,r0 GREENY,r3    ;*(&GREENY + r3) = r0 [$FF];
        loda,r0 ENEMIESKILLED;r0 = ENEMIESKILLED;
;add decimal 1 (remember that $66 is subtracted)
        addi,r0 067H         ;r0 += $67;
        dar,r0               ;convert r0 to decimal
        stra,r0 ENEMIESKILLED;r0 = ENEMIESKILLED;
        comi,r0 020H         ;compare r0 against 32
        bctr,lt CHECKCOLLIDEA_1;if (<) goto CHECKCOLLIDEA_1;
;all aliens are dead
        lodi,r0 0FAH         ;r0 = $FA;
        stra,r0 GREENX,r3    ;*(&GREENX + r3) = r0 [$FA];
CHECKCOLLIDEA_1:
        bsta,un L0360        ;gosub L0360;
        lodi,r0 010H         ;r0 = 16;
        stra,r0 1AEDh        ;*(1AED) = r0 [16];
        loda,r1 BULLETX      ;r1 = BULLETX;
        loda,r2 BULLETY      ;r2 = BULLETY;
        stra,r1 1AEFh        ;*(1AEF) = r1;
        stra,r2 1AEEh        ;*(1AEE) = r2;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;this subroutine never directly returns
SAYENEMIES:
;print the number of enemies remaining
        lodi,r0 020H         ;r0 = 32;
        suba,r0 ENEMIESKILLED;r0 -= ENEMIESKILLED;
;r0 has $20, that gets made into $1A
        dar,r0               ;convert r0 to decimal

        strz    r1           ;r1 = r0;                                  ;1
        andi,r0 00FH         ;r0 &= %00001111;                          ;2

        iori,r0 050H         ;r0 |= %01010000; // set colour
;print ones digit
        stra,r0 1ACDh        ;*(1ACD) = r0; // lower screen

        rrr,r1               ;rotate r1 to the right quarce
	rrr,r1
	rrr,r1
	rrr,r1
;extract tens digit
        andi,r1 00FH         ;r0 &= %00001111;
        iori,r1 050H         ;r1 |= %01010000; // set colour
;print tens digit
        stra,r1 1ACCh        ;*(1ACC) = r0; // lower screen
        loda,r0 ENEMIESKILLED;r0 = ENEMIESKILLED;
        comi,r0 020H         ;compare r0 against 32
        retc,lt              ;if (<) return;
        loda,r0 1AEDh        ;r0 = *(1AED);
        retc,gt              ;if (>) return;
        loda,r0 SPRITESET    ;r0 = SPRITESET;
;only interested in the low bit (bit 0)
        andi,r0 001H         ;r0 &= %00000001;
        retc,eq              ;if (==) return;
;all enemies killed
        eorz    r0           ;r0 = 0;
        strz    r2           ;r2 = r0 [0];
        bsta,un MOVESCREEN   ;gosub MOVESCREEN;
        bsta,un BONUSROUND   ;gosub BONUSROUND;
;flows into INCROUND
INCROUND:
        loda,r0 ROUND        ;r0 = ROUND;
        addi,r0 001H         ;r0++;
        stra,r0 ROUND        ;ROUND = r0;
        lodi,r0 07FH         ;r0 = %01111111;
        stra,r0 1AD1h        ;*(1AD1) = r0 [%01111111];
        bsta,un NEWROUND     ;gosub NEWROUND;
        bsta,un SETVARS      ;gosub SETVARS;
;resurrect ship
        eorz    r0           ;r0 = 0;
        stra,r0 DEAD         ;DEAD = r0 [0];
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [0];
        stra,r0 ENEMIESKILLED;ENEMIESKILLED = r0 [0];
        lodi,r0 0A5H         ;r0 = $A5;
        stra,r0 18D8h        ;*(18D8) = r0 [$A5];
        bsta,un L079B        ;gosub L079B;
        bcta,un L003C        ;goto L003C;
;Subroutine---------------------------------------------------------------
MOVESCREEN:
        eorz    r0           ;r0 = 0;
        stra,r0 SPRITE1X     ;SPRITE1X = r0 [0];
        stra,r0 SPRITE2X     ;SPRITE2X = r0 [0];
        stra,r0 SPRITE3X     ;SPRITE3X = r0 [0];
;wait for end of vertical blank
MOVESCREEN_1:
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bctr,eq MOVESCREEN_1 ;if (==) goto MOVESCREEN_1;
;end of loop
;wait for start of vertical blank
MOVESCREEN_2:
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bcfr,eq MOVESCREEN_2 ;if (!=) goto MOVESCREEN_2;
;end of loop
        lodi,r1 006H         ;r1 = 6; // loop iterator
;*(1982..1987) = *(846..84B);
;copy the 6 'ship' rows into sprite #0 rows 2..7
MOVESCREEN_3:
        loda,r0 0845h,r1     ;r0 = *(845 + r1);
        stra,r0 1981h,r1     ;*(1981 + r1) = r0;
        bdrr,r1 MOVESCREEN_3 ;if (--r1 != 0) goto MOVESCREEN_3;
;end of loop
;set initial position of ship
        lodi,r0 050H         ;r0 = $50;
        lodi,r1 06AH         ;r1 = $6A;
        stra,r0 SPRITE0Y     ;SPRITE0Y = r0 [$50];
        stra,r1 SPRITE0X     ;SPRITE0X = r1 [$6A];
        lodi,r3 013H         ;r3 = 19; // outer loop iterator
MOVESCREEN_4:
        loda,r0 0468h,r3     ;r0 = *(468 + r3);
        stra,r0 PITCH        ;PITCH = r0;
MOVESCREEN_5:
;scroll the screen
        loda,r0 VSCROLL      ;r0 = VSCROLL;
        subi,r0 003H         ;r0 -= 3;
        stra,r0 VSCROLL      ;VSCROLL = r0;
        addi,r2 0FFH         ;r2--;
        andi,r2 007H         ;r2 &= %00000111;
        iori,r2 008H         ;r2 |= %00001000;
        stra,r2 VOLUME       ;VOLUME = r2;
        eorz    r0           ;r0 = 0;
        lodi,r1 020H         ;r1 = 32;
;loop 256*32 times = 8096 times
MOVESCREEN_6:
        bdrr,r0 MOVESCREEN_6 ;if (--r0 != 0) goto MOVESCREEN_6;
;end of loop
        bdrr,r1 MOVESCREEN_6 ;if (--r1 != 0) goto MOVESCREEN_6;
;end of loop
        andi,r2 007H         ;r2 &= %00000111;
        bdrr,r2 MOVESCREEN_5 ;if (--r2 != 0) goto MOVESCREEN_5;
;end of inner loop
        bdrr,r3 MOVESCREEN_4 ;if (--r3 != 0) goto MOVESCREEN_4;
;end of outer loop
X0468:
        retc,un              ;return;
;Data---------------------------------------------------------------------
;pitches
        db      012H, 014H, 008H, 006H
        db      009H, 004H, 012H, 016H
	db	004H, 000H, 000H, 006H
	db	009H, 004H, 006H, 004H
	db	008H, 005H, 002H
;waveform
;$16        #
;$15
;$14  #
;$13
;$12 #     #
;$11
;$10
;$0F
;$0E
;$0D
;$0C
;$0B
;$0A
;$09     #       #
;$08   #             #
;$07
;$06    #       #  #
;$05                  #
;$04      #  #    # #
;$03
;$02                   #
;$01
;$00          ##
;    <----time axis---->
;Subroutine---------------------------------------------------------------
L047C:
        loda,r0 DEAD         ;r0 = DEAD;
        comi,r0 002H         ;compare r0 against 2
        bcfr,eq L048E        ;if (!=) goto L048E;
        loda,r0 1AD1h        ;r0 = *(1AD1);
        andi,r0 0F0H         ;r0 &= %11110000;
        stra,r0 1AD1h        ;*(1AD1) = r0;
        bsta,un SETVARS      ;gosub SETVARS;
L048E:
        lodi,r1 004H         ;r1 = 4; // loop iterator
        eorz    r0           ;r0 = 0;
;clear $1AC3..$1AC6
L0491:
        stra,r0 1AC2h,r1     ;*(1AC2 + r1) = r0 [0];
        bdrr,r1 L0491        ;if (--r1 != 0) goto L0491;
;end of loop
        loda,r1 1AD0h        ;r1 = *(1AD0); // loop iterator
        bcta,eq L0FF1        ;if (==) goto L0FF1;
        lodi,r0 07EH         ;r0 = $7E;
L049E:
        stra,r0 1AC1h,r1     ;*(1AC1 + r1) = r0 [$7E];
        bdrr,r1 L049E        ;if (--r1 != 0) goto L049E;
;end of loop
        eorz    r0           ;r0 = 0;
        stra,r0 1AC2h        ;*(1AC2) = r0 [0];
        loda,r0 DEAD         ;r0 = DEAD;
        comi,r0 002H         ;compare r0 against 2
        retc,gt              ;if (>) return;
        retc,lt              ;if (<) return;
;only if DEAD is 2 do we reach this point
        lodi,r0 050H         ;r0 = $50;
        lodi,r1 06AH         ;r1 = $6A;
        stra,r0 SHIPY        ;SHIPY = r0 [$50];
        stra,r1 SHIPX        ;SHIPX = r1 [$6A];
        loda,r0 18D9h        ;r0 = *(18D9);
        retc,gt              ;if (>) return;
        loda,r0 1AD0h        ;r0 = *(1AD0);
        subi,r0 001H         ;r0--;
        stra,r0 1AD0h        ;*(1AD0) = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L04C5:
;arguments: r0, r1
;hardware accessed: VSCROLL is read
;registers accessed: r0, r1, r2
;r2 is always set to $FF at exit
        addi,r1 0D7H         ;r1 += $D7;
        rrr,r1               ;rotate r1 to the right thrice
	rrr,r1
	rrr,r1
        andi,r1 00FH         ;r1 &= %00001111;
        eori,r0 0FFH         ;Exclusive OR r0 with %11111111 (ie. flip all bits)
        adda,r0 VSCROLL      ;r0 += VSCROLL;
        comi,r0 062H         ;compare r0 against $62
        bctr,gt L04DF        ;if (>) goto L04DF;
        addi,r0 005H         ;r0 += 5;
        rrl,r0               ;rotate r0 to the left once
        andi,r0 0F0H         ;r0 &= %11110000;
        iorz    r1           ;r0 |= r1;
        strz    r2           ;r2 = r0;
        lodi,r1 0FFH         ;r1 = $FF;
        retc,un              ;return;
L04DF:
        addi,r0 09EH         ;r0 += $9E;
        rrl,r0               ;rotate r0 to the left once
        andi,r0 0F0H         ;r0 &= %11110000;
        iorz    r1           ;r0 |= r1;
        strz    r1           ;r1 = r0;
        lodi,r2 0FFH         ;r2 = $FF;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
CHECKCOLLIDEB:
;arguments: r1, r2
;r0 is a scratch register
;return code: sets DEAD to $70 if a collision occurs

;return to caller if SHIPX is more than 4 more or less than r1
        loda,r0 SHIPX        ;r0 = SHIPX;
        subi,r0 004H         ;r0 -= 4;
        comz    r1           ;compare r0 against r1
        retc,gt              ;if (>) return;
        addi,r0 008H         ;r0 += 8;
        comz    r1           ;compare r0 against r1
        retc,lt              ;if (<) return;

;return to caller if SHIPY is more than 8 more or less than r2
        loda,r0 SHIPY        ;r0 = SHIPY;
        subi,r0 008H         ;r0 -= 8;
        comz    r2           ;compare r0 against r2
        retc,gt              ;if (>) return;
        addi,r0 010H         ;r0 += 16;
        comz    r2           ;compare r0 against r2
        retc,lt              ;if (<) return;

;collision
        lodi,r0 070H         ;r0 = $70;

;NORMAL:
        stra,r0 DEAD         ;DEAD = r0 [$70];
;TRAINER:
;       nop
;       nop
;       nop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0505:
        loda,r0 ENEMIESKILLED
	comi,r0	009H
	bcfr,eq	L0511
	lodi,r0	001H
        stra,r0 18D2h
L0511:
	lodi,r1	001H
        loda,r0 ENEMIESKILLED
	comi,r0	020H
	bctr,lt	L051C
	lodi,r1	000H
L051C:
        stra,r1 TEMP         ;TEMP = r1; // user RAM
        lodi,r1 004H         ;r1 = 4; // loop iterator
        loda,r0 BALLSCROLL   ;r0 = BALLSCROLL;
        anda,r0 TEMP         ;r0 &= TEMP;
        retc,gt              ;if (>) return;
L0528:
        lodz    r1           ;r0 = r1;
        strz    r2           ;r2 = r0;
;r0, r1 and r2 all have the loop iterator
        rrl,r2               ;rotate r2 to the left once
        loda,r0 1ADAh,r2     ;r0 = *(1ADA + r2);
        suba,r0 1AD1h,r1     ;r0 -= *(1AD1 + r1);
        stra,r0 1ADAh,r2     ;*(1ADA + r2) = r0;
        bdrr,r1 L0528        ;if (--r1 != 0) goto L0528;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0537:
        loda,r1 SPRITESET    ;r1 = SPRITESET; // user RAM
        andi,r1 01FH         ;r1 &= %00011111;
        retc,gt              ;if (>) return;
        loda,r1 MONOTONIC    ;r1 = MONOTONIC; // user RAM
        andi,r1 003H         ;r1 &= %00000111;
        loda,r0 1AD6h,r1     ;r0 = *(1AD6 + r1);
;r0 holds the contents of a variable in the range $1AD6..$1ADD
;flip all bits of r0
;r0 = 255 - r0;
        eori,r0 0FFH         ;Exclusive OR r0 with %11111111
        addi,r0 001H         ;r0++;
        stra,r0 1AD6h,r1     ;*(1AD6 + r1) = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
MOVESPRITES:
        loda,r1 SPRITESET    ;r1 = SPRITESET;
        andi,r1 001H         ;r1 &= %00000001;
        rrl,r1               ;rotate r1 to the left once
;r1 is now either 0 or 2, according to SPRITESET

;r1 = 0 = y, r1 = 1 = x
;get GREENX or REDX, put into r2
        loda,r0 GREENX,r1    ;r0 = *(&GREENX + r1); // user RAM
        strz    r2           ;r2 = r0;
;get GREENY or REDY, put into r0
        loda,r0 GREENY,r1    ;r0 = *(&GREENY + r1); // user RAM
        bsta,un MOVESLAVE    ;gosub MOVESLAVE;
        stra,r0 SPRITE2Y     ;SPRITE2Y = r0;
        stra,r2 SPRITE2X     ;SPRITE2X = r2;

;get CYANX or YELLOWX, put into r2
        loda,r0 CYANX,r1     ;r0 = *(&CYANX + r1); // user RAM
        strz    r2           ;r2 = r0;
;get CYANY or YELLOWY, put into r0
        loda,r0 CYANY,r1     ;r0 = *(&CYANY + r1); // user RAM
        bsta,un MOVESLAVE    ;gosub MOVESLAVE;
        stra,r0 SPRITE3Y     ;SPRITE3Y = r0;
        stra,r2 SPRITE3X     ;SPRITE3X = r2;

;get UFOX or ALIENX, put into r2
        loda,r0 UFOX,r1      ;r0 = *(&UFOX + r1); // user RAM
        strz    r2           ;r2 = r0;
;get UFOY or ALIENY, put into r0
        loda,r0 UFOY,r1      ;r0 = *(&UFOY + r1); // user RAM
        bsta,un MOVESLAVE    ;gosub MOVESLAVE;
        stra,r0 SPRITE1Y     ;SPRITE1Y = r0;
        stra,r2 SPRITE1X     ;SPRITE1X = r2;

;get SHIPX or BULLETX, put into r2
        loda,r0 SHIPX,r1     ;r0 = *(&SHIPX + r1); // user RAM
        strz    r2           ;r2 = r0;
;get SHIPY or BULLETY, put into r0
        loda,r0 SHIPY,r1     ;r0 = *(&SHIPY + r1); // user RAM
        bsta,un MOVESLAVE    ;gosub MOVESLAVE;
;r0 is y-coord, r2 is x-coord
        stra,r0 SPRITE0Y     ;SPRITE0Y = r0;
        stra,r2 SPRITE0X     ;SPRITE0X = r2;

        loda,r0 SPRITES23COPY;r0 = SPRITES23COPY;
        eori,r0 033H         ;Exclusive OR r0 with %00110011
        stra,r0 SPRITES23COPY;SPRITES23COPY = r0;
        loda,r0 SPRITES01COPY;r0 = SPRITES01COPY; // user RAM
        eori,r0 00AH         ;Exclusive OR r0 with %00001010
        stra,r0 SPRITES01COPY;SPRITES01COPY = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
MOVESLAVE:
;checks y-bounds
;r0 is y, r2 is x
        comi,r0 0F0H         ;compare r0 against $F0
        bctr,gt L05AB        ;if (>) goto L05AB;
        comi,r0 02FH         ;compare r0 against $2F
        retc,gt              ;if (>) return;
L05AB:
;r0 <= $2F, or r0 > $F0
;we are in invalid y-bounds
;kill sprite
        lodi,r2 0FFH         ;r2 = $FF;
        retc,un              ;return;
;-------------------------------------------------------------------------
PLAYNOTE:
        loda,r0 DEAD         ;r0 = DEAD; // user RAM
        bctr,gt PLAYNOTE_2   ;if (>) goto PLAYNOTE_2;
        loda,r0 1AEDh        ;r0 = *(1AED); // user RAM
        bctr,gt PLAYNOTE_2   ;if (>) goto PLAYNOTE_2;
        loda,r0 SOUNDVAR     ;r0 = SOUNDVAR; // user RAM
        strz    r1           ;r1 = r0;
        comi,r1 080H         ;compare r1 against $80
        bctr,gt PLAYNOTE_1   ;if (>) goto PLAYNOTE_1;
        lodi,r0 010H         ;r0 = 16;
        stra,r0 PITCH        ;PITCH = r0 [16];
        lodi,r0 013H         ;r0 = 19;
;not sure why bit 4 is being used
        stra,r0 VOLUME       ;VOLUME = r0 [19];
        retc,un              ;return;
PLAYNOTE_1:
        lodi,r0 00FH         ;r0 = 15;
        stra,r0 VOLUME       ;VOLUME = r0 [15]; // full volume
        loda,r0 18D0h        ;r0 = *(18D0);
        andi,r0 00AH         ;r0 &= %00001010;
        stra,r0 PITCH        ;PITCH = r0;
        retc,un              ;return;
PLAYNOTE_2:
        lodi,r0 00BH         ;r0 = 11;
        lodi,r1 017H         ;r1 = 23;
        stra,r0 PITCH        ;PITCH = r0 [11];
;not sure why bit 4 is being used
        stra,r1 VOLUME       ;VOLUME = r1 [23];
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;registers accessed:          r0, r1
;hardware registers accessed: P2MIDDLEKEYS
;variables accessed:
; $18D0
; $18D9
; BULLETY
; BULLETX
; DEAD
; SOUNDVAR
; BULLETRANGE
;external jumps:              none
;external gosubs:             none
FIREBUTTON:
        loda,r0 BULLETX      ;r0 = BULLETX;
        comi,r0 0EBH         ;compare r0 against $EB
        bctr,lt FIREBUTTON_2 ;if (<) goto FIREBUTTON_2;
        loda,r0 DEAD         ;r0 = DEAD;
        retc,gt              ;if (>) return;
        loda,r0 18D9h        ;r0 = *(18D9);
        bctr,gt FIREBUTTON_1 ;if (>) goto FIREBUTTON_1;
        loda,r0 P2MIDDLEKEYS ;r0 = P2MIDDLEKEYS;
        andi,r0 00FH         ;r0 &= %00001111;
;if not pressed, return to caller
        bcfr,gt FIREBUTTON_5 ;if (!(>)) goto FIREBUTTON_5;
FIREBUTTON_1:
;fire a bullet
        lodi,r0 097H         ;r0 = 119;
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [119];

;BULLETY = SHIPY + 8;
        loda,r0 SHIPY        ;r0 = SHIPY;
        addi,r0 008H         ;r0 += 8;
        stra,r0 BULLETY      ;BULLETY = r0;
;BULLETRANGE = BULLETY + 85;
        addi,r0 055H         ;r0 += 85;
        stra,r0 BULLETRANGE  ;BULLETRANGE = r0;
;BULLETX = SHIPX;
        loda,r0 SHIPX        ;r0 = SHIPX;
        stra,r0 BULLETX      ;BULLETX = r0;
        retc,un              ;return;
FIREBUTTON_2:
;if an existing bullet is still onscreen, we run this code
        loda,r0 BULLETY      ;r0 = BULLETY;
        addi,r0 00AH         ;r0 += 10;
        strz    r1           ;r1 = r0;
        coma,r1 BULLETRANGE  ;compare r1 against BULLETRANGE
        bctr,gt FIREBUTTON_3 ;if (>) goto FIREBUTTON_3;
        comi,r1 0EBH         ;compare r1 against $EB
        bctr,lt FIREBUTTON_4 ;if (<) goto FIREBUTTON_4;
FIREBUTTON_3:
;bullet has gone far enough
        lodi,r0 000H         ;r0 = 0;
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [0];
        lodi,r0 0F2H         ;r0 = $F2;
        stra,r0 BULLETX      ;BULLETX = r0 [$F2];
FIREBUTTON_4:
;update bullet position
        stra,r0 BULLETY      ;BULLETY = r0;

        loda,r0 BULLETRANGE  ;r0 = BULLETRANGE;
        suba,r0 BULLETY      ;r0 -= BULLETY;
        stra,r0 18D0h        ;*(18D0) = r0;
FIREBUTTON_5:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
SCROLLSTARS:
        loda,r0 SPRITESET    ;r0 = SPRITESET;
        andi,r0 01FH         ;r0 &= %00011111;
        comi,r0 001H         ;compare r0 against 1
        bcfr,eq SCROLLSTARS_2;if (!=) goto SCROLLSTARS_2;
        eorz    r0           ;r0 = 0;
        stra,r0 1AF3h        ;*(1AF3) = r0 [0];
        bstr,un SCROLLSLAVE  ;gosub SCROLLSLAVE;
        loda,r0 1AF2h        ;r0 = *(1AF2); // user RAM
        addi,r0 001H         ;r0++;
        comi,r0 00DH         ;compare r0 against 13
        bctr,lt SCROLLSTARS_1;if (<) goto SCROLLSTARS_1;
        eorz    r0           ;r0 = 0;
SCROLLSTARS_1:
        stra,r0 1AF2h        ;*(1AF2) = r0;
SCROLLSTARS_2:
        lodi,r0 03CH         ;r0 = $3C;
        stra,r0 1AF3h        ;*(1AF3) = r0;
        bsta,un SCROLLSLAVE  ;gosub SCROLLSLAVE;
        retc,un              ;return;
;-------------------------------------------------------------------------
SCROLLSLAVE:
        lodi,r3 0C0H         ;r3 = $C0; // offset into screen memory
        lodi,r2 00DH         ;r2 = 13; // loop iterator (13 columns)
;loop counter goes from 13..1
SCROLLSLAVE_1:

;r0 = r1 = r2;
;that is the effect, but the intent is just:
;r1 = r2;
;but r0 is used because of 2650 instruction set limitations.
        lodz    r2           ;r0 = r2;
        strz    r1           ;r1 = r0;

        addi,r1 00CH         ;r1 += 12;
        suba,r1 1AF2h        ;r1 -= *(1AF2);
        loda,r0 08D9h,r1     ;r0 = *(8D9 + r1);
        addz    r3           ;r0 += r3;
        strz    r1           ;r1 = r0;

;*($1AF3) is the 'star' character ($3C) or an empty space ($00)
;ie. it holds what to print here
        loda,r0 1AF3h        ;r0 = *(1AF3);
        stra,r0 1800h,r1     ;*(1800 + r1) = r0;
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0;
        subi,r3 010H         ;r3 -= 16;
        bdrr,r2 SCROLLSLAVE_1;if (--r2 != 0) goto SCROLLSLAVE_1;
;end of loop

	retc,un
;Subroutine---------------------------------------------------------------
L067D:
        loda,r3 INTERPOLATION;r3 = INTERPOLATION; // user RAM
;flip lowest bit (bit 0)
        eori,r3 001H         ;Exclusive OR r3 with %00000001
        stra,r3 INTERPOLATION;INTERPOLATION = r3;
        loda,r1 BGCOLOURCOPY ;r1 = BGCOLOURCOPY;
;flip paddle interpolation bit
        eori,r1 040H         ;Exclusive OR r1 with %01000000
        stra,r1 BGCOLOURCOPY ;BGCOLOURCOPY = r1;
        loda,r0 DEAD         ;r0 = DEAD;
        bctr,eq MOVESHIP     ;if (==) goto MOVESHIP;
        subi,r0 001H         ;r0--;

;NORMAL:
        stra,r0 DEAD         ;DEAD = r0;
;TRAINER:
;       nop
;       nop
;       nop

        comi,r0 002H         ;compare r0 against 2
        retc,gt              ;if (>) return;
        bsta,un SETVARS      ;gosub SETVARS;
        lodi,r0 015H         ;r0 = 21;
        stra,r0 1AD1h        ;*(1AD1) = r0 [21];
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
MOVESHIP:
;r3 is passed holding INTERPOLATE
;moves player, ensures player remains within bounds
        loda,r0 18D9h        ;r0 = *(18D9);
        retc,gt              ;if (>) return;
;get PADDLEX or PADDLEY
;this is the only point at which PADDLEX/PADDLEY are actually used
        loda,r0 1AF7h,r3     ;r0 = *(1AF7 + r3);
        lodi,r1 000H         ;r1 = 0;
        comi,r0 0C0H         ;compare r0 against 12
        bcfr,gt MOVESHIP_1   ;if (!(>)) goto MOVESHIP_1;
        lodi,r1 003H         ;r1 = 3;
MOVESHIP_1:
        comi,r0 040H         ;compare r0 against 64
        bcfr,lt MOVESHIP_2   ;if (!(<)) goto MOVESHIP_2;
        lodi,r1 0FDH         ;r1 = $FD;
MOVESHIP_2:
;get SHIPY or SHIPX
        loda,r0 SHIPY,r3     ;r0 = *(&SHIPY + r3);
        comi,r3 001H         ;compare r3 against 1
        bctr,eq MOVESHIP_3   ;if (==) goto MOVESHIP_3;
;this eor/add operation is only performed for the y-axis
        eori,r1 0FFH         ;Exclusive OR r1 with %11111111 (ie. flip all bits)
        addi,r1 001H         ;r1++;
MOVESHIP_3:
        addz    r1           ;r0 += r1;
;set SHIPY or SHIPX
        stra,r0 SHIPY,r3     ;*(&SHIPY + r3) = r0;
;compare r0 against SHIPYMAX or SHIPXMAX
        coma,r0 089Eh,r3     ;compare r0 against *(89Eh + r3) // ROM data
        bcfr,gt MOVESHIP_4   ;if (!(>)) goto MOVESHIP_4;
        loda,r0 089Eh,r3     ;r0 = *(89E + r3); // ROM data
MOVESHIP_4:
;compare r0 against SHIPYMIN or SHIPXMIN
        coma,r0 08A0h,r3     ;compare r0 against *(8A0 + r3) // ROM data
        bcfr,lt MOVESHIP_5   ;if (!(<)) goto MOVESHIP_5;
        loda,r0 08A0h,r3     ;r0 = *(8A0 + r3); // ROM data
MOVESHIP_5:
;set SHIPY or SHIPX
        stra,r0 SHIPY,r3     ;*(&SHIPY + r3) = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
TITLETEXT:
        loda,r0 1AD1h        ;r0 = *(1AD1); // user RAM
        comi,r0 000H         ;compare r0 against 0
        retc,gt              ;if (>) return;

        lodi,r3 01FH         ;r3 = 31; // loop iterator
TITLETEXT_1:
        loda,r0 090Bh,r3     ;r0 = *(90B + r3);
        strz    r1           ;r1 = r0;
        loda,r0 0929h,r3     ;r0 = *(929 + r3);
        stra,r0 1800h,r1     ;*(1800 + r1) = r0;
        bdrr,r3 TITLETEXT_1  ;if (--r3 != 0) goto TITLETEXT_1;
;end of loop

        lodi,r3 026H         ;r3 = 38; // loop iterator
TITLETEXT_2:
        loda,r0 0947h,r3     ;r0 = *(947 + r3);
        strz    r1           ;r1 = r0;
        loda,r0 096Dh,r3     ;r0 = *(96D + r3);             
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0;
        bdrr,r3 TITLETEXT_2  ;if (--r3 != 0) goto TITLETEXT_2;
;end of loop

        loda,r0 18EEh        ;r0 = *(18EE); // user RAM
        addi,r0 001H         ;r0++;
        stra,r0 18EEh        ;*(18EE) = r0; // user RAM
        retc,gt              ;if (>) return;
        retc,lt              ;if (<) return;
        loda,r0 18EFh        ;r0 = *(18EF);
        addi,r0 001H         ;r0++;
        stra,r0 18EFh        ;*(18EF) = r0;
        comi,r0 020H         ;compare r0 against %00100000;
        retc,lt              ;if (<) return;
        bsta,un MOVESPRITES  ;gosub MOVESPRITES;
        bcta,un L0827        ;goto L0827;
;-------------------------------------------------------------------------
L0718:
;registers accessed: r0..r2
;variables accessed:
; MONOTONIC (read and written)
; SPRITESET (read)
;hardware registers accessed: none
        loda,r0 SPRITESET    ;r0 = SPRITESET; // user RAM
        andi,r0 00FH         ;r0 &= %00001111;
        retc,gt              ;if (>) return;
        loda,r0 MONOTONIC    ;r0 = MONOTONIC; // user RAM
        strz    r2           ;r2 = r0;
        strz    r1           ;r1 = r0;
        rrr,r1               ;rotate r1 to the right twice
	rrr,r1
        andi,r1 001H         ;r1 &= %00000001;
        andi,r2 001H         ;r2 &= %00000001;
        eorz    r1           ;Exclusive OR r0 with r1
        eori,r0 001H         ;Exclusive OR r0 with %00000001
        rrl,r0               ;rotate r0 to the left once
        rrr,r2               ;rotate r2 to the right once
        andi,r2 07FH         ;r2 &= %01111111;
        iorz    r2           ;r0 |= r2;
        stra,r0 MONOTONIC    ;MONOTONIC = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0735:
        lodi,r1 004H         ;r1 = 4; // loop iterator
L0737:
        lodz    r1           ;r0 = r1;
        strz    r3           ;r3 = r0;
;now r0, r1 and r3 all contain the loop iterator
        rrl,r3               ;rotate r3 to the left once
;r3 is now 8, 7, 4 or 2
        loda,r0 1ADBh,r3     ;r0 = *(1ADB + r3);
        adda,r0 1AD5h,r1     ;r0 += *(1AD5 + r1);
        bsta,un L0749        ;gosub L0749;
        stra,r0 1ADBh,r3     ;*(1ADB + r3) = r0;
        bdrr,r1 L0737        ;if (--r1 != 0) goto L0737;
;end of loop
	retc,un
;Subroutine---------------------------------------------------------------
L0749:
        comi,r0 0F0H         ;compare r0 against $F0
        bctr,lt L0750        ;if (<) goto L0750;
        lodi,r0 0FAH         ;r0 = $FA;
        retc,un              ;return;
L0750:
        comi,r0 093H         ;compare r0 against $93
        bctr,lt L0756        ;if (<) goto L0756;
        lodi,r0 03CH         ;r0 = $3C;
L0756:
        comi,r0 03BH         ;compare r0 against $3B
        bctr,gt L075C        ;if (>) goto L075C;
        lodi,r0 092H         ;r0 = $92;
L075C:
        retc,un              ;return;
;-------------------------------------------------------------------------
UFO:
;registers accessed:          r0, r1
;ROM data accessed:           SHIPXMAX, SHIPXMIN
;hardware registers accessed: none
;variables accessed:
; $18D2 (read and written)
; $18D3 (read and written)
; UFOY (read and written)
; UFOX (written)
; SPRITESET (read)
;external jumps:              none
;external gosubs:             none
        loda,r0 18D2h        ;r0 = *(18D2);
        comi,r0 0FAH         ;compare r0 against $FA
        retc,eq              ;if (==) return;

;increment UFOY by one
        loda,r0 UFOY         ;r0 = UFOY;
        addi,r0 001H         ;r0++;
        stra,r0 UFOY         ;UFOY = r0;

;move UFO
;*(18D3) += *(18D2);
        loda,r1 18D3h        ;r1 = *(18D3);
        adda,r1 18D2h        ;r1 += UNKNOWNVAR;
        stra,r1 18D3h        ;*(18D3) = r1;
        coma,r1 SHIPXMAX     ;compare r1 against SHIPXMAX [$93] (ROM data)
        bctr,gt UFO_1        ;if (>) goto UFO_1;
        coma,r1 SHIPXMIN     ;compare r1 against SHIPXMIN [$3B] (ROM data)
        bctr,lt UFO_1        ;if (<) goto UFO_1;
        bctr,un UFO_2        ;goto UFO_2;
UFO_1:
;kill UFO
        lodi,r1 0FFH         ;r1 = -1;
UFO_2:
        stra,r1 UFOX         ;UFOX = r1;
        loda,r0 SPRITESET    ;r0 = SPRITESET;
;r0 %= 64;
        andi,r0 03FH         ;r0 &= %00111111;
        retc,gt              ;if (>) return;
        retc,lt              ;if (<) return;

;we only kill UFOs on even MONOTONICs
;kill UFO
        lodi,r1 0FFH         ;r1 = -1;
        loda,r0 MONOTONIC    ;r0 = MONOTONIC;
        andi,r0 001H         ;r0 &= %00000001;
        bctr,gt UFO_3        ;if (>) goto UFO_3;
;don't kill UFO
        lodi,r1 001H         ;r1 = 1;
UFO_3:
;r1 is either -1 or 1 at this point
        stra,r1 18D2h        ;*(18D2) = r1;
	retc,un
;Subroutine---------------------------------------------------------------
L079B:
        lodi,r0 0FAH         ;r0 = $FA;
        stra,r0 SPRITE0X     ;SPRITE0X = r0;
        lodi,r3 0FFH         ;r3 = $FF;
;wait
L07A2:
        bdrr,r2 L07A2        ;if (--r2 != 0) goto L07A2;
        lodi,r0 00FH         ;r0 = 15;
        stra,r0 VOLUME       ;VOLUME = r0 [15]; // full volume
        lodz    r3           ;r0 = r3;
        rrr,r0               ;rotate r0 to the right once
        andi,r0 07FH         ;r0 &= %01111111;
        anda,r0 18D8h        ;r0 &= *(18D8);
        stra,r0 PITCH        ;PITCH = r0;
        bdrr,r3 L07A2        ;if (--r3 != 0) goto L07A2;
        retc,un              ;return;
;-------------------------------------------------------------------------
GAMEOVER:
        lodi,r3 00AH         ;r3 = 10; // loop iterator
;say "GAME  OVER"
GAMEOVER_1:
        loda,r0 083Bh,r3     ;r0 = *(83B + r3); // ROM data
        stra,r0 1A02h,r3     ;*(1A02 + r3) = r0; // lower screen
        bdrr,r3 GAMEOVER_1   ;if (--r3 != 0) goto GAMEOVER_1;
;end of loop
        lodi,r1 000H         ;r1 = 0;
GAMEOVER_2:
;get a digit of the score
        loda,r0 1802h,r1     ;r0 = *(1802 + r1); // upper screen
;compare against the relevant digit of the high score
        coma,r0 18D4h,r1     ;compare r0 against *(18D4 + r1);
;score is not better than the previous a high score
        bctr,lt HIGHSCORE_4  ;if (<) goto HIGHSCORE_4;
;score is better than the previous high score
        bctr,gt HIGHSCORE    ;if (>) goto HIGHSCORE;
;if digits are equal, we will have to look at the next digit
        addi,r1 001H         ;r1++;
        comi,r1 004H         ;compare r1 against 4
        bcfr,eq GAMEOVER_2   ;if (!=) goto GAMEOVER_2;
;end of loop
        bctr,un HIGHSCORE_4  ;goto HIGHSCORE_4;
;-------------------------------------------------------------------------
HIGHSCORE:

;BUG:
        lodi,r1 005H         ;r1 = 5; // loop iterator
;FIX:
;       lodi,r1 004H         ;r1 = 4; // loop iterator

;*(18D4..18D8) = *(1802..1806);
HIGHSCORE_1:
        loda,r0 1801h,r1     ;r0 = *(1801 + r1);
        stra,r0 18D3h,r1     ;*(18D3 + r1) = r0;
HIGHSCORE_2:
        lodi,r0 0AAH         ;r0 = $AA;
        stra,r0 18D8h        ;*(18D8) = r0 [$AA]; // user RAM
        bsta,un L079B        ;gosub L079B;
        bdrr,r1 HIGHSCORE_1  ;if (--r1 != 0) goto HIGHSCORE_1;
;end of loop
        eorz    r0           ;r0 = 0;
        stra,r0 VOLUME       ;VOLUME = r0 [0];
        stra,r0 PITCH        ;PITCH = r0 [0];
        lodi,r3 00AH         ;r3 = 10; // loop iterator
;*(1A03..1A0C) = 0;
HIGHSCORE_3:
        eorz    r0           ;r0 = 0;
        stra,r0 1A02h,r3     ;*(1A02 + r3) = r0 [0]; // lower screen
        bdrr,r3 HIGHSCORE_3  ;if (--r3 != 0) goto HIGHSCORE_3;
;end of loop

        bsta,un OLDROUTINE   ;gosub OLDROUTINE;

        bsta,un DRAWSIDES    ;gosub DRAWSIDES;
        bcta,un TITLESCREEN  ;goto TITLESCREEN;
HIGHSCORE_4:
	lodi,r1	001H
        bctr,un HIGHSCORE_2
;Subroutine---------------------------------------------------------------
SETVARS:
;arguments: none
;return code: none
;registers written: r0
;RAM written: GREENY, REDY, CYANY, YELLOWY, UFOX, ALIENX
;hardware accessed: none
;external jumps: none
;external gosubs: none
        lodi,r0 0D5H         ;r0 = $D5;
        stra,r0 GREENY       ;GREENY = r0 [$D5];
        stra,r0 REDY         ;REDY = r0 [$D5];
        stra,r0 CYANY        ;CYANY = r0 [$D5];
        stra,r0 YELLOWY      ;YELLOWY = r0 [$D5];
        lodi,r0 0FFH         ;r0 = $FF;
        stra,r0 ALIENX       ;ALIENX = r0 [$FF];
        lodi,r0 0DFH         ;r0 = $DF;
        stra,r0 UFOX         ;UFOX = r0 [$DF];
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;OLDROUTINE is identical to CLEARSCREEN and is thus unnecessary

OLDROUTINE:
        lodi,r3 0D0H                                                    ;2
        eorz    r0                                                      ;1
OLDROUTINE_1:             
        stra,r0 17FFh,r3                                                ;3
        stra,r0 19FFh,r3                                                ;3
        bdrr,r3 OLDROUTINE_1                                            ;2

        retc,un              ;return;                                   ;1
;-------------------------------------------------------------------------
L0827:
        lodi,r0 030H         ;r0 = 48;
        stra,r0 1AD1h        ;*(1AD1) = r0 [48]; // user RAM
        stra,r0 18D9h        ;*(18D9) = r0 [48]; // user RAM
        eorz    r0           ;r0 = 0;
        stra,r0 SCORELSB     ;SCORELSB = r0 [0]; // user RAM
        stra,r0 SCOREMSB     ;SCOREMSB = r0 [0]; // user RAM
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [0]; // user RAM
        bcta,un TITLELOOP_1  ;goto TITLELOOP_1;
;Data---------------------------------------------------------------------
        db      020H, 01AH, 026H, 01EH, 000H, 000H, 028H, 02FH, 01EH ;"GAME  OVER"
X0845:
        db      02BH
;any of the following four images can be copied into rows 2..7 (ie. the
;bottom six rows) of sprite #1.
;..###... alive ship
;..###...
;..#.#...
;.#####..
;##.#.##.
;.#...#..
        db      038H, 038H, 028H, 07CH, 0D6H, 044H
;........ alive bullet
;........
;...#....
;...#....                                                     
;........                                                     
;........
        db      000H, 000H, 010H, 010H, 000H, 000H
;#.....#. dead ship
;..#.#...
;...#....
;#.....#.
;...#....
;.#...#..
        db      082H, 028H, 010H, 082H, 010H, 044H
;........ dead bullet
;........
;...#....
;...#....
;........
;........
        db      000H, 000H, 010H, 010H, 000H
X085D:
        db      000H

;...#....
;...#....
;...#....
;...#....
;...#....
;...#....
;...#....
;...#....
        db      010H, 010H, 010H, 010H, 010H, 010H, 010H, 010H

;..####..
;.######.
;.######.
;#####.##
;#.#.####
;########
;.###.##.
;..####..
        db      03CH, 07EH, 0E7H, 0FBH, 0AFH, 0FFH, 076H, 03CH

;next is the image that is used for the green and red balloons

;REDCLASH:
;........
;..###...
;.#####..
;#######.
;#######.
;#######.
;.#####..
;..###...
        db      000H, 038H, 07CH, 0FEH, 0FEH, 0FEH, 07CH, 038H

;ALIENINVADERS:
;.#....#. $42
;.##..##. $66
;.#.##.#. $5A
;.######. $7E
;..####.. $3C
;..#..#.. $24
;.#....#. $42
;..#..#.. $24
;       db      042H, 066H, 05AH, 07EH, 03CH, 024H, 042H, 024H

;next is the image that is used for the cyan and yellow balloons

;REDCLASH:
;........
;..###...
;.#####..
;#######.
;#######.
;#######.
;.#####..
;..###...
        db      000H, 038H, 07CH, 0FEH, 0FEH, 0FEH, 07CH, 038H

;ALIENINVADERS:
;..###... $38
;.#####.. $7C
;.#.#.#.. $54
;.#####.. $7C
;.#...#.. $44
;..###... $38
;#.#.#.#. $AA
;........ $00
;       db      038H, 07CH, 054H, 07CH, 044H, 038H, 0AAH, 000H

;........
;........
;........
;........
;........
;........
;........
;........
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H

;....#...
;.#.#..#.
;..#..#..
;#..####.
;.####..#
;..#..#..
;.#.#..#.
;....#...
        db      008H, 052H, 024H, 09EH, 079H, 024H, 052H, 008H

;...#....
;...#....
;..###...
;..###...
;..#.#...
;.#####..
;##.#.##.
;.#...#..
        db      010H, 010H, 038H, 038H, 028H, 07CH, 0D6H, 044H

;########
;........
;........
;........
;........
;........
;........
;........
        db      0FFH, 000H, 000H, 000H, 000H, 000H, 000H, 000H

;x-range is $3B..$93, y-range is $40..$A0
SHIPYMAX:
	db	0A0H
SHIPXMAX:
        db      093H
SHIPYMIN:
	db	040H
SHIPXMIN:
        db      03BH

;something else
        db      008H, 004H, 002H
X08A5:
        db      001H

;locations of '+' characters at sides of screen
        db      000H, 001H, 00EH, 00FH
        db      010H, 011H, 01EH, 01FH
        db      020H, 021H, 02EH, 02FH
        db      030H, 031H, 03EH, 03FH
        db      040H, 041H, 04EH, 04FH
        db      050H, 051H, 05EH, 05FH
        db      060H, 061H, 06EH, 06FH
        db      070H, 071H, 07EH, 07FH
        db      080H, 081H, 08EH, 08FH
        db      090H, 091H, 09EH, 09FH
        db      0A0H, 0A1H, 0AEH, 0AFH
        db      0B0H, 0B1H, 0BEH, 0BFH
        db      0C0H, 0C1H, 0CEH
X08D9:
	db	0CFH

;star positions
        db      005H, 009H, 003H
	db	00BH, 007H, 008H, 005H
	db	004H, 00BH, 006H, 00AH
	db	005H, 00DH, 005H, 009H
	db	003H, 00BH, 007H, 008H
	db	005H, 004H, 00BH, 006H
	db	00AH, 005H, 00DH, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H, 010H
	db	038H, 07CH, 0FEH, 0FEH
	db	0FEH, 07CH, 038H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H
X090B:
        db      000H

;screen addresses used
;---- ---- ---- 1873 1874 1875 1876 1877 1878 1879 187A 187B 187C ---- ---- ----
;---- ---- ---- 1883 1884 1885 1886 1887 1888 1889 188A 188B 188C ---- ---- ---- 
;---- ---- ---- 1893 1894 1895 1896 1897 1898 1899 189A 189B 189C ---- ---- ---- 

;order of characters
;---- ---- ----    1    2    3    4    5    6    7    8    9   10 ---- ---- ----
;---- ---- ----   22   23   24   25   26   27   28   29   30   11 ---- ---- ---- 
;---- ---- ----   21   20   19   18   17   16   15   14   13   12 ---- ---- ---- 

;characters and colours
;---- ---- ----  #9r  #4g  #4g  #4g  #4g  #4g  #4g  #4g  #4g  #8r ---- ---- ----
;---- ---- ----  #7g   Rr   Er   Dr   Cg   Lg   Ag   Sg   Hg  #5g ---- ---- ---- 
;---- ---- ---- #10r  #6g  #6g  #6g  #6g  #6g  #6g  #6g  #6g #11r ---- ---- ---- 

;screen addresses for title text
        db      073H, 074H, 075H, 076H
        db      077H, 078H, 079H, 07AH
        db      07BH, 07CH, 08CH, 09CH
        db      09BH, 09AH, 099H, 098H
        db      097H, 096H, 095H, 094H
        db      093H, 083H, 084H, 085H
        db      086H, 087H, 088H, 089H
        db      08AH
X0929:
	db	08BH

;characters and colours for title text
        db      089H                                           ;top    left  corner (red,   built-in graphics char # 9)
        db      044H, 044H, 044H, 044H, 044H, 044H, 044H, 044H ;top          row    (green, built-in graphics char # 4)
        db      088H                                           ;top    right corner (red,   built-in graphics char # 8)
        db      045H                                           ;       right column (green, built-in graphics char # 5)
        db      08BH                                           ;bottom right corner (red,   built-in graphics char #11)
        db      046H, 046H, 046H, 046H, 046H, 046H, 046H, 046H ;bottom       row    (green, built-in graphics char # 6)
        db      08AH                                           ;bottom left  corner (red,   built-in graphics char #10)
        db      047H                                           ;       left  column (green, built-in graphics char # 7)
        db      0ABH, 09EH, 09DH                               ;"RED" (red)
        db      05CH, 065H, 05AH, 06CH                         ;"CLASH" (green)

X0947:
        db      061H

;---- ---- 1A02 1A03 1A04 1A05 1A06 1A07 1A08 1A09 ---- ---- 1A0C 1A0D ---- ----
;---- ---- ---- ---- ---- 1A15 1A16 1A17 1A18 1A19 1A1A ---- ---- ---- ---- ----
;---- ---- ---- 1A23 1A24 1A25 1A26 ---- ---- 1A29 1A2A 1A2B 1A2C ---- ---- ----
;---- ---- ---- 1A33 1A34 1A35 1A36 ---- ---- 1A39 1A3A 1A3B 1A3C ---- ---- ----
;---- ---- ---- ---- 1A44 1A45 ---- ---- 1A48 1A49 1A4A 1A4B ---- ---- ---- ---- 

;---- ----    L    I    C    E    N    S    E    D ---- ----    B    Y ---- ----
;---- ---- ---- ---- ----    T    E    K    H    A    N ---- ---- ---- ---- ----
;---- ---- ----    I    N    T    L ---- ----    C    O    R    P ---- ---- ----
;---- ---- ----    C    O    P    R ---- ----    1    9    8    2 ---- ---- ----
;---- ---- ---- ----    U    A ---- ----    L    T    D    . ---- ---- ---- ---- 

;positions of characters for credits
        db      033H, 034H, 035H, 036H                         ;"COPR"
        db      039H, 03AH, 03BH, 03CH                         ;"1982"
        db      015H, 016H, 017H, 018H, 019H, 01AH             ;"TEHKAN"
        db      023H, 024H, 025H, 026H                         ;"INTL"
        db      029H, 02AH, 02BH, 02CH                         ;"CORP"
        db      002H, 003H, 004H, 005H, 006H, 007H, 008H, 009H ;"LICENSED"
        db      00CH, 00DH                                     ;"BY"
        db      044H, 045H                                     ;"UA"
        db      048H, 049H, 04AH                               ;"LTD."
X096D:
	db	04BH

;the actual credits characters themselves
        db      01CH, 028H, 029H, 02BH                         ;"COPR"
        db      011H, 019H, 018H, 012H                         ;"1982"
        db      02DH, 01EH, 021H, 024H, 01AH, 027H             ;"TEHKAN"
        db      022H, 027H, 02DH, 025H                         ;"INTL"
        db      01CH, 028H, 02BH, 029H                         ;"CORP"
        db      025H, 022H, 01CH, 01EH, 027H, 02CH, 01EH, 01DH ;"LICENSED"
        db      01BH, 032H                                     ;"BY"
        db      02EH, 01AH                                     ;"UA"
        db      025H, 02DH, 01DH, 034H                         ;"LTD."

;something else
        db      043H, 039H, 03FH, 005H
        db      0DEH, 020H, 0CCH, 001H
        db      0DFH, 00CH, 001H, 0DFH
;Code---------------------------------------------------------------------
BONUSROUND:
        lodi,r0 0EEH         ;r0 = $EE;
        stra,r0 VSCROLL      ;VSCROLL = r0 [$EE];
;wait for CHARLINE to become $FD (ie. end of frame)
L09A5:
        loda,r0 CHARLINE     ;r0 = CHARLINE;
        comi,r0 0FDH         ;compare r0 against $FD
        bcfr,eq L09A5        ;if (!=) goto L09A5;
;end of loop

;BUG:
        lodi,r3 019H         ;r3 = 25; // loop iterator
;FIX:
;       lodi,r3 018H         ;r3 = 24; // loop iterator

;copy the balloon image into sprites #1..#3
L09AE:
;*(1988..19A0) = *(C02..C1A);
;sprite #1 ($1988..$198F) = *(C02..C09); C02,C03,C04,C05,C06,C07,C08,C09
;sprite #2 ($1990..$1997) = *(C0A..C11); C0A,C0B,C0C,C0D,C0E,C0F,C10,C11
;sprite #3 ($1998..$199F) = *(C12..C19); C12,C13,C14,C15,C16,C17,C18,C19
;note that *(C1A) is actually an opcode (lodi,r0), not data
;sprite #4 row 0  ($19A0) = *(C1A);      C1A
        loda,r0 0C01h,r3     ;r0 = *(C01 + r3);
        stra,r0 1987h,r3     ;*(1987 + r3) = r0;
        bdrr,r3 L09AE        ;if (--r3 != 0) goto L09AE;
;end of loop

        bsta,un CLEARSCREEN  ;gosub CLEARSCREEN;
        bsta,un NEWROUND     ;gosub NEWROUND;
        lodi,r0 050H         ;r0 = $50;
        lodi,r1 080H         ;r1 = $80;
        stra,r0 YELLOWX      ;YELLOWX = r0 [$50];
        stra,r0 UFOX         ;UFOX = r0 [$50];
        stra,r1 ALIENX       ;ALIENX = r1 [$80];
        lodi,r0 0FFH         ;r0 = -1;
        lodi,r1 001H         ;r1 = 1;
        stra,r0 UFODELTAX    ;UFODELTAX = r0 [-1];
        stra,r1 18DBh        ;*(18DB) = r1 [1];
        stra,r0 1AD2h        ;*(1AD2) = r0 [-1];
        stra,r1 1AD3h        ;*(1AD3) = r1 [1];
        stra,r1 1AD4h        ;*(1AD4) = r1 [1];
        stra,r0 1AD5h        ;*(1AD5) = r0 [-1];
        stra,r1 18DEh        ;*(18DE) = r1 [1];
        eorz    r0           ;r0 = 0;
        stra,r0 DEAD         ;DEAD = r0 [0];
        stra,r0 ENEMIESKILLED;ENEMIESKILLED = r0 [0];
;wait for end of vertical blank
L09E9:
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bctr,eq L09E9        ;if (==) goto L09E9;
;end of loop
;wait for start of vertical blank
L09ED:
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bcfr,eq L09ED        ;if (!=) goto L09ED;
;end of loop
        loda,r3 INTERPOLATION;r3 = INTERPOLATION; // user RAM
        loda,r0 P2PADDLE     ;r0 = P2PADDLE;
;set PADDLEX or PADDLEY
        stra,r0 1AF7h,r3     ;*(1AF7 + r3) = r0;
        loda,r1 BGCOLOURCOPY ;r1 = BGCOLOURCOPY;
        stra,r1 BGCOLOUR     ;BGCOLOUR = r1;
        loda,r0 SPRITES23COPY;r0 = SPRITES23COPY;
        stra,r0 SPRITES23CTRL;SPRITES23CTRL = r0;
        loda,r0 SPRITES01COPY;r0 = SPRITES01COPY;
;set double-height mode for sprite #1
        iori,r0 040H         ;r0 |= %01000000;
        stra,r0 SPRITES01CTRL;r0 = SPRITES01CTRL;
        lodi,r3 000H         ;r3 = 0;
        loda,r0 DEAD         ;r0 = DEAD;
        bctr,eq L0A17        ;if (==) goto L01A7;
        lodi,r3 00CH         ;r3 = 12;
L0A17:
;r3 is either 0 or 12, depending on DEAD
        loda,r0 SPRITESET    ;r0 = SPRITESET;
        andi,r0 001H         ;r0 &= %00000001;
        bctr,eq L0A20        ;if (==) goto L0A20;
        addi,r3 006H         ;r3 += 6;
L0A20:
;r3 is either 0, 6, 12 or 18, depending on DEAD and SPRITESET
        lodi,r2 006H         ;r2 = 6; // loop iterator
L0A22:
        lodz    r3           ;r0 = r3;
        addz    r2           ;r0 += r2;
        strz    r1           ;r1 = r0;
        loda,r0 0845h,r1     ;r0 = *(845 + r1);
        stra,r0 1981h,r2     ;*(1981 + r2) = r0;
        bdrr,r2 L0A22        ;if (--r2 != 0) goto L0A22;
;end of loop

L0A2D:

;wait for end of vertical blank
	tpsu	080H
	bctr,eq	L0A2D
;end of loop

        loda,r0 SPRITESET    ;r0 = SPRITESET;
        addi,r0 001H         ;r0++;
        stra,r0 BALLSCROLL   ;BALLSCROLL = r0;
        stra,r0 SPRITESET    ;SPRITESET = r0;
        andi,r0 00FH         ;r0 &= %00001111;
	bsta,eq	L0B4F
        bsta,un MOVESPRITES
	bsta,un	L067D
        bsta,un PLAYNOTE
        bsta,un FIREBUTTON
	bsta,un	L0505
	bsta,un	L0B20
	bsta,un	L0735
        bsta,un ADDSCORE
        loda,r0 DEAD         ;r0 = DEAD;
        bcta,gt L0ACD        ;if (>) goto L0ACD;
        loda,r0 18DEh
	bcta,gt	L0ACD

	lodi,r3	000H
        loda,r1 GREENX
        loda,r2 GREENY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	002H
        loda,r1 REDX
        loda,r2 REDY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	004H
        loda,r1 CYANX
        loda,r2 CYANY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	006H
        loda,r1 YELLOWX
        loda,r2 YELLOWY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	008H
        loda,r1 UFOX
        loda,r2 UFOY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	00AH
        loda,r1 ALIENX
        loda,r2 ALIENY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

        loda,r0 SHIPY
        loda,r1 SHIPX
	bsta,un	L0B92
        loda,r0 *18DCh       ;r0 = *(*(18DC));
        bcta,eq L0ACD        ;if (==) goto L0ACD;
        lodi,r0 070H         ;r0 = $70;

;NORMAL:
        stra,r0 DEAD         ;DEAD = r0 [$70];
;TRAINER:
;       nop
;       nop
;       nop

L0ACD:
        bsta,un L0351        ;gosub L0351;
        bsta,un L047C        ;gosub L047C;
        bsta,un L0AF6        ;gosub L0AF6;
        bsta,un L0DDE        ;gosub L0DDE;
        bsta,un CHECKPAUSE   ;gosub CHECKPAUSE;
        loda,r0 18D9h
	bcta,eq	L09E9
	lodi,r0	003H
        stra,r0 1AD0h
	bcta,un	L09E9
;Subroutine--------------------------------------------------------------0
CLEARSCREEN:
        lodi,r3 0D0H         ;r3 = $D0; // loop iterator
        eorz    r0           ;r0 = 0;
CLEARSCREEN_1:
        stra,r0 17FFh,r3     ;*(17FF + r3) = r0 [0]; // upper screen
        stra,r0 19FFh,r3     ;*(19FF + r3) = r0 [0]; // lower screen
        bdrr,r3 CLEARSCREEN_1;if (--r3 != 0) goto CLEARSCREEN_1;
;end of loop
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0AF6:
        loda,r0 1AEDh        ;r0 = *(1AED);
        retc,gt              ;if (>) return;
;only if *(1AED) <= 0 do we proceed with this subroutine
        loda,r0 SPRITESET    ;r0 = SPRITESET;
        andi,r0 001H         ;r0 &= %00000001;
        retc,eq              ;if (==) return;
;only if SPRITESET is odd do we proceed with this subroutine

        loda,r0 DEAD         ;r0 = DEAD;
        retc,gt              ;if (>) return;
;only if DEAD <= 0 do we proceed with this subroutine
        lodi,r3 00BH         ;r3 = 11;
;r3 will be     11,    9,       7,     5,    3,      1
;looking at ALIENX, UFOX, YELLOWX, CYANX, REDX, GREENX
L0B06:
        loda,r0 GREENY,r3    ;r0 = *(&GREENY + r3);
        comi,r0 0F0H         ;compare r0 against $F0
        retc,lt              ;if (<) return;
        subi,r3 002H         ;r3 -= 2;
;if (r3 > 0) goto L0B06;
        bctr,gt L0B06        ;if (>) goto L0B06;
;end of loop
        eorz    r0           ;r0 = 0;
        stra,r0 SOUNDVAR     ;SOUNDVAR = r0 [0];
        strz    r1           ;r1 = r0 [0];
        strz    r2           ;r2 = r0 [0];
        strz    r3           ;r3 = r0 [0];
        bsta,un MOVESCREEN   ;gosub MOVESCREEN;
        bsta,un CLEARSCREEN  ;gosub CLEARSCREEN;
        bcta,un NEWGAME      ;goto NEWGAME;
;Subroutine---------------------------------------------------------------
L0B20:
;increment UFOY by one
        loda,r0 UFOY         ;r0 = UFOY;
        addi,r0 001H         ;r0++;
        stra,r0 UFOY         ;UFOY = r0;

;increment ALIENY by one
        loda,r0 ALIENY       ;r0 = ALIENY;
        addi,r0 001H         ;r0++;
        stra,r0 ALIENY       ;ALIENY = r0;

        loda,r0 SPRITESET    ;r0 = SPRITESET;
        andi,r0 005H         ;r0 &= %00000101;
        retc,gt              ;if (>) return;

        loda,r0 UFOX         ;r0 = UFOX;
        adda,r0 UFODELTAX    ;r0 += UFODELTAX;
        bsta,un L0749        ;gosub L0749;
        stra,r0 UFOX         ;UFOX = r0;

        loda,r0 ALIENX       ;r0 = ALIENX;
        adda,r0 18DBh        ;r0 += *(18DB);
        bsta,un L0749        ;gosub L0749;
        stra,r0 ALIENX       ;ALIENX = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0B4F:
        loda,r3 1AF2h
	addi,r3	001H
	comi,r3	00DH
	bctr,lt	L0B5A
	lodi,r3	000H
L0B5A:
        stra,r3 1AF2h
	lodi,r2	0D0H
L0B5F:
        loda,r0 0BCEh,r3     ;r0 = *(BCE + r3);
        stra,r0 17F1h,r2     ;*(17F1 + r2) = r0;
        stra,r0 19F1h,r2     ;*(19F1 + R2) = R0;
        loda,r0 0BDBh,r3
        stra,r0 17F2h,r2
        stra,r0 19F2h,r2
        loda,r0 0BE8h,r3     ;r0 = *(BE8 + r3);
        stra,r0 17FDh,r2     ;*(17FD + r2) = r0;
        stra,r0 19FDh,r2
        loda,r0 0BF5h,r3
        stra,r0 17FEh,r2
        stra,r0 19FEh,r2
	subi,r2	010H
	addi,r3	001H
	comi,r3	00DH
	bctr,lt	L0B8D
	lodi,r3	000H
L0B8D:
	comi,r2	000H
	bcfr,eq	L0B5F
	retc,un
;Subroutine---------------------------------------------------------------
L0B92:
;unknown function
        loda,r3 VOLUME       ;r3 = VOLUME;
        rrl,r3               ;rotate r3 to the left thrice
	rrl,r3
	rrl,r3
        andi,r3 007H         ;r3 &= %00000111;
        stra,r3 18DCh        ;*(18DC) = r3; // user RAM
        suba,r1 18DCh        ;r1 -= *(18DC); // user RAM
        addi,r1 0D7H         ;r1 += $D7;
        rrr,r1               ;rotate r1 to the right thrice
	rrr,r1
	rrr,r1
        andi,r1 00FH         ;r1 &= %00001111;
        eori,r0 0FFH         ;Exclusive OR r0 with %11111111 (ie. flip all bits)
        adda,r0 VSCROLL      ;r0 += VSCROLL;
        comi,r0 062H         ;compare r0 against $62;
        bctr,gt L0BBF        ;if (>) goto L0BBF;
        addi,r0 005H         ;r0 += 5;
        rrl,r0               ;rotate r0 to the left once
        andi,r0 0F0H         ;r0 &= %11110000;
        iorz    r1           ;r0 |= r1;
        stra,r0 18DDh        ;*(18DD) = r0;
        lodi,r0 018H         ;r0 = $18;
        stra,r0 18DCh        ;*(18DC) = r0 [$18];
        retc,un              ;return;
L0BBF:
        addi,r0 09EH         ;r0 += $9E;
        rrl,r0               ;rotate r0 to the left once
        andi,r0 0F0H         ;r0 &= %11110000;
        iorz    r1           ;r0 |= r1;
        stra,r0 18DDh        ;*(18DD) = r0;
        lodi,r0 01AH         ;r0 = $1A;
        stra,r0 18DCh        ;*(18DC) = r0 [$1A];
        retc,un              ;return;
;Data---------------------------------------------------------------------
X0BCE:
	db	007H, 007H, 04EH, 043H
	db	043H, 04DH, 08EH, 08DH
	db	001H, 04EH, 04DH, 002H
	db	002H
X0BDB:
	db	000H, 000H, 000H, 04EH
	db	04DH, 000H, 000H, 000H
	db	000H, 001H, 002H, 000H
	db	000H
X0BE8:
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H, 00FH
	db	00CH, 000H, 000H, 000H
	db	000H
X0BF5:
	db	045H, 045H, 045H, 08FH
	db	08CH, 045H, 00FH, 00DH
	db	00EH, 00CH, 045H, 045H
X0C01:
        db      045H

;changing these does not seem to change anything
;...#....
;..###...
;.#####..
;#######.
;.#####..
;..###...
;...#....
;........
        db      010H, 038H, 07CH, 0FEH, 07CH, 038H, 010H, 000H

;...#....
;..###...
;.#####..
;#######.
;.#####..
;..###...
;...#....
;........
        db      010H, 038H, 07CH, 0FEH, 07CH, 038H, 010H, 000H

;...#....
;..###...
;.#####..
;#######.
;.#####..
;..###...
;...#....
;........
        db      010H, 038H, 07CH, 0FEH, 07CH, 038H, 010H, 000H
;Code Section-------------------------------------------------------------
;This is an extension of subroutine L0AF6.
;NEWGAME loop is as follows:
; set VSCROLL to $EE
; set some variables
; wait until CHARLINE == $FD
; copy gangly image into UDC #3
; set double-height mode for sprite #1
; gosub CLEARSCREEN
; draw stars into upper screen
; draw stars into lower screen
; gosub NEWROUND
; set some variables
; flow into MAINLOOP

NEWGAME:
; set VSCROLL to $EE
        lodi,r0 0EEH         ;r0 = $EE;
        stra,r0 VSCROLL      ;VSCROLL = r0 [$EE];

;set some variables
        lodi,r0 07FH         ;r0 = $7F;
        stra,r0 18DFh        ;*(18DF) = r0 [$7F];
        stra,r0 18E0h        ;*(18E0) = r0 [$7F];
        stra,r0 18E1h        ;*(18E1) = r0 [$7F];
        stra,r0 18E4h        ;*(18E4) = r0 [$7F];
        stra,r0 18E5h        ;*(18E5) = r0 [$7F];
        stra,r0 18E6h        ;*(18E6) = r0 [$7F];
        lodi,r0 0BFH         ;r0 = $BF;
        stra,r0 18E2h        ;*(18E2) = r0 [$BF];
        stra,r0 18E3h        ;*(18E3) = r0 [$BF];

;wait until CHARLINE == $FD
NEWGAME_1:
        loda,r0 CHARLINE     ;r0 = CHARLINE;
        comi,r0 0FDH         ;compare r0 against $FD
        bcfr,eq NEWGAME_1   ;if (!=) goto NEWGAME_1;
;end of loop

        lodi,r3 008H         ;r3 = 8; // loop iterator
NEWGAME_2:
;copy gangly image into UDC #3
        loda,r0 0FCEh,r3     ;r0 = *(FCE + r3);
        stra,r0 19B7h,r3     ;*(19B7 + r3) = r0;
        bdrr,r3 NEWGAME_2   ;if (--r3 != 0) goto NEWGAME_2;
;end of loop

        loda,r0 SPRITES01COPY;r0 = SPRITES01COPY;
;set double-height mode for sprite #1
        iori,r0 040H         ;r0 |= %01000000;
        stra,r0 SPRITES01CTRL;SPRITES01CTRL = r0;
        bsta,un CLEARSCREEN  ;gosub CLEARSCREEN;

        lodi,r3 00CH         ;r3 = 12; // loop iterator
;draw stars into upper screen
NEWGAME_3:
        loda,r0 0F8Dh,r3     ;r0 = *(F8D + r3);
        strz    r1           ;r1 = r0;
        lodi,r0 034H         ;r0 = $34;
        stra,r0 1800h,r1     ;*(1800 + r1) = r0 [$34]; // character '.'
        bdrr,r3 NEWGAME_3   ;if (--r3 != 0) goto NEWGAME_3;
;end of loop

;BUG:
        lodi,r3 017H         ;r3 = 23;
;FIX:
;       lodi,r3 016H         ;r3 = 22;

;draw stars into lower screen
NEWGAME_4:
        loda,r0 0F98h,r3     ;r0 = *(F98 + r3);
        strz    r1           ;r1 = r0;
        lodi,r0 034H         ;r0 = $34;
        stra,r0 1A00h,r1     ;*(1A00 + r1) = r0 [$34]; // character '.'
        bdrr,r3 NEWGAME_4   ;if (--r3 != 0) goto NEWGAME_4;
;end of loop

        bsta,un NEWROUND

;set some variables
        lodi,r0 $50
        lodi,r1 $80
        stra,r0 YELLOWX
        stra,r0 UFOX
        stra,r1 ALIENX
        lodi,r0 $A0
        stra,r0 GREENY
        stra,r0 REDY
        stra,r0 CYANY
        stra,r0 YELLOWY
        stra,r0 UFOY
        stra,r0 ALIENY
        lodi,r0 $FF
        lodi,r1 $01
        stra,r0 UFODELTAX
        stra,r1 $18DB
        stra,r0 $1AD2
        stra,r0 $1AD3
        stra,r0 $1AD4
        stra,r1 $1AD5
        stra,r1 $18DE
        eorz    r0           ;r0 = 0;
        stra,r0 DEAD         ;DEAD = r0 [0];
        stra,r0 ENEMIESKILLED;ENEMIESKILLED = r0 [0];
;Code Section (MAINLOOP)--------------------------------------------------
;Code flows into here from NEWGAME.
; wait for start of vertical blank
; wait for end of vertical blank
; set PADDLEX or PADDLEY
; multiplex sprites
; wait for start of vertical blank
; set some variables
; wait until CHARLINE == $F1
; horizontally scroll this row
; wait until CHARLINE == $F5
; set horizontal offset to 0
; call some subroutines
; check for collisions
; call some subroutines
;...and then back to top

MAINLOOP:
;wait for end of vertical blank (ie. start of display frame)
;while ((PSU & %10000000) == 0); // ie. wait until Sense bit is 1
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bctr,eq MAINLOOP     ;if (==) goto MAINLOOP;
;end of loop

;wait for start of vertical blank (ie. end of display frame)
;while ((PSU & %10000000) == 1); // ie. wait until Sense bit is 0
MAINLOOP_1:
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bcfr,eq MAINLOOP_1   ;if (!=) goto MAINLOOP_1;
;end of loop

;set PADDLEX or PADDLEY
        loda,r3 INTERPOLATION;r3 = INTERPOLATION;
        loda,r0 P2PADDLE     ;r0 = P2PADDLE;
        stra,r0 1AF7h,r3     ;*(1AF7 + r3) = r0;

;multiplex sprites
        loda,r1 BGCOLOURCOPY
        stra,r1 BGCOLOUR
        loda,r0 SPRITES23COPY
        stra,r0 SPRITES23CTRL
        loda,r0 SPRITES01COPY
	iori,r0	040H
        stra,r0 SPRITES01CTRL
	lodi,r3	000H
        loda,r0 DEAD
        bctr,eq MAINLOOP_2
	lodi,r3	00CH
MAINLOOP_2:
        loda,r0 SPRITESET
	andi,r0	001H
        bctr,eq MAINLOOP_3
	addi,r3	006H
MAINLOOP_3:

        lodi,r2 $06          ;r2 = $06; // loop iterator
MAINLOOP_4:
;r1 = r3 + r2;
        lodz    r3           ;r0 = r3;
        addz    r2           ;r0 += r2;
        strz    r1           ;r1 = r0;

;*($1982..$1987) = *($846..$84B);
        loda,r0 $845,r1      ;ROM data
        stra,r0 $1981,r2     ;sprite #0
        bdrr,r2 MAINLOOP_4
;end of loop

MAINLOOP_5:
;wait for end of vertical blank
;while ((PSU & %10000000) == 0); // ie. wait until Sense bit is 1
	tpsu	080H
        bctr,eq MAINLOOP_5

;set some variables
        loda,r0 SPRITESET    ;r0 = SPRITESET;
        addi,r0 001H         ;r0++;
        stra,r0 BALLSCROLL   ;BALLSCROLL = r0;
        stra,r0 SPRITESET    ;SPRITESET = r0;
	andi,r0	007H
	comi,r0	007H
        bcfr,eq MAINLOOP_6
        loda,r0 1AF2h
	addi,r0	001H
        stra,r0 1AF2h

MAINLOOP_6:
;wait until CHARLINE == $F1
        loda,r0 CHARLINE
	comi,r0	0F1H
        bcfr,eq MAINLOOP_6

;horizontally scroll this row
        loda,r0 BALLSCROLL
	andi,r0	007H
	rrr,r0
	rrr,r0
	rrr,r0
        adda,r0 VOLUME
        stra,r0 VOLUME

MAINLOOP_7:
;wait until CHARLINE == $F5
        loda,r0 CHARLINE
        comi,r0 $F5
        bcfr,eq MAINLOOP_7

;set horizontal offset to 0
        loda,r0 VOLUME
	andi,r0	01FH
        stra,r0 VOLUME

;call some subroutines
        bsta,un L0F4B
        bsta,un MOVESPRITES
	bsta,un	L067D
        bsta,un FIREBUTTON
	bsta,un	L0735
        bsta,un ADDSCORE
	bsta,un	L047C
	bsta,un	L0537
	bsta,un	L0718
	bsta,un	L0505
	bsta,un	L0EFB
        loda,r0 DEAD
        bcta,gt MAINLOOP_8
        loda,r0 18DEh
        bcta,gt MAINLOOP_8

;check for collisions
	lodi,r3	000H
        loda,r1 GREENX
        loda,r2 GREENY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	002H
        loda,r1 REDX
        loda,r2 REDY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	004H
        loda,r1 CYANX
        loda,r2 CYANY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	006H
        loda,r1 YELLOWX
        loda,r2 YELLOWY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	008H
        loda,r1 UFOX
        loda,r2 UFOY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

	lodi,r3	00AH
        loda,r1 ALIENX
        loda,r2 ALIENY
        bsta,un CHECKCOLLIDEB;gosub CHECKCOLLIDEB;
        bsta,un CHECKCOLLIDEA;gosub CHECKCOLLIDEA;

;call some subroutines
	bsta,un	L0E60
MAINLOOP_8:
	bsta,un	L0351
	bsta,un	L0EBC
	bsta,un	L0E9E
	bsta,un	L0E08
	bsta,un	L0DDE
        bsta,un CHECKPAUSE
        loda,r0 $18D9
        bcta,eq MAINLOOP
	lodi,r0	080H
        stra,r0 SHIPY
        bcta,un MAINLOOP
;Subroutine---------------------------------------------------------------
L0DDE:
        loda,r0 18D9h
	bctr,gt	L0E03
        loda,r0 18DEh
	bctr,eq	L0DED
	lodi,r0	050H
        stra,r0 SHIPY
L0DED:
        loda,r0 DEAD
	comi,r0	001H
	retc,gt
	bcfr,eq	L0DFD
        stra,r0 18DEh
	lodi,r3	000H
        stra,r3 SOUNDVAR
L0DFD:
        loda,r0 P2MIDDLEKEYS
	andi,r0	00FH
	retc,eq
L0E03:
	eorz	r0
        stra,r0 18DEh
	retc,un
;
L0E08:
	lodi,r3	008H
L0E0A:
        loda,r0 18DEh,r3
	retc,gt
	retc,lt
	bdrr,r3	L0E0A
        loda,r0 SPRITESET
	andi,r0	001H
	retc,eq
        loda,r0 1AEDh
        adda,r0 DEAD
	retc,gt
	lodi,r3	014H
L0E20:
	lodi,r1	005H
        bsta,un ADDSCORE
	bdrr,r3	L0E20
	eorz	r0
	lodi,r1	010H
L0E2A:
        stra,r0 184Fh,r1
	bdrr,r1	L0E2A
	strz	r2
        bsta,un MOVESCREEN
	lodi,r0	0FAH
        stra,r0 BULLETX
        bsta,un CLEARSCREEN
	lodi,r0	0FAH
        stra,r0 UFOX
        stra,r0 ALIENX
        loda,r0 18D9h
        adda,r0 18EDh
        bcta,eq INCROUND
        loda,r0 ROUND        ;r0 = ROUND;
        comi,r0 002H         ;compare r0 against 2
        bcta,lt INCROUND     ;if (<) goto INCROUND;
        lodi,r0 018H
        stra,r0 18EFh
	eorz	r0
        stra,r0 18D9h
        bcta,un TITLESCREEN_1
;Subroutine---------------------------------------------------------------
L0E60:
        loda,r0 BULLETY      ;r0 = BULLETY;
        loda,r1 BULLETX      ;r1 = BULLETX;
        bsta,un L0B92        ;gosub L0B92;
        loda,r0 *18DCh       ;r0 = *(*(18DC)); // user RAM
        comi,r0 07FH         ;compare r0 against $7F
        bctr,eq L0E75        ;if (==) goto L0E75;
        comi,r0 0BFH         ;compare r0 against $BF
        bctr,eq L0E75        ;if (==) goto L0E75;
        retc,un              ;return;
L0E75:
        loda,r0 BULLETX      ;r0 = BULLETX;
        subi,r0 028H         ;r0 -= $28;
        loda,r1 PITCH        ;r1 = PITCH;
        rrl,r1               ;rotate r1 to the left thrice
	rrl,r1
	rrl,r1
        andi,r1 007H         ;r1 &= %00000111;
        subz    r1           ;r0 -= r1;
        rrr,r0               ;rotate r0 to the right thrice
	rrr,r0
	rrr,r0
        andi,r0 00FH         ;r0 &= %00001111;
        loda,r1 1AF2h        ;r1 = *(1AF2);
        andi,r1 00FH         ;r1 &= %00001111;
        subz    r1           ;r0 -= r1;
        strz    r3           ;r3 = r0;
        eorz    r0           ;r0 = 0;
        stra,r0 18DFh,r3     ;*(18DF + r3) = r0;
        lodi,r1 008H         ;r1 = 8;
        bsta,un ADDSCORE     ;gosub ADDSCORE;
        lodi,r0 0F2H         ;r0 = $F2;
        stra,r0 BULLETX      ;BULLETX = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0E9E:
	lodi,r1	00AH
L0EA0:
        loda,r0 GREENY,r1
	comi,r0	02BH
	bctr,gt	L0EAE
	lodi,r0	0A0H
        stra,r0 GREENY,r1
	bctr,un	L0EB7
L0EAE:
	comi,r0	0C0H
	bctr,lt	L0EB7
	lodi,r0	02BH
        stra,r0 GREENY,r1
L0EB7:
	subi,r1	002H
	bcfr,lt	L0EA0
	retc,un
;Subroutine---------------------------------------------------------------
L0EBC:
        loda,r0 DEAD
	bctr,gt	L0EF0
        loda,r0 1AEDh
	bctr,gt	L0EF0
        loda,r0 SOUNDVAR
	strz	r1
	comi,r1	080H
	bctr,gt	L0EE2
        loda,r0 1AF2h
	andi,r0	01FH
	comi,r0	011H
	bctr,lt	L0ED9
	lodi,r0	000H
L0ED9:
        stra,r0 PITCH
	lodi,r0	00FH
        stra,r0 VOLUME
	retc,un
L0EE2:
	lodi,r0	00FH
        stra,r0 VOLUME
        loda,r0 SPRITESET
	andi,r0	01FH
        stra,r0 PITCH
	retc,un
L0EF0:
	lodi,r0	017H
        stra,r0 VOLUME
	lodi,r0	00BH
        stra,r0 PITCH
	retc,un
;Subroutine---------------------------------------------------------------
;unknown function
;arguments: none
;return code: none
;registers accessed: r0, r1, r3
;hardware accessed: none
;RAM accessed: UFOY, UFOX, ALIENY, ALIENX, SHIPX (through slave
; COMPARE), SPRITESET, UFODELTAX, *(18DB)
L0EFB:
        loda,r0 UFOX
        adda,r0 UFODELTAX
        stra,r0 UFOX
        loda,r0 UFOY
	addi,r0	0FFH
        stra,r0 UFOY
        loda,r0 ALIENX
        adda,r0 18DBh
        stra,r0 ALIENX
        loda,r0 ALIENY
	addi,r0	001H
        stra,r0 ALIENY
        loda,r0 SPRITESET
	andi,r0	00FH
        retc,gt              ;if (>) return;
        loda,r0 UFOY         ;r0 = UFOY; // useless!
;r1 is argument for COMPARE
        loda,r1 UFOX         ;r1 = UFOX;
;COMPARE UFOX against SHIPX, put result in UFODELTAX
        bsta,un COMPARE      ;gosub COMPARE;
;r3 is return code of COMPARE
        stra,r3 UFODELTAX    ;UFODELTAX = r3;
        loda,r0 ALIENY       ;r0 = ALIENY;
;r1 is argument for COMPARE
        loda,r1 ALIENX       ;r1 = ALIENX;
;COMPARE ALIENX against SHIPX, put result in *(18DB)
        bsta,un COMPARE      ;gosub COMPARE;
;r3 is return code of COMPARE
        stra,r3 18DBh        ;*(18DB) = r3;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;this is a slave (ie. subordinate) subroutine of L0EFB
;r1 is the passed argument
;r3 is the return code (-1, 0, or +1)
;if r1  < SHIPX, returns -1
;if r1  > SHIPX, returns +1
;if r1 == SHIPX, returns 0
;registers accessed: r1 is read, r3 is written
;hardware accessed: none
;RAM accessed: SHIPX is read
;external jumps: none
;external gosubs: none
COMPARE:
        lodi,r3 0FFH         ;r3 = -1;
        coma,r1 SHIPX        ;compare r1 against SHIPX // user RAM
        retc,gt              ;if (>) return;
        lodi,r3 001H         ;r3 = 1;
        coma,r1 SHIPX        ;compare r1 against SHIPX // user RAM
        retc,lt              ;if (<) return;
        lodi,r3 000H         ;r3 = 0;
        retc,un              ;return;
;-------------------------------------------------------------------------
L0F4B:
	eorz	r0
        loda,r3 1AF2h
	andi,r3	00FH
        stra,r0 185Fh,r3
        stra,r0 182Fh,r3
        stra,r0 183Fh,r3
        stra,r0 184Fh,r3
	eorz	r0
	strz	r2
        loda,r3 1AF2h
	andi,r3	00FH
L0F64:
        loda,r0 0FAFh,r2
        stra,r0 1820h,r3
        loda,r0 0FB7h,r2
        stra,r0 1830h,r3
        loda,r0 0FBFh,r2
        stra,r0 1840h,r3
        loda,r0 18DFh,r2
        stra,r0 1850h,r3
	addi,r2	001H
	comi,r2	008H
	retc,eq
	addi,r3	001H
	comi,r3	010H
	bcta,lt	L0F64
	lodi,r3	000H
	bcta,un	L0F64
;Data---------------------------------------------------------------------
X0F8D:
;junk byte (never accessed)
	db	017H

;offsets into upper display memory (ie. screen coords)
;starting coords of something
;---- ---- 1872 ---- ---- ---- ---- 1877 ---- ---- ---- ---- ---- 187D ---- ----
;---- ---- ---- 1883 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
;---- ---- ---- ---- ---- ---- ---- 1897 ---- ---- ---- ---- ---- 189D ---- ----
;18A0 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
;---- 18B1 ---- ---- 18B4 ---- ---- ---- ---- ---- ---- ---- ---- 18BD ---- ----
;---- ---- ---- ---- ---- 18C5 ---- ---- ---- 18C9 ---- ---- ---- ---- ---- ----

        db      072H, 077H, 07DH, 083H, 097H, 09DH, 0B1H, 0B4H, 0BDH, 0C5H
X0F98:
	db	0C9H

;offsets into lower display memory (ie. screen coords)
;starting coords of something
;---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
;---- ---- 1A12 ---- ---- ---- ---- ---- ---- 1A19 ---- ---- ---- ---- ---- 1A1F
;---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
;---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
;---- 1A41 ---- ---- ---- ---- 1A46 ---- ---- ---- ---- 1A4B ---- ---- ---- ----
;---- 1A51 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 1A5D ---- ----
;---- 1A61 ---- ---- ---- ---- ---- ---- ---- ---- 1A6A ---- ---- ---- ---- ----
;1A70 ---- ---- ---- 1A74 ---- ---- ---- ---- 1A79 ---- ---- ---- 1A7D ---- ----
;---- ---- 1A82 ---- ---- ---- ---- ---- ---- ---- ---- ---- 1A8C ---- ---- ----
;---- ---- ---- ---- ---- ---- ---- 1A97 ---- ---- ---- ---- ---- ---- ---- 1A9F
;1AA0 ---- ---- 1AA3 ---- ---- ---- ---- ---- ---- ---- ---- ---- 1AAD ---- ----
;---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
;---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

        db      0A0H ;this byte has two uses - upper and lower

        db      0A3H, 0ADH, 012H, 019H
        db      01FH, 041H, 046H, 04BH
        db      051H, 05DH, 061H, 06AH
        db      06FH, 070H, 074H, 079H
        db      07DH, 082H, 08CH, 097H
        db      09FH
X0FAF:
        db      000H ;this byte has two uses - lower and something else

        db      002H, 002H, 00CH, 00DH, 001H, 001H, 000H
X0FB7:
	db	00CH, 003H, 003H, 036H
	db	036H, 003H, 003H, 00DH
X0FBF:
        db      000H, 001H, 001H, 00FH
	db	00EH, 002H, 002H, 000H
	db	07FH, 07FH, 07FH, 0BFH
	db	0BFH, 07FH, 07FH
X0FCE:
        db      07FH
;...##...
;.######.
;########
;.######.
;...##...
;..#..#..
;.#....#.
;.#....#.
        db      018H, 07EH, 0FFH, 07EH, 018H, 024H, 042H, 042H

;something else
        db      000H, 067H, 00CH, 001H
        db      0EDH, 075H, 008H, 08CH
        db      083H
;Code---------------------------------------------------------------------
L0FE0:
        eorz    r0           ;r0 = 0;
        stra,r0 18EDh        ;*(18ED) = r0 [0]; // user RAM
        loda,r0 CONSOLE      ;r0 = CONSOLE;
        strz    r1           ;r1 = r0;
        andi,r1 004H         ;r1 &= %00000100; // extract DIFFICULTY bit
        retc,eq              ;if (==) return;
        stra,r1 18EDh        ;*(18ED) = r1;
        lodi,r0 001H         ;r0 = 1;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0FF1:
        loda,r0 18EDh        ;r0 = *(18ED);
        bcta,eq GAMEOVER     ;if (==) goto GAMEOVER;
        retc,un              ;return;
;Junk---------------------------------------------------------------------
        db      01EH, 04AH, 098H, 00CH
        db      004H, 053H, 03FH, 005H

        end

