Files
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

407 lines
10 KiB
Scheme

//{{{ 16 bit zbuffer, 8 bit pixels
//{{{ about zbuffer.ss
//
// zbuffer.s
//
// 16 bit Z buffer routine.
//
// This routine takes a scan line segment and performs
// a standard z check across the segment, whilst interpolating z
//
// The routine assumes a pixel size of 8 bits.
// All scan segments are flat shaded.
// Assume following inputs
//
// int length; ; no. of pixels in segment
// fpoint zstart; ; z start value
// fpoint deltaz; ; delta z with x
// pixel cstart; ; initial colour
// pixel deltac; ; delta colour with x
//
//
// r1 return address
// r2 stack pointer
// r3 frame pointer
// r4..r15 local variables left unchanged by subroutine
// r16..r27 parameters and temporaries, not preserved by subroutines
// r28..r30 temporaries, not preserved by subroutine
// r31 addressing temporary
//
// f0/f1 zero
// f2..f7 local values, preserved by subroutine
// f8..f15 parameters and temporaries, not preserved by subroutine
// f16..f31 temporary
//
//}}}
// ROUTINE PARAMETRS
define(sp, r2) //stack pointer
define(Zaddr, r16) // zixel address
define(Paddr, r17) // pixel address
define(Zstart, r18) // start z value
define(dZ, r19) // delta z for each pixel
define(Xstart, r20) // start x value
define(length, r21) // total no. of pixels in segment
define(Col, r22) // start colour
//
// GLOBAL DATA
//
//
// LOCALS
define(i, r28)
define(lc, r29)
define(itemp1, r29)
define(itemp2, r30)
define(itemp3, r31)
define(oldZval, f8) //current z buffer value
define(newZval, f10) // new z value
define(lZmaskl, f12) // mask for left end of scan segment
define(lZmaskl1, f12)
define(lZmaskl2, f13)
define(lZmaskh, f14)
define(lZmaskh1, f14)
define(lZmaskh2, f15)
define(rZmaskl, f16) // mask for right end of scan segment
define(rZmaskl1, f16)
define(rZmaskl2, f17)
define(rZmaskh, f18)
define(rZmaskh1, f18)
define(rZmaskh2, f19)
define(iZval, f20) // interpolated z value
define(colour, f22) // 8 pixels of constant colour
define(colourl, f22)
define(colourh, f23)
define(ftemp1, f24) // temporary val
define(ftemp2, f26)
define(iZ, f26) // z interpolator
define(iZl, f26)
define(iZh, f27)
define(aZl, f28) // z accumulator
define(aZh, f29)
define(aZ, f28)
define(aZ1, f28)
define(aZ2, f30)
//
// Table of Z masks for un-aligned accesses
//
.data; .align .double
lZmask_table:: .long 0x00000000, 0x00000000, 0x00000000, 0x00000000
.long 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000
.long 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000
.long 0xFFFFFFFF, 0x0000FFFF, 0x00000000, 0x00000000
.long 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
.long 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0x00000000
.long 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000
.long 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF
rZmask_table:: .long 0x00000000, 0x00000000, 0x00000000, 0x00000000
.long 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
.long 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
.long 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF
.long 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF
.long 0x00000000, 0x00000000, 0xFFFF0000, 0xFFFFFFFF
.long 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF
.long 0x00000000, 0x00000000, 0x00000000, 0xFFFF0000
//
//
.globl _zbufferSegment
.text
_zbufferSegment::
// generate colour
ixfr Col,colourl
fmov.ss colourl,colourh
// generate left and right masks
and 7,Xstart,itemp1 // determine alignment of start pixel
subs 8,itemp1,itemp2 // 4 - align
subs length,itemp2,length // adjust length
and 7,length,itemp3 // determine alignment
mov lZmask_table,itemp2
shl 4,itemp1,i
adds itemp2,i,itemp2
fld.q 0(itemp2),lZmaskl
mov rZmask_table,itemp2
shl 4,itemp3,i
adds itemp2,i,itemp2
fld.q 0(itemp2),rZmaskl
subs 0,length,r0
bc over64bits // check for only 64 bit segment
fxfr lZmaskl1,i
fxfr rZmaskl1,itemp2
or i,itemp2,itemp2
ixfr itemp2,lZmaskl1
fxfr lZmaskl2,i
fxfr rZmaskl2,itemp2
or i,itemp2,itemp2
ixfr itemp2,lZmaskl2
fxfr lZmaskh1,i
fxfr rZmaskh1,itemp2
or i,itemp2,itemp2
ixfr itemp2,lZmaskh1
fxfr lZmaskh2,i
fxfr rZmaskh2,itemp2
or i,itemp2,itemp2
ixfr itemp2,lZmaskh2
over64bits:
// initialise accumulator to Zstart - ndZ
ixfr itemp1,ftemp1
ixfr dZ,ftemp2
// 2 free cycles here
fmlow.dd ftemp1,ftemp2,ftemp1 // n * dZ
// 4 free cycles here so
adds -8,Zaddr,Zaddr // anticipate autoincrement
adds -8,Paddr,Paddr // anticipate autoincrement
fxfr ftemp1,itemp1
subs Zstart,itemp1,itemp2
ixfr itemp2,aZl
fmov.ss aZl, aZh //accumulator = Zstart-ndZ | Zstart-ndZ
.dual
// Process first 1 -> 8 pixels
// interpolate z over first pixels
fmov.ss f0,iZl // iZl = 0
shl 1,dZ,itemp1
fnop
ixfr itemp1,iZh // iZh = 2dZ
faddz aZ1,iZ,aZ1 // first result
shl 1,itemp1,itemp1 // 4dZ
fnop
ixfr dZ,iZl // iZl = dZ
fnop
ixfr dZ,iZh // iZh = dZ
faddz aZ1,iZ,aZ2 // second result
fld.d 8(Zaddr)++,oldZval // get first 4 zbuffer values
form lZmaskl,iZval // merge -> zval
ixfr itemp1,iZl // iZl = 4dZ
fzchks oldZval,iZval,newZval // check z over current pixels
ixfr itemp1,iZh // iZh = 4dZ
// interpolate z over next 4 pixels
faddz aZ1,iZ,aZ1
fld.d 8(Zaddr)++,oldZval // load old Zixel
faddz aZ2,iZ,aZ2
fst.d newZval,-8(Zaddr) // store new Zixel
form lZmaskh,iZval
nop
// if length > 8 then traverse rest of segment
fzchks oldZval,iZval,newZval // check z for next 4 Pixels
subs 8,length,r0
fnop
bnc last_8_pixels
fnop
adds -8,r0,i // loop increment
fnop
adds -8,length,lc // ensure loop for length only
fnop
bla i,lc,loop1
fnop
nop
loop1:
// interpolate z over next 4 pixels
faddz aZ1,iZ,aZ1
fld.d 8(Zaddr)++,oldZval // load old Zixel
faddz aZ2,iZ,aZ2
fst.d newZval,-8(Zaddr) // store new Zixel
form f0,iZval
pst.d colour,8(Paddr)++ // store new Pixel
fzchks oldZval,iZval,newZval // check z for next 4 Pixels
nop
// interpolate z over next 4 pixels
faddz aZ1,iZ,aZ1
fld.d 8(Zaddr)++,oldZval // load old Zixel
faddz aZ2,iZ,aZ2
fst.d newZval,-8(Zaddr) // store new Zixel
form f0,iZval
bla i,lc,loop1
fzchks oldZval,iZval,newZval // check z for next 4 pixels
adds -8,length,length
endloop1:
// less than 8 pixels left at this stage
last_8_pixels:
fnop
subs 4,length,r0
fnop
bnc last_pixels
// > 4 pixels left
// interpolate z over last 5->7 pixels
faddz aZ1,iZ,aZ1
fld.d 8(Zaddr)++,oldZval // load old Zixels
faddz aZ2,iZ,aZ2
fst.d newZval,-8(Zaddr) // store new Zixels
form rZmaskl,iZval
pst.d colour,8(Paddr)++ // store new Pixel
fzchks oldZval,iZval,newZval // check z for next 4 pixels
adds -4,length,length
// 1 -> 4 pixels left
// interpolate z over last n pixels (1 - 4 pixels remain)
faddz aZ1,iZ,aZ1
fld.d 8(Zaddr)++,oldZval // load old Zixels
faddz aZ2,iZ,aZ2
fst.d newZval,-8(Zaddr) // store new Zixels
form rZmaskh,iZval
nop
.enddual
fzchks oldZval,iZval,newZval
adds -4,length,length
fnop
fst.d newZval,0(Zaddr) // store final Zixels
bri r1
pst.d colour,8(Paddr)++ // store final Pixels
// last 0 -> 4 pixels
last_pixels:
fnop
subs 0,length,r0
fnop
bnc exit
// 1 -> 4 pixels left
// interpolate z over last n pixels (1 - 4 pixels remain)
faddz aZ1,iZ,aZ1
fld.d 8(Zaddr)++,oldZval // load old Zixels
faddz aZ2,iZ,aZ2
fst.d newZval,-8(Zaddr) // store new Zixels
form rZmaskl,iZval
pst.d colour,8(Paddr)++ // store new Pixels
.enddual
fzchks oldZval,iZval,newZval
adds -4,length,length
fzchks f0,oldZval,f0 // shift PM right 4
fst.d newZval,0(Zaddr) // store final Zixels
// NOTE: to shift PM and leave top
// 4 bits clear src2 < src1
bri r1
pst.d colour,8(Paddr)++ // store final Pixels
// O.K complete now
exit:
.enddual
fnop
fst.d newZval,0(Zaddr) // store final Zixels
bri r1
pst.d colour,8(Paddr)++ // store final Pixels
// THE END
//}}}