Files
TeslaRel410/sda4/DPL3/VRENDER/AS860/TRISTRIP.S
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

997 lines
26 KiB
ArmAsm

//
//
// this is the fully working tristrip.ss from before
// trapezoom
//
// Phil 14 April 1992
//
//
//
//
//
// void tristrip ( void (*init)(int,int,int,int),
// void (*scan)(int*,int*,int,int,int,int,int,int,int,int,int),
// int *framebuffer,
// int *zbuffer,
// triangle *head,
// int n_tris,
// int processor_shift,
// int processor_id,
// int stride,
// int pxlsize )
//{{{ register allocation
// overload the processor id register with the r4 hop value
//}}}
//{{{ structure offsets
//{{{ vertex offsets
// typedef struct s_vert {
// struct s_vert *next;
// POINT position;
// POINT planeEqn;
// float snorm [3];
// float gnorm [3];
// float colour [3];
// float texcoords [2];
// } VERTEX;
// from start of structure
//}}}
//{{{ triangle offsets (plane equation etc.)
// typedef struct s_triangle {
// struct s_triangle *next;
// edge *edgy;
// edge *ziggy;
// int dr_by_dx;
// int dg_by_dx;
// int db_by_dx;
// int dz_by_dx;
// } triangle;
//}}}
//{{{ edge offsets
// typedef struct struct_edge {
// VERTEX *v0, *v1, *vmin, *vmax;
// int dx_by_dy;
// int dr_by_dy;
// int dg_by_dy;
// int db_by_dy;
// int dz_by_dy;
// } edge;
//}}}
//}}}
//{{{ stack frame layout
//}}}
//{{{ temporary registers
// head aliases r20
// n aliases r21
// e_ab aliases r22
// e_bc aliases r23
// e_ac aliases r24
// va aliases r25
// vb aliases r26
// vc safe
// ledge aliases r9
// redge aliases r10
// aedge aliases r11
//}}}
//{{{ bacon,lettuce,tomato
//}}}
.align 8
.text
//{{{ _reg_dump
.globl _reg_dump
.align 8
_reg_dump::
//{{{ proc entry - save r1 r2 r3
addu -256, sp, sp
st.l r1,0(sp)
adds 256,sp,r1
st.l r1,4(sp)
st.l fp,8(sp)
//}}}
//{{{ save r4..r31
st.l r4, 12(sp)
st.l r5, 16(sp)
st.l r6, 20(sp)
st.l r7, 24(sp)
st.l r8, 28(sp)
st.l r9, 32(sp)
st.l r10, 36(sp)
st.l r11, 40(sp)
st.l r12, 44(sp)
st.l r13, 48(sp)
st.l r14, 52(sp)
st.l r15, 56(sp)
st.l r16, 60(sp)
st.l r17, 64(sp)
st.l r18, 68(sp)
st.l r19, 72(sp)
st.l r20, 76(sp)
st.l r21, 80(sp)
st.l r22, 84(sp)
st.l r23, 88(sp)
st.l r24, 92(sp)
st.l r25, 96(sp)
st.l r26, 100(sp)
st.l r27, 104(sp)
st.l r28, 108(sp)
st.l r29, 112(sp)
st.l r30, 116(sp)
st.l r31, 120(sp)
//}}}
call _trace_regs
mov sp, r16
//{{{ save r4..r31
ld.l 12(sp) , r4
ld.l 16(sp) , r5
ld.l 20(sp) , r6
ld.l 24(sp) , r7
ld.l 28(sp) , r8
ld.l 32(sp) , r9
ld.l 36(sp) , r10
ld.l 40(sp) , r11
ld.l 44(sp) , r12
ld.l 48(sp) , r13
ld.l 52(sp) , r14
ld.l 56(sp) , r15
ld.l 60(sp) , r16
ld.l 64(sp) , r17
ld.l 68(sp) , r18
ld.l 72(sp) , r19
ld.l 76(sp) , r20
ld.l 80(sp) , r21
ld.l 84(sp) , r22
ld.l 88(sp) , r23
ld.l 92(sp) , r24
ld.l 96(sp) , r25
ld.l 100(sp) , r26
ld.l 104(sp) , r27
ld.l 108(sp) , r28
ld.l 112(sp) , r29
ld.l 116(sp) , r30
ld.l 120(sp) , r31
//}}}
//{{{ proc exit
ld.l 0(sp),r1
ld.l 8(sp),fp
bri r1
addu 256, sp, sp
//}}}
//}}}
//{{{
call _reg_dump
nop
//}}}
//{{{ _trapezoid that works ish
// this coding vaguely works ...
// .align 8
// // WORST CASE 28 ticks per line, NO MEMORY HITS!
// // subs r4 , r3 ,r0 <-- now folded into main body code
// _trapezoid::
// bnc .do_not_collect_200_pounds
// ixfr r1,f4 // NOTE f2..f7 unused in inner loops r3 present !
// and r4 , r15 ,r31
// xor r31, r28 ,r0 // r31 == r4 & r15 - if r4 & r15 != r28 , DONT call
// shra 16, r8 , r22
// .trap_loop:
// bnc .skip_call // normally we DO skip the call
//
// shra 16, r7 ,r31 // r31 = xl
// subs r22 ,r31, r22 // r22 = r8 - xl
// subs 0,r31,r0 // carry clear if r22 >0
// shl 2,r31,r31 // doesnt affect carry, avoids freeze condition
// bnc .skip_call
// // prepare to call fn
// adds r5 ,r31, r16
// adds r6 ,r31, r17
// // save volatile registers
// ixfr r18 ,f2
// calli r29 // GO MAN GO
// ixfr r19 ,f3
//
// fxfr f3, r19
// fxfr f2, r18
//
// .skip_call:
// adds 1, r4 , r4
// adds r7 , r9 , r7
// adds r8 , r10 , r8
// adds r19 , r12 , r19
// adds r18 , r11 , r18
// adds r20 , r13 , r20
// adds r21 , r14 , r21
// and r4 , r15 , r31
// bnc .skip_bmp // skip the bump if r4 & r15 !=0
// // bump r5 , r6
// adds r5 , r30 , r5
// adds r6 , r30 , r6
//
// .skip_bmp:
// subs r4 , r3 ,r0 // now folded into main body code
// shra 16, r8 , r22 // doenst affect carry flag, avoid bc.t freeze
// bc.t .trap_loop // this exits on r4 > r3
// xor r31, r28 ,r0 // r31 == r4 & r15 - if r4 & r15 != r28 , DONT call
// fxfr f4,r1
// .do_not_collect_200_pounds:
// bri r1
// nop
//}}}
//{{{ _trapezoid
//{{{ C coding of trapezoid (from tristrip.c)
//
// while ( r4 < r3 ) {
// if (( r4 & r15 ) == r28 ) {
// r31= r7 >>16;
// r22 =( r8 >>16)-r31;
//
// if ( r22 > 0) {
// /* save rgbz */
// (* r29 )( r5 +r31, r6 +r31, r18 , r19 , r20 , r21 , r22 , r23 , r24 , r25 , r26 );
// /* restore rgbz */
// }
// }
//
// r7 += r9 ; r8 += r10 ; r18 += r11 ; r19 += r12 ; r20 += r13 ; r21 += r14 ;
//
// r4 ++;
//
// if (( r4 & r15 ) == 0) {
// r5 += r30 ;
// r6 += r30 ;
// }
// }
//}}}
.align 8
// WORST CASE 28 ticks per line, NO MEMORY HITS!
// subs r4 , r3 ,r0 <-- now folded into main body code
_trapezoid::
bnc .do_not_collect_200_pounds
//
// OK - we have some crapoid code here - all the processors walk up
// all the scanlines, and check to see if this is their scanline
//
// so we need to modify this to - firstly get the real rgbzx by
// walking up until ( r4 & r15 )== r28
// now we shift all the slopes up by pshift.
// now we walk up r21 scanlines r3 a time, doing each line UNTIL ( r4 >= r3 )
// now we shift all the slopes back down, and carry on adding until
// r4 == r3 . Then we exit. Slopes are as they were before the shift, we
// are on the same scanline we would have been on. All should be well.
//
//
ixfr r1,f4 // NOTE f2..f7 unused in inner loops r3 present !
//
// while (( r4 & r15 ) != r28 ) {
// r4 ++;
// r7 += r22 ;
// r8 += r23 ;
// r18 +=dr;
// r19 +=dg;
// r20 +=db;
// r21 +=dz;
// if (( r4 & r15 )==0) {
// r6 += r30 ;
// r5 += r30 ;
// }
// }
// r22 <<=2;
// r23 <<=2;
// dr<<=2;
// dg<<=2;
// db<<=2;
// dz<<=2;
//
// while ( r4 < r3 ) {
// scanline();
// r7 += r22 ;
// r8 += r23 ;
// r18 +=dr;
// r19 +=dg;
// r20 +=db;
// r21 +=dz;
// r6 += r30 ;
// r5 += r30 ;
// r4 +=hop;
// }
//
// r22 >>=2;
// r23 >>=2;
// dr>>=2;
// dg>>=2;
// db>>=2;
// dz>>=2;
//
// while ( r4 > r3 ) {
// r7 -= r22 ;
// r8 -= r23 ;
// r18 -=dr;
// r19 -=dg;
// r20 -=db;
// r21 -=dz;
// }
//
//
and r4 , r15 ,r31
xor r31, r28 ,r0 // r31 == r4 & r15 - if r4 & r15 != r28 , DONT call
shra 16, r8 , r22
.trap_loop:
bnc.t .skip_call1 // normally we DO skip the call
adds 1, r4 , r4
shra 16, r7 ,r31 // r31 = xl
subs r22 ,r31, r22 // r22 = r8 - xl
subs 0, r22 ,r0 // carry clear if r22 >0
shl 2,r31,r31 // doesnt affect carry, avoids freeze condition
bnc.t .skip_call1
adds 1, r4 , r4
// prepare to call fn
adds r5 ,r31, r16
adds r6 ,r31, r17
// save volatile registers
ixfr r18 ,f2
calli r29 // GO MAN GO
ixfr r19 ,f3
fxfr f3, r19
fxfr f2, r18
.skip_call0:
adds 1, r4 , r4
.skip_call1:
adds r8 , r10 , r8
adds r19 , r12 , r19
adds r18 , r11 , r18
adds r20 , r13 , r20
adds r21 , r14 , r21
adds r7 , r9 , r7
and r4 , r15 , r31
bnc.t .skip_bmp1 // skip the bump if r4 & r15 !=0
subs r4 , r3 ,r0 // now folded into main body code
// bump r5 , r6
adds r5 , r30 , r5
adds r6 , r30 , r6
.skip_bmp:
subs r4 , r3 ,r0 // now folded into main body code
.skip_bmp1:
shra 16, r8 , r22 // doenst affect carry flag, avoid bc.t freeze
bc.t .trap_loop // this exits on r4 > r3
xor r31, r28 ,r0 // r31 == r4 & r15 - if r4 & r15 != r28 , DONT call
fxfr f4,r1
.do_not_collect_200_pounds:
bri r1
nop
//}}}
//{{{ _trapezoom
.align 8
// seems to be 24 ticks per line, no memory hits
// subs r4 , r3 ,r0 <-- now folded into main body code
//
//
// this is the zippywippy trapezoid which understands that it
// has been given slopes shifted up by processor_shift
// its only difference in behaviour is to add 'hop' to r4 rather
// than 1. When r4 > r3 we exit, DOING NOTHING - the calling
// code can then do smart things dependent on l/ r18 ness of the
// replace edge etc.
//
// so our trapezoom algorithm is simply
//
// while ( r4 < r3 ) {
// scanline();
// r7 += r22 ;
// r8 += r23 ;
// r18 +=dr;
// r19 +=dg;
// r20 +=db;
// r21 +=dz;
// r6 += r30 ;
// r5 += r30 ;
// r4 +=hop;
// }
// return ( r4 - r3 );
//
_trapezoom::
bnc .exit_zoom
//
ixfr r1,f4 // NOTE f2..f7 unused in inner loops r3 present !
//
shra 16, r8 , r22
.trapzoom_loop:
shra 16, r7 ,r31 // r31 = xl
subs r22 ,r31, r22 // r22 = r8 - xl
subs 0, r22 ,r0 // carry clear if r22 >0
shl 2,r31,r31 // doesnt affect carry, avoids freeze condition
bnc.t .skip_zoomcall
adds r28 , r4 , r4
// prepare to call fn
adds r5 ,r31, r16
adds r6 ,r31, r17
// save volatile registers
ixfr r18 ,f2
calli r29 // GO MAN GO
ixfr r19 ,f3
fxfr f3, r19
fxfr f2, r18
.skip_zoomcall:
adds r8 , r10 , r8
adds r19 , r12 , r19
adds r18 , r11 , r18
adds r20 , r13 , r20
adds r21 , r14 , r21
adds r7 , r9 , r7
adds r5 , r30 , r5
adds r6 , r30 , r6
subs r4 , r3 ,r31 // now folded into main body code
bc.t .trapzoom_loop // this exits on r4 > r3
shra 16, r8 , r22 // doesnt affect carry flag, avoid bc.t freeze
// 24 ticks per scanline rendered..
fxfr f4,r1 // exit with r31 == r4 - r3
.exit_zoom:
bri r1
nop
//}}}
//{{{ _setv
// #define setv(yptr, atptr, l, r18 ,act) // r4 =yptr[Y]; // r9 =l; r10 = r18 ; activate_edge=act; // r3 =atptr[Y]
// below are ordered to try and minimize freezes
//}}}
//{{{ _swap(p1,p2)
// xor r9 , r10 , r9 ;
// xor r9 , r10 , r10 ;
// xor r9 , r10 , r9
//}}}
//{{{ _astristrip
.globl _astristrip
.align 8
_astristrip::
//{{{ check for r21 > 0
subs r0, r21 , r0
bc .procentry
bri r1
nop
//}}}
//{{{ proc entry
.procentry:
addu -160 , sp, sp
st.l fp, 156 (sp)
st.l r1, 152 (sp)
//}}}
//{{{ save r4..r15
st.l r4, 92 (sp)
st.l r5, 88 (sp)
st.l r6, 84 (sp)
st.l r7, 80 (sp)
st.l r8, 76 (sp)
st.l r9, 72 (sp)
st.l r10, 68 (sp)
st.l r11, 64 (sp)
st.l r12, 60 (sp)
st.l r13, 56 (sp)
st.l r14, 52 (sp)
st.l r15, 48 (sp)
//}}}
//{{{ save f2..f7
fst.d f2, 40 (sp)
fst.d f4, 32 (sp)
fst.d f6, 24 (sp)
//}}}
//{{{ save and reorder params
st.l r16 , 96 (sp)
mov r17 , r29
st.l r18 , 44 (sp)
st.l r19 , 16 (sp)
st.l r20 , 108 (sp)
st.l r21 , 104 (sp)
st.l r22 , 100 (sp)
mov r23 , r28
shl 2, r24 , r30 // fix stride for byte addressing
or 1,r0,r31
shl r22 ,r31, r15 // 1 << r22
adds -1, r15 , r15 // r15 = (1<<processor_shift) - 1
//}}}
//{{{ call setpixelsize()
call _setpixelsize
mov r25 , r16
//}}}
.for_i_ntris:
//{{{ order edges (sort triangle on minimum r4 )
// {
// triangle * r21 = r20 ->next;
// edge *ab,*bc,*ac;
//
// ab= r20 ->ziggy; ac= r20 ->edgy;
// bc= r21 ->ziggy;
ld.l 108 (sp), r20
ld.l 0 ( r20 ), r21
st.l r21 , 108 (sp) // pre-walk triangle pointer
ld.l 8 ( r20 ), r22
ld.l 4 ( r20 ), r24
ld.l 8 ( r21 ), r23
// /* there are only 3 cases - a lowest, b lowest, c lowest */
// {
// int *a, * r20 , *c, *atp;
//
//
// a=(int *) (&ab->v0->position);
// r20 =(int *) (&ab->v1->position);
// c=(int *) (&ac->v1->position);
//
ld.l 0 ( r22 ), r25
ld.l 4 ( r22 ), r26
ld.l 4 ( r24 ), r27
// if (a[Y] < r20 [Y]) {
ld.l 8 ( r25 ), r16
ld.l 8 ( r26 ), r17
subs r0, r17 ,r31;adds r31, r16 ,r0;bnc .check_bc
// if (c[Y] < a[Y]) {
ld.l 8 ( r27 ), r17
subs r0, r16 ,r31;adds r31, r17 ,r0;bnc .a_lowest
// atp=(int *) (&ab->vmin->position);
// setv(c,atp,ac,bc,ab);
// }
.c_lowest:
ld.l 8 ( r22 ), r31;mov r24 , r9 ;ld.l 8 ( r27 ), r4 ;mov r23 , r10 ;ld.l 8 (r31), r3 ;br .l_and_r_decision;mov r22 , r11
.a_lowest:
// else {
// atp=(int *) (&bc->vmin->position);
// setv(a,atp,ac,ab,bc);
// }
// }
ld.l 8 ( r23 ), r31;mov r24 , r9 ;ld.l 8 ( r25 ), r4 ;mov r22 , r10 ;ld.l 8 (r31), r3 ;br .l_and_r_decision;mov r23 , r11
.check_bc:
// else {
// if ( r20 [Y] < c[Y]) {
ld.l 8 ( r27 ), r16 // since r20 still in r17
subs r0, r16 ,r31;adds r31, r17 ,r0;bnc .c_lowest
// atp=(int *) (&ac->vmin->position);
// setv( r20 ,atp,bc,ab,ac);
// }
ld.l 8 ( r24 ), r31;mov r23 , r9 ;ld.l 8 ( r26 ), r4 ;mov r22 , r10 ;ld.l 8 (r31), r3 ;br .l_and_r_decision;mov r24 , r11
// else {
// atp=(int *) (&ab->vmin->position);
// setv(c,atp,ac,bc,ab);
// }
// }
// }
// ld.l 8 ( r22 ), r31;mov r24 , r9 ;ld.l 8 ( r27 ), r4 ;mov r23 , r10 ;ld.l 8 (r31), r3 ;br .l_and_r_decision;mov r22 , r11
//}}}
.l_and_r_decision:
//{{{ now determine ABSOLUTELY SECURELY which edge is l and which is r18
// remember, we have not yet stored r9 / r10 / r11 into memory
// if ( r9 ->dx_by_dy == MINT) {
ld.l 16 ( r9 ), r16 // r16 = r9 ->dx_by_dy
ld.l 16 ( r10 ), r17 // r17 = r10 ->dx_by_dy
xorh 0x8000, r16 ,r0
bnc.t .check_r_horiz
xorh 0x8000, r17 ,r0 // most edges are NOT horizontal, so we TAKE this
// if ( r9 ->vmin == r10 ->vmin) {
ld.l 8 ( r9 ), r16
ld.l 8 ( r10 ), r17
xor r16 , r17 ,r0
bnc .lmin_not_rmin // branch taken if not the same
// swap ( r9 , r10 , edge* );
mov r9 ,r31;mov r10 , r9 ;mov r31, r10
// activate_edge = (edge *) (1|(int) activate_edge);
or 1, r11 , r11
// r7 = ((int *)( r9 ->vmin->position))[X];
// }
ld.l 8 ( r9 ), r31
br .extract_plane_eqn
ld.l 4 (r31), r7
.lmin_not_rmin:
// else {
// r7 = ((int *)( r10 ->vmin->position))[X];
// }
// }
ld.l 8 ( r10 ), r31
br .extract_plane_eqn
ld.l 4 (r31), r7
.check_r_horiz:
// else if ( r10 ->dx_by_dy == MINT) {
// xorh 0x8000, r17 ,r0 <--- this is now executed above in a delayed branch
bnc.t .none_horiz
subs r0, r16 ,r31 // again, this is most frequent case
// first instruction of .none_horiz
// if ( r10 ->vmax == r9 ->vmin) {
ld.l 12 ( r10 ), r16
ld.l 8 ( r9 ), r17
xor r16 , r17 ,r0
bnc .rmax_not_lmin
// swap ( r9 , r10 , edge* );
mov r9 ,r31;mov r10 , r9 ;mov r31, r10
// r7 = ((int *)( r10 ->vmin->position))[X];
// }
ld.l 8 ( r10 ), r31
br .extract_plane_eqn
ld.l 4 (r31), r7
.rmax_not_lmin:
// else {
// activate_edge = (edge *) (1|(int) activate_edge);
or 1, r11 , r11
// r7 = ((int *)( r9 ->vmin->position))[X];
// }
// }
//
ld.l 8 ( r9 ), r31
br .extract_plane_eqn
ld.l 4 (r31), r7
.none_horiz:
// else {
// if ( r10 ->dx_by_dy < r9 ->dx_by_dy) {
// this was
adds r31, r17 ,r0 // r31 holds - r9 ->dx_by_dy
bnc .dont_swap
// swap( r9 , r10 , edge* );
mov r9 ,r31;mov r10 , r9 ;mov r31, r10
// }
//
.dont_swap:
// r7 = ((int *)( r9 ->vmin->position))[X];
ld.l 8 ( r9 ), r31
ld.l 4 (r31), r7
//
// if (((int *)( r9 ->vmax->position))[Y] >
// ((int *)( r10 ->vmax->position))[Y])
// {
// activate_edge = (edge *) (1|(int) activate_edge);
ld.l 12 ( r9 ), r16
ld.l 12 ( r10 ), r17
ld.l 8 ( r16 ), r16
ld.l 8 ( r17 ), r17
subs r17 , r16 ,r0
bc.t .extract_plane_eqn
or 1, r11 , r11
//}}}
.extract_plane_eqn:
// tidy up after previous stuff
// st.l r9 , 120 (sp)
// st.l r10 , 116 (sp)
st.l r11 , 112 (sp)
mov r7 , r8 // since r8 == r7 r3 start of triangle
//{{{ extract plane eqn DONE
// remember, r20 is still in r20
mov r20 ,r31
ld.l 12 (r31), r23
ld.l 16 (r31), r24
ld.l 20 (r31), r25
ld.l 24 (r31), r26
//}}}
//{{{ set up initial values for {xyzrgb} DONE
//
mov r9 ,r31
ld.l 16 ( r10 ), r10
ld.l 8 (r31), r16 // r16 = r9 ->vmin
ld.l 4 ( r16 ), r7
ld.l 8 ( r16 ), r4
ld.l 12 ( r16 ), r21
ld.l 60 ( r16 ), r18
ld.l 64 ( r16 ), r19
ld.l 68 ( r16 ), r20
ld.l 16 (r31), r9
ld.l 20 (r31), r11
ld.l 24 (r31), r12
ld.l 28 (r31), r13
ld.l 32 (r31), r14
//}}}
// /* GO ! */
//{{{ compute start values of r5 , r6 DONE
ld.l 100 (sp), r31
shr r31, r4 , r31
ixfr r31, f2
ixfr r30 , f4
fmlow.dd f2,f4,f2
ld.l 44 (sp), r5
ld.l 16 (sp), r6
fxfr f2,r31
adds r5 ,r31, r5
adds r6 ,r31, r6
//}}}
//{{{ set up slopes for subsequent scans DONE
// (*init)( r23 , r24 , r25 , r26 );
// this can be optimised by passing hods-o-bogus parameters to init
ld.l 96 (sp), r31
calli r31
nop
//}}}
// ideally we call trapezoom here, passing it
// 4x slopes .. we need to do the trap stuff, skipping,
// until we are aligned with this processor. then we do the
// trapzoom, hopping 2 (4,8) lines r3 a time. trapzoom exits
// with r4 - r3 in r31, so IF ITS A LEFT HAND EDGE, de-click all
// incrementers until aligned - this costs way less on a right
// edge. Now extract stuff out of the new edge, walking up
// until r3 (from the new edge) == r4 (from the exit of last trap)
// then call trapzoom again
//
//{{{ trapezoid DONE
call _trapezoid
subs r4 , r3 ,r0
//}}}
//{{{ replace worn-out edge DONE
ld.l 112 (sp), r31
and 1,r31,r0
bnc .activate_right
// now activate left edge
//{{{ activate left edge - happens every other triangle
// r9 =activate_edge;
ld.l 8 (r31), r16
// r16 = r11 ->vmin
ld.l 16 (r31), r9
ld.l 20 (r31), r11
ld.l 24 (r31), r12
ld.l 28 (r31), r13
ld.l 32 (r31), r14
ld.l 4 ( r16 ), r7
ld.l 12 ( r16 ), r21
ld.l 60 ( r16 ), r18
ld.l 64 ( r16 ), r19
br .set_at
ld.l 68 ( r16 ), r20
//}}}
.activate_right:
// here activate right edge
//{{{ easy case, right edge
// r10 = (edge *) (1 ^ (int) activate_edge);
// r8 =((int *)(& r10 ->vmin->position))[X];
// r10 = r10 ->dx_by_dy;
xor 1,r31,r31
ld.l 8 (r31), r16 // r16 = r10 ->vmin
ld.l 16 (r31), r10
ld.l 4 ( r16 ), r8
//}}}
// r3 =((int *) (& r10 ->vmax->position))[Y];
.set_at:
// ld.l 116 (sp), r31
ld.l 12 (r31), r31 // since r31 holds r11 !
ld.l 8 (r31), r3
//}}}
//{{{ trapezoid DONE
call _trapezoid
subs r4 , r3 ,r0
//}}}
//{{{ r20 = r21 ; ntris--; } DONE /* i.e end loop */
ld.l 104 (sp), r16
adds -1, r16 , r16
or r0, r16 ,r0
bnc.t .for_i_ntris
st.l r16 , 104 (sp)
//}}}
.restore:
//{{{ restore f2..f7
fld.d 40 (sp), f2
fld.d 32 (sp), f4
fld.d 24 (sp), f6
//}}}
//{{{ restore r4..r15
ld.l 92 (sp), r4
ld.l 88 (sp), r5
ld.l 84 (sp), r6
ld.l 80 (sp), r7
ld.l 76 (sp), r8
ld.l 72 (sp), r9
ld.l 68 (sp), r10
ld.l 64 (sp), r11
ld.l 60 (sp), r12
ld.l 56 (sp), r13
ld.l 52 (sp), r14
ld.l 48 (sp), r15
//}}}
//{{{ proc exit
ld.l 156 (sp),fp
ld.l 152 (sp),r1
bri r1
addu 160 , sp, sp
//}}}
//{{{ E S C A P E ! ! ! ! !
br .restore
nop
//}}}
//}}}