aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.makepp/defender.ca65.mk13
-rw-r--r--.makepp/log31
-rw-r--r--Makefile35
-rw-r--r--README26
-rw-r--r--defender.8humans.rombin0 -> 16384 bytes
-rw-r--r--defender.ca657818
-rw-r--r--defender.info593
-rw-r--r--defender.rombin0 -> 16384 bytes
-rw-r--r--deftest.lbl918
-rwxr-xr-xdumpfont.pl35
-rwxr-xr-xdumpgr.pl35
-rw-r--r--dumpgttxt.c20
-rw-r--r--dumptxt.c88
-rw-r--r--notes562
-rw-r--r--spritebug.pngbin0 -> 1729 bytes
15 files changed, 10174 insertions, 0 deletions
diff --git a/.makepp/defender.ca65.mk b/.makepp/defender.ca65.mk
new file mode 100644
index 0000000..93ab342
--- /dev/null
+++ b/.makepp/defender.ca65.mk
@@ -0,0 +1,13 @@
+META_DEPS=/usr/bin/da65
+IMPLICIT_DEPS=
+CWD=.
+DEP_SIGS=1499129342,968801506110399,49693
+SORTED_DEPS=/usr/bin/da65defender.info
+INCLUDE_PATHS=
+INCLUDE_SFXS=
+SIGNATURE=1506110479,592061
+IMPLICIT_TARGETS=
+COMMAND=da65 -i defender.info
+BUILD_SIGNATURE=1506110479,592061
+ARCH=x86_64-linux-thread-multi
+END= \ No newline at end of file
diff --git a/.makepp/log b/.makepp/log
new file mode 100644
index 0000000..fcae16e
--- /dev/null
+++ b/.makepp/log
@@ -0,0 +1,31 @@
+3/usr/bin/makepp
+VERSION2.05.22.2x86_64-linux-thread-multi
+LOAD31659240Makefile22826000/export/home/urchlay/atari800_devel/defender22826000
+TRY31659240
+USEdefault rule
+DEPEND31659240
+UP_TO_DATE31659240
+LOAD_REC31659240
+LOAD_INCL20821792makepp_builtin_rules.mk31410024/usr/share/makepp31659240
+LOAD_END31659240
+TRY31661088all22826000
+USEdefault rule
+DEPEND3166108820820736defender.ca6522826000
+TRY20820736
+USE/export/home/urchlay/atari800_devel/defender/Makefile:3
+SCAN_INFO20820736
+CACHED_DEP31815520da6531815256/usr/bin20820736
+TRY31815520
+USEdefault rule
+DEPEND31815520
+UP_TO_DATE31815520
+SCAN_CACHED20820736
+DEPEND208207363181552031743264defender.info22826000
+TRY31743264
+USEdefault rule
+DEPEND31743264
+UP_TO_DATE31743264
+UP_TO_DATE20820736
+BUILD_PHONY31661088
+SUCCESSdefault rule31661088
+N_FILES010
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..77a4a94
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,35 @@
+all: defender.ca65
+
+html: defender.html
+
+test: deftest.rom
+
+clean:
+ rm -f *.o tmp.lbl 1 2 3 foo bar .*.swp deftest.rom dumptxt dumpgttxt
+
+push:
+ touch defender.info
+ $(MAKE) clean all html
+ git push
+
+tools: dumpgttxt dumptxt
+
+defender.ca65: defender.info
+ da65 -i defender.info
+
+defender.html: defender.ca65
+ vim +TOhtml '+w!defender.html' '+qall' defender.ca65
+
+deftest.rom: defender.ca65
+ ca65 -t none -o deftest.o -g defender.ca65
+ ld65 -t none -o deftest.rom -Ln tmp.lbl --start-addr 0x8000 deftest.o
+ @grep -v '\.__' tmp.lbl | sed 's, \., ,' > deftest.lbl
+ @rm -f tmp.lbl *.o
+ @echo
+ @cmp defender.rom deftest.rom && echo "=== Binary reassembles correctly" || echo "*** Binary FAILS to reassemble correctly ***"
+ @echo ; echo "-----------------------"
+ @echo labels add deftest.lbl
+ @echo "-----------------------" ; echo
+ @atari800 -nobasic -cart-type 2 -cart deftest.rom
+
+.PHONY: all clean push html
diff --git a/README b/README
new file mode 100644
index 0000000..7a54f8a
--- /dev/null
+++ b/README
@@ -0,0 +1,26 @@
+This will be a commented disassembly of the Atari 8-bit computer
+Defender cartridge.
+
+I found 2 versions of the ROM. "defender.rom" is from here:
+
+http://www.atarimania.com/game-atari-400-800-xl-xe-defender_1561.html
+
+defender.8humans.rom is found in both the Holmes Archive and the TOSEC
+collection (Atari_8_bit_TOSEC_2012_04_23.zip).
+
+These are almost identical. See "notes" for differences between the two
+images. It turns out that the 8 humans version is a badly done crack,
+that must have been converted from a cracked XEX back into a ROM!
+
+$ md5sum *.rom
+e8d52b4aa33da38f99312f9aa8b48885 defender.8humans.rom
+8709351e76ec7c407e63c47ac53f8d19 defender.rom
+
+Disassembly is done with da65 (from the cc65 suite), using the old
+"edit the da65 .info file, disassemble, name things, edit again, etc"
+cycle. At some point, I'll clean up the formatting to make it look more
+human-readable, and use some conditional assembly (ifdefs) to allow
+assembling either version, and maybe as either a .xex or a ROM.
+
+At any point, you can check whether the disassembly really assembles
+back into the original ROM image by running "make test".
diff --git a/defender.8humans.rom b/defender.8humans.rom
new file mode 100644
index 0000000..4568be2
--- /dev/null
+++ b/defender.8humans.rom
Binary files differ
diff --git a/defender.ca65 b/defender.ca65
new file mode 100644
index 0000000..ea33929
--- /dev/null
+++ b/defender.ca65
@@ -0,0 +1,7818 @@
+; da65 V2.16 - Git 6de78c5
+; Created: 2017-09-22 16:02:17
+; Input file: defender.rom
+; Page: 1
+
+
+ .setcpu "6502"
+
+; ----------------------------------------------------------------------------
+POKMSK := $0010
+RTCLOK := $0012
+ATRACT := $004D
+preshift_ptr := $0080 ; argument to preshift_sprite
+tmp_y := $0082
+tmp_hoffset_l := $0083
+tmp_height := $0084
+animation_counter:= $0085 ; for animated sprites, used to decide which frame to draw
+level_jiffies_lo:= $0087 ; init to 0 at start of level, increments every frame while game is playing
+ship_move_delay := $0093 ; counts 0-$FF (XXX how often? per-frame?), ship only moves (?) when low 2 bits == 3 (?)
+level := $009A ; player 1 only?
+landers_to_spawn:= $009B ; total # of landers to spawn, on this level. each wave is max(landers_to_spawn, 5) landers, until landers_to_spawn == 0.
+enemy_count := $009C ; total number of live enemies on level, not counting baiters.
+baiter_count := $009D ; count of baiters on level. also used for some other purpose XXX what?
+lives := $009E ; player 1 only?
+planet_dead_flag:= $00A0 ; bit 7 set = planet has exploded (no humans, all mutants)
+humanoid_count := $00A1 ; initialized to $10, counts down to 0 as they die (but changing this in mid-level changes nothing, it changes right back!)
+trigger := $00A3 ; shadow of TRIG0 or 1 depending on which player is playing
+smartbombs := $00A5
+trampoline := $00A7 ; indirect jmp vector
+scanner_colormask:= $00A9
+ship_anim_counter:= $00AA ; player's ship has its own animation counter
+draw_ok_flag := $00AB ; bit 7 set = ok to write to screen ram (set by bottom_dli_handler, cleared by top_dli_handler)
+spacebar_flag := $00AC ; bit 7 set = player pressed spacebar
+hyperspace_flag := $00AE ; bit 7 set = player pressed hyperspace key
+pause_flag := $00AF ; 00 = playing, $80 = paused while playing, $ff = not playing (title screen or game over)
+select_flag := $00B0 ; bit 7 set = select was pressed
+sound_offset := $00B1 ; offset into sound_ptr list
+sound_ptr := $00B2 ; points to a list of AUDF, AUDC values
+cur_sound_tempo := $00B4 ; speed of currently-playing event sound
+sound_tempo := $00B5 ; play_event_sound uses this to set cur_sound_tempo
+cur_sound_timer := $00B6 ; incremented each call to update_sound. when it reaches cur_sound_tempo, we increment sound_offset
+sound_priority := $00B7 ; priority of currently-playing event sound
+tmp_hoffset_r := $00B8
+enemy_firing_freq:= $00BB ; starts at $3f, $1f, $0f for easy/med/hard. shifts right at start of every other level, until it reaches $03 (and stays there forever)
+drone_volume := $00BD ; initialized to $1f by init_drone, decrements to 0 during sound fade-out
+start_flag := $00BE ; bit 7 set = start was pressed
+screen_ptr := $00C0 ; pointer to screen memory, used by print_letter, draw_glyph, draw_sprite_(left|right), etc
+current_player_shot:= $00C2 ; update_player_shots only updates one shot per call. this keeps track of which one, counts 0 4 8 $C.
+ship_x_pos := $00C3 ; ship's visible X position on screen (not in the scanner). ranges $20 to $76
+ship_y_pos := $00C4 ; lower = higher on the screen, $20 = top, $b4 = bottom
+ship_direction := $00C5 ; which way the ship is facing. 1 = right, $FF (-1) = left.
+random_seed := $00C6 ; initialized to $f3 $12 $53 by init_cart
+ship_delta := $00D5 ; ship's movement, negative = left, 0 = stationary, positive = right. range -6 ($fa) to 6.
+sprite_y := $00DF ; Y position of sprite, for draw_sprite_(left|right)
+last_kbcode := $00E0 ; KBCODE gets saved here by check_key_code
+game_type := $00E1 ; 1-3 = 1p easy/med/hard, 4-6 = 2p e/m/h, 0 = demo
+players := $00E2 ; 1 or 2 (1 in demo mode also)
+sprite_x := $00E3 ; X position of sprite, for draw_sprite_(left|right)
+tmp_ptr := $00E7 ; used to point into screen memory by draw_glyph, also used for clearing sprite memory and blowing up the planet
+invuln_flag := $00ED ; bit 7 set = ship collisions ignored... but also you can't clear a level. always set in demo game. temporarily set when the player's ship is exploding (to avoid further collisions killing it again while it's busy dying)
+glyph_color_mask:= $00EE ; used by draw_glyph, $FF = color 3, all pixels 11 (like they're stored in the ROM), $55 and $AA for printing in colors 1 and 2.
+ship_dead_flag := $00EF ; bit 7 set = collision with something that kills us (set by ship_collision)
+key_debounce_ctr:= $00F0 ; keypresses are ignored until this counts to $10
+current_player := $00F1 ; 1 or 2 in 2-player games, always 1 in 1-player and demo
+level_jiffies_hi:= $00F6 ; init to 0 at start of level, increments every 256 frames while game is playing
+protection_flag := $00F8 ; bit 7 set = protection check failed, game will show title screen but refuse to start
+current_sprite := $00F9 ; 0 = human. (lower 3 bits are word index into score_points_table)
+VDSLST := $0200 ; DLI vector
+VKEYBD := $0208 ; === page 2 OS equates
+VKEYBD_hi := $0209
+SDMCTL := $022F
+SDLSTL := $0230 ; dlist start, lo byte
+SDLSTH := $0231 ; dlist start, hi byte
+COLDST := $0244
+GPRIOR := $026F
+PCOLR0 := $02C0
+PCOLR1 := $02C1
+PCOLR2 := $02C2
+PCOLR3 := $02C3
+COLOR0 := $02C4
+COLOR1 := $02C5
+COLOR2 := $02C6
+COLOR3 := $02C7
+COLOR4 := $02C8
+CHBAS := $02F4
+splosion_particles:= $0400 ; page full of random garbage, generated by init_splosion, used/altered by animate_plosion
+plosion_x := $0505
+plosion_y := $0506
+plosion_x_start := $0507
+plosion_y_start := $0508
+cursor_line := $0512 ; cursor_x times 9, scanline where next char prints (range XXX)
+cur_line := $0513 ; current line of glyph being drawn, used by print_letter and draw_glyph
+last_line := $0514 ; last line of glyph being drawn, used by print_letter and draw_glyph
+cursor_x_tmp := $0515
+glyph_offset := $0516 ; offset of glyph from start of font (0, 8, 16, 24, ...), used by draw_glyph
+y_stash := $0519 ; temp, used by print_letter and draw_glyph
+player_shots_y := $051A ; table of active shots, 4 entries, 4 bytes per entry: y pos, x start, x end, delta
+player_shots_x_start:= $051B
+player_shots_x_end:= $051C
+player_shots_delta:= $051D
+enemy_explosion_table:= $052B ; 4 bytes per entry, 32 entries
+sprite_list := $0AEB ; enemies, humanoids, everything alive & movable. 4 bytes per entry (XXX don't know what they mean yet)
+pss_temp := $0C4B ; 16 bytes, used by preshift_sprite
+actor_list := $0C6B ; 6 bytes/entry, 32 entries max, sprites in sprite_list also an entry here XXX
+exhaust_flag := $0D2B ; bit 7 set = draw rocket exhaust
+vert_horiz_flag := $0D2C ; check_ship_move uses this, bit 0 clear = check for horizontal movement, set = vertical
+inertia_counter := $0D2D ; XXX
+horiz_acceleration:= $0D2E ; XXX
+sp_humanoid := $0D2F ; ram copies of sprites. sp_x is the original sprite. sp_x+$10, sp_x+$20, sp_x+$30 are right-shifted copies, by 1/2/3 pixels respectively
+sp_lander_1 := $0D6F
+sp_lander_2 := $0DAF
+sp_mutant_1 := $0DEF
+sp_mutant_2 := $0E2F
+sp_rship_l_1 := $0E6F
+sp_rship_r_1 := $0EAF
+sp_rship_l_2 := $0EEF
+sp_rship_r_2 := $0F2F
+sp_lship_l_1 := $0F6F
+sp_lship_r_1 := $0FAF
+sp_lship_l_2 := $0FEF
+sp_lship_r_2 := $102F
+sp_bullet := $106F
+sp_bomber_1 := $10AF
+sp_bomber_2 := $10EF
+sp_xbomb := $112F
+sp_lflame_1 := $116F
+sp_lflame_2 := $11AF
+sp_rflame_1 := $11EF
+sp_rflame_2 := $122F
+sp_pod_1 := $126F
+sp_pod_2 := $12AF
+sp_swarmer := $12EF
+sp_baiter_l := $132F
+sp_baiter_r := $136F
+sp_smartbomb_1 := $13AF
+sp_smartbomb_2 := $13EF
+score := $142F ; lsb first, binary base 100 (each byte ranges $00 to $63 (99 dec)
+cursor_x := $1439 ; column where printchar will print next character (range 0-$27 I think)
+cursor_y := $143A ; row where printchar will print next character (range XXX)
+p1_sav_sprite_list:= $1600
+p1_sav_score := $17C0
+p1_sav_fire_freq:= $17C5
+p1_sav_lives := $17C6
+p1_sav_bombs := $17C7
+p1_sav_lander_wave_count:= $17C8
+p1_sav_level := $17C9
+p2_sav_sprite_list:= $1800
+p2_sav_score := $19C0
+p2_sav_planet_dead:= $19C4
+p2_sav_fire_freq:= $19C5
+p2_sav_lives := $19C6
+p2_sav_bombs := $19C7
+p2_sav_lander_wave_count:= $19C8
+p2_sav_level := $19C9
+offset_index_table:= $1A00 ; filled with repeating pattern 00 01 02 03 00 01 02 03... basically a modulus 4 lookup
+horiz_offset_table:= $1B00 ; coarse (byte) offset for each horizontal position, the 0th thru 39th byte on a scanline
+pixel_mask_table:= $1C00 ; filled with repeating pattern c0 30 0c 03 c0 30 0c 03 ...
+screen_lo_ptrs := $1D00 ; pointers to the start of each scanline in screen memory (lo bytes)
+screen_hi_ptrs := $1E00 ; pointers to the start of each scanline in screen memory (hi bytes)
+draw_sprite_left_copy:= $1F00 ; self-modifying RAM copy of draw_sprite_left
+draw_sprite_right_copy:= $1F80 ; self-modifying RAM copy of draw_sprite_right
+dlist_ram := $2000 ; 190 scanlines of GR.15 with 2 DLIs
+screen_ram := $2218 ; 190 scanlines * 40 bytes/line = 7600 ($1db0) bytes
+p1_sav_planet_dead:= $79C4
+HPOSP3 := $D003 ; === GTIA equates
+HPOSM0 := $D004
+HPOSM1 := $D005
+HPOSM2 := $D006
+HPOSM3 := $D007
+SIZEP2 := $D00A
+SIZEP3 := $D00B
+SIZEM := $D00C
+TRIG0 := $D010
+TRIG1 := $D011
+COLPM0 := $D012
+COLPM1 := $D013
+COLPF0 := $D016
+COLPF1 := $D017
+COLPF2 := $D018
+COLPF3 := $D019
+COLBK := $D01A
+PRIOR := $D01B
+GRACTL := $D01D
+HITCLR := $D01E
+CONSOL := $D01F
+AUDF1 := $D200 ; === POKEY equates
+AUDC1 := $D201
+AUDF2 := $D202
+AUDC2 := $D203
+AUDF3 := $D204
+AUDC3 := $D205
+AUDF4 := $D206
+AUDC4 := $D207
+AUDCTL := $D208
+KBCODE := $D209
+RANDOM := $D20A
+IRQEN := $D20E
+SKCTL := $D20F
+PORTA := $D300 ; === PIA equates
+PORTB := $D301
+PACTL := $D302
+PBCTL := $D303
+DMACTL := $D400 ; === ANTIC equates
+DLISTL := $D402
+DLISTH := $D403
+HSCROL := $D404
+PMBASE := $D407
+CHBASE := $D409
+WSYNC := $D40A
+VCOUNT := $D40B
+NMIEN := $D40E
+; ----------------------------------------------------------------------------
+; cart_a_start points here. copy-protection setup prevents the game from starting if it's been >= 256 jiffies (~4 sec) since cold or warm start
+init_cart:
+ pla ; 8000 68 h
+ pla ; 8001 68 h
+ lsr protection_flag ; 8002 46 F8 F.
+ lda RTCLOK+1 ; 8004 A5 13 ..
+ beq rtclok_ok ; 8006 F0 03 ..
+ sec ; 8008 38 8
+ ror protection_flag ; 8009 66 F8 f.
+rtclok_ok:
+ jsr init_hardware ; 800B 20 89 B8 ..
+ jsr init_work_ram ; 800E 20 68 A2 h.
+ lda #$FF ; 8011 A9 FF ..
+ sta COLDST ; 8013 8D 44 02 .D.
+ lda #$F3 ; 8016 A9 F3 ..
+ sta random_seed ; 8018 85 C6 ..
+ lda #$12 ; 801A A9 12 ..
+ sta random_seed+1 ; 801C 85 C7 ..
+ lda #$53 ; 801E A9 53 .S
+ sta random_seed+2 ; 8020 85 C8 ..
+ jsr L9D18 ; 8022 20 18 9D ..
+ sec ; 8025 38 8
+ ror planet_dead_flag ; 8026 66 A0 f.
+ jsr clear_scanner_draw_planet_and_humans; 8028 20 5E 9E ^.
+ lsr planet_dead_flag ; 802B 46 A0 F.
+ lda #$01 ; 802D A9 01 ..
+ sta game_type ; 802F 85 E1 ..
+init_title_screen:
+ lda #$08 ; 8031 A9 08 ..
+ sta CONSOL ; 8033 8D 1F D0 ...
+ lsr $F2 ; 8036 46 F2 F.
+ lda #$01 ; 8038 A9 01 ..
+ sta current_player ; 803A 85 F1 ..
+ lda #$00 ; 803C A9 00 ..
+ sta level ; 803E 85 9A ..
+ sta ATRACT ; 8040 85 4D .M
+ lda #$7E ; 8042 A9 7E .~
+ sta COLOR2 ; 8044 8D C6 02 ...
+ lda #$00 ; 8047 A9 00 ..
+ sta $E9 ; 8049 85 E9 ..
+ sta $EA ; 804B 85 EA ..
+ sta planet_dead_flag ; 804D 85 A0 ..
+ sta ship_delta ; 804F 85 D5 ..
+ lda #$04 ; 8051 A9 04 ..
+ sta lives ; 8053 85 9E ..
+ sta smartbombs ; 8055 85 A5 ..
+ sta p1_sav_lives ; 8057 8D C6 17 ...
+ sta p1_sav_bombs ; 805A 8D C7 17 ...
+ sta p2_sav_lives ; 805D 8D C6 19 ...
+ sta p2_sav_bombs ; 8060 8D C7 19 ...
+ lda #$FF ; 8063 A9 FF ..
+ sta pause_flag ; 8065 85 AF ..
+ lda #$00 ; 8067 A9 00 ..
+ sta select_flag ; 8069 85 B0 ..
+ sta hyperspace_flag ; 806B 85 AE ..
+ sta start_flag ; 806D 85 BE ..
+ sta invuln_flag ; 806F 85 ED ..
+ sta ship_dead_flag ; 8071 85 EF ..
+ lda game_type ; 8073 A5 E1 ..
+ jmp set_game_type ; 8075 4C E6 80 L..
+
+; ----------------------------------------------------------------------------
+; play & fade the drone while we wait for the user to press select or start
+title_screen_idle:
+ jsr init_drone ; 8078 20 79 8D y.
+ lda #$FF ; 807B A9 FF ..
+ sta drone_volume ; 807D 85 BD ..
+ jsr clear_screen ; 807F 20 A1 B8 ..
+ jsr draw_scanner_border_and_planet ; 8082 20 B1 9F ..
+ lda game_type ; 8085 A5 E1 ..
+ beq L808F ; 8087 F0 06 ..
+ jsr draw_p1_lives_and_bombs ; 8089 20 B0 86 ..
+ jsr draw_p2_lives_and_bombs ; 808C 20 80 87 ..
+L808F: jsr draw_title_text ; 808F 20 59 82 Y.
+L8092: jsr show_game_type ; 8092 20 1F 81 ..
+L8095: lda draw_ok_flag ; 8095 A5 AB ..
+ bpl L8095 ; 8097 10 FC ..
+ clc ; 8099 18 .
+; rotate colors
+update_title_colors:
+ lda COLOR0 ; 809A AD C4 02 ...
+ adc #$10 ; 809D 69 10 i.
+ sta COLOR0 ; 809F 8D C4 02 ...
+ lda drone_volume ; 80A2 A5 BD ..
+ beq title_fx_ok ; 80A4 F0 11 ..
+; alter the drone sound's pitch
+update_title_sfx:
+ sec ; 80A6 38 8
+ sbc #$01 ; 80A7 E9 01 ..
+ sta drone_volume ; 80A9 85 BD ..
+ lsr a ; 80AB 4A J
+ lsr a ; 80AC 4A J
+ lsr a ; 80AD 4A J
+ lsr a ; 80AE 4A J
+ ora #$A0 ; 80AF 09 A0 ..
+ sta AUDC3 ; 80B1 8D 05 D2 ...
+ sta AUDC4 ; 80B4 8D 07 D2 ...
+title_fx_ok:
+ lda #$FF ; 80B7 A9 FF ..
+ sta pause_flag ; 80B9 85 AF ..
+ jsr check_consol ; 80BB 20 A0 BA ..
+ lda start_flag ; 80BE A5 BE ..
+ bmi start_game ; 80C0 30 3E 0>
+ lda select_flag ; 80C2 A5 B0 ..
+ bpl L8092 ; 80C4 10 CC ..
+ lda #$03 ; 80C6 A9 03 ..
+L80C8: pha ; 80C8 48 H
+ lda #$FF ; 80C9 A9 FF ..
+ jsr delay_loop ; 80CB 20 74 88 t.
+ pla ; 80CE 68 h
+ sec ; 80CF 38 8
+ sbc #$01 ; 80D0 E9 01 ..
+ bne L80C8 ; 80D2 D0 F4 ..
+ lda #$00 ; 80D4 A9 00 ..
+ sta select_flag ; 80D6 85 B0 ..
+ sta ATRACT ; 80D8 85 4D .M
+ inc game_type ; 80DA E6 E1 ..
+ lda game_type ; 80DC A5 E1 ..
+ cmp #$07 ; 80DE C9 07 ..
+ bcc set_game_type ; 80E0 90 04 ..
+ lda #$00 ; 80E2 A9 00 ..
+ sta game_type ; 80E4 85 E1 ..
+set_game_type:
+ tay ; 80E6 A8 .
+ lda game_type_table,y ; 80E7 B9 F9 80 ...
+ sta enemy_firing_freq ; 80EA 85 BB ..
+ lda #$01 ; 80EC A9 01 ..
+ sta players ; 80EE 85 E2 ..
+ cpy #$04 ; 80F0 C0 04 ..
+ bcc title_screen_idle ; 80F2 90 84 ..
+ inc players ; 80F4 E6 E2 ..
+ jmp title_screen_idle ; 80F6 4C 78 80 Lx.
+
+; ----------------------------------------------------------------------------
+; game select table (7 entries: demo, 1p easy/med/hard, 2p easy/med/hard)
+game_type_table:
+ .byte $3F,$3F,$1F,$0F,$3F,$1F,$0F ; 80F9 3F 3F 1F 0F 3F 1F 0F ??..?..
+; ----------------------------------------------------------------------------
+; ...
+start_game:
+ lda #$CA ; 8100 A9 CA ..
+ sta COLOR0 ; 8102 8D C4 02 ...
+ lda #$00 ; 8105 A9 00 ..
+ sta pause_flag ; 8107 85 AF ..
+ sta select_flag ; 8109 85 B0 ..
+ sta start_flag ; 810B 85 BE ..
+ sta hyperspace_flag ; 810D 85 AE ..
+ sta spacebar_flag ; 810F 85 AC ..
+ sta key_debounce_ctr ; 8111 85 F0 ..
+ sta last_kbcode ; 8113 85 E0 ..
+ bit protection_flag ; 8115 24 F8 $.
+ bpl protection_ok ; 8117 10 03 ..
+ jmp init_title_screen ; 8119 4C 31 80 L1.
+
+; ----------------------------------------------------------------------------
+protection_ok:
+ jmp game_on ; 811C 4C 69 83 Li.
+
+; ----------------------------------------------------------------------------
+; draw the text for e.g. ONE PLAYER EASY
+show_game_type:
+ lda #$55 ; 811F A9 55 .U
+ sta glyph_color_mask ; 8121 85 EE ..
+ lda game_type ; 8123 A5 E1 ..
+ asl a ; 8125 0A .
+ tay ; 8126 A8 .
+ lda game_type_text_ptrs,y ; 8127 B9 48 81 .H.
+ sta tmp_ptr ; 812A 85 E7 ..
+ lda game_type_text_ptrs+1,y ; 812C B9 49 81 .I.
+ sta tmp_ptr+1 ; 812F 85 E8 ..
+ lda #$09 ; 8131 A9 09 ..
+ sta cursor_y ; 8133 8D 3A 14 .:.
+ lda #$00 ; 8136 A9 00 ..
+ sta cursor_x ; 8138 8D 39 14 .9.
+ ldy #$00 ; 813B A0 00 ..
+L813D: lda (tmp_ptr),y ; 813D B1 E7 ..
+ beq L8147 ; 813F F0 06 ..
+ jsr printchar ; 8141 20 2E 97 ..
+ iny ; 8144 C8 .
+ bne L813D ; 8145 D0 F6 ..
+L8147: rts ; 8147 60 `
+
+; ----------------------------------------------------------------------------
+; the strings these point to are 37 characters long, null-terminated, ASCII with high bit set (this game was ported from the Apple II, where ASCII normally has the high bit set)
+game_type_text_ptrs:
+ .addr gttxt_demo ; 8148 56 81 V.
+ .addr gttxt_1p_easy ; 814A 7B 81 {.
+ .addr gttxt_1p_normal ; 814C A0 81 ..
+ .addr gttxt_1p_hard ; 814E C5 81 ..
+ .addr gttxt_2p_easy ; 8150 EA 81 ..
+ .addr gttxt_2p_normal ; 8152 0F 82 ..
+ .addr gttxt_2p_hard ; 8154 34 82 4.
+; ----------------------------------------------------------------------------
+; ' D E F E N D E R G A M E D E M O'
+gttxt_demo:
+ .byte $A0,$A0,$A0,$C4,$A0,$C5,$A0,$C6 ; 8156 A0 A0 A0 C4 A0 C5 A0 C6 ........
+ .byte $A0,$C5,$A0,$CE,$A0,$C4,$A0,$C5 ; 815E A0 C5 A0 CE A0 C4 A0 C5 ........
+ .byte $A0,$D2,$A0,$A0,$C7,$A0,$C1,$A0 ; 8166 A0 D2 A0 A0 C7 A0 C1 A0 ........
+ .byte $CD,$A0,$C5,$A0,$A0,$C4,$A0,$C5 ; 816E CD A0 C5 A0 A0 C4 A0 C5 ........
+ .byte $A0,$CD,$A0,$CF,$00 ; 8176 A0 CD A0 CF 00 .....
+; ' O N E P L A Y E R E A S Y '
+gttxt_1p_easy:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$CF,$A0 ; 817B A0 A0 A0 A0 A0 A0 CF A0 ........
+ .byte $CE,$A0,$C5,$A0,$A0,$D0,$A0,$CC ; 8183 CE A0 C5 A0 A0 D0 A0 CC ........
+ .byte $A0,$C1,$A0,$D9,$A0,$C5,$A0,$D2 ; 818B A0 C1 A0 D9 A0 C5 A0 D2 ........
+ .byte $A0,$A0,$C5,$A0,$C1,$A0,$D3,$A0 ; 8193 A0 A0 C5 A0 C1 A0 D3 A0 ........
+ .byte $D9,$A0,$A0,$A0,$00 ; 819B D9 A0 A0 A0 00 .....
+; ' O N E P L A Y E R N O R M A L '
+gttxt_1p_normal:
+ .byte $A0,$A0,$A0,$A0,$CF,$A0,$CE,$A0 ; 81A0 A0 A0 A0 A0 CF A0 CE A0 ........
+ .byte $C5,$A0,$A0,$D0,$A0,$CC,$A0,$C1 ; 81A8 C5 A0 A0 D0 A0 CC A0 C1 ........
+ .byte $A0,$D9,$A0,$C5,$A0,$D2,$A0,$A0 ; 81B0 A0 D9 A0 C5 A0 D2 A0 A0 ........
+ .byte $CE,$A0,$CF,$A0,$D2,$A0,$CD,$A0 ; 81B8 CE A0 CF A0 D2 A0 CD A0 ........
+ .byte $C1,$A0,$CC,$A0,$00 ; 81C0 C1 A0 CC A0 00 .....
+; ' O N E P L A Y E R H A R D '
+gttxt_1p_hard:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$CF,$A0 ; 81C5 A0 A0 A0 A0 A0 A0 CF A0 ........
+ .byte $CE,$A0,$C5,$A0,$A0,$D0,$A0,$CC ; 81CD CE A0 C5 A0 A0 D0 A0 CC ........
+ .byte $A0,$C1,$A0,$D9,$A0,$C5,$A0,$D2 ; 81D5 A0 C1 A0 D9 A0 C5 A0 D2 ........
+ .byte $A0,$A0,$C8,$A0,$C1,$A0,$D2,$A0 ; 81DD A0 A0 C8 A0 C1 A0 D2 A0 ........
+ .byte $C4,$A0,$A0,$A0,$00 ; 81E5 C4 A0 A0 A0 00 .....
+; ' T W O P L A Y E R E A S Y '
+gttxt_2p_easy:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$D4,$A0 ; 81EA A0 A0 A0 A0 A0 A0 D4 A0 ........
+ .byte $D7,$A0,$CF,$A0,$A0,$D0,$A0,$CC ; 81F2 D7 A0 CF A0 A0 D0 A0 CC ........
+ .byte $A0,$C1,$A0,$D9,$A0,$C5,$A0,$D2 ; 81FA A0 C1 A0 D9 A0 C5 A0 D2 ........
+ .byte $A0,$A0,$C5,$A0,$C1,$A0,$D3,$A0 ; 8202 A0 A0 C5 A0 C1 A0 D3 A0 ........
+ .byte $D9,$A0,$A0,$A0,$00 ; 820A D9 A0 A0 A0 00 .....
+; ' T W O P L A Y E R N O R M A L '
+gttxt_2p_normal:
+ .byte $A0,$A0,$A0,$A0,$D4,$A0,$D7,$A0 ; 820F A0 A0 A0 A0 D4 A0 D7 A0 ........
+ .byte $CF,$A0,$A0,$D0,$A0,$CC,$A0,$C1 ; 8217 CF A0 A0 D0 A0 CC A0 C1 ........
+ .byte $A0,$D9,$A0,$C5,$A0,$D2,$A0,$A0 ; 821F A0 D9 A0 C5 A0 D2 A0 A0 ........
+ .byte $CE,$A0,$CF,$A0,$D2,$A0,$CD,$A0 ; 8227 CE A0 CF A0 D2 A0 CD A0 ........
+ .byte $C1,$A0,$CC,$A0,$00 ; 822F C1 A0 CC A0 00 .....
+; ' T W O P L A Y E R H A R D '
+gttxt_2p_hard:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$D4,$A0 ; 8234 A0 A0 A0 A0 A0 A0 D4 A0 ........
+ .byte $D7,$A0,$CF,$A0,$A0,$D0,$A0,$CC ; 823C D7 A0 CF A0 A0 D0 A0 CC ........
+ .byte $A0,$C1,$A0,$D9,$A0,$C5,$A0,$D2 ; 8244 A0 C1 A0 D9 A0 C5 A0 D2 ........
+ .byte $A0,$A0,$C8,$A0,$C1,$A0,$D2,$A0 ; 824C A0 A0 C8 A0 C1 A0 D2 A0 ........
+ .byte $C4,$A0,$A0,$A0,$00 ; 8254 C4 A0 A0 A0 00 .....
+; ----------------------------------------------------------------------------
+; draw the text for DEFENDER/SELECT GAME AND PRESS THE START BUTTON
+draw_title_text:
+ lda #$06 ; 8259 A9 06 ..
+ sta cursor_y ; 825B 8D 3A 14 .:.
+ lda #$00 ; 825E A9 00 ..
+ sta cursor_x ; 8260 8D 39 14 .9.
+ lda #$FF ; 8263 A9 FF ..
+ sta glyph_color_mask ; 8265 85 EE ..
+; lda #<title_text
+dtt_lo: lda #$95 ; 8267 A9 95 ..
+ sta tmp_ptr ; 8269 85 E7 ..
+; lda #>title_text
+dtt_hi: lda #$82 ; 826B A9 82 ..
+ sta tmp_ptr+1 ; 826D 85 E8 ..
+ ldy #$00 ; 826F A0 00 ..
+dtt_loop:
+ lda (tmp_ptr),y ; 8271 B1 E7 ..
+ beq dtt_done ; 8273 F0 1F ..
+ cmp #$F0 ; 8275 C9 F0 ..
+ bcc dtt_print ; 8277 90 0F ..
+; multicolor support. bytes with $Fn in the message set the color mask to nn.
+dtt_color:
+ and #$0F ; 8279 29 0F ).
+ sta sprite_x ; 827B 85 E3 ..
+ asl a ; 827D 0A .
+ asl a ; 827E 0A .
+ asl a ; 827F 0A .
+ asl a ; 8280 0A .
+ ora sprite_x ; 8281 05 E3 ..
+ sta glyph_color_mask ; 8283 85 EE ..
+ jmp dtt_inc_ptr ; 8285 4C 8B 82 L..
+
+; ----------------------------------------------------------------------------
+dtt_print:
+ jsr printchar ; 8288 20 2E 97 ..
+dtt_inc_ptr:
+ inc tmp_ptr ; 828B E6 E7 ..
+ bne dtt_loop ; 828D D0 E2 ..
+ inc tmp_ptr+1 ; 828F E6 E8 ..
+ jmp dtt_loop ; 8291 4C 71 82 Lq.
+
+; ----------------------------------------------------------------------------
+dtt_done:
+ rts ; 8294 60 `
+
+; ----------------------------------------------------------------------------
+; cF, c5 are color codes. 'cF D E F E N D E RnlnlnlnlnlnlcF S E L E C T G A M E A N D P R E S Snlnl T H E S T A R T B U T T O Nnlnlnlnlc5 c) 1 9 8 2 A T A R I'
+title_text:
+ .byte $FF,$A0,$A0,$A0,$A0,$A0,$A0,$A0 ; 8295 FF A0 A0 A0 A0 A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$C4,$A0 ; 829D A0 A0 A0 A0 A0 A0 C4 A0 ........
+ .byte $C5,$A0,$C6,$A0,$C5,$A0,$CE,$A0 ; 82A5 C5 A0 C6 A0 C5 A0 CE A0 ........
+ .byte $C4,$A0,$C5,$A0,$D2,$8D,$8D,$8D ; 82AD C4 A0 C5 A0 D2 8D 8D 8D ........
+ .byte $8D,$8D,$8D,$FF,$A0,$D3,$A0,$C5 ; 82B5 8D 8D 8D FF A0 D3 A0 C5 ........
+ .byte $A0,$CC,$A0,$C5,$A0,$C3,$A0,$D4 ; 82BD A0 CC A0 C5 A0 C3 A0 D4 ........
+ .byte $A0,$A0,$C7,$A0,$C1,$A0,$CD,$A0 ; 82C5 A0 A0 C7 A0 C1 A0 CD A0 ........
+ .byte $C5,$A0,$A0,$C1,$A0,$CE,$A0,$C4 ; 82CD C5 A0 A0 C1 A0 CE A0 C4 ........
+ .byte $A0,$A0,$D0,$A0,$D2,$A0,$C5,$A0 ; 82D5 A0 A0 D0 A0 D2 A0 C5 A0 ........
+ .byte $D3,$A0,$D3,$8D,$8D,$A0,$A0,$A0 ; 82DD D3 A0 D3 8D 8D A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$D4,$A0,$C8,$A0,$C5 ; 82E5 A0 A0 A0 D4 A0 C8 A0 C5 ........
+ .byte $A0,$A0,$D3,$A0,$D4,$A0,$C1,$A0 ; 82ED A0 A0 D3 A0 D4 A0 C1 A0 ........
+ .byte $D2,$A0,$D4,$A0,$A0,$C2,$A0,$D5 ; 82F5 D2 A0 D4 A0 A0 C2 A0 D5 ........
+ .byte $A0,$D4,$A0,$D4,$A0,$CF,$A0,$CE ; 82FD A0 D4 A0 D4 A0 CF A0 CE ........
+ .byte $8D,$8D,$8D,$8D,$F5,$A0,$A0,$A0 ; 8305 8D 8D 8D 8D F5 A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$C0,$A0 ; 830D A0 A0 A0 A0 A0 A0 C0 A0 ........
+ .byte $A0,$B1,$A0,$B9,$A0,$B8,$A0,$B2 ; 8315 A0 B1 A0 B9 A0 B8 A0 B2 ........
+ .byte $A0,$A0,$C1,$A0,$D4,$A0,$C1,$A0 ; 831D A0 A0 C1 A0 D4 A0 C1 A0 ........
+ .byte $D2,$A0,$C9,$00 ; 8325 D2 A0 C9 00 ....
+; is this used at all?
+table_8329:
+ .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; 8329 FF FF FF FF FF FF FF FF ........
+ .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; 8331 FF FF FF FF FF FF FF FF ........
+ .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; 8339 FF FF FF FF FF FF FF FF ........
+ .byte $04,$FF,$03,$06,$FF,$05,$02,$01 ; 8341 04 FF 03 06 FF 05 02 01 ........
+ .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; 8349 FF FF FF FF FF FF FF FF ........
+ .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; 8351 FF FF FF FF FF FF FF FF ........
+ .byte $FF,$FF,$00,$FF,$FF,$FF,$FF,$FF ; 8359 FF FF 00 FF FF FF FF FF ........
+ .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; 8361 FF FF FF FF FF FF FF FF ........
+; ----------------------------------------------------------------------------
+; called when start button is pressed from title screen or pause mode
+game_on:jsr init_drone ; 8369 20 79 8D y.
+ lda #$FF ; 836C A9 FF ..
+ sta scanner_colormask ; 836E 85 A9 ..
+ lda #$00 ; 8370 A9 00 ..
+ sta score ; 8372 8D 2F 14 ./.
+ sta score+1 ; 8375 8D 30 14 .0.
+ sta score+2 ; 8378 8D 31 14 .1.
+ sta score+3 ; 837B 8D 32 14 .2.
+ lda #$03 ; 837E A9 03 ..
+ sta lives ; 8380 85 9E ..
+ sta smartbombs ; 8382 85 A5 ..
+ lda #$07 ; 8384 A9 07 ..
+ sta horiz_acceleration ; 8386 8D 2E 0D ...
+ lda #$00 ; 8389 A9 00 ..
+ sta inertia_counter ; 838B 8D 2D 0D .-.
+ sta exhaust_flag ; 838E 8D 2B 0D .+.
+ ldy game_type ; 8391 A4 E1 ..
+ lda game_type_table,y ; 8393 B9 F9 80 ...
+ sta enemy_firing_freq ; 8396 85 BB ..
+ jsr LA817 ; 8398 20 17 A8 ..
+ lda $D7 ; 839B A5 D7 ..
+ sta $FE ; 839D 85 FE ..
+ lda $D8 ; 839F A5 D8 ..
+ sta $FF ; 83A1 85 FF ..
+ jsr init_work_ram ; 83A3 20 68 A2 h.
+ jsr LAE17 ; 83A6 20 17 AE ..
+ lda #$00 ; 83A9 A9 00 ..
+ sta planet_dead_flag ; 83AB 85 A0 ..
+ lda #$00 ; 83AD A9 00 ..
+ sta level ; 83AF 85 9A ..
+ sta last_kbcode ; 83B1 85 E0 ..
+ jsr level_initial_spawn ; 83B3 20 55 AE U.
+ jsr save_p1_state ; 83B6 20 B9 89 ..
+ jsr save_p2_state ; 83B9 20 0D 8A ..
+ lda #$01 ; 83BC A9 01 ..
+ sta current_player ; 83BE 85 F1 ..
+ lda #$FF ; 83C0 A9 FF ..
+ sta $F4 ; 83C2 85 F4 ..
+ lsr $F7 ; 83C4 46 F7 F.
+ jmp L845B ; 83C6 4C 5B 84 L[.
+
+; ----------------------------------------------------------------------------
+; notice the check against $64? that's why we get stuck on level 99 over & over again
+next_level:
+ inc level ; 83C9 E6 9A ..
+; this branch should never be taken (means level was $FF, but it's clamped to $63 below)
+nl_wtf: beq level_cleared ; 83CB F0 5A .Z
+ lda level ; 83CD A5 9A ..
+ cmp #$64 ; 83CF C9 64 .d
+ bcc level_ok ; 83D1 90 04 ..
+ lda #$63 ; 83D3 A9 63 .c
+ sta level ; 83D5 85 9A ..
+; ramp up the speed on odd-numbered levels
+level_ok:
+ lda level ; 83D7 A5 9A ..
+ and #$01 ; 83D9 29 01 ).
+ bne nl_drone ; 83DB D0 0D ..
+ lda enemy_firing_freq ; 83DD A5 BB ..
+ lsr a ; 83DF 4A J
+ sta enemy_firing_freq ; 83E0 85 BB ..
+ cmp #$03 ; 83E2 C9 03 ..
+ bcs nl_drone ; 83E4 B0 04 ..
+ lda #$03 ; 83E6 A9 03 ..
+ sta enemy_firing_freq ; 83E8 85 BB ..
+nl_drone:
+ jsr init_drone ; 83EA 20 79 8D y.
+ jsr clear_screen ; 83ED 20 A1 B8 ..
+ jsr clear_scanner_draw_planet_and_humans; 83F0 20 5E 9E ^.
+ jsr draw_scanner_border_and_planet ; 83F3 20 B1 9F ..
+ lda #$10 ; 83F6 A9 10 ..
+L83F8: pha ; 83F8 48 H
+ jsr draw_starfield ; 83F9 20 32 A8 2.
+ pla ; 83FC 68 h
+ sec ; 83FD 38 8
+ sbc #$01 ; 83FE E9 01 ..
+ bne L83F8 ; 8400 D0 F6 ..
+ jsr print_end_level_msg ; 8402 20 42 96 B.
+ jsr draw_scores ; 8405 20 42 94 B.
+ inc lives ; 8408 E6 9E ..
+ jsr draw_p1_lives_and_bombs ; 840A 20 B0 86 ..
+ dec lives ; 840D C6 9E ..
+ jsr draw_p2_lives_and_bombs ; 840F 20 80 87 ..
+ lda #$1E ; 8412 A9 1E ..
+L8414: pha ; 8414 48 H
+ lda #$FF ; 8415 A9 FF ..
+ jsr delay_loop ; 8417 20 74 88 t.
+ pla ; 841A 68 h
+ sec ; 841B 38 8
+ sbc #$01 ; 841C E9 01 ..
+ bne L8414 ; 841E D0 F4 ..
+ lda lives ; 8420 A5 9E ..
+ bne level_cleared ; 8422 D0 03 ..
+ jmp out_of_lives ; 8424 4C 0E B7 L..
+
+; ----------------------------------------------------------------------------
+; decide whether or not to resurrect dead humans
+level_cleared:
+ lda level ; 8427 A5 9A ..
+ clc ; 8429 18 .
+ adc #$01 ; 842A 69 01 i.
+div_5_loop:
+ sec ; 842C 38 8
+ sbc #$05 ; 842D E9 05 ..
+ bcs div_5_loop ; 842F B0 FB ..
+ adc #$05 ; 8431 69 05 i.
+ bne dont_repopulate ; 8433 D0 0A ..
+ jsr init_work_ram ; 8435 20 68 A2 h.
+ jsr LAE17 ; 8438 20 17 AE ..
+ lda #$00 ; 843B A9 00 ..
+ sta planet_dead_flag ; 843D 85 A0 ..
+dont_repopulate:
+ jsr level_initial_spawn ; 843F 20 55 AE U.
+ lda #$00 ; 8442 A9 00 ..
+ sta level_jiffies_lo ; 8444 85 87 ..
+ sta $95 ; 8446 85 95 ..
+ lda #$FC ; 8448 A9 FC ..
+ sta $99 ; 844A 85 99 ..
+ sta current_player_shot ; 844C 85 C2 ..
+ sta $CC ; 844E 85 CC ..
+ sta $98 ; 8450 85 98 ..
+ sta $A6 ; 8452 85 A6 ..
+ bit $F7 ; 8454 24 F7 $.
+ bpl L845B ; 8456 10 03 ..
+ jmp LB6D1 ; 8458 4C D1 B6 L..
+
+; ----------------------------------------------------------------------------
+L845B: ldy #$00 ; 845B A0 00 ..
+ lda #$00 ; 845D A9 00 ..
+L845F: sta enemy_explosion_table,y ; 845F 99 2B 05 .+.
+ iny ; 8462 C8 .
+ bpl L845F ; 8463 10 FA ..
+L8465: jsr clear_screen ; 8465 20 A1 B8 ..
+ lda #$00 ; 8468 A9 00 ..
+ sta $A4 ; 846A 85 A4 ..
+ lda TRIG0 ; 846C AD 10 D0 ...
+ ldy current_player ; 846F A4 F1 ..
+ cpy #$02 ; 8471 C0 02 ..
+ bne L8478 ; 8473 D0 03 ..
+ lda TRIG1 ; 8475 AD 11 D0 ...
+L8478: sta trigger ; 8478 85 A3 ..
+ lda #$00 ; 847A A9 00 ..
+ sta ship_delta ; 847C 85 D5 ..
+ sta select_flag ; 847E 85 B0 ..
+ sta hyperspace_flag ; 8480 85 AE ..
+ sta spacebar_flag ; 8482 85 AC ..
+ sta start_flag ; 8484 85 BE ..
+ sta pause_flag ; 8486 85 AF ..
+ sta key_debounce_ctr ; 8488 85 F0 ..
+ lda #$50 ; 848A A9 50 .P
+ sta ship_x_pos ; 848C 85 C3 ..
+ lda #$01 ; 848E A9 01 ..
+ sta ship_direction ; 8490 85 C5 ..
+ lda #$78 ; 8492 A9 78 .x
+ sta ship_y_pos ; 8494 85 C4 ..
+ ldy #$00 ; 8496 A0 00 ..
+ lda #$00 ; 8498 A9 00 ..
+L849A: sta player_shots_y,y ; 849A 99 1A 05 ...
+ iny ; 849D C8 .
+ cpy #$10 ; 849E C0 10 ..
+ bcc L849A ; 84A0 90 F8 ..
+ jsr init_drone ; 84A2 20 79 8D y.
+ lda #$7E ; 84A5 A9 7E .~
+ sta COLOR2 ; 84A7 8D C6 02 ...
+ lda #$FF ; 84AA A9 FF ..
+ sta $D4 ; 84AC 85 D4 ..
+ lda #$00 ; 84AE A9 00 ..
+ sta ship_move_delay ; 84B0 85 93 ..
+ lda #$00 ; 84B2 A9 00 ..
+ sta ship_dead_flag ; 84B4 85 EF ..
+ sta level_jiffies_hi ; 84B6 85 F6 ..
+ lda #$00 ; 84B8 A9 00 ..
+ sta inertia_counter ; 84BA 8D 2D 0D .-.
+ jsr clear_scanner_draw_planet_and_humans; 84BD 20 5E 9E ^.
+ jsr draw_scanner_border_and_planet ; 84C0 20 B1 9F ..
+ lsr $AD ; 84C3 46 AD F.
+ jsr draw_scores ; 84C5 20 42 94 B.
+ sec ; 84C8 38 8
+ ror $AD ; 84C9 66 AD f.
+ jsr draw_p1_lives_and_bombs ; 84CB 20 B0 86 ..
+ jsr draw_p2_lives_and_bombs ; 84CE 20 80 87 ..
+ lda players ; 84D1 A5 E2 ..
+ cmp #$01 ; 84D3 C9 01 ..
+ beq prompt_done ; 84D5 F0 28 .(
+ lda $F4 ; 84D7 A5 F4 ..
+ cmp current_player ; 84D9 C5 F1 ..
+ beq prompt_done ; 84DB F0 22 ."
+ lda current_player ; 84DD A5 F1 ..
+ sta $F4 ; 84DF 85 F4 ..
+ cmp #$01 ; 84E1 C9 01 ..
+ beq p1_ok ; 84E3 F0 06 ..
+ jsr print_p2_text ; 84E5 20 3E 8B >.
+ jmp prompt_screen_delay ; 84E8 4C EE 84 L..
+
+; ----------------------------------------------------------------------------
+p1_ok: jsr print_p1_text ; 84EB 20 09 8B ..
+; wait a while to let the next player get ready
+prompt_screen_delay:
+ lda #$19 ; 84EE A9 19 ..
+psd_loop:
+ pha ; 84F0 48 H
+ lda #$FF ; 84F1 A9 FF ..
+ jsr delay_loop ; 84F3 20 74 88 t.
+ pla ; 84F6 68 h
+ sec ; 84F7 38 8
+ sbc #$01 ; 84F8 E9 01 ..
+ bne psd_loop ; 84FA D0 F4 ..
+ jsr clear_prompt_text ; 84FC 20 73 8B s.
+; either the prompt screen is finished, or we were in single-player mode & didn't need it
+prompt_done:
+ lda #$00 ; 84FF A9 00 ..
+ sta ATRACT ; 8501 85 4D .M
+L8503: jsr check_consol ; 8503 20 A0 BA ..
+ bit select_flag ; 8506 24 B0 $.
+ bpl L8511 ; 8508 10 07 ..
+ bit pause_flag ; 850A 24 AF $.
+ bpl L852A ; 850C 10 1C ..
+ jmp init_title_screen ; 850E 4C 31 80 L1.
+
+; ----------------------------------------------------------------------------
+L8511: bit start_flag ; 8511 24 BE $.
+ bpl L852A ; 8513 10 15 ..
+ bit pause_flag ; 8515 24 AF $.
+ bpl L852A ; 8517 10 11 ..
+ jmp game_on ; 8519 4C 69 83 Li.
+
+; ----------------------------------------------------------------------------
+L851C: lda game_type ; 851C A5 E1 ..
+ bne L852A ; 851E D0 0A ..
+ jsr L895C ; 8520 20 5C 89 \.
+ lda last_kbcode ; 8523 A5 E0 ..
+ beq L852A ; 8525 F0 03 ..
+ jmp init_title_screen ; 8527 4C 31 80 L1.
+
+; ----------------------------------------------------------------------------
+L852A: bit pause_flag ; 852A 24 AF $.
+ bmi L8503 ; 852C 30 D5 0.
+ inc $D4 ; 852E E6 D4 ..
+ lda $D4 ; 8530 A5 D4 ..
+ and #$3F ; 8532 29 3F )?
+ bne L8558 ; 8534 D0 22 ."
+ jsr clear_scanner_draw_planet_and_humans; 8536 20 5E 9E ^.
+ jsr smartbomb_check ; 8539 20 8A 8B ..
+ jsr LAC18 ; 853C 20 18 AC ..
+L853F: bit draw_ok_flag ; 853F 24 AB $.
+ bpl L853F ; 8541 10 FC ..
+ jsr LA4CC ; 8543 20 CC A4 ..
+ inc level_jiffies_lo ; 8546 E6 87 ..
+ bne L854C ; 8548 D0 02 ..
+ inc level_jiffies_hi ; 854A E6 F6 ..
+L854C: lda level_jiffies_lo ; 854C A5 87 ..
+ and #$3F ; 854E 29 3F )?
+ bne L8558 ; 8550 D0 06 ..
+ jsr spawn_lander_wave ; 8552 20 98 AE ..
+ jsr baiter_check ; 8555 20 7B BB {.
+L8558: lda $D4 ; 8558 A5 D4 ..
+ clc ; 855A 18 .
+ adc #$20 ; 855B 69 20 i
+ bne L8582 ; 855D D0 23 .#
+ jsr draw_scanner_border_and_planet ; 855F 20 B1 9F ..
+ lda drone_volume ; 8562 A5 BD ..
+ lsr a ; 8564 4A J
+ sta drone_volume ; 8565 85 BD ..
+ ora #$A0 ; 8567 09 A0 ..
+ sta AUDC3 ; 8569 8D 05 D2 ...
+ sta AUDC4 ; 856C 8D 07 D2 ...
+ bit $AD ; 856F 24 AD $.
+ bpl L857F ; 8571 10 0C ..
+ lda level_jiffies_lo ; 8573 A5 87 ..
+ and #$08 ; 8575 29 08 ).
+ bne L857F ; 8577 D0 06 ..
+ jsr flash_score ; 8579 20 BC 93 ..
+ jmp L8582 ; 857C 4C 82 85 L..
+
+; ----------------------------------------------------------------------------
+L857F: jsr draw_scores ; 857F 20 42 94 B.
+L8582: lda $D4 ; 8582 A5 D4 ..
+ and #$07 ; 8584 29 07 ).
+ bne L858B ; 8586 D0 03 ..
+ jsr draw_starfield ; 8588 20 32 A8 2.
+L858B: lda $D4 ; 858B A5 D4 ..
+ clc ; 858D 18 .
+ adc #$B3 ; 858E 69 B3 i.
+ bne L8595 ; 8590 D0 03 ..
+ jsr draw_p2_lives_and_bombs ; 8592 20 80 87 ..
+L8595: lda $D4 ; 8595 A5 D4 ..
+ clc ; 8597 18 .
+ adc #$A0 ; 8598 69 A0 i.
+ bne L859F ; 859A D0 03 ..
+ jsr draw_p1_lives_and_bombs ; 859C 20 B0 86 ..
+L859F: lda $D4 ; 859F A5 D4 ..
+ adc #$40 ; 85A1 69 40 i@
+ and #$3F ; 85A3 29 3F )?
+ bne L85AA ; 85A5 D0 03 ..
+ jsr check_hyperspace ; 85A7 20 81 88 ..
+L85AA: jsr update_player_shots ; 85AA 20 17 9A ..
+ jsr start_explosion ; 85AD 20 1A 9C ..
+ lda $D4 ; 85B0 A5 D4 ..
+ and #$07 ; 85B2 29 07 ).
+ beq L85B9 ; 85B4 F0 03 ..
+ jmp L851C ; 85B6 4C 1C 85 L..
+
+; ----------------------------------------------------------------------------
+L85B9: jsr erase_scanner_ship ; 85B9 20 0C A2 ..
+ jsr erase_ship ; 85BC 20 88 B5 ..
+ jsr erase_exhaust ; 85BF 20 62 99 b.
+ lda game_type ; 85C2 A5 E1 ..
+ bne move_ship ; 85C4 D0 03 ..
+ jmp demo_logic ; 85C6 4C BD 88 L..
+
+; ----------------------------------------------------------------------------
+; only in non-demo game
+move_ship:
+ lda ship_move_delay ; 85C9 A5 93 ..
+ and #$03 ; 85CB 29 03 ).
+ beq L85D2 ; 85CD F0 03 ..
+ jsr inertia_logic ; 85CF 20 81 86 ..
+L85D2: inc ship_move_delay ; 85D2 E6 93 ..
+ lda ship_move_delay ; 85D4 A5 93 ..
+ and #$03 ; 85D6 29 03 ).
+ beq L85DF ; 85D8 F0 05 ..
+ jsr check_ship_move ; 85DA 20 EE AC ..
+ bcc L85F3 ; 85DD 90 14 ..
+L85DF: lda TRIG0 ; 85DF AD 10 D0 ...
+ ldy current_player ; 85E2 A4 F1 ..
+ cpy #$02 ; 85E4 C0 02 ..
+ bne L85EB ; 85E6 D0 03 ..
+ lda TRIG1 ; 85E8 AD 11 D0 ...
+L85EB: eor trigger ; 85EB 45 A3 E.
+ and #$01 ; 85ED 29 01 ).
+ bne read_trigger ; 85EF D0 2B .+
+ beq L8603 ; 85F1 F0 10 ..
+L85F3: cmp #$88 ; 85F3 C9 88 ..
+ beq L8670 ; 85F5 F0 79 .y
+ cmp #$95 ; 85F7 C9 95 ..
+ beq L8677 ; 85F9 F0 7C .|
+ cmp #$C1 ; 85FB C9 C1 ..
+ beq L8630 ; 85FD F0 31 .1
+ cmp #$DA ; 85FF C9 DA ..
+ beq L8650 ; 8601 F0 4D .M
+L8603: clc ; 8603 18 .
+ lda ship_x_pos ; 8604 A5 C3 ..
+ adc $89 ; 8606 65 89 e.
+ sta $91 ; 8608 85 91 ..
+ lda $8A ; 860A A5 8A ..
+ adc #$00 ; 860C 69 00 i.
+ sta $92 ; 860E 85 92 ..
+ jsr draw_ship ; 8610 20 A1 B5 ..
+ jsr ship_exhaust ; 8613 20 86 99 ..
+ jsr draw_scanner_ship ; 8616 20 93 A1 ..
+ jmp L851C ; 8619 4C 1C 85 L..
+
+; ----------------------------------------------------------------------------
+; TRIG0 or 1 depending on which player is playing
+read_trigger:
+ lda TRIG0 ; 861C AD 10 D0 ...
+ ldy current_player ; 861F A4 F1 ..
+ cpy #$02 ; 8621 C0 02 ..
+ bne store_trigger ; 8623 D0 03 ..
+ lda TRIG1 ; 8625 AD 11 D0 ...
+store_trigger:
+ sta trigger ; 8628 85 A3 ..
+ jsr handle_trigger ; 862A 20 D0 99 ..
+ jmp L8603 ; 862D 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L8630: lda #$00 ; 8630 A9 00 ..
+ sta $EA ; 8632 85 EA ..
+ inc $E9 ; 8634 E6 E9 ..
+ lda $E9 ; 8636 A5 E9 ..
+ cmp #$03 ; 8638 C9 03 ..
+ bcc L863E ; 863A 90 02 ..
+ dec $E9 ; 863C C6 E9 ..
+L863E: sec ; 863E 38 8
+ lda ship_y_pos ; 863F A5 C4 ..
+ sbc $E9 ; 8641 E5 E9 ..
+ sta ship_y_pos ; 8643 85 C4 ..
+ cmp #$20 ; 8645 C9 20 .
+ bcs L8603 ; 8647 B0 BA ..
+ lda #$20 ; 8649 A9 20 .
+ sta ship_y_pos ; 864B 85 C4 ..
+ jmp L8603 ; 864D 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L8650: lda #$00 ; 8650 A9 00 ..
+ sta $E9 ; 8652 85 E9 ..
+ inc $EA ; 8654 E6 EA ..
+ lda $EA ; 8656 A5 EA ..
+ cmp #$03 ; 8658 C9 03 ..
+ bcc L865E ; 865A 90 02 ..
+ dec $EA ; 865C C6 EA ..
+L865E: clc ; 865E 18 .
+ lda ship_y_pos ; 865F A5 C4 ..
+ adc $EA ; 8661 65 EA e.
+ sta ship_y_pos ; 8663 85 C4 ..
+ cmp #$B4 ; 8665 C9 B4 ..
+ bcc L8603 ; 8667 90 9A ..
+ lda #$B4 ; 8669 A9 B4 ..
+ sta ship_y_pos ; 866B 85 C4 ..
+ jmp L8603 ; 866D 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L8670: lda #$FF ; 8670 A9 FF ..
+ sta ship_direction ; 8672 85 C5 ..
+ jmp L867B ; 8674 4C 7B 86 L{.
+
+; ----------------------------------------------------------------------------
+L8677: lda #$01 ; 8677 A9 01 ..
+ sta ship_direction ; 8679 85 C5 ..
+L867B: jmp L8603 ; 867B 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+ jmp L8603 ; 867E 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+; XXX not fully understood, stubbing this out makes the ship turn on a dime
+inertia_logic:
+ lda ship_direction ; 8681 A5 C5 ..
+ bmi L86A5 ; 8683 30 20 0
+ lda ship_x_pos ; 8685 A5 C3 ..
+ cmp #$20 ; 8687 C9 20 .
+ beq L86AF ; 8689 F0 24 .$
+ bcc L8699 ; 868B 90 0C ..
+L868D: dec ship_x_pos ; 868D C6 C3 ..
+ clc ; 868F 18 .
+ lda ship_delta ; 8690 A5 D5 ..
+ adc #$03 ; 8692 69 03 i.
+ sta ship_delta ; 8694 85 D5 ..
+ jmp L86AF ; 8696 4C AF 86 L..
+
+; ----------------------------------------------------------------------------
+L8699: inc ship_x_pos ; 8699 E6 C3 ..
+ sec ; 869B 38 8
+ lda ship_delta ; 869C A5 D5 ..
+ sbc #$03 ; 869E E9 03 ..
+ sta ship_delta ; 86A0 85 D5 ..
+ jmp L86AF ; 86A2 4C AF 86 L..
+
+; ----------------------------------------------------------------------------
+L86A5: lda ship_x_pos ; 86A5 A5 C3 ..
+ cmp #$76 ; 86A7 C9 76 .v
+ beq L86AF ; 86A9 F0 04 ..
+ bcc L8699 ; 86AB 90 EC ..
+ bcs L868D ; 86AD B0 DE ..
+L86AF: rts ; 86AF 60 `
+
+; ----------------------------------------------------------------------------
+; update HUD
+draw_p1_lives_and_bombs:
+ lda animation_counter ; 86B0 A5 85 ..
+ pha ; 86B2 48 H
+ inc ship_anim_counter ; 86B3 E6 AA ..
+ lda ship_anim_counter ; 86B5 A5 AA ..
+ sta animation_counter ; 86B7 85 85 ..
+ lda ship_x_pos ; 86B9 A5 C3 ..
+ pha ; 86BB 48 H
+ lda ship_y_pos ; 86BC A5 C4 ..
+ pha ; 86BE 48 H
+ lda ship_direction ; 86BF A5 C5 ..
+ pha ; 86C1 48 H
+ lda #$00 ; 86C2 A9 00 ..
+ sta ship_direction ; 86C4 85 C5 ..
+ lda current_player ; 86C6 A5 F1 ..
+ cmp #$02 ; 86C8 C9 02 ..
+ bne L86D0 ; 86CA D0 04 ..
+ lda #$FF ; 86CC A9 FF ..
+ sta ship_direction ; 86CE 85 C5 ..
+L86D0: lda lives ; 86D0 A5 9E ..
+ cmp #$02 ; 86D2 C9 02 ..
+ beq L870C ; 86D4 F0 36 .6
+ bcc L8724 ; 86D6 90 4C .L
+ cmp #$03 ; 86D8 C9 03 ..
+ beq L86F4 ; 86DA F0 18 ..
+ lda #$1C ; 86DC A9 1C ..
+ sta ship_x_pos ; 86DE 85 C3 ..
+ lda current_player ; 86E0 A5 F1 ..
+ cmp #$01 ; 86E2 C9 01 ..
+ beq L86EA ; 86E4 F0 04 ..
+ lda #$96 ; 86E6 A9 96 ..
+ sta ship_x_pos ; 86E8 85 C3 ..
+L86EA: lda #$00 ; 86EA A9 00 ..
+ sta ship_y_pos ; 86EC 85 C4 ..
+ jsr erase_ship ; 86EE 20 88 B5 ..
+ jsr draw_ship ; 86F1 20 A1 B5 ..
+L86F4: lda #$10 ; 86F4 A9 10 ..
+ sta ship_x_pos ; 86F6 85 C3 ..
+ lda current_player ; 86F8 A5 F1 ..
+ cmp #$01 ; 86FA C9 01 ..
+ beq L8702 ; 86FC F0 04 ..
+ lda #$8A ; 86FE A9 8A ..
+ sta ship_x_pos ; 8700 85 C3 ..
+L8702: lda #$00 ; 8702 A9 00 ..
+ sta ship_y_pos ; 8704 85 C4 ..
+ jsr erase_ship ; 8706 20 88 B5 ..
+ jsr draw_ship ; 8709 20 A1 B5 ..
+L870C: lda #$04 ; 870C A9 04 ..
+ sta ship_x_pos ; 870E 85 C3 ..
+ lda current_player ; 8710 A5 F1 ..
+ cmp #$01 ; 8712 C9 01 ..
+ beq L871A ; 8714 F0 04 ..
+ lda #$7E ; 8716 A9 7E .~
+ sta ship_x_pos ; 8718 85 C3 ..
+L871A: lda #$00 ; 871A A9 00 ..
+ sta ship_y_pos ; 871C 85 C4 ..
+ jsr erase_ship ; 871E 20 88 B5 ..
+ jsr draw_ship ; 8721 20 A1 B5 ..
+L8724: ldy #$0A ; 8724 A0 0A ..
+ sty sprite_y ; 8726 84 DF ..
+ ldy #$22 ; 8728 A0 22 ."
+ sty sprite_x ; 872A 84 E3 ..
+ lda current_player ; 872C A5 F1 ..
+ cmp #$01 ; 872E C9 01 ..
+ beq draw_smartbombs ; 8730 F0 04 ..
+ ldy #$7A ; 8732 A0 7A .z
+ sty sprite_x ; 8734 84 E3 ..
+; draw smartbombs in the HUD, if any are left (max 3)
+draw_smartbombs:
+ ldy #$07 ; 8736 A0 07 ..
+ sty current_sprite ; 8738 84 F9 ..
+ lda smartbombs ; 873A A5 A5 ..
+ beq L8760 ; 873C F0 22 ."
+ cmp #$04 ; 873E C9 04 ..
+ bcc smartbombs_ok ; 8740 90 02 ..
+ lda #$03 ; 8742 A9 03 ..
+; A holds number of visible bombs, 1 to 3
+smartbombs_ok:
+ pha ; 8744 48 H
+ jsr erase_sprite ; 8745 20 2C AB ,.
+ lda animation_counter ; 8748 A5 85 ..
+ and #$02 ; 874A 29 02 ).
+ lsr a ; 874C 4A J
+ clc ; 874D 18 .
+ adc #$1A ; 874E 69 1A i.
+ jsr draw_sprite_left_copy ; 8750 20 00 1F ..
+ clc ; 8753 18 .
+ lda sprite_y ; 8754 A5 DF ..
+ adc #$06 ; 8756 69 06 i.
+ sta sprite_y ; 8758 85 DF ..
+ pla ; 875A 68 h
+ sec ; 875B 38 8
+ sbc #$01 ; 875C E9 01 ..
+ bne smartbombs_ok ; 875E D0 E4 ..
+L8760: lda sprite_y ; 8760 A5 DF ..
+ cmp #$18 ; 8762 C9 18 ..
+ bcs L8773 ; 8764 B0 0D ..
+ jsr erase_sprite ; 8766 20 2C AB ,.
+ clc ; 8769 18 .
+ lda sprite_y ; 876A A5 DF ..
+ adc #$06 ; 876C 69 06 i.
+ sta sprite_y ; 876E 85 DF ..
+ jmp L8760 ; 8770 4C 60 87 L`.
+
+; ----------------------------------------------------------------------------
+L8773: pla ; 8773 68 h
+ sta ship_direction ; 8774 85 C5 ..
+ pla ; 8776 68 h
+ sta ship_y_pos ; 8777 85 C4 ..
+ pla ; 8779 68 h
+ sta ship_x_pos ; 877A 85 C3 ..
+ pla ; 877C 68 h
+ sta animation_counter ; 877D 85 85 ..
+ rts ; 877F 60 `
+
+; ----------------------------------------------------------------------------
+; update HUD
+draw_p2_lives_and_bombs:
+ lda players ; 8780 A5 E2 ..
+ cmp #$02 ; 8782 C9 02 ..
+ bcs L8787 ; 8784 B0 01 ..
+ rts ; 8786 60 `
+
+; ----------------------------------------------------------------------------
+L8787: lda animation_counter ; 8787 A5 85 ..
+ pha ; 8789 48 H
+ inc ship_anim_counter ; 878A E6 AA ..
+ lda ship_anim_counter ; 878C A5 AA ..
+ sta animation_counter ; 878E 85 85 ..
+ lda ship_x_pos ; 8790 A5 C3 ..
+ pha ; 8792 48 H
+ lda ship_y_pos ; 8793 A5 C4 ..
+ pha ; 8795 48 H
+ lda ship_direction ; 8796 A5 C5 ..
+ pha ; 8798 48 H
+ lda #$00 ; 8799 A9 00 ..
+ sta ship_direction ; 879B 85 C5 ..
+ lda current_player ; 879D A5 F1 ..
+ cmp #$02 ; 879F C9 02 ..
+ beq L87A7 ; 87A1 F0 04 ..
+ lda #$FF ; 87A3 A9 FF ..
+ sta ship_direction ; 87A5 85 C5 ..
+L87A7: lda current_player ; 87A7 A5 F1 ..
+ cmp #$01 ; 87A9 C9 01 ..
+ beq L87B3 ; 87AB F0 06 ..
+ lda p1_sav_lives ; 87AD AD C6 17 ...
+ jmp L87B6 ; 87B0 4C B6 87 L..
+
+; ----------------------------------------------------------------------------
+L87B3: lda p2_sav_lives ; 87B3 AD C6 19 ...
+L87B6: clc ; 87B6 18 .
+ adc #$01 ; 87B7 69 01 i.
+ cmp #$02 ; 87B9 C9 02 ..
+ beq L87F3 ; 87BB F0 36 .6
+ bcc L880B ; 87BD 90 4C .L
+ cmp #$03 ; 87BF C9 03 ..
+ beq L87DB ; 87C1 F0 18 ..
+ lda #$1C ; 87C3 A9 1C ..
+ sta ship_x_pos ; 87C5 85 C3 ..
+ lda current_player ; 87C7 A5 F1 ..
+ cmp #$01 ; 87C9 C9 01 ..
+ bne L87D1 ; 87CB D0 04 ..
+ lda #$96 ; 87CD A9 96 ..
+ sta ship_x_pos ; 87CF 85 C3 ..
+L87D1: lda #$00 ; 87D1 A9 00 ..
+ sta ship_y_pos ; 87D3 85 C4 ..
+ jsr erase_ship ; 87D5 20 88 B5 ..
+ jsr draw_ship ; 87D8 20 A1 B5 ..
+L87DB: lda #$10 ; 87DB A9 10 ..
+ sta ship_x_pos ; 87DD 85 C3 ..
+ lda current_player ; 87DF A5 F1 ..
+ cmp #$01 ; 87E1 C9 01 ..
+ bne L87E9 ; 87E3 D0 04 ..
+ lda #$8A ; 87E5 A9 8A ..
+ sta ship_x_pos ; 87E7 85 C3 ..
+L87E9: lda #$00 ; 87E9 A9 00 ..
+ sta ship_y_pos ; 87EB 85 C4 ..
+ jsr erase_ship ; 87ED 20 88 B5 ..
+ jsr draw_ship ; 87F0 20 A1 B5 ..
+L87F3: lda #$04 ; 87F3 A9 04 ..
+ sta ship_x_pos ; 87F5 85 C3 ..
+ lda current_player ; 87F7 A5 F1 ..
+ cmp #$01 ; 87F9 C9 01 ..
+ bne L8801 ; 87FB D0 04 ..
+ lda #$7E ; 87FD A9 7E .~
+ sta ship_x_pos ; 87FF 85 C3 ..
+L8801: lda #$00 ; 8801 A9 00 ..
+ sta ship_y_pos ; 8803 85 C4 ..
+ jsr erase_ship ; 8805 20 88 B5 ..
+ jsr draw_ship ; 8808 20 A1 B5 ..
+L880B: ldy #$0A ; 880B A0 0A ..
+ sty sprite_y ; 880D 84 DF ..
+ ldy #$22 ; 880F A0 22 ."
+ sty sprite_x ; 8811 84 E3 ..
+ lda current_player ; 8813 A5 F1 ..
+ cmp #$01 ; 8815 C9 01 ..
+ bne L881D ; 8817 D0 04 ..
+ ldy #$7A ; 8819 A0 7A .z
+ sty sprite_x ; 881B 84 E3 ..
+L881D: ldy #$07 ; 881D A0 07 ..
+ sty current_sprite ; 881F 84 F9 ..
+ lda current_player ; 8821 A5 F1 ..
+ cmp #$01 ; 8823 C9 01 ..
+ beq L882D ; 8825 F0 06 ..
+ lda p1_sav_bombs ; 8827 AD C7 17 ...
+ jmp L8830 ; 882A 4C 30 88 L0.
+
+; ----------------------------------------------------------------------------
+L882D: lda p2_sav_bombs ; 882D AD C7 19 ...
+L8830: beq L8854 ; 8830 F0 22 ."
+ cmp #$04 ; 8832 C9 04 ..
+ bcc L8838 ; 8834 90 02 ..
+ lda #$03 ; 8836 A9 03 ..
+L8838: pha ; 8838 48 H
+ jsr erase_sprite ; 8839 20 2C AB ,.
+ lda animation_counter ; 883C A5 85 ..
+ and #$02 ; 883E 29 02 ).
+ lsr a ; 8840 4A J
+ clc ; 8841 18 .
+ adc #$1A ; 8842 69 1A i.
+ jsr draw_sprite_left_copy ; 8844 20 00 1F ..
+ clc ; 8847 18 .
+ lda sprite_y ; 8848 A5 DF ..
+ adc #$06 ; 884A 69 06 i.
+ sta sprite_y ; 884C 85 DF ..
+ pla ; 884E 68 h
+ sec ; 884F 38 8
+ sbc #$01 ; 8850 E9 01 ..
+ bne L8838 ; 8852 D0 E4 ..
+L8854: lda sprite_y ; 8854 A5 DF ..
+ cmp #$18 ; 8856 C9 18 ..
+ bcs L8867 ; 8858 B0 0D ..
+ jsr erase_sprite ; 885A 20 2C AB ,.
+ clc ; 885D 18 .
+ lda sprite_y ; 885E A5 DF ..
+ adc #$06 ; 8860 69 06 i.
+ sta sprite_y ; 8862 85 DF ..
+ jmp L8854 ; 8864 4C 54 88 LT.
+
+; ----------------------------------------------------------------------------
+L8867: pla ; 8867 68 h
+ sta ship_direction ; 8868 85 C5 ..
+ pla ; 886A 68 h
+ sta ship_y_pos ; 886B 85 C4 ..
+ pla ; 886D 68 h
+ sta ship_x_pos ; 886E 85 C3 ..
+ pla ; 8870 68 h
+ sta animation_counter ; 8871 85 85 ..
+ rts ; 8873 60 `
+
+; ----------------------------------------------------------------------------
+; takes delay time in A. only ever called with A=$80 (delays a bit less than 3 frames) or A=$FF (almost 7 frames)
+delay_loop:
+ pha ; 8874 48 H
+ sec ; 8875 38 8
+dl_wait:sbc #$01 ; 8876 E9 01 ..
+ bcs dl_wait ; 8878 B0 FC ..
+ pla ; 887A 68 h
+ sec ; 887B 38 8
+ sbc #$01 ; 887C E9 01 ..
+ bcs delay_loop ; 887E B0 F4 ..
+ rts ; 8880 60 `
+
+; ----------------------------------------------------------------------------
+; did the player press a key to use hyperspace?
+check_hyperspace:
+ bit hyperspace_flag ; 8881 24 AE $.
+ bmi hyperspace_pressed ; 8883 30 01 0.
+ rts ; 8885 60 `
+
+; ----------------------------------------------------------------------------
+; yes, he did
+hyperspace_pressed:
+ jsr play_materialize ; 8886 20 32 8E 2.
+ jsr clear_screen ; 8889 20 A1 B8 ..
+ jsr clear_player_shots ; 888C 20 F1 B7 ..
+ inc $D0 ; 888F E6 D0 ..
+ jsr clear_scanner_draw_planet_and_humans; 8891 20 5E 9E ^.
+ jsr draw_scanner_border_and_planet ; 8894 20 B1 9F ..
+ lda #$10 ; 8897 A9 10 ..
+hsp_loop:
+ pha ; 8899 48 H
+ jsr draw_starfield ; 889A 20 32 A8 2.
+ pla ; 889D 68 h
+ sec ; 889E 38 8
+ sbc #$01 ; 889F E9 01 ..
+ bne hsp_loop ; 88A1 D0 F6 ..
+ jsr draw_scores ; 88A3 20 42 94 B.
+ jsr draw_p1_lives_and_bombs ; 88A6 20 B0 86 ..
+ jsr hyperspace_implosion ; 88A9 20 E7 97 ..
+ lsr hyperspace_flag ; 88AC 46 AE F.
+; don't ever kill the 'player' in demo mode (game_type==0)
+hsp_check_demo:
+ lda game_type ; 88AE A5 E1 ..
+ beq hsp_done ; 88B0 F0 0A ..
+; kill player if RANDOM >= $AA (in other words, 33% of the time!)
+check_hyperspace_fatal:
+ lda RANDOM ; 88B2 AD 0A D2 ...
+ cmp #$AA ; 88B5 C9 AA ..
+ bcc hsp_done ; 88B7 90 03 ..
+ jmp start_player_death ; 88B9 4C 4C B6 LL.
+
+; ----------------------------------------------------------------------------
+hsp_done:
+ rts ; 88BC 60 `
+
+; ----------------------------------------------------------------------------
+; animate the demo-game ship
+demo_logic:
+ sec ; 88BD 38 8
+ ror invuln_flag ; 88BE 66 ED f.
+ sec ; 88C0 38 8
+ ror exhaust_flag ; 88C1 6E 2B 0D n+.
+ lda #$05 ; 88C4 A9 05 ..
+ sta ship_delta ; 88C6 85 D5 ..
+ lda ship_move_delay ; 88C8 A5 93 ..
+ and #$03 ; 88CA 29 03 ).
+ beq L88D1 ; 88CC F0 03 ..
+ jsr inertia_logic ; 88CE 20 81 86 ..
+L88D1: inc ship_move_delay ; 88D1 E6 93 ..
+ lda ship_move_delay ; 88D3 A5 93 ..
+ and #$03 ; 88D5 29 03 ).
+ beq L892B ; 88D7 F0 52 .R
+ lda #$00 ; 88D9 A9 00 ..
+ sta $98 ; 88DB 85 98 ..
+L88DD: ldy $98 ; 88DD A4 98 ..
+ lda sprite_list,y ; 88DF B9 EB 0A ...
+ bne L88F0 ; 88E2 D0 0C ..
+L88E4: lda $98 ; 88E4 A5 98 ..
+ clc ; 88E6 18 .
+ adc #$04 ; 88E7 69 04 i.
+ sta $98 ; 88E9 85 98 ..
+ bpl L88DD ; 88EB 10 F0 ..
+ jmp L8603 ; 88ED 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L88F0: lda sprite_list+3,y ; 88F0 B9 EE 0A ...
+ and #$07 ; 88F3 29 07 ).
+ beq L88E4 ; 88F5 F0 ED ..
+ cmp #$03 ; 88F7 C9 03 ..
+ beq L88E4 ; 88F9 F0 E9 ..
+ cmp #$07 ; 88FB C9 07 ..
+ beq L88E4 ; 88FD F0 E5 ..
+ lda sprite_list,y ; 88FF B9 EB 0A ...
+ cmp ship_y_pos ; 8902 C5 C4 ..
+ ror a ; 8904 6A j
+ eor #$FF ; 8905 49 FF I.
+ sta $F3 ; 8907 85 F3 ..
+ bit $F3 ; 8909 24 F3 $.
+ bpl L891C ; 890B 10 0F ..
+ dec ship_y_pos ; 890D C6 C4 ..
+ lda ship_y_pos ; 890F A5 C4 ..
+ cmp #$20 ; 8911 C9 20 .
+ bcs L8959 ; 8913 B0 44 .D
+ lda #$20 ; 8915 A9 20 .
+ sta ship_y_pos ; 8917 85 C4 ..
+ jmp L8603 ; 8919 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L891C: inc ship_y_pos ; 891C E6 C4 ..
+ lda ship_y_pos ; 891E A5 C4 ..
+ cmp #$A0 ; 8920 C9 A0 ..
+ bcc L8959 ; 8922 90 35 .5
+ lda #$A0 ; 8924 A9 A0 ..
+ sta ship_y_pos ; 8926 85 C4 ..
+ jmp L8603 ; 8928 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L892B: lda level_jiffies_lo ; 892B A5 87 ..
+ beq L894C ; 892D F0 1D ..
+ lda enemy_count ; 892F A5 9C ..
+ cmp #$08 ; 8931 C9 08 ..
+ bcs L8952 ; 8933 B0 1D ..
+ lda RANDOM ; 8935 AD 0A D2 ...
+ and #$07 ; 8938 29 07 ).
+ bne L8959 ; 893A D0 1D ..
+ bit planet_dead_flag ; 893C 24 A0 $.
+ bmi L8946 ; 893E 30 06 0.
+ lda ship_y_pos ; 8940 A5 C4 ..
+ cmp #$90 ; 8942 C9 90 ..
+ bcs L8959 ; 8944 B0 13 ..
+L8946: jsr handle_trigger ; 8946 20 D0 99 ..
+ jmp L8959 ; 8949 4C 59 89 LY.
+
+; ----------------------------------------------------------------------------
+L894C: sec ; 894C 38 8
+ ror hyperspace_flag ; 894D 66 AE f.
+ jmp L8959 ; 894F 4C 59 89 LY.
+
+; ----------------------------------------------------------------------------
+L8952: sec ; 8952 38 8
+ ror spacebar_flag ; 8953 66 AC f.
+ lda #$00 ; 8955 A9 00 ..
+ sta enemy_count ; 8957 85 9C ..
+L8959: jmp L8603 ; 8959 4C 03 86 L..
+
+; ----------------------------------------------------------------------------
+L895C: lda $D4 ; 895C A5 D4 ..
+ and #$3F ; 895E 29 3F )?
+ beq draw_demo_text ; 8960 F0 01 ..
+ rts ; 8962 60 `
+
+; ----------------------------------------------------------------------------
+; draw the text for DEFENDER c 1982 ATARI, during the demo game
+draw_demo_text:
+ lda draw_ok_flag ; 8963 A5 AB ..
+ bpl L895C ; 8965 10 F5 ..
+ lda #$01 ; 8967 A9 01 ..
+ sta cursor_x ; 8969 8D 39 14 .9.
+ lda #$14 ; 896C A9 14 ..
+ sta cursor_y ; 896E 8D 3A 14 .:.
+ lda glyph_color_mask ; 8971 A5 EE ..
+ pha ; 8973 48 H
+ lda level_jiffies_lo ; 8974 A5 87 ..
+ and #$03 ; 8976 29 03 ).
+ tay ; 8978 A8 .
+ lda L89B5,y ; 8979 B9 B5 89 ...
+ sta glyph_color_mask ; 897C 85 EE ..
+ ldy #$00 ; 897E A0 00 ..
+L8980: lda demo_text,y ; 8980 B9 8F 89 ...
+ beq L898B ; 8983 F0 06 ..
+ jsr printchar ; 8985 20 2E 97 ..
+ iny ; 8988 C8 .
+ bne L8980 ; 8989 D0 F5 ..
+L898B: pla ; 898B 68 h
+ sta glyph_color_mask ; 898C 85 EE ..
+ rts ; 898E 60 `
+
+; ----------------------------------------------------------------------------
+; ' D E F E N D E R c 1982 A T A R I '
+demo_text:
+ .byte $A0,$C4,$A0,$C5,$A0,$C6,$A0,$C5 ; 898F A0 C4 A0 C5 A0 C6 A0 C5 ........
+ .byte $A0,$CE,$A0,$C4,$A0,$C5,$A0,$D2 ; 8997 A0 CE A0 C4 A0 C5 A0 D2 ........
+ .byte $A0,$A0,$A0,$A0,$C0,$A0,$B1,$B9 ; 899F A0 A0 A0 A0 C0 A0 B1 B9 ........
+ .byte $B8,$B2,$A0,$A0,$C1,$A0,$D4,$A0 ; 89A7 B8 B2 A0 A0 C1 A0 D4 A0 ........
+ .byte $C1,$A0,$D2,$A0,$C9,$00 ; 89AF C1 A0 D2 A0 C9 00 ......
+L89B5: .byte $FF,$AA,$FF,$55 ; 89B5 FF AA FF 55 ...U
+; ----------------------------------------------------------------------------
+; save game state to p1_sav_* area
+save_p1_state:
+ ldx #$00 ; 89B9 A2 00 ..
+L89BB: cpx #$80 ; 89BB E0 80 ..
+ bcs L89CB ; 89BD B0 0C ..
+ lda sprite_list,x ; 89BF BD EB 0A ...
+ sta p1_sav_sprite_list,x ; 89C2 9D 00 16 ...
+ lda sprite_list+128,x ; 89C5 BD 6B 0B .k.
+ sta p1_sav_sprite_list+128,x ; 89C8 9D 80 16 ...
+L89CB: lda actor_list,x ; 89CB BD 6B 0C .k.
+ sta $1700,x ; 89CE 9D 00 17 ...
+ inx ; 89D1 E8 .
+ cpx #$C0 ; 89D2 E0 C0 ..
+ bcc L89BB ; 89D4 90 E5 ..
+ lda score ; 89D6 AD 2F 14 ./.
+ sta p1_sav_score ; 89D9 8D C0 17 ...
+ lda score+1 ; 89DC AD 30 14 .0.
+ sta p1_sav_score+1 ; 89DF 8D C1 17 ...
+ lda score+2 ; 89E2 AD 31 14 .1.
+ sta p1_sav_score+2 ; 89E5 8D C2 17 ...
+ lda score+3 ; 89E8 AD 32 14 .2.
+ sta p1_sav_score+3 ; 89EB 8D C3 17 ...
+ lda planet_dead_flag ; 89EE A5 A0 ..
+ sta $17C4 ; 89F0 8D C4 17 ...
+ lda enemy_firing_freq ; 89F3 A5 BB ..
+ sta p1_sav_fire_freq ; 89F5 8D C5 17 ...
+ lda lives ; 89F8 A5 9E ..
+ sta p1_sav_lives ; 89FA 8D C6 17 ...
+ lda smartbombs ; 89FD A5 A5 ..
+ sta p1_sav_bombs ; 89FF 8D C7 17 ...
+ lda landers_to_spawn ; 8A02 A5 9B ..
+ sta p1_sav_lander_wave_count ; 8A04 8D C8 17 ...
+ lda level ; 8A07 A5 9A ..
+ sta p1_sav_level ; 8A09 8D C9 17 ...
+ rts ; 8A0C 60 `
+
+; ----------------------------------------------------------------------------
+; save game state to p2_sav_* area
+save_p2_state:
+ ldx #$00 ; 8A0D A2 00 ..
+L8A0F: cpx #$80 ; 8A0F E0 80 ..
+ bcs L8A1F ; 8A11 B0 0C ..
+ lda sprite_list,x ; 8A13 BD EB 0A ...
+ sta p2_sav_sprite_list,x ; 8A16 9D 00 18 ...
+ lda sprite_list+128,x ; 8A19 BD 6B 0B .k.
+ sta p2_sav_sprite_list+128,x ; 8A1C 9D 80 18 ...
+L8A1F: lda actor_list,x ; 8A1F BD 6B 0C .k.
+ sta $1900,x ; 8A22 9D 00 19 ...
+ inx ; 8A25 E8 .
+ cpx #$C0 ; 8A26 E0 C0 ..
+ bcc L8A0F ; 8A28 90 E5 ..
+ lda score ; 8A2A AD 2F 14 ./.
+ sta p2_sav_score ; 8A2D 8D C0 19 ...
+ lda score+1 ; 8A30 AD 30 14 .0.
+ sta p2_sav_score+1 ; 8A33 8D C1 19 ...
+ lda score+2 ; 8A36 AD 31 14 .1.
+ sta p2_sav_score+2 ; 8A39 8D C2 19 ...
+ lda score+3 ; 8A3C AD 32 14 .2.
+ sta p2_sav_score+3 ; 8A3F 8D C3 19 ...
+ lda planet_dead_flag ; 8A42 A5 A0 ..
+ sta p2_sav_planet_dead ; 8A44 8D C4 19 ...
+ lda enemy_firing_freq ; 8A47 A5 BB ..
+ sta p2_sav_fire_freq ; 8A49 8D C5 19 ...
+ lda lives ; 8A4C A5 9E ..
+ sta p2_sav_lives ; 8A4E 8D C6 19 ...
+ lda smartbombs ; 8A51 A5 A5 ..
+ sta p2_sav_bombs ; 8A53 8D C7 19 ...
+ lda landers_to_spawn ; 8A56 A5 9B ..
+ sta p2_sav_lander_wave_count ; 8A58 8D C8 19 ...
+ lda level ; 8A5B A5 9A ..
+ sta p2_sav_level ; 8A5D 8D C9 19 ...
+ rts ; 8A60 60 `
+
+; ----------------------------------------------------------------------------
+; restore game state from p1_sav_* area
+load_p1_state:
+ ldx #$00 ; 8A61 A2 00 ..
+L8A63: cpx #$80 ; 8A63 E0 80 ..
+ bcs L8A73 ; 8A65 B0 0C ..
+ lda p1_sav_sprite_list,x ; 8A67 BD 00 16 ...
+ sta sprite_list,x ; 8A6A 9D EB 0A ...
+ lda p1_sav_sprite_list+128,x ; 8A6D BD 80 16 ...
+ sta sprite_list+128,x ; 8A70 9D 6B 0B .k.
+L8A73: lda $1700,x ; 8A73 BD 00 17 ...
+ sta actor_list,x ; 8A76 9D 6B 0C .k.
+ inx ; 8A79 E8 .
+ cpx #$C0 ; 8A7A E0 C0 ..
+ bcc L8A63 ; 8A7C 90 E5 ..
+ lda p1_sav_score ; 8A7E AD C0 17 ...
+ sta score ; 8A81 8D 2F 14 ./.
+ lda p1_sav_score+1 ; 8A84 AD C1 17 ...
+ sta score+1 ; 8A87 8D 30 14 .0.
+ lda p1_sav_score+2 ; 8A8A AD C2 17 ...
+ sta score+2 ; 8A8D 8D 31 14 .1.
+ lda p1_sav_score+3 ; 8A90 AD C3 17 ...
+ sta score+3 ; 8A93 8D 32 14 .2.
+ lda $17C4 ; 8A96 AD C4 17 ...
+ sta planet_dead_flag ; 8A99 85 A0 ..
+ lda p1_sav_fire_freq ; 8A9B AD C5 17 ...
+ sta enemy_firing_freq ; 8A9E 85 BB ..
+ lda p1_sav_lives ; 8AA0 AD C6 17 ...
+ sta lives ; 8AA3 85 9E ..
+ lda p1_sav_bombs ; 8AA5 AD C7 17 ...
+ sta smartbombs ; 8AA8 85 A5 ..
+ lda p1_sav_lander_wave_count ; 8AAA AD C8 17 ...
+ sta landers_to_spawn ; 8AAD 85 9B ..
+ lda p1_sav_level ; 8AAF AD C9 17 ...
+ sta level ; 8AB2 85 9A ..
+ rts ; 8AB4 60 `
+
+; ----------------------------------------------------------------------------
+; restore game state from p2_sav_* area
+load_p2_state:
+ ldx #$00 ; 8AB5 A2 00 ..
+L8AB7: cpx #$80 ; 8AB7 E0 80 ..
+ bcs L8AC7 ; 8AB9 B0 0C ..
+ lda p2_sav_sprite_list,x ; 8ABB BD 00 18 ...
+ sta sprite_list,x ; 8ABE 9D EB 0A ...
+ lda p2_sav_sprite_list+128,x ; 8AC1 BD 80 18 ...
+ sta sprite_list+128,x ; 8AC4 9D 6B 0B .k.
+L8AC7: lda $1900,x ; 8AC7 BD 00 19 ...
+ sta actor_list,x ; 8ACA 9D 6B 0C .k.
+ inx ; 8ACD E8 .
+ cpx #$C0 ; 8ACE E0 C0 ..
+ bcc L8AB7 ; 8AD0 90 E5 ..
+ lda p2_sav_score ; 8AD2 AD C0 19 ...
+ sta score ; 8AD5 8D 2F 14 ./.
+ lda p2_sav_score+1 ; 8AD8 AD C1 19 ...
+ sta score+1 ; 8ADB 8D 30 14 .0.
+ lda p2_sav_score+2 ; 8ADE AD C2 19 ...
+ sta score+2 ; 8AE1 8D 31 14 .1.
+ lda p2_sav_score+3 ; 8AE4 AD C3 19 ...
+ sta score+3 ; 8AE7 8D 32 14 .2.
+ lda p2_sav_planet_dead ; 8AEA AD C4 19 ...
+ sta planet_dead_flag ; 8AED 85 A0 ..
+ lda p2_sav_fire_freq ; 8AEF AD C5 19 ...
+ sta enemy_firing_freq ; 8AF2 85 BB ..
+ lda p2_sav_lives ; 8AF4 AD C6 19 ...
+ sta lives ; 8AF7 85 9E ..
+ lda p2_sav_bombs ; 8AF9 AD C7 19 ...
+ sta smartbombs ; 8AFC 85 A5 ..
+ lda p2_sav_lander_wave_count ; 8AFE AD C8 19 ...
+ sta landers_to_spawn ; 8B01 85 9B ..
+ lda p2_sav_level ; 8B03 AD C9 19 ...
+ sta level ; 8B06 85 9A ..
+ rts ; 8B08 60 `
+
+; ----------------------------------------------------------------------------
+; print PLAYER ONE
+print_p1_text:
+ lda #$00 ; 8B09 A9 00 ..
+ sta cursor_x ; 8B0B 8D 39 14 .9.
+ lda #$0A ; 8B0E A9 0A ..
+ sta cursor_y ; 8B10 8D 3A 14 .:.
+ ldy #$00 ; 8B13 A0 00 ..
+L8B15: lda player_one_text,y ; 8B15 B9 21 8B .!.
+ beq L8B20 ; 8B18 F0 06 ..
+ jsr printchar ; 8B1A 20 2E 97 ..
+ iny ; 8B1D C8 .
+ bne L8B15 ; 8B1E D0 F5 ..
+L8B20: rts ; 8B20 60 `
+
+; ----------------------------------------------------------------------------
+; ' P L A Y E R O N E'
+player_one_text:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 ; 8B21 A0 A0 A0 A0 A0 A0 A0 A0 ........
+ .byte $A0,$A0,$D0,$A0,$CC,$A0,$C1,$A0 ; 8B29 A0 A0 D0 A0 CC A0 C1 A0 ........
+ .byte $D9,$A0,$C5,$A0,$D2,$A0,$A0,$CF ; 8B31 D9 A0 C5 A0 D2 A0 A0 CF ........
+ .byte $A0,$CE,$A0,$C5,$00 ; 8B39 A0 CE A0 C5 00 .....
+; ----------------------------------------------------------------------------
+; print PLAYER TWO
+print_p2_text:
+ lda #$00 ; 8B3E A9 00 ..
+ sta cursor_x ; 8B40 8D 39 14 .9.
+ lda #$0A ; 8B43 A9 0A ..
+ sta cursor_y ; 8B45 8D 3A 14 .:.
+ ldy #$00 ; 8B48 A0 00 ..
+L8B4A: lda player_two_text,y ; 8B4A B9 56 8B .V.
+ beq L8B55 ; 8B4D F0 06 ..
+ jsr printchar ; 8B4F 20 2E 97 ..
+ iny ; 8B52 C8 .
+ bne L8B4A ; 8B53 D0 F5 ..
+L8B55: rts ; 8B55 60 `
+
+; ----------------------------------------------------------------------------
+; ' P L A Y E R T W O'
+player_two_text:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 ; 8B56 A0 A0 A0 A0 A0 A0 A0 A0 ........
+ .byte $A0,$A0,$D0,$A0,$CC,$A0,$C1,$A0 ; 8B5E A0 A0 D0 A0 CC A0 C1 A0 ........
+ .byte $D9,$A0,$C5,$A0,$D2,$A0,$A0,$D4 ; 8B66 D9 A0 C5 A0 D2 A0 A0 D4 ........
+ .byte $A0,$D7,$A0,$CF,$00 ; 8B6E A0 D7 A0 CF 00 .....
+; ----------------------------------------------------------------------------
+; print 40 spaces over the PLAYER (ONE|TWO) message
+clear_prompt_text:
+ lda #$00 ; 8B73 A9 00 ..
+ sta cursor_x ; 8B75 8D 39 14 .9.
+ lda #$0A ; 8B78 A9 0A ..
+ sta cursor_y ; 8B7A 8D 3A 14 .:.
+ ldy #$00 ; 8B7D A0 00 ..
+L8B7F: lda #$A0 ; 8B7F A9 A0 ..
+ jsr printchar ; 8B81 20 2E 97 ..
+ iny ; 8B84 C8 .
+ cpy #$28 ; 8B85 C0 28 .(
+ bcc L8B7F ; 8B87 90 F6 ..
+ rts ; 8B89 60 `
+
+; ----------------------------------------------------------------------------
+; see if player pressed the space bar (spacebar_flag >= $80)
+smartbomb_check:
+ lda spacebar_flag ; 8B8A A5 AC ..
+ bmi smartbomb_yes ; 8B8C 30 16 0.
+; copy protection. if we're running from RAM, cause game to jump to the title screen, then refuse to start
+ram_self_destruct_2:
+ lda swarmer_spawn_y_offsets ; 8B8E AD 68 B5 .h.
+ pha ; 8B91 48 H
+ eor #$FF ; 8B92 49 FF I.
+ sta swarmer_spawn_y_offsets ; 8B94 8D 68 B5 .h.
+ pla ; 8B97 68 h
+ cmp swarmer_spawn_y_offsets ; 8B98 CD 68 B5 .h.
+ beq rom_ok ; 8B9B F0 06 ..
+ sec ; 8B9D 38 8
+ ror protection_flag ; 8B9E 66 F8 f.
+ jmp init_title_screen ; 8BA0 4C 31 80 L1.
+
+; ----------------------------------------------------------------------------
+; if we get here, we're running from ROM
+rom_ok: rts ; 8BA3 60 `
+
+; ----------------------------------------------------------------------------
+; see if we have any bombs left, if so, detonate
+smartbomb_yes:
+ lda #$00 ; 8BA4 A9 00 ..
+ sta spacebar_flag ; 8BA6 85 AC ..
+ lda smartbombs ; 8BA8 A5 A5 ..
+ beq ram_self_destruct_2 ; 8BAA F0 E2 ..
+detonate_smartbomb:
+ dec smartbombs ; 8BAC C6 A5 ..
+ jsr play_smartbomb ; 8BAE 20 4E 8E N.
+ lda #$00 ; 8BB1 A9 00 ..
+ sta $98 ; 8BB3 85 98 ..
+ lda #$0F ; 8BB5 A9 0F ..
+ sta COLOR4 ; 8BB7 8D C8 02 ...
+ jmp smartbomb_kill_stuff ; 8BBA 4C D0 8B L..
+
+; ----------------------------------------------------------------------------
+kill_next:
+ lda $98 ; 8BBD A5 98 ..
+ clc ; 8BBF 18 .
+ adc #$04 ; 8BC0 69 04 i.
+ sta $98 ; 8BC2 85 98 ..
+ bpl smartbomb_kill_stuff ; 8BC4 10 0A ..
+ lda #$00 ; 8BC6 A9 00 ..
+ sta spacebar_flag ; 8BC8 85 AC ..
+ lda #$00 ; 8BCA A9 00 ..
+ sta COLOR4 ; 8BCC 8D C8 02 ...
+ rts ; 8BCF 60 `
+
+; ----------------------------------------------------------------------------
+; kill every enemy on the screen
+smartbomb_kill_stuff:
+ jsr smartbomb_flash ; 8BD0 20 0D 9C ..
+ lda COLOR4 ; 8BD3 AD C8 02 ...
+ eor #$0F ; 8BD6 49 0F I.
+ sta COLOR4 ; 8BD8 8D C8 02 ...
+ ldy $98 ; 8BDB A4 98 ..
+ lda sprite_list,y ; 8BDD B9 EB 0A ...
+ beq kill_next ; 8BE0 F0 DB ..
+ sta sprite_y ; 8BE2 85 DF ..
+ lda sprite_list+1,y ; 8BE4 B9 EC 0A ...
+ sta $DD ; 8BE7 85 DD ..
+ lda sprite_list+2,y ; 8BE9 B9 ED 0A ...
+ sta $DE ; 8BEC 85 DE ..
+ sec ; 8BEE 38 8
+ lda $DD ; 8BEF A5 DD ..
+ sbc $8B ; 8BF1 E5 8B ..
+ sta sprite_x ; 8BF3 85 E3 ..
+ lda $DE ; 8BF5 A5 DE ..
+ sbc $8C ; 8BF7 E5 8C ..
+ sta $E4 ; 8BF9 85 E4 ..
+ bcs L8C09 ; 8BFB B0 0C ..
+ lda sprite_x ; 8BFD A5 E3 ..
+ adc #$80 ; 8BFF 69 80 i.
+ sta sprite_x ; 8C01 85 E3 ..
+ lda $E4 ; 8C03 A5 E4 ..
+ adc #$02 ; 8C05 69 02 i.
+ sta $E4 ; 8C07 85 E4 ..
+L8C09: lda $E4 ; 8C09 A5 E4 ..
+L8C0B: bne kill_next ; 8C0B D0 B0 ..
+ lda sprite_x ; 8C0D A5 E3 ..
+ cmp #$A0 ; 8C0F C9 A0 ..
+ bcs kill_next ; 8C11 B0 AA ..
+ tya ; 8C13 98 .
+ pha ; 8C14 48 H
+ lda animation_counter ; 8C15 A5 85 ..
+ and #$04 ; 8C17 29 04 ).
+ asl a ; 8C19 0A .
+ clc ; 8C1A 18 .
+ adc sprite_list+3,y ; 8C1B 79 EE 0A y..
+ and #$0F ; 8C1E 29 0F ).
+ tay ; 8C20 A8 .
+ lda scanner_colormask_table,y ; 8C21 B9 92 A5 ...
+ sta scanner_colormask ; 8C24 85 A9 ..
+ pla ; 8C26 68 h
+ tay ; 8C27 A8 .
+ lda sprite_list+3,y ; 8C28 B9 EE 0A ...
+ sta current_sprite ; 8C2B 85 F9 ..
+ and #$07 ; 8C2D 29 07 ).
+ beq kill_next ; 8C2F F0 8C ..
+ cmp #$03 ; 8C31 C9 03 ..
+L8C33: beq kill_next ; 8C33 F0 88 ..
+ cmp #$01 ; 8C35 C9 01 ..
+ beq L8C43 ; 8C37 F0 0A ..
+ cmp #$05 ; 8C39 C9 05 ..
+ beq L8C69 ; 8C3B F0 2C .,
+ jsr sb_kill ; 8C3D 20 C3 8C ..
+ jmp kill_next ; 8C40 4C BD 8B L..
+
+; ----------------------------------------------------------------------------
+L8C43: jsr sb_kill ; 8C43 20 C3 8C ..
+ lda current_sprite ; 8C46 A5 F9 ..
+ cmp #$11 ; 8C48 C9 11 ..
+ beq L8C4F ; 8C4A F0 03 ..
+ jmp kill_next ; 8C4C 4C BD 8B L..
+
+; ----------------------------------------------------------------------------
+L8C4F: ldy $98 ; 8C4F A4 98 ..
+ lda sprite_list+128,y ; 8C51 B9 6B 0B .k.
+ tax ; 8C54 AA .
+ lda sprite_list,x ; 8C55 BD EB 0A ...
+ beq L8C33 ; 8C58 F0 D9 ..
+ lda sprite_list+3,x ; 8C5A BD EE 0A ...
+ cmp #$08 ; 8C5D C9 08 ..
+ bne L8C0B ; 8C5F D0 AA ..
+ lda #$10 ; 8C61 A9 10 ..
+ sta sprite_list+3,x ; 8C63 9D EE 0A ...
+ jmp kill_next ; 8C66 4C BD 8B L..
+
+; ----------------------------------------------------------------------------
+L8C69: jsr sb_kill ; 8C69 20 C3 8C ..
+ jsr get_random ; 8C6C 20 F2 8C ..
+ and #$03 ; 8C6F 29 03 ).
+ sta $E6 ; 8C71 85 E6 ..
+ sec ; 8C73 38 8
+ lda #$06 ; 8C74 A9 06 ..
+ sbc $E6 ; 8C76 E5 E6 ..
+ sta $E5 ; 8C78 85 E5 ..
+ lda $E5 ; 8C7A A5 E5 ..
+L8C7C: pha ; 8C7C 48 H
+ jsr L8C9E ; 8C7D 20 9E 8C ..
+ pla ; 8C80 68 h
+ sec ; 8C81 38 8
+ sbc #$01 ; 8C82 E9 01 ..
+ bne L8C7C ; 8C84 D0 F6 ..
+ lda $E6 ; 8C86 A5 E6 ..
+ beq L8C9B ; 8C88 F0 11 ..
+L8C8A: pha ; 8C8A 48 H
+ jsr L8D0C ; 8C8B 20 0C 8D ..
+ lda #$06 ; 8C8E A9 06 ..
+ sta current_sprite ; 8C90 85 F9 ..
+ jsr add_to_sprite_list ; 8C92 20 A5 A4 ..
+ pla ; 8C95 68 h
+ sec ; 8C96 38 8
+ sbc #$01 ; 8C97 E9 01 ..
+ bne L8C8A ; 8C99 D0 EF ..
+L8C9B: jmp kill_next ; 8C9B 4C BD 8B L..
+
+; ----------------------------------------------------------------------------
+L8C9E: lda #$06 ; 8C9E A9 06 ..
+ jsr add_points ; 8CA0 20 B2 A7 ..
+ jsr get_random ; 8CA3 20 F2 8C ..
+ and #$0F ; 8CA6 29 0F ).
+ sbc #$07 ; 8CA8 E9 07 ..
+ clc ; 8CAA 18 .
+ adc $C9 ; 8CAB 65 C9 e.
+ sta $C9 ; 8CAD 85 C9 ..
+ jsr get_random ; 8CAF 20 F2 8C ..
+ and #$0F ; 8CB2 29 0F ).
+ sbc #$07 ; 8CB4 E9 07 ..
+ clc ; 8CB6 18 .
+ adc $CA ; 8CB7 65 CA e.
+ sta $CA ; 8CB9 85 CA ..
+ lda #$01 ; 8CBB A9 01 ..
+ sta $CB ; 8CBD 85 CB ..
+ jsr start_enemy_explosion ; 8CBF 20 E7 9B ..
+ rts ; 8CC2 60 `
+
+; ----------------------------------------------------------------------------
+; kill one enemy
+sb_kill:ldy $98 ; 8CC3 A4 98 ..
+ lda #$00 ; 8CC5 A9 00 ..
+ sta sprite_list,y ; 8CC7 99 EB 0A ...
+ lda #$80 ; 8CCA A9 80 ..
+ sta sprite_list+2,y ; 8CCC 99 ED 0A ...
+ jsr erase_scanner_sprite ; 8CCF 20 2D A1 -.
+ jsr erase_sprite_XXX ; 8CD2 20 86 A7 ..
+ lda sprite_x ; 8CD5 A5 E3 ..
+ clc ; 8CD7 18 .
+ adc #$07 ; 8CD8 69 07 i.
+ sta sprite_x ; 8CDA 85 E3 ..
+ jsr erase_sprite ; 8CDC 20 2C AB ,.
+ lda sprite_x ; 8CDF A5 E3 ..
+ sta $C9 ; 8CE1 85 C9 ..
+ lda sprite_y ; 8CE3 A5 DF ..
+ sta $CA ; 8CE5 85 CA ..
+ lda #$01 ; 8CE7 A9 01 ..
+ sta $CB ; 8CE9 85 CB ..
+ jsr start_enemy_explosion ; 8CEB 20 E7 9B ..
+ jsr add_cursprite_points ; 8CEE 20 AE A7 ..
+ rts ; 8CF1 60 `
+
+; ----------------------------------------------------------------------------
+; variant of an LFSR. could have just use 'lda RANDOM', this is likely an artifact of Baker's Apple II heritage. Returns 'random' number in A.
+get_random:
+ clc ; 8CF2 18 .
+ lda random_seed ; 8CF3 A5 C6 ..
+ adc random_seed+1 ; 8CF5 65 C7 e.
+ adc random_seed+2 ; 8CF7 65 C8 e.
+ pha ; 8CF9 48 H
+ lda random_seed+1 ; 8CFA A5 C7 ..
+ sta random_seed ; 8CFC 85 C6 ..
+ lda random_seed+2 ; 8CFE A5 C8 ..
+ sta random_seed+1 ; 8D00 85 C7 ..
+ pla ; 8D02 68 h
+ sta random_seed+2 ; 8D03 85 C8 ..
+ ror random_seed+2 ; 8D05 66 C8 f.
+ ror random_seed+1 ; 8D07 66 C7 f.
+ ror random_seed ; 8D09 66 C6 f.
+ rts ; 8D0B 60 `
+
+; ----------------------------------------------------------------------------
+L8D0C: jsr get_random ; 8D0C 20 F2 8C ..
+ and #$FE ; 8D0F 29 FE ).
+ sta $DD ; 8D11 85 DD ..
+ lda random_seed+1 ; 8D13 A5 C7 ..
+ and #$01 ; 8D15 29 01 ).
+ sta $DE ; 8D17 85 DE ..
+ eor $92 ; 8D19 45 92 E.
+ beq L8D0C ; 8D1B F0 EF ..
+ jsr get_random ; 8D1D 20 F2 8C ..
+ and #$1F ; 8D20 29 1F ).
+ adc #$30 ; 8D22 69 30 i0
+ sta sprite_y ; 8D24 85 DF ..
+ rts ; 8D26 60 `
+
+; ----------------------------------------------------------------------------
+; this is for 'event' sounds like explosions, not the 'drone' nor the engine noise
+update_sound:
+ inc cur_sound_timer ; 8D27 E6 B6 ..
+ lda cur_sound_timer ; 8D29 A5 B6 ..
+ and cur_sound_tempo ; 8D2B 25 B4 %.
+ bne us_ok ; 8D2D D0 04 ..
+ inc sound_offset ; 8D2F E6 B1 ..
+ inc sound_offset ; 8D31 E6 B1 ..
+us_ok: ldy sound_offset ; 8D33 A4 B1 ..
+ lda (sound_ptr),y ; 8D35 B1 B2 ..
+ sta AUDF1 ; 8D37 8D 00 D2 ...
+ iny ; 8D3A C8 .
+ lda (sound_ptr),y ; 8D3B B1 B2 ..
+ sta AUDC1 ; 8D3D 8D 01 D2 ...
+ and #$0F ; 8D40 29 0F ).
+ bne us_done ; 8D42 D0 06 ..
+ jsr play_silence ; 8D44 20 68 8D h.
+ jsr ram_self_destruct_1 ; 8D47 20 7F B4 ..
+us_done:rts ; 8D4A 60 `
+
+; ----------------------------------------------------------------------------
+; play the sound pointed to by Y:A (lsb:msb), if another sound isn't already in progress (X is a priority I think)
+play_event_sound:
+ cpx sound_priority ; 8D4B E4 B7 ..
+ bcs priority_ok ; 8D4D B0 0A ..
+ pha ; 8D4F 48 H
+ lda sound_offset ; 8D50 A5 B1 ..
+ cmp #$20 ; 8D52 C9 20 .
+ bcs sound_not_busy ; 8D54 B0 02 ..
+ pla ; 8D56 68 h
+ rts ; 8D57 60 `
+
+; ----------------------------------------------------------------------------
+sound_not_busy:
+ pla ; 8D58 68 h
+priority_ok:
+ stx sound_priority ; 8D59 86 B7 ..
+ sta sound_ptr+1 ; 8D5B 85 B3 ..
+ sty sound_ptr ; 8D5D 84 B2 ..
+ lda #$00 ; 8D5F A9 00 ..
+ sta sound_offset ; 8D61 85 B1 ..
+ lda sound_tempo ; 8D63 A5 B5 ..
+ sta cur_sound_tempo ; 8D65 85 B4 ..
+ rts ; 8D67 60 `
+
+; ----------------------------------------------------------------------------
+play_silence:
+ lda #$00 ; 8D68 A9 00 ..
+ sta sound_priority ; 8D6A 85 B7 ..
+ lda #$01 ; 8D6C A9 01 ..
+ sta sound_tempo ; 8D6E 85 B5 ..
+ tax ; 8D70 AA .
+ lda #$8E ; 8D71 A9 8E ..
+ ldy #$86 ; 8D73 A0 86 ..
+ jsr play_event_sound ; 8D75 20 4B 8D K.
+ rts ; 8D78 60 `
+
+; ----------------------------------------------------------------------------
+; start the drone sound you hear at the title screen & when starting/ending a level. Also silence channel 2 (the engine noise). In BASIC this would be: SOUND 1,0,0,0:SOUND 2,255,10,15:SOUND 3,254,10,15
+init_drone:
+ lda #$FF ; 8D79 A9 FF ..
+ sta AUDF3 ; 8D7B 8D 04 D2 ...
+ lda #$FE ; 8D7E A9 FE ..
+ sta AUDF4 ; 8D80 8D 06 D2 ...
+ lda #$AF ; 8D83 A9 AF ..
+ sta AUDC3 ; 8D85 8D 05 D2 ...
+ sta AUDC4 ; 8D88 8D 07 D2 ...
+ lda #$1F ; 8D8B A9 1F ..
+ sta drone_volume ; 8D8D 85 BD ..
+ lda #$00 ; 8D8F A9 00 ..
+ sta AUDF2 ; 8D91 8D 02 D2 ...
+ sta AUDC2 ; 8D94 8D 03 D2 ...
+ rts ; 8D97 60 `
+
+; ----------------------------------------------------------------------------
+play_player_fire:
+ ldx #$03 ; 8D98 A2 03 ..
+ lda #$01 ; 8D9A A9 01 ..
+ sta sound_tempo ; 8D9C 85 B5 ..
+ lda #$8E ; 8D9E A9 8E ..
+ ldy #$8A ; 8DA0 A0 8A ..
+ jsr play_event_sound ; 8DA2 20 4B 8D K.
+ rts ; 8DA5 60 `
+
+; ----------------------------------------------------------------------------
+play_swarmer_died:
+ ldx #$05 ; 8DA6 A2 05 ..
+ lda #$00 ; 8DA8 A9 00 ..
+ sta sound_tempo ; 8DAA 85 B5 ..
+ lda #$91 ; 8DAC A9 91 ..
+ ldy #$20 ; 8DAE A0 20 .
+ jsr play_event_sound ; 8DB0 20 4B 8D K.
+ rts ; 8DB3 60 `
+
+; ----------------------------------------------------------------------------
+play_lander_died:
+ ldx #$05 ; 8DB4 A2 05 ..
+ lda #$00 ; 8DB6 A9 00 ..
+ sta sound_tempo ; 8DB8 85 B5 ..
+ lda #$90 ; 8DBA A9 90 ..
+ ldy #$DA ; 8DBC A0 DA ..
+ jsr play_event_sound ; 8DBE 20 4B 8D K.
+ rts ; 8DC1 60 `
+
+; ----------------------------------------------------------------------------
+play_baiter_died:
+ ldx #$05 ; 8DC2 A2 05 ..
+ lda #$00 ; 8DC4 A9 00 ..
+ sta sound_tempo ; 8DC6 85 B5 ..
+ lda #$91 ; 8DC8 A9 91 ..
+ ldy #$AC ; 8DCA A0 AC ..
+ jsr play_event_sound ; 8DCC 20 4B 8D K.
+ rts ; 8DCF 60 `
+
+; ----------------------------------------------------------------------------
+play_pod_died:
+ ldx #$1E ; 8DD0 A2 1E ..
+ lda #$01 ; 8DD2 A9 01 ..
+ sta sound_tempo ; 8DD4 85 B5 ..
+ lda #$92 ; 8DD6 A9 92 ..
+ ldy #$08 ; 8DD8 A0 08 ..
+ jsr play_event_sound ; 8DDA 20 4B 8D K.
+ rts ; 8DDD 60 `
+
+; ----------------------------------------------------------------------------
+play_mutant_taunt:
+ ldx #$0A ; 8DDE A2 0A ..
+ lda #$01 ; 8DE0 A9 01 ..
+ sta sound_tempo ; 8DE2 85 B5 ..
+ lda #$90 ; 8DE4 A9 90 ..
+ ldy #$6A ; 8DE6 A0 6A .j
+ jsr play_event_sound ; 8DE8 20 4B 8D K.
+ rts ; 8DEB 60 `
+
+; ----------------------------------------------------------------------------
+play_swarmer_taunt:
+ ldx #$0A ; 8DEC A2 0A ..
+ lda #$00 ; 8DEE A9 00 ..
+ sta sound_tempo ; 8DF0 85 B5 ..
+ lda #$90 ; 8DF2 A9 90 ..
+ ldy #$1A ; 8DF4 A0 1A ..
+ jsr play_event_sound ; 8DF6 20 4B 8D K.
+ rts ; 8DF9 60 `
+
+; ----------------------------------------------------------------------------
+play_lander_fire:
+ ldx #$0A ; 8DFA A2 0A ..
+ lda #$00 ; 8DFC A9 00 ..
+ sta sound_tempo ; 8DFE 85 B5 ..
+ lda #$90 ; 8E00 A9 90 ..
+ ldy #$60 ; 8E02 A0 60 .`
+ jsr play_event_sound ; 8E04 20 4B 8D K.
+ rts ; 8E07 60 `
+
+; ----------------------------------------------------------------------------
+play_fall:
+ ldx #$14 ; 8E08 A2 14 ..
+ lda #$01 ; 8E0A A9 01 ..
+ sta sound_tempo ; 8E0C 85 B5 ..
+ lda #$90 ; 8E0E A9 90 ..
+ ldy #$A2 ; 8E10 A0 A2 ..
+ jsr play_event_sound ; 8E12 20 4B 8D K.
+ rts ; 8E15 60 `
+
+; ----------------------------------------------------------------------------
+play_rescued:
+ ldx #$19 ; 8E16 A2 19 ..
+ lda #$01 ; 8E18 A9 01 ..
+ sta sound_tempo ; 8E1A 85 B5 ..
+ lda #$92 ; 8E1C A9 92 ..
+ ldy #$E2 ; 8E1E A0 E2 ..
+ jsr play_event_sound ; 8E20 20 4B 8D K.
+ rts ; 8E23 60 `
+
+; ----------------------------------------------------------------------------
+play_human_died:
+ ldx #$1E ; 8E24 A2 1E ..
+ lda #$01 ; 8E26 A9 01 ..
+ sta sound_tempo ; 8E28 85 B5 ..
+ lda #$92 ; 8E2A A9 92 ..
+ ldy #$B0 ; 8E2C A0 B0 ..
+ jsr play_event_sound ; 8E2E 20 4B 8D K.
+ rts ; 8E31 60 `
+
+; ----------------------------------------------------------------------------
+play_materialize:
+ ldx #$32 ; 8E32 A2 32 .2
+ lda #$01 ; 8E34 A9 01 ..
+ sta sound_tempo ; 8E36 85 B5 ..
+ lda #$8E ; 8E38 A9 8E ..
+ ldy #$CE ; 8E3A A0 CE ..
+ jsr play_event_sound ; 8E3C 20 4B 8D K.
+ rts ; 8E3F 60 `
+
+; ----------------------------------------------------------------------------
+play_distress:
+ ldx #$64 ; 8E40 A2 64 .d
+ lda #$00 ; 8E42 A9 00 ..
+ sta sound_tempo ; 8E44 85 B5 ..
+ lda #$8F ; 8E46 A9 8F ..
+ ldy #$12 ; 8E48 A0 12 ..
+ jsr play_event_sound ; 8E4A 20 4B 8D K.
+ rts ; 8E4D 60 `
+
+; ----------------------------------------------------------------------------
+play_smartbomb:
+ ldx #$7D ; 8E4E A2 7D .}
+ lda #$01 ; 8E50 A9 01 ..
+ sta sound_tempo ; 8E52 85 B5 ..
+ lda #$92 ; 8E54 A9 92 ..
+ ldy #$76 ; 8E56 A0 76 .v
+ jsr play_event_sound ; 8E58 20 4B 8D K.
+ rts ; 8E5B 60 `
+
+; ----------------------------------------------------------------------------
+play_extra_life:
+ ldx #$96 ; 8E5C A2 96 ..
+ lda #$01 ; 8E5E A9 01 ..
+ sta sound_tempo ; 8E60 85 B5 ..
+ lda #$8F ; 8E62 A9 8F ..
+ ldy #$DC ; 8E64 A0 DC ..
+ jsr play_event_sound ; 8E66 20 4B 8D K.
+ rts ; 8E69 60 `
+
+; ----------------------------------------------------------------------------
+play_ship_died:
+ ldx #$C8 ; 8E6A A2 C8 ..
+ lda #$01 ; 8E6C A9 01 ..
+ sta sound_tempo ; 8E6E 85 B5 ..
+ lda #$91 ; 8E70 A9 91 ..
+ ldy #$66 ; 8E72 A0 66 .f
+ jsr play_event_sound ; 8E74 20 4B 8D K.
+ rts ; 8E77 60 `
+
+; ----------------------------------------------------------------------------
+play_planet_explode:
+ ldx #$C8 ; 8E78 A2 C8 ..
+ lda #$01 ; 8E7A A9 01 ..
+ sta sound_tempo ; 8E7C 85 B5 ..
+ lda #$93 ; 8E7E A9 93 ..
+ ldy #$52 ; 8E80 A0 52 .R
+ jsr play_event_sound ; 8E82 20 4B 8D K.
+ rts ; 8E85 60 `
+
+; ----------------------------------------------------------------------------
+; 'heard' during title screen, and when nothing else is going on
+snd_silence:
+ .byte $00,$00,$00,$00 ; 8E86 00 00 00 00 ....
+; heard when player fires a shot
+snd_player_fire:
+ .byte $13,$8C,$12,$8C,$11,$8C,$11,$8C ; 8E8A 13 8C 12 8C 11 8C 11 8C ........
+ .byte $12,$8C,$13,$8C,$14,$8C,$15,$8C ; 8E92 12 8C 13 8C 14 8C 15 8C ........
+ .byte $16,$8C,$17,$8C,$18,$8C,$18,$8C ; 8E9A 16 8C 17 8C 18 8C 18 8C ........
+ .byte $19,$8C,$19,$8C,$1A,$8C,$1A,$8C ; 8EA2 19 8C 19 8C 1A 8C 1A 8C ........
+ .byte $1B,$8C,$1B,$8C,$1B,$8C,$1C,$8C ; 8EAA 1B 8C 1B 8C 1B 8C 1C 8C ........
+ .byte $1C,$8C,$1C,$8C,$1D,$8C,$1D,$8C ; 8EB2 1C 8C 1C 8C 1D 8C 1D 8C ........
+ .byte $1D,$8C,$1D,$8C,$1E,$8C,$1E,$8C ; 8EBA 1D 8C 1D 8C 1E 8C 1E 8C ........
+ .byte $1E,$8C,$1E,$8C,$1F,$8C,$1F,$8C ; 8EC2 1E 8C 1E 8C 1F 8C 1F 8C ........
+ .byte $1F,$8C,$1F,$80 ; 8ECA 1F 8C 1F 80 ....
+; heard when player ship appears (start of level) or the next group of aliens appears
+snd_materialize:
+ .byte $1F,$8F,$1F,$8F,$1F,$8F,$1F,$8F ; 8ECE 1F 8F 1F 8F 1F 8F 1F 8F ........
+ .byte $1E,$8F,$1E,$8F,$1E,$8F,$1E,$8F ; 8ED6 1E 8F 1E 8F 1E 8F 1E 8F ........
+ .byte $1D,$8F,$1D,$8F,$1D,$8F,$1D,$8F ; 8EDE 1D 8F 1D 8F 1D 8F 1D 8F ........
+ .byte $1C,$8F,$1C,$8F,$1C,$8F,$1B,$8F ; 8EE6 1C 8F 1C 8F 1C 8F 1B 8F ........
+ .byte $1B,$8F,$1B,$8F,$1A,$8F,$1A,$8F ; 8EEE 1B 8F 1B 8F 1A 8F 1A 8F ........
+ .byte $19,$8F,$19,$8F,$18,$8F,$18,$8F ; 8EF6 19 8F 19 8F 18 8F 18 8F ........
+ .byte $17,$8F,$16,$8F,$15,$8F,$14,$8F ; 8EFE 17 8F 16 8F 15 8F 14 8F ........
+ .byte $12,$8F,$11,$8F,$10,$8F,$0E,$8F ; 8F06 12 8F 11 8F 10 8F 0E 8F ........
+ .byte $0D,$8F,$0C,$80 ; 8F0E 0D 8F 0C 80 ....
+; heard when lander picks up a humanoid
+snd_distress:
+ .byte $0C,$AF,$0D,$AF,$0C,$AF,$0D,$AF ; 8F12 0C AF 0D AF 0C AF 0D AF ........
+ .byte $01,$AB,$01,$AB,$0F,$AB,$10,$AB ; 8F1A 01 AB 01 AB 0F AB 10 AB ........
+ .byte $0F,$AB,$10,$AB,$0F,$AB,$10,$AB ; 8F22 0F AB 10 AB 0F AB 10 AB ........
+ .byte $01,$AB,$01,$AB,$0C,$AB,$0D,$AB ; 8F2A 01 AB 01 AB 0C AB 0D AB ........
+ .byte $0F,$AB,$10,$AB,$0C,$AB,$0D,$AB ; 8F32 0F AB 10 AB 0C AB 0D AB ........
+ .byte $0F,$AB,$10,$AB,$0C,$AB,$0D,$AB ; 8F3A 0F AB 10 AB 0C AB 0D AB ........
+ .byte $0E,$AB,$0F,$AB,$0C,$AB,$0D,$AB ; 8F42 0E AB 0F AB 0C AB 0D AB ........
+ .byte $0F,$AB,$10,$AB,$0C,$AB,$0D,$AB ; 8F4A 0F AB 10 AB 0C AB 0D AB ........
+ .byte $0E,$AB,$0F,$AB,$0E,$AB,$0D,$AA ; 8F52 0E AB 0F AB 0E AB 0D AA ........
+ .byte $0C,$A9,$0D,$A8,$0E,$A7,$0D,$A6 ; 8F5A 0C A9 0D A8 0E A7 0D A6 ........
+ .byte $0C,$A5,$0D,$A4,$0C,$A3,$0D,$A2 ; 8F62 0C A5 0D A4 0C A3 0D A2 ........
+ .byte $0C,$A1,$0D,$A0,$FF ; 8F6A 0C A1 0D A0 FF .....
+; this is in the middle of the sound effects, but it doesn't look like sound data (and doesn't sound like it either)
+table_8f6f:
+ .byte $AF,$FF,$AF,$FF,$AF,$FF,$AF,$FF ; 8F6F AF FF AF FF AF FF AF FF ........
+ .byte $AF,$FF,$AF,$FF,$AE,$FF,$AE,$FF ; 8F77 AF FF AF FF AE FF AE FF ........
+ .byte $AE,$FF,$AE,$FF,$AF,$FF,$AF,$FF ; 8F7F AE FF AE FF AF FF AF FF ........
+ .byte $AF,$FF,$AF,$FF,$AF,$FF,$AF,$FF ; 8F87 AF FF AF FF AF FF AF FF ........
+ .byte $AE,$FF,$AE,$FF,$AE,$FF,$AE,$FF ; 8F8F AE FF AE FF AE FF AE FF ........
+ .byte $AF,$FF,$AF,$FF,$AF,$FF,$AF,$FF ; 8F97 AF FF AF FF AF FF AF FF ........
+ .byte $AF,$FF,$AF,$FF,$AE,$FF,$AE,$FF ; 8F9F AF FF AF FF AE FF AE FF ........
+ .byte $AE,$FF,$AE,$FF,$AF,$FF,$AF,$FF ; 8FA7 AE FF AE FF AF FF AF FF ........
+ .byte $AF,$FF,$AF,$FF,$AF,$FF,$AF,$FF ; 8FAF AF FF AF FF AF FF AF FF ........
+ .byte $AE,$FF,$AE,$FF,$AE,$FF,$AE,$FF ; 8FB7 AE FF AE FF AE FF AE FF ........
+ .byte $AD,$FF,$AD,$FF,$AD,$FF,$AC,$FF ; 8FBF AD FF AD FF AD FF AC FF ........
+ .byte $AC,$FF,$AC,$FF,$AB,$FF,$AB,$FF ; 8FC7 AC FF AC FF AB FF AB FF ........
+ .byte $AA,$FF,$AA,$FF,$A9,$FF,$A8,$FF ; 8FCF AA FF AA FF A9 FF A8 FF ........
+ .byte $A7,$FF,$A6,$FF,$A0 ; 8FD7 A7 FF A6 FF A0 .....
+; heard when player gets an extra life
+snd_extra_life:
+ .byte $28,$6F,$39,$6F,$12,$6F,$11,$6F ; 8FDC 28 6F 39 6F 12 6F 11 6F (o9o.o.o
+ .byte $10,$6F,$0F,$6F,$28,$6F,$39,$6F ; 8FE4 10 6F 0F 6F 28 6F 39 6F .o.o(o9o
+ .byte $0E,$6F,$0D,$6F,$0C,$6F,$0B,$6F ; 8FEC 0E 6F 0D 6F 0C 6F 0B 6F .o.o.o.o
+ .byte $28,$6F,$39,$6F,$0A,$6F,$09,$6F ; 8FF4 28 6F 39 6F 0A 6F 09 6F (o9o.o.o
+ .byte $08,$6F,$07,$6F,$28,$6E,$39,$6D ; 8FFC 08 6F 07 6F 28 6E 39 6D .o.o(n9m
+ .byte $08,$6C,$07,$6B,$06,$6A,$05,$69 ; 9004 08 6C 07 6B 06 6A 05 69 .l.k.j.i
+ .byte $28,$68,$39,$67,$04,$66,$03,$65 ; 900C 28 68 39 67 04 66 03 65 (h9g.f.e
+ .byte $02,$64,$01,$63,$01,$60 ; 9014 02 64 01 63 01 60 .d.c.`
+; heard when swarmers are in the area (like a bird call)
+snd_swarmer_taunt:
+ .byte $17,$AF,$18,$AF,$19,$AF,$1A,$AF ; 901A 17 AF 18 AF 19 AF 1A AF ........
+ .byte $1B,$AF,$1C,$A1,$1C,$A1,$17,$AF ; 9022 1B AF 1C A1 1C A1 17 AF ........
+ .byte $18,$AF,$19,$AF,$1A,$AF,$1B,$AF ; 902A 18 AF 19 AF 1A AF 1B AF ........
+ .byte $1C,$A1,$1C,$A1,$17,$AF,$18,$AF ; 9032 1C A1 1C A1 17 AF 18 AF ........
+ .byte $19,$AF,$1A,$AF,$1B,$AF,$1C,$A1 ; 903A 19 AF 1A AF 1B AF 1C A1 ........
+ .byte $1C,$A1,$17,$AF,$18,$AF,$19,$AF ; 9042 1C A1 17 AF 18 AF 19 AF ........
+ .byte $1A,$AF,$1B,$AF,$1C,$A1,$1C,$A1 ; 904A 1A AF 1B AF 1C A1 1C A1 ........
+ .byte $17,$AF,$18,$AF,$19,$AF,$1A,$AF ; 9052 17 AF 18 AF 19 AF 1A AF ........
+ .byte $1B,$AF,$1C,$A1,$1C,$A0 ; 905A 1B AF 1C A1 1C A0 ......
+; heard when a lander fires a shot
+snd_lander_fire:
+ .byte $04,$6F,$05,$6F,$06,$6F,$07,$6F ; 9060 04 6F 05 6F 06 6F 07 6F .o.o.o.o
+ .byte $09,$60 ; 9068 09 60 .`
+; heard when a mutant is after you
+snd_mutant_taunt:
+ .byte $06,$6F,$05,$6F,$06,$6F,$07,$6F ; 906A 06 6F 05 6F 06 6F 07 6F .o.o.o.o
+ .byte $08,$6F,$09,$6F,$0A,$6F,$0B,$6F ; 9072 08 6F 09 6F 0A 6F 0B 6F .o.o.o.o
+ .byte $0C,$6F,$0D,$6F,$0E,$6F,$0F,$6F ; 907A 0C 6F 0D 6F 0E 6F 0F 6F .o.o.o.o
+ .byte $10,$6F,$11,$6F,$12,$6F,$13,$6F ; 9082 10 6F 11 6F 12 6F 13 6F .o.o.o.o
+ .byte $14,$6F,$15,$6E,$16,$6D,$17,$6C ; 908A 14 6F 15 6E 16 6D 17 6C .o.n.m.l
+ .byte $18,$6B,$19,$6A,$1A,$69,$1B,$68 ; 9092 18 6B 19 6A 1A 69 1B 68 .k.j.i.h
+ .byte $1C,$67,$1D,$66,$1E,$65,$1F,$60 ; 909A 1C 67 1D 66 1E 65 1F 60 .g.f.e.`
+; heard when a lander carrying a human is shot
+snd_fall:
+ .byte $06,$CF,$05,$CF,$06,$CF,$07,$CF ; 90A2 06 CF 05 CF 06 CF 07 CF ........
+ .byte $08,$CF,$09,$CF,$0A,$CF,$0B,$CF ; 90AA 08 CF 09 CF 0A CF 0B CF ........
+ .byte $0C,$CF,$0D,$CF,$0E,$CF,$0F,$CF ; 90B2 0C CF 0D CF 0E CF 0F CF ........
+ .byte $10,$CF,$11,$CF,$12,$CF,$13,$CF ; 90BA 10 CF 11 CF 12 CF 13 CF ........
+ .byte $14,$CF,$15,$CE,$16,$CD,$17,$CC ; 90C2 14 CF 15 CE 16 CD 17 CC ........
+ .byte $18,$CB,$19,$CA,$1A,$C9,$1B,$C8 ; 90CA 18 CB 19 CA 1A C9 1B C8 ........
+ .byte $1C,$C7,$1D,$C6,$1E,$C5,$1F,$C0 ; 90D2 1C C7 1D C6 1E C5 1F C0 ........
+; heard when we shoot a lander (or a bomber, same sound)
+snd_lander_died:
+ .byte $EB,$AF,$FE,$AF,$00,$A1,$00,$A1 ; 90DA EB AF FE AF 00 A1 00 A1 ........
+ .byte $00,$A1,$00,$A1,$00,$A1,$00,$A1 ; 90E2 00 A1 00 A1 00 A1 00 A1 ........
+ .byte $EB,$AE,$FE,$AE,$00,$A1,$00,$A1 ; 90EA EB AE FE AE 00 A1 00 A1 ........
+ .byte $00,$A1,$00,$A1,$00,$A1,$00,$A1 ; 90F2 00 A1 00 A1 00 A1 00 A1 ........
+ .byte $EB,$AA,$FE,$AA,$00,$A1,$00,$A1 ; 90FA EB AA FE AA 00 A1 00 A1 ........
+ .byte $00,$A1,$00,$A1,$00,$A1,$00,$A1 ; 9102 00 A1 00 A1 00 A1 00 A1 ........
+ .byte $EB,$A5,$FE,$A5,$00,$A1,$00,$A1 ; 910A EB A5 FE A5 00 A1 00 A1 ........
+ .byte $00,$A1,$00,$A1,$00,$A1,$00,$A1 ; 9112 00 A1 00 A1 00 A1 00 A1 ........
+ .byte $EB,$A2,$FE,$A2,$00,$A0 ; 911A EB A2 FE A2 00 A0 ......
+; heard when a swarmer is shot
+snd_swarmer_died:
+ .byte $EB,$8F,$FE,$8F,$00,$81,$00,$81 ; 9120 EB 8F FE 8F 00 81 00 81 ........
+ .byte $00,$81,$00,$81,$00,$81,$00,$81 ; 9128 00 81 00 81 00 81 00 81 ........
+ .byte $EB,$8E,$FE,$8E,$00,$81,$00,$81 ; 9130 EB 8E FE 8E 00 81 00 81 ........
+ .byte $00,$81,$00,$81,$00,$81,$00,$81 ; 9138 00 81 00 81 00 81 00 81 ........
+ .byte $EB,$8A,$FE,$8A,$00,$81,$00,$81 ; 9140 EB 8A FE 8A 00 81 00 81 ........
+ .byte $00,$81,$00,$81,$00,$81,$00,$81 ; 9148 00 81 00 81 00 81 00 81 ........
+ .byte $EB,$87,$FE,$87,$00,$81,$00,$81 ; 9150 EB 87 FE 87 00 81 00 81 ........
+ .byte $00,$81,$00,$81,$00,$81,$00,$81 ; 9158 00 81 00 81 00 81 00 81 ........
+ .byte $EB,$85,$FE,$85,$00,$80 ; 9160 EB 85 FE 85 00 80 ......
+; heard when the player's ship explodes
+snd_player_died:
+ .byte $0B,$8C,$0F,$86,$13,$8F,$17,$8F ; 9166 0B 8C 0F 86 13 8F 17 8F ........
+ .byte $18,$86,$19,$8A,$17,$8A,$1B,$85 ; 916E 18 86 19 8A 17 8A 1B 85 ........
+ .byte $1B,$8C,$1C,$89,$1C,$8A,$1A,$8C ; 9176 1B 8C 1C 89 1C 8A 1A 8C ........
+ .byte $1D,$85,$1A,$8E,$1D,$8A,$1D,$87 ; 917E 1D 85 1A 8E 1D 8A 1D 87 ........
+ .byte $1E,$81,$19,$85,$1E,$89,$1E,$81 ; 9186 1E 81 19 85 1E 89 1E 81 ........
+ .byte $1E,$87,$1E,$86,$1F,$81,$1E,$86 ; 918E 1E 87 1E 86 1F 81 1E 86 ........
+ .byte $01,$81,$1F,$85,$1D,$85,$1F,$85 ; 9196 01 81 1F 85 1D 85 1F 85 ........
+ .byte $1F,$85,$1F,$85,$1F,$85,$01,$81 ; 919E 1F 85 1F 85 1F 85 01 81 ........
+ .byte $20,$84,$20,$81,$20,$80 ; 91A6 20 84 20 81 20 80 . . .
+; heard when a baiter is shot (temporary reprieve!)
+snd_baiter_died:
+ .byte $6C,$6F,$6C,$61,$66,$61,$66,$61 ; 91AC 6C 6F 6C 61 66 61 66 61 lolafafa
+ .byte $60,$61,$60,$61,$5B,$61,$5B,$61 ; 91B4 60 61 60 61 5B 61 5B 61 `a`a[a[a
+ .byte $55,$6F,$55,$61,$51,$61,$51,$61 ; 91BC 55 6F 55 61 51 61 51 61 UoUaQaQa
+ .byte $4C,$61,$4C,$61,$48,$61,$48,$61 ; 91C4 4C 61 4C 61 48 61 48 61 LaLaHaHa
+ .byte $44,$6F,$44,$61,$40,$61,$40,$61 ; 91CC 44 6F 44 61 40 61 40 61 DoDa@a@a
+ .byte $3C,$61,$3C,$61,$39,$6D,$39,$61 ; 91D4 3C 61 3C 61 39 6D 39 61 <a<a9m9a
+ .byte $35,$61,$35,$61,$32,$61,$32,$61 ; 91DC 35 61 35 61 32 61 32 61 5a5a2a2a
+ .byte $2F,$6A,$2F,$61,$2D,$61,$2D,$61 ; 91E4 2F 6A 2F 61 2D 61 2D 61 /j/a-a-a
+ .byte $2A,$61,$2A,$68,$28,$61,$28,$61 ; 91EC 2A 61 2A 68 28 61 28 61 *a*h(a(a
+ .byte $25,$61,$25,$66,$23,$61,$23,$61 ; 91F4 25 61 25 66 23 61 23 61 %a%f#a#a
+ .byte $21,$64,$21,$61,$1F,$63,$1F,$61 ; 91FC 21 64 21 61 1F 63 1F 61 !d!a.c.a
+ .byte $1D,$62,$1D,$60 ; 9204 1D 62 1D 60 .b.`
+; heard when a pod is killed and spawns a bunch of swarmers
+snd_pod_died:
+ .byte $51,$A9,$E5,$AA,$51,$AB,$E5,$AC ; 9208 51 A9 E5 AA 51 AB E5 AC Q...Q...
+ .byte $51,$AC,$E5,$AC,$51,$AC,$E5,$AB ; 9210 51 AC E5 AC 51 AC E5 AB Q...Q...
+ .byte $51,$AA,$E5,$A9,$51,$A9,$E5,$A9 ; 9218 51 AA E5 A9 51 A9 E5 A9 Q...Q...
+ .byte $51,$AA,$E5,$AB,$51,$AB,$E5,$AB ; 9220 51 AA E5 AB 51 AB E5 AB Q...Q...
+ .byte $51,$AB,$E5,$AA,$51,$A9,$E5,$A8 ; 9228 51 AB E5 AA 51 A9 E5 A8 Q...Q...
+ .byte $51,$A8,$E5,$A8,$51,$A9,$E5,$AA ; 9230 51 A8 E5 A8 51 A9 E5 AA Q...Q...
+ .byte $51,$AA,$E5,$AA,$51,$AA,$E5,$A9 ; 9238 51 AA E5 AA 51 AA E5 A9 Q...Q...
+ .byte $51,$A8,$E5,$A7,$51,$A7,$E5,$A7 ; 9240 51 A8 E5 A7 51 A7 E5 A7 Q...Q...
+ .byte $51,$A8,$E5,$A9,$51,$A9,$E5,$A9 ; 9248 51 A8 E5 A9 51 A9 E5 A9 Q...Q...
+ .byte $51,$A9,$E5,$A8,$51,$A7,$E5,$A6 ; 9250 51 A9 E5 A8 51 A7 E5 A6 Q...Q...
+ .byte $51,$A6,$E5,$A6,$51,$A7,$E5,$A8 ; 9258 51 A6 E5 A6 51 A7 E5 A8 Q...Q...
+ .byte $51,$A8,$E5,$A8,$51,$A8,$E5,$A7 ; 9260 51 A8 E5 A8 51 A8 E5 A7 Q...Q...
+ .byte $51,$A6,$E5,$A5,$51,$A4,$E5,$A3 ; 9268 51 A6 E5 A5 51 A4 E5 A3 Q...Q...
+ .byte $51,$A2,$E5,$A1,$51,$A0 ; 9270 51 A2 E5 A1 51 A0 Q...Q.
+; heard when player detonates a smart bomb
+snd_smartbomb:
+ .byte $90,$CF,$90,$8F,$90,$88,$90,$85 ; 9276 90 CF 90 8F 90 88 90 85 ........
+ .byte $90,$CF,$90,$8F,$90,$88,$90,$85 ; 927E 90 CF 90 8F 90 88 90 85 ........
+ .byte $90,$CF,$90,$8F,$90,$88,$90,$85 ; 9286 90 CF 90 8F 90 88 90 85 ........
+ .byte $B6,$CF,$B6,$8F,$B6,$8E,$B6,$8D ; 928E B6 CF B6 8F B6 8E B6 8D ........
+ .byte $B6,$8C,$B6,$8B,$B6,$8A,$B6,$89 ; 9296 B6 8C B6 8B B6 8A B6 89 ........
+ .byte $B6,$88,$B6,$87,$B6,$86,$B6,$85 ; 929E B6 88 B6 87 B6 86 B6 85 ........
+ .byte $B6,$84,$B6,$83,$B6,$82,$B6,$81 ; 92A6 B6 84 B6 83 B6 82 B6 81 ........
+ .byte $B6,$80 ; 92AE B6 80 ..
+; heard when a human dies (is absorbed, shot, or falls too far)
+snd_human_died:
+ .byte $21,$8E,$21,$8E,$21,$8E,$23,$8E ; 92B0 21 8E 21 8E 21 8E 23 8E !.!.!.#.
+ .byte $28,$8E,$2D,$8E,$35,$8E,$44,$8E ; 92B8 28 8E 2D 8E 35 8E 44 8E (.-.5.D.
+ .byte $55,$8D,$60,$8D,$6C,$8D,$6C,$8D ; 92C0 55 8D 60 8D 6C 8D 6C 8D U.`.l.l.
+ .byte $6C,$8C,$72,$8B,$79,$8A,$79,$89 ; 92C8 6C 8C 72 8B 79 8A 79 89 l.r.y.y.
+ .byte $79,$88,$79,$87,$79,$86,$79,$85 ; 92D0 79 88 79 87 79 86 79 85 y.y.y.y.
+ .byte $80,$44,$80,$43,$80,$42,$80,$41 ; 92D8 80 44 80 43 80 42 80 41 .D.C.B.A
+ .byte $80,$40 ; 92E0 80 40 .@
+; heard when player catches or drops off a human, or when one lands safely on the ground
+snd_rescued:
+ .byte $88,$A8,$80,$A9,$79,$AA,$5B,$AB ; 92E2 88 A8 80 A9 79 AA 5B AB ....y.[.
+ .byte $35,$A6,$32,$A6,$2F,$A6,$88,$A8 ; 92EA 35 A6 32 A6 2F A6 88 A8 5.2./...
+ .byte $80,$A9,$79,$AA,$5B,$AB,$35,$A6 ; 92F2 80 A9 79 AA 5B AB 35 A6 ..y.[.5.
+ .byte $32,$A6,$2D,$A6,$28,$A6,$88,$A8 ; 92FA 32 A6 2D A6 28 A6 88 A8 2.-.(...
+ .byte $80,$A9,$79,$AA,$5B,$AB,$35,$A6 ; 9302 80 A9 79 AA 5B AB 35 A6 ..y.[.5.
+ .byte $32,$A6,$2D,$A6,$25,$A6,$88,$A8 ; 930A 32 A6 2D A6 25 A6 88 A8 2.-.%...
+ .byte $80,$A9,$79,$AA,$5B,$AB,$35,$A6 ; 9312 80 A9 79 AA 5B AB 35 A6 ..y.[.5.
+ .byte $32,$A6,$2A,$A6,$23,$A6,$88,$A8 ; 931A 32 A6 2A A6 23 A6 88 A8 2.*.#...
+ .byte $80,$A9,$79,$AA,$5B,$AB,$35,$A6 ; 9322 80 A9 79 AA 5B AB 35 A6 ..y.[.5.
+ .byte $32,$A6,$28,$A6,$21,$A6,$88,$A8 ; 932A 32 A6 28 A6 21 A6 88 A8 2.(.!...
+ .byte $80,$A9,$79,$AA,$5B,$AB,$35,$A6 ; 9332 80 A9 79 AA 5B AB 35 A6 ..y.[.5.
+ .byte $32,$A6,$25,$A6,$1F,$A6,$88,$A8 ; 933A 32 A6 25 A6 1F A6 88 A8 2.%.....
+ .byte $80,$A9,$79,$AA,$5B,$AB,$35,$A6 ; 9342 80 A9 79 AA 5B AB 35 A6 ..y.[.5.
+ .byte $32,$A6,$23,$A6,$1D,$A6,$88,$A0 ; 934A 32 A6 23 A6 1D A6 88 A0 2.#.....
+; heard when the last human dies and the planet asplodes
+snd_planet_explode:
+ .byte $16,$8F,$17,$8F,$18,$8F,$19,$8F ; 9352 16 8F 17 8F 18 8F 19 8F ........
+ .byte $16,$8F,$17,$8F,$18,$8F,$19,$8F ; 935A 16 8F 17 8F 18 8F 19 8F ........
+ .byte $1A,$8F,$16,$8F,$17,$8F,$18,$8F ; 9362 1A 8F 16 8F 17 8F 18 8F ........
+ .byte $19,$8F,$1A,$8F,$1B,$8F,$16,$8F ; 936A 19 8F 1A 8F 1B 8F 16 8F ........
+ .byte $17,$8F,$18,$8F,$19,$8F,$1A,$8F ; 9372 17 8F 18 8F 19 8F 1A 8F ........
+ .byte $1B,$8F,$1C,$8F,$16,$8F,$17,$8F ; 937A 1B 8F 1C 8F 16 8F 17 8F ........
+ .byte $18,$8F,$19,$8F,$1A,$8F,$1B,$8F ; 9382 18 8F 19 8F 1A 8F 1B 8F ........
+ .byte $1C,$8F,$1D,$8F,$1E,$8F,$16,$8F ; 938A 1C 8F 1D 8F 1E 8F 16 8F ........
+ .byte $17,$8F,$18,$8F,$19,$8F,$1A,$8F ; 9392 17 8F 18 8F 19 8F 1A 8F ........
+ .byte $1B,$8F,$1C,$8F,$1D,$8F,$1E,$8F ; 939A 1B 8F 1C 8F 1D 8F 1E 8F ........
+ .byte $1F,$8F,$16,$8F,$17,$8F,$18,$8F ; 93A2 1F 8F 16 8F 17 8F 18 8F ........
+ .byte $19,$8F,$1A,$8F,$1B,$8F,$1C,$8F ; 93AA 19 8F 1A 8F 1B 8F 1C 8F ........
+ .byte $1D,$8F,$1E,$8F,$1F,$8F,$20,$8F ; 93B2 1D 8F 1E 8F 1F 8F 20 8F ...... .
+ .byte $20,$80 ; 93BA 20 80 .
+; ----------------------------------------------------------------------------
+; flash the score of the current player
+flash_score:
+ lda #$01 ; 93BC A9 01 ..
+ sta cursor_x ; 93BE 8D 39 14 .9.
+ lda players ; 93C1 A5 E2 ..
+ cmp #$01 ; 93C3 C9 01 ..
+ beq L93D2 ; 93C5 F0 0B ..
+ lda current_player ; 93C7 A5 F1 ..
+ cmp #$01 ; 93C9 C9 01 ..
+ beq L93D2 ; 93CB F0 05 ..
+ lda #$20 ; 93CD A9 20 .
+ sta cursor_x ; 93CF 8D 39 14 .9.
+L93D2: lda #$02 ; 93D2 A9 02 ..
+ sta cursor_y ; 93D4 8D 3A 14 .:.
+ ldy #$07 ; 93D7 A0 07 ..
+L93D9: lda #$A0 ; 93D9 A9 A0 ..
+ jsr printchar ; 93DB 20 2E 97 ..
+ dey ; 93DE 88 .
+ bne L93D9 ; 93DF D0 F8 ..
+L93E1: rts ; 93E1 60 `
+
+; ----------------------------------------------------------------------------
+L93E2: lda #$01 ; 93E2 A9 01 ..
+ sta cursor_x ; 93E4 8D 39 14 .9.
+ lda players ; 93E7 A5 E2 ..
+ cmp #$01 ; 93E9 C9 01 ..
+ beq L93E1 ; 93EB F0 F4 ..
+ lda current_player ; 93ED A5 F1 ..
+ cmp #$01 ; 93EF C9 01 ..
+ bne L93F8 ; 93F1 D0 05 ..
+ lda #$20 ; 93F3 A9 20 .
+ sta cursor_x ; 93F5 8D 39 14 .9.
+L93F8: lda #$02 ; 93F8 A9 02 ..
+ sta cursor_y ; 93FA 8D 3A 14 .:.
+ lda #$FF ; 93FD A9 FF ..
+ sta glyph_color_mask ; 93FF 85 EE ..
+ lsr $0510 ; 9401 4E 10 05 N..
+ lda current_player ; 9404 A5 F1 ..
+ cmp #$01 ; 9406 C9 01 ..
+ beq L9426 ; 9408 F0 1C ..
+ lda p1_sav_score+3 ; 940A AD C3 17 ...
+ jsr draw_2_score_digits ; 940D 20 83 94 ..
+ lda p1_sav_score+2 ; 9410 AD C2 17 ...
+ jsr draw_2_score_digits ; 9413 20 83 94 ..
+ lda p1_sav_score+1 ; 9416 AD C1 17 ...
+ jsr draw_2_score_digits ; 9419 20 83 94 ..
+ sec ; 941C 38 8
+ ror $0510 ; 941D 6E 10 05 n..
+ lda p1_sav_score ; 9420 AD C0 17 ...
+ jmp draw_2_score_digits ; 9423 4C 83 94 L..
+
+; ----------------------------------------------------------------------------
+L9426: lda p2_sav_score+3 ; 9426 AD C3 19 ...
+ jsr draw_2_score_digits ; 9429 20 83 94 ..
+ lda p2_sav_score+2 ; 942C AD C2 19 ...
+ jsr draw_2_score_digits ; 942F 20 83 94 ..
+ lda p2_sav_score+1 ; 9432 AD C1 19 ...
+ jsr draw_2_score_digits ; 9435 20 83 94 ..
+ sec ; 9438 38 8
+ ror $0510 ; 9439 6E 10 05 n..
+ lda p2_sav_score ; 943C AD C0 19 ...
+ jmp draw_2_score_digits ; 943F 4C 83 94 L..
+
+; ----------------------------------------------------------------------------
+; draw score digits in the HUDs for both players (but not lives nor smartbombs)
+draw_scores:
+ lda #$01 ; 9442 A9 01 ..
+ sta cursor_x ; 9444 8D 39 14 .9.
+ lda players ; 9447 A5 E2 ..
+ cmp #$01 ; 9449 C9 01 ..
+ beq L9458 ; 944B F0 0B ..
+ lda current_player ; 944D A5 F1 ..
+ cmp #$01 ; 944F C9 01 ..
+ beq L9458 ; 9451 F0 05 ..
+ lda #$20 ; 9453 A9 20 .
+ sta cursor_x ; 9455 8D 39 14 .9.
+L9458: lda #$02 ; 9458 A9 02 ..
+ sta cursor_y ; 945A 8D 3A 14 .:.
+ lda #$FF ; 945D A9 FF ..
+ sta glyph_color_mask ; 945F 85 EE ..
+ lsr $0510 ; 9461 4E 10 05 N..
+ lda score+3 ; 9464 AD 32 14 .2.
+ jsr draw_2_score_digits ; 9467 20 83 94 ..
+ lda score+2 ; 946A AD 31 14 .1.
+ jsr draw_2_score_digits ; 946D 20 83 94 ..
+ lda score+1 ; 9470 AD 30 14 .0.
+ jsr draw_2_score_digits ; 9473 20 83 94 ..
+ sec ; 9476 38 8
+ ror $0510 ; 9477 6E 10 05 n..
+ lda score ; 947A AD 2F 14 ./.
+ jsr draw_2_score_digits ; 947D 20 83 94 ..
+ jmp L93E2 ; 9480 4C E2 93 L..
+
+; ----------------------------------------------------------------------------
+; called 4 times for the 4 bytes of score. does division by 10.
+draw_2_score_digits:
+ sta $0517 ; 9483 8D 17 05 ...
+ ldy #$01 ; 9486 A0 01 ..
+L9488: lda #$00 ; 9488 A9 00 ..
+ sta $0518 ; 948A 8D 18 05 ...
+L948D: sec ; 948D 38 8
+ lda $0517 ; 948E AD 17 05 ...
+ sbc power_10_table,y ; 9491 F9 07 95 ...
+ bcc L949E ; 9494 90 08 ..
+ sta $0517 ; 9496 8D 17 05 ...
+ inc $0518 ; 9499 EE 18 05 ...
+ bne L948D ; 949C D0 EF ..
+L949E: lda $0518 ; 949E AD 18 05 ...
+ asl a ; 94A1 0A .
+ asl a ; 94A2 0A .
+ asl a ; 94A3 0A .
+ sta glyph_offset ; 94A4 8D 16 05 ...
+ bit $0510 ; 94A7 2C 10 05 ,..
+ bmi L94B5 ; 94AA 30 09 0.
+ lda glyph_offset ; 94AC AD 16 05 ...
+ beq L94B8 ; 94AF F0 07 ..
+ sec ; 94B1 38 8
+ ror $0510 ; 94B2 6E 10 05 n..
+L94B5: jsr draw_glyph ; 94B5 20 BC 94 ..
+L94B8: dey ; 94B8 88 .
+ bpl L9488 ; 94B9 10 CD ..
+ rts ; 94BB 60 `
+
+; ----------------------------------------------------------------------------
+; draw the glyph at address (font + glyph_offset)
+draw_glyph:
+ sty y_stash ; 94BC 8C 19 05 ...
+ lda cursor_y ; 94BF AD 3A 14 .:.
+ asl a ; 94C2 0A .
+ asl a ; 94C3 0A .
+ asl a ; 94C4 0A .
+ clc ; 94C5 18 .
+ adc cursor_y ; 94C6 6D 3A 14 m:.
+ sta cursor_line ; 94C9 8D 12 05 ...
+ sta cur_line ; 94CC 8D 13 05 ...
+ clc ; 94CF 18 .
+ adc #$08 ; 94D0 69 08 i.
+ sta last_line ; 94D2 8D 14 05 ...
+dg_next_line:
+ ldy cur_line ; 94D5 AC 13 05 ...
+ lda screen_hi_ptrs,y ; 94D8 B9 00 1E ...
+ sta screen_ptr+1 ; 94DB 85 C1 ..
+ lda screen_lo_ptrs,y ; 94DD B9 00 1D ...
+ sta screen_ptr ; 94E0 85 C0 ..
+ ldx glyph_offset ; 94E2 AE 16 05 ...
+ lda font,x ; 94E5 BD 0A 95 ...
+ ldy cursor_x ; 94E8 AC 39 14 .9.
+ and glyph_color_mask ; 94EB 25 EE %.
+ sta (screen_ptr),y ; 94ED 91 C0 ..
+ inc glyph_offset ; 94EF EE 16 05 ...
+ inc cur_line ; 94F2 EE 13 05 ...
+ lda cur_line ; 94F5 AD 13 05 ...
+ cmp last_line ; 94F8 CD 14 05 ...
+ bcc dg_next_line ; 94FB 90 D8 ..
+ inc cursor_x_tmp ; 94FD EE 15 05 ...
+ inc cursor_x ; 9500 EE 39 14 .9.
+ ldy y_stash ; 9503 AC 19 05 ...
+ rts ; 9506 60 `
+
+; ----------------------------------------------------------------------------
+; 1, 10, 100 aka 10*0, 10*1, 10*2. used by draw_2_score_digits. last byte appears to never get read.
+power_10_table:
+ .byte $01,$0A,$64 ; 9507 01 0A 64 ..d
+; 13 4x8 glyphs, 0 thru 9, space, left & right halves of copyright symbol. 2bpp, but only one color used (11). really 3x8 as rightmost column is blank (for spacing) in all glyphs. height is the full 8 (no blanks for spacing).
+font: .byte $FC,$CC,$CC,$CC,$CC,$CC,$CC,$FC ; 950A FC CC CC CC CC CC CC FC ........
+ .byte $3C,$CC,$0C,$0C,$0C,$0C,$0C,$0C ; 9512 3C CC 0C 0C 0C 0C 0C 0C <.......
+ .byte $FC,$CC,$0C,$30,$30,$C0,$C0,$FC ; 951A FC CC 0C 30 30 C0 C0 FC ...00...
+ .byte $FC,$0C,$0C,$FC,$0C,$0C,$0C,$FC ; 9522 FC 0C 0C FC 0C 0C 0C FC ........
+ .byte $CC,$CC,$CC,$CC,$FC,$0C,$0C,$0C ; 952A CC CC CC CC FC 0C 0C 0C ........
+ .byte $FC,$C0,$C0,$FC,$0C,$0C,$0C,$FC ; 9532 FC C0 C0 FC 0C 0C 0C FC ........
+ .byte $FC,$C0,$C0,$FC,$CC,$CC,$CC,$FC ; 953A FC C0 C0 FC CC CC CC FC ........
+ .byte $FC,$0C,$0C,$30,$30,$C0,$C0,$C0 ; 9542 FC 0C 0C 30 30 C0 C0 C0 ...00...
+ .byte $FC,$CC,$CC,$30,$CC,$CC,$CC,$FC ; 954A FC CC CC 30 CC CC CC FC ...0....
+ .byte $FC,$CC,$CC,$CC,$FC,$0C,$0C,$FC ; 9552 FC CC CC CC FC 0C 0C FC ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; 955A 00 00 00 00 00 00 00 00 ........
+ .byte $3F,$C0,$CF,$CC,$CC,$CF,$C0,$3F ; 9562 3F C0 CF CC CC CF C0 3F ?......?
+ .byte $F0,$0C,$CC,$0C,$0C,$CC,$0C,$F0 ; 956A F0 0C CC 0C 0C CC 0C F0 ........
+; uppercase, 26 4x8 glyphs but no blank column for spacing (full 4x8). also J Q Z glyphs are graphics of some kind.
+font_letters:
+ .byte $3C,$C3,$C3,$C3,$FF,$C3,$C3,$C3 ; 9572 3C C3 C3 C3 FF C3 C3 C3 <.......
+ .byte $FC,$C3,$C3,$FC,$C3,$C3,$C3,$FC ; 957A FC C3 C3 FC C3 C3 C3 FC ........
+ .byte $3F,$C0,$C0,$C0,$C0,$C0,$C0,$3F ; 9582 3F C0 C0 C0 C0 C0 C0 3F ?......?
+ .byte $FC,$C3,$C3,$C3,$C3,$C3,$C3,$FC ; 958A FC C3 C3 C3 C3 C3 C3 FC ........
+ .byte $FF,$C0,$C0,$FF,$C0,$C0,$C0,$FF ; 9592 FF C0 C0 FF C0 C0 C0 FF ........
+ .byte $FF,$C0,$C0,$FF,$C0,$C0,$C0,$C0 ; 959A FF C0 C0 FF C0 C0 C0 C0 ........
+ .byte $3F,$C0,$C0,$CF,$C3,$C3,$C3,$3F ; 95A2 3F C0 C0 CF C3 C3 C3 3F ?......?
+ .byte $C3,$C3,$C3,$FF,$C3,$C3,$C3,$C3 ; 95AA C3 C3 C3 FF C3 C3 C3 C3 ........
+ .byte $FF,$30,$30,$30,$30,$30,$30,$FF ; 95B2 FF 30 30 30 30 30 30 FF .000000.
+ .byte $18,$18,$18,$18,$18,$19,$19,$0E ; 95BA 18 18 18 18 18 19 19 0E ........
+ .byte $C3,$C3,$CC,$FC,$CC,$C3,$C3,$C3 ; 95C2 C3 C3 CC FC CC C3 C3 C3 ........
+ .byte $C0,$C0,$C0,$C0,$C0,$C0,$C0,$FF ; 95CA C0 C0 C0 C0 C0 C0 C0 FF ........
+ .byte $C3,$FF,$F3,$C3,$C3,$C3,$C3,$C3 ; 95D2 C3 FF F3 C3 C3 C3 C3 C3 ........
+ .byte $C3,$F3,$F3,$FF,$CF,$CF,$C3,$C3 ; 95DA C3 F3 F3 FF CF CF C3 C3 ........
+ .byte $3C,$C3,$C3,$C3,$C3,$C3,$C3,$3C ; 95E2 3C C3 C3 C3 C3 C3 C3 3C <......<
+ .byte $FC,$C3,$C3,$FC,$C0,$C0,$C0,$C0 ; 95EA FC C3 C3 FC C0 C0 C0 C0 ........
+ .byte $1F,$19,$19,$19,$19,$1D,$09,$17 ; 95F2 1F 19 19 19 19 1D 09 17 ........
+ .byte $FC,$C3,$C3,$FC,$CC,$CC,$C3,$C3 ; 95FA FC C3 C3 FC CC CC C3 C3 ........
+ .byte $3F,$C0,$C0,$3C,$03,$03,$03,$FC ; 9602 3F C0 C0 3C 03 03 03 FC ?..<....
+ .byte $FF,$30,$30,$30,$30,$30,$30,$30 ; 960A FF 30 30 30 30 30 30 30 .0000000
+ .byte $C3,$C3,$C3,$C3,$C3,$C3,$C3,$3C ; 9612 C3 C3 C3 C3 C3 C3 C3 3C .......<
+ .byte $C3,$C3,$C3,$C3,$C3,$3C,$3C,$30 ; 961A C3 C3 C3 C3 C3 3C 3C 30 .....<<0
+ .byte $C3,$C3,$C3,$C3,$F3,$F3,$FF,$CF ; 9622 C3 C3 C3 C3 F3 F3 FF CF ........
+ .byte $C3,$C3,$C3,$3C,$3C,$C3,$C3,$C3 ; 962A C3 C3 C3 3C 3C C3 C3 C3 ...<<...
+ .byte $C3,$C3,$C3,$3C,$3C,$3C,$3C,$3C ; 9632 C3 C3 C3 3C 3C 3C 3C 3C ...<<<<<
+ .byte $1F,$19,$08,$04,$02,$01,$19,$1F ; 963A 1F 19 08 04 02 01 19 1F ........
+; ----------------------------------------------------------------------------
+; ATTACK WAVE n COMPLETED, BONUS x nnn
+print_end_level_msg:
+ lda #$08 ; 9642 A9 08 ..
+ sta cursor_x ; 9644 8D 39 14 .9.
+ lda #$06 ; 9647 A9 06 ..
+ sta cursor_y ; 9649 8D 3A 14 .:.
+ lda #$FF ; 964C A9 FF ..
+ sta glyph_color_mask ; 964E 85 EE ..
+ ldy #$00 ; 9650 A0 00 ..
+aw_loop:lda attack_wave_text,y ; 9652 B9 D6 96 ...
+ beq print_level ; 9655 F0 06 ..
+ jsr printchar ; 9657 20 2E 97 ..
+ iny ; 965A C8 .
+ bne aw_loop ; 965B D0 F5 ..
+print_level:
+ lda level ; 965D A5 9A ..
+ lsr $0510 ; 965F 4E 10 05 N..
+ jsr draw_2_score_digits ; 9662 20 83 94 ..
+ ldy #$00 ; 9665 A0 00 ..
+completed_loop:
+ lda completed_text,y ; 9667 B9 EE 96 ...
+ beq clamp_bonus ; 966A F0 06 ..
+ jsr printchar ; 966C 20 2E 97 ..
+ iny ; 966F C8 .
+ bne completed_loop ; 9670 D0 F5 ..
+; limit bonus multiplier to 5 (hundred, actually)
+clamp_bonus:
+ lda level ; 9672 A5 9A ..
+ cmp #$06 ; 9674 C9 06 ..
+ bcc print_bonus_mult ; 9676 90 02 ..
+ lda #$05 ; 9678 A9 05 ..
+; print 1st digit of bonus multiplier (range 1-5)
+print_bonus_mult:
+ lsr $0510 ; 967A 4E 10 05 N..
+ jsr draw_2_score_digits ; 967D 20 83 94 ..
+ sec ; 9680 38 8
+ ror $0510 ; 9681 6E 10 05 n..
+; print 00 after the 1-digit multiplier
+print_bonus_00:
+ lda #$00 ; 9684 A9 00 ..
+ jsr draw_2_score_digits ; 9686 20 83 94 ..
+ lda #$22 ; 9689 A9 22 ."
+ sta sprite_x ; 968B 85 E3 ..
+ lda #$90 ; 968D A9 90 ..
+ sta sprite_y ; 968F 85 DF ..
+ lda #$00 ; 9691 A9 00 ..
+ sta $E4 ; 9693 85 E4 ..
+ jmp add_bonus ; 9695 4C A2 96 L..
+
+; ----------------------------------------------------------------------------
+ab_next_sprite:
+ lda $E4 ; 9698 A5 E4 ..
+ clc ; 969A 18 .
+ adc #$04 ; 969B 69 04 i.
+ sta $E4 ; 969D 85 E4 ..
+ bpl add_bonus ; 969F 10 01 ..
+ rts ; 96A1 60 `
+
+; ----------------------------------------------------------------------------
+; add the bonus * multiplier to the score, for remaining humanoids
+add_bonus:
+ ldy $E4 ; 96A2 A4 E4 ..
+ lda sprite_list,y ; 96A4 B9 EB 0A ...
+ beq ab_next_sprite ; 96A7 F0 EF ..
+ lda sprite_list+3,y ; 96A9 B9 EE 0A ...
+ and #$07 ; 96AC 29 07 ).
+ bne ab_next_sprite ; 96AE D0 E8 ..
+ lda #$00 ; 96B0 A9 00 ..
+ sta current_sprite ; 96B2 85 F9 ..
+ jsr draw_sprite_left_copy ; 96B4 20 00 1F ..
+ jsr calc_bonus_index ; 96B7 20 C7 96 ..
+ jsr draw_scores ; 96BA 20 42 94 B.
+ clc ; 96BD 18 .
+ lda sprite_x ; 96BE A5 E3 ..
+ adc #$0A ; 96C0 69 0A i.
+ sta sprite_x ; 96C2 85 E3 ..
+ jmp ab_next_sprite ; 96C4 4C 98 96 L..
+
+; ----------------------------------------------------------------------------
+; A = 7 + (level < 6 ? level : 5); // index into score_points_table
+calc_bonus_index:
+ lda level ; 96C7 A5 9A ..
+ cmp #$06 ; 96C9 C9 06 ..
+ bcc cbi_add7 ; 96CB 90 02 ..
+ lda #$05 ; 96CD A9 05 ..
+; add 7 because that's where the bonus amounts start, in score_points_table
+cbi_add7:
+ clc ; 96CF 18 .
+ adc #$07 ; 96D0 69 07 i.
+ jmp add_points ; 96D2 4C B2 A7 L..
+
+; ----------------------------------------------------------------------------
+ rts ; 96D5 60 `
+
+; ----------------------------------------------------------------------------
+attack_wave_text:
+ .byte $C1,$A0,$D4,$A0,$D4,$A0,$C1,$A0 ; 96D6 C1 A0 D4 A0 D4 A0 C1 A0 ........
+ .byte $C3,$A0,$CB,$A0,$A0,$A0,$D7,$A0 ; 96DE C3 A0 CB A0 A0 A0 D7 A0 ........
+ .byte $C1,$A0,$D6,$A0,$C5,$A0,$A0,$00 ; 96E6 C1 A0 D6 A0 C5 A0 A0 00 ........
+completed_text:
+ .byte $8D,$8D,$A0,$A0,$A0,$A0,$A0,$A0 ; 96EE 8D 8D A0 A0 A0 A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$C3,$A0 ; 96F6 A0 A0 A0 A0 A0 A0 C3 A0 ........
+ .byte $CF,$A0,$CD,$A0,$D0,$A0,$CC,$A0 ; 96FE CF A0 CD A0 D0 A0 CC A0 ........
+ .byte $C5,$A0,$D4,$A0,$C5,$A0,$C4,$8D ; 9706 C5 A0 D4 A0 C5 A0 C4 8D ........
+ .byte $8D,$8D,$8D,$8D,$8D,$A0,$A0,$A0 ; 970E 8D 8D 8D 8D 8D A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 ; 9716 A0 A0 A0 A0 A0 A0 A0 A0 ........
+ .byte $A0,$C2,$A0,$CF,$A0,$CE,$A0,$D5 ; 971E A0 C2 A0 CF A0 CE A0 D5 ........
+ .byte $A0,$D3,$A0,$A0,$D8,$A0,$A0,$00 ; 9726 A0 D3 A0 A0 D8 A0 A0 00 ........
+; ----------------------------------------------------------------------------
+; print the DSCII text character in the A reg
+printchar:
+ pha ; 972E 48 H
+ lda cursor_y ; 972F AD 3A 14 .:.
+ asl a ; 9732 0A .
+ asl a ; 9733 0A .
+ asl a ; 9734 0A .
+ clc ; 9735 18 .
+ adc cursor_y ; 9736 6D 3A 14 m:.
+ sta cursor_line ; 9739 8D 12 05 ...
+ lda cursor_x ; 973C AD 39 14 .9.
+ sta cursor_x_tmp ; 973F 8D 15 05 ...
+ pla ; 9742 68 h
+ cmp #$C0 ; 9743 C9 C0 ..
+ beq print_copyright ; 9745 F0 11 ..
+ cmp #$8D ; 9747 C9 8D ..
+ beq print_crlf ; 9749 F0 1E ..
+ cmp #$A0 ; 974B C9 A0 ..
+ beq print_space ; 974D F0 23 .#
+ cmp #$C1 ; 974F C9 C1 ..
+ bcc print_digit ; 9751 90 28 .(
+ cmp #$DB ; 9753 C9 DB ..
+ bcc print_letter ; 9755 90 38 .8
+pch_done:
+ rts ; 9757 60 `
+
+; ----------------------------------------------------------------------------
+; print copyright symbol ($c0). it's double-wide, so 2 glyphs
+print_copyright:
+ lda #$58 ; 9758 A9 58 .X
+ sta glyph_offset ; 975A 8D 16 05 ...
+ jsr draw_glyph ; 975D 20 BC 94 ..
+ lda #$60 ; 9760 A9 60 .`
+ sta glyph_offset ; 9762 8D 16 05 ...
+ jsr draw_glyph ; 9765 20 BC 94 ..
+ rts ; 9768 60 `
+
+; ----------------------------------------------------------------------------
+; print carriage return ($8d)
+print_crlf:
+ lda #$00 ; 9769 A9 00 ..
+ sta cursor_x ; 976B 8D 39 14 .9.
+ inc cursor_y ; 976E EE 3A 14 .:.
+ rts ; 9771 60 `
+
+; ----------------------------------------------------------------------------
+; print a space ($a0)
+print_space:
+ lda #$50 ; 9772 A9 50 .P
+ sta glyph_offset ; 9774 8D 16 05 ...
+ jsr draw_glyph ; 9777 20 BC 94 ..
+ rts ; 977A 60 `
+
+; ----------------------------------------------------------------------------
+; print a number ($b0-$ba)
+print_digit:
+ cmp #$B0 ; 977B C9 B0 ..
+ bcc pch_done ; 977D 90 D8 ..
+ cmp #$BA ; 977F C9 BA ..
+ bcs pch_done ; 9781 B0 D4 ..
+ and #$0F ; 9783 29 0F ).
+ asl a ; 9785 0A .
+ asl a ; 9786 0A .
+ asl a ; 9787 0A .
+ sta glyph_offset ; 9788 8D 16 05 ...
+ jsr draw_glyph ; 978B 20 BC 94 ..
+ rts ; 978E 60 `
+
+; ----------------------------------------------------------------------------
+; print a letter ($c1-$db). does not call draw_glyph like you might expect.
+print_letter:
+ sec ; 978F 38 8
+ sbc #$C1 ; 9790 E9 C1 ..
+ asl a ; 9792 0A .
+ asl a ; 9793 0A .
+ asl a ; 9794 0A .
+ sta glyph_offset ; 9795 8D 16 05 ...
+ sty y_stash ; 9798 8C 19 05 ...
+ lda cursor_line ; 979B AD 12 05 ...
+ sta cur_line ; 979E 8D 13 05 ...
+ clc ; 97A1 18 .
+ adc #$08 ; 97A2 69 08 i.
+ sta last_line ; 97A4 8D 14 05 ...
+pl_next_line:
+ ldy cur_line ; 97A7 AC 13 05 ...
+ lda screen_hi_ptrs,y ; 97AA B9 00 1E ...
+ sta screen_ptr+1 ; 97AD 85 C1 ..
+ lda screen_lo_ptrs,y ; 97AF B9 00 1D ...
+ sta screen_ptr ; 97B2 85 C0 ..
+ ldx glyph_offset ; 97B4 AE 16 05 ...
+ lda font_letters,x ; 97B7 BD 72 95 .r.
+ and glyph_color_mask ; 97BA 25 EE %.
+ ldy cursor_x_tmp ; 97BC AC 15 05 ...
+ sta (screen_ptr),y ; 97BF 91 C0 ..
+ inc glyph_offset ; 97C1 EE 16 05 ...
+ inc cur_line ; 97C4 EE 13 05 ...
+ lda cur_line ; 97C7 AD 13 05 ...
+ cmp last_line ; 97CA CD 14 05 ...
+ bcc pl_next_line ; 97CD 90 D8 ..
+ inc cursor_x_tmp ; 97CF EE 15 05 ...
+ ldy y_stash ; 97D2 AC 19 05 ...
+ inc cursor_x ; 97D5 EE 39 14 .9.
+ rts ; 97D8 60 `
+
+; ----------------------------------------------------------------------------
+; particles
+ship_explosion:
+ lda #$01 ; 97D9 A9 01 ..
+ sta $0501 ; 97DB 8D 01 05 ...
+ sta $E4 ; 97DE 85 E4 ..
+ jsr init_splosion ; 97E0 20 F7 97 ..
+ jsr animate_explosion ; 97E3 20 30 98 0.
+ rts ; 97E6 60 `
+
+; ----------------------------------------------------------------------------
+; looks like the ship explosion, but in reverse
+hyperspace_implosion:
+ lda #$0A ; 97E7 A9 0A ..
+ sta $0501 ; 97E9 8D 01 05 ...
+ lda #$FF ; 97EC A9 FF ..
+ sta $E4 ; 97EE 85 E4 ..
+ jsr init_splosion ; 97F0 20 F7 97 ..
+ jsr animate_implosion ; 97F3 20 68 98 h.
+ rts ; 97F6 60 `
+
+; ----------------------------------------------------------------------------
+; calculate (ex|im)plosion particles for the player ship
+init_splosion:
+ ldx #$00 ; 97F7 A2 00 ..
+is_loop:jsr get_random ; 97F9 20 F2 8C ..
+ and #$0F ; 97FC 29 0F ).
+ sec ; 97FE 38 8
+ sbc #$07 ; 97FF E9 07 ..
+ cmp #$08 ; 9801 C9 08 ..
+ beq is_loop ; 9803 F0 F4 ..
+ sta splosion_particles,x ; 9805 9D 00 04 ...
+ inx ; 9808 E8 .
+ bne is_loop ; 9809 D0 EE ..
+ lda #$00 ; 980B A9 00 ..
+ sta $050C ; 980D 8D 0C 05 ...
+ lda #$BF ; 9810 A9 BF ..
+ sta $050D ; 9812 8D 0D 05 ...
+ lda #$04 ; 9815 A9 04 ..
+ sta $050E ; 9817 8D 0E 05 ...
+ lda #$9C ; 981A A9 9C ..
+ sta $050F ; 981C 8D 0F 05 ...
+ lda ship_x_pos ; 981F A5 C3 ..
+ clc ; 9821 18 .
+ adc #$05 ; 9822 69 05 i.
+ sta plosion_x_start ; 9824 8D 07 05 ...
+ lda ship_y_pos ; 9827 A5 C4 ..
+ clc ; 9829 18 .
+ adc #$04 ; 982A 69 04 i.
+ sta plosion_y_start ; 982C 8D 08 05 ...
+ rts ; 982F 60 `
+
+; ----------------------------------------------------------------------------
+animate_explosion:
+ lda #$FF ; 9830 A9 FF ..
+ sta sprite_x ; 9832 85 E3 ..
+ jsr animate_splosion ; 9834 20 95 98 ..
+ inc $0501 ; 9837 EE 01 05 ...
+ jsr animate_splosion ; 983A 20 95 98 ..
+L983D: dec $0501 ; 983D CE 01 05 ...
+ jsr animate_splosion ; 9840 20 95 98 ..
+ inc $0501 ; 9843 EE 01 05 ...
+ inc $0501 ; 9846 EE 01 05 ...
+ jsr animate_splosion ; 9849 20 95 98 ..
+ lda $0501 ; 984C AD 01 05 ...
+ lsr a ; 984F 4A J
+ eor #$0F ; 9850 49 0F I.
+ ora #$70 ; 9852 09 70 .p
+ sta COLOR2 ; 9854 8D C6 02 ...
+ lda $0501 ; 9857 AD 01 05 ...
+ cmp #$10 ; 985A C9 10 ..
+ bcc L983D ; 985C 90 DF ..
+ jsr animate_splosion ; 985E 20 95 98 ..
+ dec $0500 ; 9861 CE 00 05 ...
+ jsr animate_splosion ; 9864 20 95 98 ..
+ rts ; 9867 60 `
+
+; ----------------------------------------------------------------------------
+animate_implosion:
+ lda #$FF ; 9868 A9 FF ..
+ sta sprite_x ; 986A 85 E3 ..
+ jsr animate_splosion ; 986C 20 95 98 ..
+ dec $0501 ; 986F CE 01 05 ...
+ jsr animate_splosion ; 9872 20 95 98 ..
+L9875: inc $0501 ; 9875 EE 01 05 ...
+ jsr animate_splosion ; 9878 20 95 98 ..
+ dec $0501 ; 987B CE 01 05 ...
+ dec $0501 ; 987E CE 01 05 ...
+ jsr animate_splosion ; 9881 20 95 98 ..
+ lda $0501 ; 9884 AD 01 05 ...
+ cmp #$01 ; 9887 C9 01 ..
+ bcs L9875 ; 9889 B0 EA ..
+ jsr animate_splosion ; 988B 20 95 98 ..
+ inc $0501 ; 988E EE 01 05 ...
+ jsr animate_splosion ; 9891 20 95 98 ..
+ rts ; 9894 60 `
+
+; ----------------------------------------------------------------------------
+; called multiple times by animate_(im|ex)plosion. uses particles set up by init_splosion
+animate_splosion:
+ lda #$00 ; 9895 A9 00 ..
+ sta $0509 ; 9897 8D 09 05 ...
+L989A: lda $0501 ; 989A AD 01 05 ...
+ sta $0500 ; 989D 8D 00 05 ...
+ inc $0500 ; 98A0 EE 00 05 ...
+ lda $0509 ; 98A3 AD 09 05 ...
+ tax ; 98A6 AA .
+ lda splosion_particles,x ; 98A7 BD 00 04 ...
+ sta $0503 ; 98AA 8D 03 05 ...
+ lda splosion_particles+1,x ; 98AD BD 01 04 ...
+ sta $0504 ; 98B0 8D 04 05 ...
+ lda plosion_x_start ; 98B3 AD 07 05 ...
+ sta plosion_x ; 98B6 8D 05 05 ...
+ lda plosion_y_start ; 98B9 AD 08 05 ...
+ sta plosion_y ; 98BC 8D 06 05 ...
+L98BF: clc ; 98BF 18 .
+ lda $0503 ; 98C0 AD 03 05 ...
+ adc plosion_x ; 98C3 6D 05 05 m..
+ sta plosion_x ; 98C6 8D 05 05 ...
+ clc ; 98C9 18 .
+ lda $0504 ; 98CA AD 04 05 ...
+ adc plosion_y ; 98CD 6D 06 05 m..
+ sta plosion_y ; 98D0 8D 06 05 ...
+ dec $0500 ; 98D3 CE 00 05 ...
+ bne L98BF ; 98D6 D0 E7 ..
+ bit $E4 ; 98D8 24 E4 $.
+ bmi L98F6 ; 98DA 30 1A 0.
+ ldy plosion_y ; 98DC AC 06 05 ...
+ cpy $050C ; 98DF CC 0C 05 ...
+ bcc L9946 ; 98E2 90 62 .b
+ cpy $050D ; 98E4 CC 0D 05 ...
+ bcs L9946 ; 98E7 B0 5D .]
+ ldx plosion_x ; 98E9 AE 05 05 ...
+ cpx $050E ; 98EC EC 0E 05 ...
+ bcc L9946 ; 98EF 90 55 .U
+ cpx $050F ; 98F1 EC 0F 05 ...
+ bcs L9946 ; 98F4 B0 50 .P
+L98F6: ldx plosion_x ; 98F6 AE 05 05 ...
+ ldy plosion_y ; 98F9 AC 06 05 ...
+ lda screen_hi_ptrs,y ; 98FC B9 00 1E ...
+ sta screen_ptr+1 ; 98FF 85 C1 ..
+ lda screen_lo_ptrs,y ; 9901 B9 00 1D ...
+ sta screen_ptr ; 9904 85 C0 ..
+ ldy horiz_offset_table,x ; 9906 BC 00 1B ...
+ lda sprite_x ; 9909 A5 E3 ..
+ and pixel_mask_table,x ; 990B 3D 00 1C =..
+ eor (screen_ptr),y ; 990E 51 C0 Q.
+ sta (screen_ptr),y ; 9910 91 C0 ..
+ lda sprite_x ; 9912 A5 E3 ..
+ and pixel_mask_table+1,x ; 9914 3D 01 1C =..
+ ldy horiz_offset_table+1,x ; 9917 BC 01 1B ...
+ eor (screen_ptr),y ; 991A 51 C0 Q.
+ sta (screen_ptr),y ; 991C 91 C0 ..
+ ldy plosion_y ; 991E AC 06 05 ...
+ lda screen_hi_ptrs+1,y ; 9921 B9 01 1E ...
+ sta screen_ptr+1 ; 9924 85 C1 ..
+ lda screen_lo_ptrs+1,y ; 9926 B9 01 1D ...
+ sta screen_ptr ; 9929 85 C0 ..
+ ldy horiz_offset_table,x ; 992B BC 00 1B ...
+ lda sprite_x ; 992E A5 E3 ..
+ and pixel_mask_table,x ; 9930 3D 00 1C =..
+ eor (screen_ptr),y ; 9933 51 C0 Q.
+ sta (screen_ptr),y ; 9935 91 C0 ..
+ lda sprite_x ; 9937 A5 E3 ..
+ and pixel_mask_table+1,x ; 9939 3D 01 1C =..
+ ldy horiz_offset_table+1,x ; 993C BC 01 1B ...
+ eor (screen_ptr),y ; 993F 51 C0 Q.
+ sta (screen_ptr),y ; 9941 91 C0 ..
+ jmp L9951 ; 9943 4C 51 99 LQ.
+
+; ----------------------------------------------------------------------------
+L9946: ldx $0509 ; 9946 AE 09 05 ...
+ lda #$00 ; 9949 A9 00 ..
+ sta splosion_particles,x ; 994B 9D 00 04 ...
+ sta splosion_particles+1,x ; 994E 9D 01 04 ...
+L9951: inc $0509 ; 9951 EE 09 05 ...
+ inc $0509 ; 9954 EE 09 05 ...
+ lda $0509 ; 9957 AD 09 05 ...
+ cmp #$FA ; 995A C9 FA ..
+ bcs as_done ; 995C B0 03 ..
+ jmp L989A ; 995E 4C 9A 98 L..
+
+; ----------------------------------------------------------------------------
+as_done:rts ; 9961 60 `
+
+; ----------------------------------------------------------------------------
+; erase the player's rocket exhaust
+erase_exhaust:
+ lda #$00 ; 9962 A9 00 ..
+ sta current_sprite ; 9964 85 F9 ..
+ lda ship_direction ; 9966 A5 C5 ..
+ bmi L9978 ; 9968 30 0E 0.
+ lda ship_x_pos ; 996A A5 C3 ..
+ sec ; 996C 38 8
+ sbc #$06 ; 996D E9 06 ..
+ sta sprite_x ; 996F 85 E3 ..
+ lda ship_y_pos ; 9971 A5 C4 ..
+ sta sprite_y ; 9973 85 DF ..
+ jmp erase_sprite ; 9975 4C 2C AB L,.
+
+; ----------------------------------------------------------------------------
+L9978: lda ship_x_pos ; 9978 A5 C3 ..
+ clc ; 997A 18 .
+ adc #$0B ; 997B 69 0B i.
+ sta sprite_x ; 997D 85 E3 ..
+ lda ship_y_pos ; 997F A5 C4 ..
+ sta sprite_y ; 9981 85 DF ..
+ jmp erase_sprite ; 9983 4C 2C AB L,.
+
+; ----------------------------------------------------------------------------
+; draw the player's rocket exhaust, if he's thrusting
+ship_exhaust:
+ bit exhaust_flag ; 9986 2C 2B 0D ,+.
+ bmi L9994 ; 9989 30 09 0.
+ lda #$00 ; 998B A9 00 ..
+ sta AUDF2 ; 998D 8D 02 D2 ...
+ sta AUDC2 ; 9990 8D 03 D2 ...
+ rts ; 9993 60 `
+
+; ----------------------------------------------------------------------------
+L9994: lda #$1F ; 9994 A9 1F ..
+ sta AUDF2 ; 9996 8D 02 D2 ...
+ lda #$82 ; 9999 A9 82 ..
+ sta AUDC2 ; 999B 8D 03 D2 ...
+ lda ship_direction ; 999E A5 C5 ..
+ bmi L99B9 ; 99A0 30 17 0.
+ lda ship_x_pos ; 99A2 A5 C3 ..
+ sec ; 99A4 38 8
+ sbc #$06 ; 99A5 E9 06 ..
+ sta sprite_x ; 99A7 85 E3 ..
+ lda ship_y_pos ; 99A9 A5 C4 ..
+ sta sprite_y ; 99AB 85 DF ..
+ lda animation_counter ; 99AD A5 85 ..
+ and #$01 ; 99AF 29 01 ).
+ clc ; 99B1 18 .
+ adc #$13 ; 99B2 69 13 i.
+ sta $88 ; 99B4 85 88 ..
+ jmp draw_sprite_right_copy ; 99B6 4C 80 1F L..
+
+; ----------------------------------------------------------------------------
+L99B9: lda ship_x_pos ; 99B9 A5 C3 ..
+ clc ; 99BB 18 .
+ adc #$0B ; 99BC 69 0B i.
+ sta sprite_x ; 99BE 85 E3 ..
+ lda ship_y_pos ; 99C0 A5 C4 ..
+ sta sprite_y ; 99C2 85 DF ..
+ lda animation_counter ; 99C4 A5 85 ..
+ and #$01 ; 99C6 29 01 ).
+ clc ; 99C8 18 .
+ adc #$11 ; 99C9 69 11 i.
+ sta $88 ; 99CB 85 88 ..
+ jmp draw_sprite_right_copy ; 99CD 4C 80 1F L..
+
+; ----------------------------------------------------------------------------
+; trigger was pressed, decide what (if anything) to do about it
+handle_trigger:
+ lsr ATRACT ; 99D0 46 4D FM
+ ldy #$00 ; 99D2 A0 00 ..
+; look for an empty slot. if the table is full (4 shots in progress, ignore this trigger press. otherwise, Y is the byte index of the empty slot ($00, $04, $08, or $0c).
+check_shot_table:
+ lda player_shots_y,y ; 99D4 B9 1A 05 ...
+ beq shoot ; 99D7 F0 0D ..
+ tya ; 99D9 98 .
+ clc ; 99DA 18 .
+ adc #$04 ; 99DB 69 04 i.
+ tay ; 99DD A8 .
+ cpy #$10 ; 99DE C0 10 ..
+ bcc check_shot_table ; 99E0 90 F2 ..
+ jsr ram_self_destruct_1 ; 99E2 20 7F B4 ..
+ rts ; 99E5 60 `
+
+; ----------------------------------------------------------------------------
+; fire player's laser in the direction he's facing
+shoot: lda ship_y_pos ; 99E6 A5 C4 ..
+ clc ; 99E8 18 .
+ adc #$05 ; 99E9 69 05 i.
+ sta player_shots_y,y ; 99EB 99 1A 05 ...
+ lda ship_x_pos ; 99EE A5 C3 ..
+ and #$FC ; 99F0 29 FC ).
+ ldx ship_direction ; 99F2 A6 C5 ..
+ bmi shot_left ; 99F4 30 06 0.
+; start position for right-facing shot
+shot_right:
+ clc ; 99F6 18 .
+ adc #$0C ; 99F7 69 0C i.
+ jmp set_start_pos ; 99F9 4C FF 99 L..
+
+; ----------------------------------------------------------------------------
+; start position for left-facing shot
+shot_left:
+ sec ; 99FC 38 8
+ sbc #$04 ; 99FD E9 04 ..
+; set start and end to same pos
+set_start_pos:
+ sta player_shots_x_start,y ; 99FF 99 1B 05 ...
+ sta player_shots_x_end,y ; 9A02 99 1C 05 ...
+ lda ship_direction ; 9A05 A5 C5 ..
+ bmi delta_left ; 9A07 30 05 0.
+; delta for shot = 2
+delta_right:
+ lda #$02 ; 9A09 A9 02 ..
+ jmp set_delta ; 9A0B 4C 10 9A L..
+
+; ----------------------------------------------------------------------------
+; delta $FE aka -2
+delta_left:
+ lda #$FE ; 9A0E A9 FE ..
+set_delta:
+ sta player_shots_delta,y ; 9A10 99 1D 05 ...
+ jsr play_player_fire ; 9A13 20 98 8D ..
+ rts ; 9A16 60 `
+
+; ----------------------------------------------------------------------------
+; move and draw player shots. remove from table if they reach the end of the screen
+update_player_shots:
+ lda current_player_shot ; 9A17 A5 C2 ..
+ clc ; 9A19 18 .
+ adc #$04 ; 9A1A 69 04 i.
+ sta current_player_shot ; 9A1C 85 C2 ..
+ cmp #$10 ; 9A1E C9 10 ..
+ bcc L9A26 ; 9A20 90 04 ..
+ lda #$00 ; 9A22 A9 00 ..
+ sta current_player_shot ; 9A24 85 C2 ..
+L9A26: ldy current_player_shot ; 9A26 A4 C2 ..
+ lda player_shots_y,y ; 9A28 B9 1A 05 ...
+ bne ups_found ; 9A2B D0 01 ..
+ rts ; 9A2D 60 `
+
+; ----------------------------------------------------------------------------
+ups_found:
+ tax ; 9A2E AA .
+ lda screen_hi_ptrs,x ; 9A2F BD 00 1E ...
+ sta screen_ptr+1 ; 9A32 85 C1 ..
+ lda screen_lo_ptrs,x ; 9A34 BD 00 1D ...
+ sta screen_ptr ; 9A37 85 C0 ..
+ lda player_shots_x_end,y ; 9A39 B9 1C 05 ...
+ beq ups_erase ; 9A3C F0 42 .B
+ clc ; 9A3E 18 .
+ adc player_shots_delta,y ; 9A3F 79 1D 05 y..
+ cmp #$A0 ; 9A42 C9 A0 ..
+ bcc ups_store_x ; 9A44 90 02 ..
+ lda #$00 ; 9A46 A9 00 ..
+ups_store_x:
+ sta player_shots_x_end,y ; 9A48 99 1C 05 ...
+ beq ups_done ; 9A4B F0 32 .2
+ tax ; 9A4D AA .
+ ldy horiz_offset_table,x ; 9A4E BC 00 1B ...
+ lda #$FF ; 9A51 A9 FF ..
+ sta (screen_ptr),y ; 9A53 91 C0 ..
+ ldy current_player_shot ; 9A55 A4 C2 ..
+ lda player_shots_x_end,y ; 9A57 B9 1C 05 ...
+ sec ; 9A5A 38 8
+ sbc player_shots_x_start,y ; 9A5B F9 1B 05 ...
+ bcs L9A64 ; 9A5E B0 04 ..
+ eor #$FF ; 9A60 49 FF I.
+ adc #$01 ; 9A62 69 01 i.
+L9A64: cmp #$10 ; 9A64 C9 10 ..
+ bcc ups_done ; 9A66 90 17 ..
+ lda player_shots_x_end,y ; 9A68 B9 1C 05 ...
+ cmp player_shots_x_start,y ; 9A6B D9 1B 05 ...
+ bcc L9A75 ; 9A6E 90 05 ..
+ sbc #$0C ; 9A70 E9 0C ..
+ jmp L9A77 ; 9A72 4C 77 9A Lw.
+
+; ----------------------------------------------------------------------------
+L9A75: adc #$0C ; 9A75 69 0C i.
+L9A77: tax ; 9A77 AA .
+ ldy horiz_offset_table,x ; 9A78 BC 00 1B ...
+ lda random_seed ; 9A7B A5 C6 ..
+ sta (screen_ptr),y ; 9A7D 91 C0 ..
+ups_done:
+ rts ; 9A7F 60 `
+
+; ----------------------------------------------------------------------------
+ups_erase:
+ lda player_shots_x_start,y ; 9A80 B9 1B 05 ...
+ clc ; 9A83 18 .
+ adc player_shots_delta,y ; 9A84 79 1D 05 y..
+ sta player_shots_x_start,y ; 9A87 99 1B 05 ...
+ tax ; 9A8A AA .
+ cmp #$A0 ; 9A8B C9 A0 ..
+ bcc L9A94 ; 9A8D 90 05 ..
+ lda #$00 ; 9A8F A9 00 ..
+ sta player_shots_y,y ; 9A91 99 1A 05 ...
+L9A94: ldy horiz_offset_table,x ; 9A94 BC 00 1B ...
+ lda #$00 ; 9A97 A9 00 ..
+ sta (screen_ptr),y ; 9A99 91 C0 ..
+ rts ; 9A9B 60 `
+
+; ----------------------------------------------------------------------------
+L9A9C: sec ; 9A9C 38 8
+ lda $DD ; 9A9D A5 DD ..
+ sbc $89 ; 9A9F E5 89 ..
+ sta sprite_x ; 9AA1 85 E3 ..
+ lda $DE ; 9AA3 A5 DE ..
+ sbc $8A ; 9AA5 E5 8A ..
+ sta $E4 ; 9AA7 85 E4 ..
+ bcs L9AB7 ; 9AA9 B0 0C ..
+ lda sprite_x ; 9AAB A5 E3 ..
+ adc #$80 ; 9AAD 69 80 i.
+ sta sprite_x ; 9AAF 85 E3 ..
+ lda $E4 ; 9AB1 A5 E4 ..
+ adc #$02 ; 9AB3 69 02 i.
+ sta $E4 ; 9AB5 85 E4 ..
+L9AB7: lda $E4 ; 9AB7 A5 E4 ..
+ bne L9ACF ; 9AB9 D0 14 ..
+ lda sprite_x ; 9ABB A5 E3 ..
+ cmp #$A0 ; 9ABD C9 A0 ..
+ bcs L9ACF ; 9ABF B0 0E ..
+ ldy #$00 ; 9AC1 A0 00 ..
+L9AC3: lda sprite_list,y ; 9AC3 B9 EB 0A ...
+ beq L9AD0 ; 9AC6 F0 08 ..
+ tya ; 9AC8 98 .
+ clc ; 9AC9 18 .
+ adc #$04 ; 9ACA 69 04 i.
+ tay ; 9ACC A8 .
+ bpl L9AC3 ; 9ACD 10 F4 ..
+L9ACF: rts ; 9ACF 60 `
+
+; ----------------------------------------------------------------------------
+L9AD0: inc $BA ; 9AD0 E6 BA ..
+ lda sprite_y ; 9AD2 A5 DF ..
+ sta sprite_list,y ; 9AD4 99 EB 0A ...
+ lda $DD ; 9AD7 A5 DD ..
+ sta sprite_list+1,y ; 9AD9 99 EC 0A ...
+ lda $DE ; 9ADC A5 DE ..
+ sta sprite_list+2,y ; 9ADE 99 ED 0A ...
+ lda $94 ; 9AE1 A5 94 ..
+ sta sprite_list+3,y ; 9AE3 99 EE 0A ...
+ lda #$E2 ; 9AE6 A9 E2 ..
+ sta sprite_list+130,y ; 9AE8 99 6D 0B .m.
+ lda $94 ; 9AEB A5 94 ..
+ cmp #$0B ; 9AED C9 0B ..
+ beq L9ACF ; 9AEF F0 DE ..
+ lda ship_y_pos ; 9AF1 A5 C4 ..
+ sec ; 9AF3 38 8
+ sbc sprite_y ; 9AF4 E5 DF ..
+ bcs L9B0E ; 9AF6 B0 16 ..
+ eor #$FF ; 9AF8 49 FF I.
+ adc #$01 ; 9AFA 69 01 i.
+ lsr a ; 9AFC 4A J
+ lsr a ; 9AFD 4A J
+ lsr a ; 9AFE 4A J
+ lsr a ; 9AFF 4A J
+ lsr a ; 9B00 4A J
+ adc #$01 ; 9B01 69 01 i.
+ eor #$FF ; 9B03 49 FF I.
+ clc ; 9B05 18 .
+ adc #$01 ; 9B06 69 01 i.
+ sta sprite_list+128,y ; 9B08 99 6B 0B .k.
+ jmp L9B18 ; 9B0B 4C 18 9B L..
+
+; ----------------------------------------------------------------------------
+L9B0E: lsr a ; 9B0E 4A J
+ lsr a ; 9B0F 4A J
+ lsr a ; 9B10 4A J
+ lsr a ; 9B11 4A J
+ lsr a ; 9B12 4A J
+ adc #$01 ; 9B13 69 01 i.
+ sta sprite_list+128,y ; 9B15 99 6B 0B .k.
+L9B18: lda current_sprite ; 9B18 A5 F9 ..
+ cmp #$06 ; 9B1A C9 06 ..
+ bne L9B3B ; 9B1C D0 1D ..
+ tya ; 9B1E 98 .
+ pha ; 9B1F 48 H
+ jsr play_swarmer_taunt ; 9B20 20 EC 8D ..
+ pla ; 9B23 68 h
+ tay ; 9B24 A8 .
+ lda ship_x_pos ; 9B25 A5 C3 ..
+ cmp sprite_x ; 9B27 C5 E3 ..
+ bcs L9B33 ; 9B29 B0 08 ..
+ lda #$FC ; 9B2B A9 FC ..
+ sta sprite_list+129,y ; 9B2D 99 6C 0B .l.
+ jmp L9ACF ; 9B30 4C CF 9A L..
+
+; ----------------------------------------------------------------------------
+L9B33: lda #$04 ; 9B33 A9 04 ..
+ sta sprite_list+129,y ; 9B35 99 6C 0B .l.
+ jmp L9ACF ; 9B38 4C CF 9A L..
+
+; ----------------------------------------------------------------------------
+L9B3B: tya ; 9B3B 98 .
+ pha ; 9B3C 48 H
+ lda current_sprite ; 9B3D A5 F9 ..
+ and #$07 ; 9B3F 29 07 ).
+ cmp #$02 ; 9B41 C9 02 ..
+ beq L9B4B ; 9B43 F0 06 ..
+ jsr play_lander_fire ; 9B45 20 FA 8D ..
+ jmp L9B4E ; 9B48 4C 4E 9B LN.
+
+; ----------------------------------------------------------------------------
+L9B4B: jsr play_mutant_taunt ; 9B4B 20 DE 8D ..
+L9B4E: pla ; 9B4E 68 h
+ tay ; 9B4F A8 .
+ lda #$00 ; 9B50 A9 00 ..
+ sta $E5 ; 9B52 85 E5 ..
+ lda random_seed ; 9B54 A5 C6 ..
+ bpl L9B5C ; 9B56 10 04 ..
+ lda ship_delta ; 9B58 A5 D5 ..
+ sta $E5 ; 9B5A 85 E5 ..
+L9B5C: lda ship_x_pos ; 9B5C A5 C3 ..
+ sec ; 9B5E 38 8
+ sbc sprite_x ; 9B5F E5 E3 ..
+ bcs L9B79 ; 9B61 B0 16 ..
+ eor #$FF ; 9B63 49 FF I.
+ adc #$01 ; 9B65 69 01 i.
+ lsr a ; 9B67 4A J
+ lsr a ; 9B68 4A J
+ lsr a ; 9B69 4A J
+ lsr a ; 9B6A 4A J
+ lsr a ; 9B6B 4A J
+ adc #$01 ; 9B6C 69 01 i.
+ eor #$FF ; 9B6E 49 FF I.
+ clc ; 9B70 18 .
+ adc $E5 ; 9B71 65 E5 e.
+ sta sprite_list+129,y ; 9B73 99 6C 0B .l.
+ jmp L9ACF ; 9B76 4C CF 9A L..
+
+; ----------------------------------------------------------------------------
+L9B79: lsr a ; 9B79 4A J
+ lsr a ; 9B7A 4A J
+ lsr a ; 9B7B 4A J
+ lsr a ; 9B7C 4A J
+ lsr a ; 9B7D 4A J
+ adc $E5 ; 9B7E 65 E5 e.
+ sta sprite_list+129,y ; 9B80 99 6C 0B .l.
+ jmp L9ACF ; 9B83 4C CF 9A L..
+
+; ----------------------------------------------------------------------------
+spawn_enemy_shot:
+ ldy $98 ; 9B86 A4 98 ..
+ ldx $98 ; 9B88 A6 98 ..
+ inc sprite_list+130,x ; 9B8A FE 6D 0B .m.
+ bne L9B9A ; 9B8D D0 0B ..
+L9B8F: lda #$00 ; 9B8F A9 00 ..
+ sta sprite_y ; 9B91 85 DF ..
+ lda #$80 ; 9B93 A9 80 ..
+ sta $DE ; 9B95 85 DE ..
+ jmp L9BD9 ; 9B97 4C D9 9B L..
+
+; ----------------------------------------------------------------------------
+L9B9A: lda current_sprite ; 9B9A A5 F9 ..
+ cmp #$0B ; 9B9C C9 0B ..
+ beq L9BE0 ; 9B9E F0 40 .@
+ lda sprite_list+128,x ; 9BA0 BD 6B 0B .k.
+ clc ; 9BA3 18 .
+ adc sprite_y ; 9BA4 65 DF e.
+ sta sprite_y ; 9BA6 85 DF ..
+ lda sprite_y ; 9BA8 A5 DF ..
+ cmp #$20 ; 9BAA C9 20 .
+ bcc L9B8F ; 9BAC 90 E1 ..
+ cmp #$C0 ; 9BAE C9 C0 ..
+ bcs L9B8F ; 9BB0 B0 DD ..
+ lda sprite_list+129,x ; 9BB2 BD 6C 0B .l.
+ bmi L9BC5 ; 9BB5 30 0E 0.
+ clc ; 9BB7 18 .
+ adc $DD ; 9BB8 65 DD e.
+ sta $DD ; 9BBA 85 DD ..
+ lda $DE ; 9BBC A5 DE ..
+ adc #$00 ; 9BBE 69 00 i.
+ sta $DE ; 9BC0 85 DE ..
+ jmp L9BD9 ; 9BC2 4C D9 9B L..
+
+; ----------------------------------------------------------------------------
+L9BC5: eor #$FF ; 9BC5 49 FF I.
+ clc ; 9BC7 18 .
+ adc #$01 ; 9BC8 69 01 i.
+ sta sprite_x ; 9BCA 85 E3 ..
+ sec ; 9BCC 38 8
+ lda $DD ; 9BCD A5 DD ..
+ sbc sprite_x ; 9BCF E5 E3 ..
+ sta $DD ; 9BD1 85 DD ..
+ lda $DE ; 9BD3 A5 DE ..
+ sbc #$00 ; 9BD5 E9 00 ..
+ sta $DE ; 9BD7 85 DE ..
+L9BD9: lda #$0D ; 9BD9 A9 0D ..
+ sta $88 ; 9BDB 85 88 ..
+ jmp LA5B2 ; 9BDD 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+L9BE0: lda #$10 ; 9BE0 A9 10 ..
+ sta $88 ; 9BE2 85 88 ..
+ jmp LA5B2 ; 9BE4 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+; queue up an explosion, at first empty slot (or at last slot, if table is full)
+start_enemy_explosion:
+ ldy #$00 ; 9BE7 A0 00 ..
+see_next:
+ lda enemy_explosion_table,y ; 9BE9 B9 2B 05 .+.
+ beq see_queue ; 9BEC F0 0A ..
+ tya ; 9BEE 98 .
+ clc ; 9BEF 18 .
+ adc #$04 ; 9BF0 69 04 i.
+ tay ; 9BF2 A8 .
+ cpy #$80 ; 9BF3 C0 80 ..
+ bcc see_next ; 9BF5 90 F2 ..
+ rts ; 9BF7 60 `
+
+; ----------------------------------------------------------------------------
+see_queue:
+ lda $CA ; 9BF8 A5 CA ..
+ sta enemy_explosion_table,y ; 9BFA 99 2B 05 .+.
+ lda $C9 ; 9BFD A5 C9 ..
+ sta enemy_explosion_table+1,y ; 9BFF 99 2C 05 .,.
+ lda $CB ; 9C02 A5 CB ..
+ sta enemy_explosion_table+2,y ; 9C04 99 2D 05 .-.
+ lda #$28 ; 9C07 A9 28 .(
+ sta enemy_explosion_table+3,y ; 9C09 99 2E 05 ...
+ rts ; 9C0C 60 `
+
+; ----------------------------------------------------------------------------
+; flash screen when bomb goes off (whether any enemies are on screen or not)
+smartbomb_flash:
+ lda #$20 ; 9C0D A9 20 .
+sbf_loop:
+ pha ; 9C0F 48 H
+ jsr start_explosion ; 9C10 20 1A 9C ..
+ pla ; 9C13 68 h
+ sec ; 9C14 38 8
+ sbc #$01 ; 9C15 E9 01 ..
+ bne sbf_loop ; 9C17 D0 F6 ..
+ rts ; 9C19 60 `
+
+; ----------------------------------------------------------------------------
+; enemy or humanoid explosions, *not* the player's ship
+start_explosion:
+ lda $CC ; 9C1A A5 CC ..
+ clc ; 9C1C 18 .
+ adc #$04 ; 9C1D 69 04 i.
+ sta $CC ; 9C1F 85 CC ..
+ cmp #$80 ; 9C21 C9 80 ..
+ bcc L9C29 ; 9C23 90 04 ..
+ lda #$00 ; 9C25 A9 00 ..
+ sta $CC ; 9C27 85 CC ..
+L9C29: ldy $CC ; 9C29 A4 CC ..
+ lda enemy_explosion_table,y ; 9C2B B9 2B 05 .+.
+ bne L9C31 ; 9C2E D0 01 ..
+ rts ; 9C30 60 `
+
+; ----------------------------------------------------------------------------
+L9C31: sta $CA ; 9C31 85 CA ..
+ lda enemy_explosion_table+1,y ; 9C33 B9 2C 05 .,.
+ sta $C9 ; 9C36 85 C9 ..
+ lda enemy_explosion_table+2,y ; 9C38 B9 2D 05 .-.
+ sta $CB ; 9C3B 85 CB ..
+ jsr L9C6C ; 9C3D 20 6C 9C l.
+ lda $C9 ; 9C40 A5 C9 ..
+ sec ; 9C42 38 8
+ sbc ship_delta ; 9C43 E5 D5 ..
+ sta $C9 ; 9C45 85 C9 ..
+ ldx $CC ; 9C47 A6 CC ..
+ sta enemy_explosion_table+1,x ; 9C49 9D 2C 05 .,.
+ inc enemy_explosion_table+2,x ; 9C4C FE 2D 05 .-.
+ inc $CB ; 9C4F E6 CB ..
+ lda enemy_explosion_table+2,x ; 9C51 BD 2D 05 .-.
+ cmp enemy_explosion_table+3,x ; 9C54 DD 2E 05 ...
+ bcc L9C5F ; 9C57 90 06 ..
+ lda #$00 ; 9C59 A9 00 ..
+ sta enemy_explosion_table,x ; 9C5B 9D 2B 05 .+.
+ rts ; 9C5E 60 `
+
+; ----------------------------------------------------------------------------
+L9C5F: jmp L9C62 ; 9C5F 4C 62 9C Lb.
+
+; ----------------------------------------------------------------------------
+L9C62: lda #$FF ; 9C62 A9 FF ..
+ sta $CD ; 9C64 85 CD ..
+ lda $C030 ; 9C66 AD 30 C0 .0.
+ jmp L9C70 ; 9C69 4C 70 9C Lp.
+
+; ----------------------------------------------------------------------------
+L9C6C: lda #$00 ; 9C6C A9 00 ..
+ sta $CD ; 9C6E 85 CD ..
+L9C70: lda $CA ; 9C70 A5 CA ..
+ sec ; 9C72 38 8
+ sbc $CB ; 9C73 E5 CB ..
+ tay ; 9C75 A8 .
+ lda screen_hi_ptrs,y ; 9C76 B9 00 1E ...
+ sta screen_ptr+1 ; 9C79 85 C1 ..
+ lda screen_lo_ptrs,y ; 9C7B B9 00 1D ...
+ sta screen_ptr ; 9C7E 85 C0 ..
+ lda $C9 ; 9C80 A5 C9 ..
+ sec ; 9C82 38 8
+ sbc $CB ; 9C83 E5 CB ..
+ tax ; 9C85 AA .
+ ldy horiz_offset_table,x ; 9C86 BC 00 1B ...
+ lda random_seed ; 9C89 A5 C6 ..
+ and $CD ; 9C8B 25 CD %.
+ sta (screen_ptr),y ; 9C8D 91 C0 ..
+ ldx $C9 ; 9C8F A6 C9 ..
+ ldy horiz_offset_table,x ; 9C91 BC 00 1B ...
+ lda random_seed ; 9C94 A5 C6 ..
+ and $CD ; 9C96 25 CD %.
+ sta (screen_ptr),y ; 9C98 91 C0 ..
+ lda $C9 ; 9C9A A5 C9 ..
+ clc ; 9C9C 18 .
+ adc $CB ; 9C9D 65 CB e.
+ tax ; 9C9F AA .
+ ldy horiz_offset_table,x ; 9CA0 BC 00 1B ...
+ lda random_seed ; 9CA3 A5 C6 ..
+ and $CD ; 9CA5 25 CD %.
+ sta (screen_ptr),y ; 9CA7 91 C0 ..
+ ldy $CA ; 9CA9 A4 CA ..
+ lda screen_hi_ptrs,y ; 9CAB B9 00 1E ...
+ sta screen_ptr+1 ; 9CAE 85 C1 ..
+ lda screen_lo_ptrs,y ; 9CB0 B9 00 1D ...
+ sta screen_ptr ; 9CB3 85 C0 ..
+ lda $C9 ; 9CB5 A5 C9 ..
+ sec ; 9CB7 38 8
+ sbc $CB ; 9CB8 E5 CB ..
+ tax ; 9CBA AA .
+ ldy horiz_offset_table,x ; 9CBB BC 00 1B ...
+ lda random_seed ; 9CBE A5 C6 ..
+ and $CD ; 9CC0 25 CD %.
+ sta (screen_ptr),y ; 9CC2 91 C0 ..
+ ldx $C9 ; 9CC4 A6 C9 ..
+ ldy horiz_offset_table,x ; 9CC6 BC 00 1B ...
+ lda random_seed ; 9CC9 A5 C6 ..
+ and $CD ; 9CCB 25 CD %.
+ sta (screen_ptr),y ; 9CCD 91 C0 ..
+ lda $C9 ; 9CCF A5 C9 ..
+ clc ; 9CD1 18 .
+ adc $CB ; 9CD2 65 CB e.
+ tax ; 9CD4 AA .
+ ldy horiz_offset_table,x ; 9CD5 BC 00 1B ...
+ lda random_seed ; 9CD8 A5 C6 ..
+ and $CD ; 9CDA 25 CD %.
+ sta (screen_ptr),y ; 9CDC 91 C0 ..
+ lda $CA ; 9CDE A5 CA ..
+ clc ; 9CE0 18 .
+ adc $CB ; 9CE1 65 CB e.
+ tay ; 9CE3 A8 .
+ lda screen_hi_ptrs,y ; 9CE4 B9 00 1E ...
+ sta screen_ptr+1 ; 9CE7 85 C1 ..
+ lda screen_lo_ptrs,y ; 9CE9 B9 00 1D ...
+ sta screen_ptr ; 9CEC 85 C0 ..
+ lda $C9 ; 9CEE A5 C9 ..
+ sec ; 9CF0 38 8
+ sbc $CB ; 9CF1 E5 CB ..
+ tax ; 9CF3 AA .
+ ldy horiz_offset_table,x ; 9CF4 BC 00 1B ...
+ lda random_seed ; 9CF7 A5 C6 ..
+ and $CD ; 9CF9 25 CD %.
+ sta (screen_ptr),y ; 9CFB 91 C0 ..
+ ldx $C9 ; 9CFD A6 C9 ..
+ ldy horiz_offset_table,x ; 9CFF BC 00 1B ...
+ lda random_seed ; 9D02 A5 C6 ..
+ and $CD ; 9D04 25 CD %.
+ sta (screen_ptr),y ; 9D06 91 C0 ..
+ lda $C9 ; 9D08 A5 C9 ..
+ clc ; 9D0A 18 .
+ adc $CB ; 9D0B 65 CB e.
+ tax ; 9D0D AA .
+ ldy horiz_offset_table,x ; 9D0E BC 00 1B ...
+ lda random_seed ; 9D11 A5 C6 ..
+ and $CD ; 9D13 25 CD %.
+ sta (screen_ptr),y ; 9D15 91 C0 ..
+ rts ; 9D17 60 `
+
+; ----------------------------------------------------------------------------
+L9D18: lda #$A0 ; 9D18 A9 A0 ..
+ sta $D3 ; 9D1A 85 D3 ..
+ ldy #$00 ; 9D1C A0 00 ..
+L9D1E: sta $05AB,y ; 9D1E 99 AB 05 ...
+ sta $06AB,y ; 9D21 99 AB 06 ...
+ sta $072B,y ; 9D24 99 2B 07 .+.
+ sta $082B,y ; 9D27 99 2B 08 .+.
+ sta $092B,y ; 9D2A 99 2B 09 .+.
+ sta $09AB,y ; 9D2D 99 AB 09 ...
+ iny ; 9D30 C8 .
+ bne L9D1E ; 9D31 D0 EB ..
+ lda #$05 ; 9D33 A9 05 ..
+ sta $D0 ; 9D35 85 D0 ..
+ lda #$AB ; 9D37 A9 AB ..
+ sta $CF ; 9D39 85 CF ..
+L9D3B: jsr get_random ; 9D3B 20 F2 8C ..
+ cmp #$D8 ; 9D3E C9 D8 ..
+ bcs L9DAB ; 9D40 B0 69 .i
+ ldx #$01 ; 9D42 A2 01 ..
+L9D44: dec $D3 ; 9D44 C6 D3 ..
+ lda $D3 ; 9D46 A5 D3 ..
+ ldy #$00 ; 9D48 A0 00 ..
+ sta ($CF),y ; 9D4A 91 CF ..
+ jsr L9D8E ; 9D4C 20 8E 9D ..
+ bcs L9D62 ; 9D4F B0 11 ..
+ inc $D3 ; 9D51 E6 D3 ..
+ lda $D3 ; 9D53 A5 D3 ..
+ sta ($CF),y ; 9D55 91 CF ..
+ jsr L9D8E ; 9D57 20 8E 9D ..
+ bcs L9D62 ; 9D5A B0 06 ..
+ dex ; 9D5C CA .
+ bne L9D44 ; 9D5D D0 E5 ..
+ jmp L9D3B ; 9D5F 4C 3B 9D L;.
+
+; ----------------------------------------------------------------------------
+L9D62: ldy #$00 ; 9D62 A0 00 ..
+L9D64: jsr L9D9D ; 9D64 20 9D 9D ..
+ lda ($CF),y ; 9D67 B1 CF ..
+ cmp #$A0 ; 9D69 C9 A0 ..
+ bne L9D64 ; 9D6B D0 F7 ..
+L9D6D: lda #$A0 ; 9D6D A9 A0 ..
+ sta ($CF),y ; 9D6F 91 CF ..
+ jsr L9D8E ; 9D71 20 8E 9D ..
+ bcc L9D6D ; 9D74 90 F7 ..
+ ldx #$00 ; 9D76 A2 00 ..
+L9D78: lda $05AB,x ; 9D78 BD AB 05 ...
+ sta $082B,x ; 9D7B 9D 2B 08 .+.
+ lda $06AB,x ; 9D7E BD AB 06 ...
+ sta $092B,x ; 9D81 9D 2B 09 .+.
+ lda $072B,x ; 9D84 BD 2B 07 .+.
+ sta $09AB,x ; 9D87 9D AB 09 ...
+ inx ; 9D8A E8 .
+ bne L9D78 ; 9D8B D0 EB ..
+ rts ; 9D8D 60 `
+
+; ----------------------------------------------------------------------------
+L9D8E: inc $CF ; 9D8E E6 CF ..
+ bne L9D94 ; 9D90 D0 02 ..
+ inc $D0 ; 9D92 E6 D0 ..
+L9D94: lda $CF ; 9D94 A5 CF ..
+ cmp #$2B ; 9D96 C9 2B .+
+ lda $D0 ; 9D98 A5 D0 ..
+ sbc #$08 ; 9D9A E9 08 ..
+ rts ; 9D9C 60 `
+
+; ----------------------------------------------------------------------------
+L9D9D: sec ; 9D9D 38 8
+ lda $CF ; 9D9E A5 CF ..
+ sbc #$01 ; 9DA0 E9 01 ..
+ sta $CF ; 9DA2 85 CF ..
+ lda $D0 ; 9DA4 A5 D0 ..
+ sbc #$00 ; 9DA6 E9 00 ..
+ sta $D0 ; 9DA8 85 D0 ..
+ rts ; 9DAA 60 `
+
+; ----------------------------------------------------------------------------
+L9DAB: jsr get_random ; 9DAB 20 F2 8C ..
+ bmi L9DDD ; 9DAE 30 2D 0-
+ lda random_seed ; 9DB0 A5 C6 ..
+ and #$1F ; 9DB2 29 1F ).
+ adc #$02 ; 9DB4 69 02 i.
+ sta $D1 ; 9DB6 85 D1 ..
+ pha ; 9DB8 48 H
+L9DB9: dec $D3 ; 9DB9 C6 D3 ..
+ lda $D3 ; 9DBB A5 D3 ..
+ ldy #$00 ; 9DBD A0 00 ..
+ sta ($CF),y ; 9DBF 91 CF ..
+ jsr L9D8E ; 9DC1 20 8E 9D ..
+ dec $D1 ; 9DC4 C6 D1 ..
+ bne L9DB9 ; 9DC6 D0 F1 ..
+ pla ; 9DC8 68 h
+ sta $D1 ; 9DC9 85 D1 ..
+L9DCB: inc $D3 ; 9DCB E6 D3 ..
+ lda $D3 ; 9DCD A5 D3 ..
+ ldy #$00 ; 9DCF A0 00 ..
+ sta ($CF),y ; 9DD1 91 CF ..
+ jsr L9D8E ; 9DD3 20 8E 9D ..
+ dec $D1 ; 9DD6 C6 D1 ..
+ bne L9DCB ; 9DD8 D0 F1 ..
+ jmp L9D3B ; 9DDA 4C 3B 9D L;.
+
+; ----------------------------------------------------------------------------
+L9DDD: lda random_seed ; 9DDD A5 C6 ..
+ and #$07 ; 9DDF 29 07 ).
+ adc #$02 ; 9DE1 69 02 i.
+ sta $D1 ; 9DE3 85 D1 ..
+ pha ; 9DE5 48 H
+L9DE6: inc $D3 ; 9DE6 E6 D3 ..
+ lda $D3 ; 9DE8 A5 D3 ..
+ ldy #$00 ; 9DEA A0 00 ..
+ sta ($CF),y ; 9DEC 91 CF ..
+ jsr L9D8E ; 9DEE 20 8E 9D ..
+ dec $D1 ; 9DF1 C6 D1 ..
+ bne L9DE6 ; 9DF3 D0 F1 ..
+ pla ; 9DF5 68 h
+ sta $D1 ; 9DF6 85 D1 ..
+L9DF8: dec $D3 ; 9DF8 C6 D3 ..
+ lda $D3 ; 9DFA A5 D3 ..
+ ldy #$00 ; 9DFC A0 00 ..
+ sta ($CF),y ; 9DFE 91 CF ..
+ jsr L9D8E ; 9E00 20 8E 9D ..
+ dec $D1 ; 9E03 C6 D1 ..
+ bne L9DF8 ; 9E05 D0 F1 ..
+ jmp L9D3B ; 9E07 4C 3B 9D L;.
+
+; ----------------------------------------------------------------------------
+; planet explosion sequence. doesn't set planet_dead_flag (that's done by the caller, after this returns)
+destroy_planet:
+ lda $CF ; 9E0A A5 CF ..
+ sta tmp_ptr ; 9E0C 85 E7 ..
+ lda $D0 ; 9E0E A5 D0 ..
+ sta tmp_ptr+1 ; 9E10 85 E8 ..
+ lda #$00 ; 9E12 A9 00 ..
+ sta $C9 ; 9E14 85 C9 ..
+ lda #$10 ; 9E16 A9 10 ..
+L9E18: pha ; 9E18 48 H
+L9E19: bit draw_ok_flag ; 9E19 24 AB $.
+ bmi L9E19 ; 9E1B 30 FC 0.
+L9E1D: bit draw_ok_flag ; 9E1D 24 AB $.
+ bpl L9E1D ; 9E1F 10 FC ..
+ jsr smartbomb_flash ; 9E21 20 0D 9C ..
+ lda COLOR4 ; 9E24 AD C8 02 ...
+ eor #$0F ; 9E27 49 0F I.
+ sta COLOR4 ; 9E29 8D C8 02 ...
+ clc ; 9E2C 18 .
+ lda tmp_ptr ; 9E2D A5 E7 ..
+ adc #$10 ; 9E2F 69 10 i.
+ sta tmp_ptr ; 9E31 85 E7 ..
+ lda tmp_ptr+1 ; 9E33 A5 E8 ..
+ adc #$00 ; 9E35 69 00 i.
+ sta tmp_ptr+1 ; 9E37 85 E8 ..
+ ldy #$00 ; 9E39 A0 00 ..
+ lda (tmp_ptr),y ; 9E3B B1 E7 ..
+ sta $CA ; 9E3D 85 CA ..
+ clc ; 9E3F 18 .
+ lda $C9 ; 9E40 A5 C9 ..
+ adc #$10 ; 9E42 69 10 i.
+ sta $C9 ; 9E44 85 C9 ..
+ lda #$01 ; 9E46 A9 01 ..
+ sta $CB ; 9E48 85 CB ..
+ jsr start_enemy_explosion ; 9E4A 20 E7 9B ..
+ pla ; 9E4D 68 h
+ sec ; 9E4E 38 8
+ sbc #$01 ; 9E4F E9 01 ..
+ bne L9E18 ; 9E51 D0 C5 ..
+ lda #$00 ; 9E53 A9 00 ..
+ sta COLOR4 ; 9E55 8D C8 02 ...
+ jsr play_planet_explode ; 9E58 20 78 8E x.
+ jmp L9F90 ; 9E5B 4C 90 9F L..
+
+; ----------------------------------------------------------------------------
+; XXX don't know how this works yet
+clear_scanner_draw_planet_and_humans:
+ lda $CF ; 9E5E A5 CF ..
+ sta $FC ; 9E60 85 FC ..
+ lda $D0 ; 9E62 A5 D0 ..
+ sta $FD ; 9E64 85 FD ..
+ sec ; 9E66 38 8
+ lda $FC ; 9E67 A5 FC ..
+ sbc #$AB ; 9E69 E9 AB ..
+ sta $8B ; 9E6B 85 8B ..
+ lda $FD ; 9E6D A5 FD ..
+ sbc #$05 ; 9E6F E9 05 ..
+ sta $8C ; 9E71 85 8C ..
+ lda ship_delta ; 9E73 A5 D5 ..
+ bpl L9E92 ; 9E75 10 1B ..
+ pha ; 9E77 48 H
+ eor #$FF ; 9E78 49 FF I.
+ clc ; 9E7A 18 .
+ adc #$01 ; 9E7B 69 01 i.
+ sta ship_delta ; 9E7D 85 D5 ..
+ sec ; 9E7F 38 8
+ lda $CF ; 9E80 A5 CF ..
+ sbc ship_delta ; 9E82 E5 D5 ..
+ sta $CF ; 9E84 85 CF ..
+ lda $D0 ; 9E86 A5 D0 ..
+ sbc #$00 ; 9E88 E9 00 ..
+ sta $D0 ; 9E8A 85 D0 ..
+ pla ; 9E8C 68 h
+ sta ship_delta ; 9E8D 85 D5 ..
+ jmp L9E9F ; 9E8F 4C 9F 9E L..
+
+; ----------------------------------------------------------------------------
+L9E92: clc ; 9E92 18 .
+ lda ship_delta ; 9E93 A5 D5 ..
+ adc $CF ; 9E95 65 CF e.
+ sta $CF ; 9E97 85 CF ..
+ lda $D0 ; 9E99 A5 D0 ..
+ adc #$00 ; 9E9B 69 00 i.
+ sta $D0 ; 9E9D 85 D0 ..
+L9E9F: lda $CF ; 9E9F A5 CF ..
+ cmp #$AB ; 9EA1 C9 AB ..
+ lda $D0 ; 9EA3 A5 D0 ..
+ sbc #$05 ; 9EA5 E9 05 ..
+ bcc L9EC3 ; 9EA7 90 1A ..
+ lda $CF ; 9EA9 A5 CF ..
+ cmp #$2B ; 9EAB C9 2B .+
+ lda $D0 ; 9EAD A5 D0 ..
+ sbc #$08 ; 9EAF E9 08 ..
+ bcc L9ED0 ; 9EB1 90 1D ..
+ sec ; 9EB3 38 8
+ lda $CF ; 9EB4 A5 CF ..
+ sbc #$80 ; 9EB6 E9 80 ..
+ sta $CF ; 9EB8 85 CF ..
+ lda $D0 ; 9EBA A5 D0 ..
+ sbc #$02 ; 9EBC E9 02 ..
+ sta $D0 ; 9EBE 85 D0 ..
+ jmp L9ED0 ; 9EC0 4C D0 9E L..
+
+; ----------------------------------------------------------------------------
+L9EC3: clc ; 9EC3 18 .
+ lda $CF ; 9EC4 A5 CF ..
+ adc #$80 ; 9EC6 69 80 i.
+ sta $CF ; 9EC8 85 CF ..
+ lda $D0 ; 9ECA A5 D0 ..
+ adc #$02 ; 9ECC 69 02 i.
+ sta $D0 ; 9ECE 85 D0 ..
+L9ED0: sec ; 9ED0 38 8
+ lda $CF ; 9ED1 A5 CF ..
+ sbc #$AB ; 9ED3 E9 AB ..
+ sta $89 ; 9ED5 85 89 ..
+ lda $D0 ; 9ED7 A5 D0 ..
+ sbc #$05 ; 9ED9 E9 05 ..
+ sta $8A ; 9EDB 85 8A ..
+ lda $D7 ; 9EDD A5 D7 ..
+ sta $D9 ; 9EDF 85 D9 ..
+ lda $D8 ; 9EE1 A5 D8 ..
+ sta $DA ; 9EE3 85 DA ..
+ sec ; 9EE5 38 8
+ lda $D9 ; 9EE6 A5 D9 ..
+ sbc #$AB ; 9EE8 E9 AB ..
+ sta $8F ; 9EEA 85 8F ..
+ lda $DA ; 9EEC A5 DA ..
+ sbc #$05 ; 9EEE E9 05 ..
+ sta $90 ; 9EF0 85 90 ..
+ lda $CF ; 9EF2 A5 CF ..
+ sec ; 9EF4 38 8
+ sbc #$F0 ; 9EF5 E9 F0 ..
+ sta $D7 ; 9EF7 85 D7 ..
+ lda $D0 ; 9EF9 A5 D0 ..
+ sbc #$00 ; 9EFB E9 00 ..
+ sta $D8 ; 9EFD 85 D8 ..
+ lda $D7 ; 9EFF A5 D7 ..
+ cmp #$AB ; 9F01 C9 AB ..
+ lda $D8 ; 9F03 A5 D8 ..
+ sbc #$05 ; 9F05 E9 05 ..
+ bcc L9F23 ; 9F07 90 1A ..
+ lda $D7 ; 9F09 A5 D7 ..
+ cmp #$2B ; 9F0B C9 2B .+
+ lda $D8 ; 9F0D A5 D8 ..
+ sbc #$08 ; 9F0F E9 08 ..
+ bcc L9F30 ; 9F11 90 1D ..
+ sec ; 9F13 38 8
+ lda $D7 ; 9F14 A5 D7 ..
+ sbc #$80 ; 9F16 E9 80 ..
+ sta $D7 ; 9F18 85 D7 ..
+ lda $D8 ; 9F1A A5 D8 ..
+ sbc #$02 ; 9F1C E9 02 ..
+ sta $D8 ; 9F1E 85 D8 ..
+ jmp L9F30 ; 9F20 4C 30 9F L0.
+
+; ----------------------------------------------------------------------------
+L9F23: clc ; 9F23 18 .
+ lda $D7 ; 9F24 A5 D7 ..
+ adc #$80 ; 9F26 69 80 i.
+ sta $D7 ; 9F28 85 D7 ..
+ lda $D8 ; 9F2A A5 D8 ..
+ adc #$02 ; 9F2C 69 02 i.
+ sta $D8 ; 9F2E 85 D8 ..
+L9F30: sec ; 9F30 38 8
+ lda $D7 ; 9F31 A5 D7 ..
+ sbc #$AB ; 9F33 E9 AB ..
+ sta $8D ; 9F35 85 8D ..
+ lda $D8 ; 9F37 A5 D8 ..
+ sbc #$05 ; 9F39 E9 05 ..
+ sta $8E ; 9F3B 85 8E ..
+ lda planet_dead_flag ; 9F3D A5 A0 ..
+ bmi L9F44 ; 9F3F 30 03 0.
+ jmp L9F45 ; 9F41 4C 45 9F LE.
+
+; ----------------------------------------------------------------------------
+L9F44: rts ; 9F44 60 `
+
+; ----------------------------------------------------------------------------
+L9F45: lda $FC ; 9F45 A5 FC ..
+ sta tmp_ptr ; 9F47 85 E7 ..
+ lda $FD ; 9F49 A5 FD ..
+ sta tmp_ptr+1 ; 9F4B 85 E8 ..
+ lda #$A0 ; 9F4D A9 A0 ..
+ sta $D2 ; 9F4F 85 D2 ..
+L9F51: ldy $D2 ; 9F51 A4 D2 ..
+ lda (tmp_ptr),y ; 9F53 B1 E7 ..
+ tax ; 9F55 AA .
+ lda $1DFF,x ; 9F56 BD FF 1D ...
+ sta screen_ptr+1 ; 9F59 85 C1 ..
+ lda pixel_mask_table+255,x ; 9F5B BD FF 1C ...
+ sta screen_ptr ; 9F5E 85 C0 ..
+ ldx $D2 ; 9F60 A6 D2 ..
+ ldy $1AFF,x ; 9F62 BC FF 1A ...
+ lda horiz_offset_table+255,x ; 9F65 BD FF 1B ...
+ eor #$FF ; 9F68 49 FF I.
+ and (screen_ptr),y ; 9F6A 31 C0 1.
+ sta (screen_ptr),y ; 9F6C 91 C0 ..
+ ldy $D2 ; 9F6E A4 D2 ..
+ lda ($CF),y ; 9F70 B1 CF ..
+ tax ; 9F72 AA .
+ lda $1DFF,x ; 9F73 BD FF 1D ...
+ sta screen_ptr+1 ; 9F76 85 C1 ..
+ lda pixel_mask_table+255,x ; 9F78 BD FF 1C ...
+ sta screen_ptr ; 9F7B 85 C0 ..
+ ldx $D2 ; 9F7D A6 D2 ..
+ lda #$AA ; 9F7F A9 AA ..
+ and horiz_offset_table+255,x ; 9F81 3D FF 1B =..
+ ldy $1AFF,x ; 9F84 BC FF 1A ...
+ ora (screen_ptr),y ; 9F87 11 C0 ..
+ sta (screen_ptr),y ; 9F89 91 C0 ..
+ dec $D2 ; 9F8B C6 D2 ..
+ bne L9F51 ; 9F8D D0 C2 ..
+ rts ; 9F8F 60 `
+
+; ----------------------------------------------------------------------------
+L9F90: lda #$A0 ; 9F90 A9 A0 ..
+ sta $D2 ; 9F92 85 D2 ..
+L9F94: ldy $D2 ; 9F94 A4 D2 ..
+ lda ($CF),y ; 9F96 B1 CF ..
+ tax ; 9F98 AA .
+ lda $1DFF,x ; 9F99 BD FF 1D ...
+ sta screen_ptr+1 ; 9F9C 85 C1 ..
+ lda pixel_mask_table+255,x ; 9F9E BD FF 1C ...
+ sta screen_ptr ; 9FA1 85 C0 ..
+ tya ; 9FA3 98 .
+ tax ; 9FA4 AA .
+ ldy $1AFF,x ; 9FA5 BC FF 1A ...
+ lda #$00 ; 9FA8 A9 00 ..
+ sta (screen_ptr),y ; 9FAA 91 C0 ..
+ dec $D2 ; 9FAC C6 D2 ..
+ bne L9F94 ; 9FAE D0 E4 ..
+ rts ; 9FB0 60 `
+
+; ----------------------------------------------------------------------------
+; XXX don't know how this works yet (the planet in the scanner here!)
+draw_scanner_border_and_planet:
+ lda planet_dead_flag ; 9FB1 A5 A0 ..
+ bpl L9FB8 ; 9FB3 10 03 ..
+ jmp LA039 ; 9FB5 4C 39 A0 L9.
+
+; ----------------------------------------------------------------------------
+L9FB8: lda $FE ; 9FB8 A5 FE ..
+ sta tmp_ptr ; 9FBA 85 E7 ..
+ lda $FF ; 9FBC A5 FF ..
+ sta tmp_ptr+1 ; 9FBE 85 E8 ..
+ lda #$28 ; 9FC0 A9 28 .(
+ sta $DB ; 9FC2 85 DB ..
+ lda #$50 ; 9FC4 A9 50 .P
+ sta $DC ; 9FC6 85 DC ..
+L9FC8: ldy #$00 ; 9FC8 A0 00 ..
+ lda (tmp_ptr),y ; 9FCA B1 E7 ..
+ lsr a ; 9FCC 4A J
+ lsr a ; 9FCD 4A J
+ lsr a ; 9FCE 4A J
+ tay ; 9FCF A8 .
+ lda screen_hi_ptrs,y ; 9FD0 B9 00 1E ...
+ sta screen_ptr+1 ; 9FD3 85 C1 ..
+ lda screen_lo_ptrs,y ; 9FD5 B9 00 1D ...
+ sta screen_ptr ; 9FD8 85 C0 ..
+ ldx $DB ; 9FDA A6 DB ..
+ ldy horiz_offset_table,x ; 9FDC BC 00 1B ...
+ lda #$00 ; 9FDF A9 00 ..
+ sta (screen_ptr),y ; 9FE1 91 C0 ..
+ inc $DB ; 9FE3 E6 DB ..
+ clc ; 9FE5 18 .
+ lda tmp_ptr ; 9FE6 A5 E7 ..
+ adc #$08 ; 9FE8 69 08 i.
+ sta tmp_ptr ; 9FEA 85 E7 ..
+ bcc L9FF0 ; 9FEC 90 02 ..
+ inc tmp_ptr+1 ; 9FEE E6 E8 ..
+L9FF0: dec $DC ; 9FF0 C6 DC ..
+ bne L9FC8 ; 9FF2 D0 D4 ..
+ lda $D7 ; 9FF4 A5 D7 ..
+ sta tmp_ptr ; 9FF6 85 E7 ..
+ sta $FE ; 9FF8 85 FE ..
+ lda $D8 ; 9FFA A5 D8 ..
+ sta tmp_ptr+1 ; 9FFC 85 E8 ..
+ sta $FF ; 9FFE 85 FF ..
+ lda #$28 ; A000 A9 28 .(
+ sta $DB ; A002 85 DB ..
+ lda #$50 ; A004 A9 50 .P
+ sta $DC ; A006 85 DC ..
+LA008: ldy #$00 ; A008 A0 00 ..
+ lda (tmp_ptr),y ; A00A B1 E7 ..
+ lsr a ; A00C 4A J
+ lsr a ; A00D 4A J
+ lsr a ; A00E 4A J
+ tay ; A00F A8 .
+ lda screen_hi_ptrs,y ; A010 B9 00 1E ...
+ sta screen_ptr+1 ; A013 85 C1 ..
+ lda screen_lo_ptrs,y ; A015 B9 00 1D ...
+ sta screen_ptr ; A018 85 C0 ..
+ ldx $DB ; A01A A6 DB ..
+ ldy horiz_offset_table,x ; A01C BC 00 1B ...
+ lda #$55 ; A01F A9 55 .U
+ and pixel_mask_table,x ; A021 3D 00 1C =..
+ ora (screen_ptr),y ; A024 11 C0 ..
+ sta (screen_ptr),y ; A026 91 C0 ..
+ inc $DB ; A028 E6 DB ..
+ clc ; A02A 18 .
+ lda tmp_ptr ; A02B A5 E7 ..
+ adc #$08 ; A02D 69 08 i.
+ sta tmp_ptr ; A02F 85 E7 ..
+ bcc LA035 ; A031 90 02 ..
+ inc tmp_ptr+1 ; A033 E6 E8 ..
+LA035: dec $DC ; A035 C6 DC ..
+ bne LA008 ; A037 D0 CF ..
+LA039: lda level ; A039 A5 9A ..
+ and #$03 ; A03B 29 03 ).
+ tay ; A03D A8 .
+ lda scanner_border_table,y ; A03E B9 AB A0 ...
+ sta $BC ; A041 85 BC ..
+ ldy #$1D ; A043 A0 1D ..
+ lda screen_hi_ptrs,y ; A045 B9 00 1E ...
+ sta screen_ptr+1 ; A048 85 C1 ..
+ lda screen_lo_ptrs,y ; A04A B9 00 1D ...
+ sta screen_ptr ; A04D 85 C0 ..
+ ldy #$27 ; A04F A0 27 .'
+ ldx #$00 ; A051 A2 00 ..
+LA053: lda $BC ; A053 A5 BC ..
+ sta (screen_ptr),y ; A055 91 C0 ..
+ inx ; A057 E8 .
+ dey ; A058 88 .
+ bpl LA053 ; A059 10 F8 ..
+ ldy #$00 ; A05B A0 00 ..
+ lda screen_hi_ptrs,y ; A05D B9 00 1E ...
+ sta screen_ptr+1 ; A060 85 C1 ..
+ lda screen_lo_ptrs,y ; A062 B9 00 1D ...
+ sta screen_ptr ; A065 85 C0 ..
+ ldy #$1E ; A067 A0 1E ..
+ lda $BC ; A069 A5 BC ..
+ and #$C0 ; A06B 29 C0 ).
+ sta (screen_ptr),y ; A06D 91 C0 ..
+ dey ; A06F 88 .
+ ldx #$00 ; A070 A2 00 ..
+LA072: lda $BC ; A072 A5 BC ..
+ sta (screen_ptr),y ; A074 91 C0 ..
+ dey ; A076 88 .
+ inx ; A077 E8 .
+ cpx #$14 ; A078 E0 14 ..
+ bcc LA072 ; A07A 90 F6 ..
+ ldy #$01 ; A07C A0 01 ..
+ lda screen_hi_ptrs,y ; A07E B9 00 1E ...
+ sta screen_ptr+1 ; A081 85 C1 ..
+ lda screen_lo_ptrs,y ; A083 B9 00 1D ...
+ sta screen_ptr ; A086 85 C0 ..
+ ldy #$15 ; A088 A0 15 ..
+ lda #$FF ; A08A A9 FF ..
+LA08C: sta (screen_ptr),y ; A08C 91 C0 ..
+ dey ; A08E 88 .
+ cpy #$12 ; A08F C0 12 ..
+ bcs LA08C ; A091 B0 F9 ..
+ ldy #$1C ; A093 A0 1C ..
+ lda screen_hi_ptrs,y ; A095 B9 00 1E ...
+ sta screen_ptr+1 ; A098 85 C1 ..
+ lda screen_lo_ptrs,y ; A09A B9 00 1D ...
+ sta screen_ptr ; A09D 85 C0 ..
+ ldy #$15 ; A09F A0 15 ..
+ lda #$FF ; A0A1 A9 FF ..
+LA0A3: sta (screen_ptr),y ; A0A3 91 C0 ..
+ dey ; A0A5 88 .
+ cpy #$12 ; A0A6 C0 12 ..
+ bcs LA0A3 ; A0A8 B0 F9 ..
+ rts ; A0AA 60 `
+
+; ----------------------------------------------------------------------------
+scanner_border_table:
+ .byte $AA,$55,$FF,$00 ; A0AB AA 55 FF 00 .U..
+; ----------------------------------------------------------------------------
+; draw enemies/humanoids in scanner
+draw_scanner_sprite:
+ sec ; A0AF 38 8
+ lda $DD ; A0B0 A5 DD ..
+ sbc $8D ; A0B2 E5 8D ..
+ sta sprite_x ; A0B4 85 E3 ..
+ lda $DE ; A0B6 A5 DE ..
+ sbc $8E ; A0B8 E5 8E ..
+ sta $E4 ; A0BA 85 E4 ..
+ bcs LA0CA ; A0BC B0 0C ..
+ lda sprite_x ; A0BE A5 E3 ..
+ adc #$80 ; A0C0 69 80 i.
+ sta sprite_x ; A0C2 85 E3 ..
+ lda $E4 ; A0C4 A5 E4 ..
+ adc #$02 ; A0C6 69 02 i.
+ sta $E4 ; A0C8 85 E4 ..
+LA0CA: lsr $E4 ; A0CA 46 E4 F.
+ ror sprite_x ; A0CC 66 E3 f.
+ lsr $E4 ; A0CE 46 E4 F.
+ ror sprite_x ; A0D0 66 E3 f.
+ lsr $E4 ; A0D2 46 E4 F.
+ ror sprite_x ; A0D4 66 E3 f.
+ clc ; A0D6 18 .
+ lda sprite_x ; A0D7 A5 E3 ..
+ adc #$28 ; A0D9 69 28 i(
+ sta sprite_x ; A0DB 85 E3 ..
+ lda sprite_y ; A0DD A5 DF ..
+ lsr a ; A0DF 4A J
+ lsr a ; A0E0 4A J
+ lsr a ; A0E1 4A J
+ tay ; A0E2 A8 .
+ pha ; A0E3 48 H
+ lda screen_hi_ptrs,y ; A0E4 B9 00 1E ...
+ sta screen_ptr+1 ; A0E7 85 C1 ..
+ lda screen_lo_ptrs,y ; A0E9 B9 00 1D ...
+ sta screen_ptr ; A0EC 85 C0 ..
+ ldx sprite_x ; A0EE A6 E3 ..
+ ldy horiz_offset_table,x ; A0F0 BC 00 1B ...
+ lda scanner_colormask ; A0F3 A5 A9 ..
+ and pixel_mask_table,x ; A0F5 3D 00 1C =..
+ ora (screen_ptr),y ; A0F8 11 C0 ..
+ sta (screen_ptr),y ; A0FA 91 C0 ..
+ ldy horiz_offset_table+1,x ; A0FC BC 01 1B ...
+ lda scanner_colormask ; A0FF A5 A9 ..
+ and pixel_mask_table+1,x ; A101 3D 01 1C =..
+ ora (screen_ptr),y ; A104 11 C0 ..
+ sta (screen_ptr),y ; A106 91 C0 ..
+ pla ; A108 68 h
+ tay ; A109 A8 .
+ lda screen_hi_ptrs+1,y ; A10A B9 01 1E ...
+ sta screen_ptr+1 ; A10D 85 C1 ..
+ lda screen_lo_ptrs+1,y ; A10F B9 01 1D ...
+ sta screen_ptr ; A112 85 C0 ..
+ ldy horiz_offset_table,x ; A114 BC 00 1B ...
+ lda scanner_colormask ; A117 A5 A9 ..
+ and pixel_mask_table,x ; A119 3D 00 1C =..
+ ora (screen_ptr),y ; A11C 11 C0 ..
+ sta (screen_ptr),y ; A11E 91 C0 ..
+ ldy horiz_offset_table+1,x ; A120 BC 01 1B ...
+ lda scanner_colormask ; A123 A5 A9 ..
+ and pixel_mask_table+1,x ; A125 3D 01 1C =..
+ ora (screen_ptr),y ; A128 11 C0 ..
+ sta (screen_ptr),y ; A12A 91 C0 ..
+ rts ; A12C 60 `
+
+; ----------------------------------------------------------------------------
+; erase enemies/humanoids in scanner
+erase_scanner_sprite:
+ sec ; A12D 38 8
+ lda $DD ; A12E A5 DD ..
+ sbc $8F ; A130 E5 8F ..
+ sta sprite_x ; A132 85 E3 ..
+ lda $DE ; A134 A5 DE ..
+ sbc $90 ; A136 E5 90 ..
+ sta $E4 ; A138 85 E4 ..
+ bcs LA148 ; A13A B0 0C ..
+ lda sprite_x ; A13C A5 E3 ..
+ adc #$80 ; A13E 69 80 i.
+ sta sprite_x ; A140 85 E3 ..
+ lda $E4 ; A142 A5 E4 ..
+ adc #$02 ; A144 69 02 i.
+ sta $E4 ; A146 85 E4 ..
+LA148: lsr $E4 ; A148 46 E4 F.
+ ror sprite_x ; A14A 66 E3 f.
+ lsr $E4 ; A14C 46 E4 F.
+ ror sprite_x ; A14E 66 E3 f.
+ lsr $E4 ; A150 46 E4 F.
+ ror sprite_x ; A152 66 E3 f.
+ clc ; A154 18 .
+ lda sprite_x ; A155 A5 E3 ..
+ adc #$28 ; A157 69 28 i(
+ sta sprite_x ; A159 85 E3 ..
+ lda sprite_y ; A15B A5 DF ..
+ lsr a ; A15D 4A J
+ lsr a ; A15E 4A J
+ lsr a ; A15F 4A J
+ tay ; A160 A8 .
+ pha ; A161 48 H
+ lda screen_hi_ptrs,y ; A162 B9 00 1E ...
+ sta screen_ptr+1 ; A165 85 C1 ..
+ lda screen_lo_ptrs,y ; A167 B9 00 1D ...
+ sta screen_ptr ; A16A 85 C0 ..
+ ldx sprite_x ; A16C A6 E3 ..
+ ldy horiz_offset_table,x ; A16E BC 00 1B ...
+ lda #$00 ; A171 A9 00 ..
+ sta (screen_ptr),y ; A173 91 C0 ..
+ ldy horiz_offset_table+1,x ; A175 BC 01 1B ...
+ sta (screen_ptr),y ; A178 91 C0 ..
+ pla ; A17A 68 h
+ tay ; A17B A8 .
+ lda screen_hi_ptrs+1,y ; A17C B9 01 1E ...
+ sta screen_ptr+1 ; A17F 85 C1 ..
+ lda screen_lo_ptrs+1,y ; A181 B9 01 1D ...
+ sta screen_ptr ; A184 85 C0 ..
+ ldy horiz_offset_table,x ; A186 BC 00 1B ...
+ lda #$00 ; A189 A9 00 ..
+ sta (screen_ptr),y ; A18B 91 C0 ..
+ ldy horiz_offset_table+1,x ; A18D BC 01 1B ...
+ sta (screen_ptr),y ; A190 91 C0 ..
+ rts ; A192 60 `
+
+; ----------------------------------------------------------------------------
+; draw the player's ship (white cross) in the scanner
+draw_scanner_ship:
+ lda ship_y_pos ; A193 A5 C4 ..
+ lsr a ; A195 4A J
+ lsr a ; A196 4A J
+ lsr a ; A197 4A J
+ sec ; A198 38 8
+ sbc #$01 ; A199 E9 01 ..
+ sta sprite_x ; A19B 85 E3 ..
+ tay ; A19D A8 .
+ lda screen_hi_ptrs,y ; A19E B9 00 1E ...
+ sta screen_ptr+1 ; A1A1 85 C1 ..
+ lda screen_lo_ptrs,y ; A1A3 B9 00 1D ...
+ sta screen_ptr ; A1A6 85 C0 ..
+ lda ship_x_pos ; A1A8 A5 C3 ..
+ lsr a ; A1AA 4A J
+ lsr a ; A1AB 4A J
+ lsr a ; A1AC 4A J
+ clc ; A1AD 18 .
+ adc #$46 ; A1AE 69 46 iF
+ sta $E4 ; A1B0 85 E4 ..
+ tax ; A1B2 AA .
+ ldy horiz_offset_table,x ; A1B3 BC 00 1B ...
+ lda #$FF ; A1B6 A9 FF ..
+ and pixel_mask_table,x ; A1B8 3D 00 1C =..
+ ora (screen_ptr),y ; A1BB 11 C0 ..
+ sta (screen_ptr),y ; A1BD 91 C0 ..
+ ldy sprite_x ; A1BF A4 E3 ..
+ lda screen_hi_ptrs+1,y ; A1C1 B9 01 1E ...
+ sta screen_ptr+1 ; A1C4 85 C1 ..
+ lda screen_lo_ptrs+1,y ; A1C6 B9 01 1D ...
+ sta screen_ptr ; A1C9 85 C0 ..
+ ldx $E4 ; A1CB A6 E4 ..
+ ldy $1AFF,x ; A1CD BC FF 1A ...
+ lda #$FF ; A1D0 A9 FF ..
+ and horiz_offset_table+255,x ; A1D2 3D FF 1B =..
+ ora (screen_ptr),y ; A1D5 11 C0 ..
+ sta (screen_ptr),y ; A1D7 91 C0 ..
+ ldy horiz_offset_table,x ; A1D9 BC 00 1B ...
+ lda #$FF ; A1DC A9 FF ..
+ and pixel_mask_table,x ; A1DE 3D 00 1C =..
+ ora (screen_ptr),y ; A1E1 11 C0 ..
+ sta (screen_ptr),y ; A1E3 91 C0 ..
+ ldy horiz_offset_table+1,x ; A1E5 BC 01 1B ...
+ lda #$FF ; A1E8 A9 FF ..
+ and pixel_mask_table+1,x ; A1EA 3D 01 1C =..
+ ora (screen_ptr),y ; A1ED 11 C0 ..
+ sta (screen_ptr),y ; A1EF 91 C0 ..
+ ldy sprite_x ; A1F1 A4 E3 ..
+ lda screen_hi_ptrs+2,y ; A1F3 B9 02 1E ...
+ sta screen_ptr+1 ; A1F6 85 C1 ..
+ lda screen_lo_ptrs+2,y ; A1F8 B9 02 1D ...
+ sta screen_ptr ; A1FB 85 C0 ..
+ ldx $E4 ; A1FD A6 E4 ..
+ ldy horiz_offset_table,x ; A1FF BC 00 1B ...
+ lda #$FF ; A202 A9 FF ..
+ and pixel_mask_table,x ; A204 3D 00 1C =..
+ ora (screen_ptr),y ; A207 11 C0 ..
+ sta (screen_ptr),y ; A209 91 C0 ..
+ rts ; A20B 60 `
+
+; ----------------------------------------------------------------------------
+; erase the player's ship (white cross) in the scanner
+erase_scanner_ship:
+ lda ship_y_pos ; A20C A5 C4 ..
+ lsr a ; A20E 4A J
+ lsr a ; A20F 4A J
+ lsr a ; A210 4A J
+ sec ; A211 38 8
+ sbc #$01 ; A212 E9 01 ..
+ sta sprite_x ; A214 85 E3 ..
+ tay ; A216 A8 .
+ lda screen_hi_ptrs,y ; A217 B9 00 1E ...
+ sta screen_ptr+1 ; A21A 85 C1 ..
+ lda screen_lo_ptrs,y ; A21C B9 00 1D ...
+ sta screen_ptr ; A21F 85 C0 ..
+ lda ship_x_pos ; A221 A5 C3 ..
+ lsr a ; A223 4A J
+ lsr a ; A224 4A J
+ lsr a ; A225 4A J
+ clc ; A226 18 .
+ adc #$46 ; A227 69 46 iF
+ sta $E4 ; A229 85 E4 ..
+ tax ; A22B AA .
+ ldy horiz_offset_table,x ; A22C BC 00 1B ...
+ lda #$00 ; A22F A9 00 ..
+ sta (screen_ptr),y ; A231 91 C0 ..
+ ldy sprite_x ; A233 A4 E3 ..
+ lda screen_hi_ptrs+1,y ; A235 B9 01 1E ...
+ sta screen_ptr+1 ; A238 85 C1 ..
+ lda screen_lo_ptrs+1,y ; A23A B9 01 1D ...
+ sta screen_ptr ; A23D 85 C0 ..
+ ldx $E4 ; A23F A6 E4 ..
+ ldy $1AFF,x ; A241 BC FF 1A ...
+ lda #$00 ; A244 A9 00 ..
+ sta (screen_ptr),y ; A246 91 C0 ..
+ ldy horiz_offset_table,x ; A248 BC 00 1B ...
+ sta (screen_ptr),y ; A24B 91 C0 ..
+ ldy horiz_offset_table+1,x ; A24D BC 01 1B ...
+ sta (screen_ptr),y ; A250 91 C0 ..
+ ldy sprite_x ; A252 A4 E3 ..
+ lda screen_hi_ptrs+2,y ; A254 B9 02 1E ...
+ sta screen_ptr+1 ; A257 85 C1 ..
+ lda screen_lo_ptrs+2,y ; A259 B9 02 1D ...
+ sta screen_ptr ; A25C 85 C0 ..
+ ldx $E4 ; A25E A6 E4 ..
+ ldy horiz_offset_table,x ; A260 BC 00 1B ...
+ lda #$00 ; A263 A9 00 ..
+ sta (screen_ptr),y ; A265 91 C0 ..
+ rts ; A267 60 `
+
+; ----------------------------------------------------------------------------
+init_work_ram:
+ ldy #$00 ; A268 A0 00 ..
+LA26A: lda #$00 ; A26A A9 00 ..
+ sta sprite_list,y ; A26C 99 EB 0A ...
+ sta sprite_list+128,y ; A26F 99 6B 0B .k.
+ sta enemy_explosion_table,y ; A272 99 2B 05 .+.
+ sta actor_list,y ; A275 99 6B 0C .k.
+ iny ; A278 C8 .
+ bpl LA26A ; A279 10 EF ..
+LA27B: sta actor_list,y ; A27B 99 6B 0C .k.
+ iny ; A27E C8 .
+ cpy #$C0 ; A27F C0 C0 ..
+ bcc LA27B ; A281 90 F8 ..
+ ldx #$00 ; A283 A2 00 ..
+LA285: lda #$00 ; A285 A9 00 ..
+ sta player_shots_y,x ; A287 9D 1A 05 ...
+ inx ; A28A E8 .
+ cpx #$10 ; A28B E0 10 ..
+ bcc LA285 ; A28D 90 F6 ..
+ ldx #$00 ; A28F A2 00 ..
+; copy is done because the code is self-modifying
+copy_code_to_ram:
+ lda draw_sprite_left,x ; A291 BD 7B AA .{.
+ sta draw_sprite_left_copy,x ; A294 9D 00 1F ...
+ lda draw_sprite_right,x ; A297 BD D7 AA ...
+ sta draw_sprite_right_copy,x ; A29A 9D 80 1F ...
+ inx ; A29D E8 .
+ bpl copy_code_to_ram ; A29E 10 F1 ..
+ lda #$2F ; A2A0 A9 2F ./
+ sta tmp_ptr ; A2A2 85 E7 ..
+ lda #$0D ; A2A4 A9 0D ..
+ sta tmp_ptr+1 ; A2A6 85 E8 ..
+ ldy #$00 ; A2A8 A0 00 ..
+clr_ram_sprites_loop:
+ lda #$00 ; A2AA A9 00 ..
+ sta (tmp_ptr),y ; A2AC 91 E7 ..
+ inc tmp_ptr ; A2AE E6 E7 ..
+ bne crsl_ok ; A2B0 D0 02 ..
+ inc tmp_ptr+1 ; A2B2 E6 E8 ..
+crsl_ok:lda tmp_ptr ; A2B4 A5 E7 ..
+ cmp #$2F ; A2B6 C9 2F ./
+ lda tmp_ptr+1 ; A2B8 A5 E8 ..
+ sbc #$14 ; A2BA E9 14 ..
+ bcc clr_ram_sprites_loop ; A2BC 90 EC ..
+ ldx #$00 ; A2BE A2 00 ..
+copy_ram_sprites_loop:
+ lda sprom_humanoid,x ; A2C0 BD B3 A8 ...
+ sta sp_humanoid,x ; A2C3 9D 2F 0D ./.
+ lda sprom_lander_1,x ; A2C6 BD C3 A8 ...
+ sta sp_lander_1,x ; A2C9 9D 6F 0D .o.
+ lda sprom_lander_2,x ; A2CC BD D3 A8 ...
+ sta sp_lander_2,x ; A2CF 9D AF 0D ...
+ lda sprom_mutant_1,x ; A2D2 BD E3 A8 ...
+ sta sp_mutant_1,x ; A2D5 9D EF 0D ...
+ lda sprom_mutant_2,x ; A2D8 BD F3 A8 ...
+ sta sp_mutant_2,x ; A2DB 9D 2F 0E ./.
+ lda sprom_rship_l_1,x ; A2DE BD 03 A9 ...
+ sta sp_rship_l_1,x ; A2E1 9D 6F 0E .o.
+ lda sprom_rship_r_1,x ; A2E4 BD 13 A9 ...
+ sta sp_rship_r_1,x ; A2E7 9D AF 0E ...
+ lda sprom_rship_l_2,x ; A2EA BD 23 A9 .#.
+ sta sp_rship_l_2,x ; A2ED 9D EF 0E ...
+ lda sprom_rship_r_2,x ; A2F0 BD 33 A9 .3.
+ sta sp_rship_r_2,x ; A2F3 9D 2F 0F ./.
+ lda sprom_lship_l_1,x ; A2F6 BD 43 A9 .C.
+ sta sp_lship_l_1,x ; A2F9 9D 6F 0F .o.
+ lda sprom_lship_r_1,x ; A2FC BD 53 A9 .S.
+ sta sp_lship_r_1,x ; A2FF 9D AF 0F ...
+ lda sprom_lship_l_2,x ; A302 BD 63 A9 .c.
+ sta sp_lship_l_2,x ; A305 9D EF 0F ...
+ lda sprom_lship_r_2,x ; A308 BD 73 A9 .s.
+ sta sp_lship_r_2,x ; A30B 9D 2F 10 ./.
+ lda sprom_bullet,x ; A30E BD 83 A9 ...
+ sta sp_bullet,x ; A311 9D 6F 10 .o.
+ lda sprom_bomber_1,x ; A314 BD 93 A9 ...
+ sta sp_bomber_1,x ; A317 9D AF 10 ...
+ lda sprom_bomber_2,x ; A31A BD A3 A9 ...
+ sta sp_bomber_2,x ; A31D 9D EF 10 ...
+ lda sprom_xbomb,x ; A320 BD B3 A9 ...
+ sta sp_xbomb,x ; A323 9D 2F 11 ./.
+ lda sprom_lflame_1,x ; A326 BD E3 A9 ...
+ sta sp_lflame_1,x ; A329 9D 6F 11 .o.
+ lda sprom_lflame_2,x ; A32C BD F3 A9 ...
+ sta sp_lflame_2,x ; A32F 9D AF 11 ...
+ lda sprom_rflame_1,x ; A332 BD C3 A9 ...
+ sta sp_rflame_1,x ; A335 9D EF 11 ...
+ lda sprom_rflame_2,x ; A338 BD D3 A9 ...
+ sta sp_rflame_2,x ; A33B 9D 2F 12 ./.
+ lda sprom_pod_1,x ; A33E BD 03 AA ...
+ sta sp_pod_1,x ; A341 9D 6F 12 .o.
+ lda sprom_pod_2,x ; A344 BD 13 AA ...
+ sta sp_pod_2,x ; A347 9D AF 12 ...
+ lda sprom_swarmer,x ; A34A BD 23 AA .#.
+ sta sp_swarmer,x ; A34D 9D EF 12 ...
+ lda sprom_baiter_l,x ; A350 BD 33 AA .3.
+ sta sp_baiter_l,x ; A353 9D 2F 13 ./.
+ lda sprom_baiter_r,x ; A356 BD 43 AA .C.
+ sta sp_baiter_r,x ; A359 9D 6F 13 .o.
+ lda sprom_smartbomb_1,x ; A35C BD 53 AA .S.
+ sta sp_smartbomb_1,x ; A35F 9D AF 13 ...
+ lda sprom_smartbomb_2,x ; A362 BD 63 AA .c.
+ sta sp_smartbomb_2,x ; A365 9D EF 13 ...
+ inx ; A368 E8 .
+ cpx #$10 ; A369 E0 10 ..
+ bcs preshift_all_sprites ; A36B B0 03 ..
+ jmp copy_ram_sprites_loop ; A36D 4C C0 A2 L..
+
+; ----------------------------------------------------------------------------
+; this is why sprites are copied to RAM: we precalculate right-shifted copies, to speed up drawing
+preshift_all_sprites:
+ lda #$2F ; A370 A9 2F ./
+ sta preshift_ptr ; A372 85 80 ..
+ lda #$0D ; A374 A9 0D ..
+ sta preshift_ptr+1 ; A376 85 81 ..
+ jsr preshift_sprite ; A378 20 9F AB ..
+ lda #$AF ; A37B A9 AF ..
+ sta preshift_ptr ; A37D 85 80 ..
+ lda #$13 ; A37F A9 13 ..
+ sta preshift_ptr+1 ; A381 85 81 ..
+ jsr preshift_sprite ; A383 20 9F AB ..
+ lda #$EF ; A386 A9 EF ..
+ sta preshift_ptr ; A388 85 80 ..
+ lda #$13 ; A38A A9 13 ..
+ sta preshift_ptr+1 ; A38C 85 81 ..
+ jsr preshift_sprite ; A38E 20 9F AB ..
+ lda #$6F ; A391 A9 6F .o
+ sta preshift_ptr ; A393 85 80 ..
+ lda #$10 ; A395 A9 10 ..
+ sta preshift_ptr+1 ; A397 85 81 ..
+ jsr preshift_sprite ; A399 20 9F AB ..
+ lda #$6F ; A39C A9 6F .o
+ sta preshift_ptr ; A39E 85 80 ..
+ lda #$0D ; A3A0 A9 0D ..
+ sta preshift_ptr+1 ; A3A2 85 81 ..
+ jsr preshift_sprite ; A3A4 20 9F AB ..
+ lda #$2F ; A3A7 A9 2F ./
+ sta preshift_ptr ; A3A9 85 80 ..
+ lda #$13 ; A3AB A9 13 ..
+ sta preshift_ptr+1 ; A3AD 85 81 ..
+ jsr preshift_sprite ; A3AF 20 9F AB ..
+ lda #$6F ; A3B2 A9 6F .o
+ sta preshift_ptr ; A3B4 85 80 ..
+ lda #$13 ; A3B6 A9 13 ..
+ sta preshift_ptr+1 ; A3B8 85 81 ..
+ jsr preshift_sprite ; A3BA 20 9F AB ..
+ lda #$AF ; A3BD A9 AF ..
+ sta preshift_ptr ; A3BF 85 80 ..
+ lda #$0D ; A3C1 A9 0D ..
+ sta preshift_ptr+1 ; A3C3 85 81 ..
+ jsr preshift_sprite ; A3C5 20 9F AB ..
+ lda #$EF ; A3C8 A9 EF ..
+ sta preshift_ptr ; A3CA 85 80 ..
+ lda #$0D ; A3CC A9 0D ..
+ sta preshift_ptr+1 ; A3CE 85 81 ..
+ jsr preshift_sprite ; A3D0 20 9F AB ..
+ lda #$2F ; A3D3 A9 2F ./
+ sta preshift_ptr ; A3D5 85 80 ..
+ lda #$0E ; A3D7 A9 0E ..
+ sta preshift_ptr+1 ; A3D9 85 81 ..
+ jsr preshift_sprite ; A3DB 20 9F AB ..
+ lda #$6F ; A3DE A9 6F .o
+ sta preshift_ptr ; A3E0 85 80 ..
+ lda #$0E ; A3E2 A9 0E ..
+ sta preshift_ptr+1 ; A3E4 85 81 ..
+ jsr preshift_sprite ; A3E6 20 9F AB ..
+ lda #$AF ; A3E9 A9 AF ..
+ sta preshift_ptr ; A3EB 85 80 ..
+ lda #$0E ; A3ED A9 0E ..
+ sta preshift_ptr+1 ; A3EF 85 81 ..
+ jsr preshift_sprite ; A3F1 20 9F AB ..
+ lda #$EF ; A3F4 A9 EF ..
+ sta preshift_ptr ; A3F6 85 80 ..
+ lda #$0E ; A3F8 A9 0E ..
+ sta preshift_ptr+1 ; A3FA 85 81 ..
+ jsr preshift_sprite ; A3FC 20 9F AB ..
+ lda #$2F ; A3FF A9 2F ./
+ sta preshift_ptr ; A401 85 80 ..
+ lda #$0F ; A403 A9 0F ..
+ sta preshift_ptr+1 ; A405 85 81 ..
+ jsr preshift_sprite ; A407 20 9F AB ..
+ lda #$6F ; A40A A9 6F .o
+ sta preshift_ptr ; A40C 85 80 ..
+ lda #$0F ; A40E A9 0F ..
+ sta preshift_ptr+1 ; A410 85 81 ..
+ jsr preshift_sprite ; A412 20 9F AB ..
+ lda #$AF ; A415 A9 AF ..
+ sta preshift_ptr ; A417 85 80 ..
+ lda #$0F ; A419 A9 0F ..
+ sta preshift_ptr+1 ; A41B 85 81 ..
+ jsr preshift_sprite ; A41D 20 9F AB ..
+ lda #$EF ; A420 A9 EF ..
+ sta preshift_ptr ; A422 85 80 ..
+ lda #$0F ; A424 A9 0F ..
+ sta preshift_ptr+1 ; A426 85 81 ..
+ jsr preshift_sprite ; A428 20 9F AB ..
+ lda #$2F ; A42B A9 2F ./
+ sta preshift_ptr ; A42D 85 80 ..
+ lda #$10 ; A42F A9 10 ..
+ sta preshift_ptr+1 ; A431 85 81 ..
+ jsr preshift_sprite ; A433 20 9F AB ..
+ lda #$AF ; A436 A9 AF ..
+ sta preshift_ptr ; A438 85 80 ..
+ lda #$10 ; A43A A9 10 ..
+ sta preshift_ptr+1 ; A43C 85 81 ..
+ jsr preshift_sprite ; A43E 20 9F AB ..
+ lda #$EF ; A441 A9 EF ..
+ sta preshift_ptr ; A443 85 80 ..
+ lda #$10 ; A445 A9 10 ..
+ sta preshift_ptr+1 ; A447 85 81 ..
+ jsr preshift_sprite ; A449 20 9F AB ..
+ lda #$2F ; A44C A9 2F ./
+ sta preshift_ptr ; A44E 85 80 ..
+ lda #$11 ; A450 A9 11 ..
+ sta preshift_ptr+1 ; A452 85 81 ..
+ jsr preshift_sprite ; A454 20 9F AB ..
+ lda #$6F ; A457 A9 6F .o
+ sta preshift_ptr ; A459 85 80 ..
+ lda #$11 ; A45B A9 11 ..
+ sta preshift_ptr+1 ; A45D 85 81 ..
+ jsr preshift_sprite ; A45F 20 9F AB ..
+ lda #$AF ; A462 A9 AF ..
+ sta preshift_ptr ; A464 85 80 ..
+ lda #$11 ; A466 A9 11 ..
+ sta preshift_ptr+1 ; A468 85 81 ..
+ jsr preshift_sprite ; A46A 20 9F AB ..
+ lda #$EF ; A46D A9 EF ..
+ sta preshift_ptr ; A46F 85 80 ..
+ lda #$11 ; A471 A9 11 ..
+ sta preshift_ptr+1 ; A473 85 81 ..
+ jsr preshift_sprite ; A475 20 9F AB ..
+ lda #$2F ; A478 A9 2F ./
+ sta preshift_ptr ; A47A 85 80 ..
+ lda #$12 ; A47C A9 12 ..
+ sta preshift_ptr+1 ; A47E 85 81 ..
+ jsr preshift_sprite ; A480 20 9F AB ..
+ lda #$6F ; A483 A9 6F .o
+ sta preshift_ptr ; A485 85 80 ..
+ lda #$12 ; A487 A9 12 ..
+ sta preshift_ptr+1 ; A489 85 81 ..
+ jsr preshift_sprite ; A48B 20 9F AB ..
+ lda #$AF ; A48E A9 AF ..
+ sta preshift_ptr ; A490 85 80 ..
+ lda #$12 ; A492 A9 12 ..
+ sta preshift_ptr+1 ; A494 85 81 ..
+ jsr preshift_sprite ; A496 20 9F AB ..
+ lda #$EF ; A499 A9 EF ..
+ sta preshift_ptr ; A49B 85 80 ..
+ lda #$12 ; A49D A9 12 ..
+ sta preshift_ptr+1 ; A49F 85 81 ..
+ jsr preshift_sprite ; A4A1 20 9F AB ..
+ rts ; A4A4 60 `
+
+; ----------------------------------------------------------------------------
+; search for an empty slot. if found, add current_sprite to list, return with carry clear. if no empty slot, return with carry set.
+add_to_sprite_list:
+ ldy #$00 ; A4A5 A0 00 ..
+asl_next:
+ lda sprite_list,y ; A4A7 B9 EB 0A ...
+ beq asl_slot_found ; A4AA F0 0A ..
+ tya ; A4AC 98 .
+ clc ; A4AD 18 .
+ adc #$04 ; A4AE 69 04 i.
+ tay ; A4B0 A8 .
+ cpy #$80 ; A4B1 C0 80 ..
+ bcc asl_next ; A4B3 90 F2 ..
+ rts ; A4B5 60 `
+
+; ----------------------------------------------------------------------------
+asl_slot_found:
+ lda sprite_y ; A4B6 A5 DF ..
+ sta sprite_list,y ; A4B8 99 EB 0A ...
+ lda $DD ; A4BB A5 DD ..
+ sta sprite_list+1,y ; A4BD 99 EC 0A ...
+ lda $DE ; A4C0 A5 DE ..
+ sta sprite_list+2,y ; A4C2 99 ED 0A ...
+ lda current_sprite ; A4C5 A5 F9 ..
+ sta sprite_list+3,y ; A4C7 99 EE 0A ...
+ clc ; A4CA 18 .
+ rts ; A4CB 60 `
+
+; ----------------------------------------------------------------------------
+LA4CC: lda #$7C ; A4CC A9 7C .|
+ sta $98 ; A4CE 85 98 ..
+ lda #$00 ; A4D0 A9 00 ..
+ sta enemy_count ; A4D2 85 9C ..
+ sta humanoid_count ; A4D4 85 A1 ..
+ sta $A2 ; A4D6 85 A2 ..
+ inc animation_counter ; A4D8 E6 85 ..
+ jmp LA520 ; A4DA 4C 20 A5 L .
+
+; ----------------------------------------------------------------------------
+LA4DD: lda $98 ; A4DD A5 98 ..
+ sec ; A4DF 38 8
+ sbc #$04 ; A4E0 E9 04 ..
+ sta $98 ; A4E2 85 98 ..
+ bpl LA520 ; A4E4 10 3A .:
+ bit ship_dead_flag ; A4E6 24 EF $.
+ bpl LA4ED ; A4E8 10 03 ..
+ jmp start_player_death ; A4EA 4C 4C B6 LL.
+
+; ----------------------------------------------------------------------------
+LA4ED: lda game_type ; A4ED A5 E1 ..
+ beq LA4F6 ; A4EF F0 05 ..
+ bit invuln_flag ; A4F1 24 ED $.
+ bpl LA4F6 ; A4F3 10 01 ..
+ rts ; A4F5 60 `
+
+; ----------------------------------------------------------------------------
+LA4F6: lda enemy_count ; A4F6 A5 9C ..
+ ora landers_to_spawn ; A4F8 05 9B ..
+ ora baiter_count ; A4FA 05 9D ..
+ bne LA509 ; A4FC D0 0B ..
+ jsr clear_baiters ; A4FE 20 6D B8 m.
+ jsr clear_temp_enemies ; A501 20 69 B7 i.
+ pla ; A504 68 h
+ pla ; A505 68 h
+ jmp next_level ; A506 4C C9 83 L..
+
+; ----------------------------------------------------------------------------
+LA509: lda planet_dead_flag ; A509 A5 A0 ..
+ bmi LA51F ; A50B 30 12 0.
+ lda humanoid_count ; A50D A5 A1 ..
+ bne LA51F ; A50F D0 0E ..
+ jsr clear_temp_enemies ; A511 20 69 B7 i.
+ jsr destroy_planet ; A514 20 0A 9E ..
+ sec ; A517 38 8
+ ror planet_dead_flag ; A518 66 A0 f.
+ pla ; A51A 68 h
+ pla ; A51B 68 h
+ jmp L8465 ; A51C 4C 65 84 Le.
+
+; ----------------------------------------------------------------------------
+LA51F: rts ; A51F 60 `
+
+; ----------------------------------------------------------------------------
+LA520: ldy $98 ; A520 A4 98 ..
+ lda sprite_list,y ; A522 B9 EB 0A ...
+ beq LA4DD ; A525 F0 B6 ..
+ sta sprite_y ; A527 85 DF ..
+ lda sprite_list+1,y ; A529 B9 EC 0A ...
+ sta $DD ; A52C 85 DD ..
+ lda sprite_list+2,y ; A52E B9 ED 0A ...
+ sta $DE ; A531 85 DE ..
+ lda sprite_list+3,y ; A533 B9 EE 0A ...
+ sta current_sprite ; A536 85 F9 ..
+ and #$07 ; A538 29 07 ).
+ cmp #$03 ; A53A C9 03 ..
+ beq LA556 ; A53C F0 18 ..
+ lda animation_counter ; A53E A5 85 ..
+ and #$03 ; A540 29 03 ).
+ asl a ; A542 0A .
+ asl a ; A543 0A .
+ asl a ; A544 0A .
+ sta sprite_x ; A545 85 E3 ..
+ lda current_sprite ; A547 A5 F9 ..
+ and #$07 ; A549 29 07 ).
+ adc sprite_x ; A54B 65 E3 e.
+ tay ; A54D A8 .
+ lda scanner_colormask_table,y ; A54E B9 92 A5 ...
+ sta scanner_colormask ; A551 85 A9 ..
+ jsr erase_scanner_sprite ; A553 20 2D A1 -.
+LA556: jsr erase_sprite_XXX ; A556 20 86 A7 ..
+ bcs LA56D ; A559 B0 12 ..
+ lda current_sprite ; A55B A5 F9 ..
+ cmp #$07 ; A55D C9 07 ..
+ bne LA56D ; A55F D0 0C ..
+; no other enemy is a double-wide sprite, is it?
+erase_baiter_right_half:
+ lda sprite_x ; A561 A5 E3 ..
+ clc ; A563 18 .
+ adc #$05 ; A564 69 05 i.
+ sta sprite_x ; A566 85 E3 ..
+ bcs LA56D ; A568 B0 03 ..
+ jsr erase_sprite ; A56A 20 2C AB ,.
+LA56D: lda current_sprite ; A56D A5 F9 ..
+ and #$07 ; A56F 29 07 ).
+ asl a ; A571 0A .
+ tay ; A572 A8 .
+ lda jump_table,y ; A573 B9 82 A5 ...
+ sta trampoline ; A576 85 A7 ..
+ lda jump_table+1,y ; A578 B9 83 A5 ...
+ sta trampoline+1 ; A57B 85 A8 ..
+ ldy $98 ; A57D A4 98 ..
+ jmp (trampoline) ; A57F 6C A7 00 l..
+
+; ----------------------------------------------------------------------------
+jump_table:
+ .addr spawn_humanoid ; A582 E6 AE ..
+ .addr spawn_lander ; A584 8E B0 ..
+ .addr spawn_mutant ; A586 F4 B2 ..
+ .addr spawn_enemy_shot ; A588 86 9B ..
+ .addr spawn_bomber ; A58A F1 B3 ..
+ .addr spawn_pod ; A58C 85 B4 ..
+ .addr spawn_swarmer ; A58E A5 B4 ..
+ .addr spawn_baiter ; A590 D4 BA ..
+; ----------------------------------------------------------------------------
+scanner_colormask_table:
+ .byte $FF,$55,$AA,$00,$FF,$AA,$AA,$55 ; A592 FF 55 AA 00 FF AA AA 55 .U.....U
+ .byte $FF,$55,$55,$00,$AA,$FF,$AA,$FF ; A59A FF 55 55 00 AA FF AA FF .UU.....
+ .byte $FF,$55,$AA,$00,$FF,$55,$AA,$55 ; A5A2 FF 55 AA 00 FF 55 AA 55 .U...U.U
+ .byte $FF,$55,$55,$00,$AA,$FF,$AA,$FF ; A5AA FF 55 55 00 AA FF AA FF .UU.....
+; ----------------------------------------------------------------------------
+LA5B2: sec ; A5B2 38 8
+ lda $DD ; A5B3 A5 DD ..
+ sbc $89 ; A5B5 E5 89 ..
+ sta sprite_x ; A5B7 85 E3 ..
+ lda $DE ; A5B9 A5 DE ..
+ sbc $8A ; A5BB E5 8A ..
+ sta $E4 ; A5BD 85 E4 ..
+ bcs LA5CD ; A5BF B0 0C ..
+ lda sprite_x ; A5C1 A5 E3 ..
+ adc #$80 ; A5C3 69 80 i.
+ sta sprite_x ; A5C5 85 E3 ..
+ lda $E4 ; A5C7 A5 E4 ..
+ adc #$02 ; A5C9 69 02 i.
+ sta $E4 ; A5CB 85 E4 ..
+LA5CD: lda $DE ; A5CD A5 DE ..
+ bmi LA5EB ; A5CF 30 1A 0.
+ lda $DD ; A5D1 A5 DD ..
+ cmp #$80 ; A5D3 C9 80 ..
+ lda $DE ; A5D5 A5 DE ..
+ sbc #$02 ; A5D7 E9 02 ..
+ bcc LA5F8 ; A5D9 90 1D ..
+ sec ; A5DB 38 8
+ lda $DD ; A5DC A5 DD ..
+ sbc #$80 ; A5DE E9 80 ..
+ sta $DD ; A5E0 85 DD ..
+ lda $DE ; A5E2 A5 DE ..
+ sbc #$02 ; A5E4 E9 02 ..
+ sta $DE ; A5E6 85 DE ..
+ jmp LA5F8 ; A5E8 4C F8 A5 L..
+
+; ----------------------------------------------------------------------------
+LA5EB: clc ; A5EB 18 .
+ lda $DD ; A5EC A5 DD ..
+ adc #$80 ; A5EE 69 80 i.
+ sta $DD ; A5F0 85 DD ..
+ lda $DE ; A5F2 A5 DE ..
+ adc #$02 ; A5F4 69 02 i.
+ sta $DE ; A5F6 85 DE ..
+LA5F8: ldy $98 ; A5F8 A4 98 ..
+ lda sprite_y ; A5FA A5 DF ..
+ sta sprite_list,y ; A5FC 99 EB 0A ...
+ lda $DD ; A5FF A5 DD ..
+ sta sprite_list+1,y ; A601 99 EC 0A ...
+ lda $DE ; A604 A5 DE ..
+ sta sprite_list+2,y ; A606 99 ED 0A ...
+ lda current_sprite ; A609 A5 F9 ..
+ sta sprite_list+3,y ; A60B 99 EE 0A ...
+ lda current_sprite ; A60E A5 F9 ..
+ and #$07 ; A610 29 07 ).
+ cmp #$03 ; A612 C9 03 ..
+ beq LA629 ; A614 F0 13 ..
+ ldx #$00 ; A616 A2 00 ..
+LA618: lda player_shots_y,x ; A618 BD 1A 05 ...
+ bne LA645 ; A61B D0 28 .(
+LA61D: txa ; A61D 8A .
+ clc ; A61E 18 .
+ adc #$04 ; A61F 69 04 i.
+ tax ; A621 AA .
+ cpx #$10 ; A622 E0 10 ..
+ bcc LA618 ; A624 90 F2 ..
+ jsr draw_scanner_sprite ; A626 20 AF A0 ..
+LA629: jsr draw_sprite ; A629 20 49 A7 I.
+ bcs LA642 ; A62C B0 14 ..
+ lda current_sprite ; A62E A5 F9 ..
+ cmp #$07 ; A630 C9 07 ..
+ bne LA642 ; A632 D0 0E ..
+ lda sprite_x ; A634 A5 E3 ..
+ clc ; A636 18 .
+ adc #$05 ; A637 69 05 i.
+ sta sprite_x ; A639 85 E3 ..
+ bcs LA642 ; A63B B0 05 ..
+ lda #$19 ; A63D A9 19 ..
+ jsr draw_sprite_right_copy ; A63F 20 80 1F ..
+LA642: jmp LA4DD ; A642 4C DD A4 L..
+
+; ----------------------------------------------------------------------------
+LA645: lda sprite_y ; A645 A5 DF ..
+ cmp player_shots_y,x ; A647 DD 1A 05 ...
+ bcs LA61D ; A64A B0 D1 ..
+ adc #$08 ; A64C 69 08 i.
+ cmp player_shots_y,x ; A64E DD 1A 05 ...
+ bcc LA61D ; A651 90 CA ..
+ lda $E4 ; A653 A5 E4 ..
+ bne LA61D ; A655 D0 C6 ..
+ lda sprite_x ; A657 A5 E3 ..
+ cmp #$A0 ; A659 C9 A0 ..
+ bcs LA61D ; A65B B0 C0 ..
+ lda player_shots_delta,x ; A65D BD 1D 05 ...
+ bpl LA676 ; A660 10 14 ..
+ lda sprite_x ; A662 A5 E3 ..
+ cmp player_shots_x_start,x ; A664 DD 1B 05 ...
+ bcs LA673 ; A667 B0 0A ..
+ lda player_shots_x_end,x ; A669 BD 1C 05 ...
+ clc ; A66C 18 .
+ adc #$01 ; A66D 69 01 i.
+ cmp sprite_x ; A66F C5 E3 ..
+ bcc LA687 ; A671 90 14 ..
+LA673: jmp LA61D ; A673 4C 1D A6 L..
+
+; ----------------------------------------------------------------------------
+LA676: lda sprite_x ; A676 A5 E3 ..
+ cmp player_shots_x_start,x ; A678 DD 1B 05 ...
+ bcc LA673 ; A67B 90 F6 ..
+ lda player_shots_x_end,x ; A67D BD 1C 05 ...
+ sec ; A680 38 8
+ sbc #$01 ; A681 E9 01 ..
+ cmp sprite_x ; A683 C5 E3 ..
+ bcc LA673 ; A685 90 EC ..
+LA687: lda #$00 ; A687 A9 00 ..
+ sta player_shots_x_end,x ; A689 9D 1C 05 ...
+ lda current_sprite ; A68C A5 F9 ..
+ cmp #$05 ; A68E C9 05 ..
+ bne LA698 ; A690 D0 06 ..
+ jsr spawn_swarmers ; A692 20 11 A7 ..
+ jmp LA6BB ; A695 4C BB A6 L..
+
+; ----------------------------------------------------------------------------
+LA698: cmp #$11 ; A698 C9 11 ..
+ bne LA6BB ; A69A D0 1F ..
+ ldy $98 ; A69C A4 98 ..
+ lda sprite_list+128,y ; A69E B9 6B 0B .k.
+ tay ; A6A1 A8 .
+ lda sprite_list,y ; A6A2 B9 EB 0A ...
+ beq LA6BB ; A6A5 F0 14 ..
+ lda sprite_list+3,y ; A6A7 B9 EE 0A ...
+ cmp #$08 ; A6AA C9 08 ..
+ bne LA6BB ; A6AC D0 0D ..
+ lda #$10 ; A6AE A9 10 ..
+ sta sprite_list+3,y ; A6B0 99 EE 0A ...
+ lda #$00 ; A6B3 A9 00 ..
+ sta sprite_list+128,y ; A6B5 99 6B 0B .k.
+ jsr play_fall ; A6B8 20 08 8E ..
+LA6BB: lda sprite_x ; A6BB A5 E3 ..
+ sta $C9 ; A6BD 85 C9 ..
+ lda sprite_y ; A6BF A5 DF ..
+ clc ; A6C1 18 .
+ adc #$04 ; A6C2 69 04 i.
+ sta $CA ; A6C4 85 CA ..
+ lda #$01 ; A6C6 A9 01 ..
+ sta $CB ; A6C8 85 CB ..
+ ldy $98 ; A6CA A4 98 ..
+ lda #$00 ; A6CC A9 00 ..
+ sta sprite_list,y ; A6CE 99 EB 0A ...
+ lda current_sprite ; A6D1 A5 F9 ..
+ and #$07 ; A6D3 29 07 ).
+ beq LA6FF ; A6D5 F0 28 .(
+ cmp #$05 ; A6D7 C9 05 ..
+ beq LA6F3 ; A6D9 F0 18 ..
+ cmp #$07 ; A6DB C9 07 ..
+ beq LA6ED ; A6DD F0 0E ..
+ cmp #$06 ; A6DF C9 06 ..
+ beq LA6F9 ; A6E1 F0 16 ..
+ cmp #$04 ; A6E3 C9 04 ..
+ bne LA705 ; A6E5 D0 1E ..
+ jsr play_lander_died ; A6E7 20 B4 8D ..
+ jmp LA708 ; A6EA 4C 08 A7 L..
+
+; ----------------------------------------------------------------------------
+LA6ED: jsr play_baiter_died ; A6ED 20 C2 8D ..
+ jmp LA708 ; A6F0 4C 08 A7 L..
+
+; ----------------------------------------------------------------------------
+LA6F3: jsr play_pod_died ; A6F3 20 D0 8D ..
+ jmp LA708 ; A6F6 4C 08 A7 L..
+
+; ----------------------------------------------------------------------------
+LA6F9: jsr play_swarmer_died ; A6F9 20 A6 8D ..
+ jmp LA708 ; A6FC 4C 08 A7 L..
+
+; ----------------------------------------------------------------------------
+LA6FF: jsr play_human_died ; A6FF 20 24 8E $.
+ jmp LA708 ; A702 4C 08 A7 L..
+
+; ----------------------------------------------------------------------------
+LA705: jsr play_lander_died ; A705 20 B4 8D ..
+LA708: jsr start_enemy_explosion ; A708 20 E7 9B ..
+ jsr add_cursprite_points ; A70B 20 AE A7 ..
+ jmp LA4DD ; A70E 4C DD A4 L..
+
+; ----------------------------------------------------------------------------
+; called when a pod dies
+spawn_swarmers:
+ lda sprite_y ; A711 A5 DF ..
+ pha ; A713 48 H
+ sec ; A714 38 8
+ sbc #$12 ; A715 E9 12 ..
+ sta sprite_y ; A717 85 DF ..
+ cmp #$20 ; A719 C9 20 .
+ bcs LA721 ; A71B B0 04 ..
+ lda #$20 ; A71D A9 20 .
+ sta sprite_y ; A71F 85 DF ..
+LA721: lda #$06 ; A721 A9 06 ..
+ sta current_sprite ; A723 85 F9 ..
+LA725: pha ; A725 48 H
+ jsr add_to_sprite_list ; A726 20 A5 A4 ..
+ bcs LA734 ; A729 B0 09 ..
+ jsr get_random ; A72B 20 F2 8C ..
+ sta sprite_list+128,y ; A72E 99 6B 0B .k.
+ sta sprite_list+129,y ; A731 99 6C 0B .l.
+LA734: clc ; A734 18 .
+ lda sprite_y ; A735 A5 DF ..
+ adc #$06 ; A737 69 06 i.
+ sta sprite_y ; A739 85 DF ..
+ pla ; A73B 68 h
+ sec ; A73C 38 8
+ sbc #$01 ; A73D E9 01 ..
+ bne LA725 ; A73F D0 E4 ..
+ pla ; A741 68 h
+ sta sprite_y ; A742 85 DF ..
+ lda #$05 ; A744 A9 05 ..
+ sta current_sprite ; A746 85 F9 ..
+ rts ; A748 60 `
+
+; ----------------------------------------------------------------------------
+; draw enemies/humanoids in playfield. return with carry set if there's a ship collision (player died), else clear.
+draw_sprite:
+ sec ; A749 38 8
+ lda $DD ; A74A A5 DD ..
+ sbc $89 ; A74C E5 89 ..
+ sta sprite_x ; A74E 85 E3 ..
+ lda $DE ; A750 A5 DE ..
+ sbc $8A ; A752 E5 8A ..
+ sta $E4 ; A754 85 E4 ..
+ bcs LA764 ; A756 B0 0C ..
+ lda sprite_x ; A758 A5 E3 ..
+ adc #$80 ; A75A 69 80 i.
+ sta sprite_x ; A75C 85 E3 ..
+ lda $E4 ; A75E A5 E4 ..
+ adc #$02 ; A760 69 02 i.
+ sta $E4 ; A762 85 E4 ..
+LA764: lda $E4 ; A764 A5 E4 ..
+ bne LA784 ; A766 D0 1C ..
+ lda sprite_x ; A768 A5 E3 ..
+ cmp #$A0 ; A76A C9 A0 ..
+ bcs LA784 ; A76C B0 16 ..
+ lda current_sprite ; A76E A5 F9 ..
+ and #$07 ; A770 29 07 ).
+ beq LA77F ; A772 F0 0B ..
+ lda sprite_x ; A774 A5 E3 ..
+ pha ; A776 48 H
+ jsr check_ship_collision ; A777 20 FB B5 ..
+ pla ; A77A 68 h
+ sta sprite_x ; A77B 85 E3 ..
+ bcs LA784 ; A77D B0 05 ..
+LA77F: lda $88 ; A77F A5 88 ..
+ jmp draw_sprite_left_copy ; A781 4C 00 1F L..
+
+; ----------------------------------------------------------------------------
+LA784: sec ; A784 38 8
+ rts ; A785 60 `
+
+; ----------------------------------------------------------------------------
+; XXX wrapper for erase_sprite, dunno why yet
+erase_sprite_XXX:
+ sec ; A786 38 8
+ lda $DD ; A787 A5 DD ..
+ sbc $8B ; A789 E5 8B ..
+ sta sprite_x ; A78B 85 E3 ..
+ lda $DE ; A78D A5 DE ..
+ sbc $8C ; A78F E5 8C ..
+ sta $E4 ; A791 85 E4 ..
+ bcs LA7A1 ; A793 B0 0C ..
+ lda sprite_x ; A795 A5 E3 ..
+ adc #$80 ; A797 69 80 i.
+ sta sprite_x ; A799 85 E3 ..
+ lda $E4 ; A79B A5 E4 ..
+ adc #$02 ; A79D 69 02 i.
+ sta $E4 ; A79F 85 E4 ..
+LA7A1: lda $E4 ; A7A1 A5 E4 ..
+ bne LA784 ; A7A3 D0 DF ..
+ lda sprite_x ; A7A5 A5 E3 ..
+ cmp #$A0 ; A7A7 C9 A0 ..
+ bcs LA784 ; A7A9 B0 D9 ..
+ jmp erase_sprite ; A7AB 4C 2C AB L,.
+
+; ----------------------------------------------------------------------------
+; add points to score based on what kind of enemy we killed. does not include points for rescued humans nor end-of-level bonus.
+add_cursprite_points:
+ lda current_sprite ; A7AE A5 F9 ..
+ and #$07 ; A7B0 29 07 ).
+; this entry point takes a sprite type in A, used for end-of-level bonus (and...?)
+add_points:
+ asl a ; A7B2 0A .
+ tay ; A7B3 A8 .
+ clc ; A7B4 18 .
+ lda score_points_table,y ; A7B5 B9 FD A7 ...
+ adc score ; A7B8 6D 2F 14 m/.
+ sta score ; A7BB 8D 2F 14 ./.
+ cmp #$64 ; A7BE C9 64 .d
+ bcc LA7CA ; A7C0 90 08 ..
+ sbc #$64 ; A7C2 E9 64 .d
+ sta score ; A7C4 8D 2F 14 ./.
+ inc score+1 ; A7C7 EE 30 14 .0.
+LA7CA: clc ; A7CA 18 .
+ lda score_points_table+1,y ; A7CB B9 FE A7 ...
+ adc score+1 ; A7CE 6D 30 14 m0.
+ sta score+1 ; A7D1 8D 30 14 .0.
+ cmp #$64 ; A7D4 C9 64 .d
+; if score+1 rolled over $63 => 0, we passed 10K points. note that *all* changes to the score pass through here, so this check is always done.
+check_extra_life:
+ bcc aep_done ; A7D6 90 22 ."
+ sbc #$64 ; A7D8 E9 64 .d
+ sta score+1 ; A7DA 8D 30 14 .0.
+ inc score+2 ; A7DD EE 31 14 .1.
+ txa ; A7E0 8A .
+ pha ; A7E1 48 H
+ jsr play_extra_life ; A7E2 20 5C 8E \.
+ pla ; A7E5 68 h
+ tax ; A7E6 AA .
+ inc lives ; A7E7 E6 9E ..
+ inc smartbombs ; A7E9 E6 A5 ..
+ lda score+2 ; A7EB AD 31 14 .1.
+ cmp #$64 ; A7EE C9 64 .d
+ bcc aep_done ; A7F0 90 08 ..
+ sbc #$64 ; A7F2 E9 64 .d
+ sta score+2 ; A7F4 8D 31 14 .1.
+ inc score+3 ; A7F7 EE 32 14 .2.
+aep_done:
+ lsr $AD ; A7FA 46 AD F.
+ rts ; A7FC 60 `
+
+; ----------------------------------------------------------------------------
+; binary base 100. msb first (unlike score!). 0132 = 100*$01+$32 = 150 decimal. order: human (0), lander (150), mutant (150), enemy shot or bomber bomb (25, only by colliding with ship), bomber (250), pod (1000), swarmer (200), baiter (200), rest are bonus
+score_points_table:
+ .word $0000,$0132,$0132,$0019 ; A7FD 00 00 32 01 32 01 19 00 ..2.2...
+ .word $0232,$0A00,$0200,$0200 ; A805 32 02 00 0A 00 02 00 02 2.......
+ .word $0100,$0200,$0300,$0400 ; A80D 00 01 00 02 00 03 00 04 ........
+ .word $0500 ; A815 00 05 ..
+; ----------------------------------------------------------------------------
+LA817: ldy #$00 ; A817 A0 00 ..
+LA819: jsr get_random ; A819 20 F2 8C ..
+ and #$7F ; A81C 29 7F ).
+ adc #$20 ; A81E 69 20 i
+ sta $0C2B,y ; A820 99 2B 0C .+.
+ jsr get_random ; A823 20 F2 8C ..
+ and #$7F ; A826 29 7F ).
+ sta $0C2C,y ; A828 99 2C 0C .,.
+ iny ; A82B C8 .
+ iny ; A82C C8 .
+ cpy #$20 ; A82D C0 20 .
+ bcc LA819 ; A82F 90 E8 ..
+ rts ; A831 60 `
+
+; ----------------------------------------------------------------------------
+; XXX don't know how this works yet
+draw_starfield:
+ jsr get_random ; A832 20 F2 8C ..
+ lda $95 ; A835 A5 95 ..
+ clc ; A837 18 .
+ adc #$02 ; A838 69 02 i.
+ sta $95 ; A83A 85 95 ..
+ cmp #$20 ; A83C C9 20 .
+ bcc LA844 ; A83E 90 04 ..
+ lda #$00 ; A840 A9 00 ..
+ sta $95 ; A842 85 95 ..
+LA844: ldy $95 ; A844 A4 95 ..
+ lda $0C2B,y ; A846 B9 2B 0C .+.
+ sta sprite_y ; A849 85 DF ..
+ ldx $0C2C,y ; A84B BE 2C 0C .,.
+ stx $DD ; A84E 86 DD ..
+ tay ; A850 A8 .
+ lda screen_hi_ptrs,y ; A851 B9 00 1E ...
+ sta screen_ptr+1 ; A854 85 C1 ..
+ lda screen_lo_ptrs,y ; A856 B9 00 1D ...
+ sta screen_ptr ; A859 85 C0 ..
+ lda #$00 ; A85B A9 00 ..
+ ldy horiz_offset_table,x ; A85D BC 00 1B ...
+ sta (screen_ptr),y ; A860 91 C0 ..
+ lda $95 ; A862 A5 95 ..
+ and #$02 ; A864 29 02 ).
+ bne LA874 ; A866 D0 0C ..
+ lda random_seed+1 ; A868 A5 C7 ..
+ and #$1F ; A86A 29 1F ).
+ bne LA874 ; A86C D0 06 ..
+ lda random_seed ; A86E A5 C6 ..
+ and #$7F ; A870 29 7F ).
+ sta $DD ; A872 85 DD ..
+LA874: lda ship_delta ; A874 A5 D5 ..
+ bpl LA88C ; A876 10 14 ..
+ eor #$FF ; A878 49 FF I.
+ clc ; A87A 18 .
+ adc #$01 ; A87B 69 01 i.
+ adc $DD ; A87D 65 DD e.
+ sta $DD ; A87F 85 DD ..
+ cmp #$A0 ; A881 C9 A0 ..
+ bcc LA899 ; A883 90 14 ..
+ sbc #$A0 ; A885 E9 A0 ..
+ sta $DD ; A887 85 DD ..
+ jmp LA899 ; A889 4C 99 A8 L..
+
+; ----------------------------------------------------------------------------
+LA88C: lda $DD ; A88C A5 DD ..
+ sec ; A88E 38 8
+ sbc ship_delta ; A88F E5 D5 ..
+ sta $DD ; A891 85 DD ..
+ bcs LA899 ; A893 B0 04 ..
+ adc #$A0 ; A895 69 A0 i.
+ sta $DD ; A897 85 DD ..
+LA899: ldy $95 ; A899 A4 95 ..
+ lda $DD ; A89B A5 DD ..
+ sta $0C2C,y ; A89D 99 2C 0C .,.
+ lda random_seed ; A8A0 A5 C6 ..
+ and #$07 ; A8A2 29 07 ).
+ beq LA8B2 ; A8A4 F0 0C ..
+ ldx $DD ; A8A6 A6 DD ..
+ lda random_seed ; A8A8 A5 C6 ..
+ and pixel_mask_table,x ; A8AA 3D 00 1C =..
+ ldy horiz_offset_table,x ; A8AD BC 00 1B ...
+ sta (screen_ptr),y ; A8B0 91 C0 ..
+LA8B2: rts ; A8B2 60 `
+
+; ----------------------------------------------------------------------------
+; single-wide, non-animated, copied to $0d2f
+sprom_humanoid:
+ .byte $28,$00,$28,$00,$14,$00,$14,$00 ; A8B3 28 00 28 00 14 00 14 00 (.(.....
+ .byte $14,$00,$0C,$00,$0C,$00,$0C,$00 ; A8BB 14 00 0C 00 0C 00 0C 00 ........
+; single-wide, animated, copied to $0d6f
+sprom_lander_1:
+ .byte $00,$00,$15,$00,$44,$40,$44,$40 ; A8C3 00 00 15 00 44 40 44 40 ....D@D@
+ .byte $15,$00,$04,$00,$15,$00,$44,$40 ; A8CB 15 00 04 00 15 00 44 40 ......D@
+; copied to $0daf
+sprom_lander_2:
+ .byte $1F,$00,$15,$00,$51,$40,$51,$40 ; A8D3 1F 00 15 00 51 40 51 40 ....Q@Q@
+ .byte $15,$00,$04,$00,$15,$00,$44,$40 ; A8DB 15 00 04 00 15 00 44 40 ......D@
+; single-wide, animated, copied to $0def
+sprom_mutant_1:
+ .byte $3C,$00,$3D,$00,$6A,$40,$6A,$40 ; A8E3 3C 00 3D 00 6A 40 6A 40 <.=.j@j@
+ .byte $6A,$40,$2A,$00,$19,$00,$48,$40 ; A8EB 6A 40 2A 00 19 00 48 40 j@*...H@
+; copied to $0e2f
+sprom_mutant_2:
+ .byte $00,$00,$11,$00,$6A,$40,$6A,$40 ; A8F3 00 00 11 00 6A 40 6A 40 ....j@j@
+ .byte $6A,$40,$2A,$00,$19,$00,$48,$40 ; A8FB 6A 40 2A 00 19 00 48 40 j@*...H@
+; right-facing ship, double-wide, animated, copied to $0e6f
+sprom_rship_l_1:
+ .byte $30,$00,$F4,$00,$EC,$00,$AF,$80 ; A903 30 00 F4 00 EC 00 AF 80 0.......
+ .byte $EB,$80,$AB,$C0,$EB,$C0,$AF,$C0 ; A90B EB 80 AB C0 EB C0 AF C0 ........
+; copied to $0eaf
+sprom_rship_r_1:
+ .byte $00,$00,$00,$00,$00,$00,$88,$00 ; A913 00 00 00 00 00 00 88 00 ........
+ .byte $88,$00,$FF,$C0,$FC,$00,$00,$00 ; A91B 88 00 FF C0 FC 00 00 00 ........
+; copied to $0eef
+sprom_rship_l_2:
+ .byte $30,$00,$F4,$00,$BC,$00,$EF,$80 ; A923 30 00 F4 00 BC 00 EF 80 0.......
+ .byte $AB,$80,$EA,$C0,$AB,$C0,$AF,$C0 ; A92B AB 80 EA C0 AB C0 AF C0 ........
+; copied to $0f2f
+sprom_rship_r_2:
+ .byte $00,$00,$00,$00,$00,$00,$20,$00 ; A933 00 00 00 00 00 00 20 00 ...... .
+ .byte $28,$00,$FF,$C0,$FC,$00,$00,$00 ; A93B 28 00 FF C0 FC 00 00 00 (.......
+; left-facing ship, double-wide, animated, copied to $0f6f
+sprom_lship_l_1:
+ .byte $00,$00,$00,$00,$00,$00,$08,$80 ; A943 00 00 00 00 00 00 08 80 ........
+ .byte $08,$80,$FF,$C0,$0F,$C0,$00,$00 ; A94B 08 80 FF C0 0F C0 00 00 ........
+; copied to $0faf
+sprom_lship_r_1:
+ .byte $03,$00,$07,$C0,$0E,$C0,$BE,$80 ; A953 03 00 07 C0 0E C0 BE 80 ........
+ .byte $BA,$C0,$FA,$80,$FA,$C0,$FE,$80 ; A95B BA C0 FA 80 FA C0 FE 80 ........
+; copied to $0fef
+sprom_lship_l_2:
+ .byte $00,$00,$00,$00,$00,$00,$02,$00 ; A963 00 00 00 00 00 00 02 00 ........
+ .byte $0A,$00,$FF,$C0,$0F,$C0,$00,$00 ; A96B 0A 00 FF C0 0F C0 00 00 ........
+; copied to $102f
+sprom_lship_r_2:
+ .byte $03,$00,$07,$C0,$0E,$C0,$0F,$80 ; A973 03 00 07 C0 0E C0 0F 80 ........
+ .byte $BA,$80,$FA,$C0,$FA,$80,$FE,$80 ; A97B BA 80 FA C0 FA 80 FE 80 ........
+; enemy shot, single-wide, non-animated, copied to $106f
+sprom_bullet:
+ .byte $30,$00,$FC,$00,$FC,$00,$30,$00 ; A983 30 00 FC 00 FC 00 30 00 0.....0.
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; A98B 00 00 00 00 00 00 00 00 ........
+; single-wide, animated, copied to $10af
+sprom_bomber_1:
+ .byte $2A,$80,$2A,$80,$80,$80,$8C,$80 ; A993 2A 80 2A 80 80 80 8C 80 *.*.....
+ .byte $8C,$80,$82,$80,$AA,$00,$00,$00 ; A99B 8C 80 82 80 AA 00 00 00 ........
+; copied to $10ef
+sprom_bomber_2:
+ .byte $2A,$80,$2A,$80,$FE,$80,$CE,$80 ; A9A3 2A 80 2A 80 FE 80 CE 80 *.*.....
+ .byte $CE,$80,$FE,$80,$AA,$00,$00,$00 ; A9AB CE 80 FE 80 AA 00 00 00 ........
+; bomber's bomb, single-wide, non-animated, copied to $112f
+sprom_xbomb:
+ .byte $44,$00,$10,$00,$44,$00,$00,$00 ; A9B3 44 00 10 00 44 00 00 00 D...D...
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; A9BB 00 00 00 00 00 00 00 00 ........
+; player's exhaust flame, right-facing, single-wide, animated, copied to $11ef
+sprom_rflame_1:
+ .byte $00,$00,$02,$80,$0A,$80,$2A,$C0 ; A9C3 00 00 02 80 0A 80 2A C0 ......*.
+ .byte $AB,$00,$2A,$C0,$0A,$80,$02,$80 ; A9CB AB 00 2A C0 0A 80 02 80 ..*.....
+; copied to $122f
+sprom_rflame_2:
+ .byte $00,$00,$00,$00,$00,$00,$0A,$00 ; A9D3 00 00 00 00 00 00 0A 00 ........
+ .byte $22,$00,$0A,$00,$00,$00,$00,$00 ; A9DB 22 00 0A 00 00 00 00 00 ".......
+; player's exhaust flame, left-facing, single-wide, animated, copied to $116f
+sprom_lflame_1:
+ .byte $00,$00,$A0,$00,$A8,$00,$EA,$00 ; A9E3 00 00 A0 00 A8 00 EA 00 ........
+ .byte $3A,$80,$EA,$00,$A8,$00,$A0,$00 ; A9EB 3A 80 EA 00 A8 00 A0 00 :.......
+; copied to $11af
+sprom_lflame_2:
+ .byte $00,$00,$00,$00,$00,$00,$28,$00 ; A9F3 00 00 00 00 00 00 28 00 ......(.
+ .byte $22,$00,$28,$00,$00,$00,$00,$00 ; A9FB 22 00 28 00 00 00 00 00 ".(.....
+; single-wide, animated, copied to $126f
+sprom_pod_1:
+ .byte $C8,$C0,$2A,$00,$2A,$00,$AE,$80 ; AA03 C8 C0 2A 00 2A 00 AE 80 ..*.*...
+ .byte $2A,$00,$2A,$00,$C8,$C0,$00,$00 ; AA0B 2A 00 2A 00 C8 C0 00 00 *.*.....
+; copied to $12af
+sprom_pod_2:
+ .byte $0C,$00,$AA,$80,$AE,$80,$E2,$C0 ; AA13 0C 00 AA 80 AE 80 E2 C0 ........
+ .byte $AE,$80,$AA,$80,$0C,$00,$00,$00 ; AA1B AE 80 AA 80 0C 00 00 00 ........
+; single-wide, non-animated, copied to $12ef
+sprom_swarmer:
+ .byte $08,$00,$2A,$00,$96,$80,$2A,$00 ; AA23 08 00 2A 00 96 80 2A 00 ..*...*.
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; AA2B 00 00 00 00 00 00 00 00 ........
+; double-wide, non-animated, copied to $132f
+sprom_baiter_l:
+ .byte $01,$40,$08,$00,$28,$80,$55,$40 ; AA33 01 40 08 00 28 80 55 40 .@..(.U@
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; AA3B 00 00 00 00 00 00 00 00 ........
+; copied to $136f
+sprom_baiter_r:
+ .byte $50,$00,$88,$00,$8A,$00,$55,$40 ; AA43 50 00 88 00 8A 00 55 40 P.....U@
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; AA4B 00 00 00 00 00 00 00 00 ........
+; single-wide, animated, copied to $13af
+sprom_smartbomb_1:
+ .byte $3C,$C0,$A3,$00,$3C,$C0,$00,$00 ; AA53 3C C0 A3 00 3C C0 00 00 <...<...
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; AA5B 00 00 00 00 00 00 00 00 ........
+; copied to $13ef
+sprom_smartbomb_2:
+ .byte $3C,$C0,$03,$00,$3C,$C0,$00,$00 ; AA63 3C C0 03 00 3C C0 00 00 <...<...
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; AA6B 00 00 00 00 00 00 00 00 ........
+; XXX what (if anything) is this used for?
+table_aa73:
+ .byte $02,$BB,$5A,$30,$5F,$EE,$3D,$A8 ; AA73 02 BB 5A 30 5F EE 3D A8 ..Z0_.=.
+; ----------------------------------------------------------------------------
+; draw left half of ship, enemy, projectile, bomb, human. copied to RAM at draw_sprite_left_copy and called there.
+draw_sprite_left:
+ asl a ; AA7B 0A .
+ tay ; AA7C A8 .
+ lda sprite_ram_addrs,y ; AA7D B9 57 AB .W.
+; modify operands of (the RAM copies of) instructions marked with HERE
+dsl_selfmod_lo:
+ sta draw_sprite_left_copy+67 ; AA80 8D 43 1F .C.
+ sta draw_sprite_left_copy+77 ; AA83 8D 4D 1F .M.
+ lda sprite_ram_addrs+1,y ; AA86 B9 58 AB .X.
+; modify operands of (the RAM copies of) instructions marked with HERE
+dsl_selfmod_hi:
+ sta draw_sprite_left_copy+68 ; AA89 8D 44 1F .D.
+ sta draw_sprite_left_copy+78 ; AA8C 8D 4E 1F .N.
+ lda sprite_y ; AA8F A5 DF ..
+ sta tmp_y ; AA91 85 82 ..
+ ldx sprite_x ; AA93 A6 E3 ..
+ lda horiz_offset_table,x ; AA95 BD 00 1B ...
+ sta tmp_hoffset_l ; AA98 85 83 ..
+ lda horiz_offset_table+4,x ; AA9A BD 04 1B ...
+ sta tmp_hoffset_r ; AA9D 85 B8 ..
+ ldy offset_index_table,x ; AA9F BC 00 1A ...
+ ldx sprite_table_offsets,y ; AAA2 BE 8F AB ...
+ lda current_sprite ; AAA5 A5 F9 ..
+ and #$07 ; AAA7 29 07 ).
+ tay ; AAA9 A8 .
+ lda sprite_heights,y ; AAAA B9 97 AB ...
+ sta tmp_height ; AAAD 85 84 ..
+dsl_loop:
+ ldy tmp_y ; AAAF A4 82 ..
+ lda screen_hi_ptrs,y ; AAB1 B9 00 1E ...
+ sta screen_ptr+1 ; AAB4 85 C1 ..
+ lda screen_lo_ptrs,y ; AAB6 B9 00 1D ...
+ sta screen_ptr ; AAB9 85 C0 ..
+ ldy tmp_hoffset_l ; AABB A4 83 ..
+; operand gets modified
+dsl_HERE_1:
+ lda sprom_humanoid,x ; AABD BD B3 A8 ...
+ ora (screen_ptr),y ; AAC0 11 C0 ..
+ sta (screen_ptr),y ; AAC2 91 C0 ..
+ ldy tmp_hoffset_r ; AAC4 A4 B8 ..
+ inx ; AAC6 E8 .
+; operand gets modified
+dsl_HERE_2:
+ lda sprom_humanoid,x ; AAC7 BD B3 A8 ...
+ ora (screen_ptr),y ; AACA 11 C0 ..
+ sta (screen_ptr),y ; AACC 91 C0 ..
+ inx ; AACE E8 .
+ inc tmp_y ; AACF E6 82 ..
+ dec tmp_height ; AAD1 C6 84 ..
+ bne dsl_loop ; AAD3 D0 DA ..
+ clc ; AAD5 18 .
+ rts ; AAD6 60 `
+
+; ----------------------------------------------------------------------------
+; draw right half of ship, enemy, projectile, bomb, human. copied to RAM at draw_sprite_right_copy and called there.
+draw_sprite_right:
+ asl a ; AAD7 0A .
+ tay ; AAD8 A8 .
+ lda sprite_ram_addrs,y ; AAD9 B9 57 AB .W.
+; modify operands of (the RAM copies of) instructions marked with HERE
+dsr_selfmod_lo:
+ sta draw_sprite_right_copy+61 ; AADC 8D BD 1F ...
+ sta draw_sprite_right_copy+71 ; AADF 8D C7 1F ...
+ lda sprite_ram_addrs+1,y ; AAE2 B9 58 AB .X.
+; modify operands of (the RAM copies of) instructions marked with HERE
+dsr_selfmod_hi:
+ sta draw_sprite_right_copy+62 ; AAE5 8D BE 1F ...
+ sta draw_sprite_right_copy+72 ; AAE8 8D C8 1F ...
+ lda sprite_y ; AAEB A5 DF ..
+ sta tmp_y ; AAED 85 82 ..
+ ldx sprite_x ; AAEF A6 E3 ..
+ lda horiz_offset_table,x ; AAF1 BD 00 1B ...
+ sta tmp_hoffset_l ; AAF4 85 83 ..
+ lda horiz_offset_table+4,x ; AAF6 BD 04 1B ...
+ sta tmp_hoffset_r ; AAF9 85 B8 ..
+ ldy offset_index_table,x ; AAFB BC 00 1A ...
+ ldx sprite_table_offsets,y ; AAFE BE 8F AB ...
+ lda #$08 ; AB01 A9 08 ..
+ sta tmp_height ; AB03 85 84 ..
+dsr_loop:
+ ldy tmp_y ; AB05 A4 82 ..
+ lda screen_hi_ptrs,y ; AB07 B9 00 1E ...
+ sta screen_ptr+1 ; AB0A 85 C1 ..
+ lda screen_lo_ptrs,y ; AB0C B9 00 1D ...
+ sta screen_ptr ; AB0F 85 C0 ..
+ ldy tmp_hoffset_l ; AB11 A4 83 ..
+; operand gets modified
+dsr_HERE_1:
+ lda sprom_humanoid,x ; AB13 BD B3 A8 ...
+ ora (screen_ptr),y ; AB16 11 C0 ..
+ sta (screen_ptr),y ; AB18 91 C0 ..
+ ldy tmp_hoffset_r ; AB1A A4 B8 ..
+ inx ; AB1C E8 .
+; operand gets modified
+dsr_HERE_2:
+ lda sprom_humanoid,x ; AB1D BD B3 A8 ...
+ ora (screen_ptr),y ; AB20 11 C0 ..
+ sta (screen_ptr),y ; AB22 91 C0 ..
+ inx ; AB24 E8 .
+ inc tmp_y ; AB25 E6 82 ..
+ dec tmp_height ; AB27 C6 84 ..
+ bne dsr_loop ; AB29 D0 DA ..
+ rts ; AB2B 60 `
+
+; ----------------------------------------------------------------------------
+; zero out memory to avoid leaving trails
+erase_sprite:
+ ldx sprite_y ; AB2C A6 DF ..
+ lda current_sprite ; AB2E A5 F9 ..
+ and #$07 ; AB30 29 07 ).
+ tay ; AB32 A8 .
+ lda sprite_heights,y ; AB33 B9 97 AB ...
+ sta tmp_height ; AB36 85 84 ..
+ ldy sprite_x ; AB38 A4 E3 ..
+ lda horiz_offset_table,y ; AB3A B9 00 1B ...
+ tay ; AB3D A8 .
+LAB3E: lda screen_hi_ptrs,x ; AB3E BD 00 1E ...
+ sta screen_ptr+1 ; AB41 85 C1 ..
+ lda screen_lo_ptrs,x ; AB43 BD 00 1D ...
+ sta screen_ptr ; AB46 85 C0 ..
+ lda #$00 ; AB48 A9 00 ..
+ sta (screen_ptr),y ; AB4A 91 C0 ..
+ iny ; AB4C C8 .
+ sta (screen_ptr),y ; AB4D 91 C0 ..
+ dey ; AB4F 88 .
+ inx ; AB50 E8 .
+ dec tmp_height ; AB51 C6 84 ..
+ bne LAB3E ; AB53 D0 E9 ..
+ clc ; AB55 18 .
+ rts ; AB56 60 `
+
+; ----------------------------------------------------------------------------
+; used by draw_sprite_(left|right)
+sprite_ram_addrs:
+ .addr sp_humanoid ; AB57 2F 0D /.
+ .addr sp_lander_1 ; AB59 6F 0D o.
+ .addr sp_lander_2 ; AB5B AF 0D ..
+ .addr sp_mutant_1 ; AB5D EF 0D ..
+ .addr sp_mutant_2 ; AB5F 2F 0E /.
+ .addr sp_rship_l_1 ; AB61 6F 0E o.
+ .addr sp_rship_r_1 ; AB63 AF 0E ..
+ .addr sp_rship_l_2 ; AB65 EF 0E ..
+ .addr sp_rship_r_2 ; AB67 2F 0F /.
+ .addr sp_lship_l_1 ; AB69 6F 0F o.
+ .addr sp_lship_r_1 ; AB6B AF 0F ..
+ .addr sp_lship_l_2 ; AB6D EF 0F ..
+ .addr sp_lship_r_2 ; AB6F 2F 10 /.
+ .addr sp_bullet ; AB71 6F 10 o.
+ .addr sp_bomber_1 ; AB73 AF 10 ..
+ .addr sp_bomber_2 ; AB75 EF 10 ..
+ .addr sp_xbomb ; AB77 2F 11 /.
+ .addr sp_lflame_1 ; AB79 6F 11 o.
+ .addr sp_lflame_2 ; AB7B AF 11 ..
+ .addr sp_rflame_1 ; AB7D EF 11 ..
+ .addr sp_rflame_2 ; AB7F 2F 12 /.
+ .addr sp_pod_1 ; AB81 6F 12 o.
+ .addr sp_pod_2 ; AB83 AF 12 ..
+ .addr sp_swarmer ; AB85 EF 12 ..
+ .addr sp_baiter_l ; AB87 2F 13 /.
+ .addr sp_baiter_r ; AB89 6F 13 o.
+ .addr sp_smartbomb_1 ; AB8B AF 13 ..
+ .addr sp_smartbomb_2 ; AB8D EF 13 ..
+; ----------------------------------------------------------------------------
+; basically just a mul-by-16 table
+sprite_table_offsets:
+ .byte $00,$10,$20,$30,$40,$50,$60,$70 ; AB8F 00 10 20 30 40 50 60 70 .. 0@P`p
+; used to avoid drawing extra empty sprite rows, if they're shorter than full height
+sprite_heights:
+ .byte $08,$08,$08,$04,$07,$07,$04,$04 ; AB97 08 08 08 04 07 07 04 04 ........
+; ----------------------------------------------------------------------------
+; create right-shifted copy of a sprite, 1-3 pixels, at sp_x+$10, sp_x+$20, sp_x+$30
+preshift_sprite:
+ ldx #$00 ; AB9F A2 00 ..
+ lda #$01 ; ABA1 A9 01 ..
+ sta sprite_x ; ABA3 85 E3 ..
+ ldy #$00 ; ABA5 A0 00 ..
+LABA7: lda (preshift_ptr),y ; ABA7 B1 80 ..
+ sta pss_temp,x ; ABA9 9D 4B 0C .K.
+ iny ; ABAC C8 .
+ inx ; ABAD E8 .
+ cpx #$10 ; ABAE E0 10 ..
+ bcc LABA7 ; ABB0 90 F5 ..
+LABB2: lda #$08 ; ABB2 A9 08 ..
+ sta tmp_height ; ABB4 85 84 ..
+ lda #$02 ; ABB6 A9 02 ..
+ sta tmp_y ; ABB8 85 82 ..
+ jsr LABD9 ; ABBA 20 D9 AB ..
+ ldy sprite_x ; ABBD A4 E3 ..
+ lda sprite_table_offsets,y ; ABBF B9 8F AB ...
+ tay ; ABC2 A8 .
+ ldx #$00 ; ABC3 A2 00 ..
+LABC5: lda pss_temp,x ; ABC5 BD 4B 0C .K.
+ sta (preshift_ptr),y ; ABC8 91 80 ..
+ iny ; ABCA C8 .
+ inx ; ABCB E8 .
+ cpx #$10 ; ABCC E0 10 ..
+ bcc LABC5 ; ABCE 90 F5 ..
+ inc sprite_x ; ABD0 E6 E3 ..
+ lda sprite_x ; ABD2 A5 E3 ..
+ cmp #$04 ; ABD4 C9 04 ..
+ bcc LABB2 ; ABD6 90 DA ..
+ rts ; ABD8 60 `
+
+; ----------------------------------------------------------------------------
+LABD9: ldx #$00 ; ABD9 A2 00 ..
+LABDB: ldy #$02 ; ABDB A0 02 ..
+LABDD: lsr pss_temp,x ; ABDD 5E 4B 0C ^K.
+ ror $0C4C,x ; ABE0 7E 4C 0C ~L.
+ dey ; ABE3 88 .
+ bne LABDD ; ABE4 D0 F7 ..
+ inx ; ABE6 E8 .
+ inx ; ABE7 E8 .
+ dec tmp_height ; ABE8 C6 84 ..
+ bne LABDB ; ABEA D0 EF ..
+ rts ; ABEC 60 `
+
+; ----------------------------------------------------------------------------
+; XXX does this apply to humanoids too?
+spawn_sprite:
+ ldy #$00 ; ABED A0 00 ..
+LABEF: lda actor_list,y ; ABEF B9 6B 0C .k.
+ beq LABFE ; ABF2 F0 0A ..
+ tya ; ABF4 98 .
+ clc ; ABF5 18 .
+ adc #$06 ; ABF6 69 06 i.
+ tay ; ABF8 A8 .
+ cpy #$C0 ; ABF9 C0 C0 ..
+ bcc LABEF ; ABFB 90 F2 ..
+ rts ; ABFD 60 `
+
+; ----------------------------------------------------------------------------
+LABFE: lda sprite_y ; ABFE A5 DF ..
+ sta actor_list,y ; AC00 99 6B 0C .k.
+ lda $DD ; AC03 A5 DD ..
+ sta actor_list+1,y ; AC05 99 6C 0C .l.
+ lda $DE ; AC08 A5 DE ..
+ sta actor_list+2,y ; AC0A 99 6D 0C .m.
+ lda current_sprite ; AC0D A5 F9 ..
+ sta actor_list+3,y ; AC0F 99 6E 0C .n.
+ lda #$30 ; AC12 A9 30 .0
+ sta actor_list+4,y ; AC14 99 6F 0C .o.
+ rts ; AC17 60 `
+
+; ----------------------------------------------------------------------------
+LAC18: lda #$00 ; AC18 A9 00 ..
+ sta $86 ; AC1A 85 86 ..
+ sta baiter_count ; AC1C 85 9D ..
+ jmp LAC2D ; AC1E 4C 2D AC L-.
+
+; ----------------------------------------------------------------------------
+LAC21: lda $86 ; AC21 A5 86 ..
+ clc ; AC23 18 .
+ adc #$06 ; AC24 69 06 i.
+ sta $86 ; AC26 85 86 ..
+ cmp #$C0 ; AC28 C9 C0 ..
+ bcc LAC2D ; AC2A 90 01 ..
+ rts ; AC2C 60 `
+
+; ----------------------------------------------------------------------------
+LAC2D: ldy $86 ; AC2D A4 86 ..
+ lda actor_list,y ; AC2F B9 6B 0C .k.
+ beq LAC21 ; AC32 F0 ED ..
+ sta $CA ; AC34 85 CA ..
+ lda actor_list+3,y ; AC36 B9 6E 0C .n.
+ and #$07 ; AC39 29 07 ).
+ cmp #$07 ; AC3B C9 07 ..
+ beq LAC41 ; AC3D F0 02 ..
+ inc baiter_count ; AC3F E6 9D ..
+LAC41: sec ; AC41 38 8
+ lda actor_list+1,y ; AC42 B9 6C 0C .l.
+ sbc $8B ; AC45 E5 8B ..
+ sta sprite_x ; AC47 85 E3 ..
+ lda actor_list+2,y ; AC49 B9 6D 0C .m.
+ sbc $8C ; AC4C E5 8C ..
+ sta $E4 ; AC4E 85 E4 ..
+ bcs LAC5E ; AC50 B0 0C ..
+ lda sprite_x ; AC52 A5 E3 ..
+ adc #$80 ; AC54 69 80 i.
+ sta sprite_x ; AC56 85 E3 ..
+ lda $E4 ; AC58 A5 E4 ..
+ adc #$02 ; AC5A 69 02 i.
+ sta $E4 ; AC5C 85 E4 ..
+LAC5E: lda $E4 ; AC5E A5 E4 ..
+ bne LAC74 ; AC60 D0 12 ..
+ lda sprite_x ; AC62 A5 E3 ..
+ cmp #$A0 ; AC64 C9 A0 ..
+ bcs LAC74 ; AC66 B0 0C ..
+ lda sprite_x ; AC68 A5 E3 ..
+ sta $C9 ; AC6A 85 C9 ..
+ lda actor_list+4,y ; AC6C B9 6F 0C .o.
+ sta $CB ; AC6F 85 CB ..
+ jsr L9C6C ; AC71 20 6C 9C l.
+LAC74: ldx $86 ; AC74 A6 86 ..
+ lda actor_list+4,x ; AC76 BD 6F 0C .o.
+ sec ; AC79 38 8
+ sbc #$04 ; AC7A E9 04 ..
+ sta actor_list+4,x ; AC7C 9D 6F 0C .o.
+ bne LACA7 ; AC7F D0 26 .&
+ lda actor_list,x ; AC81 BD 6B 0C .k.
+ sta sprite_y ; AC84 85 DF ..
+ lda #$00 ; AC86 A9 00 ..
+ sta actor_list,x ; AC88 9D 6B 0C .k.
+ lda actor_list+1,x ; AC8B BD 6C 0C .l.
+ sta $DD ; AC8E 85 DD ..
+ lda actor_list+2,x ; AC90 BD 6D 0C .m.
+ sta $DE ; AC93 85 DE ..
+ lda actor_list+3,x ; AC95 BD 6E 0C .n.
+ sta current_sprite ; AC98 85 F9 ..
+ jsr add_to_sprite_list ; AC9A 20 A5 A4 ..
+ bcs LACA4 ; AC9D B0 05 ..
+ lda #$00 ; AC9F A9 00 ..
+ sta sprite_list+128,y ; ACA1 99 6B 0B .k.
+LACA4: jmp LAC21 ; ACA4 4C 21 AC L!.
+
+; ----------------------------------------------------------------------------
+LACA7: sec ; ACA7 38 8
+ lda actor_list+1,x ; ACA8 BD 6C 0C .l.
+ sbc $89 ; ACAB E5 89 ..
+ sta sprite_x ; ACAD 85 E3 ..
+ lda actor_list+2,x ; ACAF BD 6D 0C .m.
+ sbc $8A ; ACB2 E5 8A ..
+ sta $E4 ; ACB4 85 E4 ..
+ bcs LACC4 ; ACB6 B0 0C ..
+ lda sprite_x ; ACB8 A5 E3 ..
+ adc #$80 ; ACBA 69 80 i.
+ sta sprite_x ; ACBC 85 E3 ..
+ lda $E4 ; ACBE A5 E4 ..
+ adc #$02 ; ACC0 69 02 i.
+ sta $E4 ; ACC2 85 E4 ..
+LACC4: lda $E4 ; ACC4 A5 E4 ..
+ bne LACDA ; ACC6 D0 12 ..
+ lda sprite_x ; ACC8 A5 E3 ..
+ cmp #$A0 ; ACCA C9 A0 ..
+ bcs LACDA ; ACCC B0 0C ..
+ lda sprite_x ; ACCE A5 E3 ..
+ sta $C9 ; ACD0 85 C9 ..
+ lda actor_list+4,x ; ACD2 BD 6F 0C .o.
+ sta $CB ; ACD5 85 CB ..
+ jsr L9C62 ; ACD7 20 62 9C b.
+LACDA: jmp LAC21 ; ACDA 4C 21 AC L!.
+
+; ----------------------------------------------------------------------------
+ ldy #$00 ; ACDD A0 00 ..
+LACDF: lda #$30 ; ACDF A9 30 .0
+ sta actor_list+4,y ; ACE1 99 6F 0C .o.
+ tya ; ACE4 98 .
+ clc ; ACE5 18 .
+ adc #$06 ; ACE6 69 06 i.
+ tay ; ACE8 A8 .
+ cpy #$C0 ; ACE9 C0 C0 ..
+ bcc LACDF ; ACEB 90 F2 ..
+ rts ; ACED 60 `
+
+; ----------------------------------------------------------------------------
+; returns with carry clear if the ship moved, set if not. only checks one axis per call (vert or horiz). XXX magic constants and unknown locations used!
+check_ship_move:
+ inc vert_horiz_flag ; ACEE EE 2C 0D .,.
+ lda vert_horiz_flag ; ACF1 AD 2C 0D .,.
+ and #$01 ; ACF4 29 01 ).
+ php ; ACF6 08 .
+ tax ; ACF7 AA .
+ jsr read_joystick ; ACF8 20 B0 AD ..
+ plp ; ACFB 28 (
+ beq check_horiz_move ; ACFC F0 03 ..
+ jmp check_vert_move ; ACFE 4C 85 AD L..
+
+; ----------------------------------------------------------------------------
+; check for right (a&$08) or left (a&$04) movement. remember Y holds the result of read_joystick (inverted PORT(A|B) value)
+check_horiz_move:
+ lsr exhaust_flag ; AD01 4E 2B 0D N+.
+ tya ; AD04 98 .
+ and #$0C ; AD05 29 0C ).
+ cmp #$08 ; AD07 C9 08 ..
+ beq thrust_right ; AD09 F0 1E ..
+ cmp #$04 ; AD0B C9 04 ..
+ bne thrust_left ; AD0D D0 55 .U
+ inc inertia_counter ; AD0F EE 2D 0D .-.
+ lda inertia_counter ; AD12 AD 2D 0D .-.
+ and #$01 ; AD15 29 01 ).
+ bne apply_thrust ; AD17 D0 28 .(
+ ldx horiz_acceleration ; AD19 AE 2E 0D ...
+ dex ; AD1C CA .
+ stx horiz_acceleration ; AD1D 8E 2E 0D ...
+ bpl apply_thrust ; AD20 10 1F ..
+ inx ; AD22 E8 .
+ stx horiz_acceleration ; AD23 8E 2E 0D ...
+ jmp apply_thrust ; AD26 4C 41 AD LA.
+
+; ----------------------------------------------------------------------------
+thrust_right:
+ inc inertia_counter ; AD29 EE 2D 0D .-.
+ lda inertia_counter ; AD2C AD 2D 0D .-.
+ and #$01 ; AD2F 29 01 ).
+ bne apply_thrust ; AD31 D0 0E ..
+ ldx horiz_acceleration ; AD33 AE 2E 0D ...
+ inx ; AD36 E8 .
+ stx horiz_acceleration ; AD37 8E 2E 0D ...
+ cpx #$0F ; AD3A E0 0F ..
+ bcc apply_thrust ; AD3C 90 03 ..
+ dec horiz_acceleration ; AD3E CE 2E 0D ...
+apply_thrust:
+ ldx horiz_acceleration ; AD41 AE 2E 0D ...
+ lda accel_table,x ; AD44 BD A0 AD ...
+ sta ship_delta ; AD47 85 D5 ..
+ tya ; AD49 98 .
+ and #$0C ; AD4A 29 0C ).
+ cmp #$08 ; AD4C C9 08 ..
+ beq return_right ; AD4E F0 0C ..
+ cmp #$04 ; AD50 C9 04 ..
+ bne return_carry_set ; AD52 D0 4A .J
+ lda #$88 ; AD54 A9 88 ..
+ sec ; AD56 38 8
+ ror exhaust_flag ; AD57 6E 2B 0D n+.
+ clc ; AD5A 18 .
+ rts ; AD5B 60 `
+
+; ----------------------------------------------------------------------------
+return_right:
+ lda #$95 ; AD5C A9 95 ..
+ sec ; AD5E 38 8
+ ror exhaust_flag ; AD5F 6E 2B 0D n+.
+ clc ; AD62 18 .
+ rts ; AD63 60 `
+
+; ----------------------------------------------------------------------------
+thrust_left:
+ inc inertia_counter ; AD64 EE 2D 0D .-.
+ lda inertia_counter ; AD67 AD 2D 0D .-.
+ and #$03 ; AD6A 29 03 ).
+ bne apply_thrust ; AD6C D0 D3 ..
+ ldx horiz_acceleration ; AD6E AE 2E 0D ...
+ cpx #$07 ; AD71 E0 07 ..
+ beq apply_thrust ; AD73 F0 CC ..
+ bcc thrust_ok ; AD75 90 07 ..
+ dex ; AD77 CA .
+ stx horiz_acceleration ; AD78 8E 2E 0D ...
+ jmp apply_thrust ; AD7B 4C 41 AD LA.
+
+; ----------------------------------------------------------------------------
+thrust_ok:
+ inx ; AD7E E8 .
+ stx horiz_acceleration ; AD7F 8E 2E 0D ...
+ jmp apply_thrust ; AD82 4C 41 AD LA.
+
+; ----------------------------------------------------------------------------
+; check for down (a&$02) or up (a&$01) movement
+check_vert_move:
+ tya ; AD85 98 .
+ and #$03 ; AD86 29 03 ).
+ cmp #$02 ; AD88 C9 02 ..
+ beq move_down ; AD8A F0 08 ..
+ cmp #$01 ; AD8C C9 01 ..
+ bne no_vert_move ; AD8E D0 08 ..
+; XXX how does this work?
+move_up:clc ; AD90 18 .
+ lda #$C1 ; AD91 A9 C1 ..
+ rts ; AD93 60 `
+
+; ----------------------------------------------------------------------------
+; XXX how does this work?
+move_down:
+ lda #$DA ; AD94 A9 DA ..
+ clc ; AD96 18 .
+ rts ; AD97 60 `
+
+; ----------------------------------------------------------------------------
+; ship not moving up or down XXX how does this work?
+no_vert_move:
+ lda #$00 ; AD98 A9 00 ..
+ sta $E9 ; AD9A 85 E9 ..
+ sta $EA ; AD9C 85 EA ..
+return_carry_set:
+ sec ; AD9E 38 8
+ rts ; AD9F 60 `
+
+; ----------------------------------------------------------------------------
+; used for accelerating/decelarating the ship
+accel_table:
+ .byte $FA,$FB,$FC,$FD,$FE,$FF,$FF,$00 ; ADA0 FA FB FC FD FE FF FF 00 ........
+ .byte $01,$01,$02,$03,$04,$05,$06,$00 ; ADA8 01 01 02 03 04 05 06 00 ........
+; ----------------------------------------------------------------------------
+; result in A and Y. notice it's inverted.
+read_joystick:
+ lda current_player ; ADB0 A5 F1 ..
+ cmp #$02 ; ADB2 C9 02 ..
+ beq read_joystick_p2 ; ADB4 F0 09 ..
+ lda PORTA ; ADB6 AD 00 D3 ...
+ and #$0F ; ADB9 29 0F ).
+ eor #$0F ; ADBB 49 0F I.
+ tay ; ADBD A8 .
+ rts ; ADBE 60 `
+
+; ----------------------------------------------------------------------------
+read_joystick_p2:
+ lda PORTA ; ADBF AD 00 D3 ...
+ lsr a ; ADC2 4A J
+ lsr a ; ADC3 4A J
+ lsr a ; ADC4 4A J
+ lsr a ; ADC5 4A J
+ eor #$0F ; ADC6 49 0F I.
+ tay ; ADC8 A8 .
+ rts ; ADC9 60 `
+
+; ----------------------------------------------------------------------------
+ lda $11,x ; ADCA B5 11 ..
+ cmp $1437,x ; ADCC DD 37 14 .7.
+ bcc LADD6 ; ADCF 90 05 ..
+ sta $1437,x ; ADD1 9D 37 14 .7.
+ bcs LADDE ; ADD4 B0 08 ..
+LADD6: cmp $1433,x ; ADD6 DD 33 14 .3.
+ bcs LADDE ; ADD9 B0 03 ..
+ sta $1433,x ; ADDB 9D 33 14 .3.
+LADDE: lda $1437,x ; ADDE BD 37 14 .7.
+ clc ; ADE1 18 .
+ adc $1433,x ; ADE2 7D 33 14 }3.
+ ror a ; ADE5 6A j
+ sta $1435,x ; ADE6 9D 35 14 .5.
+ bit $F2 ; ADE9 24 F2 $.
+ bmi LAE02 ; ADEB 30 15 0.
+ clc ; ADED 18 .
+ lda $1435,x ; ADEE BD 35 14 .5.
+ adc table_ae15,x ; ADF1 7D 15 AE }..
+ sta $EB ; ADF4 85 EB ..
+ sec ; ADF6 38 8
+ lda $1435,x ; ADF7 BD 35 14 .5.
+ sbc table_ae15,x ; ADFA FD 15 AE ...
+ sta $EC ; ADFD 85 EC ..
+ jmp LAE12 ; ADFF 4C 12 AE L..
+
+; ----------------------------------------------------------------------------
+LAE02: clc ; AE02 18 .
+ lda $1435,x ; AE03 BD 35 14 .5.
+ adc #$10 ; AE06 69 10 i.
+ sta $EB ; AE08 85 EB ..
+ sec ; AE0A 38 8
+ lda $1435,x ; AE0B BD 35 14 .5.
+ sbc #$10 ; AE0E E9 10 ..
+ sta $EC ; AE10 85 EC ..
+LAE12: ldy $11,x ; AE12 B4 11 ..
+ rts ; AE14 60 `
+
+; ----------------------------------------------------------------------------
+table_ae15:
+ .byte $3E,$20 ; AE15 3E 20 >
+; ----------------------------------------------------------------------------
+LAE17: lda #$0A ; AE17 A9 0A ..
+LAE19: pha ; AE19 48 H
+ jsr get_random ; AE1A 20 F2 8C ..
+ sta $DD ; AE1D 85 DD ..
+ lda random_seed+1 ; AE1F A5 C7 ..
+ and #$01 ; AE21 29 01 ).
+ sta $DE ; AE23 85 DE ..
+ clc ; AE25 18 .
+ lda $DD ; AE26 A5 DD ..
+ adc #$AB ; AE28 69 AB i.
+ sta tmp_ptr ; AE2A 85 E7 ..
+ lda $DE ; AE2C A5 DE ..
+ adc #$05 ; AE2E 69 05 i.
+ sta tmp_ptr+1 ; AE30 85 E8 ..
+ ldy #$00 ; AE32 A0 00 ..
+ lda (tmp_ptr),y ; AE34 B1 E7 ..
+ clc ; AE36 18 .
+ adc #$08 ; AE37 69 08 i.
+ sta sprite_y ; AE39 85 DF ..
+ lda #$00 ; AE3B A9 00 ..
+ sta current_sprite ; AE3D 85 F9 ..
+ jsr add_to_sprite_list ; AE3F 20 A5 A4 ..
+ pla ; AE42 68 h
+ sec ; AE43 38 8
+ sbc #$01 ; AE44 E9 01 ..
+ bne LAE19 ; AE46 D0 D1 ..
+ rts ; AE48 60 `
+
+; ----------------------------------------------------------------------------
+; 3 bytes per entry: # bombers, # pods, # landers per wave
+level_spawn_table:
+ .byte $00 ; AE49 00 .
+lst_pods:
+ .byte $00 ; AE4A 00 .
+lst_landers:
+ .byte $0F,$03,$01,$14,$04,$03,$14,$06 ; AE4B 0F 03 01 14 04 03 14 06 ........
+ .byte $04,$14 ; AE53 04 14 ..
+; ----------------------------------------------------------------------------
+; at level start, spawn initial set of enemies
+level_initial_spawn:
+ lda level ; AE55 A5 9A ..
+ asl a ; AE57 0A .
+ clc ; AE58 18 .
+ adc level ; AE59 65 9A e.
+ cmp #$09 ; AE5B C9 09 ..
+ bcc spawn_bombers ; AE5D 90 02 ..
+ lda #$09 ; AE5F A9 09 ..
+; not sure what's up with location $c6 here
+spawn_bombers:
+ tax ; AE61 AA .
+ lda level_spawn_table,x ; AE62 BD 49 AE .I.
+ beq spawn_pods ; AE65 F0 16 ..
+spb_loop:
+ pha ; AE67 48 H
+ jsr L8D0C ; AE68 20 0C 8D ..
+ lda random_seed ; AE6B A5 C6 ..
+ and #$08 ; AE6D 29 08 ).
+ clc ; AE6F 18 .
+ adc #$04 ; AE70 69 04 i.
+ sta current_sprite ; AE72 85 F9 ..
+ jsr spawn_sprite ; AE74 20 ED AB ..
+ pla ; AE77 68 h
+ sec ; AE78 38 8
+ sbc #$01 ; AE79 E9 01 ..
+ bne spb_loop ; AE7B D0 EA ..
+spawn_pods:
+ lda lst_pods,x ; AE7D BD 4A AE .J.
+ beq spawn_landers ; AE80 F0 11 ..
+spp_loop:
+ pha ; AE82 48 H
+ jsr L8D0C ; AE83 20 0C 8D ..
+ lda #$05 ; AE86 A9 05 ..
+ sta current_sprite ; AE88 85 F9 ..
+ jsr spawn_sprite ; AE8A 20 ED AB ..
+ pla ; AE8D 68 h
+ sec ; AE8E 38 8
+ sbc #$01 ; AE8F E9 01 ..
+ bne spp_loop ; AE91 D0 EF ..
+spawn_landers:
+ lda lst_landers,x ; AE93 BD 4B AE .K.
+ sta landers_to_spawn ; AE96 85 9B ..
+; also called from outside level_initial_spawn, for subsequent waves
+spawn_lander_wave:
+ lda landers_to_spawn ; AE98 A5 9B ..
+ beq lis_done ; AE9A F0 49 .I
+ jsr play_materialize ; AE9C 20 32 8E 2.
+ jsr L8D0C ; AE9F 20 0C 8D ..
+ lda #$01 ; AEA2 A9 01 ..
+ sta current_sprite ; AEA4 85 F9 ..
+ jsr spawn_sprite ; AEA6 20 ED AB ..
+ dec landers_to_spawn ; AEA9 C6 9B ..
+ beq lis_done ; AEAB F0 38 .8
+ jsr L8D0C ; AEAD 20 0C 8D ..
+ lda #$01 ; AEB0 A9 01 ..
+ sta current_sprite ; AEB2 85 F9 ..
+ jsr spawn_sprite ; AEB4 20 ED AB ..
+ dec landers_to_spawn ; AEB7 C6 9B ..
+ beq lis_done ; AEB9 F0 2A .*
+ jsr L8D0C ; AEBB 20 0C 8D ..
+ lda #$01 ; AEBE A9 01 ..
+ sta current_sprite ; AEC0 85 F9 ..
+ jsr spawn_sprite ; AEC2 20 ED AB ..
+ dec landers_to_spawn ; AEC5 C6 9B ..
+ beq lis_done ; AEC7 F0 1C ..
+ jsr L8D0C ; AEC9 20 0C 8D ..
+ lda #$01 ; AECC A9 01 ..
+ sta current_sprite ; AECE 85 F9 ..
+ jsr spawn_sprite ; AED0 20 ED AB ..
+ dec landers_to_spawn ; AED3 C6 9B ..
+ beq lis_done ; AED5 F0 0E ..
+ jsr L8D0C ; AED7 20 0C 8D ..
+ lda #$01 ; AEDA A9 01 ..
+ sta current_sprite ; AEDC 85 F9 ..
+ jsr spawn_sprite ; AEDE 20 ED AB ..
+ dec landers_to_spawn ; AEE1 C6 9B ..
+ beq lis_done ; AEE3 F0 00 ..
+lis_done:
+ rts ; AEE5 60 `
+
+; ----------------------------------------------------------------------------
+; 'spawn' not the right word. this does all the logic for humanoids (falling, hitting the ground)
+spawn_humanoid:
+ ldy $98 ; AEE6 A4 98 ..
+ inc humanoid_count ; AEE8 E6 A1 ..
+ lda current_sprite ; AEEA A5 F9 ..
+ beq LAF55 ; AEEC F0 67 .g
+ cmp #$10 ; AEEE C9 10 ..
+ beq humanoid_falling ; AEF0 F0 7C .|
+ bcc humanoid_abducted ; AEF2 90 6B .k
+; player carrying a humanoid
+humanoid_carrying:
+ clc ; AEF4 18 .
+ lda $91 ; AEF5 A5 91 ..
+ adc #$02 ; AEF7 69 02 i.
+ sta $DD ; AEF9 85 DD ..
+ lda $92 ; AEFB A5 92 ..
+ adc #$00 ; AEFD 69 00 i.
+ sta $DE ; AEFF 85 DE ..
+ lda ship_y_pos ; AF01 A5 C4 ..
+ clc ; AF03 18 .
+ adc #$0A ; AF04 69 0A i.
+ sta sprite_y ; AF06 85 DF ..
+ clc ; AF08 18 .
+ lda $DD ; AF09 A5 DD ..
+ adc #$AB ; AF0B 69 AB i.
+ sta tmp_ptr ; AF0D 85 E7 ..
+ lda $DE ; AF0F A5 DE ..
+ adc #$05 ; AF11 69 05 i.
+ sta tmp_ptr+1 ; AF13 85 E8 ..
+ ldy #$00 ; AF15 A0 00 ..
+ lda (tmp_ptr),y ; AF17 B1 E7 ..
+ cmp sprite_y ; AF19 C5 DF ..
+ bcs LAF4E ; AF1B B0 31 .1
+ lda #$0C ; AF1D A9 0C ..
+ jsr add_points ; AF1F 20 B2 A7 ..
+ lda #$00 ; AF22 A9 00 ..
+ sta current_sprite ; AF24 85 F9 ..
+ clc ; AF26 18 .
+ lda $98 ; AF27 A5 98 ..
+ lsr a ; AF29 4A J
+ adc $DD ; AF2A 65 DD e.
+ sta $DD ; AF2C 85 DD ..
+ lda $DE ; AF2E A5 DE ..
+ adc #$00 ; AF30 69 00 i.
+ sta $DE ; AF32 85 DE ..
+ clc ; AF34 18 .
+ lda $98 ; AF35 A5 98 ..
+ lsr a ; AF37 4A J
+ adc tmp_ptr ; AF38 65 E7 e.
+ sta tmp_ptr ; AF3A 85 E7 ..
+ lda tmp_ptr+1 ; AF3C A5 E8 ..
+ adc #$00 ; AF3E 69 00 i.
+ sta tmp_ptr+1 ; AF40 85 E8 ..
+ ldy #$00 ; AF42 A0 00 ..
+ lda (tmp_ptr),y ; AF44 B1 E7 ..
+ clc ; AF46 18 .
+ adc #$08 ; AF47 69 08 i.
+ sta sprite_y ; AF49 85 DF ..
+ jsr play_rescued ; AF4B 20 16 8E ..
+LAF4E: lda #$00 ; AF4E A9 00 ..
+ sta $88 ; AF50 85 88 ..
+ jmp LA5B2 ; AF52 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+LAF55: jsr LB047 ; AF55 20 47 B0 G.
+ lda #$00 ; AF58 A9 00 ..
+ sta $88 ; AF5A 85 88 ..
+ jmp LA5B2 ; AF5C 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+; lander carrying a humanoid
+humanoid_abducted:
+ sec ; AF5F 38 8
+ lda sprite_y ; AF60 A5 DF ..
+ sbc sprite_list+128,y ; AF62 F9 6B 0B .k.
+ sta sprite_y ; AF65 85 DF ..
+ lda #$00 ; AF67 A9 00 ..
+ sta $88 ; AF69 85 88 ..
+ jmp LA5B2 ; AF6B 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+; called repeatedly while a humanoid is falling
+humanoid_falling:
+ ldx $98 ; AF6E A6 98 ..
+ inc sprite_list+128,x ; AF70 FE 6B 0B .k.
+ lda sprite_list+128,x ; AF73 BD 6B 0B .k.
+ lsr a ; AF76 4A J
+ lsr a ; AF77 4A J
+ lsr a ; AF78 4A J
+ lsr a ; AF79 4A J
+ lsr a ; AF7A 4A J
+ clc ; AF7B 18 .
+ adc #$01 ; AF7C 69 01 i.
+ clc ; AF7E 18 .
+ adc sprite_y ; AF7F 65 DF e.
+ sta sprite_y ; AF81 85 DF ..
+ sec ; AF83 38 8
+ lda ship_y_pos ; AF84 A5 C4 ..
+ sbc sprite_y ; AF86 E5 DF ..
+ bcs LAF8E ; AF88 B0 04 ..
+ eor #$FF ; AF8A 49 FF I.
+ adc #$01 ; AF8C 69 01 i.
+LAF8E: cmp #$0A ; AF8E C9 0A ..
+ bcs LAFD4 ; AF90 B0 42 .B
+ sec ; AF92 38 8
+ lda $DD ; AF93 A5 DD ..
+ sbc $89 ; AF95 E5 89 ..
+ sta sprite_x ; AF97 85 E3 ..
+ lda $DE ; AF99 A5 DE ..
+ sbc $8A ; AF9B E5 8A ..
+ sta $E4 ; AF9D 85 E4 ..
+ bcs LAFAE ; AF9F B0 0D ..
+ clc ; AFA1 18 .
+ lda sprite_x ; AFA2 A5 E3 ..
+ adc #$80 ; AFA4 69 80 i.
+ sta sprite_x ; AFA6 85 E3 ..
+ lda $E4 ; AFA8 A5 E4 ..
+ adc #$02 ; AFAA 69 02 i.
+ sta $E4 ; AFAC 85 E4 ..
+LAFAE: lda $E4 ; AFAE A5 E4 ..
+ bne LAFD4 ; AFB0 D0 22 ."
+ lda sprite_x ; AFB2 A5 E3 ..
+ cmp #$A0 ; AFB4 C9 A0 ..
+ bcs LAFD4 ; AFB6 B0 1C ..
+ sec ; AFB8 38 8
+ sbc ship_x_pos ; AFB9 E5 C3 ..
+ bcs LAFC1 ; AFBB B0 04 ..
+ eor #$FF ; AFBD 49 FF I.
+ adc #$01 ; AFBF 69 01 i.
+LAFC1: cmp #$10 ; AFC1 C9 10 ..
+ bcs LAFD4 ; AFC3 B0 0F ..
+ lda #$0C ; AFC5 A9 0C ..
+ jsr add_points ; AFC7 20 B2 A7 ..
+ lda #$18 ; AFCA A9 18 ..
+ sta current_sprite ; AFCC 85 F9 ..
+ jsr play_rescued ; AFCE 20 16 8E ..
+ jmp humanoid_carrying ; AFD1 4C F4 AE L..
+
+; ----------------------------------------------------------------------------
+LAFD4: clc ; AFD4 18 .
+ lda $DD ; AFD5 A5 DD ..
+ adc #$AB ; AFD7 69 AB i.
+ sta tmp_ptr ; AFD9 85 E7 ..
+ lda $DE ; AFDB A5 DE ..
+ adc #$05 ; AFDD 69 05 i.
+ sta tmp_ptr+1 ; AFDF 85 E8 ..
+ ldy #$00 ; AFE1 A0 00 ..
+ lda (tmp_ptr),y ; AFE3 B1 E7 ..
+ cmp sprite_y ; AFE5 C5 DF ..
+ bcs LB040 ; AFE7 B0 57 .W
+ lda sprite_list+128,x ; AFE9 BD 6B 0B .k.
+ cmp #$28 ; AFEC C9 28 .(
+ bcs LAFFF ; AFEE B0 0F ..
+ lda #$04 ; AFF0 A9 04 ..
+ jsr add_points ; AFF2 20 B2 A7 ..
+ lda #$00 ; AFF5 A9 00 ..
+ sta current_sprite ; AFF7 85 F9 ..
+ jsr play_rescued ; AFF9 20 16 8E ..
+ jmp LB040 ; AFFC 4C 40 B0 L@.
+
+; ----------------------------------------------------------------------------
+LAFFF: sec ; AFFF 38 8
+ lda $DD ; B000 A5 DD ..
+ sbc $89 ; B002 E5 89 ..
+ sta sprite_x ; B004 85 E3 ..
+ lda $DE ; B006 A5 DE ..
+ sbc $8A ; B008 E5 8A ..
+ sta $E4 ; B00A 85 E4 ..
+ bcs LB01A ; B00C B0 0C ..
+ lda sprite_x ; B00E A5 E3 ..
+ adc #$80 ; B010 69 80 i.
+ sta sprite_x ; B012 85 E3 ..
+ lda $E4 ; B014 A5 E4 ..
+ adc #$02 ; B016 69 02 i.
+ sta $E4 ; B018 85 E4 ..
+LB01A: lda $E4 ; B01A A5 E4 ..
+ bne LB033 ; B01C D0 15 ..
+ lda sprite_x ; B01E A5 E3 ..
+ cmp #$A0 ; B020 C9 A0 ..
+ bcs LB033 ; B022 B0 0F ..
+ lda sprite_x ; B024 A5 E3 ..
+ sta $C9 ; B026 85 C9 ..
+ lda sprite_y ; B028 A5 DF ..
+ sta $CA ; B02A 85 CA ..
+ lda #$01 ; B02C A9 01 ..
+ sta $CB ; B02E 85 CB ..
+ jsr start_enemy_explosion ; B030 20 E7 9B ..
+LB033: jsr play_human_died ; B033 20 24 8E $.
+ ldy $98 ; B036 A4 98 ..
+ lda #$00 ; B038 A9 00 ..
+ sta sprite_list,y ; B03A 99 EB 0A ...
+ jmp LA4DD ; B03D 4C DD A4 L..
+
+; ----------------------------------------------------------------------------
+LB040: lda #$00 ; B040 A9 00 ..
+ sta $88 ; B042 85 88 ..
+ jmp LA5B2 ; B044 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+LB047: lda animation_counter ; B047 A5 85 ..
+ and #$07 ; B049 29 07 ).
+ bne LB08D ; B04B D0 40 .@
+ lda $98 ; B04D A5 98 ..
+ and #$04 ; B04F 29 04 ).
+ bne LB05C ; B051 D0 09 ..
+ inc $DD ; B053 E6 DD ..
+ bne LB077 ; B055 D0 20 .
+ inc $DE ; B057 E6 DE ..
+ jmp LB077 ; B059 4C 77 B0 Lw.
+
+; ----------------------------------------------------------------------------
+LB05C: sec ; B05C 38 8
+ lda $DD ; B05D A5 DD ..
+ sbc #$01 ; B05F E9 01 ..
+ sta $DD ; B061 85 DD ..
+ lda $DE ; B063 A5 DE ..
+ sbc #$00 ; B065 E9 00 ..
+ sta $DE ; B067 85 DE ..
+ bcs LB077 ; B069 B0 0C ..
+ lda $DD ; B06B A5 DD ..
+ adc #$80 ; B06D 69 80 i.
+ sta $DD ; B06F 85 DD ..
+ lda $DE ; B071 A5 DE ..
+ adc #$02 ; B073 69 02 i.
+ sta $DE ; B075 85 DE ..
+LB077: clc ; B077 18 .
+ lda $DD ; B078 A5 DD ..
+ adc #$AB ; B07A 69 AB i.
+ sta tmp_ptr ; B07C 85 E7 ..
+ lda $DE ; B07E A5 DE ..
+ adc #$05 ; B080 69 05 i.
+ sta tmp_ptr+1 ; B082 85 E8 ..
+ ldy #$00 ; B084 A0 00 ..
+ lda (tmp_ptr),y ; B086 B1 E7 ..
+ clc ; B088 18 .
+ adc #$08 ; B089 69 08 i.
+ sta sprite_y ; B08B 85 DF ..
+LB08D: rts ; B08D 60 `
+
+; ----------------------------------------------------------------------------
+spawn_lander:
+ lda #$01 ; B08E A9 01 ..
+ sta $B9 ; B090 85 B9 ..
+ lda level ; B092 A5 9A ..
+ lsr a ; B094 4A J
+ lsr a ; B095 4A J
+ clc ; B096 18 .
+ adc $B9 ; B097 65 B9 e.
+ sta $B9 ; B099 85 B9 ..
+ lda $98 ; B09B A5 98 ..
+ and #$08 ; B09D 29 08 ).
+ bne LB0A3 ; B09F D0 02 ..
+ inc $B9 ; B0A1 E6 B9 ..
+LB0A3: lda $B9 ; B0A3 A5 B9 ..
+ cmp #$04 ; B0A5 C9 04 ..
+ bcc LB0AD ; B0A7 90 04 ..
+ lda #$03 ; B0A9 A9 03 ..
+ sta $B9 ; B0AB 85 B9 ..
+LB0AD: inc enemy_count ; B0AD E6 9C ..
+ lda planet_dead_flag ; B0AF A5 A0 ..
+ bpl LB0B9 ; B0B1 10 06 ..
+ jsr LB2DE ; B0B3 20 DE B2 ..
+ jmp spawn_mutant ; B0B6 4C F4 B2 L..
+
+; ----------------------------------------------------------------------------
+LB0B9: lda current_sprite ; B0B9 A5 F9 ..
+ cmp #$09 ; B0BB C9 09 ..
+ beq LB0DF ; B0BD F0 20 .
+ bcc LB0E2 ; B0BF 90 21 .!
+ lda #$03 ; B0C1 A9 03 ..
+ sta $94 ; B0C3 85 94 ..
+ lda animation_counter ; B0C5 A5 85 ..
+ and enemy_firing_freq ; B0C7 25 BB %.
+ bne LB0CE ; B0C9 D0 03 ..
+ jsr L9A9C ; B0CB 20 9C 9A ..
+LB0CE: sec ; B0CE 38 8
+ lda sprite_y ; B0CF A5 DF ..
+ sbc $B9 ; B0D1 E5 B9 ..
+ sta sprite_y ; B0D3 85 DF ..
+ cmp #$20 ; B0D5 C9 20 .
+ bcs LB0DC ; B0D7 B0 03 ..
+ jsr LB251 ; B0D9 20 51 B2 Q.
+LB0DC: jmp LB166 ; B0DC 4C 66 B1 Lf.
+
+; ----------------------------------------------------------------------------
+LB0DF: jmp LB18F ; B0DF 4C 8F B1 L..
+
+; ----------------------------------------------------------------------------
+LB0E2: lda animation_counter ; B0E2 A5 85 ..
+ and #$01 ; B0E4 29 01 ).
+ bne LB10D ; B0E6 D0 25 .%
+ lda $98 ; B0E8 A5 98 ..
+ lsr a ; B0EA 4A J
+ lsr a ; B0EB 4A J
+ and #$04 ; B0EC 29 04 ).
+ bne LB100 ; B0EE D0 10 ..
+ clc ; B0F0 18 .
+ lda $DD ; B0F1 A5 DD ..
+ adc $B9 ; B0F3 65 B9 e.
+ sta $DD ; B0F5 85 DD ..
+ lda $DE ; B0F7 A5 DE ..
+ adc #$00 ; B0F9 69 00 i.
+ sta $DE ; B0FB 85 DE ..
+ jmp LB10D ; B0FD 4C 0D B1 L..
+
+; ----------------------------------------------------------------------------
+LB100: sec ; B100 38 8
+ lda $DD ; B101 A5 DD ..
+ sbc $B9 ; B103 E5 B9 ..
+ sta $DD ; B105 85 DD ..
+ lda $DE ; B107 A5 DE ..
+ sbc #$00 ; B109 E9 00 ..
+ sta $DE ; B10B 85 DE ..
+LB10D: lda $B9 ; B10D A5 B9 ..
+ lsr a ; B10F 4A J
+ clc ; B110 18 .
+ adc #$01 ; B111 69 01 i.
+ adc sprite_y ; B113 65 DF e.
+ sta sprite_y ; B115 85 DF ..
+ clc ; B117 18 .
+ lda #$AB ; B118 A9 AB ..
+ adc $DD ; B11A 65 DD e.
+ sta tmp_ptr ; B11C 85 E7 ..
+ lda #$05 ; B11E A9 05 ..
+ adc $DE ; B120 65 DE e.
+ sta tmp_ptr+1 ; B122 85 E8 ..
+ ldy #$00 ; B124 A0 00 ..
+ lda (tmp_ptr),y ; B126 B1 E7 ..
+ sec ; B128 38 8
+ sbc #$1E ; B129 E9 1E ..
+ sta sprite_x ; B12B 85 E3 ..
+ lda sprite_y ; B12D A5 DF ..
+ cmp sprite_x ; B12F C5 E3 ..
+ bcc LB166 ; B131 90 33 .3
+ lda $B9 ; B133 A5 B9 ..
+ lsr a ; B135 4A J
+ clc ; B136 18 .
+ adc #$01 ; B137 69 01 i.
+ sta sprite_x ; B139 85 E3 ..
+ sec ; B13B 38 8
+ lda sprite_y ; B13C A5 DF ..
+ sbc sprite_x ; B13E E5 E3 ..
+ sta sprite_y ; B140 85 DF ..
+ dec sprite_y ; B142 C6 DF ..
+ lda current_sprite ; B144 A5 F9 ..
+ cmp #$09 ; B146 C9 09 ..
+ beq LB166 ; B148 F0 1C ..
+ lda #$09 ; B14A A9 09 ..
+ sta current_sprite ; B14C 85 F9 ..
+ jsr LB22C ; B14E 20 2C B2 ,.
+ bcc LB166 ; B151 90 13 ..
+ lda #$01 ; B153 A9 01 ..
+ sta current_sprite ; B155 85 F9 ..
+ lda #$03 ; B157 A9 03 ..
+ sta $94 ; B159 85 94 ..
+ lda animation_counter ; B15B A5 85 ..
+ adc #$01 ; B15D 69 01 i.
+ and #$03 ; B15F 29 03 ).
+ bne LB166 ; B161 D0 03 ..
+ jsr L9A9C ; B163 20 9C 9A ..
+LB166: lda animation_counter ; B166 A5 85 ..
+ and #$02 ; B168 29 02 ).
+ lsr a ; B16A 4A J
+ clc ; B16B 18 .
+ adc #$01 ; B16C 69 01 i.
+ sta $88 ; B16E 85 88 ..
+ lda animation_counter ; B170 A5 85 ..
+ adc $98 ; B172 65 98 e.
+ and #$3F ; B174 29 3F )?
+ bne LB18C ; B176 D0 14 ..
+ lda ship_delta ; B178 A5 D5 ..
+ bpl LB181 ; B17A 10 05 ..
+ eor #$FF ; B17C 49 FF I.
+ clc ; B17E 18 .
+ adc #$01 ; B17F 69 01 i.
+LB181: cmp #$03 ; B181 C9 03 ..
+ bcc LB18C ; B183 90 07 ..
+ lda #$03 ; B185 A9 03 ..
+ sta $94 ; B187 85 94 ..
+ jsr L9A9C ; B189 20 9C 9A ..
+LB18C: jmp LA5B2 ; B18C 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+LB18F: lda sprite_list+128,y ; B18F B9 6B 0B .k.
+ tax ; B192 AA .
+ lda sprite_list,x ; B193 BD EB 0A ...
+ beq LB19D ; B196 F0 05 ..
+ lda sprite_list+3,x ; B198 BD EE 0A ...
+ beq LB1A9 ; B19B F0 0C ..
+LB19D: jsr LB22C ; B19D 20 2C B2 ,.
+ bcc LB1A6 ; B1A0 90 04 ..
+ lda #$01 ; B1A2 A9 01 ..
+ sta current_sprite ; B1A4 85 F9 ..
+LB1A6: jmp LB166 ; B1A6 4C 66 B1 Lf.
+
+; ----------------------------------------------------------------------------
+LB1A9: lda $DD ; B1A9 A5 DD ..
+ cmp sprite_list+1,x ; B1AB DD EC 0A ...
+ lda $DE ; B1AE A5 DE ..
+ sbc sprite_list+2,x ; B1B0 FD ED 0A ...
+ bcs LB1C3 ; B1B3 B0 0E ..
+ clc ; B1B5 18 .
+ lda $DD ; B1B6 A5 DD ..
+ adc $B9 ; B1B8 65 B9 e.
+ sta $DD ; B1BA 85 DD ..
+ bcc LB1C0 ; B1BC 90 02 ..
+ inc $DE ; B1BE E6 DE ..
+LB1C0: jmp LB10D ; B1C0 4C 0D B1 L..
+
+; ----------------------------------------------------------------------------
+LB1C3: sec ; B1C3 38 8
+ lda $DD ; B1C4 A5 DD ..
+ sbc sprite_list+1,x ; B1C6 FD EC 0A ...
+ sta sprite_x ; B1C9 85 E3 ..
+ lda $DE ; B1CB A5 DE ..
+ sbc sprite_list+2,x ; B1CD FD ED 0A ...
+ sta $E4 ; B1D0 85 E4 ..
+ bcs LB1E0 ; B1D2 B0 0C ..
+ lda sprite_x ; B1D4 A5 E3 ..
+ adc #$80 ; B1D6 69 80 i.
+ sta sprite_x ; B1D8 85 E3 ..
+ lda $E4 ; B1DA A5 E4 ..
+ adc #$02 ; B1DC 69 02 i.
+ sta $E4 ; B1DE 85 E4 ..
+LB1E0: lda $E4 ; B1E0 A5 E4 ..
+ bne LB21C ; B1E2 D0 38 .8
+ lda sprite_x ; B1E4 A5 E3 ..
+ cmp #$03 ; B1E6 C9 03 ..
+ bcs LB21C ; B1E8 B0 32 .2
+ lda sprite_list,x ; B1EA BD EB 0A ...
+ sec ; B1ED 38 8
+ sbc #$0C ; B1EE E9 0C ..
+ cmp sprite_y ; B1F0 C5 DF ..
+ bcs LB208 ; B1F2 B0 14 ..
+ lda #$11 ; B1F4 A9 11 ..
+ sta current_sprite ; B1F6 85 F9 ..
+ lda #$08 ; B1F8 A9 08 ..
+ sta sprite_list+3,x ; B1FA 9D EE 0A ...
+ lda $B9 ; B1FD A5 B9 ..
+ sta sprite_list+128,x ; B1FF 9D 6B 0B .k.
+ jsr play_distress ; B202 20 40 8E @.
+ jmp LB166 ; B205 4C 66 B1 Lf.
+
+; ----------------------------------------------------------------------------
+LB208: inc sprite_y ; B208 E6 DF ..
+ lda #$03 ; B20A A9 03 ..
+ sta $94 ; B20C 85 94 ..
+ lda animation_counter ; B20E A5 85 ..
+ adc $98 ; B210 65 98 e.
+ and enemy_firing_freq ; B212 25 BB %.
+ bne LB219 ; B214 D0 03 ..
+ jsr L9A9C ; B216 20 9C 9A ..
+LB219: jmp LB166 ; B219 4C 66 B1 Lf.
+
+; ----------------------------------------------------------------------------
+LB21C: sec ; B21C 38 8
+ lda $DD ; B21D A5 DD ..
+ sbc $B9 ; B21F E5 B9 ..
+ sta $DD ; B221 85 DD ..
+ lda $DE ; B223 A5 DE ..
+ sbc #$00 ; B225 E9 00 ..
+ sta $DE ; B227 85 DE ..
+ jmp LB10D ; B229 4C 0D B1 L..
+
+; ----------------------------------------------------------------------------
+LB22C: jsr get_random ; B22C 20 F2 8C ..
+ clc ; B22F 18 .
+ adc #$01 ; B230 69 01 i.
+ and #$0F ; B232 29 0F ).
+ asl a ; B234 0A .
+ asl a ; B235 0A .
+ tax ; B236 AA .
+ lda sprite_list+3,x ; B237 BD EE 0A ...
+ beq LB23E ; B23A F0 02 ..
+LB23C: sec ; B23C 38 8
+ rts ; B23D 60 `
+
+; ----------------------------------------------------------------------------
+LB23E: lda sprite_list,x ; B23E BD EB 0A ...
+ beq LB23C ; B241 F0 F9 ..
+ txa ; B243 8A .
+ ldy $98 ; B244 A4 98 ..
+ sta sprite_list+128,y ; B246 99 6B 0B .k.
+ clc ; B249 18 .
+ rts ; B24A 60 `
+
+; ----------------------------------------------------------------------------
+ rts ; B24B 60 `
+
+; ----------------------------------------------------------------------------
+LB24C: lda #$01 ; B24C A9 01 ..
+ sta current_sprite ; B24E 85 F9 ..
+ rts ; B250 60 `
+
+; ----------------------------------------------------------------------------
+LB251: ldy $98 ; B251 A4 98 ..
+ lda sprite_list+128,y ; B253 B9 6B 0B .k.
+ tax ; B256 AA .
+ lda sprite_list,x ; B257 BD EB 0A ...
+ beq LB24C ; B25A F0 F0 ..
+ lda sprite_list+3,x ; B25C BD EE 0A ...
+ cmp #$08 ; B25F C9 08 ..
+ bne LB24C ; B261 D0 E9 ..
+ lda sprite_list,x ; B263 BD EB 0A ...
+ sta sprite_y ; B266 85 DF ..
+ lda #$00 ; B268 A9 00 ..
+ sta sprite_list,x ; B26A 9D EB 0A ...
+ lda sprite_list+1,x ; B26D BD EC 0A ...
+ sta $DD ; B270 85 DD ..
+ lda sprite_list+2,x ; B272 BD ED 0A ...
+ sta $DE ; B275 85 DE ..
+ lda $8B ; B277 A5 8B ..
+ pha ; B279 48 H
+ lda $8C ; B27A A5 8C ..
+ pha ; B27C 48 H
+ lda $8F ; B27D A5 8F ..
+ pha ; B27F 48 H
+ lda $90 ; B280 A5 90 ..
+ pha ; B282 48 H
+ cpx $98 ; B283 E4 98 ..
+ bcc LB297 ; B285 90 10 ..
+ lda $89 ; B287 A5 89 ..
+ sta $8B ; B289 85 8B ..
+ lda $8A ; B28B A5 8A ..
+ sta $8C ; B28D 85 8C ..
+ lda $8D ; B28F A5 8D ..
+ sta $8F ; B291 85 8F ..
+ lda $8E ; B293 A5 8E ..
+ sta $90 ; B295 85 90 ..
+LB297: jsr erase_scanner_sprite ; B297 20 2D A1 -.
+ jsr erase_sprite_XXX ; B29A 20 86 A7 ..
+ pla ; B29D 68 h
+ sta $90 ; B29E 85 90 ..
+ pla ; B2A0 68 h
+ sta $8F ; B2A1 85 8F ..
+ pla ; B2A3 68 h
+ sta $8C ; B2A4 85 8C ..
+ pla ; B2A6 68 h
+ sta $8B ; B2A7 85 8B ..
+ sec ; B2A9 38 8
+ lda $DD ; B2AA A5 DD ..
+ sbc $8B ; B2AC E5 8B ..
+ sta sprite_x ; B2AE 85 E3 ..
+ lda $DE ; B2B0 A5 DE ..
+ sbc $8C ; B2B2 E5 8C ..
+ sta $E4 ; B2B4 85 E4 ..
+ bcs LB2C4 ; B2B6 B0 0C ..
+ lda sprite_x ; B2B8 A5 E3 ..
+ adc #$80 ; B2BA 69 80 i.
+ sta sprite_x ; B2BC 85 E3 ..
+ lda $E4 ; B2BE A5 E4 ..
+ adc #$02 ; B2C0 69 02 i.
+ sta $E4 ; B2C2 85 E4 ..
+LB2C4: lda $E4 ; B2C4 A5 E4 ..
+ bne LB2DB ; B2C6 D0 13 ..
+ lda sprite_x ; B2C8 A5 E3 ..
+ cmp #$A0 ; B2CA C9 A0 ..
+ bcs LB2DB ; B2CC B0 0D ..
+ sta $C9 ; B2CE 85 C9 ..
+ lda sprite_y ; B2D0 A5 DF ..
+ sta $CA ; B2D2 85 CA ..
+ lda #$01 ; B2D4 A9 01 ..
+ sta $CB ; B2D6 85 CB ..
+ jsr start_enemy_explosion ; B2D8 20 E7 9B ..
+LB2DB: jsr play_human_died ; B2DB 20 24 8E $.
+LB2DE: ldy $98 ; B2DE A4 98 ..
+ lda sprite_list,y ; B2E0 B9 EB 0A ...
+ sta sprite_y ; B2E3 85 DF ..
+ lda sprite_list+1,y ; B2E5 B9 EC 0A ...
+ sta $DD ; B2E8 85 DD ..
+ lda sprite_list+2,y ; B2EA B9 ED 0A ...
+ sta $DE ; B2ED 85 DE ..
+ lda #$02 ; B2EF A9 02 ..
+ sta current_sprite ; B2F1 85 F9 ..
+ rts ; B2F3 60 `
+
+; ----------------------------------------------------------------------------
+spawn_mutant:
+ inc enemy_count ; B2F4 E6 9C ..
+ lda $91 ; B2F6 A5 91 ..
+ cmp $DD ; B2F8 C5 DD ..
+ lda $92 ; B2FA A5 92 ..
+ sbc $DE ; B2FC E5 DE ..
+ bcs LB319 ; B2FE B0 19 ..
+ lda random_seed ; B300 A5 C6 ..
+ and #$03 ; B302 29 03 ).
+ clc ; B304 18 .
+ adc #$02 ; B305 69 02 i.
+ sta $E5 ; B307 85 E5 ..
+ sec ; B309 38 8
+ lda $DD ; B30A A5 DD ..
+ sbc $E5 ; B30C E5 E5 ..
+ sta $DD ; B30E 85 DD ..
+ lda $DE ; B310 A5 DE ..
+ sbc #$00 ; B312 E9 00 ..
+ sta $DE ; B314 85 DE ..
+ jmp LB32A ; B316 4C 2A B3 L*.
+
+; ----------------------------------------------------------------------------
+LB319: clc ; B319 18 .
+ lda random_seed ; B31A A5 C6 ..
+ and #$03 ; B31C 29 03 ).
+ adc #$02 ; B31E 69 02 i.
+ adc $DD ; B320 65 DD e.
+ sta $DD ; B322 85 DD ..
+ lda $DE ; B324 A5 DE ..
+ adc #$00 ; B326 69 00 i.
+ sta $DE ; B328 85 DE ..
+LB32A: sec ; B32A 38 8
+ lda $DD ; B32B A5 DD ..
+ sbc $89 ; B32D E5 89 ..
+ sta sprite_x ; B32F 85 E3 ..
+ lda $DE ; B331 A5 DE ..
+ sbc $8A ; B333 E5 8A ..
+ sta $E4 ; B335 85 E4 ..
+ bcs LB345 ; B337 B0 0C ..
+ lda sprite_x ; B339 A5 E3 ..
+ adc #$80 ; B33B 69 80 i.
+ sta sprite_x ; B33D 85 E3 ..
+ lda $E4 ; B33F A5 E4 ..
+ adc #$02 ; B341 69 02 i.
+ sta $E4 ; B343 85 E4 ..
+LB345: lda $E4 ; B345 A5 E4 ..
+ bne LB35E ; B347 D0 15 ..
+ lda sprite_x ; B349 A5 E3 ..
+ cmp #$A0 ; B34B C9 A0 ..
+ bcs LB35E ; B34D B0 0F ..
+ sec ; B34F 38 8
+ lda sprite_x ; B350 A5 E3 ..
+ sbc ship_x_pos ; B352 E5 C3 ..
+ bcs LB35A ; B354 B0 04 ..
+ eor #$FF ; B356 49 FF I.
+ adc #$01 ; B358 69 01 i.
+LB35A: cmp #$20 ; B35A C9 20 .
+ bcc LB39D ; B35C 90 3F .?
+LB35E: lda ship_y_pos ; B35E A5 C4 ..
+ clc ; B360 18 .
+ adc #$40 ; B361 69 40 i@
+ cmp #$B0 ; B363 C9 B0 ..
+ bcc LB36D ; B365 90 06 ..
+ sec ; B367 38 8
+ sbc #$B0 ; B368 E9 B0 ..
+ clc ; B36A 18 .
+ adc #$20 ; B36B 69 20 i
+LB36D: cmp sprite_y ; B36D C5 DF ..
+ bcs LB386 ; B36F B0 15 ..
+ lda random_seed ; B371 A5 C6 ..
+ and #$03 ; B373 29 03 ).
+ clc ; B375 18 .
+ adc #$01 ; B376 69 01 i.
+ sta sprite_x ; B378 85 E3 ..
+ sec ; B37A 38 8
+ lda sprite_y ; B37B A5 DF ..
+ sbc sprite_x ; B37D E5 E3 ..
+ sta sprite_y ; B37F 85 DF ..
+ sta sprite_y ; B381 85 DF ..
+ jmp LB3D2 ; B383 4C D2 B3 L..
+
+; ----------------------------------------------------------------------------
+LB386: clc ; B386 18 .
+ lda random_seed ; B387 A5 C6 ..
+ and #$03 ; B389 29 03 ).
+ clc ; B38B 18 .
+ adc #$01 ; B38C 69 01 i.
+ adc sprite_y ; B38E 65 DF e.
+ sta sprite_y ; B390 85 DF ..
+ cmp #$B0 ; B392 C9 B0 ..
+ bcc LB3D2 ; B394 90 3C .<
+ lda #$20 ; B396 A9 20 .
+ sta sprite_y ; B398 85 DF ..
+ jmp LB3D2 ; B39A 4C D2 B3 L..
+
+; ----------------------------------------------------------------------------
+LB39D: lda sprite_y ; B39D A5 DF ..
+ cmp ship_y_pos ; B39F C5 C4 ..
+ bcc LB3BE ; B3A1 90 1B ..
+ lda random_seed ; B3A3 A5 C6 ..
+ and #$03 ; B3A5 29 03 ).
+ clc ; B3A7 18 .
+ adc #$01 ; B3A8 69 01 i.
+ sta sprite_x ; B3AA 85 E3 ..
+ sec ; B3AC 38 8
+ lda sprite_y ; B3AD A5 DF ..
+ sbc sprite_x ; B3AF E5 E3 ..
+ sta sprite_y ; B3B1 85 DF ..
+ cmp #$20 ; B3B3 C9 20 .
+ bcs LB3D2 ; B3B5 B0 1B ..
+ lda #$B0 ; B3B7 A9 B0 ..
+ sta sprite_y ; B3B9 85 DF ..
+ jmp LB3D2 ; B3BB 4C D2 B3 L..
+
+; ----------------------------------------------------------------------------
+LB3BE: clc ; B3BE 18 .
+ lda random_seed ; B3BF A5 C6 ..
+ and #$03 ; B3C1 29 03 ).
+ clc ; B3C3 18 .
+ adc #$01 ; B3C4 69 01 i.
+ adc sprite_y ; B3C6 65 DF e.
+ sta sprite_y ; B3C8 85 DF ..
+ cmp #$B0 ; B3CA C9 B0 ..
+ bcc LB3D2 ; B3CC 90 04 ..
+ lda #$20 ; B3CE A9 20 .
+ sta sprite_y ; B3D0 85 DF ..
+LB3D2: lda animation_counter ; B3D2 A5 85 ..
+ and #$02 ; B3D4 29 02 ).
+ lsr a ; B3D6 4A J
+ clc ; B3D7 18 .
+ adc #$03 ; B3D8 69 03 i.
+ sta $88 ; B3DA 85 88 ..
+ lda #$03 ; B3DC A9 03 ..
+ sta $94 ; B3DE 85 94 ..
+ lda animation_counter ; B3E0 A5 85 ..
+ adc #$06 ; B3E2 69 06 i.
+ and #$0F ; B3E4 29 0F ).
+ bne LB3EB ; B3E6 D0 03 ..
+ jsr L9A9C ; B3E8 20 9C 9A ..
+LB3EB: jsr ram_self_destruct_1 ; B3EB 20 7F B4 ..
+ jmp LA5B2 ; B3EE 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+spawn_bomber:
+ inc enemy_count ; B3F1 E6 9C ..
+ lda current_sprite ; B3F3 A5 F9 ..
+ cmp #$0C ; B3F5 C9 0C ..
+ bcs LB409 ; B3F7 B0 10 ..
+ sec ; B3F9 38 8
+ lda $DD ; B3FA A5 DD ..
+ sbc #$02 ; B3FC E9 02 ..
+ sta $DD ; B3FE 85 DD ..
+ lda $DE ; B400 A5 DE ..
+ sbc #$00 ; B402 E9 00 ..
+ sta $DE ; B404 85 DE ..
+ jmp LB416 ; B406 4C 16 B4 L..
+
+; ----------------------------------------------------------------------------
+LB409: clc ; B409 18 .
+ lda $DD ; B40A A5 DD ..
+ adc #$02 ; B40C 69 02 i.
+ sta $DD ; B40E 85 DD ..
+ lda $DE ; B410 A5 DE ..
+ adc #$00 ; B412 69 00 i.
+ sta $DE ; B414 85 DE ..
+LB416: ldx $98 ; B416 A6 98 ..
+ lda animation_counter ; B418 A5 85 ..
+ and #$03 ; B41A 29 03 ).
+ bne LB421 ; B41C D0 03 ..
+ inc sprite_list+128,x ; B41E FE 6B 0B .k.
+LB421: lda sprite_list+128,x ; B421 BD 6B 0B .k.
+ and #$1F ; B424 29 1F ).
+ tax ; B426 AA .
+ cmp #$08 ; B427 C9 08 ..
+ beq LB42F ; B429 F0 04 ..
+ cmp #$18 ; B42B C9 18 ..
+ bne LB43B ; B42D D0 0C ..
+LB42F: lda RANDOM ; B42F AD 0A D2 ...
+ bpl LB43B ; B432 10 07 ..
+ txa ; B434 8A .
+ clc ; B435 18 .
+ adc #$0E ; B436 69 0E i.
+ and #$1F ; B438 29 1F ).
+ tax ; B43A AA .
+LB43B: clc ; B43B 18 .
+ lda sprite_y ; B43C A5 DF ..
+ adc swarmer_spawn_y_offsets,x ; B43E 7D 68 B5 }h.
+ sta sprite_y ; B441 85 DF ..
+ cmp #$20 ; B443 C9 20 .
+ bcc LB452 ; B445 90 0B ..
+ cmp #$B0 ; B447 C9 B0 ..
+ bcc LB456 ; B449 90 0B ..
+ lda #$20 ; B44B A9 20 .
+ sta sprite_y ; B44D 85 DF ..
+ jmp LB456 ; B44F 4C 56 B4 LV.
+
+; ----------------------------------------------------------------------------
+LB452: lda #$B0 ; B452 A9 B0 ..
+ sta sprite_y ; B454 85 DF ..
+LB456: lda ship_y_pos ; B456 A5 C4 ..
+ sec ; B458 38 8
+ sbc sprite_y ; B459 E5 DF ..
+ bcs LB461 ; B45B B0 04 ..
+ eor #$FF ; B45D 49 FF I.
+ adc #$01 ; B45F 69 01 i.
+LB461: cmp #$20 ; B461 C9 20 .
+ bcs LB472 ; B463 B0 0D ..
+ lda #$0B ; B465 A9 0B ..
+ sta $94 ; B467 85 94 ..
+ lda animation_counter ; B469 A5 85 ..
+ and #$03 ; B46B 29 03 ).
+ bne LB472 ; B46D D0 03 ..
+ jsr L9A9C ; B46F 20 9C 9A ..
+LB472: lda animation_counter ; B472 A5 85 ..
+ and #$02 ; B474 29 02 ).
+ lsr a ; B476 4A J
+ clc ; B477 18 .
+ adc #$0E ; B478 69 0E i.
+ sta $88 ; B47A 85 88 ..
+ jmp LA5B2 ; B47C 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+; copy protection, causes game to crash next time the player gets killed. called from several places in the code.
+ram_self_destruct_1:
+ lda #$02 ; B47F A9 02 ..
+ sta L983D ; B481 8D 3D 98 .=.
+ rts ; B484 60 `
+
+; ----------------------------------------------------------------------------
+spawn_pod:
+ inc enemy_count ; B485 E6 9C ..
+ inc sprite_y ; B487 E6 DF ..
+ lda sprite_y ; B489 A5 DF ..
+ cmp #$B0 ; B48B C9 B0 ..
+ bcc LB493 ; B48D 90 04 ..
+ lda #$20 ; B48F A9 20 .
+ sta sprite_y ; B491 85 DF ..
+LB493: inc $DD ; B493 E6 DD ..
+ bne LB499 ; B495 D0 02 ..
+ inc $DE ; B497 E6 DE ..
+LB499: lda animation_counter ; B499 A5 85 ..
+ and #$01 ; B49B 29 01 ).
+ clc ; B49D 18 .
+ adc #$15 ; B49E 69 15 i.
+ sta $88 ; B4A0 85 88 ..
+ jmp LA5B2 ; B4A2 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+spawn_swarmer:
+ inc enemy_count ; B4A5 E6 9C ..
+ sec ; B4A7 38 8
+ lda $91 ; B4A8 A5 91 ..
+ sbc $DD ; B4AA E5 DD ..
+ sta sprite_x ; B4AC 85 E3 ..
+ lda $92 ; B4AE A5 92 ..
+ sbc $DE ; B4B0 E5 DE ..
+ sta $E4 ; B4B2 85 E4 ..
+ bcs LB4C8 ; B4B4 B0 12 ..
+ lda sprite_x ; B4B6 A5 E3 ..
+ eor #$FF ; B4B8 49 FF I.
+ sta sprite_x ; B4BA 85 E3 ..
+ lda $E4 ; B4BC A5 E4 ..
+ eor #$FF ; B4BE 49 FF I.
+ sta $E4 ; B4C0 85 E4 ..
+ inc sprite_x ; B4C2 E6 E3 ..
+ bne LB4C8 ; B4C4 D0 02 ..
+ inc $E4 ; B4C6 E6 E4 ..
+LB4C8: lda $E4 ; B4C8 A5 E4 ..
+ bne LB4D2 ; B4CA D0 06 ..
+ lda sprite_x ; B4CC A5 E3 ..
+ cmp #$64 ; B4CE C9 64 .d
+ bcc LB4DE ; B4D0 90 0C ..
+LB4D2: lda $DD ; B4D2 A5 DD ..
+ cmp $91 ; B4D4 C5 91 ..
+ lda $DE ; B4D6 A5 DE ..
+ sbc $92 ; B4D8 E5 92 ..
+ ror a ; B4DA 6A j
+ sta sprite_list+128,y ; B4DB 99 6B 0B .k.
+LB4DE: ldy $98 ; B4DE A4 98 ..
+ lda sprite_list+128,y ; B4E0 B9 6B 0B .k.
+ bmi LB4F5 ; B4E3 30 10 0.
+ clc ; B4E5 18 .
+ lda $DD ; B4E6 A5 DD ..
+ adc #$02 ; B4E8 69 02 i.
+ sta $DD ; B4EA 85 DD ..
+ lda $DE ; B4EC A5 DE ..
+ adc #$00 ; B4EE 69 00 i.
+ sta $DE ; B4F0 85 DE ..
+ jmp LB502 ; B4F2 4C 02 B5 L..
+
+; ----------------------------------------------------------------------------
+LB4F5: sec ; B4F5 38 8
+ lda $DD ; B4F6 A5 DD ..
+ sbc #$02 ; B4F8 E9 02 ..
+ sta $DD ; B4FA 85 DD ..
+ lda $DE ; B4FC A5 DE ..
+ sbc #$00 ; B4FE E9 00 ..
+ sta $DE ; B500 85 DE ..
+LB502: ldx $98 ; B502 A6 98 ..
+ lda animation_counter ; B504 A5 85 ..
+ and #$01 ; B506 29 01 ).
+ bne LB50D ; B508 D0 03 ..
+ inc sprite_list+129,x ; B50A FE 6C 0B .l.
+LB50D: lda sprite_list+129,x ; B50D BD 6C 0B .l.
+ and #$1F ; B510 29 1F ).
+ tax ; B512 AA .
+ clc ; B513 18 .
+ lda sprite_y ; B514 A5 DF ..
+ adc swarmer_spawn_y_offsets,x ; B516 7D 68 B5 }h.
+ sta sprite_y ; B519 85 DF ..
+ lda sprite_y ; B51B A5 DF ..
+ cmp ship_y_pos ; B51D C5 C4 ..
+ bcc LB526 ; B51F 90 05 ..
+ dec sprite_y ; B521 C6 DF ..
+ jmp LB528 ; B523 4C 28 B5 L(.
+
+; ----------------------------------------------------------------------------
+LB526: inc sprite_y ; B526 E6 DF ..
+LB528: cmp #$20 ; B528 C9 20 .
+ bcs LB533 ; B52A B0 07 ..
+ lda #$B0 ; B52C A9 B0 ..
+ sta sprite_y ; B52E 85 DF ..
+ jmp LB53B ; B530 4C 3B B5 L;.
+
+; ----------------------------------------------------------------------------
+LB533: cmp #$B0 ; B533 C9 B0 ..
+ bcc LB53B ; B535 90 04 ..
+ lda #$20 ; B537 A9 20 .
+ sta sprite_y ; B539 85 DF ..
+LB53B: lda #$03 ; B53B A9 03 ..
+ sta $94 ; B53D 85 94 ..
+ lda animation_counter ; B53F A5 85 ..
+ adc #$04 ; B541 69 04 i.
+ and #$0F ; B543 29 0F ).
+ bne LB561 ; B545 D0 1A ..
+ lda $DD ; B547 A5 DD ..
+ cmp $91 ; B549 C5 91 ..
+ lda $DE ; B54B A5 DE ..
+ sbc $92 ; B54D E5 92 ..
+ bcs LB559 ; B54F B0 08 ..
+ lda sprite_list+128,y ; B551 B9 6B 0B .k.
+ bpl LB55E ; B554 10 08 ..
+ jmp LB561 ; B556 4C 61 B5 La.
+
+; ----------------------------------------------------------------------------
+LB559: lda sprite_list+128,y ; B559 B9 6B 0B .k.
+ bpl LB561 ; B55C 10 03 ..
+LB55E: jsr L9A9C ; B55E 20 9C 9A ..
+LB561: lda #$17 ; B561 A9 17 ..
+ sta $88 ; B563 85 88 ..
+ jmp LA5B2 ; B565 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+; XXX I *think* that's what this is
+swarmer_spawn_y_offsets:
+ .byte $FD,$FD,$FD,$FE,$FE,$FF,$FF,$00 ; B568 FD FD FD FE FE FF FF 00 ........
+ .byte $00,$01,$01,$02,$02,$03,$03,$03 ; B570 00 01 01 02 02 03 03 03 ........
+ .byte $03,$03,$03,$02,$02,$01,$01,$00 ; B578 03 03 03 02 02 01 01 00 ........
+ .byte $00,$FF,$FF,$FE,$FE,$FD,$FD,$FD ; B580 00 FF FF FE FE FD FD FD ........
+; ----------------------------------------------------------------------------
+; zero out memory to avoid leaving trails
+erase_ship:
+ lda ship_y_pos ; B588 A5 C4 ..
+ sta sprite_y ; B58A 85 DF ..
+ lda ship_x_pos ; B58C A5 C3 ..
+ sta sprite_x ; B58E 85 E3 ..
+ lda #$00 ; B590 A9 00 ..
+ sta current_sprite ; B592 85 F9 ..
+ jsr erase_sprite ; B594 20 2C AB ,.
+ lda sprite_x ; B597 A5 E3 ..
+ clc ; B599 18 .
+ adc #$05 ; B59A 69 05 i.
+ sta sprite_x ; B59C 85 E3 ..
+ jmp erase_sprite ; B59E 4C 2C AB L,.
+
+; ----------------------------------------------------------------------------
+; draw the player's ship (in playfield, or lives in HUD), but not the rocket exhaust
+draw_ship:
+ lda ship_y_pos ; B5A1 A5 C4 ..
+ sta sprite_y ; B5A3 85 DF ..
+ lda ship_x_pos ; B5A5 A5 C3 ..
+ sta sprite_x ; B5A7 85 E3 ..
+ lda animation_counter ; B5A9 A5 85 ..
+ and #$02 ; B5AB 29 02 ).
+ bne LB5D5 ; B5AD D0 26 .&
+ lda ship_direction ; B5AF A5 C5 ..
+ bpl LB5C4 ; B5B1 10 11 ..
+ lda #$09 ; B5B3 A9 09 ..
+ jsr draw_sprite_left_copy ; B5B5 20 00 1F ..
+ clc ; B5B8 18 .
+ lda sprite_x ; B5B9 A5 E3 ..
+ adc #$05 ; B5BB 69 05 i.
+ sta sprite_x ; B5BD 85 E3 ..
+ lda #$0A ; B5BF A9 0A ..
+ jmp draw_sprite_right_copy ; B5C1 4C 80 1F L..
+
+; ----------------------------------------------------------------------------
+LB5C4: lda #$05 ; B5C4 A9 05 ..
+ jsr draw_sprite_left_copy ; B5C6 20 00 1F ..
+ clc ; B5C9 18 .
+ lda sprite_x ; B5CA A5 E3 ..
+ adc #$05 ; B5CC 69 05 i.
+ sta sprite_x ; B5CE 85 E3 ..
+ lda #$06 ; B5D0 A9 06 ..
+ jmp draw_sprite_right_copy ; B5D2 4C 80 1F L..
+
+; ----------------------------------------------------------------------------
+LB5D5: lda ship_direction ; B5D5 A5 C5 ..
+ bpl LB5EA ; B5D7 10 11 ..
+ lda #$0B ; B5D9 A9 0B ..
+ jsr draw_sprite_left_copy ; B5DB 20 00 1F ..
+ clc ; B5DE 18 .
+ lda sprite_x ; B5DF A5 E3 ..
+ adc #$05 ; B5E1 69 05 i.
+ sta sprite_x ; B5E3 85 E3 ..
+ lda #$0C ; B5E5 A9 0C ..
+ jmp draw_sprite_right_copy ; B5E7 4C 80 1F L..
+
+; ----------------------------------------------------------------------------
+LB5EA: lda #$07 ; B5EA A9 07 ..
+ jsr draw_sprite_left_copy ; B5EC 20 00 1F ..
+ clc ; B5EF 18 .
+ lda sprite_x ; B5F0 A5 E3 ..
+ adc #$05 ; B5F2 69 05 i.
+ sta sprite_x ; B5F4 85 E3 ..
+ lda #$08 ; B5F6 A9 08 ..
+ jmp draw_sprite_right_copy ; B5F8 4C 80 1F L..
+
+; ----------------------------------------------------------------------------
+; if hit, explode the ship and return with carry set. otherwise, return with carry clear.
+check_ship_collision:
+ bit invuln_flag ; B5FB 24 ED $.
+ bpl not_invuln ; B5FD 10 01 ..
+ rts ; B5FF 60 `
+
+; ----------------------------------------------------------------------------
+; bounding box is 20x10, with X offset 3 from actual ship position.
+not_invuln:
+ lda ship_y_pos ; B600 A5 C4 ..
+ sec ; B602 38 8
+ sbc sprite_y ; B603 E5 DF ..
+ bcs ni_cmp_abs_y ; B605 B0 04 ..
+ eor #$FF ; B607 49 FF I.
+ adc #$01 ; B609 69 01 i.
+; if(abs(ship_y_pos - sprite_y) < 6) goto ship_collision;
+ni_cmp_abs_y:
+ cmp #$06 ; B60B C9 06 ..
+ bcs jmp_no_coll ; B60D B0 12 ..
+ lda ship_x_pos ; B60F A5 C3 ..
+ clc ; B611 18 .
+ adc #$03 ; B612 69 03 i.
+ sec ; B614 38 8
+ sbc sprite_x ; B615 E5 E3 ..
+ bcs ni_cmp_abs_x ; B617 B0 04 ..
+ eor #$FF ; B619 49 FF I.
+ adc #$01 ; B61B 69 01 i.
+; if(abs(ship_x_pos - sprite_x) < 11) goto ship_collision;
+ni_cmp_abs_x:
+ cmp #$0B ; B61D C9 0B ..
+ bcc ship_collision ; B61F 90 03 ..
+jmp_no_coll:
+ jmp no_collision ; B621 4C 67 B7 Lg.
+
+; ----------------------------------------------------------------------------
+; player ran into something
+ship_collision:
+ jsr erase_exhaust ; B624 20 62 99 b.
+ sec ; B627 38 8
+ ror ship_dead_flag ; B628 66 EF f.
+ ldy $98 ; B62A A4 98 ..
+ lda #$00 ; B62C A9 00 ..
+ sta sprite_list,y ; B62E 99 EB 0A ...
+ lda sprite_list+3,y ; B631 B9 EE 0A ...
+ sta current_sprite ; B634 85 F9 ..
+ jsr add_cursprite_points ; B636 20 AE A7 ..
+ jsr draw_scores ; B639 20 42 94 B.
+ ldy $98 ; B63C A4 98 ..
+ lda sprite_list+3,y ; B63E B9 EE 0A ...
+ and #$07 ; B641 29 07 ).
+ cmp #$05 ; B643 C9 05 ..
+ bne no_swarmers ; B645 D0 03 ..
+ jsr spawn_swarmers ; B647 20 11 A7 ..
+no_swarmers:
+ sec ; B64A 38 8
+ rts ; B64B 60 `
+
+; ----------------------------------------------------------------------------
+; explosion animation, then bookkeeping
+start_player_death:
+ lda #$00 ; B64C A9 00 ..
+ sta ship_delta ; B64E 85 D5 ..
+ jsr clear_scanner_draw_planet_and_humans; B650 20 5E 9E ^.
+ lda #$00 ; B653 A9 00 ..
+ sta ship_dead_flag ; B655 85 EF ..
+ jsr clear_player_shots ; B657 20 F1 B7 ..
+ lda #$08 ; B65A A9 08 ..
+; flash the ship's colors just before it explodes
+flash_ship:
+ pha ; B65C 48 H
+ sec ; B65D 38 8
+ ror invuln_flag ; B65E 66 ED f.
+flash_wait_1:
+ bit draw_ok_flag ; B660 24 AB $.
+ bpl flash_wait_1 ; B662 10 FC ..
+ jsr draw_ship ; B664 20 A1 B5 ..
+ jsr LA4CC ; B667 20 CC A4 ..
+ lda #$38 ; B66A A9 38 .8
+ sta COLOR2 ; B66C 8D C6 02 ...
+flash_wait_2:
+ lda draw_ok_flag ; B66F A5 AB ..
+ bmi flash_wait_2 ; B671 30 FC 0.
+flash_wait_3:
+ bit draw_ok_flag ; B673 24 AB $.
+ bpl flash_wait_3 ; B675 10 FC ..
+ jsr draw_ship ; B677 20 A1 B5 ..
+ jsr LA4CC ; B67A 20 CC A4 ..
+ lda #$7E ; B67D A9 7E .~
+ sta COLOR2 ; B67F 8D C6 02 ...
+ pla ; B682 68 h
+ sec ; B683 38 8
+ sbc #$01 ; B684 E9 01 ..
+ bne flash_ship ; B686 D0 D4 ..
+ lda #$00 ; B688 A9 00 ..
+ sta invuln_flag ; B68A 85 ED ..
+ jsr erase_ship ; B68C 20 88 B5 ..
+ lda #$00 ; B68F A9 00 ..
+ sta AUDF2 ; B691 8D 02 D2 ...
+ sta AUDC2 ; B694 8D 03 D2 ...
+ jsr play_ship_died ; B697 20 6A 8E j.
+ lda #$0F ; B69A A9 0F ..
+ sta COLOR4 ; B69C 8D C8 02 ...
+ lda #$80 ; B69F A9 80 ..
+ jsr delay_loop ; B6A1 20 74 88 t.
+ lda #$00 ; B6A4 A9 00 ..
+ sta COLOR4 ; B6A6 8D C8 02 ...
+ lsr $AD ; B6A9 46 AD F.
+ jsr draw_scores ; B6AB 20 42 94 B.
+ jsr ship_explosion ; B6AE 20 D9 97 ..
+ lda #$7E ; B6B1 A9 7E .~
+ sta COLOR2 ; B6B3 8D C6 02 ...
+ jsr draw_scores ; B6B6 20 42 94 B.
+ lda enemy_count ; B6B9 A5 9C ..
+ ora landers_to_spawn ; B6BB 05 9B ..
+ ora baiter_count ; B6BD 05 9D ..
+ bne player_died_same_level ; B6BF D0 0E ..
+; player collided with last enemy, cleared the level, but died
+player_died_next_level:
+ jsr clear_baiters ; B6C1 20 6D B8 m.
+ jsr clear_temp_enemies ; B6C4 20 69 B7 i.
+ dec lives ; B6C7 C6 9E ..
+ sec ; B6C9 38 8
+ ror $F7 ; B6CA 66 F7 f.
+ jmp next_level ; B6CC 4C C9 83 L..
+
+; ----------------------------------------------------------------------------
+player_died_same_level:
+ dec lives ; B6CF C6 9E ..
+LB6D1: lsr $F7 ; B6D1 46 F7 F.
+ lda lives ; B6D3 A5 9E ..
+ beq out_of_lives ; B6D5 F0 37 .7
+ jsr clear_baiters ; B6D7 20 6D B8 m.
+ jsr clear_temp_enemies ; B6DA 20 69 B7 i.
+ lda players ; B6DD A5 E2 ..
+ cmp #$01 ; B6DF C9 01 ..
+ beq LB70B ; B6E1 F0 28 .(
+LB6E3: lda current_player ; B6E3 A5 F1 ..
+ cmp #$01 ; B6E5 C9 01 ..
+ beq LB6F2 ; B6E7 F0 09 ..
+ jsr save_p2_state ; B6E9 20 0D 8A ..
+ jsr load_p1_state ; B6EC 20 61 8A a.
+ jmp LB6F8 ; B6EF 4C F8 B6 L..
+
+; ----------------------------------------------------------------------------
+LB6F2: jsr save_p1_state ; B6F2 20 B9 89 ..
+ jsr load_p2_state ; B6F5 20 B5 8A ..
+LB6F8: lda lives ; B6F8 A5 9E ..
+ bne LB705 ; B6FA D0 09 ..
+ lda current_player ; B6FC A5 F1 ..
+ eor #$03 ; B6FE 49 03 I.
+ sta current_player ; B700 85 F1 ..
+ jmp LB6E3 ; B702 4C E3 B6 L..
+
+; ----------------------------------------------------------------------------
+LB705: lda current_player ; B705 A5 F1 ..
+ eor #$03 ; B707 49 03 I.
+ sta current_player ; B709 85 F1 ..
+LB70B: jmp L845B ; B70B 4C 5B 84 L[.
+
+; ----------------------------------------------------------------------------
+out_of_lives:
+ jsr clear_screen ; B70E 20 A1 B8 ..
+ jsr draw_scanner_border_and_planet ; B711 20 B1 9F ..
+ jsr draw_p1_lives_and_bombs ; B714 20 B0 86 ..
+ jsr draw_p2_lives_and_bombs ; B717 20 80 87 ..
+ jsr draw_scores ; B71A 20 42 94 B.
+ lda players ; B71D A5 E2 ..
+ cmp #$01 ; B71F C9 01 ..
+ beq LB732 ; B721 F0 0F ..
+ lda current_player ; B723 A5 F1 ..
+ cmp #$01 ; B725 C9 01 ..
+ beq LB72F ; B727 F0 06 ..
+ jsr print_p2_text ; B729 20 3E 8B >.
+ jmp LB732 ; B72C 4C 32 B7 L2.
+
+; ----------------------------------------------------------------------------
+LB72F: jsr print_p1_text ; B72F 20 09 8B ..
+LB732: jsr print_game_over ; B732 20 1E B8 ..
+ lda #$00 ; B735 A9 00 ..
+ sta start_flag ; B737 85 BE ..
+ sta select_flag ; B739 85 B0 ..
+ lda players ; B73B A5 E2 ..
+ cmp #$01 ; B73D C9 01 ..
+ beq LB753 ; B73F F0 12 ..
+ lda current_player ; B741 A5 F1 ..
+ cmp #$01 ; B743 C9 01 ..
+ beq LB74E ; B745 F0 07 ..
+ lda p1_sav_lives ; B747 AD C6 17 ...
+ beq LB753 ; B74A F0 07 ..
+ bne LB6E3 ; B74C D0 95 ..
+LB74E: lda p2_sav_lives ; B74E AD C6 19 ...
+ bne LB6E3 ; B751 D0 90 ..
+LB753: jsr check_consol ; B753 20 A0 BA ..
+ sec ; B756 38 8
+ ror pause_flag ; B757 66 AF f.
+ bit start_flag ; B759 24 BE $.
+ bpl LB760 ; B75B 10 03 ..
+ jmp game_on ; B75D 4C 69 83 Li.
+
+; ----------------------------------------------------------------------------
+LB760: bit select_flag ; B760 24 B0 $.
+ bpl LB753 ; B762 10 EF ..
+ jmp init_title_screen ; B764 4C 31 80 L1.
+
+; ----------------------------------------------------------------------------
+no_collision:
+ clc ; B767 18 .
+ rts ; B768 60 `
+
+; ----------------------------------------------------------------------------
+; remove baiters, enemy shots, bombs. called when the player dies.
+clear_temp_enemies:
+ lda #$00 ; B769 A9 00 ..
+ sta $9F ; B76B 85 9F ..
+ jmp LB781 ; B76D 4C 81 B7 L..
+
+; ----------------------------------------------------------------------------
+LB770: lda $9F ; B770 A5 9F ..
+ clc ; B772 18 .
+ adc #$04 ; B773 69 04 i.
+ sta $9F ; B775 85 9F ..
+ bpl LB781 ; B777 10 08 ..
+ lda #$64 ; B779 A9 64 .d
+ sta baiter_count ; B77B 85 9D ..
+ jsr LB7E0 ; B77D 20 E0 B7 ..
+ rts ; B780 60 `
+
+; ----------------------------------------------------------------------------
+LB781: ldy $9F ; B781 A4 9F ..
+ lda sprite_list,y ; B783 B9 EB 0A ...
+ beq LB770 ; B786 F0 E8 ..
+ lda sprite_list+3,y ; B788 B9 EE 0A ...
+ and #$07 ; B78B 29 07 ).
+ beq LB7BD ; B78D F0 2E ..
+ cmp #$01 ; B78F C9 01 ..
+ beq LB7AA ; B791 F0 17 ..
+ cmp #$07 ; B793 C9 07 ..
+ beq LB79B ; B795 F0 04 ..
+ cmp #$03 ; B797 C9 03 ..
+ bne LB7AF ; B799 D0 14 ..
+LB79B: ldy $9F ; B79B A4 9F ..
+ lda #$00 ; B79D A9 00 ..
+ sta sprite_list,y ; B79F 99 EB 0A ...
+ lda #$80 ; B7A2 A9 80 ..
+ sta sprite_list+2,y ; B7A4 99 ED 0A ...
+ jmp LB770 ; B7A7 4C 70 B7 Lp.
+
+; ----------------------------------------------------------------------------
+LB7AA: lda #$01 ; B7AA A9 01 ..
+ sta sprite_list+3,y ; B7AC 99 EE 0A ...
+LB7AF: jsr L8D0C ; B7AF 20 0C 8D ..
+ lda sprite_list+3,y ; B7B2 B9 EE 0A ...
+ sta current_sprite ; B7B5 85 F9 ..
+ jsr spawn_sprite ; B7B7 20 ED AB ..
+ jmp LB79B ; B7BA 4C 9B B7 L..
+
+; ----------------------------------------------------------------------------
+LB7BD: clc ; B7BD 18 .
+ lda sprite_list+1,y ; B7BE B9 EC 0A ...
+ adc #$AB ; B7C1 69 AB i.
+ sta tmp_ptr ; B7C3 85 E7 ..
+ lda sprite_list+2,y ; B7C5 B9 ED 0A ...
+ adc #$05 ; B7C8 69 05 i.
+ sta tmp_ptr+1 ; B7CA 85 E8 ..
+ ldy #$00 ; B7CC A0 00 ..
+ lda (tmp_ptr),y ; B7CE B1 E7 ..
+ sec ; B7D0 38 8
+ sbc #$04 ; B7D1 E9 04 ..
+ ldy $9F ; B7D3 A4 9F ..
+ sta sprite_list,y ; B7D5 99 EB 0A ...
+ lda #$00 ; B7D8 A9 00 ..
+ sta sprite_list+3,y ; B7DA 99 EE 0A ...
+ jmp LB770 ; B7DD 4C 70 B7 Lp.
+
+; ----------------------------------------------------------------------------
+LB7E0: ldy #$00 ; B7E0 A0 00 ..
+LB7E2: lda #$30 ; B7E2 A9 30 .0
+ sta actor_list+4,y ; B7E4 99 6F 0C .o.
+ tya ; B7E7 98 .
+ clc ; B7E8 18 .
+ adc #$06 ; B7E9 69 06 i.
+ tay ; B7EB A8 .
+ cpy #$C0 ; B7EC C0 C0 ..
+ bcc LB7E2 ; B7EE 90 F2 ..
+ rts ; B7F0 60 `
+
+; ----------------------------------------------------------------------------
+; clear player_shots table and erase shot graphics. called when player dies or enters hyperspace
+clear_player_shots:
+ ldx #$00 ; B7F1 A2 00 ..
+cps_next:
+ lda player_shots_y,x ; B7F3 BD 1A 05 ...
+ bne cps_clear ; B7F6 D0 0A ..
+; see if this shot exists
+cps_check:
+ txa ; B7F8 8A .
+ clc ; B7F9 18 .
+ adc #$04 ; B7FA 69 04 i.
+ tax ; B7FC AA .
+ cpx #$10 ; B7FD E0 10 ..
+ bcc cps_next ; B7FF 90 F2 ..
+ rts ; B801 60 `
+
+; ----------------------------------------------------------------------------
+; shot exists, clear it
+cps_clear:
+ tay ; B802 A8 .
+ lda #$00 ; B803 A9 00 ..
+ sta player_shots_y,x ; B805 9D 1A 05 ...
+ lda screen_hi_ptrs,y ; B808 B9 00 1E ...
+ sta screen_ptr+1 ; B80B 85 C1 ..
+ lda screen_lo_ptrs,y ; B80D B9 00 1D ...
+ sta screen_ptr ; B810 85 C0 ..
+ ldy #$27 ; B812 A0 27 .'
+cps_clear_loop:
+ lda #$00 ; B814 A9 00 ..
+ sta (screen_ptr),y ; B816 91 C0 ..
+ dey ; B818 88 .
+ bpl cps_clear_loop ; B819 10 F9 ..
+ jmp cps_check ; B81B 4C F8 B7 L..
+
+; ----------------------------------------------------------------------------
+print_game_over:
+ lda #$0C ; B81E A9 0C ..
+ sta cursor_y ; B820 8D 3A 14 .:.
+ lda #$00 ; B823 A9 00 ..
+ sta cursor_x ; B825 8D 39 14 .9.
+ ldy #$00 ; B828 A0 00 ..
+pgo_nextchar:
+ lda game_over_text,y ; B82A B9 44 B8 .D.
+ beq pgo_delay ; B82D F0 06 ..
+ jsr printchar ; B82F 20 2E 97 ..
+ iny ; B832 C8 .
+ bne pgo_nextchar ; B833 D0 F5 ..
+pgo_delay:
+ lda #$0A ; B835 A9 0A ..
+pgo_delay_loop:
+ pha ; B837 48 H
+ lda #$FF ; B838 A9 FF ..
+ jsr delay_loop ; B83A 20 74 88 t.
+ pla ; B83D 68 h
+ sec ; B83E 38 8
+ sbc #$01 ; B83F E9 01 ..
+ bne pgo_delay_loop ; B841 D0 F4 ..
+ rts ; B843 60 `
+
+; ----------------------------------------------------------------------------
+; ' G A M E O V E R '
+game_over_text:
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 ; B844 A0 A0 A0 A0 A0 A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$C7,$A0,$C1,$A0,$CD ; B84C A0 A0 A0 C7 A0 C1 A0 CD ........
+ .byte $A0,$C5,$A0,$A0,$CF,$A0,$D6,$A0 ; B854 A0 C5 A0 A0 CF A0 D6 A0 ........
+ .byte $C5,$A0,$D2,$A0,$A0,$A0,$A0,$A0 ; B85C C5 A0 D2 A0 A0 A0 A0 A0 ........
+ .byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 ; B864 A0 A0 A0 A0 A0 A0 A0 A0 ........
+ .byte $00 ; B86C 00 .
+; ----------------------------------------------------------------------------
+; XXX I think this is correct, but disabling it doesn't do what I think it should
+clear_baiters:
+ ldy #$00 ; B86D A0 00 ..
+ lda #$00 ; B86F A9 00 ..
+LB871: lda actor_list+3,y ; B871 B9 6E 0C .n.
+ and #$07 ; B874 29 07 ).
+ cmp #$07 ; B876 C9 07 ..
+ bne LB87F ; B878 D0 05 ..
+ lda #$00 ; B87A A9 00 ..
+ sta actor_list,y ; B87C 99 6B 0C .k.
+LB87F: tya ; B87F 98 .
+ clc ; B880 18 .
+ adc #$06 ; B881 69 06 i.
+ tay ; B883 A8 .
+ cpy #$C0 ; B884 C0 C0 ..
+ bcc LB871 ; B886 90 E9 ..
+ rts ; B888 60 `
+
+; ----------------------------------------------------------------------------
+init_hardware:
+ sei ; B889 78 x
+ cld ; B88A D8 .
+ lda #$00 ; B88B A9 00 ..
+ sta SDMCTL ; B88D 8D 2F 02 ./.
+ sta DMACTL ; B890 8D 00 D4 ...
+ sta NMIEN ; B893 8D 0E D4 ...
+ sta POKMSK ; B896 85 10 ..
+ sta IRQEN ; B898 8D 0E D2 ...
+ jsr clear_screen ; B89B 20 A1 B8 ..
+ jmp init_screen_ptrs ; B89E 4C 02 B9 L..
+
+; ----------------------------------------------------------------------------
+; zero out $2218 - $4017 (screen actually ends at $3fc7). the only place where ram above $3fff is accessed (written to, never read, so it's OK on a 16K Atari)
+clear_screen:
+ ldx #$00 ; B8A1 A2 00 ..
+ txa ; B8A3 8A .
+LB8A4: sta screen_ram,x ; B8A4 9D 18 22 .."
+ sta screen_ram+256,x ; B8A7 9D 18 23 ..#
+ sta screen_ram+512,x ; B8AA 9D 18 24 ..$
+ sta screen_ram+768,x ; B8AD 9D 18 25 ..%
+ sta screen_ram+1024,x ; B8B0 9D 18 26 ..&
+ sta screen_ram+1280,x ; B8B3 9D 18 27 ..'
+ sta screen_ram+1536,x ; B8B6 9D 18 28 ..(
+ sta screen_ram+1792,x ; B8B9 9D 18 29 ..)
+ sta screen_ram+2048,x ; B8BC 9D 18 2A ..*
+ sta screen_ram+2304,x ; B8BF 9D 18 2B ..+
+ sta screen_ram+2560,x ; B8C2 9D 18 2C ..,
+ sta screen_ram+2816,x ; B8C5 9D 18 2D ..-
+ sta screen_ram+3072,x ; B8C8 9D 18 2E ...
+ sta screen_ram+3328,x ; B8CB 9D 18 2F ../
+ sta screen_ram+3584,x ; B8CE 9D 18 30 ..0
+ sta screen_ram+3840,x ; B8D1 9D 18 31 ..1
+ sta screen_ram+4096,x ; B8D4 9D 18 32 ..2
+ sta screen_ram+4352,x ; B8D7 9D 18 33 ..3
+ sta screen_ram+4608,x ; B8DA 9D 18 34 ..4
+ sta screen_ram+4864,x ; B8DD 9D 18 35 ..5
+ sta screen_ram+5120,x ; B8E0 9D 18 36 ..6
+ sta screen_ram+5376,x ; B8E3 9D 18 37 ..7
+ sta screen_ram+5632,x ; B8E6 9D 18 38 ..8
+ sta screen_ram+5888,x ; B8E9 9D 18 39 ..9
+ sta screen_ram+6144,x ; B8EC 9D 18 3A ..:
+ sta screen_ram+6400,x ; B8EF 9D 18 3B ..;
+ sta screen_ram+6656,x ; B8F2 9D 18 3C ..<
+ sta screen_ram+6912,x ; B8F5 9D 18 3D ..=
+ sta screen_ram+7168,x ; B8F8 9D 18 3E ..>
+ sta screen_ram+7424,x ; B8FB 9D 18 3F ..?
+ inx ; B8FE E8 .
+ bne LB8A4 ; B8FF D0 A3 ..
+ rts ; B901 60 `
+
+; ----------------------------------------------------------------------------
+init_screen_ptrs:
+ lda #$18 ; B902 A9 18 ..
+ sta tmp_ptr ; B904 85 E7 ..
+ lda #$22 ; B906 A9 22 ."
+ sta tmp_ptr+1 ; B908 85 E8 ..
+ ldx #$C0 ; B90A A2 C0 ..
+ ldy #$00 ; B90C A0 00 ..
+_isp_loop:
+ lda tmp_ptr ; B90E A5 E7 ..
+ sta screen_lo_ptrs,y ; B910 99 00 1D ...
+ lda tmp_ptr+1 ; B913 A5 E8 ..
+ sta screen_hi_ptrs,y ; B915 99 00 1E ...
+ clc ; B918 18 .
+ lda tmp_ptr ; B919 A5 E7 ..
+ adc #$28 ; B91B 69 28 i(
+ sta tmp_ptr ; B91D 85 E7 ..
+ lda tmp_ptr+1 ; B91F A5 E8 ..
+ adc #$00 ; B921 69 00 i.
+ sta tmp_ptr+1 ; B923 85 E8 ..
+ iny ; B925 C8 .
+ dex ; B926 CA .
+ bne _isp_loop ; B927 D0 E5 ..
+LB929: lda #$E0 ; B929 A9 E0 ..
+ sta screen_lo_ptrs,y ; B92B 99 00 1D ...
+ sta screen_hi_ptrs,y ; B92E 99 00 1E ...
+ iny ; B931 C8 .
+ bne LB929 ; B932 D0 F5 ..
+ ldy #$00 ; B934 A0 00 ..
+ tya ; B936 98 .
+; fill $1a00-$1aff with repeating pattern 00 01 02 03 ...
+fill_offset_index_table:
+ sta offset_index_table,y ; B937 99 00 1A ...
+ clc ; B93A 18 .
+ adc #$01 ; B93B 69 01 i.
+ cmp #$04 ; B93D C9 04 ..
+ bcc LB943 ; B93F 90 02 ..
+ lda #$00 ; B941 A9 00 ..
+LB943: iny ; B943 C8 .
+ bne fill_offset_index_table ; B944 D0 F1 ..
+ ldy #$00 ; B946 A0 00 ..
+ lda #$C0 ; B948 A9 C0 ..
+fill_pixel_mask_table:
+ sta pixel_mask_table,y ; B94A 99 00 1C ...
+ lsr a ; B94D 4A J
+ lsr a ; B94E 4A J
+ bne LB953 ; B94F D0 02 ..
+ lda #$C0 ; B951 A9 C0 ..
+LB953: iny ; B953 C8 .
+ bne fill_pixel_mask_table ; B954 D0 F4 ..
+ ldy #$00 ; B956 A0 00 ..
+ lda #$00 ; B958 A9 00 ..
+; fill horizontal offset table (if that's what it really is): 00 00 00 00 01 01 01 01 ... to 27 27 27 27, which repeats to the end of the page
+fill_hoffset_table:
+ ldx #$04 ; B95A A2 04 ..
+LB95C: sta horiz_offset_table,y ; B95C 99 00 1B ...
+ iny ; B95F C8 .
+ beq LB96C ; B960 F0 0A ..
+ dex ; B962 CA .
+ bne LB95C ; B963 D0 F7 ..
+ clc ; B965 18 .
+ adc #$01 ; B966 69 01 i.
+ cpy #$00 ; B968 C0 00 ..
+ bne fill_hoffset_table ; B96A D0 EE ..
+LB96C: ldy #$00 ; B96C A0 00 ..
+LB96E: lda horiz_offset_table,y ; B96E B9 00 1B ...
+ cmp #$28 ; B971 C9 28 .(
+ bcc LB97A ; B973 90 05 ..
+ lda #$27 ; B975 A9 27 .'
+ sta horiz_offset_table,y ; B977 99 00 1B ...
+LB97A: iny ; B97A C8 .
+ bne LB96E ; B97B D0 F1 ..
+; create display list at dlist_ram
+setup_display_list:
+ lda #$70 ; B97D A9 70 .p
+ sta dlist_ram ; B97F 8D 00 20 ..
+ sta dlist_ram+1 ; B982 8D 01 20 ..
+ sta dlist_ram+2 ; B985 8D 02 20 ..
+ lda #$4E ; B988 A9 4E .N
+ sta dlist_ram+3 ; B98A 8D 03 20 ..
+ lda #$18 ; B98D A9 18 ..
+ sta dlist_ram+4 ; B98F 8D 04 20 ..
+ lda #$22 ; B992 A9 22 ."
+ sta dlist_ram+5 ; B994 8D 05 20 ..
+ ldy #$58 ; B997 A0 58 .X
+ ldx #$00 ; B999 A2 00 ..
+LB99B: lda #$0E ; B99B A9 0E ..
+ cpx #$00 ; B99D E0 00 ..
+ bne LB9A3 ; B99F D0 02 ..
+ ora #$80 ; B9A1 09 80 ..
+LB9A3: sta dlist_ram+6,x ; B9A3 9D 06 20 ..
+ inx ; B9A6 E8 .
+ dey ; B9A7 88 .
+ bne LB99B ; B9A8 D0 F1 ..
+ lda #$4E ; B9AA A9 4E .N
+ sta dlist_ram+6,x ; B9AC 9D 06 20 ..
+ lda #$00 ; B9AF A9 00 ..
+ sta dlist_ram+7,x ; B9B1 9D 07 20 ..
+ lda #$30 ; B9B4 A9 30 .0
+ sta dlist_ram+8,x ; B9B6 9D 08 20 ..
+ ldy #$65 ; B9B9 A0 65 .e
+LB9BB: lda #$0E ; B9BB A9 0E ..
+ sta dlist_ram+9,x ; B9BD 9D 09 20 ..
+ inx ; B9C0 E8 .
+ dey ; B9C1 88 .
+ bne LB9BB ; B9C2 D0 F7 ..
+ lda #$8E ; B9C4 A9 8E ..
+ sta dlist_ram+8,x ; B9C6 9D 08 20 ..
+ lda #$41 ; B9C9 A9 41 .A
+ sta dlist_ram+9,x ; B9CB 9D 09 20 ..
+ lda #$00 ; B9CE A9 00 ..
+ sta dlist_ram+10,x ; B9D0 9D 0A 20 ..
+ lda #$20 ; B9D3 A9 20 .
+ sta dlist_ram+11,x ; B9D5 9D 0B 20 ..
+setup_vectors:
+ lda #$46 ; B9D8 A9 46 .F
+ sta VDSLST ; B9DA 8D 00 02 ...
+ lda #$BA ; B9DD A9 BA ..
+ sta VDSLST+1 ; B9DF 8D 01 02 ...
+ lda #$6D ; B9E2 A9 6D .m
+ sta VKEYBD ; B9E4 8D 08 02 ...
+ lda #$BA ; B9E7 A9 BA ..
+ sta VKEYBD_hi ; B9E9 8D 09 02 ...
+ lda #$00 ; B9EC A9 00 ..
+ sta spacebar_flag ; B9EE 85 AC ..
+ sta hyperspace_flag ; B9F0 85 AE ..
+ sta pause_flag ; B9F2 85 AF ..
+ sta select_flag ; B9F4 85 B0 ..
+ lda #$00 ; B9F6 A9 00 ..
+ sta SDLSTL ; B9F8 8D 30 02 .0.
+ lda #$20 ; B9FB A9 20 .
+ sta SDLSTH ; B9FD 8D 31 02 .1.
+ lda #$22 ; BA00 A9 22 ."
+ sta DMACTL ; BA02 8D 00 D4 ...
+ sta SDMCTL ; BA05 8D 2F 02 ./.
+ lda #$00 ; BA08 A9 00 ..
+ sta COLOR4 ; BA0A 8D C8 02 ...
+ lda #$CA ; BA0D A9 CA ..
+ sta COLOR0 ; BA0F 8D C4 02 ...
+ lda #$38 ; BA12 A9 38 .8
+ sta COLOR1 ; BA14 8D C5 02 ...
+ lda #$7E ; BA17 A9 7E .~
+ sta COLOR2 ; BA19 8D C6 02 ...
+ lda #$04 ; BA1C A9 04 ..
+ sta PACTL ; BA1E 8D 02 D3 ...
+ lda #$03 ; BA21 A9 03 ..
+ sta SKCTL ; BA23 8D 0F D2 ...
+ lda #$00 ; BA26 A9 00 ..
+ sta GRACTL ; BA28 8D 1D D0 ...
+ sta AUDCTL ; BA2B 8D 08 D2 ...
+ lda #$01 ; BA2E A9 01 ..
+ sta PRIOR ; BA30 8D 1B D0 ...
+ lda #$04 ; BA33 A9 04 ..
+ sta CONSOL ; BA35 8D 1F D0 ...
+ lda #$C0 ; BA38 A9 C0 ..
+ sta POKMSK ; BA3A 85 10 ..
+ sta IRQEN ; BA3C 8D 0E D2 ...
+ lda #$C0 ; BA3F A9 C0 ..
+ sta NMIEN ; BA41 8D 0E D4 ...
+ cli ; BA44 58 X
+ rts ; BA45 60 `
+
+; ----------------------------------------------------------------------------
+; stuffed into VDSLST in setup_vectors
+dli_handler:
+ pha ; BA46 48 H
+ lda VCOUNT ; BA47 AD 0B D4 ...
+ cmp #$64 ; BA4A C9 64 .d
+ bcc top_dli_handler ; BA4C 90 0B ..
+; handle 2nd DLI (VCOUNT == $6F)
+bottom_dli_handler:
+ sec ; BA4E 38 8
+ ror draw_ok_flag ; BA4F 66 AB f.
+ lda key_debounce_ctr ; BA51 A5 F0 ..
+ bmi LBA57 ; BA53 30 02 0.
+ inc key_debounce_ctr ; BA55 E6 F0 ..
+LBA57: pla ; BA57 68 h
+ rti ; BA58 40 @
+
+; ----------------------------------------------------------------------------
+; handle first DLI (VCOUNT == $10)
+top_dli_handler:
+ lsr draw_ok_flag ; BA59 46 AB F.
+ txa ; BA5B 8A .
+ pha ; BA5C 48 H
+ tya ; BA5D 98 .
+ pha ; BA5E 48 H
+ jsr update_sound ; BA5F 20 27 8D '.
+ pla ; BA62 68 h
+ tay ; BA63 A8 .
+ pla ; BA64 68 h
+ tax ; BA65 AA .
+ pla ; BA66 68 h
+ rti ; BA67 40 @
+
+; ----------------------------------------------------------------------------
+ sec ; BA68 38 8
+ ror spacebar_flag ; BA69 66 AC f.
+ pla ; BA6B 68 h
+ rti ; BA6C 40 @
+
+; ----------------------------------------------------------------------------
+; stuffed into VKEYBD in setup_vectors
+vkeybd_handler:
+ lda key_debounce_ctr ; BA6D A5 F0 ..
+ cmp #$10 ; BA6F C9 10 ..
+ bcs check_key_code ; BA71 B0 03 ..
+ jmp vkeybd_finish ; BA73 4C 98 BA L..
+
+; ----------------------------------------------------------------------------
+; keypress is debounced, see which key was hit
+check_key_code:
+ lda KBCODE ; BA76 AD 09 D2 ...
+ sta last_kbcode ; BA79 85 E0 ..
+ cmp #$1C ; BA7B C9 1C ..
+ beq esc_pressed ; BA7D F0 10 ..
+ cmp #$21 ; BA7F C9 21 .!
+ beq space_pressed ; BA81 F0 06 ..
+; neither space nor esc was pressed. either some other key, or no key ($ff)
+other_key_pressed:
+ sec ; BA83 38 8
+ ror hyperspace_flag ; BA84 66 AE f.
+ jmp vkeybd_finish ; BA86 4C 98 BA L..
+
+; ----------------------------------------------------------------------------
+; detonate smart bomb if any left, when game is playing
+space_pressed:
+ sec ; BA89 38 8
+ ror spacebar_flag ; BA8A 66 AC f.
+ jmp vkeybd_finish ; BA8C 4C 98 BA L..
+
+; ----------------------------------------------------------------------------
+; toggle pause mode, when game is playing
+esc_pressed:
+ lda pause_flag ; BA8F A5 AF ..
+ eor #$80 ; BA91 49 80 I.
+ sta pause_flag ; BA93 85 AF ..
+ jmp vkeybd_finish ; BA95 4C 98 BA L..
+
+; ----------------------------------------------------------------------------
+; reset debounce counter and exit
+vkeybd_finish:
+ lda #$00 ; BA98 A9 00 ..
+ sta key_debounce_ctr ; BA9A 85 F0 ..
+ sta ATRACT ; BA9C 85 4D .M
+ pla ; BA9E 68 h
+ rti ; BA9F 40 @
+
+; ----------------------------------------------------------------------------
+; see if start or select are pressed
+check_consol:
+ lda #$08 ; BAA0 A9 08 ..
+ sta CONSOL ; BAA2 8D 1F D0 ...
+ lda CONSOL ; BAA5 AD 1F D0 ...
+ and #$07 ; BAA8 29 07 ).
+ eor #$07 ; BAAA 49 07 I.
+ cmp #$01 ; BAAC C9 01 ..
+ beq start_pressed ; BAAE F0 16 ..
+ cmp #$02 ; BAB0 C9 02 ..
+ beq select_pressed ; BAB2 F0 01 ..
+; several code paths jump here instead of doing their own RTS
+consol_done:
+ rts ; BAB4 60 `
+
+; ----------------------------------------------------------------------------
+; user pressed select key, ignore if game is playing & not paused
+select_pressed:
+ bit pause_flag ; BAB5 24 AF $.
+ bmi handle_select ; BAB7 30 03 0.
+ jmp consol_done ; BAB9 4C B4 BA L..
+
+; ----------------------------------------------------------------------------
+handle_select:
+ sec ; BABC 38 8
+ ror select_flag ; BABD 66 B0 f.
+ lda #$00 ; BABF A9 00 ..
+ sta ATRACT ; BAC1 85 4D .M
+ jmp consol_done ; BAC3 4C B4 BA L..
+
+; ----------------------------------------------------------------------------
+; user pressed start key, ignore if game is playing & not paused
+start_pressed:
+ bit pause_flag ; BAC6 24 AF $.
+ bpl ignore_start ; BAC8 10 07 ..
+ sec ; BACA 38 8
+ ror start_flag ; BACB 66 BE f.
+ lda #$00 ; BACD A9 00 ..
+ sta ATRACT ; BACF 85 4D .M
+; don't handle start key while game is playing & not paused
+ignore_start:
+ jmp consol_done ; BAD1 4C B4 BA L..
+
+; ----------------------------------------------------------------------------
+spawn_baiter:
+ lda sprite_y ; BAD4 A5 DF ..
+ cmp ship_y_pos ; BAD6 C5 C4 ..
+ bcs LBADF ; BAD8 B0 05 ..
+ inc sprite_y ; BADA E6 DF ..
+ jmp LBAE1 ; BADC 4C E1 BA L..
+
+; ----------------------------------------------------------------------------
+LBADF: dec sprite_y ; BADF C6 DF ..
+LBAE1: lda ship_delta ; BAE1 A5 D5 ..
+ bpl LBAEA ; BAE3 10 05 ..
+ eor #$FF ; BAE5 49 FF I.
+ clc ; BAE7 18 .
+ adc #$01 ; BAE8 69 01 i.
+LBAEA: clc ; BAEA 18 .
+ adc #$02 ; BAEB 69 02 i.
+ sta $E5 ; BAED 85 E5 ..
+ sec ; BAEF 38 8
+ lda $91 ; BAF0 A5 91 ..
+ sbc $DD ; BAF2 E5 DD ..
+ sta sprite_x ; BAF4 85 E3 ..
+ lda $92 ; BAF6 A5 92 ..
+ sbc $DE ; BAF8 E5 DE ..
+ sta $E4 ; BAFA 85 E4 ..
+ bcs LBB10 ; BAFC B0 12 ..
+ lda sprite_x ; BAFE A5 E3 ..
+ eor #$FF ; BB00 49 FF I.
+ sta sprite_x ; BB02 85 E3 ..
+ lda $E4 ; BB04 A5 E4 ..
+ eor #$FF ; BB06 49 FF I.
+ sta $E4 ; BB08 85 E4 ..
+ inc sprite_x ; BB0A E6 E3 ..
+ bne LBB10 ; BB0C D0 02 ..
+ inc $E4 ; BB0E E6 E4 ..
+LBB10: lda $E4 ; BB10 A5 E4 ..
+ bne LBB28 ; BB12 D0 14 ..
+ lda sprite_x ; BB14 A5 E3 ..
+ cmp #$20 ; BB16 C9 20 .
+ bcs LBB28 ; BB18 B0 0E ..
+ ldy $98 ; BB1A A4 98 ..
+ lda sprite_list+128,y ; BB1C B9 6B 0B .k.
+ sta $E5 ; BB1F 85 E5 ..
+ lda sprite_list+129,y ; BB21 B9 6C 0B .l.
+ bpl LBB4E ; BB24 10 28 .(
+ bmi LBB32 ; BB26 30 0A 0.
+LBB28: lda $DD ; BB28 A5 DD ..
+ cmp $91 ; BB2A C5 91 ..
+ lda $DE ; BB2C A5 DE ..
+ sbc $92 ; BB2E E5 92 ..
+ bcc LBB4E ; BB30 90 1C ..
+LBB32: sec ; BB32 38 8
+ lda $DD ; BB33 A5 DD ..
+ sbc $E5 ; BB35 E5 E5 ..
+ sta $DD ; BB37 85 DD ..
+ lda $DE ; BB39 A5 DE ..
+ sbc #$00 ; BB3B E9 00 ..
+ sta $DE ; BB3D 85 DE ..
+ ldy $98 ; BB3F A4 98 ..
+ lda $E5 ; BB41 A5 E5 ..
+ sta sprite_list+128,y ; BB43 99 6B 0B .k.
+ lda #$FF ; BB46 A9 FF ..
+ sta sprite_list+129,y ; BB48 99 6C 0B .l.
+ jmp LBB65 ; BB4B 4C 65 BB Le.
+
+; ----------------------------------------------------------------------------
+LBB4E: clc ; BB4E 18 .
+ lda $E5 ; BB4F A5 E5 ..
+ adc $DD ; BB51 65 DD e.
+ sta $DD ; BB53 85 DD ..
+ lda $DE ; BB55 A5 DE ..
+ adc #$00 ; BB57 69 00 i.
+ sta $DE ; BB59 85 DE ..
+ ldy $98 ; BB5B A4 98 ..
+ lda $E5 ; BB5D A5 E5 ..
+ sta sprite_list+128,y ; BB5F 99 6B 0B .k.
+ sta sprite_list+129,y ; BB62 99 6C 0B .l.
+LBB65: lda #$03 ; BB65 A9 03 ..
+ sta $94 ; BB67 85 94 ..
+ lda animation_counter ; BB69 A5 85 ..
+ adc #$0C ; BB6B 69 0C i.
+ and #$07 ; BB6D 29 07 ).
+ bne LBB74 ; BB6F D0 03 ..
+ jsr L9A9C ; BB71 20 9C 9A ..
+LBB74: lda #$18 ; BB74 A9 18 ..
+ sta $88 ; BB76 85 88 ..
+ jmp LA5B2 ; BB78 4C B2 A5 L..
+
+; ----------------------------------------------------------------------------
+; decide whether to spawn a baiter
+baiter_check:
+ lda level_jiffies_hi ; BB7B A5 F6 ..
+ beq bc_done ; BB7D F0 23 .#
+ cmp #$02 ; BB7F C9 02 ..
+ bcs bc_spawn ; BB81 B0 0A ..
+ lda enemy_count ; BB83 A5 9C ..
+ ora landers_to_spawn ; BB85 05 9B ..
+ ora baiter_count ; BB87 05 9D ..
+ cmp #$04 ; BB89 C9 04 ..
+ bcs bc_done ; BB8B B0 15 ..
+; yes, spawn it
+bc_spawn:
+ jsr L8D0C ; BB8D 20 0C 8D ..
+ lda $91 ; BB90 A5 91 ..
+ sta $DD ; BB92 85 DD ..
+ lda $92 ; BB94 A5 92 ..
+ sta $DE ; BB96 85 DE ..
+ lda #$07 ; BB98 A9 07 ..
+ sta current_sprite ; BB9A 85 F9 ..
+ jsr spawn_sprite ; BB9C 20 ED AB ..
+ jsr play_materialize ; BB9F 20 32 8E 2.
+bc_done:rts ; BBA2 60 `
+
+; ----------------------------------------------------------------------------
+filler_bba3:
+ .byte $00,$00,$00,$08,$00,$00,$00,$00 ; BBA3 00 00 00 08 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BBAB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$08,$00,$00,$00,$00 ; BBB3 00 00 00 08 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BBBB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$08,$00,$00,$00,$00 ; BBC3 00 00 00 08 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BBCB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$08,$00,$00,$00,$00 ; BBD3 00 00 00 08 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BBDB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$08,$00,$00,$00,$00 ; BBE3 00 00 00 08 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BBEB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$08,$00,$00,$00,$00 ; BBF3 00 00 00 08 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BBFB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC03 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC0B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC13 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC1B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC23 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC2B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC33 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC3B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC43 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC4B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC53 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC5B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC63 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC6B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC73 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC7B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC83 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC8B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC93 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BC9B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BCA3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BCAB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$10 ; BCB3 00 00 00 00 00 00 00 10 ........
+ .byte $00,$00,$00,$00,$08,$00,$00,$10 ; BCBB 00 00 00 00 08 00 00 10 ........
+ .byte $02,$08,$00,$00,$01,$00,$00,$10 ; BCC3 02 08 00 00 01 00 00 10 ........
+ .byte $00,$00,$00,$00,$09,$00,$00,$10 ; BCCB 00 00 00 00 09 00 00 10 ........
+ .byte $02,$08,$00,$00,$01,$00,$00,$10 ; BCD3 02 08 00 00 01 00 00 10 ........
+ .byte $00,$00,$00,$00,$08,$00,$00,$10 ; BCDB 00 00 00 00 08 00 00 10 ........
+ .byte $02,$08,$00,$00,$01,$00,$00,$10 ; BCE3 02 08 00 00 01 00 00 10 ........
+ .byte $00,$00,$00,$00,$08,$00,$00,$10 ; BCEB 00 00 00 00 08 00 00 10 ........
+ .byte $02,$08,$00,$00,$00,$00,$00,$10 ; BCF3 02 08 00 00 00 00 00 10 ........
+ .byte $00,$00,$00,$00,$08,$00,$01,$00 ; BCFB 00 00 00 00 08 00 01 00 ........
+ .byte $00,$00,$01,$00,$01,$00,$00,$00 ; BD03 00 00 01 00 01 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$01,$00 ; BD0B 00 00 00 00 00 00 01 00 ........
+ .byte $00,$00,$01,$00,$01,$00,$00,$00 ; BD13 00 00 01 00 01 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD1B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD23 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD2B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD33 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD3B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD43 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD4B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD53 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD5B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD63 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD6B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD73 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD7B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD83 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD8B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD93 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BD9B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDA3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDAB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDB3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDBB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDC3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDCB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDD3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDDB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDE3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDEB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDF3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BDFB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE03 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE0B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE13 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE1B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE23 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE2B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE33 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE3B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE43 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE4B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE53 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE5B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE63 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE6B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE73 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE7B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE83 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE8B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE93 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BE9B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEA3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEAB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEB3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEBB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEC3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BECB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BED3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEDB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEE3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEEB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEF3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BEFB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF03 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF0B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF13 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF1B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF23 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF2B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF33 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF3B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF43 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF4B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF53 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF5B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF63 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF6B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF73 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF7B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF83 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF8B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF93 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BF9B 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFA3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFAB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFB3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFBB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFC3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFCB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFD3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFDB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFE3 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$00,$00,$00 ; BFEB 00 00 00 00 00 00 00 00 ........
+ .byte $00,$00,$00,$00,$00,$FF,$00 ; BFF3 00 00 00 00 00 FF 00 .......
+; ----------------------------------------------------------------------------
+cart_a_start:
+ .addr init_cart ; BFFA 00 80 ..
+; ----------------------------------------------------------------------------
+; 0 = cart present
+cart_a_present:
+ .byte $00 ; BFFC 00 .
+; no disk boot, yes init+start the cart, non-diagnostic
+cart_a_opts:
+ .byte $04 ; BFFD 04 .
+; ----------------------------------------------------------------------------
+cart_a_init:
+ .addr init_cart ; BFFE 00 80 ..
diff --git a/defender.info b/defender.info
new file mode 100644
index 0000000..58b2e95
--- /dev/null
+++ b/defender.info
@@ -0,0 +1,593 @@
+global {
+ outputname "defender.ca65";
+ inputname "defender.rom";
+ startaddr $8000;
+ cpu "6502";
+ comments 4;
+};
+
+# code addresses
+label { name "init_cart"; addr $8000; comment "cart_a_start points here. copy-protection setup prevents the game from starting if it's been >= 256 jiffies (~4 sec) since cold or warm start"; };
+label { name "rtclok_ok"; addr $800b; };
+label { name "init_work_ram"; addr $a268; };
+label { name "start_game"; addr $8100; comment "..."; };
+label { name "show_game_type"; addr $811f; comment "draw the text for e.g. ONE PLAYER EASY"; };
+label { name "draw_title_text"; addr $8259; comment "draw the text for DEFENDER/SELECT GAME AND PRESS THE START BUTTON"; };
+label { name "draw_demo_text"; addr $8963; comment "draw the text for DEFENDER c 1982 ATARI, during the demo game"; };
+label { name "dtt_lo"; addr $8267; comment "lda #<title_text"; };
+label { name "dtt_hi"; addr $826b; comment "lda #>title_text"; };
+label { name "dtt_loop"; addr $8271; };
+label { name "dtt_color"; addr $8279; comment "multicolor support. bytes with $Fn in the message set the color mask to nn."; };
+label { name "dtt_print"; addr $8288; };
+label { name "dtt_inc_ptr"; addr $828b; };
+label { name "dtt_done"; addr $8294; };
+label { name "check_consol"; addr $baa0; comment "see if start or select are pressed"; };
+label { name "start_pressed"; addr $bac6; comment "user pressed start key, ignore if game is playing & not paused"; };
+label { name "consol_done"; addr $bab4; comment "several code paths jump here instead of doing their own RTS"; };
+label { name "ignore_start"; addr $bad1; comment "don't handle start key while game is playing & not paused"; };
+label { name "handle_select"; addr $babc; };
+label { name "select_pressed"; addr $bab5; comment "user pressed select key, ignore if game is playing & not paused"; };
+label { name "vkeybd_handler"; addr $ba6d; comment "stuffed into VKEYBD in setup_vectors"; };
+label { name "vkeybd_finish"; addr $ba98; comment "reset debounce counter and exit"; };
+label { name "check_key_code"; addr $ba76; comment "keypress is debounced, see which key was hit"; };
+label { name "esc_pressed"; addr $ba8f; comment "toggle pause mode, when game is playing"; };
+label { name "space_pressed"; addr $ba89; comment "detonate smart bomb if any left, when game is playing"; };
+label { name "other_key_pressed"; addr $ba83; comment "neither space nor esc was pressed. either some other key, or no key ($ff)"; };
+label { name "dli_handler"; addr $ba46; comment "stuffed into VDSLST in setup_vectors"; };
+label { name "top_dli_handler"; addr $ba59; comment "handle first DLI (VCOUNT == $10)"; };
+label { name "bottom_dli_handler"; addr $ba4e; comment "handle 2nd DLI (VCOUNT == $6F)"; };
+label { name "update_sound"; addr $8d27; comment "this is for 'event' sounds like explosions, not the 'drone' nor the engine noise"; };
+label { name "us_ok"; addr $8d33; };
+label { name "us_done"; addr $8d4a; };
+label { name "ram_self_destruct_1"; addr $b47f; comment "copy protection, causes game to crash next time the player gets killed. called from several places in the code."; };
+label { name "smartbomb_check"; addr $8b8a; comment "see if player pressed the space bar (spacebar_flag >= $80)"; };
+label { name "ram_self_destruct_2"; addr $8b8e; comment "copy protection. if we're running from RAM, cause game to jump to the title screen, then refuse to start"; };
+label { name "rom_ok"; addr $8ba3; comment "if we get here, we're running from ROM"; };
+label { name "smartbomb_yes"; addr $8ba4; comment "see if we have any bombs left, if so, detonate"; };
+label { name "clear_screen"; addr $b8a1; comment "zero out $2218 - $4017 (screen actually ends at $3fc7). the only place where ram above $3fff is accessed (written to, never read, so it's OK on a 16K Atari)"; };
+label { name "next_level"; addr $83c9; comment "notice the check against $64? that's why we get stuck on level 99 over & over again"; };
+label { name "level_ok"; addr $83d7; comment "ramp up the speed on odd-numbered levels"; };
+label { name "set_game_type"; addr $80e6; };
+label { name "update_title_colors"; addr $809a; comment "rotate colors"; };
+label { name "update_title_sfx"; addr $80a6; comment "alter the drone sound's pitch"; };
+label { name "title_fx_ok"; addr $80b7; };
+label { name "title_screen_idle"; addr $8078; comment "play & fade the drone while we wait for the user to press select or start"; };
+label { name "init_title_screen"; addr $8031; };
+label { name "init_drone"; addr $8d79; comment "start the drone sound you hear at the title screen & when starting/ending a level. Also silence channel 2 (the engine noise). In BASIC this would be: SOUND 1,0,0,0:SOUND 2,255,10,15:SOUND 3,254,10,15"; };
+label { name "game_on"; addr $8369; comment "called when start button is pressed from title screen or pause mode"; };
+label { name "protection_ok"; addr $811c; };
+label { name "init_hardware"; addr $b889; };
+label { name "init_screen_ptrs"; addr $b902; };
+label { name "_isp_loop"; addr $b90e; };
+label { name "fill_offset_index_table"; addr $b937; comment "fill $1a00-$1aff with repeating pattern 00 01 02 03 ..."; };
+label { name "fill_pixel_mask_table"; addr $b94a; };
+label { name "fill_hoffset_table"; addr $b95a; comment "fill horizontal offset table (if that's what it really is): 00 00 00 00 01 01 01 01 ... to 27 27 27 27, which repeats to the end of the page"; };
+label { name "setup_display_list"; addr $b97d; comment "create display list at dlist_ram"; };
+label { name "setup_vectors"; addr $b9d8; };
+label { name "out_of_lives"; addr $b70e; };
+label { name "player_died_same_level"; addr $b6cf; };
+label { name "player_died_next_level"; addr $b6c1; comment "player collided with last enemy, cleared the level, but died"; };
+label { name "start_player_death"; addr $b64c; comment "explosion animation, then bookkeeping"; };
+label { name "flash_ship"; addr $b65c; comment "flash the ship's colors just before it explodes"; };
+label { name "flash_wait_1"; addr $b660; };
+label { name "flash_wait_2"; addr $b66f; };
+label { name "flash_wait_3"; addr $b673; };
+label { name "play_event_sound"; addr $8d4b; comment "play the sound pointed to by Y:A (lsb:msb), if another sound isn't already in progress (X is a priority I think)"; };
+label { name "priority_ok"; addr $8d59; };
+label { name "sound_not_busy"; addr $8d58; };
+label { name "play_planet_explode"; addr $8e78; };
+label { name "play_ship_died"; addr $8e6a; };
+label { name "play_extra_life"; addr $8e5c; };
+label { name "play_smartbomb"; addr $8e4e; };
+label { name "play_distress"; addr $8e40; };
+label { name "play_materialize"; addr $8e32; };
+label { name "play_human_died"; addr $8e24; };
+label { name "play_rescued"; addr $8e16; };
+label { name "play_fall"; addr $8e08; };
+label { name "play_lander_fire"; addr $8dfa; };
+label { name "play_swarmer_taunt"; addr $8dec; };
+label { name "play_mutant_taunt"; addr $8dde; };
+label { name "play_pod_died"; addr $8dd0; };
+label { name "play_baiter_died"; addr $8dc2; };
+label { name "play_lander_died"; addr $8db4; };
+label { name "play_swarmer_died"; addr $8da6; };
+label { name "play_player_fire"; addr $8d98; };
+label { name "play_silence"; addr $8d68; };
+label { name "check_hyperspace"; addr $8881; comment "did the player press a key to use hyperspace?"; };
+label { name "hyperspace_pressed"; addr $8886; comment "yes, he did"; };
+label { name "hsp_loop"; addr $8899; };
+label { name "hsp_check_demo"; addr $88ae; comment "don't ever kill the 'player' in demo mode (game_type==0)"; };
+label { name "check_hyperspace_fatal"; addr $88b2; comment "kill player if RANDOM >= $AA (in other words, 33% of the time!)"; };
+label { name "hsp_done"; addr $88bc; };
+label { name "draw_starfield"; addr $a832; comment "XXX don't know how this works yet"; };
+label { name "hyperspace_implosion"; addr $97e7; comment "looks like the ship explosion, but in reverse"; };
+label { name "ship_explosion"; addr $97d9; comment "particles"; };
+label { name "init_splosion"; addr $97f7; comment "calculate (ex|im)plosion particles for the player ship"; };
+label { name "animate_explosion"; addr $9830; };
+label { name "animate_implosion"; addr $9868; };
+label { name "animate_splosion"; addr $9895; comment "called multiple times by animate_(im|ex)plosion. uses particles set up by init_splosion"; };
+label { name "as_done"; addr $9961; };
+label { name "is_loop"; addr $97f9; };
+label { name "clear_scanner_draw_planet_and_humans"; addr $9e5e; comment "XXX don't know how this works yet"; };
+label { name "draw_scanner_border_and_planet"; addr $9fb1; comment "XXX don't know how this works yet (the planet in the scanner here!)"; };
+label { name "add_cursprite_points"; addr $a7ae; comment "add points to score based on what kind of enemy we killed. does not include points for rescued humans nor end-of-level bonus."; };
+label { name "add_points"; addr $a7b2; comment "this entry point takes a sprite type in A, used for end-of-level bonus (and...?)"; };
+label { name "draw_scores"; addr $9442; comment "draw score digits in the HUDs for both players (but not lives nor smartbombs)"; };
+label { name "draw_2_score_digits"; addr $9483; comment "called 4 times for the 4 bytes of score. does division by 10."; };
+label { name "flash_score"; addr $93bc; comment "flash the score of the current player"; };
+label { name "copy_code_to_ram"; addr $a291; comment "copy is done because the code is self-modifying"; };
+label { name "clr_ram_sprites_loop"; addr $a2aa; };
+label { name "crsl_ok"; addr $a2b4; };
+label { name "copy_ram_sprites_loop"; addr $a2c0; };
+label { name "draw_sprite_left"; addr $aa7b; comment "draw left half of ship, enemy, projectile, bomb, human. copied to RAM at draw_sprite_left_copy and called there."; };
+label { name "dsl_selfmod_lo"; addr $aa80; comment "modify operands of (the RAM copies of) instructions marked with HERE"; };
+label { name "dsl_selfmod_hi"; addr $aa89; comment "modify operands of (the RAM copies of) instructions marked with HERE"; };
+label { name "dsl_HERE_1"; addr $aabd; comment "operand gets modified"; };
+label { name "dsl_HERE_2"; addr $aac7; comment "operand gets modified"; };
+label { name "dsl_loop"; addr $aaaf; };
+label { name "draw_sprite_right"; addr $aad7; comment "draw right half of ship, enemy, projectile, bomb, human. copied to RAM at draw_sprite_right_copy and called there."; };
+label { name "dsr_selfmod_lo"; addr $aadc; comment "modify operands of (the RAM copies of) instructions marked with HERE"; };
+label { name "dsr_selfmod_hi"; addr $aae5; comment "modify operands of (the RAM copies of) instructions marked with HERE"; };
+label { name "dsr_HERE_1"; addr $ab13; comment "operand gets modified"; };
+label { name "dsr_HERE_2"; addr $ab1d; comment "operand gets modified"; };
+label { name "dsr_loop"; addr $ab05; };
+label { name "draw_sprite_left_copy"; addr $1f00; size 128; comment "self-modifying RAM copy of draw_sprite_left"; };
+label { name "draw_sprite_right_copy"; addr $1f80; size 128; comment "self-modifying RAM copy of draw_sprite_right"; };
+label { name "read_trigger"; addr $861c; comment "TRIG0 or 1 depending on which player is playing"; };
+label { name "store_trigger"; addr $8628; };
+label { name "handle_trigger"; addr $99d0; comment "trigger was pressed, decide what (if anything) to do about it"; };
+label { name "check_shot_table"; addr $99d4; comment "look for an empty slot. if the table is full (4 shots in progress, ignore this trigger press. otherwise, Y is the byte index of the empty slot ($00, $04, $08, or $0c)."; };
+label { name "shoot"; addr $99e6; comment "fire player's laser in the direction he's facing"; };
+label { name "delta_right"; addr $9a09; comment "delta for shot = 2"; };
+label { name "delta_left"; addr $9a0e; comment "delta $FE aka -2"; };
+label { name "shot_right"; addr $99f6; comment "start position for right-facing shot"; };
+label { name "shot_left"; addr $99fc; comment "start position for left-facing shot"; };
+label { name "set_start_pos"; addr $99ff; comment "set start and end to same pos"; };
+label { name "set_delta"; addr $9a10; };
+label { name "update_player_shots"; addr $9a17; comment "move and draw player shots. remove from table if they reach the end of the screen"; };
+label { name "ups_found"; addr $9a2e; };
+label { name "ups_store_x"; addr $9a48; };
+label { name "ups_done"; addr $9a7f; };
+label { name "ups_erase"; addr $9a80; };
+label { name "start_explosion"; addr $9c1a; comment "enemy or humanoid explosions, *not* the player's ship"; };
+label { name "smartbomb_flash"; addr $9c0d; comment "flash screen when bomb goes off (whether any enemies are on screen or not)"; };
+label { name "sbf_loop"; addr $9c0f; };
+label { name "spawn_sprite"; addr $abed; comment "XXX does this apply to humanoids too?"; };
+label { name "nl_wtf"; addr $83cb; comment "this branch should never be taken (means level was $FF, but it's clamped to $63 below)"; };
+label { name "nl_drone"; addr $83ea; };
+label { name "level_cleared"; addr $8427; comment "decide whether or not to resurrect dead humans"; };
+label { name "dont_repopulate"; addr $843f; };
+label { name "div_5_loop"; addr $842c; };
+label { name "draw_p1_lives_and_bombs"; addr $86b0; comment "update HUD"; };
+label { name "draw_p2_lives_and_bombs"; addr $8780; comment "update HUD"; };
+label { name "move_ship"; addr $85c9; comment "only in non-demo game"; };
+label { name "erase_ship"; addr $b588; comment "zero out memory to avoid leaving trails"; };
+label { name "erase_sprite"; addr $ab2c; comment "zero out memory to avoid leaving trails"; };
+label { name "erase_sprite_XXX"; addr $a786; comment "XXX wrapper for erase_sprite, dunno why yet"; };
+label { name "erase_baiter_right_half"; addr $a561; comment "no other enemy is a double-wide sprite, is it?"; };
+label { name "check_ship_collision"; addr $b5fb; comment "if hit, explode the ship and return with carry set. otherwise, return with carry clear."; };
+label { name "not_invuln"; addr $b600; comment "bounding box is 20x10, with X offset 3 from actual ship position."; };
+label { name "ni_cmp_abs_y"; addr $b60b; comment "if(abs(ship_y_pos - sprite_y) < 6) goto ship_collision;"; };
+label { name "ni_cmp_abs_x"; addr $b61d; comment "if(abs(ship_x_pos - sprite_x) < 11) goto ship_collision;"; };
+label { name "no_collision"; addr $b767; };
+label { name "jmp_no_coll"; addr $b621; };
+label { name "ship_collision"; addr $b624; comment "player ran into something"; };
+label { name "no_swarmers"; addr $b64a; };
+label { name "clear_baiters"; addr $b86d; comment "XXX I think this is correct, but disabling it doesn't do what I think it should"; };
+label { name "clear_temp_enemies"; addr $b769; comment "remove baiters, enemy shots, bombs. called when the player dies."; };
+label { name "destroy_planet"; addr $9e0a; comment "planet explosion sequence. doesn't set planet_dead_flag (that's done by the caller, after this returns)"; };
+label { name "spawn_swarmers"; addr $a711; comment "called when a pod dies"; };
+label { name "draw_ship"; addr $b5a1; comment "draw the player's ship (in playfield, or lives in HUD), but not the rocket exhaust"; };
+label { name "erase_exhaust"; addr $9962; comment "erase the player's rocket exhaust"; };
+label { name "erase_scanner_ship"; addr $a20c; comment "erase the player's ship (white cross) in the scanner"; };
+label { name "draw_scanner_ship"; addr $a193; comment "draw the player's ship (white cross) in the scanner"; };
+label { name "draw_scanner_sprite"; addr $a0af; comment "draw enemies/humanoids in scanner"; };
+label { name "erase_scanner_sprite"; addr $a12d; comment "erase enemies/humanoids in scanner"; };
+label { name "draw_sprite"; addr $a749; comment "draw enemies/humanoids in playfield. return with carry set if there's a ship collision (player died), else clear."; };
+label { name "ship_exhaust"; addr $9986; comment "draw the player's rocket exhaust, if he's thrusting"; };
+label { name "draw_smartbombs"; addr $8736; comment "draw smartbombs in the HUD, if any are left (max 3)"; };
+label { name "smartbombs_ok"; addr $8744; comment "A holds number of visible bombs, 1 to 3"; };
+label { name "check_extra_life"; addr $a7d6; comment "if score+1 rolled over $63 => 0, we passed 10K points. note that *all* changes to the score pass through here, so this check is always done."; };
+label { name "aep_done"; addr $a7fa; };
+label { name "read_joystick"; addr $adb0; comment "result in A and Y. notice it's inverted."; };
+label { name "read_joystick_p2"; addr $adbf; };
+label { name "check_horiz_move"; addr $ad01; comment "check for right (a&$08) or left (a&$04) movement. remember Y holds the result of read_joystick (inverted PORT(A|B) value)"; };
+label { name "apply_thrust"; addr $ad41; };
+label { name "check_ship_move"; addr $acee; comment "returns with carry clear if the ship moved, set if not. only checks one axis per call (vert or horiz). XXX magic constants and unknown locations used!"; };
+label { name "check_vert_move"; addr $ad85; comment "check for down (a&$02) or up (a&$01) movement"; };
+label { name "thrust_right"; addr $ad29; };
+label { name "thrust_left"; addr $ad64; };
+label { name "no_vert_move"; addr $ad98; comment "ship not moving up or down XXX how does this work?"; };
+label { name "move_up"; addr $ad90; comment "XXX how does this work?"; };
+label { name "move_down"; addr $ad94; comment "XXX how does this work?"; };
+label { name "demo_logic"; addr $88bd; comment "animate the demo-game ship"; };
+label { name "printchar"; addr $972e; comment "print the DSCII text character in the A reg"; };
+label { name "pch_done"; addr $9757; };
+label { name "print_copyright"; addr $9758; comment "print copyright symbol ($c0). it's double-wide, so 2 glyphs"; };
+label { name "print_crlf"; addr $9769; comment "print carriage return ($8d)"; };
+label { name "print_space"; addr $9772; comment "print a space ($a0)"; };
+label { name "print_digit"; addr $977b; comment "print a number ($b0-$ba)"; };
+label { name "print_letter"; addr $978f; comment "print a letter ($c1-$db). does not call draw_glyph like you might expect."; };
+label { name "draw_glyph"; addr $94bc; comment "draw the glyph at address (font + glyph_offset)"; };
+label { name "pl_next_line"; addr $97a7; };
+label { name "dg_next_line"; addr $94d5; };
+label { name "print_end_level_msg"; addr $9642; comment "ATTACK WAVE n COMPLETED, BONUS x nnn"; };
+label { name "aw_loop"; addr $9652; };
+label { name "print_level"; addr $965d; };
+label { name "completed_loop"; addr $9667; };
+label { name "clamp_bonus"; addr $9672; comment "limit bonus multiplier to 5 (hundred, actually)"; };
+label { name "print_bonus_mult"; addr $967a; comment "print 1st digit of bonus multiplier (range 1-5)"; };
+label { name "print_bonus_00"; addr $9684; comment "print 00 after the 1-digit multiplier"; };
+label { name "add_bonus"; addr $96a2; comment "add the bonus * multiplier to the score, for remaining humanoids"; };
+label { name "ab_next_sprite"; addr $9698; };
+label { name "calc_bonus_index"; addr $96c7; comment "A = 7 + (level < 6 ? level : 5); // index into score_points_table"; };
+label { name "cbi_add7"; addr $96cf; comment "add 7 because that's where the bonus amounts start, in score_points_table"; };
+label { name "save_p1_state"; addr $89b9; comment "save game state to p1_sav_* area"; };
+label { name "save_p2_state"; addr $8a0d; comment "save game state to p2_sav_* area"; };
+label { name "load_p1_state"; addr $8a61; comment "restore game state from p1_sav_* area"; };
+label { name "load_p2_state"; addr $8ab5; comment "restore game state from p2_sav_* area"; };
+label { name "p1_ok"; addr $84eb; };
+label { name "prompt_screen_delay"; addr $84ee; comment "wait a while to let the next player get ready"; };
+label { name "psd_loop"; addr $84f0; };
+label { name "delay_loop"; addr $8874; comment "takes delay time in A. only ever called with A=$80 (delays a bit less than 3 frames) or A=$FF (almost 7 frames)"; };
+label { name "dl_wait"; addr $8876; };
+label { name "prompt_done"; addr $84ff; comment "either the prompt screen is finished, or we were in single-player mode & didn't need it"; };
+label { name "print_p1_text"; addr $8b09; comment "print PLAYER ONE"; };
+label { name "print_p2_text"; addr $8b3e; comment "print PLAYER TWO"; };
+label { name "clear_prompt_text"; addr $8b73; comment "print 40 spaces over the PLAYER (ONE|TWO) message"; };
+# not sure 'spawn' is quite the right word here
+label { name "spawn_humanoid"; addr $aee6; comment "'spawn' not the right word. this does all the logic for humanoids (falling, hitting the ground)"; };
+label { name "spawn_lander"; addr $b08e; };
+label { name "spawn_mutant"; addr $b2f4; };
+label { name "spawn_enemy_shot"; addr $9b86; };
+label { name "spawn_bomber"; addr $b3f1; };
+label { name "spawn_pod"; addr $b485; };
+label { name "spawn_swarmer"; addr $b4a5; };
+label { name "spawn_baiter"; addr $bad4; };
+label { name "humanoid_falling"; addr $af6e; comment "called repeatedly while a humanoid is falling"; };
+label { name "humanoid_carrying"; addr $aef4; comment "player carrying a humanoid"; };
+label { name "humanoid_abducted"; addr $af5f; comment "lander carrying a humanoid"; };
+label { name "baiter_check"; addr $bb7b; comment "decide whether to spawn a baiter"; };
+label { name "bc_done"; addr $bba2; };
+label { name "bc_spawn"; addr $bb8d; comment "yes, spawn it"; };
+label { name "get_random"; addr $8cf2; comment "variant of an LFSR. could have just use 'lda RANDOM', this is likely an artifact of Baker's Apple II heritage. Returns 'random' number in A."; };
+label { name "detonate_smartbomb"; addr $8bac; };
+label { name "smartbomb_kill_stuff"; addr $8bd0; comment "kill every enemy on the screen"; };
+label { name "kill_next"; addr $8bbd; };
+label { name "sb_kill"; addr $8cc3; comment "kill one enemy"; };
+label { name "start_enemy_explosion"; addr $9be7; comment "queue up an explosion, at first empty slot (or at last slot, if table is full)"; };
+label { name "see_next"; addr $9be9; };
+label { name "see_queue"; addr $9bf8; };
+label { name "print_game_over"; addr $b81e; };
+label { name "pgo_nextchar"; addr $b82a; };
+label { name "pgo_delay"; addr $b835; };
+label { name "pgo_delay_loop"; addr $b837; };
+label { name "clear_player_shots"; addr $b7f1; comment "clear player_shots table and erase shot graphics. called when player dies or enters hyperspace"; };
+label { name "cps_next"; addr $b7f3; };
+label { name "cps_check"; addr $b7f8; comment "see if this shot exists"; };
+label { name "cps_clear"; addr $b802; comment "shot exists, clear it"; };
+label { name "cps_clear_loop"; addr $b814; };
+label { name "preshift_sprite"; addr $ab9f; comment "create right-shifted copy of a sprite, 1-3 pixels, at sp_x+$10, sp_x+$20, sp_x+$30"; };
+label { name "preshift_all_sprites"; addr $a370; comment "this is why sprites are copied to RAM: we precalculate right-shifted copies, to speed up drawing"; };
+label { name "add_to_sprite_list"; addr $a4a5; comment "search for an empty slot. if found, add current_sprite to list, return with carry clear. if no empty slot, return with carry set."; };
+label { name "asl_next"; addr $a4a7; };
+label { name "asl_slot_found"; addr $a4b6; };
+label { name "inertia_logic"; addr $8681; comment "XXX not fully understood, stubbing this out makes the ship turn on a dime"; };
+
+# zp data addresses
+label { name "invuln_flag"; addr $ed; comment "bit 7 set = ship collisions ignored... but also you can't clear a level. always set in demo game. temporarily set when the player's ship is exploding (to avoid further collisions killing it again while it's busy dying)"; };
+label { name "ship_move_delay"; addr $93; comment "counts 0-$FF (XXX how often? per-frame?), ship only moves (?) when low 2 bits == 3 (?)"; };
+label { name "animation_counter"; addr $85; comment "for animated sprites, used to decide which frame to draw"; };
+label { name "ship_anim_counter"; addr $AA; comment "player's ship has its own animation counter"; };
+label { name "glyph_color_mask"; addr $ee; comment "used by draw_glyph, $FF = color 3, all pixels 11 (like they're stored in the ROM), $55 and $AA for printing in colors 1 and 2."; };
+label { name "current_player_shot"; addr $c2; comment "update_player_shots only updates one shot per call. this keeps track of which one, counts 0 4 8 $C."; };
+label { name "scanner_colormask"; addr $a9; };
+label { name "tmp_y"; addr $82; };
+label { name "tmp_hoffset_l"; addr $83; };
+label { name "tmp_hoffset_r"; addr $b8; };
+label { name "tmp_height"; addr $84; };
+label { name "tmp_ptr"; addr $e7; size 2; comment "used to point into screen memory by draw_glyph, also used for clearing sprite memory and blowing up the planet"; };
+label { name "preshift_ptr"; addr $80; size 2; comment "argument to preshift_sprite"; };
+label { name "random_seed"; addr $c6; size 3; comment "initialized to $f3 $12 $53 by init_cart"; };
+label { name "landers_to_spawn"; addr $9b; comment "total # of landers to spawn, on this level. each wave is max(landers_to_spawn, 5) landers, until landers_to_spawn == 0."; };
+label { name "enemy_count"; addr $9c; comment "total number of live enemies on level, not counting baiters."; };
+label { name "baiter_count"; addr $9d; comment "count of baiters on level. also used for some other purpose XXX what?"; };
+label { name "draw_ok_flag"; addr $ab; comment "bit 7 set = ok to write to screen ram (set by bottom_dli_handler, cleared by top_dli_handler)"; };
+label { name "level_jiffies_lo"; addr $87; comment "init to 0 at start of level, increments every frame while game is playing"; };
+label { name "level_jiffies_hi"; addr $f6; comment "init to 0 at start of level, increments every 256 frames while game is playing"; };
+label { name "sprite_x"; addr $e3; comment "X position of sprite, for draw_sprite_(left|right)"; };
+label { name "sprite_y"; addr $df; comment "Y position of sprite, for draw_sprite_(left|right)"; };
+label { name "ship_direction"; addr $c5; comment "which way the ship is facing. 1 = right, $FF (-1) = left."; };
+label { name "ship_delta"; addr $d5; comment "ship's movement, negative = left, 0 = stationary, positive = right. range -6 ($fa) to 6."; };
+label { name "ship_y_pos"; addr $c4; comment "lower = higher on the screen, $20 = top, $b4 = bottom"; };
+label { name "ship_x_pos"; addr $c3; comment "ship's visible X position on screen (not in the scanner). ranges $20 to $76"; };
+label { name "ship_dead_flag"; addr $ef; comment "bit 7 set = collision with something that kills us (set by ship_collision)"; };
+label { name "current_player"; addr $f1; comment "1 or 2 in 2-player games, always 1 in 1-player and demo"; };
+label { name "trigger"; addr $a3; comment "shadow of TRIG0 or 1 depending on which player is playing"; };
+label { name "current_sprite"; addr $f9; comment "0 = human. (lower 3 bits are word index into score_points_table)"; };
+label { name "planet_dead_flag"; addr $a0; comment "bit 7 set = planet has exploded (no humans, all mutants)"; };
+label { name "humanoid_count"; addr $a1; comment "initialized to $10, counts down to 0 as they die (but changing this in mid-level changes nothing, it changes right back!)"; };
+label { name "hyperspace_flag"; addr $ae; comment "bit 7 set = player pressed hyperspace key"; };
+label { name "spacebar_flag"; addr $ac; comment "bit 7 set = player pressed spacebar"; };
+label { name "enemy_firing_freq"; addr $bb; comment "starts at $3f, $1f, $0f for easy/med/hard. shifts right at start of every other level, until it reaches $03 (and stays there forever)"; };
+label { name "pause_flag"; addr $af; comment "00 = playing, $80 = paused while playing, $ff = not playing (title screen or game over)"; };
+label { name "select_flag"; addr $b0; comment "bit 7 set = select was pressed"; };
+label { name "start_flag"; addr $be; comment "bit 7 set = start was pressed"; };
+label { name "last_kbcode"; addr $e0; comment "KBCODE gets saved here by check_key_code"; };
+label { name "key_debounce_ctr"; addr $f0; comment "keypresses are ignored until this counts to $10"; };
+label { name "sound_ptr"; addr $b2; size 2; comment "points to a list of AUDF, AUDC values"; };
+label { name "sound_tempo"; addr $b5; comment "play_event_sound uses this to set cur_sound_tempo"; };
+label { name "cur_sound_tempo"; addr $b4; comment "speed of currently-playing event sound"; };
+label { name "cur_sound_timer"; addr $b6; comment "incremented each call to update_sound. when it reaches cur_sound_tempo, we increment sound_offset"; };
+label { name "sound_offset"; addr $b1; comment "offset into sound_ptr list"; };
+label { name "sound_priority"; addr $b7; comment "priority of currently-playing event sound"; };
+label { name "protection_flag"; addr $f8; comment "bit 7 set = protection check failed, game will show title screen but refuse to start"; };
+label { name "level"; addr $9a; comment "player 1 only?"; };
+label { name "lives"; addr $9e; comment "player 1 only?"; };
+label { name "smartbombs"; addr $a5; };
+label { name "players"; addr $e2; comment "1 or 2 (1 in demo mode also)"; };
+label { name "game_type"; addr $e1; comment "1-3 = 1p easy/med/hard, 4-6 = 2p e/m/h, 0 = demo"; };
+label { name "drone_volume"; addr $bd; comment "initialized to $1f by init_drone, decrements to 0 during sound fade-out"; };
+label { name "trampoline"; addr $a7; size 2; comment "indirect jmp vector"; };
+label { name "screen_ptr"; addr $c0; size 2; comment "pointer to screen memory, used by print_letter, draw_glyph, draw_sprite_(left|right), etc"; };
+
+# non-zp data addresses
+label { name "enemy_explosion_table"; addr $052b; size 128; comment "4 bytes per entry, 32 entries"; };
+label { name "splosion_particles"; addr $0400; size 256; comment "page full of random garbage, generated by init_splosion, used/altered by animate_plosion"; };
+label { name "plosion_x_start"; addr $0507; };
+label { name "plosion_y_start"; addr $0508; };
+label { name "plosion_x"; addr $0505; };
+label { name "plosion_y"; addr $0506; };
+label { name "inertia_counter"; addr $0d2d; comment "XXX"; };
+label { name "exhaust_flag"; addr $0d2b; comment "bit 7 set = draw rocket exhaust"; };
+label { name "return_carry_set"; addr $ad9e; };
+label { name "thrust_ok"; addr $ad7e; };
+label { name "return_right"; addr $ad5c; };
+label { name "horiz_acceleration"; addr $0d2e; comment "XXX"; };
+label { name "pixel_mask_table"; addr $1c00; size 256; comment "filled with repeating pattern c0 30 0c 03 c0 30 0c 03 ..."; };
+label { name "offset_index_table"; addr $1a00; comment "filled with repeating pattern 00 01 02 03 00 01 02 03... basically a modulus 4 lookup"; };
+label { name "pss_temp"; addr $0c4b; comment "16 bytes, used by preshift_sprite"; };
+label { name "vert_horiz_flag"; addr $0d2c; comment "check_ship_move uses this, bit 0 clear = check for horizontal movement, set = vertical"; };
+label { name "p2_sav_sprite_list"; addr $1800; size 256; };
+label { name "p2_sav_score"; addr $19c0; size 4; };
+label { name "p2_sav_planet_dead"; addr $19c4; };
+label { name "p2_sav_fire_freq"; addr $19c5; };
+label { name "p2_sav_lives"; addr $19c6; };
+label { name "p2_sav_bombs"; addr $19c7; };
+label { name "p2_sav_lander_wave_count"; addr $19c8; };
+label { name "p2_sav_level"; addr $19c9; };
+label { name "p1_sav_sprite_list"; addr $1600; size 256; };
+label { name "p1_sav_score"; addr $17c0; size 4; };
+label { name "p1_sav_planet_dead"; addr $79c4; };
+label { name "p1_sav_fire_freq"; addr $17c5; };
+label { name "p1_sav_lives"; addr $17c6; };
+label { name "p1_sav_bombs"; addr $17c7; };
+label { name "p1_sav_lander_wave_count"; addr $17c8; };
+label { name "p1_sav_level"; addr $17c9; };
+#label { name "player_shots"; addr $051a; size 16; comment "table of active shots, 4 entries, 4 bytes per entry: y pos, x start, x end, delta"; };
+label { name "player_shots_y"; addr $051a; comment "table of active shots, 4 entries, 4 bytes per entry: y pos, x start, x end, delta"; };
+label { name "player_shots_x_start"; addr $051b; };
+label { name "player_shots_x_end"; addr $051c; };
+label { name "player_shots_delta"; addr $051d; };
+label { name "sprite_list"; addr $0aeb; size 256; comment "enemies, humanoids, everything alive & movable. 4 bytes per entry (XXX don't know what they mean yet)"; };
+label { name "actor_list"; addr $0c6b; size 192; comment "6 bytes/entry, 32 entries max, sprites in sprite_list also an entry here XXX"; };
+label { name "y_stash"; addr $0519; comment "temp, used by print_letter and draw_glyph"; };
+label { name "cur_line"; addr $0513; comment "current line of glyph being drawn, used by print_letter and draw_glyph"; };
+label { name "last_line"; addr $0514; comment "last line of glyph being drawn, used by print_letter and draw_glyph"; };
+label { name "score"; addr $142f; size 4; comment "lsb first, binary base 100 (each byte ranges $00 to $63 (99 dec)"; };
+#range { name "dlist_ram"; start $2000; end $20c6; type bytetable; comment "basically GR.15"; };
+label { name "dlist_ram"; addr $2000; size $c7; comment "190 scanlines of GR.15 with 2 DLIs"; };
+label { name "VDSLST"; addr $200; size 2; comment "DLI vector"; };
+label { name "SDLSTL"; addr $230; comment "dlist start, lo byte"; };
+label { name "SDLSTH"; addr $231; comment "dlist start, hi byte"; };
+label { name "COLDST"; addr $244; };
+label { name "screen_ram"; addr $2218; size 7600; comment "190 scanlines * 40 bytes/line = 7600 ($1db0) bytes"; };
+label { name "screen_hi_ptrs"; addr $1e00; size 192; comment "pointers to the start of each scanline in screen memory (hi bytes)"; };
+label { name "screen_lo_ptrs"; addr $1d00; size 192; comment "pointers to the start of each scanline in screen memory (lo bytes)"; };
+label { name "horiz_offset_table"; addr $1b00; size 256; comment "coarse (byte) offset for each horizontal position, the 0th thru 39th byte on a scanline"; };
+label { name "cursor_x"; addr $1439; comment "column where printchar will print next character (range 0-$27 I think)"; };
+label { name "cursor_y"; addr $143a; comment "row where printchar will print next character (range XXX)"; };
+label { name "cursor_line"; addr $0512; comment "cursor_x times 9, scanline where next char prints (range XXX)"; };
+label { name "cursor_x_tmp"; addr $0515; };
+label { name "glyph_offset"; addr $0516; comment "offset of glyph from start of font (0, 8, 16, 24, ...), used by draw_glyph"; };
+label { name "level_initial_spawn"; addr $ae55; comment "at level start, spawn initial set of enemies"; };
+label { name "spawn_bombers"; addr $ae61; comment "not sure what's up with location $c6 here"; };
+label { name "spawn_pods"; addr $ae7d; };
+label { name "spawn_landers"; addr $ae93; };
+label { name "spb_loop"; addr $ae67; };
+label { name "spp_loop"; addr $ae82; };
+label { name "lis_done"; addr $aee5; };
+label { name "spawn_lander_wave"; addr $ae98; comment "also called from outside level_initial_spawn, for subsequent waves"; };
+
+
+# data tables
+range { name "snd_silence"; start $8e86; end $93bb; type bytetable; comment "'heard' during title screen, and when nothing else is going on"; };
+label { name "snd_extra_life"; addr $8fdc; comment "heard when player gets an extra life"; };
+label { name "snd_materialize"; addr $8ece; comment "heard when player ship appears (start of level) or the next group of aliens appears"; };
+label { name "snd_player_fire"; addr $8e8a; comment "heard when player fires a shot"; };
+label { name "snd_smartbomb"; addr $9276; comment "heard when player detonates a smart bomb"; };
+label { name "snd_distress"; addr $8f12; comment "heard when lander picks up a humanoid"; };
+label { name "table_8f6f"; addr $8f6f; comment "this is in the middle of the sound effects, but it doesn't look like sound data (and doesn't sound like it either)"; };
+label { name "snd_rescued"; addr $92e2; comment "heard when player catches or drops off a human, or when one lands safely on the ground"; };
+label { name "snd_fall"; addr $90a2; comment "heard when a lander carrying a human is shot"; };
+label { name "snd_lander_fire"; addr $9060; comment "heard when a lander fires a shot"; };
+label { name "snd_planet_explode"; addr $9352; comment "heard when the last human dies and the planet asplodes"; };
+label { name "snd_human_died"; addr $92b0; comment "heard when a human dies (is absorbed, shot, or falls too far)"; };
+label { name "snd_player_died"; addr $9166; comment "heard when the player's ship explodes"; };
+label { name "snd_lander_died"; addr $90da; comment "heard when we shoot a lander (or a bomber, same sound)"; };
+label { name "snd_swarmer_taunt"; addr $901a; comment "heard when swarmers are in the area (like a bird call)"; };
+label { name "snd_mutant_taunt"; addr $906a; comment "heard when a mutant is after you"; };
+label { name "snd_pod_died"; addr $9208; comment "heard when a pod is killed and spawns a bunch of swarmers"; };
+label { name "snd_baiter_died"; addr $91ac; comment "heard when a baiter is shot (temporary reprieve!)"; };
+label { name "snd_swarmer_died"; addr $9120; comment "heard when a swarmer is shot"; };
+
+range { name "scanner_border_table"; start $a0ab; end $a0ae; type bytetable; };
+range { name "jump_table"; start $a582; end $a591; type addrtable; };
+range { name "scanner_colormask_table"; start $a592; end $a5b1; type bytetable; };
+range { name "attack_wave_text"; start $96d6; end $96ed; type bytetable; };
+range { name "completed_text"; start $96ee; end $972d; type bytetable; };
+range { name "game_type_table"; start $80f9; end $80ff; type bytetable; comment "game select table (7 entries: demo, 1p easy/med/hard, 2p easy/med/hard)"; };
+range { name "game_type_text_ptrs"; start $8148; end $8155; type addrtable; comment "the strings these point to are 37 characters long, null-terminated, ASCII with high bit set (this game was ported from the Apple II, where ASCII normally has the high bit set)"; };
+range { name "gttxt_demo"; start $8156; end $817a; type bytetable; comment "' D E F E N D E R G A M E D E M O'"; };
+range { name "gttxt_1p_easy"; start $817b; end $819f; type bytetable; comment "' O N E P L A Y E R E A S Y '"; };
+range { name "gttxt_1p_normal"; start $81a0; end $81c4; type bytetable; comment "' O N E P L A Y E R N O R M A L '"; };
+range { name "gttxt_1p_hard"; start $81c5; end $81e9; type bytetable; comment "' O N E P L A Y E R H A R D '"; };
+range { name "gttxt_2p_easy"; start $81ea; end $820e; type bytetable; comment "' T W O P L A Y E R E A S Y '"; };
+range { name "gttxt_2p_normal"; start $820f; end $8233; type bytetable; comment "' T W O P L A Y E R N O R M A L '"; };
+range { name "gttxt_2p_hard"; start $8234; end $8258; type bytetable; comment "' T W O P L A Y E R H A R D '"; };
+range { name "title_text"; start $8295; end $8328; type bytetable; comment "cF, c5 are color codes. 'cF D E F E N D E RnlnlnlnlnlnlcF S E L E C T G A M E A N D P R E S Snlnl T H E S T A R T B U T T O Nnlnlnlnlc5 c) 1 9 8 2 A T A R I'"; };
+range { name "table_8329"; start $8329; end $8368; type bytetable; comment "is this used at all?"; };
+range { name "power_10_table"; start $9507; end $9509; type bytetable; comment "1, 10, 100 aka 10*0, 10*1, 10*2. used by draw_2_score_digits. last byte appears to never get read."; };
+range { name "font"; start $950a; end $9641; type bytetable; comment "13 4x8 glyphs, 0 thru 9, space, left & right halves of copyright symbol. 2bpp, but only one color used (11). really 3x8 as rightmost column is blank (for spacing) in all glyphs. height is the full 8 (no blanks for spacing)."; };
+label { name "font_letters"; addr $9572; comment "uppercase, 26 4x8 glyphs but no blank column for spacing (full 4x8). also J Q Z glyphs are graphics of some kind."; };
+range { name "demo_text"; start $898f; end $89b8; type bytetable; comment "' D E F E N D E R c 1982 A T A R I '"; };
+range { name "game_over_text"; start $b844; end $b86c; type bytetable; comment "' G A M E O V E R '"; };
+range { name "player_one_text"; start $8b21; end $8b3d; type bytetable; comment "' P L A Y E R O N E'"; };
+range { name "player_two_text"; start $8b56; end $8b72; type bytetable; comment "' P L A Y E R T W O'"; };
+range { name "score_points_table"; start $a7fd; end $a816; type wordtable; comment "binary base 100. msb first (unlike score!). 0132 = 100*$01+$32 = 150 decimal. order: human (0), lander (150), mutant (150), enemy shot or bomber bomb (25, only by colliding with ship), bomber (250), pod (1000), swarmer (200), baiter (200), rest are bonus"; };
+range { name "sprite_ram_addrs"; start $ab57; end $ab8e; type addrtable; comment "used by draw_sprite_(left|right)"; };
+range { name "sprite_table_offsets"; start $ab8f; end $ab9e; type bytetable; comment "basically just a mul-by-16 table"; };
+label { name "sprite_heights"; addr $ab97; comment "used to avoid drawing extra empty sprite rows, if they're shorter than full height"; };
+range { name "accel_table"; start $ada0; end $adaf; type bytetable; comment "used for accelerating/decelarating the ship"; };
+range { name "level_spawn_table"; start $ae49; end $ae54; type bytetable; comment "3 bytes per entry: # bombers, # pods, # landers per wave"; };
+label { name "lst_pods"; addr $ae4a;};
+label { name "lst_landers"; addr $ae4b;};
+range { name "swarmer_spawn_y_offsets"; start $b568; end $b587; type bytetable; comment "XXX I *think* that's what this is"; };
+range { name "filler_bba3"; start $bba3; end $bff9; type bytetable; };
+range { name "sprom_humanoid"; start $a8b3; end $a8c2; type bytetable; comment "single-wide, non-animated, copied to $0d2f"; };
+range { name "sprom_lander_1"; start $a8c3; end $a8d2; type bytetable; comment "single-wide, animated, copied to $0d6f"; };
+range { name "sprom_lander_2"; start $a8d3; end $a8e2; type bytetable; comment "copied to $0daf"; };
+range { name "sprom_mutant_1"; start $a8e3; end $a8f2; type bytetable; comment "single-wide, animated, copied to $0def"; };
+range { name "sprom_mutant_2"; start $a8f3; end $a902; type bytetable; comment "copied to $0e2f"; };
+range { name "sprom_rship_l_1"; start $a903; end $a912; type bytetable; comment "right-facing ship, double-wide, animated, copied to $0e6f"; };
+range { name "sprom_rship_r_1"; start $a913; end $a922; type bytetable; comment "copied to $0eaf"; };
+range { name "sprom_rship_l_2"; start $a923; end $a932; type bytetable; comment "copied to $0eef"; };
+range { name "sprom_rship_r_2"; start $a933; end $a942; type bytetable; comment "copied to $0f2f"; };
+range { name "sprom_lship_l_1"; start $a943; end $a952; type bytetable; comment "left-facing ship, double-wide, animated, copied to $0f6f"; };
+range { name "sprom_lship_r_1"; start $a953; end $a962; type bytetable; comment "copied to $0faf"; };
+range { name "sprom_lship_l_2"; start $a963; end $a972; type bytetable; comment "copied to $0fef"; };
+range { name "sprom_lship_r_2"; start $a973; end $a982; type bytetable; comment "copied to $102f"; };
+range { name "sprom_bullet"; start $a983; end $a992; type bytetable; comment "enemy shot, single-wide, non-animated, copied to $106f"; };
+range { name "sprom_bomber_1"; start $a993; end $a9a2; type bytetable; comment "single-wide, animated, copied to $10af"; };
+range { name "sprom_bomber_2"; start $a9a3; end $a9b2; type bytetable; comment "copied to $10ef"; };
+range { name "sprom_xbomb"; start $a9b3; end $a9c2; type bytetable; comment "bomber's bomb, single-wide, non-animated, copied to $112f"; };
+range { name "sprom_rflame_1"; start $a9c3; end $a9d2; type bytetable; comment "player's exhaust flame, right-facing, single-wide, animated, copied to $11ef"; };
+range { name "sprom_rflame_2"; start $a9d3; end $a9e2; type bytetable; comment "copied to $122f"; };
+range { name "sprom_lflame_1"; start $a9e3; end $a9f2; type bytetable; comment "player's exhaust flame, left-facing, single-wide, animated, copied to $116f"; };
+range { name "sprom_lflame_2"; start $a9f3; end $aa02; type bytetable; comment "copied to $11af"; };
+range { name "sprom_pod_1"; start $aa03; end $aa12; type bytetable; comment "single-wide, animated, copied to $126f"; };
+range { name "sprom_pod_2"; start $aa13; end $aa22; type bytetable; comment "copied to $12af"; };
+range { name "sprom_swarmer"; start $aa23; end $aa32; type bytetable; comment "single-wide, non-animated, copied to $12ef"; };
+range { name "sprom_baiter_l"; start $aa33; end $aa42; type bytetable; comment "double-wide, non-animated, copied to $132f"; };
+range { name "sprom_baiter_r"; start $aa43; end $aa52; type bytetable; comment "copied to $136f"; };
+range { name "sprom_smartbomb_1"; start $aa53; end $aa62; type bytetable; comment "single-wide, animated, copied to $13af"; };
+range { name "sprom_smartbomb_2"; start $aa63; end $aa72; type bytetable; comment "copied to $13ef"; };
+range { name "table_aa73"; start $aa73; end $aa7a; type bytetable; comment "XXX what (if anything) is this used for?"; };
+range { name "table_ae15"; start $ae15; end $ae16; type bytetable; };
+
+# not used by defender ($9ffa-$9fff has code in it)
+#range { name "cart_b_start"; start $9ffa; end $9ffb; type addrtable; };
+#range { name "cart_b_present"; start $9ffc; end $9ffc; type bytetable; };
+#range { name "cart_b_opts"; start $9ffd; end $9ffd; type bytetable; };
+#range { name "cart_b_init"; start $9ffe; end $9fff; type addrtable; };
+
+range { name "cart_a_start"; start $bffa; end $bffb; type addrtable; };
+range { name "cart_a_present"; start $bffc; end $bffc; type bytetable; comment "0 = cart present"; };
+range { name "cart_a_opts"; start $bffd; end $bffd; type bytetable; comment "no disk boot, yes init+start the cart, non-diagnostic"; };
+range { name "cart_a_init"; start $bffe; end $bfff; type addrtable; };
+label { name "sp_humanoid"; addr $0d2f; comment "ram copies of sprites. sp_x is the original sprite. sp_x+$10, sp_x+$20, sp_x+$30 are right-shifted copies, by 1/2/3 pixels respectively"; };
+label { name "sp_lander_1"; addr $0d6f; };
+label { name "sp_lander_2"; addr $0daf; };
+label { name "sp_mutant_1"; addr $0def; };
+label { name "sp_mutant_2"; addr $0e2f; };
+label { name "sp_rship_l_1"; addr $0e6f; };
+label { name "sp_rship_r_1"; addr $0eaf; };
+label { name "sp_rship_l_2"; addr $0eef; };
+label { name "sp_rship_r_2"; addr $0f2f; };
+label { name "sp_lship_l_1"; addr $0f6f; };
+label { name "sp_lship_r_1"; addr $0faf; };
+label { name "sp_lship_l_2"; addr $0fef; };
+label { name "sp_lship_r_2"; addr $102f; };
+label { name "sp_bullet"; addr $106f; };
+label { name "sp_bomber_1"; addr $10af; };
+label { name "sp_bomber_2"; addr $10ef; };
+label { name "sp_xbomb"; addr $112f; };
+label { name "sp_rflame_1"; addr $11ef; };
+label { name "sp_rflame_2"; addr $122f; };
+label { name "sp_lflame_1"; addr $116f; };
+label { name "sp_lflame_2"; addr $11af; };
+label { name "sp_pod_1"; addr $126f; };
+label { name "sp_pod_2"; addr $12af; };
+label { name "sp_swarmer"; addr $12ef; };
+label { name "sp_baiter_l"; addr $132f; };
+label { name "sp_baiter_r"; addr $136f; };
+label { name "sp_smartbomb_1"; addr $13af; };
+label { name "sp_smartbomb_2"; addr $13ef; };
+
+label { name "RTCLOK"; addr $12; size 3; };
+label { name "POKMSK"; addr $10; };
+label { name "ATRACT"; addr $4d; };
+label { name "VKEYBD"; addr $0208; comment "=== page 2 OS equates"; };
+label { name "VKEYBD_hi"; addr $0209; };
+label { name "SDMCTL"; addr $022f; };
+label { name "GPRIOR"; addr $026f; };
+label { name "PCOLR0"; addr $02c0; };
+label { name "PCOLR1"; addr $02c1; };
+label { name "PCOLR2"; addr $02c2; };
+label { name "PCOLR3"; addr $02c3; };
+label { name "COLOR0"; addr $02c4; };
+label { name "COLOR1"; addr $02c5; };
+label { name "COLOR2"; addr $02c6; };
+label { name "COLOR3"; addr $02c7; };
+label { name "COLOR4"; addr $02c8; };
+label { name "CHBAS"; addr $02f4; };
+label { name "HPOSP3"; addr $d003; comment "=== GTIA equates"; };
+label { name "HPOSM0"; addr $d004; };
+label { name "HPOSM1"; addr $d005; };
+label { name "HPOSM2"; addr $d006; };
+label { name "HPOSM3"; addr $d007; };
+label { name "SIZEP2"; addr $d00a; };
+label { name "SIZEP3"; addr $d00b; };
+label { name "SIZEM"; addr $d00c; };
+label { name "TRIG0"; addr $d010; };
+#label { name "GRAFM"; addr $d011; }; # PMG not used, but:
+label { name "TRIG1"; addr $d011; };
+label { name "COLPM0"; addr $d012; };
+label { name "COLPM1"; addr $d013; };
+label { name "COLPF0"; addr $d016; };
+label { name "COLPF1"; addr $d017; };
+label { name "COLPF2"; addr $d018; };
+label { name "COLPF3"; addr $d019; };
+label { name "COLBK"; addr $d01a; };
+label { name "PRIOR"; addr $d01b; };
+label { name "GRACTL"; addr $d01d; };
+label { name "HITCLR"; addr $d01e; };
+label { name "CONSOL"; addr $d01f; };
+label { name "AUDF1"; addr $d200; comment "=== POKEY equates"; };
+label { name "AUDC1"; addr $d201; };
+label { name "AUDF2"; addr $d202; };
+label { name "AUDC2"; addr $d203; };
+label { name "AUDF3"; addr $d204; };
+label { name "AUDC3"; addr $d205; };
+label { name "AUDF4"; addr $d206; };
+label { name "AUDC4"; addr $d207; };
+label { name "AUDCTL"; addr $d208; };
+label { name "KBCODE"; addr $d209; };
+label { name "RANDOM"; addr $d20a; };
+label { name "IRQEN"; addr $d20e; };
+label { name "SKCTL"; addr $d20f; };
+label { name "DMACTL"; addr $d400; comment "=== ANTIC equates"; };
+label { name "DLISTL"; addr $d402; };
+label { name "DLISTH"; addr $d403; };
+label { name "HSCROL"; addr $d404; };
+label { name "PMBASE"; addr $d407; };
+label { name "CHBASE"; addr $d409; };
+label { name "WSYNC"; addr $d40a; };
+label { name "VCOUNT"; addr $d40b; };
+label { name "NMIEN"; addr $d40e; };
+#label { name "SETVBV"; addr $e45c; comment "=== OS equates"; };
+#label { name "XITVBV"; addr $e462; };
+label { name "PORTA"; addr $d300; comment "=== PIA equates"; };
+label { name "PORTB"; addr $d301; };
+label { name "PACTL"; addr $d302; };
+label { name "PBCTL"; addr $d303; };
diff --git a/defender.rom b/defender.rom
new file mode 100644
index 0000000..4cc5a7f
--- /dev/null
+++ b/defender.rom
Binary files differ
diff --git a/deftest.lbl b/deftest.lbl
new file mode 100644
index 0000000..127e3fa
--- /dev/null
+++ b/deftest.lbl
@@ -0,0 +1,918 @@
+al 00BFFE cart_a_init
+al 00BFFD cart_a_opts
+al 00BFFC cart_a_present
+al 00BFFA cart_a_start
+al 00BBA3 filler_bba3
+al 00BB8D bc_spawn
+al 00BBA2 bc_done
+al 00BB74 LBB74
+al 00BB65 LBB65
+al 00BB32 LBB32
+al 00BB4E LBB4E
+al 00BB28 LBB28
+al 00BB10 LBB10
+al 00BAEA LBAEA
+al 00BAE1 LBAE1
+al 00BADF LBADF
+al 00BAD1 ignore_start
+al 00BABC handle_select
+al 00BAB4 consol_done
+al 00BAB5 select_pressed
+al 00BAC6 start_pressed
+al 00BA83 other_key_pressed
+al 00BA89 space_pressed
+al 00BA8F esc_pressed
+al 00BA98 vkeybd_finish
+al 00BA76 check_key_code
+al 00BA6D vkeybd_handler
+al 00BA57 LBA57
+al 00BA4E bottom_dli_handler
+al 00BA59 top_dli_handler
+al 00BA46 dli_handler
+al 00B9D8 setup_vectors
+al 00B9BB LB9BB
+al 00B9A3 LB9A3
+al 00B99B LB99B
+al 00B97D setup_display_list
+al 00B97A LB97A
+al 00B96E LB96E
+al 00B96C LB96C
+al 00B95C LB95C
+al 00B95A fill_hoffset_table
+al 00B953 LB953
+al 00B94A fill_1c00_table
+al 00B943 LB943
+al 00B937 fill_1a00_table
+al 00B929 LB929
+al 00B90E _isp_loop
+al 00B8A4 LB8A4
+al 00B902 init_screen_ptrs
+al 00B87F LB87F
+al 00B871 LB871
+al 00B837 pgo_delay_loop
+al 00B835 pgo_delay
+al 00B844 game_over_text
+al 00B82A pgo_nextchar
+al 00B814 cps_clear_loop
+al 00B7F8 cps_check
+al 00B802 cps_clear
+al 00B7F3 cps_next
+al 00B7E2 LB7E2
+al 00B7AF LB7AF
+al 00B79B LB79B
+al 00B7AA LB7AA
+al 00B7BD LB7BD
+al 00B7E0 LB7E0
+al 00B770 LB770
+al 00B781 LB781
+al 00B760 LB760
+al 00B74E LB74E
+al 00B753 LB753
+al 00B81E print_game_over
+al 00B72F LB72F
+al 00B732 LB732
+al 00B705 LB705
+al 00B6F8 LB6F8
+al 00B6F2 LB6F2
+al 00B6E3 LB6E3
+al 00B70B LB70B
+al 00B6C1 player_died_next_level
+al 00B6CF player_died_same_level
+al 00B673 LB673
+al 00B66F LB66F
+al 00B660 LB660
+al 00B65C flash_ship
+al 00B64A no_swarmers
+al 00B767 LB767
+al 00B624 ship_collision
+al 00B61D LB61D
+al 00B621 LB621
+al 00B60B LB60B
+al 00B600 LB600
+al 00B5EA LB5EA
+al 00B5C4 LB5C4
+al 00B5D5 LB5D5
+al 00B55E LB55E
+al 00B559 LB559
+al 00B561 LB561
+al 00B53B LB53B
+al 00B533 LB533
+al 00B528 LB528
+al 00B526 LB526
+al 00B50D LB50D
+al 00B502 LB502
+al 00B4F5 LB4F5
+al 00B4DE LB4DE
+al 00B4D2 LB4D2
+al 00B4C8 LB4C8
+al 00B499 LB499
+al 00B493 LB493
+al 00B472 LB472
+al 00B461 LB461
+al 00B456 LB456
+al 00B452 LB452
+al 00B43B LB43B
+al 00B42F LB42F
+al 00B421 LB421
+al 00B416 LB416
+al 00B409 LB409
+al 00B3EB LB3EB
+al 00B3BE LB3BE
+al 00B3D2 LB3D2
+al 00B386 LB386
+al 00B36D LB36D
+al 00B39D LB39D
+al 00B35A LB35A
+al 00B35E LB35E
+al 00B345 LB345
+al 00B32A LB32A
+al 00B319 LB319
+al 00B2DB LB2DB
+al 00B2C4 LB2C4
+al 00B297 LB297
+al 00B24C LB24C
+al 00B23C LB23C
+al 00B23E LB23E
+al 00B219 LB219
+al 00B208 LB208
+al 00B21C LB21C
+al 00B1E0 LB1E0
+al 00B1C0 LB1C0
+al 00B1C3 LB1C3
+al 00B1A6 LB1A6
+al 00B1A9 LB1A9
+al 00B19D LB19D
+al 00B181 LB181
+al 00B18C LB18C
+al 00B22C LB22C
+al 00B100 LB100
+al 00B10D LB10D
+al 00B18F LB18F
+al 00B166 LB166
+al 00B251 LB251
+al 00B0DC LB0DC
+al 00B0CE LB0CE
+al 00B0E2 LB0E2
+al 00B0DF LB0DF
+al 00B2DE LB2DE
+al 00B0B9 LB0B9
+al 00B0AD LB0AD
+al 00B0A3 LB0A3
+al 00B077 LB077
+al 00B05C LB05C
+al 00B08D LB08D
+al 00B033 LB033
+al 00B01A LB01A
+al 00AFFF LAFFF
+al 00B040 LB040
+al 00AFC1 LAFC1
+al 00AFAE LAFAE
+al 00AFD4 LAFD4
+al 00AF8E LAF8E
+al 00B047 LB047
+al 00AF4E LAF4E
+al 00AEF4 humanoid_carrying
+al 00AF5F humanoid_abducted
+al 00AF6E humanoid_falling
+al 00AF55 LAF55
+al 00AEE5 lis_done
+al 00AE82 spp_loop
+al 00AE93 spawn_landers
+al 00AE67 spb_loop
+al 00AE7D spawn_pods
+al 00AE61 spawn_bombers
+al 00AE4B lst_landers
+al 00AE4A lst_pods
+al 00AE49 level_spawn_table
+al 00AE19 LAE19
+al 00AE12 LAE12
+al 00AE15 table_ae15
+al 00AE02 LAE02
+al 00ADDE LADDE
+al 00ADD6 LADD6
+al 00ADBF read_joystick_p2
+al 00AD98 move_up
+al 00AD94 move_down
+al 00AD7E LAD7E
+al 00AD9E LAD9E
+al 00AD5C LAD5C
+al 00ADA0 table_ada0
+al 00AD41 LAD41
+al 00AD64 thrust_left
+al 00AD29 thrust_right
+al 00AD85 check_vert_move
+al 00AD01 check_horiz_move
+al 00ADB0 read_joystick
+al 00ACDF LACDF
+al 00ACDA LACDA
+al 00ACC4 LACC4
+al 00ACA4 LACA4
+al 00ACA7 LACA7
+al 00AC74 LAC74
+al 00AC5E LAC5E
+al 00AC41 LAC41
+al 00AC21 LAC21
+al 00AC2D LAC2D
+al 00ABFE LABFE
+al 00ABEF LABEF
+al 00ABED spawn_sprite
+al 00ABDD LABDD
+al 00ABDB LABDB
+al 00ABC5 LABC5
+al 00ABD9 LABD9
+al 00ABB2 LABB2
+al 00ABA7 LABA7
+al 00AB3E LAB3E
+al 00AB05 LAB05
+al 00AAAF LAAAF
+al 00AB97 LAB97
+al 00AB8F table_ab8f
+al 00AB57 sprite_ram_addrs
+al 00AA73 table_aa73
+al 00A8B2 LA8B2
+al 00A899 LA899
+al 00A88C LA88C
+al 00A874 LA874
+al 00A844 LA844
+al 00A819 LA819
+al 00A7FA aep_done
+al 00A7D6 check_extra_life
+al 00A7CA LA7CA
+al 00A7FD score_points_table
+al 00A7A1 LA7A1
+al 00B5FB check_ship_collision
+al 00A77F LA77F
+al 00A784 LA784
+al 00A764 LA764
+al 00A734 LA734
+al 00A725 LA725
+al 00A721 LA721
+al 00A708 LA708
+al 00A705 LA705
+al 00A6F9 LA6F9
+al 00A6ED LA6ED
+al 00A6F3 LA6F3
+al 00A6FF LA6FF
+al 00A6BB LA6BB
+al 00A711 spawn_baiters
+al 00A698 LA698
+al 00A687 LA687
+al 00A673 LA673
+al 00A676 LA676
+al 00A642 LA642
+al 00A749 draw_sprite
+al 00A61D LA61D
+al 00A645 LA645
+al 00A618 LA618
+al 00A629 LA629
+al 00A5F8 LA5F8
+al 00A5EB LA5EB
+al 00A5CD LA5CD
+al 00BAD4 spawn_baiter
+al 00B4A5 spawn_swarmer
+al 00B485 spawn_pod
+al 00B3F1 spawn_bomber
+al 00B2F4 spawn_mutant
+al 00B08E spawn_lander
+al 00AEE6 spawn_humanoid
+al 00A582 jump_table
+al 00A561 erase_baiter_right_half
+al 00A56D LA56D
+al 00A556 LA556
+al 00A51F LA51F
+al 00B769 clear_temp_enemies
+al 00B86D clear_baiters
+al 00A509 LA509
+al 00A4F6 LA4F6
+al 00A4ED LA4ED
+al 00A4DD LA4DD
+al 00A520 LA520
+al 00A4B6 LA4B6
+al 00A4A7 LA4A7
+al 00AB9F LAB9F
+al 00A370 LA370
+al 00AA63 sprom_whitex_2
+al 00AA53 sprom_whitex_1
+al 00AA43 sprom_baiter_r
+al 00AA33 sprom_baiter_l
+al 00AA23 sprom_swarmer
+al 00AA13 sprom_pod_2
+al 00AA03 sprom_pod_1
+al 00A9D3 sprom_rflame_2
+al 00A9C3 sprom_rflame_1
+al 00A9F3 sprom_lflame_2
+al 00A9E3 sprom_lflame_1
+al 00A9B3 sprom_xbomb
+al 00A9A3 sprom_bomber_2
+al 00A993 sprom_bomber_1
+al 00A983 sprom_bullet
+al 00A973 sprom_lship_r_2
+al 00A963 sprom_lship_l_2
+al 00A953 sprom_lship_r_1
+al 00A943 sprom_lship_l_1
+al 00A933 sprom_rship_r_2
+al 00A923 sprom_rship_l_2
+al 00A913 sprom_rship_r_1
+al 00A903 sprom_rship_l_1
+al 00A8F3 sprom_mutant_2
+al 00A8E3 sprom_mutant_1
+al 00A8D3 sprom_lander_2
+al 00A8C3 sprom_lander_1
+al 00A8B3 sprom_humanoid
+al 00A2C0 LA2C0
+al 00A2B4 LA2B4
+al 00A2AA LA2AA
+al 00AAD7 draw_sprite_right
+al 00AA7B draw_sprite_left
+al 00A291 copy_code_to_ram
+al 00A285 LA285
+al 00A27B LA27B
+al 00A26A LA26A
+al 00A148 LA148
+al 00A0CA LA0CA
+al 00A0AF draw_scanner_sprite
+al 00A0A3 LA0A3
+al 00A08C LA08C
+al 00A072 LA072
+al 00A053 LA053
+al 00A0AB scanner_border_table
+al 00A035 LA035
+al 00A008 LA008
+al 009FF0 L9FF0
+al 009FC8 L9FC8
+al 00A039 LA039
+al 009FB8 L9FB8
+al 009F94 L9F94
+al 009F51 L9F51
+al 009F45 L9F45
+al 009F44 L9F44
+al 009F30 L9F30
+al 009F23 L9F23
+al 009ED0 L9ED0
+al 009EC3 L9EC3
+al 009E9F L9E9F
+al 009E92 L9E92
+al 009F90 L9F90
+al 009E1D L9E1D
+al 009E19 L9E19
+al 009E18 L9E18
+al 009E0A destroy_planet
+al 009DF8 L9DF8
+al 009DE6 L9DE6
+al 009DCB L9DCB
+al 009DB9 L9DB9
+al 009DDD L9DDD
+al 009D94 L9D94
+al 009D78 L9D78
+al 009D6D L9D6D
+al 009D9D L9D9D
+al 009D64 L9D64
+al 009D62 L9D62
+al 009D8E L9D8E
+al 009D44 L9D44
+al 009DAB L9DAB
+al 009D3B L9D3B
+al 009D1E L9D1E
+al 009C70 L9C70
+al 009C62 L9C62
+al 009C5F L9C5F
+al 009C6C L9C6C
+al 009C31 L9C31
+al 009C29 L9C29
+al 009C0F sbf_loop
+al 009BF8 L9BF8
+al 009BE9 L9BE9
+al 00A5B2 LA5B2
+al 009BC5 L9BC5
+al 009BE0 L9BE0
+al 009BD9 L9BD9
+al 009B8F L9B8F
+al 009B9A L9B9A
+al 009B86 spawn_enemy_shot
+al 009B79 L9B79
+al 009B5C L9B5C
+al 009B4E L9B4E
+al 009B4B L9B4B
+al 009B33 L9B33
+al 009B3B L9B3B
+al 009B18 L9B18
+al 009B0E L9B0E
+al 009AD0 L9AD0
+al 009AC3 L9AC3
+al 009ACF L9ACF
+al 009AB7 L9AB7
+al 009A9C L9A9C
+al 009A94 L9A94
+al 009A77 L9A77
+al 009A75 L9A75
+al 009A64 L9A64
+al 009A7F L9A7F
+al 009A48 L9A48
+al 009A80 L9A80
+al 009A2E L9A2E
+al 009A26 L9A26
+al 009A10 set_delta
+al 009A09 delta_right
+al 009A0E delta_left
+al 0099FF set_start_pos
+al 0099F6 shot_right
+al 0099FC shot_left
+al 0099E6 shoot
+al 0099D4 check_shot_table
+al 0099B9 L99B9
+al 009994 L9994
+al 009978 L9978
+al 009961 L9961
+al 009951 L9951
+al 009946 L9946
+al 0098F6 L98F6
+al 0098BF L98BF
+al 00989A L989A
+al 009875 L9875
+al 00983D L983D
+al 009895 L9895
+al 0097F9 L97F9
+al 009868 L9868
+al 009830 L9830
+al 0097F7 L97F7
+al 0097D9 L97D9
+al 0097A7 pl_next_line
+al 009757 pch_done
+al 00978F print_letter
+al 00977B print_digit
+al 009772 print_space
+al 009769 print_crlf
+al 009758 print_copyright
+al 0096CF cbi_add7
+al 0096C7 calc_bonus_index
+al 009698 ab_next_sprite
+al 0096A2 add_bonus
+al 009684 print_bonus_00
+al 00967A print_bonus_mult
+al 009672 clamp_bonus
+al 0096EE completed_text
+al 009667 completed_loop
+al 00965D print_level
+al 0096D6 attack_wave_text
+al 009652 aw_loop
+al 009572 font_letters
+al 00950A font
+al 0094D5 dg_next_line
+al 0094BC draw_glyph
+al 0094B8 L94B8
+al 0094B5 L94B5
+al 00949E L949E
+al 009507 power_10_table
+al 00948D L948D
+al 009488 L9488
+al 009458 L9458
+al 009483 draw_2_score_digits
+al 009426 L9426
+al 0093F8 L93F8
+al 0093E2 L93E2
+al 0093E1 L93E1
+al 0093D9 L93D9
+al 0093D2 L93D2
+al 009352 snd_planet_explode
+al 0092E2 snd_rescued
+al 0092B0 snd_human_died
+al 009276 snd_smartbomb
+al 009208 snd_pod_died
+al 0091AC snd_baiter_died
+al 009166 snd_player_died
+al 009120 snd_swarmer_died
+al 0090DA snd_lander_died
+al 0090A2 snd_fall
+al 00906A snd_mutant_taunt
+al 009060 snd_lander_fire
+al 00901A snd_swarmer_taunt
+al 008FDC snd_extra_life
+al 008F6F table_8f6f
+al 008F12 snd_distress
+al 008ECE snd_materialize
+al 008E8A snd_player_fire
+al 008E86 snd_silence
+al 008E78 play_planet_explode
+al 008E6A play_ship_died
+al 008E5C play_extra_life
+al 008E40 play_distress
+al 008E24 play_human_died
+al 008E16 play_rescued
+al 008E08 play_fall
+al 008DFA play_lander_fire
+al 008DEC play_swarmer_taunt
+al 008DDE play_mutant_taunt
+al 008DD0 play_pod_died
+al 008DC2 play_baiter_died
+al 008DB4 play_lander_died
+al 008DA6 play_swarmer_died
+al 008D98 play_player_fire
+al 008D58 sound_not_busy
+al 008D59 priority_ok
+al 008D4B play_event_sound
+al 00B47F ram_self_destruct_1
+al 008D68 play_silence
+al 008D4A us_done
+al 008D33 us_ok
+al 008D27 update_sound
+al 00A7AE add_cursprite_points
+al 00A786 erase_sprite_XXX
+al 00A12D erase_scanner_sprite
+al 009BE7 L9BE7
+al 00A7B2 add_points
+al 00A4A5 LA4A5
+al 008D0C L8D0C
+al 008C8A L8C8A
+al 008C9B L8C9B
+al 008C9E L8C9E
+al 008C7C L8C7C
+al 008CF2 get_random
+al 008C4F L8C4F
+al 008CC3 L8CC3
+al 008C69 L8C69
+al 008C43 L8C43
+al 008C33 L8C33
+al 00A592 table_a592
+al 008C0B L8C0B
+al 008C09 L8C09
+al 009C0D smartbomb_flash
+al 008BBD L8BBD
+al 008BD0 smartbomb_kill_stuff
+al 008E4E play_smartbomb
+al 008BAC detonate_smartbomb
+al 008BA3 rom_ok
+al 00B568 table_b568
+al 008B8E ram_self_destruct_2
+al 008BA4 smartbomb_yes
+al 008B7F L8B7F
+al 008B55 L8B55
+al 008B56 player_two_text
+al 008B4A L8B4A
+al 008B20 L8B20
+al 008B21 player_one_text
+al 008B15 L8B15
+al 008AC7 L8AC7
+al 008AB7 L8AB7
+al 008AB5 load_p2_state
+al 008A73 L8A73
+al 008A63 L8A63
+al 008A61 load_p1_state
+al 008A1F L8A1F
+al 008A0F L8A0F
+al 0089CB L89CB
+al 0089BB L89BB
+al 00898B L898B
+al 00898F demo_text
+al 008980 L8980
+al 0089B5 L89B5
+al 008963 draw_demo_text
+al 008946 L8946
+al 008952 L8952
+al 00894C L894C
+al 008959 L8959
+al 00891C L891C
+al 0088E4 L88E4
+al 0088F0 L88F0
+al 0088DD L88DD
+al 00892B L892B
+al 0088D1 L88D1
+al 00B64C start_player_death
+al 0088B2 check_hyperspace_fatal
+al 0088BC hsp_done
+al 0088AE hsp_check_demo
+al 0097E7 L97E7
+al 008899 hsp_loop
+al 00B7F1 clear_player_shots
+al 008E32 play_materialize
+al 008886 hyperspace_pressed
+al 008876 L8876
+al 008867 L8867
+al 008838 L8838
+al 008854 L8854
+al 008830 L8830
+al 00882D L882D
+al 00881D L881D
+al 008801 L8801
+al 0087E9 L87E9
+al 0087D1 L87D1
+al 0087DB L87DB
+al 00880B L880B
+al 0087F3 L87F3
+al 0087B6 L87B6
+al 0087B3 L87B3
+al 0087A7 L87A7
+al 008787 L8787
+al 008773 L8773
+al 00AB2C erase_sprite
+al 008744 smartbombs_ok
+al 008760 L8760
+al 008736 draw_smartbombs
+al 00871A L871A
+al 008702 L8702
+al 0086EA L86EA
+al 0086F4 L86F4
+al 008724 L8724
+al 00870C L870C
+al 0086D0 L86D0
+al 00868D L868D
+al 008699 L8699
+al 0086AF L86AF
+al 0086A5 L86A5
+al 00867B L867B
+al 00865E L865E
+al 00863E L863E
+al 0099D0 handle_trigger
+al 008628 store_trigger
+al 00A193 draw_scanner_ship
+al 009986 ship_exhaust
+al 00B5A1 draw_ship
+al 008650 L8650
+al 008630 L8630
+al 008677 L8677
+al 008670 L8670
+al 008603 L8603
+al 00861C read_trigger
+al 0085EB L85EB
+al 0085F3 L85F3
+al 00ACEE LACEE
+al 0085DF L85DF
+al 008681 L8681
+al 0085D2 L85D2
+al 0088BD demo_logic
+al 0085C9 L85C9
+al 009962 erase_exhaust
+al 00B588 erase_ship
+al 00A20C erase_scanner_ship
+al 0085B9 L85B9
+al 009C1A start_explosion
+al 009A17 draw_player_shots
+al 008881 check_hyperspace
+al 0085AA L85AA
+al 00859F L859F
+al 008595 L8595
+al 00858B L858B
+al 0093BC flash_score
+al 00857F L857F
+al 008582 L8582
+al 00BB7B baiter_check
+al 00AE98 spawn_lander_wave
+al 00854C L854C
+al 00A4CC LA4CC
+al 00853F L853F
+al 00AC18 LAC18
+al 008B8A smartbomb_check
+al 008558 L8558
+al 00895C L895C
+al 00851C L851C
+al 00852A L852A
+al 008511 L8511
+al 008503 L8503
+al 008B73 clear_prompt_text
+al 0084F0 psd_loop
+al 008B09 print_p1_text
+al 0084EE prompt_screen_delay
+al 008B3E print_p2_text
+al 0084EB p1_ok
+al 0084FF prompt_done
+al 00849A L849A
+al 008478 L8478
+al 008465 L8465
+al 00845F L845F
+al 00B6D1 LB6D1
+al 00843F dont_repopulate
+al 00842C div_5_loop
+al 00B70E out_of_lives
+al 008414 L8414
+al 009442 draw_scores
+al 009642 print_end_level_msg
+al 00A832 LA832
+al 0083F8 L83F8
+al 0083EA nl_drone
+al 0083D7 level_ok
+al 008427 level_cleared
+al 0083CB nl_wtf
+al 0083C9 next_level
+al 00845B L845B
+al 008A0D save_p2_state
+al 0089B9 save_p1_state
+al 00AE55 level_initial_spawn
+al 00AE17 LAE17
+al 00A817 LA817
+al 008295 title_text
+al 00828B L828B
+al 008288 L8288
+al 008294 dtt_done
+al 008271 L8271
+al 00826B dtt_hi
+al 008267 dtt_lo
+al 008234 gttxt_2p_hard
+al 00820F gttxt_2p_normal
+al 0081EA gttxt_2p_easy
+al 0081C5 gttxt_1p_hard
+al 0081A0 gttxt_1p_normal
+al 00817B gttxt_1p_easy
+al 008156 gttxt_demo
+al 00972E printchar
+al 008147 L8147
+al 00813D L813D
+al 008148 game_type_text_ptrs
+al 008369 game_on
+al 00811C protection_ok
+al 0080F9 game_type_table
+al 008874 prompt_delay_loop
+al 0080C8 L80C8
+al 008100 start_game
+al 00BAA0 check_consol
+al 0080A6 update_title_sfx
+al 0080B7 title_fx_ok
+al 00809A update_title_colors
+al 008095 L8095
+al 00811F show_game_type
+al 008092 L8092
+al 008259 draw_title_text
+al 008780 L8780
+al 0086B0 draw_lives_and_bombs
+al 00808F L808F
+al 009FB1 draw_scanner_border_and_planet
+al 00B8A1 clear_screen
+al 008D79 init_drone
+al 008078 title_screen_idle
+al 0080E6 set_game_type
+al 008031 init_title_screen
+al 009E5E clear_scanner_draw_planet_and_humans
+al 009D18 L9D18
+al 00A268 init_work_ram
+al 00B889 init_hardware
+al 00800B rtclok_ok
+al 008000 init_cart
+al 00D40E NMIEN
+al 00D40B VCOUNT
+al 00D40A WSYNC
+al 00D409 CHBASE
+al 00D407 PMBASE
+al 00D404 HSCROL
+al 00D403 DLISTH
+al 00D402 DLISTL
+al 00D400 DMACTL
+al 00D303 PBCTL
+al 00D302 PACTL
+al 00D301 PORTB
+al 00D300 PORTA
+al 00D20F SKCTL
+al 00D20E IRQEN
+al 00D20A RANDOM
+al 00D209 KBCODE
+al 00D208 AUDCTL
+al 00D207 AUDC4
+al 00D206 AUDF4
+al 00D205 AUDC3
+al 00D204 AUDF3
+al 00D203 AUDC2
+al 00D202 AUDF2
+al 00D201 AUDC1
+al 00D200 AUDF1
+al 00D01F CONSOL
+al 00D01E HITCLR
+al 00D01D GRACTL
+al 00D01B PRIOR
+al 00D01A COLBK
+al 00D019 COLPF3
+al 00D018 COLPF2
+al 00D017 COLPF1
+al 00D016 COLPF0
+al 00D013 COLPM1
+al 00D012 COLPM0
+al 00D011 TRIG1
+al 00D010 TRIG0
+al 00D00C SIZEM
+al 00D00B SIZEP3
+al 00D00A SIZEP2
+al 00D007 HPOSM3
+al 00D006 HPOSM2
+al 00D005 HPOSM1
+al 00D004 HPOSM0
+al 00D003 HPOSP3
+al 0079C4 p1_sav_planet_dead
+al 002218 screen_ram
+al 002000 dlist_ram
+al 001F80 draw_sprite_right_copy
+al 001F00 draw_sprite_left_copy
+al 001E00 screen_hi_ptrs
+al 001D00 screen_lo_ptrs
+al 001B00 horiz_offset_table
+al 0019C9 p2_sav_level
+al 0019C8 p2_sav_lander_wave_count
+al 0019C7 p2_sav_bombs
+al 0019C6 p2_sav_lives
+al 0019C5 p2_sav_fire_freq
+al 0019C4 p2_sav_planet_dead
+al 0019C0 p2_sav_score
+al 001800 p2_sav_sprite_list
+al 0017C9 p1_sav_level
+al 0017C8 p1_sav_lander_wave_count
+al 0017C7 p1_sav_bombs
+al 0017C6 p1_sav_lives
+al 0017C5 p1_sav_fire_freq
+al 0017C0 p1_sav_score
+al 001600 p1_sav_sprite_list
+al 00143A cursor_y
+al 001439 cursor_x
+al 00142F score
+al 0013EF sp_whitex_2
+al 0013AF sp_whitex_1
+al 00136F sp_baiter_r
+al 00132F sp_baiter_l
+al 0012EF sp_swarmer
+al 0012AF sp_pod_2
+al 00126F sp_pod_1
+al 00122F sp_rflame_2
+al 0011EF sp_rflame_1
+al 0011AF sp_lflame_2
+al 00116F sp_lflame_1
+al 00112F sp_xbomb
+al 0010EF sp_bomber_2
+al 0010AF sp_bomber_1
+al 00106F sp_bullet
+al 00102F sp_lship_r_2
+al 000FEF sp_lship_l_2
+al 000FAF sp_lship_r_1
+al 000F6F sp_lship_l_1
+al 000F2F sp_rship_r_2
+al 000EEF sp_rship_l_2
+al 000EAF sp_rship_r_1
+al 000E6F sp_rship_l_1
+al 000E2F sp_mutant_2
+al 000DEF sp_mutant_1
+al 000DAF sp_lander_2
+al 000D6F sp_lander_1
+al 000D2F sp_humanoid
+al 000C6B actor_list
+al 000AEB sprite_list
+al 00051A player_shots
+al 000519 y_stash
+al 000516 glyph_offset
+al 000515 cursor_x_tmp
+al 000514 last_line
+al 000513 cur_line
+al 000512 cursor_line
+al 0002F4 CHBAS
+al 0002C8 COLOR4
+al 0002C7 COLOR3
+al 0002C6 COLOR2
+al 0002C5 COLOR1
+al 0002C4 COLOR0
+al 0002C3 PCOLR3
+al 0002C2 PCOLR2
+al 0002C1 PCOLR1
+al 0002C0 PCOLR0
+al 00026F GPRIOR
+al 000244 COLDST
+al 000231 SDLSTH
+al 000230 SDLSTL
+al 00022F SDMCTL
+al 000209 VKEYBD_hi
+al 000208 VKEYBD
+al 000200 VDSLST
+al 0000F9 current_sprite
+al 0000F8 protection_flag
+al 0000F6 level_jiffies_hi
+al 0000F1 current_player
+al 0000F0 key_debounce_ctr
+al 0000EF ship_dead_flag
+al 0000E3 sprite_x
+al 0000E2 players
+al 0000E1 game_type
+al 0000E0 last_kbcode
+al 0000DF sprite_y
+al 0000C6 random_seed
+al 0000C5 ship_direction
+al 0000C4 ship_y_pos
+al 0000C3 ship_x_pos
+al 0000C0 screen_ptr
+al 0000BE start_flag
+al 0000BD drone_volume
+al 0000BB enemy_firing_freq
+al 0000B7 sound_priority
+al 0000B6 cur_sound_timer
+al 0000B5 sound_speed
+al 0000B4 cur_sound_speed
+al 0000B2 sound_ptr
+al 0000B1 sound_offset
+al 0000B0 select_flag
+al 0000AF pause_flag
+al 0000AE hyperspace_flag
+al 0000AC spacebar_flag
+al 0000AB draw_ok_flag
+al 0000A7 trampoline
+al 0000A5 smartbombs
+al 0000A3 trigger
+al 0000A1 humanoid_count
+al 0000A0 planet_dead_flag
+al 00009E lives
+al 00009D baiter_count
+al 00009C enemy_count
+al 00009B landers_to_spawn
+al 00009A level
+al 000087 level_jiffies_lo
+al 00004D ATRACT
+al 000012 RTCLOK
diff --git a/dumpfont.pl b/dumpfont.pl
new file mode 100755
index 0000000..2d2e448
--- /dev/null
+++ b/dumpfont.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl -w
+
+use bytes;
+
+# dump rom as 4-color bitmap, each byte is 4 pixels wide
+$/ = \1;
+$addr = 0x8000;
+#@chars = (" ", "X", "o", ".");
+@chars = ("\x1b[30;40m ", "\x1b[30;42m ", "\x1b[30;41m ", "\x1b[30;47m ");
+
+$start = hex(shift) || 0x950a;
+$end = hex(shift) || 0x9641;
+@ARGV="defender.rom" unless @ARGV;
+
+my $pos = 0;
+my $count = 0;
+while(<>) {
+ my $str = "";
+ my @pairs;
+ my $byte = ord($_);
+ my $tmp = $byte;
+ for(my $i = 0; $i < 4; $i++) {
+ my $pixel = $tmp & 3;
+ $str = $chars[$pixel] . $str;
+ $str = $chars[$pixel] . $str;
+ $tmp >>= 2;
+ }
+ $str .= "\x1b[0m";
+ if($addr >= $start && $addr <= $end) {
+ printf "%04x: %02x |%s|\n", $addr, $byte, $str;
+ $count++;
+ print ("\n"), $count = 0 if $count == 8;
+ }
+ $addr++;
+}
diff --git a/dumpgr.pl b/dumpgr.pl
new file mode 100755
index 0000000..c382c51
--- /dev/null
+++ b/dumpgr.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl -w
+
+use bytes;
+
+# dump rom as 4-color bitmap, each byte is 4 pixels wide
+$startaddr = 0x8000;
+#@chars = (" ", "X", "o", ".");
+@chars = ("\x1b[30;40m ", "\x1b[30;42m ", "\x1b[30;41m ", "\x1b[30;47m ");
+
+$start = hex(shift) || 0xa8b3;
+$end = hex(shift) || 0xaa72;
+@ARGV="defender.rom" unless @ARGV;
+
+undef $/;
+$data = <>;
+@bytes = split "", $data;
+
+for($addr = $start; $addr < $end; $addr += 2) {
+ my $str = "";
+ my $pos = $addr - $startaddr;
+ my $word = ord($bytes[$pos + 1]) + 256 * ord($bytes[$pos]);
+ my $tmp = $word;
+ for(my $i = 0; $i < 8; $i++) {
+ my $pixel = $tmp & 3;
+ $str = $chars[$pixel] . $str;
+ $str = $chars[$pixel] . $str;
+ $tmp >>= 2;
+ }
+ $str .= "\x1b[0m";
+ if($addr >= $start && $addr <= $end) {
+ printf "%04x: %04x |%s|\n", $addr, $word, $str;
+ $count++;
+ print ("\n"), $count = 0 if $count == 8;
+ }
+}
diff --git a/dumpgttxt.c b/dumpgttxt.c
new file mode 100644
index 0000000..9b6c7e8
--- /dev/null
+++ b/dumpgttxt.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ int i;
+ unsigned char buf[16384];
+ FILE *f = fopen("defender.rom", "rb");
+ fread(buf, 16384, 1, f);
+
+ putchar('\'');
+ for(i = 0; i < 7 * 37; i++) {
+ unsigned char c = buf[i + 0x156];
+ if(!c) {
+ putchar('\'');
+ putchar('\n');
+ putchar('\'');
+ } else {
+ putchar(c - 0x80);
+ }
+ }
+}
diff --git a/dumptxt.c b/dumptxt.c
new file mode 100644
index 0000000..1c1c3cd
--- /dev/null
+++ b/dumptxt.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/* extract DSCII text from rom image, print in human-readable form.
+ usage: ./dumptxt startaddr endaddr
+ addresses are hex.
+
+ $C0: copyright symbol (double-wide), we print as 'c)'
+ $C1 - $DA: alphabet (but J Q Z are bogus-looking)
+ $B0 - $BA: numbers
+ $8D - carriage return (and newline), we print as 'nl'
+ $A0 - space
+
+ $F0-$FF set the color mask, but only in text drawn by draw_title_text.
+ We print these as cN where N is the low nybble.
+ */
+
+#define ROM "defender.rom"
+
+int main(int argc, char **argv) {
+ int i, start, end, needaddr = 1;
+ unsigned char buf[16384];
+ FILE *f = fopen(ROM, "rb");
+
+ if(argc != 3) {
+ fprintf(stderr, "Usage: %s startaddr endaddr\n give addresses in hex, e.g. %s b844 b86c\n", argv[0], argv[0]);
+ exit(1);
+ }
+
+ if(!f) {
+ perror(ROM);
+ exit(1);
+ }
+
+ fread(buf, 16384, 1, f);
+
+ start = (int)strtol(argv[1], 0, 16);
+ end = (int)strtol(argv[2], 0, 16);
+
+ if(start < 0x8000 || start >= 0xc000 || end < 0x8000 || end >= 0xc000) {
+ fprintf(stderr, "start/end addr(s) invalid or out of range, must be 8000-bfff\n");
+ exit(1);
+ }
+
+ fprintf(stderr, "dumping text from $%04x to $%04x\n", start, end);
+
+ for(i = start; i <= end; i++) {
+ unsigned char c = buf[i - 0x8000];
+
+ if(needaddr) {
+ printf("%04x: '", start);
+ needaddr = 0;
+ }
+
+ if(!c) {
+ putchar('\'');
+ putchar('\n');
+ needaddr = 1;
+ } else if(c >= 0xb0 && c <= 0xba) {
+ putchar(c - 0xb0 + '0');
+ } else if(c == 0xc0) {
+ putchar('c');
+ putchar(')');
+ } else if(c == 0xa0) {
+ putchar(' ');
+ } else if(c == 0x8d) {
+ putchar('n');
+ putchar('l');
+ } else if(c >= 0xc1 && c <= 0xda) {
+ putchar(c - 0xc1 + 'A');
+ } else if(c >= 0xf0) {
+ putchar('c');
+ if(c > 0xf9)
+ putchar(c - 0xfa + 'A');
+ else
+ putchar(c - 0xf0 + '0');
+ } else {
+ putchar('?');
+ }
+ }
+
+ if(!needaddr) {
+ putchar('\'');
+ putchar('\n');
+ fprintf(stderr, "last string not null-terminated!\n");
+ }
+ return 0;
+}
diff --git a/notes b/notes
new file mode 100644
index 0000000..e293535
--- /dev/null
+++ b/notes
@@ -0,0 +1,562 @@
+General
+-------
+
+The Atari 8-bit port of Defender is (c) 1982, Atari
+Corporation. Author is Steve A. Baker. Interviews with him:
+
+http://www.ataricompendium.com/archives/interviews/steve_baker/interview_steve_baker.html
+http://www.mobygames.com/developer/sheet/view/developerId,153781/
+
+Defender is a 16K cartridge, no bankswitching, maps to $8000-$BFFF. The
+cartridge-present byte for Cartridge B is non-zero, so the OS doesn't
+try to init or start the lower half of the cart separately.
+
+The game only uses RAM up to $3FFF [1], so it'll run on a 16K Atari
+(I first played it on a 400).
+
+There's almost 1K of filler bytes at the end of the cart (just before
+the cartridge start address). The code isn't really optimized heavily
+for space [2] (e.g. lots of jsr followed by rts, or jmp to an rts instead
+of saving 2 bytes by coding another rts), so prospective hack authors
+could make more room if needed.
+
+The author likes to use "sec : ror someflag" to set booleans, and
+"lsr someflag" to clear them, then later checks them with either "lda
+someflag" or "bit someflag" followed by bmi or bpl. Nothing wrong with
+that, it's just a fairly uncommon technique, so I mention it here.
+
+The game doesn't take advantage of the Atari hardware as much as it
+might. It doesn't use player/missile graphics, or hardware scrolling.
+This is likely because Baker first wrote the game for the Apple II (sadly,
+never released [3]), then ported it to (or rewrote it for) the Atari. Also,
+it was his first game on the Atari.
+
+[1] Actually, the code that clears the graphics screen writes a few
+bytes past $3fff, but nothing ever tries to read them, so no harm done.
+
+[2] Don't take that as a criticism. It just means the code fits
+comfortably in a 16K ROM, so there was no need to spend time shrinking it.
+
+[3] There is an Atarisoft Defender release for the Apple II, but it's
+nothing to do with Steve Baker's Defender. It looks and plays completely
+different, there's no way its codebase is related to Atari 8-bit Defender.
+
+Memory Map
+----------
+$80-$ff: various game-state and other variables, temporaries, pointers
+...
+$1b00-$1eff: precalculated data tables
+$1f00-$1fff: self-modifying code copied to RAM
+$2000-$20c6: display list (only one for the whole game, never changes)
+$2218-$3fc7: video memory (7600 bytes)
+
+Graphics
+--------
+The entire game uses a Mode E (GR.15) display. Display list:
+
+2000: 3x 8 BLANK
+2003: LMS 2218 MODE E
+2006: DLI MODE E
+2007: 87x MODE E
+205E: LMS 3000 MODE E
+2061: 100x MODE E
+20C5: DLI MODE E
+20C6: JVB 2000
+
+...total of 190 scanlines (real GR.15 is 192), contiguous screen memory
+running from $2218 to $3fc7. There's 2 DLIs, one on the 2nd visible
+scanline, the other at the bottom. Both use dli_handler, which checks
+VCOUNT to decide what to do. 2nd LMS is needed to cross a 4K boundary
+($2xxx -> $3xxx).
+
+Game doesn't use player/missile graphics at all. All graphics are
+"soft sprites" being blitted into video memory.
+
+Elements of the game display: I've named these all and tried to stick
+strictly to the naming system.
+
+There are 4 "screens": the game-select screen (DEFENDER (c) 1982 ATARI),
+the gameplay screen, the "prompt" screen (PLAYER ONE or PLAYER TWO,
+in a 2-player game; not seen in 1-player), and the game-over screen.
+Soft sprites are only rendered on the gameplay screen, and even there
+only in the playfield (see below).
+
+The top of the gameplay screen has areas on the left and right for the
+players' scores, lives, smartbombs displays. I call these HUDs. In a
+one-player game, player 2's HUD isn't displayed.
+
+In between the HUDs is the scanner.
+
+Above and below the HUDs/scanner area are a couple of horizontal lines.
+I call these the scanner border.
+
+The rest of the screen is the playfield. This is where ships, enemies,
+etc appear. Near the bottom of the playfield is the planet surface (unless
+you've managed to blow up the planet by losing all your humanoids).
+
+Soft Sprites
+------------
+
+I've barely started to tease apart the soft-sprite rendering code. What I
+do know:
+
+- Sprites are definitely used for the player's ship, enemies, enemy shots,
+ bomber's bombs, humanoids.
+
+- All sprites are defined in a 10 pixel wide grid. These are 4-color-mode
+ pixels (2bpp), so they're 20 bits wide. The left and right halves
+ are drawn separately. Sprites that appear to be <= 5 pixels wide
+ are generally the left halves (their right halves are blank).
+
+- When the ship (a full 10px wide sprite) collides with an enemy,
+ it looks like only the left half of the enemy is drawn when it
+ overlaps the ship.
+
+- Drawing is done by logical OR with whatever's already on
+ the screen.
+
+- Collision checking isn't done by the drawing code. Not yet determined
+ where this is done though.
+
+- The drawing routines (draw_sprite_left and draw_sprite_right) are
+ copied to RAM, because they're self-modifying.
+
+The in-game text and players' scores aren't drawn by the soft-sprite
+code. Instead they've got their own separate renderers.
+
+The scanner and planet surface also have their own renderer(s) (of course,
+they look totally different from everything else).
+
+sprite_list is a 128-byte table, 32 entries, 4 bytes per entry:
+
++0: ?? (0 = unused entry?)
++1: ??
++2: ??
++3: type
+
+Sprite types are:
+0 - humanoid
+1 - lander
+2 - mutant
+3 - enemy shot (or bomber bomb?)
+4 - bomber
+5 - pod
+6 - swarmer
+7 - baiter
+
+There can never be more than 32 sprites in the world (not counting the
+player's ship). That's why sometimes on higher levels it's possible to
+shoot a pod and see no baiters (or only one) come out. XXX Am I 100%
+sure of this?
+
+sp_*, sprom_* format:
+
+
+Each pixel pair is used for one of the 4 color registers, as usual
+for ANTIC mode E. The colors are:
+
+00 - COLBK - $00 (black)
+01 - COLPF0 - $CA (green)
+10 - COLPF1 - $38 (red)
+11 - COLPF2 - $7E (white)
+
+Each sprite is either 10x8 pixels, split into two 5x8 left/right halves,
+or one 5x8 half-sprite. Each half is split into two 5x8 "characters" (not
+that we're using character-cell modes, I just need a name to call this).
+In the source, the half-sprites look like this (XXX not yet they don't):
+
+gfxrom_humanoid:
+ .byte $28,$00
+ .byte $28,$00
+ .byte $14,$00
+ .byte $14,$00
+ .byte $14,$00
+ .byte $0C,$00
+ .byte $0C,$00
+ .byte $0C,$00
+
+...each pair of bytes is one row, or 5 pixels, packed into the top 10
+bits of a 16-bit *MSB first* word. Notice the 2nd byte of each row is
+$00, because the humanoid fits in a 4x8 grid (actually he's only 2px
+wide). Most of the enemies are 5px wide, except the baiter.
+
+In other words, for each byte pair, the first byte is the left-most 4
+pixels. The 2nd byte is the right-most 1 pixel, and always has 000000
+in its bottom 6 bits [1].
+
+Some of the sprites are animated (e.g. the player's ship, the pod). These
+are 2-frame animations. Each frame is a separate sprite.
+
+The sprite graphics in the ROM get labels like:
+
+sprom_humanoid (single-wide, non-animated sprite)
+sprom_lander_1 (single-wide, animated, this is frame 1, the other one will
+ be called sprom_lander_2)
+sprom_baiter_l (double-wide, non-animated, this is the left half)
+sprom_lship_l_1 (double-wide, animated, this is the left half of frame 1)
+
+For the player's ship, there are 2 sets of sprites, one facing left and
+the other facing right. I'm calling these lship and rship. Also there's
+lflame and rflame for the ship's rocket exhaust.
+
+The game doesn't read the sprite data from ROM during gameplay. Instead,
+it copies it to RAM (in init_work_ram), then reads it from there. XXX not
+100% sure why this is done or even if there's a reason. The RAM copies
+have the same labels as the ROM copies, but with sp_ instead of sprom_
+as a prefix.
+
+[1] Patching the ROM to set these bits to something else sort-of works,
+but they aren't drawn always. This is because the drawing code only
+updates 2 bytes of screen memory (which is all that's needed for 10-bit
+wide sprite). With 11 or more bits, it's possible for them to be spread
+out over 3 bytes, which the engine doesn't handle.
+
+Text Rendering
+--------------
+
+All text in the game is stored in the cartridge in an ASCII-like encoding,
+which I'll call DSCII here [1]. All character codes have their high bit
+set (so e.g. A is $41 in ASCII, $C1 in DSCII) [2].
+
+The character set:
+
+$8D: carriage return (and newline)
+$A0: space
+$B0 - $B9: numbers 0 to 9
+$C0: copyright symbol (in place of the @ from ASCII). prints double-wide.
+$C1 - $DA: alphabet A to Z (caps only, no lowercase in DSCII)
+
+Also, for the title screen text, draw_title_text supports escape codes
+to change the text color:
+
+$F0 - $FF: set glyph_color_mask. The mask gets set to NN where N is the
+ low nybble (so $FA sets the mask to $AA, e.g.)
+
+The letters J, Q, and Z are never used in the game. Their glyphs in
+the font are backwards monochrome versions of the letters that look
+multicolored when rendered. This may be an artifact of the Apple
+II version, or just leftover data from an earlier version of the
+text-rendering code.
+
+The copyright symbol is actually 2 glyphs (left & right halves).
+
+The printing code checks for a valid character from the list above,
+so attempts to print any other character fail silently. Not that the
+game ever tries to do that anyway.
+
+All the strings of text in the game are null-terminated ($00 byte, like C).
+
+The subroutine that prints DSCII characters is at $972E. I've labelled it
+'printchar'. It keeps track of its own cursor position (labelled cursor_x
+and cursor_y).
+
+[1] Defender Simplified Code, Internal Implementation :)
+
+[2] This is how characters are normally stored on the Apple II machines.
+I thought this might prove the Atari version was a port from Baker's
+unreleased Apple II version, but it turns out he used an Apple II as
+a development system while working on Defender at Atari. So even if
+the code was rewritten from scratch, it would make sense for it to use
+Apple-style ASCII codes.
+
+Scanner Rendering
+-----------------
+
+Not looked into this yet.
+
+Sound
+-----
+
+Audio channel 2 is used only for the sound of the player's engines. You
+can reproduce it in BASIC with:
+
+SOUND 1,31,8,2
+
+This plays while the joystick is pressed left or right. When the joystick
+is released (or the player clears the level, or dies), channel 2 is muted,
+the equivalent of SOUND 1,0,0,0.
+
+Audio channels 3 and 4 are used only for the 'drone' you hear on the
+title screen and briefly at the start of each level. The sound is made
+by playing the two lowest notes on the two channels. It seems to rise
+and fall because of the beat frequency caused by the two notes being
+out of tune with each other. You can reproduce this in BASIC with:
+
+SOUND 2,255,10,15:SOUND 3,254,10,15
+
+At the start/end of a level, the drone volume is steadily decreased
+until it reaches zero, so you hear the drone fade out.
+
+Audio channel 1 is used for event sounds, like explosions, distress calls,
+shots firing. This is everything except the 'drone' and engine noise.
+
+Each event sound has a priority, a tempo, and a list of AUDF1/AUDC1 values
+(which I'll call "steps"). The end of the list is marked by the volume bits
+(bits 0-3) in AUDC1 being all zero (silence).
+
+When the game wants to play a new sound and an old sound is still playing,
+the new sound will start to play if either:
+
+- its priority is equal or greater than the old sound's priority,
+- or the old sound has been playing for >=32 steps (regardless of tempo).
+
+When a new sound starts to play, any currently-playing one is replaced
+with the new one.
+
+The event sound engine is still active during the title screen, playing
+silence. You can test-play a sound (or a chunk of memory you suspect is
+a sound) from the atari800 debugger with e.g. "c b1 0 ll hh tt" where ll
+and hh are the low and high bytes of the sound's address and tt is the
+tempo (lower numbers = faster). Playing random chunks of memory won't
+hurt anything, usually makes "bump" or radio-static noises.
+
+The sound data tables in the code are named with a snd_ prefix. It turns
+out, each sound also has a specific subroutine that plays it. I've named
+these play_*. These all call a routine I've labelled play_event_sound.
+
+Once per jiffy, update_sound gets called. It sets the AUDC1/AUDF1
+registers as needed. When the end of the current sound is reached,
+it queues up snd_silence (which will start playing next jiffy), so the
+sound engine is always playing something.
+
+Bugs
+----
+
+Defender is almost bug-free. There's one actual bug (in my opinion):
+
+- Sprites drawn at the right edge of the screen are distorted. Take
+ a look at spritebug.png to see an example.
+
+There are a few things that people think of as bugs, which seem more
+like design limitations or compromises to me:
+
+- Too many objects on the screen causes slowdown. It's not much
+ of a slowdown, but it's noticeable (maybe moreso on NTSC than PAL).
+
+- If your score reaches 10 million (8 digits), the rightmost digit
+ flickers. This is just because there's only space for 7 digits, and
+ the 8th is drawn in the same spot as the smartbombs in the HUD. Did
+ anyone ever get 10 million points without cheating?
+
+- Sometimes when you shoot a pod, it doesn't spawn enough (or any)
+ swarmers. This is due to the limit of 32 sprites: if you already had
+ 30 when you shot the pod, you only get 2 swarmers.
+
+- The game gets stuck at level 99. Every time you beat level 99, the
+ next level is also level 99. This isn't a bug because there's an
+ explicit check in the code that causes it to happen. It's there
+ because the code that prints the level number only knows how to
+ print 2-digit numbers.
+
+Copy Protection
+---------------
+
+Several places in the code check to see whether the game is being
+run from RAM instead of ROM:
+
+1. init_cart checks the 2nd byte of RTCLOK to see how long the Atari has
+been running. RTCLOK+1 increments every time the RTCLOK+2 jiffy counter
+rolls over, which happens every 4.27 sec on NTSC (5.12 sec on PAL). This
+check detects whether the game was loaded from DOS, since it would take
+longer than that for DOS to boot and then load the game. If the check
+fails, bit 7 of protection_flag is set (see 3, below).
+
+2. The routine at $8b8e (ram_self_destruct_2) is called during the main
+loop of the game. It attempts to write to ROM, then checks to see if
+the write succeeded. If it did, bit 7 of protection_flag is set, then
+the game jumps to the title screen (see 3, below).
+
+3. When the user presses Start (from the title screen, or while the game
+is paused), start_game checks bit 7 of protection_flag. If it's set (due
+to checks 1 or 2 failing), it jumps back to the title screen instead of
+starting the game.
+
+4. Another routine (ram_self_destruct_2 at $b47f) writes to ROM, replacing
+the DEC opcode at $983d with $02 (an invalid opcode, crashes the CPU
+when executed). The effect is that the game plays normally when running
+from RAM until the first time you get killed, which locks up the Atari.
+
+Tools
+-----
+
+I used da65 from the cc65 suite for the disassembler, and the atari800
+emulator's monitor for poking & prodding at the code to test theories.
+If anyone cares, all the text in these files was edited with vim.
+
+I wrote a few tools of my own:
+
+dumpfont.pl - dumps the font, uses ANSI color. Try piping into less +M.
+
+dumpgr.pl - dumps the graphics (sprites).
+
+dumptxt.c, dumpgttxt.c - dumps text strings from the ROM.
+
+10 humanoids vs. 8 humanoids:
+-----------------------------
+
+TL;DR version: 10 humanoids GOOD, 8 humanoids BAAAD!
+
+The obvious difference between the two is the number of humanoids you
+start out with. The version with 10 (I call this 10H) is what I had as
+a kid. It was a real cartridge made by Atari, bought for some outlandish
+price.
+
+The 8-humanoids (8H) version is almost identical. You'll notice at the
+end of a level where you still have all 8 humanoids, they're displayed
+off-center, with space on the right for 2 more, the same as they would
+be in the 10H version if you ended a level with 8 humanoids left.
+
+I remember finding pirated versions of Defender on BBSes back in the
+300-baud days, and they were all the 8-humanoids version. I assumed
+this was an unofficial hack or a mistake made by whoever cracked the
+game... and now I'm 100% certain that I was right.
+
+The 8H image looks like a binary patch. Several places in the code
+are NOPped out, including a couple of places where the 10H code tries
+to write to ROM. The init code at $8000 is slightly different, and the
+table at $ae15 (which is DATA, not code) was modified (to $EA $EA, which
+are NOP opcodes also).
+
+Also see $ae17: "lda #$0a" was patched to "nop:asl a", which means someone
+went NOP-happy. This is where the number of humanoids get initialized
+($0a = 10). Replacing with "asl a" is a bug... it so happens that the
+accumulator always holds 4 when this code runs, which gets left-shifted
+to 8... which is exactly how many humanoids this version of the game has.
+
+[Side note: with the 10H version, you can change the byte at $AE18 to
+change the number of starting humanoids. The game starts acting weird
+when you increase this too much. Also 0 means 256 here, not 0.]
+
+How did this happen? The table at $ae15 is 2 bytes of data, right in
+the middle of a section that's otherwise code. The disassemblers available
+on the Atari weren't very smart, and generally didn't give you much help
+separating code from data. Someone disassembled this sequence of bytes:
+
+AE15: 3E 20 A9 0A
+
+...and it looked like this:
+
+ ROL $A920 ; 3E 20 A9
+ ASL A ; 0A
+
+...which looked to him like something that tried to modify ROM (since
+$A920 is in the ROM address space), so he replaced the ROL + its operand
+with NOPs.
+
+The correct disassembly looks like:
+
+ .BYTE $3E,$20 ; 3E 20
+ LDA #$0A ; A9 0A
+
+The #$0A is the number of humanoids (10 in decimal). After the bad patch,
+knowing as we do that $AE15 is a data table, the code would look like:
+
+ .BYTE $EA,$EA ; EA EA
+ NOP ; EA
+ ASL A ; 0A
+
+The operand of the LDA instruction is now an opcode, an ASL A. It so
+happens that when this code runs, the A register always has 4 in it. So
+it ends up as 8.
+
+I'm not (yet) sure what the $AE15 table is for, but changing it didn't
+make any obvious changes in gameplay. If it had caused the game to crash
+or display corrupted graphics, the cracker would have noticed that and
+gotten rid of this patch.
+
+Conclusion: the 8-humanoids version of the game started life as a dump
+of the 10-humanoids cartridge that someone hacked to get it to run
+from RAM without self-destructing. The NOPs are intended to get rid
+of the copy-protection code that makes it self-destruct if running from
+RAM... but whoever did this bungled the job, which caused the game to only
+have 8 humanoids. This was almost certainly done by an amateur cracker,
+and got circulated widely around the BBS scene as a binary load (xex) file
+and/or a bootdisk. Later on, someone found this hacked/cracked version and
+turned it back into a ROM image, which got included in the Holmes Archive.
+
+If someone out there owns a real Defender cartridge from Atari that has
+only 8 humanoids, my theory about the amateur cracker will be proved
+wrong, but that would just mean a professional programmer at Atari made
+this mistake instead of an amateur!
+
+...it turns out someone else already figured this out 7 years ago. I
+couldn't find the answer by googling, so I disassembled the code and
+stared at it until I understood it well enough to write this explanation.
+Then I showed it to someone, and he pointed me towards Fandal's analysis:
+
+http://www.atarimania.com/atari_forum/viewtopic.php?f=1&t=2356
+
+...but, it wasn't a waste of my time, I learned a lot about the code in
+the process.
+
+Fandal also figured out the first change in the init code (to defeat
+the RTCLOK check), so I didn't have to...
+
+The 2nd change in the init code is to clear the coldstart flag, so
+the Reset key doesn't reboot the Atari.
+
+Diff of 10H vs. 8H disassemblies:
+
+--- defender.ca65 2017-09-16 15:16:41.984218123 -0400
++++ defender.8humans.ca65 2017-09-16 15:16:51.914217595 -0400
+@@ -1,6 +1,6 @@
+ ; da65 V2.16 - Git 6de78c5
+-; Created: 2017-09-16 15:16:41
+-; Input file: defender.rom
++; Created: 2017-09-16 15:16:51
++; Input file: defender.8humans.rom
+ ; Page: 1
+
+
+@@ -184,14 +184,14 @@
+ pla ; 8000 68 h
+ pla ; 8001 68 h
+ lsr protection_flag ; 8002 46 F8 F.
+- lda RTCLOK+1 ; 8004 A5 13 ..
++ lda #$00 ; 8004 A9 00 ..
+ beq rtclok_ok ; 8006 F0 03 ..
+ sec ; 8008 38 8
+ ror protection_flag ; 8009 66 F8 f.
+ rtclok_ok:
+ jsr init_hardware ; 800B 20 89 B8 ..
+ jsr init_work_ram ; 800E 20 68 A2 h.
+- lda #$FF ; 8011 A9 FF ..
++ lda #$00 ; 8011 A9 00 ..
+ sta COLDST ; 8013 8D 44 02 .D.
+ lda #$F3 ; 8016 A9 F3 ..
+ sta random_seed ; 8018 85 C6 ..
+@@ -1588,7 +1588,9 @@
+ lda table_b568 ; 8B8E AD 68 B5 .h.
+ pha ; 8B91 48 H
+ eor #$FF ; 8B92 49 FF I.
+- sta table_b568 ; 8B94 8D 68 B5 .h.
++ nop ; 8B94 EA .
++ nop ; 8B95 EA .
++ nop ; 8B96 EA .
+ pla ; 8B97 68 h
+ cmp table_b568 ; 8B98 CD 68 B5 .h.
+ beq rom_ok ; 8B9B F0 06 ..
+@@ -5593,9 +5595,10 @@
+
+ ; ----------------------------------------------------------------------------
+ table_ae15:
+- .byte $3E,$20 ; AE15 3E 20 >
++ .byte $EA,$EA ; AE15 EA EA ..
+ ; ----------------------------------------------------------------------------
+-LAE17: lda #$0A ; AE17 A9 0A ..
++LAE17: nop ; AE17 EA .
++ asl a ; AE18 0A .
+ LAE19: pha ; AE19 48 H
+ jsr get_random ; AE1A 20 F2 8C ..
+ sta $DD ; AE1D 85 DD ..
+@@ -6517,7 +6520,9 @@
+ ; copy protection, causes game to crash next time the player gets killed. called from several places in the code.
+ ram_self_destruct_1:
+ lda #$02 ; B47F A9 02 ..
+- sta L983D ; B481 8D 3D 98 .=.
++ nop ; B481 EA .
++ nop ; B482 EA .
++ nop ; B483 EA .
+ rts ; B484 60 `
+
+ ; ----------------------------------------------------------------------------
diff --git a/spritebug.png b/spritebug.png
new file mode 100644
index 0000000..e3e3199
--- /dev/null
+++ b/spritebug.png
Binary files differ