dos33fsprogs/fire/fire_extreme.s

139 lines
3.1 KiB
ArmAsm
Raw Normal View History

; Apple ][ Lo-res fire animation, size-optimized to 63 bytes
2019-01-04 01:09:32 +00:00
; by deater (Vince Weaver) <vince@deater.net>
; 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
2019-01-04 01:09:32 +00:00
; Zero Page
WNDTOP = $22
WNDBTM = $23
2019-01-04 01:09:32 +00:00
CV = $25
BASL = $28
BASH = $29
BAS2L = $2A
BAS2H = $2B
SEEDL = $4E
2019-01-04 01:09:32 +00:00
; Soft Switches
SET_GR = $C050 ; Enable graphics
FULLGR = $C052 ; Full screen, no text
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)
2019-01-04 02:20:49 +00:00
VTABZ = $FC24 ; VTABZ variant takes row in Accumulator
2019-01-04 01:09:32 +00:00
fire_demo:
; Set lores graphics
2019-01-04 01:09:32 +00:00
bit SET_GR ; force graphics mode ; 3
; happily at bootup FULLGR and LORES
; seem to already be in the right positions
; so we get LORES 40x48 mode
2019-01-04 01:09:32 +00:00
; Set window. This seems to be set properly at boot though
; lda #0
; sta WNDTOP
; lda #24
; sta WNDBTM
2019-01-04 01:09:32 +00:00
scroll_loop:
jsr SCROLL ; scrolls screen up one row ; 3
2019-01-04 01:09:32 +00:00
;======================================
; re-draw bottom line (row 23) as white
2019-01-04 01:09:32 +00:00
; 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
2019-01-04 01:09:32 +00:00
w_loop:
sta (BAS2L),Y ; hline 23 (46+47) ; 2
2019-01-04 01:09:32 +00:00
dey ; 1
bpl w_loop ; 2
2019-01-04 01:09:32 +00:00
;============
; 8
2019-01-04 01:09:32 +00:00
fire_loop:
lda #22 ; start at line 22 ; 2
sta CV ; store in Row location ; 2
2019-01-04 01:09:32 +00:00
yloop:
; puts address of row CV into BASL:BASH
jsr VTAB ; 3
; loop for X values 39 ... 0
ldy #39 ; 2
2019-01-04 01:09:32 +00:00
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:
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
; end inlined RNG
; Randomly either use current value, or decay by one
2019-01-04 01:09:32 +00:00
bmi no_change ; assume bit 7 is as random as bit 0 ; 2
; Lookup the new color in table
2019-01-04 01:09:32 +00:00
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
.byte $bb ; 9->11 ; 1001 1011
.byte $00 ; 10->0 ; 1010 0000
.byte $aa ; 11->10 ; 1011 1010
.byte $00 ; 12->0 ; 1100 0000
.byte $99 ; 13->9 ; 1101 1001
.byte $00 ; 14->0 ; 1110 0000
.byte $dd ; 15->13 ; 1111 1101