// // 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<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