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