Nightshade disassembly ====================== Published by Ultimate Play the Game in 1985, Nightshade was originally written by Chris and Tim Stamper for the ZX Spectrum, and was converted to the BBC Micro by Paul Proctor. Featuring scrolling isometric graphics, it is the first and only game for the BBC Micro to employ the Filmation II game engine. As a knight, the player must destroy four demons in a plague-infested village. The following disassembly was created by reverse engineering binary images, without access to any source code. It is nevertheless reasonably complete, allowing the technical approaches used to be understood. The author of this disassembly imposes no additional copyright restrictions beyond those already present on the game itself. It is provided for educational purposes only, and it is hoped that the original authors will accept it in the good faith it was intended - as a tribute to their skills. Technical notes =============== The custom tape loader is protected by a multi-stage VIA-based decryption routine written by Kevin Edwards, notable for including disk formatting code which triggers if tampering is detected. The disassembly analyses each stage immediately after decryption has taken place. The Filmation II game engine plots to a buffer, which is then copied to the screen in its entirety every frame. Sprites can be flipped horizontally and shifted by an even number of pixels by means of pre-calculated lookup tables. Notes ===== Object slots: &00 player &01 - &02 fired antibodies &03 - &06 wild antibodies &07 - &0a weapons &0b - &0e demons &0f - &14 imps &15 collectable Co-ordinates: fraction room facing screen x- y+ x- y+ 3 4 0 y+ \ / \ / \|/ | x x 7-x-5 | / \ / \ /|\ | y- x+ y- x+ 2 6 1 y- Because a fixed seed is used for the random number generator, the player, demons and weapons are in fixed places the first time the game is played: x 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f x y 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 y 1f ################################################################ 1f 1e ##########PP.. ##########......####################..##.... ## 1e 1d ###### ..######.. w1################ ..## 1d 1c ## .......... ####.. ####........##.. ........ #### 1c 1b #### .... .... ##........####.. ..##.. .. ....#### 1b 1a #### .. .. .. .... ..####.. ..##.. .. .. #### 1a 19 ####.... ...... ........ .. ##............ ........ #### 19 18 ## .. .. .. ..........######## .. w2 ## 18 17 ## .... ...... .. ..######..########.................... ## 17 16 ## .. .. ....D3##########........ ..w3 .. ## 16 15 #### .......... .. ## .. .. ...... .. ..#### 15 14 #### ...... ####...... .. ...... ........#### 14 13 ############ ......D4.. ###### ##...... ..########## 13 12 ## .... ........ ########.. ................## #### 12 11 #### ........####D2.. ......######.. .. .. .... ........## 11 10 ###### ####.. .. .......... ## ..###### .. ## 10 0f ################ ##...... .......... ......###### #### 0f 0e ########......###### .......... .. ..################## 0e 0d ###### .. ........ .. .. ........ ......############## 0d 0c #### .... ...... ...... .. .. .. ..##.... ###### 0c 0b ###### ........ .. ............ ...... ..#### 0b 0a ###### .. .. ............ .. .. .. ..........## 0a 09 ###### .. .... .... .... ....####............ .. ## 09 08 ###### ...... .. ...... .. ## .... ....## 08 07 ######## ................ .......... ## ...... ..## ..#### 07 06 ############....###### ## .. .. ..## .. .. ..########## 06 05 ############ ..########## .. .... ## ...... ..########## 05 04 ##........ .. ########## ........ #### .. ..########## 04 03 ##D1w4 ################## ################.. .... ## 03 02 ##...... ###################################################### 02 01 ##.. .. ###################################################### 01 00 ################################################################ 00 y 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f y x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 x PP: player D1, D2, D3, D4: demons w1, w2, w3, w4: weapons Interesting pokes ================= &521e = &ff player is invulnerable &5059 = &a0 player always moves quickly Tape protection disassembly =========================== ; Nightshade ; 000700 000f01 000900 # &0700 - &07ff decrypted at &0e4c ; perturb_disk_controller_and_check_roms &0700 68 PLA &0701 48 PHA &0702 a8 TAY &0703 a9 93 LDA #&93 &0705 8d 4a 0e STA &0e4a ; decrypt_eor_address_low # Overwrite address used for decryption of &0700 - &07ff &0708 a9 0c LDA #&0c ; &0c93 &070a 8d 4b 0e STA &0e4b ; decrypt_eor_address_high &070d 78 SEI &070e a9 01 LDA #&01 # Reset controller by writing 1 and 0 to reset register &0710 8d 82 fe STA &fe82 ; 8271 disk controller reset register &0713 20 43 07 JSR &0743 ; short_delay &0716 a9 00 LDA #&00 # Then configure controller to use unhelpful settings &0718 8d 82 fe STA &fe82 ; 8271 disk controller reset register &071b 20 43 07 JSR &0743 ; short_delay &071e a9 35 LDA #&35 # Command &35: specify &0720 8d 80 fe STA &fe80 ; 8271 disk controller command register &0723 20 43 07 JSR &0743 ; short_delay &0726 a9 0d LDA #&0d # Parameter &0d: specify initialization &0728 8d 81 fe STA &fe81 ; 8271 disk controller parameter register &072b 20 43 07 JSR &0743 ; short_delay &072e a9 01 LDA #&01 &0730 8d 81 fe STA &fe81 ; 8271 disk controller parameter register # Set step rate to 2ms &0733 20 43 07 JSR &0743 ; short_delay &0736 8d 81 fe STA &fe81 ; 8271 disk controller parameter register # Set head settling time to 2ms &0739 20 43 07 JSR &0743 ; short_delay &073c 8d 81 fe STA &fe81 ; 8271 disk controller parameter register # Set head load time to 4ms, index count to 0 &073f 4c 49 07 JMP &0749 ; check_roms ; unused &0742 60 RTS ; short_delay &0743 a2 14 LDX #&14 ; short_delay_loop &0745 ca DEX &0746 d0 fd BNE &0745 ; short_delay_loop &0748 60 RTS ; check_roms &0749 a2 49 LDX #&49 &074b 8a TXA ; wipe_0700_to_0749_loop &074c 9d 00 07 STA &0700,X ; perturb_disk_controller_and_check_roms # Wipe &0700 - &0749 with &49 &074f ca DEX &0750 10 fa BPL &074c ; wipe_0700_to_0749_loop &0752 a2 0f LDX #&0f ; check_roms_loop &0754 8e 30 fe STX &fe30 ; paged ROM latch # Check each ROM in turn &0757 ad 00 80 LDA &8000 &075a c9 b7 CMP #&b7 &075c d0 0a BNE &0768 ; second_check &075e ad 09 80 LDA &8009 ; rom_title_string &0761 c9 52 CMP #&52 ; "R" &0763 d0 03 BNE &0768 ; second_check # Fail if &8000 = &b7 and &8009 = &52 ; to_failed_rom_check &0765 4c b7 07 JMP &07b7 ; failed_rom_check ; second_check &0768 ad fc 9f LDA &9ffc &076b c9 cd CMP #&cd &076d d0 07 BNE &0776 ; third_check &076f ad fd 9f LDA &9ffd &0772 c9 d9 CMP #&d9 &0774 f0 ef BEQ &0765 ; to_failed_rom_check # Fail if &9ffc = &cd and &9ffd = &d9 ; third_check &0776 ad fa 9f LDA &9ffa &0779 c9 aa CMP #&aa &077b d0 07 BNE &0784 ; fourth_check &077d ad fb 9f LDA &9ffb &0780 c9 ff CMP #&ff &0782 f0 e1 BEQ &0765 ; to_failed_rom_check # Fail if &9ffa = &aa and &9ffb = &ff ; fourth_check &0784 ad 0f 9f LDA &9f0f &0787 c9 20 CMP #&20 &0789 d0 0e BNE &0799 ; check_next_rom &078b ad 10 9f LDA &9f10 &078e c9 51 CMP #&51 &0790 d0 07 BNE &0799 ; check_next_rom &0792 ad 11 9f LDA &9f11 &0795 c9 ff CMP #&ff &0797 f0 cc BEQ &0765 ; to_failed_rom_check # Fail if &9f0f = &20, &9f10 = &51 and &9f11 = &ff ; check_next_rom &0799 ca DEX &079a 10 b8 BPL &0754 ; check_roms_loop &079c a9 f1 LDA #&f1 # Change &0e52 - &0e53 to 4c b5 f1 JMP &f1b5, &079e 99 00 0e STA &0e00,Y ; tape_loader_payload # overwriting call to &0700 &07a1 88 DEY &07a2 a9 b5 LDA #&b5 &07a4 99 00 0e STA &0e00,Y ; tape_loader_payload &07a7 88 DEY &07a8 a9 4c LDA #&4c ; JMP &07aa 99 00 0e STA &0e00,Y ; tape_loader_payload &07ad a2 ad LDX #&ad &07af 8a TXA ; wipe_0701_to_07ad_loop &07b0 9d 00 07 STA &0700,X ; perturb_disk_controller_and_check_roms # Wipe &0701 - &07ad with &ad &07b3 ca DEX &07b4 d0 fa BNE &07b0 ; wipe_0701_to_07ad_loop &07b6 60 RTS ; failed_rom_check &07b7 a2 b7 LDX #&b7 &07b9 8a TXA ; wipe_0701_to_07b7_loop &07ba 9d 00 07 STA &0700,X ; perturb_disk_controller_and_check_roms # Wipe &0701 - &07b7 with &b7 &07bd ca DEX &07be d0 fa BNE &07ba ; wipe_0701_to_07b7_loop &07c0 a9 07 LDA #&07 # MODE 7 &07c2 20 1d cb JSR &cb1d ; os_rom_set_mode ; write_remove_replay # Endlessly write "Remove REPLAY and try again!" &07c5 a2 00 LDX #&00 ; write_remove_replay_loop &07c7 bd d8 07 LDA &07d8,X ; remove_replay_string &07ca f0 06 BEQ &07d2 ; end_of_string &07cc 20 ee ff JSR &ffee ; OSWRCH &07cf e8 INX &07d0 d0 f5 BNE &07c7 ; write_remove_replay_loop ; end_of_string &07d2 20 e7 ff JSR &ffe7 ; OSNEWL &07d5 4c c5 07 JMP &07c5 ; write_remove_replay ; remove_replay_string &07d8 52 65 6d 6f 76 65 20 52 45 50 4c 41 59 20 61 6e ; "Remove REPLAY an" &07e8 64 20 74 72 79 20 61 67 61 69 6e 21 00 ; "d try again!" ; unused &07f5 4b 65 76 69 6e 20 20 20 20 20 20 ; "Kevin " # &0800 - &08ff is unencrypted (and unused) ; OS sound workspace (unused) &0800 00 00 00 00 00 00 00 00 c0 c0 c0 c0 04 04 04 04 &0810 00 00 00 64 00 00 00 ff 00 00 00 00 00 00 00 00 &0820 00 00 00 05 00 00 00 ff 00 00 00 00 00 00 00 00 &0830 00 00 00 00 00 00 00 00 ff 00 00 00 00 f0 00 0e ; OS channel buffers (unused) &0840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0870 64 06 90 64 06 90 64 06 00 00 00 00 00 00 00 90 ; OS printer buffer (unused) &0880 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; OS envelope storage area (unused) &08c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0900 - &09ff decrypted at &71bf if tampering is detected ; small_table # Encrypted against &d9d8 - &dad7 &0900 ec fe 80 d5 f0 07 45 88 f8 a4 cc 08 c0 e8 e3 a2 # Decrypted when tampering is detected in main binary &0910 81 f6 8c dd 02 01 dd 8d 42 03 7d 09 c5 79 e2 45 # to produce disk_and_video_unpleasantness (see below) &0920 60 e4 a8 19 7c 07 8c ab 4b 09 03 af a6 87 cf fc &0930 c7 ae df f7 c0 8b b9 d8 7a 83 85 5a 20 ea 29 0f &0940 dc 16 c3 79 f4 ae 22 0b 06 6e 29 42 8d 4a 1e 95 &0950 05 fd 48 5f 00 09 6a b0 be a9 2e 4f ad ad e7 24 &0960 02 85 53 40 56 99 af ad ab 3d ed fe 6d ce 6e af &0970 cd 01 10 01 fc c4 50 0a bd 8c 53 0b 5c 04 e5 4c &0980 a0 d9 52 83 1f 65 90 56 22 a8 7f fe 00 2a a5 42 &0990 29 6a 52 c5 5f 54 94 e0 7f 63 44 fa 3a e4 97 f1 &09a0 42 04 40 59 aa 37 75 5f ab 5b 4f 6e 51 ab 64 c6 &09b0 e1 7e 57 49 ad 9b 07 c1 83 0c b8 9e a1 ec 00 bd &09c0 3b 73 4d 92 9e b8 ae 6e 89 2b ad d7 88 ca 7a 73 &09d0 2d be 8d e0 12 84 8a f2 de d2 a1 59 aa 7e 8d 52 &09e0 82 6c 54 ad 8a 54 7f b3 cc 23 84 64 a9 99 4b e5 &09f0 ab 65 b1 f0 6b ac bd 71 86 c2 87 84 d4 e8 e0 30 # &0a00 - &0dff is unencrypted ; eor_slide # Filled with 128 EOR instructions at &0b17, values &0a00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # incremented on system timer 1 interrupt at &0c40 &0a10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a00 49 00 EOR #&00 -> 49 08 EOR #&08 &0a30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a02 49 02 EOR #&02 49 07 EOR #&07 &0a40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a04 49 04 EOR #&04 49 05 EOR #&05 &0a50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a06 49 06 EOR #&06 49 0c EOR #&0c &0a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a08 49 08 EOR #&08 49 0b EOR #&0b &0a70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a0a 49 0a EOR #&0a 49 10 EOR #&10 &0a80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a0c 49 0c EOR #&0c 49 12 EOR #&12 &0a90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a10 49 0e EOR #&0e 49 11 EOR #&11 &0aa0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0a12 49 10 EOR #&10 49 16 EOR #&16 &0ab0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # ... &0ac0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0afc 49 fc EOF #&fc 49 fd EOR #&fd &0ad0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0afe 49 fe EOR #&fe 49 ff EOR #&ff &0ae0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &0af0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # then falls through into fixed code ; after_eor_slide &0b00 8d 48 fe STA &fe48 ; System VIA timer 2 counter LSB &0b03 ce 69 fe DEC &fe69 ; User VIA timer 2 counter MSB &0b06 a5 fc LDA &fc ; irq_accumulator &0b08 40 RTI ; via_decryption &0b09 78 SEI &0b0a a2 ff LDX #&ff &0b0c 9a TXS &0b0d a9 2a LDA #&2a &0b0f 8d 04 02 STA &0204 ; irq1_vector_low &0b12 a9 0c LDA #&0c ; &0c2a = via_decryption_irq_routine &0b14 8d 05 02 STA &0205 ; irq1_vector_high ; create_eor_slide &0b17 a2 00 LDX #&00 # Fill &0a00 - &0aff with EOR instructions ; create_eor_slide_loop &0b19 a9 49 LDA #&49 ; EOR &0b1b 9d 00 0a STA &0a00,X ; eor_slide &0b1e 8a TXA &0b1f 9d 01 0a STA &0a01,X ; eor_slide + 1 &0b22 e8 INX &0b23 e8 INX &0b24 d0 f3 BNE &0b19 ; create_eor_slide_loop &0b26 a9 40 LDA #&40 &0b28 8d 4b fe STA &fe4b ; System VIA auxiliary control register # Set timer 1 to continuous countdown &0b2b 8d 6b fe STA &fe6b ; User VIA auxiliary control register &0b2e a9 7f LDA #&7f # Disable all interrupts &0b30 8d 4e fe STA &fe4e ; System VIA interrupt enable register &0b33 8d 6e fe STA &fe6e ; User VIA interrupt enable register &0b36 a9 e0 LDA #&e0 # Enable timer 1 and timer 2 interrupts &0b38 8d 4e fe STA &fe4e ; System VIA interrupt enable register &0b3b 8d 6e fe STA &fe6e ; User VIA interrupt enable register &0b3e a9 34 LDA #&34 &0b40 8d 48 fe STA &fe48 ; System VIA timer 2 counter LSB &0b43 8d 49 fe STA &fe49 ; System VIA timer 2 counter MSB &0b46 a9 ac LDA #&ac &0b48 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &0b4b 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &0b4e a9 7b LDA #&7b &0b50 8d 44 fe STA &fe44 ; System VIA timer 1 counter LSB &0b53 8d 45 fe STA &fe45 ; System VIA timer 1 counter MSB &0b56 a9 cd LDA #&cd &0b58 8d 64 fe STA &fe64 ; User VIA timer 1 counter LSB &0b5b 8d 65 fe STA &fe65 ; User VIA timer 1 counter MSB ; create_big_table &0b5e a0 00 LDY #&00 &0b60 84 70 STY &70 ; big_table_address_low &0b62 a9 10 LDA #&10 ; &1000 = big_table # Fill &1000 - &3fff with VIA-dependent values &0b64 85 71 STA &71 ; big_table_address_high ; create_big_table_loop &0b66 ad 49 fe LDA &fe49 ; System VIA timer 2 counter MSB &0b69 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &0b6c 4d 69 fe EOR &fe69 ; User VIA timer 2 counter MSB &0b6f 38 SEC &0b70 ed 44 fe SBC &fe44 ; System VIA timer 1 counter LSB &0b73 4d 48 fe EOR &fe48 ; System VIA timer 2 counter LSB &0b76 59 00 0b EOR &0b00,Y ; code_page_b &0b79 91 70 STA (&70),Y ; big_table_address &0b7b c8 INY &0b7c d0 e8 BNE &0b66 ; create_big_table_loop &0b7e e6 71 INC &71 ; address_low &0b80 a5 71 LDA &71 ; address_high &0b82 c9 40 CMP #&40 &0b84 90 e0 BCC &0b66 ; create_big_table_loop &0b86 a2 00 LDX #&00 &0b88 a0 00 LDY #&00 &0b8a 4c 00 0d JMP &0d00 ; via_decryption_loop ; calculate_checksum &0b8d 78 SEI &0b8e a9 00 LDA #&00 # Checksum &0e00 - &0e1f &0b90 85 70 STA &70 ; checksum_one &0b92 85 71 STA &71 ; checksum_two &0b94 a8 TAY ; calculate_checksum_loop &0b95 a5 71 LDA &71 ; checksum_two &0b97 59 00 0e EOR &0e00,Y ; tape_loader_payload &0b9a 85 71 STA &71 ; checksum_two &0b9c a2 08 LDX #&08 ; calculate_checksum_inner_loop &0b9e a5 71 LDA &71 ; checksum_two &0ba0 2a ROL A &0ba1 90 0c BCC &0baf ; clear_unset &0ba3 a5 71 LDA &71 ; checksum_two &0ba5 49 08 EOR #&08 &0ba7 85 71 STA &71 ; checksum_two &0ba9 a5 70 LDA &70 ; checksum_one &0bab 49 10 EOR #&10 &0bad 85 70 STA &70 ; checksum_one ; clear_unset &0baf 26 70 ROL &70 ; checksum_one &0bb1 26 71 ROL &71 ; checksum_two &0bb3 ca DEX &0bb4 d0 e8 BNE &0b9e ; calculate_checksum_inner_loop &0bb6 c8 INY &0bb7 c0 20 CPY #&20 &0bb9 d0 da BNE &0b95 ; calculate_checksum_loop &0bbb a5 70 LDA &70 ; checksum_one &0bbd cd fe 0e CMP &0efe ; valid_checksum_one &0bc0 d0 0a BNE &0bcc ; invalid_checksum &0bc2 a5 71 LDA &71 ; checksum_two &0bc4 cd ff 0e CMP &0eff ; valid_checksum_two &0bc7 d0 03 BNE &0bcc ; invalid_checksum &0bc9 4c 00 0e JMP &0e00 ; tape_loader_payload ; invalid_checksum &0bcc a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect # This is handled by the OS OSBYTE handler at &e99c, &0bce a2 03 LDX #&03 ; Clear memory on next RESET # which isn't checked in the decryption routine, &0bd0 a0 00 LDY #&00 # so could be intercepted with a custom ROM &0bd2 20 f4 ff JSR &fff4 ; OSBYTE ; endless_wiping_loop # Otherwise, if the checksum doesn't match, &0bd5 99 00 0e STA &0e00,Y ; tape_loader_payload # Wipe &0e00 - &0eff (failed decryption) with &c8 &0bd8 c8 INY &0bd9 4c d5 0b JMP &0bd5 ; endless_wiping_loop ; unused &0bdc 4b 65 76 69 6e 21 ; "Kevin!" ; stop_tape &0be2 78 SEI &0be3 a9 05 LDA #&05 # Switch off cassette motor &0be5 8d 10 fe STA &fe10 ; Serial ULA control register &0be8 a9 03 LDA #&03 # Disable transmit and receiver interrupts &0bea 8d 08 fe STA &fe08 ; Cassette ACIA control register &0bed 60 RTS ; fail_with_load_error &0bee 20 e2 0b JSR &0be2 ; stop_tape &0bf1 a2 00 LDX #&00 ; wipe_0e00_to_0eff_and_0c2a_to_0d29_loop # Wipe &0e00 - &0eff and &0c2a - &0d29 &0bf3 9d 00 0e STA &0e00,X ; tape_loader_payload &0bf6 9d 2a 0c STA &0c2a,X ; via_decryption_irq_routine &0bf9 e8 INX &0bfa d0 f7 BNE &0bf3 ; wipe_0e00_to_0eff_and_0c2a_to_0d29_loop &0bfc a9 07 LDA #&07 # MODE 7 &0bfe 20 1d cb JSR &cb1d ; os_rom_set_mode ; write_load_error # Endlessly write "LOAD ERROR! TRY AGAIN" &0c01 a2 00 LDX #&00 ; write_load_error_loop &0c03 bd 14 0c LDA &0c14,X ; load_error_string &0c06 f0 06 BEQ &0c0e ; end_of_string &0c08 20 ee ff JSR &ffee ; OSWRCH &0c0b e8 INX &0c0c d0 f5 BNE &0c03 ; write_load_error_loop ; end_of_string &0c0e 20 e7 ff JSR &ffe7 ; OSNEWL &0c11 4c 01 0c JMP &0c01 ; write_load_error ; load_error_string &0c14 4c 4f 41 44 20 45 52 52 4f 52 21 20 54 52 59 20 ; "LOAD ERROR! TRY " &0c24 41 47 41 49 4e 00 ; "AGAIN" ; via_decryption_irq_routine &0c2a ad 4d fe LDA &fe4d ; System VIA interrupt flag register &0c2d 10 4d BPL &0c7c ; no_system_interrupt &0c2f 29 40 AND #&40 &0c31 f0 16 BEQ &0c49 ; system_timer_2_interrupt ; system_timer_1_interrupt &0c33 38 SEC &0c34 6e 64 fe ROR &fe64 ; User VIA timer 1 counter LSB &0c37 ce 49 fe DEC &fe49 ; System VIA timer 2 counter MSB &0c3a ad 48 fe LDA &fe48 ; System VIA timer 2 counter LSB &0c3d 09 01 ORA #&01 &0c3f aa TAX &0c40 fe 00 0a INC &0a00,X ; eor_slide # Alter part of eor_slide depending on system timer 2 &0c43 ae 44 fe LDX &fe44 ; System VIA timer 1 counter LSB &0c46 a5 fc LDA &fc ; irq_accumulator &0c48 40 RTI ; system_timer_2_interrupt &0c49 ad 64 fe LDA &fe64 ; User VIA timer 1 counter LSB &0c4c 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &0c4f 09 01 ORA #&01 &0c51 8d 48 fe STA &fe48 ; System VIA timer 2 counter LSB &0c54 ee 44 fe INC &fe44 ; System VIA timer 1 counter LSB &0c57 ce 69 fe DEC &fe69 ; User VIA timer 2 counter MSB &0c5a ad 69 fe LDA &fe69 ; User VIA timer 2 counter MSB &0c5d 09 01 ORA #&01 &0c5f 8d 44 fe STA &fe44 ; System VIA timer 1 counter LSB &0c62 4d 45 fe EOR &fe45 ; System VIA timer 1 counter MSB &0c65 49 d4 EOR #&d4 # actually EOR system_timer_2_interrupt_eor_value &0c67 09 01 ORA #&01 &0c69 8d 49 fe STA &fe49 ; System VIA timer 2 counter MSB &0c6c ad 48 fe LDA &fe48 ; System VIA timer 2 counter LSB &0c6f 0a ASL A &0c70 85 70 STA &70 ; address_low &0c72 a9 0a LDA #&0a; &0a00 = eor_slide &0c74 85 71 STA &71 ; address_high &0c76 ad 64 fe LDA &fe64 ; User VIA timer 1 counter LSB &0c79 6c 70 00 JMP (&0070) ; address # Run part of eor_slide depending on system timer 2 ; no_system_interrupt &0c7c ad 6d fe LDA &fe6d ; User VIA interrupt flag register &0c7f 29 40 AND #&40 &0c81 f0 30 BEQ &0cb3 ; user_timer_2_interrupt ; user_timer_1_interrupt &0c83 ad 64 fe LDA &fe64 ; User VIA timer 1 counter LSB &0c86 ad 68 fe LDA &fe68 ; User VIA timer 2 counter LSB &0c89 4d 48 fe EOR &fe48 ; System VIA timer 2 counter LSB &0c8c 09 01 ORA #&01 &0c8e 8d 45 fe STA &fe45 ; System VIA timer 1 counter MSB &0c91 ba TSX &0c92 e0 fe CPX #&fe &0c94 b0 0d BCS &0ca3 ; use_zero_page ; use_stack &0c96 bd 02 01 LDA &0102,X # Use low byte of address interrupt occurred at &0c99 4d 48 fe EOR &fe48 ; System VIA timer 2 counter LSB &0c9c 09 01 ORA #&01 &0c9e 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &0ca1 d0 0a BNE &0cad ; leave_after_decrementing_user_timer_1_msb ; use_zero_page &0ca3 b5 02 LDA &02,X # Uses &00 and &01, BASIC LOMEM, uninitialised here, &0ca5 4d 49 fe EOR &fe49 ; System VIA timer 2 counter MSB # and so requiring PAGE=&0e00 for first BASIC loader &0ca8 09 01 ORA #&01 &0caa 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB ; leave_after_decrementing_user_timer_1_msb &0cad a5 fc LDA &fc ; irq_accumulator &0caf ce 65 fe DEC &fe65 ; User VIA timer 1 counter MSB &0cb2 40 RTI ; user_timer_2_interrupt &0cb3 ae 44 fe LDX &fe44 ; System VIA timer 1 counter LSB &0cb6 ad 67 fe LDA &fe67 ; User VIA timer 1 latch MSB &0cb9 4d 49 fe EOR &fe49 ; System VIA timer 2 counter MSB &0cbc 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &0cbf 49 ee EOR #&ee # actually EOR user_timer_2_interrupt_eor_value &0cc1 09 01 ORA #&01 &0cc3 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &0cc6 4d 46 fe EOR &fe46 ; System VIA timer 1 latch LSB &0cc9 ee 49 fe INC &fe49 ; System VIA timer 2 counter MSB &0ccc 09 01 ORA #&01 &0cce 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &0cd1 a5 fc LDA &fc ; irq_accumulator &0cd3 40 RTI ; reset_vectors_and_start_irq &0cd4 78 SEI &0cd5 a2 35 LDX #&35 # Reset all vectors to OS defaults ; reset_vector_table_loop &0cd7 bd 40 d9 LDA &d940,X ; os_default_vector_table &0cda 9d 00 02 STA &0200,X ; os_vector_table &0cdd ca DEX &0cde 10 f7 BPL &0cd7 ; reset_vector_table_loop &0ce0 a9 2a LDA #&2a &0ce2 8d 04 02 STA &0204 ; irq1_vector_low &0ce5 a9 0c LDA #&0c ; &0c2a = via_decryption_irq_routine &0ce7 8d 05 02 STA &0205 ; irq1_vector_high &0cea a9 4c LDA #&4c ; JMP # Set BREAK intercept code to JMP &0287, endless loop &0cec 8d 87 02 STA &0287 ; BREAK intercept code &0cef a9 87 LDA #&87 &0cf1 8d 88 02 STA &0288 ; BREAK intercept code + 1 &0cf4 a9 02 LDA #&02 &0cf6 8d 89 02 STA &0289 ; BREAK intercept code + 2 &0cf9 a9 03 LDA #&03 # Enable ESCAPE, clear memory on BREAK &0cfb 8d 58 02 STA &0258 ; ESCAPE/BREAK effect &0cfe 58 CLI &0cff 60 RTS ; via_decryption_loop &0d00 ad 00 0d LDA &0d00 ; code_page_d # Ensure &0d00 - &0dff hasn't been changed # actually LDA &0d00 + via_decryption_offset &0d03 38 SEC &0d04 69 cd ADC #&cd # actually ADC via_decryption_add &0d06 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &0d09 ee 05 0d INC &0d05 ; via_decryption_add &0d0c ce 69 fe DEC &fe69 ; User VIA timer 2 counter MSB &0d0f 59 00 ff EOR &ff00,Y # Ensure OS ROM from &ff00 to &ffff hasn't been changed &0d12 5d 1c dc EOR &dc1c,X ; os_irq_handler # Ensure OS main IRQ handler hasn't been changed &0d15 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &0d18 ae 69 fe LDX &fe69 ; User VIA timer 2 counter MSB &0d1b ec 48 fe CPX &fe48 ; System VIA timer 2 counter LSB &0d1e 6e 49 fe ROR &fe49 ; System VIA timer 2 counter MSB &0d21 59 00 0e EOR &0e00,Y ; tape_loader_payload # Ensure &0e00 - &0eff hasn't been changed &0d24 ee 28 0d INC &0d28 ; via_decryption_eor &0d27 49 d9 EOR #&d9 # actually EOR via_decryption_eor &0d29 4d 65 fe EOR &fe65 ; User VIA timer 1 counter MSB &0d2c 38 SEC &0d2d 2e 48 fe ROL &fe48 ; System VIA timer 2 counter LSB &0d30 ae 44 fe LDX &fe44 ; System VIA timer 1 counter LSB &0d33 5d cd d9 EOR &d9cd,X ; os_reset_handler # Ensure OS reset handler hasn't been changed &0d36 59 00 0b EOR &0b00,Y ; code_page_b # Ensure &0b00 - &0bff hasn't been changed &0d39 ce 48 fe DEC &fe48 ; System VIA timer 2 counter LSB &0d3c ea NOP &0d3d 4d 47 fe EOR &fe47 ; System VIA timer 1 latch MSB &0d40 59 00 0d EOR &0d00,Y ; code_page_d # Ensure &0d00 - &0dff hasn't been changed &0d43 ce 48 0d DEC &0d48 ; via_decryption_sbc_offset &0d46 18 CLC &0d47 ed 00 0c SBC &0c00 ; code_page_c # Ensure &0c00 - &0cff hasn't been changed # actually SBC &0c00 + via_decryption_sbc_offset &0d4a 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &0d4d 4d 46 fe EOR &fe46 ; System VIA timer 1 latch LSB &0d50 5d 01 0b EOR &0b01,X ; code_page_b + 1 # Ensure &0b00 - &0c01 hasn't been changed &0d53 4d 66 fe EOR &fe66 ; User VIA timer 1 latch LSB &0d56 59 00 19 EOR &1900,Y # Runs over &1000 - &3fff # actually big_table_address_one,Y &0d59 4d 69 fe EOR &fe69 ; User VIA timer 2 counter MSB &0d5c 78 SEI &0d5d 48 PHA &0d5e ad 68 fe LDA &fe68 ; User VIA timer 2 counter LSB &0d61 8d 66 0c STA &0c66 ; system_timer_2_interrupt_eor_value &0d64 4d 05 0d EOR &0d05 ; via_decryption_add &0d67 4d 44 fe EOR &fe44 ; System VIA timer 1 counter LSB &0d6a aa TAX &0d6b 68 PLA &0d6c 58 CLI &0d6d 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &0d70 4d 45 fe EOR &fe45 ; System VIA timer 1 counter MSB &0d73 38 SEC &0d74 ed 48 fe SBC &fe48 ; System VIA timer 2 counter LSB &0d77 59 01 0d EOR &0d01,Y ; code_page_d + 1 # Ensure &0d01 - &0e00 hasn't been changed &0d7a 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &0d7d 49 ff EOR #&ff &0d7f 48 PHA &0d80 fe 00 19 INC &1900,X # Runs over &1000 - &3fff # actually big_table_address_two,X &0d83 4d 65 fe EOR &fe65 ; User VIA timer 1 counter MSB &0d86 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &0d89 59 00 09 EOR &0900,Y ; small_table &0d8c ae 45 fe LDX &fe45 ; System VIA timer 1 counter MSB &0d8f 8e c0 0c STX &0cc0 ; user_timer_2_interrupt_eor_value &0d92 59 00 13 EOR &1300,Y # Runs over &1000 - &3fff # actually EOR big_table_address_three,Y &0d95 5d 00 0b EOR &0b00,X ; code_page_b # Ensure &0b00 - &0bff hasn't been changed # actually EOR &0b00 + via_decryption_eor_offset, X &0d98 ce 96 0d DEC &0d96 ; via_decryption_eor_offset &0d9b 4d 45 fe EOR &fe45 ; System VIA timer 1 counter MSB &0d9e 59 00 07 EOR &0700,Y ; code_page_7 # Ensure &0700 - &07ff hasn't been changed &0da1 ae 48 fe LDX &fe48 ; System VIA timer 2 counter LSB &0da4 ec 44 fe CPX &fe44 ; System VIA timer 1 counter LSB &0da7 ed 49 fe SBC &fe49 ; System VIA timer 2 counter MSB &0daa 59 00 d0 EOR &d000,Y # Ensure OS ROM from &c100 to &e4ff hasn't been changed # actually EOR os_rom_address,Y &0dad 99 00 0e STA &0e00,Y ; tape_loader_payload &0db0 c8 INY &0db1 f0 03 BEQ &0db6 ; next_round &0db3 4c 00 0d JMP &0d00 ; via_decryption_loop ; next_round &0db6 ee 94 0d INC &0d94 ; big_table_address_three_high &0db9 ad 94 0d LDA &0d94 ; big_table_address_three_high &0dbc c9 30 CMP #&30 &0dbe 90 05 BCC &0dc5 ; skip_wraparound_one &0dc0 a9 10 LDA #&10 &0dc2 8d 94 0d STA &0d94 ; big_table_address_three_high ; skip_wraparound_one &0dc5 ee 58 0d INC &0d58 ; big_table_address_one_high &0dc8 ad 58 0d LDA &0d58 ; big_table_address_one_high &0dcb c9 40 CMP #&40 &0dcd 90 05 BCC &0dd4 ; skip_wraparound_two &0dcf a9 10 LDA #&10 &0dd1 8d 58 0d STA &0d58 ; big_table_address_one_high ; skip_wraparound_two &0dd4 ee 82 0d INC &0d82 ; big_table_address_two_high &0dd7 ad 82 0d LDA &0d82 ; big_table_address_two_high &0dda c9 40 CMP #&40 &0ddc 90 05 BCC &0de3 ; skip_wraparound_three &0dde a9 10 LDA #&10 &0de0 8d 82 0d STA &0d82 ; big_table_address_two_high ; skip_wraparound_three &0de3 ee ac 0d INC &0dac ; os_rom_address_high &0de6 ad ac 0d LDA &0dac ; os_rom_address_high &0de9 c9 e5 CMP #&e5 &0deb 90 05 BCC &0df2 ; skip_wraparound_rom &0ded a9 c1 LDA #&c1 &0def 8d ac 0d STA &0dac ; os_rom_address_high ; skip_wraparound_rom &0df2 ee 01 0d INC &0d01 ; via_decryption_offset &0df5 f0 06 BEQ &0dfd ; to_calculate_checksum &0df7 20 d4 0c JSR &0cd4 ; reset_vectors_and_start_irq &0dfa 4c 00 0d JMP &0d00 ; via_decryption_loop ; to_calculate_checksum &0dfd 4c 8d 0b JMP &0b8d ; calculate_checksum # &0e00 - &0eff decrypted by via_decryption (&0d00 - &0dff) ; tape_loader_payload &0e00 a2 0e LDX #&0e # R14: Memory-address of text-cursor (high) &0e02 8e 00 fe STX &fe00 ; video register number &0e05 a9 3d LDA #&3d # Stored value checked at &7115 of main binary &0e07 8d 01 fe STA &fe01 ; video register value &0e0a e8 INX # R15: Memory-address of text-cursor (low) &0e0b 8e 00 fe STX &fe00 ; video register number &0e0e a9 b4 LDA #&b4 # Stored value checked at &7121 of main binary &0e10 8d 01 fe STA &fe01 ; video register value &0e13 e8 INX &0e14 8e 00 fe STX &fe00 ; video register number # Unnecessary &0e17 a9 bb LDA #&bb &0e19 8d 44 fe STA &fe44 ; System VIA timer 1 counter LSB &0e1c a9 81 LDA #&81 &0e1e 8d 45 fe STA &fe45 ; System VIA timer 1 counter MSB &0e21 a9 22 LDA #&22 # Stored value checked at &7103 of main binary, &0e23 8d 40 02 STA &0240 ; os_cfs_timeout_counter # decremented every v-sync if interrupts enabled &0e26 a2 e2 LDX #&e2 &0e28 9a TXS &0e29 48 PHA &0e2a a9 72 LDA #&72 # Push &03, &72, &72 and &22 to stack, &0e2c 48 PHA # i.e. return address of &7204 (main_binary_entry_point) &0e2d 48 PHA &0e2e a9 03 LDA #&03 &0e30 48 PHA &0e31 a2 00 LDX #&00 &0e33 8a TXA ; wipe_0e00_to_0e33_loop &0e34 9d 00 0e STA &0e00,X ; tape_loader_payload # Wipe &0e00 - &0e33 &0e37 e8 INX &0e38 e0 34 CPX #&34 &0e3a d0 f8 BNE &0e34 ; wipe_0e00_to_0e33_loop &0e3c a9 7f LDA #&7f # Disable all interrupts &0e3e 8d 4e fe STA &fe4e ; System VIA interrupt enable register &0e41 8d 6e fe STA &fe6e ; User VIA interrupt enable register &0e44 a2 00 LDX #&00 ; decrypt_0700_loop &0e46 bd 00 07 LDA &0700,X ; perturb_disk_controller_and_check_roms &0e49 5d e9 d9 EOR &d9e9,X ; os_rom_clear_memory + 2 # Ensure OS clear memory routine hasn't been changed # becomes EOR &0c93,X # Overwritten at &0705 as a distraction &0e4c 9d 00 07 STA &0700,X ; perturb_disk_controller_and_check_roms &0e4f e8 INX &0e50 d0 f4 BNE &0e46 ; decrypt_0700_loop &0e52 20 00 07 JSR &0700 ; perturb_disk_controller_and_check_roms # becomes JMP &f1b5 # Overwritten at &079e as a distraction &0e55 a9 9d LDA #&9d &0e57 8d 04 02 STA &0204 ; irq1_vector_low &0e5a a9 0e LDA #&0e ; &0e9d = tape_irq_routine &0e5c 8d 05 02 STA &0205 ; irq1_vector_high &0e5f a9 00 LDA #&00 &0e61 85 75 STA &75 ; loaded &0e63 85 70 STA &70 ; loading &0e65 85 71 STA &71 ; load_address_low &0e67 85 73 STA &73 ; length_low &0e69 a9 11 LDA #&11 # Load first file at &1100 - &57ff &0e6b 85 72 STA &72 ; load_address_high &0e6d a9 47 LDA #&47 &0e6f 85 74 STA &74 ; length_high &0e71 20 e3 0e JSR &0ee3 ; start_tape ; wait_for_first_file_to_load_loop &0e74 24 75 BIT &75 ; loaded &0e76 10 fc BPL &0e74 ; wait_for_first_file_to_load_loop &0e78 20 e2 0b JSR &0be2 ; stop_tape &0e7b 20 38 57 JSR &5738 ; loading_screen # Change to a custom MODE 4, plot "LOADING" &0e7e a9 00 LDA #&00 &0e80 85 75 STA &75 ; loaded &0e82 85 70 STA &70 ; loading &0e84 85 71 STA &71 ; load_address_low &0e86 a9 57 LDA #&57 # Load second file at &5700 - &74ff &0e88 85 72 STA &72 ; load_address_high &0e8a a9 00 LDA #&00 &0e8c 85 73 STA &73 ; length_low &0e8e a9 1e LDA #&1e &0e90 85 74 STA &74 ; length_high &0e92 20 e3 0e JSR &0ee3 ; start_tape ; wait_for_second_file_to_load_loop &0e95 24 75 BIT &75 ; loaded &0e97 10 fc BPL &0e95 ; wait_for_second_file_to_load_loop &0e99 20 e2 0b JSR &0be2 ; stop_tape &0e9c 60 RTS # Returns to &7204, main_binary_entry_point ; tape_irq_routine &0e9d 98 TYA &0e9e 48 PHA &0e9f ad 08 fe LDA &fe08 ; Cassette ACIA control register &0ea2 10 34 BPL &0ed8 ; leave_irq # Is this an interrupt from the cassette system? &0ea4 a8 TAY &0ea5 29 01 AND #&01 &0ea7 f0 2f BEQ &0ed8 ; leave_irq # If so, is it a receiver interrupt? &0ea9 98 TYA &0eaa 29 70 AND #&70 # Is there a framing, receiver overrun or parity error? &0eac f0 07 BEQ &0eb5 ; received_data_from_tape # If not, it's data &0eae 24 70 BIT &70 ; loading &0eb0 10 26 BPL &0ed8 ; leave_irq # Top bit clear if still waiting for start of data &0eb2 4c ee 0b JMP &0bee ; fail_with_load_error # Otherwise, abort the load ; received_data_from_tape &0eb5 ad 09 fe LDA &fe09 ; Cassette ACIA data register &0eb8 24 70 BIT &70 ; loading # Top bit set if reading data &0eba 30 08 BMI &0ec4 ; write_byte_to_memory &0ebc c9 bc CMP #&bc &0ebe d0 18 BNE &0ed8 ; leave_irq # Otherwise, wait for &bc byte &0ec0 85 70 STA &70 ; loading # Set top bit to indicate data is being read &0ec2 f0 14 BEQ &0ed8 ; leave_irq ; write_byte_to_memory &0ec4 a0 00 LDY #&00 &0ec6 91 71 STA (&71),Y ; load_address &0ec8 e6 71 INC &71 ; load_address_low &0eca d0 02 BNE &0ece ; not_load_page &0ecc e6 72 INC &72 ; load_address_high ; not_load_page &0ece a5 73 LDA &73 ; length_low &0ed0 d0 04 BNE &0ed6 ; not_page &0ed2 c6 74 DEC &74 ; length_high &0ed4 30 07 BMI &0edd ; set_loaded ; not_page &0ed6 c6 73 DEC &73 ; length_low ; leave_irq &0ed8 68 PLA &0ed9 a8 TAY &0eda a5 fc LDA &fc ; irq_accumulator &0edc 40 RTI ; set_loaded &0edd a9 ff LDA #&ff &0edf 85 75 STA &75 ; loaded &0ee1 30 f5 BMI &0ed8 ; leave_irq # Always branches ; start_tape &0ee3 a9 03 LDA #&03 # Disable transmit and receiver interrupts &0ee5 8d 08 fe STA &fe08 ; Cassette ACIA control register &0ee8 a9 05 LDA #&05 # Switch off cassette motor &0eea 8d 10 fe STA &fe10 ; Serial ULA control register &0eed a2 00 LDX #&00 ; delay_loop &0eef ca DEX &0ef0 d0 fd BNE &0eef ; delay_loop &0ef2 a9 85 LDA #&85 # Set to 2400 baud, switch on cassette motor &0ef4 8d 10 fe STA &fe10 ; Serial ULA control register &0ef7 a9 d5 LDA #&d5 # 1200 baud, odd parity, 8 bit words, disable transmit &0ef9 8d 08 fe STA &fe08 ; Cassette ACIA control register # interrupts, enable all receiver interrupts &0efc 58 CLI &0efd 60 RTS ; valid_checksum_one &0efe ff ; valid_checksum_two &0eff bd # &0f00 - &0fff is unencrypted ; unused &0f00 00 ; entry_point &0f01 a9 0f LDA #&0f ; flush all buffers &0f03 a2 00 LDX #&00 &0f05 20 f4 ff JSR &fff4 ; OSBYTE &0f08 4c 09 0b JMP &0b09 ; via_decryption &0f0b 50 72 6f 74 65 63 74 69 6f 6e 20 28 63 29 20 4b ; "Protection (c) K" &0f1b 65 76 69 6e 20 45 64 77 61 72 64 73 20 31 39 38 ; "evin Edwards 198" &0f2b 35 20 54 68 69 73 20 70 72 6f 74 65 63 74 69 6f ; "5 This protectio" &0f3b 6e 20 73 79 73 74 65 6d 20 6d 61 79 20 6e 6f 74 ; "n system may not" &0f4b 20 62 65 20 63 6f 70 69 65 64 20 69 6e 20 70 61 ; " be copied in pa" &0f5b 72 74 20 6f 72 20 77 68 6f 6c 65 20 77 69 74 68 ; "rt or whole with" &0f6b 6f 75 74 20 77 72 69 74 74 65 6e 20 70 65 72 6d ; "out written perm" &0f7b 69 73 73 69 6f 6e 20 66 72 6f 6d 20 74 68 65 20 ; "ission from the " &0f8b 61 75 74 68 6f 72 2e ; "author." ; unused &0f93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fa3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fb3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fc3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fd3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fe3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0ff3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 If tampering is detected, small_table is decrypted to the following code: ; disk_and_video_unpleasantness &0900 a2 00 LDX #&00 &0902 8a TXA ; wipe_0e00_to_7fff_loop &0903 9d 00 0e STA &0e00,X # Wipe &0e00 - &7fff with &00 # actually STA wipe_address,X &0906 e8 INX &0907 d0 fa BNE &0903 ; wipe_0e00_to_7fff_loop &0909 ee 05 09 INC &0905 ; wipe_address_high &090c 10 f5 BPL &0903 ; wipe_0e00_to_7fff_loop &090e a9 00 LDA #&00 &0910 85 70 STA &70 ; track &0912 8d 58 02 STA &0258 ; ESCAPE/BREAK effect ; break_handler &0915 a9 4c LDA #&4c ; JMP &0917 8d 87 02 STA &0287 ; BREAK intercept code &091a 8d 00 0d STA &0d00 ; NMI entry point &091d a9 15 LDA #&15 # Set BREAK intercept code to JMP &0915 ; break_handler &091f 8d 88 02 STA &0288 ; BREAK intercept code + 1 &0922 a9 09 LDA #&09 &0924 8d 89 02 STA &0289 ; BREAK intercept code + 2 &0927 a9 c5 LDA #&c5 # Set NMI entry point to JMP &09c5 ; nmi_handler &0929 8d 01 0d STA &0d01 ; NMI entry point + 1 &092c a9 09 LDA #&09 &092e 8d 02 0d STA &0d02 ; NMI entry point + 2 &0931 20 9f 09 JSR &099f ; set_mode_register_to_use_non_DMA_mode &0934 20 82 09 JSR &0982 ; load_drive_head_against_disk &0937 20 92 09 JSR &0992 ; wait_for_drive_to_become_ready &093a a5 70 LDA &70 ; track &093c d0 0a BNE &0948 ; format_tracks_loop &093e a9 69 LDA #&69 # Command &69: seek (drive 0) &0940 20 bc 09 JSR &09bc ; push_command &0943 a9 00 LDA #&00 # Track 0 &0945 20 af 09 JSR &09af ; push_parameter ; format_tracks_loop &0948 20 92 09 JSR &0992 ; wait_for_drive_to_become_ready &094b a9 63 LDA #&63 # Command &63: format track (drive 0) &094d 20 bc 09 JSR &09bc ; push_command &0950 a5 70 LDA &70 ; track # Track number &0952 20 af 09 JSR &09af ; push_parameter &0955 a9 14 LDA #&14 # Gap 3 size minus 6 &0957 20 af 09 JSR &09af ; push_parameter &095a a9 a1 LDA #&a1 # One 4096 byte sector per track &095c 20 af 09 JSR &09af ; push_parameter &095f a9 00 LDA #&00 # Gap 5 size minus 6 &0961 20 af 09 JSR &09af ; push_parameter &0964 a9 14 LDA #&14 # Gap 1 size minus 6 &0966 20 af 09 JSR &09af ; push_parameter ; randomise_video_registers_loop &0969 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB # Write a random value to a random video register &096c 8d 00 fe STA &fe00 ; video register number &096f ad 64 fe LDA &fe64 ; User VIA timer 1 counter LSB &0972 8d 01 fe STA &fe01 ; video register value &0975 2c 80 fe BIT &fe80 ; 8271 disk controller status register # &80: command busy, set when controller is busy &0978 30 ef BMI &0969 ; randomise_video_registers_loop # When the drive finishes formatting a track, &097a ad 81 fe LDA &fe81 ; 8271 disk controller result register # clear the resulting interrupt, &097d e6 70 INC &70 ; track # and move on to the next &097f 4c 48 09 JMP &0948 ; format_tracks_loop ; load_drive_head_against_disk &0982 a9 3a LDA #&3a # Command &3a: write special register &0984 20 bc 09 JSR &09bc ; push_command &0987 a9 23 LDA #&23 # Register &23: drive control output port &0989 20 af 09 JSR &09af ; push_parameter &098c a9 48 LDA #&48 # Load head against the disk (drive 0) &098e 20 af 09 JSR &09af ; push_parameter &0991 60 RTS ; wait_for_drive_to_become_ready &0992 a9 6c LDA #&6c # Command &6c: read drive status (drive 0) &0994 20 bc 09 JSR &09bc ; push_command &0997 ad 81 fe LDA &fe81 ; 8271 disk controller result register &099a 29 04 AND #&04 # &04: ready 0, set when drive becomes ready &099c f0 f4 BEQ &0992 ; wait_for_drive_to_become_ready &099e 60 RTS ; set_mode_register_to_use_non_DMA_mode &099f a9 3a LDA #&3a # Command &3a: write special register &09a1 20 bc 09 JSR &09bc ; push_command &09a4 a9 17 LDA #&17 # Register &17: mode register &09a6 20 af 09 JSR &09af ; push_parameter &09a9 a9 c1 LDA #&c1 # Use non-DMA mode &09ab 20 af 09 JSR &09af ; push_parameter &09ae 60 RTS ; push_parameter &09af 48 PHA ; wait_for_controller_to_accept_previous_parameter &09b0 ad 80 fe LDA &fe80 ; 8271 disk controller status register &09b3 29 20 AND #&20 # &20: parameter full, clear after parameter accepted &09b5 d0 f9 BNE &09b0 ; wait_for_controller_to_accept_previous_parameter &09b7 68 PLA # When the controller is ready, &09b8 8d 81 fe STA &fe81 ; 8271 disk controller parameter register # push the parameter to the controller &09bb 60 RTS ; push_command &09bc 2c 80 fe BIT &fe80 ; 8271 disk controller status register # &80: command busy, set when controller is busy &09bf 30 fb BMI &09bc ; push_command # When the controller is ready, &09c1 8d 80 fe STA &fe80 ; 8271 disk controller command register # push the command to the controller &09c4 60 RTS ; nmi_handler &09c5 48 PHA &09c6 ad 80 fe LDA &fe80 ; 8271 disk controller status register # &04: non-DMA data request: set when data required &09c9 29 04 AND #&04 &09cb f0 05 BEQ &09d2 ; no_data_required &09cd 8d 84 fe STA &fe84 ; 8271 disk controller data # Push a byte of (meaningless) data to the controller ; leave_interrupt &09d0 68 PLA &09d1 40 RTI ; no_data_required &09d2 ad 80 fe LDA &fe80 ; 8271 disk controller status register &09d5 29 08 AND #&08 # &08: interrupt request, set on controller interrupt &09d7 f0 f7 BEQ &09d0 ; leave_interrupt &09d9 ad 81 fe LDA &fe81 ; 8271 disk controller result register # Clear the interrupt &09dc 4c d0 09 JMP &09d0 ; leave_interrupt ; unused &09df 50 72 6f 74 65 63 74 69 6f 6e 20 28 63 29 20 4b ; "Protection (c) K" &09ef 65 76 69 6e 20 45 64 77 61 72 64 73 20 20 20 20 ; "evin Edwards " &09ff 20 ; " " Intermediate loading screen disassembly ======================================= The tape loader loads the main game binary in two sections. A single block of code ends the first, which is later overwritten by the start of the second. ; loading_sprite &5700 e0 60 60 60 60 60 62 fe ; "L" &5708 38 6c c6 c6 c6 c6 6c 38 ; "O" &5710 0c 1c 2e 66 46 ce db 66 ; "A" &5718 60 70 68 6c 66 66 66 fc ; "D" &5720 7c 18 18 18 18 18 18 7c ; "I" &5728 cc d6 d6 e6 e4 c4 c8 de ; "N" &5730 0e 30 60 c6 ce f6 66 1c ; "G" ; loading_screen &5738 a9 88 LDA #&88 # Change to MODE 4 without clearing screen memory &573a 8d 20 fe STA &fe20 ; video ULA control register &573d a0 37 LDY #&37 ; plot_loading_sprite_loop &573f b9 00 57 LDA &5700,Y ; loading_sprite &5742 99 c8 7f STA &7fc8,Y ; screen_memory &5745 88 DEY &5746 10 f7 BPL &573f ; plot_loading_sprite_loop &5748 a0 0d LDY #&0d ; set_video_registers_loop &574a b9 62 57 LDA &5762,Y ; video_register_values &574d 8c 00 fe STY &fe00 ; video register number &5750 8d 01 fe STA &fe01 ; video register value &5753 88 DEY &5754 10 f4 BPL &574a ; set_video_registers_loop &5756 a0 0f LDY #&0f ; set_palette_loop &5758 b9 70 57 LDA &5770,Y ; palette_data &575b 8d 21 fe STA &fe21 ; video ULA palette register &575e 88 DEY &575f 10 f7 BPL &5758 ; set_palette_loop &5761 60 RTS ; video_register_values &5762 3f ; R0: Horizontal total register &5763 07 ; R1: Number of characters per line # Screen is 7 characters wide &5764 21 ; R2: Horizontal sync position register &5765 24 ; R3: Sync width register &5766 26 ; R4: Vertical total register &5767 00 ; R5: Vertical total adjust register &5768 01 ; R6: Vertical displayed register # Screen is 1 column high &5769 16 ; R7: Vertical sync position &576a 01 ; R8: Interlace and delay register &576b 07 ; R9: Scan lines per character register &576c 20 ; R10: Cursor start register &576d 08 ; R11: Cursor end register &576e 0f ; R12: Displayed screen start address register (high) # Set screen start address to &7fc8 &576f f9 ; R13: Displayed screen start address register (low) ; palette_data &5770 07 17 27 37 47 57 67 77 81 91 a1 b1 c1 d1 e1 f1 # Set colour 0 to black, colour 1 to cyan ; unused &5780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &5790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &57a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &57b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &57c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &57d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &57e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &57f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Game disassembly ================ ; (no filename) ; 001100 007204 006300 # Loaded in two chunks (&1100 - &57ff, &5700 - &74ff) ; &0067 - &0082 available_antibodies ; &0083 - &008d pockets ; ; &0290 - &10ff screen memory ; ; &5fd7 - &5fed objects_sprite ; &5fed - &6002 objects_x_fraction ; &6003 - &6018 objects_x_room ; &6019 - &602e objects_animation ; &602f - &6044 objects_facing ; &6045 - &605a objects_data ; &605b - &6070 objects_size ; &6071 - &6086 objects_speed_change_cooldown ; &6087 - &609c objects_y_fraction ; &609d - &60b2 objects_y_room ; &60b3 - &60c8 objects_speed_x ; &60c9 - &60de objects_speed_y ; &60df - &60f4 objects_flipped ; &60f5 - &610a objects_x_offset ; &610b - &6120 objects_y_offset ; ; &6c80 - &76ff screen buffer ; ; &7724 - &77ff shifted_sprite_data ; &7824 - &78ff shifted_mask_data ; ; &7900 - &79ff bits_shifted_right_two_bits ; &7a00 - &7aff bits_shifted_left_six_bits ; &7b00 - &7bff bits_shifted_right_four_bits ; &7c00 - &7cff bits_shifted_left_four_bits ; &7d00 - &7dff bits_shifted_right_six_bits ; &7e00 - &7eff bits_shifted_left_two_bits ; &7f00 - &7fff bit_reversed_bytes # &1100 - &6fff decrypted by decrypt_main_binary (&716d - &7192) ; sprite_address_table &1100 1a 39 ; &391a = sprite_01 ; WINGED_BOOT &1102 a5 3a ; &3aa5 = sprite_02 ; POTION &1104 ba 3b ; &3bba = sprite_03 ; HAMMER &1106 17 3c ; &3c17 = sprite_04 ; HOURGLASS &1108 e8 3a ; &3ae8 = sprite_05 ; CROSS &110a 45 3b ; &3b45 = sprite_06 ; BIBLE &110c b5 39 ; &39b5 = sprite_07 ; BURSTING &110e e8 39 ; &39e8 = sprite_08 ; BURSTING_2 &1110 23 3a ; &3a23 = sprite_09 ; BURSTING_3 &1112 62 3a ; &3a62 = sprite_0a ; BURSTING_4 &1114 c6 28 ; &28c6 = sprite_0b ; PLAYER_BACK &1116 59 29 ; &2959 = sprite_0c ; PLAYER_BACK_2 &1118 ec 29 ; &29ec = sprite_0d ; PLAYER_BACK_3 &111a 7f 2a ; &2a7f = sprite_0e ; PLAYER_BACK_4 &111c ec 29 ; &29ec = sprite_0f ; PLAYER_BACK_5 &111e 59 29 ; &2959 = sprite_10 ; PLAYER_BACK_6 &1120 12 2b ; &2b12 = sprite_11 ; PLAYER_FRONT &1122 a5 2b ; &2ba5 = sprite_12 ; PLAYER_FRONT_2 &1124 38 2c ; &2c38 = sprite_13 ; PLAYER_FRONT_3 &1126 cb 2c ; &2ccb = sprite_14 ; PLAYER_FRONT_4 &1128 38 2c ; &2c38 = sprite_15 ; PLAYER_FRONT_5 &112a a5 2b ; &2ba5 = sprite_16 ; PLAYER_FRONT_6 &112c b0 3c ; &3cb0 = sprite_17 ; ANTIBODY_SWIRL &112e e7 3c ; &3ce7 = sprite_18 ; ANTIBODY_SWIRL_2 &1130 1e 3d ; &3d1e = sprite_19 ; ANTIBODY_SWIRL_3 &1132 55 3d ; &3d55 = sprite_1a ; ANTIBODY_SWIRL_4 &1134 88 3d ; &3d88 = sprite_1b ; ANTIBODY_SPIKES &1136 cb 3d ; &3dcb = sprite_1c ; ANTIBODY_SPIKES_2 &1138 06 3e ; &3e06 = sprite_1d ; ANTIBODY_SPIKES_3 &113a cb 3d ; &3dcb = sprite_1e ; ANTIBODY_SPIKES_4 &113c 49 3e ; &3e49 = sprite_1f ; ANTIBODY_STICKS &113e 8c 3e ; &3e8c = sprite_20 ; ANTIBODY_STICKS_2 &1140 cf 3e ; &3ecf = sprite_21 ; ANTIBODY_STICKS_3 &1142 12 3f ; &3f12 = sprite_22 ; ANTIBODY_STICKS_4 &1144 55 3f ; &3f55 = sprite_23 ; ANTIBODY_BLOB &1146 8c 3f ; &3f8c = sprite_24 ; ANTIBODY_BLOB_2 &1148 c7 3f ; &3fc7 = sprite_25 ; ANTIBODY_BLOB_3 &114a 06 40 ; &4006 = sprite_26 ; ANTIBODY_BLOB_4 &114c e3 18 ; &18e3 = sprite_27 ; LESSER_IMP_SCUTTLER &114e 4c 19 ; &194c = sprite_28 ; LESSER_IMP_SCUTTLER_2 &1150 e3 18 ; &18e3 = sprite_29 ; LESSER_IMP_SCUTTLER_3 &1152 4c 19 ; &194c = sprite_2a ; LESSER_IMP_SCUTTLER_4 &1154 cb 1a ; &1acb = sprite_2b ; LESSER_IMP_MIASMA &1156 40 1b ; &1b40 = sprite_2c ; LESSER_IMP_MIASMA_2 &1158 cb 1a ; &1acb = sprite_2d ; LESSER_IMP_MIASMA_3 &115a 40 1b ; &1b40 = sprite_2e ; LESSER_IMP_MIASMA_4 &115c f3 17 ; &17f3 = sprite_2f ; LESSER_IMP_MUSHROOM &116e 6e 18 ; &186e = sprite_30 ; LESSER_IMP_MUSHROOM_2 &1160 f3 17 ; &17f3 = sprite_31 ; LESSER_IMP_MUSHROOM_3 &1162 6e 18 ; &186e = sprite_32 ; LESSER_IMP_MUSHROOM_4 &1164 40 1a ; &1a40 = sprite_33 ; LESSER_IMP_PUDDLE &1166 b5 19 ; &19b5 = sprite_34 ; LESSER_IMP_PUDDLE_2 &1168 40 1a ; &1a40 = sprite_35 ; LESSER_IMP_PUDDLE_3 &116a b5 19 ; &19b5 = sprite_36 ; LESSER_IMP_PUDDLE_4 &116c f9 22 ; &22f9 = sprite_37 ; DEMON_SKELETON_FRONT &116e c8 23 ; &23c8 = sprite_38 ; DEMON_SKELETON_FRONT_2 &1170 a3 24 ; &24a3 = sprite_39 ; DEMON_SKELETON_BACK &1172 7e 25 ; &257e = sprite_3a ; DEMON_SKELETON_BACK_2 &1174 59 26 ; &2659 = sprite_3b ; DEMON_REAPER_FRONT &1176 59 26 ; &2659 = sprite_3c ; DEMON_REAPER_FRONT_2 &1178 2b 21 ; &212b = sprite_3d ; DEMON_REAPER_BACK &117a 2b 21 ; &212b = sprite_3e ; DEMON_REAPER_BACK_2 &117c 28 27 ; &2728 = sprite_3f ; DEMON_TIME_FRONT &117e 28 27 ; &2728 = sprite_40 ; DEMON_TIME_FRONT_2 &1180 f7 27 ; &27f7 = sprite_41 ; DEMON_TIME_BACK &1182 f7 27 ; &27f7 = sprite_42 ; DEMON_TIME_BACK_2 &1184 f4 21 ; &21f4 = sprite_43 ; DEMON_CHICKEN_FRONT &1186 f4 21 ; &21f4 = sprite_44 ; DEMON_CHICKEN_FRONT_2 &1188 f4 21 ; &21f4 = sprite_45 ; DEMON_CHICKEN_BACK &118a f4 21 ; &21f4 = sprite_46 ; DEMON_CHICKEN_BACK_2 &118c b1 1f ; &1fb1 = sprite_47 ; IMP_PIGGY_FRONT &118e 6e 20 ; &206e = sprite_48 ; IMP_PIGGY_FRONT_2 &1190 73 16 ; &1673 = sprite_49 ; IMP_PIGGY_BACK &1192 36 17 ; &1736 = sprite_4a ; IMP_PIGGY_BACK_2 &1194 00 1f ; &1f00 = sprite_4b ; IMP_HAIRY_FRONT &1196 4f 1e ; &1e4f = sprite_4c ; IMP_HAIRY_FRONT_2 &1198 8f 12 ; &128f = sprite_4d ; IMP_HAIRY_BACK &119a 34 13 ; &1334 = sprite_4e ; IMP_HAIRY_BACK_2 &119c b0 1d ; &1db0 = sprite_4f ; IMP_EVIL_FRONT &119e 11 1d ; &1d11 = sprite_50 ; IMP_EVIL_FRONT_2 &11a0 df 13 ; &13df = sprite_51 ; IMP_EVIL_BACK &11a2 7e 14 ; &147e = sprite_52 ; IMP_EVIL_BACK_2 &11a4 bb 1b ; &1bbb = sprite_53 ; IMP_FEET_FRONT &11a6 66 1c ; &1c66 = sprite_54 ; IMP_FEET_FRONT_2 &11a8 1d 15 ; &151d = sprite_55 ; IMP_FEET_BACK &11aa c8 15 ; &15c8 = sprite_56 ; IMP_FEET_BACK_2 &11ac 62 3a ; &3a62 = sprite_57 ; UNBURSTING &11ae 23 3a ; &3a23 = sprite_58 ; UNBURSTING_2 &11b0 e8 39 ; &39e8 = sprite_59 ; UNBURSTING_3 &11b2 b5 39 ; &39b5 = sprite_5a ; UNBURSTING_4 &11b4 5e 2d ; &2d5e = sprite_5b ; PLAYER_HEAD_BACK &11b6 a3 2d ; &2da3 = sprite_5c ; PLAYER_HEAD_FRONT &11b8 ba 11 ; &11ba = sprite_5d ; FIRE ; sprite_5d ; FIRE &11ba 69 03 23 &11bd 00 00 00 00 36 00 00 6f 80 01 ff e0 03 f9 f0 07 &11cd d1 e8 06 c1 70 0e 80 38 1e 15 3c 1e 3d b6 1e 3f &11dd f2 1e fc fa 3d ec f8 3d c6 7c 3f cf 6c 37 df e6 &11ed 33 ff e0 13 ff f0 07 ff f8 07 fe fc 0f 9c f2 0f &11fd 1d 42 0f 0b 40 07 0b 88 03 87 98 00 8f 9c 00 8f &120d 1c 00 07 18 00 03 08 00 81 08 01 c0 00 01 c0 00 &121d 01 80 00 00 80 00 00 00 00 &1226 ff c9 ff ff 80 7f fe 00 1f fc 00 0f f8 00 07 f0 &1236 00 03 f0 00 07 e0 00 03 c0 00 01 c0 00 00 c0 00 &1246 00 c0 00 00 80 00 01 80 00 01 80 00 01 80 00 00 &1256 80 00 01 c0 00 07 e0 00 03 f0 00 01 e0 00 00 e0 &1266 40 08 e0 60 15 f0 60 23 f8 30 03 fc 20 01 fe 20 &1276 41 ff 70 43 ff 78 63 fe 3c 63 fc 1e f7 fc 1f ff &1286 fc 3f ff fe 3f ff ff 7f ff ; sprite_4d ; IMP_HAIRY_BACK &128f 51 03 1b &1292 00 00 00 00 00 00 00 02 00 00 03 00 00 01 84 66 &12a2 3d cc 3e fe d8 1d fe f0 0b fe fe 07 fe f8 07 fd &12b2 e0 08 bf d0 07 bf b0 0b bf b8 0d df f8 00 df f8 &12c2 0e 5f f0 07 df f0 09 df f0 04 6f e0 03 ef e0 01 &12d2 f3 c0 00 3c 00 00 2d c0 00 4b 40 00 0a 40 00 00 &12e2 00 &12e3 ff ff ff ff fd ff ff f8 ff ff f8 7b 99 c0 31 00 &12f3 00 01 80 00 03 c0 00 01 e0 00 00 f0 00 01 f0 00 &1303 07 e0 00 07 e0 00 07 e0 00 03 e0 00 03 f0 00 03 &1313 e0 00 07 e0 00 07 e0 00 07 f0 00 0f f8 00 0f fc &1323 00 1f fe 00 1f ff 80 1f ff 00 1f ff a0 1f ff f5 &1333 bf ; sprite_4e ; IMP_HAIRY_BACK_2 &1334 54 03 1c &1337 00 00 00 00 00 00 00 10 00 00 1c 60 00 0e c0 00 &1347 37 98 00 f7 f0 0d fb e0 03 fb c0 07 fb a0 0f ff &1357 70 0f ff 70 01 7f 70 0f 7f f8 17 7f f8 1b 7f f8 &1367 01 bf f0 1c bf f0 0f bf f0 13 bf e0 18 df e0 07 &1377 df c0 03 e7 c0 00 78 80 00 ef c0 01 9b 40 00 1c &1387 00 00 00 00 &138b ff ff ff ff ef ff ff c3 9f ff c1 0f ff c0 07 ff &139b 00 03 f2 00 07 e0 00 0f f0 00 1f f0 00 0f e0 00 &13ab 07 e0 00 07 f0 00 07 e0 00 03 c0 00 03 c0 00 03 &13bb e0 00 07 c0 00 07 e0 00 07 c0 00 0f c0 00 0f e0 &13cb 00 1f f8 00 1f fc 00 3f fe 00 1f fc 00 1f fe 40 &13db bf ff e1 ff ; sprite_51 ; IMP_EVIL_BACK &13df 4e 03 1a &13e2 00 00 00 00 0c 00 00 03 00 1c 7c 00 3b f3 00 37 &13f2 ed 80 0f ee c0 0f ee c0 1f f7 60 1f fb e0 1f fd &1402 e0 1f ff e0 0f ff d0 0f ff d0 07 ff a0 07 ff c0 &1412 03 ff e0 03 ff f0 07 ff 70 07 fc 38 07 80 18 07 &1422 00 08 07 00 00 03 00 00 02 00 00 00 00 00 &1430 ff f3 ff ff e0 ff e3 80 7f c0 00 ff 80 00 7f 80 &1440 00 3f c0 00 1f e0 00 1f c0 00 0f c0 00 0f c0 00 &1450 0f c0 00 0f e0 00 07 e0 00 07 f0 00 0f f0 00 1f &1460 f8 00 0f f8 00 07 f0 00 07 f0 00 83 f0 03 c3 f0 &1470 7f e3 f0 7f f7 f8 7f ff f8 ff ff fd ff ff ; sprite_52 ; IMP_EVIL_BACK_2 &147e 4e 03 1a &1481 00 00 00 00 7c 00 00 62 00 00 1c 00 06 7f 00 0d &1491 ff 80 0b ff 60 07 fe e0 07 fd e0 2f ff c0 6f ff &14a1 80 2f ff 40 0f ff d0 0f ff d0 07 ff a0 07 ff c0 &14b1 03 ff e0 03 ff f0 07 ff 70 07 fc 38 07 80 18 07 &14c1 00 08 07 00 00 03 00 00 02 00 00 00 00 00 &14cf ff 83 ff ff 01 ff ff 00 ff f9 00 ff f0 00 7f e0 &14df 00 1f e0 00 0f f0 00 0f d0 00 0f 80 00 1f 00 00 &14ef 3f 80 00 0f c0 00 07 e0 00 07 f0 00 0f f0 00 1f &14ff f8 00 0f f8 00 07 f0 00 07 f0 00 83 f0 03 c3 f0 &150f 7f e3 f0 7f f7 f8 7f ff f8 ff ff fd ff ff ; sprite_55 ; IMP_FEET_BACK &151d 54 03 1c &1520 00 00 00 00 00 00 00 00 00 06 00 00 0f 83 80 0f &1530 c7 e0 0f e7 f8 0e 97 fc 0f 7f 7e 07 ff 36 07 fe &1540 98 07 ff c0 07 fc 60 00 fb a0 0f bb a0 07 bd a0 &1550 0b bd a0 07 bd a0 1f bf e0 07 bf c0 03 df c0 01 &1560 df 80 00 cf 00 0f f0 00 03 bf 00 00 35 00 00 65 &1570 00 00 00 00 &1574 ff ff ff ff ff ff f9 ff ff f0 7c 7f e0 38 1f e0 &1584 10 07 e0 00 03 e0 00 01 e0 00 00 f0 00 00 f0 00 &1594 01 f0 00 07 f0 00 0f f0 00 0f e0 00 0f f0 00 0f &15a4 e0 00 0f e0 00 0f c0 00 0f e0 00 1f f8 00 1f fc &15b4 00 3f f0 00 7f e0 00 7f f0 00 7f fc 00 7f ff 00 &15c4 7f ff 9a ff ; sprite_56 ;IMP_FEET_BACK_2 &15c8 54 03 1c &15cb 00 00 00 00 00 00 00 1c 00 00 3f 00 00 3f 80 00 &15db 3f c0 00 1d f8 03 9d f8 03 5e e0 02 de 00 01 ff &15eb 80 03 ff c0 07 ff e0 10 ff c0 2f bf b0 17 bf 78 &15fb 0b bf f0 07 bf e0 1f bf c0 07 bf 80 03 df c0 01 &160b df 80 00 cf 00 0f f0 00 03 bf 00 00 35 00 00 65 &161b 00 00 00 00 &161f ff ff ff ff e3 ff ff c0 ff ff 80 7f ff 80 3f ff &162f 80 07 fc 40 03 f8 00 03 f8 00 07 f8 00 1f fc 00 &163f 3f f8 00 1f e0 00 0f c0 00 0f 80 00 07 c0 00 03 &164f e0 00 07 e0 00 0f c0 00 1f e0 00 3f f8 00 1f fc &165f 00 3f f0 00 7f e0 00 7f f0 00 7f fc 00 7f ff 00 &166f 7f ff 9a ff ; sprite_49 ; IMP_PIGGY_BACK &1673 60 03 20 &1676 00 00 00 00 00 00 00 03 80 1e 3c e0 3c ff 70 33 &1686 ff 80 0f ff c0 1e 7f e0 1d bf e0 1b df f0 19 df &1696 f0 1d df f0 0e 3f e0 0f ff e0 01 ff c0 07 ff c4 &16a6 0f ff e0 0f ff f6 0f 7d fa 1e fe fa 3e ff 7c 3c &16b6 ff bc 38 ff dc 38 77 dc 38 66 38 70 64 3a 70 20 &16c6 3c 7c 00 38 60 00 1e 30 00 10 18 00 00 00 00 00 &16d6 ff ff ff ff fc 7f e1 c0 1f c0 00 0f 80 00 07 80 &16e6 00 0f c0 00 1f c0 00 0f c0 00 0f c0 00 07 c0 00 &16f6 07 c0 00 07 e0 00 0f e0 00 0f f0 00 1b f0 00 11 &1706 e0 00 01 e0 00 00 e0 00 00 c0 00 00 80 00 01 80 &1716 00 01 82 00 01 83 00 01 83 00 01 07 01 80 03 8b &1726 81 01 df 81 03 ff c0 87 ff c1 c3 ff ef e7 ff ff ; sprite_4a ; IMP_PIGGY_BACK_2 &1736 5d 03 1f &1739 00 00 00 00 fc 00 00 c3 00 00 3c 80 0c ff 00 13 &1749 ff 80 2f ff c0 1e 7f e0 1d bf e0 1b df f0 1b df &1759 f0 1d df f0 0e 3f e0 0f ff e0 01 ff c0 07 ff c4 &1769 07 ff e0 07 ff f6 07 7d f6 06 7e f6 0e fe f8 0e &1779 ff 78 0e ff 78 06 77 b8 06 66 30 0e 64 70 0c 20 &1789 60 0f 00 7c 0c 00 30 07 00 5c 00 00 00 &1796 ff 03 ff fe 00 ff fe 00 7f f3 00 3f e0 00 7f c0 &17a6 00 3f 80 00 1f c0 00 0f c0 00 0f c0 00 07 c0 00 &17b6 07 c0 00 07 e0 00 0f e0 00 0f f0 00 1b f0 00 11 &17c6 f0 00 01 f0 00 00 f0 00 00 f0 00 00 e0 00 01 e0 &17d6 00 03 e0 00 03 f0 00 03 f0 00 07 e0 01 07 e0 0b &17e6 03 e0 5f 01 e0 ff 83 f0 7f 01 f8 ff a3 ; sprite_2f ; LESSER_IMP_MUSHROOM ; sprite_31 ; LESSER_IMP_MUSHROOM_3 &17f3 3c 03 14 &17f6 00 00 00 00 00 00 00 ff 00 01 ff 80 03 ff c0 03 &1806 ff c0 07 ff e0 1f ff f8 39 ff fc 39 ff fc 38 ff &1816 fc 1c ff f8 1c ff f8 0e 7f f0 0e 7f f0 07 3f e0 &1826 03 9f c0 01 cf 80 00 6e 00 00 00 00 &1832 ff ff ff ff 00 ff fe 00 7f fc 00 3f f8 00 1f f8 &1842 00 1f e0 00 07 c0 00 03 80 00 01 80 00 01 80 00 &1852 01 c0 00 03 c0 00 03 e0 00 07 e0 00 07 f0 00 0f &1862 f8 00 1f fc 00 3f fe 00 7f ff 81 ff ; sprite_30 ; LESSER_IMP_MUSHROOM_2 ; sprite_32 ; LESSER_IMP_MUSHROOM_4 &186e 39 03 13 &1871 00 00 00 01 ff 80 07 ff e0 1b ff f8 33 ff fc 73 &1881 ff fe 73 ff fe 31 ff fc 39 ff fc 39 ff fc 1c ff &1891 f8 1c ff f8 0e 7f f0 0f 3f f0 07 bf e0 03 df c0 &18a1 01 ef 80 00 7e 00 00 00 00 &18aa fe 00 7f f8 00 1f e0 00 07 c0 00 03 80 00 01 00 &18ba 00 00 00 00 00 80 00 01 80 00 01 80 00 01 c0 00 &18ca 03 c0 00 03 e0 00 07 e0 00 07 f0 00 0f f8 00 1f &18da fc 00 3f fe 00 7f ff 81 ff ; sprite_27 ; LESSER_IMP_SCUTTLER ; sprite_29 ; LESSER_IMP_SCUTTLER_3 &18e3 33 03 11 &18e6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &18f6 7e 00 03 ff 80 07 ff e0 07 ff e0 07 3f f0 03 3f &1906 f0 03 9f f0 01 cf e0 00 63 e0 00 3b c0 00 0f 00 &1916 00 00 00 &1919 ff ff ff ff ff ff ff ff ff ff ff ff ff 81 ff fc &1929 00 7f f8 00 1f f0 00 0f f0 00 0f f0 00 07 f8 00 &1939 07 f8 00 07 fc 00 0f fe 00 0f ff 80 1f ff c0 3f &1949 ff f0 ff ; sprite_28 ; LESSER_IMP_SCUTTLER_2 ; sprite_2a ; LESSER_IMP_SCUTTLER_4 &194c 33 03 11 &194f 00 00 00 01 00 00 01 81 00 00 81 00 00 c3 00 00 &195f 5a 00 71 b6 80 1e f9 c0 01 ff de 07 ff b0 03 3f &196f c0 1d 3f e0 73 9f c0 00 cf b8 03 6f 0c 02 3e 80 &197f 00 00 00 &1982 fe ff ff fc 7e ff fc 3c 7f fe 3c 7f fe 00 7f 8e &1992 00 7f 00 00 3f 80 00 01 e0 00 00 f0 00 01 e0 00 &19a2 0f 80 00 0f 00 00 07 8c 00 03 f8 00 01 f8 00 33 &19b2 fd c1 7f ; sprite_34 ; LESSER_IMP_PUDDLE_2 ; sprite_36 ; LESSER_IMP_PUDDLE_4 &19b5 44 04 11 &19b6 00 00 00 00 00 70 00 00 00 fc 00 00 00 fc 00 00 &19c6 07 ff 80 00 0e 7f e0 00 07 9f f0 00 00 ff ff 00 &19d6 00 1f ff 80 00 1f ff 80 00 0f ff 00 00 18 7f 00 &19e6 00 1f ff e0 00 00 70 f0 00 00 3f f0 00 00 01 e0 &19f6 00 00 00 00 &19fc ff 8f ff ff ff 03 ff ff fe 01 ff ff f8 00 7f ff &1a0c f0 00 1f ff e0 00 0f ff f0 00 00 ff f8 00 00 7f &1a1c ff 00 00 3f ff c0 00 3f ff e0 00 7f ff c0 00 1f &1a2c ff c0 00 0f ff e0 00 07 ff ff 80 07 ff ff c0 0f &1a3c ff ff fe 1f ; sprite_33 ; LESSER_IMP_PUDDLE ; sprite_35 ; LESSER_IMP_PUDDLE_3 &1a40 44 04 11 &1a43 00 00 00 00 03 80 00 00 05 e3 80 00 05 ff c0 00 &1a53 07 ff e0 00 02 ff c0 00 0e 1f 80 00 07 ff 80 00 &1a63 00 3f fc 00 00 7f fe 00 00 61 fe 00 00 3e 3f e0 &1a73 00 03 ff f0 00 00 2f e0 00 00 63 80 00 00 7f 00 &1a83 00 00 00 00 &1a87 fc 7f ff ff f8 1c 7f ff f0 00 3f ff f0 00 1f ff &1a97 f0 00 0f ff f0 00 1f ff e0 00 3f ff e0 00 03 ff &1aa7 f0 00 01 ff ff 00 00 ff ff 00 00 1f ff 80 00 0f &1ab7 ff c0 00 07 ff fc 00 0f ff ff 00 1f ff ff 00 7f &1ac7 ff ff 80 ff ; sprite_2b ; LESSER_IMP_MIASMA ; sprite_2d ; LESSER_IMP_MIASMA_3 &1acb 39 03 13 &1ace 00 00 00 00 00 00 00 13 00 00 eb 00 08 d0 00 14 &1ade 32 40 08 bb 00 02 4b 5c 03 b6 ac 0b 7e d0 15 9d &1aee e4 09 df 4a 01 b7 44 0d 5d a0 0c 14 00 00 3b 20 &1afe 00 3b 00 00 08 00 00 00 00 &1b07 ff ff ff ff ec ff ff 00 7f f6 00 7f e2 00 bf c0 &1b17 00 1f e0 00 23 f0 00 01 f0 00 01 e0 00 03 c0 00 &1b27 01 e0 00 00 f0 00 11 e0 00 0b e0 80 5f f3 80 0f &1b37 ff 80 5f ff c0 ff ff f7 ff ; sprite_2c ; LESSER_IMP_MIASMA_2 ; sprite_2e ; LESSER_IMP_MIASMA_4 &1b40 3c 03 14 &1b43 00 00 00 00 01 00 00 8a 80 01 41 00 00 90 60 04 &1b53 0c 60 00 6e 84 02 67 4a 05 3b a4 02 d7 40 10 af &1b63 a0 01 7d 68 02 fe 80 09 6d b0 14 16 30 08 29 00 &1b73 00 52 98 00 21 18 00 04 00 00 00 00 &1b7f ff fe ff ff 74 7f fe 20 3f fc 04 1f fa 02 0f f1 &1b8f 01 0b f9 00 11 f8 00 00 f0 00 01 e8 00 1b c4 00 &1b9f 07 ec 00 03 f0 00 07 e0 00 07 c0 80 07 e3 80 47 &1baf f7 00 03 ff 88 43 ff d2 e7 ff fb ff ; sprite_53 ; IMP_FEET_FRONT &1bbb 54 03 1c &1bbe 00 00 00 00 0c 00 00 36 00 00 f7 00 00 7f c0 00 &1bce 1f e0 03 87 c0 05 87 c0 0f 1b 80 1a ff 40 05 f7 &1bde 70 03 f3 b8 0b a3 d8 0b 03 b8 0a 0b b8 0a 2f b8 &1bee 0b 7f f0 0b f7 e0 07 a7 c0 03 97 80 03 37 b0 01 &1bfe ff 00 00 3e c0 00 c1 e0 00 db 00 00 d9 00 00 88 &1c0e 00 00 00 00 &1c12 ff f3 ff ff c1 ff ff 00 ff fe 00 3f ff 00 1f fc &1c22 00 0f f8 20 1f f0 20 1f e0 00 3f c0 00 0f e0 00 &1c32 07 f0 00 03 e0 00 03 e0 00 03 e0 00 03 e0 00 03 &1c42 e0 00 07 e0 00 0f f0 00 1f f8 00 0f f8 00 07 fc &1c52 00 0f fe 00 1f fe 00 0f fe 00 1f fe 00 7f fe 22 &1c62 ff ff 77 ff ; sprite_54 ; IMP_FEET_FRONT_2 &1c66 54 03 1c &1c69 00 00 00 00 00 00 00 01 80 00 06 c0 00 1d f0 02 &1c79 0f f8 1b 03 fc 77 c0 fc 3f 18 f8 0e fc 20 01 f5 &1c89 c0 03 d5 e0 03 c2 e0 06 8a e0 06 2b 60 06 6f 60 &1c99 06 7f f0 07 f7 e0 07 a7 e0 03 97 c0 03 37 b0 01 &1ca9 ff 00 00 3e c0 00 c1 e0 00 db 00 00 d9 00 00 88 &1cb9 00 00 00 00 &1cbd ff ff ff ff fe 7f ff f8 3f ff e0 0f fd c0 07 e0 &1ccd e0 03 80 30 01 00 00 01 80 00 03 c0 00 07 f0 00 &1cdd 1f f8 00 0f f8 00 0f f0 00 0f f0 00 0f f0 00 0f &1ced f0 00 07 f0 00 0f f0 00 0f f8 00 0f f8 00 07 fc &1cfd 00 0f fe 00 1f fe 00 0f fe 00 1f fe 00 7f fe 22 &1d0d ff ff 77 ff ; sprite_50 ; IMP_EVIL_FRONT_2 &1d11 4e 03 1a &1d14 00 00 00 00 f0 00 00 7e 00 00 39 00 01 06 c0 06 &1d24 7d 60 05 fd a0 03 fd b0 03 fd b0 0b ff b0 0b cf &1d34 f0 0d 17 e0 05 47 e0 07 8d c0 07 f8 c0 03 9e e0 &1d44 03 bf f0 01 bf f8 00 ff 38 00 fe 18 01 e0 08 01 &1d54 c0 00 01 80 00 01 80 00 00 80 00 00 00 00 &1d62 ff 0f ff fe 01 ff fe 00 ff fe 00 3f f8 00 1f f0 &1d72 00 0f f0 00 0f f8 00 07 f0 00 07 e0 00 07 e0 00 &1d82 07 e0 00 0f f0 00 0f f0 00 1f f0 00 1f f8 00 0f &1d92 f8 00 07 fc 00 03 fe 00 03 fe 00 c3 fc 01 e3 fc &1da2 1f f7 fc 3f ff fc 3f ff fe 3f ff ff 7f ff ; sprite_4f ; IMP_EVIL_FRONT &1db0 4e 03 1a &1db3 00 00 00 00 00 00 00 3e 00 00 19 00 1e 06 c0 1e &1dc3 7d 60 05 fd a0 03 fd b0 03 fd b0 0b ff b0 0b cf &1dd3 f0 0d 17 e0 05 47 e0 07 8d c0 07 f8 c0 03 9e e0 &1de3 03 bf f0 01 bf f8 00 ff 38 00 fe 18 01 e0 08 01 &1df3 c0 00 01 80 00 01 80 00 00 80 00 00 00 00 &1e01 ff ff ff ff c1 ff ff 80 ff e1 c0 3f c0 80 1f c0 &1e11 00 0f e0 00 0f f8 00 07 f0 00 07 e0 00 07 e0 00 &1e21 07 e0 00 0f f0 00 0f f0 00 1f f0 00 1f f8 00 0f &1e31 f8 00 07 fc 00 03 fe 00 03 fe 00 c3 fc 01 e3 fc &1e41 1f f7 fc 3f ff fc 3f ff fe 3f ff ff 7f ff ; sprite_4c ; IMP_HAIRY_FRONT_2 &1e4f 57 03 1d &1e52 00 00 00 00 61 00 00 37 30 00 1e e0 00 0f e0 0b &1e62 0f c0 0d b7 80 06 7b c0 01 fb e0 02 1f e0 04 2f &1e72 f0 00 67 f8 04 e3 f8 0c 01 f8 0d e1 f8 0b 7f f8 &1e82 07 7f f0 09 c7 f0 0f b3 e0 06 33 d0 05 03 bc 03 &1e92 67 58 04 7e e0 03 c1 f0 00 ff 00 00 5b 80 00 48 &1ea2 c0 00 08 00 00 00 00 &1ea9 ff 9e ff ff 08 4f ff 80 07 ff c0 0f f4 e0 0f e0 &1eb9 40 1f e0 00 3f f0 00 1f f8 00 0f f8 00 0f f0 00 &1ec9 07 f0 00 03 f0 00 03 e0 00 03 e0 00 03 e0 00 03 &1ed9 f0 00 07 e0 00 07 e0 00 0f f0 00 03 f0 00 01 f8 &1ee9 00 03 f0 00 07 f8 00 07 fc 00 0f ff 00 3f ff 00 &1ef9 1f ff a3 3f ff f7 ff ; sprite_4b ; IMP_HAIRY_FRONT &1f00 57 03 1d &1f03 00 00 00 00 00 00 00 31 00 04 1b 10 06 0f f0 1b &1f13 8f f0 0d b3 e0 06 7b c0 01 fb e0 02 1f e0 04 4f &1f23 f0 00 67 f8 04 e3 f8 0c 01 f8 0d e1 f8 0b 7f f8 &1f33 07 7f f0 09 c7 f0 0f b3 e0 06 33 d0 05 03 bc 03 &1f43 67 58 04 7e e0 03 c1 f0 01 ff 00 00 5b 80 00 48 &1f53 c0 00 08 00 00 00 00 &1f5a ff ff ff ff ce ff fb 84 6f f1 c0 07 e0 60 07 c0 &1f6a 00 07 e0 00 0f f0 00 1f f8 00 0f f8 00 0f f0 00 &1f7a 07 f0 00 03 f0 00 03 e0 00 03 e0 00 03 e0 00 03 &1f8a f0 00 07 e0 00 07 e0 00 0f f0 00 03 f0 00 01 f8 &1f9a 00 03 f0 00 07 f8 00 07 fc 00 0f ff 00 3f ff 00 &1faa 1f ff a3 3f ff f7 ff ; sprite_47 ; IMP_PIGGY_FRONT &1fb1 5d 03 1f &1fb4 00 00 00 00 1c 00 00 3f 00 03 03 80 04 fc 40 0b &1fc4 ff 80 07 ff c0 0f ff c0 0f ff c0 0f ff e8 00 3f &1fd4 f4 21 1f f4 31 8f f2 20 05 d0 1f c1 d4 7f f9 e6 &1fe4 3f fd f0 07 fd f4 18 04 f8 1e 4a f8 1e da 78 1e &1ff4 02 3c 1d 27 3c 1c fe 1c 58 76 1c 38 32 0c 1c 20 &1f04 0c 7c 00 3c 18 00 1c 30 00 34 00 00 00 &2011 ff e3 ff ff c0 ff fc 80 7f f8 00 3f f0 00 1f e0 &2021 00 3f f0 00 1f e0 00 1f e0 00 17 e0 00 03 c0 00 &2031 01 80 00 01 80 00 00 80 00 01 80 00 01 00 00 00 &2041 80 00 01 c0 00 01 c0 00 03 c0 00 03 c0 00 03 c0 &2051 00 01 c0 00 01 80 00 c1 03 00 c1 83 80 e1 81 8d &2061 c1 01 df 81 83 ff c1 87 ff 81 cf ff cb ; sprite_48 ; IMP_PIGGY_FRONT_2 &206e 5d 03 1f &2071 00 00 00 00 00 00 00 1e 00 0f 03 80 1c fc 40 0b &2081 ff 80 07 ff c0 0f ff c0 0f ff c0 0f ff e8 00 3f &2091 f4 21 1f f4 31 8f f2 20 05 d0 1f c1 d4 7f f9 e6 &20a1 3f fd e0 07 fd f4 08 05 f0 0e 4a f0 0e da fa 0e &20b1 02 78 07 27 78 07 fe 38 07 76 30 27 32 70 1e 20 &20c1 60 06 03 f0 1b 00 50 06 00 d0 00 00 00 &20ce ff ff ff ff e1 ff f0 c0 7f e0 00 3f c0 00 1f e0 &20de 00 3f f0 00 1f e0 00 1f e0 00 17 e0 00 03 c0 00 &20ee 01 80 00 01 80 00 00 80 00 01 80 00 01 00 00 00 &20fe 80 00 01 c0 00 01 e0 00 03 e0 00 07 e0 00 03 e0 &210e 00 03 f0 00 03 f0 00 83 d0 00 87 80 00 07 c0 8c &211e 0f e0 d8 07 c0 7c 07 e0 fe 07 f9 ff 2f ; sprite_3d ; DEMON_REAPER_BACK ; sprite_3e ; DEMON_REAPER_BACK_2 &212b 63 03 21 &212e 00 00 00 0c 00 00 0f 80 00 07 f0 00 07 f8 00 03 &213e ff 80 03 ff e0 03 bf f8 01 df f8 01 ff f8 00 ef &214e f0 00 ef f0 00 ff e0 00 f7 e0 01 f7 e0 01 f7 e0 &215e 01 f7 d0 01 ef b8 01 ef 78 03 df f8 07 df f8 07 &216e bf f0 02 7f e0 01 ff 80 3f ff e2 1f ff e4 0f ff &217e 98 33 f8 70 30 07 c0 77 ff 20 7f fc c0 3f c3 00 &218e 00 00 00 &2191 f3 ff ff e0 7f ff e0 0f ff f0 07 ff f0 00 7f f8 &21a1 00 1f f8 00 07 f8 00 03 fc 00 03 fc 00 03 fe 00 &21b1 07 fe 00 07 fe 00 0f fe 00 0f fc 00 0f fc 00 0f &21c1 fc 00 07 fc 00 03 fc 00 03 f8 00 03 f0 00 03 f0 &21d1 00 07 f8 00 0f c0 00 1d 80 00 08 c0 00 01 c0 00 &21e1 03 80 00 07 80 00 0f 00 00 0f 00 00 1f 80 00 3f &21f1 c0 3c ff ; sprite_43 ; DEMON_CHICKEN_FRONT ; sprite_44 ; DEMON_CHICKEN_FRONT_2 ; sprite_45 ; DEMON_CHICKEN_BACK ; sprite_46 ; DEMON_CHICKEN_BACK_2 &21f4 81 03 2b &21f7 00 00 00 00 80 00 00 00 00 04 00 00 00 02 00 00 &2207 00 00 00 40 00 02 94 00 01 50 00 0a aa 00 05 54 &2217 00 03 6b 00 0a 90 00 06 fc 80 0b fe 00 07 ff 00 &2227 1f ff 80 1f ff c0 1f ff e0 3f ff e0 3f ff e0 3f &2237 ff f0 3f ff f0 3f ff f0 3f ff f0 3f ed f8 1e c4 &2247 f8 1c 46 f8 3c 4e f8 3e 7e fc 3b fc fc 3b fc fc &2257 3d f8 7c 3d f8 7c 3d f8 3c 3c f7 3e 7c 7e 0e 78 &2267 18 00 70 00 00 70 00 00 60 00 00 40 00 00 00 00 &2277 00 &2278 ff 7f ff fe 3f ff fb 7f ff f1 fd ff fb f8 ff ff &2288 bd ff fd 0b ff f8 01 ff f0 01 ff e0 00 ff f0 00 &2298 ff f0 00 7f e0 00 7f f0 00 3f e0 00 7f e0 00 7f &22a8 c0 00 3f c0 00 1f c0 00 0f 80 00 0f 80 00 0f 80 &22b8 00 07 80 00 07 80 00 07 80 00 07 80 00 03 c0 10 &22c8 03 c1 10 03 81 00 03 80 00 01 80 00 01 80 00 01 &22d8 80 03 01 80 03 01 80 00 01 80 00 00 01 00 c0 03 &22e8 81 f1 07 e7 ff 07 ff ff 0f ff ff 1f ff ff bf ff &22f8 ff ; sprite_37 ;DEMON_SKELETON_FRONT &22f9 66 03 22 &22fc 00 00 00 04 00 00 06 00 80 0f c2 c0 03 c1 e0 01 &230c 80 70 01 83 d0 03 04 e0 02 8f 80 03 0c 00 03 8a &231c 00 01 49 00 00 95 00 00 50 80 00 ae 00 00 19 80 &232c 00 46 40 00 81 60 00 75 40 00 83 40 01 74 a0 01 &233c 82 a0 01 39 a0 03 54 c0 07 56 00 05 7f 00 02 6b &234c 80 00 d1 c0 00 8b c0 00 9f c0 00 7f 80 00 7f 00 &235c 00 3e 00 00 00 00 &2362 fb ff ff f1 ff 7f f0 3c 3f e0 18 1f f0 1c 0f fc &2372 3c 07 fc 38 07 f8 70 0f f8 20 1f f8 60 7f f8 20 &2382 ff fc 00 7f fe 00 7f ff 00 3f fe 00 7f ff 00 3f &2392 ff 00 1f fe 00 0f fe 00 1f fe 00 1f fc 00 0f fc &23a2 00 0f fc 00 0f f8 00 1f f0 00 3f f0 00 7f f8 00 &23b2 3f fc 00 1f fe 00 1f fe 00 1f ff 00 3f ff 00 7f &23c2 ff 80 ff ff c1 ff ; sprite_38 ; DEMON_SKELETON_FRONT_2 &23c8 6c 03 24 &23cb 00 00 00 00 40 00 00 60 00 00 f8 00 00 3c 00 00 &23db 0c 00 00 18 00 00 0a 00 00 19 00 00 3b 00 00 38 &23eb 00 00 58 00 00 4d 00 00 d2 00 00 4a 88 20 41 8c &23fb 58 ed 98 70 80 18 38 4c 18 14 82 9c 0a 75 8a 04 &240b 82 8a 05 74 e6 05 82 1e 05 38 fc 03 54 c0 07 56 &241b c0 05 7f 00 02 6b 80 00 d1 c0 00 8b c0 00 9f c0 &242b 00 7f 80 00 7f 00 00 3e 00 00 00 00 &2437 ff bf ff ff 1f ff ff 07 ff fe 03 ff ff 01 ff ff &2447 c1 ff ff c1 ff ff c0 ff ff c0 7f ff 80 7f ff 80 &2457 ff ff 03 ff fe 01 ff fe 00 77 df 00 23 87 00 21 &2467 02 00 03 06 00 43 80 00 43 c0 00 01 e0 00 20 f0 &2477 00 00 f0 00 00 f0 00 00 f0 00 01 f8 00 03 f0 00 &2487 1f f0 00 3f f8 00 3f fc 00 1f fe 00 1f fe 00 1f &2497 ff 00 3f ff 00 7f ff 80 ff ff c1 ff ; sprite_39 ; DEMON_SKELETON_BACK &24a3 6c 03 24 &24a6 00 00 00 00 00 00 00 00 00 00 00 00 06 00 c0 07 &24b6 81 e0 07 f1 70 03 61 a8 01 a1 90 01 c2 80 00 a2 &24c6 80 00 a3 80 01 47 80 02 1b 00 02 f6 20 03 b8 60 &24d6 03 b7 c0 00 0b e0 00 b4 00 03 b8 00 05 54 00 03 &24e6 ea 00 04 c5 00 0b f4 80 04 c2 80 09 db 00 01 c0 &24f6 00 0e 3c 00 0d fe 00 03 fe 00 03 fe 00 03 fe 00 &2506 03 fc 00 01 f8 00 00 f0 00 00 00 00 &2512 ff ff ff ff ff ff ff ff ff f9 ff 3f f0 7e 1f f0 &2522 0c 0f f0 04 07 f8 0c 03 fc 0c 07 fc 18 2f fe 08 &2532 3f fe 08 3f fc 00 3f f8 00 5f f8 00 8f f8 00 0f &2542 f8 00 1f fc 00 0f fc 00 1f f8 03 ff f0 01 ff f0 &2552 00 ff f0 00 7f e0 00 3f f0 00 3f e0 00 7f f0 00 &2562 ff e0 01 ff e0 00 ff f0 00 ff f8 00 ff f8 00 ff &2572 f8 01 ff fc 03 ff fe 07 ff ff 0f ff ; sprite_3a ; DEMON_SKELETON_BACK_2 &257e 6c 03 24 &2581 00 00 00 00 30 00 00 7c 00 00 7f 00 00 2a 00 00 &2591 30 00 00 18 00 00 14 00 00 14 00 00 2e 00 00 4e &25a1 00 00 92 00 01 54 00 02 a4 00 00 f8 00 03 b8 00 &25b1 03 b0 00 03 00 00 08 a0 60 13 b8 f0 25 45 68 73 &25c1 e2 d4 44 d6 8e 6b f7 84 34 c1 0a 19 db 00 11 c0 &25d1 00 0e 3c 00 0d fe 00 03 fe 00 03 fe 00 03 fe 00 &25e1 03 fc 00 01 f8 00 00 f0 00 00 00 00 &25ed ff cf ff ff 83 ff ff 00 ff ff 00 7f ff 80 ff ff &25fd 85 ff ff c3 ff ff c1 ff ff c1 ff ff 80 ff ff 00 &260d ff fe 00 ff fc 01 ff f8 01 ff fc 03 ff f8 03 ff &261d f8 07 ff f0 0f 9f e0 07 0f c0 02 07 80 00 03 00 &262d 00 01 00 00 20 00 00 31 80 00 60 c0 00 75 c0 00 &263d ff e0 01 ff e0 00 ff f0 00 ff f8 00 ff f8 00 ff &264d f8 01 ff fc 03 ff fe 07 ff ff 0f ff ; sprite_3b ; DEMON_REAPER_FRONT ; sprite_3c ; DEMON_REAPER_FRONT_2 &2659 66 03 22 &265c 00 00 00 07 e0 00 0f fc 00 0f 9f 00 07 6f 80 07 &266c 6f c0 03 b7 e0 03 ab f0 01 dd f0 02 da 88 03 3c &267c 80 03 f9 80 07 e6 80 07 90 40 07 b7 80 07 bb a0 &268c 07 a9 a0 0f a3 20 0f 44 c0 0f 42 c0 0e 83 60 06 &269c 81 60 01 09 b0 01 2d b0 01 61 d8 01 03 d8 01 cf &26ac cc 00 ff ae 00 1e 7e 00 01 fc 60 1f f0 1f ff 80 &26bc 01 f8 00 00 00 00 &26c2 f8 1f ff f0 03 ff e0 00 ff e0 00 7f f0 00 3f f0 &26d2 00 1f f8 00 0f f8 00 07 f8 00 07 f8 00 03 f8 00 &26e2 37 f8 00 3f f0 00 3f f0 00 1f f0 00 1f f0 00 0f &26f2 f0 00 0f e0 00 0f e0 00 1f e0 00 1f e0 00 0f f0 &2702 00 0f f8 00 07 fc 00 07 fc 00 03 fc 00 03 fc 00 &2712 01 fe 00 00 ff 00 00 9f e0 01 00 00 03 80 00 0f &2722 e0 00 7f fe 07 ff ; sprite_3f ; DEMON_TIME_FRONT ; sprite_40 ; DEMON_TIME_FRONT_2 &2728 66 03 22 &272b 00 00 00 01 b6 00 03 bb 80 0e bf 60 1e bf 70 0e &273b ff 78 0f fb fc 05 f5 f6 07 65 e0 06 ad c0 02 dd &274b 80 02 ed 80 02 f5 c0 02 fb c0 02 fd c0 02 fe c0 &275b 06 ff e0 06 ff e0 06 43 e0 07 bb e0 0f ff c0 0f &276b df 80 0f 8f 00 07 03 80 01 03 80 01 0b 80 01 5b &277b 80 01 63 c0 01 03 c0 00 c7 c0 00 3f e0 00 01 f0 &278b 00 00 70 00 00 00 &2791 fe 01 ff fc 00 7f f0 00 1f e0 00 0f c0 00 07 e0 &27a1 00 03 e0 00 01 f0 00 00 f0 00 09 f0 00 1f f8 00 &27b1 3f f8 00 3f f8 00 1f f8 00 1f f8 00 1f f8 00 1f &27c1 f0 00 0f f0 00 0f f0 00 0f f0 00 0f e0 00 1f e0 &27d1 00 3f e0 00 7f f0 00 3f f8 00 3f fc 00 3f fc 00 &27e1 3f fc 00 1f fc 00 1f fe 00 1f ff 00 0f ff c0 07 &27f1 ff fe 07 ff ff 8f ; sprite_41 ; DEMON_TIME_BACK ; sprite_42 ; DEMON_TIME_BACK_2 &27f7 66 03 22 &27fa 00 00 00 63 d0 00 3c ed 00 1f 6d c0 07 b6 d0 03 &280a d6 b8 01 da bc 01 eb b8 01 ef f0 00 ef f0 00 ff &281a f0 00 ff f0 00 7f e0 00 7f c0 00 7f c0 00 7f e0 &282a 00 df e0 00 df e0 00 df f0 01 df f0 01 bf f0 01 &283a bf f0 01 bf e0 00 ff 80 00 7f c0 00 ff e0 01 ff &284a e0 07 ff f0 1f ff f0 0f ff f0 03 ff e0 00 7f c0 &285a 00 07 80 00 00 00 &2860 9c 07 ff 00 00 ff 80 00 3f c0 00 0f e0 00 07 f8 &2870 00 03 fc 00 01 fc 00 03 fc 00 07 fe 00 07 fe 00 &2880 07 fe 00 07 ff 00 0f ff 00 1f ff 00 1f ff 00 0f &2890 fe 00 0f fe 00 0f fe 00 07 fc 00 07 fc 00 07 fc &28a0 00 07 fc 00 0f fe 00 1f ff 00 1f fe 00 0f f8 00 &28b0 0f e0 00 07 c0 00 07 e0 00 07 f0 00 0f fc 00 1f &28c0 ff 80 3f ff f8 7f ; sprite_0b ; PLAYER_BACK &28c6 48 03 18 &28c9 00 00 00 00 00 00 00 00 00 07 00 00 07 c0 00 07 &28d9 e0 60 00 70 f0 03 80 fc 01 00 1e 00 b0 60 03 b4 &28e9 60 05 b7 60 05 ae a0 02 ed c0 03 fa 00 03 8d c0 &28f9 00 71 f0 01 f6 38 03 f7 88 07 f7 80 04 7f 00 03 &2909 9f 00 07 ee 00 0f f6 00 &2911 ff ff ff ff ff ff f8 ff ff f0 3f ff f0 1f 9f f0 &2921 0f 0f f8 06 03 f8 0e 01 fc 0f 00 fc 05 01 f8 00 &2931 0f f0 00 0f f0 00 0f f8 00 1f f8 00 3f f8 00 0f &2941 fe 00 07 fc 00 03 f8 00 03 f0 00 37 f0 00 7f f8 &2951 00 7f f0 00 ff e0 00 ff ; sprite_0c ; PLAYER_BACK_2 ; sprite_10 ; PLAYER_BACK_6 &2959 48 03 18 &295c 00 00 00 00 00 00 00 00 00 00 03 00 01 c7 c0 01 &296c f7 e0 00 78 f0 00 8f 00 00 63 00 03 6d 00 03 6e &297c 00 07 6d c0 07 6d c0 05 fb 80 02 fe 00 01 8c 00 &298c 06 70 e0 05 fa 78 0b fb 9c 07 fb c4 0c 7f 80 03 &299c 9f 00 07 ef 00 0f f6 00 &29a4 ff ff ff ff ff ff ff fc ff fe 38 3f fc 00 1f fc &29b4 00 0f fc 00 07 fe 00 0f fc 00 7f f8 00 7f f8 00 &29c4 3f f0 00 1f f0 00 1f f0 00 3f f8 00 7f f8 01 1f &29d4 f0 04 07 f0 00 03 e0 00 01 f0 00 01 e0 00 3b f0 &29e4 00 7f f0 00 7f e0 00 ff ; sprite_0d ; PLAYER_BACK_3 ; sprite_0f ; PLAYER_BACK_5 &29ec 48 03 18 &29ef 00 00 00 00 00 00 00 18 00 00 3e 00 00 3f 00 00 &29ff 47 80 00 58 00 00 4c 00 00 26 80 01 6a 80 01 6d &2a0f 00 05 5b 80 02 5b 00 03 fb 00 03 fe 00 03 8e 00 &2a1f 04 70 00 1d fc 70 11 fb bc 0b ff de 1c 7f c6 03 &2a2f 9f 80 07 ef 00 0f f6 00 &2a37 ff ff ff ff e7 ff ff c1 ff ff 80 ff ff 80 7f ff &2a47 00 3f ff 00 7f ff 00 7f fe 80 3f fc 00 3f f8 00 &2a57 7f f0 00 3f f8 00 7f f8 00 7f f8 00 ff f8 00 ff &2a67 e0 01 8f c0 00 03 c0 00 01 e0 00 00 c0 00 00 e0 &2a77 00 39 f0 00 7f e0 00 ff ; sprite_0e ; PLAYER_BACK_4 &2a7f 48 03 18 &2a82 00 00 00 00 60 00 00 f8 00 00 fc 00 00 0e 00 00 &2a92 60 00 00 30 00 00 1b 00 00 0b 80 00 d1 c0 00 da &2aa2 00 06 bb 00 06 b7 00 06 fc c0 03 fb c0 39 8f 00 &2ab2 3e 70 00 15 fe 18 21 fd b8 1b fb dc 1c 7f ec 03 &2ac2 9f c6 07 ef 86 0f f6 00 &2aca ff 9f ff ff 07 ff fe 03 ff fe 01 ff ff 00 ff ff &2ada 01 ff ff 80 ff ff c0 7f ff 00 3f fe 00 1f f8 00 &2aea 3f f0 00 7f f0 00 3f f0 00 1f c0 00 1f 80 00 3f &2afa 80 00 e7 80 00 43 80 00 03 c0 00 01 c0 00 01 e0 &2b0a 00 10 f0 00 30 e0 00 79 ; sprite_11 ; PLAYER_FRONT &2b12 48 03 18 &2b15 00 00 00 00 00 00 1c 00 00 1f 00 00 0f c0 e0 03 &2b25 e0 78 00 c0 3c 01 80 0e 03 00 f6 04 cd 48 02 6c &2b35 20 06 6b b0 03 3d d8 03 fe e0 01 e2 e0 00 1c f0 &2b45 10 fe 30 38 fd c0 1d 7d f0 0b 7f f0 03 ff e0 03 &2b55 8f c0 01 00 00 00 63 c0 &2b5d ff ff ff e3 ff ff c0 ff ff c0 3f 1f e0 1e 07 f0 &2b6d 0f 03 fc 1f 81 fc 3f 00 f8 32 00 f0 00 01 f8 00 &2b7d 07 f0 00 07 f8 00 03 f8 00 07 fc 00 0f ee 00 07 &2b8d c6 00 07 82 00 0f c0 00 07 e0 00 07 f0 00 0f f8 &2b9d 00 1f fc 00 3f fe 00 1f ; sprite_12 ; PLAYER_FRONT_2 ; sprite_16 ; PLAYER_FRONT_6 &2ba5 48 03 18 &2ba8 00 00 00 00 00 00 00 00 00 07 07 00 03 c3 c0 01 &2bb8 f1 e0 00 f0 f0 00 00 30 00 0d c0 00 6c 00 03 6d &2bc8 80 03 6d 20 01 72 c0 01 fe e0 00 fe e0 00 e3 70 &2bd8 20 1c 70 70 ff 18 38 fe e8 17 7e f0 07 7f f0 03 &2be8 ff e0 03 8c 00 01 63 c0 &2bf0 ff ff ff ff ff ff f8 f8 ff f0 30 3f f8 08 1f fc &2c00 04 0f fe 06 07 ff 00 07 ff 80 0f fc 00 3f f8 00 &2c10 1f f8 00 0f fc 00 0f fc 00 0f fe 00 0f de 00 07 &2c20 8f 00 07 06 00 03 80 00 03 c0 00 07 e0 00 07 f8 &2c30 00 0f f8 00 1f fc 00 1f ; sprite_13 ; PLAYER_FRONT_3 ; sprite_15 ; PLAYER_FRONT_5 &2c38 48 03 18 &2c3b 00 00 00 00 00 00 00 1c 00 00 0f 00 01 c7 c0 00 &2c4b f3 c0 00 3c 40 00 11 80 00 0c 80 00 6d 00 01 6d &2c5b 40 01 7d 00 00 ff 60 00 ff 70 60 e3 b8 78 1c b8 &2c6b 7c ff 18 1a ff 6c 07 7e f0 0f 7f f8 07 ff f0 03 &2c7b 8f e0 01 00 00 00 63 c0 &2c83 ff ff ff ff e3 ff ff c0 ff fe 20 3f fc 00 1f fe &2c93 00 1f ff 00 1f ff c0 3f ff 80 3f fe 00 3f fc 00 &2ca3 1f fc 00 1f fe 00 0f 9e 00 07 06 00 03 02 00 03 &2cb3 00 00 03 80 00 01 e0 00 03 e0 00 03 f0 00 07 f8 &2cc3 00 0f fc 00 1f fe 00 1f ; sprite_14 ; PLAYER_FRONT_4 &2ccb 48 03 18 &2cce 00 00 00 00 f0 00 00 7e 00 00 3f 00 00 07 00 00 &2cde 0a 00 00 1d 00 00 63 c0 00 6c 40 00 ed 80 01 b5 &2cee a0 01 b5 70 01 df 40 01 ff b0 60 e3 b8 70 1c 98 &2cfe 3c ff 1c 1a ff ec 07 7e f4 0f 7f f8 07 ff f8 03 &2d0e 8f e0 01 00 00 00 63 c0 &2d16 ff 0f ff fe 01 ff ff 00 ff ff 80 7f ff c0 7f ff &2d26 e0 ff ff 80 3f ff 00 1f ff 00 1f fe 00 1f fc 00 &2d36 0f fc 00 07 fc 00 0f 9c 00 07 0e 00 03 02 00 03 &2d46 80 00 01 c0 00 01 e0 00 01 e0 00 03 f0 00 03 f8 &2d56 00 07 fc 00 1f fe 00 1f ; sprite_5b ; PLAYER_HEAD_BACK &2d5e 21 03 0b &2d61 0f f3 00 0f f3 00 0f ec 00 0f e6 00 0f e7 00 0f &2d71 ee 00 07 ee 00 07 dc 00 03 b8 00 01 60 00 00 80 &2d81 00 &2d82 e0 00 7f e0 00 7f e0 00 ff e0 00 ff e0 00 7f e0 &2d92 00 ff f0 00 ff f0 01 ff f8 03 ff fc 07 ff fe 1f &2da2 ff ; sprite_5c ; PLAYER_HEAD_FRONT &2da3 21 03 0b &2da6 00 62 60 02 aa 60 02 da 60 02 02 60 03 3e c0 03 &2db6 fe c0 03 fd 80 01 fd 80 00 f3 00 00 6c 00 00 10 &2dc6 00 &2dc7 fc 00 0f f8 00 0f f8 00 0f f8 00 0f f8 00 1f f8 &2dd7 00 1f f8 00 3f fc 00 3f fe 00 7f ff 00 ff ff 83 &2de7 ff ; wall_sprite_00 ; PANED_WINDOW_LEFT &2de8 00 03 00 0f 00 3f 00 ff 03 fc 0e 73 3f cd ff 32 &2df8 fc c5 fb 2a c4 55 1a aa d5 55 d2 aa d5 55 c0 2a &2e08 df d5 df ea df f5 c0 f2 d5 78 d2 b3 d5 0f d2 3f &2e18 d1 fc c7 f3 df cf df 39 dc e1 d3 c1 ce 41 d8 41 &2e28 d0 41 d0 43 d0 4d f0 71 f0 c1 f3 41 fc 41 f0 41 &2e38 f0 41 f0 43 f0 4d f0 71 d0 c1 d3 41 dc 41 d0 41 &2e48 d0 41 d0 41 90 43 90 4e 90 79 d0 e7 d3 9e de 7f &2e58 d9 ff c7 fc 9f f3 7f cf ff 3f 7c ff 73 ff cf fc ; wall_sprite_01 ; PANED_WINDOW_RIGHT &2e68 00 03 00 0f 00 3f 00 ff 03 fc 0f f3 3f cf ff 33 &2e78 fc c3 f3 2b cc 53 32 ab c5 5b 2a bb 55 3b aa 7b &2e88 54 e3 a9 d9 53 a1 ab a9 53 51 a7 4b 57 3b ae fb &2e98 49 fb a7 e3 4f cb 3f 3b 7c eb f3 8b ce 0b 3a 0b &2ea8 e2 0b 82 0b 82 0b 82 3b 82 cb 83 0b 8e 0b b2 0b &2eb8 c2 0b 82 0b 82 0b 82 3b 82 cb 83 0b 8e 0b b2 0b &2ec8 c2 0b 82 0b 82 0b 82 0a 82 39 80 e7 83 9e 8e 7f &2ed8 b9 ff e3 fc 8f f3 3f cf ff 3f fc ff 73 ff cf fc ; wall_sprite_02 ; ARCHWAY_LEFT ; wall_sprite_04 ; ARCHWAY_LEFT &2ee8 00 00 00 00 00 00 00 00 00 00 00 00 20 00 e8 00 &2ef8 e5 00 ea 00 e5 00 ea 00 e5 00 ea 00 c5 00 2a 00 &2f08 e5 00 ea 00 e5 00 ea 00 e5 00 ea 00 c5 00 2a 00 &2f18 e5 00 ea 00 e5 00 ea 00 e5 00 ea 00 c5 00 2a 00 &2f28 e5 00 ea 00 e5 00 ea 00 e5 00 ea 00 c5 00 2a 80 &2f38 e9 40 ec a0 ed 50 ee aa eb 55 e9 88 c8 e7 28 3d &2f48 e8 03 e8 0e e8 39 e8 e7 eb 9f ee 3f c9 bf 27 bf &2f58 ff bf ff bc ff b3 ff 8f ff 3f fc ff f3 ff cf fc ; wall_sprite_03 ; ARCHWAY_RIGHT ; wall_sprite_05 ; ARCHWAY_RIGHT &2f68 00 03 00 07 00 07 00 07 00 07 00 07 00 07 00 07 &2f78 00 04 00 03 00 07 00 07 00 07 00 07 00 07 00 07 &2f88 00 04 00 03 00 07 00 07 00 07 00 07 00 07 00 07 &2f98 00 04 00 03 00 07 00 07 00 07 00 07 00 07 00 07 &2fa8 00 04 00 03 00 07 00 17 00 17 00 17 00 17 00 37 &2fb8 00 34 00 33 00 77 00 57 00 d7 00 97 01 97 03 17 &2fc8 06 14 0c 13 18 37 b0 e7 63 9f ce 7f b9 ff e5 ff &2fd8 9d ff 7d fc fd f3 fd cf fd 3f fc ff f3 ff cf fc ; wall_sprite_06 ; STONE_WINDOW_LEFT &2fe8 00 01 00 0d 00 3d 00 f9 01 e1 0c 01 38 39 f8 f9 &2ff8 f8 f8 f0 f9 e0 fb ce f3 3e c3 7e 33 7e f8 79 f8 &3008 37 f8 07 e3 3b cb 38 3b 78 bb 78 b8 7b b1 7b 89 &3018 fb 95 fb a9 f3 95 f7 a3 f7 8f 77 bd 77 b1 73 89 &3028 7b 95 0b a9 e3 95 f3 a9 f3 95 f7 a3 f7 8f e7 bd &3038 e7 b1 f3 89 f3 95 fb a9 fb 94 fb a3 73 8f 03 bf &3048 cf bc ef b1 ef 81 ef 19 ec 3c e0 3c f3 79 e7 7b &3058 e7 7b 0f 78 8f b3 e7 8f f7 3f f4 ff f3 ff cf fc ; wall_sprite_07 ; STONE_WINDOW_RIGHT &3068 00 03 00 0f 00 2f 00 ee 03 e0 07 e3 27 cf f7 9f &3078 f0 3f f7 3f f7 bf f7 9c f7 99 f3 03 e1 8f 87 df &3088 3f de ff cc ff 83 ff 0f f0 df e1 df cd de 1d de &3098 dd cf dd ef d1 ef c9 ef 15 cf ab cc 95 c0 a1 c1 &30a8 8d cd bd cd f1 c1 c1 ed 81 ed 81 ec 81 ec 81 cc &30b8 81 ce 81 cf 8d cf bd c7 f1 c7 c1 f7 81 f7 81 f0 &30c8 81 f3 81 f3 8d c3 3d 13 fc 77 f1 e7 c7 97 16 33 &30d8 70 f3 f9 f0 fd e3 f1 cf 8d 3f 3c ff f3 ff cf fc ; wall_sprite_08 ; STONES &30e8 00 03 00 03 00 31 00 f0 00 f8 08 f8 3a fc f6 f8 &30f8 f7 62 ef 8f cf 8f 1f df 7f df 7f de 7f 9e 7e 0e &3108 7d de 3b de 03 d8 3b c2 fb ce f9 9e f0 1e 63 9e &3118 07 de 6f d8 ef d3 ef c7 ef cf 6f cf 0f 86 67 00 &3128 f7 78 f7 7e e6 7e c0 3e 01 de 79 dc fd c0 fd ee &3138 fe ef fe ef fe ef fe ef ff 03 ff 33 7e 7b 18 f8 &3148 63 f8 73 fc 7b f9 7b f3 79 f7 78 37 39 87 9b e7 &3158 c7 f3 f3 f0 fb f3 f9 cf f8 3f f0 ff f3 ff cf fc ; wall_sprite_09 ; STONE_CORNER_LEFT &3168 00 03 00 0e 00 3e 00 fe 03 fe 0f fe 2f fd ef fd &3178 ef fd ef fb cf fb 0f fb cf f0 ef c7 ef 37 cc f7 &3188 00 f7 f8 f7 fe f7 fe f7 fc f7 f0 f7 66 f7 1e f7 &3198 7e f7 fc f7 f0 f7 0c f0 3e c7 7c 37 f0 f7 c3 f7 &31a8 0f f7 ef f7 ef f0 cf c7 8f 37 6c f7 60 f7 f6 f7 &31b8 e6 f7 4e f7 1e f7 7c f7 7c f7 f8 f7 f0 f0 04 cb &31c8 7c 3b 78 fd 63 fd 8f fe cf fe ef fe ef fe 4f fe &31d8 2f ff ef fc ef f3 ef cf ef 3f cc ff c3 ff cf fc ; wall_sprite_0a ; BUTTRESS &31e8 00 03 00 07 00 33 00 f8 00 fc 08 fe 3c fe fd f0 &31f8 fd c2 f9 8f 80 3f 3c 7c 7e f3 fe cf fe 3f fc ff &3208 73 ff 0f ff df fc df f3 df cf 1f 3f 1c ff 1b c3 &3218 c7 3c f0 bc fd bc 7d bc 7d bc 3d bf 19 bc e1 bc &3228 fd be 3d be 8d bf e1 bf f9 bf f9 df 00 df 1e ef &3238 7e ef 7e 77 78 7b 63 3d 0f 9e 7f c7 7f 99 3e 3e &3248 b8 bf 83 bf df be ff 18 fc 43 f0 e7 c3 f7 13 f7 &3258 73 f7 f9 f0 f9 f3 fc cf fc 3f fc ff f3 ff cf fc ; wall_sprite_0b ; STONE_OTHER_WINDOW_LEFT &3268 00 03 00 07 00 33 00 f3 00 f8 09 fe 39 fe f1 f8 &3278 f0 f2 e6 07 cf 8f 1f cf 7f cf ff cf ff 37 7c db &3288 33 d8 0f d8 3f d9 ff d9 ff d9 ff 0b fc f7 f3 c7 &3298 cf 2f 3d 60 fd 63 fb 67 fb 6f f3 6f e3 66 23 60 &32a8 23 6e 23 6e 2f 6e 33 6e e3 6e 23 64 27 60 26 ee &32b8 26 df 26 df 2e df 2d bf 9d bf fb 8f fb 67 f7 7b &32c8 ee fc dd fc b9 fd 76 fb ef 37 df 07 9e 07 1c e7 &32d8 8d f3 81 f0 39 f3 fd cf fc 3f fc ff f3 ff cf fc ; wall_sprite_0c ; GRILL_WINDOW_LEFT &32e8 00 03 00 0e 00 3e 00 ff 03 fc 0f f3 3f cb ff 3b &32f8 fc d3 f3 ab cd 53 2a a8 ed 53 ea 8c ed 30 e8 c8 &3308 e3 0c cc 4c 30 ab c3 31 11 11 91 2a aa aa aa 64 &3318 a4 46 c6 66 e6 99 99 98 98 99 99 95 95 56 d6 22 &3328 a2 23 a3 55 d5 4c cc c8 c8 cc cc cb cb 33 b3 11 &3338 91 32 b2 aa ea a4 e4 43 e4 4f d6 3f 99 ff c3 fe &3348 cf f9 bf e7 7f 9f be 7e d9 f9 e7 e7 9f 9f 7e 7f &3358 f9 ff e7 fc 9f f3 7f cf ff 3f fc ff f3 ff cf fc ; wall_sprite_0d ; GRILL_WINDOW_RIGHT &3368 00 03 00 0f 00 3f 00 ff 03 fc 0f f3 3f c7 ff 37 &3378 fc e7 73 57 ce a7 15 54 da a3 d5 4f da 3f d4 ff &3388 d3 ff cf ff 30 7c c2 03 0e 33 19 4b c8 83 49 4b &3398 ce 33 ae 33 19 4b 18 83 29 4b ae 33 6e 33 49 4b &33a8 68 83 99 4b 9e 33 9e 33 99 4b 58 83 29 4b 2e 33 &33b8 5e 33 49 4b c8 83 c9 4b ce 33 3e 33 19 4b 30 82 &33c8 88 41 3f c7 ff 9f fe 7e f9 f9 e7 e7 9f 9f 7e 7f &33d8 f9 ff e7 fc 9f f3 7f cf ff 3f fc ff f3 ff cf fc ; wall_sprite_0e ; ARROW_SLIT &33e8 00 03 00 0f 00 07 00 37 00 fb 0b f9 27 fc ef f8 &33f8 ef e0 ef 8f c6 0f 01 df 7f df 7f 9f 7f 3f 7e 7e &3408 7e fe 00 fe 1e 78 3f 62 ff 0e fe 3e fc 7e 73 7e &3418 07 3e 77 be f7 86 f7 80 f6 6b 61 eb 07 eb 5f eb &3428 de 6a d8 68 d8 6b 18 eb dc eb dc eb dc e8 dc e8 &3438 1c eb dc eb dc eb dc eb dc eb dc eb 5c eb 1c 6a &3448 58 68 58 68 59 e9 5f eb 1f 97 de 67 d9 87 06 37 &3458 c0 f3 f3 f0 fb f3 fb cf f9 3f f0 ff f3 ff cf fc ; wall_sprite_0f ; STONE_ALCOVE_LEFT &3468 00 00 00 00 00 01 00 07 00 1f 00 7c 21 f5 eb c5 &3478 eb 15 eb 65 eb 55 eb 55 eb 55 eb 55 cb 55 2b 55 &3488 eb 55 eb 55 eb 55 eb 55 eb 55 ea 55 c9 95 2b 55 &3498 ea 55 e9 95 ea 55 eb 55 eb 55 eb 55 cb 55 2b 55 &34a8 eb 55 eb 55 eb 2d eb ae eb ae e9 8e c5 df 2c ff &34b8 ea ff ee 7f ed 3f ee 8f ef 63 ef 98 cd e7 2c f9 &34c8 ec 7f ec 3e ec f9 ef e7 ef 9f ee 3f c9 bf 27 bf &34d8 ff bf ff bc ff b3 ff 8f ff 3f fc ff f3 ff cf fc ; wall_sprite_10 ; STONE_ALCOVE_RIGHT &34e8 00 03 00 07 00 07 00 07 00 17 00 77 01 f7 07 f7 &34f8 1f 34 7c 33 f9 b7 ca b7 0a b7 6a b7 8a b7 2a b7 &3508 6a b4 6a b3 6a b7 6a b7 6a b7 6a b7 6a b7 6a b7 &3518 6a b4 6a b3 6a b7 6a b7 6a b7 6a b7 6a b7 6a b7 &3528 6a b4 6a a3 6a a7 6a 67 6a 67 6d 57 6d 57 6c b7 &3538 6e b4 6f b3 6f 77 9f 77 9e f7 5e f7 3d f7 7b b7 &3548 f7 34 ee 33 dc f7 bb e7 7f 9f fe 7f f9 ff e5 ff &3558 9d ff 7d fc fd f3 fd cf fd 3f fc ff f3 ff cf fc ; wall_sprite_11 ; STONE_CORNER_RIGHT &3568 00 03 00 0f 00 37 00 f7 03 f2 0f f0 3f f1 ff f7 &3578 ff f7 ff f7 ff f7 ff f6 ff f0 ff c0 7f 02 3c 36 &3588 12 76 0e f6 1e f6 1e f6 1e f6 1e f0 1e 32 1e 0e &3598 1e 3e 1e fc 1e f1 1e c7 1e 0f 1e 2f 1c ef 13 ef &35a8 0f ef 1f ec 1f e0 1f c6 1f 3e 1c fe 12 ce 0e 0c &35b8 1e 63 1e e7 1e e7 1e e7 1e e7 1e e7 1e f7 1e 07 &35c8 1e 33 1c f0 13 f1 0f f7 1f f7 1f f7 3f f7 3f f7 &35d8 7f f7 7f f4 ff f3 ff cf ff 3f fc ff f3 ff cf fc ; wall_sprite_12 ; BRICKWORK &35e8 00 00 00 02 00 0e 00 3e 00 fe 03 fe 0f fe 3f fe &35f8 7f f8 7f e3 7f 8f 7e 0f 78 8f 63 cf 0f cf 3f cf &3608 ff cf ff cc ff c0 ff c3 ff 0f fc 3f f0 ff c3 ff &3618 0f ff 0f ff cf ff cf fc cf f0 cf c3 cf 0f cc 3f &3628 c0 7f c2 7f 0e 7f 3e 7f fe 7f fe 7c fe 70 fe 43 &3638 fe 07 fc 27 f0 e7 c3 e7 07 e7 27 e7 e7 e7 e7 e4 &3648 e7 e0 e7 c3 e7 0f e4 3f e0 7f c2 7f 0e 7f 3e 7c &3658 fe 70 fe 42 fe 0e fc 3e f0 fe c3 fe 0f fe 3f fc ; wall_sprite_13 ; SMALL_STONE_WINDOW &3668 00 03 00 07 00 37 00 f3 00 f8 08 f8 3a fc f6 f8 &3678 f7 62 ef 8f cf 8f 1f df 7f df 7f de 7f 9e 7e 0e &3688 7d de 3b de 03 d8 3b c2 fb ce f9 9e f0 1e 67 9e &3698 0f de 6f d8 ef d3 e7 c7 e7 cf ef ce 0f 80 6f 14 &36a8 f4 76 f1 f6 c7 e6 1f 9a 7e 7e 79 fa 67 fa 5f fa &36b8 3f e2 9f a2 c6 22 d8 2a dc 34 cc 65 cf a5 0e 28 &36c8 67 28 73 93 79 e7 78 cf 7a 1f 7b 1f 3b 8f 9b e7 &36d8 c7 f3 f3 f0 fb f3 f9 cf f8 3f f0 ff f3 ff cf fc ; wall_sprite_14 ; STONE_CLOSED_ARCHWAY_LEFT &36e8 00 00 00 00 00 00 00 00 00 00 08 00 3a 00 7b 00 &36f8 7b c0 7b f7 7b f7 73 d7 49 f7 3a 77 7b 87 7b b0 &3708 7b bf 61 b9 1a 10 7b 8f 7b e0 7b e9 71 ae 48 ef &3718 3a 6a 7b 87 7b d0 7b 1f 60 99 1a 59 7b 13 7b cc &3728 7b 90 79 58 60 d0 02 00 71 80 7a 40 7b 00 7b 00 &3738 7a 00 25 00 1d 00 3e 80 1f 40 0e 90 45 e3 e3 f7 &3748 f3 f7 f9 e7 fc ef fc 0f f8 1f f3 9e cf c0 0f ff &3758 63 ff f8 f8 fe 63 fe 0f ff 3f fc ff f3 ff 0f fc ; wall_sprite_15 ; STONE_CLOSED_ARCHWAY_RIGHT &3768 00 02 00 0e 00 3e 00 3e 00 3e 00 38 00 a6 00 9e &3778 00 be 01 be 01 be 00 38 01 26 03 1e 02 3e 14 3e &3788 64 3e f4 3e c6 3c d4 32 b0 0e c8 3e 30 3e 60 3e &3798 50 3e 69 38 53 26 45 1e 0c 3e a9 3e 28 3e 2c 3c &37a8 c0 32 00 0e 70 3e 20 3e 40 3e 00 3e 00 3e 00 00 &37b8 00 3c 00 3c 00 7c 00 79 00 39 00 cb 00 f3 01 f7 &37c8 01 e7 02 e7 07 47 0f 93 2f bb ef 39 f6 3c f0 fc &37d8 f9 fc f9 f0 f3 c3 c7 07 0f 3f 1c ff 13 ff cf fc ; wall_sprite_17 ; WOOD_RIGHT &37e8 00 03 00 0e 00 3e 00 ff 03 bf 0e 3c 3c f3 f3 cb &37f8 ef 33 7e c3 e1 2b 96 53 48 ab e9 53 ea ab e9 53 &3808 ea ab e9 55 ea a5 e9 55 d2 aa d5 52 d2 aa d5 53 &3818 d2 ab d5 53 ea ab e9 53 ea a9 e9 55 6a a9 69 55 &3828 6a a9 a9 55 aa ab b5 53 b4 ab 95 53 94 ab d5 53 &3838 d4 ab d5 53 d4 a7 95 57 b4 a7 b5 53 b4 ab a9 53 &3848 aa ab a9 53 6a ab 69 52 6a a9 69 47 ea be e8 7f &3858 e9 ff e3 fc 9f f3 7f cf ff 3f 7c ff 73 ff cf fc ; wall_sprite_16 ; WOOD_LEFT ; wall_sprite_18 ; WOOD_LEFT &3868 00 03 00 0f 00 3f 00 ff 03 fc 0f f3 3f c7 ff 07 &3878 fc 57 f1 27 cd 57 3a ab fa 53 f4 ab f5 53 f4 ab &3888 f5 53 74 ab 69 53 6a ab 69 53 74 ab 75 53 74 ab &3898 75 53 74 ab 75 53 7a ab 7a 53 7a ab 7a 53 7a ab &38a8 7a 57 7a a7 7a 57 7a a7 3a 57 3a a7 3d 57 3d 27 &38b8 3d 57 3d 27 3d 4f 3d 2f 3d 4f 3d 2f 3d 4f 3d 27 &38c8 3b 57 3a a7 7a 53 7a aa 7a 51 7a a7 7a 1e f8 fe &38d8 f3 ff cf fc 3f f3 ff cf cf 3f dc ff f3 ff cf fc ; wall_sprite_address_table &38e8 e8 2d ; &2de8 = wall_sprite_00 ; PANED_WINDOW_LEFT &38ea 68 2e ; &2e68 = wall_sprite_01 ; PANED_WINDOW_RIGHT &38ec e8 2e ; &2ee8 = wall_sprite_02 ; ARCHWAY_LEFT &38ee 68 2f ; &2f68 = wall_sprite_03 ; ARCHWAY_RIGHT &38f0 e8 2e ; &2ee8 = wall_sprite_04 ; ARCHWAY_LEFT &38f2 68 2f ; &2f68 = wall_sprite_05 ; ARCHWAY_RIGHT &38f4 e8 2f ; &2fe8 = wall_sprite_06 ; STONE_WINDOW_LEFT &38f6 68 30 ; &3068 = wall_sprite_07 ; STONE_WINDOW_RIGHT &38f8 e8 30 ; &30e8 = wall_sprite_08 ; STONES &38fa 68 31 ; &3168 = wall_sprite_09 ; STONE_CORNER_LEFT &38fc e8 31 ; &31e8 = wall_sprite_0a ; BUTTRESS &38fe 68 32 ; &3268 = wall_sprite_0b ; STONE_OTHER_WINDOW_LEFT &3900 e8 32 ; &32e8 = wall_sprite_0c ; GRILL_WINDOW_LEFT &3902 68 33 ; &3368 = wall_sprite_0d ; GRILL_WINDOW_RIGHT &3904 e8 33 ; &33e8 = wall_sprite_0e ; ARROW_SLIT &3906 68 34 ; &3468 = wall_sprite_0f ; STONE_ALCOVE_LEFT &3908 e8 34 ; &34e8 = wall_sprite_10 ; STONE_ALCOVE_RIGHT &390a 68 35 ; &3568 = wall_sprite_11 ; STONE_CORNER_RIGHT &390c e8 35 ; &35e8 = wall_sprite_12 ; BRICKWORK &390e 68 36 ; &3668 = wall_sprite_13 ; SMALL_STONE_WINDOW &3910 e8 36 ; &36e8 = wall_sprite_14 ; STONE_CLOSED_ARCHWAY_LEFT &3912 68 37 ; &3768 = wall_sprite_15 ; STONE_CLOSED_ARCHWAY_RIGHT &3914 68 38 ; &3868 = wall_sprite_16 ; WOOD_LEFT &3916 e8 37 ; &37e8 = wall_sprite_17 ; WOOD_RIGHT &3918 68 38 ; &3868 = wall_sprite_18 ; WOOD_LEFT ; sprite_01 ; WINGED_BOOT &391a 4c 04 13 &391d 00 00 00 00 00 00 01 80 00 00 03 00 00 00 0b 00 &392d 00 07 cb 00 00 0f eb 10 00 0c 2f b0 0f 93 cf a0 &393d 1f ef ff a0 30 1f df a0 2f ff df 60 1b ff e7 60 &394d 33 eb f0 c0 31 ff f7 c0 18 ef 1f c0 0f c4 13 80 &395d 07 84 20 00 00 03 c0 00 00 00 00 00 &3969 ff ff fe 7f ff ff fc 3f ff ff f0 7f ff f8 20 7f &3979 ff f0 00 6f ff e0 00 47 f0 60 00 07 e0 00 00 0f &3989 c0 00 00 0f 80 00 00 0f 80 00 00 0f 80 00 00 0f &3999 80 00 00 1f 80 00 00 1f c0 00 00 1f e0 10 00 3f &39a9 f0 30 0c 7f f8 78 1f ff ff fc 3f ff ; sprite_07 ; BURSTING ; sprite_5a ; UNBURSTING_4 &39b5 18 02 0c &39b8 00 00 00 00 00 00 00 00 00 00 01 00 07 a0 01 20 &39c8 06 00 07 60 03 40 00 00 &39d0 ff ff ff ff ff ff ff ff fe ff f8 1f f0 0f f0 0f &39e0 f0 0f f0 0f f8 1f fc 3f ; sprite_08 ; BURSTING_2 ; sprite_59 ; UNBURSTING_3 &39e8 1c 02 0e &39eb 00 00 00 00 00 00 00 00 00 00 03 80 07 c0 0f b0 &39fb 0c 30 00 00 0e 30 06 70 02 e0 00 00 &3a07 ff ff ff ff ff ff ff ff fc 7f f8 3f f0 0f e0 07 &3a17 e0 07 e0 07 e0 07 f0 07 f8 0f fc 1f ; sprite_09 ; BURSTING_3 ; sprite_58 ; UNBURSTING_2 &3a23 1e 02 0f &3a26 00 00 00 00 00 00 07 c0 1f e0 3f c8 3f 0c 38 0c &3a36 00 0c 30 00 3c 20 1e 3c 0f 78 07 70 00 00 &3a44 ff ff ff ff f8 3f e0 1f c0 07 80 03 80 01 80 01 &3a54 80 01 80 01 80 01 c0 01 e0 03 f0 07 f8 0f ; sprite_0a ; BURSTING_4 ; sprite_57 ; UNBURSTING &3a62 20 02 10 &3a65 00 00 07 80 1f 00 38 18 64 1c 50 06 40 26 00 00 &3a75 00 00 00 06 40 2e 68 44 74 0c 3a 78 0e e0 00 00 &3a85 f8 7f e0 3f c0 07 80 03 00 01 00 00 00 00 00 00 &3a95 00 00 00 00 00 00 00 01 00 01 80 03 c0 07 f0 0f ; sprite_02 ; POTION &3aa5 20 02 10 &3aa8 00 00 07 f0 1f f8 3f fc 63 fe 63 fe 73 fe 39 fc &3ab8 0e f0 02 c0 03 c0 02 40 05 a0 03 c0 01 80 00 00 &3ac8 fc 1f e0 07 c0 03 80 01 00 00 00 00 00 00 80 01 &3ad8 c0 03 f0 0f f8 1f f8 1f f0 0f f8 1f fc 3f fe 7f ; sprite_05 ; CROSS &3ae8 2d 03 0f &3aeb 00 00 00 30 00 00 58 00 00 66 00 00 3f 80 38 03 &3afb e0 5c 00 f9 e4 00 3f f8 00 1f c0 00 ff f0 01 7d &3b0b fc 01 90 5c 00 f0 64 00 00 38 00 00 00 &3b18 cf ff ff 87 ff ff 01 ff ff 00 7f c7 80 1f 83 c0 &3b18 06 01 fc 00 01 ff 00 03 ff 00 07 fe 00 03 fc 00 &3b28 01 fc 02 01 fe 07 01 ff 0f 83 ff ff c7 ; sprite_06 ; BIBLE &3b45 39 03 13 &3b48 00 00 00 00 04 00 00 1b 00 00 6a c0 01 d1 30 06 &3b58 aa ac 1d 55 52 2a 9f 2a 65 7f c4 69 f9 f2 67 e0 &3b68 7c 3d 8d 1e 3e 63 86 0f 99 18 03 e6 60 00 f9 80 &3b78 00 3e 00 00 04 00 00 00 00 &3b81 ff fb ff ff e0 ff ff 80 3f fe 00 0f f8 00 03 e0 &3b91 00 01 c0 00 00 80 00 00 00 00 00 00 00 00 00 00 &3ba1 01 80 00 00 80 00 00 c0 00 01 f0 00 07 fc 00 1f &3bb1 ff 00 7f ff c1 ff ff fb ff ; sprite_03 ; HAMMER &3bba 2d 03 0f &3bbd 00 00 00 70 00 00 7c 00 00 3f 00 00 0f c0 5c 03 &3bcd f1 be 00 fd be 00 3e be 00 0d be 00 33 dc 00 3f &3bdd f0 00 3f e0 00 1f 80 00 0e 00 00 00 00 &3bea 8f ff ff 03 ff ff 00 ff ff 80 3f 83 c0 0e 01 f0 &3bfa 00 00 fc 00 00 ff 00 00 ff c0 00 ff 80 01 ff 80 &3c0a 03 ff 80 07 ff c0 1f ff e0 7f ff f1 ff ; sprite_04 ; HOURGLASS &3c17 4b 03 19 &3c1a 00 00 00 00 7e 00 01 81 80 03 7e c0 06 df 60 02 &3c2a 9f 40 05 1f a0 05 bf a0 04 cf 20 04 cf 20 04 6e &3c3a 20 04 3c 20 04 2c 20 04 6e 20 04 ff 20 05 81 a0 &3c4a 04 7e 20 05 ff a0 03 ff c0 07 ff e0 07 ff e0 03 &3c5a ff c0 01 ff 80 00 7e 00 00 00 00 &3c65 ff 81 ff fe 00 7f fc 00 3f f8 00 1f f0 00 0f f0 &3c75 00 0f f0 00 0f f0 00 0f f0 00 0f f0 00 0f f0 00 &3c85 0f f0 00 0f f0 00 0f f0 00 0f f0 00 0f f0 00 0f &3c95 f0 00 0f f0 00 0f f0 00 0f f0 00 0f f0 00 0f f8 &3ca5 00 1f fc 00 3f fe 00 7f ff 81 ff ; sprite_17 ; ANTIBODY_SWIRL &3cb0 1a 02 0d &3cc3 00 00 00 00 01 e0 0e 38 3f cc 78 e6 62 76 67 f6 &3cd3 73 f6 38 1c 1f f8 07 f0 00 00 &3cdd ff ff fe 1f f0 07 c0 03 80 01 00 00 00 00 00 00 &3ced 00 00 80 01 c0 03 e0 07 f8 0f ; sprite_18 ; ANTIBODY_SWIRL_2 &3ce7 1a 02 0d &3cea 00 00 0f 00 3f c0 70 e0 67 74 6f ba 6a 3a 37 f2 &3cfa 39 e6 1e 0c 07 f8 01 e0 00 00 &3d04 f0 ff c0 3f 80 1f 00 0b 00 01 00 00 00 00 80 00 &3d14 80 00 c0 01 e0 03 f8 07 fe 1f ; sprite_19 ; ANTIBODY_SWIRL_3 &3d1e 1a 02 0d &3d21 00 00 0f 00 3f e0 78 f8 73 7c 67 9e 76 ce 37 3e &3d31 3b fc 1c f8 07 00 01 e0 00 00 &3d3b f0 ff c0 1f 80 07 00 03 00 01 00 00 00 00 80 00 &3d4b 80 01 c0 03 e0 07 f8 0f fe 1f ; sprite_1a ; ANTIBODY_SWIRL_4 &3d55 18 02 0c &3d58 00 00 00 00 0f e0 38 78 67 bc 4f ce 5c 66 1d c6 &3d68 0e 0e 07 fc 01 f0 00 00 &3d70 ff ff f0 1f c0 07 80 03 00 01 00 00 00 00 80 00 &3d80 e0 00 f0 01 f8 03 fe 0f ; sprite_1b ; ANTIBODY_SPIKES &3d88 20 02 10 &3d8b 00 00 00 00 00 08 03 d0 67 e0 2f f0 1f f8 1f f8 &3d9b 19 fa 16 f8 0e c0 18 b0 23 78 00 18 00 04 00 00 &3dab ff ff ff f7 fc 23 98 07 00 0f 80 07 c0 03 c0 01 &3dbb c0 00 c0 01 e0 07 c0 07 80 03 dc 03 ff e1 ff fb ; sprite_1c ; ANTIBODY_SPIKES_2 ; sprite_1e ; ANTIBODY_SPIKES_4 &3dcb 1c 02 0e &3dde 00 00 00 00 00 00 03 c0 07 e0 0b f0 1f e8 1f f8 &3dee 1f f8 1f f8 0b f0 07 c0 03 c0 00 00 &3dea ff ff ff ff fc 3f f8 1f f0 0f e0 07 c0 03 c0 03 &3dfa c0 03 c0 03 e0 07 f0 0f f8 1f fc 3f ; sprite_1d ; ANTIBODY_SPIKES_3 &3e06 20 02 10 &3e09 00 00 20 00 10 00 1d c0 0d e6 0b dc 17 b8 1f d0 &3e19 5f e8 1f f8 0d f0 02 e0 07 40 06 00 08 00 00 00 &3e29 df ff 8f ff c2 3f c0 19 e0 00 e0 01 c0 03 80 03 &3e39 00 03 80 03 e0 07 f0 0f f0 1f f0 3f e1 ff f7 ff ; sprite_1f ; ANTIBODY_STICKS &3e49 20 02 10 &3e4c 00 00 00 0c 18 1e 2c 3e 24 7c 1e f8 05 f0 03 e0 &3e5c 07 c0 0f a0 1f 78 3e 2c 5c 24 68 18 30 00 00 00 &3e6c ff f3 e7 e1 c3 c0 81 80 81 01 c0 03 e0 07 f8 0f &3e7c f0 1f e0 07 c0 03 80 81 01 81 03 c3 87 e7 cf ff ; sprite_20 ; ANTIBODY_STICKS_2 &3e8c 20 02 10 &3e8f 00 00 00 0c 00 1e 00 3e 00 7c 30 f8 59 f0 4b 0c &3e9f 36 f6 0e f2 1f 0c 3e 00 5c 00 68 00 30 00 00 00 &3eaf ff f3 ff e1 ff c0 ff 80 cf 01 86 03 00 03 00 01 &3ebf 80 00 c0 00 c0 01 80 f3 01 ff 03 ff 87 ff cf ff ; sprite_21 ; ANTIBODY_STICKS_3 &3ecf 20 02 10 &3ed2 00 00 00 0c 00 0e 00 36 00 58 00 48 00 f0 01 c0 &3ee2 06 80 0f 00 1f 00 3e 00 5c 00 68 00 30 00 00 00 &3ef2 ff f3 ff e1 ff c0 ff 80 ff 01 fe 03 fc 07 f8 0f &3f02 f0 1f e0 3f c0 7f 80 ff 01 ff 03 ff 87 ff cf ff ; sprite_22 ; ANTIBODY_STICKS_4 &3f12 20 02 10 &3f15 00 00 03 0c 05 9e 04 be 03 7c 03 78 03 70 03 60 &3f25 04 c0 0f 80 1f 00 3e c0 7d 60 79 20 30 c0 00 00 &3f35 fc f3 f8 61 f0 00 f0 00 f8 01 f8 03 f8 07 f8 0f &3f45 f0 1f e0 3f c0 3f 80 1f 00 0f 00 0f 86 1f cf 3f ; sprite_23 ; ANTIBODY_BLOB &3f55 1a 02 0d &3f58 00 00 00 00 00 00 00 00 03 c0 07 e0 0f f0 0f 70 &3f68 0e f0 0f f0 07 e0 03 c0 00 00 &3f72 ff ff ff ff ff ff fc 3f f8 1f f0 0f e0 07 e0 07 &3f82 e0 07 e0 07 f0 0f f8 1f fc 3f ; sprite_24 ; ANTIBODY_BLOB_2 &3f8c 1c 02 0e &3f8f 00 00 00 00 00 00 03 c0 07 e0 0f f0 1f b8 1d f8 &3f9f 1f f8 1f 78 0f f0 07 e0 03 c0 00 00 &3fab ff ff ff ff fc 3f f8 1f f0 0f e0 07 c0 03 c0 03 &3fbb c0 03 c0 03 e0 07 f0 0f f8 1f fc 3f ; sprite_25 ; ANTIBODY_BLOB_3 &3fc7 1e 02 0f &3fca 00 00 00 00 03 c0 07 e0 0f f0 1f f8 3c 9c 3c 1c &3fda 3e fc 3c 7c 1e 78 0f f0 07 e0 03 c0 00 00 &3fe8 ff ff fc 3f f8 1f f0 0f e0 07 c0 03 80 01 80 01 &3ff8 80 01 80 01 c0 03 e0 07 f0 0f f8 1f fc 3f ; sprite_26 ; ANTIBODY_BLOB_4 &4006 20 02 10 &4009 00 00 03 c0 0f f0 1f f8 38 fc 30 cc 70 86 78 06 &4019 7e 0e 7c 7e 38 3c 3c 3c 1e 78 0f f0 03 c0 00 00 &4029 fc 3f f0 0f e0 07 c0 03 80 01 80 01 00 00 00 00 &4039 00 00 00 00 80 01 80 01 c0 03 e0 07 f0 0f fc 3f ; update_exploding_demon_antibody &4049 20 7c 50 JSR &507c ; move_object &404c 20 58 43 JSR &4358 ; animate_object_with_four_frames &404f bd b3 60 LDA &60b3,X ; objects_speed_x &4052 f0 05 BEQ &4059 ; to_burst_object # Burst it if it hits a wall &4054 a9 03 LDA #&03 &4056 85 54 STA &54 ; colour_change_cooldown # Keep colours changed while demon is exploding &4058 60 RTS ; to_burst_object &4059 4c c8 40 JMP &40c8 ; burst_object ; update_fired_antibody &405c bd d7 5f LDA &5fd7,X ; objects_sprite &405f f0 12 BEQ &4073 ; leave # Is there a fired antibody in this slot? &4061 c9 07 CMP #&07 ; BURSTING &4063 f0 73 BEQ &40d8 ; update_bursting_object &4065 20 7c 50 JSR &507c ; move_object &4068 20 58 43 JSR &4358 ; animate_object_with_four_frames &406b bd b3 60 LDA &60b3,X ; objects_speed_x &406e f0 58 BEQ &40c8 ; burst_object # Burst it if it hits a wall &4070 4c bb 41 JMP &41bb ; check_fired_antibody_for_overlap_with_imps ; leave &4073 60 RTS ; update_wild_antibody &4074 bd d7 5f LDA &5fd7,X ; objects_sprite &4077 f0 39 BEQ &40b2 ; leave # Is there a wild antibody in this slot? &4079 c9 07 CMP #&07 ; BURSTING &407b f0 5b BEQ &40d8 ; update_bursting_object &407d bd 45 60 LDA &6045,X ; objects_data &4080 30 c7 BMI &4049 ; update_exploding_demon_antibody # Top bit set if this is part of a demon exploding &4082 ad d7 5f LDA &5fd7 ; objects_sprite &4085 c9 0b CMP #&0b ; PLAYER_BACK &4087 90 20 BCC &40a9 ; remove_wild_antibody # Remove wild antibody if player not active &4089 a0 00 LDY #&00 ; PLAYER_SLOT &408b 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &408e 90 23 BCC &40b3 ; collect_wild_antibody # Collect wild antibody if overlapping with player &4090 ad 03 60 LDA &6003 ; objects_x_room &4093 dd 03 60 CMP &6003,X ; objects_x_room &4096 d0 11 BNE &40a9 ; remove_wild_antibody # Remove wild antibody when player leaves room &4098 ad 9d 60 LDA &609d ; objects_y_room &409b dd 9d 60 CMP &609d,X ; objects_y_room &409e d0 09 BNE &40a9 ; remove_wild_antibody &40a0 20 f3 40 JSR &40f3 ; change_object_velocity &40a3 20 7c 50 JSR &507c ; move_object &40a6 4c 58 43 JMP &4358 ; animate_object_with_four_frames ; remove_wild_antibody &40a9 20 c8 40 JSR &40c8 ; burst_object &40ac bd 45 60 LDA &6045,X ; objects_data # object_data is the room type for wild antibodies &40af aa TAX &40b0 f6 67 INC &67,X ; available_antibodies # Return antibody to room's reservoir ; leave &40b2 60 RTS ; collect_wild_antibody &40b3 a5 4a LDA &4a ; pocket_position &40b5 c9 0b CMP #&0b &40b7 d0 03 BNE &40bc ; free_pocket &40b9 4c c8 40 JMP &40c8 ; burst_object # Burst wild antibody if pockets are full ; free_pocket &40bc bc d7 5f LDY &5fd7,X ; objects_sprite &40bf a9 00 LDA #&00 &40c1 9d d7 5f STA &5fd7,X ; objects_sprite # Remove wild antibody &40c4 98 TYA &40c5 4c 89 53 JMP &5389 ; collect_object # and pocket it ; burst_object &40c8 a9 07 LDA #&07 ; BURSTING &40ca 9d d7 5f STA &5fd7,X ; objects_sprite &40cd a9 03 LDA #&03 &40cf 9d 19 60 STA &6019,X ; objects_animation &40d2 a9 00 LDA #&00 &40d4 9d 2f 60 STA &602f,X ; objects_facing &40d7 60 RTS ; update_bursting_object &40d8 de 19 60 DEC &6019,X ; objects_animation &40db 10 15 BPL &40f2 ; leave # Has the bursting object finished bursting? &40dd a9 00 LDA #&00 &40df 9d d7 5f STA &5fd7,X ; objects_sprite # If so, remove bursting object &40e2 e4 5a CPX &5a ; fire_object &40e4 d0 02 BNE &40e8 ; not_fire # Was it the FIRE? &40e6 85 5a STA &5a ; fire_object # If so, note FIRE has been removed ; not_fire &40e8 e0 0f CPX #&0f ; LAST_DEMON_SLOT + 1 # Was it a demon? &40ea b0 06 BCS &40f2 ; leave &40ec e0 0b CPX #&0b ; FIRST_DEMON_SLOT &40ee 90 02 BCC &40f2 ; leave &40f0 e6 62 INC &62 ; demons_destroyed # If so, note a demon has been destroyed ; leave &40f2 60 RTS ; change_object_velocity &40f3 de 71 60 DEC &6071,X ; objects_speed_change_cooldown &40f6 f0 05 BEQ &40fd ; randomise_object_velocity &40f8 bd b3 60 LDA &60b3,X ; objects_speed_x &40fb d0 34 BNE &4131 ; leave ; randomise_object_velocity &40fd 20 eb 5e JSR &5eeb ; rnd &4100 29 3f AND #&3f &4102 9d 71 60 STA &6071,X ; objects_speed_change_cooldown &4105 20 eb 5e JSR &5eeb ; rnd &4108 29 03 AND #&03 # Antibodies and imps move at a random speed &410a 09 04 ORA #&04 &410c 9d b3 60 STA &60b3,X ; objects_speed_x &410f 9d c9 60 STA &60c9,X ; objects_speed_y &4112 20 eb 5e JSR &5eeb ; rnd &4115 29 07 AND #&07 &4117 bc d7 5f LDY &5fd7,X ; objects_sprite &411a c0 37 CPY #&37 ; FIRST_DEMON_SPRITE # Is this a demon? &411c 90 10 BCC &412e ; not_demon &411e 29 03 AND #&03 &4120 c0 47 CPY #&47 ; LAST_DEMON_SPRITE + 1 &4122 b0 0a BCS &412e ; not_demon &4124 a8 TAY &4125 a9 04 LDA #&04 # Demons move at a constant speed &4127 9d b3 60 STA &60b3,X ; objects_speed_x &412a 9d c9 60 STA &60c9,X ; objects_speed_y &412d 98 TYA ; not_demon &412e 9d 2f 60 STA &602f,X ; objects_facing ; leave &4131 60 RTS ; randomise_available_antibodies &4132 a2 1b LDX #&1b ; randomise_available_antibodies_loop &4134 20 eb 5e JSR &5eeb ; rnd &4137 29 0f AND #&0f &4139 09 10 ORA #&10 &413b 95 67 STA &67,X ; available_antibodies &413d ca DEX &413e 10 f4 BPL &4134 ; randomise_available_antibodies_loop &4140 60 RTS ; summon_wild_antibody &4141 a5 23 LDA &23 ; player_height &4143 c9 92 CMP #&92 &4145 d0 12 BNE &4159 ; leave # Is the player fully present? If not, leave &4147 a5 1a LDA &1a ; game_timer &4149 29 0f AND #&0f &414b d0 0c BNE &4159 ; leave # Only summon antibodies every 16 frames &414d a2 03 LDX #&03 ; FIRST_WILD_ANTIBODY_SLOT ; find_free_slot &414f bd d7 5f LDA &5fd7,X ; objects_sprite &4152 f0 06 BEQ &415a ; found_slot # Is this slot empty? &4154 e8 INX &4155 e0 07 CPX #&07 ; LAST_WILD_ANTIBODY_SLOT + 1 &4157 d0 f6 BNE &414f ; find_free_slot ; leave &4159 60 RTS ; found_slot &415a 86 20 STX &20 ; slot &415c ae 03 60 LDX &6003 ; objects_x_room &415f ac 9d 60 LDY &609d ; objects_y_room &4162 20 c4 4a JSR &4ac4 ; get_room_data_byte &4165 f0 f2 BEQ &4159 ; leave # Don't summon wild antibodies outside &4167 aa TAX &4168 b5 67 LDA &67,X ; available_antibodies &416a f0 ed BEQ &4159 ; leave # Does this type of room have antibodies available? &416c d6 67 DEC &67,X ; available_antibodies &416e ad 03 60 LDA &6003 ; objects_x_room &4171 8d ae 41 STA &41ae ; wild_antibody_template + 2 # Set x room from player &4174 ad 9d 60 LDA &609d ; objects_y_room &4177 8d b5 41 STA &41b5 ; wild_antibody_template + 9 # Set y room from player &417a 8a TXA &417b 8d b1 41 STA &41b1 ; wild_antibody_template + 5 # Set data to be type of room &417e 8a TXA &417f 29 03 AND #&03 &4181 0a ASL A &4182 0a ASL A &4183 69 17 ADC #&17 ; FIRST_ANTIBODY_SPRITE &4185 8d ac 41 STA &41ac ; wild_antibody_template # Set sprite from type of room &4188 20 eb 5e JSR &5eeb ; rnd &418b 29 7c AND #&7c &418d 18 CLC &418e 69 40 ADC #&40 &4190 8d ad 41 STA &41ad ; wild_antibody_template + 1 # Set x fraction at random &4193 20 eb 5e JSR &5eeb ; rnd &4196 29 7c AND #&7c &4198 18 CLC &4199 69 40 ADC #&40 &419b 8d b4 41 STA &41b4 ; wild_antibody_template + 8 # Set y fraction at random &419e a2 ac LDX #&ac &41a0 a0 41 LDY #&41; &41ac = wild_antibody_template &41a2 a5 20 LDA &20 ; slot &41a4 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y &41a7 a6 20 LDX &20 ; slot &41a9 4c fd 40 JMP &40fd ; randomise_object_velocity ; wild_antibody_template &41ac 00 ; sprite (overwritten) &41ad 00 ; x_fraction (overwritten) &41ae 00 ; x_room (overwritten) &41af 00 ; animation &41b0 00 ; facing &41b1 00 ; data (overwritten) &41b2 08 ; size &41b3 00 ; objects_speed_change_cooldown &41b4 00 ; y_fraction (overwritten) &41b5 00 ; y_room (overwritten) &41b6 00 ; velocity_x (overwritten) &41b7 00 ; velocity_y (overwritten) &41b8 00 ; flipped &41b9 f8 ; x_offset &41ba 04 ; y_offset # Antibodies have the following effects on imps: # # 0:SWIRL 1:SPIKES 2:STICKS 3:BLOB # 0:PIGGY destroy split bonus split # 1:HAIRY change reduce change destroy # 2:EVIL split bonus split bonus # 3:IMP reduce destroy reduce change ; check_fired_antibody_for_overlap_with_imps # Called with X = fired antibody to consider &41bb a0 0f LDY #&0f ; FIRST_IMP_SLOT ; check_fired_antibody_for_overlap_with_imps_loop &41bd 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &41c0 b0 45 BCS &4207 ; consider_next_imp &41c2 bd d7 5f LDA &5fd7,X ; objects_sprite &41c5 38 SEC &41c6 e9 17 SBC #&17 ; FIRST_ANTIBODY_SPRITE &41c8 4a LSR A &41c9 4a LSR A &41ca 85 12 STA &12 ; antibody_type &41cc 20 c8 40 JSR &40c8 ; burst_object &41cf b9 d7 5f LDA &5fd7,Y ; objects_sprite &41d2 c9 47 CMP #&47 ; FIRST_IMP_SPRITE # Did it hit an imp that has already been hit? &41d4 90 3f BCC &4215 ; destroy_lesser_imp # If so, destroy the imp &41d6 c9 5d CMP #&5d ; FIRE &41d8 f0 33 BEQ &420d ; destroy_fire &41da 38 SEC &41db e9 47 SBC #&47 ; FIRST_IMP_SPRITE &41dd 4a LSR A &41de 4a LSR A &41df 18 CLC &41e0 65 12 ADC &12 ; antibody_type &41e2 29 03 AND #&03 &41e4 f0 2f BEQ &4215 ; destroy_imp # If (IMP + ANTIBODY) % 4 == 0, destroy imp &41e6 18 CLC &41e7 65 12 ADC &12 ; antibody_type &41e9 29 03 AND #&03 &41eb f0 24 BEQ &4211 ; destroy_imp_with_bonus # If (IMP + 2 * ANTIBODY) % 4 == 0, destroy imp + bonus &41ed c9 01 CMP #&01 &41ef f0 32 BEQ &4223 ; change_imp_type # If (IMP + 2 * ANTIBODY) % 4 == 1, change imp type &41f1 c9 02 CMP #&02 &41f3 f0 42 BEQ &4237 ; split_imp_into_two # If (IMP + 2 * ANTIBODY) % 4 == 2, split imp into two &41f5 b9 d7 5f LDA &5fd7,Y ; objects_sprite # If (IMP + 2 * ANTIBODY) % 4 == 3, reduce to lesser imp &41f8 38 SEC &41f9 e9 20 SBC #&20 ; FIRST_IMP_SPRITE - FIRST_LESSER_IMP_SPRITE &41fb 99 d7 5f STA &5fd7,Y ; objects_sprite &41fe a9 00 LDA #&00 &4200 99 df 60 STA &60df,Y ; objects_flipped &4203 a9 0a LDA #&0a # Score 1000 points for reducing imp to lesser imp &4205 d0 17 BNE &421e ; increase_score_by_hundreds # Always branches ; consider_next_imp &4207 c8 INY &4208 c0 15 CPY #&15 ; LAST_IMP_SLOT + 1 &420a d0 b1 BNE &41bd ; check_fired_antibody_for_overlap_with_imps_loop &420c 60 RTS ; destroy_fire &420d a9 0a LDA #&0a # Score 1000 points for destroying fire &420f d0 06 BNE &4217 ; burst_and_score ; destroy_imp_with_bonus &4211 a9 19 LDA #&19 # Score 2500 points for destroying imp with bonus &4213 d0 02 BNE &4217 ; burst_and_score ; destroy_imp ; destroy_lesser_imp &4215 a9 05 LDA #&05 # Score 500 points for destroying imp or lesser imp ; burst_and_score &4217 48 PHA &4218 98 TYA &4219 aa TAX &421a 20 c8 40 JSR &40c8 ; burst_object &421d 68 PLA ; increase_score_by_hundreds &421e a2 04 LDX #&04 ; * 100 &4220 4c f3 4e JMP &4ef3 ; increase_score ; change_imp_type &4223 b9 d7 5f LDA &5fd7,Y ; objects_sprite &4226 c9 53 CMP #&53 ; IMP_FEET_FRONT &4228 f0 04 BEQ &422e ; use_piggy &422a 18 CLC &422b 69 04 ADC #&04 &422d 2c a9 47 BIT &47a9 ; use_piggy #422e LDA #&47 ; IMP_PIGGY_FRONT &4230 99 d7 5f STA &5fd7,Y ; objects_sprite &4233 a9 14 LDA #&14 # Score 2000 points for changing type of imp &4235 d0 e7 BNE &421e ; increase_score_by_hundreds # Always branches ; split_imp_into_two &4237 84 12 STY &12 ; imp_to_split &4239 a9 0f LDA #&0f # Score 1500 points for splitting imp in two &423b 20 1e 42 JSR &421e ; increase_score_by_hundreds &423e a4 12 LDY &12 ; imp_to_split &4240 a2 0f LDX #&0f ; FIRST_IMP_SLOT ; find_free_slot_loop &4242 bd d7 5f LDA &5fd7,X ; objects_sprite &4245 f0 0d BEQ &4254 ; found_slot # Is the slot empty? If so, use it &4247 a9 03 LDA #&03 &4249 20 8a 44 JSR &448a ; check_if_object_is_near_player &424c b0 06 BCS &4254 ; found_slot # Is the slot occupied by a distant imp? If so, use it &424e e8 INX &424f e0 15 CPX #&15 ; LAST_IMP_SLOT + 1 &4251 d0 ef BNE &4242 ; find_free_slot_loop &4253 60 RTS ; found_slot &4254 20 7b 42 JSR &427b ; copy_object_Y_into_object_X # Copy imp into new slot &4257 b9 2f 60 LDA &602f,Y ; objects_facing &425a 18 CLC &425b 69 01 ADC #&01 # Turn copy 90 degrees clockwise &425d 29 03 AND #&03 &425f 99 2f 60 STA &602f,Y ; objects_facing &4262 ee 90 02 INC &0290 ; screen_memory # Bug: unnecessary write to screen memory &4265 a9 1f LDA #&1f # Force copy to keep moving &4267 99 71 60 STA &6071,Y ; objects_speed_change_cooldown &426a bd 2f 60 LDA &602f,X ; objects_facing &426d 38 SEC &426e e9 01 SBC #&01 # Turn original 90 degrees anti-clockwise &4270 29 03 AND #&03 &4272 9d 2f 60 STA &602f,X ; objects_facing &4275 a9 1f LDA #&1f # Force original to keep moving &4277 9d 71 60 STA &6071,X ; objects_speed_change_cooldown &427a 60 RTS ; copy_object_Y_into_object_X &427b 84 12 STY &12 ; source_object &427d 86 13 STX &13 ; target_object &427f a9 05 LDA #&05 &4281 85 14 STA &14 ; count ; copy_object_loop # Loops over all object variables &4283 b9 d7 5f LDA &5fd7,Y ; objects_sprite &4286 9d d7 5f STA &5fd7,X ; objects_sprite &4289 b9 45 60 LDA &6045,Y ; objects_data &428c 9d 45 60 STA &6045,X ; objects_data &428f b9 b3 60 LDA &60b3,Y ; objects_speed_x &4292 9d b3 60 STA &60b3,X ; objects_speed_x &4295 8a TXA &4296 18 CLC &4297 69 16 ADC #&16 &4299 aa TAX &429a 98 TYA &429b 18 CLC &429c 69 16 ADC #&16 &429e a8 TAY &429f c6 14 DEC &14 ; count &42a1 d0 e0 BNE &4283 ; copy_object_loop &42a3 a4 12 LDY &12 ; source_object &42a5 a6 13 LDX &13 ; target_object &42a7 60 RTS ; check_for_overlap_between_objects_X_and_Y # Leaves with carry clear if overlap &42a8 bd d7 5f LDA &5fd7,X ; objects_sprite &42ab f0 77 BEQ &4324 ; leave_with_carry_set &42ad c9 07 CMP #&07 ; BURSTING &42af f0 73 BEQ &4324 ; leave_with_carry_set &42b1 b9 d7 5f LDA &5fd7,Y ; objects_sprite &42b4 f0 6e BEQ &4324 ; leave_with_carry_set &42b6 c9 07 CMP #&07 ; BURSTING &42b8 f0 6a BEQ &4324 ; leave_with_carry_set &42ba b9 5b 60 LDA &605b,Y ; objects_size &42bd 18 CLC &42be 7d 5b 60 ADC &605b,X ; objects_size &42c1 85 4e STA &4e ; size_of_objects &42c3 bd ed 5f LDA &5fed,X ; objects_x_fraction &42c6 38 SEC &42c7 f9 ed 5f SBC &5fed,Y ; objects_x_fraction &42ca 85 4f STA &4f ; distance_between_objects_fraction &42cc bd 03 60 LDA &6003,X ; objects_x_room &42cf f9 03 60 SBC &6003,Y ; objects_x_room &42d2 85 50 STA &50 ; distance_between_objects_rooms &42d4 b0 13 BCS &42e9 ; skip_inversion_x &42d6 a5 50 LDA &50 ; distance_between_objects_rooms &42d8 49 ff EOR #&ff &42da 48 PHA &42db a5 4f LDA &4f ; distance_between_objects_fraction &42dd 49 ff EOR #&ff &42df 18 CLC &42e0 69 01 ADC #&01 &42e2 85 4f STA &4f ; distance_between_objects_fraction &42e4 68 PLA &42e5 69 00 ADC #&00 &42e7 85 50 STA &50 ; distance_between_objects_rooms ; skip_inversion_x &42e9 a5 4f LDA &4f ; distance_between_objects_fraction &42eb 38 SEC &42ec e5 4e SBC &4e ; size_of_objects &42ee a5 50 LDA &50 ; distance_between_objects_rooms &42f0 e9 00 SBC #&00 &42f2 b0 30 BCS &4324 ; leave_with_carry_set &42f4 bd 87 60 LDA &6087,X ; objects_y_fraction &42f7 38 SEC &42f8 f9 87 60 SBC &6087,Y ; objects_y_fraction &42fb 85 4f STA &4f ; distance_between_objects_fraction &42fd bd 9d 60 LDA &609d,X ; objects_y_room &4300 f9 9d 60 SBC &609d,Y ; objects_y_room &4303 85 50 STA &50 ; distance_between_objects_rooms &4305 b0 13 BCS &431a ; skip_inversion &4307 a5 50 LDA &50 ; distance_between_objects_rooms &4309 49 ff EOR #&ff &430b 48 PHA &430c a5 4f LDA &4f ; distance_between_objects_fraction &430e 49 ff EOR #&ff &4310 18 CLC &4311 69 01 ADC #&01 &4313 85 4f STA &4f ; distance_between_objects_fraction &4315 68 PLA &4316 69 00 ADC #&00 &4318 85 50 STA &50 ; distance_between_objects_rooms ; skip_inversion_y &431a a5 4f LDA &4f ; distance_between_objects_fraction &431c 38 SEC &431d e5 4e SBC &4e ; size_of_objects &431f a5 50 LDA &50 ; distance_between_objects_rooms &4321 e9 00 SBC #&00 &4323 60 RTS ; leave_with_carry_set &4324 38 SEC &4325 60 RTS ; to_update_bursting_object &4326 4c d8 40 JMP &40d8 ; update_bursting_object ; update_demon &4329 bd d7 5f LDA &5fd7,X ; objects_sprite &432c f0 3a BEQ &4368 ; leave &432e c9 07 CMP #&07 ; BURSTING &4330 f0 f4 BEQ &4326 ; to_update_bursting_object &4332 20 f3 40 JSR &40f3 ; change_object_velocity &4335 20 7c 50 JSR &507c ; move_object &4338 bd d7 5f LDA &5fd7,X ; objects_sprite &433b 38 SEC &433c e9 37 SBC #&37 ; FIRST_DEMON_SPRITE &433e 29 0c AND #&0c &4340 bc 2f 60 LDY &602f,X ; objects_facing &4343 18 CLC &4344 79 50 43 ADC &4350,Y ; demon_sprites_by_direction &4347 9d d7 5f STA &5fd7,X ; objects_sprite &434a 20 1a 52 JSR &521a ; check_for_collision_between_player_and_enemy &434d 4c 54 43 JMP &4354 ; animate_object_with_two_frames ; demon_sprites_by_direction &4350 39 37 37 39 ; animate_object_with_two_frames &4354 a9 01 LDA #&01 &4356 d0 02 BNE &435a ; set_number_of_frames # Always branches ; animate_object_with_four_frames &4358 a9 03 LDA #&03 ; set_number_of_frames &435a 85 12 STA &12 ; number_of_frames &435c a6 17 LDX &17 ; object_to_consider &435e bc 19 60 LDY &6019,X ; objects_animation &4361 c8 INY &4362 98 TYA &4363 25 12 AND &12 ; number_of_frames &4365 9d 19 60 STA &6019,X ; objects_animation ; leave &4368 60 RTS ; initialise_demons &4369 a2 03 LDX #&03 ; initialise_demons_loop &436b 86 20 STX &20 ; demon_to_consider ; choose_random_room &436d 20 eb 5e JSR &5eeb ; rnd &4370 29 1f AND #&1f &4372 aa TAX &4373 20 eb 5e JSR &5eeb ; rnd &4376 29 1f AND #&1f &4378 a8 TAY &4379 20 c4 4a JSR &4ac4 ; get_room_data_byte # Stores X and Y in room_x and room_y &437c f0 04 BEQ &4382 ; found_room &437e c9 03 CMP #&03 # Don't put demons outside or beyond walls &4380 90 eb BCC &436d ; choose_random_room ; found_room &4382 a2 a6 LDX #&a6 &4384 a0 43 LDY #&43 ; &43a6 = demon_template &4386 a5 20 LDA &20 ; demon_to_consider &4388 18 CLC &4389 69 0b ADC #&0b &438b 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y &438e a5 20 LDA &20 ; demon_to_consider &4390 aa TAX &4391 0a ASL A &4392 0a ASL A &4393 69 37 ADC #&37 ; FIRST_DEMON_SPRITE &4395 9d e2 5f STA &5fe2,X ; objects_sprite + &b &4398 a5 21 LDA &21 ; room_x &439a 9d 0e 60 STA &600e,X ; objects_x_room + &b &439d a5 22 LDA &22 ; room_y &439f 9d a8 60 STA &60a8,X ; objects_y_room + &b &43a2 ca DEX &43a3 10 c6 BPL &436b ; initialise_demons_loop &43a5 60 RTS ; demon_template &43a6 00 ; sprite (overwritten) &43a7 80 ; x_fraction &43a8 00 ; x_room (overwritten) &43a9 00 ; animation &43aa 00 ; facing &43ab 04 ; data &43ac 10 ; size &43ad 00 ; objects_speed_change_cooldown &43ae 80 ; y_fraction &43af 00 ; y_room (overwritten) &43b0 00 ; velocity_x &43b1 00 ; velocity_y &43b2 00 ; flipped &43b3 f4 ; x_offset &43b4 04 ; y_offset ; to_burst_object &43b5 4c c8 40 JMP &40c8 ; burst_object ; update_fire &43b8 20 db 43 JSR &43db ; move_enemy_towards_player # FIRE homes in on player &43bb 20 7c 50 JSR &507c ; move_object &43be bd df 60 LDA &60df,X ; objects_flipped # FIRE is animated by flipping sprite each frame &43c1 49 ff EOR #&ff &43c3 9d df 60 STA &60df,X ; objects_flipped &43c6 bd b3 60 LDA &60b3,X ; objects_speed_x &43c9 f0 ea BEQ &43b5 ; to_burst_object &43cb 20 1a 52 JSR &521a ; check_for_collision_between_player_and_enemy &43ce b0 0a BCS &43da ; leave &43d0 20 c8 40 JSR &40c8 ; burst_object # Burst FIRE on collision with player &43d3 a9 01 LDA #&01 # Score 1000 points for colliding with FIRE &43d5 a2 03 LDX #&03 ; * 1000 &43d7 4c f3 4e JMP &4ef3 ; increase_score ; leave &43da 60 RTS ; move_enemy_towards_player &43db a0 08 LDY #&08 # +8 if object x >= player x &43dd ad ed 5f LDA &5fed ; objects_x_fraction &43e0 38 SEC &43e1 fd ed 5f SBC &5fed,X ; objects_x_fraction &43e4 ad 03 60 LDA &6003 ; objects_x_room &43e7 fd 03 60 SBC &6003,X ; objects_x_room &43ea b0 02 BCS &43ee ; greater_or_equal_x_than_player &43ec a0 04 LDY #&04 # +4 if object x < player x ; greater_or_equal_x_than_player &43ee 84 12 STY &12 ; tmp &43f0 a0 01 LDY #&01 # +1 if object y >= player y &43f2 ad 87 60 LDA &6087 ; objects_y_fraction &43f5 38 SEC &43f6 fd 87 60 SBC &6087,X ; objects_y_fraction &43f9 ad 9d 60 LDA &609d ; objects_y_room &43fc fd 9d 60 SBC &609d,X ; objects_y_room &43ff b0 02 BCS &4403 ; greater_or_equal_y_than_player &4401 a0 02 LDY #&02 # +2 if object y < player_y ; greater_or_equal_y_than_player &4403 98 TYA &4404 18 CLC &4405 65 12 ADC &12 ; tmp &4407 a8 TAY &4408 b9 17 44 LDA &4417,Y ; facing_table &440b 9d 2f 60 STA &602f,X ; objects_facing &440e a9 02 LDA #&02 &4410 9d b3 60 STA &60b3,X ; objects_speed_x &4413 9d c9 60 STA &60c9,X ; objects_speed_y &4416 60 RTS ; facing_table ; 0 1 2 3 4 *5 *6 7 8 *9 *a # Only *ed values are used &4417 00 00 02 00 03 04 07 00 01 05 06 ; summon_fire &4422 a5 1a LDA &1a ; game_timer &4424 d0 63 BNE &4489 ; leave # Only summon fire every 256 frames &4426 a5 5a LDA &5a ; fire_object &4428 d0 5f BNE &4489 ; leave # Leave if FIRE already summoned &442a a2 0f LDX #&0f ; FIRST_IMP_SLOT &442c a9 02 LDA #&02 # Find imps that are off screen ; find_free_slot_loop &442e 20 8a 44 JSR &448a ; check_if_object_is_near_player # Sets A to be distance of imp, carry set if distant &4431 b0 09 BCS &443c ; found_slot # Is the slot occupied by a distant imp? If so, use it &4433 e8 INX &4434 e0 15 CPX #&15 ; LAST_IMP_SLOT + 1 &4436 d0 f4 BNE &442c ; find_free_slot_loop &4438 a2 0f LDX #&0f ; FIRST_IMP_SLOT # Otherwise, turn the first imp into FIRE &443a d0 32 BNE &446e ; put_fire_in_slot ; found_slot &443c 20 eb 5e JSR &5eeb ; rnd &443f 29 7f AND #&7f &4441 18 CLC &4442 69 40 ADC #&40 &4444 9d ed 5f STA &5fed,X ; objects_x_fraction # Put FIRE in random position in player's room &4447 ad 03 60 LDA &6003 ; objects_x_room &444a 9d 03 60 STA &6003,X ; objects_x_room &444d 20 eb 5e JSR &5eeb ; rnd &4450 29 7f AND #&7f &4452 18 CLC &4453 69 40 ADC #&40 &4455 9d 87 60 STA &6087,X ; objects_y_fraction &4458 ad 9d 60 LDA &609d ; objects_y_room &445b 9d 9d 60 STA &609d,X ; objects_y_room &445e a9 f4 LDA #&f4 &4460 9d f5 60 STA &60f5,X ; objects_x_offset &4463 a0 00 LDY #&00 ; PLAYER_SLOT # Does the newly summoned FIRE overlap the player? &4465 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &4468 b0 04 BCS &446e ; put_fire_in_slot &446a a9 07 LDA #&07 ; BURSTING # If so, burst it immediately, so no damage &446c d0 02 BNE &4470 ; put_object_in_slot # Always branches ; put_fire_in_slot &446e a9 5d LDA #&5d ; FIRE ; put_object_in_slot &4470 9d d7 5f STA &5fd7,X ; objects_sprite &4473 a9 f4 LDA #&f4 &4475 9d f5 60 STA &60f5,X ; objects_x_offset &4478 a9 00 LDA #&00 &447a 9d 19 60 STA &6019,X ; objects_animation &447d a9 04 LDA #&04 &447f 9d 0b 61 STA &610b,X ; objects_y_offset &4482 a9 10 LDA #&10 &4484 9d 5b 60 STA &605b,X ; objects_size &4487 86 5a STX &5a ; fire_object ; leave &4489 60 RTS ; check_if_object_is_near_player # Returns carry clear if object within range &448a 85 12 STA &12 ; maximum_distance &448c ad 03 60 LDA &6003 ; objects_x_room &448f 38 SEC &4490 fd 03 60 SBC &6003,X ; objects_x_room &4493 10 07 BPL &449c ; skip_x_inversion &4495 85 13 STA &13 ; distance &4497 a9 00 LDA #&00 &4499 38 SEC &449a e5 13 SBC &13 ; distance ; skip_x_inversion &449c c5 12 CMP &12 ; maximum_distance &449e b0 12 BCS &44b2 ; leave &44a0 ad 9d 60 LDA &609d ; objects_y_room &44a3 38 SEC &44a4 fd 9d 60 SBC &609d,X ; objects_y_room &44a7 10 07 BPL &44b0 ; skip_y_inversion &44a9 85 13 STA &13 ; distance &44ab a9 00 LDA #&00 &44ad 38 SEC &44ae e5 13 SBC &13 ; distance ; skip_y_inversion &44b0 c5 12 CMP &12 ; maximum_distance ; leave &44b2 60 RTS ; to_update_fire &44b3 4c b8 43 JMP &43b8 ; update_fire ; update_imp &44b6 bd d7 5f LDA &5fd7,X ; objects_sprite &44b9 f0 60 BEQ &451b ; leave # Is there an imp in this slot? &44bb c9 07 CMP #&07 ; BURSTING &44bd f0 48 BEQ &4507 ; to_update_bursting_object &44bf c9 57 CMP #&57 ; UNBURSTING &44c1 f0 47 BEQ &450a ; to_update_unbursting_imp &44c3 e4 5a CPX &5a ; fire_object &44c5 f0 ec BEQ &44b3 ; to_update_fire &44c7 a9 03 LDA #&03 &44c9 20 8a 44 JSR &448a ; check_if_object_is_near_player &44cc b0 27 BCS &44f5 ; remove_imp # Remove imp if too distant &44ce 20 1a 52 JSR &521a ; check_for_collision_between_player_and_enemy &44d1 90 28 BCC &44fb ; burst_imp # Burst imp if touching player &44d3 20 f3 40 JSR &40f3 ; change_object_velocity &44d6 20 7c 50 JSR &507c ; move_object &44d9 bd d7 5f LDA &5fd7,X ; objects_sprite &44dc c9 47 CMP #&47 ; FIRST_IMP_SPRITE &44de 90 12 BCC &44f2 ; is_lesser_imp &44e0 38 SEC # If this is a full imp, sprite depends on direction &44e1 e9 47 SBC #&47 ; FIRST_IMP_SPRITE &44e3 29 0c AND #&0c &44e5 bc 2f 60 LDY &602f,X ; objects_facing &44e8 18 CLC &44e9 79 03 45 ADC &4503,Y ; imp_sprites_by_direction &44ec 9d d7 5f STA &5fd7,X ; objects_sprite &44ef 4c 54 43 JMP &4354 ; animate_object_with_two_frames ; is_lesser_imp &44f2 4c 54 43 JMP &4354 ; animate_object_with_two_frames # Lesser imps are animated regardless ; remove_imp &44f5 a9 00 LDA #&00 &44f7 9d d7 5f STA &5fd7,X ; objects_sprite &44fa 60 RTS ; burst_imp &44fb 20 c8 40 JSR &40c8 ; burst_object &44fe a9 19 LDA #&19 &4500 4c 1e 42 JMP &421e ; increase_score_X4 ; imp_sprites_by_direction &4503 49 47 47 49 ; to_update_bursting_object &4507 4c d8 40 JMP &40d8 ; update_bursting_object ; to_update_unbursting_imp &450a 4c b7 45 JMP &45b7 ; update_unbursting_imp ; initialise_imps &450d a0 0f LDY #&0f ; FIRST_IMP_SLOT &450f a9 00 LDA #&00 # No FIRE present &4511 85 5a STA &5a ; fire_object ; initialise_imps_loop &4513 99 d7 5f STA &5fd7,Y ; objects_sprite # No imps present &4516 c8 INY &4517 c0 15 CPY #&15 ; LAST_IMP_SLOT + 1 &4519 d0 f8 BNE &4513 ; initialise_imps_loop ; leave &451b 60 RTS ; summon_imp &451c a5 23 LDA &23 ; player_height &451e c9 92 CMP #&92 &4520 d0 14 BNE &4536 ; leave # Is the player fully present? If not, leave &4522 a5 1a LDA &1a ; game_timer &4524 29 03 AND #&03 &4526 c9 03 CMP #&03 &4528 d0 0c BNE &4536 ; leave # Only summon imps every four frames &452a a2 0f LDX #&0f ; FIRST_IMP_SLOT ; find_free_slot &452c bd d7 5f LDA &5fd7,X ; objects_sprite &452f f0 06 BEQ &4537 ; found_slot &4531 e8 INX &4532 e0 15 CPX #&15 ; LAST_IMP_SLOT + 1 &4534 d0 f6 BNE &452c ; find_free_slot ; leave &4536 60 RTS ; found_slot &4537 86 20 STX &20 ; imp_slot &4539 8a TXA &453a a2 a8 LDX #&a8 &453c a0 45 LDY #&45 ; &45a8 = imp_template &453e 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y &4541 ae 03 60 LDX &6003 ; objects_x_room # Put the imp in a nearby room at random &4544 ac 9d 60 LDY &609d ; objects_y_room &4547 20 eb 5e JSR &5eeb ; rnd &454a c9 40 CMP #&40 # 1 in 4 chance to use each of x - 1 and x + 1 &454c 90 06 BCC &4554 ; use_player_room_x_plus_one &454e c9 c0 CMP #&c0 # 1 in 2 chance to use x &4550 90 03 BCC &4555 ; use_player_room_x ; use_player_room_x_minus_one &4552 ca DEX &4553 ca DEX ; use_player_room_x_plus_one &4554 e8 INX ; use_player_room_x &4555 20 eb 5e JSR &5eeb ; rnd &4558 c9 40 CMP #&40 # 1 in 4 chance to use each of y - 1 and y + 1 &455a 90 06 BCC &4562 ; use_player_room_y_plus_one &455c c9 c0 CMP #&c0 # 1 in 2 chance to use y &455e 90 03 BCC &4563 ; use_player_room_y ; use_player_room_y_minus_one # i.e. &4560 88 DEY # 1 2 1 &4561 88 DEY # 2 4 2 ; use_player_room_y_plus_one # 1 2 1 chance in 16, where player is in centre &4562 c8 INY ; use_player_room_y &4563 8a TXA &4564 48 PHA &4565 98 TYA &4566 48 PHA &4567 20 c4 4a JSR &4ac4 ; get_room_data_byte &456a 85 12 STA &12 ; room_byte &456c 68 PLA &456d a8 TAY &456e 68 PLA &456f aa TAX &4570 a5 12 LDA &12 ; room_byte &4572 f0 04 BEQ &4578 ; room_ok # Can put imps outside, &4574 c9 03 CMP #&03 &4576 90 be BCC &4536 ; leave # but not beyond walls ; room_ok &4578 8a TXA &4579 a6 20 LDX &20 ; imp_slot &457b 9d 03 60 STA &6003,X ; objects_x_room &457e 98 TYA &457f 9d 9d 60 STA &609d,X ; objects_y_room &4582 20 eb 5e JSR &5eeb ; rnd # Put the imp in a random position, &20 <= imp < &e0 &4585 c9 c0 CMP #&c0 &4587 90 03 BCC &458c ; skip_overflow_x &4589 38 SEC &458a e9 40 SBC #&40 ; skip_overflow_x &458c 18 CLC &458d 69 20 ADC #&20 &458f 9d ed 5f STA &5fed,X ; objects_x_fraction &4592 20 eb 5e JSR &5eeb ; rnd &4595 c9 c0 CMP #&c0 &4597 90 03 BCC &459c ; skip_overflow_y &4599 38 SEC &459a e9 40 SBC #&40 ; skip_overflow_y &459c 18 CLC &459d 69 20 ADC #&20 &459f 9d 87 60 STA &6087,X ; objects_y_fraction &45a2 a9 57 LDA #&57 ; UNBURSTING &45a4 9d d7 5f STA &5fd7,X ; objects_sprite &45a7 60 RTS ; imp_template &45a8 00 ; sprite (overwritten) &45a9 00 ; x_fraction (overwritten) &45aa 00 ; x_room (overwritten) &45ab 03 ; animation &45ac 00 ; facing &45ad 06 ; data &45ae 10 ; size &45af 00 ; objects_speed_change_cooldown &45b0 00 ; y_fraction (overwritten) &45b1 00 ; y_room (overwritten) &45b2 00 ; velocity_x &45b3 00 ; velocity_y &45b4 00 ; flipped &45b5 f4 ; x_offset &45b6 04 ; y_offset ; update_unbursting_imp &45b7 de 19 60 DEC &6019,X ; objects_animation &45ba 10 1b BPL &45d7 ; leave # Has the imp finished unbursting? &45bc fe 19 60 INC &6019,X ; objects_animation &45bf a0 27 LDY #&27 ; FIRST_LESSER_IMP_SPRITE &45c1 20 eb 5e JSR &5eeb ; rnd &45c4 30 02 BMI &45c8 ; use_sprite # 1 in 2 chance to become a lesser imp &45c6 a0 47 LDY #&47 ; FIRST_IMP_SPRITE # 1 in 2 chance to become a full imp ; use_sprite &45c8 84 12 STY &12 ; base &45ca 20 d8 45 JSR &45d8 ; find_nearest_demon # The type of imp depends on which demon is nearest &45cd 0a ASL A &45ce 0a ASL A &45cf 65 12 ADC &12 ; base &45d1 9d d7 5f STA &5fd7,X ; objects_sprite &45d4 4c fd 40 JMP &40fd ; randomise_object_velocity ; leave &45d7 60 RTS ; find_nearest_demon &45d8 a0 0b LDY #&0b ; FIRST_DEMON_SLOT &45da a9 ff LDA #&ff &45dc 8d e7 45 STA &45e7 ; distance_to_nearest_demon &45df a9 0b LDA #&0b ; FIRST_DEMON_SLOT &45e1 85 13 STA &13 ; demon_to_consider ; find_nearest_demon_loop &45e3 20 fc 45 JSR &45fc ; find_distance_to_demon &45e6 c9 ff CMP #&ff # actually CMP distance_to_nearest_demon &45e8 b0 05 BCS &45ef ; demon_is_further_away &45ea 8d e7 45 STA &45e7 ; distance_to_nearest_demon &45ed 84 13 STY &13 ; demon_to_consider ; demon_is_further_away &45ef c8 INY &45f0 c0 0f CPY #&0f ; LAST_DEMON_SLOT + 1 &45f2 d0 ef BNE &45e3 ; find_nearest_demon_loop &45f4 a5 13 LDA &13 ; demon_to_consider &45f6 38 SEC &45f7 e9 0b SBC #&0b ; FIRST_DEMON_SLOT &45f9 49 03 EOR #&03 &45fb 60 RTS ; find_distance_to_demon # Called with X = imp, Y = demon_to_consider &45fc bd 03 60 LDA &6003,X ; objects_x_room &45ff 38 SEC &4600 f9 03 60 SBC &6003,Y ; objects_x_room &4603 10 07 BPL &460c ; skip_inversion_x &4605 85 14 STA &14 ; tmp &4607 a9 00 LDA #&00 &4609 38 SEC &460a e5 14 SBC &14 ; tmp ; skip_inversion_x &460c 85 15 STA &15 ; distance &460e bd 9d 60 LDA &609d,X ; objects_y_room &4611 38 SEC &4612 f9 9d 60 SBC &609d,Y ; objects_y_room &4615 10 07 BPL &461e ; skip_inversion_y &4617 85 14 STA &14 ; tmp &4619 a9 00 LDA #&00 &461b 38 SEC &461c e5 14 SBC &14 ; tmp ; skip_inversion_y &461e 18 CLC &461f 65 15 ADC &15 ; distance &4621 60 RTS ; bursting_pitches &4622 38 3a 3c 3e ; update_screen &4626 a9 00 LDA #&00 # Start with &00 &4628 48 PHA &4629 a2 0c LDX #&0c # No more than twelve walls can fit on screen &462b 86 45 STX &45 ; walls_to_plot ; reset_walls_sections_plotted_loop &462d 9d 08 4d STA &4d08,X ; wall_sections_plotted - 1 &4630 ca DEX &4631 d0 fa BNE &462d ; reset_walls_sections_plotted_loop &4633 ae 03 60 LDX &6003 ; objects_x_room &4636 ac 9d 60 LDY &609d ; objects_y_room &4639 ca DEX &463a c8 INY &463b 20 c4 4a JSR &4ac4 ; get_room_data_byte &463e f0 04 BEQ &4644 ; skip_room_x_minus_y_plus &4640 68 PLA &4641 09 01 ORA #&01 # + &01 if room (x - 1, y + 1) has walls &4643 48 PHA ; skip_room_x_minus_y_plus &4644 ae 03 60 LDX &6003 ; objects_x_room &4647 ac 9d 60 LDY &609d ; objects_y_room &464a ca DEX &464b 20 c4 4a JSR &4ac4 ; get_room_data_byte &464e f0 04 BEQ &4654 ; skip_room_x_minus &4650 68 PLA &4651 09 02 ORA #&02 # + &02 if room (x - 1, y) has walls &4653 48 PHA ; skip_room_x_minus &4654 ae 03 60 LDX &6003 ; objects_x_room &4657 ac 9d 60 LDY &609d ; objects_y_room &465a c8 INY &465b 20 c4 4a JSR &4ac4 ; get_room_data_byte &465e f0 04 BEQ &4664 ; skip_room_y_plus &4660 68 PLA &4661 09 04 ORA #&04 # + &04 if room (x, y + 1) has walls &4663 48 PHA ; skip_room_y_plus &4664 ae 03 60 LDX &6003 ; objects_x_room &4667 ac 9d 60 LDY &609d ; objects_y_room &466a ca DEX &466b 88 DEY &466c 20 c4 4a JSR &4ac4 ; get_room_data_byte &466f f0 04 BEQ &4675 ; skip_room_x_minus_y_minus &4671 68 PLA &4672 09 08 ORA #&08 # + &08 if room (x - 1, y - 1) has walls &4674 48 PHA &4675 ae 03 60 LDX &6003 ; objects_x_room &4678 ac 9d 60 LDY &609d ; objects_y_room &467b e8 INX &467c c8 INY &467d 20 c4 4a JSR &4ac4 ; get_room_data_byte &4680 f0 04 BEQ &4686 ; skip_room_x_plus_y_plus &4682 68 PLA &4683 09 10 ORA #&10 # + &10 if room (x + 1, y + 1) has walls &4685 48 PHA ; skip_room_x_plus_y_plus # Final results is rooms beyond player with walls: &4686 68 PLA # &4687 85 13 STA &13 ; rooms_with_walls # x- y+ 2 1 4 &4689 0a ASL A # \ / \ / &468a 0a ASL A # x 8 x 10 &468b 65 13 ADC &13 ; rooms_with_walls # / \ &468d a8 TAY # y- x+ &468e a2 05 LDX #&05 ; plot_rooms_beyond_player_loop # Five bytes of plotting order &4690 ad 03 60 LDA &6003 ; objects_x_room &4693 85 26 STA &26 ; wall_x_room &4695 ad 9d 60 LDA &609d ; objects_y_room &4698 85 27 STA &27 ; wall_y_room &469a b9 b9 65 LDA &65b9,Y ; beyond_player_plotting_order_table # Top six bits determine which rooms to consider: &469d 29 20 AND #&20 # If &20 set, use x &469f d0 0d BNE &46ae ; use_x &46a1 b9 b9 65 LDA &65b9,Y ; beyond_player_plotting_order_table &46a4 29 10 AND #&10 # If &10 set, use x + 1, otherwise use x - 1 &46a6 f0 04 BEQ &46ac ; use_x_minus ; use_x_plus &46a8 e6 26 INC &26 ; wall_x_room &46aa e6 26 INC &26 ; wall_x_room ; use_x_minus &46ac c6 26 DEC &26 ; wall_x_room ; use_x &46ae b9 b9 65 LDA &65b9,Y ; beyond_player_plotting_order_table &46b1 29 80 AND #&80 # If &80 set, use y &46b3 d0 0d BNE &46c2 ; use_y &46b5 b9 b9 65 LDA &65b9,Y ; beyond_player_plotting_order_table &46b8 29 40 AND #&40 # If &40 set, use y + 1, otherwise use y - 1 &46ba f0 04 BEQ &46c0 ; use_y_minus ; use_y_plus &46bc e6 27 INC &27 ; wall_y_room &46be e6 27 INC &27 ; wall_y_room ; use_y_minus &46c0 c6 27 DEC &27 ; wall_y_room ; use_y &46c2 8a TXA &46c3 48 PHA &46c4 98 TYA &46c5 48 PHA &46c6 b9 b9 65 LDA &65b9,Y ; beyond_player_plotting_order_table &46c9 a6 26 LDX &26 ; wall_x_room &46cb a4 27 LDY &27 ; wall_y_room &46cd 29 03 AND #&03 # Bottom two bits determine what to plot: &46cf f0 0e BEQ &46df ; plot_objects_for_room_beyond_player # &00: objects &46d1 c9 01 CMP #&01 &46d3 f0 10 BEQ &46e5 ; plot_walls_for_room_beyond_player # &01: wall &46d5 c9 03 CMP #&03 &46d7 f0 0f BEQ &46e8 ; finished_plotting_room_beyond_player # &03: nothing (unused) &46d9 20 0c 48 JSR &480c ; plot_boundaries # &02: boundary (unused) &46dc 4c e8 46 JMP &46e8 ; finished_plotting_room_beyond_player ; plot_objects_for_room_beyond_player &46df 20 20 47 JSR &4720 ; plot_objects &46e2 4c e8 46 JMP &46e8 ; finished_plotting_room_beyond_player ; plot_walls_for_room_beyond_player &46e5 20 f1 4a JSR &4af1 ; plot_walls ; finished_plotting_room_beyond_player &46e8 68 PLA &46e9 a8 TAY &46ea 68 PLA &46eb aa TAX &46ec c8 INY &46ed ca DEX &46ee d0 a0 BNE &4690 ; plot_rooms_beyond_player_loop ; plot_rooms_nearer_than_player &46f0 ae 03 60 LDX &6003 ; objects_x_room &46f3 ac 9d 60 LDY &609d ; objects_y_room # room (x, y) &46f6 20 15 47 JSR &4715 ; plot_boundaries_and_objects_in_room &46f9 ae 03 60 LDX &6003 ; objects_x_room &46fc ac 9d 60 LDY &609d ; objects_y_room &46ff 88 DEY # room (x, y - 1) &4700 20 15 47 JSR &4715 ; plot_boundaries_and_objects_in_room &4703 ae 03 60 LDX &6003 ; objects_x_room &4706 ac 9d 60 LDY &609d ; objects_y_room &4709 e8 INX # room (x + 1, y) &470a 20 15 47 JSR &4715 ; plot_boundaries_and_objects_in_room &470d ae 03 60 LDX &6003 ; objects_x_room &4710 ac 9d 60 LDY &609d ; objects_y_room &4713 e8 INX &4714 88 DEY # room (x + 1, y - 1) ; plot_boundaries_and_objects_in_room &4715 86 10 STX &10 ; tmp_x &4717 84 11 STY &11 ; tmp_y &4719 20 0c 48 JSR &480c ; plot_boundaries &471c a6 10 LDX &10 ; tmp_x &471e a4 11 LDY &11 ; tmp_y ; plot_objects &4720 20 e4 47 JSR &47e4 ; prepare_list_of_objects_in_room &4723 4c 2a 47 JMP &472a ; plot_objects_in_order_of_depth ; to_plot_object_from_list &4726 4c a4 47 JMP &47a4 ; plot_object_from_list ; leave &4729 60 RTS ; plot_objects_in_order_of_depth &472a a0 00 LDY #&00 # Starting at the beginning of the list, ; find_unplotted_object # find an object that has not yet been plotted &472c b9 8e 00 LDA &008e,Y ; list_of_objects_to_plot &472f c8 INY &4730 c9 ff CMP #&ff # Is this the end of the list? If so, leave &4732 f0 f5 BEQ &4729 ; leave &4734 c9 40 CMP #&40 # Has the object already been plotted? &4736 f0 f4 BEQ &472c ; find_unplotted_object &4738 84 38 STY &38 ; first_object_for_comparison &473a aa TAX ; find_another_unplotted_object # Find a second unplotted object for comparison &473b b9 8e 00 LDA &008e,Y ; list_of_objects_to_plot &473e c8 INY &473f c9 ff CMP #&ff # Is this the end of the list? If so, plot object &4741 f0 e3 BEQ &4726 ; to_plot_object_from_list &4743 c9 40 CMP #&40 # Has this object already been plotted? &4745 f0 f4 BEQ &473b ; find_another_unplotted_object &4747 84 39 STY &39 ; second_object_for_comparison &4749 a8 TAY &474a bd 5b 60 LDA &605b,X ; objects_size &474d 4a LSR A &474e 85 63 STA &63 ; half_first_object_size &4750 b9 5b 60 LDA &605b,Y ; objects_size &4753 4a LSR A &4754 85 64 STA &64 ; half_second_object_size &4756 bd 87 60 LDA &6087,X ; objects_y_fraction &4759 4a LSR A &475a 18 CLC &475b 69 40 ADC #&40 &475d 38 SEC &475e e5 63 SBC &63 ; half_first_object_size &4760 85 3d STA &3d ; first_y &4762 b9 87 60 LDA &6087,Y ; objects_y_fraction &4765 4a LSR A &4766 18 CLC &4767 69 40 ADC #&40 &4769 38 SEC &476a e5 64 SBC &64 ; half_second_object_size &476c c5 3d CMP &3d ; first_y &476e f0 0d BEQ &477d ; compare_objects_x &4770 90 06 BCC &4778 ; to_find_another_unplotted_object ; use_second_object &4772 a5 39 LDA &39 ; second_object_for_comparison &4774 85 38 STA &38 ; first_object_for_comparison &4776 98 TYA &4777 aa TAX ; to_find_another_unplotted_object &4778 a4 39 LDY &39 ; second_object_for_comparison &477a 4c 3b 47 JMP &473b ; find_another_unplotted_object ; compare_objects_x &477d bd ed 5f LDA &5fed,X ; objects_x_fraction &4780 4a LSR A &4781 18 CLC &4782 69 40 ADC #&40 &4784 18 CLC &4785 65 63 ADC &63 ; half_first_object_size &4787 85 3b STA &3b ; first_x &4789 b9 ed 5f LDA &5fed,Y ; objects_x_fraction &478c 4a LSR A &478d 18 CLC &478e 69 40 ADC #&40 &4790 18 CLC &4791 65 64 ADC &64 ; half_second_object_size &4793 c5 3b CMP &3b ; first_x &4795 b0 e1 BCS &4778 ; to_find_another_unplotted_object # First object is further, so keep comparing that &4797 90 d9 BCC &4772 ; use_second_object # Second object is further, so use that instead ; unused &4799 bd ed 5f LDA &5fed,X ; objects_x_fraction # Unused code &479c 4a LSR A &479d 18 CLC &479e 69 40 ADC #&40 &47a0 65 63 ADC &63 ; half_first_object_size &47a2 85 3b STA &3b ; first_x ; plot_object_from_list &47a4 a4 38 LDY &38 ; first_object_for_comparison &47a6 88 DEY &47a7 a9 40 LDA #&40 &47a9 99 8e 00 STA &008e,Y ; list_of_objects_to_plot # Mark object as plotted &47ac 86 17 STX &17 ; object_to_consider &47ae 20 36 57 JSR &5736 ; plot_object # Plot object &47b1 a5 17 LDA &17 ; object_to_consider &47b3 d0 28 BNE &47dd ; continue_plotting_objects # Is this the player? &47b5 ad d7 5f LDA &5fd7 ; objects_sprite &47b8 c9 0b CMP #&0b ; PLAYER_BACK &47ba 90 21 BCC &47dd ; continue_plotting_objects # Is the player bursting? If not, &47bc c9 17 CMP #&17 ; PLAYER_FRONT_6 + 1 &47be b0 1d BCS &47dd ; continue_plotting_objects &47c0 a5 23 LDA &23 ; player_height &47c2 c9 88 CMP #&88 &47c4 90 17 BCC &47dd ; continue_plotting_objects # Is the player tall enough to have a head? &47c6 ac 2f 60 LDY &602f ; objects_facing &47c9 b9 e0 47 LDA &47e0,Y ; player_head_sprites_by_direction &47cc 20 10 57 JSR &5710 ; calculate_sprite_address &47cf a9 03 LDA #&03 &47d1 85 43 STA &43 ; sprite_offset &47d3 a5 31 LDA &31 ; screen_y_low &47d5 18 CLC &47d6 69 18 ADC #&18 &47d8 85 31 STA &31 ; screen_y_low &47da 20 68 57 JSR &5768 ; plot_object_without_initialisation # If so, plot head as well ; continue_plotting_objects &47dd 4c 2a 47 JMP &472a ; plot_objects_in_order_of_depth ; player_head_sprites_by_direction &47e0 5b 5c 5c 5b ; prepare_list_of_objects_in_room &47e4 86 28 STX &28 ; x_room &47e6 84 29 STY &29 ; y_room &47e8 a2 15 LDX #&15 &47ea a0 00 LDY #&00 ; prepare_list_of_objects_in_room_loop &47ec bd d7 5f LDA &5fd7,X ; objects_sprite &47ef f0 13 BEQ &4804 ; consider_next_object # Is there an object in this slot? &47f1 bd 03 60 LDA &6003,X ; objects_x_room &47f4 c5 28 CMP &28 ; x_room &47f6 d0 0c BNE &4804 ; consider_next_object # Is the object in this room? &47f8 bd 9d 60 LDA &609d,X ; objects_y_room &47fb c5 29 CMP &29 ; y_room &47fd d0 05 BNE &4804 ; consider_next_object &47ff 8a TXA &4800 99 8e 00 STA &008e,Y ; list_of_objects_to_plot # If so, add object to list &4803 c8 INY ; consider_next_object &4804 ca DEX &4805 10 e5 BPL &47ec ; prepare_list_of_objects_in_room_loop &4807 8a TXA # Add &ff for end of list &4808 99 8e 00 STA &008e,Y ; list_of_objects_to_plot &480b 60 RTS ; plot_boundaries &480c 20 c4 4a JSR &4ac4 ; get_room_data_byte &480f f0 54 BEQ &4865 ; leave # No boundaries if room doesn't have walls &4811 0a ASL A &4812 85 35 STA &35 ; wall_pattern # First pattern used for southern boundaries &4814 20 8d 5a JSR &5a8d ; calculate_room_screen_x_and_y &4817 20 66 48 JSR &4866 ; plot_southern_boundaries ; plot_northern_boundaries &481a a5 35 LDA &35 ; wall_pattern &481c 09 01 ORA #&01 # Second pattern used for northern boundaries &481e 0a ASL A &481f aa TAX &4820 bd 55 66 LDA &6655,X ; wall_patterns_address_table - 4 &4823 85 1b STA &1b ; wall_pattern_address_low &4825 bd 56 66 LDA &6656,X ; wall_patterns_address_table - 3 &4828 85 1c STA &1c ; wall_pattern_address_high &482a a5 2f LDA &2f ; screen_x_low &482c 38 SEC &482d e9 10 SBC #&10 &482f 85 2f STA &2f ; screen_x_low &4831 b0 02 BCS &4835 ; skip_carry &4833 c6 30 DEC &30 ; screen_x_high ; skip_carry &4835 a2 00 LDX #&00 &4837 86 1d STX &1d ; wall_is_flipped &4839 86 1e STX &1e ; wall_section &483b e8 INX &483c 86 36 STX &36 ; boundary_sprite_eor &483e a2 08 LDX #&08 ; plot_north_east_boundary_loop &4840 20 f4 48 JSR &48f4 ; plot_boundary_section # Plot north east boundary &4843 20 cb 48 JSR &48cb ; move_up_and_left_on_screen &4846 ca DEX &4847 d0 f7 BNE &4840 ; plot_north_east_boundary_loop &4849 a5 31 LDA &31 ; screen_y_low &484b 38 SEC &484c e9 08 SBC #&08 &484e 85 31 STA &31 ; screen_y_low &4850 b0 02 BCS &4854 ; skip_carry &4852 c6 32 DEC &32 ; screen_y_high ; skip_carry &4854 a9 01 LDA #&01 &4856 85 1d STA &1d ; wall_is_flipped &4858 85 36 STA &36 ; boundary_sprite_eor &485a a2 08 LDX #&08 ; plot_north_west_boundary_loop &485c 20 f4 48 JSR &48f4 ; plot_boundary_section # Plot north west boundary &485f 20 e6 48 JSR &48e6 ; move_down_and_left_on_screen &4862 ca DEX &4863 d0 f7 BNE &485c ; plot_north_west_boundary_loop ; leave &4865 60 RTS ; plot_southern_boundaries &4866 a5 35 LDA &35 ; wall_pattern &4868 0a ASL A &4869 aa TAX &486a bd 55 66 LDA &6655,X ; wall_patterns_address_table - 4 &486d 85 1b STA &1b ; wall_pattern_address_low &486f bd 56 66 LDA &6656,X ; wall_patterns_address_table - 3 &4872 85 1c STA &1c ; wall_pattern_address_high &4874 a9 00 LDA #&00 &4876 85 1e STA &1e ; wall_section &4878 85 1d STA &1d ; wall_is_flipped &487a 85 36 STA &36 ; boundary_sprite_eor &487c a2 08 LDX #&08 ; plot_south_west_boundary_loop &487e 20 f4 48 JSR &48f4 ; plot_boundary_section # Plot south west boundary &4881 20 a2 48 JSR &48a2 ; move_down_and_right_on_screen &4884 ca DEX &4885 d0 f7 BNE &487e ; plot_south_west_boundary_loop &4887 a5 31 LDA &31 ; screen_y_low &4889 18 CLC &488a 69 08 ADC #&08 &488c 85 31 STA &31 ; screen_y_low &488e 90 02 BCC &4892 ; skip_carry &4890 e6 32 INC &32 ; screen_y_high ; skip_carry &4892 a2 01 LDX #&01 &4894 86 1d STX &1d ; wall_is_flipped &4896 a2 08 LDX #&08 ; plot_south_east_boundary_loop &4898 20 f4 48 JSR &48f4 ; plot_boundary_section # Plot south east boundary &489b 20 bd 48 JSR &48bd ; move_up_and_right_on_screen &489e ca DEX &489f d0 f7 BNE &4898 ; plot_south_east_boundary_loop &48a1 60 RTS ; move_down_and_right_on_screen &48a2 a5 31 LDA &31 ; screen_y_low &48a4 38 SEC &48a5 e9 08 SBC #&08 &48a7 85 31 STA &31 ; screen_y_low &48a9 b0 02 BCS &48ad ; move_right_on_screen &48ab c6 32 DEC &32 ; screen_y_high ; move_right_on_screen &48ad a5 2f LDA &2f ; screen_x_low &48af 18 CLC &48b0 69 10 ADC #&10 &48b2 85 2f STA &2f ; screen_x_low &48b4 90 02 BCC &48b8 ; skip_overflow &48b6 e6 30 INC &30 ; screen_x_high ; skip_overflow &48b8 e6 1e INC &1e ; wall_section &48ba e6 1e INC &1e ; wall_section &48bc 60 RTS ; move_up_and_right_on_screen &48bd a5 31 LDA &31 ; screen_y_low &48bf 18 CLC &48c0 69 08 ADC #&08 &48c2 85 31 STA &31 ; screen_y_low &48c4 90 e7 BCC &48ad ; move_right_on_screen &48c6 e6 32 INC &32 ; screen_y_high &48c8 4c ad 48 JMP &48ad ; move_right_on_screen ; move_up_and_left_on_screen &48cb a5 31 LDA &31 ; screen_y_low &48cd 18 CLC &48ce 69 08 ADC #&08 &48d0 85 31 STA &31 ; screen_y_low &48d2 90 02 BCC &48d6 ; move_left_on_screen &48d4 e6 32 INC &32 ; screen_y_high ; move_left_on_screen &48d6 a5 2f LDA &2f ; screen_x_low &48d8 38 SEC &48d9 e9 10 SBC #&10 &48db 85 2f STA &2f ; screen_x_low &48dd b0 02 BCS &48e1 ; skip_overflow &48df c6 30 DEC &30 ; screen_x_high ; skip_overflow &48e1 e6 1e INC &1e ; wall_section &48e3 e6 1e INC &1e ; wall_section &48e5 60 RTS ; move_down_and_left_on_screen &48e6 a5 31 LDA &31 ; screen_y_low &48e8 38 SEC &48e9 e9 08 SBC #&08 &48eb 85 31 STA &31 ; screen_y_low &48ed b0 e7 BCS &48d6 ; move_left_on_screen &48ef c6 32 DEC &32 ; screen_y_high &48f1 4c d6 48 JMP &48d6 ; move_left_on_screen ; plot_boundary_section &48f4 a5 30 LDA &30 ; screen_x_high &48f6 d0 2f BNE &4927 ; leave # Leave if beyond the left or right of screen &48f8 a5 2f LDA &2f ; screen_x_low &48fa c9 d8 CMP #&d8 &48fc b0 29 BCS &4927 ; leave # Leave if beyond the right of the screen &48fe c9 18 CMP #&18 &4900 90 25 BCC &4927 ; leave # Leave if beyond the left of the screen &4902 a5 32 LDA &32 ; screen_y_high &4904 d0 21 BNE &4927 ; leave # Leave if beyond the top or bottom of screen &4906 a4 1e LDY &1e ; wall_section &4908 b1 1b LDA (&1b),Y ; wall_pattern_address &490a a8 TAY &490b b9 65 61 LDA &6165,Y ; wall_pattern_byte_to_boundary_sprite_table &490e 45 36 EOR &36 ; boundary_sprite_eor &4910 0a ASL A &4911 a8 TAY &4912 b9 7e 61 LDA &617e,Y ; boundary_sprite_address_table &4915 85 0c STA &0c ; wall_sprite_address_low &4917 b9 7f 61 LDA &617f,Y ; boundary_sprite_address_table + 1 &491a 85 0d STA &0d ; wall_sprite_address_high &491c 86 1f STX &1f ; x &491e a6 2f LDX &2f ; screen_x_low &4920 a4 31 LDY &31 ; screen_y_low &4922 20 28 49 JSR &4928 ; plot_boundary_sprite &4925 a6 1f LDX &1f ; x ; leave &4927 60 RTS ; plot_boundary_sprite &4928 a9 01 LDA #&01 &492a 85 43 STA &43 ; sprite_offset &492c a0 00 LDY #&00 &492e b1 0c LDA (&0c),Y ; wall_sprite_address &4930 85 2d STA &2d ; height_of_column &4932 a4 31 LDY &31 ; screen_y_low &4934 c0 b8 CPY #&b8 &4936 b0 ef BCS &4927 ; leave # Leave if boundary starts beyond the top of the screen &4938 84 12 STY &12 ; y &493a c0 48 CPY #&48 &493c 90 0f BCC &494d ; cropped_at_bottom # Does the sprite start before the bottom of the screen? &493e a9 b8 LDA #&b8 # If not, does it end after the top of the screen? &4940 38 SEC &4941 e5 12 SBC &12 ; y &4943 a0 00 LDY #&00 &4945 d1 0c CMP (&0c),Y ; wall_sprite_address # First byte of boundary sprite data is height of sprite &4947 b0 23 BCS &496c ; plot_from_y ; cropped_at_top &4949 85 2d STA &2d ; height_of_column # If so, crop sprite to stop plotting at top of screen &494b d0 1f BNE &496c ; plot_from_y # Always branches ; cropped_at_bottom &494d a9 48 LDA #&48 &494f 38 SEC &4950 e5 12 SBC &12 ; y &4952 85 13 STA &13 ; cropped_height &4954 a0 00 LDY #&00 &4956 b1 0c LDA (&0c),Y ; wall_sprite_address &4958 38 SEC &4959 e5 13 SBC &13 ; cropped_height &495b f0 ca BEQ &4927 ; leave &495d 30 c8 BMI &4927 ; leave # Leave if sprite ends before the bottom of the screen &495f 85 2d STA &2d ; height_of_column # Otherwise, crop sprite to start at bottom of screen, &4961 a5 13 LDA &13 ; cropped_height &4963 0a ASL A &4964 69 01 ADC #&01 &4966 85 43 STA &43 ; sprite_offset # using new start of sprite data &4968 a0 48 LDY #&48 # Start plotting at bottom of screen &496a d0 02 BNE &496e ; plot_from_Y # Always branches ; plot_from_y &496c a4 12 LDY &12 ; y ; plot_from_Y &496e a6 2f LDX &2f ; screen_x_low &4970 20 31 5a JSR &5a31 ; calculate_buffer_address_from_X_and_Y &4973 a6 43 LDX &43 ; sprite_offset &4975 a5 2f LDA &2f ; screen_x_low &4977 29 06 AND #&06 &4979 f0 03 BEQ &497e ; plot_aligned_boundary # Is the sprite byte-wise aligned with the screen? &497b 4c 08 4a JMP &4a08 ; plot_misaligned_boundary ; plot_aligned_boundary &497e a5 1d LDA &1d ; wall_is_flipped &4980 f0 48 BEQ &49ca ; plot_aligned_unflipped_boundary ; plot_aligned_flipped_boundary &4982 a5 0c LDA &0c ; wall_sprite_address_low &4984 8d 97 49 STA &4997 ; aligned_flipped_boundary_sprite_address_low_one &4987 8d a6 49 STA &49a6 ; aligned_flipped_boundary_sprite_address_low_two &498a a5 0d LDA &0d ; wall_sprite_address_high &498c 8d 98 49 STA &4998 ; aligned_flipped_boundary_sprite_address_high_one &498f 8d a7 49 STA &49a7 ; aligned_flipped_boundary_sprite_address_high_two ; plot_aligned_flipped_boundary_loop &4992 a0 08 LDY #&08 &4994 b1 2b LDA (&2b),Y ; buffer_address &4996 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4999 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &499c a0 08 LDY #&08 &499e 91 2b STA (&2b),Y ; buffer_address &49a0 e8 INX &49a1 a0 00 LDY #&00 &49a3 b1 2b LDA (&2b),Y ; buffer_address &49a5 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &49a8 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &49ab a0 00 LDY #&00 &49ad 91 2b STA (&2b),Y ; buffer_address &49af e8 INX &49b0 a5 2b LDA &2b ; buffer_address_low &49b2 29 07 AND #&07 &49b4 d0 0d BNE &49c3 ; not_group &49b6 a5 2b LDA &2b ; buffer_address_low &49b8 38 SEC &49b9 e9 b9 SBC #&b9 &49bb 85 2b STA &2b ; buffer_address_low &49bd b0 06 BCS &49c5 ; next_row &49bf c6 2c DEC &2c ; buffer_address_high &49c1 10 02 BPL &49c5 ; next_row ; not_group &49c3 c6 2b DEC &2b ; buffer_address_low ; next_row &49c5 c6 2d DEC &2d ; height_of_column &49c7 d0 c9 BNE &4992 ; plot_aligned_flipped_boundary_loop &49c9 60 RTS ; plot_aligned_unflipped_boundary &49ca a5 0c LDA &0c ; wall_sprite_address_low &49cc 8d df 49 STA &49df ; aligned_unflipped_boundary_sprite_address_low_one &49cf 8d e9 49 STA &49e9 ; aligned_unflipped_boundary_sprite_address_low_two &49d2 a5 0d LDA &0d ; wall_sprite_address_high &49d4 8d e0 49 STA &49e0 ; aligned_unflipped_boundary_sprite_address_high_one &49d7 8d ea 49 STA &49ea ; aligned_unflipped_boundary_sprite_address_high_one ; plot_aligned_unflipped_boundary_loop &49da a0 00 LDY #&00 &49dc b1 2b LDA (&2b),Y ; buffer_address &49de 1d ff ff ORA &ffff,X # actually ORA wall_sprite_address,X &49e1 91 2b STA (&2b),Y ; buffer_address &49e3 e8 INX &49e4 a0 08 LDY #&08 &49e6 b1 2b LDA (&2b),Y ; buffer_address &49e8 1d ff ff ORA &ffff,X # actually ORA wall_sprite_address,X &49eb 91 2b STA (&2b),Y ; buffer_address &49ed e8 INX &49ee a5 2b LDA &2b ; buffer_address_low &49f0 29 07 AND #&07 &49f2 d0 0d BNE &4a01 ; not_group &49f4 a5 2b LDA &2b ; buffer_address_low &49f6 38 SEC &49f7 e9 b9 SBC #&b9 &49f9 85 2b STA &2b ; buffer_address_low &49fb b0 06 BCS &4a03 ; next_row &49fd c6 2c DEC &2c ; buffer_address_high &49ff 10 02 BPL &4a03 ; next_row ; not_group &4a01 c6 2b DEC &2b ; buffer_address_low ; next_row &4a03 c6 2d DEC &2d ; height_of_column &4a05 d0 d3 BNE &49da ; plot_aligned_unflipped_boundary_loop &4a07 60 RTS ; plot_misaligned_boundary &4a08 18 CLC &4a09 69 77 ADC #&77 ; (bits_shifted_right_two_bits / &100) + 2 # Use bits_shifted_right_*_bits &4a0b 8d 46 4a STA &4a46 ; boundary_shift_table_one_address_high_one &4a0e 8d 5b 4a STA &4a5b ; boundary_shift_table_one_address_high_two &4a11 18 CLC &4a12 69 01 ADC #&01 # Use bits_shifted_left_*_bits &4a14 8d 54 4a STA &4a54 ; boundary_shift_table_two_address_high_one &4a17 8d 69 4a STA &4a69 ; boundary_shift_table_two_address_high_two &4a1a a5 1d LDA &1d ; wall_is_flipped &4a1c f0 03 BEQ &4a21 ; use_unflipped_boundary &4a1e 4c 89 4a JMP &4a89 ; use_flipped_boundary ; use_unflipped_boundary &4a21 a5 0c LDA &0c ; wall_sprite_address_low &4a23 a4 0d LDY &0d ; wall_sprite_address_high ; set_boundary_sprite &4a25 8d 42 4a STA &4a42 ; misaligned_boundary_sprite_address_low_one &4a28 8d 50 4a STA &4a50 ; misaligned_boundary_sprite_address_low_two &4a2b 8d 57 4a STA &4a57 ; misaligned_boundary_sprite_address_low_three &4a2e 8d 65 4a STA &4a65 ; misaligned_boundary_sprite_address_low_four &4a31 8c 43 4a STY &4a43 ; misaligned_boundary_sprite_address_high_one &4a34 8c 51 4a STY &4a51 ; misaligned_boundary_sprite_address_high_two &4a37 8c 58 4a STY &4a58 ; misaligned_boundary_sprite_address_high_three &4a3a 8c 66 4a STY &4a66 ; misaligned_boundary_sprite_address_high_four ; plot_misaligned_boundary_loop &4a3d a0 00 LDY #&00 &4a3f b1 2b LDA (&2b),Y ; buffer_address &4a41 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4a44 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA boundary_shift_table_one_address,Y &4a47 a0 00 LDY #&00 &4a49 91 2b STA (&2b),Y ; buffer_address &4a4b a0 08 LDY #&08 &4a4d b1 2b LDA (&2b),Y ; buffer_address &4a4f bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4a52 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA boundary_shift_table_two_address,Y &4a55 e8 INX &4a56 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4a59 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA boundary_shift_table_one_address,Y &4a5c a0 08 LDY #&08 &4a5e 91 2b STA (&2b),Y ; buffer_address &4a60 a0 10 LDY #&10 &4a62 b1 2b LDA (&2b),Y ; buffer_address &4a64 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4a67 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA boundary_shift_table_two_address,Y &4a6a a0 10 LDY #&10 &4a6c 91 2b STA (&2b),Y ; buffer_address &4a6e e8 INX &4a6f a5 2b LDA &2b ; buffer_address_low &4a71 29 07 AND #&07 &4a73 d0 0d BNE &4a82 ; not_group &4a75 a5 2b LDA &2b ; buffer_address_low &4a77 38 SEC &4a78 e9 b9 SBC #&b9 &4a7a 85 2b STA &2b ; buffer_address_low &4a7c b0 06 BCS &4a84 ; next_row &4a7e c6 2c DEC &2c ; buffer_address_high &4a80 d0 02 BNE &4a84 ; next_row ; not_group &4a82 c6 2b DEC &2b ; buffer_address_low ; next_row &4a84 c6 2d DEC &2d ; height_of_column &4a86 d0 b5 BNE &4a3d ; plot_misaligned_boundary_loop &4a88 60 RTS ; use_flipped_boundary &4a89 20 8f 4a JSR &4a8f ; flip_wall_sprite &4a8c 4c 25 4a JMP &4a25 ; set_boundary_sprite ; flip_wall_sprite &4a8f a5 0c LDA &0c ; wall_sprite_address_low &4a91 8d a6 4a STA &4aa6 ; flip_wall_sprite_address_low_one &4a94 8d b0 4a STA &4ab0 ; flip_wall_sprite_address_low_two &4a97 a5 0d LDA &0d ; wall_sprite_address_high &4a99 8d a7 4a STA &4aa7 ; flip_wall_sprite_address_high_one &4a9c 8d b1 4a STA &4ab1 ; flip_wall_sprite_address_high_two &4a9f a5 2d LDA &2d ; height_of_column &4aa1 85 2e STA &2e ; columns_to_flip &4aa3 a6 43 LDX &43 ; sprite_offset ; flip_wall_sprite_loop &4aa5 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4aa8 b9 00 7f LDA &7f00,Y ; bit_reversed_bytes &4aab 9d 25 77 STA &7725,X ; flipped_wall_sprite + 1 &4aae e8 INX &4aaf bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4ab2 b9 00 7f LDA &7f00,Y ; bit_reversed_bytes &4ab5 9d 23 77 STA &7723,X ; flipped_wall_sprite - 1 &4ab8 e8 INX &4ab9 c6 2e DEC &2e ; columns_to_flip &4abb d0 e8 BNE &4aa5 ; flip_wall_sprite_loop &4abd a6 43 LDX &43 ; sprite_offset &4abf a9 24 LDA #&24 &4ac1 a0 77 LDY #&77 ; &7724 = flipped_wall_sprite &4ac3 60 RTS ; get_room_data_byte &4ac4 86 21 STX &21 ; room_x &4ac6 84 22 STY &22 ; room_y &4ac8 a9 00 LDA #&00 &4aca 85 12 STA &12 ; room_data_address_low &4acc 98 TYA &4acd 0a ASL A &4ace 0a ASL A &4acf 0a ASL A &4ad0 26 12 ROL &12 ; room_data_address_low &4ad2 0a ASL A &4ad3 26 12 ROL &12 ; room_data_address_low &4ad5 0a ASL A &4ad6 26 12 ROL &12 ; room_data_address_low &4ad8 85 13 STA &13 ; room_data_address_high &4ada a4 12 LDY &12 ; room_data_address_low &4adc 8a TXA &4add 05 13 ORA &13 ; room_data_address_high &4adf 18 CLC &4ae0 69 b9 ADC #&b9 &4ae2 85 12 STA &12 ; room_data_address_low &4ae4 98 TYA &4ae5 69 61 ADC #&61 ; &61b9 = room_data # Address is &61b9 + room_x + room_y * 32 &4ae7 85 13 STA &13 ; room_data_address_high &4ae9 a0 00 LDY #&00 &4aeb b1 12 LDA (&12),Y ; room_data_address &4aed 29 7f AND #&7f # actually AND get_room_data_byte_and &4aef 60 RTS ; leave &4af0 60 RTS ; plot_walls &4af1 20 c4 4a JSR &4ac4 ; get_room_data_byte &4af4 f0 fa BEQ &4af0 ; leave &4af6 0a ASL A # Convert room byte into wall pattern &4af7 0a ASL A &4af8 a8 TAY &4af9 b9 55 66 LDA &6655,Y ; wall_patterns_address_table - 4 &4afc 85 1b STA &1b ; wall_pattern_address_low &4afe b9 56 66 LDA &6656,Y ; wall_patterns_address_table - 3 &4b01 85 1c STA &1c ; wall_pattern_address_high &4b03 20 8d 5a JSR &5a8d ; calculate_room_screen_x_and_y &4b06 a9 00 LDA #&00 &4b08 85 1e STA &1e ; wall_section &4b0a 85 1d STA &1d ; wall_is_flipped &4b0c a2 08 LDX #&08 ; plot_north_east_wall_loop &4b0e 20 3e 4b JSR &4b3e ; plot_wall_section # Plot north east wall &4b11 a5 45 LDA &45 ; walls_to_plot &4b13 f0 28 BEQ &4b3d ; leave # Don't consider more walls than can fit on screen &4b15 20 a2 48 JSR &48a2 ; move_down_and_right_on_screen &4b18 a6 1f LDX &1f ; x &4b1a ca DEX &4b1b d0 f1 BNE &4b0e ; plot_north_east_wall_loop &4b1d a5 31 LDA &31 ; screen_y_low &4b1f 18 CLC &4b20 69 08 ADC #&08 &4b22 85 31 STA &31 ; screen_y_low &4b24 90 02 BCC &4b28 &4b26 e6 32 INC &32 ; screen_y_high &4b28 a9 01 LDA #&01 &4b2a 85 1d STA &1d ; wall_is_flipped &4b2c a2 08 LDX #&08 ; plot_north_west_wall_loop &4b2e 20 3e 4b JSR &4b3e ; plot_wall_section # Plot north west wall &4b31 a5 45 LDA &45 ; walls_to_plot &4b33 f0 08 BEQ &4b3d ; leave # Don't consider more walls than can fit on screen &4b35 20 bd 48 JSR &48bd ; move_up_and_right_on_screen &4b38 a6 1f LDX &1f ; x &4b3a ca DEX &4b3b d0 f1 BNE &4b2e ; plot_north_west_wall_loop ; leave &4b3d 60 RTS ; plot_wall_section &4b3e 86 1f STX &1f ; x &4b40 a5 30 LDA &30 ; screen_x_high &4b42 d0 f9 BNE &4b3d ; leave # Leave if beyond the left or right of screen &4b44 a5 2f LDA &2f ; screen_x_low &4b46 c9 18 CMP #&18 &4b48 90 f3 BCC &4b3d ; leave # Leave if beyond the left of the screen &4b4a f0 f1 BEQ &4b3d ; leave &4b4c c9 d8 CMP #&d8 &4b4e b0 ed BCS &4b3d ; leave # Leave if beyond the right of the screen &4b50 38 SEC &4b51 e9 08 SBC #&08 &4b53 4a LSR A &4b54 4a LSR A &4b55 4a LSR A &4b56 4a LSR A &4b57 aa TAX &4b58 bd 08 4d LDA &4d08,X ; wall_sections_plotted - 1 # Leave if wall section has already been plotted &4b5b d0 e0 BNE &4b3d ; leave &4b5d fe 08 4d INC &4d08,X ; wall_sections_plotted - 1 # Mark wall section as plotted &4b60 c6 45 DEC &45 ; walls_to_plot &4b62 a5 32 LDA &32 ; screen_y_high &4b64 d0 d7 BNE &4b3d ; leave &4b66 a4 1e LDY &1e ; wall_section &4b68 20 9c 4b JSR &4b9c ; plot_wall_sprite # Plot bottom floor &4b6b a5 31 LDA &31 ; screen_y_low &4b6d 48 PHA &4b6e a5 32 LDA &32 ; screen_y_high &4b70 48 PHA &4b71 a4 1e LDY &1e ; wall_section &4b73 c8 INY &4b74 a5 31 LDA &31 ; screen_y_low &4b76 18 CLC &4b77 69 40 ADC #&40 &4b79 85 31 STA &31 ; screen_y_low &4b7b a5 32 LDA &32 ; screen_y_high &4b7d 69 00 ADC #&00 &4b7f 85 32 STA &32 ; screen_y_high &4b81 d0 12 BNE &4b95 ; skip_top_section &4b83 20 9c 4b JSR &4b9c ; plot_wall_sprite # Plot top floor &4b86 a9 15 LDA #&15 &4b88 85 0c STA &0c ; wall_sprite_address_low &4b8a a9 4d LDA #&4d ; &4d15 = wall_separator_sprite &4b8c 85 0d STA &0d ; wall_sprite_address_high &4b8e a6 2f LDX &2f ; screen_x_low &4b90 a4 31 LDY &31 ; screen_y_low &4b92 20 28 49 JSR &4928 ; plot_boundary_sprite # Plot boundary between top and bottom floors ; skip_top_section &4b95 68 PLA &4b96 85 32 STA &32 ; screen_y_high &4b98 68 PLA &4b99 85 31 STA &31 ; screen_y_low ; leave &4b9b 60 RTS ; plot_wall_sprite &4b9c b1 1b LDA (&1b),Y ; wall_pattern_address &4b9e 0a ASL A &4b9f a8 TAY &4ba0 b9 e8 38 LDA &38e8,Y ; wall_sprite_address_table &4ba3 85 0c STA &0c ; wall_sprite_address_low &4ba5 b9 e9 38 LDA &38e9,Y ; wall_sprite_address_table + 1 &4ba8 85 0d STA &0d ; wall_sprite_address_high &4baa a9 40 LDA #&40 &4bac 85 2d STA &2d ; height_of_column &4bae a9 00 LDA #&00 &4bb0 85 43 STA &43 ; sprite_offset &4bb2 a4 31 LDY &31 ; screen_y_low &4bb4 c0 b8 CPY #&b8 # Leave if wall starts beyond the top of the screen &4bb6 b0 e3 BCS &4b9b ; leave &4bb8 84 12 STY &12 ; y &4bba c0 48 CPY #&48 &4bbc 90 0d BCC &4bcb ; cropped_at_bottom # Does the sprite start before the bottom of the screen? &4bbe a9 b8 LDA #&b8 # If not, does it end after the top of the screen? &4bc0 38 SEC &4bc1 e5 12 SBC &12 ; y &4bc3 c9 40 CMP #&40 &4bc5 b0 1f BCS &4be6 ; plot_from_y ; cropped_at_top &4bc7 85 2d STA &2d ; height_of_column # If so, crop sprite to stop plotting at top of screen &4bc9 d0 1b BNE &4be6 ; plot_from_y # Always branches ; cropped_at_bottom &4bcb a9 48 LDA #&48 &4bcd 38 SEC &4bce e5 12 SBC &12 ; y &4bd0 85 13 STA &13 ; cropped_height &4bd2 a9 40 LDA #&40 &4bd4 38 SEC &4bd5 e5 13 SBC &13 ; cropped_height &4bd7 f0 c2 BEQ &4b9b ; leave &4bd9 30 c0 BMI &4b9b ; leave # Leave if sprite ends before the bottom of the screen &4bdb 85 2d STA &2d ; height_of_column # Otherwise, crop sprite to start at bottom of screen, &4bdd a5 13 LDA &13 ; cropped_height &4bdf 0a ASL A &4be0 85 43 STA &43 ; sprite_offset # using new start of sprite data &4be2 a0 48 LDY #&48 # Start plotting at bottom of screen &4be4 d0 02 BNE &4be8 ; plot_from_Y # Always branches ; plot_from_y &4be6 a4 12 LDY &12 ; y ; plot_from_Y &4be8 a6 2f LDX &2f ; screen_x_low &4bea 20 31 5a JSR &5a31 ; calculate_buffer_address_from_X_and_Y &4bed a6 43 LDX &43 ; sprite_offset &4bef a5 2f LDA &2f ; screen_x_low &4bf1 29 06 AND #&06 &4bf3 f0 03 BEQ &4bf8 ; plot_aligned_wall &4bf5 4c 76 4c JMP &4c76 ; plot_misaligned_wall ; plot_aligned_wall &4bf8 a5 1d LDA &1d ; wall_is_flipped &4bfa d0 3a BNE &4c36 ; plot_flipped_aligned_wall ; plot_unflipped_aligned_wall &4bfc a5 0c LDA &0c ; wall_sprite_address_low &4bfe 8d 0d 4c STA &4c0d ; unflipped_aligned_wall_sprite_address_low_one &4c01 8d 15 4c STA &4c15 ; unflipped_aligned_wall_sprite_address_low_two &4c04 a5 0d LDA &0d ; wall_sprite_address_high &4c06 8d 0e 4c STA &4c0e ; unflipped_aligned_wall_sprite_address_high_one &4c09 8d 16 4c STA &4c16 ; unflipped_aligned_wall_sprite_address_high_two ; plot_unflipped_aligned_wall_loop &4c0c bd ff ff LDA &ffff,X # actually LDA wall_sprite_address,X &4c0f a0 00 LDY #&00 &4c11 91 2b STA (&2b),Y ; buffer_address &4c13 e8 INX &4c14 bd ff ff LDA &ffff,X # actually LDA wall_sprite_address,X &4c17 a0 08 LDY #&08 &4c19 91 2b STA (&2b),Y ; buffer_address &4c1b e8 INX &4c1c a5 2b LDA &2b ; buffer_address_low &4c1e 29 07 AND #&07 &4c20 d0 0d BNE &4c2f ; not_group &4c22 a5 2b LDA &2b ; buffer_address_low &4c24 38 SEC &4c25 e9 b9 SBC #&b9 &4c27 85 2b STA &2b ; buffer_address_low &4c29 b0 06 BCS &4c31 ; next_row &4c2b c6 2c DEC &2c ; buffer_address_high &4c2d d0 02 BNE &4c31 ; next_row ; not_group &4c2f c6 2b DEC &2b ; buffer_address_low ; next_row &4c31 c6 2d DEC &2d ; height_of_column &4c33 d0 d7 BNE &4c0c ; plot_unflipped_aligned_wall_loop &4c35 60 RTS ; plot_flipped_aligned_wall &4c36 a5 0c LDA &0c ; wall_sprite_address_low &4c38 8d 47 4c STA &4c47 ; flipped_aligned_wall_sprite_address_low_one &4c3b 8d 52 4c STA &4c52 ; flipped_aligned_wall_sprite_address_low_two &4c3e a5 0d LDA &0d ; wall_sprite_address_high &4c40 8d 48 4c STA &4c48 ; flipped_aligned_wall_sprite_address_high_one &4c43 8d 53 4c STA &4c53 ; flipped_aligned_wall_sprite_address_high_two ; plot_flipped_aligned_wall_loop &4c46 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4c49 b9 00 7f LDA &7f00,Y ; bit_reversed_bytes &4c4c a0 08 LDY #&08 &4c4e 91 2b STA (&2b),Y ; buffer_address &4c50 e8 INX &4c51 bc ff ff LDY &ffff,X # actually LDY wall_sprite_address,X &4c54 b9 00 7f LDA &7f00,Y ; bit_reversed_bytes &4c57 a0 00 LDY #&00 &4c59 91 2b STA (&2b),Y ; buffer_address &4c5b e8 INX &4c5c a5 2b LDA &2b ; buffer_address_low &4c5e 29 07 AND #&07 &4c60 d0 0d BNE &4c6f ; not_group &4c62 a5 2b LDA &2b ; buffer_address_low &4c64 38 SEC &4c65 e9 b9 SBC #&b9 &4c67 85 2b STA &2b ; buffer_address_low &4c69 b0 06 BCS &4c71 ; next_row &4c6b c6 2c DEC &2c ; buffer_address_high &4c6d d0 02 BNE &4c71 ; next_row ; not_group &4c6f c6 2b DEC &2b ; buffer_address_low ; next_row &4c71 c6 2d DEC &2d ; height_of_column &4c73 d0 d1 BNE &4c46 ; plot_flipped_aligned_wall_loop &4c75 60 RTS ; plot_misaligned_wall &4c76 a8 TAY &4c77 18 CLC &4c78 69 77 ADC #&77 ; (bits_shifted_right_two_bits / &100) + 2 # Use bits_shifted_right_*_bits &4c7a 8d c2 4c STA &4cc2 ; shift_table_one_address_high_one &4c7d 8d d3 4c STA &4cd3 ; shift_table_one_address_high_two &4c80 18 CLC &4c81 69 01 ADC #&01 # Use bits_shifted_left_*_bits &4c83 8d cc 4c STA &4ccc ; shift_table_two_address_high_one &4c86 8d e3 4c STA &4ce3 ; shift_table_two_address_high_two &4c89 b9 fb 5a LDA &5afb,Y ; bits_in_shifted_byte_table - 2 &4c8c 8d bc 4c STA &4cbc ; left_bits &4c8f 49 ff EOR #&ff &4c91 8d dd 4c STA &4cdd ; right_bits &4c94 a5 1d LDA &1d ; wall_is_flipped &4c96 f0 03 BEQ &4c9b ; use_unflipped_wall &4c98 4c 03 4d JMP &4d03 ; use_flipped_wall ; use_unflipped_wall &4c9b a5 0c LDA &0c ; wall_sprite_address_low &4c9d a4 0d LDY &0d ; wall_sprite_address_high ; set_wall_sprite &4c9f 8d be 4c STA &4cbe ; misaligned_wall_sprite_address_low_one &4ca2 8d c8 4c STA &4cc8 ; misaligned_wall_sprite_address_low_two &4ca5 8d cf 4c STA &4ccf ; misaligned_wall_sprite_address_low_three &4ca8 8d df 4c STA &4cdf ; misaligned_wall_sprite_address_low_four &4cab 8c bf 4c STY &4cbf ; misaligned_wall_sprite_address_high_one &4cae 8c c9 4c STY &4cc9 ; misaligned_wall_sprite_address_high_two &4cb1 8c d0 4c STY &4cd0 ; misaligned_wall_sprite_address_high_three &4cb4 8c e0 4c STY &4ce0 ; misaligned_wall_sprite_address_high_four ; plot_misaligned_wall_loop &4cb7 a0 00 LDY #&00 &4cb9 b1 2b LDA (&2b),Y ; buffer_address &4cbb 29 00 AND #&00 # actually AND left_bits &4cbd bc ff ff LDY &ffff,X # actually LDY wall_sprite,X &4cc0 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA shift_table_one,Y &4cc3 a0 00 LDY #&00 &4cc5 91 2b STA (&2b),Y ; buffer_address &4cc7 bc ff ff LDY &ffff,X # actually LDY wall_sprite,X &4cca b9 00 79 LDA &7900,Y ; bits_shifted_right_two_bits # actually LDA shift_table_two,Y &4ccd e8 INX &4cce bc ff ff LDY &ffff,X # actually LDY wall_sprite,X &4cd1 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA shift_table_one,Y &4cd4 a0 08 LDY #&08 &4cd6 91 2b STA (&2b),Y ; buffer_address &4cd8 a0 10 LDY #&10 &4cda b1 2b LDA (&2b),Y ; buffer_address &4cdc 29 00 AND #&00 # actually AND right_bits &4cde bc ff ff LDY &ffff,X # actually LDY wall_sprite,X &4ce1 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA shift_table_two,Y &4ce4 a0 10 LDY #&10 &4ce6 91 2b STA (&2b),Y ; buffer_address &4ce8 e8 INX &4ce9 a5 2b LDA &2b ; buffer_address_low &4ceb 29 07 AND #&07 &4ced d0 0d BNE &4cfc ; not_group &4cef a5 2b LDA &2b ; buffer_address_low &4cf1 38 SEC &4cf2 e9 b9 SBC #&b9 &4cf4 85 2b STA &2b ; buffer_address_low &4cf6 b0 06 BCS &4cfe ; next_row &4cf8 c6 2c DEC &2c ; buffer_address_high &4cfa d0 02 BNE &4cfe ; next_row ; not_group &4cfc c6 2b DEC &2b ; buffer_address_low ; next_row &4cfe c6 2d DEC &2d ; height_of_column &4d00 d0 b5 BNE &4cb7 ; plot_misaligned_wall_loop &4d02 60 RTS ; use_flipped_wall &4d03 20 8f 4a JSR &4a8f ; flip_wall_sprite &4d06 4c 9f 4c JMP &4c9f ; set_wall_sprite ; wall_sections_plotted &4d09 00 00 00 00 00 00 00 00 00 00 00 00 ; wall_separator_sprite # Separator between top and bottom floors &4d15 06 &4d16 3f f0 ff c0 ff 00 fc 00 f0 00 c0 00 ; start_game &4d22 a9 07 LDA #&07 ; K # Set main background to black &4d24 85 03 STA &03 ; main_background_colour &4d26 a9 80 LDA #&80 ; W # Set main foreground to white &4d28 85 04 STA &04 ; main_foreground_colour &4d2a 58 CLI &4d2b a2 ff LDX #&ff &4d2d 9a TXS &4d2e 20 fe 5d JSR &5dfe ; start_screen &4d31 a2 9e LDX #&9e &4d33 a9 00 LDA #&00 ; wipe_0008_to_00a6_loop &4d35 95 07 STA &07,X # Wipe &0008 to &00a6 with &00 &4d37 ca DEX &4d38 d0 fb BNE &4d35 ; wipe_0008_to_00a6_loop &4d3a a2 15 LDX #&15 ; wipe_objects_sprite_loop &4d3c 9d d7 5f STA &5fd7,X ; objects_sprite # Remove all objects &4d3f ca DEX &4d40 10 fa BPL &4d3c ; wipe_objects_sprite_loop ; wipe_0c30_to_0d8f_loop &4d42 9d 30 0c STA &0c30,X # Wipe screen memory used for pockets &4d45 9d e0 0c STA &0ce0,X &4d48 e8 INX &4d49 e0 b0 CPX #&b0 &4d4b d0 f5 BNE &4d42 ; wipe_0c30_to_0d8f_loop &4d4d a2 06 LDX #&06 ; reset_score_loop &4d4f 9d 18 4f STA &4f18,X ; score_text + 2 # Reset score to 0000000 &4d52 ca DEX &4d53 10 fa BPL &4d4f ; reset_score_loop ; mark_rooms_as_unvisited &4d55 a2 04 LDX #&04 &4d57 a0 00 LDY #&00 &4d59 a9 61 LDA #&61 ; &61b9 = room_data &4d5b 85 13 STA &13 ; room_data_address_high &4d5d a9 b9 LDA #&b9 &4d5f 85 12 STA &12 ; room_data_address_low ; mark_rooms_as_unvisited_loop &4d61 b1 12 LDA (&12),Y ; room_data_address &4d63 29 7f AND #&7f # Clear top bit to indicate room hasn't been visited &4d65 91 12 STA (&12),Y ; room_data_address &4d67 c8 INY &4d68 d0 f7 BNE &4d61 ; mark_rooms_as_unvisited &4d6a e6 13 INC &13 ; room_data_address_high &4d6c ca DEX &4d6d d0 f2 BNE &4d61 ; mark_rooms_as_unvisited &4d6f a9 05 LDA #&05 &4d71 85 19 STA &19 ; player_lives &4d73 20 d3 51 JSR &51d3 ; initialise_player &4d76 20 82 52 JSR &5282 ; initialise_player_life &4d79 20 69 43 JSR &4369 ; initialise_demons &4d7c 20 02 56 JSR &5602 ; initialise_weapons &4d7f 20 28 5e JSR &5e28 ; plot_demons_needing_destroying &4d82 20 32 41 JSR &4132 ; randomise_available_antibodies &4d85 20 7e 5f JSR &5f7e ; wipe_screen_buffer &4d88 20 0f 4f JSR &4f0f ; plot_score &4d8b 20 eb 5e JSR &5eeb ; rnd &4d8e 85 65 STA &65 ; random_number_for_demon_destruction_colours &4d90 a9 81 LDA #&81 ; C # Set main foreground to cyan &4d92 85 04 STA &04 ; main_foreground_colour ; main_game_loop &4d94 a2 ff LDX #&ff &4d96 9a TXS &4d97 86 53 STX &53 ; score_has_changed &4d99 e6 1a INC &1a ; game_timer &4d9b 20 aa 53 JSR &53aa ; silence_sound &4d9e a2 90 LDX #&90 ; "Q" &4da0 20 d3 5e JSR &5ed3 ; check_for_keypress &4da3 10 04 BPL &4da9 ; q_not_pressed &4da5 a9 00 LDA #&00 &4da7 85 05 STA &05 ; sound_enabled ; q_not_pressed &4da9 a2 d1 LDX #&d1 ; "S" &4dab 20 d3 5e JSR &5ed3 ; check_for_keypress &4dae 10 04 BPL &4db4 ; s_not_pressed &4db0 a9 01 LDA #&01 &4db2 85 05 STA &05 ; sound_enabled ; s_not_pressed &4db4 20 20 4f JSR &4f20 ; update_objects &4db7 a9 ff LDA #&ff # Read room data including visited state &4db9 8d ee 4a STA &4aee ; get_room_data_byte_and &4dbc 20 c2 4e JSR &4ec2 ; mark_room_as_visited &4dbf a9 7f LDA #&7f # Read room data excluding visited state &4dc1 8d ee 4a STA &4aee ; get_room_data_byte_and &4dc4 20 eb 5e JSR &5eeb ; rnd &4dc7 20 41 41 JSR &4141 ; summon_wild_antibody &4dca 20 1c 45 JSR &451c ; summon_imp &4dcd 20 4a 56 JSR &564a ; summon_collectable &4dd0 20 22 44 JSR &4422 ; summon_fire &4dd3 20 de 54 JSR &54de ; invert_weapons_for_nearby_demons &4dd6 20 26 46 JSR &4626 ; update_screen &4dd9 a9 df LDA #&df # Set channel 1 to volume 0 &4ddb 20 25 54 JSR &5425 ; write_byte_to_sound_chip &4dde a5 60 LDA &60 ; jingle_length &4de0 f0 13 BEQ &4df5 ; skip_jingle # Is there a jingle being played? &4de2 18 CLC &4de3 65 5f ADC &5f ; jingle_start &4de5 aa TAX &4de6 bd ca 54 LDA &54ca,X ; jingle_pitches - 1 &4de9 a2 a0 LDX #&a0 # Use channel 2 &4deb 20 04 54 JSR &5404 ; write_frequency_in_A_times_four_to_sound_chip &4dee a9 b4 LDA #&b4 # Set channel 2 to volume 11 &4df0 20 25 54 JSR &5425 ; write_byte_to_sound_chip &4df3 c6 60 DEC &60 ; jingle_length ; skip_jingle &4df5 a9 00 LDA #&00 &4df7 85 a4 STA &a4 ; object_is_bursting &4df9 85 a5 STA &a5 ; object_is_unbursting &4dfb a2 15 LDX #&15 &4dfd 86 12 STX &12 ; object_to_consider ; check_objects_for_bursting_loop &4dff a6 12 LDX &12 ; object_to_consider &4e01 bd 45 60 LDA &6045,X ; objects_data &4e04 f0 37 BEQ &4e3d ; skip_bursting_sound # Is the object on screen? &4e06 bd d7 5f LDA &5fd7,X ; objects_sprite &4e09 c9 07 CMP #&07 ; BURSTING &4e0b f0 19 BEQ &4e26 ; is_bursting_object &4e0d c9 57 CMP #&57 ; UNBURSTING &4e0f d0 2c BNE &4e3d ; skip_bursting_sound ; is_unbursting_object &4e11 a5 a4 LDA &a4 ; object_is_bursting &4e13 d0 28 BNE &4e3d ; skip_bursting_sound &4e15 e6 a4 INC &a4 ; object_is_bursting # Only play one bursting sound at once &4e17 bc 19 60 LDY &6019,X ; objects_animation &4e1a b9 22 46 LDA &4622,Y ; bursting_pitches &4e1d a2 80 LDX #&80 # Use channel 3 &4e1f 20 04 54 JSR &5404 ; write_frequency_in_A_times_four_to_sound_chip &4e22 a9 95 LDA #&95 # Set channel 3 to volume 10 &4e24 d0 14 BNE &4e3a ; set_volume ; is_bursting_object &4e26 bd 19 60 LDA &6019,X ; objects_animation &4e29 c9 03 CMP #&03 &4e2b f0 10 BEQ &4e3d ; skip_bursting_sound &4e2d a4 a5 LDY &a5 ; object_is_unbursting &4e2f d0 0c BNE &4e3d ; skip_bursting_sound # Only play one unbursting sound at once &4e31 e6 a5 INC &a5 ; object_is_unbursting &4e33 49 e7 EOR #&e7 # Use channel 0, set noise frequency from animation &4e35 20 25 54 JSR &5425 ; write_byte_to_sound_chip &4e38 a9 f7 LDA #&f7 # Set channel 0 to volume 9 ; set_volume &4e3a 20 25 54 JSR &5425 ; write_byte_to_sound_chip ; skip_bursting_sound &4e3d c6 12 DEC &12 ; object_to_consider &4e3f 10 be BPL &4dff ; check_objects_for_bursting_loop &4e41 a6 5a LDX &5a ; fire_object &4e43 bd d7 5f LDA &5fd7,X ; objects_sprite &4e46 c9 5d CMP #&5d ; FIRE &4e48 d0 19 BNE &4e63 ; skip_fire_sound # Is there an active FIRE? &4e4a bd 45 60 LDA &6045,X ; objects_data &4e4d f0 14 BEQ &4e63 ; skip_fire_sound # Is the FIRE on screen? &4e4f e6 66 INC &66 ; fire_pitch_offset &4e51 a5 66 LDA &66 ; fire_pitch_offset &4e53 29 0f AND #&0f &4e55 aa TAX &4e56 bd bb 54 LDA &54bb,X ; fire_pitches &4e59 a2 80 LDX #&80 # Use channel 3 &4e5b 20 04 54 JSR &5404 ; write_frequency_in_A_times_four_to_sound_chip &4e5e a9 94 LDA #&94 # Set channel 3 to volume 11 &4e60 20 25 54 JSR &5425 ; write_byte_to_sound_chip ; skip_fire_sound &4e63 a2 0b LDX #&0b ; FIRST_DEMON_SLOT ; check_demons_for_sound_loop &4e65 bd d7 5f LDA &5fd7,X ; objects_sprite &4e68 c9 37 CMP #&37 ; FIRST_DEMON_SPRITE &4e6a 90 1a BCC &4e86 ; skip_demon_sound # Is there a demon in this slot? &4e6c bd 45 60 LDA &6045,X ; objects_data &4e6f f0 15 BEQ &4e86 ; skip_demon_sound # Is the demon on screen? &4e71 a5 1a LDA &1a ; game_timer &4e73 29 0f AND #&0f &4e75 aa TAX &4e76 bd ab 54 LDA &54ab,X ; demon_pitches &4e79 a2 80 LDX #&80 # Use channel 3 &4e7b 20 04 54 JSR &5404 ; write_frequency_in_A_times_four_to_sound_chip &4e7e a9 94 LDA #&94 # Set channel 3 to volume 11 &4e80 20 25 54 JSR &5425 ; write_byte_to_sound_chip &4e83 4c 8b 4e JMP &4e8b ; break_out_of_loop ; skip_demon_sound &4e86 e8 INX &4e87 e0 0f CPX #&0f ; LAST_DEMON_SLOT + 1 &4e89 d0 da BNE &4e65 ; check_demons_for_sound_loop ; break_out_of_loop ; wait_for_middle_of_screen &4e8b a5 37 LDA &37 ; palette_changing_state # Wait until the main area has been refreshed by the &4e8d d0 fc BNE &4e8b ; wait_for_middle_of_screen # video circuitry before updating it from the buffer &4e8f 20 3a 5f JSR &5f3a ; copy_buffer_to_screen_and_wipe_buffer &4e92 a5 53 LDA &53 ; score_has_changed &4e94 30 03 BMI &4e99 ; skip_plotting_score &4e96 20 0f 4f JSR &4f0f ; plot_score ; skip_plotting_score &4e99 a5 54 LDA &54 ; colour_change_cooldown &4e9b f0 0c BEQ &4ea9 ; skip_resetting_colour &4e9d c6 54 DEC &54 ; colour_change_cooldown &4e9f d0 08 BNE &4ea9 ; skip_resetting_colour &4ea1 a9 07 LDA #&07 ; K # Set main background to black &4ea3 85 03 STA &03 ; main_background_colour &4ea5 a9 81 LDA #&81 ; C # Set main foreground to cyan &4ea7 85 04 STA &04 ; main_foreground_colour ; skip_resetting_colour &4ea9 a5 3a LDA &3a ; demons_have_changed &4eab f0 03 BEQ &4eb0 ; skip_plotting_demons &4ead 20 28 5e JSR &5e28 ; plot_demons_needing_destroying ; skip_plotting_demons &4eb0 20 9b 5f JSR &5f9b ; check_for_pause &4eb3 20 71 52 JSR &5271 ; check_player &4eb6 a5 62 LDA &62 ; demons_destroyed &4eb8 c9 04 CMP #&04 &4eba f0 03 BEQ &4ebf ; to_game_completed # End the game when all four demons have been destroyed &4ebc 4c 94 4d JMP &4d94 ; main_game_loop ; to_game_completed &4ebf 4c fe 52 JMP &52fe ; game_completed ; mark_room_as_visited &4ec2 ae 03 60 LDX &6003 ; objects_x_room &4ec5 e4 56 CPX &56 ; previous_player_x_room &4ec7 d0 08 BNE &4ed1 ; player_has_changed_room &4ec9 ac 9d 60 LDY &609d ; objects_y_room &4ecc c4 57 CPY &57 ; previous_player_y_room &4ece d0 01 BNE &4ed1 ; player_has_changed_room &4ed0 60 RTS ; player_has_changed_room &4ed1 86 56 STX &56 ; previous_player_x_room &4ed3 84 57 STY &57 ; previous_player_y_room &4ed5 20 c4 4a JSR &4ac4 ; get_room_data_byte &4ed8 30 0c BMI &4ee6 ; leave # Leave if room has already been visited &4eda d0 0b BNE &4ee7 ; play_jingle_on_entering_room ; increase_rooms_visited &4edc e6 58 INC &58 ; rooms_visited_low # Score 0.125% for visiting a room for the first time &4ede d0 02 BNE &4ee2 ; set_flag &4ee0 e6 59 INC &59 ; rooms_visited_high ; set_flag &4ee2 09 80 ORA #&80 &4ee4 91 12 STA (&12),Y ; room_data_address # Set top bit of room data to indicate visited ; leave &4ee6 60 RTS ; play_jingle_on_entering_room &4ee7 20 dc 4e JSR &4edc ; increase_rooms_visited &4eea a9 03 LDA #&03 # Play jingle on entering unvisited room &4eec 85 60 STA &60 ; jingle_length &4eee a9 00 LDA #&00 &4ef0 85 5f STA &5f ; jingle_start &4ef2 60 RTS ; increase_score # Called with X = offset into score &4ef3 18 CLC ; increase_score_loop &4ef4 7d 18 4f ADC &4f18,X ; score_text + 2 &4ef7 a0 00 LDY #&00 ; check_for_overflow &4ef9 c9 0a CMP #&0a &4efb 90 06 BCC &4f03 ; skip_overflow &4efd 38 SEC &4efe e9 0a SBC #&0a &4f00 c8 INY &4f01 d0 f6 BNE &4ef9 ; check_for_overflow # Always branches ; skip_overflow &4f03 9d 18 4f STA &4f18,X ; score_text + 2 &4f06 98 TYA &4f07 f0 03 BEQ &4f0c ; no_overflow &4f09 ca DEX &4f0a 10 e7 BPL &4ef3 ; increase_score_loop ; no_overflow &4f0c e6 53 INC &53 ; score_has_changed &4f0e 60 RTS ; plot_score &4f0f a2 16 LDX #&16 &4f11 a0 4f LDY #&4f ; &4f16 = score_text &4f13 4c 02 5f JMP &5f02 ; plot_text ; score_text &4f16 58 10 ; &1058 &4f18 00 00 00 00 00 00 00 ; "0000000" &4f1f ff ; update_objects &4f20 a9 15 LDA #&15 &4f22 85 17 STA &17 ; object_to_consider ; update_objects_loop &4f24 a5 17 LDA &17 ; object_to_consider &4f26 aa TAX &4f27 c9 0b CMP #&0b ; FIRST_DEMON_SLOT &4f29 90 06 BCC &4f31 ; skip_resetting_state &4f2b a9 00 LDA #&00 # Mark demons and imps as off-screen by default &4f2d 9d 45 60 STA &6045,X ; objects_data &4f30 8a TXA ; skip_resetting_state &4f31 0a ASL A &4f32 a8 TAY &4f33 b9 77 4f LDA &4f77,Y ; object_update_routine_address_table &4f36 85 12 STA &12 ; object_update_routine_address_low &4f38 b9 78 4f LDA &4f78,Y ; object_update_routine_address_table + 1 &4f3b 85 13 STA &13 ; object_update_routine_address_high &4f3d 20 74 4f JSR &4f74 ; to_object_update_routine &4f40 a6 17 LDX &17 ; object_to_consider &4f42 bd d7 5f LDA &5fd7,X ; objects_sprite &4f45 f0 28 BEQ &4f6f ; update_next_object &4f47 c9 5d CMP #&5d ; FIRE &4f49 f0 24 BEQ &4f6f ; update_next_object # FIRE is flipped in update_fire every other frame &4f4b c9 57 CMP #&57 ; UNBURSTING &4f4d b0 0c BCS &4f5b ; zero_flipped &4f4f c9 37 CMP #&37 ; FIRST_DEMON_SPRITE &4f51 b0 0c BCS &4f5f ; non_zero_flipped # Demons, imps and player are flipped based on facing &4f53 c9 0b CMP #&0b ; PLAYER_BACK &4f55 f0 08 BEQ &4f5f ; non_zero_flipped &4f57 c9 11 CMP #&11 ; PLAYER_FRONT &4f59 f0 04 BEQ &4f5f ; non_zero_flipped ; zero_flipped &4f5b a9 00 LDA #&00 # All other objects are never flipped &4f5d f0 0d BEQ &4f6c ; set_objects_flipped # Always branches ; non_zero_flipped &4f5f bd 2f 60 LDA &602f,X ; objects_facing &4f62 c9 04 CMP #&04 &4f64 90 02 BCC &4f68 ; not_both_x_and_y &4f66 a9 00 LDA #&00 ; not_both_x_and_y &4f68 29 01 AND #&01 &4f6a 4a LSR A &4f6b 6a ROR A ; set_objects_flipped &4f6c 9d df 60 STA &60df,X ; objects_flipped ; update_next_object &4f6f c6 17 DEC &17 ; object_to_consider &4f71 10 b1 BPL &4f24 ; update_objects_loop &4f73 60 RTS ; to_object_update_routine &4f74 6c 12 00 JMP (&0012) ; object_update_routine_address ; object_update_routine_address_table &4f77 a6 4f ; &4fa6 = update_player &4f79 5c 40 ; &405c = update_fired_antibody &4f7b 5c 40 ; &405c = update_fired_antibody &4f7d 74 40 ; &4074 = update_wild_antibody &4f7f 74 40 ; &4074 = update_wild_antibody &4f81 74 40 ; &4074 = update_wild_antibody &4f83 74 40 ; &4074 = update_wild_antibody &4f85 41 55 ; &5541 = update_weapons &4f87 41 55 ; &5541 = update_weapons &4f89 41 55 ; &5541 = update_weapons &4f8b 41 55 ; &5541 = update_weapons &4f8d 29 43 ; &4329 = update_demon &4f8f 29 43 ; &4329 = update_demon &4f91 29 43 ; &4329 = update_demon &4f93 29 43 ; &4329 = update_demon &4f95 b6 44 ; &44b6 = update_imp &4f97 b6 44 ; &44b6 = update_imp &4f99 b6 44 ; &44b6 = update_imp &4f9b b6 44 ; &44b6 = update_imp &4f9d b6 44 ; &44b6 = update_imp &4f9f b6 44 ; &44b6 = update_imp &4fa1 b1 56 ; &56b1 = update_collectable ; to_update_bursting_object &4fa3 4c d8 40 JMP &40d8 ; update_bursting_object ; update_player &4fa6 ad d7 5f LDA &5fd7 ; objects_sprite &4fa9 c9 0b CMP #&0b ; PLAYER_BACK &4fab 90 f6 BCC &4fa3 ; to_update_bursting_object &4fad a4 23 LDY &23 ; player_height &4faf c0 92 CPY #&92 &4fb1 f0 1d BEQ &4fd0 ; player_is_full_height # Is the player fully present? &4fb3 c8 INY &4fb4 c8 INY &4fb5 84 23 STY &23 ; player_height # If not, increase their height &4fb7 98 TYA &4fb8 38 SEC &4fb9 e9 48 SBC #&48 &4fbb 49 ff EOR #&ff # with accompanying increasing sound &4fbd 4a LSR A &4fbe 18 CLC &4fbf 69 30 ADC #&30 &4fc1 a2 c0 LDX #&c0 # Use channel 1 &4fc3 20 04 54 JSR &5404 ; write_frequency_in_A_times_four_to_sound_chip &4fc6 a9 d4 LDA #&d4 # Set channel 1 to volume 11 &4fc8 20 25 54 JSR &5425 ; write_byte_to_sound_chip &4fcb a6 17 LDX &17 ; object_to_consider &4fcd 4c d6 4f JMP &4fd6 ; skip_movement ; player_is_full_height &4fd0 20 31 51 JSR &5131 ; check_for_player_firing &4fd3 20 e4 4f JSR &4fe4 ; check_for_player_movement ; skip_movement &4fd6 ae 2f 60 LDX &602f ; objects_facing &4fd9 bd e0 4f LDA &4fe0,X ; player_sprites_by_direction &4fdc 8d d7 5f STA &5fd7 ; objects_sprite &4fdf 60 RTS ; player_sprites_by_direction &4fe0 0b 11 11 0b ; check_for_player_movement &4fe4 a2 99 LDX #&99 ; LEFT &4fe6 20 d3 5e JSR &5ed3 ; check_for_keypress &4fe9 30 10 BMI &4ffb ; left_pressed &4feb a2 f9 LDX #&f9 ; RIGHT &4fed 20 d3 5e JSR &5ed3 ; check_for_keypress &4ff0 10 23 BPL &5015 ; check_for_player_walking &4ff2 c6 44 DEC &44 ; player_rotation_cooldown &4ff4 10 1f BPL &5015 ; check_for_player_walking &4ff6 ee 2f 60 INC &602f ; objects_facing &4ff9 10 0e BPL &5009 ; set_player_facing # Always branches ; left_pressed &4ffb a2 f9 LDX #&f9 ; RIGHT &4ffd 20 d3 5e JSR &5ed3 ; check_for_keypress &5000 30 13 BMI &5015 ; check_for_player_walking &5002 c6 44 DEC &44 ; player_rotation_cooldown &5004 10 0f BPL &5015 ; check_for_player_walking &5006 ce 2f 60 DEC &602f ; objects_facing ; set_player_facing &5009 ad 2f 60 LDA &602f ; objects_facing &500c 29 03 AND #&03 &500e 8d 2f 60 STA &602f ; objects_facing &5011 a9 01 LDA #&01 &5013 85 44 STA &44 ; player_rotation_cooldown ; check_for_player_walking &5015 a2 e1 LDX #&e1 ; Z &5017 20 d3 5e JSR &5ed3 ; check_for_keypress &501a 10 57 BPL &5073 ; player_isn't_walking &501c e6 61 INC &61 ; walking_sound_timer &501e a0 66 LDY #&66 &5020 a5 61 LDA &61 ; walking_sound_timer &5022 29 02 AND #&02 # Alternate between lower and higher pitches &5024 f0 02 BEQ &5028 ; use_low_sound &5026 a0 70 LDY #&70 ; use_low_sound &5028 a5 61 LDA &61 ; walking_sound_timer &502a 29 01 AND #&01 # Play sound for walking every two steps &502c d0 0b BNE &5039 ; skip_walking_sound &502e 98 TYA &502f a2 c0 LDX #&c0 # Use channel 1 &5031 20 04 54 JSR &5404 ; write_frequency_in_A_times_four_to_sound_chip &5034 a9 d4 LDA #&d4 # Set channel 1 to volume 11 &5036 20 25 54 JSR &5425 ; write_byte_to_sound_chip ; skip_walking_sound &5039 a6 17 LDX &17 ; object_to_consider &503b ee 19 60 INC &6019 ; objects_animation # Animate player with six frames &503e ad 19 60 LDA &6019 ; objects_animation &5041 c9 06 CMP #&06 &5043 d0 05 BNE &504a ; skip_ceiling &5045 a9 00 LDA #&00 &5047 8d 19 60 STA &6019 ; objects_animation ; skip_ceiling &504a a9 04 LDA #&04 &504c ac b3 60 LDY &60b3 ; objects_speed_x &504f f0 18 BEQ &5069 ; set_player_speeds # Keep player speed zero if player not moving &5051 98 TYA &5052 18 CLC &5053 69 04 ADC #&04 &5055 c9 0c CMP #&0c &5057 90 10 BCC &5069 ; set_player_speeds # Is the player moving fast? &5059 a4 55 LDY &55 ; player_has_boot &505b f0 0a BEQ &5067 ; no_boot &505d c6 55 DEC &55 ; player_has_boot # If so, drain the boot &505f c9 14 CMP #&14 &5061 90 06 BCC &5069 ; set_player_speeds &5063 a9 10 LDA #&10 # Player walks twice as fast with WINGED_BOOT &5065 d0 02 BNE &5069 ; set_player_speeds ; no_boot &5067 a9 08 LDA #&08 ; set_player_speeds &5069 8d b3 60 STA &60b3 ; objects_speed_x &506c 8d c9 60 STA &60c9 ; objects_speed_y &506f 20 7c 50 JSR &507c ; move_object &5072 60 RTS ; player_isn't_walking &5073 a9 00 LDA #&00 &5075 8d b3 60 STA &60b3 ; objects_speed_x &5078 8d c9 60 STA &60c9 ; objects_speed_y &507b 60 RTS ; move_object &507c a6 17 LDX &17 ; object_to_consider &507e bd ed 5f LDA &5fed,X ; objects_x_fraction &5081 48 PHA &5082 bd 03 60 LDA &6003,X ; objects_x_room &5085 48 PHA &5086 bd 87 60 LDA &6087,X ; objects_y_fraction &5089 48 PHA &508a bd 9d 60 LDA &609d,X ; objects_y_room &508d 48 PHA &508e 20 b6 50 JSR &50b6 ; apply_objects_speed &5091 20 bd 5c JSR &5cbd ; check_for_overlap_between_object_and_wall &5094 a6 17 LDX &17 ; object_to_consider &5096 90 19 BCC &50b1 ; keep_new_object_position # Carry clear if no overlap with wall &5098 a9 00 LDA #&00 &509a 9d b3 60 STA &60b3,X ; objects_speed_x # Zero speeds when object hits wall &509d 9d c9 60 STA &60c9,X ; objects_speed_y &50a0 68 PLA &50a1 9d 9d 60 STA &609d,X ; objects_y_room # Restore position before hitting wall &50a4 68 PLA &50a5 9d 87 60 STA &6087,X ; objects_y_fraction &50a8 68 PLA &50a9 9d 03 60 STA &6003,X ; objects_x_room &50ac 68 PLA &50ad 9d ed 5f STA &5fed,X ; objects_x_fraction &50b0 60 RTS ; keep_new_object_position &50b1 68 PLA &50b2 68 PLA &50b3 68 PLA &50b4 68 PLA &50b5 60 RTS ; apply_objects_speed # position facing &50b6 bc 2f 60 LDY &602f,X ; objects_facing # x- y+ 3 4 0 &50b9 f0 3d BEQ &50f8 ; increase_y # \ / \|/ &50bb 88 DEY ; 1 # x 7-x-5 &50bc f0 4d BEQ &510b ; increase_x # / \ /|\ &50be 88 DEY ; 2 # y- x+ 2 6 1 &50bf f0 5d BEQ &511e ; decrease_y &50c1 88 DEY ; 3 &50c2 f0 21 BEQ &50e5 ; decrease_x &50c4 88 DEY ; 4 &50c5 f0 0c BEQ &50d3 ; decrease_x_and_increase_y &50c7 88 DEY ; 5 &50c8 f0 0f BEQ &50d9 ; increase_x_and_increase_y &50ca 88 DEY ; 6 &50cb f0 12 BEQ &50df ; increase_x_and_decrease_y ; decrease_x_and_decrease_y &50cd 20 e5 50 JSR &50e5 ; decrease_x &50d0 4c 1e 51 JMP &511e ; decrease_y ; decrease_x_and_increase_y &50d3 20 e5 50 JSR &50e5 ; decrease_x &50d6 4c f8 50 JMP &50f8 ; increase_y ; increase_x_and_increase_y &50d9 20 0b 51 JSR &510b ; increase_x &50dc 4c f8 50 JMP &50f8 ; increase_y ; increase_x_and_decrease_y &50df 20 0b 51 JSR &510b ; increase_x &50e2 4c 1e 51 JMP &511e ; decrease_y ; decrease_x &50e5 bd ed 5f LDA &5fed,X ; objects_x_fraction &50e8 38 SEC &50e9 fd b3 60 SBC &60b3,X ; objects_speed_x &50ec 9d ed 5f STA &5fed,X ; objects_x_fraction &50ef bd 03 60 LDA &6003,X ; objects_x_room &50f2 e9 00 SBC #&00 &50f4 9d 03 60 STA &6003,X ; objects_x_room &50f7 60 RTS ; increase_y &50f8 bd 87 60 LDA &6087,X ; objects_y_fraction &50fb 18 CLC &50fc 7d c9 60 ADC &60c9,X ; objects_speed_y &50ff 9d 87 60 STA &6087,X ; objects_y_fraction &5102 bd 9d 60 LDA &609d,X ; objects_y_room &5105 69 00 ADC #&00 &5107 9d 9d 60 STA &609d,X ; objects_y_room &510a 60 RTS ; increase_x &510b bd ed 5f LDA &5fed,X ; objects_x_fraction &510e 18 CLC &510f 7d b3 60 ADC &60b3,X ; objects_speed_x &5112 9d ed 5f STA &5fed,X ; objects_x_fraction &5115 bd 03 60 LDA &6003,X ; objects_x_room &5118 69 00 ADC #&00 &511a 9d 03 60 STA &6003,X ; objects_x_room &511d 60 RTS ; decrease_y &511e bd 87 60 LDA &6087,X ; objects_y_fraction &5121 38 SEC &5122 fd c9 60 SBC &60c9,X ; objects_speed_y &5125 9d 87 60 STA &6087,X ; objects_y_fraction &5128 bd 9d 60 LDA &609d,X ; objects_y_room &512b e9 00 SBC #&00 &512d 9d 9d 60 STA &609d,X ; objects_y_room ; leave &5130 60 RTS ; check_for_player_firing &5131 a5 4c LDA &4c ; firing_cooldown &5133 f0 03 BEQ &5138 ; can_fire &5135 c6 4c DEC &4c ; firing_cooldown &5137 60 RTS ; can_fire &5138 a2 80 LDX #&80 ; SHIFT &513a 20 d3 5e JSR &5ed3 ; check_for_keypress &513d 10 f1 BPL &5130 ; leave &513f a6 4a LDX &4a ; pocket_position &5141 f0 ed BEQ &5130 ; leave # Can't fire if pockets are empty &5143 b5 82 LDA &82,X ; pockets - 1 # Consider most recently filled pocket &5145 c9 07 CMP #&07 &5147 90 69 BCC &51b2 ; fire_weapon # Is it a weapon? &5149 a2 02 LDX #&02 ; LAST_FIRED_ANTIBODY_SLOT # If not, it's an antibody ; find_free_slot_loop # Find a free slot for a new fired antibody &514b bc d7 5f LDY &5fd7,X ; objects_sprite &514e f0 13 BEQ &5163 ; found_free_slot &5150 ca DEX &5151 d0 f8 BNE &514b ; find_free_slot_loop &5153 a9 01 LDA #&01 # If both slots are occupied, &5155 18 CLC &5156 65 4d ADC &4d ; oldest_fired_antibody_slot &5158 aa TAX &5159 bd d7 5f LDA &5fd7,X ; objects_sprite &515c c9 07 CMP #&07 ; BURSTING &515e f0 d0 BEQ &5130 ; leave &5160 4c c8 40 JMP &40c8 ; burst_object # burst the oldest of the fired antibodies ; found_free_slot &5163 38 SEC # Convert antibody type into antibody sprite &5164 e9 07 SBC #&07 &5166 0a ASL A &5167 0a ASL A &5168 69 17 ADC #&17 ; FIRST_ANTIBODY_SPRITE &516a a8 TAY &516b 8a TXA &516c 38 SEC &516d e9 01 SBC #&01 &516f 49 01 EOR #&01 &5171 85 4d STA &4d ; oldest_fired_antibody_slot &5173 98 TYA ; add_fired_object &5174 8d c4 51 STA &51c4 ; fired_template # Set sprite &5177 86 20 STX &20 ; fired_slot &5179 8a TXA &517a a2 c4 LDX #&c4 &517c a0 51 LDY #&51 ; &51c4 = fired_antibody_template &517e 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y &5181 a6 20 LDX &20 ; fired_slot &5183 ad ed 5f LDA &5fed ; objects_x_fraction # Put fired object in same position as player &5186 9d ed 5f STA &5fed,X ; objects_x_fraction &5189 ad 03 60 LDA &6003 ; objects_x_room &518c 9d 03 60 STA &6003,X ; objects_x_room &518f ad 87 60 LDA &6087 ; objects_y_fraction &5192 9d 87 60 STA &6087,X ; objects_y_fraction &5195 ad 9d 60 LDA &609d ; objects_y_room &5198 9d 9d 60 STA &609d,X ; objects_y_room &519b ad 2f 60 LDA &602f ; objects_facing &519e 9d 2f 60 STA &602f,X ; objects_facing &51a1 a9 03 LDA #&03 &51a3 85 4c STA &4c ; firing_cooldown &51a5 20 6e 5b JSR &5b6e ; plot_pocket # Remove antibody or weapon from pocket &51a8 c6 4a DEC &4a ; pocket_position &51aa a5 4b LDA &4b ; pocket_screen_position &51ac 38 SEC &51ad e9 10 SBC #&10 &51af 85 4b STA &4b ; pocket_screen_position &51b1 60 RTS ; fire_weapon &51b2 a8 TAY # Convert weapon type into weapon slot &51b3 18 CLC &51b4 69 04 ADC #&04 &51b6 aa TAX &51b7 98 TYA &51b8 bc 01 55 LDY &5501,X ; weapons_inverted_in_pocket - 7; # Uninvert pocket if inverted &51bb 10 b7 BPL &5174 ; add_fired_object &51bd 48 PHA &51be 20 0c 55 JSR &550c ; invert_weapon_in_pocket &51c1 68 PLA &51c2 10 b0 BPL &5174 ; add_fired_object # Always branches ; fired_template &51c4 00 ; sprite (overwritten) &51c5 00 ; x_fraction &51c6 00 ; x_room &51c7 00 ; animation &51c8 00 ; facing &51c9 00 ; data &51ca 10 ; size &51cb 00 ; objects_speed_change_cooldown &51cc 00 ; y_fraction &51cd 00 ; y_room &51ce 14 ; velocity_x &51cf 14 ; velocity_y &51d0 00 ; flipped &51d1 f8 ; x_offset &51d2 04 ; y_offset ; initialise_player &51d3 20 eb 5e JSR &5eeb ; rnd # Pick a room at random for the player to start in &51d6 a8 TAY &51d7 29 03 AND #&03 &51d9 18 CLC &51da 69 61 ADC #&61 # Use &61b9, &62b9, &63b9 or &64b9 for room_data_address &51dc 8d e5 51 STA &51e5 ; room_data_address_high &51df 20 eb 5e JSR &5eeb ; rnd &51e2 aa TAX &51e3 bd b9 61 LDA &61b9,X ; room_data # actually LDA room_data_address,X &51e6 c9 03 CMP #&03 # Don't start player outside or beyond walls &51e8 90 e9 BCC &51d3 ; initialise_player &51ea 8a TXA &51eb 29 1f AND #&1f &51ed 8d f1 52 STA &52f1 ; player_template + 2 # Set x room &51f0 8a TXA &51f1 4a LSR A &51f2 4a LSR A &51f3 4a LSR A &51f4 4a LSR A &51f5 4a LSR A &51f6 85 12 STA &12 ; tmp &51f8 98 TYA &51f9 0a ASL A &51fa 0a ASL A &51fb 0a ASL A &51fc 29 18 AND #&18 &51fe 05 12 ORA &12 ; tmp &5200 8d f8 52 STA &52f8 ; player_template + 9 # Set y room &5203 a9 01 LDA #&01 &5205 8d f3 52 STA &52f3 ; player_template + 4 # Set facing &5208 60 RTS ; player_still_has_energy &5209 a5 18 LDA &18 ; player_energy &520b c9 01 CMP #&01 &520d d0 02 BNE &5211 ; not_last_energy_in_life &520f c6 19 DEC &19 ; player_lives ; not_last_energy_in_life &5211 8a TXA &5212 48 PHA &5213 20 bb 52 JSR &52bb ; plot_partial_life # Update life on screen &5216 68 PLA &5217 aa TAX &5218 18 CLC &5219 60 RTS ; check_for_collision_between_player_and_enemy # Leaves with carry set if no collision &521a ad d7 5f LDA &5fd7 ; objects_sprite &521d c9 0b CMP #&0b ; PLAYER_BACK &521f 90 4b BCC &526c ; leave_with_carry_set # Leave if player is bursting &5221 a5 23 LDA &23 ; player_height &5223 c9 92 CMP #&92 &5225 d0 45 BNE &526c ; leave_with_carry_set # Leave if player isn't fully present &5227 a0 00 LDY #&00 ; PLAYER_SLOT &5229 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &522c b0 3e BCS &526c ; leave_with_carry_set # Leave if player isn't overlapping enemy &522e e0 0f CPX #&0f ; LAST_DEMON_SLOT + 1 &5230 90 04 BCC &5236 ; is_demon &5232 c6 18 DEC &18 ; player_energy # Drain energy if player has collided with imp &5234 10 d3 BPL &5209 ; player_still_has_energy ; is_demon &5236 a5 18 LDA &18 ; player_energy &5238 c9 02 CMP #&02 &523a d0 02 BNE &523e ; skip_life &523c c6 19 DEC &19 ; player_lives # Lose a life if player has collided with demon ; skip_life &523e a9 02 LDA #&02 &5240 85 18 STA &18 ; player_energy &5242 8a TXA &5243 48 PHA &5244 20 bb 52 JSR &52bb ; plot_partial_life # Update life on screen &5247 68 PLA &5248 aa TAX &5249 ad 03 60 LDA &6003 ; objects_x_room # Store player's position for when they unburst &524c 8d f1 52 STA &52f1 ; player_template + 2 # Set x room &524f ad 9d 60 LDA &609d ; objects_y_room &5252 8d f8 52 STA &52f8 ; player_template + 9 # Set y room &5255 ad 2f 60 LDA &602f ; objects_facing &5258 8d f3 52 STA &52f3 ; player_template + 4 # Set facing &525b ad d7 5f LDA &5fd7 ; objects_sprite &525e 8d ef 52 STA &52ef ; player_template # Set sprite &5261 86 12 STX &12 ; x &5263 a2 00 LDX #&00 ; PLAYER_SLOT &5265 20 c8 40 JSR &40c8 ; burst_object # Burst player &5268 a6 12 LDX &12 ; x &526a 18 CLC &526b 60 RTS ; leave_with_carry_set &526c 38 SEC ; leave &526d 60 RTS ; to_game_over_screen &526e 4c 06 53 JMP &5306 ; game_over_screen ; check_player &5271 ad d7 5f LDA &5fd7 ; objects_sprite # Has the player finished bursting? &5274 d0 f7 BNE &526d ; leave &5276 20 aa 53 JSR &53aa ; silence_sound &5279 a5 19 LDA &19 ; player_lives &527b f0 f1 BEQ &526e ; to_game_over_screen # Game over if the player has no more lives &527d a0 02 LDY #&02 # Play tune for losing a life &527f 20 b9 53 JSR &53b9 ; play_tune ; initialise_player_life &5282 a0 52 LDY #&52 ; &52ef = player_template &5284 a2 ef LDX #&ef &5286 a9 00 LDA #&00 &5288 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y # Put player in room &528b a9 02 LDA #&02 &528d 85 18 STA &18 ; player_energy &528f a9 70 LDA #&70 # Player has no height at all &5291 85 23 STA &23 ; player_height &5293 20 0d 45 JSR &450d ; initialise_imps # Remove any imps ; plot_lives &5296 a0 00 LDY #&00 &5298 a5 19 LDA &19 ; player_lives &529a f0 1f BEQ &52bb ; plot_partial_life # Unnecessary; never branches &529c 85 12 STA &12 ; life ; plot_lives_loop &529e a2 0f LDX #&0f ; plot_life_loop &52a0 bd 35 61 LDA &6135,X ; sprite_life &52a3 99 90 0d STA &0d90,Y ; life_screen_address # Plot top third of life &52a6 bd 45 61 LDA &6145,X ; sprite_life + &10 &52a9 99 40 0e STA &0e40,Y ; life_screen_address + &b0 # Plot middle third of life &52ac bd 55 61 LDA &6155,X ; sprite_life + &20 &52af 99 f0 0e STA &0ef0,Y ; life_screen_address + &160 # Plot bottom third of life &52b2 c8 INY &52b3 ca DEX &52b4 10 ea BPL &52a0 ; plot_life_loop &52b6 c6 12 DEC &12 ; life &52b8 d0 e4 BNE &529e ; plot_lives_loop &52ba 60 RTS ; plot_partial_life &52bb a5 19 LDA &19 ; player_lives &52bd f0 05 BEQ &52c4 ; skip_multiply &52bf a2 10 LDX #&10 &52c1 20 21 61 JSR &6121 ; multiply_A_and_X # Calculate screen position offset for life ; skip_multiply &52c4 a8 TAY &52c5 a2 0f LDX #&0f ; plot_partial_life_loop &52c7 a5 18 LDA &18 ; player_energy &52c9 c9 02 CMP #&02 &52cb f0 04 BEQ &52d1 ; bottom_third_empty &52cd bd 55 61 LDA &6155,X ; sprite_life + &20 &52d0 2c a9 00 BIT &00a9 ; bottom_third_empty #52d1 LDA #&00 &52d3 99 f0 0e STA &0ef0,Y ; life_screen_address + &160 # Plot bottom third of life &52d6 a5 18 LDA &18 ; player_energy &52d8 c9 01 CMP #&01 &52da d0 04 BNE &52e0 ; middle_third_empty &52dc bd 45 61 LDA &6145,X ; sprite_life + &10 &52df 2c a9 00 BIT &00a9 ; middle_third_empty #52e0 LDA #&00 &52e2 99 40 0e STA &0e40,Y ; life_screen_address + &b0 # Plot middle third of life &52e5 a9 00 LDA #&00 &52e7 99 90 0d STA &0d90,Y ; life_screen_address # Plot top third of life &52ea c8 INY &52eb ca DEX &52ec 10 d9 BPL &52c7 ; plot_partial_life_loop &52ee 60 RTS ; player_template &52ef 0b ; sprite &52f0 80 ; x_fraction &52f1 00 ; x_room (overwritten) &52f2 00 ; animation &52f3 01 ; facing (overwritten) &52f4 00 ; data &52f5 10 ; size &52f6 00 ; objects_speed_change_cooldown &52f7 80 ; y_fraction &52f8 00 ; y_room (overwritten) &52f9 00 ; velocity_x &52fa 00 ; velocity_y &52fb 00 ; flipped &52fc f4 ; x_offset &52fd 02 ; y_offset ; game_completed &52fe 20 aa 53 JSR &53aa ; silence_sound &5301 a0 01 LDY #&01 # Play tune for completing game &5303 20 b9 53 JSR &53b9 ; play_tune ; game_over_screen &5306 20 3a 5f JSR &5f3a ; copy_buffer_to_screen_and_wipe_buffer &5309 a9 85 LDA #&85 ; G # Set main foreground to green &530b 85 04 STA &04 ; main_foreground_colour &530d a9 07 LDA #&07 ; K # Set main background to black &530f 85 03 STA &03 ; main_background_colour &5311 a2 59 LDX #&59 &5313 a0 53 LDY #&53 ; &5359 = game_over_text # Write "GAME OVER" &5315 20 02 5f JSR &5f02 ; plot_text &5318 a2 65 LDX #&65 &531a a0 53 LDY #&53 ; &5365 = percentage_of_game_text # Write "PERCENTAGE OF GAME" &531c 20 02 5f JSR &5f02 ; plot_text &531f 46 59 LSR &59 ; rooms_visited_high &5321 66 58 ROR &58 ; rooms_visited_low &5323 46 59 LSR &59 ; rooms_visited_high &5325 66 58 ROR &58 ; rooms_visited_low &5327 46 59 LSR &59 ; rooms_visited_high &5329 66 58 ROR &58 ; rooms_visited_low &532b a0 00 LDY #&00 &532d a5 58 LDA &58 ; rooms_visited_low ; divide_into_tens_and_units_loop &532f c9 0a CMP #&0a &5331 90 06 BCC &5339 ; poke_into_score &5333 38 SEC &5334 e9 0a SBC #&0a &5336 c8 INY &5337 d0 f6 BNE &532f ; divide_into_tens_and_units_loop ; poke_into_score &5339 8d 87 53 STA &5387 ; completed_text + 13 # Poke percentage complete into "COMPLETED 00" text &533c 8c 86 53 STY &5386 ; completed_text + 12 &533f a2 7a LDX #&7a &5341 a0 53 LDY #&53 ; &537a = completed_text # Write "COMPLETE " and percentage &5343 20 02 5f JSR &5f02 ; plot_text &5346 a9 cd LDA #&cd &5348 85 51 STA &51 ; vsync_counter ; delay_loop &534a a5 51 LDA &51 ; vsync_counter &534c d0 fc BNE &534a ; delay_loop &534e a0 00 LDY #&00 # Play tune for Game Over &5350 20 b9 53 JSR &53b9 ; play_tune &5353 20 3a 5f JSR &5f3a ; copy_buffer_to_screen_and_wipe_buffer # Wipe screen &5356 4c 22 4d JMP &4d22 ; start_game # Start again! ; game_over_text &5359 28 04 ; &0428 &535b 0e 0a 12 0d 1b 14 19 0d 16 ; "GAME OVER" &5364 ff ; percentage_of_game_text &5365 c0 06 ; &06c0 &5367 15 0d 16 0b 0d 13 18 0a 0e 0d 1b 14 1a 1b 0e 0a ; "PERCENTAGE OF GA" &5377 12 0d ; "ME" &5379 ff ; completed_text &537a e8 08 ; &08e8 &537c 0b 14 12 15 11 0d 18 0d 0c 1b 00 00 ; "COMPLETED 00" &5388 ff ; collect_object # Called with A = object_sprite &5389 a6 4a LDX &4a ; pocket_position &538b e0 0b CPX #&0b &538d f0 1a BEQ &53a9 ; leave # Leave if no free pockets &538f c9 07 CMP #&07 &5391 90 08 BCC &539b ; is_weapon ; is_antibody &5393 38 SEC # Convert sprite into antibody type &5394 e9 17 SBC #&17 # SWIRL = &07, SPIKES = &08, STICKS = &09, BLOB = &0a &5396 4a LSR A &5397 4a LSR A &5398 18 CLC &5399 69 07 ADC #&07 ; is_weapon &539b 95 83 STA &83,X ; pockets &539d e6 4a INC &4a ; pocket_position &539f a5 4b LDA &4b ; pocket_screen_position &53a1 18 CLC &53a2 69 10 ADC #&10 &53a4 85 4b STA &4b ; pocket_screen_position &53a6 4c 6e 5b JMP &5b6e ; plot_pocket ; leave &53a9 60 RTS ; silence_sound &53aa a2 0f LDX #&0f # Pushes &0f, &1f, &2f, &3f, &4f, &5f, &6f and &7f &53ac 8a TXA # which set low four bits of last channel frequency, &53ad 18 CLC # then &8f, &af, &cf and &ef, which set high six bits ; silence_sound_loop # and &9f, &bf, &df, &ff, which set volumes to zero &53ae 20 25 54 JSR &5425 ; write_byte_to_sound_chip &53b1 69 10 ADC #&10 &53b3 ca DEX &53b4 10 f8 BPL &53ae ; silence_sound_loop &53b6 86 5c STX &5c ; note_address_high # Unnecessary &53b8 60 RTS ; play_tune &53b9 b9 5e 54 LDA &545e,Y ; tune_addresses_low_table &53bc 85 5b STA &5b ; note_address_low &53be a9 54 LDA #&54 &53c0 85 5c STA &5c ; note_address_high &53c2 a9 01 LDA #&01 &53c4 85 5e STA &5e ; duration &53c6 a9 d0 LDA #&d0 # Set channel 1 to volume 15 &53c8 20 25 54 JSR &5425 ; write_byte_to_sound_chip ; play_tune_loop ; wait_for_middle_of_screen &53cb a5 37 LDA &37 ; palette_changing_state # Becomes zero in middle of screen &53cd d0 fc BNE &53cb ; wait_for_middle_of_screen &53cf a4 5e LDY &5e ; duration &53d1 f0 d7 BEQ &53aa ; silence_sound # Leave &53d3 88 DEY &53d4 84 5e STY &5e ; duration &53d6 d0 24 BNE &53fc ; wait_for_vsync_two # Has the previous note finished? &53d8 b1 5b LDA (&5b),Y ; note_address # If so, get next note &53da 30 ce BMI &53aa ; silence_sound # Leave if top bit set &53dc aa TAX &53dd bd 3e 54 LDA &543e,X ; pitch_table &53e0 e0 18 CPX #&18 &53e2 b0 0b BCS &53ef ; use_frequency # A + &100 if X < &18 &53e4 c8 INY &53e5 e0 0c CPX #&0c &53e7 b0 06 BCS &53ef ; use_frequency # A + &200 if X < &0c &53e9 c8 INY &53ea e0 05 CPX #&05 &53ec b0 01 BCS &53ef ; use_frequency # A + &300 if X < &05 &53ee c8 INY ; use_frequency &53ef a2 c0 LDX #&c0 # Use channel 1 &53f1 20 10 54 JSR &5410 ; write_frequency_in_A_and_Y_to_sound_chip &53f4 84 5e STY &5e ; duration &53f6 e6 5b INC &5b ; note_address_low &53f8 d0 02 BNE &53fc ; skip_page &53fa e6 5c INC &5c ; note_address_high ; skip_page ; brief_delay &53fc a5 37 LDA &37 ; palette_changing_state # Becomes non-zero at bottom of screen &53fe f0 fc BEQ &53fc ; brief_delay &5400 4c cb 53 JMP &53cb ; play_tune_loop ; leave &5403 60 RTS ; write_frequency_in_A_times_four_to_sound_chip # Call with A = frequency / 4 &5404 a0 00 LDY #&00 &5406 84 5d STY &5d ; tmp &5408 0a ASL A &5409 66 5d ROR &5d ; tmp &540b 0a ASL A &540c 66 5d ROR &5d ; tmp &540e a4 5d LDY &5d ; tmp ; write_frequency_in_A_and_Y_to_sound_chip # Called with A = frequency lsb, Y = frequency msb &5410 86 5d STX &5d ; register_bits # X sets channel &5412 aa TAX &5413 29 0f AND #&0f # Low four bits of frequency &5415 05 5d ORA &5d ; register_bits &5417 84 5d STY &5d ; frequency_msb &5419 20 25 54 JSR &5425 ; write_byte_to_sound_chip # Set channel and low four bits of frequency &541c 8a TXA &541d 66 5d ROR &5d ; frequency_msb &541f 6a ROR A &5420 66 5d ROR &5d ; frequency_msb &5422 6a ROR A &5423 4a LSR A &5424 4a LSR A # Set high six bits of frequency ; write_byte_to_sound_chip &5425 a4 05 LDY &05 ; sound_enabled &5427 f0 14 BEQ &543d ; leave &5429 a0 ff LDY #&ff # Set all bits to output &542b 8c 43 fe STY &fe43 ; System VIA data direction register A &542e 8d 41 fe STA &fe41 ; System VIA output register A &5431 c8 INY # Set sound chip write pin low &5432 8c 40 fe STY &fe40 ; System VIA port B input/output register &5435 ea NOP &5436 ea NOP &5437 ea NOP &5438 a0 08 LDY #&08 # Set sound chip write pin high &543a 8c 40 fe STY &fe40 ; System VIA port B input/output register ; leave &543d 60 RTS ; pitch_table &543e f4 bb 85 53 23 # + &300 &5443 f6 cb a3 7d 59 38 18 # + &200 &544a fa dd c2 a9 91 7b 65 51 3e 2c 1c 0c # + &100 &5456 fd ee e1 d4 c8 bd b2 a8 # ; tune_addresses_low_table &545e 62 79 99 a0 ; tune_0_data # Played on Game Over screen &5462 1b 18 13 18 13 0f 13 0f 0c 0f 0c 07 08 0c 0f 07 &5472 0c 0f 0e 0c 0b 0c ff ; tune_1_data # Played on completing game &5479 1a 18 1b 1b 1a 16 13 1a 18 14 11 18 18 13 0f 11 &5489 13 18 1b 1b 1a 16 13 12 13 11 0f 0e 0c 0c 0c ff ; tune_2_data # Played on losing a life &5499 13 12 11 10 0f 0f ff ; tune_3_data # Played on starting game &54a0 13 18 1b 18 1b 1f 13 15 17 18 ff ; demon_pitches &54ab 20 20 30 30 40 40 50 50 60 60 70 70 80 80 90 90 ; fire_pitches &54bb 20 50 40 30 20 20 50 40 30 20 20 50 40 30 20 20 ; jingle_pitches &54cb 70 40 70 # Played on entry to unvisited room &54ce 40 50 60 70 50 # Played on collection of WINGED_BOOT &54d3 80 80 80 70 60 50 40 # Played on collection of POTION &54da 60 30 60 30 # Played on destruction of demon ; invert_weapons_for_nearby_demons &54de a2 0e LDX #&0e ; LAST_DEMON_SLOT # For each demon, &5de0 bd d7 5f LDA &5fd7,X ; objects_sprite &54e3 c9 37 CMP #&37 ; FIRST_DEMON_SPRITE &54e5 90 17 BCC &54fe ; consider_next_weapon # Has the demon been destroyed? If not, &54e7 bd d3 5f LDA &5fd3,X ; objects_sprite - 4 &54ea d0 12 BNE &54fe ; consider_next_weapon # Is the corresponding weapon in a pocket? If so, &54ec a9 05 LDA #&05 &54ee 20 8a 44 JSR &448a ; check_if_object_is_near_player &54f1 b0 0b BCS &54fe ; consider_next_weapon # Is the demon near the player? &54f3 86 12 STX &12 ; slot &54f5 ca DEX &54f6 ca DEX &54f7 ca DEX &54f8 ca DEX &54f9 20 0c 55 JSR &550c ; invert_weapon_in_pocket # If so, make the weapon flash in the pocket &54fc a6 12 LDX &12 ; slot ; consider_next_weapon &54fe ca DEX &54ff e0 0a CPX #&0a ; FIRST_DEMON_SLOT - 1 &5501 d0 dd BNE &54e0 &5503 60 RTS ; weapons_pocket_screen_positions &5504 00 00 00 00 ; weapons_inverted_in_pocket &5508 00 00 00 00 ; invert_weapon_in_pocket &550c 86 13 STX &13 ; slot &550e bc fd 54 LDY &54fd,X ; weapons_pocket_screen_positions - 7 &5511 a2 0f LDX #&0f ; invert_weapon_in_pocket_loop &5513 98 TYA &5514 29 07 AND #&07 &5516 f0 08 BEQ &5520 ; skip_row &5518 a9 ff LDA #&ff &551a 59 20 0c EOR &0c20,Y ; pockets_screen_address &551d 99 20 0c STA &0c20,Y ; pockets_screen_address ; skip_row &5520 98 TYA &5521 29 07 AND #&07 &5523 c9 07 CMP #&07 &5525 f0 08 BEQ &552f ; skip_row_two &5527 a9 ff LDA #&ff &5529 59 d0 0c EOR &0cd0,Y ; pockets_screen_address + &b0 &552c 99 d0 0c STA &0cd0,Y ; pockets_screen_address + &b0 ; skip_row_two &552f c8 INY &5530 ca DEX &5531 10 e0 BPL &5513 ; invert_weapon_in_pocket_loop &5533 a6 13 LDX &13 ; slot &5535 bd 01 55 LDA &5501,X ; weapons_inverted_in_pocket - 7; &5538 49 ff EOR #&ff &553a 9d 01 55 STA &5501,X ; weapons_inverted_in_pocket - 7; &553d 60 RTS ; to_update_bursting_object &553e 4c d8 40 JMP &40d8 ; update_bursting_object ; update_weapons &5541 bd d7 5f LDA &5fd7,X ; objects_sprite &5544 f0 48 BEQ &558e ; leave # Is there a weapon in this slot? &5546 c9 07 CMP #&07 ; BURSTING &5548 f0 f4 BEQ &553e ; to_update_bursting_object &554a 20 7c 50 JSR &507c ; move_object &554d bd b3 60 LDA &60b3,X ; objects_speed_x &5550 d0 26 BNE &5578 ; weapon_is_being_fired # Is it being fired? &5552 a0 00 LDY #&00 ; PLAYER_SLOT # If not, it's a collectable object &5554 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &5557 b0 35 BCS &558e ; leave # Is the player collecting it? &5559 a5 4a LDA &4a ; pocket_position &555b c9 0b CMP #&0b &555d f0 2f BEQ &558e ; leave # Leave if pockets are full &555f bc d7 5f LDY &5fd7,X ; objects_sprite &5562 a9 00 LDA #&00 # Remove weapon from screen &5564 9d d7 5f STA &5fd7,X ; objects_sprite &5567 9d 01 55 STA &5501,X ; weapons_inverted_in_pocket - 7; # Mark weapon as uninverted in pocket &556a 8a TXA &556b 48 PHA &556c 98 TYA &556d 20 89 53 JSR &5389 ; collect_object # Put weapon in pocket &5570 68 PLA &5571 aa TAX &5572 a5 4b LDA &4b ; pocket_screen_position &5574 9d fd 54 STA &54fd,X ; weapons_pocket_screen_positions - 7 &5577 60 RTS ; weapon_is_being_fired &5578 a0 0b LDY #&0b ; FIRST_DEMON_SLOT ; check_for_collision_between_weapon_and_demon_loop &557a 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &557d b0 0a BCS &5589 ; consider_next_demon # Has the weapon hit a demon? &557f 98 TYA &5580 38 SEC &5581 e9 04 SBC #&04 &5583 85 12 STA &12 ; weapon_required &5585 e4 12 CPX &12 ; weapon_required # If so, is it the right weapon to destroy the demon? &5587 f0 06 BEQ &558f ; destroy_demon ; consider_next_demon &5589 c8 INY &558a c0 0f CPY #&0f ; LAST_DEMON_SLOT + 1 &558c d0 ec BNE &557a ; check_for_collision_between_weapon_and_demon_loop ; leave &558e 60 RTS ; destroy_demon # Called with Y = demon to be destroyed &558f 20 c8 40 JSR &40c8 ; burst_object &5592 a2 03 LDX #&03 ; FIRST_WILD_ANTIBODY_SLOT &5594 a5 58 LDA &58 ; rooms_visited_low &5596 18 CLC &5597 69 2a ADC #&2a # Score 5.25% for destroying demon &5599 85 58 STA &58 ; rooms_visited_low &559b 90 02 BCC &559f ; skip_overflow &559d e6 59 INC &59 ; rooms_visited_high ; skip_overflow &559f a9 80 LDA #&80 ; W # Set main foreground to white &55a1 85 04 STA &04 ; main_foreground_colour &55a3 86 12 STX &12 ; slot &55a5 98 TYA &55a6 18 CLC &55a7 65 65 ADC &65 ; random_number_for_demon_destruction_colours &55a9 29 03 AND #&03 &55ab aa TAX &55ac bd fe 55 LDA &55fe,X ; demon_destruction_colours # Choose a random background colour &55af 85 03 STA &03 ; main_background_colour &55b1 85 54 STA &54 ; colour_change_cooldown # Don't revert the changed colours &55b3 a6 12 LDX &12 ; slot ; add_exploding_demon_antibodies_loop &55b5 20 7b 42 JSR &427b ; copy_object_Y_into_object_X # Copy demon position into slot X &55b8 a9 00 LDA #&00 &55ba 9d df 60 STA &60df,X ; objects_flipped &55bd 9d 19 60 STA &6019,X ; objects_animation &55c0 8a TXA &55c1 38 SEC &55c2 e9 03 SBC #&03 &55c4 9d 2f 60 STA &602f,X ; objects_facing &55c7 b9 d7 5f LDA &5fd7,Y ; objects_sprite # Turn demon sprite into antibody sprite &55ca 38 SEC &55cb e9 37 SBC #&37 ; FIRST_DEMON_SPRITE &55cd 29 0c AND #&0c &55cf 18 CLC &55d0 69 17 ADC #&17 &55d2 9d d7 5f STA &5fd7,X ; objects_sprite &55d5 a9 ff LDA #&ff # Top bit set to indicate exploding demon antibody &55d7 9d 45 60 STA &6045,X ; objects_data &55da a9 0c LDA #&0c &55dc 9d b3 60 STA &60b3,X ; objects_speed_x &55df 9d c9 60 STA &60c9,X ; objects_speed_y &55e2 e8 INX &55e3 e0 07 CPX #&07 ; LAST_WILD_ANTIBODY_SLOT + 1 &55e5 d0 ce BNE &55b5 ; add_exploding_demon_antibodies_loop &55e7 98 TYA &55e8 aa TAX &55e9 20 c8 40 JSR &40c8 ; burst_object # Burst demon &55ec 20 28 5e JSR &5e28 ; plot_demons_needing_destroying &55ef a9 0f LDA #&0f # Play jingle for destroying demon &55f1 85 5f STA &5f ; jingle_start &55f3 a9 04 LDA #&04 &55f5 85 60 STA &60 ; jingle_length &55f7 a9 19 LDA #&19 &55f9 a2 02 LDX #&02 # Score 250000 points for killing demon &55fb 4c f3 4e JMP &4ef3 ; increase_score ; demon_destruction_colours &55fe 06 03 02 05 ; R B M G ; initialise_weapons &5602 a2 07 LDX #&07 ; FIRST_WEAPON_SLOT ; initialise_weapons_loop &5604 86 20 STX &20 ; weapon_slot ; choose_random_room &5606 20 eb 5e JSR &5eeb ; rnd &5609 29 1f AND #&1f &560b aa TAX &560c 20 eb 5e JSR &5eeb ; rnd &560f 29 1f AND #&1f &5611 a8 TAY &5612 20 c4 4a JSR &4ac4 ; get_room_data_byte # Stores X and Y in room_x and room_y &5615 c9 03 CMP #&03 # Don't put weapons outside or beyond walls &5617 90 ed BCC &5606 ; choose_random_room &5619 a2 3b LDX #&3b &561b a0 56 LDY #&56 ; &563b = weapon_or_collectable_template &561d a5 20 LDA &20 ; weapon_slot &561f 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y &5622 a6 20 LDX &20 ; weapon_slot # Convert weapon slot into weapon sprite &5624 8a TXA &5625 38 SEC &5626 e9 04 SBC #&04 &5628 9d d7 5f STA &5fd7,X ; objects_sprite &562b a5 21 LDA &21 ; room_x &562d 9d 03 60 STA &6003,X ; objects_x_room &5630 a5 22 LDA &22 ; room_y &5632 9d 9d 60 STA &609d,X ; objects_y_room &5635 e8 INX &5636 e0 0b CPX #&0b ; LAST_WEAPON_SLOT + 1 &5638 d0 ca BNE &5604 ; initialise_weapons_loop &563a 60 RTS ; weapon_or_collectable_template &563b 00 ; sprite &563c 80 ; x_fraction &563d 00 ; x_room &563e 00 ; animation &563f 00 ; facing &5640 00 ; data &5641 10 ; size &5642 00 ; objects_speed_change_cooldown &5643 80 ; y_fraction &5644 00 ; y_room &5645 00 ; velocity_x &5646 00 ; velocity_y &5647 00 ; flipped &5648 f4 ; x_offset &5649 04 ; y_offset ; summon_collectable &564a ad ec 5f LDA &5fec ; objects_sprite + &15 &564d d0 61 BNE &56b0 ; leave # Is there a collectable already present? If so, leave &564f a2 3b LDX #&3b &5651 a0 56 LDY #&56 ; &563b = weapon_or_collectable_template &5653 a9 15 LDA #&15 &5655 20 ad 5f JSR &5fad ; initialise_object_A_from_data_at_X_Y &5658 20 eb 5e JSR &5eeb ; rnd &565b 29 07 AND #&07 &565d 18 CLC &565e 69 fc ADC #&fc &5660 18 CLC &5661 6d 03 60 ADC &6003 ; objects_x_room # Choose a random room within three to either side &5664 29 1f AND #&1f &5666 aa TAX &5667 20 eb 5e JSR &5eeb ; rnd &566a 29 07 AND #&07 &566c 18 CLC &566d 69 fc ADC #&fc &566f 18 CLC &5670 6d 9d 60 ADC &609d ; objects_y_room # in both x and y &5673 29 1f AND #&1f &5675 a8 TAY &5676 20 c4 4a JSR &4ac4 ; get_room_data_byte # Stores X and Y in room_x and room_y &5679 c9 03 CMP #&03 &567b 90 33 BCC &56b0 ; leave # Don't put collectable outside or beyond walls &567d a5 21 LDA &21 ; room_x &567f 8d 18 60 STA &6018 ; objects_x_room + &15 &5682 a5 22 LDA &22 ; room_y &5684 8d b2 60 STA &60b2 ; objects_y_room + &15 &5687 a2 15 LDX #&15 &5689 a9 04 LDA #&04 &568b 20 8a 44 JSR &448a ; check_if_object_is_near_player &568e b0 20 BCS &56b0 ; leave # Avoid wrapping around edges of map &5690 a5 01 LDA &01 ; rnd_1 &5692 29 01 AND #&01 # Choose either WINGED_BOOT or POTION at random &5694 18 CLC &5695 69 01 ADC #&01 ; WINGED_BOOT &5697 8d ec 5f STA &5fec ; objects_sprite + &15 &569a 20 eb 5e JSR &5eeb ; rnd &569d 29 7f AND #&7f # Position collectable randomly in middle of room &569f 18 CLC &56a0 69 40 ADC #&40 &56a2 8d 02 60 STA &6002 ; objects_x_fraction + &15 &56a5 20 eb 5e JSR &5eeb ; rnd &56a8 29 7f AND #&7f &56aa 18 CLC &56ab 69 40 ADC #&40 &56ad 8d 9c 60 STA &609c ; objects_y_fraction + &15 ; leave &56b0 60 RTS ; update_collectable &56b1 bd d7 5f LDA &5fd7,X ; objects_sprite &56b4 f0 fa BEQ &56b0 ; leave # Is there a collectable in this slot? If not, leave &56b6 c9 07 CMP #&07 ; BURSTING &56b8 f0 4a BEQ &5704 ; to_update_bursting_object &56ba a9 04 LDA #&04 # Is the collectable too distant? &56bc 20 8a 44 JSR &448a ; check_if_object_is_near_player &56bf 90 06 BCC &56c7 ; check_if_player_can_collect_collectable &56c1 a9 00 LDA #&00 # If so, remove it &56c3 9d d7 5f STA &5fd7,X ; objects_sprite &56c6 60 RTS ; check_if_player_can_collect_collectable &56c7 a0 00 LDY #&00 ; PLAYER_SLOT &56c9 20 a8 42 JSR &42a8 ; check_for_overlap_between_objects_X_and_Y &56cc b0 35 BCS &5703 ; leave # Leave if not touching player &56ce bc d7 5f LDY &5fd7,X ; objects_sprite &56d1 a9 07 LDA #&07 ; BURSTING # Burst the collectable &56d3 9d d7 5f STA &5fd7,X ; objects_sprite &56d6 c0 01 CPY #&01 ; WINGED_BOOT &56d8 f0 1d BEQ &56f7 ; is_winged_boot ; is_potion &56da a5 19 LDA &19 ; player_lives &56dc c9 05 CMP #&05 &56de f0 d0 BEQ &56b0 ; leave # POTION does nothing if all four lives are full &56e0 a5 18 LDA &18 ; player_energy &56e2 c9 02 CMP #&02 &56e4 f0 ca BEQ &56b0 ; leave # POTION does nothing if last life is full &56e6 a9 02 LDA #&02 &56e8 85 18 STA &18 ; player_energy &56ea e6 19 INC &19 ; player_lives # POTION tops up partial life to full &56ec a9 08 LDA #&08 # Play jingle for collecting POTION &56ee 85 5f STA &5f ; jingle_start &56f0 a9 07 LDA #&07 &56f2 85 60 STA &60 ; jingle_length &56f4 4c 96 52 JMP &5296 ; plot_lives ; is_winged_boot &56f7 a9 ff LDA #&ff # WINGED_BOOT gives 255 steps of double speed &56f9 85 55 STA &55 ; player_has_boot &56fb a9 03 LDA #&03 # Play jingle for collecting WINGED_BOOT &56fd 85 5f STA &5f ; jingle_start &56ff a9 05 LDA #&05 &5701 85 60 STA &60 ; jingle_length ; leave &5703 60 RTS ; to_update_bursting_object &5704 4c d8 40 JMP &40d8 ; update_bursting_object ; calculate_object_sprite_address &5707 a6 17 LDX &17 ; object_to_consider &5709 bd d7 5f LDA &5fd7,X ; objects_sprite &570c 18 CLC &570d 7d 19 60 ADC &6019,X ; objects_animation ; calculate_sprite_address &5710 0a ASL A &5711 a8 TAY &5712 b9 fe 10 LDA &10fe,Y ; sprite_address_table - 1 &5715 85 0c STA &0c ; sprite_address_low &5717 b9 ff 10 LDA &10ff,Y ; sprite_address_table - 1 &571a 85 0d STA &0d ; sprite_address_high &571c a0 00 LDY #&00 &571e b1 0c LDA (&0c),Y ; sprite_address # First byte of sprite data is offset to mask &5720 18 CLC &5721 65 0c ADC &0c ; sprite_address_low &5723 85 0e STA &0e ; mask_address_low &5725 a5 0d LDA &0d ; sprite_address_high &5727 69 00 ADC #&00 &5729 85 0f STA &0f ; mask_address_high &572b c8 INY &572c b1 0c LDA (&0c),Y ; sprite_address # Second byte of sprite data is sprite width (in bytes) &572e 85 33 STA &33 ; sprite_width &5730 c8 INY &5731 b1 0c LDA (&0c),Y ; sprite_address # Third byte of sprite data is sprite height (in rows) &5733 85 2d STA &2d ; height_of_column ; leave &5735 60 RTS ; plot_object &5736 20 74 5a JSR &5a74 ; calculate_object_screen_x_and_y &5739 a6 17 LDX &17 ; object_to_consider &573b a5 30 LDA &30 ; screen_x_high &573d d0 f6 BNE &5735 ; leave # Leave if object is beyond the left or right of screen &573f a5 2f LDA &2f ; screen_x_low &5741 18 CLC &5742 7d f5 60 ADC &60f5,X ; objects_x_offset &5745 c9 d0 CMP #&d0 &5747 b0 ec BCS &5735 ; leave # Leave if object is beyond the right of the screen &5749 c9 18 CMP #&18 &574b 90 e8 BCC &5735 ; leave # Leave if object is beyond the left of the screen &574d 85 2f STA &2f ; screen_x_low &574f a5 32 LDA &32 ; screen_y_high &5751 d0 e2 BNE &5735 ; leave # Leave if object is beyond the top or bottom of screen &5753 a5 31 LDA &31 ; screen_y_low &5755 18 CLC &5756 7d 0b 61 ADC &610b,X ; objects_y_offset &5759 c9 b8 CMP #&b8 # Leave if object is beyond the top of the screen &575b b0 d8 BCS &5735 ; leave &575d 85 31 STA &31 ; screen_y_low &575f 20 07 57 JSR &5707 ; calculate_object_sprite_address &5762 a9 b8 LDA #&b8 &5764 e0 00 CPX #&00 &5766 d0 02 BNE &576a ; not_player ; plot_object_without_initialisation &5768 a5 23 LDA &23 ; player_height # Crop the player if not fully present ; not_player &576a 85 13 STA &13 ; maximum_y &576c a9 03 LDA #&03 &576e 85 43 STA &43 ; sprite_offset &5770 a4 31 LDY &31 ; screen_y_low &5772 84 12 STY &12 ; y &5774 c0 48 CPY #&48 &5776 90 0d BCC &5785 ; cropped_at_bottom # Does the sprite start before the bottom of the screen? &5778 a5 13 LDA &13 ; maximum_y # If not, does it end after the top of the screen? &577a 38 SEC &577b e5 12 SBC &12 ; y &577d c5 2d CMP &2d ; height_of_column &577f b0 26 BCS &57a7 ; plot_from_y ; cropped_at_top &5781 85 2d STA &2d ; height_of_column # If so, crop sprite to stop plotting at top of screen &5783 d0 22 BNE &57a7 ; plot_from_y # Always branches ; cropped_at_bottom &5785 a9 48 LDA #&48 &5787 38 SEC &5788 e5 12 SBC &12 ; y &578a 85 13 STA &13 ; cropped_height &578c a5 2d LDA &2d ; height_of_column &578e 38 SEC &578f e5 13 SBC &13 ; cropped_height &5791 f0 a2 BEQ &5735 ; leave &5793 30 a0 BMI &5735 ; leave # Leave if sprite ends before the bottom of the screen &5795 85 2d STA &2d ; height_of_column # Otherwise, crop sprite to start at bottom of screen &5797 a5 33 LDA &33 ; sprite_width &5799 a6 13 LDX &13 ; cropped_height &579b 20 21 61 JSR &6121 ; multiply_A_and_X # calculating new start of sprite data &579e 18 CLC &579f 69 03 ADC #&03 &57a1 85 43 STA &43 ; sprite_offset &57a3 a0 48 LDY #&48 # Start plotting at bottom of screen &57a5 d0 02 BNE &57a9 ; plot_from_Y # Always branches ; plot_from_y &57a7 a4 12 LDY &12 ; y ; plot_from_Y &57a9 a6 2f LDX &2f ; screen_x_low &57ab 20 31 5a JSR &5a31 ; calculate_buffer_address_from_X_and_Y &57ae e6 2d INC &2d ; height_of_column &57b0 a6 17 LDX &17 ; object_to_consider &57b2 e0 0b CPX #&0b ; FIRST_DEMON_SLOT # Set if player, fired antibodies, demons and imps &57b4 b0 04 BCS &57ba ; set_data &57b6 e0 03 CPX #&03 ; FIRST_WILD_ANTIBODY_SLOT # Don't set for wild antibodies &57b8 b0 03 BCS &57bd ; skip_data ; set_data &57ba fe 45 60 INC &6045,X ; objects_data # Set to non-zero to indicate object is on screen ; skip_data &57bd a5 2f LDA &2f ; screen_x_low &57bf 29 06 AND #&06 &57c1 f0 03 BEQ &57c6 ; plot_aligned_object # Does the sprite need to be shifted before plotting? &57c3 4c 4b 59 JMP &594b ; shift_sprite_and_mask_data ; plot_aligned_object &57c6 bd df 60 LDA &60df,X ; objects_flipped &57c9 10 46 BPL &5811 ; plot_unflipped_object ; plot_flipped_object &57cb a2 05 LDX #&05 ; offset_for_flipped_mask_address_low &57cd a5 0e LDA &0e ; mask_address_low &57cf 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &57d2 a5 0f LDA &0f ; mask_address_high &57d4 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &57d7 a2 0b LDX #&0b ; offset_for_flipped_sprite_address_low &57d9 a5 0c LDA &0c ; sprite_address_low &57db 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &57de a5 0d LDA &0d ; sprite_address_high ; plot_flipped_object_after_shifting &57e0 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &57e3 a5 33 LDA &33 ; sprite_width &57e5 0a ASL A &57e6 aa TAX &57e7 bd f4 57 LDA &57f4,X ; plot_next_row_of_flipped_object_addresses_table - 4 &57ea 8d 48 59 STA &5948 ; plot_next_row_of_flipped_object_address_low &57ed bd f5 57 LDA &57f5,X ; plot_next_row_of_flipped_object_addresses_table - 4 + 1 &57f0 8d 49 59 STA &5949 ; plot_next_row_of_flipped_object_address_high &57f3 a6 43 LDX &43 ; sprite_offset &57f5 4c 43 59 JMP &5943 ; plot_next_row_of_flipped_object ; plot_next_row_of_flipped_object_addresses_table &57f8 04 59 ; &5904 = plot_row_of_flipped_object_10 &57fa ef 58 ; &58ef = plot_row_of_flipped_object_18 &57fc da 58 ; &58da = plot_row_of_flipped_object_18 &57fe c5 58 ; &58c5 = plot_row_of_flipped_object_20 ; poke_byte_into_plot_row_of_flipped_object_code &5800 9d c5 58 STA &58c5,X ; plot_row_of_flipped_object_20 &5803 9d da 58 STA &58da,X ; plot_row_of_flipped_object_18 &5806 9d ef 58 STA &58ef,X ; plot_row_of_flipped_object_10 &5809 9d 04 59 STA &5904,X ; plot_row_of_flipped_object_08 &580c 9d 19 59 STA &5919,X ; plot_row_of_flipped_object_00 &580f e8 INX &5810 60 RTS ; plot_unflipped_object &5811 a2 05 LDX #&05 ; offset_for_unflipped_mask_address_low &5813 a5 0e LDA &0e ; mask_address_low &5815 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &5818 a5 0f LDA &0f ; mask_address_high &581a 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &581d e8 INX ; offset_for_unflipped_sprite_address_low &581e a5 0c LDA &0c ; sprite_address_low &5820 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &5823 a5 0d LDA &0d ; sprite_address_high ; plot_unflipped_object_after_shifting &5825 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &5828 a6 33 LDX &33 ; sprite_width &582a bd ae 58 LDA &58ae,X ; branch_offsets - 2 &582d 8d ae 58 STA &58ae ; plot_next_row_of_unflipped_object_branch &5830 ca DEX &5831 8a TXA &5832 0a ASL A &5833 0a ASL A &5834 0a ASL A &5835 8d 8a 58 STA &588a ; plot_row_of_unflipped_object_Y_20 &5838 38 SEC &5839 e9 08 SBC #&08 &583b 8d 7d 58 STA &587d ; plot_row_of_unflipped_object_Y_18 &583e 38 SEC &583f e9 08 SBC #&08 &5841 8d 70 58 STA &5870 ; plot_row_of_unflipped_object_Y_10 &5844 38 SEC &5845 e9 08 SBC #&08 &5847 8d 63 58 STA &5863 ; plot_row_of_unflipped_object_Y_08 &584a 38 SEC &584b e9 08 SBC #&08 &584d 8d 56 58 STA &5856 ; plot_row_of_unflipped_object_Y_00 &5850 a6 43 LDX &43 ; sprite_offset &5852 4c ab 58 JMP &58ab ; plot_next_row_of_unflipped_object ; plot_row_of_unflipped_object_00 &5855 a0 00 LDY #&00 # actually LDY plot_row_of_unflipped_object_Y_00 &5857 b1 2b LDA (&2b),Y ; buffer_address &5859 3d ff ff AND &ffff,X # actually AND mask_address,X &585c 1d ff ff ORA &ffff,X &585f 91 2b STA (&2b),Y ; buffer_address &5861 e8 INX ; plot_row_of_unflipped_object_08 &5862 a0 08 LDY #&08 # actually LDY plot_row_of_unflipped_object_Y_08 &5864 b1 2b LDA (&2b),Y ; buffer_address &5866 3d ff ff AND &ffff,X # actually AND mask_address,X &5869 1d ff ff ORA &ffff,X # actually ORA sprite_address,X &586c 91 2b STA (&2b),Y ; buffer_address &586e e8 INX ; plot_row_of_unflipped_object_10 &586f a0 10 LDY #&10 # actually LDY plot_row_of_unflipped_object_Y_10 &5871 b1 2b LDA (&2b),Y ; buffer_address &5873 3d ff ff AND &ffff,X # actually AND mask_address,X &5876 1d ff ff ORA &ffff,X # actually ORA sprite_address,X &5879 91 2b STA (&2b),Y ; buffer_address &587b e8 INX ; plot_row_of_unflipped_object_18 &587c a0 18 LDY #&18 # actually LDY plot_row_of_unflipped_object_Y_18 &587e b1 2b LDA (&2b),Y ; buffer_address &5880 3d ff ff AND &ffff,X # actually AND mask_address,X &5883 1d ff ff ORA &ffff,X # actually ORA sprite_address,X &5886 91 2b STA (&2b),Y ; buffer_address &5888 e8 INX ; plot_row_of_unflipped_object_20 &5889 a0 20 LDY #&20 # actually LDY plot_row_of_unflipped_object_Y_20 &588b b1 2b LDA (&2b),Y ; buffer_address &588d 3d ff ff AND &ffff,X # actually AND mask_address,X &5890 1d ff ff ORA &ffff,X # actually ORA sprite_address,X &5893 91 2b STA (&2b),Y ; buffer_address &5895 e8 INX &5896 a5 2b LDA &2b ; buffer_address_low &5898 29 07 AND #&07 &589a d0 0d BNE &58a9 ; not_group &589c a5 2b LDA &2b ; buffer_address_low &589e 38 SEC &589f e9 b9 SBC #&b9 &58a1 85 2b STA &2b ; buffer_address_low &58a3 b0 06 BCS &58ab ; plot_next_row_of_unflipped_object &58a5 c6 2c DEC &2c ; buffer_address_high &58a7 d0 02 BNE &58ab ; plot_next_row_of_unflipped_object ; not_group &58a9 c6 2b DEC &2b ; buffer_address_low ; plot_next_row_of_unflipped_object &58ab c6 2d DEC &2d ; height_of_column &58ad d0 a6 BNE &5855 ; plot_row_of_unflipped_object_00 # actually BNE plot_next_row_of_unflipped_object_branch &58af 60 RTS ; branch_offsets &58b0 cd c0 b3 a6 # Offsets for plot_row_of_unflipped_object_18,10,08,00 ; poke_byte_into_plot_row_of_unflipped_object_code &58b4 9d 55 58 STA &5855,X ; plot_row_of_unflipped_object_00 &58b7 9d 62 58 STA &5862,X ; plot_row_of_unflipped_object_08 &58ba 9d 6f 58 STA &586f,X ; plot_row_of_unflipped_object_10 &58bd 9d 7c 58 STA &587c,X ; plot_row_of_unflipped_object_08 &58c0 9d 89 58 STA &5889,X ; plot_row_of_unflipped_object_20 &58c3 e8 INX &58c4 60 RTS ; plot_row_of_flipped_object_20 &58c5 a0 20 LDY #&20 &58c7 b1 2b LDA (&2b),Y ; buffer_address &58c9 bc ff ff LDY &ffff,X # actually LDY mask_address,X &58cc 39 00 7f AND &7f00,Y ; bit_reversed_bytes &58cf bc ff ff LDY &ffff,X # actually LDY sprite_address,X &58d2 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &58d5 a0 20 LDY #&20 &58d7 91 2b STA (&2b),Y ; buffer_address &58d9 e8 INX ; plot_row_of_flipped_object_18 &58da a0 18 LDY #&18 &58dc b1 2b LDA (&2b),Y ; buffer_address &58de bc ff ff LDY &ffff,X # actually LDY mask_address,X &58e1 39 00 7f AND &7f00,Y ; bit_reversed_bytes &58e4 bc ff ff LDY &ffff,X # actually LDY sprite_address,X &58e7 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &58ea a0 18 LDY #&18 &58ec 91 2b STA (&2b),Y ; buffer_address &58ee e8 INX ; plot_row_of_flipped_object_10 &58ef a0 10 LDY #&10 &58f1 b1 2b LDA (&2b),Y ; buffer_address &58f3 bc ff ff LDY &ffff,X # actually LDY mask_address,X &58f6 39 00 7f AND &7f00,Y ; bit_reversed_bytes &58f9 bc ff ff LDY &ffff,X # actually LDY sprite_address,X &58fc 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &58ff a0 10 LDY #&10 &5901 91 2b STA (&2b),Y ; buffer_address &5903 e8 INX ; plot_row_of_flipped_object_08 &5904 a0 08 LDY #&08 &5906 b1 2b LDA (&2b),Y ; buffer_address &5908 bc ff ff LDY &ffff,X # actually LDY mask_address,X &590b 39 00 7f AND &7f00,Y ; bit_reversed_bytes &590e bc ff ff LDY &ffff,X # actually LDY sprite_address,X &5911 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &5914 a0 08 LDY #&08 &5916 91 2b STA (&2b),Y ; buffer_address &5918 e8 INX ; plot_row_of_flipped_object_00 &5919 a0 00 LDY #&00 &591b b1 2b LDA (&2b),Y ; buffer_address &591d bc ff ff LDY &ffff,X # actually LDY mask_address,X &5920 39 00 7f AND &7f00,Y ; bit_reversed_bytes &5923 bc ff ff LDY &ffff,X # actually LDY sprite_address,X &5926 19 00 7f ORA &7f00,Y ; bit_reversed_bytes &5929 a0 00 LDY #&00 &592b 91 2b STA (&2b),Y ; buffer_address &592d e8 INX &592e a5 2b LDA &2b ; buffer_address_low &5930 29 07 AND #&07 &5932 d0 0d BNE &5941 ; not_group &5934 a5 2b LDA &2b ; buffer_address_low &5936 38 SEC &5937 e9 b9 SBC #&b9 &5939 85 2b STA &2b ; buffer_address_low &593b b0 06 BCS &5943 ; plot_next_row_of_flipped_object &593d c6 2c DEC &2c ; buffer_address_high &593f d0 02 BNE &5943 ; plot_next_row_of_flipped_object ; not_group &5941 c6 2b DEC &2b ; buffer_address_low ; plot_next_row_of_flipped_object &5943 c6 2d DEC &2d ; height_of_column &5945 f0 03 BEQ &594a ; leave &5947 4c c5 58 JMP &58c5 ; plot_row_of_flipped_object_20 # actually JMP plot_next_row_of_flipped_object_address ; leave &594a 60 RTS ; shift_sprite_and_mask_data # Called with A = number of bits misaligned &594b bc df 60 LDY &60df,X ; objects_flipped &594e 10 07 BPL &5957 ; not_flipped &5950 85 12 STA &12 ; tmp &5952 a9 08 LDA #&08 &5954 38 SEC &5955 e5 12 SBC &12 ; tmp ; not_flipped &5957 a8 TAY # Y is number of bits to shift &5958 18 CLC &5959 69 77 ADC #&77 ; (bits_shifted_right_two_bits / &100) + 2 # Use bits_shifted_right_*_bits &595b 8d e0 59 STA &59e0 ; shift_table_one_address_high_one &595e 8d b4 59 STA &59b4 ; shift_table_one_address_high_two &5961 18 CLC &5962 69 01 ADC #&01 # Use bits_shifted_left_*_bits &5964 8d e6 59 STA &59e6 ; shift_table_two_address_high_one &5967 8d ba 59 STA &59ba ; shift_table_two_address_high_two &596a b9 fb 5a LDA &5afb,Y ; bits_in_shifted_byte_table - 2 &596d 8d ae 59 STA &59ae ; bits_in_byte_one &5970 49 ff EOR #&ff &5972 8d c1 59 STA &59c1 ; bits_in_byte_two &5975 a5 0e LDA &0e ; mask_address_low &5977 8d b0 59 STA &59b0 ; shift_mask_address_low &597a a5 0f LDA &0f ; mask_address_high &597c 8d b1 59 STA &59b1 ; shift_mask_address_high &597f a5 0c LDA &0c ; sprite_address_low &5981 8d dc 59 STA &59dc ; shift_sprite_address_low &5984 a5 0d LDA &0d ; sprite_address_high &5986 8d dd 59 STA &59dd ; shift_sprite_address_high &5989 a9 24 LDA #&24 &598b 8d b6 59 STA &59b6 ; shifted_mask_data_address_low_one &598e 8d c3 59 STA &59c3 ; shifted_mask_data_address_low_two &5991 a9 24 LDA #&24 &5993 8d e2 59 STA &59e2 ; shifted_sprite_data_address_low_one &5996 8d ed 59 STA &59ed ; shifted_sprite_data_address_low_two &5999 a5 33 LDA &33 ; sprite_width &599b a6 2d LDX &2d ; height_of_column &599d 20 21 61 JSR &6121 ; multiply_A_and_X &59a0 18 CLC &59a1 69 03 ADC #&03 # Unnecessary ; shift_mask &59a3 a6 43 LDX &43 ; sprite_offset &59a5 a5 2d LDA &2d ; height_of_column &59a7 85 2e STA &2e ; columns_to_shift ; shift_mask_data_column_loop &59a9 a5 33 LDA &33 ; sprite_width &59ab 85 34 STA &34 ; rows_to_shift &59ad a9 00 LDA #&00 # actually LDA bits_in_byte_one ; shift_mask_data_row_loop &59af bc ff ff LDY &ffff,X # actually LDY mask_address,X &59b2 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA shift_table_one_address,Y &59b5 9d 24 78 STA &7824,X ; shifted_mask_data # actually STA shifted_mask_data_address,X &59b8 b9 00 79 LDA &7900,Y ; bits_shifted_right_two_bits # actually LDA shift_table_two_address_high_two,Y &59bb e8 INX &59bc c6 34 DEC &34 ; rows_to_shift &59be d0 ef BNE &59af ; shift_mask_data_row_loop &59c0 09 00 ORA #&00 # actually ORA bits_in_byte_two &59c2 9d 24 78 STA &7824,X ; shifted_mask_data # actually STA shifted_mask_data_address,X &59c5 ee b6 59 INC &59b6 ; shifted_mask_data_address_low_one &59c8 ee c3 59 INC &59c3 ; shifted_mask_data_address_low_two &59cb c6 2e DEC &2e ; columns_to_shift &59cd d0 da BNE &59a9 ; shift_mask_data_column_loop ; shift_sprite &59cf a5 2d LDA &2d ; height_of_column &59d1 85 2e STA &2e ; columns_to_shift &59d3 a6 43 LDX &43 ; sprite_offset ; shift_sprite_data_column_loop &59d5 a5 33 LDA &33 ; sprite_width &59d7 85 34 STA &34 ; rows_to_shift &59d9 a9 00 LDA #&00 ; shift_sprite_data_row_loop &59db bc ff ff LDY &ffff,X # actually LDY sprite_address,X &59de 19 00 79 ORA &7900,Y ; bits_shifted_right_two_bits # actually ORA shift_table_one,Y &59e1 9d 24 77 STA &7724,X ; shifted_sprite_data # actually STA shifted_sprite_data_address,X &59e4 b9 00 79 LDA &7900,Y ; bits_shifted_right_two_bits # actually LDA shift_table_two_address_high_one,Y &59e7 e8 INX &59e8 c6 34 DEC &34 ; rows_to_shift &59ea d0 ef BNE &59db ; shift_sprite_data_row_loop &59ec 9d 24 77 STA &7724,X ; shifted_sprite_data # actually STA shifted_sprite_data_address,X &59ef ee e2 59 INC &59e2 ; shifted_sprite_data_address_low_one &59f2 ee ed 59 INC &59ed ; shifted_sprite_data_address_low_two &59f5 c6 2e DEC &2e ; columns_to_shift &59f7 d0 dc BNE &59d5 ; shift_sprite_data_column_loop ; plot_shifted_sprite &59f9 e6 33 INC &33 ; sprite_width &59fb a6 17 LDX &17 ; object_to_consider &59fd bd df 60 LDA &60df,X ; objects_flipped &5a00 10 18 BPL &5a1a ; plot_unflipped_shifted_sprite ; plot_flipped_shifted_sprite &5a02 a2 05 LDX #&05 ; offset_for_flipped_mask_address_low &5a04 a9 24 LDA #&24 &5a06 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &5a09 a9 78 LDA #&78 ; &7824 = shifted_mask_data &5a0b 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &5a0e a2 0b LDX #&0b ; offset_for_flipped_sprite_address_low &5a10 a9 24 LDA #&24 &5a12 20 00 58 JSR &5800 ; poke_byte_into_plot_row_of_flipped_object_code &5a15 a9 77 LDA #&77 ; &7724 = shifted_sprite_data &5a17 4c e0 57 JMP &57e0 ; plot_flipped_object_after_shifting ; plot_unflipped_shifted_sprite &5a1a a2 05 LDX #&05 ; offset_for_unflipped_mask_address_low &5a1c a9 24 LDA #&24 &5a1e 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &5a21 a9 78 LDA #&78 ; &7824 = shifted_mask_data &5a23 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &5a26 e8 INX ; offset_for_unflipped_sprite_address_low &5a27 a9 24 LDA #&24 &5a29 20 b4 58 JSR &58b4 ; poke_byte_into_plot_row_of_unflipped_object_code &5a2c a9 77 LDA #&77 ; &7724 = shifted_sprite_data &5a2e 4c 25 58 JMP &5825 ; plot_unflipped_object_after_shifting ; calculate_buffer_address_from_X_and_Y &5a31 8a TXA &5a32 38 SEC &5a33 e9 18 SBC #&18 &5a35 29 f8 AND #&f8 &5a37 85 12 STA &12 ; group_offset &5a39 98 TYA &5a3a 29 07 AND #&07 &5a3c 49 07 EOR #&07 &5a3e 85 13 STA &13 ; row_in_group &5a40 98 TYA &5a41 4a LSR A &5a42 4a LSR A &5a43 29 fe AND #&fe &5a45 a8 TAY &5a46 b9 46 5a LDA &5a46,Y ; row_address_table - 18 &5a49 05 13 ORA &13 ; row_in_group &5a4b 18 CLC &5a4c 65 12 ADC &12 ; group_offset &5a4e 85 2b STA &2b ; buffer_address_low &5a50 b9 47 5a LDA &5a47,Y ; row_address_table - 18 + 1 &5a53 69 00 ADC #&00 &5a55 85 2c STA &2c ; buffer_address_high &5a57 60 RTS ; row_address_table &5a58 40 76 ; &7640 &5a5a 80 75 ; &7580 &5a5c c0 74 ; &74c0 &5a5e 00 74 ; &7400 &5a60 40 73 ; &7340 &5a62 80 72 ; &7280 &5a64 c0 71 ; &71c0 &5a66 00 71 ; &7100 &5a68 40 70 ; &7040 &5a6a 80 6f ; &6f80 &5a6b c0 6e ; &6ec0 &5a6e 00 6e ; &6e00 &5a70 40 6d ; &6d40 &5a72 80 6c ; &6c80 ; calculate_object_screen_x_and_y &5a74 a6 17 LDX &17 ; object_to_consider &5a76 bd 87 60 LDA &6087,X ; objects_y_fraction &5a79 85 3d STA &3d ; y_fraction &5a7b bd 9d 60 LDA &609d,X ; objects_y_room &5a7e 85 3e STA &3e ; y_room &5a80 bd ed 5f LDA &5fed,X ; objects_x_fraction &5a83 85 3b STA &3b ; x_fraction &5a85 bd 03 60 LDA &6003,X ; objects_x_room &5a88 85 3c STA &3c ; x_room &5a8a 4c 9b 5a JMP &5a9b ; calculate_screen_x_and_y ; calculate_room_screen_x_and_y &5a8d a5 22 LDA &22 ; room_y &5a8f 85 3e STA &3e ; y_room &5a91 a5 21 LDA &21 ; room_x &5a93 85 3c STA &3c ; x_room &5a95 a9 00 LDA #&00 # Use corner of room &5a97 85 3b STA &3b ; x_fraction &5a99 85 3d STA &3d ; y_fraction ; calculate_screen_x_and_y &5a9b a5 3b LDA &3b ; x_fraction &5a9d 38 SEC &5a9e ed ed 5f SBC &5fed ; objects_x_fraction # Player x fraction &5aa1 85 3f STA &3f ; x_fraction_relative_to_player &5aa3 a5 3c LDA &3c ; x_room &5aa5 ed 03 60 SBC &6003 ; objects_x_room # Player x room &5aa8 85 40 STA &40 ; x_room_relative_to_player &5aaa a5 3d LDA &3d ; y_fraction &5aac 38 SEC &5aad ed 87 60 SBC &6087 ; objects_y_fraction # Player y fraction &5ab0 85 41 STA &41 ; y_fraction_relative_to_player &5ab2 a5 3e LDA &3e ; y_room &5ab4 ed 9d 60 SBC &609d ; objects_y_room # Player y room &5ab7 85 42 STA &42 ; y_room_relative_to_player &5ab9 a5 3f LDA &3f ; x_fraction_relative_to_player &5abb 18 CLC &5abc 65 41 ADC &41 ; y_fraction_relative_to_player &5abe 85 2f STA &2f ; screen_x_low &5ac0 a5 40 LDA &40 ; x_room_relative_to_player &5ac2 65 42 ADC &42 ; y_room_relative_to_player &5ac4 18 CLC &5ac5 69 01 ADC #&01 &5ac7 a8 TAY &5ac8 0a ASL A &5ac9 98 TYA &5aca 6a ROR A &5acb 85 30 STA &30 ; screen_x_high &5acd 66 2f ROR &2f ; screen_x_low &5acf a5 41 LDA &41 ; y_fraction_relative_to_player &5ad1 38 SEC &5ad2 e5 3f SBC &3f ; x_fraction_relative_to_player &5ad4 85 31 STA &31 ; screen_y_low &5ad6 a5 42 LDA &42 ; y_room_relative_to_player &5ad8 e5 40 SBC &40 ; x_room_relative_to_player &5ada 18 CLC &5adb 69 02 ADC #&02 &5add a8 TAY &5ade 29 80 AND #&80 &5ae0 85 12 STA &12 ; tmp &5ae2 98 TYA &5ae3 4a LSR A &5ae4 05 12 ORA &12 ; tmp &5ae6 66 31 ROR &31 ; screen_y_low &5ae8 4a LSR A &5ae9 05 12 ORA &12 ; tmp &5aeb 85 32 STA &32 ; screen_y_high &5aed 66 31 ROR &31 ; screen_y_low &5aef a5 31 LDA &31 ; screen_y_low &5af1 38 SEC &5af2 e9 14 SBC #&14 &5af4 85 31 STA &31 ; screen_y_low &5af6 a5 32 LDA &32 ; screen_y_high &5af8 e9 00 SBC #&00 &5afa 85 32 STA &32 ; screen_y_high &5afc 60 RTS ; bits_in_shifted_byte_table &5afd c0 c0 ; 2 # Second byte is unused &5aff f0 f0 ; 4 # Second byte is unused &5b01 fc ; 6 ; irq1_handler &5b02 84 07 STY &07 ; irq_y &5b04 86 06 STX &06 ; irq_x &5b06 e6 52 INC &52 ; irq_count &5b08 a9 02 LDA #&02 &5b0a 2c 4d fe BIT &fe4d ; System VIA interrupt flag register &5b0d d0 2e BNE &5b3d ; vsync_occurred # &02 set if interrupt caused by a v-sync &5b0f 50 13 BVC &5b24 ; leave_interrupt # &40 set if interrupt caused by timer 1 &5b11 e6 37 INC &37 ; palette_changing_state &5b13 f0 16 BEQ &5b2b ; use_middle_colours ; use_bottom_colours &5b15 a9 84 LDA #&84 ; Y # Set colour 1 to yellow for bottom section &5b17 20 62 5b JSR &5b62 ; change_palette_to_colour_A &5b1a a2 00 LDX #&00 &5b1c a0 ff LDY #&ff # Don't trigger timer again until after next v-sync ; leave_interrupt_after_setting_timer &5b1e 8e 44 fe STX &fe44 ; System VIA timer 1 counter LSB &5b21 8c 45 fe STY &fe45 ; System VIA timer 1 counter MSB ; leave_interrupt &5b24 a6 06 LDX &06 ; irq_x &5b26 a4 07 LDY &07 ; irq_y &5b28 a5 fc LDA &fc ; irq_accumulator &5b2a 40 RTI ; use_middle_colours &5b2b a9 82 LDA #&82 ; C # Set colour 0 to black, colour 1 to cyan for middle &5b2d 20 62 5b JSR &5b62 ; change_palette_to_colour_A &5b30 a9 07 LDA #&07 ; K &5b32 20 62 5b JSR &5b62 ; change_palette_to_colour_A &5b35 e6 51 INC &51 ; vsync_counter &5b37 a2 1e LDX #&1e # &031e delay between middle and bottom sections &5b39 a0 03 LDY #&03 &5b3b d0 e1 BNE &5b1e ; leave_interrupt_after_setting_timer ; vsync_occurred &5b3d a9 3c LDA #&3c # &2d3c delay between v-sync and middle section &5b3f 8d 44 fe STA &fe44 ; System VIA timer 1 counter LSB &5b42 a9 2d LDA #&2d &5b44 8d 45 fe STA &fe45 ; System VIA timer 1 counter MSB &5b47 a9 ff LDA #&ff &5b49 85 37 STA &37 ; palette_changing_state ; use_top_colours &5b4b a5 04 LDA &04 ; main_foreground_colour # Use main colours for top section &5b4d 20 62 5b JSR &5b62 ; change_palette_to_colour_A &5b50 a5 03 LDA &03 ; main_background_colour &5b52 20 62 5b JSR &5b62 ; change_palette_to_colour_A &5b55 20 10 02 JSR &0210 ; wipe_memory_if_replay_detected # Copy protection code set up by loader &5b58 a6 06 LDX &06 ; irq_x &5b5a a4 07 LDY &07 ; irq_y &5b5c ad 41 fe LDA &fe41 ; System VIA output register A # Clear interrupt &5b5f a5 fc LDA &fc ; irq_accumulator &5b61 40 RTI ; change_palette_to_colour_A &5b62 a0 07 LDY #&07 ; change_palette_to_colour_A_loop &5b64 8d 21 fe STA &fe21 ; video ULA palette register &5b67 18 CLC &5b68 69 10 ADC #&10 # Change all eight instances of colour in turn &5b6a 88 DEY &5b6b 10 f7 BPL &5b64 ; change_palette_to_colour_A_loop &5b6d 60 RTS ; plot_pocket &5b6e a4 4a LDY &4a ; pocket_position &5b70 b9 82 00 LDA &0082,Y ; pockets &5b73 0a ASL A &5b74 aa TAX &5b75 bd a7 5b LDA &5ba7,X ; pocket_sprite_addresses_table &5b78 8d 91 5b STA &5b91 ; pocket_sprite_address_top_low &5b7b 18 CLC &5b7c 69 10 ADC #&10 &5b7e 8d 9a 5b STA &5b9a ; pocket_sprite_address_bottom_low &5b81 bd a8 5b LDA &5ba8,X ; pocket_sprite_addresses_table + 1 &5b84 8d 92 5b STA &5b92 ; pocket_sprite_address_top_high &5b87 69 00 ADC #&00 &5b89 8d 9b 5b STA &5b9b ; pocket_sprite_address_bottom_high &5b8c a6 4b LDX &4b ; pocket_screen_position &5b8e a0 0f LDY #&0f ; plot_pocket_loop &5b90 b9 ff ff LDA &ffff,Y # actually LDA pocket_sprite_address_top,Y &5b93 5d 20 0c EOR &0c20,X ; pockets_screen_address &5b96 9d 20 0c STA &0c20,X ; pockets_screen_address &5b99 b9 ff ff LDA &ffff,Y # actually LDA pocket_sprite_address_bottom,Y &5b9c 5d d0 0c EOR &0cd0,X ; pockets_screen_address + &b0 &5b9f 9d d0 0c STA &0cd0,X ; pockets_screen_address + &b0 &5ba2 e8 INX &5ba3 88 DEY &5ba4 10 ea BPL &5b90 ; plot_pocket_loop &5ba6 60 RTS ; pocket_sprite_addresses_table &5ba7 00 00 ; (unused) &5ba9 00 00 ; (unused) &5bab 00 00 ; (unused) &5bad 1d 5c ; &5c1d = pocket_sprite_hammer &5baf fd 5b ; &5bfd = pocket_sprite_hourglass &5bc1 dd 5b ; &5bdd = pocket_sprite_cross &5bc3 bd 5b ; &5bbd = pocket_sprite_bible &5bc5 3d 5c ; &5c3d = pocket_sprite_antibody_swirl &5bc7 5d 5c ; &5c5d = pocket_sprite_antibody_spikes &5bc9 7d 5c ; &5c7d = pocket_sprite_antibody_sticks &5bcb 9d 5c ; &5c9d = pocket_sprite_antibody_blob ; pocket_sprite_bible &5bbd 8c 8c 8c ec 8c 0c fc 00 28 28 28 2b 28 28 2f 00 &5bcd 00 fc fc fc fc fc fc 0c 00 2f 2f 2f 2f 2f 2f 28 ; pocket_sprite_cross &5bdd ec e4 98 80 c0 40 80 00 2f 27 19 01 02 02 01 00 &5bed 00 80 c0 40 80 80 80 98 00 01 02 02 01 01 01 19 ; pocket_sprite_hourglass &5bfd 88 c8 e8 f0 f0 f8 f8 00 11 13 16 0c 09 19 1f 00 &5c0d 00 f8 f8 f0 f0 e8 c8 88 00 1f 19 09 0c 16 12 11 ; pocket_sprite_hammer &5c1d c0 c0 b4 74 f4 f4 f4 00 01 01 16 17 17 17 17 00 &5c2d 00 c0 c0 c0 c0 c0 c0 c0 00 01 01 01 01 01 01 01 ; pocket_sprite_antibody_swirl &5c3d f6 e6 1c f8 f0 00 00 00 67 73 38 1f 07 00 00 00 &5c4d 00 00 00 e0 38 cc e6 76 00 00 00 01 0e 3f 7b 62 ; pocket_sprite_antibody_spikes &5c5d e8 f8 f0 e0 40 00 00 00 5f 1f 0d 02 07 06 08 00 &5c6d 00 00 00 c0 e6 dc b8 d0 00 20 10 1d 0d 0b 17 1f ; pocket_sprite_antibody_sticks &5c7d f6 f2 0c 00 00 00 00 00 36 0e 1f 3e 5c 68 30 00 &5c8d 00 0c 1e 3e 7c f8 f0 0c 00 00 00 00 00 30 59 4b ; pocket_sprite_antibody_blob &5c9d 0e 7e 3c 3c 78 f0 c0 00 7e 7c 38 3c 1e 0f 03 00 &5cad 00 c0 f0 f8 fc cc 86 06 00 03 0f 1f 38 30 70 78 ; check_for_overlap_between_object_and_wall # Leaves with carry set if object overlapping wall &5cbd a6 17 LDX &17 ; object_to_consider &5cbf bd 5b 60 LDA &605b,X ; objects_size &5cc2 85 3f STA &3f ; object_size &5cc4 bd ed 5f LDA &5fed,X ; objects_x_fraction &5cc7 38 SEC &5cc8 e5 3f SBC &3f ; object_size &5cca 85 3b STA &3b ; x_fraction &5ccc bd 03 60 LDA &6003,X ; objects_x_room &5ccf e9 00 SBC #&00 &5cd1 85 3c STA &3c ; x_room &5cd3 85 41 STA &41 ; min_x_room &5cd5 bd 87 60 LDA &6087,X ; objects_y_fraction &5cd8 38 SEC &5cd9 e5 3f SBC &3f ; object_size &5cdb 85 3d STA &3d ; y_fraction &5cdd bd 9d 60 LDA &609d,X ; objects_y_room &5ce0 e9 00 SBC #&00 &5ce2 85 3e STA &3e ; y_room &5ce4 a8 TAY &5ce5 85 45 STA &45 ; min_y_room &5ce7 a5 3b LDA &3b ; x_fraction &5ce9 4a LSR A &5cea 18 CLC &5ceb 69 40 ADC #&40 &5ced 85 3b STA &3b ; x_fraction &5cef a5 3d LDA &3d ; y_fraction &5cf1 4a LSR A &5cf2 18 CLC &5cf3 69 40 ADC #&40 &5cf5 85 3d STA &3d ; y_fraction &5cf7 a6 3c LDX &3c ; x_room &5cf9 20 c4 4a JSR &4ac4 ; get_room_data_byte &5cfc f0 03 BEQ &5d01 ; skip_min_x_min_y_room_check # Don't check if there is no wall &5cfe 20 a3 5d JSR &5da3 ; check_position_for_wall # Pops with carry clear if (x-, y-) overlapping wall ; skip_min_x_min_y_room_check &5d01 a6 17 LDX &17 ; object_to_consider &5d03 bd ed 5f LDA &5fed,X ; objects_x_fraction &5d06 18 CLC &5d07 65 3f ADC &3f ; object_size &5d09 85 3b STA &3b ; x_fraction &5d0b bd 03 60 LDA &6003,X ; objects_x_room &5d0e 69 00 ADC #&00 &5d10 85 3c STA &3c ; x_room &5d12 aa TAX &5d13 a5 3b LDA &3b ; x_fraction &5d15 38 SEC &5d16 e5 3f SBC &3f ; object_size &5d18 38 SEC &5d19 e5 3f SBC &3f ; object_size &5d1b 18 CLC &5d1c 69 80 ADC #&80 &5d1e 4a LSR A &5d1f 85 3b STA &3b ; x_fraction &5d21 a4 3e LDY &3e ; y_room &5d23 86 42 STX &42 ; max_x_room &5d25 e4 41 CPX &41 ; min_x_room &5d27 f0 08 BEQ &5d31 ; skip_max_x_min_y_room_check # Don't check if room x the same, i.e. already checked &5d29 20 c4 4a JSR &4ac4 ; get_room_data_byte &5d2c f0 03 BEQ &5d31 ; skip_max_x_min_y_room_check # Don't check if there is no wall &5d2e 20 a3 5d JSR &5da3 ; check_position_for_wall # Pops with carry clear if (x+, y-) overlapping wall ; skip_max_x_min_y_room_check &5d31 a6 17 LDX &17 ; object_to_consider &5d33 bd ed 5f LDA &5fed,X ; objects_x_fraction &5d36 38 SEC &5d37 e5 3f SBC &3f ; object_size &5d39 4a LSR A &5d3a 18 CLC &5d3b 69 40 ADC #&40 &5d3d 85 12 STA &12 ; max_x_fraction &5d3f bd 87 60 LDA &6087,X ; objects_y_fraction &5d42 18 CLC &5d43 65 3f ADC &3f ; object_size &5d45 85 3d STA &3d ; y_fraction &5d47 bd 9d 60 LDA &609d,X ; objects_y_room &5d4a 69 00 ADC #&00 &5d4c 85 3e STA &3e ; y_room &5d4e a8 TAY &5d4f a5 3d LDA &3d ; y_fraction &5d51 38 SEC &5d52 e5 3f SBC &3f ; object_size &5d54 38 SEC &5d55 e5 3f SBC &3f ; object_size &5d57 18 CLC &5d58 69 80 ADC #&80 &5d5a 4a LSR A &5d5b 85 3d STA &3d ; y_fraction &5d5d a6 3c LDX &3c ; x_room &5d5f 84 47 STY &47 ; max_y_room &5d61 c4 45 CPY &45 ; min_y_room &5d63 f0 10 BEQ &5d75 ; skip_max_x_max_y_room_check # Don't check if room y the same, i.e. already checked &5d65 e4 41 CPX &41 ; max_x_room &5d67 d0 04 BNE &5d6d ; skip_max &5d69 a5 12 LDA &12 ; max_x_fraction &5d6b 85 3b STA &3b ; x_fraction ; skip_max &5d6d 20 c4 4a JSR &4ac4 ; get_room_data_byte &5d70 f0 03 BEQ &5d75 ; skip_max_x_max_y_room_check # Don't check if there is no wall &5d72 20 a3 5d JSR &5da3 ; check_position_for_wall # Pops with carry clear if (x+, y+) overlapping wall ; skip_max_x_max_y_room_check &5d75 a6 17 LDX &17 ; object_to_consider &5d77 bd ed 5f LDA &5fed,X ; objects_x_fraction &5d7a 38 SEC &5d7b e5 3f SBC &3f ; object_size &5d7d 85 3b STA &3b ; x_fraction &5d7f bd 03 60 LDA &6003,X ; objects_x_room &5d82 e9 00 SBC #&00 &5d84 85 3c STA &3c ; x_room &5d86 aa TAX &5d87 a5 3b LDA &3b ; x_fraction &5d89 4a LSR A &5d8a 18 CLC &5d8b 69 40 ADC #&40 &5d8d 85 3b STA &3b ; x_fraction &5d8f a4 47 LDY &47 ; max_y_room &5d91 c4 45 CPY &45 ; min_y_room &5d93 f0 0c BEQ &5da1 ; skip_min_x_max_y_room_check # Don't check if room y the same, i.e. already checked &5d95 e4 42 CPX &42 ; max_x_room &5d97 f0 08 BEQ &5da1 ; skip_min_x_max_y_room_check # Don't check if room x the same, i.e. already checked &5d99 20 c4 4a JSR &4ac4 ; get_room_data_byte &5d9c f0 03 BEQ &5da1 ; skip_min_x_max_y_room_check # Don't check if there is no wall &5d9e 20 a3 5d JSR &5da3 ; check_position_for_wall # Pops with carry clear if (x-, y+) overlapping wall ; skip_min_x_max_y_room_check &5da1 18 CLC &5da2 60 RTS ; check_position_for_wall # Called with A = room type &5da3 0a ASL A &5da4 a8 TAY &5da5 b9 33 6a LDA &6a33,Y ; wall_sections_address_table - 2 &5da8 85 1b STA &1b ; wall_sections_address_low &5daa b9 34 6a LDA &6a34,Y ; wall_sections_address_table - 2 + 1 &5dad 85 1c STA &1c ; wall_sections_address_high &5daf a9 00 LDA #&00 ; check_position_for_wall_loop # Walls are stored as four byte sections &5db1 85 1e STA &1e ; offset &5db3 a8 TAY &5db4 b1 1b LDA (&1b),Y ; wall_sections_address # First byte is x start of wall &5db6 f0 41 BEQ &5df9 ; leave &5db8 c5 3b CMP &3b ; x_fraction &5dba 90 29 BCC &5de5 ; check_x_end &5dbc f0 09 BEQ &5dc7 ; check_y &5dbe a5 3b LDA &3b ; x_fraction &5dc0 18 CLC &5dc1 65 3f ADC &3f ; object_size &5dc3 d1 1b CMP (&1b),Y ; wall_sections_address # Second byte is x size of wall &5dc5 90 17 BCC &5dde ; consider_next_section ; check_y &5dc7 c8 INY ; check_y_two &5dc8 c8 INY &5dc9 b1 1b LDA (&1b),Y ; wall_sections_address # Third byte is y start of wall &5dcb c5 3d CMP &3d ; y_fraction &5dcd 90 20 BCC &5def ; check_y_end &5dcf f0 09 BEQ &5dda ; object_overlaps_with_wall &5dd1 a5 3d LDA &3d ; y_fraction &5dd3 18 CLC &5dd4 65 3f ADC &3f ; object_size &5dd6 d1 1b CMP (&1b),Y ; wall_sections_address # Fourth byte is y size of wall &5dd8 90 04 BCC &5dde ; consider_next_section ; object_overlaps_with_wall &5dda 68 PLA # Pop out of check_for_overlap_between_object_and_wall &5ddb 68 PLA &5ddc 38 SEC # Leave with carry set to indicate overlap &5ddd 60 RTS ; consider_next_section &5dde a5 1e LDA &1e ; offset &5de0 18 CLC &5de1 69 04 ADC #&04 &5de3 d0 cc BNE &5db1 ; check_position_for_wall_loop # Always branches ; check_x_end &5de5 c8 INY ; +1 &5de6 18 CLC &5de7 71 1b ADC (&1b),Y ; wall_sections_address &5de9 c5 3b CMP &3b ; x_fraction &5deb b0 db BCS &5dc8 ; check_y_two &5ded 90 ef BCC &5dde ; consider_next_section # Always branches ; check_y_end &5def c8 INY ; +3 &5df0 18 CLC &5df1 71 1b ADC (&1b),Y ; wall_sections_address &5df3 c5 3d CMP &3d ; y_fraction &5df5 b0 e3 BCS &5dda ; object_overlaps_with_wall &5df7 90 e5 BCC &5dde ; consider_next_section # Always branches ; leave &5df9 60 RTS ; unused &5dfa 88 40 20 28 ; start_screen &5dfe a2 0e LDX #&15 # Show whole screen &5e00 20 1f 5e JSR &5e1f ; set_screen_height &5e03 a2 aa LDX #&aa &5e05 a0 5e LDY #&5e ; &5eaa = night_shade_text # Write "NIGHT SHADE" &5e07 20 02 5f JSR &5f02 ; plot_text &5e0a a2 b8 LDX #&b8 &5e0c a0 5e LDY #&5e ; &5eb8 = press_space_to_start_text # Write "PRESS SPACE TO START" &5e0e 20 02 5f JSR &5f02 ; plot_text ; wait_for_space &5e11 a2 e2 LDX #&e2 ; SPACE &5e13 20 d3 5e JSR &5ed3 ; check_for_keypress &5e16 10 f9 BPL &5e11 ; wait_for_space &5e18 a0 03 LDY #&03 # Play tune for starting game &5e1a 20 b9 53 JSR &53b9 ; play_tune &5e1d a2 15 LDX #&15 # Show whole screen (unnecessary) ; set_screen_height &5e1f a9 06 LDA #&06 # R6: Vertical displayed register &5e21 8d 00 fe STA &fe00 ; video register number &5e24 8e 01 fe STX &fe01 ; video register value &5e27 60 RTS ; plot_demons_needing_destroying &5e28 a9 03 LDA #&03 &5e2a 85 12 STA &12 ; demon_to_plot &5e2c a9 00 LDA #&00 &5e2e 85 3a STA &3a ; demons_have_changed ; plot_demons_needing_destroying_loop &5e30 a6 12 LDX &12 ; demon &5e32 a0 a9 LDY #&a9 ; LDA &5e34 bd e2 5f LDA &5fe2,X ; objects_sprite + &b &5e37 c9 37 CMP #&37 ; FIRST_DEMON_SPRITE &5e39 90 05 BCC &5e40 ; use_lda # Has the demon been destroyed? &5e3b a0 49 LDY #&49 ; EOR # If not, invert it &5e3d a9 ff LDA #&ff &5e3f 2c a9 00 BIT &00a9 ; use_lda #5e40 LDA #&00 &5e42 8c 6d 5e STY &5e6d ; plot_mask_operation &5e45 8d 6e 5e STA &5e6e ; plot_mask_operation + 1 &5e48 bd a2 5e LDA &5ea2,X ; demons_screen_address_low_table &5e4b 85 2b STA &2b ; buffer_address_low &5e4d a9 10 LDA #&10 &5e4f 85 2c STA &2c ; buffer_address_high &5e51 bd a6 5e LDA &5ea6,X ; demons_sprite_table &5e54 20 10 57 JSR &5710 ; calculate_sprite_address &5e57 a5 12 LDA &12 ; demon_to_plot &5e59 c9 03 CMP #&03 &5e5b d0 08 BNE &5e65 ; not_chicken &5e5d a9 28 LDA #&28 # Crop DEMON_CHICKEN &5e5f 85 2d STA &2d ; height_of_column &5e61 a0 0c LDY #&0c &5e63 d0 02 BNE &5e67 ; plot_column_loop # Always branches ; not_chicken &5e65 a0 03 LDY #&03 ; plot_column_loop &5e67 a9 00 LDA #&00 &5e69 85 14 STA &14 ; screen_offset ; plot_row_loop &5e6b b1 0e LDA (&0e),Y ; mask_address ; plot_mask_operation &5e6d 49 ff EOR #&ff # or LDA #&00 &5e6f 51 0c EOR (&0c),Y ; sprite_address &5e71 c8 INY &5e72 84 13 STY &13 ; sprite_offset &5e74 a4 14 LDY &14 ; screen_offset &5e76 91 2b STA (&2b),Y ; screen_address &5e78 98 TYA &5e79 a4 13 LDY &13 ; sprite_offset &5e7b 18 CLC &5e7c 69 08 ADC #&08 &5e7e 85 14 STA &14 ; screen_offset &5e80 c9 18 CMP #&18 &5e82 d0 e7 BNE &5e6b ; plot_row_loop &5e84 a5 2b LDA &2b ; buffer_address_low &5e86 29 07 AND #&07 &5e88 d0 0d BNE &5e97 ; not_group &5e8a a5 2b LDA &2b ; buffer_address_low &5e8c 38 SEC &5e8d e9 a9 SBC #&a9 &5e8f 85 2b STA &2b ; buffer_address_low &5e91 b0 06 BCS &5e99 ; next_row &5e93 c6 2c DEC &2c ; buffer_address_high &5e95 d0 02 BNE &5e99 ; next_row ; not_group &5e97 c6 2b DEC &2b ; buffer_address_low ; next_row &5e99 c6 2d DEC &2d ; height_of_column &5e9b d0 ca BNE &5e67 ; plot_column_loop &5e9d c6 12 DEC &12 ; demon_to_plot &5e9f 10 8f BPL &5e30 ; plot_demons_needing_destroying &5ea1 60 RTS ; demons_screen_address_low_table &5ea2 a7 bf d7 ef ; demons_sprite_table &5ea6 37 3b 3f 43 ; night_shade_text &5eaa d0 04 ; &04d0 &5eac 13 10 0e 0f 18 1b 17 0f 0a 0c 0d ; "NIGHT SHADE" &5eb7 ff ; press_space_to_start_text &5eb8 90 0b ; &0b90 &5eba 15 16 0d 17 17 1b 17 15 0a 0b 0d 1b 18 14 1b 17 ; "PRESS SPACE TO S" &5eca 18 0a 16 18 ; "TART" &5ece ff ; unused &5ecf 99 f9 e1 80 # Keycodes for LEFT, RIGHT, Z, SHIFT ; check_for_keypress &5ed3 a0 7f LDY #&7f # Set top bit as input, low seven bits as output &5ed5 8c 43 fe STY &fe43 ; System VIA data direction register A &5ed8 a0 03 LDY #&03 # Disable keyboard auto-scanning &5eda 8c 40 fe STY &fe40 ; System VIA port B input/output register &5edd 8e 4f fe STX &fe4f ; System VIA input/output register A # Write key to check &5ee0 ad 4f fe LDA &fe4f ; System VIA input/output register A # Top bit set if key pressed &5ee3 08 PHP &5ee4 a0 0b LDY #&0b # Enable keyboard auto-scanning &5ee6 8c 40 fe STY &fe40 ; System VIA port B input/output register &5ee9 28 PLP &5eea 60 RTS # Leaves with negative set if key pressed ; rnd &5eeb a5 00 LDA &00 ; rnd_0 &5eed 29 48 AND #&48 &5eef 69 38 ADC #&38 &5ef1 0a ASL A &5ef2 0a ASL A &5ef3 26 02 ROL &02 ; rnd_2 &5ef5 26 01 ROL &01 ; rnd_1 &5ef7 26 00 ROL &00 ; rnd_0 &5ef9 a5 00 LDA &00 ; rnd_0 &5efb 65 52 ADC &52 ; irq_count &5efd d0 02 BNE &5f01 ; leave &5eff a5 00 LDA &00 ; rnd_0 ; leave &5f01 60 RTS ; plot_text &5f02 86 08 STX &08 ; text_address_low &5f04 84 09 STY &09 ; text_address_high &5f06 a0 00 LDY #&00 &5f08 b1 08 LDA (&08),Y ; text_address # First two bytes of text set screen address &5f0a 85 0a STA &0a ; screen_address_low &5f0c c8 INY &5f0d b1 08 LDA (&08),Y ; text_address &5f0f 85 0b STA &0b ; screen_address_high &5f11 c8 INY ; plot_text_loop &5f12 b1 08 LDA (&08),Y ; text_address &5f14 30 23 BMI &5f39 ; leave # Top bit set indicates end of text &5f16 84 12 STY &12 ; text_offset &5f18 0a ASL A &5f19 0a ASL A &5f1a 0a ASL A &5f1b 09 07 ORA #&07 &5f1d aa TAX &5f1e a0 07 LDY #&07 ; plot_character_loop &5f20 bd 00 01 LDA &0100,X ; font_data &5f23 91 0a STA (&0a),Y ; screen_address &5f25 ca DEX &5f26 88 DEY &5f27 10 f7 BPL &5f20 ; plot_character_loop &5f29 a5 0a LDA &0a ; screen_address_low &5f2b 18 CLC &5f2c 69 08 ADC #&08 &5f2e 85 0a STA &0a ; screen_address_low &5f30 90 02 BCC &5f34 ; skip_page &5f32 e6 0b INC &0b ; screen_address_high ; skip_page &5f34 a4 12 LDY &12 ; text_offset &5f36 c8 INY &5f37 d0 d9 BNE &5f12 ; plot_text_loop ; leave &5f39 60 RTS ; copy_buffer_to_screen_and_wipe_buffer &5f3a a9 8f LDA #&8f &5f3c 8d 57 5f STA &5f57 ; source_address_low &5f3f a9 6c LDA #&6c ; &6c8f &5f41 8d 58 5f STA &5f58 ; source_address_high &5f44 a9 3f LDA #&3f # Unnecessary &5f46 a9 8f LDA #&8f &5f48 8d 5a 5f STA &5f5a ; target_address_low &5f4b a9 04 LDA #&04 ; &043f # Unnecessary; would use screen start address of &0440 &5f4d a9 02 LDA #&02 ; &028f &5f4f 8d 5b 5f STA &5f5b ; target_address_high &5f52 a0 0e LDY #&0e ; copy_outer_loop &5f54 a2 b0 LDX #&b0 ; copy_loop &5f56 bd 8f 6c LDA &6c8f,X # actually LDA source_address,X &5f59 9d 90 02 STA &0290,X # actually STA target_address,X &5f5c ca DEX &5f5d d0 f7 BNE &5f56 ; copy_loop &5f5f ad 57 5f LDA &5f57 ; source_address_low # The screen buffer is &c0 bytes per row &5f62 18 CLC &5f63 69 c0 ADC #&c0 &5f65 8d 57 5f STA &5f57 ; source_address_low &5f68 90 03 BCC &5f6d &5f6a ee 58 5f INC &5f58 ; source_address_high &5f6d ad 5a 5f LDA &5f5a ; target_address_low &5f70 18 CLC &5f71 69 b0 ADC #&b0 # The screen is &b0 bytes per row &5f73 8d 5a 5f STA &5f5a ; target_address_low &5f76 90 03 BCC &5f7b ; target_address_high &5f78 ee 5b 5f INC &5f5b ; target_address_high &5f7b 88 DEY &5f7c d0 d6 BNE &5f54 ; copy_outer_loop ; wipe_screen_buffer &5f7e a9 6c LDA #&6c &5f80 8d 8a 5f STA &5f8a ; wipe_address_high &5f83 a9 00 LDA #&00 &5f85 aa TAX &5f86 a0 0a LDY #&0a ; wipe_screen_buffer_loop # Wipe &6c80 - &767f &5f88 9d 80 6c STA &6c80,X # actually STA wipe_address,X &5f8b ca DEX &5f8c d0 fa BNE &5f88 ; wipe_end_of_screen_buffer_loop &5f8e ee 8a 5f INC &5f8a ; wipe_address_high &5f91 88 DEY &5f92 d0 f4 BNE &5f88 ; wipe_end_of_screen_buffer_loop ; wipe_end_of_screen_buffer_loop &5f94 9d 80 76 STA &7680,X # Wipe &7680 - &76ff &5f97 e8 INX &5f98 10 fa BPL &5f94 ; wipe_end_of_screen_buffer_loop &5f9a 60 RTS ; check_for_pause &5f9b a2 e9 LDX #&e9 ; COPY &5f9d 20 d3 5e JSR &5ed3 ; check_for_keypress &5fa0 10 0a BPL &5fac ; leave &5fa2 20 aa 53 JSR &53aa ; silence_sound ; wait_for_delete &5fa5 a2 d9 LDX #&d9 ; DELETE &5fa7 20 d3 5e JSR &5ed3 ; check_for_keypress &5faa 10 f9 BPL &5fa5 ; wait_for_delete ; leave &5fac 60 RTS ; initialise_object_A_from_data_at_X_Y &5fad 86 12 STX &12 ; data_address_low &5faf 84 13 STY &13 ; data_address_high &5fb1 aa TAX &5fb2 a0 00 LDY #&00 &5fb4 a9 5f LDA #&5f ; &5fd7 = objects_sprite &5fb6 8d c2 5f STA &5fc2 ; objects_data_address_high &5fb9 a9 d7 LDA #&d7 &5fbb 8d c1 5f STA &5fc1 ; objects_data_address_low ; initialise_object_A_from_data_at_X_Y_loop &5fbe b1 12 LDA (&12),Y ; data_address &5fc0 9d d7 5f STA &5fd7,X ; objects_sprite # actually STA &5fd7,X ; objects_data_address &5fc3 ad c1 5f LDA &5fc1 &5fc6 18 CLC &5fc7 69 16 ADC #&16 &5fc9 8d c1 5f STA &5fc1 ; objects_data_address_low &5fcc 90 03 BCC &5fd1 ; skip_page &5fce ee c2 5f INC &5fc2 ; objects_data_address_high ; skip_page &5fd1 c8 INY &5fd2 c0 0f CPY #&0f &5fd4 d0 e8 BNE &5fbe ; initialise_object_A_from_data_at_X_Y_loop &5fd6 60 RTS ; objects_sprite &5fd7 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &5fe7 aa 55 aa 55 aa 55 ; objects_x_fraction &5fed aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &5ffd aa 55 aa 55 aa 55 ; objects_x_room &6003 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &6013 aa 55 aa 55 aa 55 ; objects_animation &6019 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &6029 aa 55 aa 55 aa 55 ; objects_facing &602f aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &603f aa 55 aa 55 aa 55 ; objects_data &6045 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &6055 aa 55 aa 55 aa 55 ; objects_size &605b aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &606b aa 55 aa 55 aa 55 ; objects_speed_change_cooldown &6071 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &608b aa 55 aa 55 aa 55 ; objects_y_fraction &6087 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &6097 aa 55 aa 55 aa 55 ; objects_y_room &609d aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &60ad aa 55 aa 55 aa 55 ; objects_speed_x &60b3 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &60c3 aa 55 aa 55 aa 55 ; objects_speed_y &60c9 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &60d9 aa 55 aa 55 aa 55 ; objects_flipped &60df aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &60ef aa 55 aa 55 aa 55 ; objects_x_offset &60f5 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &6105 aa 55 aa 55 aa 55 ; objects_y_offset &610b aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 &611b aa 55 aa 55 aa 55 ; multiply_A_and_X &6121 85 12 STA &12 ; a &6123 86 13 STX &13 ; x &6125 a2 08 LDX #&08 &6127 a9 00 LDA #&00 ; multiply_A_and_X_loop &6129 0a ASL A &612a 06 12 ASL &12 ; a &612c 90 03 BCC &6131 ; skip_power &612e 18 CLC &612f 65 13 ADC &13 ; x ; skip_power &6131 ca DEX &6132 d0 f5 BNE &6129 ; multiply_A_and_X_loop &6134 60 RTS ; sprite_life &6135 e0 e0 e0 e0 e0 c0 80 00 04 04 0a 11 1f 0f 07 03 &6145 58 98 c0 b8 b8 f8 38 d0 18 07 2f 2f 0f 2f 38 10 &6155 00 c0 c0 00 40 60 60 d8 03 03 38 3c 01 0b 3b 1f ; wall_pattern_byte_to_boundary_sprite_table &6165 00 ; PANED_WINDOW_LEFT &6166 00 ; PANED_WINDOW_RIGHT &6167 02 ; ARCHWAY_LEFT &6168 03 ; ARCHWAY_RIGHT &6169 02 ; ARCHWAY_LEFT &616a 03 ; ARCHWAY_RIGHT &616b 00 ; STONE_WINDOW_LEFT &616c 00 ; STONE_WINDOW_RIGHT &616d 00 ; STONES &616e 00 ; STONE_CORNER_LEFT &616f 00 ; BUTTRESS &6170 00 ; STONE_OTHER_WINDOW_LEFT &6171 00 ; GRILL_WINDOW_LEFT &6172 00 ; GRILL_WINDOW_RIGHT &6173 00 ; ARROW_SLIT &6174 00 ; STONE_ALCOVE_LEFT &6175 00 ; STONE_ALCOVE_RIGHT &6176 00 ; STONE_CORNER_RIGHT &6177 00 ; BRICKWORK &6178 00 ; SMALL_STONE_WINDOW &6179 00 ; STONE_CLOSED_ARCHWAY_LEFT &617a 00 ; STONE_CLOSED_ARCHWAY_RIGHT &617b 00 ; WOOD_LEFT &617c 00 ; WOOD_RIGHT &617d 00 ; WOOD_LEFT ; boundary_sprite_address_table &617e 86 61 ; &6186 = boundary_sprite_0 &6180 86 61 ; &6186 = boundary_sprite_1 &6182 9b 61 ; &619b = boundary_sprite_2 &6184 b0 61 ; &61b0 = boundary_sprite_3 ; boundary_sprite_0 # Boundary ; boundary_sprite_1 &6186 0a &6187 00 03 00 0f 00 3f 00 fc 03 f0 0f c0 3f 00 fc 00 &6197 f0 00 c0 00 ; boundary_sprite_2 # Right end of boundary &619b 0a &619c 00 00 00 00 00 00 00 00 00 00 00 00 30 00 f0 00 &61ac f0 00 c0 00 ; boundary_sprite_3 # Left end of boundary &61b0 04 &61b1 00 03 00 0f 00 0f 00 0c ; room_data ; x 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f y &61b9 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ; 00 &61d9 01 00 0c 00 03 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ; 01 &61f9 01 00 00 00 03 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ; 02 &6219 01 00 03 08 04 01 01 01 01 01 01 01 01 01 04 04 04 04 01 01 01 01 01 01 01 01 00 12 00 00 03 01 ; 03 &6239 01 00 00 00 00 12 00 04 01 01 01 01 01 05 00 00 00 00 1b 01 01 05 1b 05 00 12 00 01 01 01 01 01 ; 04 &6259 01 01 01 01 01 01 08 00 01 01 01 01 01 05 00 0a 0a 00 00 03 01 05 00 00 00 12 00 01 01 01 01 01 ; 05 &6279 01 01 01 01 01 01 00 00 01 01 01 04 01 05 00 0a 0a 00 12 00 01 05 00 0a 00 07 00 01 01 01 01 01 ; 06 &6299 01 01 01 01 1a 00 00 00 00 00 00 00 00 12 00 00 00 00 00 03 01 05 00 00 00 07 00 01 05 00 01 01 ; 07 &62b9 01 01 01 05 00 00 00 03 06 00 06 05 00 00 00 06 06 04 00 03 01 0c 08 06 06 05 00 00 05 00 00 01 ; 08 &62d9 01 01 01 05 00 1a 00 00 03 00 00 03 04 04 00 00 05 00 00 01 01 00 00 00 00 00 00 0c 04 00 03 01 ; 09 &62f9 01 01 01 04 00 18 15 00 0f 03 00 00 00 00 00 00 03 00 11 0f 0f 00 03 04 00 0a 00 00 00 00 00 01 ; 0a &6319 01 01 01 14 00 00 00 00 0f 0f 11 07 11 09 11 00 05 00 00 00 00 00 00 10 00 00 00 0c 0d 00 01 01 ; 0b &6339 01 01 0d 00 00 0b 0e 0e 05 00 00 00 08 00 00 00 12 00 17 16 00 10 00 09 00 01 00 00 0b 01 01 01 ; 0c &6359 01 01 01 0e 00 04 00 00 00 00 11 00 09 00 04 04 04 00 00 00 00 0e 00 00 00 01 01 01 01 01 01 01 ; 0d &6379 01 01 01 01 00 00 00 01 01 01 0e 00 00 00 00 00 08 08 08 00 0f 03 00 01 01 01 01 01 01 01 01 01 ; 0e &6399 01 01 01 01 01 01 01 01 04 01 00 00 00 09 03 00 00 00 00 00 0f 03 00 00 00 01 01 01 05 1b 01 01 ; 0f &63b9 01 01 01 0c 0c 0c 01 01 00 0f 00 06 08 08 00 00 00 00 00 13 0c 01 10 0d 00 01 01 01 02 00 03 01 ; 10 &63d9 01 01 0d 00 00 00 00 01 01 0d 00 04 00 00 00 01 01 01 00 0d 00 13 00 13 00 00 03 00 00 00 00 01 ; 11 &63f9 01 0d 0f 0f 0f 19 00 00 0d 00 00 00 00 0b 01 01 01 01 00 0c 00 00 00 00 00 00 00 00 01 0e 01 01 ; 12 &6419 01 01 01 01 01 01 06 00 00 00 0a 00 0e 01 01 01 0c 01 00 00 00 1a 11 0f 11 1b 00 01 01 01 01 01 ; 13 &6439 01 01 0d 0f 1b 0c 0c 0d 19 00 00 00 0f 1b 01 01 00 00 00 06 00 09 00 00 00 09 00 00 00 00 01 01 ; 14 &6459 01 01 0d 00 00 00 00 00 03 00 14 15 01 14 0f 0f 0f 00 03 05 00 09 00 00 00 09 00 0f 0f 00 01 01 ; 15 &6479 01 0c 1a 00 0d 0f 19 00 05 00 00 00 01 01 01 01 01 00 00 00 00 18 11 0f 11 19 00 13 0d 00 1b 01 ; 16 &6499 01 14 00 00 03 00 00 00 05 00 1a 00 01 01 01 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 10 01 ; 17 &64b9 01 0d 00 10 05 00 0a 00 03 0e 06 00 00 00 00 00 01 01 01 01 1a 00 13 08 0e 0c 0c 08 08 0c 06 01 ; 18 &64d9 01 01 00 00 05 00 00 00 03 00 00 00 00 1a 1b 00 13 01 00 00 00 00 00 00 0f 00 00 00 00 08 01 01 ; 19 &64f9 01 01 08 00 0f 03 00 03 05 00 08 00 00 18 19 00 01 01 00 16 17 00 01 00 0f 00 16 17 00 08 01 01 ; 1a &6519 01 01 08 00 00 04 06 04 00 00 08 01 00 00 00 00 01 01 00 14 15 00 01 00 0c 00 14 15 00 00 01 01 ; 1b &6539 01 05 19 08 00 00 00 00 00 08 06 01 01 00 16 17 01 01 00 00 00 00 01 00 11 00 00 00 00 03 01 01 ; 1c &6559 01 01 01 0e 06 06 08 06 06 00 01 01 01 00 14 15 01 01 01 01 01 01 01 01 0e 0d 11 0f 0f 1b 00 01 ; 1d &6579 01 01 01 01 01 05 00 03 01 01 01 01 01 00 00 00 01 01 01 01 01 01 01 01 01 01 00 01 00 00 19 01 ; 1e &6599 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ; 1f ; beyond_player_plotting_order_table &65b9 40 80 60 00 50 ; &00 &65be 41 80 60 00 50 ; &01 &65c3 40 81 60 00 50 ; &02 &65c8 81 41 60 00 50 ; &03 &65cd 40 80 61 00 50 ; &04 &65d2 61 41 80 00 50 ; &05 &65d7 40 81 61 00 50 ; &06 &65dc 81 61 41 00 50 ; &07 &65e1 40 80 60 01 50 ; &08 &65e6 41 80 60 01 50 ; &09 &65eb 40 01 81 60 50 ; &0a &65f0 01 81 41 60 50 ; &0b &65f5 40 80 61 01 50 ; &0c &65fa 61 41 80 01 50 ; &0d &65ff 40 01 81 61 50 ; &0e &6604 01 81 61 41 50 ; &0f &6609 40 80 60 00 51 ; &10 &660e 41 80 60 00 51 ; &11 &6613 40 81 60 00 51 ; &12 &6618 81 41 60 00 51 ; &13 &661d 40 80 51 61 00 ; &14 &6622 51 61 41 80 00 ; &15 &6627 40 51 61 81 00 ; &16 &662c 51 61 81 41 00 ; &17 &6631 40 80 60 01 51 ; &18 &6636 41 80 60 01 51 ; &19 &663b 40 01 81 60 51 ; &1a &6640 01 81 41 60 51 ; &1b &6645 40 51 61 80 01 ; &1c &664a 51 61 41 80 01 ; &1d &664f 40 01 81 51 61 ; &1e &6654 01 81 51 61 41 ; &1f ; wall_patterns_address_table &6659 c5 66 ; &66c5 = wall_pattern_01 ; room type &01 &665b c5 66 ; &66c5 = wall_pattern_01 &665d e5 66 ; &66e5 = wall_pattern_02 ; room type &02 &665f e5 66 ; &66e5 = wall_pattern_02 &6661 05 67 ; &6705 = wall_pattern_03 ; room type &03 &6663 45 67 ; &6745 = wall_pattern_05 &6665 25 67 ; &6725 = wall_pattern_04 ; room type &04 &6667 65 67 ; &6765 = wall_pattern_06 &6669 45 67 ; &6745 = wall_pattern_05 ; room type &05 &666b c5 66 ; &66c5 = wall_pattern_01 &666d 65 67 ; &6765 = wall_pattern_06 ; room type &06 &666f c5 66 ; &66c5 = wall_pattern_01 &6671 45 67 ; &6745 = wall_pattern_05 ; room type &07 &6673 45 67 ; &6745 = wall_pattern_05 &6675 85 67 ; &6785 = wall_pattern_07 ; room type &08 &6677 85 67 ; &6785 = wall_pattern_07 &6679 a5 67 ; &67a5 = wall_pattern_08 ; room type &09 &667b a5 67 ; &67a5 = wall_pattern_08 &667d c5 67 ; &67c5 = wall_pattern_09 ; room type &0a &667f c5 67 ; &67c5 = wall_pattern_09 &6681 e5 67 ; &67e5 = wall_pattern_0a ; room type &0b &6683 45 67 ; &6745 = wall_pattern_05 &6685 05 68 ; &6805 = wall_pattern_0b ; room type &0c &6687 85 67 ; &6785 = wall_pattern_07 &6689 25 68 ; &6825 = wall_pattern_0c ; room type &0d &668b c5 66 ; &66c5 = wall_pattern_01 &668d 45 68 ; &6845 = wall_pattern_0d ; room type &0e &668f c5 66 ; &66c5 = wall_pattern_01 &6691 65 68 ; &6865 = wall_pattern_0e ; room type &0f &6693 65 68 ; &6865 = wall_pattern_0e &6695 85 68 ; &6885 = wall_pattern_0f ; room type &10 &6697 85 68 ; &6885 = wall_pattern_0f &6699 a5 68 ; &68a5 = wall_pattern_10 ; room type &11 &669b a5 68 ; &68a5 = wall_pattern_10 &669d c5 68 ; &68c5 = wall_pattern_11 ; room type &12 &669f c5 68 ; &68c5 = wall_pattern_11 &66a1 e5 68 ; &68e5 = wall_pattern_12 ; room type &13 &66a3 15 6a ; &6a15 = wall_pattern_1c &66a5 25 69 ; &6925 = wall_pattern_14 ; room type &14 &66a7 c5 66 ; &66c5 = wall_pattern_01 &66a9 45 69 ; &6945 = wall_pattern_15 ; room type &15 &66ab 45 67 ; &6745 = wall_pattern_05 &66ad 65 69 ; &6965 = wall_pattern_16 ; room type &16 &66af 65 67 ; &6765 = wall_pattern_06 &66b1 85 69 ; &6985 = wall_pattern_17 ; room type &17 &66b3 45 67 ; &6745 = wall_pattern_05 &66b5 a5 69 ; &69a5 = wall_pattern_18 ; room type &18 &66b7 05 69 ; &6905 = wall_pattern_13 &66b9 c5 69 ; &69c5 = wall_pattern_19 ; room type &19 &66bb 45 67 ; &6745 = wall_pattern_05 &66bd e5 69 ; &69e5 = wall_pattern_1a ; room type &1a &66bf 65 67 ; &6765 = wall_pattern_06 &66c1 05 6a ; &6a05 = wall_pattern_1b ; room type &1b &66c3 a5 69 ; &69a5 = wall_pattern_18 ; wall_patterns # Sixteen bytes per side (right, left), 1d 1u 2d 2u etc ; wall_pattern_01 &66c5 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 # Brick wall &66d5 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 # Brick wall ; wall_pattern_02 &66e5 11 18 0f 17 10 00 0f 01 10 00 0f 01 10 17 11 16 # Three closed doors &66f5 11 16 10 17 0f 01 10 00 0f 01 10 00 0f 17 11 18 # Three closed door ; wall_pattern_03 &6705 18 18 00 17 01 17 00 00 01 01 00 17 01 17 16 16 # Three wooden window &6715 16 16 01 17 00 17 17 01 17 00 01 17 00 17 18 18 # Two wooden windows ; wall_pattern_04 &6725 18 18 17 17 17 17 17 17 17 17 17 17 17 17 16 16 # Wooden panels &6735 16 16 17 17 17 17 17 17 17 17 17 17 17 17 18 18 # Wooden panels ; wall_pattern_05 &6745 18 18 0c 17 0d 17 17 17 17 17 0c 17 0d 17 16 16 # Leaded windows and wooden panel &6755 16 16 0d 0d 0c 0c 05 17 04 17 0d 0d 0c 0c 18 18 # Leaded windows and open door ; wall_pattern_06 &6765 18 18 00 00 01 01 04 00 05 01 00 00 01 01 16 16 # Windows and open door &6775 16 16 17 01 17 00 10 01 0f 00 17 01 17 00 18 18 # Wooden panels and closed door ; wall_pattern_07 &6785 18 18 0c 17 0d 17 02 0c 03 0d 0c 17 0d 17 16 16 # Windows and open door &6795 16 16 01 17 00 17 17 0d 17 0c 01 17 00 17 18 18 # Wooden panels and closed door ; wall_pattern_08 &67a5 18 18 00 0c 01 0d 04 0c 05 0d 00 0c 01 0d 16 16 # Windows and open door &67b5 16 16 17 01 17 00 05 17 04 17 17 01 17 00 18 18 # Wooden panels and closed door ; wall_pattern_09 &67c5 02 11 03 06 02 07 03 06 02 07 03 06 02 07 03 09 # Archways &67d5 03 09 02 07 03 06 02 07 03 06 02 07 03 06 02 11 # Archways ; wall_pattern_0a &67e5 11 11 14 08 15 06 0f 07 10 06 0f 07 10 08 09 09 # Alcove and two closed doors &67f5 09 09 15 08 14 07 15 06 14 07 15 06 14 08 11 11 # Three alcoves ; wall_pattern_0b &6805 11 11 14 0a 15 0b 0f 08 10 08 14 0a 15 0b 09 09 # Alcoves and closed door &6815 09 09 15 0b 14 0a 10 08 0f 08 15 0b 14 0a 11 11 # Alcoves and closed door ; wall_pattern_0c &6825 11 11 14 08 15 06 0f 07 10 06 0f 07 10 08 09 09 # Alcove and two closed doors &6835 09 09 15 08 14 07 03 06 02 07 15 06 14 08 11 11 # Alcoves and open door ; wall_pattern_0d &6845 11 11 13 06 08 07 04 08 05 08 08 06 13 07 09 09 # Stone wall and open door &6855 09 09 13 07 08 06 13 08 08 08 13 08 08 08 11 11 # Stone wall and windows ; wall_pattern_0e &6865 11 11 08 08 08 08 0f 08 10 08 08 08 08 08 09 09 # Stone wall and closed door &6875 09 09 0b 0b 0a 0a 03 08 02 08 0b 0b 0a 0a 11 11 # Stone wall and open door ; wall_pattern_0f &6885 11 11 0e 0a 0e 0b 02 0a 03 0b 14 0a 15 0b 09 09 # Stone wall and open door and alcove &6895 09 09 08 0b 0e 0a 08 0b 0e 0a 08 0b 0e 0a 11 11 # Stone wall and arrow slits ; wall_pattern_10 &68a5 11 11 0f 0e 10 0e 02 0e 03 0e 0f 0e 10 0e 09 09 # Closed doors and open door &68b5 09 09 10 0e 0f 0e 03 0e 02 0e 10 0e 0f 0e 11 11 # Closed doors and open door ; wall_pattern_11 &68c5 18 18 17 17 00 17 01 17 00 0c 01 0d 17 17 16 16 # Wooden panel and two flat windows &68d5 16 16 17 17 0d 17 0c 0d 17 0c 05 17 04 17 18 18 # Open door and leaded window ; wall_pattern_12 &68e5 11 11 08 08 13 06 08 07 13 06 14 07 15 08 09 09 # Stone wall and alcove &68f5 09 09 08 08 15 08 14 07 08 06 13 08 08 08 11 11 # Alcove and stone wall ; wall_pattern_13 &6905 08 08 02 08 03 08 08 08 0e 08 0e 08 0e 08 09 09 # Stone wall, open door and arrow slits &6915 09 09 0b 08 0a 08 0b 08 0a 08 0b 08 0a 08 08 08 # Stone wall and small windows ; wall_pattern_14 &6925 0e 08 08 08 08 08 02 08 03 08 08 08 08 08 08 09 # Stone wall and open door &6935 08 09 08 08 08 08 03 08 02 08 08 08 08 08 0e 09 # Stone wall and open door ; wall_pattern_15 &6945 11 11 08 08 0e 08 08 08 0e 08 08 08 0e 08 0e 08 # Stone wall and arrow slits &6955 0e 08 0e 08 0e 08 0e 08 0e 08 0e 08 0e 08 0e 09 # Stone wall and arrow slits ; wall_pattern_16 &6965 11 11 0e 08 02 08 03 08 0e 08 0e 08 0e 08 0e 08 # Stone wall, arrow slits and open door &6975 0e 08 08 08 08 08 03 08 02 08 08 08 08 08 11 11 # Stone wall, arrow slits and open door ; wall_pattern_17 &6985 0e 08 0e 08 0e 08 0e 08 08 08 0e 08 0e 08 09 09 # Stone wall and arrow slits &6995 09 09 0e 08 0e 08 0e 08 0e 08 0e 08 0e 08 0e 08 # Stone wall and arrow slits ; wall_pattern_18 &69a5 08 08 08 08 08 08 02 08 03 08 08 08 08 08 08 08 # Stone wall and open door &69b5 08 08 08 08 08 08 03 08 02 08 08 08 08 08 08 08 # Stone wall and open door ; wall_pattern_19 &69c5 08 11 08 0e 0e 0e 02 08 03 08 0e 0e 08 0e 08 08 # Stone wall and open door &69d5 08 08 0b 0e 0a 0e 0b 08 0a 08 0e 08 0e 08 11 11 # Stone wall and small windows ; wall_pattern_1a &69e5 11 11 0a 08 0b 08 0a 0e 0b 0e 0e 08 0e 08 08 08 # Stone wall and small windows &69f5 08 08 08 08 08 08 03 08 02 08 08 08 08 08 08 08 # Stone wall and open door ; wall_pattern_1b &6a05 08 08 0a 08 0b 08 0a 0e 0b 0e 0e 08 0e 08 09 09 # Stone wall and small windows ; wall_pattern_1c &6a15 09 09 08 08 08 08 0e 0e 0e 0e 08 08 08 08 08 08 # Stone wall and arrow slits &6a25 08 08 03 08 02 08 08 08 08 08 08 08 08 08 08 08 # Stone wall and open door ; wall_sections_address_table &6a35 6b 6a ; &6a6b = wall_sections_01 &6a37 6b 6a ; &6a6b = wall_sections_02 &6a39 7c 6a ; &6a7c = wall_sections_03 &6a3b 91 6a ; &6a91 = wall_sections_04 &6a3d a6 6a ; &6aa6 = wall_sections_05 &6a3f bb 6a ; &6abb = wall_sections_06 &6a41 d0 6a ; &6ad0 = wall_sections_07 &6a43 e9 6a ; &6ae9 = wall_sections_08 &6a45 02 6b ; &6b02 = wall_sections_09 &6a47 23 6b ; &6b23 = wall_sections_0a &6a49 7c 6a ; &6a7c = wall_sections_0b &6a4b 91 6a ; &6a91 = wall_sections_0c &6a4d a6 6a ; &6aa6 = wall_sections_0d &6a4f bb 6a ; &6abb = wall_sections_0e &6a51 d0 6a ; &6ad0 = wall_sections_0f &6a53 e9 6a ; &6ae9 = wall_sections_10 &6a55 02 6b ; &6b02 = wall_sections_11 &6a57 64 6b ; &6b64 = wall_sections_12 &6a59 1b 6c ; &6c1b = wall_sections_13 &6a5b 7d 6b ; &6b7d = wall_sections_14 &6a5d 7c 6a ; &6a7c = wall_sections_15 &6a5f 96 6b ; &6b96 = wall_sections_16 &6a61 7c 6a ; &6a7c = wall_sections_17 &6a63 b3 6b ; &6bb3 = wall_sections_18 &6a65 d0 6b ; &6bd0 = wall_sections_19 &6a67 e9 6b ; &6be9 = wall_sections_1a &6a69 02 6c ; &6c02 = wall_sections_1b ; wall_sections_01 ; wall_sections_02 ; x + y + &6a6b 40 80 40 02 &6a6f be 02 40 80 &6a77 40 80 be 02 &6a73 40 02 40 80 &6a7b 00 ; wall_sections_03 ; wall_sections_0b ; wall_sections_15 ; wall_sections_17 ; x + y + &6a7c 40 80 40 02 &6a80 be 02 40 80 &6a84 40 80 be 02 &6a88 40 02 40 30 &6a8c 40 02 90 30 &6a90 00 ; wall_sections_04 ; wall_sections_0c ; x + y + &6a91 40 80 40 02 &6a95 be 02 40 80 &6a99 40 30 be 02 &6a9d 90 30 be 02 &6aa1 40 02 40 80 &6aa5 00 ; wall_sections_05 ; wall_sections_0d ; x + y + &6aa6 40 80 40 02 &6aaa be 02 40 30 &6aae be 02 90 30 &6ab2 40 80 be 02 &6ab6 40 02 40 80 &6aba 00 ; wall_sections_06 ; wall_sections_0e ; x + y + &6abb 40 30 40 02 &6abf 90 30 40 02 &6ac3 be 02 40 80 &6ac7 40 80 be 02 &6acb 40 02 40 80 &6acf 00 ; wall_sections_07 ; wall_sections_0f ; x + y + &6ad0 40 80 40 02 &6ad4 40 80 be 02 &6ad8 40 02 40 30 &6adc 40 02 90 30 &6ae0 be 02 40 30 &6ae4 be 02 90 30 &6ae8 00 ; wall_sections_08 ; wall_sections_10 ; x + y + &6ae9 40 30 40 02 &6aed 90 30 40 02 &6af1 40 30 be 02 &6af5 90 30 be 02 &6af9 40 02 40 80 &6afd be 02 40 80 &6b01 00 ; wall_sections_09 ; wall_sections_11 ; x + y + &6b02 40 30 40 02 &6a06 90 30 40 02 &6a0a 40 30 be 02 &6a0e 90 30 be 02 &6a12 40 02 40 30 &6a16 40 02 90 30 &6a1a be 02 40 30 &6a1e be 02 90 30 &6b22 00 ; wall_sections_0a ; x + y + &6b23 40 02 40 02 &6a27 5c 08 40 02 &6a2b 7c 08 40 02 &6a2f 9c 08 40 02 &6a33 be 02 40 02 &6a37 be 02 5c 08 &6a3b be 02 7c 08 &6a3f be 02 9c 08 &6a43 be 02 be 02 &6a47 40 02 5c 08 &6a4b 40 02 7c 08 &6a4f 40 02 9c 08 &6a53 40 02 be 02 &6a57 5c 08 be 02 &6a5b 7c 08 be 02 &6a5f 9c 08 be 02 &6a63 00 ; wall_sections_12 ; x + y + &6b64 40 80 40 02 &6a68 40 80 be 02 &6a6c be 02 40 50 &6a70 be 02 b0 10 &6a74 40 02 40 10 &6a78 40 02 70 50 &6b7c 00 ; wall_sections_14 ; x + y + &6b7d 40 30 40 02 &6a81 90 30 40 02 &6a85 be 02 40 30 &6a89 be 02 90 30 &6a8d 40 80 be 02 &6a91 40 02 40 80 &6b95 00 ; wall_sections_16 ; x + y + &6b96 40 20 40 02 &6a9a 80 40 40 02 &6a9e be 02 40 30 &6aa2 be 02 90 30 &6aa6 40 30 be 02 &6aaa 90 30 be 02 &6aae 40 02 40 80 &6bb2 00 ; wall_sections_18 ; x + y + &6bb3 40 30 40 02 &6ab7 90 30 40 02 &6abb be 02 40 30 &6abf be 02 90 30 &6ac3 40 02 40 80 &6ac7 40 50 be 02 &6acb b0 10 be 02 &6acf 00 ; wall_sections_19 ; x + y + &6bd0 40 30 40 02 &6bd4 90 30 40 02 &6bd8 be 02 40 80 &6bdc 40 80 be 02 &6be0 40 02 40 30 &6be4 40 02 90 30 &6be8 00 ; wall_sections_1a ; x + y + &6be9 40 80 40 02 &6bed be 02 40 30 &6bf1 be 02 90 30 &6bf5 40 02 40 80 &6bf9 40 30 be 02 &6bfd 90 30 be 02 &6c01 00 ; wall_sections_1b ; x + y + &6c02 40 80 40 02 &6c06 be 02 40 80 &6c0a 40 02 40 30 &6c0e 40 02 90 30 &6c12 40 30 be 02 &6c16 90 30 be 02 &6c1a 00 ; wall_sections_13 ; x + y + &6c1b 40 80 40 02 &6c1f be 02 40 80 &6c23 40 80 be 02 &6c27 40 02 40 50 &6c2b 40 02 b0 10 &6c2f 00 ; unused &6c30 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa &6c40 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa &6c50 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa &6c60 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa &6c70 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa # &6c80 - &6ca7 is copied to &0fb0 - &0fd7 at &6ce3 ; score_sprite &6c80 38 64 60 3c 06 86 c6 7c ; "S" &6c88 0e 32 60 40 c0 c2 e6 7c ; "C" &6c90 38 6c c6 c6 c6 c6 6c 38 ; "O" &6c98 f8 6c 66 76 7e 78 6c e6 ; "R" &6ca0 fe 60 64 7c 64 60 7a c6 ; "E" ; irq1_handler_address &6ca8 02 5b ; &5b02 = irq1_handler ; start_game_address &6caa 22 4d ; &4d22 = start_game ; original_entry_point &6cac 78 SEI &6cad a2 ff LDX #&ff &6caf 9a TXS &6cb0 a9 00 LDA #&00 &6cb2 a2 0f LDX #&0f ; remove_roms_loop &6cb4 9d a1 02 STA &02a1,X ; os_paged_rom_type_table # Remove paged ROMs from ROM information table &6cb7 ca DEX &6cb8 10 fa BPL &6cb4 ; remove_roms_loop &6cba a2 90 LDX #&90 ; wipe_0290_to_02ff_loop &6cbc 9d 00 02 STA &0200,X # Wipe &0290 - &02ff &6cbf e8 INX &6cc0 d0 fa BNE &6cbc ; wipe_0290_to_02ff_loop &6cc2 a0 0e LDY #&0e ; wipe_0300_to_10ff_loop &6cc4 9d 00 03 STA &0300,X # Wipe &0300 - &10ff # actually STA wipe_address,X &6cc7 e8 INX &6cc8 d0 fa BNE &6cc4 ; wipe_0300_to_10ff_loop &6cca ee c6 6c INC &6cc6 ; wipe_address_high &6ccd 88 DEY &6cce d0 f4 BNE &6cc4 ; wipe_0300_to_10ff_loop &6cd0 a0 06 LDY #&06 ; set_video_registers_loop &6cd2 b9 7f 6d LDA &6d7f,Y ; video_register_numbers &6cd5 be 86 6d LDX &6d86,Y ; video_register_values &6cd8 8d 00 fe STA &fe00 ; video register number &6cdb 8e 01 fe STX &fe01 ; video register value &6cde 88 DEY &6cdf 10 f1 BPL &6cd2 ; set_video_registers_loop &6ce1 a2 27 LDX #&27 ; plot_score_sprite_loop &6ce3 bd 80 6c LDA &6c80,X ; score_sprite # Move &6c80 - &6ca7 to &0fb0 - &0fd7 &6ce6 9d b0 0f STA &0fb0,X &6ce9 ca DEX &6cea 10 f7 BPL &6ce3 ; plot_score_sprite_loop &6cec a2 df LDX #&df ; relocate_font_data &6cee bd 90 6d LDA &6d90,X ; unrelocated_font_data # Move &6d90 - &6e6f to &0100 - &01df &6cf1 9d 00 01 STA &0100,X ; font_data &6cf4 ca DEX &6cf5 e0 ff CPX #&ff &6cf7 d0 f5 BNE &6cee ; relocate_font_data &6cf9 a2 00 LDX #&00 ; make_bit_shifted_tables_byte_loop &6cfb 8a TXA &6cfc 4a LSR A &6cfd 4a LSR A &6cfe 9d 00 79 STA &7900,X ; bits_shifted_right_two_bits &6d01 4a LSR A &6d02 4a LSR A &6d03 9d 00 7b STA &7b00,X ; bits_shifted_right_four_bits &6d06 4a LSR A &6d07 4a LSR A &6d08 9d 00 7d STA &7d00,X ; bits_shifted_right_six_bits &6d0b 8a TXA &6d0c 0a ASL A &6d0d 0a ASL A &6d0e 9d 00 7e STA &7e00,X ; bits_shifted_left_two_bits &6d11 0a ASL A &6d12 0a ASL A &6d13 9d 00 7c STA &7c00,X ; bits_shifted_left_four_bits &6d16 0a ASL A &6d17 0a ASL A &6d18 9d 00 7a STA &7a00,X ; bits_shifted_left_six_bits &6d1b a0 08 LDY #&08 &6d1d a9 01 LDA #&01 &6d1f 8d 8e 6d STA &6d8e ; bit &6d22 a9 80 LDA #&80 &6d24 8d 8f 6d STA &6d8f ; reversed_bit &6d27 a9 00 LDA #&00 &6d29 8d 8d 6d STA &6d8d ; reversed_byte ; make_bit_reversed_byte_loop &6d2c 8a TXA &6d2d 2d 8e 6d AND &6d8e ; bit &6d30 f0 0a BEQ &6d3c ; bit_unset &6d32 ad 8f 6d LDA &6d8f ; reversed_bit &6d35 18 CLC &6d36 6d 8d 6d ADC &6d8d ; reversed_byte &6d39 8d 8d 6d STA &6d8d ; reversed_byte ; bit_unset &6d3c 0e 8e 6d ASL &6d8e ; bit &6d3f 4e 8f 6d LSR &6d8f ; reversed_bit &6d42 88 DEY &6d43 d0 e7 BNE &6d2c ; make_bit_reversed_byte_loop &6d45 ad 8d 6d LDA &6d8d ; reversed_byte &6d48 9d 00 7f STA &7f00,X ; bit_reversed_bytes &6d4b e8 INX &6d4c d0 ad BNE &6cfb ; make_bit_shifted_tables_byte_loop &6d4e a9 7f LDA #&7f # Disable all interrupts &6d50 8d 4e fe STA &fe4e ; System VIA interrupt enable register &6d53 8d 6e fe STA &fe6e ; User VIA interrupt enable register &6d56 a9 c2 LDA #&c2 # Enable System VIA timer 1 and CA1 (v-sync) interrupts &6d58 8d 4e fe STA &fe4e ; System VIA interrupt enable register &6d5b ad a8 6c LDA &6ca8 ; irq1_handler_address_low &6d5e 8d 04 02 STA &0204 ; irq1_vector_low &6d61 ad a9 6c LDA &6ca9 ; irq1_handler_address_high &6d64 8d 05 02 STA &0205 ; irq1_vector_high &6d67 a9 ff LDA #&ff &6d69 8d 45 fe STA &fe45 ; System VIA timer 1 counter MSB &6d6c a9 01 LDA #&01 &6d6e 85 05 STA &05 ; sound_enabled &6d70 a9 4c LDA #&4c &6d72 85 00 STA &00 ; rnd_0 &6d74 a9 45 LDA #&45 &6d76 85 01 STA &01 ; rnd_1 &6d78 a9 04 LDA #&04 &6d7a 85 02 STA &02 ; rnd_2 &6d7c 6c aa 6c JMP (&6caa) ; start_game_address # Set video registers: # &06 = &15 ; R6: Vertical displayed register # 184 pixels high # &01 = &16 ; R1: Number of characters per line # 192 pixels wide # &02 = &29 ; R2: Horizontal sync position register # &07 = &1e ; R7: Vertical sync position # &0c = &00 ; R12: Displayed screen start address register (high) # &0d = &52 ; R13: Displayed screen start address register (low) # Set screen start address to &0290 (ends at &10ff) # &0a = &20 ; R10: Cursor start register # Disable cursor ; video_register_numbers &6d7f 06 01 02 07 0c 0d 0a ; video_register_values &6d86 15 16 29 1e 00 52 20 ; reversed_byte &6d8d ea ; bit &6d8e ea ; reversed_bit &6d8f ea # &6d90 - &6e6f is moved to &0100 - &01df at &6cee ; font_data &0100 38 6c d6 d6 d6 d6 6c 38 ; &00 = "0" &0108 18 38 58 18 18 18 18 7c ; &01 = "1" &0110 38 4c 0c 3c 60 c2 c2 fe ; &02 = "2" &0118 38 4c 0c 3c 0e 86 86 fc ; &03 = "3" &0120 18 38 58 9a fe 1a 18 7c ; &04 = "4" &0128 fe c2 c0 fc 06 06 86 7c ; &05 = "5" &0130 1e 32 60 7c c6 c6 c6 7c ; &06 = "6" &0138 7e 46 4c 0c 18 18 30 f8 ; &07 = "7" &0140 38 6c 6c 7c fe c6 c6 7c ; &08 = "8" &0148 7c c6 c6 c6 7c 0c 98 f0 ; &09 = "9" &0150 0c 1c 2e 66 46 ce db 66 ; &0a = "A" &0158 0e 32 60 40 c0 c2 e6 7c ; &0b = "C" &0160 60 70 68 6c 66 66 66 fc ; &0c = "D" &0168 fe 60 64 7c 64 60 7a c6 ; &0d = "E" &0170 0e 30 60 c6 ce f6 66 0e ; &0e = "G" &0178 ee c6 c6 fe c6 c6 c6 ee ; &0f = "H" &0180 7c 18 18 18 18 18 18 7c ; &10 = "I" &0188 e0 60 60 60 60 60 62 fe ; &11 = "L" &0190 c6 ee ee d6 d6 d6 c6 ee ; &12 = "M" &0198 cc d6 d6 e6 e4 c4 c8 de ; &13 = "N" &01a0 38 6c c6 c6 c6 c6 6c 38 ; &14 = "O" &01a8 f8 6c 66 76 6e 60 60 f0 ; &15 = "P" &01b0 f8 6c 66 76 7e 78 6c e6 ; &16 = "R" &01b8 38 64 60 3c 06 86 c6 7c ; &17 = "S" &01c0 fe 9a 98 18 18 18 18 18 ; &18 = "T" &01c8 e2 62 64 64 68 68 70 60 ; &19 = "V" &01d0 fe 60 64 7c 64 60 60 f0 ; &1a = "F" &01d8 00 00 00 00 00 00 00 00 ; &1b = " " ; unused &6e70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6e80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6e90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6ea0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6ec0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6ed0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6ee0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &6ef0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; unused &6f00 0b 31 19 d3 fb ef 67 0b fb f7 df fb c3 df f7 fb &6f10 78 1b 03 2f 0f 63 1b 7b d7 73 9b 67 67 5b 71 89 &6f20 c1 ed d5 c1 3e d3 db f7 c5 bb d3 ff fd c1 25 d7 &6f30 21 71 c3 af cf e3 71 21 17 67 45 69 71 03 6b df &6f40 e7 77 85 79 51 7b 77 f9 37 4f 63 20 1b 87 ef 71 &6f50 e3 83 99 35 15 f9 01 05 cf 6b 05 79 75 49 79 8c &6f60 e1 7b 47 73 0b 63 7b ef 0f eb 03 1f 1f 03 6b 0f &6f70 1f 1b 03 e8 09 25 1d 19 69 0d 25 19 19 e5 0d 29 &6f80 19 1d 65 09 29 05 1c 17 07 23 0b 17 17 0b 23 07 &6f90 17 13 0b 27 07 6b 13 17 27 03 e8 15 15 29 01 65 &6fa0 15 11 29 05 e5 09 11 15 05 61 09 15 15 09 e0 07 &6fb0 17 13 0b 67 07 2b 13 17 e7 03 2b 17 17 6b 03 27 &6fc0 17 13 e5 09 29 05 1d 19 09 2d 05 19 19 05 2d 09 &6fd0 19 1d 05 29 09 e4 1b 1f 2f 0b 63 1f 1f 23 0b ef &6fe0 1f 1b 23 0f 6f 03 1b 1f 0f e8 01 1d 1d 01 69 0d &6ff0 1d 19 01 ed 0d 21 19 1d 6d 09 21 1d 1d e3 0b 2f # &7000 - &70ff is unencrypted ; second_stage_via_decryption &7000 ad 00 70 LDA &7000 ; second_stage_via_decryption # Ensure &7000 - &70ff hasn't been changed # actually LDA &7000 + second_stage_via_decryption_offset &7003 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7006 ee 69 fe INC &fe69 ; User VIA timer 2 counter MSB &7009 4d 69 fe EOR &fe69 ; User VIA timer 2 counter MSB &700c ae 64 fe LDX &fe64 ; User VIA timer 1 counter LSB &700f 4d 67 fe EOR &fe67 ; User VIA timer 1 latch MSB &7012 5d cd d9 EOR &d9cd,X ; os_reset_handler # Ensure OS reset handler hasn't been changed &7015 ce 69 fe DEC &fe69 ; User VIA timer 2 counter MSB &7018 ce 1c 70 DEC &701c ; second_stage_via_decryption_eor &701b 49 dd EOR #&dd # actually EOR second_stage_via_decryption_eor &701d ae 68 fe LDX &fe68 ; User VIA timer 2 counter LSB &7020 59 00 ff EOR &ff00,Y # Ensure OS ROM from &ff00 to &ffff hasn't been changed &7023 48 PHA &7024 ad 69 fe LDA &fe69 ; User VIA timer 2 counter MSB &7027 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &702a ee 69 fe INC &fe69 ; User VIA timer 2 counter MSB &702d 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7030 18 CLC &7031 6d 65 fe ADC &fe65 ; User VIA timer 1 latch MSB &7034 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &7037 68 PLA &7038 5d 00 70 EOR &7000,X ; second_stage_via_decryption # Ensure &7000 - &70ff hasn't been changed &703b ce 65 fe DEC &fe65 ; User VIA timer 1 latch MSB &703e 8e 4d 70 STX &704d ; second_stage_via_decryption_add_one &7041 59 01 71 EOR &7101,Y ; second_stage_payload + 1 &7044 38 SEC &7045 2e 69 fe ROL &fe69 ; User VIA timer 2 counter MSB &7048 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &704b 18 CLC &704c 69 fe ADC #&fe # actually ADC second_stage_via_decryption_add_one &704e ee 65 fe INC &fe65 ; User VIA timer 1 latch MSB &7051 4d 67 fe EOR &fe67 ; User VIA timer 1 latch MSB &7054 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &7057 59 00 09 EOR &0900,Y ; small_table # small_table initialised in tape loader &705a 38 SEC &705b 6e 68 fe ROR &fe68 ; User VIA timer 2 counter LSB &705e 5d 1c dc EOR &dc1c,X ; os_irq_handler # Ensure OS main IRQ handler hasn't been changed &7061 ae 69 fe LDX &fe69 ; User VIA timer 2 counter MSB &7064 8e 79 70 STX &7079 ; second_stage_via_decryption_add_two &7067 4d 66 fe EOR &fe66 ; User VIA timer 1 latch LSB &706a 38 SEC &706b ed 01 70 SBC &7001 ; second_stage_via_decryption_offset &706e ae 68 fe LDX &fe68 ; User VIA timer 2 counter LSB &7071 59 00 71 EOR &7100,Y ; second_stage_payload # Ensure &7100 - &71ff hasn't been changed &7074 ee 68 fe INC &fe68 ; User VIA timer 2 counter LSB &7077 18 CLC &7078 69 ff ADC #&ff # actually ADC second_stage_via_decryption_add_two &707a 5d 40 d9 EOR &d940,X ; os_default_vector_table # Ensure OS default vector table hasn't been changed &707d 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &7080 49 92 EOR #&92 &7082 99 00 71 STA &7100,Y ; second_stage_payload &7085 a9 40 LDA #&40 ; RTI &7087 8d 00 0d STA &0d00 ; NMI entry point &708a 88 DEY &708b f0 03 BEQ &7090 ; next_round ; to_second_stage_via_decryption &708d 4c 00 70 JMP &7000 ; second_stage_via_decryption ; next_round &7090 a9 03 LDA #&03 # Enable ESCAPE, clear memory on BREAK &7092 8d 58 02 STA &0258 ; ESCAPE/BREAK effect &7095 a9 4c LDA #&4c ; JMP # Set BREAK intercept code to JMP &0287, endless loop &7097 8d 87 02 STA &0287 ; BREAK intercept code &709a a9 87 LDA #&87 &709c 8d 88 02 STA &0288 ; BREAK intercept code + 1 &709f a9 02 LDA #&02 &70a1 8d 89 02 STA &0289 ; BREAK intercept code + 2 &70a4 a0 35 LDY #&35 # Reset all vectors to OS defaults ; reset_vector_table_loop &70a6 b9 40 d9 LDA &d940,Y ; os_default_vector_table &70a9 99 00 02 STA &0200,Y ; os_vector_table &70ac 88 DEY &70ad 10 f7 BPL &70a6 ; reset_vector_table_loop &70af c8 INY &70b0 ee 01 70 INC &7001 ; second_stage_via_decryption_offset &70b3 d0 d8 BNE &708d ; to_second_stage_via_decryption ; calculate_checksum_after_second_stage &70b5 a9 00 LDA #&00 &70b7 85 70 STA &70 ; checksum_one &70b9 85 71 STA &71 ; checksum_two &70bb a8 TAY ; calculate_checksum_loop &70bc a5 71 LDA &71 ; checksum_two &70be 59 00 71 EOR &7100,Y ; second_stage_payload &70c1 85 71 STA &71 ; checksum_two &70c3 a2 08 LDX #&08 ; calculate_checksum_inner_loop &70c5 a5 71 LDA &71 ; checksum_two &70c7 2a ROL A &70c8 90 0c BCC &70d6 &70ca a5 71 LDA &71 ; checksum_two &70cc 49 08 EOR #&08 &70ce 85 71 STA &71 ; checksum_two &70d0 a5 70 LDA &70 ; checksum_one &70d2 49 10 EOR #&10 &70d4 85 70 STA &70 ; checksum_one &70d6 26 70 ROL &70 ; checksum_one &70d8 26 71 ROL &71 ; checksum_two &70da ca DEX &70db d0 e8 BNE &70c5 ; calculate_checksum_inner_loop &70dd c8 INY &70de c0 20 CPY #&20 &70e0 d0 da BNE &70bc ; calculate_checksum_loop &70e2 a5 70 LDA &70 ; checksum_one &70e4 cd fe 71 CMP &71fe &70e7 d0 07 BNE &70f0 ; invalid_checksum &70e9 a5 71 LDA &71 ; checksum_two &70eb cd ff 71 CMP &71ff &70ee f0 10 BEQ &7100 ; second_stage_payload ; invalid_checksum &70f0 a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect # This is handled by the OS OSBYTE handler at &e99c, &70f2 a2 03 LDX #&03 ; Clear memory on next RESET # which isn't checked in the decryption routine, &70f4 a0 00 LDY #&00 # so could be intercepted with a custom ROM &70f6 20 f4 ff JSR &fff4 ; OSBYTE ; wipe_second_stage_payload_loop &70f9 99 00 71 STA &7100,Y ; second_stage_payload_loop &70fc c8 INY &70fd 4c f9 70 JMP &70f9 ; wipe_second_stage_payload_loop # &7100 - &71ff decrypted by second_stage_via_decryption ; second_stage_payload &7100 ad 40 02 LDA &0240 ; os_cfs_timeout_counter # Set to &22 at &0e23 of tape loader, ; compare_cfs_timeout_counter &7103 c9 22 CMP #&22 # decremented every v-sync if interrupts enabled # becomes CMP Y # Overwritten at &7107 if tampering detected &7105 f0 06 BEQ &710d ; cfs_timeout_counter_hasn't_changed &7107 8c 04 71 STY &7104 ; compare_cfs_timeout_counter + 1 ; to_tampering_detected &710a 4c 9c 71 JMP &719c ; tampering_detected ; cfs_timeout_counter_hasn't_changed &710d a9 0e LDA #&0e # R14: Memory-address of text-cursor (high) &710f 8d 00 fe STA &fe00 ; video register number &7112 ad 01 fe LDA &fe01 ; video register value &7115 c9 3d CMP #&3d # Set to &3d at &0e07 of tape loader &7117 d0 f1 BNE &710a ; to_tampering_detected &7119 a9 0f LDA #&0f # R15: Memory-address of text-cursor (low) &711b 8d 00 fe STA &fe00 ; video register number &711e ad 01 fe LDA &fe01 ; video register value &7121 c9 b4 CMP #&b4 # Set to &b4 at &0e10 of tape loader &7123 d0 e5 BNE &710a ; to_tampering_detected ; push_return_address_high &7125 a9 6c LDA #&6c # Push &6c, &ab to stack # becomes LDA Y # Overwritten at &712b &7127 48 PHA # i.e return address of &6cac = original_entry_point ; push_return_address_low &7128 a9 ab LDA #&ab # becomes LDA Y # Overwritten at &712e &712a 48 PHA &712b 8c 26 71 STY &7126 ; push_return_address_high + 1 &712e 8c 29 71 STY &7129 ; push_return_address_low + 1 &7131 ad 46 fe LDA &fe46 ; System VIA timer 1 latch LSB &7134 48 PHA &7135 ad 47 fe LDA &fe47 ; System VIA timer 1 latch MSB &7138 48 PHA &7139 a0 00 LDY #&00 &713b 98 TYA ; wipe_7100_to_713b_loop &713c 99 00 71 STA &7100,Y ; second_stage_payload # Wipe &7100 - &713b with &00 &713f c8 INY &7140 c0 3c CPY #&3c &7142 90 f8 BCC &713c ; wipe_7100_to_713b_loop &7144 a0 00 LDY #&00 ; copy_wipe_memory_if_replay_detected_loop &7146 b9 d3 71 LDA &71d3,Y ; unrelocated_wipe_memory_if_replay_detected &7149 c9 05 CMP #&05 &714b f0 0b BEQ &7158 ; copy_wipe_memory_if_replay_detected_loop ; copy_vector_table_byte &714d 99 10 02 STA &0210,Y ; wipe_memory_if_replay_detected # becomes BRK BRK BRK # Overwritten at &7158 &7150 a9 00 LDA #&00 &7152 99 d3 71 STA &71d3,Y ; unrelocated_wipe_memory_if_replay_detected &7155 c8 INY &7156 d0 ee BNE &7146 ; copy_vector_table_code_loop # Always branches ; copied_vector_table_code &7158 8d 4d 71 STA &714d ; copy_vector_table_byte &715b 8d 4e 71 STA &714e ; copy_vector_table_byte + 1 &715e 8d 4f 71 STA &714f ; copy_vector_table_byte + 2 &7161 a0 00 LDY #&00 &7163 98 TYA ; wipe_719c_to_729b_loop &7164 99 9c 71 STA &719c,Y ; tampering_detected # Wipe &719c - &729b with &00 &7167 99 00 80 STA &8000,Y # Wipe &8000 - &80ff with &00 &716a c8 INY &716b d0 f7 BNE &7164 ; wipe_719c_to_729b_loop ; decrypt_main_binary &716d 68 PLA &716e 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &7171 68 PLA &7172 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &7175 a0 00 LDY #&00 ; decrypt_main_binary_loop &7177 b9 00 11 LDA &1100,Y # Decrypt &1100 to &70ff using VIA timers # actually LDA source_address,Y &717a 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &717d 4d 69 fe EOR &fe69 ; User VIA timer 2 counter MSB &7180 99 00 11 STA &1100,Y # actually STA target_address_Y &7183 c8 INY &7184 d0 f1 BNE &7177 ; decrypt_loop &7186 ee 79 71 INC &7179 ; source_address_high &7189 ee 82 71 INC &7182 ; target_address_high &718c ad 79 71 LDA &7179 ; source_address_high &718f c9 71 CMP #&71 &7191 90 e4 BCC &7177 ; decrypt_main_binary_loop &7193 a0 93 LDY #&93 ; wipe_7101_to_7193_loop &7195 99 00 71 STA &7100,Y ; second_stage_payload # Wipe &7101 to &7193 with &93 &7198 88 DEY &7199 d0 fa BNE &7195 ; wipe_7101_to_7193_loop &719b 60 RTS # Returns to &6cac = original_entry_point (&7125) ; tampering_detected &719c a0 00 LDY #&00 &719e 98 TYA ; wipe_7100_to_719b_loop &719f 99 00 71 STA &7100,Y ; second_stage_payload # Wipe &7100 - &719b with &00 &71a2 c8 INY &71a3 c0 9c CPY #&9c &71a5 d0 f8 BNE &719f ; wipe_7100_to_719b_loop &71a7 a2 00 LDX #&00 ; wipe_0e00_to_6fff_loop &71a9 9d 00 0e STA &0e00,X ; tape_loader_payload # Wipe &0e00 - &6fff with &00 # actually STA wipe_address,X &71ac e8 INX &71ad d0 fa BNE &71a9 ; wipe_0e00_to_0eff_loop &71af ee ab 71 INC &71ab ; wipe_address_high &71b2 ad ab 71 LDA &71ab ; wipe_address_high &71b5 c9 70 CMP #&70 &71b7 90 f0 BCC &71a9 ; wipe_0e00_to_6fff_loop ; decrypt_disk_and_video_unpleasantness_loop &71b9 bd 00 09 LDA &0900,X ; small_table ; decrypt_disk_and_video_unpleasantness_eor &71bc 5d d8 d9 EOR &d9d8,X ; os_reset_handler + 12 # becomes BRK BRK BRK # Overwritten at &71c7 &71bf 9d 00 09 STA &0900,X ; small_table # Decrypt &0900 - &09ff, disk_and_video_unpleasantness &71c2 e8 INX &71c3 d0 f4 BNE &71b9 ; decrypt_disk_and_video_unpleasantness_loop &71c5 a9 00 LDA #&00 &71c7 8d bc 71 STA &71bc ; decrypt_disk_and_video_unpleasantness_eor &71ca 8d bd 71 STA &71bd ; decrypt_disk_and_video_unpleasantness_eor + 1 &71cd 8d be 71 STA &71be ; decrypt_disk_and_video_unpleasantness_eor + 2 &71d0 4c 00 09 JMP &0900 ; disk_and_video_unpleasantness # &71d3 - &71f6 copied to &0210 - &0233 at &714d ; wipe_memory_if_replay_detected &0210 a2 0f LDX #&0f ; check_roms_loop &0212 8e 30 fe STX &fe30 ; paged ROM latch # Check each ROM in turn &0215 ad 00 80 LDA &8000 &0218 c9 b7 CMP #&b7 &021a f0 04 BEQ &0220 ; wipe_memory &021c ca DEX &021d 10 f3 BPL &0212 ; check_roms_loop &021f 60 RTS ; wipe_memory &0220 a9 03 LDA #&03 &0222 85 71 STA &71 ; wipe_address_high &0224 a0 ff LDY #&ff &0226 98 TYA &0227 c8 INY &0228 84 70 STY &70 ; wipe_address_low ; wipe_memory_loop &022a 91 70 STA (&70),Y ; wipe_address &022c c8 INY &022d d0 fb BNE &022a ; wipe_memory_loop &022f e6 71 INC &71 ; wipe_address_high &0231 38 SEC &0232 b0 f6 BCS &022a ; wipe_memory_loop # Always branches; endless loop &71f7 05 # Marks end of code_in_vector_table ; unused &71f8 2a 2a 2a 2a 2a 2a ; first_stage_valid_checksum_one &71fe 79 ; first_stage_valid_checksum_two &71ff de # &7200 - &73ff is unencrypted &7200 00 # Used in final round of second_stage_via_decryption ; unused &7201 20 37 72 JSR &7237 ; unused_decoy_code ; main_binary_entry_point &7204 a9 00 LDA #&00 # Used in final round of first_stage_via_decryption &7206 8d 00 75 STA &7500 ; first_stage_payload + &100 &7209 a9 7f LDA #&7f # Disable all interrupts &720b 8d 4e fe STA &fe4e ; System VIA interrupt enable register &720e 8d 6e fe STA &fe6e ; User VIA interrupt enable register &7211 a9 e0 LDA #&e0 # Enable timer 1 and timer 2 interrupts &7213 8d 4e fe STA &fe4e ; System VIA interrupt enable register &7216 8d 6e fe STA &fe6e ; User VIA interrupt enable register &7219 a9 40 LDA #&40 # Set timer 1 to continuous countdown &721b 8d 6b fe STA &fe6b ; User VIA auxiliary control register &721e a9 43 LDA #&43 &7220 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &7223 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &7226 a5 00 LDA &00 # Use BASIC LOMEM as seed for timers &7228 8d 64 fe STA &fe64 ; User VIA timer 1 counter LSB &722b a5 01 LDA &01 &722d 8d 65 fe STA &fe65 ; User VIA timer 1 latch MSB &7230 a2 00 LDX #&00 &7232 a0 00 LDY #&00 &7234 4c 00 73 JMP &7300 ; first_stage_via_decryption ; unused_decoy_code # Unused code; distraction from use of BASIC LOMEM? &7237 ba TSX &7238 bc 01 01 LDY &0101,X &723b bd 02 01 LDA &0102,X &723e 4d ff 01 EOR &01ff &7241 85 00 STA &00 &7243 a5 70 LDA &70 &7245 59 00 01 EOR &0100,Y &7248 59 00 11 EOR &1100,Y &724b 85 01 STA &01 &724d 60 RTS &724e 20 41 20 62 69 67 20 68 69 20 74 6f 2e 2e 2e 2e ; " A big hi to...." &725e 42 54 57 2c 44 4d 2c 41 6e 64 79 2c 50 50 2c 53 ; "BTW,DM,Andy,PP,S" &726e 70 61 72 72 6f 77 20 6d 61 6e 2c 4d 47 2c 43 4a ; "parrow man,MG,CJ" &727e 20 61 6e 64 20 61 6c 6c 20 6d 65 6d 62 65 72 73 ; " and all members" &728e 20 6f 66 20 74 68 65 20 56 49 41 20 68 61 74 65 ; " of the VIA hate" &729e 20 73 6f 63 69 65 74 79 ; " society" ; unused &72a6 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 &72b6 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 &72c6 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 &72d6 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 &72e6 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 &72f6 40 40 40 40 40 40 40 40 40 40 ; first_stage_via_decryption &7300 ad 00 73 LDA &7300 ; first_stage_via_decryption # Ensure &7300 - &73ff hasn't been changed # actually LDA &7300 + first_stage_via_decryption_offset &7303 ee 1f 73 INC &731f ; first_stage_via_decryption_eor &7306 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7309 38 SEC &730a 2e 68 fe ROL &fe68 ; User VIA timer 2 counter LSB &730d a8 TAY &730e ad 1f 73 LDA &731f ; first_stage_via_decryption_eor &7311 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7314 8d 1a 73 STA &731a ; first_stage_via_decryption_add &7317 98 TYA &7318 18 CLC &7319 69 f6 ADC #&f6 # actually ADC first_stage_via_decryption_add &731b ce 69 fe DEC &fe69 ; User VIA timer 2 counter MSB &731e 49 38 EOR #&38 # actually EOR first_stage_via_decryption_eor &7320 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7323 5d 00 ff EOR &ff00,X # Ensure OS ROM from &ff00 to &ffff hasn't been changed &7326 ee 1f 73 INC &731f ; first_stage_via_decryption_eor &7329 5d 00 70 EOR &7000,X ; second_stage_via_decryption # Ensure &7000 - &70ff hasn't been changed &732c ce 64 fe DEC &fe64 ; User VIA timer 1 counter LSB &732f 5d 40 d9 EOR &d940,X ; os_default_vector_table # Ensure OS default vector table hasn't been changed &7332 ce 69 fe DEC &fe69 ; User VIA timer 2 counter MSB &7335 5d 00 73 EOR &7300,X ; first_stage_via_decryption # Ensure &7300 - &73ff hasn't been changed &7338 5d 00 74 EOR &7400,X ; first_stage_payload # Ensure &7400 - &74ff hasn't been changed &733b 4d 64 fe EOR &fe64 ; User VIA timer 1 counter LSB &733e 38 SEC &733f 6d 01 73 ADC &7301 ; first_stage_via_decryption_offset &7342 ac 68 fe LDY &fe68 ; User VIA timer 2 counter LSB &7345 8c 69 fe STY &fe69 ; User VIA timer 2 counter MSB &7348 4d 65 fe EOR &fe65 ; User VIA timer 1 latch MSB &734b 5d cd d9 EOR &d9cd,X ; os_reset_handler # Ensure OS reset handler hasn't been changed &734e 4d 66 fe EOR &fe66 ; User VIA timer 1 latch LSB &7351 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7354 18 CLC &7355 7d 01 74 ADC &7401,X ; first_stage_payload + 1 &7358 ee 1a 73 INC &731a ; first_stage_via_decryption_add &735b a8 TAY &735c ad 1a 73 LDA &731a ; first_stage_via_decryption_add &735f 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &7362 8d 1a 73 STA &731a ; first_stage_via_decryption_add &7365 98 TYA &7366 4d 69 fe EOR &fe69 ; User VIA timer 2 counter MSB &7369 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &736c 9d 00 74 STA &7400,X ; first_stage_payload &736f e8 INX &7370 d0 8e BNE &7300 ; first_stage_via_decryption &7372 a9 03 LDA #&03 # Enable ESCAPE, clear memory on BREAK &7374 8d 58 02 STA &0258 ; ESCAPE/BREAK effect &7377 a9 40 LDA #&40 ; RTI &7379 8d 00 0d STA &0d00 ; NMI entry point &737c a9 4c LDA #&4c ; JMP # Set BREAK intercept code to JMP &0287, endless loop &737e 8d 87 02 STA &0287 ; BREAK intercept code &7381 a9 87 LDA #&87 &7383 8d 88 02 STA &0288 ; BREAK intercept code + 1 &7386 a9 02 LDA #&02 &7388 8d 89 02 STA &0289 ; BREAK intercept code + 2 &738b a0 35 LDY #&35 # Reset all vectors to OS defaults ; reset_vector_table_loop &738d b9 40 d9 LDA &d940,Y ; os_default_vector_table &7390 99 00 02 STA &0200,Y ; os_vector_table &7393 88 DEY &7394 10 f7 BPL &738d ; reset_vector_table_loop &7396 ad 1f 73 LDA &731f ; first_stage_via_decryption_eor &7399 4d 68 fe EOR &fe68 ; User VIA timer 2 counter LSB &739c 8d 1f 73 STA &731f ; first_stage_via_decryption_eor &739f ee 1f 73 INC &731f ; first_stage_via_decryption_eor &73a2 ee 01 73 INC &7301 ; first_stage_via_decryption_offset &73a5 f0 03 BEQ &73aa ; calculate_checksum_after_first_stage &73a7 4c 00 73 JMP &7300 ; first_stage_via_decryption ; calculate_checksum_after_first_stage &73aa a9 00 LDA #&00 # Checksum &7400 - &741f &73ac 85 70 STA &70 ; checksum_one &73ae 85 71 STA &71 ; checksum_two &73b0 a8 TAY ; calculate_checksum_loop &73b1 a5 71 LDA &71 ; checksum_two &73b3 59 00 74 EOR &7400,Y ; first_stage_payload &73b6 85 71 STA &71 ; checksum_two &73b8 a2 08 LDX #&08 ; calculate_checksum_inner_loop &73ba a5 71 LDA &71 ; checksum_two &73bc 2a ROL A &73bd 90 0c BCC &73cb ; clear_unset &73bf a5 71 LDA &71 ; checksum_two &73c1 49 08 EOR #&08 &73c3 85 71 STA &71 ; checksum_two &73c5 a5 70 LDA &70 ; checksum_one &73c7 49 10 EOR #&10 &73c9 85 70 STA &70 ; checksum_one ; clear_unset &73cb 26 70 ROL &70 ; checksum_one &73cd 26 71 ROL &71 ; checksum_two &73cf ca DEX &73d0 d0 e8 BNE &73ba ; calculate_checksum_inner_loop &73d2 c8 INY &73d3 c0 20 CPY #&20 &73d5 d0 da BNE &73b1 ; calculate_checksum_loop &73d7 a5 70 LDA &70 ; checksum_one &73d9 cd fe 74 CMP &74fe ; first_stage_valid_checksum_one &73dc d0 07 BNE &73e5 ; invalid_checksum &73de a5 71 LDA &71 ; checksum_two &73e0 cd ff 74 CMP &74ff ; first_stage_valid_checksum_two &73e3 f0 1b BEQ &7400 ; first_stage_payload ; invalid_checksum &73e5 a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect # This is handled by the OS OSBYTE handler at &e99c, &73e7 a2 03 LDX #&03 ; Clear memory on next RESET # which isn't checked in the decryption routine, &73e9 a0 00 LDY #&00 # so could be intercepted with a custom ROM &73eb 20 f4 ff JSR &fff4 ; OSBYTE ; wipe_first_stage_payload_loop &73ee 99 00 74 STA &7400,Y ; first_stage_payload &73f1 c8 INY &73f2 4c ee 73 JMP &73ee ; wipe_first_stage_payload_loop ; unused &73f5 4b 65 76 69 6e 20 20 20 20 20 20 ; "Kevin " # &7400 - &74ff decrypted by first_stage_via_decryption ; first_stage_payload &7400 ad b2 03 LDA &03b2 ; block_header_filename # Fail if not loading NIGHTSHADE &7403 c9 4e CMP #&4e ; "N" &7405 d0 e7 BNE &73ee ; wipe_first_stage_payload_loop &7407 a9 6f LDA #&6f # Push to &6f, &ff, &b2 and &44 to stack, &7409 48 PHA # initial timer values for second stage (&b2 and &44), &740a a9 ff LDA #&ff # and return address of &7000 used at &7474 &740c 48 PHA &740d a9 b2 LDA #&b2 &740f 48 PHA &7410 a9 44 LDA #&44 &7412 48 PHA &7413 4c 2c 74 JMP &742c ; check_roms_for_replay ; unused &7416 28 63 29 20 4b 65 76 69 6e 20 45 64 77 61 72 64 ; "(c) Kevin Edward" &7426 73 20 31 39 38 35 ; "s 1985" ; check_roms_for_replay &742c a2 00 LDA #&00 &742e 8a TXA ; wipe_7400_to_742e_loop &742f 9d 00 74 STA &7400,X ; first_stage_payload # Wipe &7400 - &742e with &00 &7432 e8 INX &7433 e0 2f CPX #&2f &7435 d0 f8 BNE &742f ; wipe_7400_to_742e_loop &7437 a2 0f LDX #&0f ; check_roms_for_replay_loop &7439 8e 30 fe STX &fe30 ; paged ROM latch # Check each ROM in turn &743c a0 05 LDY #&05 ; check_rom_loop &743e b9 09 80 LDA &8009,Y ; rom_title_string &7441 d9 51 74 CMP &7451,Y ; replay_string # Does the ROM title string start with "Replay"? &7444 d0 06 BNE &744c ; check_next_rom &7446 88 DEY &7447 10 f5 BPL &743e ; check_rom_loop &7449 4c ee 73 JMP &73ee ; wipe_first_stage_payload_loop # If so, fail &744c ca DEX ; check_next_rom &744d 10 ea BPL &7439 ; check_roms_for_replay_loop &744f 30 06 BMI &7457 ; initialise_second_stage # Always branches ; replay_string &7451 52 65 70 6c 61 79 ; "Replay" ; initialise_second_stage &7457 a9 fc LDA #&fc &7459 8d 64 fe STA &fe64 ; User VIA timer 1 counter LSB &745c a9 34 LDA #&34 &745e 8d 65 fe STA &fe65 ; User VIA timer 1 latch MSB &7461 68 PLA ; &b2 # Pushed at &7410 &7462 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &7465 68 PLA ; &44 # Pushed at &740d &7466 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &7469 a2 69 LDX #&69 &746b 8a TXA ; wipe_7401_to_7469_loop &746c 9d 00 74 STA &7400,X ; first_stage_payload # Wipe &7401 - &7469 with &69 &746f ca DEX &7470 d0 fa BNE &746c ; wipe_7401_to_7469_loop &7472 a0 00 LDY #&00 &7474 60 RTS # Returns to &7000, second_stage_via_decryption ; unused # Possibly intended to imply wiped code? &7475 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a &7485 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a &7495 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a &74a5 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a &74b5 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a &74c5 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a &74d5 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ; unused # Unused code; distraction from real values at &7457 ? &74e5 a9 ff LDA #&ff &74e7 8d 64 fe STA &fe64 ; User VIA timer 1 counter LSB &74ea 8d 65 fe STA &fe65 ; User VIA timer 1 latch MSB &74ed a9 67 LDA #&67 &74ef 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &74f2 a9 dd LDA #&dd &74f4 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &74f7 a9 1f LDA #&1f &74f9 a2 ff LDX #&ff &74fb a0 01 LDY #&01 &74fd 60 RTS ; first_stage_valid_checksum_one &74fe 18 ; first_stage_valid_checksum_two &74ff b0