;
; Del`s handy tombraider asm... sorted by del... just for you lot... :)
;
;
;
; PHD_ATAN routine converted to ASM 10/5/96 by DEL!
;
; lotto shorter than the compiled C version...
;
;
; also converted phd_sqrt,phd_sin,phd_cos 21/5/96
;
;
; also loads of other shit asm`ed for speed!
;

	OPT	at+,w-,c+

				include	..\spec_psx\tomb.inc

				global phd_sqrt_asm
				global phd_atan_asm
;				global phd_cos_asm
;				global phd_sin_asm
				global phd_RotYXZpack_asm
				global phd_RotYXZ_asm
				global phd_TranslateRel_asm
				global phd_PushMatrix_asm
				global phd_TranslateAbs_asm
				global GetRoomBounds_asm
				global SetRoomBounds_asm
				global psx_calc_vertice_light_asm
;				global InterpolateMatrix_asm

;	xref phdtan2
;	xref phdtantab
	XREF	atanTab
	XREF	atanOctantTab

W2V_SHIFT2 equ 12

				xref phdsintab
				xref phd_mxptr

				xref ls_divider 				;sint32 		ls_divider;
				xref ls_vector_view 			;PHD_VECTOR 	ls_vector_view;   /* light vector in View Frame*/
				xref ls_adder					;sint32 		ls_adder;

				xref	w2v_matrix

; sweetner GP reference of the small phdtan2C table... :)

;GPVAR_phdtan2	equ (phdtan2-gp_start_address)

GPVAR_phd_mxptr 		equ (phd_mxptr-gp_start_address)
GPVAR_ls_vector_view	equ (ls_vector_view-gp_start_address)
GPVAR_ls_adder			equ (ls_adder-gp_start_address)
GPVAR_ls_divider		equ (ls_divider-gp_start_address)

;
; Square-root...
;
; R4 = N
;
; returns Square root of entry in R2
;
; uses at,r2,r3,r4,r5 (check the at- and at+)
;


phd_sqrt_asm
		lui 	r3,$4000				;r3 = $40000000
		move	r2,r0					;a = 0
		move	r5,r2

.loop
		addu	r2,r2,r3				;r2 = a+b
		slt 	at,r4,r2				;a > c ?
		beq 	at,r0,.elseme			;a > c ?
		nop

		j		.contme
		move	r2,r5

.elseme
		subu	r4,r4,r2				;c-=a
		or		r2,r3,r5				;a |= d
.contme
		sra 	r3,r3,2

		bne 	r3,r0,.loop
		sra 	r5,r2,1 				;sweetner!

		j		r31
		nop

; dels c version...
;		angle &=65535
;		if angle > 32768
;		{
;		 flag++
;		}
;		angle &= 32767
;		if(angle>=16384)
;		{
;		 angle=(32768-angle)
;		}
;		angle>>=4
;		tmp = phdsintab+angle
;		if(flag!=0)
;		 return(0-*tmp)
;		else
;		 return(*tmp)


;****************************************************************************
;*
;*				Int 	phd_atan( int x,int y );
;*
;*				Entry R4: Distance along X axis..
;*					  R5: Distance along Y axis..
;*				Exit  R2: Angle ( 0 - 65536 )
;*
;****************************************************************************

phd_atan_asm
		bne 	r4,r0,.cont 			;x == 0 ?
		nop
		beq 	r5,r0,.exit 			;y == 0 ?
		move	r2,r0					;Angle = 0

.cont
		bgez	r4,.skip1				;x >= 0?
		move	r6,r0					;octant = 0

		li		r6,4					;octant = 4
		subu	r4,r0,r4				;x = -x (make x positive)

.skip1
		bgez	r5,.skip2				;y >= 0?
		slt 	r2,r4,r5				;y>x ??

		addu	r6,r6,2 				;octant+=2
		subu	r5,r0,r5				;y = -y (make y positive)
		slt 	r2,r4,r5				;y>x ??
.skip2
		beq 	r2,r0,.scale_it_down	;y>x ??
		move	r2,r4					;r2 = xstash

		addu	r6,r6,1 				;octant++
		move	r4,r5					;x=y
		j		.scale_it_down
		move	r5,r2					;y=xstash

.while_loop
		sra 	r5,r5,1 				;y>>=1
		sra 	r4,r4,1 				;x>>=1
