;
;	Disassembled by:
;		DASMx object code disassembler
;		(c) Copyright 1996-1999   Conquest Consultants
;		Version 1.30 (Oct  6 1999)
;
;       File:           gundam.bin
;       CPU:            Signetics 2650 (2650 family)
;
;$VER: 1.0 (6.4.2009)
;Disassembled by Amigan Software in February-June 2003 and April 2009.
;URL:   http://amigan.classicgaming.gamespy.com/
;EMail: amigansoftware@gmail.com
;
;An IMPATIENT mode is available - replace PATIENT code with IMPATIENT code
;to enable it.
;
;Hardware Equates/Memory Map----------------------------------------------
;                $0000..$0FFF are ROM (first 4K of cartridge)
;                $1000..$17FF are unmapped
;                $1800..$18CF are upper screen display
;                $18D0..$18EF are user RAM
SPRITE0Y      equ 18F0h
SPRITE0X      equ 18F1h
SPRITE1Y      equ 18F2h
SPRITE1X      equ 18F3h
SPRITE2Y      equ 18F4h
SPRITE2X      equ 18F5h
SPRITE3Y      equ 18F6h
SPRITE3X      equ 18F7h
;                $18F8..$18FB are user RAM
VSCROLL       equ 18FCh ;crtc vertical position register
PITCH         equ 18FDh
;bit  7:    0 = normal mode
;           1 = alternate character mode color2x2 (2 backgrounds, 2 foreground colours)
;bits 6..0: pitch
VOLUME        equ 18FEh ;also other uses
;bits 7..5: horizontal scanline scrolling
;bits 4:    0 = sound on
;           1 = sound off
;bits 3..0: volume
CHARLINE      equ 18FFh ;current character line
P1LEFTKEYS    equ 1900h ;unused
;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 1901h
;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 1902h ;unused
;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 1903h ;unused
;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 1904h ;unused
;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 1905h ;unused
;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 1906h ;unused
;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 1907h ;unused
;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 1908h
;bits 7..3: unknown
;bit  2:    DIFFICULTY button
;bit  1:    OPTION button
;bit  0:    START button
;$1909..$197F: unmapped
UDC0          equ 1980h
;$1980..$1987: user-defined character #0
UDC1          equ 1988h
;$1988..$198F: user-defined character #1
UDC2          equ 1990h
;$1990..$1997: user-defined character #2
UDC3          equ 1998h
;$1998..$199F: user-defined character #3
;$19A0..$19A7: sprite #0
;$19A8..$19AF: sprite #1
;$19B0..$19B7: sprite #2
;$19B8..$19BF: sprite #3
;$19C0..$19F7: unmapped
RESOLUTION    equ 19F8h
;bit  7: 0 = normal mode
;        1 = block graphics mode
;bit  6: 0 = low-res mode
;        1 = high-res mode
;bits 5..0: rectangle descriptions in block graphics mode
BGCOLOUR      equ 19F9h
;bit  7:    0 = doublescanned sprites
;           1 = singlescanned sprites
;bit  6:    paddle interpolation (switches between the axes of the analog sticks)
;bits 5..3: colours of tile set 0
;bits 2..0: background colour
SPRITES23CTRL equ 19FAh
;bit  7:    0 = sprite #2 normal
;           1 = sprite #2 double-height
;bit  6:    0 = sprite #3 normal
;           1 = sprite #3 double-height
;bits 5..3: colours of sprite #2
;bits 2..0: colours of sprite #3
SPRITES01CTRL equ 19FBh
;bit  7:    0 = sprite #0 normal
;           1 = sprite #0 double-height
;bit  6:    0 = sprite #2 normal
;           1 = sprite #2 double-height
;bits 5..3: colours of sprite #0
;bits 2..0: colours of sprite #2
BGCOLLIDE     equ 19FCh ;unused
;bits 7..4: unknown
;bits 3..0: collision between sprites #3..#0 (respectively) and the background
SPRITECOLLIDE equ 19FDh ;unused
;bits 7..6: unknown
;bit 5:     sprite #2/#3 collision
;bit 4:     sprite #1/#3 collision
;bit 3:     sprite #1/#2 collision
;bit 2:     sprite #0/#3 collision
;bit 1:     sprite #0/#3 collision
;bit 0:     sprite #0/#3 collision
P2PADDLE      equ 19FEh ;unused
P1PADDLE      equ 19FFh
;                $1A00..$1ACF are lower screen display
;                $1AD0..$1AFF are user RAM
;                $1B00..$1FFF are unmapped
;                $2000..$7FFF are ROM (last 24K of cartridge)
;Variable Equates---------------------------------------------------------
;$18D0..$18D3: these are part of a set
ROMPOINTER2_H equ 18D4h
ROMPOINTER2_L equ 18D5h
POINTER_H     equ 18D6h
POINTER_L     equ 18D7h ;low (higher in memory but less significant) byte of POINTER
FLAGS         equ 18D8h
;FLAGS bit 7: 0=demo, 1=game
;      bit 6: frame toggle (for sprite multiplexing and/or paddle interleaving)
;      bit 5: 0=level 1, 1=level 2
;      bit 4: 0=flyby, 1=playing
; low nybble:  ?
P1PADDLEY     equ $18D9 ;$00: pushing up,   $6F: not pushing, $FF: pushing down
P1PADDLEX     equ $18DA ;$00: pushing left, $6F: not pushing, $FF: pushing right
;$18DB:        ?
LIVES         equ 18DCh ;(normally) $20 + lives (eg. $25 for '5')
;high nybble is as follows: $0 during first half of flyby
;                           $1 when dying
;                           $2 when healthy
;                           $3 when dying
PLAYERY       equ 18DDh ;range is $16..$B2
PLAYERX       equ 18DEh ;range is $6..$72
;$18DF:        normally $11, but when you move it goes $13, $12, $11.
FACING        equ 18E0h ;direction the player is facing and pointing
;FACING can have these values: %0000,0000 $00: facing right pointing up
;                              %0000,1011 $0B: facing left  pointing up
;                              %0001,0001 $11: facing right pointing up-right
;                              %0010,0011 $23: facing right pointing right
;                              %0011,0100 $34: facing right pointing down-right
;                              %0100,0101 $45: facing right pointing down
;                              %0100,0110 $46: facing left  pointing down
;                              %0101,0111 $57: facing left  pointing down-left
;                              %0110,1000 $68: facing left  pointing left
;                              %0111,1010 $7A: facing left  pointing up-left
;when low nybble is 0..5,  we are facing right.
;when low nybble is 6..11, we are facing left.
PLAYERCOUNTER equ $18E1 ;$00:      not moving, able to control.
;                        $FF..$FD: turning/moving, can't control.
;since you move smoothly by several pixels, this counts down.
;$18E2..$18EC: ?
BULLETDIR     equ 18EDh ;lower nybble (bits 3..0): direction of bullet
;always an even number. It is an offset into the table at $7D7
BULLETY       equ 18EEh
BULLETX       equ 18EFh
DURATION      equ 18F8h
NOTE          equ 18F9h ;offset into MUSICDATA
ROMPOINTER1_H equ 18FAh ;points to ROM data areas
ROMPOINTER1_L equ 18FBh ;low byte of ROMPOINTER1
GAMESTATUS    equ $1AD0
;$1AD0 is $20 during 1st half of level 1 flyby
;         $30 during 2nd half of level 1 flyby
;         $00 then $E7 after level 1 flyby
;         $20 during 1st half of level 2 flyby
;         $30 during 2nd half of level 2 flyby
;         $00 then $20 after level 2 flyby
;perhaps it should be $00 then $E7 after level 2 flyby
ENEMIES       equ 1AD1h
;ENEMIES upper nybble is number of enemies remaining
;ENEMIES lower nybble toggles between 0 and 1 according to frame
;$1AD2:        ?
ALIEN1STATUS  equ 1AD3h ;$10: dead, $20: alive, $30: dying
ALIEN1Y       equ 1AD4h ;stored inverted (increasing values towards bottom of screen)
ALIEN1X       equ 1AD5h ;add $2B to get screen coordinate
ALIEN1TOGGLE  equ 1AD6h ;seems to toggle between $10 and $11
ALIEN1DELTA   equ 1AD7h
;these are values of ALIEN1DELTA: $30 for down-right
;                                 $40 for down
;                                 $70 for up-left
ALIEN1COUNTER equ 1AD8h
ALIEN2STATUS  equ 1AD9h ;$10: dead, $20: alive, $30: dying
ALIEN2Y       equ 1ADAh ;stored inverted (increasing values towards bottom of screen)
ALIEN2X       equ 1ADBh ;add $2B to get screen coordinate
ALIEN2TOGGLE  equ 1ADCh ;seems to toggle between $10 and $11
ALIEN2DELTA   equ 1ADDh
;these are values of ALIEN2DELTA: $30 for down-right
;                                 $40 for down
;                                 $70 for up-left
ALIEN2COUNTER equ 1ADEh
;$1ADF..$1AF8: ?
;$1AF9..$1AFD: score. The trailing '0' is not stored. Score can be 0..999990.
SPR23CTRLCOPY equ 1AFEh
;$1AFF:        ?
;2650 Equates-------------------------------------------------------------
z     equ  0
eq    equ  z
p     equ  1
gt    equ  p
n     equ  2
lt    equ  n
un    equ  3
;-------------------------------------------------------------------------
        org     0000H
;BOOT:
        bsta,un INIT         ;gosub INIT;
        bsta,un 2913h        ;gosub CLEARSCREEN1;
        bsta,un 2913h        ;gosub CLEARSCREEN1;
        bsta,un SETXPOS      ;gosub SETXPOS;
        bsta,un SETHARDWARE  ;gosub SETHARDWARE;

;IMPATIENT:
;       bcta,un 2FFAH        ;gosub IMPATIENTROUTINE;
;PATIENT:
        bsta,un CREDITS      ;gosub CREDITS;

;hold credits onscreen momentarily
        lodi,r2 001H         ;r2 = 1; // useless! (only one iteration)
BOOT_1:
        lodi,r0 0FFH         ;r0 = 255;
        bsta,un DELAY        ;gosub DELAY;
        bdrr,r2 BOOT_1       ;if (--r2 != 0) goto BOOT_1; // useless! (only one iteration)
;end of loop

        bsta,un SCROLLDOWN   ;gosub SCROLLDOWN;
        bsta,un SETUDCS      ;gosub SETUDCS;
        bsta,un TITLESCREEN  ;gosub TITLESCREEN;
        bsta,un SCROLLUP     ;gosub SCROLLUP;

        loda,r0 FLAGS        ;r0 = FLAGS; // user RAM
        andi,r0 080H         ;r0 &= %10000000;
        bcfr,eq BOOT_2       ;if (!=) goto BOOT_2;
        lodi,r0 01DH         ;r0 = $1D; // character 'D'
        stra,r0 1820H        ;*(1820) = r0 [$1D]; // upper screen
        bctr,un CONSOLELOOP  ;goto CONSOLELOOP;
BOOT_2:
        lodi,r0 020H         ;r0 = $20; // character 'G'
        stra,r0 1820H        ;*(1820) = r0 [$20]; // upper screen

CONSOLELOOP:
;you are able to change between game ('G') and demo ('D') mode
;from the game over screen.

        loda,r0 CONSOLE      ;r0 = CONSOLE;
        andi,r0 002H         ;r0 &= %00000010; // extract OPTION bit
        bctr,eq CONSOLELOOP_3;if (==) goto CONSOLELOOP_3;

;Exclusive OR FLAGS with %10000000 (flip high bit)
        loda,r0 FLAGS        ;r0 = FLAGS; // user RAM
        eori,r0 080H         ;Exclusive OR r0 with %10000000
        stra,r0 FLAGS        ;FLAGS = r0; // user RAM

;extract high bit
        andi,r0 080H         ;r0 &= %10000000;
        bcfr,eq CONSOLELOOP_1;if (!=) goto CONSOLELOOP_1;
        lodi,r0 01DH         ;r0 = $1D; // character 'D'
        stra,r0 1820H        ;*(1820) = r0 [$1D]; // upper screen
        bctr,un CONSOLELOOP_2;goto CONSOLELOOP_2;
CONSOLELOOP_1:
        lodi,r0 020H         ;r0 = $20; // character 'G'
        stra,r0 1820H        ;*(1820) = r0 [$20]; // upper screen

CONSOLELOOP_2:
;wait for OPTION button to be released
        loda,r0 CONSOLE      ;r0 = CONSOLE;
        andi,r0 002H         ;r0 &= %00000010; // extract OPTION bit
        bcfr,eq CONSOLELOOP_2;if (!=) goto CONSOLELOOP_2;
;end of loop

CONSOLELOOP_3:
        loda,r0 CONSOLE      ;r0 = CONSOLE;
        andi,r0 001H         ;r0 &= %00000001; // extract START bit
        bctr,eq CONSOLELOOP  ;if (==) goto CONSOLELOOP;
        bctr,un NEWGAME      ;goto NEWGAME;

CONSOLELOOP_4:

;FLAGS |= %10000000;
        loda,r0 FLAGS        ;r0 = FLAGS;
        iori,r0 080h         ;r0 |= %10000000;
        stra,r0 FLAGS        ;FLAGS = r0;

NEWGAME:
;SPR23CTRLCOPY = r0 [$C0];
        lodi,r0 0C0H         ;r0 = $C0;
        stra,r0 SPR23CTRLCOPY;SPR23CTRLCOPY = r0 [$C0]; // user RAM

        bsta,un HISCORE      ;gosub HISCORE;
        lodi,r3 006H         ;r3 = 6; // music on
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;
        bsta,un SETBG        ;gosub SETBG;
        bsta,un 2913h        ;gosub CLEARSCREEN1;
        bsta,un 2913h        ;gosub CLEARSCREEN1;
        bsta,un SETXPOS      ;gosub SETXPOS;
        bsta,un DOHISCORE    ;gosub DOHISCORE;
        bsta,un DOSCORE      ;gosub DOSCORE;
        bsta,un DRAWLINE     ;gosub DRAWLINE;
        bsta,un DRAWBUILDINGS;gosub DRAWBUILDINGS;

;LIVES = 5;
        lodi,r0 005H         ;r0 = 5;
        stra,r0 LIVES        ;LIVES = r0 [5]; // user RAM

LEVEL1INIT:
;set up for level 1 flyby sequence
        bsta,un 2000h        ;gosub $2000;

LEVEL1FLYBY:
        lodi,r1 000H         ;r1 = 0; // level 1, flyby
        bsta,un SETFLAGS     ;gosub SETFLAGS;
        bsta,un VBLROUTINE   ;gosub VBLROUTINE;
        bsta,un FLIPFRAME    ;gosub FLIPFRAME;

;POINTER = GAMESTATUS;
        lodi,r3 000H         ;r3 = 0;
        bsta,un SETPOINTER   ;gosub SETPOINTER;

        bsta,un 2016h        ;gosub $2016;
        bsta,un 2042h        ;gosub $2042;

;POINTER = LIVES;
        lodi,r3 002H         ;r3 = 2;
        bsta,un SETPOINTER   ;gosub SETPOINTER;

        bsta,un L0365        ;gosub L0365;
        bsta,un L036E        ;gosub L036E;
        bsta,un PLAYMUSIC    ;gosub PLAYMUSIC;
        loda,r0 GAMESTATUS   ;r0 = GAMESTATUS; // loop iterator

;when GAMESTATUS = 0, flyby has finished
        bcfr,eq LEVEL1FLYBY  ;if (!=) goto LEVEL1FLYBY;
;end of loop

;level 1 flyby sequence has finished
;set up for level 1 main game
        bsta,un SETVARS      ;gosub SETVARS;

;if we skip LEVEL1FLYBY_1 we get exactly the same problem we have with level 2
        bcta,un 2FE0h        ;goto LEVEL1FLYBY_1;
;Code Section-------------------------------------------------------------
LEVEL1FLYBY_2:

;following subroutine just does *(1AF2) = $10;
        bsta,un 22e0h        ;gosub $22E0;

;following subroutine just does *(1AEB) = $10;
        bsta,un 2408h        ;gosub $2408;

LEVEL1LOOP:
        lodi,r1 010h         ;r1 = $10; // level 1, playing
        bsta,un SETFLAGS     ;gosub SETFLAGS;

;During demo mode, after the flyby has finished, you can press START to
;instantly start a new game (switches to game mode automatically).

;if ((FLAGS &= %10000000 == 0) && (CONSOLE &= %00000001 == 0)) goto CONSOLELOOP_4;
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 080h         ;r0 &= %10000000; // demo/game flag
        bcfr,eq LEVEL1LOOP_1 ;if (!=) goto LEVEL1LOOP_1;
        loda,r0 CONSOLE      ;r0 = CONSOLE;
        andi,r0 001h         ;r0 &= %00000001; // extract START bit
        bcfa,eq CONSOLELOOP_4;if (!=) goto CONSOLELOOP_4;

LEVEL1LOOP_1:
        bsta,un VBLROUTINE
        bsta,un FLIPFRAME
        bsta,un L056C
        bsta,un PLAYMUSIC

;POINTER = LIVES;
        lodi,r3 002h
        bsta,un SETPOINTER

        bsta,un L0365
        bsta,un L036E
        bsta,un 28e9h
        bsta,un L02DD
        loda,r0 ENEMIES      ;r0 = ENEMIES;
        strz    r1           ;r1 = r0;
        andi,r0 00fh         ;r0 &= %11110000;
        addi,r0 001h         ;r0++;
        comi,r0 002h         ;compare r0 against %00000010
        bcfr,eq LEVEL1LOOP_2 ;if (!=) goto LEVEL1LOOP_2;
        lodi,r0 000h         ;r0 = 0;
LEVEL1LOOP_2:
        andi,r1 0f0h         ;r1 &= %11110000;
        iorz    r1           ;r0 |= r1;
        stra,r0 ENEMIES      ;ENEMIES = r0; // user RAM
        andi,r0 001h         ;r0 &= %00000001;
        bcfr,eq LEVEL1LOOP_3 ;if (!=) goto LEVEL1LOOP_3;
        lodi,r3 00ch         ;r3 = %00001100;
        bsta,un 0ee3h        ;gosub $EE3;
        bctr,un LEVEL1LOOP_4 ;goto LEVEL1LOOP_4;
LEVEL1LOOP_3:

;POINTER = ALIEN2STATUS;
        lodi,r3 00eh         ;r3 = 14;
        bsta,un SETPOINTER   ;gosub SETPOINTER;

LEVEL1LOOP_4:
        bsta,un 212ah        ;gosub $212A;
        bsta,un 219eh        ;gosub ALIENDIRECTION;
        bsta,un COLLDETECT   ;gosub COLLDETECT;

;POINTER = $1AF2;
        lodi,r3 010h         ;r3 = 16;
        bsta,un SETPOINTER   ;gosub SETPOINTER;

        bsta,un 22e6h        ;gosub $22E6;
        bsta,un 234ch        ;gosub $234C;
        bsta,un COLLDETECT   ;gosub COLLDETECT;

;POINTER = $1AEB;
        lodi,r3 012h         ;r3 = 18;
        bsta,un SETPOINTER   ;gosub SETPOINTER;

        bsta,un 240eh
        bsta,un 2459h
        bsta,un COLLDETECT   ;gosub COLLDETECT;

;if (LIVES != 0) goto LEVEL1LOOP_6;
        loda,r0 LIVES        ;r0 = LIVES;
        comi,r0 020h         ;compare r0 against '0' [$20]
        bcfr,eq LEVEL1LOOP_6 ;if (!=) goto LEVEL1LOOP_6;

;say "GAME OVER"
        bsta,un GAMEOVER     ;gosub GAMEOVER;

;wait
        lodi,r2 003h         ;r2 = 3; // loop iterator
LEVEL1LOOP_5:
        lodi,r0 0ffh         ;r0 = 255;
        bsta,un DELAY        ;gosub DELAY;
        bdrr,r2 LEVEL1LOOP_5 ;if (--r2 != 0) goto LEVEL1LOOP_5;
;end of loop

        lodi,r1 000h         ;r1 = 0; // level 1, flyby
        bsta,un SETFLAGS     ;gosub SETFLAGS;

;if (FLAGS & %10000000 == 0) goto NEWGAME; else goto CONSOLELOOP;
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 080h         ;r0 &= %10000000;
;if demo mode
        bcta,eq NEWGAME      ;if (==) goto NEWGAME;
;otherwise must be game mode
        bcta,un CONSOLELOOP  ;goto CONSOLELOOP;

LEVEL1LOOP_6:
;it is not game over
        loda,r0 ENEMIES
        andi,r0 0f0h
        bcfa,eq LEVEL1LOOP
        loda,r0 1af2h
        andi,r0 0f0h
        comi,r0 010h
        bcfa,eq LEVEL1LOOP

;level 1 has been completed

;LIVES &= %00001111;
        loda,r0 LIVES        ;r0 = LIVES;
        andi,r0 00fh         ;r0 &= %00001111; // clear high nybble
        stra,r0 LIVES        ;LIVES = r0;

;PITCH = 0;
        lodi,r0 000h         ;r0 = 0;
        stra,r0 PITCH        ;PITCH = r0 [0];

        bsta,un SETXPOS      ;gosub SETXPOS;
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un DRAWLINE     ;gosub DRAWLINE;
        bsta,un DRAWBUILDINGS;gosub DRAWBUILDINGS;
        bsta,un SCROLLDOWN   ;gosub SCROLLDOWN;
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un DRAWLINE     ;gosub DRAWLINE;
        bsta,un SETBG_1      ;gosub SETBG_1;
        lodi,r1 020h         ;r1 = $20; // level 2, flyby
        bsta,un SETFLAGS     ;gosub SETFLAGS;
        bsta,un SCROLLUP     ;gosub SCROLLDOWN;
        lodi,r3 006h         ;r3 = 6; // music on
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;

;set up for level 2 flyby sequence
        bsta,un 2000h        ;gosub $2000;

;level 2 flyby loop
LEVEL2FLYBY:
        bsta,un VBLROUTINE   ;gosub VBLROUTINE;
        bsta,un FLIPFRAME    ;gosub FLIPFRAME;

;POINTER = GAMESTATUS;
        lodi,r3 000h
        bsta,un SETPOINTER

        bsta,un 2016h
        bsta,un 2042h

;POINTER = LIVES;
        lodi,r3 002h
        bsta,un SETPOINTER

        bsta,un L0365
        bsta,un L036E
        bsta,un PLAYMUSIC
        bsta,un DRAWSTARS
        loda,r0 GAMESTATUS

;when GAMESTATUS = 0, flyby has finished
        bcfr,eq LEVEL2FLYBY
;end of loop

;level 2 flyby sequence has finished
;set up for level 2 main game
        bsta,un SETVARS
        bsta,un 24F9h        ;gosub SETLEVEL2VARS;
        bsta,un 2748h        ;gosub $2748; // *(1AEE) = $10;

LEVEL2LOOP:
;set bits 5 and 4 of FLAGS to 1
        lodi,r1 030h         ;r1 = %00110000; // level 2, playing
        bsta,un SETFLAGS     ;gosub SETFLAGS;

;if ((FLAGS &= %10000000 == 0) && (CONSOLE &= %00000001 == 0)) goto CONSOLELOOP_4;
        loda,r0 FLAGS
        andi,r0 080h
        bcfr,eq LEVEL2LOOP_1
        loda,r0 CONSOLE
        andi,r0 001h
        bcfa,eq CONSOLELOOP_4

LEVEL2LOOP_1:
        bsta,un VBLROUTINE
        bsta,un FLIPFRAME
        bsta,un L056C
        bsta,un DRAWSTARS
        bsta,un PLAYMUSIC

;POINTER = LIVES;
        lodi,r3 002h
        bsta,un SETPOINTER

        bsta,un L0365
        bsta,un L036e
        bsta,un 28e9h
        bsta,un L02DD
        loda,r0 ENEMIES
        strz    r1
        andi,r0 00fh
        addi,r0 001h
        comi,r0 004h
        bcfr,eq LEVEL2LOOP_2
        lodi,r0 000h
LEVEL2LOOP_2:
        andi,r1 0f0h
        iorz    r1
        stra,r0 ENEMIES
        andi,r0 00fh
        comi,r0 000h
        bctr,eq LEVEL2LOOP_3
        comi,r0 001h
        bctr,eq LEVEL2LOOP_4
        comi,r0 002h
        bctr,eq LEVEL2LOOP_5
        bctr,un LEVEL2LOOP_6
LEVEL2LOOP_3:

;POINTER = $1AD2;
        lodi,r3 014h
        bsta,un SETPOINTER

        bctr,un LEVEL2LOOP_7
LEVEL2LOOP_4:

;POINTER = ALIEN2STATUS;
        lodi,r3 016h
        bsta,un SETPOINTER

        bctr,un LEVEL2LOOP_7
LEVEL2LOOP_5:

;POINTER = $1AE0;
        lodi,r3 018h
        bsta,un SETPOINTER

        bctr,un LEVEL2LOOP_7
LEVEL2LOOP_6:

;POINTER = $1AE7;
        lodi,r3 01ah
        bsta,un SETPOINTER

LEVEL2LOOP_7:
        bsta,un 2520h
        bsta,un 25aah
        bsta,un COLLDETECT

;POINTER = $1AEE;
        lodi,r3 01ch
        bsta,un SETPOINTER

        bsta,un 274eh
        bsta,un 27cbh
        bsta,un COLLDETECT
        loda,r0 LIVES
        comi,r0 020h
        bcfr,eq LEVEL2LOOP_9

;game over
        bsta,un GAMEOVER

        lodi,r2 003h         ;r2 = 3; // loop iterator
LEVEL2LOOP_8:
        lodi,r0 0ffh
        bsta,un DELAY
        bdrr,r2 LEVEL2LOOP_8
;end of loop

        lodi,r1 000h         ;r1 = 0; // level 1, flyby
        bsta,un SETFLAGS

;if (r0 & %10000000 == 0) goto NEWGAME; // if demo mode goto NEWGAME;
        loda,r0 FLAGS
        andi,r0 080h
        bcta,eq NEWGAME

        bcta,un CONSOLELOOP

LEVEL2LOOP_9:
;not game over

;if ((ENEMIES & %11110000) != 0 || (*($1AEE) & %11110000) != %00010000) goto LEVEL2LOOP;
        loda,r0 ENEMIES      ;r0 = ENEMIES;
        andi,r0 0f0h         ;r0 &= %11110000;
        bcfa,eq LEVEL2LOOP   ;if (!=) goto LEVEL2LOOP;
        loda,r0 1aeeh        ;r0 = *($1AEE);
        andi,r0 0f0h         ;r0 &= %11110000;
        comi,r0 010h         ;compare r0 against $10
        bcfa,eq LEVEL2LOOP   ;if (!=) goto LEVEL2LOOP;

;level 2 has been completed

;LIVES &= %00001111;
        loda,r0 LIVES        ;r0 = LIVES;
        andi,r0 00fh         ;r0 &= %00001111; // clear high nybble
        stra,r0 LIVES        ;LIVES = r0;

;PITCH = 0;
        lodi,r0 000h         ;r0 = 0;
        stra,r0 PITCH        ;PITCH = r0;

        bsta,un SETXPOS      ;gosub SETXPOS;
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un DRAWLINE     ;gosub DRAWLINE;
        bsta,un SCROLLDOWN   ;gosub SCROLLDOWN;
        bsta,un DRAWBUILDINGS;gosub DRAWBUILDINGS;
        lodi,r1 000h         ;r1 = 0; // level 1, flyby
        bsta,un SETFLAGS     ;gosub SETFLAGS;
        bsta,un SETBG        ;gosub SETBG;
        lodi,r3 006h         ;r3 = 6; // music on
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;
        bsta,un SCROLLUP     ;gosub SCROLLUP;
        bcta,un LEVEL1INIT   ;goto LEVEL1INIT;
;Subroutine---------------------------------------------------------------
L02DD:
;this seems to be the master bullet control routine

        loda,r0 FLAGS        ;r0 = FLAGS;
        lodi,r1 000h         ;r1 = 0;
        andi,r0 020h         ;r0 &= %00100000;
        bcfr,eq L02E8        ;if (!=) goto L02E8;
        lodi,r1 001h         ;r1 = 1;

L02E8:
;r1 is 0 or 1 at this point

;*(18E3)++;
        loda,r0 18e3h        ;r0 = *(18E3);
        addi,r0 001h         ;r0++;
        stra,r0 18e3h        ;*(18E3) = r0;

        comi,r0 004h         ;compare r0 against 4
        bcfr,eq L02F7        ;if (!=) goto L02F7;
        stra,r1 18e3h        ;*(18E3) = r1 [0 or 1];

L02F7:
        loda,r0 18e3h        ;r0 = *(18E3);

        lodi,r3 004h         ;r3 = 4;

;if (r0 == 0) goto L030E; // POINTER will be set to $18E4
        comi,r0 000h
        bctr,eq L030E

        lodi,r3 006h         ;r3 = 6;

;if (r0 == 1) goto L030E; // POINTER will be set to $18E7
        comi,r0 001h
        bctr,eq L030E

        lodi,r3 008h         ;r3 = 8;

;if (r0 == 2) goto L030E; // POINTER will be set to $18EA
        comi,r0 002h
        bctr,eq L030E

        bctr,un L031A
L030E:

;r3 is 4, 6 or 8 at this point
;POINTER = $18E4, $18E7 or $18EA for values of r3 of 4, 6 or 8 respectively
        bsta,un SETPOINTER

        bsta,un L0676
        bsta,un MOVEBULLET
        bsta,un L07E7
L031A:

;POINTER = BULLETDIR;
        lodi,r3 00ah
        bsta,un SETPOINTER

        bsta,un FIREBUTTON
        bsta,un MOVEBULLET
        bsta,un L07E7
        retc,un
;Subroutine---------------------------------------------------------------
SETBG:
;changing this line to lodi,r1 007h gives a black background for level 1
        lodi,r1 003H         ;r1 = %00000011;

        bctr,un SETBG_2      ;goto SETBG_2;
SETBG_1:
;alternate entry point
        lodi,r1 006H         ;r1 = %00000100;
SETBG_2:
        loda,r0 18E2H        ;r0 = *(18E2); // user RAM
        andi,r0 0F8H         ;r0 &= %11111000;
        iorz    r1           ;r0 |= r1;
        stra,r0 18E2H        ;*(18E2) = r0; // user RAM
        stra,r0 BGCOLOUR     ;BGCOLOUR = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
SETFLAGS:
;r1 is passed as an argument
;this routine sets bits 4 and 5 of FLAGS according to r1
;these bits are bit 5: the 'level number flag' (0 or 1 for level 1 or 2 respectively)
;and bit 4: the 'flyby/playing' flag (0 for flyby, 1 for playing)
        loda,r0 FLAGS        ;r0 = FLAGS; // user RAM
        andi,r0 0CFH         ;r0 &= %11001111;
        iorz    r1           ;r0 |= r1;
        stra,r0 FLAGS        ;FLAGS = r0; // user RAM

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0346:
        loda,r0 LIVES        ;r0 = LIVES; // user RAM
        andi,r0 00FH         ;r0 &= %00001111;
        iori,r0 020H         ;r0 |= %00100000;
        stra,r0 LIVES        ;LIVES = r0;

;LIVES   = *(360) [$98];
;PLAYERY = *(361) [64];
;PLAYERX = *(362) [17];
;*(18DF) = *(363) [105];
;FACING  = *(364) [1];
        lodi,r2 005H         ;r2 = 5; // loop iterator
        lodi,r1 001H         ;r1 = 1;
L0354:
        loda,r0 035FH,r1     ;r0 = *(35F + r1);
        stra,r0 LIVES,r1     ;*(&LIVES + r1) = r0; // user RAM
        addi,r1 001H         ;r1++;
        bdrr,r2 L0354        ;if (--r2 != 0) goto L0354;
;end of loop

        retc,un              ;return;
;Data for L0346-----------------------------------------------------------
X035F:
        db      025H, 098H, 040H, 011H, 069H, 001H
;Subroutine---------------------------------------------------------------
L0365:
        bsta,un TEST10       ;gosub TEST10;
        bcfr,eq L036D        ;if (!=) goto L036D;
        bsta,un L0346        ;gosub L0346;
L036D:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L036E:
;this routine is called by LEVEL1FLYBY, LEVEL1LOOP, LEVEL2FLYBY and LEVEL2LOOP
;POINTER points to LIVES during this routine

;if status nybble of LIVES is $20
        bsta,un TEST20       ;gosub TEST20;
        bcfa,eq L03A0        ;if (!=) goto L03A0;

        bsta,un 2885h        ;gosub CHECKXMOVE;
        comi,r0 000H         ;compare r0 against 0
        bcfr,eq L0385        ;if (!=) goto L0385;
        bsta,un 28B3h        ;gosub CHECKYMOVE;
        comi,r0 000H         ;compare r0 against 0
        bcfr,eq L0385        ;if (!=) goto L0385;
        bsta,un L0D27        ;gosub L0D27;
L0385:
        lodi,r1 005H         ;r1 = 5;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [5]);
                             ;r0 = *(&LIVES + r1 [5]);
                             ;r0 = *(18E2);
        comi,r0 001H         ;compare r0 against 1
        bcfr,eq L0393        ;if (!=) goto L0393;
        lodi,r0 0FFH         ;r0 = $FF;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [5]) = r0;
L0393:

;if (FLAGS & %01000000 != 0) then goto L03A0;
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 040H         ;r0 &= %01000000;
        bcfr,eq L03A0        ;if (!=) goto L03A0;

;it is an even-numbered frame
        bsta,un READPADDLE   ;gosub READPADDLE;
        bsta,un L042A        ;gosub L042A;
L03A0:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
READPADDLE:
;this routine is only called on even-numbered frames
;it is a service routine of L036E
;it reads P1PADDLEX and P1PADDLEY rather than directly accessing P1PADDLE
;POINTER points to LIVES during this routine

        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 080H         ;r0 &= %10000000;
        bcfr,eq READPADDLE_3 ;if (!= 0) goto READPADDLE_3;

;definitely demo (not game) mode here
;demo mode player just moves left and right

;P1PADDLEY = $80;
        lodi,r0 080H         ;r0 = %10000000;
        stra,r0 P1PADDLEY    ;P1PADDLEY = r0;

        loda,r0 PLAYERCOUNTER;r0 = PLAYERCOUNTER;
        andi,r0 010H         ;r0 &= %00010000;
        bcfr,eq READPADDLE_1 ;if (!= 0) goto READPADDLE_1;
        lodi,r0 000H         ;r0 = 0;
        bctr,un READPADDLE_2 ;goto READPADDLE_2;
;
READPADDLE_1:
        lodi,r0 0FFH         ;r0 = -1;
READPADDLE_2:
        stra,r0 P1PADDLEX    ;P1PADDLEX = r0;
READPADDLE_3:
        loda,r0 P1PADDLEY    ;r0 = P1PADDLEY;
        loda,r1 P1PADDLEX    ;r1 = P1PADDLEX;
        comi,r0 040H         ;compare r0 against $40
        bctr,lt READPADDLE_4 ;if (<) goto READPADDLE_4;
        comi,r0 0C0H         ;compare r0 against $C0
        bctr,gt READPADDLE_5 ;if (>) goto READPADDLE_5;
        comi,r1 040H         ;compare r1 against $40
        bctr,lt READPADDLE_12;if (<) goto READPADDLE_12;
        comi,r1 0C0H         ;compare r1 against $C0
        bctr,gt READPADDLE_8 ;if (>) goto READPADDLE_8;
        bctr,un READPADDLE_14;goto READPADDLE_14;
;
READPADDLE_4:
        comi,r1 040H         ;compare r1 against $40
        bctr,lt READPADDLE_13;if (<) goto READPADDLE_13;
        comi,r1 0C0H         ;compare r1 against $C0
        bctr,gt READPADDLE_7 ;if (>) goto READPADDLE_7;
        bctr,un READPADDLE_6 ;goto READPADDLE_6;
;
READPADDLE_5:
        comi,r1 040H         ;compare r1 against $40
        bctr,lt READPADDLE_11;if (<) goto READPADDLE_11;
        comi,r1 0C0H         ;compare r1 against $C0
        bctr,gt READPADDLE_9 ;if (>) goto READPADDLE_9;
        bctr,un READPADDLE_10;goto READPADDLE_10;
;
READPADDLE_6:
        lodi,r0 000H         ;r0 = 0;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_7:
        lodi,r0 010H         ;r0 = $10;
        bctr,un READPADDLE_15;goto READPADDLE_15
;
READPADDLE_8:
        lodi,r0 020H         ;r0 = $20;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_9:
        lodi,r0 030H         ;r0 = $30;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_10:
        lodi,r0 040H         ;r0 = $40;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_11:
        lodi,r0 050H         ;r0 = $50;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_12:
        lodi,r0 060H         ;r0 = $60;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_13:
        lodi,r0 070H         ;r0 = $70;
        bctr,un READPADDLE_15;goto READPADDLE_15;
;
READPADDLE_14:
;player is not pushing paddle
;PLAYERCOUNTER = 0;
        lodi,r1 005H         ;r1 = 5;
        lodi,r0 000H         ;r0 = 0;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [5]) = r0 [0];
                             ;*(&LIVES + r1 [5]) = r0 [0];
                             ;PLAYERCOUNTER = r0 [0];

        lodi,r1 004H         ;r1 = 4;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
                             ;r0 = *(&LIVES + r1 [4]);
                             ;r0 = FACING;
        andi,r0 0F0H         ;r0 &= %11110000; // extract high nybble
        bctr,un READPADDLE_END;goto READPADDLE_END; // return to caller

READPADDLE_15:
;this entire section means:
;if (PLAYERCOUNTER == 0) then PLAYERCOUNTER = $FF;
        strz    r2           ;r2 = r0; // preserve r0 in r2
        lodi,r1 005H         ;r1 = 5;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [5]);
                             ;r0 = *(&LIVES + r1 [5]);
                             ;r0 = PLAYERCOUNTER;
        comi,r0 000H         ;compare r0 against 0
;if player is already turning/moving then skip ahead
        bcfr,eq READPADDLE_16;if (!=) goto READPADDLE_16;
        lodi,r0 0FFH         ;r0 = $FF;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [5]) = r0 [$FF];
                             ;*(&LIVES + r1 [5]) = r0 [$FF];
                             ;PLAYERCOUNTER = r0 [$FF];
READPADDLE_16:
        lodz    r2           ;r0 = r2; // restore r0 from r2

READPADDLE_END:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L042A:
;this routine is only called for even-numbered frames
;it is a service routine of L036E
;POINTER points to LIVES during this routine
;r0 is passed as an argument

        strz    r2           ;r2 = r0;

        lodi,r1 004H         ;r1 = 4;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
                             ;r0 = *(&LIVES + r1 [4]);
                             ;r0 = FACING;
        andi,r0 00FH         ;r0 &= %00001111; // extract low nybble

;r0 is low nybble of FACING

;on (r2 / $10) goto L0453, L045A, L045C, L0466, L0468, L046E, L0470, L047A
;(assuming 'on goto' entries begin at 0)
        comi,r2 000H         ;compare r2 against 0
        bctr,eq L0453        ;if (r2 == 0) goto L0453;
        comi,r2 010H         ;compare r2 against $10
        bctr,eq L045A        ;if (r2 == $10) goto L045A;
        comi,r2 020H         ;compare r2 against $20
        bctr,eq L045C        ;if (r2 == $20) goto L045C;
        comi,r2 030H         ;compare r2 against $30
        bctr,eq L0466        ;if (r2 == $30) goto L0466;
        comi,r2 040H         ;compare r2 against $40
        bctr,eq L0468        ;if (r2 == $40) goto L0468;
        comi,r2 050H         ;compare r2 against $50
        bctr,eq L046E        ;if (r2 == $50) goto L046E;
        comi,r2 060H         ;compare r2 against $60
        bctr,eq L0470        ;if (r2 == $60) goto L0470;
        comi,r2 070H         ;compare r2 against $70
        bctr,eq L047A        ;if (r2 == $70) goto L047A;
        retc,un              ;return; // this opcode should never be reached
;
L0453: ;r2 == 0 
        comi,r0 006H         ;compare r0 against 6
        bctr,lt L047C        ;if (r0 < 6) goto L047C;
        bcta,un L04A8        ;goto L04A8;

L045A: ;r2 == $10
        bctr,un L0480        ;goto L0480; // inefficient!
;
L045C: ;r2 == $20
        comi,r0 003H         ;compare r0 against 3
        bctr,lt L0484        ;if (r0 < 3) goto L0484;
        comi,r0 009H         ;compare r0 against 9
        bcfr,lt L0484        ;if (!(r0 < 9)) goto L0484; // or, in other words
                             ;if (r0 >= 9) goto L0484;
        bctr,un L0488        ;goto L0488;

L0466: ;r2 == $30
        bctr,un L048C        ;goto L048C; // inefficient!
;
L0468: ;r2 == $40
        comi,r0 006H         ;compare r0 against 6
        bctr,lt L0490        ;if (r0 < 6) goto L0490;
        bctr,un L0494        ;goto L0494;

L046E: ;r2 == $50
        bctr,un L0498        ;goto L0498; // inefficient!
;
L0470: ;r2 == $60
        comi,r0 003H         ;compare r0 against 3
        bctr,lt L04A0        ;if (r0 < 3) goto L04A0;
        comi,r0 009H         ;compare r0 against 9
        bcfr,lt L04A0        ;if (!(r0 < 9)) goto L04A0; // or, in other words
                             ;if (r0 >= 9) goto L04A0;
        bctr,un L049C        ;goto L049C;

L047A: ;r2 == $70
        bctr,un L04A4        ;goto L04A4; // inefficient!
;
L047C: ;r2 == 0 && r0 < 6
        lodi,r0 000H         ;r0 = 0;
        bctr,un L04AC        ;goto L04AC;
;
L0480: ;r2 == $10
        lodi,r0 001H         ;r0 = 1;
        bctr,un L04AC        ;goto L04AC;
;
L0484: ;r2 == $20 && (r0 < 3 || r0 >= 9)
        lodi,r0 002H         ;r0 = 2;
        bctr,un L04AC        ;goto L04AC;
;
L0488: ;r2 == $20 && (r0 >= 3 && r0 < 9)
        lodi,r0 003H         ;r0 = 3;
        bctr,un L04AC        ;goto L04AC;
;
L048C: ;r2 == $30
        lodi,r0 004H         ;r0 = 4;
        bctr,un L04AC        ;goto L04AC;
;
L0490: ;r2 == $40 && r0 < 6
        lodi,r0 005H         ;r0 = 5;
        bctr,un L04AC        ;goto L04AC;
;
L0494: ;r2 == $40 && r0 >= 6
        lodi,r0 006H         ;r0 = 6;
        bctr,un L04AC        ;goto L04AC;
;
L0498: ;r2 == $50
        lodi,r0 007H         ;r0 = 7;
        bctr,un L04AC        ;goto L04AC;
;
L049C: ;r2 == $60 && (r0 >= 3 && r0 < 9)
        lodi,r0 008H         ;r0 = 8;
        bctr,un L04AC        ;goto L04AC;
;
L04A0: ;r2 == $60 && (r0 < 3 || r0 >= 9)
        lodi,r0 009H         ;r0 = 9;
        bctr,un L04AC        ;goto L04AC;
;
L04A4: ;r2 == $70
        lodi,r0 00AH         ;r0 = 10;
        bctr,un L04AC        ;goto L04AC;
;
L04A8: ;r2 == 0 && r0 >= 6
        lodi,r0 00BH         ;r0 = 11;
        bctr,un L04AC        ;goto L04AC; // so useless! :-)
;
L04AC:
        iorz    r2           ;r0 |= r2;
        strz    r2           ;r2 = r0;
        andi,r0 0F0H         ;r0 &= %11110000;
        strz    r3           ;r3 = r0;

        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
                             ;r0 = *(&LIVES + r1 [4]);
                             ;r0 = FACING;
        andi,r0 0F0H         ;r0 &= %11110000;

;if (r0 == r3) goto L04C2;
        comz    r3           ;compare r0 against r3
        bctr,eq L04C2        ;if (==) goto L04C2;

        lodi,r1 003H         ;r1 = 3;
        lodi,r0 013H         ;r0 = $13;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [3]) = r0 [$13];
                             ;*(&LIVES + r1 [3]) = r0 [$13];
                             ;*(18DF) = r0 [$13];
        lodi,r1 004H         ;r1 = 4;
L04C2:
        lodz    r2           ;r0 = r2;
        stra,r0 *POINTER_H,r1;*(POINTER + r1) = r0;
                             ;*(&LIVES + r1) = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L04C7:
;this is a popular routine
;it seems to print LIVES, and also handle some aspects of sprite
;positioning/imagery

;print LIVES on screen
        loda,r0 LIVES        ;r0 = LIVES;
        andi,r0 00FH         ;r0 &= %00001111;
        iori,r0 090H         ;r0 |= %10010000;
;r0 is now %1001xxxx, where x are unchanged
        stra,r0 1808H        ;*(1808) = r0; // upper screen (0,8)

;POINTER = LIVES;
        lodi,r3 002H
        bsta,un SETPOINTER

;compare status bits of LIVES against $20 (healthy)
        bsta,un TEST20       ;gosub TEST20;
        bctr,eq L04E2        ;if (==) goto L04E2;
        comi,r0 030H         ;compare r0 against $30

;inefficient - better to just bcfa,eq L0524 instead of these two lines
        bctr,eq L04E2        ;if (==) goto L04E2;
        bcta,un L0524        ;goto L0524;

L04E2:
;only if status nybble of LIVES is $20 (healthy) or $30 (dying)

        lodi,r1 001H         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(LIVES + r1 [1]);
                             ;r0 = PLAYERY;
        eori,r0 0FFH         ;Exclusive OR r0 with %11111111 (flip all bits)
        subi,r0 010H         ;r0 -= 16;
        stra,r0 SPRITE0Y     ;SPRITE0Y = r0;
        subi,r0 008H         ;r0 -= 8;
        stra,r0 SPRITE1Y     ;SPRITE1Y = r0;
        lodi,r1 002H         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(LIVES + r1 [2]);
                             ;r0 = PLAYERX;
        addi,r0 02BH         ;r0 += $2B;
        stra,r0 SPRITE0X     ;SPRITE0X = r0;
        stra,r0 SPRITE1X     ;SPRITE1X = r0;
        bsta,un L0525        ;gosub L0525;
        bsta,un L0F8E        ;gosub L0F8E;
        rrl,r0               ;rotate r0 to the left once
        strz    r1           ;r1 = r0;

;change UDC #0
        lodi,r2 000H
        bsta,un CHANGEUDC

;change UDC #1
	lodi,r2	008H
        bsta,un CHANGEUDC

        loda,r0 LIVES        ;r0 = LIVES;
        andi,r0 0F0H         ;r0 &= %11110000;
        comi,r0 030H         ;compare r0 against %001100000
        bcfr,eq L051F        ;if (!=) goto L051F;

        lodi,r0 0E4H         ;r0 = $E4;
        bctr,un L0521        ;goto L0521;
L051F:
        lodi,r0 0C0H         ;r0 = $C0;
L0521:
        stra,r0 SPRITES01CTRL;SPRITES01CTRL = r0 [$E4 or $C0];
L0524:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0525:
;POINTER is always LIVES during this routine
;this routine starts getting called halfway through flyby, and from then onwards

        bsta,un TEST20       ;gosub TEST20;
        bctr,eq L0545        ;if (==) goto L0545;

;*(18DF)--;
        lodi,r1 003H         ;r1 = 3;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [3]);
                             ;r0 = *(LIVES + r1 [3]);
                             ;r0 = $18DF;
        subi,r0 001H         ;r0--;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [3]) = r0;

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

        lodi,r1 000H         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]);
                             ;r0 = *(LIVES + r1 [0]);
                             ;r0 = LIVES;
        andi,r0 00FH         ;r0 &= %00001111;
        iori,r0 010H         ;r0 |= %00010000;
;r0 is now %0001xxxx, where x are unchanged
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0;

        bcta,un L055F        ;goto L055F;
;
L0545:

;ROMPOINTER2 = $2B57; // ROM data (upper of man facing right pointing up)
        lodi,r3 020H         ;r3 = $20;
        bsta,un SETROMPOINTER2;gosub SETROMPOINTER2;

        bcta,un L056B        ;goto L056B;
;
L054D:
        andi,r0 002H         ;r0 &= %00000010;
        bcfr,eq L0558        ;if (!=) goto L0558;

;ROMPOINTER2 = $2E3B; // ROM data (tall explosion)
        lodi,r3 034H         ;r3 = $34;
        bsta,un SETROMPOINTER2;gosub SETROMPOINTER2;

        bctr,un L0564        ;goto L0564;
;
L0558:

;ROMPOINTER2 = $2E4B; // ROM data (blank #3)
        lodi,r3 040H         ;r3 = $40;
        bsta,un SETROMPOINTER2;gosub SETROMPOINTER2;

        bctr,un L0564        ;goto L0564;
;
L055F:

;ROMPOINTER2 = $2E53; // ROM data (blank #4)
        lodi,r3 03AH         ;r3 = $3A;
        bsta,un SETROMPOINTER2;gosub SETROMPOINTER2;

L0564:
        lodi,r1 004H         ;r1 = 4;
        lodi,r0 000H         ;r0 = 0;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [4]) = r0 [0];
                             ;*(18E0 + r1 [4]) = r0 [0];
                             ;FACING = 0;
L056B:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;this subroutine is called by both LEVEL1LOOP and LEVEL2LOOP
;POINTER always points to LIVES during this routine

L056C:
        bsta,un TEST20       ;gosub TEST20;
        bcfa,eq L05DC        ;goto L05CD;

        lodi,r3 003h         ;r3 = 3; // loop iterator
        lodi,r2 000h         ;r2 = 0;
L0576:
;r2 is 0, 3, 6 for values of r3 of 3, 2, 1 respectively
        loda,r0 18e4h,r2     ;r0 = *(18E4 + r2);
        andi,r0 070h         ;r0 &= %01110000;
        comi,r0 020h         ;compare r0 against %00100000
        bcfa,eq L05B2        ;if (!=) goto L05B2;
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(&LIVES + r1 [1]);
                             ;r0 = PLAYERY;
        addi,r0 008h         ;r0 += 8;
        strz    r1           ;r1 = r0;
        loda,r0 18e5h,r2     ;r0 = *(18E5 + r2);
        addi,r0 004h         ;r0 += 4;
        subz    r1           ;r0 -= r1;
        bctr,eq L0594        ;if (==) goto L0594;
        bctr,gt L0594        ;if (>) goto L0594;
        eori,r0 0ffh         ;Exclusive OR r0 with %11111111 (flip all bits)
L0594:
        comi,r0 008h         ;compare r0 against 8
        bctr,gt L05B2        ;if (>) goto L05B2;
        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(&LIVES + r1 [2]);
                             ;r0 = PLAYERX;
        addi,r0 004h         ;r0 += 4;
        strz    r1           ;r1 = r0;
        loda,r0 18e6h,r2     ;r0 = *(18E6 + r2);
        addi,r0 004h         ;r0 += 4;
        subz    r1           ;r0 -= r1;
        bctr,eq L05AC        ;if (==) goto L05AC;
        bctr,gt L05AC        ;if (>) goto L05AC;
        eori,r0 0ffh         ;Exclusive OR r0 with %11111111
L05AC:
        comi,r0 004h         ;compare r0 against 4
        bctr,gt L05B2        ;if (>) goto L05B2;
        bctr,un L05B8        ;goto L05B8;
L05B2:
        addi,r2 003h         ;r2 += 3;
        bdrr,r3 L0576        ;if (--r3 != 0) goto L0576;
;end of loop

        bctr,un L05DC        ;goto L05DC;
L05B8:

;if (LIVES > '0') LIVES--;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = *(&LIVES + r1 [0]);
                             ;r0 = LIVES;
        andi,r0 00fh         ;r0 &= %00001111;
        bctr,eq L05C3        ;if (==) goto L05C3;
        subi,r0 001h         ;r0--;
L05C3:
        iori,r0 030h         ;r0 |= %00110000;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0; // inefficient!
                             ;*(&LIVES + r1 [0]) = r0;
                             ;LIVES = r0;

;*(18DF) = $30;
        lodi,r0 030h         ;r0 = $30;
        stra,r0 18dfh        ;*(18DF) = r0 [$30];

        loda,r0 18e4h,r2     ;r0 = *(18E4 + r2);
        andi,r0 00fh         ;r0 &= %00001111;
        iori,r0 030h         ;r0 |= %00110000;
;r0 is now 0011xxxx, where x are unchanged
        stra,r0 18e4h,r2     ;*(18E4 + r2) = r0;

        lodi,r3 004h         ;r3 = 4; // sound effect #3 (player killed)
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;
L05DC:
        retc,un              ;return;
;Data--------------------------------------------------------------------
;$5DD:
        db      02BH, 057H, 02EH
	db	03BH, 02EH, 04BH, 02EH
	db	053H
;Subroutine---------------------------------------------------------------
SETVARS:
        lodi,r0 003H         ;r3 = 3;
        stra,r0 18E3H        ;*(18E3) = r0 [3];
        lodi,r0 010H         ;r0 = $10;
        stra,r0 18E4H        ;*(18E4)   =
        stra,r0 18E7H        ;*(18E7)   =
        stra,r0 18EAH        ;*(18EA)   =
        stra,r0 BULLETDIR    ;BULLETDIR = r0 [$10];
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
FIREBUTTON:
;POINTER is always BULLETDIR in this subroutine
;this is a service routine of L02DD

        bsta,un TEST10
        bcfa,eq FIREBUTTON_END
        loda,r0 FLAGS
        andi,r0 080h
        bctr,eq FIREBUTTON_1

;the firebutton is only checked if it is possible to fire
;(ie. no bullet onscreen)
        loda,r0 P1MIDDLEKEYS ;r0 = P1MIDDLEKEYS;
        andi,r0 008h         ;r0 &= %00001000; // extract 'Fire/2' button
        bcta,eq FIREBUTTON_END;if (==) goto FIREBUTTON_END;

FIREBUTTON_1:
;firebutton was pressed, make a bullet
        lodi,r2 003h         ;r2 = 3; // loop iterator
        lodi,r1 000h         ;r1 = 0;
FIREBUTTON_2:
;we are accessing $18DC..$18DE and $18ED..$18EF
;r1 is 0..2 here, for values of r2 of 3..1, respectively
        loda,r0 LIVES,r1     ;r0 = *(&LIVES + r1);
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1) = r0;
                             ;*(BULLETDIR + r1) = r0;
        addi,r1 001h         ;r1++;
        bdrr,r2 FIREBUTTON_2 ;if (--r2 != 0) goto FIREBUTTON_2;
;end of loop

        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(BULLETDIR + r1 [1]);
                             ;r0 = BULLETY;
        addi,r0 004h         ;r0 += 4;
        andi,r0 0f8h         ;r0 &= %11111000;
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1 [1]) = r0;
                             ;*(BULLETDIR + r1 [1]) = r0;
                             ;BULLETY = r0;

        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(BULLETDIR + r1 [2]);
                             ;r0 = BULLETX;
        addi,r0 004h         ;r0 += 4;
        andi,r0 0f8h         ;r0 &= %11111000;
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1 [2]) = r0;
                             ;*(BULLETDIR + r1 [2]) = r0;
                             ;BULLETX = r0;

        lodi,r1 000h         ;r1 = 0;
        loda,r0 FACING       ;r0 = FACING;
        rrr,r0               ;rotate r0 to the right quarce
        rrr,r0
        rrr,r0
        rrr,r0
        andi,r0 00fh         ;r0 &= %00001111;
        strz    r2           ;r2 = r0;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = *(BULLETDIR + r1 [0]);
                             ;r0 = BULLETX;
        andi,r0 0f0h         ;r0 &= %11110000;
        iorz    r2           ;r0 |= r2;
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1 [0]) = r0; // inefficient!
                             ;*(BULLETDIR + r1 [0]) = r0;
                             ;BULLETX = r0;
        andi,r0 007h         ;r0 &= %00000111;

;if (r0 == %00000001) goto FIREBUTTON_3;
        comi,r0 001h         ;compare r0 against %00000001
        bctr,eq FIREBUTTON_3 ;if (==) goto FIREBUTTON_3;

;if (r0 == %00000101) goto FIREBUTTON_3;
        comi,r0 005h         ;compare r0 against %00000101
        bctr,eq FIREBUTTON_3 ;if (==) goto FIREBUTTON_3;

        bctr,un FIREBUTTON_4 ;goto FIREBUTTON_4;

FIREBUTTON_3:

;BULLETY--;
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(BULLETDIR + r1 [1]);
                             ;r0 = BULLETY;
        subi,r0 001h         ;r0--;
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1 [1]) = r0;
                             ;*(BULLETDIR + r1 [1]) = r0;
                             ;BULLETY = r0;

FIREBUTTON_4:
        lodi,r3 000h         ;r3 = 0; // sound effect #1 (player firing)
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 080h         ;r0 &= %10000000;
        bcfr,eq FIREBUTTON_END;if (!=) goto FIREBUTTON_END;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = *(BULLETDIR + r1 [0]);
                             ;r0 = BULLETDIR;
        andi,r0 0f0h         ;r0 &= %11110000;
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1 [0]) = r0; // inefficient!
                             ;*(BULLETDIR + r1 [0]) = r0;
                             ;BULLETDIR = r0;

FIREBUTTON_END:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0676:
;POINTER always points to $18E7 or $18EA during this routine

        bsta,un TEST10       ;gosub TEST10;
        bcfa,eq L076B        ;if (!=) goto L076B;
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 020h         ;r0 &= %00100000;
        bcfr,eq L06A2        ;if (!=) goto L06A2;

;we are on level 1

        bsta,un 28e9h        ;gosub $28E9;
        comi,r0 004h         ;compare r0 against 4
        bctr,lt L0690        ;if (<) goto L0690;
        comi,r0 008h         ;compare r0 against 8
        bctr,lt L0695        ;if (<) goto L0695;
        bctr,un L069A        ;goto L069A;
L0690:
        lodi,r3 00ch         ;r3 = $C;
        bcta,un L069C        ;goto L069C;
L0695:
        lodi,r3 00eh         ;r3 = $E;
        bcta,un L069C        ;goto L069C;
L069A:
        lodi,r3 012h         ;r3 = $12;
L069C:
        bsta,un SETROMPOINTER2;gosub SETROMPOINTER2;
        bcta,un L06BF        ;goto L06BF;

L06A2:

;we are on level 2

        bsta,un 28e9h        ;gosub $28E9;
        comi,r0 005h         ;compare r0 against 5
        bctr,lt L06B2        ;if (<) goto L06B2;
        comi,r0 00ah         ;compare r0 against $A
        bctr,lt L06B7        ;if (<) goto L06B7;
        lodi,r3 014h         ;r3 = $14;
        bcta,un L06B9        ;goto L06B9;
L06B2:
        lodi,r3 016h         ;r3 = $16;
        bcta,un L06B9        ;goto L06B9;
L06B7:
        lodi,r3 01ch         ;r3 = $1C;
L06B9:
        bsta,un SETROMPOINTER2;gosub SETROMPOINTER2;
        bcta,un L06BF        ;goto L06BF; // useless!

L06BF:

;level can be either 1 or 2

        lodi,r1 000h         ;r1 = 0;
        loda,r0 *ROMPOINTER2_H,r1;r0 = *(ROMPOINTER2 + r1 [0]); // inefficient!
                             ;r0 = *(ROMPOINTER2);
        andi,r0 0f0h         ;r0 &= %11110000;
        comi,r0 020h         ;compare r0 against %00100000
        bcfa,eq L076B        ;if (!=) goto L076B;

;*(ROMPOINTER2)     = *(POINTER);
;*(ROMPOINTER2 + 1) = *(POINTER + 1);
;*(ROMPOINTER2 + 2) = *(POINTER + 2);
        lodi,r2 003h         ;r2 = 3; // loop iterator
        lodi,r1 000h         ;r1 = 0;
L06CF:
        loda,r0 *ROMPOINTER2_H,r1;r0 = *(ROMPOINTER2 + r1);
        stra,r0 *POINTER_H,r1;*(POINTER + r1) = r0;
        addi,r1 001h         ;r1++;
        bdrr,r2 L06CF        ;if (--r2 != 0) goto L06CF;
;end of loop

;*(POINTER + 1) = (*(POINTER + 1) + 4) & %11111000;
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
        addi,r0 004h         ;r0 += 4;
        andi,r0 0f8h         ;r0 &= %11111000;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [1]) = r0;

;*(POINTER + 2) = (*(POINTER + 2) + 4) & %11111000;
        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
        addi,r0 004h         ;r0 += 4;
        andi,r0 0f8h         ;r0 &= %11111000;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [2]) = r0;

        loda,r2 PLAYERY      ;r2 = PLAYERY;
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
        comz    r2           ;compare r0 against r2
        bctr,lt L0709        ;if (<) goto L0709;

        loda,r2 PLAYERX      ;r2 = PLAYERY;
        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
        comz    r2           ;compare r0 against r2
        bctr,lt L0716        ;if (<) goto L0716;

        bctr,un L0722        ;goto L0722;
L0709:
        loda,r2 PLAYERX      ;r2 = PLAYERX;
        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
        comz    r2           ;compare r0 against r2
        bctr,lt L071A        ;if (<) goto L071A;

        bctr,un L071E        ;goto L071E;
L0716:
        lodi,r3 000h         ;r3 = 0;
        bctr,un L0724        ;goto L0724;
L071A:
        lodi,r3 002h         ;r3 = 2;
        bctr,un L0724        ;goto L0724;
L071E:
        lodi,r3 004h         ;r3 = 4;
        bctr,un L0724        ;goto L0724;

L0722:
        lodi,r3 006h         ;r3 = 6;
L0724:
        bsta,un 28e9h        ;gosub $28E9;
        comi,r0 005h         ;compare r0 against 5
        bctr,lt L0733        ;if (<) goto L0733;
        comi,r0 00ah         ;compare r0 against 10
        bctr,lt L0731        ;if (<) goto L0731;
        addi,r3 001h         ;r3++;
L0731:
        addi,r3 001h         ;r3++;
L0733:
;if (ROMPOINTER2 != $??EB) goto L074A; // where ? is wild
        loda,r0 ROMPOINTER2_L ;r0 = ROMPOINTER2_L;
        comi,r0 0ebh         ;compare r0 against $EB
        bcfr,eq L074A        ;if (!=) goto L074A;

;if (r3 == 2) then r3--; else if (r3 == 6) then r3++;
;or, in other words:
;if (r3 == 2) then r3 = 1; else if (r3 == 6) then r3 = 7;
        comi,r3 002h         ;compare r3 against 2
        bctr,eq L0744        ;if (==) goto L0744;
        comi,r3 006h         ;compare r3 against 6
        bctr,eq L0748        ;if (==) goto L0748;
        bctr,un L074A        ;goto L074A;
L0744:
        subi,r3 001h         ;r3--;
        bctr,un L074A        ;goto L074A;
L0748:
        addi,r3 001h         ;r3++;

L074A:

;POINTER &= %11110000;
;POINTER |= r3;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = POINTER;
        andi,r0 0f0h         ;r0 &= %11110000;
        iorz    r3           ;r0 |= r3;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0; // inefficient!
                             ;POINTER = r0;

        andi,r0 007h         ;r0 &= %00000111;

;if (r0 == 1 || r0 == 5) then (*(POINTER + 1))--;
        comi,r0 001h         ;compare r0 against 1
        bctr,eq L0761        ;if (==) goto L0761;
        comi,r0 005h         ;compare r0 against 5
        bctr,eq L0761        ;if (==) goto L0761;
        bctr,un L076B        ;goto L076B;
L0761:
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = *(POINTER + 1);
        subi,r0 001h         ;r0--;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [1]) = r0;
                             ;*(POINTER + 1) = r0;
L076B:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
MOVEBULLET:
;this is a service routine of L02DD
;POINTER can be $18E7, $18EA or BULLETDIR at this point

        bsta,un TEST20
        bcfa,eq MOVEBULLET_END

;*(POINTER) |= %10000000;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
        iori,r0 080h         ;r0 |= %10000000;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0; // inefficient!

        bsta,un L07E7        ;gosub L07E7;

;*(POINTER) |= %10000000;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
        andi,r0 07fh         ;r0 &= %01111111;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0; // inefficient!

        bsta,un REALMOVEBULLET;gosub REALMOVEBULLET;

        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);

;if (r0 < 4 || r0 > $7C) goto MOVEBULLET_1;
        comi,r0 014h         ;compare r0 against $14
        bctr,lt MOVEBULLET_1 ;if (<) goto MOVEBULLET_1;
        comi,r0 0c0h         ;compare r0 against $C0
        bctr,gt MOVEBULLET_1 ;if (>) goto MOVEBULLET_1;
                             
        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);

;if (r0 < 4 || r0 > $7C) goto MOVEBULLET_1; else goto MOVEBULLET_END;
        comi,r0 004h         ;compare r0 against 4
        bctr,lt MOVEBULLET_1 ;if (<) goto MOVEBULLET_1;
        comi,r0 07ch         ;compare r0 against $7C
        bctr,gt MOVEBULLET_1 ;if (>) goto MOVEBULLET_1;
        bctr,un MOVEBULLET_END;goto MOVEBULLET_END;

MOVEBULLET_1:
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
        andi,r0 00fh         ;r0 &= %00001111;
        iori,r0 030h         ;r0 |= %00110000;
;r0 is now %0011xxxx, where x are unchanged
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0; // inefficient!

MOVEBULLET_END:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
REALMOVEBULLET:
;this is a service routine of MOVEBULLET, which itself is a service routine of L02DD
;POINTER always points to BULLETDIR during this subroutine

;BULLETDIR = (BULLETDIR & %00001111) * 2;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = *(BULLETDIR + r1 [0]);
                             ;r0 = BULLETDIR;
        andi,r0 00fh         ;r0 &= %00001111;
        addz    r0           ;r0 += r0; // double r0

;BULLETY += *(7D7 + BULLETDIR);
        strz    r2           ;r2 = r0;
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(BULLETDIR + r1 [1]);
                             ;r0 = BULLETY;
        adda,r0 07d7h,r2     ;r0 += *(7D7 + r2); // ROM data
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [1]) = r0;
                             ;*(BULLETDIR + r1 [1]) = r0;
                             ;BULLETY = r0;

;BULLETX += *(7D8 + BULLETDIR);
        addi,r1 001h         ;r1++; // r1 = 2;
        addi,r2 001h         ;r2++;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(BULLETDIR + r1 [2]);
                             ;r0 = BULLETX;
        adda,r0 07d7h,r2     ;r0 += *(7D7 + r2); // ROM data
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [2]) = r0;
                             ;*(BULLETDIR + r1 [2]) = r0;
                             ;BULLETX = r0;
        retc,un              ;return;
;Data for REALMOVEBULLET--------------------------------------------------
;$7D7:
        db      0FCH, 000H ;-4,  0 (down)
        db      0FCH, 004H ;-4, +4 (down and right)
        db      000H, 004H ; 0, +4 (right)
        db      004H, 004H ;+4, +4 (up and right)
        db      004H, 000H ;+4,  0 (up)
        db      004H, 0FCH ;+4, -4 (up and left)
        db      000H, 0FCH ; 0, -4 (left)
        db      0FCH, 0FCH ;-4, -4 (down and left)
;Subroutine---------------------------------------------------------------
L07E7:
        bsta,un TEST20
        bctr,eq L07F3
        comi,r0 030h
        bctr,eq L07F3
        bcta,un L0811
L07F3:
        loda,r0 POINTER_L
        comi,r0 0edh
        bcta,eq L0839
        loda,r0 18e3h
        andi,r0 00fh
        comi,r0 000h
        bctr,eq L0812
        comi,r0 001h
        bcta,eq L081F
        comi,r0 002h
        bcta,eq L082C
        bcta,un L0839
L0811:
        retc,un
L0812:
        lodi,r0 03ch
        stra,r0 18d2h
        lodi,r0 000h
        stra,r0 18d3h
        bcta,un L0843
L081F:
        lodi,r0 03dh
        stra,r0 18d2h
        lodi,r0 $08  
        stra,r0 18d3h
        bcta,un L0843
L082C:                              
        lodi,r0 03eh
        stra,r0 18d2h
        lodi,r0 010h
        stra,r0 18d3h
        bcta,un L0843
L0839:
        lodi,r0 03fh
        stra,r0 18d2h
        lodi,r0 018h
        stra,r0 18d3h
L0843:
        lodi,r1 001h
        loda,r0 *POINTER_H,r1
        comi,r0 068h
        bctr,lt L084E
        subi,r0 068h
L084E:
        rrl,r0
        andi,r0 0f0h
        strz    r2
        lodi,r1 002h
        loda,r0 *POINTER_H,r1
        rrr,r0
        rrr,r0
        rrr,r0
        andi,r0 00fh
        addz    r2
        strz    r2
        loda,r0 18d2h
;r0, r1 and r2 are all set up by this point
        bsta,un SHOOT
        bsta,un L0879

        lodi,r3 008h         ;r3 = 8; // loop iterator
        loda,r1 18d3h
L086C:
        loda,r0 *091fh,r2
        stra,r0 19a0h,r1
        addi,r1 001h
        addi,r2 001h
        bdrr,r3 086ch
;end of loop

L0878:
        retc,un
;Subroutine---------------------------------------------------------------
L0879:
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
        andi,r0 007h         ;r0 &= %00000111;
        comi,r0 002h         ;compare r0 against %00000010
        bctr,eq L088C        ;if (==) goto L088C;
        comi,r0 006h         ;compare r0 against %00000110
        bctr,eq L088C        ;if (==) goto L088C;
        lodi,r1 001h         ;r1 = 1;
        bctr,un L088E        ;goto L088E;
L088C:
        lodi,r1 002h         ;r1 = 2;
L088E:
        rrl,r0               ;rotate r0 to the left quince
        rrl,r0
        rrl,r0
        rrl,r0
        rrl,r0
        strz    r2           ;r2 = r0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1);
        andi,r0 004h         ;r0 &= %00000100;
        rrl,r0               ;rotate r0 to the left twice
        rrl,r0
        addz    r2           ;r0 += r2;
        strz    r2           ;r2 = r0;
        loda,r0 POINTER_L    ;r0 = POINTER_L;
        comi,r0 0edh         ;compare r0 against $ED
        bctr,eq L08A6        ;if (==) goto L08A6;
        addi,r2 008h         ;r2 += 8;
L08A6:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
SHOOT:
;this is a service routine of L07E7
;POINTER is always BULLETDIR during this routine
;r0 is passed as an argument, it is *(18D2)
;r2 is passed as an argument, it is the bullet offset into the screen

        stra,r0 18d0h        ;*(18D0) = r0; // user RAM
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(BULLETDIR + r1 [1]);
                             ;r0 = BULLETY; // user RAM
        lodi,r1 001h         ;r1 = 1; // useless!
        comi,r0 067h         ;compare r0 against $67 
;if BULLETY > $67, bullet is in lower half of screen, otherwise upper half
        bctr,gt SHOOT_1      ;if (>) goto SHOOT_1;
        lodi,r1 000h         ;r1 = 0;
SHOOT_1:
        stra,r1 18d1h        ;*(18D1) = r1 [0 or 1]; // user RAM

        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]);
                             ;r0 = *(BULLETDIR + r1 [0]);
                             ;r0 = BULLETDIR; // user RAM
        andi,r0 070h         ;r0 &= %01110000;
        comi,r0 030h         ;compare r0 against $30
        bcfr,eq SHOOT_2      ;if (!=) goto SHOOT_2;

;adjust the value of BULLETDIR
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]);
                             ;r0 = *(BULLETDIR + r1 [0]);
                             ;r0 = BULLETDIR;
        andi,r0 00fh         ;r0 &= %00001111;
        iori,r0 010h         ;r0 |= %00010000;
;r0 is now %xxx10000, where x are unchanged
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0;
                             ;*(BULLETDIR + r1 [0]) = r0;
                             ;BULLETDIR = r0;

;*(18D0) = 0;
        lodi,r0 000h         ;r0 = 0;
        stra,r0 18d0h        ;*(18D0) = r0 [0]; // user RAM

SHOOT_2:
        loda,r0 18d0h        ;r0 = *(18D0); // user RAM
        strz    r3           ;r3 = r0;

        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]);
                             ;r0 = *(BULLETDIR + r1 [0]);
                             ;r0 = BULLETDIR;
        andi,r0 080h         ;r0 &= %10000000;
        bctr,eq SHOOT_3      ;if (==) goto SHOOT_3;
        lodi,r3 000h         ;r3 = 0;

SHOOT_3:
        lodz    r3           ;r0 = r3;
        comi,r2 0d0h         ;compare r2 against $D0
        bctr,gt SHOOT_9
        strz    r3           ;r3 = r0;
        loda,r0 FLAGS        ;r0 = FLAGS; // user RAM
        lodi,r1 03ch         ;r1 = $3C; // UDC #0
        andi,r0 020h         ;r0 &= %00100000;
        bcfr,eq SHOOT_4      ;if (!=) goto SHOOT_4;
        lodi,r1 03dh         ;r1 = $3D; // UDC #1

SHOOT_4:

;if (*(18D1) != 0) goto SHOOT_5;
        loda,r0 18d1h        ;r0 = *(18D1);
        bcfr,eq SHOOT_5      ;if (!=) goto SHOOT_5;

        loda,r0 1800h,r2     ;r0 = *(1800 + r2); // upper screen
        bctr,un SHOOT_6      ;goto SHOOT_6;
SHOOT_5:
        loda,r0 1a00h,r2     ;r0 = *(1A00 + r2); // lower screen

SHOOT_6:
        andi,r0 03fh         ;r0 &= %00111111; // discard colour bits
        comi,r0 000h         ;compare r0 against 0
        bctr,eq SHOOT_7      ;if (==) goto SHOOT_7;

;if (r0 < r1) goto SHOOT_9;
        comz    r1           ;compare r0 against r1 [$3C or $3D]
        bctr,lt SHOOT_9      ;if (<) goto SHOOT_9;

;if (r0 > $40) goto SHOOT_9;
        comi,r0 040h         ;compare r0 against $40;
        bctr,gt SHOOT_9      ;if (>) goto SHOOT_9;

SHOOT_7:
        lodz    r3           ;r0 = r3; // bullet image character

;*(18D1) is 0 for upper half of screen, 1 for lower half
;if (*(18D1) != 0) goto SHOOT_8;
        loda,r1 18d1h        ;r1 = *(18D1);
        bcfr,eq SHOOT_8      ;if (!=) goto SHOOT_8;

;upper half of screen
        stra,r0 1800h,r2     ;*(1800 + r2) = r0; // upper screen
        bctr,un SHOOT_9      ;goto SHOOT_9; // skip ahead
SHOOT_8:
        stra,r0 1a00h,r2     ;*(1A00 + r2) = r0; // lower screen
SHOOT_9:
;this return code is never used by anything
        lodi,r1 000h         ;r1 = 0; // always returns 0 in r1 (useless!)
SHOOT_END:
        retc,un
;Pointer for L07E7--------------------------------------------------------
;$91F:
        dw      2D0Bh        ;vertical bullet
;Subroutine---------------------------------------------------------------
SETUDCS:
        lodi,r2 004H         ;r2 = 4; // loop iterator
        lodi,r1 000H         ;r1 = 0;

;copies from $293F..$2942 (ROM data) to $19F8..$19FB (hardware registers)
;$19F8..$19FB are RESOLUTION, BGCOLOUR, SPRITES23CTRL, SPRITES01CTRL respectively
;results are as follows:
;RESOLUTION    = $40;
;BGCOLOUR      = $87;
;SPRITES23CTRL =  $9;
;SPRITES01CTRL =  $9;
SETUDCS_1:
        loda,r0 *0C79H,r1    ;r0 = *(*(C79) + r1);
                             ;r0 = *(293F + r1);
        stra,r0 19F7H,r1+    ;*(19F7 + ++r1) = r0;
        bdrr,r2 SETUDCS_1    ;if (--r2 != 0) goto SETUDCS_1;
;end of loop

;*(18E2) = $87;
        lodi,r0 087H         ;r0 = $87;
        stra,r0 18E2H        ;*(18E2) = r0 [$87];

        lodi,r2 008H         ;r2 = 8; // loop iterator
        lodi,r1 000H         ;r1 = 0;
;copies from $2943..$294A (ROM data) to SPRITE0Y..SPRITE3X (hardware registers)
;$18F0..$18F7 are SPRITE0Y, SPRITE0X, SPRITE1Y, SPRITE1X, SPRITE2Y, SPRITE2X, SPRITE3Y, SPRITE3X respectively
;results are as follows:
;SPRITE0Y      =  $0;
;SPRITE0X      = $6B;
;SPRITE1Y      =  $0;
;SPRITE1X      = $8B;
;SPRITE2Y      =  $0;
;SPRITE2X      = $73;
;SPRITE3Y      =  $0;
;SPRITE3X      = $83;
SETUDCS_2:
        loda,r0 *0C7BH,r1    ;r0 = *(*(C7B) + r1);
                             ;r0 = *(2943 + r1);
        stra,r0 18EFH,r1+    ;*(18EF + ++r1) = r0;
        bdrr,r2 SETUDCS_2    ;if (--r2 != 0) goto SETUDCS_2;
;end of loop

        lodi,r2 040H         ;r2 = $40; // loop iterator
        lodi,r1 000H         ;r1 = 0;
;copies from $294B..$298A (ROM data) to $1980..$19BF (sprites/UDCs)
SETUDCS_3:
        loda,r0 *0C7DH,r1    ;r0 = *(*(C7D) + r1);
                             ;r0 = *(294B + r1);
        stra,r0 197FH,r1+    ;*(197F + ++r1) = r0;
        bdrr,r2 SETUDCS_3    ;if (--r2 != 0) goto SETUDCS_3;
;end of loop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
SETHARDWARE:
        lodi,r2 004H         ;r2 = 4; // loop iterator
        lodi,r1 000H         ;r1 = 0;

;copies from $2ADB..$2ADE (ROM data) to $19F8..$19FB (hardware registers)
;$19F8..$19FB are RESOLUTION, BGCOLOUR, SPRITES23CTRL, SPRITES01CTRL respectively
;results are as follows:
;RESOLUTION    = $40;
;BGCOLOUR      =  $0;
;SPRITES23CTRL =  $0;
;SPRITES01CTRL =  $0;
SETHARDWARE_1:
        loda,r0 *0C83H,r1    ;r0 = *(*(C83) + r1);
                             ;r0 = *(2ADB + r1);
        stra,r0 19F7H,r1+    ;*(19F7 + ++r1) = r0;
        bdrr,r2 SETHARDWARE_1;if (--r2 != 0) goto SETHARDWARE_1;
;end of loop

        lodi,r0 000H         ;r0 = 0;
        stra,r0 18E2H        ;*(18E2) = r0 [0]; // user RAM
        lodi,r2 008H         ;r2 = 8; // loop iterator
        lodi,r1 000H         ;r1 = 0;

;copies from $2ADF..$2AE6 (ROM data) to SPRITE0Y..SPRITE3X (hardware registers)
;$18F0..$18F7 are SPRITE0Y, SPRITE0X, SPRITE1Y, SPRITE1X, SPRITE2Y, SPRITE2X, SPRITE3Y, SPRITE3X respectively
;results are as follows:
;SPRITE0Y      =  $0;
;SPRITE0X      =  $0;
;SPRITE1Y      =  $0;
;SPRITE1X      =  $0;
;SPRITE2Y      =  $0;
;SPRITE2X      =  $0;
;SPRITE3Y      =  $0;
;SPRITE3X      =  $0;
SETHARDWARE_2:
        loda,r0 *0C85H,r1    ;r0 = *(*(C85) + r1);
                             ;r0 = *(2ADF + r1);
        stra,r0 18EFH,r1+    ;*(18EF + ++r1) = r0;
        bdrr,r2 SETHARDWARE_2;if (--r2 != 0) goto SETHARDWARE_2;
;end of loop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
TITLESCREEN:
        lodi,r1 030H         ;r1 = 48;
        lodi,r2 010H         ;r2 = 16;
        lodi,r3 00AH         ;r3 = 10;

;ROMPOINTER2 = $298B; // ROM data
        loda,r0 0C7FH        ;r0 = *(C7F); // ROM data
                             ;r0 = 41 [$29];
        stra,r0 ROMPOINTER2_H ;ROMPOINTER2_H = r0 [41]; // user RAM
        loda,r0 0C80H        ;r0 = *(C80); // ROM data
                             ;r0 = $8B;
        stra,r0 ROMPOINTER2_L ;ROMPOINTER2_L = r0 [$8B]; // user RAM

        bsta,un DRAWTOP      ;gosub DRAWTOP;

        lodi,r1 000H         ;r1 = 0;
        lodi,r2 010H         ;r2 = 16;
        lodi,r3 00BH         ;r3 = 11;

;ROMPOINTER2 = $2A2B; // ROM data
        loda,r0 0C81H        ;r0 = *(C81); // ROM data
                             ;r0 = $2A;
        stra,r0 ROMPOINTER2_H ;ROMPOINTER2_H = r0 [$2A]; // user RAM
        loda,r0 0C82H        ;r0 = *(C82); // ROM data
                             ;r0 = $2B;
        stra,r0 ROMPOINTER2_L ;ROMPOINTER2_L = r0 [$2B];

        bsta,un DRAWBOTTOM   ;gosub DRAWBOTTOM;

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
CREDITS:
        lodi,r1 030H         ;r1 = $30;
        lodi,r2 010H         ;r2 = $10;
        lodi,r3 007H         ;r3 = $7;

;ROMPOINTER2 = $2AE7;
        loda,r0 0C87H        ;r0 = *(C87); // ROM data
                             ;r0 = $2A;
        stra,r0 ROMPOINTER2_H ;ROMPOINTER2_H = r0 [$2A]; // user RAM
        loda,r0 0C88H        ;r0 = *(C88); // ROM data
                             ;r0 = $E7;
        stra,r0 ROMPOINTER2_L ;ROMPOINTER2_L = r0; // user RAM

        bsta,un DRAWTOP      ;gosub DRAWTOP;

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
DOHISCORE:
        lodi,r2 005H         ;r2 = 5; // loop iterator
        lodi,r1 000H         ;r1 = 0;
;set colours at coords (0..4,0) (score)
DOHISCORE_1:
        loda,r0 1800H,r1     ;*(1800 + r1) = r0; // upper screen
        iori,r0 010H         ;r0 |= %00010000;
        stra,r0 17FFH,r1+    ;*(17FF + ++r1) = r0; // upper screen
        bdrr,r2 DOHISCORE_1  ;if (--r2 != 0) goto DOHISCORE_1;
;end of loop

;draw a '0' at end of score (score is always an even multiple of 10)
;*(1805) = '0';
        lodi,r0 010H         ;r0 = $10; // '0' character
        stra,r0 1805H        ;*(1805) = r0 [$10]; // upper screen (5,0)

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
DOSCORE:
        lodi,r2 005H         ;r2 = 5; // loop iterator
        lodi,r1 000H         ;r1 = 0;
DOSCORE_1:
;copy from $1AF9..$1AFD (user RAM) to $180A..$180E (upper screen)
        loda,r0 1AF9H,r1     ;r0 = *(1AF9 + r1); // user RAM
        iori,r0 010H         ;r0 |= %00010000; // set colour
        stra,r0 1809H,r1+    ;*(1809 + ++r1) = r0;
        bdrr,r2 DOSCORE_1    ;if (--r2 != 0) goto DOSCORE_1;
;end of loop

;draw a '0' at end of score (score is always an even multiple of 10)
;*(180F) = '0';
        lodi,r0 010H         ;r0 = %00010000;
        stra,r0 180FH        ;*(180F) = r0; // upper screen (15,0)

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
DRAWLINE:
        lodi,r2 010H         ;r2 = 16; // loop iterator
        lodi,r1 0FFH         ;r1 = -1;
        lodi,r0 046H         ;r0 = $46; // graphics character #6
;........ built-in graphics character #6 (shown as 'd' by HowDif 2.x)
;........
;........
;........
;........
;........
;########
;########
L09D8:
;fill $1810..$181F (upper screen) with graphics character #6
        stra,r0 1810H,r1+    ;*(1810 + ++r1) = r0;
        bdrr,r2 L09D8        ;if (--r2 != 0) goto L09D8;
;end of loop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
DRAWBUILDINGS:
        lodi,r2 010H         ;r2 = 16; // loop iterator
        lodi,r1 000H         ;r1 = 0;
DRAWBUILDINGS_1:
;copy from $9ED..$9FC to $1A80..$1A8F (lower screen), setting colour
        loda,r0 09EDH,r1     ;r0 = *(9ED + r1); // ROM data
        iori,r0 040H         ;r0 |= %01000000;
        stra,r0 1A7FH,r1+    ;*(1A7F + ++r1) = r0; // user RAM
        bdrr,r2 DRAWBUILDINGS_1;if (--r2 != 0) goto DRAWBUILDINGS_1;
;end of loop

        retc,un              ;return;
;Data for DRAWBUILDINGS---------------------------------------------------
X09ED:
;made with only built-in graphics characters
;HowDif 2.x terminology is: djkdadaa djkjaaka

;........ .......# #....... ........ ######## ........ ######## ########
;........ ......## ##...... ........ ######## ........ ######## ########
;........ .....### ###..... ........ ######## ........ ######## ########
;........ ....#### ####.... ........ ######## ........ ######## ########
;........ ...##### #####... ........ ######## ........ ######## ########
;........ ..###### ######.. ........ ######## ........ ######## ########
;######## .####### #######. ######## ######## ######## ######## ########
;######## ######## ######## ######## ######## ######## ######## ########

;........ .......# #....... .......# ######## ######## #....... ########
;........ ......## ##...... ......## ######## ######## ##...... ########
;........ .....### ###..... .....### ######## ######## ###..... ########
;........ ....#### ####.... ....#### ######## ######## ####.... ########
;........ ...##### #####... ...##### ######## ######## #####... ########
;........ ..###### ######.. ..###### ######## ######## ######.. ########
;######## .####### #######. .####### ######## ######## #######. ########
;######## ######## ######## ######## ######## ######## ######## ########

        db      006H, 00CH, 00DH, 006H, 003H, 006H, 003H, 003H
        db      006H, 00CH, 00DH, 00CH, 003H, 003H, 00DH, 003H
;Subroutine---------------------------------------------------------------
HISCORE:
        lodi,r2 005H         ;r2 = 5;
        lodi,r1 000H         ;r1 = 0;
HISCORE_1:
        loda,r0 1800H,r1     ;r0 = *(1800 + r1); // upper screen
        andi,r0 00FH         ;r0 &= %00001111;
        strz    r3           ;r3 = r0;
        loda,r0 1AF9H,r1     ;r0 = *(1AF9 + r1); // user RAM
        andi,r0 00FH         ;r0 &= %00001111;
        comz    r3           ;compare r0 against r3
        bctr,gt HISCORE_END  ;if (>) goto HISCORE_END;
        bctr,lt HISCORE_2    ;if (<) goto HISCORE_2;
        addi,r1 001H         ;r1++;
        bdrr,r2 HISCORE_1    ;if (--r2 != 0) goto HISCORE_1;
;end of loop
        bctr,un HISCORE_END  ;goto HISCORE_END;

HISCORE_2:
        lodi,r2 005H         ;r2 = 5;
        lodi,r1 000H         ;r1 = 0;
HISCORE_3:
        loda,r0 1800H,r1     ;r0 = *(1800 + r1); // upper screen
        stra,r0 1AF9H,r1     ;*(1AF9 + r1) = r0;
        addi,r1 001H         ;r1++;
        bdrr,r2 HISCORE_3    ;if (--r2 != 0) goto HISCORE_3;
;end of loop
HISCORE_END:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;the contents of the screen move down - the virtual camera moves up
SCROLLDOWN:
        loda,r2 VSCROLL      ;r2 = VSCROLL; // loop iterator
SCROLLDOWN_1:
        lodi,r0 008H         ;r1 = 8;
        bsta,un DELAY        ;gosub DELAY;
        subi,r2 001H         ;r2--;
        stra,r2 VSCROLL      ;VSCROLL = r2;
        comi,r2 000H         ;compare r2 against 0
        bcfr,eq SCROLLDOWN_1 ;if (!=) goto SCROLLDOWN_1;
;end of loop
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;the contents of the screen move up - the virtual camera moves down
SCROLLUP:
        loda,r2 VSCROLL      ;r2 = VSCROLL; // loop iterator
SCROLLUP_1:
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 020H         ;r0 &= %00100000;
        bctr,eq SCROLLUP_2   ;if (==) goto SCROLLUP_2;
;only if level 2
        bsta,un DRAWSTARS    ;gosub DRAWSTARS;
SCROLLUP_2:
        lodi,r0 008H         ;r0 = 8;
        bsta,un DELAY        ;gosub DELAY;
        addi,r2 001H         ;r2++;
        stra,r2 VSCROLL      ;VSCROLL = r2;
        comi,r2 040H         ;compare r2 against $40
        bcfr,gt SCROLLUP_3   ;if (>) goto SCROLLUP_3;
        lodz    r2           ;r0 = r2;
        subi,r0 040H         ;r0 -= $40;
        stra,r0 SPRITE0Y     ;SPRITE0Y = r0;
        stra,r0 SPRITE1Y     ;SPRITE1Y = r0;
        stra,r0 SPRITE2Y     ;SPRITE2Y = r0;
        stra,r0 SPRITE3Y     ;SPRITE3Y = r0;
SCROLLUP_3:
        comi,r2 0EEH         ;compare r2 against $EE
        bcfr,eq SCROLLUP_1   ;if (!=) goto SCROLLUP_1;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
VBLROUTINE:
;this subroutine is called by LEVEL1FLYBY, LEVEL1LOOP, LEVEL2FLYBY and LEVEL2LOOP

;wait for end of vertical blank
        tpsu    080H         ;test mask %10000000 of PSU (Sense bit)
        bctr,eq VBLROUTINE   ;if (==) goto VBLROUTINE;
;end of loop
VBLROUTINE_1:
;wait for low nybble of CHARLINE to become $D
        loda,r0 CHARLINE     ;r0 = CHARLINE;
        andi,r0 00FH         ;r0 &= %00001111;
        comi,r0 00DH         ;compare r0 against $D
        bcfr,eq VBLROUTINE_1    ;if (!=) goto VBLROUTINE_1;
;end of loop

;flip frame
        loda,r0 FLAGS        ;r0 = FLAGS;
        eori,r0 040H         ;Exclusive OR r0 with %01000000 (flip bit 6)
        stra,r0 FLAGS        ;FLAGS = r0;

;if ((FLAGS & %00010000) == 0) goto VBLROUTINE_2;
        loda,r0 FLAGS        ;r0 = FLAGS; // useless!
        andi,r0 010H         ;r0 &= %00010000; // test bit 4 (flyby/playing bit)
        bctr,eq VBLROUTINE_2    ;if (==) goto VBLROUTINE_2;

;we are not in flyby, and could be on either level

        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 020H         ;r0 &= %00100000;
        bctr,eq VBLROUTINE_5    ;if (==) goto VBLROUTINE_5;

        bcta,un VBLROUTINE_8    ;goto VBLROUTINE_8;

VBLROUTINE_2:

;we are in flyby, and could be on either level

        bcta,un 2FF0h        ;goto VBLROUTINE_3;
VBLROUTINE_4:
        bsta,un L04C7        ;gosub L04C7;
        retc,un              ;return;

VBLROUTINE_5:

;we are not in flyby, and we are on level 1

        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 040H         ;r0 &= %01000000;
        bcfr,eq VBLROUTINE_6    ;if (!=) goto VBLROUTINE_6;

;we are not in flyby, we are on level 1, and this is an even-numbered frame

        bsta,un 21F9h        ;gosub $21F9;
        bctr,un VBLROUTINE_7    ;goto VBLROUTINE_7;

VBLROUTINE_6:

;we are not in flyby, we are on level 1, and this is an odd-numbered frame

        bsta,un 234Fh        ;gosub $234F;
        bsta,un 245Ch        ;gosub $245C;

VBLROUTINE_7:

;we are not in flyby, and we are on level 1

        bsta,un L04C7        ;gosub L04C7;
        retc,un              ;return;

VBLROUTINE_8:

;we are not in flyby, and we are on level 2

        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 040H         ;r0 &= %01000000;
        bcfr,eq VBLROUTINE_9    ;if (!=) goto VBLROUTINE_9;
        bsta,un 25ADh        ;gosub $25AD;
        bctr,un VBLROUTINE_11   ;goto VBLROUTINE_11;

VBLROUTINE_9:

;we are not in flyby, we are on level 2, and this is an odd-numbered frame

        loda,r0 1AEEH        ;r0 = *(1AEE);
        andi,r0 0F0H         ;r0 &= %11110000;
        comi,r0 010H         ;compare r0 against $10
        bcfr,eq VBLROUTINE_10   ;if (!=) goto VBLROUTINE_10;
        bsta,un 25D4h        ;gosub $25D4;
        bctr,un VBLROUTINE_11   ;goto VBLROUTINE_11;

VBLROUTINE_10:
        bsta,un 27CEh        ;gosub $27CE;

VBLROUTINE_11:
        bsta,un L04C7        ;gosub L04C7;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
FLIPFRAME:
;wait for Sense bit to be off
        tpsu    080H         ;test mask %10000000 of PSU
        bctr,lt FLIPFRAME    ;if (<) goto FLIPFRAME;
;end of loop

        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 040H         ;r0 &= %01000000;
        bcfr,eq FLIPFRAME_1  ;if (!=) goto FLIPFRAME_1;

;it is an even-numbered frame
;switch paddle axes

;*(18E2) |= %0100000;
        loda,r0 18E2H        ;r0 = *(18E2);
        iori,r0 040H         ;r0 |= %01000000;
        stra,r0 18E2H        ;*(18E2) = r0;

;BGCOLOUR = *(18E2);
        stra,r0 BGCOLOUR     ;BGCOLOUR = r0;

;P1PADDLEY = P1PADDLE;
        loda,r0 P1PADDLE     ;r0 = P1PADDLE;
        stra,r0 P1PADDLEY    ;P1PADDLEY = r0;

        bctr,un FLIPFRAME_END;goto FLIPFRAME_END;

FLIPFRAME_1:
;it is an odd-numbered frame
;switch paddle axes

        loda,r0 $18E2        ;r0 = *(18E2);
        andi,r0 0BFH         ;r0 &= %10111111;
        stra,r0 18E2H        ;*(18E2) = r0;
        stra,r0 BGCOLOUR     ;BGCOLOUR = r0;

;P1PADDLEX = P1PADDLE;
        loda,r0 P1PADDLE     ;r0 = P1PADDLE;
        stra,r0 P1PADDLEX    ;P1PADDLEX = r0;

FLIPFRAME_END:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
COLLDETECT:
;this subroutine is used on both levels
;POINTER always seems to be ALIEN1STATUS, ALIEN2STATUS, $1AEB or $1AF2 during this routine

;if (FLAGS & %00100000 != 0) goto COLLDETECT_1;
        loda,r0 FLAGS        ;r0 = FLAGS;
        andi,r0 020h         ;r0 &= %00100000;
        bcfr,eq COLLDETECT_1 ;if (!=) goto COLLDETECT_1;

;we are on level 2
;if (POINTER_L == $F2) goto COLLDETECT_3; else goto COLLDETECT_2;
        loda,r0 POINTER_L    ;r0 = POINTER_L;
        comi,r0 0f2h         ;compare r0 against $F2
        bctr,eq COLLDETECT_3 ;if (==) goto COLLDETECT_3;
        bctr,un COLLDETECT_2 ;goto COLLDETECT_2;

COLLDETECT_1:
;we are on level 1
;if (POINTER_L == $EE) goto COLLDETECT_3; else goto COLLDETECT_4;
        loda,r0 POINTER_L    ;r0 = POINTER_L;
        comi,r0 0eeh         ;compare r0 against $EE
        bctr,eq COLLDETECT_3 ;if (==) goto COLLDETECT_3;
        bctr,un COLLDETECT_4 ;goto COLLDETECT_4;

COLLDETECT_2:
;we are on level 2
        lodi,r0 004h         ;r0 = 4;
        lodi,r1 006h         ;r1 = 6;
        lodi,r2 004h         ;r2 = 4;
        lodi,r3 006h         ;r3 = 6;
        bctr,un COLLDETECT_5 ;goto COLLDETECT_5;

COLLDETECT_3:
;we could be on either level
        lodi,r0 008h         ;r0 = 8;
        lodi,r1 00ah         ;r1 = 10;
        lodi,r2 004h         ;r2 = 4;
        lodi,r3 006h         ;r3 = 6;
        bctr,un COLLDETECT_5 ;goto COLLDETECT_5;

COLLDETECT_4:
;we are on level 1
        lodi,r0 004h         ;r0 = 4;
        lodi,r1 006h         ;r1 = 6;
        lodi,r2 008h         ;r2 = 8;
        lodi,r3 00ah         ;r3 = 10;

COLLDETECT_5:
        stra,r0 18d0h        ;*(18D0) = r0;
        stra,r1 18d1h        ;*(18D1) = r1;
        stra,r2 18d2h        ;*(18D2) = r2;
        stra,r3 18d3h        ;*(18D3) = r3;

;so far all this subroutine has done is to set the user variables
;$18D0..$18D3.

        bsta,un TEST20       ;gosub TEST20;
        bcfa,eq COLLDETECT_END;if (!=) goto COLLDETECT_END;

;if ((BULLETDIR & %01110000) == %00010000) then goto COLLDETECT_8;
;or, in other words:
;if bits 6..5 of BULLETDIR are clear and bit 4 of BULLETDIR is set
        loda,r0 BULLETDIR    ;r0 = BULLETDIR;
        andi,r0 070h         ;r0 &= %01110000;
        comi,r0 020h         ;compare r0 against %00100000
        bcfa,eq COLLDETECT_8 ;if (!=) goto COLLDETECT_8;

        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [1]);
        strz    r3           ;r3 = r0;
        loda,r0 18d0h        ;r0 = *(18D0);
        addz    r3           ;r0 += r3;
        strz    r3           ;r3 = r0;
        loda,r0 BULLETY      ;r0 = BULLETY;
        addi,r0 004h         ;r0 += 4;
        subz    r3           ;r0 -= r3;
        bctr,eq COLLDETECT_6 ;if (==) goto COLLDETECT_6;
        bctr,gt COLLDETECT_6 ;if (>) goto COLLDETECT_6;
        eori,r0 0ffh         ;Exclusive OR r0 with %11111111 (flip all bits)
COLLDETECT_6:
        loda,r3 18d1h
        comz    r3
        bcta,gt COLLDETECT_8
        lodi,r1 002h
        loda,r0 *POINTER_H,r1
        strz    r3
        loda,r0 18d2h
        addz    r3
        strz    r3
        loda,r0 BULLETX
        addi,r0 004h
        subz    r3
        bctr,eq COLLDETECT_7
        bctr,gt COLLDETECT_7
        eori,r0 0ffh
COLLDETECT_7:
        loda,r3 18d3h        ;r3 = *(18D3);
        comz    r3           ;compare r0 against r3
        bctr,gt COLLDETECT_8 ;if (>) goto COLLDETECT_8;

        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1  ;r0 = *(POINTER + r1 [0]); // inefficient!
        andi,r0 00fh         ;r0 &= %00001111; // clear high nybble
        iori,r0 030h         ;r0 |= %00110000;
        stra,r0 *POINTER_H,r1  ;*(POINTER + r1 [0]) = r0;

;BULLETDIR &= %00001111;
;BULLETDIR |= %00110000;
        loda,r0 BULLETDIR    ;r0 = BULLETDIR;
        andi,r0 00fh         ;r0 &= %00001111;
        iori,r0 030h         ;r0 |= %00110000;
;BULLETDIR is now 0011xxxx, where x are unchanged
        stra,r0 BULLETDIR    ;BULLETDIR = r0;

        lodi,r3 002h         ;r3 = 2; // sound effect #2 (alien killed)
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;
;alien has been killed, update score
        bsta,un UPDATESCORE  ;gosub UPDATESCORE;
        bcta,un COLLDETECT_END ;gosub COLLDETECT_END;
COLLDETECT_8:
        lodi,r1 001h
        loda,r0 *POINTER_H,r1
        addi,r0 004h
        strz    r3
        loda,r0 PLAYERY
        addi,r0 008h
        subz    r3
        bctr,eq COLLDETECT_9
        bctr,gt COLLDETECT_9
        eori,r0 0ffh
COLLDETECT_9:
        comi,r0 00ah
        bcta,gt COLLDETECT_END
        lodi,r1 002h
        loda,r0 *POINTER_H,r1
        addi,r0 004h
        strz    r3
        loda,r0 PLAYERX
        addi,r0 004h
        subz    r3
        bctr,eq COLLDETECT_10
        bctr,gt COLLDETECT_10
        eori,r0 0ffh
COLLDETECT_10:
        comi,r0 006h
        bcta,gt COLLDETECT_END
        lodi,r1 000h
        loda,r0 *POINTER_H,r1
        andi,r0 00fh
        iori,r0 030h
        stra,r0 *POINTER_H,r1
        loda,r0 LIVES
        andi,r0 00fh
        iori,r0 030h
        stra,r0 LIVES
        lodi,r3 004h         ;sound effect #3 (player killed)
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;
        loda,r0 LIVES
        andi,r0 00fh
        bctr,eq COLLDETECT_END

;LIVES--;
        loda,r0 LIVES        ;r0 = LIVES;
        subi,r0 001h         ;r0--;
        stra,r0 LIVES        ;LIVES = r0;

COLLDETECT_END:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
PLAYMUSIC:
;this is called by LEVEL1FLYBY, LEVEL1LOOP, LEVEL2FLYBY and LEVEL2LOOP

        loda,r0 DURATION     ;r0 = DURATION; // user RAM
        bcta,eq PLAYMUSIC_END;if (== 0) goto PLAYMUSIC_END;
        subi,r0 001H         ;r0--;
        stra,r0 DURATION     ;DURATION = r0; // user RAM
        bcfa,eq PLAYMUSIC_END;if (!= 0) goto PLAYMUSIC_END;
        loda,r1 NOTE         ;r1 = NOTE; // user RAM
        loda,r0 *ROMPOINTER1_H,r1; r0 = *(ROMPOINTER1 + r1);
        andi,r0 0E0H         ;r0 &= %11100000; // extract bits 7..5
        comi,r0 080H         ;compare r0 against %10000000
        bctr,eq PLAYMUSIC_3  ;if (==) goto PLAYMUSIC_3;
        comi,r0 0E0H         ;compare r0 against %11100000
        bcfr,eq PLAYMUSIC_2  ;if (!=) goto PLAYMUSIC_2;
        loda,r0 18FBH        ;r0 = ROMPOINTER1_L;
        comi,r0 0C8H         ;compare r0 against %11001000
        bcfr,eq PLAYMUSIC_1  ;if (!=) goto PLAYMUSIC_1;

;DURATION = NOTE = 1;
        lodi,r0 001H         ;r0 = 1;
        stra,r0 DURATION     ;DURATION = r0 [1];
        stra,r0 NOTE         ;NOTE = r0 [1];

;VOLUME = 11;
        lodi,r0 00BH         ;r0 = 11;
        stra,r0 VOLUME       ;VOLUME = r0 [11];

        bcta,un PLAYMUSIC_END;goto PLAYMUSIC_END;

PLAYMUSIC_1:

;VOLUME = 11;
        lodi,r0 00BH         ;r0 = 11;
        stra,r0 VOLUME       ;VOLUME = r0 [11];

        lodi,r3 006H         ;r3 = 6; // music on
        bsta,un CHANGESOUND  ;gosub CHANGESOUND;

;NOTE = *(1AFF);
        loda,r0 1AFFH        ;r0 = *(1AFF);
        stra,r0 NOTE         ;NOTE = r0;

        bctr,un PLAYMUSIC_END;goto PLAYMUSIC_END;

PLAYMUSIC_2:
;ROMPOINTER1 is $2EC8 (MUSICDATA) at this point

;PITCH = *(MUSICDATA + r1++);
        loda,r0 *ROMPOINTER1_H,r1
                             ;r0 = *(*(ROMPOINTER1) + r1);
                             ;r0 = *(MUSICDATA + r1); // ROM data
        stra,r0 PITCH        ;PITCH = r0;
        addi,r1 001H         ;r1++;

;DURATION = *(MUSICDATA + r1);
        loda,r0 *ROMPOINTER1_H,r1
                             ;r0 = *(*(ROMPOINTER1) + r1); // user RAM
                             ;r0 = *(MUSICDATA + r1); // ROM data
        stra,r0 DURATION     ;DURATION = r0;

        lodi,r2 002H         ;r2 = 2;
        bctr,un PLAYMUSIC_4  ;goto PLAYMUSIC_4;

PLAYMUSIC_3:

;VOLUME = *(MUSICDATA + r1) & 00011111; 
        loda,r0 *ROMPOINTER1_H,r1
                             ;r0 = *(ROMPOINTER1 + r1); // user RAM
        andi,r0 01FH         ;r0 &= %00011111; // clear bits 7..5
        strz    r2           ;r2 = r0;
        andi,r0 0E0H         ;r0 &= %11100000;
;r0 is now 0
        iorz    r2           ;r0 |= r2;
;r0 is now r2
        stra,r0 VOLUME       ;VOLUME = r0;

;DURATION = 1;
        lodi,r0 001H         ;r0 = 1;
        stra,r0 DURATION     ;DURATION = r0 [1];

        lodi,r2 001H         ;r2 = 1;
PLAYMUSIC_4:

;NOTE += r2;
        loda,r0 NOTE         ;r0 = NOTE; // user RAM
        addz    r2           ;r0 += r2;
        stra,r0 NOTE         ;NOTE = r0; // user RAM

PLAYMUSIC_END:
        retc,un              ;return;
;Data for SETUDCS---------------------------------------------------------
X0C79:
	dw	293FH
X0C7B:
	dw	2943H
X0C7D:
	dw	294BH
;Data for TITLESCREEN-----------------------------------------------------
X0C7F:
	db	029H
X0C80:
	db	08BH
X0C81:
	db	02AH
X0C82:
	db	02BH
;Data for SETHARDWARE-----------------------------------------------------
X0C83:
	dw	2ADBH
X0C85:
	dw	2ADFH
;Pointer for CREDITS------------------------------------------------------
;$C87:
        dw      2AE7h
;Subroutine---------------------------------------------------------------
INIT:
        cpsu    040H         ;PSU &= %10111111;
        cpsl    008H         ;PSL &= %11110111;
        ppsl    002H         ;PSL |= %00000010;
        lodi,r0 0EEH         ;r0 = $EE;
        stra,r0 VSCROLL      ;VSCROLL = r0 [$EE];

;PITCH = VOLUME = 0;
        lodi,r0 000H         ;r0 = 0;
        stra,r0 PITCH        ;PITCH = r0 [0];
        lodi,r0 000H         ;r0 = 0; // useless!
        stra,r0 VOLUME       ;VOLUME = r0 [0];

        lodi,r2 020H         ;r2 = 32; // loop iterator
        lodi,r1 0FFH         ;r1 = -1;
        lodi,r0 000H         ;r0 = 0; // useless!
;clear memory from $18D0..$18EF (user RAM)
INIT_1:
        stra,r0 18D0H,r1+    ;*(18D0 + ++r1) = r0 [0];
        bdrr,r2 INIT_1       ;if (--r2 != 0) goto INIT_1;
;end of loop

        lodi,r2 004H         ;r2 = 4; // loop iterator
        lodi,r1 0FFH         ;r1 = -1;
        lodi,r0 000H         ;r0 = 0; // useless!
;clear memory from $18F8..18FB (user RAM)
INIT_2:
        stra,r0 18F8H,r1+    ;*(18F8 + ++r1) = r0 [0];
        bdrr,r2 INIT_2       ;if (--r2 != 0) goto INIT_2;
;end of loop

        lodi,r2 030H         ;r2 = 48; // loop iterator
        lodi,r1 0FFH         ;r1 = -1;
        lodi,r0 000H         ;r0 = 0; // useless!
;clear memory from $1AD0..$1AFF (user RAM)
INIT_3:
        stra,r0 1AD0H,r1+    ;*(1AD0 + ++r1) = r0 [0]; // user RAM
        bdrr,r2 INIT_3       ;if (--r2 != 0) goto INIT_3;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;Although this routine is usable from anywhere, only LEVEL1FLYBY actually
;makes use of it - thus it is considered a service subroutine of
;LEVEL1FLYBY.

WAITVBL:
        tpsu    080h
        bctr,eq WAITVBL
WAITVBL_1:
        tpsu    080h
        bctr,lt WAITVBL_1
        retc,un
;Subroutine---------------------------------------------------------------
;This subroutine sets SPRITE0X, SPRITE1X, SPRITE2X and SPRITE3X to $FF.
SETXPOS:
        lodi,r1 000H         ;r1 = 0; // loop iterator
        lodi,r0 0FFH         ;r0 = $FF;
SETXPOS_1:
        stra,r0 SPRITE0X,r1  ;*(&SPRITE0X + r1) = r0 [$FF]; // sprite coordinates
        addi,r1 002H         ;r1 += 2;
        comi,r1 008H         ;compare r1 against 8
        bcfr,eq SETXPOS_1    ;if (!=) goto SETXPOS_1;
;end of loop
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;r1, r2, r3 are arguments to this subroutine
;r0 is a scratch register
;$18D0, $18D1 and $18D2 preserve r3, r2, r1 respectively
DRAWTOP:
;called by TITLESCREEN and CREDITS
;draws part of the title image

        stra,r3 18D0H        ;*(18D0) = r3; // user RAM
        lodi,r3 0FFH         ;r3 = -1;
L0CDC:
        stra,r2 18D1H        ;*(18D1) = r2; // user RAM
        stra,r1 18D2H        ;*(18D2) = r1; // user RAM
L0CE2:
        loda,r0 *ROMPOINTER2_H,r3+;r0 = *(ROMPOINTER2_H + ++r3); // user RAM
        stra,r0 17FFH,r1+    ;*(17FF + r1) = r0;
        subi,r2 001H         ;r2--;
        bcfr,eq L0CE2        ;if (!=) goto L0CE2;

        loda,r1 18D2H        ;r1 = *(18D2); // user RAM
        addi,r1 010H         ;r1 += 16;
        loda,r2 18D1H        ;r2 = *(18D1); // user RAM
        loda,r0 18D0H        ;r0 = *(18D0);
        subi,r0 001H         ;r0--;
        stra,r0 18D0H        ;*(18D0) = r0;
        bcfr,eq L0CDC        ;if (!=) goto L0CDC;
;end of loop

	retc,un
;Subroutine---------------------------------------------------------------
DRAWBOTTOM:
;service subroutine of TITLESCREEN
;draws part of the title image
	stra,r3	18D0H
	lodi,r3	0FFH
DRAWBOTTOM_1:
	stra,r2	18D1H
	stra,r1	18D2H
DRAWBOTTOM_2:
        loda,r0 *ROMPOINTER2_H,r3+
        stra,r0 19FFH,r1+
	subi,r2	001H
        bcfr,eq DRAWBOTTOM_2
	loda,r1	18D2H
	addi,r1	010H
	loda,r2	18D1H
	loda,r0	18D0H
	subi,r0	001H
	stra,r0	18D0H
        bcfr,eq DRAWBOTTOM_1
	retc,un
;Subroutine---------------------------------------------------------------
L0D27:
;this vital routine accesses all of *(POINTER + 1)..*(POINTER + 5)
;it has been seen to be called with POINTER values of:
; $1AD0: ?
; $1AD3 (ALIEN1STATUS) - ALIEN1Y, ALIEN1X, ALIEN1TOGGLE, ALIEN1DELTA, ALIEN1COUNTER
; $1AD9 (ALIEN2STATUS) - ALIEN2Y, ALIEN2X, ALIEN2TOGGLE, ALIEN2DELTA, ALIEN2COUNTER
; $18DC (LIVES)        - PLAYERY, PLAYERX, $18DF,        FACING,      PLAYERCOUNTER

        lodi,r1 005H         ;r1 = 5;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [5]);
        bcta,eq L0D8B        ;if (==) goto L0D8B;

;subtract 1 from the low nybble but preserve the high nybble
        lodi,r1 003H         ;r1 = 3;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [3]);
        andi,r0 00FH         ;r0 &= %00001111;
        subi,r0 001H         ;r0--;
        strz    r2           ;r2 = r0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [3]);
        andi,r0 0F0H         ;r0 &= %11110000;
        iorz    r2           ;r0 |= r2;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [3]) = r0;

        andi,r0 00FH         ;r0 &= %00001111; // extract low nybble
        bcfa,eq L0D8B        ;if (!= 0) goto L0D8B;

;copy high nybble of *(POINTER + 3) into low nybble
        lodi,r1 003h         ;r1 = 3;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [3]);
        andi,r0 0F0H         ;r0 &= %11110000; // extract high nybble
        rrr,r0               ;rotate r0 to the right quarce
	rrr,r0
	rrr,r0
	rrr,r0
;high nybble has been extracted and normalized
        strz    r2           ;r2 = r0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [3]);
        andi,r0 0F0H         ;r0 &= %11110000; // extract high nybble
        iorz    r2           ;r0 |= r2;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [3]) = r0;

        lodi,r1 004H         ;r1 = 4;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
        andi,r0 0F0H         ;r0 &= %11110000; // extract high nybble
        rrr,r0               ;rotate r0 to the right quarce
	rrr,r0
	rrr,r0
        rrr,r0
        addz    r0           ;r0 += r0; // double r0
        strz    r2           ;r2 = r0;
        lodi,r1 001H         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
        adda,r0 0D8CH,r2     ;r0 += *(D8C + r2); // ROM data
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [1]) = r0;
        addi,r1 001H         ;r1++;
        addi,r2 001H         ;r2++;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
        adda,r0 0D8CH,r2     ;r0 += *(D8C + r2); // ROM data
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [2]) = r0;

;*(POINTER + 5)--;
        lodi,r1 005H         ;r1 = 5;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [5]);
        subi,r0 001H         ;r0--;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [5]) = r0;

L0D8B:
        retc,un              ;return;
;Data for L0D27-----------------------------------------------------------
X0D8C:
	db	0FEH, 000H, 0FEH, 002H
	db	000H, 002H, 002H, 002H
	db	002H, 000H, 002H, 0FEH
	db	000H, 0FEH, 0FEH, 0FEH
;Subroutine---------------------------------------------------------------
DELAY:
        lodi,r1 000H         ;r1 = 0; // inner loop iterator
DELAY_1:
        bdrr,r1 DELAY_1      ;if (--r1 != 0) goto DELAY_1;
;end of inner loop

        bdrr,r0 DELAY_1      ;if (--r2 != 0) goto DELAY_1;
;end of outer loop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
LOADR0:
;r1 is passed as argument
;sets r0
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1); // user RAM
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
STORER0:
;r0 and r1 are passed as arguments
        stra,r0 *POINTER_H,r1;*(POINTER + r1) = r0; // user RAM
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0DAB:
        loda,r0 *ROMPOINTER2_H,r1;r0 = *(ROMPOINTER2_H + r1); // user RAM
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;this is a slave subroutine of ALIENDIRECTION ($219E), which itself is a slave of LEVEL1LOOP
;its only action is to return a boolean value (0 or 1)
;it doesn't change memory or hardware
;return code is in r0
;POINTER is ALIENnSTATUS (ALIEN1STATUS or ALIEN2STATUS) during this routine
L0DAF:

;pseudocode translation of entire subroutine is as follows:
;r0 = ALIENnDELTA & 11110000;
;if (r0 == 0 || r0 == $40) then return(0);
;else if (r0 < $40)
;    if (ALIENnX > $70) then return(1); else return(0);
;else
;    if (ALIENnX < 8) then return(1); else return(0);

        lodi,r1 004h         ;r1 = 4;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
                             ;r0 = *(ALIENnSTATUS + r1 [4]);
                             ;r0 = ALIENnDELTA;
        andi,r0 0f0h         ;r0 &= %11110000;
        comi,r0 000h         ;compare r0 against 0
        bctr,eq L0DD6        ;if (==) goto L0DD6;
        comi,r0 040h         ;compare r0 against $40
        bctr,eq L0DD6        ;if (==) goto L0DD6;
        comi,r0 040h         ;compare r0 against $40
        bctr,lt L0DCD        ;if (<) goto L0DCD;

        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(ALIENnSTATUS + r1 [2]);
                             ;r0 = ALIENnX;
        comi,r0 008h         ;compare r0 against 8
        bctr,lt L0DDA        ;if (<) goto L0DDA;
        bctr,un L0DD6        ;goto L0DD6;
L0DCD:
        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(ALIENnSTATUS + r1 [2]);
                             ;r0 = ALIENnX;
        comi,r0 070h         ;compare r0 against $70
        bctr,gt L0DDA        ;if (>) goto L0DDA;
L0DD6:

;return(0);
        lodi,r0 000h         ;r0 = 0;
        bctr,un L0DDC        ;goto L0DDC;

L0DDA:
;return(1);
        lodi,r0 001h         ;r0 = 1;
L0DDC:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0DDD:
;this is a slave subroutine of ALIENDIRECTION ($219E), which itself is a slave of LEVEL1LOOP
;its only action is to return a boolean value (0 or 1)
;it doesn't change memory or hardware
;return code is in r0
;POINTER is ALIENnSTATUS (ALIEN1STATUS or ALIEN2STATUS) during this routine
        lodi,r1 004h         ;r1 = 4;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
                             ;r0 = *(ALIENnSTATUS + r1 [4]);
                             ;r0 = ALIENnDELTA;
        andi,r0 0f0h         ;r0 &= %11110000;

