add sprites library and Xmas demo
This commit is contained in:
parent
def08c6c94
commit
d22baa3f36
5 changed files with 699 additions and 0 deletions
363
examples/sprites.s
Normal file
363
examples/sprites.s
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
.EQU SPRITE_HEIGHT 16
|
||||
|
||||
.EQU WORDS_PER_LINE 80
|
||||
.EQU FB_RA $900
|
||||
.EQU FB_WA $901
|
||||
.EQU FB_IO $902
|
||||
.EQU FB_PS $903
|
||||
|
||||
; calculate mask for a word of pixels
|
||||
; args: word of pixels with four bits per pixel
|
||||
; returns: value that masks out all pixels that are set
|
||||
CALC_MASK:
|
||||
LOADC $F ; pixel mask
|
||||
C_M_L0:
|
||||
SWAP ; swap mask and pixels value
|
||||
AND.S1.X2Y ; isolate one pixel, keep args
|
||||
CBRANCH.Z C_M_L1 ; if pixel is zero, dont set mask bits
|
||||
OVER ; copy current mask
|
||||
OR ; or into pixels value
|
||||
C_M_L1:
|
||||
SWAP ; swap back, ToS is now mask bits
|
||||
SHL 2 ; shift mask for next pixel to the left
|
||||
SHL 2
|
||||
|
||||
DUP
|
||||
CBRANCH.NZ C_M_L0 ; if mask is zero, we are done
|
||||
DROP ; remove mask bits
|
||||
NOT ; invert result
|
||||
RET
|
||||
|
||||
; calculate vmem address from coordinates
|
||||
; args: x,y
|
||||
; returns: vmem word number
|
||||
CALC_VMEM_ADDR:
|
||||
; only works if WORDS_PER_LINE is 80
|
||||
; and pixels per word is 8
|
||||
|
||||
DUP
|
||||
; y
|
||||
SHL 2
|
||||
SHL 2
|
||||
SHL 2 ; * 64
|
||||
|
||||
SWAP
|
||||
; + y
|
||||
SHL 2
|
||||
SHL 2 ; * 16
|
||||
ADD
|
||||
|
||||
SWAP
|
||||
; word offset = X/8
|
||||
SHR
|
||||
SHR
|
||||
SHR
|
||||
ADD
|
||||
|
||||
RET
|
||||
|
||||
; put a sprite on screen
|
||||
; arg: x,y pointer to sprite data
|
||||
.EQU PS_VMEM_ADDR 0
|
||||
.EQU PS_SPRITE_DATA 4
|
||||
.EQU PS_SPRITE_LINES 8
|
||||
.EQU PS_X 12
|
||||
.EQU PS_Y 16
|
||||
.EQU PS_SHIFT_C 20
|
||||
.EQU PS_SPILL 24
|
||||
.EQU PS_FS 28
|
||||
PUTSPRITE:
|
||||
FPADJ -PS_FS
|
||||
STORE PS_SPRITE_DATA
|
||||
STORE PS_Y
|
||||
STORE PS_X
|
||||
|
||||
; calculate vmem address
|
||||
LOAD PS_X
|
||||
LOAD PS_Y
|
||||
LOADCP CALC_VMEM_ADDR
|
||||
CALL
|
||||
STORE PS_VMEM_ADDR
|
||||
|
||||
LOAD PS_X ; shift count = x mod 8
|
||||
LOADC 7
|
||||
AND
|
||||
STORE PS_SHIFT_C
|
||||
|
||||
LOADC SPRITE_HEIGHT
|
||||
STORE PS_SPRITE_LINES
|
||||
|
||||
; loop over each line of the sprite
|
||||
PS_LOOP1:
|
||||
; set read and write address
|
||||
; in the vga controller
|
||||
LOADC FB_RA ; read address register
|
||||
LOAD PS_VMEM_ADDR
|
||||
STOREI 1 ; use autoincrement to get to the next register
|
||||
LOAD PS_VMEM_ADDR
|
||||
STOREI
|
||||
DROP
|
||||
|
||||
LOAD PS_SPRITE_DATA ; address of sprite data
|
||||
DUP
|
||||
INC 4 ; increment pointer
|
||||
STORE PS_SPRITE_DATA ; and store it again
|
||||
LOADI ; load word from orig. address
|
||||
|
||||
|
||||
LOADC 0
|
||||
STORE PS_SPILL
|
||||
|
||||
; loop to shift pixel data to right
|
||||
LOAD PS_SHIFT_C ; load shift count
|
||||
PS_LOOP2:
|
||||
DUP ; test it for zero
|
||||
CBRANCH.Z PS_LOOP2_X
|
||||
|
||||
SWAP ; swap count with pixels
|
||||
|
||||
; save the pixel that is shifted out
|
||||
LOADC $F ; mask the four bits
|
||||
AND.S0 ; keep original value on stack
|
||||
BROT ; and move them to MSB
|
||||
BROT
|
||||
BROT
|
||||
SHL 2
|
||||
SHL 2 ; shift by 28 in total
|
||||
|
||||
LOAD PS_SPILL ; load spill bits
|
||||
SHR ; shift by four to make space
|
||||
SHR
|
||||
SHR
|
||||
SHR
|
||||
OR ; or with orig value
|
||||
STORE PS_SPILL ; store new value
|
||||
|
||||
SHR ; shift pixels right
|
||||
SHR ; four bits per pixel
|
||||
SHR
|
||||
SHR
|
||||
|
||||
SWAP ; swap back, count now ToS
|
||||
DEC 1
|
||||
BRANCH PS_LOOP2
|
||||
PS_LOOP2_X:
|
||||
DROP ; remove shift count, shifted pixels now in ToS
|
||||
|
||||
DUP
|
||||
LOADCP CALC_MASK ; calculate sprite mask for this word
|
||||
CALL
|
||||
|
||||
LOADCP FB_IO ; address of the i/o register
|
||||
LOADI ; read word from video mem
|
||||
|
||||
AND ; and word with mask
|
||||
|
||||
OR ; OR sprite data with original pixels
|
||||
|
||||
LOADCP FB_IO
|
||||
SWAP
|
||||
STOREI ; store result into i/o reg
|
||||
DROP
|
||||
|
||||
;
|
||||
; process spilled bits and right half of sprite data
|
||||
;
|
||||
|
||||
; put spill bits on stack for later
|
||||
LOAD PS_SPILL
|
||||
|
||||
LOAD PS_SPRITE_DATA ; address of sprite data
|
||||
DUP
|
||||
INC 4 ; increment pointer
|
||||
STORE PS_SPRITE_DATA ; and store it again
|
||||
LOADI ; load word from orig. address
|
||||
|
||||
; reset spill bits
|
||||
LOADC 0
|
||||
STORE PS_SPILL
|
||||
|
||||
; shift pixel data to right
|
||||
LOAD PS_SHIFT_C ; load shift count
|
||||
PS_LOOP3: ; test it for zero
|
||||
DUP
|
||||
CBRANCH.Z PS_LOOP3_X
|
||||
|
||||
SWAP ; swap count with pixels
|
||||
|
||||
; save the pixel that is shifted out
|
||||
LOADC $F ; mask the four bits
|
||||
AND.S0 ; keep original value on stack
|
||||
BROT ; and move them to MSB
|
||||
BROT
|
||||
BROT
|
||||
SHL 2
|
||||
SHL 2 ; shift by 28 in total
|
||||
|
||||
LOAD PS_SPILL ; load spill bits
|
||||
SHR ; shift by four to make space
|
||||
SHR
|
||||
SHR
|
||||
SHR
|
||||
OR ; or with orig value
|
||||
STORE PS_SPILL ; store new value
|
||||
|
||||
SHR ; shift pixels right
|
||||
SHR ; four bits per pixel
|
||||
SHR
|
||||
SHR
|
||||
|
||||
SWAP ; swap back, count now ToS
|
||||
DEC 1
|
||||
BRANCH PS_LOOP3
|
||||
PS_LOOP3_X:
|
||||
DROP ; remove shift count, shifted pixels now in ToS
|
||||
|
||||
OR ; or together with spill bits
|
||||
|
||||
DUP
|
||||
LOADCP CALC_MASK ; calculate sprite mask
|
||||
CALL
|
||||
|
||||
LOADCP FB_IO ; load original pixels
|
||||
LOADI
|
||||
|
||||
AND ; and with mask
|
||||
|
||||
OR ; or together with original pixels
|
||||
|
||||
LOADCP FB_IO
|
||||
SWAP
|
||||
STOREI
|
||||
DROP
|
||||
|
||||
; write spilled bits into next vmem word
|
||||
LOAD PS_SPILL ; get spill bits
|
||||
DUP
|
||||
LOADCP CALC_MASK ; calculate sprite mask for spill bits
|
||||
CALL
|
||||
|
||||
LOADCP FB_IO
|
||||
LOADI ; load next vmem word
|
||||
AND ; apply sprite mask
|
||||
|
||||
OR ; OR in spill bits
|
||||
|
||||
LOADCP FB_IO
|
||||
SWAP ; swap pixels and addr
|
||||
STOREI ; write back
|
||||
DROP
|
||||
|
||||
LOAD PS_SPRITE_LINES ; decrement lines count
|
||||
DEC 1
|
||||
DUP
|
||||
CBRANCH.Z PS_L_XT ; exit if zero
|
||||
STORE PS_SPRITE_LINES
|
||||
; prepare next line
|
||||
LOAD PS_VMEM_ADDR
|
||||
LOADC WORDS_PER_LINE ; increment to next screen line
|
||||
ADD
|
||||
STORE PS_VMEM_ADDR
|
||||
BRANCH PS_LOOP1
|
||||
PS_L_XT:
|
||||
DROP
|
||||
|
||||
FPADJ PS_FS
|
||||
RET
|
||||
|
||||
; undraw a sprite, i.e. draw background data
|
||||
; over a sprite location
|
||||
; args: x,y, ptr to background data
|
||||
.EQU UD_S_X 0
|
||||
.EQU UD_S_Y 4
|
||||
.EQU UD_S_PXS 8
|
||||
.EQU UD_S_BGDATA 12
|
||||
.EQU UD_S_OFFSET 16
|
||||
.EQU UD_S_BGORIG 20
|
||||
.EQU UD_S_FS 24
|
||||
UNDRAWSPRITE:
|
||||
FPADJ -UD_S_FS
|
||||
STORE UD_S_BGORIG
|
||||
STORE UD_S_Y
|
||||
STORE UD_S_X
|
||||
|
||||
; calculate pixel shift
|
||||
LOAD UD_S_X
|
||||
LOADC $7
|
||||
AND
|
||||
STORE UD_S_PXS
|
||||
|
||||
; calculate vmem offset
|
||||
LOAD UD_S_X
|
||||
LOAD UD_S_Y
|
||||
LOADCP CALC_VMEM_ADDR
|
||||
CALL
|
||||
|
||||
DUP
|
||||
STORE UD_S_OFFSET
|
||||
|
||||
; calculate background data address from offset
|
||||
SHL 2
|
||||
LOAD UD_S_BGORIG
|
||||
ADD
|
||||
STORE UD_S_BGDATA
|
||||
|
||||
LOADC SPRITE_HEIGHT ; line count
|
||||
UD_S_L1:
|
||||
; store vmem offset into write addr reg
|
||||
LOADCP FB_WA
|
||||
LOAD UD_S_OFFSET
|
||||
STOREI 1 ; ugly but fast: reuse addr
|
||||
; with postincrement to
|
||||
; get to FB_IO for STOREI below
|
||||
|
||||
; load a word of background data
|
||||
LOAD UD_S_BGDATA
|
||||
LOADI
|
||||
; and write it to vmem
|
||||
STOREI
|
||||
; reuse addr from STOREI
|
||||
|
||||
; load 2nd word of background data
|
||||
LOAD UD_S_BGDATA
|
||||
INC 4
|
||||
DUP
|
||||
STORE UD_S_BGDATA
|
||||
LOADI
|
||||
STOREI ; and write it to vmem
|
||||
DROP
|
||||
|
||||
; if pixel shift is zero, no 3rd word
|
||||
LOAD UD_S_PXS
|
||||
CBRANCH.Z UD_S_L2
|
||||
|
||||
; load 3rd word of background data
|
||||
LOADCP FB_IO
|
||||
LOAD UD_S_BGDATA
|
||||
INC 4
|
||||
DUP
|
||||
STORE UD_S_BGDATA
|
||||
LOADI
|
||||
STOREI ; and write it to vmem
|
||||
DROP
|
||||
|
||||
UD_S_L2:
|
||||
LOAD UD_S_OFFSET
|
||||
LOADCP WORDS_PER_LINE
|
||||
ADD
|
||||
DUP
|
||||
STORE UD_S_OFFSET
|
||||
SHL 2
|
||||
LOAD UD_S_BGORIG
|
||||
ADD
|
||||
STORE UD_S_BGDATA
|
||||
|
||||
DEC 1 ; decrement counter
|
||||
DUP
|
||||
CBRANCH.NZ UD_S_L1 ; check for zero
|
||||
|
||||
DROP ; remove counter
|
||||
|
||||
FPADJ UD_S_FS
|
||||
RET
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue