;*======================================================================* ;* TITLE: SORT.GAS * ;* Function: Sort Turtles into Painter's Order * ;* * ;* 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 | ; +-------------------+ ViewPoint Turtle Record ; | Ydown | Zdown | ; +-------------------+ ; | Xhead | Yhead | ; +-------------------+ ; | Zhead | Xposn | ; +-------------------+ ; | Yposn | Zposn | ; +-------------------+ ; ... ; +---------+ +---------------+ ; | Drawers |<---| (DrawList) | INPUT2 ; +---------+ +---------------+ ; +---------+ +---------------+ ; | Scrubs |<---| (ScrubList) | INPUT3 ; +---------+ +---------------+ ; +-------------------+ +---------------+ ; | Turtle[1] |<---| (TURTLE[1]) | INPUT4 ; +-------------------+ +---------------+ ; +-------------------+ ; | No. of Turtles | INPUT5 ; +-------------------+ ; | Turtle Rcd Size | INPUT6 ; +-------------------+ ; ; ; COMMON EQUATES ; .data .gpu .nojpad DEBUG_ON .equ 0 .nolist .include "jaguar.inc" .include "blit.inc" .include "gpu.inc" .include "macros.inc" .list SORT:: .dc.l G_RAM .dc.l EndGPU-StartGPU 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 .org G_RAM StartGPU: ; ; GLOBAL REGISTER EQUATES ; temp .equr r0 temp2 .equr r1 lomask .equr r2 himask .equr r3 ptr .equr r4 matptr .equr r5 mtxa .equr r6 jumpr .equr r10 gpuptr .equr r11 inptr .equr r12 step .equr r13 ndx .equr r14 this .equr r15 ; * Caution Multiply Defined* now .equr r16 ; * Caution Multiply Defined* last .equr r17 ; * Caution Multiply Defined* thisrec .equr r18 ; * Caution Multiply Defined* thisptr .equr r19 ; * Caution Multiply Defined* link .equr r15 xtemp .equr r16 ytemp .equr r17 ztemp .equr r18 xviewr .equr r19 yviewr .equr r20 zviewr .equr r21 zposn .equr r22 scrublist .equr r23 oldlist .equr r24 turtlsiz .equr r25 nturtles .equr r26 turtle68k .equr r27 draw68k .equr r28 scrub68k .equr r29 rsort .equr r30 return .equr r31 ; ; ALTERNATE REGISTER EQUATES ; left1 .equr r11 left2 .equr r12 ; ; LOCAL MACROS ; ; NOTE: Dedicated Subroutine calls expect the proper ; registers to be pre-set. No Nesting! .macro JSR_SORT move PC,return jump T,(rsort) addq #6,return ; Determine Return Address .endm .macro SORT_RTS jump T,(return) .endm ; ; CODE SEGMENT ; ; ; System Initialization ; DEBUG_INIT moveq #1,himask neg himask move himask,lomask shlq #16,himask ; HIMASK = $ffff0000 shrq #16,lomask ; LOMASK = $0000ffff movei #sort,rsort movei #INPUT1,ptr load (ptr),temp2 ; TEMP2 = 68000 ptr to Viewpt Turtle addq #4,ptr load (ptr),draw68k ; DRAW68K = Ptr to 68000 Drawlist addq #4,ptr load (ptr),scrub68k ; SCRUB68K = Ptr to 68000 Scrublist addq #4,ptr load (ptr),turtle68k ; TURTLE68K = Ptr to 68000 Turtles addq #4,ptr load (ptr),nturtles ; NTURTLES = Number of Active Turtles addq #4,ptr load (ptr),turtlsiz ; TURTLSIZ = Size of a Turtle Record (Bytes) or turtlsiz,turtlsiz ; *KLUDGE* BUG 21 FIX movei #G_MTXC,ptr movei #(GPUM3x1|GPUMROW),temp ; Righthand matrix is [3x1] - COLUMN major store temp,(ptr) ; Since we wish to multiply by the TRANSPOSE of the Viewer's Matrix movei #G_MTXA,mtxa ; Prepare GPU for ROW MAJOR multiply movei #matrix,matptr addq #12,temp2 move matptr,gpuptr moveq #5,ndx .10: loadw (temp2),temp ; FOR (X,Y and Z Head and Posn) DO addq #2,temp2 shlq #16,temp sharq #16,temp subq #1,ndx store temp,(gpuptr) ; Matrix[i] = Head/Posn Element Sign-extended jr PL,.10 addq #4,gpuptr nop ; << WHY IS THIS NOP REQUIRED? >> **KLUDGE** move matptr,gpuptr ; Extract Posn values into registers addq #12,gpuptr load (gpuptr),xviewr addq #4,gpuptr load (gpuptr),yviewr addq #4,gpuptr load (gpuptr),zviewr ; ; Find Final Zpos for all Turtles ; NOTE: This code assumes ALL Turtles are active and displayed ; movei #zloop,jumpr movei #(gpuram+4),gpuptr move turtle68k,inptr addq #18,inptr ; INPTR = Ptr to Turtle[1].Xposn move turtlsiz,step subq #6,step ; STEP = Offset to same .Xposn of next turtle move nturtles,ndx zloop: ; FOR (All Turtles) DO loadw (inptr),xtemp ; Fetch this Turtle addq #2,inptr loadw (inptr),ytemp addq #2,inptr shlq #16,xtemp shlq #16,ytemp sharq #16,xtemp ; XTEMP = 32-bit Xpos sharq #16,ytemp ; YTEMP = 32-bit Ypos loadw (inptr),ztemp addq #2,inptr loadw (inptr),link add step,inptr shlq #16,ztemp shlq #2,link ; LINK = GPU Internal Index sharq #16,ztemp ; ZTEMP = 32-bit Zpos sub xviewr,xtemp ; XTEMP = DeltaX sub yviewr,ytemp ; YTEMP = DeltaY sub zviewr,ztemp ; ZTEMP = DeltaZ and lomask,xtemp shlq #16,ytemp or ytemp,xtemp ; XTEMP = DeltaY | DeltaX store matptr,(mtxa) moveta xtemp,left1 moveta ztemp,left2 nop mmult left1,zposn ; ZPOSN = Final Z in Viewer Space sharq #14,zposn shlq #16,zposn or zposn,link ; LINK = ZPosn | LinkIndex subq #1,ndx store link,(gpuptr) ; Save this result in local memory jump NE,(jumpr) addq #4,gpuptr ; ; Sort Internal Records by Zpos ; loadw (draw68k),oldlist ; OLDLIST = 68000 DrawList Root movei #gpuram,gpuptr shlq #2,oldlist ; OLDLIST = Internalized Drawlist Root moveq #0,scrublist ; SCRUBLIST = Nil store scrublist,(gpuptr) ; DRAWLIST = Nil JSR_SORT loadw (scrub68k),oldlist ; OLDLIST = 68000 ScrubList Root shlq #2,oldlist ; OLDLIST = Internalized Drawlist Root JSR_SORT ; ; Write-Back Results to 68000 RAM ; shrq #2,scrublist load (gpuptr),temp storew scrublist,(scrub68k) ; New ScrubList Root shrq #2,temp storew temp,(draw68k) ; New DrawList Root addq #4,gpuptr addq #24,turtle68k ; TURTLE68K = Turtle[1].Turtlnk writlp: load (gpuptr),temp addq #4,gpuptr and lomask,temp shrq #2,temp ; Divide Index back down for 68000 land subq #1,nturtles storew temp,(turtle68k) jr NE,writlp add turtlsiz,turtle68k ; ; 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 T,endloop ; infinite loop nop ; ; SUBROUTINE AREA ; ; ; sort Sort Turtles by Zposn ; ; GIVEN: ; OLDLIST = Index of First Turtle in list ; SCRUBLIST = Index of First Turtle in ScrubList ; GPUPTR = Address of TurtleRecord[0] ; TURTLE[0] = Drawlist Root ; ; RETURNS: ; SCRUBLIST = New Turtles Scrubbed as needed ; TURTLE[0] = New Drawlist Root ; Turtle Records Re-Linked ; ; REGISTER USAGE: ; temp, ptr, lomask, himask, rsort ; this, now, last, thisptr, thisrec ; sort: cmpq #0,oldlist ; WHILE (Oldlist <> Nil) DO move oldlist,thisptr jr NE,.10 nop SORT_RTS ; NOTE: Exit from the side .10: move oldlist,this ; THIS = Current Record Index add gpuptr,thisptr ; THISPTR = Address of This Record load (thisptr),oldlist move oldlist,thisrec ; THISREC = Current Record and lomask,oldlist ; OLDLIST = This.Next cmpq #0,thisrec jr PL,.33 ; IF (Zpos < 0) THEN Scrub this Turtle ; ; Add this record to the Scrublist ; and himask,thisrec or scrublist,thisrec ; This.Next = Scrublist move this,scrublist ; Scrublist = This jump T,(rsort) store thisrec,(thisptr) .33: ; ELSE (Zpos >= 0) ; ; Insert this record into the Drawlist ; or lomask,thisrec ; New guy wins ties moveq #0,last ; LAST = Index to Root load (gpuptr),now ; NOW = Last.Next .40: and lomask,now ; WHILE ((Now <> Nil) .. move now,ptr jr EQ,.49 add gpuptr,ptr load (ptr),temp cmp thisrec,temp ; .. AND (Now.Z > This.Z)) DO jr MI,.49 nop move now,last ; LAST = Now jr T,.40 move temp,now ; NOW = Now.Next .49: ; Drawlist Insertion Point found and himask,thisrec add gpuptr,last or now,thisrec ; This.Next = Now load (last),temp store thisrec,(thisptr) ; Save 'This' record and himask,temp or this,temp ; Last.Next = This jump T,(rsort) store temp,(last) ; Save 'Last' record ; ; CONSTANT DATA ; ; ; VARIABLE STORAGE ; .phrase matrix: ; HEAD portion of Viewpt .dcb.l 3,0 gpuram: ; Array of Turtle Zpos|Link Records ; .. All the rest of memory .phrase ; this is VERY IMPORTANT TO HAVE HERE IF YOU USE THE ; LINKER to include a *.BIN file via -iFILENAME LABELNAME EndGPU: .end ;*======================================================================* ;* EOF * ;*======================================================================*