;if (r0 == $20 || r0 == $60) goto L0E0A;
;if (r0 < $20 || r0 > $60) goto L0DF6;
        comi,r0 020h         ;compare r0 against $20
        bctr,eq L0E0A        ;if (==) goto L0E0A;
        comi,r0 060h         ;compare r0 against $60
        bctr,eq L0E0A        ;if (==) goto L0E0A;
        comi,r0 020h         ;compare r0 against $20
        bctr,lt L0DF6        ;if (<) goto L0DF6;
        comi,r0 060h         ;compare r0 against $60
        bctr,gt L0DF6        ;if (>) goto L0DF6;
        bctr,un L0E01        ;goto L0E01;
L0DF6:
;out of bounds
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(ALIENnSTATUS + r1 [1]);
                             ;r0 = ALIENnY;
        comi,r0 010h         ;compare r0 against $10
        bctr,lt L0E0E        ;if (<) goto L0E0E;
        bctr,un L0E0A        ;goto L0E0A;
L0E01:
        lodi,r1 001h         ;r1 = 1;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [1]);
                             ;r0 = *(ALIENnSTATUS + r1 [1]);
                             ;r0 = ALIENnY;
        comi,r0 0b0h         ;compare r0 against $B0
        bctr,gt L0E0E        ;if (>) goto L0E0E;
L0E0A:
        lodi,r0 000h         ;r0 = 0; // return code
        bctr,un L0E10        ;goto L0E10;
L0E0E:
        lodi,r0 001h         ;r0 = 1; // return code
L0E10:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
UPDATESCORE:
;this is a slave subroutine of COLLDETECT

;if (FLAGS & %00100000 != 0) goto L0E25;
        loda,r0 FLAGS
        andi,r0 020h
        bcfr,eq L0E25

;level is 1
;look at the low byte of POINTER
        loda,r0 POINTER_L    ;r0 = POINTER_L;
        comi,r0 0f2h         ;compare r0 against $F2
        bctr,eq L0E40        ;if (==) goto L0E40;
        comi,r0 0ebh         ;compare r0 against $EB
        bctr,eq L0E40        ;if (==) goto L0E40;
        bctr,un L0E3A        ;goto L0E3A;
L0E25:

;level is 2
;look at the low byte of POINTER
        loda,r0 POINTER_L    ;r0 = POINTER_L;
        comi,r0 0d2h         ;compare r0 against $D2
        bctr,eq L0E3A        ;if (==) goto L0E3A;
        comi,r0 0d9h         ;compare r0 against $D9
        bctr,eq L0E3A        ;if (==) goto L0E3A;
        comi,r0 0e0h         ;compare r0 against $E0
        bctr,eq L0E3A        ;if (==) goto L0E3A;
        comi,r0 0eeh         ;compare r0 against $EE
        bctr,eq L0E40        ;if (==) goto L0E40;
        bctr,un L0E46        ;goto L0E46;
L0E3A:
        lodi,r1 004h         ;r1 = 4;
        lodi,r3 002h         ;r3 = 2;
        bctr,un L0E4A        ;goto L0E4A;
L0E40:
        lodi,r1 004h         ;r1 = 4;
        lodi,r3 005h         ;r3 = 5;
        bctr,un L0E4A        ;goto L0E4A;
L0E46:
        lodi,r1 003h         ;r1 = 3;
        lodi,r3 001h         ;r3 = 1;
L0E4A:
        loda,r0 1800h,r1     ;r0 = *(1800 + r1);
        addz    r3           ;r0 += r3;
        comi,r0 01ah         ;compare r0 against $1A
        bctr,lt L0E69        ;if (<) goto L0E69;
        lodi,r0 010h         ;r0 = '1' [$10];
        stra,r0 1800h,r1     ;*(1800 + r1) = r0;
L0E57:
        subi,r1 001h         ;r1--;
        loda,r0 1800h,r1     ;r0 = *(1800 + r1);
        addi,r0 001h         ;r0++;
        comi,r0 01ah         ;compare r0 against $1A ['A']
        bctr,lt L0E69        ;if (<) goto L0E69;
        lodi,r0 010h         ;r0 = $10 ['1'];
        stra,r0 1800h,r1     ;*(1800 + r1) = r0 [$10];
        bctr,un L0E57        ;goto L0E57;
L0E69:
        stra,r0 1800h,r1     ;*(1800 + r1) = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
DRAWSTARS:
;called by LEVEL2FLYBY, LEVEL2LOOP, SCROLLUP
;it is only used on level 2

        bsta,un 28E9h        ;gosub $28E9;
        comi,r0 003H         ;compare r0 against 3
        bctr,lt DRAWSTARS_1  ;if (<) goto DRAWSTARS_1;
        lodi,r0 034H         ;r0 = $34 ['.'];
        bctr,un DRAWSTARS_2  ;goto DRAWSTARS_2;
DRAWSTARS_1:
        lodi,r0 000H         ;r0 = ' ' [0];
DRAWSTARS_2:

;    --0- --1- --2- --3- --4- --5- --6- --7- --8- --9- -10- -11- -12- -13- -14- -15-
; 0: 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 180A 180B 180C 180D 180E 180F
; 1: 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 181A 181B 181C 181D 181E 181F
; 2: 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 182A 182B 182C 182D 182E 182F
; 3: 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 183A 183B 183C 183D 183E 183F
; 4: 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 184A 184B 184C   *  184E 184F
; 5: 1850   *  1852 1853 1854 1855 1856 1857   *  1859 185A 185B 185C 185D 185E 185F
; 6: 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 186A 186B 186C 186D 186E 186F
; 7: 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 187A 187B 187C 187D 187E 187F
; 8: 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 188A 188B 188C 188D 188E 188F
; 9: 1890 1891 1892   *  1894 1895 1896   *  1898 1899 189A 189B 189C 189D   *  189F
;10: 18A0 18A1 18A2 18A3 18A4 18A5 18A6 18A7 18A8 18A9 18AA 18AB 18AC 18AD 18AE 18AF
;11: 18B0 18B1 18B2 18B3 18B4 18B5 18B6 18B7 18B8 18B9 18BA 18BB 18BC 18BD 18BE 18BF
;12: 18C0 18C1 18C2 18C3 18C4 18C5 18C6 18C7 18C8 18C9 18CA 18CB 18CC 18CD 18CE 18CF
;13: 1A00 1A01 1A02 1A03 1A04 1A05 1A06 1A07 1A08   *  1A0A 1A0B 1A0C 1A0D   *  1A0F
;14: 1A10 1A11 1A12 1A13 1A14 1A15 1A16 1A17 1A18 1A19 1A1A 1A1B 1A1C 1A1D 1A1E 1A1F
;15: 1A20   *  1A22 1A23 1A24 1A25 1A26 1A27 1A28 1A29 1A2A 1A2B 1A2C 1A2D 1A2E 1A2F
;16: 1A30 1A31 1A32 1A33 1A34   *  1A36 1A37 1A38 1A39 1A3A 1A3B   *  1A3D 1A3E 1A3F
;17: 1A40 1A41 1A42 1A43 1A44 1A45 1A46 1A47 1A48 1A49 1A4A 1A4B 1A4C 1A4D 1A4E 1A4F
;1A: 1A50 1A51 1A52 1A53 1A54 1A55 1A56 1A57 1A58 1A59 1A5A 1A5B 1A5C 1A5D 1A5E 1A5F
;19: 1A60 1A61 1A62 1A63 1A64 1A65 1A66 1A67 1A68 1A69   *  1A6B 1A6C 1A6D 1A6E 1A6F
;20: 1A70 1A71   *  1A73 1A74 1A75 1A76 1A77 1A78 1A79 1A7A 1A7B 1A7C 1A7D   *  1A7F
;21: 1A80 1A81 1A82 1A83 1A84 1A85 1A86   *  1A88 1A89 1A8A 1A8B 1A8C 1A8D 1A8E 1A8F
;22: 1A90 1A91 1A92 1A93 1A94 1A95 1A96 1A97 1A98 1A99 1A9A 1A9B 1A9C 1A9D 1A9E 1A9F
;23: 1AA0 1AA1 1AA2 1AA3 1AA4 1AA5 1AA6 1AA7 1AA8 1AA9 1AAA   *  1AAC 1AAD 1AAE 1AAF
;24: 1AB0 1AB1 1AB2 1AB3 1AB4 1AB5 1AB6 1AB7 1AB8 1AB9 1ABA 1ABB 1ABC 1ABD 1ABE 1ABF
;25: 1AC0 1AC1 1AC2 1AC3 1AC4 1AC5 1AC6 1AC7 1AC8 1AC9 1ACA 1ACB 1ACC 1ACD 1ACE 1ACF

        stra,r0 184DH        ;*(184D) = r0; // (13,4)
        stra,r0 1851H        ;etc.
	stra,r0	1858H
	stra,r0	1893H
	stra,r0	1897H
	stra,r0	189EH
	stra,r0	1A09H
	stra,r0	1A0EH
	stra,r0	1A21H
	stra,r0	1A35H
	stra,r0	1A3CH
	stra,r0	1A6AH
	stra,r0	1A72H
	stra,r0	1A7EH
	stra,r0	1A87H
	stra,r0	1AABH
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
GAMEOVER:
        bsta,un 2922h        ;gosub CLEARSCREEN2;
        bsta,un DRAWLINE     ;gosub DRAWLINE;
        bsta,un SETXPOS      ;gosub SETXPOS;

;LIVES = 5;
        lodi,r0 005h         ;r0 = 5;
        stra,r0 LIVES        ;LIVES = r0 [5]; // user RAM

;PITCH = 0;
        lodi,r0 000h         ;r0 = 0;
        stra,r0 PITCH        ;PITCH = r0 [0];

        lodi,r2 009h         ;r2 = 9; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;copy from $ECD..$ED5 ("GAME OVER" in ROM data) to $18C3..$18CB (upper screen)
GAMEOVER_1:
        loda,r0 0ecdh,r1     ;r0 = *(ECD + r1);
        stra,r0 18c3h,r1     ;*(18C3 + r1) = r0;
        addi,r1 001h         ;r1++;
        bdrr,r2 GAMEOVER_1   ;if (--r2 != 0) goto GAMEOVER_1;
;end of loop

        retc,un              ;return;
;Data for GAMEOVER--------------------------------------------------------
;$ECD:
        db      020H, 01AH, 026H, 01EH, 000H, 028H, 02FH, 01EH, 02BH ;"GAME OVER"
;Subroutine---------------------------------------------------------------
SETROMPOINTER2:
;r3 is passed as an argument
;it can be $C, $E, $12, $1C, $1E, $20, $24, $26, $28,
;$2A, $2E, $32, $34, $36, $38, $3A, $3C, $3E, $40 or $42

;ROMPOINTER2 = *(F4A + r3);
        loda,r0 0F4AH,r3     ;r0 = *(F4A + r3);
        stra,r0 ROMPOINTER2_H ;ROMPOINTER2_H = r0;
        loda,r0 0F4BH,r3     ;r0 = *(F4B + r3);
        stra,r0 ROMPOINTER2_L ;ROMPOINTER2_L = r0;

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
SETPOINTER:
;r3 is passed as an argument, it is a multiple of 2
;This subroutine sets POINTER to any of many values
;held in a table in ROM.

;POINTER = *(F4A + r3);
        loda,r0 0F4AH,r3     ;r0 = *(F4A + r3);
        stra,r0 POINTER_H    ;POINTER_H = r0; // user RAM
        loda,r0 0F4BH,r3     ;r0 = *(F4B + r3);
        stra,r0 POINTER_L    ;POINTER_L = r0; // user RAM

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;this popular subroutine has three entry points.
;it tests bits 6..4 of *(POINTER) against $10, $20 or $30

TEST10:
;entry point
;POINTER is pointing to $18EC
	lodi,r3	010H
        bctr,un TEST_1
TEST20:
;entry point
;POINTER is pointing to $18EC or $1AD0 or LIVES
	lodi,r3	020H
        bctr,un TEST_1
TEST30:
;entry point
;POINTER is pointing to $1AD0
        lodi,r3 030h

TEST_1:
        lodi,r1 000H         ;r1 = 0;

        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]); // inefficient!
                             ;r0 = POINTER;
        andi,r0 070H         ;r0 &= %01110000;
;r0 is %0xxx0000, where x are corresponding bits of *(POINTER)
        comz    r3           ;compare r0 against r3 [$10, $20 or $30]

;condition codes are set before returning
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
L0F03:
;POINTER points to $1AEB or $1AF2 during this routine

        bsta,un TEST20       ;gosub TEST20;
        bcfa,eq L0F49        ;if (!=) goto L0F49;
        bsta,un L0D27        ;gosub L0D27;

        lodi,r1 002h         ;r1 = 2;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [2]);
                             ;r0 = *(1AED) or *(1AF4);
        andi,r0 0f0h         ;r0 &= %11110000;
        comi,r0 0b0h         ;compare r0 against $B0
        bctr,eq L0F3D        ;if (==) goto L0F3D;

        lodi,r1 005h         ;r1 = 5;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [5]);
                             ;r0 = *(1AF0) or *(1AF7);
        bcfr,eq L0F49        ;if (!=) goto L0F49;

        lodi,r1 006h         ;r1 = 6;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [6]);
                             ;r0 = *(1AF1) or *(1AF8);
        addi,r0 002h         ;r0 += 2;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [6]) = r0;
                             ;*(1AF1) or *(1AF8) = r0;
        strz    r2
        lodi,r1 004h
        loda,r0 *0ff3h,r2    ;r0 = *(*(FF3) + r2);
                             ;r0 = *(2CAF + r2); // ROM data
        stra,r0 *POINTER_H,r1;*(POINTER + r1) = r0;
        lodi,r1 005h         ;r1 = 5;
        addi,r2 001h         ;r2++;
        loda,r0 *0ff3h,r2    ;r0 = *(*(FF3) + r2);
                             ;r0 = *(2CAF + r2); // ROM data
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [5]) = r0;
        bctr,un L0F49
L0F3D:

;*(POINTER) &= %00001111;
;*(POINTER) |= %00010000;
        lodi,r1 000h         ;r1 = 0;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [0]);
                             ;r0 = *(POINTER);
        andi,r0 00fh         ;r0 &= %00001111;
        iori,r0 010h         ;r0 |= %00010000;
        stra,r0 *POINTER_H,r1;*(POINTER + r1 [0]) = r0;
                             ;*(POINTER) = r0;

L0F49:
        retc,un              ;return;
;Pointers for SETPOINTER and SETROMPOINTER2--------------------------------
X0F4A:
;pointers to user RAM
        dw      1AD0h        ;r3 =   0
        dw      LIVES        ;r3 =   2
        dw      18E4h        ;r3 =   4
        dw      18E7H        ;r3 =   6
        dw      18EAh        ;r3 =   8
        dw      BULLETDIR    ;r3 =  $A
        dw      ALIEN1STATUS ;r3 =  $C
        dw      ALIEN2STATUS ;r3 =  $E
        dw      1AF2h        ;r3 = $10
        dw      1AEBH        ;r3 = $12
        dw      1AD2h        ;r3 = $14
        dw      ALIEN2STATUS ;r3 = $16
        dw      1AE0h        ;r3 = $18
        dw      1AE7H        ;r3 = $1A
        dw      1AEEh        ;r3 = $1C
;pointers to ROM graphics
        dw      2C8FH        ;r3 = $1E
        dw      2B57h        ;r3 = $20 (upper of man facing right pointing up)
        dw      2B57H        ;r3 = $22 (upper of man facing right pointing up)
        dw      2C87h        ;r3 = $24 (alien)
        dw      2C47H        ;r3 = $26
        dw      2C27h        ;r3 = $28 ('tank' facing right pointing right)
        dw      2C17H        ;r3 = $2A ('infantry' facing right)
        dw      2C17h        ;r3 = $2C ('infantry' facing right)
        dw      2C67H        ;r3 = $2E
        dw      2D0Bh        ;r3 = $30 (vertical bullet)