.scale_it_down
		sll 	r2,r5,16				;r2 = y<<16
		sra 	r2,r2,16				;r2 = y

		bne 	r2,r5,.while_loop		;while ( (sint16)y!=y
		sll 	r2,r5,11				;r2 = y<<NUMSTEPBITS

		div 	r2,r4					;(y<<NUMSTEPBITS)/x

		sll 	r3,r6,2 				;r3 = octant<<2

		mac.la	r2,atanOctantTab
		addu	r3,r3,r2				;r3 = (octant<<2)+phdtan2
		lw		r2,(r3)

;		addu	r3,r3,gp				;r3 = (octant<<2)+GP
;		lw		r2,GPVAR_phdtan2(r3)	;r2 = phdtan2C[octant];

		mflo	r7						;r2 = (y<<NUMSTEPBITS)/x

		sll 	r7,r7,1 				;((y<<NUMSTEPBITS)/x) << 1
		mac.lh	r4,atanTab(r7)		;r4 = phdtantabC[(y<<NUMSTEPBITS)/x]

		nop
		addu	r2,r4,r2				;r2 = phdtantabC[(y<<NUMSTEPBITS)/x] + phdtan2C[octant];
		bgez	r2,.exit				;n>= 0??
		nop
		subu	r2,r0,r2				;n = -n

.exit
		j		r31
		nop




;
;enter with:- r4 = angle
;
; returns:- r2 = result
;

	XREF	rcossin_tbl

phd_cos_asm
	lui	r2,rcossin_tbl>>16
	ori	r2,rcossin_tbl&$ffff
	srl	r4,2
	andi	r4,16380
	add	r2,r4
	lh	r2,2(r2)
	jr	ra
	nop

	sll	r4,18
	jr	ra
	sra	r2,r4,16

phd_sin_asm
	lui	r2,rcossin_tbl>>16
	ori	r2,rcossin_tbl&$ffff
	srl	r4,2
	andi	r4,16380
	add	r2,r4
	lh	r2,0(r2)
	jr	ra
	nop

	sll	r4,18
	jr	ra
	sra	r2,r4,16

	if 0
;
;enter with:- r4 = angle
;
; returns:- r2 = result
;

phd_cos_asm
		addi	r4,16384

phd_sin_asm
		andi	r3,r4,$ffff 			;r3 = angle & $ffff
		li		r4,$8000				;r4 = 32768
		andi	r6,r3,$7fff 			;r3 = angle & $7fff
		slt 	r2,r6,16384 			;angle < (DEG360/4) ??
		bne 	r2,r0,.elseme
		slt 	r5,r4,r3				;r5 = angle > DEG360/2 ??
		subu	r6,r4,r6				;r3 = $8000-angle
.elseme
		sra 	r6,r6,4 				;r3 = angle >>4
		sll 	r6,r6,1 				;r3 = (angle >>4) << 1
		mac.la	r2,phdsintab			;r2 = sintab
		addu	r6,r6,r2				;r3 = phdsintab+angle

		bne 	r5,r0,.negate_result
		lh		r2,0(r6)
		j		r31
		nop

.negate_result
		j		r31
		subu	r2,r0,r2				;neg the result...


	endif


; phd_RotYXZpack_asm
;
; r4 = rots
;
; freed r16,r17,r18,r19,r13 (used to stash return address)
;
;
;
;
;
;
; ok, this routine assumes that r13,r14,r15,r24 and r25 are NOT used by phd_sin_asm or phd_cos_asm.
;
;

phd_RotYXZpack_asm
		move	r25,r4					;r25 = rots
		lw	r24,GPVAR_phd_mxptr(gp)
		sra 	r14,r25,4				;r2 = rots>>4
		andi	r14,r14,$ffc0			;r14 = (((rots>>10)&1023)<<6) (extract RotY)
;r14 = ang
		beq 	r14,r0,.do_rotx 		;ang == 0?
		move	r13,r31 				;r13 = return address

		jal 	phd_sin_asm 			;sin angle me...
		move	r4,r14					;r4 = ang
		move	r15,r2					;r15 = sina
;r15 = sina
		jal 	phd_cos_asm
		move	r4,r14

		lw		r3,M_00(r24)			;r3 = *(mptr+M00)
		move	r14,r2					;r14 = cosa
;r14 = cosa

		mult	r14,r3					;*(mptr+M00) * cosa
		mflo	at						;at = *(mptr+M00) * cosa

		lw		r2,M_02(r24)			;r2 = *(mptr+M02)
		nop

		mult	r15,r2					;*(mptr+M02) * sina
		mflo	r5						;r5 = *(mptr+M02) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M02)*cosa
		mflo	r12 					;r12 = *(mptr+M02)*cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M00) * sina
		mflo	r10 					;r10 = *(mptr+M00) * sina

		lw		r3,M_10(r24)			;r3 = *(mptr+M10)
		nop

		mult	r14,r3					;*(mptr+M10) * cosa
		mflo	r11 					;r11 = *(mptr+M10) * cosa

		lw		r2,M_12(r24)			;r2 = *(mptr+M12)
		nop

		mult	r15,r2					;*(mptr+M12) * sina
		mflo	r8						;r8 = *(mptr+M12) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M12) * cosa
		mflo	r9						;r9 = *(mptr+M12) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M10) * sina
		mflo	r6						;r6 = *(mptr+M10) * sina

		lw		r3,M_20(r24)			;r3 = *(mptr+M20)
		nop

		mult	r14,r3					;*(mptr+M20) * cosa
		mflo	r7						;r7 = *(mptr+M20) * cosa

		lw		r2,M_22(r24)			;r2 = *(mptr+M22)
		nop

		mult	r15,r2					;*(mptr+M22) * sina
		mflo	r4						;r4 = *(mptr+M22) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M22) * cosa
		subu	r2,at,r5				;r2 = (*(mptr+M00) * cosa) - (*(mptr+M02) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M00) * cosa) - (*(mptr+M02) * sina) >> W2V_SHIFT2
		mflo	r5						;r5 = *(mptr+M22) * cosa

		sw		r2,M_00(r24)			;*(mptr+M00) = (*(mptr+M00) * cosa) - (*(mptr+M02) * sina) >> W2V_SHIFT2
		addu	r2,r12,r10				;r2 = ( *(mptr+M02)*cosa + *(mptr+M00) * sina )

		mult	r15,r3					;*(mptr+M20) * sina
		sra 	r2,r2,W2V_SHIFT2				;r2 = ( *(mptr+M02)*cosa + *(mptr+M00) * sina ) >> W2V_SHIFT2
		sw		r2,M_02(r24)			;*(mptr+M02) = ( *(mptr+M02)*cosa + *(mptr+M00) * sina ) >> W2V_SHIFT2
		subu	r2,r11,r8				;r2 = (*(mptr+M10) * cosa) - (*(mptr+M12) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M10) * cosa) - (*(mptr+M12) * sina)) >> W2V_SHIFT2
		sw		r2,M_10(r24)			;*(mptr+M10) = ((*(mptr+M10) * cosa) - (*(mptr+M12) * sina)) >> W2V_SHIFT2
		addu	r2,r9,r6				;r2 = (*(mptr+M12) * cosa) + (*(mptr+M10) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M12) * cosa) + (*(mptr+M10) * sina) >> W2V_SHIFT2
		sw		r2,M_12(r24)			;*(mptr+M12) = (*(mptr+M12) * cosa) + (*(mptr+M10) * sina) >> W2V_SHIFT2
		subu	r2,r7,r4				;r2 = (*(mptr+M20) * cosa) - (*(mptr+M22) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M20) * cosa) - (*(mptr+M22) * sina) >> W2V_SHIFT2
		sw		r2,M_20(r24)			;*(mptr+M20) = (*(mptr+M20) * cosa) - (*(mptr+M22) * sina) >> W2V_SHIFT2
		mflo	r2						;r2 = *(mptr+M20) * sina

		addu	r2,r5,r2				;r2 = (*(mptr+M22) * cosa) + (*(mptr+M20) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M22) * cosa) + (*(mptr+M20) * sina) >> W2V_SHIFT2
		sw		r2,M_22(r24)			;*(mptr+M22) = (*(mptr+M22) * cosa) + (*(mptr+M20) * sina) >> W2V_SHIFT2


