diff --git a/megademo/Makefile b/megademo/Makefile index 993508f0..32cd4d8d 100644 --- a/megademo/Makefile +++ b/megademo/Makefile @@ -30,6 +30,7 @@ megademo.o: megademo.s \ starring_people.s fs.inc FS_HGRC.BIN.lz4 deater.inc DEATER_HGRC.BIN.lz4\ check_email.s email_40_96.inc \ bird_mountain.s \ + mode7.s \ 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/bg_scroll.s b/megademo/bg_scroll.s new file mode 100644 index 00000000..64444f24 --- /dev/null +++ b/megademo/bg_scroll.s @@ -0,0 +1,79 @@ + ;================== + ; scroll background + ;================== + ; background already loaded + ; ANGLE 0-15 sets angle + ; CV is Y position to display at + ; 182/220... 220/16 = 13.75 + ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + ; 0 11 22 34 45 56 68 79 91 102 113 125 136 147 159 170 182 + +scroll_offsets: + .byte 0,11,22,34,45,56,68,79,91,102,113,125,136,147,159,170 + +scroll_background: + ldy ANGLE ; use angle + lda scroll_offsets,Y ; lookup in table + sta OFFSET ; calculate offset + + ldx #0 + + ldy CV ; lookup Y co-ord + lsr ; and set up self-modify code + + lda gr_offsets,Y ; get position + sta bgsm1+1 + lda gr_offsets+2,Y ; get position + sta bgsm2+1 + lda gr_offsets+4,Y ; get position + sta bgsm3+1 + lda gr_offsets+6,Y ; get position + sta bgsm4+1 + + + iny + + clc + + lda gr_offsets,Y ; get position + adc DRAW_PAGE + sta bgsm1+2 + lda gr_offsets+2,Y ; get position + adc DRAW_PAGE + sta bgsm2+2 + lda gr_offsets+4,Y ; get position + adc DRAW_PAGE + sta bgsm3+2 + lda gr_offsets+6,Y ; get position + adc DRAW_PAGE + sta bgsm4+2 + + ldy OFFSET + + +bgdraw_loop: + + lda scroll_row1,Y +bgsm1: + sta $400,X + + lda scroll_row2,Y +bgsm2: + sta $480,X + + lda scroll_row3,Y +bgsm3: + sta $500,X + + lda scroll_row4,Y +bgsm4: + sta $580,X + + iny + inx + cpx #40 + bne bgdraw_loop + + rts + + diff --git a/megademo/fw.s b/megademo/fw.s index 01356ba6..4db677e3 100644 --- a/megademo/fw.s +++ b/megademo/fw.s @@ -25,7 +25,7 @@ MARGIN = 24 ; Zero page addresses ;STATE = $ED -OFFSET = $EF +;OFFSET = $EF COLOR_GROUP = $F0 X_VELOCITY = $F1 Y_VELOCITY_H = $F2 diff --git a/megademo/gr_fast_clear.s b/megademo/gr_fast_clear.s new file mode 100644 index 00000000..796b985a --- /dev/null +++ b/megademo/gr_fast_clear.s @@ -0,0 +1,192 @@ +clear_screens: + ;=================================== + ; Clear top/bottom of page 0 + ;=================================== + + lda #$0 + sta DRAW_PAGE + jsr clear_top + jsr clear_bottom + + ;=================================== + ; Clear top/bottom of page 1 + ;=================================== + + lda #$4 + sta DRAW_PAGE + jsr clear_top + jsr clear_bottom + + rts + +clear_bottoms: + ;=================================== + ; Clear bottom of page 0 + ;=================================== + + lda #$0 + sta DRAW_PAGE + jsr clear_bottom + + ;=================================== + ; Clear bottom of page 1 + ;=================================== + + lda #$4 + sta DRAW_PAGE + jsr clear_bottom + + rts + + + + ;========================================================= + ; clear_top + ;========================================================= + ; clear DRAW_PAGE + ; original = 14,558 cycles(?) 15ms, 70Hz + ; OPTIMIZED MAX (page0,48rows): 45*120+4+6 = 5410 = 5.4ms 185Hz + ; (pageX,40rows): 50*120+4+6 = 6010 = 6.0ms 166Hz + ; 50*120+4+6+37 = 6055 = 6.0ms 166Hz +clear_top: + lda #0 ; 2 +clear_top_a: + sta COLOR ; 3 + clc ; 2 + lda DRAW_PAGE ; 3 + + adc #4 ; 2 + sta __ctf+2 ; 3 + sta __ctf+5 ; 3 + adc #1 ; 2 + sta __ctf+8 ; 3 + sta __ctf+11 ; 3 + adc #1 ; 2 + sta __ctf2+2 ; 3 + sta __ctf2+5 ; 3 + adc #1 ; 2 + sta __ctf2+8 ; 3 + sta __ctf2+11 ; 3 + + + ldy #120 ; 2 + lda COLOR ; 3 +clear_top_fast_loop: +__ctf: + sta $400,Y ; 5 + sta $480,Y ; 5 + sta $500,Y ; 5 + sta $580,Y ; 5 + + cpy #80 ; 2 + bpl no_draw_bottom ; 2nt/3 +__ctf2: + sta $600,Y ; 5 + sta $680,Y ; 5 + sta $700,Y ; 5 + sta $780,Y ; 5 +no_draw_bottom: + + dey ; 2 + bpl clear_top_fast_loop ; 2nt/3 + + rts ; 6 + + + + + ;========================================================= + ; clear_bottom + ;========================================================= + ; clear bottom of draw page + +clear_bottom: + clc ; 2 + lda DRAW_PAGE ; 3 + + adc #6 ; 2 + sta __cbf2+2 ; 3 + sta __cbf2+5 ; 3 + adc #1 ; 2 + sta __cbf2+8 ; 3 + sta __cbf2+11 ; 3 + + + ldy #120 ; 2 + lda #$a0 ; Normal Space ; 2 +clear_bottom_fast_loop: +__cbf2: + sta $600,Y ; 5 + sta $680,Y ; 5 + sta $700,Y ; 5 + sta $780,Y ; 5 + + dey ; 2 + cpy #80 ; 2 + bpl clear_bottom_fast_loop ; 2nt/3 + + rts ; 6 + + +clear_screens_notext: + ;=================================== + ; Clear top/bottom of page 0 + ;=================================== + + lda #$0 + sta DRAW_PAGE + jsr clear_all + + ;=================================== + ; Clear top/bottom of page 1 + ;=================================== + + lda #$4 + sta DRAW_PAGE + jsr clear_all + + rts + + + ;========================================================= + ; clear_all + ;========================================================= + ; clear 48 rows + +clear_all: + clc ; 2 + lda DRAW_PAGE ; 3 + + adc #4 ; 2 + sta __caf+2 ; 3 + sta __caf+5 ; 3 + adc #1 ; 2 + sta __caf+8 ; 3 + sta __caf+11 ; 3 + adc #1 ; 2 + sta __caf2+2 ; 3 + sta __caf2+5 ; 3 + adc #1 ; 2 + sta __caf2+8 ; 3 + sta __caf2+11 ; 3 + + + ldy #120 ; 2 +clear_all_color: + lda #0 ; 2 +clear_all_fast_loop: +__caf: + sta $400,Y ; 5 + sta $480,Y ; 5 + sta $500,Y ; 5 + sta $580,Y ; 5 +__caf2: + sta $600,Y ; 5 + sta $680,Y ; 5 + sta $700,Y ; 5 + sta $780,Y ; 5 + + dey ; 2 + bpl clear_all_fast_loop ; 2nt/3 + + rts ; 6 diff --git a/megademo/gr_hlin_double.s b/megademo/gr_hlin_double.s new file mode 100644 index 00000000..127dd30e --- /dev/null +++ b/megademo/gr_hlin_double.s @@ -0,0 +1,67 @@ +;===================================================================== +;= ROUTINES +;===================================================================== + + ;================================ + ; hlin_setup + ;================================ + ; put address in GBASL/GBASH + ; Ycoord in A, Xcoord in Y +hlin_setup: + sty TEMPY ; 3 + tay ; y=A ; 2 + lda gr_offsets,Y ; lookup low-res memory address ; 4 + clc ; 2 + adc TEMPY ; 3 + sta GBASL ; 3 + iny ; 2 + + lda gr_offsets,Y ; 4 + adc DRAW_PAGE ; add in draw page offset ; 3 + sta GBASH ; 3 + rts ; 6 + ;=========== + ; 35 + ;================================ + ; hlin_double: + ;================================ + ; HLIN Y, V2 AT A + ; Y, X, A trashed + ; start at Y, draw up to and including X +hlin_double: +;int hlin_double(int page, int x1, int x2, int at) { + + jsr hlin_setup ; 41 + + sec ; 2 + lda V2 ; 3 + sbc TEMPY ; 3 + + tax ; 2 + inx ; 2 + ;=========== + ; 53 + ; fallthrough + + ;================================= + ; hlin_double_continue: width + ;================================= + ; GBASL has correct offset for row/col + ; width in X + +hlin_double_continue: + + ldy #0 ; 2 + lda COLOR ; 3 +hlin_double_loop: + sta (GBASL),Y ; 6 + inc GBASL ; 5 + dex ; 2 + bne hlin_double_loop ; 2nt/3 + + rts ; 6 + ;============= + ; 53+5+X*16+5 + + + diff --git a/megademo/gr_pageflip.s b/megademo/gr_pageflip.s new file mode 100644 index 00000000..f199f5be --- /dev/null +++ b/megademo/gr_pageflip.s @@ -0,0 +1,24 @@ + ;========== + ; page_flip + ;========== + +page_flip: + lda DISP_PAGE ; 3 + beq page_flip_show_1 ; 2nt/3 +page_flip_show_0: + bit PAGE0 ; 4 + lda #4 ; 2 + sta DRAW_PAGE ; DRAW_PAGE=1 ; 3 + lda #0 ; 2 + sta DISP_PAGE ; DISP_PAGE=0 ; 3 + rts ; 6 +page_flip_show_1: + bit PAGE1 ; 4 + sta DRAW_PAGE ; DRAW_PAGE=0 ; 3 + lda #1 ; 2 + sta DISP_PAGE ; DISP_PAGE=1 ; 3 + rts ; 6 + ;==================== + ; DISP_PAGE=0 26 + ; DISP_PAGE=1 24 + diff --git a/megademo/gr_setpage.s b/megademo/gr_setpage.s new file mode 100644 index 00000000..167e8dd1 --- /dev/null +++ b/megademo/gr_setpage.s @@ -0,0 +1,11 @@ + ;========================================================== + ; set_gr_page0 + ;========================================================== + ; +set_gr_page0: + bit PAGE0 ; set page 0 + bit LORES ; Lo-res graphics + bit TEXTGR ; mixed gr/text mode + bit SET_GR ; set graphics + rts + diff --git a/megademo/island_lookup.s b/megademo/island_lookup.s new file mode 100644 index 00000000..01d4df67 --- /dev/null +++ b/megademo/island_lookup.s @@ -0,0 +1,63 @@ + + ;==================================== + ; do a full lookup, takes much longer + ; used to be a separate function but we inlined it here + + ;==================== + ; lookup_map + ;==================== + ; finds value in space_x.i,space_y.i + ; returns color in A + ; CLOBBERS: A,Y + + lda SPACEX_I ; 3 + sta spacex_label+1 ; self modifying code, LAST_SPACEX_I ; 4 + and #CONST_MAP_MASK_X ; wrap at 64 ; 2 + sta SPACEX_I ; store i patch out ; 3 + tay ; copy to Y for later ; 2 + + lda SPACEY_I ; 3 + sta spacey_label+1 ; self modifying code, LAST_SPACEY_I ; 4 + and #CONST_MAP_MASK_Y ; wrap to 64x64 grid ; 2 + sta SPACEY_I ; 3 + + asl ; 2 + asl ; 2 + asl ; multiply by 8 ; 2 + clc ; 2 + adc SPACEX_I ; add in X value ; 3 + ; only valid if x<8 and y<8 + + ; SPACEX_I is also in y + cpy #$8 ; 2 + ;============ + ; 39 + + bcs @ocean_color ; bgt 8 ; 2nt/3 + ldy SPACEY_I ; 3 + cpy #$8 ; 2 + ;============= + ; 7 + + bcs @ocean_color ; bgt 8 ; 2nt/3 + + tay ; 2 + lda flying_map,Y ; load from array ; 4 + + bcc @update_cache ; 3 + ;============ + ; 11 +@ocean_color: + and #$1f ; 2 + tay ; 2 + lda water_map,Y ; the color of the sea ; 4 + ;=========== + ; 8 + +@update_cache: + sta map_color_label+1 ; self-modifying ; 4 + + ;=========== + ; 4 + +; rts ; 6 diff --git a/megademo/island_map.inc b/megademo/island_map.inc new file mode 100644 index 00000000..3a42dcf2 --- /dev/null +++ b/megademo/island_map.inc @@ -0,0 +1,16 @@ +flying_map: + .byte $22,$ff,$ff,$ff, $ff,$ff,$ff,$22 + .byte $dd,$cc,$cc,$88, $44,$44,$00,$dd + .byte $dd,$cc,$cc,$cc, $88,$44,$44,$dd + .byte $dd,$cc,$cc,$88, $44,$44,$44,$dd + .byte $dd,$cc,$99,$99, $88,$44,$44,$dd + .byte $dd,$cc,$99,$88, $44,$44,$44,$dd + .byte $dd,$cc,$99,$99, $11,$44,$44,$dd + .byte $22,$dd,$dd,$dd, $dd,$dd,$dd,$22 + + +water_map: + .byte $22,$22,$22,$22, $22,$22,$22,$22 + .byte $ee,$22,$22,$22, $22,$22,$22,$22 + .byte $22,$22,$22,$22, $22,$22,$22,$22 + .byte $22,$22,$22,$22, $ee,$22,$22,$22 diff --git a/megademo/megademo.s b/megademo/megademo.s index 1348e418..7080ede4 100644 --- a/megademo/megademo.s +++ b/megademo/megademo.s @@ -25,6 +25,8 @@ apple_iie: ;=================== jsr HOME + jsr mode7_flying + ; C64 Opening Sequence jsr c64_opener @@ -54,6 +56,7 @@ apple_iie: ; Enter ship ; mode7 (???) + jsr mode7_flying ; Fly in space @@ -61,7 +64,7 @@ apple_iie: ; Fireworks - jsr fireworks +; jsr fireworks ; Game over game_over_man: @@ -88,9 +91,10 @@ loop_forever: .include "wait_keypress.s" .include "random16.s" .align $100 - .include "fireworks.s" +; .include "fireworks.s" .include "hgr.s" .include "bird_mountain.s" .include "move_letters.s" .align $100 .include "gr_putsprite.s" + .include "mode7.s" diff --git a/megademo/mode7.s b/megademo/mode7.s new file mode 100644 index 00000000..2b53a27e --- /dev/null +++ b/megademo/mode7.s @@ -0,0 +1,1130 @@ +.include "mode7_zp.inc" + +square1_lo = $2000 +square1_hi = $2200 +square2_lo = $2400 +square2_hi = $2600 + +scroll_row1 = $2800 +scroll_row2 = $2900 +scroll_row3 = $2a00 +scroll_row4 = $2b00 + + +;=========== +; CONSTANTS +;=========== +CONST_SHIPX = 15 +CONST_TILE_W = 64 +CONST_TILE_H = 64 +CONST_MAP_MASK_X = (CONST_TILE_W - 1) +CONST_MAP_MASK_Y = (CONST_TILE_H - 1) +CONST_LOWRES_W = 40 +CONST_LOWRES_H = 40 +CONST_BETA_I = $ff +CONST_BETA_F = $80 +CONST_SCALE_I = $14 +CONST_SCALE_F = $00 +CONST_LOWRES_HALF_I = $ec ; -(LOWRES_W/2) +CONST_LOWRES_HALF_F = $00 + + ; pre-programmed directions + +island_flying_directions: + .byte $2,$00 ; 2 frames, do nothing + .byte $1,'Z' ; start moving forward + .byte $10,$00 ; 16 frames, do nothing + .byte $3,'D' ; 3 frames, turn right + .byte $1,'Z' ; move faster + .byte $8,$00 ; 8 frames, do nothing + .byte $2,'D' ; 2 frames, turn left + .byte $8,$00 ; 8 frames, do nothing + .byte $3,'A' ; 3 frames, turn left + .byte $1,'Z' ; speedup + .byte $8,$00 ; 8 frames, do nothing + .byte $6,'S' ; 6 frames down + .byte $6,$00 ; 6 frames do nothing + .byte $3,'A' ; 3 frames left + .byte $3,'D' ; 3 frames right + .byte $2,$00 ; 2 frames nothing + .byte $1,'D' ; 1 frame right + .byte $2,$00 ; 2 frames nothing + .byte $8,'D' ; 8 frame right + .byte $1,'Z' ; 8 frames up + .byte $6,'W' ; 2 speedup + .byte $a,$00 ; 10 nothing + .byte $3,'S' ; 3 down + .byte $1,'Q' ; quit + + ;===================== + ; Flying + ;===================== + +mode7_flying: + + ;================================ + ; one-time setup + ;================================ + ; Initialize the 2kB of multiply lookup tables + jsr init_multiply_tables + + + ;================================ + ; Clear screen and setup graphics + ;================================ + + jsr clear_screens ; clear top/bottom of page 0/1 + jsr set_gr_page0 + + ;=============== + ; Init Variables + ;=============== + lda #20 + sta SHIPY + lda #0 + sta TURNING + sta ANGLE + sta SPACEX_I + sta SPACEY_I + sta CX_I + sta CX_F + sta CY_I + sta CY_F + sta DRAW_SPLASH + sta SPEED + sta SPLASH_COUNT + sta DISP_PAGE + sta KEY_COUNT + sta KEY_OFFSET + sta FRAME_COUNT + + lda #2 ; initialize sky both pages + sta DRAW_SKY + + lda #4 ; starts out at 4.5 altitude + sta SPACEZ_I + lda #$80 + sta SPACEZ_F + + jsr update_z_factor + +flying_loop: + + lda SPLASH_COUNT ; 3 + beq flying_keyboard ; 2nt/3 + dec SPLASH_COUNT ; decrement splash count ; 5 + +flying_keyboard: + +; jsr get_key ; get keypress ; 6 + + lda KEY_COUNT + bne done_key + + ldy KEY_OFFSET +direction_smc_1: + lda island_flying_directions,Y + sta KEY_COUNT + iny +direction_smc_2: + lda island_flying_directions,Y + sta LASTKEY + inc KEY_OFFSET + inc KEY_OFFSET + +done_key: + dec KEY_COUNT + lda LASTKEY ; 3 + + cmp #('Q') ; 2 + bne check_up ; 3/2nt + + ; done + rts + +check_up: + cmp #('W') ; 2 + bne check_down ; 3/2nt + + ;=========== + ; UP PRESSED + ;=========== + + lda SHIPY + cmp #17 + bcc check_down ; bgt, if shipy>16 + dec SHIPY + dec SHIPY ; move ship up + inc SPACEZ_I ; incement height + jsr update_z_factor + lda #0 + sta SPLASH_COUNT + +check_down: + cmp #('S') + bne check_left + + ;============= + ; DOWN PRESSED + ;============= + + lda SHIPY + cmp #28 + bcs splashy ; ble, if shipy < 28 + inc SHIPY + inc SHIPY ; move ship down + dec SPACEZ_I ; decrement height + jsr update_z_factor + bcc check_left + +splashy: + lda #10 + sta SPLASH_COUNT + +check_left: + cmp #('A') + bne check_right + + ;============= + ; LEFT PRESSED + ;============= + + lda TURNING + bmi turn_left + beq turn_left + + lda #$0 + sta TURNING + clv + bvc check_right + +turn_left: + lda #253 ; -3 + sta TURNING + + dec ANGLE + + inc DRAW_SKY + inc DRAW_SKY + +check_right: + cmp #('D') + bne check_speedup + + ;============== + ; RIGHT PRESSED + ;============== + + lda TURNING ;; FIXME: optimize me + bpl turn_right + lda #0 + sta TURNING + clv + bvc check_speedup + +turn_right: + lda #3 + sta TURNING + + inc ANGLE + inc DRAW_SKY + inc DRAW_SKY + +check_speedup: + cmp #('Z') + bne check_speeddown + + ;========= + ; SPEED UP + ;========= + lda #$8 + cmp SPEED + beq check_speeddown + inc SPEED + +check_speeddown: + cmp #('X') + bne check_brake + + ;=========== + ; SPEED DOWN + ;=========== + + lda SPEED + beq check_brake + dec SPEED + +check_brake: + cmp #(' '+128) + bne check_land + + ;============ + ; BRAKE + ;============ + lda #$0 + sta SPEED + +check_land: + cmp #13 + bne check_help + +check_help: + cmp #('H') + bne check_done + +check_done: + + ;================ + ; Wrap the Angle + ;================ + ; FIXME: only do this in right/left routine? + lda ANGLE ; 3 + and #$f ; 2 + sta ANGLE ; 3 + + ;================ + ; Handle Movement + ;================ + +speed_move: + ldx SPEED ; 3 + beq draw_background ; 2nt/3 + ;============= + lda ANGLE ; dx.i=fixed_sin[(angle+4)&0xf].i; // cos() ; 3 + clc ; 2 + adc #4 ; 2 + and #$f ; 2 + asl ; 2 + tay ; 2 + lda fixed_sin_scale,Y ; 4 + sta DX_I ; 3 + iny ; dx.f=fixed_sin[(angle+4)&0xf].f; // cos() ; 2 + lda fixed_sin_scale,Y ; 4 + sta DX_F ; 3 + + lda ANGLE ; dy.i=fixed_sin[angle&0xf].i; // sin() ; 3 + and #$f ; 2 + asl ; 2 + tay ; 2 + lda fixed_sin_scale,Y ; 4 + sta DY_I ; 3 + iny ; dx.f=fixed_sin[angle&0xf].f; // sin() ; 2 + lda fixed_sin_scale,Y ; 4 + sta DY_F ; 3 + ;============ + ; 54 +speed_loop: + + clc ; fixed_add(&cx,&dx,&cx); ; 2 + lda CX_F ; 3 + adc DX_F ; 3 + sta CX_F ; 3 + lda CX_I ; 3 + adc DX_I ; 3 + sta CX_I ; 3 + + clc ; fixed_add(&cy,&dy,&cy); ; 2 + lda CY_F ; 3 + adc DY_F ; 3 + sta CY_F ; 3 + lda CY_I ; 3 + adc DY_I ; 3 + sta CY_I ; 3 + + dex ; 2 + bne speed_loop ; 2nt/3 + ;============ + ; 45 + + ;==================== + ; Draw the background + ;==================== +draw_background: + jsr draw_background_mode7 ; 6 + + ;======================================== + ;======================================== + ; DRAW SPACESHIP CODE + ;======================================== + ;======================================== +draw_spaceship: + +check_over_water: + ; See if we are over water + lda CX_I ; 3 + sta SPACEX_I ; 3 + lda CY_I ; 3 + sta SPACEY_I ; 3 + + jsr lookup_island_map ; 6 + + sec ; 2 + sbc #COLOR_BOTH_DARKBLUE ; 2 + sta OVER_LAND ; 3 + ;=========== + ; 31 + + ; Calculate whether to draw the splash + + lda #0 ; set splash drawing to 0 ; 2 + sta DRAW_SPLASH ; 3 + + lda SPEED ; if speed==0, no splash ; 3 + beq no_splash ; 2nt/3 + + lda TURNING ; 3 + beq no_turning_splash ; 2nt/3 + + lda SHIPY ; 3 + cmp #27 ; 2 + bcc no_turning_splash ; blt if shipy<25 skip ; 2nt/3 + + lda #1 ; 2 + sta SPLASH_COUNT ; 3 + +no_turning_splash: + lda OVER_LAND ; no splash if over land ; 3 + bne no_splash ; 2nt/3 + + lda SPLASH_COUNT ; no splash if splash_count expired ; 3 + beq no_splash ; 2nt/3 + + lda #1 ; 2 + sta DRAW_SPLASH ; 3 + +no_splash: + + ;============== + ; Draw the ship + ;============== + + clv ; 2 + lda TURNING ; 3 + beq draw_ship_forward ; 2nt/3 + bpl draw_ship_right ; 2nt/3 + bmi draw_ship_left ;; FIXME: optimize order ; 2nt/3 + +draw_ship_forward: + lda DRAW_SPLASH ; 2 + beq no_forward_splash ; 2nt/3 + + ; Draw Splash + lda #>splash_forward ; 2 + sta INH ; 3 + lda #shadow_forward ; 2 + sta INH ; 3 + lda #ship_forward ; 2 + sta INH ; 3 + lda #splash_right ; 2 + sta INH ; 3 + lda #shadow_right ; 2 + sta INH ; 3 + lda #ship_right ; 2 + sta INH ; 3 + lda #splash_left ; 2 + sta INH ; 3 + lda #shadow_left ; 2 + sta INH ; 3 + lda #ship_left ; 2 + sta INH ; 3 + lda #((I*I)/4) +; square2_lo = <(((I-255)*(I-255))/4) +; square2_hi = >(((I-255)*(I-255))/4) + +; Note: DOS3.3 starts at $9600 + +.ifndef square1_lo +square1_lo = $8E00 +square1_hi = $9000 +square2_lo = $9200 +square2_hi = $9400 +.endif + +; for(i=0;i<512;i++) { +; square1_lo[i]=((i*i)/4)&0xff; +; square1_hi[i]=(((i*i)/4)>>8)&0xff; +; square2_lo[i]=( ((i-255)*(i-255))/4)&0xff; +; square2_hi[i]=(( ((i-255)*(i-255))/4)>>8)&0xff; +; } + +init_multiply_tables: + + ; Build the add tables + + ldx #$00 + txa + .byte $c9 ; CMP #immediate - skip TYA and clear carry flag +lb1: tya + adc #$00 ; 0 +ml1: sta square1_hi,x ; square1_hi[0]=0 + tay ; y=0 + cmp #$40 ; subtract 64 and update flags (c=0) + txa ; a=0 + ror ; rotate +ml9: adc #$00 ; add 0 + sta ml9+1 ; update add value + inx ; x=1 +ml0: sta square1_lo,x ; square1_lo[0]=1 + bne lb1 ; if not zero, loop + inc ml0+2 ; increment values + inc ml1+2 ; increment values + clc ; c=0 + iny ; y=1 + bne lb1 ; loop + + ; Build the subtract tables based on the existing one + + ldx #$00 + ldy #$ff +second_table: + lda square1_hi+1,x + sta square2_hi+$100,x + lda square1_hi,x + sta square2_hi,y + lda square1_lo+1,x + sta square2_lo+$100,x + lda square1_lo,x + sta square2_lo,y + dey + inx + bne second_table + + + rts + + +; Fast 16x16 bit unsigned multiplication, 32-bit result +; Input: NUM1H:NUM1L * NUM2H:NUM2L +; Result: RESULT3:RESULT2:RESULT1:RESULT0 +; +; Does self-modifying code to hard-code NUM1H:NUM1L into the code +; carry=0: re-use previous NUM1H:NUM1L +; carry=1: reload NUM1H:NUM1L (58 cycles slower) +; +; clobbered: RESULT, X, A, C +; Allocation setup: T1,T2 and RESULT preferably on Zero-page. +; +; NUM1H (x_i), NUM1L (x_f) +; NUM2H (y_i), NUM2L (y_f) + +; NUM1L * NUM2L = AAaa +; NUM1L * NUM2H = BBbb +; NUM1H * NUM2L = CCcc +; NUM1H * NUM2H = DDdd +; +; AAaa +; BBbb +; CCcc +; + DDdd +; ---------- +; RESULT + +;fixed_16x16_mul_unsigned: + +multiply: + + bcc num1_same_as_last_time ; 2nt/3 + + ;============================ + ; Set up self-modifying code + ; this changes the code to be hard-coded to multiply by NUM1H:NUM1L + ;============================ + + lda NUM1L ; load the low byte ; 3 + sta sm1a+1 ; 3 + sta sm3a+1 ; 3 + sta sm5a+1 ; 3 + sta sm7a+1 ; 3 + eor #$ff ; invert the bits for subtracting ; 2 + sta sm2a+1 ; 3 + sta sm4a+1 ; 3 + sta sm6a+1 ; 3 + sta sm8a+1 ; 3 + lda NUM1H ; load the high byte ; 3 + sta sm1b+1 ; 3 + sta sm3b+1 ; 3 + sta sm5b+1 ; 3 +; sta sm7b+1 ; + eor #$ff ; invert the bits for subtractin ; 2 + sta sm2b+1 ; 3 + sta sm4b+1 ; 3 + sta sm6b+1 ; 3 +; sta sm8b+1 ; + ;=========== + ; 52 + +num1_same_as_last_time: + + ;========================== + ; Perform NUM1L * NUM2L = AAaa + ;========================== + + ldx NUM2L ; (low le) ; 3 + sec ; 2 +sm1a: + lda square1_lo,x ; 4 +sm2a: + sbc square2_lo,x ; 4 + + ; a is _aa + +; sta RESULT+0 ; + +sm3a: + lda square1_hi,x ; 4 +sm4a: + sbc square2_hi,x ; 4 + ; a is _AA + sta _AA+1 ; 3 + ;=========== + ; 24 + + ; Perform NUM1H * NUM2L = CCcc + sec ; 2 +sm1b: + lda square1_lo,x ; 4 +sm2b: + sbc square2_lo,x ; 4 + ; a is _cc + sta _cc+1 ; 3 +sm3b: + lda square1_hi,x ; 4 +sm4b: + sbc square2_hi,x ; 4 + ; a is _CC + sta _CC+1 ; 3 + ;=========== + ; 24 + + ;========================== + ; Perform NUM1L * NUM2H = BBbb + ;========================== + ldx NUM2H ; 3 + sec ; 2 +sm5a: + lda square1_lo,x ; 4 +sm6a: + sbc square2_lo,x ; 4 + ; a is _bb + sta _bb+1 ; 3 + +sm7a: + lda square1_hi,x ; 4 +sm8a: + sbc square2_hi,x ; 4 + ; a is _BB + sta _BB+1 ; 3 + ;=========== + ; 27 + + ;========================== + ; Perform NUM1H * NUM2H = DDdd + ;========================== + sec ; 2 +sm5b: + lda square1_lo,x ; 4 +sm6b: + sbc square2_lo,x ; 4 + ; a is _dd + sta _dd+1 ; 3 +;sm7b: +; lda square1_hi,x ; +;sm8b: +; sbc square2_hi,x ; + ; a = _DD +; sta RESULT+3 ; + ;=========== + ; 13 + + ;=========================================== + ; Add the separate multiplications together + ;=========================================== + + clc ; 2 +_AA: + lda #0 ; loading _AA ; 2 +_bb: + adc #0 ; adding in _bb ; 2 + sta RESULT+1 ; 3 + ;========== + ; 9 + ; product[2]=_BB+_CC+c + +_BB: + lda #0 ; loading _BB ; 2 +_CC: + adc #0 ; adding in _CC ; 2 + sta RESULT+2 ; 3 + ;=========== + ; 7 + + ; product[3]=_DD+c + +; bcc dd_no_carry1 ; +; inc RESULT+3 ; + clc ; 2 + ;============= + ; 2 +dd_no_carry1: + + ; product[1]=_AA+_bb+_cc + +_cc: + lda #0 ; load _cc ; 2 + adc RESULT+1 ; 3 + sta RESULT+1 ; 3 + + ; product[2]=_BB+_CC+_dd+c + +_dd: + lda #0 ; load _dd ; 2 + adc RESULT+2 ; 3 + sta RESULT+2 ; 3 + + ;=========== + ; 16 + ; product[3]=_DD+c + + +; bcc dd_no_carry2 ; +; inc RESULT+3 ; + + ;============= + ; 0 + +dd_no_carry2: + +; *z_i=product[1]; +; *z_f=product[0]; + +; rts ; 6 + + + ;================= + ; Signed multiply + ;================= + +;multiply: + +; jsr fixed_16x16_mul_unsigned ; 6 + + lda NUM1H ; x_i ; 3 + ;=========== + ; 12 + + + bpl x_positive ;^3/2nt + + sec ; 2 + lda RESULT+2 ; 3 + sbc NUM2L ; 3 + sta RESULT+2 ; 3 +; lda RESULT+3 ; +; sbc NUM2H ; +; sta RESULT+3 ; + ;============ + ; 10 + +x_positive: + + lda NUM2H ; y_i ; 3 + ;============ + ; ; 6 + + bpl y_positive ;^3/2nt + + + sec ; 2 + lda RESULT+2 ; 3 + sbc NUM1L ; 3 + sta RESULT+2 ; 3 +; lda RESULT+3 ; +; sbc NUM1H ; +; sta RESULT+3 ; + ;=========== + ; 10 + +y_positive: + ldx RESULT+2 ; *z_i=product[2]; ; 3 + lda RESULT+1 ; *z_f=product[1]; ; 3 + + rts ; 6 + ;========== + ; 12 + diff --git a/megademo/starry_sky.scroll b/megademo/starry_sky.scroll new file mode 100644 index 00000000..60d7fbab --- /dev/null +++ b/megademo/starry_sky.scroll @@ -0,0 +1,10 @@ +; Original size = 1020 bytes +sky_background: +; scroll_length: +.byte 255 + .byte $A9,$00,$D0,$A9,$00,$50,$F5,$50,$AB,$00,$0F,$A7,$00,$0D,$DD,$D0,$A7,$00,$F0,$A5,$00,$11,$A7,$00,$A4,$70,$D0,$D0,$A7,$00,$70,$A9,$00,$05,$A0,$11,$00,$0F,$A0,$11,$00,$D0,$A0,$12,$00,$50,$A0,$2F,$00,$D0,$A9,$00,$50,$F5,$50,$AB,$00,$0F,$A0,$28,$00 + .byte $A5,$00,$0F,$A6,$00,$F0,$A4,$00,$0F,$00,$00,$05,$A9,$00,$0F,$A4,$00,$05,$A7,$00,$DD,$A7,$00,$0F,$00,$F0,$00,$F0,$A8,$00,$07,$70,$A4,$75,$FF,$FF,$F0,$A0,$11,$00,$F0,$A5,$00,$05,$A5,$00,$07,$A0,$11,$00,$50,$A0,$1D,$00,$0F,$A0,$18,$00,$05,$AB,$00,$0F,$A6,$00,$F0,$A4,$00,$0F,$00,$00,$05,$A9,$00,$0F,$A4,$00,$05,$A0,$26,$00 + .byte $00,$00,$F0,$AA,$00,$F0,$00,$00,$F0,$A7,$00,$07,$A4,$00,$70,$AB,$00,$D0,$DD,$0D,$A5,$00,$D0,$A5,$00,$0F,$A8,$00,$07,$70,$05,$75,$75,$D5,$DF,$0F,$A5,$00,$F0,$A5,$00,$50,$A0,$19,$00,$50,$A4,$00,$0D,$AE,$00,$0F,$A5,$00,$07,$A8,$00,$D0,$AB,$00,$07,$AB,$00,$0F,$AF,$00,$F0,$AA,$00,$F0,$00,$00,$F0,$A7,$00,$07,$A4,$00,$70,$A0,$2C,$00 + .byte $A0,$40,$00,$07,$A0,$BF,$00 + .byte $A1 +; Compressed size = 231 bytes diff --git a/megademo/zp.inc b/megademo/zp.inc index 1a6e7d7b..3fe90f4a 100644 --- a/megademo/zp.inc +++ b/megademo/zp.inc @@ -1,3 +1,7 @@ +;; Zero Page + +FRAMEBUFFER = $00 ; $00 - $0F + ;; LZ4 addresses LZ4_SRC = $00 @@ -46,7 +50,7 @@ LETTERX = $65 LETTERY = $66 LETTERD = $67 LETTER = $68 - +BLARGH = $69 ;FACTOR_I = $66 ;FACTOR_F = $67 @@ -122,6 +126,7 @@ CURSOR = $9D ;MATCH = $E2 ;XX = $E3 YY = $E4 +HGR_COLOR = $E4 ;SHIPY = $E4 ;YADD = $E5 ;LOOP = $E6 @@ -131,12 +136,16 @@ YY = $E4 ;NAMEH = $EA ;NAMEX = $EB ;CHAR = $EC +STATE = $ED DISP_PAGE = $ED DRAW_PAGE = $EE +OFFSET = $EF ;FIRST = $F0 - ;LASTKEY = $F1 - ;PADDLE_STATUS = $F2 + +LASTKEY = $F1 +PADDLE_STATUS = $F2 + SPRITETEMP = $F2 XPOS = $F3 YPOS = $F4