;*======================================================================* ;* TITLE: TURTLE.GAS * ;* Function: Turtle Geometry Rotation and Translation * ;* * ;* Project #: RAPIER * ;* Programmer: Rob Zdybel * ;* * ;* COPYRIGHT 1993 Atari Computer Corporation * ;* UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION, * ;* PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR * ;* THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED. * ;* ALL RIGHTS RESERVED. * ;* * ;*======================================================================* ; ; DATA ORGANIZATION ; ; ; +-------------------+ +---------------+ ; | Xrite | Yrite |<---| PTR to ARG1 | INPUT1 ; +-------------------+ +---------------+ ; | Zrite | Xdown | ; +-------------------+ Turtle Record ; | Ydown | Zdown | ; +-------------------+ ; | Xhead | Yhead | ; +-------------------+ ; | Zhead | Xposn | ; +-------------------+ ; | Yposn | Zposn | ; +-------------------+ ; ... ; +-------------------+ ; | Pitch (Brads) | INPUT2 (16-bits) ; +-------------------+ ; | Yaw (Brads) | INPUT3 (16-bits) ; +-------------------+ ; | Roll (Brads) | INPUT4 (16-bits) ; +-------------------+ ; | Velocity | INPUT5 (16-bits) ; +-------------------+ ; XDEF turtpak ; ; COMMON EQUATES ; DEBUG_ON EQU 0 PTRSIZE EQU (1*4) ; 1 LONG INPUT6 EQU G_ENDRAM-PTRSIZE INPUT5 EQU INPUT6-PTRSIZE INPUT4 EQU INPUT5-PTRSIZE INPUT3 EQU INPUT4-PTRSIZE INPUT2 EQU INPUT3-PTRSIZE INPUT1 EQU INPUT2-PTRSIZE NOLIST include "jaguar.inc" include "blit.inc" include "gpu.inc" include "macros.inc" .gpu LIST ALIGN PHRASE ORG G_RAM ; ; GLOBAL REGISTER EQUATES ; temp REGEQU r0 temp2 REGEQU r1 ptr REGEQU r2 pitch REGEQU r3 yaw REGEQU r4 roll REGEQU r5 velocity REGEQU r6 half REGEQU r7 xrite REGEQU r10 yrite REGEQU r11 zrite REGEQU r12 xdown REGEQU r13 ydown REGEQU r14 zdown REGEQU r15 xhead REGEQU r16 yhead REGEQU r17 zhead REGEQU r18 xposn REGEQU r19 yposn REGEQU r20 zposn REGEQU r21 sin REGEQU r22 cos REGEQU r23 rpi2 REGEQU r24 rsintbl REGEQU r25 rcos REGEQU r26 rsin REGEQU r27 return REGEQU r28 ; ; LOCAL MACROS ; ; NOTE: Dedicated Subroutine calls expect the proper ; registers to be pre-set. No Nesting! MACRO JSR_SIN move PC,return jump (rsin) addq #6,return ; Determine Return Address ENDM MACRO JSR_COS move PC,return jump (rcos) addq #6,return ; Determine Return Address ENDM MACRO SIN_RTS jump (return) ENDM ; ; CODE SEGMENT ; ; ; System Initialization ; DEBUG_INIT turtpak: moveq #1,half movei #sine,rsin shlq #13,half ; Half of One ($2000) movei #cosine,rcos moveq #4,rpi2 movei #sintbl,rsintbl shlq #4,rpi2 ; RPI2 = Pi/2 ($40 in Brads) movei #INPUT1,ptr load (ptr),temp ; TEMP = 68000 ptr to active Turtle addq #4,ptr load (ptr),pitch ; PITCH = Amount to Pitch the Turtle addq #4,ptr load (ptr),yaw ; YAW = Amount to Yaw the Turtle addq #4,ptr load (ptr),roll ; ROLL = Amount to Roll the Turtle addq #4,ptr load (ptr),velocity ; VELOCITY = Amount to Move the Turtle shlq #16,velocity sharq #16,velocity ; Sign-extend Velocity loadw (temp),xrite ; Fetch Turtle into registers addq #2,temp loadw (temp),yrite addq #2,temp shlq #16,xrite shlq #16,yrite sharq #16,xrite ; And sign-extend to 32-bits sharq #16,yrite loadw (temp),zrite addq #2,temp loadw (temp),xdown addq #2,temp shlq #16,zrite shlq #16,xdown sharq #16,zrite sharq #16,xdown loadw (temp),ydown addq #2,temp loadw (temp),zdown addq #2,temp shlq #16,ydown shlq #16,zdown sharq #16,ydown sharq #16,zdown loadw (temp),xhead addq #2,temp loadw (temp),yhead addq #2,temp shlq #16,xhead shlq #16,yhead sharq #16,xhead sharq #16,yhead loadw (temp),zhead addq #2,temp loadw (temp),xposn addq #2,temp shlq #16,zhead shlq #16,xposn sharq #16,zhead sharq #16,xposn loadw (temp),yposn addq #2,temp loadw (temp),zposn shlq #16,yposn shlq #16,zposn sharq #16,yposn sharq #16,zposn ; ; PITCH (Rotation about the X-Axis) ; cmpq #0,pitch jr NE,ipitch nop movei #iyaw,temp jump (temp) nop ipitch: ; IF (Pitch <> 0) THEN Pitch the Turtle move pitch,temp JSR_SIN move temp,sin ; SIN = SINE(Pitch) move pitch,temp JSR_COS move temp,cos ; COS = COSINE(Pitch) move sin,temp2 imult xdown,temp ; TEMP = xdown*cos(a) imult xhead,temp2 sub temp2,temp ; TEMP = xdown*cos(a) - xhead*sin(a) move sin,temp2 add half,temp sharq #14,temp imult xdown,temp2 ; TEMP2 = xdown*sin(a) move temp,xdown ; XDOWN = xdown*cos(a) - xhead*sin(a) move cos,temp imult xhead,temp add temp2,temp ; TEMP = xhead*cos(a) + xdown*sin(a) add half,temp sharq #14,temp move temp,xhead ; XHEAD = xhead*cos(a) + xdown*sin(a) move cos,temp move sin,temp2 imult ydown,temp ; TEMP = ydown*cos(a) imult yhead,temp2 sub temp2,temp ; TEMP = ydown*cos(a) - yhead*sin(a) move sin,temp2 add half,temp sharq #14,temp imult ydown,temp2 ; TEMP2 = ydown*sin(a) move temp,ydown ; YDOWN = ydown*cos(a) - yhead*sin(a) move cos,temp imult yhead,temp add temp2,temp ; TEMP = yhead*cos(a) + ydown*sin(a) add half,temp sharq #14,temp move temp,yhead ; YHEAD = yhead*cos(a) + ydown*sin(a) move cos,temp move sin,temp2 imult zdown,temp ; TEMP = zdown*cos(a) imult zhead,temp2 sub temp2,temp ; TEMP = zdown*cos(a) - zhead*sin(a) move sin,temp2 add half,temp sharq #14,temp imult zdown,temp2 ; TEMP2 = zdown*sin(a) move temp,zdown ; ZDOWN = zdown*cos(a) - zhead*sin(a) move cos,temp imult zhead,temp add temp2,temp ; TEMP = zhead*cos(a) + zdown*sin(a) add half,temp sharq #14,temp move temp,zhead ; ZHEAD = zhead*cos(a) + zdown*sin(a) ; ; YAW (Rotation about the Y-Axis) ; iyaw: cmpq #0,yaw jr NE,10$ nop movei #iroll,temp jump (temp) nop 10$: ; IF (Yaw <> 0) THEN Yaw the Turtle move yaw,temp JSR_SIN move temp,sin ; SIN = SINE(Yaw) move yaw,temp JSR_COS move temp,cos ; COS = COSINE(Yaw) move sin,temp2 imult xhead,temp ; TEMP = xhead*cos(a) imult xrite,temp2 sub temp2,temp ; TEMP = xhead*cos(a) - xrite*sin(a) move sin,temp2 add half,temp sharq #14,temp imult xhead,temp2 ; TEMP2 = xhead*sin(a) move temp,xhead ; XHEAD = xhead*cos(a) - xrite*sin(a) move cos,temp imult xrite,temp add temp2,temp ; TEMP = xrite*cos(a) + xhead*sin(a) add half,temp sharq #14,temp move temp,xrite ; XRITE = xrite*cos(a) + xhead*sin(a) move cos,temp move sin,temp2 imult yhead,temp ; TEMP = yhead*cos(a) imult yrite,temp2 sub temp2,temp ; TEMP = yhead*cos(a) - yrite*sin(a) move sin,temp2 add half,temp sharq #14,temp imult yhead,temp2 ; TEMP2 = yhead*sin(a) move temp,yhead ; YHEAD = yhead*cos(a) - yrite*sin(a) move cos,temp imult yrite,temp add temp2,temp ; TEMP = yrite*cos(a) + yhead*sin(a) add half,temp sharq #14,temp move temp,yrite ; YRITE = yrite*cos(a) + yhead*sin(a) move cos,temp move sin,temp2 imult zhead,temp ; TEMP = zhead*cos(a) imult zrite,temp2 sub temp2,temp ; TEMP = zhead*cos(a) - zrite*sin(a) move sin,temp2 add half,temp sharq #14,temp imult zhead,temp2 ; TEMP2 = zhead*sin(a) move temp,zhead ; ZHEAD = zhead*cos(a) - zrite*sin(a) move cos,temp imult zrite,temp add temp2,temp ; TEMP = zrite*cos(a) + zhead*sin(a) add half,temp sharq #14,temp move temp,zrite ; ZRITE = zrite*cos(a) + zhead*sin(a) ; ; ROLL (Rotation about the Z-Axis) ; iroll: cmpq #0,roll jr NE,10$ nop movei #imove,temp jump (temp) nop 10$: ; IF (Roll <> 0) THEN Roll the Turtle move roll,temp JSR_SIN move temp,sin ; SIN = SINE(Roll) move roll,temp JSR_COS move temp,cos ; COS = COSINE(Roll) move sin,temp2 imult xrite,temp ; TEMP = xrite*cos(a) imult xdown,temp2 sub temp2,temp ; TEMP = xrite*cos(a) - xdown*sin(a) move sin,temp2 add half,temp sharq #14,temp imult xrite,temp2 ; TEMP2 = xrite*sin(a) move temp,xrite ; XRITE = xrite*cos(a) - xdown*sin(a) move cos,temp imult xdown,temp add temp2,temp ; TEMP = xdown*cos(a) + xrite*sin(a) add half,temp sharq #14,temp move temp,xdown ; XDOWN = xdown*cos(a) + xrite*sin(a) move cos,temp move sin,temp2 imult yrite,temp ; TEMP = yrite*cos(a) imult ydown,temp2 sub temp2,temp ; TEMP = yrite*cos(a) - ydown*sin(a) move sin,temp2 add half,temp sharq #14,temp imult yrite,temp2 ; TEMP2 = yrite*sin(a) move temp,yrite ; YRITE = yrite*cos(a) - ydown*sin(a) move cos,temp imult ydown,temp add temp2,temp ; TEMP = ydown*cos(a) + yrite*sin(a) add half,temp sharq #14,temp move temp,ydown ; YDOWN = ydown*cos(a) + yrite*sin(a) move cos,temp move sin,temp2 imult zrite,temp ; TEMP = zrite*cos(a) imult zdown,temp2 sub temp2,temp ; TEMP = zrite*cos(a) - zdown*sin(a) move sin,temp2 add half,temp sharq #14,temp imult zrite,temp2 ; TEMP2 = zrite*sin(a) move temp,zrite ; ZRITE = zrite*cos(a) - zdown*sin(a) move cos,temp imult zdown,temp add temp2,temp ; TEMP = zdown*cos(a) + zrite*sin(a) add half,temp sharq #14,temp move temp,zdown ; ZDOWN = zdown*cos(a) + zrite*sin(a) ; ; MOVE (Translation along the HEAD vector) ; imove: cmpq #0,velocity move velocity,temp jr EQ,idone move velocity,temp2 ; IF (Velocity <> 0) THEN Move the Turtle imult xhead,temp imult yhead,temp2 add half,temp add half,temp2 sharq #14,temp sharq #14,temp2 add temp,xposn ; Xpos = Xpos + Vel*Xhead add temp2,yposn ; Ypos = Ypos + Vel*Yhead imult zhead,velocity add half,velocity sharq #14,velocity add velocity,zposn ; Zpos = Zpos + Vel*Zhead ; ; Write Final Rotated and Translated Turtle Record ; idone: movei #INPUT1,ptr load (ptr),temp ; TEMP = 68000 ptr to active Turtle storew xrite,(temp) addq #2,temp storew yrite,(temp) ; Write back turtle addq #2,temp storew zrite,(temp) addq #2,temp storew xdown,(temp) addq #2,temp storew ydown,(temp) addq #2,temp storew zdown,(temp) addq #2,temp storew xhead,(temp) addq #2,temp storew yhead,(temp) addq #2,temp storew zhead,(temp) addq #2,temp storew xposn,(temp) addq #2,temp cmpq #0,yposn ; don't let it go below zero jr MI,sky ; DLF nop moveq #0,yposn sky: storew yposn,(temp) addq #2,temp storew zposn,(temp) ; ; Prepare for GPU RTS ; gpuend: movei #G_CTRL,temp2 ; GPU control/status register load (temp2),temp bclr 0,temp ; clear GPUGO bit store temp,(temp2) ; stop the GPU endloop: jr endloop ; infinite loop nop ; ; SUBROUTINE AREA ; ; ; COSINE 16-bit table lookup Cosine ; ; GIVEN: ; TEMP = Angle (Binary Radians 0..255) ; RPI2 = PI/2 ($40 in Brads) ; RSINTBL = Ptr to Sine Table ; ; RETURNS: ; TEMP = Cos(Angle)*$4000 ; ; REGISTER USAGE: ; ptr, temp, temp2 ; cosine: add rpi2,temp ; Cos(a) = Sin(a + pi/2) ; ; *CAUTION* Fall Thru to SINE Subroutine *CAUTION* ; ; ; SINE 16-bit table lookup Sine ; ; GIVEN: ; TEMP = Angle (Binary Radians 0..255) ; RPI2 = PI/2 ($40 in Brads) ; RSINTBL = Ptr to Sine Table ; ; RETURNS: ; TEMP = Sin(Angle)*$4000 ; ; REGISTER USAGE: ; ptr, temp, temp2 ; sine: shlq #24,temp ; Strip any extraneous bits move rsintbl,ptr jr MI,69$ shrq #24,temp ; IF (Angle < Pi) THEN cmp temp,rpi2 jr PL,49$ ; IF (Angle > Pi/2) THEN Reduce it move rpi2,temp2 shlq #1,temp2 ; TEMP2 = Pi ($80 in Brads) sub temp,temp2 ; Sin(pi/2 + a) = Sin(pi/2 -a) move temp2,temp 49$: shlq #2,temp add temp,ptr SIN_RTS load (ptr),temp ; TEMP = Table Lookup Result 69$: ; ELSE (Angle >= Pi) bclr #7,temp ; TEMP = TEMP - $80 cmp temp,rpi2 jr PL,99$ ; IF (Angle > Pi/2) THEN Reduce it move rpi2,temp2 shlq #1,temp2 ; TEMP2 = Pi ($80 in Brads) sub temp,temp2 ; Sin(pi/2 + a) = Sin(pi/2 -a) move temp2,temp 99$: shlq #2,temp add temp,ptr load (ptr),temp ; TEMP = Table Lookup SIN_RTS neg temp ; Sin(a) = -1*Sin(a - pi) ; ; CONSTANT DATA ; ALIGN LONG sintbl: ; Lookup Table for Trigonometry ; dc.l $0000,$0192,$0324,$04b5,$0646,$07d6,$0964,$0af1 ; True BRAD Values ; dc.l $0c7c,$0e06,$0f8d,$1112,$1294,$1413,$1590,$1709 ; True BRAD Values ; dc.l $187e,$19ef,$1b5d,$1cc6,$1e2b,$1f8c,$20e7,$223d ; True BRAD Values ; dc.l $0000,$0195,$0329,$04b0,$0647,$07d4,$0962,$0af0 ; Better integer approximations for sin/cos matching ; dc.l $0c7d,$0e05,$0f8d,$1110,$1292,$1414,$1590,$1709 ; dc.l $187e,$19f0,$1b5d,$1cc6,$1e2c,$1f8b,$20e7,$223e ; dc.l $238e,$24da,$2620,$2760,$289a,$29ce,$2afb,$2c21 ; dc.l $2d41,$2e5a,$2f6c,$3076,$3179,$3274,$3368,$3453 ; dc.l $3537,$3612,$36e5,$37b0,$3871,$392b,$39db,$3a82 ; dc.l $3b21,$3bb6,$3c42,$3cc5,$3d3f,$3daf,$3e15,$3e72 ; dc.l $3ec5,$3f0f,$3f4f,$3f85,$3fb1,$3fd4,$3fec,$3ffb ; dc.l $4000 ; Swapped for GASM BUG **KLUDGE** dc.l $00000000,$01950000,$03290000,$04b00000,$06470000,$07d40000,$09620000,$0af00000 dc.l $0c7d0000,$0e050000,$0f8d0000,$11100000,$12920000,$14140000,$15900000,$17090000 dc.l $187e0000,$19f00000,$1b5d0000,$1cc60000,$1e2c0000,$1f8b0000,$20e70000,$223e0000 dc.l $238e0000,$24da0000,$26200000,$27600000,$289a0000,$29ce0000,$2afb0000,$2c210000 dc.l $2d410000,$2e5a0000,$2f6c0000,$30760000,$31790000,$32740000,$33680000,$34530000 dc.l $35370000,$36120000,$36e50000,$37b00000,$38710000,$392b0000,$39db0000,$3a820000 dc.l $3b210000,$3bb60000,$3c420000,$3cc50000,$3d3f0000,$3daf0000,$3e150000,$3e720000 dc.l $3ec50000,$3f0f0000,$3f4f0000,$3f850000,$3fb10000,$3fd40000,$3fec0000,$3ffb0000 dc.l $40000000 ;*======================================================================* ;* EOF * ;*======================================================================* ALIGN PHRASE