From bf0ece4109c5cf054c158a516c31ee0f846ab01b Mon Sep 17 00:00:00 2001 From: nanochess Date: Fri, 3 Nov 2017 22:14:39 -0600 Subject: [PATCH 1/8] First commit --- README | 27 ++++ pretty6502 | Bin 0 -> 17316 bytes pretty6502.c | 330 +++++++++++++++++++++++++++++++++++++++++++++++++ pretty6502.exe | Bin 0 -> 64000 bytes 4 files changed, 357 insertions(+) create mode 100644 README create mode 100755 pretty6502 create mode 100644 pretty6502.c create mode 100644 pretty6502.exe diff --git a/README b/README new file mode 100644 index 0000000..9dbe00b --- /dev/null +++ b/README @@ -0,0 +1,27 @@ +Pretty6502 v0.1 by Oscar Toledo G. http://nanochess.org/ + +Usage: + pretty6502 [args] input.asm output.asm + +DON'T USE SAME OUTPUT FILE AS INPUT, though it's possible, +you can DAMAGE YOUR SOURCE if this program has bugs. + +Arguments: + -s0 Code in four columns (default) + label: mnemonic operand comment + -s1 Code in three columns + label: mnemonic+operand comment + -m8 Start of mnemonic column (default) + -o16 Start of operand column (default) + -c32 Start of comment column (default) + -t8 Use tabs of size 8 to reach column + -t0 Use spaces to align (default) + -a0 Align comments to nearest column + -a1 Comments at line start are aligned + to mnemonic (default) + +Assumes all your labels are at start of line and there is space +before mnemonic. + +Accepts any assembler file where ; means comment +[label] mnemonic [operand] ; comment diff --git a/pretty6502 b/pretty6502 new file mode 100755 index 0000000000000000000000000000000000000000..ab6669526f2df8cef75f9f3e0df7e33e5003dc80 GIT binary patch literal 17316 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 +#include +#include +#include + +#define VERSION "v0.1" +int tabs; + +/* +** Request space in line +*/ +void request_space(FILE *output, int *current, int new, int force) +{ + + /* + ** If already exceeded space... + */ + if (*current >= new) { + if (force) + fputc(' ', output); + (*current)++; + return; + } + + /* + ** Advance one step at a time + */ + while (1) { + if (tabs == 0) { + fputc(' ', output); + (*current)++; + } else { + fputc('\t', output); + *current = (*current + tabs) / tabs * tabs; + } + if (*current >= new) + return; + } +} + +/* +** Main program +*/ +int main(int argc, char *argv[]) +{ + int c; + int style; + int start_mnemonic; + int start_operand; + int start_comment; + 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; + int current_column; + int request; + + /* + ** Show usage if less than 3 arguments (program name counts as one) + */ + if (argc < 3) { + fprintf(stderr, "\n"); + fprintf(stderr, "Pretty6502 " VERSION " by Oscar Toledo G. http://nanochess.org/\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " pretty6502 [args] input.asm output.asm\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "DON'T USE SAME OUTPUT FILE AS INPUT, though it's possible,\n"); + fprintf(stderr, "you can DAMAGE YOUR SOURCE if this program has bugs.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Arguments:\n"); + fprintf(stderr, " -s0 Code in four columns (default)\n"); + fprintf(stderr, " label: mnemonic operand comment\n"); + fprintf(stderr, " -s1 Code in three columns\n"); + fprintf(stderr, " label: mnemonic+operand comment\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"); + fprintf(stderr, " -t8 Use tabs of size 8 to reach column\n"); + fprintf(stderr, " -t0 Use spaces to align (default)\n"); + 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, "\n"); + fprintf(stderr, "Assumes all your labels are at start of line and there is space\n"); + fprintf(stderr, "before mnemonic.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Accepts any assembler file where ; means comment\n"); + fprintf(stderr, "[label] mnemonic [operand] ; comment\n"); + exit(1); + } + + /* + ** Default settings + */ + style = 0; + start_mnemonic = 8; + start_operand = 16; + start_comment = 32; + tabs = 0; + align_comment = 1; + + /* + ** Process arguments + */ + c = 1; + while (c < argc - 2) { + if (argv[c][0] != '-') { + fprintf(stderr, "Bad argument\n"); + exit(1); + } + switch (argv[c][1]) { + case 's': /* Style */ + style = atoi(&argv[c][2]); + if (style != 0 && style != 1) { + fprintf(stderr, "Bad style code: %d\n", style); + exit(1); + } + break; + case 'm': /* Mnemonic start */ + start_mnemonic = atoi(&argv[c][2]); + break; + case 'o': /* Operand start */ + start_operand = atoi(&argv[c][2]); + break; + case 'c': /* Comment start */ + start_comment = atoi(&argv[c][2]); + break; + case 't': /* Tab size */ + tabs = atoi(&argv[c][2]); + break; + case 'a': /* Comment alignment */ + align_comment = atoi(&argv[c][2]); + if (align_comment != 0 && align_comment != 1) { + fprintf(stderr, "Bad comment alignment: %d\n", align_comment); + exit(1); + } + break; + default: /* Other */ + fprintf(stderr, "Unknown argument: %c\n", argv[c][1]); + exit(1); + } + c++; + } + + /* + ** Validate constraints + */ + if (style == 1) { + if (start_mnemonic > start_comment) { + fprintf(stderr, "Operand error: -m%d > -c%d\n", start_mnemonic, start_comment); + exit(1); + } + start_operand = start_mnemonic; + } else if (style == 0) { + if (start_mnemonic > start_operand) { + fprintf(stderr, "Operand error: -m%d > -o%d\n", start_mnemonic, start_operand); + exit(1); + } + if (start_operand > start_comment) { + fprintf(stderr, "Operand error: -o%d > -c%d\n", start_operand, start_comment); + exit(1); + } + } + if (tabs > 0) { + if (start_mnemonic % tabs) { + fprintf(stderr, "Operand error: -m%d isn't a multiple of %d\n", start_mnemonic, tabs); + exit(1); + } + if (start_operand % tabs) { + fprintf(stderr, "Operand error: -m%d isn't a multiple of %d\n", start_operand, tabs); + exit(1); + } + if (start_comment % tabs) { + fprintf(stderr, "Operand error: -m%d isn't a multiple of %d\n", start_comment, tabs); + exit(1); + } + } + + /* + ** Open input file, measure it and read it into buffer + */ + input = fopen(argv[c], "r"); + 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); + if (data == NULL) { + fprintf(stderr, "Unable to allocate memory\n"); + exit(1); + } + input = fopen(argv[c], "r"); + if (input == NULL) { + fprintf(stderr, "Unable to open input file: %s\n", argv[c]); + 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); + + /* + ** Now generate output file + */ + c++; + output = fopen(argv[c], "w"); + if (output == NULL) { + fprintf(stderr, "Unable to open output file: %s\n", argv[c]); + exit(1); + } + p = data; + for (input_lines = 0; input_lines < current_line; input_lines++) { + 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; + } else { + current_column = 0; + } + while (*p1 && isspace(*p1)) + p1++; + 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)) + p2++; + fwrite(p1, sizeof(char), p2 - p1, output); + current_column += p2 - p1; + p1 = p2; + while (*p1 && isspace(*p1)) + p1++; + if (*p1 && *p1 != ';') { /* Operand */ + request = start_operand; + request_space(output, ¤t_column, request, 1); + p2 = p1; + while (*p2 && *p2 != ';' && *p2 != '\r' && *p2 != '\n') { + if (*p2 == '"') { + p2++; + while (*p2 && *p2 != '"') + p2++; + p2++; + } else if (*p2 == '\'') { + p2++; + while (*p2 && *p2 != '"') + p2++; + p2++; + } else { + p2++; + } + } + while (p2 > p1 && isspace(*(p2 - 1))) + p2--; + fwrite(p1, sizeof(char), p2 - p1, output); + current_column += p2 - p1; + p1 = p2; + while (*p1 && isspace(*p1)) + p1++; + } + } + 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; + request_space(output, ¤t_column, request, 0); + p2 = p1; + while (*p2 && *p2 != '\r' && *p2 != '\n') + p2++; + while (p2 > p1 && isspace(*(p2 - 1))) + p2--; + fwrite(p1, sizeof(char), p2 - p1, output); + fputc('\n', output); + current_column += p2 - p1; + while (*p++) ; + continue; + } + fputc('\n', output); + while (*p++) ; + } + fclose(output); + free(data); + exit(0); +} diff --git a/pretty6502.exe b/pretty6502.exe new file mode 100644 index 0000000000000000000000000000000000000000..cba50a8aa7afa03f71f029d39b545bb2c3ed52fa GIT binary patch literal 64000 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≫}xR?`wUz}=w* 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 Date: Fri, 3 Nov 2017 22:17:59 -0600 Subject: [PATCH 2/8] clarify executable --- .gitignore | 2 ++ README | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97efaa5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.DS_Store +*.o diff --git a/README b/README index 9dbe00b..47430f6 100644 --- a/README +++ b/README @@ -1,5 +1,7 @@ Pretty6502 v0.1 by Oscar Toledo G. http://nanochess.org/ +Executables provided for Mac OS X and Windows. + Usage: pretty6502 [args] input.asm output.asm From 5f46ea09f6521933c7cdca23ce5d2618fff6fcb4 Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 10:27:10 -0600 Subject: [PATCH 3/8] Reads the input file in one pass. Nicer repetition of spaces in output (robertlipe). --- aard1.asm | 2040 +++++++++++++++++++++++++++++++++++++++++++++++++ aard1.new.asm | 2040 +++++++++++++++++++++++++++++++++++++++++++++++++ pretty6502 | Bin 17316 -> 13204 bytes pretty6502.c | 72 +- 4 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 b/pretty6502 index ab6669526f2df8cef75f9f3e0df7e33e5003dc80..29dcbb91516c9848912ac4af6e28bf25f286b5f4 100755 GIT binary patch literal 13204 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 literal 17316 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 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 10f056f7fed9856b5147e24d283e8986f0d6e2bd Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 10:27:10 -0600 Subject: [PATCH 4/8] Reads the input file in one pass. Nicer repetition of spaces in output (robertlipe). --- pretty6502 | Bin 17316 -> 13204 bytes pretty6502.c | 72 ++++++++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/pretty6502 b/pretty6502 index ab6669526f2df8cef75f9f3e0df7e33e5003dc80..29dcbb91516c9848912ac4af6e28bf25f286b5f4 100755 GIT binary patch literal 13204 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 literal 17316 zcmeHPeQ;dWb$@GHK~aGf#Uw5T`k+>@1C}K~?%J}2WP8nXV%Y*o#KAG^r`3~o!+x>v zZ7gL_P_ufDp4J--iCPFD@eG+MQSRz(G){=6E!uRw3eNZ z?eE<4-hMnugfP?TKl^6hz31HDJ?EZ#&bjxk?%UOCm;U2-mr0Umr6i56kR-{AyQ@Z$ zOi2bMNq>S{!5s*6b=>8@&wtN8YOTCHmF$un={bvzfk2Oce@|r>A>UNlCfPh}lVFax zsYf7SXhQ~3d@a(q8j}HZ;u^aH_*FJ3s#VfxIU5M*MygLQHo5hkSkLF zbH&&M08po4*;i}J5bxIK zthq|(P?Jq-a4Q{>bT#Vv z?Tr5sXu``cnhV|Kel5p|9)kS!?ndxe;+An=j(cNDPi~Ba`!@CuNBY6j^{2SWj{Tp1 z{Pp*Jc-z{~^=;qyQ1i7vUW>MR+|uQB;-=*xcxuD74)Z0sIqVbV7mee?O&HBllKvH@ zdrD(t{O)1h(4vjo8(~MdPjr$#fQt0D!ylAe*ggbL{;6J74^%x+^+44FRS#4>Q1w97 z162=HJy7*P)dN)z{C|0%SFzqu((_GssqKD_c9~y+?0>W$BTe zt8?R60INnZ0t@Fl51ND1X_ z>1mJEX8Gsxjnv`2Bt>d>QHN~H8~A%($#kC2Y+i{@v(~~B7uvkfy@#4C505FVqf@WE zD8>tgf|CAr)4^{I;A-^#*%%;667&1Z`SUP-+W#ABu_u}ySy<`K-h*Qh3^y*!swrGc zqxw!rxv%3m0PRW9zU^nC{Z7jq`_DoF=#z}z!|1CHI?Ct>qX|ZzbY!bWUc)FQB7C*OLH96v;g7|9=^PkngM%uJ{)o|UF?yMU?qu|vjQ)_(JkEfGH`*C} ziqSV2{hotvW%OZ27a0ATgZda%8NK{{!m39c^bSUMFnWoq%(e#|w29FMM*o{NcRT2< zj9$j*8rIz6pz9dTBmWWo&je%mfWD|U9%QLO#5@R;HLfO=p<~~KSu{+)BahRD%`}-I{{SlRAv10na+iDe#Pb) zZ}xJWx+y{bJS}-8vuetFsy=;bgLe!Eb~KYO2wQ79g*CKdFDu!xn(X)~2CJ0s@}yt+ zvUMi?^Q#rhtVJJdaurJNXAWR+Y*}}cL?%m!5?np5cwQ;|d$|TBeR_prP3Im)Kg*xv zO|b>$fbw|9XrqK-UN-D`;VoaLHwW7ufQ0QMiEP^eK7T!pS~fvPy)4w9%m0@2ErHW< zBJG<$Sq7iO@hY~={K;kT)4-MN6=@h~dGdd~Os_8pEoajsXR-71B+r&6*(P?8n%Bf! zG0C%-Sd6Jb-5k_CQ&M-H)Qt*tbLECS#**J~BhY)3BERjFKKXgAW;Z zuutw2+gpuKDE5`oZ1og;@+OY-ZJ)eI`cHvJ`uJI9)sixQk3Q4pOIWiQ0Mv^%Wtq=I z#i;_aRLPz^O*=-W_e}0EsZ1{*NSlN~0?9opT2FhF;7O8KJk!=iD@$Z1ORDL^lOXcX z(r1{=$eG+a65;Nad4jCnMJ=F7LHZF&U*yHrtnR-=<@Vz7lImwj^$_@J^Q&Z!@X#|hwa7OIXe{BIpQB?&h_njV zdb7MsupfgaslZf^lloqg%A6z`epB$FQ3;ADD4VCfNB%;1x#c*Br z{30p&F<9Fjj}!lGf~Q}BvkOZ01&$tjHkcKIduC{#f0Vk}(Y4HDB>5d`!ltA+9j7|1 znVps}c_+`Q129_1Bl!!z!w3}5{X$hs0}Rb{&QriU=at|H9&WvOxNW^;nMXuFMN$J5{GD8j^deu}@U)2l$`@y0R;Wm>dP~B+xAn zpO?9Ax#`By)jLKnCW}7u<%Tc<`EGJ*JWCxWOe%lhguWy;hKiV62?rGQvhRP5H8HF)aHS>`y*&%@Q?87MfUKF#UtKQOlFe$SBr#AXlVLVHHCQK^bvm*gJTtw!dtOyr7KPx(M{wT$89fCFv7g4ze zjEHc#x&|jjtUTZCu+Cs53dZhaacC`bKg5^F(2t;bQON!Q-z{)LMja+hD&3P3X4BSS z=im|{yO;jhtXwWT#NVH#KonzD7Lkvhe+Ln{S6JSKh`7VmI-X_l_9eh89ME2J%6q&NN~cWvN+wnycZNZ-sClpl=7e~tZqB70rUzZ-9z0Zh9Ydjq_Q}ay}Cts*|S9E zpXSBjZaz`6Ld@XiKfth_w=s;c36siqX&4^M6n3}0XqED};R#W`e~3=4V%Hqcc9T^{ zaFF7Ndru7&a+|Qqophug6DF0**hX8HaM~B&@fuU0jn^1axhavf?`Dm)Lwt!fb|;z_ ztuYm&IFq6d6DF1JNiDU;g!e>IxwK3#{(wxMq}7in6&|73v1x-7ZodU(M(hl&{&U_e z?~>;#cF9?rqy9xT_>hRd9Po#bxztwL{A$^%eR}>KtlBo=i)9ujgYMPB3zM)3lS;Rb z+-Y_MfnPSmw$b>DGVBLf;!ZHA$An4cG6TJf3~Pcm&M=~K0SxytJyLN1h-b37jvCv< zHnVKnSwFNyXf1OsDRVx&Oey$mrC3>d$dBSrsxk2?;V0yRtr(y-F<`I zug%r}WvKrY+6oPQcpMcP`b9Y)%8)2OF3N}~W1>umGAT+!l%EjgkSITiQj+#$ulIoH z=q@z81!o-#QDgp13>3m&X;OZcD4D456Ll+5Gem76>J(9T5%oM#Jw*L2Q9+`P6O|z9 zuZSW?<&P3ILDZ*-dV;7SqW*@c7^pg_E2$aA@TQig+vHC)H8#tA!}2~os3zr}ctq=u z%Xc-(A;U;)*|;&L#^S+{rt6LIIda;ERixARXr-l zQ-)2}NjvxLy}3v3?e@#v9i4u8UvE!WZ;!ld_a498(Jk-Z3+`6g2*p!_AvtW^tjmeG zu7~>~+O2ica6Bak)tJ1qqZ8kbl|Q<#_a3<$#SXt59)M67y_505q#Bh&sxJ4X2KB}| zsUtaY}8}w#d!clI7lA7jd|2;ZySz2e*XY1@X)TAND2TDe; z)o!CV#G5y!dsoj%e~>A>1lQH5EBnOsNAR=?)f^$Or5=9+X>4y|%0U zFpIOiP9jb>hM_cw{N5rrV8+zu1XMVjGM1s<*aNZn;aE`tT7z}cK0CR!WHO%IB5#N` z^viAXh9D_h28%C+q490y!g}mxLssP|R$Mp%o8eK?lazX6D%?XEf+@#%Hxa&qfjaG4 zaU_tAuWEyBY=n190ti_=s2cD+mTGbs(@&*R$;6EmB3VZ)gBp8%FsU8Bu}(T%CMyQx z4XbQ4JRT+bWJp(eExxOYotsX?=>EI))Pre!#=`e!JvcxnX>k<^r@^V~Kgiz;zSgeS z+I6E{`|NtVUGK5$d+qv=U4PuJ4ZHr7U60$fGhVf>dZ6lost2kbsCuC4fvN|p9;kYt z>Vc{Usvf9%pz4ADI}coS(;7Obmab|K&`;O3QOLk~!3lhLLc@i5WrKx;!`gXkvE1HnjK*NF2GH>eppG3~_A z5eG2}F$w(I-54OYORy;;NX&j>aBxZVA)*f_!-n8O;KI5%<03EtHYyHWh#LZjAJ9j{ z05nlg0RKy1RUjIIby_fGX!xzZO4Hkv)E-RX7%#w@wnWu%OuCZ}5~ZDVsBoH#?F9$pW=qJfJV=(UX(1pTgcp zS= 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 7b4601724300f33053d6ccf9b44d0e8047adb6cf Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 13:28:48 -0600 Subject: [PATCH 5/8] 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 | Bin 13204 -> 17612 bytes pretty6502.c | 228 +++++- pretty6502.exe | Bin 64000 -> 67072 bytes 7 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 b/pretty6502 index 29dcbb91516c9848912ac4af6e28bf25f286b5f4..01eaa29b384cc367a533469fcb3c4eb64e435935 100755 GIT binary patch literal 17612 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 literal 13204 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 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) diff --git a/pretty6502.exe b/pretty6502.exe index cba50a8aa7afa03f71f029d39b545bb2c3ed52fa..8872ba1c68a9d3fe5bf7d4f43981b2cfdc6209b0 100644 GIT binary patch delta 28993 zcmd_Te?XMQ_CNmYvcRf~iwcN{xGE|N83ib~VvDj!CAx?#lA@xLE20tZ`lH0vR?78} zQm5{v0qI(Li?yy^3-&DOxUx@e84KAeTCjY$Q zf=I7!cvqx+!?Pm2yx|PeS<4pNsI27svzR4mx+*}bIwalY$F)cSsy?b-l5_%?ISTg4 z2}nbw07+_Ly;Vb1CN@?zE-?C%B*n2@_0))6ze$owAyqzGBq>_8V^|bBt?q=n-umK58ICF$;=$Y=ooDZS77s-ya@r-~&NxFPxRz4 z>uONB&03JSj)H;C^GZ^~{G!HFzCZAHwQHNqT~xcLmu&75^j&gJmuu38bDRMglBD0f z1DSGum#q1G4iFYTP^rjm?v``VmVU0w;~e8*DjZY5Cobu?hnVs+Pk(q>5(APP5j+FJJXhJG4ssJdU<}aJbfL zG?qHog{oYW9!pfA(e|03m33A0lFOI&6QZI9_tckgeSOtLHw)sjaJi?t-tqt;kBiM7 zjpxav2Kk>PxSg6P=LqP3Lv;<-M)z^eiRiOJ&^1uy-};*Ba&%VsC4HRgn_S9{bR z`PyKf5~DfKRjCcoSN}sTNw#gMkoOyo&NrAWycw$LICC+wABKI}0c_7q|N>BsK( zVNVnGV?Xv!3f5_BCiEMA^hO`CCJ@+KKep6|)e^SakDcwqW)gOdA3NEHT~F9zKQ_*X z-ALFw{n-AYPNg5)2%X|bck31GVZsjeW54%d+X>stk3H?fh6Mrpo53fEH+|Sl!v4dL z-Rr~J2-_sEP6+d1A9@d=U-1*K^kq@g42DZwNo$kXfgR|_e(l315LV^Kp7dcC64rxtNodNeKJ24} z{oIe;?ZY-W3H^>A{h$whlCUrMvE@Fjt{1S(kG;!>H4wJakInR9V+p&|j~(a3&LM2B z9~%j*6IxuV;?KoMQj@ts!XMTGl}OsPBB_Js0D0U%iI_Tg0HQ;oI!TLjlbI{XeT2je zba8c>d7r*okEtW)?89V}HCy#Zw604x*@xIRQZqh4m97RF|D7R1$Y_QEI5~eGEe5*n z`Xjk2cm7`4yw}Bx-T18BJ3#+X6>5-k_UaGqIB76R-q^?XAd$`cXaNY@h>VL~?>shnk-sB1vueg14`=t_Exj|BUjn z>T*?fN$Z2~soF3M>uRoTFR{}4S$(V{LgG|Joca(ae@9$L)w%phKd1J#pGZc&Oy_oy zyTPAZ*Y?SExk_fSKl6Co!T-q2R5EL6g=>54Ke9*q%XYXbJA^DcNEZ1WvuuZ{1I}zT zS178!rw31AtHPU8K}^tx%jCPNlFT)>&-j zRO(Brgz9~|x6nT-mLQ59zrI)q6+?TE&$8{NVm1C^ww}s5F}kw(