.do_rotx
		sra 	r2,r25,W2V_SHIFT2				;r2 = rots>>14
		andi	r14,r2,$ffc0			;r14 = (((rots>>20)&1023)<<6);			// Extract RotX

		beq 	r14,r0,.do_rotz 		;ang == 0 ??
		andi	r2,r25,$3ff 			;r2 = rots&1023

		jal 	phd_sin_asm 			;sin angle me...!
		move	r4,r14					;r4 = ang

		move	r15,r2					;r15 = sina
;r15 = sina
		jal 	phd_cos_asm 			;cos angle me...!
		move	r4,r14					;r4 = ang

		lw		r3,M_01(r24)			;r3 = *(mptr+M01)
		move	r14,r2					;r14 = cosa
;r14 = cosa
		mult	r14,r3					;*(mptr+M01) * cosa
		mflo	at						;at = *(mptr+M01) * cosa

		lw		r2,M_02(r24)			;r2 = *(mptr+M02)
		nop

		mult	r15,r2					;*(mptr+M02) * sina
		mflo	r5						;r5 = *(mptr+M02) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M02) * cosa
		mflo	r12 					;r12 = *(mptr+M02) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M01) * sina
		mflo	r10 					;r10 = *(mptr+M01) * sina

		lw		r3,M_11(r24)			;r3 = *(mptr+M11)
		nop

		mult	r14,r3					;*(mptr+M11) * cosa
		mflo	r11 					;r11 = *(mptr+M11) * cosa

		lw		r2,M_12(r24)			;r2 = *(mptr+M12)
		nop

		mult	r15,r2					;*(mptr+M12) * sina
		mflo	r8						;r8 = *(mptr+M12) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M12) * cosa
		mflo	r9						;r9 = *(mptr+M12) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M11) * sina
		mflo	r6						;r6 = *(mptr+M11) * sina

		lw		r3,M_21(r24)			;r3 = *(mptr+M21)
		nop

		mult	r14,r3					;*(mptr+M21) * cosa
		mflo	r7						;r7 = *(mptr+M21) * cosa

		lw		r2,M_22(r24)			;r2 = *(mptr+M22)
		nop

		mult	r15,r2					;*(mptr+M22) * sina
		mflo	r4						;r4 = *(mptr+M22) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M22) * cosa
		addu	r2,at,r5				;r2 = (*(mptr+M01) * cosa) + (*(mptr+M02) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M01) * cosa) + (*(mptr+M02) * sina) >> W2V_SHIFT2
		mflo	r5						;r5 = *(mptr+M22) * cosa

		sw		r2,M_01(r24)			;*(mptr+M01) = (*(mptr+M01) * cosa) + (*(mptr+M02) * sina) >> W2V_SHIFT2
		subu	r2,r12,r10				;r2 = (*(mptr+M02) * cosa) - (*(mptr+M01) * sina)

		mult	r15,r3					;*(mptr+M21) * sina
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M02) * cosa) - (*(mptr+M01) * sina) >> W2V_SHIFT2
		sw		r2,M_02(r24)			;*(mptr+M02) = (*(mptr+M02) * cosa) - (*(mptr+M01) * sina) >> W2V_SHIFT2
		addu	r2,r11,r8				;r2 = (*(mptr+M11) * cosa)+(*(mptr+M12) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M11) * cosa)+(*(mptr+M12) * sina) >> W2V_SHIFT2
		sw		r2,M_11(r24)			;*(mptr+M11) = (*(mptr+M11) * cosa)+(*(mptr+M12) * sina) >> W2V_SHIFT2
		subu	r2,r9,r6				;r2 = (*(mptr+M12) * cosa) - (*(mptr+M11) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M12) * cosa) - (*(mptr+M11) * sina) >> W2V_SHIFT2
		sw		r2,M_12(r24)			;*(mptr+M12) = (*(mptr+M12) * cosa) - (*(mptr+M11) * sina) >> W2V_SHIFT2
		addu	r2,r7,r4				;r2 = (*(mptr+M21) * cosa) + (*(mptr+M22) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M21) * cosa) + (*(mptr+M22) * sina) >> W2V_SHIFT2
		sw		r2,M_21(r24)			;*(mptr+M21) = (*(mptr+M21) * cosa) + (*(mptr+M22) * sina) >> W2V_SHIFT2
		mflo	r2						;r2 = *(mptr+M21) * sina

		subu	r2,r5,r2				;r2 = (*(mptr+M22) * cosa) - (*(mptr+M21) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M22) * cosa) - (*(mptr+M21) * sina)) >> W2V_SHIFT2
		sw		r2,M_22(r24)			;*(mptr+M22) = ((*(mptr+M22) * cosa) - (*(mptr+M21) * sina)) >> W2V_SHIFT2

		andi	r2,r25,$3ff 			;r2 = rots&1023

