; DSR Scroll Demo -- 256B Apple II Demo for Outline 2022 ; by Vince `deater` Weaver / dSr ; sound routines inspired by those in the Pollywog Game by Alan Wootton ; 253 bytes -- initial implementation with no sound ; 251 bytes -- no phase ; 247 bytes -- move scale before so don't have to reload 0 ; 243 bytes -- use BIT trick ; 242 bytes -- load frame into Y ; 240 bytes -- more BIT trick ; 239 bytes -- compare with BMI ; 263 bytes -- initially add sound ; 262 bytes -- make Y always 0 in xdraw ; 260 bytes -- ust BIT to determine phase ; 258 bytes -- no need to init PAGE at start ; 257 bytes -- remove a CLC as we know carry always set ; 256 bytes -- optimize phase now that we are setting 0/7 not 1/8 ; 255 bytes -- optimize same area some more ; 263 bytes -- make it two-tone ; 262 bytes -- note can set X to 0 from A ; 257 bytes -- use HGR/HGR2 to clear both screens ; 256 bytes -- call into ROM to save one last byte ; zero page locations OUTL = $14 OUTH = $15 GBASL = $26 GBASH = $27 PAGE = $6E FRAME = $7A ; note $D0-$EF used by the hi-res Applesoft ROM routines HGR_PAGE = $E6 HGR_SCALE = $E7 ; soft-switch SPEAKER = $C030 SET_GR = $C050 SET_TEXT = $C051 FULLGR = $C052 PAGE1 = $C054 PAGE2 = $C055 LORES = $C056 ; Enable LORES graphics HIRES = $C057 ; Enable HIRES graphics ; ROM calls HGR2 = $F3D8 HGR = $F3E2 HCLR = $F3F2 ; A=0, Y=0 after, X unchanged HPOSN = $F411 XDRAW0 = $F65D XDRAW1 = $F661 PLOT = $F800 ; PLOT AT Y,A (A colors output, Y preserved) GBASCALC = $F847 ; Y in A, put addr in GBASL/GBASH SETGR = $FB40 WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us ; d000 was first ; f300 not bad ; f400 good ; f500 so so ; f600 less so ; f700 soso ; f800 pattern1 = $f800 ; location in memory to use as ;pattern1 = $d000 ; location in memory to use as ; background pixel pattern ;======================================== ;======================================== ; actual start ;======================================== ;======================================== dsr_scroll_intro: lda #8 sta HGR_SCALE ; init scale to 8 jsr HGR ; Hi-res, PAGE1, split-screen ; Y=0, A=0 after this call ; can save 1 byte by calling $D690 ; sets $7A and $14 to 0 ; sta FRAME ; sta OUTL jsr $D690 ;========================================= ; setup hi-res dsr on both pages ;========================================= hires_setup: ; A is 0 here ; Y is also 0 here ; lda #0 ; non-rotate, on HGR PAGE2 jsr xdraw ; ; tay ; reset Y to 0 jsr HGR2 ; Hi-res, PAGE2, full-screen ; Y=0, A=0 after this call lda #2 ; rotate 2/64 of 360 degrees jsr xdraw ;=============================== ;=============================== ; main loop ;=============================== ;=============================== ; A is zero due to call to xdraw main_loop: ; current page is in A at this point sta PAGE asl ; make OUTH $4 or $8 depending on value in PAGE ; which we have in A above or at end of loop asl ; C is 0 adc #4 sta OUTH ;======================= ; delay ;======================= lda #200 jsr play_sound ; A is 0 after this ;======================= ; handle state ;======================= ; HI-RES WIGGLE 0.. 63 ; LO-RES RIGHT SCROLL 64..127 ; LO-RES DOWN SCROLL 128..191 ; TEXT RIGHT SCROLL 192..255 tax ; put 0 into X inc FRAME lda #$1F bit FRAME ; puts bit 7 in N and bit 6 in V php ; save flags (zero is one we care) bpl n_clear bvc phase2 bvs phase3 n_clear: bvc phase0 ; bvs phase1 phase1: ; LORES Vertical Scroll bit LORES ; enable lo-res ldx #7 ; make vertical scroll phase2: ; LORES Horizontal Scroll ; X is 7 or 0 here stx pattern_dir_smc+1 ; self-modify the add code jmp done_phase ; bra phase0: ; HIRES on GRAPHICS on bit HIRES .byte $24 ; BIT trick to skip the inx phase3: ; TEXT ON inx ; point to SET_TEXT rather than SET_GR lda SET_GR,X ; set mode done_phase: plp ; restore flags bne not_zero was_zero: ; update pointer to "random" background color inc pattern_smc+2 ldy #135 boop_loop: bl_smc: lda #8 jsr play_sound lda #9 jsr play_sound dey bne boop_loop lda bl_smc+1 ; toggle short to long sound eor #$2 sta bl_smc+1 not_zero: ;============================ ; draw an interleaved line full_loop: ldx #3 line_loop: ldy #119 screen_loop: tya ; extrapolate X from Y ; and #$7 ; could be bigger? ; tax pattern_smc: lda pattern1,Y inner_loop_smc: sta (OUTL),Y dey bpl screen_loop ;================================= ; move to next pattern scroll_pattern: clc lda pattern_smc+1 adc #8 and #$1f sta pattern_smc+1 ; move to next line by adding $80 ; we save a byte by using EOR instead lda OUTL eor #$80 ; add $80 sta OUTL bne line_loop ; we overflowed, so increment OUTH inc OUTH ; lda OUTH ; check if at end ; and #$3 ; bne line_loop dex bpl line_loop done_bg: ;======================================= ; done drawing frame ;======================================= bit $C030 ; additional click noise ;====================== ; draw bitmap ldx #7 boxloop: txa jsr GBASCALC ; calc address of X ; note we center to middle of screen ; by noting the middle 8 lines ; are offset by $28 from first 8 lines ; GBASL is in A at this point clc adc #12+$28 sta GBASL ; center x-coord and y-coord at same time lda PAGE ; want to add 0 or 4 (not 0 or 1) asl asl ; this sets C to 0 adc GBASH sta GBASH ldy #15 draw_line_loop: lda bitmap2,X ; get low bit of bitmap2 into carry lsr lda #$00 ; black is default color ror bitmap,X ; 16-bit rotate (in memory) ror bitmap2,X bcc its_black lda #$ff its_black: sta (GBASL),Y ; partway down screen dey bpl draw_line_loop dex bpl boxloop ;========================= ; scroll one line ;========================= ; if +1 then horizontal ; if +8 then vertical ; our current bitmap top line is all FFs ; so we know carry will be set here ; clc lda pattern_smc+1 pattern_dir_smc: adc #$8 sta pattern_smc+1 ; switch page flip_page: lda PAGE tax ldy PAGE1,X ; flip page eor #$1 ; bpl main_loop ; bra jmp main_loop ;======================= ; xdraw ;======================= ; rotation in A ; Y should be 0 on entry xdraw: pha ; save rotation ; setup X and Y co-ords ; ldy #0 ; XPOSH always 0 for us ldx #140 lda #80 ; 96 would be halfway? jsr HPOSN ; X= (y,x) Y=(a) ; after, A=COLOR.BITS ; Y = xoffset (140/7=20?) ; X = remainder? ; jsr HCLR ; A=0 and Y=0 after, X=unchanged ldx #shape_dsr ; pla ; restore rotation jmp XDRAW0 ; XDRAW 1 AT X,Y ; A is zero at end ; tail call ;============================= ; play_sound ;============================= play_sound: bit $C030 jmp WAIT ; updated desire logo thanks to Jade/HMD ;012|456|012|456| ;@@@@@@@@@@@@@@@@' ;@ @@ @ @@' ;@@@ @@@@@@@@ @' ;@ @ @ @ @@' ;@ @ @@@ @@@ @' ;@ @ @ @ @' ;@@@@@@@@@@@@@@@@' ; bitmap: .byte $FF ;,$FF .byte $8C ;,$23 .byte $E7 ;,$F9 .byte $A4 ;,$23 .byte $A7 ;,$39 .byte $84 ;,$29 .byte $FF ;,$FF .byte $00 ;,$00 bitmap2: .byte $FF .byte $23 .byte $F9 .byte $23 .byte $39 .byte $29 .byte $FF .byte $00 shape_dsr: .byte $2d,$36,$ff,$3f .byte $24,$ad,$22,$24,$94,$21,$2c,$4d .byte $91,$3f,$36,$00