From 3715d95f77cc22373f173d53a1463a5c7de48405 Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 10:27:10 -0600 Subject: [PATCH 1/2] Reads the input file in one pass. Nicer repetition of spaces in output (robertlipe). --- aard1.asm | 2040 +++++++++++++++++++++++++++++++++++++++++++++++++ aard1.new.asm | 2040 +++++++++++++++++++++++++++++++++++++++++++++++++ pretty6502.c | 72 +- 3 files changed, 4119 insertions(+), 33 deletions(-) create mode 100755 aard1.asm create mode 100644 aard1.new.asm diff --git a/aard1.asm b/aard1.asm new file mode 100755 index 0000000..af203eb --- /dev/null +++ b/aard1.asm @@ -0,0 +1,2040 @@ + ; + ; Aardvark + ; + ; by Oscar Toledo G. (nanochess) + ; + ; Creation date: Sep/02/2016. + ; Revision date: Dec/02/2016. Added holes and playfield mouth/eggs. + ; Revision date: Dec/03/2016. Added enemy bitmaps and color. + ; Revision date: Dec/04/2016. Tongue can be started/reverted with joystick. + ; Added eggs in board. + ; Revision date: Dec/06/2016. Tongue rules more close to arcade. Queen ants + ; are now fixed and flashing. Counts eaten eggs + ; and score. Displays score. + ; Revision date: Dec/07/2016. Enemies are filled randomly, also two speeds. + ; Aardvark centered. Dots are thicker now (uses + ; 2 rows). Aardvark walks slower. + ; Revision date: Dec/11/2016. Now is main bank of 8K ROM. Worm appears at + ; tongue tip level. Player can eat ants and + ; worms. + ; Revision date: Dec/12/2016. Enemy collisions now are checked here to avoid + ; too many cycles used in display. + ; Revision date: Jan/18/2016. Added Ranz des Vaches and Mountain King music. + ; Revision date: Jan/19/2016. Corrected lack of feet in aardvark. Added + ; tongue touched music. Added sound effects. + ; Aardvark exits level when all eggs eaten. + ; Remade code for collision of tongue. Corrected + ; bug where eating right queen would delete left + ; queen. + ; Revision date: May/27/2017. Moved all display code to bank 0, this makes it + ; to work with Atari Flashback Portable. + ; Revision date: Oct/02/2017. Sun moves to left. Counts level. + ; Revision date: Oct/08/2017. Added tongue retrain sound effect. Changes hole + ; position randomly. + ; Revision date: Oct/09/2017. Lives counting. Avoids worm appearing over ant. + ; Going down has priority over going left/right + ; but tries also left/right. New enemies: red + ; ant and caterpillar. Only one worm can appear + ; at any moment. Added more difficulty per level. + ; Calculates bonus. New enemy: spider. + ; Revision date: Oct/10/2017. Solved bug where worm would overwrite spider. + ; Solved bug where tongue removed eggs without + ; adjusting egg count. Solved bug where 150 points + ; sprites wouldn't disappear. Added click sound + ; effect for sunset. Added title screen. + ; Revision date: Nov/01/2017. Changed holes1-6 to bitmap interpretation. + ; Revision date: Nov/02/2017. Moved eggs and tongue to extra RAM (Sara chip). + ; Revision date: Nov/03/2017. Renamed level as antHill. Now tongue and eggs + ; bitmaps are intermixed (new display kernel). + ; Sprites now appear at right places. Now hole + ; map is aligned with kernelLst. Updated egg + ; count. Configurable X-limit. + ; Revision date: Nov/04/2017. Relocated direction bit. Collisions working + ; again. + ; Revision date: Nov/05/2017. Corrected worm catch. Score resets REFP0/1. + ; Collision working again. Supports player + ; reflection in display kernel. + ; + + ; Next available label: aa128 + ; Free label: aa84, aa85 + + ; TODO: + ; * Bug: live counting isn't working right. + ; * Bug: egg counting isn't working right. + ; * Tune collisions. + ; * Check if spider is working. + ; * Bug: slight bam tone after winning music. + ; * Bug: spider is slow to appear or doesn't appear. + ; * Handle holes like a bitset instead of coordinate. + ; * Allow backtracking (using up) + ; * Test in MAME for movement details + ; * Clouds (using PF) + ; * Maybe new aardvark sprite, maybe multicolor, maybe 48px: + ; * Aardvark moving ears. + ; * Aardvark sprite sitting when tongue is touched. + ; * Aardvark walking. + ; * Options in title screen. + ; * Starting level. + ; * Message "Press start" in title screen. + ; * Intermediate screen (losing live and completing level): + ; ants + ; x worms + ; * 10 = bonus + ; * Game over (shown below intermediate screen) + ; * Give an extra live each 20000 points. + + ; Differences versus arcade: + ; * Arcade has 8 tunnels, we have 7. + ; * Red ant appears at tunnel 4, in arcade is 5. + ; * Centipede appears at tunnel 5, in arcade is 6. + ; * Worm can appear at tunnel 7 in arcade (we have no space in screen) + + ; Things in unreleased ROM: + ; * Sun timer using a digit counter. + ; * White line after first bottom section + ; * Level and time in second bottom section (separated) + + ; Game in brief: + ; * Move tongue in joystick direction. + ; * Press button to retrain tongue. + ; * Bugs appear randomly on both sides. + ; * Bug touching tongue -> lost life. + ; * Tongue touching bug from behind -> score. + ; * Spider descends from top to bottom, if touch tip -> lost life. + ; * If tongue eats queen -> all enemies in board disappear. + ; * Eating all dots -> level change. + ; * Each level has different configuration of holes in floors. + ; * Ant: 100 points, appears starting in level 1, tunnels 1-4 + ; * Red ant: 150 points, appears starting in level 2, tunnel 5 + ; * Centipede: 150 points, appears starting in level 3, tunnel 6 + ; * Worm: 200 points, appears always at level of tongue. + ; * Only enemy that can appear at tunnel 7. + ; * Tongue cannot move in tunnel 8, nor there are points, only can eat queen. + ; * On restarting level the holes configuration changes. + ; * On restarting level preserves darkness even if the initial animation is + ; done again. + ; * Sun starts more at left per level. Since level 22 always starts barely + ; some pixels from left. + ; * Extra lives each 20000 points + + processor 6502 + + include aardm.asm + + ; + ; Set object in X + ; A = X position + ; First argument = Object to position (0=P0, 1=P1, 2=M0, 3=M1, 4=BALL) + ; + MAC set_x_position + sta WSYNC ; 0- Start line synchro + sec ; 2- Set carry flag (avoids it in loop) +.AE2: sbc #15 ; 4- Uses required time dividing A by 15 + bcs .AE2 ; 6/7 - 11/16/21/26/31/36/41/46/51/56/61/66 + tay ; 8 + lda fine_adjustment-$f1,y; 13 - Eats 5 cycles crossing page + sta HMP0+{1} + nop + sta RESP0+{1} ; 21/26/31/36/41/46/51/56/61/66/71 - "big" positioning + ENDM + + org $f000 ; ROM start address (4K) + + REPEAT 256 + .byte $4f + REPEND + +START: + sta bank1 ; Ghost + sei ; Disable interruptions + cld ; Disable decimal mode + jmp START2 + +ba0: sta bank0 + jmp 0 ; Ghost + + sta bank1 ; Ghost + jmp ba1 + +ba2: sta bank0 + jmp 0 ; Ghost + + sta bank1 + jmp ba3 + +START2: + ldy rand + ; Clean up the memory + ldx #$ff ; Load X with $FF... + txs ; ...copy to stack pointer + lda #0 ; Load zero in accumulator +AE1: sta 0,X ; Save in address 0 plus X + dex ; Decrement X + bne AE1 ; Repeat until X is zero. + sta SWACNT ; Allow to read joysticks + sta SWBCNT ; Allow to read buttons + tsx ; ldx #$ff + stx prev_button + sty rand + + lda rand + sta level_seed + +title_screen: + lda #20 + sta temp1 + jmp ba2 + +ba3: + lda #0 + sta antHill + lda #4 + sta lives + + lda #0 + sta score + sta score+1 + sta score+2 + + ldx #tongue_size*2-12 +aa124: lda #0 + sta tongue1+W,x + sta tongue1+W+1,x + sta tongue1+W+2,x + sta tongue1+W+3,x + sta tongue1+W+4,x + sta tongue1+W+5,x + txa + sec + sbc #12 + tax + bpl aa124 + + ; + ; Goes to next level + ; +next_level: + inc antHill + inc level_seed + + ; + ; Setup starting sun position + ; + lda antHill + asl + bmi aa82 + asl + bpl aa83 +aa82: lda #$80 +aa83: eor #$ff + adc #$98 + sta sun_pos + + lda #$00 + sta COLUBK ; Background color + + ; VERTICAL_SYNC + lda #2 + sta VSYNC ; Start vertical synchro + sta WSYNC ; Wait for 3 lines + sta WSYNC + sta WSYNC + ; + lda #43 + sta TIM64T + lda #0 + sta VSYNC ; Stop vertical synchro + + ldx #tongue_size*2-12 +aa29: lda #0 + sta tongue1+W,x + sta tongue1+W+1,x + sta tongue1+W+2,x + sta tongue1+W+3,x + sta tongue1+W+4,x + sta tongue1+W+5,x + cpx #0 + beq .+4 + lda #$aa + sta eggs1+W,x + sta eggs1+W+2,x + sta eggs1+W+3,x + sta eggs1+W+5,x + lsr + sta eggs1+W+1,x + sta eggs1+W+4,x + txa + sec + sbc #12 + tax + bpl aa29 + + lda #7*20 + sta eggs + + ; + ; Setup queen ants + ; + lda #sprite_queen_ant+ENEMY_DIR_MASK + sta enemy0_t + sta enemy8_t + lda #$2e + sta enemy0_x + lda #$66 + sta enemy8_x + + jmp aa73 + +restart_level: + inc level_seed + lda #$00 + sta effect0 + sta effect1 + sta ants_eaten + sta worms_eaten + sta COLUBK ; Background color + + ; VERTICAL_SYNC + lda #2 + sta VSYNC ; Start vertical synchro + sta WSYNC ; Wait for 3 lines + sta WSYNC + sta WSYNC + ; + lda #43 + sta TIM64T + lda #0 + sta VSYNC ; Stop vertical synchro + +aa73: + lda #1 ; Ranz des Vaches (Rossini) + sta tracker + lda #1 ; Start immediately + sta tracker_c + + lda #6 + sta aa_x_pos + lda #1 + sta timer + lda #0 + sta filling + sta flags + ; + ; Delete tongue and delete also any eggs under + ; + ldx #tongue_size*2-12 +aa69: + ldy #5 +aa80: lda tongue1+R,x + eor #$ff + and eggs1+R,x + sta eggs1+W,x + lda #0 + sta tongue1+W,x + inx + dey + bpl aa80 + txa + sec + sbc #18 + tax + bpl aa69 + + lda #0 + sta enemy1_t + sta enemy2_t + sta enemy3_t + sta enemy4_t + sta enemy5_t + sta enemy6_t + sta enemy7_t + sta enemy9_t + sta enemy10_t + sta enemy11_t + sta enemy12_t + sta enemy13_t + sta enemy14_t + sta enemy15_t + sta holeCols + sta holeCols+1 + sta holeCols+2 + sta holeCols+3 + sta holeCols+4 + sta holeCols+5 + sta holeCols+6 + sta holeCols+7 + lda #$ff + sta tip_y + jmp aa75 + +main_loop: + lda #$00 + sta COLUBK ; Background color + + ; VERTICAL_SYNC + lda #2 + sta VSYNC ; Start vertical synchro + sta WSYNC ; Wait for 3 lines + sta WSYNC + sta WSYNC + ; + lda #43 + sta TIM64T + lda #0 + sta VSYNC ; Stop vertical synchro + +aa75: + ; Nanochess' mini sound effects player + ldx tracker + bne ef4 + lda effect0 + beq ef0 + tax + lda sound_effect,x + bne ef1 + sta effect0 + beq ef0 + +ef1: sta AUDF0 + lda sound_effect+1,x + sta AUDC0 + lsr + lsr + lsr + lsr + inx + inx + stx effect0 + +ef0: sta AUDV0 + + lda effect1 + beq ef2 + tax + lda sound_effect,x + bne ef3 + sta effect1 + beq ef2 + +ef3: sta AUDF1 + lda sound_effect+1,x + sta AUDC1 + lsr + lsr + lsr + lsr + inx + inx + stx effect1 + +ef2: sta AUDV1 + bpl tr0 + + ; Nanochess' mini tracker +ef4: + ldx tracker + beq tr1 + dec tracker_c + bne tr3 + lda music-1,x + bne tr2 + sta tracker + beq tr1 + +tr2: and #$1f + asl + tay + lda music_notes-2,y + sta AUDC0 + lda music_notes-1,y + sta AUDF0 + lda music-1,x + lsr + lsr + and #$38 + sta tracker_c + lda music,x + asl + tay + lda music_notes-2,y + sta AUDC1 + lda music_notes-1,y + sta AUDF1 + inx + inx + stx tracker + lda #$3f + sta tracker_v +tr3: dec tracker_v + lda tracker_v + lsr + lsr + cpx #43 + bcs tr1 + lda tracker_v + and #$03 + bne tr4 + lda #$02 +tr4: ora #$0c +tr1: sta AUDV0 + sta AUDV1 +tr0: + + lda aa_x_pos + cmp #$0f ; Corrects left side X-pos, for some reason it breaks. + bcs *+4 + sbc #2 + set_x_position 0 ; Player 0 + ; ldx #1 ; Player 1 + lda sun_pos + set_x_position 1 ; Player 1 + lda #84 + set_x_position 2 ; Missile 0 + lda #$20 + sta NUSIZ0 + sta NUSIZ1 + + jsr build_hole_map + + lda #$00 + sta GRP0 + sta GRP1 + sta COLUPF + lda #$20 + sta CTRLPF + + jmp ba0 + +ba1: + + ; + ; Score zone + ; + sta WSYNC ; 0 + ldx #$00 ; 3 + stx COLUBK ; 5 Background color + stx GRP0 ; 8 + stx GRP1 ; 11 + stx REFP0 ; 14 + stx REFP1 ; 17 + sta en5 ; 20 + lda score ; 23 + and #$0f ; 26 + asl ; 28 + asl ; 30 + asl ; 32 + sta en4 ; 34 + lda score ; 37 + lsr ; 40 + and #$78 ; 42 + sta en3 ; 44 + lda #$21 ; 47 + sta CTRLPF ; 49 + lda #lives_color ; 52 + sta COLUPF ; 54 + ldx lives ; 57 + cpx #7 ; 60 + bcc aa88 ; 62 + ldx #7 ; 64 +aa88: + lda lives_pf,x ; 66 + sta WSYNC ; 71 + sta PF0 + lda lives_pf+8,x + sta PF1 + lda lives_pf+16,x + sta PF2 + lda score+1 ; 35 + and #$0f ; 38 + asl ; 40 + asl ; 42 + asl ; 44 + sta en2 ; 46 + lda score+1 ; 49 + lsr ; 52 + and #$78 ; 54 + sta en1 ; 56 + lda score+2 ; 59 + and #$0f ; 62 + asl ; 64 + asl ; 66 + asl ; 68 + sta en0 ; 70 + ldx #0 + + lda #score_color ; 73 + jmp $f400 ; 75 + org $F400 +mp0: + sta WSYNC + stx GRP0 + stx GRP1 + ldy #numbers>>8 ; 8 + sty en0+1 ; 11 + sty en1+1 ; 14 + sty en2+1 ; 17 + sty en3+1 ; 20 + sty en4+1 ; 23 + sty en5+1 ; 26 + + sta COLUP0 ; 29 + sta COLUP1 ; 32 + lda #$03 ; 35 3 copies together + ldx #$f0 ; 37 + stx RESP0 ; 39 + stx RESP1 ; 42 + stx HMP0 ; 45 + sta NUSIZ0 ; 48 + sta NUSIZ1 ; 51 + lsr ; 53 + sta VDELP0 ; 56 + sta VDELP1 ; 59 + lsr + sta HMP1 + sta WSYNC ; 62 + sta HMOVE ; 3 + lda #4 + sta temp2 +mp1: ldy temp2 ; 2 + lda (en0),y ; 7 + sta GRP0 ; 10 + sta WSYNC ; 13 + 61 = 76 + lda (en1),y ; 5 + sta GRP1 ; 8 + lda (en2),y ; 13 + sta GRP0 ; 16 + lda (en3),y ; 21 + sta temp1 ; 24 Write (this depends on being at "root" stack pos) + lda (en4),y ; 29 (and of course not being called) + tax ; 31 + lda (en5),y ; 36 + tay ; 38 + lda temp1 ; 41 Read + sta GRP1 ; 44 + stx GRP0 ; 47 + sty GRP1 ; 50 + sta GRP0 ; 53 + dec temp2 ; 58 + bpl mp1 ; 60/61 +mp3: + ; Looks for code spanning page + if (mp1&$ff00)!=(mp3&$ff00) + lda megabug3 ; :P + endif + echo "mp0 ",mp0," mp1 ",mp1," mp3 ",mp3 + + ; + ; End of graphics (204 lines) + ; + ldx #$00 + lda #2 + sta WSYNC + sta VBLANK + stx VDELP0 + stx VDELP1 + stx GRP0 + stx GRP1 + stx PF0 + stx PF1 + stx PF2 + + ; + ; Start overscan timer + ; + lda #43 ; 37 lines * 76 = 2812 cycles / 64 = 43.9375 + sta TIM64T + + lda flags + and #$03 + cmp #$02 ; Tongue touched? + bne aa67 + jmp wait_overscan + +aa67: lda eggs + bne aa70 + ldx aa_x_pos + cpx #52 + bne aa71 + inc aa_x_pos + lda #43 ; Mountain King (Grieg) + sta tracker + lda #1 + sta tracker_c + lda #0 + sta filling + sta flags + ldx #tongue_size*2-1 + lda #0 +aa72: sta tongue1+W,x + dex + bpl aa72 + + sta enemy0_t + sta enemy1_t + sta enemy2_t + sta enemy3_t + sta enemy4_t + sta enemy5_t + sta enemy6_t + sta enemy7_t + sta enemy8_t + sta enemy9_t + sta enemy10_t + sta enemy11_t + sta enemy12_t + sta enemy13_t + sta enemy14_t + sta enemy15_t + sta holeCols + sta holeCols+1 + sta holeCols+2 + sta holeCols+3 + sta holeCols+4 + sta holeCols+5 + sta holeCols+6 + sta holeCols+7 + lda #$ff + sta tip_y +aa71: jmp aa34 + +aa70: lda flags + and #$fc + sta flags + + ; + ; Check for collisions of enemies versus tongue (playfield pixels) + ; + ldx #15 +aa53: lda enemy0_t,x + tay + cmp #non_interactive_sprites + bcc aa86 + cpx #8 + bcs aa45 + lda cxLst,x + and #$20 + beq aa86 ; No, jump + bne aa127 + +aa45: lda cxLst-8,x + asl + bpl aa86 + +aa127: tya + and #$f0 + cmp #sprite_spider + beq aa106 + cmp #sprite_worm ; Is it a worm? + beq aa55 + bne aa87 + +aa86: + dex + bpl aa53 + jmp aa78 + + ; + ; Spider + ; * Kills if touches tongue tip + ; +aa106: + txa + and #$07 + cmp tip_y ; Is it at same level than tongue? + bne aa86 ; No, jumps + lda enemy0_x,x + tay + sbc #3 + lsr + lsr + cmp tip_x + beq aa56sc + tya + clc + adc #10 + lsr + lsr + cmp tip_x + beq aa56sc + bne aa86 + +aa87: + ; + ; Ant: + ; * Eaten if tongue tip. + ; * Kills if it touch any other part of tongue. + ; + txa + and #$07 + cmp tip_y ; Is it at same level than tongue? + bne aa56sc ; No, kills + lda enemy0_x,x + sbc #3 + tay + lsr + lsr + cmp tip_x + beq aa57 + bcs aa56 + tya + clc + adc #10 + lsr + lsr + cmp tip_x + beq aa57 + bcc aa56 + +aa57: lda enemy0_t,x + cmp #sprite_queen_ant+$20 + bcs aa125 + cmp #sprite_queen_ant + bcs aa59 +aa125: cmp #pricey_sprites ; Red ant and caterpillar + bcs aa97 + sed + lda ants_eaten + adc #1 + sta ants_eaten + cld + lda #sprite_explosion; Goodbye ant + .byte $2c ; BIT opcode to jump +aa97: lda #sprite_150 + ldy #11 + bne aa79 + +aa56sc: jmp aa56 + +aa59: jsr clear_enemies + ldy #33 +aa79: sty effect1 + bne aa60 + + ; + ; Worm: + ; * Eaten if tongue tip from behind. + ; * Kills only if tongue tip in front. + ; +aa55: txa + and #$07 + cmp tip_y + bne aa54 + lda enemy0_x,x + tay + sbc #3 + lsr + lsr + cmp tip_x + beq aa58 + bcs aa54 + tya + clc + adc #10 + lsr + lsr + cmp tip_x + beq aa58 + bcc aa54 +aa58: lda tip_dir + beq aa56 + lsr ; $ff left $00 right + eor enemy0_t,x + and #ENEMY_SPEED_MASK + bne aa56 + lda flags + and #~FLAGS_WORM + sta flags + inc worms_eaten + lda #20 + sta effect1 + lda #sprite_200 ; 200 points +aa60: sta enemy0_t,x + bne aa54 + + ; Kill +aa56: lda flags + and #$fc + ora #$01 + sta flags + +aa54: + dex + bmi aa78 + jmp aa53 +aa78: + + lda flags + and #$03 + beq aa52 + jmp wait_overscan + + ; + ; Invoke an enemy + ; +aa52: + dec timer + beq aa95 + jmp aa14 +aa95: + jsr random_proc ; Get a random number (just because :P) + tay ; Save it + and #$0e ; Restart timer + ora #$01 + sta timer + lda antHill ; Starts at 1 + clc + adc #$03 ; Level 1 - fills 4 tunnels, 2 - 5 t., 4 and so- 6 t. + cmp #$06 ; No more than 6 tunnels + bcc aa92 + lda #$06 +aa92: asl + sta temp1 + lda filling + cmp temp1 + bcc aa102 +aa103: jmp aa8 +aa102: + and #$0e + lsr + eor #$07 + tax + cmp #$07 + bne aa111 + lda enemy8_t,x + bne aa111 + lda #FLAGS_SPIDER + bit flags + bne aa111 + lda sun_pos + cmp #8 ; Now it's night? + beq aa110 ; No, jump +aa111: lda enemy0_t,x ; There is space for a common enemy? + beq aa12 ; Yep, jump. +aa110: lda enemy8_t,x ; There is space for a worm/spider? + bne aa103 ; No, jump + cpx #0 ; Top tunnel? + bne aa101 ; No, jump + lda sun_pos + cmp #8 ; Now it's night? + bne aa101 ; No, jump + lda #FLAGS_SPIDER + bit flags ; We have already the spider? + bne aa101 ; Yes, jump + ora flags + sta flags + lda #ENEMY_MAX_X + sta enemy8_x,x + tya + and #ENEMY_SPEED_MASK + ora #sprite_spider + sta enemy8_t,x + bne aa8 + +aa101: + txa + and #$07 + cmp tip_y + bne aa103 + lda #FLAGS_WORM + bit flags ; Already a worm in screen? + bne aa8 ; Yes, jump + ora flags + sta flags + tya + and #$40 + beq aa37 + lda enemy0_x,x + cmp #40 + bcc aa90 +aa91: lda #ENEMY_MIN_X + sta enemy8_x,x + tya + and #ENEMY_SPEED_MASK + ora #sprite_worm+ENEMY_DIR_MASK + sta enemy8_t,x + bne aa8 + +aa37: lda enemy0_x,x + cmp #129 + bcs aa91 +aa90: lda #ENEMY_MAX_X + sta enemy8_x,x + tya + and #ENEMY_SPEED_MASK + ora #sprite_worm + sta enemy8_t,x + bne aa8 + +aa12: tya + and #$40 + beq aa15 + lda #ENEMY_MIN_X + sta enemy0_x,x + tya + and #ENEMY_SPEED_MASK + ora enemies_going_right,x + sta enemy0_t,x + bne aa8 + +aa15: lda #ENEMY_MAX_X + sta enemy0_x,x + tya + and #ENEMY_SPEED_MASK + ora enemies_going_left,x + sta enemy0_t,x + ; bne aa8 + +aa8: ldx antHill + cpx #32 + bcc aa93 + ldx #31 +aa93: lda filling + clc + adc #2 + cmp refilling,x + bne aa94 + lda #0 +aa94: sta filling +aa14: + + ; + ; Sun animation + ; + lda frame + and #$1f ; Each 32 frames + bne aa81 + lda sun_pos + cmp #8 + beq aa81 + dec sun_pos ; Move sun left by one pixel + cmp #9 + bne aa81 + lda #129 ; Click effect + sta effect0 +aa81: + + ; + ; Enemy animation and movement + ; + ldy #0 + lda frame + and #$07 ; Enemies change animation frame each 8 frames + bne aa11 + ldy #8 +aa11: and #$03 ; Enemies move each 4 frame + beq aa117 + jmp aa43 +aa117: + ldx #$0f +aa10: + lda enemy0_t,x ; Active enemy? + bne aa118 ; Yes, jump +aa120: dex + bpl aa10 + jmp aa43 + + ; + ; Check first for brief sprites (explosion, 150 and 200 points) + ; +aa118: cmp #non_interactive_sprites + bcs aa39 +aa49: inc enemy0_t,x + cmp #sprite_150+$03 + beq aa96 + cmp #sprite_200+$03 + beq aa46 + cmp #sprite_200_spider+$03 + beq aa46 + cmp #sprite_explosion+$03 + bne aa38sd + lda #$10 ; 100 points + .byte $2c ; BIT opcode to jump +aa46: lda #$20 ; 200 points + .byte $2c ; BIT opcode to jump +aa96: lda #$15 ; 150 points + jsr score_points + lda #$00 + sta enemy0_t,x +aa38sd: jmp aa38 + ; + ; All other sprites + ; +aa39: and #$f0 + cmp #sprite_spider + bne aa108 + ; + ; Spider handling + ; + lda tip_y ; Tongue tip active? + bmi aa120 ; No, jump (spider stays quiet) + txa ; Get vertical position of spider + and #$07 + cmp tip_y ; Comparison with tongue tip vertical position. + beq aa109 ; Same vertical position? yes, jump + bcs aa120 ; Jump if spider deeper than tongue tip. It shouldn't happen + stx temp1 + tax + lda holeCols,x ; Check if tongue goes thru a hole !!! + lsr + bcs aa112 + lsr + bcs aa113 + lsr + bcs aa114 + lda #0 + .byte $2c ; BIT opcode to jump +aa114: lda #8 + .byte $2c ; BIT opcode to jump +aa113: lda #16 + .byte $2c ; BIT opcode to jump +aa112: lda #24 + clc + adc kernelLst,x + tax + lda hole_pos,x ; Now get the X-coordinate for hole + ldx temp1 + sec ; There's an X-coordinate, center spider over it + sbc #2 + jmp aa116 + + ; + ; Spider at same level than tongue tip + ; +aa109: lda tip_x + asl + asl + beq aa116 + sbc #1 +aa116: sbc enemy0_x,x ; Take a decision of direction to move + beq aa119 ; At target position? yes, jump + bcc aa44 + bcs aa40 + + ; + ; Try to lower spider by one level + ; +aa119: cpx #1 ; Is spider at bottom-most position? + beq aa41 ; Yes, jump, stay quiet + cpx #9 + beq aa41 + lda enemy0_t-1,x ; Is it busy the next enemy slot? + bne aa41 ; Yes, jump, stay quiet + lda enemy0_x,x ; Copy X position + sta enemy0_x-1,x + lda enemy0_t,x ; Copy type + sta enemy0_t-1,x + lda #0 ; Erase spider from old slot + sta enemy0_t,x + beq aa41 + + ; + ; Ant, red ant, worm or centipede + ; +aa108: + cmp #sprite_queen_ant + beq aa38 + cmp #sprite_queen_ant+$10 + beq aa38 + lda enemy0_t,x + and #ENEMY_SPEED_MASK ; Fast? + beq aa44 + lda frame + and #$04 +aa38sc: bne aa38 +aa44: + lda enemy0_t,x + and #ENEMY_DIR_MASK ; Goes to left? + bne aa40 ; No, jump + dec enemy0_x,x + lda enemy0_x,x + cmp #ENEMY_MIN_X ; Reached left limit? + bne aa41 ; No, jump +aa42: + lda enemy0_t,x + and #$f0 + cmp #sprite_worm + bne aa98 + lda flags + and #~FLAGS_WORM + sta flags +aa98: cmp #sprite_spider ; It could happen *sigh* + bne aa107 + lda flags + and #~FLAGS_SPIDER + sta flags +aa107: lda #0 + sta enemy0_t,x + beq aa38 + +aa40: + inc enemy0_x,x + lda enemy0_x,x + cmp #ENEMY_MAX_X ; Reached right limit? + beq aa42 ; Yes, jump +aa41: + tya + eor enemy0_t,x ; Changed animation frame if required + sta enemy0_t,x +aa38: dex + bmi aa43 + jmp aa10 +aa43: + + ; + ; Queen ant flashing + ; + lda frame + and #$01 + bne aa34 + lda enemy0_t + beq aa32 + cmp #non_interactive_sprites + bcs aa51 + adc #1 + cmp #sprite_1000+8 + bne aa32 + jsr score_points_2 ; 1000 points + lda #0 + beq aa32 + +aa51: adc #$07 + cmp #sprite_queen_ant+$20 + bcc aa32 + sbc #$20 +aa32: sta enemy0_t + + lda enemy8_t + beq aa33 + cmp #non_interactive_sprites + bcs aa50 + adc #1 + cmp #sprite_1000+8 + bne aa33 + jsr score_points_2 ; 1000 points + lda #0 + beq aa33 + +aa50: adc #$07 + cmp #sprite_queen_ant+$20 + bcc aa33 + sbc #$20 +aa33: sta enemy8_t +aa34: + ; + ; Count frame, step on random generator + ; + inc frame + jsr random_proc + ; + ; Aardvark enters game + ; + ldx aa_x_pos + cpx #52 + beq aa7 + lda frame + and #$07 + bne aa31 + inc aa_x_pos + cpx #51 + bne aa31 + ; Start tongue + lda #$02 + sta holeCols+7 + ldx #19 + stx tip_x + lda #7 + sta tip_y + lda #0 + sta tip_dir + jsr point_egg + ldx tip_x + lda tip_y + jsr draw_block +aa31: + lda frame + and #$07 + bne aa4 + lda aa_offset + eor #$28 + sta aa_offset +aa4: + jmp aa20 + +aa7: + lda #0 + + jsr fire_button ; Fire button pressed? + bpl aa22 ; No, jump + + ldx tip_x ; Get tongue coordinates + lda tip_y + cpx #19 + bne aa19 + cmp #7 + beq aa123 ; Is it at base? yes, jump without doing anything +aa19: + jsr clear_block + lda effect0 + cmp #128 + bcs aa122 + cmp #66 + bcs aa121 +aa122: + lda #66 + sta effect0 +aa121: ldx tip_x + beq aa23 + dex + lda tip_y + jsr check_block + bne aa24 + inx + +aa23: cpx #39 + beq aa25 + inx + lda tip_y + jsr check_block + bne aa24 + +aa25: ldx tip_y + lda #$00 + sta holeCols,x + inc tip_y + jmp aa20 + +aa24: stx tip_x + jmp aa20 + +aa123: jmp aa28 + +aa22: + jsr build_hole_map + lda SWCHA + ; Note #$10 isn't used (going up) + and #$20 ; Going down? + beq aa17 ; Yes, jump +aa18: lda SWCHA + bmi aa16 ; Going right? No, jump + lda tip_y + bmi aa28 + beq aa28 ; Last tunnel? Yes, cannot move + lda frame + lsr + bcc aa28 + ldx tip_x + cpx #39 + beq aa28 + inx +aa26: lda tip_y + jsr check_block + bne aa30 + txa + sec + sbc tip_x + sta tip_dir + stx tip_x + lda tip_y + jsr point_egg + ldx tip_x + lda tip_y + jsr draw_block + jmp aa20 + +aa30: txa + pha + ldx tip_x + lda tip_y + jsr clear_block + pla + sta tip_x +aa28: jmp aa20 + +aa16: rol ; Going left? + bmi aa20 + lda tip_y + bmi aa20 + beq aa20 ; Last tunnel? Yes, cannot move + lda frame + lsr + bcc aa20 + ldx tip_x + beq aa20 + dex + bpl aa26 + + ; + ; Going down + ; +aa17: ldx tip_y ; Get row of tongue tip + bmi aa18 ; Invalid? Yes, jump to check for right/left + beq aa18 ; Vertical limit? Yes, jump to check for right/left + lda kernelLst-1,x + tax + lda tip_x ; Tongue tip at 0? + beq aa18 ; Jump to check for right/left + cmp hole_pos,x + beq aa126 + cmp hole_pos+8,x + beq aa27 + cmp hole_pos+16,x + beq aa115 + cmp hole_pos+24,x + bne aa18 ; No hole, so jump to check for right/left + ldy #$01 + .byte $2c ; BIT opcode to jump +aa115: ldy #$02 + .byte $2c ; BIT opcode to jump +aa126: ldy #$08 + .byte $2c ; BIT opcode to jump +aa27: ldy #$04 + tya + ldx tip_y + dex + ora holeCols,x + sta holeCols,x + stx tip_y + txa + ldx tip_x + jsr point_egg + ldx tip_x + lda tip_y + jsr draw_block + lda #0 + sta tip_dir + +aa20: + +wait_overscan: + lda INTIM + bne wait_overscan + sta WSYNC + sta WSYNC + + lda aa_x_pos + cpx #135 + bne aa74 + jsr bonus_screen + jmp next_level +aa74: + + lda flags + and #$03 + cmp #$02 ; Has finished tongue color changing animation? + beq aa68 ; Yes, jump + jmp main_loop ; Continue with main loop + +aa68: dec lives + jsr bonus_screen + lda lives + bmi aa89 + jmp restart_level ; Restart level + +aa89: jmp title_screen + + ; + ; Bonus screen + ; +bonus_screen: + ldx worms_eaten + beq aa99 +aa100: + lda ants_eaten + jsr score_points + dex + bne aa100 +aa99: + rts + + ; + ; Run random number generator + ; +random_proc: + ; + ; Random number generator + ; + lda rand + sec + ror + eor frame + ror + eor rand + ror + eor #9 + sta rand + rts + + ; + ; Check for fire button + ; +fire_button_single: + lda INPT4 + eor #$ff + tax + eor prev_button + stx prev_button + bpl fire_button1 + txa +fire_button1: + rts + +fire_button: + lda INPT4 + eor #$ff + sta prev_button + rts + + ; + ; Calculate memory zone for tongue block + ; a = zone (0-7) + ; +calc_zone: + asl ; x2 + asl ; x4 + sta en0 + asl ; x8 + adc en0 ; x12 + adc #tongue1 + sta en0 + adc #W + sta en0+1 + sta en1+1 + rts + + ; + ; Check for tongue block + ; + ; a = zone (0-5) + ; x = x pixel (0-39) + ; +check_block: + jsr calc_zone + lda pixel_to_byte,x + tay + lda (en1),y + and pixel_to_bit,x + rts + + ; + ; Clear enemies (used when eating queen ant) + ; +clear_enemies: + txa + pha + ldx #9 +aa61: lda enemy0_t,x + cmp #non_interactive_sprites + bcc aa62 + and #$f0 + cmp #sprite_worm + beq aa63 + cmp #sprite_spider + beq aa104 + cmp #pricey_sprites + bcs aa64 + lda #sprite_explosion + .byte $2c ; BIT opcode to jump +aa63: lda #sprite_200 + .byte $2c ; BIT opcode to jump +aa64: lda #sprite_150 + .byte $2c ; BIT opcode to jump +aa104: lda #sprite_200_spider + sta enemy0_t,x + cmp #sprite_200_spider + bne aa105 + lda flags + and #~FLAGS_SPIDER + sta flags +aa105: + cmp #sprite_200 ; Only a worm gives a 200 points bonus + bne aa62 + lda flags + and #~FLAGS_WORM + sta flags +aa62: dex + bpl aa61 + pla + tax + lda #sprite_1000 + rts + + ; + ; Give points per egg eaten + ; + ; a = zone (0-7) + ; x = x pixel (0-39) + ; +point_egg: + cmp #0 + beq aa35 + jsr calc_zone + lda en1 + clc + adc #tongue_to_eggs + sta en1 + lda pixel_to_byte,x + tay + lda (en1),y + and pixel_to_bit,x + beq aa35 + lda eggs + ror + lda #1 + bcc aa77 + lda #6 +aa77: sta effect0 + dec eggs + lda #1 + + ; Score 1 point for egg eaten +score_points: + clc + sed + adc score + sta score +aa48: lda score+1 + adc #0 + sta score+1 + lda score+2 + adc #0 + sta score+2 + cld +aa35: + rts + +score_points_2: + sec + sed + bcs aa48 + + ; + ; Draw a tongue block + ; + ; a = zone (0-7) + ; x = x pixel (0-39) + ; +draw_block: + jsr calc_zone + lda pixel_to_byte,x + tay + lda (en1),y + ora pixel_to_bit,x + sta (en0),y + lda en0 + clc + adc #tongue_to_eggs + sta en0 + lda en1 + adc #tongue_to_eggs + sta en1 + lda (en1),y + ora pixel_to_bit,x + sta (en0),y + rts + + ; + ; Clear a tongue block + ; + ; a = zone (0-7) + ; x = x pixel (0-39) + ; +clear_block: + jsr calc_zone + lda pixel_to_byte,x + tay + lda (en1),y + and pixel_to_bit2,x + sta (en0),y + lda en0 + clc + adc #tongue_to_eggs + sta en0 + lda en1 + adc #tongue_to_eggs + sta en1 + lda (en1),y + and pixel_to_bit2,x + sta (en0),y + rts + + ; + ; Build random hole map for the current level seed + ; See also random.c + ; +build_hole_map: SUBROUTINE +.lastPat = tmpVars + lda #255 + sta .lastPat + ldy #NUM_FLOORS-1 + ldx level_seed +.0: + lda random_level,x + tax + and #$07 + cmp .lastPat + bne .1 + txa + lsr + lsr + tax + and #$07 +.1: + sta kernelLst,y + sta .lastPat + dey + bne .0 + sty kernelLst ; Fixed tunnel for queen ants + rts + + ; + ; With the help of: + ; + ; http://alienbill.com/2600/basic/music/tune2600.html + ; http://piano-player.info/ + ; + + ; + ; Songs refer to these notes. + ; These notes contain frequency and "instrument" and are + ; choosen per usage in song instead of full "continuous" octaves + ; +music_notes: + .byte 12,12 ; 1 + .byte 4,28 + .byte 4,25 ; 3 + .byte 4,22 + .byte 4,18 ; 5 + .byte 4,16 + + .byte 12,20 ; 7 + .byte 12,19 + .byte 12,18 ; 9 + .byte 12,17 + .byte 12,15 ; 11 + .byte 12,14 + .byte 12,13 ; 13 + .byte 12,11 + .byte 4,31 ; 15 + + .byte 6,7 ; 16 + .byte 6,6 ; 17 + .byte 12,27 ; 18 + .byte 12,23 ; 19 + + .byte 0,0 ; 20 Unused + + .byte 6,7 ; 21 + .byte 12,30 + .byte 12,27 ; 23 + .byte 12,24 + .byte 12,20 ; 25 + .byte 12,18 + + .byte 0,0 ; 27 Unused + .byte 1,12 ; 29 + .byte 1,6 ; 31 + .byte 1,13 ; 33 + .byte 1,9 ; 35 + .byte 0,0 + + ; + ; Global label to access music + ; +music: + + ; + ; Ranz des vaches + ; +music_ranz_des_vaches: + .byte 6*32+2,22 ; 1 -> tracker + .byte 1*32+3,23 + .byte 1*32+1,21 + .byte 1*32+2,22 + .byte 1*32+4,24 + .byte 1*32+1,21 + + .byte 6*32+2,22 + .byte 1*32+3,23 + .byte 1*32+1,21 + .byte 1*32+2,22 + .byte 1*32+4,24 + .byte 1*32+1,21 + + .byte 6*32+2,22 + .byte 1*32+4,24 + .byte 1*32+6,26 + .byte 1*32+5,25 + .byte 1*32+1,21 + .byte 1*32+4,24 + + .byte 5*32+3,23 + .byte 1*32+5,25 + + .byte 0,0 + + ; + ; Mountain king + ; +music_mountain_king: + .byte 2*32+7,16 ; 43 -> tracker + .byte 2*32+9,16 + .byte 2*32+10,18 + .byte 2*32+11,18 + .byte 2*32+13,16 + .byte 2*32+10,16 + .byte 4*32+13,18 + + .byte 2*32+12,16 + .byte 2*32+9,16 + .byte 4*32+12,18 + .byte 2*32+11,16 + .byte 2*32+8,16 + .byte 4*32+11,18 + + .byte 2*32+7,16 + .byte 2*32+9,16 + .byte 2*32+10,18 + .byte 2*32+11,18 + .byte 2*32+13,16 + .byte 2*32+10,16 + .byte 2*32+13,18 + .byte 2*32+15,18 + + .byte 2*32+14,17 + .byte 2*32+13,17 + .byte 2*32+10,19 + .byte 2*32+13,19 + .byte 7*32+14,17 + + .byte 0,0 + + ; + ; Death music + ; +music_touch: + .byte 4*32+28,28 ; 97 -> tracker + .byte 4*32+29,29 + .byte 4*32+30,30 + .byte 7*32+31,31 + .byte 0,0 + + ; + ; Global label to access sound effects + ; +sound_effect: + .byte 0 + + .byte $04,$81 ; 1 Eating egg (1) + .byte $03,$71 ; 3 + .byte 0 ; 5 + + .byte $08,$81 ; 6 Eating egg (2) + .byte $07,$71 ; 8 + .byte 0 ; 10 + + .byte $07,$88 ; 11 Eating bug + .byte $06,$88 ; 13 + .byte $07,$88 ; 15 + .byte $06,$88 ; 17 + .byte 0 ; 19 + + .byte $1c,$fc ; 20 Eating worm + .byte $1c,$cc ; 22 + .byte $1c,$ac ; 24 + .byte $1c,$8c ; 26 + .byte $1c,$6c ; 28 + .byte $1c,$4c ; 30 + .byte 0 ; 32 + + .byte $1c,$fc ; 33 Eating queen + .byte $1c,$cc ; 35 + .byte $1c,$ac ; 37 + .byte $1c,$8c ; 39 + .byte $1c,$6c ; 41 + .byte $1c,$4c ; 43 + .byte $10,$ec ; 45 + .byte $10,$cc ; 47 + .byte $10,$ac ; 49 + .byte $10,$6c ; 51 + .byte $10,$4c ; 53 + .byte $10,$3c ; 55 + .byte $10,$4c ; 57 + .byte $10,$3c ; 59 + .byte $10,$4c ; 61 + .byte $10,$3c ; 63 + .byte 0 ; 65 + + .byte $1f,$c4 ; 66 Retrain tongue + .byte $1e,$b4 ; 68 + .byte $1d,$c4 ; 70 + .byte $1c,$b4 ; 72 + .byte $1b,$c4 ; 74 + .byte $1a,$b4 ; 76 + .byte $19,$c4 ; 78 + .byte $18,$b4 ; 80 + .byte $17,$c4 ; 82 + .byte $16,$b4 ; 84 + .byte $15,$c4 ; 86 + .byte $14,$b4 ; 88 + .byte $13,$c4 ; 90 + .byte $12,$b4 ; 92 + .byte $11,$c4 ; 94 + .byte $10,$b4 ; 96 + .byte $0f,$c4 ; 98 + .byte $0e,$b4 ; 100 + .byte $0d,$c4 ; 102 + .byte $0c,$b4 ; 104 + .byte $0b,$c4 ; 106 + .byte $0a,$b4 ; 108 + .byte $09,$c4 ; 110 + .byte $08,$b4 ; 112 + .byte $07,$c4 ; 114 + .byte $06,$b4 ; 116 + .byte $05,$c4 ; 118 + .byte $04,$b4 ; 120 + .byte $03,$c4 ; 122 + .byte $02,$b4 ; 124 + .byte $01,$c4 ; 126 + .byte 0 + + .byte $18,$c1 ; 129 Click effect for sunset + .byte $0c,$61 ; 131 + .byte $06,$a1 ; 133 + .byte $03,$41 ; 135 + .byte $02,$81 ; 137 + .byte $01,$21 ; 139 + .byte 0 + + echo "Before random_level at $fd00: ",* + + org $fd00 + + .include "aardlev.asm" + + org $fe00 +fine_adjustment: + .byte $70 ; -7 + .byte $60 ; -6 + .byte $50 ; -5 + .byte $40 ; -4 + .byte $30 ; -3 + .byte $20 ; -2 + .byte $10 ; -1 + .byte $00 ; 0 + .byte $f0 ; +1 + .byte $e0 ; +2 + .byte $d0 ; +3 + .byte $c0 ; +4 + .byte $b0 ; +5 + .byte $a0 ; +6 + .byte $90 ; +7 + +pixel_to_byte: + .byte 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2 + .byte 3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5 + +pixel_to_bit: + .byte $10,$20,$40,$80 + .byte $80,$40,$20,$10,$08,$04,$02,$01 + .byte $01,$02,$04,$08,$10,$20,$40,$80 + + .byte $10,$20,$40,$80 + .byte $80,$40,$20,$10,$08,$04,$02,$01 + .byte $01,$02,$04,$08,$10,$20,$40,$80 + +pixel_to_bit2: + .byte $ef,$df,$bf,$7f + .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe + .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f + + .byte $ef,$df,$bf,$7f + .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe + .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f + + ; + ; Position for holes (in "fat" pixels) + ; Note vertical sorting, one line of holes is made from one column of data. + ; A B C D E F G H + ; +hole_pos: + .byte 0, 6, 3, 0, 0, 0, 0, 0 + .byte 12,12, 9, 6, 9, 3, 0,15 + .byte 26,18,20,26,23,15,18,23 + .byte 0,32,35,32, 0,29,29,35 + + ; + ; Lives representation as playfield graphics + ; +lives_pf: + .byte $00,$40,$40,$40,$40,$40,$40,$40 + .byte $00,$00,$80,$a0,$a8,$aa,$aa,$aa + .byte $00,$00,$00,$00,$00,$00,$01,$05 + + ; + ; Refilling constant per level + ; +refilling: + .byte 128,126,124,122,120,118,116,114 + .byte 112,110,108,106,104,102,100,98 + .byte 96,94,92,90,88,86,84,82 + .byte 80,78,76,74,72,70,68,66 + + ; + ; Enemies per tunnel + ; +enemies_going_right: + .byte 0 + .byte 0 + .byte sprite_caterpillar+ENEMY_DIR_MASK + .byte sprite_red_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte 0 + .byte 0 + .byte sprite_caterpillar+ENEMY_DIR_MASK + .byte sprite_red_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + +enemies_going_left: + .byte 0 + .byte 0 + .byte sprite_caterpillar + .byte sprite_red_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + .byte 0 + .byte 0 + .byte sprite_caterpillar + .byte sprite_red_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + + org $ff00 +numbers: + .byte $fe,$c6,$c6,$c6,$fe,$00,$00,$00 + .byte $78,$30,$30,$70,$30,$00,$00,$00 + .byte $fe,$c0,$fe,$06,$fe,$00,$00,$00 + .byte $fe,$06,$fe,$06,$fe,$00,$00,$00 + .byte $06,$06,$fe,$c6,$c6,$00,$00,$00 + .byte $fe,$06,$fe,$c0,$fe,$00,$00,$00 + .byte $fe,$c6,$fe,$c0,$fe,$00,$00,$00 + .byte $18,$18,$0c,$06,$fe,$00,$00,$00 + .byte $fe,$c6,$fe,$c6,$fe,$00,$00,$00 + .byte $fe,$06,$fe,$c6,$fe,$00,$00,$00 + + org $fffc + .word START ; RESET + .word START ; BRK + diff --git a/aard1.new.asm b/aard1.new.asm new file mode 100644 index 0000000..54ea7db --- /dev/null +++ b/aard1.new.asm @@ -0,0 +1,2040 @@ + ; + ; Aardvark + ; + ; by Oscar Toledo G. (nanochess) + ; + ; Creation date: Sep/02/2016. + ; Revision date: Dec/02/2016. Added holes and playfield mouth/eggs. + ; Revision date: Dec/03/2016. Added enemy bitmaps and color. + ; Revision date: Dec/04/2016. Tongue can be started/reverted with joystick. + ; Added eggs in board. + ; Revision date: Dec/06/2016. Tongue rules more close to arcade. Queen ants + ; are now fixed and flashing. Counts eaten eggs + ; and score. Displays score. + ; Revision date: Dec/07/2016. Enemies are filled randomly, also two speeds. + ; Aardvark centered. Dots are thicker now (uses + ; 2 rows). Aardvark walks slower. + ; Revision date: Dec/11/2016. Now is main bank of 8K ROM. Worm appears at + ; tongue tip level. Player can eat ants and + ; worms. + ; Revision date: Dec/12/2016. Enemy collisions now are checked here to avoid + ; too many cycles used in display. + ; Revision date: Jan/18/2016. Added Ranz des Vaches and Mountain King music. + ; Revision date: Jan/19/2016. Corrected lack of feet in aardvark. Added + ; tongue touched music. Added sound effects. + ; Aardvark exits level when all eggs eaten. + ; Remade code for collision of tongue. Corrected + ; bug where eating right queen would delete left + ; queen. + ; Revision date: May/27/2017. Moved all display code to bank 0, this makes it + ; to work with Atari Flashback Portable. + ; Revision date: Oct/02/2017. Sun moves to left. Counts level. + ; Revision date: Oct/08/2017. Added tongue retrain sound effect. Changes hole + ; position randomly. + ; Revision date: Oct/09/2017. Lives counting. Avoids worm appearing over ant. + ; Going down has priority over going left/right + ; but tries also left/right. New enemies: red + ; ant and caterpillar. Only one worm can appear + ; at any moment. Added more difficulty per level. + ; Calculates bonus. New enemy: spider. + ; Revision date: Oct/10/2017. Solved bug where worm would overwrite spider. + ; Solved bug where tongue removed eggs without + ; adjusting egg count. Solved bug where 150 points + ; sprites wouldn't disappear. Added click sound + ; effect for sunset. Added title screen. + ; Revision date: Nov/01/2017. Changed holes1-6 to bitmap interpretation. + ; Revision date: Nov/02/2017. Moved eggs and tongue to extra RAM (Sara chip). + ; Revision date: Nov/03/2017. Renamed level as antHill. Now tongue and eggs + ; bitmaps are intermixed (new display kernel). + ; Sprites now appear at right places. Now hole + ; map is aligned with kernelLst. Updated egg + ; count. Configurable X-limit. + ; Revision date: Nov/04/2017. Relocated direction bit. Collisions working + ; again. + ; Revision date: Nov/05/2017. Corrected worm catch. Score resets REFP0/1. + ; Collision working again. Supports player + ; reflection in display kernel. + ; + + ; Next available label: aa128 + ; Free label: aa84, aa85 + + ; TODO: + ; * Bug: live counting isn't working right. + ; * Bug: egg counting isn't working right. + ; * Tune collisions. + ; * Check if spider is working. + ; * Bug: slight bam tone after winning music. + ; * Bug: spider is slow to appear or doesn't appear. + ; * Handle holes like a bitset instead of coordinate. + ; * Allow backtracking (using up) + ; * Test in MAME for movement details + ; * Clouds (using PF) + ; * Maybe new aardvark sprite, maybe multicolor, maybe 48px: + ; * Aardvark moving ears. + ; * Aardvark sprite sitting when tongue is touched. + ; * Aardvark walking. + ; * Options in title screen. + ; * Starting level. + ; * Message "Press start" in title screen. + ; * Intermediate screen (losing live and completing level): + ; ants + ; x worms + ; * 10 = bonus + ; * Game over (shown below intermediate screen) + ; * Give an extra live each 20000 points. + + ; Differences versus arcade: + ; * Arcade has 8 tunnels, we have 7. + ; * Red ant appears at tunnel 4, in arcade is 5. + ; * Centipede appears at tunnel 5, in arcade is 6. + ; * Worm can appear at tunnel 7 in arcade (we have no space in screen) + + ; Things in unreleased ROM: + ; * Sun timer using a digit counter. + ; * White line after first bottom section + ; * Level and time in second bottom section (separated) + + ; Game in brief: + ; * Move tongue in joystick direction. + ; * Press button to retrain tongue. + ; * Bugs appear randomly on both sides. + ; * Bug touching tongue -> lost life. + ; * Tongue touching bug from behind -> score. + ; * Spider descends from top to bottom, if touch tip -> lost life. + ; * If tongue eats queen -> all enemies in board disappear. + ; * Eating all dots -> level change. + ; * Each level has different configuration of holes in floors. + ; * Ant: 100 points, appears starting in level 1, tunnels 1-4 + ; * Red ant: 150 points, appears starting in level 2, tunnel 5 + ; * Centipede: 150 points, appears starting in level 3, tunnel 6 + ; * Worm: 200 points, appears always at level of tongue. + ; * Only enemy that can appear at tunnel 7. + ; * Tongue cannot move in tunnel 8, nor there are points, only can eat queen. + ; * On restarting level the holes configuration changes. + ; * On restarting level preserves darkness even if the initial animation is + ; done again. + ; * Sun starts more at left per level. Since level 22 always starts barely + ; some pixels from left. + ; * Extra lives each 20000 points + + processor 6502 + + include aardm.asm + + ; + ; Set object in X + ; A = X position + ; First argument = Object to position (0=P0, 1=P1, 2=M0, 3=M1, 4=BALL) + ; + MAC set_x_position + sta WSYNC ; 0- Start line synchro + sec ; 2- Set carry flag (avoids it in loop) +.AE2: sbc #15 ; 4- Uses required time dividing A by 15 + bcs .AE2 ; 6/7 - 11/16/21/26/31/36/41/46/51/56/61/66 + tay ; 8 + lda fine_adjustment-$f1,y; 13 - Eats 5 cycles crossing page + sta HMP0+{1} + nop + sta RESP0+{1} ; 21/26/31/36/41/46/51/56/61/66/71 - "big" positioning + ENDM + + org $f000 ; ROM start address (4K) + + REPEAT 256 + .byte $4f + REPEND + +START: + sta bank1 ; Ghost + sei ; Disable interruptions + cld ; Disable decimal mode + jmp START2 + +ba0: sta bank0 + jmp 0 ; Ghost + + sta bank1 ; Ghost + jmp ba1 + +ba2: sta bank0 + jmp 0 ; Ghost + + sta bank1 + jmp ba3 + +START2: + ldy rand + ; Clean up the memory + ldx #$ff ; Load X with $FF... + txs ; ...copy to stack pointer + lda #0 ; Load zero in accumulator +AE1: sta 0,X ; Save in address 0 plus X + dex ; Decrement X + bne AE1 ; Repeat until X is zero. + sta SWACNT ; Allow to read joysticks + sta SWBCNT ; Allow to read buttons + tsx ; ldx #$ff + stx prev_button + sty rand + + lda rand + sta level_seed + +title_screen: + lda #20 + sta temp1 + jmp ba2 + +ba3: + lda #0 + sta antHill + lda #4 + sta lives + + lda #0 + sta score + sta score+1 + sta score+2 + + ldx #tongue_size*2-12 +aa124: lda #0 + sta tongue1+W,x + sta tongue1+W+1,x + sta tongue1+W+2,x + sta tongue1+W+3,x + sta tongue1+W+4,x + sta tongue1+W+5,x + txa + sec + sbc #12 + tax + bpl aa124 + + ; + ; Goes to next level + ; +next_level: + inc antHill + inc level_seed + + ; + ; Setup starting sun position + ; + lda antHill + asl + bmi aa82 + asl + bpl aa83 +aa82: lda #$80 +aa83: eor #$ff + adc #$98 + sta sun_pos + + lda #$00 + sta COLUBK ; Background color + + ; VERTICAL_SYNC + lda #2 + sta VSYNC ; Start vertical synchro + sta WSYNC ; Wait for 3 lines + sta WSYNC + sta WSYNC + ; + lda #43 + sta TIM64T + lda #0 + sta VSYNC ; Stop vertical synchro + + ldx #tongue_size*2-12 +aa29: lda #0 + sta tongue1+W,x + sta tongue1+W+1,x + sta tongue1+W+2,x + sta tongue1+W+3,x + sta tongue1+W+4,x + sta tongue1+W+5,x + cpx #0 + beq .+4 + lda #$aa + sta eggs1+W,x + sta eggs1+W+2,x + sta eggs1+W+3,x + sta eggs1+W+5,x + lsr + sta eggs1+W+1,x + sta eggs1+W+4,x + txa + sec + sbc #12 + tax + bpl aa29 + + lda #7*20 + sta eggs + + ; + ; Setup queen ants + ; + lda #sprite_queen_ant+ENEMY_DIR_MASK + sta enemy0_t + sta enemy8_t + lda #$2e + sta enemy0_x + lda #$66 + sta enemy8_x + + jmp aa73 + +restart_level: + inc level_seed + lda #$00 + sta effect0 + sta effect1 + sta ants_eaten + sta worms_eaten + sta COLUBK ; Background color + + ; VERTICAL_SYNC + lda #2 + sta VSYNC ; Start vertical synchro + sta WSYNC ; Wait for 3 lines + sta WSYNC + sta WSYNC + ; + lda #43 + sta TIM64T + lda #0 + sta VSYNC ; Stop vertical synchro + +aa73: + lda #1 ; Ranz des Vaches (Rossini) + sta tracker + lda #1 ; Start immediately + sta tracker_c + + lda #6 + sta aa_x_pos + lda #1 + sta timer + lda #0 + sta filling + sta flags + ; + ; Delete tongue and delete also any eggs under + ; + ldx #tongue_size*2-12 +aa69: + ldy #5 +aa80: lda tongue1+R,x + eor #$ff + and eggs1+R,x + sta eggs1+W,x + lda #0 + sta tongue1+W,x + inx + dey + bpl aa80 + txa + sec + sbc #18 + tax + bpl aa69 + + lda #0 + sta enemy1_t + sta enemy2_t + sta enemy3_t + sta enemy4_t + sta enemy5_t + sta enemy6_t + sta enemy7_t + sta enemy9_t + sta enemy10_t + sta enemy11_t + sta enemy12_t + sta enemy13_t + sta enemy14_t + sta enemy15_t + sta holeCols + sta holeCols+1 + sta holeCols+2 + sta holeCols+3 + sta holeCols+4 + sta holeCols+5 + sta holeCols+6 + sta holeCols+7 + lda #$ff + sta tip_y + jmp aa75 + +main_loop: + lda #$00 + sta COLUBK ; Background color + + ; VERTICAL_SYNC + lda #2 + sta VSYNC ; Start vertical synchro + sta WSYNC ; Wait for 3 lines + sta WSYNC + sta WSYNC + ; + lda #43 + sta TIM64T + lda #0 + sta VSYNC ; Stop vertical synchro + +aa75: + ; Nanochess' mini sound effects player + ldx tracker + bne ef4 + lda effect0 + beq ef0 + tax + lda sound_effect,x + bne ef1 + sta effect0 + beq ef0 + +ef1: sta AUDF0 + lda sound_effect+1,x + sta AUDC0 + lsr + lsr + lsr + lsr + inx + inx + stx effect0 + +ef0: sta AUDV0 + + lda effect1 + beq ef2 + tax + lda sound_effect,x + bne ef3 + sta effect1 + beq ef2 + +ef3: sta AUDF1 + lda sound_effect+1,x + sta AUDC1 + lsr + lsr + lsr + lsr + inx + inx + stx effect1 + +ef2: sta AUDV1 + bpl tr0 + + ; Nanochess' mini tracker +ef4: + ldx tracker + beq tr1 + dec tracker_c + bne tr3 + lda music-1,x + bne tr2 + sta tracker + beq tr1 + +tr2: and #$1f + asl + tay + lda music_notes-2,y + sta AUDC0 + lda music_notes-1,y + sta AUDF0 + lda music-1,x + lsr + lsr + and #$38 + sta tracker_c + lda music,x + asl + tay + lda music_notes-2,y + sta AUDC1 + lda music_notes-1,y + sta AUDF1 + inx + inx + stx tracker + lda #$3f + sta tracker_v +tr3: dec tracker_v + lda tracker_v + lsr + lsr + cpx #43 + bcs tr1 + lda tracker_v + and #$03 + bne tr4 + lda #$02 +tr4: ora #$0c +tr1: sta AUDV0 + sta AUDV1 +tr0: + + lda aa_x_pos + cmp #$0f ; Corrects left side X-pos, for some reason it breaks. + bcs *+4 + sbc #2 + set_x_position 0 ; Player 0 + ; ldx #1 ; Player 1 + lda sun_pos + set_x_position 1 ; Player 1 + lda #84 + set_x_position 2 ; Missile 0 + lda #$20 + sta NUSIZ0 + sta NUSIZ1 + + jsr build_hole_map + + lda #$00 + sta GRP0 + sta GRP1 + sta COLUPF + lda #$20 + sta CTRLPF + + jmp ba0 + +ba1: + + ; + ; Score zone + ; + sta WSYNC ; 0 + ldx #$00 ; 3 + stx COLUBK ; 5 Background color + stx GRP0 ; 8 + stx GRP1 ; 11 + stx REFP0 ; 14 + stx REFP1 ; 17 + sta en5 ; 20 + lda score ; 23 + and #$0f ; 26 + asl ; 28 + asl ; 30 + asl ; 32 + sta en4 ; 34 + lda score ; 37 + lsr ; 40 + and #$78 ; 42 + sta en3 ; 44 + lda #$21 ; 47 + sta CTRLPF ; 49 + lda #lives_color ; 52 + sta COLUPF ; 54 + ldx lives ; 57 + cpx #7 ; 60 + bcc aa88 ; 62 + ldx #7 ; 64 +aa88: + lda lives_pf,x ; 66 + sta WSYNC ; 71 + sta PF0 + lda lives_pf+8,x + sta PF1 + lda lives_pf+16,x + sta PF2 + lda score+1 ; 35 + and #$0f ; 38 + asl ; 40 + asl ; 42 + asl ; 44 + sta en2 ; 46 + lda score+1 ; 49 + lsr ; 52 + and #$78 ; 54 + sta en1 ; 56 + lda score+2 ; 59 + and #$0f ; 62 + asl ; 64 + asl ; 66 + asl ; 68 + sta en0 ; 70 + ldx #0 + + lda #score_color ; 73 + jmp $f400 ; 75 + org $F400 +mp0: + sta WSYNC + stx GRP0 + stx GRP1 + ldy #numbers>>8 ; 8 + sty en0+1 ; 11 + sty en1+1 ; 14 + sty en2+1 ; 17 + sty en3+1 ; 20 + sty en4+1 ; 23 + sty en5+1 ; 26 + + sta COLUP0 ; 29 + sta COLUP1 ; 32 + lda #$03 ; 35 3 copies together + ldx #$f0 ; 37 + stx RESP0 ; 39 + stx RESP1 ; 42 + stx HMP0 ; 45 + sta NUSIZ0 ; 48 + sta NUSIZ1 ; 51 + lsr ; 53 + sta VDELP0 ; 56 + sta VDELP1 ; 59 + lsr + sta HMP1 + sta WSYNC ; 62 + sta HMOVE ; 3 + lda #4 + sta temp2 +mp1: ldy temp2 ; 2 + lda (en0),y ; 7 + sta GRP0 ; 10 + sta WSYNC ; 13 + 61 = 76 + lda (en1),y ; 5 + sta GRP1 ; 8 + lda (en2),y ; 13 + sta GRP0 ; 16 + lda (en3),y ; 21 + sta temp1 ; 24 Write (this depends on being at "root" stack pos) + lda (en4),y ; 29 (and of course not being called) + tax ; 31 + lda (en5),y ; 36 + tay ; 38 + lda temp1 ; 41 Read + sta GRP1 ; 44 + stx GRP0 ; 47 + sty GRP1 ; 50 + sta GRP0 ; 53 + dec temp2 ; 58 + bpl mp1 ; 60/61 +mp3: + ; Looks for code spanning page + if (mp1&$ff00)!=(mp3&$ff00) + lda megabug3 ; :P + endif + echo "mp0 ",mp0," mp1 ",mp1," mp3 ",mp3 + + ; + ; End of graphics (204 lines) + ; + ldx #$00 + lda #2 + sta WSYNC + sta VBLANK + stx VDELP0 + stx VDELP1 + stx GRP0 + stx GRP1 + stx PF0 + stx PF1 + stx PF2 + + ; + ; Start overscan timer + ; + lda #43 ; 37 lines * 76 = 2812 cycles / 64 = 43.9375 + sta TIM64T + + lda flags + and #$03 + cmp #$02 ; Tongue touched? + bne aa67 + jmp wait_overscan + +aa67: lda eggs + bne aa70 + ldx aa_x_pos + cpx #52 + bne aa71 + inc aa_x_pos + lda #43 ; Mountain King (Grieg) + sta tracker + lda #1 + sta tracker_c + lda #0 + sta filling + sta flags + ldx #tongue_size*2-1 + lda #0 +aa72: sta tongue1+W,x + dex + bpl aa72 + + sta enemy0_t + sta enemy1_t + sta enemy2_t + sta enemy3_t + sta enemy4_t + sta enemy5_t + sta enemy6_t + sta enemy7_t + sta enemy8_t + sta enemy9_t + sta enemy10_t + sta enemy11_t + sta enemy12_t + sta enemy13_t + sta enemy14_t + sta enemy15_t + sta holeCols + sta holeCols+1 + sta holeCols+2 + sta holeCols+3 + sta holeCols+4 + sta holeCols+5 + sta holeCols+6 + sta holeCols+7 + lda #$ff + sta tip_y +aa71: jmp aa34 + +aa70: lda flags + and #$fc + sta flags + + ; + ; Check for collisions of enemies versus tongue (playfield pixels) + ; + ldx #15 +aa53: lda enemy0_t,x + tay + cmp #non_interactive_sprites + bcc aa86 + cpx #8 + bcs aa45 + lda cxLst,x + and #$20 + beq aa86 ; No, jump + bne aa127 + +aa45: lda cxLst-8,x + asl + bpl aa86 + +aa127: tya + and #$f0 + cmp #sprite_spider + beq aa106 + cmp #sprite_worm ; Is it a worm? + beq aa55 + bne aa87 + +aa86: + dex + bpl aa53 + jmp aa78 + + ; + ; Spider + ; * Kills if touches tongue tip + ; +aa106: + txa + and #$07 + cmp tip_y ; Is it at same level than tongue? + bne aa86 ; No, jumps + lda enemy0_x,x + tay + sbc #3 + lsr + lsr + cmp tip_x + beq aa56sc + tya + clc + adc #10 + lsr + lsr + cmp tip_x + beq aa56sc + bne aa86 + +aa87: + ; + ; Ant: + ; * Eaten if tongue tip. + ; * Kills if it touch any other part of tongue. + ; + txa + and #$07 + cmp tip_y ; Is it at same level than tongue? + bne aa56sc ; No, kills + lda enemy0_x,x + sbc #3 + tay + lsr + lsr + cmp tip_x + beq aa57 + bcs aa56 + tya + clc + adc #10 + lsr + lsr + cmp tip_x + beq aa57 + bcc aa56 + +aa57: lda enemy0_t,x + cmp #sprite_queen_ant+$20 + bcs aa125 + cmp #sprite_queen_ant + bcs aa59 +aa125: cmp #pricey_sprites ; Red ant and caterpillar + bcs aa97 + sed + lda ants_eaten + adc #1 + sta ants_eaten + cld + lda #sprite_explosion; Goodbye ant + .byte $2c ; BIT opcode to jump +aa97: lda #sprite_150 + ldy #11 + bne aa79 + +aa56sc: jmp aa56 + +aa59: jsr clear_enemies + ldy #33 +aa79: sty effect1 + bne aa60 + + ; + ; Worm: + ; * Eaten if tongue tip from behind. + ; * Kills only if tongue tip in front. + ; +aa55: txa + and #$07 + cmp tip_y + bne aa54 + lda enemy0_x,x + tay + sbc #3 + lsr + lsr + cmp tip_x + beq aa58 + bcs aa54 + tya + clc + adc #10 + lsr + lsr + cmp tip_x + beq aa58 + bcc aa54 +aa58: lda tip_dir + beq aa56 + lsr ; $ff left $00 right + eor enemy0_t,x + and #ENEMY_SPEED_MASK + bne aa56 + lda flags + and #~FLAGS_WORM + sta flags + inc worms_eaten + lda #20 + sta effect1 + lda #sprite_200 ; 200 points +aa60: sta enemy0_t,x + bne aa54 + + ; Kill +aa56: lda flags + and #$fc + ora #$01 + sta flags + +aa54: + dex + bmi aa78 + jmp aa53 +aa78: + + lda flags + and #$03 + beq aa52 + jmp wait_overscan + + ; + ; Invoke an enemy + ; +aa52: + dec timer + beq aa95 + jmp aa14 +aa95: + jsr random_proc ; Get a random number (just because :P) + tay ; Save it + and #$0e ; Restart timer + ora #$01 + sta timer + lda antHill ; Starts at 1 + clc + adc #$03 ; Level 1 - fills 4 tunnels, 2 - 5 t., 4 and so- 6 t. + cmp #$06 ; No more than 6 tunnels + bcc aa92 + lda #$06 +aa92: asl + sta temp1 + lda filling + cmp temp1 + bcc aa102 +aa103: jmp aa8 +aa102: + and #$0e + lsr + eor #$07 + tax + cmp #$07 + bne aa111 + lda enemy8_t,x + bne aa111 + lda #FLAGS_SPIDER + bit flags + bne aa111 + lda sun_pos + cmp #8 ; Now it's night? + beq aa110 ; No, jump +aa111: lda enemy0_t,x ; There is space for a common enemy? + beq aa12 ; Yep, jump. +aa110: lda enemy8_t,x ; There is space for a worm/spider? + bne aa103 ; No, jump + cpx #0 ; Top tunnel? + bne aa101 ; No, jump + lda sun_pos + cmp #8 ; Now it's night? + bne aa101 ; No, jump + lda #FLAGS_SPIDER + bit flags ; We have already the spider? + bne aa101 ; Yes, jump + ora flags + sta flags + lda #ENEMY_MAX_X + sta enemy8_x,x + tya + and #ENEMY_SPEED_MASK + ora #sprite_spider + sta enemy8_t,x + bne aa8 + +aa101: + txa + and #$07 + cmp tip_y + bne aa103 + lda #FLAGS_WORM + bit flags ; Already a worm in screen? + bne aa8 ; Yes, jump + ora flags + sta flags + tya + and #$40 + beq aa37 + lda enemy0_x,x + cmp #40 + bcc aa90 +aa91: lda #ENEMY_MIN_X + sta enemy8_x,x + tya + and #ENEMY_SPEED_MASK + ora #sprite_worm+ENEMY_DIR_MASK + sta enemy8_t,x + bne aa8 + +aa37: lda enemy0_x,x + cmp #129 + bcs aa91 +aa90: lda #ENEMY_MAX_X + sta enemy8_x,x + tya + and #ENEMY_SPEED_MASK + ora #sprite_worm + sta enemy8_t,x + bne aa8 + +aa12: tya + and #$40 + beq aa15 + lda #ENEMY_MIN_X + sta enemy0_x,x + tya + and #ENEMY_SPEED_MASK + ora enemies_going_right,x + sta enemy0_t,x + bne aa8 + +aa15: lda #ENEMY_MAX_X + sta enemy0_x,x + tya + and #ENEMY_SPEED_MASK + ora enemies_going_left,x + sta enemy0_t,x + ; bne aa8 + +aa8: ldx antHill + cpx #32 + bcc aa93 + ldx #31 +aa93: lda filling + clc + adc #2 + cmp refilling,x + bne aa94 + lda #0 +aa94: sta filling +aa14: + + ; + ; Sun animation + ; + lda frame + and #$1f ; Each 32 frames + bne aa81 + lda sun_pos + cmp #8 + beq aa81 + dec sun_pos ; Move sun left by one pixel + cmp #9 + bne aa81 + lda #129 ; Click effect + sta effect0 +aa81: + + ; + ; Enemy animation and movement + ; + ldy #0 + lda frame + and #$07 ; Enemies change animation frame each 8 frames + bne aa11 + ldy #8 +aa11: and #$03 ; Enemies move each 4 frame + beq aa117 + jmp aa43 +aa117: + ldx #$0f +aa10: + lda enemy0_t,x ; Active enemy? + bne aa118 ; Yes, jump +aa120: dex + bpl aa10 + jmp aa43 + + ; + ; Check first for brief sprites (explosion, 150 and 200 points) + ; +aa118: cmp #non_interactive_sprites + bcs aa39 +aa49: inc enemy0_t,x + cmp #sprite_150+$03 + beq aa96 + cmp #sprite_200+$03 + beq aa46 + cmp #sprite_200_spider+$03 + beq aa46 + cmp #sprite_explosion+$03 + bne aa38sd + lda #$10 ; 100 points + .byte $2c ; BIT opcode to jump +aa46: lda #$20 ; 200 points + .byte $2c ; BIT opcode to jump +aa96: lda #$15 ; 150 points + jsr score_points + lda #$00 + sta enemy0_t,x +aa38sd: jmp aa38 + ; + ; All other sprites + ; +aa39: and #$f0 + cmp #sprite_spider + bne aa108 + ; + ; Spider handling + ; + lda tip_y ; Tongue tip active? + bmi aa120 ; No, jump (spider stays quiet) + txa ; Get vertical position of spider + and #$07 + cmp tip_y ; Comparison with tongue tip vertical position. + beq aa109 ; Same vertical position? yes, jump + bcs aa120 ; Jump if spider deeper than tongue tip. It shouldn't happen + stx temp1 + tax + lda holeCols,x ; Check if tongue goes thru a hole !!! + lsr + bcs aa112 + lsr + bcs aa113 + lsr + bcs aa114 + lda #0 + .byte $2c ; BIT opcode to jump +aa114: lda #8 + .byte $2c ; BIT opcode to jump +aa113: lda #16 + .byte $2c ; BIT opcode to jump +aa112: lda #24 + clc + adc kernelLst,x + tax + lda hole_pos,x ; Now get the X-coordinate for hole + ldx temp1 + sec ; There's an X-coordinate, center spider over it + sbc #2 + jmp aa116 + + ; + ; Spider at same level than tongue tip + ; +aa109: lda tip_x + asl + asl + beq aa116 + sbc #1 +aa116: sbc enemy0_x,x ; Take a decision of direction to move + beq aa119 ; At target position? yes, jump + bcc aa44 + bcs aa40 + + ; + ; Try to lower spider by one level + ; +aa119: cpx #1 ; Is spider at bottom-most position? + beq aa41 ; Yes, jump, stay quiet + cpx #9 + beq aa41 + lda enemy0_t-1,x ; Is it busy the next enemy slot? + bne aa41 ; Yes, jump, stay quiet + lda enemy0_x,x ; Copy X position + sta enemy0_x-1,x + lda enemy0_t,x ; Copy type + sta enemy0_t-1,x + lda #0 ; Erase spider from old slot + sta enemy0_t,x + beq aa41 + + ; + ; Ant, red ant, worm or centipede + ; +aa108: + cmp #sprite_queen_ant + beq aa38 + cmp #sprite_queen_ant+$10 + beq aa38 + lda enemy0_t,x + and #ENEMY_SPEED_MASK; Fast? + beq aa44 + lda frame + and #$04 +aa38sc: bne aa38 +aa44: + lda enemy0_t,x + and #ENEMY_DIR_MASK ; Goes to left? + bne aa40 ; No, jump + dec enemy0_x,x + lda enemy0_x,x + cmp #ENEMY_MIN_X ; Reached left limit? + bne aa41 ; No, jump +aa42: + lda enemy0_t,x + and #$f0 + cmp #sprite_worm + bne aa98 + lda flags + and #~FLAGS_WORM + sta flags +aa98: cmp #sprite_spider ; It could happen *sigh* + bne aa107 + lda flags + and #~FLAGS_SPIDER + sta flags +aa107: lda #0 + sta enemy0_t,x + beq aa38 + +aa40: + inc enemy0_x,x + lda enemy0_x,x + cmp #ENEMY_MAX_X ; Reached right limit? + beq aa42 ; Yes, jump +aa41: + tya + eor enemy0_t,x ; Changed animation frame if required + sta enemy0_t,x +aa38: dex + bmi aa43 + jmp aa10 +aa43: + + ; + ; Queen ant flashing + ; + lda frame + and #$01 + bne aa34 + lda enemy0_t + beq aa32 + cmp #non_interactive_sprites + bcs aa51 + adc #1 + cmp #sprite_1000+8 + bne aa32 + jsr score_points_2 ; 1000 points + lda #0 + beq aa32 + +aa51: adc #$07 + cmp #sprite_queen_ant+$20 + bcc aa32 + sbc #$20 +aa32: sta enemy0_t + + lda enemy8_t + beq aa33 + cmp #non_interactive_sprites + bcs aa50 + adc #1 + cmp #sprite_1000+8 + bne aa33 + jsr score_points_2 ; 1000 points + lda #0 + beq aa33 + +aa50: adc #$07 + cmp #sprite_queen_ant+$20 + bcc aa33 + sbc #$20 +aa33: sta enemy8_t +aa34: + ; + ; Count frame, step on random generator + ; + inc frame + jsr random_proc + ; + ; Aardvark enters game + ; + ldx aa_x_pos + cpx #52 + beq aa7 + lda frame + and #$07 + bne aa31 + inc aa_x_pos + cpx #51 + bne aa31 + ; Start tongue + lda #$02 + sta holeCols+7 + ldx #19 + stx tip_x + lda #7 + sta tip_y + lda #0 + sta tip_dir + jsr point_egg + ldx tip_x + lda tip_y + jsr draw_block +aa31: + lda frame + and #$07 + bne aa4 + lda aa_offset + eor #$28 + sta aa_offset +aa4: + jmp aa20 + +aa7: + lda #0 + + jsr fire_button ; Fire button pressed? + bpl aa22 ; No, jump + + ldx tip_x ; Get tongue coordinates + lda tip_y + cpx #19 + bne aa19 + cmp #7 + beq aa123 ; Is it at base? yes, jump without doing anything +aa19: + jsr clear_block + lda effect0 + cmp #128 + bcs aa122 + cmp #66 + bcs aa121 +aa122: + lda #66 + sta effect0 +aa121: ldx tip_x + beq aa23 + dex + lda tip_y + jsr check_block + bne aa24 + inx + +aa23: cpx #39 + beq aa25 + inx + lda tip_y + jsr check_block + bne aa24 + +aa25: ldx tip_y + lda #$00 + sta holeCols,x + inc tip_y + jmp aa20 + +aa24: stx tip_x + jmp aa20 + +aa123: jmp aa28 + +aa22: + jsr build_hole_map + lda SWCHA + ; Note #$10 isn't used (going up) + and #$20 ; Going down? + beq aa17 ; Yes, jump +aa18: lda SWCHA + bmi aa16 ; Going right? No, jump + lda tip_y + bmi aa28 + beq aa28 ; Last tunnel? Yes, cannot move + lda frame + lsr + bcc aa28 + ldx tip_x + cpx #39 + beq aa28 + inx +aa26: lda tip_y + jsr check_block + bne aa30 + txa + sec + sbc tip_x + sta tip_dir + stx tip_x + lda tip_y + jsr point_egg + ldx tip_x + lda tip_y + jsr draw_block + jmp aa20 + +aa30: txa + pha + ldx tip_x + lda tip_y + jsr clear_block + pla + sta tip_x +aa28: jmp aa20 + +aa16: rol ; Going left? + bmi aa20 + lda tip_y + bmi aa20 + beq aa20 ; Last tunnel? Yes, cannot move + lda frame + lsr + bcc aa20 + ldx tip_x + beq aa20 + dex + bpl aa26 + + ; + ; Going down + ; +aa17: ldx tip_y ; Get row of tongue tip + bmi aa18 ; Invalid? Yes, jump to check for right/left + beq aa18 ; Vertical limit? Yes, jump to check for right/left + lda kernelLst-1,x + tax + lda tip_x ; Tongue tip at 0? + beq aa18 ; Jump to check for right/left + cmp hole_pos,x + beq aa126 + cmp hole_pos+8,x + beq aa27 + cmp hole_pos+16,x + beq aa115 + cmp hole_pos+24,x + bne aa18 ; No hole, so jump to check for right/left + ldy #$01 + .byte $2c ; BIT opcode to jump +aa115: ldy #$02 + .byte $2c ; BIT opcode to jump +aa126: ldy #$08 + .byte $2c ; BIT opcode to jump +aa27: ldy #$04 + tya + ldx tip_y + dex + ora holeCols,x + sta holeCols,x + stx tip_y + txa + ldx tip_x + jsr point_egg + ldx tip_x + lda tip_y + jsr draw_block + lda #0 + sta tip_dir + +aa20: + +wait_overscan: + lda INTIM + bne wait_overscan + sta WSYNC + sta WSYNC + + lda aa_x_pos + cpx #135 + bne aa74 + jsr bonus_screen + jmp next_level +aa74: + + lda flags + and #$03 + cmp #$02 ; Has finished tongue color changing animation? + beq aa68 ; Yes, jump + jmp main_loop ; Continue with main loop + +aa68: dec lives + jsr bonus_screen + lda lives + bmi aa89 + jmp restart_level ; Restart level + +aa89: jmp title_screen + + ; + ; Bonus screen + ; +bonus_screen: + ldx worms_eaten + beq aa99 +aa100: + lda ants_eaten + jsr score_points + dex + bne aa100 +aa99: + rts + + ; + ; Run random number generator + ; +random_proc: + ; + ; Random number generator + ; + lda rand + sec + ror + eor frame + ror + eor rand + ror + eor #9 + sta rand + rts + + ; + ; Check for fire button + ; +fire_button_single: + lda INPT4 + eor #$ff + tax + eor prev_button + stx prev_button + bpl fire_button1 + txa +fire_button1: + rts + +fire_button: + lda INPT4 + eor #$ff + sta prev_button + rts + + ; + ; Calculate memory zone for tongue block + ; a = zone (0-7) + ; +calc_zone: + asl ; x2 + asl ; x4 + sta en0 + asl ; x8 + adc en0 ; x12 + adc #tongue1 + sta en0 + adc #W + sta en0+1 + sta en1+1 + rts + + ; + ; Check for tongue block + ; + ; a = zone (0-5) + ; x = x pixel (0-39) + ; +check_block: + jsr calc_zone + lda pixel_to_byte,x + tay + lda (en1),y + and pixel_to_bit,x + rts + + ; + ; Clear enemies (used when eating queen ant) + ; +clear_enemies: + txa + pha + ldx #9 +aa61: lda enemy0_t,x + cmp #non_interactive_sprites + bcc aa62 + and #$f0 + cmp #sprite_worm + beq aa63 + cmp #sprite_spider + beq aa104 + cmp #pricey_sprites + bcs aa64 + lda #sprite_explosion + .byte $2c ; BIT opcode to jump +aa63: lda #sprite_200 + .byte $2c ; BIT opcode to jump +aa64: lda #sprite_150 + .byte $2c ; BIT opcode to jump +aa104: lda #sprite_200_spider + sta enemy0_t,x + cmp #sprite_200_spider + bne aa105 + lda flags + and #~FLAGS_SPIDER + sta flags +aa105: + cmp #sprite_200 ; Only a worm gives a 200 points bonus + bne aa62 + lda flags + and #~FLAGS_WORM + sta flags +aa62: dex + bpl aa61 + pla + tax + lda #sprite_1000 + rts + + ; + ; Give points per egg eaten + ; + ; a = zone (0-7) + ; x = x pixel (0-39) + ; +point_egg: + cmp #0 + beq aa35 + jsr calc_zone + lda en1 + clc + adc #tongue_to_eggs + sta en1 + lda pixel_to_byte,x + tay + lda (en1),y + and pixel_to_bit,x + beq aa35 + lda eggs + ror + lda #1 + bcc aa77 + lda #6 +aa77: sta effect0 + dec eggs + lda #1 + + ; Score 1 point for egg eaten +score_points: + clc + sed + adc score + sta score +aa48: lda score+1 + adc #0 + sta score+1 + lda score+2 + adc #0 + sta score+2 + cld +aa35: + rts + +score_points_2: + sec + sed + bcs aa48 + + ; + ; Draw a tongue block + ; + ; a = zone (0-7) + ; x = x pixel (0-39) + ; +draw_block: + jsr calc_zone + lda pixel_to_byte,x + tay + lda (en1),y + ora pixel_to_bit,x + sta (en0),y + lda en0 + clc + adc #tongue_to_eggs + sta en0 + lda en1 + adc #tongue_to_eggs + sta en1 + lda (en1),y + ora pixel_to_bit,x + sta (en0),y + rts + + ; + ; Clear a tongue block + ; + ; a = zone (0-7) + ; x = x pixel (0-39) + ; +clear_block: + jsr calc_zone + lda pixel_to_byte,x + tay + lda (en1),y + and pixel_to_bit2,x + sta (en0),y + lda en0 + clc + adc #tongue_to_eggs + sta en0 + lda en1 + adc #tongue_to_eggs + sta en1 + lda (en1),y + and pixel_to_bit2,x + sta (en0),y + rts + + ; + ; Build random hole map for the current level seed + ; See also random.c + ; +build_hole_map: SUBROUTINE +.lastPat = tmpVars + lda #255 + sta .lastPat + ldy #NUM_FLOORS-1 + ldx level_seed +.0: + lda random_level,x + tax + and #$07 + cmp .lastPat + bne .1 + txa + lsr + lsr + tax + and #$07 +.1: + sta kernelLst,y + sta .lastPat + dey + bne .0 + sty kernelLst ; Fixed tunnel for queen ants + rts + + ; + ; With the help of: + ; + ; http://alienbill.com/2600/basic/music/tune2600.html + ; http://piano-player.info/ + ; + + ; + ; Songs refer to these notes. + ; These notes contain frequency and "instrument" and are + ; choosen per usage in song instead of full "continuous" octaves + ; +music_notes: + .byte 12,12 ; 1 + .byte 4,28 + .byte 4,25 ; 3 + .byte 4,22 + .byte 4,18 ; 5 + .byte 4,16 + + .byte 12,20 ; 7 + .byte 12,19 + .byte 12,18 ; 9 + .byte 12,17 + .byte 12,15 ; 11 + .byte 12,14 + .byte 12,13 ; 13 + .byte 12,11 + .byte 4,31 ; 15 + + .byte 6,7 ; 16 + .byte 6,6 ; 17 + .byte 12,27 ; 18 + .byte 12,23 ; 19 + + .byte 0,0 ; 20 Unused + + .byte 6,7 ; 21 + .byte 12,30 + .byte 12,27 ; 23 + .byte 12,24 + .byte 12,20 ; 25 + .byte 12,18 + + .byte 0,0 ; 27 Unused + .byte 1,12 ; 29 + .byte 1,6 ; 31 + .byte 1,13 ; 33 + .byte 1,9 ; 35 + .byte 0,0 + + ; + ; Global label to access music + ; +music: + + ; + ; Ranz des vaches + ; +music_ranz_des_vaches: + .byte 6*32+2,22 ; 1 -> tracker + .byte 1*32+3,23 + .byte 1*32+1,21 + .byte 1*32+2,22 + .byte 1*32+4,24 + .byte 1*32+1,21 + + .byte 6*32+2,22 + .byte 1*32+3,23 + .byte 1*32+1,21 + .byte 1*32+2,22 + .byte 1*32+4,24 + .byte 1*32+1,21 + + .byte 6*32+2,22 + .byte 1*32+4,24 + .byte 1*32+6,26 + .byte 1*32+5,25 + .byte 1*32+1,21 + .byte 1*32+4,24 + + .byte 5*32+3,23 + .byte 1*32+5,25 + + .byte 0,0 + + ; + ; Mountain king + ; +music_mountain_king: + .byte 2*32+7,16 ; 43 -> tracker + .byte 2*32+9,16 + .byte 2*32+10,18 + .byte 2*32+11,18 + .byte 2*32+13,16 + .byte 2*32+10,16 + .byte 4*32+13,18 + + .byte 2*32+12,16 + .byte 2*32+9,16 + .byte 4*32+12,18 + .byte 2*32+11,16 + .byte 2*32+8,16 + .byte 4*32+11,18 + + .byte 2*32+7,16 + .byte 2*32+9,16 + .byte 2*32+10,18 + .byte 2*32+11,18 + .byte 2*32+13,16 + .byte 2*32+10,16 + .byte 2*32+13,18 + .byte 2*32+15,18 + + .byte 2*32+14,17 + .byte 2*32+13,17 + .byte 2*32+10,19 + .byte 2*32+13,19 + .byte 7*32+14,17 + + .byte 0,0 + + ; + ; Death music + ; +music_touch: + .byte 4*32+28,28 ; 97 -> tracker + .byte 4*32+29,29 + .byte 4*32+30,30 + .byte 7*32+31,31 + .byte 0,0 + + ; + ; Global label to access sound effects + ; +sound_effect: + .byte 0 + + .byte $04,$81 ; 1 Eating egg (1) + .byte $03,$71 ; 3 + .byte 0 ; 5 + + .byte $08,$81 ; 6 Eating egg (2) + .byte $07,$71 ; 8 + .byte 0 ; 10 + + .byte $07,$88 ; 11 Eating bug + .byte $06,$88 ; 13 + .byte $07,$88 ; 15 + .byte $06,$88 ; 17 + .byte 0 ; 19 + + .byte $1c,$fc ; 20 Eating worm + .byte $1c,$cc ; 22 + .byte $1c,$ac ; 24 + .byte $1c,$8c ; 26 + .byte $1c,$6c ; 28 + .byte $1c,$4c ; 30 + .byte 0 ; 32 + + .byte $1c,$fc ; 33 Eating queen + .byte $1c,$cc ; 35 + .byte $1c,$ac ; 37 + .byte $1c,$8c ; 39 + .byte $1c,$6c ; 41 + .byte $1c,$4c ; 43 + .byte $10,$ec ; 45 + .byte $10,$cc ; 47 + .byte $10,$ac ; 49 + .byte $10,$6c ; 51 + .byte $10,$4c ; 53 + .byte $10,$3c ; 55 + .byte $10,$4c ; 57 + .byte $10,$3c ; 59 + .byte $10,$4c ; 61 + .byte $10,$3c ; 63 + .byte 0 ; 65 + + .byte $1f,$c4 ; 66 Retrain tongue + .byte $1e,$b4 ; 68 + .byte $1d,$c4 ; 70 + .byte $1c,$b4 ; 72 + .byte $1b,$c4 ; 74 + .byte $1a,$b4 ; 76 + .byte $19,$c4 ; 78 + .byte $18,$b4 ; 80 + .byte $17,$c4 ; 82 + .byte $16,$b4 ; 84 + .byte $15,$c4 ; 86 + .byte $14,$b4 ; 88 + .byte $13,$c4 ; 90 + .byte $12,$b4 ; 92 + .byte $11,$c4 ; 94 + .byte $10,$b4 ; 96 + .byte $0f,$c4 ; 98 + .byte $0e,$b4 ; 100 + .byte $0d,$c4 ; 102 + .byte $0c,$b4 ; 104 + .byte $0b,$c4 ; 106 + .byte $0a,$b4 ; 108 + .byte $09,$c4 ; 110 + .byte $08,$b4 ; 112 + .byte $07,$c4 ; 114 + .byte $06,$b4 ; 116 + .byte $05,$c4 ; 118 + .byte $04,$b4 ; 120 + .byte $03,$c4 ; 122 + .byte $02,$b4 ; 124 + .byte $01,$c4 ; 126 + .byte 0 + + .byte $18,$c1 ; 129 Click effect for sunset + .byte $0c,$61 ; 131 + .byte $06,$a1 ; 133 + .byte $03,$41 ; 135 + .byte $02,$81 ; 137 + .byte $01,$21 ; 139 + .byte 0 + + echo "Before random_level at $fd00: ",* + + org $fd00 + + .include "aardlev.asm" + + org $fe00 +fine_adjustment: + .byte $70 ; -7 + .byte $60 ; -6 + .byte $50 ; -5 + .byte $40 ; -4 + .byte $30 ; -3 + .byte $20 ; -2 + .byte $10 ; -1 + .byte $00 ; 0 + .byte $f0 ; +1 + .byte $e0 ; +2 + .byte $d0 ; +3 + .byte $c0 ; +4 + .byte $b0 ; +5 + .byte $a0 ; +6 + .byte $90 ; +7 + +pixel_to_byte: + .byte 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2 + .byte 3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5 + +pixel_to_bit: + .byte $10,$20,$40,$80 + .byte $80,$40,$20,$10,$08,$04,$02,$01 + .byte $01,$02,$04,$08,$10,$20,$40,$80 + + .byte $10,$20,$40,$80 + .byte $80,$40,$20,$10,$08,$04,$02,$01 + .byte $01,$02,$04,$08,$10,$20,$40,$80 + +pixel_to_bit2: + .byte $ef,$df,$bf,$7f + .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe + .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f + + .byte $ef,$df,$bf,$7f + .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe + .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f + + ; + ; Position for holes (in "fat" pixels) + ; Note vertical sorting, one line of holes is made from one column of data. + ; A B C D E F G H + ; +hole_pos: + .byte 0, 6, 3, 0, 0, 0, 0, 0 + .byte 12,12, 9, 6, 9, 3, 0,15 + .byte 26,18,20,26,23,15,18,23 + .byte 0,32,35,32, 0,29,29,35 + + ; + ; Lives representation as playfield graphics + ; +lives_pf: + .byte $00,$40,$40,$40,$40,$40,$40,$40 + .byte $00,$00,$80,$a0,$a8,$aa,$aa,$aa + .byte $00,$00,$00,$00,$00,$00,$01,$05 + + ; + ; Refilling constant per level + ; +refilling: + .byte 128,126,124,122,120,118,116,114 + .byte 112,110,108,106,104,102,100,98 + .byte 96,94,92,90,88,86,84,82 + .byte 80,78,76,74,72,70,68,66 + + ; + ; Enemies per tunnel + ; +enemies_going_right: + .byte 0 + .byte 0 + .byte sprite_caterpillar+ENEMY_DIR_MASK + .byte sprite_red_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte 0 + .byte 0 + .byte sprite_caterpillar+ENEMY_DIR_MASK + .byte sprite_red_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + .byte sprite_ant+ENEMY_DIR_MASK + +enemies_going_left: + .byte 0 + .byte 0 + .byte sprite_caterpillar + .byte sprite_red_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + .byte 0 + .byte 0 + .byte sprite_caterpillar + .byte sprite_red_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + .byte sprite_ant + + org $ff00 +numbers: + .byte $fe,$c6,$c6,$c6,$fe,$00,$00,$00 + .byte $78,$30,$30,$70,$30,$00,$00,$00 + .byte $fe,$c0,$fe,$06,$fe,$00,$00,$00 + .byte $fe,$06,$fe,$06,$fe,$00,$00,$00 + .byte $06,$06,$fe,$c6,$c6,$00,$00,$00 + .byte $fe,$06,$fe,$c0,$fe,$00,$00,$00 + .byte $fe,$c6,$fe,$c0,$fe,$00,$00,$00 + .byte $18,$18,$0c,$06,$fe,$00,$00,$00 + .byte $fe,$c6,$fe,$c6,$fe,$00,$00,$00 + .byte $fe,$06,$fe,$c6,$fe,$00,$00,$00 + + org $fffc + .word START ; RESET + .word START ; BRK + diff --git a/pretty6502.c b/pretty6502.c index f6d564d..69c46bd 100644 --- a/pretty6502.c +++ b/pretty6502.c @@ -37,8 +37,8 @@ void request_space(FILE *output, int *current, int new, int force) */ while (1) { if (tabs == 0) { - fputc(' ', output); - (*current)++; + fprintf(output, "%*s", new - *current, ""); + *current = new; } else { fputc('\t', output); *current = (*current + tabs) / tabs * tabs; @@ -61,12 +61,8 @@ int main(int argc, char *argv[]) int align_comment; FILE *input; FILE *output; - char line[4096]; - int input_lines; int allocation; char *data; - int current_line; - int next_position; char *p; char *p1; char *p2; @@ -198,43 +194,53 @@ int main(int argc, char *argv[]) /* ** Open input file, measure it and read it into buffer */ - input = fopen(argv[c], "r"); + input = fopen(argv[c], "rb"); if (input == NULL) { fprintf(stderr, "Unable to open input file: %s\n", argv[c]); exit(1); } fprintf(stderr, "Processing %s...\n", argv[c]); - input_lines = 0; - allocation = 0; - while (fgets(line, sizeof(line) - 1, input)) { - allocation += strlen(line) + 1; - input_lines++; - } - fclose(input); - data = malloc(allocation); + fseek(input, 0, SEEK_END); + allocation = ftell(input); + data = malloc(allocation + sizeof(char)); if (data == NULL) { fprintf(stderr, "Unable to allocate memory\n"); + fclose(input); exit(1); } - input = fopen(argv[c], "r"); - if (input == NULL) { - fprintf(stderr, "Unable to open input file: %s\n", argv[c]); + fseek(input, 0, SEEK_SET); + if (fread(data, sizeof(char), allocation, input) != allocation) { + fprintf(stderr, "Something went wrong reading the input file\n"); + fclose(input); + free(data); exit(1); } - current_line = 0; - next_position = 0; - while (fgets(line, sizeof(line) - 1, input)) { - if (current_line >= input_lines || next_position + strlen(line) + 1 > allocation) { - fprintf(stderr, "Buuurp! the source file grew!\n"); - fclose(input); - exit(1); - } - strcpy(data + next_position, line); - next_position += strlen(line) + 1; - current_line++; - } fclose(input); + /* + ** Ease processing of input file + */ + request = 0; + p1 = data; + p2 = data; + while (p1 < data + allocation) { + if (*p1 == '\r') { /* Ignore \r characters */ + p1++; + continue; + } + if (*p1 == '\n') { + p1++; + *p2++ = '\0'; /* Break line */ + request = 1; + continue; + } + *p2++ = *p1++; + request = 0; + } + if (request == 0) + *p2++ = '\0'; /* Force line break */ + allocation = p2 - data; + /* ** Now generate output file */ @@ -245,7 +251,7 @@ int main(int argc, char *argv[]) exit(1); } p = data; - for (input_lines = 0; input_lines < current_line; input_lines++) { + while (p < data + allocation) { current_column = 0; p1 = p; if (*p1 && !isspace(*p1) && *p1 != ';') { /* Label */ @@ -276,7 +282,7 @@ int main(int argc, char *argv[]) request = start_operand; request_space(output, ¤t_column, request, 1); p2 = p1; - while (*p2 && *p2 != ';' && *p2 != '\r' && *p2 != '\n') { + while (*p2 && *p2 != ';') { if (*p2 == '"') { p2++; while (*p2 && *p2 != '"') @@ -311,7 +317,7 @@ int main(int argc, char *argv[]) request = start_mnemonic; request_space(output, ¤t_column, request, 0); p2 = p1; - while (*p2 && *p2 != '\r' && *p2 != '\n') + while (*p2) p2++; while (p2 > p1 && isspace(*(p2 - 1))) p2--; From c09e116829a9ca4b8ce3a578d6d63e075062a312 Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 13:28:48 -0600 Subject: [PATCH 2/2] Indents nested preprocessor. Allows label in its own line. Tries to preserve horizontal position of comments. --- LICENSE | 22 + README | 5 + aard1.asm | 2040 ------------------------------------------------- aard1.new.asm | 2040 ------------------------------------------------- pretty6502.c | 228 +++++- 5 files changed, 235 insertions(+), 4100 deletions(-) create mode 100644 LICENSE delete mode 100755 aard1.asm delete mode 100644 aard1.new.asm diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..496122f --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017 Oscar Toledo G. http://nanochess.org/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README b/README index 47430f6..86e0aa9 100644 --- a/README +++ b/README @@ -13,6 +13,8 @@ Arguments: label: mnemonic operand comment -s1 Code in three columns label: mnemonic+operand comment + -p0 Processor unknown. + -p1 Processor 6502 + DASM syntax (default) -m8 Start of mnemonic column (default) -o16 Start of operand column (default) -c32 Start of comment column (default) @@ -21,6 +23,9 @@ Arguments: -a0 Align comments to nearest column -a1 Comments at line start are aligned to mnemonic (default) + -n4 Nesting spacing (can be any number + of spaces or multiple of tab size) + -l Put labels in its own line Assumes all your labels are at start of line and there is space before mnemonic. diff --git a/aard1.asm b/aard1.asm deleted file mode 100755 index af203eb..0000000 --- a/aard1.asm +++ /dev/null @@ -1,2040 +0,0 @@ - ; - ; Aardvark - ; - ; by Oscar Toledo G. (nanochess) - ; - ; Creation date: Sep/02/2016. - ; Revision date: Dec/02/2016. Added holes and playfield mouth/eggs. - ; Revision date: Dec/03/2016. Added enemy bitmaps and color. - ; Revision date: Dec/04/2016. Tongue can be started/reverted with joystick. - ; Added eggs in board. - ; Revision date: Dec/06/2016. Tongue rules more close to arcade. Queen ants - ; are now fixed and flashing. Counts eaten eggs - ; and score. Displays score. - ; Revision date: Dec/07/2016. Enemies are filled randomly, also two speeds. - ; Aardvark centered. Dots are thicker now (uses - ; 2 rows). Aardvark walks slower. - ; Revision date: Dec/11/2016. Now is main bank of 8K ROM. Worm appears at - ; tongue tip level. Player can eat ants and - ; worms. - ; Revision date: Dec/12/2016. Enemy collisions now are checked here to avoid - ; too many cycles used in display. - ; Revision date: Jan/18/2016. Added Ranz des Vaches and Mountain King music. - ; Revision date: Jan/19/2016. Corrected lack of feet in aardvark. Added - ; tongue touched music. Added sound effects. - ; Aardvark exits level when all eggs eaten. - ; Remade code for collision of tongue. Corrected - ; bug where eating right queen would delete left - ; queen. - ; Revision date: May/27/2017. Moved all display code to bank 0, this makes it - ; to work with Atari Flashback Portable. - ; Revision date: Oct/02/2017. Sun moves to left. Counts level. - ; Revision date: Oct/08/2017. Added tongue retrain sound effect. Changes hole - ; position randomly. - ; Revision date: Oct/09/2017. Lives counting. Avoids worm appearing over ant. - ; Going down has priority over going left/right - ; but tries also left/right. New enemies: red - ; ant and caterpillar. Only one worm can appear - ; at any moment. Added more difficulty per level. - ; Calculates bonus. New enemy: spider. - ; Revision date: Oct/10/2017. Solved bug where worm would overwrite spider. - ; Solved bug where tongue removed eggs without - ; adjusting egg count. Solved bug where 150 points - ; sprites wouldn't disappear. Added click sound - ; effect for sunset. Added title screen. - ; Revision date: Nov/01/2017. Changed holes1-6 to bitmap interpretation. - ; Revision date: Nov/02/2017. Moved eggs and tongue to extra RAM (Sara chip). - ; Revision date: Nov/03/2017. Renamed level as antHill. Now tongue and eggs - ; bitmaps are intermixed (new display kernel). - ; Sprites now appear at right places. Now hole - ; map is aligned with kernelLst. Updated egg - ; count. Configurable X-limit. - ; Revision date: Nov/04/2017. Relocated direction bit. Collisions working - ; again. - ; Revision date: Nov/05/2017. Corrected worm catch. Score resets REFP0/1. - ; Collision working again. Supports player - ; reflection in display kernel. - ; - - ; Next available label: aa128 - ; Free label: aa84, aa85 - - ; TODO: - ; * Bug: live counting isn't working right. - ; * Bug: egg counting isn't working right. - ; * Tune collisions. - ; * Check if spider is working. - ; * Bug: slight bam tone after winning music. - ; * Bug: spider is slow to appear or doesn't appear. - ; * Handle holes like a bitset instead of coordinate. - ; * Allow backtracking (using up) - ; * Test in MAME for movement details - ; * Clouds (using PF) - ; * Maybe new aardvark sprite, maybe multicolor, maybe 48px: - ; * Aardvark moving ears. - ; * Aardvark sprite sitting when tongue is touched. - ; * Aardvark walking. - ; * Options in title screen. - ; * Starting level. - ; * Message "Press start" in title screen. - ; * Intermediate screen (losing live and completing level): - ; ants - ; x worms - ; * 10 = bonus - ; * Game over (shown below intermediate screen) - ; * Give an extra live each 20000 points. - - ; Differences versus arcade: - ; * Arcade has 8 tunnels, we have 7. - ; * Red ant appears at tunnel 4, in arcade is 5. - ; * Centipede appears at tunnel 5, in arcade is 6. - ; * Worm can appear at tunnel 7 in arcade (we have no space in screen) - - ; Things in unreleased ROM: - ; * Sun timer using a digit counter. - ; * White line after first bottom section - ; * Level and time in second bottom section (separated) - - ; Game in brief: - ; * Move tongue in joystick direction. - ; * Press button to retrain tongue. - ; * Bugs appear randomly on both sides. - ; * Bug touching tongue -> lost life. - ; * Tongue touching bug from behind -> score. - ; * Spider descends from top to bottom, if touch tip -> lost life. - ; * If tongue eats queen -> all enemies in board disappear. - ; * Eating all dots -> level change. - ; * Each level has different configuration of holes in floors. - ; * Ant: 100 points, appears starting in level 1, tunnels 1-4 - ; * Red ant: 150 points, appears starting in level 2, tunnel 5 - ; * Centipede: 150 points, appears starting in level 3, tunnel 6 - ; * Worm: 200 points, appears always at level of tongue. - ; * Only enemy that can appear at tunnel 7. - ; * Tongue cannot move in tunnel 8, nor there are points, only can eat queen. - ; * On restarting level the holes configuration changes. - ; * On restarting level preserves darkness even if the initial animation is - ; done again. - ; * Sun starts more at left per level. Since level 22 always starts barely - ; some pixels from left. - ; * Extra lives each 20000 points - - processor 6502 - - include aardm.asm - - ; - ; Set object in X - ; A = X position - ; First argument = Object to position (0=P0, 1=P1, 2=M0, 3=M1, 4=BALL) - ; - MAC set_x_position - sta WSYNC ; 0- Start line synchro - sec ; 2- Set carry flag (avoids it in loop) -.AE2: sbc #15 ; 4- Uses required time dividing A by 15 - bcs .AE2 ; 6/7 - 11/16/21/26/31/36/41/46/51/56/61/66 - tay ; 8 - lda fine_adjustment-$f1,y; 13 - Eats 5 cycles crossing page - sta HMP0+{1} - nop - sta RESP0+{1} ; 21/26/31/36/41/46/51/56/61/66/71 - "big" positioning - ENDM - - org $f000 ; ROM start address (4K) - - REPEAT 256 - .byte $4f - REPEND - -START: - sta bank1 ; Ghost - sei ; Disable interruptions - cld ; Disable decimal mode - jmp START2 - -ba0: sta bank0 - jmp 0 ; Ghost - - sta bank1 ; Ghost - jmp ba1 - -ba2: sta bank0 - jmp 0 ; Ghost - - sta bank1 - jmp ba3 - -START2: - ldy rand - ; Clean up the memory - ldx #$ff ; Load X with $FF... - txs ; ...copy to stack pointer - lda #0 ; Load zero in accumulator -AE1: sta 0,X ; Save in address 0 plus X - dex ; Decrement X - bne AE1 ; Repeat until X is zero. - sta SWACNT ; Allow to read joysticks - sta SWBCNT ; Allow to read buttons - tsx ; ldx #$ff - stx prev_button - sty rand - - lda rand - sta level_seed - -title_screen: - lda #20 - sta temp1 - jmp ba2 - -ba3: - lda #0 - sta antHill - lda #4 - sta lives - - lda #0 - sta score - sta score+1 - sta score+2 - - ldx #tongue_size*2-12 -aa124: lda #0 - sta tongue1+W,x - sta tongue1+W+1,x - sta tongue1+W+2,x - sta tongue1+W+3,x - sta tongue1+W+4,x - sta tongue1+W+5,x - txa - sec - sbc #12 - tax - bpl aa124 - - ; - ; Goes to next level - ; -next_level: - inc antHill - inc level_seed - - ; - ; Setup starting sun position - ; - lda antHill - asl - bmi aa82 - asl - bpl aa83 -aa82: lda #$80 -aa83: eor #$ff - adc #$98 - sta sun_pos - - lda #$00 - sta COLUBK ; Background color - - ; VERTICAL_SYNC - lda #2 - sta VSYNC ; Start vertical synchro - sta WSYNC ; Wait for 3 lines - sta WSYNC - sta WSYNC - ; - lda #43 - sta TIM64T - lda #0 - sta VSYNC ; Stop vertical synchro - - ldx #tongue_size*2-12 -aa29: lda #0 - sta tongue1+W,x - sta tongue1+W+1,x - sta tongue1+W+2,x - sta tongue1+W+3,x - sta tongue1+W+4,x - sta tongue1+W+5,x - cpx #0 - beq .+4 - lda #$aa - sta eggs1+W,x - sta eggs1+W+2,x - sta eggs1+W+3,x - sta eggs1+W+5,x - lsr - sta eggs1+W+1,x - sta eggs1+W+4,x - txa - sec - sbc #12 - tax - bpl aa29 - - lda #7*20 - sta eggs - - ; - ; Setup queen ants - ; - lda #sprite_queen_ant+ENEMY_DIR_MASK - sta enemy0_t - sta enemy8_t - lda #$2e - sta enemy0_x - lda #$66 - sta enemy8_x - - jmp aa73 - -restart_level: - inc level_seed - lda #$00 - sta effect0 - sta effect1 - sta ants_eaten - sta worms_eaten - sta COLUBK ; Background color - - ; VERTICAL_SYNC - lda #2 - sta VSYNC ; Start vertical synchro - sta WSYNC ; Wait for 3 lines - sta WSYNC - sta WSYNC - ; - lda #43 - sta TIM64T - lda #0 - sta VSYNC ; Stop vertical synchro - -aa73: - lda #1 ; Ranz des Vaches (Rossini) - sta tracker - lda #1 ; Start immediately - sta tracker_c - - lda #6 - sta aa_x_pos - lda #1 - sta timer - lda #0 - sta filling - sta flags - ; - ; Delete tongue and delete also any eggs under - ; - ldx #tongue_size*2-12 -aa69: - ldy #5 -aa80: lda tongue1+R,x - eor #$ff - and eggs1+R,x - sta eggs1+W,x - lda #0 - sta tongue1+W,x - inx - dey - bpl aa80 - txa - sec - sbc #18 - tax - bpl aa69 - - lda #0 - sta enemy1_t - sta enemy2_t - sta enemy3_t - sta enemy4_t - sta enemy5_t - sta enemy6_t - sta enemy7_t - sta enemy9_t - sta enemy10_t - sta enemy11_t - sta enemy12_t - sta enemy13_t - sta enemy14_t - sta enemy15_t - sta holeCols - sta holeCols+1 - sta holeCols+2 - sta holeCols+3 - sta holeCols+4 - sta holeCols+5 - sta holeCols+6 - sta holeCols+7 - lda #$ff - sta tip_y - jmp aa75 - -main_loop: - lda #$00 - sta COLUBK ; Background color - - ; VERTICAL_SYNC - lda #2 - sta VSYNC ; Start vertical synchro - sta WSYNC ; Wait for 3 lines - sta WSYNC - sta WSYNC - ; - lda #43 - sta TIM64T - lda #0 - sta VSYNC ; Stop vertical synchro - -aa75: - ; Nanochess' mini sound effects player - ldx tracker - bne ef4 - lda effect0 - beq ef0 - tax - lda sound_effect,x - bne ef1 - sta effect0 - beq ef0 - -ef1: sta AUDF0 - lda sound_effect+1,x - sta AUDC0 - lsr - lsr - lsr - lsr - inx - inx - stx effect0 - -ef0: sta AUDV0 - - lda effect1 - beq ef2 - tax - lda sound_effect,x - bne ef3 - sta effect1 - beq ef2 - -ef3: sta AUDF1 - lda sound_effect+1,x - sta AUDC1 - lsr - lsr - lsr - lsr - inx - inx - stx effect1 - -ef2: sta AUDV1 - bpl tr0 - - ; Nanochess' mini tracker -ef4: - ldx tracker - beq tr1 - dec tracker_c - bne tr3 - lda music-1,x - bne tr2 - sta tracker - beq tr1 - -tr2: and #$1f - asl - tay - lda music_notes-2,y - sta AUDC0 - lda music_notes-1,y - sta AUDF0 - lda music-1,x - lsr - lsr - and #$38 - sta tracker_c - lda music,x - asl - tay - lda music_notes-2,y - sta AUDC1 - lda music_notes-1,y - sta AUDF1 - inx - inx - stx tracker - lda #$3f - sta tracker_v -tr3: dec tracker_v - lda tracker_v - lsr - lsr - cpx #43 - bcs tr1 - lda tracker_v - and #$03 - bne tr4 - lda #$02 -tr4: ora #$0c -tr1: sta AUDV0 - sta AUDV1 -tr0: - - lda aa_x_pos - cmp #$0f ; Corrects left side X-pos, for some reason it breaks. - bcs *+4 - sbc #2 - set_x_position 0 ; Player 0 - ; ldx #1 ; Player 1 - lda sun_pos - set_x_position 1 ; Player 1 - lda #84 - set_x_position 2 ; Missile 0 - lda #$20 - sta NUSIZ0 - sta NUSIZ1 - - jsr build_hole_map - - lda #$00 - sta GRP0 - sta GRP1 - sta COLUPF - lda #$20 - sta CTRLPF - - jmp ba0 - -ba1: - - ; - ; Score zone - ; - sta WSYNC ; 0 - ldx #$00 ; 3 - stx COLUBK ; 5 Background color - stx GRP0 ; 8 - stx GRP1 ; 11 - stx REFP0 ; 14 - stx REFP1 ; 17 - sta en5 ; 20 - lda score ; 23 - and #$0f ; 26 - asl ; 28 - asl ; 30 - asl ; 32 - sta en4 ; 34 - lda score ; 37 - lsr ; 40 - and #$78 ; 42 - sta en3 ; 44 - lda #$21 ; 47 - sta CTRLPF ; 49 - lda #lives_color ; 52 - sta COLUPF ; 54 - ldx lives ; 57 - cpx #7 ; 60 - bcc aa88 ; 62 - ldx #7 ; 64 -aa88: - lda lives_pf,x ; 66 - sta WSYNC ; 71 - sta PF0 - lda lives_pf+8,x - sta PF1 - lda lives_pf+16,x - sta PF2 - lda score+1 ; 35 - and #$0f ; 38 - asl ; 40 - asl ; 42 - asl ; 44 - sta en2 ; 46 - lda score+1 ; 49 - lsr ; 52 - and #$78 ; 54 - sta en1 ; 56 - lda score+2 ; 59 - and #$0f ; 62 - asl ; 64 - asl ; 66 - asl ; 68 - sta en0 ; 70 - ldx #0 - - lda #score_color ; 73 - jmp $f400 ; 75 - org $F400 -mp0: - sta WSYNC - stx GRP0 - stx GRP1 - ldy #numbers>>8 ; 8 - sty en0+1 ; 11 - sty en1+1 ; 14 - sty en2+1 ; 17 - sty en3+1 ; 20 - sty en4+1 ; 23 - sty en5+1 ; 26 - - sta COLUP0 ; 29 - sta COLUP1 ; 32 - lda #$03 ; 35 3 copies together - ldx #$f0 ; 37 - stx RESP0 ; 39 - stx RESP1 ; 42 - stx HMP0 ; 45 - sta NUSIZ0 ; 48 - sta NUSIZ1 ; 51 - lsr ; 53 - sta VDELP0 ; 56 - sta VDELP1 ; 59 - lsr - sta HMP1 - sta WSYNC ; 62 - sta HMOVE ; 3 - lda #4 - sta temp2 -mp1: ldy temp2 ; 2 - lda (en0),y ; 7 - sta GRP0 ; 10 - sta WSYNC ; 13 + 61 = 76 - lda (en1),y ; 5 - sta GRP1 ; 8 - lda (en2),y ; 13 - sta GRP0 ; 16 - lda (en3),y ; 21 - sta temp1 ; 24 Write (this depends on being at "root" stack pos) - lda (en4),y ; 29 (and of course not being called) - tax ; 31 - lda (en5),y ; 36 - tay ; 38 - lda temp1 ; 41 Read - sta GRP1 ; 44 - stx GRP0 ; 47 - sty GRP1 ; 50 - sta GRP0 ; 53 - dec temp2 ; 58 - bpl mp1 ; 60/61 -mp3: - ; Looks for code spanning page - if (mp1&$ff00)!=(mp3&$ff00) - lda megabug3 ; :P - endif - echo "mp0 ",mp0," mp1 ",mp1," mp3 ",mp3 - - ; - ; End of graphics (204 lines) - ; - ldx #$00 - lda #2 - sta WSYNC - sta VBLANK - stx VDELP0 - stx VDELP1 - stx GRP0 - stx GRP1 - stx PF0 - stx PF1 - stx PF2 - - ; - ; Start overscan timer - ; - lda #43 ; 37 lines * 76 = 2812 cycles / 64 = 43.9375 - sta TIM64T - - lda flags - and #$03 - cmp #$02 ; Tongue touched? - bne aa67 - jmp wait_overscan - -aa67: lda eggs - bne aa70 - ldx aa_x_pos - cpx #52 - bne aa71 - inc aa_x_pos - lda #43 ; Mountain King (Grieg) - sta tracker - lda #1 - sta tracker_c - lda #0 - sta filling - sta flags - ldx #tongue_size*2-1 - lda #0 -aa72: sta tongue1+W,x - dex - bpl aa72 - - sta enemy0_t - sta enemy1_t - sta enemy2_t - sta enemy3_t - sta enemy4_t - sta enemy5_t - sta enemy6_t - sta enemy7_t - sta enemy8_t - sta enemy9_t - sta enemy10_t - sta enemy11_t - sta enemy12_t - sta enemy13_t - sta enemy14_t - sta enemy15_t - sta holeCols - sta holeCols+1 - sta holeCols+2 - sta holeCols+3 - sta holeCols+4 - sta holeCols+5 - sta holeCols+6 - sta holeCols+7 - lda #$ff - sta tip_y -aa71: jmp aa34 - -aa70: lda flags - and #$fc - sta flags - - ; - ; Check for collisions of enemies versus tongue (playfield pixels) - ; - ldx #15 -aa53: lda enemy0_t,x - tay - cmp #non_interactive_sprites - bcc aa86 - cpx #8 - bcs aa45 - lda cxLst,x - and #$20 - beq aa86 ; No, jump - bne aa127 - -aa45: lda cxLst-8,x - asl - bpl aa86 - -aa127: tya - and #$f0 - cmp #sprite_spider - beq aa106 - cmp #sprite_worm ; Is it a worm? - beq aa55 - bne aa87 - -aa86: - dex - bpl aa53 - jmp aa78 - - ; - ; Spider - ; * Kills if touches tongue tip - ; -aa106: - txa - and #$07 - cmp tip_y ; Is it at same level than tongue? - bne aa86 ; No, jumps - lda enemy0_x,x - tay - sbc #3 - lsr - lsr - cmp tip_x - beq aa56sc - tya - clc - adc #10 - lsr - lsr - cmp tip_x - beq aa56sc - bne aa86 - -aa87: - ; - ; Ant: - ; * Eaten if tongue tip. - ; * Kills if it touch any other part of tongue. - ; - txa - and #$07 - cmp tip_y ; Is it at same level than tongue? - bne aa56sc ; No, kills - lda enemy0_x,x - sbc #3 - tay - lsr - lsr - cmp tip_x - beq aa57 - bcs aa56 - tya - clc - adc #10 - lsr - lsr - cmp tip_x - beq aa57 - bcc aa56 - -aa57: lda enemy0_t,x - cmp #sprite_queen_ant+$20 - bcs aa125 - cmp #sprite_queen_ant - bcs aa59 -aa125: cmp #pricey_sprites ; Red ant and caterpillar - bcs aa97 - sed - lda ants_eaten - adc #1 - sta ants_eaten - cld - lda #sprite_explosion; Goodbye ant - .byte $2c ; BIT opcode to jump -aa97: lda #sprite_150 - ldy #11 - bne aa79 - -aa56sc: jmp aa56 - -aa59: jsr clear_enemies - ldy #33 -aa79: sty effect1 - bne aa60 - - ; - ; Worm: - ; * Eaten if tongue tip from behind. - ; * Kills only if tongue tip in front. - ; -aa55: txa - and #$07 - cmp tip_y - bne aa54 - lda enemy0_x,x - tay - sbc #3 - lsr - lsr - cmp tip_x - beq aa58 - bcs aa54 - tya - clc - adc #10 - lsr - lsr - cmp tip_x - beq aa58 - bcc aa54 -aa58: lda tip_dir - beq aa56 - lsr ; $ff left $00 right - eor enemy0_t,x - and #ENEMY_SPEED_MASK - bne aa56 - lda flags - and #~FLAGS_WORM - sta flags - inc worms_eaten - lda #20 - sta effect1 - lda #sprite_200 ; 200 points -aa60: sta enemy0_t,x - bne aa54 - - ; Kill -aa56: lda flags - and #$fc - ora #$01 - sta flags - -aa54: - dex - bmi aa78 - jmp aa53 -aa78: - - lda flags - and #$03 - beq aa52 - jmp wait_overscan - - ; - ; Invoke an enemy - ; -aa52: - dec timer - beq aa95 - jmp aa14 -aa95: - jsr random_proc ; Get a random number (just because :P) - tay ; Save it - and #$0e ; Restart timer - ora #$01 - sta timer - lda antHill ; Starts at 1 - clc - adc #$03 ; Level 1 - fills 4 tunnels, 2 - 5 t., 4 and so- 6 t. - cmp #$06 ; No more than 6 tunnels - bcc aa92 - lda #$06 -aa92: asl - sta temp1 - lda filling - cmp temp1 - bcc aa102 -aa103: jmp aa8 -aa102: - and #$0e - lsr - eor #$07 - tax - cmp #$07 - bne aa111 - lda enemy8_t,x - bne aa111 - lda #FLAGS_SPIDER - bit flags - bne aa111 - lda sun_pos - cmp #8 ; Now it's night? - beq aa110 ; No, jump -aa111: lda enemy0_t,x ; There is space for a common enemy? - beq aa12 ; Yep, jump. -aa110: lda enemy8_t,x ; There is space for a worm/spider? - bne aa103 ; No, jump - cpx #0 ; Top tunnel? - bne aa101 ; No, jump - lda sun_pos - cmp #8 ; Now it's night? - bne aa101 ; No, jump - lda #FLAGS_SPIDER - bit flags ; We have already the spider? - bne aa101 ; Yes, jump - ora flags - sta flags - lda #ENEMY_MAX_X - sta enemy8_x,x - tya - and #ENEMY_SPEED_MASK - ora #sprite_spider - sta enemy8_t,x - bne aa8 - -aa101: - txa - and #$07 - cmp tip_y - bne aa103 - lda #FLAGS_WORM - bit flags ; Already a worm in screen? - bne aa8 ; Yes, jump - ora flags - sta flags - tya - and #$40 - beq aa37 - lda enemy0_x,x - cmp #40 - bcc aa90 -aa91: lda #ENEMY_MIN_X - sta enemy8_x,x - tya - and #ENEMY_SPEED_MASK - ora #sprite_worm+ENEMY_DIR_MASK - sta enemy8_t,x - bne aa8 - -aa37: lda enemy0_x,x - cmp #129 - bcs aa91 -aa90: lda #ENEMY_MAX_X - sta enemy8_x,x - tya - and #ENEMY_SPEED_MASK - ora #sprite_worm - sta enemy8_t,x - bne aa8 - -aa12: tya - and #$40 - beq aa15 - lda #ENEMY_MIN_X - sta enemy0_x,x - tya - and #ENEMY_SPEED_MASK - ora enemies_going_right,x - sta enemy0_t,x - bne aa8 - -aa15: lda #ENEMY_MAX_X - sta enemy0_x,x - tya - and #ENEMY_SPEED_MASK - ora enemies_going_left,x - sta enemy0_t,x - ; bne aa8 - -aa8: ldx antHill - cpx #32 - bcc aa93 - ldx #31 -aa93: lda filling - clc - adc #2 - cmp refilling,x - bne aa94 - lda #0 -aa94: sta filling -aa14: - - ; - ; Sun animation - ; - lda frame - and #$1f ; Each 32 frames - bne aa81 - lda sun_pos - cmp #8 - beq aa81 - dec sun_pos ; Move sun left by one pixel - cmp #9 - bne aa81 - lda #129 ; Click effect - sta effect0 -aa81: - - ; - ; Enemy animation and movement - ; - ldy #0 - lda frame - and #$07 ; Enemies change animation frame each 8 frames - bne aa11 - ldy #8 -aa11: and #$03 ; Enemies move each 4 frame - beq aa117 - jmp aa43 -aa117: - ldx #$0f -aa10: - lda enemy0_t,x ; Active enemy? - bne aa118 ; Yes, jump -aa120: dex - bpl aa10 - jmp aa43 - - ; - ; Check first for brief sprites (explosion, 150 and 200 points) - ; -aa118: cmp #non_interactive_sprites - bcs aa39 -aa49: inc enemy0_t,x - cmp #sprite_150+$03 - beq aa96 - cmp #sprite_200+$03 - beq aa46 - cmp #sprite_200_spider+$03 - beq aa46 - cmp #sprite_explosion+$03 - bne aa38sd - lda #$10 ; 100 points - .byte $2c ; BIT opcode to jump -aa46: lda #$20 ; 200 points - .byte $2c ; BIT opcode to jump -aa96: lda #$15 ; 150 points - jsr score_points - lda #$00 - sta enemy0_t,x -aa38sd: jmp aa38 - ; - ; All other sprites - ; -aa39: and #$f0 - cmp #sprite_spider - bne aa108 - ; - ; Spider handling - ; - lda tip_y ; Tongue tip active? - bmi aa120 ; No, jump (spider stays quiet) - txa ; Get vertical position of spider - and #$07 - cmp tip_y ; Comparison with tongue tip vertical position. - beq aa109 ; Same vertical position? yes, jump - bcs aa120 ; Jump if spider deeper than tongue tip. It shouldn't happen - stx temp1 - tax - lda holeCols,x ; Check if tongue goes thru a hole !!! - lsr - bcs aa112 - lsr - bcs aa113 - lsr - bcs aa114 - lda #0 - .byte $2c ; BIT opcode to jump -aa114: lda #8 - .byte $2c ; BIT opcode to jump -aa113: lda #16 - .byte $2c ; BIT opcode to jump -aa112: lda #24 - clc - adc kernelLst,x - tax - lda hole_pos,x ; Now get the X-coordinate for hole - ldx temp1 - sec ; There's an X-coordinate, center spider over it - sbc #2 - jmp aa116 - - ; - ; Spider at same level than tongue tip - ; -aa109: lda tip_x - asl - asl - beq aa116 - sbc #1 -aa116: sbc enemy0_x,x ; Take a decision of direction to move - beq aa119 ; At target position? yes, jump - bcc aa44 - bcs aa40 - - ; - ; Try to lower spider by one level - ; -aa119: cpx #1 ; Is spider at bottom-most position? - beq aa41 ; Yes, jump, stay quiet - cpx #9 - beq aa41 - lda enemy0_t-1,x ; Is it busy the next enemy slot? - bne aa41 ; Yes, jump, stay quiet - lda enemy0_x,x ; Copy X position - sta enemy0_x-1,x - lda enemy0_t,x ; Copy type - sta enemy0_t-1,x - lda #0 ; Erase spider from old slot - sta enemy0_t,x - beq aa41 - - ; - ; Ant, red ant, worm or centipede - ; -aa108: - cmp #sprite_queen_ant - beq aa38 - cmp #sprite_queen_ant+$10 - beq aa38 - lda enemy0_t,x - and #ENEMY_SPEED_MASK ; Fast? - beq aa44 - lda frame - and #$04 -aa38sc: bne aa38 -aa44: - lda enemy0_t,x - and #ENEMY_DIR_MASK ; Goes to left? - bne aa40 ; No, jump - dec enemy0_x,x - lda enemy0_x,x - cmp #ENEMY_MIN_X ; Reached left limit? - bne aa41 ; No, jump -aa42: - lda enemy0_t,x - and #$f0 - cmp #sprite_worm - bne aa98 - lda flags - and #~FLAGS_WORM - sta flags -aa98: cmp #sprite_spider ; It could happen *sigh* - bne aa107 - lda flags - and #~FLAGS_SPIDER - sta flags -aa107: lda #0 - sta enemy0_t,x - beq aa38 - -aa40: - inc enemy0_x,x - lda enemy0_x,x - cmp #ENEMY_MAX_X ; Reached right limit? - beq aa42 ; Yes, jump -aa41: - tya - eor enemy0_t,x ; Changed animation frame if required - sta enemy0_t,x -aa38: dex - bmi aa43 - jmp aa10 -aa43: - - ; - ; Queen ant flashing - ; - lda frame - and #$01 - bne aa34 - lda enemy0_t - beq aa32 - cmp #non_interactive_sprites - bcs aa51 - adc #1 - cmp #sprite_1000+8 - bne aa32 - jsr score_points_2 ; 1000 points - lda #0 - beq aa32 - -aa51: adc #$07 - cmp #sprite_queen_ant+$20 - bcc aa32 - sbc #$20 -aa32: sta enemy0_t - - lda enemy8_t - beq aa33 - cmp #non_interactive_sprites - bcs aa50 - adc #1 - cmp #sprite_1000+8 - bne aa33 - jsr score_points_2 ; 1000 points - lda #0 - beq aa33 - -aa50: adc #$07 - cmp #sprite_queen_ant+$20 - bcc aa33 - sbc #$20 -aa33: sta enemy8_t -aa34: - ; - ; Count frame, step on random generator - ; - inc frame - jsr random_proc - ; - ; Aardvark enters game - ; - ldx aa_x_pos - cpx #52 - beq aa7 - lda frame - and #$07 - bne aa31 - inc aa_x_pos - cpx #51 - bne aa31 - ; Start tongue - lda #$02 - sta holeCols+7 - ldx #19 - stx tip_x - lda #7 - sta tip_y - lda #0 - sta tip_dir - jsr point_egg - ldx tip_x - lda tip_y - jsr draw_block -aa31: - lda frame - and #$07 - bne aa4 - lda aa_offset - eor #$28 - sta aa_offset -aa4: - jmp aa20 - -aa7: - lda #0 - - jsr fire_button ; Fire button pressed? - bpl aa22 ; No, jump - - ldx tip_x ; Get tongue coordinates - lda tip_y - cpx #19 - bne aa19 - cmp #7 - beq aa123 ; Is it at base? yes, jump without doing anything -aa19: - jsr clear_block - lda effect0 - cmp #128 - bcs aa122 - cmp #66 - bcs aa121 -aa122: - lda #66 - sta effect0 -aa121: ldx tip_x - beq aa23 - dex - lda tip_y - jsr check_block - bne aa24 - inx - -aa23: cpx #39 - beq aa25 - inx - lda tip_y - jsr check_block - bne aa24 - -aa25: ldx tip_y - lda #$00 - sta holeCols,x - inc tip_y - jmp aa20 - -aa24: stx tip_x - jmp aa20 - -aa123: jmp aa28 - -aa22: - jsr build_hole_map - lda SWCHA - ; Note #$10 isn't used (going up) - and #$20 ; Going down? - beq aa17 ; Yes, jump -aa18: lda SWCHA - bmi aa16 ; Going right? No, jump - lda tip_y - bmi aa28 - beq aa28 ; Last tunnel? Yes, cannot move - lda frame - lsr - bcc aa28 - ldx tip_x - cpx #39 - beq aa28 - inx -aa26: lda tip_y - jsr check_block - bne aa30 - txa - sec - sbc tip_x - sta tip_dir - stx tip_x - lda tip_y - jsr point_egg - ldx tip_x - lda tip_y - jsr draw_block - jmp aa20 - -aa30: txa - pha - ldx tip_x - lda tip_y - jsr clear_block - pla - sta tip_x -aa28: jmp aa20 - -aa16: rol ; Going left? - bmi aa20 - lda tip_y - bmi aa20 - beq aa20 ; Last tunnel? Yes, cannot move - lda frame - lsr - bcc aa20 - ldx tip_x - beq aa20 - dex - bpl aa26 - - ; - ; Going down - ; -aa17: ldx tip_y ; Get row of tongue tip - bmi aa18 ; Invalid? Yes, jump to check for right/left - beq aa18 ; Vertical limit? Yes, jump to check for right/left - lda kernelLst-1,x - tax - lda tip_x ; Tongue tip at 0? - beq aa18 ; Jump to check for right/left - cmp hole_pos,x - beq aa126 - cmp hole_pos+8,x - beq aa27 - cmp hole_pos+16,x - beq aa115 - cmp hole_pos+24,x - bne aa18 ; No hole, so jump to check for right/left - ldy #$01 - .byte $2c ; BIT opcode to jump -aa115: ldy #$02 - .byte $2c ; BIT opcode to jump -aa126: ldy #$08 - .byte $2c ; BIT opcode to jump -aa27: ldy #$04 - tya - ldx tip_y - dex - ora holeCols,x - sta holeCols,x - stx tip_y - txa - ldx tip_x - jsr point_egg - ldx tip_x - lda tip_y - jsr draw_block - lda #0 - sta tip_dir - -aa20: - -wait_overscan: - lda INTIM - bne wait_overscan - sta WSYNC - sta WSYNC - - lda aa_x_pos - cpx #135 - bne aa74 - jsr bonus_screen - jmp next_level -aa74: - - lda flags - and #$03 - cmp #$02 ; Has finished tongue color changing animation? - beq aa68 ; Yes, jump - jmp main_loop ; Continue with main loop - -aa68: dec lives - jsr bonus_screen - lda lives - bmi aa89 - jmp restart_level ; Restart level - -aa89: jmp title_screen - - ; - ; Bonus screen - ; -bonus_screen: - ldx worms_eaten - beq aa99 -aa100: - lda ants_eaten - jsr score_points - dex - bne aa100 -aa99: - rts - - ; - ; Run random number generator - ; -random_proc: - ; - ; Random number generator - ; - lda rand - sec - ror - eor frame - ror - eor rand - ror - eor #9 - sta rand - rts - - ; - ; Check for fire button - ; -fire_button_single: - lda INPT4 - eor #$ff - tax - eor prev_button - stx prev_button - bpl fire_button1 - txa -fire_button1: - rts - -fire_button: - lda INPT4 - eor #$ff - sta prev_button - rts - - ; - ; Calculate memory zone for tongue block - ; a = zone (0-7) - ; -calc_zone: - asl ; x2 - asl ; x4 - sta en0 - asl ; x8 - adc en0 ; x12 - adc #tongue1 - sta en0 - adc #W - sta en0+1 - sta en1+1 - rts - - ; - ; Check for tongue block - ; - ; a = zone (0-5) - ; x = x pixel (0-39) - ; -check_block: - jsr calc_zone - lda pixel_to_byte,x - tay - lda (en1),y - and pixel_to_bit,x - rts - - ; - ; Clear enemies (used when eating queen ant) - ; -clear_enemies: - txa - pha - ldx #9 -aa61: lda enemy0_t,x - cmp #non_interactive_sprites - bcc aa62 - and #$f0 - cmp #sprite_worm - beq aa63 - cmp #sprite_spider - beq aa104 - cmp #pricey_sprites - bcs aa64 - lda #sprite_explosion - .byte $2c ; BIT opcode to jump -aa63: lda #sprite_200 - .byte $2c ; BIT opcode to jump -aa64: lda #sprite_150 - .byte $2c ; BIT opcode to jump -aa104: lda #sprite_200_spider - sta enemy0_t,x - cmp #sprite_200_spider - bne aa105 - lda flags - and #~FLAGS_SPIDER - sta flags -aa105: - cmp #sprite_200 ; Only a worm gives a 200 points bonus - bne aa62 - lda flags - and #~FLAGS_WORM - sta flags -aa62: dex - bpl aa61 - pla - tax - lda #sprite_1000 - rts - - ; - ; Give points per egg eaten - ; - ; a = zone (0-7) - ; x = x pixel (0-39) - ; -point_egg: - cmp #0 - beq aa35 - jsr calc_zone - lda en1 - clc - adc #tongue_to_eggs - sta en1 - lda pixel_to_byte,x - tay - lda (en1),y - and pixel_to_bit,x - beq aa35 - lda eggs - ror - lda #1 - bcc aa77 - lda #6 -aa77: sta effect0 - dec eggs - lda #1 - - ; Score 1 point for egg eaten -score_points: - clc - sed - adc score - sta score -aa48: lda score+1 - adc #0 - sta score+1 - lda score+2 - adc #0 - sta score+2 - cld -aa35: - rts - -score_points_2: - sec - sed - bcs aa48 - - ; - ; Draw a tongue block - ; - ; a = zone (0-7) - ; x = x pixel (0-39) - ; -draw_block: - jsr calc_zone - lda pixel_to_byte,x - tay - lda (en1),y - ora pixel_to_bit,x - sta (en0),y - lda en0 - clc - adc #tongue_to_eggs - sta en0 - lda en1 - adc #tongue_to_eggs - sta en1 - lda (en1),y - ora pixel_to_bit,x - sta (en0),y - rts - - ; - ; Clear a tongue block - ; - ; a = zone (0-7) - ; x = x pixel (0-39) - ; -clear_block: - jsr calc_zone - lda pixel_to_byte,x - tay - lda (en1),y - and pixel_to_bit2,x - sta (en0),y - lda en0 - clc - adc #tongue_to_eggs - sta en0 - lda en1 - adc #tongue_to_eggs - sta en1 - lda (en1),y - and pixel_to_bit2,x - sta (en0),y - rts - - ; - ; Build random hole map for the current level seed - ; See also random.c - ; -build_hole_map: SUBROUTINE -.lastPat = tmpVars - lda #255 - sta .lastPat - ldy #NUM_FLOORS-1 - ldx level_seed -.0: - lda random_level,x - tax - and #$07 - cmp .lastPat - bne .1 - txa - lsr - lsr - tax - and #$07 -.1: - sta kernelLst,y - sta .lastPat - dey - bne .0 - sty kernelLst ; Fixed tunnel for queen ants - rts - - ; - ; With the help of: - ; - ; http://alienbill.com/2600/basic/music/tune2600.html - ; http://piano-player.info/ - ; - - ; - ; Songs refer to these notes. - ; These notes contain frequency and "instrument" and are - ; choosen per usage in song instead of full "continuous" octaves - ; -music_notes: - .byte 12,12 ; 1 - .byte 4,28 - .byte 4,25 ; 3 - .byte 4,22 - .byte 4,18 ; 5 - .byte 4,16 - - .byte 12,20 ; 7 - .byte 12,19 - .byte 12,18 ; 9 - .byte 12,17 - .byte 12,15 ; 11 - .byte 12,14 - .byte 12,13 ; 13 - .byte 12,11 - .byte 4,31 ; 15 - - .byte 6,7 ; 16 - .byte 6,6 ; 17 - .byte 12,27 ; 18 - .byte 12,23 ; 19 - - .byte 0,0 ; 20 Unused - - .byte 6,7 ; 21 - .byte 12,30 - .byte 12,27 ; 23 - .byte 12,24 - .byte 12,20 ; 25 - .byte 12,18 - - .byte 0,0 ; 27 Unused - .byte 1,12 ; 29 - .byte 1,6 ; 31 - .byte 1,13 ; 33 - .byte 1,9 ; 35 - .byte 0,0 - - ; - ; Global label to access music - ; -music: - - ; - ; Ranz des vaches - ; -music_ranz_des_vaches: - .byte 6*32+2,22 ; 1 -> tracker - .byte 1*32+3,23 - .byte 1*32+1,21 - .byte 1*32+2,22 - .byte 1*32+4,24 - .byte 1*32+1,21 - - .byte 6*32+2,22 - .byte 1*32+3,23 - .byte 1*32+1,21 - .byte 1*32+2,22 - .byte 1*32+4,24 - .byte 1*32+1,21 - - .byte 6*32+2,22 - .byte 1*32+4,24 - .byte 1*32+6,26 - .byte 1*32+5,25 - .byte 1*32+1,21 - .byte 1*32+4,24 - - .byte 5*32+3,23 - .byte 1*32+5,25 - - .byte 0,0 - - ; - ; Mountain king - ; -music_mountain_king: - .byte 2*32+7,16 ; 43 -> tracker - .byte 2*32+9,16 - .byte 2*32+10,18 - .byte 2*32+11,18 - .byte 2*32+13,16 - .byte 2*32+10,16 - .byte 4*32+13,18 - - .byte 2*32+12,16 - .byte 2*32+9,16 - .byte 4*32+12,18 - .byte 2*32+11,16 - .byte 2*32+8,16 - .byte 4*32+11,18 - - .byte 2*32+7,16 - .byte 2*32+9,16 - .byte 2*32+10,18 - .byte 2*32+11,18 - .byte 2*32+13,16 - .byte 2*32+10,16 - .byte 2*32+13,18 - .byte 2*32+15,18 - - .byte 2*32+14,17 - .byte 2*32+13,17 - .byte 2*32+10,19 - .byte 2*32+13,19 - .byte 7*32+14,17 - - .byte 0,0 - - ; - ; Death music - ; -music_touch: - .byte 4*32+28,28 ; 97 -> tracker - .byte 4*32+29,29 - .byte 4*32+30,30 - .byte 7*32+31,31 - .byte 0,0 - - ; - ; Global label to access sound effects - ; -sound_effect: - .byte 0 - - .byte $04,$81 ; 1 Eating egg (1) - .byte $03,$71 ; 3 - .byte 0 ; 5 - - .byte $08,$81 ; 6 Eating egg (2) - .byte $07,$71 ; 8 - .byte 0 ; 10 - - .byte $07,$88 ; 11 Eating bug - .byte $06,$88 ; 13 - .byte $07,$88 ; 15 - .byte $06,$88 ; 17 - .byte 0 ; 19 - - .byte $1c,$fc ; 20 Eating worm - .byte $1c,$cc ; 22 - .byte $1c,$ac ; 24 - .byte $1c,$8c ; 26 - .byte $1c,$6c ; 28 - .byte $1c,$4c ; 30 - .byte 0 ; 32 - - .byte $1c,$fc ; 33 Eating queen - .byte $1c,$cc ; 35 - .byte $1c,$ac ; 37 - .byte $1c,$8c ; 39 - .byte $1c,$6c ; 41 - .byte $1c,$4c ; 43 - .byte $10,$ec ; 45 - .byte $10,$cc ; 47 - .byte $10,$ac ; 49 - .byte $10,$6c ; 51 - .byte $10,$4c ; 53 - .byte $10,$3c ; 55 - .byte $10,$4c ; 57 - .byte $10,$3c ; 59 - .byte $10,$4c ; 61 - .byte $10,$3c ; 63 - .byte 0 ; 65 - - .byte $1f,$c4 ; 66 Retrain tongue - .byte $1e,$b4 ; 68 - .byte $1d,$c4 ; 70 - .byte $1c,$b4 ; 72 - .byte $1b,$c4 ; 74 - .byte $1a,$b4 ; 76 - .byte $19,$c4 ; 78 - .byte $18,$b4 ; 80 - .byte $17,$c4 ; 82 - .byte $16,$b4 ; 84 - .byte $15,$c4 ; 86 - .byte $14,$b4 ; 88 - .byte $13,$c4 ; 90 - .byte $12,$b4 ; 92 - .byte $11,$c4 ; 94 - .byte $10,$b4 ; 96 - .byte $0f,$c4 ; 98 - .byte $0e,$b4 ; 100 - .byte $0d,$c4 ; 102 - .byte $0c,$b4 ; 104 - .byte $0b,$c4 ; 106 - .byte $0a,$b4 ; 108 - .byte $09,$c4 ; 110 - .byte $08,$b4 ; 112 - .byte $07,$c4 ; 114 - .byte $06,$b4 ; 116 - .byte $05,$c4 ; 118 - .byte $04,$b4 ; 120 - .byte $03,$c4 ; 122 - .byte $02,$b4 ; 124 - .byte $01,$c4 ; 126 - .byte 0 - - .byte $18,$c1 ; 129 Click effect for sunset - .byte $0c,$61 ; 131 - .byte $06,$a1 ; 133 - .byte $03,$41 ; 135 - .byte $02,$81 ; 137 - .byte $01,$21 ; 139 - .byte 0 - - echo "Before random_level at $fd00: ",* - - org $fd00 - - .include "aardlev.asm" - - org $fe00 -fine_adjustment: - .byte $70 ; -7 - .byte $60 ; -6 - .byte $50 ; -5 - .byte $40 ; -4 - .byte $30 ; -3 - .byte $20 ; -2 - .byte $10 ; -1 - .byte $00 ; 0 - .byte $f0 ; +1 - .byte $e0 ; +2 - .byte $d0 ; +3 - .byte $c0 ; +4 - .byte $b0 ; +5 - .byte $a0 ; +6 - .byte $90 ; +7 - -pixel_to_byte: - .byte 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2 - .byte 3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5 - -pixel_to_bit: - .byte $10,$20,$40,$80 - .byte $80,$40,$20,$10,$08,$04,$02,$01 - .byte $01,$02,$04,$08,$10,$20,$40,$80 - - .byte $10,$20,$40,$80 - .byte $80,$40,$20,$10,$08,$04,$02,$01 - .byte $01,$02,$04,$08,$10,$20,$40,$80 - -pixel_to_bit2: - .byte $ef,$df,$bf,$7f - .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe - .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f - - .byte $ef,$df,$bf,$7f - .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe - .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f - - ; - ; Position for holes (in "fat" pixels) - ; Note vertical sorting, one line of holes is made from one column of data. - ; A B C D E F G H - ; -hole_pos: - .byte 0, 6, 3, 0, 0, 0, 0, 0 - .byte 12,12, 9, 6, 9, 3, 0,15 - .byte 26,18,20,26,23,15,18,23 - .byte 0,32,35,32, 0,29,29,35 - - ; - ; Lives representation as playfield graphics - ; -lives_pf: - .byte $00,$40,$40,$40,$40,$40,$40,$40 - .byte $00,$00,$80,$a0,$a8,$aa,$aa,$aa - .byte $00,$00,$00,$00,$00,$00,$01,$05 - - ; - ; Refilling constant per level - ; -refilling: - .byte 128,126,124,122,120,118,116,114 - .byte 112,110,108,106,104,102,100,98 - .byte 96,94,92,90,88,86,84,82 - .byte 80,78,76,74,72,70,68,66 - - ; - ; Enemies per tunnel - ; -enemies_going_right: - .byte 0 - .byte 0 - .byte sprite_caterpillar+ENEMY_DIR_MASK - .byte sprite_red_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte 0 - .byte 0 - .byte sprite_caterpillar+ENEMY_DIR_MASK - .byte sprite_red_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - -enemies_going_left: - .byte 0 - .byte 0 - .byte sprite_caterpillar - .byte sprite_red_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - .byte 0 - .byte 0 - .byte sprite_caterpillar - .byte sprite_red_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - - org $ff00 -numbers: - .byte $fe,$c6,$c6,$c6,$fe,$00,$00,$00 - .byte $78,$30,$30,$70,$30,$00,$00,$00 - .byte $fe,$c0,$fe,$06,$fe,$00,$00,$00 - .byte $fe,$06,$fe,$06,$fe,$00,$00,$00 - .byte $06,$06,$fe,$c6,$c6,$00,$00,$00 - .byte $fe,$06,$fe,$c0,$fe,$00,$00,$00 - .byte $fe,$c6,$fe,$c0,$fe,$00,$00,$00 - .byte $18,$18,$0c,$06,$fe,$00,$00,$00 - .byte $fe,$c6,$fe,$c6,$fe,$00,$00,$00 - .byte $fe,$06,$fe,$c6,$fe,$00,$00,$00 - - org $fffc - .word START ; RESET - .word START ; BRK - diff --git a/aard1.new.asm b/aard1.new.asm deleted file mode 100644 index 54ea7db..0000000 --- a/aard1.new.asm +++ /dev/null @@ -1,2040 +0,0 @@ - ; - ; Aardvark - ; - ; by Oscar Toledo G. (nanochess) - ; - ; Creation date: Sep/02/2016. - ; Revision date: Dec/02/2016. Added holes and playfield mouth/eggs. - ; Revision date: Dec/03/2016. Added enemy bitmaps and color. - ; Revision date: Dec/04/2016. Tongue can be started/reverted with joystick. - ; Added eggs in board. - ; Revision date: Dec/06/2016. Tongue rules more close to arcade. Queen ants - ; are now fixed and flashing. Counts eaten eggs - ; and score. Displays score. - ; Revision date: Dec/07/2016. Enemies are filled randomly, also two speeds. - ; Aardvark centered. Dots are thicker now (uses - ; 2 rows). Aardvark walks slower. - ; Revision date: Dec/11/2016. Now is main bank of 8K ROM. Worm appears at - ; tongue tip level. Player can eat ants and - ; worms. - ; Revision date: Dec/12/2016. Enemy collisions now are checked here to avoid - ; too many cycles used in display. - ; Revision date: Jan/18/2016. Added Ranz des Vaches and Mountain King music. - ; Revision date: Jan/19/2016. Corrected lack of feet in aardvark. Added - ; tongue touched music. Added sound effects. - ; Aardvark exits level when all eggs eaten. - ; Remade code for collision of tongue. Corrected - ; bug where eating right queen would delete left - ; queen. - ; Revision date: May/27/2017. Moved all display code to bank 0, this makes it - ; to work with Atari Flashback Portable. - ; Revision date: Oct/02/2017. Sun moves to left. Counts level. - ; Revision date: Oct/08/2017. Added tongue retrain sound effect. Changes hole - ; position randomly. - ; Revision date: Oct/09/2017. Lives counting. Avoids worm appearing over ant. - ; Going down has priority over going left/right - ; but tries also left/right. New enemies: red - ; ant and caterpillar. Only one worm can appear - ; at any moment. Added more difficulty per level. - ; Calculates bonus. New enemy: spider. - ; Revision date: Oct/10/2017. Solved bug where worm would overwrite spider. - ; Solved bug where tongue removed eggs without - ; adjusting egg count. Solved bug where 150 points - ; sprites wouldn't disappear. Added click sound - ; effect for sunset. Added title screen. - ; Revision date: Nov/01/2017. Changed holes1-6 to bitmap interpretation. - ; Revision date: Nov/02/2017. Moved eggs and tongue to extra RAM (Sara chip). - ; Revision date: Nov/03/2017. Renamed level as antHill. Now tongue and eggs - ; bitmaps are intermixed (new display kernel). - ; Sprites now appear at right places. Now hole - ; map is aligned with kernelLst. Updated egg - ; count. Configurable X-limit. - ; Revision date: Nov/04/2017. Relocated direction bit. Collisions working - ; again. - ; Revision date: Nov/05/2017. Corrected worm catch. Score resets REFP0/1. - ; Collision working again. Supports player - ; reflection in display kernel. - ; - - ; Next available label: aa128 - ; Free label: aa84, aa85 - - ; TODO: - ; * Bug: live counting isn't working right. - ; * Bug: egg counting isn't working right. - ; * Tune collisions. - ; * Check if spider is working. - ; * Bug: slight bam tone after winning music. - ; * Bug: spider is slow to appear or doesn't appear. - ; * Handle holes like a bitset instead of coordinate. - ; * Allow backtracking (using up) - ; * Test in MAME for movement details - ; * Clouds (using PF) - ; * Maybe new aardvark sprite, maybe multicolor, maybe 48px: - ; * Aardvark moving ears. - ; * Aardvark sprite sitting when tongue is touched. - ; * Aardvark walking. - ; * Options in title screen. - ; * Starting level. - ; * Message "Press start" in title screen. - ; * Intermediate screen (losing live and completing level): - ; ants - ; x worms - ; * 10 = bonus - ; * Game over (shown below intermediate screen) - ; * Give an extra live each 20000 points. - - ; Differences versus arcade: - ; * Arcade has 8 tunnels, we have 7. - ; * Red ant appears at tunnel 4, in arcade is 5. - ; * Centipede appears at tunnel 5, in arcade is 6. - ; * Worm can appear at tunnel 7 in arcade (we have no space in screen) - - ; Things in unreleased ROM: - ; * Sun timer using a digit counter. - ; * White line after first bottom section - ; * Level and time in second bottom section (separated) - - ; Game in brief: - ; * Move tongue in joystick direction. - ; * Press button to retrain tongue. - ; * Bugs appear randomly on both sides. - ; * Bug touching tongue -> lost life. - ; * Tongue touching bug from behind -> score. - ; * Spider descends from top to bottom, if touch tip -> lost life. - ; * If tongue eats queen -> all enemies in board disappear. - ; * Eating all dots -> level change. - ; * Each level has different configuration of holes in floors. - ; * Ant: 100 points, appears starting in level 1, tunnels 1-4 - ; * Red ant: 150 points, appears starting in level 2, tunnel 5 - ; * Centipede: 150 points, appears starting in level 3, tunnel 6 - ; * Worm: 200 points, appears always at level of tongue. - ; * Only enemy that can appear at tunnel 7. - ; * Tongue cannot move in tunnel 8, nor there are points, only can eat queen. - ; * On restarting level the holes configuration changes. - ; * On restarting level preserves darkness even if the initial animation is - ; done again. - ; * Sun starts more at left per level. Since level 22 always starts barely - ; some pixels from left. - ; * Extra lives each 20000 points - - processor 6502 - - include aardm.asm - - ; - ; Set object in X - ; A = X position - ; First argument = Object to position (0=P0, 1=P1, 2=M0, 3=M1, 4=BALL) - ; - MAC set_x_position - sta WSYNC ; 0- Start line synchro - sec ; 2- Set carry flag (avoids it in loop) -.AE2: sbc #15 ; 4- Uses required time dividing A by 15 - bcs .AE2 ; 6/7 - 11/16/21/26/31/36/41/46/51/56/61/66 - tay ; 8 - lda fine_adjustment-$f1,y; 13 - Eats 5 cycles crossing page - sta HMP0+{1} - nop - sta RESP0+{1} ; 21/26/31/36/41/46/51/56/61/66/71 - "big" positioning - ENDM - - org $f000 ; ROM start address (4K) - - REPEAT 256 - .byte $4f - REPEND - -START: - sta bank1 ; Ghost - sei ; Disable interruptions - cld ; Disable decimal mode - jmp START2 - -ba0: sta bank0 - jmp 0 ; Ghost - - sta bank1 ; Ghost - jmp ba1 - -ba2: sta bank0 - jmp 0 ; Ghost - - sta bank1 - jmp ba3 - -START2: - ldy rand - ; Clean up the memory - ldx #$ff ; Load X with $FF... - txs ; ...copy to stack pointer - lda #0 ; Load zero in accumulator -AE1: sta 0,X ; Save in address 0 plus X - dex ; Decrement X - bne AE1 ; Repeat until X is zero. - sta SWACNT ; Allow to read joysticks - sta SWBCNT ; Allow to read buttons - tsx ; ldx #$ff - stx prev_button - sty rand - - lda rand - sta level_seed - -title_screen: - lda #20 - sta temp1 - jmp ba2 - -ba3: - lda #0 - sta antHill - lda #4 - sta lives - - lda #0 - sta score - sta score+1 - sta score+2 - - ldx #tongue_size*2-12 -aa124: lda #0 - sta tongue1+W,x - sta tongue1+W+1,x - sta tongue1+W+2,x - sta tongue1+W+3,x - sta tongue1+W+4,x - sta tongue1+W+5,x - txa - sec - sbc #12 - tax - bpl aa124 - - ; - ; Goes to next level - ; -next_level: - inc antHill - inc level_seed - - ; - ; Setup starting sun position - ; - lda antHill - asl - bmi aa82 - asl - bpl aa83 -aa82: lda #$80 -aa83: eor #$ff - adc #$98 - sta sun_pos - - lda #$00 - sta COLUBK ; Background color - - ; VERTICAL_SYNC - lda #2 - sta VSYNC ; Start vertical synchro - sta WSYNC ; Wait for 3 lines - sta WSYNC - sta WSYNC - ; - lda #43 - sta TIM64T - lda #0 - sta VSYNC ; Stop vertical synchro - - ldx #tongue_size*2-12 -aa29: lda #0 - sta tongue1+W,x - sta tongue1+W+1,x - sta tongue1+W+2,x - sta tongue1+W+3,x - sta tongue1+W+4,x - sta tongue1+W+5,x - cpx #0 - beq .+4 - lda #$aa - sta eggs1+W,x - sta eggs1+W+2,x - sta eggs1+W+3,x - sta eggs1+W+5,x - lsr - sta eggs1+W+1,x - sta eggs1+W+4,x - txa - sec - sbc #12 - tax - bpl aa29 - - lda #7*20 - sta eggs - - ; - ; Setup queen ants - ; - lda #sprite_queen_ant+ENEMY_DIR_MASK - sta enemy0_t - sta enemy8_t - lda #$2e - sta enemy0_x - lda #$66 - sta enemy8_x - - jmp aa73 - -restart_level: - inc level_seed - lda #$00 - sta effect0 - sta effect1 - sta ants_eaten - sta worms_eaten - sta COLUBK ; Background color - - ; VERTICAL_SYNC - lda #2 - sta VSYNC ; Start vertical synchro - sta WSYNC ; Wait for 3 lines - sta WSYNC - sta WSYNC - ; - lda #43 - sta TIM64T - lda #0 - sta VSYNC ; Stop vertical synchro - -aa73: - lda #1 ; Ranz des Vaches (Rossini) - sta tracker - lda #1 ; Start immediately - sta tracker_c - - lda #6 - sta aa_x_pos - lda #1 - sta timer - lda #0 - sta filling - sta flags - ; - ; Delete tongue and delete also any eggs under - ; - ldx #tongue_size*2-12 -aa69: - ldy #5 -aa80: lda tongue1+R,x - eor #$ff - and eggs1+R,x - sta eggs1+W,x - lda #0 - sta tongue1+W,x - inx - dey - bpl aa80 - txa - sec - sbc #18 - tax - bpl aa69 - - lda #0 - sta enemy1_t - sta enemy2_t - sta enemy3_t - sta enemy4_t - sta enemy5_t - sta enemy6_t - sta enemy7_t - sta enemy9_t - sta enemy10_t - sta enemy11_t - sta enemy12_t - sta enemy13_t - sta enemy14_t - sta enemy15_t - sta holeCols - sta holeCols+1 - sta holeCols+2 - sta holeCols+3 - sta holeCols+4 - sta holeCols+5 - sta holeCols+6 - sta holeCols+7 - lda #$ff - sta tip_y - jmp aa75 - -main_loop: - lda #$00 - sta COLUBK ; Background color - - ; VERTICAL_SYNC - lda #2 - sta VSYNC ; Start vertical synchro - sta WSYNC ; Wait for 3 lines - sta WSYNC - sta WSYNC - ; - lda #43 - sta TIM64T - lda #0 - sta VSYNC ; Stop vertical synchro - -aa75: - ; Nanochess' mini sound effects player - ldx tracker - bne ef4 - lda effect0 - beq ef0 - tax - lda sound_effect,x - bne ef1 - sta effect0 - beq ef0 - -ef1: sta AUDF0 - lda sound_effect+1,x - sta AUDC0 - lsr - lsr - lsr - lsr - inx - inx - stx effect0 - -ef0: sta AUDV0 - - lda effect1 - beq ef2 - tax - lda sound_effect,x - bne ef3 - sta effect1 - beq ef2 - -ef3: sta AUDF1 - lda sound_effect+1,x - sta AUDC1 - lsr - lsr - lsr - lsr - inx - inx - stx effect1 - -ef2: sta AUDV1 - bpl tr0 - - ; Nanochess' mini tracker -ef4: - ldx tracker - beq tr1 - dec tracker_c - bne tr3 - lda music-1,x - bne tr2 - sta tracker - beq tr1 - -tr2: and #$1f - asl - tay - lda music_notes-2,y - sta AUDC0 - lda music_notes-1,y - sta AUDF0 - lda music-1,x - lsr - lsr - and #$38 - sta tracker_c - lda music,x - asl - tay - lda music_notes-2,y - sta AUDC1 - lda music_notes-1,y - sta AUDF1 - inx - inx - stx tracker - lda #$3f - sta tracker_v -tr3: dec tracker_v - lda tracker_v - lsr - lsr - cpx #43 - bcs tr1 - lda tracker_v - and #$03 - bne tr4 - lda #$02 -tr4: ora #$0c -tr1: sta AUDV0 - sta AUDV1 -tr0: - - lda aa_x_pos - cmp #$0f ; Corrects left side X-pos, for some reason it breaks. - bcs *+4 - sbc #2 - set_x_position 0 ; Player 0 - ; ldx #1 ; Player 1 - lda sun_pos - set_x_position 1 ; Player 1 - lda #84 - set_x_position 2 ; Missile 0 - lda #$20 - sta NUSIZ0 - sta NUSIZ1 - - jsr build_hole_map - - lda #$00 - sta GRP0 - sta GRP1 - sta COLUPF - lda #$20 - sta CTRLPF - - jmp ba0 - -ba1: - - ; - ; Score zone - ; - sta WSYNC ; 0 - ldx #$00 ; 3 - stx COLUBK ; 5 Background color - stx GRP0 ; 8 - stx GRP1 ; 11 - stx REFP0 ; 14 - stx REFP1 ; 17 - sta en5 ; 20 - lda score ; 23 - and #$0f ; 26 - asl ; 28 - asl ; 30 - asl ; 32 - sta en4 ; 34 - lda score ; 37 - lsr ; 40 - and #$78 ; 42 - sta en3 ; 44 - lda #$21 ; 47 - sta CTRLPF ; 49 - lda #lives_color ; 52 - sta COLUPF ; 54 - ldx lives ; 57 - cpx #7 ; 60 - bcc aa88 ; 62 - ldx #7 ; 64 -aa88: - lda lives_pf,x ; 66 - sta WSYNC ; 71 - sta PF0 - lda lives_pf+8,x - sta PF1 - lda lives_pf+16,x - sta PF2 - lda score+1 ; 35 - and #$0f ; 38 - asl ; 40 - asl ; 42 - asl ; 44 - sta en2 ; 46 - lda score+1 ; 49 - lsr ; 52 - and #$78 ; 54 - sta en1 ; 56 - lda score+2 ; 59 - and #$0f ; 62 - asl ; 64 - asl ; 66 - asl ; 68 - sta en0 ; 70 - ldx #0 - - lda #score_color ; 73 - jmp $f400 ; 75 - org $F400 -mp0: - sta WSYNC - stx GRP0 - stx GRP1 - ldy #numbers>>8 ; 8 - sty en0+1 ; 11 - sty en1+1 ; 14 - sty en2+1 ; 17 - sty en3+1 ; 20 - sty en4+1 ; 23 - sty en5+1 ; 26 - - sta COLUP0 ; 29 - sta COLUP1 ; 32 - lda #$03 ; 35 3 copies together - ldx #$f0 ; 37 - stx RESP0 ; 39 - stx RESP1 ; 42 - stx HMP0 ; 45 - sta NUSIZ0 ; 48 - sta NUSIZ1 ; 51 - lsr ; 53 - sta VDELP0 ; 56 - sta VDELP1 ; 59 - lsr - sta HMP1 - sta WSYNC ; 62 - sta HMOVE ; 3 - lda #4 - sta temp2 -mp1: ldy temp2 ; 2 - lda (en0),y ; 7 - sta GRP0 ; 10 - sta WSYNC ; 13 + 61 = 76 - lda (en1),y ; 5 - sta GRP1 ; 8 - lda (en2),y ; 13 - sta GRP0 ; 16 - lda (en3),y ; 21 - sta temp1 ; 24 Write (this depends on being at "root" stack pos) - lda (en4),y ; 29 (and of course not being called) - tax ; 31 - lda (en5),y ; 36 - tay ; 38 - lda temp1 ; 41 Read - sta GRP1 ; 44 - stx GRP0 ; 47 - sty GRP1 ; 50 - sta GRP0 ; 53 - dec temp2 ; 58 - bpl mp1 ; 60/61 -mp3: - ; Looks for code spanning page - if (mp1&$ff00)!=(mp3&$ff00) - lda megabug3 ; :P - endif - echo "mp0 ",mp0," mp1 ",mp1," mp3 ",mp3 - - ; - ; End of graphics (204 lines) - ; - ldx #$00 - lda #2 - sta WSYNC - sta VBLANK - stx VDELP0 - stx VDELP1 - stx GRP0 - stx GRP1 - stx PF0 - stx PF1 - stx PF2 - - ; - ; Start overscan timer - ; - lda #43 ; 37 lines * 76 = 2812 cycles / 64 = 43.9375 - sta TIM64T - - lda flags - and #$03 - cmp #$02 ; Tongue touched? - bne aa67 - jmp wait_overscan - -aa67: lda eggs - bne aa70 - ldx aa_x_pos - cpx #52 - bne aa71 - inc aa_x_pos - lda #43 ; Mountain King (Grieg) - sta tracker - lda #1 - sta tracker_c - lda #0 - sta filling - sta flags - ldx #tongue_size*2-1 - lda #0 -aa72: sta tongue1+W,x - dex - bpl aa72 - - sta enemy0_t - sta enemy1_t - sta enemy2_t - sta enemy3_t - sta enemy4_t - sta enemy5_t - sta enemy6_t - sta enemy7_t - sta enemy8_t - sta enemy9_t - sta enemy10_t - sta enemy11_t - sta enemy12_t - sta enemy13_t - sta enemy14_t - sta enemy15_t - sta holeCols - sta holeCols+1 - sta holeCols+2 - sta holeCols+3 - sta holeCols+4 - sta holeCols+5 - sta holeCols+6 - sta holeCols+7 - lda #$ff - sta tip_y -aa71: jmp aa34 - -aa70: lda flags - and #$fc - sta flags - - ; - ; Check for collisions of enemies versus tongue (playfield pixels) - ; - ldx #15 -aa53: lda enemy0_t,x - tay - cmp #non_interactive_sprites - bcc aa86 - cpx #8 - bcs aa45 - lda cxLst,x - and #$20 - beq aa86 ; No, jump - bne aa127 - -aa45: lda cxLst-8,x - asl - bpl aa86 - -aa127: tya - and #$f0 - cmp #sprite_spider - beq aa106 - cmp #sprite_worm ; Is it a worm? - beq aa55 - bne aa87 - -aa86: - dex - bpl aa53 - jmp aa78 - - ; - ; Spider - ; * Kills if touches tongue tip - ; -aa106: - txa - and #$07 - cmp tip_y ; Is it at same level than tongue? - bne aa86 ; No, jumps - lda enemy0_x,x - tay - sbc #3 - lsr - lsr - cmp tip_x - beq aa56sc - tya - clc - adc #10 - lsr - lsr - cmp tip_x - beq aa56sc - bne aa86 - -aa87: - ; - ; Ant: - ; * Eaten if tongue tip. - ; * Kills if it touch any other part of tongue. - ; - txa - and #$07 - cmp tip_y ; Is it at same level than tongue? - bne aa56sc ; No, kills - lda enemy0_x,x - sbc #3 - tay - lsr - lsr - cmp tip_x - beq aa57 - bcs aa56 - tya - clc - adc #10 - lsr - lsr - cmp tip_x - beq aa57 - bcc aa56 - -aa57: lda enemy0_t,x - cmp #sprite_queen_ant+$20 - bcs aa125 - cmp #sprite_queen_ant - bcs aa59 -aa125: cmp #pricey_sprites ; Red ant and caterpillar - bcs aa97 - sed - lda ants_eaten - adc #1 - sta ants_eaten - cld - lda #sprite_explosion; Goodbye ant - .byte $2c ; BIT opcode to jump -aa97: lda #sprite_150 - ldy #11 - bne aa79 - -aa56sc: jmp aa56 - -aa59: jsr clear_enemies - ldy #33 -aa79: sty effect1 - bne aa60 - - ; - ; Worm: - ; * Eaten if tongue tip from behind. - ; * Kills only if tongue tip in front. - ; -aa55: txa - and #$07 - cmp tip_y - bne aa54 - lda enemy0_x,x - tay - sbc #3 - lsr - lsr - cmp tip_x - beq aa58 - bcs aa54 - tya - clc - adc #10 - lsr - lsr - cmp tip_x - beq aa58 - bcc aa54 -aa58: lda tip_dir - beq aa56 - lsr ; $ff left $00 right - eor enemy0_t,x - and #ENEMY_SPEED_MASK - bne aa56 - lda flags - and #~FLAGS_WORM - sta flags - inc worms_eaten - lda #20 - sta effect1 - lda #sprite_200 ; 200 points -aa60: sta enemy0_t,x - bne aa54 - - ; Kill -aa56: lda flags - and #$fc - ora #$01 - sta flags - -aa54: - dex - bmi aa78 - jmp aa53 -aa78: - - lda flags - and #$03 - beq aa52 - jmp wait_overscan - - ; - ; Invoke an enemy - ; -aa52: - dec timer - beq aa95 - jmp aa14 -aa95: - jsr random_proc ; Get a random number (just because :P) - tay ; Save it - and #$0e ; Restart timer - ora #$01 - sta timer - lda antHill ; Starts at 1 - clc - adc #$03 ; Level 1 - fills 4 tunnels, 2 - 5 t., 4 and so- 6 t. - cmp #$06 ; No more than 6 tunnels - bcc aa92 - lda #$06 -aa92: asl - sta temp1 - lda filling - cmp temp1 - bcc aa102 -aa103: jmp aa8 -aa102: - and #$0e - lsr - eor #$07 - tax - cmp #$07 - bne aa111 - lda enemy8_t,x - bne aa111 - lda #FLAGS_SPIDER - bit flags - bne aa111 - lda sun_pos - cmp #8 ; Now it's night? - beq aa110 ; No, jump -aa111: lda enemy0_t,x ; There is space for a common enemy? - beq aa12 ; Yep, jump. -aa110: lda enemy8_t,x ; There is space for a worm/spider? - bne aa103 ; No, jump - cpx #0 ; Top tunnel? - bne aa101 ; No, jump - lda sun_pos - cmp #8 ; Now it's night? - bne aa101 ; No, jump - lda #FLAGS_SPIDER - bit flags ; We have already the spider? - bne aa101 ; Yes, jump - ora flags - sta flags - lda #ENEMY_MAX_X - sta enemy8_x,x - tya - and #ENEMY_SPEED_MASK - ora #sprite_spider - sta enemy8_t,x - bne aa8 - -aa101: - txa - and #$07 - cmp tip_y - bne aa103 - lda #FLAGS_WORM - bit flags ; Already a worm in screen? - bne aa8 ; Yes, jump - ora flags - sta flags - tya - and #$40 - beq aa37 - lda enemy0_x,x - cmp #40 - bcc aa90 -aa91: lda #ENEMY_MIN_X - sta enemy8_x,x - tya - and #ENEMY_SPEED_MASK - ora #sprite_worm+ENEMY_DIR_MASK - sta enemy8_t,x - bne aa8 - -aa37: lda enemy0_x,x - cmp #129 - bcs aa91 -aa90: lda #ENEMY_MAX_X - sta enemy8_x,x - tya - and #ENEMY_SPEED_MASK - ora #sprite_worm - sta enemy8_t,x - bne aa8 - -aa12: tya - and #$40 - beq aa15 - lda #ENEMY_MIN_X - sta enemy0_x,x - tya - and #ENEMY_SPEED_MASK - ora enemies_going_right,x - sta enemy0_t,x - bne aa8 - -aa15: lda #ENEMY_MAX_X - sta enemy0_x,x - tya - and #ENEMY_SPEED_MASK - ora enemies_going_left,x - sta enemy0_t,x - ; bne aa8 - -aa8: ldx antHill - cpx #32 - bcc aa93 - ldx #31 -aa93: lda filling - clc - adc #2 - cmp refilling,x - bne aa94 - lda #0 -aa94: sta filling -aa14: - - ; - ; Sun animation - ; - lda frame - and #$1f ; Each 32 frames - bne aa81 - lda sun_pos - cmp #8 - beq aa81 - dec sun_pos ; Move sun left by one pixel - cmp #9 - bne aa81 - lda #129 ; Click effect - sta effect0 -aa81: - - ; - ; Enemy animation and movement - ; - ldy #0 - lda frame - and #$07 ; Enemies change animation frame each 8 frames - bne aa11 - ldy #8 -aa11: and #$03 ; Enemies move each 4 frame - beq aa117 - jmp aa43 -aa117: - ldx #$0f -aa10: - lda enemy0_t,x ; Active enemy? - bne aa118 ; Yes, jump -aa120: dex - bpl aa10 - jmp aa43 - - ; - ; Check first for brief sprites (explosion, 150 and 200 points) - ; -aa118: cmp #non_interactive_sprites - bcs aa39 -aa49: inc enemy0_t,x - cmp #sprite_150+$03 - beq aa96 - cmp #sprite_200+$03 - beq aa46 - cmp #sprite_200_spider+$03 - beq aa46 - cmp #sprite_explosion+$03 - bne aa38sd - lda #$10 ; 100 points - .byte $2c ; BIT opcode to jump -aa46: lda #$20 ; 200 points - .byte $2c ; BIT opcode to jump -aa96: lda #$15 ; 150 points - jsr score_points - lda #$00 - sta enemy0_t,x -aa38sd: jmp aa38 - ; - ; All other sprites - ; -aa39: and #$f0 - cmp #sprite_spider - bne aa108 - ; - ; Spider handling - ; - lda tip_y ; Tongue tip active? - bmi aa120 ; No, jump (spider stays quiet) - txa ; Get vertical position of spider - and #$07 - cmp tip_y ; Comparison with tongue tip vertical position. - beq aa109 ; Same vertical position? yes, jump - bcs aa120 ; Jump if spider deeper than tongue tip. It shouldn't happen - stx temp1 - tax - lda holeCols,x ; Check if tongue goes thru a hole !!! - lsr - bcs aa112 - lsr - bcs aa113 - lsr - bcs aa114 - lda #0 - .byte $2c ; BIT opcode to jump -aa114: lda #8 - .byte $2c ; BIT opcode to jump -aa113: lda #16 - .byte $2c ; BIT opcode to jump -aa112: lda #24 - clc - adc kernelLst,x - tax - lda hole_pos,x ; Now get the X-coordinate for hole - ldx temp1 - sec ; There's an X-coordinate, center spider over it - sbc #2 - jmp aa116 - - ; - ; Spider at same level than tongue tip - ; -aa109: lda tip_x - asl - asl - beq aa116 - sbc #1 -aa116: sbc enemy0_x,x ; Take a decision of direction to move - beq aa119 ; At target position? yes, jump - bcc aa44 - bcs aa40 - - ; - ; Try to lower spider by one level - ; -aa119: cpx #1 ; Is spider at bottom-most position? - beq aa41 ; Yes, jump, stay quiet - cpx #9 - beq aa41 - lda enemy0_t-1,x ; Is it busy the next enemy slot? - bne aa41 ; Yes, jump, stay quiet - lda enemy0_x,x ; Copy X position - sta enemy0_x-1,x - lda enemy0_t,x ; Copy type - sta enemy0_t-1,x - lda #0 ; Erase spider from old slot - sta enemy0_t,x - beq aa41 - - ; - ; Ant, red ant, worm or centipede - ; -aa108: - cmp #sprite_queen_ant - beq aa38 - cmp #sprite_queen_ant+$10 - beq aa38 - lda enemy0_t,x - and #ENEMY_SPEED_MASK; Fast? - beq aa44 - lda frame - and #$04 -aa38sc: bne aa38 -aa44: - lda enemy0_t,x - and #ENEMY_DIR_MASK ; Goes to left? - bne aa40 ; No, jump - dec enemy0_x,x - lda enemy0_x,x - cmp #ENEMY_MIN_X ; Reached left limit? - bne aa41 ; No, jump -aa42: - lda enemy0_t,x - and #$f0 - cmp #sprite_worm - bne aa98 - lda flags - and #~FLAGS_WORM - sta flags -aa98: cmp #sprite_spider ; It could happen *sigh* - bne aa107 - lda flags - and #~FLAGS_SPIDER - sta flags -aa107: lda #0 - sta enemy0_t,x - beq aa38 - -aa40: - inc enemy0_x,x - lda enemy0_x,x - cmp #ENEMY_MAX_X ; Reached right limit? - beq aa42 ; Yes, jump -aa41: - tya - eor enemy0_t,x ; Changed animation frame if required - sta enemy0_t,x -aa38: dex - bmi aa43 - jmp aa10 -aa43: - - ; - ; Queen ant flashing - ; - lda frame - and #$01 - bne aa34 - lda enemy0_t - beq aa32 - cmp #non_interactive_sprites - bcs aa51 - adc #1 - cmp #sprite_1000+8 - bne aa32 - jsr score_points_2 ; 1000 points - lda #0 - beq aa32 - -aa51: adc #$07 - cmp #sprite_queen_ant+$20 - bcc aa32 - sbc #$20 -aa32: sta enemy0_t - - lda enemy8_t - beq aa33 - cmp #non_interactive_sprites - bcs aa50 - adc #1 - cmp #sprite_1000+8 - bne aa33 - jsr score_points_2 ; 1000 points - lda #0 - beq aa33 - -aa50: adc #$07 - cmp #sprite_queen_ant+$20 - bcc aa33 - sbc #$20 -aa33: sta enemy8_t -aa34: - ; - ; Count frame, step on random generator - ; - inc frame - jsr random_proc - ; - ; Aardvark enters game - ; - ldx aa_x_pos - cpx #52 - beq aa7 - lda frame - and #$07 - bne aa31 - inc aa_x_pos - cpx #51 - bne aa31 - ; Start tongue - lda #$02 - sta holeCols+7 - ldx #19 - stx tip_x - lda #7 - sta tip_y - lda #0 - sta tip_dir - jsr point_egg - ldx tip_x - lda tip_y - jsr draw_block -aa31: - lda frame - and #$07 - bne aa4 - lda aa_offset - eor #$28 - sta aa_offset -aa4: - jmp aa20 - -aa7: - lda #0 - - jsr fire_button ; Fire button pressed? - bpl aa22 ; No, jump - - ldx tip_x ; Get tongue coordinates - lda tip_y - cpx #19 - bne aa19 - cmp #7 - beq aa123 ; Is it at base? yes, jump without doing anything -aa19: - jsr clear_block - lda effect0 - cmp #128 - bcs aa122 - cmp #66 - bcs aa121 -aa122: - lda #66 - sta effect0 -aa121: ldx tip_x - beq aa23 - dex - lda tip_y - jsr check_block - bne aa24 - inx - -aa23: cpx #39 - beq aa25 - inx - lda tip_y - jsr check_block - bne aa24 - -aa25: ldx tip_y - lda #$00 - sta holeCols,x - inc tip_y - jmp aa20 - -aa24: stx tip_x - jmp aa20 - -aa123: jmp aa28 - -aa22: - jsr build_hole_map - lda SWCHA - ; Note #$10 isn't used (going up) - and #$20 ; Going down? - beq aa17 ; Yes, jump -aa18: lda SWCHA - bmi aa16 ; Going right? No, jump - lda tip_y - bmi aa28 - beq aa28 ; Last tunnel? Yes, cannot move - lda frame - lsr - bcc aa28 - ldx tip_x - cpx #39 - beq aa28 - inx -aa26: lda tip_y - jsr check_block - bne aa30 - txa - sec - sbc tip_x - sta tip_dir - stx tip_x - lda tip_y - jsr point_egg - ldx tip_x - lda tip_y - jsr draw_block - jmp aa20 - -aa30: txa - pha - ldx tip_x - lda tip_y - jsr clear_block - pla - sta tip_x -aa28: jmp aa20 - -aa16: rol ; Going left? - bmi aa20 - lda tip_y - bmi aa20 - beq aa20 ; Last tunnel? Yes, cannot move - lda frame - lsr - bcc aa20 - ldx tip_x - beq aa20 - dex - bpl aa26 - - ; - ; Going down - ; -aa17: ldx tip_y ; Get row of tongue tip - bmi aa18 ; Invalid? Yes, jump to check for right/left - beq aa18 ; Vertical limit? Yes, jump to check for right/left - lda kernelLst-1,x - tax - lda tip_x ; Tongue tip at 0? - beq aa18 ; Jump to check for right/left - cmp hole_pos,x - beq aa126 - cmp hole_pos+8,x - beq aa27 - cmp hole_pos+16,x - beq aa115 - cmp hole_pos+24,x - bne aa18 ; No hole, so jump to check for right/left - ldy #$01 - .byte $2c ; BIT opcode to jump -aa115: ldy #$02 - .byte $2c ; BIT opcode to jump -aa126: ldy #$08 - .byte $2c ; BIT opcode to jump -aa27: ldy #$04 - tya - ldx tip_y - dex - ora holeCols,x - sta holeCols,x - stx tip_y - txa - ldx tip_x - jsr point_egg - ldx tip_x - lda tip_y - jsr draw_block - lda #0 - sta tip_dir - -aa20: - -wait_overscan: - lda INTIM - bne wait_overscan - sta WSYNC - sta WSYNC - - lda aa_x_pos - cpx #135 - bne aa74 - jsr bonus_screen - jmp next_level -aa74: - - lda flags - and #$03 - cmp #$02 ; Has finished tongue color changing animation? - beq aa68 ; Yes, jump - jmp main_loop ; Continue with main loop - -aa68: dec lives - jsr bonus_screen - lda lives - bmi aa89 - jmp restart_level ; Restart level - -aa89: jmp title_screen - - ; - ; Bonus screen - ; -bonus_screen: - ldx worms_eaten - beq aa99 -aa100: - lda ants_eaten - jsr score_points - dex - bne aa100 -aa99: - rts - - ; - ; Run random number generator - ; -random_proc: - ; - ; Random number generator - ; - lda rand - sec - ror - eor frame - ror - eor rand - ror - eor #9 - sta rand - rts - - ; - ; Check for fire button - ; -fire_button_single: - lda INPT4 - eor #$ff - tax - eor prev_button - stx prev_button - bpl fire_button1 - txa -fire_button1: - rts - -fire_button: - lda INPT4 - eor #$ff - sta prev_button - rts - - ; - ; Calculate memory zone for tongue block - ; a = zone (0-7) - ; -calc_zone: - asl ; x2 - asl ; x4 - sta en0 - asl ; x8 - adc en0 ; x12 - adc #tongue1 - sta en0 - adc #W - sta en0+1 - sta en1+1 - rts - - ; - ; Check for tongue block - ; - ; a = zone (0-5) - ; x = x pixel (0-39) - ; -check_block: - jsr calc_zone - lda pixel_to_byte,x - tay - lda (en1),y - and pixel_to_bit,x - rts - - ; - ; Clear enemies (used when eating queen ant) - ; -clear_enemies: - txa - pha - ldx #9 -aa61: lda enemy0_t,x - cmp #non_interactive_sprites - bcc aa62 - and #$f0 - cmp #sprite_worm - beq aa63 - cmp #sprite_spider - beq aa104 - cmp #pricey_sprites - bcs aa64 - lda #sprite_explosion - .byte $2c ; BIT opcode to jump -aa63: lda #sprite_200 - .byte $2c ; BIT opcode to jump -aa64: lda #sprite_150 - .byte $2c ; BIT opcode to jump -aa104: lda #sprite_200_spider - sta enemy0_t,x - cmp #sprite_200_spider - bne aa105 - lda flags - and #~FLAGS_SPIDER - sta flags -aa105: - cmp #sprite_200 ; Only a worm gives a 200 points bonus - bne aa62 - lda flags - and #~FLAGS_WORM - sta flags -aa62: dex - bpl aa61 - pla - tax - lda #sprite_1000 - rts - - ; - ; Give points per egg eaten - ; - ; a = zone (0-7) - ; x = x pixel (0-39) - ; -point_egg: - cmp #0 - beq aa35 - jsr calc_zone - lda en1 - clc - adc #tongue_to_eggs - sta en1 - lda pixel_to_byte,x - tay - lda (en1),y - and pixel_to_bit,x - beq aa35 - lda eggs - ror - lda #1 - bcc aa77 - lda #6 -aa77: sta effect0 - dec eggs - lda #1 - - ; Score 1 point for egg eaten -score_points: - clc - sed - adc score - sta score -aa48: lda score+1 - adc #0 - sta score+1 - lda score+2 - adc #0 - sta score+2 - cld -aa35: - rts - -score_points_2: - sec - sed - bcs aa48 - - ; - ; Draw a tongue block - ; - ; a = zone (0-7) - ; x = x pixel (0-39) - ; -draw_block: - jsr calc_zone - lda pixel_to_byte,x - tay - lda (en1),y - ora pixel_to_bit,x - sta (en0),y - lda en0 - clc - adc #tongue_to_eggs - sta en0 - lda en1 - adc #tongue_to_eggs - sta en1 - lda (en1),y - ora pixel_to_bit,x - sta (en0),y - rts - - ; - ; Clear a tongue block - ; - ; a = zone (0-7) - ; x = x pixel (0-39) - ; -clear_block: - jsr calc_zone - lda pixel_to_byte,x - tay - lda (en1),y - and pixel_to_bit2,x - sta (en0),y - lda en0 - clc - adc #tongue_to_eggs - sta en0 - lda en1 - adc #tongue_to_eggs - sta en1 - lda (en1),y - and pixel_to_bit2,x - sta (en0),y - rts - - ; - ; Build random hole map for the current level seed - ; See also random.c - ; -build_hole_map: SUBROUTINE -.lastPat = tmpVars - lda #255 - sta .lastPat - ldy #NUM_FLOORS-1 - ldx level_seed -.0: - lda random_level,x - tax - and #$07 - cmp .lastPat - bne .1 - txa - lsr - lsr - tax - and #$07 -.1: - sta kernelLst,y - sta .lastPat - dey - bne .0 - sty kernelLst ; Fixed tunnel for queen ants - rts - - ; - ; With the help of: - ; - ; http://alienbill.com/2600/basic/music/tune2600.html - ; http://piano-player.info/ - ; - - ; - ; Songs refer to these notes. - ; These notes contain frequency and "instrument" and are - ; choosen per usage in song instead of full "continuous" octaves - ; -music_notes: - .byte 12,12 ; 1 - .byte 4,28 - .byte 4,25 ; 3 - .byte 4,22 - .byte 4,18 ; 5 - .byte 4,16 - - .byte 12,20 ; 7 - .byte 12,19 - .byte 12,18 ; 9 - .byte 12,17 - .byte 12,15 ; 11 - .byte 12,14 - .byte 12,13 ; 13 - .byte 12,11 - .byte 4,31 ; 15 - - .byte 6,7 ; 16 - .byte 6,6 ; 17 - .byte 12,27 ; 18 - .byte 12,23 ; 19 - - .byte 0,0 ; 20 Unused - - .byte 6,7 ; 21 - .byte 12,30 - .byte 12,27 ; 23 - .byte 12,24 - .byte 12,20 ; 25 - .byte 12,18 - - .byte 0,0 ; 27 Unused - .byte 1,12 ; 29 - .byte 1,6 ; 31 - .byte 1,13 ; 33 - .byte 1,9 ; 35 - .byte 0,0 - - ; - ; Global label to access music - ; -music: - - ; - ; Ranz des vaches - ; -music_ranz_des_vaches: - .byte 6*32+2,22 ; 1 -> tracker - .byte 1*32+3,23 - .byte 1*32+1,21 - .byte 1*32+2,22 - .byte 1*32+4,24 - .byte 1*32+1,21 - - .byte 6*32+2,22 - .byte 1*32+3,23 - .byte 1*32+1,21 - .byte 1*32+2,22 - .byte 1*32+4,24 - .byte 1*32+1,21 - - .byte 6*32+2,22 - .byte 1*32+4,24 - .byte 1*32+6,26 - .byte 1*32+5,25 - .byte 1*32+1,21 - .byte 1*32+4,24 - - .byte 5*32+3,23 - .byte 1*32+5,25 - - .byte 0,0 - - ; - ; Mountain king - ; -music_mountain_king: - .byte 2*32+7,16 ; 43 -> tracker - .byte 2*32+9,16 - .byte 2*32+10,18 - .byte 2*32+11,18 - .byte 2*32+13,16 - .byte 2*32+10,16 - .byte 4*32+13,18 - - .byte 2*32+12,16 - .byte 2*32+9,16 - .byte 4*32+12,18 - .byte 2*32+11,16 - .byte 2*32+8,16 - .byte 4*32+11,18 - - .byte 2*32+7,16 - .byte 2*32+9,16 - .byte 2*32+10,18 - .byte 2*32+11,18 - .byte 2*32+13,16 - .byte 2*32+10,16 - .byte 2*32+13,18 - .byte 2*32+15,18 - - .byte 2*32+14,17 - .byte 2*32+13,17 - .byte 2*32+10,19 - .byte 2*32+13,19 - .byte 7*32+14,17 - - .byte 0,0 - - ; - ; Death music - ; -music_touch: - .byte 4*32+28,28 ; 97 -> tracker - .byte 4*32+29,29 - .byte 4*32+30,30 - .byte 7*32+31,31 - .byte 0,0 - - ; - ; Global label to access sound effects - ; -sound_effect: - .byte 0 - - .byte $04,$81 ; 1 Eating egg (1) - .byte $03,$71 ; 3 - .byte 0 ; 5 - - .byte $08,$81 ; 6 Eating egg (2) - .byte $07,$71 ; 8 - .byte 0 ; 10 - - .byte $07,$88 ; 11 Eating bug - .byte $06,$88 ; 13 - .byte $07,$88 ; 15 - .byte $06,$88 ; 17 - .byte 0 ; 19 - - .byte $1c,$fc ; 20 Eating worm - .byte $1c,$cc ; 22 - .byte $1c,$ac ; 24 - .byte $1c,$8c ; 26 - .byte $1c,$6c ; 28 - .byte $1c,$4c ; 30 - .byte 0 ; 32 - - .byte $1c,$fc ; 33 Eating queen - .byte $1c,$cc ; 35 - .byte $1c,$ac ; 37 - .byte $1c,$8c ; 39 - .byte $1c,$6c ; 41 - .byte $1c,$4c ; 43 - .byte $10,$ec ; 45 - .byte $10,$cc ; 47 - .byte $10,$ac ; 49 - .byte $10,$6c ; 51 - .byte $10,$4c ; 53 - .byte $10,$3c ; 55 - .byte $10,$4c ; 57 - .byte $10,$3c ; 59 - .byte $10,$4c ; 61 - .byte $10,$3c ; 63 - .byte 0 ; 65 - - .byte $1f,$c4 ; 66 Retrain tongue - .byte $1e,$b4 ; 68 - .byte $1d,$c4 ; 70 - .byte $1c,$b4 ; 72 - .byte $1b,$c4 ; 74 - .byte $1a,$b4 ; 76 - .byte $19,$c4 ; 78 - .byte $18,$b4 ; 80 - .byte $17,$c4 ; 82 - .byte $16,$b4 ; 84 - .byte $15,$c4 ; 86 - .byte $14,$b4 ; 88 - .byte $13,$c4 ; 90 - .byte $12,$b4 ; 92 - .byte $11,$c4 ; 94 - .byte $10,$b4 ; 96 - .byte $0f,$c4 ; 98 - .byte $0e,$b4 ; 100 - .byte $0d,$c4 ; 102 - .byte $0c,$b4 ; 104 - .byte $0b,$c4 ; 106 - .byte $0a,$b4 ; 108 - .byte $09,$c4 ; 110 - .byte $08,$b4 ; 112 - .byte $07,$c4 ; 114 - .byte $06,$b4 ; 116 - .byte $05,$c4 ; 118 - .byte $04,$b4 ; 120 - .byte $03,$c4 ; 122 - .byte $02,$b4 ; 124 - .byte $01,$c4 ; 126 - .byte 0 - - .byte $18,$c1 ; 129 Click effect for sunset - .byte $0c,$61 ; 131 - .byte $06,$a1 ; 133 - .byte $03,$41 ; 135 - .byte $02,$81 ; 137 - .byte $01,$21 ; 139 - .byte 0 - - echo "Before random_level at $fd00: ",* - - org $fd00 - - .include "aardlev.asm" - - org $fe00 -fine_adjustment: - .byte $70 ; -7 - .byte $60 ; -6 - .byte $50 ; -5 - .byte $40 ; -4 - .byte $30 ; -3 - .byte $20 ; -2 - .byte $10 ; -1 - .byte $00 ; 0 - .byte $f0 ; +1 - .byte $e0 ; +2 - .byte $d0 ; +3 - .byte $c0 ; +4 - .byte $b0 ; +5 - .byte $a0 ; +6 - .byte $90 ; +7 - -pixel_to_byte: - .byte 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2 - .byte 3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5 - -pixel_to_bit: - .byte $10,$20,$40,$80 - .byte $80,$40,$20,$10,$08,$04,$02,$01 - .byte $01,$02,$04,$08,$10,$20,$40,$80 - - .byte $10,$20,$40,$80 - .byte $80,$40,$20,$10,$08,$04,$02,$01 - .byte $01,$02,$04,$08,$10,$20,$40,$80 - -pixel_to_bit2: - .byte $ef,$df,$bf,$7f - .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe - .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f - - .byte $ef,$df,$bf,$7f - .byte $7f,$bf,$df,$ef,$f7,$fb,$fd,$fe - .byte $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f - - ; - ; Position for holes (in "fat" pixels) - ; Note vertical sorting, one line of holes is made from one column of data. - ; A B C D E F G H - ; -hole_pos: - .byte 0, 6, 3, 0, 0, 0, 0, 0 - .byte 12,12, 9, 6, 9, 3, 0,15 - .byte 26,18,20,26,23,15,18,23 - .byte 0,32,35,32, 0,29,29,35 - - ; - ; Lives representation as playfield graphics - ; -lives_pf: - .byte $00,$40,$40,$40,$40,$40,$40,$40 - .byte $00,$00,$80,$a0,$a8,$aa,$aa,$aa - .byte $00,$00,$00,$00,$00,$00,$01,$05 - - ; - ; Refilling constant per level - ; -refilling: - .byte 128,126,124,122,120,118,116,114 - .byte 112,110,108,106,104,102,100,98 - .byte 96,94,92,90,88,86,84,82 - .byte 80,78,76,74,72,70,68,66 - - ; - ; Enemies per tunnel - ; -enemies_going_right: - .byte 0 - .byte 0 - .byte sprite_caterpillar+ENEMY_DIR_MASK - .byte sprite_red_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte 0 - .byte 0 - .byte sprite_caterpillar+ENEMY_DIR_MASK - .byte sprite_red_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - .byte sprite_ant+ENEMY_DIR_MASK - -enemies_going_left: - .byte 0 - .byte 0 - .byte sprite_caterpillar - .byte sprite_red_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - .byte 0 - .byte 0 - .byte sprite_caterpillar - .byte sprite_red_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - .byte sprite_ant - - org $ff00 -numbers: - .byte $fe,$c6,$c6,$c6,$fe,$00,$00,$00 - .byte $78,$30,$30,$70,$30,$00,$00,$00 - .byte $fe,$c0,$fe,$06,$fe,$00,$00,$00 - .byte $fe,$06,$fe,$06,$fe,$00,$00,$00 - .byte $06,$06,$fe,$c6,$c6,$00,$00,$00 - .byte $fe,$06,$fe,$c0,$fe,$00,$00,$00 - .byte $fe,$c6,$fe,$c0,$fe,$00,$00,$00 - .byte $18,$18,$0c,$06,$fe,$00,$00,$00 - .byte $fe,$c6,$fe,$c6,$fe,$00,$00,$00 - .byte $fe,$06,$fe,$c6,$fe,$00,$00,$00 - - org $fffc - .word START ; RESET - .word START ; BRK - diff --git a/pretty6502.c b/pretty6502.c index 69c46bd..02ae2d1 100644 --- a/pretty6502.c +++ b/pretty6502.c @@ -6,6 +6,7 @@ ** © Copyright 2017 Oscar Toledo G. ** ** Creation date: Nov/03/2017. +** Revision date: Nov/06/2017. Processor selection. Indents nested IF/ENDIF. Tries to preserve vertical structure of comments. Allows label in its own line. */ #include @@ -13,9 +14,113 @@ #include #include -#define VERSION "v0.1" +#define VERSION "v0.2" int tabs; +/* +** 6502 mnemonics +*/ +char *mnemonics_6502[] = { + "adc", "anc", "and", "ane", "arr", "asl", "asr", "bcc", + "bcs", "beq", "bit", "bmi", "bne", "bpl", "brk", "bvc", + "bvs", "clc", "cld", "cli", "clv", "cmp", "cpx", "cpy", + "dcp", "dec", "dex", "dey", "eor", "inc", "inx", "iny", + "isb", "jmp", "jsr", "las", "lax", "lda", "ldx", "ldy", + "lsr", "lxa", "nop", "ora", "pha", "php", "pla", "plp", + "rla", "rol", "ror", "rra", "rti", "rts", "sax", "sbc", + "sbx", "sec", "sed", "sei", "sha", "shs", "shx", "shy", + "slo", "sre", "sta", "stx", "sty", "tax", "tay", "tsx", + "txa", "txs", "tya", NULL, +}; + +#define DONT_RELOCATE_LABEL 0x01 +#define LEVEL_IN 0x02 +#define LEVEL_OUT 0x04 +#define LEVEL_MINUS 0x08 + +/* +** DASM directives +*/ +struct { + char *directive; + int flags; +} directives_dasm[] = { + "=", DONT_RELOCATE_LABEL, + "align", 0, + "byte", 0, + "dc", 0, + "ds", 0, + "dv", 0, + "echo", 0, + "eif", LEVEL_OUT, + "else", LEVEL_MINUS, + "end", 0, + "endif", LEVEL_OUT, + "endm", LEVEL_OUT, + "eqm", DONT_RELOCATE_LABEL, + "equ", DONT_RELOCATE_LABEL, + "err", 0, + "hex", 0, + "if", LEVEL_IN, + "ifconst", LEVEL_IN, + "ifnconst", LEVEL_IN, + "incbin", 0, + "incdir", 0, + "include", 0, + "list", 0, + "long", 0, + "mac", LEVEL_IN, + "mexit", 0, + "org", 0, + "processor", 0, + "rend", 0, + "repeat", LEVEL_IN, + "repend", LEVEL_OUT, + "rorg", 0, + "seg", 0, + "set", DONT_RELOCATE_LABEL, + "subroutine", DONT_RELOCATE_LABEL, + "trace", 0, + "word", 0, + NULL, 0, +}; + +/* +** Comparison without case +*/ +int memcmpcase(char *p1, char *p2, int size) +{ + while (size--) { + if (tolower(*p1) != tolower(*p2)) + return 1; + p1++; + p2++; + } + return 0; +} + +/* +** Check for opcode or directive +*/ +int check_opcode(char *p1, char *p2) +{ + int c; + int length; + + for (c = 0; directives_dasm[c].directive != NULL; c++) { + length = strlen(directives_dasm[c].directive); + if ((*p1 == '.' && length == p2 - p1 - 1 && memcmpcase(p1 + 1, directives_dasm[c].directive, p2 - p1 - 1) == 0) || (length == p2 - p1 && memcmpcase(p1, directives_dasm[c].directive, p2 - p1) == 0)) { + return c + 1; + } + } + for (c = 0; mnemonics_6502[c] != NULL; c++) { + length = strlen(mnemonics_6502[c]); + if (length == p2 - p1 && memcmpcase(p1, mnemonics_6502[c], p2 - p1) == 0) + return -(c + 1); + } + return 0; +} + /* ** Request space in line */ @@ -55,10 +160,13 @@ int main(int argc, char *argv[]) { int c; int style; + int processor; int start_mnemonic; int start_operand; int start_comment; int align_comment; + int nesting_space; + int labels_own_line; FILE *input; FILE *output; int allocation; @@ -68,6 +176,10 @@ int main(int argc, char *argv[]) char *p2; int current_column; int request; + int current_level; + int prev_comment_original_location; + int prev_comment_final_location; + int flags; /* ** Show usage if less than 3 arguments (program name counts as one) @@ -87,6 +199,8 @@ int main(int argc, char *argv[]) fprintf(stderr, " label: mnemonic operand comment\n"); fprintf(stderr, " -s1 Code in three columns\n"); fprintf(stderr, " label: mnemonic+operand comment\n"); + fprintf(stderr, " -p0 Processor unknown\n"); + fprintf(stderr, " -p1 Processor 6502 + DASM syntax (default)\n"); fprintf(stderr, " -m8 Start of mnemonic column (default)\n"); fprintf(stderr, " -o16 Start of operand column (default)\n"); fprintf(stderr, " -c32 Start of comment column (default)\n"); @@ -95,6 +209,9 @@ int main(int argc, char *argv[]) fprintf(stderr, " -a0 Align comments to nearest column\n"); fprintf(stderr, " -a1 Comments at line start are aligned\n"); fprintf(stderr, " to mnemonic (default)\n"); + fprintf(stderr, " -n4 Nesting spacing (can be any number\n"); + fprintf(stderr, " of spaces or multiple of tab size)\n"); + fprintf(stderr, " -l Puts labels in its own line\n"); fprintf(stderr, "\n"); fprintf(stderr, "Assumes all your labels are at start of line and there is space\n"); fprintf(stderr, "before mnemonic.\n"); @@ -108,11 +225,14 @@ int main(int argc, char *argv[]) ** Default settings */ style = 0; + processor = 1; start_mnemonic = 8; start_operand = 16; start_comment = 32; tabs = 0; align_comment = 1; + nesting_space = 4; + labels_own_line = 0; /* ** Process arguments @@ -131,6 +251,13 @@ int main(int argc, char *argv[]) exit(1); } break; + case 'p': /* Processor */ + processor = atoi(&argv[c][2]); + if (processor < 0 || processor > 1) { + fprintf(stderr, "Bad processor code: %d\n", processor); + exit(1); + } + break; case 'm': /* Mnemonic start */ start_mnemonic = atoi(&argv[c][2]); break; @@ -150,6 +277,12 @@ int main(int argc, char *argv[]) exit(1); } break; + case 'n': /* Nesting space */ + nesting_space = atoi(&argv[c][2]); + break; + case 'l': /* Labels in own line */ + labels_own_line = 1; + break; default: /* Other */ fprintf(stderr, "Unknown argument: %c\n", argv[c][1]); exit(1); @@ -189,6 +322,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "Operand error: -m%d isn't a multiple of %d\n", start_comment, tabs); exit(1); } + if (nesting_space % tabs) { + fprintf(stderr, "Operand error: -n%d isn't a multiple of %d\n", nesting_space, tabs); + exit(1); + } } /* @@ -250,29 +387,62 @@ int main(int argc, char *argv[]) fprintf(stderr, "Unable to open output file: %s\n", argv[c]); exit(1); } + prev_comment_original_location = 0; + prev_comment_final_location = 0; + current_level = 0; p = data; while (p < data + allocation) { current_column = 0; p1 = p; - if (*p1 && !isspace(*p1) && *p1 != ';') { /* Label */ - while (*p1 && !isspace(*p1) && *p1 != ';') - p1++; - fwrite(p, sizeof(char), p1 - p, output); - current_column = p1 - p; + p2 = p1; + while (*p2 && !isspace(*p2) && *p2 != ';') + p2++; + if (p2 - p1) { /* Label */ + fwrite(p1, sizeof(char), p2 - p1, output); + current_column = p2 - p1; + p1 = p2; } else { current_column = 0; } while (*p1 && isspace(*p1)) p1++; + flags = 0; if (*p1 && *p1 != ';') { /* Mnemonic */ - if (*p1 == '=') - request = start_operand; - else - request = start_mnemonic; - request_space(output, ¤t_column, request, 1); p2 = p1; - while (*p2 && !isspace(*p2)) + while (*p2 && !isspace(*p2) && *p2 != ';') p2++; + if (processor == 1) { + c = check_opcode(p1, p2); + if (c == 0) { + request = start_mnemonic; + } else if (c < 0) { + request = start_mnemonic; + } else { + flags = directives_dasm[c - 1].flags; + if (flags & DONT_RELOCATE_LABEL) + request = start_operand; + else + request = start_mnemonic; + } + } else { + request = start_mnemonic; + } + + /* + ** Move label to own line + */ + if (current_column != 0 && labels_own_line != 0 && (flags & DONT_RELOCATE_LABEL) == 0) { + fputc('\n', output); + current_column = 0; + } + if (flags & LEVEL_OUT) { + if (current_level > 0) + current_level--; + } + request += current_level * nesting_space; + if (flags & LEVEL_MINUS) + request -= nesting_space; + request_space(output, ¤t_column, request, 1); fwrite(p1, sizeof(char), p2 - p1, output); current_column += p2 - p1; p1 = p2; @@ -280,6 +450,7 @@ int main(int argc, char *argv[]) p1++; if (*p1 && *p1 != ';') { /* Operand */ request = start_operand; + request += current_level * nesting_space; request_space(output, ¤t_column, request, 1); p2 = p1; while (*p2 && *p2 != ';') { @@ -305,16 +476,33 @@ int main(int argc, char *argv[]) while (*p1 && isspace(*p1)) p1++; } + if (flags & LEVEL_IN) { + current_level++; + } } if (*p1 == ';') { /* Comment */ - if (current_column == 0) - request = 0; - else if (current_column < start_mnemonic) - request = start_mnemonic; - else - request = start_comment; - if (current_column == 0 && align_comment == 1) - request = start_mnemonic; + + /* + ** Try to keep comments horizontally aligned (only works + ** if spaces were used in source file) + */ + p2 = p1; + while (p2 - 1 >= p && isspace(*(p2 - 1))) + p2--; + if (p2 == p && p1 - p == prev_comment_original_location) { + request = prev_comment_final_location; + } else { + prev_comment_original_location = p1 - p; + if (current_column == 0) + request = 0; + else if (current_column < start_mnemonic) + request = start_mnemonic; + else + request = start_comment; + if (current_column == 0 && align_comment == 1) + request = start_mnemonic; + prev_comment_final_location = request; + } request_space(output, ¤t_column, request, 0); p2 = p1; while (*p2)