; r2 = rots&1023

.do_rotz
		sll 	r14,r2,6				;r14 = (rots&1023) << 6
		beq 	r14,r0,.exitme			;ang == 0 ??
		nop

		jal 	phd_sin_asm 			;sinme
		move	r4,r14					;r4 = ang

		move	r15,r2
;r15 = sina

		jal 	phd_cos_asm 			;cosme
		move	r4,r14					;r4 = ang

		lw		r3,M_00(r24)			;r3 = *(mptr+M00)
		move	r14,r2
;r14 = cosa
		mult	r14,r3					;*(mptr+M00) * cosa
		mflo	at						;at = *(mptr+M00) * cosa

		lw		r2,M_01(r24)			;r2 = *(mptr+M01)
		nop

		mult	r15,r2					;*(mptr+M01) * sina
		mflo	r5						;r5 = *(mptr+M01) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M01) * cosa
		mflo	r12 					;r12 = *(mptr+M01) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M00) * sina
		mflo	r10 					;r10 = *(mptr+M00) * sina

		lw		r3,M_10(r24)			;r3 = *(mptr+M10)
		nop

		mult	r14,r3					;*(mptr+M10) * cosa
		mflo	r11 					;r11 = *(mptr+M10) * cosa

		lw		r2,M_11(r24)			;r2 = *(mptr+M11)
		nop

		mult	r15,r2					;*(mptr+M11) * sina
		mflo	r8						;r8 = *(mptr+M11) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M11) * cosa
		mflo	r9						;r9 = *(mptr+M11) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M10) * sina
		mflo	r6						;r6 = *(mptr+M10) * sina

		lw		r3,M_20(r24)			;r3 = *(mptr+M20)
		nop

		mult	r14,r3					;*(mptr+M20) * cosa
		mflo	r7						;r7 = *(mptr+M20) * cosa

		lw		r2,M_21(r24)			;r2 = *(mptr+M21)
		nop

		mult	r15,r2					;*(mptr+M21) * sina
		mflo	r4						;r4 = *(mptr+M21) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M21) * cosa
		addu	r2,at,r5				;r2 = (*(mptr+M00) * cosa) + (*(mptr+M01) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M00) * cosa) + (*(mptr+M01) * sina) >> W2V_SHIFT2
		mflo	r5						;r5 = *(mptr+M21) * cosa

		sw		r2,M_00(r24)			;*(mptr+M00) = (*(mptr+M00) * cosa) + (*(mptr+M01) * sina) >> W2V_SHIFT2
		subu	r2,r12,r10				;r2 = (*(mptr+M01) * cosa) - (*(mptr+M00) * sina)

		mult	r15,r3					;*(mptr+M20) * sina
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M01) * cosa) - (*(mptr+M00) * sina)) >> W2V_SHIFT2
		sw		r2,M_01(r24)			;*(mptr+M01) = ((*(mptr+M01) * cosa) - (*(mptr+M00) * sina)) >> W2V_SHIFT2
		addu	r2,r11,r8				;r2 = (*(mptr+M10) * cosa) + (*(mptr+M11) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M10) * cosa) + (*(mptr+M11) * sina)) >> W2V_SHIFT2
		sw		r2,M_10(r24)			;*(mptr+M10) = ((*(mptr+M10) * cosa) + (*(mptr+M11) * sina)) >> W2V_SHIFT2
		subu	r2,r9,r6				;r2 = (*(mptr+M11) * cosa) - (*(mptr+M10) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M11) * cosa) - (*(mptr+M10) * sina) >> W2V_SHIFT2
		sw		r2,M_11(r24)			;*(mptr+M11) = (*(mptr+M11) * cosa) - (*(mptr+M10) * sina) >> W2V_SHIFT2
		addu	r2,r7,r4				;r2 = (*(mptr+M20) * cosa) + (*(mptr+M21) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M20) * cosa) + (*(mptr+M21) * sina) >> W2V_SHIFT2
		sw		r2,M_20(r24)			;*(mptr+M20) = (*(mptr+M20) * cosa) + (*(mptr+M21) * sina) >> W2V_SHIFT2
		mflo	r2						;r2 = *(mptr+M20) * sina

		subu	r2,r5,r2				;r2 = (*(mptr+M21) * cosa) - (*(mptr+M20) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M21) * cosa) - (*(mptr+M20) * sina) >> W2V_SHIFT2
		sw		r2,M_21(r24)			;*(mptr+M21) = (*(mptr+M21) * cosa) - (*(mptr+M20) * sina) >> W2V_SHIFT2

.exitme
		j		r13 					;it`s all over... taste it!
		nop


; Do Successive Rotations In Order Y-X-Z
;
; phd_RotYXZpack_asm
;
; r4 = ry
; r5 = rx
; r6 = rz
;
; ok, this routine assumes that r13,r14,r15,r24 and r25 are NOT used by phd_sin_asm or phd_cos_asm.
;


phd_RotYXZ_asm
		subu	sp,sp,4
		sw		r31,0(sp)

		sll 	r13,r5,16				;r13 = rx<<16

		lw		r24,GPVAR_phd_mxptr(gp) ;fill the delay slot...

		sll 	r14,r4,16
		sra 	r14,r14,16				;r14 = ry

;r14 = ry
		beq 	r14,r0,.do_rotx 		;ang == 0?
		sll 	r25,r6,16				;r25 = rz<<16

		jal 	phd_sin_asm 			;sin angle me...
		move	r4,r14					;r4 = ang
		move	r15,r2					;r15 = sina
;r15 = sina
		jal 	phd_cos_asm
		move	r4,r14

		lw		r3,M_00(r24)			;r3 = *(mptr+M00)
		move	r14,r2					;r14 = cosa
;r14 = cosa

		mult	r14,r3					;*(mptr+M00) * cosa
		mflo	at						;at = *(mptr+M00) * cosa

		lw		r2,M_02(r24)			;r2 = *(mptr+M02)
		nop

		mult	r15,r2					;*(mptr+M02) * sina
		mflo	r5						;r5 = *(mptr+M02) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M02)*cosa
		mflo	r12 					;r12 = *(mptr+M02)*cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M00) * sina
		mflo	r10 					;r10 = *(mptr+M00) * sina

		lw		r3,M_10(r24)			;r3 = *(mptr+M10)
		nop

		mult	r14,r3					;*(mptr+M10) * cosa
		mflo	r11 					;r11 = *(mptr+M10) * cosa

		lw		r2,M_12(r24)			;r2 = *(mptr+M12)
		nop

		mult	r15,r2					;*(mptr+M12) * sina
		mflo	r8						;r8 = *(mptr+M12) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M12) * cosa
		mflo	r9						;r9 = *(mptr+M12) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M10) * sina
		mflo	r6						;r6 = *(mptr+M10) * sina

		lw		r3,M_20(r24)			;r3 = *(mptr+M20)
		nop

		mult	r14,r3					;*(mptr+M20) * cosa
		mflo	r7						;r7 = *(mptr+M20) * cosa

		lw		r2,M_22(r24)			;r2 = *(mptr+M22)
		nop

		mult	r15,r2					;*(mptr+M22) * sina
		mflo	r4						;r4 = *(mptr+M22) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M22) * cosa
		subu	r2,at,r5				;r2 = (*(mptr+M00) * cosa) - (*(mptr+M02) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M00) * cosa) - (*(mptr+M02) * sina) >> W2V_SHIFT2
		mflo	r5						;r5 = *(mptr+M22) * cosa

		sw		r2,M_00(r24)			;*(mptr+M00) = (*(mptr+M00) * cosa) - (*(mptr+M02) * sina) >> W2V_SHIFT2
		addu	r2,r12,r10				;r2 = ( *(mptr+M02)*cosa + *(mptr+M00) * sina )

		mult	r15,r3					;*(mptr+M20) * sina
		sra 	r2,r2,W2V_SHIFT2				;r2 = ( *(mptr+M02)*cosa + *(mptr+M00) * sina ) >> W2V_SHIFT2
		sw		r2,M_02(r24)			;*(mptr+M02) = ( *(mptr+M02)*cosa + *(mptr+M00) * sina ) >> W2V_SHIFT2
		subu	r2,r11,r8				;r2 = (*(mptr+M10) * cosa) - (*(mptr+M12) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M10) * cosa) - (*(mptr+M12) * sina)) >> W2V_SHIFT2
		sw		r2,M_10(r24)			;*(mptr+M10) = ((*(mptr+M10) * cosa) - (*(mptr+M12) * sina)) >> W2V_SHIFT2
		addu	r2,r9,r6				;r2 = (*(mptr+M12) * cosa) + (*(mptr+M10) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M12) * cosa) + (*(mptr+M10) * sina) >> W2V_SHIFT2
		sw		r2,M_12(r24)			;*(mptr+M12) = (*(mptr+M12) * cosa) + (*(mptr+M10) * sina) >> W2V_SHIFT2
		subu	r2,r7,r4				;r2 = (*(mptr+M20) * cosa) - (*(mptr+M22) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M20) * cosa) - (*(mptr+M22) * sina) >> W2V_SHIFT2
		sw		r2,M_20(r24)			;*(mptr+M20) = (*(mptr+M20) * cosa) - (*(mptr+M22) * sina) >> W2V_SHIFT2
		mflo	r2						;r2 = *(mptr+M20) * sina

		addu	r2,r5,r2				;r2 = (*(mptr+M22) * cosa) + (*(mptr+M20) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M22) * cosa) + (*(mptr+M20) * sina) >> W2V_SHIFT2
		sw		r2,M_22(r24)			;*(mptr+M22) = (*(mptr+M22) * cosa) + (*(mptr+M20) * sina) >> W2V_SHIFT2


.do_rotx
		sra 	r14,r13,16				;r14 = rx

		beq 	r14,r0,.do_rotz 		;ang == 0 ??
		nop

		jal 	phd_sin_asm 			;sin angle me...!
		move	r4,r14					;r4 = ang

		move	r15,r2					;r15 = sina
;r15 = sina
		jal 	phd_cos_asm 			;cos angle me...!
		move	r4,r14					;r4 = ang

		lw		r3,M_01(r24)			;r3 = *(mptr+M01)
		move	r14,r2					;r14 = cosa
;r14 = cosa
		mult	r14,r3					;*(mptr+M01) * cosa
		mflo	at						;at = *(mptr+M01) * cosa

		lw		r2,M_02(r24)			;r2 = *(mptr+M02)
		nop

		mult	r15,r2					;*(mptr+M02) * sina
		mflo	r5						;r5 = *(mptr+M02) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M02) * cosa
		mflo	r12 					;r12 = *(mptr+M02) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M01) * sina
		mflo	r10 					;r10 = *(mptr+M01) * sina

		lw		r3,M_11(r24)			;r3 = *(mptr+M11)
		nop

		mult	r14,r3					;*(mptr+M11) * cosa
		mflo	r11 					;r11 = *(mptr+M11) * cosa

		lw		r2,M_12(r24)			;r2 = *(mptr+M12)
		nop

		mult	r15,r2					;*(mptr+M12) * sina
		mflo	r8						;r8 = *(mptr+M12) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M12) * cosa
		mflo	r9						;r9 = *(mptr+M12) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M11) * sina
		mflo	r6						;r6 = *(mptr+M11) * sina

		lw		r3,M_21(r24)			;r3 = *(mptr+M21)
		nop

		mult	r14,r3					;*(mptr+M21) * cosa
		mflo	r7						;r7 = *(mptr+M21) * cosa

		lw		r2,M_22(r24)			;r2 = *(mptr+M22)
		nop

		mult	r15,r2					;*(mptr+M22) * sina
		mflo	r4						;r4 = *(mptr+M22) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M22) * cosa
		addu	r2,at,r5				;r2 = (*(mptr+M01) * cosa) + (*(mptr+M02) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M01) * cosa) + (*(mptr+M02) * sina) >> W2V_SHIFT2
		mflo	r5						;r5 = *(mptr+M22) * cosa

		sw		r2,M_01(r24)			;*(mptr+M01) = (*(mptr+M01) * cosa) + (*(mptr+M02) * sina) >> W2V_SHIFT2
		subu	r2,r12,r10				;r2 = (*(mptr+M02) * cosa) - (*(mptr+M01) * sina)

		mult	r15,r3					;*(mptr+M21) * sina
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M02) * cosa) - (*(mptr+M01) * sina) >> W2V_SHIFT2
		sw		r2,M_02(r24)			;*(mptr+M02) = (*(mptr+M02) * cosa) - (*(mptr+M01) * sina) >> W2V_SHIFT2
		addu	r2,r11,r8				;r2 = (*(mptr+M11) * cosa)+(*(mptr+M12) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M11) * cosa)+(*(mptr+M12) * sina) >> W2V_SHIFT2
		sw		r2,M_11(r24)			;*(mptr+M11) = (*(mptr+M11) * cosa)+(*(mptr+M12) * sina) >> W2V_SHIFT2
		subu	r2,r9,r6				;r2 = (*(mptr+M12) * cosa) - (*(mptr+M11) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M12) * cosa) - (*(mptr+M11) * sina) >> W2V_SHIFT2
		sw		r2,M_12(r24)			;*(mptr+M12) = (*(mptr+M12) * cosa) - (*(mptr+M11) * sina) >> W2V_SHIFT2
		addu	r2,r7,r4				;r2 = (*(mptr+M21) * cosa) + (*(mptr+M22) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M21) * cosa) + (*(mptr+M22) * sina) >> W2V_SHIFT2
		sw		r2,M_21(r24)			;*(mptr+M21) = (*(mptr+M21) * cosa) + (*(mptr+M22) * sina) >> W2V_SHIFT2
		mflo	r2						;r2 = *(mptr+M21) * sina

		subu	r2,r5,r2				;r2 = (*(mptr+M22) * cosa) - (*(mptr+M21) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M22) * cosa) - (*(mptr+M21) * sina)) >> W2V_SHIFT2
		sw		r2,M_22(r24)			;*(mptr+M22) = ((*(mptr+M22) * cosa) - (*(mptr+M21) * sina)) >> W2V_SHIFT2


.do_rotz
		sra 	r14,r25,16				;r14 = rz

		beq 	r14,r0,.exitme			;ang == 0 ??
		nop

		jal 	phd_sin_asm 			;sinme
		move	r4,r14					;r4 = ang

		move	r15,r2
;r15 = sina

		jal 	phd_cos_asm 			;cosme
		move	r4,r14					;r4 = ang

		lw		r3,M_00(r24)			;r3 = *(mptr+M00)
		move	r14,r2
;r14 = cosa
		mult	r14,r3					;*(mptr+M00) * cosa
		mflo	at						;at = *(mptr+M00) * cosa

		lw		r2,M_01(r24)			;r2 = *(mptr+M01)
		nop

		mult	r15,r2					;*(mptr+M01) * sina
		mflo	r5						;r5 = *(mptr+M01) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M01) * cosa
		mflo	r12 					;r12 = *(mptr+M01) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M00) * sina
		mflo	r10 					;r10 = *(mptr+M00) * sina

		lw		r3,M_10(r24)			;r3 = *(mptr+M10)
		nop

		mult	r14,r3					;*(mptr+M10) * cosa
		mflo	r11 					;r11 = *(mptr+M10) * cosa

		lw		r2,M_11(r24)			;r2 = *(mptr+M11)
		nop

		mult	r15,r2					;*(mptr+M11) * sina
		mflo	r8						;r8 = *(mptr+M11) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M11) * cosa
		mflo	r9						;r9 = *(mptr+M11) * cosa

		nop
		nop

		mult	r15,r3					;*(mptr+M10) * sina
		mflo	r6						;r6 = *(mptr+M10) * sina

		lw		r3,M_20(r24)			;r3 = *(mptr+M20)
		nop

		mult	r14,r3					;*(mptr+M20) * cosa
		mflo	r7						;r7 = *(mptr+M20) * cosa

		lw		r2,M_21(r24)			;r2 = *(mptr+M21)
		nop

		mult	r15,r2					;*(mptr+M21) * sina
		mflo	r4						;r4 = *(mptr+M21) * sina

		nop
		nop

		mult	r14,r2					;*(mptr+M21) * cosa
		addu	r2,at,r5				;r2 = (*(mptr+M00) * cosa) + (*(mptr+M01) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M00) * cosa) + (*(mptr+M01) * sina) >> W2V_SHIFT2
		mflo	r5						;r5 = *(mptr+M21) * cosa

		sw		r2,M_00(r24)			;*(mptr+M00) = (*(mptr+M00) * cosa) + (*(mptr+M01) * sina) >> W2V_SHIFT2
		subu	r2,r12,r10				;r2 = (*(mptr+M01) * cosa) - (*(mptr+M00) * sina)

		mult	r15,r3					;*(mptr+M20) * sina
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M01) * cosa) - (*(mptr+M00) * sina)) >> W2V_SHIFT2
		sw		r2,M_01(r24)			;*(mptr+M01) = ((*(mptr+M01) * cosa) - (*(mptr+M00) * sina)) >> W2V_SHIFT2
		addu	r2,r11,r8				;r2 = (*(mptr+M10) * cosa) + (*(mptr+M11) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = ((*(mptr+M10) * cosa) + (*(mptr+M11) * sina)) >> W2V_SHIFT2
		sw		r2,M_10(r24)			;*(mptr+M10) = ((*(mptr+M10) * cosa) + (*(mptr+M11) * sina)) >> W2V_SHIFT2
		subu	r2,r9,r6				;r2 = (*(mptr+M11) * cosa) - (*(mptr+M10) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M11) * cosa) - (*(mptr+M10) * sina) >> W2V_SHIFT2
		sw		r2,M_11(r24)			;*(mptr+M11) = (*(mptr+M11) * cosa) - (*(mptr+M10) * sina) >> W2V_SHIFT2
		addu	r2,r7,r4				;r2 = (*(mptr+M20) * cosa) + (*(mptr+M21) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M20) * cosa) + (*(mptr+M21) * sina) >> W2V_SHIFT2
		sw		r2,M_20(r24)			;*(mptr+M20) = (*(mptr+M20) * cosa) + (*(mptr+M21) * sina) >> W2V_SHIFT2
		mflo	r2						;r2 = *(mptr+M20) * sina

		subu	r2,r5,r2				;r2 = (*(mptr+M21) * cosa) - (*(mptr+M20) * sina)
		sra 	r2,r2,W2V_SHIFT2				;r2 = (*(mptr+M21) * cosa) - (*(mptr+M20) * sina) >> W2V_SHIFT2
		sw		r2,M_21(r24)			;*(mptr+M21) = (*(mptr+M21) * cosa) - (*(mptr+M20) * sina) >> W2V_SHIFT2

.exitme
		lw		r31,0(sp)
		addu	sp,sp,4
		j		r31 					;it`s all over... taste it!
		nop




