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

632 lines
13 KiB
Scheme

//{{{ on higher-level fns
//
// Under old 8-bit shader, we called scanline from scansegment
//
// scansegment is called twice per triangle, so it pays to
// make the entry to scansegment as cheap as possible
//
// so i suggest that triangle() is fully assembly-coded.
//
// we can pre-compute the floats dr dg db dz into dbl floating
// registers for the duration of a whole triangle
// then only ir ig ib iz need setting up, according to alignment
// of start segment
//
// we can organise that scansegment is called with all the right
// register parameters to pass on to scanline
//
// we are trying to optimise 100 pixel triangles - i.e 16 pixels
// wide by 16 pixels high (128)
//
// so we will call scansegment twice per triangle, scanline 16 times
// and will fill 8 lines > 8, 4 > 4, 4 < 4
// giving rates of 16 / (8/2.6 + 4/2 + 4) = 1.76 Mpix
// so a 128 pixel triangle will fill in 72 uS, giving a triangle rate of
// 13.8 k - however, we will have a rate of 26k 64 pixel triangles
//
// this is crap
//
//
//}}}
//
// 32-bit gouraud shaded z-buffered entrypoint
//
.globl _zbufferline
.align 8
//{{{ do the funky gibbon
//{{{ define registers
//
// r1 return address
// r2 sp
// r3 frameP
// r4 .. r15 I should strive to conserve
// r16 .. r30 I can trash away
// r31 reserved as an addressing temporary - but available
//
// scanline ( int *fbuffer, int *zbuffer,
// int ir, int ig, int ib, int iz,
// int idr, int idg, int idb, int idz, int dx )
//
//
//
//
// FUNCTION PARAMETERS
//
#define paddr r16
#define zaddr r17
#define ir r18
#define ig r19
#define ib r20
#define iz r21
#define idr r22
#define idg r23
#define idb r24
#define idz r25
#define dx r26
//
// LOCALS
//
//
// interpolant values
// we should save these first !
#define oddz f6
#define ddz f4
#define ddz_lo f4
#define ddz_hi f5
#define r_lo f8
#define r_hi f9
#define r r_lo
#define g_lo f10
#define g_hi f11
#define g g_lo
#define b_lo f12
#define b_hi f13
#define b b_lo
#define z_lo f14
#define z_hi f15
#define z z_lo
// interpolant delta values
#define dr_lo f16
#define dr_hi f17
#define dr dr_lo
#define dg_lo f18
#define dg_hi f19
#define dg dg_lo
#define db_lo f20
#define db_hi f21
#define db db_lo
#define dz_lo f22
#define dz_hi f23
#define dz dz_lo
// double-length float temporaries
#define oldz_lo f24
#define oldz_hi f25
#define oldz oldz_lo
#define nuz f26
#define col f28
#define dbltmp f30
// integer temporaries
#define itemp1 r27
#define itemp2 r28
#define itemp3 r29
#define itemp4 r30
#define minus1 itemp1
//}}}
_zbufferline:
adds -5,dx,r0
bnc .zb_optimise // if dx >= 17, GOTO optimise (i.e at least 2 runs)
//{{{ short-run setup
ixfr ib, b_lo
ixfr ig, g_lo
br .tidy_up
ixfr ir, r_lo
//}}}
.zb_optimise:
//{{{ fast z-buffer loop
// construct floating-point 2dr 2dg 2db 2dz
//{{{
addu idr,idr,itemp1
ixfr itemp1, dr_lo
addu idg,idg,itemp1
ixfr itemp1, dg_lo
addu idb,idb,itemp1
ixfr itemp1, db_lo
addu idz,idz,itemp1
ixfr itemp1, dz_lo
addu itemp1,itemp1,itemp1
ixfr itemp1, ddz_lo
fmov.ss dr_lo,dr_hi
fmov.ss dg_lo,dg_hi
fmov.ss db_lo,db_hi
fmov.ss dz_lo,dz_hi
fmov.ss ddz_lo,ddz_hi
and 4,paddr,r0 // if paddr&7 == 0, cc set
bc .aligned // so we jump if paddr&7==0, i.e aligned
//}}}
// on entering inner loop, we need a col and an oldz, and we need
// paddr and zaddr down-ticked
// unaligned branch
//{{{
// ir corresponds to high word of 64-bit pair, so we down tick to
// get ir_lo etc.
//
//
ixfr ir, r_hi
ixfr ig, g_hi
ixfr ib, b_hi
ixfr iz, z_hi
// construct lo word of rgbz by subtraction
subs ir, idr, ir
subs ig, idg, ig
subs ib, idb, ib
subs iz, idz, iz
ixfr ir, r_lo
ixfr ig, g_lo
ixfr ib, b_lo
adds -1,r0,minus1
ixfr minus1, z_lo // important - zlo MUST be invisible for fchkz
// align to double boundary
adds -12, zaddr, zaddr
adds -4, paddr, paddr // the branch destination adds -8!
fld.d 8(zaddr), oldz // load zbuffer value (from &z0-4)
adds 1,dx,dx // tick count
fzchkl oldz,z,nuz // z-check with frigged z
and 3,dx,itemp3 // itemp3 = extras on rhs
br .aligned_path
ixfr iz, z_lo // correct z
//}}}
.aligned:
//{{{
//
// write iz into dbl z lo, iz+dz into dbl z hi etc
//
ixfr ir, r_lo
ixfr ig, g_lo
ixfr ib, b_lo
ixfr iz, z_lo
adds ib, idb, ib
adds ig, idg, ig
adds ir, idr, ir
adds iz, idz, iz
fld.d r0(zaddr), oldz // load zbuffer value
ixfr ib, b_hi
ixfr ig, g_hi
ixfr ir, r_hi
ixfr iz, z_hi
adds -1,r0,minus1
adds -8, zaddr, zaddr
and 3,dx,itemp3 // itemp3 = extras on rhs
.dual
fzchkl oldz,z,nuz // z-check with unfrigged z
nop
.aligned_path:
faddp b,f0,f0
shr 2,dx,dx
faddp g,f0,f0
adds -1,dx,dx // fix dx for by 8 inner loop
faddp r,f0,f0
bla minus1, dx, .inner_loop
form f0,col
adds -8, paddr, paddr
//}}}
// THIS IS THE INNER LOOP
//{{{ 32-bit z, 32-bit pixel inner loop
.inner_loop:
faddz z,dz,oddz
fst.d nuz, 8(zaddr)++
faddz z,ddz,z
nop
fzchkl oldz,oddz,nuz
fld.d 16(zaddr), oldz
fzchks f0,f0,f0
nop
faddp b,db,b
fst.d nuz, 8(zaddr)++
faddp g,dg,g
pst.d col, 8(paddr)++
faddp r,dr,r
nop
form f0,col
nop
faddp b,db,b
nop
faddp g,dg,g
pst.d col, 8(paddr)++
faddp r,dr,r
nop
form f0,col
bla minus1,dx,.inner_loop
fzchkl oldz,z,nuz
fld.d 16(zaddr), oldz
//}}}
// on exit, we have yet to do itemp3 loops
// not only that but zaddr and paddr are pointing 8 ahead
// we have a formed colour and have read oldz
// however, we just HAVE to read oldz again,
// but we can fix the pointers
.enddual
fmov.ss f0, f0
or r0,itemp3,dx
fnop
bc .slow_exit
adds 8,zaddr,zaddr
adds 8,paddr,paddr
fxfr z_lo, iz
//}}}
// this is the entrypoint for short runs -
.tidy_up:
//{{{ short runs, deltas hold single click, dx holds pixels_left-1
// loop doing simple z-buffer
//
ixfr idr, dr_lo
ixfr idg, dg_lo
ixfr idb, db_lo
.dual
faddp b,f0,f0
adds -1, r0, minus1 // set up decrementing counter
faddp g,f0,f0
adds minus1, dx, dx // correct for bla
faddp r,f0,f0
bla minus1,dx,.longhand_loop // SET UP LCC ! ! ! required by bla
form f0,col
adds -4, paddr, paddr
.longhand_loop:
faddp b,db,b
ld.l r0(zaddr), itemp3
fnop
subu iz,itemp3,r0
fnop
bnc.t .do_replace
faddp g,dg,g
fst.l col, 4(paddr)++
.no_replace:
// walk pointers to pixel + colour
fnop
addu 4,zaddr,zaddr
fnop
addu 4,paddr,paddr
faddp r,dr,r
bla minus1, dx, .longhand_loop
form f0,col
adds iz,idz,iz
fnop
br .slow_exit
fnop
nop
.do_replace:
// replace pixel / zixel
faddp r,dr,r
addu 4,zaddr,zaddr
fnop
st.l iz, -4(zaddr)
form f0,col
bla minus1, dx, .longhand_loop
fnop
adds iz,idz,iz
// right, weve done
.slow_exit:
.enddual
fmov.ss f0,f0
bri r1
fnop
nop
//}}}
//{{{ undefine registers
#undef paddr
#undef zaddr
#undef ir
#undef ig
#undef ib
#undef iz
#undef idr
#undef idg
#undef idb
#undef idz
#undef dx
//
// LOCALS
//
//
// interpolant values
#undef r_lo
#undef r_hi
#undef r
#undef g_lo
#undef g_hi
#undef g
#undef b_lo
#undef b_hi
#undef b
#undef z_lo
#undef z_hi
#undef z
// interpolant delta values
#undef dr_lo
#undef dr_hi
#undef dr
#undef dg_lo
#undef dg_hi
#undef dg
#undef db_lo
#undef db_hi
#undef db
#undef dz_lo
#undef dz_hi
#undef dz
// double-length float temporaries
#undef oldz_lo
#undef oldz_hi
#undef oldz
#undef nuz
#undef col
// integer temporaries
#undef itemp1
#undef itemp2
#undef itemp3
#undef itemp4
#undef minus1
//}}}
//}}}
//
// simple 1 pixel at a time texturing
//
.globl _textureline
.align 8
//{{{ texture (YEAH!)
//{{{ define registers
//
// texline ( int *fbuffer, int *zbuffer,
// int iu, int iv, int iz,
// int idu, int idv, int idz, int texbase )
//
// FUNCTION PARAMETERS
//
#define paddr r16
#define zaddr r17
#define ir r18
#define ig r19
#define iz r20
#define idr r21
#define idg r22
#define idz r23
#define tex_base r24
#define dx r25
//
// LOCALS
//
//
// interpolant values
#define r_lo f8
#define r_hi f9
#define r r_lo
#define g_lo f10
#define g_hi f11
#define g g_lo
#define dblspare f12
#define z_lo f14
#define z_hi f15
#define z z_lo
// interpolant delta values
#define dr_lo f16
#define dr_hi f17
#define dr dr_lo
#define dg_lo f18
#define dg_hi f19
#define dg dg_lo
#define tex_val1 f20
#define tex_val2 f21
#define dz_lo f22
#define dz_hi f23
#define dz dz_lo
// double-length float temporaries
#define oldz_lo f24
#define oldz_hi f25
#define oldz oldz_lo
#define nuz f26
#define col_lo f28
#define col_hi f29
#define col col_lo
#define dbltmp f30
// integer temporaries
#define itemp1 r27
#define itemp2 r28
#define itemp3 r29
#define itemp4 r30
#define minus1 itemp1
//}}}
_textureline:
//{{{ setup
.tx_slow:
//
// build floating-point dr dg db registers
// NB replace on new <= old
//
// or r1,r0, itemp2
// or r16,r0,itemp1
//
// call _setpixelsize
// or 1,r0,r16 // set pixel size to 16 bits
//
// or itemp2,r0,r1
// or itemp1,r0,r16
// fmov.dd f0, g
// fmov.dd f0, dg
// fmov.dd f0, r
// fmov.dd f0, dr
and 0xffff, idg, itemp1
ixfr itemp1, dg_lo // these are 16 bit deltas !!!!
and 0xffff, idr, itemp1
ixfr itemp1, dr_lo
and 0xffff, ig, itemp1
ixfr itemp1, g_lo
and 0xffff, ir, itemp1
ixfr itemp1, r_lo
//}}}
//{{{ short runs, deltas hold single click, dx holds pixels_left-1
//
// loop doing simple textured (!) z-buffer
//
// possible optimisation is to do 2 at a time, so we save on faddps
// and stuff
//
// if we do fld.d, faddz, fchkz we can branch on PM
// to determine visibility
//
//
.dual
faddp f0,f0,f0
adds -1, r0, minus1 // set up decrementing counter
fnop
adds minus1, dx, dx // correct for bla
fnop
bla minus1,dx,.t_longhand_loop // SET UP LCC ! ! ! required by bla
fnop
adds -4, paddr, paddr
.t_longhand_loop:
pfaddp g,dg,f0
addu 4,zaddr,zaddr
pfaddp r,dr,g
ld.l -4(zaddr), itemp3
pform f0,r
addu 4,paddr,paddr
pform f0,col
subu iz,itemp3,r0
fxfr col_lo, itemp2
bnc.t .t_do_replace
fnop
st.l iz, -4(zaddr)
.t_no_replace:
// walk pointers to pixel + colour
fnop
bla minus1, dx, .t_longhand_loop
fnop
adds iz,idz,iz
fnop
br .t_slow_exit
fnop
nop
.t_do_replace:
// replace pixel / zixel
fnop
adds iz,idz,iz
fnop
fld.l tex_base(itemp2), tex_val1
fnop
bla minus1, dx, .t_longhand_loop
fnop
fst.l tex_val1, r0(paddr)
// right, weve done
.t_slow_exit:
.enddual
fmov.ss f0,f0
bri r1
fnop
nop
//}}}
//}}}