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>
997 lines
26 KiB
ArmAsm
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
|
|
//}}}
|
|
|
|
//}}}
|
|
|