;ok, lets sweeten it...
;
;
; r4 = x
; r5 = y
; r6 = z
;
;
; added GP ref`ed vars
; added equates
; removed a few useless loads...
; twatted the zeroexit stuff
;
;

DPQ_END 		equ (20*1024)
phd_viewdist	equ DPQ_END
phd_zfar		equ (phd_viewdist<<W2V_SHIFT2)

phd_TranslateRel_asm
		lw		r7,GPVAR_phd_mxptr(gp)					;r7 = mptr
		nop
		lw		r2,M_00(r7) 							;r2 = *(mptr+M00)
		move	r8,r4									;r8 = x
		mult	r2,r8									;x * *(mptr+M00)
		lw		r2,M_01(r7) 							;r2 = *(mptr+M01)
		mflo	r11 									;r11 = ( x * *(mptr+M00) )

		nop
		nop

		mult	r2,r5									;y * *(mptr+M01)
		lw		r2,M_02(r7) 							;r2 = *(mptr+M02)
		mflo	r24 									;r24 = ( y * *(mptr+M01) )

		nop
		nop

		mult	r2,r6									;z* *(mptr+M02)
		lw		r2,M_10(r7) 							;r2 = *(mptr+M10)
		mflo	r9

		nop
		nop

		mult	r2,r8									;x*
		lw		r2,M_11(r7) 							;r2 = *(mptr+M11)
		mflo	r14

		nop
		nop

		mult	r2,r5									;y*
		lw		r2,M_12(r7) 							;r2 = *(mptr+M12)
		mflo	r12

		nop
		nop

		mult	r2,r6									;z*
		lw		r2,M_20(r7) 							;r2 = *(mptr+M20)
		mflo	r10

		nop
		nop

		mult	r2,r8									;x*
		lw		r2,M_21(r7) 							;r2 = *(mptr+M21)
		mflo	r13

		nop
		nop

		mult	r2,r5									;y*
		lw		r4,M_22(r7) 							;r4 = *(mptr+M22)
		mflo	r5

		lw		r3,M_03(r7) 							;r3 = *(mptr+M03)
		addu	r2,r11,r24

		mult	r4,r6									;z*
		addu	r2,r2,r9
		addu	r8,r3,r2
;r8 = mptr+M03
		lw		r3,M_13(r7) 							;r3 = *(mptr+M13)
		lw		r4,M_23(r7) 							;r4 = *(mptr+M23)

		addu	r2,r14,r12
		addu	r2,r2,r10
		addu	r3,r3,r2

		sw		r8,M_03(r7) 							;stash mptr+M03
		sw		r3,M_13(r7) 							;stash *(mptr+M13)
		addu	r2,r13,r5
		mflo	r11

		addu	r2,r2,r11
		addu	r6,r4,r2

		bgez	r8,.one
		sw		r6,M_23(r7) 							;stash *(mptr+M23)

		subu	r8,r0,r8
.one
		li		r3,phd_zfar
		slt 	r2,r3,r8
		bne 	r2,r0,.zeroexit
		move	r2,r0					;nop

		lw		r5,M_13(r7) 							;r5 = *(mptr+M13)
		nop

		bgez	r5,.two
		slt 	r2,r3,r5

		subu	r5,r0,r5
		slt 	r2,r3,r5
.two
		bne 	r2,r0,.zeroexit
		move	r2,r0					;nop

		bgez	r6,.three
		slt 	r2,r3,r6

		subu	r6,r0,r6
		slt 	r2,r3,r6
.three
		beq 	r2,r0,.exit
		li		r2,1

		move	r2,r0

.zeroexit
.exit
		j		r31
		nop





; phd_PushMatrix_asm
;
; hmm... not alot I could do to this one, except use (GP) where the compiler forgot... :(
;
; uses r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15
;

phd_PushMatrix_asm
		lw		r2,GPVAR_phd_mxptr(gp)			;r2 = p1
		nop

		lw		r3,M_00(r2)
		lw		r4,M_01(r2)
		lw		r5,M_02(r2)
		lw		r6,M_03(r2)

		lw		r7,M_10(r2)
		lw		r8,M_11(r2)
		lw		r9,M_12(r2)
		lw		r10,M_13(r2)

		lw		r11,M_20(r2)
		lw		r12,M_21(r2)
		lw		r13,M_22(r2)
		lw		r14,M_23(r2)

		addu	r15,r2,48						;r15 = p2

		sw		r3,M_00(r15)
		sw		r4,M_01(r15)
		sw		r5,M_02(r15)
		sw		r6,M_03(r15)

		sw		r7,M_10(r15)
		sw		r8,M_11(r15)
		sw		r9,M_12(r15)
		sw		r10,M_13(r15)

		sw		r11,M_20(r15)
		sw		r12,M_21(r15)
		sw		r13,M_22(r15)
		sw		r14,M_23(r15)

		j		r31
		sw		r15,GPVAR_phd_mxptr(gp) 		;phd_mxptr+=12 (fill delay slot...)


;Translate Matrix to Absolute Position
;
;phd_TranslateAbs_asm
;
; r4=x
; r5=y
; r6=z
;
;
;
; unused r14,r15,r24,r25
;


phd_TranslateAbs_asm
		lw		r3,GPVAR_phd_mxptr(gp)			;r3 = mptr
		mac.la	at,w2v_matrix					;at = w2v_matrix

		lw		r2,M_03(at) 					;r2 = *(w2v_matrix+M_03)
		lw		r7,M_00(r3) 					;r7 = *(mptr+M00)
		subu	r4,r4,r2						;r4 = x - *(w2v_matrix+M_03)

		mult	r7,r4							;*(mptr+M00) * (x - *(w2v_matrix+M_03))
		lw		r2,M_13(at) 					;r2 = *(w2v_matrix+M_13)
		lw		r7,M_01(r3) 					;r7 = *(mptr+M01)
		mflo	r13 							;r13 = *(mptr+M00) * (x - *(w2v_matrix+M_03))

		subu	r5,r5,r2						;r5 = y - *(w2v_matrix+M_13)
		nop

		mult	r7,r5							;*(mptr+M01) * (y - *(w2v_matrix+M_13))
		lw		r2,M_23(at) 					;r2 = *(w2v_matrix+M_23)
		lw		r7,M_02(r3) 					;r7 = *(mptr+M02)
		mflo	r12 							;r12 = *(mptr+M01) * (y - *(w2v_matrix+M_13))

		subu	r6,r6,r2						;r6 = z - *(w2v_matrix+M_23)
		nop

		mult	r7,r6							;*(mptr+M02) * (z - *(w2v_matrix+M_23))
		lw		r2,M_10(r3) 					;r2 = *(mptr+M10)
		mflo	r10 							;r10 = *(mptr+M02) * (z - *(w2v_matrix+M_23))

		addu	r12,r12,r13
		addu	r12,r12,r10

		mult	r2,r4							;*(mptr+M10) * (x - *(w2v_matrix+M_03))
		lw		r2,M_11(r3) 					;r2 = *(mptr+M_11)
		mflo	r11 							;r11 = *(mptr+M10) * (x - *(w2v_matrix+M_03))

		nop
		nop

		mult	r2,r5							;*(mptr+M_11) * (y - *(w2v_matrix+M_13))
		lw		r2,M_12(r3) 					;r2 = *(mptr+M_12)
		mflo	r9								;r9 = *(mptr+M_11) * (y - *(w2v_matrix+M_13))

		nop
		nop

		mult	r2,r6							;*(mptr+M_12) * (z - *(w2v_matrix+M_23))
		lw		r2,M_20(r3) 					;r2 = *(mptr+M_20)
		mflo	r7								;r7 = *(mptr+M_12) * (z - *(w2v_matrix+M_23))

		addu	r11,r11,r9						;
		addu	r11,r11,r7						;

		mult	r2,r4							;*(mptr+M_20) * (x - *(w2v_matrix+M_03))
		lw		r2,M_21(r3) 					;r2 = *(mptr+M_21)
		mflo	r8								;r8 = *(mptr+M_20) * (x - *(w2v_matrix+M_03))

		nop
		nop

		mult	r2,r5							;*(mptr+M_21) * (y - *(w2v_matrix+M_13))
		lw		r2,M_22(r3) 					;r2 = *(mptr+M_22)
		mflo	r4								;r4 = *(mptr+M_21) * (y - *(w2v_matrix+M_13))

		addu	r8,r8,r4						;
		nop

		mult	r2,r6							;*(mptr+M_22) * (z - *(w2v_matrix+M_23))
		sw		r12,M_03(r3)					;*(mptr+M_03) =
		sw		r11,M_13(r3)					;*(mptr+M_13) =
		mflo	r4								;r4 = *(mptr+M_22) * (z - *(w2v_matrix+M_23))

		addu	r8,r8,r4

		j		r31 							;exit...
		sw		r8,M_23(r3) 					;*(mptr+M_23) = 				(fill delay slot...)