gEj*cPJ4uDg z{DqQw3LQlu+XZBj4m!nD%jKUBqz-7^<}MpUq83!+Pa9(NI#!;Sb2(~-$#}E zbv)M=*#~4-N!_Sx@A}BprJy-8izh^gVzT*+g~x@{Gv;Troa1a3X3WceGibl7azE|% z3B>IcKex4ln^tgoLoq-gv&+!QQv4H4PYI?vIp+*S);z0JC7btKc$e7rLXGBTdx|Za zcozA2#tNQJ*mGxcd5OYQ&fh&o_Q-ZwFQ&A6CvecR~fZoO2y>Vu?EkzG6Zhkj>{n zzqQ|%P&^3^^e!e&y{~f5!>-DMl0%QuC)8+N581hRYF0Bw#B~fz_u1B>yFD{>7Vi`S z!U(sxDqCoT#hU5FqB+a9o+Oh+Q=G;w1Pi}1#7{=j+TKc?ZZe-%l2eqR+rnhsACS|W zmeZ|wMFtYdVUd^L?ar@9XWi7BbC3z9&KR^5>whi}5zCCGs=*O~F6f;{)UGb0y$=XQ zH_v%K1Uf#y-VP(S1yc>(s?Wt}=GV{SUPXt&DxSC>MlJ@z6WmiV20#s~F-8&kEM6lf zHY!5}e&KtXo6HwPJ88U}XqMHD)&ibcelIE2R*mYTcuWZ=Cr$W4thq= zMACdd8>YJ3d_m5+;QCf&hrZXj^ACE0d}V^LMuON?d04WKa8+{2K19yH;5x5zgp;gF zd-IB58aW(7lz|{N8oSpw?7Vp7$imh#k5^s zlm9HSds5$TXe(Nlb1=6$|1j3l77K3>l7;18@6I`=3{O>qe)E&0p8k>1Z{8-fl}6EZ zX}BX9bYgm7;);=VzGoMDNNPCzdNpk6q4Z=cw605||Fiu6MR6PjeUr4U0B0?<&6rca zdZ=je6sOn1>EMj@P-rQp0i90IdA=g)E5fx<$Ln)>keHXDC>Wn#ACQ08oqrevZgah& z?wDmUiV$=8-vp_`GQVE*xZcw&n=iOp)EMiWQ)056lJlK3R+xeMs_`Urzbv6C#{BMz zp`z#6-dsNadWPqOBAxSmfovm=r~^E4$Y_S{Gi7PmQV_oT*=nNe3v6N`5v)^%D8nmXLtHDsz zSSooPTHXjJLSbPMV}l>>rL##FOgI5gWUma1=sy8$nj{z&l9m4WP(I`dHmT_wkLW>ZxgI3Pv9FT!!uao@SzsvwH~ihrzv)$J(@o?`bKtp(`Yoq zTsf`YG)JprL>_NKg>qN5In+Y^&*L|t+tBd50)G1#_RR3`MIWL_BQ<&#l5tp^38D@LOkjNn4j#EL)?ckM zATN&>5=?5~{os>>V8Zwr20@SOO3o~k)jm+ zp%ijR98^{Rx+cTbqV=mq6_!${1<80JH9?KKWQVq@)9!GkCt|Dv98*g*ylWaNa+P#L zn1*aTVz{84y{s0VkOC4G107v;Dwkqa)&ou0>Z+3(HsgY z75o`%BD(dXqlA=m$t%d^Rd*3Bw8j3$bp&hn%ax(}mn*|A zX6bZTvE7v&@;9&)vLazOkR^11yrxxN{pKH`K|UgTCZ;sHovz=OLaY20V{?UC?lM+( z>zxmM0J;M2c(0?|>*(S;3ngjH290X6sYxhgM6_MvY; z`p%?JjbE+qB_F-$xF8?(1j~)|&=`Nr)2E)Yjm>M+awGN!{X-0OSis)O58euKTlly+ zqH|RZPW|RX$aHm~#k6y)%w6%#W6a&2I4d8LOJhelRYX$RE!k(_=XfeYs|KpW89|MqKOTtULOJ+SJYlv(@`qqJ(NczIOdhX;T1tJ| zL}%#ZVNm8Kb2r-Isohj&Y^B`DuX-2JD{UB=JQkN*kgcHMHGNL-h=NM(#wuOC$^A#<`v_D>o7u z-wa%ngcB0<4p$4l^-+fgRce#Y8n0l_CO08wuu>Rnd~hXR%={-QEdjpiG4ahgstz)xkOB3)Fs0<`sn^-TYAuF?XO{hFm*LhTH*IqnIw@vl{ zc^Vc})ZCewsL|MoB{rflxCf!rSy#Z(`3tasW8$}vCOZ4xOe2=mndZ>a-hRR{gue~f zkkV~sb|1&6D8u9#O?q)VtW9NVYk4H5@c*Q!-6$i>iARW7Q3ujgIZL zjqWUUwfyX=3{|1OhBa;J{3Bj^d44FT8SS!db@lSnu(rE|3=Rv(88n!=M6o7 z7p|h~dw%Mso}N#}=4HHU@9pxc?13(?+VLrg!bEckt6YI^b)(fB_5BYs_g`Qo1hSEe z2>Xg!F?I*=NoUJbZAQOvO3SU=D=Z@8|7ZHXC@u`{0ptL5M1Ax+ss{+4~%sKsL9Jq@1Cai-IUc zMu`#xq^e_&6QYI&c@qW4-Jm(B(ao$jF> zs*wM60jin=R<>At@EQo1taQf|+vhv*9*^w$Xyi0$Vhu#Fm_{IdEwL@M54O<*kMZ%v zRw*W7IAN0-pbPUNZ6+FqVet@{mXF3(Ay(j|vs2TCoWZr7Ufkxohn&XqR&(fIP9epn zDCw)7f{eW>WyF61E?^4fE_Y>fmDj%3n_?s6a6K~_1|?tZi)k8U|CjM%#U0-9ybG^# z7w1UaLEbNY49*Lzui)o>S+yZ{E;>_hq8=@vDQ25Z?-qKWN$>v6b0}JYi6c4U+@ihc zM7|NNp#kg0EJ8;p+pa~%B+6*y)5bF0u-v@MA!td5mG{B0T6y?l`b@_u!OAZ$qR)Sd z&krFwE5933w(^-Y6m3ap!gQ2%9gnRgWtiVszYj@c&B6)n)bPk<3(@&fjfF1($HKze z%+WZZH8^5QHCA^DowcZ-%t~$I`3w zK~WEi0{Pg{u0UB+Wg5kDMhtgG>X84@0_-`Bd?!rQjp;N(l0A?YqZ)4tvEvW^3W;4? zgG76c9TmejUDbm9nkf0B_>)I31-g!g=5ohGN!m0+Cv8OQJ-uBg3|4P=G?drBr(rF1 zb%j+%xEew&JX3+|Dd7V5lCuQ&cE8ZJtW#Citv9|uKD z4?_zx#~QLaQ*Xfa@N=cNqCaZ%=adEg!Ke6?4J0>^i8jtH|YBqer^W~QuN_1#O^57{y5i2f}2_7Un|`mu!DUx=;;U$JLyBsu>Mq48ZXROPOk z*#p=ww-0nKy@(#mCwMrHk&UGx{Bx+HSV-hGHdxih6ycK?k0V|b^eGWC#(3yAT}9I* zd$5&n{TE4$h}_d`vYHzVx&&#HzxsQQxSe@G|sB8 zPGh_8G~c=$hgmtN6}!dq_Y&QXmg-l^sk4q&&)BV5s?81dIQ^l?`a=yK)ZDUl<2=+e zV7fVA3DUXKm&H*x^i^{(u&@^3o?0+J>BG7F0H!#GCCs*mhNa5@*G&8LMD_D`v6!5R zPM?(f$yv5^Ma~v}_m7aXd%i7CPAAEFzwFE^SL>_jz}Xo{&Low->K}N4gsrgOl_8v} zsqI4j@>FeYw@7uh60GZ_25j@LuE5IByXEOqL+^I$%Y-sIqP(;%q-z_eXtQ#+(3oA9otP;ZXb(PZUU ze!#0Z+KD3x&W$MvEv$X!9qKs)*vFP6w%ih>PHbThS+W$&lCcY^E=)VCADbwK>l2c5igkNCU99EMJ1cuc<5X&WHdcW|VMut}2NI?yr(MLkhnTr`2D7mAm(=phal7M-_OK8u5so|%{CV~_58+*DOfi5Q#rI9FMQ-+W*yfxGj z5=me5Z8{3MLWE%2c9XS+0}KtwK^VL@ie`cXWA{5PsF-T!!obq|nfpPKuPxy`bL0(k(u~67x6lECc1Z7P+l`Ab>{ryyZzck`HxcjQ&MKqL zwT7J1c=oO?<0@=UJtkT>O7ID2W+R$__JI9Bbb!tPysvnG^ss=Ev(5%r9@xM_+<|%O zJuT!o!xpASr7HdfOf|U!=5MEcBBUvVl#)n-`RGd2p zz;070L|b`)c&BPbRYH8q?5q`<_8r8DC0x|TA0AD1puNQQa3-db!ZDo;LGS5W|9Y0~ z*WNA|us-cg?$O?4!L+wh2CN2?`u;$#H>ht?gUJ)jcLGliXf|$p)Ljc&K-A-C3ahzh z-C2{)7RbM(4M{~O9I1JEn05s=8-#A79XQV$z69b!U0QcKk$A$Dx##Ly>*(DSm>SLg zvVEKy$)`vbwlMXMsS&z`X!~(&GSN-aDG1fm&%)1s$L8*sq+Zg(9^bKiP!0}9@&)5> z_R^*xqHvwidZG}g^&K0sb1V_vzH^v*UJEPRnW5f0kG;HeO#frBZ(Ya9`whltVD+`I zA9p6EPnZu*-Nq~Se>4RPPECSS04XX6do@Y_fQjO2(8^sNHC&Td><8f^!cERcI76@k zcB{JIJSMYo)90X@az|Rx1$!^A;{yNY92mf^0}oxAIg)1FDShuoe| zHr2K34K10KZ+^}KA5AO5qM!7hQS+gN=F)%+M8sA6Ql0%T*QI`I`j&>w!C+`UoQ=Gq z#=uNyRcYTs@bKe%?YLCo=&3zjn zVRuz43R!sdM{LxprE2?Z_QW1(GXIBqVspVXDdCeyE^p9BO+Fa+sEYg$hXLC)`xtS(OXF+2D zhX6+b!N8}?0&cb~k#?45m`rq!*j;VjjosW%3z*{nFEy1K=3DtU+ix zrzxrMqE>H_w3u*-Crld2rS+aL1@?BY)w1rh zm?Lhoj+m@}3ZW?JK)e$-YH+zS{U^ze7Wo7n%7u40AQ?V|ons=^KO0%pn32RhW6Zd) zGMYqPF0a=<75m9;*o(?rm}^YDy3ok##*9cK?%r@4sGwo}pjC8U^>qzr75)X59A!FT z_E?iTg@<)AEH|bbJNlMPsGDyM+teNh8C_e(T+cQ`m887V>D5)|@Kg%bes~mHGWLLT z8)`#zL9;h}3!bX0;%K0~;hXV-38sT99~ansUk)T{8>o>Qyx|*>1&Z}Z#5AAFznIc9 z&*3FOGx+jWtPhZ4K#{iv#g|d>qPACIN}RGK&NoR*yg1ZiY04ZB8|p5L4Xp;mx8zw1 zsLd=TAxBJxssuw=BzVg+bhv>J_&7yT-BZgoLoiu%}VJRpd|PRd{EU zZZc#hLzt4?V55|~l4yCP%RfYnA<}o2H=OVkrI4fJPr}NE@s&15XYVhZoCWe{@=5;m zIJW1e!Nux7)bOi`s5|6rt^6gw1x4Q^^C~S*ha)T=d<;I|wFoTdaq7lk)_?S^gGfs~fxcUOjlmvPs?N*Hhu~rs5oni;clt`_#bF-H9;wkhKZjS)=Q z+)1OdGmq=PeJR4r^`#;E95V1719 zSP1dm13bDDJ-2yZGocWF`#ZKiBR1q-L4ebk#Mgbt{+cm#WFmG(I0`~-7FvrO|E4Qf zxbdz!2J>_fy9{vGe#d^vh`fcSbHy-W@VZm^WprJsithRfxC$j9IL~`B`3tL~vDC0z z=0>W2oyKNQ8P)I4J>>iuJi1d^`QEVJ|3(;^@cd6=FHA{MfBP$InX>ebweU&e+dGhU z;l<{{!425T>D~;^jB;vY8zRI++=aXH94!AI;QOKD2HnxN7=<5IU+qE<;V)%7riSSY zKfvTIO!{<+JHMN72dC!rA>XGrxz5TLeZX{?F#}7%vk}ZJxH7@%L&b+e(F+^dl+4r# zq3Aa(&jPFK2fgciz47Y&1rF`}1x0Q5qlFinurf)G@S|;N*ZBa~C2hsn-=0PMdS)4W zC39fRoaHe7VykDDnWXJVoAJ8chL1-9^~>4!nWNR9)SF|cW)jJWPqqea33i=O5xXW8 zvD@NfhsEr6$q1r2fB_H*2nA>X5}<22TW!t`BR;a1Dx3$f0oIqXPt8k;T2@fT#jnte z?RW$?x#>-6yz7#tLg#7;h(C$#vlRtELB!iH;5iZxCcxILfDxZ;nHJ#sNwn=}(Y9BA z|Lxgsbhc#$V_9)(ByVRWj-;~S{wR{&fW3hIfP;X;fa8EKSFrxmvcr@nbpX)?(5^H| z(JR@J2d6ue8gPAAD(N3>u#vTa<#{*eKy5bGVyqYHBDft)wG<9Q8wBDsI^VI7aWd)O z(Gl=dIby0c|Bl3yJJq&F533;2)fCAoJW1F-x-8e#*!7=+#e(^bu2?}yJJc_-H%}h2 z78TuWJwn9`B%~6vNDEXmz0^?to5mq$* zrD0Uz^7q2zaA!2?k3U&Gy;g%6%ez1G6%>J_xcKq6kPajnpXp+h+0#Zvpt z+FHW9)2Rb<7tDXJu_g{r@RU){5g>%UEEzW!%NxSrsG)KN{&wucs3RVXtn0N-S0EJ& zRf^RT-SW<`08zkp9Lr0o)?ZAEV(zR^W0Sq9RAZA2Pzd_UB#f)QB1Z?F{k^M0d+N~u z?RnBQL+f=sgx{9oeJcE7g9e_g_8i_^+qJ97*j{EYvi6G?2(D#F?6&b8C=B8 z_zS1KUa=GS_S?Gi?8muAXAPn<3O#|acW|e-I?}ruXOT`io?3W0wphsDjkrXZwr&hQ z-9>NShzCTAJm8pV<)?^}++5?Vyg_-sY9EexBRs=8wc=DlwgTUacUQ~M!lNxg0l}zF zm=0S_npn1XUOqefR7CHpkCnZw^ka7AsX^9Ml&Tob=K|}F7dv10Nbr0Fi6RQ+lKM~7MC^~r z^07}izNm^@umHCi#zZKuf(-+Q9FDq<7+xUC(TwH`#G@9E)Dj!ECIo%pw5R1?-Go-@ z-I;ykDERkysC#zb1X&;OQD=sRO@HPg_5K$2`7?)f`=J_`zrBUA@aH{~H7N;LD8AZL z9z~0lWanE4=nuWGKjNm>s`qeju0F*U*G$iz3*Q^qVp)hUy6_3d)wmAzUMR&K=kHig z!xxe&nmfQdS#c0p`17>Ox^miKK3p)Gb##P&`gwM-=It9>(eRf%&BZZj#lYIENN_0) zoDZ{qAiwgS-<;q9?=wejY)L&WmH}AbdhC%8K;tqVWRv6 z1hDP4^w2568joNt{G*9-wKjIpY=wNHAgA~MPo0G?7>7n0_r`{3dbn`id#r44q;nDY z2&?4<&|JGb4O6B9P56?uN-YeiLnm=IiJ0$BR7|8J;(9MkKH)J_L}5glLs!uc(QLw^ zJWl6t#33AotPwJy<{8pSak4>96OBHiRbZ-7t6)zy)A&_$tuVwfEN-1 zN)BfuUA7}*Ffuk>=|+q7n=|li+X4seTVXJx^4{5pb+Ul(juFEKdp$(ax@W%-jkak( ze&i@<5S4l&@ZFdUnn(u~d5^M{bCXlDT~Sjo!CgHp^nOQ4vBJd4UAw(r69#nB>QpOV zjThHX#()#00dE{eY?`eMt%*O0?QPKzY6ZFU`z3WM?TArWV1zntHqgNE&tx}@HW!P2JSVSKLYqqQOSz0o8yzc>2yckqAec{S90qv3bC$*0&|q}Z*Hfp1~b4d(k%+y%wn(Rlqy$ptL5 zco~xGPfF#A`2KiON-L&L(7lNWPgB_=#L6HdL)&pA#}MGs#uLGVdie3aq6RujMJ)kW zq4h5j8%66~?V&ZX!`bii68b+0d(yYX(F(`^a^`@sNLB^!#qjZY>FmS#qq6tm83AHO z-*7v0t`mWqa&+`d4W10#gVc%qt=H#kMZQ|{3@Z(`9TxeeMrK@K=)bJt#tO?nWh)j$ zMSOzerlOd%P8ty2ORh%t)Pi9*M_xozZiBNh>8v>3;S@HR{4R*!y5Vg1G1^b(xPL7e zx=;kn$eOxN6QW&p7AyZ+ptC$XC?KiTV>|l2x-^wP+y?@a zLqv3qrmrXza3U?ze!Dn4$Z#hc5GYPWs7Yiy26&T$c*&FAXhbH6a?wGa!LlZZNEH(q zX!f^-$*CouU|8hJR&*vC=iWm4VF~z!VJi(-@vj#_v>6UiB%Mj(}WDbzO=V^(TJJIM0DcWr1z3OP4arb#}`Dvn0ytsE8vyO zUDMc@MK_PB+ew-l3U>`HvUasQ5%yXF&wKkud+n}|*``Hzs@^{E;i9Q3^{a2O{!7-( zp=f&T-5%rpONKk|4OT?zh^U?hd$+;_Gozc&^Dk)#tDR@d2?O{)r4A*YKb0g2#!`>|!8uXh?p;~L`!_)f+)muX!`1UEOwS~98#7aw}LUud_kE6MjjK&RLu^pvp{iyl$1;7x| z!SJ|2>}+YYdiG1~Qt3Fgu9=Nlo-n-w=7Az8^rH40_+IN&Ex+-#UA)39si$t;i<06B zTLj*F!;iPHn&snew_s18*mK{}m`=rud+H!J11X^VC~`QuOcT;zJpV788`ceUHd7yNeV0~B zoa(W(Bz=iN!#Y_Su)tl}VoaxC!pZ{qA{Mx7>sh7@k0w?^1e3goH9=T~2!U>OdBfJn z39_CQjGQ0>L+jjI4}(~|xub)od7f@!*8B7!KVhFGN7)(dJB4iR{b}*txN$+`DDH}F zDUZX8Bs}nl5AlcC1oAKU!r3aPoEyx}-5=@f-hz_V_8`^Ppv?`AA4@gU3V1R$Iue9C zokHYbTYf;~Fhe|3to#EMkejD&oSa^0zXeAj9t3L824fGOVMRE6NpHWU(qlN4Vc&yN zx|%crziotD;|;Ii#~-UsK*mVoExAVH#&`)tMmm|)P>6GWqc?>b!0)Lhs)K{sGwbK8 zBa)eS{dekHl2~iyFm>M~7QEs11PUK=1oFJUz*R0xye_DOHE+w1?qOIPgn?IMg16C~ za(pmbzadjS;R-vpA$AM}{JBN&ANIij*eb#f5~h2NG#oZ|yN&{K&a^PSGkiEy96q@d0|%kQp@i?&gr5Xmn;GjleY2;4|B7`GI_%3JBSpM2#vEhBF zDty@@kMDY(EqN?X{b&$-__3kt!$Iuj$A*sQ$c1O_Hwuy3{Sc%tH&vIk_go-nqQd{U zK;F8MY5sJJ(-=bCb*O)9Y@3T?WzQLoR{l*GdcImvE8lc!)?td7wzc`0o!= zekA`lrQ`We;uV4KB8}x=i!_dZA<_i?kw_Ey38YT%>STUIAfovpk*4y$iF6Ww4yo(7 z$-CObpA@J}&P1BcWsy$jE|FUJ{UV*sSBZ2EUoO&le6dIu^0^{i!t+FG<9CX*j60`_ zhjMNdshuZ@bS;k;>3Ti_DYfCyMhKCI6ZX(%dh9J8x6q@vim==0@q&2VPLFNk@lksG zT0HKe$Iry$ZhAb4N2mAD9(sOTp!d?_tKxAVJwA^|*YN}#Y_A&^dx{)n43wfMBF@4$ zg9LFv_>Qf{hp7;l)%Y5dR$#1rAz}W&WCM<+#z39ZR|pgFwBRE zQZSLmz(^lPt6-vyfzdup=VrmjU<@?)Fs%Z!I@XvHD==36DPergVKuwL`)%6i^H(S? zEBBkMY1er5#C^=WD}oswxA*(o^EVJ2dV@Xt_%e0!^DOj<*nWL)%#3)0nV%S|{_ME} z_dan*HA8o8I+q4jn=e>w8hG}xp`I{b#yZ&{rm#bNfu}cR^Sf#FQUWjD#{$(eZ<58L zqke0=J`QCN_>hbE9eD_5@U*vXRhQq-?td#r70RA?>t=Q1X7<5bqtsi@vftjirQbYJ zg?*vBsKql^9)h(pUQdCqGOlygqIRbEFc|LtjNhPkD> z1da_~AV@?PwFj1bZuRt7ZTv~sxB7sigWv0Ow6N_77@a-XU_W*|KA_DJ-m7T-KC;A-UCHO493W^fqG_DpC zhEWLEbyAh|URt0I`@zAi5tG3R4k$64aEN6ooZx_h*C~>sNEWYQFCUBxe+n)WEb`og z?~pV}V@c&(YFPWhn0^hwln(FVaPj~f{Mu~VXYPG%2reBTd2OirL^G>BD|bmgcsBGF`{*v9R2vXJ$@m`P4btXJMgu}>YVOe zY&_T<=(LWKARM6Vd063lS-1gZ3OyhHkH>VUhR*4zEgw&s8Gv>Yaf^p=q2I*3v+lk|=^-;lqC0g(4`ar5PoML=R>= z9tsUHxVSQ*F6bYvqfdWEoqdoMvELP?@nkIk4L>dxiUXxUaGQ!z2wjickWTBbIAW5cBZI zCvKeKzu?S8Mk@JFW%@b|4y2J?&|EJv@YOfDiCTPd!gbL&J!dFfBF@)3#^ZM?T8_{X zhHtCmJxcg4s zvLV|>jYl`AkbN*biPTcp36tjmxw09-ODO-;VU%ygYA!jxKLIjVUvE4$gst0Vh`Q^a z$i$sX3l^2)YMp3}TZxN0ux%1WiTtu{)W}OO(ix`@|K=@Xg~Q`Q62sHL`c{zvJZ~49 zR2?~1EZtH3)?I#;Q+CiakkS%yT3I4UciD#OlsFAE6@u%dOf_=r1>hi;R@7=A#6S5n z*ypsmwfx|p$)Bwr^x}a_)%U4_H&W$!``CStWT^A^v9}*t9!!3JoUmAC=J@{}rqJiA z*ZbeX6b`;F!W2#(!g(#W`uOWgm_jzC&A@5!5cj$WQvfA}DIBD%{~D%1xw!g&3CS)Z z1Z)9p1gr&=18lF0Fa@HNy;R{TKr^8IbrGgud4n=Un1Y1I{}QG!yIwSyh_^4n^A71tb8H0n^?PVG2r<76M@dtOaa)gRPu4jotso z_fD~`yV}Fx>EWAUhm%{ul^%+72%^yRRdl&wONGnG8{R&5sn52n_YP*Go|~O; zH$r*fAjEzb#aH3@t`xE2N%=ysxNo98DqZ_6d+xbqV#!lhR>jkQRhg9*-ntF_=JoiL zr8YZuV%UQe*2IPCJAr_)o9Toe{QO9jSHAx}R3r{VMqYn1) z^AQ6s{)|e3qHZ33n3?uPhE?^0y@lT!X|gxs>Ucaa0H*_G`+BLyMgB-UL;D=F zH$lwE3I<}tF`ytj{pN>>UjTi94Oy?g$!cGiHE>s(uZVv0R49y6%+=LZW6vG)UUC2h{ihL(-AagkJm1-lR!ovPfGML)s5dug$H#1kxg|L{;{>r|?kz%%~E z?%SWN-Y}2V?H{Mk*RhuUhW>QK7Ru_2e)!ie*8i`u{pe?;Op08Qd%ZC2@aV)!@*MUDV=gR}5SHP6kL4)G?x<3$XB!YkUPB@8G1`f(u zA#6k4DD_Rv?76xmeKN4V@KkYd;&l#n@=3PfmB<7O>^)DPyxh0w0XGpk_nlhzRE>MN zEw5k1oL(4rk$+sp*SZ6p9MJX zbe%v*V29g*pEW`FfdR-h6VT>C)MoUNhGXb{dcO91CHOJ~eiftD_>H|EvJ3L~ov(|@ zV*JKYY`rlKNNxsldRn^p-H{|Kk0Uz-TSZj`d+pG$g12$HD{KTw2#!~n;Xz6}c$GAlP_F|;1I2E7J!;~pTA;)z z%@j}O77EgN8g2LeD$DKUaJ>Z%1FSBPb0CG6rC7Q265I58RR5!}@$0srJButd!+hr0qp*_hep(a1^voP zhyGA7oq7?J1PrTtJI*QYHq-FiF8D>S$M3t*BH4pI8fzEM%U-8vG@@_p=QdS_(%YKP z<`=b5yoVCEBW~vpLDR5p;@n18VWk21&ju-(Y}-VywOH9|=?vZ|PU3LtlPy5Itepa_ z?E&y#)kF?vyWfmtNk_tBc6>#%hKsG(o!?G$g%ki!i;3eaR&pfiR&b>AH`oY+4DnMB zt@A4*Uynyw39GP48_8;c$C$l;#GwAR5YEv^iGUg z-^@OEC%V7*5j6_Dp>L8@htcm+tZaB~jBCw}!rtl@!bUukr?(uU#Tx3?ih%C}wqx0< zfWs{&{GTN%oeM8ZQaNBfU<+V3U@zbh;5gtM-~u4%iX`<1j0H>qOb5&XlmgZQHUoA7 zb_4bUjsZReaKKeS-)>1V01^R{0TzI*8$ap19uM0A`vLC*z6SgVxD3!CEG`NV2S^2E z0cHUf0#*aI03HSG1)KtW54Z}5yedhz0;U7z0V)9708azz0LK8I0{GSGlGKFr?ZY z?L_8*x)YH>wR6-ecE{=d2k!c4xR$klv5>9*qCA*Z0IUow@5_vksWWHH%%2@A7-q9# zl`(=mP%Y4OObRJ+z9h}AmZap9JBCHo`bi8Zk+Uk(YFGg3*@M=NP`oRa=HR!J|# zE9o5xB2~xS%-(Dss!mkieo16cG~*5?iA8-C6xL|M$ri`QIiNyZn#+ z?7}yPM}DiGJ~gMfJkMUSY~@nyU-xMWmMtlnYAddoeNT>~%)V^OI(rEldVZk(yXz?n zB=+prpY*QQ6jUs;mt-v~W2e7~WvjoLILH<-tE6}dFeQ>SRhn9M&#IE_;+0FvO4!RS z1N(gwkXK@-Ov^pXR@zG{qywL|1ghA5=f|@jza7uUpO0mS&$l{@@k>I*D+!hWN~Ge7 z3aNNi8K6R1w0JRKm9(hjUTM)XyR>Ms{lz&dHk;&N$8$zs4-z&feqo(gFh>RYyQEnuBfTDEGDREh$nsIaVf6=1DY zwxk$9={l*5@N0{umG_iO_f!;1G-lmqO5wSe`2jeyO7Er4x+?SMxCy8ycZdjNX@`vCg^b%29_dca{o z1K>E|B*1wJAEyCl0L_4NfEGY2fCJhA9e@jfEwW2Fq#6|5f)pNZ zX}b^qs1Lu}m+nPM73}k+`;pRLoi9Cz6g#w3?@Jqe=_y~n^NjD|oG)$lrR~1-0#aho z<$IR`lnOMyG}M>)V!!;VgCEk#k zk(XmwwQeP5w;^sx$=$_Rb;tCU4jlUD!zyO@KG3-`*;jN%$tn!$Qp2k9;>DE4EiPVZ zSX5#tUb)V&(y?MuNd?vCBlact+%3pURvGT8Fsz^jy}Yc%0Ia=ukzv)c`$|xiuZd;; zk`{-3m7%P75ftCBY-PA%8D7yDLm4y*)S^?&{KI#>dX)3PAU;sVnt7;dC3~9>R#z-y z54H_wv)dBK<=wNQ#BQVJt|?h*H>|0ErW-1-MG(qvD?ttA4!hxQ>k+%L|65nvGM@k|#AVnmBbm4oG z)DP)#r2UcZK{^1b9VzyAX%bTWhKm%2Gz#gtf10GhNcSR*M!Ftp4AOZ>ha&B2Mg0am zG_;zeVMtGY2h$m89MZK&BayB{szrJq(ysF+EU;(@QZlSskEkdbpb8_Isoke4rm3O1Dpn&1T;ADK?UlO)&cebb^{&-YyqqXtOeKsHo$B^HUKAj zG4$w!P=#?wyP*==;s4*@^!<@)(T#{ig()Q+pg*>yE1K=^dNgh=DCz;ELP{3Sy4O9E OX-&WuUfKhVGW{Q$hrg%* delta 26167 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 From ecad2b1e6c68d3fca31d7f9fd06678d390b00e77 Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 13:28:48 -0600 Subject: [PATCH 6/8] Indents nested preprocessor. Allows label in its own line. Tries to preserve horizontal position of comments. --- LICENSE | 22 +++++ README | 5 ++ pretty6502 | Bin 13204 -> 17612 bytes pretty6502.c | 228 ++++++++++++++++++++++++++++++++++++++++++++----- pretty6502.exe | Bin 64000 -> 67072 bytes 5 files changed, 235 insertions(+), 20 deletions(-) create mode 100644 LICENSE 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/pretty6502 b/pretty6502 index 29dcbb91516c9848912ac4af6e28bf25f286b5f4..01eaa29b384cc367a533469fcb3c4eb64e435935 100755 GIT binary patch literal 17612 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 literal 13204 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 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) diff --git a/pretty6502.exe b/pretty6502.exe index cba50a8aa7afa03f71f029d39b545bb2c3ed52fa..8872ba1c68a9d3fe5bf7d4f43981b2cfdc6209b0 100644 GIT binary patch delta 28993 zcmd_Te?XMQ_CNmYvcRf~iwcN{xGE|N83ib~VvDj!CAx?#lA@xLE20tZ`lH0vR?78} zQm5{v0qI(Li?yy^3-&DOxUx@e84KAeTCjY$Q zf=I7!cvqx+!?Pm2yx|PeS<4pNsI27svzR4mx+*}bIwalY$F)cSsy?b-l5_%?ISTg4 z2}nbw07+_Ly;Vb1CN@?zE-?C%B*n2@_0))6ze$owAyqzGBq>_8V^|bBt?q=n-umK58ICF$;=$Y=ooDZS77s-ya@r-~&NxFPxRz4 z>uONB&03JSj)H;C^GZ^~{G!HFzCZAHwQHNqT~xcLmu&75^j&gJmuu38bDRMglBD0f z1DSGum#q1G4iFYTP^rjm?v``VmVU0w;~e8*DjZY5Cobu?hnVs+Pk(q>5(APP5j+FJJXhJG4ssJdU<}aJbfL zG?qHog{oYW9!pfA(e|03m33A0lFOI&6QZI9_tckgeSOtLHw)sjaJi?t-tqt;kBiM7 zjpxav2Kk>PxSg6P=LqP3Lv;<-M)z^eiRiOJ&^1uy-};*Ba&%VsC4HRgn_S9{bR z`PyKf5~DfKRjCcoSN}sTNw#gMkoOyo&NrAWycw$LICC+wABKI}0c_7q|N>BsK( zVNVnGV?Xv!3f5_BCiEMA^hO`CCJ@+KKep6|)e^SakDcwqW)gOdA3NEHT~F9zKQ_*X z-ALFw{n-AYPNg5)2%X|bck31GVZsjeW54%d+X>stk3H?fh6Mrpo53fEH+|Sl!v4dL z-Rr~J2-_sEP6+d1A9@d=U-1*K^kq@g42DZwNo$kXfgR|_e(l315LV^Kp7dcC64rxtNodNeKJ24} z{oIe;?ZY-W3H^>A{h$whlCUrMvE@Fjt{1S(kG;!>H4wJakInR9V+p&|j~(a3&LM2B z9~%j*6IxuV;?KoMQj@ts!XMTGl}OsPBB_Js0D0U%iI_Tg0HQ;oI!TLjlbI{XeT2je zba8c>d7r*okEtW)?89V}HCy#Zw604x*@xIRQZqh4m97RF|D7R1$Y_QEI5~eGEe5*n z`Xjk2cm7`4yw}Bx-T18BJ3#+X6>5-k_UaGqIB76R-q^?XAd$`cXaNY@h>VL~?>shnk-sB1vueg14`=t_Exj|BUjn z>T*?fN$Z2~soF3M>uRoTFR{}4S$(V{LgG|Joca(ae@9$L)w%phKd1J#pGZc&Oy_oy zyTPAZ*Y?SExk_fSKl6Co!T-q2R5EL6g=>54Ke9*q%XYXbJA^DcNEZ1WvuuZ{1I}zT zS178!rw31AtHPU8K}^tx%jCPNlFT)>&-j zRO(Brgz9~|x6nT-mLQ59zrI)q6+?TE&$8{NVm1C^ww}s5F}kw(

gEj*cPJ4uDg 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 OX-&WuUfKhVGW{Q$hrg%* delta 26167 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 From ed87f868798b5d11f3d8f5bb00a00156f46f6b14 Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 13:35:29 -0600 Subject: [PATCH 7/8] Removed executables --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 97efaa5..5fbbc08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ *.DS_Store *.o +Aa* +aa* +dasm +pretty6502 +pretty6502.exe From d90a597160080f636c3ff272d8c58b555b2d6e79 Mon Sep 17 00:00:00 2001 From: nanochess Date: Mon, 6 Nov 2017 13:41:08 -0600 Subject: [PATCH 8/8] Updated version in README --- README | 2 +- pretty6502 | Bin 17612 -> 0 bytes pretty6502.exe | Bin 67072 -> 0 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100755 pretty6502 delete mode 100644 pretty6502.exe diff --git a/README b/README index 86e0aa9..6e41f26 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Pretty6502 v0.1 by Oscar Toledo G. http://nanochess.org/ +Pretty6502 v0.2 by Oscar Toledo G. http://nanochess.org/ Executables provided for Mac OS X and Windows. diff --git a/pretty6502 b/pretty6502 deleted file mode 100755 index 01eaa29b384cc367a533469fcb3c4eb64e435935..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17612 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 diff --git a/pretty6502.exe b/pretty6502.exe deleted file mode 100644 index 8872ba1c68a9d3fe5bf7d4f43981b2cfdc6209b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67072 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 bd1M{%9pFjeFz_+pB;2(?4p0I7y`KLIaWzm$