update sprites unit to use shifter/maskgen
This commit is contained in:
parent
c119a2a5bb
commit
66a50d5ea8
2 changed files with 86 additions and 157 deletions
|
|
@ -1,5 +1,17 @@
|
|||
program graphbench;
|
||||
uses sprites;
|
||||
|
||||
var starttime,endtime:DateTime;
|
||||
spriteData:SpritePixels;
|
||||
|
||||
procedure readSpriteData(filename:string);
|
||||
var f:file;
|
||||
begin
|
||||
open(f,filename,ModeReadOnly);
|
||||
seek(f,8); (* skip file header *)
|
||||
read(f,spriteData);
|
||||
close(f);
|
||||
end;
|
||||
|
||||
procedure startBench(name:string);
|
||||
begin
|
||||
|
|
@ -13,7 +25,7 @@ var secDelta, minDelta, hourDelta:integer;
|
|||
begin
|
||||
if i < 10 then
|
||||
write('0');
|
||||
write(i);
|
||||
write(i);
|
||||
end;
|
||||
begin
|
||||
endTime := GetTime;
|
||||
|
|
@ -49,6 +61,20 @@ begin
|
|||
randint := r;
|
||||
end;
|
||||
|
||||
procedure drawsprites(count:integer);
|
||||
var i,col,x,y:integer;
|
||||
begin
|
||||
col := 1;
|
||||
for i := 1 to count do
|
||||
begin
|
||||
x := randint(350);
|
||||
y := randint(350);
|
||||
PutSprite(x,y,spriteData);
|
||||
col := col + 1;
|
||||
if col > 15 then col := 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure drawlines(count:integer);
|
||||
var i,col,x1,y1,x2,y2:integer;
|
||||
begin
|
||||
|
|
@ -80,13 +106,20 @@ begin
|
|||
end;
|
||||
|
||||
begin
|
||||
readSpriteData('rocket.sprt');
|
||||
|
||||
InitGraphics;
|
||||
startBench('200K points');
|
||||
startBench('points 200K');
|
||||
drawpoints(200000);
|
||||
endBench;
|
||||
|
||||
InitGraphics;
|
||||
startBench('10K lines');
|
||||
startBench('lines 10K');
|
||||
drawlines(10000);
|
||||
endBench;
|
||||
|
||||
InitGraphics;
|
||||
startBench('sprites 50K');
|
||||
drawsprites(50000);
|
||||
endBench;
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -6,28 +6,13 @@
|
|||
.EQU FB_WA $904
|
||||
.EQU FB_IO $908
|
||||
.EQU FB_PS $90C
|
||||
|
||||
; 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
|
||||
.EQU FB_PD $910
|
||||
.EQU FB_CTL $914
|
||||
.EQU FB_SHIFTER $918
|
||||
.EQU FB_SHIFTCOUNT $91C
|
||||
.EQU FB_SHIFTERM $920
|
||||
.EQU FB_SHIFTERSP $924
|
||||
.EQU FB_MASKGEN $928
|
||||
|
||||
; calculate vmem address from coordinates
|
||||
; args: x,y
|
||||
|
|
@ -67,13 +52,19 @@ CALC_VMEM_ADDR:
|
|||
.EQU PS_SHIFT_C 20
|
||||
.EQU PS_SPILL 24
|
||||
.EQU PS_STRIPE_C 28
|
||||
.EQU PS_FS 32
|
||||
.EQU PS_BPSAVE 32
|
||||
.EQU PS_FS 36
|
||||
PUTSPRITE:
|
||||
FPADJ -PS_FS
|
||||
STORE PS_SPRITE_DATA
|
||||
STORE PS_Y
|
||||
STORE PS_X
|
||||
|
||||
LOADREG BP
|
||||
STORE PS_BPSAVE
|
||||
LOADC 0
|
||||
STOREREG BP
|
||||
|
||||
; calculate vmem address
|
||||
LOAD PS_X
|
||||
LOAD PS_Y
|
||||
|
|
@ -81,11 +72,6 @@ PUTSPRITE:
|
|||
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
|
||||
|
||||
|
|
@ -93,12 +79,10 @@ PUTSPRITE:
|
|||
PS_LOOP1:
|
||||
; set read and write address
|
||||
; in the vga controller
|
||||
LOADC FB_RA ; read address register
|
||||
LOAD PS_VMEM_ADDR
|
||||
STOREI 4 ; use autoincrement to get to the next register
|
||||
LOAD PS_VMEM_ADDR
|
||||
STOREI
|
||||
DROP
|
||||
DUP
|
||||
STORE.B FB_RA
|
||||
STORE.B FB_WA
|
||||
|
||||
LOAD PS_SPRITE_DATA ; address of sprite data
|
||||
DUP
|
||||
|
|
@ -106,61 +90,19 @@ PS_LOOP1:
|
|||
STORE PS_SPRITE_DATA ; and store it again
|
||||
LOADI ; load word from orig. address
|
||||
|
||||
; ------- one word of sprite pixels on stack
|
||||
|
||||
LOADC 0
|
||||
STORE PS_SPILL
|
||||
STORE.B FB_SHIFTER
|
||||
LOAD PS_X
|
||||
STORE.B FB_SHIFTCOUNT
|
||||
|
||||
; 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
|
||||
LOAD.B FB_SHIFTERM ; get shifted mask
|
||||
LOAD.B FB_IO ; and background pixel data
|
||||
AND ; remove foreground pixels
|
||||
|
||||
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
|
||||
LOAD.B FB_SHIFTER ; get shifted pixels
|
||||
OR ; combine with background
|
||||
STORE.B FB_IO ; store into vmem
|
||||
|
||||
; set counter for remaining stripes
|
||||
LOADC SPRITE_STRIPES - 1
|
||||
|
|
@ -170,8 +112,8 @@ PS_LOOP2_X:
|
|||
; process spilled bits and next vertical stripe of sprite data
|
||||
;
|
||||
PS_NEXT_STRIPE:
|
||||
; put spill bits on stack for later
|
||||
LOAD PS_SPILL
|
||||
;use spill bits from first column
|
||||
LOAD.B FB_SHIFTERSP
|
||||
|
||||
LOAD PS_SPRITE_DATA ; address of sprite data
|
||||
DUP
|
||||
|
|
@ -179,65 +121,20 @@ PS_NEXT_STRIPE:
|
|||
STORE PS_SPRITE_DATA ; and store it again
|
||||
LOADI ; load word from orig. address
|
||||
|
||||
; reset spill bits
|
||||
LOADC 0
|
||||
STORE PS_SPILL
|
||||
|
||||
; last spill bits are on ToS now
|
||||
|
||||
; shift pixel data to right
|
||||
LOAD PS_SHIFT_C ; load shift count
|
||||
PS_LOOP3: ; test it for zero
|
||||
STORE.B FB_SHIFTER ; store into shifter
|
||||
LOAD PS_X
|
||||
STORE.B FB_SHIFTCOUNT ; shift stuff
|
||||
LOAD.B FB_SHIFTER ; get shifted pixels
|
||||
OR ; combine with spill bits (see above)
|
||||
DUP
|
||||
CBRANCH.Z PS_LOOP3_X
|
||||
STORE.B FB_MASKGEN ; store to mask reg to get new mask
|
||||
|
||||
SWAP ; swap count with pixels
|
||||
LOAD.B FB_MASKGEN ; get mask for spill bits + shifted pixels
|
||||
LOAD.B FB_IO ; get vmem data
|
||||
AND ; remove foreground pixels from bg
|
||||
|
||||
; 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
|
||||
OR ; combine with shifted pixels
|
||||
STORE.B FB_IO ; write to vmem
|
||||
|
||||
LOAD PS_STRIPE_C ; decrement stripe count
|
||||
DEC 1
|
||||
|
|
@ -246,22 +143,18 @@ PS_LOOP3_X:
|
|||
CBRANCH.NZ PS_NEXT_STRIPE ; if non-zero, next stripe
|
||||
|
||||
; write spilled bits of the last stripe into next vmem word
|
||||
LOAD PS_SPILL ; get spill bits
|
||||
LOAD.B FB_SHIFTERSP ; get spill bits
|
||||
DUP
|
||||
LOADCP CALC_MASK ; calculate sprite mask for spill bits
|
||||
CALL
|
||||
STORE.B FB_MASKGEN
|
||||
LOAD.B FB_MASKGEN ; get sprite mask for spill bits
|
||||
|
||||
LOADCP FB_IO
|
||||
LOADI ; load next vmem word
|
||||
LOAD.B FB_IO ; 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
|
||||
|
||||
STORE.B FB_IO ; write to vmem
|
||||
|
||||
LOAD PS_SPRITE_LINES ; decrement lines count
|
||||
DEC 1
|
||||
DUP
|
||||
|
|
@ -275,7 +168,10 @@ PS_LOOP3_X:
|
|||
BRANCH PS_LOOP1
|
||||
PS_L_XT:
|
||||
DROP
|
||||
|
||||
|
||||
LOAD PS_BPSAVE
|
||||
STOREREG BP
|
||||
|
||||
FPADJ PS_FS
|
||||
RET
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue