#include "\projects\dbi0150\dbi0151\ucode\igc_opco.h" #include "\dpl3\vrender\pxpl5sup\pxplmacr.h" #include "\dpl3\vrender\pxpl5sup\divpxmap.h" #include "\dpl3\vrender\pxpl5sup\dmaengn.h" #include "\dpl3\vrender\pxpl5sup\nuregmap.ss" #define fv1 fr0 #define fv2 fr1 #define fv3 fr2 #define dz1 fA #define dz2 fB #define dx0 fx0 #define dy0 fy0 // fits a plane equation to a single variable held in fv1 fv2 fv3 --{{{ fitplane_fn_p .align 8 fitplane_fn_p:: d.pfsub.ss fv2, fv1, f0 nop d.pfsub.ss fv3, fv1, f0 nop d.pfsub.ss f0, f0, f0 // dz1 in last-stage adder fld.l variable(rv1), fv1 d.pfadd.ss f0, f0, dz1 nop d.pfadd.ss f0, f0, dz2 fld.l variable(rv2), fv2 d.pfmul.ss dy1, dz2,f0 nop d.pfmul.ss dy2, dz1,f0 fld.l variable(rv3), fv3 d.pfmul.ss dx1, dz2,f0 nop d.pfmul.ss dx2, dz1,dz2 nop d.r2s1.ss dz2, f0, f0 // adder1 = A nop d.r2ap1.ss f0, f0, f0 st.l iparam1, 4(rcoeffptr) d.r2st.ss dx0, f0, f0 // adder1 = B, adder3 = A, KR=dx0 nop d.rat1p2.ss f0, f0, fA // mul1 = A*dx0 adder2 = B, nop d.r2st.ss dy0, f0, f0 // adder3 = B, mul2=A*dx0, KR=dy0 fst.l fA, 8(rcoeffptr) d.rat1p2.ss f0, f0, fB // mul1 = B*dy0 mul3=A*dx0 nop d.r2as1.ss z0, f0, f0 // add1=z0-A.dx0, mul2=b*dy0 nop d.r2ps.ss f0, f0, f0 // add2=z0-A.dx0, mul3=b*dy0 fst.l fB, 12(rcoeffptr) d.pfadd.ss f0, f0, f0 // add3=z0-A.dx0,mul3=b.dy0 nop d.m12asm.ss f0,f0,f0 // add1=add3-mul3 nop d.pfadd.ss f0, f0, f0 // add2 nop pfadd.ss f0, f0, f0 // add3 bri r1 pfadd.ss f0, f0, fC fst.l fC, 16(rcoeffptr)++ --}}} ld.l FACET_touched_offs(connection), r31 --{{{ // // need a kosher coding of... // with edgizer // // static void Edgize ( POINT a, POINT b ) // { // float A, B, C; // // A=b[Y]-a[Y]; // B=a[X]-b[X]; // C=-(A*a[X]) -(B*a[Y]); // } // // to edgize, need dx0,dy0, dx1,dy1,dx2,dy2, x1,y1,x2,y2 // so to triangleize, need // dx0,dy0, dx1,dy1, dx2,dy2, x1,y1,x2,y2, z0,z1,z2 // // this would appear to be a kosher coding of... // // // #define FitPlane(A, B, C, d,z0,z1,z2) // { // dz1 = (z1) - (z0); // dz2 = (z2) - (z0); // A = d[Y2]*dz1 - d[Y1]*dz2; // B = d[X1]*dz2 - d[X2]*dz1; // C = (z0) - A * d[X0] - B * d[Y0]; // } // need registers z0,z1,z2, dx0,dx1,dx2, dy0,dy1,dy2 --}}} #if 0 --{{{ fitplanes3_fn_p // // now check out FitPlanes3 // // #define FitPlane(A, B, C, d,z0,z1,z2) // { // dz1 = (z1) - (z0); // dz2 = (z2) - (z0); // A = d[Y2]*dz1 - d[Y1]*dz2; // B = d[X1]*dz2 - d[X2]*dz1; // C = (z0) - A * d[X0] - B * d[Y0]; // } // need registers z0,z1,z2, dx0,dx1,dx2, dy0,dy1,dy2 // conceptually rz1-z0 rz2-z0 gz1-z0 gz2-z0 ->drz1 bz1-z0 ->drz2 bz2-z0 ->dgz1 dy1*drz2 ->dgz2 dy2*drz1 ->dbz1 dy1*dgz2 ->dbz2 dy2*dgz1 y1*z2 --> t dy1*dbz2 y1*z2 - y2*z1 dy2*dbz1 y2*gz1 -> t dx2*drz1 y1*gz2 - y2*gz1 dx1*drz2 y1*bz2 -> t dx2*dgz1 y2*bz1 - y1*bz2 ==> rA dx1*dgz2 x2 * rz1 -> t dx2*dbz1 x1*rz2 - x2*rz1 ==> rB dx1*dbz2 x2*gz1 -> t rA*dx0 x1*gz2 - x2*gz1 ==> gA rB*dx0 x2*bz1 -> t gA*dx0 x2*bz1 - z=x1*bz2 => gB gB*dx0 ->t bA*dx0 -> bA, A*dx0 - B*dx0 flush ->t bB*dx0 -> bB, A*dx0-B*dx0 flush -> t flush -> A*dx0-B*dx0 sub z0 sub z0 sub z0 sub st sub st sub st looks like 33 cycles for 3 variables, assuming they are pre-loaded --}}} #endif // // general polygonal geometry // // i have wimped out on the control structure, and threaded // everything as though it were a bunch of procedure calls. // but the code knows the return address, so just branches to the // next bit of the decision - this burns around 20 cycles per triangle // but makes it easier to read at present. also the btnes are in range! // .globl _pxpl5_poly_geometry .align 8 _pxpl5_poly_geometry:: --{{{ save registers on entry, copy parameters to secure regs fst.d f2, -8(sp) fst.d f4, -16(sp) fst.d f6, -24(sp) st.l r4, -28(sp) st.l r5, -32(sp) st.l r6, -36(sp) st.l r7, -40(sp) st.l r8, -44(sp) st.l r9, -48(sp) st.l r10, -52(sp) st.l r11, -56(sp) st.l r12, -60(sp) st.l r13, -64(sp) st.l r14, -68(sp) st.l r15, -72(sp) st.l r1, -76(sp) st.l r3, -80(sp) adds -96, sp, sp fmov.ss fparam1, fmaterial or r0, iparam1, rcoeff_pp or r0, iparam2, rcoeff_basep or r0, iparam3, connection or r0, iparam4, draw_mode or r0, iparam5, backwards or r0, iparam6, opacity ld.l r0(rcoeff_pp), rcoeffptr ld.l r0(rcoeff_basep), rcoeffbase --}}} // set up edge opcode for all subsequent geometry btne backwards, 0x0, draw_forwards pxpl5op_2(edge_opcode,Ix_TREEgeZERO_L3) br next_poly nop draw_forwards: pxpl5op_2(edge_opcode,Ix_TREEltZERO_L3) next_poly:: ld.l FACET_touched_offs(connection), r31 bte 0x0, r31, walk_poly --{{{ if not enough room, call next_coeffchunk subs rcoeffbase, rcoeffptr, r0 bnc.t enough_room or r0, rcoeffptr, tri_coeffbase // // we enter C land here - push all registers onto stack // st.l r17, -8(sp) st.l r18, -12(sp) st.l r19, -16(sp) st.l r20, -20(sp) st.l r21, -24(sp) st.l r22, -28(sp) st.l r23, -32(sp) st.l r24, -36(sp) st.l r25, -40(sp) st.l r26, -44(sp) st.l r27, -48(sp) st.l r28, -52(sp) st.l r29, -56(sp) st.l r30, -60(sp) st.l r1, -64(sp) call _next_coeffchunk adds -80, sp, sp bte 0x0, r16, exit_poly_geometry or r0, r16, rcoeffptr // lets restore registers adds 80, sp, sp ld.l -4(sp), r16 ld.l -8(sp), r17 ld.l -12(sp), r18 ld.l -16(sp), r19 ld.l -20(sp), r20 ld.l -24(sp), r21 ld.l -28(sp), r22 ld.l -32(sp), r23 ld.l -36(sp), r24 ld.l -40(sp), r25 ld.l -44(sp), r26 ld.l -48(sp), r27 ld.l -52(sp), r28 ld.l -56(sp), r29 ld.l -60(sp), r30 ld.l -64(sp), r1 adds COEFF_FULL, rcoeffptr, rcoeffbase --}}} enough_room:: --{{{ set up coeffptrs to draw triangle // or r0, rcoeffptr, tri_coeffbase adds -4, rcoeffptr, rcoeffptr --}}} --{{{ set up pointers for edgize, load v1 v2 v3 ld.l FACET_nverts_offs(connection), n_verts ld.l (FACET_vert0_offs+0)(connection), rv1 ld.l (FACET_vert0_offs+4)(connection), rv2 ld.l (FACET_vert0_offs+8)(connection), rv3 adds FACET_vert0_offs, connection, vert0_ref or r0, vert0_ref, vertex_ref --}}} start_drawing: --{{{ do preplanarize-and-edgize-in-one --{{{ // static int CalcDeltas2 ( POINT *s, int i, float *d) // { // float recip, temp, cc; // // d[X0] = s[0][X]; // d[Y0] = s[0][Y]; // d[X1] = s[i][X] - s[0][X]; // d[Y1] = s[i][Y] - s[0][Y]; // d[X2] = s[i+1][X] - s[0][X]; // d[Y2] = s[i+1][Y] - s[0][Y]; // cc = d[X1]*d[Y2] - d[Y1]*d[X2]; // temp = cc; // if (cc < 0) // temp = -cc; // if (temp < MINAREA) return -1; /* is polygon degenerate ? */ // recip = 1.0f/cc; // d[X1] *= recip; // d[Y1] *= recip; // d[X2] *= recip; // d[Y2] *= recip; // return(0); // } --}}} // this needs to both execute CalcDeltas AND do the first 3 // triangle edges. subsequent edges are dealt with less efficiently, // but heck #define max_screen_x fr2 #define max_screen_y fg2 or I_SETENABS, r0, iparam1 st.l iparam1, 4(rcoeffptr) fld.d VERT_position_offs(rv1), fx1 fld.d VERT_position_offs(rv2), fx2 fld.d VERT_position_offs(rv3), fx3 fld_from(ftmp3,.C00037) fld_from(ftmp1,.C362436) dfld_from(max_screen_x,.Cmax_x) --}}} alpha_decision:: and draw_mode, DRAW_MODE_VERTEX_ALPHA, r0 bc vertex_alpha br surface_alpha or P_MEMgeSCA(dvpx_opacity, dvpx_opacitybits), r0, iparam2 z_buffer_decision:: and draw_mode, DRAW_MODE_TEXTURE, r0 z_buffer_decision_db:: bc z_buffer_only br z_buffer_texture nop shading_decision:: and draw_mode, DRAW_MODE_SMOOTH, r0 shading_decision_db:: bc gouraud_shade br flat_shade fld.l FACET_r_offs(rvertex), fv2 binitize_it:: --{{{ binitize the triangle and fix coeffptrs .. and walk // now binitize it // first, slam in a NOOP and implicitly correct rcoeffptr ... // looks like 10 ticks spent in here // fst.l f0, 4(rcoeffptr)++ mov tri_coeffbase, iparam1 adds 7, rcoeffptr, r31 subs r31, tri_coeffbase, r31 shl 3, r31, iparam2 orh (DMA_SEND_VAL >> 16), iparam2, iparam2 call _safe_binitize_fn or 10, r0, iparam3 ld.l FACET_next_offs(connection), connection adds 35, rcoeffptr, rcoeffptr andnot 31, rcoeffptr, rcoeffptr btne 0x0, connection, next_poly br exit_poly_geometry nop --}}} walk_poly:: ld.l FACET_next_offs(connection), connection btne 0x0, connection, next_poly exit_poly_geometry:: --{{{ restore registers on exit st.l rcoeffptr, r0(rcoeff_pp) st.l rcoeffbase, r0(rcoeff_basep) adds 96, sp, sp ld.l -80(sp), r3 ld.l -76(sp), r1 ld.l -72(sp), r15 ld.l -68(sp), r14 ld.l -64(sp), r13 ld.l -60(sp), r12 ld.l -56(sp), r11 ld.l -52(sp), r10 ld.l -48(sp), r9 ld.l -44(sp), r8 ld.l -40(sp), r7 ld.l -36(sp), r6 ld.l -32(sp), r5 ld.l -28(sp), r4 fld.d -24(sp), f6 fld.d -16(sp), f4 bri r1 fld.d -8(sp), f2 --}}} // same as walk_poly, but clears out any // coefficient usage for the undrawn poly skip_poly:: br walk_poly or r0, tri_coeffbase, rcoeffptr // the almost procedure calls used internally surface_alpha:: --{{{ just do compare scalar with pixel memory // or P_MEMgeSCA(dvpx_opacity, dvpx_opacitybits), r0, iparam2 st.l iparam2, 8(rcoeffptr) pxpl5op_2(iparam2,Ix_MEMgeSCA_S1, dvpx_opacity, dvpx_opacitybits) st.l iparam2, 4(rcoeffptr) st.l opacity, 12(rcoeffptr) adds 12, rcoeffptr, rcoeffptr fld.l VERT_z_offs(rv1), fv1 fld.l VERT_z_offs(rv2), fv2 br z_buffer_decision fld.l VERT_z_offs(rv3), fv3 --}}} vertex_alpha:: --{{{ planarize alpha, load up Z fld.l VERT_a_offs(rv1), fv1 fld.l VERT_a_offs(rv2), fv2 fld.l VERT_a_offs(rv3), fv3 call fitplane_fn_p or VERT_z_offs, r0, variable br z_buffer_decision_db and draw_mode, DRAW_MODE_TEXTURE, r0 --}}} z_buffer_only:: --{{{ planarize just z call fitplane_fn_p or VERT_r_offs, r0, variable pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits) st.l iparam1, 4(rcoeffptr) br shading_decision adds 4, rcoeffptr, rcoeffptr --}}} z_buffer_texture:: --{{{ fun fun fun - planarize z, texscale*z, t*z*u and t*z*v call fitplane_fn_p or VERT_tex_u_offs, r0, variable pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits) st.l iparam1, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr // hmm - we have A, B, C - need to multiply them by the // frig and re-save them. we need to multiply the frig // by z1,2 3 and multiply z1 2 3 by br shading_decision_db and draw_mode, DRAW_MODE_SMOOTH, r0 --}}} gouraud_shade:: --{{{ pxpl5op_2(variable,Ix_TREEclmpintoMEM_L3, dvpx_r24, 8 ) st.l variable, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 ) call fitplane_fn_p or VERT_g_offs, r0, variable pxpl5op_2(variable,Ix_TREEclmpintoMEM_L3, dvpx_g24, 8 ) st.l variable, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 ) call fitplane_fn_p or VERT_b_offs, r0, variable pxpl5op_2(variable,Ix_TREEclmpintoMEM_L3, dvpx_b24, 8 ) st.l variable, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 ) call fitplane_fn_p or VERT_b_offs, r0, variable br binitize_it fst.l f0, 4(rcoeffptr)++ --}}} flat_shade:: --{{{ // fld.l FACET_r_offs(rvertex), fv2 pxpl5op_2(variable,Ix_TREEclmpintoMEM_C1, dvpx_r24, 8 ) st.l variable, 4(rcoeffptr) pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 ) st.l iparam1, 8(rcoeffptr) fst.l fv2, 12(rcoeffptr)++ fld.l FACET_g_offs(rvertex), fv2 pxpl5op_2(variable,Ix_TREEclmpintoMEM_C1, dvpx_g24, 8) st.l variable, 4(rcoeffptr) pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 ) st.l iparam1, 8(rcoeffptr) fst.l fv2, 12(rcoeffptr)++ fld.l FACET_b_offs(rvertex), fv2 pxpl5op_2(variable,Ix_TREEclmpintoMEM_C1, dvpx_b24, 8) st.l variable, 4(rcoeffptr) pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 ) st.l iparam1, 8(rcoeffptr) fst.l fv2, 12(rcoeffptr)++ br binitize_it fst.l f0, 4(rcoeffptr)++ --}}} --{{{ #define rcoeffptr r9 #define rcoeffbase r10 #define tri_coeffbase r11 --}}} geometry_entry(_poly_zb_rgb_o_t) // 1 1 // // new opacity code // ignore_opacity_intro(label008,label009) adds 1, r0, needs_texture call _preplanarize_fn_p adds VERT_a_offs, r0, iparam2 // should we just exit ? xor 0x0, r31, r0 bnc .bomb_tri_zb_rgb_o_t // 12 13 --{{{ edgize in-line, pre-loads ix_MEMgeTREE_L3() into iparam1 for opacity compare // per edge // // eqn[0]=p1[Y] - p2[Y]; // eqn[1]=p2[X] - p1[X]; // eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]); // // NB we already have // fx13 fx21 fx32 in registers // .align 8 d.pfsub.ss fy1, fy2, f0 adds 4, rcoeffptr, rcoeffptr d.pfsub.ss fy2, fy3, f0 st.l iparam1, 4(rcoeffptr) // TREEltZERO d.pfsub.ss fy3, fy1, f0 st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO d.m12tpm.ss fx1, fy2, ftmp1 fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0] d.m12tpm.ss fx2, fy3, ftmp2 fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0] d.m12tpm.ss fx3, fy1, ftmp1 fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0] d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1 fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1] d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2 fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1] d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3 fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1] d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1 st.l iparam1, 36(rcoeffptr) d.i2s1.ss ftmp5, f0, f0 pxpl5op_2_l(iparam1,Ix_MEMgeTREE_L3, dvpx_opacity, dvpx_opacitybits ) d.i2s1.ss ftmp6, f0, f0 pxpl5op_2_h(iparam1,Ix_MEMgeTREE_L3, dvpx_opacity, dvpx_opacitybits ) d.pfadd.ss f0, f0, ftmp1 fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2] pfadd.ss f0, f0, ftmp2 fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2] pfadd.ss f0, f0, ftmp3 fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2] --}}} // 4 17 call _planarize_fn_p or VERT_z_offs, r0, iparam2 pxpl5op_2(iparam1,Ix_MEMltTREE_L3, dvpx_zbuf,dvpx_zbufbits) // 5 22 // TEXTURIZE TO FIND ZSCALE fld_from ( ftmp2, _.Cturn_z_to_tex ) frcp.ss ftexscale, ftmp1 fmul.ss ftmp1, ftmp2, ftmp1 pfmul.ss fv1, ftmp1, f0 pfmul.ss fv2, ftmp1, f0 pfmul.ss fv3, ftmp1, f0 pfmul.ss f0, f0, ftmp7 pfmul.ss f0, f0, ftmp8 pfmul.ss f0, f0, ftmp9 call _planarize_fn_p or VERT_tex_u_offs, r0, iparam2 // push enable flag for texture support pxpl5op_1 ( iparam1,Ix_ENABintoMEM, dvpx_enblpush ); st.l iparam1, 4(rcoeffptr) pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits) st.l iparam1, 8(rcoeffptr) fmov.ss ftmp7, fv1 adds 8, rcoeffptr, rcoeffptr // cater for tree_l0 and enable push fmov.ss ftmp8, fv2 pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits) fmov.ss ftmp9, fv3 // 4 26 tex z-coordinate call _planarize_fn_p or VERT_tex_u_offs, r0, iparam2 // fix u-coordinate // fix v-coordinate fld_from ( ftmp2, _Cdelta_u ) pfadd.ss ftmp2, fv1, f0 pfadd.ss ftmp2, fv2, f0 pfadd.ss ftmp2, fv3, f0 pfadd.ss f0, f0, fv1 m12apm.ss ftmp7, fv1, fv2 m12apm.ss ftmp8, fv2, fv3 pfmul.ss ftmp9, fv3, f0 pfmul.ss f0, f0, fv1 pfmul.ss f0, f0, fv2 pfmul.ss f0, f0, fv3 // 4 30 tex v-coordinate pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texu, dvpx_texubits) call _planarize_fn_p or VERT_tex_v_offs, r0, iparam2 // fix v-coordinate // fix v-coordinate fld_from ( ftmp2, _Cdelta_v ) pfadd.ss ftmp2, fv1, f0 pfadd.ss ftmp2, fv2, f0 pfadd.ss ftmp2, fv3, f0 pfadd.ss f0, f0, fv1 m12apm.ss ftmp7, fv1, fv2 m12apm.ss ftmp8, fv2, fv3 pfmul.ss ftmp9, fv3, f0 pfmul.ss f0, f0, fv1 pfmul.ss f0, f0, fv2 pfmul.ss f0, f0, fv3 // 4 34 tex u-coordinate pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits) call _planarize_fn_p or VERT_r_offs, r0, iparam2 // do texture dynamic range frig call _texture_rescale adds 1, r0, extra_stuff // 2 36 pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits ) st.l iparam1, 4(rcoeffptr) fst.l fmaterial, 8(rcoeffptr)++ // 15 51 pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_r24, 8 ) st.l iparam2, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 ) call _planarize_fn_p or VERT_g_offs, r0, iparam2 pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_g24, 8 ) st.l iparam2, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 ) call _planarize_fn_p or VERT_b_offs, r0, iparam2 pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_b24, 8 ) st.l iparam2, 4(rcoeffptr) adds 4, rcoeffptr, rcoeffptr pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 ) call _planarize_fn_p or VERT_b_offs, r0, iparam2 fst.l f0, 4(rcoeffptr)++ adds 26, extra_stuff, iparam2 orh (DMA_SEND_VAL>>16)&0xffff, iparam2, iparam2 adds 35, rcoeffptr, rcoeffptr andnot 31, rcoeffptr, rcoeffptr adds -4, rcoeffptr, rcoeffptr mov rcoeffsave, iparam1 call _safe_binitize_fn addu 10, r0, iparam3 .bomb_tri_zb_rgb_o_t:: triangle_exit or r0, rcoeffptr, tri_coeffbase