; width and height of the fire cell matrix ; Be sure to sync this with fastfire.inc! .EQU FIREWIDTH 319 .EQU FIREHEIGHT 79 ; ; The cell matrix actually has one column ; and one row more than FIREWIDTH and ; FIREHEIGHT to handle the negative ; X offsets when calculating new ; cell values. ; Likewise, there is one more row. ; So rows are processed from 0 to FIREHEIGHT - 2 ; and columms from 1 to FIREWIDTH - 1. ; cells considered for calculating new ; value for cell O (reference cells): ; .....O...... ; ....123..... ; .....4...... ; args: pointer to fire cell buffer .EQU FF_ROW_COUNT 0 .EQU FF_COL_COUNT 4 .EQU FF_ROW_OFFS 8 .EQU FF_OFFS1 12 .EQU FF_OFFS2 16 .EQU FF_OFFS3 20 .EQU FF_OFFS4 24 .EQU FF_CELL_PTR 28 .EQU FF_FS 32 FASTFIREUPDATE: FPADJ -FF_FS STORE FF_CELL_PTR LOADC FIREHEIGHT-1 STORE FF_ROW_COUNT ; calculate offsets for reference cells LOADC FIREWIDTH+1 SHL 2 DUP STORE FF_ROW_OFFS ; offset to next row: WIDTH*4 DEC 4 ; offset to cell 1: row offset - 4 DUP STORE FF_OFFS1 INC 4 DUP STORE FF_OFFS2 ; offset to cell 2: + 4 INC 4 STORE FF_OFFS3 ; offset to cell 3: + 4 LOAD FF_ROW_OFFS SHL 1 ; offset to cell 4: row offset * 2 STORE FF_OFFS4 ; start at column 1 LOAD FF_CELL_PTR INC 4 STORE FF_CELL_PTR FF_ROW: LOADC FIREWIDTH-1 STORE FF_COL_COUNT FF_COL: LOAD FF_CELL_PTR LOAD FF_OFFS1 ADD LOADI LOAD FF_CELL_PTR LOAD FF_OFFS2 ADD LOADI LOAD FF_CELL_PTR LOAD FF_OFFS3 ADD LOADI LOAD FF_CELL_PTR LOAD FF_OFFS4 ADD LOADI ADD ADD ADD SHR SHR ; if new cell value > 0, subtract 1 to cool down DUP CBRANCH.Z FF_SKIP DEC 1 FF_SKIP: LOAD FF_CELL_PTR ; load cell ptr SWAP ; swap with new value STOREI 4 ; store with postincrement STORE FF_CELL_PTR ; save new ptr value LOAD FF_COL_COUNT ; decrement column count DEC 1 DUP STORE FF_COL_COUNT CBRANCH.NZ FF_COL ; loop if col count <> 0 ; at the end of a row, go to next row ; by adding 8 to the cell pointer, ; skipping the first cell of the next row LOAD FF_CELL_PTR INC 8 STORE FF_CELL_PTR LOAD FF_ROW_COUNT ; decrement row count DEC 1 DUP STORE FF_ROW_COUNT CBRANCH.NZ FF_ROW ; loop if row count <> 0 FF_EXIT: FPADJ FF_FS RET ; framebuffer controller registers .EQU FB_RA $900 .EQU FB_WA $901 .EQU FB_IO $902 .EQU FB_PS $903 .EQU FB_PD $904 .EQU FB_CTL $905 .EQU WORDS_PER_LINE 80 ; fire width in vmem words (strict left-to-right evaluation) .EQU FFD_ROW_WORDS 1 + FIREWIDTH / 8 ; draw all fire cells ; args: pointer to fire cell buffer, screen x, screen y .EQU FFD_CELL_PTR 0 .EQU FFD_X 4 .EQU FFD_Y 8 .EQU FFD_ROW_COUNT 12 .EQU FFD_ROW_WORDCOUNT 16 .EQU FFD_VMEM_PTR 20 .EQU FFD_FS 24 FASTFIREDRAW: FPADJ -FFD_FS STORE FFD_Y STORE FFD_X STORE FFD_CELL_PTR ; calculate video memory addr ; addr = y * 80 + X / 8 LOAD FFD_Y SHL 2 ; y * 16 SHL 2 DUP SHL 2 ; + y * 64 ADD ; = y * 80 LOAD FFD_X SHR SHR SHR ADD ; + x / 8 DUP STORE FFD_VMEM_PTR LOADC FB_WA ; set vmem write address SWAP STOREI DROP LOADC FIREHEIGHT + 1 STORE FFD_ROW_COUNT FFD_ROW: LOADC FFD_ROW_WORDS STORE FFD_ROW_WORDCOUNT LOADC FB_WA ; set vmem write address LOAD FFD_VMEM_PTR STOREI DROP FFD_WORD: LOAD FFD_CELL_PTR ; load cell ptr LOADC 0 ; vmem word, start with 0 ; leftmost pixel (0) OVER ; [ cptr, vmemw, cptr ] LOADI ; load cell value [ cptr, vmemw, cellval ] SHR ; scale it down (from 7 bits to 4) SHR SHR ; [ cptr, vmemw, cellval shr 3 ] OR ; [ cptr, vmemw ] SWAP ; [ vmemw, cptr ] INC 4 ; increment cell ptr on stack [ vmemw, cptr + 4 ] SWAP ; [ cptr + 4, vmemw ] SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 1 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 2 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 3 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 4 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 5 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 6 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP SHL 2 ; move bits to left for next pixel SHL 2 ; pixel 7 OVER LOADI ; load cell value SHR ; scale it down (from 7 bits to 4) SHR SHR OR SWAP INC 4 ; increment cell ptr on stack SWAP ; store word to vmem ; vmem write addr will autoincrement LOADC FB_IO SWAP STOREI DROP STORE FFD_CELL_PTR ; prepare for next word LOAD FFD_ROW_WORDCOUNT DEC 1 DUP STORE FFD_ROW_WORDCOUNT CBRANCH.NZ FFD_WORD ; prepare for next row LOAD FFD_VMEM_PTR LOADC WORDS_PER_LINE ADD STORE FFD_VMEM_PTR LOAD FFD_ROW_COUNT DEC 1 DUP STORE FFD_ROW_COUNT CBRANCH.NZ FFD_ROW FFD_EXIT: FPADJ FFD_FS RET