********************************************************************************
* Space Eggs for the Apple II, by Nasir Gebelli *
* Copyright 1981 Sirius Software *
********************************************************************************
* This is the 30.5KB cracked version found in various game collections. *
********************************************************************************
* Disassembly by Andy McFadden, using 6502bench SourceGen v1.5. *
* Last updated 2020/02/16 *
********************************************************************************
BCC_inst .eq $90 {const}
BCS_inst .eq $b0 {const}
button_was_down .eq $1f ;bool (00/ff): is button being held?
alien0 .eq $20 {addr/16} ;alien #0 state ($20-29)
alien1 .eq $30 {addr/16} ;alien #1 state
alien2 .eq $40 {addr/16} ;(state is copied to $c0 during updates;
alien3 .eq $50 {addr/16} ; see $c0-c9 for details)
alien4 .eq $60 {addr/16}
alien5 .eq $70 {addr/16}
alien6 .eq $80 {addr/16}
did_multi_ship .eq $90 ;$00 if we haven't, $ff if we have
cur_score_hi .eq $b0 ;current score, high two BCD digits
cur_score_lo .eq $b1 ;current score, low two BCD digits
high_score_hi .eq $b2 ;high score, high two BCD digits
high_score_lo .eq $b3 ;high score, low two BCD digits
chirp_counter .eq $bb ;chirp every N frames
wave_num .eq $bf ;which wave we're on; resets to 1 on death
alien_state .eq $c0 ;0-15 (arriving, egg, alien, exploding)
alien_type_index .eq $c1 ;index into score table (1-4)
alien_row .eq $c2 ;vertical position (top row)
alien_col .eq $c3 ;horizontal position (left col byte)
alien_prev_row .eq $c4 ;previous row, used for next erase
alien_prev_col .eq $c5 ;previous col, used for next erase
alien_shift_flag .eq $c6 ;bool (00/ff): determines color shift
alien_move_direction .eq $c7 ;movement direction (0-7)
alien_dir_move_count .eq $c8 ;number of times to move before changing dir
alien_move_flag .eq $c9 ;bool (00/ff): true if moving down
collision_flag .eq $cd ;bool (00/ff): 0=collided
egg_arrival_counter .eq $ce ;counts frames btwn egg arrival anim
bullet1_fired .eq $d0 ;0 if ready to fire, 1 if fired
bullet1_row .eq $d1 ;bullet vertical position
bullet1_col .eq $d2 ;bullet coarse horizontal position
bullet1_img_00 .eq $d3 ;bitmap data, row 0, byte 0
bullet1_img_01 .eq $d4 ;bitmap data, row 0, byte 1
bullet1_img_02 .eq $d5
bullet1_img_10 .eq $d6 ;bitmap data, row 1, byte 0
bullet1_img_11 .eq $d7
bullet1_img_12 .eq $d8
bullet2_state .eq $d9 {addr/9} ;$d9-e1
bullet2_fired .eq $d9
bullet2_row .eq $da
bullet3_state .eq $e2 {addr/9} ;$e2-ea
bullet3_row .eq $e3
explosion_counter .eq $f2 ;counts frames between ship expl steps
post_death_frame_count .eq $f3 ;used for post-death animation
ship_left_byte_pos .eq $f4 ;byte offset of left edge of ship
ship_life .eq $f6 ;which life we're on (1-3)
exhaust_anim_counter .eq $f7 ;counts frames between exhaust anim updates
ship_stage .eq $f8 ;1-3=single stage, 4=1+2, 5+=exploding
ship_pos_coarse .eq $f9 ;hi-res column, 1-37, always odd
ship_pos_fine .eq $fa ;ship position, fine (0-6)
ship_position_abs .eq $fb ;absolute ship position (0-104), for PDL cmp
exhaust_seq .eq $fc ;Exhaust animation sequence (0-2)
ship_top_row .eq $fd ;row at which we draw the player ship
ship_exhaust_row .eq $fe ;row at which we draw the exhaust plume
star_field_adj .eq $ff ;creates shifting star pattern
INPUT_BUFFER .eq $0200 {addr/256}
CP_SET_BY_INIT .eq $0400 {addr/4}
CP_SET_TO_ONE .eq $37f4
blank_screen_image .eq $a000 {addr/8192} ;data source for blank screen transition
SPKR .eq $c030 ;RW toggle speaker
TXTCLR .eq $c050 ;RW display graphics
MIXCLR .eq $c052 ;RW display full screen
TXTPAGE1 .eq $c054 ;RW display page 1
HIRES .eq $c057 ;RW display hi-res graphics
BUTN0 .eq $c061 ;R switch input 0 / open-apple
PADDL0 .eq $c064 ;R analog input 0
PTRIG .eq $c070 ;RW analog input reset
MON_WAIT .eq $fca8 ;delay for (26 + 27*Acc + 5*(Acc*Acc))/2 cycles
MON_MOVE .eq $fe2c ;move bytes from A1 to A4 until A1=A2
.org $15fd
15fd: 4c 00 4f ENTRY jmp Start
.org $0800
;
; Hi-res row base address table.
;
0800: 20 24 28 2c+ hr_ytable_hi .bulk 2024282c3034383c2024282c3034383c2125292d3135393d2125292d3135393d
+ 22262a2e32363a3e22262a2e32363a3e23272b2f33373b3f23272b2f33373b3f
+ 2024282c3034383c2024282c3034383c2125292d3135393d2125292d3135393d
+ 22262a2e32363a3e22262a2e32363a3e23272b2f33373b3f23272b2f33373b3f
+ 2024282c3034383c2024282c3034383c2125292d3135393d2125292d3135393d
+ 22262a2e32363a3e22262a2e32363a3e23272b2f33373b3f23272b2f33373b3f
08c0: 00 00 00 00+ hr_ytable_lo .bulk 0000000000000000808080808080808000000000000000008080808080808080
+ 0000000000000000808080808080808000000000000000008080808080808080
+ 2828282828282828a8a8a8a8a8a8a8a82828282828282828a8a8a8a8a8a8a8a8
+ 2828282828282828a8a8a8a8a8a8a8a82828282828282828a8a8a8a8a8a8a8a8
+ 5050505050505050d0d0d0d0d0d0d0d05050505050505050d0d0d0d0d0d0d0d0
+ 5050505050505050d0d0d0d0d0d0d0d05050505050505050d0d0d0d0d0d0d0d0
;
; Horizontal position (hi-res column) for 64 stars [0,36].
;
0980: 22 0e 03 1d+ star_field_col .bulk 220e031d06091909020a1710220a1721230d0f1414042004211e1d051a17240e
+ 0616260c181f0710030c0d041d061f1d0c20060705000b160226041e2404261c
;
; Vertical position for 64 stars [9,191].
;
09c0: 32 52 53 36+ star_field_row .bulk 32525336198f956a950f195372b64eb695b012b66aab673274b6b4b674ae8f53
+ a80c9595103ab67032b648956ea653b653a848b695509574b6b590537432b634
;
; Visibility counters for 64 stars. Reset to 32, visible for 31-16, hidden for
; 15-0.
;
star_field_counter
0a00: 01 11 03 14+ .bulk 011103140616071a0b1a0e0112011504061617071a1b1d0c0d10120102181605
+ 1e1d0307190f071405081b0f16200909101e1b0e0f130c0b0b11150c0b0b0a16
;
; Hi-res color byte for 64 stars.
;
0a40: 01 82 02 81+ star_color .bulk 0182028103020181818281020301818203810282828182010102818202018281
+ 0282810104010203018281018102830181828102030181820381028282818201
;
; Address of seven pre-shifted images of stage 1 (smallest) player ship. 6x9
; (54 bytes, padded to 64).
;
; Each successive image is shifted 2 pixels to the right, to avoid having the
; colors shimmer when the ship is moved. Ships are an even number of bytes, and
; are always drawn starting from an odd column, so the initial center position
; is in the center of the screen.
;
ship1_s7_index_lo
0a80: 00 .dd1 <T6000
0a81: 40 .dd1 <T6040
0a82: 80 .dd1 <T6080
0a83: c0 .dd1 <T60C0
0a84: 00 .dd1 <T6100
0a85: 40 .dd1 <T6140
0a86: 80 .dd1 <T6180
0a87: 00 .junk 1
ship1_s7_index_hi
0a88: 60 .dd1 >T6000
0a89: 60 .dd1 >T6040
0a8a: 60 .dd1 >T6080
0a8b: 60 .dd1 >T60C0
0a8c: 61 .dd1 >T6100
0a8d: 61 .dd1 >T6140
0a8e: 61 .dd1 >T6180
0a8f: 61 .junk 1
;
; Seven pre-shifted images of the stage 2 player ship. 8x12 (96 bytes).
;
ship2_s7_index_lo
0a90: c0 .dd1 <T61C0
0a91: 20 .dd1 <T6220
0a92: 80 .dd1 <T6280
0a93: e0 .dd1 <T62E0
0a94: 40 .dd1 <T6340
0a95: a0 .dd1 <T63A0
0a96: 00 .dd1 <T6400
0a97: 00 .junk 1
ship2_s7_index_hi
0a98: 61 .dd1 >T61C0
0a99: 62 .dd1 >T6220
0a9a: 62 .dd1 >T6280
0a9b: 62 .dd1 >T62E0
0a9c: 63 .dd1 >T6340
0a9d: 63 .dd1 >T63A0
0a9e: 64 .dd1 >T6400
0a9f: 00 .junk 1
;
; Seven pre-shifted images of the stage 3 player ship. 10x12 (120 bytes, padded
; to 128).
;
ship3_s7_index_lo
0aa0: 60 .dd1 <T6460
0aa1: e0 .dd1 <T64E0
0aa2: 60 .dd1 <T6560
0aa3: e0 .dd1 <T65E0
0aa4: 60 .dd1 <T6660
0aa5: e0 .dd1 <T66E0
0aa6: 60 .dd1 <T6760
0aa7: 00 .junk 1
ship3_s7_index_hi
0aa8: 64 .dd1 >T6460
0aa9: 64 .dd1 >T64E0
0aaa: 65 .dd1 >T6560
0aab: 65 .dd1 >T65E0
0aac: 66 .dd1 >T6660
0aad: 66 .dd1 >T66E0
0aae: 67 .dd1 >T6760
0aaf: 00 .junk 1
;
; Ship exhaust animation. Three images, each of which has seven pre-shifted
; copies. Depending on the value of $FC, the code grabs an index from $0ab0,
; $0ac0, or $0ad0.
;
; Each image is 5x21 (112/$70 bytes).
;
exhaust0_s7_index_lo
0ab0: 05 .dd1 <T6805
0ab1: 75 .dd1 <T6875
0ab2: e5 .dd1 <T68E5
0ab3: 55 .dd1 <T6955
0ab4: c5 .dd1 <T69C5
0ab5: 35 .dd1 <T6A35
0ab6: a5 .dd1 <T6AA5
0ab7: 00 .junk 1
exhaust0_s7_index_hi
0ab8: 68 .dd1 >T6805
0ab9: 68 .dd1 >T6875
0aba: 68 .dd1 >T68E5
0abb: 69 .dd1 >T6955
0abc: 69 .dd1 >T69C5
0abd: 6a .dd1 >T6A35
0abe: 6a .dd1 >T6AA5
0abf: 00 .junk 1
exhaust1_s7_index_lo
0ac0: 10 .dd1 <T6B10
0ac1: 80 .dd1 <T6B80
0ac2: f0 .dd1 <T6BF0
0ac3: 60 .dd1 <T6C60
0ac4: d0 .dd1 <T6CD0
0ac5: 40 .dd1 <T6D40
0ac6: b0 .dd1 <T6DB0
0ac7: 00 .junk 1
exhaust1_s7_index_hi
0ac8: 6b .dd1 >T6B10
0ac9: 6b .dd1 >T6B80
0aca: 6b .dd1 >T6BF0
0acb: 6c .dd1 >T6C60
0acc: 6c .dd1 >T6CD0
0acd: 6d .dd1 >T6D40
0ace: 6d .dd1 >T6DB0
0acf: 00 .junk 1
exhaust2_s7_index_lo
0ad0: 20 .dd1 <T6E20
0ad1: 90 .dd1 <T6E90
0ad2: 00 .dd1 <T6F00
0ad3: 70 .dd1 <T6F70
0ad4: e0 .dd1 <T6FE0
0ad5: 50 .dd1 <T7050
0ad6: c0 .dd1 <T70C0
0ad7: 00 .junk 1
exhaust2_s7_index_hi
0ad8: 6e .dd1 >T6E20
0ad9: 6e .dd1 >T6E90
0ada: 6f .dd1 >T6F00
0adb: 6f .dd1 >T6F70
0adc: 6f .dd1 >T6FE0
0add: 70 .dd1 >T7050
0ade: 70 .dd1 >T70C0
0adf: 00 .junk 1
;
; Clears the hi-res framebuffer to black.
;
• Clear variables
]ptr .var $00 {addr/2}
0ae0: a9 00 ClearHiRes lda #<HIRES_PAGE_1 ;start at $2000
0ae2: 85 00 sta ]ptr
0ae4: a9 20 lda #>HIRES_PAGE_1
0ae6: 85 01 sta ]ptr+1
0ae8: a0 00 ldy #$00
0aea: a9 00 :Loop2 lda #$00
0aec: 91 00 :Loop1 sta (]ptr),y
0aee: c8 iny
0aef: d0 fb bne :Loop1
0af1: e6 01 inc ]ptr+1
0af3: a5 01 lda ]ptr+1
0af5: 29 1f and #$1f ;reached $40?
0af7: d0 f1 bne :Loop2
0af9: 60 rts
0afa: 00 00 00 00+ .junk 6
;
; Updates the animated star field.
;
; There are 64 stars that move from the top of the screen to the bottom, one
; line at a time. To make things a bit more interesting, a counter is used to
; turn them on and off, so they're visible for 15 lines and invisible for 16.
;
; When the star reaches the bottom, it moves back to the top, but starts in a
; different column. The initial row and counter values are staggered. The net
; effect is a very dynamic-looking star field.
;
; The color of each star is fixed.
;
0b00: a2 00 UpdateStarField ldx #$00 ;star index in X-reg
0b02: de 00 0a :UpdateLoop dec star_field_counter,x ;decrement the counter
0b05: 10 18 bpl :NotReset ;still >= 0, branch
0b07: a9 20 lda #32 ;reset to 32
0b09: 9d 00 0a sta star_field_counter,x
0b0c: bd c0 09 lda star_field_row,x ;move it down 16 rows
0b0f: 18 clc
0b10: 69 10 adc #16
0b12: c9 c0 cmp #192 ;hit bottom?
0b14: 90 06 bcc :NotBottom ;not yet
0b16: 20 90 0b jsr MoveRestartStar ;yes, move the star to the top, in a different column
0b19: 4c 82 0b jmp :LoopBottom ;move on to next star
0b1c: 9d c0 09 :NotBottom sta star_field_row,x
0b1f: bd 00 0a :NotReset lda star_field_counter,x
0b22: c9 0f cmp #15 ;hit the halfway point (iteration 15)?
0b24: d0 1c bne :DrawMaybe ;nope
0b26: bd c0 09 lda star_field_row,x ;yes, erase it
0b29: a8 tay
0b2a: b9 00 08 lda hr_ytable_hi,y
0b2d: 8d 3e 0b sta :_ClearByte+2
0b30: b9 c0 08 lda hr_ytable_lo,y
0b33: 8d 3d 0b sta :_ClearByte+1
0b36: bd 80 09 lda star_field_col,x
0b39: a8 tay
0b3a: a9 00 lda #$00
0b3c: 99 50 35 :_ClearByte sta HIRES_PAGE_1+$1550,y
0b3f: 4c 82 0b jmp :LoopBottom
0b42: c9 10 :DrawMaybe cmp #16 ;is counter in range 0-15?
0b44: 90 3c bcc :LoopBottom ;yes, don't draw
0b46: bd c0 09 lda star_field_row,x ;no, move it down one row
0b49: 18 clc
0b4a: 69 01 adc #$01
0b4c: c9 c0 cmp #192 ;bottom?
0b4e: 90 06 bcc :DrawStar ;no
0b50: 20 90 0b jsr MoveRestartStar ;yes, recreate it elsewhere
0b53: 4c 82 0b jmp :LoopBottom
0b56: 9d c0 09 :DrawStar sta star_field_row,x ;counter is 16-31, draw it
0b59: a8 tay
0b5a: b9 00 08 lda hr_ytable_hi,y
0b5d: 8d 81 0b sta :_DrawStarStore+2
0b60: b9 c0 08 lda hr_ytable_lo,y
0b63: 8d 80 0b sta :_DrawStarStore+1
0b66: 88 dey ;back up one row for erase
0b67: b9 00 08 lda hr_ytable_hi,y
0b6a: 8d 7b 0b sta :_EraseStarStore+2
0b6d: b9 c0 08 lda hr_ytable_lo,y
0b70: 8d 7a 0b sta :_EraseStarStore+1
0b73: bd 80 09 lda star_field_col,x
0b76: a8 tay
0b77: a9 00 lda #$00
:_EraseStarStore
0b79: 99 00 2f sta HIRES_PAGE_1+$f00,y ;erase old
0b7c: bd 40 0a lda star_color,x ;get star color
0b7f: 99 00 33 :_DrawStarStore sta HIRES_PAGE_1+$1300,y ;draw new
0b82: e8 :LoopBottom inx
0b83: e0 40 cpx #64 ;done with stars?
0b85: b0 03 bcs :done ;yes, bail
0b87: 4c 02 0b jmp :UpdateLoop
0b8a: 60 :done rts
0b8b: 00 00 00 00+ .junk 5
; Call this when a star reaches the bottom of the screen. The row is reset to
; the top, and the column is changed to the next position.
;
; On entry: star index in X-reg
0b90: bd c0 09 MoveRestartStar lda star_field_row,x ;set up to erase the star
0b93: a8 tay
0b94: b9 00 08 lda hr_ytable_hi,y
0b97: 8d a8 0b sta :_EraseStarStore+2
0b9a: b9 c0 08 lda hr_ytable_lo,y
0b9d: 8d a7 0b sta :_EraseStarStore+1
0ba0: bd 80 09 lda star_field_col,x
0ba3: a8 tay
0ba4: a9 00 lda #$00 ;clear to black
:_EraseStarStore
0ba6: 99 50 3b sta $3b50,y
0ba9: a9 09 lda #9 ;set row to 9 (below scores)
0bab: 9d c0 09 sta star_field_row,x ;near top of screen, below score
0bae: e6 ff inc star_field_adj ;advance the start field adjust pointer
0bb0: a4 ff ldy star_field_adj
0bb2: b9 00 1f lda star_field_start_col,y ;use it to get the next start column
0bb5: 9d 80 09 sta star_field_col,x ;set that in the column index
0bb8: 60 rts
0bb9: 00 00 00 00+ .junk 7
;
; Draws a bitmap. Used for aliens, player ships, etc.
;
; On entry:
; $04/05 - start/end row
; $06/07 - start/end col
;
; Ends are exclusive, so size is equal to (end - start).
;
• Clear variables
]start_row .var $04 {addr/1}
]end_row .var $05 {addr/1}
]start_col .var $06 {addr/1}
]end_col .var $07 {addr/1}
]bitmap_top_row .var $0a {addr/1}
]bitmap_top_adj .var $0b {addr/1}
0bc0: a6 04 DrawBitmap ldx ]start_row ;get the top row
0bc2: bd 00 08 :Loop lda hr_ytable_hi,x
0bc5: 8d d5 0b sta :_DrawBitmapDst+2 ;configure destination row addr
0bc8: bd c0 08 lda hr_ytable_lo,x
0bcb: 8d d4 0b sta :_DrawBitmapDst+1
0bce: a4 06 ldy ]start_col
0bd0: ad 20 62 _DrawBitmapSrc lda T6220
0bd3: 99 d0 2a :_DrawBitmapDst sta HIRES_PAGE_1+$ad0,y
0bd6: ee d1 0b inc _DrawBitmapSrc+1
0bd9: d0 03 bne :NoInc
0bdb: ee d2 0b inc _DrawBitmapSrc+2
0bde: c8 :NoInc iny
0bdf: c4 07 cpy ]end_col
0be1: 90 ed bcc _DrawBitmapSrc
0be3: e8 inx
0be4: e4 05 cpx ]end_row
0be6: 90 da bcc :Loop
0be8: 60 rts
0be9: ea 00 00 00+ .junk 7
0bf0: a6 fa DrawShipStage1 ldx ship_pos_fine
0bf2: bd 80 0a lda ship1_s7_index_lo,x
0bf5: 8d d1 0b sta _DrawBitmapSrc+1
0bf8: bd 88 0a lda ship1_s7_index_hi,x
0bfb: 8d d2 0b sta _DrawBitmapSrc+2
0bfe: a5 f9 lda ship_pos_coarse
0c00: 38 sec
0c01: e9 02 sbc #$02
0c03: 85 06 sta ]start_col
0c05: 18 clc
0c06: 69 06 adc #6 ;bitmap width
0c08: 85 07 sta ]end_col
0c0a: a5 fd lda ship_top_row
0c0c: 85 04 sta ]start_row
0c0e: 18 clc
0c0f: 69 09 adc #9 ;bitmap height
0c11: 85 05 sta ]end_row
0c13: 4c c0 0b jmp DrawBitmap
0c16: 00 00 00 00+ .junk 16
0c26: 20 c4 0c DrawShipExhaust jsr UpdateExhaustCounter
0c29: a5 fc lda exhaust_seq
0c2b: 0a asl A
0c2c: 0a asl A
0c2d: 0a asl A
0c2e: 0a asl A
0c2f: 18 clc
0c30: 69 b0 adc #$b0
0c32: 8d 3e 0c sta L0C3D+1
0c35: 18 clc
0c36: 69 08 adc #$08
0c38: 8d 44 0c sta L0C43+1
0c3b: a6 fa ldx ship_pos_fine
0c3d: bd b0 0a L0C3D lda exhaust0_s7_index_lo,x
0c40: 8d d1 0b sta _DrawBitmapSrc+1
0c43: bd b8 0a L0C43 lda exhaust0_s7_index_hi,x
0c46: 8d d2 0b sta _DrawBitmapSrc+2
0c49: a5 f9 lda ship_pos_coarse
0c4b: 38 sec
0c4c: e9 02 sbc #$02 ;center on ship
0c4e: 85 06 sta ]start_col
0c50: 18 clc
0c51: 69 05 adc #$05
0c53: 85 07 sta ]end_col
0c55: a5 fe lda ship_exhaust_row
0c57: 85 04 sta ]start_row
0c59: 18 clc
0c5a: 69 15 adc #$15
0c5c: 85 05 sta ]end_row
0c5e: 4c c0 0b jmp DrawBitmap
0c61: 00 00 00 00+ .junk 15
0c70: e6 fa MoveShipRight inc ship_pos_fine ;update fine position (2 pixels)
0c72: a5 fa lda ship_pos_fine
0c74: c9 07 cmp #$07 ;reached end of byte pair?
0c76: 90 08 bcc L0C80 ;not yet
0c78: a9 00 lda #$00 ;moved into next byte pair
0c7a: 85 fa sta ship_pos_fine
0c7c: e6 f9 inc ship_pos_coarse
0c7e: e6 f9 inc ship_pos_coarse
0c80: e6 fb L0C80 inc ship_position_abs
0c82: 60 rts
0c83: ea .dd1 $ea
0c84: ea .dd1 $ea
0c85: ea .dd1 $ea
0c86: c6 fa MoveShipLeft dec ship_pos_fine ;update fine position (2 pixels)
0c88: 10 08 bpl L0C92 ;not at end yet, branch
0c8a: a9 06 lda #$06 ;moved into prev byte pair, reset
0c8c: 85 fa sta ship_pos_fine
0c8e: c6 f9 dec ship_pos_coarse
0c90: c6 f9 dec ship_pos_coarse
0c92: c6 fb L0C92 dec ship_position_abs
0c94: 60 rts
0c95: 00 00 00 00+ .junk 11
; Standard analog paddle read. The value returned is in the range [0,104], less
; than half the full range of the game paddle.
;
; This makes the ship docking maneuver slightly harder to control with a
; joystick, but has the advantage of reducing the total time spent reading the
; paddle.
0ca0: ad 70 c0 ReadPaddle lda PTRIG ;trigger paddle timers
0ca3: a0 00 ldy #$00
0ca5: ea nop
0ca6: ea nop
0ca7: ad 64 c0 :PdlLoop lda PADDL0 ;are we there yet?
0caa: 10 05 bpl :PdlDone ;yes
0cac: c8 iny
0cad: c0 68 cpy #104 ;clamp value
0caf: 90 f6 bcc :PdlLoop
0cb1: c4 fb :PdlDone cpy ship_position_abs ;does PDL read match current position?
0cb3: d0 01 bne :Move ;no, move ship
0cb5: 60 rts
0cb6: 90 03 :Move bcc :MoveLeft
0cb8: 4c 70 0c jmp MoveShipRight
0cbb: 4c 86 0c :MoveLeft jmp MoveShipLeft
0cbe: 00 00 00 00+ .junk 6
; Every 16 updates we change the appearance of the exhaust plume, which cycles
; through a 3-part animation.
UpdateExhaustCounter
0cc4: c6 f7 dec exhaust_anim_counter ;time to update exhaust?
0cc6: 30 01 bmi :DoUpdate ;yup
0cc8: 60 :Okay rts
0cc9: a9 10 :DoUpdate lda #16 ;every 16 frames we change the exhaust state
0ccb: 85 f7 sta exhaust_anim_counter
0ccd: e6 fc inc exhaust_seq
0ccf: a5 fc lda exhaust_seq ;check for overflow
0cd1: c9 03 cmp #$03
0cd3: 90 f3 bcc :Okay
0cd5: a9 00 lda #$00 ;reset to zero
0cd7: 85 fc sta exhaust_seq
0cd9: 60 rts
0cda: 00 00 00 00+ .junk 6
0ce0: 20 e0 0a MultiShipGrab jsr ClearHiRes ;clear screen to black
0ce3: 20 80 43 jsr DrawScoreBase ;redraw scores
0ce6: 20 10 44 jsr DrawCurScore
0ce9: 20 50 44 jsr DrawHighScore
0cec: 4c 80 47 jmp MultiShipGrab1 ;do ship grab thing
0cef: 00 00 00 00+ .junk 17
0d00: a5 f8 DrawPlayerShip lda ship_stage ;check which stage we're flying
0d02: c9 01 cmp #$01 ;stage 1?
0d04: d0 0f bne :Not1 ;nope
0d06: a9 a0 lda #160 ;set position
0d08: 85 fd sta ship_top_row
0d0a: a9 aa lda #170
0d0c: 85 fe sta ship_exhaust_row
0d0e: 20 f0 0b jsr DrawShipStage1 ;draw parts
0d11: 20 26 0c jsr DrawShipExhaust
0d14: 60 rts
0d15: c9 04 :Not1 cmp #$04 ;stage 4 (1+2)?
0d17: d0 18 bne :Not4 ;nope
0d19: a9 96 lda #150 ;start a bit higher to make room
0d1b: 85 fd sta ship_top_row
0d1d: 20 f0 0b jsr DrawShipStage1
0d20: a9 9f lda #159 ;second stage here
0d22: 85 fd sta ship_top_row
0d24: 20 80 0d jsr DrawShipStage2
0d27: a9 aa lda #170
0d29: 85 fe sta ship_exhaust_row
0d2b: 20 26 0c jsr DrawShipExhaust
0d2e: 60 rts
0d2f: 00 00 .junk 2
0d31: c9 02 :Not4 cmp #$02 ;stage 2?
0d33: d0 11 bne :Not2 ;nope
0d35: a9 9f lda #159
0d37: 85 fd sta ship_top_row
0d39: 20 80 0d jsr DrawShipStage2
0d3c: a9 aa lda #170
0d3e: 85 fe sta ship_exhaust_row
0d40: 20 26 0c jsr DrawShipExhaust
0d43: 60 rts
0d44: ea ea .junk 2
0d46: c9 03 :Not2 cmp #$03 ;stage 3?
0d48: d0 0b bne :Not3 ;nope
0d4a: 20 b0 0d jsr DrawShipStage3 ;? should we have set ship_top_row?
0d4d: a9 aa lda #170
0d4f: 85 fe sta ship_exhaust_row
0d51: 20 26 0c jsr DrawShipExhaust
0d54: 60 rts
0d55: c9 05 :Not3 cmp #$05 ;stage >= 5? (exploding)
0d57: 90 0c bcc :Not5_11 ;never taken? 1-4 handled earlier
0d59: c9 0c cmp #12 ;past last explosion (5-11)?
0d5b: b0 08 bcs :Not5_11 ;yup
0d5d: 20 00 1c jsr DrawShipExplosion ;nope, draw it
0d60: e6 f8 inc ship_stage ;inc every frame; balanced by dec in draw code
0d62: 60 rts
0d63: ea ea .junk 2
0d65: c9 0c :Not5_11 cmp #12 ;stage 12?
0d67: d0 0a bne :Not12 ;nope
0d69: 20 90 1c jsr EraseShipAfterDeath
0d6c: e6 f8 inc ship_stage ;advance stage
0d6e: a9 ff lda #$ff ;do 255 fast frames
0d70: 85 f3 sta post_death_frame_count
0d72: 60 :Not13OrDone rts
0d73: c9 0d :Not12 cmp #13 ;stage 13?
0d75: d0 fb bne :Not13OrDone ;nope
0d77: c6 f3 dec post_death_frame_count
0d79: d0 f7 bne :Not13OrDone
0d7b: 4c 00 1d jmp NextLife
0d7e: 00 00 .junk 2
0d80: a6 fa DrawShipStage2 ldx ship_pos_fine
0d82: bd 90 0a lda ship2_s7_index_lo,x
0d85: 8d d1 0b sta _DrawBitmapSrc+1
0d88: bd 98 0a lda ship2_s7_index_hi,x
0d8b: 8d d2 0b sta _DrawBitmapSrc+2
0d8e: a5 f9 lda ship_pos_coarse
0d90: 38 sec
0d91: e9 03 sbc #$03 ;will start from even column
0d93: 85 06 sta ]start_col
0d95: 18 clc
0d96: 69 08 adc #8 ;bitmap width
0d98: 85 07 sta ]end_col
0d9a: a5 fd lda ship_top_row
0d9c: 85 04 sta ]start_row
0d9e: 18 clc
0d9f: 69 0c adc #12 ;bitmap height
0da1: 85 05 sta ]end_row
0da3: 4c c0 0b jmp DrawBitmap
0da6: 00 00 00 00+ .junk 10
0db0: a6 fa DrawShipStage3 ldx ship_pos_fine
0db2: bd a0 0a lda ship3_s7_index_lo,x
0db5: 8d d1 0b sta _DrawBitmapSrc+1
0db8: bd a8 0a lda ship3_s7_index_hi,x
0dbb: 8d d2 0b sta _DrawBitmapSrc+2
0dbe: a5 f9 lda ship_pos_coarse
0dc0: 38 sec
0dc1: e9 04 sbc #$04
0dc3: 85 06 sta ]start_col
0dc5: 18 clc
0dc6: 69 0a adc #10
0dc8: 85 07 sta ]end_col
0dca: a9 9e lda #$9e
0dcc: 85 04 sta ]start_row
0dce: 18 clc
0dcf: 69 0c adc #12
0dd1: 85 05 sta ]end_row
0dd3: 4c c0 0b jmp DrawBitmap
0dd6: 00 00 00 00+ .junk 10
; Check to see if the fire button (paddle button 0) is down.
;
; The player is not allowed to fire continuously by holding the button down.
CheckFireButton1
0de0: a5 1f lda button_was_down ;was button down before?
0de2: f0 0a beq :Check ;no, check it now
0de4: ad 61 c0 lda BUTN0 ;yes, see if it has come up
0de7: 30 04 bmi L0DED ;still down
0de9: a9 00 lda #$00 ;it's up, clear flag
0deb: 85 1f sta button_was_down
0ded: 60 L0DED rts
0dee: ad 61 c0 :Check lda BUTN0
0df1: 30 01 bmi L0DF4 ;it's pressed
0df3: 60 rts
0df4: a9 ff L0DF4 lda #$ff ;set the button-down flag
0df6: 85 1f sta button_was_down
0df8: 4c c6 12 jmp FireAllGuns
0dfb: 00 00 00 00+ .junk 5
; Draws a bitmap for the initial ship animation.
;
; Draws at start_col,start_row. Dimensions are determined by end_col,end_row.
; Bitmaps are clipped at the bottom of the screen.
;
; The caller must set the source address in _draw_bitmap_source+1 before
; calling.
DrawBitmap_Initial
0e00: a6 04 ldx ]start_row ;init X-reg to top row
0e02: e0 c0 :Loop cpx #192 ;are we off the bottom?
0e04: b0 26 bcs :Done ;yes, done drawing
0e06: bd 00 08 lda hr_ytable_hi,x ;set up row destination address
0e09: 8d 19 0e sta :_DrawBitmapDest+2
0e0c: bd c0 08 lda hr_ytable_lo,x
0e0f: 8d 18 0e sta :_DrawBitmapDest+1
0e12: a4 06 ldy ]start_col
_DrawBitmapSource
0e14: ad 79 6b lda T6B10+105
:_DrawBitmapDest
0e17: 99 d0 37 sta $37d0,y
0e1a: ee 15 0e inc _DrawBitmapSource+1
0e1d: d0 03 bne :NoInc
0e1f: ee 16 0e inc _DrawBitmapSource+2
0e22: c8 :NoInc iny
0e23: c4 07 cpy ]end_col
0e25: 90 ed bcc _DrawBitmapSource
0e27: e8 inx
0e28: e4 05 cpx ]end_row
0e2a: 90 d6 bcc :Loop
0e2c: 60 :Done rts
0e2d: ea 00 00 .junk 3
; Draw stage 1 of the ship.
;
; On entry:
; $0a - top row
; $f9/fa - ship horizontal position
DrawShipStage1_Initial
0e30: a6 fa ldx ship_pos_fine
0e32: bd 80 0a lda ship1_s7_index_lo,x
0e35: 8d 15 0e sta _DrawBitmapSource+1
0e38: bd 88 0a lda ship1_s7_index_hi,x
0e3b: 8d 16 0e sta _DrawBitmapSource+2
0e3e: a5 f9 lda ship_pos_coarse
0e40: 38 sec
0e41: e9 02 sbc #$02 ;shift to center: subtract (4 bytes wide / 2)
0e43: 85 06 sta ]start_col
0e45: 18 clc
0e46: 69 06 adc #6 ;bitmap width (4+2)
0e48: 85 07 sta ]end_col
0e4a: a5 0a lda ]bitmap_top_row
0e4c: 85 04 sta ]start_row
0e4e: 18 clc
0e4f: 69 09 adc #9 ;bitmap height
0e51: 85 05 sta ]end_row
0e53: 4c 00 0e jmp DrawBitmap_Initial
0e56: 00 00 00 00+ .junk 10
; Draw stage 2 of the ship.
;
; Same args as stage 1, but $0b provides the vertical offset from stage 1.
DrawShipStage2_Initial
0e60: a6 fa ldx ship_pos_fine
0e62: bd 90 0a lda ship2_s7_index_lo,x
0e65: 8d 15 0e sta _DrawBitmapSource+1
0e68: bd 98 0a lda ship2_s7_index_hi,x
0e6b: 8d 16 0e sta _DrawBitmapSource+2
0e6e: a5 f9 lda ship_pos_coarse
0e70: 38 sec
0e71: e9 03 sbc #$03 ;6/2, will start from even column
0e73: 85 06 sta ]start_col
0e75: 18 clc
0e76: 69 08 adc #8 ;bitmap width (6+2)
0e78: 85 07 sta ]end_col
0e7a: a5 0a lda ]bitmap_top_row
0e7c: 18 clc
0e7d: 65 0b adc ]bitmap_top_adj
0e7f: 85 04 sta ]start_row
0e81: 18 clc
0e82: 69 0c adc #12 ;bitmap height
0e84: 85 05 sta ]end_row
0e86: 4c 00 0e jmp DrawBitmap_Initial
0e89: 00 00 00 00+ .junk 7
; Draw stage 3 of the ship. Same args as stage 2.
DrawShipStage3_Initial
0e90: a6 fa ldx ship_pos_fine
0e92: bd a0 0a lda ship3_s7_index_lo,x
0e95: 8d 15 0e sta _DrawBitmapSource+1
0e98: bd a8 0a lda ship3_s7_index_hi,x
0e9b: 8d 16 0e sta _DrawBitmapSource+2
0e9e: a5 f9 lda ship_pos_coarse
0ea0: 38 sec
0ea1: e9 04 sbc #$04 ;8/2
0ea3: 85 06 sta ]start_col
0ea5: 18 clc
0ea6: 69 0a adc #10 ;bitmap width (8+2)
0ea8: 85 07 sta ]end_col
0eaa: a5 0a lda ]bitmap_top_row
0eac: 18 clc
0ead: 65 0b adc ]bitmap_top_adj
0eaf: 85 04 sta ]start_row
0eb1: 18 clc
0eb2: 69 0c adc #12 ;bitmap height
0eb4: 85 05 sta ]end_row
0eb6: 4c 00 0e jmp DrawBitmap_Initial
0eb9: 00 00 00 00+ .junk 7
; Draw animated exhaust plume. Same args as ship sections.
DrawShipExhaust_Initial
0ec0: 20 c4 0c jsr UpdateExhaustCounter
0ec3: a5 fc lda exhaust_seq
0ec5: 0a asl A
0ec6: 0a asl A
0ec7: 0a asl A
0ec8: 0a asl A
0ec9: 18 clc
0eca: 69 b0 adc #<exhaust0_s7_index_lo
0ecc: 8d d8 0e sta :_ExhaustSrcLo+1
0ecf: 18 clc
0ed0: 69 08 adc #$08
0ed2: 8d de 0e sta :_ExhaustSrcHi+1 ;assumes page boundary not crossed
0ed5: a6 fa ldx ship_pos_fine
0ed7: bd c0 0a :_ExhaustSrcLo lda exhaust1_s7_index_lo,x
0eda: 8d 15 0e sta _DrawBitmapSource+1
0edd: bd c8 0a :_ExhaustSrcHi lda exhaust1_s7_index_hi,x
0ee0: 8d 16 0e sta _DrawBitmapSource+2
0ee3: a5 f9 lda ship_pos_coarse
0ee5: 38 sec
0ee6: e9 02 sbc #$02 ;image positioned to match ship stage 1
0ee8: 85 06 sta ]start_col
0eea: 18 clc
0eeb: 69 05 adc #5 ;bitmap width
0eed: 85 07 sta ]end_col
0eef: a5 0a lda ]bitmap_top_row
0ef1: 18 clc
0ef2: 65 0b adc ]bitmap_top_adj
0ef4: 85 04 sta ]start_row
0ef6: 18 clc
0ef7: 69 15 adc #21 ;bitmap height
0ef9: 85 05 sta ]end_row
0efb: 4c 00 0e jmp DrawBitmap_Initial
0efe: ea ea .junk 2
;
; Animate the arrival of the player's ship at the start of the game. The three
; stacked ships rise up from the bottom until they're about a third of the way
; from the top, then settle back down.
;
AnimateShipArrival_123
0f00: 20 e0 1c jsr PrepareScreenInitRow ;also stores 192 in $0a (bitmap_top_row)
0f03: ea nop ;so first DrawShipStage1 doesn't draw anything
0f04: 20 00 0b :UpLoop jsr UpdateStarField
0f07: 20 30 0e jsr DrawShipStage1_Initial
0f0a: a9 09 lda #9 ;position below stage 1
0f0c: 85 0b sta ]bitmap_top_adj
0f0e: 20 60 0e jsr DrawShipStage2_Initial
0f11: a9 14 lda #20 ;position below stage 1+2
0f13: 85 0b sta ]bitmap_top_adj
0f15: 20 90 0e jsr DrawShipStage3_Initial
0f18: a9 20 lda #32 ;position below stage 1+2+3
0f1a: 85 0b sta ]bitmap_top_adj
0f1c: 20 c0 0e jsr DrawShipExhaust_Initial
0f1f: 20 f0 1c jsr ChirpEvery4
0f22: c6 0a dec ]bitmap_top_row ;move up a row
0f24: a5 0a lda ]bitmap_top_row
0f26: c9 40 cmp #64 ;reached highest point?
0f28: b0 da bcs :UpLoop ;no, continue
; Now animate then back down.
0f2a: 20 00 43 jsr _MakeChirp
0f2d: 20 00 0b :DnLoop jsr UpdateStarField
0f30: e6 0a inc ]bitmap_top_row
0f32: a5 0a lda ]bitmap_top_row
0f34: c9 c1 cmp #193 ;hit bottom of screen?
0f36: 90 01 bcc :Cont ;not yet
0f38: 60 rts
0f39: 20 00 10 :Cont jsr DrawShipStage1_DropIn
0f3c: a9 09 lda #$09
0f3e: 85 0b sta ]bitmap_top_adj
0f40: 20 60 0e jsr DrawShipStage2_Initial
0f43: a9 14 lda #$14
0f45: 85 0b sta ]bitmap_top_adj
0f47: 20 90 0e jsr DrawShipStage3_Initial
0f4a: a9 20 lda #$20
0f4c: 85 0b sta ]bitmap_top_adj
0f4e: 20 c0 0e jsr DrawShipExhaust_Initial
0f51: 20 f0 1c jsr ChirpEvery4
0f54: 4c 2d 0f jmp :DnLoop
0f57: 0f 00 00 00+ .junk 9
;
; At the start of the second life, animate player ship stages 2+3 onto the
; screen.
;
AnimateShipArrival_23
0f60: 20 e0 1c jsr PrepareScreenInitRow
0f63: ea nop
0f64: 20 00 0b :UpLoop jsr UpdateStarField
0f67: a9 00 lda #$00
0f69: 85 0b sta ]bitmap_top_adj
0f6b: 20 60 0e jsr DrawShipStage2_Initial
0f6e: a9 0b lda #$0b
0f70: 85 0b sta ]bitmap_top_adj
0f72: 20 90 0e jsr DrawShipStage3_Initial
0f75: a9 17 lda #$17
0f77: 85 0b sta ]bitmap_top_adj
0f79: 20 c0 0e jsr DrawShipExhaust_Initial
0f7c: 20 f0 1c jsr ChirpEvery4
0f7f: c6 0a dec ]bitmap_top_row
0f81: a5 0a lda ]bitmap_top_row
0f83: c9 40 cmp #$40
0f85: b0 dd bcs :UpLoop
; now animate back down
0f87: 20 f0 1c jsr ChirpEvery4
0f8a: 20 00 0b :DnLoop jsr UpdateStarField
0f8d: e6 0a inc ]bitmap_top_row
0f8f: a5 0a lda ]bitmap_top_row
0f91: c9 c1 cmp #193 ;bottom?
0f93: 90 01 bcc :Cont
0f95: 60 rts
0f96: 20 10 10 :Cont jsr DrawShipStage2_DropIn
0f99: a9 0b lda #$0b
0f9b: 85 0b sta ]bitmap_top_adj
0f9d: 20 90 0e jsr DrawShipStage3_Initial
0fa0: a9 17 lda #$17
0fa2: 85 0b sta ]bitmap_top_adj
0fa4: 20 c0 0e jsr DrawShipExhaust_Initial
0fa7: 20 f0 1c jsr ChirpEvery4
0faa: 4c 8a 0f jmp :DnLoop
0fad: 00 00 89 0f+ .junk 19
;
; At the start of the 3rd life, animate the arrival of the player's ship, but
; only stage 3 (the widest).
;
AnimateShipArrival_3
0fc0: 20 e0 1c jsr PrepareScreenInitRow ;sets $0a to 192
0fc3: ea nop
0fc4: 20 00 0b :UpLoop jsr UpdateStarField
0fc7: a9 00 lda #0
0fc9: 85 0b sta ]bitmap_top_adj
0fcb: 20 90 0e jsr DrawShipStage3_Initial
0fce: a9 0c lda #12
0fd0: 85 0b sta ]bitmap_top_adj
0fd2: 20 c0 0e jsr DrawShipExhaust_Initial
0fd5: 20 f0 1c jsr ChirpEvery4
0fd8: c6 0a dec ]bitmap_top_row
0fda: a5 0a lda ]bitmap_top_row
0fdc: c9 40 cmp #64
0fde: b0 e4 bcs :UpLoop
; now animate it back down
0fe0: 20 00 43 jsr _MakeChirp
0fe3: e6 0a :DnLoop inc ]bitmap_top_row
0fe5: a5 0a lda ]bitmap_top_row
0fe7: c9 9e cmp #158
0fe9: 90 01 bcc :Cont+179
0feb: 60 rts
0fec: 20 00 0b jsr UpdateStarField
0fef: a9 00 lda #0
0ff1: 85 0b sta ]bitmap_top_adj
0ff3: 20 90 0e jsr DrawShipStage3_Initial
0ff6: a9 0c lda #12
0ff8: 85 0b sta ]bitmap_top_adj
0ffa: 20 c0 0e jsr DrawShipExhaust_Initial
0ffd: 4c e3 0f jmp :DnLoop
; Draw stage 1 of the ship with the appropriate routine. Used on the player
; arrival screen when animating the stack of ships, and we want the later stages
; to continue moving downward without the first stage.
;
; On entry:
; A-reg: top row
DrawShipStage1_DropIn
1000: c9 a1 cmp #161 ;have we reached the target row?
1002: b0 03 bcs L1007 ;yes, use other draw function
1004: 4c 30 0e jmp DrawShipStage1_Initial ;not yet
1007: a9 a0 L1007 lda #160
1009: 85 fd sta ship_top_row
100b: 4c f0 0b jmp DrawShipStage1
100e: ea 00 .junk 2
; Draws stage 2 while animating stages 2+3 in at the start of a life.
DrawShipStage2_DropIn
1010: c9 9f cmp #159 ;stage 2 reached final position?
1012: b0 07 bcs L101B ;yes, draw at fixed position
1014: a9 00 lda #$00 ;no, draw at animated position
1016: 85 0b sta ]bitmap_top_adj
1018: 4c 60 0e jmp DrawShipStage2_Initial
101b: a9 9f L101B lda #$9f
101d: 85 fd sta ship_top_row
101f: 4c 80 0d jmp DrawShipStage2
1022: 00 00 00 00+ .align $0100 (222 bytes)
; Bullet bitmap data. There are seven pre-shifted bitmaps, each 3x2. The rows
; are repeated 3x each by the bullet rendering code.
1100: 02 00 00 07+ bullet_data0 .bulk 0200000700000000
1108: 08 00 00 1c+ bullet_data1 .bulk 0800001c00000000
1110: 20 00 00 70+ bullet_data2 .bulk 2000007000000000
1118: 00 01 00 40+ bullet_data3 .bulk 0001004003000000
1120: 00 04 00 00+ bullet_data4 .bulk 000400000e000000
1128: 00 10 00 00+ bullet_data5 .bulk 0010000038000000
1130: 00 40 00 00+ bullet_data6 .bulk 0040000060010000
1138: 00 00 00 00+ .junk 18
; Fire one bullet from the stage 1 ship.
FireBullet_Stage1
114a: d0 41 bne L118D ;(branch never?)
FireBullet_Stage1a
114c: a5 d0 lda bullet1_fired ;already fired?
114e: f0 01 beq :DoFire ;no
1150: 60 rts
1151: a9 01 :DoFire lda #$01
1153: 85 d0 sta bullet1_fired
1155: a9 9e lda #158 ;start just above the ship
1157: 85 d1 sta bullet1_row
1159: a5 f9 lda ship_pos_coarse
115b: 38 sec
115c: e9 00 sbc #$00 ;? does nothing
115e: 85 d2 sta bullet1_col
1160: a5 fa lda ship_pos_fine ;value is 0-6
1162: 18 clc
1163: 69 00 adc #$00 ;? does nothing
1165: c9 07 cmp #$07
1167: 90 05 bcc L116E ;always
1169: e6 d2 inc bullet1_col ;(maybe left over from an earlier implementation in
116b: 38 sec ; which the fine position was 0-12?)
116c: e9 07 sbc #$07
116e: aa L116E tax ;now calculate bitmap address
116f: a9 00 lda #$00
1171: e0 00 :Loop cpx #$00
1173: f0 07 beq L117C
1175: ca dex
1176: 18 clc
1177: 69 08 adc #$08
1179: 4c 71 11 jmp :Loop
117c: 8d 82 11 L117C sta L1181+1
117f: a0 00 ldy #$00
1181: b9 18 11 L1181 lda bullet_data3,y ;copy 8 bytes from $11xx to $d3-da
1184: 99 d3 00 sta bullet1_img_00,y
1187: c8 iny
1188: c0 07 cpy #$07
118a: 90 f5 bcc L1181
118c: 60 rts
118d: c9 L118D .dd1 $c9
118e: 02 .dd1 $02
118f: d0 .dd1 $d0
1190: ef .dd1 $ef
; Fire two bullets from the stage 2 (medium) ship.
FireTwoBullets_2
1191: a5 d0 lda bullet1_fired
1193: f0 01 beq :DoFire
1195: 60 rts
1196: a9 01 :DoFire lda #$01
1198: 85 d0 sta bullet1_fired
119a: a9 9a lda #$9a
119c: 85 d1 sta bullet1_row
119e: a5 f9 lda ship_pos_coarse
11a0: 38 sec
11a1: e9 02 sbc #$02
11a3: 85 d2 sta bullet1_col
11a5: a5 fa lda ship_pos_fine
11a7: 18 clc
11a8: 69 00 adc #$00
11aa: c9 07 cmp #$07
11ac: 90 05 bcc L11B3
11ae: e6 d2 inc bullet1_col
11b0: 38 sec
11b1: e9 07 sbc #$07
11b3: aa L11B3 tax ;calculate bitmap address
11b4: a9 00 lda #$00 ;start at 0
11b6: e0 00 :Loop cpx #$00
11b8: f0 07 beq L11C1
11ba: ca dex
11bb: 18 clc
11bc: 69 08 adc #$08 ;step by 8
11be: 4c b6 11 jmp :Loop
11c1: 8d c7 11 L11C1 sta :Loop+1 ;A-reg holds 0, 8, 16, 24, ...
11c4: a0 00 ldy #$00
11c6: b9 20 11 :Loop lda bullet_data0+32,y ;copy 6 bytes to $d3-d8
11c9: 99 d3 00 sta bullet1_img_00,y
11cc: c8 iny
11cd: c0 06 cpy #$06
11cf: 90 f5 bcc :Loop
11d1: a5 d9 lda bullet2_fired
11d3: f0 01 beq L11D6
11d5: 60 rts
11d6: a9 01 L11D6 lda #$01
11d8: 85 d9 sta bullet2_fired
11da: a9 9a lda #$9a
11dc: 85 da sta bullet2_row
11de: a5 f9 lda ship_pos_coarse
11e0: 18 clc
11e1: 69 02 adc #$02
11e3: 85 db sta bullet2_state+2
11e5: a5 fa lda ship_pos_fine
11e7: 18 clc
11e8: 69 00 adc #$00
11ea: c9 07 cmp #$07
11ec: 90 05 bcc L11F3
11ee: e6 db inc bullet2_state+2
11f0: 38 sec
11f1: e9 07 sbc #$07
11f3: aa L11F3 tax ;calculate bitmap address
11f4: a9 00 lda #$00 ;start at 0
11f6: e0 00 L11F6 cpx #$00
11f8: f0 07 beq L1201
11fa: ca dex
11fb: 18 clc
11fc: 69 08 adc #$08 ;step by 8
11fe: 4c f6 11 jmp L11F6
1201: 8d 07 12 L1201 sta :Loop+1
1204: a0 00 ldy #$00
1206: b9 20 11 :Loop lda bullet_data0+32,y ;copy 6 bytes to $dc-e1
1209: 99 dc 00 sta bullet2_state+3,y
120c: c8 iny
120d: c0 06 cpy #$06
120f: 90 f5 bcc :Loop
1211: 60 rts
1212: c9 02 d0 ef .junk 4
; Fire two bullets from the stage 3 (widest) ship.
FireTwoBullets_3
1216: a5 d0 lda bullet1_fired ;should've been checked already?
1218: f0 01 beq :DoFire ;always?
121a: 60 rts
121b: a9 01 :DoFire lda #$01
121d: 85 d0 sta bullet1_fired
121f: a9 9a lda #$9a
1221: 85 d1 sta bullet1_row
1223: a5 f9 lda ship_pos_coarse
1225: 38 sec
1226: e9 03 sbc #$03
1228: 85 d2 sta bullet1_col
122a: a5 fa lda ship_pos_fine
122c: 18 clc
122d: 69 00 adc #$00
122f: c9 07 cmp #$07
1231: 90 05 bcc L1238
1233: e6 d2 inc bullet1_col
1235: 38 sec
1236: e9 07 sbc #$07
1238: aa L1238 tax ;calculate bitmap address
1239: a9 00 lda #$00
123b: e0 00 L123B cpx #$00
123d: f0 07 beq L1246
123f: ca dex
1240: 18 clc
1241: 69 08 adc #$08
1243: 4c 3b 12 jmp L123B
1246: 8d 4c 12 L1246 sta :_BulletSrc+1
1249: a0 00 ldy #$00
124b: b9 28 11 :_BulletSrc lda bullet_data5,y
124e: 99 d3 00 sta bullet1_img_00,y
1251: c8 iny
1252: c0 07 cpy #$07
1254: 90 f5 bcc :_BulletSrc
1256: a5 d9 lda bullet2_fired
1258: f0 01 beq L125B
125a: 60 rts
125b: a9 01 L125B lda #$01
125d: 85 d9 sta bullet2_fired
125f: a9 9a lda #$9a
1261: 85 da sta bullet2_row
1263: a5 f9 lda ship_pos_coarse
1265: 18 clc
1266: 69 03 adc #$03
1268: 85 db sta bullet2_state+2
126a: a5 fa lda ship_pos_fine
126c: 18 clc
126d: 69 00 adc #$00
126f: c9 07 cmp #$07
1271: 90 05 bcc L1278
1273: e6 db inc bullet2_state+2
1275: 38 sec
1276: e9 07 sbc #$07
1278: aa L1278 tax
1279: a9 00 lda #$00
127b: e0 00 L127B cpx #$00
127d: f0 07 beq L1286
127f: ca dex
1280: 18 clc
1281: 69 08 adc #$08
1283: 4c 7b 12 jmp L127B
1286: 8d 8c 12 L1286 sta L128B+1
1289: a0 00 ldy #$00
128b: b9 28 11 L128B lda bullet_data5,y
128e: 99 dc 00 sta bullet2_state+3,y
1291: c8 iny
1292: c0 07 cpy #$07
1294: 90 f5 bcc L128B
1296: 60 rts
1297: 00 00 00 00+ .junk 9
FireThreeBullets
12a0: 20 4c 11 jsr FireBullet_Stage1a ;do the setup for stage 1 firing
12a3: a0 00 ldy #$00
12a5: b9 d0 00 :Loop lda bullet1_fired,y ;copy the bullet1 state to bullet3
12a8: 99 e2 00 sta bullet3_state,y
12ab: c8 iny
12ac: c0 09 cpy #$09
12ae: 90 f5 bcc :Loop
12b0: a5 e3 lda bullet3_row ;adjust the row because the ships are stacked
12b2: 38 sec
12b3: e9 10 sbc #16
12b5: 85 e3 sta bullet3_row
12b7: c6 d0 dec bullet1_fired ;undo bullet1
12b9: 4c 91 11 jmp FireTwoBullets_2 ;fire bullets for stage 2
12bc: 00 00 00 00 .junk 4
12c0: 4c e0 0d CheckFireButton jmp CheckFireButton1
12c3: 30 01 60 .junk 3
; Fires all guns when the paddle button is pressed.
12c6: a5 f8 FireAllGuns lda ship_stage
12c8: c9 01 cmp #$01
12ca: d0 03 bne :Not1
12cc: 4c 4a 11 jmp FireBullet_Stage1
12cf: c9 02 :Not1 cmp #$02
12d1: d0 03 bne :Not2
12d3: 4c f0 12 jmp FireBullet_Stage2
12d6: c9 03 :Not2 cmp #$03
12d8: d0 03 bne :Not3
12da: 4c 00 13 jmp FireBullet_Stage3
12dd: c9 04 :Not3 cmp #$04
12df: d0 03 bne :Not4
12e1: 4c 10 13 jmp FireBullet_Stage4
12e4: 60 :Not4 rts
12e5: 00 00 00 00+ .junk 11
FireBullet_Stage2
12f0: a5 d0 lda bullet1_fired ;check to see if either bullet is active
12f2: f0 01 beq L12F5
12f4: 60 rts
12f5: a5 d9 L12F5 lda bullet2_fired
12f7: f0 01 beq L12FA
12f9: 60 rts
12fa: 4c 91 11 L12FA jmp FireTwoBullets_2
12fd: a5 d0 00 .junk 3
FireBullet_Stage3
1300: a5 d0 lda bullet1_fired ;check to see if either bullet is active
1302: f0 01 beq L1305
1304: 60 rts
1305: a5 d9 L1305 lda bullet2_fired
1307: f0 01 beq L130A
1309: 60 rts
130a: 4c 16 12 L130A jmp FireTwoBullets_3
130d: a5 .dd1 $a5
130e: d0 .dd1 $d0
130f: 00 .dd1 $00
FireBullet_Stage4
1310: a5 d0 lda bullet1_fired ;check if any of the 3 bullets are active
1312: f0 01 beq L1315
1314: 60 rts
1315: a5 d9 L1315 lda bullet2_fired
1317: f0 01 beq L131A
1319: 60 rts
131a: a5 e2 L131A lda bullet3_state
131c: f0 01 beq L131F
131e: 60 rts
131f: 4c a0 12 L131F jmp FireThreeBullets
1322: 00 00 00 00+ .junk 14
MoveEggCheckCollision
1330: a9 ff lda #$ff
1332: 85 cd sta collision_flag ;clear flag
1334: 20 00 17 jsr CheckBulletCollision
1337: a5 cd lda collision_flag ;collided with bullet?
1339: f0 03 beq :Hit ;yes
133b: 4c 00 19 jmp UpdateEggPosition ;no, move egg
133e: e6 c0 :Hit inc alien_state ;inc state to hatch egg
1340: 60 rts
1341: 00 00 00 00+ .junk 15
; Updates the position of the current alien, and checks for collisions with
; bullets.
1350: a9 ff UpdateAlienPos lda #$ff
1352: 85 cd sta collision_flag ;clear flag
1354: 20 00 17 jsr CheckBulletCollision
1357: a5 cd lda collision_flag ;collided with bullet?
1359: d0 05 bne :Alive ;no
135b: a9 0b :Dead lda #11 ;set state to "exploding"
135d: 85 c0 sta alien_state
135f: 60 rts
1360: 20 90 1b :Alive jsr CheckShipCollision
1363: a5 cd lda collision_flag
1365: f0 f4 beq :Dead
1367: a5 c0 lda alien_state
1369: c9 0a cmp #10 ;fuzzball?
136b: f0 03 beq L1370 ;yes, use special move
136d: 4c f0 1a jmp MoveAlien
1370: 4c 60 1b L1370 jmp MoveAlienSeek
1373: 00 00 00 00+ .junk 13
;
; Updates the state for a single alien. Pass the alien DP base address ($20,
; $30, ... $80) in A-reg.
;
UpdateAlienState
1380: 8d 89 13 sta :_AlienOffset1+1
1383: 8d 9a 13 sta :_AlienOffset2+1
1386: a0 09 ldy #$09 ;copy $x0-x9 to $c0-c9
1388: b9 20 00 :_AlienOffset1 lda alien0,y
138b: 99 c0 00 sta alien_state,y
138e: 88 dey
138f: 10 f7 bpl :_AlienOffset1
1391: 20 70 15 jsr DoUpdateAlienState ;update state
1394: a0 09 ldy #$09 ;copy it back to $x0-x9
1396: b9 c0 00 :Loop lda alien_state,y
1399: 99 20 00 :_AlienOffset2 sta alien0,y
139c: 88 dey
139d: 10 f7 bpl :Loop
139f: 60 rts
13a0: 85 05 4c 50+ .junk 16
:CheckDoubleShip1
13b0: a5 90 lda did_multi_ship ;have we done the multi-ship grab yet?
13b2: d0 06 bne L13BA ;yes, don't do it again
13b4: a5 b0 lda cur_score_hi ;check the current score
13b6: c9 0f cmp #$0f ;at least 1000 (BCD)?
13b8: b0 01 bcs L13BB ;yes, do the multi-ship thing
13ba: 60 L13BA rts
13bb: 20 e0 0c L13BB jsr MultiShipGrab
13be: a9 ff lda #$ff
13c0: 85 90 sta did_multi_ship
13c2: 60 rts
13c3: 00 .dd1 $00
; Called after we clear out an entire stage of aliens, to see if we want to do
; the ship-merge thing.
13c4: a5 f8 CheckDoubleShip lda ship_stage
13c6: c9 02 cmp #$02
13c8: f0 e6 beq :CheckDoubleShip1
13ca: 60 rts
13cb: 00 00 00 00+ .junk 5
; Straightforward bitmap draw, only used for the egg hatch bitmap.
13d0: a6 04 DrawHatchImage ldx ]start_row
13d2: bd 00 08 :Loop lda hr_ytable_hi,x
13d5: 8d e5 13 sta :_DrawHatchDst+2
13d8: bd c0 08 lda hr_ytable_lo,x
13db: 8d e4 13 sta :_DrawHatchDst+1
13de: a4 06 ldy ]start_col
13e0: ad 20 62 _DrawHatchSrc lda T6220
13e3: 99 d0 2a :_DrawHatchDst sta HIRES_PAGE_1+$ad0,y
13e6: ee e1 13 inc _DrawHatchSrc+1
13e9: d0 03 bne :NoInc
13eb: ee e2 13 inc _DrawHatchSrc+2
13ee: c8 :NoInc iny
13ef: c4 07 cpy ]end_col
13f1: 90 ed bcc _DrawHatchSrc
13f3: 8d 30 c0 sta SPKR
13f6: e8 inx
13f7: e4 05 cpx ]end_row
13f9: 90 d7 bcc :Loop
13fb: 60 rts
13fc: 00 00 00 00 .junk 4
; Draws part of a bullet. Pass in one 3-byte row of the image, which is
; repeated 3x. This will be called twice, once for the top part and once for
; the bottom.
;
; On entry:
; X-reg: top row number
; Y-reg: left column number
; $03/04/05: bytes to draw
• Clear variables
]ptr .var $00 {addr/2}
]count .var $02 {addr/1}
]row_data .var $03 {addr/3}
1400: a9 03 DrawBullet lda #$03
1402: 85 02 sta ]count
1404: bd 00 08 :Loop lda hr_ytable_hi,x ;get hi-res base address
1407: 85 01 sta ]ptr+1
1409: bd c0 08 lda hr_ytable_lo,x
140c: 85 00 sta ]ptr
140e: a5 03 lda ]row_data ;draw 3 bytes
1410: 91 00 sta (]ptr),y
1412: c8 iny
1413: a5 04 lda ]row_data+1
1415: 91 00 sta (]ptr),y
1417: c8 iny
1418: a5 05 lda ]row_data+2
141a: 91 00 sta (]ptr),y
141c: 88 dey ;reset Y-reg
141d: 88 dey
141e: ea nop
141f: e8 inx
1420: c6 02 dec ]count
1422: d0 e0 bne :Loop
1424: 60 rts
1425: c8 60 60 .junk 3
; Erases both parts of a bullet (a 3x6 area). Same args as DrawBullet.
1428: a9 06 EraseBullet lda #$06
142a: 85 02 sta ]count
142c: bd 00 08 L142C lda hr_ytable_hi,x ;get hi-res base address
142f: 85 01 sta ]ptr+1
1431: bd c0 08 lda hr_ytable_lo,x
1434: 85 00 sta ]ptr
1436: a9 00 lda #$00 ;draw zero in all three bytes
1438: 91 00 sta (]ptr),y
143a: c8 iny
143b: 91 00 sta (]ptr),y
143d: c8 iny
143e: 91 00 sta (]ptr),y
1440: 88 dey ;reset Y-reg
1441: 88 dey
1442: ea nop
1443: e8 inx
1444: c6 02 dec ]count
1446: d0 e4 bne L142C
1448: 60 rts
1449: 00 00 00 00+ .junk 7
; Updates the position of bullet #1.
1450: a5 d0 MoveBullet1 lda bullet1_fired
1452: d0 01 bne :DoMove
1454: 60 rts
1455: a6 d1 :DoMove ldx bullet1_row
1457: a4 d2 ldy bullet1_col
1459: 20 28 14 jsr EraseBullet
145c: a5 d1 lda bullet1_row ;move it up 6 pixels
145e: 38 sec
145f: e9 06 sbc #$06
1461: c9 08 cmp #$08 ;reached the top?
1463: b0 05 bcs :DoDraw ;not yet
1465: a9 00 lda #$00 ;yes, clear it
1467: 85 d0 sta bullet1_fired
1469: 60 rts
146a: 85 d1 :DoDraw sta bullet1_row ;top row
146c: aa tax ;keep in X-reg
146d: a4 d2 ldy bullet1_col
146f: a5 d3 lda bullet1_img_00 ;get bitmap data out of DP
1471: 85 03 sta ]row_data
1473: a5 d4 lda bullet1_img_01
1475: 85 04 sta ]row_data+1
1477: a5 d5 lda bullet1_img_02
1479: 85 05 sta ]row_data+2
147b: 20 00 14 jsr DrawBullet ;draw first part
147e: a5 d6 lda bullet1_img_10
1480: 85 03 sta ]row_data
1482: a5 d7 lda bullet1_img_11
1484: 85 04 sta ]row_data+1
1486: a5 d8 lda bullet1_img_12
1488: 85 05 sta ]row_data+2
148a: 20 00 14 jsr DrawBullet ;draw second part
148d: 60 rts
; Updates the position of bullet #2.
148e: a5 d9 MoveBullet2 lda bullet2_fired
1490: d0 02 bne :DoMove
1492: 60 rts
1493: 60 .junk 1
1494: a6 da :DoMove ldx bullet2_row
1496: a4 db ldy bullet2_state+2
1498: 20 28 14 jsr EraseBullet
149b: a5 da lda bullet2_row
149d: 38 sec
149e: e9 06 sbc #$06
14a0: c9 08 cmp #$08
14a2: b0 05 bcs :DoDraw
14a4: a9 00 lda #$00
14a6: 85 d9 sta bullet2_fired
14a8: 60 rts
14a9: 85 da :DoDraw sta bullet2_row
14ab: aa tax
14ac: a4 db ldy bullet2_state+2
14ae: a5 dc lda bullet2_state+3
14b0: 85 03 sta ]row_data
14b2: a5 dd lda bullet2_state+4
14b4: 85 04 sta ]row_data+1
14b6: a5 de lda bullet2_state+5
14b8: 85 05 sta ]row_data+2
14ba: 20 00 14 jsr DrawBullet
14bd: a5 df lda bullet2_state+6
14bf: 85 03 sta ]row_data
14c1: a5 e0 lda bullet2_state+7
14c3: 85 04 sta ]row_data+1
14c5: a5 e1 lda bullet2_state+8
14c7: 85 05 sta ]row_data+2
14c9: 20 00 14 jsr DrawBullet
14cc: 60 rts
14cd: d9 .dd1 $d9
14ce: d0 .dd1 $d0
14cf: 03 .dd1 $03
; Updates the position of bullet #3.
14d0: a5 e2 MoveBullet3 lda bullet3_state
14d2: d0 02 bne :DoMove
14d4: 60 rts
14d5: 60 .junk 1
14d6: a6 e3 :DoMove ldx bullet3_row
14d8: a4 e4 ldy bullet3_state+2
14da: 20 28 14 jsr EraseBullet
14dd: a5 e3 lda bullet3_row
14df: 38 sec
14e0: e9 06 sbc #$06
14e2: c9 08 cmp #$08
14e4: b0 05 bcs :DoDraw
14e6: a9 00 lda #$00
14e8: 85 e2 sta bullet3_state
14ea: 60 rts
14eb: 85 e3 :DoDraw sta bullet3_row
14ed: aa tax
14ee: a4 e4 ldy bullet3_state+2
14f0: a5 e5 lda bullet3_state+3
14f2: 85 03 sta ]row_data
14f4: a5 e6 lda bullet3_state+4
14f6: 85 04 sta ]row_data+1
14f8: a5 e7 lda bullet3_state+5
14fa: 85 05 sta ]row_data+2
14fc: 20 00 14 jsr DrawBullet
14ff: a5 e8 lda bullet3_state+6
1501: 85 03 sta ]row_data
1503: a5 e9 lda bullet3_state+7
1505: 85 04 sta ]row_data+1
1507: a5 ea lda bullet3_state+8
1509: 85 05 sta ]row_data+2
150b: 20 00 14 jsr DrawBullet
150e: 60 rts
150f: 00 .dd1 $00
; Erases, moves, draws all active bullets.
1510: 20 50 14 UpdateBullets jsr MoveBullet1
1513: 20 8e 14 jsr MoveBullet2
1516: 20 d0 14 jsr MoveBullet3
1519: 60 rts
151a: 00 00 00 00+ .junk 6
;
; Alien bitmap addresses.
;
; Aliens are 3x12, explosions are 4x20.
;
1520: 00 alien_gfx_lo .dd1 $00
1521: e0 .dd1 <egg_img_tiny ;1-4 is egg arriving
1522: b0 .dd1 <egg_img_small
1523: 80 .dd1 <egg_img_medium
1524: 50 .dd1 <egg_img_large
1525: 90 .dd1 <alien_img_egg ;5 is egg
1526: 20 .dd1 <egg_hatch_img ;6 is egg hatching
1527: f0 .dd1 <alien_img_spider ;7-10 is hatched alien
1528: 30 .dd1 <alien_img_lips
1529: 60 .dd1 <alien_img_wolf
152a: c0 .dd1 <alien_img_fuzzball
152b: 10 .dd1 <alien_explosion_1 ;11-15 is exploding
152c: 60 .dd1 <alien_explosion_2
152d: 10 .dd1 <alien_explosion_1
152e: 60 .dd1 <alien_explosion_2
152f: 10 .dd1 <alien_explosion_1
1530: 00 alien_gfx_hi .dd1 $00
1531: 72 .dd1 >egg_img_tiny
1532: 72 .dd1 >egg_img_small
1533: 72 .dd1 >egg_img_medium
1534: 72 .dd1 >egg_img_large
1535: 71 .dd1 >alien_img_egg
1536: 72 .dd1 >egg_hatch_img
1537: 71 .dd1 >alien_img_spider
1538: 71 .dd1 >alien_img_lips
1539: 71 .dd1 >alien_img_wolf
153a: 71 .dd1 >alien_img_fuzzball
153b: 73 .dd1 >alien_explosion_1
153c: 73 .dd1 >alien_explosion_2
153d: 73 .dd1 >alien_explosion_1
153e: 73 .dd1 >alien_explosion_2
153f: 73 .dd1 >alien_explosion_1
; Clears a 3x12 area to black. Used to erase aliens.
;
; On entry:
; X: top row
; Y: left column
• Clear variables
]ptr1 .var $00 {addr/2}
]count .var $02 {addr/1}
]start_row .var $04 {addr/1}
]end_row .var $05 {addr/1}
]start_col .var $06 {addr/1}
]end_col .var $07 {addr/1}
1540: a9 0c EraseAlienRect lda #12 ;12 rows
1542: 85 02 sta ]count
1544: bd 00 08 :Loop lda hr_ytable_hi,x
1547: 85 01 sta ]ptr1+1
1549: bd c0 08 lda hr_ytable_lo,x
154c: 85 00 sta ]ptr1
154e: a9 00 lda #$00 ;zero out 3 bytes
1550: 91 00 sta (]ptr1),y
1552: c8 iny
1553: 91 00 sta (]ptr1),y
1555: c8 iny
1556: 91 00 sta (]ptr1),y
1558: 88 dey
1559: 88 dey
155a: ea nop
155b: e8 inx
155c: c6 02 dec ]count
155e: d0 e4 bne :Loop
1560: 60 rts
1561: 00 00 00 00+ .junk 15
;
; Update aliens, erasing / drawing and advancing state as needed.
;
; This is called after copying $x0-x9 to $c0-c9 for one of the alien state sets
; from $20-$80.
;
; The states are:
; 0: dead
; 1-4: arriving (small egg)
; 5: egg
; 6-10: hatched alien
; 11-15: exploding (with score shown)
;
DoUpdateAlienState
1570: a5 c0 lda alien_state ;still alive?
1572: d0 01 bne :Alive ;yes
1574: 60 rts ;no, nothing to do
1575: c9 05 :Alive cmp #$05 ;state 5?
1577: b0 37 bcs HandleEggUpdate ;no, must be 1-4
; Draw eggs as they "zoom in". They don't move, so we don't need to erase
; anything. There are 4 pre-egg stages. We draw the eggs every time but don't
; advance to the next animation frame every time; this is necessary to let them
; pop in gradually without the star field animation overwriting them.
1579: aa tax ;draw the appropriately sized egg
157a: bd 20 15 lda alien_gfx_lo,x
157d: 8d d1 0b sta _DrawBitmapSrc+1
1580: bd 30 15 lda alien_gfx_hi,x
1583: 8d d2 0b sta _DrawBitmapSrc+2
1586: a5 c2 lda alien_row
1588: 85 04 sta ]start_row
158a: 18 clc
158b: 69 0c adc #12 ;bitmap height
158d: 85 05 sta ]end_row
158f: a5 c3 lda alien_col
1591: 85 06 sta ]start_col
1593: 18 clc
1594: 69 03 adc #3 ;bitmap width
1596: 85 07 sta ]end_col
1598: 20 c0 0b jsr DrawBitmap
159b: e6 ce inc egg_arrival_counter ;advance state every 3 frames
159d: a5 ce lda egg_arrival_counter
159f: c9 03 cmp #$03
15a1: b0 01 bcs :Advance
15a3: 60 rts
15a4: e6 c0 :Advance inc alien_state
15a6: a9 00 lda #$00 ;reset counter
15a8: 85 ce sta egg_arrival_counter
15aa: 60 rts
15ab: 00 00 00 00+ .junk 5
15b0: c9 05 HandleEggUpdate cmp #$05 ;is it an egg?
15b2: d0 3c bne HandleEggHatching ;nope
; update egg position
15b4: a5 c2 lda alien_row ;save previous row/col before update
15b6: 85 c4 sta alien_prev_row
15b8: a5 c3 lda alien_col
15ba: 85 c5 sta alien_prev_col
15bc: 20 30 13 jsr MoveEggCheckCollision ;do update
15bf: a5 c0 lda alien_state ;still an egg?
15c1: c9 05 cmp #$05
15c3: d0 2b bne HandleEggHatching ;no, must've been hit
; draw egg
15c5: a6 c4 ldx alien_prev_row
15c7: a4 c5 ldy alien_prev_col
15c9: 20 40 15 jsr EraseAlienRect ;erase previous position
15cc: a9 90 lda #<alien_img_egg ;draw new
15ce: 8d 20 18 sta :_DrawAlienSrc+1
15d1: a9 c6 lda #alien_shift_flag
15d3: 8d fb 17 sta _DpFlag+1
15d6: a5 c2 lda alien_row
15d8: 85 04 sta ]start_row
15da: 18 clc
15db: 69 0c adc #12 ;bitmap height
15dd: 85 05 sta ]end_row
15df: a5 c3 lda alien_col
15e1: 85 06 sta ]start_col
15e3: 18 clc
15e4: 69 03 adc #3 ;bitmap width
15e6: 85 07 sta ]end_col
15e8: 4c f8 17 jmp DrawShiftableAlien
15eb: 00 00 00 00+ .junk 5
HandleEggHatching
15f0: c9 06 cmp #$06 ;state 6?
15f2: d0 2c bne HandleAlien ;nope
; draw hatch image, then set state to hatched alien
15f4: a9 20 lda #<egg_hatch_img
15f6: 8d e1 13 sta _DrawHatchSrc+1
15f9: a9 72 lda #>egg_hatch_img
15fb: 8d e2 13 sta _DrawHatchSrc+2
15fe: a5 c2 lda alien_row
1600: 85 04 sta ]start_row
1602: 18 clc
1603: 69 0c adc #12 ;bitmap width
1605: 85 05 sta ]end_row
1607: a5 c3 lda alien_col
1609: 85 06 sta ]start_col
160b: 18 clc
160c: 69 03 adc #3 ;bitmap height
160e: 85 07 sta ]end_col
1610: 20 d0 13 jsr DrawHatchImage
1613: a5 c1 lda alien_type_index ;get type index (1-4)
1615: 18 clc
1616: 69 06 adc #$06 ;add 6
1618: 85 c0 sta alien_state ;state now 7-10 (hatched alien)
161a: 60 rts
161b: 00 00 00 00+ .junk 5
1620: c9 0b HandleAlien cmp #11 ;exploding?
1622: b0 4c bcs DrawScoreplosion ;yes, go deal with that
; update position and draw alien
1624: a5 c2 lda alien_row
1626: 85 c4 sta alien_prev_row
1628: a5 c3 lda alien_col
162a: 85 c5 sta alien_prev_col
162c: 20 50 13 jsr UpdateAlienPos ;update position, watch for collisions
162f: a5 c0 lda alien_state
1631: c9 0b cmp #$0b
1633: b0 3b bcs DrawScoreplosion
1635: a6 c4 ldx alien_prev_row
1637: a4 c5 ldy alien_prev_col
1639: 20 40 15 jsr EraseAlienRect
163c: a6 c0 ldx alien_state
163e: bd 20 15 lda alien_gfx_lo,x
1641: 8d 20 18 sta :_DrawAlienSrc+1
1644: a9 c9 lda #alien_move_flag
1646: 8d fb 17 sta _DpFlag+1
1649: ea nop
164a: a5 c2 lda alien_row
164c: 85 04 sta ]start_row
164e: 18 clc
164f: 69 0c adc #$0c
1651: 85 05 sta ]end_row
1653: a5 c3 lda alien_col
1655: 85 06 sta ]start_col
1657: 18 clc
1658: 69 03 adc #$03
165a: 85 07 sta ]end_col
165c: 4c f8 17 jmp DrawShiftableAlien
165f: 00 00 00 00+ .junk 17
DrawScoreplosion
1670: c9 10 cmp #16 ;done exploding?
1672: b0 3c bcs EraseScoreplosion ;yes, clean up
1674: ea nop
1675: aa tax
1676: bd 20 15 lda alien_gfx_lo,x
1679: 8d d1 0b sta _DrawBitmapSrc+1
167c: bd 30 15 lda alien_gfx_hi,x
167f: 8d d2 0b sta _DrawBitmapSrc+2
1682: a5 c2 lda alien_row ;set center position
1684: 38 sec
1685: e9 04 sbc #$04
1687: 85 04 sta ]start_row
1689: 18 clc
168a: 69 14 adc #20 ;bitmap height
168c: 85 05 sta ]end_row
168e: a5 c3 lda alien_col
1690: 38 sec
1691: e9 01 sbc #$01
1693: 09 01 ora #$01 ;set to odd column
1695: 85 06 sta ]start_col
1697: 18 clc
1698: 69 04 adc #4 ;bitmap width
169a: 85 07 sta ]end_col
169c: 20 c0 0b jsr DrawBitmap
169f: e6 c0 inc alien_state
16a1: 20 00 45 jsr DrawAlienScore
16a4: 20 00 43 jsr _MakeChirp
16a7: 60 rts
16a8: 00 00 00 00+ .junk 8
;
; Erases the explosion-with-score.
;
• Clear variables
]ptr1 .var $00 {addr/2}
]end_row .var $05 {addr/1}
EraseScoreplosion
16b0: a9 00 lda #$00
16b2: 85 c0 sta alien_state
16b4: a5 c2 lda alien_row ;scoreplosion row
16b6: 38 sec
16b7: e9 04 sbc #4 ;start 4 above
16b9: aa tax
16ba: 18 clc
16bb: 69 14 adc #20 ;end 16 below
16bd: 85 05 sta ]end_row
16bf: bd 00 08 :Loop lda hr_ytable_hi,x
16c2: 85 01 sta ]ptr1+1
16c4: bd c0 08 lda hr_ytable_lo,x
16c7: 85 00 sta ]ptr1
16c9: a5 c3 lda alien_col ;scoreplosion column
16cb: 38 sec
16cc: e9 01 sbc #$01 ;start 1 left
16ce: 09 01 ora #$01 ;but make sure we're on an odd column
16d0: a8 tay
16d1: a9 00 lda #$00 ;clear 4 bytes to black
16d3: 91 00 sta (]ptr1),y
16d5: c8 iny
16d6: 91 00 sta (]ptr1),y
16d8: c8 iny
16d9: 91 00 sta (]ptr1),y
16db: c8 iny
16dc: 91 00 sta (]ptr1),y
16de: e8 inx
16df: e4 05 cpx ]end_row
16e1: 90 dc bcc :Loop
16e3: 20 10 45 jsr AddKillScore
16e6: 60 rts
16e7: 00 00 00 00+ .junk 25
;
; Checks for collisions between bullets and the current alien. All 3 bullets
; are checked.
;
; On exit, $cd will be set to zero if a collision was detected.
;
]coll_left .var $04 {addr/1}
]coll_right .var $05 {addr/1}
CheckBulletCollision
1700: a5 d0 lda bullet1_fired
1702: d0 03 bne :Check1
1704: 4c 50 17 :NoColl1 jmp CheckBulletCollision2
1707: a5 d1 :Check1 lda bullet1_row ;past top?
1709: c5 c2 cmp alien_row
170b: 90 f7 bcc :NoColl1 ;yes, miss
170d: 38 sec
170e: e9 13 sbc #19 ;check bottom (alien height 12, bullet 6)
1710: c5 c2 cmp alien_row
1712: b0 f0 bcs :NoColl1 ;miss
1714: a5 d2 lda bullet1_col ;check horizontal
1716: 38 sec
1717: e9 02 sbc #$02
1719: 85 04 sta ]coll_left
171b: 18 clc
171c: 69 04 adc #$04
171e: 85 05 sta ]coll_right
1720: a5 d3 lda bullet1_img_00 ;does bullet occupy first column?
1722: d0 05 bne :TowardLeft ;yes, check for collision there
1724: e6 04 inc ]coll_left ;no, adjust hit box to right
1726: 4c 2b 17 jmp L172B
1729: c6 05 :TowardLeft dec ]coll_right
172b: a5 c3 L172B lda alien_col ;check the bounds
172d: c5 04 cmp ]coll_left
172f: 90 d3 bcc :NoColl1
1731: c5 05 cmp ]coll_right
1733: b0 cf bcs :NoColl1
; collision detected; discard bullet, set flag
1735: a6 d1 ldx bullet1_row
1737: a4 d2 ldy bullet1_col
1739: 20 28 14 jsr EraseBullet
173c: a9 00 lda #$00
173e: 85 d0 sta bullet1_fired
1740: 85 cd sta collision_flag
1742: 60 rts
1743: ea 00 00 00+ .junk 13
; Do it all again, for bullet #2.
CheckBulletCollision2
1750: a5 d9 lda bullet2_fired
1752: d0 03 bne L1757
1754: 4c a0 17 :NoColl2 jmp CheckBulletCollision3
1757: a5 da L1757 lda bullet2_row
1759: c5 c2 cmp alien_row
175b: 90 f7 bcc :NoColl2
175d: 38 sec
175e: e9 13 sbc #$13
1760: c5 c2 cmp alien_row
1762: b0 f0 bcs :NoColl2
1764: a5 db lda bullet2_state+2
1766: 38 sec
1767: e9 02 sbc #$02
1769: 85 04 sta ]coll_left
176b: 18 clc
176c: 69 04 adc #$04
176e: 85 05 sta ]coll_right
1770: a5 dc lda bullet2_state+3
1772: d0 05 bne :DecRight
1774: e6 04 inc ]coll_left
1776: 4c 7b 17 jmp :IncLeft
1779: c6 05 :DecRight dec ]coll_right
177b: a5 c3 :IncLeft lda alien_col
177d: c5 04 cmp ]coll_left
177f: 90 d3 bcc :NoColl2
1781: c5 05 cmp ]coll_right
1783: b0 cf bcs :NoColl2
1785: a6 da ldx bullet2_row
1787: a4 db ldy bullet2_state+2
1789: 20 28 14 jsr EraseBullet
178c: a9 00 lda #$00
178e: 85 d9 sta bullet2_fired
1790: 85 cd sta collision_flag
1792: 60 rts
1793: ea 00 00 00+ .junk 13
; Repeat for bullet #3.
CheckBulletCollision3
17a0: a5 e2 lda bullet3_state
17a2: d0 03 bne L17A7
17a4: 60 :NoColl3 rts
17a5: ea ea .junk 2
17a7: a5 e3 L17A7 lda bullet3_row
17a9: c5 c2 cmp alien_row
17ab: 90 f7 bcc :NoColl3
17ad: 38 sec
17ae: e9 13 sbc #$13
17b0: c5 c2 cmp alien_row
17b2: b0 f0 bcs :NoColl3
17b4: a5 e4 lda bullet3_state+2
17b6: 38 sec
17b7: e9 02 sbc #$02
17b9: 85 04 sta ]coll_left
17bb: 18 clc
17bc: 69 04 adc #$04
17be: 85 05 sta ]coll_right
17c0: a5 e5 lda bullet3_state+3
17c2: d0 05 bne L17C9
17c4: e6 04 inc ]coll_left
17c6: 4c cb 17 jmp L17CB
17c9: c6 05 L17C9 dec ]coll_right
17cb: a5 c3 L17CB lda alien_col
17cd: c5 04 cmp ]coll_left
17cf: 90 d3 bcc :NoColl3
17d1: c5 05 cmp ]coll_right
17d3: b0 cf bcs :NoColl3
17d5: a6 e3 ldx bullet3_row
17d7: a4 e4 ldy bullet3_state+2
17d9: 20 28 14 jsr EraseBullet
17dc: a9 00 lda #$00
17de: 85 e2 sta bullet3_state
17e0: 85 cd sta collision_flag
17e2: 60 rts
17e3: ea 00 00 00+ .junk 21
;
; Draws eggs and aliens. The color set changes when eggs and aliens change
; direction; the current color mode is specified by a flag ($c6 for eggs, $c9
; for aliens).
;
; The low byte of _draw_alien_src is set up by the caller. The high byte is set
; here, to select from bitmap set 1 ($71xx) or set 2 ($7dxx).
;
• Clear variables
]start_row .var $04 {addr/1}
]end_row .var $05 {addr/1}
]start_col .var $06 {addr/1}
]end_col .var $07 {addr/1}
DrawShiftableAlien
17f8: a0 90 ldy #BCC_inst ;configure low bit check depending on which set
17fa: a5 c6 _DpFlag lda alien_shift_flag ; we want to be showing (green vs. purple, etc.)
17fc: f0 02 beq :Zero
17fe: a0 b0 ldy #BCS_inst
1800: 8c 08 18 :Zero sty :_Test
1803: a5 06 lda ]start_col ;check odd vs. even column
1805: a0 71 ldy #>alien_img_egg
1807: 4a lsr A ;shift low bit into carry
1808: b0 02 :_Test bcs L180C ;BCC or BCS based on flag
180a: a0 7d ldy #>alien_img_egg2
180c: 8c 21 18 L180C sty :_DrawAlienSrc+2
180f: a6 04 ldx ]start_row
1811: bd 00 08 :OuterLoop lda hr_ytable_hi,x
1814: 8d 24 18 sta :_DrawAlienDst+2
1817: bd c0 08 lda hr_ytable_lo,x
181a: 8d 23 18 sta :_DrawAlienDst+1
181d: a4 06 ldy ]start_col
181f: ad 14 72 :_DrawAlienSrc lda L7214
1822: 99 50 3c :_DrawAlienDst sta $3c50,y
1825: ee 20 18 inc :_DrawAlienSrc+1
1828: d0 03 bne :NoInc
182a: ee 21 18 inc :_DrawAlienSrc+2
182d: c8 :NoInc iny
182e: c4 07 cpy ]end_col
1830: 90 ed bcc :_DrawAlienSrc
1832: e8 inx
1833: e4 05 cpx ]end_row
1835: 90 da bcc :OuterLoop
1837: 60 rts
1838: ea f0 03 00+ .junk 8
; Standard pattern is 0-1-2-3-4-5-6-7.
; Reverse pattern is 4-3-2-1-0-7-6-5.
1840: 04 03 02 01+ reverse_dir .bulk 0403020100070605
1848: c5 cc d0 06+ .junk 10
;
; Egg movement.
;
; Eggs move in a given direction 4x, starting with direction 0. After 4x, the
; direction is incremented. This results in a roughly circular pattern,
; starting from the top and moving clockwise:
; 0 right
; 1 right+down
; 2 down
; 3 left+down
; 4 left
; 5 left+up
; 6 up
; 7 right+up
;
; The caller reverses direction when we're 2 moves into direction 0.
;
1852: a5 c6 MoveEgg lda alien_shift_flag ;moving opposite?
1854: d0 0f bne :Normal ;no
1856: a6 c7 ldx alien_move_direction ;yes, move in opposite pattern
1858: bd 40 18 lda reverse_dir,x
185b: 4c 67 18 jmp :Cont
185e: 03 38 e9 08+ .junk 7
1865: a5 c7 :Normal lda alien_move_direction
1867: c9 00 :Cont cmp #$00 ;direction 0?
1869: d0 17 bne :Not0
186b: e6 c3 inc alien_col ;move right
; update count and possibly direction after each movement
186d: c6 c8 :UpdateDir dec alien_dir_move_count ;out of moves?
186f: d0 10 bne L1881 ;not yet
1871: a9 04 lda #$04 ;yes, reset count
1873: 85 c8 sta alien_dir_move_count
1875: e6 c7 inc alien_move_direction ;update direction
1877: a5 c7 lda alien_move_direction
1879: c9 08 cmp #$08 ;still 0-7?
187b: 90 04 bcc L1881 ;yes
187d: a9 00 lda #$00 ;nope, set dir to 0
187f: 85 c7 sta alien_move_direction
1881: 60 L1881 rts
1882: c9 01 :Not0 cmp #$01
1884: d0 0c bne :Not1
1886: e6 c3 inc alien_col ;move right and down
1888: a5 c2 lda alien_row
188a: 18 clc
188b: 69 04 adc #$04
188d: 85 c2 sta alien_row
188f: 4c 6d 18 jmp :UpdateDir
1892: c9 02 :Not1 cmp #$02
1894: d0 0a bne :Not2
1896: a5 c2 lda alien_row ;move down
1898: 18 clc
1899: 69 04 adc #$04
189b: 85 c2 sta alien_row
189d: 4c 6d 18 jmp :UpdateDir
18a0: c9 03 :Not2 cmp #$03
18a2: d0 0c bne :Not3
18a4: c6 c3 dec alien_col ;move left and down
18a6: a5 c2 lda alien_row
18a8: 18 clc
18a9: 69 04 adc #$04
18ab: 85 c2 sta alien_row
18ad: 4c 6d 18 jmp :UpdateDir
18b0: c9 04 :Not3 cmp #$04 ;move left
18b2: d0 05 bne :Not4
18b4: c6 c3 dec alien_col
18b6: 4c 6d 18 jmp :UpdateDir
18b9: c9 05 :Not4 cmp #$05
18bb: d0 0c bne :Not5
18bd: c6 c3 dec alien_col ;move left and up
18bf: a5 c2 lda alien_row
18c1: 38 sec
18c2: e9 04 sbc #$04
18c4: 85 c2 sta alien_row
18c6: 4c 6d 18 jmp :UpdateDir
18c9: c9 06 :Not5 cmp #$06
18cb: d0 0a bne :Not6
18cd: a5 c2 lda alien_row ;move up
18cf: 38 sec
18d0: e9 04 sbc #$04
18d2: 85 c2 sta alien_row
18d4: 4c 6d 18 jmp :UpdateDir
18d7: c9 07 :Not6 cmp #$07
18d9: d0 0c bne :Not7
18db: e6 c3 inc alien_col ;move right and up
18dd: a5 c2 lda alien_row
18df: 38 sec
18e0: e9 04 sbc #$04
18e2: 85 c2 sta alien_row
18e4: 4c 6d 18 jmp :UpdateDir
18e7: 60 :Not7 rts
18e8: 00 00 00 00+ .junk 24
UpdateEggPosition
1900: a5 c8 lda alien_dir_move_count ;two moves left?
1902: c9 02 cmp #$02
1904: d0 0c bne :SameDir
1906: a5 c7 lda alien_move_direction ;currently in direction 0?
1908: c9 00 cmp #$00
190a: d0 06 bne :SameDir
190c: a5 c6 lda alien_shift_flag ;both conditions are true; reverse direction
190e: 49 ff eor #$ff
1910: 85 c6 sta alien_shift_flag
1912: 4c 52 18 :SameDir jmp MoveEgg
1915: 00 00 00 00+ .junk 59
alien_vertical_speed
1950: 00 04 06 08+ .bulk 000406080a ;vertical speed, based on alien type
1955: 00 00 00 .junk 3
; Move alien down. Speed is determined by alien type.
1958: a6 c1 MoveAlienDown ldx alien_type_index
195a: bd 50 19 lda alien_vertical_speed,x
195d: 18 clc
195e: 65 c2 adc alien_row
1960: c9 aa cmp #170 ;at lowest row (bottom of ship)?
1962: 90 09 bcc :NoRev ;not yet
1964: a9 00 lda #$00 ;yes, change direction to up
1966: 85 c9 sta alien_move_flag
1968: a9 01 lda #$01 ;change dir after 1 step
196a: 85 c8 sta alien_dir_move_count
196c: 60 rts
196d: 85 c2 :NoRev sta alien_row
196f: 60 rts
1970: 00 00 00 00+ .junk 8
; Move alien up. Speed is determined by alien type.
1978: a6 c1 MoveAlienUp ldx alien_type_index
197a: bd 50 19 lda alien_vertical_speed,x
197d: 85 00 sta $00
197f: a5 c2 lda alien_row
1981: 38 sec
1982: e5 00 sbc $00
1984: c9 40 cmp #64 ;at highest row?
1986: b0 09 bcs :NoRev ;not yet
1988: a9 ff lda #$ff ;yes, change direction to down
198a: 85 c9 sta alien_move_flag
198c: a9 01 lda #$01 ;change dir after 1 step
198e: 85 c8 sta alien_dir_move_count
1990: 60 rts
1991: 85 c2 :NoRev sta alien_row
1993: 60 rts
1994: 00 00 00 00+ .junk 12
; Move an alien to the right, homing in on the ship.
MoveAlienRightHoming
19a0: c6 c3 dec alien_col
19a2: a5 c2 lda alien_row
19a4: c9 70 cmp #112
19a6: b0 2a bcs L19D2
19a8: a5 c3 lda alien_col
19aa: c5 f9 cmp ship_pos_coarse ;are we there yet?
19ac: b0 0a bcs :NoInc
19ae: e6 c3 inc alien_col
19b0: a9 05 lda #$05 ;advance to next direction (left+down)
19b2: 85 c7 sta alien_move_direction
19b4: a9 04 lda #$04
19b6: 85 c8 sta alien_dir_move_count
19b8: 60 :NoInc rts
; Move an alien to the left, homing in on the ship.
MoveAlienLeftHoming
19b9: e6 c3 inc alien_col
19bb: a5 c2 lda alien_row
19bd: c9 70 cmp #112
19bf: b0 11 bcs L19D2
19c1: a5 c3 lda alien_col
19c3: c5 f9 cmp ship_pos_coarse
19c5: 90 0a bcc :NoInc
19c7: c6 c3 dec alien_col
19c9: a9 01 lda #$01 ;advance to next direction (right+down)
19cb: 85 c7 sta alien_move_direction
19cd: a9 04 lda #$04
19cf: 85 c8 sta alien_dir_move_count
19d1: 60 :NoInc rts
19d2: e6 c7 L19D2 inc alien_move_direction
19d4: a9 04 lda #$04
19d6: 85 c8 sta alien_dir_move_count
19d8: 60 rts
19d9: 00 00 00 00+ .junk 39
MoveAlien_Downish
1a00: a5 c7 lda alien_move_direction ;which way should it move?
1a02: d0 04 bne :Not0
1a04: 20 b9 19 jsr MoveAlienLeftHoming ;0=left
1a07: 60 rts
1a08: c9 01 :Not0 cmp #$01
1a0a: d0 0c bne :Not1
1a0c: 20 58 19 jsr MoveAlienDown ;1=down+right
1a0f: a5 c7 lda alien_move_direction ;was direction updated?
1a11: c9 01 cmp #$01
1a13: d0 02 bne L1A17
1a15: e6 c3 inc alien_col
1a17: 60 L1A17 rts
1a18: c9 02 :Not1 cmp #$02
1a1a: d0 04 bne :Not2
1a1c: 20 58 19 jsr MoveAlienDown ;2=down
1a1f: 60 rts
1a20: c9 03 :Not2 cmp #$03
1a22: d0 06 bne :Not3
1a24: 20 58 19 jsr MoveAlienDown ;3=down+left
1a27: c6 c3 dec alien_col
1a29: 60 rts
1a2a: c9 04 :Not3 cmp #$04
1a2c: d0 04 bne :Not4
1a2e: 20 a0 19 jsr MoveAlienRightHoming ;4=right
1a31: 60 rts
1a32: c9 05 :Not4 cmp #$05
1a34: d0 0c bne :Not5
1a36: 20 58 19 jsr MoveAlienDown ;5=down+left
1a39: a5 c7 lda alien_move_direction ;was direction updated?
1a3b: c9 05 cmp #$05
1a3d: d0 02 bne L1A41
1a3f: c6 c3 dec alien_col
1a41: 60 L1A41 rts
1a42: c9 06 :Not5 cmp #$06
1a44: d0 04 bne :Not6
1a46: 20 58 19 jsr MoveAlienDown ;6=down
1a49: 60 rts
1a4a: c9 07 :Not6 cmp #$07
1a4c: d0 05 bne :Not7
1a4e: 20 58 19 jsr MoveAlienDown ;7=down+right
1a51: e6 c3 inc alien_col
1a53: 60 :Not7 rts
1a54: 00 00 00 00+ .junk 12
UpdateAlienMoveDir_Downish
1a60: 20 00 1a jsr MoveAlien_Downish
1a63: a5 c7 lda alien_move_direction
1a65: f0 18 beq L1A7F ;dir=0 (right) using homing
1a67: c9 04 cmp #$04 ; when moving generally downward
1a69: f0 14 beq L1A7F ;as does dir=4 (left)
1a6b: c6 c8 dec alien_dir_move_count ;update counter
1a6d: d0 10 bne L1A7F ;move moves left
1a6f: a9 04 lda #$04 ;no, advance to next direction
1a71: 85 c8 sta alien_dir_move_count ; and move that way 4x
1a73: e6 c7 inc alien_move_direction
1a75: a5 c7 lda alien_move_direction
1a77: c9 08 cmp #$08 ;did we wrap around?
1a79: 90 04 bcc L1A7F
1a7b: a9 00 lda #$00 ;yes, back to zero
1a7d: 85 c7 sta alien_move_direction
1a7f: 60 L1A7F rts
1a80: a5 c7 MoveAlien_Upish lda alien_move_direction
1a82: d0 03 bne :Not0
1a84: e6 c3 inc alien_col ;0 = right
1a86: 60 rts
1a87: c9 01 :Not0 cmp #$01
1a89: d0 06 bne :Not1
1a8b: e6 c3 inc alien_col ;1 = right + up
1a8d: 20 78 19 jsr MoveAlienUp
1a90: 60 rts
1a91: c9 02 :Not1 cmp #$02
1a93: d0 04 bne :Not2
1a95: 20 78 19 jsr MoveAlienUp ;2 = up
1a98: 60 rts
1a99: c9 03 :Not2 cmp #$03
1a9b: d0 06 bne :Not3
1a9d: 20 78 19 jsr MoveAlienUp ;3 = left + up
1aa0: c6 c3 dec alien_col
1aa2: 60 rts
1aa3: c9 04 :Not3 cmp #$04
1aa5: d0 03 bne :Not4
1aa7: c6 c3 dec alien_col ;4 = left
1aa9: 60 rts
1aaa: c9 05 :Not4 cmp #$05
1aac: d0 06 bne :Not5
1aae: 20 78 19 jsr MoveAlienUp ;5 = left + up
1ab1: c6 c3 dec alien_col
1ab3: 60 rts
1ab4: c9 06 :Not5 cmp #$06
1ab6: d0 04 bne :Not6
1ab8: 20 78 19 jsr MoveAlienUp ;6 = up
1abb: 60 rts
1abc: c9 07 :Not6 cmp #$07
1abe: d0 05 bne :Not7
1ac0: 20 78 19 jsr MoveAlienUp ;7 = right + up
1ac3: e6 c3 inc alien_col
1ac5: 60 :Not7 rts
1ac6: 00 00 00 00+ .junk 10
UpdateAlienMoveDir_Upish
1ad0: 20 80 1a jsr MoveAlien_Upish
1ad3: c6 c8 dec alien_dir_move_count ;have we moved this way 4x?
1ad5: d0 10 bne L1AE7 ;not yet
1ad7: e6 c7 inc alien_move_direction ;yes, advance to next direction
1ad9: a9 04 lda #$04 ;reset count
1adb: 85 c8 sta alien_dir_move_count
1add: a5 c7 lda alien_move_direction ;clamp to 0-7
1adf: c9 08 cmp #$08
1ae1: 90 04 bcc L1AE7
1ae3: a9 00 lda #$00
1ae5: 85 c7 sta alien_move_direction
1ae7: 60 L1AE7 rts
1ae8: 00 00 00 00+ .junk 8
;
; Top level function for alien movement.
;
; The first 3 types of aliens use the same movement pattern, but their vertical
; speed is significantly different, which gives spiders and wolves a very
; different feeling. Mostly the ships walk through a set pattern (moves 0-7).
; The upward/downward flag is flipped when a certain row is reached.
;
; # upward downward
; 0 left right (homing)
; 1 right+down +up
; 2 down up
; 3 left+down +up
; 4 right left (homing)
; 5 left+down +up
; 6 down up
; 7 right+down +up
;
; When in the downward phase, directions 0 and 4 do not advance until the alien
; reaches the same column as the ship.
;
; None of this applies to fuzzballs, which have a very linear homing pattern.
;
1af0: a5 c9 MoveAlien lda alien_move_flag ;up or down?
1af2: f0 06 beq :Move1
1af4: 20 60 1a jsr UpdateAlienMoveDir_Downish
1af7: 4c fd 1a jmp :Move2
1afa: 20 d0 1a :Move1 jsr UpdateAlienMoveDir_Upish
1afd: a5 c3 :Move2 lda alien_col
1aff: d0 05 bne :NotLeft ;at left edge?
1b01: a9 01 lda #$01 ;yes, move it back in
1b03: 85 c3 sta alien_col
1b05: 60 L1B05 rts
1b06: c9 25 :NotLeft cmp #37 ;at right edge? (aliens are 3 bytes wide)
1b08: 90 fb bcc L1B05
1b0a: a9 24 lda #36 ;yes, move back in
1b0c: 85 c3 sta alien_col
1b0e: 60 rts
1b0f: 00 00 00 00+ .junk 17
; Fuzzball movement homes in on ship.
MoveFuzzballDown
1b20: a5 c3 lda alien_col
1b22: c5 f9 cmp ship_pos_coarse ;are we lined up on the ship?
1b24: f0 09 beq :MoveDown ;yes, just move down
1b26: 90 05 bcc :MoveRight ;we're to the left, move right
1b28: c6 c3 dec alien_col ;we're to the right, move left
1b2a: 4c 2f 1b jmp :MoveDown
1b2d: e6 c3 :MoveRight inc alien_col
1b2f: 20 58 19 :MoveDown jsr MoveAlienDown
1b32: 60 rts
1b33: 00 00 00 00+ .junk 13
1b40: a5 c3 MoveFuzzballUp lda alien_col
1b42: c5 f9 cmp ship_pos_coarse ;are we lined up on the ship?
1b44: f0 09 beq :MoveUp ;yes, just move up
1b46: 90 05 bcc :MoveRight ;we're to the left, move right
1b48: c6 c3 dec alien_col ;we're to the right, move left
1b4a: 4c 2f 1b jmp :MoveDown ;BUG - should be MoveUp
1b4d: e6 c3 :MoveRight inc alien_col
1b4f: 20 78 19 :MoveUp jsr MoveAlienUp
1b52: 60 rts
1b53: 00 00 00 00+ .junk 13
; Aggressively move toward the ship while moving up or down (fuzzballs only).
1b60: a5 c9 MoveAlienSeek lda alien_move_flag
1b62: d0 bc bne MoveFuzzballDown
1b64: 4c 40 1b jmp MoveFuzzballUp
1b67: 00 00 00 00+ .junk 25
; Ship dimensions for collision detection. Each table has 4 entries, one for
; each ship stage (remember, stage 4 is 1+2 after the ship merge).
1b80: 04 05 05 05 ship_dim_left .bulk 04050505 ;left-of-center width
1b84: 03 04 05 04 ship_dim_right .bulk 03040504 ;right-of-center width
1b88: 98 96 96 90 ship_dim_top .bulk 98969690 ;topmost row
1b8c: a8 a8 a8 a8 ship_dim_bottom .bulk a8a8a8a8 ;bottom-most row
• Clear variables
]coll_top .var $00 {addr/1}
]coll_bottom .var $01 {addr/1}
]coll_left .var $02 {addr/1}
]coll_right .var $03 {addr/1}
CheckShipCollision
1b90: a5 f8 lda ship_stage ;make sure we're 1-4 (not dead or exploding)
1b92: f0 04 beq :NoCheck
1b94: c9 05 cmp #$05
1b96: 90 01 bcc :DoCheck
1b98: 60 :NoCheck rts
1b99: aa :DoCheck tax
1b9a: ca dex
1b9b: a5 f9 lda ship_pos_coarse ;get ship position to nearest two bytes
1b9d: 38 sec
1b9e: fd 80 1b sbc ship_dim_left,x ;subtract left width
1ba1: 85 02 sta ]coll_left
1ba3: a5 f9 lda ship_pos_coarse
1ba5: 18 clc
1ba6: 7d 84 1b adc ship_dim_right,x ;add right width
1ba9: 85 03 sta ]coll_right
1bab: bd 88 1b lda ship_dim_top,x ;pull top/bottom out of table
1bae: 85 00 sta ]coll_top
1bb0: bd 8c 1b lda ship_dim_bottom,x
1bb3: 85 01 sta ]coll_bottom
; see if hitboxes overlap
1bb5: a5 c2 lda alien_row
1bb7: c5 00 cmp ]coll_top
1bb9: b0 01 bcs :InTop
1bbb: 60 :NoColl rts
1bbc: c5 01 :InTop cmp ]coll_bottom
1bbe: b0 fb bcs :NoColl
1bc0: a5 c3 lda alien_col
1bc2: c5 02 cmp ]coll_left
1bc4: 90 f5 bcc :NoColl
1bc6: c5 03 cmp ]coll_right
1bc8: b0 f1 bcs :NoColl
; Collision! Make everybody explode and update game state.
1bca: a5 f8 lda ship_stage ;advance to next life
1bcc: 85 f6 sta ship_life
1bce: a9 05 lda #$05 ;set stage to 5 (exploding)
1bd0: 85 f8 sta ship_stage
1bd2: a5 f9 lda ship_pos_coarse ;adjust position to center explosion
1bd4: 38 sec
1bd5: e9 04 sbc #$04
1bd7: 85 f4 sta ship_left_byte_pos
1bd9: a9 0b lda #11 ;blow up the alien too
1bdb: 85 c0 sta alien_state
1bdd: 20 70 1c jsr EraseExhaustAfterDeath ;delete exhaust plume
1be0: a9 00 lda #$00
1be2: 85 cd sta collision_flag
1be4: a9 06 lda #$06
1be6: 85 f2 sta explosion_counter
1be8: 60 rts
1be9: 00 00 00 00+ .junk 7
; Ship explosion pointers. Bitmaps are 10x24.
ship_explosion_lo
1bf0: 40 .dd1 <explode0
1bf1: 30 .dd1 <explode1
1bf2: 20 .dd1 <explode2
1bf3: 10 .dd1 <explode3
1bf4: 00 .dd1 <explode4
1bf5: f0 .dd1 <explode5
1bf6: e0 .dd1 <explode6
ship_explosion_hi
1bf7: 76 .dd1 >explode0
1bf8: 77 .dd1 >explode1
1bf9: 78 .dd1 >explode2
1bfa: 79 .dd1 >explode3
1bfb: 7a .dd1 >explode4
1bfc: 7a .dd1 >explode5
1bfd: 7b .dd1 >explode6
1bfe: 00 00 .junk 2
;
; Draws the animated ship explosion.
;
; The animation frame is stored in the ship stage (5-11).
;
• Clear variables
]start_row .var $04 {addr/1}
]end_row .var $05 {addr/1}
]start_col .var $06 {addr/1}
]end_col .var $07 {addr/1}
DrawShipExplosion
1c00: a5 f4 lda ship_left_byte_pos
1c02: 18 clc
1c03: 69 0a adc #10 ;bitmap width
1c05: 85 05 sta ]end_row
1c07: a5 f8 lda ship_stage ;get ship stage, which will be >= 5
1c09: 38 sec
1c0a: e9 05 sbc #$05 ;subtract 5 to get animation frame
1c0c: aa tax
1c0d: bd f0 1b lda ship_explosion_lo,x ;get animation frame addr
1c10: 8d 2a 1c sta :_ImageSrc+1
1c13: bd f7 1b lda ship_explosion_hi,x
1c16: 8d 2b 1c sta :_ImageSrc+2
1c19: a2 96 ldx #150 ;top row of explosion
1c1b: bd 00 08 :Loop lda hr_ytable_hi,x
1c1e: 8d 2e 1c sta :_ImageDst+2
1c21: bd c0 08 lda hr_ytable_lo,x
1c24: 8d 2d 1c sta :_ImageDst+1
1c27: a4 f4 ldy ship_left_byte_pos
1c29: ad 00 20 :_ImageSrc lda HIRES_PAGE_1
1c2c: 99 00 20 :_ImageDst sta HIRES_PAGE_1,y
1c2f: ee 2a 1c inc :_ImageSrc+1
1c32: d0 03 bne :NoInc
1c34: ee 2b 1c inc :_ImageSrc+2
1c37: c8 :NoInc iny
1c38: c4 05 cpy ]end_row
1c3a: 90 ed bcc :_ImageSrc
1c3c: e8 inx
1c3d: e0 ae cpx #174 ;bitmap height is (174-150)=24
1c3f: 90 da bcc :Loop
1c41: c6 f2 dec explosion_counter
1c43: f0 03 beq L1C48 ;counter has zeroed, chirp and reset
1c45: c6 f8 dec ship_stage ;counter didn't zero, dec the ship stage
1c47: 60 rts
1c48: a9 06 L1C48 lda #$06 ;every 6 frames we chirp
1c4a: 85 f2 sta explosion_counter
1c4c: 4c 00 43 jmp _MakeChirp
1c4f: 00 .dd1 $00
; Used to erase ships and aliens from the screen after they have died. Not used
; for general animations.
;
; On entry:
; $04/05: start row, end row
; $06/07: start col, end col
;
; End values are exclusive, so (end-start) is count.
EraseRectAfterDeath
1c50: a6 04 ldx ]start_row
1c52: bd 00 08 :Loop lda hr_ytable_hi,x
1c55: 8d 64 1c sta :_EraseRectAddr+2
1c58: bd c0 08 lda hr_ytable_lo,x
1c5b: 8d 63 1c sta :_EraseRectAddr+1
1c5e: a4 06 ldy ]start_col
1c60: a9 00 lda #$00
1c62: 99 00 20 :_EraseRectAddr sta HIRES_PAGE_1,y
1c65: c8 iny
1c66: c4 07 cpy ]end_col
1c68: 90 f8 bcc :_EraseRectAddr
1c6a: e8 inx
1c6b: e4 05 cpx ]end_row
1c6d: 90 e3 bcc :Loop
1c6f: 60 rts
; Erases the ship exhaust after the player is killed. (The player's ship is
; part of an explosion animation.)
EraseExhaustAfterDeath
1c70: a9 aa lda #170 ;clear line 170 to 190
1c72: 85 04 sta ]start_row
1c74: 18 clc
1c75: 69 15 adc #21
1c77: 85 05 sta ]end_row
1c79: a5 f9 lda ship_pos_coarse
1c7b: 38 sec
1c7c: e9 02 sbc #$02 ;from 2 bytes on the left...
1c7e: 85 06 sta ]start_col
1c80: 18 clc
1c81: 69 07 adc #$07 ;to 4 bytes on the right
1c83: 85 07 sta ]end_col
1c85: 4c 50 1c jmp EraseRectAfterDeath
1c88: 00 00 00 00+ .junk 8
EraseShipAfterDeath
1c90: a5 f4 lda ship_left_byte_pos ;start from leftmost ship position
1c92: 85 06 sta ]start_col
1c94: 18 clc
1c95: 69 0a adc #10 ;widest ship (stage 3) is 10 bytes wide
1c97: 85 07 sta ]end_col
1c99: a9 92 lda #146 ;clear line 146 to 169
1c9b: 85 04 sta ]start_row
1c9d: 18 clc
1c9e: 69 18 adc #24
1ca0: 85 05 sta ]end_row
1ca2: 4c 50 1c jmp EraseRectAfterDeath
1ca5: 00 00 00 00+ .junk 11
CheckAllAliensDead
1cb0: a9 00 lda #$00
1cb2: c5 20 cmp alien0
1cb4: d0 1b bne :NotDead
1cb6: c5 30 cmp alien1
1cb8: d0 17 bne :NotDead
1cba: c5 40 cmp alien2
1cbc: d0 13 bne :NotDead
1cbe: c5 50 cmp alien3
1cc0: d0 0f bne :NotDead
1cc2: c5 60 cmp alien4
1cc4: d0 0b bne :NotDead
1cc6: c5 70 cmp alien5
1cc8: d0 07 bne :NotDead
1cca: c5 80 cmp alien6
1ccc: d0 03 bne :NotDead
1cce: 4c d2 1c jmp AllAliensAreDead
1cd1: 60 :NotDead rts
AllAliensAreDead
1cd2: 20 c4 13 jsr CheckDoubleShip
1cd5: 20 a0 1d jsr InitAlienStates
1cd8: e6 bf inc wave_num ;advance to next wave
1cda: 60 rts
1cdb: 00 00 00 00+ .junk 5
; Does the white-in-black-out transition, draws the score and high score text,
; and marks all aliens as dead. Stores 192 in $0a for the animated ship fly-in.
PrepareScreenInitRow
1ce0: 20 40 43 jsr TransitionToBlank
1ce3: a9 c0 lda #192
1ce5: 85 0a sta $0a
1ce7: 20 80 43 jsr DrawScoreBase
1cea: 20 10 44 jsr DrawCurScore
1ced: 4c a0 1e jmp ZeroAliensDrawHighScore
1cf0: e6 bb ChirpEvery4 inc chirp_counter
1cf2: a5 bb lda chirp_counter
1cf4: c9 04 cmp #$04
1cf6: b0 01 bcs :DoChirp
1cf8: 60 rts
1cf9: a9 00 :DoChirp lda #$00
1cfb: 85 bb sta chirp_counter
1cfd: 4c 00 43 jmp _MakeChirp
1d00: a5 f6 NextLife lda ship_life ;what stage of life are we at?
1d02: d0 03 bne :NextLife1 ;not zero, branch
1d04: 4c 40 1d :ZeroOrGE3 jmp NextLife_0_3plus ;0 or >= 3; 4 requires special handling
1d07: c9 03 :NextLife1 cmp #$03 ;>= 3?
1d09: b0 f9 bcs :ZeroOrGE3 ;yup
1d0b: 18 clc ;ship_life is 1 or 2
1d0c: 69 01 adc #$01 ;set ship stage to 2 or 3
1d0e: 85 f8 sta ship_stage
1d10: a9 13 lda #19 ;put ship in center
1d12: 85 f9 sta ship_pos_coarse
1d14: a9 00 lda #$00
1d16: 85 fa sta ship_pos_fine
1d18: 85 fb sta ship_position_abs ;(overwritten with correct value below)
1d1a: 85 fc sta exhaust_seq ;reset some things
1d1c: 85 fd sta ship_top_row
1d1e: 85 fe sta ship_exhaust_row
1d20: 85 d0 sta bullet1_fired
1d22: 85 d9 sta bullet2_fired
1d24: 85 e2 sta bullet3_state
1d26: 85 c0 sta alien_state
1d28: a9 31 lda #49 ;actually center ship
1d2a: 85 fb sta ship_position_abs
1d2c: a5 f8 lda ship_stage ;is this stage 2?
1d2e: c9 02 cmp #$02
1d30: d0 06 bne :AnimageStage3 ;no, do stage 3 animation
1d32: 20 60 0f jsr AnimateShipArrival_23 ;yes, do stage 2+3 animation
1d35: 4c 3b 1d jmp :Done
1d38: 20 c0 0f :AnimageStage3 jsr AnimateShipArrival_3
1d3b: ea :Done nop
1d3c: ea nop
1d3d: ea nop
1d3e: 60 rts
1d3f: 00 .junk 1
NextLife_0_3plus
1d40: c9 04 cmp #$04 ;is ship life at 4?
1d42: d0 05 bne :GameIsOver ;0 or >= 5; go to game over
1d44: a9 02 lda #$02 ;was at stage 4 (1+2), so go to stage 2
1d46: 4c 07 1d jmp :NextLife1
1d49: 4c 68 1d :GameIsOver jmp GameOver
1d4c: 00 00 00 00 .junk 4
;
; Updates one alien.
;
; The alien to update is incremented on every call, so calling this 7x will
; update all possible aliens.
;
1d50: a9 20 _UpdateOneAlien lda #alien0 ;self-mod
1d52: 20 80 13 jsr UpdateAlienState
1d55: ad 51 1d lda _UpdateOneAlien+1
1d58: 18 clc
1d59: 69 10 adc #$10 ;goes from $20-$80 inclusive
1d5b: c9 90 cmp #alien6+16
1d5d: 90 02 bcc L1D61
1d5f: a9 20 lda #$20 ;reset to $20 before exit
1d61: 8d 51 1d L1D61 sta _UpdateOneAlien+1
1d64: 60 rts
1d65: 00 00 00 .junk 3
1d68: 20 80 49 GameOver jsr DrawGameOver ;show message, pause briefly
1d6b: 20 00 48 jsr InitZP ;this jumps into the attract loop
1d6e: 4c 00 49 jmp MainLoop ; so this is not reached
1d71: 00 00 00 00+ .junk 15
; Loads a byte of data from $41xx into X-reg, and advances to the next byte.
1d80: ae 00 41 _load_4100 ldx egg_init_data
1d83: ee 81 1d inc _load_4100+1
1d86: ad 81 1d lda _load_4100+1
1d89: c9 f5 cmp #$f5 ;data runs from $4100-41f4, inclusive
1d8b: 90 05 bcc :NotEnd
1d8d: a9 00 lda #$00 ;reset to zero
1d8f: 8d 81 1d sta _load_4100+1
1d92: 60 :NotEnd rts
1d93: 00 00 00 00+ .junk 13
;
; Initialize alien egg state.
;
; Some data comes from the table at $4100. We call the "get next byte" function
; 35 times, and the table has 35*7 entries.
;
1da0: 20 80 1d InitAlienStates jsr _load_4100 ;prep alien #0
1da3: 86 22 stx alien0+2 ;row
1da5: 20 80 1d jsr _load_4100
1da8: 86 23 stx alien0+3 ;col
1daa: 20 80 1d jsr _load_4100
1dad: 86 26 stx alien0+6 ;color shift
1daf: 20 80 1d jsr _load_4100
1db2: 86 27 stx alien0+7 ;movement dir
1db4: 20 80 1d jsr _load_4100
1db7: 86 28 stx alien0+8 ;movement count
1db9: 20 80 1d jsr _load_4100 ;prep alien #1
1dbc: 86 32 stx alien1+2
1dbe: 20 80 1d jsr _load_4100
1dc1: 86 33 stx alien1+3
1dc3: 20 80 1d jsr _load_4100
1dc6: 86 36 stx alien1+6
1dc8: 20 80 1d jsr _load_4100
1dcb: 86 37 stx alien1+7
1dcd: 20 80 1d jsr _load_4100
1dd0: 86 38 stx alien1+8
1dd2: 20 80 1d jsr _load_4100
1dd5: 86 42 stx alien2+2
1dd7: 20 80 1d jsr _load_4100
1dda: 86 43 stx alien2+3
1ddc: 20 80 1d jsr _load_4100
1ddf: 86 46 stx alien2+6
1de1: 20 80 1d jsr _load_4100
1de4: 86 47 stx alien2+7
1de6: 20 80 1d jsr _load_4100
1de9: 86 48 stx alien2+8
1deb: 20 80 1d jsr _load_4100
1dee: 86 52 stx alien3+2
1df0: 20 80 1d jsr _load_4100
1df3: 86 53 stx alien3+3
1df5: 20 80 1d jsr _load_4100
1df8: 86 56 stx alien3+6
1dfa: 20 80 1d jsr _load_4100
1dfd: 86 57 stx alien3+7
1dff: 20 80 1d jsr _load_4100
1e02: 86 58 stx alien3+8
1e04: 20 80 1d jsr _load_4100
1e07: 86 62 stx alien4+2
1e09: 20 80 1d jsr _load_4100
1e0c: 86 63 stx alien4+3
1e0e: 20 80 1d jsr _load_4100
1e11: 86 66 stx alien4+6
1e13: 20 80 1d jsr _load_4100
1e16: 86 67 stx alien4+7
1e18: 20 80 1d jsr _load_4100
1e1b: 86 68 stx alien4+8
1e1d: 20 80 1d jsr _load_4100
1e20: 86 72 stx alien5+2
1e22: 20 80 1d jsr _load_4100
1e25: 86 73 stx alien5+3
1e27: 20 80 1d jsr _load_4100
1e2a: 86 76 stx alien5+6
1e2c: 20 80 1d jsr _load_4100
1e2f: 86 77 stx alien5+7
1e31: 20 80 1d jsr _load_4100
1e34: 86 78 stx alien5+8
1e36: 20 80 1d jsr _load_4100
1e39: 86 82 stx alien6+2
1e3b: 20 80 1d jsr _load_4100
1e3e: 86 83 stx alien6+3
1e40: 20 80 1d jsr _load_4100
1e43: 86 86 stx alien6+6
1e45: 20 80 1d jsr _load_4100
1e48: 86 87 stx alien6+7
1e4a: 20 80 1d jsr _load_4100
1e4d: 86 88 stx alien6+8
1e4f: a9 01 lda #$01 ;set all alien states to 1 (tiny egg)
1e51: a0 00 ldy #$00
1e53: 20 e0 1e jsr WriteAlienIndexed
1e56: a9 ff lda #$ff ;set all move flags to $ff
1e58: a0 09 ldy #$09
1e5a: 20 e0 1e jsr WriteAlienIndexed
1e5d: a5 bf lda wave_num ;which wave are we on?
1e5f: c9 05 cmp #$05 ;wave >= 5?
1e61: b0 08 bcs RandomizeAliens ;yes, aliens get randomized
1e63: a0 01 ldy #$01 ;no, set alien type to wave number
1e65: 20 e0 1e jsr WriteAlienIndexed
1e68: 60 rts
1e69: ea ea .junk 2
; For wave 5+, eggs hatch aliens with randomized types. The first egg is set
; based on the star field counter, the rest are just incremented from there.
; There are seven eggs, so you'll get not-quite 2 of each type.
1e6b: a5 ff RandomizeAliens lda star_field_adj ;semi-random value
1e6d: 29 03 and #$03 ;now 0-3
1e6f: 85 00 sta $00
1e71: 20 d0 1e jsr Inc_00_1234 ;increment, value now 1-4
1e74: 85 21 sta alien0+1
1e76: 20 d0 1e jsr Inc_00_1234
1e79: 85 31 sta alien1+1
1e7b: 20 d0 1e jsr Inc_00_1234
1e7e: 85 41 sta alien2+1
1e80: 20 d0 1e jsr Inc_00_1234
1e83: 85 51 sta alien3+1
1e85: 20 d0 1e jsr Inc_00_1234
1e88: 85 61 sta alien4+1
1e8a: 20 d0 1e jsr Inc_00_1234
1e8d: 85 71 sta alien5+1
1e8f: 20 d0 1e jsr Inc_00_1234
1e92: 85 81 sta alien6+1
1e94: 60 rts
1e95: 00 00 00 00+ .junk 11
; Sets all aliens to "dead", sets the game stage to 1, and then draws the high
; score. Called at the start of each life.
ZeroAliensDrawHighScore
1ea0: a9 00 lda #$00
1ea2: 85 20 sta alien0
1ea4: 85 30 sta alien1
1ea6: 85 40 sta alien2
1ea8: 85 50 sta alien3
1eaa: 85 60 sta alien4
1eac: 85 70 sta alien5
1eae: 85 80 sta alien6
1eb0: a9 01 lda #$01
1eb2: 85 bf sta wave_num
1eb4: 4c 50 44 jmp DrawHighScore
1eb7: 00 00 00 00+ .junk 25
; Increments the value in $00, rotating through the values 1,2,3,4. Value is
; returned in A-reg.
1ed0: e6 00 Inc_00_1234 inc $00
1ed2: a5 00 lda $00
1ed4: c9 05 cmp #$05
1ed6: 90 04 bcc L1EDC
1ed8: a9 01 lda #$01
1eda: 85 00 sta $00
1edc: 60 L1EDC rts
1edd: 00 00 00 .junk 3
WriteAlienIndexed
1ee0: 99 20 00 sta alien0,y
1ee3: 99 30 00 sta alien1,y
1ee6: 99 40 00 sta alien2,y
1ee9: 99 50 00 sta alien3,y
1eec: 99 60 00 sta alien4,y
1eef: 99 70 00 sta alien5,y
1ef2: 99 80 00 sta alien6,y
1ef5: 60 rts
1ef6: 99 40 00 99+ .align $0100 (10 bytes)
;
; Star field start column. Used to move stars to different start positions.
;
star_field_start_col
1f00: 02 06 0c 0d+ .bulk 02060c0d001e1d0c1f0a231722051102050c19151215140d1713220d04150110
+ 14201e01060d07220516260a12211e090a20010a0905210e0f061605200d0f0f
+ 19171e0d231a02101822221214031a0a052114070c1d2602071e261d0d170406
+ 20062623190c020b04050409241a16242122101d09142010030e1f1e0c0e0017
+ 0d062203040425230923181818131b250d211a100a151519041709230c100907
+ 182503080503050f0e10041d25200c0c1c052318230b1824150f1e1a0f220a00
+ 1314190b141720250b03240d1316142000221914031207091e000125131f0401
+ 231f1c221101031f1e13111303231f1d1c06170f180a160c220f1d0f041b0315
;
; Big chunk of data that doesn't need to be part of the file.
;
2000: fd bd e7 b4+ HIRES_PAGE_1 .junk 5632
.org $4100
;
; Data used to init alien state. Must be page-aligned. This specifies the
; initial position and movement for the eggs.
;
; 5 bytes per alien, 7 aliens per set, 7 sets = 5*7*7=245
;
4100: 2c 03 ff 07+ egg_init_data .bulk 2c03ff070338150006023410ff0601501d0004021c10ff0101280c0002021c1e
+ 000703
4123: 38 02 00 02+ .bulk 38020002022c140007035015ff04012819000102380f0005022c0cff0603281f
+ 000602
4146: 24 05 00 01+ .bulk 24050001032011ff01042015000001201fff0104100a0000011014ff01041018
+ 000001
4169: 20 07 00 00+ .bulk 2007000001200e0000012018ff0104201fff010410090001041014ff01041019
+ ff0002
418c: 50 09 00 04+ .bulk 5009000401500fff04022014000104201d000002100a0000014012000402101b
+ ff0104
41af: 20 06 00 01+ .bulk 2006000104500eff04012014000104501dff040210090001041014ff01044019
+ ff0402
41d2: 2c 03 00 01+ .bulk 2c03000101500e000403381c0006022420ff0103400cff04032c0cff06031018
+ ff0003
41f5: 00 00 00 00+ .align $0100 (11 bytes)
;
; Parameters for the sound function that makes semi-random chirping noises.
; Larger values a lower in pitch and take longer to play. (Setting these to $50
; will have a very noticeable effect on animation.)
;
; Must be page-aligned.
;
4200: 06 1f 06 0b+ sound_params .bulk 061f060b021806251e241c0f1c27220b2414270a1c10162103190f0103201b23
+ 01230d140407241503190c1412061d140215032107120815191b171620051f24
+ 180d03231226232419041e26171f0416080e171e241325191812030d27030614
+ 1b240116120b0603010227200c211e230d0a0d011804142317180725020c0a01
+ 1c12010f231e19181d06211d17132117122512080f1e26160f08170a15132304
+ 111a0d140a0a1b18250b0c081e1325050c0d171908040e01030c14041a0c0d0a
+ 0f211e27100e022303230f1d221927090a1b010c05181e26212609131b210d18
+ 1c0f020a1c021f12171c160510220f09230105070f031f1718100a0b0f091c15
;
; Make a chirp. Used for the intro animation and explosions.
;
]click_delay .var $00 {addr/1}
]chirp_delay .var $01 {addr/1}
4300: ad 03 42 _MakeChirp lda sound_params+3 ;address is incremented
4303: 85 00 sta ]click_delay ;inter-click delay value
4305: 49 ff eor #$ff
4307: 18 clc
4308: 69 31 adc #$31
430a: 85 01 sta ]chirp_delay ;inter-chirp delay value
430c: ee 01 43 inc _MakeChirp+1 ;next sound will be different
430f: a2 30 ldx #48 ;48 clicks
4311: a4 00 :SoundLoop ldy ]click_delay
4313: ea :DelayLoop nop
4314: ea nop
4315: ea nop
4316: ea nop
4317: ea nop
4318: 88 dey
4319: d0 f8 bne :DelayLoop
431b: 8d 30 c0 sta SPKR ;click
431e: ca dex
431f: d0 f0 bne :SoundLoop
; pause briefly post-chirp
4321: a2 30 ldx #48 ;48 iterations of the delay
4323: a4 01 :Loop1 ldy ]chirp_delay
4325: ea :Loop2 nop
4326: ea nop
4327: ea nop
4328: ea nop
4329: ea nop
432a: 88 dey
432b: d0 f8 bne :Loop2
432d: ea nop
432e: ea nop
432f: ca dex
4330: d0 f1 bne :Loop1
4332: 60 rts
4333: ff 00 00 ff+ .junk 13
• Clear variables
]screen_src .var $08 {addr/1}
TransitionToBlank
4340: a9 80 lda #>blank_screen_image-$2000
4342: 85 08 sta ]screen_src
4344: 4c f0 46 jmp ScreenTransition
4347: 8d 4f 43 a0+ .junk 24
435f: ff 00 00 ff+ .junk 33
; Draws "SCORE:0000 HI:0000" at the top of the screen.
]ptr .var $00 {addr/2}
4380: a9 20 DrawScoreBase lda #$20
4382: 8d 99 43 sta :Loop2+1
4385: a9 75 lda #>base_score_image
4387: 8d 9a 43 sta :Loop2+2
438a: a2 00 ldx #<base_score_image-32
438c: bd 00 08 :Loop1 lda hr_ytable_hi,x
438f: 85 01 sta ]ptr+1
4391: bd c0 08 lda hr_ytable_lo,x
4394: 85 00 sta ]ptr
4396: a0 00 ldy #$00
4398: ad 38 76 :Loop2 lda base_score_image+$118 ;starts at $7520
439b: 91 00 sta (]ptr),y
439d: ee 99 43 inc :Loop2+1
43a0: d0 03 bne :NoInc
43a2: ee 9a 43 inc :Loop2+2
43a5: c8 :NoInc iny
43a6: c0 28 cpy #40 ;40 bytes per row
43a8: 90 ee bcc :Loop2
43aa: e8 inx
43ab: e0 07 cpx #$07 ;7 lines
43ad: 90 dd bcc :Loop1
43af: 60 rts
; Draw one score digit. Each glyph is two bytes wide by 7 bytes high.
;
; On entry:
; X: digit index (0-9)
; Y: hi-res column index (0-38)
43b0: bd 70 74 DrawScoreDigit lda digit_row0,x
43b3: 99 00 20 sta HIRES_PAGE_1,y
43b6: bd 71 74 lda digit_row0+1,x
43b9: 99 01 20 sta HIRES_PAGE_1+1,y
43bc: bd 88 74 lda digit_row1,x
43bf: 99 00 24 sta HIRES_PAGE_1+$400,y
43c2: bd 89 74 lda digit_row1+1,x
43c5: 99 01 24 sta HIRES_PAGE_1+$401,y
43c8: bd a0 74 lda digit_row2,x
43cb: 99 00 28 sta HIRES_PAGE_1+$800,y
43ce: bd a1 74 lda digit_row2+1,x
43d1: 99 01 28 sta HIRES_PAGE_1+$801,y
43d4: bd b8 74 lda digit_row3,x
43d7: 99 00 2c sta HIRES_PAGE_1+$c00,y
43da: bd b9 74 lda digit_row3+1,x
43dd: 99 01 2c sta HIRES_PAGE_1+$c01,y
43e0: bd d0 74 lda digit_row4,x
43e3: 99 00 30 sta HIRES_PAGE_1+$1000,y
43e6: bd d1 74 lda digit_row4+1,x
43e9: 99 01 30 sta HIRES_PAGE_1+$1001,y
43ec: bd e8 74 lda digit_row5,x
43ef: 99 00 34 sta HIRES_PAGE_1+$1400,y
43f2: bd e9 74 lda digit_row5+1,x
43f5: 99 01 34 sta HIRES_PAGE_1+$1401,y
43f8: bd 00 75 lda digit_row6,x
43fb: 99 00 38 sta HIRES_PAGE_1+$1800,y
43fe: bd 01 75 lda digit_row6+1,x
4401: 99 01 38 sta HIRES_PAGE_1+$1801,y
4404: 60 rts
4405: 00 ff ff 00+ .junk 11
; Draws the current score.
4410: a5 b0 DrawCurScore lda cur_score_hi
4412: 4a lsr A
4413: 4a lsr A
4414: 4a lsr A
4415: 4a lsr A
4416: 0a asl A
4417: aa tax
4418: a0 0c ldy #$0c
441a: 20 b0 43 jsr DrawScoreDigit
441d: a5 b0 lda cur_score_hi
441f: 29 0f and #$0f
4421: 0a asl A
4422: aa tax
4423: a0 0e ldy #$0e
4425: 20 b0 43 jsr DrawScoreDigit
4428: a5 b1 lda cur_score_lo
442a: 4a lsr A
442b: 4a lsr A
442c: 4a lsr A
442d: 4a lsr A
442e: 0a asl A
442f: aa tax
4430: a0 10 ldy #$10
4432: 20 b0 43 jsr DrawScoreDigit
4435: a5 b1 lda cur_score_lo
4437: 29 0f and #$0f
4439: 0a asl A
443a: aa tax
443b: a0 12 ldy #$12
443d: 20 b0 43 jsr DrawScoreDigit
4440: 60 rts
4441: 00 ff ff 00+ .junk 15
; Draws the high score.
4450: a5 b2 DrawHighScore lda high_score_hi
4452: 4a lsr A
4453: 4a lsr A
4454: 4a lsr A
4455: 4a lsr A
4456: 0a asl A
4457: aa tax
4458: a0 1e ldy #$1e
445a: 20 b0 43 jsr DrawScoreDigit
445d: a5 b2 lda high_score_hi
445f: 29 0f and #$0f
4461: 0a asl A
4462: aa tax
4463: a0 20 ldy #$20
4465: 20 b0 43 jsr DrawScoreDigit
4468: a5 b3 lda high_score_lo
446a: 4a lsr A
446b: 4a lsr A
446c: 4a lsr A
446d: 4a lsr A
446e: 0a asl A
446f: aa tax
4470: a0 22 ldy #$22
4472: 20 b0 43 jsr DrawScoreDigit
4475: a5 b3 lda high_score_lo
4477: 29 0f and #$0f
4479: 0a asl A
447a: aa tax
447b: a0 24 ldy #$24
447d: 20 b0 43 jsr DrawScoreDigit
4480: 60 rts
4481: 00 ff ff 00+ .junk 15
; Draws a small digit at the specified row and column.
• Clear variables
]ptr1 .var $00 {addr/2}
]digit .var $04 {addr/1} ;digit to draw
]digit_row .var $05 {addr/1} ;hi-res row
]digit_col .var $06 {addr/1} ;hi-res column
]counter .var $07 {addr/1}
4490: a9 07 DrawSmallDigit lda #$07
4492: 85 07 sta ]counter
4494: a9 00 lda #$00
4496: 8d a8 44 sta L44A7+1 ;set addr to $7400
4499: a6 05 ldx ]digit_row
449b: bd 00 08 L449B lda hr_ytable_hi,x
449e: 85 01 sta ]ptr1+1
44a0: bd c0 08 lda hr_ytable_lo,x
44a3: 85 00 sta ]ptr1
44a5: a4 04 ldy ]digit
44a7: b9 70 74 L44A7 lda small_digits+112,y
44aa: a4 06 ldy ]digit_col
44ac: 91 00 sta (]ptr1),y
44ae: ad a8 44 lda L44A7+1
44b1: 18 clc
44b2: 69 10 adc #$10
44b4: 8d a8 44 sta L44A7+1
44b7: e8 inx
44b8: c6 07 dec ]counter
44ba: d0 df bne L449B
44bc: 60 rts
44bd: 00 ff ff .junk 3
;
; Draw a small number at a specific screen position. Used for the explosions
; that show the score.
;
; On entry:
; A = two-digit BCD value
; $c2 = hi-res row
; $06 = hi-res col
;
44c0: 48 DrawSmallNumber pha
44c1: 4a lsr A ;start with high nibble
44c2: 4a lsr A
44c3: 4a lsr A
44c4: 4a lsr A
44c5: 85 04 sta ]digit
44c7: a5 c2 lda alien_row
44c9: 18 clc
44ca: 69 02 adc #$02
44cc: 85 05 sta ]digit_row
44ce: a5 06 lda ]digit_col
44d0: 18 clc
44d1: 69 01 adc #$01
44d3: 85 06 sta ]digit_col
44d5: 20 90 44 jsr DrawSmallDigit
44d8: 68 pla
44d9: 29 0f and #$0f ;now the low nibble
44db: 85 04 sta ]digit
44dd: e6 06 inc ]digit_col
44df: 20 90 44 jsr DrawSmallDigit
44e2: 60 rts
44e3: ff 00 00 ff+ .junk 13
; BCD point values for shooting aliens.
44f0: 00 alien_score_tab .dd1 $00 ;(unused)
44f1: 15 .dd1 $15 ;spiders - 15 pts
44f2: 30 .dd1 $30 ;lips - 30 pts
44f3: 45 .dd1 $45 ;wolves - 45 pts
44f4: 80 .dd1 $80 ;fuzzballs - 80 pts
44f5: 00 ff ff 00+ .junk 11
4500: a6 c1 DrawAlienScore ldx alien_type_index
4502: bd f0 44 lda alien_score_tab,x
4505: 20 c0 44 jsr DrawSmallNumber
4508: 60 rts
4509: 44 68 f8 18+ .junk 7
; Adds the point value from an alien kill to the score, then updates the scores.
4510: a6 c1 AddKillScore ldx alien_type_index
4512: bd f0 44 lda alien_score_tab,x ;add score to total
4515: f8 sed ;this is what 6502 decimal mode is for
4516: 18 clc
4517: 65 b1 adc cur_score_lo
4519: 85 b1 sta cur_score_lo
451b: a9 00 lda #$00
451d: 65 b0 adc cur_score_hi
451f: 85 b0 sta cur_score_hi
4521: d8 cld
4522: 20 10 44 jsr DrawCurScore ;draw it
4525: a5 b2 lda high_score_hi ;new high score?
4527: c5 b0 cmp cur_score_hi
4529: d0 06 bne L4531
452b: a5 b3 lda high_score_lo
452d: c5 b1 cmp cur_score_lo
452f: ea nop
4530: ea nop
4531: b0 0b L4531 bcs L453E
4533: a5 b0 lda cur_score_hi ;update high score
4535: 85 b2 sta high_score_hi
4537: a5 b1 lda cur_score_lo
4539: 85 b3 sta high_score_lo
453b: 20 50 44 jsr DrawHighScore
453e: 60 L453E rts
453f: 44 60 00 ff+ .junk 17
; Hi-res bit patterns, used when drawing the screen transitions.
4550: 7f 7e 7c 78+ right_edge_bits .bulk 7f7e7c78602000 ;drawing and masking
4557: ff .junk 1
4558: 00 20 60 78+ .bulk 002060787c7e7f ;unused?
455f: ff .junk 1
4560: 01 03 07 0f+ left_edge_bits .bulk 0103070f1f3f7f ;for drawing white
4567: 0f .junk 1
4568: 00 01 03 07+ left_edge_mask .bulk 000103070f1f3f ;mask part of title/black
456f: ff a9 00 85+ .junk 23
;
; Draw a thin white rectangle, as part of "whiting out" the screen.
;
• Clear variables
]ptr1 .var $00 {addr/2}
]ptr2 .var $02 {addr/2}
]ptr3 .var $04 {addr/2}
]ptr4 .var $06 {addr/2}
]screen_src .var $08 {addr/1} ;high byte of source page for copy, -$20
]delay_adj .var $09 {addr/1}
]top_row .var $0a {addr/1}
]bottom_row .var $0b {addr/1}
]left_col .var $0c {addr/1}
]left_bit_index .var $0d {addr/1} ;0-6
]right_col .var $0e {addr/1}
]right_bit_index .var $0f {addr/1} ;0-6
4586: a6 0a DrawWhiteRect ldx ]top_row ;set up pointers for top/bottom
4588: bd 00 08 lda hr_ytable_hi,x
458b: 85 01 sta ]ptr1+1
458d: bd c0 08 lda hr_ytable_lo,x
4590: 85 00 sta ]ptr1
4592: a6 0b ldx ]bottom_row
4594: bd 00 08 lda hr_ytable_hi,x
4597: 85 03 sta ]ptr2+1
4599: bd c0 08 lda hr_ytable_lo,x
459c: 85 02 sta ]ptr2
459e: a4 0c ldy ]left_col
45a0: a9 7f lda #$7f ;white
45a2: 91 00 :HLoop sta (]ptr1),y ;draw horizontal lines
45a4: 91 02 sta (]ptr2),y ;(slight overdraw at edges; faster that way)
45a6: c4 0e cpy ]right_col
45a8: f0 04 beq :DrawVerticals
45aa: c8 iny
45ab: 4c a2 45 jmp :HLoop
45ae: a6 0a :DrawVerticals ldx ]top_row ;now do the vertical lines
45b0: bd 00 08 :VLoop lda hr_ytable_hi,x
45b3: 85 01 sta ]ptr1+1
45b5: bd c0 08 lda hr_ytable_lo,x
45b8: 85 00 sta ]ptr1
45ba: a4 0d ldy ]left_bit_index
45bc: b9 60 45 lda left_edge_bits,y
45bf: a4 0c ldy ]left_col
45c1: 11 00 ora (]ptr1),y
45c3: 91 00 sta (]ptr1),y
45c5: a4 0f ldy ]right_bit_index
45c7: b9 50 45 lda right_edge_bits,y
45ca: a4 0e ldy ]right_col
45cc: 11 00 ora (]ptr1),y
45ce: 91 00 sta (]ptr1),y
45d0: e4 0b cpx ]bottom_row
45d2: f0 04 beq :Done
45d4: e8 inx
45d5: 4c b0 45 jmp :VLoop
45d8: 60 :Done rts
45d9: 00 ff ff 00+ .junk 7
ScreenTransitionWhiteIn
45e0: a9 00 lda #$00
45e2: 85 0a sta ]top_row
45e4: 85 0c sta ]left_col
45e6: 85 0d sta ]left_bit_index
45e8: a9 bf lda #191
45ea: 85 0b sta ]bottom_row
45ec: a9 27 lda #39
45ee: 85 0e sta ]right_col
45f0: a9 06 lda #$06
45f2: 85 0f sta ]right_bit_index
45f4: 20 86 45 :Loop jsr DrawWhiteRect
45f7: e6 0a inc ]top_row
45f9: c6 0b dec ]bottom_row
45fb: a5 0a lda ]top_row
45fd: c9 60 cmp #96 ;192/2
45ff: 90 01 bcc :NotDone
4601: 60 rts
4602: a5 0d :NotDone lda ]left_bit_index ;adjust the bit indices by 1
4604: 18 clc
4605: 69 01 adc #$01
4607: c9 07 cmp #$07 ;have we reached 7?
4609: 90 04 bcc :Not7 ;not yet
460b: e6 0c inc ]left_col ;yes, advance to the next column
460d: a9 00 lda #$00
460f: 85 0d :Not7 sta ]left_bit_index
4611: a5 0f lda ]right_bit_index ;do the same on the right
4613: 38 sec
4614: e9 01 sbc #$01
4616: 10 04 bpl :Pos
4618: c6 0e dec ]right_col
461a: a9 06 lda #$06
461c: 85 0f :Pos sta ]right_bit_index
461e: e6 09 inc ]delay_adj
4620: a5 09 lda ]delay_adj
4622: 4a lsr A
4623: 20 a8 fc jsr MON_WAIT
4626: 4c f4 45 jmp :Loop
4629: 45 00 00 00+ .junk 7
;
; Copy a thin rectangle from one screen to another.
;
; This looks glitchy at the bottom corners because it writes a full byte at the
; ends of the horizontal lines, and then fixes them while drawing the vertical
; lines. The code does the top/bottom lines first, which means there's an
; excellent chance that the display refresh will happen while the bottom line is
; overdrawn.
;
; Part of the "screen transition from white" routine.
;
4630: a6 0a CopyScreenRect ldx ]top_row ;start with the horizontal lines
4632: bd 00 08 lda hr_ytable_hi,x
4635: 85 01 sta ]ptr1+1
4637: bd c0 08 lda hr_ytable_lo,x
463a: 85 00 sta ]ptr1
463c: a6 0b ldx ]bottom_row
463e: bd 00 08 lda hr_ytable_hi,x
4641: 85 03 sta ]ptr2+1
4643: bd c0 08 lda hr_ytable_lo,x
4646: 85 02 sta ]ptr2
4648: a5 00 lda ]ptr1
464a: 85 04 sta ]ptr3
464c: a5 02 lda ]ptr2
464e: 85 06 sta ]ptr4
4650: a5 01 lda ]ptr1+1
4652: 18 clc
4653: 65 08 adc ]screen_src
4655: 85 05 sta ]ptr3+1
4657: a5 03 lda ]ptr2+1
4659: 18 clc
465a: 65 08 adc ]screen_src
465c: 85 07 sta ]ptr4+1
465e: a4 0c ldy ]left_col
4660: b1 04 :HLoop lda (]ptr3),y
4662: 91 00 sta (]ptr1),y
4664: b1 06 lda (]ptr4),y
4666: 91 02 sta (]ptr2),y
4668: c4 0e cpy ]right_col
466a: f0 04 beq :DrawVerticals
466c: c8 iny
466d: 4c 60 46 jmp :HLoop
4670: a6 0a :DrawVerticals ldx ]top_row ;now do the vertical lines
4672: bd 00 08 :VLoop lda hr_ytable_hi,x
4675: 85 01 sta ]ptr1+1
4677: bd c0 08 lda hr_ytable_lo,x
467a: 85 00 sta ]ptr1
467c: a5 00 lda ]ptr1
467e: 85 02 sta ]ptr2
4680: a5 01 lda ]ptr1+1
4682: 18 clc
4683: 65 08 adc ]screen_src
4685: 85 03 sta ]ptr2+1
4687: a4 0d ldy ]left_bit_index
4689: b9 68 45 lda left_edge_mask,y
468c: a4 0c ldy ]left_col
468e: 11 02 ora (]ptr2),y
4690: 91 00 sta (]ptr1),y
4692: a4 0f ldy ]right_bit_index
4694: b9 50 45 lda right_edge_bits,y
4697: a4 0e ldy ]right_col
4699: 11 02 ora (]ptr2),y
469b: 91 00 sta (]ptr1),y
469d: e4 0b cpx ]bottom_row
469f: f0 04 beq :Done
46a1: e8 inx
46a2: 4c 72 46 jmp :VLoop
46a5: 4c bf 49 :Done jmp SmallDelay
46a8: 00 00 00 00+ .junk 8
;
; Transition from a screen full of white to either the title screen or a blank
; screen.
;
ScreenTransitionScrnOut
46b0: 20 30 46 jsr CopyScreenRect
46b3: c6 0a dec ]top_row
46b5: e6 0b inc ]bottom_row
46b7: a5 0b lda ]bottom_row
46b9: c9 c0 cmp #192
46bb: 90 01 bcc L46BE
46bd: 60 rts
46be: a5 0f L46BE lda ]right_bit_index ;update the horizontal bit counters
46c0: 18 clc
46c1: 69 01 adc #$01
46c3: c9 07 cmp #$07 ;reached bit 7?
46c5: 90 04 bcc L46CB ;not yet, keep going
46c7: e6 0e inc ]right_col ;advance to next byte
46c9: a9 00 lda #$00 ;reset bit index
46cb: 85 0f L46CB sta ]right_bit_index
46cd: a5 0d lda ]left_bit_index
46cf: 38 sec
46d0: e9 01 sbc #$01
46d2: 10 04 bpl L46D8
46d4: c6 0c dec ]left_col ;advance to previous byte
46d6: a9 06 lda #$06 ;reset bit index
46d8: 85 0d L46D8 sta ]left_bit_index
46da: c6 09 dec ]delay_adj ;update the delay
46dc: a5 09 lda ]delay_adj
46de: 4a lsr A
46df: 20 a8 fc jsr MON_WAIT ;pause to try to keep the fill steady
46e2: 4c b0 46 jmp ScreenTransitionScrnOut
46e5: 46 00 00 00+ .junk 11
; Draw white-in then screen-copy-out.
ScreenTransition
46f0: a9 02 lda #$02 ;init delay
46f2: 85 09 sta ]delay_adj
46f4: 20 e0 45 jsr ScreenTransitionWhiteIn
46f7: c6 0a dec ]top_row ;start a row apart
46f9: e6 0b inc ]bottom_row
46fb: 20 b0 46 jsr ScreenTransitionScrnOut
46fe: 60 rts
46ff: 00 .junk 1
; Draws the stage 1 ship, descending from the top of the screen.
;
; On entry:
; $0a/0b - horizontal position
; $0c - vertical position (top row)
• Clear variables
]start_row .var $04 {addr/1}
]end_row .var $05 {addr/1}
]start_col .var $06 {addr/1}
]end_col .var $07 {addr/1}
]screen_pos_coarse .var $0a {addr/1}
]screen_pos_fine .var $0b {addr/1}
]top_row .var $0c {addr/1}
]chirp_ctr .var $0d {addr/1}
DrawGrabbableShip
4700: a6 0b ldx ]screen_pos_fine
4702: bd 80 0a lda ship1_s7_index_lo,x ;stage 1 ship
4705: 8d 3c 47 sta :_DrawSrc+1
4708: bd 88 0a lda ship1_s7_index_hi,x
470b: 8d 3d 47 sta :_DrawSrc+2
470e: a5 0a lda ]screen_pos_coarse
4710: 38 sec
4711: e9 02 sbc #$02
4713: 85 06 sta ]start_col
4715: 18 clc
4716: 69 06 adc #6 ;bitmap width
4718: 85 07 sta ]end_col
471a: a5 0c lda ]top_row
471c: 85 04 sta ]start_row
471e: 18 clc
471f: 69 0a adc #10 ;bitmap height
4721: 85 05 sta ]end_row
4723: a6 04 ldx ]start_row
4725: e0 c0 cpx #192
4727: b0 2b bcs L4754
4729: e0 08 L4729 cpx #$08
472b: 90 27 bcc L4754
472d: bd 00 08 lda hr_ytable_hi,x
4730: 8d 40 47 sta :_DrawDst+2
4733: bd c0 08 lda hr_ytable_lo,x
4736: 8d 3f 47 sta :_DrawDst+1
4739: a4 06 ldy ]start_col
473b: ad 3c 60 :_DrawSrc lda T6000+60
473e: 99 d0 3d :_DrawDst sta $3dd0,y
4741: ee 3c 47 inc :_DrawSrc+1
4744: d0 03 bne L4749
4746: ee 3d 47 inc :_DrawSrc+2
4749: c8 L4749 iny
474a: c4 07 cpy ]end_col
474c: 90 ed bcc :_DrawSrc
474e: e8 L474E inx
474f: e4 05 cpx ]end_row
4751: d0 d6 bne L4729
4753: 60 rts
4754: ad 3c 47 L4754 lda :_DrawSrc+1
4757: 18 clc
4758: 69 06 adc #$06
475a: 8d 3c 47 sta :_DrawSrc+1
475d: d0 03 bne L4762
475f: ee 3d 47 inc :_DrawSrc+2
4762: 4c 4e 47 L4762 jmp L474E
4765: 00 ff ff 00+ .junk 27
;
; Mini-game: catch stage 1 with stage 2 to get triple action.
;
4780: a5 ff MultiShipGrab1 lda star_field_adj ;semi-random value
4782: 29 0f and #$0f ;reduce to 0-15
4784: 18 clc
4785: 69 10 adc #16 ;adjust to 16-31
4787: 85 0a sta ]screen_pos_coarse ;use for horizontal position
4789: a9 00 lda #$00
478b: 85 0b sta ]screen_pos_fine ;just set "fine" pos to zero
478d: 85 0d sta ]chirp_ctr
478f: 85 0c sta ]top_row
4791: ea nop
4792: ea nop
4793: ea nop
4794: ea nop
4795: 20 f0 47 :GrabLoop jsr UpdateStarField2x
4798: 20 00 47 jsr DrawGrabbableShip
479b: 20 a0 0c jsr ReadPaddle
479e: 20 00 0d jsr DrawPlayerShip
47a1: a9 50 lda #$50 ;?
47a3: 20 e0 47 jsr ChirpEvery4_d
47a6: e6 0c inc ]top_row
47a8: a5 0c lda ]top_row
47aa: c9 97 cmp #151 ;reached the ship merge row?
47ac: d0 e7 bne :GrabLoop ;no, keep going
47ae: a5 f9 lda ship_pos_coarse
47b0: c5 0a cmp ]screen_pos_coarse ;lined up?
47b2: d0 12 bne ShipGrabFail ;no, fail
47b4: a5 0b lda ]screen_pos_fine
47b6: c5 fa cmp ship_pos_fine
47b8: d0 0c bne ShipGrabFail
47ba: a9 04 lda #$04 ;success, set ship stage to 1+2
47bc: 85 f8 sta ship_stage
47be: 60 rts
47bf: a9 ff 85 0d+ .junk 7
47c6: 20 00 0b ShipGrabFail jsr UpdateStarField ;animate stage 1 back off the screen
47c9: 20 a0 0c jsr ReadPaddle
47cc: 20 00 0d jsr DrawPlayerShip
47cf: 20 00 47 jsr DrawGrabbableShip
47d2: a9 20 lda #$20
47d4: 20 a8 fc jsr MON_WAIT ;pause for 3000 cycles
47d7: c6 0c dec ]top_row
47d9: a5 0c lda ]top_row
47db: c9 fe cmp #$fe
47dd: d0 e7 bne ShipGrabFail
47df: 60 rts
; Makes a chirp every 4 calls, using $0d as a counter.
47e0: e6 0d ChirpEvery4_d inc ]chirp_ctr
47e2: a5 0d lda ]chirp_ctr
47e4: c9 04 cmp #$04
47e6: b0 01 bcs :Over4
47e8: 60 rts
47e9: a9 00 :Over4 lda #$00
47eb: 85 0d sta ]chirp_ctr
47ed: 4c 00 43 jmp _MakeChirp
UpdateStarField2x
47f0: 20 00 0b jsr UpdateStarField
47f3: 20 00 0b jsr UpdateStarField
47f6: 60 rts
47f7: ff 00 00 ff+ .junk 9
4800: a5 b0 InitZP lda cur_score_hi ;preserve scores ($b0-b3)
4802: 48 pha
4803: a5 b1 lda cur_score_lo
4805: 48 pha
4806: a5 b2 lda high_score_hi
4808: 48 pha
4809: a5 b3 lda high_score_lo
480b: 48 pha
480c: a9 00 lda #$00 ;completely zero out zero page
480e: a8 tay
480f: 99 00 00 :Loop sta $0000,y
4812: c8 iny
4813: d0 fa bne :Loop
4815: 68 pla ;restore $b0-b3
4816: 85 b3 sta high_score_lo
4818: 68 pla
4819: 85 b2 sta high_score_hi
481b: 68 pla
481c: 85 b1 sta cur_score_lo
481e: 68 pla
481f: 85 b0 sta cur_score_hi
4821: 7a nop ;these are NOPs on 6502
4822: 3a nop ;on 65C02 these are INC/DEC A, PHY, and PLY
4823: 7a nop ;there's nothing useful on the stack right now
4824: 1a nop ; so it all works out okay
4825: 5a nop
4826: 5a nop
4827: 3a nop
4828: 1a nop
4829: 3a nop
482a: 1a nop
482b: 3a nop
482c: 5a nop
482d: 20 60 48 jsr TransitionToTitle
4830: 20 80 43 jsr DrawScoreBase
4833: 20 10 44 jsr DrawCurScore
4836: 20 50 44 jsr DrawHighScore
4839: 4c d3 4b jmp AttractEntry
483c: 10 fb .junk 2
483e: a9 13 StartGame lda #19 ;center of screen
4840: 85 f9 sta ship_pos_coarse
4842: a9 31 lda #49
4844: 85 fb sta ship_position_abs
4846: a9 01 lda #$01
4848: 85 f8 sta ship_stage
484a: 20 00 0f jsr AnimateShipArrival_123
484d: a9 01 lda #$01
484f: 85 bf sta wave_num
4851: a9 00 lda #$00
4853: 85 b0 sta cur_score_hi
4855: 85 b1 sta cur_score_lo
4857: 20 10 44 jsr DrawCurScore
485a: 4c 00 49 jmp MainLoop
485d: 00 ff ff .junk 3
• Clear variables
]screen_src .var $08 {addr/1}
TransitionToTitle
4860: a9 60 lda #>title_screen_image-$2000
4862: 85 08 sta ]screen_src
4864: 4c f0 46 jmp ScreenTransition
4867: ff 00 00 ff+ .junk 25
4880: 3a FunkyStartup nop ;$3A is an undocumented NOP on 6502
4881: 3a nop ;on 65C02 it's DEC A, which is harmless here
4882: 3a nop
4883: 3a nop
4884: 3a nop
4885: 3a nop
4886: 3a nop
4887: 3a nop
4888: 3a nop
4889: 38 sec ;set carry for branch below
488a: 3a nop
488b: 3a nop
488c: 3a nop
488d: 3a nop
488e: 3a nop
488f: 3a nop
4890: 3a nop
4891: 3a nop
4892: 3a nop
4893: 3a nop
4894: 3a nop
4895: 3a nop
4896: 3a nop
4897: 3a nop
4898: 3a nop
4899: 3a nop
489a: 3a nop
489b: 3a nop
489c: 3a nop
489d: 38 sec
489e: 3a nop
489f: 3a nop
48a0: 3a nop
48a1: 3a nop
48a2: 3a nop
48a3: b0 1f bcs Start2 ;branch always
48a5: 3a 3a 3a 3a+ .junk 31
48c4: 4c 00 48 Start2 jmp InitZP
48c7: 00 00 00 ff+ .junk 57
;
; Main game loop.
;
4900: 20 00 0b MainLoop jsr UpdateStarField
4903: 20 a0 0c jsr ReadPaddle
4906: 20 00 0d jsr DrawPlayerShip
4909: 20 50 1d jsr _UpdateOneAlien
490c: 20 c0 12 jsr CheckFireButton
490f: 20 10 15 jsr UpdateBullets
4912: 20 50 1d jsr _UpdateOneAlien
4915: 20 a0 0c jsr ReadPaddle
4918: 20 00 0d jsr DrawPlayerShip
491b: 20 b0 1c jsr CheckAllAliensDead
491e: 4c 00 49 jmp MainLoop
4921: 7a 8d e1 57+ .junk 95
• Clear variables
]start_row .var $04 {addr/1}
]end_row .var $05 {addr/1}
]start_col .var $06 {addr/1}
]end_col .var $07 {addr/1}
4980: a9 00 DrawGameOver lda #<game_over_text
4982: 8d d1 0b sta _DrawBitmapSrc+1
4985: a9 4a lda #>game_over_text
4987: 8d d2 0b sta _DrawBitmapSrc+2
498a: a9 48 lda #72
498c: 85 04 sta ]start_row
498e: 18 clc
498f: 69 0e adc #$0e
4991: 85 05 sta ]end_row
4993: a9 0a lda #$0a
4995: 85 06 sta ]start_col
4997: 18 clc
4998: 69 12 adc #$12
499a: 85 07 sta ]end_col
499c: 20 c0 0b jsr DrawBitmap
499f: a9 10 lda #16 ;call MON_WAIT 16x
49a1: 48 pha ;(could've left the counter in X-reg)
49a2: 68 :Loop pla
49a3: f0 0c beq :Done
49a5: 38 sec
49a6: e9 01 sbc #$01
49a8: 48 pha
49a9: a9 00 lda #$00 ;delay for about 167K cycles
49ab: 20 a8 fc jsr MON_WAIT ; x16 = about 2.6 seconds
49ae: 4c a2 49 jmp :Loop
49b1: 60 :Done rts
49b2: ff ff 00 00+ .junk 13
; Trivial delay function (20 cycles), used during screen transition.
;
; (Not sure what the point of this is.)
49bf: 48 SmallDelay pha
49c0: 4c d9 49 jmp :Delay2
49c3: 3a 5a 2c 78+ .junk 22
49d9: 1a :Delay2 nop
49da: 68 pla
49db: 3a nop
49dc: 60 rts
49dd: 5a 7a 7a 5a+ .junk 35
;
; "Game Over". 18x14
;
4a00: 60 07 60 03+ game_over_text .bulk 600760030c187c1f000060070c187c1f7c07780f70071e3c7e3f0000780f1e3c
+ 7e3f7e1f7c1f780f3e3e7e1f00007c1f1e3c7e1f7e3f3e3c7c1f7e3f3e000000
+ 3e3c3c1e3e003e3c3e383e3e7e3f3e0000003e383c1e3e003e3c3e001e3c7e3f
+ 7e0700003e38780f7e077e3f3e001e3c5e3f7e0f00003e38780f7e0f7e1f3e3f
+ 7e3f1e3d7e0700003e3870077e077e073e3e7e3f1e3c3e0000003e3870073e00
+ 3e0f3e3c7e3f1e3c3e0000003e3870073e003e1e3e3c1e3c1e3c3e0000003e3c
+ 60033e003e3c7c1f3e3c1e3c7e1f00007c1f60037e1f3e3c781f3e3e1e3c7e3f
+ 0000781f60037e3f3e3c60071e1c0c187c1f0000600740017c1f1c18
4afc: 00 00 00 ff .align $0100 (4 bytes)
; Checks to see if the paddle button was hit. If so, instead of returning this
; jumps to game mode.
CheckBtnStartGame
4b00: ad 61 c0 lda BUTN0 ;button 0 pressed?
4b03: 30 01 bmi :Pressed ;yes, start game
4b05: 60 L4B05 rts
4b06: 4c 3e 48 :Pressed jmp StartGame
4b09: 68 60 ff 00+ .junk 7
;
; Delay while showing title screen. Watch for paddle button.
;
4b10: a9 f0 LongDelay lda #240 ;loop for about 5.7 seconds
4b12: 48 pha
4b13: 68 :Loop pla
4b14: f0 ef beq L4B05 ;return, for "attract mode"
4b16: 38 sec
4b17: e9 01 sbc #$01
4b19: 48 pha
4b1a: a9 60 lda #96
4b1c: 20 a8 fc jsr MON_WAIT ;wait for about 24K cycles
4b1f: 20 00 4b jsr CheckBtnStartGame ;does not return if button hit
4b22: 4c 13 4b jmp :Loop
4b25: ea ff ff 00+ .junk 27
4b40: a9 00 AttractPlay lda #$00
4b42: 85 20 sta alien0
4b44: 85 30 sta alien1
4b46: 85 40 sta alien2
4b48: 85 50 sta alien3
4b4a: 85 60 sta alien4
4b4c: 85 70 sta alien5
4b4e: 85 80 sta alien6
4b50: 20 a0 1d jsr InitAlienStates ;set up aliens
4b53: a9 04 lda #$04 ;show the 1+2 ship
4b55: 85 f8 sta ship_stage
4b57: a9 05 lda #$05 ;put ship near left side
4b59: 85 f9 sta ship_pos_coarse
4b5b: a9 00 lda #$00
4b5d: 85 fa sta ship_pos_fine
4b5f: 85 fb sta ship_position_abs
4b61: 85 d0 sta bullet1_fired
4b63: 85 d9 sta bullet2_fired
4b65: 85 e2 sta bullet3_state
4b67: 20 00 0b :RightLoop jsr UpdateStarField ;animate while moving ship to the right
4b6a: 20 00 4b jsr CheckBtnStartGame
4b6d: 20 50 1d jsr _UpdateOneAlien
4b70: 20 00 4b jsr CheckBtnStartGame
4b73: 20 00 0d jsr DrawPlayerShip
4b76: 20 50 1d jsr _UpdateOneAlien
4b79: 20 70 0c jsr MoveShipRight
4b7c: 20 00 4b jsr CheckBtnStartGame
4b7f: 20 00 0b jsr UpdateStarField
4b82: 20 50 1d jsr _UpdateOneAlien
4b85: a5 f9 lda ship_pos_coarse
4b87: c9 22 cmp #34 ;near right edge?
4b89: 90 dc bcc :RightLoop ;no, keep going
4b8b: 20 00 0b :LeftLoop jsr UpdateStarField ;animate while moving ship to the left
4b8e: 20 00 4b jsr CheckBtnStartGame
4b91: 20 50 1d jsr _UpdateOneAlien
4b94: 20 00 4b jsr CheckBtnStartGame
4b97: 20 00 0d jsr DrawPlayerShip
4b9a: 20 50 1d jsr _UpdateOneAlien
4b9d: 20 86 0c jsr MoveShipLeft
4ba0: 20 00 4b jsr CheckBtnStartGame
4ba3: 20 00 0b jsr UpdateStarField
4ba6: 20 50 1d jsr _UpdateOneAlien
4ba9: a5 f9 lda ship_pos_coarse
4bab: c9 05 cmp #$05 ;near left edge?
4bad: b0 dc bcs :LeftLoop ;no, keep going
4baf: 60 rts ;yes, return to title screen
;
; "Attract mode" loop. Shows the title screen for a bit, then the game
; "playing" for a bit. If the paddle button is hit, the subroutines will jump
; directly to the start-game code.
;
• Clear variables
]screen_src .var $08 {addr/1}
4bb0: a9 80 AttractLoop lda #>blank_screen_image-$2000
4bb2: 85 08 sta ]screen_src
4bb4: 20 f0 46 jsr ScreenTransition ;clear to black
4bb7: 20 80 43 jsr DrawScoreBase ;draw scores
4bba: 20 10 44 jsr DrawCurScore
4bbd: 20 50 44 jsr DrawHighScore
4bc0: 20 40 4b jsr AttractPlay ;do some animation
4bc3: a9 60 lda #>title_screen_image-$2000
4bc5: 85 08 sta ]screen_src
4bc7: 20 f0 46 jsr ScreenTransition ;clear to title screen
4bca: 20 80 43 jsr DrawScoreBase ;draw scores
4bcd: 20 10 44 jsr DrawCurScore
4bd0: 20 50 44 jsr DrawHighScore
4bd3: 20 10 4b AttractEntry jsr LongDelay ;sit and spin for a bit
4bd6: 4c b0 4b jmp AttractLoop
4bd9: 00 ff ff 00+ .align $0100 (39 bytes)
.org $4f00
;
; Program init. Relocates sections to their final execution locations.
;
]ptr .var $00 {addr/2}
]mov_src .var $3c {addr/2} ;A1
]mov_src_end .var $3e {addr/2} ;A2
]mov_dst .var $42 {addr/2} ;A4
4f00: a0 00 Start ldy #$00
4f02: 84 3c sty ]mov_src
4f04: 84 42 sty ]mov_dst
4f06: a9 ff lda #$ff
4f08: 85 3e sta ]mov_src_end
4f0a: a9 08 lda #$08
4f0c: 85 43 sta ]mov_dst+1 ;dst=$800
4f0e: a9 16 lda #$16
4f10: 85 3d sta ]mov_src+1 ;src=$1600
4f12: a9 43 lda #$43
4f14: 85 3f sta ]mov_src_end+1 ;srcend=$43ff
4f16: 20 2c fe jsr MON_MOVE ;$1600-43ff -> $800-35ff
4f19: a9 4e lda #$4e
4f1b: 85 3f sta ]mov_src_end+1 ;srcend=$4eff
4f1d: a9 41 lda #$41
4f1f: 85 43 sta ]mov_dst+1 ;dst=$4100
4f21: 20 2c fe jsr MON_MOVE ;$4400-4eff -> $4100-4bff
4f24: e6 3d inc ]mov_src+1 ;src=$5000
4f26: a9 5f lda #$5f
4f28: 85 3f sta ]mov_src_end+1 ;srcend=$5fff
4f2a: a9 90 lda #$90
4f2c: 85 43 sta ]mov_dst+1 ;dst=$9000
4f2e: 20 2c fe jsr MON_MOVE ;$5000-5fff -> $9000-9fff
; Zero out $b0-b3. These get preserved when zero page is wiped during InitZP.
4f31: a9 00 lda #$00
4f33: 85 b0 sta cur_score_hi
4f35: 85 b1 sta cur_score_lo
4f37: 85 b2 sta high_score_hi
4f39: 85 b3 sta high_score_lo
; Zero out $a000-bfff. This is used as the source when we're doing a screen
; transition to a blank screen.
4f3b: a9 00 lda #<blank_screen_image
4f3d: 85 00 sta ]ptr
4f3f: a9 a0 lda #>blank_screen_image
4f41: 85 01 sta ]ptr+1
4f43: a0 00 ldy #$00
4f45: a9 00 :ZLoop lda #$00
4f47: 91 00 :Loop sta (]ptr),y
4f49: c8 iny
4f4a: d0 fb bne :Loop
4f4c: e6 01 inc ]ptr+1
4f4e: a5 01 lda ]ptr+1
4f50: c9 c0 cmp #>blank_screen_image+$2000
4f52: 90 f1 bcc :ZLoop
; Store some odd values in the keyboard input buffer and text screen (vestigial
; copy protection?)
4f54: a9 f0 lda #$f0
4f56: 8d 00 02 sta INPUT_BUFFER
4f59: a9 46 lda #$46
4f5b: 8d 01 02 sta INPUT_BUFFER+1
4f5e: ad 50 c0 lda TXTCLR
4f61: ad 57 c0 lda HIRES
4f64: ad 52 c0 lda MIXCLR
4f67: ad 54 c0 lda TXTPAGE1
4f6a: a9 01 lda #$01
4f6c: 8d f4 37 sta CP_SET_TO_ONE
4f6f: a9 7f lda #$7f
4f71: 8d 00 04 sta CP_SET_BY_INIT
4f74: a9 06 lda #$06
4f76: 8d 01 04 sta CP_SET_BY_INIT+1
4f79: a9 22 lda #$22
4f7b: 8d 02 04 sta CP_SET_BY_INIT+2
4f7e: a9 71 lda #$71
4f80: 8d 03 04 sta CP_SET_BY_INIT+3
4f83: 4c 80 48 jmp FunkyStartup
4f86: 00 00 ff ff+ .align $0100 (122 bytes)
.org $9000
; Second half of title screen image ($9000-9fff; image starts at $8000).
:title_screen_image_pt2
9000: 00 00 00 00+ .bulk 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000007c7f7f1f7c1f00007c07701f787f7f0f7c7f7f070000007c
+ 7f7f07787f7f0f787f7f0f7c7f7f1f0000000000000000000000000000102a04
+ 0060017c1f003800000000000000000000000000000000000000000000000000
+ 0000000000000040000400400000000000000000000000040040000210200104
+ 0004000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000040000408400000000000000000000000040040000a14021004
+ 080400000000000000022204080a083222080000000000000000000000000000
+ 0000000000020220000820220800000000000000000000000000000000302808
+ 0000007c1f3e3800000000000000000000000000000000000000000000000000
+ 0000000000000000000000000400040004000000040014204000000000000000
+ 00000000000000000000000000000000000000000000550000000060077c3f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000400040804000000040004204000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0001000400040020000200000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000028550a007003003c3e3c00
+ 0000000000000000000000000000000000000000000000000000000000200500
+ 0001000200000420000200000000000000000000000000000000000000000000
+ 7c1f400f7c1f701f707f7f077c1f781f7c1f00000000007c1f00007c1f701f7c
+ 1f701f7c1f400f0000000000000000000000000000c0a2810060017c3f7c1f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 607f7f077c7f7f017c7f7f1f7c1f00007c7f7f000000007c7f7f007c1f7f1f7c
+ 1f7f1f607f7f07000000000000000000000000000000aa00000000000f7e1f00
+ 00000000000000000000000000000000000000001c1e0c1c1c001c221c3e1c22
+ 0808222a00022a20000822001c08221e08000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000007c7f7f1f7c1f00007c0f701f707f7f0f7c7f7f0f0000007c
+ 7f7f0f707f7f0f707f7f0f7c7f7f1f0000000000000000000000000000002a00
+ 007003000e043800000000000000000000000000000000000000000000000000
+ 0000000000040000000010000004200400000004000420000000000000000000
+ 1000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000108a01
+ 000000780f600700000000000000000000000000000000000000000000000000
+ 0000000000081000000000000008100810000008100810000000000000000000
+ 0000000000000000002422040812082222080000000000000000000000000000
+ 000000000004241000081022080000000000000000000000000000000028012a
+ 0060011e3c3e3800000000000000000000000000000000000000000000000000
+ 0000000000000000000000000010001000000400000000000000040000000000
+ 000000000000000000000000000000000000000000d0aa850000006007003800
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000810000000000000081000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000000000002a152a14000000
+ 002a152a152a1520052a15000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000542a15007003003c3e3800
+ 000000000000000000000000000000000000000000000000002a142001000000
+ 002a142a14001420052a14000000000000000000000000000000000000000000
+ 7c1f40077c1f701f787f7f0f7c1f701f7c1f00000000007c1f00007c1f701f7c
+ 1f701f7c1f400700000000000000000000000000000000000000007e1f781f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 407f7f0f7c7f3f007c7f7f1f7c1f00007c7f3f000000007c7f3f007c1f7f1f7c
+ 1f7f1f407f7f0f0000000000000000000000000000d0aa85000000400f7e0f00
+ 0000000000000000000000000000000000000000040a04202000042220222422
+ 08082232000226200008220020083e0a08000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000787f7f0f7c1f00007c0f781f607f7f077c7f7f1f0000007c
+ 7f7f1f607f7f07607f7f07787f7f0f0000000000000000000000000000000800
+ 007003000e7e3f00000000000000000000000000000000000000000000000000
+ 0000000000000040000400400000000000000000000000040040000210100204
+ 0004000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000000000000000000090a284
+ 0000007c1f780f00000000000000000000000000000000000000000000000000
+ 0000000000200540000410400020052005000020052005040040000210012004
+ 10540a000000000000181c0e08221c3c221c00000000000000000000007c0f00
+ 0000000000081808001c0e1c1c0000000000000000000000000000000020450a
+ 0070031e3c3e3800000000000000000000000000000000000000000000000000
+ 0000000000000000000000000400040004000000040044204000000000000000
+ 00000000000000000000000000000000000000000094aa940060016007003800
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000004000410540a2005540a04204000200500000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0001000200020020000200000000000000000000000000000000000000000000
+ 407f7f01707f3f0000780f00007c3f00707f7f07000000707f7f0700783f0000
+ 783f00407f7f01000000000000000000000000000070c007006001601f3e3800
+ 0000000000000000000000000000000000000000000000000000000000200500
+ 0001000200000420000200000000000000000000000000000000000000000000
+ 7c1f00007c1f701f7c1f7c1f7c1f601f7c1f00000000007c1f00007c1f601f7c
+ 1f601f7c1f000000000000000000000000000000000000000000007c0f600700
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00007c1f7c1f00007c7f7f1f7c1f000f7c1f00000000007c1f00007c1f7c1f7c
+ 1f7c1f00007c1f0000000000000000000000000000d0aa85006001600f0e0000
+ 0000000000000000000000000000000000000000041224222200042222222422
+ 0808222200042210000822002208221208000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000707f7f077c1f00007c0f781f407f7f037c7f7f1f0000007c
+ 7f7f1f407f7f07407f7f07707f7f070000000000000000000000000000000800
+ 006001000e7c1f00000000000000000000000000000000000000000000000000
+ 0000000000080000000008000004200800000008000420000000000000000000
+ 0800000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000d08085
+ 0060017e3f7c1f00000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000080800000000060077e1f00
+ 0000000000000000000000000000000000000000000000000000000000204402
+ 0070031e3c3e3c00000000000000000000000000000000000000000000000000
+ 0000000000000000000000000008000800000800000000000000080000000000
+ 0000000000000000000000000000000000000000009488940070036007003800
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000000000002a142a14200500
+ 002a142a142a0020052a14000000000000000000000000000000000000000000
+ 607f7f03787f7f01007c1f00007e7f00787f7f0f000000787f7f0f007e7f0000
+ 7e7f00607f7f03000000000000000000000000000070c007000000700f3e3800
+ 000000000000000000000000000000000000000000000000002a152001000000
+ 002a142a142a1520052a14000000000000000000000000000000000000000000
+ 7c1f00007c1f701f7c0f781f7c1f400f7c1f00000000007c1f00007c1f401f7c
+ 1f401f7c1f000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000080800000000000000000000000
+ 00007c1f7c1f00007c7f7f1f7c1f401f7c1f00000000007c1f00007c1f781f7c
+ 1f7c1f00007c1f0000000000000000000000000000d4aa95007003700e7e0f00
+ 00000000000000000000000000000000000000000e223e1c1c000e1c1c221e1c
+ 1c1c1c2200081c08001c1c001c1c22221c000000000000000000000000000000
.org $6000
; Player ship, stage 1. 6x9
;
; Each successive image is shifted two pixels to the right. Thus, each image is
; two bytes (14 pixels) wider than it needs to be, to have room to shift over.
;
; The left edge of the ship bitmap is always drawn in an odd column for stages 1
; and 3, an even column for stage 2.
6000: 80 80 80 80+ T6000 .bulk 80808080808080c08180808080c081808080d0c8918a8080a8a182958080aceb
+ b5958080acebd5958080aceedd9580808cb08394808080808080808000000000
6040: 80 80 80 80+ T6040 .bulk 808080808080808086808080808086808080c0a2c6a88080a08589d48080b0ad
+ d7d58080b0add7d68080b0b9f7d68080b0c08dd0808080808080808000000000
6080: 80 80 80 80+ T6080 .bulk 808080808080808098808080808098808080808a99a281808095a4d08280c0b5
+ ddd68280c0b5ddda8280c0e5dddb8280c081b6c0828080808080808000000000
60c0: 80 80 80 80+ T60C0 .bulk 8080808080808080e08080808080e080808080a8e488858080d490c18a8080d6
+ f5da8a8080d6f5ea8a808096f7ee8a808086d8818a8080808080808000000000
6100: 80 80 80 80+ T6100 .bulk 80808080808080808083808080808083808080a091a3948080d0c284aa8080d8
+ d6ebaa8080d8d6abab8080d8dcbbab808098e086a88080808080808000000000
6140: 80 80 80 80+ T6140 .bulk 8080808080808080808c80808080808c80808080c58cd18080c08a92a88180e0
+ daaeab8180e0daaead8180e0f2eead8180e0809ba08180808080808000000000
6180: 80 80 80 80+ T6180 .bulk 808080808080808080b08080808080b08080808094b2c4828080aac8a0858080
+ ebbaad858080ebbab5858080cbbbb785808083ec808580808080808000000000
; Player ship, stage 2. 8x12
61c0: 80 80 80 80+ T61C0 .bulk 8080808080808080a080c08180828080a080e08280828080d080e083c0828080
+ b085e893b0858080d8daaef5da8a8080d8ea8ad1d68a8080d8ea8ad1d58a8080
+ d8aa8bf1d48a8080988aac8d948a80809888f085888c80808080808080808080
6220: 80 80 80 80+ T6220 .bulk 808080808080808080818086808880808081808b80888080c082808f808a8080
+ c095a0cfc0958080e0eabad5ebaa8080e0aaabc4daaa8080e0aaabc4d6aa8080
+ e0aaadc4d3aa8080e0a8b0b5d0a88080e0a0c097a0b080808080808080808080
6280: 80 80 80 80+ T6280 .bulk 80808080808080808084809880a08080808480ac80a08080808a80bc80a88080
+ 80d680bd82d6808080abebd5aeab818080abad91eaaa818080abad91daaa8180
+ 80abb591ceaa818080a3c1d5c1a28180808381de80c181808080808080808080
62e0: 80 80 80 80+ T62E0 .bulk 8080808080808080809080e080808180809080b08180818080a880f081a08180
+ 80d882f489d8828080acadd7baad858080acb5c5a8ab858080acb5c5e8aa8580
+ 80acd5c5b8aa8580808c85d6868a8580808c84f8828486808080808080808080
6340: 80 80 80 80+ T6340 .bulk 808080808080808080c080808380848080c080c08580848080a081c087808580
+ 80e08ad0a7e08a8080b0b5ddeab5958080b0d595a2ad958080b0d595a2ab9580
+ 80b0d596e2a9958080b094d89aa8948080b090e08b9098808080808080808080
63a0: 80 80 80 80+ T63A0 .bulk 8080808080808080808082808c8090808080828096809080808085809e809480
+ 8080abc09e81ab8080c0d5f5aad7d58080c0d5d688b5d58080c0d5d688add580
+ 80c0d5da88a7d58080c0d1e0eaa0d18080c0c180afc0e0808080808080808080
6400: 80 80 80 80+ T6400 .bulk 808080808080808080808880b080c08080808880d880c08080809480f880d080
+ 8080ac81fa84ac818080d6d6abddd6828080d6daa2d4d5828080d6daa2b4d582
+ 8080d6eaa29cd5828080c682ab83c58280808682bc8182838080808080808080
; Player ship, stage 3. 10x12
6460: 80 80 80 80+ T6460 .bulk 80808080808080808080a08080e0808080828080a08080b0818080828080a081
+ c0f1c181c0828080f083e8f3e98bf8868080d8daaef7dabaad8d8080d8eaaadd
+ d6eaab8d8080d8eaaa95d5aaab8d8080d8aaabf5d6eaaa8d808098aaac8ddc9a
+ 8a8c80809888f08dec87888c8080808080908280808080808080808080808080
64e0: 80 80 80 80+ T64E0 .bulk 8080808080808080808080818080838080888080808180c08580808880808085
+ 80c68786808a8080c08fa0cfa7afe09b8080e0eabaddebeab5b58080e0aaabf5
+ daaaafb58080e0aaabd5d4aaadb58080e0aaadd5dbaaabb58080e0a8b1b5f0ea
+ a8b08080e0a0c0b7b09fa0b08080808080c08880808080808080808080808080
6560: 80 80 80 80+ T6560 .bulk 80808080808080808080808480808c8080a0808080848080968080a080808094
+ 80989e9880a8808080be80bd9ebd81ef808080abebf5aeabd7d5818080abadd5
+ ebaabdd5818080abadd5d2aab5d5818080abb5d5eeaaadd5818080a3c5d5c1ab
+ a3c18180808381dec1fd80c1818080808080a280808080808080808080808080
65e0: 80 80 80 80+ T65E0 .bulk 8080808080808080808080908080b0808080818080908080d8808080818080d0
+ 80e0f8e080a0818080f881f4f9f485bc838080acadd7bbadddd6868080acb5d5
+ aeabf5d5868080acb5d5caaad5d5868080acd5d5baabb5d58680808c95d686ae
+ 8d858680808c84f886f683848680808080808881808080808080808080808080
6660: 80 80 80 80+ T6660 .bulk 8080808080808080808080c08080c0818080848080c08080e0828080848080c0
+ 8280e3838380858080e087d0e7d397f08d8080b0b5ddeeb5f5da9a8080b0d5d5
+ baadd5d79a8080b0d5d5aaaad5d69a8080b0d5d6eaadd5d59a8080b0d4d89ab8
+ b594988080b090e09bd88f90988080808080a084808080808080808080808080
66e0: 80 80 80 80+ T66E0 .bulk 808080808080808080808080828080868080908080808280808b808090808080
+ 8a808c8f8c80948080809fc09ecfdec0b78080c0d5f5bad7d5ebea8080c0d5d6
+ eab5d5deea8080c0d5d6aaa9d5daea8080c0d5daaab7d5d6ea8080c0d1e2eae0
+ d5d1e08080c0c180efe0bec0e080808080808091808080808080808080808080
6760: 80 80 80 80+ T6760 .bulk 808080808080808080808080888080988080c0808080888080ac8080c0808080
+ a880b0bcb080d0808080fc80fabcfa82de818080d6d6ebddd6aeab838080d6da
+ aad7d5faaa838080d6daaaa5d5eaaa838080d6eaaaddd5daaa838080c68aab83
+ d7c6828380808682bc83fb8182838080808080c4808080808080808080808080
67e0: 80 80 00 00+ .junk 37
; Exhaust animation, frame 1. 5x21
6805: 80 80 80 80+ T6805 .bulk 808080808080a0808080808284808080c88180808080808080c0c891808080e4
+ 848080808a85808080f18880808080808080c088918080808c83808080808080
+ 8080a284808080f08080808080808080808881808080a080808080a080808080
+ 80808080808080808000008080808080
6875: 80 80 80 80+ T6875 .bulk 80808080808080818080808890808080a0868080808080808080a2c680808090
+ 93808080a894808080c4a38080808080808080a2c4808080b08c808080808080
+ 80808891808080c0838080808080808080a08480808080818080808081808080
+ 80808080808080808000008080808080
68e5: 80 80 80 80+ T68E5 .bulk 8080808080808084808080a0c0808080809980808080808080808899828080c0
+ cc808080a0d1808080908e81808080808080808891828080c0b1808080808080
+ 8080a0c4808080808e8080808080808080809180808080848080808084808080
+ 80808080808080808000008080808080
6955: 80 80 80 80+ T6955 .bulk 8080808080808090808080808182808080e48080808080808080a0e488808080
+ b282808080c5828080c0b88480808080808080a0c488808080c6818080808080
+ 8080809182808080b8808080808080808080c480808080908080808090808080
+ 80808080808080808000008080808080
69c5: 80 80 80 80+ T69C5 .bulk 80808080808080c08080808084888080809083808080808080808091a3808080
+ c889808080948a808080e291808080808080808091a280808098868080808080
+ 808080c488808080e08180808080808080809082808080c080808080c0808080
+ 80808080808080808000008080808080
6a35: 80 80 80 80+ T6A35 .bulk 80808080808080808280808090a0808080c08c8080808080808080c48c818080
+ a0a6808080d0a880808088c78080808080808080c488818080e0988080808080
+ 80808090a280808080878080808080808080c088808080808280808080828080
+ 80808080808080808000008080808080
6aa5: 80 80 80 80+ T6AA5 .bulk 808080808080808088808080c08081808080b2808080808080808090b2848080
+ 8099818080c0a2818080a09c828080808080808090a284808080e38080808080
+ 808080c088818080809c808080808080808080a2808080808880808080888080
+ 8080808080808080800000
; Exhaust animation, frame 2. 5x21
6b10: 80 80 80 80+ T6B10 .bulk 8080808080808080808080a0808080808284808080888180808080808080c088
+ 91808080a08080808082848080c0a09080808084828080c0a090808080888180
+ 80808080808080a284808080a080808080808080808088818080808080808080
+ a0808080808080808080808080800000
6b80: 80 80 80 80+ T6B80 .bulk 808080808080808080808080818080808890808080a0848080808080808080a2
+ c48080808081808080889080808082c1808080908880808082c1808080a08480
+ 80808080808080889180808080818080808080808080a0848080808080808080
+ 80818080808080808080808080800000
6bf0: 80 80 80 80+ T6BF0 .bulk 80808080808080808080808084808080a0c08080808091808080808080808088
+ 918280808084808080a0c08080808884828080c0a08080808884828080809180
+ 80808080808080a0c48080808084808080808080808080918080808080808080
+ 80848080808080808080808080800000
6c60: 80 80 80 80+ T6C60 .bulk 80808080808080808080808090808080808182808080c48080808080808080a0
+ c488808080908080808081828080a0908880808082818080a09088808080c480
+ 8080808080808080918280808090808080808080808080c48080808080808080
+ 80908080808080808080808080800000
6cd0: 80 80 80 80+ T6CD0 .bulk 808080808080808080808080c080808080848880808090828080808080808080
+ 91a2808080c0808080808488808080c1a08080808884808080c1a08080809082
+ 8080808080808080c488808080c0808080808080808080908280808080808080
+ 80c08080808080808080808080800000
6d40: 80 80 80 80+ T6D40 .bulk 808080808080808080808080808280808090a0808080c0888080808080808080
+ c488818080808280808090a08080808482818080a0908080808482818080c088
+ 808080808080808090a280808080828080808080808080c08880808080808080
+ 80808280808080808080808080800000
6db0: 80 80 80 80+ T6DB0 .bulk 8080808080808080808080808088808080c08081808080a28080808080808080
+ 90a28480808088808080c080818080908884808080c1808080908884808080a2
+ 8080808080808080c0888180808088808080808080808080a280808080808080
+ 80808880808080808080808080800000
; Exhaust animation, frame 3. 5x21
6e20: 80 80 80 80+ T6E20 .bulk 8080808080808080808080a0808080808284808080888180808080808080c088
+ 91808080a0808080808284808080a0808080808881808080a080808080a08080
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
6e90: 80 80 80 80+ T6E90 .bulk 808080808080808080808080818080808890808080a0848080808080808080a2
+ c4808080808180808088908080808081808080a0848080808081808080808180
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
6f00: 80 80 80 80+ T6F00 .bulk 80808080808080808080808084808080a0c08080808091808080808080808088
+ 918280808084808080a0c0808080808480808080918080808084808080808480
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
6f70: 80 80 80 80+ T6F70 .bulk 80808080808080808080808090808080808182808080c48080808080808080a0
+ c488808080908080808081828080809080808080c48080808090808080809080
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
6fe0: 80 80 80 80+ T6FE0 .bulk 808080808080808080808080c080808080848880808090828080808080808080
+ 91a2808080c0808080808488808080c0808080809082808080c080808080c080
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
7050: 80 80 80 80+ T7050 .bulk 808080808080808080808080808280808090a0808080c0888080808080808080
+ c488818080808280808090a08080808082808080c08880808080828080808082
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
70c0: 80 80 80 80+ T70C0 .bulk 8080808080808080808080808088808080c08081808080a28080808080808080
+ 90a28480808088808080c080818080808880808080a280808080888080808088
+ 8080808080808080808080808080808080808080808080808080808080808080
+ 80808080808080808080808080800000
;
; Aliens, first set (3x12). There are two sets, which have the same bitmaps but
; the colors shifted so things don't shimmer when drawn in odd vs. even columns.
;
; The second set has the same low byte, but the high byte is $7dxx instead of
; $71xx. These must all start on the same page in memory.
;
7130: 40 22 01 20+ alien_img_lips .bulk 402201205502502a0528550a542a1570c00770c007d4aa95a8d58ad0aa85a0d5
+ 82c0a281000000000000000000000000
7160: 00 aa 00 d0+ alien_img_wolf .bulk 00aa00d0aa85d0aa85d4aa95d4aa95542a15502a05102a04102a04002a000008
+ 00000800000000000000000000000000
7190: 00 aa 00 d0+ alien_img_egg .bulk 00aa00d0aa85d0aa85d4aa95d4aa95502a05502a0528552a28552a20550a2055
+ 0a005400000000000000000000000000
alien_img_fuzzball
71c0: 10 8a 01 90+ .bulk 108a0190a284d08085d4949490f284127a5214721030280828012a20450a2044
+ 02085404000000000000000000000000
alien_img_spider
71f0: 00 00 00 02+ .bulk 0000000242202a492a28410a205502005500d0aa8594aa94948894c4889184c9
+ 90000800
7214: 00 00 00 00+ L7214 .junk 12
7220: 84 a0 90 b0+ egg_hatch_img .bulk 84a090b0889484848c85808084a12090920c808000908031849400c6a08cd180
+ 94908091000000000000000000000000
; egg appearance animation (3x12)
7250: 00 00 00 c0+ egg_img_large .bulk 000000c0aa81c0aa81d0aa85d0aa85402a01402a0120550a20550a0055020055
+ 02000000000000000000000000000000
7280: 00 00 00 00+ egg_img_medium .bulk 00000000000080aa80c0aa81c0aa81002a00002a000055020055020054000000
+ 00000000000000000000000000000000
72b0: 00 00 00 00+ egg_img_small .bulk 00000000000000000000aa8000aa80002a00002a000054000054000000000000
+ 00000000000000000000000000000000
72e0: 80 80 00 00+ egg_img_tiny .bulk 80800000000000808000808000a8800068000028000050000000000000000000
+ 00000000000000000000000000000000
; Alien explosions are 4x20.
alien_explosion_1
7310: 81 82 c0 a0+ .bulk 8182c0a08582c1a0848890889088908890a0848281808080840000a89000008a
+ 900000828400008884000088900000829000008a840000a8c1a0848090a08482
+ 90889088848890888582c1a08182c0a0
alien_explosion_2
7360: 40 88 80 80+ .bulk 4088808045a0906804a2902a10a2c10244a0c4880580808884000080900000a0
+ 840000a0800000a88400008a90000080100000080400002841a0844014a0c442
+ 5088d148448290484480c1200182c020
73b0: 00 00 00 00+ .align $0100 (80 bytes)
;
; Digits 0-9, for the center of the graphic that appears when you shoot an
; enemy.
;
; Glyphs are 1 byte * 7 rows, with a stride of 16. Top line is $7400+val,
; second line is $7410+val, and so on.
;
7400: 1c 08 1c 3e+ small_digits .bulk 1c081c3e103e383e1c1c000000000000220c2220180204202222000000000000
+ 32082010141e021022220000000000002a08181812201e081c3c000000000000
+ 260804203e202204222000000000000022080222102222042210000000000000
+ 1c1c3e1c101c1c041c0e000000000000
;
; Digits for the current / high score display. Glyphs are 2 bytes * 7 rows,
; with a stride of 24 ($18).
;
7470: 70 07 00 01+ digit_row0 .bulk 700700015002a89580827c1f0015540aa085d08280808080
7488: 0c 18 20 01+ digit_row1 .bulk 0c18200104088090c0820c00200000088890848880808080
74a0: 0c 1e 00 01+ digit_row2 .bulk 0c1e00010008808490827c07080000028890848880808080
74b8: 4c 19 00 01+ digit_row3 .bulk 4c190001400280858482001828054000a085d08a80808080
74d0: 3c 18 00 01+ digit_row4 .bulk 3c18000110008090d48a0018081010008890808880808080
74e8: 0c 18 00 01+ digit_row5 .bulk 0c1800010400889080820c18081010008890808280808080
7500: 70 07 20 05+ digit_row6 .bulk 70072005540aa0858082700720051000a085d48080808080
7518: 00 00 00 00+ .junk 8
;
; Graphic for "SCORE:0000 HI:0000". 40 bytes wide, 7 lines high.
;
base_score_image
7520: 70 07 00 05+ .bulk 700700055002a885d48a00007007700770077007000000000c18a08500007007
+ 70077007700700000c18201004088890908870010c180c180c180c1800000000
+ 0c18808170010c180c180c180c1800000c00080004088890908070010c1e0c1e
+ 0c1e0c1e000000000c18808170010c1e0c1e0c1e0c1e0000700708000408a885
+ d08000004c194c194c194c19000000007c1f808100004c194c194c194c190000
+ 0018080004088881908070013c183c183c183c18000000000c18808170013c18
+ 3c183c183c1800000c18201004088884908870010c180c180c180c1800000000
+ 0c18808170010c180c180c180c1800007007000550028890d48a000070077007
+ 70077007000000000c18a085000070077007700770070000
7638: 00 00 00 00+ .junk 8
;
; Ship explosion animation. 7 frames, 10x24, 240 bytes.
;
7640: 00 00 00 00+ explode0 .bulk 000000009400000080808080000094000080818080880000c40000a8818000a0
+ 8100d58000aa80000080d582d180d08280000080d0aad1a2d58200000000d5be
+ 858ad58000000080c4fe81fe9580808000a895a2c5ae95a08080c0a2d1b0c5a6
+ 94808180c0a8d580c18090008580008095888082d08085800080c1cae78bc080
+ 808000a0d08aa58f848280000080d4eac7bfd18880000080d5e281f8c5828000
+ 00a0d5a0858a858a800000a88500d1aa94aa808080a88000d580c4a880808082
+ 8000d40090a08180808000009400848085808000000094008080818080000000
+ 90000080808000000000000000000000
7730: 80 00 00 00+ explode1 .bulk 80000000000000000000800000a080808000c00080800088808080008000c080
+ 0088c18080808000808a00fad1b8c080810090a08182d084d0a88100c0808583
+ c684d68800000080c483c7a6d5800000008af4aa8daa8580000000a8f588c1aa
+ 8100810000a0b5e0e1a3c80080000000f5c080809700808000c0c7ae80e097a0
+ 818000c0908297fcd5a8910000e0858cf6fb9382840000b0818ae4ffc0888000
+ 00b0c08af093c082800000b8c0bed08af0aa800080e0e1bbd784fc82800080aa
+ ffe3d5f8ffa8808080aa0000d4f0d7a88580c0820000840000808080c0820000
+ 940000808180800000009400000080a0
7820: 90 80 00 00+ explode2 .bulk 908000000000000080008080e087000000808400c0a0e085fc00818081000082
+ b1a6d7f983a0850000a8dfb395cfd780810000e097d0940084a0810000e0d48c
+ f18087ba000000b0d487f885d19a000000b0f4838f87fc8e000000e0f98b9000
+ e78300000000a8808000b8a000000000b880808488808100008af080809eb8be
+ 85000080d083f88f8eae850000b8f09df0afc7be000000b0d487f1fb819f0000
+ 00f0c5feffca87ae000000f0d5b8de8a8faf800000baff00d482fc89808000ea
+ 8100d400c0aa8180c08a0000800000a88180c0800000900000a08180c0000000
+ 90000080858000000000000000808080
7910: 00 00 f8 83+ explode3 .bulk 0000f8830000008000000080fd000000008000000000d482b900008000000000
+ c6a2cf82f0880000000093dac3fed98f8100008097bcd4a7fa8f00000080d784
+ e4afe08387000000df87b5bcc08281000000ff81c198c08300000000fc0000bc
+ c08a00000000e00000fe878b84000000a00090fbff8900000000e0f9d0b3d088
+ 8800000090defb00c08a00000000d4f0be9e88aa0000000094c09f8fdcaa0000
+ 00008500909dd78881000080810080e1c38a810000a0000084f88088850000a0
+ 00008400c0008400000000000000c00000000000000000000000000000000000
+ 00000000000000000000000000000000
7a00: 00 00 00 00+ explode4 .bulk 00000000000000000000000000009000000000000000c082c082009000000000
+ d00000e0bbb000000000c0e8c7bae0b900000000c082cc8ae0a900000000e0a2
+ b888f8b100000000a080808f889c00000000a5808083dc9f00000080e10000b9
+ e0810000008081a087dfffab8100000000f881dcffaa00000000c0ca83880083
+ 000000809184c2f88381000000800000d4b1829f000000808100d4a2829f0000
+ 00800082d0f08e870000008800f89100f0000000008000a00000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000
7af0: 00 00 00 00+ explode5 .bulk 0000000000000000000000000000000000000000000000000000000000000000
+ 0000009482000000000000f0b8009c000000008085c0880090000000008084d0
+ 84809c0000000000949c8580b9820000000000878480bc0081000000d4838c80
+ 8f0000000000008e8c00de83000000000080b8ecc300810000008198f0fb8f00
+ 00000000a080c0ffc7f000000080b000e0818e8100000000d0a3849000000000
+ 0000a0ea87f0810000000000a0fec390f9a800000000a000d292fea000000000
+ 0080d5f2bf00000000000000b080828000000000000000c28300000000000000
+ 00000000000000000000000000000000
7be0: 00 00 00 00+ explode6 .bulk 000000000000000000000000000000c0000000000000000000c0810000000000
+ 00809000810000000000848085c400000000000080809400870000000080818c
+ 9400888600000080808c9482008700000000c08c90a0008400000000009c808a
+ aa000000000088f000be0000000000c000c000ae81840000000000c000a88300
+ 00000000008285a081000000000084a08584900000000000a0a2810000820000
+ 000000000088000000000000c000000000000000000000000000000000000000
+ 0000009000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000
7cd0: 00 00 00 00+ .junk 96
;
; Aliens, second set. These have their odd/even pattern flipped. The first set
; has the same low byte for the address, but are at $71xx instead of $7dxx.
;
7d30: 00 45 02 40+ alien_img_lips2 .bulk 004502402a0520550a502a1528552a60810f60810fa8d5aad0aa95a0d58ac0aa
+ 8580c582000000000000000000000000
7d60: 00 d4 00 a0+ alien_img_wolf2 .bulk 00d400a0d58aa0d58aa8d5aaa8d5aa28552a20550a2054082054080054000010
+ 00001000000000000000000000000000
7d90: 00 d4 00 a0+ alien_img_egg2 .bulk 00d400a0d58aa0d58aa8d5aaa8d5aa20550a20550a502a55502a55402a15402a
+ 15002801000000000000000000000000
alien_img_fuzzball2
7dc0: 20 94 02 a0+ .bulk 209402a0c488a0818aa8a9a8a0e489247425296421605010500254400a154008
+ 05102809000000000000000000000000
alien_img_spider2
7df0: 00 00 00 04+ .bulk 000000040441541255500215402a05002a01a0d58aa8d4a8a890a88891a28892
+ a1001000000000000000000000000000
7e20: 88 80 80 80+ .junk 480
; First half of title screen image (which runs $8000-9fff).
title_screen_image
8000: 00 00 00 00+ .bulk 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000007c1f7c1f00007c7f7f1f7c1f401f7c1f00000000007c
+ 1f00007c1f701f7c1f701f00007c1f0000000000000000000000000000d4aa95
+ 007003380e7e1f00000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000607f7f03780f0000780f780f007e7f01787f7f0f00000078
+ 7f7f0f007e7f01007e7f01607f7f030000000000000000000000000000000000
+ 0000000004780f00000000000000000000000000000000000000000000000000
+ 0000000000200540005402400000002005000020050000540240004210280554
+ 025402000000000000181c1e221e1c1c223e0000000000000000000000000000
+ 000000000008180800081c1c0800000000000000000000000000000000d49494
+ 0070031e3c3e3c00000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000002422000600170077e0f00
+ 0000000000000000000000000000000000000000000000000000000000085404
+ 0060017e3f7c1f00000000000000000000000000000000000000000000000000
+ 0000000000000000000000005402540254022005540204224000200500000000
+ 000000000000000000000000000000000000000000c488910070036007043800
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0001000200020020000200000000000000000000000000000000000000000000
+ 707f7f077c7f7f07007e3f00407f7f017c7f7f1f0000007c7f7f1f407f7f0140
+ 7f7f01707f7f070000000000000000000000000000d4aa95000000601f3e3800
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0001000200020020000200000000000000000000000000000000000000000000
+ 7c7f3f007c7f7f1f7c07701f7c1f00007c7f3f000000007c7f3f007c1f00007c
+ 1f00007c7f3f0000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000008080808000000000808080
+ 8000000000000000008080808000000000808000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000007c1f7c1f00007c7f7f1f7c1f601f7c1f00000000007c
+ 1f00007c1f701f7c1f701f00007c1f0000000000000000000000000000542a15
+ 0060011c0e7c3f00000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000407f7f01700700007007700700783f00707f7f0700000070
+ 7f7f0700783f0000783f00407f7f010000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000001000000000000004200010000000100420000000000000000000
+ 00000000000000000024222422220822222a0000000000000000000000000000
+ 0000000000042410000c22220c0000000000000000000000000000000090f284
+ 0070031e3c3e3800000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000002a492a00700378070e0000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000007c1f781f00000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000010000000000000001000000000
+ 00000000000000000000000000000000000000000084c99000600160077e3f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000004022010000007c0f600700
+ 000000000000000000000000000000000000000000000000002a052805200500
+ 002a142a152a0520052a15000000000000000000000000000000000000000000
+ 787f7f0f7c7f7f0f007f7f00607f7f037c7f7f1f0000007c7f7f1f607f7f0360
+ 7f7f03787f7f0f0000000000000000000000000000a8d58a006001003c3e3800
+ 000000000000000000000000000000000000000000000000002a052001000000
+ 002a142a142a0520052a14000000000000000000000000000000000000000000
+ 7c7f7f007c7f7f1f7c07701f7c1f00007c7f7f000000007c7f7f007c1f00007c
+ 1f00007c7f7f0000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000001e1e3e1c1c001e221c221e22
+ 3e3e1c2200081c08003e1c001c3e081e3e000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000070017c1f7c1f00007c07701f7c1f701f7c1f00000000007c
+ 1f00007c1f701f7c1f701f70017c1f0000000000000000000000000000502a05
+ 0000007e1f003800000000000000000000000000000000000000000000000000
+ 0000000000200540005402400000002005000020052005540a2a150210400054
+ 02540a0000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000040004400400000000000000000000000040040002211040844
+ 0004000000000000000222241422080222080000000000000000000000000000
+ 0000000000020220000822220800000000000000000000000000000000127a52
+ 0060017c1f3e3800000000000000000000000000000000000000000000000000
+ 00000000000000000000000054025402540a2005540a04202a15200500000000
+ 00000000000000000000000000000000000000000028410a00700370077e0f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000780f600700000000000000000000000000000000000000000000000000
+ 0000000000000000000000000400440004000000040004284000000000000000
+ 00000000000000000000000000000000000000000000080000000060077c1f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000002055020000007e1f780f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0001000200000020000200000000000000000000000000000000000000000000
+ 7c7f7f1f7c7f7f1f407f7f01707f7f077c7f7f0f0000007c7f7f0f707f7f0770
+ 7f7f077c7f7f1f0000000000000000000000000000d0aa85007003003c3e3800
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 787f7f017c7f7f0f7c07701f7c1f00007c7f7f010000007c7f7f017c1f00007c
+ 1f0000787f7f0100000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000242224222200242222222422
+ 2a2a222200042210002a2200222a14222a000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000078017c1f7c1f00007c07701f7c1f781f7c1f00000000007c
+ 1f00007c1f701f7c1f701f78017c1f0000000000000000000000000000102a04
+ 0000007e3f003800000000000000000000000000000000000000000000000000
+ 0000000000081000000008000004200810000008100810000000000000000000
+ 0800000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000042000000002000004200420000004200420000000000000000000
+ 02000000000000000002221c081e08023e080000000000000000000000000000
+ 000000000002022000083c1c0800000000000000000000000000000000147210
+ 000000780f3e3800000000000000000000000000000000000000000000000000
+ 0000000000000000000000000008000800000810000000000000081000000000
+ 00000000000000000000000000000000000000000020550200600160077e1f00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000200000420000000000000042000000000
+ 0000000000000000000000000000000000000000000000000000004003780f00
+ 000000000000000000000000000000000000000000000000002a052a14000000
+ 002b052805281520052a05000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000502a050060017c3f7c1f00
+ 000000000000000000000000000000000000000000000000002a152001000000
+ 002a142a15281520052a05000000000000000000000000000000000000000000
+ 7c7f7f1f7c7f7f1f607f7f03787f7f0f7c7f7f070000007c7f7f07787f7f0f78
+ 7f7f0f7c7f7f1f0000000000000000000000000000a0d582007003003c3e3c00
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 707f7f037c7f7f077c07701f7c1f00007c7f7f010000007c7f7f017c1f00007c
+ 1f0000707f7f03000000000000000000000000000000000000000000067c0f00
+ 0000000000000000000000000000000000000000242204020200242202222422
+ 0808222600023220000822000208222208000000000000000000000000000000