Arcadians disassembly ===================== Arcadians was written by Nick "Orlando" Pelling, and was published by Acornsoft for the BBC Micro in 1982. It is an unofficial conversion of Namco's 1979 arcade space shooter, Galaxian. 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 =============== Each enemy has twelve sprites for rotations, shifted by zero to three pixels. These were originally stored from &0c00 to &1bff, but the code has been patched to free &0d00 - &0dff, relocating that page of sprites to &2a00 - &2aff. Enemy slots are as follows: 16 17 18 19 1a 1b (type 4, leaders) 13 14 15 1c 1d 1e (type 3, escorts) 03 07 0b 0f 22 26 2a 2e (type 2, blue with yellow wings) 00 04 08 0c 10 21 25 29 2d 31 (type 1, blue with red eyes) 01 05 09 0d 11 20 24 28 2c 30 (type 1, blue with red eyes) 02 06 0a 0e 12 1f 23 27 2b 2f (type 1, blue with red eyes) Interesting pokes ================= &4b3e = &ad infinite lives Game disassembly ================ ; Arcadians ; 00001900 00003f00 00004c00 # &1900 - &19ff is moved to &0c00 - &0cff at &60d5 ; enemy_type_0_shift_0_sprites &0c00 10 40 00 10 40 00 a0 a0 80 c1 14 80 00 00 00 60 30 00 c0 90 80 ; SPRITE_ROTATION_0 &0c15 c0 90 80 60 30 00 00 00 00 c1 14 80 a0 a0 80 10 40 00 10 40 00 ; SPRITE_ROTATION_1 &0c2a 40 80 00 70 a0 00 01 60 80 00 14 80 60 10 00 d0 10 80 00 00 80 ; SPRITE_ROTATION_2 &0c3f 00 90 00 20 f0 00 b0 04 00 e1 00 00 40 30 00 c0 50 80 80 00 00 ; SPRITE_ROTATION_3 &0c54 80 c0 00 c0 80 00 41 60 00 40 40 00 40 38 00 60 40 00 c0 60 00 ; SPRITE_ROTATION_4 &0c69 30 10 00 10 30 00 60 28 00 20 20 00 c1 20 00 20 60 00 60 30 00 ; SPRITE_ROTATION_5 &0c7e c0 60 00 60 40 00 00 38 00 20 40 00 00 38 00 60 40 00 c0 60 00 ; SPRITE_ROTATION_6 &0c93 60 30 00 20 60 00 c1 00 00 20 40 00 c1 00 00 20 60 00 60 30 00 ; SPRITE_ROTATION_7 &0ca8 c0 60 00 60 40 00 40 38 00 40 40 00 41 60 00 c0 80 00 80 c0 00 ; SPRITE_ROTATION_8 &0cbd 60 30 00 20 60 00 c1 20 00 20 20 00 60 28 00 10 30 00 30 10 00 ; SPRITE_ROTATION_9 &0cd2 00 00 80 d0 10 80 60 10 00 00 14 80 01 60 80 70 a0 00 40 80 00 ; SPRITE_ROTATION_10 &0ce7 80 00 00 c0 50 80 40 30 00 e1 00 00 b0 04 00 20 f0 00 00 90 00 ; SPRITE_ROTATION_11 ; unused &0cfc 00 00 00 00 # &1a00 - &1aff is unused, would relocate to &0d00 - &0dff # &1a00 - &1aff is a copy of &2a00 - &2aff ; unused_enemy_type_1_shift_0_sprites &1a00 10 40 00 10 40 00 b0 e0 80 f1 f4 80 30 e0 00 76 f3 00 cc 91 88 ; SPRITE_ROTATION_0 &1a15 cc 91 88 76 f3 00 30 e0 00 f1 f4 80 b0 e0 80 10 40 00 10 40 00 ; SPRITE_ROTATION_1 &1a2a 40 80 00 70 a0 00 31 e0 80 30 f4 80 76 f1 00 ec 91 88 00 00 88 ; SPRITE_ROTATION_2 &1a3f 00 90 00 20 f0 00 b0 e4 00 f1 e0 00 74 f3 00 cc d1 88 88 00 00 ; SPRITE_ROTATION_3 &1a54 44 e0 00 76 c0 00 32 f8 00 30 e0 00 30 f4 80 33 e0 00 66 30 00 ; SPRITE_ROTATION_4 &1a69 30 91 00 10 f3 00 70 ea 00 30 e0 00 f1 e0 00 30 e6 00 60 33 00 ; SPRITE_ROTATION_5 &1a7e cc e0 00 76 c0 00 30 f8 00 70 c0 00 30 f8 00 76 c0 00 cc e0 00 ; SPRITE_ROTATION_6 &1a93 70 33 00 30 e6 00 f1 c0 00 30 e0 00 f1 c0 00 30 e6 00 70 33 00 ; SPRITE_ROTATION_7 &1aa8 66 30 00 33 e0 00 30 f4 80 30 e0 00 32 f8 00 76 c0 00 44 e0 00 ; SPRITE_ROTATION_8 &1abd 60 33 00 30 e6 00 f1 e0 00 30 e0 00 70 ea 00 10 f3 00 30 91 00 ; SPRITE_ROTATION_9 &1ad2 00 00 88 ec 91 88 76 f1 00 30 f4 80 31 e0 80 70 a0 00 40 80 00 ; SPRITE_ROTATION_10 &1ae7 88 00 00 cc d1 88 74 f3 00 f1 e0 00 b0 e4 00 20 f0 00 00 90 00 ; SPRITE_ROTATION_11 ; unused &1afc 00 00 00 00 # &1b00 - &64ff is moved to to &0e00 - &57ff at &60ec ; enemy_type_2_shift_0_sprites &0e00 01 04 00 01 04 00 0b 0e 08 1f 4f 08 03 0e 00 61 3c 00 c0 18 80 ; SPRITE_ROTATION_0 &0e15 c0 18 80 61 3c 00 03 0e 00 1f 4f 08 0b 0e 08 01 04 00 01 04 00 ; SPRITE_ROTATION_1 &0e2a 04 08 00 07 0a 00 13 0e 08 03 4f 08 61 1e 00 c1 18 80 00 00 80 ; SPRITE_ROTATION_2 &0e3f 00 09 00 02 0f 00 0b 4e 00 1f 0e 00 43 3c 00 c0 1c 80 80 00 00 ; SPRITE_ROTATION_3 &0e54 40 0e 00 61 0c 00 21 8f 00 03 0e 00 03 4f 08 30 0e 00 60 03 00 ; SPRITE_ROTATION_4 &0e69 03 18 00 01 3c 00 07 ac 00 03 0e 00 1f 0e 00 03 68 00 06 30 00 ; SPRITE_ROTATION_5 &0e7e c0 0e 00 61 0c 00 03 8f 00 07 0c 00 03 8f 00 61 0c 00 c0 0e 00 ; SPRITE_ROTATION_6 &0e93 07 30 00 03 68 00 1f 0c 00 03 0e 00 1f 0c 00 03 68 00 07 30 00 ; SPRITE_ROTATION_7 &0ea8 60 03 00 30 0e 00 03 4f 08 03 0e 00 21 8f 00 61 0c 00 40 0e 00 ; SPRITE_ROTATION_8 &0ebd 06 30 00 03 68 00 1f 0e 00 03 0e 00 07 ac 00 01 3c 00 03 18 00 ; SPRITE_ROTATION_9 &0ed2 00 00 80 c1 18 80 61 1e 00 03 4f 08 13 0e 08 07 0a 00 04 08 00 ; SPRITE_ROTATION_10 &0ee7 80 00 00 c0 1c 80 43 3c 00 1f 0e 00 0b 4e 00 02 0f 00 00 09 00 ; SPRITE_ROTATION_11 ; unused &0efc 00 00 00 00 ; enemy_type_3_shift_0_sprites &0f00 80 88 80 91 cc 80 b7 6f 80 a7 2f 80 e1 3c 80 60 38 00 00 08 00 ; SPRITE_ROTATION_0 &0f15 00 08 00 60 38 00 e1 3c 80 a7 2f 80 b7 6f 80 91 cc 80 80 88 80 ; SPRITE_ROTATION_1 &0f2a 40 44 00 d1 ee 80 b7 6e 80 a7 5e 80 e1 5a 80 41 70 00 01 20 00 ; SPRITE_ROTATION_2 &0f3f 11 10 00 b3 dc 80 b3 6f 80 d3 2f 80 d2 3c 80 70 14 00 20 04 00 ; SPRITE_ROTATION_3 &0f54 60 22 00 c0 ee 80 b7 6f 80 c3 5e 80 c3 f0 80 82 e0 00 04 00 00 ; SPRITE_ROTATION_4 &0f69 22 30 00 b3 98 80 b7 6f 80 d3 1e 80 f0 96 80 30 82 80 00 01 00 ; SPRITE_ROTATION_5 &0f7e 61 f0 00 71 88 00 03 cc 00 0f 6e 00 03 cc 00 71 88 00 61 f0 00 ; SPRITE_ROTATION_6 &0f93 f0 68 00 11 e8 00 33 0c 00 67 0f 00 33 0c 00 11 e8 00 f0 68 00 ; SPRITE_ROTATION_7 &0fa8 04 00 00 82 e0 00 c3 f0 80 c3 5e 80 b7 6f 80 c0 ee 80 60 22 00 ; SPRITE_ROTATION_8 &0fbd 00 01 00 30 82 80 f0 96 80 d3 1e 80 b7 6f 80 b3 98 80 22 30 00 ; SPRITE_ROTATION_9 &0fd2 01 20 00 41 70 00 e1 5a 80 a7 5e 80 b7 6e 80 d1 ee 80 40 44 00 ; SPRITE_ROTATION_10 &0fe7 20 04 00 70 14 00 d2 3c 80 d3 2f 80 b3 6f 80 b3 dc 80 11 10 00 ; SPRITE_ROTATION_11 ; unused &0ffc 00 00 00 00 ; enemy_type_0_shift_1_sprites &1000 00 a0 00 40 a0 40 30 50 80 40 0a 40 40 00 40 30 10 80 00 40 00 ; SPRITE_ROTATION_0 &1015 60 40 c0 30 10 80 00 00 00 60 0a c0 50 50 40 00 a0 00 00 a0 00 ; SPRITE_ROTATION_1 &102a 20 40 00 30 d0 00 00 38 40 00 02 c0 30 00 80 60 80 c0 00 00 40 ; SPRITE_ROTATION_2 &103f 00 40 80 10 70 80 50 82 00 70 08 00 20 10 80 60 20 c0 40 00 00 ; SPRITE_ROTATION_3 &1054 40 60 00 60 40 00 20 38 00 20 20 00 20 14 80 30 20 00 60 30 00 ; SPRITE_ROTATION_4 &1069 10 80 80 00 90 80 30 14 00 10 10 00 60 18 00 10 30 00 30 10 80 ; SPRITE_ROTATION_5 &107e 60 30 00 30 20 00 00 14 80 10 20 00 00 14 80 30 20 00 60 30 00 ; SPRITE_ROTATION_6 &1093 30 10 80 10 30 00 60 08 00 10 20 00 60 08 00 10 30 00 30 10 80 ; SPRITE_ROTATION_7 &10a8 60 30 00 30 20 00 20 14 80 20 20 00 20 38 00 60 40 00 40 60 00 ; SPRITE_ROTATION_8 &10bd 30 10 80 10 30 00 60 18 00 10 10 00 30 14 00 00 90 80 10 80 80 ; SPRITE_ROTATION_9 &10d2 00 00 40 60 80 c0 30 00 80 00 02 c0 00 38 40 30 d0 00 20 40 00 ; SPRITE_ROTATION_10 &10e7 40 00 00 60 20 c0 20 10 80 70 08 00 50 82 00 10 70 80 00 40 80 ; SPRITE_ROTATION_11 ; unused &10fc 00 00 00 00 ; enemy_type_1_shift_1_sprites &1100 00 a0 00 40 a0 40 70 f0 c0 54 fa 44 54 f0 44 33 f1 88 00 40 00 ; SPRITE_ROTATION_0 &1115 66 40 cc 33 f1 88 10 f0 00 70 fa c0 50 f0 40 00 a0 00 00 a0 00 ; SPRITE_ROTATION_1 &112a 20 40 00 30 d0 00 10 f8 40 10 f2 c0 33 f0 88 76 40 cc 00 00 44 ; SPRITE_ROTATION_2 &113f 00 40 80 10 70 80 50 f2 00 70 f8 00 32 f1 88 66 60 44 44 00 00 ; SPRITE_ROTATION_3 &1154 22 70 00 33 e0 00 11 f4 80 10 f0 00 10 f2 c0 11 f8 00 33 10 80 ; SPRITE_ROTATION_4 &1169 10 c0 88 00 f1 88 30 f5 00 10 f0 00 70 f8 00 10 f3 00 30 11 88 ; SPRITE_ROTATION_5 &117e 66 70 00 33 e0 00 10 f4 80 30 e0 00 10 f4 80 33 e0 00 66 70 00 ; SPRITE_ROTATION_6 &1193 30 91 88 10 f3 00 70 e8 00 10 f0 00 70 e8 00 10 f3 00 30 91 88 ; SPRITE_ROTATION_7 &11a8 33 10 80 11 f8 00 10 f2 c0 10 f0 00 11 f4 80 33 e0 00 22 70 00 ; SPRITE_ROTATION_8 &11bd 30 11 88 10 f3 00 70 f8 00 10 f0 00 30 f5 00 00 f1 88 10 c0 88 ; SPRITE_ROTATION_9 &11d2 00 00 44 76 40 cc 33 f0 88 10 f2 c0 10 f8 40 30 d0 00 20 40 00 ; SPRITE_ROTATION_10 &11e7 44 00 00 66 60 44 32 f1 88 70 f8 00 50 f2 00 10 70 80 00 40 80 ; SPRITE_ROTATION_11 ; unused &11fc 00 00 00 00 ; enemy_type_2_shift_1_sprites &1200 00 0a 00 04 0a 04 07 0f 0c 41 af 40 41 0f 40 30 1e 80 00 04 00 ; SPRITE_ROTATION_0 &1215 60 04 c0 30 1e 80 01 0f 00 07 af 0c 05 0f 04 00 0a 00 00 0a 00 ; SPRITE_ROTATION_1 &122a 02 04 00 03 0d 00 01 8f 04 01 2f 0c 30 0f 80 60 0c c0 00 00 40 ; SPRITE_ROTATION_2 &123f 00 04 08 01 07 08 05 2f 00 07 8f 00 21 1e 80 60 06 c0 40 00 00 ; SPRITE_ROTATION_3 &1254 20 07 00 30 0e 00 10 4f 08 01 0f 00 01 2f 0c 10 87 00 30 01 08 ; SPRITE_ROTATION_4 &1269 01 0c 80 00 1e 80 03 5e 00 01 0f 00 07 8f 00 01 3c 00 03 10 80 ; SPRITE_ROTATION_5 &127e 60 07 00 30 0e 00 01 4f 08 03 0e 00 01 4f 08 30 0e 00 60 07 00 ; SPRITE_ROTATION_6 &1293 03 18 80 01 3c 00 07 8e 00 01 0f 00 07 8e 00 01 3c 00 03 18 80 ; SPRITE_ROTATION_7 &12a8 30 01 08 10 87 00 01 2f 0c 01 0f 00 10 4f 08 30 0e 00 20 07 00 ; SPRITE_ROTATION_8 &12bd 03 10 80 01 3c 00 07 8f 00 01 0f 00 03 5e 00 00 1e 80 01 0c 80 ; SPRITE_ROTATION_9 &12d2 00 00 40 60 0c c0 30 0f 80 01 2f 0c 01 8f 04 03 0d 00 02 04 00 ; SPRITE_ROTATION_10 &12e7 40 00 00 60 06 c0 21 1e 80 07 8f 00 05 2f 00 01 07 08 00 04 08 ; SPRITE_ROTATION_11 ; unused &12fc 00 00 00 00 ; enemy_type_3_shift_1_sprites &1300 40 44 40 40 ee 40 53 bf 48 53 1f 48 70 1e c0 30 14 80 00 04 00 ; SPRITE_ROTATION_0 &1315 00 04 00 30 14 80 70 1e c0 53 1f 48 53 bf 48 40 ee 40 40 44 40 ; SPRITE_ROTATION_1 &132a 20 22 00 60 ff 40 53 bf 40 53 2f c0 70 2d c0 20 38 80 00 18 00 ; SPRITE_ROTATION_2 &133f 00 88 80 51 ee c0 51 bf 48 61 9f 48 61 96 c0 30 82 80 10 02 00 ; SPRITE_ROTATION_3 &1354 30 11 00 60 77 40 53 bf 48 61 2f c0 61 78 c0 41 70 00 02 00 00 ; SPRITE_ROTATION_4 &1369 11 10 80 51 cc c0 53 bf 48 61 8f c0 70 c3 c0 10 c1 40 00 00 08 ; SPRITE_ROTATION_5 &137e 30 78 80 30 cc 00 01 6e 00 07 3f 00 01 6e 00 30 cc 00 30 78 80 ; SPRITE_ROTATION_6 &1393 70 b4 00 00 fc 00 11 8e 00 33 0f 08 11 8e 00 00 fc 00 70 b4 00 ; SPRITE_ROTATION_7 &13a8 02 00 00 41 70 00 61 78 c0 61 2f c0 53 bf 48 60 77 40 30 11 00 ; SPRITE_ROTATION_8 &13bd 00 00 08 10 c1 40 70 c3 c0 61 8f c0 53 bf 48 51 cc c0 11 10 80 ; SPRITE_ROTATION_9 &13d2 00 18 00 20 38 80 70 2d c0 53 2f c0 53 bf 40 60 ff 40 20 22 00 ; SPRITE_ROTATION_10 &13e7 10 02 00 30 82 80 61 96 c0 61 9f 48 51 bf 48 51 ee c0 00 88 80 ; SPRITE_ROTATION_11 ; unused &13fc 00 00 00 00 ; enemy_type_0_shift_2_sprites &1400 00 50 00 00 50 00 20 a0 a0 30 05 60 00 00 00 10 80 c0 30 20 60 ; SPRITE_ROTATION_0 &1415 30 20 60 10 80 c0 00 00 00 30 05 60 20 a0 a0 00 50 00 00 50 00 ; SPRITE_ROTATION_1 &142a 10 20 00 10 e0 80 00 14 a0 00 01 60 10 80 40 30 40 60 00 00 20 ; SPRITE_ROTATION_2 &143f 00 20 40 00 b0 c0 20 c1 00 30 84 00 10 00 c0 30 10 60 20 00 00 ; SPRITE_ROTATION_3 &1454 20 30 00 30 20 00 10 14 80 10 10 00 10 02 c0 10 90 00 30 10 80 ; SPRITE_ROTATION_4 &1469 00 c0 40 00 40 c0 10 82 80 00 80 80 30 04 80 00 90 80 10 80 c0 ; SPRITE_ROTATION_5 &147e 30 10 80 10 90 00 00 02 c0 00 10 00 00 02 c0 10 90 00 30 10 80 ; SPRITE_ROTATION_6 &1493 10 80 c0 00 90 80 30 04 00 00 90 00 30 04 00 00 90 80 10 80 c0 ; SPRITE_ROTATION_7 &14a8 30 10 80 10 90 00 10 02 c0 10 10 00 10 14 80 30 20 00 20 30 00 ; SPRITE_ROTATION_8 &14bd 10 80 c0 00 90 80 30 04 80 00 80 80 10 82 80 00 40 c0 00 c0 40 ; SPRITE_ROTATION_9 &14d2 00 00 20 30 40 60 10 80 40 00 01 60 00 14 a0 10 e0 80 10 20 00 ; SPRITE_ROTATION_10 &14e7 20 00 00 30 10 60 10 00 c0 30 84 00 20 c1 00 00 b0 c0 00 20 40 ; SPRITE_ROTATION_11 ; unused &14fc 00 00 00 00 ; enemy_type_1_shift_2_sprites &1500 00 50 00 00 50 00 20 f0 a0 30 f5 e0 00 f0 80 11 f8 cc 33 20 66 ; SPRITE_ROTATION_0 &1515 33 20 66 11 f8 cc 00 f0 80 30 f5 e0 20 f0 a0 00 50 00 00 50 00 ; SPRITE_ROTATION_1 &152a 10 20 00 10 e0 80 00 f4 a0 00 f1 e0 11 f8 c4 33 a0 66 00 00 22 ; SPRITE_ROTATION_2 &153f 00 20 40 00 b0 c0 20 f1 80 30 f4 80 11 f0 cc 33 30 22 22 00 00 ; SPRITE_ROTATION_3 &1554 11 30 80 11 f8 00 00 fa c0 00 f0 80 00 f1 e0 00 fc 80 11 88 c0 ; SPRITE_ROTATION_4 &1569 00 e0 44 00 70 cc 10 f2 88 00 f0 80 30 f4 80 00 f1 88 10 80 cc ; SPRITE_ROTATION_5 &157e 33 30 80 11 f8 00 00 f2 c0 10 f0 00 00 f2 c0 11 f8 00 33 30 80 ; SPRITE_ROTATION_6 &1593 10 c0 cc 00 f1 88 30 f4 00 00 f0 80 30 f4 00 00 f1 88 10 c0 cc ; SPRITE_ROTATION_7 &15a8 11 88 c0 00 fc 80 00 f1 e0 00 f0 80 00 fa c0 11 f8 00 11 30 80 ; SPRITE_ROTATION_8 &15bd 10 80 cc 00 f1 88 30 f4 80 00 f0 80 10 f2 88 00 70 cc 00 e0 44 ; SPRITE_ROTATION_9 &15d2 00 00 22 33 a0 66 11 f8 c4 00 f1 e0 00 f4 a0 10 e0 80 10 20 00 ; SPRITE_ROTATION_10 &15e7 22 00 00 33 30 22 11 f0 cc 30 f4 80 20 f1 80 00 b0 c0 00 20 40 ; SPRITE_ROTATION_11 ; unused &15fc 00 00 00 00 ; enemy_type_2_shift_2_sprites &1600 00 05 00 00 05 00 02 0f 0a 03 5f 0e 00 0f 08 10 87 c0 30 02 60 ; SPRITE_ROTATION_0 &1615 30 02 60 10 87 c0 00 0f 08 03 5f 0e 02 0f 0a 00 05 00 00 05 00 ; SPRITE_ROTATION_1 &162a 01 02 00 01 0e 08 00 4f 0a 00 1f 0e 10 87 48 30 06 60 00 00 20 ; SPRITE_ROTATION_2 &163f 00 02 04 00 0b 0c 02 1f 08 03 4f 08 10 0f c0 30 03 60 20 00 00 ; SPRITE_ROTATION_3 &1654 10 03 08 10 87 00 00 a7 0c 00 0f 08 00 1f 0e 00 c3 08 10 80 0c ; SPRITE_ROTATION_4 &1669 00 0e 40 00 07 c0 01 2f 80 00 0f 08 03 4f 08 00 1e 80 01 08 c0 ; SPRITE_ROTATION_5 &167e 30 03 08 10 87 00 00 2f 0c 01 0f 00 00 2f 0c 10 87 00 30 03 08 ; SPRITE_ROTATION_6 &1693 01 0c c0 00 1e 80 03 4f 00 00 0f 08 03 4f 00 00 1e 80 01 0c c0 ; SPRITE_ROTATION_7 &16a8 10 80 0c 00 c3 08 00 1f 0e 00 0f 08 00 a7 0c 10 87 00 10 03 08 ; SPRITE_ROTATION_8 &16bd 01 08 c0 00 1e 80 03 4f 08 00 0f 08 01 2f 80 00 07 c0 00 0e 40 ; SPRITE_ROTATION_9 &16d2 00 00 20 30 06 60 10 87 48 00 1f 0e 00 4f 0a 01 0e 08 01 02 00 ; SPRITE_ROTATION_10 &16e7 20 00 00 30 03 60 10 0f c0 03 4f 08 02 1f 08 00 0b 0c 00 02 04 ; SPRITE_ROTATION_11 ; unused &16fc 00 00 00 00 ; enemy_type_3_shift_2_sprites &1700 20 22 20 20 77 20 21 df ac 21 8f ac 30 87 e0 10 82 c0 00 02 00 ; SPRITE_ROTATION_0 &1715 00 02 00 10 82 c0 30 87 e0 21 8f ac 21 df ac 20 77 20 20 22 20 ; SPRITE_ROTATION_1 &172a 10 11 00 30 77 a8 21 df a8 21 9f 68 30 96 68 10 14 c0 00 04 80 ; SPRITE_ROTATION_2 &173f 00 44 40 20 ff 60 20 df ac 30 4f ac 30 4b e0 10 c1 40 00 81 00 ; SPRITE_ROTATION_3 &1754 10 80 88 30 33 a8 21 df ac 30 1f 68 30 3c e0 20 38 80 01 00 00 ; SPRITE_ROTATION_4 &1769 00 88 c0 20 ee 60 21 df ac 30 4f 68 30 e1 68 00 e0 28 00 00 04 ; SPRITE_ROTATION_5 &177e 10 b4 c0 10 e6 00 00 3f 00 03 1f 88 00 3f 00 10 e6 00 10 b4 c0 ; SPRITE_ROTATION_6 &1793 30 d2 80 00 76 80 00 cf 00 11 8f 0c 00 cf 00 00 76 80 30 d2 80 ; SPRITE_ROTATION_7 &17a8 01 00 00 20 38 80 30 3c e0 30 1f 68 21 df ac 30 33 a8 10 80 88 ; SPRITE_ROTATION_8 &17bd 00 00 04 00 e0 28 30 e1 68 30 4f 68 21 df ac 20 ee 60 00 88 c0 ; SPRITE_ROTATION_9 &17d2 00 04 80 10 14 c0 30 96 68 21 9f 68 21 df a8 30 77 a8 10 11 00 ; SPRITE_ROTATION_10 &17e7 00 81 00 10 c1 40 30 4b e0 30 4f ac 20 df ac 20 ff 60 00 44 40 ; SPRITE_ROTATION_11 ; unused &17fc 00 00 00 00 ; enemy_type_0_shift_3_sprites &1800 00 20 80 10 20 90 00 d0 60 10 02 18 10 00 10 00 c0 60 00 10 00 ; SPRITE_ROTATION_0 &1815 10 90 30 00 c0 60 00 00 00 10 82 38 10 50 50 00 20 80 00 20 80 ; SPRITE_ROTATION_1 &182a 00 90 00 00 f0 40 00 02 d0 00 00 38 00 c0 20 10 a0 30 00 00 10 ; SPRITE_ROTATION_2 &183f 00 10 20 00 50 e0 10 60 08 10 c2 00 00 80 60 10 80 b0 10 00 00 ; SPRITE_ROTATION_3 &1854 10 10 80 10 90 00 00 82 c0 00 80 80 00 81 60 00 c0 80 10 80 c0 ; SPRITE_ROTATION_4 &1869 00 60 20 00 20 60 00 c1 40 00 40 40 10 82 40 00 40 c0 00 c0 60 ; SPRITE_ROTATION_5 &187e 10 80 c0 00 c0 80 00 01 60 00 00 00 00 01 60 00 c0 80 10 80 c0 ; SPRITE_ROTATION_6 &1893 00 c0 60 00 40 c0 10 82 00 00 40 80 10 82 00 00 40 c0 00 c0 60 ; SPRITE_ROTATION_7 &18a8 10 80 c0 00 c0 80 00 81 60 00 80 80 00 82 c0 10 90 00 10 10 80 ; SPRITE_ROTATION_8 &18bd 00 c0 60 00 40 c0 10 82 40 00 40 40 00 c1 40 00 20 60 00 60 20 ; SPRITE_ROTATION_9 &18d2 00 00 10 10 a0 30 00 c0 20 00 00 38 00 02 d0 00 f0 40 00 90 00 ; SPRITE_ROTATION_10 &18e7 10 00 00 10 80 b0 00 80 60 10 c2 00 10 60 08 00 50 e0 00 10 20 ; SPRITE_ROTATION_11 ; unused &18fc 00 00 00 00 ; enemy_type_1_shift_3_sprites &1900 00 20 80 10 20 90 10 f0 f0 11 72 d9 11 70 d1 00 fc e6 00 10 00 ; SPRITE_ROTATION_0 &1915 11 98 33 00 fc e6 00 70 c0 10 f2 f8 10 70 d0 00 20 80 00 20 80 ; SPRITE_ROTATION_1 &192a 00 90 00 00 f0 40 00 72 d0 00 70 f8 00 fc e2 11 d8 33 00 00 11 ; SPRITE_ROTATION_2 &193f 00 10 20 00 50 e0 10 70 c8 10 f2 c0 00 f8 e6 11 20 11 11 00 00 ; SPRITE_ROTATION_3 &1954 00 98 c0 00 fc 80 00 75 e0 00 70 c0 00 70 f8 00 76 c0 00 cc 60 ; SPRITE_ROTATION_4 &1969 00 70 22 00 30 e6 00 f1 c4 00 70 c0 10 f2 c0 00 70 cc 00 c0 66 ; SPRITE_ROTATION_5 &197e 11 98 c0 00 fc 80 00 71 e0 00 f0 80 00 71 e0 00 fc 80 11 98 c0 ; SPRITE_ROTATION_6 &1993 00 e0 66 00 70 cc 10 f2 80 00 70 c0 10 f2 80 00 70 cc 00 e0 66 ; SPRITE_ROTATION_7 &19a8 00 cc 60 00 76 c0 00 70 f8 00 70 c0 00 75 e0 00 fc 80 00 98 c0 ; SPRITE_ROTATION_8 &19bd 00 c0 66 00 70 cc 10 f2 c0 00 70 c0 00 f1 c4 00 30 e6 00 70 22 ; SPRITE_ROTATION_9 &19d2 00 00 11 11 d8 33 00 fc e2 00 70 f8 00 72 d0 00 f0 40 00 90 00 ; SPRITE_ROTATION_10 &19e7 11 00 00 11 20 11 00 f8 e6 10 f2 c0 10 70 c8 00 50 e0 00 10 20 ; SPRITE_ROTATION_11 ; unused &19fc 00 00 00 00 ; enemy_type_2_shift_3_sprites &1a00 00 02 08 01 02 09 01 0f 0f 10 27 9c 10 07 1c 00 c3 68 00 01 00 ; SPRITE_ROTATION_0 &1a15 10 81 30 00 c3 68 00 07 0c 01 2f 8f 01 07 0d 00 02 08 00 02 08 ; SPRITE_ROTATION_1 &1a2a 00 09 00 00 0f 04 00 27 0d 00 07 8f 00 c3 2c 10 83 30 00 00 10 ; SPRITE_ROTATION_2 &1a3f 00 01 02 00 05 0e 01 07 8c 01 2f 0c 00 87 68 10 81 38 10 00 00 ; SPRITE_ROTATION_3 &1a54 00 81 0c 00 c3 08 00 53 0e 00 07 0c 00 07 8f 00 61 0c 00 c0 06 ; SPRITE_ROTATION_4 &1a69 00 07 20 00 03 68 00 1f 48 00 07 0c 01 2f 0c 00 07 c0 00 0c 60 ; SPRITE_ROTATION_5 &1a7e 10 81 0c 00 c3 08 00 17 0e 00 0f 08 00 17 0e 00 c3 08 10 81 0c ; SPRITE_ROTATION_6 &1a93 00 0e 60 00 07 c0 01 2f 08 00 07 0c 01 2f 08 00 07 c0 00 0e 60 ; SPRITE_ROTATION_7 &1aa8 00 c0 06 00 61 0c 00 07 8f 00 07 0c 00 53 0e 00 c3 08 00 81 0c ; SPRITE_ROTATION_8 &1abd 00 0c 60 00 07 c0 01 2f 0c 00 07 0c 00 1f 48 00 03 68 00 07 20 ; SPRITE_ROTATION_9 &1ad2 00 00 10 10 83 30 00 c3 2c 00 07 8f 00 27 0d 00 0f 04 00 09 00 ; SPRITE_ROTATION_10 &1ae7 10 00 00 10 81 38 00 87 68 01 2f 0c 01 07 8c 00 05 0e 00 01 02 ; SPRITE_ROTATION_11 ; unused &1afc 00 00 00 00 ; enemy_type_3_shift_3_sprites &1b00 10 11 10 10 33 98 10 6f de 10 4f 5e 10 c3 78 00 c1 60 00 01 00 ; SPRITE_ROTATION_0 &1b15 00 01 00 00 c1 60 10 c3 78 10 4f 5e 10 6f de 10 33 98 10 11 10 ; SPRITE_ROTATION_1 &1b2a 00 80 88 10 b3 dc 10 6f dc 10 4f bc 10 c3 b4 00 82 e0 00 02 40 ; SPRITE_ROTATION_2 &1b3f 00 22 20 10 77 b8 10 67 de 10 a7 5e 10 a5 78 00 e0 28 00 40 08 ; SPRITE_ROTATION_3 &1b54 00 c0 44 10 91 dc 10 6f de 10 87 bc 10 96 f0 10 14 c0 00 08 00 ; SPRITE_ROTATION_4 &1b69 00 44 60 10 77 30 10 6f de 10 a7 3c 10 f0 3c 00 70 14 00 00 02 ; SPRITE_ROTATION_5 &1b7e 00 d2 e0 00 f3 00 00 17 88 01 0f cc 00 17 88 00 f3 00 00 d2 e0 ; SPRITE_ROTATION_6 &1b93 10 e1 c0 00 33 c0 00 67 08 00 cf 0e 00 67 08 00 33 c0 10 e1 c0 ; SPRITE_ROTATION_7 &1ba8 00 08 00 10 14 c0 10 96 f0 10 87 bc 10 6f de 10 91 dc 00 c0 44 ; SPRITE_ROTATION_8 &1bbd 00 00 02 00 70 14 10 f0 3c 10 a7 3c 10 6f de 10 77 30 00 44 60 ; SPRITE_ROTATION_9 &1bd2 00 02 40 00 82 e0 10 c3 b4 10 4f bc 10 6f dc 10 b3 dc 00 80 88 ; SPRITE_ROTATION_10 &1be7 00 40 08 00 e0 28 10 a5 78 10 a7 5e 10 67 de 10 77 b8 00 22 20 ; SPRITE_ROTATION_11 ; unused &1bfc 00 00 00 00 ; player_shift_0_sprite &1c00 11 c4 00 11 c4 00 11 c4 00 32 e2 00 32 e2 00 32 &1c10 e2 00 74 f1 00 74 f1 00 74 f1 00 00 08 00 01 0c &1c20 00 01 0c 00 03 0e 00 03 0e 00 07 0f 00 07 0f 00 &1c30 0f 0f 08 19 4c 08 19 4c 08 19 4c 08 33 6e 00 77 &1c40 7f 00 cf 17 88 0c 01 08 08 00 08 ; player_shift_1_sprite &1c4b 00 ea 00 00 ea 00 00 ea 00 11 f1 00 11 f1 00 11 &1c5b f1 00 32 f0 88 32 f0 88 32 f0 88 00 04 00 00 0e &1c6b 00 00 0e 00 01 0f 00 01 0f 00 03 0f 08 03 0f 08 &1c7b 07 0f 0c 04 ae 04 04 ae 04 04 ae 04 11 bf 00 33 &1c8b bf 88 67 0b cc 06 00 0c 04 00 04 ; player_shift_2_sprite &1c96 00 75 00 00 75 00 00 75 00 00 f8 88 00 f8 88 00 &1ca6 f8 88 11 f0 c4 11 f0 c4 11 f0 c4 00 02 00 00 07 &1cb6 00 00 07 00 00 0f 08 00 0f 08 01 0f 0c 01 0f 0c &1cc6 03 0f 0e 02 57 02 02 57 02 02 57 02 00 df 88 11 &1cd6 df cc 33 0d 6e 03 00 06 02 00 02 ; player_shift_3_sprite &1ce1 00 32 88 00 32 88 00 32 88 00 74 c4 00 74 c4 00 &1cf1 74 c4 00 f8 e2 00 f8 e2 00 f8 e2 00 01 00 00 03 &1d01 08 00 03 08 00 07 0c 00 07 0c 00 0f 0e 00 0f 0e &1d11 01 0f 0f 01 23 89 01 23 89 01 23 89 00 67 cc 00 &1d21 ef ee 11 8e 3f 01 08 03 01 00 01 ; initial_passive_enemies_sprite_address_high ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &1d2c 0c 0c 0c 0d 0c 0c 0c 0d 0c 0c 0c 0d 0c 0c 0c 0d ; &00 &1d3c 0c 0c 0c 0e 0e 0e 0f 0f 0f 0f 0f 0f 0e 0e 0e 0c ; &10 &1d4c 0c 0c 0d 0c 0c 0c 0d 0c 0c 0c 0d 0c 0c 0c 0d 0c ; &20 &1d5c 0c 0c ; &30 ; initial_passive_enemies_screen_address_low ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &1d5e 28 6c e8 c4 40 84 00 dc 58 9c 18 f4 70 b4 30 0c ; &00 &1d6e 88 cc 48 98 b0 c8 1c 34 4c 64 7c 94 e0 f8 10 60 ; &10 &1d7e e4 a0 24 78 fc b8 3c 90 14 d0 54 a8 2c e8 6c c0 ; &20 &1d8e 44 00 ; &30 ; initial_passive_enemies_screen_address_high ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &1d90 62 63 65 5f 62 63 66 5f 62 63 66 5f 62 63 66 60 ; &00 &1da0 62 63 66 5e 5e 5e 5c 5c 5c 5c 5c 5c 5e 5e 5f 66 ; &10 &1db0 63 62 60 66 63 62 60 66 64 62 60 66 64 62 60 66 ; &20 &1dc0 64 63 ; &30 ; initial_passive_enemies_group ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &1dc2 06 07 09 04 06 07 09 04 06 07 09 04 06 07 09 04 ; &00 &1dd2 06 07 09 03 03 03 01 01 01 01 01 01 03 03 03 09 ; &10 &1de2 07 06 04 09 07 06 04 09 07 06 04 09 07 06 04 09 ; &20 &1df2 07 06 ; &30 ; unused &1df4 00 00 00 00 00 00 00 00 ; unused # &1dfc - &1dff is a copy of &1e68 - &1e6b &1dfc 77 ee dd bb ; sound_0 # Laser ; chan vol pitch dur &1e00 11 00 02 00 e0 00 2d 00 ; sound_1 # Laser ; chan vol pitch dur &1e08 10 00 03 00 ff 00 01 00 ; sound_2 # Silence channel 1 ; chan vol pitch dur &1e10 11 00 00 00 e0 00 01 00 ; sound_3 # Silence channel 0 ; chan vol pitch dur &1e18 10 00 00 00 01 00 01 00 ; sound_5 # Enemy explosion ; chan vol pitch dur &1e20 13 00 01 00 ac 00 08 00 ; sound_4 # Background sound ; chan vol pitch dur &1e28 12 00 04 00 32 00 01 00 ; envelope_0 # Enemy explosion &1e30 01 83 03 f7 08 05 04 0a 7e fd 00 f6 7e 64 ; unused # Unused envelope; would be used for laser &1e3e 02 01 ff 01 01 ff 0a 0a 6e ff ff 00 6e 6b ; envelope_2 # Laser &1e4c 03 01 00 00 00 00 00 00 19 ff ff 00 7d 78 ; envelope_3 # Background sound &1e5a 04 82 30 ff 00 01 30 01 41 00 00 00 41 41 ; laser_mask_values &1e68 77 ee dd bb ; removable_leaders_slots &1e6c 16 1b 18 19 ; unused &1e70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1e80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1e90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1ea0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1ec0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1ed0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1ee0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1ef0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; group_addresses_low ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &1f00 80 c0 00 40 80 c0 00 40 80 c0 00 40 80 c0 00 40 ; &00 &1f10 80 c0 00 40 80 c0 00 40 80 c0 00 40 80 c0 ; &10 ; unused &1f1e 00 00 ; group_addresses_high &1f20 5a 5b 5d 5e 5f 60 62 63 64 65 67 68 69 6a 6c 6d ; &00 &1f30 6e 6f 71 72 73 74 76 77 78 79 7b 7c 7d 7e ; &10 ; unused &1f3e 00 00 ; sound_6 # Enemy starting attack ; chan vol pitch dur &1f40 13 00 02 00 cc 00 26 00 ; unused # &1f48 - &1f57 is a copy of &2f57 - &2f66 &1f48 00 00 00 &1f4b 14 ; Restore default logical colours &1f4c 16 05 ; MODE 5 &1f4e 10 ; Clear graphics area &1f4f 13 02 04 00 00 00 ; Set logical colour 2 to blue &1f55 13 03 03 ; Set logical colour 3 to yellow ; sound_9 # Extra life ; chan vol pitch dur &1f58 02 00 f3 ff 91 00 08 00 ; unused # &1f60 - &1f91 is a copy of &2f6f - &2fa1 &1f60 00 0b 00 00 00 00 00 00 ; unused # &1f68 - &1f91 is a copy of &2f78 - &2fa1 &1f68 20 31 55 50 20 20 48 49 2d 53 43 4f 52 45 20 20 ; " 1UP HI-SCORE 2UP" &1f78 32 55 50 &1f7b 11 03 ; COLOUR 3 &1f7d 20 20 20 20 30 30 20 20 20 20 20 30 30 20 20 20 ; " 00 00 00" &1f8d 20 20 20 30 30 ; unused &1f92 00 00 08 02 06 0a ; sprite_small_flag &1f98 30 52 96 52 30 10 10 10 ; sprite_flag &1fa0 10 21 63 a7 a7 63 21 10 f0 1e fe be be fe 1e f0 ; sprite_life &1fb0 75 f8 f0 02 07 0f 57 8d 00 88 80 00 00 08 00 88 ; rising_movement_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &1fc0 41 41 41 01 41 41 41 01 81 41 41 01 01 01 c1 01 ; &00 # &80 set to change sprite &1fd0 01 40 81 01 01 40 40 01 81 40 40 40 01 40 40 40 ; &10 # &40 set to move vertically, clear to move horizontally &1fe0 40 40 40 00 40 40 40 00 80 40 40 00 00 00 c0 00 ; &20 # &01 set to move right or up, clear to move left or down &1ff0 00 41 80 00 00 41 41 00 80 41 41 41 00 41 41 41 ; &30 ; explosion_shift_0_sprites &2000 00 00 00 00 08 00 01 8c 00 13 4e 00 01 8c 00 00 08 00 00 00 00 ; SPRITE_EXPLOSION &2015 00 00 00 01 0c 00 13 ce 00 27 2f 00 06 03 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_TWO &202a 03 0e 00 37 6f 00 6f 37 08 4e 13 08 4e 13 08 04 01 00 00 00 00 ; SPRITE_EXPLOSION_THREE &203f 00 00 00 03 06 00 04 01 00 0c 01 08 4e 13 08 6f 37 08 06 03 00 ; SPRITE_EXPLOSION_FOUR &2054 00 00 00 00 08 00 01 8c 00 1b ce 08 1b 4e 08 2f 27 08 06 03 00 ; SPRITE_EXPLOSION_FIVE &2069 01 0c 00 17 cf 00 6f 3f 08 4e 1b 08 04 09 00 01 04 00 01 04 00 ; SPRITE_EXPLOSION_SIX &207e 07 07 00 6e 33 08 4c 11 08 08 00 08 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_SEVEN &2093 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_LAST &20a8 00 00 00 45 3f 88 45 22 88 45 2e 88 44 26 88 45 3f 88 00 00 00 ; SPRITE_SCORE_150 &20bd 00 00 00 ef 3f 88 23 26 88 ef 26 88 89 26 88 ef 3f 88 00 00 00 ; SPRITE_SCORE_200 &20d2 00 00 00 f1 fc 80 b1 64 80 f1 64 80 b1 64 80 f1 fc 80 00 00 00 ; SPRITE_SCORE_800 &20e7 00 00 00 fe f3 88 ba 62 88 fe 62 88 ba 62 88 fe f3 88 00 00 00 ; SPRITE_SCORE_800_TWO ; unused &20fc 00 00 00 0a ; explosion_shift_1_sprites &2100 00 00 00 00 04 00 00 4e 00 01 af 00 00 4e 00 00 04 00 00 00 00 ; SPRITE_EXPLOSION &2115 00 00 00 00 0e 00 01 ef 00 13 1f 08 03 01 08 00 00 00 00 00 00 ; SPRITE_EXPLOSION_TWO &212a 01 0f 00 13 bf 08 37 1b 8c 27 01 8c 27 01 8c 02 00 08 00 00 00 ; SPRITE_EXPLOSION_THREE &213f 00 00 00 01 0b 00 02 00 08 06 00 0c 27 01 8c 37 1b 8c 03 01 08 ; SPRITE_EXPLOSION_FOUR &2154 00 00 00 00 04 00 00 4e 00 05 ef 04 05 af 04 17 1b 0c 03 01 08 ; SPRITE_EXPLOSION_FIVE &2169 00 0e 00 03 ef 08 37 1f 8c 27 05 8c 02 04 08 00 0a 00 00 0a 00 ; SPRITE_EXPLOSION_SIX &217e 03 0b 08 37 11 8c 26 00 8c 04 00 04 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_SEVEN &2193 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_LAST &21a8 00 00 00 22 1f cc 22 19 44 22 1f 44 22 13 44 22 1f cc 00 00 00 ; SPRITE_SCORE_150 &21bd 00 00 00 77 1f cc 11 1b 44 77 1b 44 44 1b 44 77 1f cc 00 00 00 ; SPRITE_SCORE_200 &21d2 00 00 00 70 fe c0 50 ba 40 70 ba 40 50 ba 40 70 fe c0 00 00 00 ; SPRITE_SCORE_800 &21e7 00 00 00 77 f1 cc 55 b1 44 77 b1 44 55 b1 44 77 f1 cc 00 00 00 ; SPRITE_SCORE_800_TWO ; unused &21fc 00 00 00 81 ; explosion_shift_2_sprites &2200 00 00 00 00 02 00 00 27 00 00 5f 08 00 27 00 00 02 00 00 00 00 ; SPRITE_EXPLOSION &2215 00 00 00 00 07 00 00 7f 08 01 8f 8c 01 08 0c 00 00 00 00 00 00 ; SPRITE_EXPLOSION_TWO &222a 00 0f 08 01 df 8c 13 8d ce 13 08 4e 13 08 4e 01 00 04 00 00 00 ; SPRITE_EXPLOSION_THREE &223f 00 00 00 00 0d 08 01 00 04 03 00 06 13 08 4e 13 8d ce 01 08 0c ; SPRITE_EXPLOSION_FOUR &2254 00 00 00 00 02 00 00 27 00 02 7f 0a 02 5f 0a 03 8d 8e 01 08 0c ; SPRITE_EXPLOSION_FIVE &2269 00 07 00 01 7f 0c 13 8f ce 13 0a 4e 01 02 04 00 05 00 00 05 00 ; SPRITE_EXPLOSION_SIX &227e 01 0d 0c 13 88 ce 13 00 46 02 00 02 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_SEVEN &2293 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_LAST &22a8 00 00 00 11 07 ee 11 04 aa 11 07 aa 11 01 aa 11 07 ee 00 00 00 ; SPRITE_SCORE_150 &22bd 00 00 00 33 8f ee 00 8d aa 33 8d aa 22 05 aa 33 8f ee 00 00 00 ; SPRITE_SCORE_200 &22d2 00 00 00 30 f7 e0 20 d5 a0 30 d5 a0 20 d5 a0 30 f7 e0 00 00 00 ; SPRITE_SCORE_800 &22e7 00 00 00 33 f8 ee 22 d8 aa 33 d8 aa 22 d8 aa 33 f8 ee 00 00 00 ; SPRITE_SCORE_800_TWO ; unused &22fc 00 00 00 ee ; explosion_shift_3_sprites &2300 00 00 00 00 01 00 00 13 08 00 27 8c 00 13 08 00 01 00 00 00 00 ; SPRITE_EXPLOSION &2315 00 00 00 00 03 08 00 37 8c 00 4f 4e 00 0c 06 00 00 00 00 00 00 ; SPRITE_EXPLOSION_TWO &232a 00 07 0c 00 6f ce 01 ce 6f 01 8c 27 01 8c 27 00 08 02 00 00 00 ; SPRITE_EXPLOSION_THREE &233f 00 00 00 00 06 0c 00 08 02 01 08 03 01 8c 27 01 ce 6f 00 0c 06 ; SPRITE_EXPLOSION_FOUR &2354 00 00 00 00 01 00 00 13 08 01 37 8d 01 27 8d 01 4e 4f 00 0c 06 ; SPRITE_EXPLOSION_FIVE &2369 00 03 08 00 3f 8e 01 cf 6f 01 8d 27 00 09 02 00 02 08 00 02 08 ; SPRITE_EXPLOSION_SIX &237e 00 0e 0e 01 cc 67 01 88 23 01 00 01 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_SEVEN &2393 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; SPRITE_EXPLOSION_LAST &23a8 00 00 00 00 8b 7f 00 8a 55 00 8b 5d 00 88 5d 00 8b 7f 00 00 00 ; SPRITE_SCORE_150 &23bd 00 00 00 11 cf 7f 00 46 5d 11 ce 5d 11 02 5d 11 cf 7f 00 00 00 ; SPRITE_SCORE_200 &23d2 00 00 00 10 f3 f8 10 62 d8 10 e2 d8 10 62 d8 10 f3 f8 00 00 00 ; SPRITE_SCORE_800 &23e7 00 00 00 11 fc f7 11 64 d5 11 ec d5 11 64 d5 11 fc f7 00 00 00 ; SPRITE_SCORE_800_TWO ; unused &23fc 00 00 00 a2 ; tune_sound_data ; chan vol pitch dur &2400 01 00 01 00 29 00 08 00 &2408 01 00 01 00 45 00 04 00 &2410 01 00 01 00 65 00 08 00 &2418 01 00 01 00 45 00 04 00 &2420 01 00 01 00 59 00 08 00 &2428 01 00 01 00 21 00 08 00 &2430 02 00 00 00 00 00 04 00 &2438 02 00 02 00 75 00 04 00 &2440 02 00 02 00 75 00 04 00 &2448 02 00 02 00 75 00 02 00 &2450 02 00 02 00 79 00 06 00 &2458 02 00 02 00 75 00 04 00 &2460 03 00 03 00 59 00 08 00 &2468 03 00 03 00 59 00 08 00 &2470 03 00 03 00 59 00 08 00 &2478 03 00 03 00 59 00 08 00 &2480 03 00 03 00 65 00 08 00 &2488 03 00 03 00 51 00 04 00 &2490 01 00 01 00 3d 00 04 00 &2498 02 00 02 00 6d 00 02 00 &24a0 03 00 03 00 59 00 0c 00 &24a8 02 00 02 00 65 00 06 00 &24b0 01 00 01 00 51 00 08 00 &24b8 02 00 00 00 00 00 04 00 &24c0 01 00 01 00 3d 00 05 00 &24c8 02 00 02 00 6d 00 05 00 &24d0 03 00 00 00 00 00 09 00 &24d8 01 00 01 00 51 00 04 00 &24e0 02 00 02 00 6d 00 04 00 &24e8 01 00 01 00 21 00 04 00 &24f0 02 00 02 00 6d 00 02 00 &24f8 03 00 03 00 59 00 04 00 &2500 02 00 02 00 75 00 06 00 &2508 01 00 01 00 19 00 04 00 &2510 03 00 03 00 59 00 04 00 &2518 01 00 01 00 35 00 05 00 &2520 02 00 02 00 6d 00 05 00 &2528 03 00 00 00 00 00 05 00 &2530 01 00 01 00 49 00 08 00 &2538 02 00 02 00 65 00 02 00 &2540 03 00 03 00 59 00 04 00 &2548 02 00 02 00 61 00 02 00 &2550 03 00 03 00 59 00 09 00 &2558 02 00 02 00 59 00 02 00 &2560 02 00 02 00 51 00 02 00 &2568 01 00 01 00 21 00 05 00 &2570 02 00 02 00 59 00 03 00 &2578 02 00 02 00 65 00 02 00 &2580 01 00 01 00 3d 00 04 00 &2588 03 00 03 00 59 00 08 00 &2590 02 00 02 00 79 00 02 00 &2598 02 00 02 00 65 00 02 00 &25a0 01 00 01 00 51 00 08 00 &25a8 02 00 02 00 89 00 02 00 &25b0 02 00 02 00 79 00 02 00 &25b8 03 00 03 00 6d 00 09 00 &25c0 02 00 02 00 65 00 02 00 &25c8 02 00 02 00 59 00 03 00 &25d0 01 00 01 00 29 00 05 00 &25d8 02 00 02 00 61 00 02 00 &25e0 02 00 02 00 6d 00 02 00 &25e8 01 00 01 00 35 00 04 00 &25f0 03 00 03 00 65 00 04 00 &25f8 02 00 02 00 81 00 02 00 &2600 02 00 02 00 6d 00 02 00 &2608 01 00 01 00 45 00 04 00 &2610 03 00 03 00 59 00 0d 00 &2618 02 00 02 00 91 00 02 00 &2620 02 00 02 00 81 00 02 00 &2628 01 00 01 00 59 00 0d 00 &2630 02 00 02 00 6d 00 03 00 &2638 02 00 02 00 61 00 02 00 &2640 02 00 02 00 65 00 02 00 &2648 02 00 02 00 75 00 02 00 &2650 02 00 02 00 89 00 02 00 &2658 03 00 00 00 00 00 04 00 &2660 02 00 02 00 75 00 02 00 &2668 02 00 02 00 65 00 02 00 &2670 01 00 00 00 00 00 05 00 &2678 03 00 00 00 00 00 05 00 &2680 02 00 02 00 59 00 02 00 &2688 02 00 02 00 65 00 03 00 &2690 01 00 00 00 00 00 04 00 &2698 03 00 00 00 00 00 76 00 &26a0 02 00 02 00 75 00 02 00 &26a8 02 00 02 00 89 00 08 00 ; end_of_tune_sound_data ; unused # Source code fragment corresponding to &4a99 - &4aa6 &26b0 15 22 0d &26b3 44 c0 0c 2e 76 64 31 20 52 54 53 0d ; 17600.vd1 RTS &26bf 45 2e 31 30 0d 69 73 69 6e 74 20 4c 44 41 23 32 ; 177100\risint # Line contains "0" and CR &26cf 3a 42 49 54 26 46 45 34 44 3a 42 45 51 50 25 2b ; LDA#2: &26df 35 3a 49 4e 43 68 69 73 32 32 34 3a 4a 4d 50 28 ; BIT&FE4D: &26ef 26 34 31 39 29 0d ; BEQP%+5 ; INChis224: ; JMP(&419) &26f5 45 88 0a 2e 76 73 79 6e 63 0d ; 17800.vsync &26ff 45 ; high_scores &2700 00 00 03 00 00 00 00 00 ; 3000 &2708 00 09 02 00 00 00 00 00 ; 2900 &2710 00 08 02 00 00 00 00 00 ; 2800 &2718 00 07 02 00 00 00 00 00 ; 2700 &2720 00 06 02 00 00 00 00 00 ; 2600 &2728 00 05 02 00 00 00 00 00 ; 2500 &2730 00 04 02 00 00 00 00 00 ; 2400 &2738 00 03 02 00 00 00 00 00 ; 2300 &2740 00 02 02 00 00 00 00 00 ; 2200 &2748 00 01 02 00 00 00 00 00 ; 2100 &2750 00 00 02 00 00 00 00 00 ; 2000 &2758 00 09 01 00 00 00 00 00 ; 1900 &2760 00 08 01 00 00 00 00 00 ; 1800 &2768 00 07 01 00 00 00 00 00 ; 1700 &2770 00 06 01 00 00 00 00 00 ; 1600 &2778 00 05 01 00 00 00 00 00 ; 1500 &2780 00 04 01 00 00 00 00 00 ; 1400 &2788 00 03 01 00 00 00 00 00 ; 1300 &2790 00 02 01 00 00 00 00 00 ; 1200 &2798 00 01 01 00 00 00 00 00 ; 1100 &27a0 00 00 01 00 00 00 00 00 ; 1000 &27a8 00 09 00 00 00 00 00 00 ; 900 &27b0 00 08 00 00 00 00 00 00 ; 800 &27b8 00 07 00 00 00 00 00 00 ; 700 &27c0 00 06 00 00 00 00 00 00 ; 600 &27c8 00 05 00 00 00 00 00 00 ; 500 &27d0 00 04 00 00 00 00 00 00 ; 400 &27d8 00 03 00 00 00 00 00 00 ; 300 &27e0 00 02 00 00 00 00 00 00 ; 200 &27e8 00 01 00 00 00 00 00 00 ; 100 ; unused # Source code fragment &27f0 29 3a e7 20 c1 61 24 2c 5a 25 2c 31 29 3d 22 2e ; ):IF MID$(a$,Z%,1)=". ; high_score_names # Names contain source code fragments &2800 41 63 6f 72 6e 73 6f 66 74 0d 3a 3f 62 25 3d 97 28 c1 61 24 2c 5a 25 2c 41 ; "Acornsoft.:?b%=.(.a$,Z%,A" # :?b%=ASC(MID$(a$,Z%, &2819 41 63 6f 72 6e 73 6f 66 74 0d 3a fd 3f 28 62 25 2d 31 29 3d 97 22 2e 41 63 ; "Acornsoft.:.?(b%-1)=.".Ac" # :UNTIL?(b%-1)=ASC". &2832 41 63 6f 72 6e 73 6f 66 74 0d 29 2b 31 3a 62 25 3d 62 25 2d 31 3a 41 63 6f ; "Acornsoft.)+1:b%=b%-1:Aco" # )+1:b%=b%-1: &284b 41 63 6f 72 6e 73 6f 66 74 0d 24 2c 5a 25 2c 32 29 29 3a 5a 25 41 63 6f 72 ; "Acornsoft.$,Z%,2)):Z%Acor" # $,Z%,2)):Z% &2864 41 63 6f 72 6e 73 6f 66 74 0d 08 98 12 ed 3a 43 25 3d 62 25 41 63 6f 72 6e ; "Acornsoft.....:C%=b%Acorn" # 2200NEXT:C%=b% &287d 41 63 6f 72 6e 73 6f 66 74 0d 32 35 2c 2e 57 45 20 41 52 41 63 6f 72 6e 73 ; "Acornsoft.25,.WE ARAcorns" # 25,.WE AR &2896 41 63 6f 72 6e 73 6f 66 74 0d 2c 2e 41 52 43 41 44 49 41 63 6f 72 6e 73 6f ; "Acornsoft.,.ARCADIAcornso" # ,.ARCADIA &28af 41 63 6f 72 6e 73 6f 66 74 0d 31 20 52 54 53 0d 45 41 63 6f 72 6e 73 6f 66 ; "Acornsoft.1 RTS.EAcornsof" # 1 RTS &28c8 41 63 6f 72 6e 73 6f 66 74 0d 54 26 46 45 34 44 41 63 6f 72 6e 73 6f 66 74 ; "Acornsoft.T&FE4DAcornsoft" # T&FE4D &28e1 41 63 6f 72 6e 73 6f 66 74 0d 4a 4d 50 28 26 34 31 39 29 0d 45 88 0a 2e 76 ; "Acornsoft.JMP(&419).E...v" # JMP(&419) 17800 .v ; unused &28fa 73 79 6e 63 0d 45 ; "sync.E" ; sound_7 # Player explosion ; chan vol pitch dur &2900 00 00 02 00 06 00 0b 00 ; unused &2908 44 41 68 69 73 32 32 34 ; "DAhis224" ; envelope_player_explosion # Player explosion &2910 02 03 00 00 00 01 01 01 7e ff ff ff 7e 50 ; unused &291e 76 73 ; "vs" ; tape_command # Used unrelocated &3620 54 41 50 45 0d ; "TAPE" ; unused # Source code fragment corresponding to &4ab3 - &4ab9 &2925 54 41 6f 6c 64 32 32 34 3a 52 54 53 0d ; ... TAold224:RTS &2932 46 50 0c 2e 69 73 76 73 79 6e 63 0d ; 18000.isvsync &293e 46 b4 20 2e 60 50 32 20 4c 44 41 68 69 73 32 32 ; 18100.`P2 &294e 34 3a 43 4d 50 6f 6c 64 32 32 34 3a 52 54 53 0d ; LDAhis224: ; CMPold224: ; RTS &295e 47 18 05 5d 0d ; 18200] &2963 47 7c 05 f8 0d ; 18300RETURN &2968 47 e0 0e dd f2 46 49 4e 44 28 41 24 29 0d ; 18400DEFPROCFIND(A$) &2976 48 44 11 5a 25 3d 90 3a f5 41 25 3d 5a 25 2b 34 ; 18500Z%=PAGE: &2986 0d ; REPEAT ; A%=Z%+4 &2987 48 a8 26 e7 a9 24 41 25 3e 3d a9 41 24 e7 a7 24 ; 18600IFLEN$A%>=LENA$ &2997 41 25 2c 41 24 29 3a f1 5a 25 3f 31 2a 32 35 36 ; IFINSTR($A%,A$): &29a7 2b 5a 25 3f 32 0d ; PRINTZ%?1*256+Z%?2 &29ad 49 0c 1a 5a 25 3d 5a 25 2b 5a 25 3f 33 3a fd 5a ; 18700Z%=Z%+Z%?3: &29bd 25 3f 31 3e 26 37 46 3a e1 0d ; UNTILZ%?1>&7F: ; ENDPROC &29c7 ff # End of BASIC program ; unused # Source code fragment, doesn't correspond to any code &29c8 24 54 58 73 74 61 63 6b 31 3a 4c 44 58 23 30 3a ; ... $TXstack1: &29d8 4c 44 41 26 31 46 34 30 2c 58 3a 4a 53 52 26 46 ; LDX#0: &29e8 46 45 45 3a 49 4e 58 3a 43 50 58 23 34 30 3a 42 ; LDA&1F40,X: &29f8 4e 45 50 25 2d 39 3a 4c ; JSR&FFEE: ; INX: ; CPX#40: ; BNEP%-9: ; L ... ; enemy_type_1_shift_0_sprites &2a00 10 40 00 10 40 00 b0 e0 80 f1 f4 80 30 e0 00 76 f3 00 cc 91 88 ; SPRITE_ROTATION_0 &2a15 cc 91 88 76 f3 00 30 e0 00 f1 f4 80 b0 e0 80 10 40 00 10 40 00 ; SPRITE_ROTATION_1 &2a2a 40 80 00 70 a0 00 31 e0 80 30 f4 80 76 f1 00 ec 91 88 00 00 88 ; SPRITE_ROTATION_2 &2a3f 00 90 00 20 f0 00 b0 e4 00 f1 e0 00 74 f3 00 cc d1 88 88 00 00 ; SPRITE_ROTATION_3 &2a54 44 e0 00 76 c0 00 32 f8 00 30 e0 00 30 f4 80 33 e0 00 66 30 00 ; SPRITE_ROTATION_4 &2a69 30 91 00 10 f3 00 70 ea 00 30 e0 00 f1 e0 00 30 e6 00 60 33 00 ; SPRITE_ROTATION_5 &2a7e cc e0 00 76 c0 00 30 f8 00 70 c0 00 30 f8 00 76 c0 00 cc e0 00 ; SPRITE_ROTATION_6 &2a93 70 33 00 30 e6 00 f1 c0 00 30 e0 00 f1 c0 00 30 e6 00 70 33 00 ; SPRITE_ROTATION_7 &2aa8 66 30 00 33 e0 00 30 f4 80 30 e0 00 32 f8 00 76 c0 00 44 e0 00 ; SPRITE_ROTATION_8 &2abd 60 33 00 30 e6 00 f1 e0 00 30 e0 00 70 ea 00 10 f3 00 30 91 00 ; SPRITE_ROTATION_9 &2ad2 00 00 88 ec 91 88 76 f1 00 30 f4 80 31 e0 80 70 a0 00 40 80 00 ; SPRITE_ROTATION_10 &2ae7 88 00 00 cc d1 88 74 f3 00 f1 e0 00 b0 e4 00 20 f0 00 00 90 00 ; SPRITE_ROTATION_11 ; unused &2afc 00 00 00 00 ; unused # Source code fragment similar to &41f1 - &4213 &2b00 32 35 35 3a 53 54 41 26 35 46 42 0d ; ... 255: ; STA&5FB # Missing &41f5 -&41f7 &2b0c 39 d0 11 4c 44 41 23 30 3a 53 54 41 26 35 46 41 ; 14800LDA#0: &2b1c 0d ; STA&5FA &2b1d 3a 34 58 4a 53 52 72 61 6e 6b 64 69 73 70 6c 61 ; 14900JSRrankdisplay: &2b2d 79 3a 4c 44 41 23 39 30 3a 53 54 41 63 6f 75 6e ; LDA#90: &2b3d 74 65 72 33 3a 4c 44 41 23 32 35 35 3a 53 54 41 ; STAcounter3: &2b4d 26 34 30 43 3a 4c 44 41 23 33 3a 4a 53 52 70 72 ; LDA#255: &2b5d 6f 63 6d ; STA&40C: ; LDA#3: # Missing &420a - &420e ; JSRprocm ; envelope_6 # Tune &2b60 01 02 00 00 00 01 01 01 0f 05 f6 f6 32 4b ; envelope_7 # Tune &2b6e 02 01 00 00 00 01 01 01 1e ff fc fc 64 46 ; envelope_8 # Tune &2b7c 03 01 00 01 ff 09 01 02 32 04 fb fc 64 78 ; unused # Source code fragment similar to &421b - &429f &2b8a 35 35 3a 53 54 41 26 34 30 43 0d ; ... dx55: ; STA&40C # Missing &421f - 4233 &2b95 3a fc 0d 2e 6e 65 77 73 68 65 65 74 0d ; 15100.newsheet &2ba2 3b 60 63 4c 44 41 26 35 46 41 3a 53 54 41 26 34 ; 15200LDA&5FA: &2bb2 34 34 3a 4c 44 41 26 35 46 42 3a 53 54 41 26 34 ; STA&444: &2bc2 34 33 3a 4c 44 41 26 35 46 43 3a 53 54 41 26 34 ; LDA&5FB: &2bd2 32 32 3a 4c 44 41 26 35 46 44 3a 53 54 41 26 34 ; STA&443: &2be2 32 30 3a 4c 44 41 26 35 46 45 3a 53 54 41 26 34 ; LDA&5FC: &2bf2 32 31 3a 4c 44 41 26 35 46 46 3a 53 54 41 26 34 ; STA&422: &2c02 32 34 0d ; LDA&5FD: ; STA&420: ; LDA&5FE: ; STA&421: ; LDA&5FF: ; STA&424 &2c05 3b c4 4e 4c 44 58 26 34 32 30 3a 49 4e 58 3a 54 ; 15300LDX&420: # Missing &4258 - &425c &2c15 58 41 3a 80 23 31 35 3a 43 4d 50 23 31 30 3a 54 ; INX: &2c25 58 41 3a 42 43 43 50 25 2b 36 3a 43 4c 43 3a 54 ; TXA: &2c35 58 41 3a 41 44 43 23 36 3a 53 54 41 26 34 32 30 ; AND#15: &2c45 3a 4a 53 52 73 68 65 65 74 64 69 73 70 0d ; CMP#10: ; TXA: ; BCCP%+6: ; CLC: ; TXA: ; ADC#6: ; STA&420: ; JSRsheetdisp # Not present in actual code &2c53 3c 28 12 4c 44 41 23 34 39 3a 53 54 41 26 35 31 ; 15400LDA#49: &2c63 31 0d ; STA&511 &2c65 3c 8c 21 4c 44 41 23 30 3a 53 54 41 26 34 33 35 ; 15500LDA#0: &2c75 3a 53 54 41 26 35 31 30 3a 53 54 41 26 34 30 45 ; STA&435: # Not present in actual code &2c85 0d ; STA&510: ; STA&40E &2c86 3c f0 4d 4c 44 41 26 34 34 33 3a 53 45 43 3a 53 ; 15600LDA&443: &2c96 42 43 23 33 30 3a 43 4d 50 23 38 30 3a 42 43 53 ; SEC: &2ca6 50 25 2b 31 30 3a 41 44 43 23 32 32 3a 43 4d 50 ; SBC#30: &2cb6 23 32 33 30 3a 42 43 43 50 25 2b 34 3a 4c 44 41 ; CMP#80: &2cc6 23 31 30 30 3a 53 54 41 26 34 34 33 0d ; BCSP%+10: ; ADC#22: ; CMP#230: ; BCCP%+4: ; LDA#100: ; STA&443 &2cd3 3d 54 11 4c 44 41 23 36 3a 53 54 41 26 34 32 36 ; 15700LDA#6: &2ce3 0d ; STA&426 &2ce4 3d b8 4f 49 4e 43 26 34 34 34 3a 4c 44 41 26 34 ; 15800INC&444: &2cf4 34 34 3a 4c 44 59 23 26 38 33 3a 43 ; LDA&444: ; LDY#&83: ; C ... ; demo_text &2d00 0e 04 0a ; text at (&0e, &04), length &0a &2d03 57 45 20 41 52 45 20 54 48 45 ; "WE ARE THE" &2d0d 0e 05 0a ; text at (&0e, &05), length &0a &2d10 41 52 43 41 44 49 41 4e 53 21 ; "ARCADIANS!" &2d1a 0d 07 08 ; text at (&0d, &07), length &08 &2d1d 4d 49 53 53 49 4f 4e 3a ; "MISSION:" &2d25 12 08 12 ; text at (&12, &08), length &12 &2d28 44 45 53 54 52 4f 59 20 41 4c 4c 20 41 4c 49 45 ; "DESTROY ALL ALIENS" &2d38 4e 53 &2d3a 13 0b 14 ; text at (&13, &0b), length &14 &2d3d 53 43 4f 52 45 20 43 4f 4e 56 4f 59 2f 43 48 41 ; "SCORE CONVOY/CHARGER" &2d4d 52 47 45 52 &2d51 11 0d 0f ; text at (&11, &0d), length &0f &2d54 20 20 20 20 20 20 20 35 30 20 2f 20 31 30 30 ; " 50 / 100" &2d63 11 0e 0f ; text at (&11, &0e), length &0f &2d66 20 20 20 20 20 20 20 34 30 20 2f 20 20 38 30 ; " 40 / 80" &2d75 11 0f 0f ; text at (&11, &0f), length &0f &2d78 20 20 20 20 20 20 20 33 30 20 2f 20 20 36 30 ; " 30 / 60" &2d87 11 10 0f ; text at (&11, &10), length &0f &2d8a 20 20 20 20 20 20 20 32 30 20 2f 20 20 34 30 ; " 20 / 40" &2d99 12 13 12 ; text at (&12, &13), length &12 &2d9c 28 43 29 20 41 63 6f 72 6e 73 6f 66 74 20 31 39 ; "(C) Acornsoft 1982" &2dac 38 32 &2dae 10 17 0f ; text at (&10, &17), length &0f &2db1 50 72 65 73 73 20 22 31 22 2c 20 22 32 22 2c ; "Press "1", "2"," &2dc0 0d 19 09 ; text at (&0d, &19), length &09 &2dc3 6f 72 20 28 66 69 72 65 29 ; "or (fire)" &2dcc 10 1b 0f ; text at (&10, &1b), length &0f &2dcf 66 6f 72 20 61 20 6e 65 77 20 67 61 6d 65 2e ; "for a new game." ; unused &2dde b1 ; string_addresses_low ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2ddf 18 28 32 3c 4c 56 ce d1 43 4b 4e a3 a8 b0 b4 bf ; &00 &2def c2 d3 db e3 eb f3 fb 95 b6 ce e5 f8 ; &10 ; string_addresses_high ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2dfb 2e 2e 2e 2e 2e 2e 2e 2e 2f 2f 2f 2f 2f 2f 2f 2f ; &00 &2e0b 2f 2f 2f 2f 2f 2f 2f 30 30 30 30 30 ; &10 ; unused &2e17 00 ; string_0 &2e18 1f 05 12 ; TAB(&05, &12) &2e1b 47 61 6d 65 20 20 4f 76 65 72 ; "Game Over" &2e25 1f 05 13 ; TAB(&05, &13) ; string_1 &2e28 50 6c 61 79 65 72 20 4f 6e 65 ; "Player One ; string_2 &2e32 50 6c 61 79 65 72 20 54 77 6f ; "Player Two" ; string_3 &2e3c 1f 05 13 ; TAB(&05, &13) &2e3f 47 61 6d 65 20 53 74 61 72 74 ; "Game Start" &2e49 1f 05 12 ; TAB(&05, &12) ; string_4 &2e4c 20 20 20 20 20 20 20 20 20 20 ; " " ; string_5 &2e56 0f &2e57 16 07 ; MODE 7 &2e59 1f 08 04 ; TAB(&08, &04) &2e5c 88 8d 81 ; FLASH, DOUBLE_HEIGHT, RED &2e5f 41 72 63 61 64 69 61 6e 20 48 69 2d 73 63 6f 72 ; "Arcadian Hi-scores" &2e6f 65 73 &2e71 1f 08 05 ; TAB(&08, &05) &2e74 88 8d 81 ; FLASH, DOUBLE_HEIGHT, RED &2e77 41 72 63 61 64 69 61 6e 20 48 69 2d 73 63 6f 72 ; "Arcadian Hi-scores" &2e87 65 73 &2e89 1f 03 0c ; TAB(&03, &0c) &2e8c 59 6f 75 72 20 73 63 6f 72 65 20 6f 66 20 ; "Your score of " &2e9a 1f 07 0e ; TAB(&07, &0e) &2e9d 50 6c 65 61 73 65 20 74 79 70 65 20 69 6e 20 79 ; Please type in your name:" &2ead 6f 75 72 20 6e 61 6d 65 3a &2eb6 1f 05 12 ; TAB(&05, &12) &2eb9 84 9d 85 ; BLUE, NEW_BACKGROUND, MAGENTA &2ebc 1f 22 12 ; TAB(&22, &12) &2ebf 9c ; BLACK_BACKGROUND &2ec0 1f 0a 08 ; TAB(&0a, &08) &2ec3 57 65 6c 6c 20 64 6f 6e 65 2c 20 ; "Well done, " ; string_6 &2ece 1f 08 12 ; TAB(&08, &12) ; string_7 &2ed1 0f &2ed2 1f 0d 00 ; TAB(&0d, &00) &2ed5 82 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ; "**********" &2ee0 1f 0c 01 ; TAB(&0c, &01) &2ee3 82 2a 81 41 72 63 61 64 69 61 6e 82 2a ; "*.Arcadian.*" &2ef0 1f 0c 02 ; TAB(&0c, &02) &2ef3 82 2a 81 48 69 73 63 6f 72 65 73 82 2a ; "*.Hiscores.*" &2f00 1f 0d 03 ; TAB(&0d, &03) &2f03 82 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 00 ; "**********" &2f0f 1f 00 18 ; TAB(&00, &18) &2f12 88 86 50 72 65 73 73 83 22 31 22 2c 20 22 32 22 ; "Press."1", "2",.or.(fire).to restart" &2f22 2c 86 6f 72 83 28 66 69 72 65 29 86 74 6f 20 72 &2f32 65 73 74 61 72 74 &2f38 17 00 0b 00 00 00 00 00 00 00 00 ; Set R11: Cursor end register ; string_8 &2f43 1f 03 1f ; TAB(&03, &1f) &2f46 52 41 4e 4b 3a ; "RANK:" ; string_9 &2f4b 1f 08 1f ; TAB(&08, &1f) ; string_a &2f4e 06 ; Enable VDU drivers &2f4f 03 ; End print job &2f50 17 00 08 00 00 00 00 00 00 00 ; Set R8: Interlace and delay register &2f5a 14 ; Restore default logical colours &2f5b 16 05 ; MODE 5 &2f5d 10 ; Clear graphics area &2f5e 13 02 04 00 00 00 ; Set logical colour 2 to blue &2f64 13 03 03 00 00 00 ; Set logical colour 3 to yellow &2f6a 06 ; Enable VDU drivers &2f6b 11 01 ; COLOUR 1 &2f6d 1e ; Home text cursor to top left &2f6e 17 00 0b 00 00 00 00 00 00 00 ; Set R11: Cursor end register &2f78 20 31 55 50 20 20 48 49 2d 53 43 4f 52 45 20 20 ; " 1UP HI-SCORE 2UP" &2f88 32 55 50 &2f8b 11 03 ; COLOUR 3 &2f8d 20 20 20 20 30 30 20 20 20 20 20 30 30 20 20 20 ; " 00 00 00" &2f9d 20 20 20 30 30 &2fa2 04 ; Write text at text cursor ; string_b &2fa3 1f 01 16 ; TAB(&01, &16) &2fa6 31 30 ; "10" ; string_c &2fa8 1f 0b 1f ; TAB(&0b, &1f) &2fab 11 01 ; COLOUR 1 &2fad 51 ; "Q" &2fae 11 03 ; COLOUR 3 ; string_d &2fb0 1f 0b 1f ; TAB(&0b, &1f) &2fb3 20 ; " " ; string_e # Disable cursor &2fb4 17 00 0b 00 00 00 00 00 00 00 00 ; Set R11: Cursor end register ; string_f &2fbf 1f 11 0c ; TAB(&11, &0c) ; string_10 &2fc2 1f 15 0c ; TAB(&15, &0c) &2fc5 30 20 20 77 61 73 20 72 61 6e 6b 65 64 20 ; "0 was ranked " ; string_11 &2fd3 1f 0e 0d ; TAB(&0e, &0d) &2fd6 11 03 ; COLOUR 3 &2fd8 31 30 30 ; "100" ; string_12 &2fdb 1f 0e 0d ; TAB(&0e, &0d) &2fde 11 01 ; COLOUR 1 &2fe0 31 35 30 ; "150" ; string_13 &2fe3 1f 0e 0d ; TAB(&0e, &0d) &2fe6 11 01 ; COLOUR 1 &2fe8 32 30 30 ; "200" ; string_14 &2feb 1f 0e 0d ; TAB(&0e, &0d) &2fee 11 01 ; COLOUR 1 &2ff0 38 30 30 ; "800" ; string_15 &2ff3 1f 0e 0d ; TAB(&0e, &0d) &2ff6 11 01 ; COLOUR 1 &2ff8 20 20 20 ; " " ; string_16 &2ffb 16 07 ; MODE 7 &2ffd 1f 07 04 ; TAB(&07, &04) &3000 8d 81 9d 83 ; DOUBLE_HEIGHT, RED, NEW_BACKGROUND, YELLOW &3004 41 20 52 20 43 20 41 20 44 20 49 20 41 20 4e 20 ; "A R C A D I A N S " &3014 53 20 20 &3017 9c ; BLACK_BACKGROUND &3018 1f 07 05 ; TAB(&07, &05) &301b 8d 81 9d 83 ; DOUBLE_HEIGHT, RED, NEW_BACKGROUND, YELLOW &301f 41 20 52 20 43 20 41 20 44 20 49 20 41 20 4e 20 ; "A R C A D I A N S " &302f 53 20 20 &3032 9c ; BLACK_BACKGROUND &3033 1f 07 08 ; TAB(&07, &08) &3036 81 9d 83 ; RED, NEW_BACKGROUND, YELLOW &3039 28 63 29 20 41 63 6f 72 6e 73 6f 66 74 20 20 31 ; "(c) Acornsoft 1982 " &3049 39 38 32 20 20 &304e 9c ; BLACK_BACKGROUND &304f 1f 08 0a ; TAB(&08, &0a) &3052 81 9d 83 ; RED, NEW_BACKGROUND, YELLOW &3055 2d 2d 4a 4f 59 53 54 49 43 4b 20 4d 45 4e 55 2d ; "--JOYSTICK MENU-- " &3065 2d 20 20 &3068 9c ; BLACK_BACKGROUND &3069 1f 08 11 ; TAB(&08, &11) &306c 4f 6e 65 ; "One" &306f 1f 07 12 ; TAB(&07, &12) &3072 50 6c 61 79 65 72 ; "Player" &3078 1f 08 13 ; TAB(&08, &13) &307b 47 61 6d 65 ; "Game"" &307f 1f 1c 11 ; TAB(&1c, &11) &3082 54 77 6f ; "Two" &3085 1f 1b 12 ; TAB(&1b, &12) &3088 50 6c 61 79 65 72 ; "Player" &308e 1f 1c 13 ; TAB(&1c, &13) &3091 47 61 6d 65 ; "Game" ; string_17 &3095 1f 03 17 ; TAB(&03, &17) &3098 83 88 53 65 6c 65 63 74 20 67 61 6d 65 20 77 69 ; "Select game with joystick #1" &30a8 74 68 20 6a 6f 79 73 74 69 63 6b 20 23 31 ; string_18 # Highlight one player game &30b6 83 9d 82 ; YELLOW, NEW_BACKGROUND, GREEN &30b9 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 &30c9 9c ; BLACK_BACKGROUND &30ca 20 20 ; " " &30cd 0d 0a ; string_19 # Highlight two player game &30ce 20 20 20 ; " " &30d1 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 &30e0 82 9d 87 ; GREEN, NEW_BACKGROUND, WHITE &30e3 0d 0a ; string_1a # Unused &30e5 1f 02 1f ; TAB(&02, &1f) &30e8 41 75 74 68 6f 72 20 3a 20 4f 72 6c 61 6e 64 6f ; "Author : Orlando" ; sound_addresses_low ; 0 1 2 3 4 5 6 7 9 # 8 and a unused &30f8 00 08 10 18 28 20 40 00 50 58 60 ; sound_addresses_high ; 0 1 2 3 4 5 6 7 9 # 8 and a unused &3103 1e 1e 1e 1e 1e 1e 1f 29 1f 1f 1f ; envelope_addresses_low ; 0 1 2 3 6 7 8 # 4, 5 and 9 unused &310e 30 a0 4c 5a 68 76 60 6e 7c 2e ; envelope_addresses_high ; 0 1 2 3 6 7 8 # 4, 5 and 9 unused &3118 1e 31 1e 1e 1f 1f 2b 2b 2b 4c ; escorts_for_leaders_table ; 16 17 18 19 1a 1b &3122 00 13 14 15 1c 1d 1e 00 # Zero indicates no escort, otherwise escort slot ; unused # Source code fragment corresponding to &3234 - &3250 &312a 44 59 23 32 35 35 3a 4c 44 58 23 26 42 46 3a 4a ; ... DY#255: &313a 53 52 26 46 46 46 34 3a 54 58 41 3a 42 45 51 50 ; LDX#&BF: &314a 25 2b 34 3a 44 45 43 26 38 34 0d ; JSR&FFF4: ; TXA: ; BEQP%+4: ; DEC&84 &3155 03 20 37 4c 44 41 23 31 32 39 3a 4c 44 59 23 32 ; 800LDA#129: &3165 35 35 3a 4c 44 58 23 26 46 45 3a 4a 53 52 26 46 ; LDY#255: &3175 46 46 34 3a 54 58 41 3a 42 45 51 50 25 2b 34 3a ; LDX#&FE: &3185 49 4e 43 26 38 34 0d ; JSR&FFF4: ; TXA: ; BEQP%+4: ; INC&84 &318c 03 84 1b 2e 73 63 61 6e 64 6f 6e 65 20 4a 4d 50 ; 900.scandone &319c 6c 61 7a 61 ; JMPlaza ... ; envelope_1 # Laser &31a0 02 01 ff 00 00 ff 01 01 6e ff 00 ec 6e 5c ; unused # Source code fragment corresponding to &3251 - &325e &31ae 63 20 4a 4d 50 28 66 69 72 65 76 65 63 74 6f 72 ; ... c &31be 29 0d ; JMP(firevector) &31c0 04 4c 0e 2e 64 75 6d 6d 79 6c 61 7a 61 0d ; 1100.dummylaza &31ce 04 b0 2d 49 4e 43 26 38 34 3a 4c 44 41 64 75 6d ; 1200INC&84: &31de 64 69 72 65 63 74 3a 42 50 4c 50 25 2b 36 3a 44 ; LDAdumdrect: &31ee 45 43 26 38 34 3a 44 45 43 26 38 34 0d ; BPLP%+6: ; DEC&84: ; DEC&84: &31fb 05 14 1c 4c 44 ; 1300LD ... ; entry_point # Used unrelocated &3f00 4c d0 60 JMP &60d0 ; relocate_binary ; check_for_keyboard_fire &3203 a9 81 LDA #&81 ; Scan for a particular key &3205 a0 ff LDY #&ff &3207 a2 b6 LDX #&b6 ; RETURN &3209 20 f4 ff JSR &fff4 ; OSBYTE &320c 8a TXA &320d 60 RTS ; check_for_joystick_one_fire &320e a2 00 LDX #&00 ; joystick buttons &3210 a9 80 LDA #&80 ; Read I/O device or buffer status &3212 20 f4 ff JSR &fff4 ; OSBYTE &3215 d8 CLD &3216 8a TXA &3217 29 01 AND #&01 &3219 aa TAX &321a 60 RTS ; check_for_joystick_two_fire &321b a2 00 LDX #&00 ; joystick buttons &321d a9 80 LDA #&80 ; Read I/O device or buffer status &321f 20 f4 ff JSR &fff4 ; OSBYTE &3222 d8 CLD &3223 8a TXA &3224 29 02 AND #&02 &3226 aa TAX &3227 60 RTS ; check_for_demo_fire &3228 a2 ff LDX #&ff &322a ad 01 04 LDA &0401 ; laser_firing_suppressed # Zero if firing suppressed &322d d0 01 BNE &3230 ; skip_suppressing_fire # Always fire when possible &322f e8 INX ; skip_suppressing_fire &3230 8a TXA &3231 60 RTS ; check_for_keyboard_movement &3232 a9 81 LDA #&81 ; Scan for a particular key &3234 a0 ff LDY #&ff &3236 a2 bf LDX #&bf ; CAPSLOCK &3238 20 f4 ff JSR &fff4 ; OSBYTE &323b 8a TXA &323c f0 02 BEQ &3240 ; capslock_not_pressed &323e c6 84 DEC &84 ; player_x ; capslock_not_pressed &3240 a9 81 LDA #&81 ; Scan for a particular key &3242 a0 ff LDY #&ff &3244 a2 fe LDX #&fe ; CTRL &3246 20 f4 ff JSR &fff4 ; OSBYTE &3249 8a TXA &324a f0 02 BEQ &324e ; ctrl_not_pressed &324c e6 84 INC &84 ; player_x ; ctrl_not_pressed ; to_move_player &324e 4c d7 40 JMP &40d7 ; move_player ; check_for_firing &3251 6c 12 00 JMP (&0012) ; firing_check_routine_address ; check_for_demo_movement &3254 e6 84 INC &84 ; player_x &3256 a5 50 LDA &50 ; demo_direction # Top bit set if moving left, clear if moving right &3258 10 04 BPL &325e ; moving_right ; moving_left &325a c6 84 DEC &84 ; player_x &325c c6 84 DEC &84 ; player_x ; moving_right &325e a5 84 LDA &84 ; player_x &3260 c9 05 CMP #&05 &3262 d0 06 BNE &326a ; not_at_left_edge # If the player is at the left edge of the screen, &3264 a9 00 LDA #&00 # Clear top bit to move right &3266 85 50 STA &50 ; demo_direction &3268 f0 08 BEQ &3272 ; set_demo_direction_change_cooldown ; not_at_left_edge &326a c9 97 CMP #&97 &326c d0 0e BNE &327c ; not_at_right_edge # If the player is at the right edge of the screen &326e a9 ff LDA #&ff # Set top bit to move left &3270 85 50 STA &50 ; demo_direction ; set_demo_direction_change_cooldown &3272 20 c8 3e JSR &3ec8 ; rnd &3275 29 1f AND #&1f &3277 85 51 STA &51 ; demo_direction_change_cooldown &3279 4c d7 40 JMP &40d7 ; move_player ; not_at_right_edge &327c c6 51 DEC &51 ; demo_direction_change_cooldown &327e d0 ce BNE &324e ; to_move_player # Is it time to change direction? &3280 20 c8 3e JSR &3ec8 ; rnd &3283 85 50 STA &50 ; demo_direction &3285 20 c8 3e JSR &3ec8 ; rnd # Shouldn't return zero &3288 29 1f AND #&1f &328a 85 51 STA &51 ; demo_direction_change_cooldown &328c d0 c0 BNE &324e ; to_move_player # Should always branch ; check_for_joystick_one_movement &328e a2 01 LDX #&01 ; Analogue channel 1 (joystick one x) &3290 d0 02 BNE &3294 ; check_for_joystick_movement # Always branches ; check_for_joystick_two_movement &3292 a2 03 LDX #&03 ; Analogue channel 3 (joystick two x) ; check_for_joystick_movement &3294 a9 80 LDA #&80 ; Read I/O device or buffer status &3296 20 f4 ff JSR &fff4 ; OSBYTE &3299 c0 0f CPY #&0f &329b b0 02 BCS &329f ; not_right &329d e6 84 INC &84 ; player_x ; not_right &329f c0 f0 CPY #&f0 &32a1 90 02 BCC &32a5 ; not_left &32a3 c6 84 DEC &84 ; player_x ; not_left &32a5 4c 4e 32 JMP &324e ; to_move_player ; unused # Unused code &32a8 c0 e7 CPY #&e7 &32aa 90 16 BCC &32c2 ; to_to_move_player &32ac c0 ff CPY #&ff &32ae d0 08 BNE &32b8 ; not_left &32b0 e0 a0 CPX #&a0 &32b2 90 04 BCC &32b8 ; not_left &32b4 c6 84 DEC &84 ; player_x &32b6 d0 0a BNE &32c2 ; to_to_move_player ; not_left &32b8 8a TXA &32b9 c5 40 CMP &40 ; unused_40 &32bb 98 TYA &32bc e5 41 SBC &41 ; unused_41 &32be b0 02 BCS &32c2 ; to_to_move_player &32c0 c6 84 DEC &84 ; player_x ; to_to_move_player &32c2 84 41 STY &41 ; unused_41 &32c4 86 40 STX &40 ; unused_40 &32c6 4c 4e 32 JMP &324e ; to_move_player ; set_movement_and_firing_check_routine_addresses &32c9 0a ASL A &32ca 0a ASL A &32cb aa TAX &32cc bd a0 53 LDA &53a0,X ; movement_and_firing_check_routines_addresses_table &32cf 85 10 STA &10 ; movement_check_routine_address_low &32d1 bd a1 53 LDA &53a1,X ; movement_and_firing_check_routines_addresses_table + 1 &32d4 85 11 STA &11 ; movement_check_routine_address_high &32d6 bd a2 53 LDA &53a2,X ; movement_and_firing_check_routines_addresses_table + 2 &32d9 85 12 STA &12 ; firing_check_routine_address_low &32db bd a3 53 LDA &53a3,X ; movement_and_firing_check_routines_addresses_table + 3 &32de 85 13 STA &13 ; firing_check_routine_address_high &32e0 60 RTS ; update_background_sound &32e1 ce 29 05 DEC &0529 ; background_sound_cooldown &32e4 f0 01 BEQ &32e7 ; end_of_cooldown ; leave &32e6 60 RTS ; end_of_cooldown &32e7 ad 2d 04 LDA &042d ; background_sound_start_cooldown &32ea d0 fa BNE &32e6 ; leave &32ec ad 28 05 LDA &0528 ; background_sound_tempo &32ef 8d 29 05 STA &0529 ; background_sound_cooldown &32f2 ad 2a 05 LDA &052a ; background_sound_pitch &32f5 8d 2c 1e STA &1e2c ; sound_4 + 4 (pitch) &32f8 a9 03 LDA #&03 ; envelope_3 # Use background sound envelope &32fa 20 ba 4a JSR &4aba ; define_envelope &32fd a9 04 LDA #&04 ; sound_4 &32ff 4c c8 4a JMP &4ac8 ; play_sound ; plot_player_sprite_with_collision_check &3302 a9 19 LDA #&19 &3304 d0 02 BNE &3308 ; plot_sprite_with_collision_check # Always branches ; plot_enemy_sprite_with_collision_check # Unused entry point &3306 a9 07 LDA #&07 ; plot_sprite_with_collision_check &3308 85 74 STA &74 ; height &330a a2 72 LDX #&72 ; sprite_address &330c a0 00 LDY #&00 &330e 84 77 STY &77 ; collision_result &3310 a5 73 LDA &73 ; sprite_address_high &3312 c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &3314 d0 04 BNE &331a ; skip_patching &3316 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites &3318 85 73 STA &73 ; sprite_address_high ; skip_patching &331a 18 CLC ; plot_sprite_with_collision_check_row_loop &331b a9 03 LDA #&03 &331d 85 75 STA &75 ; width ; plot_sprite_with_collision_check_column_loop &331f a1 00 LDA (&00,X) ; sprite_address - &72 &3321 85 76 STA &76 ; sprite_byte &3323 51 70 EOR (&70),Y ; screen_address &3325 91 70 STA (&70),Y ; screen_address &3327 25 76 AND &76 ; sprite_byte &3329 45 76 EOR &76 ; sprite_byte &332b d0 35 BNE &3362 ; leave_with_collision &332d f6 00 INC &00,X ; sprite_address_low - &72 &332f d0 02 BNE &3333 ; skip_page &3331 f6 01 INC &01,X ; sprite_address_high - &72 ; skip_page &3333 98 TYA &3334 69 08 ADC #&08 # Move right four pixels &3336 a8 TAY &3337 c6 75 DEC &75 ; width &3339 d0 e4 BNE &331f ; plot_sprite_with_collision_check_column_loop &333b c6 74 DEC &74 ; height &333d f0 22 BEQ &3361 ; leave &333f 38 SEC &3340 e9 17 SBC #&17 # Move left twelve pixels &3342 a8 TAY &3343 18 CLC &3344 65 70 ADC &70 ; screen_address_low &3346 18 CLC &3347 29 07 AND #&07 &3349 d0 d0 BNE &331b ; plot_sprite_with_collision_check_row_loop &334b a5 70 LDA &70 ; screen_address_low &334d 69 38 ADC #&38 # Move down a group &334f 85 70 STA &70 ; screen_address_low &3351 a5 71 LDA &71 ; screen_address_high &3353 69 01 ADC #&01 &3355 85 71 STA &71 ; screen_address_high &3357 a5 70 LDA &70 ; screen_address_low &3359 c9 c0 CMP #&c0 ; &7ec0 = group &1d &335b a5 71 LDA &71 ; screen_address_high &335d e9 7e SBC #&7e &335f 90 ba BCC &331b ; plot_sprite_with_collision_check_row_loop ; leave &3361 60 RTS ; leave_with_collision &3362 e6 77 INC &77 ; collision_result # Set to non-zero to indicate collision &3364 60 RTS ; unplot_player_sprite_with_collision_check &3365 a9 19 LDA #&19 &3367 d0 02 BNE &336b ; unplot_sprite_with_collision_check # Always branches ; unplot_enemy_sprite_with_collision_check # Unused entry point &3369 a9 07 LDA #&07 ; unplot_sprite_with_collision_check &336b 85 74 STA &74 ; height &336d a2 72 LDX #&72 ; sprite_address &336f a0 00 LDY #&00 &3371 84 77 STY &77 ; collision_result # Set to zero to indicate no collision &3373 a5 73 LDA &73 ; sprite_address_high &3375 c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &3377 d0 04 BNE &337d ; skip_patching &3379 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites &337b 85 73 STA &73 ; sprite_address_high ; skip_patching &337d 18 CLC ; unplot_sprite_with_collision_check_row_loop &337e a9 03 LDA #&03 &3380 85 75 STA &75 ; width ; unplot_sprite_with_collision_check_column_loop &3382 a1 00 LDA (&00,X) ; sprite_address - &72 &3384 51 70 EOR (&70),Y ; screen_address &3386 91 70 STA (&70),Y ; screen_address &3388 21 00 AND (&00,X) ; sprite_address - &72 &338a d0 d6 BNE &3362 ; leave_with_collision &338c f6 00 INC &00,X ; sprite_address_low - &72 &338e d0 02 BNE &3392 ; skip_page &3390 f6 01 INC &01,X ; sprite_address_high - &72 ; skip_page &3392 98 TYA &3393 69 08 ADC #&08 # Move right four pixels &3395 a8 TAY &3396 c6 75 DEC &75 ; width &3398 d0 e8 BNE &3382 ; unplot_sprite_with_collision_check_column_loop &339a c6 74 DEC &74 ; height &339c f0 c3 BEQ &3361 ; leave &339e 38 SEC &339f e9 17 SBC #&17 # Move left twelve pixels &33a1 a8 TAY &33a2 18 CLC &33a3 65 70 ADC &70 ; screen_address_low &33a5 18 CLC &33a6 29 07 AND #&07 &33a8 d0 d4 BNE &337e ; unplot_sprite_with_collision_check_row_loop &33aa a5 70 LDA &70 ; screen_address_low &33ac 69 38 ADC #&38 # Move down a group &33ae 85 70 STA &70 ; screen_address_low &33b0 a5 71 LDA &71 ; screen_address_high &33b2 69 01 ADC #&01 &33b4 85 71 STA &71 ; screen_address_high &33b6 a5 70 LDA &70 ; screen_address_low &33b8 c9 c0 CMP #&c0 ; &7ec0 = group &1d &33ba a5 71 LDA &71 ; screen_address_high &33bc e9 7e SBC #&7e &33be 90 be BCC &337e ; unplot_sprite_with_collision_check_row_loop &33c0 60 RTS ; unplot_player_sprite # Unused entry point &33c1 a9 19 LDA #&19 &33c3 d0 02 BNE &33c7 ; unplot_sprite # Always branches ; unplot_enemy_sprite &33c5 a9 07 LDA #&07 ; unplot_sprite &33c7 85 74 STA &74 ; height &33c9 a2 72 LDX #&72 ; sprite_address &33cb a5 73 LDA &73 ; sprite_address_high &33cd c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &33cf d0 04 BNE &33d5 ; skip_patching &33d1 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites &33d3 85 73 STA &73 ; sprite_address_high ; skip_patching &33d5 18 CLC ; unplot_sprite_row_loop &33d6 a0 00 LDY #&00 &33d8 a1 00 LDA (&00,X) ; sprite_address - &72 &33da 49 ff EOR #&ff &33dc 31 70 AND (&70),Y ; screen_address &33de 91 70 STA (&70),Y ; screen_address &33e0 f6 00 INC &00,X ; sprite_address_low - &72 &33e2 a0 08 LDY #&08 &33e4 a1 00 LDA (&00,X) ; sprite_address - &72 &33e6 49 ff EOR #&ff &33e8 31 70 AND (&70),Y ; screen_address &33ea 91 70 STA (&70),Y ; screen_address &33ec f6 00 INC &00,X ; sprite_address_low - &72 &33ee a0 10 LDY #&10 &33f0 a1 00 LDA (&00,X) ; sprite_address - &72 &33f2 49 ff EOR #&ff &33f4 31 70 AND (&70),Y ; screen_address &33f6 91 70 STA (&70),Y ; screen_address &33f8 f6 00 INC &00,X ; sprite_address_low - &72 &33fa c6 74 DEC &74 ; height &33fc f0 23 BEQ &3421 ; leave &33fe e6 70 INC &70 ; screen_address_low &3400 d0 02 BNE &3404 ; skip_page &3402 e6 71 INC &71 ; screen_address_high ; skip_page &3404 a5 70 LDA &70 ; screen_address_low &3406 29 07 AND #&07 &3408 d0 cc BNE &33d6 ; unplot_sprite_row_loop &340a 18 CLC &340b a5 70 LDA &70 ; screen_address_low &340d 69 38 ADC #&38 # Move down a group &340f 85 70 STA &70 ; screen_address_low &3411 a5 71 LDA &71 ; screen_address_high &3413 69 01 ADC #&01 &3415 85 71 STA &71 ; screen_address_high &3417 a5 70 LDA &70 ; screen_address_low &3419 c9 c0 CMP #&c0 ; &7ec0 = group &1d &341b a5 71 LDA &71 ; screen_address_high &341d e9 7e SBC #&7e &341f 90 b5 BCC &33d6 ; unplot_sprite_row_loop ; leave &3421 60 RTS ; plot_player_sprite &3422 a9 19 LDA #&19 &3424 d0 02 BNE &3428 ; plot_sprite # Always branches ; plot_enemy_sprite &3426 a9 07 LDA #&07 ; plot_sprite &3428 85 74 STA &74 ; height &342a a2 72 LDX #&72 ; sprite_address &342c a5 73 LDA &73 ; sprite_address_high &342e c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &3430 d0 04 BNE &3436 ; skip_patching &3432 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites &3434 85 73 STA &73 ; sprite_address_high ; skip_patching &3436 18 CLC ; plot_sprite_row_loop &3437 a0 00 LDY #&00 &3439 a1 00 LDA (&00,X) ; sprite_address - &72 &343b 11 70 ORA (&70),Y ; screen_address &343d 91 70 STA (&70),Y ; screen_address &343f f6 00 INC &00,X ; sprite_address_low - &72 &3441 a0 08 LDY #&08 &3443 a1 00 LDA (&00,X) ; sprite_address - &72 &3445 11 70 ORA (&70),Y ; screen_address &3447 91 70 STA (&70),Y ; screen_address &3449 f6 00 INC &00,X ; sprite_address_low - &72 &344b a0 10 LDY #&10 &344d a1 00 LDA (&00,X) ; sprite_address - &72 &344f 11 70 ORA (&70),Y ; screen_address &3451 91 70 STA (&70),Y ; screen_address &3453 f6 00 INC &00,X ; sprite_address_low - &72 &3455 c6 74 DEC &74 ; height &3457 f0 23 BEQ &347c ; leave &3459 e6 70 INC &70 ; screen_address_low &345b d0 02 BNE &345f ; skip_page &345d e6 71 INC &71 ; screen_address_high ; skip_page &345f a5 70 LDA &70 ; screen_address_low &3461 29 07 AND #&07 &3463 d0 d2 BNE &3437 ; plot_sprite_row_loop &3465 18 CLC &3466 a5 70 LDA &70 ; screen_address_low &3468 69 38 ADC #&38 # Move down a group &346a 85 70 STA &70 ; screen_address_low &346c a5 71 LDA &71 ; screen_address_high &346e 69 01 ADC #&01 &3470 85 71 STA &71 ; screen_address_high &3472 a5 70 LDA &70 ; screen_address_low &3474 c9 c0 CMP #&c0 ; &7ec0 = group &1d &3476 a5 71 LDA &71 ; screen_address_high &3478 e9 7e SBC #&7e &347a 90 bb BCC &3437 ; plot_sprite_row_loop ; leave &347c 60 RTS ; plot_enemy_sprite_with_overwrite &347d a9 03 LDA #&03 &347f 8d 96 34 STA &3496 ; sprite_width &3482 a9 07 LDA #&07 &3484 85 74 STA &74 ; height &3486 a2 72 LDX #&72 ; sprite_address &3488 a0 00 LDY #&00 &348a a5 73 LDA &73 ; sprite_address_high &348c c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &348e d0 04 BNE &3494 ; skip_patching &3490 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites &3492 85 73 STA &73 ; sprite_address_high ; skip_patching &3494 18 CLC ; plot_enemy_sprite_with_overwrite_row_loop &3495 a9 03 LDA #&03 # actually LDA sprite_width &3497 85 75 STA &75 ; width ; plot_enemy_sprite_with_overwrite_column_loop &3499 a1 00 LDA (&00,X) ; sprite_address - &72 &349b 91 70 STA (&70),Y ; screen_address &349d f6 00 INC &00,X ; sprite_address_low - &72 &349f 98 TYA &34a0 18 CLC &34a1 69 08 ADC #&08 # Move right four pixels &34a3 a8 TAY &34a4 c6 75 DEC &75 ; width &34a6 d0 f1 BNE &3499 ; plot_enemy_sprite_with_overwrite_column_loop &34a8 c6 74 DEC &74 ; height &34aa f0 25 BEQ &34d1 ; leave &34ac a0 00 LDY #&00 &34ae e6 70 INC &70 ; screen_address_low &34b0 d0 02 BNE &34b4 ; skip_page &34b2 e6 71 INC &71 ; screen_address_high ; skip_page &34b4 a5 70 LDA &70 ; screen_address_low &34b6 29 07 AND #&07 &34b8 d0 db BNE &3495 ; plot_enemy_sprite_with_overwrite_row_loop &34ba 18 CLC &34bb a5 70 LDA &70 ; screen_address_low &34bd 69 38 ADC #&38 # Move down a group &34bf 85 70 STA &70 ; screen_address_low &34c1 a5 71 LDA &71 ; screen_address_high &34c3 69 01 ADC #&01 &34c5 85 71 STA &71 ; screen_address_high &34c7 a5 70 LDA &70 ; screen_address_low &34c9 c9 c0 CMP #&c0 ; &7ec0 = group &1d &34cb a5 71 LDA &71 ; screen_address_high &34cd e9 7e SBC #&7e &34cf 90 c4 BCC &3495 ; plot_enemy_sprite_with_overwrite_row_loop ; leave &34d1 60 RTS ; unplot_bottom_of_laser &34d2 ad 03 04 LDA &0403 ; laser_screen_address_high &34d5 85 71 STA &71 ; screen_address_high &34d7 ad 02 04 LDA &0402 ; laser_screen_address_low &34da 85 70 STA &70 ; screen_address_low &34dc 29 04 AND #&04 &34de f0 0d BEQ &34ed ; is_group_aligned &34e0 a5 70 LDA &70 ; screen_address_low &34e2 18 CLC &34e3 69 38 ADC #&38 # Move down a group &34e5 85 70 STA &70 ; screen_address_low &34e7 a5 71 LDA &71 ; screen_address_high &34e9 69 01 ADC #&01 &34eb 85 71 STA &71 ; screen_address_high ; is_group_aligned &34ed a0 04 LDY #&04 ; unplot_bottom_of_laser_loop &34ef b1 70 LDA (&70),Y ; screen_address &34f1 2d 04 04 AND &0404 ; laser_mask &34f4 91 70 STA (&70),Y ; screen_address &34f6 c8 INY &34f7 c0 08 CPY #&08 &34f9 d0 f4 BNE &34ef ; unplot_bottom_of_laser_loop &34fb 60 RTS ; plot_top_of_laser_with_collision_check &34fc ad 02 04 LDA &0402 ; laser_screen_address_low &34ff 85 70 STA &70 ; screen_address_low &3501 ad 03 04 LDA &0403 ; laser_screen_address_high &3504 85 71 STA &71 ; screen_address_high &3506 ad 04 04 LDA &0404 ; laser_mask &3509 49 ff EOR #&ff &350b 85 72 STA &72 ; laser_pixel_value &350d a0 03 LDY #&03 ; plot_top_of_laser_with_collision_check_loop &350f b1 70 LDA (&70),Y ; screen_address &3511 45 72 EOR &72 ; laser_pixel_value &3513 91 70 STA (&70),Y ; screen_address &3515 25 72 AND &72 ; laser_pixel_value &3517 45 72 EOR &72 ; laser_pixel_value &3519 d0 04 BNE &351f ; to_handle_laser_collision &351b 88 DEY &351c 10 f1 BPL &350f ; plot_top_of_laser_with_collision_check_loop &351e 60 RTS ; to_handle_laser_collision &351f 4c f3 51 JMP &51f3 ; handle_laser_collision ; plot_laser &3522 ad 02 04 LDA &0402 ; laser_screen_address_low &3525 85 70 STA &70 ; screen_address_low &3527 ad 03 04 LDA &0403 ; laser_screen_address_high &352a 85 71 STA &71 ; screen_address_high &352c a9 ff LDA #&ff &352e 38 SEC &352f e5 70 SBC &70 ; screen_address_low &3531 29 07 AND #&07 &3533 48 PHA ; row in group &3534 a8 TAY &3535 ad 04 04 LDA &0404 ; laser_mask &3538 49 ff EOR #&ff &353a 85 72 STA &72 ; laser_pixel_value ; plot_laser_top_loop &353c b1 70 LDA (&70),Y ; screen_address &353e 05 72 ORA &72 ; laser_pixel_value &3540 91 70 STA (&70),Y ; screen_address &3542 88 DEY &3543 10 f7 BPL &353c ; plot_laser_top_loop &3545 68 PLA ; row in group &3546 c9 07 CMP #&07 &3548 d0 01 BNE &354b ; plot_laser_bottom &354a 60 RTS ; plot_laser_bottom &354b a8 TAY &354c 18 CLC &354d a5 70 LDA &70 ; screen_address_low &354f 69 38 ADC #&38 # Move down a group &3551 85 70 STA &70 ; screen_address_low &3553 a5 71 LDA &71 ; screen_address_high &3555 69 01 ADC #&01 &3557 85 71 STA &71 ; screen_address_high &3559 c8 INY ; plot_laser_bottom_loop &355a b1 70 LDA (&70),Y ; screen_address &355c 05 72 ORA &72 ; laser_pixel_value &355e 91 70 STA (&70),Y ; screen_address &3560 c8 INY &3561 c0 08 CPY #&08 &3563 90 f5 BCC &355a ; plot_laser_bottom_loop &3565 60 RTS ; unplot_laser &3566 ad 02 04 LDA &0402 ; laser_screen_address_low &3569 85 70 STA &70 ; screen_address_low &356b ad 03 04 LDA &0403 ; laser_screen_address_high &356e 85 71 STA &71 ; screen_address_high &3570 a9 ff LDA #&ff &3572 38 SEC &3573 e5 70 SBC &70 ; screen_address_low &3575 29 07 AND #&07 &3577 48 PHA ; row in group &3578 a8 TAY ; unplot_laser_top_loop &3579 b1 70 LDA (&70),Y ; screen_address &357b 2d 04 04 AND &0404 ; laser_mask &357e 91 70 STA (&70),Y ; screen_address &3580 88 DEY &3581 10 f6 BPL &3579 ; unplot_laser_top_loop &3583 68 PLA ; row in group &3584 c9 07 CMP #&07 &3586 d0 01 BNE &3589 ; unplot_laser_bottom &3588 60 RTS ; unplot_laser_bottom &3589 a8 TAY &358a 18 CLC &358b a5 70 LDA &70 ; screen_address_low &358d 69 38 ADC #&38 # Move down a group &358f 85 70 STA &70 ; screen_address_low &3591 a5 71 LDA &71 ; screen_address_high &3593 69 01 ADC #&01 &3595 85 71 STA &71 ; screen_address_high &3597 c8 INY ; unplot_laser_bottom_loop &3598 b1 70 LDA (&70),Y ; screen_address &359a 2d 04 04 AND &0404 ; laser_mask &359d 91 70 STA (&70),Y ; screen_address &359f c8 INY &35a0 c0 08 CPY #&08 &35a2 90 f4 BCC &3598 ; unplot_laser_bottom_loop &35a4 60 RTS ; wipe_game_area &35a5 a9 80 LDA #&80 ; &5a80 = group &00 &35a7 85 70 STA &70 ; screen_address_low &35a9 a2 7e LDX #&7e &35ab a9 5a LDA #&5a &35ad 85 71 STA &71 ; screen_address_high &35af a9 00 LDA #&00 &35b1 a8 TAY ; wipe_5a80_to_7dff_loop &35b2 91 70 STA (&70),Y ; screen_address &35b4 e6 70 INC &70 ; screen_address_low &35b6 d0 fa BNE &35b2 ; wipe_5a80_to_7dff_loop &35b8 e6 71 INC &71 ; screen_address_high &35ba e4 71 CPX &71 ; screen_address_high &35bc d0 f4 BNE &35b2 ; wipe_5a80_to_7dff_loop &35be a0 c0 LDY #&c0 ; &7ec0 = group &1d ; wipe_7e00_to_7ebf_loop &35c0 99 ff 7d STA &7dff,Y &35c3 88 DEY &35c4 d0 fa BNE &35c0 ; wipe_7e00_to_7ebf_loop &35c6 60 RTS ; wipe_bottom_half_of_game_area &35c7 a9 80 LDA #&80 ; &6e80 = group &10 &35c9 85 70 STA &70 ; screen_address_low &35cb a2 7e LDX #&7e &35cd a9 6e LDA #&6e &35cf 85 71 STA &71 ; screen_address_high &35d1 a9 00 LDA #&00 &35d3 a8 TAY ; wipe_6e00_to_7dff_loop &35d4 91 70 STA (&70),Y ; screen_address &35d6 e6 70 INC &70 ; screen_address_low &35d8 d0 fa BNE &35d4 ; wipe_6e00_to_7dff_loop &35da e6 71 INC &71 ; screen_address_high &35dc e4 71 CPX &71 ; screen_address_high &35de d0 f4 BNE &35d4 ; wipe_6e00_to_7dff_loop &35e0 a0 c0 LDY #&c0 ; &7ec0 = group &1d ; wipe_7e00_to_7ebf_loop &35e2 99 ff 7d STA &7dff,Y &35e5 88 DEY &35e6 d0 fa BNE &35e2; wipe_7e00_to_7ebf_loop &35e8 60 RTS ; wipe_bottom_quarter_of_game_area &35e9 a9 80 LDA #&80 ; &7380 = group &14 &35eb 85 70 STA &70 ; screen_address_low &35ed a2 7e LDX #&7e &35ef a9 73 LDA #&73 &35f1 85 71 STA &71 ; screen_address_high &35f3 a9 00 LDA #&00 &35f5 a8 TAY ; wipe_7380_to_7dff_loop &35f6 91 70 STA (&70),Y ; screen_address &35f8 e6 70 INC &70 ; screen_address_low &35fa d0 fa BNE &35f6 ; wipe_7380_to_7dff_loop &35fc e6 71 INC &71 ; screen_address_high &35fe e4 71 CPX &71 ; screen_address_high &3600 d0 f4 BNE &35f6 ; wipe_7380_to_7dff_loop &3602 a0 c0 LDY #&c0 ; &7ec0 = group &1d ; wipe_7e00_to_7ebf_loop &3604 99 ff 7d STA &7dff,Y &3607 88 DEY &3608 d0 fa BNE &3604 ; wipe_7e00_to_7ebf_loop &360a 60 RTS ; check_for_sound_keys_and_escape &360b e6 79 INC &79 ; update_counter &360d d0 07 BNE &3616 ; skip_flush # Every 256 updates, flush input buffer &360f a9 0f LDA #&0f ; input buffer &3611 a2 01 LDX #&01 ; Flush buffer &3613 20 f4 ff JSR &fff4 ; OSBYTE ; skip_flush &3616 ad 2d 04 LDA &042d ; background_sound_start_cooldown &3619 f0 03 BEQ &361e ; skip_reducing_cooldown &361b ce 2d 04 DEC &042d ; background_sound_start_cooldown ; skip_reducing_cooldown &361e ce 39 04 DEC &0439 ; sound_key_check_cooldown &3621 d0 50 BNE &3673 ; check_for_escape &3623 a9 0c LDA #&0c # Check for sound keys every 12 updates &3625 8d 39 04 STA &0439 ; sound_key_check_cooldown &3628 ad 38 04 LDA &0438 ; sound_muted # Non-zero if sound muted &362b 48 PHA ; sound_muted &362c a9 81 LDA #&81 ; Scan for a particular key &362e a0 ff LDY #&ff &3630 a2 ef LDX #&ef ; Q &3632 20 f4 ff JSR &fff4 ; OSBYTE &3635 8a TXA &3636 10 05 BPL &363d ; q_not_pressed &3638 a9 01 LDA #&01 &363a 8d 38 04 STA &0438 ; sound_muted # Set to non-zero to indicate sound muted ; q_not_pressed &363d a9 81 LDA #&81 ; Scan for a particular key &363f a0 ff LDY #&ff &3641 a2 ae LDX #&ae ; S &3643 20 f4 ff JSR &fff4 ; OSBYTE &3646 8a TXA &3647 10 05 BPL &364e ; s_not_pressed &3649 a9 00 LDA #&00 &364b 8d 38 04 STA &0438 ; sound_muted # Set to zero to indicate sound not muted ; s_not_pressed &364e 68 PLA ; sound_muted &364f cd 38 04 CMP &0438 ; sound_muted # Has the sound muting changed? &3652 f0 1f BEQ &3673 ; check_for_escape &3654 a2 0d LDX #&0d ; " " &3656 ad 38 04 LDA &0438 ; sound_muted # Non-zero if sound muted &3659 f0 0f BEQ &366a ; consider_writing_sound_string &365b 20 e1 4a JSR &4ae1 ; flush_buffers &365e a9 7d LDA #&7d ; Set ESCAPE condition &3660 20 f4 ff JSR &fff4 ; OSBYTE &3663 a9 7e LDA #&7e ; Acknowledge ESCAPE condition &3665 20 f4 ff JSR &fff4 ; OSBYTE &3668 a2 0c LDX #&0c ; "Q" ; consider_writing_sound_string &366a ad 2e 04 LDA &042e ; suppress_sound_status # Zero if sound status should not be displayed &366d f0 04 BEQ &3673 ; check_for_escape &366f 8a TXA &3670 20 32 43 JSR &4332 ; write_string # Plot sound status ; check_for_escape &3673 a9 81 LDA #&81 ; Scan for a particular key &3675 a0 ff LDY #&ff &3677 a2 8f LDX #&8f ; ESCAPE &3679 20 f4 ff JSR &fff4 ; OSBYTE &367c 8a TXA &367d 30 06 BMI &3685 ; escape_pressed &367f a9 00 LDA #&00 &3681 8d 2f 04 STA &042f ; quit_game_cooldown &3684 60 RTS ; escape_pressed &3685 ae 2f 04 LDX &042f ; quit_game_cooldown &3688 f0 2a BEQ &36b4 ; start_quit_game_cooldown &368a ca DEX &368b 8e 2f 04 STX &042f ; quit_game_cooldown &368e f0 0c BEQ &369c ; quit_game &3690 60 RTS ; unused # Unused code &3691 78 SEI &3692 20 b3 4a JSR &4ab3 ; check_for_vsync # Returns A = frame_counter, not equal if vsync occurred &3695 f0 03 BEQ &369a ; skip_setting_previous_frame_counter &3697 8d 1b 04 STA &041b ; previous_frame_counter ; skip_setting_previous_frame_counter &369a 58 CLI &369b 60 RTS ; quit_game &369c 58 CLI &369d 24 ff BIT &ff ; os_escape_flag # Top bit set if ESCAPE pressed &369f 10 05 BPL &36a6 ; skip_escape &36a1 a9 7e LDA #&7e ; Acknowledge ESCAPE condition &36a3 20 f4 ff JSR &fff4 ; OSBYTE ; skip_escape &36a6 20 e1 4a JSR &4ae1 ; flush_buffers &36a9 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &36ac f0 03 BEQ &36b1 ; is_demo &36ae 4c 66 4c JMP &4c66 ; prepare_for_high_score_and_demo_screens ; is_demo &36b1 4c 4f 4c JMP &4c4f ; title_screen ; start_quit_game_cooldown &36b4 a9 28 LDA #&28 # ESCAPE must be pressed for 40 updates to end game &36b6 8d 2f 04 STA &042f ; quit_game_cooldown &36b9 60 RTS ; use_move_passive_enemy_right &36ba a9 d0 LDA #&d0 ; &36d0 = move_passive_enemy_right &36bc 8d 08 05 STA &0508 ; move_passive_enemy_routine_address_low &36bf a9 36 LDA #&36 &36c1 8d 09 05 STA &0509 ; move_passive_enemy_routine_address_high &36c4 60 RTS ; use_move_passive_enemy_left &36c5 a9 eb LDA #&eb ; &36eb = move_passive_enemy_left &36c7 8d 08 05 STA &0508 ; move_passive_enemy_routine_address_low &36ca a9 36 LDA #&36 &36cc 8d 09 05 STA &0509 ; move_passive_enemy_routine_address_high &36cf 60 RTS ; move_passive_enemy_right &36d0 a5 73 LDA &73 ; sprite_address_high # Use sprite shifted one more pixel to right &36d2 18 CLC &36d3 69 04 ADC #&04 ; &0400 = enemy_type_0_shift_1_sprites - enemy_type_0_shift_0_sprites &36d5 c9 1c CMP #&1c ; &1c00 = enemy_type_3_shift_3_sprites + &100 &36d7 90 0f BCC &36e8 ; set_sprite_address_high # Does this move the sprite into a new byte? &36d9 e9 10 SBC #&10 ; &1000 = &1c00 - &0c00 &36db 48 PHA ; sprite_address_high &36dc 18 CLC &36dd a5 70 LDA &70 ; screen_address_low &36df 69 08 ADC #&08 # Move right four pixels &36e1 85 70 STA &70 ; screen_address_low &36e3 90 02 BCC &36e7 ; skip_page &36e5 e6 71 INC &71 ; screen_address_high ; skip_page &36e7 68 PLA ; sprite_address_high ; set_sprite_address_high &36e8 85 73 STA &73 ; sprite_address_high &36ea 60 RTS ; move_passive_enemy_left &36eb a5 73 LDA &73 ; sprite_address_high # Use sprite shifted one fewer pixel to right &36ed 38 SEC &36ee e9 04 SBC #&04 ; &0400 = enemy_type_0_shift_1_sprites - enemy_type_0_shift_0_sprites &36f0 c9 0c CMP #&0c ; &0c00 = enemy_type_0_shift_0_sprites &36f2 b0 0f BCS &3703 ; set_sprite_address_high # Does this move the sprite into a new byte? &36f4 69 10 ADC #&10 ; &1000 = &1c00 - &0c00 &36f6 48 PHA ; sprite_address_high &36f7 38 SEC &36f8 a5 70 LDA &70 ; screen_address_low &36fa e9 08 SBC #&08 &36fc 85 70 STA &70 ; screen_address_low &36fe b0 02 BCS &3702 ; skip_page &3700 c6 71 DEC &71 ; screen_address_high ; skip_page &3702 68 PLA ; sprite_address_high ; set_sprite_address_high &3703 85 73 STA &73 ; sprite_address_high &3705 60 RTS ; plot_very_small_sprite &3706 a0 07 LDY #&07 &3708 d0 02 BNE &370c ; plot_small_or_very_small_sprite # Always branches ; plot_small_sprite &370a a0 0f LDY #&0f ; plot_small_or_very_small_sprite &370c a9 1f LDA #&1f &370e 85 73 STA &73 ; sprite_address_high ; plot_small_sprite_loop &3710 b1 72 LDA (&72),Y ; sprite_address &3712 91 70 STA (&70),Y ; screen_address &3714 88 DEY &3715 10 f9 BPL &3710 ; plot_small_sprite_loop &3717 60 RTS ; plot_lives &3718 a0 2f LDY #&2f &371a a9 00 LDA #&00 ; wipe_lives_loop # Wipe &7ec0 - &7eef, i.e. life area &371c 99 c0 7e STA &7ec0,Y &371f 88 DEY &3720 10 fa BPL &371c ; wipe_lives_loop &3722 ae fc 05 LDX &05fc ; player_lives &3725 ca DEX &3726 d0 01 BNE &3729 ; plot_life_sprites &3728 60 RTS ; plot_life_sprites &3729 a9 c0 LDA #&c0 ; &7ec0 = group &1d &372b 85 70 STA &70 ; screen_address_low &372d a9 7e LDA #&7e &372f 85 71 STA &71 ; screen_address_high &3731 a9 b0 LDA #&b0 ; &1fb0 = sprite_life &3733 85 72 STA &72 ; sprite_address_low ; plot_life_sprites_loop &3735 20 0a 37 JSR &370a ; plot_small_sprite &3738 a5 70 LDA &70 ; screen_address_low &373a 18 CLC &373b 69 10 ADC #&10 # Move right eight pixels &373d 85 70 STA &70 ; screen_address_low &373f 90 02 BCC &3743 ; skip_page &3741 e6 71 INC &71 ; screen_address_high ; skip_page &3743 ca DEX &3744 d0 ef BNE &3735 ; plot_life_sprites_loop &3746 60 RTS ; plot_level_flags_and_sound_status &3747 a9 00 LDA #&00 &3749 a0 a0 LDY #&a0 ; wipe_flags_loop # Wipe &7f5f - &7fff, i.e. flags area &374b 99 5f 7f STA &7f5f,Y &374e 88 DEY &374f d0 fa BNE &374b ; wipe_flags_loop &3751 a9 f0 LDA #&f0 ; &7ff0 = group &1d + &130 &3753 85 70 STA &70 ; screen_address_low &3755 a9 7f LDA #&7f &3757 85 71 STA &71 ; screen_address_high &3759 ad fd 05 LDA &05fd ; player_level # Level is stored as BCD &375c 4a LSR A &375d 4a LSR A &375e 4a LSR A &375f 4a LSR A &3760 aa TAX ; plot_flags_loop # Plot one large flag for every ten levels &3761 8a TXA &3762 f0 16 BEQ &377a ; plot_small_flags &3764 a9 a0 LDA #&a0 ; &1fa0 = sprite_flag &3766 85 72 STA &72 ; sprite_address_low &3768 20 0a 37 JSR &370a ; plot_small_sprite &376b a5 70 LDA &70 ; screen_address_low &376d 38 SEC &376e e9 10 SBC #&10 # Move left eight pixels &3770 85 70 STA &70 ; screen_address_low &3772 b0 02 BCS &3776 ; skip_page &3774 c6 71 DEC &71 ; screen_address_high ; skip_page &3776 ca DEX &3777 4c 61 37 JMP &3761 ; plot_flags_loop ; plot_small_flags &377a a5 70 LDA &70 ; screen_address_low &377c 18 CLC &377d 69 08 ADC #&08 # Move right four pixels &377f 85 70 STA &70 ; screen_address_low &3781 90 02 BCC &3785 ; skip_page &3783 e6 71 INC &71 ; screen_address_high ; skip_page &3785 ad fd 05 LDA &05fd ; player_level &3788 29 0f AND #&0f &378a aa TAX ; plot_small_flags_loop # Plot one small flag for every remaining level &378b 8a TXA &378c f0 16 BEQ &37a4 ; plot_sound_status &378e a9 98 LDA #&98 ; &1f98 = sprite_small_flag &3790 85 72 STA &72 ; sprite_address_low &3792 20 06 37 JSR &3706 ; plot_very_small_sprite &3795 a5 70 LDA &70 ; screen_address_low &3797 38 SEC &3798 e9 08 SBC #&08 # Move left four pixels &379a 85 70 STA &70 ; screen_address_low &379c b0 02 BCS &37a0 ; skip_page &379e c6 71 DEC &71 ; screen_address_high ; skip_page &37a0 ca DEX &37a1 4c 8b 37 JMP &378b ; plot_small_flags_loop ; plot_sound_status &37a4 a2 0c LDX #&0c ; "Q" &37a6 ad 38 04 LDA &0438 ; sound_muted # Non-zero if sound muted &37a9 d0 02 BNE &37ad ; is_muted &37ab a2 0d LDX #&0d ; " " ; is_muted &37ad 8a TXA &37ae 4c 32 43 JMP &4332 ; write_string ; update_passive_enemy &37b1 ac 00 05 LDY &0500 ; passive_enemy_to_update &37b4 be c8 05 LDX &05c8,Y ; passive_enemies_group # &ff if passive enemy isn't present &37b7 e8 INX &37b8 d0 01 BNE &37bb ; is_present &37ba 60 RTS ; is_present &37bb ca DEX &37bc 08 PHP ; group &37bd a9 00 LDA #&00 ; SPRITE_ROTATION_0 # Use unrotated sprites for passive enemies &37bf 85 72 STA &72 ; sprite_address_low &37c1 b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &37c4 85 73 STA &73 ; sprite_address_high &37c6 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &37c9 85 70 STA &70 ; screen_address_low &37cb b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &37ce 85 71 STA &71 ; screen_address_high &37d0 28 PLP ; group &37d1 08 PHP ; group &37d2 30 15 BMI &37e9 ; skip_unplotting_enemy # Top bit set if enemy is active &37d4 a2 03 LDX #&03 ; backup_screen_and_sprite_addresses_loop &37d6 b5 70 LDA &70,X ; screen_and_sprite_address &37d8 48 PHA ; address byte &37d9 ca DEX &37da 10 fa BPL &37d6 ; backup_screen_and_sprite_addresses_loop &37dc 20 c5 33 JSR &33c5 ; unplot_enemy_sprite # Unplot passive enemy &37df a2 00 LDX #&00 ; restore_screen_and_sprite_addresses_loop &37e1 68 PLA ; address byte &37e2 95 70 STA &70,X ; screen_and_sprite_address &37e4 e8 INX &37e5 e0 04 CPX #&04 &37e7 d0 f8 BNE &37e1 ; restore_screen_and_sprite_addresses_loop ; skip_unplotting_enemy &37e9 20 2e 38 JSR &382e ; move_passive_enemy &37ec ac 00 05 LDY &0500 ; passive_enemy_to_update &37ef a5 73 LDA &73 ; sprite_address_high &37f1 99 32 05 STA &0532,Y ; passive_enemies_sprite_address_high &37f4 a5 71 LDA &71 ; screen_address_high &37f6 99 96 05 STA &0596,Y ; passive_enemies_screen_address_high &37f9 48 PHA ; enemy_screen_address_high &37fa a5 70 LDA &70 ; screen_address_low &37fc 99 64 05 STA &0564,Y ; passive_enemies_screen_address_low &37ff 48 PHA ; enemy_screen_address_low &3800 b9 c8 05 LDA &05c8,Y ; passive_enemies_group &3803 29 7f AND #&7f ; GROUP_MASK # Lowest seven bits are group &3805 aa TAX &3806 68 PLA ; enemy_screen_address_low &3807 38 SEC &3808 fd 00 1f SBC &1f00,X ; group_addresses_low &380b 85 75 STA &75 ; enemy_x &380d 68 PLA ; enemy_screen_address_high &380e fd 20 1f SBC &1f20,X ; group_addresses_high &3811 4a LSR A &3812 a5 75 LDA &75 ; enemy_x &3814 6a ROR A &3815 4a LSR A &3816 4a LSR A &3817 cd 0a 05 CMP &050a ; minimum_enemy_x # Is this enemy the leftmost enemy? &381a b0 03 BCS &381f ; not_minimum &381c 8d 0a 05 STA &050a ; minimum_enemy_x ; not_minimum &381f cd 0b 05 CMP &050b ; maximum_enemy_x # Is this enemy the rightmost enemy? &3822 90 03 BCC &3827 ; not_maximum &3824 8d 0b 05 STA &050b ; maximum_enemy_x ; not_maximum &3827 28 PLP ; group &3828 10 01 BPL &382b ; to_plot_enemy_sprite # Top bit set if enemy is active &382a 60 RTS ; to_plot_enemy_sprite &382b 4c 26 34 JMP &3426 ; plot_enemy_sprite # Plot passive enemy ; move_passive_enemy &382e 6c 08 05 JMP (&0508) ; move_passive_enemy_routine_address ; consider_starting_next_wave &3831 ce 1c 04 DEC &041c ; end_of_wave_cooldown &3834 f0 01 BEQ &3837 ; start_next_wave &3836 60 RTS ; start_next_wave &3837 ae 32 04 LDX &0432 ; initial_stack_offset &383a 9a TXS &383b 4c 1f 42 JMP &421f ; start_wave ; update_passive_enemies &383e ad 1c 04 LDA &041c ; end_of_wave_cooldown # Non-zero at end of wave &3841 d0 ee BNE &3831 ; consider_starting_next_wave &3843 ad 01 05 LDA &0501 ; number_of_enemies &3846 d0 06 BNE &384e ; wave_not_destroyed &3848 a9 b4 LDA #&b4 # Wait for 180 frames after last enemy destroyed &384a 8d 1c 04 STA &041c ; end_of_wave_cooldown # Set to non-zero to indicate end of wave &384d 60 RTS ; wave_not_destroyed &384e 20 b1 37 JSR &37b1 ; update_passive_enemy &3851 ce 00 05 DEC &0500 ; passive_enemy_to_update &3854 20 b1 37 JSR &37b1 ; update_passive_enemy &3857 ce 00 05 DEC &0500 ; passive_enemy_to_update &385a 10 25 BPL &3881 ; leave &385c ad 0b 05 LDA &050b ; maximum_enemy_x &385f c9 22 CMP #&22 &3861 90 06 BCC &3869 ; not_right_edge # Has the formation reached the right of the screen? &3863 20 c5 36 JSR &36c5 ; use_move_passive_enemy_left # If so, set moving left &3866 4c 73 38 JMP &3873 ; not_left_edge ; not_right_edge &3869 ad 0a 05 LDA &050a ; minimum_enemy_x &386c c9 04 CMP #&04 &386e b0 03 BCS &3873 ; not_left_edge # Has the formation reached the left of the screen? &3870 20 ba 36 JSR &36ba ; use_move_passive_enemy_right # If so, set moving right ; not_left_edge ; reset_passive_enemy_to_update_and_maximum_and_minimum_enemy_x &3873 a9 31 LDA #&31 &3875 8d 00 05 STA &0500 ; passive_enemy_to_update &3878 a2 00 LDX #&00 &387a 8e 0b 05 STX &050b ; maximum_enemy_x &387d ca DEX ; &ff &387e 8e 0a 05 STX &050a ; minimum_enemy_x ; leave &3881 60 RTS ; update_returning_enemies &3882 a9 09 LDA #&09 &3884 85 7c STA &7c ; enemy_to_update ; update_returning_enemies_loop # For each returning enemy, &3886 a6 7c LDX &7c ; enemy_to_update &3888 bd 30 07 LDA &0730,X ; returning_enemies_screen_address_high &388b d0 05 BNE &3892 ; update_returning_enemy # Non-zero if enemy is returning ; consider_next_enemy &388d c6 7c DEC &7c ; enemy_to_update &388f 10 f5 BPL &3886 ; update_returning_enemies_loop &3891 60 RTS ; update_returning_enemy &3892 bd 50 07 LDA &0750,X ; returning_enemies_sprite_address_high &3895 f0 23 BEQ &38ba ; skip_unplot # Zero if sprite wasn't previously plotted &3897 85 73 STA &73 ; sprite_address_high &3899 bd 40 07 LDA &0740,X ; returning_enemies_sprite_address_low &389c 85 72 STA &72 ; sprite_address_low &389e bd 30 07 LDA &0730,X ; returning_enemies_screen_address_high &38a1 85 71 STA &71 ; screen_address_high &38a3 bd 20 07 LDA &0720,X ; returning_enemies_screen_address_low &38a6 85 70 STA &70 ; screen_address_low &38a8 20 c5 33 JSR &33c5 ; unplot_enemy_sprite # Unplot returning enemy &38ab a6 7c LDX &7c ; enemy_to_update &38ad de 00 07 DEC &0700,X ; returning_enemies_row_in_group # Move up one pixel &38b0 10 08 BPL &38ba ; not_group &38b2 a9 07 LDA #&07 &38b4 9d 00 07 STA &0700,X ; returning_enemies_row_in_group &38b7 de 10 07 DEC &0710,X ; returning_enemies_groups_to_return ; not_group ; skip_unplot &38ba bc 60 07 LDY &0760,X ; returning_enemies_passive_slot &38bd b9 c8 05 LDA &05c8,Y ; passive_enemies_group &38c0 29 1f AND #&1f ; GROUP_MASK # Lowest five bits are group &38c2 38 SEC &38c3 fd 10 07 SBC &0710,X ; returning_enemies_groups_to_return &38c6 85 74 STA &74 ; group &38c8 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &38cb 29 07 AND #&07 &38cd 38 SEC &38ce fd 00 07 SBC &0700,X ; returning_enemies_row_in_group &38d1 b0 04 BCS &38d7 ; skip_group &38d3 69 08 ADC #&08 &38d5 c6 74 DEC &74 ; group ; skip_group &38d7 85 75 STA &75 ; row &38d9 b9 c8 05 LDA &05c8,Y ; passive_enemies_group &38dc 29 1f AND #&1f ; GROUP_MASK # Lowest five bits are group &38de aa TAX &38df b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &38e2 29 f8 AND #&f8 &38e4 fd 00 1f SBC &1f00,X ; group_addresses_low &38e7 85 70 STA &70 ; screen_address_low &38e9 b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &38ec fd 20 1f SBC &1f20,X ; group_addresses_high &38ef 85 71 STA &71 ; screen_address_high &38f1 18 CLC &38f2 a5 70 LDA &70 ; screen_address_low # Move returning enemy towards passive position &38f4 65 75 ADC &75 ; row &38f6 a4 74 LDY &74 ; group &38f8 a6 7c LDX &7c ; enemy_to_update &38fa 79 00 1f ADC &1f00,Y ; group_addresses_low &38fd 85 70 STA &70 ; screen_address_low &38ff 9d 20 07 STA &0720,X ; returning_enemies_screen_address_low &3902 a5 71 LDA &71 ; screen_address_high &3904 79 20 1f ADC &1f20,Y ; group_addresses_high &3907 85 71 STA &71 ; screen_address_high &3909 9d 30 07 STA &0730,X ; returning_enemies_screen_address_high &390c bc 60 07 LDY &0760,X ; returning_enemies_passive_slot &390f b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &3912 9d 50 07 STA &0750,X ; returning_enemies_sprite_address_high &3915 bd 10 07 LDA &0710,X ; returning_enemies_groups_to_return &3918 c9 02 CMP #&02 &391a b0 2d BCS &3949 ; consider_next_enemy_after_plotting ; is_close_to_passive_position &391c bd 00 07 LDA &0700,X ; returning_enemies_row_in_group &391f 1d 10 07 ORA &0710,X ; returning_enemies_groups_to_return &3922 f0 35 BEQ &3959 ; is_at_passive_position ; rotate_enemy_into_passive_position &3924 bd 10 07 LDA &0710,X ; returning_enemies_groups_to_return &3927 0a ASL A &3928 0a ASL A &3929 0a ASL A &392a 1d 00 07 ORA &0700,X ; returning_enemies_row_in_group &392d 4a LSR A &392e b0 19 BCS &3949 ; consider_next_enemy_after_plotting &3930 c9 05 CMP #&05 &3932 d0 0a BNE &393e ; change_rotation ; set_rotation &3934 a9 e7 LDA #&e7 ; SPRITE_ROTATION_11 &3936 c0 19 CPY #&19 ; ENEMY_FIRST_RIGHT # Is the enemy on the right of the formation? &3938 b0 0c BCS &3946 ; set_sprite_address_low &393a a9 d2 LDA #&d2 ; SPRITE_ROTATION_10 &393c d0 08 BNE &3946 ; set_sprite_address_low # Always branches ; change_rotation &393e b0 09 BCS &3949 ; consider_next_enemy_after_plotting &3940 bd 40 07 LDA &0740,X ; returning_enemies_sprite_address_low &3943 38 SEC &3944 e9 2a SBC #&2a ; SPRITE_SIZE * 2 # Rotate clockwise by two ; set_sprite_address_low &3946 9d 40 07 STA &0740,X ; returning_enemies_sprite_address_low ; consider_next_enemy_after_plotting &3949 bd 40 07 LDA &0740,X ; returning_enemies_sprite_address_low &394c 85 72 STA &72 ; sprite_address_low &394e bd 50 07 LDA &0750,X ; returning_enemies_sprite_address_high &3951 85 73 STA &73 ; sprite_address_high &3953 20 26 34 JSR &3426 ; plot_enemy_sprite # Plot returning enemy &3956 4c 8d 38 JMP &388d ; consider_next_enemy ; is_at_passive_position &3959 a9 00 LDA #&00 ; SPRITE_ROTATION_0 # Use unrotated sprite &395b 85 72 STA &72 ; sprite_address_low &395d bd 50 07 LDA &0750,X ; returning_enemies_sprite_address_high &3960 85 73 STA &73 ; sprite_address_high &3962 b9 c8 05 LDA &05c8,Y ; passive_enemies_group &3965 29 1f AND #&1f ; GROUP_MASK # Lowest five bits are group &3967 99 c8 05 STA &05c8,Y ; passive_enemies_group &396a a9 00 LDA #&00 &396c 9d 30 07 STA &0730,X ; returning_enemies_screen_address_high # Set to zero to indicate enemy is no longer returning &396f ce 0c 04 DEC &040c ; number_of_active_enemies &3972 ee 0d 04 INC &040d ; number_of_passive_enemies &3975 20 26 34 JSR &3426 ; plot_enemy_sprite # Plot newly returned enemy &3978 4c 8d 38 JMP &388d ; consider_next_enemy ; initialise_active_enemies_and_enemy_bombs &397b a9 00 LDA #&00 &397d a8 TAY ; initialise_active_enemies_loop &397e 99 00 07 STA &0700,Y ; returning_enemies_row_in_group # Wipe &0700 - &07ff, i.e. returning and attacking enemies &3981 88 DEY &3982 d0 fa BNE &397e ; initialise_active_enemies_loop ; initialise_enemy_bombs_loop &3984 99 80 04 STA &0480,Y ; enemy_bombs_screen_address_low # Wipe &0480 - &057f, i.e. enemy bombs &3987 c8 INY &3988 10 fa BPL &3984 ; initialise_enemy_bombs_loop &398a 60 RTS ; set_enemy_returning &398b a2 ff LDX #&ff ; find_free_slot_loop &398d e8 INX &398e e0 10 CPX #&10 &3990 f0 47 BEQ &39d9 ; remove_passive_enemy # Remove enemy if no free slots &3992 bd 30 07 LDA &0730,X ; returning_enemies_screen_address_high &3995 d0 f6 BNE &398d ; find_free_slot_loop &3997 b9 c8 05 LDA &05c8,Y ; passive_enemies_group &399a 29 1f AND #&1f ; GROUP_MASK # Lowest five bits are group &399c 9d 10 07 STA &0710,X ; returning_enemies_groups_to_return &399f 86 75 STX &75 ; enemy_slot &39a1 aa TAX &39a2 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &39a5 38 SEC &39a6 fd 00 1f SBC &1f00,X ; group_addresses_low &39a9 48 PHA ; x_low &39aa b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &39ad fd 20 1f SBC &1f20,X ; group_addresses_high &39b0 aa TAX &39b1 68 PLA ; x_low &39b2 18 CLC &39b3 69 80 ADC #&80 ; &5a80 = group &00 &39b5 48 PHA ; screen_address_low &39b6 8a TXA &39b7 69 5a ADC #&5a &39b9 a6 75 LDX &75 ; enemy_slot &39bb 9d 30 07 STA &0730,X ; returning_enemies_screen_address_high &39be 68 PLA ; screen_address_low &39bf 9d 20 07 STA &0720,X ; returning_enemies_screen_address_low &39c2 98 TYA &39c3 9d 60 07 STA &0760,X ; returning_enemies_passive_slot &39c6 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &39c9 29 07 AND #&07 &39cb 9d 00 07 STA &0700,X ; returning_enemies_row_in_group &39ce a9 00 LDA #&00 &39d0 9d 50 07 STA &0750,X ; returning_enemies_sprite_address_high # Set to zero to indicate sprite not plotted &39d3 a9 15 LDA #&15 ; SPRITE_ROTATION_1 &39d5 9d 40 07 STA &0740,X ; returning_enemies_sprite_address_low &39d8 60 RTS ; remove_passive_enemy &39d9 a9 ff LDA #&ff &39db 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set to &ff to indicate passive enemy not present &39de 60 RTS ; add_attacking_enemy # Called with Y = passive enemy &39df a2 00 LDX #&00 ; find_free_slot_loop &39e1 bd b0 07 LDA &07b0,X ; attacking_enemies_screen_address_high &39e4 f0 06 BEQ &39ec ; add_attacking_enemy_to_slot_X &39e6 e8 INX &39e7 e0 06 CPX #&06 &39e9 d0 f6 BNE &39e1 ; find_free_slot_loop &39eb 60 RTS ; add_attacking_enemy_to_slot_X # Called with Y = passive enemy &39ec 86 6c STX &6c ; unused # Unused variable &39ee 98 TYA &39ef 9d e0 07 STA &07e0,X ; attacking_enemies_passive_slot &39f2 ee 0c 04 INC &040c ; number_of_active_enemies &39f5 ce 0d 04 DEC &040d ; number_of_passive_enemies &39f8 b9 c8 05 LDA &05c8,Y ; passive_enemies_group &39fb 9d d0 07 STA &07d0,X ; attacking_enemies_group &39fe 09 80 ORA #&80 ; GROUP_ACTIVE_FLAG &3a00 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set top bit to indicate passive enemy is active &3a03 a9 2a LDA #&2a ; SPRITE_ROTATION_2 &3a05 2c 0e 04 BIT &040e ; size_and_direction_of_attack # Top bit set if attacking from right &3a08 30 02 BMI &3a0c ; set_sprite_address_low &3a0a a9 3f LDA #&3f ; SPRITE_ROTATION_3 ; set_sprite_address_low &3a0c 9d 80 07 STA &0780,X ; attacking_enemies_sprite_address_low &3a0f b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &3a12 9d 90 07 STA &0790,X ; attacking_enemies_sprite_address_high &3a15 85 73 STA &73 ; sprite_address_high &3a17 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &3a1a 9d a0 07 STA &07a0,X ; attacking_enemies_screen_address_low &3a1d 85 70 STA &70 ; screen_address_low &3a1f b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &3a22 9d b0 07 STA &07b0,X ; attacking_enemies_screen_address_high &3a25 85 71 STA &71 ; screen_address_high &3a27 a9 00 LDA #&00 # &40 clear to indicate rising to right, offset is &00 &3a29 9d f0 07 STA &07f0,X ; attacking_enemies_bombing_state # Set to zero to allow enemy to bomb &3a2c 85 72 STA &72 ; sprite_address_low &3a2e 2c 0e 04 BIT &040e ; size_and_direction_of_attack # Top bit set if attacking from right &3a31 30 02 BMI &3a35 ; set_attacking_enemies_state &3a33 a9 7f LDA #&7f ; STATE_RISING_LEFT | &3f # &40 set to indicate rising to left, offset is &3f ; set_attacking_enemies_state &3a35 9d c0 07 STA &07c0,X ; attacking_enemies_state &3a38 4c c5 33 JMP &33c5 ; unplot_enemy_sprite # Unplot previously passive enemy ; set_enemy_returning_after_moving_offscreen &3a3b 68 PLA # Leave update_grouped_enemy_diving_towards_player &3a3c 68 PLA # or update_enemy_diving_towards_player on return &3a3d a6 7c LDX &7c ; enemy_to_update &3a3f a9 00 LDA #&00 &3a41 9d b0 07 STA &07b0,X ; attacking_enemies_screen_address_high # Set to zero to indicate enemy not attacking &3a44 a9 ff LDA #&ff &3a46 e0 06 CPX #&06 ; ENEMY_GROUP_LEADER &3a48 90 15 BCC &3a5f ; not_grouped_enemy &3a4a 8d f6 07 STA &07f6 ; attacking_enemies_bombing_state + 6 # Used as direction change cooldown for grouped enemies &3a4d 8d f7 07 STA &07f7 ; attacking_enemies_bombing_state + 7 # Set to &ff for group leader and escorts &3a50 8d f8 07 STA &07f8 ; attacking_enemies_bombing_state + 8 # to stop grouped enemies changing direction on return &3a53 bd c0 07 LDA &07c0,X ; attacking_enemies_state &3a56 8d c6 07 STA &07c6 ; attacking_enemies_state + 6 &3a59 8d c7 07 STA &07c7 ; attacking_enemies_state + 7 &3a5c 8d c8 07 STA &07c8 ; attacking_enemies_state + 8 ; not_grouped_enemy &3a5f bc e0 07 LDY &07e0,X ; attacking_enemies_passive_slot &3a62 4c 93 3d JMP &3d93 ; to_set_enemy_returning ; move_enemy_right_a_pixel &3a65 a5 73 LDA &73 ; sprite_address_high # Use sprite shifted one more pixel to right &3a67 18 CLC &3a68 69 04 ADC #&04 ; &0400 = enemy_type_0_shift_1_sprites - enemy_type_0_shift_0_sprites &3a6a 85 73 STA &73 ; sprite_address_high &3a6c c9 1c CMP #&1c ; &1c00 = enemy_type_3_shift_3_sprites + &100 &3a6e b0 01 BCS &3a71 ; move_to_next_byte_left # Does this move the sprite into a new byte? &3a70 60 RTS ; move_to_next_byte_left &3a71 e9 10 SBC #&10 ; &1000 = &1c00 - &0c00 &3a73 85 73 STA &73 ; sprite_address_high &3a75 a5 70 LDA &70 ; screen_address_low &3a77 18 CLC &3a78 69 08 ADC #&08 # Move right four pixels &3a7a 85 70 STA &70 ; screen_address_low &3a7c 90 02 BCC &3a80 ; skip_page &3a7e e6 71 INC &71 ; screen_address_high ; skip_page &3a80 a6 7b LDX &7b ; group &3a82 38 SEC &3a83 fd 00 1f SBC &1f00,X ; group_addresses_low &3a86 48 PHA ; enemy x &3a87 a5 71 LDA &71 ; screen_address_high &3a89 fd 20 1f SBC &1f20,X ; group_addresses_high &3a8c f0 32 BEQ &3ac0 ; leave_after_pla &3a8e 68 PLA ; enemy x &3a8f c9 30 CMP #&30 &3a91 90 2e BCC &3ac1 ; leave # Has the enemy moved off the left of the screen? &3a93 4c 3b 3a JMP &3a3b ; set_enemy_returning_after_moving_offscreen ; move_enemy_left_a_pixel &3a96 a5 73 LDA &73 ; sprite_address_high # Use sprite shifted one fewer pixel to right &3a98 38 SEC &3a99 e9 04 SBC #&04 ; &0400 = enemy_type_0_shift_1_sprites - enemy_type_0_shift_0_sprites &3a9b 85 73 STA &73 ; sprite_address_high &3a9d c9 0c CMP #&0c ; &0c00 = enemy_type_0_shift_0_sprites &3a9f 90 01 BCC &3aa2 ; move_to_next_byte_right # Does this move the sprite into a new byte? &3aa1 60 RTS ; move_to_next_byte_right &3aa2 69 10 ADC #&10 ; &1000 = &1c00 - &0c00 &3aa4 85 73 STA &73 ; sprite_address_high &3aa6 a5 70 LDA &70 ; screen_address_low &3aa8 38 SEC &3aa9 e9 08 SBC #&08 # Move left four pixels &3aab 85 70 STA &70 ; screen_address_low &3aad b0 02 BCS &3ab1 ; skip_page &3aaf c6 71 DEC &71 ; screen_address_high ; skip_page &3ab1 a6 7b LDX &7b ; group &3ab3 dd 00 1f CMP &1f00,X ; group_addresses_low &3ab6 a5 71 LDA &71 ; screen_address_high &3ab8 fd 20 1f SBC &1f20,X ; group_addresses_high &3abb b0 04 BCS &3ac1 ; leave # Has the enemy moved off the right of the screen? &3abd 4c 3b 3a JMP &3a3b ; set_enemy_returning_after_moving_offscreen ; leave_after_pla &3ac0 68 PLA ; leave &3ac1 60 RTS ; move_enemy_up_a_pixel &3ac2 c6 70 DEC &70 ; screen_address_low # Move up a pixel &3ac4 a5 70 LDA &70 ; screen_address_low &3ac6 c9 ff CMP #&ff &3ac8 d0 02 BNE &3acc ; skip_page &3aca c6 71 DEC &71 ; screen_address_high ; skip_page &3acc 29 07 AND #&07 &3ace c9 07 CMP #&07 &3ad0 d0 ef BNE &3ac1 ; leave &3ad2 c6 7b DEC &7b ; group &3ad4 a5 70 LDA &70 ; screen_address_low &3ad6 38 SEC &3ad7 e9 38 SBC #&38 # Move up a group &3ad9 85 70 STA &70 ; screen_address_low &3adb a5 71 LDA &71 ; screen_address_high &3add e9 01 SBC #&01 &3adf 85 71 STA &71 ; screen_address_high &3ae1 60 RTS ; move_enemy_down_a_pixel &3ae2 98 TYA &3ae3 48 PHA ; tmp_y &3ae4 8a TXA &3ae5 48 PHA ; tmp_x &3ae6 e6 70 INC &70 ; screen_address_low # Move down a pixel &3ae8 d0 02 BNE &3aec ; skip_page &3aea e6 71 INC &71 ; screen_address_high ; skip_page &3aec a5 70 LDA &70 ; screen_address_low &3aee 29 07 AND #&07 &3af0 d0 0f BNE &3b01 ; not_group ; is_group &3af2 e6 7b INC &7b ; group &3af4 a5 70 LDA &70 ; screen_address_low &3af6 18 CLC &3af7 69 38 ADC #&38 # Move down a group &3af9 85 70 STA &70 ; screen_address_low &3afb a5 71 LDA &71 ; screen_address_high &3afd 69 01 ADC #&01 &3aff 85 71 STA &71 ; screen_address_high ; not_group ; leave_after_restoring_x_and_y &3b01 68 PLA ; tmp_x &3b02 aa TAX &3b03 68 PLA ; tmp_y &3b04 a8 TAY &3b05 60 RTS ; move_enemy_down_two_pixels &3b06 98 TYA &3b07 48 PHA ; tmp_y &3b08 8a TXA &3b09 48 PHA ; tmp_x &3b0a a5 70 LDA &70 ; screen_address_low &3b0c 18 CLC &3b0d 69 02 ADC #&02 # Move down two pixels &3b0f 85 70 STA &70 ; screen_address_low &3b11 29 06 AND #&06 &3b13 08 PHP ; is group &3b14 90 02 BCC &3b18 ; skip_page &3b16 e6 71 INC &71 ; screen_address_high ; skip_page &3b18 28 PLP ; is group &3b19 d0 e6 BNE &3b01 ; leave_after_restoring_x_and_y &3b1b f0 d5 BEQ &3af2 ; is_group # Always branches ; move_enemy_down_three_pixels # Unused code &3b1d 98 TYA &3b1e 48 PHA ; tmp_y &3b1f 8a TXA &3b20 48 PHA ; tmp_x &3b21 a5 70 LDA &70 ; screen_address_low &3b23 18 CLC &3b24 69 03 ADC #&03 # Move down three pixels &3b26 85 70 STA &70 ; screen_address_low &3b28 90 02 BCC &3b2c ; skip_page &3b2a e6 71 INC &71 ; screen_address_high ; skip_page &3b2c 29 07 AND #&07 &3b2e c9 03 CMP #&03 &3b30 b0 cf BCS &3b01 ; leave_after_restoring_x_and_y &3b32 90 be BCC &3af2 ; is_group # Always branches ; move_enemy_horizontally &3b34 a5 75 LDA &75 ; enemy_state &3b36 4a LSR A &3b37 b0 03 BCS &3b3c ; to_move_enemy_right_a_pixel # Carry set if STATE_DIVING_RIGHT is set &3b39 4c 96 3a JMP &3a96 ; move_enemy_left_a_pixel ; to_move_enemy_right_a_pixel &3b3c 4c 65 3a JMP &3a65 ; move_enemy_right_a_pixel ; increment_bombing_state # Called with Y = enemy_to_update &3b3f c0 06 CPY #&06 ; ENEMY_GROUP_LEADER &3b41 b0 06 BCS &3b49 ; is_grouped_enemy ; not_grouped_enemy &3b43 98 TYA &3b44 aa TAX &3b45 fe f0 07 INC &07f0,X ; attacking_enemies_bombing_state ; leave &3b48 60 RTS ; is_grouped_enemy &3b49 b9 b1 07 LDA &07b1,Y ; attacking_enemies_screen_address_high + 1 &3b4c 19 b2 07 ORA &07b2,Y ; attacking_enemies_screen_address_high + 2 &3b4f d0 f7 BNE &3b48 ; leave # Is this the final member of the group present? &3b51 e6 1f INC &1f ; grouped_enemy_bombing_state # If so, change bombing state for the group &3b53 60 RTS ; remove_absent_leaders &3b54 a9 ff LDA #&ff &3b56 ae 24 04 LDX &0424 ; leaders_to_remove_minus_one &3b59 10 07 BPL &3b62 ; remove_absent_leaders_loop &3b5b 8d 24 04 STA &0424 ; leaders_to_remove_minus_one &3b5e 8d ff 05 STA &05ff ; player_leaders_to_remove_minus_one &3b61 60 RTS ; remove_absent_leaders_loop &3b62 bc 6c 1e LDY &1e6c,X ; removable_leaders_slots &3b65 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set to &ff to indicate enemy isn't present &3b68 ce 01 05 DEC &0501 ; number_of_enemies &3b6b ce 0d 04 DEC &040d ; number_of_passive_enemies &3b6e ca DEX &3b6f 10 f1 BPL &3b62 ; remove_absent_leaders_loop &3b71 60 RTS ; finished_rising_from_formation &3b72 a4 7c LDY &7c ; enemy_to_update &3b74 a9 15 LDA #&15 ; SPRITE_ROTATION_1 &3b76 85 72 STA &72 ; sprite_address_low &3b78 c0 06 CPY #&06 ; ENEMY_GROUP_LEADER &3b7a b0 03 BCS &3b7f ; is_grouped_enemy &3b7c 4c b3 3d JMP &3db3 ; set_enemy_moving_right_without_incrementing_bombing_state ; is_grouped_enemy &3b7f a9 ff LDA #&ff ; STATE_DIVING | STATE_HOMING | &3f # &3f is timer for homing &3b81 85 75 STA &75 ; enemy_state &3b83 99 c0 07 STA &07c0,Y ; attacking_enemies_state &3b86 a9 01 LDA #&01 &3b88 99 f0 07 STA &07f0,Y ; attacking_enemies_bombing_state # Used as direction change cooldown for grouped enemies &3b8b a9 00 LDA #&00 &3b8d 85 1f STA &1f ; grouped_enemy_bombing_state # Set to zero to allow group to bomb &3b8f 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; set_rising_sprite # Unused code; never called (see &3bf0) &3b92 48 PHA ; tmp_a &3b93 8a TXA &3b94 48 PHA ; tmp_x &3b95 a5 75 LDA &75 ; enemy_state &3b97 a2 2a LDX #&2a ; SPRITE_ROTATION_2 &3b99 4a LSR A &3b9a b0 02 BCS &3b9e ; set_sprite_address_low &3b9c a2 3f LDX #&3f ; SPRITE_ROTATION_3 ; set_sprite_address_low &3b9e 8a TXA &3b9f 85 72 STA &72 ; sprite_address_low &3ba1 68 PLA ; tmp_x &3ba2 aa TAX &3ba3 68 PLA ; tmp_a &3ba4 60 RTS ; update_attacking_enemy &3ba5 84 7c STY &7c ; enemy_to_update &3ba7 b9 80 07 LDA &0780,Y ; attacking_enemies_sprite_address_low &3baa 85 72 STA &72 ; sprite_address_low &3bac b9 90 07 LDA &0790,Y ; attacking_enemies_sprite_address_high &3baf 85 73 STA &73 ; sprite_address_high &3bb1 b9 a0 07 LDA &07a0,Y ; attacking_enemies_screen_address_low &3bb4 85 70 STA &70 ; screen_address_low &3bb6 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high &3bb9 85 71 STA &71 ; screen_address_high &3bbb a2 03 LDX #&03 ; backup_screen_and_sprite_addresses_loop &3bbd b5 70 LDA &70,X ; screen_and_sprite_address &3bbf 48 PHA ; address byte &3bc0 ca DEX &3bc1 10 fa BPL &3bbd ; backup_screen_and_sprite_addresses_loop &3bc3 20 c5 33 JSR &33c5 ; unplot_enemy_sprite # Unplot attacking enemy &3bc6 a2 00 LDX #&00 ; restore_screen_and_sprite_addresses_loop &3bc8 68 PLA ; address byte &3bc9 95 70 STA &70,X ; screen_and_sprite_address &3bcb e8 INX &3bcc e0 04 CPX #&04 &3bce d0 f8 BNE &3bc8 ; restore_screen_and_sprite_addresses_loop &3bd0 a4 7c LDY &7c ; enemy_to_update &3bd2 b9 d0 07 LDA &07d0,Y ; attacking_enemies_group &3bd5 85 7b STA &7b ; group &3bd7 b9 c0 07 LDA &07c0,Y ; attacking_enemies_state &3bda 85 75 STA &75 ; enemy_state &3bdc 24 75 BIT &75 ; enemy_state &3bde 10 03 BPL &3be3 ; update_enemy_rising_out_of_formation # If &80 (STATE_DIVING) is set, &3be0 4c ed 3c JMP &3ced ; update_enemy_diving_towards_player # enemy is diving towards player ; update_enemy_rising_out_of_formation # Otherwise, enemy is rising out of formation &3be3 29 3f AND #&3f ; STATE_RISING_TIMER_MASK # If so, low six bits are used to determine movement &3be5 aa TAX &3be6 24 75 BIT &75 ; enemy_state &3be8 50 02 BVC &3bec ; is_rising_from_right # &40 (STATE_RISING_LEFT) sets change of offset ; is_rising_from_left &3bea ca DEX # If rising to left, starts at &3f and decreases &3beb ca DEX ; is_rising_from_right &3bec e8 INX # If rising to right, starts at &00 and increases &3bed 8a TXA &3bee 29 3f AND #&3f ; STATE_RISING_TIMER_MASK &3bf0 f0 a0 BEQ &3b92 ; set_rising_sprite # Never branches &3bf2 e0 20 CPX #&20 ; RISING_MOVEMENT_MIDDLE &3bf4 d0 03 BNE &3bf9 ; not_finished_rising_from_formation &3bf6 4c 72 3b JMP &3b72 ; finished_rising_from_formation ; not_finished_rising_from_formation &3bf9 a5 75 LDA &75 ; enemy_state &3bfb 29 c0 AND #&c0 ; STATE_DIVING | STATE_RISING_LEFT # &80 (STATE_DIVING) is never set here &3bfd 85 6c STA &6c ; state_flags &3bff 8a TXA &3c00 29 3f AND #&3f ; STATE_RISING_TIMER_MASK &3c02 05 6c ORA &6c ; state_flags &3c04 99 c0 07 STA &07c0,Y ; attacking_enemies_state &3c07 bd c0 1f LDA &1fc0,X ; rising_movement_table &3c0a 48 PHA ; rising movement &3c0b 10 20 BPL &3c2d ; skip_setting_sprite # If &80 of rising movement set, change sprite &3c0d b9 c0 07 LDA &07c0,Y ; attacking_enemies_state &3c10 29 40 AND #&40 ; STATE_RISING_LEFT &3c12 f0 0e BEQ &3c22 ; is_rising_from_right_wing ; is_rising_from_left_wing &3c14 e0 20 CPX #&20 ; RISING_MOVEMENT_MIDDLE &3c16 b0 0e BCS &3c26 ; shift_sprite_right # Always branches ; shift_sprite_left # Unused code &3c18 a5 72 LDA &72 ; sprite_address_low &3c1a 38 SEC &3c1b e9 2a SBC #&2a ; SPRITE_SIZE * 2 # Rotate sprite clockwise by two &3c1d 85 72 STA &72 ; sprite_address_low &3c1f 4c 2d 3c JMP &3c2d ; skip_setting_sprite ; is_rising_from_right_wing &3c22 e0 20 CPX #&20 ; RISING_MOVEMENT_MIDDLE &3c24 b0 f2 BCS &3c18 ; shift_sprite_left # Never branches ; shift_sprite_right &3c26 a5 72 LDA &72 ; sprite_address_low &3c28 18 CLC &3c29 69 2a ADC #&2a ; SPRITE_SIZE * 2 # Rotate sprite anticlockwise by two &3c2b 85 72 STA &72 ; sprite_address_low ; skip_setting_sprite &3c2d 68 PLA ; rising movement &3c2e 39 c0 07 AND &07c0,Y ; attacking_enemies_state # Unnecessary code &3c31 29 40 AND #&40 # Unclear; STATE_RISING_LEFT or RISING_MOVEMENT_VERTICAL &3c33 08 PHP ; flag set &3c34 bd c0 1f LDA &1fc0,X ; rising_movement_table &3c37 28 PLP ; flag set &3c38 f0 02 BEQ &3c3c ; skip_unnecessary_eor # If &40 of rising movement set, &3c3a 49 00 EOR #&00 # Unnecessary code ; skip_unnecessary_eor &3c3c 29 41 AND #&41 ; RISING_MOVEMENT_VERTICAL | RISING_MOVEMENT_RIGHT_OR_UP &3c3e c9 40 CMP #&40 ; RISING_MOVEMENT_VERTICAL &3c40 b0 10 BCS &3c52 ; is_moving_vertically ; is_moving_horizontally &3c42 29 01 AND #&01 ; RISING_MOVEMENT_RIGHT_OR_UP &3c44 f0 06 BEQ &3c4c ; is_moving_left ; is_moving_right &3c46 20 65 3a JSR &3a65 ; move_enemy_right_a_pixel &3c49 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; is_moving_left &3c4c 20 96 3a JSR &3a96 ; move_enemy_left_a_pixel &3c4f 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; is_moving_vertically &3c52 29 01 AND #&01 ; RISING_MOVEMENT_RIGHT_OR_UP &3c54 f0 06 BEQ &3c5c ; is_moving_down ; is_moving_up &3c56 20 c2 3a JSR &3ac2 ; move_enemy_up_a_pixel &3c59 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; is_moving_down &3c5c 20 e2 3a JSR &3ae2 ; move_enemy_down_a_pixel ; set_attacking_enemy_addresses &3c5f a4 7c LDY &7c ; enemy_to_update &3c61 a5 70 LDA &70 ; screen_address_low &3c63 99 a0 07 STA &07a0,Y ; attacking_enemies_screen_address_low &3c66 a5 71 LDA &71 ; screen_address_high &3c68 99 b0 07 STA &07b0,Y ; attacking_enemies_screen_address_high &3c6b a5 72 LDA &72 ; sprite_address_low &3c6d 99 80 07 STA &0780,Y ; attacking_enemies_sprite_address_low &3c70 a5 73 LDA &73 ; sprite_address_high &3c72 99 90 07 STA &0790,Y ; attacking_enemies_sprite_address_high &3c75 a5 7b LDA &7b ; group &3c77 99 d0 07 STA &07d0,Y ; attacking_enemies_group &3c7a 20 26 34 JSR &3426 ; plot_enemy_sprite &3c7d a4 7c LDY &7c ; enemy_to_update &3c7f 60 RTS ; consider_flipping_enemy_direction &3c80 a5 1f LDA &1f ; grouped_enemy_bombing_state &3c82 d0 13 BNE &3c97 ; flip_direction # Non-zero below group &0c &3c84 c0 06 CPY #&06 ; ENEMY_GROUP_LEADER &3c86 f0 19 BEQ &3ca1 ; is_group_leader ; not_group_leader &3c88 ad c6 07 LDA &07c6 ; attacking_enemies_state + 6 &3c8b 99 c0 07 STA &07c0,Y ; attacking_enemies_state # Set escort state from leader &3c8e ad f6 07 LDA &07f6 ; attacking_enemies_bombing_state + 6 # Used as direction change cooldown for grouped enemies &3c91 99 f0 07 STA &07f0,Y ; attacking_enemies_bombing_state # Set escort cooldown for subsequent changes from leader &3c94 4c c4 3c JMP &3cc4 ; set_enemy_bombing_state # i.e. escorts change direction at same time as leader ; flip_direction &3c97 a5 75 LDA &75 ; enemy_state &3c99 49 01 EOR #&01 ; STATE_DIVING_RIGHT # Flip horizontal direction of dive &3c9b 85 75 STA &75 ; enemy_state &3c9d 99 c0 07 STA &07c0,Y ; attacking_enemies_state &3ca0 60 RTS ; is_group_leader &3ca1 be d0 07 LDX &07d0,Y ; attacking_enemies_group &3ca4 a5 70 LDA &70 ; screen_address_low &3ca6 38 SEC &3ca7 fd 00 1f SBC &1f00,X ; group_addresses_low &3caa 85 22 STA &22 ; enemy_x &3cac a5 71 LDA &71 ; screen_address_high &3cae fd 20 1f SBC &1f20,X ; group_addresses_high &3cb1 d0 0a BNE &3cbd ; set_diving_left &3cb3 a5 22 LDA &22 ; enemy_x &3cb5 c9 a0 CMP #&a0 &3cb7 b0 04 BCS &3cbd ; set_diving_left ; set_diving_right &3cb9 a9 81 LDA #&81 ; STATE_DIVING | STATE_DIVING_RIGHT &3cbb d0 02 BNE &3cbf ; set_enemy_state # Always branches ; set_diving_left &3cbd a9 80 LDA #&80 ; STATE_DIVING ; set_enemy_state &3cbf 85 75 STA &75 ; enemy_state &3cc1 99 c0 07 STA &07c0,Y ; attacking_enemies_state ; set_enemy_bombing_state &3cc4 a9 31 LDA #&31 # Schedule another direction change &3cc6 99 f0 07 STA &07f0,Y ; attacking_enemies_bombing_state # Used as direction change cooldown for grouped enemies &3cc9 60 RTS ; update_grouped_enemy_diving_towards_player &3cca be f0 07 LDX &07f0,Y ; attacking_enemies_bombing_state # Used as direction change cooldown for grouped enemies &3ccd ca DEX &3cce 8a TXA &3ccf 99 f0 07 STA &07f0,Y ; attacking_enemies_bombing_state &3cd2 d0 03 BNE &3cd7 ; skip_flipping_direction # Is is time to change direction? &3cd4 20 80 3c JSR &3c80 ; consider_flipping_enemy_direction ; skip_flipping_direction &3cd7 20 06 3b JSR &3b06 ; move_enemy_down_two_pixels &3cda 20 34 3b JSR &3b34 ; move_enemy_horizontally &3cdd a5 70 LDA &70 ; screen_address_low &3cdf 29 06 AND #&06 &3ce1 f0 03 BEQ &3ce6 ; to_consider_bombing # Has the enemy moved into a new group? &3ce3 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; to_consider_bombing &3ce6 a4 7c LDY &7c ; enemy_to_update &3ce8 a6 1f LDX &1f ; grouped_enemy_bombing_state # Use group bombing state when considering bombing &3cea 4c 27 3d JMP &3d27 ; consider_bombing ; update_enemy_diving_towards_player # STATE_DIVING set, enemy is diving towards player &3ced c0 06 CPY #&06 ; ENEMY_GROUP_LEADER &3cef b0 d9 BCS &3cca ; update_grouped_enemy_diving_towards_player ; not_grouped_enemy &3cf1 20 e2 3a JSR &3ae2 ; move_enemy_down_a_pixel &3cf4 24 75 BIT &75 ; enemy_state &3cf6 50 03 BVC &3cfb ; not_homing # Is STATE_HOMING (&40) set? &3cf8 4c 45 3e JMP &3e45 ; consider_homing_towards_player ; not_homing # STATE_DIVING set, STATE_HOMING unset &3cfb b9 f0 07 LDA &07f0,Y ; attacking_enemies_bombing_state &3cfe c9 02 CMP #&02 &3d00 90 03 BCC &3d05 ; skip_moving_down &3d02 20 e2 3a JSR &3ae2 ; move_enemy_down_a_pixel # Enemies dive faster below group &0d ; skip_moving_down &3d05 a5 75 LDA &75 ; enemy_state &3d07 29 04 AND #&04 ; STATE_DIVING_HORIZONTAL &3d09 f0 03 BEQ &3d0e ; skip_moving_horizontally &3d0b 20 34 3b JSR &3b34 ; move_enemy_horizontally ; skip_moving_horizontally &3d0e a5 75 LDA &75 ; enemy_state &3d10 29 02 AND #&02 ; STATE_DIVING_HORIZONTAL_HALF &3d12 f0 08 BEQ &3d1c ; skip_moving_horizontally_one_time_in_two &3d14 a5 79 LDA &79 ; update_counter &3d16 4a LSR A &3d17 90 03 BCC &3d1c ; skip_moving_horizontally_one_time_in_two &3d19 20 34 3b JSR &3b34 ; move_enemy_horizontally ; skip_moving_horizontally_one_time_in_two &3d1c a4 7c LDY &7c ; enemy_to_update &3d1e be f0 07 LDX &07f0,Y ; attacking_enemies_bombing_state &3d21 a5 70 LDA &70 ; screen_address_low &3d23 29 07 AND #&07 &3d25 d0 57 BNE &3d7e ; to_set_attacking_enemy_addresses # Has the enemy moved into a new group? ; consider_bombing &3d27 a5 71 LDA &71 ; screen_address_high &3d29 48 PHA ; screen_address_high &3d2a a5 70 LDA &70 ; screen_address_low &3d2c e0 00 CPX #&00 &3d2e f0 47 BEQ &3d77 ; is_bombing_state_0 &3d30 e0 01 CPX #&01 &3d32 f0 3a BEQ &3d6e ; is_bombing_state_1 &3d34 e0 02 CPX #&02 &3d36 f0 2d BEQ &3d65 ; is_bombing_state_2 &3d38 e0 03 CPX #&03 &3d3a f0 22 BEQ &3d5e ; is_bombing_state_3 &3d3c e0 04 CPX #&04 &3d3e f0 14 BEQ &3d54 ; is_bombing_state_4 &3d40 e0 05 CPX #&05 &3d42 f0 09 BEQ &3d4d ; is_bombing_state_5 ; is_bombing_state_6 &3d44 c9 c0 CMP #&c0 ; &7ec0 = group &1d &3d46 68 PLA ; screen_address_high &3d47 e9 7e SBC #&7e &3d49 b0 36 BCS &3d81 ; at_bottom_of_screen &3d4b 90 31 BCC &3d7e ; to_set_attacking_enemy_addresses # Always branches ; is_bombing_state_5 &3d4d 68 PLA ; screen_address_high &3d4e c9 76 CMP #&76 ; &7600 = group &16 &3d50 b0 76 BCS &3dc8 ; rotate_enemy_depending_on_direction # Rotate enemy at group &16 &3d52 90 2a BCC &3d7e ; to_set_attacking_enemy_addresses # Always branches ; is_bombing_state_4 &3d54 c9 80 CMP #&80 ; &7380 = group &14 &3d56 68 PLA ; screen_address_high &3d57 e9 73 SBC #&73 &3d59 90 23 BCC &3d7e ; to_set_attacking_enemy_addresses &3d5b 4c dd 3d JMP &3ddd ; add_enemy_bomb # Drop bomb at group &14 ; is_bombing_state_3 &3d5e 68 PLA ; screen_address_high &3d5f c9 71 CMP #&71 ; &7100 = group &12 &3d61 b0 7a BCS &3ddd ; add_enemy_bomb # Drop bomb at group &12 &3d63 90 19 BCC &3d7e ; to_set_attacking_enemy_addresses # Always branches ; is_bombing_state_2 &3d65 c9 40 CMP #&40 ; &6d40 = group &0f &3d67 68 PLA ; screen_address_high &3d68 e9 6d SBC #&6d &3d6a b0 44 BCS &3db0 ; set_enemy_moving_right # Set enemy moving right at group &0f &3d6c 90 10 BCC &3d7e ; to_set_attacking_enemy_addresses # Always branches ; is_bombing_state_1 &3d6e c9 c0 CMP #&c0 ; &6ac0 = group &0d &3d70 68 PLA ; screen_address_high &3d71 e9 6a SBC #&6a &3d73 b0 68 BCS &3ddd ; add_enemy_bomb # Drop bomb at group &0d &3d75 90 07 BCC &3d7e ; to_set_attacking_enemy_addresses # Always branches ; is_bombing_state_0 &3d77 c9 80 CMP #&80 ; &6980 = group &0c &3d79 68 PLA ; screen_address_high &3d7a e9 69 SBC #&69 &3d7c b0 4a BCS &3dc8 ; rotate_enemy_depending_on_direction # Rotate enemy at group &0d ; to_set_attacking_enemy_addresses &3d7e 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; at_bottom_of_screen &3d81 a6 7c LDX &7c ; enemy_to_update &3d83 a9 00 LDA #&00 &3d85 9d b0 07 STA &07b0,X ; attacking_enemies_screen_address_high # Set to zero to indicate enemy no longer attacking &3d88 bc e0 07 LDY &07e0,X ; attacking_enemies_passive_slot &3d8b c0 16 CPY #&16 ; ENEMY_FIRST_LEADER &3d8d 90 04 BCC &3d93 ; to_set_enemy_returning &3d8f c0 1c CPY #&1c ; ENEMY_LAST_LEADER + 1 &3d91 90 06 BCC &3d99 ; set_group_leader_returning ; to_set_enemy_returning &3d93 20 8b 39 JSR &398b ; set_enemy_returning &3d96 a4 7c LDY &7c ; enemy_to_update &3d98 60 RTS ; set_group_leader_returning &3d99 20 9a 52 JSR &529a ; find_escorting_enemies # Returns X = number of escorting enemies &3d9c 8a TXA &3d9d d0 f4 BNE &3d93 ; to_set_enemy_returning # If escorts present, leader returns to formation ; no_escort # If escorts, but not leader, were destroyed, &3d9f a9 ff LDA #&ff # leader does not return to formation, but is removed &3da1 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set to &ff to indicate passive enemy not present &3da4 ce 0c 04 DEC &040c ; number_of_active_enemies &3da7 ce 01 05 DEC &0501 ; number_of_enemies &3daa ce ff 05 DEC &05ff ; player_leaders_to_remove_minus_one &3dad a4 7c LDY &7c ; enemy_to_update &3daf 60 RTS ; set_enemy_moving_right &3db0 20 3f 3b JSR &3b3f ; increment_bombing_state ; set_enemy_moving_right_without_incrementing_bombing_state &3db3 a4 7c LDY &7c ; enemy_to_update &3db5 c0 06 CPY #&06 ; ENEMY_GROUP_LEADER &3db7 b0 0c BCS &3dc5 ; to_set_attacking_enemy_addresses ; not_grouped_enemy &3db9 a9 c0 LDA #&c0 ; STATE_DIVING | STATE_HOMING &3dbb 0d 26 04 ORA &0426 ; delay_before_homing &3dbe 99 c0 07 STA &07c0,Y ; attacking_enemies_state &3dc1 a9 15 LDA #&15 ; SPRITE_ROTATION_1 &3dc3 85 72 STA &72 ; sprite_address_low ; to_set_attacking_enemy_addresses &3dc5 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; rotate_enemy_depending_on_direction &3dc8 a9 d2 LDA #&d2 ; SPRITE_ROTATION_10 &3dca 46 75 LSR &75 ; enemy_state # Set carry from STATE_DIVING_RIGHT &3dcc 90 02 BCC &3dd0 ; set_sprite_address &3dce a9 e7 LDA #&e7 ; SPRITE_ROTATION_11 ; set_sprite_address &3dd0 85 72 STA &72 ; sprite_address_low &3dd2 26 75 ROL &75 ; enemy_state # Restore STATE_DIVING_RIGHT from carry &3dd4 20 3f 3b JSR &3b3f ; increment_bombing_state &3dd7 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; to_set_attacking_enemy_addresses &3dda 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; add_enemy_bomb &3ddd 20 3f 3b JSR &3b3f ; increment_bombing_state &3de0 a4 7c LDY &7c ; enemy_to_update &3de2 a2 ff LDX #&ff ; find_free_bomb_slot_loop &3de4 e8 INX &3de5 e0 10 CPX #&10 &3de7 f0 f1 BEQ &3dda ; to_set_attacking_enemy_addresses # Leave if no free bomb slot &3de9 bd a0 04 LDA &04a0,X ; enemy_bombs_pixel_value &3dec d0 f6 BNE &3de4 ; find_free_bomb_slot_loop &3dee b9 a0 07 LDA &07a0,Y ; attacking_enemies_screen_address_low &3df1 18 CLC &3df2 69 08 ADC #&08 # Drop bomb from middle of enemy &3df4 9d 80 04 STA &0480,X ; enemy_bombs_screen_address_low &3df7 86 76 STX &76 ; bomb_slot &3df9 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high &3dfc 69 00 ADC #&00 &3dfe 9d 90 04 STA &0490,X ; enemy_bombs_screen_address_high &3e01 85 75 STA &75 ; unused &3e03 a9 88 LDA #&88 ; 3000 &3e05 85 77 STA &77 ; pixel_value &3e07 b9 90 07 LDA &0790,Y ; attacking_enemies_sprite_address_high &3e0a 38 SEC &3e0b e9 0c SBC #&0c ; &0c00 = enemy_type_0_shift_0_sprites &3e0d 4a LSR A &3e0e 4a LSR A &3e0f aa TAX &3e10 f0 05 BEQ &3e17 ; use_pixel_value ; shift_pixel_value_loop # Use enemy shift to set bomb shift &3e12 46 77 LSR &77 ; pixel_value &3e14 ca DEX &3e15 d0 fb BNE &3e12 ; shift_pixel_value_loop ; use_pixel_value &3e17 a6 76 LDX &76 ; bomb_slot &3e19 a5 77 LDA &77 ; pixel_value &3e1b 9d a0 04 STA &04a0,X ; enemy_bombs_pixel_value &3e1e b9 d0 07 LDA &07d0,Y ; attacking_enemies_group &3e21 9d b0 04 STA &04b0,X ; enemy_bombs_group &3e24 a8 TAY &3e25 bd 80 04 LDA &0480,X ; enemy_bombs_screen_address_low &3e28 38 SEC &3e29 f9 00 1f SBC &1f00,Y ; group_addresses_low &3e2c 85 77 STA &77 ; bomb_x &3e2e bd 90 04 LDA &0490,X ; enemy_bombs_screen_address_high &3e31 f9 20 1f SBC &1f20,Y ; group_addresses_high &3e34 a4 76 LDY &76 ; bomb_slot &3e36 4a LSR A &3e37 66 77 ROR &77 ; bomb_x &3e39 46 77 LSR &77 ; bomb_x &3e3b 46 77 LSR &77 ; bomb_x &3e3d a5 77 LDA &77 ; bomb_x &3e3f 9d c0 04 STA &04c0,X ; enemy_bombs_x &3e42 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; consider_homing_towards_player # STATE_DIVING and STATE_HOMING set &3e45 c6 75 DEC &75 ; enemy_state &3e47 a5 75 LDA &75 ; enemy_state &3e49 99 c0 07 STA &07c0,Y ; attacking_enemies_state &3e4c 29 1f AND #&1f ; STATE_HOMING_TIMER_MASK &3e4e f0 03 BEQ &3e53 ; move_enemy_towards_player &3e50 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; move_enemy_towards_player &3e53 a6 7b LDX &7b ; group &3e55 a4 7c LDY &7c ; enemy_to_update &3e57 a5 70 LDA &70 ; screen_address_low &3e59 29 f8 AND #&f8 &3e5b 38 SEC &3e5c fd 00 1f SBC &1f00,X ; group_addresses_low &3e5f 48 PHA ; enemy_x_low &3e60 a5 71 LDA &71 ; screen_address_high &3e62 fd 20 1f SBC &1f20,X ; group_addresses_high &3e65 aa TAX &3e66 a5 80 LDA &80 ; player_screen_address_low &3e68 38 SEC &3e69 e9 c0 SBC #&c0 &3e6b 85 74 STA &74 ; player_x_low &3e6d a5 81 LDA &81 ; player_screen_address_high &3e6f e9 79 SBC #&79 &3e71 85 75 STA &75 ; player_x_high &3e73 68 PLA ; enemy_x_low &3e74 c5 74 CMP &74 ; player_x_low &3e76 8a TXA &3e77 e5 75 SBC &75 ; player_x_high &3e79 90 04 BCC &3e7f ; enemy_is_left_of_player ; enemy_is_right_of_player &3e7b a9 84 LDA #&84 ; STATE_DIVING | STATE_DIVING_HORIZONTAL &3e7d d0 02 BNE &3e81 ; set_enemy_state ; enemy_is_left_of_player &3e7f a9 85 LDA #&85 ; STATE_DIVING | STATE_DIVING_HORIZONTAL | STATE_DIVING_RIGHT ; set_enemy_state &3e81 aa TAX ; state &3e82 a5 73 LDA &73 ; sprite_address_high &3e84 c9 2a CMP #&2a ; &2a00 = enemy_type_1_shift_0_sprites &3e86 d0 02 BNE &3e8a ; skip_unpatching_address &3e88 a9 0d LDA #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites ; skip_unpatching_address # cdef &3e8a 29 03 AND #&03 # 0123 &3e8c 49 01 EOR #&01 # 1032 &3e8e 08 PHP ; enemy is type two &3e8f 8a TXA ; state &3e90 28 PLP ; enemy is type two &3e91 d0 02 BNE &3e95 ; not_type_two # Type 2 aliens move more horizontally &3e93 09 02 ORA #&02 ; STATE_DIVING_HORIZONTAL_HALF ; not_rank_two &3e95 99 c0 07 STA &07c0,Y ; attacking_enemies_state &3e98 4c 5f 3c JMP &3c5f ; set_attacking_enemy_addresses ; leave &3e9b 60 RTS ; update_attacking_enemies_in_bottom_half &3e9c a0 ff LDY #&ff ; update_attacking_enemies_in_bottom_half_loop &3e9e c8 INY &3e9f c0 0f CPY #&0f &3ea1 f0 f8 BEQ &3e9b ; leave &3ea3 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high &3ea6 f0 f6 BEQ &3e9e ; update_attacking_enemies_in_bottom_half_loop &3ea8 c9 6c CMP #&6c ; &6c00 = group &0e &3eaa 90 f2 BCC &3e9e ; update_attacking_enemies_in_bottom_half_loop &3eac 20 a5 3b JSR &3ba5 ; update_attacking_enemy &3eaf 4c 9e 3e JMP &3e9e ; update_attacking_enemies_in_bottom_half_loop ; update_attacking_enemies_in_top_half &3eb2 a0 ff LDY #&ff &3eb4 c8 INY ; update_attacking_enemies_in_top_half_loop &3eb5 c0 0f CPY #&0f &3eb7 f0 e2 BEQ &3e9b ; leave &3eb9 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high &3ebc f0 f6 BEQ &3eb4 ; update_attacking_enemies_in_top_half_loop &3ebe c9 6c CMP #&6c ; &6c00 = group &0e &3ec0 b0 f2 BCS &3eb4 ; update_attacking_enemies_in_top_half_loop &3ec2 20 a5 3b JSR &3ba5 ; update_attacking_enemy &3ec5 4c b4 3e JMP &3eb4 ; update_attacking_enemies_in_top_half_loop ; rnd &3ec8 86 6f STX &6f ; tmp_x &3eca a2 08 LDX #&08 ; shuffle_rnd_state_loop &3ecc a5 0a LDA &0a ; rnd_state &3ece 29 48 AND #&48 &3ed0 69 38 ADC #&38 &3ed2 0a ASL A &3ed3 0a ASL A &3ed4 26 0c ROL &0c ; rnd_state + 2 &3ed6 26 0b ROL &0b ; rnd_state + 1 &3ed8 26 0a ROL &0a ; rnd_state &3eda ca DEX &3edb d0 ef BNE &3ecc ; shuffle_rnd_state_loop &3edd a5 0a LDA &0a ; rnd_state &3edf 05 0b ORA &0b ; rnd_state + 1 &3ee1 05 0c ORA &0c ; rnd_state + 2 &3ee3 d0 11 BNE &3ef6 ; skip_resetting_rnd_state &3ee5 a5 84 LDA &84 ; player_x &3ee7 85 0c STA &0c ; rnd_state + 2 &3ee9 2a ROL A &3eea 49 5a EOR #&5a &3eec 85 0b STA &0b ; rnd_state + 1 &3eee a5 70 LDA &70 ; screen_address_low &3ef0 45 71 EOR &71 ; screen_address_high &3ef2 45 72 EOR &72 ; sprite_address_low &3ef4 85 0a STA &0a ; rnd_state ; skip_resetting_rnd_state &3ef6 a6 6f LDX &6f ; tmp_x &3ef8 a5 0a LDA &0a ; rnd_state &3efa 60 RTS # Shouldn't leave with zero ; consider_starting_or_continuing_to_attack &3efb c6 8b DEC &8b ; attack_cooldown &3efd f0 01 BEQ &3f00 ; start_or_add_to_attack &3eff 60 RTS ; start_or_add_to_attack &3f00 ad 0e 04 LDA &040e ; size_and_direction_of_attack &3f03 29 07 AND #&07 &3f05 f0 03 BEQ &3f0a ; consider_starting_attack # Zero if no enemies need adding to previous attack &3f07 4c 25 40 JMP &4025 ; continue_attack ; consider_starting_ttack &3f0a ad 0d 04 LDA &040d ; number_of_passive_enemies &3f0d f0 07 BEQ &3f16 ; to_reset_attack_cooldown # Can't attack if no passive enemies &3f0f ad 0c 04 LDA &040c ; number_of_active_enemies &3f12 c9 06 CMP #&06 &3f14 90 03 BCC &3f19 ; start_attack # Can't attack if too many attacking enemies already ; to_reset_attack_cooldown &3f16 4c 9a 40 JMP &409a ; reset_attack_cooldown ; start_attack &3f19 c6 54 DEC &54 ; grouped_attack_cooldown &3f1b f0 03 BEQ &3f20 ; consider_starting_grouped_attack &3f1d 4c 10 40 JMP &4010 ; start_regular_attack ; consider_starting_grouped_attack &3f20 20 c8 3e JSR &3ec8 ; rnd &3f23 29 03 AND #&03 &3f25 18 CLC &3f26 69 04 ADC #&04 &3f28 85 54 STA &54 ; grouped_attack_cooldown # Grouped attacks occur every four to seven attacks &3f2a ad b6 07 LDA &07b6 ; attacking_enemies_screen_address_high + 6 &3f2d 0d b7 07 ORA &07b7 ; attacking_enemies_screen_address_high + 7 &3f30 0d b8 07 ORA &07b8 ; attacking_enemies_screen_address_high + 8 &3f33 d0 07 BNE &3f3c ; to_start_regular_attack # so long as a grouped attack isn't already in progress &3f35 ad 0c 04 LDA &040c ; number_of_active_enemies &3f38 c9 05 CMP #&05 &3f3a 90 03 BCC &3f3f ; start_grouped_attack # and there aren't too many attacking enemies already ; to_start_regular_attack &3f3c 4c 10 40 JMP &4010 ; start_regular_attack ; start_grouped_attack &3f3f 20 c6 52 JSR &52c6 ; get_random_leader_enemy # Returns random leader enemy offset, or zero if none &3f42 8a TXA &3f43 d0 03 BNE &3f48 ; found_random_leader_enemy &3f45 4c 10 40 JMP &4010 ; start_regular_attack # Can't start grouped attack if no leader ; found_random_leader_enemy &3f48 84 6a STY &6a ; group_leader_passive_slot &3f4a 20 b9 51 JSR &51b9 ; play_sound_for_attacking_enemy &3f4d a4 6a LDY &6a ; group_leader_passive_slot &3f4f b9 c8 05 LDA &05c8,Y ; passive_enemies_group &3f52 29 7f AND #&7f ; GROUP_MASK | &60 # Lowest five bits are group &3f54 aa TAX &3f55 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &3f58 38 SEC &3f59 fd 00 1f SBC &1f00,X ; group_addresses_low &3f5c 85 40 STA &40 ; enemy_x_low &3f5e b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &3f61 fd 20 1f SBC &1f20,X ; group_addresses_high &3f64 85 41 STA &41 ; enemy_x_high &3f66 a5 40 LDA &40 ; enemy_x_low &3f68 c9 a0 CMP #&a0 &3f6a a5 41 LDA &41 ; enemy_x_high &3f6c e9 00 SBC #&00 &3f6e a9 00 LDA #&00 # Clear top bit to indicate attacking from left &3f70 90 02 BCC &3f74 ; set_size_and_direction_of_attack &3f72 a9 80 LDA #&80 ; ATTACK_RIGHT # Set top bit to indicate attacking from right ; set_size_and_direction_of_attack &3f74 8d 0e 04 STA &040e ; size_and_direction_of_attack &3f77 a2 06 LDX #&06 ; ENEMY_GROUP_LEADER &3f79 20 ec 39 JSR &39ec ; add_attacking_enemy_to_slot_X &3f7c a9 08 LDA #&08 # Leader changes direction after escorts &3f7e 8d f6 07 STA &07f6 ; attacking_enemies_bombing_state + 6 # Used as direction change cooldown for grouped enemies &3f81 a4 6a LDY &6a ; group_leader_passive_slot &3f83 a9 00 LDA #&00 &3f85 85 1f STA &1f ; grouped_enemy_bombing_state # Set to zero to allow group to bomb &3f87 a9 00 LDA #&00 &3f89 8d 23 04 STA &0423 ; group_escorts_killed &3f8c a9 84 LDA #&84 # Unnecessary code; value is unused &3f8e 2c 0e 04 BIT &040e ; size_and_direction_of_attack # Top bit set if attacking from right &3f91 10 02 BPL &3f95 ; skip_eor &3f93 49 01 EOR #&01 ; skip_eor &3f95 85 3d STA &3d ; unused # Unused variable &3f97 20 9a 52 JSR &529a ; find_escorting_enemies # Returns X = number of escorting enemies &3f9a a4 6a LDY &6a ; group_leader_passive_slot &3f9c 8a TXA &3f9d d0 03 BNE &3fa2 ; has_escorts &3f9f 4c 9a 40 JMP &409a ; reset_attack_cooldown ; has_escorts &3fa2 86 6b STX &6b ; escort_count &3fa4 c0 19 CPY #&19 ; ENEMY_FIRST_RIGHT # Is the enemy on the right of the formation? &3fa6 b0 1e BCS &3fc6 ; is_on_right ; is_on_left &3fa8 a2 00 LDX #&00 &3faa a9 07 LDA #&07 ; ENEMY_GROUP_LEADER + 1 &3fac 85 01 STA &01 ; escort_slot ; add_escorts_to_leader_enemy_on_left_loop # For each found escort, from the left, &3fae b5 70 LDA &70,X ; escorting_enemies_passive_slot &3fb0 f0 06 BEQ &3fb8 ; consider_next_escort # Is there an escort in this slot? &3fb2 a8 TAY &3fb3 20 e3 3f JSR &3fe3 ; add_escorting_enemy # If so, add it to group &3fb6 e6 01 INC &01 ; escort_slot ; consider_next_escort &3fb8 e8 INX &3fb9 e4 6b CPX &6b ; escort_count &3fbb f0 06 BEQ &3fc3 ; to_reset_attack_cooldown &3fbd a5 01 LDA &01 ; escort_slot &3fbf c9 09 CMP #&09 ; ENEMY_GROUP_LEADER + 3 # until two escorts have been added &3fc1 d0 eb BNE &3fae ; add_escorts_to_leader_enemy_on_left_loop ; to_reset_attack_cooldown &3fc3 4c 9a 40 JMP &409a ; reset_attack_cooldown ; is_on_right &3fc6 a6 6b LDX &6b ; escort_count &3fc8 ca DEX &3fc9 a9 07 LDA #&07 ; ENEMY_GROUP_LEADER + 1 &3fcb 85 01 STA &01 ; escort_slot ; add_escorts_to_leader_enemy_on_right_loop # For each found escort, from the right, &3fcd b5 70 LDA &70,X ; escorting_enemies_passive_slot &3fcf f0 06 BEQ &3fd7 ; consider_next_escort # Is there an escort in this slot? &3fd1 a8 TAY &3fd2 20 e3 3f JSR &3fe3 ; add_escorting_enemy # If so, add it to group &3fd5 e6 01 INC &01 ; escort_slot ; consider_next_escort &3fd7 ca DEX &3fd8 30 06 BMI &3fe0 ; add_escorts_to_leader_enemy_on_right_loop &3fda a5 01 LDA &01 ; escort_slot &3fdc c9 09 CMP #&09 ; ENEMY_GROUP_LEADER + 3 # until two escorts have been added &3fde d0 ed BNE &3fcd &3fe0 4c 9a 40 JMP &409a ; reset_attack_cooldown ; add_escorting_enemy &3fe3 98 TYA &3fe4 48 PHA ; tmp_y &3fe5 8a TXA &3fe6 48 PHA ; tmp_x &3fe7 a2 02 LDX #&02 ; backup_escorting_enemies_passive_slot_loop &3fe9 b5 70 LDA &70,X ; escorting_enemies_passive_slot &3feb 48 PHA ; slot &3fec ca DEX &3fed 10 fa BPL &3fe9 ; backup_escorting_enemies_passive_slot_loop &3fef a6 01 LDX &01 ; escort_slot &3ff1 20 ec 39 JSR &39ec ; add_attacking_enemy_to_slot_X &3ff4 a6 01 LDX &01 ; escort_slot &3ff6 a9 01 LDA #&01 # Escorts change direction before leader &3ff8 9d f0 07 STA &07f0,X ; attacking_enemies_bombing_state # Used as direction change cooldown for grouped enemies &3ffb ad c6 07 LDA &07c6 ; attacking_enemies_state + 6 &3ffe 9d c0 07 STA &07c0,X ; attacking_enemies_state # Set escort state from leader &4001 a2 00 LDX #&00 ; restore_escorting_enemies_passive_slot_loop &4003 68 PLA ; slot &4004 95 70 STA &70,X ; escorting_enemies_passive_slot &4006 e8 INX &4007 e0 03 CPX #&03 &4009 d0 f8 BNE &4003 ; restore_escorting_enemies_passive_slot_loop &400b 68 PLA ; tmp_x &400c aa TAX &400d 68 PLA ; tmp_y &400e a8 TAY &400f 60 RTS ; start_regular_attack ; choose_random_attack_size &4010 20 c8 3e JSR &3ec8 ; rnd &4013 2d 47 04 AND &0447 ; attack_direction_and_size_mask # Either &87 or &83 &4016 8d 0e 04 STA &040e ; size_and_direction_of_attack &4019 29 07 AND #&07 &401b cd fa 05 CMP &05fa ; player_maximum_size_of_regular_attack_minus_one &401e f0 02 BEQ &4022 ; set_attack_size &4020 b0 ee BCS &4010 ; choose_random_attack_size ; set_attack_size &4022 ee 0e 04 INC &040e ; size_and_direction_of_attack ; continue_attack &4025 ad 0d 04 LDA &040d ; number_of_passive_enemies &4028 f0 5b BEQ &4085 ; consider_next_enemy_in_attack # Can't attack if no passive enemies &402a ad 0c 04 LDA &040c ; number_of_active_enemies &402d c9 06 CMP #&06 &402f b0 54 BCS &4085 ; consider_next_enemy_in_attack # Can't attack if too many enemies attacking already &4031 2c 0e 04 BIT &040e ; size_and_direction_of_attack # Top bit set if attacking from right &4034 30 29 BMI &405f ; attacking_from_right ; attacking_from_left &4036 ce 10 05 DEC &0510 ; leftmost_enemy_slot ; find_leftmost_enemy_loop # Find the leftmost enemy that is still present &4039 ee 10 05 INC &0510 ; leftmost_enemy_slot &403c ac 10 05 LDY &0510 ; leftmost_enemy_slot &403f cc 11 05 CPY &0511 ; rightmost_enemy_slot &4042 b0 41 BCS &4085 ; consider_next_enemy_in_attack &4044 be c8 05 LDX &05c8,Y ; passive_enemies_group # &ff if passive enemy not present &4047 e8 INX &4048 f0 ef BEQ &4039 ; find_leftmost_enemy_loop &404a 88 DEY ; find_left_enemy_loop &404b c8 INY &404c be c8 05 LDX &05c8,Y ; passive_enemies_group # Top bit set if enemy is active &404f 30 fa BMI &404b ; find_left_enemy_loop &4051 cc 11 05 CPY &0511 ; rightmost_enemy_slot &4054 b0 2f BCS &4085 ; consider_next_enemy_in_attack &4056 20 df 39 JSR &39df ; add_attacking_enemy # Add leftmost passive enemy &4059 20 b9 51 JSR &51b9 ; play_sound_for_attacking_enemy &405c 4c 85 40 JMP &4085 ; consider_next_enemy_in_attack ; attacking_from_right &405f ee 11 05 INC &0511 ; rightmost_enemy_slot ; find_rightmost_enemy_loop # Find the rightmost enemy that is still present &4062 ce 11 05 DEC &0511 ; rightmost_enemy_slot &4065 ac 11 05 LDY &0511 ; rightmost_enemy_slot &4068 cc 10 05 CPY &0510 ; leftmost_enemy_slot &406b 90 18 BCC &4085 ; consider_next_enemy_in_attack &406d be c8 05 LDX &05c8,Y ; passive_enemies_group # &ff if passive enemy not present &4070 e8 INX &4071 f0 ef BEQ &4062 ; find_rightmost_enemy_loop &4073 c8 INY ; find_right_enemy_loop &4074 88 DEY &4075 be c8 05 LDX &05c8,Y ; passive_enemies_group # Top bit set if enemy is active &4078 30 fa BMI &4074 ; find_right_enemy_loop &407a cc 10 05 CPY &0510 ; leftmost_enemy_slot &407d 90 06 BCC &4085 ; consider_next_enemy_in_attack &407f 20 df 39 JSR &39df ; add_attacking_enemy # Add rightmost passive enemy &4082 20 b9 51 JSR &51b9 ; play_sound_for_attacking_enemy ; consider_next_enemy_in_attack &4085 ce 0e 04 DEC &040e ; size_and_direction_of_attack &4088 ad 0e 04 LDA &040e ; size_and_direction_of_attack &408b 29 07 AND #&07 &408d f0 0b BEQ &409a ; reset_attack_cooldown # Is this attack finished? &408f 20 c8 3e JSR &3ec8 ; rnd &4092 29 03 AND #&03 &4094 18 CLC &4095 69 06 ADC #&06 &4097 85 8b STA &8b ; attack_cooldown # If not, set random delay for next enemy to attack &4099 60 RTS ; reset_attack_cooldown &409a ad 0e 04 LDA &040e ; size_and_direction_of_attack &409d 29 80 AND #&80 ; ATTACK_RIGHT # Keep top bit (direction of attack) &409f 8d 0e 04 STA &040e ; size_and_direction_of_attack &40a2 20 c8 3e JSR &3ec8 ; rnd &40a5 29 03 AND #&03 &40a7 18 CLC &40a8 6d 43 04 ADC &0443 ; attack_frequency &40ab 85 8b STA &8b ; attack_cooldown # Set random delay for next attack &40ad ce 43 04 DEC &0443 ; attack_frequency &40b0 d0 03 BNE &40b5 ; skip_floor &40b2 ee 43 04 INC &0443 ; attack_frequency ; skip_floor &40b5 60 RTS ; to_start_player_explosion &40b6 4c fc 4a JMP &4afc ; start_player_explosion ; to_update_player_explosion &40b9 4c 28 4b JMP &4b28 ; update_player_explosion ; to_consider_starting_new_life &40bc 4c e8 4a JMP &4ae8 ; consider_starting_new_life ; update_player &40bf ad 30 04 LDA &0430 ; player_explosion_timer # Non-zero if player exploding &40c2 d0 f5 BNE &40b9 ; to_update_player_explosion &40c4 ad 34 04 LDA &0434 ; new_life_cooldown # Non-zero if waiting to start new life &40c7 d0 f3 BNE &40bc ; to_consider_starting_new_life &40c9 ad 00 04 LDA &0400 ; laser_active # Non-zero if laser active &40cc d0 03 BNE &40d1 ; skip_unplotting_laser &40ce 20 66 35 JSR &3566 ; unplot_laser ; skip_unplotting_laser &40d1 a5 84 LDA &84 ; player_x &40d3 48 PHA ; previous player x ; check_for_movement &40d4 6c 10 00 JMP (&0010) ; movement_check_routine_address ; move_player &40d7 a2 03 LDX #&03 ; copy_player_screen_and_sprite_addresses_loop &40d9 b5 80 LDA &80,X ; player_screen_address &40db 95 70 STA &70,X ; screen_address &40dd ca DEX &40de 10 f9 BPL &40d9 ; copy_player_screen_and_sprite_addresses_loop &40e0 20 65 33 JSR &3365 ; unplot_player_sprite_with_collision_check &40e3 68 PLA ; previous player x &40e4 a6 77 LDX &77 ; collision_result &40e6 d0 ce BNE &40b6 ; to_start_player_explosion # Non-zero if collision occurred &40e8 c5 84 CMP &84 ; player_x &40ea f0 5a BEQ &4146 ; replot_player &40ec 90 2c BCC &411a ; consider_moving_player_right ; consider_moving_player_left &40ee a5 84 LDA &84 ; player_x &40f0 c9 03 CMP #&03 &40f2 b0 04 BCS &40f8 ; move_player_left # Is the player at the left edge of the screen? &40f4 e6 84 INC &84 ; player_x &40f6 90 4e BCC &4146 ; replot_player # Always branches ; move_player_left &40f8 a5 82 LDA &82 ; player_sprite_address_low &40fa d0 3f BNE &413b ; shift_player_sprite_left # Is the player moving into a new byte? &40fc a9 e1 LDA #&e1 ; &1ce1 = player_shift_3_sprite &40fe 85 82 STA &82 ; player_sprite_address_low &4100 a5 80 LDA &80 ; player_screen_address_low &4102 38 SEC &4103 e9 08 SBC #&08 # Move left four pixels &4105 85 80 STA &80 ; player_screen_address_low &4107 b0 3d BCS &4146 ; replot_player &4109 c6 81 DEC &81 ; player_screen_address_high &410b 90 39 BCC &4146 ; replot_player # Always branches ; shift_player_sprite_right &410d a5 82 LDA &82 ; player_sprite_address_low &410f 18 CLC &4110 69 4b ADC #&4b ; PLAYER_SPRITE_SIZE &4112 85 82 STA &82 ; player_sprite_address_low &4114 90 30 BCC &4146 ; replot_player &4116 e6 83 INC &83 ; player_sprite_address_high &4118 b0 2c BCS &4146 ; replot_player # Always branches ; consider_moving_player_right &411a a5 84 LDA &84 ; player_x &411c c9 9b CMP #&9b &411e 90 04 BCC &4124 ; move_player_right # Is the player at the left edge of the screen? &4120 c6 84 DEC &84 ; player_x &4122 b0 22 BCS &4146 ; replot_player # Always branches ; move_player_right &4124 a5 82 LDA &82 ; player_sprite_address_low &4126 c9 e1 CMP #&e1 ; PLAYER_SPRITE_SIZE * 3 &4128 d0 e3 BNE &410d ; shift_player_sprite_right # Is the player moving into a new byte? &412a a9 00 LDA #&00 ; &1c00 = player_shift_0_sprite &412c 85 82 STA &82 ; player_sprite_address_low &412e a5 80 LDA &80 ; player_screen_address_low &4130 18 CLC &4131 69 08 ADC #&08 # Move right four pixels &4133 85 80 STA &80 ; player_screen_address_low &4135 90 0f BCC &4146 ; replot_player &4137 e6 81 INC &81 ; player_screen_address_high &4139 b0 0b BCS &4146 ; replot_player # Always branches ; shift_player_sprite_left &413b a5 82 LDA &82 ; player_sprite_address_low &413d 38 SEC &413e e9 4b SBC #&4b ; PLAYER_SPRITE_SIZE &4140 85 82 STA &82 ; player_sprite_address_low &4142 b0 02 BCS &4146 ; replot_player &4144 c6 83 DEC &83 ; player_sprite_address_high ; replot_player &4146 a2 03 LDX #&03 ; copy_player_screen_and_sprite_addresses_loop &4148 b5 80 LDA &80,X ; player_screen_address &414a 95 70 STA &70,X ; screen_address &414c ca DEX &414d 10 f9 BPL &4148 ; copy_player_screen_and_sprite_addresses_loop &414f 20 02 33 JSR &3302 ; plot_player_sprite_with_collision_check &4152 a6 77 LDX &77 ; collision_result &4154 f0 03 BEQ &4159 ; to_consider_firing_laser # Non-zero if collision occurred &4156 4c b6 40 JMP &40b6 ; to_start_player_explosion ; to_consider_firing_laser &4159 20 71 52 JSR &5271 ; consider_firing_laser &415c 60 RTS ; main_game_loop &415d 20 d2 34 JSR &34d2 ; unplot_bottom_of_laser &4160 ad 00 04 LDA &0400 ; laser_active # Non-zero if laser active &4163 f0 03 BEQ &4168 ; skip_updating_laser &4165 20 c8 51 JSR &51c8 ; update_laser ; skip_updating_laser &4168 20 9f 47 JSR &479f ; update_explosions &416b 20 b2 3e JSR &3eb2 ; update_attacking_enemies_in_top_half &416e 20 03 46 JSR &4603 ; update_enemy_bombs &4171 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &4174 20 bf 40 JSR &40bf ; update_player &4177 20 3e 38 JSR &383e ; update_passive_enemies &417a 20 82 38 JSR &3882 ; update_returning_enemies &417d 20 9c 3e JSR &3e9c ; update_attacking_enemies_in_bottom_half &4180 20 fb 3e JSR &3efb ; consider_starting_or_continuing_to_attack &4183 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &4186 d0 03 BNE &418b ; skip_key_check &4188 20 95 4d JSR &4d95 ; check_for_game_start_keys ; skip_key_check &418b 20 a7 4a JSR &4aa7 ; wait_for_vsync &418e 20 e1 32 JSR &32e1 ; update_background_sound &4191 4c 5d 41 JMP &415d ; main_game_loop ; unused # Unused code; &4194 - &419c is a copy of &4171 - &4179 &4194 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &4197 20 bf 40 JSR &40bf ; update_player &419a 20 3e 38 JSR &383e ; update_passive_enemies ; start_new_game &419d ae 32 04 LDX &0432 ; initial_stack_offset &41a0 ba TSX &41a1 a9 0a LDA #&0a # Change to MODE 5 and set up game screen &41a3 20 32 43 JSR &4332 ; write_string &41a6 a9 04 LDA #&04 ; Write text at text cursor &41a8 20 ee ff JSR &ffee ; OSWRCH &41ab 20 77 47 JSR &4777 ; plot_high_score &41ae 20 a5 35 JSR &35a5 ; wipe_game_area &41b1 a9 08 LDA #&08 ; "RANK:" &41b3 20 32 43 JSR &4332 ; write_string &41b6 20 62 47 JSR &4762 ; initialise_player_score &41b9 a9 05 LDA #&05 &41bb 85 54 STA &54 ; grouped_attack_cooldown ; start_new_game_without_setting_up_screen &41bd a9 03 LDA #&03 # Player starts with three lives &41bf 8d fc 05 STA &05fc ; player_lives &41c2 a9 03 LDA #&03 # Formation starts with two leaders &41c4 8d ff 05 STA &05ff ; player_leaders_to_remove_minus_one &41c7 a9 00 LDA #&00 &41c9 8d fd 05 STA &05fd ; player_level &41cc a2 00 LDX #&00 &41ce 8e 00 04 STX &0400 ; laser_active # Non-zero if laser active &41d1 ca DEX ; &ff &41d2 8e 01 04 STX &0401 ; laser_firing_suppressed # Set to non-zero to allow firing &41d5 a9 90 LDA #&90 &41d7 8d 03 04 STA &0403 ; laser_screen_address_high &41da a9 1e LDA #&1e ; 30 &41dc 8d fe 05 STA &05fe ; player_rank &41df a9 00 LDA #&00 &41e1 8d 23 04 STA &0423 ; group_escorts_killed &41e4 8d 1f 04 STA &041f ; explosion_is_active_group_leader &41e7 8d 30 04 STA &0430 ; player_explosion_timer &41ea 8d 31 04 STA &0431 ; unused # Unused variable &41ed 8d 34 04 STA &0434 ; new_life_cooldown &41f0 a9 ff LDA #&ff # First level has slowest attack frequency &41f2 8d fb 05 STA &05fb ; player_attack_frequency &41f5 8d 2e 04 STA &042e ; suppress_sound_status # Set to non-zero to display sound status &41f8 a9 00 LDA #&00 &41fa 8d fa 05 STA &05fa ; player_maximum_size_of_regular_attack_minus_one &41fd 20 7e 49 JSR &497e ; plot_rank &4200 a9 5a LDA #&5a # Wait 90 frames to start life &4202 8d 34 04 STA &0434 ; new_life_cooldown &4205 a9 ff LDA #&ff &4207 8d 0c 04 STA &040c ; number_of_active_enemies &420a ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &420d f0 08 BEQ &4217 ; skip_writing_game_start_and_player &420f a9 03 LDA #&03 ; "Game Start" &4211 20 32 43 JSR &4332 ; write_string &4214 20 58 4b JSR &4b58 ; write_current_player ; skip_writing_game_start_and_player &4217 20 18 37 JSR &3718 ; plot_lives &421a a9 ff LDA #&ff &421c 8d 0c 04 STA &040c ; number_of_active_enemies ; start_wave &421f a9 34 LDA #&34 &4221 8d 28 05 STA &0528 ; background_sound_tempo &4224 a2 00 LDX #&00 &4226 8e 1c 04 STX &041c ; end_of_wave_cooldown # Set to zero to indicate not end of wave &4229 8e 2d 04 STX &042d ; background_sound_start_cooldown &422c e8 INX ; 1 &422d 8e 29 05 STX &0529 ; background_sound_cooldown &4230 e8 INX ; 2 &4231 8e 2a 05 STX &052a ; background_sound_pitch &4234 ad fa 05 LDA &05fa ; player_maximum_size_of_regular_attack_minus_one &4237 8d 44 04 STA &0444 ; maximum_size_of_regular_attack_minus_one &423a ad fb 05 LDA &05fb ; player_attack_frequency &423d 8d 43 04 STA &0443 ; attack_frequency &4240 ad fc 05 LDA &05fc ; player_lives &4243 8d 22 04 STA &0422 ; lives # Copy is never modified &4246 ad fd 05 LDA &05fd ; player_level &4249 8d 20 04 STA &0420 ; level &424c ad fe 05 LDA &05fe ; player_rank &424f 8d 21 04 STA &0421 ; rank # Copy is never modified &4252 ad ff 05 LDA &05ff ; player_leaders_to_remove_minus_one &4255 8d 24 04 STA &0424 ; leaders_to_remove_minus_one &4258 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &425b f0 13 BEQ &4270 ; skip_adjusting_level &425d ae 20 04 LDX &0420 ; level &4260 e8 INX # Increase level number &4261 8a TXA &4262 29 0f AND #&0f &4264 c9 0a CMP #&0a &4266 8a TXA &4267 90 04 BCC &426d ; skip_overflow &4269 18 CLC &426a 8a TXA &426b 69 06 ADC #&06 # Level number is stored as BCD ; skip_overflow &426d 8d 20 04 STA &0420 ; level ; skip_adjusting_level &4270 a9 31 LDA #&31 &4272 8d 11 05 STA &0511 ; rightmost_enemy_slot &4275 a9 00 LDA #&00 &4277 8d 10 05 STA &0510 ; leftmost_enemy_slot &427a 8d 0e 04 STA &040e ; size_and_direction_of_attack &427d ad 43 04 LDA &0443 ; attack_frequency &4280 38 SEC &4281 e9 1e SBC #&1e # Enemies attack more frequently on later levels &4283 c9 50 CMP #&50 &4285 b0 08 BCS &428f ; set_attack_frequency &4287 69 16 ADC #&16 &4289 c9 e6 CMP #&e6 &428b 90 02 BCC &428f ; set_attack_frequency # Always branches &428d a9 64 LDA #&64 # Unnecessary floor ; set_attack_frequency &428f 8d 43 04 STA &0443 ; attack_frequency &4292 a9 06 LDA #&06 &4294 8d 26 04 STA &0426 ; delay_before_homing &4297 ee 44 04 INC &0444 ; maximum_size_of_regular_attack_minus_one &429a ad 44 04 LDA &0444 ; maximum_size_of_regular_attack_minus_one &429d a0 83 LDY #&83 ; ATTACK_RIGHT | 3 &429f c9 04 CMP #&04 &42a1 90 02 BCC &42a5 ; set_attack_direction_and_size_mask &42a3 a0 87 LDY #&87 ; ATTACK_RIGHT | 7 ; set_attack_direction_and_size_mask &42a5 8c 47 04 STY &0447 ; attack_direction_and_size_mask &42a8 c9 06 CMP #&06 &42aa 90 03 BCC &42af ; skip_ceiling &42ac ce 44 04 DEC &0444 ; maximum_size_of_regular_attack_minus_one ; skip_ceiling &42af 20 7b 39 JSR &397b ; initialise_active_enemies_and_enemy_bombs &42b2 a0 32 LDY #&32 ; ENEMY_LAST_PASSIVE + 1 &42b4 8c 01 05 STY &0501 ; number_of_enemies &42b7 8c 0d 04 STY &040d ; number_of_passive_enemies &42ba 88 DEY &42bb 8c 00 05 STY &0500 ; passive_enemy_to_update ; initialise_passive_enemies_loop &42be b9 c2 1d LDA &1dc2,Y ; initial_passive_enemies_group &42c1 99 c8 05 STA &05c8,Y ; passive_enemies_group &42c4 b9 2c 1d LDA &1d2c,Y ; initial_passive_enemies_sprite_address_high &42c7 99 32 05 STA &0532,Y ; passive_enemies_sprite_address_high &42ca b9 5e 1d LDA &1d5e,Y ; initial_passive_enemies_screen_address_low &42cd 99 64 05 STA &0564,Y ; passive_enemies_screen_address_low &42d0 b9 90 1d LDA &1d90,Y ; initial_passive_enemies_screen_address_high &42d3 99 96 05 STA &0596,Y ; passive_enemies_screen_address_high &42d6 88 DEY &42d7 10 e5 BPL &42be ; initialise_passive_enemies_loop &42d9 a9 06 LDA #&06 &42db 8d c8 05 STA &05c8 ; passive_enemies_group # Unnecessary code; same value as set at &42c1 &42de ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &42e1 f0 03 BEQ &42e6 ; skip_setting_previous_score_offset &42e3 8d 37 04 STA &0437 ; previous_score_offset # Set to non-zero for use at &4ef0 ; skip_setting_previous_score_offset &42e6 ad 44 04 LDA &0444 ; maximum_size_of_regular_attack_minus_one &42e9 8d fa 05 STA &05fa ; player_maximum_size_of_regular_attack_minus_one &42ec ad 43 04 LDA &0443 ; attack_frequency &42ef 8d fb 05 STA &05fb ; player_attack_frequency &42f2 ad 22 04 LDA &0422 ; lives &42f5 8d fc 05 STA &05fc ; player_lives &42f8 ad 20 04 LDA &0420 ; level &42fb 8d fd 05 STA &05fd ; player_level &42fe ad 21 04 LDA &0421 ; rank &4301 8d fe 05 STA &05fe ; player_rank &4304 ad 24 04 LDA &0424 ; leaders_to_remove_minus_one &4307 8d ff 05 STA &05ff ; player_leaders_to_remove_minus_one &430a 20 47 37 JSR &3747 ; plot_level_flags_and_sound_status &430d 20 54 3b JSR &3b54 ; remove_absent_leaders &4310 a9 03 LDA #&03 &4312 8d ff 05 STA &05ff ; player_leaders_to_remove_minus_one &4315 20 73 38 JSR &3873 ; reset_passive_enemy_to_update_and_maximum_and_minimum_enemy_x &4318 20 ba 36 JSR &36ba ; use_move_passive_enemy_right &431b a9 00 LDA #&00 ; envelope_0 # Use game envelopes &431d 20 ba 4a JSR &4aba ; define_envelope &4320 a9 01 LDA #&01 ; envelope_1 &4322 20 ba 4a JSR &4aba ; define_envelope &4325 a9 02 LDA #&02 ; envelope_2 &4327 20 ba 4a JSR &4aba ; define_envelope &432a a9 03 LDA #&03 ; envelope_3 &432c 20 ba 4a JSR &4aba ; define_envelope &432f 4c 5d 41 JMP &415d ; main_game_loop ; write_string &4332 aa TAX &4333 bd df 2d LDA &2ddf,X ; string_addresses_low &4336 85 72 STA &72 ; string_address_low &4338 bd fb 2d LDA &2dfb,X ; string_addresses_high &433b 85 73 STA &73 ; string_address_high &433d e8 INX &433e bd df 2d LDA &2ddf,X ; string_addresses_low &4341 85 70 STA &70 ; string_end_address_low &4343 bd fb 2d LDA &2dfb,X ; string_addresses_high &4346 85 71 STA &71 ; string_end_address_high ; write_string_loop &4348 a0 00 LDY #&00 &434a b1 72 LDA (&72),Y ; string_address &434c 20 ee ff JSR &ffee ; OSWRCH &434f e6 72 INC &72 ; string_address_low &4351 d0 02 BNE &4355 ; skip_page &4353 e6 73 INC &73 ; string_address_high ; skip_page &4355 a5 72 LDA &72 ; string_address_low &4357 c5 70 CMP &70 ; string_end_address_low &4359 a5 73 LDA &73 ; string_address_high &435b e5 71 SBC &71 ; string_end_address_high &435d 90 e9 BCC &4348 ; write_string_loop &435f 60 RTS ; move_down_a_pixel &4360 e6 70 INC &70 ; screen_address_low &4362 d0 02 BNE &4366 ; skip_page &4364 e6 71 INC &71 ; screen_address_high ; skip_page &4366 a5 70 LDA &70 ; screen_address_low &4368 29 07 AND #&07 &436a d0 0f BNE &437b ; leave &436c e6 7b INC &7b ; group &436e a5 70 LDA &70 ; screen_address_low &4370 18 CLC &4371 69 38 ADC #&38 # Move down a group &4373 85 70 STA &70 ; screen_address_low &4375 a5 71 LDA &71 ; screen_address_high &4377 69 01 ADC #&01 &4379 85 71 STA &71 ; screen_address_high ; leave &437b 60 RTS ; check_for_collision_with_enemies &437c a9 00 LDA #&00 &437e 8d 1f 04 STA &041f ; explosion_is_active_group_leader &4381 20 8e 43 JSR &438e ; check_for_collision_with_attacking_enemies &4384 20 75 44 JSR &4475 ; check_for_collision_with_passive_enemies &4387 20 2f 45 JSR &452f ; check_for_collision_with_returning_enemies &438a 4c c6 50 JMP &50c6 ; check_for_collision_with_enemy_bombs ; leave &438d 60 RTS ; check_for_collision_with_attacking_enemies &438e a0 0a LDY #&0a ; check_for_collision_with_attacking_enemies_loop # For each attacking enemy, &4390 88 DEY &4391 30 fa BMI &438d ; leave &4393 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high # Is there an attacking enemy in this slot? &4396 f0 f8 BEQ &4390 ; check_for_collision_with_attacking_enemies_loop &4398 84 7c STY &7c ; enemy_to_check &439a b9 a0 07 LDA &07a0,Y ; attacking_enemies_screen_address_low &439d 29 07 AND #&07 &439f 85 71 STA &71 ; enemy_y &43a1 b9 d0 07 LDA &07d0,Y ; attacking_enemies_group &43a4 aa TAX &43a5 86 7a STX &7a ; enemy_group &43a7 0a ASL A &43a8 0a ASL A &43a9 0a ASL A &43aa 05 71 ORA &71 ; enemy_y &43ac 85 71 STA &71 ; enemy_y &43ae a5 75 LDA &75 ; collision_y &43b0 38 SEC &43b1 e5 71 SBC &71 ; enemy_y # Is there a vertical overlap? &43b3 90 db BCC &4390 ; check_for_collision_with_attacking_enemies_loop &43b5 c9 07 CMP #&07 &43b7 b0 d7 BCS &4390 ; check_for_collision_with_attacking_enemies_loop &43b9 85 71 STA &71 ; relative_y &43bb 0a ASL A # Multiply by three to get offset into sprite &43bc 65 71 ADC &71 ; relative_y &43be 85 71 STA &71 ; relative_y &43c0 b9 a0 07 LDA &07a0,Y ; attacking_enemies_screen_address_low &43c3 38 SEC &43c4 fd 00 1f SBC &1f00,X ; group_addresses_low &43c7 85 70 STA &70 ; enemy_x &43c9 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high &43cc fd 20 1f SBC &1f20,X ; group_addresses_high &43cf 4a LSR A &43d0 66 70 ROR &70 ; enemy_x &43d2 46 70 LSR &70 ; enemy_x &43d4 46 70 LSR &70 ; enemy_x &43d6 a5 74 LDA &74 ; collision_x &43d8 38 SEC &43d9 e5 70 SBC &70 ; enemy_x # Is there a horizontal overlap? &43db 90 b3 BCC &4390 ; check_for_collision_with_attacking_enemies_loop &43dd c9 03 CMP #&03 &43df b0 af BCS &4390 ; check_for_collision_with_attacking_enemies_loop &43e1 65 71 ADC &71 ; relative_y &43e3 48 PHA ; sprite offset &43e4 b9 80 07 LDA &0780,Y ; attacking_enemies_sprite_address_low &43e7 85 72 STA &72 ; sprite_address_low &43e9 b9 90 07 LDA &0790,Y ; attacking_enemies_sprite_address_high &43ec c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &43ee d0 02 BNE &43f2 ; skip_patching &43f0 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites ; skip_patching &43f2 85 73 STA &73 ; sprite_address_high &43f4 68 PLA ; sprite offset &43f5 a8 TAY &43f6 b1 72 LDA (&72),Y ; sprite_address # Get byte of sprite corresponding to collision &43f8 a4 7c LDY &7c ; enemy_to_check &43fa 25 78 AND &78 ; collision_pixel_value # Has the laser hit a non-black pixel? &43fc f0 92 BEQ &4390 ; check_for_collision_with_attacking_enemies_loop &43fe c0 07 CPY #&07 ; ENEMY_GROUP_LEADER + 1 &4400 f0 04 BEQ &4406 ; is_group_escort &4402 c0 08 CPY #&08 ; ENEMY_GROUP_LEADER + 2 &4404 d0 03 BNE &4409 ; not_group_escort ; is_group_escort &4406 ee 23 04 INC &0423 ; group_escorts_killed ; not_group_escort &4409 b9 90 07 LDA &0790,Y ; attacking_enemies_sprite_address_high &440c 29 03 AND #&03 &440e 18 CLC &440f 69 02 ADC #&02 # Score 40, 60 and 80 points for types 1, 2 and 3 &4411 0a ASL A &4412 c9 0a CMP #&0a &4414 90 1f BCC &4435 ; set_score_to_add # For type 4 enemies, &4416 c0 06 CPY #&06 ; ENEMY_GROUP_LEADER &4418 f0 09 BEQ &4423 ; is_group_leader &441a a9 01 LDA #&01 # Score 1000 points if not group leader &441c 8d 11 04 STA &0411 ; score_to_add + 1 &441f a9 00 LDA #&00 &4421 f0 12 BEQ &4435 ; set_score_to_add # Always branches ; is_group_leader &4423 ae 23 04 LDX &0423 ; group_escorts_killed &4426 bd cc 53 LDA &53cc,X ; group_leader_scoring_table # Score 150, 200 or 800 points for group leader &4429 8d 11 04 STA &0411 ; score_to_add + 1 &442c 8d 1f 04 STA &041f ; explosion_is_active_group_leader # Set to non-zero to indicate active group leader &442f e0 00 CPX #&00 &4431 d0 02 BNE &4435 ; set_score_to_add &4433 a9 05 LDA #&05 # Score 150 points for group leader if no escorts killed ; set_score_to_add &4435 8d 10 04 STA &0410 ; score_to_add &4438 20 f2 46 JSR &46f2 ; update_score &443b a4 7c LDY &7c ; enemy_to_check &443d ce 0c 04 DEC &040c ; number_of_active_enemies &4440 ce 01 05 DEC &0501 ; number_of_enemies &4443 b9 80 07 LDA &0780,Y ; attacking_enemies_sprite_address_low &4446 85 72 STA &72 ; sprite_address_low &4448 b9 90 07 LDA &0790,Y ; attacking_enemies_sprite_address_high &444b c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &444d d0 02 BNE &4451 ; skip_patching &444f a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites ; skip_patching &4451 85 73 STA &73 ; sprite_address_high &4453 b9 a0 07 LDA &07a0,Y ; attacking_enemies_screen_address_low &4456 85 70 STA &70 ; screen_address_low &4458 b9 b0 07 LDA &07b0,Y ; attacking_enemies_screen_address_high &445b 85 71 STA &71 ; screen_address_high &445d a9 00 LDA #&00 &445f 99 b0 07 STA &07b0,Y ; attacking_enemies_screen_address_high # Set to zero to indicate no attacking enemy &4462 b9 e0 07 LDA &07e0,Y ; attacking_enemies_passive_slot &4465 a8 TAY &4466 a9 ff LDA #&ff &4468 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set to &ff to indicate passive enemy not present &446b 4c 16 45 JMP &4516 ; explode_enemy ; unused # Unused code &446e 88 DEY &446f 30 03 BMI &4474 ; leave &4471 4c 90 43 JMP &4390 ; check_for_collision_with_attacking_enemies_loop ; leave &4474 60 RTS ; check_for_collision_with_passive_enemies &4475 a0 32 LDY #&32 ; ENEMY_LAST_PASSIVE + 1 ; check_for_collision_with_passive_enemies_loop # For each passive enemy, &4477 88 DEY &4478 30 fa BMI &4474 ; leave &447a be c8 05 LDX &05c8,Y ; passive_enemies_group # Top bit set if enemy active or not present &447d 30 f8 BMI &4477 ; check_for_collision_with_passive_enemies_loop &447f 84 7c STY &7c ; enemy_to_check &4481 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &4484 29 07 AND #&07 &4486 85 71 STA &71 ; enemy_y &4488 8a TXA &4489 85 7b STA &7b ; enemy_group &448b 0a ASL A &448c 0a ASL A &448d 0a ASL A &448e 05 71 ORA &71 ; enemy_y &4490 85 71 STA &71 ; enemy_y &4492 a5 75 LDA &75 ; collision_y &4494 38 SEC &4495 e5 71 SBC &71 ; enemy_y # Is there a vertical overlap? &4497 90 de BCC &4477 ; check_for_collision_with_passive_enemies_loop &4499 c9 07 CMP #&07 &449b b0 da BCS &4477 ; check_for_collision_with_passive_enemies_loop &449d 85 71 STA &71 ; relative_y &449f 0a ASL A # Multiply by three to get offset into sprite &44a0 18 CLC &44a1 65 71 ADC &71 ; relative_y &44a3 85 71 STA &71 ; relative_y &44a5 b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &44a8 38 SEC &44a9 fd 00 1f SBC &1f00,X ; group_addresses_low &44ac 85 70 STA &70 ; enemy_x &44ae b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &44b1 fd 20 1f SBC &1f20,X ; group_addresses_high &44b4 4a LSR A &44b5 66 70 ROR &70 ; enemy_x &44b7 46 70 LSR &70 ; enemy_x &44b9 46 70 LSR &70 ; enemy_x &44bb a5 74 LDA &74 ; collision_x &44bd 38 SEC &44be e5 70 SBC &70 ; enemy_x # Is there a horizontal overlap? &44c0 90 b5 BCC &4477 ; check_for_collision_with_passive_enemies_loop &44c2 c9 03 CMP #&03 &44c4 b0 b1 BCS &4477 ; check_for_collision_with_passive_enemies_loop &44c6 65 71 ADC &71 ; relative_y &44c8 48 PHA ; sprite offset &44c9 a9 00 LDA #&00 &44cb 85 72 STA &72 ; sprite_address_low &44cd b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &44d0 c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &44d2 d0 02 BNE &44d6 ; skip_patching &44d4 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites ; skip_patching &44d6 85 73 STA &73 ; sprite_address_high &44d8 68 PLA ; sprite offset &44d9 a8 TAY &44da b1 72 LDA (&72),Y ; sprite_address # Get byte of sprite corresponding to collision &44dc a4 7c LDY &7c ; enemy_to_check &44de 25 78 AND &78 ; collision_pixel_value # Has the laser hit a non-black pixel? &44e0 f0 51 BEQ &4533 ; check_for_collision_with_returning_enemies_loop &44e2 b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &44e5 29 03 AND #&03 &44e7 18 CLC &44e8 69 02 ADC #&02 # Score 20, 30, 40 and 50 points for types 1, 2, 3 and 4 &44ea 8d 10 04 STA &0410 ; score_to_add &44ed 20 f2 46 JSR &46f2 ; update_score &44f0 ce 01 05 DEC &0501 ; number_of_enemies &44f3 ce 0d 04 DEC &040d ; number_of_passive_enemies &44f6 a4 7c LDY &7c ; enemy_to_check &44f8 a9 ff LDA #&ff &44fa 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set to &ff to indicate passive enemy not present &44fd a9 00 LDA #&00 ; SPRITE_ROTATION_0 &44ff 85 72 STA &72 ; sprite_address_low &4501 b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &4504 c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &4506 d0 02 BNE &450a ; skip_patching &4508 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites ; skip_patching &450a 85 73 STA &73 ; sprite_address_high &450c b9 64 05 LDA &0564,Y ; passive_enemies_screen_address_low &450f 85 70 STA &70 ; screen_address_low &4511 b9 96 05 LDA &0596,Y ; passive_enemies_screen_address_high &4514 85 71 STA &71 ; screen_address_high ; explode_enemy &4516 20 ee 47 JSR &47ee ; add_explosion &4519 a9 00 LDA #&00 &451b 8d 1f 04 STA &041f ; explosion_is_active_group_leader # Set to zero to indicate not active group leader ; leave_collision_check &451e 68 PLA # Pull check_for_collision_with_passive_enemies or &451f 68 PLA # check_for_collision_with_attacking_enemies from stack &4520 ce 28 05 DEC &0528 ; background_sound_tempo &4523 ee 2a 05 INC &052a ; background_sound_pitch &4526 ee 2a 05 INC &052a ; background_sound_pitch &4529 a9 05 LDA #&05 ; sound_5 &452b 4c c8 4a JMP &4ac8 ; play_sound # i.e. don't check for further collisions ; leave &452e 60 RTS ; check_for_collision_with_returning_enemies &452f a0 0a LDY #&0a &4531 84 7c STY &7c ; enemy_to_check ; check_for_collision_with_returning_enemies_loop # For each returning enemy, &4533 c6 7c DEC &7c ; enemy_to_check &4535 30 f7 BMI &452e ; leave u &4537 a4 7c LDY &7c ; enemy_to_check &4539 b9 30 07 LDA &0730,Y ; returning_enemies_screen_address_high # Is there a returning enemy in this slot? &453c f0 f5 BEQ &4533 ; check_for_collision_with_returning_enemies_loop &453e b9 20 07 LDA &0720,Y ; returning_enemies_screen_address_low &4541 29 07 AND #&07 &4543 85 71 STA &71 ; enemy_y &4545 be 60 07 LDX &0760,Y ; returning_enemies_passive_slot &4548 bd c8 05 LDA &05c8,X ; passive_enemies_group &454b 29 1f AND #&1f &454d 38 SEC &454e f9 10 07 SBC &0710,Y ; returning_enemies_groups_to_return &4551 85 70 STA &70 ; group &4553 bd 64 05 LDA &0564,X ; passive_enemies_screen_address_low &4556 29 07 AND #&07 &4558 d9 00 07 CMP &0700,Y ; returning_enemies_row_in_group &455b b0 02 BCS &455f ; skip_dec &455d c6 70 DEC &70 ; group ; skip_dec &455f a6 70 LDX &70 ; group &4561 8a TXA &4562 85 7a STA &7a ; enemy_group &4564 0a ASL A &4565 0a ASL A &4566 0a ASL A &4567 05 71 ORA &71 ; enemy_y &4569 85 71 STA &71 ; enemy_y &456b a5 75 LDA &75 ; collision_y &456d 38 SEC &456e e5 71 SBC &71 ; enemy_y # Is there a vertical overlap? &4570 90 c1 BCC &4533 ; check_for_collision_with_returning_enemies_loop &4572 c9 07 CMP #&07 &4574 b0 bd BCS &4533 ; check_for_collision_with_returning_enemies_loop &4576 85 71 STA &71 ; relative_y &4578 0a ASL A # Multiply by three to get offset into sprite &4579 65 71 ADC &71 ; relative_y &457b 85 71 STA &71 ; relative_y &457d b9 20 07 LDA &0720,Y ; returning_enemies_screen_address_low &4580 38 SEC &4581 fd 00 1f SBC &1f00,X ; group_addresses_low &4584 85 70 STA &70 ; enemy_x &4586 b9 30 07 LDA &0730,Y ; returning_enemies_screen_address_high &4589 fd 20 1f SBC &1f20,X ; group_addresses_high &458c 4a LSR A &458d 66 70 ROR &70 ; enemy_x &458f 46 70 LSR &70 ; enemy_x &4591 46 70 LSR &70 ; enemy_x &4593 a5 74 LDA &74 ; collision_x &4595 38 SEC &4596 e5 70 SBC &70 ; enemy_x # Is there a horizontal overlap? &4598 90 99 BCC &4533 ; check_for_collision_with_returning_enemies_loop &459a c9 03 CMP #&03 &459c b0 95 BCS &4533 ; check_for_collision_with_returning_enemies_loop &459e 65 71 ADC &71 ; relative_y &45a0 48 PHA ; sprite offset &45a1 b9 50 07 LDA &0750,Y ; returning_enemies_sprite_address_high &45a4 c9 0d CMP #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites &45a6 d0 02 BNE &45aa ; skip_patching &45a8 a9 2a LDA #&2a ; &2a00 = enemy_type_1_shift_0_sprites ; skip_patching &45aa 85 73 STA &73 ; sprite_address_high &45ac b9 40 07 LDA &0740,Y ; returning_enemies_sprite_address_low &45af 85 72 STA &72 ; sprite_address_low &45b1 68 PLA ; sprite offset &45b2 a8 TAY &45b3 b1 72 LDA (&72),Y ; sprite_address # Get byte of sprite corresponding to collision &45b5 a4 7c LDY &7c ; enemy_to_check &45b7 25 78 AND &78 ; collision_pixel_value # Has the laser hit a non-black pixel? &45b9 d0 03 BNE &45be ; explode_returning_enemy &45bb 4c 33 45 JMP &4533 ; check_for_collision_with_returning_enemies_loop ; explode_returning_enemy &45be ce 0c 04 DEC &040c ; number_of_active_enemies &45c1 ce 01 05 DEC &0501 ; number_of_enemies &45c4 b9 20 07 LDA &0720,Y ; returning_enemies_screen_address_low &45c7 85 70 STA &70 ; screen_address_low &45c9 b9 30 07 LDA &0730,Y ; returning_enemies_screen_address_high &45cc 85 71 STA &71 ; screen_address_high &45ce a9 00 LDA #&00 &45d0 99 30 07 STA &0730,Y ; returning_enemies_screen_address_high # Set to zero to indicate enemy is no longer returning &45d3 b9 60 07 LDA &0760,Y ; returning_enemies_passive_slot &45d6 a8 TAY &45d7 48 PHA ; passive slot &45d8 a9 ff LDA #&ff &45da 99 c8 05 STA &05c8,Y ; passive_enemies_group # Set to &ff to indicate passive enemy not present &45dd 20 ee 47 JSR &47ee ; add_explosion &45e0 20 c5 33 JSR &33c5 ; unplot_enemy_sprite &45e3 68 PLA ; passive slot &45e4 a8 TAY &45e5 b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high &45e8 29 03 AND #&03 &45ea 18 CLC &45eb 69 02 ADC #&02 # Score 40, 60, 80 and 100 points for types 1, 2, 3 and 4 &45ed 0a ASL A &45ee c9 0a CMP #&0a &45f0 90 07 BCC &45f9 ; not_100 &45f2 a9 01 LDA #&01 &45f4 8d 11 04 STA &0411 ; score_to_add + 1 &45f7 a9 00 LDA #&00 ; not_100 &45f9 8d 10 04 STA &0410 ; score_to_add &45fc 20 f2 46 JSR &46f2 ; update_score &45ff 4c 1e 45 JMP &451e ; leave_collision_check ; leave &4602 60 RTS ; update_enemy_bombs &4603 a0 10 LDY #&10 &4605 84 7c STY &7c ; bomb_to_update ; update_enemy_bombs_loop # For each enemy bomb, &4607 c6 7c DEC &7c ; bomb_to_update &4609 30 f7 BMI &4602 ; leave &460b a4 7c LDY &7c ; bomb_to_update &460d b9 a0 04 LDA &04a0,Y ; enemy_bombs_pixel_value &4610 f0 f5 BEQ &4607 ; update_enemy_bombs_loop # Zero if no bomb in slot &4612 85 74 STA &74 ; bomb_pixel_value &4614 b9 80 04 LDA &0480,Y ; enemy_bombs_screen_address_low &4617 85 70 STA &70 ; screen_address_low &4619 b9 90 04 LDA &0490,Y ; enemy_bombs_screen_address_high &461c 85 71 STA &71 ; screen_address_high &461e b9 b0 04 LDA &04b0,Y ; enemy_bombs_group &4621 85 7b STA &7b ; group &4623 20 60 43 JSR &4360 ; move_down_a_pixel &4626 20 47 46 JSR &4647 ; update_enemy_bomb &4629 20 60 43 JSR &4360 ; move_down_a_pixel &462c 20 47 46 JSR &4647 ; update_enemy_bomb &462f 20 60 43 JSR &4360 ; move_down_a_pixel &4632 a5 70 LDA &70 ; screen_address_low &4634 99 80 04 STA &0480,Y ; enemy_bombs_screen_address_low &4637 a5 71 LDA &71 ; screen_address_high &4639 99 90 04 STA &0490,Y ; enemy_bombs_screen_address_high &463c a5 7b LDA &7b ; group &463e 99 b0 04 STA &04b0,Y ; enemy_bombs_group &4641 20 47 46 JSR &4647 ; update_enemy_bomb &4644 4c 07 46 JMP &4607 ; update_enemy_bombs_loop ; update_enemy_bomb &4647 a5 70 LDA &70 ; screen_address_low &4649 c9 c0 CMP #&c0 ; &7ec0 = group &1d &464b a5 71 LDA &71 ; screen_address_high &464d e9 7e SBC #&7e &464f 90 0a BCC &465b ; replot_bomb # Has the bomb reached the bottom of the game area? ; remove_bomb_at_bottom_of_screen &4651 a9 00 LDA #&00 &4653 99 a0 04 STA &04a0,Y ; enemy_bombs_pixel_value # Set to zero to indicate no bomb in slot &4656 68 PLA # Leave update_enemy_bombs on return &4657 68 PLA &4658 4c 07 46 JMP &4607 ; update_enemy_bombs_loop # Don't update this bomb further; consider next bomb ; replot_bomb &465b a0 00 LDY #&00 &465d a5 74 LDA &74 ; bomb_pixel_value &465f 49 ff EOR #&ff &4661 31 70 AND (&70),Y ; screen_address # Unplot pixel at top of bomb &4663 91 70 STA (&70),Y ; screen_address &4665 a5 70 LDA &70 ; screen_address_low &4667 85 72 STA &72 ; new_screen_address_low &4669 a5 71 LDA &71 ; screen_address_high &466b 85 73 STA &73 ; new_screen_address_high &466d a5 70 LDA &70 ; screen_address_low &466f 29 07 AND #&07 &4671 c9 03 CMP #&03 &4673 90 0d BCC &4682 ; not_group &4675 a5 70 LDA &70 ; screen_address_low &4677 18 CLC &4678 69 38 ADC #&38 # Move down a group &467a 85 72 STA &72 ; new_screen_address_low &467c a5 71 LDA &71 ; screen_address_high &467e 69 01 ADC #&01 &4680 85 73 STA &73 ; new_screen_address_high ; not_group &4682 a5 72 LDA &72 ; new_screen_address_low &4684 18 CLC &4685 69 05 ADC #&05 &4687 85 72 STA &72 ; new_screen_address_low &4689 90 02 BCC &468d ; skip_page &468b e6 73 INC &73 ; new_screen_address_high ; skip_page &468d c9 c0 CMP #&c0 ; &7ec0 = group &1d &468f a5 73 LDA &73 ; new_screen_address_high &4691 e9 7e SBC #&7e &4693 b0 06 BCS &469b ; leave_with_bomb_to_update # Don't plot beyond bottom of game area &4695 b1 72 LDA (&72),Y ; new_screen_address &4697 05 74 ORA &74 ; bomb_pixel_value # Plot pixel at bottom of bomb &4699 91 72 STA (&72),Y ; new_screen_address ; leave_with_bomb_to_update &469b a4 7c LDY &7c ; bomb_to_update &469d 60 RTS ; tab_to_player_score &469e ac 46 04 LDY &0446 ; player_score_offset # Zero if demo, &50 for player one, &58 for player two &46a1 f0 15 BEQ &46b8 ; leave &46a3 a9 1f LDA #&1f # TAB(&00, &01) or TAB(&0f, &01) &46a5 20 ee ff JSR &ffee ; OSWRCH &46a8 a9 00 LDA #&00 &46aa c0 58 CPY #&58 &46ac d0 02 BNE &46b0 ; is_player_one ; is_player_two &46ae a9 0f LDA #&0f ; is_player_one &46b0 20 ee ff JSR &ffee ; OSWRCH &46b3 a9 01 LDA #&01 &46b5 4c ee ff JMP &ffee ; OSWRCH ; leave &46b8 60 RTS ; consider_writing_zero &46b9 28 PLP ; digit is zero &46ba d0 fc BNE &46b8 ; leave # If no digits were written, &46bc a9 08 LDA #&08 ; move cursor left one character &46be 20 ee ff JSR &ffee ; OSWRCH &46c1 a9 30 LDA #&30 ; "0" &46c3 4c ee ff JMP &ffee ; OSWRCH # Write a single "0" ; plot_score &46c6 a0 03 LDY #&03 # Scores have four digits plus trailing zero &46c8 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &46cb f0 eb BEQ &46b8 ; leave ; write_number &46cd b1 70 LDA (&70),Y ; number_address &46cf 08 PHP ; digit is zero &46d0 d0 02 BNE &46d4 ; not_zero &46d2 a9 f0 LDA #&f0 ; " " - "0" ; not_zero &46d4 18 CLC &46d5 69 30 ADC #&30 ; "0" &46d7 20 ee ff JSR &ffee ; OSWRCH # Write digit or leading space &46da 88 DEY &46db 30 dc BMI &46b9 ; consider_writing_zero # Continue until end of number &46dd 28 PLP ; digit is zero &46de f0 ed BEQ &46cd ; write_number # or non-zero digit ; write_number_loop &46e0 b1 70 LDA (&70),Y ; number_address &46e2 18 CLC &46e3 69 30 ADC #&30 ; "0" &46e5 20 ee ff JSR &ffee ; OSWRCH # Write remaining digits &46e8 88 DEY &46e9 10 f5 BPL &46e0 ; write_number_loop &46eb 4c 6c 47 JMP &476c ; initialise_score_to_add ; unused # Unused code &46ee 28 PLP &46ef 4c 6c 47 JMP &476c ; initialise_score_to_add ; update_score &46f2 ac 46 04 LDY &0446 ; player_score_offset # Zero if demo, &50 for player one, &58 for player two &46f5 d0 01 BNE &46f8 ; not_demo &46f7 60 RTS ; not_demo &46f8 b9 02 04 LDA &0402,Y ; player_score - &50 + 2 &46fb 85 52 STA &52 ; previous_score_thousands &46fd 20 9e 46 JSR &469e ; tab_to_player_score # Returns Y = player_score_offset &4700 a9 04 LDA #&04 ; &0450 = player_score &4702 85 71 STA &71 ; number_address_high &4704 84 70 STY &70 ; number_address_low &4706 a0 00 LDY #&00 &4708 18 CLC &4709 08 PHP ; overflowed ; update_score_loop &470a 28 PLP ; overflowed &470b b1 70 LDA (&70),Y ; number_address &470d 79 10 04 ADC &0410,Y ; score_to_add &4710 c9 0a CMP #&0a &4712 08 PHP ; overflowed &4713 90 03 BCC &4718 ; skip_overflow &4715 38 SEC &4716 e9 0a SBC #&0a ; skip_overflow &4718 91 70 STA (&70),Y ; number_address &471a c8 INY &471b c0 08 CPY #&08 &471d d0 eb BNE &470a ; update_score_loop &471f 28 PLP ; overflowed &4720 ac 46 04 LDY &0446 ; player_score_offset # Zero if demo, &50 for player one, &58 for player two &4723 b9 07 04 LDA &0407,Y ; player_score - &50 + 7 &4726 19 06 04 ORA &0406,Y ; player_score - &50 + 6 &4729 19 05 04 ORA &0405,Y ; player_score - &50 + 5 &472c 19 04 04 ORA &0404,Y ; player_score - &50 + 4 &472f 19 03 04 ORA &0403,Y ; player_score - &50 + 3 &4732 d0 28 BNE &475c ; skip_extra_life &4734 be 02 04 LDX &0402,Y ; player_score - &50 + 2 &4737 ca DEX &4738 e0 06 CPX #&06 # Extra life at 5000 points &473a d0 20 BNE &475c ; skip_extra_life &473c e4 52 CPX &52 ; previous_score_thousands &473e d0 1c BNE &475c ; skip_extra_life &4740 a9 09 LDA #&09 ; sound_9 &4742 20 c8 4a JSR &4ac8 ; play_sound # Play sound for extra life &4745 a9 14 LDA #&14 &4747 8d 2d 04 STA &042d ; background_sound_start_cooldown &474a ee fc 05 INC &05fc ; player_lives &474d a5 70 LDA &70 ; number_address_low &474f 48 PHA ; number_address_low &4750 a5 71 LDA &71 ; number_address_high &4752 48 PHA ; number_address_high &4753 20 18 37 JSR &3718 ; plot_lives &4756 68 PLA ; number_address_high &4757 85 71 STA &71 ; number_address_high &4759 68 PLA ; number_address_low &475a 85 70 STA &70 ; number_address_low ; skip_extra_life &475c 20 c6 46 JSR &46c6 ; plot_score &475f 4c a7 49 JMP &49a7 ; check_for_new_rank ; initialise_player_score &4762 a2 0f LDX #&0f &4764 a9 00 LDA #&00 ; initialise_player_score_loop &4766 9d 50 04 STA &0450,X ; player_score # Wipe &0450 - &045f, i.e. both players' score &4769 ca DEX &476a 10 fa BPL &4766 ; initialise_player_score_loop ; initialise_score_to_add &476c a2 07 LDX #&07 &476e a9 00 LDA #&00 ; initialise_score_to_add_loop &4770 9d 10 04 STA &0410,X ; score_to_add &4773 ca DEX &4774 10 fa BPL &4770 ; initialise_score_to_add_loop &4776 60 RTS ; plot_high_score &4777 a9 1f LDA #&1f # TAB(&05, &01) &4779 20 ee ff JSR &ffee ; OSWRCH &477c a9 05 LDA #&05 &477e 20 ee ff JSR &ffee ; OSWRCH &4781 a9 01 LDA #&01 &4783 20 ee ff JSR &ffee ; OSWRCH &4786 a9 00 LDA #&00 &4788 85 70 STA &70 ; number_address_low &478a a9 27 LDA #&27 ; &2700 = high_scores &478c 85 71 STA &71 ; number_address_high &478e a0 05 LDY #&05 &4790 4c cd 46 JMP &46cd ; write_number # Write high score as six digit number plus trailing zero ; unused # Unused code &4793 20 6c 47 JSR &476c ; initialise_score_to_add &4796 b9 32 05 LDA &0532,Y ; passive_enemies_sprite_address_high # &4797 - &479d is a copy of &44e2 - &44e9 &4799 29 03 AND #&03 &479b 18 CLC &479c 69 02 ADC #&02 &479e 60 RTS ; update_explosions &479f a2 03 LDX #&03 ; update_explosions_loop # For each explosion, &47a1 bd 74 07 LDA &0774,X ; explosions_screen_address_high &47a4 f0 2a BEQ &47d0 ; consider_next_explosion # Is there an explosion in this slot? &47a6 85 71 STA &71 ; screen_address_high &47a8 bd 70 07 LDA &0770,X ; explosions_screen_address_low &47ab 85 70 STA &70 ; screen_address_low &47ad bd 7c 07 LDA &077c,X ; explosions_sprite_address_high &47b0 85 73 STA &73 ; sprite_address_high &47b2 86 7b STX &7b ; explosion_to_update &47b4 bd 78 07 LDA &0778,X ; explosions_sprite_address_low &47b7 85 72 STA &72 ; sprite_address_low &47b9 c9 a8 CMP #&a8 ; SPRITE_SCORE_150 &47bb b0 17 BCS &47d4 ; is_score_sprite # Is this a regular explosion? &47bd 69 15 ADC #&15 ; SPRITE_SIZE # If so, move to next frame of explosion &47bf 9d 78 07 STA &0778,X ; explosions_sprite_address_low &47c2 c9 a8 CMP #&a8 ; SPRITE_SCORE_150 &47c4 90 05 BCC &47cb ; skip_removing_explosion # Is this the end of the animation? &47c6 a9 00 LDA #&00 &47c8 9d 74 07 STA &0774,X ; explosions_screen_address_high # If so, set to zero to remove explosion ; skip_removing_explosion &47cb 20 7d 34 JSR &347d ; plot_enemy_sprite_with_overwrite &47ce a6 7b LDX &7b ; explosion_to_update ; consider_next_explosion &47d0 ca DEX &47d1 10 ce BPL &47a1 ; update_explosions_loop &47d3 60 RTS ; is_score_sprite # If this is a 150, 200 or 800 score, &47d4 c9 d2 CMP #&d2 ; SPRITE_SCORE_800 &47d6 90 05 BCC &47dd ; skip_animation &47d8 49 35 EOR #&35 ; SPRITE_SCORE_800_TWO ^ SPRITE_SCORE_800 &47da 9d 78 07 STA &0778,X ; explosions_sprite_address_low # Animate 800 score ; skip_animation &47dd a9 00 LDA #&00 &47df de 4c 04 DEC &044c,X ; explosions_timer &47e2 10 07 BPL &47eb ; to_skip_removing_explosion &47e4 9d 74 07 STA &0774,X ; explosions_screen_address_high # Set to zero to remove explosion &47e7 a9 93 LDA #&93 ; SPRITE_EXPLOSION_LAST &47e9 85 72 STA &72 ; sprite_address_low # Unplot score sprite ; to_skip_removing_explosion &47eb 4c cb 47 JMP &47cb ; skip_removing_explosion ; add_explosion &47ee a2 04 LDX #&04 ; find_free_slot_loop &47f0 ca DEX &47f1 30 40 BMI &4833 ; leave &47f3 bd 74 07 LDA &0774,X ; explosions_screen_address_high &47f6 d0 f8 BNE &47f0 ; find_free_slot_loop &47f8 a5 70 LDA &70 ; screen_address_low &47fa 9d 70 07 STA &0770,X ; explosions_screen_address_low &47fd a5 71 LDA &71 ; screen_address_high &47ff 9d 74 07 STA &0774,X ; explosions_screen_address_high &4802 a9 20 LDA #&20 # Score explosions last for 32 frames &4804 9d 4c 04 STA &044c,X ; explosions_timer &4807 a9 00 LDA #&00 ; SPRITE_EXPLOSION &4809 ac 1f 04 LDY &041f ; explosion_is_active_group_leader # Non-zero if active group leader is exploding &480c f0 0f BEQ &481d ; set_sprite_address_low ; is_active_group_leader &480e a9 a8 LDA #&a8 ; SPRITE_SCORE_150 &4810 ac 23 04 LDY &0423 ; group_escorts_killed &4813 f0 08 BEQ &481d ; set_sprite_address_low &4815 a9 d2 LDA #&d2 ; SPRITE_SCORE_800 &4817 c0 02 CPY #&02 &4819 f0 02 BEQ &481d ; set_sprite_address_low &481b a9 bd LDA #&bd ; SPRITE_SCORE_200 ; set_sprite_address_low &481d 9d 78 07 STA &0778,X ; explosions_sprite_address_low &4820 a5 73 LDA &73 ; sprite_address_high &4822 c9 2a CMP #&2a ; &2a00 = enemy_type_1_shift_0_sprites &4824 d0 02 BNE &4828 ; skip_unpatching &4826 a9 0d LDA #&0d ; &0d00 = unused_enemy_type_1_shift_0_sprites ; skip_unpatching &4828 38 SEC &4829 e9 0c SBC #&0c ; &0c00 = enemy_type_0_shift_0_sprites # Use enemy shift to set explosion shift &482b 4a LSR A &482c 4a LSR A &482d 18 CLC &482e 69 20 ADC #&20 ; &2000 = explosion_shift_0_sprites &4830 9d 7c 07 STA &077c,X ; explosions_sprite_address_high ; leave &4833 60 RTS ; check_for_high_score &4834 a9 7d LDA #&7d ; Set ESCAPE condition &4836 20 f4 ff JSR &fff4 ; OSBYTE &4839 a9 7e LDA #&7e ; Acknowledge ESCAPE condition &483b 20 f4 ff JSR &fff4 ; OSBYTE &483e ac fe 05 LDY &05fe ; player_rank &4841 c0 1e CPY #&1e ; 30 &4843 d0 01 BNE &4846 ; is_high_score &4845 60 RTS ; is_high_score &4846 88 DEY &4847 98 TYA &4848 0a ASL A &4849 0a ASL A &484a 0a ASL A &484b 85 74 STA &74 ; high_score_offset &484d a0 f7 LDY #&f7 ; shuffle_high_scores_loop &484f b9 00 27 LDA &2700,Y ; high_scores # Move all scores below player down a rank &4852 99 08 27 STA &2708,Y ; high_scores + 8 &4855 88 DEY &4856 c4 74 CPY &74 ; high_score_offset &4858 d0 f5 BNE &484f ; shuffle_high_scores_loop &485a b9 00 27 LDA &2700,Y ; high_scores &485d 99 08 27 STA &2708,Y ; high_scores + 8 &4860 a6 74 LDX &74 ; high_score_offset &4862 ac 46 04 LDY &0446 ; player_score_offset # &50 for player one, &58 for player two &4865 a9 08 LDA #&08 &4867 85 74 STA &74 ; count ; copy_player_score_loop &4869 b9 00 04 LDA &0400,Y ; player_score - &50 # Copy player score into rank score &486c 9d 00 27 STA &2700,X ; high_scores &486f c8 INY &4870 e8 INX &4871 c6 74 DEC &74 ; count &4873 d0 f4 BNE &4869 ; copy_player_score_loop &4875 ac fe 05 LDY &05fe ; player_rank &4878 c0 0b CPY #&0b &487a 90 01 BCC &487d ; is_top_ten &487c 60 RTS ; is_top_ten &487d 88 DEY &487e 98 TYA &487f 85 70 STA &70 ; tmp &4881 0a ASL A &4882 0a ASL A &4883 0a ASL A &4884 aa TAX &4885 65 70 ADC &70 ; tmp &4887 85 70 STA &70 ; tmp &4889 8a TXA &488a 0a ASL A &488b 65 70 ADC &70 ; tmp &488d 85 74 STA &74 ; name_offset &488f c0 09 CPY #&09 &4891 f0 13 BEQ &48a6 ; skip_shuffling_names &4893 a0 e0 LDY #&e0 ; shuffle_names_loop &4895 b9 00 28 LDA &2800,Y ; high_score_names # Move all names below player down a rank &4898 99 19 28 STA &2819,Y ; high_score_names + &19 &489b 88 DEY &489c c4 74 CPY &74 ; name_offset &489e d0 f5 BNE &4895 ; shuffle_names_loop &48a0 b9 00 28 LDA &2800,Y ; high_score_names &48a3 99 19 28 STA &2819,Y ; high_score_names + &19 ; skip_shuffling_names &48a6 a5 74 LDA &74 ; name_offset &48a8 48 PHA ; name_offset ; call_set_shiftlock &48a9 20 b8 50 JSR &50b8 ; set_shiftlock # or JSR &50c1 ; set_shiftlock_mos_0.10 if MOS 0.10 &48ac a9 0d LDA #&0d ; CR &48ae 20 ee ff JSR &ffee ; OSWRCH &48b1 a9 20 LDA #&20 ; " " &48b3 20 ee ff JSR &ffee ; OSWRCH &48b6 a9 0d LDA #&0d ; CR &48b8 20 ee ff JSR &ffee ; OSWRCH &48bb a9 05 LDA #&05 # Change to MODE 7 and set up high score screen &48bd 20 32 43 JSR &4332 ; write_string &48c0 20 58 4b JSR &4b58 ; write_current_player &48c3 a9 0f LDA #&0f ; TAB(&11, &0c) &48c5 20 32 43 JSR &4332 ; write_string &48c8 a9 04 LDA #&04 ; &0450 = player_score &48ca 85 71 STA &71 ; number_address_high &48cc ad 46 04 LDA &0446 ; player_score_offset # &50 for player one, &58 for player two &48cf 85 70 STA &70 ; number_address_low &48d1 20 c6 46 JSR &46c6 ; plot_score &48d4 a9 10 LDA #&10 ; "0 was ranked " &48d6 20 32 43 JSR &4332 ; write_string &48d9 20 89 49 JSR &4989 ; plot_rank_without_tab &48dc a9 06 LDA #&06 ; TAB(&08, &12) &48de 20 32 43 JSR &4332 ; write_string &48e1 a9 28 LDA #&28 ; &2800 = high_score_names &48e3 85 71 STA &71 ; name_address_high &48e5 68 PLA ; name_offset &48e6 85 70 STA &70 ; name_address_low &48e8 a9 0f LDA #&0f ; Flush buffer &48ea a2 01 LDX #&01 ; input buffer &48ec 20 f4 ff JSR &fff4 ; OSBYTE &48ef a9 0c LDA #&0c ; Set auto-repeat period &48f1 a2 00 LDX #&00 &48f3 20 f4 ff JSR &fff4 ; OSBYTE &48f6 a9 04 LDA #&04 ; Define action of cursor editing keys &48f8 a2 00 LDX #&00 ; Cursor keys have editing effect &48fa 20 f4 ff JSR &fff4 ; OSBYTE &48fd a0 00 LDY #&00 ; enter_name_loop &48ff 20 e0 ff JSR &ffe0 ; OSRDCH &4902 c9 1b CMP #&1b : ESCAPE &4904 f0 3f BEQ &4945 ; escape_pressed &4906 c9 15 CMP #&15 ; ctrl-U &4908 f0 44 BEQ &494e ; clear_line &490a c9 0d CMP #&0d ; CR &490c f0 5b BEQ &4969 ; return_pressed &490e c9 20 CMP #&20 ; " " &4910 90 ed BCC &48ff ; enter_name_loop &4912 c9 7f CMP #&7f ; DELETE &4914 f0 16 BEQ &492c ; delete_pressed &4916 b0 e7 BCS &48ff ; enter_name_loop &4918 c0 18 CPY #&18 &491a b0 08 BCS &4924 ; end_of_line &491c 20 ee ff JSR &ffee ; OSWRCH &491f 91 70 STA (&70),Y ; name_address &4921 c8 INY &4922 d0 db BNE &48ff ; enter_name_loop # Always branches ; end_of_line &4924 a9 07 LDA #&07 ; BELL &4926 20 ee ff JSR &ffee ; OSWRCH &4929 4c ff 48 JMP &48ff ; enter_name_loop ; delete_pressed &492c 98 TYA &492d d0 03 BNE &4932 ; delete_character &492f 4c ff 48 JMP &48ff ; enter_name_loop ; delete_character &4932 a9 08 LDA #&08 ; BACKSPACE &4934 20 ee ff JSR &ffee ; OSWRCH &4937 a9 20 LDA #&20 ; " " &4939 20 ee ff JSR &ffee ; OSWRCH &493c a9 08 LDA #&08 ; BACKSPACE &493e 20 ee ff JSR &ffee ; OSWRCH &4941 88 DEY &4942 4c ff 48 JMP &48ff ; enter_name_loop ; escape_pressed &4945 98 TYA &4946 48 PHA ; tmp_y &4947 a9 7e LDA #&7e ; Acknowledge ESCAPE condition &4949 20 f4 ff JSR &fff4 ; OSBYTE &494c 68 PLA ; tmp_y &494d a8 TAY ; clear_line &494e a9 08 LDA #&08 ; BACKSPACE &4950 20 ee ff JSR &ffee ; OSWRCH &4953 a9 20 LDA #&20 ; " " &4955 20 ee ff JSR &ffee ; OSWRCH &4958 a9 08 LDA #&08 ; BACKSPACE &495a 20 ee ff JSR &ffee ; OSWRCH &495d 88 DEY &495e 10 ee BPL &494e ; clear_line &4960 c8 INY &4961 a9 85 LDA #&85 ; TELETEXT_MAGENTA &4963 20 ee ff JSR &ffee ; OSWRCH &4966 4c ff 48 JMP &48ff ; enter_name_loop ; return_pressed &4969 a9 0d LDA #&0d ; CR &496b 91 70 STA (&70),Y ; name_address &496d 20 ee ff JSR &ffee ; OSWRCH &4970 a9 0b LDA #&0b ; Set auto-repeat delay &4972 a2 00 LDX #&00 &4974 20 f4 ff JSR &fff4 ; OSBYTE &4977 a9 04 LDA #&04 ; Define action of cursor editing keys &4979 a2 01 LDX #&01 ; Cursor keys return ASCII values 135-139 &497b 4c f4 ff JMP &fff4 ; OSBYTE ; plot_rank &497e ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &4981 d0 01 BNE &4984 ; not_demo &4983 60 RTS ; not_demo &4984 a9 09 LDA #&09 ; TAB(&08, &1f) &4986 20 32 43 JSR &4332 ; write_string ; plot_rank_without_tab &4989 38 SEC &498a ad fe 05 LDA &05fe ; player_rank &498d a0 2f LDY #&2f ; "0" - 1 ; division_loop &498f c8 INY &4990 e9 0a SBC #&0a &4992 b0 fb BCS &498f ; division_loop &4994 69 3a ADC #&3a ; "0" + &a &4996 48 PHA ; ones &4997 98 TYA &4998 20 ee ff JSR &ffee ; OSWRCH &499b 68 PLA ; ones &499c 4c ee ff JMP &ffee ; OSWRCH ; consider_plotting_rank &499f ad fe 05 LDA &05fe ; player_rank &49a2 c5 74 CMP &74 ; previous_player_rank &49a4 d0 d8 BNE &497e ; plot_rank ; leave &49a6 60 RTS ; check_for_new_rank &49a7 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &49aa f0 fa BEQ &49a6 ; leave &49ac ac fe 05 LDY &05fe ; player_rank &49af 84 74 STY &74 ; previous_player_rank ; check_for_new_rank_loop &49b1 88 DEY &49b2 f0 eb BEQ &499f ; consider_plotting_rank &49b4 98 TYA &49b5 0a ASL A &49b6 0a ASL A &49b7 0a ASL A &49b8 aa TAX &49b9 ca DEX &49ba ad 46 04 LDA &0446 ; player_score_offset # &50 for player one, &58 for player two &49bd 69 07 ADC #&07 &49bf a8 TAY ; check_score_loop &49c0 b9 00 04 LDA &0400,Y ; player_score - &50 &49c3 dd 00 27 CMP &2700,X ; high_scores &49c6 90 d7 BCC &499f ; consider_plotting_rank &49c8 d0 07 BNE &49d1 ; consider_next_rank &49ca 88 DEY &49cb ca DEX &49cc cc 46 04 CPY &0446 ; player_score_offset &49cf b0 ef BCS &49c0 ; check_score_loop ; consider_next_rank &49d1 ce fe 05 DEC &05fe ; player_rank &49d4 ac fe 05 LDY &05fe ; player_rank &49d7 4c b1 49 JMP &49b1 ; check_for_new_rank_loop ; relocated_entry_point &49da a9 50 LDA #&50 &49dc 8d 46 04 STA &0446 ; player_score_offset # Set to &50 to indicate player one &49df a9 10 LDA #&10 ; Set maximum number of ADC channel &49e1 a2 04 LDX #&04 # Use both joysticks &49e3 20 f4 ff JSR &fff4 ; OSBYTE &49e6 a9 04 LDA #&04 ; Define action of cursor editing keys &49e8 a2 01 LDX #&01 ; Cursor keys return ASCII values 135-139 &49ea 20 f4 ff JSR &fff4 ; OSBYTE &49ed a9 00 LDA #&00 &49ef 8d 38 04 STA &0438 ; sound_muted # Set to zero to indicate sound not muted &49f2 8d 2f 04 STA &042f ; quit_game_cooldown # Set to zero to indicate quit not in progress &49f5 a9 7d LDA #&7d ; Set ESCAPE condition &49f7 20 f4 ff JSR &fff4 ; OSBYTE &49fa a9 7c LDA #&7c ; Clear ESCAPE condition &49fc 20 f4 ff JSR &fff4 ; OSBYTE &49ff a9 03 LDA #&03 ; end print job &4a01 20 ee ff JSR &ffee ; OSWRCH &4a04 20 62 47 JSR &4762 ; initialise_player_score &4a07 a9 1e LDA #&1e ; 30 &4a09 8d fe 05 STA &05fe ; player_rank # Unnecessary code; variables set at start of fame &4a0c a9 01 LDA #&01 &4a0e 8d fd 05 STA &05fd ; player_level &4a11 a9 04 LDA #&04 &4a13 8d fc 05 STA &05fc ; player_lives &4a16 a9 50 LDA #&50 &4a18 8d 37 04 STA &0437 ; previous_score_offset # Set to &50 to indicate player one &4a1b a2 00 LDX #&00 &4a1d 8e 2f 04 STX &042f ; quit_game_cooldown # Unnecessary code; set at &49f2 &4a20 8e 30 04 STX &0430 ; player_explosion_timer &4a23 8e 31 04 STX &0431 ; unused # Unused variable &4a26 8e 34 04 STX &0434 ; new_life_cooldown &4a29 a9 0f LDA #&0f ; Flush buffers &4a2b 20 f4 ff JSR &fff4 ; OSBYTE # Flush all buffers &4a2e ba TSX &4a2f 86 70 STX &70 ; previous_stack_offset &4a31 a9 40 LDA #&40 ; &4a40 = brk_handler &4a33 8d 02 02 STA &0202 ; brk_vector_low &4a36 a9 4a LDA #&4a &4a38 8d 03 02 STA &0203 ; brk_vector_high &4a3b a9 00 LDA #&00 ; Identify Host/Operating System # X = 0, so generate error containing operating system &4a3d 20 f4 ff JSR &fff4 ; OSBYTE # Returns at brk_handler ; brk_handler &4a40 ba TSX &4a41 8e 32 04 STX &0432 ; initial_stack_offset &4a44 a6 70 LDX &70 ; previous_stack_offset &4a46 9a TXS &4a47 20 89 4a JSR &4a89 ; check_if_mos_1.xx &4a4a f0 1a BEQ &4a66 ; not_mos_0.10 &4a4c a9 24 LDA #&24 ; &0224 = mos_0.10_frame_counter &4a4e 8d a8 4a STA &4aa8 ; wait_for_vsync + 1 &4a51 8d b4 4a STA &4ab4 ; check_for_vsync + 1 &4a54 a9 02 LDA #&02 &4a56 8d a9 4a STA &4aa9 ; wait_for_vsync + 2 &4a59 8d b5 4a STA &4ab5 ; check_for_vsync + 2 &4a5c a9 50 LDA #&50 ; &50c1 = set_shiftlock_mos_0.10 &4a5e 8d ab 48 STA &48ab ; call_set_shiftlock + 2 &4a61 a9 c1 LDA #&c1 &4a63 8d aa 48 STA &48aa ; call_set_shiftlock + 1 ; not_mos_0.10 &4a66 78 SEI &4a67 ad 04 02 LDA &0204 ; irq1_vector_low &4a6a 8d 19 04 STA &0419 ; previous_irq1_vector_low &4a6d ad 05 02 LDA &0205 ; irq1_vector_high &4a70 8d 1a 04 STA &041a ; previous_irq1_vector_high &4a73 a9 9a LDA #&9a ; &4a9a = irq_handler &4a75 8d 04 02 STA &0204 ; irq1_vector_low &4a78 a9 4a LDA #&4a &4a7a 8d 05 02 STA &0205 ; irq1_vector_high &4a7d 58 CLI &4a7e a0 50 LDY #&50 # Unnecessary code; value set elsewhere &4a80 8d 46 04 STA &0446 ; player_score_offset # Bug: should be STY &4a83 20 62 47 JSR &4762 ; initialise_player_score &4a86 4c 4f 4c JMP &4c4f ; title_screen ; check_if_mos_1.xx &4a89 a0 00 LDY #&00 ; find_dot_loop &4a8b c8 INY &4a8c b1 fd LDA (&fd),Y ; os_error_message_address &4a8e f0 09 BEQ &4a99 ; leave &4a90 c9 2e CMP #&2e ; "." &4a92 d0 f7 BNE &4a8b ; find_dot_loop &4a94 88 DEY &4a95 b1 fd LDA (&fd),Y ; os_error_message_address &4a97 c9 31 CMP #&31 ; "1" ; leave &4a99 60 RTS # Leave with equals set if MOS 1.xx ; irq_handler &4a9a a9 02 LDA #&02 # &02 set if interrupt was caused by a v-sync &4a9c 2c 4d fe BIT &fe4d ; System VIA interrupt flag register &4a9f f0 03 BEQ &4aa4 ; to_previous_irq1_vector &4aa1 ee 18 04 INC &0418 ; frame_counter ; to_previous_irq1_vector &4aa4 6c 19 04 JMP (&0419) ; previous_irq1_vector ; wait_for_vsync &4aa7 ad 18 04 LDA &0418 ; frame_counter # or LDA &0224 ; mos_0.10_frame_counter if MOS 0.10 &4aaa cd 1b 04 CMP &041b ; previous_frame_counter &4aad f0 f8 BEQ &4aa7 ; wait_for_vsync &4aaf 8d 1b 04 STA &041b ; previous_frame_counter &4ab2 60 RTS ; check_for_vsync &4ab3 ad 18 04 LDA &0418 ; frame_counter # or LDA &0224 ; mos_0.10_frame_counter if MOS 0.10 &4ab6 cd 1b 04 CMP &041b ; previous_frame_counter &4ab9 60 RTS ; define_envelope &4aba aa TAX &4abb bd 18 31 LDA &3118,X ; envelope_addresses_high &4abe a8 TAY &4abf bd 0e 31 LDA &310e,X ; envelope_addresses_low &4ac2 aa TAX &4ac3 a9 08 LDA #&08 ; Define a sound envelope &4ac5 4c f1 ff JMP &fff1 ; OSWORD ; play_sound &4ac8 aa TAX &4ac9 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &4acc d0 01 BNE &4acf ; not_demo ; leave &4ace 60 RTS ; not_demo &4acf ad 38 04 LDA &0438 ; sound_muted # Non-zero if sound muted &4ad2 d0 fa BNE &4ace ; leave &4ad4 bd 03 31 LDA &3103,X ; sound_addresses_high &4ad7 a8 TAY &4ad8 bd f8 30 LDA &30f8,X ; sound_addresses_low &4adb aa TAX &4adc a9 07 LDA #&07 ; Generate a sound &4ade 4c f1 ff JMP &fff1 ; OSWORD ; flush_buffers &4ae1 a2 00 LDX #&00 ; all buffers &4ae3 a9 0f LDA #&0f ; Flush all buffers &4ae5 4c f4 ff JMP &fff4 ; OSBYTE ; consider_starting_new_life &4ae8 ce 34 04 DEC &0434 ; new_life_cooldown &4aeb f0 01 BEQ &4aee ; start_new_life &4aed 60 RTS ; start_new_life &4aee 20 18 37 JSR &3718 ; plot_lives &4af1 20 c7 35 JSR &35c7 ; wipe_bottom_half_of_game_area &4af4 a9 00 LDA #&00 &4af6 8d 0c 04 STA &040c ; number_of_active_enemies &4af9 4c 83 51 JMP &5183 ; initialise_player ; start_player_explosion &4afc a9 64 LDA #&64 # Player explosion lasts 100 frames &4afe 8d 30 04 STA &0430 ; player_explosion_timer &4b01 a9 ff LDA #&ff &4b03 8d 0c 04 STA &040c ; number_of_active_enemies &4b06 20 66 35 JSR &3566 ; unplot_laser &4b09 a9 00 LDA #&00 &4b0b 8d 00 04 STA &0400 ; laser_active # Non-zero if laser active &4b0e a9 02 LDA #&02 ; sound_2 &4b10 20 c8 4a JSR &4ac8 ; play_sound # Silence channel 1 &4b13 a9 03 LDA #&03 ; sound_3 &4b15 20 c8 4a JSR &4ac8 ; play_sound # Silence channel 0 &4b18 a2 10 LDX #&10 ; &2910 = envelope_player_explosion &4b1a a0 29 LDY #&29 &4b1c a9 08 LDA #&08 ; Define a sound envelope &4b1e 20 f1 ff JSR &fff1 ; OSWORD &4b21 a9 07 LDA #&07 ; sound_7 &4b23 20 c8 4a JSR &4ac8 ; play_sound # Play sound for player explosion &4b26 60 RTS ; leave &4b27 60 RTS ; update_player_explosion &4b28 a5 79 LDA &79 ; update_counter &4b2a 4a LSR A &4b2b 90 fa BCC &4b27 ; leave &4b2d ce 30 04 DEC &0430 ; player_explosion_timer &4b30 f0 37 BEQ &4b69 ; end_player_explosion &4b32 ad 30 04 LDA &0430 ; player_explosion_timer &4b35 c9 2d CMP #&2d &4b37 d0 12 BNE &4b4b ; not_game_over &4b39 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &4b3c f0 e9 BEQ &4b27 ; leave &4b3e ce fc 05 DEC &05fc ; player_lives &4b41 d0 08 BNE &4b4b ; not_game_over &4b43 a9 00 LDA #&00 ; "Game Over" &4b45 20 32 43 JSR &4332 ; write_string &4b48 20 58 4b JSR &4b58 ; write_current_player ; not_game_over &4b4b a2 03 LDX #&03 ; copy_player_screen_and_sprite_addresses_loop &4b4d b5 80 LDA &80,X ; player_screen_address &4b4f 95 70 STA &70,X ; screen_address &4b51 ca DEX &4b52 10 f9 BPL &4b4d ; copy_player_screen_and_sprite_addresses_loop &4b54 4c 19 51 JMP &5119 ; plot_random_player_explosion ; leave &4b57 60 RTS ; write_current_player &4b58 ad 46 04 LDA &0446 ; player_score_offset # Zero if demo, &50 for player one, &58 for player two &4b5b f0 fa BEQ &4b57 ; leave &4b5d a0 02 LDY #&02 ; "Player Two" &4b5f c9 58 CMP #&58 &4b61 f0 02 BEQ &4b65 ; to_write_string &4b63 a0 01 LDY #&01 ; "Player One" ; to_write_string &4b65 98 TYA &4b66 4c 32 43 JMP &4332 ; write_string ; end_player_explosion &4b69 a9 00 LDA #&00 ; envelope_0 # Use game envelopes &4b6b 20 ba 4a JSR &4aba ; define_envelope &4b6e a9 02 LDA #&02 ; envelope_2 &4b70 20 ba 4a JSR &4aba ; define_envelope &4b73 a9 03 LDA #&03 ; envelope_3 &4b75 20 ba 4a JSR &4aba ; define_envelope &4b78 a9 01 LDA #&01 ; envelope_1 &4b7a 20 ba 4a JSR &4aba ; define_envelope &4b7d ad 46 04 LDA &0446 ; player_score_offset # Zero if demo &4b80 d0 03 BNE &4b85 ; not_demo &4b82 4c 66 4c JMP &4c66 ; prepare_for_high_score_and_demo_screens # Demo ends when player is killed ; not_demo &4b85 ad fc 05 LDA &05fc ; player_lives &4b88 d0 2e BNE &4bb8 ; skip_checking_for_high_score # Has the player run out of lives? ; end_of_game &4b8a 20 34 48 JSR &4834 ; check_for_high_score &4b8d ad fc 06 LDA &06fc ; other_player_lives &4b90 f0 26 BEQ &4bb8 ; skip_checking_for_high_score # Is the other player still active? &4b92 20 6c 47 JSR &476c ; initialise_score_to_add &4b95 a9 0a LDA #&0a # Change to MODE 5 and set up game screen &4b97 20 32 43 JSR &4332 ; write_string &4b9a a9 08 LDA #&08 ; "RANK:" &4b9c 20 32 43 JSR &4332 ; write_string &4b9f 20 77 47 JSR &4777 ; plot_high_score &4ba2 20 f2 46 JSR &46f2 ; update_score # Plot current player's score &4ba5 ad 46 04 LDA &0446 ; player_score_offset &4ba8 49 08 EOR #&08 # Swap between &50 for player one and &58 for player two &4baa 8d 46 04 STA &0446 ; player_score_offset &4bad 20 f2 46 JSR &46f2 ; update_score # Plot next player's score &4bb0 ad 46 04 LDA &0446 ; player_score_offset &4bb3 49 08 EOR #&08 # Swap between &50 for player one and &58 for player two &4bb5 8d 46 04 STA &0446 ; player_score_offset ; skip_checking_for_high_score &4bb8 ad fc 06 LDA &06fc ; other_player_lives &4bbb 0d fc 05 ORA &05fc ; player_lives &4bbe d0 03 BNE &4bc3 ; not_end_of_both_players &4bc0 4c 4c 4c JMP &4c4c ; to_prepare_for_high_score_and_demo_screens ; not_end_of_both_players &4bc3 ad fc 06 LDA &06fc ; other_player_lives &4bc6 f0 61 BEQ &4c29 ; skip_swapping_player &4bc8 a0 00 LDY #&00 ; swap_player_variables &4bca b9 00 05 LDA &0500,Y ; player_variables # Swap &0500 - &05ff and &0600 - &06ff &4bcd be 00 06 LDX &0600,Y ; other_player_variables &4bd0 99 00 06 STA &0600,Y ; other_player_variables &4bd3 8a TXA &4bd4 99 00 05 STA &0500,Y ; player_variables &4bd7 c8 INY &4bd8 d0 f0 BNE &4bca ; swap_player_variables &4bda ad 46 04 LDA &0446 ; player_score_offset &4bdd 49 08 EOR #&08 # Swap between &50 for player one and &58 for player two &4bdf 8d 46 04 STA &0446 ; player_score_offset &4be2 8d 37 04 STA &0437 ; previous_score_offset &4be5 24 02 BIT &02 ; keyboard_or_joystick &4be7 10 0d BPL &4bf6 ; skip_changing_input # Positive if using keyboard &4be9 48 PHA ; score offset &4bea a2 01 LDX #&01 ; INPUT_JOYSTICK_ONE &4bec 29 08 AND #&08 &4bee f0 01 BEQ &4bf1 ; is_player_one ; is_player_two &4bf0 e8 INX ; INPUT_JOYSTICK_TWO ; is_player_one &4bf1 8a TXA &4bf2 20 c9 32 JSR &32c9 ; set_movement_and_firing_check_routine_addresses &4bf5 68 PLA ; score offset ; skip_changing_input &4bf6 18 CLC &4bf7 69 07 ADC #&07 &4bf9 a8 TAY &4bfa a9 00 LDA #&00 ; check_for_zero_score_loop &4bfc 19 00 04 ORA &0400,Y ; player_score - &50 &4bff 88 DEY &4c00 cc 46 04 CPY &0446 ; player_score_offset &4c03 b0 f7 BCS &4bfc ; check_for_zero_score_loop &4c05 a8 TAY &4c06 d0 0d BNE &4c15 ; not_first_life # Non-zero if player's score is non-zero &4c08 ad fc 05 LDA &05fc ; player_lives &4c0b c9 03 CMP #&03 &4c0d d0 06 BNE &4c15 ; not_first_life &4c0f 20 a5 35 JSR &35a5 ; wipe_game_area &4c12 4c bd 41 JMP &41bd ; start_new_game_without_setting_up_screen ; not_first_life &4c15 20 a5 35 JSR &35a5 ; wipe_game_area &4c18 a9 03 LDA #&03 ; "Game Start" &4c1a 20 32 43 JSR &4332 ; write_string &4c1d 20 58 4b JSR &4b58 ; write_current_player &4c20 ad 01 05 LDA &0501 ; number_of_enemies &4c23 8d 0d 04 STA &040d ; number_of_passive_enemies &4c26 20 47 37 JSR &3747 ; plot_level_flags_and_sound_status ; skip_swapping_player &4c29 ee fc 05 INC &05fc ; player_lives &4c2c 20 18 37 JSR &3718 ; plot_lives # Unplot lost life &4c2f ce fc 05 DEC &05fc ; player_lives &4c32 20 e9 35 JSR &35e9 ; wipe_bottom_quarter_of_game_area &4c35 a9 1e LDA #&1e ; 30 &4c37 8d fe 05 STA &05fe ; player_rank &4c3a 20 a7 49 JSR &49a7 ; check_for_new_rank &4c3d 20 7e 49 JSR &497e ; plot_rank &4c40 ae 32 04 LDX &0432 ; initial_stack_offset &4c43 9a TXS &4c44 a9 96 LDA #&96 # Wait 150 frames before starting game &4c46 8d 34 04 STA &0434 ; new_life_cooldown &4c49 4c 5d 41 JMP &415d ; main_game_loop ; to_prepare_for_high_score_and_demo_screens &4c4c 4c 66 4c JMP &4c66 ; prepare_for_high_score_and_demo_screens ; title_screen &4c4f ae 32 04 LDX &0432 ; initial_stack_offset &4c52 9a TXS &4c53 a9 03 LDA #&03 ; INPUT_DEMO &4c55 20 c9 32 JSR &32c9 ; set_movement_and_firing_check_routine_addresses &4c58 a2 00 LDX #&00 &4c5a 8e 46 04 STX &0446 ; player_score_offset # Zero if demo, &50 for player one, &58 for player two &4c5d 8e 2e 04 STX &042e ; suppress_sound_status # Set to zero to suppress displaying sound status &4c60 ca DEX ; &ff &4c61 86 05 STX &05 ; suppress_joystick_button # Set to non-zero to suppress joystick button &4c63 20 3b 4d JSR &4d3b ; instructions_screen ; prepare_for_high_score_and_demo_screens &4c66 ae 32 04 LDX &0432 ; initial_stack_offset &4c69 9a TXS &4c6a a9 03 LDA #&03 ; INPUT_DEMO &4c6c 20 c9 32 JSR &32c9 ; set_movement_and_firing_check_routine_addresses &4c6f a2 00 LDX #&00 &4c71 8e 46 04 STX &0446 ; player_score_offset # Set to zero to indicate demo mode &4c74 8e 2e 04 STX &042e ; suppress_sound_status # Set to zero to suppress displaying sound status &4c77 ca DEX ; &ff &4c78 86 05 STX &05 ; suppress_joystick_button # Set to non-zero to suppress joystick button &4c7a 20 83 4d JSR &4d83 ; high_score_and_demo_screens ; determine_game_type &4c7d a9 00 LDA #&00 &4c7f 85 02 STA &02 ; keyboard_or_joystick # Set to positive to indicate keyboard &4c81 a5 70 LDA &70 ; game_type &4c83 48 PHA ; game_type &4c84 29 80 AND #&80 &4c86 85 3a STA &3a ; unused # Top bit set if joystick, clear if keyboard &4c88 68 PLA ; game_type &4c89 30 2c BMI &4cb7 ; is_joystick_game ; is_keyboard_game &4c8b 48 PHA ; game_type &4c8c a9 00 LDA #&00 ; INPUT_KEYBOARD &4c8e 20 c9 32 JSR &32c9 ; set_movement_and_firing_check_routine_addresses &4c91 68 PLA ; game_type &4c92 d0 05 BNE &4c99 ; is_two_player_game # Zero if one player keyboard game ; is_one_player_game &4c94 a2 00 LDX #&00 &4c96 8a TXA &4c97 f0 04 BEQ &4c9d ; set_other_player_lives # Always branches ; is_two_player_game &4c99 a2 01 LDX #&01 # Unnecessary code &4c9b a9 03 LDA #&03 ; set_other_player_lives &4c9d 8d fc 06 STA &06fc ; other_player_lives &4ca0 a9 03 LDA #&03 &4ca2 8d fc 05 STA &05fc ; player_lives &4ca5 a9 50 LDA #&50 &4ca7 8d 46 04 STA &0446 ; player_score_offset # Set to &50 to indicate player one &4caa a9 0b LDA #&0b ; Set auto-repeat delay &4cac a2 00 LDX #&00 &4cae 20 f4 ff JSR &fff4 ; OSBYTE &4cb1 20 02 53 JSR &5302 ; play_tune &4cb4 4c 9d 41 JMP &419d ; start_new_game ; is_joystick_game &4cb7 a9 ff LDA #&ff &4cb9 85 05 STA &05 ; suppress_joystick_button # Set to non-zero to suppress joystick button &4cbb a9 00 LDA #&00 &4cbd 8d 2e 04 STA &042e ; suppress_sound_status # Set to zero to suppress displaying sound status &4cc0 a9 01 LDA #&01 &4cc2 20 c9 32 JSR &32c9 ; set_movement_and_firing_check_routine_addresses &4cc5 a9 16 LDA #&16 # Change to MODE 7 and set up joystick menu screen &4cc7 20 32 43 JSR &4332 ; write_string &4cca a9 0e LDA #&0e # Disable cursor &4ccc 20 32 43 JSR &4332 ; write_string &4ccf a9 17 LDA #&17 ; "Select game with joystick #1" &4cd1 20 32 43 JSR &4332 ; write_string &4cd4 a9 02 LDA #&02 &4cd6 85 77 STA &77 ; joystick_menu_cooldown_high &4cd8 a9 00 LDA #&00 &4cda 85 78 STA &78 ; joystick_menu_cooldown_low ; joystick_menu_loop &4cdc a2 01 LDX #&01 ; Analogue channel 1 (joystick one x) &4cde a9 80 LDA #&80 ; Read I/O device or buffer status &4ce0 20 f4 ff JSR &fff4 ; OSBYTE &4ce3 a2 18 LDX #&18 ; string_18 &4ce5 98 TYA &4ce6 30 01 BMI &4ce9 ; highlight_one_player_game ; highlight_two_player_game &4ce8 e8 INX ; string_19 ; highlight_one_player_game &4ce9 8a TXA &4cea 48 PHA ; joystick highlight string &4ceb a9 1f LDA #&1f # TAB(&00, &0e) &4ced 20 ee ff JSR &ffee ; OSWRCH &4cf0 a9 00 LDA #&00 &4cf2 20 ee ff JSR &ffee ; OSWRCH &4cf5 a9 0e LDA #&0e &4cf7 20 ee ff JSR &ffee ; OSWRCH &4cfa a9 09 LDA #&09 &4cfc 85 76 STA &76 ; count ; highlight_loop # Write highlight string for each of nine lines &4cfe 68 PLA ; joystick highlight string &4cff 48 PHA ; joystick highlight string &4d00 20 32 43 JSR &4332 ; write_string &4d03 c6 76 DEC &76 ; count &4d05 d0 f7 BNE &4cfe ; highlight_loop &4d07 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &4d0a 20 a7 4a JSR &4aa7 ; wait_for_vsync &4d0d 20 0e 32 JSR &320e ; check_for_joystick_one_fire &4d10 8a TXA &4d11 d0 06 BNE &4d19 ; button_pressed &4d13 a9 00 LDA #&00 &4d15 85 05 STA &05 ; suppress_joystick_button # Set to zero to permit joystick button &4d17 f0 16 BEQ &4d2f ; button_not_pressed # Always branches ; button_pressed &4d19 a5 05 LDA &05 ; suppress_joystick_button &4d1b d0 12 BNE &4d2f ; button_not_pressed # Non-zero if joystick button suppressed &4d1d a9 ff LDA #&ff &4d1f 85 02 STA &02 ; keyboard_or_joystick # Set to negative to indicate keyboard &4d21 68 PLA ; joystick highlight string &4d22 a2 00 LDX #&00 &4d24 4a LSR A &4d25 90 04 BCC &4d2b ; to_set_other_player_lives # Carry set for two players, clear for one player &4d27 a2 03 LDX #&03 # Set to non-zero to indicate player two active &4d29 c6 02 DEC &02 ; keyboard_or_joystick # Unnecessary code; sign is already negative ; to_set_other_player_lives &4d2b 8a TXA &4d2c 4c 9d 4c JMP &4c9d ; set_other_player_lives ; button_not_pressed &4d2f 68 PLA ; joystick highlight string &4d30 c6 78 DEC &78 ; joystick_menu_cooldown_low &4d32 d0 a8 BNE &4cdc ; joystick_menu_loop &4d34 c6 77 DEC &77 ; joystick_menu_cooldown_high &4d36 d0 a4 BNE &4cdc ; joystick_menu_loop &4d38 4c 66 4c JMP &4c66 ; prepare_for_high_score_and_demo_screens ; instructions_screen &4d3b a9 16 LDA #&16 # Change to MODE 7 &4d3d 20 ee ff JSR &ffee ; OSWRCH &4d40 a9 07 LDA #&07 &4d42 20 ee ff JSR &ffee ; OSWRCH &4d45 a9 0e LDA #&0e # Disable cursor &4d47 20 32 43 JSR &4332 ; write_string &4d4a a0 00 LDY #&00 &4d4c 84 70 STY &70 ; target_address_low &4d4e 84 72 STY &72 ; source_address_low &4d50 a9 7c LDA #&7c ; &7c00 = screen memory &4d52 85 71 STA &71 ; target_address_high &4d54 a9 54 LDA #&54 ; &5400 = instructions_screen_data &4d56 85 73 STA &73 ; source_address_high &4d58 a2 04 LDX #&04 ; copy_instructions_screen_loop &4d5a b1 72 LDA (&72),Y ; source_address &4d5c 91 70 STA (&70),Y ; target_address &4d5e c8 INY &4d5f d0 f9 BNE &4d5a ; copy_instructions_screen_loop &4d61 e6 73 INC &73 ; source_address_high &4d63 e6 71 INC &71 ; target_address_high &4d65 ca DEX &4d66 d0 f2 BNE &4d5a ; copy_instructions_screen_loop &4d68 a9 be LDA #&be &4d6a 85 7b STA &7b ; count &4d6c 86 75 STX &75 ; count_fraction ; instructions_screen_loop &4d6e 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &4d71 20 95 4d JSR &4d95 ; check_for_game_start_keys &4d74 20 a7 4a JSR &4aa7 ; wait_for_vsync &4d77 e6 75 INC &75 ; count_fraction &4d79 a5 75 LDA &75 ; count_fraction &4d7b 29 03 AND #&03 &4d7d d0 ef BNE &4d6e ; instructions_screen_loop &4d7f c6 7b DEC &7b ; count &4d81 d0 eb BNE &4d6e ; instructions_screen_loop ; high_score_and_demo_screens &4d83 20 e1 4a JSR &4ae1 ; flush_buffers &4d86 20 e9 4d JSR &4de9 ; high_score_screen &4d89 20 e1 4a JSR &4ae1 ; flush_buffers &4d8c 20 c6 4e JSR &4ec6 ; demo_introduction_screen &4d8f 20 e1 4a JSR &4ae1 ; flush_buffers &4d92 20 8e 50 JSR &508e ; start_demo ; check_for_game_start_keys &4d95 a0 ff LDY #&ff &4d97 a2 cf LDX #&cf ; 1 &4d99 a9 81 LDA #&81 ; Scan for a particular key &4d9b 20 f4 ff JSR &fff4 ; OSBYTE &4d9e 8a TXA &4d9f f0 0b BEQ &4dac ; one_not_pressed &4da1 a9 00 LDA #&00 ; GAME_ONE_PLAYER_KEYBOARD &4da3 85 70 STA &70 ; game_type &4da5 ae 32 04 LDX &0432 ; initial_stack_offset &4da8 9a TXS &4da9 4c 7d 4c JMP &4c7d ; determine_game_type ; one_not_pressed &4dac a0 ff LDY #&ff &4dae a2 ce LDX #&ce ; 2 &4db0 a9 81 LDA #&81 ; Scan for a particular key &4db2 20 f4 ff JSR &fff4 ; OSBYTE &4db5 8a TXA &4db6 f0 0b BEQ &4dc3 ; two_not_pressed &4db8 a9 01 LDA #&01 ; GAME_TWO_PLAYER_KEYBOARD &4dba 85 70 STA &70 ; game_type &4dbc ae 32 04 LDX &0432 ; initial_stack_offset &4dbf 9a TXS &4dc0 4c 7d 4c JMP &4c7d ; determine_game_type ; two_not_pressed &4dc3 a9 80 LDA #&80 ; Read I/O device or buffer status &4dc5 a2 00 LDX #&00 ; joystick buttons &4dc7 20 f4 ff JSR &fff4 ; OSBYTE &4dca d8 CLD &4dcb 8a TXA &4dcc 29 01 AND #&01 &4dce d0 05 BNE &4dd5 ; fire_pressed &4dd0 a9 00 LDA #&00 &4dd2 85 05 STA &05 ; suppress_joystick_button # Set to zero to permit joystick button &4dd4 60 RTS ; fire_pressed &4dd5 a5 05 LDA &05 ; suppress_joystick_button # Non-zero if joystick button suppressed &4dd7 f0 01 BEQ &4dda ; start_joystick_game &4dd9 60 RTS ; start_joystick_game &4dda a9 ff LDA #&ff ; GAME_JOYSTICK &4ddc 85 70 STA &70 ; game_type &4dde ae 32 04 LDX &0432 ; initial_stack_offset &4de1 9a TXS &4de2 a9 ff LDA #&ff &4de4 85 05 STA &05 ; suppress_joystick_button # Set to non-zero to suppress joystick button &4de6 4c 7d 4c JMP &4c7d ; determine_game_type ; high_score_screen &4de9 a9 16 LDA #&16 # Change to MODE 7 &4deb 20 ee ff JSR &ffee ; OSWRCH &4dee a9 07 LDA #&07 &4df0 20 ee ff JSR &ffee ; OSWRCH &4df3 a9 07 LDA #&07 # Arcadian Hi-scores &4df5 20 32 43 JSR &4332 ; write_string &4df8 a9 09 LDA #&09 &4dfa 85 7b STA &7b ; rank ; write_high_scores_loop &4dfc a9 1f LDA #&1f # TAB(&02, rank * 2 + 4) &4dfe 20 ee ff JSR &ffee ; OSWRCH &4e01 a9 02 LDA #&02 &4e03 20 ee ff JSR &ffee ; OSWRCH &4e06 a5 7b LDA &7b ; rank &4e08 0a ASL A &4e09 69 04 ADC #&04 &4e0b 20 ee ff JSR &ffee ; OSWRCH &4e0e a5 7b LDA &7b ; rank &4e10 18 CLC &4e11 69 31 ADC #&31 ; "1" &4e13 20 ee ff JSR &ffee ; OSWRCH # Write rank number &4e16 a9 2e LDA #&2e &4e18 20 ee ff JSR &ffee ; OSWRCH &4e1b a5 7b LDA &7b ; rank &4e1d 0a ASL A &4e1e 0a ASL A &4e1f 0a ASL A &4e20 85 70 STA &70 ; high_score_offset &4e22 69 07 ADC #&07 &4e24 a8 TAY &4e25 a9 2e LDA #&2e ; "." ; write_leading_periods_loop &4e27 be 00 27 LDX &2700,Y ; high_scores &4e2a d0 07 BNE &4e33 ; write_high_score_loop &4e2c 20 ee ff JSR &ffee ; OSWRCH &4e2f 88 DEY &4e30 4c 27 4e JMP &4e27 ; write_leading_periods_loop ; write_high_score_loop &4e33 b9 00 27 LDA &2700,Y ; high_scores &4e36 18 CLC &4e37 69 30 ADC #&30 ; "0" &4e39 20 ee ff JSR &ffee ; OSWRCH &4e3c 88 DEY &4e3d c4 70 CPY &70 ; high_score_offset &4e3f d0 f2 BNE &4e33 ; write_high_score_loop &4e41 b9 00 27 LDA &2700,Y ; high_scores &4e44 18 CLC &4e45 69 30 ADC #&30 ; "0" &4e47 20 ee ff JSR &ffee ; OSWRCH &4e4a a9 30 LDA #&30 ; "0" &4e4c 20 ee ff JSR &ffee ; OSWRCH &4e4f a2 03 LDX #&03 ; write_trailing_periods_loop &4e51 a9 2e LDA #&2e ; "." &4e53 20 ee ff JSR &ffee ; OSWRCH &4e56 ca DEX &4e57 d0 f8 BNE &4e51 ; write_trailing_periods_loop &4e59 a5 7b LDA &7b ; rank &4e5b 85 70 STA &70 ; name_offset &4e5d 0a ASL A &4e5e 0a ASL A &4e5f 0a ASL A &4e60 48 PHA ; rank times eight &4e61 65 70 ADC &70 ; name_offset &4e63 85 70 STA &70 ; name_offset &4e65 68 PLA ; rank times eight &4e66 0a ASL A &4e67 65 70 ADC &70 ; name_offset &4e69 a8 TAY ; write_name_loop &4e6a b9 00 28 LDA &2800,Y ; high_score_names &4e6d c9 0d CMP #&0d ; CR &4e6f f0 07 BEQ &4e78 ; consider_next_rank &4e71 20 ee ff JSR &ffee ; OSWRCH &4e74 c8 INY &4e75 4c 6a 4e JMP &4e6a ; write_name_loop ; consider_next_rank &4e78 c6 7b DEC &7b ; rank &4e7a 30 03 BMI &4e7f ; finished_writing_high_scores &4e7c 4c fc 4d JMP &4dfc ; write_high_scores_loop ; finished_writing_high_scores &4e7f a9 0b LDA #&0b ; "10" &4e81 20 32 43 JSR &4332 ; write_string # Write number for tenth rank &4e84 a9 50 LDA #&50 &4e86 85 75 STA &75 ; count ; high_score_screen_loop &4e88 a9 07 LDA #&07 &4e8a 85 7b STA &7b ; inner_count ; high_score_screen_inner_loop &4e8c 20 95 4d JSR &4d95 ; check_for_game_start_keys &4e8f 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &4e92 20 a7 4a JSR &4aa7 ; wait_for_vsync &4e95 c6 7b DEC &7b ; inner_count &4e97 10 f3 BPL &4e8c ; high_score_screen_inner_loop &4e99 ad e6 2e LDA &2ee6 ; string_7 + &15 &4e9c 48 PHA ; arcadian character &4e9d ad f6 2e LDA &2ef6 ; string_7 + &25 &4ea0 48 PHA ; hiscores character &4ea1 a0 00 LDY #&00 ; rotate_high_score_text_loop &4ea3 b9 f7 2e LDA &2ef7,Y ; string_7 + &26 # Rotate "Hiscores" &4ea6 99 f6 2e STA &2ef6,Y ; string_7 + &25 &4ea9 b9 e7 2e LDA &2ee7,Y ; string_7 + &16 # Rotate "Arcadian" &4eac 99 e6 2e STA &2ee6,Y ; string_7 + &15 &4eaf c8 INY &4eb0 c0 07 CPY #&07 &4eb2 d0 ef BNE &4ea3 ; rotate_high_score_text_loop &4eb4 68 PLA ; hiscores character &4eb5 8d ed 2e STA &2eed ; string_7 + &2d &4eb8 68 PLA ; arcadian character &4eb9 8d fd 2e STA &2efd ; string_7 + &1d &4ebc a9 07 LDA #&07 &4ebe 20 32 43 JSR &4332 ; write_string &4ec1 c6 75 DEC &75 ; count &4ec3 d0 c3 BNE &4e88 ; high_score_screen_loop &4ec5 60 RTS ; demo_introduction_screen &4ec6 a9 ff LDA #&ff &4ec8 8d 2e 04 STA &042e ; suppress_sound_status # Set to non-zero to display sound status &4ecb a9 04 LDA #&04 ; Write text at text cursor &4ecd 20 ee ff JSR &ffee ; OSWRCH &4ed0 a9 0a LDA #&0a # Change to MODE 5 and set up game screen &4ed2 20 32 43 JSR &4332 ; write_string &4ed5 20 77 47 JSR &4777 ; plot_high_score &4ed8 a9 08 LDA #&08 ; "RANK:" &4eda 20 32 43 JSR &4332 ; write_string &4edd a9 50 LDA #&50 &4edf 8d 46 04 STA &0446 ; player_score_offset # Set to &50 for player one &4ee2 20 6c 47 JSR &476c ; initialise_score_to_add &4ee5 20 f2 46 JSR &46f2 ; update_score &4ee8 a9 58 LDA #&58 &4eea 8d 46 04 STA &0446 ; player_score_offset # Set to &58 for player two &4eed 20 f2 46 JSR &46f2 ; update_score &4ef0 ad 37 04 LDA &0437 ; previous_score_offset &4ef3 8d 46 04 STA &0446 ; player_score_offset # Set to non-zero to permit rank to be plotted &4ef6 a9 03 LDA #&03 &4ef8 8d fc 05 STA &05fc ; player_lives &4efb 20 18 37 JSR &3718 ; plot_lives &4efe 20 47 37 JSR &3747 ; plot_level_flags_and_sound_status &4f01 a9 1e LDA #&1e ; 30 &4f03 8d fe 05 STA &05fe ; player_rank &4f06 20 a7 49 JSR &49a7 ; check_for_new_rank &4f09 20 7e 49 JSR &497e ; plot_rank &4f0c a9 00 LDA #&00 &4f0e 8d 46 04 STA &0446 ; player_score_offset # Set to zero to indicate demo mode &4f11 a9 0d LDA #&0d &4f13 85 7b STA &7b ; text_count &4f15 a9 00 LDA #&00 ; &2d00 = demo_text &4f17 85 76 STA &76 ; demo_text_address_low &4f19 a9 2d LDA #&2d &4f1b 85 77 STA &77 ; demo_text_address_high &4f1d a0 00 LDY #&00 ; demo_introduction_screen_text_loop # For each string, &4f1f a0 00 LDY #&00 &4f21 b1 76 LDA (&76),Y ; demo_text_address # First byte sets x position &4f23 85 7d STA &7d ; text_x &4f25 85 78 STA &78 ; initial_text_x &4f27 c8 INY &4f28 b1 76 LDA (&76),Y ; demo_text_address # Second byte sets y position &4f2a 85 7c STA &7c ; text_y &4f2c c8 INY &4f2d b1 76 LDA (&76),Y ; demo_text_address # Third byte sets length &4f2f 85 7e STA &7e ; text_length &4f31 a5 76 LDA &76 ; demo_text_address_low &4f33 18 CLC &4f34 69 03 ADC #&03 &4f36 85 76 STA &76 ; demo_text_address_low &4f38 90 02 BCC &4f3c ; skip_page &4f3a e6 77 INC &77 ; demo_text_address_high ; skip_page &4f3c 20 86 4f JSR &4f86 ; animate_demo_text # Scroll string onto screen &4f3f c6 7b DEC &7b ; text_count &4f41 d0 dc BNE &4f1f ; demo_introduction_screen_text_loop &4f43 a9 03 LDA #&03 &4f45 85 7d STA &7d ; count &4f47 a9 00 LDA #&00 &4f49 85 7f STA &7f ; count_fraction &4f4b a9 12 LDA #&12 ; "150" &4f4d 85 7e STA &7e ; scoring_string ; demo_introduction_screen_score_loop # Animate group leader scoring &4f4f 20 95 4d JSR &4d95 ; check_for_game_start_keys &4f52 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &4f55 20 a7 4a JSR &4aa7 ; wait_for_vsync &4f58 a5 7f LDA &7f ; count_fraction &4f5a 29 1f AND #&1f &4f5c d0 1f BNE &4f7d ; skip_replotting_score &4f5e a5 7f LDA &7f ; count_fraction &4f60 29 20 AND #&20 &4f62 d0 08 BNE &4f6c ; flash_on ; flash_off &4f64 a9 15 LDA #&15 ; " " &4f66 20 32 43 JSR &4332 ; write_string &4f69 4c 7d 4f JMP &4f7d ; skip_replotting_score ; flash_on &4f6c a5 7e LDA &7e ; scoring_string &4f6e 20 32 43 JSR &4332 ; write_string &4f71 e6 7e INC &7e ; scoring_string &4f73 a5 7e LDA &7e ; scoring_string &4f75 c9 15 CMP #&15 ; " " &4f77 d0 04 BNE &4f7d ; skip_wraparound &4f79 a9 11 LDA #&11 ; "100" &4f7b 85 7e STA &7e ; scoring_string ; skip_wraparound ; skip_replotting_score &4f7d e6 7f INC &7f ; count_fraction &4f7f d0 ce BNE &4f4f ; demo_introduction_screen_score_loop &4f81 c6 7d DEC &7d ; count &4f83 d0 ca BNE &4f4f ; demo_introduction_screen_score_loop &4f85 60 RTS ; animate_demo_text &4f86 a9 1f LDA #&1f # TAB(&13, text_y) &4f88 20 ee ff JSR &ffee ; OSWRCH &4f8b a9 13 LDA #&13 &4f8d 20 ee ff JSR &ffee ; OSWRCH &4f90 a5 7c LDA &7c ; text_y &4f92 20 ee ff JSR &ffee ; OSWRCH &4f95 a0 00 LDY #&00 &4f97 a5 7e LDA &7e ; text_length &4f99 f0 11 BEQ &4fac ; skip_character &4f9b b1 76 LDA (&76),Y ; demo_text_address &4f9d c9 20 CMP #&20 ; " " &4f9f f0 03 BEQ &4fa4 ; skip_writing_character &4fa1 20 ee ff JSR &ffee ; OSWRCH ; skip_writing_character &4fa4 e6 76 INC &76 ; demo_text_address_low &4fa6 d0 02 BNE &4faa ; skip_page &4fa8 e6 77 INC &77 ; demo_text_address_high ; skip_page &4faa c6 7e DEC &7e ; text_length ; skip_character &4fac a5 7c LDA &7c ; text_y &4fae c9 11 CMP #&11 &4fb0 b0 3a BCS &4fec ; skip_sprite &4fb2 c9 0d CMP #&0d &4fb4 90 36 BCC &4fec ; skip_sprite &4fb6 a5 78 LDA &78 ; initial_text_x &4fb8 38 SEC &4fb9 e5 7d SBC &7d ; text_x &4fbb c9 01 CMP #&01 &4fbd d0 2d BNE &4fec ; skip_sprite &4fbf a2 03 LDX #&03 ; backup_screen_addresses_loop &4fc1 b5 70 LDA &70,X ; screen_address &4fc3 48 PHA ; address byte &4fc4 ca DEX &4fc5 10 fa BPL &4fc1 ; backup_screen_addresses_loop &4fc7 a5 72 LDA &72 ; end_screen_address_low &4fc9 18 CLC &4fca 69 28 ADC #&28 # Position sprite at end of line initially &4fcc 85 70 STA &70 ; screen_address_low &4fce a5 73 LDA &73 ; end_screen_address_high &4fd0 69 01 ADC #&01 &4fd2 85 71 STA &71 ; screen_address_high &4fd4 a9 00 LDA #&00 ; SPRITE_ROTATION_0 &4fd6 85 72 STA &72 ; sprite_address_low &4fd8 a9 1c LDA #&1c ; &1c00 = enemy_type_3_shift_3_sprites + &100 &4fda 38 SEC &4fdb e5 7c SBC &7c ; text_y # Use enemies in decreasing order of rank &4fdd 85 73 STA &73 ; sprite_address_high &4fdf 20 7d 34 JSR &347d ; plot_enemy_sprite_with_overwrite &4fe2 a2 00 LDX #&00 ; restore_screen_addresses_loop &4fe4 68 PLA ; address byte &4fe5 95 70 STA &70,X ; screen_address &4fe7 e8 INX &4fe8 e0 04 CPX #&04 &4fea d0 f8 BNE &4fe4 ; restore_screen_addresses_loop ; skip_sprite &4fec a5 7d LDA &7d ; text_x &4fee d0 01 BNE &4ff1 ; not_at_left_edge &4ff0 60 RTS ; not_at_left_edge &4ff1 20 00 50 JSR &5000 ; shift_text_left_eight_pixels &4ff4 c6 7d DEC &7d ; text_x &4ff6 d0 8e BNE &4f86 ; animate_demo_text &4ff8 a5 7e LDA &7e ; text_length &4ffa d0 01 BNE &4ffd ; to_animate_demo_text &4ffc 60 RTS ; to_animate_demo_text &4ffd 4c 86 4f JMP &4f86 ; animate_demo_text ; shift_text_left_eight_pixels &5000 a9 08 LDA #&08 &5002 85 62 STA &62 ; count &5004 a5 7c LDA &7c ; text_y &5006 38 SEC &5007 e9 02 SBC #&02 &5009 85 7f STA &7f ; previous_group ; animate_demo_text_loop &500b 20 19 50 JSR &5019 ; shift_text_left_one_pixel &500e 20 0b 36 JSR &360b ; check_for_sound_keys_and_escape &5011 20 95 4d JSR &4d95 ; check_for_game_start_keys &5014 c6 62 DEC &62 ; count &5016 d0 f3 BNE &500b ; animate_demo_text_loop &5018 60 RTS ; shift_text_left_one_pixel &5019 a0 00 LDY #&00 &501b a6 7f LDX &7f ; previous_group &501d bd 00 1f LDA &1f00,X ; group_addresses_low &5020 85 72 STA &72 ; end_screen_address_low &5022 bd 20 1f LDA &1f20,X ; group_addresses_high &5025 85 73 STA &73 ; end_screen_address_high &5027 e8 INX # Consider the next group &5028 bd 00 1f LDA &1f00,X ; group_addresses_low &502b 38 SEC &502c e9 01 SBC #&01 # to calculate the end of this group &502e 85 70 STA &70 ; screen_address_low &5030 bd 20 1f LDA &1f20,X ; group_addresses_high &5033 e9 00 SBC #&00 &5035 85 71 STA &71 ; screen_address_high &5037 20 a7 4a JSR &4aa7 ; wait_for_vsync ; shift_text_row_loop &503a a9 00 LDA #&00 &503c 85 74 STA &74 ; right_pixel ; shift_text_byte_loop &503e b1 70 LDA (&70),Y ; screen_address &5040 48 PHA ; byte &5041 0a ASL A &5042 29 ee AND #&ee ; 3330 &5044 05 74 ORA &74 ; right_pixel &5046 91 70 STA (&70),Y ; screen_address &5048 68 PLA ; byte &5049 29 88 AND #&88 ; 3000 &504b 4a LSR A &504c 4a LSR A &504d 4a LSR A &504e 85 74 STA &74 ; right_pixel &5050 a5 70 LDA &70 ; screen_address_low &5052 38 SEC &5053 e9 08 SBC #&08 # Move left four pixels &5055 85 70 STA &70 ; screen_address_low &5057 b0 02 BCS &505b ; skip_page &5059 c6 71 DEC &71 ; screen_address_high ; skip_page &505b a5 70 LDA &70 ; screen_address_low &505d c5 72 CMP &72 ; end_screen_address_low &505f a5 71 LDA &71 ; screen_address_high &5061 e5 73 SBC &73 ; end_screen_address_high &5063 b0 d9 BCS &503e ; shift_text_byte_loop &5065 a5 70 LDA &70 ; screen_address_low &5067 18 CLC &5068 69 3f ADC #&3f &506a 85 70 STA &70 ; screen_address_low &506c e6 71 INC &71 ; screen_address_high &506e 90 02 BCC &5072 ; skip_page &5070 e6 71 INC &71 ; screen_address_high ; skip_page &5072 aa TAX &5073 29 03 AND #&03 &5075 c9 03 CMP #&03 &5077 d0 c1 BNE &503a ; shift_text_row_loop &5079 8a TXA &507a 29 04 AND #&04 &507c f0 01 BEQ &507f ; delay_before_shifting_next_row &507e 60 RTS ; delay_before_shifting_next_row &507f a0 00 LDY #&00 &5081 a2 06 LDX #&06 ; delay_loop &5083 ea NOP &5084 88 DEY &5085 d0 fc BNE &5083 ; delay_loop &5087 ca DEX &5088 d0 f9 BNE &5083 ; delay_loop &508a 4c 3a 50 JMP &503a ; shift_text_row_loop ; unused &508d 60 RTS ; start_demo &508e 20 a5 35 JSR &35a5 ; wipe_game_area &5091 20 83 51 JSR &5183 ; initialise_player &5094 a2 00 LDX #&00 &5096 8e 0c 04 STX &040c ; number_of_active_enemies &5099 8e fa 05 STX &05fa ; player_maximum_size_of_regular_attack_minus_one &509c 8e 30 04 STX &0430 ; player_explosion_timer &509f 8e 31 04 STX &0431 ; unused # Unused variable &50a2 8e 34 04 STX &0434 ; new_life_cooldown &50a5 ca DEX &50a6 8e fb 05 STX &05fb ; player_attack_frequency &50a9 a9 03 LDA #&03 &50ab 8d ff 05 STA &05ff ; player_leaders_to_remove_minus_one &50ae 4c 1f 42 JMP &421f ; start_wave ; switch_to_tape # Used unrelocated &5db1 a2 20 LDX #&20 ; &3620 = tape_command &5db3 a0 36 LDY #&36 &5db5 4c f7 ff JMP &fff7 ; OSCLI # *TAPE ; set_shiftlock &50b8 a9 ca LDA #&ca ; Read/Write Keyboard Status &50ba a2 20 LDX #&20 ; Shift lock &50bc a0 cf LDY #&cf &50be 4c f4 ff JMP &fff4 ; OSBYTE ; set_shiftlock_mos_0.10 &50c1 a9 20 LDA #&20 &50c3 85 d8 STA &d8 ; keyboardStatusFlags &50c5 60 RTS ; check_for_collision_with_enemy_bombs &50c6 a0 00 LDY #&00 # Bug: only checks first bomb ; check_for_collision_with_enemy_bombs_loop &50c8 b9 a0 04 LDA &04a0,Y ; enemy_bombs_pixel_value &50cb f0 48 BEQ &5115 ; consider_next_bomb # Is there a bomb in this slot? &50cd 25 78 AND &78 ; collision_pixel_value &50cf f0 44 BEQ &5115 ; consider_next_bomb # If so, is it in the same pixel horizontally? &50d1 b9 c0 04 LDA &04c0,Y ; enemy_bombs_x &50d4 c5 74 CMP &74 ; collision_x &50d6 d0 3d BNE &5115 ; consider_next_bomb &50d8 b9 b0 04 LDA &04b0,Y ; enemy_bombs_group &50db 0a ASL A &50dc 0a ASL A &50dd 0a ASL A &50de 85 03 STA &03 ; bomb_y &50e0 b9 80 04 LDA &0480,Y ; enemy_bombs_screen_address_low &50e3 29 07 AND #&07 &50e5 05 03 ORA &03 ; bomb_y &50e7 85 03 STA &03 ; bomb_y &50e9 a5 75 LDA &75 ; collision_y &50eb 38 SEC &50ec e5 03 SBC &03 ; bomb_y &50ee 90 25 BCC &5115 ; consider_next_bomb # If so, has it collided vertically? &50f0 c9 06 CMP #&06 &50f2 b0 21 BCS &5115 ; consider_next_bomb &50f4 a9 00 LDA #&00 &50f6 99 a0 04 STA &04a0,Y ; enemy_bombs_pixel_value # Set to zero to remove enemy bomb &50f9 b9 80 04 LDA &0480,Y ; enemy_bombs_screen_address_low &50fc 85 70 STA &70 ; screen_address_low &50fe b9 90 04 LDA &0490,Y ; enemy_bombs_screen_address_high &5101 85 71 STA &71 ; screen_address_high &5103 a0 00 LDY #&00 &5105 a2 05 LDX #&05 ; unplot_enemy_bomb_loop &5107 a5 78 LDA &78 ; collision_pixel_value &5109 49 ff EOR #&ff &510b 31 70 AND (&70),Y ; screen_address # Unplot enemy bomb &510d 91 70 STA (&70),Y ; screen_address &510f 20 60 43 JSR &4360 ; move_down_a_pixel &5112 ca DEX &5113 d0 f2 BNE &5107 ; unplot_enemy_bomb_loop ; consider_next_bomb &5115 88 DEY &5116 10 b0 BPL &50c8 ; check_for_collision_with_enemy_bombs_loop &5118 60 RTS ; plot_random_player_explosion &5119 20 c8 3e JSR &3ec8 ; rnd &511c 85 77 STA &77 ; random_address_low &511e 20 c8 3e JSR &3ec8 ; rnd &5121 85 78 STA &78 ; random_address_high &5123 a9 19 LDA #&19 &5125 85 74 STA &74 ; height &5127 a2 72 LDX #&72 ; sprite_address &5129 a0 00 LDY #&00 &512b f0 4b BEQ &5178 ; check_for_bottom # Always branches ; plot_random_player_explosion_row_loop &512d a9 03 LDA #&03 &512f 85 75 STA &75 ; width ; plot_random_player_explosion_column_loop &5131 a1 00 LDA (&00,X) ; sprite_address - &72 # Get a byte of sprite data: byte carry &5133 0a ASL A # 6543210. 7 &5134 2a ROL A # 543210.7 6 &5135 2a ROL A # 43210.76 5 &5136 2a ROL A # 3210.765 4 &5137 48 PHA ; rotated byte &5138 29 f0 AND #&f0 # 3210.... &513a 85 20 STA &20 ; nibble &513c 68 PLA ; rotated byte &513d 2a ROL A # 210.7654 3 &513e 29 0f AND #&0f # ....7654 &5140 05 20 ORA &20 ; nibble # Swap the nibbles, then OR with original byte &5142 01 00 ORA (&00,X) ; sprite_address - &72 # i.e. set all non-black pixels to colour 3 &5144 21 05 AND (&05,X) ; random_address - &72 # AND with random byte to apply random colours &5146 91 70 STA (&70),Y ; screen_address &5148 e6 72 INC &72 ; sprite_address_low &514a d0 02 BNE &514e ; skip_sprite_page &514c e6 73 INC &73 ; sprite_address_high ; skip_sprite_page &514e e6 77 INC &77 ; random_address_low &5150 98 TYA &5151 18 CLC &5152 69 08 ADC #&08 # Move right four pixels &5154 a8 TAY &5155 c6 75 DEC &75 ; width &5157 d0 d8 BNE &5131 ; plot_random_player_explosion_column_loop &5159 c6 74 DEC &74 ; height &515b f0 25 BEQ &5182 ; leave &515d a0 00 LDY #&00 &515f e6 70 INC &70 ; screen_address_low &5161 d0 02 BNE &5165 ; skip_screen_page &5163 e6 71 INC &71 ; screen_address_high ; skip_screen_page &5165 a5 70 LDA &70 ; screen_address_low &5167 29 07 AND #&07 &5169 d0 c2 BNE &512d ; plot_random_player_explosion_row_loop &516b 18 CLC &516c a5 70 LDA &70 ; screen_address_low &516e 69 38 ADC #&38 # Move down a group &5170 85 70 STA &70 ; screen_address_low &5172 a5 71 LDA &71 ; screen_address_high &5174 69 01 ADC #&01 &5176 85 71 STA &71 ; screen_address_high ; check_for_bottom &5178 a5 70 LDA &70 ; screen_address_low &517a c9 c0 CMP #&c0 ; &7ec0 = group &1d &517c a5 71 LDA &71 ; screen_address_high &517e e9 7e SBC #&7e &5180 90 ab BCC &512d ; plot_random_player_explosion_row_loop ; leave &5182 60 RTS ; initialise_player &5183 a9 4b LDA #&4b &5185 85 84 STA &84 ; player_x &5187 a9 1c LDA #&1c ; &1c00 = player_shift_0_sprite &5189 85 83 STA &83 ; player_sprite_address_high &518b a9 00 LDA #&00 &518d 85 40 STA &40 ; unused_40 # Unnecessary code; variable only used in unused code &518f 85 82 STA &82 ; player_sprite_address_low &5191 a9 7a LDA #&7a ; &7a50 = group &19 + &90 &5193 85 81 STA &81 ; player_screen_address_high &5195 a9 50 LDA #&50 &5197 85 80 STA &80 ; player_screen_address_low &5199 20 3d 52 JSR &523d ; reset_laser_without_unplotting &519c a2 03 LDX #&03 ; copy_player_screen_and_sprite_addresses_loop &519e b5 80 LDA &80,X ; player_screen_address &51a0 95 70 STA &70,X ; screen_address &51a2 ca DEX &51a3 10 f9 BPL &519e ; copy_player_screen_and_sprite_addresses_loop &51a5 20 22 34 JSR &3422 ; plot_player_sprite &51a8 a2 00 LDX #&00 &51aa 8e 1c 04 STX &041c ; end_of_wave_cooldown # Set to zero to indicate not end of wave &51ad 8e 00 04 STX &0400 ; laser_active # Non-zero if laser active &51b0 ca DEX ; &ff &51b1 8e 01 04 STX &0401 ; laser_firing_suppressed # Set to non-zero to allow firing &51b4 a9 80 LDA #&80 &51b6 85 41 STA &41 ; unused_41 # Unnecessary code; variable only used in unused code &51b8 60 RTS ; play_sound_for_attacking_enemy &51b9 a9 06 LDA #&06 ; sound_6 &51bb 4c c8 4a JMP &4ac8 ; play_sound ; fire_laser &51be a9 00 LDA #&00 ; sound_0 &51c0 20 c8 4a JSR &4ac8 ; play_sound # Play sound for laser &51c3 a9 01 LDA #&01 ; sound_1 &51c5 20 c8 4a JSR &4ac8 ; play_sound ; update_laser &51c8 ad 02 04 LDA &0402 ; laser_screen_address_low &51cb 29 04 AND #&04 &51cd f0 0b BEQ &51da ; is_aligned ; not_aligned &51cf ad 02 04 LDA &0402 ; laser_screen_address_low &51d2 29 f8 AND #&f8 &51d4 8d 02 04 STA &0402 ; laser_screen_address_low &51d7 4c f0 51 JMP &51f0 ; to_plot_top_of_laser_with_collision_check ; is_aligned &51da ce 05 04 DEC &0405 ; laser_group &51dd 30 58 BMI &5237 ; reset_laser &51df ad 02 04 LDA &0402 ; laser_screen_address_low &51e2 38 SEC &51e3 e9 3c SBC #&3c &51e5 8d 02 04 STA &0402 ; laser_screen_address_low &51e8 ad 03 04 LDA &0403 ; laser_screen_address_high &51eb e9 01 SBC #&01 &51ed 8d 03 04 STA &0403 ; laser_screen_address_high ; to_plot_top_of_laser_with_collision_check &51f0 4c fc 34 JMP &34fc ; plot_top_of_laser_with_collision_check ; handle_laser_collision # &70-71 is laser screen address, Y is collision offset &51f3 98 TYA &51f4 18 CLC &51f5 65 70 ADC &70 ; screen_address_low &51f7 85 76 STA &76 ; collision_screen_address_low &51f9 a5 71 LDA &71 ; screen_address_high &51fb 69 00 ADC #&00 &51fd 85 77 STA &77 ; collision_screen_address_high &51ff a5 72 LDA &72 ; laser_pixel_value &5201 85 78 STA &78 ; collision_pixel_value &5203 ae 05 04 LDX &0405 ; laser_group &5206 86 7a STX &7a ; collision_group &5208 a5 76 LDA &76 ; collision_screen_address_low &520a 38 SEC &520b fd 00 1f SBC &1f00,X ; group_addresses_low &520e a8 TAY &520f a5 77 LDA &77 ; collision_screen_address_high &5211 fd 20 1f SBC &1f20,X ; group_addresses_high &5214 4a LSR A &5215 98 TYA &5216 6a ROR A &5217 4a LSR A &5218 4a LSR A &5219 85 74 STA &74 ; collision_x &521b ad 05 04 LDA &0405 ; laser_group &521e 0a ASL A &521f 0a ASL A &5220 0a ASL A &5221 85 75 STA &75 ; collision_y &5223 a5 76 LDA &76 ; collision_screen_address_low &5225 29 07 AND #&07 &5227 05 75 ORA &75 ; collision_y &5229 85 75 STA &75 ; collision_y &522b 20 7c 43 JSR &437c ; check_for_collision_with_enemies &522e 20 a7 4a JSR &4aa7 ; wait_for_vsync &5231 20 66 35 JSR &3566 ; unplot_laser &5234 4c 3d 52 JMP &523d ; reset_laser_without_unplotting ; reset_laser &5237 20 66 35 JSR &3566 ; unplot_laser &523a 20 d2 34 JSR &34d2 ; unplot_bottom_of_laser ; reset_laser_without_unplotting &523d a9 00 LDA #&00 &523f 8d 00 04 STA &0400 ; laser_active # Non-zero if laser active &5242 8d 01 04 STA &0401 ; laser_firing_suppressed # Set to zero to suppress firing &5245 a9 02 LDA #&02 ; sound_2 &5247 20 c8 4a JSR &4ac8 ; play_sound # Silence channel 1 &524a a9 03 LDA #&03 ; sound_3 &524c 20 c8 4a JSR &4ac8 ; play_sound # Silence channel 0 ; reset_laser_without_unplotting_or_sound &524f 38 SEC &5250 a5 80 LDA &80 ; player_screen_address_low &5252 e9 38 SBC #&38 &5254 8d 02 04 STA &0402 ; laser_screen_address_low &5257 a5 81 LDA &81 ; player_screen_address_high &5259 e9 01 SBC #&01 # Move up a group &525b 8d 03 04 STA &0403 ; laser_screen_address_high &525e a5 82 LDA &82 ; player_sprite_address_low &5260 29 03 AND #&03 &5262 aa TAX &5263 bd 68 1e LDA &1e68,X ; laser_mask_values &5266 8d 04 04 STA &0404 ; laser_mask &5269 a9 18 LDA #&18 &526b 8d 05 04 STA &0405 ; laser_group &526e 4c 22 35 JMP &3522 ; plot_laser ; consider_firing_laser &5271 ad 00 04 LDA &0400 ; laser_active # Non-zero if laser active &5274 f0 01 BEQ &5277 ; laser_not_active &5276 60 RTS ; laser_not_active &5277 20 51 32 JSR &3251 ; check_for_firing # Returns X non-zero if fire pressed &527a 8a TXA &527b d0 07 BNE &5284 ; fire_pressed &527d a9 ff LDA #&ff &527f 8d 01 04 STA &0401 ; laser_firing_suppressed # Set to non-zero to allow firing &5282 d0 cb BNE &524f ; reset_laser_without_unplotting_or_sound # Always branches ; fire_pressed &5284 ad 01 04 LDA &0401 ; laser_firing_suppressed # Zero if firing suppressed &5287 f0 c6 BEQ &524f ; reset_laser_without_unplotting_or_sound &5289 ce 00 04 DEC &0400 ; laser_active # Set to non-zero to indicate laser active &528c 4c be 51 JMP &51be ; fire_laser ; check_if_enemy_is_leader # Unused code &528f c0 16 CPY #&16 ; ENEMY_FIRST_LEADER &5291 b0 02 BCS &5295 ; second_check &5293 38 SEC # Leave with carry set if not leader enemy ; leave &5294 60 RTS ; second_check &5295 c0 1c CPY #&1c ; ENEMY_LAST_LEADER + 1 &5297 b0 fb BCS &5294 ; leave &5299 60 RTS # Leave with carry clear if leader enemy ; find_escorting_enemies # Called with Y = passive slot between &16 and &1b &529a a9 03 LDA #&03 &529c 85 73 STA &73 ; count &529e a2 00 LDX #&00 ; find_escorting_enemies_loop &52a0 84 74 STY &74 ; enemy_slot &52a2 b9 0c 31 LDA &310c,Y ; escorts_for_leaders_table - ENEMY_FIRST_LEADER + 1 &52a5 f0 14 BEQ &52bb ; consider_next_companion &52a7 a8 TAY &52a8 b9 c8 05 LDA &05c8,Y ; passive_enemies_group # &ff if not present &52ab c9 ff CMP #&ff &52ad f0 0c BEQ &52bb ; consider_next_companion &52af c9 00 CMP #&00 &52b1 30 03 BMI &52b6 ; set_escort_as_not_present # Negative if escort is already active &52b3 98 TYA &52b4 d0 02 BNE &52b8 ; set_escorting_enemies_passive_slot # Zero if formation doesn't have escort here ; set_escort_as_not_present &52b6 a9 00 LDA #&00 # Set to zero to indicate escort not present ; set_escorting_enemies_passive_slot &52b8 95 70 STA &70,X ; escorting_enemies_passive_slot # Otherwise store slot of escort &52ba e8 INX ; consider_next_companion &52bb a4 74 LDY &74 ; enemy_slot &52bd c8 INY &52be c6 73 DEC &73 ; count &52c0 d0 de BNE &52a0 ; find_escorting_enemies_loop &52c2 88 DEY &52c3 88 DEY &52c4 88 DEY &52c5 60 RTS # Leave with X = number of escorting enemies ; get_random_leader_enemy &52c6 a2 00 LDX #&00 &52c8 a0 16 LDY #&16 ; ENEMY_FIRST_LEADER ; count_leader_enemies_loop &52ca b9 c8 05 LDA &05c8,Y ; passive_enemies_group # Top bit set if not present or active &52cd 30 01 BMI &52d0 ; skip_counting &52cf e8 INX ; skip_counting &52d0 c8 INY &52d1 c0 1c CPY #&1c ; ENEMY_LAST_LEADER + 1 &52d3 d0 f5 BNE &52ca ; count_leader_enemies_loop &52d5 8a TXA &52d6 d0 01 BNE &52d9 ; leader_enemies_present &52d8 60 RTS # Leave with zero to indicate no leader enemies ; leader_enemies_present &52d9 85 70 STA &70 ; count ; get_random_leader_enemy &52db 20 c8 3e JSR &3ec8 ; rnd &52de 29 07 AND #&07 &52e0 f0 f9 BEQ &52db ; get_random_leader_enemy &52e2 c5 70 CMP &70 ; count &52e4 f0 02 BEQ &52e8 ; use_value &52e6 b0 f3 BCS &52db ; get_random_leader_enemy ; use_value &52e8 85 70 STA &70 ; random &52ea a0 16 LDY #&16 ; ENEMY_FIRST_LEADER &52ec a2 00 LDX #&00 ; find_leader_enemy_loop &52ee b9 c8 05 LDA &05c8,Y ; passive_enemies_group # Top bit set if not present or active &52f1 30 05 BMI &52f8 ; consider_next_enemy &52f3 e8 INX &52f4 e4 70 CPX &70 ; random &52f6 f0 08 BEQ &5300 ; leave_with_x ; consider_next_enemy &52f8 c8 INY &52f9 c0 1c CPY #&1c ; ENEMY_LAST_LEADER + 1 &52fb d0 f1 BNE &52ee ; find_leader_enemy_loop &52fd 00 BRK # Abort if enemy couldn't be found; should never happen &52fe 00 BRK &52ff 00 BRK ; leave_with_x &5300 8a TXA &5301 60 RTS # Leave with A = random leader enemy offset ; play_tune &5302 ad 38 04 LDA &0438 ; sound_muted # Non-zero if sound muted &5305 f0 01 BEQ &5308 ; not_muted &5307 60 RTS ; not_muted &5308 20 e1 4a JSR &4ae1 ; flush_buffers &530b a9 06 LDA #&06 ; envelope_6 # Use tune envelopes &530d 20 ba 4a JSR &4aba ; define_envelope &5310 a9 07 LDA #&07 ; envelope_7 &5312 20 ba 4a JSR &4aba ; define_envelope &5315 a9 08 LDA #&08 ; envelope_8 &5317 20 ba 4a JSR &4aba ; define_envelope &531a a0 00 LDY #&00 &531c 84 70 STY &70 ; tune_sound_address_low &531e a9 24 LDA #&24 ; &2400 = tune_sound_data &5320 85 71 STA &71 ; tune_sound_address_high ; play_tune_loop &5322 a6 70 LDX &70 ; tune_sound_address_low &5324 a4 71 LDY &71 ; tune_sound_address_high &5326 a9 07 LDA #&07 ; Generate a sound &5328 20 f1 ff JSR &fff1 ; OSWORD &532b a5 70 LDA &70 ; tune_sound_address_low &532d 18 CLC &532e 69 08 ADC #&08 &5330 85 70 STA &70 ; tune_sound_address_low &5332 90 02 BCC &5336 &5334 e6 71 INC &71 ; tune_sound_address_high &5336 a5 70 LDA &70 ; tune_sound_address_low &5338 c9 b0 CMP #&b0 ; &26b0 = end_of_tune_sound_data &533a a5 71 LDA &71 ; tune_sound_address_high &533c e9 26 SBC #&26 &533e 90 e2 BCC &5322 ; play_tune_loop &5340 a9 5a LDA #&5a # Wait for 90 frames after last note is played &5342 85 7b STA &7b ; count ; delay_loop &5344 20 a7 4a JSR &4aa7 ; wait_for_vsync &5347 c6 7b DEC &7b ; count &5349 d0 f9 BNE &5344 ; delay_loop &534b 20 e1 4a JSR &4ae1 ; flush_buffers &534e a9 00 LDA #&00 ; envelope_0 # Use game envelopes &5350 20 ba 4a JSR &4aba ; define_envelope &5353 a9 01 LDA #&01 ; envelope_1 &5355 20 ba 4a JSR &4aba ; define_envelope &5358 a9 02 LDA #&02 ; envelope_2 &535a 20 ba 4a JSR &4aba ; define_envelope &535d a9 03 LDA #&03 ; envelope_3 &535f 20 ba 4a JSR &4aba ; define_envelope &5362 60 RTS ; unused # &5363 - &539f is a copy of &466d - &46a9 &5363 a5 70 LDA &70 &5365 29 07 AND #&07 &5367 c9 03 CMP #&03 &5369 90 0d BCC &5378 &536b a5 70 LDA &70 &536d 18 CLC &536e 69 38 ADC #&38 &5370 85 72 STA &72 &5372 a5 71 LDA &71 &5374 69 01 ADC #&01 &5376 85 73 STA &73 &5378 a5 72 LDA &72 &537a 18 CLC &537b 69 05 ADC #&05 &537d 85 72 STA &72 &537f 90 02 BCC &5383 &5381 e6 73 INC &73 &5383 c9 c0 CMP #&c0 &5385 a5 73 LDA &73 &5387 e9 7e SBC #&7e &5389 b0 06 BCS &5391 &538b b1 72 LDA (&72),Y &538d 05 74 ORA &74 &538f 91 72 STA (&72),Y &5391 a4 7c LDY &7c &5393 60 RTS &5394 ac 46 04 LDY &0446 &5397 f0 15 BEQ &53ae &5399 a9 1f LDA #&1f &539b 20 ee ff JSR &ffee ; OSWRCH &539e a9 00 LDA #&00 ; movement_and_firing_check_routines_addresses_table &53a0 32 32 ; &3232 = check_for_keyboard_movement &53a2 03 32 ; &3203 = check_for_keyboard_fire &53a4 8e 32 ; &328e = check_for_joystick_one_movement &53a6 0e 32 ; &320e = check_for_joystick_one_fire &53a8 92 32 ; &3292 = check_for_joystick_two_movement &53aa 1b 32 ; &321b = check_for_joystick_two_fire &53ac 54 32 ; &3254 = check_for_demo_movement &53ae 28 32 ; &3228 = check_for_demo_fire ; unused # &53b0 - &53cb is a copy of &46ba - &46d7 &53b0 d0 fc BNE &53ae &53b2 a9 08 LDA #&08 &53b4 20 ee ff JSR &ffee ; OSWRCH &53b7 a9 30 LDA #&30 &53b9 4c ee ff JMP &ffee ; OSWRCH &53bc a0 03 LDY #&03 &53be ad 46 04 LDA &0446 &53c1 f0 eb BEQ &53ae &53c3 b1 70 LDA (&70),Y &53c5 08 PHP &53c6 d0 02 BNE &53ca &53c8 a9 f0 LDA #&f0 &53ca 18 CLC &53cb 69 ADC #.. ; group_leader_scoring_table ; 0 1 2 escorts killed &53cc 01 02 08 # Score 150, 200 and 800 for group leader (see &4423) ; unused &53cf 00 ; relocate_binary # Used unrelocated &60d0 20 b1 5d JSR &5db1 ; switch_to_tape &60d3 a0 00 LDY #&00 ; move_1900_to_19ff_loop # Move &1900 - &19ff to &0c00 - &0cff &60d5 b9 00 19 LDA &1900,Y &60d8 99 00 0c STA &0c00,Y &60db 88 DEY &60dc d0 f7 BNE &60d5 ; move_1900_to_19ff_loop &60de 84 70 STY &70 ; target_address_low &60e0 84 72 STY &72 ; source_address_low &60e2 a9 0e LDA #&0e &60e4 85 71 STA &71 ; target_address_high &60e6 a9 1b LDA #&1b &60e8 85 73 STA &73 ; source_address_high &60ea a2 58 LDX #&58 ; move_1b00_to_64ff_loop # Move &1b00 - &64ff to &0e00 - &57ff &60ec b1 72 LDA (&72),Y ; source_address &60ee 91 70 STA (&70),Y ; target_address &60f0 c8 INY &60f1 d0 f9 BNE &60ec ; move_1b00_to_64ff_loop &60f3 e6 71 INC &71 ; target_address_high &60f5 e6 73 INC &73 ; source_address_high &60f7 e4 71 CPX &71 ; target_address_high &60f9 d0 f1 BNE &60ec ; move_1b00_to_64ff_loop &60fb 4c da 49 JMP &49da ; relocated_entry_point ; unused &53fe 18 08 ; instructions_screen_data &5400 83 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. " &5410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; "... Acornsoft Presents.... " &5420 20 20 20 20 20 20 20 20 83 9d 84 20 20 41 63 6f ; ".. " &5430 72 6e 73 6f 66 74 20 20 50 72 65 73 65 6e 74 73 ; "...................................... " &5440 2e 2e 2e 2e 20 20 20 20 20 20 20 20 20 20 20 20 ; "...................................... " &5450 94 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; "...................................... " &5460 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. " &5470 20 20 20 20 20 20 20 20 94 9d 93 b6 a3 a3 b4 e8 ; ".. " &5480 a3 a3 e9 a0 b6 a3 e9 a0 b6 a3 a3 b4 ea a3 ab f4 ; ".. " &5490 a0 ea a0 b6 a3 a3 b4 ea ab b4 ea a0 ff a3 20 20 ; " " &54a0 94 9d 93 b7 a3 a3 b5 ea ef b3 a1 a0 b5 a0 a0 a0 ; " " &54b0 b7 a3 a3 b5 ea a0 f8 a7 a0 fe a0 b7 a3 a3 b5 ea ; " .Options:- . ESCAPE .returns to menu " &54c0 a0 f5 ea a0 a3 ff 20 20 94 9d 93 a0 a0 a0 b5 ea ; " Q .turns sound off " &54d0 a0 ab a4 a0 e5 f0 f0 b0 a0 a0 a0 b5 aa ae a1 a0 ; " S .turns sound on " &54e0 a0 af a0 a0 a0 a0 b5 e2 f0 f2 f3 f0 f0 ff 20 20 ; " . 1..selects 1-player game " &54f0 94 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " . 2..selects 2-player game " &5500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " . fire . .to joystick menu " &5510 20 20 20 20 20 20 20 20 83 9d 20 20 20 20 20 20 ; " " &5520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " " &5530 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " " &5540 83 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " .Controls:-. CAPS LOCK .moves left " &5550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " CTRL . moves right " &5560 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " RETURN .fires " &5570 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " " &5580 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " " &5590 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; " " &55a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &55b0 20 20 20 20 20 20 20 20 20 20 82 4f 70 74 69 6f &55c0 6e 73 3a 2d 20 87 20 45 53 43 41 50 45 20 20 81 &55d0 72 65 74 75 72 6e 73 20 74 6f 20 6d 65 6e 75 20 &55e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 51 &55f0 20 81 74 75 72 6e 73 20 73 6f 75 6e 64 20 6f 66 &5600 66 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &5610 20 20 20 20 20 20 20 53 20 81 74 75 72 6e 73 20 &5620 73 6f 75 6e 64 20 6f 6e 20 20 20 20 20 20 20 20 &5630 20 20 20 20 20 20 20 20 20 20 20 20 20 88 20 31 &5640 89 83 73 65 6c 65 63 74 73 20 31 2d 70 6c 61 79 &5650 65 72 20 67 61 6d 65 20 20 20 20 20 20 20 20 20 &5660 20 20 20 20 20 88 20 32 89 83 73 65 6c 65 63 74 &5670 73 20 32 2d 70 6c 61 79 65 72 20 67 61 6d 65 20 &5680 20 20 20 20 20 20 20 20 20 20 20 20 20 88 20 66 &5690 69 72 65 20 89 20 83 74 6f 20 6a 6f 79 73 74 69 &56a0 63 6b 20 6d 65 6e 75 20 20 20 20 20 20 20 20 20 &56b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &56c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &56d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &56e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &56f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &5700 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &5710 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &5720 20 20 82 43 6f 6e 74 72 6f 6c 73 3a 2d 87 20 43 &5730 41 50 53 20 4c 4f 43 4b 20 81 6d 6f 76 65 73 20 &5740 6c 65 66 74 20 20 20 20 20 20 20 20 20 20 20 20 &5750 20 20 20 20 20 20 20 43 54 52 4c 20 81 20 20 20 &5760 20 20 6d 6f 76 65 73 20 72 69 67 68 74 20 20 20 &5770 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 52 &5780 45 54 55 52 4e 20 20 20 20 81 66 69 72 65 73 20 &5790 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &57a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &57b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &57c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &57d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &57e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &57f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20