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>
253 lines
6.3 KiB
Scheme
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
|
|
|
|
|
|
|