diff --git a/graphics/gr/drops/Makefile b/graphics/gr/drops/Makefile index a1c4d59e..c1621efb 100644 --- a/graphics/gr/drops/Makefile +++ b/graphics/gr/drops/Makefile @@ -6,10 +6,11 @@ LINKERSCRIPTS = ../../../linker_scripts all: drops.dsk -drops.dsk: HELLO DROPS +drops.dsk: HELLO DROPS DROPS_TINY cp empty.dsk drops.dsk $(DOS33) -y drops.dsk SAVE A HELLO $(DOS33) -y drops.dsk BSAVE -a 0x300 DROPS + $(DOS33) -y drops.dsk BSAVE -a 0x300 DROPS_TINY ### @@ -27,5 +28,14 @@ drops.o: drops.s ### +DROPS_TINY: drops_tiny.o + ld65 -o DROPS_TINY drops_tiny.o -C $(LINKERSCRIPTS)/apple2_300.inc + +drops_tiny.o: drops_tiny.s + ca65 -o drops_tiny.o drops_tiny.s -l drops_tiny.lst + + +### + clean: - rm -f *~ *.o *.lst HELLO DROPS + rm -f *~ *.o *.lst HELLO DROPS DROPS_TINY diff --git a/graphics/gr/drops/drops.s b/graphics/gr/drops/drops.s index 2f224a9a..0dac4663 100644 --- a/graphics/gr/drops/drops.s +++ b/graphics/gr/drops/drops.s @@ -13,6 +13,11 @@ ; then flip buffers +; 211 bytes -- initial +; 208 bytes -- use HGR2 to clear +; 204 bytes -- optimize buffer switch +; 197 bytes -- inline random8 + .include "hardware.inc" GBASH = $27 @@ -33,42 +38,56 @@ BUF2H = $FF ; Clear screen and setup graphics ;================================ drops: - jsr HGR - bit LORES -; jsr SETGR ; set lo-res 40x40 mode - bit FULLGR ; make it 40x48 - + jsr HGR2 ; clear $4000-$6000 to zero, full page + bit LORES ; switch to LORES drops_outer: + ;================================= + ; handle new frame + ;================================= + inc FRAME lda FRAME and #$f bne no_drop - jsr random8 + ; inline random8 + + ;============================= + ; random8 + ;============================= + ; 8-bit 6502 Random Number Generator + ; Linear feedback shift register PRNG by White Flame + ; http://codebase64.org/doku.php?id=base:small_fast_8-bit_prng + +random8: + lda SEEDL ; 2 + beq doEor ; 2 + asl ; 1 + beq noEor ; if the input was $80, skip the EOR ; 2 + bcc noEor ; 2 +doEor: + eor #$1d ; 2 +noEor: + sta SEEDL ; buffer is 40x48 = roughly 2k? ; so random top bits = 0..7 - lda SEEDL sta BUF1L and #$7 clc - adc #$20 + adc #$40 sta BUF1H lda #$1f -; ldy #1 -; sta (BUF1L),Y ldy #41 sta (BUF1L),Y iny sta (BUF1L),Y -; iny -; sta (BUF1L),Y ldy #81 sta (BUF1L),Y iny @@ -82,18 +101,15 @@ no_drop: beq even_frame odd_frame: - lda #$20 - sta BUF1H - lda #$30 - sta BUF2H - jmp done_frame + ldy #$40 + lda #$48 + bne done_frame even_frame: - lda #$30 - sta BUF1H - lda #$20 - sta BUF2H - + ldy #$48 + lda #$40 done_frame: + sty BUF1H + sta BUF2H lda #$00 sta BUF1L @@ -102,6 +118,11 @@ done_frame: lda #47 sta YY + + ;================================= + ; yloop + ;================================= + drops_yloop: lda YY ; plot call needs Y/2 @@ -128,6 +149,11 @@ draw_page_smc: lda #39 ; XX sta XX + + ;================================= + ; xloop + ;================================= + drops_xloop: clc @@ -195,25 +221,7 @@ done_page: colors: .byte $00,$22,$66,$EE,$77,$FF,$FF,$FF - ;============================= - ; random8 - ;============================= - ; 8-bit 6502 Random Number Generator - ; Linear feedback shift register PRNG by White Flame - ; http://codebase64.org/doku.php?id=base:small_fast_8-bit_prng -random8: - lda SEEDL ; 2 - beq doEor ; 2 - asl ; 1 - beq noEor ; if the input was $80, skip the EOR ; 2 - bcc noEor ; 2 -doEor: - eor #$1d ; 2 -noEor: - sta SEEDL - - rts diff --git a/graphics/gr/drops/drops_tiny.s b/graphics/gr/drops/drops_tiny.s new file mode 100644 index 00000000..c6c7b653 --- /dev/null +++ b/graphics/gr/drops/drops_tiny.s @@ -0,0 +1,239 @@ +; water drops + +; based roughly on +; https://github.com/seban-slt/Atari8BitBot/blob/master/ASM/water/water.m65 + +; for each pixel + +; C +; A V B +; D +; +; calculate color as NEW_V = (A+B+C+D)/2 - OLD_V +; then flip buffers + + +; 211 bytes -- initial +; 208 bytes -- use HGR2 to clear +; 204 bytes -- optimize buffer switch +; 197 bytes -- inline random8 +; 169 bytes -- rip out page flipping +; 163 bytes -- use EOR for BUFH setting +; 159 bytes -- put YY in X +; 153 bytes -- fake random by reading ROM +; 151 bytes -- no seed at all, use frame +; 149 bytes -- FRAME saved in Y +; 148 bytes -- beq instead of jmp +; 147 bytes -- reuse color in drop +; 145 bytes -- leave out carry setting + +.include "hardware.inc" + +GBASH = $27 +MASK = $2E +COLOR = $30 +SEEDL = $4E + +FRAME = $F8 +XX = $F9 +DROPL = $FA +DROPH = $FB +BUF1L = $FC +BUF1H = $FD +BUF2L = $FE +BUF2H = $FF + + + ;================================ + ; Clear screen and setup graphics + ;================================ +drops: + jsr HGR ; clear $2000-$4000 to zero + ; A is $00 after this + ; Y is $00 + + bit FULLGR ; full page + bit LORES ; switch to LORES + +drops_outer: + + ; in all but first loop X is $FF on arrival + + inx + stx BUF1L + stx BUF2L + + ;================================= + ; handle new frame + ;================================= + + inc FRAME + + + ; alternate $20/$28 in BUF1H/BUF2H + + lda FRAME + tay + + and #$1 + asl + asl + asl + + ora #$20 + sta BUF1H + eor #$8 + sta BUF2H + + + + + tya ; FRAME + and #$f + bne no_drop + + ; fake random by reading ROM + + lda $E000,Y + + ; buffer is 40x48 = roughly 2k? + ; so random top bits = 0..7 + + sta DROPL + and #$7 + ora #$20 + sta DROPH + + lda #31 ; $1f + +; ldy #41 + + tay + + sta (DROPL),Y + iny + sta (DROPL),Y + + ldy #71 + sta (DROPL),Y + iny + sta (DROPL),Y + +no_drop: + + + ldx #47 +; sta YY + + + ;================================= + ; yloop + ;================================= + +drops_yloop: + + txa ; YY + tay ; plot YY,YY + + jsr PLOT ; PLOT Y,A, setting up MASK and putting addr in GBASL/H + + + ; reset XX to 39 + + lda #39 ; XX + sta XX + + + ;================================= + ; xloop + ;================================= + +drops_xloop: + + clc + ldy #1 + lda (BUF1L),Y + ldy #81 + adc (BUF1L),Y + ldy #40 + adc (BUF1L),Y + ldy #42 + adc (BUF1L),Y + lsr + dey + +; sec + sbc (BUF2L),Y + bpl done_calc + eor #$ff +done_calc: + sta (BUF2L),Y + + inc BUF1L + inc BUF2L + bne no_oflo + + inc BUF1H + inc BUF2H + +no_oflo: + + ; adjust color + + lsr + and #$7 + tay + lda colors,Y + sta COLOR + + ldy XX + jsr PLOT1 ; PLOT AT (GBASL),Y + + dec XX + bpl drops_xloop + + dex ; YY + bpl drops_yloop + +weird_outer: + + bmi drops_outer ; small enough now! + + + +colors: +.byte $00,$22,$66,$EE,$77,$ff,$ff,$ff + +; 0 2 6 e 7 f f f +; 0000 0010 0110 1110 0111 1111 1111 1111 +; 0 1 2 3 4 5 6 7 + + + + + ; for maximum twitter size we enter this program + ; by using the "&" operator which jumps to $3F5 + + ; we can't load there though as the code would end up overlapping + ; $400 which is the graphics area + + ; this is at 389 + ; we want to be at 3F5, so load program at 36C? + + ; called by EXECUTE.STATEMENT at $D828 + ; which jumps to CHRGET at $00B1 + ; which does a RTS to $3F4 at end + + ; CHRGET sets up state based on the char that follows the & + ; Z==C==1 is colon + ; Z==1 is EOL (nul) + ; C==0 is digit + + ; when we call with " following + ; A=$22 (") X=$FF Y=$5E + ; N=0 V=0 Z=0 C=1 + + jmp drops ; entry point from & + + +