YOK-dfa Posted March 3, 2009 Share Posted March 3, 2009 Not sure if this is the right place (mods feel free to move this to the appropriate place), but here goes. A long time ago i decided to reverse engineer Satellite Attack (#34) for the G7000 Videopac console to see if i could learn anything from it. Unfortunately i never really finished the work, but i found this version when i was cleaning an old external harddrive. I'm posting the code + my comments here, maybe someone finds it interesting to study/finish it exram_pos_04 .equ 004h ; highscore pos 4 x1000 exram_pos_05 .equ 005h ; highscore pos 3 x100 exram_pos_06 .equ 006h ; highscore pos 2 x10 exram_pos_07 .equ 007h ; highscore pos 1 exram_pos_08 .equ 004h ; '[rightarrow]' exram_pos_09 .equ 005h ; '?' - player name char 1 exram_pos_0a .equ 006h ; '?' - player name char 2 exram_pos_0b .equ 007h ; '?' - player name char 3 exram_pos_0c .equ 004h ; '?' - player name char 4 exram_pos_0d .equ 005h ; '?' - player name char 5 exram_pos_0e .equ 006h ; '?' - player name char 6 exram_pos_0f .equ 007h ; '[space]' exram_pos_10 .equ 010h ; score pos 4 x1000 exram_pos_11 .equ 011h ; score pos 3 x100 exram_pos_12 .equ 012h ; score pos 2 x10 exram_pos_13 .equ 013h ; score pos 1 exram_pos_22 .equ 022h ; Countdown timer for changing fire direction (starts at ; either 0x04 or 0x10) exram_pos_23 .equ 023h ; Fire direction (white dot in shield). See figure: ; 12 ; 11|13 ; 10 | 14 ; 9 | 15 ; 8 ---- X ---- 0 ; 7 | 1 ; 6 | 2 ; 5 | 3 ; 4 iram_pos_22 .equ 022h iram_pos_24 .equ 024h ; length of player name ; bit 7 set ?? iram_pos_25 .equ 025h ; counter (??). Used for choosing new position of satellites iram_pos_26 .equ 026h ; used as counter for number of player name flashes. iram_pos_27 .equ 027h ; is set to 0xc4 when R3(RB0) = zero in SetNewFireDirection ; set to 56 after keypress for name, ; set to AC after hitting satellite, ; set to A4 after player fire. ; set to F5 after 2b increment (and smaller then 10) ; set to 0 after bit 1 is zero in 3rd byte sprite 0. ; set to 4a during flashing of player name after end game iram_pos_2d .equ 02dh ; used in CheckPlayerHit as counter for flashing speed of player name ; used in UpdateStatusbar iram_pos_3c .equ 03ch ; direction of movement for satellite 0 iram_pos_3b .equ 03bh ; direction of movement for satellite 1 iram_pos_3a .equ 03ah ; direction of movement for satellite 2 iram_pos_39 .equ 039h ; direction of movement for satellite 3 iram_pos_38 .equ 038h ; direction of movement for satellite 4 iram_pos_37 .equ 037h ; direction of movement for satellite 5 iram_pos_36 .equ 036h ; direction of movement for satellite 6 iram_pos_35 .equ 035h ; direction of movement for satellite 7 iram_pos_34 .equ 034h ; direction of movement for satellite 8 iram_pos_33 .equ 033h ; direction of movement for satellite 9 ------- iram_collision .equ 03Dh vdc_table_01 .equ 07Ch vdc_table_03 .equ 07Ah ; bit 0 set? player hit ; bit 1 set? new highscore animation is busy ; bit 4 in CollisionDetected vdc_table_06 .equ 077h vdc_table_0A .equ 073h vdc_table_0E .equ 06Fh vdc_table_10 .equ 06Dh 0400: [ 44 C3 ] JMP selectgame ; Selectgame 0402: [ 04 09 ] JMP irq ; irq 0404: [ 93 ] RETR ; time 0405: [ 00 ] NOP 0406: [ C4 00 ] JMP vsync ; vsync 0408: [ A4 00 ] JMP 500 ; start 040A: [ FC ] MOV A, R4 ; soundirq. r4 = current tune position 040B: [ F2 0F ] JB7 0F ; bit 7 set? 040D: [ 04 44 ] JMP soundirq ; no, do sound irq 040F: [ E4 00 ] JMP play_custom_sound main_loop1: 0411: [ B8 25 ] MOV R0, iram_pos_25 ; 0413: [ 10 ] INC @R0 ; increment 0x25 in intram 0414: [ F5 ] SEL MB1 0415: [ 34 76 ] CALL move_player 0417: [ 14 2B ] CALL show_particles 0419: [ 54 00 ] CALL 200 041B: [ E5 ] SEL MB0 041C: [ 94 B0 ] CALL ChangeFireDirection 041E: [ 94 24 ] CALL test_for_collision 0420: [ A4 00 ] JMP main_loop2 player_dead: 0422: [ A4 7E ] JMP PlayerDiesAnimation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TestForCollision ; ; For each sprite the collision register is read. If a collision is detected, ; all characters are scanned to find out which character it collided with. ; Apriopriate action is taken (see subroutines for more info). ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0424: [ BF 01 ] MOV R7, 01 0426: [ B9 7A ] MOV R1, vdc_table_03 0428: [ 81 ] MOVX A, @R1 ; move VDC adres 03 to A. 0429: [ 12 22 ] JB0, player_dead ; bit 0 set? (player hit) 042B: [ 19 ] INC R1 ; r1 = 7b (sprite attribute byte) 042C: [ 94 3E ] CALL 43E 042E: [ BF 02 ] MOV R7, 02 0430: [ B9 77 ] MOV R1, vdc_table_06 0432: [ 94 3E ] CALL 43E ; do next sprite 0434: [ BF 03 ] MOV R7, 03 0436: [ B9 73 ] MOV R1, vdc_table_0A 0438: [ 94 3E ] CALL 43E ; do next sprite 043A: [ BF 04 ] MOV R7, 04 043C: [ B9 6F ] MOV R1, vdc_table_0E 043E: [ 81 ] MOVX A, @R1 ; move sprite attribute byte to A 043F: [ C6 70 ] JZ 70 ; zero? jmp 70 (RET) 0441: [ D3 18 ] XRL A, 18 ; XRL with 0x18 0443: [ 53 38 ] ANL A, 38 ; take only the color bytes 0445: [ C6 70 ] JZ 70 ; if color is orange (explosion), jmp 470 (ret) 0447: [ 19 ] INC R1 ; 0448: [ 19 ] INC R1 ; R1 sprite y-pos 0449: [ B8 3D ] MOV R0, iram_collision 044B: [ F0 ] MOV A, @R0 ; get collision register 044C: [ 67 ] RRC A ; right with carry 044D: [ EF 4C ] DJNZ R7 4C ; get right bit 044F: [ E6 70 ] JNC 70 ; no collision? jmp 70 (RET) 0451: [ BE 0C ] MOV R6, 0C ; R6 = 12 (number of chars = satellites) 0453: [ B8 6D ] MOV R0, vdc_table_10 ; start of char data in VDC mirror 0455: [ 94 5D ] CALL CheckCollision ; check for each char 0457: [ C8 ] DEC R0 0458: [ C8 ] DEC R0 0459: [ C8 ] DEC R0 045A: [ EE 55 ] DJNZ R6 55 ; next character 045C: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CheckCollision ; ; Checks for a collision between a sprite and a character. Both are said ; to have collided when the difference in vertical position is smaller than ; 12 and the horizontal difference is smaller than 7. ; ; IN: ; r0 holds pointer to character y-position ; r1 holds pointer to sprite y-position ; ; SIDE-EFFECTS: ; ; r0 is lowered by one. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 045D: [ F5 ] SEL MB1 045E: [ 74 00 ] CALL GetDistanceBetweenObjects ; calc y-distance between sprite and char 0460: [ E5 ] SEL MB0 0461: [ 03 F3 ] ADD A, F3 ; A holds distance. 0xF3 = -13 0463: [ C8 ] DEC R0 ; move to character x-position 0464: [ F6 70 ] JC 70 ; y-distance bigger then 0x0C? jmp RET 0466: [ C9 ] DEC R1 ; move to sprite x-position 0467: [ F5 ] SEL MB1 0468: [ 74 00 ] CALL GetDistanceBetweenObjects ; calc x-distance between sprite and char 046A: [ E5 ] SEL MB0 046B: [ 03 F8 ] ADD A, F8 ; 0xF8 = -7 046D: [ E6 71 ] JNC CollisionDetected ; x-distance not bigger then 0x07? 046F: [ 19 ] INC R1 ; yes it was. move to character y-position 0470: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CollisionDetected ; ; Takes action based on what objects collided. If player is hit then bit 0 of ; byte 3 of sprite 0 is set. Otherwise, hit object is removed and points are ; added to the score. ; ; IN: ; r0 holds pointer to character x-position ; r1 holds pointer to sprite x-position ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0471: [ F9 ] MOV A, R1 ; move sprite x-position to A 0472: [ D3 7C ] XRL A, 7C ; 0474: [ 96 80 ] JNZ, 80 ; is it 7C? (sprite 0 x-position)? no jmp 480 0476: [ B9 2B ] MOV R1, 2B ; player sprite has been hit 0478: [ F1 ] MOV A, @R1 ; move intram 2B to A 0479: [ 92 80 ] JB4, 80 ; bit 4 set? yes jmp 480 047B: [ B9 7A ] MOV R1, 7A 047D: [ 23 01 ] MOV A, 01 047F: [ 91 ] MOVX @R1, A ; move 0x01 to exram 7A -> player hit 0480: [ BC 38 ] MOV R4, 38 ; color is 0x07 (white) for explosion sprite 0482: [ B4 9D ] CALL InitExplosion ; set sprites to correct position for animation 0484: [ 23 F8 ] MOV A, F8 ; move f8 to char x,y-pos (char invisible) 0486: [ 90 ] MOVX @R0, A ; y-pos 0487: [ C8 ] DEC R0 0488: [ 90 ] MOVX @R0, A ; x-pos 0489: [ C8 ] DEC R0 048A: [ C8 ] DEC R0 048B: [ 80 ] MOVX A, @R0 ; get char attribute byte to find out what was hit 048C: [ BC 00 ] MOV R4, 00 ; 0 points 048E: [ D2 9A ] JB6 9A ; bit 6 set. Laser from UFO 0490: [ BC 0A ] MOV R4, 0A ; 10 points 0492: [ B2 9A ] JB5 9A ; bit 5 set. UFO 0494: [ BC 03 ] MOV R4, 03 ; 3 points 0496: [ 92 9A ] JB4, 9A ; bit 4 set. Homing satellite 0498: [ BC 01 ] MOV R4, 01 ; 1 point. Normal satellite. 049A: [ F5 ] SEL MB1 049B: [ 14 10 ] CALL StartFlyingShrapnel ; start explosion animation 049D: [ E5 ] SEL MB0 049E: [ BE 01 ] MOV R6, 01 04A0: [ 00 ] NOP ; add R4 to score starts here 04A1: [ B8 13 ] MOV R0, 13 ; move exram 13 to r0 04A3: [ 80 ] MOVX A, @R0 04A4: [ 6C ] ADD A, R4 ; add r4 (=1) 04A5: [ 90 ] MOVX @R0, A ; save in exram 13 04A6: [ 03 F6 ] ADD A, F6 04A8: [ E6 70 ] JNC 70 ; is not 10? jmp 470 (RET) 04AA: [ 90 ] MOVX @R0, A ; replace with 0 04AB: [ BC 01 ] MOV R4, 01 ; add one to next digit 04AD: [ C8 ] DEC R0 ; next digit 04AE: [ 84 A3 ] JMP 4A3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ChangeFireDirection ; ; If intram_pos_22 has reached zero, a new fire direction is calculated. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 04B0: [ B8 22 ] MOV R0, intram_pos_22 ; get timer 04B2: [ 80 ] MOVX A, @R0 ; 04B3: [ C6 B8 ] JZ SetNewFireDirection ; reached zero? 04B5: [ 07 ] DEC A ; nope, decrease with 1 04B6: [ 90 ] MOVX @R0, A ; store 04B7: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetNewFireDirection ; ; Calculates the new fire direction after movement. First part of the routine ; calculates how many steps (clock-wise direction) there are between the current ; fire direction and the movement direction (value in R7). Second part ; caculates the new delay stored in exram_pos_22. If the distance between old ; and new position >= 5 delay is 0x04. Otherwise new delay is 0x10 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 04B8: [ B9 00 ] MOV R1, 00 04BA: [ 74 8F ] CALL getjoystick ; test joystick 0 (r1 = 0) 04BC: [ FA ] MOV A, R2 ; x-axis to R2 04BD: [ 4B ] ORL A, R3 ; OR with y-axis (r3) 04BE: [ C6 FD ] JZ FD ; no direction? go 4FD (ret) 04C0: [ 74 B1 ] CALL decodejoystick 04C2: [ F9 ] MOV A, R1 ; move direction to R1 04C3: [ C6 CA ] JZ CA ; if direction is to right jump CA 04C5: [ 37 ] CPL A ; 04C6: [ 17 ] INC A ; A = (-A+ * 2 04C7: [ 03 08 ] ADD A, 08 ; 04C9: [ E7 ] RL A ; 04CA: [ AC ] MOV R4, A ; move direction to R4 04CB: [ B8 23 ] MOV R0, exram_pos_23 ; exram 23 is fire_direction 04CD: [ BF 00 ] MOV R7, 00 ; r7 = 0 04CF: [ 80 ] MOVX A, @R0 ; move fire_direction to A 04D0: [ DC ] XRL A, R4 ; compare with direction 04D1: [ C6 DE ] JZ DE ; the same? Continue at 4DE 04D3: [ CC ] DEC R4 ; change new fire direction 04D4: [ 1F ] INC R7 ; inc r7 (contains steps from old to new position) 04D5: [ FC ] MOV A, R4 ; move fire_direction to A 04D6: [ 17 ] INC A ; increment A 04D7: [ 96 DC ] JNZ, DC ; not zero? 04D9: [ 23 0F ] MOV A, 0F ; set A and R4 to 0x0F (mod 0x0f) 04DB: [ AC ] MOV R4, A 04DC: [ 84 CF ] JMP 4CF 04DE: [ FF ] MOV A, R7 ; r7 contains steps from old to new position 04DF: [ C6 FB ] JZ FB ; zero? set exram_pos_22 to zero. 04E1: [ 03 FB ] ADD A, FB ; 04E3: [ BC 04 ] MOV R4, 04 ; r4 (holds new delay) = 0x04 04E5: [ F6 E9 ] JC E9 ; jmp if A (r7) => 5. 04E7: [ BC 10 ] MOV R4, 10 ; r4 = 0x10 (big delay if almost there) 04E9: [ 80 ] MOVX A, @R0 ; r0 holds exram_23. 04EA: [ 17 ] INC A ; rotate fire_direction anti-clockwise 04EB: [ 90 ] MOVX @R0, A ; store it 04EC: [ D3 10 ] XRL A, 10 ; is it 0x10? 04EE: [ 96 F1 ] JNZ, F1 ; nope, skip to 4f1 04F0: [ 90 ] MOVX @R0, A ; store it again (a is now zero) 04F1: [ C5 ] SEL RB0 ; huh? 04F2: [ FB ] MOV A, R3 ; huh? 04F3: [ D5 ] SEL RB1 ; huh? 04F4: [ 96 FA ] JNZ, FA 04F6: [ B9 27 ] MOV R1, iram_pos_27 04F8: [ B1 C4 ] MOV @R1, C4 ; move 0xc4 to intram_pos_27 04FA: [ FC ] MOV A, R4 ; r4 holds delay. 04FB: [ C8 ] DEC R0 ; r0 now points to exram_pos_22 04FC: [ 90 ] MOVX @R0, A ; move new delay to exram_pos_22 04FD: [ 83 ] RET 04FE: [ 00 ] NOP ; just some NOPs to allign the code 04FF: [ 00 ] NOP main_loop2: 0500: [ 14 EC ] CALL extramenable 0502: [ F4 92 ] CALL increment_2a_2b_counters 0504: [ B4 3E ] CALL CheckPlayerHit 0506: [ D4 63 ] CALL 663 0508: [ B9 2E ] MOV R1, 2E ;0x2e to R1 050A: [ F1 ] MOV A, @R1 ;exram (2e) to A 050B: [ 96 12 ] JNZ, 12 ;not zero? jmp 12 050D: [ 11 ] INC @R1 ;inc exram (2e) 050E: [ F4 5D ] CALL init_graphics_and_exram_to_vcd_table: 0510: [ F4 4D ] CALL InitPlayerName 0512: [ B8 27 ] MOV R0, 27 0514: [ F0 ] MOV A, @R0 0515: [ C6 1B ] JZ 1B 0517: [ B0 00 ] MOV @R0, 00 0519: [ 34 A2 ] CALL playsound 051B: [ BA 27 ] MOV R2, 27 051D: [ BB AA ] MOV R3, AA 051F: [ 15 ] DIS I 0520: [ F4 16 ] CALL wait_until_scanline 0522: [ F4 08 ] CALL set_VDC_control_register_to_0x80 0524: [ D4 AB ] CALL update_status_bar 0526: [ 34 76 ] CALL waitvsync 0528: [ 34 34 ] CALL 134 052A: [ B8 A3 ] MOV R0, A3 052C: [ 23 00 ] MOV A, 00 052E: [ 90 ] MOVX @R0, A 052F: [ C8 ] DEC R0 0530: [ 23 8F ] MOV A, 8F 0532: [ 90 ] MOVX @R0, A 0533: [ 14 EC ] CALL extramenable 0535: [ D4 03 ] CALL check_for_keypress 0537: [ B8 08 ] MOV R0, 08 ; place right-arrow symbol 0539: [ 23 36 ] MOV A, 36 ; in first place 053B: [ 90 ] MOVX @R0, A ; of name 053C: [ 84 11 ] JMP main_loop1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CheckPlayerHit ; ; if bit 0 of 3rd byte of sprite 0 is cleared then return. Also return if ; bit 0 is set and the x-position of sprite 0 is 0xf8. If bit 1 is not set ; then check (and update) the highscore. If bit 1 is set then the player ; name is flashed. ; ; intram_02d controls the flashing speed ; intram_026 controls the number of flashes ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 053E: [ B8 7A ] MOV R0, vdc_table_03 ; 3rd byte sprite zero address in VDC mirror 0540: [ 80 ] MOVX A, @R0 ; to A 0541: [ 12 44 ] JB0, 44 ; bit zero set? Jump 44 (player has been hit) 0543: [ 83 ] RET ; ret 0544: [ B9 7C ] MOV R1, vdc_table_01 ; 0546: [ 81 ] MOVX A, @R1 ; get player x-pos 0547: [ D3 F8 ] XRL A, F8 ; 0549: [ 96 43 ] JNZ, 43 ; is it 0xF8? (sprite invisible) nope RET 054B: [ 80 ] MOVX A, @R0 ; get 3rd byte sprite 0 054C: [ 32 50 ] JB1, 50 ; bit 1 set? jmp 50 (means player dead) 054E: [ C4 30 ] JMP CheckNewHighScore 0550: [ B9 27 ] MOV R1, iram_pos_27 0552: [ B1 00 ] MOV @R1, 00 ; move zero to intram 027 0554: [ C9 ] DEC R1 ; r1 = 0x26 0555: [ BC 80 ] MOV R4, 80 0557: [ B8 2D ] MOV R0, iram_pos_2d ; move 2D to R0 0559: [ 10 ] INC @R0 ; increment intram 0x2D 055A: [ F0 ] MOV A, @R0 ; move intram 0x2D to A 055B: [ 53 03 ] ANL A, 03 ; 055D: [ 96 43 ] JNZ, 43 ; bit 1 or 2 set? jmp 543 (RET) 055F: [ A0 ] MOV @R0, A ; move 0 to intram 0x2D (reset counter) 0560: [ 11 ] INC @R1 ; increment intram 026 0561: [ BF 06 ] MOV R7, 06 ; loop 6 times 0563: [ B8 09 ] MOV R0, exram_pos_09 ; r0 = 0x09 0565: [ 80 ] MOVX A, @R0 ; get exram 0x09 (start of player name) 0566: [ F2 70 ] JB7 70 ; bit 7 set. Jmp 570 0568: [ 18 ] INC R0 ; next character 0569: [ EF 65 ] DJNZ R7 65 ; search all 6 chars of name 056B: [ C8 ] DEC R0 ; take last char 056C: [ 80 ] MOVX A, @R0 ; move it to A 056D: [ 4C ] ORL A, R4 ; ORL it with R4 (=0x80) (flashing effect) 056E: [ 90 ] MOVX @R0, A ; store it. 056F: [ 83 ] RET 0570: [ DC ] XRL A, R4 ; reset bit 7 of character 0571: [ 90 ] MOVX @R0, A ; store character in player name 0572: [ F1 ] MOV A, @R1 ; get intram 026 0573: [ D2 7A ] JB6 7A ; bit 6 set? (enough flashes) -> jmp 57a 0575: [ 19 ] INC R1 ; r1 is now inram 027 0576: [ B1 4A ] MOV @R1, 4A ; set intram 027 to 0x4a 0578: [ A4 6B ] JMP 56B ; continue flashing player name 057A: [ 27 ] CLR A ; A = 0x00 057B: [ A1 ] MOV @R1, A ; move 0x00 to intram 026 057C: [ E4 5D ] JMP init_graphics_and_exram_to_vcd_table: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PlayerDiesAnimation ; ; IN: ; r1 value is vdc_table_03 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 057E: [ 03 04 ] ADD A, 04 ; add 4 to 3rd sprite byte ( 0580: [ 91 ] MOVX @R1, A ; store in sprite 0581: [ 53 38 ] ANL A, 38 ; only take bit 3,4,5 0583: [ 96 9C ] JNZ, 9C ; jmp to 9C (RET) 0585: [ 19 ] INC R1 ; inc R1 (vdc_table_02) = sprite attribute 0586: [ 81 ] MOVX A, @R1 ; get it 0587: [ 03 08 ] ADD A, 08 ; Add 8 (to get color changes during animation) 0589: [ 91 ] MOVX @R1, A ; store 058A: [ AC ] MOV R4, A ; move to r4 058B: [ F2 96 ] JB7 HidePlayerSprite ; Bit 7 set? jmp (enough color changes) 058D: [ B8 7C ] MOV R0, 7C ; x-pos of player sprite 058F: [ B4 9D ] CALL InitExplosion 0591: [ F5 ] SEL MB1 0592: [ 14 10 ] CALL StartFlyingShrapnel 0594: [ E5 ] SEL MB0 0595: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; HidePlayerSprite ; ; Sets sprite 0 x and y position to 0xf8 effectively placing it outside the ; visible screen area. ; ; IN: ; r1 value is 0x7b. (points to attribute byte for sprite 0) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0596: [ 19 ] INC R1 ; increment r1 so it points to sprite 0 x-pos 0597: [ 23 F8 ] MOV A, F8 0599: [ 91 ] MOVX @R1, A ; set sprite 0 x-pos to 0xf8 059A: [ 19 ] INC R1 ; increment r1 so it points to sprite 0 y-pos 059B: [ 91 ] MOVX @R1, A ; set sprite 0 y-pos to 0xf8 059C: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; InitExplosion ; ; copies x and y position of the source to the sprites 1-3 (which are ; used for the explosion) to start the beginning of the explosion animation. ; note that the source can either be the player sprite (in case the player dies) ; or a character (in case the player missile or explosion shrapnel hits ; another satellite). ; ; IN: ; r0 holds pointer to source (char or sprite 0) ; r4 sprite attributes (byte 2 of sprite data) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 059D: [ B9 79 ] MOV R1, 79 ; moves 0x79 to r1 (y-pos of sprite 1) 059F: [ 18 ] INC R0 ; r0 is y-pos 05A0: [ BF 03 ] MOV R7, 03 ; r7 (counter) = 3 05A2: [ 80 ] MOVX A, @R0 ; copy y-pos of player to sprite 05A3: [ 91 ] MOVX @R1, A 05A4: [ C8 ] DEC R0 ; r0 is x-pos 05A5: [ C9 ] DEC R1 ; r1 is x-pos of particle sprite 05A6: [ 80 ] MOVX A, @R0 ; copy x-pos of player to sprite 05A7: [ 91 ] MOVX @R1, A 05A8: [ 18 ] INC R0 ; r0 is y-pos 05A9: [ C9 ] DEC R1 ; r1 is sprite attribute of sprite 05AA: [ FC ] MOV A, R4 05AB: [ 91 ] MOVX @R1, A ; copy to sprite attributes 05AC: [ C9 ] DEC R1 ; skip next to byte (unused byte) 05AD: [ C9 ] DEC R1 ; skip to sprite y-pos 05AE: [ EF A2 ] DJNZ R7 A2 ; finished copying? no. copy again. 05B0: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check_satellite_vertical_pos ; ; For each satellite is checked if it is in the visible screen. If not, a ; new position is chosen. ; ; IN ; r1 0x6d (vdc_table_10) ; r7 0x0a (number of satellites) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 05B1: [ BE 3C ] MOV R6, iram_pos_3c ; checks if y_pos of foreground chars 05B3: [ 81 ] MOVX A, @R1 ; 1 - 10 are either zero or F8 05B4: [ C6 C2 ] JZ SetNewSatellitePos ; zero? -> jmp 05B6: [ D3 F8 ] XRL A, F8 05B8: [ C6 C2 ] JZ SetNewSatellitePos ; 0xf8? -> jmp 05BA: [ CE ] DEC R6 ; check next char 05BB: [ C9 ] DEC R1 ; r6 = position in intram for each 05BC: [ C9 ] DEC R1 ; satellite 05BD: [ C9 ] DEC R1 05BE: [ C9 ] DEC R1 05BF: [ EF B3 ] DJNZ R7 B3 05C1: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetNewSatellitePos ; ; Calculates the new starting position of a satellite. byte 25 (000000xx) in ; intram decides new location as follows ; ; xx = ; 00: y-pos = [27,154], x-pos = a0 r5= 0x04 + [0,7] ; 01: y-pos = 0x0b , x-pos = [16, 144] r5= 0x00 + [0,7] ; 10: y-pos = [27,154], x-pos = 01 r5= 0x0C + [0,7] ; 11: y-pos = 0xb8, x-pos = [16, 144] r5= 0x08 + [0,7] ; ; r5 controls the initial movement direction of satellite ; ; IN: ; r1 y_pos of satellite character ; r6 storage area for satellite ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 05C2: [ B8 25 ] MOV R0, iram_pos_25 ; take pos.25 in intram 05C4: [ F0 ] MOV A, @R0 05C5: [ 12 DC ] JB0, DC ; bit 0 set? if so jmp 05DC 05C7: [ BA 01 ] MOV R2, 01 ; nope. move 01 to R2 05C9: [ BD 0C ] MOV R5, 0C ; move 0c to R5 05CB: [ 32 D1 ] JB1, D1 ; bit 1 set? if so jmp 05D1 05CD: [ BD 04 ] MOV R5, 04 ; nope. move 04 to R5 05CF: [ BA A0 ] MOV R2, A0 ; move a0 to R2 05D1: [ 42 ] MOV A, T ; move timer to A (take random number between 27 and 154) 05D2: [ 53 7F ] ANL A, 7F ; strip high bit. 05D4: [ 03 1B ] ADD A, 1B ; add 1B (27 dec) 05D6: [ 91 ] MOVX @R1, A ; move this to r1 (y-pos of current satellite) 05D7: [ C9 ] DEC R1 ; switch to x-pos 05D8: [ FA ] MOV A, R2 ; r2 to A (either 01 or A0) 05D9: [ 91 ] MOVX @R1, A ; move to x-pos of current satellite 05DA: [ A4 EF ] JMP 5EF ; 05DC: [ BA 0B ] MOV R2, 0B ; move 0B to R2 05DE: [ BD 00 ] MOV R5, 00 ; move 00 to R5 05E0: [ 32 E6 ] JB1, E6 ; bit 1 set? jmp to e6 05E2: [ BD 08 ] MOV R5, 08 ; move 08 to R5 05E4: [ BA B8 ] MOV R2, B8 ; move b8 to R2 05E6: [ FA ] MOV A, R2 05E7: [ 91 ] MOVX @R1, A ; move R2 to y-pos 05E8: [ C9 ] DEC R1 05E9: [ 42 ] MOV A, T ; random 05EA: [ 53 7F ] ANL A, 7F ; strip high bit 05EC: [ 03 10 ] ADD A, 10 ; add 10 (a between 0x10 and 0x8f) 05EE: [ 91 ] MOVX @R1, A ; move to x-pos 05EF: [ C9 ] DEC R1 05F0: [ C9 ] DEC R1 05F1: [ 42 ] MOV A, T ; a = random 05F2: [ 53 0F ] ANL A, 0F ; a = [0,0x0f] 05F4: [ 91 ] MOVX @R1, A ; move to byte 3 of char. (new color) 05F5: [ FE ] MOV A, R6 ; take R6 (starts at 3C. decreases for each char) 05F6: [ A8 ] MOV R0, A ; moves A to R0 05F7: [ 42 ] MOV A, T ; a = random 05F8: [ 47 ] SWAP A ; swap nibbles (randomize maybe?) 05F9: [ 62 ] MOV T, A ; save to timer 05FA: [ 53 07 ] ANL A, 07 ; a = [0,7] 05FC: [ 6D ] ADD A, R5 ; add r5 (00,04,08,0C) 05FD: [ A0 ] MOV @R0, A ; move to R0 (0x33-0x3C) 05FE: [ 83 ] RET 05FF: [ 00 ] NOP ; just a NOP to align the code vsync: 0600: [ 55 ] STRT T ; start Timer 0601: [ 04 1A ] JMP vsyncirq ; jmp to vsyncirq check_for_keypress: ; ; check for keypress. if key is pressed. bit 7 of length register is checked. ; if set -> exit. if not, length is incremented, and bit 7 is set. ; next call to this function keypress OR 80 OR 40 is returned. ; ; kinda strange routine. Why isn't the keypress processed immediately?? ; could be to wait until key isn't pressed anymore. 0603: [ 14 B0 ] CALL 0B0 ; get key 0605: [ 15 ] DIS I ; no interrupts 0606: [ AA ] MOV R2, A ; a = key pressed 0607: [ B9 24 ] MOV R1, 24 ; r1 = length of name 0609: [ F2 19 ] JB7 process_key_press ; no keypress? jmp 0619 060B: [ F1 ] MOV A, @R1 ; move length to a 060C: [ F2 18 ] JB7 18 ; now what's this??? 060E: [ 17 ] INC A ; increment length 060F: [ 43 80 ] ORL A, 80 ; set bit 7 0611: [ A1 ] MOV @R1, A ; move back 0612: [ D3 87 ] XRL A, 87 ; EXCL or with 87. (length = 7) 0614: [ 96 18 ] JNZ, 18 ; nope ready 0616: [ B1 86 ] MOV @R1, 86 ; set length = 6 (max length) 0618: [ 83 ] RET process_key_press: 0619: [ B8 08 ] MOV R0, 08 ; start of name in exram 061B: [ F1 ] MOV A, @R1 ; r1 = 24 intram (length of player name) 061C: [ 53 07 ] ANL A, 07 ; max 7. 061E: [ A1 ] MOV @R1, A ; back in 24 061F: [ 68 ] ADD A, R0 ; add 8. 0620: [ A8 ] MOV R0, A ; move to r0 (current position of cursor) 0621: [ FA ] MOV A, R2 ; move keypress to A 0622: [ 53 3F ] ANL A, 3F ; and with 3f (63) (strip 2 high bits) 0624: [ AA ] MOV R2, A ; back to r2 0625: [ 03 D2 ] ADD A, D2 ; 0627: [ F6 18 ] JC 18 ; bigger than 2D? jmp 18 (no funny chars) 0629: [ FA ] MOV A, R2 ; keypress in a 062A: [ 90 ] MOVX @R0, A ; move to 062B: [ B8 27 ] MOV R0, 27 062D: [ B0 56 ] MOV @R0, 56 ; 56 to place 27 in intram (why??) 062F: [ 83 ] RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CheckNewHighScore ; ; Checks if the current score is higher than the highscore. If so, the score ; is copied and the player name is erased to make room for the new one. ; ; IN ; r0 vdc_table_03 ; ; OUT ; f0 0 (new highscore) 1 (no new highscore) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0630: [ 23 03 ] MOV A, 03 0632: [ 90 ] MOVX @R0, A ; move 03 (set bit 0 and 1) to 3rd byte sprite 0 0633: [ B8 04 ] MOV R0, exram_pos_04; first digit of highscore in exram 0635: [ B9 10 ] MOV R1, exram_pos_10; first digit of score in exram 0637: [ BF 04 ] MOV R7, 04 0639: [ 81 ] MOVX A, @R1 ; move digit to score 063A: [ 17 ] INC A 063B: [ 37 ] CPL A ; A = - A + 1 063C: [ 17 ] INC A 063D: [ AA ] MOV R2, A ; move to r2 063E: [ 80 ] MOVX A, @R0 ; get first digit of highscore from exram 063F: [ 17 ] INC A ; increment 0640: [ 6A ] ADD A, R2 ; add r2 0641: [ C6 4A ] JZ 4A ; zero? (both digits are the same) -> jmp 64a 0643: [ 85 ] CLR F0 ; clear f0 0644: [ 95 ] CPL F0 ; set f0 0645: [ F6 54 ] JC 54 ; score digit smaller then highscore digit -> jmp 65a 0647: [ 85 ] CLR F0 ; clear f0 0648: [ E6 4E ] JNC 4E ; score digit bigger then highscore digit -> jmp 64e 064A: [ 18 ] INC R0 ; increment r0 (next highscore digit) 064B: [ 19 ] INC R1 ; increment r1 (next score digit) 064C: [ EF 39 ] DJNZ R7 39 ; loop until all digits checked 064E: [ B8 24 ] MOV R0, iram_pos_24 ; 0650: [ B0 80 ] MOV @R0, 80 ; set length of playername to zero (bit 7 doesn't count) 0652: [ F4 4D ] CALL InitPlayerName ; set player name to default 0654: [ B8 13 ] MOV R0, exram_pos_13; score 0656: [ B9 07 ] MOV R1, exram_pos_07; highscore 0658: [ BF 04 ] MOV R7, 04 ; length of score 065A: [ 80 ] MOVX A, @R0 ; move score digit to A 065B: [ B6 5E ] JF0 5E ; F0 set (score < highscore) -> jmp 65e 065D: [ 91 ] MOVX @R1, A ; move score to highscore 065E: [ C9 ] DEC R1 ; next digit highscore 065F: [ C8 ] DEC R0 ; next digit score 0660: [ EF 5A ] DJNZ R7 5A ; loop for all digits 0662: [ 83 ] RET 0663: [ BA 0C ] MOV R2, 0C ; 0x0C to R2 (counter register) 0665: [ B8 6D ] MOV R0, 6D ; 0667: [ 80 ] MOVX A, @R0 ; move y-pos of 1st foreground char to A 0668: [ AC ] MOV R4, A ; move to R4 0669: [ C8 ] DEC R0 ; take byte 3 of character 066A: [ C8 ] DEC R0 066B: [ C8 ] DEC R0 066C: [ 80 ] MOVX A, @R0 ; move to A 066D: [ BD 3C ] MOV R5, 3C ; move 0x3C to R5 = 'char ship1' 066F: [ B2 83 ] JB5 83 ; bit 5 of A set? Jmp 83 (char is UFO) 0671: [ D2 96 ] JB6 96 ; bit 6 of A set? Jmp 96 (char is fire from UFO) 0673: [ B9 25 ] MOV R1, int_25 ; 0675: [ F1 ] MOV A, @R1 ; counter register to R1 to A 0676: [ BD 31 ] MOV R5, 31 ; 0x31 to R5 0678: [ 12 81 ] JB0, 81 ; Bit 0 of int_25 set? Jmp 81 067A: [ 80 ] MOVX A, @R0 ; move byte 3 of character to A 067B: [ CC ] DEC R4 ; sub 2 from y-pos 067C: [ CC ] DEC R4 067D: [ 92 83 ] JB4, 83 ; bit 4 of A set? JMP 83 067F: [ 1C ] INC R4 ; add 2 to R4 0680: [ 1C ] INC R4 0681: [ F4 26 ] CALL mutate_enemy_shape 0683: [ 80 ] MOVX A, @R0 ; move exram r0 to A 0684: [ AE ] MOV R6, A ; move A to R6 0685: [ 34 4B ] CALL calcchar23 ; r4 = y, r5 = char r6= color (-> r5/r6 byte 2/3) 0687: [ 18 ] INC R0 ; inc r0 0688: [ FD ] MOV A, R5 ; r5 to A 0689: [ 90 ] MOVX @R0, A ; A to R0 (exram) 068A: [ C8 ] DEC R0 ; dec r0 068B: [ 80 ] MOVX A, @R0 ; mov R0 (exram) to A 068C: [ 53 F0 ] ANL A, F0 ; and with f0 (right 4 bytes, left) 068E: [ 4E ] ORL A, R6 ; OR with R6 068F: [ 90 ] MOVX @R0, A ; move to exram (r0) 0690: [ B2 A3 ] JB5 A3 ; bit 5 of A set? JMP a3 0692: [ C8 ] DEC R0 ; dec r0 0693: [ EA 67 ] DJNZ R2 67 ; r2 niet 0, jmp 67 0695: [ 83 ] RET ; return 0696: [ B9 2F ] MOV R1, 2F ; 0698: [ F1 ] MOV A, @R1 ; move 2F (intram) TO A 0699: [ 19 ] INC R1 ; 069A: [ D1 ] XRL A, @R1 ; 2F (intram) XOR 30 (intram) 069B: [ BD 2E ] MOV R5, 2E ; 0x2e = '/' 069D: [ 72 A1 ] JB3, A1 069F: [ BD 3B ] MOV R5, 3B ; 0x3b = '\' 06A1: [ C4 83 ] JMP 683 06A3: [ 18 ] INC R0 06A4: [ 80 ] MOVX A, @R0 06A5: [ 03 05 ] ADD A, 05 06A7: [ 90 ] MOVX @R0, A 06A8: [ C8 ] DEC R0 06A9: [ C4 92 ] JMP 692 update_status_bar: 06AB: [ B8 2C ] MOV R0, 2C ; 06AD: [ F0 ] MOV A, @R0 ; move 2C (intram) to A 06AE: [ 10 ] INC @R0 ; INC 2D (intram) 06AF: [ A5 ] CLR F1 ; F1 = 0 06B0: [ 12 B3 ] JB0, B3 ; bit 0 set of 2c (intram)? 06B2: [ B5 ] CPL F1 ; F1 = 1 06B3: [ 15 ] DIS I ; no interrupt 06B4: [ 89 7C ] ORL P1, 7C ; copy mode enable on VDC 06B6: [ 99 E7 ] ANL P1, E7 06B8: [ F4 30 ] CALL set_location_of_quads 06BA: [ BC C7 ] MOV R4, C7 06BC: [ B8 0C ] MOV R0, 0C 06BE: [ B9 62 ] MOV R1, 62 06C0: [ 76 C6 ] JF1, C6 06C2: [ B8 04 ] MOV R0, 04 06C4: [ B9 42 ] MOV R1, 42 06C6: [ BB 04 ] MOV R3, 04 06C8: [ D4 DC ] CALL put_score_in_quads 06CA: [ B9 72 ] MOV R1, 72 06CC: [ B8 0D ] MOV R0, 0D 06CE: [ 76 D4 ] JF1, D4 06D0: [ B9 52 ] MOV R1, 52 06D2: [ B8 05 ] MOV R0, 05 06D4: [ BB 04 ] MOV R3, 04 06D6: [ D4 DC ] CALL put_score_in_quads 06D8: [ 14 E7 ] CALL vcdenable 06DA: [ E4 12 ] JMP set_VDC_control_register_to_0xA8 put_score_in_quads: ; on entry r4 = c7, r3 = 04 ; r0 = 04, 05, 0C, 0D ; r1 = 42, 52, 62, 72 ; 06DC: [ 80 ] MOVX A, @R0 ; move first char of string to A 06DD: [ BD 0C ] MOV R5, 0C ; 0x0c = '[sPACE]' char 06DF: [ F2 E2 ] JB7 E2 ; bit 7 of char set? (because of bit 7 usage for ; keypressed routine... 06E1: [ AD ] MOV R5, A ; copy char to R5 06E2: [ F8 ] MOV A, R0 ; location to R0 06E3: [ BE 02 ] MOV R6, 02 ; color = 01 (red) 06E5: [ 92 EF ] JB4, EF ; bit 4 set? jmp EF (>16) 06E7: [ BE 04 ] MOV R6, 04 ; color = 02 (green) 06E9: [ D3 08 ] XRL A, 08 ; location == 8 (right arrow) 06EB: [ 96 EF ] JNZ, EF ; nope, jmp ef 06ED: [ BE 0E ] MOV R6, 0E ; color = 07 (white) 06EF: [ 18 ] INC R0 ; skip 2 chars (space between quads) 06F0: [ 18 ] INC R0 06F1: [ 34 4B ] CALL calcchar23 ; r4 = y-pos, r5 = char, r6 = color.Output r5/r6 06F3: [ FD ] MOV A, R5 ; store to quad byte 2/3 06F4: [ 91 ] MOVX @R1, A 06F5: [ 19 ] INC R1 06F6: [ FE ] MOV A, R6 06F7: [ 91 ] MOVX @R1, A 06F8: [ 19 ] INC R1 06F9: [ 19 ] INC R1 06FA: [ 19 ] INC R1 06FB: [ EB DC ] DJNZ R3 DC ; done all 4 chars in quad? 06FD: [ 83 ] RET 06FE: [ 00 ] NOP 06FF: [ 00 ] NOP ; ; on entry r4 = current tune position ; play_custom_sound: 0700: [ A3 ] MOVP A, @A ; custom sound routine?? 0701: [ A9 ] MOV R1, A ; R1 = command byte 0702: [ 1C ] INC R4 0703: [ FC ] MOV A, R4 0704: [ A3 ] MOVP A, @A 0705: [ AA ] MOV R2, A ; R2 = parameter byte 0706: [ 04 4B ] JMP parsesnd set_VDC_control_register_to_0x80: 0708: [ 14 E7 ] CALL vcdenable 070A: [ 23 80 ] MOV A, 80 move_to_VDC_control_register: 070C: [ C5 ] SEL RB0 ; not sure why RB0 is selected. 070D: [ B8 A0 ] MOV R0, A0 070F: [ 90 ] MOVX @R0, A ; move A to VDC control register 0710: [ D5 ] SEL RB1 ; select RB1 0711: [ 83 ] RET set_VDC_control_register_to_0xA8: 0712: [ 23 A8 ] MOV A, A8 ; A8 = 1010010 0714: [ E4 0C ] JMP move_to_VDC_control_register wait_until_scanline: ; ; on entry r2=27, r3=aa (10101010) ; 0716: [ 14 E7 ] CALL vcdenable 0718: [ B8 A0 ] MOV R0, A0 071A: [ B9 A5 ] MOV R1, A5 071C: [ FB ] MOV A, R3 071D: [ 90 ] MOVX @R0, A ; move 0xAA to VDC Control Register 071E: [ 81 ] MOVX A, @R1 ; move Y beam location to A 071F: [ C9 ] DEC R1 ; 0720: [ 81 ] MOVX A, @R1 ; move X beam location to A 0721: [ 97 ] CLR C ; clear carry (why?) 0722: [ 6A ] ADD A, R2 ; 0723: [ E6 1A ] JNC 1A ; if not bigger than D8 then do again. 0725: [ 83 ] RET mutate_enemy_shape: ;return r5 = new shape 0726: [ B9 25 ] MOV R1, int_25 ; 0x25 to R1 0728: [ F1 ] MOV A, @R1 ; move intram 25 to A 0729: [ BD 29 ] MOV R5, 29 ; 0x29 (char 'x') to R5 072B: [ 52 2F ] JB2, 2F ; bit 2 of A set? jmp ret 072D: [ BD 10 ] MOV R5, 10 ; 0x10 (char '+') to R5 072F: [ 83 ] RET set_location_of_quads: 0730: [ B8 41 ] MOV R0, 41 0732: [ BB C7 ] MOV R3, C7 ; move c7 to 40 in VDC (y-pos first quad) 0734: [ 23 11 ] MOV A, 11 ; move 11 to 41 in VDC (x-pos first quad) 0736: [ F4 48 ] CALL copy_word_to_VDC 0738: [ B8 51 ] MOV R0, 51 ; move c7 to 50 in VDC (y-pos 2nd quad) 073A: [ 23 19 ] MOV A, 19 ; move 19 to 51 in VDC (x-pos 2nd quad) 073C: [ F4 48 ] CALL copy_word_to_VDC 073E: [ B8 61 ] MOV R0, 61 ; move c7 to 60 in VDC (y-pos 3rd quad) 0740: [ 23 52 ] MOV A, 52 ; move 52 to 61 in VDC (x-pos 3rd quad) 0742: [ F4 48 ] CALL copy_word_to_VDC 0744: [ B8 71 ] MOV R0, 71 ; move c7 to 70 in VDC (y-pos 4th quad) 0746: [ 23 5A ] MOV A, 5A ; move 5a to 71 in VDC (x-pos 4th quad) copy_word_to_VDC: 0748: [ 90 ] MOVX @R0, A 0749: [ C8 ] DEC R0 074A: [ FB ] MOV A, R3 074B: [ 90 ] MOVX @R0, A 074C: [ 83 ] RET InitPlayerName: 074D: [ BF 08 ] MOV R7, 08 074F: [ B8 55 ] MOV R0, high_score_string 0751: [ B9 0F ] MOV R1, 0F 0753: [ E4 65 ] JMP copy_to_exram high_score_string: 0755: [ 0C ] .db 0x0C ; [sPACE] 0756: [ 0D ] .db 0x0D ; ? 0757: [ 0D ] .db 0x0D ; ? 0758: [ 0D ] .db 0x0D ; ? 0759: [ 0D ] .db 0x0D ; ? 075A: [ 0D ] .db 0x0D ; ? 075B: [ 0D ] .db 0x0D ; ? 075C: [ 36 ] .db 0x36 ; [right arrow] init_graphics_and_exram_to_vcd_table: 075D: [ F4 6D ] CALL clear_sprites_and_chars 075F: [ BF 06 ] MOV R7, 06 0761: [ B8 8C ] MOV R0, start_data 0763: [ B9 7F ] MOV R1, 7F copy_to_exram: 0765: [ F8 ] MOV A, R0 0766: [ A3 ] MOVP A, @A 0767: [ 91 ] MOVX @R1, A 0768: [ 18 ] INC R0 0769: [ C9 ] DEC R1 076A: [ EF 65 ] DJNZ R7 65 076C: [ 83 ] RET clear_sprites_and_chars 076D: [ BF 0F ] MOV R7, 0F 076F: [ B9 79 ] MOV R1, 79 ; (0x04 in VDC, y-pos sprite #1) 0771: [ 23 F8 ] MOV A, F8 0773: [ 91 ] MOVX @R1, A ; move f8 to 0x04 in VDC 0774: [ C9 ] DEC R1 0775: [ 91 ] MOVX @R1, A ; move f8 to 0x05 in VDC (x-pos sprite #1) 0776: [ C9 ] DEC R1 0777: [ 27 ] CLR A ; a = 0 0778: [ 91 ] MOVX @R1, A ; move 0 to 0x06 in VDC 0779: [ C9 ] DEC R1 077A: [ 91 ] MOVX @R1, A ; move 0 to 0x07 in VDC 077B: [ C9 ] DEC R1 077C: [ EF 71 ] DJNZ R7 71 ; do this for sprite (1-3) and all foreground chars 077E: [ BF 04 ] MOV R7, 04 ; fill 4 bytes at 0x10-0x13 with 00 in exram 0780: [ B9 10 ] MOV R1, 10 ; (this is current score) 0782: [ 91 ] MOVX @R1, A 0783: [ 19 ] INC R1 0784: [ EF 82 ] DJNZ R7 82 0786: [ B9 28 ] MOV R1, 28 ; set bytes 28 & 29 to zero. 0788: [ A1 ] MOV @R1, A 0789: [ 19 ] INC R1 078A: [ A1 ] MOV @R1, A 078B: [ 83 ] RET start_data: 078C: [ 40 ] .db 0x40 ; number of bytes to copy from exram to VDC 078D: [ 00 ] .db 0x00 ; destination address in VDC 078E: [ 60 ] .db 0x60 ; Y-pos of sprite 0 (starting position) 078F: [ 51 ] .db 0x51 ; X-pos of sprite 0 (starting position) 0790: [ 08 ] .db 0x08 ; color of sprite 0 (RED) 0791: [ 00 ] .db 0x00 ; byte 3 sprite 0 increment_2a_2b_counters: 0792: [ B9 2A ] MOV R1, 2A ; position 2a 0794: [ 11 ] INC @R1 ; increment position 2a in intram 0795: [ F1 ] MOV A, @R1 ; move position 2a (intram) to A 0796: [ 53 03 ] ANL A, 03 ; and with 3 0798: [ 96 A3 ] JNZ, A3 ; bit 1 or 2 set? Jump to A3 (return) 079A: [ 19 ] INC R1 ; if not, increment R1 079B: [ 11 ] INC @R1 ; increment 0x2b in intram 079C: [ F1 ] MOV A, @R1 ; move position R1 (intram) to A 079D: [ 03 F0 ] ADD A, F0 ; IF a is smaller then #0f 079F: [ E6 F0 ] JNC F0 ; then jump to F0 07A1: [ B1 10 ] MOV @R1, 10 ; else, move 10 to position R1 07A3: [ 83 ] RET ; ret custom_sound_data: 07A4: [ 42 ] MOV A, T 07A5: [ FF ] MOV A, R7 07A6: [ 81 ] MOVX A, @R1 07A7: [ 20 ] XCHA, @R0 07A8: [ 81 ] MOVX A, @R1 07A9: [ 1C ] INC R4 07AA: [ 21 ] XCHA, @R1 07AB: [ 00 ] NOP 07AC: [ 41 ] ORL A, @R1 07AD: [ FF ] MOV A, R7 07AE: [ 82 ] ??? 07AF: [ 1C ] INC R4 07B0: [ 42 ] MOV A, T 07B1: [ FF ] MOV A, R7 07B2: [ 82 ] ??? 07B3: [ 08 ] INS A, BUS 07B4: [ 10 ] INC @R0 07B5: [ 2E ] XCH A, R6 07B6: [ 42 ] MOV A, T 07B7: [ DF ] XRL A, R7 07B8: [ 82 ] ??? 07B9: [ 04 10 ] JMP 010 07BB: [ 32 84 ] JB1, 84 07BD: [ 10 ] INC @R0 07BE: [ 21 ] XCHA, @R1 07BF: [ 00 ] NOP 07C0: [ 44 FF ] JMP 2FF 07C2: [ 21 ] XCHA, @R1 07C3: [ 00 ] NOP 07C4: [ 81 ] MOVX A, @R1 07C5: [ 24 81 ] JMP 181 07C7: [ 14 21 ] CALL 021 07C9: [ 00 ] NOP 07CA: [ 00 ] NOP 07CB: [ 00 ] NOP 07CC: [ 00 ] NOP 07CD: [ 00 ] NOP 07CE: [ 00 ] NOP 07CF: [ 00 ] NOP 07D0: [ 00 ] NOP 07D1: [ 00 ] NOP 07D2: [ 00 ] NOP 07D3: [ 00 ] NOP 07D4: [ 00 ] NOP 07D5: [ 00 ] NOP 07D6: [ 00 ] NOP 07D7: [ 00 ] NOP 07D8: [ 00 ] NOP 07D9: [ 00 ] NOP 07DA: [ 00 ] NOP 07DB: [ 00 ] NOP 07DC: [ 00 ] NOP 07DD: [ 00 ] NOP 07DE: [ 00 ] NOP 07DF: [ 00 ] NOP 07E0: [ 00 ] NOP 07E1: [ 00 ] NOP 07E2: [ 00 ] NOP 07E3: [ 00 ] NOP 07E4: [ 00 ] NOP 07E5: [ 00 ] NOP 07E6: [ 00 ] NOP 07E7: [ 00 ] NOP 07E8: [ 00 ] NOP 07E9: [ 00 ] NOP 07EA: [ 00 ] NOP 07EB: [ 00 ] NOP 07EC: [ 00 ] NOP 07ED: [ 00 ] NOP 07EE: [ 00 ] NOP 07EF: [ 00 ] NOP 07F0: [ B9 27 ] MOV R1, 27 07F2: [ B1 F5 ] MOV @R1, F5 07F4: [ 83 ] RET 07F5: [ 81 ] MOVX A, @R1 07F6: [ 1C ] INC R4 07F7: [ 44 C2 ] JMP 2C2 07F9: [ 21 ] XCHA, @R1 07FA: [ 00 ] NOP 07FB: [ 00 ] NOP 07FC: [ 00 ] NOP 07FD: [ 00 ] NOP 07FE: [ 00 ] NOP 07FF: [ 00 ] NOP ; ; on entry A = direction of fire ; return R3/R2 delta YX ; huh? why not start at D3 and remove INC R7?? ; get_deltaxy_for_firing: 0000: [ BC D1 ] MOV R4, fire_direction_table-2 ; D1 is start of table 0002: [ AF ] MOV R7, A ; direction of fire to R7 0003: [ 1F ] INC R7 ; increment 1 0004: [ 1C ] INC R4 ; increment index to table (2 bytes per entry) 0005: [ 1C ] INC R4 0006: [ EF 04 ] DJNZ R7 04 ; continue looking 0008: [ FC ] MOV A, R4 ; get two bytes from table and put them in R3/R2 0009: [ A3 ] MOVP A, @A 000A: [ AB ] MOV R3, A 000B: [ 1C ] INC R4 000C: [ FC ] MOV A, R4 000D: [ A3 ] MOVP A, @A 000E: [ AA ] MOV R2, A 000F: [ 83 ] RET StartFlyingShrapnel: 0010: [ B8 15 ] MOV R0, 15 ; 0012: [ BF 09 ] MOV R7, 09 ; counter 9 bytes 0014: [ BA 22 ] MOV R2, init_schrapnel_table ; start at address 22 0016: [ FA ] MOV A, R2 ; 22 to A 0017: [ A3 ] MOVP A, @A ; get data 0018: [ 90 ] MOVX @R0, A ; move data to exram (15) 0019: [ 1A ] INC R2 ; 001A: [ 18 ] INC R0 001B: [ EF 16 ] DJNZ R7 16 ; loop 9 times 001D: [ B8 27 ] MOV R0, 27 001F: [ B0 AC ] MOV @R0, AC ; move 0xAC to intram 27 0021: [ 83 ] RET init_schrapnel_table: 0022: [ A8 ] .db 0xA8 ; data for 010 routine 0023: [ FF ] .db 0xFF 0024: [ 01 ] .db 0x01 0025: [ A8 ] .db 0xA8 0026: [ FF ] .db 0xFF 0027: [ FF ] .db 0xFF 0028: [ A8 ] .db 0xA8 0029: [ 01 ] .db 0x01 002A: [ 00 ] .db 0x00 show_particles: 002B: [ B8 25 ] MOV R0, int_25 002D: [ F0 ] MOV A, @R0 002E: [ A5 ] CLR F1 ; clear flag 002F: [ 12 32 ] JB0, 32 ; bit 0 set of int_25 0031: [ B5 ] CPL F1 ; complement f1 bit0 = 0 -> f1 = 0. bit0 = 1 -> f1=1 0032: [ B8 14 ] MOV R0, 14 ; move exram 0x14 to A 0034: [ 80 ] MOVX A, @R0 0035: [ 17 ] INC A ; increment it 0036: [ 90 ] MOVX @R0, A ; store it 0037: [ B9 79 ] MOV R1, 79 ; start of sprite 1 in VDC mirror 0039: [ B8 15 ] MOV R0, 15 ; shrapnel_table in intram (particle 2) 003B: [ BA 00 ] MOV R2, 00 ; distance from other particles 003D: [ 14 78 ] CALL do_new_particle_position 003F: [ B9 75 ] MOV R1, 75 ; start of sprite 2 in VDC mirror 0041: [ B8 18 ] MOV R0, 18 ; shrapnel table in intram (particle 2) 0043: [ BA 05 ] MOV R2, 05 ; distance from other particles 0045: [ 14 78 ] CALL do_new_particle_position 0047: [ B9 71 ] MOV R1, 71 ; start of sprite 3 in VDC mirror 0049: [ B8 1B ] MOV R0, 1B ; shrapnel table in intram (particle 3) 004B: [ BA 0A ] MOV R2, 0A ; distance from other particles 004D: [ 14 78 ] CALL do_new_particle_position 004F: [ B8 3D ] MOV R0, 3D 0051: [ 23 10 ] MOV A, 10 0053: [ 90 ] MOVX @R0, A ; move 0x10 to 3D (exram) 0054: [ C8 ] DEC R0 ; r0 = 0x3C 0055: [ 23 80 ] MOV A, 80 ; A = 0x80 0057: [ B9 15 ] MOV R1, 15 ; r1 = 0x15 (particle 0) 0059: [ 76 5F ] JF1, 5F ; F1 = 1, jmp 5F 005B: [ B9 1B ] MOV R1, 1B ; r1 = 0x1B (particle 2) 005D: [ 23 90 ] MOV A, 90 ; A = 0x90 005F: [ 90 ] MOVX @R0, A ; move A to 0x3C 0060: [ 81 ] MOVX A, @R1 ; get particle status byte 0061: [ B9 33 ] MOV R1, 33 ; r1 = 0x33 (3B-33) + 90 = 98 is sprite 3 in VDC mirror 0063: [ 14 6C ] CALL 06C ; show sprite 0065: [ 76 A0 ] JF1, A0 ' F1=1, jmp RET 0067: [ B9 18 ] MOV R1, 18 0069: [ 81 ] MOVX A, @R1 ; get status byte particle 2 006A: [ B9 3B ] MOV R1, 3B 006C: [ BC E8 ] MOV R4, E8 ; explosion sprite 006E: [ D2 76 ] JB6 76 0070: [ BC EF ] MOV R4, EF ; explosion2 sprite 0072: [ B2 76 ] JB5 76 0074: [ BC 6E ] MOV R4, 6E ; particle sprite 0076: [ 24 D6 ] JMP 1D6 ; copy routine; r4 = source, r1 = destinations ; ; on entry r0 = 15, 18, 1b. All values point to memory location holding 0xA8 (10101000) ; do_new_particle_position: 0078: [ 80 ] MOVX A, @R0 ; move exram to A 0079: [ B2 A1 ] JB5 A1 ; bit 5 set, to A1 007B: [ D2 A1 ] JB6 A1 ; bit 6 set, to A1 007D: [ F2 85 ] JB7 move_shrapnel ; bit 7 set, to 85 007F: [ 96 83 ] JNZ, 83 ; not zero to 83 0081: [ B6 B7 ] JF0 player_fire ; F0=1, to B7 0083: [ 24 00 ] JMP do_particle_shield move_shrapnel: 0085: [ 53 7F ] ANL A, 7F ; and particle status with 7f. (strip high bit) 0087: [ C6 AB ] JZ start_particle_shield; zero? jmp AB 0089: [ 80 ] MOVX A, @R0 ; take particle status byte 008A: [ 07 ] DEC A ; decrement 008B: [ 90 ] MOVX @R0, A ; store 008C: [ 18 ] INC R0 ; take particle delta y. 008D: [ 80 ] MOVX A, @R0 ; move delta y to A 008E: [ AB ] MOV R3, A ; move to R3 008F: [ 18 ] INC R0 ; take particle delta x 0090: [ 80 ] MOVX A, @R0 0091: [ AA ] MOV R2, A ; move to r2 0092: [ 81 ] MOVX A, @R1 ; take y-pos particle. 0093: [ 6B ] ADD A, R3 ; add delta y 0094: [ 91 ] MOVX @R1, A ; store 0095: [ C9 ] DEC R1 0096: [ 81 ] MOVX A, @R1 ; take x-pos particle 0097: [ 6A ] ADD A, R2 ; add delta x 0098: [ 91 ] MOVX @R1, A ; store 0099: [ B9 2B ] MOV R1, 2B ; reset counter (intram 2B) 009B: [ B1 00 ] MOV @R1, 00 009D: [ C9 ] DEC R1 ; reset counter (intram 2A?) 009E: [ B1 00 ] MOV @R1, 00 00A0: [ 83 ] RET 00A1: [ 07 ] DEC A ; decrement A 00A2: [ 90 ] MOVX @R0, A ; move back to exram 00A3: [ 53 1F ] ANL A, 1F ; and with 1F 00A5: [ C6 AB ] JZ start_particle_shield; first 5 bytes are not set. Jmp AB 00A7: [ 80 ] MOVX A, @R0 ; get original value again. 00A8: [ B2 8A ] JB5 8A ; bit 5 set? 00AA: [ 83 ] RET start_particle_shield: 00AB: [ 90 ] MOVX @R0, A ; move zero to R0 00AC: [ C9 ] DEC R1 00AD: [ C9 ] DEC R1 ; go to attribute byte 00AE: [ 91 ] MOVX @R1, A ; set it to zero (color is dark grey) 00AF: [ B9 23 ] MOV R1, 23 00B1: [ 81 ] MOVX A, @R1 ; get position 23 in exram (fire direction) 00B2: [ 17 ] INC A ; increment it (moves anti-clockwise) 00B3: [ B9 14 ] MOV R1, 14 ; 00B5: [ 91 ] MOVX @R1, A ; store it in exram 14 00B6: [ 83 ] RET player_fire: 00B7: [ C9 ] DEC R1 00B8: [ C9 ] DEC R1 00B9: [ 81 ] MOVX A, @R1 ; get 3rd sprite byte. Store in A 00BA: [ 19 ] INC R1 00BB: [ 19 ] INC R1 00BC: [ D3 38 ] XRL A, 38 ; 3rd sprite byte = 0x38?? 00BE: [ 96 83 ] JNZ, 83 ; nope to 083 (jmp do_particle_shield) 00C0: [ 23 90 ] MOV A, 90 00C2: [ 90 ] MOVX @R0, A ; move 0x90 to particle status byte 00C3: [ 18 ] INC R0 ; delta-y 00C4: [ B9 23 ] MOV R1, 23 ; 00C6: [ 81 ] MOVX A, @R1 ; get exram 23 (direction of fire) 00C7: [ 14 00 ] CALL get_deltaxy_for_firing 00C9: [ FB ] MOV A, R3 ; 00CA: [ 90 ] MOVX @R0, A ; move delta y to particle delta y 00CB: [ 18 ] INC R0 00CC: [ FA ] MOV A, R2 00CD: [ 90 ] MOVX @R0, A ; move delta x to particle delta x 00CE: [ B9 27 ] MOV R1, 27 00D0: [ B1 A4 ] MOV @R1, A4 ; move A4 to 27 00D2: [ 83 ] RET fire_direction_table: 00D3: [ 00 ] .db 0x00 00D4: [ 03 ] .db 0x03 00D5: [ 01 ] .db 0x01 00D6: [ 03 ] .db 0x03 00D7: [ 02 ] .db 0x02 00D8: [ 02 ] .db 0x02 00D9: [ 03 ] .db 0x03 00DA: [ 01 ] .db 0x01 00DB: [ 04 ] .db 0x04 00DC: [ 00 ] .db 0x00 00DD: [ 03 ] .db 0x03 00DD: [ FF ] .db 0xFF 00DF: [ 02 ] .db 0x02 00E0: [ FE ] .db 0xFE 00E1: [ 01 ] .db 0x01 00E2: [ FD ] .db 0xFD 00E3: [ 00 ] .db 0x00 00E4: [ FD ] .db 0xFD 00E5: [ FF ] .db 0xFF 00E6: [ FD ] .db 0xFD 00E7: [ FE ] .db 0xFE 00E8: [ FE ] .db 0xFE 00E9: [ FD ] .db 0xFD 00EA: [ FF ] .db 0xFF 00EB: [ FC ] .db 0xFC 00EC: [ 00 ] .db 0x00 00ED: [ FD ] .db 0xFD 00EE: [ 01 ] .db 0x01 00EF: [ FE ] .db 0xFE 00F0: [ 02 ] .db 0x02 00F1: [ FF ] .db 0xFF 00F2: [ 03 ] .db 0x03 satellite_movement: 00F3: [ B8 28 ] MOV R0, #28 ; 28 counter reg 00F5: [ F0 ] MOV A, @R0 00F6: [ C6 FA ] JZ FA ; if zero do stuff 00F8: [ 10 ] INC @R0 ; if not, increment counter 00F9: [ 83 ] RET 00FA: [ BD 1C ] MOV R5, 1C 00FC: [ 54 09 ] CALL set_new_intram28_delay 00FE: [ 24 F7 ] JMP move_satellite_y_pos ; ; on entry r2 = 0, 05, 0A ; do_particle_shield: 0100: [ B8 14 ] MOV R0, 14 0102: [ 80 ] MOVX A, @R0 ; get exram 0x14 0103: [ 03 F0 ] ADD A, F0 0105: [ E6 09 ] JNC 09 ; smaller then 0x0f, jmp 09 0107: [ 27 ] CLR A ; A = 0 0108: [ 90 ] MOVX @R0, A ; move 0 to 0x14 0109: [ 80 ] MOVX A, @R0 ; get 0x14 010A: [ 6A ] ADD A, R2 ; Add R2 (distance from particle 0) 010B: [ AF ] MOV R7, A ; move to R7 010C: [ 03 F0 ] ADD A, F0 ; 010E: [ E6 11 ] JNC 11 ; smaller then 0x0f, jmp 11 0110: [ AF ] MOV R7, A ; get original from r7 0111: [ 1F ] INC R7 ; increment 0112: [ BC 4C ] MOV R4, circling_shield_particles_positions-2 ; start of table 0114: [ B8 2B ] MOV R0, 2B ; 0116: [ F0 ] MOV A, @R0 ; get 2b from intram 0117: [ 17 ] INC A ; increment by one 0118: [ 37 ] CPL A ; complement (A = -A) 0119: [ 17 ] INC A ; increment by 1 (A = -A +1) 011A: [ 6F ] ADD A, R7 ; add index to table 011B: [ BE 00 ] MOV R6, 00 ; R6 = 0x00 (color is dark grey) 011D: [ F6 21 ] JC 21 ; A was zero 011F: [ BE 20 ] MOV R6, 20 ; r6 = 0x20 (color is blue) 0121: [ B8 23 ] MOV R0, 23 0123: [ 80 ] MOVX A, @R0 ; get exram 23 (direction of fire) 0124: [ 17 ] INC A ; inc 0125: [ 37 ] CPL A ; complement 0126: [ 17 ] INC A ; inc 0127: [ 6F ] ADD A, R7 ; add index to table (distance 2 other particles) 0128: [ F6 2C ] JC 2C ; jmp is A was 0 012A: [ 37 ] CPL A ; original + 1 012B: [ 17 ] INC A ; inc 012C: [ 03 FE ] ADD A, FE ; Add 0xFE 012E: [ F6 35 ] JC 35 ; smaller then 2, jmp 35 0130: [ 80 ] MOVX A, @R0 ; get direction of fire 0131: [ AF ] MOV R7, A ; move to R7 0132: [ 1F ] INC R7 ; next position (anti clockwise) 0133: [ BE 38 ] MOV R6, 38 ; R6 = 0x38 (color is white) 0135: [ 1C ] INC R4 ; increment table-index by 2 0136: [ 1C ] INC R4 0137: [ EF 35 ] DJNZ R7 35 ; keep doing that for R7 times 0139: [ FC ] MOV A, R4 ; move table data to r3 and r4 013A: [ A3 ] MOVP A, @A 013B: [ AB ] MOV R3, A 013C: [ 1C ] INC R4 013D: [ FC ] MOV A, R4 013E: [ A3 ] MOVP A, @A 013F: [ AA ] MOV R2, A ; table index to R2 0140: [ B8 7D ] MOV R0, 7D ; 0142: [ 80 ] MOVX A, @R0 ; get player y-pos 0143: [ 6B ] ADD A, R3 ; add y-offset 0144: [ 91 ] MOVX @R1, A ; move to particle y-pos 0145: [ C8 ] DEC R0 0146: [ C9 ] DEC R1 0147: [ 80 ] MOVX A, @R0 ; get player x-pos 0148: [ 6A ] ADD A, R2 ; add x-offset 0149: [ 91 ] MOVX @R1, A ; move to particle x-pos 014A: [ C9 ] DEC R1 014B: [ FE ] MOV A, R6 014C: [ 91 ] MOVX @R1, A ; move color to sprite 014D: [ 83 ] RET circling_shield_particles_positions: 014E: [ 00 ] .db 0x00 014F: [ 09 ] .db 0x00 0150: [ 03 ] .db 0x03 0151: [ 08 ] .db 0x08 0152: [ 05 ] .db 0x05 0153: [ 06 ] .db 0x06 0154: [ 07 ] .db 0x07 0155: [ 04 ] .db 0x04 0155: [ 08 ] .db 0x08 0157: [ 01 ] .db 0x01 0158: [ 07 ] .db 0x07 0159: [ FE ] .db 0xFE 015A: [ 05 ] .db 0x05 015B: [ FB ] .db 0xFB 015C: [ 03 ] .db 0x03 015D: [ F9 ] .db 0xF9 015E: [ 00 ] .db 0x00 015F: [ F8 ] .db 0xF8 0160: [ FD ] .db 0xFD 0161: [ F9 ] .db 0xF9 0162: [ FA ] .db 0xFA 0163: [ FB ] .db 0xFB 0164: [ F8 ] .db 0xF8 0165: [ FE ] .db 0xFE 0166: [ F7 ] .db 0xF7 0167: [ 01 ] .db 0x01 0168: [ F8 ] .db 0xF8 0169: [ 04 ] .db 0x04 016A: [ FA ] .db 0xFA 016B: [ 06 ] .db 0x06 016C: [ FC ] .db 0xFC 016D: [ 08 ] .db 0x08 016E: [ 00 ] .db 00000000 ; start particle sprite 016F: [ 00 ] .db 00000000 0170: [ 00 ] .db 00000000 0171: [ 10 ] .db 00010000 0172: [ 00 ] .db 00000000 0173: [ 00 ] .db 00000000 0174: [ 00 ] .db 00000000 0175: [ 00 ] .db 00000000 ; end particle sprite move_player: 0176: [ B9 00 ] MOV R1, 00 ; get joystick 0 0178: [ E5 ] SEL MB0 0179: [ 74 8F ] CALL getjoystick 017B: [ F5 ] SEL MB1 017C: [ B8 2B ] MOV R0, 2B 017E: [ F0 ] MOV A, @R0 ; intram 2B to A 017F: [ 92 86 ] JB4, 86 ; bit 4 set? jmp to 86 0181: [ B8 25 ] MOV R0, int_25 0183: [ F0 ] MOV A, @R0 ; get counter?? to A 0184: [ 12 BB ] JB0, BB ; bit 0 set? jmp BB 0186: [ B8 7D ] MOV R0, 7D ; get y-pos of player sprite in A 0188: [ 80 ] MOVX A, @R0 0189: [ D3 F8 ] XRL A, F8 ; is it f8? 018B: [ C6 DF ] JZ DF ; yep jmp df (RET) 018D: [ 80 ] MOVX A, @R0 ; get y-pos of player again. 018E: [ 6B ] ADD A, R3 ; add r3 (r3 holds delta-Y from getjoystick) 018F: [ 90 ] MOVX @R0, A ; put in y-pos of player. 0190: [ BC F0 ] MOV R4, F0 0192: [ 6C ] ADD A, R4 ; i a > 0f then jmp 97 0193: [ F6 97 ] JC 97 0195: [ 34 CF ] CALL set_player_xy_pos 0197: [ BC 48 ] MOV R4, 48 ; move 48 to r4 0199: [ 80 ] MOVX A, @R0 ; get player y-pos in A 019A: [ 6C ] ADD A, R4 ; player pos <= b7 019B: [ E6 9F ] JNC 9F ; jmp 9f. 019D: [ 34 CF ] CALL set_player_xy_pos 019F: [ C8 ] DEC R0 ; dec. r0. Now holds x-pos of player 01A0: [ 80 ] MOVX A, @R0 ; move x-pos player to A 01A1: [ 6A ] ADD A, R2 ; Add r2 (delta x from get joystick) 01A2: [ 90 ] MOVX @R0, A ; move back to x-pos player (VDC mirror in Exram) 01A3: [ BC F8 ] MOV R4, F8 ; is smaller <= 08 then rest position at 08 01A5: [ 6C ] ADD A, R4 01A6: [ F6 AA ] JC AA ; no? keep current position 01A8: [ 34 CF ] CALL set_player_xy_pos 01AA: [ 80 ] MOVX A, @R0 ; get player x-pos 01AB: [ BC 70 ] MOV R4, 70 ; bigger then 8f? 01AD: [ 6C ] ADD A, R4 01AE: [ E6 B2 ] JNC B2 ; no? keep value 01B0: [ 34 CF ] CALL set_player_xy_pos 01B2: [ C8 ] DEC R0 ;r0 = r0 - 2 01B3: [ C8 ] DEC R0 01B4: [ 80 ] MOVX A, @R0 ; get value from this (what is this?) 01B5: [ 18 ] INC R0 ; increases to byte 2 from player sprite 01B6: [ 12 BB ] JB0, BB ; if bit0=1 (from byte 4) 01B8: [ 23 09 ] MOV A, 09 ; color = red. full-shift = 1 01BA: [ 90 ] MOVX @R0, A ; move to byte 2 player sprite 01BB: [ BC E0 ] MOV R4, E0 ; e0 = UFO sprite 01BD: [ 34 D4 ] CALL sprite_copy_routine; copy sprite 01BF: [ B8 25 ] MOV R0, int_25 ; 01C1: [ F0 ] MOV A, @R0 ; get intram 25 to A 01C2: [ 77 ] RR A ; 01C3: [ 77 ] RR A ; divide by 4 01C4: [ 53 07 ] ANL A, 07 ; and 07 01C6: [ AF ] MOV R7, A ; move to R7 (counter) 01C7: [ B9 37 ] MOV R1, 37 ; get bottom part of player sprite 01C9: [ 81 ] MOVX A, @R1 ; move it to A 01CA: [ E7 ] RL A ; Rotate left 01CB: [ EF CA ] DJNZ R7 CA ; R7 times. 01CD: [ 91 ] MOVX @R1, A ; store in sprite 01CE: [ 83 ] RET set_player_xy_pos: 01CF: [ FC ] MOV A, R4 ; (r4 holds complement of max position) 01D0: [ 37 ] CPL A ; complement (now 0f) 01D1: [ 17 ] INC A ; increment 01D2: [ 90 ] MOVX @R0, A ; move to player y-pos 01D3: [ 83 ] RET sprite_copy_routine: 01D4: [ B9 3B ] MOV R1, 3B ; 3b = 90 in VDC mirror in exram 01D6: [ BF 08 ] MOV R7, 08 01D8: [ FC ] MOV A, R4 01D9: [ A3 ] MOVP A, @A 01DA: [ 91 ] MOVX @R1, A 01DB: [ 1C ] INC R4 01DC: [ C9 ] DEC R1 01DD: [ EF D8 ] DJNZ R7 D8 01DF: [ 83 ] RET 01E0: [ 00 ] .db 00000000 ; start of UFO sprite 01E1: [ 00 ] .db 00000000 01E2: [ 18 ] .db 00011000 01E3: [ 3C ] .db 00111100 01E4: [ EF ] .db 11101111 01E5: [ 3C ] .db 00111100 01E6: [ 00 ] .db 00000000 01E7: [ 00 ] .db 00000000 ; end UFO sprite 01E8: [ 09 ] .db 00001001 ; start of explostion sprite 01E9: [ D2 ] .db 11010010 01EA: [ 26 ] .db 00100110 01EB: [ 7C ] .db 01111100 01EC: [ 3F ] .db 00111111 01ED: [ 24 ] .db 00100100 01EE: [ 54 ] .db 01010100 01EF: [ 82 ] .db 11101111 ; end, start ?? sprite 01F0: [ 11 ] .db 00010001 01F1: [ 44 ] .db 01000100 01F2: [ 20 ] .db 00100000 01F3: [ 88 ] .db 10001000 01F4: [ 02 ] .db 00000010 01F5: [ 20 ] .db 00100000 01F6: [ 89 ] .db 10001001 ; end ?? sprite move_satellite_y_pos: 01F7: [ BF 0A ] MOV R7, 0A ; 10 satellites max 01F9: [ B9 6D ] MOV R1, 6D ; y-pos of first char (satellite) in exram mirror 01FB: [ E5 ] SEL MB0 01FC: [ B4 B1 ] CALL Check_satellite_vertical_pos 01FE: [ F5 ] SEL MB1 01FF: [ 83 ] RET 0200: [ 14 F3 ] CALL satellite_movement 0202: [ 74 A4 ] CALL 3A4 0204: [ 54 20 ] CALL 220 0206: [ 54 5F ] CALL 25F 0208: [ 83 ] RET set_new_intram28_delay: ; ; on entry r5 = 1c, r0 = 28 ; 0209: [ B9 10 ] MOV R1, 10 ; memory 0x10 in extram 020B: [ BF 03 ] MOV R7, 03 ; counter = 3 020D: [ 81 ] MOVX A, @R1 ; move to A 020E: [ 96 13 ] JNZ, 13 ; non-zero? jmp to 13 0210: [ 19 ] INC R1 ; increment pointer to memory 0211: [ EF 0D ] DJNZ R7 0D ; test next one 0213: [ FD ] MOV A, R5 ; move 1c to A 0214: [ 6F ] ADD A, R7 ; Add counter to 1C 0215: [ A3 ] MOVP A, @A ; move from memory to A ([1C,1F]) 0216: [ A0 ] MOV @R0, A ; move memory value to intram 28. 0217: [ 83 ] RET 0218: [ FF ] MOV A, R7 0219: [ 7F ] ADC A, R7 021A: [ 3F ] MOVD P7, A 021B: [ 1F ] INC R7 021C: [ C0 ] .db 0xC0 021D: [ E0 ] .db 0xE0 021E: [ F0 ] .db 0xF0 021F: [ 00 ] .db 0x00 0220: [ B9 25 ] MOV R1, int_25 0222: [ F1 ] MOV A, @R1 0223: [ 03 03 ] ADD A, 03 0225: [ 53 0F ] ANL A, 0F 0227: [ AF ] MOV R7, A 0228: [ 03 F5 ] ADD A, F5 022A: [ E6 2F ] JNC 2F 022C: [ 03 04 ] ADD A, 04 022E: [ AF ] MOV R7, A 022F: [ 1F ] INC R7 0230: [ B9 6E ] MOV R1, 6E 0232: [ C9 ] DEC R1 0233: [ C9 ] DEC R1 0234: [ C9 ] DEC R1 0235: [ C9 ] DEC R1 0236: [ EF 32 ] DJNZ R7 32 0238: [ 81 ] MOVX A, @R1 0239: [ 92 5B ] JB4, 5B 023B: [ 83 ] RET 023C: [ B8 7C ] MOV R0, 7C 023E: [ 19 ] INC R1 023F: [ 19 ] INC R1 0240: [ 27 ] CLR A 0241: [ AB ] MOV R3, A 0242: [ AA ] MOV R2, A 0243: [ 74 00 ] CALL GetDistanceBetweenObjects 0245: [ AD ] MOV R5, A 0246: [ C6 4E ] JZ 4E 0248: [ BA FE ] MOV R2, FE 024A: [ F6 4E ] JC 4E 024C: [ BA 02 ] MOV R2, 02 024E: [ 19 ] INC R1 024F: [ 18 ] INC R0 0250: [ 74 00 ] CALL GetDistanceBetweenObjects 0252: [ C6 5A ] JZ 5A 0254: [ BB FE ] MOV R3, FE 0256: [ F6 5A ] JC 5A 0258: [ BB 02 ] MOV R3, 02 025A: [ 83 ] RET 025B: [ 54 3C ] CALL 23C 025D: [ 64 E0 ] JMP 3E0 025F: [ B8 25 ] MOV R0, 25 0261: [ F0 ] MOV A, @R0 0262: [ 53 03 ] ANL A, 03 0264: [ 96 A1 ] JNZ, A1 0266: [ B9 45 ] MOV R1, 45 0268: [ BE 32 ] MOV R6, 32 026A: [ 81 ] MOVX A, @R1 026B: [ C6 71 ] JZ 71 026D: [ D3 F8 ] XRL A, F8 026F: [ 96 97 ] JNZ, 97 0271: [ B8 29 ] MOV R0, 29 0273: [ 10 ] INC @R0 0274: [ F0 ] MOV A, @R0 0275: [ 96 08 ] JNZ, 08 0277: [ BD 18 ] MOV R5, 18 0279: [ 54 09 ] CALL set_new_intram28_delay 027B: [ B9 45 ] MOV R1, 45 027D: [ AC ] MOV R4, A 027E: [ 42 ] MOV A, T 027F: [ 5C ] ANL A, R4 0280: [ A0 ] MOV @R0, A 0281: [ E5 ] SEL MB0 0282: [ B4 C5 ] CALL 5C5 0284: [ F5 ] SEL MB1 0285: [ B9 42 ] MOV R1, 42 0287: [ 81 ] MOVX A, @R1 0288: [ 43 20 ] ORL A, 20 028A: [ 91 ] MOVX @R1, A 028B: [ 54 3C ] CALL 23C 028D: [ B8 22 ] MOV R0, 22 028F: [ FB ] MOV A, R3 0290: [ C6 93 ] JZ 93 0292: [ 67 ] RRC A 0293: [ A0 ] MOV @R0, A 0294: [ 18 ] INC R0 0295: [ FA ] MOV A, R2 0296: [ A0 ] MOV @R0, A 0297: [ B9 45 ] MOV R1, 45 0299: [ B8 27 ] MOV R0, 27 029B: [ B0 BC ] MOV @R0, BC 029D: [ B8 23 ] MOV R0, 23 029F: [ 44 EA ] JMP 2EA 02A1: [ B9 41 ] MOV R1, 41 02A3: [ 81 ] MOVX A, @R1 02A4: [ D3 F8 ] XRL A, F8 02A6: [ 96 E6 ] JNZ, E6 02A8: [ 42 ] MOV A, T 02A9: [ 12 FD ] JB0, FD 02AB: [ B9 45 ] MOV R1, 45 02AD: [ 81 ] MOVX A, @R1 02AE: [ D3 F8 ] XRL A, F8 02B0: [ C6 FD ] JZ FD 02B2: [ B9 42 ] MOV R1, 42 02B4: [ 54 3C ] CALL 23C 02B6: [ C6 FD ] JZ FD 02B8: [ 97 ] CLR C 02B9: [ 67 ] RRC A 02BA: [ AC ] MOV R4, A 02BB: [ FD ] MOV A, R5 02BC: [ C6 FD ] JZ FD 02BE: [ 74 03 ] CALL 303 02C0: [ 03 F0 ] ADD A, F0 02C2: [ F6 FD ] JC FD 02C4: [ B8 30 ] MOV R0, 30 02C6: [ FA ] MOV A, R2 02C7: [ A0 ] MOV @R0, A 02C8: [ C8 ] DEC R0 02C9: [ FB ] MOV A, R3 02CA: [ A0 ] MOV @R0, A 02CB: [ B8 41 ] MOV R0, 41 02CD: [ 81 ] MOVX A, @R1 02CE: [ BF 04 ] MOV R7, 04 02D0: [ 6B ] ADD A, R3 02D1: [ EF D0 ] DJNZ R7 D0 02D3: [ 90 ] MOVX @R0, A 02D4: [ C8 ] DEC R0 02D5: [ C9 ] DEC R1 02D6: [ BF 04 ] MOV R7, 04 02D8: [ 81 ] MOVX A, @R1 02D9: [ 6A ] ADD A, R2 02DA: [ EF D9 ] DJNZ R7 D9 02DC: [ 90 ] MOVX @R0, A 02DD: [ C8 ] DEC R0 02DE: [ C8 ] DEC R0 02DF: [ 23 4E ] MOV A, 4E 02E1: [ 90 ] MOVX @R0, A 02E2: [ B9 27 ] MOV R1, 27 02E4: [ B1 C0 ] MOV @R1, C0 02E6: [ B9 41 ] MOV R1, 41 02E8: [ B8 30 ] MOV R0, 30 02EA: [ 81 ] MOVX A, @R1 02EB: [ D3 F8 ] XRL A, F8 02ED: [ C6 FA ] JZ FA 02EF: [ F0 ] MOV A, @R0 02F0: [ AA ] MOV R2, A 02F1: [ C8 ] DEC R0 02F2: [ F0 ] MOV A, @R0 02F3: [ 97 ] CLR C 02F4: [ F7 ] RLC A 02F5: [ AB ] MOV R3, A 02F6: [ B8 32 ] MOV R0, 32 02F8: [ 64 E0 ] JMP 3E0 02FA: [ A0 ] MOV @R0, A 02FB: [ C8 ] DEC R0 02FC: [ A0 ] MOV @R0, A 02FD: [ 83 ] RET 02FE: [ 00 ] NOP ; just some NOPs to align the code 02FF: [ 00 ] NOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; GetDistanceBetweenObjects ; ; Returns the distance between 2 objects. Only one axis is compared ; ; IN: ; r0 holds pointer to foreground character data ; r1 holds pointer to sprite coordinate data ; ; OUT: ; a, r4 ABS (position sprite - position foreground character) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0300: [ 81 ] MOVX A, @R1 0301: [ AC ] MOV R4, A ; move sprite coordinate to R4 0302: [ 80 ] MOVX A, @R0 ; move foreground character coordinate to A 0303: [ 37 ] CPL A ; 0304: [ 17 ] INC A ; A = - A 0305: [ 6C ] ADD A, R4 ; add sprite position 0306: [ F6 0A ] JC 0A ; if result is positive, move to 0x30a 0308: [ 37 ] CPL A ; outcome is negative, so complement and 0309: [ 17 ] INC A ; add one to get corresponding positive number 030A: [ AC ] MOV R4, A ; move result to R4 030B: [ 83 ] RET 030C: [ F8 ] MOV A, R0 ; move satellite databyte to A 030D: [ AF ] MOV R7, A ; move to R7 030E: [ B8 6D ] MOV R0, 6D 0310: [ BE 0C ] MOV R6, 0C 0312: [ F8 ] MOV A, R0 0313: [ D9 ] XRL A, R1 0314: [ C6 1D ] JZ 1D 0316: [ 80 ] MOVX A, @R0 0317: [ D3 F8 ] XRL A, F8 0319: [ C6 1D ] JZ 1D 031B: [ 74 24 ] CALL 324 031D: [ C8 ] DEC R0 031E: [ C8 ] DEC R0 031F: [ C8 ] DEC R0 0320: [ C8 ] DEC R0 0321: [ EE 12 ] DJNZ R6 12 0323: [ 83 ] RET 0324: [ 81 ] MOVX A, @R1 0325: [ 6B ] ADD A, R3 0326: [ 74 01 ] CALL 301 0328: [ AD ] MOV R5, A 0329: [ 03 EC ] ADD A, EC 032B: [ 85 ] CLR F0 032C: [ F6 68 ] JC 68 032E: [ 95 ] CPL F0 032F: [ C8 ] DEC R0 0330: [ C9 ] DEC R1 0331: [ 81 ] MOVX A, @R1 0332: [ 6A ] ADD A, R2 0333: [ 74 01 ] CALL 301 0335: [ 03 F3 ] ADD A, F3 0337: [ C6 45 ] JZ 45 0339: [ F6 66 ] JC 66 033B: [ 23 FA ] MOV A, FA 033D: [ 6C ] ADD A, R4 033E: [ F6 45 ] JC 45 0340: [ 23 F3 ] MOV A, F3 0342: [ 6D ] ADD A, R5 0343: [ E6 69 ] JNC 69 0345: [ C9 ] DEC R1 0346: [ C9 ] DEC R1 0347: [ 81 ] MOVX A, @R1 0348: [ 53 70 ] ANL A, 70 034A: [ 96 5F ] JNZ, 5F 034C: [ 95 ] CPL F0 034D: [ B6 57 ] JF057 034F: [ 97 ] CLR C 0350: [ A7 ] CPL C 0351: [ FA ] MOV A, R2 0352: [ F2 55 ] JB7 55 0354: [ 97 ] CLR C 0355: [ 67 ] RRC A 0356: [ AA ] MOV R2, A 0357: [ 97 ] CLR C 0358: [ A7 ] CPL C 0359: [ FB ] MOV A, R3 035A: [ F2 5D ] JB7 5D 035C: [ 97 ] CLR C 035D: [ 67 ] RRC A 035E: [ AB ] MOV R3, A 035F: [ 19 ] INC R1 0360: [ 19 ] INC R1 0361: [ FF ] MOV A, R7 0362: [ 28 ] XCH A, R0 0363: [ 10 ] INC @R0 0364: [ 28 ] XCH A, R0 0365: [ AF ] MOV R7, A 0366: [ 18 ] INC R0 0367: [ 19 ] INC R1 0368: [ 83 ] RET 0369: [ C8 ] DEC R0 036A: [ C8 ] DEC R0 036B: [ 80 ] MOVX A, @R0 036C: [ 43 10 ] ORL A, 10 036E: [ 90 ] MOVX @R0, A 036F: [ B8 15 ] MOV R0, 15 0371: [ BC 78 ] MOV R4, 78 0373: [ BE 02 ] MOV R6, 02 0375: [ 80 ] MOVX A, @R0 0376: [ 53 C0 ] ANL A, C0 0378: [ C6 83 ] JZ 83 037A: [ CC ] DEC R4 037B: [ CC ] DEC R4 037C: [ CC ] DEC R4 037D: [ CC ] DEC R4 037E: [ 18 ] INC R0 037F: [ 18 ] INC R0 0380: [ 18 ] INC R0 0381: [ EE 75 ] DJNZ R6 75 0383: [ 23 CF ] MOV A, CF 0385: [ 90 ] MOVX @R0, A 0386: [ FC ] MOV A, R4 0387: [ A8 ] MOV R0, A 0388: [ 81 ] MOVX A, @R1 0389: [ 90 ] MOVX @R0, A 038A: [ 18 ] INC R0 038B: [ 19 ] INC R1 038C: [ 81 ] MOVX A, @R1 038D: [ 90 ] MOVX @R0, A 038E: [ C8 ] DEC R0 038F: [ C8 ] DEC R0 0390: [ 23 18 ] MOV A, 18 0392: [ 90 ] MOVX @R0, A 0393: [ 23 F8 ] MOV A, F8 0395: [ 91 ] MOVX @R1, A 0396: [ C9 ] DEC R1 0397: [ 91 ] MOVX @R1, A 0398: [ BE 01 ] MOV R6, 01 039A: [ C5 ] SEL RB0 039B: [ FB ] MOV A, R3 039C: [ D5 ] SEL RB1 039D: [ 96 A3 ] JNZ, A3 039F: [ B9 27 ] MOV R1, 27 03A1: [ B1 B6 ] MOV @R1, B6 03A3: [ 83 ] RET ; ; ; 03A4: [ B8 25 ] MOV R0, 25 03A6: [ F0 ] MOV A, @R0 ; get intram 0x25 03A7: [ 53 0F ] ANL A, 0F ; [0, 0x0f] 03A9: [ AF ] MOV R7, A ; move to r7 03AA: [ 03 F5 ] ADD A, F5 03AC: [ E6 B1 ] JNC B1 ; a smaller than 0b? jmp b1 03AE: [ 03 04 ] ADD A, 04 ; add 04 03B0: [ AF ] MOV R7, A ; move to r7 03B1: [ 1F ] INC R7 ; inc r7 03B2: [ B8 3D ] MOV R0, 3D 03B4: [ B9 6E ] MOV R1, 6E ; basically select a random foreground character 03B6: [ C8 ] DEC R0 03B7: [ C9 ] DEC R1 03B8: [ C9 ] DEC R1 03B9: [ C9 ] DEC R1 03BA: [ C9 ] DEC R1 03BB: [ EF B6 ] DJNZ R7 B6 03BD: [ 81 ] MOVX A, @R1 ; r1 = 3rd byte of foreground char 03BE: [ 92 FE ] JB4, FE ; bit 4 set? (homing satellite) (ret) 03C0: [ 19 ] INC R1 03C1: [ 19 ] INC R1 03C2: [ 19 ] INC R1 ; move to y-pos of satellite 03C3: [ 81 ] MOVX A, @R1 ; get in A 03C4: [ D3 F8 ] XRL A, F8 ; is F8? (invisible) 03C6: [ C6 FE ] JZ FE ; yes. jmp FE (ret) 03C8: [ F0 ] MOV A, @R0 ; get satellite data from intram. 03C9: [ 03 10 ] ADD A, 10 ; add 0x10 03CB: [ A0 ] MOV @R0, A ; store 03CC: [ 53 F0 ] ANL A, F0 ; take 4 high bits 03CE: [ 96 DB ] JNZ, DB ; one of them set? jmp DB 03D0: [ 10 ] INC @R0 ; increment with 1 03D1: [ F0 ] MOV A, @R0 ; get satellite data to A 03D2: [ D3 10 ] XRL A, 10 ; XRL with 10. 03D4: [ 96 D7 ] JNZ, D7 ; bit 4 not set? jmp D7 03D6: [ A0 ] MOV @R0, A ; store in satellite data 03D7: [ F0 ] MOV A, @R0 ; get it again. 03D8: [ 43 10 ] ORL A, 10 ; put bit 4 on. 03DA: [ A0 ] MOV @R0, A ; store it. 03DB: [ F0 ] MOV A, @R0 03DC: [ 53 0F ] ANL A, 0F ; get 4 lower bits 03DE: [ 14 00 ] CALL Get_deltaxy_for_firing ; A is direction for Fire 03E0: [ 74 0C ] CALL 30C 03E2: [ 81 ] MOVX A, @R1 03E3: [ 6B ] ADD A, R3 03E4: [ 91 ] MOVX @R1, A 03E5: [ 03 F8 ] ADD A, F8 03E7: [ E6 F9 ] JNC F9 03E9: [ 81 ] MOVX A, @R1 03EA: [ 03 47 ] ADD A, 47 03EC: [ F6 F9 ] JC F9 03EE: [ C9 ] DEC R1 03EF: [ 81 ] MOVX A, @R1 03F0: [ 6A ] ADD A, R2 03F1: [ 91 ] MOVX @R1, A 03F2: [ 19 ] INC R1 03F3: [ C6 F9 ] JZ F9 03F5: [ 03 50 ] ADD A, 50 03F7: [ E6 FE ] JNC FE 03F9: [ 23 F8 ] MOV A, F8 03FB: [ 91 ] MOVX @R1, A 03FC: [ C9 ] DEC R1 03FD: [ 91 ] MOVX @R1, A 03FE: [ 83 ] RET 03FF: [ 00 ] NOP intram 10 - 12 countdown timers?? some how linked to satellite movement. 24 length of player name 25 general counter. Used for many subroutines. (int_25) 27 set to 56 after keypress for name, set to AC after hitting satellite, set to A4 after player fire. set to F5 after 2b increment (and smaller then 10) set to 0 after player hit. 28 counter linked to satellite movement 2A counter linked to particle movement reset to zero when particle is moved. every 4th increment, 2B is alo incremented 2B counter linked to particle movement reset to zero when particle is moved. Probably index to particle place in shield also used to find leading dot. bit 4?? player does not die if bit 4 is set 2C used in update_status_bar 2D used in update_status_bar (bit 1,2) 2F ?? 30 ?? 32-3C foreground character satellite movement?? 3C = char0, 3B is char1, 32 is char11 EXRAM 004 - 007 highscore 008 - 00F '[rightarrow]??????[space]' 010 - 013 score 014 ?? loops from 0x00 - 0x0f. 15 - 1D Controls location and direction of shield particles. 3 bytes per particle 1st byte status, 2nd byte y-offset, 3rd byte x-offset. Used for explosions 1st byte: bit 7 set -> explosion shrapnel bit 6 set -> explosion bit 5 set -> explosion2 03D has something to do with particle movement. Set to 0x10 after particle move. 033-03c Satellite data? 025 Type of Satellite? values can be 00,04,08,0C 023 Direction of fire 0 = right, 1 = right/little down, 2 = right/more down, etc. 022 countdown timer for changing fire direction fire_direction 7D - 3E goes to VDC 0x00 3C- 2D goes to VDC 0x80 3rd byte of foreground char: normal homing bit 4 set (of 3rd character byte) UFO bit 5 set (of 3rd character byte) Laser from UFO bit 6 set (of 3rd character byte) 3rd byte of sprite: bit 0 object hit bit 1 Quote Link to comment Share on other sites More sharing options...
Gorf Posted March 7, 2009 Share Posted March 7, 2009 You sir, truly have quite a pair to attempt such a thing! Nice work indeed! Have you been to the VideoPac/Odyssey^2 forums yet? http://videopac.nl/forum/index.php We'd love to have you join us there. Gorf^2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.