Files
TeslaRel410/sda4/DPL3/VRENDER/AS860/SCANSEG.SS
T
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

253 lines
6.3 KiB
Scheme

//
// Define EDGE structure
//
// .dsect
#define EDGE_ex 0
#define EDGE_ez 4
#define EDGE_ec 8
#define EDGE_edx 12
#define EDGE_edz 16
#define EDGE_edc 20
// .end
//
// scanSegment( char *framebufer, short int *zbuffer,
// int y0, int yend,
// EDGE *left, EDGE *right, int dzBydx,
// processor_bits, processor_id, STEP
// )
//
// Parameters:
#define p_fbuffer r16
#define p_zbuffer r17
#define p_y0 r18
#define p_yend r19
#define p_leftE r20
#define p_rightE r21
#define p_dzBydx r22
#define processor_bits r23
#define processor_id r24
#define STEP r25
//
// Locals:
#define pixline r4
#define zixline r5
#define nlines r6
#define zbuffer r7
#define fbuffer r8
#define leftE r9
#define rightE r10
#define left_ex r11
#define right_ex r12
#define right_ez r13
#define save_1 r14
#define save_2 r15
#define save_3 r7
#define zaddr r16
#define paddr r17
#define left_ez r18
#define dz r19
#define x0 r20
#define dx r21
#define left_ec r22
#define mask r23
#define y0 r26
#define y00 r27
//
.globl _scanSegment
.text
_scanSegment::
// Save return address
addu -80,sp,sp
st.l r1, 0(sp)
st.l r4,4(sp)
st.l r5,8(sp)
st.l r6,12(sp)
st.l r7,16(sp)
st.l r8,20(sp)
st.l r9,24(sp)
st.l r10,28(sp)
st.l r11,32(sp)
st.l r12,36(sp)
st.l r13,40(sp)
st.l r14,44(sp)
st.l r15,48(sp)
// copy parameters to ease call to zbufferSegment
or p_fbuffer,r0,fbuffer
or p_zbuffer,r0,zbuffer
or p_y0,r0,y0
subs p_yend,p_y0,nlines // nlines = yend-y0
or p_leftE,r0,leftE
or p_rightE,r0,rightE
or p_dzBydx,r0,dz
//
// y00 = y0 >> processor_bits
// mask = (1<<processor_bits) -1;
//
// pixline = fbuffer + STEP * y00
// zixline = zbuffer + STEP * y00
//
shr processor_bits, y0, y00
or 1, r0, itemp1
ixfr STEP, f2 // copy STEP and y00 to fp regs
ixfr y00, f4 // for multiply
shl processor_bits, itemp1, mask
adds -1, mask, mask
fmlow.dd f4, f2, f6 // do STEP * y00
fxfr f6, itemp1
addu itemp1,fbuffer,pixline
addu itemp1,zbuffer,zixline
// load stuff left_ec same reg as Col
ld.l EDGE_ex(leftE),left_ex
ld.l EDGE_ex(rightE),right_ex
ld.l EDGE_ez(leftE),left_ez
ld.l EDGE_ez(rightE),right_ez
ld.l EDGE_ec(leftE),Col
adds 1,nlines,nlines // anticipate decrement
// For each scanline
next_scan_line:
// WHILE nlines>0 LOOP
adds -1,nlines,nlines
bte r0,nlines,exit_scanSegment
//
// If (y0 &mask != processor_id ) continue;
//
and y0,mask, itemp1
bte itemp1,processor_id,ignore_line
// dx=(right->ex)>>16-(left->ex)>>16
shr 16,left_ex,x0 // descale left edge to temp
shr 16,right_ex,dx // descale right edge to dx
subs dx,x0,dx // form right-left
// if (dx==0) then ignore this line, walk edges (not a delayed br )
bte r0, dx, ignore_line
subs r0, dx, r0 // if (dx<0) swap pointers etc..
bc no_swap
// swap l / r values
subs r0,dx,dx // dx = -dx
or leftE,r0,itemp1
or rightE,r0,leftE
or itemp1,r0,rightE
or left_ex,r0,itemp1
or right_ex,r0,left_ex
or itemp1,r0,right_ex
or left_ez,r0,itemp1
or right_ez,r0,left_ez
or itemp1,r0,right_ez
shr 16,left_ex,x0
no_swap:
// pixel = pixline+x0
addu pixline,x0,paddr
// pixel = pixel&0xfffffff8
andnot 0x7,paddr,paddr
// zixel = zixline+x0
shl 1,x0,itemp1
addu zixline,itemp1,zaddr
// zixel = zixel&0xfffffff0
andnot 0xf,zaddr,zaddr
// try to avoid any memory hits here
or r0,dz,save_1
or r0,x0,save_2
call _zbufferSegment // this is a delayed op
or r0,left_ez,save_3
or r0,save_1,dz
or r0,save_2,x0
or r0,save_3,left_ez
ignore_line:
// walk up edges of screen
ld.l EDGE_edx(leftE),itemp1 // dx and dz are contiguous fields
adds left_ex,itemp1,left_ex
ld.l EDGE_edz(leftE),itemp1 // dx and dz are contiguous fields
adds left_ez,itemp1,left_ez
ld.l EDGE_edx(rightE),itemp1
adds right_ex,itemp1,right_ex
ld.l EDGE_edz(rightE),itemp1
adds right_ez,itemp1,right_ez
//
//
// if((y0 & mask) == mask)
// {
// pixline += STEP;
// zixline += STEP;
// }
//
and y0,mask,itemp1
btne itemp1, mask, NoStep
adds pixline, STEP, pixline
adds zixline, STEP, zixline
NoStep:
br next_scan_line
// delayed branch
adds 1,y0,y0
exit_scanSegment:
// restore registers into edge structures
st.l right_ex,EDGE_ex(rightE)
st.l right_ez,EDGE_ez(rightE)
st.l left_ex, EDGE_ex(leftE)
st.l left_ez, EDGE_ez(leftE)
// restore local registers
ld.l 4(sp), r4
ld.l 8(sp), r5
ld.l 12(sp), r6
ld.l 16(sp), r7
ld.l 20(sp), r8
ld.l 24(sp), r9
ld.l 28(sp), r10
ld.l 32(sp), r11
ld.l 36(sp), r12
ld.l 40(sp), r13
ld.l 44(sp), r14
ld.l 48(sp), r15
// restore return address
ld.l 0(sp), r1
bri r1
addu 80,sp,sp