;KLUDGE:
;to get better alien explosions at the cost of worse player explosions
;       dw      2E09H        ;r3 = $32 (short explosion)
;       dw      2E09H        ;r3 = $32 (short explosion)
;OLD:
        dw      2E0BH        ;r3 = $32 (short explosion)
        dw      2E3Bh        ;r3 = $34 (tall explosion)

        dw      2E1BH        ;r3 = $36
        dw      2E4Bh        ;r3 = $38 (blank #3)
        dw      2E53H        ;r3 = $3A (blank #4)
        dw      2E63h        ;r3 = $3C (blank #5)
        dw      2E13H        ;r3 = $3E (blank #2)
        dw      2E4Bh        ;r3 = $40 (blank #3)
        dw      2E2Bh        ;r3 = $42 (blank #1)
;Subroutine---------------------------------------------------------------
L0F8E:
;sets r1
;POINTER is $1AD0 during LEVEL1FLYBY
;POINTER is $18DC during LEVEL1LOOP

        lodi,r1 004H         ;r1 = 4;
        loda,r0 *POINTER_H,r1;r0 = *(POINTER + r1 [4]);
                             ;r0 = ALIEN1Y; // during LEVEL1FLYBY, or
                             ;r0 = FACING;  // during LEVEL1LOOP
        andi,r0 00FH         ;r0 &= %00001111; // extract low nybble
        rrl,r0               ;rotate r0 to the left thrice
	rrl,r0
	rrl,r0
        strz    r1           ;r1 = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;this subroutine also works for sprites
;ROMPOINTER must be set by the caller
;r1 and r2 are passed as arguments
;r0 and r3 are scratch registers
;r1: offset into ROM
;r2: which UDC to change
; 0 = UDC #0
; 8 = UDC #1
;16 = UDC #2
;24 = UDC #3
CHANGEUDC:
        lodi,r3 008H         ;r3 = 8;
CHANGEUDC_1:
        loda,r0 *ROMPOINTER2_H,r1;r0 = *(ROMPOINTER2_H + r1); // user RAM
        stra,r0 UDC0,r2      ;*(&UDC0 + r2) = r0; // UDCs
        addi,r1 001H         ;r1++;
        addi,r2 001H         ;r2++;
        bdrr,r3 CHANGEUDC_1  ;if (--r3 != 0) goto CHANGEUDC_1;
;end of loop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
ALIEN1CTRL:
        loda,r0 SPR23CTRLCOPY;r0 = SPR23CTRLCOPY;
        andi,r0 0c7h         ;r0 &= %11000111;
        iori,r0 0c0h         ;r0 |= %11000000;
;r0 is now %11000xxx, where x are unchanged
        iorz    r3           ;r0 |= r3;
        stra,r0 SPR23CTRLCOPY;SPR23CTRLCOPY = r0;
        stra,r0 SPRITES23CTRL;SPRITES23CTRL = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
ALIEN2CTRL:
        loda,r0 SPR23CTRLCOPY;r0 = SPR23CTRLCOPY;
        andi,r0 0f8h         ;r0 &= %11111000;
        iori,r0 0c0h         ;r0 |= %11000000;
;r0 is now %11xxx000, where x are unchanged
        iorz    r3           ;r0 |= r3;
        stra,r0 SPR23CTRLCOPY;SPR23CTRLCOPY = r0;
        stra,r0 SPRITES23CTRL;SPRITES23CTRL = r0;
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;r3 is passed to this popular subroutine, it can be 0, 2, 4 or 6
;it doesn't return anything to the caller
CHANGESOUND:

;if (ROMPOINTER1_L == $C8) then *(1AFF) = NOTE;
        loda,r0 ROMPOINTER1_L; r0 = ROMPOINTER1_L; // user RAM
        comi,r0 0C8H         ;compare r0 against $C8
        bcfr,eq L0FD4        ;if (!=) goto L0FD4;
        loda,r0 NOTE         ;r0 = NOTE; // user RAM
        stra,r0 1AFFH        ;*(1AFF) = r0; // user RAM

L0FD4:

;DURATION = 1;
        lodi,r0 001H         ;r0 = 1;
        stra,r0 DURATION     ;DURATION = r0 [1]; // user RAM

;NOTE = 0;
        lodi,r0 000H         ;r0 = 0;
        stra,r0 NOTE         ;NOTE = r0 [0]; // user RAM

;ROMPOINTER1 = *(FEB + r3);
        loda,r0 0FEBH,r3     ;r0 = *(FEB + r3); // ROM data
        stra,r0 ROMPOINTER1_H;ROMPOINTER1_H = r0; // user RAM
        loda,r0 0FECH,r3     ;r0 = *(FEC + r3); // ROM data
        stra,r0 ROMPOINTER1_L;ROMPOINTER1_L = r0; // user RAM

        retc,un              ;return;
;Pointers for CHANGESOUND-------------------------------------------------
X0FEB:
;ROMPOINTER1 is a pointer which can point to any of the following ROM data areas:
        dw      $2E73        ;sound effect #1 (player firing)
        dw      $2E7E        ;sound effect #2 (alien killed)
        dw      $2E8E        ;sound effect #3 (player killed)
        dw      $2EC8        ;MUSICDATA
;Pointer for L0F03--------------------------------------------------------
X0FF3:
        dw      2CAFH
;Junk?--------------------------------------------------------------------
        db      0CCH, 010H, 0E9H
	db	01BH, 00EH, 00CH, 010H
	db	0E9H, 0ECH, 01EH, 084H
;4K Break-----------------------------------------------------------------
;Subroutine---------------------------------------------------------------
;$2000:
;FLYBYSETUP:
        lodi,r2 007h         ;r2 = 7; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$2004:
;copy from $200F..$2015 (ROM data) to $1AD0..$1AD6 (user RAM)
                                       
        db      00Dh, 060h, 00Fh
;means  loda,r0 200fh,r1     ;r0 = *(200F + r1);

        db      0CDh, 0E0H, 0C8h
;means  stra,r0 *20c8h,r1    ;*(*(20C8 + r1)) = r0;
                             ;*(1AD0 + r1) = r0;

        addi,r1 001h         ;r1++;
        bdrr,r2 1004h        ;if (--r2 != 0) goto $2004;
;end of loop

        retc,un
;Data for $2000 (FLYBYSETUP)----------------------------------------------
;$200F:
        db      020H, 0A0H, 0A0H, 041H, 061H, 032H, 000H
;Subroutine---------------------------------------------------------------
;$2016:
        bsta,un TEST20       ;gosub TEST20;
        bcfa,eq 2041h        ;if (!=) goto $2041;
        lodi,r0 005h         ;r0 = 5;
        bsta,un DELAY        ;gosub DELAY;
        bsta,un L0D27        ;gosub L0D27;

;load r0 from *(POINTER + 5)
        lodi,r1 005h         ;r1 = 5;
        bsta,un LOADR0       ;gosub LOADR0;

        bcfr,eq 1041h        ;if (!=) goto $2041;

;store $30 at *(POINTER + 5)
        lodi,r1 005h         ;r1 = 5;
        lodi,r0 030h         ;r0 = $30;
        bsta,un STORER0      ;gosub STORER0;

        lodi,r1 000h         ;r1 = 0;
        bsta,un LOADR0       ;gosub LOADR0;

;store $30 at *(POINTER + 0)
        andi,r0 00fh         ;r0 &= %00001111; // useless! r0 remains $30!
        iori,r0 030h         ;r0 |= %00110000; // useless! r0 remains $30!
        bsta,un STORER0      ;gosub STORER0;

        bsta,un L0346        ;gosub L0346;
;$2041:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$2042:
        bsta,un TEST30
        bcfa,eq 2068h
        bsta,un L0D27
        lodi,r1 005h
        bsta,un LOADR0
        bcfr,eq 1068h        ;if (!=) goto $2068;

;store $FF at *(POINTER + 1)
        lodi,r1 001h
        lodi,r0 0ffh
        bsta,un STORER0

;store $30 at *(POINTER + 2)
        addi,r1 001h
        bsta,un STORER0

        lodi,r1 000h
        bsta,un LOADR0

;store $30 at *(POINTER + 0)
        andi,r0 00fh         ;r0 &= %00001111; // useless! r0 remains $30!
        bsta,un STORER0

;$2068:
        retc,un
;Subroutine---------------------------------------------------------------
;$2069:
;MOVESHIP:

;POINTER = $1AD0;
        lodi,r3 000h         ;r3 = 0;
        bsta,un SETPOINTER   ;gosub SETPOINTER;

        bsta,un TEST20       ;gosub TEST20;
        bctr,eq 107ah        ;if (==) goto $207A;
        comi,r0 030h         ;compare r0 against $30
        bctr,eq 107ah        ;if (==) goto $207A;
        bcta,un 20b1h        ;goto $20B1;

;$207A:
        lodi,r1 001h         ;r1 = 1;
        bsta,un LOADR0       ;gosub LOADR0;

        eori,r0 0ffh         ;Exclusive r0 with %11111111 (flip all bits)
        subi,r0 010h         ;r0 -= $10;

        db      0CCH, 080H, 0B2H
;means  stra,r0 *20b2h       ;*(*(20B2)) = r0;
                             ;SPRITE2Y = r0;

        db      0CCH, 080H, 0B4H
;means  stra,r0 *20b4h       ;*(*(20B4)) = r0;
                             ;SPRITE3Y = r0;

        lodi,r1 002h         ;r1 = 2;
        bsta,un LOADR0       ;gosub LOADR0;

        addi,r0 02bh         ;r0 += $2B;

        db      0CCH, 080H, 0B6H
;means  stra,r0 *20b6h       ;*(*(20B6)) = r0;
                             ;SPRITE2X = r0;

        addi,r0 008h         ;r0 += 8;

        db      0CCH, 080H, 0B8H
;means  stra,r0 *20b8h       ;*(*(20B8)) = r0;
                             ;SPRITE3X = r0;

        bsta,un L0F8E        ;gosub L0F8E;

        rrl,r0               ;rotate r0 to the left once
        strz    r1           ;r1 = r0;

        lodi,r3 01eh         ;r3 = $1E;
        bsta,un SETROMPOINTER2        ;gosub SETROMPOINTER2;

;change UDC #2
        lodi,r2 010h         ;r2 = $10;
        bsta,un CHANGEUDC    ;gosub CHANGEUDC;

;change UDC #3
        lodi,r2 018h         ;r2 = $18;
        bsta,un CHANGEUDC    ;gosub CHANGEUDC;

        lodi,r0 0c0h

        db      0CCH, 080H, 0BEH
;means  stra,r0 *20beh       ;*(*(20BE)) = r0;
                             ;SPRITES23CTRL = r0;

;$20B1:
        retc,un              ;return;
;Data for $2069 (MOVESHIP)------------------------------------------------
;$20B2:
        dw      SPRITE2Y, SPRITE3Y, SPRITE2X, SPRITE3X
        dw      UDC2, UDC3
        dw      SPRITES23CTRL
        dw      ROMPOINTER2_H, ROMPOINTER2_L
        dw      POINTER_H, POINTER_L
;Pointer for $2000 (FLYBYSETUP)-------------------------------------------
;$20C8:
        dw      1AD0H
;Pointer------------------------------------------------------------------
        dw      2C8FH
;Subroutine---------------------------------------------------------------
;$20CC:
;DRAWSWARM:
;this is a service subroutine of LEVEL1FLYBY

        lodi,r2 003h         ;r2 = 3; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$20D0:
;copies from $211B..$211D (ROM data) to $1AD0..$1AD2 (user RAM)
;r1 ranges here from 0..2
        db      00Dh, 061h, 01Bh
;means  loda,r0 211bh,r1     ;r0 = *(211B + r1);
        db      0CDh, 0E2h, 0D0h
;means  stra,r0 *22d0h,r1    ;*(*(22D0) + r1) = r0;
                             ;*(1AD0 + r1) = r0; // user RAM
        addi,r1 001h         ;r1++;
        bdrr,r2 10d0h        ;if (--r2 != 0) goto $20D0;
;end of loop

        lodi,r0 010h         ;r0 = $10;

        lodi,r1 000h         ;r1 = 0;
        db      0CDH, 0E2h, 0D2h
;means  stra,r0 *22d2h,r1    ;*(*(22D2) + r1 [0]) = r0 [$10]; // inefficient!
                             ;*(&ALIEN1STATUS + r1 [0]) = r0 [$10]; // user RAM
                             ;ALIEN1STATUS = r0 [$10];

        lodi,r1 006h         ;r1 = 6;
        db      0CDH, 0E2h, 0D2h
;means  stra,r0 *22d2h,r1    ;*(*(22D2) + r1 [6]) = r0 [$10];
                             ;*(&ALIEN1STATUS + r1 [6]) = r0 [$10]; // user RAM
                             ;ALIEN2STATUS = r0 [$10];

        lodi,r2 00ch         ;r2 = 12; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$20EA:
;copies from $211E..$2129 (ROM data) to $1ADF..$1AEA (user RAM)
        db      00Dh, 061h, 01Eh
;means  loda,r0 211eh,r1     ;r0 = *(211E + r1); // ROM data
        db      0CDh, 0E2h, 0D4h
;means  stra,r0 *22d4h,r1    ;*(*(22D4) + r1) = r0;
                             ;*(1ADF + r1) = r0;
        addi,r1 001h         ;r1++;
        bdrr,r2 10eah        ;if (--r2 != 0) goto $20EA;
;end of loop

        lodi,r2 008h         ;r2 = 8; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$20F8:
;copies from $2C87..$2CA4 (ROM data) to $19A0..$19A7 (UDC #0 imagery)
        db      00Dh, 0E2h, 0D6h
;means  loda,r0 *22d6h,r1    ;r0 = *(*(22D6) + r1);
                             ;r0 = *(2C87 + r1);
        db      0CDh, 0A2h, 0B0h
;means  stra,r0 *22b0h,r1+   ;*(*(22B0) + ++r1) = r0;
                             ;*(199F + ++r1) = r0;
        bdrr,r2 10f8h        ;if (--r2 != 0) goto $20F8;
;end of loop

;    --0- --1- --2- --3- --4- --5- --6- --7- --8- --9- -10- -11- -12- -13- -14- -15-
; 0: 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 180A 180B 180C 180D 180E 180F
; 1: 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 181A 181B 181C 181D 181E 181F
; 2: 1820   *  1822   *  1824   *  1826   *  1828   *  182A   *  182C   *  182E   *
; 3: 1830 1831   *  1833 1834 1835   *  1837 1838 1839   *  183B 183C 183D   *  183F

;draw top row of alien swarm
        lodi,r2 008h         ;r2 = 8; // loop iterator
        lodi,r1 000h         ;r1 = 0;
        lodi,r0 0fch         ;r0 = $FC;
;$2106:
        db      0CDh, 0E2h, 0B2h
;means  stra,r0 *22b2h,r1    ;*(*(22B2) + r1) = r0 [$FC]; // UDC #0
                             ;*(1821 + r1) = r0 [$FC]; // UDC #0
        addi,r1 002h         ;r1 += 2;
        bdrr,r2 1106h        ;if (--r2 != 0) goto $2106;
;end of loop

        lodi,r2 004h         ;r2 = 4; // loop iterator
        lodi,r1 000h         ;r1 = 0;
        lodi,r0 0fch         ;r0 = $FC; // useless!
;$2113:
        db      0CDh, 0E2h, 0B4h
;means  stra,r0 *22b4h,r1    ;*(*(22B4) + r1) = r0 [$FC]; // UDC #0
                             ;*(1832 + r1) = r0 [$FC]; // UDC #0
        addi,r1 004h         ;r1 += 4;
        bdrr,r2 1113h        ;if (--r2 != 0) goto $2113;
;end of loop

        retc,un              ;return;
;Data for $20CC (DRAWSWARM)-----------------------------------------------
;$211B:
        db      $20  ;copied into $1AD0
        db      0C0H ;copied into ENEMIES
        db      001H ;copied into $1AD2

        db      021H ;copied into $1ADF
        db      032H ;copied into $1AE0
        db      023H ;copied into $1AE1
        db      025H ;copied into $1AE2
        db      036H ;copied into $1AE3
        db      027H ;copied into $1AE4
        db      029H ;copied into $1AE5
        db      03AH ;copied into $1AE6
        db      02BH ;copied into $1AE7
        db      02DH ;copied into $1AE8
        db      03EH ;copied into $1AE9
        db      02FH ;copied into $1AEA
;Subroutine---------------------------------------------------------------
;$212A:
;this subroutine is for level 1

        bsta,un TEST10
        bcfa,eq 2197h

        lodi,r3 006h         ;r3 = 6; // loop iterator
        lodi,r2 005h
        lodi,r1 006h
;$2136:

        db      00Eh, 0E2h, 0D4h
;means  loda,r0 *22d4h,r2    ;r0 = *(*(22D4) + r2);
                             ;r0 = *(1ADF + r2);

        bcfr,eq 1149h        ;if (!=) goto $2149;

        db      00Dh, 0E2h, 0D4h
;means  loda,r0 *22d4h,r1

        bcfr,eq 114ch        ;if (!=) goto $214C;
        subi,r2 001h
        addi,r1 001h
        bdrr,r3 1136h        ;if (--r3 != 0) goto $2136;
;end of loop

        bcta,un 2197h
;$2149:
        lodz    r2           ;r0 = r2;
        bctr,un 114dh        ;goto $214D;
;$214C:
        lodz    r1           ;r0 = r1;
;$214D:
        strz    r3

        lodi,r2 006h         ;r2 = 6; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$2152:
;r1 is 0..5 for values of r2 of 6..1 respectively

        db      00Dh, 061h, 098h
;means  loda,r0 2198h,r1     ;r0 = *(2198 + r1);

;store r0 at *(POINTER + r1)
        bsta,un STORER0      ;gosub STORER0;

        addi,r1 001h         ;r1++;
        bdrr,r2 1152h        ;if (--r2 != 0) goto $2152;
;end of loop

        lodi,r1 001h

        db      00Fh, 0E2h, 0D4h
;means  loda,r0 *22d4h,r3    ;r0 = *(*(22D4) + r3);
                             ;r0 = *(1ADF + r3);

;store r0 at *(POINTER + 1)
        andi,r0 0f0h
        rrr,r0
        bsta,un STORER0

        lodi,r1 002h

        db      00Fh, 0E2h, 0D4h
;means  loda,r0 *22d4h,r3    ;r0 = *(*(22D4) + r3);
                             ;r0 = *(1ADF + r3);

        andi,r0 00fh
        rrl,r0
        rrl,r0
        rrl,r0
        strz    r2

        db      00Ch, 082h, 0B6h
;means  loda,r0 *22b6h

        andi,r0 0e0h
        rrr,r0    
        rrr,r0
        rrr,r0
        rrr,r0
        rrr,r0
        addz    r2
;store r0 at *(POINTER + 2)
        bsta,un STORER0

        db      00Fh, 0E2h, 0D4h
;means  loda,r0 *22d4h,r3    ;r0 = *(*(22D4) + r3);
                             ;r0 = *(1ADF + r3);

        andi,r0 0f0h
        strz    r1

        db      00Fh, 0E2h, 0D4h
;means  loda,r0 *22d4h,r3    ;r0 = *(*(22D4) + r3);
                             ;r0 = *(1ADF + r3);

        andi,r0 00fh
        addz    r1
        strz    r1
        lodi,r0 000h

        db      0CDh, 0E2h, 0B8h
;means  stra,r0 *22b8h,r1    ;*(*(22B8) + r1) = r0;
                             ;*(1800 + r1) = r0;

        lodi,r0 000h

        db      0CFh, 0E2h, 0D4h
;means  stra,r0 *22d4h,r3    ;r0 = *(*(22D4) + r3);
                             ;r0 = *(1ADF + r3);

;$2197:
        retc,un
;Data for $212A-----------------------------------------------------------
;$2198:
        db      020H, 0FFH, 0FFH, 011H, 040H, 030H
;Subroutine---------------------------------------------------------------
;$219E:
;ALIENDIRECTION:
;POINTER is ALIENnSTATUS during this routine
;this routine is for level 1 only

        bsta,un TEST20       ;gosub TEST20;
        bcfa,eq 21f8h        ;if (!=) goto $21F8;
        bsta,un L0DAF        ;gosub L0DAF;
        comi,r0 000h         ;compare r0 against 0
        bcfr,eq 11b4h        ;if (!=) goto $21B4;
        bsta,un L0DDD        ;gosub L0DDD;
        comi,r0 000h         ;compare r0 against 0
        bcfr,eq 11b4h        ;if (!=) goto $21B4;
        bctr,un 11c7h        ;goto $21C7;
;$21B4:
        lodi,r1 004h         ;r1 = 4;
        bsta,un LOADR0       ;gosub LOADR0;
;r0 = *(POINTER + 4);
;in other words, r0 = ALIENnDELTA; // n is 1 or 2

;store r0 at *(POINTER + 4)
;ALIEN1DELTA
        addi,r0 040h         ;r0 += $40;
        andi,r0 07fh         ;r0 &= %01111111;
;the next line seems to be the one which changes ALIENnDELTA to $30
        bsta,un STORER0      ;gosub STORER0;

;store 4 at *(POINTER + 5)
;ALIENnCOUNTER = 4;
        lodi,r1 005h
        lodi,r0 004h
        bsta,un STORER0

;$21C7:
        bsta,un L0D27        ;gosub L0D27;
        lodi,r1 005h         ;r1 = 5;
        bsta,un LOADR0       ;gosub LOADR0;
;r0 = *(POINTER + 5);
;r0 = ALIENnCOUNTER;
        bcfa,eq 21f8h        ;if (!=) goto $21F8;
        bsta,un 28e9h        ;gosub $28E9;
        andi,r0 007h         ;r0 &= %00000111;
        rrl,r0               ;rotate r0 to the left quarce
        rrl,r0
        rrl,r0
        rrl,r0

;store r0 at *(POINTER + 4)
;in other words, ALIENnDELTA = r0;
        lodi,r1 004h         ;r1 = 4;
;the next line seems to be the one which changes ALIENnDELTA to $70
        bsta,un STORER0      ;gosub STORER0;

        bsta,un 28e9h        ;gosub $28E9;

;store r0 at *(POINTER + 5)
        addi,r0 010h
        lodi,r1 005h
        bsta,un STORER0

        bctr,un 11f8h        ;goto $21F8;
        lodi,r1 000h
        bsta,un LOADR0

        andi,r0 00fh
        iori,r0 010h
;store r0 at *(POINTER + 0)
        bsta,un STORER0

;$21F8:
        retc,un
;Subroutine---------------------------------------------------------------
;$21F9:

;POINTER = ALIEN1STATUS;
        lodi,r3 00ch
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 1209h        ;if (==) goto $2209;
        comi,r0 030h
        bctr,eq 1209h        ;if (==) goto $2209;
        bctr,un 120ch        ;goto $220C;
;$2209:
        bsta,un 2220h        ;gosub MOVEALIEN1;
;$220C:

;POINTER = ALIEN2STATUS;
        lodi,r3 00eh
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 121ch        ;if (==) goto $221C;
        comi,r0 030h
        bctr,eq 121ch        ;if (==) goto $221C;
        bctr,un 121fh        ;goto $221F;
;$221C:
        bsta,un 2244h        ;gosub MOVEALIEN2;
;$221F:
        retc,un
;Subroutine---------------------------------------------------------------
;MOVEALIEN1:
;$2220:
;POINTER is ALIEN1STATUS during this routine
        lodi,r1 001h         ;r1 = 1;
        bsta,un LOADR0       ;gosub LOADR0;
;r0 = ALIEN1Y;
;console uses bottom-left corner as origin, game uses top-left corner
        eori,r0 0ffh         ;Exclusive OR r0 with %11111111 (flip all bits)
        subi,r0 010h         ;r0 -= $10; // move alien down

        db      0CCh, 082h, 0BAh
;means  stra,r0 *22bah       ;*(*(22BA)) = r0;
                             ;SPRITE2Y = r0;

        lodi,r1 002h         ;r1 = 2;
        bsta,un LOADR0       ;gosub LOADR0;
;r0 = ALIEN1X;
        addi,r0 02bh         ;r0 += $2B;

        db      0CCh, 082h, 0BCh
;means  stra,r0 *22bch       ;*(*(22BC)) = r0;
                             ;SPRITE2X = r0;

        bsta,un 2268h        ;gosub $2268;

;change UDC #2
        lodi,r2 010h
        bsta,un CHANGEUDC

        lodi,r3 030h
        bsta,un ALIEN1CTRL
        retc,un
;Subroutine---------------------------------------------------------------
;MOVEALIEN2:
;$2244:
;POINTER is ALIEN2STATUS during this routine
        lodi,r1 001h         ;r1 = 1;
        bsta,un LOADR0       ;gosub LOADR0;
        eori,r0 0ffh         ;Exclusive OR r0 with %11111111 (flip all bits)
        subi,r0 010h         ;r0 -= $10;

        db      0CCh, 082h, 0C2h
;means  stra,r0 *22c2h       ;*(*(22C2)) = r0;
                             ;SPRITE3Y = r0;
        lodi,r1 002h         ;r1 = 2;
        bsta,un LOADR0       ;gosub LOADR0;
        addi,r0 02bh         ;r0 += $2B;

        db      0CCh, 082h, 0C4h
;means  stra,r0 *22c4h       ;*(*(22C4)) = r0;
                             ;SPRITE3X = r0;

        bsta,un 2268h        ;gosub $2268;

;change UDC #3
        lodi,r2 018h         ;r2 = $18;
        bsta,un CHANGEUDC    ;gosub CHANGEUDC;

        lodi,r3 006h         ;r3 = 6;
        bsta,un ALIEN2CTRL   ;gosub ALIEN2CTRL;

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$2268:
        bsta,un TEST20

        bctr,eq 1287h        ;goto $2287;
        lodi,r1 003h
        bsta,un LOADR0

        subi,r0 001h
;store r0 at *(POINTER + 3)
        bsta,un STORER0

        bcfr,eq 128eh        ;if (!=) goto $228E;
        lodi,r1 000h
        bsta,un LOADR0

        andi,r0 00fh
        iori,r0 010h
;store r0 at *(POINTER + 0)
        bsta,un STORER0

        bctr,un 12a0h        ;goto $22A0;
;$2287:
        lodi,r3 024h
        bsta,un SETROMPOINTER2
        bctr,un 12afh        ;goto $22AF;
;$228E:
        andi,r0 002h
        bcfr,eq 1299h        ;if (!=) goto $2299;
        lodi,r3 032h
        bsta,un SETROMPOINTER2
        bctr,un 12afh        ;goto $22AF;
;$2299:
        lodi,r3 034h
        bsta,un SETROMPOINTER2
        bctr,un 12afh        ;goto $22AF;
;$22A0:
        lodi,r3 038h
        bsta,un SETROMPOINTER2

;ENEMIES -= $10;
        lodi,r1 001h
        db      00Dh, 0E2h, 0D0h
;means  loda,r0 *22d0h,r1    ;r0 = *(*(22D0) + r1 [1]);
                             ;r0 = *(1AD0 + r1 [1]);
                             ;r0 = ENEMIES;
        subi,r0 010h
        db      0CDh, 0E2h, 0D0h
;means  stra,r0 *22d0h,r1    ;*(*(22D0) + r1 [1]) = r0;
                             ;*(1AD0 + r1 [1]) = r0;
                             ;ENEMIES = r0;

;$22AF:
        retc,un              ;return;
;Pointers-----------------------------------------------------------------
;$22B0:
        dw      199FH
        dw      1821H        ;start position for alien swarm, 1st row
        dw      1832H        ;start position for alien swarm, 2nd row
        dw      VOLUME
;$22B8:
        dw      1800H
        dw      SPRITE2Y, SPRITE2X
        dw      UDC2
        dw      SPRITES23CTRL
        dw      SPRITE3Y, SPRITE3X
        dw      UDC3
        dw      ROMPOINTER2_H, ROMPOINTER2_L
        dw      POINTER_H, POINTER_L
        dw      1AD0H
        dw      ALIEN1STATUS
;$22D4:
        dw      1ADFH
        dw      2C87H ;alien
        dw      2E0BH ;short explosion
        dw      2E13H ;blank #2
        dw      2E4BH ;blank #3
        dw      2CAFH
;Subroutine---------------------------------------------------------------
;$22E0:
;this is a service subroutine of LEVEL1FLYBY

;*(1AF2) = $10;
        lodi,r0 010h         ;r0 = $10;
        db      0CCh, 083h, 0F6h
;means  stra,r0 *23f6h       ;*(*(23F6)) = r0 [$10];
                             ;*(1AF2) = r0 [$10]; // user RAM

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$22E6:
        bsta,un TEST10
        bcfa,eq 2344h
        lodi,r1 001h

        db      00Dh, 0E3h, 0F8h
;means  loda,r0 *23f8h,r1

        andi,r0 0f0h
        bcta,eq 2344h

        db      00Ch, 083h, 0FAh
;means  loda,r0 *23fah

        andi,r0 0f0h
        comi,r0 010h
        bcfa,eq 2344h
        bsta,un 28e9h
        comi,r0 008h
        bctr,gt 1344h        ;if (>) goto $2344;

        lodi,r2 007h         ;r2 = 7; // loop iterator
        lodi,r1 000h
;$230B:

        db      00Dh, 063h, 045h
;means  loda,r0 2345h,r1

;store r0 at *(POINTER + r1)
        bsta,un STORER0

        addi,r1 001h
        bdrr,r2 130bh        ;if (--r2 != 0) goto $230B;
;end of loop

        bsta,un 28e9h
        andi,r0 004h
        bctr,eq 1344h        ;if (==) goto $2344;

;store $A0 at *(POINTER + 2)
        lodi,r1 002h
        lodi,r0 0a0h
        bsta,un STORER0

;store $61 at *(POINTER + 4)
        lodi,r1 004h
        lodi,r0 061h
        bsta,un STORER0

        lodi,r1 001h
        bsta,un LOADR0
        strz    r2

        db      00Ch, 083h, 0FCh
;means  loda,r0 *23fch

        rrr,r0
        rrr,r0
        andi,r0 03fh
        addz    r2
;store r0 at *(POINTER + 1)
        bsta,un STORER0

        comi,r0 070h
        bctr,lt 1344h        ;if (<) goto $2344;
        addi,r0 008h
;store r0 at *(POINTER + 5)
        bsta,un STORER0
;$2344:
        retc,un
;Data---------------------------------------------------------------------
;$2345:
        db      020H, 060H, 0C0H
	db	011H, 020H, 0FFH, 000H
;Unterminated Subroutine--------------------------------------------------
;$234C:
;jumps directly to subroutine L0F03, rather than branching and returning
        bcta,un L0F03
;Subroutine---------------------------------------------------------------
;this is a slave subroutine of VBLROUTINE
;$234F:
        lodi,r3 010h
        bsta,un 0ee3h
        bsta,un TEST20
        bctr,eq 1360h        ;if (==) goto $2360;
        comi,r0 030h
        bctr,eq 1360h        ;if (==) goto $2360;
        bcta,un 239ah
;$2360:
        lodi,r1 001h
        bsta,un LOADR0
        eori,r0 0ffh
        subi,r0 010h

        db      0CCh,  083h,  09Bh
;means  stra,r0 *239bh       ;r0 = *(*(239B));
                             ;r0 = SPRITE2Y;

        db      0CCh,  083h,  09Fh
;means  stra,r0 *239fh       ;r0 = *(*(239F));
                             ;r0 = SPRITE3Y;

        lodi,r1 002h
        bsta,un LOADR0
        addi,r0 02bh

        db      0CCh,  083h,  09Dh
;means  stra,r0 *239dh       ;r0 = *(*(239D));
                             ;r0 = SPRITE2X;

        addi,r0 008h

        db      0CCh,  083h,  0A1h
;means  stra,r0 *23a1h       ;r0 = *(*(23A1));
                             ;r0 = SPRITE3X;

        bsta,un 23a9h        ;gosub $23A9;
        bsta,un 0f8eh        ;gosub $F8E;
        rrl,r0
        strz    r1
        lodi,r2 010h
        bsta,un 0f9ah
        lodi,r2 018h
        bsta,un 0f9ah
        lodi,r3 008h
        bsta,un 0fa9h
        lodi,r3 001h
        bsta,un 0fb8h
;$239A:
        retc,un
;Pointers for $234F-------------------------------------------------------
;239B:
        dw      SPRITE2Y, SPRITE2X, SPRITE3Y, SPRITE3X
;Pointers-----------------------------------------------------------------
        dw      UDC2, UDC3, SPRITES23CTRL
;Subroutine---------------------------------------------------------------
;this subroutine is a slave subroutine of $234F

;$23A9:
        bsta,un TEST20       ;gosub TEST20;
        bctr,eq 13c8h        ;if (==) goto $23C8;

;*(POINTER + 3)--;
        lodi,r1 003h         ;r1 = 3;
        bsta,un LOADR0       ;gosub LOADR0;
        subi,r0 001h         ;r0--;
        bsta,un STORER0      ;gosub STORER0;

        bcfr,eq 13cfh        ;if (!=) goto $23CF;
        lodi,r1 000h
        bsta,un LOADR0
        andi,r0 00fh
        iori,r0 010h
        bsta,un STORER0
        bctr,un 13e1h        ;goto $23E1;
;$23C8:
        lodi,r3 026h
        bsta,un SETROMPOINTER2
        bctr,un 13edh        ;goto $23ED;
;$23CF:
        andi,r0 002h
        bcfr,eq 13dah        ;if (!=) goto $23DA;
        lodi,r3 036h
        bsta,un SETROMPOINTER2
        bctr,un 13e6h        ;goto $23E6;
;$23DA:
        lodi,r3 042h
        bsta,un SETROMPOINTER2
        bctr,un 13e6h        ;goto $23E6;
;$23E1:
        lodi,r3 03ch
        bsta,un SETROMPOINTER2
;$23E6:
        lodi,r1 004h
        lodi,r0 000h
        bsta,un STORER0
;$23ED:
        retc,un
;Pointers-----------------------------------------------------------------
;$23EE:
        dw      ROMPOINTER2_H, ROMPOINTER2_L, POINTER_H, POINTER_L
;$23F6:
        dw      1AF2H
;$23F8:
        dw      1AD0H
        dw      1AEBH
        dw      18DBH
        dw      2C47H
        dw      2E1BH
        dw      2E2BH ;blank #1
        dw      2E63H ;blank #5
        dw      2CAFH
;Subroutine---------------------------------------------------------------
;$2408:
;this is a service subroutine of LEVEL1FLYBY

;*(1AEB) = $10;
        lodi,r0 010h         ;r0 = $10;
        db      0CCh, 084h, 0EBh
;means  stra,r0 *24ebh       ;*(*(24EB)) = r0 [$10];
                             ;*(1AEB) = r0 [$10];

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$240E:
        bsta,un TEST10
        bcfa,eq 2451h
        lodi,r1 001h

        db      00Dh, 0E4h, 0E9h
;means  loda,r0 *24e9h,r1

        andi,r0 0f0h
        bcta,eq 2451h

        db      00Ch, 084h, 0EDh
;means  loda,r0 *24edh

        andi,r0 0f0h
        comi,r0 010h
        bcfr,eq 1451h        ;goto $2451;
        bsta,un 28e9h
        comi,r0 008h
        bctr,gt 1451h        ;goto $2451;

        lodi,r2 007h         ;r2 = 7; // loop iterator
        lodi,r1 000h
;$2432:

        db      00Dh, 064h, 052h
;means  loda,r0 2452h,r1

;store r0 at *(POINTER + r1)
        bsta,un STORER0

        addi,r1 001h
        bdrr,r2 1432h        ;if (--r2 != 0) goto $2432;
;end of loop

        bsta,un 28e9h
        andi,r0 004h
        bctr,eq 1451h        ;if (==) goto $2451;

;store $A0 at *(POINTER + 2)
        lodi,r1 002h
        lodi,r0 0a0h
        bsta,un STORER0

;store $62 at *(POINTER + 4)
        lodi,r1 004h
        lodi,r0 062h
        bsta,un STORER0
;$2451:
        retc,un
;Data for $240E-----------------------------------------------------------
;$2452:
        db      020H, 0B0H, 0C0H, 011H, 020H, 0FFH, 000H
;Subroutine---------------------------------------------------------------
;$2459:
        bcta,un L0F03

;POINTER = $1AEB;
        lodi,r3 012h
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 146dh        ;if (==) goto $246D;
        comi,r0 030h
        bctr,eq 146dh        ;if (==) goto $246D;
        bcta,un 2493h
;$246D:
        lodi,r1 001h
        bsta,un LOADR0
        eori,r0 0ffh
        subi,r0 010h

        db      0CCh, 084h, 094h
;means  stra,r0 *2494h

        lodi,r1 002h
        bsta,un LOADR0
        addi,r0 02bh

        db      0CCh, 084h, 096h
;means  stra,r0 *2496h

        bsta,un 249ch
        bsta,un L0F8E

;change UDC #2
        lodi,r2 010h
        bsta,un CHANGEUDC

        lodi,r3 020h
        bsta,un ALIEN1CTRL
;$2493:
        retc,un
;Pointers-----------------------------------------------------------------
;$2494:
        dw      SPRITE2Y, SPRITE2X
        dw      UDC2, SPRITES23CTRL
;Subroutine---------------------------------------------------------------
;$249C:
        bsta,un TEST20
        bctr,eq 14bbh        ;if (==) goto $24BB;
        lodi,r1 003h
        bsta,un LOADR0
        subi,r0 001h

;store r0 at *(POINTER + 3)
        bsta,un STORER0

        bcfr,eq 14c2h        ;if (!=) goto $24C2;
        lodi,r1 000h
        bsta,un LOADR0
        andi,r0 00fh
        iori,r0 010h

;store r0 at *(POINTER + 0)
        bsta,un STORER0

        bctr,un 14d4h        ;goto $24D4;
;$24BB:
        lodi,r3 028h
        bsta,un SETROMPOINTER2
        bctr,un 14e0h        ;goto $24E0;
;$24C2:
        andi,r0 002h
        bcfr,eq 14cdh        ;if (!=) goto $24CD;
        lodi,r3 032h
        bsta,un SETROMPOINTER2
        bctr,un 14d9h        ;goto $24D9;
;$24CD:
        lodi,r3 03eh
        bsta,un SETROMPOINTER2
        bctr,un 14d9h        ;goto $24D9;
;$24D4:
        lodi,r3 038h
        bsta,un SETROMPOINTER2
;$24D9:

;store $0 at *(POINTER + 4)
        lodi,r1 004h
        lodi,r0 000h
        bsta,un STORER0

;$24E0:
        retc,un
;Pointers----------------------------------------------------------------
;$24E1:
        dw      ROMPOINTER2_H, ROMPOINTER2_L
        dw      POINTER_H, POINTER_L
        dw      1AD0H, 1AEBH, 1AF2H ;variables
        dw      2C27H               ;'tank' facing right pointing right
        dw      2E0BH               ;short explosion
        dw      2E13H               ;blank #2
        dw      2E4BH               ;blank #3
        dw      2CAFH
;Subroutine---------------------------------------------------------------
;SETLEVEL2VARS:
;$24F9:
;this is a service subroutine of LEVEL2FLYBY
;pseudocode summary of entire routine is:
;*(1AD0) = $20;
;ENEMIES = $E0; // high nybble [15] is enemies remaining
;*(1AD2) =
;ALIEN2STATUS =
;*(1AE0) =
;*(1AE7) = 16;
;return;

;*(1AD0) = 32;
;ENEMIES = $E0;
        lodi,r2 002h         ;r2 = 2; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$24FD:
        db      00Dh, 065h, 01Eh
;means  loda,r0 251eh,r1     ;r0 = *(251E + r1); // ROM data
        db      0CDh, 0E7h, 038h
;means  stra,r0 *2738h,r1    ;*(*(2738) + r1) = r0;
                             ;*(1AD0 + r1) = r0; // user RAM
        addi,r1 001h         ;r1++;
        bdrr,r2 14fdh        ;if (--r2 != 0) goto $24FD;
;end of loop

;*(1AD2) = 16;
        lodi,r0 010h         ;r0 = 16;
        lodi,r1 000h         ;r1 = 0;
        db      0CDh, 0E7h, 03Ah
;means  stra,r0 *273ah,r1    ;*(*(273A) + r1 [0]) = r0 [16]; // inefficient!
                             ;*(1AD2 + r1 [0]) = r0 [16]; // user RAM
                             ;*(1AD2) = r0 [16];

;ALIEN2STATUS = 16;
        lodi,r1 007h         ;r1 = 7;
        db      0CDh, 0E7h, 03Ah
;means  stra,r0 *273ah,r1    ;*(*(273A) + r1 [7]) = r0 [16];
                             ;*(1AD2 + r1 [7]) = r0 [16]; // user RAM
                             ;ALIEN2STATUS = r0 [16];

;*(1AE0) = 16;
        lodi,r1 00eh         ;r1 = 14;
        db      0CDh, 0E7h, 03Ah
;means  stra,r0 *273ah,r1    ;*(*(273A) + r1 [14]) = r0 [16];
                             ;*(1AD2 + r1 [14]) = r0 [16]; // user RAM
                             ;*(1AE0) = r0 [16]);

;*(1AE7) = 16;
        lodi,r1 015h         ;r1 = 21;
        db      0CDh, 0E7h, 03Ah
;means  stra,r0 *273ah,r1    ;*(*(273A) + r1 [21]) = r0 [16];
                             ;*(1AD2 + r1 [21]) = r0 [16]; // user RAM
                             ;*(1AE7) = r0 [16]);

        retc,un              ;return;
;Pointer------------------------------------------------------------------
;$251E:
        db      020h, 0F0H
;Subroutine---------------------------------------------------------------
;$2520:
;this is a slave subroutine of LEVEL2LOOP
        bsta,un TEST10       ;gosub TEST10;
        bcfa,eq 2582h        ;if (!=) goto $2582;
        lodi,r1 001h         ;r1 = 1;

        db      00Dh, 0E7h, 038h
;means  loda,r0 *2738h,r1

        andi,r0 0f0h         ;r0 &= %11110000;
        bcta,eq 2582h        ;if (==) goto $2582;
        comi,r0 020h         ;compare r0 against $20
        bctr,lt 153eh        ;if (<) goto $253E;

        db      00Ch, 087h, 03Ch
;means  loda,r0 *273ch

        andi,r0 0f0h         ;r0 &= %11110000;
        comi,r0 010h         ;compare r0 against $10
        bcfa,eq 2582h        ;if (!=) goto $2582;
;$253E:
        bsta,un 28e9h        ;gosub $28E9;
        comi,r0 003h         ;compare r0 against 3
        bctr,gt 1582h        ;if (>) goto $2582;

        lodi,r2 007h         ;r2 = 7; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$2549:

        db      00Dh, 065h, 0A3h
;means  loda,r0 25a3h,r1

;store r0 at *(POINTER + r1)
        bsta,un STORER0      ;gosub STORER0;

        addi,r1 001h         ;r1++;
        bdrr,r2 1549h        ;if (--r2 != 0) goto $2549;
;end of loop

        bsta,un 28e9h        ;gosub $28E9;
        andi,r0 007h         ;r0 &= %00000111;
        rrl,r0
        rrl,r0
        strz    r2

        db      00Eh, 065h, 083h
;means  loda,r0 2583h,r2

        strz    r1
        bsta,un 28e9h
        rrl,r0
        rrl,r0
        addz    r1

;store r0 at *(POINTER + 1)
        lodi,r1 001h
        bsta,un STORER0

        db      00Eh, 065h, 084h
;means  loda,r0 2584h,r2

;store r0 at *(POINTER + 2)
        lodi,r1 002h
        bsta,un STORER0

        db      00Eh, 065h, 085h
;means  loda,r0 2585h,r2

;store r0 at *(POINTER + 4)
        lodi,r1 004h
        bsta,un STORER0

        db      00Eh, 065h, 086h
;means  loda,r0 2586h,r2

;store r0 at *(POINTER + 6)
        lodi,r1 006h
        bsta,un STORER0
;$2582:
        retc,un
;Data---------------------------------------------------------------------
;$2583:
        db      030H
        db      0C0H, 022H, 000H, 060H
	db	0A0H, 066H, 026H, 030H
	db	0C0H, 022H, 008H, 048H
	db	0A0H, 066H, 02EH, 030H
	db	0C0H, 022H, 01AH, 060H
	db	0A0H, 066H, 03CH, 030H
	db	0C0H, 022H, 008H, 060H
	db	0A0H, 066H, 03CH, 020H
	db	030H, 030H, 011H, 000H
	db	001H, 000H
;Subroutine---------------------------------------------------------------
;$25AA:
        bcta,un L0F03

;POINTER = $1AD2;
        lodi,r3 014h
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 15bdh        ;if (==) goto $25BD;
        comi,r0 030h  
        bctr,eq 15bdh        ;if (==) goto $25BD;
        bctr,un 15c0h        ;goto $25C0;
;$25BD:
        bcta,un 25fbh
;$25C0:

;POINTER = ALIEN2STATUS;
        lodi,r3 016h
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 15d0h        ;if (==) goto $25D0;
        comi,r0 030h
        bctr,eq 15d0h        ;if (==) goto $25D0;
        bctr,un 15d3h        ;goto $25D3;
;$25D0:
        bcta,un 262ch
;$25D3:
        retc,un
;Subroutine---------------------------------------------------------------
;$25D4:

;POINTER = $1AE0;
        lodi,r3 018h
        bsta,un SETPOINTER

        bsta,un TEST20       ;gosub TEST20;
        bctr,eq 15e4h        ;if (==) goto $25E4;
        comi,r0 030h         ;compare r0 against $30
        bctr,eq 15e4h        ;if (==) goto $25E4;
        bctr,un 15e7h        ;goto $25E7;
;$25E4:
        bcta,un 265dh
;$25E7:

;POINTER = $1AE7;
        lodi,r3 01ah
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 15f7h        ;if (==) goto $25F7;
        comi,r0 030h
        bctr,eq 15f7h        ;if (==) goto $25F7;
        bctr,un 15fah        ;goto $25FA;
;$25F7:
        bcta,un 268eh
;$25FA:
        retc,un
;Code Section-------------------------------------------------------------
;this is part of the subroutine at $25AA
;$25FB:
        lodi,r1 001h
        bsta,un LOADR0
        eori,r0 0ffh
        subi,r0 010h

        db      0CCh, 086h, 0BFh
;means  stra,r0 *26bfh

        lodi,r1 002h
        bsta,un LOADR0
        addi,r0 02bh

        db      0CCh, 086h, 0C1h
;means  stra,r0 *26c1h

        bsta,un 26cfh
        bsta,un L0F8E

;change UDC #2
        lodi,r2 010h
        bsta,un CHANGEUDC

        db      00Ch, 086h, 0CDh
;means  loda,r0 *26cdh

        andi,r0 047h
        iori,r0 018h

        db      0CCh, 086h, 0CDh
;means  stra,r0 *26cdh

        db      0CCh, 086h, 0CBh
;means  stra,r0 *26cbh

        bcta,un 25c0h
;Code Section-------------------------------------------------------------
;this is part of the subroutine at $25AA
;$262C:
        lodi,r1 001h
        bsta,un LOADR0
        eori,r0 0ffh
        subi,r0 010h

        db      0CCh, 086h, 0C3h
;means  stra,r0 *26c3h

        lodi,r1 002h
        bsta,un LOADR0
        addi,r0 02bh

        db      0CCh, 086h, 0C5h
;means  stra,r0 *26c5h

        bsta,un 26cfh
        bsta,un L0F8E

;change UDC #3
        lodi,r2 018h
        bsta,un CHANGEUDC

        db      00Ch, 086h, 0CDh
;means  loda,r0 *26cdh

        andi,r0 0b8h
        iori,r0 003h

        db      0CCh, 086h, 0CDh
;means  stra,r0 *26cdh

        db      0CCh, 086h, 0CBh
;means  stra,r0 *26cbh

        bcta,un 25d3h
;Code Section-------------------------------------------------------------
;this is part of the subroutine at $25D4
;$265D:
        lodi,r1 001h
        bsta,un LOADR0
        eori,r0 0ffh
        subi,r0 010h

        db      0CCh, 086h, 0BFh
;means  stra,r0 *26bfh

        lodi,r1 002h
        bsta,un LOADR0
        addi,r0 02bh

        db      0CCh, 086h, 0C1h
;means  stra,r0 *26c1h

        bsta,un 26cfh
        bsta,un L0F8E

;change UDC #2
        lodi,r2 010h
        bsta,un CHANGEUDC

        db      00Ch, 086h, 0CDh
;means  loda,r0 *26cdh

        andi,r0 047h
        iori,r0 018h

        db      0CCh, 086h, 0CDh
;means  stra,r0 *26cdh

        db      0CCh, 086h, 0CBh
;means  stra,r0 *26cbh

        bcta,un 25e7h
;Code Section-------------------------------------------------------------
;this is part of the subroutine at $25D4
;$268E:
        lodi,r1 001h         ;r1 = 1;
        bsta,un LOADR0       ;gosub LOADR0;
;now r0 is *(POINTER + r1 [1])
        eori,r0 0ffh         ;Exclusive OR r0 with %11111111 (flip all bits)
        subi,r0 010h         ;r0 -= $10;

        db      0CCh, 086h, 0C3h
;means  stra,r0 *26c3h       ;*(*(26C3)) = r0;
                             ;SPRITE3X = r0;
        lodi,r1 002h         ;r1 = 2;
        bsta,un LOADR0       ;gosub LOADR0;
;now r0 is *(POINTER + r1 [2])
        addi,r0 02bh         ;r0 += $2B;

        db      0CCh, 086h, 0C5h
;means  stra,r0 *26c5h       ;*(*(26C5)) = r0;
                             ;UDC2 = r0;
        bsta,un 26cfh        ;gosub $26CF;
        bsta,un L0F8E        ;gosub L0F8E;

;change UDC #3
        lodi,r2 018h         ;r2 = $18;
        bsta,un CHANGEUDC    ;gosub CHANGEUDC;

        db      00Ch, 086h, 0CDh
;means  loda,r0 *26cdh       ;r0 = *(*(26CD));
                             ;r0 = SPR23CTRLCOPY;
        andi,r0 0b8h         ;r0 &= %10111000;
        iori,r0 004h         ;r0 |= %00000100;
;r0 is now x0xxx100, where x are unchanged
        db      0CCh, 086h, 0CDh
;means  stra,r0 *26cdh       ;*(*(26CD)) = r0;
                             ;SPR23CTRLCOPY = r0;

        db      0CCh, 086h, 0CBh
;means  stra,r0 *26cbh       ;*(*(26CB)) = r0;
                             ;SPRITES23CTRL = r0;

        bcta,un 25fah        ;goto $25FA;
;Pointers-----------------------------------------------------------------
;$26BD:
        dw      SPRITE2Y, SPRITE2X, SPRITE3Y, SPRITE3X
        dw      UDC2, UDC3, SPRITES23CTRL, SPR23CTRLCOPY
;Subroutine---------------------------------------------------------------
;$26CF:
        bsta,un TEST20       ;gosub TEST20;
        bctr,eq 16efh        ;if (==) goto $26EF;

;load r0 from *(POINTER + 3)
        lodi,r1 003h         ;r1 = 3;
        bsta,un LOADR0       ;gosub LOADR0;

        subi,r0 001h         ;r0--;
;store r0 at *(POINTER + 3)
        bsta,un STORER0      ;gosub STORER0;

        bcfr,eq 1707h        ;if (!=) goto $2707;

;load r0 from *(POINTER + 0)
        lodi,r1 000h         ;r1 = 0;
        bsta,un LOADR0       ;gosub LOADR0;

        andi,r0 00fh         ;r0 &= %00001111;
        iori,r0 010h         ;r0 |= %00010000;
;store r0 at *(POINTER + 0)
        bsta,un STORER0      ;gosub STORER0;

        bcta,un 2719h        ;goto $2719;
;$26EF:
        lodi,r1 005h
        bsta,un LOADR0
        andi,r0 002h
        bcfr,eq 1700h        ;if (!=) goto $2700;
        lodi,r3 02ah
        bsta,un SETROMPOINTER2
        bcta,un 272fh
;$2700:
        lodi,r3 02ah
        bsta,un SETROMPOINTER2
        bctr,un 172fh        ;goto $272F;
;$2707:
        andi,r0 002h
        bcfr,eq 1712h        ;if (!=) goto $2712;
        lodi,r3 032h
        bsta,un SETROMPOINTER2
        bctr,un 1728h        ;if (!=) goto $2728;
;$2712:
        lodi,r3 03eh
        bsta,un SETROMPOINTER2
        bctr,un 1728h        ;goto $2728;
;$2719:
        lodi,r3 038h
        bsta,un SETROMPOINTER2
        lodi,r1 001h

        db      00Dh, 0E7h, 038h
;means  loda,r0 *2738h,r1

        subi,r0 010h

        db      0CDh, 0E7h, 038h
;means  stra,r0 *2738h,r1

;$2728:

;store $0 at *(POINTER + 4)
        lodi,r1 004h
        lodi,r0 000h
        bsta,un STORER0

;$272F:
        retc,un
;Pointers-----------------------------------------------------------------
;$2730:
        dw      ROMPOINTER2_H, ROMPOINTER2_L
        dw      POINTER_H, POINTER_L
        dw      1AD0H, 1AD2H
        dw      1AEEH
        dw      2C17H ;'infantry' facing right
        dw      2E0BH ;short explosion
        dw      2E13H ;blank #2
        dw      2E4BH ;blank #3
        dw      2CAFH
;Subroutine---------------------------------------------------------------
;$2748:

;*(1AEE) = $10;
        lodi,r0 010h         ;r0 = $10;
        db      0CCh, 088h, 075h
;means  stra,r0 *2875h       ;*(*(2875)) = r0 [$10];
                             ;*(1AEE) = r0 [$10];

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$274E:
        bsta,un TEST10       ;gosub TEST10;
        bcfa,eq $27bb        ;if (!= 0) goto $27BB;
        lodi,r1 001h         ;r1 = 1;

        db      00Dh, 0E8h, 077h
;means  loda,r0 *2877h,r1    ;r0 = *(*(2877) + r1 [1]);
                             ;r0 = *(1AD0 + r1 [1]);
                             ;r0 = *(1AD1);

        andi,r0 0f0h         ;r0 &= %11110000;
        bcta,eq 27bbh        ;if (== 0) goto $27BB;

        lodi,r3 002h         ;r3 = 2; // loop iterator
        lodi,r2 00eh         ;r2 = 15;
        lodi,r1 000h         ;r1 = 0;
;$2764:

        db      00Eh, 0E8h, 079h
;means  loda,r0 *2879h,r2

        andi,r0 0f0h         ;r0 &= %11110000;
        comi,r0 010h         ;compare r0 against %00010000
        bcfr,eq 176fh        ;if (!= 0) goto $276F;
        addi,r1 001h         ;r1++;
;$276F:
        addi,r2 007h         ;r2 += 7;
        bdrr,r3 1764h        ;if (--r3 != 0) goto $2764;
;end of loop

        comi,r1 002h         ;compare r1 against 2
        bcta,lt 27bbh        ;if (r1 < 2) goto $27BB;
        bsta,un 28e9h        ;gosub $28E9;
        comi,r0 006h         ;compare r0 against 6
        bctr,gt 17bbh        ;if (r0 > 6) goto $27BB;

        lodi,r2 007h         ;r2 = 7; // loop iterator
        lodi,r1 000h         ;r1 = 0;
;$2783:

        db      00Dh, 067h, 0C4h
;means  loda,r0 27c4h,r1     ;r0 = *(27C4 + r1); // ROM data

;store r0 at *(POINTER + r1)
        bsta,un STORER0

        addi,r1 001h         ;r1++;
        bdrr,r2 1783h        ;if (--r2 != 0) goto $2783;
;end of loop

        bsta,un 28e9h
        andi,r0 001h
        rrl,r0
        rrl,r0
        strz    r2

        db      00Eh, 067h, 0BCh
;means  loda,r0 27bch,r2

        strz    r1
        bsta,un 28e9h
        rrl,r0
        addz    r1

;store r0 at *(POINTER + 1)
        lodi,r1 001h
        bsta,un STORER0

        db      00Eh, 067h, 0BDh
;means  loda,r0 27bdh,r2

;store r0 at *(POINTER + 2)
        lodi,r1 002h
        bsta,un STORER0

        db      00Eh, 067h, 0BEh
;means  loda,r0 27beh,r2

;store r0 at *(POINTER + 4)
        lodi,r1 004h
        bsta,un STORER0

        db      00Eh, 067h, 0BFh
;means  loda,r0 27bfh,r2

;store r0 at *(POINTER + 6)
        lodi,r1 006h
        bsta,un STORER0

;$27BB:
        retc,un
;Data for $274E-----------------------------------------------------------
;$27BC:
	db	030H, 0C0H, 020H, 046H
	db	060H, 0A0H, 061H, 052H
	db	020H, 050H, 040H, 011H
	db	000H, 001H, 000H
;Subroutine---------------------------------------------------------------
;$27CB:
        bcta,un L0F03

;POINTER = $1AEE;
        lodi,r3 01ch
        bsta,un SETPOINTER

        bsta,un TEST20
        bctr,eq 17dfh        ;if (==) goto $27DF;
        comi,r0 030h
        bctr,eq 17dfh        ;if (==) goto $27DF;
        bcta,un 2817h
;$27DF:
        lodi,r1 001h
        bsta,un LOADR0
        eori,r0 0ffh
        subi,r0 010h

        db      0CCh, 088h, 01Ah
;means  stra,r0 *281ah

        db      0CCh, 088h, 01Eh
;means  stra,r0 *281eh

        lodi,r1 002h
        bsta,un LOADR0
        addi,r0 02bh

        db      0CCh, 088h, 01Ch
;means  stra,r0 *281ch

        addi,r0 008h

        db      0CCh, 088h, 020h
;means  stra,r0 *2820h

        bsta,un 2828h
        bsta,un L0F8E

        rrl,r0
        strz    r1

;change UDC #2
        lodi,r2 010h
        bsta,un CHANGEUDC
        lodi,r2 $18
        bsta,un CHANGEUDC
        lodi,r0 0C9h

        db      0CCh, 088h, 018h
;means  stra,r0 *2818h

        db      0CCh, 088h, 026h
;means  stra,r0 *2826h

;$2817:
        retc,un
;Pointers-----------------------------------------------------------------
;$2818:
        dw      SPR23CTRLCOPY
        dw      SPRITE2Y, SPRITE2X, SPRITE3Y, SPRITE3X
        dw      UDC2, UDC3, SPRITES23CTRL
;Subroutine---------------------------------------------------------------
;$2828:
        bsta,un TEST20
        bctr,eq 1847h        ;if (==) goto $2847;
        lodi,r1 003h
        bsta,un LOADR0
        subi,r0 001h

;store r0 at *(POINTER + 3)
        bsta,un STORER0

        bcfr,eq 184eh        ;if (!=) goto $284E;
        lodi,r1 000h
        bsta,un LOADR0
        andi,r0 00fh
        iori,r0 010h

;store r0 at *(POINTER + 0)
        bsta,un STORER0

        bctr,un 1860h        ;goto $2860;
;$2847:
        lodi,r3 02eh
        bsta,un SETROMPOINTER2
        bctr,un 186ch        ;goto $286C;
;$284E:
        andi,r0 002h
        bcfr,eq 1859h        ;if (!=) goto $2859;
        lodi,r3 036h
        bsta,un SETROMPOINTER2
        bctr,un 1865h        ;goto $2865;
;$2859:
        lodi,r3 042h
        bsta,un SETROMPOINTER2
        bctr,un 1865h        ;goto $2865;
;$2860:
        lodi,r3 03ch
        bsta,un SETROMPOINTER2
;$2865:

;store $0 at *(POINTER + 4)
        lodi,r1 004h
        lodi,r0 000h
        bsta,un STORER0

;$286C:
        retc,un
;Pointers-----------------------------------------------------------------
;$286D:
        dw      ROMPOINTER2_H, ROMPOINTER2_L
        dw      POINTER_H, POINTER_L
        dw      1AEEH, 1AD0H, 1AD2H, 2C67h
        dw      2E1BH
        dw      2E2BH ;blank #1
        dw      2E63H ;blank #5
        dw      2CAFh
;Subroutine---------------------------------------------------------------
;$2885:
;CHECKXMOVE:
;this is a service routine of L036E, it can be called for either level
;returns 0 in r0 if further movement is possible
;returns 1 in r0 if further movement not possible
;POINTER points to $18DC during this routine
;this routine checks whether X-movement is possible for the player

;load r0 from *(POINTER + 4)
;in other words, r0 = FACING;
        lodi,r1 004h
        bsta,un LOADR0

        andi,r0 0f0h         ;r0 &= %11110000;

;if (r0 == 0) goto $28AC;
        comi,r0 000h         ;compare r0 against 0
        bctr,eq 18ach        ;if (==) goto $28AC;

;if (r0 == $40) goto $28AC;
        comi,r0 040h         ;compare r0 against $40
        bctr,eq 18ach        ;if (==) goto $28AC;

;if (r0 < $40) goto $28A3;
        comi,r0 040h         ;compare r0 against $40
        bctr,lt 18a3h        ;if (==) goto $28A3;

;load r0 from *(POINTER + 2)
;in other words, r0 = PLAYERX;
        lodi,r1 002h
        bsta,un LOADR0

;if (r0 < 8) goto $28B0;
        comi,r0 008h         ;compare r0 against 8
        bctr,lt 18b0h        ;if (<) goto $28B0;

        bctr,un 18ach        ;goto $28AC;

;$28A3:

;load r0 from *(POINTER + 2)
;in other words, r0 = PLAYERX;
        lodi,r1 002h
        bsta,un LOADR0

;if (r0 > $70) goto $28B0;
        comi,r0 070h         ;compare r0 against $70
        bctr,gt 18b0h        ;if (>) goto $28B0;

;$28AC:
        lodi,r0 000h         ;r0 = 0; // return code
        bctr,un 18b2h        ;goto $28B2;

;$28B0:
        lodi,r0 001h         ;r0 = 1; // return code

;$28B2:
        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$28B3:
;CHECKYMOVE:
;this is a service routine of L036E, it can be called for either level
;returns 0 in r0 if further movement is possible
;returns 1 in r0 if further movement not possible
;POINTER points to $18DC during this routine
;this routine checks whether Y-movement is possible for the player

;load r0 from *(POINTER + 4)
;in other words, r0 = FACING;
        lodi,r1 004
        bsta,un LOADR0

        andi,r0 0f0h         ;r0 &= %11110000;

;if (r0 == $20) goto $2828; // if pointing right
        comi,r0 020h
        bcta,eq 28E2h        ;if (==) goto $2828;

;if (r0 == $60) goto $28E2; // if pointing left
        comi,r0 060h
        bcta,eq 28E2h        ;if (==) goto $2828;

;if (r0 < $20) goto $28CE;
        comi,r0 020h
        bctr,lt 18ceh        ;if (<) goto $28CE;

;if (r0 > $60) goto $28CE;
        comi,r0 060h
        bctr,gt 18ceh        ;if (>) goto $28CE;

        bctr,un 18d9h        ;goto $28D9;

;$28CE:

;load r0 from *(POINTER + 1)
;in other words, r0 = PLAYERY;
        lodi,r1 001h
        bsta,un LOADR0

;if (r0 < $18) goto $28E6;
        comi,r0 018h
        bctr,lt 18e6h        ;if (<) goto $28E6;

        bctr,un 18e2h        ;goto $28E2;

;$28D9:

;load r0 from *(POINTER + 1)
;in other words, r0 = PLAYERY;
        lodi,r1 001h
        bsta,un LOADR0

;if (r0 > $B0) goto $28E6;
        comi,r0 0b0h
        bctr,gt 18e6h        ;if (>) goto $28E6;

;$28E2:
        lodi,r0 000h         ;r0 = 0; // return code
        bctr,un 18e8h        ;goto $28E8;

;$28E6:
        lodi,r0 001h         ;r0 = 1; // return code
;$28E8:
        retc,un
;Subroutine---------------------------------------------------------------
;$28E9:
;this popular subroutine works with the value of *(18DB).
;it is not passed any arguments.
;the return code is put into r0.

;if (*(18DB) == 0) then *(18DB) = 3;
        db      00Ch, 089h, 011h
;means  loda,r0 *2911h
        bcfr,eq 18F3h        ;if (!=) goto $28F3;
        lodi,r0 003h         ;r0 = 3;
        db      0CCH, 089H, 011H
;means  stra,r0 *2911h

;$28F3:
        andi,r0 $81          ;r0 &= %10000001;
        bctr,eq 1905h        ;if (==) goto $2905;
        eori,r0 081h         ;Exclusive OR r0 with %10000001
        bctr,eq 1905h        ;if (==) goto $2905;

        db      00Ch, 089h, 011h
;means  loda,r0 *2911h

        db      08Ch, 089h, 011h
;means  adda,r0 *2911h

        addi,r0 001h         ;r0++;
        bctr,un 190bh        ;goto $290B;
;$2905:

        db      00Ch, 089h, 011h
;means  loda,r0 *2911h

        db      08Ch, 089h, 011h
;means  adda,r0 *2911h

;$290B:

        db      0CCH, 089H, 011H
;means  stra,r0 *2911h

        andi,r0 00fh         ;r0 &= %00001111;
        retc,un              ;return;
;Pointer for $28E9--------------------------------------------------------
;$2911:
        dw      18DBh
;Subroutine---------------------------------------------------------------
;$2913:
;CLEARSCREEN1:
        lodi,r2 0d0h         ;r2 = $D0; // loop iterator
        lodi,r1 0ffh         ;r1 = -1;
        lodi,r0 000h         ;r0 = 0; // ' ' character
;$2919:

        db      0CDh, 0A9h, 039h
;clear all of upper screen
;means  stra,r0 *2939h,r1+   ;*(*(2939) + ++r1) = r0 [' '];
;       stra,r0 1800h,r1+    ;*(1800 + ++r1) = r0 [' '];

        db      0CDh, 0E9h, 03Bh
;clear all of lower screen
;means  stra,r0 *293bh,r1    ;*(*(293B) + r1) = r0 [' '];
;       stra,r0 1A00h,r1     ;*(1A00 + r1) = r0 [' '];

        bdrr,r2 1919h        ;if (--r2 != 0) goto $2919;
;end of loop

        retc,un              ;return;
;Subroutine---------------------------------------------------------------
;$2922:
;CLEARSCREEN2:
        lodi,r2 0c0h         ;r2 = $C0; // loop iterator
        lodi,r1 00fh         ;r1 = 15;
        lodi,r0 000h         ;r0 = 0; // ' ' character
;clear from $1810..$18CF (all of upper screen except top row)
;$2928:

        db      0CDh, 0A9h, 039h
;means  stra,r0 *2939h,r1+   ;*(*(2939) + ++r1) = r0;
;       stra,r0 4087h,r1+    ;*(1800 + ++r1) = r0; // upper screen

        bdrr,r2 1928h        ;if (--r2 != 0) goto $2928;
;end of loop

        lodi,r2 0d0h         ;r2 = $D0; // loop iterator
        lodi,r1 0ffh         ;r1 = -1;
        lodi,r0 000h         ;r0 = 0; // ' ' character (useless!)
;clear from $1A00..$1ACF (all of lower screen)
;$2933:

        db      0CDh, 0A9h, 03Bh
;means  stra,r0 *293bh,r1+   ;*(*(293B) + ++r1) = r0;
;       stra,r0 FLAGS,r1+    ;*(1A00 + ++r1) = r0; // lower screen

        bdrr,r2 1933h        ;if (--r2 != 0) goto $2933;
;end of loop

        retc,un              ;return;
;Pointers-----------------------------------------------------------------
;$2939:
        dw      1800h
;$293B:
        dw      1A00h
;$293D:
        dw      18D8H
;Data for SETUDCS---------------------------------------------------------
;$293F:
        db      040H, 087H, 009H, 009H
;$2943:
        db      000H, 06BH, 000H, 08BH, 000H, 073H, 000H, 083H
;$294B:
        db      000H ;........ sprite #0
        db      00FH ;....####
        db      03FH ;..######
        db      0FFH ;########
        db      0FFH ;########
        db      03FH ;..######
        db      00FH ;....####
        db      003H ;......##

        db      000H ;........ sprite #1
        db      0F0H ;####....
        db      0FCH ;######..
        db      0FFH ;########
        db      0FFH ;########
        db      0FCH ;######..
        db      0F0H ;####....
        db      0C0H ;##......

        db      000H ;........ sprite #2
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########

        db      000H ;........ sprite #3
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########
        db      0FFH ;########

        db      018H ;...##... UDC #4
        db      018H ;...##...
        db      03CH ;..####..
        db      03CH ;..####..
        db      07EH ;.######.
        db      07EH ;.######.
        db      0FFH ;########
        db      0FFH ;########

        db      0FFH ;######## UDC #5
        db      0FFH ;########
        db      07EH ;.######.
        db      07EH ;.######.
        db      03CH ;..####..
        db      03CH ;..####..
        db      018H ;...##...
        db      018H ;...##...

        db      01FH ;...##... UDC #6
        db      01FH ;...##...
        db      01FH ;...##...
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H

        db      0C3H ;##....## UDC #7
        db      0C3H ;##....##
        db      0C3H ;##....##
        db      0C3H ;##....##
        db      0C3H ;##....##
        db      0C3H ;##....##
        db      0C3H ;##....##
        db      0C3H ;##....##
;Data---------------------------------------------------------------------
;$298B:
        db      000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 00DH, 000H
	db	00CH, 043H, 04DH, 000H
	db	00CH, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 00FH, 00DH
	db	003H, 083H, 043H, 00CH
	db	00EH, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H, 00FH
	db	00DH, 043H, 00CH, 00EH
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 00CH, 003H
	db	00FH, 083H, 00EH, 0C3H
	db	0CDH, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 003H, 00CH
	db	003H, 0BDH, 003H, 00DH
	db	0C3H, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 003H, 000H
	db	000H, 083H, 000H, 000H
	db	0C3H, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 00CH, 008H, 000H
	db	000H, 000H, 000H
	db	000H, 0C9H
	db	0CDH, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 003H, 008H
	db	00DH, 000H, 03CH, 000H
	db	04CH, 0C9H
	db	0C3H, 000H, 000H, 000H
	db	000H
	db	000H, 000H, 000H, 003H
	db	00BH, 003H, 003H, 004H
	db	043H, 043H, 0CAH, 0C3H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H
	db	003H, 005H, 00FH, 003H
	db	004H, 043H, 04EH, 0C7H
	db	0C3H, 000H
;$2A2B:
        db      000H, 000H
	db	000H, 000H, 000H, 000H
	db	003H, 008H, 043H, 003H
	db	0FCH, 043H, 003H, 0C9H
	db	0C3H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 003H, 00BH, 043H
	db	003H, 0BCH, 043H, 003H
	db	0CAH, 0C3H, 000H, 000H
	db	08CH, 083H, 08DH, 000H
	db	000H, 00FH, 005H, 043H
	db	003H, 083H, 043H, 003H
	db	0C7H, 0CEH, 000H, 000H
	db	083H, 000H, 083H, 000H
	db	000H, 000H, 0CFH, 04FH
	db	003H, 083H, 043H, 00EH
	db	0CEH, 000H
	db	000H, 000H, 083H, 000H
	db	083H, 000H, 000H, 000H
	db	000H, 043H, 00BH, 083H
	db	04AH, 0C3H, 000H, 000H
	db	000H, 000H, 083H, 000H
	db	083H
	db	000H, 00CH, 003H, 043H
	db	043H, 003H, 003H, 003H
	db	003H, 043H, 04DH, 000H
	db	000H, 083H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 000H, 000H, 000H
	db	000H, 083H, 0BEH, 083H
	db	0C0H, 07AH, 070H, 04DH
	db	064H, 060H, 05BH, 07FH
	db	042H, 049H, 064H, 000H
X1AAB:
	db	000H, 083H, 000H, 083H
	db	0C0H, 057H, 056H, 044H
	db	000H, 064H, 076H, 07BH
	db	042H, 05BH, 000H, 000H
	db	000H, 083H, 083H, 083H
	db	0C0H, 052H, 052H, 000H
	db	048H, 064H, 000H, 05FH
	db	000H, 072H, 05BH, 000H
	db	000H, 08FH, 08EH, 083H
	db	0C0H
X1AD0:
        db      076H, 076H, 049H, 07FH
	db	044H, 05BH, 077H, 000H
	db	07FH, 07FH, 000H
;Data for SETHARDWARE-----------------------------------------------------
;$2ADB:
        db      040H, 000H, 000H, 000H
;$2ADF:
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H
;Data for CREDITS---------------------------------------------------------
;$2AE7:
        db      000H, 000H, 09CH, 0A8H, 0A9H, 0B2H, 000H, 0ABH ;"  COPY RIGHT    "
        db      0A2H, 0A0H, 0A1H, 0ADH, 000H, 000H, 000H, 000H
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H ;"                "
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H
        db      000H, 000H, 0ACH, 0A8H, 0AEH, 0ADH, 0ACH, 0AEH ;"  SOUTSU AGENCY "
        db      000H, 09AH, 0A0H, 09EH, 0A7H, 09CH, 0B2H, 000H
        db      000H, 000H, 0A7H, 0A2H, 0A1H, 0A8H, 0A7H, 000H ;"  NIHON SUNRISE "
        db      0ACH, 0AEH, 0A7H, 0ABH, 0A2H, 0ACH, 09EH, 000H
        db      000H, 000H, 09BH, 09AH, 0A7H, 09DH, 09AH, 0A2H ;"  BANDAI        "
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H ;"                "
        db      000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H
        db      000H, 000H, 000H, 000H, 000H, 000H, 091H, 099H ;"      1983      "
        db      098H, 093H, 000H, 000H, 000H, 000H, 000H, 000H
;Data---------------------------------------------------------------------
;it is rather wasteful to store so many identical copies of the man's legs

;$2B57:
        db      0D9H ;##.##..# upper of man facing right pointing up
        db      0D9H ;##.##..#
        db      0FFH ;########
        db      0FFH ;########
        db      0FCH ;######..
        db      0FCH ;######..
        db      0D8H ;##.##...
        db      0DCH ;##.###..
        db      01CH ;...###.. lower of man facing right pointing up
        db      016H ;...#.##.
        db      013H ;...#..##
        db      033H ;..##..##
        db      066H ;.##..##.
        db      0ECH ;###.##..
        db      0CEH ;##..###.
        db      0CEH ;##..###.

        db      0D9H ;##.##..# upper of man facing right pointing up-right
        db      0DBH ;##.##.##
        db      0FEH ;#######.
        db      0FEH ;#######.
        db      0FCH ;######..
        db      0FCH ;######..
        db      0D8H ;##.##...
        db      0DCH ;##.###..
        db      01CH ;...###.. lower of man facing right pointing up-right
        db      016H ;...#.##.
        db      013H ;...#..##
        db      033H ;..##..##
        db      066H ;.##..##.
        db      0ECH ;###.##..
        db      0CEH ;##..###.
        db      0CEH ;##..###.

        db      0D8H ;##.##... upper of man facing right pointing right
        db      0D8H ;##.##...
        db      0FFH ;########
        db      0FFH ;########
        db      0FCH ;######..
        db      0FCH ;######..
        db      0D8H ;##.##...
        db      0DCH ;##.###..
        db      01CH ;...###.. lower of man facing right pointing right
        db      016H ;...#.##.
        db      013H ;...#..##
        db      033H ;..##..##
        db      066H ;.##..##.
        db      0ECH ;###.##..
        db      0CEH ;##..###.
        db      0CEH ;##..###.

        db      0D8H ;##.##... upper of man facing right pointing right (again!)
        db      0D8H ;##.##...
        db      0FFH ;########
        db      0FFH ;########
        db      0FCH ;######..
        db      0FCH ;######..
        db      0D8H ;##.##...
        db      0DCH ;##.###..
        db      01CH ;...###.. lower of man facing right pointing right (again!)
        db      016H ;...#.##.
        db      013H ;...#..##
        db      033H ;..##..##
        db      066H ;.##..##.
        db      0ECH ;###.##..
        db      0CEH ;##..###.
        db      0CEH ;##..###.

        db      0D8H ;##.##... upper of man facing right pointing down-right
        db      0D8H ;##.##...
        db      0FCH ;######..
        db      0FCH ;######..
        db      0FEH ;#######.
        db      0FEH ;#######.
        db      0DBH ;##.##.##
        db      0DDH ;##.###.#
        db      01CH ;...###.. lower of man facing right pointing down-right
        db      016H ;...#.##.
        db      013H ;...#..##
        db      033H ;..##..##
        db      066H ;.##..##.
        db      0ECH ;###.##..
        db      0CEH ;##..###.
        db      0CEH ;##..###.

        db      0D8H ;##.##... upper of man facing right pointing down
        db      0D8H ;##.##...
        db      0FFH ;########
        db      0FFH ;########
        db      0FDH ;######.#
        db      0FDH ;######.#
        db      0D8H ;##.##...
        db      0DCH ;##.###..
        db      01CH ;...###.. lower of man facing right pointing down
        db      016H ;...#.##.
        db      013H ;...#..##
        db      033H ;..##..##
        db      066H ;.##..##.
        db      0ECH ;###.##..
        db      0CEH ;##..###.
        db      0CEH ;##..###.

        db      01BH ;...##.## upper of man facing left pointing down
        db      01BH ;...##.##
        db      0FFH ;########
        db      0FFH ;########
        db      0BFH ;#.######
        db      0BFH ;#.######
        db      01BH ;...##.##
        db      03BH ;..###.##

        db      038H ;..###... lower of man facing left pointing down
        db      068H ;.##.#...
        db      0C8H ;##..#...
        db      0CCH ;##..##..
        db      066H ;.##..##.
        db      037H ;..##.###
        db      073H ;.###..##
        db      073H ;.###..##

        db      01BH ;...##.## upper of man facing left pointing down-left
        db      01BH ;...##.##
        db      03FH ;..######
        db      03FH ;..######
        db      07FH ;.#######
        db      07FH ;.#######
        db      0DBH ;##.##.##
        db      0DBH ;##.##.##
        db      038H ;..###... lower of man facing left pointing down-left
        db      068H ;.##.#...
        db      0C8H ;##..#...
        db      0CCH ;##..##..
        db      066H ;.##..##.
        db      037H ;..##.###
        db      073H ;.###..##
        db      073H ;.###..##

        db      01BH ;...##.## upper of man facing left pointing left
        db      01BH ;...##.##
        db      0FFH ;########
        db      0FFH ;########
        db      03FH ;..######
        db      03FH ;..######
        db      01BH ;...##.##
        db      03BH ;..###.##
        db      038H ;..###... lower of man facing left pointing left
        db      068H ;.##.#...
        db      0C8H ;##..#...
        db      0CCH ;##..##..
        db      066H ;.##..##.
        db      037H ;..##.###
        db      073H ;.###..##
        db      073H ;.###..##

        db      01BH ;...##.## upper of man facing left pointing left (again!)
        db      01BH ;...##.##
        db      0FFH ;########
        db      0FFH ;########
        db      03FH ;..######
        db      03FH ;..######
        db      01BH ;...##.##
        db      03BH ;..###.##
        db      038H ;..###... lower of man facing left pointing left (again!)
        db      068H ;.##.#...
        db      0C8H ;##..#...
        db      0CCH ;##..##..
        db      066H ;.##..##.
        db      037H ;..##.###
        db      073H ;.###..##
        db      073H ;.###..##

        db      09BH ;#..##.## upper of man facing left pointing up-left
        db      0DBH ;##.##.##
        db      07FH ;.#######
        db      07FH ;.#######
        db      03FH ;..######
        db      03FH ;..######
        db      01BH ;...##.##
        db      03BH ;..###.##
        db      038H ;..###... lower of man facing left pointing up-left
        db      068H ;.##.#...
        db      0C8H ;##..#...
        db      0CCH ;##..##..
        db      066H ;.##..##.
        db      037H ;..##.###
        db      073H ;.###..##
        db      073H ;.###..##

        db      09BH ;#..##.## upper of man facing left pointing up
        db      09BH ;#..##.##
        db      0FFH ;########
        db      0FFH ;########
        db      03FH ;..######
        db      03FH ;..######
        db      01BH ;...##.##
        db      03BH ;..###.##
        db      038H ;..###... lower of man facing left pointing up
        db      068H ;.##.#...
        db      0C8H ;##..#...
        db      0CCH ;##..##..
        db      066H ;.##..##.
        db      037H ;..##.###
        db      073H ;.###..##
        db      073H ;.###..##

;$2C17:
        db      00CH ;....##.. 'infantry' facing right
        db      078H ;.####...
        db      07CH ;.#####..
        db      03FH ;..######
        db      03AH ;..###.#.
        db      02CH ;..#.##..
        db      0ECH ;###.##..
        db      0CEH ;##..###.

        db      030H ;..##.... 'infantry' facing left
        db      01EH ;...####.
        db      03EH ;..#####.
        db      0FCH ;######..
        db      05CH ;.#.###..
        db      034H ;..##.#..
        db      037H ;..##.###
        db      073H ;.###..##

;$2C27:
        db      040H ;.#...... 'tank' facing right pointing right
        db      070H ;.###....
        db      0FFH ;########
        db      0F0H ;####....
        db      07CH ;.#####..
        db      0FEH ;#######.
        db      0FFH ;########
        db      07EH ;.######.

        db      041H ;.#.....# 'tank' facing right pointing up-right
        db      072H ;.###..#.
        db      0F4H ;####.#..
        db      0F8H ;#####...
        db      07CH ;.#####..
        db      0FEH ;#######.
        db      0FFH ;########
        db      07EH ;.######.

        db      002H ;......#. 'tank' facing left pointing left
        db      00EH ;....###.
        db      0FFH ;########
        db      00FH ;....####
        db      03EH ;..#####.
        db      07FH ;.#######
        db      0FFH ;########
        db      07EH ;.######.
               
        db      082H ;#.....#. 'tank' facing left pointing up-left
        db      04EH ;.#..###.
        db      02FH ;..######
        db      01FH ;...#####
        db      03EH ;..#####.
        db      07FH ;.#######
        db      0FFH ;########
        db      07EH ;.######.

;$2C47:
;.##..........##.
;.##..........##.
;.###........###.
;.#####....#####.
;.##############.
;..############..
;.......##.......
;.......##.......

        db      060H ;.##..... left side of object
        db      060H ;.##.....
        db      070H ;.###....
        db      07CH ;.#####..
        db      07FH ;.#######
        db      03FH ;..######
        db      001H ;.......#
        db      001H ;.......#

;................
;................
;....##....##....
;...##########...
;..############..
;..############..
;..############..
;...##########...

        db      000H ;........ right side of object
        db      000H ;........
        db      030H ;..##....
        db      0F8H ;#####...
        db      0FCH ;######..
        db      0FCH ;######..
        db      0FCH ;######..
        db      0F8H ;#####...

        db      000H ;........ left side of object
        db      000H ;........
        db      00CH ;....##..
        db      01FH ;...#####
        db      03FH ;..######
        db      03FH ;..######
        db      03FH ;..######
        db      01FH ;...#####

        db      006H ;.....##. right side of object
        db      006H ;.....##.
        db      00EH ;....###.
        db      03EH ;..#####.
        db      0FEH ;#######.
        db      0FCH ;######..
        db      080H ;#.......
        db      080H ;#.......

;$2C67:
;................
;................
;................
;................
;...###....###...
;..############..
;.##############.
;...##########...
;...#........#...
;...##.####.##...
;...#.#....#.#...
;...#.##..##.#...
;..#...####...#..
;.##....##....##.
;.###..####..###.
;................

        db      010H ;...#.... bottom left of object
        db      01BH ;...##.##
        db      014H ;...#.#..
        db      016H ;...#.##.
        db      023H ;..#...##
        db      061H ;.##....#
        db      073H ;.###..##
        db      000H ;........

        db      000H ;........ top right side of object
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      038H ;..###...
        db      0FCH ;######..
        db      0FEH ;#######.
        db      0F8H ;#####...

        db      000H ;........ top left side of object
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      01CH ;...###..
        db      03FH ;..######
        db      07FH ;.#######
        db      01FH ;...#####

        db      008H ;....#... bottom right of object
        db      0D8H ;##.##...
        db      028H ;..#.#...
        db      068H ;.##.#...
        db      0C4H ;##...#..
        db      086H ;#....##.
        db      0CEH ;##..###.
        db      000H ;........

;$2C87:
        db      018H ;...##... alien
        db      05AH ;.#.##.#.
        db      024H ;..#..#..
        db      018H ;...##...
        db      099H ;#..##..#
        db      07EH ;.######.
        db      03CH ;..####..
        db      018H ;...##...

;$2C8F:
;..#......#......
;..##....##......
;..###....##.....
;..##########....
;..############.
;.###############
;.#####.###.#####
;..####..#...####

        db      020H ;..#..... left side of object
        db      030H ;..##....
        db      038H ;..###...
        db      03FH ;..######
        db      01FH ;...#####
        db      07FH ;.#######
        db      07DH ;.#####.#
        db      03CH ;..####..

        db      040H ;.#...... right side of object
        db      0C0H ;##......
        db      060H ;.##.....
        db      0F0H ;####....
        db      0FEH ;#######.
        db      0FFH ;########
        db      0DFH ;##.#####
        db      08FH ;#...####

;$2C9F:
;......###...##.. ship
;........#..##...
;.......##.###..#
;...#########..#.
;....###########.
;.####..#########
;################
;#######...#####.

        db      003H ;......## left (front) of ship
        db      000H ;........
        db      001H ;.......#
        db      01FH ;...#####
        db      00FH ;....####
        db      079H ;.####..#
        db      0FFH ;########
        db      0FEH ;#######.

        db      08CH ;#...##.. right (back) of ship
        db      098H ;#..##...
        db      0B9H ;#.###..#
        db      0F2H ;####..#.
        db      0FEH ;#######.
        db      0FFH ;########
        db      0FFH ;########
        db      03EH ;..#####.

;$2CAF:
;non-graphics
        db      000H, 000H, 020H, 050H, 051H, 028H, 020H, 0FFH
        db      000H, 000H, 020H, 040H, 030H, 010H, 040H, 010H
        db      051H, 010H, 061H, 010H, 071H, 010H, 010H, 010H
        db      030H, 0FFH, 000H, 000H, 020H, 030H, 030H, 040H
        db      051H, 010H, 071H, 020H, 020H, 0FFH, 000H, 000H
        db      061H, 050H, 010H, 028H, 061H, 0FFH, 000H, 000H
        db      061H, 020H, 051H, 010H, 071H, 010H, 051H, 010H
        db      071H, 010H, 061H, 0FFH, 000H, 000H, 071H, 050H
        db      010H, 010H, 030H, 010H, 071H, 0FFH, 000H, 000H
        db      020H, 050H, 040H, 020H, 060H, 030H, 040H, 020H
        db      020H, 0FFH, 000H, 000H, 061H, 050H, 011H, 028H
        db      061H, 020H, 051H, 0FFH

;graphics again
;$2D0B:
        db      010H ;...#.... vertical bullet
        db      018H ;...##...
        db      030H ;..##....
        db      018H ;...##...
        db      030H ;..##....
        db      010H ;...#....
        db      000H ;........
        db      000H ;........

        db      000H ;........ enemy bullet
        db      028H ;..#.#...
        db      010H ;...#....
        db      028H ;..#.#...
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........ vertical bullet
        db      000H ;........
        db      010H ;...#....
        db      030H ;..##....
        db      018H ;...##...
        db      030H ;..##....
        db      018H ;...##...
        db      010H ;...#....

        db      000H ;........ enemy bullet
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      010H ;...#....
        db      038H ;..###...
        db      010H ;...#....

        db      005H ;.....#.#
        db      007H ;.....###
        db      004H ;.....#..
        db      01CH ;...###..
        db      014H ;...#.#..
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........ enemy bullet
        db      00AH ;....#.#.
        db      004H ;.....#..
        db      00AH ;....#.#.
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      018H ;...##...
        db      050H ;.#.#....
        db      070H ;.###....
        db      050H ;.#.#....
        db      000H ;........

        db      000H ;........ enemy bullet
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      040H ;.#......
        db      0E0H ;###.....
        db      040H ;.#......

        db      000H ;........ bullet at left
        db      000H ;........
        db      0A8H ;#.#.#...
        db      0F8H ;#####...
        db      050H ;.#.#....
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      000H ;........
        db      040H ;.#......
        db      0E0H ;###.....
        db      040H ;.#......
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........ bullet at right
        db      000H ;........
        db      00AH ;....#.#.
        db      01FH ;...#####
        db      015H ;...#.#.#
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      000H ;........
        db      00AH ;....#.#.
        db      004H ;.....#..
        db      00AH ;....#.#.
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      0C0H ;##......
        db      050H ;.#.#....
        db      070H ;.###....
        db      050H ;.#.#....
        db      018H ;...##...
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      040H ;.#......
        db      0E0H ;###.....
        db      040H ;.#......
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      014H ;...#.#..
        db      01CH ;...###..
        db      004H ;.....#..
        db      007H ;.....###
        db      005H ;.....#.#

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      00AH ;....#.#.
        db      004H ;.....#..
        db      00AH ;....#.#.
        db      000H ;........

        db      010H ;...#....
        db      018H ;...##...
        db      030H ;..##....
        db      018H ;...##...
        db      030H ;..##....
        db      010H ;...#....
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      028H ;..#.#...
        db      010H ;...#....
        db      028H ;..#.#...
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      000H ;........
        db      010H ;...#....
        db      030H ;..##....
        db      018H ;...##...
        db      030H ;..##....
        db      018H ;...##...
        db      010H ;...#....

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      010H ;...#....
        db      038H ;..###...
        db      010H ;...#....

        db      003H ;......##
        db      00AH ;....#.#.
        db      00EH ;....###.
        db      00AH ;....#.#.
        db      018H ;...##...
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      00AH ;....#.#.
        db      004H ;.....#..
        db      00AH ;....#.#.
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      028H ;..#.#...
        db      038H ;..###...
        db      020H ;..#.....
        db      0E0H ;###.....
        db      0A0H ;#.#.....

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      040H ;.#......
        db      0E0H ;###.....
        db      040H ;.#......

        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      0A8H ;#.#.#...
        db      0F8H ;#####...
        db      050H ;.#.#....
        db      000H ;........
        db      000H ;........

        db      000H ;........ duplicate
        db      000H ;........
        db      040H ;.#......
        db      0E0H ;###.....
        db      040H ;.#......
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........ duplicate
        db      000H ;........
        db      000H ;........
        db      00AH ;....#.#.
        db      01FH ;...#####
        db      015H ;...#.#.#
        db      000H ;........
        db      000H ;........

        db      000H ;........ duplicate
        db      000H ;........
        db      00AH ;....#.#.
        db      004H ;.....#..
        db      00AH ;....#.#.
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      0C0H ;##...... duplicate
        db      050H ;.#.#....
        db      070H ;.###....
        db      050H ;.#.#....
        db      018H ;...##...
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      040H ;.#...... duplicate
        db      0E0H ;###.....
        db      040H ;.#......
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

        db      000H ;........ duplicate
        db      000H ;........
        db      000H ;........
        db      014H ;...#.#..
        db      01CH ;...###..
        db      004H ;.....#..
        db      007H ;.....###
        db      005H ;.....#.#

        db      000H ;........ duplicate
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      00AH ;....#.#.
        db      004H ;.....#..
        db      00AH ;....#.#.
        db      000H ;........

;$2E0B:
        db      091H ;#..#...# short explosion
        db      024H ;..#..#..
        db      058H ;.#.##...
        db      0BBH ;#.###.##
        db      038H ;..###...
        db      014H ;...#.#..
        db      042H ;.#....#.
        db      091H ;#..#...#

;$2E13:
        db      000H ;........ blank #2
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

;$2E1B:
;#....#..#.#....# wide explosion
;..#.#.####.#.#..
;...########.#...
;#.#...####.#...#
;....#..##..#.#..
;...#..##.##.#...
;..#.#..##..#.#..
;#.....#..#.....#

        db      084H ;#....#.. left side of wide explosion
        db      02BH ;..#.#.##
        db      01FH ;...#####
        db      0A3H ;#.#...##
        db      009H ;....#..#
        db      013H ;...#..##
        db      029H ;..#.#..#
        db      082H ;#.....#.

        db      0A1H ;#.#....# right side of wide explosion
        db      0D4H ;##.#.#..
        db      0E8H ;###.#...
        db      0D1H ;##.#...#
        db      094H ;#..#.#..
        db      068H ;.##.#...
        db      094H ;#..#.#..
        db      041H ;.#.....#

;$2E2B:
        db      000H ;........ blank #1
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

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

;$2E3B:
        db      000H ;........ tall explosion (top half)
        db      024H ;..#..#..
        db      081H ;#......#
        db      028H ;..#.#...
        db      04AH ;.#..#.#.
        db      01CH ;...###..
        db      038H ;..###...
        db      0BFH ;#.######
        db      01CH ;...###.. tall explosion (bottom half)
        db      018H ;...##...
        db      0BDH ;#.####.#
        db      02CH ;..#.##..
        db      02AH ;..#.#.#.
        db      008H ;....#...
        db      081H ;#......#
        db      024H ;..#..#..

;$2E4B:
        db      000H ;........ blank #3
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

;$2E53:
        db      000H ;........ blank #4
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

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

;$2E63:
        db      000H ;........ blank #5
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........
        db      000H ;........

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

;$2E73:
;sound effect #1 (player firing)
        db      09FH
        db      010H, 002H
        db      008H, 002H
        db      004H, 002H
        db      000H, 001H
        db      0FFH, 0FFH
;$2E7E:
;sound effect #2 (alien killed)
        db      097H, 030H
        db      002H, 096H
        db      030H, 002H
        db      094H, 030H
        db      002H, 092H
        db      030H, 002H
        db      000H, 001H
        db      0FFH, 0FFH
;$2E8E:
;sound effect #3 (player killed)
        db      097H, 008H
        db      010H, 092H
        db      010H, 002H
        db      097H, 020H
        db      002H, 092H
        db      030H, 002H
        db      096H, 030H
        db      002H, 091H
        db      030H, 002H
        db      096H, 030H
        db      002H, 091H
        db      030H, 002H
        db      094H, 030H
        db      002H, 091H
        db      030H, 002H
        db      094H, 030H
        db      002H, 091H
        db      030H, 002H
        db      093H, 030H
        db      002H, 091H
        db      030H, 002H
        db      093H, 030H
        db      002H, 091H
        db      030H, 002H
        db      092H, 030H
        db      002H, 091H
        db      030H, 002H
        db      000H, 001H
        db      0FFH, 0FFH
;$2EC8:
;MUSICDATA:
;musical notes
;higher notes use lower values
; low D#: $32
;     E : $2F
;     F#: $2A
;     G#: $25
;     A#: $21
;     B : $1F
;     C#: $1C
;high D#: $19

        db      08FH
        db      032H, 004H, 000H, 001H ;low D#
        db      02AH, 004H, 000H, 001H ;F#
        db      01FH, 004H, 000H, 001H ;B
        db      01FH, 008H, 000H, 001H ;B
        db      01FH, 00CH, 000H, 001H ;B
        db      032H, 004H, 000H, 001H ;low D#
        db      02AH, 004H, 000H, 001H ;F#
        db      01FH, 004H, 000H, 001H ;B
        db      01FH, 008H, 000H, 001H ;B
        db      01FH, 00CH, 000H, 001H ;B
        db      02FH, 004H, 000H, 001H ;E
        db      025H, 004H, 000H, 001H ;G#
        db      01FH, 004H, 000H, 001H ;B
        db      01FH, 008H, 000H, 001H ;B
        db      01FH, 00CH, 000H, 001H ;B
        db      021H, 004H, 000H, 001H ;A#
        db      025H, 004H, 000H, 001H ;G#
        db      021H, 004H, 000H, 001H ;A#
        db      021H, 004H, 000H, 001H ;A#
        db      021H, 010H, 000H, 001H ;A#
        db      02AH, 004H, 000H, 001H ;F#
        db      02AH, 004H, 000H, 001H ;F#
        db      019H, 004H, 000H, 001H ;high D#
        db      019H, 004H, 000H, 001H ;high D#
        db      019H, 010H, 000H, 001H ;high D#
        db      01CH, 004H, 000H, 001H ;C#
        db      01FH, 004H, 000H, 001H ;B
        db      021H, 004H, 000H, 001H ;A#
        db      021H, 004H, 000H, 001H ;A#
        db      021H, 010H, 000H, 001H ;A#
        db      021H, 004H, 000H, 001H ;A#
        db      021H, 004H, 000H, 001H ;A#
        db      025H, 004H, 000H, 001H ;G#
        db      025H, 004H, 000H, 001H ;G#
        db      025H, 010H, 000H, 001H ;G#
        db      01FH, 004H, 000H, 001H ;B
        db      025H, 004H, 000H, 001H ;G#
        db      025H, 00CH, 000H, 001H ;G#
        db      02AH, 00CH, 000H, 001H ;F#
        db      02AH, 004H, 000H, 001H ;F#
        db      02AH, 004H, 000H, 001H ;F#
        db      025H, 010H, 000H, 001H ;G#
        db      025H, 004H, 000H, 001H ;G#
        db      01FH, 008H, 000H, 001H ;B
        db      025H, 004H, 000H, 001H ;G#
        db      019H, 008H, 000H, 001H ;high D#
        db      000H, 008H, 000H, 001H ;rest
        db      01CH, 004H, 000H, 001H ;C#
        db      01FH, 008H, 000H, 001H ;B
        db      021H, 004H, 000H, 001H ;A#
        db      01FH, 018H, 000H, 001H ;B
        db      000H, 001H, 0FFH, 0FFH ;end
;end of MUSICDATA

;unknown
        db      004H, 007H, 006H, 01BH
        db      012H, 004H, 008H, 005H
        db      00AH, 006H
	db	004H, 007H, 006H, 01BH
	db	008H, 004H, 004H, 005H
	db	006H, 006H, 008H, 007H
	db	00AH, 0CCH, 018H, 0D0H
	db	0CDH, 018H, 0D1H, 0CEH
	db	018H, 0D2H, 0CFH, 018H
	db	0D3H, 03FH, 00EH, 0F4H
	db	09CH, 00CH, 004H, 00CH
	db	018H, 0EDH, 044H, 070H
        db      0E4H, 020H, 09CH, 00BH
	db	0A8H, 005H, 001H, 00DH
	db	0F8H, 0D6H, 0C3H, 00CH
	db	018H, 0D0H, 083H, 0C3H
	db	00CH, 018H, 0EEH, 084H
	db	004H, 0A3H, 018H, 004H
	db	019H
;Code Section-------------------------------------------------------------
;LEVEL1FLYBY_1:
;$2FE0:
        bsta,un WAITVBL      ;gosub WAITVBL;                            ;3
        bsta,un 20cch        ;gosub DRAWSWARM;                          ;3
        bcta,un LEVEL1FLYBY_2;goto LEVEL1FLYBY_2;                       ;3
;Data---------------------------------------------------------------------
;$2FE9:
        db      0A8h, 005h, 002h, 00Dh, 0F8h, 0D6h, 0C3h
;Code Section-------------------------------------------------------------
;$2FF0:
;VBLROUTINE_3:

;we are in flyby, and could be on either level

        lodi,r1 0d0h         ;r1 = $D0; // loop iterator
;wait
;$2FF2:
        bdrr,r1 1ff2h        ;if (--r1 != 0) goto $2FF2;
;end of loop

        bsta,un 2069h        ;gosub MOVESHIP;
        bcta,un VBLROUTINE_4 ;goto VBLROUTINE_4;
;Junk---------------------------------------------------------------------
;$2FFA:
;IMPATIENTROUTINE:

;PATIENT:
        db      0A3H, 018H, 004H, 019H, 002H, 024H                      ;6
;IMPATIENT:
;       bsta,un SETUDCS                                                 ;3
;       bcta,un CONSOLELOOP_4                                           ;3

        end

Sprite #0: top of player
Sprite #1: bottom of player
Sprite #2: 1st alien
Sprite #3: 2nd alien
UDC #0: swarm alien
UDC #1: inverted triangle
UDC #2: unknown
UDC #3: bullet

List of Subroutines and Code Sections, ordered by address

BOOT
CONSOLELOOP
NEWGAME
LEVEL1INIT
LEVEL1FLYBY
LEVEL1LOOP
LEVEL2FLYBY
LEVEL2LOOP
L02DD
SETBG
SETFLAGS
L0346
L0365
L036E
READPADDLE
L042A
L04C7
L0525
L056C
SETVARS
FIREBUTTON
L0676
MOVEBULLET
REALMOVEBULLET
L07E7
L0879
SHOOT
SETUDCS
SETHARDWARE
TITLESCREEN
CREDITS
DOHISCORE
DOSCORE
DRAWLINE
DRAWBUILDINGS
HISCORE
SCROLLDOWN
SCROLLUP
VBLROUTINE
FLIPFRAME
COLLDETECT
PLAYMUSIC
INIT
WAITVBL
SETXPOS
DRAWTOP
DRAWBOTTOM
L0D27
DELAY
LOADR0
STORER0
L0DAB
L0DAF
L0DDD
UPDATESCORE
DRAWSTARS
GAMEOVER
SETROMPOINTER2
SETPOINTER
TEST10/20/30
L0F03
CHANGEUDC
ALIEN1CTRL
ALIEN2CTRL
CHANGESOUND
FLYBYSETUP ($2000)
$2016
$2042
MOVESHIP ($2069)
DRAWSWARM ($20CC)
$212A
ALIENDIRECTION ($219E)
$21F9
MOVEALIEN1 ($2220)
MOVEALIEN2 ($2244)
$2268
$22E0
$22E6
$234F
$23A9
$2408
$240E
$2459
$249C
SETLEVEL2VARS ($24F9)
$2520
$25AA
$25D4
$26CF
$2748
$274E
$27CB
$2828
CHECKXMOVE ($2885)
CHECKYMOVE ($28B3)
$28E9
CLEARSCREEN1 ($2913)
CLEARSCREEN2 ($2922)

player's head: sprite #0
player's legs: sprite #1
1st alien:     sprite #2
2nd alien:     sprite #3
