diff --git a/megademo/Makefile b/megademo/Makefile index 7fc3bd1d..e8c925d4 100644 --- a/megademo/Makefile +++ b/megademo/Makefile @@ -8,7 +8,7 @@ PNG_TO_40x96 = ../gr-utils/png_to_40x96 all: megademo.dsk megademo.dsk: MEGADEMO - $(DOS33) -y megademo.dsk BSAVE -a 0x1000 MEGADEMO + $(DOS33) -y megademo.dsk BSAVE -a 0x4000 MEGADEMO # $(DOS33) -y megademo.dsk BSAVE -a 0x2000 C64C.BIN # $(DOS33) -y megademo.dsk BSAVE -a 0x2000 C64.BIN # $(DOS33) -y megademo.dsk BSAVE -a 0x2000 C64_BW.BIN @@ -17,13 +17,15 @@ megademo.dsk: MEGADEMO #### MEGADEMO: megademo.o - ld65 -o MEGADEMO megademo.o -C ../linker_scripts/apple2_1000.inc + ld65 -o MEGADEMO megademo.o -C ../linker_scripts/apple2_4000.inc megademo.o: megademo.s \ zp.inc hardware.inc \ gr_hline.s gr_offsets.s vapor_lock.s delay_a.s wait_keypress.s \ c64_opener.s c64.img.lz4 \ - falling_apple.s apple_40_96.inc + falling_apple.s apple_40_96.inc \ + fireworks.s fw_background.inc fw_state_machine.s fw.s \ + hgr.s random16.s move_letters.s ca65 -o megademo.o megademo.s -l megademo.lst diff --git a/megademo/README b/megademo/README new file mode 100644 index 00000000..d8ff9686 --- /dev/null +++ b/megademo/README @@ -0,0 +1,14 @@ + + +Memory Map: + $0000-$0100 = ZERO PAGE + $0100-$0200 = STACK + $0400-$0800 = TEXT/GR PAGE0 + $0800-$0C00 = TEXT/GR PAGE1 + $0C00-$0fff = we use this as TEXT/GR offscreen buffer + $1000-$1fff = 4k free + $2000-$3fFF = HGR1 page ; note we never use HGR2 ($4000-$6000) + $4000-$9600 = roughly 20k(?) + $9600-$BFFF = DOS3.3 + $C000-$FFFF = peripherals/ROM + diff --git a/megademo/c64_opener.s b/megademo/c64_opener.s index 36c7eeaf..26716f62 100644 --- a/megademo/c64_opener.s +++ b/megademo/c64_opener.s @@ -29,12 +29,13 @@ c64_opener: lda #>c64 sta LZ4_SRC+1 - lda #c64_end + lda #>(c64_end-8) ; skip checksum at end sta LZ4_END+1 + lda #<$2000 sta LZ4_DST lda #>$2000 @@ -45,7 +46,6 @@ c64_opener: jsr wait_until_keypress - ;============================== ; setup graphics for vapor lock ;============================== @@ -377,7 +377,6 @@ c64: c64_end: - ;========================================================= ; DdBbbNnNnNnNnNnNnNnNnNnNn NnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNnNn Nothing ; DdBbbNnNnNnNnNnNnNnNnNnNn NnNnNnNnNnNnNnNnTtttGgggNnNnNnNnNnNnNnNn 16= 4W diff --git a/megademo/fireworks.s b/megademo/fireworks.s new file mode 100644 index 00000000..121f7a06 --- /dev/null +++ b/megademo/fireworks.s @@ -0,0 +1,399 @@ +; Display fancy Fireworks + +; HGR plus 40x48d page1/page2 every-1-scanline pageflip mode + +; Zero Page +FRAMEBUFFER = $00 ; $00 - $0F +;YPOS = $10 +FRAME = $60 +WAITING = $62 +LETTERL = $63 +LETTERH = $64 +LETTERX = $65 +LETTERY = $66 +LETTERD = $67 +LETTER = $68 +BLARGH = $69 +HGR_COLOR = $E4 +STATE = $ED +;DRAW_PAGE = $EE +LASTKEY = $F1 +PADDLE_STATUS = $F2 + + + ;================================== + ;================================== +fireworks: + + +setup_background: + + ;=================== + ; init screen + jsr TEXT + jsr HOME + jsr hgr + bit KEYRESET + +;gom: +; jmp gom + + + ;=================== + ; init vars + + lda #0 + sta DRAW_PAGE + sta STATE + sta WAITING +init_letters: + lda #letters + sta LETTERH + lda #39 + sta LETTERX + lda #22 + sta LETTERY + lda #25 + sta LETTERD + + + + ;============================= + ; Load graphic page0 + + lda #$0c + sta BASH + lda #$00 + sta BASL ; load image to $c00 + + lda #bg_final_low + sta GBASH + jsr load_rle_gr + + lda #4 + sta DRAW_PAGE + + jsr gr_copy_to_current ; copy to page1 + + ; GR part + bit PAGE1 + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + +; jsr wait_until_keypressed + + + ;============================= + ; Load graphic page1 + + lda #$0c + sta BASH + lda #$00 + sta BASL ; load image to $c00 + + lda #bg_final_high + sta GBASH + jsr load_rle_gr + + lda #0 + sta DRAW_PAGE + + jsr gr_copy_to_current + + ; GR part + bit PAGE0 + +; jsr wait_until_keypressed + + + ;============================== + ; setup graphics for vapor lock + ;============================== + + jsr vapor_lock ; 6 + + ; vapor lock returns with us at beginning of hsync in line + ; 114 (7410 cycles), so with 5070 lines to go + + ; so we have 5070 + 4550 = 9620 to kill + + jsr gr_copy_to_current ; 6+ 9292 + + ; now we have 322 left + + ; GR part + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + + ; 322 - 12 = 310 + ; - 3 for jmp + ; 307 + + ; Try X=9 Y=6 cycles=307 + + ldy #6 ; 2 +fwloopA:ldx #9 ; 2 +fwloopB:dex ; 2 + bne fwloopB ; 2nt/3 + dey ; 2 + bne fwloopA ; 2nt/3 + + jmp fw_display_loop ; 3 +.align $100 + + + ;================================================ + ; Display Loop + ;================================================ + ; each scan line 65 cycles + ; 1 cycle each byte (40cycles) + 25 for horizontal + ; Total of 12480 cycles to draw screen + ; Vertical blank = 4550 cycles (70 scan lines) + ; Total of 17030 cycles to get back to where was + + ; We want to alternate between page1 and page2 every 65 cycles + ; vblank = 4550 cycles to do scrolling + + + ; 2 + 48*( (4+2+25*(2+3)) + (4+2+23*(2+3)+4+5)) + 9) + ; 48*[(6+125)-1] + [(6+115+10)-1] + +fw_display_loop: + + ;=================================== + ; HIRES PAGE0 for the top 152 lines + ;=================================== + + ; 152 * 65 = 9880 + ; -12 for HIRES/PAGE0 at top + ; -5 for LORES+ldy+br fallthrough at bottom + ; -132 for move_letters + ; 9731 + + bit HIRES ; 4 + bit PAGE0 ; 4 + bit FULLGR ; 4 + ;=========== + ; 12 + jsr move_letters ; 6+126 + + ; Try X=242 Y=8 cycles=9729 R2 + + nop ; 2 + + + ldy #8 ; 2 +hgloop1:ldx #242 ; 2 +hgloop2:dex ; 2 + bne hgloop2 ; 2nt/3 + dey ; 2 + bne hgloop1 ; 2nt/3 + + bit LORES ; 4 + + + ;==================================================== + ; LORES PAGE0/PAGE1 alternating for the next 24 lines + ;==================================================== + + + ldy #12 ; *2=24 lines ; 2 + + ; we set PAGE0 (4) then want to NOP (61) for a total of 65 +bouter_loop: + bit PAGE0 ; 4 + ldx #12 ; 65 cycles with PAGE0 ; 2 +bpage0_loop: ; delay 61+bit + dex ; 2 + bne bpage0_loop ; 2/3 + ;============= + ; 6+(12*5)-1=65 + + ; we set PAGE1 (4) as well as dey (2) and bne (3) then nop (55) + ; + + bit PAGE1 ; 4 + ldx #11 ; 65 cycles with PAGE1 ; 2 +bpage1_loop: + dex ; 2 + bne bpage1_loop ; 2/3 + ;============= + ; 6+(11*5)-1=60 + + dey ; 2 + bne bouter_loop ; 2/3 + ;============== + ; 5 to make 65 + + + + ;========================================================= + ; LORES PAGE0/PAGE1+TEXT alternating for the next 16 lines + ;========================================================= + + + ldy #8 ; *2=16 lines ; 2 + + ; we set PAGE0 (4) then want to NOP (61) for a total of 65 +couter_loop: + bit FULLGR ; 4 + bit PAGE0 ; 4 + ldx #5 ; 2 +cpage0_loop: + dex ; 2 + bne cpage0_loop ; 2/3 + ;============= + ; 10+(5*5)-1=34 + bit $1000 ; 4 + bit $1000 ; 4 + bit TEXTGR ; 4 + bit $1000 ; 4 + bit $1000 ; 4 + bit $1000 ; 4 + bit $1000 ; 4 + lda DRAW_PAGE ; 3 + + ; we set PAGE1 (4) as well as dey (2) and bne (3) then nop (55) + ; + + bit FULLGR ; 4 + bit PAGE1 ; 4 + ldx #5 ; 2 +cpage1_loop: + dex ; 2 + bne cpage1_loop ; 2/3 + ;============= + ; 10+(5*5)-1=34 + + bit $1000 ; 4 + bit $1000 ; 4 + bit TEXTGR ; 4 + + bit $1000 ; 4 + lda DRAW_PAGE ; 3 + nop ; 2 + lda DRAW_PAGE ; 3 + nop ; 2 + + dey ; 2 + bne couter_loop ; 2/3 + ;============== + ; 5 to make 65 + + + + ;====================================================== + ; We have 4550 cycles in the vblank, use them wisely + ;====================================================== + ; 4550 + ; +1 fallthrough + ; -2 for ldy in previous + ; -35 call through jumptable + ; -7 keyboard + ; -3 jmp + ; ======== + ; 4504 + ;======================== + ; each subunit should take 4504 cycles + +firework_state_machine: + + ; if killing time, 16+19 = 35 + ; if not, 16+19 = 35 + + ldy STATE ; 3 + inc FRAME ; 5 + lda FRAME ; 3 + and #$3 ; 2 + beq kill_time ; 3 + ;=========== + ; 16 + + + ; Set up jump table that runs same speed on 6502 and 65c02 + ;-1 + lda jump_table+1,y ; 4 + pha ; 3 + lda jump_table,y ; 4 + pha ; 3 + rts ; 6 + + ;============= + ; 19 + +kill_time: + + ; need 16 cycles nop + ldy STATE ; (nop) ; 3 + ldy STATE ; (nop) ; 3 + ldy STATE ; (nop) ; 3 + ldy STATE ; (nop) ; 3 + nop ; 2 + nop ; 2 + jmp action_stars ; 3 + + ;============= + ; 19 + +fw_check_keyboard: + + lda KEYPRESS ; 4 + bpl fw_no_keypress ; 3 + jmp restart +fw_no_keypress: + + jmp fw_display_loop ; 3 + + + ; Restart and toggle sound +restart: + ; self mofifying code, flip from bit C030 to bit 0030 + lda sound1+2 + eor #$C0 + sta sound1+2 + +; lda sound2+2 +; eor #$C0 +; sta sound2+2 + + lda sound3+2 + eor #$C0 + sta sound3+2 + + jmp setup_background + + +jump_table: + .word (action_launch_firework-1) + .word (action_move_rocket-1) + .word (action_start_explosion-1) + .word (action_continue_explosion-1) + .word (action_stall_rocket-1) + + + +.include "fw_state_machine.s" +.include "fw.s" + +;.include "gr_hline.s" +;.include "../asm_routines/gr_unrle.s" +;.include "../asm_routines/keypress.s" +;.include "gr_copy.s" +;.include "random16.s" + +;.include "hgr.s" +;.include "vapor_lock.s" +;.include "move_letters.s" +;.include "delay_a.s" + +background: + +.include "fw_background.inc" diff --git a/megademo/fw.s b/megademo/fw.s new file mode 100644 index 00000000..29d3b8c6 --- /dev/null +++ b/megademo/fw.s @@ -0,0 +1,843 @@ +;======================================================================= +; Based on BASIC program posted by FozzTexx, originally written in 1987 +;======================================================================= + +; State: +; 0: Launch Rocket -> goes to 1 +; 1: Move Rocket -> repeats 1 until CS done, then 2 +; 2: Start Explosion -> goes to 3 +; 3: Continue Explosion -> repeats 3 until done. +; then randomly might go to 2 +; before going to 0 + + +STATE_LAUNCH_ROCKET = 0 +STATE_MOVE_ROCKET = 2 +STATE_START_EXPLOSION = 4 +STATE_CONTINUE_EXPLOSION = 6 +STATE_STALL_ROCKET = 8 + +; Constants +NUMSTARS = 16 +YSIZE = 160 +XSIZE = 280 +MARGIN = 24 + +; Zero page addresses +;STATE = $ED +OFFSET = $EF +COLOR_GROUP = $F0 +X_VELOCITY = $F1 +Y_VELOCITY_H = $F2 +Y_VELOCITY_L = $F3 +MAX_STEPS = $F4 +XPOS_H = $F5 +XPOS_L = $F6 +YPOS_H = $F7 +YPOS_L = $F8 +PEAK = $F9 +CURRENT_STEP = $FA +Y_OLD = $FB +Y_OLDER = $FC +X_OLD = $FD +X_OLDER = $FE +FWTEMP = $FF + +.align $100 + + ;=========================== + ; LAUNCH_FIREWORK + ;=========================== + ; cycles= 60+60+67+60+56+56+15+8+21+11 = 414 + +launch_firework: + +sound1: + bit SPEAKER ; 4 + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$4 ; 2 + sta COLOR_GROUP ; HGR color group (0 PG or 4 BO) ; 3 + ;============ + ; 60 + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$3 ; 2 + clc ; 2 + adc #$1 ; 2 + sta X_VELOCITY ; x velocity = 1..4 ; 3 + ;=========== + ; 60 + + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$3 ; 2 + clc ; 2 + adc #$2 ; 2 + eor #$ff ; 2 + sta Y_VELOCITY_H ; y velocity = -3..-6 ; 3 + lda #0 ; 2 + sta Y_VELOCITY_L ; it's 8:8 fixed point ; 3 + ;============ + ; 67 + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$1f ; 2 + clc ; 2 + adc #33 ; 2 + sta MAX_STEPS ; 33..64 ; 3 + ;============ + ; 60 + + ; launch from the two hills + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$3f ; 2 + sta XPOS_L ; base of 0..63 ; 3 + ;============ + ; 56 + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$1 ; 2 + + beq right_hill ; 3 + ;============ + ; 56 + + + +left_hill: ;-1 + lda X_VELOCITY ; nop ; 3 + lda X_VELOCITY ; nop ; 3 + lda X_VELOCITY ; nop ; 3 + nop ; 2 + lda #24 ; make it 24..87 ; 2 + jmp done_hill ; 3 + ;=========== + ; 15 + +right_hill: + lda X_VELOCITY ; 3 + eor #$ff ; 2 + sta X_VELOCITY ; 3 + inc X_VELOCITY ; aim toward middle ; 5 + + lda #191 ; make it 191..254 ; 2 + ;=========== + ; 15 + +done_hill: + clc ; 2 + adc XPOS_L ; 3 + sta XPOS_L ; 3 + + ;=========== + ; 8 + + lda #YSIZE ; 2 + sta YPOS_H ; 3 + lda #0 ; fixed point 8:8 ; 2 + sta YPOS_L ; start at ground ; 3 + + lda YPOS_H ; 3 + sta PEAK ; peak starts at ground ; 3 + + lda #1 ; 2 + sta CURRENT_STEP ; 3 + ;=========== + ; 21 + + lda #STATE_MOVE_ROCKET ; 2 + sta STATE ; move to launch ; 3 + + rts ; 6 + ;============ + ; 11 + + +.align $100 + +;========================================================================== +; Move rocket +;========================================================================== +; cycles=24+11+20+18+14+53 = 140+1096 = 1236 + +move_rocket: + + ; save old values + lda Y_OLD ; 3 + sta Y_OLDER ; 3 + lda YPOS_H ; 3 + sta Y_OLD ; 3 + lda X_OLD ; 3 + sta X_OLDER ; 3 + lda XPOS_L ; 3 + sta X_OLD ; 3 + ;=========== + ; 24 + + ; Move xpos + lda XPOS_L ; 3 + clc ; 2 + adc X_VELOCITY ; 3 + sta XPOS_L ; 3 + ;============ + ; 11 + ; Move ypos, 16-bit add + clc ; 2 + lda YPOS_L ; 3 + adc Y_VELOCITY_L ; 3 + sta YPOS_L ; 3 + lda YPOS_H ; 3 + adc Y_VELOCITY_H ; 3 + sta YPOS_H ; 3 + ;=========== + ; 20 + + ; adjust Y velocity, slow it down + clc ; 2 + lda Y_VELOCITY_L ; 3 + adc #$20 ; $20 = 0.125 ; 2 + sta Y_VELOCITY_L ; 3 + lda Y_VELOCITY_H ; 3 + adc #0 ; 2 + sta Y_VELOCITY_H ; 3 + ;=========== + ; 18 + ; if we went higher, adjust peak + lda YPOS_H ; 3 + cmp PEAK ; 3 + bcc no_peak_nop ; blt ; 3 + + ;-1 + sta PEAK ; 3 + jmp no_peak ; 3 +no_peak_nop: + nop ; 2 + jmp no_peak ; 3 +no_peak: + ;============= + ; 14 + + ;======================================== + ; Check if out of bounds and stop moving + ;======================================== + ; bcc = 8+7+12+20+6 = 53 + ; bcs/bcc = 8+7+12+20+6 = 53 + ; bcs/bcs/bmi = 8+7+5+33 = 53 + ; bcs/bcs/bpl/bcs = 8+7+5+7+20+6 = 53 + ; bcs/bcs/bpl/bcc/bcc = 8+7+5+7+20+6 = 53 + ; bcs/bcs/bpl/bcc/bcs = 8+7+5+7+20+6 = 53 + + lda XPOS_L ; if (xpos_l<=margin) too far left ; 3 + cmp #MARGIN ; 2 + bcc done_moving_first ; 3 + ;=========== + ; 8 + + ; Due to 256 wraparound, the above will catch this case??? +; cmp #XSIZE-MARGIN ; if (xpos_l>=(xsize-margin)) too far right +; bcs done_moving + + ; -1 + lda YPOS_H ; if (ypos_h<=margin) too far up ; 3 + cmp #MARGIN ; 2 + bcc done_moving_second ; 3 + ;=========== + ; 7 + ;====================== + ; if falling downward + ;====================== + ; -1 + lda Y_VELOCITY_H ; 3 + bmi going_up ; if (y_velocity_h>0) ; 3 + ;============ + ; 5 + + ; if too close to ground, explode ; -1 + lda YPOS_H ; if (ypos_h>=ysize-margin) ; 3 + cmp #(YSIZE-MARGIN) ; 2 + bcs done_moving_third ; 3 + ;============ + ; 7 + + ; if fallen a bit past peak, explode ; -1 + sec ; if (ypos_h>ysize-(ysize-peak)/2) ; 2 + lda #YSIZE ; 2 + sbc PEAK ; 3 + lsr ; 2 + eor #$FF ; 2 + sec ; 2 + adc #YSIZE ; 2 + cmp YPOS_H ; 3 + bcc done_moving ; 3 + ;=========== + ; 20 + + + ;-1 +done_moving_ft: + nop ; 2 + nop ; 2 + jmp done_bounds_checking ; 3 + ;=========== + ; 6 + +going_up: + ; 33 cycles + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + nop ; 2 + jmp done_moving_ft ; 3+7 + +done_moving_first: + ; 7 cycles + lda MAX_STEPS ; 3 + nop ; 2 + nop ; 2 +done_moving_second: + ; 12 cycles + lda MAX_STEPS ; 3 + nop ; 2 + lda MAX_STEPS ; 3 + nop ; 2 + nop ; 2 +done_moving_third: + ; 20 cycles + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + lda MAX_STEPS ; 3 + nop ; 2 +done_moving: + lda MAX_STEPS ; 3 + sta CURRENT_STEP ; 3 + ;============ + ; 6 +done_bounds_checking: + + +;======================================================================= +; draw rocket +;======================================================================= +; +; cs!=mx 9+15+258+258+3+10+258+258+9+7+11 = 1096 +; cs==mx 9+ + + + +10+258+258+9+7+11 = 562 (need 534) +draw_rocket: + + lda CURRENT_STEP ; 3 + cmp MAX_STEPS ; 3 + beq skip_drawing_rocket ; 3 + ;=========== + ; 9 + + ; set hcolor to proper white (3 or 7) + ;-1 + clc ; 2 + lda COLOR_GROUP ; 3 + adc #3 ; 2 + tax ; 2 + lda colortbl,X ; get color from table ; 4+ + sta HGR_COLOR ; 3 + ;============ + ; 15 + ; HPLOT X,Y: X= (y,x), Y=a + + ldx X_OLD ; 3 + lda Y_OLD ; 3 + ldy #0 ; 2 + jsr hplot0 ; hplot(x_old,y_old); ;6+244 + ;============= + ; 258 + + ; HPLOT TO X,Y X=(x,a), y=Y + ldx XPOS_L ; 3 + ldy #0 ; 2 + lda YPOS_H ; 3 + jsr hplot0 ;6+244 + ;============= + ; 258 + +; lda XPOS_L ; 3 +; ldx #0 ; 2 +; ldy YPOS_H ; 3 +; jsr hglin ; hplot_to(xpos_l,ypos_h); ;????? + + + jmp erase_rocket ; 3 + +skip_drawing_rocket: + ; Try X=7 Y=13 cycles=534 + ldy #13 ; 2 +sdloop1:ldx #7 ; 2 +sdloop2:dex ; 2 + bne sdloop2 ; 2nt/3 + dey ; 2 + bne sdloop1 ; 2nt/3 + +erase_rocket: + ; erase with proper color black (0 or 4) + + ldx COLOR_GROUP ; 3 + lda colortbl,X ; get color from table ; 4+ + sta HGR_COLOR ; 3 + ;=========== + ; 10 + ; HPLOT X,Y: X= (y,x), Y=a + + ldx X_OLDER ; 3 + lda Y_OLDER ; 3 + ldy #0 ; 2 + jsr hplot0 ; hplot(x_old,y_old); ; 6+244 + ;============ + ; 258 + + ; HPLOT TO X,Y X=(x,a), y=Y + + ldx X_OLD ; 3 + ldy #0 ; 2 + lda Y_OLD ; 3 + jsr hplot0 ;6+244 + ;============= + ; 258 +; lda X_OLD +; ldx #0 +; ldy Y_OLD +; jsr hglin ; hplot_to(x_old,y_old); + +done_with_loop: + + lda CURRENT_STEP ; 3 + cmp MAX_STEPS ; 3 + bne not_done_with_launch ; 3 + ;============= + ; 9 + + ;-1 + lda #STATE_START_EXPLOSION ; 2 + sta STATE ; 3 + jmp not_done_with_launch2 ; 3 + ;========== + ; 7 + +not_done_with_launch: + lda #STATE_STALL_ROCKET ; 2 + sta STATE ; 3 + nop ; 2 + ;========== + ; 7 +not_done_with_launch2: + + inc CURRENT_STEP ; 5 + rts ; 6 + ;=========== + ; 11 + +.align $100 + +;====================================================================== +; Start explosion near x_old, y_old +;====================================================================== +; cycles = 67+16+63+16+258+20 = 440 +; + +start_explosion: + + ; Set X position + + lda #0 ; 2 + sta XPOS_H ; 3 + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$f ; 0..15 ; 2 + sec ; 2 + sbc #8 ; -8..7 ; 2 + clc ; 2 + bmi signextend_neg ; 3 + ;============ + ; 67 + + ;-1 + adc X_OLD ; 3 + sta XPOS_L ; xpos=x_old+(random()%16)-8; x +/- 8 ; 3 + + lda #0 ; 2 + adc XPOS_H ; 3 + sta XPOS_H ; 3 + + jmp exp_sub_done ; 3 + ;=========== + ; 16 +signextend_neg: + + adc X_OLD ; 3 + sta XPOS_L ; xpos=x_old+(random()%16)-8; x +/- 8 ; 3 + + lda #$ff ; 2 + adc XPOS_H ; 3 + sta XPOS_H ; 3 + nop ; 2 + ;=========== + ; 16 + +exp_sub_done: + + ; set Y position + + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$f ; 0..15 ; 2 + sec ; 2 + sbc #8 ; -8..7 ; 2 + adc Y_OLD ; 3 + sta YPOS_H ; ypos_h=y_old+(random()%16)-8; y +/- 8 ; 3 + ;============ + ; 63 + + ; draw white (with fringes) + + lda COLOR_GROUP ; 3 + clc ; 2 + adc #$3 ; 2 + tax ; 2 + lda colortbl,X ; get color from table ; 4+ + sta HGR_COLOR ; 3 + ;=========== + ; 16 + + ; hplot(xpos,ypos_h); draw at center of explosion + + ; HPLOT X,Y: X= (y,x), Y=a + + ldx XPOS_L ; 3 + lda YPOS_H ; 3 + ldy #0 ; never above 255 ; 2 + jsr hplot0 ; hplot(x_old,y_old); ; 6+244 + ;============== + ; 258 + ; Make sound and ready explosion + +sound3: + bit SPEAKER ; 4 + + ldy #1 ; 2 + sty FWTEMP ; save Y ; 3 + + ; move to continue explosion + lda #STATE_CONTINUE_EXPLOSION ; 2 + + sta STATE ; 3 + + rts ; 6 + ;============= + ; 20 + +;========================================================================== +; Continue Explosion +;========================================================================== +; +; cycles cpy!=9 : 8+2233+2227+13+5 = 4486 +; cpy==9 : 8+ +2227+13+62 = 2310 waste 2176 + +continue_explosion: + ldy FWTEMP ; 3 + + ;================================ + ; Draw spreading dots in white + + cpy #9 ; 2 + beq explosion_erase_waste ; 3 + ;=========== + ; 8 + + + ; -1 + ; hcolor_equals(color_group+3); + lda COLOR_GROUP ; 3 + clc ; 2 + adc #$3 ; 2 + tax ; 2 + lda colortbl,X ; get color from table ; 4+ + sta HGR_COLOR ; 3 + + ldx FWTEMP ; 3 + stx OFFSET ; 3 + + jsr explosion ; 6+2203 + + jmp explosion_erase ; 3 + ;============ + ; 2233 +explosion_erase_waste: + ; waste 2176-4 = 2172 + +sound2: +; bit SPEAKER ; 4 + nop + nop + + ; Try X=47 Y=9 cycles=2170 R2 + + nop ; 2 + + ldy #9 ; 2 +eeloop1:ldx #47 ; 2 +eeloop2:dex ; 2 + bne eeloop2 ; 2nt/3 + dey ; 2 + bne eeloop1 ; 2nt/3 + + + +explosion_erase: + ;====================== + ; erase old + + ; erase with proper color black (0 or 4) + + ldx COLOR_GROUP ; 3 + lda colortbl,X ; get color from table ; 4+ + sta HGR_COLOR ; 3 + + ldx FWTEMP ; 3 + dex ; 2 + stx OFFSET ; 3 + + jsr explosion ; 6+2203 + ;============== + ; 2227 +done_with_explosion: + +; lda #$c0 ; +; jsr WAIT ; + + inc FWTEMP ; 5 + lda FWTEMP ; 3 + cmp #10 ; 2 + beq explosion_done ; 3 + ;============= + ; 13 + + ; -1 + rts ; 6 + +explosion_done: + ;================================== + ; randomly draw more explosions + ;================================== + jsr random16 ; 6+42 + lda SEEDL ; 3 + and #$4 ; 2 + sta STATE ; 3 + + ; if 0, then move to state 0 (start over) + ; if 1, then move to state 4 (new random explosion) + + rts ; 6 + ;============ + ; 62 + + +.align $100 + + ;=============================== + ; Draw explosion rays + ;=============================== + ; + ; Note: the western pixels don't do the full 16-bit math + ; as currently it's not possible for those to overflow 256 + ; + ; cycles = 275+275+270+270+272+278+278+279+6=2203 + +explosion: + + ; HPLOT X,Y: X= (y,x), Y=a + + ; Southeast pixel + clc ; 2 + lda XPOS_L ; 3 + adc OFFSET ; 3 + tax ; 2 + lda XPOS_H ; 3 + adc #0 ; 2 + tay ; 2 + clc ; 2 + lda YPOS_H ; 3 + adc OFFSET ; 3 + jsr hplot0 ; hplot(xpos+o,ypos_h+o); ; 6+244 + ;============== + ; 275 + + ; Northeast Pixel + clc ; 2 + lda XPOS_L ; 3 + adc OFFSET ; 3 + tax ; 2 + lda XPOS_H ; 3 + adc #0 ; 2 + tay ; 2 + sec ; 2 + lda YPOS_H ; 3 + sbc OFFSET ; 3 + jsr hplot0 ; hplot(xpos+o,ypos_h-o); ; 6+244 + ;============== + ; 275 + + ; Northwest Pixel + sec ; 2 + lda XPOS_L ; 3 + sbc OFFSET ; 3 + tax ; 2 + ldy #0 ; 2 + sec ; 2 + lda YPOS_H ; 3 + sbc OFFSET ; 3 + jsr hplot0 ; hplot(xpos-o,ypos_h-o); NW ; 6+244 + ;============== + ; 270 + + ; Southwest Pixel + sec ; 2 + lda XPOS_L ; 3 + sbc OFFSET ; 3 + tax ; 2 + ldy #0 ; 2 + clc ; 2 + lda YPOS_H ; 3 + adc OFFSET ; 3 + jsr hplot0 ; hplot(xpos-o,ypos_h+o); SW ; 6+244 + ;============= + ; 270 + + ; HPLOT X,Y: X= (y,x), Y=a + + ; South Pixel + ldx XPOS_L ; 3 + ldy XPOS_H ; 3 + clc ; 2 + lda OFFSET ; 3 + adc OFFSET ; 3 + adc OFFSET ; 3 + lsr ; 2 + adc YPOS_H ; 3 + jsr hplot0 ; hplot(xpos,ypos_h+(o*1.5)); S ; 6+244 + ;============= + ; 272 + + ; North Pixel + ldx XPOS_L ; 3 + ldy XPOS_H ; 3 + clc ; O O*1.5 NEG ; 2 + lda OFFSET ; 0 = 0 0 ; 3 + adc OFFSET ; 1 = 1 -1 ; 3 + adc OFFSET ; 2 = 3 -3 ; 3 + lsr ; 3 = 4 -4 ; 2 + eor #$FF ; 4 = 6 -6 ; 2 + clc ; 2 + adc #1 ; 2 + adc YPOS_H ; 3 + jsr hplot0 ; hplot(xpos,ypos_h-(o*1.5)); N ; 6+244 + ;============== + ; 278 + + ; HPLOT X,Y: X= (y,x), Y=a + + ; East Pixel + clc ; 2 + lda OFFSET ; 3 + adc OFFSET ; 3 + adc OFFSET ; 3 + lsr ; 2 + adc XPOS_L ; 3 + tax ; 2 + lda #0 ; 2 + adc XPOS_H ; 3 + tay ; 2 + lda YPOS_H ; 3 + jsr hplot0 ; hplot(xpos+(o*1.5),ypos_h); E ; 6+244 + ;============== + ; 278 + + ; West Pixel + clc ; O O*1.5 NEG ; 2 + lda OFFSET ; 0 = 0 0 ; 3 + adc OFFSET ; 1 = 1 -1 ; 3 + adc OFFSET ; 2 = 3 -3 ; 3 + lsr ; 3 = 4 -4 ; 2 + eor #$FF ; 4 = 6 -6 ; 2 + clc ; 2 + adc #1 ; 2 + adc XPOS_L ; 3 + tax ; 2 + ldy #0 ; 2 + lda YPOS_H ; 3 + jsr hplot0 ; hplot(xpos-(o*1.5),ypos_h); W ; 6+244 + ;============== + ; 279 + + rts ; 6 + + + +;========================================================================= +; Draw the stars +;========================================================================= +; 7+ 280X + 5 +; 16 stars = 4492 + + +.align $100 +draw_stars: + ; HCOLOR = 3, white (though they are drawn purple) + lda #$7f ; 2 + sta HGR_COLOR ; 3 + ldy #0 ; 2 + ;=========== + ; 7 + +star_loop: + tya ; 2 + pha ; 3 + + ; HPLOT X,Y + ; X= (y,x), Y=a + + ldx stars,Y ; 4+ + lda stars+1,Y ; 4+ + ldy #0 ; 2 + + jsr hplot0 ;6+244 + + pla ; 4 + tay ; 2 + + iny ; 2 + iny ; 2 + cpy #NUMSTARS*2 ; 2 + + bne star_loop ; 3 + ;============ + ; 279 + + ; -1 + rts ; 6 + +stars: ; even x so they are purple + .byte 28,107, 108, 88, 126, 88, 136, 95 + .byte 150,108, 148,120, 172,124, 180,109 + .byte 216, 21, 164, 40, 124, 18, 60, 12 + .byte 240,124, 94,125, 12, 22, 216,116 + diff --git a/megademo/fw_background.inc b/megademo/fw_background.inc new file mode 100644 index 00000000..cc7fe59e --- /dev/null +++ b/megademo/fw_background.inc @@ -0,0 +1,12 @@ +bg_final_low: .byte $28 ; ysize=48 + .byte $A0,$FF,$22, $A0,$FF,$22, $A0,$FA,$22, $A0,$28,$20, $21, $01,$01, $A8,$00 + .byte $01,$01, $AE,$21, $01,$01, $A9,$00, $01,$01, $AE,$00, $01 + .byte $A9,$11, $01, $A0,$1F,$00, $01, $A5,$91, $01, $A0,$23,$00 + .byte $A3,$0D, $A0,$13,$00 + .byte $A1 +bg_final_high: .byte $28 ; ysize=48 + .byte $A0,$FF,$22, $A0,$FF,$22, $A0,$FA,$22, $A0,$28,$55, $B2, $02,$02, $A8,$00 + .byte $02,$02, $AE,$B2, $02,$02, $A9,$00, $02,$02, $AE,$00, $0B + .byte $A9,$1B, $0B, $A0,$1F,$00, $09, $A5,$D9, $09, $A0,$23,$00 + .byte $A3,$0D, $A0,$13,$00 + .byte $A1 diff --git a/megademo/fw_state_machine.s b/megademo/fw_state_machine.s new file mode 100644 index 00000000..89497c2a --- /dev/null +++ b/megademo/fw_state_machine.s @@ -0,0 +1,128 @@ + ;================================= + ; action_stars + ;================================= + ; and take 4504 cycles to do it + + ; we take 4501, so waste 3 +action_stars: + + jsr draw_stars ; 6+4492 = 4498 + + ldy FRAME ;nop ; 3 + + jmp fw_check_keyboard ; 3 + + + ;================================= + ; action_launch_firework + ;================================= + ; and take 4504 cycles to do it + + ; we take 423 so waste 4081 +action_launch_firework: + + ; Try X=26 Y=30 cycles=4081 + + ldy #30 ; 2 +Xloop1: ldx #26 ; 2 +Xloop2: dex ; 2 + bne Xloop2 ; 2nt/3 + dey ; 2 + bne Xloop1 ; 2nt/3 + + jsr launch_firework ; 6+414 = 420 + + jmp fw_check_keyboard ; 3 + + + ;================================= + ; action_move_rocket + ;================================= + ; and take 4504 cycles to do it + + ; we take 1245 so waste 3259 +action_move_rocket: + + ; Try X=35 Y=18 cycles=3259 + + ldy #18 ; 2 +Yloop1: ldx #35 ; 2 +Yloop2: dex ; 2 + bne Yloop2 ; 2nt/3 + dey ; 2 + bne Yloop1 ; 2nt/3 + + jsr move_rocket ; 6+1236 = 1242 + + jmp fw_check_keyboard ; 3 + + + ;================================= + ; action_start_explosion + ;================================= + ; and take 4504 cycles to do it + + ; we take 449 so waste 4055 +action_start_explosion: + + ; Try X=15 Y=50 cycles=4051 R4 + + nop + nop + + ldy #50 ; 2 +Zloop1: ldx #15 ; 2 +Zloop2: dex ; 2 + bne Zloop2 ; 2nt/3 + dey ; 2 + bne Zloop1 ; 2nt/3 + + jsr start_explosion ; 6+440 = 446 + + jmp fw_check_keyboard ; 3 + + + ;================================= + ; action_continue_explosion + ;================================= + ; and take 4504 cycles to do it + + ; we take 4495 so waste 9 +action_continue_explosion: + lda STATE ; nop 3 + lda STATE ; nop 3 + lda STATE ; nop 3 + + jsr continue_explosion ; 6+4486 = 4492 + + jmp fw_check_keyboard ; 3 + + + + + ;================================= + ; action_stall_rocket + ;================================= + ; and take 4504 cycles to do it + + ; 4504 - 8 = 4496 +action_stall_rocket: + + lda #STATE_MOVE_ROCKET ; 2 + sta STATE ; 3 + + + ; Try X=12 Y=68 cycles=4489 R7 + nop ; + nop ; + lda STATE ;3 + + ldy #68 ; 2 +Bloop1: ldx #12 ; 2 +Bloop2: dex ; 2 + bne Bloop2 ; 2nt/3 + dey ; 2 + bne Bloop1 ; 2nt/3 + + jmp fw_check_keyboard ; 3 + diff --git a/megademo/hgr.s b/megademo/hgr.s new file mode 100644 index 00000000..835bd407 --- /dev/null +++ b/megademo/hgr.s @@ -0,0 +1,280 @@ + +HGR_SHAPE = $1A +HGR_SHAPE_H = $1B +HGR_BITS = $1C +HGR_COUNT = $1D + +HMASK = $30 + +DSCTMP = $9D + +HGR_DX = $D0 +HGR_DX_H = $D1 +HGR_DY = $D2 +HGR_QUADRANT = $D3 +HGR_E = $D4 +HGR_E_H = $D5 +HGR_X = $E0 +HGR_X_H = $E1 +HGR_Y = $E2 +;HGR_COLOR = $E4 +HGR_HORIZ = $E5 +HGR_PAGE = $E6 + + +TXTCLR = $C050 +MIXSET = $C053 +LOWSCR = $C054 +MIXCLR = $C052 +HISCR = $C055 + + +.align $100 + + ;========================== + ; HGR + ;========================== +hgr: + ; F3E2 + lda #$20 ; HIRES Page 1 at $2000 + bit LOWSCR ; BIT SW.LOWSCR Use PAGE1 ($C054) + bit MIXSET ; BIT SW.MIXSET (Mixed text) +sethpg: + ; F3EA + sta HGR_PAGE + lda HIRES + lda TXTCLR +hclr: + lda #0 ; black background + sta HGR_BITS +bkgnd: + ; F3F6 + lda HGR_PAGE + sta HGR_SHAPE+1 + ldy #0 + sty HGR_SHAPE +bkgnd_loop: + lda HGR_BITS + + sta (HGR_SHAPE),y + + jsr color_shift + + iny + bne bkgnd_loop + + inc HGR_SHAPE+1 + lda HGR_SHAPE+1 + and #$1f ; see if $40 or $60 + bne bkgnd_loop + rts + + +msktbl: .byte $81,$82,$84,$88,$90,$A0,$C0 ; original + + ;==================================================== + ; HPOSN + ; time = 9 + 61 + 31 + 22 + 42 + 22 + 23 = 210 + +hposn: + ; F411: move values into expected zp locations + sta HGR_Y ; 3 + stx HGR_X ; 3 + sty HGR_X+1 ; 3 + ;=========== + ; 9 + + ; calc y-position addr. no lookup table? + pha ; 3 + and #$C0 ; 2 + sta GBASL ; 3 + lsr ; 2 + lsr ; 2 + ora GBASL ; 3 + sta GBASL ; 3 + pla ; 4 + sta GBASH ; 3 + asl ; 2 + asl ; 2 + asl ; 2 + rol GBASH ; 5 + asl ; 2 + rol GBASH ; 5 + asl ; 2 + ror GBASL ; 5 + lda GBASH ; 3 + and #$1f ; 2 + ora HGR_PAGE ; 3 + sta GBASH ; 3 + ;============ + ; 61 + ; F438 + ; divide/mod 16-bit x poisition by 7 + ; incoming, X=(y,x) + ; outgoing y=q, a=r + + ; Divide by 7 (From December '84 Apple Assembly Line) + + txa ; 2 + clc ; 2 + sta HGR_HORIZ ; 3 + lsr ; 2 + lsr ; 2 + lsr ; 2 + adc HGR_HORIZ ; 3 + ror ; 2 + lsr ; 2 + lsr ; 2 + adc HGR_HORIZ ; 3 + ror ; 2 + lsr ; 2 + lsr ; 2 + ; x/7 is in A + ;============ + ; 31 + ; calculate remainder + clc ; 2 + sta HGR_HORIZ ; 3 + asl ; 2 + adc HGR_HORIZ ; 3 + asl ; 2 + adc HGR_HORIZ ; 3 + ; HGR_HORIZ=x/7, A=HGR_HORIZ*7 + ; calculate remainder by X-(Q*7) + sec ; 2 + eor #$ff ; 2 + adc HGR_X ; 3 + ; A = remainder ;=========== + ; 22 +;============================================================================ + + cpy #0 ; 2 + beq done_mod_nop_23 ; 3 + ;========== + ; 5 +theres_high: + ; -1 + clc ; 2 + adc #4 ; make remainder match ; 2 + pha ; 3 + lda HGR_HORIZ ; 3 + adc #36 ; 2 + sta HGR_HORIZ ; 3 + pla ; 4 + + cmp #7 ; 2 + bcc done_mod_nop14 ; blt ; 3 + ;============ + ; 23 + + + ; -1 + sec ; 2 + sbc #7 ; 2 + inc HGR_HORIZ ; 5 + ldy HGR_HORIZ ; nop ; 3 + jmp done_mod ; 3 + ;============ + ; 14 + ;=========================== + ; Y=HIGH,bcc = 5+23+ 14 = 42 + ; Y=HIGH,bcs = 5+23+ 14 = 42 + ; Y=LOW = 5 + 14+23 = 42 + +done_mod_nop_23: + inc HGR_HORIZ,X ; (nop) ; 6 + dec HGR_HORIZ,X ; (nop) ; 6 + ldy HGR_HORIZ ; (nop) ; 3 + ldy HGR_HORIZ ; (nop) ; 3 + ldy HGR_HORIZ ; (nop) ; 3 + nop ; 2 +done_mod_nop14: + inc HGR_HORIZ,X ; (nop) ; 6 + dec HGR_HORIZ,X ; (nop) ; 6 + nop ; 2 + +done_mod: + ldy HGR_HORIZ ; 3 + tax ; 2 + lda msktbl,x ; 4+ + + sta HMASK ; 3 + tya ; 2 + lsr ; 2 + lda HGR_COLOR ; 3 + sta HGR_BITS ; 3 + ;=========== + ; 22 + + bcs color_shift ; 3 + ; cs = 3+20 + ;-1 + + ; need 23 = 2+6+X = 15 + inc HMASK,X ; nop ; 6 + dec HMASK,X ; nop ; 6 + lda HMASK ; nop ; 3 + + + rts ; 6 + ;=========== + ; 23 + + ;===================================== + ; HPLOT0 + ;===================================== + ; point in (YX),A + ; 244 cycles +hplot0: + ; F457 + jsr hposn ; 6+210 + lda HGR_BITS ; 3 + eor (GBASL),y ; 5+ + and HMASK ; 3 + eor (GBASL),y ; 5+ + sta (GBASL),y ; 6 + rts ; 6 + ;============ + ; 244 + + ;=================================== + ; COLOR_SHIFT + ;=================================== + ; positive = 7+(7)+6 = 20 + ; negative = 7+ 7 +6 = 20 + +color_shift: ; F47E + asl ; 2 + cmp #$c0 ; 2 + + bpl done_color_shift ; 3 + ; -1 + lda HGR_BITS ; 3 + eor #$7f ; 2 + sta HGR_BITS ; 3 + rts ; 6 +done_color_shift: + lda HGR_BITS ; nop ; 3 + nop ; 2 + nop ; 2 + rts ; 6 + +.align $100 + + ;============================= + ; HCOLOR_EQUALS + ;============================= + ; Color in X + ; 13 cycles +hcolor_equals: + + ; F6E9 + ; TODO: mask to be less than 8 + + lda colortbl,x ; 4+ + sta HGR_COLOR ; 3 + rts ; 6 + +colortbl: + .byte $00,$2A,$55,$7F,$80,$AA,$D5,$FF + diff --git a/megademo/lz4_decode.s b/megademo/lz4_decode.s index 1ce7de64..4355da11 100644 --- a/megademo/lz4_decode.s +++ b/megademo/lz4_decode.s @@ -18,7 +18,8 @@ ; size=0, checksum=1, reserved ; MAX Blocksize: 40 (64kB) ; HEADER CHECKSUM: a7 -; BLOCK HEADER: 4 bytes (le) If highest bit set, uncompressed! +; BLOCK HEADER: 4 bytes (le) length If highest bit set, uncompressed! +; data (see below), followed by checksum? ; BLOCKS: ; Token byte. High 4-bits literal length, low 4-bits copy length ; + If literal length==15, then following byte gets added to length @@ -30,6 +31,11 @@ ; 4 added to it. As with the literal length, if it is 15 then ; you read a byte and add (and if that byte is 255, keep adding) +; At end you have 4 byte end-of-block marker (all zeros?) then +; 4 bytes of checksum (if marked in flags) +; our code does that, so be sure to set end -8 + + ;LZ4_SRC EQU $00 ;LZ4_DST EQU $02 ;LZ4_END EQU $04 diff --git a/megademo/megademo.s b/megademo/megademo.s index bf02bc03..1074cfc6 100644 --- a/megademo/megademo.s +++ b/megademo/megademo.s @@ -11,7 +11,6 @@ ;=================== jsr HOME - ; C64 Opening Sequence jsr c64_opener @@ -24,6 +23,25 @@ ; E-mail arriving + ; Leaving house + + ; Riding bird + + ; Waterfall + + ; Enter ship + + ; Fly in space + + ; Arrive + + ; Fireworks + + jsr fireworks + + ; Game over +game_over_man: + jmp game_over_man ;=================== ; Loop Forever @@ -41,3 +59,8 @@ loop_forever: .include "vapor_lock.s" .include "delay_a.s" .include "wait_keypress.s" + .include "random16.s" +.align $100 + .include "fireworks.s" + .include "hgr.s" + .include "move_letters.s" diff --git a/megademo/move_letters.s b/megademo/move_letters.s new file mode 100644 index 00000000..2e6c2e0c --- /dev/null +++ b/megademo/move_letters.s @@ -0,0 +1,223 @@ + ;=============================================== + ; Move Letters + ;=============================================== + ; Normal P0 =6+13+2+22+46+37 = 126 + ; Normal P1 =6+13+2+22+46+37 = 126 + ; End of line =6+13+2+22+46+9+(28) = 126 + ; Next line =6+13+5+14+34+(26+28) = 126 + ; done entirely =6+13+5+(6+42+26+28) = 126 + ; Waiting =6+7+(11+6+42+26+28) = 126 + + ; all forced to be 126 + +move_letters: + ldy WAITING ; 3 + beq not_waiting ; 3 + ;============ + ; 6 + + ;-1 + dec WAITING ; 5 + jmp wait_it_out ; 3 + ;=========== + ; 7 + +not_waiting: + ; load letter from pointer, save into LETTER + + ldy #0 ; 2 + lda (LETTERL),Y ; 5 + sta LETTER ; 3 + + ; if high bit set, is special case + bmi letter_special ; 3 + ;========== + ; 13 + + ; just regular letter + + ;-1 + lda LETTERY ; get letter Y ; 3 + bmi letter_page1 + ;========== + ; 2 + +letter_page0: ; -1 + asl ; map to memory address ; 2 + tay ; 2 + lda gr_offsets,Y ; lookup low-res memory address ; 4 + sta BASL ; store out low byte of addy ; 3 + lda gr_offsets+1,Y ; look up high byte ; 4 + sta BASH ; 3 + lda #0 ; cycle-killer ; 2 + jmp letter_erase ; 3 + ;========== + ; 22 + +letter_page1: + asl ; map to memory address ; 2 + tay ; 2 + lda gr_offsets,Y ; lookup low-res memory address ; 4 + sta BASL ; store out low byte of addy ; 3 + lda gr_offsets+1,Y ; look up high byte ; 4 + clc ; 2 + adc #$4 ; adjust to page1 ; 2 + sta BASH ; 3 + ;========== + ; 22 + + ;============================ +letter_erase: + ldy LETTERX ; nop ; 3 + nop ; nop ; 5 + + ldy #0 ; erase old char with space ; 2 + lda #' '|$80 ; 2 + ldy LETTERX ; 3 + sta (BASL),Y ; 6 + + dey ; draw new char ; 2 + sty LETTERX ; 3 + lda LETTER ; 3 + ora #$80 ; 2 + ldy LETTERX ; 3 + sta (BASL),Y ; 6 + + lda LETTERX ; see if we are at destination ; 3 + cmp LETTERD ; 3 + beq letter_next ; 3 + ;=========== + ; 46 + + ;-1 + lda #0 ; 2 + lda #0 ; 2 + jmp waste_28 ; 3 + ;========== + ; 9 +letter_next: + clc ; 16-bit inc letter pointer ; 2 + lda LETTERL ; 3 + adc #1 ; 2 + sta LETTERL ; 3 + lda LETTERH ; 3 + adc #0 ; 2 + sta LETTERH ; 3 + + inc LETTERD ; inc destination X ; 5 + lda #39 ; start at right of screen ; 2 + sta LETTERX ; 3 + rts ; 6 + ;=========== + ; 37 + +letter_special: + cmp #$ff ; handle FF, we're done ; 2 + beq letter_done ; 3 + ;========== + ; 5 + + + ; -1 + and #$7f ; clear top ; 2 + sta WAITING ; this is waiting value ; 3 + + ldy #1 ; otherwise, Y,X pair ; 2 + lda (LETTERL),Y ; get Y, put in LETTERY ; 5 + sta LETTERY ; 3 + ;=========== + ; 14 + + iny ; get dest ; 2 + lda (LETTERL),Y ; 5 + sta LETTERD ; put in LETTERD ; 3 + + clc ; skip 3 bytes to begin of letters ; 2 + lda LETTERL ; 16-bit add ; 3 + adc #3 ; 2 + sta LETTERL ; 3 + lda LETTERH ; 3 + adc #0 ; 2 + sta LETTERH ; 3 + lda LETTERH ; waste ; 3 + jmp waste_26 ; 3 + + ;=========== + ; 34 + +wait_it_out: + ; wait 11 + inc BLARGH ; 5 + lda LETTERH ; 3 + lda LETTERH ; 3 + +letter_done: + lda LETTERH ; 3 + lda LETTERH ; 3 + +waste_42: + ldx #0 ; 2 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 +waste_26: + ldx #0 ; 2 + ldx #0 ; 2 + ldx #0 ; 2 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + +waste_28: + ldx #0 ; 2 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + inc BLARGH ; 5 + rts ; 6 + +letters: +; .byte 22,28, + .byte " ",128 + .byte 22+128,25," ",128 + + .byte 23,25, " ",128 + .byte 23+128,25," ",128 + + .byte 22,26, "CODE BY",128 + .byte 22+128,26,"CODE BY",128 + + .byte 23,26, "DEATER",128 + .byte 23+128,26,"DEATER",198 + + .byte 22,26, " ",128 + .byte 22+128,26," ",128 + + .byte 23,26, " ",128 + .byte 23+128,26," ",128 + + .byte 22,26, "FIREWORKS",128 + .byte 22+128,26,"FIREWORKS",128 + + .byte 23,26, "FOZZTEXX",128 + .byte 23+128,26,"FOZZTEXX",198 + + .byte 22,26, " ",128 + .byte 22+128,26," ",128 + + .byte 23,26, " ",128 + .byte 23+128,26," ",128 + + .byte 22,26,"A VMW",128 + .byte 22+128,26,"A VMW",128 + + .byte 23,26,"PRODUCTION",128 + .byte 23+128,26,"PRODUCTION" + + .byte 255 diff --git a/megademo/random16.s b/megademo/random16.s new file mode 100644 index 00000000..4ab4a384 --- /dev/null +++ b/megademo/random16.s @@ -0,0 +1,119 @@ +; 16-bit 6502 Random Number Generator (cycle-invariant version) + +; Linear feedback shift register PRNG by White Flame +; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng + +; The Apple II KEYIN routine increments SEEDL:SEEDH +; while waiting for keypress + +SEEDL = $4E +SEEDH = $4F + +XOR_MAGIC = $7657 ; "vW" + + ;============================= + ; random16 + ;============================= + ; takes: + ; not 0, cs = 6(r16)+12(lnz)+5(nop)+ 19(deo) = 42 + ; not 0, cc = 6(r16)+14(lnz)+2(nop)+ 20(neo) = 42 + + ; $0000 = 6(r16)+ 6(loz)+11nops+ 19(deo) = 42 + ; $8000 = 6(r16)+ 6(loz)+ 4(ceo) + 6nops+ 20(neo) = 42 + + ; $XX00 cc = 6(r16)+ 6(loz)+4(ceo)+2(cep) +4nops+ 20(neo) = 42 + ; $XX00 cs = 6(r16)+ 6(loz)+4(ceo)+4(cep) +3nops+ 19(deo) = 42* +random16: + + lda SEEDL ; 3 + beq low_zero ; $0000 and $8000 are special values ; 3 + ;========== + ; 6 +lownz: + ; -1 + asl SEEDL ; Do a normal shift ; 5 + lda SEEDH ; 3 + rol ; 2 + bcs five_cycle_do_eor ; 3 + ;=========== + ; 12 + + bcc two_cycle_no_eor ; 3 + ;========== + ; 12+3-1 = 14 + + +;=================================================================== + +eleven_cycle_do_eor: + nop ; 2 + nop ; 2 + nop ; 2 +five_cycle_do_eor: + nop ; 2 +three_cycle_do_eor: + sta SEEDH ; nop ; 3 + +do_eor: + ; high byte is in A + + eor #>XOR_MAGIC ; 2 + sta SEEDH ; 3 + lda SEEDL ; 3 + eor #