From ffb014892c165a4f1be2d70e7df8e3d5523a5f86 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 9 Jan 2019 00:33:15 -0500 Subject: [PATCH] fire: add raster start --- fire/Makefile | 14 ++++- fire/raster.s | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 fire/raster.s diff --git a/fire/Makefile b/fire/Makefile index a958970a..3c8ca8bd 100644 --- a/fire/Makefile +++ b/fire/Makefile @@ -6,13 +6,14 @@ PNG_TO_RLE = ../gr-utils/png2rle all: fire.dsk -fire.dsk: FIRE FIRE_TINY FIRE_FIRMWARE FIRE_EXTREME FIRE_QKUMBA HELLO COOL_EFFECT +fire.dsk: FIRE FIRE_TINY FIRE_FIRMWARE FIRE_EXTREME FIRE_QKUMBA HELLO COOL_EFFECT RASTER $(DOS33) -y fire.dsk SAVE A HELLO $(DOS33) -y fire.dsk BSAVE -a 0x1000 FIRE $(DOS33) -y fire.dsk BSAVE -a 0x70 FIRE_TINY $(DOS33) -y fire.dsk BSAVE -a 0x70 FIRE_FIRMWARE $(DOS33) -y fire.dsk BSAVE -a 0x70 FIRE_EXTREME $(DOS33) -y fire.dsk BSAVE -a 0x70 FIRE_QKUMBA + $(DOS33) -y fire.dsk BSAVE -a 0x70 RASTER $(DOS33) -y fire.dsk BSAVE -a 0x70 COOL_EFFECT #### @@ -67,6 +68,14 @@ cool_effect.o: cool_effect.s ca65 -o cool_effect.o cool_effect.s -l cool_effect.lst +#### + + +RASTER: raster.o + ld65 -o RASTER raster.o -C ../linker_scripts/apple2_70.inc + +raster.o: raster.s + ca65 -o raster.o raster.s -l raster.lst #### @@ -77,6 +86,7 @@ HELLO: hello.bas ##### clean: - rm -f *~ *.o *.lst FIRE FIRE_TINY FIRE_FIRMWARE COOL_EFFECT HELLO FIRE_EXTREME FIRE_QKUMBA + rm -f *~ *.o *.lst FIRE FIRE_TINY FIRE_FIRMWARE COOL_EFFECT HELLO FIRE_EXTREME FIRE_QKUMBA RASTER + diff --git a/fire/raster.s b/fire/raster.s new file mode 100644 index 00000000..fb94a5d9 --- /dev/null +++ b/fire/raster.s @@ -0,0 +1,152 @@ +; Apple ][ Lo-res fire animation, size-optimized to 64 bytes + +; by deater (Vince Weaver) + +; originally based on code described here +; http://fabiensanglard.net/doom_fire_psx/ +; but this is a slightly different algorithm (but still cool looking) + +; Optimization history: +; 80 bytes -- the size of tire_tiny.s +; 64 bytes -- use the firmware SCROLL routine to handle the scrolling +; this adds some flicker but saves many bytes +; 63 bytes -- qkumba noted that SCROLL leaves BAS2L:BAS2H pointing at $7d0 +; 66 bytes -- tried on real hardware. Found that the original firmware +; never sets MIXCLR on boot, and my II+ machine was leaving +; it off so for correctness need to add it on. +; 66 bytes -- wasted a lot of time trying to either find clever ways to +; get $C050/C052 accessed, or to shorten the lookup table +; in half by lsr. Nothing panned out. +; 64 bytes -- realized I could save/restore the random SEEDL on the stack! +; doesn't seem to affect the output pattern either. + + +; Zero Page + +WNDTOP = $22 +WNDBTM = $23 +CV = $25 +BASL = $28 +BASH = $29 +BAS2L = $2A +BAS2H = $2B +SEEDL = $4E + +; Soft Switches +SET_GR = $C050 ; Enable graphics +MIXCLR = $C052 ; Full screen, no text at bottom +LORES = $C056 ; Enable LORES graphics + +; Monitor ROM routines. Try to use well-known entry points as +; these did sometimes change with newer models +SCROLL = $FC70 +VTAB = $FC22 ; takes row in CV, Result is in BASL:BASH ($28/$29) +VTABZ = $FC24 ; VTABZ variant takes row in Accumulator + +fire_demo: + + ; Set lores graphics + + bit SET_GR ; force graphics mode ; 3 + ; LORES and LOWSCR (lo-res page1) + ; are set by the boot rom + + bit MIXCLR ; want full-screen graphics w/o mixed ; 3 + ; text the boot process doesn't set this + ; (it doesn't matter in text mode) + ; and while IIe and emulators come up clear + ; my Apple II+ doesn't + + ; Set window. This seems to be set properly at boot though + ; lda #0 + ; sta WNDTOP + ; lda #24 + ; sta WNDBTM + + +scroll_loop: + + jsr SCROLL ; scrolls screen up one row ; 3 + + + ;====================================== + ; re-draw bottom line (row 23) as white + + + ; Y is left at 40 after SCROLL + ; also BAS2L:BAS2H is left at $7d0 + ; this code over-writes $7F8 (the MSLOT screen hole value) + ; but this should not matter for this demo + + lda #$ff ; top/bottom white ; 2 +w_loop: + sta (BAS2L),Y ; hline 23 (46+47) ; 2 + dey ; 1 + bpl w_loop ; 2 + ;============ + ; 8 + +fire_loop: + + lda #22 ; start at line 22 ; 2 + sta CV ; store in Row location ; 2 + +yloop: + ; puts address of row CV into BASL:BASH + jsr VTAB ; 3 + + + ; loop for X values 39 ... 0 + ldy #39 ; 2 +xloop: + + ;============================= + ; 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: + pla +; 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 ; 2 + pha + + ; end inlined RNG + + ; Randomly either use current value, or decay by one + bmi no_change ; assume bit 7 is as random as bit 0 ; 2 + + ; Lookup the new color in table + lda (BASL),Y ; load value ; 2 + and #$7 ; mask off ; 2 + tax ; 1 + lda <(color_progression),X ; 2 + sta (BASL),Y ; 2 +no_change: + + dey ; 1 + bpl xloop ; 2 + + dec CV ; 2 + + bpl yloop ; 2 + + bmi scroll_loop ; 2 + +color_progression: + .byte $00 ; 8->0 ; 1000 -> 0000 ; needed + .byte $bb ; 9->11 ; 1001 -> 1011 + .byte $00 ; 10->0 ; 1010 -> 0000 ; needed + .byte $aa ; 11->10 ; 1011 -> 1010 + .byte $00 ; 12->0 ; 1100 -> 0000 ; don't care + .byte $99 ; 13->9 ; 1101 -> 1001 + .byte $00 ; 14->0 ; 1110 -> 0000 ; don't care + .byte $dd ; 15->13 ; 1111 -> 1101 +