Sabre Wulf disassembly ====================== Published by Ultimate Play the Game in 1984, Sabre Wulf was originally written by Chris and Tim Stamper for the ZX Spectrum, and was converted to the BBC Micro by Paul Proctor. The player must navigate a jungle maze, collecting pieces of an amulet while defeating or avoiding creatures. 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 tape loader is protected by a decryption routine written by Kevin Edwards. The loading screen and main game binary are stored encrypted on tape. The decryption code for each file is hidden in the block load addresses, one byte per block. The disassembly analyses each stage immediately after decryption has taken place. The game has three separate sprite plotting routines. Two use run-length encoding to compress multi-coloured data; a third converts one-bit-per-pixel single-coloured data. The first and third of these have the capability to flip sprites horizontally. The second has stubs that suggests it was also once able to, and is swapped in and out of zero page in a manner indicative of being developed separately. The haphazard layout of memory and leftover fragments also suggest that the game was developed piecemeal. Some of the unused bytes are consistent with there once being routines that were subsequently removed. The BRK opcode is used to novel effect, acting as a one byte random number instruction. This is achieved by hooking the BRKV vector, ignoring the usual RTI return in favour of a JMP on exit. The EVNTV vector is also hooked to provide a delay timer with 50ms granularity. There is use of self-modifying code, plus unofficial OS character data at &c000 and key handling at &ec. Interesting Pokes ================= &3b76 = &e6, &3b77 = &c0 infinite lives &454a = &18, &45ac = &18, &476a = &18, &2fd4 = &60 player can walk through scenery &4415 = &00 player always moves at top speed &3b2a = &92 creatures are killed by touching player, not the reverse &32e4 = &ff remove guardian from cave room Notes ===== Creature slots: 0 - 2 small creatures 3 FIRE 4 - 7 RHINOs 8 GUARDIAN 9 WOLF a - b HIPPOs Player sprites: 0 - 3 WALKING LEFT 4 SITTING LEFT 5 FLYING LEFT 6 DEAD LEFT 7 - c FIGHTING LEFT d -10 WALKING RIGHT 11 SITTING RIGHT 12 FLYING RIGHT 13 DEAD RIGHT 14-19 FIGHTING RIGHT 1a-1d WALKING UP 1e-21 WALKING DOWN Object sprites: 0 CRATE 1 SWORD 2 FRUIT 3 RING 4 CAP 5 BAG 6 SHIELD 7 LIFE 8 AMULET_TOP_LEFT 9 AMULET_TOP_RIGHT a AMULET_BOTTOM_LEFT b AMULET_BOTTOM_RIGHT Creature sprites: 0 - 4 APPEARING 5 - a DISAPPEARING b - c SPIDER d - e LIZARD f -10 BIRD 11-12 TRIBESMAN 13-14 MOUSE 15-16 MOSQUITO 17-18 SNAKE 19-1a FLEA 1b-1e RHINO 1f-22 WOLF 23-26 HIPPO 27 SLEEPING_HIPPO 28 GUARDIAN 29-2b FIRE Orchid colours: 0 WHITE 1 RED 2 MAGENTA 3 CYAN 4 YELLOW Small creature species: 0 SPIDER 1 LIZARD 2 BIRD 3 TRIBESMAN 4 MOUSE 5 MOSQUITO 6 SNAKE 7 FLEA Tape protection disassembly =========================== ; SABRE.WULF ; 000d00 000d00 000300 # &0d00 - &0d45 is unencrypted ; first_stage_decryption &0d00 a2 ee LDX #&ee # actually LDX first_stage_decryption_x &0d02 ac 0b 0d LDY &0d0b ; first_stage_decryption_offset &0d05 a9 ed LDA #&ed # actually LDA first_stage_decryption_a ; first_stage_decryption_loop &0d07 bd 00 0d LDA &0d00,X ; first_stage_decryption # Ensure decryption code is unmodified &0d0a 4d 08 0d EOR &0d08 # actually EOR &0d00 + first_stage_decryption_offset &0d0d 5d 46 0d EOR &0d46,X ; first_stage_payload &0d10 38 SEC &0d11 69 4d ADC #&4d &0d13 9d 46 0d STA &0d46,X ; first_stage_payload &0d16 e8 INX &0d17 ce 06 0d DEC &0d06 ; first_stage_decryption_a &0d1a ec 08 0d CPX &0d08 ; always #&00, offset to start of decoder &0d1d d0 e8 BNE &0d07 ; first_stage_decryption_loop &0d1f ee 01 0d INC &0d01 ; first_stage_decryption_x &0d22 98 TYA &0d23 18 CLC &0d24 6d 0b 0d ADC &0d0b ; first_stage_decryption_offset &0d27 ed 0e 0d SBC &0d0e ; always #&46, offset to start of payload ; infinite_loop_if_osbyte_vector_in_ram &0d2a 2c 0b 02 BIT &020b ; osbyte_vector_high &0d2d 10 fb BPL &0d2a ; infinite_loop_if_osbyte_vector_in_ram # Infinite loop if OSBYTE vector is in RAM, not ROM &0d2f a8 TAY &0d30 d0 03 BNE &0d35 ; skip_offset &0d32 ce 0b 0d DEC &0d0b ; first_stage_decryption_offset ; skip_offset &0d35 cc 01 0d CPY &0d01 ; first_stage_decryption_x &0d38 d0 c6 BNE &0d00 ; first_stage_decryption &0d3a ad 0b 02 LDA &020b ; osbyte_vector_high &0d3d 10 c8 BPL &0d07 ; first_stage_decryption_loop &0d3f a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect &0d41 a2 03 LDX #&03 ; Clear memory on next RESET &0d43 20 f4 ff JSR &fff4 ; OSBYTE # Could be intercepted with a custom ROM # &0d46 - &0e45 decrypted by first_stage_decryption ; first_stage_payload &0d46 a9 03 LDA #&03 # Enable ESCAPE, clear memory on BREAK &0d48 8d 58 02 STA &0258 ; ESCAPE/BREAK effect &0d4b a9 4c LDA #&4c ; JMP # Set BREAK intercept code to JMP &0287, endless loop &0d4d 8d 87 02 STA &0287 ; BREAK intercept code &0d50 a9 87 LDA #&87 &0d52 8d 88 02 STA &0288 ; BREAK intercept code + 1 &0d55 a9 02 LDA #&02 &0d57 8d 89 02 STA &0289 ; BREAK intercept code + 2 &0d5a ad fc ff LDA &fffc ; os_reset_address_low &0d5d c9 cd CMP #&cd &0d5f f0 0a BEQ &0d6b ; reset_address_unchanged &0d61 a2 00 LDX #&00 ; wipe_0d46_to_0d62_loop &0d63 9d 46 0d STA &0d46,X ; first_stage_payload # Breaks when X = &1d, setting &0d63 = &00 BRK &0d66 e8 INX &0d67 d0 fa BNE &0d63 ; wipe_0d46_to_0d62_loop &0d69 f0 f8 BEQ &0d63 ; wipe_0d46_to_0d62_loop # Would always branch; intended as endless loop? ; reset_address_unchanged &0d6b 78 SEI &0d6c a0 35 LDY #&35 # Reset all vectors to OS defaults ; reset_vector_table_loop &0d6e b9 40 d9 LDA &d940,Y ; os_default_vector_table &0d71 99 00 02 STA &0200,Y ; os_vector_table &0d74 88 DEY &0d75 10 f7 BPL &0d6e ; reset_vector_table_loop &0d77 58 CLI &0d78 a0 0f LDY #&0f &0d7a a9 00 LDA #&00 ; remove_roms_loop &0d7c 99 a1 02 STA &02a1,Y ; os_paged_rom_type_table # Remove paged ROMs from ROM information table &0d7f 88 DEY &0d80 10 fa BPL &0d7c ; remove_roms_loop &0d82 a9 8c LDA #&8c ; Select Tape FS &0d84 a2 0c LDX #&0c ; 1200 baud &0d86 a0 00 LDY #&00 &0d88 20 f4 ff JSR &fff4 ; OSBYTE &0d8b a0 40 LDY #&40 ; wipe_0d47_to_0d86_loop &0d8d 99 46 0d STA &0d46,Y ; first_stage_payload &0d90 88 DEY &0d91 10 fa BPL &0d8d ; wipe_0d47_to_0d86_loop &0d93 78 SEI &0d94 a9 cd LDA #&cd &0d96 8d 00 02 STA &0200 ; user_vector_low &0d99 8d 02 02 STA &0202 ; brk_vector_low &0d9c 8d 06 02 STA &0206 ; irq2_vector_low &0d9f 8d 20 02 STA &0220 ; event_vector_low &0da2 8d 24 02 STA &0224 ; net_vector_low &0da5 a9 d9 LDA #&d9 ; &d9cd = os_reset_handler # Reset system if various interrupts or events occur &0da7 8d 01 02 STA &0201 ; user_vector_high &0daa 8d 03 02 STA &0203 ; brk_vector_high &0dad 8d 07 02 STA &0207 ; irq2_vector_high &0db0 8d 21 02 STA &0221 ; event_vector_high &0db3 8d 25 02 STA &0225 ; net_vector_high &0db6 58 CLI &0db7 a2 21 LDX #&21 ; relocate_irq1_handler_loop &0db9 bd c3 0d LDA &0dc3,X ; unrelocated_irq1_handler # Copy &0dc3 - &0de4 to &0000 - &0021 &0dbc 95 00 STA &00,X ; irq1_handler &0dbe ca DEX &0dbf 10 f8 BPL &0db9 ; relocate_irq1_handler_loop &0dc1 30 33 BMI &0df6 ; prepare_for_second_stage # Always branches # &0dc3 - &0de4 is copied to &0000 - &0021 at &0dbc ; irq1_handler &0000 78 SEI &0001 08 PHP &0002 48 PHA &0003 8a TXA &0004 48 PHA &0005 ad ca 03 LDA &03ca ; tape_block_flag &0008 29 fe AND #&fe # Clear locked flag for title page, but not main binary # actually AND block_flags &000a 8d ca 03 STA &03ca ; tape_block_flag &000d ae c6 03 LDX &03c6 ; tape_block_number &0010 e4 8f CPX &8f ; last_block_read &0012 f0 07 BEQ &0dde ; same_block &0014 86 8f STX &8f ; last_block_read &0016 ad bf 03 LDA &03bf ; tape_load_address + 1 # A single byte of decryption code is stored in the &0019 95 22 STA &22,X ; file_decryption_code # second byte of the load address of each block ; same_block &001b 68 PLA &001c aa TAX &001d 68 PLA &001e 28 PLP &001f 4c 93 dc JMP &dc93 ; os_irq1_handler ; unused &0de5 46 72 61 6b 20 6f 66 66 20 70 69 72 61 74 65 20 ; "Frak off pirate " &0df5 21 ; "!" ; prepare_for_second_stage &0df6 78 SEI &0df7 a9 00 LDA #&00 ; &0000 = irq1_handler &0df9 8d 04 02 STA &0204 ; irq1_vector_low &0dfc 8d 05 02 STA &0205 ; irq1_vector_high &0dff 58 CLI ; second_stage_decryption # Identical to first_stage_decryption &0e00 a2 ee LDX #&ee # actually LDX second_stage_decryption_x &0e02 ac 0b 0e LDY &0e0b ; second_stage_decryption_offset &0e05 a9 ed LDA #&ed # actually LDA second_stage_decryption_a ; second_stage_decryption_loop &0e07 bd 00 0e LDA &0e00,X ; second_stage_decryption # Ensure decryption code is unmodified &0e0a 4d 08 0e EOR &0e08 # actually EOR &0e00 + second_stage_decryption_offset &0e0d 5d 46 0e EOR &0e46,X ; second_stage_payload &0e10 38 SEC &0e11 69 4d ADC #&4d &0e13 9d 46 0e STA &0e46,X ; second_stage_payload &0e16 e8 INX &0e17 ce 06 0e DEC &0e06 ; second_stage_decryption_a &0e1a ec 08 0e CPX &0e08 ; always #&00, offset to start of decoder &0e1d d0 e8 BNE &0e07 ; second_stage_decryption_loop &0e1f ee 01 0e INC &0e01 ; second_stage_decryption_x &0e22 98 TYA &0e23 18 CLC &0e24 6d 0b 0e ADC &0e0b ; second_stage_decryption_offset &0e27 ed 0e 0e SBC &0e0e ; always #&46, offset to start of payload ; infinite_loop_if_osbyte_vector_in_ram &0e2a 2c 0b 02 BIT &020b ; osbyte_vector_high &0e2d 10 fb BPL &0e2a ; infinite_loop_if_osbyte_vector_in_ram # Infinite loop if OSBYTE vector is in RAM, not ROM &0e2f a8 TAY &0e30 d0 03 BNE &0e35 ; skip_offset &0e32 ce 0b 0e DEC &0e0b ; second_stage_decryption_offset ; skip_offset &0e35 cc 01 0e CPY &0e01 ; second_stage_decryption_x &0e38 d0 c6 BNE &0e00 ; second_stage_decryption &0e3a ad 0b 02 LDA &020b ; osbyte_vector_high &0e3d 10 c8 BPL &0e07 ; second_stage_decryption_loop &0e3f a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect &0e41 a2 03 LDX #&03 ; Clear memory on next RESET &0e43 20 f4 ff JSR &fff4 ; OSBYTE # Could be intercepted with a custom ROM # &0e46 - &0f45 decrypted by second_stage_decryption ; second_stage_payload &0e46 a9 86 LDA #&86 ; RIGHT &0e48 85 8a STA &8a ; key_right # Used in main binary &0e4a a9 e6 LDA #&e6 ; LEFT &0e4c 85 8b STA &8b ; key_left &0e4e a9 9e LDA #&9e ; Z &0e50 85 8c STA &8c ; key_down &0e52 a9 be LDA #&be ; A &0e54 85 8d STA &8d ; key_up &0e56 a2 28 LDX #&28 ; write_sabre_wulf_is_loading_loop &0e58 bd f7 0e LDA &0ef7,X ; sabre_wulf_is_loading_text &0e5b 20 ee ff JSR &ffee ; OSWRCH # Write "SABRE WULF is loading" &0e5e ca DEX &0e5f 10 f7 BPL &0e58 ; write_sabre_wulf_is_loading_loop &0e61 a2 06 LDX #&06 # R6: Vertical displayed register &0e63 8e 00 fe STX &fe00 ; video register number &0e66 a9 15 LDA #&15 # 168 pixels high &0e68 8d 01 fe STA &fe01 ; video register value &0e6b e8 INX ; 7 # R7: Vertical sync position &0e6c 8e 00 fe STX &fe00 ; video register number &0e6f a9 1d LDA #&1d &0e71 8d 01 fe STA &fe01 ; video register value &0e74 a2 0c LDX #&0c # R12: Displayed screen start address register (high) &0e76 8e 00 fe STX &fe00 ; video register number &0e79 a9 09 LDA #&09 &0e7b 8d 01 fe STA &fe01 ; video register value &0e7e e8 INX ; &d # R13: Displayed screen start address register (low) &0e7f 8e 00 fe STX &fe00 ; video register number &0e82 a9 70 LDA #&70 # Set screen start address to &4b80 &0e84 8d 01 fe STA &fe01 ; video register value &0e87 a2 0a LDX #&0a # R10: Cursor start register &0e89 8e 00 fe STX &fe00 ; video register number &0e8c a9 20 LDA #&20 # Disable cursor &0e8e 8d 01 fe STA &fe01 ; video register value &0e91 a9 8c LDA #&8c ; Select Tape FS &0e93 a2 0c LDX #&0c ; 1200 baud &0e95 a0 00 LDY #&00 &0e97 8e c6 03 STX &03c6 ; tape_block_number &0e9a 20 f4 ff JSR &fff4 ; OSBYTE &0e9d a0 0f LDY #&0f &0e9f a2 20 LDX #&20 ; &0f20 = load_command &0ea1 20 f7 ff JSR &fff7 ; OSCLI # Load TITLE.PAGE &0ea4 a2 06 LDX #&06 ; write_clear_screen_loop &0ea6 bd 3f 0f LDA &0f3f,X ; clear_screen_text &0ea9 20 ee ff JSR &ffee ; OSWRCH &0eac ca DEX &0ead 10 f7 BPL &0ea6 ; write_clear_screen_loop &0eaf a2 01 LDX #&01 # R1: Number of characters per line &0eb1 8e 00 fe STX &fe00 ; video register number &0eb4 ca DEX ; 0 # Hide screen &0eb5 8e 01 fe STX &fe01 ; video register value &0eb8 a2 0c LDX #&0c # R12: Displayed screen start address register (high) &0eba 8e 00 fe STX &fe00 ; video register number &0ebd a9 09 LDA #&09 &0ebf 8d 01 fe STA &fe01 ; video register value &0ec2 e8 INX ; &d # R13: Displayed screen start address register (low) &0ec3 8e 00 fe STX &fe00 ; video register number &0ec6 a9 70 LDA #&70 # Set screen address to &4b80 &0ec8 8d 01 fe STA &fe01 ; video register value &0ecb a9 ee LDA #&ee # Add last two bytes to decrypt_title_page &0ecd 85 33 STA &33 ; file_decryption_code + &11 &0ecf a9 60 LDA #&60 ; RTS &0ed1 85 34 STA &34 ; file_decryption_code + &12 &0ed3 a0 00 LDY #&00 &0ed5 20 22 00 JSR &0022 ; decrypt_title_page &0ed8 20 05 1f JSR &1f05 ; title_page_entry_point # Plot the loading screen &0edb a2 01 LDX #&01 # R1: Number of characters per line &0edd 8e 00 fe STX &fe00 ; video register number &0ee0 a9 50 LDA #&50 # Restore screen &0ee2 8d 01 fe STA &fe01 ; video register value &0ee5 a2 ff LDX #&ff &0ee7 86 09 STX &09; block_flags # Keep locked flag for main binary &0ee9 a2 0c LDX #&0c ; 1200 baud &0eeb a9 8c LDA #&8c ; Select Tape FS &0eed 20 f4 ff JSR &fff4 ; OSBYTE &0ef0 a0 0f LDY #&0f &0ef2 a2 32 LDX #&32 ; &0f32 = run_command &0ef4 4c f7 ff JMP &fff7 ; OSCLI # Run , entry point &0023 ; sabre_wulf_is_loading_text # Stored backwards &0ef7 18 10 19 03 1c 67 6e 69 64 61 6f 6c 20 73 69 80 ; MODE 2; &0f07 11 07 11 11 05 1f 46 4c 55 57 20 45 52 42 41 53 ; TAB(&05, &0f); COLOUR 8; COLOUR &8f; "SABRE WULF"; &0f17 8f 11 08 11 0f 05 1f 02 16 ; TAB(&05, &11); COLOUR 7; COLOUR &80; "is loading"; ; define text window x:(&03, &10), y:(&18, &19) ; load_command &0f20 4c 2e 54 49 54 4c 45 2e 50 41 47 45 20 31 46 30 ; "L.TITLE.PAGE 1F00" &0f30 30 0d ; run_command &0f32 52 2e 3c 54 48 45 2e 47 41 4d 45 3e 0d ; "R." ; clear_screen_text # Stored backwards &0f3f 18 10 19 04 1c 0c 1a ; Default window; CLS; define text window x:(&04, &10), y:(&18, &19) # &0f46 - &0fff is unencrypted ; unused &0f46 00 00 ; unused &0f48 54 61 70 65 20 50 72 6f ; "Tape Pro" ; "Tape Protection By Kevin Edwards" &0f50 74 65 63 74 69 6f 6e 00 ; "tection." ; "Program written by Paul Proctor" &0f58 62 79 20 4b 65 76 69 6e ; "by Kevin" ; "Title Page by Chris Thompson" &0f60 45 64 77 61 72 64 73 00 ; "Edwards." ; "Sounds by Martin Galway" &0f68 20 20 20 20 20 20 20 20 ; " " ; "FLICKER-FREE FRAK! COKE" &0f70 00 00 00 00 00 00 00 00 ; "........" &0f78 50 72 6f 67 72 61 6d 00 ; "Program." &0f80 77 72 69 74 74 65 6e 00 ; "written." &0f88 62 79 20 50 61 75 6c 00 ; "by Paul." &0f90 50 72 6f 63 74 6f 72 00 ; "Proctor." &0f98 20 20 20 20 20 20 20 20 ; " " &0fa0 54 69 74 6c 65 00 50 61 ; "Title.Pa" &0fa8 67 65 20 62 79 20 43 68 ; "ge by Ch" &0fb0 72 69 73 20 54 68 6f 6d ; "ris Thom" &0fb8 70 73 6f 6e 00 00 00 00 ; "pson...." &0fc0 20 20 20 20 20 20 20 20 ; " " &0fc8 53 6f 75 6e 64 73 20 62 ; "Sounds b" &0fd0 79 20 4d 61 72 74 69 6e ; "y Martin" &0fd8 20 47 61 6c 77 61 79 00 ; " Galway." &0fe0 20 20 20 20 20 20 20 20 ; " " &0fe8 46 4c 49 43 4b 45 52 2d ; "FLICKER-" &0ff0 46 52 45 45 20 46 52 41 ; "FREE FRA" &0ff8 4b 21 20 43 4f 4b 45 00 ; "K! COKE." Decryption code for title page: ; decrypt_title_page &0022 a9 32 LDA #&32 &0024 59 00 1f EOR &1f00,Y # Decrypt &1f00 - &2eff # actually EOR address,Y &0027 91 25 STA (&25),Y ; address &0029 c8 INY &002a d0 f6 BNE &0022 ; decrypt_title_page &002c e6 26 INC &26 ; address_high &002e a5 26 LDA &26 ; address_high &0030 c9 2f CMP #&2f &0032 d0 ee BNE &0022 ; decrypt_title_page # &0033 set at &0ecd &0034 60 RTS # &0034 set at &0ed1 Decryption code for main binary: ; unused &0022 04 # Actual load address of main binary is &0400 ; decrypt_main_binary &0023 a9 0a LDA #&0a ; Set duration of second flash colour &0025 a2 00 LDX #&00 ; hold still &0027 20 f4 ff JSR &fff4 ; OSBYTE &002a a0 00 LDY #&00 ; decrypt_main_binary_loop &002c a5 4f LDA &4f ; prnd_1 &002e 29 48 AND #&48 &0030 69 38 ADC #&38 &0032 0a ASL A &0033 0a ASL A &0034 26 50 ROL &50 ; prnd_2 &0036 26 51 ROL &51 ; prnd_3 &0038 26 4f ROL &4f ; prnd_1 &003a a5 4f LDA &4f ; prnd_1 &003c 59 00 04 EOR &0400,Y # Decrypt &0400 - &4bff using pseudo-random stream # actually EOR address,Y &003f 91 3d STA (&3d),Y ; address &0041 c8 INY &0042 d0 e8 BNE &002c ; decrypt_main_binary_loop &0044 e6 3e INC &3e ; address_high &0046 a5 3e LDA &3e ; address_high &0048 c9 4c CMP #&4c &004a d0 e0 BNE &002c ; decrypt_main_binary_loop &004c 4c ca 4a JMP &4aca ; decrypted_entry_point ; prnd_1 &004f 16 ; prnd_2 &0050 02 ; prnd_3 &0051 42 ; unused &0052 42 42 43 42 42 43 42 42 43 42 42 43 42 42 43 42 &0062 42 43 42 42 43 42 42 43 Loading screen disassembly ========================== ; TITLE.PAGE ; 001f00 001f03 001038 # Load address varies per block # &1f00 - &2eff is decrypted by decrypt_title_page ; finished_sprite &1f00 c6 70 DEC &70 ; sprites_to_plot &1f02 d0 0d BNE &1f11 ; plot_next_sprite ; leave &1f04 60 RTS ; title_page_entry_point &1f05 a9 09 LDA #&09 &1f07 85 70 STA &70 ; sprites_to_plot &1f09 a0 00 LDY #&00 &1f0b 84 71 STY &71 ; sprite_address_low &1f0d a9 20 LDA #&20; &2000 = sprite_data &1f0f 85 72 STA &72 ; sprite_address_high ; plot_next_sprite &1f11 b1 71 LDA (&71),Y ; sprite_address # First byte of sprite header is screen address low &1f13 85 73 STA &73 ; column_start_address_low &1f15 85 75 STA &75 ; screen_address_low &1f17 c8 INY ; 1 &1f18 b1 71 LDA (&71),Y ; sprite_address # Second byte of sprite header is screen address low &1f1a 85 74 STA &74 ; column_start_address_high &1f1c 85 76 STA &76 ; screen_address_high &1f1e c8 INY ; 2 &1f1f b1 71 LDA (&71),Y ; sprite_address # Third byte of sprite header is sprite width &1f21 85 77 STA &77 ; sprite_width &1f23 c8 INY ; 3 &1f24 b1 71 LDA (&71),Y ; sprite_address # Fourth byte of sprite header is sprite height &1f26 85 78 STA &78 ; sprite_height &1f28 c8 INY ; 4 &1f29 b1 71 LDA (&71),Y ; sprite_address # Fifth byte of sprite header determines data format &1f2b 85 79 STA &79 ; number_of_bits_for_palette &1f2d c8 INY ; 5 &1f2e aa TAX &1f2f a9 ff LDA #&ff ; calculate_mask_loop &1f31 4a LSR A &1f32 e8 INX &1f33 e0 08 CPX #&08 &1f35 d0 fa BNE &1f31 ; calculate_mask_loop &1f37 85 7a STA &7a ; mask_for_run_length &1f39 b1 71 LDA (&71),Y ; sprite_address # Sixth byte of sprite header is palette size &1f3b 85 7b STA &7b ; palette_size &1f3d c8 INY &1f3e 18 CLC &1f3f a5 71 LDA &71 ; sprite_address_low &1f41 69 06 ADC #&06 # Palette starts after sprite header &1f43 85 7c STA &7c ; palette_address_low &1f45 a9 00 LDA #&00 &1f47 65 72 ADC &72 ; sprite_address_high &1f49 85 7d STA &7d ; palette_address_high &1f4b 18 CLC &1f4c a5 7c LDA &7c ; palette_address_low &1f4e 65 7b ADC &7b ; palette_size # Sprite data starts after palette &1f50 85 71 STA &71 ; sprite_address_low &1f52 a9 00 LDA #&00 &1f54 65 72 ADC &72 ; sprite_address_high &1f56 85 72 STA &72 ; sprite_address_high ; plot_sprite_loop &1f58 a5 77 LDA &77 ; sprite_width &1f5a f0 a4 BEQ &1f00 ; finished_sprite &1f5c a0 00 LDY #&00 &1f5e 84 7e STY &7e ; rows_plotted_in_column ; plot_column_loop &1f60 b1 71 LDA (&71),Y ; sprite_address # Get a byte of sprite data &1f62 85 7f STA &7f ; sprite_byte &1f64 25 7a AND &7a ; mask_for_run_length # Low bits set run length &1f66 aa TAX &1f67 e8 INX &1f68 18 CLC &1f69 8a TXA &1f6a 65 7e ADC &7e ; rows_plotted_in_column &1f6c 85 7e STA &7e ; rows_plotted_in_column &1f6e a5 79 LDA &79 ; number_of_bits_for_palette &1f70 85 7b STA &7b ; bits_to_shift ; extract_pixel_value_loop &1f72 46 7f LSR &7f ; sprite_byte # High bits determine entry from palette &1f74 c6 7b DEC &7b ; bits_to_shift &1f76 d0 fa BNE &1f72 ; extract_pixel_value_loop &1f78 a5 7f LDA &7f ; sprite_byte &1f7a a8 TAY &1f7b b1 7c LDA (&7c),Y ; palette_address &1f7d 85 7f STA &7f ; pixel_value &1f7f a0 00 LDY #&00 &1f81 18 CLC &1f82 a5 71 LDA &71 ; sprite_address_low &1f84 69 01 ADC #&01 &1f86 85 71 STA &71 ; sprite_address_low &1f88 a9 00 LDA #&00 &1f8a 65 72 ADC &72 ; sprite_address_high &1f8c 85 72 STA &72 ; sprite_address_high &1f8e b0 45 BCS &1fd5 ; leave # Never branches ; plot_run_loop # Plot a run of length X &1f90 a5 7f LDA &7f ; pixel_value &1f92 51 75 EOR (&75),Y ; screen_address &1f94 91 75 STA (&75),Y ; screen_address &1f96 a5 75 LDA &75 ; screen_address_low &1f98 29 07 AND #&07 &1f9a d0 0d BNE &1fa9 ; not_group &1f9c 38 SEC &1f9d a5 75 LDA &75 ; screen_address_low &1f9f e9 78 SBC #&78 &1fa1 85 75 STA &75 ; screen_address_low &1fa3 a5 76 LDA &76 ; screen_address_high &1fa5 e9 02 SBC #&02 &1fa7 85 76 STA &76 ; screen_address_high ; not_group &1fa9 38 SEC &1faa a5 75 LDA &75 ; screen_address_low &1fac e9 01 SBC #&01 # Move up one pixel &1fae 85 75 STA &75 ; screen_address_low &1fb0 a5 76 LDA &76 ; screen_address_high &1fb2 e9 00 SBC #&00 &1fb4 85 76 STA &76 ; screen_address_high &1fb6 ca DEX &1fb7 d0 d7 BNE &1f90 ; plot_run_loop &1fb9 a5 78 LDA &78 ; sprite_height &1fbb c5 7e CMP &7e ; rows_plotted_in_column &1fbd d0 a1 BNE &1f60 ; plot_column_loop &1fbf c6 77 DEC &77 ; sprite_width &1fc1 18 CLC &1fc2 a5 73 LDA &73 ; column_start_address_low &1fc4 69 08 ADC #&08 # Move right two pixels &1fc6 85 73 STA &73 ; column_start_address_low &1fc8 85 75 STA &75 ; screen_address_low &1fca a9 00 LDA #&00 &1fcc 65 74 ADC &74 ; column_start_address_high &1fce 85 74 STA &74 ; column_start_address_high &1fd0 85 76 STA &76 ; screen_address_high &1fd2 4c 58 1f JMP &1f58 ; plot_sprite_loop ; leave &1fd5 60 RTS ; unused # Part of a ten times multiplication table &1fd6 00 c8 # that would have started at &1fae &1fd8 00 d2 &1fda 00 dc &1fdc 00 e6 &1fde 00 f0 &1fe0 00 fa &1fe2 01 04 &1fe4 01 0e &1fe6 01 18 &1fe8 01 22 &1fea 01 36 &1fec 01 54 &1fee 01 5e &1ff0 01 68 &1ff2 01 72 &1ff4 01 7c &1ff6 01 86 &1ff8 01 90 &1ffa 01 9a &1ffc 01 a4 &1ffe 01 ae ; sprite_data ; header # SABRE WULF logo &2000 81 69 3e 62 04 0b # at &6981, width &3e, height &62, 4 bits, palette &0b ; palette &2006 00 11 22 32 33 41 54 82 a8 c3 fc ; data &2011 0f 0f 0c 1a 4d 13 0f 07 0f 0b 18 47 24 5a 22 4f &2021 12 0e 0f 01 14 4f 23 51 9f 92 51 21 4f 41 11 09 &2031 0d 11 4f 41 22 51 93 73 11 00 14 74 97 50 00 20 &2041 46 20 52 21 44 10 07 0c 4f 40 21 51 94 71 11 44 &2051 20 00 46 20 50 94 71 90 70 00 10 46 00 95 50 21 &2061 43 06 0b 4e 21 50 94 71 11 47 00 90 00 44 20 50 &2071 94 70 10 41 11 47 00 99 50 20 42 05 0b 4c 20 50 &2081 94 70 11 4b 00 90 00 43 20 50 94 70 10 4c 00 9b &2091 00 42 04 0a 10 49 21 50 93 70 11 4d 00 91 00 43 &20a1 00 94 70 10 4c 00 9d 50 20 41 03 0a 48 20 50 93 &20b1 70 11 4f 40 00 91 00 43 00 94 00 4c 20 50 93 00 &20c1 13 71 93 50 20 40 03 0a 46 20 50 93 70 10 4f 43 &20d1 00 91 00 43 00 94 00 4b 20 50 92 70 10 45 10 00 &20e1 93 50 20 40 02 08 11 45 00 94 00 4f 45 00 92 00 &20f1 42 00 94 00 4a 20 50 93 00 47 00 94 00 40 10 01 &2101 08 45 20 50 93 70 10 4f 47 00 91 00 42 00 95 00 &2111 48 20 50 93 00 48 00 94 00 41 01 08 44 20 50 92 &2121 70 10 48 20 4f 00 91 00 42 10 00 95 50 21 43 20 &2131 50 94 70 10 48 00 93 00 43 00 06 10 44 00 50 92 &2141 70 10 49 00 50 21 4c 10 70 91 00 43 00 97 53 96 &2151 00 41 00 20 44 00 94 00 43 10 05 10 44 00 93 00 &2161 4b 00 92 51 20 4a 00 92 00 43 10 70 9f 00 42 00 &2171 90 51 21 50 94 00 45 04 10 44 00 93 00 4c 00 95 &2181 51 21 47 00 92 00 40 00 20 41 00 70 9c 00 44 10 &2191 70 95 71 10 46 03 10 44 20 50 92 00 4d 00 99 52 &21a1 25 00 91 50 20 00 a0 61 20 00 10 71 96 71 10 46 &21b1 10 70 94 00 47 00 03 45 00 92 00 4e 00 9f 97 51 &21c1 80 a2 61 20 00 15 4b 11 70 92 50 20 44 20 00 03 &21d1 20 44 00 92 00 4e 00 95 50 00 10 71 9b 71 60 a7 &21e1 61 21 4f 40 15 43 01 04 20 43 00 92 00 4e 00 70 &21f1 96 50 21 13 73 13 40 00 a1 82 10 81 a4 62 21 4f &2201 43 03 05 20 42 00 92 00 4f 40 10 71 96 52 20 48 &2211 00 80 10 45 10 80 a7 60 21 44 20 48 20 04 06 42 &2221 00 92 00 4f 41 21 00 70 98 00 47 00 10 47 00 60 &2231 a9 60 21 61 a0 00 45 20 06 06 20 42 00 91 00 4e &2241 00 51 9d 00 46 10 46 20 60 a5 80 a9 00 43 20 09 &2251 07 42 00 92 00 4d 00 9d 72 10 4c 20 60 a4 80 10 &2261 40 00 a8 00 41 0c 08 42 00 91 00 4d 00 94 50 01 &2271 10 71 00 11 49 00 44 20 60 a4 00 43 00 a7 00 42 &2281 0b 08 43 10 70 90 00 4c 00 97 50 24 44 24 01 60 &2291 21 40 00 a4 00 44 20 00 a4 80 10 43 10 0a 07 45 &22a1 10 70 50 20 4b 00 9d 54 93 71 00 a2 60 00 a3 64 &22b1 20 60 a6 00 45 0a 06 48 10 01 4a 00 91 73 9c 71 &22c1 00 10 40 00 af a6 00 47 09 05 4a 02 49 12 43 11 &22d1 71 96 70 10 70 91 50 20 00 a8 85 a7 00 47 09 04 &22e1 48 21 01 10 4c 25 42 11 00 50 90 70 10 42 00 92 &22f1 00 a3 83 11 43 15 81 a0 00 40 21 43 20 09 03 10 &2301 46 20 00 11 4d 20 60 a5 62 20 00 91 00 10 44 00 &2311 70 90 00 80 52 92 54 29 00 52 00 43 0a 03 46 10 &2321 46 20 49 00 ab 60 00 40 20 60 00 44 10 70 96 71 &2331 9f 90 00 41 20 0b 02 4d 20 00 10 49 00 a3 83 a5 &2341 60 a1 00 45 00 94 70 10 40 00 96 72 11 00 93 00 &2351 41 0c 01 10 4c 00 a0 00 4a 00 a2 00 43 13 81 a2 &2361 00 45 00 93 70 10 41 10 70 95 50 20 42 00 93 00 &2371 40 20 0c 01 4c 00 a0 00 4b 00 a3 60 20 47 10 80 &2381 a0 00 45 00 93 00 43 10 70 95 00 21 50 93 00 41 &2391 0d 00 10 4b 00 a0 80 10 4c 10 80 a3 60 21 46 11 &23a1 45 10 70 93 50 21 41 00 96 50 94 70 10 42 10 0b &23b1 10 4b 20 60 a0 00 4c 00 61 a6 63 21 41 20 46 10 &23c1 70 95 51 94 70 96 70 10 44 10 0a 4c 00 a1 00 48 &23d1 00 20 41 00 a3 82 12 81 a2 61 00 47 10 70 9a 00 &23e1 40 10 73 11 47 10 09 00 4b 00 a1 00 49 01 40 00 &23f1 81 11 47 10 80 a2 00 49 10 72 94 70 10 4f 42 08 &2401 00 20 49 20 60 a1 00 49 10 70 51 20 4c 10 80 a0 &2411 00 40 2c 04 28 01 20 49 07 01 49 00 a2 00 4a 00 &2421 92 51 21 4a 10 00 41 10 80 af aa 61 20 47 06 02 &2431 48 00 a2 60 20 49 10 70 95 51 22 45 23 41 10 80 &2441 af aa 00 47 10 05 02 20 47 10 80 a2 60 20 49 00 &2451 9a 55 92 00 43 10 80 a0 83 a9 80 13 00 a3 00 48 &2461 05 03 20 47 00 a4 60 20 46 20 50 9f 93 00 44 11 &2471 43 10 80 a8 00 42 00 a3 00 49 04 04 20 47 00 a5 &2481 60 21 43 00 93 70 00 12 73 97 00 49 20 60 aa 60 &2491 21 60 a4 00 48 04 06 20 46 10 80 a6 61 20 00 94 &24a1 00 a0 61 21 42 11 71 93 00 47 20 60 a5 80 00 ad &24b1 00 47 20 04 08 21 45 10 80 a7 00 94 00 a4 00 45 &24c1 12 70 00 45 20 60 a5 80 10 40 00 81 ab 00 47 05 &24d1 0c 20 44 11 81 a2 00 94 00 a5 62 21 45 10 43 20 &24e1 60 a6 80 10 44 10 81 a8 00 46 06 0f 46 11 80 50 &24f1 93 00 aa 61 21 46 20 60 a4 81 00 25 43 10 82 a1 &2501 81 10 46 30 06 0f 01 20 45 00 93 70 11 80 ac 60 &2511 21 42 20 60 a3 80 50 98 52 22 41 11 49 07 0f 03 &2521 20 43 00 92 70 10 41 00 a4 00 82 a6 60 20 40 00 &2531 a3 00 9f 90 51 20 49 08 0f 05 42 10 70 91 00 42 &2541 00 a4 00 42 10 80 a6 60 80 a2 00 94 71 9d 00 47 &2551 09 0f 06 42 10 70 90 00 42 00 a4 00 44 00 a6 00 &2561 a2 00 92 70 10 41 00 94 70 10 70 95 50 21 00 42 &2571 20 09 0f 06 20 42 00 90 50 20 41 00 a2 81 10 44 &2581 00 a6 00 80 a1 00 90 70 10 44 00 93 00 41 00 96 &2591 70 10 41 20 0a 0f 07 43 10 70 00 41 00 80 11 46 &25a1 00 a5 80 10 40 00 80 a1 60 00 45 10 72 10 42 00 &25b1 95 70 10 42 0b 0f 07 20 44 01 20 49 20 60 a2 81 &25c1 10 42 00 50 80 a1 60 20 4c 00 94 70 10 43 0b 0f &25d1 08 45 10 00 20 46 20 00 81 12 45 00 91 50 80 a0 &25e1 60 20 4b 00 93 70 10 43 20 0b 0f 09 20 45 10 4f &25f1 44 00 92 50 81 00 4a 00 91 70 10 44 20 0c 0f 0c &2601 21 4f 48 11 70 90 00 40 11 49 00 70 10 43 21 0e &2611 0f 0f 00 21 4f 47 12 4a 11 40 21 0f 03 0f 0f 04 &2621 22 4f 4a 25 0f 08 0f 0f 0c 24 47 24 0f 0f 02 ; header # Ultimate Play The Game logo &2630 9f 7e 2d 2a 04 0a # at &7e9f, width &2d, height &2a, 4 bits, palette &0a ; palette &2636 00 04 08 0c 14 15 28 2a 3c 3f ; data &2640 02 51 9f 9f 51 02 00 50 91 70 0f 0f 70 91 50 00 &2655 92 02 37 02 10 23 30 21 40 89 02 92 92 05 31 00 &2660 31 01 30 10 33 00 46 85 02 92 92 05 20 32 20 01 &2670 34 20 0f 00 92 92 02 17 01 34 20 4d 02 92 92 02 &2680 31 25 01 20 34 41 00 63 86 02 92 92 02 31 09 23 &2690 60 00 6b 02 92 92 02 16 02 31 24 60 8b 02 92 92 &26a0 02 22 31 20 31 01 34 10 45 87 02 92 92 02 12 31 &26b0 10 31 01 33 0b 43 02 92 92 02 26 02 33 0b 83 02 &26c0 92 92 02 31 00 10 33 01 18 40 00 44 83 02 92 92 &26d0 02 31 00 31 04 31 20 03 42 89 02 92 92 02 20 36 &26e0 01 22 00 22 68 83 02 92 92 0f 0c 83 02 92 92 08 &26f0 11 0f 01 63 02 92 92 02 15 31 01 34 23 61 88 02 &2700 92 92 02 25 31 01 30 15 83 40 87 02 92 92 08 21 &2710 01 18 4a 02 92 92 02 37 01 32 10 04 41 88 02 92 &2720 92 05 31 04 26 60 80 60 40 88 02 92 92 02 37 03 &2730 12 30 21 00 84 62 05 92 92 02 17 01 21 32 10 60 &2740 80 40 82 41 08 92 92 02 31 20 31 20 31 06 21 60 &2750 80 60 86 42 02 92 92 02 31 03 31 01 37 60 40 89 &2760 02 92 92 02 21 03 21 01 34 11 44 87 02 92 92 0c &2770 16 00 4b 02 92 92 02 10 35 10 01 32 12 02 60 89 &2780 02 92 92 02 31 00 11 00 31 01 22 33 64 80 00 85 &2790 02 92 92 02 34 00 31 05 30 20 30 01 41 80 41 83 &27a0 61 02 92 92 02 16 02 11 33 00 21 82 62 07 92 92 &27b0 02 22 31 20 31 01 34 10 20 61 06 83 02 92 92 02 &27c0 12 31 10 31 01 22 0c 83 02 92 92 02 26 02 33 24 &27d0 60 89 02 92 92 02 37 01 36 80 43 60 86 02 92 92 &27e0 02 12 31 21 0f 02 83 02 92 92 02 22 31 11 0f 02 &27f0 83 02 92 92 02 37 01 18 4a 02 92 92 02 17 01 32 &2800 11 03 62 87 02 92 92 02 31 20 31 20 31 01 33 22 &2810 60 81 60 80 63 83 02 92 92 02 31 03 31 01 33 03 &2820 80 60 00 80 03 83 02 92 70 91 50 01 21 03 21 01 &2830 23 03 63 03 63 01 50 91 70 01 70 91 5f 5f 91 70 &2840 01 04 7f 7f 04 ; header # Palm tree top &2845 65 5c 14 34 03 12 # at &5c65, width &14, height &34, 3 bits, palette &12 ; palette &284b 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f &285b 10 21 ; data &285d 07 06 21 07 02 20 07 07 06 07 07 40 60 68 20 07 &286d 40 60 20 07 07 02 20 00 07 07 01 40 30 68 60 20 &287d 05 40 30 60 20 05 60 07 01 60 00 07 07 03 60 30 &288d 68 60 20 04 40 60 58 60 03 60 48 60 07 61 00 24 &289d 07 07 40 60 30 68 61 20 02 60 70 61 02 60 70 60 &28ad 20 05 20 38 60 00 00 40 30 70 60 68 48 60 22 05 &28bd 40 21 02 62 68 61 01 60 70 68 60 20 01 61 58 60 &28cd 04 20 60 38 60 00 03 41 60 70 60 68 48 61 21 02 &28dd 40 30 61 20 00 62 48 61 20 00 60 38 61 01 61 70 &28ed 60 04 60 70 60 01 06 41 61 70 60 68 62 20 00 40 &28fd 60 70 48 60 20 62 38 61 20 61 68 60 20 00 61 70 &290d 60 03 60 48 70 40 01 07 01 41 61 30 68 62 21 61 &291d 70 63 30 68 63 38 61 20 60 58 60 40 01 20 60 68 &292d 70 60 02 81 01 40 60 22 03 40 62 30 68 64 70 48 &293d 62 30 68 62 70 63 70 60 01 20 60 68 61 03 19 89 &294d 80 00 40 70 30 68 61 20 01 40 63 68 64 58 62 30 &295d 68 61 68 61 48 70 61 00 61 58 61 03 20 1b 10 89 &296d 81 40 60 30 68 61 21 40 62 30 68 63 70 63 18 60 &297d 38 61 78 60 40 20 60 68 60 70 60 02 20 68 70 1a &298d 00 1b 10 89 40 61 70 68 61 20 62 70 48 63 70 62 &299d 70 48 62 70 61 68 30 64 68 60 30 40 00 50 39 1b &29ad 00 1b 08 40 61 30 48 65 58 63 70 63 70 48 60 70 &29bd 68 30 64 68 30 60 40 02 02 51 39 08 1d 08 40 61 &29cd 70 65 78 64 30 64 30 64 30 60 40 05 06 51 3a 1a &29dd 30 20 63 68 67 67 67 61 21 01 07 02 20 64 68 48 &29ed 70 66 68 67 63 70 48 68 64 70 20 48 40 06 21 61 &29fd 68 60 30 70 64 40 63 68 62 48 63 58 67 60 70 48 &290d 68 62 20 70 03 20 60 68 48 60 70 30 62 42 01 20 &2a1d 62 68 30 61 40 62 68 61 40 58 61 30 68 60 30 68 &2a2d 61 40 60 30 68 48 20 50 01 20 60 30 61 43 05 20 &2a3d 62 68 30 61 40 01 30 40 00 60 50 48 60 00 50 68 &2a4d 61 10 68 20 28 40 20 01 42 60 ; header # Palm tree trunk &2a57 1f 73 0d 4a 04 0f # at &731f, width &0d, height &4a, 4 bits, palette &0f ; palette &2a5d 00 01 02 03 04 05 07 08 0a 0c 0d 0e 0f 10 21 ; data &2a6c 0a 40 0f 0f 02 d3 e2 d1 e7 d2 06 08 40 a0 90 0f &2a7c 0b d2 e3 34 20 10 3a 20 30 e2 d1 01 06 40 a0 b0 &2a8c a2 91 70 0f 01 d2 e2 30 20 39 00 39 20 10 36 e1 &2a9c 05 90 c0 b0 90 a0 91 44 90 70 08 d2 e1 35 00 3a &2aac 10 20 38 00 36 20 10 30 05 a0 b0 91 b2 90 b2 70 &2abc 05 d2 e1 3a 00 3b 10 36 65 33 00 31 05 90 41 0a &2acc d1 e1 31 20 3d 10 20 37 62 86 05 83 50 60 30 06 &2adc 71 91 40 03 d1 e1 35 00 3f 31 61 83 0f 05 80 0b &2aec 70 d1 e0 3a 00 20 3b 60 82 0f 0c 09 d1 e0 3f 10 &2afc 20 35 61 81 0f 0f 00 06 d1 e0 30 00 3f 32 10 31 &2b0c 61 80 0f 0f 04 04 d0 e0 34 00 3f 32 60 80 0f 0f &2b1c 07 01 d0 e1 37 10 20 3d 60 81 0f 0f 09 d0 e0 3c &2b2c 10 20 39 60 80 0f 0f 0c ; header # Bird &2b34 19 6b 06 13 04 0e # at &6b19, width &06, height &13, 4 bits, palette &0e ; palette &2b3a 00 01 02 03 05 14 15 1e 1f 28 2a 3c 3d 3e ; data &2b48 00 30 10 05 42 06 30 10 20 50 b0 91 b0 50 71 81 &2b58 70 60 52 00 31 00 b0 00 50 01 90 b0 d0 61 d0 b1 &2b68 51 60 21 50 b6 91 b2 50 02 00 91 00 b0 90 00 90 &2b78 50 90 b0 50 02 90 a0 01 04 c0 01 90 60 01 a0 05 ; header # Sunburst &2b88 49 52 08 10 04 0c # at &5249, width &08, height &10, 4 bits, palette &0c ; palette &2b8e 00 05 07 15 2a 2f 3f 40 55 80 aa bf ; data &2b9a 0d 70 a0 02 70 03 70 02 70 a0 01 03 a0 30 01 b0 &2baa 00 30 40 03 05 40 10 50 30 40 04 00 a0 02 40 60 &2bba 21 60 41 01 a0 00 03 30 40 00 60 01 40 80 03 01 &2bca 80 90 02 70 03 90 02 80 90 0d ; header # Tribesman &2bd4 86 76 05 17 03 15 # at &7686, width &05, height &17, 3 bits, palette &15 ; palette &2bda 00 01 02 03 04 05 08 0a 0c 0e 0f 11 14 15 19 22 &2bea 28 2a 2b 33 36 ; data &2bef 01 5a 03 28 3a 50 03 90 01 68 00 00 78 00 98 58 &2bff 21 00 38 50 00 39 50 99 79 19 10 01 98 58 00 79 &2c0f 30 43 4a 38 00 08 00 38 00 18 11 88 78 00 78 99 &2c1f 78 01 31 70 31 01 10 00 38 00 10 62 04 29 62 a0 &2c2f 98 87 02 ; header # Wolf &2c32 20 7e 0b 17 03 12 # at &7e20, width &0b, height &17, 3 bits, palette &12 ; palette &2c38 00 01 02 03 04 05 0b 10 12 14 16 21 28 2d 30 34 &2c48 43 a8 ; data &2c4a 03 12 30 08 28 07 04 01 08 29 68 18 00 10 19 30 &2c5a 08 28 07 00 78 18 12 1a 09 19 40 08 30 08 06 03 &2c6a 28 60 1e 58 40 19 05 38 08 31 11 00 11 18 58 40 &2c7a 59 19 10 05 60 10 08 03 10 1b 70 19 10 08 05 78 &2c8a 18 10 18 30 28 48 12 18 70 1a 10 18 08 04 03 11 &2c9a 48 19 10 19 58 1a 09 18 08 21 08 01 29 31 11 00 &2caa 10 08 18 10 08 1a 80 19 11 00 78 18 11 07 18 10 &2cba 08 18 08 88 10 03 07 04 10 50 10 06 ; header # Fern &2cc6 87 7d 10 3d 03 18 # at &7d87, width &10, height &3d, 3 bits, palette &18 ; palette &2ccc 00 01 02 03 04 06 08 09 0c 10 12 13 14 1c 20 21 &2cdc 22 23 24 26 28 2c 33 3c ; data &2ce4 41 20 07 07 07 07 07 07 07 01 43 06 20 07 07 07 &2cf4 07 07 07 00 40 00 41 20 02 20 43 07 00 20 41 20 &2d04 07 07 07 07 02 40 b8 00 41 01 42 68 00 40 02 20 &2d14 40 20 02 40 60 30 40 20 02 20 40 68 41 07 07 07 &2d24 01 38 a8 00 41 00 42 68 00 41 00 20 41 60 40 20 &2d34 01 41 00 41 01 40 68 30 20 41 01 20 40 20 07 07 &2d44 04 50 18 42 00 42 a0 20 41 00 42 00 41 01 41 00 &2d54 40 30 00 41 a0 20 41 01 40 68 20 40 01 20 07 07 &2d64 01 50 88 50 39 00 30 40 a0 20 42 00 41 b8 00 41 &2d74 01 40 00 41 01 30 40 20 40 30 02 40 00 40 30 00 &2d84 40 30 40 20 07 07 28 1b 50 18 39 42 02 40 00 41 &2d94 02 08 48 38 53 19 79 18 51 78 18 78 51 38 08 38 &2da4 30 02 20 40 30 40 07 00 41 28 78 18 88 79 50 18 &2db4 50 58 52 1a 79 18 58 78 18 78 29 10 29 20 01 40 &2dc4 00 40 01 40 10 28 10 70 19 51 08 18 38 31 07 00 &2de4 40 30 42 98 90 28 19 50 18 50 18 50 10 71 29 90 &2dd4 30 21 01 30 68 00 41 20 01 40 a0 40 01 68 30 40 &2df4 01 68 29 78 18 78 18 08 20 41 30 20 03 68 00 41 &2e04 68 00 42 01 41 30 41 02 40 b8 00 41 20 01 30 a8 &2e14 20 30 41 01 32 00 30 60 40 01 30 20 40 01 28 18 &2e24 50 08 00 31 04 40 b8 00 40 b8 00 42 20 00 40 b8 &2e34 00 42 01 30 40 a8 00 41 03 30 40 30 41 07 06 41 &2e44 10 18 50 08 00 20 40 20 01 a8 60 40 30 41 60 30 &2e54 41 01 40 60 30 41 02 30 40 60 30 b0 05 80 30 07 &2e64 07 00 41 10 78 18 00 22 01 30 20 40 00 30 40 a0 &2e74 20 41 01 40 a8 00 41 04 31 80 07 07 07 03 41 50 &2e84 08 30 02 04 40 20 41 02 30 28 a0 41 07 07 07 07 &2e94 04 30 00 10 18 08 31 05 31 05 31 07 07 07 07 07 &2ea4 30 40 10 50 00 ; unused &2ea9 54 68 69 73 20 74 69 74 6c 65 20 70 61 67 65 20 ; "This title page " &2eb9 77 61 73 20 64 65 73 69 67 6e 65 64 20 61 6e 64 ; "was designed and" &2ec9 20 70 72 6f 67 72 61 6d 6d 65 64 20 62 79 20 43 ; "programmed by Ch" &2ed9 68 72 69 73 74 6f 70 68 65 72 20 54 68 6f 6d 70 ; "ristopher Thomps" &2ee9 73 6f 6e 20 28 43 29 20 31 39 38 34 20 20 20 20 ; "on (C) 1984 " &2ef9 20 20 20 20 20 20 20 ; " " # &2f00 - &2f37 is unencrypted ; unused &2f00 54 68 69 73 20 74 69 74 6c 65 20 70 61 67 65 20 ; "This title page " &2f10 77 61 73 20 64 65 73 69 67 6e 65 64 20 62 79 20 ; "was designed by " &2f20 43 68 72 69 73 74 6f 70 68 65 72 20 54 68 6f 6d ; "Christopher Thom" &2f30 70 73 6f 6e 20 20 20 18 ; "pson ." Game disassembly ================ ; ; 000400 000023 004780 # Entry point is decrypt_main_binary ; &006a amulet_parts_uncollected ; &006b room_amulet_part ; &006c amulet_part_colour ; &006d rooms_visited ; &006e game_seed ; &006f life_counter ; &0070 sprite_rows_to_plot ; &0071 sprite_data_offset ; &0072 end_column, screen_address_low ; &0073 screen_address_high ; &0074 byte_of_packed_sprite_data ; &0075 chunks_left_in_byte_of_sprite_data, tmp ; &0076 neither_pixel ; &0077 right_hand_pixel ; &0078 left_hand_pixel ; &0079 both_pixels ; &007a music_address_low ; &007b music_address_high ; &007c - &0083 sound_0 ; &0084 room_type ; &0085 orchid_influence_timer_low ; &0086 orchid_flash_count ; &0087 white_or_orchid_colour ; &0088 orchid_influence_colour ; &0089 unused ; &008a key_right ; &008b key_left ; &008c key_down ; &008d key_up ; &008e player_body_colour ; &008f interrupt_ticker ; &0090 unused ; &0091 tmp ; &0092 maximum_species ; &0093 creature_being_considered ; &0094 orchid_position_y ; &0095 orchid_position_x ; &0096 orchid_influence_timer_high ; &0097 orchid_fading ; &0098 previous_orchid_stage ; &0099 orchid_stage ; &009a orchid_colour ; &009b orchid_screen_address_low ; &009c orchid_screen_address_high ; &009d step_count ; &009e numbers_have_changed ; &009f fire_countdown ; &00a0 player_has_tried_to_move_up ; &00a1 player_room ; &00a2 object_screen_address_high ; &00a3 object_screen_address_low ; &00a4 object_position_x ; &00a5 object_position_y ; &00a6 room_object_type ; &00a7 object_colour ; &00c0 lives_as_digit ; &00c1 player_stun_counter ; &00c2 player_has_changed ; &00c3 player_horizontal_direction ; &00c4 player_frame_has_been_updated ; &00c5 player_x_for_check, ; &00c6 rnd_1 ; &00c7 rnd_2 ; &00c8 rnd_3 ; &00c9 turns_per_player_move ; &00ca player_direction : &00 = left, &0d = right, &1a = up, &1e = down ; &00cb previous_player_direction ; &00cc player_sprite ; &00cd previous_player_sprite ; &00ce player_frame ; &00cf previous_player_frame ; &00d0 player_screen_address_high ; &00d1 previous_player_screen_address_high ; &00d2 player_x ; &00d3 previous_player_x ; &00d4 player_y ; &00d5 previous_player_y ; &00d6 screen_address_low, position_x, creature_to_consider, room_data_address_low ; &00d7 screen_address_high, position_y, target_height, room_data_address_high ; &00d8 player_screen_address_low ; &00d9 previous_player_screen_address_low ; &00e0 player_move_counter ; &00e1 screen_x, rows_plotted, height, text_table_address_low, sprite_start_column ; &00e2 rows_to_plot, text_table_address_high, sprite_x_offset, target_y, width ; &00e3 screen_address_low, target_width, horizontal_range ; &0180 - &019f scenery_twopixel_table ; &4900 - &7fff screen memory (after initialisation) ; room sprite &13 data, single colour &0400 00 40 02 09 00 d4 82 02 49 42 d6 b6 03 a8 65 c3 &0410 bd 32 e0 45 3e bd 96 e6 47 ba bf 1a 76 6e ba be &0420 12 b6 ed b3 be 92 fe ef b7 b6 92 fe ef b7 f6 93 &0430 fe ef ff f5 93 ee 7f ff f5 93 ef 7f ff f5 b3 e7 &0440 7f fb f1 f3 e5 7f fb fb f3 65 7f fd 7b f7 67 ff &0450 fb 7b f7 7b ff fb 7b f7 7b ff fb 7f ff 7b ff fb &0460 37 fc 02 ff 0b 50 90 b4 fc f0 4f 0b fd b0 f4 ff &0470 ff ff 43 ff ff ff ff ff ; room sprite &15 data, single colour &0478 d5 08 fb 0d f9 2c b8 2e 9c 26 0c 31 ba 00 fa 00 &0488 fa 00 3a 00 ce 00 df 02 df 00 df 00 9f 02 9f 02 &0498 5f 03 6f 0e 7a 0a 57 0d 1f 0d dc 1d f5 b8 54 b2 ; room sprite &1d data, single colour &04a8 ff ff ff ff ff ff df ff ff ff f7 bf ff fe ff ff &04b8 7f fc ff 70 ; room sprite &01 data &04bc 0a 04 05 11 08 0c 0a 0f 22 33 d0 31 35 f0 80 11 &04cc 30 11 35 10 11 25 14 10 11 15 11 b0 12 17 12 50 &04dc 72 00 10 12 16 17 12 60 11 65 10 11 25 11 20 21 &04ec 90 21 20 11 25 20 25 24 10 11 24 20 11 25 14 20 &04fc 11 15 11 70 27 20 12 37 56 20 12 00 20 16 12 16 &050c 17 40 11 65 14 11 35 14 10 45 10 11 40 21 10 25 &051c 10 15 14 10 21 15 11 95 41 15 34 20 11 40 27 12 &052c 10 27 10 32 57 16 00 17 12 10 17 10 27 30 55 24 &053c 11 35 14 10 45 10 11 25 10 11 35 10 15 14 10 11 &054c 25 14 35 11 10 25 11 10 11 15 10 24 15 14 25 21 &055c 44 20 12 37 12 37 46 00 10 16 17 12 17 12 17 12 &056c 21 35 14 10 44 20 11 35 14 10 11 25 14 10 25 14 &057c 20 14 11 25 31 14 45 10 25 10 25 20 25 20 11 24 &058c 15 11 10 11 12 f7 37 12 00 32 47 16 24 25 14 a5 &059c 31 25 31 25 21 35 14 10 14 45 21 34 10 14 20 14 &05ac 10 24 20 35 20 14 15 10 26 87 96 00 16 10 22 16 &05bc 27 30 35 11 10 11 15 21 20 15 11 74 15 44 10 55 &05cc 21 24 35 20 23 20 23 20 13 10 14 20 11 15 11 14 &05dc 15 20 11 10 87 32 00 12 17 16 22 17 40 14 45 10 &05ec 45 11 14 55 31 14 11 45 11 24 55 14 10 23 10 18 &05fc 19 10 18 19 18 10 13 19 18 30 24 30 15 11 24 20 &060c 27 12 20 36 37 12 00 22 17 26 60 55 10 14 35 11 &061c 10 34 55 10 24 35 80 28 10 13 30 13 30 13 20 13 &062c 19 13 20 11 15 14 10 15 11 24 10 37 12 50 16 27 &063c 16 00 c0 14 25 14 30 34 f0 a0 38 10 18 29 10 28 &064c 19 13 20 28 40 21 24 11 20 16 47 22 00 00 ; room sprite &02 data &065a 0e 04 05 10 08 0c 0d 3c 0a 34 0f 38 20 30 30 23 &066a 3d 23 f0 20 41 00 20 9d 10 13 1d 13 90 11 24 10 &067a 61 00 20 dd 13 20 13 3d 13 30 24 11 10 11 00 30 &068a 5d 19 1b 6d 13 5d 1c 60 34 00 40 4d 1b 19 cd 20 &069a 33 60 11 25 24 00 50 4d 19 1b fd 2d 40 14 25 44 &06aa 11 00 40 fd 19 7d 80 14 00 20 13 fd 1d 1b 19 9d &06ba 23 00 10 3d 1b 19 dd 1b 8d 19 4d 13 00 5d 19 1b &06ca fd 7d 17 4d 00 fd 1b 19 ad 19 1b 5d 00 2d 19 dd &06da 1b 19 5d 19 ad 00 2d 19 1b 5d 19 6d 1b 7d 17 ad &06ea 13 00 2d 1b 19 5d 19 1b 4d 1c 6d 19 1b 6d 19 4d &06fa 00 9d 1b 19 3d 30 2c 4d 1b 7d 17 3d 00 10 bd 1c &070a 80 1c 7d 19 1b 4d 00 20 2c 5d 2c 40 51 30 6d 1b &071a 19 5d 23 00 11 15 a1 34 61 14 10 8d 1b 2d 29 3d &072a 13 00 20 24 11 30 31 10 24 11 90 cd 17 3d 00 10 &073a 11 14 20 11 25 71 6a 12 10 13 bd 1b 4d 00 35 24 &074a a1 26 42 20 8d 1c 7d 00 30 34 31 60 78 20 1c 4d &075a 1c 40 4c 00 00 ; room sprite &04 data &075f 10 01 04 05 02 03 11 23 08 13 0c 0d 0a 22 0e 0f &076f 25 19 17 25 19 17 31 16 40 13 1b 12 10 13 1a 00 &077f 34 1d 24 1d 25 19 17 25 11 10 13 1f 1a 10 1f 1a &078f 10 22 00 30 12 60 24 19 17 15 11 18 22 18 12 28 &079f 00 30 1f 1a 30 13 5e 12 10 1a 18 2a 22 28 00 23 &07af 1f 1e 1a 12 1a 10 1c 10 12 20 1a 1f 2a 10 1f 1b &07bf 12 00 38 1b 1a 28 1b 1a 28 1b 1a 12 18 1e 1a 18 &07cf 00 30 12 1e 18 20 1c 1a 20 1c 1a 00 00 ; player_sprite_twopixel_table_one ; KK KG KY KB KC KW GK GG YK YY BK BB CK BG CC CY # B = orchid colour &07dc 00 04 05 10 14 15 08 0c 0a 0f 20 30 28 24 3c 2d # For WALKING and SITTING ; player_sprite_twopixel_table_two ; KK KG KY YC KC KW GK GG YK YY WW WC CK BG CC CY &07ec 00 04 05 1e 14 15 08 0c 0a 0f 3f 2a 28 1d 3c 2d # For DEAD, FLYING and FIGHTING ; unused ; CC YY GG RR &07fc 3c 0f 0c 03 # Colourful leftovers? ; OS sound workspace and channel buffers &0800 ff 00 00 00 00 00 00 00 c0 c0 c0 c0 04 04 04 04 &0810 07 00 76 64 ff 00 01 ff 00 48 00 00 00 00 00 00 &0820 03 03 05 05 ff c0 80 ff 00 61 0a 00 00 00 00 00 &0830 00 14 47 64 00 14 d1 00 ff ff c1 00 00 f3 00 0a &0840 07 0f 0f 58 07 0a 58 07 0a 80 07 0f 58 07 0a 80 &0850 0a 60 00 0f 0f 50 0a 0a 50 0a 0a 60 00 0f 50 0a &0860 76 01 01 48 fa 01 48 fa 01 48 fa 01 40 64 01 40 &0870 64 06 1e 70 00 05 68 46 4c dd 75 05 1e 70 00 90 ; room sprite &06 data &0880 0f 04 05 14 08 0c 0d 1c 0a 0e 0f 3d 28 3e 3c 40 &0890 21 26 15 14 10 11 25 14 10 31 f0 13 3b 13 00 10 &08a0 11 15 16 2a 15 14 10 11 16 1a 14 10 12 16 19 14 &08b0 10 11 16 14 20 11 14 40 31 1c 1d 3e 1c 00 25 1a &08c0 56 15 39 45 38 16 24 18 19 44 17 14 41 10 42 00 &08d0 10 15 19 1a 12 10 24 19 16 11 30 18 19 15 11 10 &08e0 14 19 11 20 14 20 13 3b 23 10 1a 22 18 2a 00 20 &08f0 24 15 19 12 20 44 e0 1c 2e 1c 1d 1c 20 18 1a 10 &0900 1a 00 00 ; room sprite &1b data, single colour &0903 de da f7 fd 7c 26 b0 c6 b6 f3 45 74 01 d4 c0 3c &0913 b0 05 7c 01 5d 00 16 20 02 ad 40 2b 40 1a 0c 46 &0923 9b c1 7c 58 5f d3 d7 fe 16 c4 ; second_orchid_sprite_address_table &092d ba bf c7 ; OS envelope storage area &0930 02 00 00 00 00 00 00 7e fe ff f7 7e 64 00 00 00 ; envelope 8 (sound 0) &0940 01 81 7f 00 03 03 00 7e f6 f6 f6 7e 64 00 00 00 ; envelope 9 (sound 8) &0950 01 e2 00 00 05 00 00 7e f6 f6 ec 7e 64 00 00 00 ; envelope 10 (sound 9) &0960 02 10 fb 00 0f 28 00 00 00 00 00 00 00 00 00 00 ; envelope 11 (sound 10) &0970 01 00 00 00 00 00 00 32 fe fe fe 7e 64 00 00 00 ; envelope 12 (sound 11) &0980 01 03 00 00 64 00 00 00 00 00 00 00 00 00 00 00 ; envelope 13 (sound 5) &0990 02 10 7f 00 05 c8 00 7e fe 00 e2 7e 64 00 00 00 ; envelope 14 (sound 1) &09a0 01 01 00 00 0a 00 00 7e fc fc fc 7e 64 00 00 00 ; envelope 15 (sound 2) &09b0 02 f7 5a ca 02 02 02 7e fd fe fb 64 46 00 00 00 ; envelope 16 (sound 7) ; sound_table_two ; chan vol pitch dur &09c0 12 00 09 00 64 00 01 00 ; sound_8 # pitch is modified &09c8 12 00 0a 00 fa 00 01 00 ; sound_9 &09d0 11 00 0b 00 0a 00 0a 00 ; sound_10 &09d8 10 00 0c 00 07 00 0a 00 ; sound_11 &09e0 10 00 f1 ff 07 00 01 00 ; unused # Room for four more sounds &09e8 11 00 00 00 00 00 01 00 ; unused &09f0 11 00 01 00 00 00 00 00 ; unused &09f8 01 00 02 00 00 00 05 00 ; unused ; room sprite &00 data &0a00 15 01 04 05 11 03 06 07 13 08 09 0c 0a 0b 0e 0f &0a10 1b 22 23 27 33 20 23 20 23 40 23 40 23 c0 23 4f &0a20 2c 40 23 2f e0 60 23 e0 64 21 00 8f 8c 6f 43 2f &0a30 23 6f 43 6f 2c 20 23 2f 80 43 2f 2d 81 33 54 72 &0a40 94 44 21 24 00 2f 2c 43 4f 4c 22 ce 4f ce 2c 4e &0a50 cf 2d e5 27 30 54 28 92 34 32 28 74 24 00 eb 6b &0a60 62 49 6b 69 42 4b 69 4b 26 e5 45 2d 33 54 32 54 &0a70 28 74 25 28 74 00 eb eb 29 22 eb ab 20 22 2b 4a &0a80 26 a5 27 30 94 48 72 34 32 28 51 00 29 2b 29 4b &0a90 49 4b 49 4b 40 29 2b 22 40 29 4b 20 49 4b 29 6b &0aa0 22 e0 31 d4 71 00 80 49 40 49 40 49 60 49 60 49 &0ab0 60 29 60 69 00 00 ; room sprite &05 data &0ab6 0b 04 05 11 08 0c 0d 23 13 27 33 10 13 17 1a 17 &0ac6 1a 17 13 20 31 00 1a 18 17 18 17 18 27 1a 35 14 &0ad6 11 25 14 31 00 12 19 1a 18 1a 18 1a 19 36 12 36 &0ae6 12 36 22 26 12 00 10 14 35 21 14 35 11 14 25 11 &0af6 14 25 11 10 24 00 20 14 55 10 14 35 10 34 00 00 ; room sprite &07 data &0b06 0c 01 04 11 02 03 06 08 09 0c 22 33 80 12 50 12 &0b16 40 62 30 12 39 12 70 32 49 12 00 30 32 27 20 ; room sprite &14 data, single colour &0b25 22 29 17 20 12 39 12 40 12 29 17 50 32 69 37 30 &0b35 12 29 12 00 37 f9 39 37 69 57 f9 39 22 19 00 40 &0b45 12 49 10 17 39 17 10 17 29 70 17 49 80 37 39 10 &0b55 27 49 12 27 00 70 37 20 17 19 12 30 27 90 37 b0 &0b65 39 40 47 12 00 60 11 15 11 c0 12 30 12 20 12 19 &0b75 22 20 12 30 12 50 17 29 10 12 50 12 00 10 31 45 &0b85 14 40 31 19 22 17 29 27 59 17 69 17 39 12 70 29 &0b95 12 19 12 39 00 55 24 11 85 16 19 10 19 22 29 52 &0ba5 19 62 19 12 39 20 31 35 69 17 00 85 44 60 17 22 &0bb5 27 10 12 39 27 89 22 11 35 34 20 19 27 29 17 00 &0bc5 f5 28 89 32 29 12 27 12 17 19 17 12 17 19 24 a0 &0bd5 17 00 95 74 19 27 19 37 39 17 89 12 29 12 13 8b &0be5 13 00 10 64 85 11 12 19 12 10 22 19 12 17 12 10 &0bf5 17 10 17 20 39 17 29 17 10 8a 40 12 17 00 10 42 &0c05 57 30 34 a9 12 19 22 19 12 10 17 20 17 50 12 19 &0c15 12 10 22 19 22 29 20 12 00 29 22 10 57 12 40 19 &0c25 27 10 29 27 89 18 55 31 12 79 27 29 12 27 00 10 &0c35 47 82 17 40 27 20 27 20 17 10 17 19 17 30 54 69 &0c45 37 20 17 19 00 00 ; room sprite &1f data, single colour &0c4b 30 00 c0 0b 3c 00 a0 c3 2f 00 a9 46 0a c0 aa 91 &0c5b 02 b0 6a 84 00 84 ba 0d 00 a8 6e 01 00 6a 1b 02 &0c6b 90 da a7 00 8c f6 2d 00 a0 7d 08 c0 6c 1d 02 b0 &0c7b 51 a2 00 54 9c 05 00 61 55 0a 40 62 95 02 10 61 &0c8b a7 00 8c e8 29 00 13 7a 06 40 85 9e 01 f0 98 7f &0c9b 00 18 ed 8f 40 0a b9 13 10 42 3e 23 a8 90 3f c7 &0cab 20 14 3f 9f 03 3d 3f 6c 40 3f bf 17 d0 3f 7f 0e &0cbb f4 7f 1f 02 f6 f2 8e 80 0d 7c 27 04 40 3b 2f c1 &0ccb d2 db 82 d0 db 3c 04 f0 6f 03 02 b4 bf 3f 00 2c &0cdb 0f 00 00 09 02 00 ; object_colours_table ; RR MM YY CC &0ce1 03 33 0f 3c ; room sprite &0c data &0ce5 06 04 05 0c 0a 08 21 13 71 35 14 20 31 13 21 12 &0cf5 00 10 15 51 12 20 75 51 12 00 00 ; room sprite &08 data &0d00 0e 01 04 05 02 03 07 08 0c 0d 0a 0b 0e 0f 60 12 &0d10 60 42 20 32 38 17 10 32 38 12 00 20 22 17 38 17 &0d20 10 12 28 37 10 12 38 52 28 40 22 18 27 18 12 20 &0d30 22 00 12 68 17 10 12 28 12 48 57 18 47 18 17 88 &0d40 42 18 12 27 10 12 17 18 00 48 17 10 38 17 18 27 &0d50 10 27 48 12 20 28 12 10 28 12 20 18 12 30 18 27 &0d60 18 27 38 22 10 22 00 17 18 17 22 28 17 22 10 27 &0d70 28 72 10 17 18 17 20 18 17 20 18 17 30 18 17 20 &0d80 18 12 20 12 27 18 12 10 12 10 12 00 12 28 29 1c &0d90 58 1c 12 13 10 67 30 12 28 30 27 18 32 28 70 27 &0da0 10 12 17 39 00 19 18 4c 1d 39 38 19 1d 13 10 52 &0db0 48 22 38 12 10 18 39 a3 4d 00 1d 19 68 1c 5d 1a &0dc0 1d a8 37 20 17 10 38 bb 81 00 2d 19 78 4d 10 1d &0dd0 e8 12 10 12 17 38 6b 6d 16 64 00 1a 4d 49 2d 2a &0de0 13 1d 1a 10 37 48 22 20 37 10 28 12 19 4d 16 24 &0df0 35 41 00 30 3a 1d 43 1d 2a 80 37 28 10 68 17 40 &0e00 1a 2d 13 30 44 25 00 f0 b0 17 30 37 40 23 2d 1a &0e10 00 00 ; room sprite &09 data &0e12 15 01 04 05 11 02 03 07 13 08 0c 0a 0b 0e 0f 1b &0e22 22 23 26 27 33 46 34 26 21 24 41 e0 40 22 2a 40 &0e32 22 00 25 30 45 28 31 46 34 66 24 41 20 4a 29 20 &0e42 2a 29 20 22 00 e0 30 65 28 31 26 28 32 4a 22 4a &0e52 22 2a 29 00 60 22 e0 82 4a 29 6a 29 00 20 2a 22 &0e62 29 2a 22 40 c9 20 42 4a 20 29 2a 00 40 2a 20 4a &0e72 20 22 29 a0 89 60 29 00 20 22 2a 20 4a 20 2a a0 &0e82 62 20 64 20 44 30 00 22 2a 20 4a 22 4a 22 ca 32 &0e92 34 2f 33 74 24 00 29 2a 22 29 2a 20 4a 20 89 4a &0ea2 32 30 2f 54 30 34 24 00 40 4a 20 2a 20 29 22 80 &0eb2 a3 6e 00 20 22 2a 29 22 29 20 83 ee 2e 2d 22 20 &0ec2 22 00 20 82 4d 8e 4d 2a a9 42 29 22 2a 00 2a 22 &0ed2 69 ca 62 a9 80 2a 00 20 29 6a c2 49 4a 29 40 21 &0ee2 40 21 00 a0 e9 29 80 27 25 21 26 2c 26 00 23 2e &0ef2 2b 2e 2b 2e 2b 2e 2b 2e 2b 2e 6a 2d 46 27 26 2c &0f02 46 25 00 2e 23 2b 23 2b 23 2b 23 2b 23 2b 2e 4a &0f12 2d 2e 66 27 66 25 00 20 2b 4d eb 2b 89 25 2c 26 &0f22 20 26 2c 25 00 20 6a 22 20 42 2a 22 c0 21 26 25 &0f32 40 25 00 40 22 2a 62 29 2a 49 20 22 4a 22 00 40 &0f42 22 2a 22 20 22 2a 89 22 2a a2 2a 29 00 20 29 6a &0f52 20 29 6a 20 29 4a 22 40 22 2a 69 22 00 00 ; creature sprite &1f data - WOLF &0f60 0c 27 03 c3 c9 40 92 93 90 cc 24 70 93 19 9c d4 &0f70 07 29 fc 41 57 cf c0 dd 26 54 bf 0b fe fe c0 73 &0f80 3f 9c e3 49 f9 ab b2 f7 37 f4 d7 0b b8 da 00 ac &0f90 02 40 1f 00 c0 06 00 90 00 00 24 00 00 08 00 00 ; creature sprite &21 data - WOLF &0fa0 0c 27 03 c3 c9 40 92 93 90 4c 26 70 c3 19 b8 b4 &0fb0 07 2d ef 41 57 e7 c0 dd 24 54 bf 0b fe fe c0 73 &0fc0 3f 9c e3 49 f9 ab b2 f7 37 f4 d7 0b b8 da 00 ac &0fd0 02 40 1f 00 c0 06 00 90 00 00 24 00 00 08 00 00 ; creature sprite &20, &22 data - WOLF &0fe0 c0 c0 00 30 30 00 24 24 00 09 0c 40 02 03 b0 d0 &0ff0 04 2c 2c 01 43 4b c0 d5 3a 50 3f 0b f5 ff 82 b7 &1000 3f 90 de 0f f7 b8 52 fe 9e ec ff 0c fd f5 02 ae &1010 3f 00 ab 09 d0 07 00 b0 01 00 24 00 00 09 00 00 &1020 02 00 ; creature sprite &1b, &1c data - RHINO frames 0 and 1 &1022 20 00 04 0d 00 c9 df c3 c3 fb b6 d0 be 0f f0 dd &1032 02 f4 77 00 fc be 7d ff 2f fd ff 9b ff ff f6 ff &1042 bf e4 ff 0f fb ff d3 2d bf 0c 03 0b 42 00 00 ; creature sprite &1d, &1e data - RHINO frames 2 and 3 &1051 00 01 02 40 92 00 f0 3c 00 2d 2d c0 b7 0f b0 7f &1061 03 ec ef f6 f9 bb f4 fe 6e fe bf db ff df 92 ff &1071 bf ec ff 4f f7 ff 33 dc bf 08 f1 0f 00 f0 00 ; creature sprite &0e data - LIZARD frame 1 &1080 24 24 34 2c 30 0c f0 0b dd ff f4 ff fb bb fd 36 &1090 b7 3d f5 1f fc 09 c0 08 40 00 ; creature sprite &0d data - LIZARD frame 0 &109a 90 09 b0 0d 30 4c 9d d9 fd ff ff bf fd 3b f7 b7 &10aa b5 ac fc 2f c0 29 c0 29 40 08 ; creature sprite &18 data - SNAKE frame 1 &10b4 40 c3 c0 db c0 bf d0 3c 90 24 90 00 90 00 90 00 &10c4 90 00 c0 00 c0 00 c0 02 40 02 40 02 10 03 d0 03 &10d4 d0 03 90 03 80 03 40 02 ; creature sprite &17 data - SNAKE frame 0 &10dc b0 c0 f4 b3 fc 3f 2c 2f 0c 09 0c 00 0c 00 0e 00 &10ec 2f 00 2b 00 29 00 2c 00 04 00 ; creature sprite &0c data - SPIDER frame 1 &10f6 00 01 00 01 00 21 00 21 00 a1 00 a1 24 a6 1c 86 &1106 9c 16 b8 1a b8 33 34 25 61 0d c9 09 38 34 ac ab &1116 84 be 70 b6 40 b1 40 19 40 2c 40 00 ; creature sprite &0b data - SPIDER frame 0 &1122 80 00 80 04 80 04 c0 04 40 04 40 84 64 84 5c 84 &1132 9c 86 b8 16 b8 1e 34 18 e0 2d 99 01 7c 2c c0 3b &1142 94 be 34 ae 20 b6 c0 b1 40 18 00 24 ; creature sprite &12 data - TRIBESMAN frame 1 &114e 34 80 41 20 b7 9c 5a 22 8b 0c 66 18 fb 91 55 56 &115e 49 1f 4c 39 41 54 15 64 3d 51 46 10 08 ; creature sprite &2a data - FIRE frame 1 &116b 28 29 37 97 8e 8a b8 ad c5 e3 ea da 5e 7d 79 31 &117b 31 24 a4 8c 20 ; creature sprite &29 data - FIRE frame 0 &117f 34 3c b9 a1 e3 67 6d 78 f8 e9 65 c5 94 15 87 a5 &118f b1 60 0c ; creature sprite &2b data - FIRE frame 2 &1193 28 39 b7 c6 5c 9d 85 e7 66 62 7a fa fe ad a7 a6 &11a3 24 71 31 90 ; creature sprite &28 data - GUARDIAN &11a7 00 0b c0 40 43 c0 1c 08 07 7a 81 6d e0 1f f8 07 &11b7 b6 81 40 60 9b f8 6f ff d3 7f e0 10 c8 06 f6 81 &11c7 51 60 bf 98 47 ef 83 bf e0 25 60 08 b8 02 bf 40 &11d7 0f ; creature sprite &27 data - SLEEPING_HIPPO &11d8 00 d0 00 50 bb 12 4b d3 d4 6e b3 bd ff 46 ef fd &11e8 d0 eb db f4 3e 3e fd dc 6b ff bc ca ef 75 f2 7b &11f8 bd fc ed 2f fd ff 03 ff bf 40 ff 0b 40 bf 00 ; creature sprite &23, &24 data - HIPPO frames 0 and 1 &1207 20 00 24 0d 00 cb 0b d0 f3 b3 fc f4 7e 2f bc df &1217 03 ed be 00 9f 1f 40 7f 4f df ff 4b ff ff ee ff &1227 bf fe ff 4f f7 ff 03 6f bf 00 03 0b 40 00 00 ; creature sprite &25, &26 data - HIPPO frames 2 and 3 &1236 00 43 02 d0 f2 00 fc 3d 00 2f 2f c0 73 0b f0 dd &1246 03 7c fb f4 fd 37 f4 ff df fe ff e7 ff ff 76 ff &1256 3f f0 ff 0f 70 ff 02 d4 bf 00 f0 0f 00 f0 00 ; object_sprite_address_low_table &1265 0b 1f 33 47 5b 6f 83 97 ab bf d3 e7 ; player_body_colour_to_video_ula_table ; W R M C Y &1271 40 46 42 41 44 ; turns_required_per_move_by_orchid_colour &1276 02 03 02 00 00 ; fire_colour_table ; GG YY RR MM CC WW RR RR &127b 0c 0f 03 33 3c 3f 03 03 ; orchid_sprite_rows_table &1283 03 03 04 05 08 07 08 08 ; orchid_sprite_address_table &128b 73 78 7d 83 8b 97 a2 ae ; room sprite &0b data &1293 1b 01 04 05 14 02 03 33 07 13 08 22 0c 0d 1c 0a &12a3 0b 0e 0f 11 28 23 2c 3f 3c 2a 15 a0 41 e0 8a 6d &12b3 42 20 42 cd 22 e0 60 23 72 40 43 00 20 41 26 29 &12c3 35 66 33 41 ea 2a ec 2c 62 e0 80 43 32 2f 20 23 &12d3 52 2f 00 45 26 29 35 66 29 35 66 27 a6 21 33 41 &12e3 50 20 a1 aa 80 23 52 2f 20 23 52 2f 00 a1 45 2b &12f3 85 29 35 a6 29 35 86 27 a6 27 a6 27 22 28 52 8f &1303 32 43 d2 23 00 20 a6 c5 c0 2b a5 2b a5 29 35 86 &1313 29 35 28 32 31 23 f2 72 6f 00 40 25 80 22 e0 e0 &1323 e0 80 62 20 4c 20 ac 62 00 40 42 6c 2a 40 22 4c &1333 2a 20 82 e0 20 82 8c 2a 20 6c 22 2a ec 4c 22 00 &1343 20 6c 2a 40 42 4c 2a 40 22 4c 2a 40 22 4c 2a 20 &1353 22 ec 2c 2a 22 20 8c 42 6a 8c 4a 00 6c 42 6c 2a &1363 60 22 4c 2a 60 22 4c 80 6a a2 6c 20 cc 00 2a 4c &1373 4a 4c 2a ec 2c 22 8c 22 20 22 4c 2a 20 6a 4c 6a &1383 40 ac 2a 00 20 4c 40 4c 40 4c 40 4c 20 6a 4c 2a &1393 6c 42 2c 6a 40 6a 42 20 4a 00 20 4c 40 4c 40 4c &13a3 40 4c 80 4c 80 6a 6c 42 a0 8a 5a 57 59 57 7a 00 &13b3 20 2a 4c 20 4c 40 4c 40 4c 80 4c 22 c0 2c 40 4a &13c3 2c 22 4a a0 39 37 5a 80 39 57 39 00 40 4c 20 4c &13d3 22 40 4c 40 4c 60 2a 4c c0 4c 80 2a 2c 22 c0 39 &13e3 77 5a 00 40 4c 40 4c 40 4c 22 20 4c 44 40 2a 4c &13f3 a0 2a 4c a0 2a 2c 32 23 2f 32 2f 23 00 60 4e 24 &1403 20 2a 2e 44 f8 38 54 20 4a 63 d2 6f 20 72 20 32 &1413 2f 32 00 20 24 58 34 20 24 98 34 62 24 62 2e 8c &1423 2e 56 4c 2e 36 c2 20 2f 20 6f 20 84 00 98 20 34 &1433 82 20 34 56 38 76 38 56 6e 38 8e 38 8e 38 6e 63 &1443 24 b8 54 00 2a 2c 42 20 8a 4c 62 20 6a 34 cc 36 &1453 2e 4c 36 2e 6a 34 4a a0 54 98 34 00 60 6a 4c 22 &1463 20 2a cc 2a 80 cf 00 00 ; room sprite &0d data &146b 19 01 04 05 11 02 03 3c 07 13 08 09 0c 1c 2c 0a &147b 0b 0e 0f 28 22 23 26 14 33 af 83 a0 41 24 41 46 &148b 38 66 24 61 40 22 2c 60 22 00 b0 68 26 32 35 29 &149b 26 38 46 35 29 46 38 65 34 25 66 38 26 2b 4c 20 &14ab 22 2c 20 22 2a 00 90 68 26 32 26 32 34 45 34 25 &14bb e0 80 25 34 25 46 38 2c 22 4c 22 2c 00 6f 63 20 &14cb 2f 23 2f 23 6f 43 20 24 38 20 38 24 20 38 44 38 &14db 80 45 8c 2a 00 80 22 20 2f 43 2f 23 4f 63 38 35 &14eb 58 26 58 26 38 34 e0 4c 2a 4c 22 00 60 2c 2a 40 &14fb 22 c0 42 34 38 34 78 26 58 e0 4c 2a 40 2a 4c 00 &150b 40 2c 2a 40 22 2c 60 22 6c 80 22 25 34 22 54 35 &151b 24 c0 83 40 2a 00 22 4c 42 2c 2a 20 62 6c 62 ac &152b 82 36 62 ac 51 52 2f 00 20 2a 4c 20 4a 4c 22 40 &153b 2a 6c 6a 6c 42 40 2a 8c 22 00 40 2a 27 2d 60 2a &154b 4c 22 40 8c 22 20 4a 6c 22 40 6a 8c 42 23 00 40 &155b 37 27 33 a0 2d 2c 60 2a 8c 2d 37 20 8c 4d 57 60 &156b 4f 52 2f 00 20 27 33 a0 37 27 33 e0 2a 53 40 aa &157b 33 00 00 ; room sprite &0e data &157e 1d 01 04 05 14 02 03 06 33 11 08 22 0c 23 1c 0a &158e 13 1b 0f 27 28 15 2c 2a 3c 3d 3e 3f 2e 40 42 4c &159e 2e 22 40 42 6c 2e 36 4c 2e 36 42 a0 62 2c 38 2c &15ae 24 00 20 4c 2e 56 4c 20 4a 4e 76 38 76 2e 2c 4a &15be 40 2a 2c 36 2e 38 4e 56 2c 2a 00 22 2e 36 4c 4a &15ce 20 e2 e2 4e 38 2c 22 24 22 20 6a 34 2a 00 4e 20 &15de 40 84 35 64 35 64 8a 36 4c 2e 56 4e 36 22 00 34 &15ee 58 7a 59 3b 79 3b 79 38 3b 58 39 44 34 4c 38 4c &15fe 36 2a 20 42 60 22 00 20 34 78 24 54 3a 39 38 3a &160e 59 58 3b 7a 79 34 e0 2a 6c 20 2a 4c 00 20 42 56 &161e 60 a2 40 34 36 3c 56 37 34 62 40 42 20 42 2a 6c &162e 20 6c 00 8c 6a ac 4a 8c 6a 8c 8a 4c 2a 20 6c 20 &163e 6c 00 20 2a 6c 62 20 2a 6c 42 20 2a 6c 42 20 2a &164e 4c 4a 40 4a 22 4c 2a 22 6c 00 26 21 29 20 aa 40 &165e 4a 6c 22 20 4a 4c 2a e0 20 6c 2a 22 6c 00 46 28 &166e 66 29 61 e0 c0 21 29 61 29 6c 2a 22 6c 2a 22 2c &167e 00 25 46 2d 46 25 2b 65 2b 65 2b 45 26 2d 30 66 &168e 28 66 28 2a 42 6c 2a 22 4c 2a 00 20 61 29 21 46 &169e 28 86 28 86 29 41 45 47 2b 62 4c 4a 42 6c 2a 22 &16ae 00 26 28 46 2d 30 46 25 2b 65 2b 30 46 30 2d 66 &16be 28 45 4a 22 ac 6a 42 4c 00 26 25 2b e0 e0 20 65 &16ce 2d 46 30 2b ac 42 2a 6c 22 2a 2c 00 40 23 29 23 &16de 32 33 52 31 52 43 e0 40 2b 2c 22 2a 4c 22 20 2a &16ee 4c 22 2a 6c 00 23 52 31 52 33 52 31 52 33 52 22 &16fe 2c 2a 20 22 80 6c 20 4c 60 6c 20 4c 2a 00 2b 52 &170e 31 52 33 52 31 52 33 52 2a 2c 4a c0 4c 20 2a 4c &171e 60 4c 22 20 2a 00 40 6f 32 33 52 31 52 2b 2f e0 &172e 80 4c 40 2a 4c 60 2a 4c 00 e0 e0 e0 80 2a a0 2a &173e 00 00 ; room sprite &0f data &1740 10 01 04 05 02 03 33 13 08 09 0c 23 0a 11 22 0f &1750 32 48 80 12 2a 12 20 22 00 38 1a 38 1c 12 4a 22 &1760 18 3a 12 48 00 11 30 18 1c 40 38 2a 19 11 32 3a &1770 12 00 25 16 25 11 1d 31 17 25 1b 17 15 10 1a 22 &1780 18 2a 18 00 10 24 1e 14 15 1b 17 25 1b 17 24 30 &1790 18 2a 00 20 22 20 12 40 22 50 18 00 10 2a 18 10 &17a0 12 2a 10 12 2a 18 12 2a 18 10 12 2a 12 00 18 2a &17b0 18 3a 28 2a 28 2a 28 3a 18 12 2a 00 10 18 2a 10 &17c0 18 2a 12 18 1a 12 20 28 20 38 10 18 00 5f 1c 1f &17d0 1a 10 1a 22 6a 22 00 2f 2c 13 1f 1c 10 1a 10 18 &17e0 2a 12 18 1a 12 28 3a 12 00 1c 2f 2c 30 2a 10 3a &17f0 10 2a 40 2a 12 00 60 12 1a 18 12 2a 18 12 1a 18 &1800 60 28 00 00 ; room sprite &10 data &1804 0e 04 05 14 08 0c 0d 1c 0a 0e 0f 28 2c 3c 10 51 &1814 1c 2d 23 30 13 3d 13 00 85 2c 3d 13 2d 2b 63 00 &1824 55 2d 47 15 2c 1d 13 1b 4d 13 00 10 54 6c 5d 30 &1834 2b 00 10 41 2c 1b 3d 2b 31 12 31 16 15 19 12 00 &1844 15 17 4c 17 15 10 1a 25 19 16 35 1a 15 16 19 25 &1854 18 00 15 1c 47 1c 15 12 19 35 18 24 18 24 10 11 &1864 12 11 00 11 15 47 15 11 10 11 12 21 16 25 1a 25 &1874 1a 15 19 16 15 00 15 1d 45 1d 15 10 15 1a 35 1a &1884 15 19 25 14 18 24 00 14 15 4c 15 14 10 18 34 18 &1894 40 41 14 11 00 00 ; room sprite &11, &16, &17, &18 data ; mountain_sprite_data &189a 0e 11 15 30 31 35 22 32 33 37 2a 3a 3b 3f 48 23 &18aa b8 1c 19 a8 1c 2d 12 00 58 23 14 98 19 2d 19 88 &18ba 39 3d 32 00 68 14 13 27 58 3c 4d 18 27 98 29 3d &18ca 32 00 78 63 14 38 1d 2c 3d 23 28 37 58 5c 7d 32 &18da 00 58 39 15 13 14 68 29 4d 15 13 17 63 17 18 27 &18ea 18 19 fd 22 00 38 2c 5d 68 2d 1c 28 1c 4d 15 63 &18fa 14 68 29 cd 12 00 28 19 8d 19 38 2c 19 58 1d 2b &190a 73 14 68 1c 18 19 18 1c 9d 2a 00 38 29 8d 18 19 &191a 1d 2c 38 19 3d 25 83 17 28 29 2c 28 1c 4a 00 48 &192a 29 5d 1c 88 1d 1c 6d 53 24 18 17 14 38 26 00 38 &193a 1d 1c 28 2d 1c 58 19 3c 48 1c 2d 1b 53 27 18 13 &194a 48 26 10 18 11 00 68 19 1c 48 19 68 1d 19 38 1d &195a 73 14 18 14 18 27 14 58 1c 3d 12 00 28 39 78 1c &196a 1d 19 38 5d 19 35 43 15 17 43 14 58 3c 5d 22 00 &197a 18 19 2d 1c 28 1d 19 58 1c 1d 19 38 2c 8d 15 1d &198a 15 33 17 48 29 1c 18 29 7d 00 19 2d 1c 48 1c 1d &199a 29 38 2c 2d 29 28 1c dd 15 19 58 4c 3d 2a 00 4d &19aa 29 48 1c 18 3c 18 29 4d 19 18 1c 1d 2c 19 3d 2c &19ba 19 4d 1c 18 29 58 1a 00 2c 7d 19 78 19 28 2c 2d &19ca 39 18 2c 38 19 2d 1c 4d 2c 19 1d 29 00 18 2c 19 &19da 4d 2c 1d 19 18 29 2c 48 19 9d 39 18 2c 4d 4a 00 &19ea 28 1c 38 19 1d 29 1d 1c 18 1c 68 4c 19 9d 1c 1d &19fa 1c 12 00 48 2d 1c 3d 1c 48 49 28 29 1d 3c 19 2d &1a0a 2c 18 19 2d 1a 00 38 1c 38 1d 1c 28 39 1c c8 1c &1a1a 58 1d 1a 00 00 ; room sprite &12 data &1a1f 0a 01 05 02 03 13 0a 0f 22 23 f0 70 42 00 30 11 &1a2f 14 15 74 15 54 13 12 17 16 12 16 27 12 00 20 14 &1a3f 15 e4 10 47 12 16 12 10 27 12 00 10 54 19 64 29 &1a4f 24 10 27 12 26 10 17 12 16 12 37 12 00 15 24 39 &1a5f 84 19 14 10 27 12 26 12 16 47 16 12 10 16 17 12 &1a6f 00 43 18 b3 12 17 12 17 16 12 16 17 12 27 10 12 &1a7f 27 12 10 16 17 12 00 f0 10 17 26 17 20 16 17 12 &1a8f 20 17 10 17 16 12 17 22 27 12 00 f0 10 17 16 17 &1a9f 16 20 27 12 20 12 16 22 17 16 17 16 12 37 12 00 &1aaf f0 10 17 36 20 22 16 10 16 12 16 17 22 17 36 10 &1abf 12 16 00 f0 10 17 12 26 20 12 16 12 16 12 17 22 &1acf 16 20 17 22 16 00 f4 14 10 17 16 10 12 17 16 40 &1adf 16 12 40 12 16 00 13 24 13 11 14 10 44 11 14 11 &1aef 24 11 16 22 10 27 12 10 16 30 26 12 16 00 10 13 &1aff 34 13 54 43 24 11 16 12 20 16 22 40 12 16 00 20 &1b0f 13 34 43 64 23 10 16 12 40 26 12 16 00 40 f3 13 &1b1f 10 16 42 16 00 00 00 00 d0 b0 00 6b 1f b2 7c f1 &1b2f 4f 17 ff e4 f1 4f 9e ff e4 fb 6f be ff d6 fb 6f &1b3f bd ff d6 eb 7d fe de e7 ef 79 fe 9e e7 ef fa fe &1b4f ac ef cf da ff ac 2d c1 da 4c 84 d8 3f 22 ff ff &1b5f ff ff ; room sprite &1e data, single colour &1b61 fb f7 bf 7d df d1 bf 1d f7 fb 77 3f 6f df e3 be &1b71 1c 2f 00 d0 ; room sprite &22, &24 data, single colour &1b75 fc 7f cb ff f7 fc 7f df eb fe bd c3 de f2 ce fd &1b85 3d dd df f3 ff 7e fe ef de ff a7 9b fd f9 f5 5f &1b95 cb ff b5 ed ef fb bd 7c db e6 07 fe 7e 3c 7f fe &1ba5 df cb ff ff f8 ff 7b ff ff df ff ff ; second_orchid_sprite_rows_to_plot_table &1bb1 03 05 08 ; creature sprite &13 data - MOUSE frame 0 &1bb4 0c 0b 24 d9 a0 37 70 0f 70 0b 77 0b bf 03 fd 01 &1bc4 d5 03 c5 02 0c 00 08 ; creature sprite &0f data - BIRD frame 0 &1bcb 00 00 00 20 42 27 ec c8 9c dc 83 2f b4 c0 33 75 &1bdb b3 2e dc 92 0c ; creature sprite &10 data - BIRD frame 1 &1be0 01 30 00 0b b2 24 c7 78 9e d5 93 2f b4 c0 07 f5 &1bf0 b2 ba cc 90 b4 00 cf ; creature sprite &14 data - MOUSE frame 1 &1bf7 c0 d2 30 33 64 27 c7 0f ef 0b ed 0b 75 03 95 01 &1c07 dc 03 c8 02 ; object sprite &0 data - CRATE &1c0b 90 90 93 a8 60 86 a9 a6 98 60 b2 39 36 95 e1 21 &1c0b 21 49 09 08 ; object sprite &1 data - SWORD &1c1f 03 24 90 00 03 38 90 c0 01 0e 90 40 02 0c 30 40 &1c2f 00 08 20 40 ; object sprite &2 data - FRUIT &1c33 a4 b0 d3 67 af ff ff fe fb ef 7f f7 d9 2a 97 a4 &1c43 c1 05 20 00 ; object sprite &3 data - RING &1c47 b0 d0 c3 2f 93 09 27 9c 30 c0 00 2f fc b0 9b e7 &1c57 a6 c3 0a 09 ; object sprite &4 data - CAP &1c5b 22 88 21 04 1b 3d 4d e6 5e 97 9d e7 97 1a 56 c8 &1c6b d5 8a 07 00 ; object sprite &5 data - BAG &1c6f f3 bf df 64 aa ad 36 99 6e aa 4d b2 cb 2f 3d 00 &1c7f d1 89 0b 2a ; object sprite &6 data - SHIELD &1c83 b4 20 11 e0 c0 7a 19 76 d8 e3 7b 3f bf ff 7d bf &1c93 f7 c9 0f 2d ; object sprite &7 data - LIFE &1c97 35 e4 80 02 0a aa a8 72 8b 2f be f8 72 4b 0e 28 &1ca7 a0 80 02 01 ; object sprite &8 data - AMULET_TOP_LEFT &1cab f7 c7 97 1d d2 88 a3 87 2d 26 0c 10 4d 3f 6c 00 &1cbb 01 08 20 40 ; object sprite &9 data - AMULET_TOP_RIGHT &1cbf 3f bf fa e0 8b 0f 3e d8 22 af 30 02 38 e4 12 fe &1ccf d4 12 80 00 ; object sprite &a data - AMULET_BOTTOM_LEFT &1cd3 00 00 40 3f ff 09 04 32 85 9c e2 0b 6d b5 c5 16 &1ce3 f9 ea af fa ; object sprite &b data - AMULET_BOTTOM_RIGHT &1ce7 00 24 b0 a4 ff b4 01 04 90 61 a7 fd f6 db 4f 7f &1cf7 7d 17 9f 6f ; room sprite &1c data, single colour &1cfb 00 40 00 30 05 40 53 00 3c a7 ed f3 f6 3e 6f ee &1d0b f2 ee 2f ef ff b2 f6 2f 6b fe 72 e6 6f 4f fe f6 &1d1b e4 6b 4f 3e e6 64 63 4e 36 ee 64 e7 ce 73 ee 3c &1d2b e6 ce 63 ee 3e e6 ec 43 cf 3e f4 fc cb cf bb fc &1d3b bc cb cf 9f fd fc d3 8f 3f ff 7c f7 cf 77 ff 7c &1d4b 77 4f 77 b6 74 f7 4b 66 bf 64 fe 4a e7 af 55 ee &1d5b 4b e3 bd 35 de 4b f3 bd 35 df 40 f0 b9 71 42 5f &1d6b db df f5 ff cb bd bf ff ; orchid_sprite_1 &1d73 10 00 0f 14 00 ; orchid_sprite_2 &1d78 10 00 0f 1c 02 ; orchid_sprite_3 &1d7d 10 40 0f fc 82 25 ; orchid_sprite_4 &1d83 10 40 0f fc c2 25 18 02 ; orchid_sprite_5 &1d8b 10 40 0f fc c2 2f 5c 82 21 30 00 09 10 c0 05 5d &1d9b d2 35 5d 93 32 20 00 ; orchid_sprite_6 &1da2 10 c0 05 5d f2 35 5f b3 37 23 41 02 ; orchid_sprite_7 &1dae 10 c0 05 5d f2 35 5f bb b7 23 4b 02 ; second_orchid_sprite_5 &1dba 34 00 0b 90 00 00 ; second_orchid_sprite_6 &1dc0 00 03 f4 40 0f b0 00 ; second_orchid_sprite_7 &1dc7 89 c9 73 e4 fe 6f fd de 6d 68 87 92 ; creature sprite &11 data - TRIBESMAN frame 0 &1dd3 94 80 02 0a 05 14 18 22 8b 1c e6 5a f4 95 55 d6 &1de3 0b 10 4c 39 41 54 11 7c 3d 51 44 18 01 ; fire_pitch_table &1df0 81 69 75 96 85 71 5d 63 4d 4d 4d 63 4d 4d 4d 7d ; hippo_charge_countdown &1e00 f0 f0 ; room sprite &20 data &1e02 09 05 15 0a 0f 1f 2a 2f 3f 10 32 f0 f0 60 12 28 &1e12 10 42 00 58 12 10 22 f0 d0 26 12 18 16 28 12 16 &1e22 18 16 38 32 00 16 58 10 26 f0 b0 32 18 17 68 11 &1e32 28 12 58 12 00 10 36 f0 e0 16 28 16 28 15 14 17 &1e42 28 17 14 15 98 00 12 48 32 f0 22 30 22 38 16 12 &1e52 16 18 22 18 17 44 18 15 14 16 18 56 00 28 12 48 &1e62 16 18 12 10 12 18 16 38 22 10 12 38 26 18 12 16 &1e72 78 15 74 27 25 14 11 34 13 14 00 38 26 58 11 17 &1e82 28 16 28 26 18 10 68 16 18 12 16 48 17 74 13 21 &1e92 34 21 34 13 00 17 58 12 28 17 34 27 48 17 24 37 &1ea2 48 17 34 73 41 10 14 13 44 13 14 11 00 34 47 54 &1eb2 23 74 21 53 34 21 14 33 64 13 11 34 10 54 00 10 &1ec2 54 11 94 21 44 13 54 61 23 74 10 13 54 11 24 13 &1ed2 00 20 13 11 50 23 30 23 40 21 74 13 24 13 24 23 &1ee2 50 23 10 13 14 21 14 13 34 11 00 40 13 11 40 41 &1ef2 84 63 10 13 10 13 20 51 73 30 11 34 13 24 00 30 &1f02 14 21 c4 31 30 41 24 11 10 31 10 11 30 24 21 14 &1f12 13 10 34 23 44 00 20 f4 23 74 21 a4 11 54 13 10 &1f22 94 00 10 13 14 73 40 31 54 11 54 33 41 24 23 54 &1f32 10 64 13 00 10 11 13 11 30 41 b4 43 21 f4 14 13 &1f42 11 34 11 44 13 00 10 53 d4 21 f4 84 10 94 11 00 &1f52 00 ; room sprite &21 data &1f53 09 05 15 0a 0f 1f 2a 31 3f 20 11 10 63 44 13 84 &1f63 13 74 11 c4 10 94 11 00 30 13 10 61 14 23 44 31 &1f73 43 10 53 54 33 24 23 30 54 13 34 00 30 11 34 11 &1f83 44 13 34 c3 50 31 40 51 10 34 23 24 13 00 20 74 &1f93 43 a4 43 24 13 44 13 64 11 24 13 11 64 00 30 14 &1fa3 10 13 b0 43 21 44 13 10 41 33 14 21 44 10 44 11 &1fb3 44 00 40 13 20 41 34 31 34 31 24 13 10 11 24 11 &1fc3 54 41 44 10 54 11 10 24 00 30 21 64 11 34 31 20 &1fd3 33 20 11 34 31 23 11 33 30 33 10 14 13 74 11 00 &1fe3 20 44 11 e4 23 f4 21 10 21 30 44 13 21 13 24 00 &1ff3 11 24 45 44 15 28 45 64 25 f4 34 21 10 34 23 14 &2003 11 10 14 00 15 78 15 14 98 14 25 48 15 13 14 15 &2013 18 25 d4 11 34 11 20 13 11 14 00 48 22 28 16 12 &2023 18 16 12 16 38 16 12 28 10 58 10 15 58 15 94 13 &2033 10 94 13 00 48 16 28 16 20 66 10 26 18 32 38 16 &2043 10 28 12 38 10 94 10 84 11 00 10 56 f0 10 36 10 &2053 16 48 26 10 12 15 38 15 54 10 64 25 18 12 00 10 &2063 12 18 16 38 32 f0 70 12 28 26 12 28 25 34 15 44 &2073 25 18 10 28 00 10 46 18 12 38 16 28 22 f0 40 36 &2083 38 10 25 38 14 15 18 20 58 00 20 12 28 12 26 28 &2093 16 18 26 28 12 f0 70 12 18 26 28 13 15 78 16 00 &20a3 26 28 12 10 18 20 26 58 16 f0 80 16 28 16 12 48 &20b3 36 00 40 36 60 26 f0 e0 16 00 00 ; room sprite &23, &25 data, single colour &20be fd 37 f3 e3 37 ff 7d fb 6f bb ff 7f df ff 77 fd &20ce 7f 4e ff 97 fd bf c1 ff 2b fc 74 d1 fb 1e 6d 9f &20de f2 ff 35 bf d0 f3 3f 3f ff fb db bf 3f fd df db &20ee 2f ad cd df d1 fc aa fd ef ff ff fe ff ef ff ff &20fe fe ff ef da ff 17 f4 3e f2 7f a3 fc 73 db bf bc &210e fd e7 df 7f fd fc de cf df 5d fd df dc ff ea fd &211e af db ff b6 fc 6f df ff be fd ef f7 fe 7d df df &212e 0e ff ad fd ef c9 ff be ; creature sprite &06, &0a data - DISAPPEARING frame 1 and 5 &2136 00 00 00 2c d0 33 7d db bf fc df fa 7d bf f7 0f &2146 de d2 3d ca f4 39 ff f7 bf df ff bd 8b 1f b4 01 &2156 01 ; creature sprite &07, &09 data - DISAPPEARING frames 2 and 4 &2157 00 00 90 08 f0 0d f4 2f f4 3b f0 3f 90 3f f4 2f &2167 fc 1c bd b4 2d b0 3d b0 bc b4 b4 bc b0 3c b4 34 &2177 3c 28 6d 2d fd 2f fc 3f fc 3f f4 2d 70 0c ; creature sprite &08 data - DISAPPEARING frame 3 &2185 30 09 b4 0f fc 2b fc 2f f5 3f bd 3f 3f 35 0f 20 &2195 2f b0 2d f4 24 f4 2d f4 0f d0 0b f4 0f b4 25 24 &21a5 2c 30 2d b4 1d be 7c be d4 37 f0 0f f0 2d 90 2d ; creature sprite &05 data - DISAPPEARING frame 0 &21b5 00 00 00 00 00 00 00 00 0c d0 42 3d 7c c3 0a ac &21c5 42 3d d0 4b be 7c 8b 17 3c 42 39 70 02 20 ; creature sprite &04 data - APPEARING frame 4 &21d3 80 00 80 00 80 00 88 00 cc 10 4c b0 64 34 64 2f &21e3 70 0d 7b 2a 93 22 9c 22 ec 04 c4 06 c0 04 80 04 &21f3 80 0c 80 08 80 00 ; creature sprite &03 data - APPEARING frame 3 &21f9 80 00 80 00 80 80 c0 c0 40 90 49 90 4d 32 09 32 &2209 0e 26 07 26 a4 1c e0 1e 70 19 50 11 90 1c 80 14 &2219 c0 11 40 11 00 11 00 11 00 01 00 01 00 01 f0 f0 &2229 f0 f0 f0 f0 f0 ; room type &00 scenery data &222e 07 01 8d 01 cd 85 ed c9 ae 85 ce c9 8f 45 af 81 &223e 29 81 03 45 42 c9 22 85 61 c9 41 85 00 ; room type &01 scenery data &224b 07 01 41 85 61 c9 d0 86 e4 c5 0a 03 8d 00 ad c8 &225b 0e c0 4e 8b ee c8 6f 0b 2c 83 0c 46 29 81 66 c4 &226b 82 09 42 c5 4a 84 00 ; room type &02 scenery data &2272 8d 00 ad c0 ed 80 2e 48 ee 80 2f 40 6f 0b 07 0d &2282 87 0e 08 06 28 46 48 8d a8 86 e8 0e 01 14 41 93 &2292 e1 95 42 db 82 93 23 94 00 ; room type &03 scenery data &229b 8d 00 ad c8 2e 0b ce 07 4f 08 af 08 07 0e a7 06 &22ab c7 8d 28 8e c8 8d 29 86 49 c6 01 13 a1 13 42 13 &22bb e2 13 00 ; room type &04 scenery data &22be 8d 00 ad cb 4e c0 ee 47 6f 0b 2c 83 29 81 86 45 &22ce 23 0c e2 04 a2 44 42 d0 c1 0f a1 8c 01 09 07 0d &22de 67 02 6a 03 00 ; room type &05 scenery data &22e3 8d 0b 2e 07 ee 4b 8f 47 e8 0e a8 c6 08 ce 0b 4c &22f3 aa c3 6a 43 07 06 27 46 47 86 67 c1 c7 41 01 04 &2303 21 c4 43 c5 23 04 e2 c5 a2 50 42 d0 02 cc 85 cc &2313 00 ; room type &06 scenery data &2314 41 85 81 0f e1 84 87 8e 28 86 48 c1 a8 41 e8 cd &2324 49 c6 66 c4 e2 d0 43 44 07 01 0a 03 8d 0b 2e 07 &2334 ee 4a 8f 47 00 ; room type &07 scenery data &2339 8d 07 ed ca 8e c0 ce 87 4f 80 8f 47 49 c6 29 86 &2349 88 8e 68 46 c7 c1 a7 86 47 8d 27 46 07 06 01 04 &2359 41 0f a1 85 05 50 42 cf c2 50 23 04 43 c5 00 ; room type &08 scenery data &2368 8d 00 ad cb 4e 80 ee 4a 8f 47 07 06 27 4d 87 46 &2378 a7 ce 48 c1 a8 4d 09 46 29 86 49 c6 43 c5 a2 49 &2388 26 50 c1 0f a1 8c 01 09 00 ; room type &09 scenery data &2391 8d 0a 2e 07 ee 47 6f 0a 29 81 86 45 e2 84 a2 10 &23a1 e1 89 81 0f c4 84 41 85 07 01 00 ; room type &0a scenery data &23ac 8d 0b ed c0 2e 8b ae 80 ee 4a 8f 47 29 0d c8 41 &23bc 68 4d 08 06 67 0e 07 0d 01 05 21 8f a1 04 c1 d0 &23cc 42 cf 23 04 43 c5 e5 45 06 84 00 ; room type &0b scenery data &23d7 8d 07 ed ca ee 47 6f 0b 29 0d a8 86 08 8e a7 8d &23e7 67 01 07 0d 01 04 21 c5 25 cf a5 44 e5 05 a1 84 &23f7 e1 8f 62 10 a2 c4 e2 90 43 44 00 ; room type &0c scenery data &2402 01 09 a1 c4 e1 84 42 c9 03 45 23 85 43 c5 07 0d &2412 67 06 e8 0e 8d 07 ed cb ee 4b 8f 47 00 ; room type &0d scenery data &241f 01 10 41 c4 81 c9 42 8f c2 0f 23 90 07 06 27 46 &242f 47 8d a7 8e 48 8e e8 86 29 0d 8d 0b 2e 00 4e c7 &243f ce 87 4f 47 cf 40 00 ; room type &0e scenery data &2446 01 09 a1 84 e1 89 a2 45 c2 84 03 45 66 c4 07 0e &2456 e7 06 08 46 28 8d 88 86 29 81 0c 46 2c 83 8d 08 &2466 ed 4b 8e 48 ee 40 2f 48 8f 47 00 ; ro6m type &0f scenery data &2471 41 90 a1 04 c1 d0 42 c5 82 4f e2 cc 03 45 c4 85 &2481 46 84 91 46 07 01 e7 02 29 81 0a 03 4a 85 eb c4 &2491 2c 83 8d 00 ad cb 4e c7 ce 87 4f 47 cf 40 00 ; room type &10 scenery data &24a0 01 04 41 0f a1 85 c1 d0 22 49 07 0d 67 06 87 4d &24b0 e7 46 48 ce c5 cf 46 44 86 05 23 90 e2 10 e8 c6 &24c0 29 0d 8f 47 ee 4a 2e 07 8d 0b 00 ; room type &11 scenery data &24cb 01 09 a1 8c c1 0f 42 c9 03 84 43 44 07 06 27 8e &24db c7 8d 28 8e c8 86 e8 cd 49 c6 8d 11 2e 11 ce 11 &24eb 6f 11 00 ; room type &12 scenery data &24ee 01 09 a1 cf 22 50 82 09 23 90 07 0e a7 02 48 ce &24fe e8 cd 49 c6 8d 11 2e 11 ce 11 6f 11 00 ; room type &13 scenery data &250b 8d 00 ad c0 ed 8b ee 80 2f 40 6f 0b 0c 45 2c 83 &251b 29 81 91 46 66 05 e2 c4 c2 04 82 c5 62 04 02 05 &252b 41 89 c4 84 07 01 0a 03 4a 85 08 52 00 ; room type &14 scenery data &2538 01 0f 61 4f c1 cc e7 41 c5 0f 22 c4 62 c9 23 90 &2548 07 06 27 4d 87 4d 48 0e e8 0e 8d 11 2e 11 ce 11 &2558 6f 11 00 ; room type &15 scenery data &255b 01 04 21 d0 81 4f 02 05 42 d0 a2 4f 23 04 43 c5 &256b 86 4f e8 c6 29 0d 2c 83 6f 0b ee 07 ed ca 8d 07 &257b 07 0d 67 0e 08 02 85 05 c4 89 00 ; room type &16 scenery data &2586 41 85 61 c9 22 84 62 49 23 04 43 c5 07 01 c4 84 &2596 0a 03 4a 85 8d 07 0e 08 6e 00 8e c8 0f 0b af 08 &25a6 49 c6 68 ce 48 86 e7 8d c7 46 00 ; room type &17 scenery data &25b1 01 09 a1 85 c1 c5 02 05 42 c4 e4 4f 07 0d 67 06 &25c1 87 46 a7 8e 48 8d 8d 11 2e 11 ce 11 6f 11 82 85 &25d1 a2 c4 eb d7 71 d7 00 ; room type &18 scenery data &25d8 01 0f 61 90 42 50 82 c4 c2 85 c4 8f 07 06 27 4e &25e8 c7 41 08 cd 68 c6 8d 08 ed 0a ce cb 6f d7 eb d7 &25f8 71 d7 00 ; room type &19 scenery data &25fb 81 44 c1 49 62 c5 c2 89 49 c6 68 ce c7 ce a7 86 &260b 87 46 2e 11 ce 11 6f 11 8d 11 0a 16 90 16 00 ; room type &1a scenery data &261a 81 4c 81 cf c7 8d 28 81 88 01 c8 ce 46 cf c6 85 &262a 43 c5 23 04 c2 90 6f 0a ae 48 0e 4b 8d 16 0a 16 &263a 90 16 00 ; room type &1b scenery data &263d 81 4f 25 84 87 4d 8a c3 0e 48 ce 0a 6f 0b 49 c6 &264d 29 86 e8 01 a8 c6 88 86 28 8d a5 84 e5 8f 23 90 &265d a2 c5 62 c4 22 10 8d 16 0a 16 90 16 00 ; room type &1c scenery data &266a 81 4f 22 04 42 cf c2 05 e2 45 03 cf e8 0e 88 0d &267a c7 82 0e 48 ce 48 2f 4b cf 40 8d 16 0a 16 90 16 &268a 00 ; room type &1d scenery data &268b 01 09 a1 8c c1 0f 42 d0 a2 84 e2 44 23 0c 29 81 &269b 86 45 2c 83 6f 0b ee 47 4e c0 ad cb 8d 00 07 0d &26ab 00 ; room type &1e scenery data &26ac 81 84 c1 44 22 8f a2 04 c2 cf 43 44 e8 0e a8 86 &26bc 88 46 28 4d 87 4e 8d 16 0a 16 90 16 0e 48 ce 40 &26cc 0f 0a af 08 00 ; room type &1f scenery data &26d1 8d 07 ed cb ee 4a 8f 47 49 c6 a8 ce 88 46 28 4d &26e1 87 4e 27 4d 07 06 01 18 a1 18 42 18 e2 18 00 ; room type &20 scenery data &26f0 8d 0b 2e 07 8e c0 ce 87 4f 87 cf 40 49 c6 a8 ce &2700 48 cd 28 46 08 06 67 0e 07 0d 01 18 a1 18 42 18 &2710 e2 18 00 ; room type &21 scenery data &2713 a1 18 42 18 e2 18 a1 18 8d 16 0a 16 90 16 49 c6 &2723 e8 cd 48 ce e7 cd c7 86 cf 40 2f 0b ae c8 0e cb &2733 00 ; room type &23 scenery data &2734 07 0e a7 06 c7 46 88 0d e8 0e 8f 47 ee 4a ed ca &2744 8d 07 01 18 a1 18 42 18 e2 18 00 ; room type &24 scenery data &274f 41 93 e1 93 82 93 a7 c3 88 03 08 5f 01 22 15 23 &275f 0a 23 8c 1d 8d 1c cc 9e cd 9c 2e 21 ce e0 6f 1c &276f 74 1e af 9c b4 9d 23 a4 36 a5 2c a5 00 ; room type &25 scenery data &277c 01 10 41 85 61 c9 42 c9 03 84 43 44 29 0d 88 0e &278c a7 0e 07 0d 8d 1c cd 9c 2e 1c 6e 9c ce 1c 0f 9c &279c 6f 1c af 9c 8c 1e cc 9e 33 1e 73 9e d3 1e 14 9e &27ac 74 1e b4 9e 00 ; room type &26 scenery data &27b1 41 93 e1 95 42 db 82 93 01 22 15 23 0a 23 8d 1c &27c1 cd 9c 2e 1c 6e 9c ce 1c 0f 9c 6f 1c af 9c 8c 1d &27d1 cc 9e 33 1e 73 9e d3 1e 14 9e 74 1e b4 9d 23 a4 &27e1 36 a5 2c a5 00 ; room type &27 scenery data &27e6 8c 1d 8d 1c cc 9e cd 9c 2e 21 ce e0 6f 1c 74 1e &27f6 af 9c b4 9d 01 10 07 06 27 46 47 81 a1 05 c1 44 &2806 02 05 42 cf c2 0c c8 81 29 0d 23 05 43 44 28 4d &2816 08 06 c7 c6 00 ; room type &28 scenery data &281b 8d 0b 2e 07 ee 47 6f 0b 09 cd e8 86 48 8e a7 8e &282b 47 8d 27 46 07 06 01 10 41 84 81 49 22 cf a2 05 &283b c2 4f 23 90 00 ; room type &29 scenery data &2840 8d 0b 2e 4b ce 8b 6f d7 eb d7 71 d7 a2 84 82 45 &2850 42 84 42 0c 02 0c 01 09 07 06 27 4d 87 46 a7 81 &2860 08 0d 68 06 88 46 00 ; room type &2a scenery data &2867 8d 08 ed 00 0e c8 ce ca 6f d7 eb d7 71 d7 a8 41 &2877 48 c1 01 0f 61 90 c1 44 02 10 07 06 27 4e c7 46 &2887 e7 86 00 ; room type &2b scenery data &288a 8d 08 ed 00 0e c8 ce cb 6f d7 eb d7 71 d7 01 18 &289a a1 18 42 18 07 06 27 4e 08 8d 68 86 88 cd 00 ; room type &2c scenery data &2aa9 8d 08 ed 4a 8e 48 ee 4b 8f 47 e8 0e 88 0d a7 0e &28b9 07 0e 06 04 26 d0 01 18 a1 18 42 18 e2 18 00 ; room type &2d scenery data &28c8 01 04 21 c5 61 0c 61 8f e1 04 42 4c a2 44 6f d7 &28d8 eb d7 71 d7 ce ca 48 c1 a8 46 c8 86 e7 46 87 4d &28e8 67 06 07 0d 8d 0b 2e 08 00 ; room type &2e scenery data &28f1 8d 16 0a 16 90 16 81 4f e1 85 02 c5 42 04 62 d0 &2901 c2 4f 23 90 29 0d c8 0d 28 0e 6f 0b ae ca 0e 48 &2911 87 46 a7 86 05 50 00 ; unused &2918 00 00 00 00 00 00 ; room_scenery_address_table &291e 2e 22 4b 22 72 22 9b 22 be 22 e3 22 14 23 39 23 &292e 68 23 91 23 ac 23 d7 23 02 24 1f 24 46 24 71 24 &293e a0 24 cb 24 ee 24 0b 25 38 25 5b 25 86 25 b1 25 &294e d8 25 fb 25 1a 26 3d 26 6a 26 8b 26 ac 26 d1 26 &295e f0 26 13 27 34 27 4f 27 7c 27 b1 27 e6 27 1b 28 &296e 40 28 67 28 8a 28 a9 28 c8 28 f1 28 ; room_data_table ; byte & &3f = room type ; byte & &40 set if object collected ; bute & &80 set if room visited &297a 21 20 20 1f 22 20 20 22 20 1f 2b 20 1f 20 22 2a &298a 2d 10 0b 0a 05 0e 16 08 0b 08 0b 10 05 0d 0c 28 &299a 1b 06 06 16 0c 0e 09 15 06 05 08 15 15 09 05 29 &29aa 1b 15 05 0e 13 09 06 07 0a 0f 05 0c 0c 1d 05 28 &29ba 1c 0a 06 09 01 15 06 16 0d 0d 0a 15 06 01 05 29 &29ca 1c 10 13 05 0d 0a 05 0e 09 09 16 08 15 16 0c 28 &29da 1c 08 05 0c 0d 0e 05 27 0c 05 0e 06 05 0d 08 29 &29ea 1b 05 08 01 09 16 0c 26 24 26 0e 05 08 16 08 2c &29fa 1e 0c 0c 0d 1d 09 06 25 23 25 09 06 07 0d 0a 18 &2a0a 1b 13 15 0b 0c 08 05 03 02 03 04 05 0e 09 0b 28 &2a1a 1b 07 0a 0f 06 15 06 09 01 09 05 08 09 06 07 29 &2a2a 1e 10 0b 0d 0a 01 07 08 0b 0a 06 0c 08 0c 0d 2c &2a3a 1c 0c 1d 09 0b 0d 10 05 0a 16 08 01 15 15 0b 2c &2a4a 1b 15 13 13 07 10 07 0c 0d 0e 05 0d 0a 06 15 18 &2a5a 1a 01 0f 06 09 07 10 0f 0b 10 06 0b 0d 0a 06 18 &2a6a 19 12 14 11 11 12 11 12 11 11 11 11 12 12 11 17 ; room_sprites_screen_address_table + 1 &2a7a 4e 4f 50 55 56 57 62 63 64 6c 6d 6e 7d 7e 7f 5a &2a8a 5c 5e 6f 70 5d 5f ; room_types_in_which_hippos_can_appear &2a90 01 02 03 04 09 0c 0d 0e 0f 11 12 13 1c 1d 19 16 &2aa0 20 21 23 24 25 26 27 2a 08 0a 10 29 2c 05 07 0b ; unused &2ab0 38 38 18 ; alternate_zero_page_routine ; plot_column_of_rle_sprite_data_to_screen # For plotting a column of scenery sprite ; sprite_data_loop &2ab3 &0000 b9 ff ff LDA &ffff,Y # actually LDA (&01),Y ; sprite_data_address # Get a byte of RLE sprite data &2ab6 &0003 c8 INY &2ab7 &0004 d0 02 BNE &0008 ; not_page_boundary &2ab9 &0006 e6 02 INC &02 ; sprite_data_address_high ; not_page_boundary &2abb &0008 aa TAX &2abc &0009 f0 49 BEQ &0054 ; plot_padding_at_end # A zero byte marks end of the data, start of padding &2abe &000b 48 PHA &2abf &000c 29 00 AND #&00 # actually AND bits_for_twopixel_data # either &f0 or &e0 &2ac1 &000e aa TAX &2ac2 &000f bd 80 01 LDA &0180,X ; scenery_twopixel_table # The top bits are the pointer for the twopixel table &2ac5 &0012 aa TAX ; unchanged_instructions &2ac6 bd 00 01 LDA &0100,X ; twopixel_reverse_table # See &3e1c; # actually TXA # &13 and &14 are overwritten with fixed values # actually LDX #&01 # suggesting this routine once had flipping capabilities &2ac9 &0016 49 ff EOR #&ff &2acb &0018 85 29 STA &29 ; twopixel_value &2acd &001a 68 PLA &2ace &001b 29 f0 AND #&00 # The bottom bits are the number of rows to plot # actually AND bits_for_row_count # either &0f or &1f ; shift_instructions &2ad0 &001d ea NOP # actually LSR A # or ASL A &2ad1 &001e ea NOP # actually LSR A # or ROL A &2ad2 &001f ea NOP # actually LSR A # or ROL A &2ad3 &0020 ea NOP # actually LSR A # or ROL A &2ad4 &0021 85 e2 STA &e2 ; rows_to_plot &2ad6 &0023 18 CLC &2ad7 &0024 65 e1 ADC &e1 ; rows_plotted &2ad9 &0026 85 e1 STA &e1 ; rows_plotted ; row_loop &2adb &0028 a9 ff LDA #&00 # actually LDA &29 ; twopixel_value &2add &002a 8d ff ff STA &ffff # actually STA (&2b) ; screen_address # Push the pixels to the screen &2ae0 &002d a5 2b LDA &2b ; screen_address_low &2ae2 &002f 29 07 AND #&07 &2ae4 &0031 f0 08 BEQ &003b ; change_group_of_rows # Move up a row, or group of rows as required &2ae6 &0033 c6 2b DEC &2b ; screen_address_low ; continue_after_heading_up_a_row &2ae8 &0035 c6 e2 DEC &e2 ; rows_to_plot &2aea &0037 d0 ef BNE &0028 ; row_loop ; end_of_run_branch_pointer # See &3e35 and &0063; &2aec &0039 f0 19 BEQ &0054 ; plot_padding_at_end # never branches to plot_padding_at_end # actually f0 2c BEQ &0067 ; leave # Unless plotting padding, # or f0 c5 BEQ &0000 ; sprite_data_loop # start the process again with the next RLE byte ; change_group_of_rows &2aee &003b a5 2b LDA &2b ; screen_address_low &2af0 &003d a6 2c LDX &2c ; screen_address_high &2af2 &003f ca DEX &2af3 &0040 ca DEX &2af4 &0041 38 SEC &2af5 &0042 e9 79 SBC #&79 &2af7 &0044 85 2b STA &2b ; screen_address_low &2af9 &0046 b0 01 BCS &0049 &2afb &0048 ca DEX &2afc &0049 e0 49 CPX #&49 &2afe &004b b0 02 BCS &004f ; still_in_screen_memory &2b00 &004d a2 c0 LDX #&c0 # Change to somewhere safe if above the top of screen ; still_in_screen_memory &2b02 &004f 86 2c STX &2c ; screen_address_high &2b04 &0051 4c 35 00 JMP &0035 ; continue_after_heading_up_a_row ; plot_padding_at_end &2b07 &0054 a9 00 LDA #&00 # After a zero byte of RLE data, # actually LDA &55 ; room_sprite_top_height # a final round to plot padding at the top &2b09 &0056 38 SEC &2b0a &0057 e5 e1 SBC &e1 ; rows_plotted &2b0c &0059 f0 0c BEQ &0067 ; leave &2b0e &005b 85 e2 STA &e2 ; rows_to_plot &2b10 &005d a9 ff LDA #&ff # of impenetrable black &2b12 &005f 85 29 STA &29 ; twopixel_value &2b14 &0061 a9 2c LDA #&2c &2b16 &0063 85 3a STA &3a ; end_of_run_branch_pointer &2b18 &0065 d0 c1 BNE &0028 ; inner_loop &2b1a &0067 60 RTS ; player sprites RLE data &2b1b 00 ; extra row for top half of FIGHTING frame 0 &2b1c 10 00 10 00 10 00 10 00 10 22 20 14 1e 00 29 12 ; top half of WALKING frames 0-4 and FIGHTING frames 1, 2 and 4 &2b2c 18 14 1e 10 1c 14 00 29 18 14 1c 2e 14 1e 00 18 &2b3c 14 1e 44 1c 00 10 1c 00 00 ; &2b45 00 10 00 10 00 10 00 10 00 1e 14 20 23 1b 10 3b ; bottom half of WALKING frames 0 and 2 &2b55 13 00 3c 10 2b 00 50 1a 1b 1a 13 2b 1d 00 50 66 &2b65 17 16 00 00 ; &2b69 00 10 00 10 00 10 00 14 1e 1c 40 23 00 2c 10 1b ; bottom half of WALKING frame 1 &2b79 13 1b 10 3b 13 00 40 1a 1b 20 1a 00 1e 14 10 1b &2b89 1a 1b 1a 1b 10 13 1d 00 10 2c 10 66 17 16 00 00 ; &2b99 00 10 00 10 00 10 00 14 1e 1c 00 2c 10 1b 13 1b ; bottom half of WALKING frame 3 &2ba9 20 2b 13 00 40 13 1b 1a 00 1e 14 10 1b 1a 1b 10 &2bb9 1b 23 1d 00 10 2c 10 66 17 16 00 00 ; &2bc5 00 10 00 10 00 10 00 13 30 24 00 1b 1a 14 1e 1c ; top half of UP frames 0-3 &2bd5 14 3c 14 00 1b 10 2e 10 4e 14 1e 00 1b 13 1c 1e &2be5 14 1c 3e 1c 00 1a 30 2c 00 00 ; &2bef 00 10 00 10 00 10 00 14 50 43 00 2e 10 1b 23 10 ; bottom half of UP frames 0 and 2 &2bff 33 00 40 2b 10 3b 00 2e 10 1b 2a 10 3a 00 1c 50 &2c0f 4a 00 00 ; &2c12 00 10 00 10 00 10 00 90 13 00 14 30 23 10 13 2a ; bottom half of UP frames 1 and 3 (flipped) &2c22 00 2e 10 1a 2b 10 3b 00 10 24 10 1b 1a 23 2a 00 &2c32 20 2c 30 3a 00 00 ; &2c38 00 10 00 10 00 10 00 50 24 00 1a 12 29 18 10 1e ; top half of DOWN frames 0-3 &2c48 2c 14 00 10 49 10 3e 10 1e 00 13 18 29 12 10 1e &2c58 24 1c 00 50 2c 00 00 ; &2c5f 00 10 00 10 00 10 00 14 40 53 00 2e 10 1b 23 10 ; bottom half of DOWN frames 0 and 2 &2c6f 23 1b 00 40 2b 10 3b 00 2e 10 1b 2a 10 2a 1b 00 &2c7f 1c 40 5a 00 00 ; &2c84 00 10 00 10 00 10 00 80 23 00 1e 14 10 1b 13 10 ; bottom half of DOWN frames 1 and 3 (flipped) &2c94 13 1b 2a 00 2c 10 1a 13 2a 13 2b 00 10 2e 14 2a &2ca4 13 2a 1b 00 20 2c 30 3a 00 00 ; &2cae 00 10 00 10 00 2e 2c 00 33 00 7b 13 00 3b 00 10 ; bottom half of SITTING &2cbe 1a 1b 1a 13 2b 1d 00 10 66 17 16 00 00 ; &2ccb 00 10 00 10 00 10 00 40 41 17 11 30 44 00 20 16 ; bottom half of FLYING (no top half) &2cdb 1d 1b 3a 16 1b 10 1c 1f 1c 34 2e 14 00 20 3a 10 &2ceb 1a 10 2a 18 39 12 1c 1e 10 14 1e 00 20 1b 1a 3b &2cfb 15 1a 1b 15 10 39 18 12 1c 1e 14 00 10 24 40 2b &2d0b 15 1a 30 28 00 1c 2e 14 00 00 ; &2d15 00 a0 17 00 a0 17 00 90 36 00 90 15 1a 00 14 80 ; bottom half of FIGHTING frame 0 &2d25 1b 15 00 1e 14 1e 10 1a 15 10 25 2a 00 2c 10 1b &2d35 2a 10 4a 00 24 10 1b 1a 1b 10 2b 2a 00 1e 2c 30 &2d45 15 2a 15 1b 00 00 ; &2d4b 30 11 00 30 17 00 40 17 21 00 30 26 35 00 1e 24 ; bottom half of FIGHTING frame 1 &2d5b 30 2b 1a 1b 15 00 2c 20 1a 15 10 25 2a 00 14 20 &2d6b 1b 2a 10 4a 00 1e 1c 14 1b 1a 1b 10 2b 2a 00 70 &2d7b 15 1a 15 1b 00 90 2b 00 00 ; &2d84 11 00 10 16 11 00 30 16 21 00 40 16 1b 2a 25 00 ; bottom half of FIGHTING frame 2 &2d94 14 30 15 30 1b 15 1a 00 2e 1c 15 2a 10 4a 00 24 &2da4 10 15 2a 10 4a 00 1e 2c 10 1b 30 15 1b 1a 00 60 &2db4 15 2a 1b 00 00 ; &2db9 00 10 00 d0 11 00 90 25 1a 10 17 66 00 14 70 1a ; bottom half of FIGHTING frame 3 &2dc9 1b 15 00 2e 1c 10 15 20 25 2a 00 30 15 2a 10 4a &2dd9 00 24 10 15 2a 10 2b 2a 00 1e 2c 10 1b 10 25 1a &2de9 15 1b 00 70 2b 00 00 ; &2df0 00 10 00 60 11 10 15 00 30 31 16 11 1b 1a 15 00 ; bottom half of FIGHTING frame 4 &2e00 36 60 1b 15 00 1e 14 1e 10 1a 15 10 25 2a 00 2c &2e10 10 1b 2a 10 4a 00 2e 14 1b 1a 1b 10 2b 2a 00 1c &2e20 70 1a 15 1b 00 90 1b 1a 15 00 00 ; &2e2b f0 20 21 00 b0 11 10 21 26 00 a0 25 16 11 00 80 ; bottom half of FIGHTING frame 5 &2e3b 2a 1b 00 1e 24 10 15 30 1b 15 1a 00 2c 10 15 2a &2e4b 10 4a 00 24 10 15 2a 10 4a 00 1e 2c 10 1b 10 25 &2e5b 10 1b 1a 00 70 1b 2a 00 00 ; &2e64 00 ; extra row for top half of FIGHTING frame 3 &2e65 10 00 10 00 10 00 60 14 00 12 19 18 12 10 1e 1c ; top half of FIGHTING frame 5 &2e75 14 00 39 10 2e 14 10 1e 00 19 18 14 1c 10 2c 1e &2e85 1c 00 10 1e 5c 00 00 ; &2e8c 00 10 00 10 00 14 3e 1c 00 10 25 2a 3b 1a 15 00 ; bottom half of DEAD (no top half) &2e9c 10 25 2b 20 35 00 20 3b 30 1b 00 10 24 28 59 22 &2eac 00 20 1e 1c 1e 34 23 44 00 20 1c 1e 34 1e 14 1e &2ebc 1c 00 00 ; title_music &2ebf 56 66 72 86 96 &2ec4 5e 6a 7a 8e 9a &2ec9 52 5e 72 82 8e &2ece 56 66 72 86 96 &2ed3 56 66 7a 96 aa &2ed8 56 5e 6e 7a 8e &2edd 5e 72 82 8e a2 &2ee2 52 56 66 72 86 &2ee7 4a 56 66 7a 86 &2eec 3e 56 66 7a 86 &2ef1 42 52 5e 6a 72 &2ef6 56 66 72 86 96 ; creature sprite &02 data - APPEARING frame 2 &2efb 40 80 c0 92 40 92 40 13 08 33 0d 32 0c 24 2e 24 &2f0b 27 06 75 0e 71 0e b1 0b 99 0b d8 25 c8 35 c8 b2 &2f1b 4c d0 84 80 84 00 84 00 80 00 80 00 80 00 ; creature sprite &01 data - APPEARING frame 1 &2f29 40 02 40 03 00 0b 14 21 14 20 14 20 14 20 18 20 &2f39 18 20 18 20 11 23 11 2b 11 28 12 a2 12 a2 12 22 &2f49 12 02 00 01 00 01 00 01 00 08 00 08 ; creature sprite &00 data - APPEARING frame 0 &2f55 90 01 d0 02 44 0b 24 09 84 00 cc 24 9c e4 9c 74 &2f65 39 94 a9 94 a9 d4 87 ec c3 cc 43 4d 42 09 40 09 &2f75 40 02 00 02 00 02 00 02 ; creature sprite &16 data - MOSQUITO frame 1 &2f7d 00 88 80 18 1f 76 c5 a6 8d 9a a9 3f 79 42 08 6a &2f8d f2 11 a5 c8 44 00 06 d0 ; creature sprite &15 data - MOSQUITO frame 0 &2f95 00 44 c0 18 8f f6 c5 a4 b9 5a a8 8a 39 41 22 6a &2fa5 f0 09 25 c0 00 ; creature sprite &1a data - FLEA frame 1 &2faa 40 00 06 a0 40 08 14 8b b5 78 8b 39 58 83 27 c5 &2fba 92 0f bd 80 0b 38 40 02 ; creature sprite &19 data - FLEA frame 0 &2fc2 14 4b bc e8 8b 31 e8 83 2e d5 92 0f bd 80 0b 38 &2fd2 40 02 ; ensure_player_isn't_in_scenery &2fd4 84 c5 STY &c5 ; player_x_for_check &2fd6 a0 00 LDY #&00 &2fd8 84 e1 STY &e1 ; height ; check_loop &2fda 85 d6 STA &d6 ; screen_address_low &2fdc 86 d7 STX &d7 ; screen_address_high &2fde a0 20 LDY #&20 ; width &2fe0 20 19 30 JSR &3019 ; check_for_scenery_in_single_row # Is the player in scenery? &2fe3 f0 2d BEQ &3012 ; no_scenery # If not, leave ; consider_left_edge &2fe5 a5 d6 LDA &d6 ; screen_address_low &2fe7 a6 d7 LDX &d7 ; screen_address_high &2fe9 c0 00 CPY #&00 # Is there scenery on the left edge of the player? &2feb f0 09 BEQ &2ff6 ; scenery_on_left_edge &2fed a0 08 LDY #&08 # If not, move left two pixels &2fef 20 23 47 JSR &4723 ; subtract_y_from_a_and_x &2ff2 c6 c5 DEC &c5 ; player_x_for_check &2ff4 d0 e4 BNE &2fda ; check_loop # and check again ; scenery_on_left_edge &2ff6 a0 28 LDY #&28 &2ff8 20 1a 47 JSR &471a ; add_y_to_a_and_x &2ffb a0 00 LDY #&00 &2ffd 20 19 30 JSR &3019 ; check_for_scenery_in_single_row &3000 f0 03 BEQ &3005 ; no_scenery_to_right # Is there scenery on the right edge of the player? &3002 c8 INY &3003 d0 e0 BNE &2fe5 ; consider_left_edge # If so, consider left edge again ; no_scenery_to_right &3005 a5 d6 LDA &d6 ; screen_address_low &3007 a6 d7 LDX &d7 ; screen_address_high &3009 a0 08 LDY #&08 # If not, move right two pixels &300b 20 1a 47 JSR &471a ; add_y_to_a_and_x &300e e6 c5 INC &c5 ; player_x_for_check &3010 d0 c8 BNE &2fda ; check_loop # and check again ; no_scenery &3012 a5 d6 LDA &d6 ; screen_address_low &3014 a6 d7 LDX &d7 ; screen_address_high &3016 a4 c5 LDY &c5 ; player_x_for_check # Leave with an x value outside of any scenery &3018 60 RTS ; check_for_scenery_in_single_row &3019 e6 e1 INC &e1 ; height ; check_for_scenery &301b 84 77 STY &77 ; width # Check a box (width, height) around screen_address ; check_for_scenery_row_loop &301d 85 78 STA &78 ; screen_address_low &301f 86 79 STX &79 ; screen_address_high &3021 a0 00 LDY #&00 ; check_for_scenery_column_loop &3023 b1 78 LDA (&78),Y ; screen_address # Read a byte of screen memory &3025 30 17 BMI &303e ; leave # Top bit set indicates presence of scenery &3027 c4 77 CPY &77 ; width &3029 f0 06 BEQ &3031 ; check_for_scenery_next_row &302b 98 TYA &302c 69 08 ADC #&08 # Move right two pixels &302e a8 TAY &302f d0 f2 BNE &3023 ; check_for_scenery_column_loop ; check_for_scenery_next_row &3031 a5 78 LDA &78 ; screen_address_low &3033 a6 79 LDX &79 ; screen_address_high &3035 a0 01 LDY #&01 &3037 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows # Move up one pixel &303a c6 e1 DEC &e1 ; height &303c d0 df BNE &301d ; check_for_scenery_row_loop &303e 60 RTS ; leave ; event_vector_routine &303f 08 PHP &3040 e6 8f INC &8f ; interrupt_ticker # Increment interrupt_ticker once every 50ms &3042 28 PLP &3043 60 RTS ; title_music_note_table &3044 01 02 03 04 03 02 01 00 04 03 02 04 03 02 01 00 ; play_sound_on_three_channels &3054 85 80 STA &80 ; sound_0_pitch &3056 a9 11 LDA #&11 &3058 85 7c STA &7c ; sound_0_channel &305a 20 6b 30 JSR &306b ; play_sound_at_7c &305d e6 7c INC &7c ; sound_0 &305f a5 80 LDA &80 ; sound_0_pitch &3061 38 SEC &3062 e9 30 SBC #&30 &3064 85 80 STA &80 ; sound_0_pitch &3066 20 6b 30 JSR &306b ; play_sound_at_7c &3069 e6 7c INC &7c ; sound_0_channel ; play_sound_at_7c &306b a0 00 LDY #&00 &306d a2 7c LDX #&7c ; sound_0 &306f 4c a4 32 JMP &32a4 ; play_sound_from_xy ; collection_music &3072 81 89 81 89 81 89 81 89 81 00 79 00 81 00 89 00 &3082 8d 00 95 00 8d 00 89 00 81 ; game_start_and_end_music &308b 92 00 7e 8a 92 00 7e 8a 92 9e 7e 9e 92 ; start &3098 7e a2 92 7a 9e 92 76 9a 8e 92 ; end ; play_game_over_music &30a2 a9 0a LDA #&0a &30a4 a0 0d LDY #&0d ; play_music &30a6 85 cc STA &cc ; number_of_notes &30a8 84 cd STY &cd ; offset_into_music &30aa 20 93 3b JSR &3b93 ; flush_buffers ; play_music_loop &30ad a4 cd LDY &cd ; offset_into_music &30af b9 8b 30 LDA &308b,Y ; game_start_and_end_music &30b2 f0 03 BEQ &30b7 ; rest &30b4 20 54 30 JSR &3054 ; play_sound_on_three_channels ; rest &30b7 a9 f9 LDA #&f9 # Wait 350ms between notes &30b9 20 13 47 JSR &4713 ; delay &30bc e6 cd INC &cd ; offset_into_music &30be c6 cc DEC &cc ; number_of_notes &30c0 d0 eb BNE &30ad ; play_music_loop &30c2 60 RTS ; increase_score &30c3 fe 1a 32 INC &321a,X ; score &30c6 bd 1a 32 LDA &321a,X ; score &30c9 c9 1a CMP #&1a &30cb d0 08 BNE &30d5 ; leave_noting_change &30cd a9 10 LDA #&10 &30cf 9d 1a 32 STA &321a,X ; score &30d2 ca DEX &30d3 10 ee BPL &30c3 ; increase_score ; leave_noting_change &30d5 e6 9e INC &9e ; numbers_have_changed &30d7 60 RTS ; plot_score_and_lives &30d8 a2 00 LDX #&00 &30da a0 02 LDY #&02 ; plot_text &30dc 86 38 STX &38 ; line_to_plot &30de 84 39 STY &39 ; maximum_line_to_plot &30e0 a9 a2 LDA #&a2 ; LDX # Overwrite rather than EOR with what's on screen &30e2 8d 84 40 STA &4084 ; plot_single_colour_sprite_eor_instruction &30e5 a9 47 LDA #&47 # &472c = increase_screen_address_by_y_rows &30e7 a0 2c LDY #&2c # so text is plotted from top to bottom &30e9 20 67 31 JSR &3167 ; set_plot_single_colour_sprite_move_function ; plot_text_line_loop &30ec a9 00 LDA #&00 &30ee a8 TAY &30ef e0 01 CPX #&01 &30f1 f0 04 BEQ &30f7 ; is_lives # For the life counter, use &0000 + &c0, lives_as_digit &30f3 a9 31 LDA #&31 &30f5 a0 d2 LDY #&d2 # Otherwise use &31d2, text_table + text_offset ; is_lives &30f7 85 e2 STA &e2 ; text_table_address_high &30f9 84 e1 STY &e1 ; text_table_address_low &30fb bd 6e 31 LDA &316e,X ; text_screen_address_high_table &30fe 85 eb STA &eb ; screen_address_high &3100 bd 82 31 LDA &3182,X ; text_screen_address_low_table &3103 85 e3 STA &e3 ; screen_address_low &3105 bd 96 31 LDA &3196,X ; text_length_table &3108 85 c5 STA &c5 ; characters_to_plot &310a bd aa 31 LDA &31aa,X ; text_offset_table &310d 85 15 STA &15 ; text_offset &310f bd be 31 LDA &31be,X ; text_colour_table &3112 20 b4 40 JSR &40b4 ; split_a_into_pixel_values &3115 a9 00 LDA #&00 &3117 8d 8d 40 STA &408d ; screen_end_column &311a a9 e9 LDA #&e9 ; SBC # Sprite is plotted right to left &311c 8d 91 40 STA &4091 ; plot_single_colour_sprite_move_instruction ; plot_text_character_loop &311f a4 15 LDY &15 ; text_offset &3121 b1 e1 LDA (&e1),Y ; text_table_address # Get a character &3123 8d 75 40 STA &4075 ; sprite_data_address_low &3126 a9 c0 LDA #&c0 # Use OS character font table at &c000 &3128 0e 75 40 ASL &4075 ; sprite_data_address_low &312b 0e 75 40 ASL &4075 ; sprite_data_address_low &312e 69 00 ADC #&00 &3130 0e 75 40 ASL &4075 ; sprite_data_address_low &3133 69 00 ADC #&00 &3135 8d 76 40 STA &4076 ; sprite_data_address_high &3138 a9 08 LDA #&08 &313a 85 70 STA &70 ; sprite_rows_to_plot &313c a9 18 LDA #&18 # 8 pixels wide; &18 = ((8/2)-1)*8 &313e a6 eb LDX &eb ; screen_address_high &3140 a4 e3 LDY &e3 ; screen_address_low &3142 20 66 40 JSR &4066 ; plot_single_colour_sprite # Plot character on screen &3145 a5 e3 LDA &e3 ; screen_address_low # Increase screen address by &20 (one character right) &3147 18 CLC &3148 69 20 ADC #&20 &314a 85 e3 STA &e3 ; screen_address_low &314c 90 02 BCC &3150 &314e e6 eb INC &eb ; screen_address_high &3150 e6 15 INC &15 ; text_offset &3152 c6 c5 DEC &c5 ; characters_to_plot &3154 d0 c9 BNE &311f ; plot_text_character_loop &3156 e6 38 INC &38 ; line_to_plot &3158 a6 38 LDX &38 ; line_to_plot &315a e4 39 CPX &39 ; maximum_line_to_plot &315c d0 8e BNE &30ec ; plot_text_line_loop &315e a9 51 LDA #&51 ; EOR # Restore EOR mode &3160 8d 84 40 STA &4084 ; plot_single_colour_sprite_eor_instruction &3163 a9 47 LDA #&47 # &4746 = reduce_screen_address_by_y_rows &3165 a0 46 LDY #&46 # and bottom to top sprite plotting ; set_plot_single_colour_sprite_move_function &3167 8d a9 40 STA &40a9 ; plot_single_colour_sprite_move_function_high &316a 8c a8 40 STY &40a8 ; plot_single_colour_sprite_move_function_low &316d 60 RTS ; text_screen_address_high_table &316e 7b 7d 53 5a 5f 64 69 90 71 74 5d 62 68 53 58 5d &317e 62 69 6e 74 ; text_screen_address_low_table &3182 11 51 80 e0 e0 e0 e0 00 80 40 a8 08 08 50 60 90 &3192 e0 d0 f0 90 ; text_length_table &3196 06 01 0c 0e 0e 0e 0e 0e 0c 08 09 13 03 0f 0e 0b &31a6 06 0f 0d 03 ; text_offset_table &31aa 48 c0 00 0c 1a 28 36 44 52 5f 67 70 83 86 95 a3 &31ba ae b4 c3 d0 ; text_colour_table ; WW WW WW WW YY CC MM WW GG GG MM CC WW CC CC CC &31be 3f 3f 3f 3f 0f 3c 33 3f 0c 0c 33 3c 3f 3c 3c 3c ; CC MM MM WW &31ce 3c 33 33 3f ; text_table &31d2 48 61 6c 6c 00 6f 66 00 46 61 6d 65 ; line &02 "Hall of Fame" &31de 11 73 74 00 11 19 12 17 15 10 00 50 0e 50 ; line &03 "1st 192750 P.P" &31ec 12 6e 64 00 10 16 14 18 11 10 00 55 4c 54 ; line &04 "2nd 064810 ULT" &31fa 13 72 64 00 10 11 12 17 16 10 00 4d 0e 47 ; line &05 "3rd 012760 M.G" &3208 14 74 68 00 10 10 15 11 19 10 00 41 47 46 ; line &06 "4th 005190 AGF" &3216 35 54 48 00 ; line &07 "5TH 000000 " (never actually plotted) ; score &321a 10 10 10 10 10 10 ; line &00 "000000" &3220 00 00 00 00 ; " " &3224 50 72 65 73 73 00 52 45 54 55 52 4e 00 ; text &08 "Press RETURN" &3231 74 6f 00 53 54 41 52 54 ; text &09 "to START" &3239 47 61 6d 65 00 4f 76 65 72 ; text &0a "Game Over" &3242 41 64 76 65 6e 74 75 72 65 00 43 6f 6d 70 6c 65 74 65 64 ; text &0b "Adventure Completed" ; percentage_complete &3255 10 10 05 ; text &0c "00%" &3258 43 6f 6e 67 72 61 74 75 6c 61 74 69 6f 6e 73 ; text &0d "Congratulations" &3267 59 6f 75 00 61 72 65 00 74 6f 64 61 79 73 ; text &0e "You are todays" &3275 51 51 51 00 68 69 67 68 65 73 74 ; text &0f "QQQ highest" &3280 73 63 6f 72 65 72 ; text &10 "scorer" &3286 50 6c 65 61 73 65 00 72 65 67 69 73 74 65 72 ; text &11 "Please register" &3295 79 6f 75 72 00 69 6e 69 74 69 61 6c 73 ; text &12 "your initials" ; text &13 gets pointed to initials in the Hall of Fame ; play_sound_from_second_table &32a2 a0 09 LDY #&09 ; play_sound_from_xy #32a4 2c BIT #&01a0 ; play_sound_from_first_table &32a5 a0 01 LDY #&01 &32a7 a9 07 LDA #&07 ; Generate a sound (SOUND) &32a9 6c 0c 02 JMP (&020c) ; OSWORD ; creature_screen_address_high &32ac 30 31 32 33 55 55 69 69 6d 55 69 55 ; creature_screen_address_low &32b8 30 31 32 33 87 87 87 87 2e 87 87 87 ; creature_x &32c4 30 31 32 33 b0 b0 b0 b0 d5 b0 b0 b0 ; creature_y &32d0 30 31 32 33 2f 2f 6f 6f 76 2f 6f 2f ; creature_sprite &32dc ff ff ff ff 1b 1b 1b 1b 28 1f 23 23 ; creature_frame &32e8 30 31 32 33 00 00 00 00 00 00 00 00 ; creature_direction &32f4 30 31 32 33 01 01 01 01 01 01 01 01 ; creature_colour &3300 00 00 00 03 33 33 33 33 3c 3c 0f 0f ; creature_room &330c 30 31 32 33 00 97 99 f0 88 f6 98 98 ; creature_species &3318 00 00 00 ; creature_movement_duration &331b 00 00 00 00 ff ff ff ff ff ff ff ff ; creature_attacked &3327 ff ff ff ff ff ff ff ff ff ff ff ff ; creature_movement &3333 30 31 32 33 ; increase_score_by_one_hundred_and_tens &3337 a2 03 LDX #&03 ; hundreds &3339 20 c3 30 JSR &30c3 ; increase_score # Increase score by between one hundred &333c 00 BRK ; random_number &333d 29 07 AND #&07 # and one hundred and seventy, in units of ten &333f a8 TAY &3340 c8 INY ; tens_loop &3341 a2 04 LDX #&04 ; tens &3343 20 c3 30 JSR &30c3 ; increase_score &3346 88 DEY &3347 d0 f8 BNE &3341 ; tens_loop &3349 60 RTS ; remove_creature_if_frame_negative &334a bd e8 32 LDA &32e8,X ; creature_frame &334d 10 03 BPL &3352 ; leave &334f 9d dc 32 STA &32dc,X ; creature_sprite &3352 60 RTS ; remove_fire &3353 a9 19 LDA #&19 &3355 85 9f STA &9f ; fire_countdown &3357 a2 02 LDX #&02 ; thousand &3359 20 c3 30 JSR &30c3 ; increase_score # Two thousand points for letting fire burn out &335c 4c 91 33 JMP &3391 ; to_kill_creature ; creature_has_been_attacked &335f 08 PHP &3360 c0 11 CPY #&11 ; TRIBESMAN &3362 d0 2c BNE &3390 ; not_tribesman # Is this a TRIBESMAN? &3364 a9 ff LDA #&ff &3366 9d 27 33 STA &3327,X ; creature_attacked # If so, it can't be killed &3369 bd 33 33 LDA &3333,X ; creature_movement &336c 28 PLP ; status after original LDA creature_attacked # Consider how the TRIBESMAN was attacked &336d f0 06 BEQ &3375 ; attacked_by_player_facing_left &336f 29 01 AND #&01 &3371 d0 15 BNE &3388 ; play_attacking_tribesman_sound # Play a sound if the TRIBEMAN is facing the player &3373 f0 04 BEQ &3379 ; turn_tribesman ; attacked_by_player_facing_left &3375 29 01 AND #&01 &3377 f0 0f BEQ &3388 ; play_attacking_tribesman_sound ; turn_tribesman # If not, &3379 49 01 EOR #&01 &337b 85 16 STA &16 ; new_movement # turn the TRIBESMAN around &337d 00 BRK ; random_number &337e 29 02 AND #&02 # and one time in two give it downwards movement too &3380 05 16 ORA &16 ; new_movement &3382 9d 33 33 STA &3333,X ; creature_movement &3385 20 51 34 JSR &3451 ; set_creature_direction_from_A ; play_attacking_tribesman_sound &3388 a2 c8 LDX #&c8 ; sound_9 &338a 20 a2 32 JSR &32a2 ; play_sound_from_second_table &338d 4c e7 33 JMP &33e7 ; continue_updating_creature ; not_tribesman &3390 28 PLP ; to_kill_creature &3391 20 37 33 JSR &3337 ; increase_score_by_one_hundred_and_tens &3394 a6 93 LDX &93 ; creature_being_considered ; kill_creature &3396 bd dc 32 LDA &32dc,X ; creature_sprite &3399 30 b7 BMI &3352 ; leave # Leave if there is no creature in this slot &339b c9 05 CMP #&05 ; DISAPPEARING &339d f0 ab BEQ &334a ; remove_creature_if_frame_negative # Remove creature if disappeared &339f a9 05 LDA #&05 &33a1 9d dc 32 STA &32dc,X ; creature_sprite &33a4 9d e8 32 STA &32e8,X ; creature_frame &33a7 a2 d0 LDX #&d0 ; sound_10 &33a9 20 a2 32 JSR &32a2 ; play_sound_from_second_table &33ac a2 d8 LDX #&d8 ; sound_11 &33ae 4c a2 32 JMP &32a2 ; play_sound_from_second_table ; to_creature_has_been_attacked &33b1 10 ac BPL &335f ; creature_has_been_attacked ; to_remove_fire &33b3 f0 9e BEQ &3353 ; remove_fire ; to_remove_creature_if_frame_negative &33b5 f0 93 BEQ &334a ; remove_creature_if_frame_negative ; to_consider_spawning_new_creature &33b7 4c 5a 34 JMP &345a ; consider_spawning_new_creature ; creature_in_different_room &33ba 4c 57 34 JMP &3457 ; consider_spawning_new_creature_after_increasing_frame ; update_creature &33bd a6 93 LDX &93 ; creature_being_considered &33bf de e8 32 DEC &32e8,X ; creature_frame &33c2 a5 cc LDA &cc ; player_sprite &33c4 f0 04 BEQ &33ca ; player_is_alive &33c6 c9 07 CMP #&07 # Is the player SITTING, FLYING or DEAD? &33c8 90 cc BCC &3396 ; kill_creature # If so, kill all creatures ; player_is_alive &33ca bd dc 32 LDA &32dc,X ; creature_sprite # Is there a creature in this slot? &33cd 30 e8 BMI &33b7 ; to_consider_spawning_new_creature # If not, consider spawning one &33cf a8 TAY &33d0 bd 0c 33 LDA &330c,X ; creature_room &33d3 c5 a1 CMP &a1 ; player_room # Is the creature in this room? &33d5 d0 e3 BNE &33ba ; creature_in_different_room # If not, consider spawning one here instead &33d7 c0 05 CPY #&05 ; DISAPPEARING &33d9 f0 da BEQ &33b5 ; to_remove_creature_if_frame_negative # Remove the creature if has fully disappeared &33db e0 03 CPX #&03 &33dd f0 05 BEQ &33e4 ; is_fire # FIRE cannot die &33df bd 27 33 LDA &3327,X ; creature_attacked &33e2 10 cd BPL &33b1 ; to_creature_has_been_attacked # Handle an attacked creature separately ; is_fire &33e4 98 TYA &33e5 f0 57 BEQ &343e ; is_appearing_creature # Handle an APPEARING creature separately ; continue_updating_creature &33e7 20 da 35 JSR &35da ; move_creature # Otherwise, handle the creature's movement &33ea a6 93 LDX &93 ; creature_being_considered &33ec a5 16 LDA &16 ; creature_has_moved &33ee d0 03 BNE &33f3 ; skip_updating_frame &33f0 fe e8 32 INC &32e8,X ; creature_frame # Don't update frame if creature hasn't moved ; skip_updating_frame # (cancels out DEC at &33bf) &33f3 e0 03 CPX #&03 &33f5 d0 34 BNE &342b ; not_fire &33f7 c6 9f DEC &9f ; fire_countdown &33f9 f0 b8 BEQ &33b3 ; to_remove_fire # Has the FIRE burned out? &33fb c9 00 CMP #&00 &33fd d0 03 BNE &3402 ; skip_changing_fire_state &33ff 9d 1b 33 STA &331b,X ; creature_movement_duration # Make the FIRE change direction if it can't move ; skip_changing_fire_state &3402 ee c1 03 INC &03c1 ; fire_state &3405 ad c1 03 LDA &03c1 ; fire_state &3408 29 0f AND #&0f &340a aa TAX &340b bd f0 1d LDA &1df0,X ; fire_pitch_table &340e 8d 74 01 STA &0174 ; pitch_of_sound_7 &3411 a2 70 LDX #&70 ; sound_7 &3413 20 a5 32 JSR &32a5 ; play_sound_from_first_table # Play a sound if the FIRE is present &3416 00 BRK ; random_number &3417 29 07 AND #&07 &3419 aa TAX &341a bd 7b 12 LDA &127b,X ; fire_colour_table &341d 8d 03 33 STA &3303 ; creature_colour + 3 # Set colour of FIRE at random &3420 a2 03 LDX #&03 ; pick_a_random_number_between_0_and_2 &3422 00 BRK ; random_number &3423 29 03 AND #&03 &3425 c9 03 CMP #&03 &3427 f0 f9 BEQ &3422 ; pick_a_random_number_between_0_and_2 &3429 d0 05 BNE &3430 ; set_frame # Set the frame of the FIRE at random ; not_fire &342b bd e8 32 LDA &32e8,X ; creature_frame &342e 29 01 AND #&01 ; set_frame &3430 9d e8 32 STA &32e8,X ; creature_frame &3433 de 1b 33 DEC &331b,X ; creature_movement_duration # Is the creature due to change direction? &3436 10 05 BPL &343d ; leave &3438 20 cd 34 JSR &34cd ; give_creature_random_movement # If so, set it moving in a random direction &343b d0 11 BNE &344e ; set_creature_direction_from_movement &343d 60 RTS ; is_appearing_creature &343e bd e8 32 LDA &32e8,X ; creature_frame &3441 10 fa BPL &343d ; leave # If the creature has just finished APPEARING, &3443 bd 18 33 LDA &3318,X ; creature_species ; set_creature_sprite &3446 9d dc 32 STA &32dc,X ; creature_sprite # change its sprite to its proper one &3449 a9 01 LDA #&01 &344b 9d e8 32 STA &32e8,X ; creature_frame ; set_creature_direction_from_movement &344e bd 33 33 LDA &3333,X ; creature_movement ; set_creature_direction_from_A &3451 29 01 AND #&01 &3453 9d f4 32 STA &32f4,X ; creature_direction # Set the creature looking either left or right &3456 60 RTS ; consider_spawning_new_creature_after_increasing_frame &3457 fe e8 32 INC &32e8,X ; creature_frame ; consider_spawning_new_creature &345a a2 48 LDX #&48 ; horizontal_range &345c a9 18 LDA #&18 ; height &345e a0 38 LDY #&38 ; width &3460 20 04 40 JSR &4004 ; get_random_screen_address # Pick a space at random on the screen &3463 30 d8 BMI &343d ; leave # If it has no scenery, spawn a new creature there &3465 a6 93 LDX &93 ; creature_being_considered &3467 a5 eb LDA &eb ; screen_address_high &3469 9d ac 32 STA &32ac,X ; creature_screen_address_high &346c a5 e3 LDA &e3 ; screen_address_low &346e 9d b8 32 STA &32b8,X ; creature_screen_address_low &3471 a5 d6 LDA &d6 ; position_x &3473 9d c4 32 STA &32c4,X ; creature_x &3476 a5 d7 LDA &d7 ; position_y &3478 9d d0 32 STA &32d0,X ; creature_y &347b a9 ff LDA #&ff &347d 9d 27 33 STA &3327,X ; creature_attacked &3480 e0 03 CPX #&03 &3482 f0 58 BEQ &34dc ; spawn_fire # Handle FIRE spawning separately ; pick_a_species_at_random &3484 00 BRK ; random_number &3485 29 07 AND #&07 &3487 c5 92 CMP &92 ; maximum_species &3489 b0 f9 BCS &3484 ; pick_a_species_at_random # Pick a creature type at random, up to the maximum &348b a8 TAY &348c 0a ASL A &348d 69 0b ADC #&0b &348f 9d 18 33 STA &3318,X ; creature_species &3492 ad 08 41 LDA &4108 ; species_colour_table &3495 49 33 EOR #&33 &3497 8d 08 41 STA &4108 ; species_colour_table # Alternate colour of SPIDERs &349a b9 08 41 LDA &4108,Y ; species_colour_table &349d 9d 00 33 STA &3300,X ; creature_colour &34a0 00 BRK ; random_number &34a1 29 1f AND #&1f # There's a 1 in 32 chance &34a3 d0 0a BNE &34af ; standard_colour_creature &34a5 00 BRK ; random_number &34a6 29 03 AND #&03 &34a8 a8 TAY &34a9 b9 09 41 LDA &4109,Y ; species_colour_table + 1 # that the creature is an unusual colour &34ac 9d 00 33 STA &3300,X ; creature_colour ; standard_colour_creature &34af a9 00 LDA #&00 ; APPEARING &34b1 9d dc 32 STA &32dc,X ; creature_sprite # Set the creature as APPEARING to start with &34b4 9d f4 32 STA &32f4,X ; creature_direction &34b7 a9 04 LDA #&04 &34b9 9d e8 32 STA &32e8,X ; creature_frame &34bc a2 60 LDX #&60 ; sound_5 &34be 20 a5 32 JSR &32a5 ; play_sound_from_first_table &34c1 a2 68 LDX #&68 ; sound_6 &34c3 20 a5 32 JSR &32a5 ; play_sound_from_first_table &34c6 a6 93 LDX &93 ; creature_being_considered ; insert_creature_into_room &34c8 a5 a1 LDA &a1 ; player_room &34ca 9d 0c 33 STA &330c,X ; creature_room ; give_creature_random_movement &34cd 00 BRK ; random_number &34ce 29 03 AND #&03 &34d0 9d 33 33 STA &3333,X ; creature_movement # Give it a random direction &34d3 00 BRK ; random_number &34d4 29 1f AND #&1f &34d6 69 20 ADC #&20 &34d8 9d 1b 33 STA &331b,X ; creature_movement_duration # and random duration for it to move in that direction ; leave &34db 60 RTS ; spawn_fire &34dc c6 9f DEC &9f ; fire_countdown &34de d0 fb BNE &34db ; leave # Can the FIRE appear yet? &34e0 20 c8 34 JSR &34c8 ; insert_creature_into_room &34e3 a9 29 LDA #&29 ; FIRE &34e5 4c 46 34 JMP &3446 ; set_creature_sprite # If so, spawn it ; handle_creature &34e8 20 ee 34 JSR &34ee ; plot_creature # Remove the creature from the screen by plotting it &34eb 20 bd 33 JSR &33bd ; update_creature # Update its position and sprite ; plot_creature # And then update it on screen by plotting it again &34ee a4 93 LDY &93 ; creature_being_considered &34f0 b9 00 33 LDA &3300,Y ; creature_colour &34f3 20 b4 40 JSR &40b4 ; split_a_into_pixel_values &34f6 b9 0c 33 LDA &330c,Y ; creature_room &34f9 c5 a1 CMP &a1 ; player_room # Is the creature in the same room as the player? &34fb d0 de BNE &34db ; leave &34fd b9 dc 32 LDA &32dc,Y ; creature_sprite # Is there actually a creature in the slot? &3500 30 d9 BMI &34db ; leave &3502 18 CLC &3503 79 e8 32 ADC &32e8,Y ; creature_frame # Calculate sprite to use from base and frame (Y) &3506 a8 TAY &3507 a2 00 LDX #&00 &3509 a9 20 LDA #&20 &350b c0 11 CPY #&11 ; TRIBESMAN # Is this a TRIBESMAN? A = &20, X = &00 wide &350d f0 1f BEQ &352e ; set_sprite_details &350f c0 12 CPY #&12 ; TRIBESMAN &3511 f0 1b BEQ &352e ; set_sprite_details &3513 a9 18 LDA #&18 &3515 c0 29 CPY #&29 ; FIRE # Is this a FIRE? A = &18, X = &00 &3517 b0 15 BCS &352e ; set_sprite_details &3519 a9 30 LDA #&30 &351b c0 28 CPY #&28 ; SLEEPING_HIPPO # Is this a SLEEPING_HIPPO? A = &30, X = &00 &351d f0 0f BEQ &352e ; set_sprite_details &351f a9 50 LDA #&50 &3521 c0 1b CPY #&1b # Is this a HIPPO, RHINO or WOLF? A = &50, X = &00 &3523 b0 09 BCS &352e ; set_sprite_details &3525 b9 ed 40 LDA &40ed,Y ; sprites_for_creatures_columns_table # Otherwise, look it up in a table &3528 c9 38 CMP #&38 &352a f0 02 BEQ &352e # A = &38, X = &00 or A = &28, X = &08 &352c a2 08 LDX #&08 # i.e. smaller sprites are offset ; set_sprite_details &352e 85 e1 STA &e1 ; sprite_start_column &3530 86 e2 STX &e2 ; sprite_x_offset &3532 b9 81 35 LDA &3581,Y ; sprites_for_creatures_address_table_high &3535 8d 76 40 STA &4076 ; sprite_data_address_high &3538 b9 ad 35 LDA &35ad,Y ; sprites_for_creatures_address_table_low &353b 8d 75 40 STA &4075 ; sprite_data_address_low &353e b9 c1 40 LDA &40c1,Y ; sprites_for_creatures_row_table &3541 85 70 STA &70 ; sprite_rows_to_plot &3543 a4 93 LDY &93 ; creature_being_considered &3545 be ac 32 LDX &32ac,Y ; creature_screen_address_high &3548 b9 f4 32 LDA &32f4,Y ; creature_direction &354b 48 PHA &354c b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &354f a4 e2 LDY &e2 ; sprite_x_offset &3551 20 1a 47 JSR &471a ; add_y_to_a_and_x &3554 a8 TAY &3555 68 PLA ; creature_direction &3556 c9 01 CMP #&01 &3558 a5 e1 LDA &e1 ; screen_start_column &355a b0 0c BCS &3568 ; flip_sprite ; into_plot_single_colour_sprite &355c 8d 8d 40 STA &408d ; screen_end_column &355f a9 69 LDA #&69 ; ADC # Sprite is plotted left to right &3561 8d 91 40 STA &4091 ; plot_single_colour_sprite_move_instruction &3564 a9 00 LDA #&00 &3566 f0 16 BEQ &357e ; to_plot_single_colour_sprite ; flip_sprite &3568 48 PHA &3569 a9 00 LDA #&00 &356b 8d 8d 40 STA &408d ; screen_end_column &356e a9 e9 LDA #&e9 ; SBC # Sprite is plotted right to left &3570 8d 91 40 STA &4091 ; plot_single_colour_sprite_move_instruction &3573 a5 77 LDA &77 ; right_hand_pixel &3575 48 PHA &3576 a5 78 LDA &78 ; left_hand_pixel &3578 85 77 STA &77 ; right_hand_pixel &357a 68 PLA ; right_hand_pixel &357b 85 78 STA &78 ; left_hand_pixel &357d 68 PLA ; screen_start_column ; to_plot_single_colour_sprite &357e 4c 66 40 JMP &4066 ; plot_single_colour_sprite ; sprites_for_creatures_address_table_high &3581 2f 2f 2e 21 21 21 21 21 21 21 21 11 10 10 10 1b &3591 1b 1d 11 1b 1b 2f 2f 10 10 2f 2f 10 10 10 10 0f &35a1 0f 0f 0f 12 12 12 12 11 11 11 11 11 ; sprites_for_creatures_address_table_low &35ad 55 29 fb f9 d3 b5 36 57 85 57 36 22 f6 9a 80 cb &35bd e0 d3 4e b4 f7 95 7d dc b4 c2 aa 22 22 51 51 60 &35cd e0 a0 e0 07 07 36 36 d8 a7 7f 6b 93 ; leave &35d9 60 RTS ; move_creature &35da a4 93 LDY &93 ; creature_being_considered &35dc a9 00 LDA #&00 &35de 85 16 STA &16 ; creature_has_moved &35e0 b9 dc 32 LDA &32dc,Y ; creature_sprite # Leave if there isn't a creature in this slot &35e3 30 f4 BMI &35d9 ; leave &35e5 c9 0b CMP #&0b # Leave if creature is APPEARING or DISAPPEARING &35e7 90 f0 BCC &35d9 ; leave &35e9 c9 17 CMP #&17 ; SNAKE &35eb f0 08 BEQ &35f5 ; snake_bird_or_lizard &35ed c9 0f CMP #&0f ; BIRD &35ef f0 04 BEQ &35f5 ; snake_bird_or_lizard &35f1 c9 0d CMP #&0d ; LIZARD &35f3 d0 3a BNE &362f ; not_snake_bird_or_lizard ; snake_bird_or_lizard &35f5 99 1b 33 STA &331b,Y ; creature_movement_duration # SNAKEs, BIRDs and LIZARDs home in on player &35f8 a9 0c LDA #&0c &35fa 85 15 STA &15 ; tmp &35fc a5 d2 LDA &d2 ; player_x &35fe 18 CLC &35ff 69 04 ADC #&04 &3601 d9 c4 32 CMP &32c4,Y ; creature_x &3604 f0 0a BEQ &3610 ; creature_at_same_x_position_as_player &3606 a9 00 LDA #&00 &3608 90 02 BCC &360c ; creature_to_right_of_player &360a a9 01 LDA #&01 ; creature_to_right_of_player &360c 09 04 ORA #&04 &360e 85 15 STA &15 ; tmp ; creature_at_same_x_position_as_player &3610 b9 d0 32 LDA &32d0,Y ; creature_y &3613 c5 d4 CMP &d4 ; player_y &3615 08 PHP &3616 a9 00 LDA #&00 &3618 28 PLP &3619 f0 06 BEQ &3621 ; creature_at_same_y_position_as_player &361b b0 02 BCS &361f ; creature_below_player &361d a9 02 LDA #&02 ; creature_below_player &361f 09 04 ORA #&04 ; creature_at_same_y_position_as_player # creature_movement = 3 a 2 v above &3621 45 15 EOR &15 ; tmp # 5 c 4 > . < left - player - right &3623 99 33 33 STA &3333,Y ; creature_movement # 1 8 0 ^ below &3626 e6 16 INC &16 ; creature_has_moved &3628 a6 93 LDX &93 ; creature_being_considered &362a 20 4e 34 JSR &344e ; set_creature_direction_from_movement &362d a4 93 LDY &93 ; creature_being_considered ; not_snake_bird_or_lizard &362f a9 18 LDA #&18 # Creatures are 24 pixels high &3631 85 e1 STA &e1 ; height &3633 a9 38 LDA #&38 # and 16 pixels wide ; &38 = ((16/2)-1)*8 &3635 c0 03 CPY #&03 # for collision checking with scenery &3637 d0 02 BNE &363b ; not_fire &3639 a9 18 LDA #&18 # except for FIRE, which is 8 ; &18 = ((8/2)-1)*8 &363b 85 7c STA &7c ; creature_width_for_scenery_check ; not_fire &363d b9 33 33 LDA &3333,Y ; creature_movement &3640 48 PHA &3641 4a LSR A &3642 29 04 AND #&04 &3644 d0 61 BNE &36a7 ; finished_x_movement # creature_movement & 8 set if moving just up or down &3646 90 31 BCC &3679 ; move_creature_left # creature_movement & 1 clear if moving left ; move_creature_right &3648 b9 c4 32 LDA &32c4,Y ; creature_x &364b c0 03 CPY #&03 &364d f0 04 BEQ &3653 ; is_fire &364f c9 f8 CMP #&f8 # Is the creature at the right of the screen? &3651 f0 54 BEQ &36a7 ; finished_x_movement ; is_fire &3653 c9 fb CMP #&fb # (FIRE is smaller) &3655 f0 50 BEQ &36a7 ; finished_x_movement &3657 be ac 32 LDX &32ac,Y ; creature_screen_address_high &365a b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &365d a0 08 LDY #&08 &365f 20 1a 47 JSR &471a ; add_y_to_a_and_x # If not, move creature right two pixels &3662 86 eb STX &eb ; screen_address_high &3664 85 e3 STA &e3 ; screen_address_low &3666 a4 7c LDY &7c ; creature_width_for_scenery_check &3668 20 1a 47 JSR &471a ; add_y_to_a_and_x &366b a0 00 LDY #&00 ; width &366d 20 1b 30 JSR &301b ; check_for_scenery # checking that this doesn't put it in scenery &3670 30 35 BMI &36a7 ; finished_x_movement &3672 a6 93 LDX &93 ; creature_being_considered &3674 fe c4 32 INC &32c4,X ; creature_x # If it doesn't, update its position &3677 d0 22 BNE &369b ; store_creatures_new_screen_address_x # and screen address ; move_creature_left &3679 b9 c4 32 LDA &32c4,Y ; creature_x &367c c9 b0 CMP #&b0 # Is the creature at the left of the screen?: &367e f0 27 BEQ &36a7 ; finished_x_movement &3680 be ac 32 LDX &32ac,Y ; creature_screen_address_high &3683 b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &3686 a0 08 LDY #&08 &3688 20 23 47 JSR &4723 ; subtract_y_from_a_and_x # If not, move creature left two pixels &368b 86 eb STX &eb ; screen_address_high &368d 85 e3 STA &e3 ; screen_address_low &368f a0 00 LDY #&00 ; width &3691 20 1b 30 JSR &301b ; check_for_scenery # checking that this doesn't put it in scenery &3694 30 11 BMI &36a7 ; finished_x_movement &3696 a6 93 LDX &93 ; creature_being_considered &3698 de c4 32 DEC &32c4,X ; creature_x # If it doesn't, update its position ; store_creatures_new_screen_address_x &369b a5 eb LDA &eb ; screen_address_high &369d 9d ac 32 STA &32ac,X ; creature_screen_address_high # and screen address &36a0 a5 e3 LDA &e3 ; screen_address_low &36a2 9d b8 32 STA &32b8,X ; creature_screen_address_low &36a5 e6 16 INC &16 ; creature_has_moved ; finished_x_movement &36a7 a4 93 LDY &93 ; creature_being_considered &36a9 a9 04 LDA #&04 &36ab 85 e1 STA &e1 ; height &36ad 68 PLA ; creature_movement &36ae aa TAX &36af 29 04 AND #&04 # creature_movement & 4 set if moving just left or right &36b1 d0 3e BNE &36f1 ; leave &36b3 8a TXA &36b4 29 02 AND #&02 # creature_movement & 2 set if moving up &36b6 d0 3a BNE &36f2 ; move_creature_down ; move_creature_up &36b8 b9 d0 32 LDA &32d0,Y ; creature_y &36bb c9 17 CMP #&17 # Is the creature at the top of the screen? &36bd f0 32 BEQ &36f1 ; leave &36bf be ac 32 LDX &32ac,Y ; creature_screen_address_high &36c2 b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &36c5 a0 04 LDY #&04 &36c7 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows # If not, move creature up four pixels &36ca 86 eb STX &eb ; screen_address_high &36cc 85 e3 STA &e3 ; screen_address_low &36ce a0 14 LDY #&14 # (looking at the top of the creature) &36d0 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows &36d3 a4 7c LDY &7c ; creature_width_for_scenery_check &36d5 20 1b 30 JSR &301b ; check_for_scenery # checking that this doesn't put it in scenery &36d8 30 17 BMI &36f1 ; leave &36da a4 93 LDY &93 ; creature_being_considered &36dc b9 d0 32 LDA &32d0,Y ; creature_y &36df 38 SEC &36e0 e9 04 SBC #&04 &36e2 99 d0 32 STA &32d0,Y ; creature_y # If it doesn't, update its position ; store_creatures_new_screen_address &36e5 a5 eb LDA &eb ; screen_address_high &36e7 99 ac 32 STA &32ac,Y ; creature_screen_address_high # and screen address &36ea a5 e3 LDA &e3 ; screen_address_low &36ec 99 b8 32 STA &32b8,Y ; creature_screen_address_low &36ef e6 16 INC &16 ; creature_has_moved ; leave &36f1 60 RTS ; move_creature_down &36f2 b9 d0 32 LDA &32d0,Y ; creature_y &36f5 c9 af CMP #&af # Is the creature at the bottom of the screen? &36f7 f0 f8 BEQ &36f1 ; leave &36f9 be ac 32 LDX &32ac,Y ; creature_screen_address_high &36fc b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &36ff a0 04 LDY #&04 &3701 20 2c 47 JSR &472c ; increase_screen_address_by_y_rows # If not, move creature down four pixels &3704 86 eb STX &eb ; screen_address_high &3706 85 e3 STA &e3 ; screen_address_low &3708 a4 7c LDY &7c ; creature_width_for_scenery_check &370a 20 1b 30 JSR &301b ; check_for_scenery # checking that this doesn't put it in scenery &370d 30 e2 BMI &36f1 ; leave &370f a4 93 LDY &93 ; creature_being_considered &3711 b9 d0 32 LDA &32d0,Y ; creature_y &3714 18 CLC &3715 69 04 ADC #&04 &3717 99 d0 32 STA &32d0,Y ; creature_y # If it doesn't, update its position &371a d0 c9 BNE &36e5 ; store_creatures_new_screen_address # and screen address ; does_player_overlap_target # Returns carry clear if overlap, set if not &371c a5 15 LDA &15 ; player_x_for_overlap_test &371e c5 16 CMP &16 ; target_x &3720 f0 11 BEQ &3733 ; player_and_target_have_equal_x &3722 b0 08 BCS &372c ; player_right_of_target ; player_left_of_target &3724 65 eb ADC &eb ; player_width_for_overlap_test &3726 c5 16 CMP &16 ; target_x &3728 90 21 BCC &374b ; leave_with_carry_set &372a b0 07 BCS &3733 ; player_and_target_have_equal_x ; player_right_of_target &372c 18 CLC &372d e5 e3 SBC &e3 ; target_width &372f c5 16 CMP &16 ; target_x &3731 b0 18 BCS &374b ; leave_with_carry_set ; player_and_target_have_equal_x &3733 a5 d4 LDA &d4 ; player_y &3735 c5 e2 CMP &e2 ; target_y &3737 f0 0a BEQ &3743 ; player_and_target_have_equal_y &3739 b0 0a BCS &3745 ; player_below_target ; player_above_target &373b 65 d7 ADC &d7 ; target_height &373d c5 e2 CMP &e2 ; target_y &373f f0 0a BEQ &374b ; leave_with_carry_set &3741 90 08 BCC &374b ; leave_with_carry_set ; player_and_target_have_equal_y ; leave_with_carry_clear &3743 18 CLC &3744 60 RTS ; player_below_target &3745 e9 16 SBC #&16 &3747 c5 e2 CMP &e2 ; target_y &3749 90 f8 BCC &3743 ; leave_with_carry_clear ; leave_with_carry_set &374b 38 SEC &374c 60 RTS ; reset_game &374d ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &3750 85 6e STA &6e ; game_seed &3752 a9 28 LDA #&28 ; GUARDIAN &3754 8d e4 32 STA &32e4 ; creature_sprite + 8 # Restore GUARDIAN &3757 20 33 3d JSR &3d33 ; clear_screen &375a a2 06 LDX #&06 &375c a9 10 LDA #&10 &375e 85 cd STA &cd ; number_of_notes &3760 8d 55 32 STA &3255 ; percentage_complete_high &3763 8d 56 32 STA &3256 ; percentage_complete_low ; reset_score_loop &3766 9d 19 32 STA &3219,X ; score - 1 # Zero score &3769 ca DEX &376a d0 fa BNE &3766 ; reset_score_loop &376c 20 4f 3d JSR &3d4f ; plot_scenery_type_X # Plot title screen scenery (room type &00) &376f 20 d8 30 JSR &30d8 ; plot_score_and_lives &3772 a2 02 LDX #&02 &3774 a0 0a LDY #&0a &3776 20 dc 30 JSR &30dc ; plot_text # Display "Hall of Fame" to "Press RETURN to START" &3779 a2 00 LDX #&00 ; reset_room_data_loop &377b bd 7a 29 LDA &297a,X ; room_data_table &377e 29 3f AND #&3f # Mark rooms as unvisited and having objects &3780 9d 7a 29 STA &297a,X ; room_data_table &3783 e8 INX &3784 d0 f5 BNE &377b ; reset_room_data_loop &3786 a2 03 LDX #&03 &3788 86 6a STX &6a ; amulet_parts_uncollected ; reset_amulet_data_loop &378a a9 ff LDA #&ff &378c 9d dc 32 STA &32dc,X ; creature_sprite &378f 85 6d STA &6d ; rooms_visited &3791 a9 00 LDA #&00 &3793 9d ca 03 STA &03ca,X ; amulet_parts_collected # Mark amulet parts as uncollected ; pick_a_random_room &3796 00 BRK ; random_number # Pick a room at random &3797 a8 TAY &3798 b9 7a 29 LDA &297a,Y ; room_data_table &379b c9 09 CMP #&09 # Is it a clearing with a south entrance? &379d f0 08 BEQ &37a7 ; is_clearing &379f c9 0f CMP #&0f # Is it a clearing with a north entrance? &37a1 f0 04 BEQ &37a7 ; is_clearing &37a3 c9 13 CMP #&13 # Is it a clearing with north and south entrances? &37a5 d0 ef BNE &3796 ; pick_a_random_room ; is_clearing &37a7 98 TYA &37a8 9d bd 03 STA &03bd,X ; amulet_rooms # If so, put a part of the amulet there &37ab ca DEX &37ac 10 dc BPL &378a ; reset_amulet_data_loop &37ae a9 0c LDA #&0c # Play title screen music &37b0 85 cc STA &cc ; number_of_bars &37b2 a9 bf LDA #&bf ; title_music # Title screen music starts at &2ebf &37b4 85 7a STA &7a ; music_address_low ; next_note &37b6 c6 cd DEC &cd ; number_of_notes &37b8 10 0f BPL &37c9 ; not_at_end_of_bar &37ba a5 7a LDA &7a ; music_address_low &37bc 18 CLC &37bd 69 05 ADC #&05 &37bf 85 7a STA &7a ; music_address_low &37c1 c6 cc DEC &cc ; number_of_bars &37c3 f0 1c BEQ &37e1 ; wait_for_return_to_be_pressed &37c5 a9 0f LDA #&0f # Twelve bars of sixteen notes &37c7 85 cd STA &cd ; number_of_notes ; not_at_end_of_bar &37c9 a6 cd LDX &cd ; number_of_notes &37cb bc 44 30 LDY &3044,X ; title_music_note_table &37ce b1 7a LDA (&7a),Y ; music_address &37d0 20 54 30 JSR &3054 ; play_sound_on_three_channels &37d3 a9 f9 LDA #&f9 # Wait 350ms between notes &37d5 85 8f STA &8f ; interrupt_ticker ; delay_loop &37d7 a5 ec LDA &ec ; Internal key number of most recently pressed key &37d9 d0 06 BNE &37e1 ; wait_for_return_to_be_pressed # Pressing a key stops the title music &37db a5 8f LDA &8f ; interrupt_ticker &37dd d0 f8 BNE &37d7 ; delay_loop &37df f0 d5 BEQ &37b6 ; next_note ; wait_for_return_to_be_pressed &37e1 a2 b6 LDX #&b6 ; RETURN # Wait for RETURN to be pressed &37e3 20 09 47 JSR &4709 ; check_for_keypress &37e6 d0 f9 BNE &37e1 ; wait_for_return_to_be_pressed &37e8 a9 0d LDA #&0d # Play game start music &37ea a0 00 LDY #&00 &37ec 20 a6 30 JSR &30a6 ; play_music &37ef a9 14 LDA #&14 &37f1 85 c0 STA &c0 ; lives_as_digit &37f3 a9 04 LDA #&04 &37f5 85 6f STA &6f ; life_counter # Player starts with 4 lives &37f7 85 92 STA &92 ; maximum_species &37f9 a9 63 LDA #&63 &37fb 85 d0 STA &d0 ; player_screen_address_high &37fd a9 0f LDA #&0f &37ff 85 d8 STA &d8 ; player_screen_address_low &3801 a9 00 LDA #&00 &3803 85 ca STA &ca ; player_direction &3805 85 cc STA &cc ; player_sprite # Player is WALKING &3807 85 ce STA &ce ; player_frame &3809 85 e0 STA &e0 ; player_move_counter &380b 85 c3 STA &c3 ; player_horizontal_direction &380d 8d 00 1e STA &1e00 ; hippo_charge_countdown &3810 8d 01 1e STA &1e01 ; hippo_charge_countdown &3813 85 15 STA &15 ; irrelevant # Apparently redundant code. &3815 a9 57 LDA #&57 &3817 85 d4 STA &d4 ; player_y &3819 a9 a8 LDA #&a8 &381b 85 a1 STA &a1 ; player_room # Player starts in room &a8 &381d a9 d1 LDA #&d1 &381f 85 d2 STA &d2 ; player_x &3821 20 13 47 JSR &4713 ; delay # 2350ms delay before plotting room &3824 a9 40 LDA #&40 &3826 8d 21 fe STA &fe21 ; Video ULA # Set palette for player's body ; entering_room &3829 20 93 3b JSR &3b93 ; flush_buffers &382c 20 44 3d JSR &3d44 ; plot_scenery &382f 20 85 42 JSR &4285 ; summon_hippos &3832 a9 19 LDA #&19 &3834 85 9f STA &9f ; fire_countdown # Reset the FIRE countdown &3836 20 d8 30 JSR &30d8 ; plot_score_and_lives &3839 a6 84 LDX &84 ; room_type &383b bd 5d 3f LDA &3f5d,X ; room_types_state_table # Get orchid colour from table &383e a8 TAY &383f 29 07 AND #&07 &3841 85 9a STA &9a ; orchid_colour &3843 98 TYA &3844 4a LSR A &3845 4a LSR A &3846 4a LSR A &3847 a8 TAY &3848 b9 d1 3f LDA &3fd1,Y ; orchid_position_y_table &384b 48 PHA &384c b9 b8 3f LDA &3fb8,Y ; orchid_position_x_table &384f 48 PHA &3850 bd 8a 3f LDA &3f8a,X ; state_of_orchid_in_rooms # Read stored orchid state from room table &3853 a8 TAY &3854 29 01 AND #&01 &3856 85 97 STA &97; orchid_fading &3858 98 TYA &3859 29 0f AND #&0f &385b 4a LSR A &385c 85 99 STA &99 ; orchid_stage &385e 98 TYA &385f 4a LSR A &3860 4a LSR A &3861 4a LSR A &3862 4a LSR A &3863 a8 TAY &3864 a2 ff LDX #&ff &3866 8e df 32 STX &32df ; creature_sprite + 3 # Remove any FIRE &3869 20 bb 3e JSR &3ebb ; write_time &386c 68 PLA ; orchid_position_x_table &386d aa TAX &386e 68 PLA ; orchid_position_y_table &386f 20 19 40 JSR &4019 ; calculate_screen_position # Calculate where the orchid is on screen &3872 a5 d7 LDA &d7 ; position_y &3874 85 94 STA &94 ; orchid_position_y &3876 a5 d6 LDA &d6 ; position_x &3878 85 95 STA &95 ; orchid_position_x &387a a5 e3 LDA &e3 ; screen_address_low &387c 85 9b STA &9b ; orchid_screen_address_low &387e a5 eb LDA &eb ; screen_address_high &3880 85 9c STA &9c ; orchid_screen_address_high &3882 20 06 3f JSR &3f06 ; plot_new_orchid # Plot orchid &3885 a5 d8 LDA &d8 ; player_screen_address_low &3887 a6 d0 LDX &d0 ; player_screen_address_high &3889 a0 20 LDY #&20 &388b 20 1a 47 JSR &471a ; add_y_to_a_and_x &388e a4 d2 LDY &d2 ; player_x &3890 20 d4 2f JSR &2fd4 ; ensure_player_isn't_in_scenery # Move the player out of any scenery &3893 84 d2 STY &d2 ; player_x # (some north/south room boundaries don't match) &3895 a0 20 LDY #&20 &3897 20 23 47 JSR &4723 ; subtract_y_from_a_and_x &389a 85 d8 STA &d8 ; player_screen_address_low &389c 86 d0 STX &d0 ; player_screen_address_high &389e 20 4a 46 JSR &464a ; plot_current_player # Plot player &38a1 a9 0b LDA #&0b &38a3 85 93 STA &93 ; creature_being_considered ; plot_creatures_loop &38a5 20 ee 34 JSR &34ee ; plot_creature # Plot creatures &38a8 c6 93 DEC &93 ; creature_being_considered &38aa 10 f9 BPL &38a5 ; plot_creatures_loop &38ac a5 6d LDA &6d ; rooms_visited &38ae c9 ff CMP #&ff &38b0 d0 05 BNE &38b7 ; no_delay &38b2 a9 c8 LDA #&c8 # 2800 ms pause when entering first room &38b4 20 13 47 JSR &4713 ; delay ; no_delay &38b7 a5 c6 LDA &c6 ; rnd_1 # Store the state of the random number generator &38b9 48 PHA &38ba a5 c7 LDA &c7 ; rnd_2 &38bc 48 PHA &38bd a5 c8 LDA &c8 ; rnd_3 &38bf 48 PHA &38c0 20 9a 3b JSR &3b9a ; put_object_in_room # Put the object in the room, if there is one &38c3 68 PLA # (which reseeds the random number generator) &38c4 85 c8 STA &c8 ; rnd_3 &38c6 68 PLA &38c7 85 c7 STA &c7 ; rnd_2 &38c9 68 PLA &38ca 85 c6 STA &c6 ; rnd_1 # then restore the state of the random number generator ; main_game_loop &38cc a9 ff LDA #&ff &38ce 85 8f STA &8f ; interrupt_ticker # A minimum of 50ms per frame &38d0 c6 93 DEC &93 ; creature_being_considered &38d2 10 04 BPL &38d8 &38d4 a9 04 LDA #&04 &38d6 85 93 STA &93 ; creature_being_considered # Loop through creatures 4 through 0, one per turn &38d8 a5 a6 LDA &a6 ; room_object_type &38da c9 08 CMP #&08 &38dc 90 12 BCC &38f0 ; no_amulet_part_here # Is there a amulet in the room? &38de 20 09 3c JSR &3c09 ; plot_object # If so, remove its sprite by plotting it &38e1 e6 6c INC &6c ; amulet_part_colour &38e3 a5 6c LDA &6c ; amulet_part_colour &38e5 29 07 AND #&07 &38e7 aa TAX &38e8 bd c2 03 LDA &03c2,X ; amulet_color_table # Change the colour of the amulet part &38eb 85 a7 STA &a7 ; object_colour &38ed 20 09 3c JSR &3c09 ; plot_object # And plot its sprite again ; no_amulet_part_here &38f0 a9 00 LDA #&00 &38f2 85 9e STA &9e ; numbers_have_changed &38f4 a5 96 LDA &96 ; orchid_influence_timer_high &38f6 d0 0d BNE &3905 ; not_losing_orchid_influence &38f8 a4 88 LDY &88 ; orchid_influence_colour &38fa c0 02 CPY #&02 ; MAGENTA &38fc d0 03 BNE &3901 ; not_magenta_orchid &38fe 20 97 3a JSR &3a97 ; swap_keypresses # Restore keys when MAGENTA orchid runs out ; not_magenta_orchid &3901 85 88 STA &88 ; orchid_influence_colour # Remove orchid influence &3903 f0 22 BEQ &3927 ; set_player_body_colour ; not_losing_orchid_influence &3905 c6 85 DEC &85 ; orchid_influence_timer_low &3907 d0 20 BNE &3929 ; not_flashing_orchid_influence &3909 a9 14 LDA #&14 &390b 85 85 STA &85 ; orchid_influence_timer_low &390d c6 96 DEC &96 ; orchid_influence_timer_high &390f a5 96 LDA &96 ; orchid_influence_timer_high &3911 c9 05 CMP #&05 &3913 b0 14 BCS &3929 ; not_flashing_orchid_influence &3915 a5 88 LDA &88 ; orchid_influence_colour &3917 f0 05 BEQ &391e ; no_sound &3919 a2 58 LDX #&58 ; sound_4 &391b 20 a5 32 JSR &32a5 ; play_sound_from_first_table ; no_sound &391e e6 86 INC &86 ; orchid_flash_count &3920 a5 86 LDA &86 ; orchid_flash_count &3922 29 01 AND #&01 &3924 aa TAX &3925 b5 87 LDA &87,X ; white_or_orchid_colour ; set_player_body_colour &3927 85 8e STA &8e ; player_body_colour ; not_flashing_orchid_influence &3929 a5 93 LDA &93 ; creature_being_considered # Update either the orchid &392b c9 03 CMP #&03 &392d d0 05 BNE &3934 ; not_fire &392f 20 1d 41 JSR &411d ; handle_fire_and_big_creatures # or the FIRE and big creatures, 1 in 4 turns &3932 d0 0e BNE &3942 ; don't_do_orchid_stuff ; not_fire &3934 b0 06 BCS &393c ; update_orchid &3936 20 e8 34 JSR &34e8 ; handle_creature &3939 4c 42 39 JMP &3942 ; skip_orchid_update ; update_orchid &393c 20 99 3e JSR &3e99 ; handle_orchid_blooming &393f 20 fb 3e JSR &3efb ; plot_orchid_on_screen ; skip_orchid_update &3942 20 c9 3e JSR &3ec9 ; read_time &3945 a6 84 LDX &84 ; room_type &3947 bd 5d 3f LDA &3f5d,X ; room_types_state_table &394a 29 f8 AND #&f8 &394c 05 9a ORA &9a ; orchid_colour &394e 9d 5d 3f STA &3f5d,X ; room_types_state_table # Store orchid colour in table &3951 ad 81 01 LDA &0181 ; time_array + 1 &3954 0a ASL A &3955 0a ASL A &3956 0a ASL A &3957 0a ASL A &3958 8d 81 01 STA &0181 ; time_array + 1 &395b a5 99 LDA &99 ; orchid_stage &395d 0a ASL A &395e 0d 81 01 ORA &0181 ; time_array + 1 &3961 05 97 ORA &97; orchid_fading &3963 9d 8a 3f STA &3f8a,X ; state_of_orchid_in_rooms # Store orchid state in table &3966 a4 88 LDY &88 ; orchid_influence_colour &3968 a9 00 LDA #&00 &396a 85 eb STA &eb ; player_has_moved &396c a6 cc LDX &cc ; player_sprite &396e f0 04 BEQ &3974 ; orchid_sets_turns_required # If the player is WALKING, consider their speed &3970 e0 07 CPX #&07 ; FIGHTING &3972 d0 03 BNE &3977 ; is_unhappy_player # Player always has a turn when SITTING, FLYING or DEAD ; orchid_sets_turns_required &3974 b9 76 12 LDA &1276,Y ; turns_required_per_move_by_orchid_colour ; is_unhappy_player &3977 85 c9 STA &c9 ; turns_per_player_move &3979 20 ec 43 JSR &43ec ; move_player # Consider the player's move &397c 20 83 47 JSR &4783 ; walking_sound_effect # Play a sound if they're moving &397f a5 cc LDA &cc ; player_sprite &3981 f0 17 BEQ &399a ; is_walking # Don't attack creatures if player is only WALKING &3983 c9 07 CMP #&07 ; FIGHTING &3985 f0 03 BEQ &398a ; is_fighting &3987 4c 5a 3a JMP &3a5a ; skip_interaction_with_room # No creature interaction if SITTING, FLYING or DEAD ; is_fighting # If the player is FIGHTING, &398a a5 d2 LDA &d2 ; player_x &398c a4 c3 LDY &c3 ; player_horizontal_direction &398e f0 03 BEQ &3993 &3990 18 CLC &3991 69 09 ADC #&09 &3993 a2 03 LDX #&03 ; player_width_for_overlap_test &3995 a0 01 LDY #&01 # Interact with creatures by attacking them &3997 20 a8 3a JSR &3aa8 ; interact_with_creatures # (i.e. the player kills them) ; is_walking &399a a5 95 LDA &95 ; orchid_position_x # If the player is WALKING or FIGHTING, &399c 85 16 STA &16 ; target_x &399e a5 94 LDA &94 ; orchid_position_y &39a0 85 e2 STA &e2 ; taget_y &39a2 a5 d2 LDA &d2 ; player_x &39a4 18 CLC &39a5 69 04 ADC #&04 &39a7 85 15 STA &15 ; player_x_for_overlap_test &39a9 a2 05 LDX #&05 &39ab 86 e3 STX &e3 ; target_width &39ad ca DEX &39ae 86 eb STX &eb ; player_width_for_overlap_test &39b0 a9 10 LDA #&10 &39b2 85 d7 STA &d7 ; target_height &39b4 20 1c 37 JSR &371c ; does_player_overlap_target &39b7 b0 47 BCS &3a00 ; hasn't_touched_orchid # Has the player touched an orchid? &39b9 a5 99 LDA &99 ; orchid_stage &39bb c9 07 CMP #&07 &39bd d0 41 BNE &3a00 ; hasn't_touched_orchid # If so, is it in full bloom? &39bf a5 97 LDA &97; orchid_fading &39c1 d0 3d BNE &3a00 ; hasn't_touched_orchid # and hasn't already been touched? &39c3 e6 97 INC &97; orchid_fading &39c5 a2 00 LDX #&00 &39c7 86 85 STX &85 ; orchid_influence_timer_low &39c9 e8 INX &39ca 86 86 STX &86 ; orchid_flash_count &39cc a9 0c LDA #&0c &39ce 85 96 STA &96 ; orchid_influence_timer_high &39d0 a2 50 LDX #&50 ; sound_3 &39d2 20 a5 32 JSR &32a5 ; play_sound_from_first_table &39d5 a5 9a LDA &9a ; orchid_colour &39d7 a4 88 LDY &88 ; orchid_influence_colour &39d9 85 8e STA &8e ; player_body_colour &39db 85 88 STA &88 ; orchid_influence_colour # If so, colour the player accordingly &39dd c0 02 CPY #&02 ; MAGENTA &39df d0 03 BNE &39e4 ; not_magenta_orchid &39e1 20 97 3a JSR &3a97 ; swap_keypresses # Swap the keys if the orchid is MAGENTA, ; not_magenta_orchid &39e4 c9 04 CMP #&04 ; YELLOW &39e6 d0 11 BNE &39f9 ; not_yellow_orchid # If the orchid is YELLOW, &39e8 aa TAX ; SITTING &39e9 a5 c3 LDA &c3 ; player_horizontal_direction # Make the player look either left or right &39eb 20 84 3b JSR &3b84 ; set_player_direction_and_sprite # Set the player to be sitting down &39ee a9 06 LDA #&06 &39f0 85 96 STA &96 ; orchid_influence_timer_high &39f2 a9 1e LDA #&1e &39f4 85 c1 STA &c1 ; player_stun_counter # and stun them for a while &39f6 20 80 45 JSR &4580 ; not_yellow_orchid &39f9 c9 02 CMP #&02 ; MAGENTA &39fb d0 03 BNE &3a00 ; previous_orchid_wasn't_magenta &39fd 20 97 3a JSR &3a97 ; swap_keypresses # Restore the keys if previous orchid was MAGENTA ; previous_orchid_wasn't_magenta ; hasn't_touched_orchid &3a00 a9 10 LDA #&10 # Objects have width 4, height &10 &3a02 85 d7 STA &d7 ; target_height &3a04 a9 04 LDA #&04 &3a06 85 e3 STA &e3 ; target_width &3a08 a5 a6 LDA &a6 ; room_object_type &3a0a 30 45 BMI &3a51 ; no_object_in_room # Is there an object in the room? &3a0c a5 a4 LDA &a4 ; object_position_x &3a0e 85 16 STA &16 ; target_x &3a10 a5 a5 LDA &a5 ; object_position_y &3a12 85 e2 STA &e2 ; target_y &3a14 20 1c 37 JSR &371c ; does_player_overlap_target &3a17 b0 38 BCS &3a51 ; no_object_in_room # If so, has the player touched it? &3a19 20 09 3c JSR &3c09 ; plot_object # If so, remove object from screen &3a1c a5 a6 LDA &a6 ; room_object_type &3a1e c9 07 CMP #&07 ; LIFE &3a20 d0 0a BNE &3a2c ; not_extra_life # Is it a LIFE? &3a22 a5 6f LDA &6f ; life_counter &3a24 c9 09 CMP #&09 # If so, and the player hasn't already got 9 lives &3a26 f0 04 BEQ &3a2c ; not_extra_life &3a28 e6 6f INC &6f ; life_counter # give them another &3a2a e6 c0 INC &c0 ; lives_as_digit ; not_extra_life &3a2c a9 ff LDA #&ff &3a2e 85 a6 STA &a6 ; room_object_type &3a30 a4 a1 LDY &a1 ; player_room &3a32 b9 7a 29 LDA &297a,Y ; room_data_table &3a35 09 40 ORA #&40 # Mark object as collected &3a37 99 7a 29 STA &297a,Y ; room_data_table &3a3a a2 50 LDX #&50 ; sound_3 &3a3c 20 a5 32 JSR &32a5 ; play_sound_from_first_table &3a3f 20 37 33 JSR &3337 ; increase_score_by_one_hundred_and_tens # Score 100-170 points for its collection &3a42 a6 6b LDX &6b ; room_amulet_part &3a44 30 0b BMI &3a51 ; no_object_in_room # Is the object a amulet part? &3a46 a9 09 LDA #&09 &3a48 9d ca 03 STA &03ca,X ; amulet_parts_collected # If so, mark it as collected &3a4b 20 37 33 JSR &3337 ; increase_score_by_one_hundred_and_tens # Score another 100-170 points &3a4e 4c 4b 3c JMP &3c4b ; collect_amulet_part # and display the collection screen ; no_object_in_room &3a51 a5 15 LDA &15 ; player_x_for_overlap_test &3a53 a2 04 LDX #&04 ; player_width_for_overlap_test &3a55 a0 00 LDY #&00 # Interact with creatures without attacking them &3a57 20 a8 3a JSR &3aa8 ; interact_with_creatures # (i.e. they can kill the player this time) ; skip_interaction_with_room &3a5a a6 8e LDX &8e ; player_body_colour &3a5c bd 71 12 LDA &1271,X ; player_body_colour_to_video_ula_table &3a5f 8d 21 fe STA &fe21 ; Video ULA # Set palette for player's body &3a62 a5 c2 LDA &c2 ; player_has_changed &3a64 f0 03 BEQ &3a69 ; skip_update &3a66 20 45 46 JSR &4645 ; update_player_on_screen # Update the player on screen if necessary ; skip_update &3a69 a5 9e LDA &9e ; numbers_have_changed &3a6b f0 03 BEQ &3a70 ; numbers_haven't_changed &3a6d 20 d8 30 JSR &30d8 ; plot_score_and_lives # Update the score and life counter if necessary ; numbers_haven't_changed ; frame_rate_loop &3a70 a5 8f LDA &8f ; interrupt_ticker &3a72 30 fc BMI &3a70 ; frame_rate_loop # Ensure each frame takes at least 50ms &3a74 a5 a0 LDA &a0 ; player_has_tried_to_move_up # Has the player tried to move up? &3a76 f0 15 BEQ &3a8d ; not_at_cave &3a78 a5 a1 LDA &a1 ; player_room &3a7a c9 88 CMP #&88 &3a7c d0 0f BNE &3a8d ; not_at_cave # If so, is the player in the room with the cave? (&88) &3a7e a5 d2 LDA &d2 ; player_x &3a80 c9 d2 CMP #&d2 &3a82 d0 09 BNE &3a8d ; not_at_cave &3a84 a5 d4 LDA &d4 ; player_y &3a86 c9 6f CMP #&6f &3a88 d0 03 BNE &3a8d ; not_at_cave # If so, are they at the cave entrance? &3a8a 4c f0 42 JMP &42f0 ; game_over_routine # If so, game over ; not_at_cave ; pause_while_tab_pressed &3a8d a2 9f LDX #&9f ; TAB &3a8f 20 09 47 JSR &4709 ; check_for_keypress # Pause the game while TAB is held down &3a92 f0 f9 BEQ &3a8d ; pause_while_tab_pressed &3a94 4c cc 38 JMP &38cc ; main_game_loop # Otherwise go round the loop again! ; swap_keypresses &3a97 a6 8b LDX &8b ; key_left &3a99 a4 8a LDY &8a ; key_right &3a9b 84 8b STY &8b ; key_left &3a9d 86 8a STX &8a ; key_right &3a9f a6 8d LDX &8d ; key_up &3aa1 a4 8c LDY &8c ; key_down &3aa3 84 8d STY &8d ; key_up &3aa5 86 8c STX &8c ; key_down &3aa7 60 RTS ; interact_with_creatures &3aa8 85 15 STA &15 ; player_x_for_overlap_test &3aaa 86 eb STX &eb ; player_width_for_overlap_test &3aac 84 c5 STY &c5 ; player_is_fighting &3aae a9 0b LDA #&0b &3ab0 85 d6 STA &d6 ; creature_to_consider ; creature_interaction_loop # For each creature, &3ab2 a4 d6 LDY &d6 ; creature_to_consider &3ab4 b9 0c 33 LDA &330c,Y ; creature_room &3ab7 c5 a1 CMP &a1 ; player_room &3ab9 d0 50 BNE &3b0b ; to_next_creature # Is the creature in the same room as the player? &3abb b9 c4 32 LDA &32c4,Y ; creature_x &3abe 85 16 STA &16 ; target_x &3ac0 b9 d0 32 LDA &32d0,Y ; creature_y &3ac3 85 e2 STA &e2 ; target_y &3ac5 b9 dc 32 LDA &32dc,Y ; creature_sprite &3ac8 30 41 BMI &3b0b ; to_next_creature # Is there actually a creature? &3aca 18 CLC &3acb 79 e8 32 ADC &32e8,Y ; creature_frame &3ace aa TAX &3acf bd c1 40 LDA &40c1,X ; sprites_for_creatures_row_table &3ad2 85 d7 STA &d7 ; target_height &3ad4 a9 04 LDA #&04 &3ad6 e0 11 CPX #&11 ; TRIBESMAN # TRIBESMAN width = 4 &3ad8 f0 1c BEQ &3af6 ; set_width_of_creature &3ada e0 12 CPX #&12 ; TRIBESMAN &3adc f0 18 BEQ &3af6 ; set_width_of_creature &3ade a9 03 LDA #&03 # FIRE width = 3 &3ae0 e0 29 CPX #&29 ; FIRE &3ae2 b0 12 BCS &3af6 ; set_width_of_creature &3ae4 a9 06 LDA #&06 &3ae6 e0 28 CPX #&28 ; GUARDIAN # GUARDIAN width = 6 &3ae8 f0 0c BEQ &3af6 ; set_width_of_creature &3aea a9 0a LDA #&0a &3aec e0 1b CPX #&1b # Big creatures width = &a &3aee b0 06 BCS &3af6 ; set_width_of_creature &3af0 bd ed 40 LDA &40ed,X ; sprites_for_creatures_columns_table # Otherwise, width = creature sprite width / 8 &3af3 4a LSR A &3af4 4a LSR A &3af5 4a LSR A ; set_width_of_creature &3af6 85 e3 STA &e3 ; target_width &3af8 c9 05 CMP #&05 &3afa d0 02 BNE &3afe &3afc e6 16 INC &16 ; target_x &3afe 20 1c 37 JSR &371c ; does_player_overlap_target &3b01 b0 4b BCS &3b4e ; next_creature # Has the creature touched the player? &3b03 a6 d6 LDX &d6 ; creature_to_consider &3b05 a5 88 LDA &88 ; orchid_influence_colour # If so, is the player under the influence of an orchid? &3b07 f0 04 BEQ &3b0d ; consider_killing_player &3b09 e0 08 CPX #&08 ; guardian_slot # If not, or the creature is the GUARDIAN ; to_next_creature &3b0b d0 41 BNE &3b4e ; next_creature ; consider_killing_player &3b0d a5 c5 LDA &c5 ; player_is_fighting &3b0f d0 22 BNE &3b33 ; attack_creature &3b11 bd dc 32 LDA &32dc,X ; creature_sprite &3b14 c9 0b CMP #&0b # Is this creature APPEARING or DISAPPEARING? &3b16 90 36 BCC &3b4e ; next_creature # If so, ignore it and move to next creature &3b18 e0 09 CPX #&09 ; wolf_slot &3b1a f0 0d BEQ &3b29 ; certain_death # Is it the WOLF? &3b1c e0 03 CPX #&03 ; fire_slot &3b1e f0 09 BEQ &3b29 ; certain_death # the FIRE, &3b20 e0 08 CPX #&08 ; guardian_slot &3b22 f0 05 BEQ &3b29 ; certain_death # or the GUARDIAN? &3b24 bd 27 33 LDA &3327,X ; creature_attacked &3b27 10 25 BPL &3b4e ; next_creature # If not, escape death if creature has been attacked ; certain_death &3b29 20 56 3b JSR &3b56 ; kill_player # Otherwise, kill the player &3b2c a2 40 LDX #&40 ; sound_1 &3b2e 20 a5 32 JSR &32a5 ; play_sound_from_first_table # and play a sound &3b31 a6 d6 LDX &d6 ; creature_to_consider ; attack_creature &3b33 a5 c3 LDA &c3 ; player_horizontal_direction &3b35 9d 27 33 STA &3327,X ; creature_attacked # Mark the creature as attacked &3b38 e0 0a CPX #&0a ; hippo_slot &3b3a 90 05 BCC &3b41 ; not_a_hippo &3b3c bd f6 1d LDA &1df6,X ; hippo_charge_countdown - &a # If it's not a HIPPO that's about to charge, &3b3f d0 0d BNE &3b4e ; next_creature ; not_a_hippo &3b41 e0 04 CPX #&04 &3b43 90 09 BCC &3b4e ; next_creature # or a RHINO &3b45 e0 09 CPX #&09 ; wolf_slot &3b47 f0 05 BEQ &3b4e ; next_creature # (not the WOLF) &3b49 a2 c8 LDX #&c8 ; sound_9 &3b4b 20 a2 32 JSR &32a2 ; play_sound_from_second_table # then play an extra sound ; next_creature &3b4e c6 d6 DEC &d6 ; creature_to_consider &3b50 30 03 BMI &3b55 ; leave &3b52 4c b2 3a JMP &3ab2 ; creature_interaction_loop &3b55 60 RTS ; kill_player &3b56 a5 a1 LDA &a1 ; player_room &3b58 c9 88 CMP #&88 &3b5a d0 18 BNE &3b74 ; not_touching_guardian # Is this the room with the GUARDIAN? &3b5c a5 d4 LDA &d4 ; player_y &3b5e c9 8b CMP #&8b &3b60 d0 12 BNE &3b74 ; not_touching_guardian # Has the player moved up into the GUARDIAN? &3b62 18 CLC &3b63 69 04 ADC #&04 &3b65 85 d4 STA &d4 ; player_y # If so, move them down again &3b67 a5 d8 LDA &d8 ; player_screen_address_low &3b69 a6 d0 LDX &d0 ; player_screen_address_high &3b6b a0 04 LDY #&04 &3b6d 20 2c 47 JSR &472c ; increase_screen_address_by_y_rows &3b70 85 d8 STA &d8 ; player_screen_address_low &3b72 86 d0 STX &d0 ; player_screen_address_high ; not_touching_guardian &3b74 c6 c0 DEC &c0 ; lives_as_digit # Reduce the player's lives &3b76 c6 6f DEC &6f ; life_counter &3b78 10 04 BPL &3b7e ; lives_left &3b7a a9 00 LDA #&00 &3b7c 85 c0 STA &c0 ; lives_as_digit # Change the character to a space if none left ; lives_left &3b7e a5 c3 LDA &c3 ; player_horizontal_direction &3b80 49 0d EOR #&0d &3b82 a2 05 LDX #&05 ; FLYING # Set the player FLYING in the opposite direction ; set_player_direction_and_sprite &3b84 85 ca STA &ca ; player_direction &3b86 86 cc STX &cc ; player_sprite &3b88 86 c2 STX &c2 ; player_has_changed &3b8a a9 00 LDA #&00 &3b8c 85 ce STA &ce ; player_frame &3b8e a9 19 LDA #&19 &3b90 85 9f STA &9f ; fire_countdown # Reset the FIRE countdown &3b92 60 RTS ; flush_buffers &3b93 a9 0f LDA #&0f &3b95 a2 00 LDX #&00 # Flush all buffers &3b97 6c 0a 02 JMP (&020a) ; OSBYTE ; put_object_in_room &3b9a a5 6e LDA &6e ; game_seed # Seed the RNG using the room number and game seed &3b9c 85 c6 STA &c6 ; rnd_1 &3b9e 45 a1 EOR &a1 ; player_room &3ba0 85 c7 STA &c7 ; rnd_2 &3ba2 a5 a1 LDA &a1 ; player_room &3ba4 85 c8 STA &c8 ; rnd_3 &3ba6 a9 ff LDA #&ff &3ba8 85 a6 STA &a6 ; room_object_type &3baa 85 6b STA &6b ; room_amulet_part &3bac a6 a1 LDX &a1 ; player_room &3bae bd 7a 29 LDA &297a,X ; room_data_table &3bb1 30 07 BMI &3bba ; room_already_visited &3bb3 09 80 ORA #&80 # Mark room as having been visited &3bb5 9d 7a 29 STA &297a,X ; room_data_table &3bb8 e6 6d INC &6d ; rooms_visited ; room_already_visited &3bba 00 BRK ; random_number # Discard a deterministic number of random numbers &3bbb e0 01 CPX #&01 # to make the one finally used really "random" &3bbd ca DEX &3bbe b0 fa BCS &3bba ; room_already_visited ; get_unoccupied_screen_address # Find a place for the room object &3bc0 a2 4c LDX #&4c ; horizontal_range &3bc2 a0 20 LDY #&20 ; height &3bc4 a9 10 LDA #&10 ; width &3bc6 20 04 40 JSR &4004 ; get_random_screen_address &3bc9 30 f5 BMI &3bc0 ; get_unoccupied_screen_address &3bcb a0 03 LDY #&03 ; check_if_room_has_amulet_part_loop &3bcd b9 ca 03 LDA &03ca,Y ; amulet_parts_collected # Does the room have an uncollected amulet part? &3bd0 d0 07 BNE &3bd9 ; part_already_collected &3bd2 a5 a1 LDA &a1 ; player_room &3bd4 d9 bd 03 CMP &03bd,Y ; amulet_rooms &3bd7 f0 52 BEQ &3c2b ; room_has_amulet_part ; part_already_collected &3bd9 88 DEY &3bda 10 f1 BPL &3bcd ; check_if_room_has_amulet_part_loop &3bdc a4 a1 LDY &a1 ; player_room &3bde b9 7a 29 LDA &297a,Y ; room_data_table &3be1 29 40 AND #&40 &3be3 d0 45 BNE &3c2a ; object_has_already_been_collected # If not, has the object already been collected? &3be5 00 BRK ; random_number &3be6 29 07 AND #&07 &3be8 85 a6 STA &a6 ; room_object_type # If not, pick an object type at random &3bea a0 00 LDY #&00 &3bec c9 07 CMP #&07 ; LIFE # Is the object a LIFE? &3bee f0 04 BEQ &3bf4 &3bf0 00 BRK ; random_number &3bf1 29 03 AND #&03 # If not, pick a colour for it at random &3bf3 a8 TAY &3bf4 b9 e1 0c LDA &0ce1,Y ; object_colours_table &3bf7 85 a7 STA &a7 ; object_colour ; set_object_screen_address &3bf9 a5 eb LDA &eb ; screen_address_high &3bfb 85 a2 STA &a2 ; object_screen_address_high &3bfd a5 e3 LDA &e3 ; screen_address_low &3bff 85 a3 STA &a3 ; object_screen_address_low &3c01 a5 d6 LDA &d6 ; position_x &3c03 85 a4 STA &a4 ; object_position_x &3c05 a5 d7 LDA &d7 ; position_y &3c07 85 a5 STA &a5 ; object_position_y ; plot_object &3c09 a4 a6 LDY &a6 ; room_object_type &3c0b 30 1d BMI &3c2a ; object_has_already_been_collected # If there is an object to plot, plot it ; plot_object_skipping_collection_check &3c0d b9 65 12 LDA &1265,Y ; object_sprite_address_low_table &3c10 8d 75 40 STA &4075 ; sprite_data_address_low &3c13 a9 1c LDA #&1c &3c15 8d 76 40 STA &4076 ; sprite_data_address_high &3c18 a5 a7 LDA &a7 ; object_colour &3c1a 20 b4 40 JSR &40b4 ; split_a_into_pixel_values &3c1d a9 10 LDA #&10 &3c1f 85 70 STA &70 ; sprite_rows_to_plot &3c21 a4 a3 LDY &a3 ; object_screen_address_low &3c23 a6 a2 LDX &a2 ; object_screen_address_high &3c25 a9 20 LDA #&20 # 10 pixels wide; &20 = ((10/2)-1)*8 &3c27 4c 5c 35 JMP &355c ; into_plot_single_colour_sprite ; object_has_already_been_collected &3c2a 60 RTS ; room_has_amulet_part &3c2b 84 6b STY &6b ; room_amulet_part &3c2d 98 TYA &3c2e 09 08 ORA #&08 &3c30 85 a6 STA &a6 ; room_object_type &3c32 a9 03 LDA #&03 &3c34 85 6c STA &6c ; amulet_part_colour &3c36 85 a7 STA &a7 ; object_colour &3c38 a2 0b LDX #&0b &3c3a a9 07 LDA #&07 &3c3c a4 84 LDY &84 ; room_type &3c3e c0 09 CPY #&09 # Is it a clearing with a south entrance? &3c40 d0 03 BNE &3c45 # If so, amulet part is at (&16, &0b) &3c42 8a TXA # (bottom left of clearing) &3c43 a2 16 LDX #&16 &3c45 20 19 40 JSR &4019 ; calculate_screen_position # otherwise (&0b, &07) (left of clearing) &3c48 4c f9 3b JMP &3bf9 ; set_object_screen_address # Plot the amulet piece as per any other object ; collect_amulet_part &3c4b e6 92 INC &92 ; maximum_species &3c4d c6 6a DEC &6a ; amulet_parts_uncollected &3c4f 10 05 BPL &3c56 ; parts_still_to_collect # Has the player collected all four amulet parts? &3c51 a9 ff LDA #&ff &3c53 8d e4 32 STA &32e4 ; creature_sprite + 8 # If so, remove GUARDIAN ; parts_still_to_collect &3c56 20 5c 3c JSR &3c5c ; display_amulet_parts_collected_screen # Show the parts collected &3c59 4c 29 38 JMP &3829 ; entering_room # then return to the game ; display_amulet_parts_collected_screen &3c5c 20 33 3d JSR &3d33 ; clear_screen &3c5f a2 00 LDX #&00 &3c61 20 4f 3d JSR &3d4f ; plot_scenery_type_X # Plot title screen scenery (room type &00) &3c64 a9 03 LDA #&03 &3c66 85 cf STA &cf ; part_to_consider ; part_loop &3c68 a6 cf LDX &cf ; part_to_consider &3c6a bd ca 03 LDA &03ca,X ; amulet_parts_collected &3c6d f0 16 BEQ &3c85 ; next_part &3c6f bd a8 3c LDA &3ca8,X ; amulet_parts_screen_address_high_table &3c72 85 a2 STA &a2 ; object_screen_address_high &3c74 bd ac 3c LDA &3cac,X ; amulet_parts_screen_address_low_table &3c77 85 a3 STA &a3 ; object_screen_address_low &3c79 a9 3c LDA #&3c ; cyan, cyan &3c7b 85 a7 STA &a7 ; object_colour &3c7d 8a TXA &3c7e 18 CLC &3c7f 69 08 ADC #&08 &3c81 a8 TAY &3c82 20 0d 3c JSR &3c0d ; plot_object_skipping_collection_check # Plot collected amulet parts in cyan ; next_part &3c85 c6 cf DEC &cf ; part_to_consider &3c87 10 df BPL &3c68 ; part_loop &3c89 a9 18 LDA #&18 &3c8b 85 cf STA &cf ; number_of_notes ; collection_tune_loop # Play collection music &3c8d a6 cf LDX &cf ; number_of_notes &3c8f bd 72 30 LDA &3072,X ; collection_music &3c92 f0 03 BEQ &3c97 ; skip_note &3c94 20 54 30 JSR &3054 ; play_sound_on_three_channels ; skip_note &3c97 a9 f8 LDA #&f8 # Wait 400ms between notes &3c99 85 8f STA &8f ; interrupt_ticker ; wait_for_ticker &3c9b a5 8f LDA &8f ; interrupt_ticker &3c9d d0 fc BNE &3c9b ; wait_for_ticker &3c9f c6 cf DEC &cf ; number_of_notes &3ca1 10 ea BPL &3c8d ; collection_tune_loop &3ca3 a9 e6 LDA #&e6 # Wait 1300ms before returning to the game &3ca5 4c 13 47 JMP &4713 ; delay ; amulet_parts_screen_address_high_table &3ca8 63 63 68 68 ; amulet_parts_screen_address_low_table &3cac 1f 47 1f 47 ; room_sprites_address_low_table &3cb0 00 bc 5a 00 5f b6 80 06 00 12 60 93 e5 6b 7e 40 &3cc0 04 9a 1f 00 25 78 9a 9a 9a 00 00 03 fb a8 61 4b &3cd0 02 53 75 be 75 be ; room_sprites_address_high_table &3cd6 0a 04 06 03 07 0a 08 0b 0d 0e 0f 12 0c 14 15 17 &3ce6 18 18 1a 84 9b 84 18 18 18 00 00 89 9c 84 9b 8c &3cf6 1e 1f 9b a0 9b a0 ; room_sprites_single_colour_width_table + &13 &3cfc 98 48 38 10 10 80 80 00 30 48 48 48 70 00 00 48 &3d0c 48 48 48 ; restore_zero_page_routine &3d0f 85 76 STA &76 ; neither_pixel # Reset neither_pixel to zero &3d11 a9 50 LDA #&50 # Restore the screen ; swap_between_zero_page_subroutines &3d13 48 PHA &3d14 a9 13 LDA #&13 ; Wait for Vertical Retrace &3d16 20 f4 ff JSR &fff4 ; OSBYTE &3d19 a9 01 LDA #&01 # R1: Number of characters per line &3d1b 8d 00 fe STA &fe00 ; video register number &3d1e 68 PLA &3d1f 8d 01 fe STA &fe01 ; video register value &3d22 a0 67 LDY #&67 ; swap_between_zero_page_subroutines_loop &3d24 be b3 2a LDX &2ab3,Y ; alternate_zero_page_routine &3d27 b9 00 00 LDA &0000,Y ; zero_page_routine &3d2a 99 b3 2a STA &2ab3,Y ; alternate_zero_page_routine &3d2d 96 00 STX &00,Y ; zero_page_routine &3d2f 88 DEY &3d30 10 f2 BPL &3d24 ; swap_between_zero_page_subroutines_loop &3d32 60 RTS ; clear_screen &3d33 a9 49 LDA #&49 &3d35 85 77 STA &77 ; screen_address_high # Clear memory from &4900 to &7fff &3d37 a9 00 LDA #&00 &3d39 a8 TAY ; clear_screen_loop &3d3a 91 76 STA (&76),Y ; screen_address &3d3c c8 INY &3d3d d0 fb BNE &3d3a ; clear_screen_loop &3d3f e6 77 INC &77 ; screen_address_high &3d41 10 f7 BPL &3d3a ; clear_screen_loop &3d43 60 RTS ; each piece of scenery is packed in two bytes: ; first second ; ...18421 ........ lookup for screen_address_high ; 842..... ........ screen_address_low, top three bits 842..... ; ........ 84...... screen_address_low, next three bits ...18... ; screen_address_low is ORed with &7 .....421 ; ........ ..218421 scenery sprite ; plot_scenery &3d44 a6 a1 LDX &a1 ; player_room &3d46 bd 7a 29 LDA &297a,X ; room_data_table &3d49 29 3f AND #&3f &3d4b 85 84 STA &84 ; room_type &3d4d 0a ASL A &3d4e aa TAX ; plot_scenery_type_X &3d4f bd 1e 29 LDA &291e,X ; room_scenery_address_table &3d52 85 d6 STA &d6 ; room_data_address_low &3d54 bd 1f 29 LDA &291f,X ; room_scenery_address_table + 1 &3d57 85 d7 STA &d7 ; room_data_address_high &3d59 a9 00 LDA #&00 # Hide the screen &3d5b 85 c5 STA &c5 ; room_data_offset &3d5d 85 d1 STA &d1 ; duplicate_sprite &3d5f 20 13 3d JSR &3d13 ; swap_between_zero_page_subroutines # Use plot_column_of_rle_sprite_data_to_screen &3d62 20 33 3d JSR &3d33 ; clear_screen ; consider_next_room_sprite &3d65 a5 d1 LDA &d1 ; duplicate_sprite # Was the previous sprite a double? &3d67 d0 27 BNE &3d90 ; use_previous_sprite # If not, &3d69 a4 c5 LDY &c5 ; room_data_offset &3d6b b1 d6 LDA (&d6),Y ; room_data_address # Read a byte of room type data &3d6d f0 a0 BEQ &3d0f ; restore_zero_page_routine # Is it zero? If so, display the screen and leave &3d6f 48 PHA &3d70 29 1f AND #&1f # first_byte & &1f is lookup for screen_address_high &3d72 aa TAX &3d73 bd 79 2a LDA &2a79,X ; room_sprites_screen_address_table &3d76 85 eb STA &eb ; screen_address_high &3d78 68 PLA ; first_byte &3d79 29 e0 AND #&e0 &3d7b 85 e3 STA &e3 ; screen_address_low # first_byte & &e0 = screen_address_low, top three bits &3d7d c8 INY &3d7e b1 d6 LDA (&d6),Y ; room_data_address # Read a second byte of room type data &3d80 48 PHA &3d81 4a LSR A # Top two bits are next two bits of screen_address_low &3d82 4a LSR A &3d83 4a LSR A &3d84 09 07 ORA #&07 # Last three bits of screen_address_low always set &3d86 05 e3 ORA &e3 ; screen_address_low &3d88 85 e3 STA &e3 ; screen_address_low &3d8a 68 PLA ; second_byte &3d8b 29 3f AND #&3f # second_byte & &3f = scenery sprite number &3d8d c8 INY &3d8e 84 c5 STY &c5 ; room_data_offset ; use_previous_sprite &3d90 a0 00 LDY #&00 &3d92 84 d1 STY &d1 ; duplicate_sprite &3d94 c9 0a CMP #&0a # Scenery sprite &0a is plotted twice &3d96 d0 04 BNE &3d9c ; not_double_fern &3d98 a9 01 LDA #&01 &3d9a e6 d1 INC &d1 ; duplicate_sprite ; not_double_fern &3d9c 48 PHA ; sprite ; tweak_mountain_sprite # Tweak sprite for mountains &3d9d a0 0c LDY #&0c &3d9f a2 28 LDX #&28 &3da1 c9 19 CMP #&19 &3da3 b0 0c BCS &3db1 ; write_terminator &3da5 c9 16 CMP #&16 # Sprite &11 uses one palette &3da7 90 08 BCC &3db1 ; write_terminator &3da9 a0 19 LDY #&19 # Sprite &16, &17 and &18 use a different palette &3dab c9 18 CMP #&18 &3dad f0 02 BEQ &3db1 ; write_terminator &3daf a2 00 LDX #&00 # Cut off last few columns for sprites &16 and &17 ; write_terminator &3db1 8e ea 19 STX &19ea ; mountain_sprite_data + &150 # Alter sprite data to reflect this &3db4 a2 0c LDX #&0c ; copy_palette_loop &3db6 b9 ea 3f LDA &3fea,Y ; mountain_sprite_palettes &3db9 9d 9b 18 STA &189b,X ; mountain_sprite_data + 1 # Alter sprite palette &3dbc 88 DEY &3dbd ca DEX &3dbe 10 f6 BPL &3db6 ; copy_palette_loop &3dc0 68 PLA ; sprite &3dc1 48 PHA # Redundant code &3dc2 a8 TAY &3dc3 b9 8d 03 LDA &038d,Y ; room_sprites_height_table &3dc6 85 55 STA &55 ; room_sprite_top_height &3dc8 85 70 STA &70 ; sprite_rows_to_plot &3dca b9 e9 3c LDA &3ce9,Y ; room_sprites_single_colour_width_table &3dcd 85 72 STA &72 ; end_column &3dcf b9 b0 3c LDA &3cb0,Y ; room_sprites_address_low_table # Copy sprite address into both subroutines &3dd2 85 01 STA &01 ; spirite_data_address_low &3dd4 8d 75 40 STA &4075 ; sprite_data_address_low &3dd7 b9 d6 3c LDA &3cd6,Y ; room_sprites_address_high_table &3dda 48 PHA &3ddb 29 3f AND #&3f &3ddd 85 02 STA &02 ; sprite_data_address_high &3ddf 8d 76 40 STA &4076 ; sprite_data_address_high &3de2 a0 1f LDY #&1f ; copy_sprite_palette_into_twopixel_table &3de4 b1 01 LDA (&01),Y ; sprite_data_address # First 32 bytes of RLE sprite are the palette entries &3de6 99 80 01 STA &0180,Y ; scenery_twopixel_table # (starting at the 31st byte) &3de9 88 DEY &3dea d0 f8 BNE &3de4 ; copy_sprite_palette_into_twopixel_table &3dec 8c 80 01 STY &0180 ; scenery_twopixel_table &3def b1 01 LDA (&01),Y ; sprite_data_address # The 0th byte specifies the number of palette entries &3df1 a8 TAY &3df2 a2 00 LDX #&00 &3df4 c9 11 CMP #&11 # Are there more than &10 palette entries &3df6 b0 02 BCS &3dfa # If so, use a different bit split for data &3df8 a2 06 LDX #&06 &3dfa bd 88 3e LDA &3e88,X ; alternate_sprite_plotting_shift_instructions &3dfd 85 1d STA &1d ; shift_instructions &3dff bd 89 3e LDA &3e89,X ; alternate_sprite_plotting_shift_instructions + 1 &3e02 85 1e STA &1e ; shift_instructions + 1 &3e04 bd 8a 3e LDA &3e8a,X ; alternate_sprite_plotting_shift_instructions + 2 &3e07 85 1f STA &1f ; shift_instructions + 2 &3e09 bd 8b 3e LDA &3e8b,X ; alternate_sprite_plotting_shift_instructions + 3 &3e0c 85 20 STA &20 ; shift_instructions + 3 &3e0e bd 8c 3e LDA &3e8c,X ; alternate_sprite_plotting_shift_instructions + 4 &3e11 85 1c STA &1c ; bits_for_twopixel_data &3e13 bd 8d 3e LDA &3e8d,X ; alternate_sprite_plotting_shift_instructions + 5 &3e16 85 0d STA &0d ; bits_for_row_count &3e18 68 PLA ; room_sprites_address_high_table &3e19 30 31 BMI &3e4c ; single_colour_sprite # If the high bit is set, use single colour routine &3e1b 68 PLA ; sprite &3e1c a9 8a LDA #&8a ; TXA # &13 and &14 are set to fixed values prior to &3e1e 85 13 STA &13 ; unchanged_instructions # calling plot_column_of_rle_sprite_data_to_screen &3e20 a9 a2 LDA #&a2 ; LDX &3e22 85 14 STA &14 ; unchanged_instructions + 1 ; column_loop &3e24 a5 e3 LDA &e3 ; screen_address_low # Copy the screen address into the sprite routine &3e26 85 2b STA &2b ; screen_address_low &3e28 a5 eb LDA &eb ; screen_address_high &3e2a 85 2c STA &2c ; screen_address_high &3e2c a2 00 LDX #&00 &3e2e 86 e1 STX &e1 ; rows_plotted &3e30 ca DEX &3e31 86 e0 STX &e0 ; irrelevant # Redundant code &3e33 a9 c5 LDA #&c5 # Reset plotting routine for multiple loops &3e35 85 3a STA &3a ; end_of_run_branch_pointer &3e37 20 00 00 JSR &0000 ; plot_column_of_rle_sprite_data_to_screen # Plot a column of the sprite &3e3a a5 e3 LDA &e3 ; screen_address_low # Move right two pixels &3e3c 18 CLC &3e3d 69 08 ADC #&08 &3e3f 85 e3 STA &e3 ; screen_address_low &3e41 90 02 BCC &3e45 &3e43 e6 eb INC &eb ; screen_address_high &3e45 b1 01 LDA (&01),Y ; run_length_data_address # Is the next byte of RLE data zero? &3e47 d0 db BNE &3e24 ; column_loop # If not, continue with the next column &3e49 4c 65 3d JMP &3d65 ; consider_next_room_sprite # If so, move on to the next bit of scenery ; single_colour_sprite &3e4c 20 6f 3e JSR &3e6f ; set_pixels_to_yellow &3e4f a9 ff LDA #&ff ; black, black &3e51 85 76 STA &76 ; neither_pixel &3e53 68 PLA ; sprite &3e54 c9 24 CMP #&24 &3e56 b0 0f BCS &3e67 ; flipped_single_colour_sprite # Single colour sprites *can* be flipped &3e58 c9 1f CMP #&1f ; cave &3e5a d0 03 BNE &3e5f ; not_white &3e5c 20 77 3e JSR &3e77 ; set_pixels_to_white ; not_white &3e5f a5 72 LDA &72 ; end_column &3e61 20 5c 35 JSR &355c ; into_plot_single_colour_sprite # Use same plotting routine as for creatures &3e64 4c 65 3d JMP &3d65 ; consider_next_room_sprite # and then continue plotting the scenery ; flipped_single_colour_sprite &3e67 a5 72 LDA &72 ; end_column &3e69 20 68 35 JSR &3568 ; flip_sprite # Use same plotting routine as for creatures &3e6c 4c 65 3d JMP &3d65 ; consider_next_room_sprite # and then continue plotting the scenery ; set_pixels_to_yellow &3e6f a9 f0 LDA #&f0 ; yellow, yellow &3e71 a2 f5 LDX #&f5 ; yellow, black &3e73 a0 fa LDY #&fa ; black, yellow &3e75 d0 06 BNE &3e7d ; set_pixels ; set_pixels_to_white &3e77 a9 c0 LDA #&c0 ; white, white &3e79 a2 d5 LDX #&d5 ; white, black &3e7b a0 ea LDY #&ea ; black, white ; set_pixels &3e7d 85 79 STA &79 ; both_pixels &3e7f 86 78 STX &78 ; left_hand_pixel &3e81 84 77 STY &77 ; right_hand_pixels &3e83 a4 e3 LDY &e3 ; screen_address_low &3e85 a6 eb LDX &eb ; screen_address_high &3e87 60 RTS ; alternate_sprite_plotting_shift_instructions &3e88 0a 2a 2a 2a e0 1f ; ASL A, ROL A, ROL A, ROL A, &e0 for colours, &1f for rows &3e8e 4a 4a 4a 4a f0 0f ; LSR A, LSR A, LSR A, LSR A, &f0 for colours, &0f for rows ; time_for_writing &3e94 00 00 00 00 00 ; handle_orchid_blooming &3e99 a5 99 LDA &99 ; orchid_stage &3e9b 85 98 STA &98 ; previous_orchid_stage &3e9d 20 c9 3e JSR &3ec9 ; read_time &3ea0 a4 97 LDY &97; orchid_fading &3ea2 f0 2d BEQ &3ed1 ; orchid_isn't_fading &3ea4 c6 99 DEC &99 ; orchid_stage &3ea6 d0 36 BNE &3ede ; leave # Has the orchid finished fading? &3ea8 a9 00 LDA #&00 &3eaa 85 97 STA &97; orchid_fading ; pick_a_random_orchid_colour &3eac 00 BRK ; random_number &3ead 29 07 AND #&07 &3eaf c9 05 CMP #&05 &3eb1 b0 f9 BCS &3eac ; pick_a_random_orchid_colour &3eb3 85 9a STA &9a ; orchid_colour # If so, pick a colour for the next bloom &3eb5 00 BRK ; random_number &3eb6 aa TAX &3eb7 00 BRK ; random_number &3eb8 29 03 AND #&03 &3eba a8 TAY ; write_time &3ebb 8e 94 3e STX &3e94 ; time_for_writing &3ebe 8c 95 3e STY &3e95 ; time_for_writing + 1 # and set the system clock between &000 and &3ff &3ec1 a0 3e LDY #&3e ; time_for_writing &3ec3 a2 94 LDX #&94 &3ec5 a9 02 LDA #&02 ; Write system clock (TIME=) &3ec7 d0 05 BNE &3ece ; to_osword ; read_time &3ec9 a0 01 LDY #&01 ; Read system clock (=TIME) &3ecb a2 80 LDX #&80 &3ecd 98 TYA ; to_osword &3ece 6c 0c 02 JMP (&020c) ; OSWORD ; orchid_isn't_fading &3ed1 ad 81 01 LDA &0181 ; time_array + 1 &3ed4 a4 99 LDY &99 ; orchid_stage &3ed6 d0 07 BNE &3edf ; orchid_is_blooming &3ed8 c9 0a CMP #&0a # Has the clock reached &a00? &3eda 90 02 BCC &3ede ; leave &3edc e6 99 INC &99 ; orchid_stage # If so, start the orchid blooming ; leave &3ede 60 RTS ; orchid_is_blooming &3edf c0 07 CPY #&07 &3ee1 f0 0f BEQ &3ef2 ; orchid_at_full_bloom &3ee3 e6 99 INC &99 ; orchid_stage &3ee5 c0 06 CPY #&06 &3ee7 d0 f5 BNE &3ede ; leave # Is the orchid about to reach full bloom? &3ee9 00 BRK ; random_number &3eea 29 3f AND #&3f # If so, set the system clock between &000 and &03f &3eec aa TAX &3eed a0 00 LDY #&00 &3eef 4c bb 3e JMP &3ebb ; write_time ; orchid_at_full_bloom &3ef2 c9 00 CMP #&00 &3ef4 f0 e8 BEQ &3ede ; leave # Has the clock reached &100? &3ef6 a9 01 LDA #&01 &3ef8 85 97 STA &97; orchid_fading # If so, start the orchid fading ; leave &3efa 60 RTS ; plot_orchid_on_screen &3efb a5 99 LDA &99 ; orchid_stage &3efd c5 98 CMP &98 ; previous_orchid_stage &3eff f0 f9 BEQ &3efa ; leave &3f01 a0 00 LDY #&00 # Remove the previous orchid &3f03 20 08 3f JSR &3f08 ; plot_orchid ; plot_new_orchid &3f06 a0 01 LDY #&01 # Then plot the new one ; plot_orchid &3f08 a9 0c LDA #&0c &3f0a 20 b4 40 JSR &40b4 ; split_a_into_pixel_values &3f0d b6 98 LDX &98,Y ; previous_orchid_stage &3f0f 86 16 STX &16 ; stage &3f11 bd 8b 12 LDA &128b,X ; orchid_sprite_address_table &3f14 8d 75 40 STA &4075 ; sprite_data_address_low &3f17 a9 1d LDA #&1d &3f19 8d 76 40 STA &4076 ; sprite_data_address_high &3f1c bd 83 12 LDA &1283,X ; orchid_sprite_rows_table &3f1f 85 70 STA &70 ; sprite_rows_to_plot &3f21 a6 9c LDX &9c ; orchid_screen_address_high &3f23 a4 9b LDY &9b ; orchid_screen_address_low &3f25 a9 28 LDA #&28 # 12 pixels wide; &28 = ((12/2)-1)*8 &3f27 20 5c 35 JSR &355c ; into_plot_single_colour_sprite &3f2a a6 16 LDX &16 ; stage &3f2c e0 05 CPX #&05 &3f2e 90 ca BCC &3efa ; leave # Stage five onwards has a flower as well &3f30 bd 28 09 LDA &0928,X ; second_orchid_sprite_address_table - 5 &3f33 8d 75 40 STA &4075 ; sprite_data_address_low &3f36 a4 9a LDY &9a ; orchid_colour &3f38 b9 52 3f LDA &3f52,Y ; orchid_flower_colour_Table &3f3b 20 b4 40 JSR &40b4 ; split_a_into_pixel_values &3f3e bd ac 1b LDA &1bac,X ; second_orchid_sprite_rows_to_plot_table - 5 &3f41 85 70 STA &70 ; sprite_rows_to_plot &3f43 a6 9c LDX &9c ; orchid_screen_address_high &3f45 a5 9b LDA &9b ; orchid_screen_address_low &3f47 a0 08 LDY #&08 &3f49 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows &3f4c a8 TAY &3f4d a9 28 LDA #&28 # 12 pixels wide; &28 = ((12/2)-1)*8 &3f4f 4c 5c 35 JMP &355c ; into_plot_single_colour_sprite ; orchid_flower_colour_Table ; WW RR MM CC YY &3f52 3f 03 33 3c 0f ; unused ; KG KY YY GK GG GY &3f57 04 05 0f 08 0c 0d # Colourful leftovers? ; room_types_state_table ; byte & &07 = orchid colour ; byte & &f8 / 8 = pointer into location tables for orchid screen address &3f5d 0a 01 0b 13 14 1a 22 19 0c 2b 11 32 3c c4 49 52 &3f6d 5a 0c 1b 3a 11 39 62 42 6c 71 7a 0a 7c 72 81 8b &3f7d 91 13 9b a4 4c 31 4b 53 ac 8b 5b 4c b3 ; state_of_orchid_in_rooms ; byte & &01 fading ; byte & &0e orchid_stage ; byte & &f0 time / 256 &3f8a bb f0 f0 f0 ff ff ff f0 ff f0 f0 fd ff fd f0 ff &3f9a ff ff f0 ff f0 f2 ff fd ff f0 fd ff fd ff f0 f0 &3faa f0 00 f0 fd fd f0 f0 f0 fd f0 f0 ff f0 f0 ; orchid_position_x_table &3fb8 25 42 12 3e 0b 25 3d 37 1b 27 25 1a 20 05 19 32 &3fc8 14 0b 3d 16 0d 0e 23 1d 38 ; orchid_position_y_table &3fd1 08 0b 03 0b 03 07 0b 0b 03 0b 03 0b 0b 0b 0b 0b &3fe1 0b 0b 03 03 04 0b 0b 05 03 ; mountain_sprite_palettes ; KM KW WW WM WW MK MW MM MW WK WW WM WW &3fea 11 15 30 31 35 22 32 33 37 2a 3a 3b 3f # For scenery sprite &11 ; KK KM WW WM WM KK KW KK KM MK MW MK MM &3ff7 00 11 3f 2a 3b 00 15 00 11 22 37 22 33 # For scenery sprites &16, &17, &18 ; get_random_screen_address &4004 86 e3 STX &e3 ; horizontal_range &4006 85 e1 STA &e1 ; height &4008 84 e2 STY &e2 ; width ; pick_a_random_number_less_than_horizontal_range &400a 00 BRK ; random_number # Pick an X between 0 and (horizontal_range - 1) &400b 29 7f AND #&7f &400d c5 e3 CMP &e3 ; horizontal_range &400f b0 f9 BCS &400a ; pick_a_random_number_less_than_horizontal_range &4011 aa TAX ; pick_a_random_number_less_than_14 &4012 00 BRK ; random_number # And a Y between 0 and &13 &4013 29 1f AND #&1f &4015 c9 14 CMP #&14 &4017 b0 f9 BCS &4012 ; pick_a_random_number_less_than_14 ; calculate_screen_position &4019 a8 TAY &401a 29 01 AND #&01 &401c 4a LSR A &401d 6a ROR A &401e 85 e3 STA &e3 ; screen_address_low &4020 98 TYA &4021 0a ASL A &4022 0a ASL A &4023 0a ASL A &4024 69 17 ADC #&17 &4026 09 07 ORA #&07 &4028 85 d7 STA &d7 ; position_y # position_y = (Y * 8 + &17) or 7 &402a 8a TXA &402b 18 CLC &402c 69 b0 ADC #&b0 &402e 85 d6 STA &d6 ; position_x # position_x = X + &b0 &4030 8a TXA &4031 4a LSR A &4032 4a LSR A &4033 4a LSR A &4034 4a LSR A &4035 4a LSR A &4036 18 CLC &4037 79 52 40 ADC &4052,Y ; position_to_screen_address_high_table &403a 85 eb STA &eb ; screen_address_high # Calculate screen address corresponding to these &403c 8a TXA &403d 0a ASL A &403e 0a ASL A &403f 0a ASL A &4040 18 CLC &4041 69 07 ADC #&07 &4043 65 e3 ADC &e3 ; screen_address_low &4045 90 02 BCC &4049 &4047 e6 eb INC &eb ; screen_address_high &4049 85 e3 STA &e3 ; screen_address_low &404b a4 e2 LDY &e2 ; width &404d a6 eb LDX &eb ; screen_address_high &404f 4c 1b 30 JMP &301b ; check_for_scenery # and check that address for scenery ; position_to_screen_address_high_table &4052 4e 50 53 55 58 5a 5d 5f 62 64 67 69 6c 6e 71 73 &4062 76 78 7b 7d ; plot_single_colour_sprite &4066 86 73 STX &73 ; screen_address_high &4068 84 72 STY &72 ; screen_address_low &406a 8d af 40 STA &40af ; screen_start_column # Self-modifying code &406d a8 TAY # Y is the column offset (bytes from screen_address) &406e a9 00 LDA #&00 &4070 85 71 STA &71 ; sprite_data_offset ; byte_loop &4072 a6 71 LDX &71 ; sprite_data_offset &4074 bd ff ff LDA &ffff,X # actually LDA sprite_data_address, X # Get a byte of packed sprite data &4077 85 74 STA &74 ; byte_of_packed_sprite_data &4079 a9 04 LDA #&04 &407b 85 75 STA &75 ; chunks_left_in_byte_of_sprite_data ; chunk_loop &407d a5 74 LDA &74 ; byte_of_packed_sprite_data # Pull two bits off it &407f 29 03 AND #&03 &4081 aa TAX &4082 b5 76 LDA &76,X ; twopixel_values # Use those bits to get the colour of two pixels ; plot_single_colour_sprite_eor_instruction &4084 51 72 EOR (&72),Y ; screen_address # Either EOR with what's on screen # also LDX #&72 # Or just overwrite what's there &4086 91 72 STA (&72),Y ; screen_address &4088 46 74 LSR &74 ; byte_of_packed_sprite_data &408a 46 74 LSR &74 ; byte_of_packed_sprite_data &408c c0 00 CPY #&00 # actually CPY screen_end_column ; screen_end_column &408e f0 0d BEQ &409d ; next_row # Continue until the end of a row is reached &4090 98 TYA ; plot_single_colour_sprite_move_instruction &4091 e9 08 SBC #&08 # Move left two pixels # also ADC #&08 # or right two pixels &4093 a8 TAY ; consider_next_chunk &4094 c6 75 DEC &75 ; chunks_left_in_byte_of_sprite_data &4096 d0 e5 BNE &407d ; chunk_loop &4098 e6 71 INC &71 ; sprite_data_offset &409a 4c 72 40 JMP &4072 ; byte_loop # Go get another byte of packed sprite data ; next_row &409d c6 70 DEC &70 ; sprite_rows_to_plot &409f f0 12 BEQ &40b3 ; leave &40a1 a6 73 LDX &73 ; screen_address_high &40a3 a5 72 LDA &72 ; screen_address_low &40a5 a0 01 LDY #&01 ; plot_single_colour_sprite_move_function &40a7 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows # Move up (or down) a row &40aa 86 73 STX &73 ; screen_address_high &40ac 85 72 STA &72 ; screen_address_low &40ae a0 00 LDY #&00 # actually LDY screen_start_column # Reset the number of columns &40b0 4c 94 40 JMP &4094 ; consider_next_chunk ; leave &40b3 60 RTS ; split_a_into_pixel_values &40b4 85 79 STA &79 ; both_pixels &40b6 48 PHA &40b7 29 55 AND #&55 &40b9 85 77 STA &77 ; right_hand_pixel &40bb 68 PLA &40bc 29 aa AND #&aa &40be 85 78 STA &78 ; left_hand_pixel &40c0 60 RTS ; sprites_for_creatures_row_table &40c1 14 16 17 17 13 14 16 17 18 17 16 16 16 0d 0d 0e &40d1 0f 17 17 0c 0a 0e 10 0d 14 0c 10 11 11 11 11 17 &40e1 18 17 18 11 11 11 11 11 1c 14 14 14 ; sprites_for_creatures_columns_table &40ed 38 38 38 38 38 28 28 38 38 38 28 38 38 38 38 28 &40fd 28 28 28 38 38 28 28 38 38 28 28 ; species_colour_table ; YY RR MM CC YY CC MM RR &4108 0f 03 33 3c 0f 3c 33 03 ; rouse_hippo &4110 a9 23 LDA #&23 ; HIPPO &4112 9d dc 32 STA &32dc,X ; creature_sprite &4115 a9 0a LDA #&0a &4117 9d f6 1d STA &1df6,X ; hippo_charge_countdown - &a # When attacked, HIPPO waits ten turns before charging ; ignore_attack &411a 28 PLP &411b 10 4b BPL &4168 ; creature_hasn't_been_attacked ; handle_fire_and_big_creatures &411d 20 e8 34 JSR &34e8 ; handle_creature # Handle the FIRE, in slot 3 &4120 4c 7b 41 JMP &417b ; handle_big_creatures # then the big creatures in slots &4 - &b ; handle_big_creature &4123 20 ee 34 JSR &34ee ; plot_creature # Remove the creature from the screen &4126 a6 93 LDX &93 ; creature_being_considered &4128 bd f4 32 LDA &32f4,X ; creature_direction &412b e0 08 CPX #&08 ; guardian_slot &412d d0 05 BNE &4134 ; not_guardian &412f 49 01 EOR #&01 &4131 8d fc 32 STA &32fc ; creature_direction + 8 # Toggle the GUARDIAN's direction every update ; not_guardian &4134 bc 27 33 LDY &3327,X ; creature_attacked &4137 30 2f BMI &4168 ; creature_hasn't_been_attacked # Has the player attacked the creature? &4139 08 PHP &413a bc dc 32 LDY &32dc,X ; creature_sprite &413d c0 27 CPY #&27 ; SLEEPING_HIPPO # If so, is it a SLEEPING_HIPPO? If so, rouse it. &413f f0 cf BEQ &4110 ; rouse_hippo &4141 c0 28 CPY #&28 ; GUARDIAN # Ignore the attack if it is the GUARDIAN &4143 f0 d5 BEQ &411a ; ignore_attack &4145 c0 1f CPY #&1f ; WOLF # or the WOLF &4147 f0 d1 BEQ &411a ; ignore_attack &4149 c0 23 CPY #&23 ; HIPPO &414b d0 05 BNE &4152 ; not_hippo &414d bc f6 1d LDY &1df6,X ; hippo_charge_countdown - &a &4150 d0 c8 BNE &411a ; ignore_attack # or a HIPPO that has just been roused ; not_hippo &4152 28 PLP &4153 d0 09 BNE &415e ; creature_attacked_from_right &4155 c9 00 CMP #&00 &4157 f0 0c BEQ &4165 ; set_creature_movement_duration &4159 de f4 32 DEC &32f4,X ; creature_direction # Turn the creature when attacked &415c f0 07 BEQ &4165 ; set_creature_movement_duration ; creature_attacked_from_right &415e c9 01 CMP #&01 &4160 f0 03 BEQ &4165 ; set_creature_movement_duration &4162 fe f4 32 INC &32f4,X ; creature_direction ; set_creature_movement_duration &4165 9d 1b 33 STA &331b,X ; creature_movement_duration ; creature_hasn't_been_attacked &4168 a9 ff LDA #&ff &416a 9d 27 33 STA &3327,X ; creature_attacked # Big creatures can't be destroyed &416d 20 8b 41 JSR &418b ; update_big_creature &4170 bd 1b 33 LDA &331b,X ; creature_movement_duration # Has the creature just turned? &4173 30 03 BMI &4178 ; no_second_update &4175 20 8b 41 JSR &418b ; update_big_creature # If not, move it again - runs away twice as fast ; no_second_update &4178 20 ee 34 JSR &34ee ; plot_creature # Plot the creature again after updating it ; handle_big_creatures &417b e6 93 INC &93 ; creature_being_considered # Loop over creature slots &4 - &b &417d a5 93 LDA &93 ; creature_being_considered &417f c9 0c CMP #&0c &4181 f0 03 BEQ &4186 ; leave_with_slot_3 &4183 4c 23 41 JMP &4123 ; handle_big_creature ; leave_with_slot_3 &4186 a9 03 LDA #&03 &4188 85 93 STA &93 ; creature_being_considered &418a 60 RTS ; update_big_creature &418b 20 25 42 JSR &4225 ; consider_whether_to_turn_big_creature &418e b9 dc 32 LDA &32dc,Y ; creature_sprite &4191 c9 27 CMP #&27 # Is it a SLEEPING_HIPPO, the GUARDIAN or the FIRE? &4193 b0 13 BCS &41a8 ; leave # If so, leave &4195 c0 0a CPY #&0a ; hippo_slot &4197 90 0c BCC &41a5 ; not_hippo # Is it one of the two HIPPO slots? &4199 b9 f6 1d LDA &1df6,Y ; hippo_charge_countdown - &a &419c f0 07 BEQ &41a5 ; not_hippo &419e a6 93 LDX &93 ; creature_being_considered &41a0 de f6 1d DEC &1df6,X ; hippo_charge_countdown - &a &41a3 10 03 BPL &41a8 ; skip_moving_creature # If so, only move it when its countdown has expired ; not_hippo &41a5 20 bf 41 JSR &41bf ; move_big_creature ; skip_moving_creature &41a8 a6 93 LDX &93 ; creature_being_considered &41aa fe e8 32 INC &32e8,X ; creature_frame &41ad bd e8 32 LDA &32e8,X ; creature_frame &41b0 29 03 AND #&03 # Four frames for most big creatures, but &41b2 bc dc 32 LDY &32dc,X ; creature_sprite &41b5 c0 27 CPY #&27 : SLEEPING_HIPPO &41b7 90 02 BCC &41bb ; not_sleeping_hippo &41b9 29 00 AND #&00 # Only one frame for the SLEEPING_HIPPO ; not_sleeping_hippo &41bb 9d e8 32 STA &32e8,X ; creature_frame &41be 60 RTS ; move_big_creature &41bf a6 93 LDX &93 ; creature_being_considered &41c1 bd f4 32 LDA &32f4,X ; creature_direction &41c4 f0 33 BEQ &41f9 ; move_big_creature_left &41c6 bd c4 32 LDA &32c4,X ; creature_x &41c9 c9 f5 CMP #&f5 # Is the creature at the right of the screen? &41cb f0 18 BEQ &41e5 ; move_big_creature_right_a_room # If so, move it right a room &41cd fe c4 32 INC &32c4,X ; creature_x &41d0 be ac 32 LDX &32ac,Y ; creature_screen_address_high &41d3 b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &41d6 a0 08 LDY #&08 &41d8 20 1a 47 JSR &471a ; add_y_to_a_and_x # Otherwise, move it right two pixels ; set_big_creature_screen_address &41db a4 93 LDY &93 ; creature_being_considered &41dd 99 b8 32 STA &32b8,Y ; creature_screen_address_low &41e0 8a TXA &41e1 99 ac 32 STA &32ac,Y ; creature_screen_address_high &41e4 60 RTS ; move_big_creature_right_a_room &41e5 a9 87 LDA #&87 &41e7 9d b8 32 STA &32b8,X ; creature_screen_address_low &41ea de ac 32 DEC &32ac,X ; creature_screen_address_high &41ed de ac 32 DEC &32ac,X ; creature_screen_address_high &41f0 a9 b0 LDA #&b0 &41f2 9d c4 32 STA &32c4,X ; creature_x &41f5 fe 0c 33 INC &330c,X ; creature_room &41f8 60 RTS ; move_big_creature_left &41f9 bd c4 32 LDA &32c4,X ; creature_x &41fc c9 b0 CMP #&b0 # Is the creature at the left of the screen? &41fe f0 11 BEQ &4211 ; move_big_creature_left_a_room # If so, move it left a room &4200 de c4 32 DEC &32c4,X ; creature_x &4203 be ac 32 LDX &32ac,Y ; creature_screen_address_high &4206 b9 b8 32 LDA &32b8,Y ; creature_screen_address_low &4209 a0 08 LDY #&08 &420b 20 23 47 JSR &4723 ; subtract_y_from_a_and_x # Otherwise, move it left two pixels &420e 4c db 41 JMP &41db ; set_big_creature_screen_address ; move_big_creature_left_a_room &4211 fe ac 32 INC &32ac,X ; creature_screen_address_high &4214 fe ac 32 INC &32ac,X ; creature_screen_address_high &4217 a9 af LDA #&af &4219 9d b8 32 STA &32b8,X ; creature_screen_address_low &421c a9 f5 LDA #&f5 &421e 9d c4 32 STA &32c4,X ; creature_x &4221 de 0c 33 DEC &330c,X ; creature_room &4224 60 RTS ; consider_whether_to_turn_big_creature &4225 a4 93 LDY &93 ; creature_being_considered &4227 a9 00 LDA #&00 &4229 be d0 32 LDX &32d0,Y ; creature_y # Calculate where the creature must turn &422c e0 2f CPX #&2f &422e f0 02 BEQ &4232 ; creature_is_in_top_corridor &4230 a9 5a LDA #&5a ; creature_is_in_top_corridor &4232 be 0c 33 LDX &330c,Y ; creature_room &4235 85 75 STA &75 ; tmp &4237 bd 7a 29 LDA &297a,X ; room_data_table &423a 29 3f AND #&3f &423c 18 CLC &423d 65 75 ADC &75 ; tmp &423f be f4 32 LDX &32f4,Y ; creature_direction &4242 7d 83 42 ADC &4283,X ; direction_times_2d_table &4245 aa TAX # X = (&5a * corridor) + room_type + (&2d * direction) &4246 bd 4a 48 LDA &484a,X ; turning_point_table &4249 aa TAX &424a 29 7f AND #&7f &424c 69 b0 ADC #&b0 # Turning point is (turning_point_table(X) & &7f) + &b0 &424e d9 c4 32 CMP &32c4,Y ; creature_x # Has the creature reached the room's turning point? &4251 f0 14 BEQ &4267 ; at_turning_point &4253 8a TXA # If not, &4254 10 2c BPL &4282 ; leave # If the top bit of the turning data is set, &4256 be c4 32 LDX &32c4,Y ; creature_x # this is a room where creatures turn at its edges &4259 b9 f4 32 LDA &32f4,Y ; creature_direction &425c f0 05 BEQ &4263 ; creature_facing_left &425e e0 b0 CPX #&b0 # Is the creature at the left edge of the screen? &4260 f0 05 BEQ &4267 ; at_turning_point &4262 60 RTS ; creature_direction &4263 e0 f5 CPX #&f5 # Is the creature at the right edge of the screen? &4265 d0 1b BNE &4282 ; leave ; at_turning_point &4267 c0 0a CPY #&0a ; hippo_slot # Is the creature a HIPPO? &4269 90 0a BCC &4275 ; flip_creature_direction &426b a9 27 LDA #&27 ; SLEEPING_HIPPO # If so, make it sleep at the turning point &426d 99 dc 32 STA &32dc,Y ; creature_sprite &4270 a9 00 LDA #&00 &4272 99 f6 1d STA &1df6,Y ; hippo_charge_countdown - &a ; flip_creature_direction &4275 b9 f4 32 LDA &32f4,Y ; creature_direction # Flip the direction of the creature &4278 49 01 EOR #&01 &427a 99 f4 32 STA &32f4,Y ; creature_direction &427d a9 ff LDA #&ff &427f 99 1b 33 STA &331b,Y ; creature_movement_duration ; leave &4282 60 RTS ; direction_times_2d_table &4283 00 2d ; summon_hippos &4285 a0 0a LDY #&0a ; hippo_slot # Do so twice, once for creature slot &a &4287 20 8b 42 JSR &428b ; summon_hippo &428a c8 INY # and once for creature slot &b ; summon_hippo &428b 00 BRK ; random_number &428c 29 0f AND #&0f &428e d0 13 BNE &42a3 ; leave # One in sixteen chance to consider HIPPOs &4290 a5 a1 LDA &a1 ; player_room &4292 d9 0c 33 CMP &330c,Y ; creature_room # Is the creature in this slot in this room? &4295 f0 0c BEQ &42a3 ; leave &4297 a2 1f LDX #&1f &4299 a5 84 LDA &84 ; room_type # If not, can HIPPOs appear in this room? ; check_room_type_loop &429b dd 90 2a CMP &2a90,X ; room_types_in_which_hippos_can_appear &429e f0 04 BEQ &42a4 ; hippo_can_appear_in_room &42a0 ca DEX &42a1 10 f8 BPL &429b ; check_room_type_loop ; leave &42a3 60 RTS ; hippo_can_appear_in_room &42a4 a5 a1 LDA &a1 ; player_room &42a6 99 0c 33 STA &330c,Y ; creature_room &42a9 e0 1d CPX #&1d # Room type determines where hippo appears horizontally &42ab b0 08 BCS &42b5 ; hippo_at_right_of_screen &42ad e0 18 CPX #&18 &42af b0 08 BCS &42b9 ; hippo_at_left_of_screen &42b1 a2 02 LDX #&02 &42b3 d0 06 BNE &42bb ; hippo_at_middle_of_screen ; hippo_at_right_of_screen &42b5 a2 04 LDX #&04 &42b7 d0 02 BNE &42bb ; choose_top_or_bottom_corridor ; hippo_at_left_of_screen &42b9 a2 00 LDX #&00 ; hippo_at_middle_of_screen ; choose_top_or_bottom_corridor &42bb ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &42be 10 01 BPL &42c1 ; set_hippo_details_from_table &42c0 e8 INX # Hippo appears in bottom corridor 1 in 2 times ; set_hippo_details_from_table &42c1 bd b3 03 LDA &03b3,X ; hippo_x_table &42c4 99 c4 32 STA &32c4,Y ; creature_x # Set initial position of hippo &42c7 bd ce 03 LDA &03ce,X ; hippo_y_table &42ca 99 d0 32 STA &32d0,Y ; creature_y &42cd bd d4 03 LDA &03d4,X ; hippo_screen_address_high_table &42d0 99 ac 32 STA &32ac,Y ; creature_screen_address_high &42d3 bd da 03 LDA &03da,X ; hippo_screen_address_low_table &42d6 99 b8 32 STA &32b8,Y ; creature_screen_address_low &42d9 a9 23 LDA #&23 ; HIPPO &42db 99 dc 32 STA &32dc,Y ; creature_sprite &42de 00 BRK ; random_number &42df 99 27 33 STA &3327,Y ; creature_attacked # This doesn't make much difference to behaviour &42e2 29 01 AND #&01 &42e4 99 f4 32 STA &32f4,Y ; creature_direction # Set the HIPPO moving in a random direction &42e7 60 RTS ; unused_game_over_routine &42e8 20 5c 3c JSR &3c5c ; display_amulet_parts_collected_screen # Unused code &42eb 4c f0 42 JMP &42f0 ; game_over_routine ; game_over_routine_from_subroutine &42ee 68 PLA # Pop out of parent routine when finished &42ef 68 PLA ; game_over_routine &42f0 20 a2 30 JSR &30a2 ; play_game_over_music # Play game over music &42f3 a5 6d LDA &6d ; rooms_visited &42f5 4a LSR A # Score 0.25% for each room visited, bar the first &42f6 4a LSR A # (so 63.75% for all 256 rooms) &42f7 a0 03 LDY #&03 &42f9 18 CLC ; count_amulet_parts_loop &42fa 79 ca 03 ADC &03ca,Y ; amulet_parts_collected # Score 9% for each amulet part collected &42fd 88 DEY # (so 36% for all four) &42fe 10 fa BPL &42fa ; count_amulet_parts_loop &4300 a8 TAY &4301 f0 15 BEQ &4318 ; skip_conversion ; convert_percentage_into_figures_loop # Convert the score into two figures &4303 ee 56 32 INC &3256 ; percentage_complete_low &4306 ad 56 32 LDA &3256 ; percentage_complete_low &4309 c9 1a CMP #&1a &430b d0 08 BNE &4315 &430d ee 55 32 INC &3255 ; percentage_complete_high &4310 a9 10 LDA #&10 &4312 8d 56 32 STA &3256 ; percentage_complete_low &4315 88 DEY &4316 d0 eb BNE &4303 ; convert_percentage_into_figures_loop # Note that it is not possible to score 100%! ; skip_conversion &4318 20 33 3d JSR &3d33 ; clear_screen &431b a2 0a LDX #&0a &431d a0 0d LDY #&0d &431f 20 dc 30 JSR &30dc ; plot_text # Display "Game Over", "Adventure Completed", "00%" &4322 a9 96 LDA #&96 # Wait 5300ms before displaying Hall of Fame &4324 20 13 47 JSR &4713 ; delay &4327 a9 00 LDA #&00 &4329 85 6f STA &6f ; hall_of_fame_position &432b a2 2a LDX #&2a # Starting with 4th place, compare the player's score &432d 86 9d STX &9d ; hall_of_fame_offset # against those in the Hall of Fame ; compare_with_hall_of_fame_position_loop &432f a0 05 LDY #&05 &4331 a6 9d LDX &9d ; hall_of_fame_offset ; compare_with_hall_of_fame_digit_loop &4333 bd f0 31 LDA &31f0,X ; lower_score &4336 dd e2 31 CMP &31e2,X ; higher_score &4339 90 2b BCC &4366 ; player_scored_lower &433b f0 02 BEQ &433f ; consider_next_digit &433d b0 04 BCS &4343 ; player_scored_higher ; consider_next_digit &433f e8 INX &4340 88 DEY &4341 10 f0 BPL &4333 ; compare_with_hall_of_fame_digit_loop ; player_scored_higher # If the player scored higher, &4343 a6 9d LDX &9d ; hall_of_fame_offset &4345 a0 09 LDY #&09 ; shuffle_scores_down_a_place_loop # shuffle the beaten score down a place &4347 bd f0 31 LDA &31f0,X ; lower_score &434a 48 PHA &434b bd e2 31 LDA &31e2,X ; higher_score &434e 9d f0 31 STA &31f0,X ; lower_score &4351 68 PLA &4352 9d e2 31 STA &31e2,X ; higher_score &4355 e8 INX &4356 88 DEY &4357 10 ee BPL &4347 ; shuffle_scores_down_a_place_loop &4359 a5 9d LDA &9d ; hall_of_fame_offset &435b 38 SEC &435c e9 0e SBC #&0e &435e 85 9d STA &9d ; hall_of_fame_offset &4360 90 08 BCC &436a ; player_entered_hall_of_fame &4362 e6 6f INC &6f ; hall_of_fame_position &4364 d0 c9 BNE &432f ; compare_with_hall_of_fame_position_loop # Consider higher scores, if there are any ; player_scored_lower &4366 a5 6f LDA &6f ; hall_of_fame_position # Has the player entered the hall of fame? &4368 f0 7f BEQ &43e9 ; to_reset_game # If not, restart the game ; player_entered_hall_of_fame &436a a5 9d LDA &9d ; hall_of_fame_offset &436c 18 CLC &436d 69 0e ADC #&0e &436f 85 9d STA &9d ; hall_of_fame_offset &4371 aa TAX &4372 a0 00 LDY #&00 ; copy_position_into_text &4374 bd de 31 LDA &31de,X ; players_position # Copy the position the player entered, e.g. "1st" &4377 99 75 32 STA &3275,Y ; position_in_text # into the text "QQQ highest" &437a e8 INX &437b c8 INY &437c c0 03 CPY #&03 &437e d0 f4 BNE &4374 ; copy_position_into_text_loop &4380 a5 9d LDA &9d ; hall_of_fame_offset &4382 aa TAX &4383 18 CLC &4384 69 17 ADC #&17 &4386 8d bd 31 STA &31bd ; text_offset_table + 13 # Make text string 13 point at initials for position &4389 a9 00 LDA #&00 &438b 9d ea 31 STA &31ea,X ; position_initials + 1 &438e 9d eb 31 STA &31eb,X ; position_initials + 2 &4391 a9 41 LDA #&41 &4393 9d e9 31 STA &31e9,X ; position_initials # Set initials to be "A " &4396 20 33 3d JSR &3d33 ; clear_screen &4399 a2 00 LDX #&00 &439b 20 4f 3d JSR &3d4f ; plot_scenery_type_X # Plot title screen scenery (room type &00) &439e a2 0d LDX #&0d &43a0 a0 14 LDY #&14 &43a2 20 dc 30 JSR &30dc ; plot_text # Display "Congratulations" through to initials &43a5 a9 02 LDA #&02 &43a7 85 6f STA &6f ; initials_to_enter ; enter_initials_loop &43a9 a9 fe LDA #&fe # Wait 100ms between keypresses &43ab 20 13 47 JSR &4713 ; delay &43ae a6 8d LDX &8d ; key_up &43b0 20 09 47 JSR &4709 ; check_for_keypress &43b3 d0 05 BNE &43ba ; no_key_up # If the player presses UP, increase the character &43b5 a6 9d LDX &9d ; hall_of_fame_offset &43b7 fe e9 31 INC &31e9,X ; position_initials # (no bounds checking, but it wraps around reasonably) ; no_key_up &43ba a6 8c LDX &8c ; key_down &43bc 20 09 47 JSR &4709 ; check_for_keypress &43bf d0 05 BNE &43c6 ; no_key_down # If the player presses DOWN, decrease the character &43c1 a6 9d LDX &9d ; hall_of_fame_offset &43c3 de e9 31 DEC &31e9,X ; position_initials ; no_key_down &43c6 a2 12 LDX #&12 &43c8 a0 14 LDY #&14 &43ca 20 dc 30 JSR &30dc ; plot_text # Display "your initials" (unnecessarily) and initials &43cd a2 ff LDX #&ff ; SHIFT &43cf 20 09 47 JSR &4709 ; check_for_keypress &43d2 d0 d5 BNE &43a9 ; enter_initials_loop # If the player presses SHIFT, move to next initial &43d4 e6 9d INC &9d ; hall_of_fame_offset &43d6 c6 6f DEC &6f ; initials_to_enter &43d8 30 0f BMI &43e9 ; to_reset_game # If three have been entered, start the game again &43da a6 9d LDX &9d ; hall_of_fame_offset &43dc bd e8 31 LDA &31e8,X ; position_initials &43df 9d e9 31 STA &31e9,X ; position_initials + 1 # Otherwise, copy the previous letter for the next &43e2 a9 f0 LDA #&f0 # Wait 800ms before moving on to next initial &43e4 20 13 47 JSR &4713 ; delay &43e7 f0 c0 BEQ &43a9 ; enter_initials_loop ; to_reset_game &43e9 4c 4d 37 JMP &374d ; reset_game ; move_player &43ec a5 d0 LDA &d0 ; player_screen_address_high # Note the player's previous state &43ee 85 d1 STA &d1 ; previous_player_screen_address_high &43f0 a5 d8 LDA &d8 ; player_screen_address_low &43f2 85 d9 STA &d9 ; previous_player_screen_address_low &43f4 a5 d2 LDA &d2 ; player_x &43f6 85 d3 STA &d3 ; previous_player_x &43f8 a5 d4 LDA &d4 ; player_y &43fa 85 d5 STA &d5 ; previous_player_y &43fc a5 ca LDA &ca ; player_direction &43fe 85 cb STA &cb ; previous_player_direction &4400 a5 cc LDA &cc ; player_sprite &4402 85 cd STA &cd ; previous_player_sprite &4404 a5 ce LDA &ce ; player_frame &4406 85 cf STA &cf ; previous_player_frame &4408 a9 00 LDA #&00 &440a 85 c2 STA &c2 ; player_has_changed &440c 85 a0 STA &a0 ; player_has_tried_to_move_up &440e e6 e0 INC &e0 ; player_move_counter &4410 a6 e0 LDX &e0 ; player_move_counter &4412 e4 c9 CPX &c9 ; turns_per_player_move &4414 90 38 BCC &444e ; leave # Can the player make a move yet? If not, leave &4416 85 e0 STA &e0 ; player_move_counter &4418 85 c4 STA &c4 ; player_frame_has_been_updated &441a a5 cc LDA &cc ; player_sprite &441c f0 6b BEQ &4489 ; try_moving_up_and_down # If the player is WALKING &441e c9 07 CMP #&07 : FIGHTING &4420 f0 67 BEQ &4489 ; try_moving_up_and_down # or FIGHTING, then allow them to move. &4422 c9 05 CMP #&05 ; FLYING &4424 f0 31 BEQ &4457 ; player_is_flying # If the player is SITTING or DEAD, &4426 a5 88 LDA &88 ; orchid_influence_colour &4428 d0 24 BNE &444e ; leave # Don't allow the player to move while YELLOW &442a e6 c1 INC &c1 ; player_stun_counter &442c a5 c1 LDA &c1 ; player_stun_counter &442e c9 3c CMP #&3c &4430 d0 1c BNE &444e ; leave # Keep the player SITTING or DEAD for &3c turns &4432 a5 cc LDA &cc ; player_sprite &4434 c9 06 CMP #&06 ; DEAD # Is the player DEAD? &4436 d0 03 BNE &443b ; continue_game &4438 4c ee 42 JMP &42ee ; game_over_routine_from_subroutine # If so, game over ; continue_game &443b e6 9e INC &9e ; numbers_have_changed # Update life counter after player stops SITTING &443d a5 6f LDA &6f ; life_counter &443f 30 0e BMI &444f ; no_lives_left # If the player still has lives left, &4441 a9 01 LDA #&01 &4443 a2 00 LDX #&00 # Set them WALKING again ; set_player_sprite &4445 86 cc STX &cc ; player_sprite &4447 85 c2 STA &c2 ; player_has_changed &4449 d0 03 BNE &444e ; leave # If the player hasn't yet had a chance to, &444b 4c e0 45 JMP &45e0 ; check_for_shift_keypress # allow them to start FIGHTING ; leave &444e 60 RTS ; no_lives_left &444f a9 01 LDA #&01 # Stun the player, so the game isn't over immediately &4451 85 c1 STA &c1 ; player_stun_counter &4453 a2 06 LDX #&06 ; DEAD # but mark the player as DEAD, so it will be soon &4455 d0 ee BNE &4445 ; set_player_sprite ; player_is_flying # If the player is FLYING, force their movement &4457 a5 ca LDA &ca ; player_direction &4459 d0 03 BNE &445e ; to_try_moving_right &445b 4c 96 45 JMP &4596 ; try_moving_left_without_key_check ; to_try_moving_right &445e 4c 34 45 JMP &4534 ; try_moving_right ; move_down_a_room &4461 a9 17 LDA #&17 &4463 85 d4 STA &d4 ; player_y &4465 a5 cc LDA &cc ; player_sprite &4467 c9 07 CMP #&07 ; FIGHTING &4469 f0 04 BEQ &446f ; skip_direction_set &446b a9 1e LDA #&1e ; DOWN &446d 85 ca STA &ca ; player_direction # Player faces down if not FIGHTING ; skip_direction_set &446f a6 d0 LDX &d0 ; player_screen_address_high &4471 a5 d8 LDA &d8 ; player_screen_address_low &4473 a0 98 LDY #&98 &4475 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows # Move the player to the top of the next room &4478 a0 10 LDY #&10 # and increase the room number by &10 ; change_room &447a 85 d8 STA &d8 ; player_screen_address_low &447c 86 d0 STX &d0 ; player_screen_address_high &447e 98 TYA &447f 18 CLC &4480 65 a1 ADC &a1 ; player_room &4482 85 a1 STA &a1 ; player_room &4484 68 PLA &4485 68 PLA &4486 4c 29 38 JMP &3829 ; entering_room ; try_moving_up_and_down &4489 a6 8d LDX &8d ; key_up &448b 20 09 47 JSR &4709 ; check_for_keypress &448e f0 50 BEQ &44e0 ; try_moving_up &4490 a6 8c LDX &8c ; key_down &4492 20 09 47 JSR &4709 ; check_for_keypress &4495 f0 03 BEQ &449a ; try_moving_down ; to_try_moving_left_and_right &4497 4c 23 45 JMP &4523 ; try_moving_left_and_right ; try_moving_down # If DOWN is pressed, and UP is not pressed: &449a a5 d4 LDA &d4 ; player_y &449c c9 af CMP #&af &449e f0 c1 BEQ &4461 ; move_down_a_room # Has the player moved out of the room? &44a0 a5 d8 LDA &d8 ; player_screen_address_low &44a2 a6 d0 LDX &d0 ; player_screen_address_high &44a4 a0 04 LDY #&04 &44a6 20 2c 47 JSR &472c ; increase_screen_address_by_y_rows &44a9 20 5e 47 JSR &475e ; check_for_scenery_in_centre_of_player &44ac 30 e9 BMI &4497 ; to_try_moving_left_and_right # If not, check they haven't hit scenery &44ae a9 1e LDA #&1e ; DOWN &44b0 85 ca STA &ca ; player_direction # Player faces down &44b2 a5 d4 LDA &d4 ; player_y &44b4 18 CLC &44b5 69 04 ADC #&04 &44b7 85 d4 STA &d4 ; player_y &44b9 a5 d8 LDA &d8 ; player_screen_address_low &44bb a6 d0 LDX &d0 ; player_screen_address_high &44bd a0 04 LDY #&04 &44bf 20 2c 47 JSR &472c ; increase_screen_address_by_y_rows # Move the player down four pixels &44c2 4c 11 45 JMP &4511 ; store_player_address ; move_up_a_room &44c5 a9 af LDA #&af &44c7 85 d4 STA &d4 ; player_y &44c9 a5 cc LDA &cc ; player_sprite &44cb c9 07 CMP #&07 ; FIGHTING &44cd f0 04 BEQ &44d3 ; skip_setting_direction &44cf a9 1a LDA #&1a ; UP &44d1 85 ca STA &ca ; player_direction # Player faces up if not FIGHTING ; skip_setting_direction &44d3 a6 d0 LDX &d0 ; player_screen_address_high &44d5 a5 d8 LDA &d8 ; player_screen_address_low &44d7 a0 98 LDY #&98 &44d9 20 2c 47 JSR &472c ; increase_screen_address_by_y_rows # Move the player to the bottom of the next room &44dc a0 f0 LDY #&f0 # and decrease the room number by &10 &44de d0 9a BNE &447a ; change_room ; try_moving_up &44e0 a6 8c LDX &8c ; key_down &44e2 20 09 47 JSR &4709 ; check_for_keypress &44e5 f0 3c BEQ &4523 ; try_moving_left_and_right # If UP is pressed, and DOWN is not pressed: &44e7 e6 a0 INC &a0 ; player_has_tried_to_move_up # Note the player has moved up for the cave room &44e9 a5 d4 LDA &d4 ; player_y &44eb c9 17 CMP #&17 &44ed f0 d6 BEQ &44c5 ; move_up_a_room # Has the player moved out of the room? &44ef a5 d8 LDA &d8 ; player_screen_address_low &44f1 a6 d0 LDX &d0 ; player_screen_address_high &44f3 a0 16 LDY #&16 &44f5 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows &44f8 20 5e 47 JSR &475e ; check_for_scenery_in_centre_of_player &44fb 30 26 BMI &4523 ; can't_move_up # If not, check they haven't hit scenery &44fd a9 1a LDA #&1a ; UP &44ff 85 ca STA &ca ; player_direction # Player faces up &4501 a5 d4 LDA &d4 ; player_y &4503 38 SEC &4504 e9 04 SBC #&04 &4506 85 d4 STA &d4 ; player_y &4508 a5 d8 LDA &d8 ; player_screen_address_low &450a a6 d0 LDX &d0 ; player_screen_address_high &450c a0 04 LDY #&04 &450e 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows # Move the player up by four pixels ; store_player_address &4511 85 d8 STA &d8 ; player_screen_address_low &4513 86 d0 STX &d0 ; player_screen_address_high &4515 e6 ce INC &ce ; player_frame &4517 a5 ce LDA &ce ; player_frame &4519 29 03 AND #&03 &451b 85 ce STA &ce ; player_frame &451d e6 c4 INC &c4 ; player_frame_has_been_updated &451f e6 c2 INC &c2 ; player_has_changed &4521 e6 eb INC &eb ; player_has_moved ; try_moving_left_and_right &4523 a6 8b LDX &8b ; key_left &4525 20 09 47 JSR &4709 ; check_for_keypress &4528 f0 65 BEQ &458f ; try_moving_left &452a a6 8a LDX &8a ; key_right &452c 20 09 47 JSR &4709 ; check_for_keypress &452f f0 03 BEQ &4534 ; try_moving_right &4531 4c dc 45 JMP &45dc ; try_sword_movement ; try_moving_right # If RIGHT is pressed, and LEFT is not pressed: &4534 a5 d2 LDA &d2 ; player_x &4536 c9 f7 CMP #&f7 &4538 f0 31 BEQ &456b ; left_or_right_edge_of_room # Has the player moved out of the room? &453a a5 d8 LDA &d8 ; player_screen_address_low &453c a6 d0 LDX &d0 ; player_screen_address_high &453e a0 48 LDY #&48 &4540 20 1a 47 JSR &471a ; add_y_to_a_and_x &4543 a0 16 LDY #&16 &4545 84 e1 STY &e1 ; height &4547 a0 00 LDY #&00 ; width &4549 20 1b 30 JSR &301b ; check_for_scenery &454c 30 14 BMI &4562 ; can't_move_left_or_right # If not, check they haven't hit scenery &454e a9 0d LDA #&0d ; RIGHT &4550 85 ca STA &ca ; player_direction # Player faces right &4552 85 c3 STA &c3 ; player_horizontal_direction &4554 e6 d2 INC &d2 ; player_x &4556 a5 d8 LDA &d8 ; player_screen_address_low &4558 a6 d0 LDX &d0 ; player_screen_address_high &455a a0 08 LDY #&08 &455c 20 1a 47 JSR &471a ; add_y_to_a_and_x # Move the player right by two pixels &455f 4c c1 45 JMP &45c1 ; store_addresses ; can't_move_left_or_right &4562 a6 cc LDX &cc ; player_sprite &4564 e0 05 CPX #&05 ; FLYING # If the player hits scenery while FLYING, stop them &4566 f0 09 BEQ &4571 ; make_player_sit &4568 4c dc 45 JMP &45dc ; try_sword_movement # Otherwise, consider sword fighting ; left_or_right_edge_of_room &456b a6 cc LDX &cc ; player_sprite &456d e0 05 CPX #&05 ; FLYING &456f d0 14 BNE &4585 ; move_left_or_right_a_room # Is the player moving because they are FLYING? ; make_player_sit &4571 ca DEX &4572 86 cc STX &cc ; player_sprite # If so, set the player to be SITTING &4574 86 c2 STX &c2 ; player_has_changed &4576 86 c1 STX &c1 ; player_stun_counter &4578 a5 ca LDA &ca ; player_direction &457a 49 0d EOR #&0d &457c 85 c3 STA &c3 ; player_horizontal_direction &457e 85 ca STA &ca ; player_direction &4580 a2 48 LDX #&48 ; sound_2 &4582 4c a5 32 JMP &32a5 ; play_sound_from_first_table ; move_left_or_right_a_room # Otherwise, move to the next room &4585 c9 f7 CMP #&f7 &4587 d0 03 BNE &458c ; to_move_left_a_room &4589 4c 2b 46 JMP &462b ; move_right_a_room ; to_move_left_a_room &458c 4c 10 46 JMP &4610 ; move_left_a_room ; try_moving_left &458f a6 8a LDX &8a ; key_right &4591 20 09 47 JSR &4709 ; check_for_keypress &4594 f0 46 BEQ &45dc ; try_sword_movement # If LEFT is pressed and RIGHT is not pressed, ; try_moving_left_without_key_check # or the player is FLYING to the left, &4596 a5 d2 LDA &d2 ; player_x &4598 c9 ac CMP #&ac &459a f0 cf BEQ &456b ; left_or_right_edge_of_room # Has the player moved out of the room? &459c a5 d8 LDA &d8 ; player_screen_address_low &459e a6 d0 LDX &d0 ; player_screen_address_high &45a0 a0 18 LDY #&18 &45a2 20 1a 47 JSR &471a ; add_y_to_a_and_x &45a5 a0 16 LDY #&16 &45a7 84 e1 STY &e1 ; height &45a9 a0 00 LDY #&00 ; width &45ab 20 1b 30 JSR &301b ; check_for_scenery &45ae 30 b2 BMI &4562 ; can't_move_left_or_right # If not, check they haven't hit scenery &45b0 a9 00 LDA #&00 ; LEFT &45b2 85 ca STA &ca ; player_direction # Player faces left &45b4 85 c3 STA &c3 ; player_horizontal_direction &45b6 c6 d2 DEC &d2 ; player_x &45b8 a5 d8 LDA &d8 ; player_screen_address_low &45ba a6 d0 LDX &d0 ; player_screen_address_high &45bc a0 08 LDY #&08 &45be 20 23 47 JSR &4723 ; subtract_y_from_a_and_x # Move the player left by two pixels ; store_addresses &45c1 e6 c2 INC &c2 ; player_has_changed &45c3 86 d0 STX &d0 ; player_screen_address_high &45c5 85 d8 STA &d8 ; player_screen_address_low &45c7 a5 cc LDA &cc ; player_sprite &45c9 c9 05 CMP #&05 ; FLYING &45cb d0 01 BNE &45ce ; player_isn't_flying &45cd 60 RTS # No choice of movement if the player is FLYING ; player_isn't_flying &45ce a5 c4 LDA &c4 ; player_frame_has_been_updated &45d0 d0 08 BNE &45da ; skip_frame_update &45d2 e6 ce INC &ce ; player_frame &45d4 a5 ce LDA &ce ; player_frame &45d6 29 03 AND #&03 &45d8 85 ce STA &ce ; player_frame ; skip_frame_update &45da e6 eb INC &eb ; player_has_moved ; try_sword_movement &45dc a5 88 LDA &88 ; orchid_influence_colour &45de d0 1f BNE &45ff ; can't_use_sword # Can't start FIGHTING while under the influence ; check_for_shift_keypress &45e0 a2 ff LDX #&ff ; SHIFT &45e2 20 09 47 JSR &4709 ; check_for_keypress &45e5 d0 18 BNE &45ff ; can't_use_sword &45e7 a9 80 LDA #&80 &45e9 05 c2 ORA &c2 ; player_has_changed &45eb 85 c2 STA &c2 ; player_has_changed &45ed a5 c3 LDA &c3 ; player_horizontal_direction &45ef 85 ca STA &ca ; player_direction # Player faces either LEFT or RIGHT while FIGHTING &45f1 00 BRK ; random_number &45f2 29 07 AND #&07 &45f4 c9 06 CMP #&06 &45f6 b0 02 BCS &45fa ; leave_frame_unchanged &45f8 85 ce STA &ce ; player_frame # FIGHTING frame is random, but sticks 1 in 4 times ; leave_frame_unchanged &45fa a9 07 LDA #&07 ; FIGHTING ; store_player_sprite &45fc 85 cc STA &cc ; player_sprite ; leave &45fe 60 RTS ; can't_use_sword &45ff a5 cc LDA &cc ; player_sprite &4601 c9 07 CMP #&07 ; FIGHTING &4603 d0 f9 BNE &45fe ; leave # If the player has just stopped FIGHTING, &4605 e6 c2 INC &c2 ; player_has_changed &4607 00 BRK ; random_number # set them WALKING, with a random frame &4608 29 03 AND #&03 &460a 85 ce STA &ce ; player_frame &460c a9 00 LDA #&00 ; WALKING &460e f0 ec BEQ &45fc ; store_player_sprite ; move_left_a_room &4610 a9 00 LDA #&00 ; LEFT &4612 85 ca STA &ca ; player_direction # Player faces left &4614 85 c3 STA &c3 ; player_horizontal_direction &4616 a9 f7 LDA #&f7 &4618 85 d2 STA &d2 ; player_x # Move the player to the right of the next room &461a a0 ff LDY #&ff # and decrease the room number by &1 &461c a5 d8 LDA &d8 ; player_screen_address_low &461e a6 d0 LDX &d0 ; player_screen_address_high &4620 e8 INX &4621 e8 INX &4622 18 CLC &4623 69 58 ADC #&58 &4625 90 01 BCC &4628 ; to_change_room &4627 e8 INX ; to_change_room &4628 4c 7a 44 JMP &447a ; change_room ; move_right_a_room &462b a9 0d LDA #&0d ; RIGHT &462d 85 ca STA &ca ; player_direction # Player faces right &462f 85 c3 STA &c3 ; player_horizontal_direction &4631 a9 ac LDA #&ac &4633 85 d2 STA &d2 ; player_x # Move the player to the left of the next room &4635 a0 01 LDY #&01 # and increase the room number by &1 &4637 a5 d8 LDA &d8 ; player_screen_address_low &4639 a6 d0 LDX &d0 ; player_screen_address_high &463b ca DEX &463c ca DEX &463d 38 SEC &463e e9 58 SBC #&58 &4640 b0 e6 BCS &4628 ; to_change_room &4642 ca DEX &4643 d0 e3 BNE &4628 ; to_change_room ; update_player_on_screen &4645 a0 01 LDY #&01 &4647 20 4c 46 JSR &464c ; plot_player # Remove the player by plotting their previous position ; plot_current_player &464a a0 00 LDY #&00 # Then plot their current position ; plot_player &464c 84 c5 STY &c5 ; use_previous_or_current &464e a2 dc LDX #&dc ; &07dc = player_sprite_twopixel_table_one &4650 b9 cc 00 LDA &00cc,Y ; player_sprite &4653 c9 05 CMP #&05 &4655 90 02 BCC &4659 ; use_orchid_player_pixel_table # Use a different pixel table if WALKING or SITTING &4657 a2 ec LDX #&ec ; &07ec = player_sprite_twopixel_table_two # (to allow for the colour of the orchid) ; use_orchid_player_pixel_table &4659 86 24 STX &24 ; sprite_pixel_value_table_low &465b b9 ca 00 LDA &00ca,Y ; player_direction # Calculate which player sprite to use &465e 18 CLC &465f 79 cc 00 ADC &00cc,Y ; player_sprite &4662 79 ce 00 ADC &00ce,Y ; player_frame &4665 0a ASL A &4666 aa TAX &4667 86 c4 STX &c4 ; calculated_sprite_times_two &4669 bd a1 47 LDA &47a1,X ; top_half_of_player_sprite_address_table; &466c 85 15 STA &15 ; sprite_data_address_low &466e bd a2 47 LDA &47a2,X ; top_half_of_player_sprite_address_table + 1; &4671 85 16 STA &16 ; sprite_data_address_high &4673 8a TXA &4674 4a LSR A &4675 aa TAX ; calculated_sprite &4676 b9 d2 00 LDA &00d2,Y ; player_x &4679 85 e1 STA &e1 ; screen_x &467b b9 d0 00 LDA &00d0,Y ; player_screen_address_high &467e 85 c2 STA &c2 ; copy_of_player_screen_address_high &4680 b9 d8 00 LDA &00d8,Y ; player_screen_address_low &4683 bc e5 47 LDY &47e5,X ; player_sprite_offset_table &4686 f0 08 BEQ &4690 ; skip_offset # Is there a top half of the player? &4688 a6 c2 LDX &c2 ; copy_of_player_screen_address_high &468a 20 46 47 JSR &4746 ; reduce_screen_address_by_y_rows # If so, reduce the screen address by offset rows &468d 20 a8 46 JSR &46a8 ; plot_half_of_player # and plot the sprite ; skip_offset &4690 a6 c4 LDX &c4 ; calculated_sprite_times_two &4692 a4 c5 LDY &c5 ; use_previous_or_current &4694 bd 07 48 LDA &4807,X ; bottom_half_of_player_sprite_address_table &4697 85 15 STA &15 ; sprite_data_address_low &4699 bd 08 48 LDA &4808,X ; bottom_half_of_player_sprite_address_table + 1 &469c 85 16 STA &16 ; sprite_data_address_high &469e b9 d2 00 LDA &00d2,Y ; player_x &46a1 85 e1 STA &e1 ; screen_x &46a3 b6 d0 LDX &d0,Y ; player_screen_address_high &46a5 b9 d8 00 LDA &00d8,Y ; player_screen_address_low # Plot the bottom half of the player ; plot_half_of_player &46a8 85 e3 STA &e3 ; screen_address_low &46aa 86 eb STX &eb ; screen_address_high &46ac a0 00 LDY #&00 &46ae a5 16 LDA &16 ; sprite_data_address_high &46b0 30 1d BMI &46cf ; plot_flipped_sprite &46b2 a9 8a LDA #&8a ; TXA # If the high bit isn't set, don't flip pixels &46b4 85 27 STA &27 ; pixel_value_processing_instructions &46b6 a9 a2 LDA #&a2 ; LDX #$ &46b8 85 28 STA &28 ; pixel_value_processing_instructions + 1 ; regular_column_loop &46ba 20 00 00 JSR &0000 ; eor_column_of_rle_sprite_data_to_screen # Plot a column of the sprite &46bd e6 e1 INC &e1 ; screen_x &46bf f0 0d BEQ &46ce ; leave # Don't plot beyond right edge of screen &46c1 a5 e3 LDA &e3 ; screen_address_low &46c3 18 CLC &46c4 69 08 ADC #&08 # Move right two pixels &46c6 85 e3 STA &e3 ; screen_address_low &46c8 90 f0 BCC &46ba ; regular_column_loop &46ca e6 eb INC &eb ; screen_address_high &46cc d0 ec BNE &46ba ; regular_column_loop &46ce 60 RTS ; plot_flipped_sprite &46cf 29 7f AND #&7f &46d1 85 16 STA &16 ; sprite_data_address_high &46d3 a9 60 LDA #&60 &46d5 18 CLC &46d6 65 e3 ADC &e3 ; screen_address_low &46d8 85 e3 STA &e3 ; screen_address_low &46da 90 02 BCC &46de &46dc e6 eb INC &eb ; screen_address_high &46de a9 0c LDA #&0c &46e0 18 CLC &46e1 65 e1 ADC &e1 ; screen_x &46e3 85 e1 STA &e1 ; screen_x &46e5 a9 bd LDA #&bd ; LDA $0000,X # If the high bit is set, flip pixels &46e7 85 27 STA &27 ; pixel_value_processing_instructions &46e9 a9 00 LDA #&00 &46eb 85 28 STA &28 ; pixel_value_processing_instructions + 1 ; flipped_column_loop &46ed 20 00 00 JSR &0000 ; eor_column_of_rle_sprite_data_to_screen # Plot a column of the sprite &46f0 c6 e1 DEC &e1 ; screen_x &46f2 a5 e1 LDA &e1 ; screen_x &46f4 c9 b0 CMP #&b0 &46f6 90 0d BCC &4705 ; at_left_of_screen # Don't plot beyond left of screen ; move_left_two_pixels &46f8 a5 e3 LDA &e3 ; screen_address_low &46fa 38 SEC &46fb e9 08 SBC #&08 # Move left two pixels &46fd 85 e3 STA &e3 ; screen_address_low &46ff b0 ec BCS &46ed ; flipped_column_loop &4701 c6 eb DEC &eb ; screen_address_high &4703 d0 e8 BNE &46ed ; flipped_column_loop ; at_left_of_screen &4705 c9 32 CMP #&32 # Redundant / buggy code. An RTS does the same here, &4707 90 ef BCC &46f8 ; move_left_two_pixels # without the apparently unintended fallthrough ; check_for_keypress &4709 a9 81 LDA #&81 ; Scan for a particular key &470b a0 ff LDY #&ff &470d 20 f4 ff JSR &fff4 ; OSBYTE &4710 e0 ff CPX #&ff &4712 60 RTS ; delay &4713 85 8f STA &8f ; interrupt_ticker ; delay_loop &4715 a5 8f LDA &8f ; interrupt_ticker &4717 d0 fc BNE &4715 ; delay_loop &4719 60 RTS ; add_y_to_a_and_x &471a 84 91 STY &91 ; tmp &471c 18 CLC &471d 65 91 ADC &91 ; tmp &471f 90 01 BCC &4722 ; leave &4721 e8 INX &4722 60 RTS ; subtract_y_from_a_and_x &4723 84 91 STY &91 ; tmp &4725 38 SEC &4726 e5 91 SBC &91 ; tmp &4728 b0 01 BCS &472b ; leave &472a ca DEX &472b 60 RTS ; increase_screen_address_by_y_rows &472c 48 PHA &472d 29 07 AND #&07 &472f c9 07 CMP #&07 &4731 f0 08 BEQ &473b ; increase_screen_address_group &4733 68 PLA &4734 18 CLC &4735 69 01 ADC #&01 # Add 1 to address if remaining in group ; increase_screen_address_next_row &4737 88 DEY &4738 d0 f2 BNE &472c ; increase_screen_address_by_y_rows &473a 60 RTS ; increase_screen_address_group &473b 68 PLA &473c e8 INX &473d e8 INX &473e 18 CLC &473f 69 79 ADC #&79 # Add &280 to address if changing group &4741 90 f4 BCC &4737 ; increase_screen_address_next_row &4743 e8 INX &4744 d0 f1 BNE &4737 ; increase_screen_address_next_row ; reduce_screen_address_by_y_rows &4746 48 PHA &4747 29 07 AND #&07 &4749 f0 08 BEQ &4753 ; reduce_screen_address_group &474b 68 PLA &474c 38 SEC &474d e9 01 SBC #&01 # Subtract 1 from address if remaining in group ; reduce_screen_address_next_row &474f 88 DEY &4750 d0 f4 BNE &4746 ; reduce_screen_screen_address_by_y_rows &4752 60 RTS ; reduce_screen_address_group &4753 68 PLA &4754 ca DEX &4755 ca DEX &4756 38 SEC &4757 e9 79 SBC #&79 # Subtract &280 from address if changing group &4759 b0 f4 BCS &474f ; reduce_screen_address_next_row &475b ca DEX &475c d0 f1 BNE &474f ; reduce_screen_address_next_row ; check_for_scenery_in_centre_of_player &475e a0 20 LDY #&20 &4760 20 1a 47 JSR &471a ; add_y_to_a_and_x &4763 a0 03 LDY #&03 &4765 84 e1 STY &e1 ; height &4767 a0 20 LDY #&20 ; width &4769 4c 1b 30 JMP &301b ; check_for_scenery ; random_number &476c a5 c6 LDA &c6 ; rnd_1 &476e 29 48 AND #&48 &4770 69 38 ADC #&38 &4772 0a ASL A &4773 0a ASL A &4774 26 c8 ROL &c8 ; rnd_3 &4776 26 c7 ROL &c7 ; rnd_2 &4778 26 c6 ROL &c6 ; rnd_1 &477a 68 PLA # BRK pushed the processor status (1 byte) &477b 68 PLA # and program counter (2 bytes) &477c 68 PLA # in anticipation of an RTI that never occurs &477d a5 c6 LDA &c6 ; rnd_1 &477f 6c fd 00 JMP (&00fd) ; address_of_byte_after_BRK # Return to immediately after the BRK instruction &4782 60 RTS ; walking_sound_effect &4783 a5 eb LDA &eb ; player_has_moved # Has the player moved? &4785 f0 fb BEQ &4782 ; leave &4787 e6 9d INC &9d ; step_count &4789 a5 9d LDA &9d ; step_count &478b 29 03 AND #&03 &478d d0 f3 BNE &4782 ; leave # If so, play a sound once every four steps &478f ad c4 09 LDA &09c4 ; pitch_of_sound_8 &4792 49 12 EOR #&12 # alternating in pitch &4794 8d c4 09 STA &09c4 ; pitch_of_sound_8 &4797 ad df 32 LDA &32df ; creature_sprite + 3 # unless there's a FIRE &479a 10 e6 BPL &4782 ; leave &479c a2 c0 LDX #&c0 ; sound_8 &479e 4c a2 32 JMP &32a2 ; play_sound_from_second_table ; top_half_of_player_sprite_address_table &47a1 1c 2b 1c 2b 1c 2b 1c 2b 1c 2b 00 00 00 00 1b 2b &47b1 1c 2b 1c 2b 64 2e 1c 2b 65 2e 1c ab 1c ab 1c ab &47c1 1c ab 1c ab 00 00 00 00 1b ab 1c ab 1c ab 64 ae &47d1 1c ab 65 ae c5 2b c5 2b c5 2b c5 2b 38 2c 38 2c &47e1 38 2c 38 2c ; player_sprite_offset_table; &47e5 0d 0c 0d 0c 09 00 00 0c 0c 0c 0c 0c 0c 0d 0c 0d &47f5 0c 09 00 00 0c 0c 0c 0c 0c 0c 0a 0a 0a 0a 0a 0a &4805 0a 0a ; bottom_half_of_player_sprite_address_table &4807 45 2b 69 2b 45 2b 99 2b ae 2c cb 2c 8c 2e 15 2d &4817 4b 2d 84 2d b9 2d f0 2d 2b 2e 45 ab 69 ab 45 ab &4827 99 ab ae ac cb ac 8c ae 15 ad 4b ad 84 ad b9 ad &4837 f0 ad 2b ae ef 2b 12 2c ef 2b 12 ac 5f 2c 84 2c &4847 5f 2c 84 ac ; turning_point_table + 1 &484b .. 14 50 50 50 25 8a 25 3f 11 43 31 50 50 50 0f ; top corridor, left &485b 45 50 50 11 35 25 11 1a 23 11 11 45 11 50 11 50 &486b 50 11 50 0a 50 0a 94 50 20 50 50 41 50 &4877 1b 34 50 50 36 04 20 06 20 36 22 01 50 50 34 2f ; top corridor, right &4887 20 50 50 31 12 b6 50 b4 34 50 1b 50 50 36 50 50 &4897 50 50 50 3b 50 3b af 50 0b 20 34 25 20 &48a4 50 11 50 50 16 23 8a 23 41 14 41 23 50 50 50 0f ; bottom corridor, left &48b4 41 50 50 0f 50 23 0f 50 20 11 11 3c 11 50 91 41 &48c4 50 11 41 0a 50 0a 50 50 50 50 50 21 50 &48d1 3b 36 50 50 bb 02 22 04 22 31 22 04 50 50 36 34 ; bottom_corridor, right &48e1 22 50 50 36 50 3b 50 34 34 50 31 50 50 3b 25 22 &48f1 50 50 04 3b 50 3b 50 50 34 21 34 01 20 ; unused &48fe 1d 00 # &4900 - &497f is moved to &0100 - &017f at &4ad1 ; twopixel_reverse_table &0100 00 02 01 03 08 0a 09 0b 04 06 05 07 0c 0e 0d 0f &0110 20 22 21 23 28 2a 29 2b 24 26 25 27 2c 2e 2d 2f &0120 10 12 11 13 18 1a 19 1b 14 16 15 17 1c 1e 1d 1f &0130 30 32 31 33 38 3a 39 3b 34 36 35 37 3c 3e 3d 3f ; sound_table ; chan vol pitch dur &0140 13 00 0e 00 46 00 1e 00 ; sound_1 &0148 13 00 0f 00 00 00 05 00 ; sound_2 &0150 13 00 f1 ff c8 00 02 00 ; sound_3 &0158 13 00 f1 ff 96 00 01 00 ; sound_4 &0160 11 00 0d 00 00 00 0f 00 ; sound_5 &0168 10 00 f1 ff 07 00 0f 00 ; sound_6 &0170 12 00 10 00 00 00 01 00 ; sound_7 # pitch is modified ; unused &0178 b4 b6 b5 b7 bc be bd bf # Suggests twopixel_reverse_table was once larger # &4980 - &4a5f is moved to &0300 - &03df at &4adb ; room sprite &03 data &0300 0b 04 14 08 0c 0d 1c 0e 0f 28 2c 20 21 10 13 14 &0310 11 20 21 80 61 00 21 10 13 14 11 10 13 14 11 10 &0320 24 10 21 36 1a 49 00 10 13 14 11 34 10 24 10 14 &0330 11 33 41 66 23 11 00 21 10 34 21 14 15 14 36 6a &0340 43 00 10 13 14 15 68 15 44 51 a6 21 00 11 14 13 &0350 14 18 57 14 16 91 93 00 20 11 34 11 10 14 11 13 &0360 14 8a 76 21 00 11 14 13 10 24 13 10 24 10 14 13 &0370 41 40 73 00 20 11 14 13 10 11 14 13 10 11 14 13 &0380 10 13 19 66 14 31 00 50 23 d0 43 00 00 ; room_sprites_height_table &038d 38 58 28 20 18 18 28 38 38 18 58 38 18 28 28 18 &039d 18 38 28 18 18 18 38 38 38 38 18 18 30 08 08 28 &03ad 38 38 18 30 18 30 ; hippo_x_table &03b3 b0 b0 d2 d2 f5 f5 ; unused &03b9 fb 31 4b 4f ; amulet_rooms &03bd 13 14 31 33 ; fire_state &03c1 34 ; amulet_color_table ; GG GG RR RR CC CC YY YY &03c2 0c 0c 03 03 3c 3c 0f 0f ; amulet_parts_collected &03ca 54 41 45 00 ; hippo_y_table &03ce 2f 6f 2f 6f 2f 6f ; hippo_screen_address_high_table &03d4 55 69 56 6a 57 6b ; hippo_screen_address_high_table &03da 87 87 97 97 af af # &4a60 - &4ac9 is moved to &0000 - &0069 at &4b08 ; zero_page_routine ; eor_column_of_rle_sprite_data_to_screen # For plotting a colour of player sprite &0000 a5 eb LDA &eb ; screen_address_high &0002 a6 e1 LDX &e1 ; screen_x &0004 e0 b0 CPX #&b0 &0006 b0 02 BCS &000a ; column_is_on_screen &0008 a9 e0 LDA #&e0 # Write somewhere nonsensical if off-screen ; column_on_on_screen &000a 85 39 STA &39 ; screen_address_for_eor_high &000c 85 3c STA &3c ; screen_address_for_sta_high &000e a5 e3 LDA &e3 ; screen_address_low &0010 85 38 STA &38 ; screen_address_for_eor_low &0012 85 3b STA &3b ; screen_address_for_sta_low ; sprite_data_loop &0014 b9 ff ff LDA &ffff,Y # Get a byte of sprite data # actually LDA (&15),Y ; sprite_data_address &0017 c8 INY # Increase sprite_data_address by 1 &0018 d0 02 BNE &001c &001a e6 16 INC &16 ; sprite_data_address_high &001c aa TAX &001d f0 44 BEQ &0063 ; end_of_column # A zero byte marks the end of the column &001f 48 PHA &0020 29 0f AND #&0f # sprite_data_byte & &0f is the pixel value &0022 aa TAX &0023 bd 00 07 LDA &0700,X # (via a lookup table) # actually LDA &07dc,X or LDA &07ec,X ; sprite_pixel_value_table &0026 aa TAX ; pixel_value_processing_instructions &0027 bd 00 01 LDA &0100,X ; twopixel_reverse_table # Flip the two pixels if necessary # also TXA # LDX #&01 &002a 85 36 STA &36 ; pixel_value &002c 68 PLA &002d 29 f0 AND #&f0 # (sprite_data_byte & &f0) / 16 is the number of rows &002f 4a LSR A &0030 4a LSR A &0031 4a LSR A &0032 4a LSR A &0033 85 e2 STA &e2 ; rows_to_plot ; row_loop &0035 a9 00 LDA #&00 # actually LDA &36 ; pixel_value # Take the pixel value &0037 4d ff ff EOR &ffff # actually EOR screen_address_for_eor # EOR it with whatever's at the screen address &003a 8d ff ff STA &ffff # actually STA screen_address_for_sta # And store it on the screen &003d a5 38 LDA &38 ; screen_address_for_eor_low &003f 29 07 AND #&07 &0041 f0 0a BEQ &004d ; change_group_of_rows &0043 c6 38 DEC &38 ; screen_address_for_eor_low # Subtract 1 from screen address &0045 c6 3b DEC &3b ; screen_address_for_sta_low # (i.e. move up a row) ; continue_after_heading_up_a_row &0047 c6 e2 DEC &e2 ; rows_to_plot &0049 d0 ea BNE &0035 ; row_loop &004b f0 c7 BEQ &0014 ; sprite_data_loop ; change_group_of_rows &004d a5 38 LDA &38 ; screen_address_for_eor_low # Subtract &279 from screen address &004f a6 39 LDX &39 ; screen_address_for_eor_high &0051 ca DEX &0052 ca DEX &0053 38 SEC &0054 e9 79 SBC #&79 &0056 85 38 STA &38 ; screen_address_for_eor_low &0058 85 3b STA &3b ; screen_address_for_sta_low &005a b0 01 BCS &005d &005c ca DEX &005d 86 39 STX &39 ; screen_address_for_eor_high &005f 86 3c STX &3c ; screen_address_for_sta_high &0061 d0 e4 BNE &0047 ; continue_after_heading_up_a_row ; end_of_column &0063 b1 15 LDA (&15),Y ; sprite_data_address # Consider next byte of sprite data &0065 d0 02 BNE &0069 ; leave &0067 68 PLA # A second zero byte marks the end of the sprite &0068 68 PLA # (popping us out of the parent plotting routine) &0069 60 RTS ; decrypted_entry_point &4aca ad 05 02 LDA &0205 ; irq1_vector_high &4acd d0 fb BNE &4aca ; decrypted_entry_point # Infinite loop if IRQ1 vector changed from loader &4acf a2 7f LDX #&7f ; move_4900_to_497f_loop # Move &4900 - &497f to &0100 - &017f &4ad1 bd 00 49 LDA &4900,X ; unrelocated_twopixel_reverse_table &4ad4 9d 00 01 STA &0100,X ; twopixel_reverse_table &4ad7 ca DEX &4ad8 10 f7 BPL &4ad1 ; move_4900_to_497f_loop &4ada e8 INX ; move_4980_to_4a5f_loop # Move &4980 - &4a5f to &0300 - &03df &4adb bd 80 49 LDA &4980,X ; unrelocated_room_03_sprite_data &4ade 9d 00 03 STA &0300,X ; room_03_sprite_data &4ae1 e8 INX &4ae2 e0 e0 CPX #&e0 &4ae4 d0 f5 BNE &4adb ; move_4980_to_4a5f_loop &4ae6 78 SEI &4ae7 a9 3f LDA #&3f &4ae9 8d 20 02 STA &0220 ; event_vector_low &4aec a9 30 LDA #&30 ; &303f = event_vector_routine &4aee 8d 21 02 STA &0221 ; event_vector_high &4af1 a9 6c LDA #&6c &4af3 8d 02 02 STA &0202 ; brk_vector_low &4af6 a9 47 LDA #&47 ; &476c = random_number # Turn BRK opcode into a call to random_number &4af8 8d 03 02 STA &0203 ; brk_vector_high &4afb a5 20 LDA &20 ; copy_of_os_irq1_handler_address_low # Set in loader &4afd 8d 04 02 STA &0204 ; irq1_vector_low &4b00 a5 21 LDA &21 ; copy_of_os_irq1_handler_address_high &4b02 8d 05 02 STA &0205 ; irq1_vector_high &4b05 58 CLI &4b06 a2 69 LDX #&69 ; move_4a60_to_4ac9_loop # Move &4a60 - &4ac9 to &0000 - &0069 &4b08 bd 60 4a LDA &4a60,X ; unrelocated_zero_page_routine &4b0b 95 00 STA &00,X ; zero_page_routine &4b0d ca DEX &4b0e 10 f8 BPL &4b08 ; move_4a60_to_4ac9_loop &4b10 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &4b13 09 04 ORA #&04 &4b15 85 c6 STA &c6 ; rnd_1 &4b17 a9 00 LDA #&00 &4b19 85 90 STA &90 ; unused &4b1b 85 8e STA &8e ; player_body_colour &4b1d 85 88 STA &88 ; orchid_influence_colour &4b1f 85 87 STA &87 ; white_or_orchid_colour &4b21 85 86 STA &86 ; orchid_flash_count &4b23 85 76 STA &76 ; neither_pixel &4b25 85 83 STA &83 ; sound_0_duration_high &4b27 85 81 STA &81 ; sound_0_pitch_high &4b29 85 7e STA &7e ; sound_0_volume # Bug: should be STA &7f ; sound 0 + 3 &4b2b 85 c0 STA &c0 ; lives_as_digit &4b2d a2 0f LDX #&0f ; remove_roms_loop &4b2f 9d a1 02 STA &02a1,X ; os_paged_rom_type_table # Remove paged ROMs from ROM information table &4b32 ca DEX &4b33 10 fa BPL &4b2f ; remove_roms_loop &4b35 ad 45 fe LDA &fe45 ; System VIA timer 1 counter MSB &4b38 09 80 ORA #&80 &4b3a 85 c7 STA &c7 ; rnd_2 &4b3c a9 02 LDA #&02 &4b3e 85 7d STA &7d ; sound_0_channel_high &4b40 a9 07 LDA #&07 &4b42 85 82 STA &82 ; sound_0_duration &4b44 a9 08 LDA #&08 &4b46 85 7e STA &7e ; sound_0_volume &4b48 a9 2e LDA #&2e &4b4a 85 7b STA &7b ; music_address_high &4b4c a9 0e LDA #&0e ; Enable event &4b4e a2 04 LDX #&04 ; vsync event &4b50 20 f4 ff JSR &fff4 ; OSBYTE &4b53 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &4b56 4d 45 fe EOR &fe45 ; System VIA timer 1 counter MSB &4b59 09 01 ORA #&01 &4b5b 85 c8 STA &c8 ; rnd_3 &4b5d 85 6e STA &6e ; game_seed &4b5f a9 0d LDA #&0d # R13: Displayed screen start address register (low) &4b61 8d 00 fe STA &fe00 ; video register number &4b64 a9 20 LDA #&20 # Set screen start address to &4900 &4b66 8d 01 fe STA &fe01 ; video register value &4b69 a9 06 LDA #&06 # R6: Vertical displayed register &4b6b 8d 00 fe STA &fe00 ; video register number &4b6e a9 16 LDA #&16 &4b70 8d 01 fe STA &fe01 ; video register value &4b73 4c 4d 37 JMP &374d ; reset_game ; unused &4b76 00 00 00 00 00 00 00 00 00 00