From b2cad8050e2077f09535607a829183a842023da7 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Fri, 22 Sep 2017 16:09:17 -0400 Subject: initial commit --- .makepp/defender.ca65.mk | 13 + .makepp/log | 31 + Makefile | 35 + README | 26 + defender.8humans.rom | Bin 0 -> 16384 bytes defender.ca65 | 7818 ++++++++++++++++++++++++++++++++++++++++++++++ defender.info | 593 ++++ defender.rom | Bin 0 -> 16384 bytes deftest.lbl | 918 ++++++ dumpfont.pl | 35 + dumpgr.pl | 35 + dumpgttxt.c | 20 + dumptxt.c | 88 + notes | 562 ++++ spritebug.png | Bin 0 -> 1729 bytes 15 files changed, 10174 insertions(+) create mode 100644 .makepp/defender.ca65.mk create mode 100644 .makepp/log create mode 100644 Makefile create mode 100644 README create mode 100644 defender.8humans.rom create mode 100644 defender.ca65 create mode 100644 defender.info create mode 100644 defender.rom create mode 100644 deftest.lbl create mode 100755 dumpfont.pl create mode 100755 dumpgr.pl create mode 100644 dumpgttxt.c create mode 100644 dumptxt.c create mode 100644 notes create mode 100644 spritebug.png 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 Binary files /dev/null and b/defender.8humans.rom 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_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 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_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 Binary files /dev/null and b/defender.rom 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 + +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 +#include + +/* 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 Binary files /dev/null and b/spritebug.png differ -- cgit v1.2.3