	     .width    132
;-------------------------------------------------------------------------;
;				   TIGA 				  ;
;        Copyright (c) 1989-1990  Texas Instruments Incorporated.         ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager Extension					  ;
;-------------------------------------------------------------------------;
; trig_values function							  ;
;									  ;
;     Given an angle in integer degrees, calculate the sine and cosine	  ;
;     as 32-bit fixed point values with 16-bit fractions.		  ;
;-------------------------------------------------------------------------;
; Usage:  trig_values(angle, sincos)					  ;
;									  ;
; Stack parameters:							  ;
;	  typedef struct { long sin, cos; } TRIGVALS;			  ;
;	  int angle;	    /* angle in integer degrees */		  ;
;	  TRIGVALS sincos;  /* pointer to fixed-pt sine and cosine */	  ;
;									  ;
; Registers altered:  none						  ;
;									  ;
; Value returned in A8:  void (undefined)				  ;
;-------------------------------------------------------------------------;
; Revision History:							  ;
;   08/10/89...Original version written...................Jerry Van Aken  ;
;-------------------------------------------------------------------------;
;
	.title	  'trig values'
	.file	  'trigvals.asm'
;
;
	.global   _trig_values	      ;global function name
;
;
;   DECLARE EXTERNAL VARIABLES
;
        .global   _sin_tbl            ;sine lookup table for 0...90 degrees
;
;
;   DEFINE CONSTANTS
;
; Define symbolic A-file register names.
ANGLE	.set	  A8		      ;angle in integer degrees
SINE	.set	  A8		      ;sine of angle
COSINE	.set	  A0		      ;cosine of angle
ATMP	.set	  A0		      ;temporary register
TRIGVAL .set	  A14		      ;pointer to structure
;
;
;   ENTRY POINT
;
_trig_values:

	SETF	  16,0,0	      ;set up for unsigned word moves
	MOVE	  A0,-*SP,1	      ;save register
;
; Pop arguments off stack.
	MOVE	  -*A14,ANGLE,1       ;get argument angle
	MOVE	  -*A14,TRIGVAL,1     ;get argument trigval
	CALLR	  TRIGFUN	      ;call local function
	MOVE	  SINE,*TRIGVAL+,1    ;store sin(angle)
	MOVE	  COSINE,*TRIGVAL+,1  ;store cos(angle)
;
; Restore registers and return.
	MOVE	  *SP+,A0,1	      ;restore register
	MOVE	  *SP(32),A14,1       ;restore program stack pointer
	RETS	  2		      ;


*------------------------------------------------------------------------
*
*  Local function fetches sine and cosine from lookup table.
*
*------------------------------------------------------------------------

TRIGFUN:
	MOVE	  ANGLE,ATMP	      ;copy angle (in integer degrees)
	ABS	  ATMP		      ;|angle|
	CMPI	  360,ATMP	      ;is |angle| >= 360 degrees ?
        JRN       LT360               ;jump if |angle| < 360 degrees
	MOVI	  360,ATMP	      ;else angle %= 360 degrees
	MODS	  ATMP,ANGLE	      ;
LT360:
	SLL	  4,ANGLE	      ;convert angle to table offset
	JRNC	  POSANGLE	      ;jump if angle >= 0
	ADDI	  (360<<4),ANGLE      ;else make angle positive
POSANGLE:
;
; Now angle is in the range 0 to 359 degrees.  Is angle < 180 degrees?
        CMPI      (180<<4),ANGLE      ;is angle < 180 degrees ?
        JRNN      GE180               ;jump if angle >= 180 degrees
;
; Is angle < 90 degrees?
        CMPI      (90<<4),ANGLE       ;is angle < 90 degrees ?
        JRNN      GE90                ;jump if angle >= 90 degrees
;
; 0 <= angle < 90 degrees.  Get sine and cosine as 16-bit fractions.
; Set cos(angle) = sin_tbl[90 - angle], and sin(angle) = sin_tbl[angle].
	MOVI	  _sin_tbl+(90<<4),ATMP ;
	SUB	  ANGLE,ATMP	      ;
	MOVE	  *ATMP,COSINE,0      ;cos(angle) = sin_tbl[90 - angle]
        ADDI      _sin_tbl,ANGLE      ;
        MOVE      *ANGLE,SINE,0       ;sin(angle) = sin_tbl[angle]
        RETS      0                   ;
;
; 90 <= angle < 180 degrees.  Get sine and cosine as 16-bit fractions.
; Set cos(angle) = -sin_tbl[angle-90], sin(angle) = sin_tbl[180-angle].
GE90:
	MOVI	  _sin_tbl-(90<<4),ATMP ;
	ADD	  ANGLE,ATMP	      ;
	MOVE	  *ATMP,COSINE,0      ;
        NEG       COSINE              ;cos(angle) = -sin_tbl[angle - 90]
        NEG       ANGLE               ;
        ADDI      _sin_tbl+(180<<4),ANGLE ;
        MOVE      *ANGLE,SINE,0       ;sin(angle) = sin_tbl[180 - angle]
        RETS      0                   ;
;
; We have 180 <= angle < 360 degrees.  Is angle < 270?
GE180:
        CMPI      (270<<4),ANGLE      ;is angle < 270?
	JRNN	  GE270 	      ;jump if angle >= 270
;
; 180 <= angle < 270 degrees.  Get sine and cosine as 16-bit fractions.
; Set cos(angle) = -sin_tbl[270-angle], sin(angle) = -sin_tbl[angle-180].
	MOVI	  _sin_tbl+(270<<4),ATMP ;
	SUB	  ANGLE,ATMP	      ;
	MOVE	  *ATMP,COSINE,0      ;
        NEG       COSINE              ;cos(angle) = -sin_tbl[270 - angle]
        ADDI      _sin_tbl-(180<<4),ANGLE ;
        MOVE      *ANGLE,SINE,0       ;
        NEG       SINE                ;sin(angle) = -sin_tbl[angle - 180]
        RETS      0                   ;
;
; 270 <= angle < 360 degrees.  Get sine and cosine as 16-bit fractions.
; Set cos(angle) = sin_tbl[angle-270], sin(angle) = -sin_tbl[360-angle].
GE270:
	MOVI	  _sin_tbl-(270<<4),ATMP ;
	ADD	  ANGLE,ATMP	      ;
	MOVE	  *ATMP,COSINE,0      ;cos(angle) = sin_tbl[angle - 270]
        NEG       ANGLE               ;
        ADDI      _sin_tbl+(360<<4),ANGLE ;
        MOVE      *ANGLE,SINE,0       ;
        NEG       SINE                ;sin(angle) = -sin_tbl[360 - angle]
        RETS      0                   ;
	.end

