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

1142 lines
28 KiB
Scheme

//{{{ register allocation
//
// 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
//
// extern void scaninit ( int idr, int idg, int idb, int idz );
//
// extern void texinit ( int idu, int idv, int willy, int idz );
//
// extern void scanline ( int *fbuffer, int *zbuffer,
// int ir, int ig, int ib, int iz, int dx,
// int dr, int dg, int db, int dz );
//
// extern void ftexline ( int *fbuffer, int *zbuffer,
// int iu, int iv, int texbase, int iz, int dx,
// int idu, idv, dummy, dz );
//
// extern void scansegment ( void (*fbuffer)(),
// int fbuffer, int *zbuffer,
//
//
//
// FUNCTION PARAMETERS
//
#define param1 r16
#define param2 r17
#define param3 r18
#define param4 r19
#define param5 r20
#define param6 r21
#define param7 r22
#define param8 r23
#define param9 r24
#define param10 r25
#define param11 r26
#define param12 r27
//
// DOUBLE FLOAT LOCALS
//
// interpolant values
// we should save these first !
//
#define fminus1 f6
#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 u_lo f8
#define u_hi f9
#define u u_lo
#define v_lo f10
#define v_hi f11
#define v v_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
#define dr_lo f16
#define dr_hi f17
#define dr dr_lo
#define du_lo f16
#define du_hi f17
#define du du_lo
#define dg_lo f18
#define dg_hi f19
#define dg dg_lo
#define dv_lo f18
#define dv_hi f19
#define dv dv_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_lo f28
#define col_hi f29
#define col col_lo
#define dbltmp f30
#define dbltmp_lo f30
#define dbltmp_hi f31
//}}}
//{{{ macros
#define push(reg,offs) st.l reg, offs(sp)
#define pop(reg,offs) ld.l offs(sp), reg
//}}}
.data
.align 8
slope_table::
.double[16] 0
.text
//{{{ scaninit ( int idr, int idg, int idb, int idz )
.globl _scaninit
.align 8
#define indr param1
#define indg param2
#define indb param3
#define indz param4
#define itemp1 param5
_scaninit::
adds -1,r0,r31
ixfr r31,fminus1
addu indr,indr,itemp1
ixfr itemp1, dr_lo
addu indg,indg,itemp1
ixfr itemp1, dg_lo
addu indb,indb,itemp1
ixfr itemp1, db_lo
addu indz,indz,itemp1
ixfr itemp1, dz_lo
fmov.ss dr_lo,dr_hi
fmov.ss dg_lo,dg_hi
fmov.ss db_lo,db_hi
bri r1
fmov.ss dz_lo,dz_hi
#undef indr
#undef indg
#undef indb
#undef indz
#undef itemp1
//}}}
//{{{ texinit ( int idu, int idv, int compat, int idz )
.globl _texinit
.align 8
#define indu param1
#define indv param2
#define tx_and_or_mask param3
#define indz param4
#define itemp1 param5
_texinit::
// build dr*2 dg*2 dz*2
adds -1,r0,r31
ixfr r31,fminus1
adds indu, indu,itemp1
and 0xffff, itemp1,itemp1
ixfr itemp1, du_lo
ixfr itemp1, du_hi
adds indv, indv,itemp1
and 0xffff, itemp1,itemp1
ixfr itemp1, dv_lo
ixfr itemp1, dv_hi
adds indz,indz,itemp1
ixfr itemp1, dz_lo // dz_lo=2*idz
ixfr itemp1, dz_hi // dz_lo=2*idz
bri r1
ixfr param3, db_lo
shr 16, tx_and_or_mask,itemp1
andh 0xffff, tx_and_or_mask, r31
or r16,r31,r31
ixfr r31, db_hi
and 0xffff, tx_and_or_mask, r31
shl 16, tx_and_or_mask,itemp1
or r16,r31,r31
ixfr r31, db_lo
bri r1
nop
#undef indu
#undef indv
#undef indz
#undef tx_and_or_mask
#undef itemp1
//}}}
//{{{ ascaninit ( int idr, int idg, int idb, int idz )
.text
.globl _ascaninit
.align 8
#define indr param8
#define indg param9
#define indb param10
#define indz param11
#define itemp1 r31
#define st_slope(reg)\
st.l reg,4(r31);\
st.l r0, 0(r31);\
subs r0,reg,r16;\
st.l r16,32(r31);\
st.l r0,36(r31)
_ascaninit::
// ixfr r16, r_lo
// mov slope_table, r31
// st_slope (indz)
// addu 8,r31,r31
// st_slope (indr)
// addu 8,r31,r31
// st_slope (indg)
// addu 8,r31,r31
// st_slope (indb)
// fxfr r_lo, r16
adds -1,r0,r31
ixfr r31,fminus1
addu indr,indr,itemp1
ixfr itemp1, dr_lo
addu indg,indg,itemp1
ixfr itemp1, dg_lo
addu indb,indb,itemp1
ixfr itemp1, db_lo
addu indz,indz,itemp1
ixfr itemp1, dz_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
bri r1
nop
#undef indr
#undef indg
#undef indb
#undef indz
#undef itemp1
//}}}
//{{{ atexinit ( int idu, int idv, int compat, int idz )
.globl _atexinit
.align 8
#define indu param8
#define indv param9
#define tx_and_or_mask param10
#define indz param11
#define itemp1 r31
_atexinit::
// build dr*2 dg*2 dz*2
adds -1,r0,r31
ixfr r31,fminus1
adds indu, indu,itemp1
and 0xffff, itemp1,itemp1
ixfr itemp1, du_lo
ixfr itemp1, du_hi
adds indv, indv,itemp1
and 0xffff, itemp1,itemp1
ixfr itemp1, dv_lo
ixfr itemp1, dv_hi
adds indz,indz,itemp1
ixfr itemp1, dz_lo // dz_lo=2*idz
ixfr itemp1, dz_hi // dz_lo=2*idz
bri r1
ixfr param10, db_lo
#undef indu
#undef indv
#undef indz
#undef tx_and_or_mask
#undef itemp1
//}}}
//{{{ texinit256 ( int idu, int idv, int compat, int idz )
.globl _texinit256
.align 8
#define indu param1
#define indv param2
#define tx_and_or_mask param3
#define indz param4
#define itemp1 param5
_texinit256::
// build dr*2 dg*2 dz*2
adds indu, indu,itemp1
ixfr itemp1, du_lo
ixfr itemp1, du_hi
adds indv, indv,itemp1
ixfr itemp1, dv_lo
ixfr itemp1, dv_hi
adds indz,indz,itemp1
ixfr itemp1, dz_lo // dz_lo=2*idz
ixfr itemp1, dz_hi // dz_lo=2*idz
shr 16, tx_and_or_mask,itemp1
andh 0xffff, tx_and_or_mask, r31
or r16,r31,r31
ixfr r31, db_hi
and 0xffff, tx_and_or_mask, r31
shl 16, tx_and_or_mask,itemp1
or r16,r31,r31
ixfr r31, db_lo
bri r1
nop
#undef indu
#undef indv
#undef indz
#undef tx_and_or_mask
#undef itemp1
//}}}
//{{{ scanline ( int *fb, int *zb, int ir, int ig, int ib, int iz, int dx, int safeload )
.globl _scanline
.align 8
#define paddr param1
#define zaddr param2
#define ir param3
#define ig param4
#define ib param5
#define iz param6
#define dx param7
#define idr param8
#define idg param9
#define idb param10
#define idz param11
// WARNING - itemp1 and itemp3 overload ir and ig - be careful
#define itemp1 param3
#define itemp3 param4
#define minus1 itemp1
_scanline:
and 4,paddr,r0 // if paddr&4 == 0, cc set
bc .aligned // so we jump if paddr&4==0, i.e aligned
.unaligned: // ie first pixel NOT on a 64-bit boundary
//{{{
// ir corresponds to high word of 64-bit pair, so we down tick to
// get ir_lo etc.
//
// align to double boundary
//
addu -12, zaddr, zaddr
fld.d 8(zaddr), oldz // load zbuffer value (from &z0-4)
addu -12, paddr, paddr
ixfr ir, r_hi
ixfr ig, g_hi
ixfr ib, b_hi
ixfr iz, z_hi
// construct lo word of rgbz by subtraction
subu ir, idr, r31
ixfr r31, r_lo
subu ig, idg, r31
ixfr r31, g_lo
subu ib, idb, r31
ixfr r31, b_lo
subu iz, idz, r31
adds -1,r0,minus1
fmov.ss fminus1, z_lo // important - zlo MUST be invisible for fchkz
adds 1,dx,dx // tick count
fzchkl oldz,z,nuz // z-check with frigged z
ixfr r31, z_lo // correct z
br .aligned_path
and 1,dx,itemp3 // itemp3 = extras on rhs
//}}}
.aligned: // ie first pixel IS on a 64-bit boundary
//{{{
//
// write iz into dbl z lo, iz+dz into dbl z hi etc
//
addu -8, zaddr, zaddr
fld.d 8(zaddr), oldz // load zbuffer value HOURS to complete
addu -8, paddr, paddr
ixfr ir, r_lo
ixfr ig, g_lo
ixfr ib, b_lo
ixfr iz, z_lo
addu ib, idb, r31
ixfr r31, b_hi
addu ig, idg, r31
ixfr r31, g_hi
addu ir, idr, r31
ixfr r31, r_hi
addu iz, idz, r31
ixfr r31, z_hi
adds -1,r0,minus1
.dual
fzchkl oldz,z,nuz // z-check with unfrigged z
and 1,dx,itemp3 // itemp3 = extras on rhs
.aligned_path:
faddp b,f0,f0
or r0,dx,r31 // r31 = orig dx
faddp g,f0,f0
shr 1,dx,dx // dx now n of 2s
faddp r,f0,f0
adds -2, r31, r0 // goto last 4 if dx < 2
form f0,col
bc .last_few
fnop
adds -1,dx,dx // corrected for autoincrement, so test -3 below
fnop
bla minus1, dx, .inner_loop
//}}}
//{{{ 32-bit z, 32-bit pixel inner loop OPENED out in 2s
.inner_loop_db:
fzchks f0,f0,f0
nop
.inner_loop:
fzchkl f0,f0,f0
fst.d nuz, 8(zaddr)++
faddz z,dz,z
nop
faddp b,db,b
pst.d col, 8(paddr)++
faddp g,dg,g
nop
faddp r,dr,r
fld.d 8(zaddr), oldz
form f0,col
bla minus1,dx,.inner_loop_db
fzchkl oldz,z,nuz
or r0,itemp3,r0 // for exit condition code
form f0,f0
bc .zb_exit
//}}}
//{{{ there is just 1 pixel to go
//
// this is fortunate - if pixels left = 1, then we CANT have a -1
// mask in z_lo, since it would have bumped dx to 2
//
// we only enter here if pixels == 1 and that pixel is on screen
// so we unconditionally mask off hi word, re-execute the fzchkl
// and proceed
//
.last_few:
fmov.ss fminus1,z_hi
nop
fzchkl oldz,z,nuz
nop
fzchks f0,f0,f0 // trash 4 PM bits
fst.d nuz, 8(zaddr)++
.enddual
fzchkl f0,f0,f0 // and 2 more PM bits
bri r1
fnop
pst.d col, 8(paddr)++
.zb_exit::
fnop
bri r1
fnop
nop
//}}}
#undef paddr
#undef zaddr
#undef ir
#undef ig
#undef ib
#undef iz
#undef dx
#undef idr
#undef idg
#undef idb
#undef idz
#undef itemp1
#undef itemp2
#undef itemp3
#undef minus1
//}}}
//{{{ flatline ( int *fb, int *zb, int ir, int ig, int ib, int iz, int dx, int safeload )
.globl _flatline
.align 8
#define paddr param1
#define zaddr param2
#define ir param3
#define ig param4
#define ib param5
#define iz param6
#define dx param7
#define idr param8
#define idg param9
#define idb param10
#define idz param11
// WARNING - itemp1 and itemp3 overload ir and ig - be careful
#define itemp1 param3
#define itemp3 param4
#define minus1 itemp1
_flatline:
ixfr ir, r_hi
ixfr ig, g_hi
ixfr ib, b_hi
fmov.ss r_hi, r_lo
fmov.ss g_hi, g_lo
fmov.ss b_hi, b_lo
and 4,paddr,r0 // if paddr&4 == 0, cc set
bc .faligned // so we jump if paddr&4==0, i.e aligned
.funaligned: // ie first pixel NOT on a 64-bit boundary
//{{{
// ir corresponds to high word of 64-bit pair, so we down tick to
// get ir_lo etc.
//
// align to double boundary
//
addu -12, zaddr, zaddr
addu -12, paddr, paddr
fld.d 8(zaddr), oldz // load zbuffer value (from &z0-4)
ixfr iz, z_hi
// construct lo word of rgbz by subtraction
subu iz, idz, r31
adds -1,r0,minus1
fmov.ss fminus1, z_lo // important - zlo MUST be invisible for fchkz
adds 1,dx,dx // tick count
fzchkl oldz,z,nuz // z-check with frigged z
ixfr r31, z_lo // correct z
br .faligned_path
and 1,dx,itemp3 // itemp3 = extras on rhs
//}}}
.faligned: // ie first pixel IS on a 64-bit boundary
//{{{
//
// write iz into dbl z lo, iz+dz into dbl z hi etc
//
addu -8, zaddr, zaddr
addu -8, paddr, paddr
fld.d 8(zaddr), oldz // load zbuffer value HOURS to complete
ixfr iz, z_lo
addu iz, idz, r31
ixfr r31, z_hi // this needs 3 cycles to complete before fzchkl
adds -1,r0,minus1
.dual
fzchkl oldz,z,nuz // z-check with unfrigged z
and 1,dx,itemp3 // itemp3 = extras on rhs
.faligned_path:
faddp b,f0,f0
or r0,dx,r31 // r31 = orig dx
faddp g,f0,f0
shr 1,dx,dx // dx now n of 4s
faddp r,f0,f0
adds -2, r31, r0 // goto last 4 if dx < 2
form f0,col
bc .flast_few
fnop
adds -1,dx,dx // corrected for autoincrement, so test -3 below
fnop
bla minus1, dx, .finner_loop
//}}}
//{{{ 32-bit z, 32-bit flat shaded pixel inner loop OPENED out in 2s
.finner_loop_db:
fzchks f0,f0,f0
fst.d nuz, 8(zaddr)++
.finner_loop:
fzchkl f0,f0,f0
fld.d 8(zaddr), oldz
faddz z,dz,z
pst.d col, 8(paddr)++
fnop
bla minus1,dx,.finner_loop_db
fzchkl oldz,z,nuz
or r0,itemp3,r0 // for exit condition code
// weve exited the loop here
form f0,f0
bc .fzb_exit
//}}}
//{{{ there is just 1 pixel to go
//
// this is fortunate - if pixels left = 1, then we CANT have a -1
// mask in z_lo, since it would have bumped dx to 2
//
// we only enter here if pixels == 1 and that pixel is on screen
// so we unconditionally mask off hi word, re-execute the fzchkl
// and proceed
//
.flast_few:
fmov.ss fminus1, z_hi
nop
pfzchkl oldz,z,f0 // nuz
nop
pfzchks f0,f0,nuz // trash 4 PM bits
fst.d nuz, 8(zaddr)++
.enddual
pfzchkl f0,f0,f0 // and 2 more PM bits
bri r1
fnop
pst.d col, 8(paddr)++
.fzb_exit:
fnop
bri r1
fnop
nop
//}}}
#undef paddr
#undef zaddr
#undef ir
#undef ig
#undef ib
#undef iz
#undef dx
#undef idr
#undef idg
#undef idb
#undef idz
#undef itemp1
#undef itemp2
#undef itemp3
#undef minus1
//}}}
//{{{ ftexline ( *fb, *zb, u, v, *tb, z, dx, du, dv, DUMMY ,dz )
.globl _ftexline
.align 8
#define paddr param1
#define zaddr param2
#define iu param3
#define iv param4
#define texbase param5
#define iz param6
#define dx param7
#define idu param8
#define idv param9
#define itemp1 param10
#define idz param11
#define itemp3 param3
#define itemp4 param4
#define minus1 itemp1
// WARNING - itemp3 and itemp4 overload ir and ig - be careful
_ftexline::
fxfr db_lo,texbase
and 4,paddr,r0 // if paddr&7 == 0, cc set
bc .txaligned // so we jump if paddr&7==0, i.e aligned
.txunaligned: // ie first pixel NOT on a 64-bit boundary
//{{{
// align to double boundary
adds -12, zaddr, zaddr
adds -12, paddr, paddr
fld.d 8(zaddr), oldz // load zbuffer value (from &z0-4)
// correct for interpolant over-tick - first u,v
subs iu, idu, r31
and 0xffff,r31,r31
ixfr r31, u_lo
and 0xffff,iu,r31
ixfr r31, u_hi
subs iv, idv, r31
and 0xffff,r31,r31
ixfr r31, v_lo
and 0xffff,iv,r31
ixfr r31, v_hi
ixfr iz, z_hi
adds -1,r0,minus1
fmov.ss fminus1, z_lo // important - zlo MUST be invisible for fchkz
adds 1,dx,dx // tick count
fzchkl oldz,z,nuz // z-check with frigged z
subs iz, idz, r31
and 1,dx,itemp3 // itemp3 = extras on rhs
br .txaligned_path
ixfr r31, z_lo // correct z
//}}}
.txaligned: // ie first pixel IS on a 64-bit boundary
//{{{
//
// write iz into dbl z lo, iz+dz into dbl z hi etc
//
adds -8, zaddr, zaddr
adds -8, paddr, paddr
fld.d 8(zaddr), oldz // load zbuffer value HOURS to complete
ixfr iz, z_lo
adds iz, idz, r31
ixfr r31, z_hi // this needs 3 cycles to complete before fzchkl
and 0xffff,iu,r31
ixfr r31, u_lo
addu iu, idu, r31
and 0xffff,r31,r31
ixfr r31, u_hi
and 0xffff,iv,r31
ixfr r31, v_lo
addu iv, idv, r31
and 0xffff,r31,r31
ixfr r31, v_hi
adds -1,r0,minus1
.dual
fzchkl oldz,z,nuz // z-check with unfrigged z
and 1,dx,itemp3 // itemp3 = extras on rhs
//}}}
.txaligned_path: // above branches re-merge here
//{{{
form f0,f0 // clear merge to start up
or r0,dx,r31 // r31 = orig dx
faddp u,f0,f0
shr 1,dx,dx // dx now n of 2s
faddp v,f0,f0
adds -2, r31, r0 // goto last few if dx < 2
form f0,col
bc .txlast_few
fnop
adds -1,dx,dx // corrected for autoincrement, so test -3 below
fnop
bla minus1, dx, .txinner_loop
//}}}
//{{{ 32-bit z, texture inner loop, 2 pixels at a time
.txinner_loop_db:
fxfr col_lo,r31 // r31 = low pixel interpolated u,v
fst.d nuz, 8(zaddr) // IMPORTANT - we cannot auto-increment
.txinner_loop:
fxfr col_hi,itemp4 // in same cycle as fxfr ! ! ! ! !
fld.d 16(zaddr), oldz
faddz z,dz,z
shr 2,r31,r31 // drop 2 of 4 blue bits, i.e word address
fzchks f0,f0,f0 // drop 4 more PM bits
shr 2,itemp4,itemp4
fzchkl f0,f0,f0 // drop 2 more PM bits
fld.l texbase(r31),dbltmp_lo
faddp u,du,u
fld.l texbase(itemp4),dbltmp_hi
faddp v,dv,v
addu 8,zaddr,zaddr // see note on zaddr++ above
fnop
ld.c psr,r31 // r31 holds 16-bit pixel size
form f0,col // and merge the colour ready for next
xorh 0x00c0,r31,itemp4 // 0xc flips 32-16
fnop // itemp4 holds 32-bit pixelsize
st.c itemp4, psr // goto 32 bits
fnop
pst.d dbltmp, 8(paddr)++ // do pixel store
fnop
st.c r31, psr // and go back to 16 bits
fnop
bla minus1,dx,.txinner_loop_db
fzchkl oldz,z,nuz
nop
// weve exited the loop here
fnop
or r0,itemp3,r0
fnop
bc .tx_exit
//}}}
//{{{ there is just 1 pixel to go - we have a good z in nuz, and 2 good cols
.txlast_few: // we CANNOT ixfr and fxfr
fmov.ss fminus1, z_hi
nop
fxfr col_lo,r31 // txtemp1 = interpolated u,v
nop
fzchkl oldz,z,nuz
shr 2,r31,r31
fzchks f0,f0,f0 // trash 4 PM bits
fld.l texbase(r31), col_lo
fzchkl f0,f0,f0 // and 2 more PM bits
fst.d nuz, 8(zaddr)++
fnop
ld.c psr,r31
fnop
xorh 0x00c0,r31,itemp4
fnop
st.c itemp4, psr
fnop
pst.d col, 8(paddr)++
fnop
st.c r31,psr
.tx_exit:
.enddual
form f0,f0
bri r1
form f0,f0
nop
//}}}
#undef paddr
#undef zaddr
#undef iu
#undef iv
#undef texbase
#undef iz
#undef dx
#undef idu
#undef idv
#undef idz
#undef itemp1
#undef itemp3
#undef itemp4
#undef txtemp1
#undef minus1
//}}}
//{{{ ftexline256 ( *fb, *zb, u, v, *tb, z, dx, du, dv, DUMMY ,dz )
.globl _ftexline256
.align 8
#define paddr param1
#define zaddr param2
#define iu param3
#define iv param4
#define texbase param5
#define iz param6
#define dx param7
#define idu param8
#define idv param9
#define itemp1 param10
#define idz param11
#define itemp3 param3
#define itemp4 param4
#define minus1 itemp1
// WARNING - itemp3 and itemp4 overload ir and ig - be careful
_ftexline256::
fxfr db_lo,texbase
and 4,paddr,r0 // if paddr&7 == 0, cc set
bc .txaligned256 // so we jump if paddr&7==0, i.e aligned
.txunaligned256: // ie first pixel NOT on a 64-bit boundary
//{{{
// align to double boundary
adds -12, zaddr, zaddr
adds -12, paddr, paddr
fld.d 8(zaddr), oldz // load zbuffer value (from &z0-4)
// correct for interpolant over-tick - first u,v
subs iu, idu, r31
and 0xffff,r31,r31
ixfr r31, u_lo
and 0xffff,iu,r31
ixfr r31, u_hi
subs iv, idv, r31
and 0xffff,r31,r31
ixfr r31, v_lo
and 0xffff,iv,r31
ixfr r31, v_hi
ixfr iz, z_hi
adds -1,r0,minus1
fmov.ss fminus1, z_lo // important - zlo MUST be invisible for fchkz
adds 1,dx,dx // tick count
fzchkl oldz,z,nuz // z-check with frigged z
subs iz, idz, r31
and 1,dx,itemp3 // itemp3 = extras on rhs
br .txaligned_path256
ixfr r31, z_lo // correct z
//}}}
.txaligned256: // ie first pixel IS on a 64-bit boundary
//{{{
//
// write iz into dbl z lo, iz+dz into dbl z hi etc
//
adds -8, zaddr, zaddr
adds -8, paddr, paddr
fld.d 8(zaddr), oldz // load zbuffer value HOURS to complete
ixfr iz, z_lo
adds iz, idz, r31
ixfr r31, z_hi // this needs 3 cycles to complete before fzchkl
ixfr iu, u_lo
addu iu, idu, r31
ixfr r31, u_hi
ixfr iv, v_lo
addu iv, idv, r31
ixfr r31, v_hi
adds -1,r0,minus1
.dual
fzchkl oldz,z,nuz // z-check with unfrigged z
and 1,dx,itemp3 // itemp3 = extras on rhs
//}}}
.txaligned_path256: // above branches re-merge here
//{{{
form f0,f0 // clear merge to start up
or r0,dx,r31 // r31 = orig dx
faddp u,f0,f0
shr 1,dx,dx // dx now n of 2s
faddp v,f0,f0
adds -2, r31, r0 // goto last few if dx < 2
form f0,col
bc .txlast_few256
fnop
adds -1,dx,dx // corrected for autoincrement, so test -3 below
fnop
bla minus1, dx, .txinner_loop256
//}}}
//{{{ 32-bit z, texture inner loop, 2 pixels at a time
.txinner_loop_db256:
fxfr col_lo,r31 // r31 = low pixel interpolated u,v
fst.d nuz, 8(zaddr) // IMPORTANT - we cannot auto-increment
.txinner_loop256:
fxfr col_hi,itemp4 // in same cycle as fxfr ! ! ! ! !
fld.d 16(zaddr), oldz
faddz z,dz,z
shr 6,r31,r31 // drop 6 of 8 blue bits, i.e word address
fzchks f0,f0,f0 // drop 4 more PM bits
shr 6,itemp4,itemp4
fzchkl f0,f0,f0 // drop 2 more PM bits
fld.l texbase(r31),dbltmp_lo
faddp u,du,u
fld.l texbase(itemp4),dbltmp_hi
faddp v,dv,v
addu 8,zaddr,zaddr // see note on zaddr++ above
form f0,col // and merge the colour ready for next
pst.d dbltmp, 8(paddr)++ // do pixel store
fnop
bla minus1,dx,.txinner_loop_db256
fzchkl oldz,z,nuz
nop
// weve exited the loop here
fnop
or r0,itemp3,r0
fnop
bc .tx_exit256
//}}}
//{{{ there is just 1 pixel to go - we have a good z in nuz, and 2 good cols
.txlast_few256: // we CANNOT ixfr and fxfr
fmov.ss fminus1, z_hi
nop
fxfr col_lo,r31 // txtemp1 = interpolated u,v
nop
fzchkl oldz,z,nuz
shr 6,r31,r31
fzchks f0,f0,f0 // trash 4 PM bits
fld.l texbase(r31), col_lo
fzchkl f0,f0,f0 // and 2 more PM bits
fst.d nuz, 8(zaddr)++
fnop
pst.d col, 8(paddr)++
.tx_exit256:
.enddual
form f0,f0
bri r1
form f0,f0
nop
//}}}
#undef paddr
#undef zaddr
#undef iu
#undef iv
#undef texbase
#undef iz
#undef dx
#undef idu
#undef idv
#undef idz
#undef itemp1
#undef itemp3
#undef itemp4
#undef txtemp1
#undef minus1
//}}}
//{{{ 32-bit z, 32-bit pixel inner loop OPENED out in 4s
// .inner4_loop:
// pfaddz z,dz,f0
// fld.d 16(zaddr), dbltemp
// pfzchkl dbltemp,z,z
// nop
// pfaddz z,dz,dbltemp
// fst.d nuz, 8(zaddr)
// pfzchkl f0,f0,z // now 4 pixels worth of mask is ready
// nop
// faddp b,db,b
// fst.d dbltemp, 16(zaddr)++
// faddp g,dg,g
// nop
// faddp r,dr,r
// pst.d col, 8(paddr)++
// form f0,col
// nop
// faddp b,db,b
// nop // adds -4, dx, dx
// faddp g,dg,g
// pst.d col, 8(paddr)++
// faddp r,dr,r
// nop
// form f0,col
// bla minus1,dx,.inner4_loop // bnc.t .inner4_loop
// fzchkl oldz,z,nuz
// nop
// // weve exited the loop here
// fnop
// or r0,itemp3,r0 // for exit condition code
// fnop
// bc .zb_exit
//}}}
//{{{ 32-bit z, flat pixel inner loop OPENED out in 4s
// .flat4_loop:
// pfaddz z,dz,f0
// fld.d 16(zaddr), dbltemp
// pfzchkl dbltemp,z,z
// fst.d nuz, 8(zaddr)
// pfaddz z,dz,dbltemp
// nop
// pfzchkl f0,f0,z // now 4 pixels worth of mask is ready
// fst.d dbltemp, 16(zaddr)++
// fnop
// pst.d col, 8(paddr)++
// fnop
// pst.d col, 8(paddr)++
// fnop
// bla minus1,dx,.flat4_loop
// fzchkl oldz,z,nuz
// nop
// // weve exited the loop here
// fnop
// or r0,itemp3,r0 // for exit condition code
// fnop
// bc .zb_exit
//}}}