
; Fire104b 
; an Intro for the ZX Spectrum 48k 
; by nf

; nf@wh3rd.net
; http://nf.wh3rd.net/ 
; 31 October 2009

; Partycoded at Syntax Party 2009 in Melbourne, Australia.

; Just your typical cellular automata fire effect in Speccy chunkymode.
; The party version was 139b. It's now 104b without any sizecoding trickery.

; This is my first ZX Spectrum 48K production. In fact, it's my first proper 
; Z80 assembly program of any kind. If you're good at Z80 assembly and can 
; make any suggestions, please drop me a line.

; Thanks and Greets to:
;  darkmoon - for helping me type the whole prod into my Speccy in decimal
;             when we couldn't get the tape loader to work,
;  an4ki rob - for lending me his mixer so I could get the tape loader working,
;  a life in hell - for the prng algorithm and being crazily talented,
;  alhazan, scurge, sh0ck, cTrix, ript, voltage, spoony, 
;  everyone who was amused by the unusual choice in platform,
;  and all the Syntax Party crew and participants; what an awesome event!

; Without further ado, the code:

	org 32768
loop:

	; pseudorandom number generator
	ld a, (rand_seed)
	sla a
	jp nc, rand_jp
	xor $1d
rand_jp:
	ld (rand_seed), a

	; plot random white point on the lower part of the buffer
	ld c, $07 ; pal white
	ld h, $62
	ld l, a
	ld (hl), c

;calc_fire
	; update each pixel in the buffer, top-to-bottom
	ld ix, $6000 ; buffer pointer
calc_fire_loop:
	; add 1/2 below left/right
	ld a, (ix+$21)
	add a, (ix+$1F)
	sra a

	; add 1/4 below direct
	ld b, (ix+$20)
	sra b
	sra b
	add a, b

	; add 1/2 original value
	ld b, (ix+0)
	sra b
	add a, b

	; limit to pallette range
	cp $08
	jp c, calc_fire_write
	ld a, $07

calc_fire_write:
	; write to buffer
	ld (ix+0), a

	; increment pointer and check if done
	inc ix
	ld c, ixh ; (it seems like there must be an easier way
	ld a, c   ;  do this than using the c register temporarily?)
	cp $63
	jp nz, calc_fire_loop
;calc_fire_end

;put_pal
	; write the buffer to the screen attribute memory
	; using pal as the attribute look-up table
	ld ix, $6000     ; buffer pointer
	ld de, $5800     ; screen attribute pointer
	ld b, 0
put_pal_loop:
	; load palette value from buffer
	ld c, (ix+0)     ; palette val (0-7)

	; load attribute value from pal
	ld hl, pal
	add hl, bc
	ld a, (hl)

	; write to attribute memory
	ld (de), a

	; increment pointers 
	inc ix
	inc de
	; check if done
	ld a, d
	cp $5B
	jp nz, put_pal_loop
;put_pal_end

	jp loop

pal:
	defb %01111000, %01101000, %01110000, %01010000
	defb %00111000, %00110000, %00010000, %00000000
rand_seed:
	defb $0F

; fin
