.FILE 'NDSP1.ASM' .TITLE "GSP DISPLAY PROCESSOR VER. 3.1" ************************************************************************** * * * COPYRIGHT (C) 1988 WILLIAMS ELECTRONICS GAMES, INC. * * ALL RIGHTS RESERVED. * * * ************************************************************************** .WIDTH 132 .OPTION B,D,L,T .MNOLIST * *GSP DMA OBJECT HANDLER *VERSION 1.0 BY WARREN DAVIS 9/1/87 *VERSION 2.01 BY EUGENE JARVIS 10/25/87 *VERSION 3.0 BY EUGENE JARVIS 12/20/87 *VERSION 3.1 BY EUGENE JARVIS 7/4/88 *VERSION 3.2 BY EUGENE JARVIS 8/8/88 **************************************** *FILES REQUIRED FOR ASSEMBLY .INCLUDE \VIDEO\SYS\GSP.INC .INCLUDE \VIDEO\SYS\SYS.INC .INCLUDE \VIDEO\SYS\MACROS.HDR .INCLUDE MPROC.EQU .INCLUDE DISP.EQU .DEF QDMA,DMAQ,QDMAFLG,ANI ;FOR FILE SCORE USAGE .REF HALT,GETFPAL * * GLOBAL VARIABLES * .SECT "OFIXED" OBJLST .LONG 0 ;POINTER TO ACTIVE OBJECT LIST OFREE .LONG 0 ; POINTER TO FREE OBJECT BLOCK ENDOFREE .LONG 0 BAKLST .LONG 0 ;BACKGROUND LIST ;BAK2LST .LONG 0 ;SLOW SCROLL BACKGROUND PLANE .SECT ".text" * .BSS SCROLLX,32 ;X SCROLL VALUE .BSS SCROLLY,32 ;Y SCROLL VALUE .BSS WORLDTLX,32 ;TOP LEFT X SCREEN COORD (WORLD) .BSS WORLDTLY,32 ;TOP LEFT Y SCREEN COORD (WORLD) .BSS WORLDTL,32 ;PACKED TOP LEFT WORLD COORD .BSS SCRNTL,32 ;TOP LEFT [Y,X] SCREEN (SCRN COORD.) .BSS SCRNLR,32 ;LOWER RIGHT [Y,X] SCREEN (SCRN COORD.) ; .BSS BAK2TLY,32 ;TOP LFT Y SLOW SCROLL BACKGROUND ; .BSS BAK2TLX,32 ;TOP LFT X SLOW SCROLL BACKGROUND .BSS QSYNC,16 ;SIGNALS ACTIVE Q .BSS DMAQCUR,32 ;CURRENT DMAQ .BSS DMAQCNT,16 ;CURRENT DMAQ COUNT .BSS BOTQ0CNT,16 ;BOTTOM QUEUE COUNT #0 .BSS BOTQ1CNT,16 ;BOTTOM QUEUE COUNT #1 .BSS TOPQ0CNT,16 ;TOP QUEUE COUNT #0 .BSS TOPQ1CNT,16 ;TOP QUEUE COUNT #1 .BSS BOTQ0FLG,16 ;BOTTOM Q0 VALID FLAG VALID=NE .BSS BOTQ1FLG,16 ;BOTTOM Q1 VALID FLAG VALID=NE .BSS TOPQ0FLG,16 ;TOP Q0 VALID FLAG VALID=NE .BSS TOPQ1FLG,16 ;TOP Q1 VALID FLAG VALID=NE .BSS OBJSTR,NOBJ*OBSIZ ;OBJECT STRUCTURE LIST START .BSS OBJLSTND,0 ;OBJECT LIST END QSIZE .SET NOBJ*BQCELL ;SIZE OF QUEUES .BSS BOTQ0,QSIZE ;BOTTOM OBJECT DMA Q #0 .BSS BOTQ1,QSIZE ;BOTTOM OBJECT DMA Q #1 .BSS TOPQ0,QSIZE ;TOP OBJECT DMA Q #0 .BSS TOPQ1,QSIZE ;TOP OBJECT DMA Q #1 .BSS DMAQ,QSIZE ;MISC. NON-SYNC DMA QUEUE .BSS DISPLAYON,16 ;DO DISPLAY PROCESSING WHEN != 0 .BSS SKIPDMA,16 ;SKIP DMA RESTART IF != 0 .BSS QDMAFLG,16 ;SPECIAL DMAQ BEING UPDATED=1 ***************OVERLOAD ****> .BSS OVTOP,16 ;TOP SCREEN OVERLOAD ****> .BSS OVBOT,16 ;BOTTOM SCREEN OVERLOAD * *DMA INTERRUPT * DMAINT: MMTM B12,B6,B7,B8,B9 ;EMPTY HER OUT MOVE B10,-*B12,W MOVE B11,-*B12,W MOVI DMAREGS,B12 DEC B13 * JRN $ ;ERROR, DMA QUEUE UNDERFLOW JRN DMAINT1 JRNZ DMAINTX ;BR = MORE LEFT IN THIS QUEUE DMAINT1: CALLR DMANUQ ;LOOK TO START A NEW Q RETI DMAINTX: SUBI >140,B14 ;SETUP Q PULL MMFM B14,B6,B7,B8,B9,B10 ;LOAD HER UP MOVE B10,B11 SRL 16,B10 RETI DCLIPL: MOVE *A0(OXPOS),A10 ; MOVE *A0(OYPOS),A2 ; SLL 16,A2 MOVY A2,A10 ; Y:X IN A10 MOVE A10,*A0(ODMAXY),L ;UPDATED XY POSITION MOVE B4,A6 ;SUBTRACT WORLD COORD TO GET SCREEN COORD. SUBXY A6,A10 MOVE A0,A3 ADDI OFLAGS,A3 ;GET PARAMETER LOCATION MMFM A3,A12,A11,A9,A8 * CHECK FOR FLIPPING, NECESSITY OF CLIPPING, ADJUST OFFSET, SAG * A0 IS THE ADDRESS OF THE OBJECT BLOCK * A1 BECOMES OFFSET * A2=AMOUNT TO CLIP OFF BOTTOM, RIGHT (BC,RC) * A3=AMOUNT TO CLIP OFF TOP, LEFT (TC,LC) * A6=SCREEN TOP LEFT (SCREEN COORDINATES); THEN TOTAL HORIZ. SIZE * * A8 IS CONST:PALETTE * A9 BECOMES VS : HS * A10 IS DAG (Y : X) * A11 IS THE SAG * A12 IS THE CONTROL WORD B0-15; OFFSET B16-31 * A13 IS THE WINDOW BOTTOM RT * A14 IS THE WINDOW TOP LEFT * * COMPUTE LC, RC, TC, BC * CLR A6 ; UPPER LEFT SCREEN COORDINATES CLR A1 ; USE FOR CLEARING NOW, BECOMES OFFSET LATER MOVE A10,A2 ; PT IN A2 ADDXY A9,A2 ; LOWER RIGHT IN A2 SUBXY A13,A2 ; PT - WEND -> A2 ( BC : RC ) JRYGE DIS_CLP0 MOVY A1,A2 ; CLEAR BC IF Y NEGATIVE DIS_CLP0: JRXGE DIS_CLP1 MOVX A1,A2 ; CLEAR RC IF X NEGATIVE DIS_CLP1: MOVE A14,A7 ; MOVE WSTART CLR A3 ; SUBXY A10,A7 ; WSTART - PT -> A7 (TC : LC) JRYLT DIS_CLP2 MOVY A7,A3 ; TC IN UPPER HALF OF A3 MOVY A14,A10 ; ADJUST START POSITION TO WINDOW EDGE DIS_CLP2: JRXLT DIS_CLP3 MOVX A7,A3 ; LC IN LOWER HALF OF A3 MOVX A14,A10 ; ADJUST START POSITION TO WINDOW EDGE DIS_CLP3: MOVX A9,A6 ;GET TOTAL HORIZONTAL SIZE (MORSEL CORRECTED) ADD A3,A2 ; (TC+BC : LC+RC) IN A2 JREQ NOCLIP ; TOTAL CLIP IS ZERO, NOCLIP SUBXY A2,A9 ; GET CLIPPED SIZE...TOTALLY CLIPPED? JRXLE NODIS ; YES, DON'T DISPLAY IT JRYLE NODIS * *CLIP THE SAG, HS, VS, AND ADJUST OFFSET * MOVX A3,A1 ;GET LEFT CLIP SRL 16,A3 ;GET TOP CLIP JREQ CLIP1 MOVE *A0(OXCLIP),A7 ADD A6,A7 ;ADD PRECLIP TO THE WIDTH TO CALC NEW SAG MPYS A7,A3 ;TOP CLIP X TOTAL HORIZ SIZE CLIP1: SLL 16,A2 BTST B_FLIPH,A12 JREQ CLIP2 NEG A2 ;NEGATE RC+LC NEG A1 ;NEGATE LC CLIP2: BTST B_FLIPV,A12 JREQ CLIP3 NEG A3 ;NEGATE THS*TC CLIP3: ADD A1,A3 ;ADD LEFT CLIP TERM + TC*THS SLL 3,A3 ADD A3,A11 ;ADD TO SAG ADD A2,A12 ;ADD CLIP OFFSET TO OFFSET NOCLIP: ********************************************************** .IF DEBUG BTST 15,A12 JREQ $ .ENDIF * *BEAM AVOIDANCE, AT HALF SCREEN, DMA TOP HALF * AT FULL SCREEN, DMA BOTTOM HALF * *B1 = HALF SCREEN LINE COUNT *B2=BOTTOM Q COUNT *B3=TOP Q COUNT *A4=BOTTOM DMA Q TO LOAD *A5=TOP DMA Q TO LOAD *A8 = CONST:PALETTE XLATE *A9 = VSIZE:HSIZE *A10 = DESTINATION Y:X *A11 = IMAGE SAG *A12 = OFFSET:CONTROL MOVE B1,A2 ;GET HALF SCREEN LINE NUMBER(Y ADJUSTED) CMPXY A10,A2 ;WHERE'S THE IMAGE? JRYLE BEAM_STKIMG ;BR = ON THE OTHER SIDE, TOTALLY, STACK IT SUBXY A10,A2 ;DETERMINE HEIGHT ABOVE MID SCREEN CMPXY A2,A9 ;TOTALLY ABOVE? JRYLE BEAM_DODMA ;BR = YES, DMA AS IS MOVE A9,B0 ;SAVE THE SIZES MOVY A2,A9 ;STUFF NEW VSIZE AND DO IT *STACK THE SUCKER *B1 = HALF SCREEN LINE COUNT *B2= BOTTOM Q COUNT *B3= TOP Q COUNT *A4= BOTTOM DMA Q TO LOAD *A5= TOP DMA Q TO LOAD *A6= TOTAL HORIZONTAL SIZE *A8 = CONST:PALETTE XLATE *A9 = VSIZE:HSIZE *A10 = DESTINATION Y:X *A11 = IMAGE SAG *A12 = OFFSET:CONTROL MMTM A5,A8,A9,A10,A11,A12 ;SAVE THE DMA REGS INC B3 *SET UP DMA REGS FOR BOTTOM HALF AND STACK THEM MOVE B0,A9 SRL 16,A2 ;SLIDE DOWN THE Y DIFFERENTIAL MOVE *A0(OXCLIP),A3 ;ADD PRECLIP TO WIDTH ADD A6,A3 ;WE NEED TS IN AN ODD REG. FOR 32 BIT MULT. SLL 3,A3 ;TS = TS*8 MPYU A2,A3 ;A3 = SAG OFFSET SLL 16,A2 ;Y DIFF BACK TO Y POS SUBXY A2,A9 ;NEW VSIZE ADDXY A2,A10 ;NEW DMA POSITION BTST B_FLIPV,A12 JREQ BEAM_ADDSAG ;BR = SUBTRACT FOR NEW SAG BECAUSE OF VFLIP NEG A3 ;SAG = -SAG BEAM_ADDSAG: ADD A3,A11 ;SAG = SAG + OFFSET BEAM_STKIMG: MMTM A4,A8,A9,A10,A11,A12 ;SAVE THE DMA REGS INC B2 JRUC NODIS *STACK THE SUCKER *B1 = HALF SCREEN LINE COUNT *B2=BOTTOM Q COUNT *B3=TOP Q COUNT *A4=BOTTOM DMA Q TO LOAD *A5=TOP DMA Q TO LOAD *A8 = CONST:PALETTE XLATE *A9 = VSIZE:HSIZE *A10 = DESTINATION Y:X *A11 = IMAGE SAG *A12 = OFFSET:CONTROL BEAM_DODMA: MMTM A5,A8,A9,A10,A11,A12 ;SAVE THE DMA REGS INC B3 NODIS: MOVE *A0,A0,L ;GET NEXT LINK NODIS1: JRNE DCLIPL ;DONE? RETS * *GET NEW DMA Q CALLED FROM DMA INTERRUPT * DMANUQ: CLR B13 MOVE @TOPQ0FLG,B14,W JREQ DMANUQ1 CLR B14 MOVE B14,@TOPQ0FLG,W MOVE @TOPQ0CNT,B13,W JREQ DMANUQ1 MOVE B14,@TOPQ0CNT,W MOVI TOPQ0+(QSIZE),B14 JRUC DMANUQL DMANUQ1: MOVE @TOPQ1FLG,B14,W JREQ DMANUQ2 CLR B14 MOVE B14,@TOPQ1FLG,W MOVE @TOPQ1CNT,B13,W JREQ DMANUQ2 MOVE B14,@TOPQ1CNT,W MOVI TOPQ1+(QSIZE),B14 JRUC DMANUQL DMANUQ2: MOVE @BOTQ0FLG,B14,W JREQ DMANUQ3 CLR B14 MOVE B14,@BOTQ0FLG,W MOVE @BOTQ0CNT,B13,W JREQ DMANUQ3 MOVE B14,@BOTQ0CNT,W MOVI BOTQ0+(QSIZE),B14 JRUC DMANUQL DMANUQ3: MOVE @BOTQ1FLG,B14 ,W JREQ DMANUQX CLR B14 MOVE B14,@BOTQ1FLG,W MOVE @BOTQ1CNT,B13,W JREQ DMANUQX MOVE B14,@BOTQ1CNT,W MOVI BOTQ1+(QSIZE),B14 DMANUQL: SUBI >A0,B14 MMFM B14,B6,B7,B8,B9,B10 ;LOAD HER UP MOVE B10,B11 SRL 16,B10 RETS DMANUQX: MOVE @INTENB,B14,W ;DISABLE DMA INTERRUPT ANDI >FFFD,B14 MOVE B14,@INTENB,W RETS * *ENABLE TOP DISPLAY QUEUES * DISPQT: MOVK 1,A0 ;ENABLE YOUR QUEUES MOVE @QSYNC,A1,W NOT A1 MOVE A1,@QSYNC,W JRNE DISPQT1 MOVE A0,@TOPQ1FLG,W JRUC DISPQT2 DISPQT1: MOVE A0,@TOPQ0FLG,W DISPQT2: ****> MOVK 1,A1 ****> MOVE @DMACTRL,A0,W ;DMA BUSY? ****> JRN DISP3 ****> CLR A1 ;NO OVERLOAD DISP3: ****> MOVE A1,@OVBOT,W ;STORE OVERLOAD CALLR DMASTRT RETS * * DISPLAY OBJECT LIST * CALLED AT MIDSCREEN INTERRUPT * DISPLAY: MOVE @QSYNC,A1,W JRNE DISP1 MOVI BOTQ0+(QSIZE),A4 ;SETUP NEW INTERRUPT LOAD DMA QUEUES MOVI TOPQ0+(QSIZE),A5 JRUC DISP2 DISP1: MOVI BOTQ1+(QSIZE),A4 ;SETUP NEW INTERRUPT LOAD DMA QUEUES MOVI TOPQ1+(QSIZE),A5 DISP2: *********************************************** .IF DEBUG *SPECIAL TRAP *CHECK IF B14 IS WITHIN Q BEING FILLED MOVE B14,A0 CMP A4,A0 JRHI DDDD1 MOVE A4,A1 SUBI QSIZE,A1 CMP A1,A0 JRLO DDDD1 JRUC $ DDDD1 CMP A5,A0 JRHI DDDD2 MOVE A5,A1 SUBI QSIZE,A1 CMP A1,A0 JRLO DDDD2 JRUC $ DDDD2 .ENDIF *********************************************** PUSHST DINT MOVE @INTENB,A0,W ;ENABLE DISPLAY INTERRUPT ORI DIE,A0 MOVE A0,@INTENB,W POPST MOVE @DISPLAYON,A0,W JREQ DISPRETS ;BR = STOP ALL NEW DISPLAY PROCESSING *VELOCITY UPDATE MOVE @HALT,A0 JRNE SJPAD MOVI OXVEL,A1 MOVI OBJLST,A0 CALLR DVELP SJPAD: *CLIP AND LOAD DMA *A4=BOTTOM DMA Q TO LOAD *A5=TOP DMA Q TO LOAD *B1=HALF SCREEN ADDRESS *B2=BOTTOM Q COUNT *B3=TOP Q COUNT *B4=WORLD TOP LEFT [Y,X] DCLIP: MOVI (HSINT-20)*>10000,B1 ;GET HALF SCREEN LINE NUMBER(Y ADJUSTED) ;27 CLR B3 ;TOP Q COUNT CLR B2 ;BOTTOM Q COUNT ; MOVE @SCROLLX,A6,L ; GET Y:X SCROLL VALUES ; MOVE @SCROLLY,A7,L ; SRA 1,A6 ; SRA 1,A7 ;SCROLL 1/2 AS FAST ; MOVE @BAK2TLY,A14,L ;BACKGRD 2 SCREEN TL Y INTEGER:FRACTION ; MOVE @BAK2TLX,A13,L ;BACKGRD 2 SCREEN TL X INTEGER:FRACTION ; ADD A7,A14 ; MOVE A14,@BAK2TLY,L ; ADD A6,A13 ; MOVE A13,@BAK2TLX,L ; SRL 16,A13 ; MOVX A13,A14 ;COMBINE TO FORM TOP LEFT Y:X ; MOVE A14,B4 ;SETUP WORLD TOP LEFT [Y,X] ; MOVE @SCRNTL,A14,L ;GET SCREEN BOUNDARIES ; MOVE @SCRNLR,A13,L ****> MOVE @OVTOP,A0,W ;IF OVERLOAD SKIP BAK2 UPDATE ****> MOVE @OVBOT,A1,W ****> OR A0,A1 ****> JRNE DCLIP1 ; MOVI BAK2LST,A0,L ; CALLR NODIS DCLIP1: MOVE @SCROLLX,A6,L ; GET Y:X SCROLL VALUES MOVE @SCROLLY,A7,L MOVE @WORLDTLY,A14,L ;SCROLL YOUR SCREEN FOLKS MOVE @WORLDTLX,A13,L ADD A6,A13 ADD A7,A14 MOVE A14,@WORLDTLY,L MOVE A13,@WORLDTLX,L SRL 16,A13 MOVX A13,A14 ;COMBINE TO FORM TOP LEFT Y:X MOVE A14,B4 ;SETUP WORLD TOP LEFT [Y,X] MOVE B4,@WORLDTL,L ;STORE THE WORLD TOP LEFT [Y,X] MOVE @SCRNTL,A14,L ;GET SCREEN BOUNDARIES MOVE @SCRNLR,A13,L ***********Z PLANE CHECK KLUDGE*********************************** * * .GLOBAL PLZMIN * MOVE @PLZMIN,A1,W * SUBI 10,A1 ;FUDGE FACTOR * MOVE @OBJLST,A0,L * JREQ DISPBAK ;FORGET IT NULL LIST * MOVE *A0(OZPOS),A2,W ;FIND STUFF IN BACK * CMP A1,A2 * JRGE DISPBAK ;TEST FIRST ONE, NOTHING IN BACK *DZCHL * MOVE *A0(OZPOS),A2,W ;FIND STUFF IN BACK * CMP A1,A2 * JRGE DZCHK1 * MOVE *A0,A0,L * JRNE DZCHL * * MOVI OBJLST,A0,L ;EVERYTHINGS IN BACK * CALLR NODIS * * MOVI BAKLST,A0,L * CALLR NODIS * JRUC DISPX * *DZCHK1: * MOVE *A0,A1,L * MMTM SP,A0,A1 ;SAVE OLD LIST POINTERS * CLR A1 * MOVE A1,*A0,L ;ZERO OUT LIST (SPLIT IT UP) * * MOVI OBJLST,A0,L ;OUTPUT BACK OBJECTS * CALLR NODIS * * MOVI BAKLST,A0,L ;OUTPUT BACKGROUND PLANE * CALLR NODIS * * MMFM SP,A0,A1 * MOVE A1,*A0,L ;RESTORE LIST * MOVE A0,A0 * CALLR NODIS1 ;PROCESS REST OF OBJECT LIST * JRUC DISPX ***************************************************************************** DISPBAK: MOVI BAKLST,A0,L CALLR NODIS MOVE @QDMAFLG,A2 ;Q BEING MODIFIED? JRNE DISPX0 ;YES, DON'T SCREW WITH IT MOVE @DMAQCUR,A2,L MOVI DMAQ+QSIZE,A1 CMP A1,A2 JREQ DISPX0 ;NONE MOVE A1,@DMAQCUR,L ;RESET TOP OF QUEUE DISPXL: MOVE -*A1,-*A5,L ;TRANSFER YOUR Q'S MOVE -*A1,-*A5,L MOVE -*A1,-*A5,L MOVE -*A1,-*A5,L MOVE -*A1,-*A5,L INC B3 ;INCREMENT COUNT CMP A2,A1 JRHI DISPXL DISPX0: MOVI OBJLST,A0,L CALLR NODIS *PUT NULL DMA ON DMA QUEUES MOVI NULLDMA,A0 MMFM A0,A8,A9,A10,A11,A12 MMTM A5,A8,A9,A10,A11,A12 ;NULL DMA JUNK TOPQ MMTM A4,A8,A9,A10,A11,A12 ;NULL DMA JUNK BOTQ MOVE @QSYNC,A0,W JRNE DISPX1 MOVE B2,@BOTQ0CNT MOVE B3,@TOPQ0CNT RETS DISPX1: MOVE B2,@BOTQ1CNT MOVE B3,@TOPQ1CNT DISPRETS RETS ;YIP, SHOVE IT... *NULL DMA DATA NULLDMA: .LONG >8000,IROM,0,>00010001,0 * *VELOCITY ADD LOOP * DVEL: *** MOVE *A0(OFLAGS),A3,W ;CHECK FOR NO VELOCITY BLOCKS *** BTST B_NOMOV,A3 *** JRNE DVELP ;NO VELOCITY, SKIP IT DVEL1: MOVE A0,A3 ADD A1,A3 ;ADD IN OXVEL *A12:OXVEL, A11:0YVEL, A10:OXPOS, A9:OYPOS, A8: OZPOS A7:OZVEL ** MMFM A3,A7,A8,A9,A10,A11,A12 *A12:OXVEL, A11:0YVEL, A10:OXPOS, A9:OYPOS MMFM A3,A9,A10,A11,A12 ADD A12,A10 ;ADD X VELOCITY TO XVAL ADD A11,A9 ;ADD Y VELOCITY TO YVAL ** ADD A7,A8 ;ADD Z VELOCITY TO ZVAL ** SUBK 20H,A3 ** MMTM A3,A8,A9,A10 MMTM A3,A9,A10 DVELP: MOVE *A0,A0,L ;GET NEXT ONE FOLKS JRNE DVEL RETS * *PRIME DMA INTERRUPT FOR BOTTOM QUEUE * DISPH: MOVK 1,A0 ;ENABLE YOUR QUEUES MOVE @QSYNC,A1,W JRNE DISPH1 MOVE A0,@BOTQ1FLG,W JRUC DISPH2 DISPH1: MOVE A0,@BOTQ0FLG,W DISPH2: ****> NOP ****> MOVK 1,A1 ****> MOVE @DMACTRL,A0,W ;DMA BUSY? ****> JRN DISPH3 ;YES, DO NOT RESTART ****> CLR A1 DISPH3: ****> MOVE A1,@OVTOP,W ;OVERLOAD INDICATOR CALLR DMASTRT ;START DMA IF APPROPRIATE RETS * *START DMA IF APPROPRIATE * DMASTRT: PUSHST DINT MOVE B13,B13 JRNE DMASTRTX ;IF COUNT > 0, DMA ALREADY GOING CALLR DMANUQ ;GET NEW Q MOVE B13,B13 JREQ DMASTRTX ;ZERO COUNT DONT RESTART MOVE @SKIPDMA,A0,W JRNZ DMASTRTX ;BR = DMA BLOCKED MOVE @INTENB,A0,W ;ENABLE DMA INTERRUPT ORI X1E,A0 MOVE A0,@INTENB,W MOVE @DMACTRL,A0,W ;DMA BUSY? JRN DMASTRTX ;YES, DO NOT RESTART MOVI DMAREGS,B12 ;MAKE SURE B12 SETUP CLR A0 MOVE A0,@DMACTRL,W ;KILL ANY PENDING TRAP 1 DMASTRTX: POPST RETS * *QDMA PUTS IMAGE ON DMA Q *INPUTS: *A1: CONSTANT COLOR:PALETTE *A3: DESTINATION Y:X *A5: OFFSET:CONTROL *A14: ADDRESS OF IMAGE HEADER *GETS: A2=H/W; A4=SAG QDMA: MMTM SP,A2,A4,A13 MOVE *A14,A2,L ;GET VSIZE:HSIZE MOVE *A14(ISAG),A4,L ;GET SAG QDMA1: MOVK 1,A13 MOVE A13,@QDMAFLG,W ;Q BEING MODIFIED MOVE @DMAQCUR,A13,L CMPI DMAQ,A13 JRLS QDMAX ;Q OVERLOAD, CAN IT MMTM A13,A1,A2,A3,A4,A5 MOVE A13,@DMAQCUR,L CLR A13 MOVE A13,@QDMAFLG,W QDMAX: MMFM SP,A2,A4,A13 RETS *MANUAL DMA (SETUP YOUR OWN REGS) *INPUTS: *A1: CONSTANT COLOR:PALETTE *A2: VSIZE:HSIZE *A3: DESTINATION Y:X *A4: SAG *A5: OFFSET:CONTROL QDMAN: MMTM SP,A2,A4,A13 JRUC QDMA1 ************************************************************************** * * * STOPOBJS - ZEROS VELOCITIES FOR ALL OBJECTS ON OBJLST. * * * ************************************************************************** STOPOBJS MMTM SP,A0,A1 CLR A0 MOVI OBJLST,A1 SOBJS1 MOVE *A1,A1,L JREQ SOBJSX MOVE A0,*A1(OXVEL),L MOVE A0,*A1(OYVEL),L ; MOVE A0,*A1(OZVEL),L JRUC SOBJS1 SOBJSX MMFM SP,A0,A1 RETS * *SORT OBJECT LIST IN Z:Y PRIORITY * YZSORT: MMTM SP,A0,A1,A2,A4,A5,A7,A8 MOVI 080000000H,A1 ;LOWEST POSSIBLE Z MOVI 080000000H,A5 ;LOWEST POSSIBLE Y MOVI OBJLST,A0 JRUC YZLP YZLP0: ; MOVE *A2(OZVAL),A8,L ;TEST Z MOVE *A2(OZPOS),A8,W ;TEST Z ; TURMELL CHANGED MAY 9 1989 MOVE *A2(OYVAL),A7,L ;TEST Y CMP A1,A8 JRGT PRIOK JRLT PRISWAP CMP A5,A7 JRGE PRIOK PRISWAP: PUSHST DINT MOVE A2,*A4,L MOVE *A2,*A0,L MOVE A0,*A2,L POPST MOVE A2,A4 JRUC YZLP PRIOK: MOVE A0,A4 MOVE A2,A0 MOVE A8,A1 MOVE A7,A5 YZLP: MOVE *A0,A2,L ; CURRENT LINK IN A2, PREV IN A4 JRNE YZLP0 MMFM SP,A0,A1,A2,A4,A5,A7,A8 RETS * * ************************************************************************** * *TEST IF OBJECT ON SCREEN *A8=OBJECT *RETURNS EQ IF ON SCREEN * *ENTER HERE AND PROVIDE YOUR OWN SCREEN BOUNDRIES SCRTSTG ; MMTM SP,A0,A1,A2,A3 MMTM SP,A1,A2,A3 JRUC SCRTST1 *NORMAL SCREEN BOUNDRIES SCRTST: ; MMTM SP,A0,A1,A2,A3 MMTM SP,A1,A2,A3 MOVE @SCRNTL,A2,L ;GET SCREEN TOP LEFT MOVE @SCRNLR,A3,L ;GET SCREEN LOWER RT. SCRTST1 MOVE *A8(OYPOS),A0,W MOVE *A8(OXPOS),A1,W SLL 16,A0 MOVX A1,A0 ;GET TOP LEFT OF OBJECT MOVE @WORLDTL,A1,L SUBXY A1,A0 ;SUBTRACT OUT WORLD BASE MOVE *A8(OSIZE),A1,L ADDXY A0,A1 ;GET LOWER RT OF OBJECT CMPXY A3,A0 ;IS IT LOWER THAN LOWER RT? JRYGE SCRTF_D ;LOWER JRXGE SCRTF_R ;TO THE RIGHT CMPXY A2,A1 JRYLE SCRTF_U ;ABOVE... JRXLE SCRTF_L ;TO THE LEFT.. CLR A0 MMFM SP,A1,A2,A3 RETS SCRTF_L MOVI 1,A0 MMFM SP,A1,A2,A3 RETS SCRTF_R MOVI 2,A0 MMFM SP,A1,A2,A3 RETS SCRTF_U MOVI 3,A0 MMFM SP,A1,A2,A3 RETS SCRTF_D MOVI 4,A0 MMFM SP,A1,A2,A3 RETS * *CLIP AN OBJECT *INPUTS: *A2=BOTTOM:RIGHT CLIP (RELATIVE TO CURRENT SIZE) *A3=TOP:LEFT CLIP (RELATIVE TO CURRENT SIZE) *A8=OBJECT BLOCK *RETURNS *NEW SAG,H,W,OFFSET,XCLIP IN OBJECT STRUCTURE *ALL REGISTERS PRESERVED * CLIPOBJ: MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A11,A12 MOVE A8,A0 MOVE *A8(OXPOS),A4,W MOVE *A8(OYPOS),A5,W ADDI OFLAGS,A0 ;GET INDEX INTO OBJECT STRUCTURE * A1 BECOMES OFFSET * A6= TOTAL HORIZ. SIZE * A9= VS:HS * A11= SAG * A12= OFFSET:FLAGS MMFM A0,A9,A11,A12 MOVE *A8(OXCLIP),A7 CLR A6 MOVX A9,A6 ;GET TOTAL HORIZ SIZE ADD A3,A2 ;LC+RC SUBXY A2,A9 ;DECREASE H,W BY XCLIP,YCLIP * *CLIP THE SAG, HS, VS, AND ADJUST OFFSET * MOVX A3,A1 ;GET LEFT CLIP SEXT A1,W ADD A1,A4 ;ADJUST OXPOS SRA 16,A3 ;GET TOP CLIP ADD A3,A5 ;ADJUST OYPOS JREQ OCLIP1 ADD A7,A6 ;ADD PRECLIP TO THE WIDTH TO CALC NEW SAG MPYS A6,A3 ;TOP CLIP X TOTAL HORIZ SIZE OCLIP1: ADDXY A2,A7 ZEXT A7,W ;NEW OXCLIP SLL 16,A2 BTST B_FLIPH,A12 JREQ OCLIP2 NEG A2 ;NEGATE RC+LC NEG A1 ;NEGATE LC OCLIP2: BTST B_FLIPV,A12 JREQ OCLIP3 NEG A3 ;NEGATE THS*TC OCLIP3: ADD A1,A3 ;ADD LEFT CLIP TERM + TC*THS SLL 3,A3 ADD A3,A11 ;ADD TO SAG ADD A2,A12 ;ADD CLIP OFFSET TO OFFSET PUSHST DINT MMTM A0,A9,A11,A12 MOVE A4,*A8(OXPOS),W MOVE A5,*A8(OYPOS),W MOVE A7,*A8(OXCLIP),W ;NEW OXCLIP POPST MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A11,A12 RETS ************************************************************************** * * * OBJECT BLOCK INITIALIZATION ROUTINES * * * ************************************************************************** ************************************************************************** * * * OINIT - INITIALIZE FREE LIST * * * ************************************************************************** OINIT: MMTM SP,A0,A1,A2,A3 ;SAVE REG CLR B13 ;CLEAR OUT DMA DEDICATED REGISTERS CLR B14 MOVI NOBJ,A3,W ;# OF OBJECT BLOCKS TO INIT MOVI SCRNST,A0,L ;INIT SCREEN TOP LEFT [Y,X] MOVE A0,@SCRNTL,L MOVI SCRNEND,A0,L ;INIT SCREEN LOWER RIGHT [Y,X] MOVE A0,@SCRNLR,L PUSHST DINT MOVE @INTENB,A0,W ANDNI X1E,A0 ;NO MORE DMA INTERRUPTS MOVE A0,@INTENB,W POPST CLR A0 MOVE A0,@SKIPDMA,W MOVE A0,@WORLDTLY,L ; MOVE A0,@BAK2TLY,L MOVE A0,@WORLDTLX,L ; MOVE A0,@BAK2TLX,L MOVE A0,@WORLDTL,L MOVE A0,@DMAQCNT,W ;CLEAR CURRENT DMAQ COUNT MOVE A0,@BOTQ0CNT,W ;CLEAR BOTTOM QUEUE COUNT #0 MOVE A0,@BOTQ1CNT,W ;CLEAR BOTTOM QUEUE COUNT #1 MOVE A0,@TOPQ0CNT,W ;CLEAR TOP QUEUE COUNT #0 MOVE A0,@TOPQ1CNT,W ;CLEAR TOP QUEUE COUNT #1 MOVI DMAQ+QSIZE,A1 MOVE A1,@DMAQCUR,L ;INIT MISC DMA QUEUE MOVE A0,@SCROLLX,L ;CLEAR SCROLLX MOVE A0,@SCROLLY,L ;CLEAR SCROLLX ; MOVE A0,@BAK2LST,L ;NULL BACKGROUND 2 OBJECT LIST MOVE A0,@BAKLST,L ;NULL BACKGROUND OBJECT LIST MOVE A0,@OBJLST,L ;NULL OBJECT LIST MOVI OBJSTR,A1,L MOVE A1,@OFREE,L ;SETUP FREE LIST OINITL: MOVE A1,A2 ADDI OBSIZ,A1,W MOVE A1,*A2,L ;LINK EM UP DSJS A3,OINITL ;CONTINUE FOR NPROC MOVE A0,*A2,L ;ZERO LAST LINK MMFM SP,A0,A1,A2,A3 ;RESTORE REGS RETS ************************************************************************** * * * GETOBJ - GET A FREE OBJECT BLOCK FOR USE * * RETURNS * * A0 = PTR TO OBJECT BLOCK * * IF NO BLOCKS WERE AVAILABLE THEN THE Z FLAG IS SET * * * ************************************************************************** GETOBJ: MOVE A2,*-SP,1 MOVE @OFREE,A0,L ; POINTER TO NEXT AVAILABLE OBJ BLOCK JREQ NONELFT MOVE *A0,A2,L MOVE A2,@OFREE,L ; ADJUST POINTER TO FREE LIST CLR A2 ; MOVE A2,*A0(OSHAD),L ;CLEAR SHADOW LINK MOVE A2,*A0(OXCLIP),W ;CLEAR CLIP MOVE A2,*A0(ODMAXY),L ;CLEAR DMA XY POSITION MOVE A2,*A0(OPLINK),L ;CLEAR LINK ; MOVE A2,*A0(OSLINK),L ;CLEAR SUPPLEMENTAL LINK ; MOVE A2,*A0(OBLIPIMG),L ;CLEAR SCANNER BLIP STUFF ; MOVE A2,*A0(OEBLIP),L MOVE A2,*A0(OFLAGS),W MOVE A0,A0 ; CLEAR Z FLAG GETOX: MMFM SP,A2 ;DONT SCREW UP Z-FLAG RETS NONELFT: .IF DEBUG LOCKUP EINT .ELSE CALLERR 3,1 .ENDIF JRUC GETOX * *FREE OBJECT WITH ERROR CHECKING * ;FREEOBJE ; MMTM SP,A1,A2 ; CMPI OBJSTR,A0 ; JRHS FREEE1 ; ; .IF DEBUG ; LOCKUP ;* CALLERR 2 ;PTR TOO LOW ; EINT ; .ENDIF ; ; JRUC FREERRX ;FREEE1 ; CMPI OBJLSTND,A0 ; JRLO FREEE2 ; ; .IF DEBUG ;* CALLERR 2 ;PTR TOO HIGH ; LOCKUP ; EINT ; .ENDIF ; ; JRUC FREERRX ;FREEE2 ; MOVE A0,A2 ; SUBI OBJSTR,A2 ; MOVI OBSIZ,A1 ; MODU A1,A2 ; JRZ FREEE3 ; ; .IF DEBUG ;* CALLERR 2 ;PTR NOT VALID ; LOCKUP ; EINT ; .ENDIF ; ; JRUC FREERRX ;FREEE3 ; CALLR ISOBJ ; JREQ FREEE4 ; ; .IF DEBUG ;* CALLERR 2 ;OBJECT IS ON THE ACTIVE LIST ; LOCKUP ; EINT ; .ENDIF ; ; JRUC FREERRX ;FREEE4 ; CALLR ISFREE ; JREQ FREEEC ; ; .IF DEBUG ;* CALLERR 2 ;OBJECT IS ALREADY ON THE FREE LIST ; LOCKUP ; EINT ; .ENDIF ; ;FREERRX ; MMFM SP,A1,A2 ;EXIT WITH ERROR ; RETS ;FREEEC ; MMFM SP,A1,A2 ;EVERYTHING IS O.K. CONTINUE TO FREEOBJ * *MAIN FREE OBJECT ENTRY FREEOBJ PUSH A2 MOVE @OFREE,A2,L MOVE A2,*A0,L MOVE A0,@OFREE,L ;BLOCK IS ON FREE LIST NOW PULL A2 RETS * * INSERT AN OBJECT BLOCK INTO AN OBJECT LIST * LIST IS SORTED BY INCREASING Z AND INCREASING Y WITHIN CONSTANT Z * * BLOCK TO BE INSERTED IN A0 * *INSERT BACKGROUND 2 OBJECT (SORTED) ;INSB2OBJ: ; MMTM SP,A1,A2,A3,A4,A5 ; MOVI BAK2LST,A4 ; JRUC INSOBJ0 *INSERT BACKGROUND OBJECT (SORTED) INSBOBJ: MMTM SP,A1,A2,A3,A4,A5 MOVI BAKLST,A4 JRUC INSOBJ0 *INSERT FOREGROUND OBJECT INSOBJ: MMTM SP,A1,A2,A3,A4,A5 MOVI OBJLST,A4 INSOBJ0: ; MOVE *A0(OZVAL),A1,L ; GET Z POSITION MOVE *A0(OZPOS),A1,W ; GET Z POSITION ; TURMELL CHANGED MOVE *A0(OYVAL),A5,L ; GET Y POSITION INS_LOOP: MOVE A4,A2 ; PTR TO PREV IN A2 MOVE *A2,A4,L ; PTR TO NEXT IN A4 JREQ INS_AT_END ; BRA IF AT END OF LIST ; MOVE *A4(OZVAL),A3,L ; ZPOS IN A3 MOVE *A4(OZPOS),A3,W ; ZPOS IN A3 CMP A3,A1 JRGT INS_LOOP JRLT INS_AT_END MOVE *A4(OYVAL),A3,L ;TEST Y POSITION CMP A3,A5 JRGT INS_LOOP INS_AT_END: MOVE A4,*A0,L ; PUT NEXT LINK IN NEW BLOCK MOVE A0,*A2,L ; PUT LINK TO NEW IN PREV BLOCK MMFM SP,A1,A2,A3,A4,A5 RETS * * DELETE AN OBJECT BLOCK FROM THE OBJECT LIST * * BLOCK TO BE DELETED IN A0 * *DELETE BACKGROUND OBJECT ;DELB2OBJ: ; MMTM SP,A2,A4 ; MOVI BAK2LST,A4 ; JRUC DEL_LOOP *DELETE BACKGROUND OBJECT ;DELBOBJ: ; MMTM SP,A2,A4 ; MOVI BAKLST,A4 ; JRUC DEL_LOOP ; ; .IF DEBUG ; LOCKUP ; .ENDIF *DELETE FOREGROUND OBJECT DELOBJ: MMTM SP,A0,A2,A3,A4,A8 MOVI OBJLST,A4 DEL_LOOP: MOVE A4,A2 ; PTR TO PREV IN A2 MOVE *A2,A4,L ; PTR TO NEXT IN A4 JRNZ DEL_CHK .IF DEBUG LOCKUP EINT .ELSE CALLERR 1,5 .ENDIF JRUC DELOBJX ***NO_DEL: *** JREQ NO_DEL ; ERROR IF AT END OF LIST (HANG UP) DEL_CHK CMP A4,A0 JRNE DEL_LOOP MOVE *A0,*A2,L ; PUT NEXT LINK IN PREV BLOCK MOVE @OFREE,A2,L MOVE A2,*A0,L MOVE A0,@OFREE,L ; RETURN DELETED BLOCK TO FREE STACK move *A0(OFLAGS),A4,W andni M_INUSE,A4 move A4,*A0(OFLAGS),W DELOBJX MMFM SP,A0,A2,A3,A4,A8 RETS ************************************************************************** * * * KILL A CLASS OF OBJECTS * * A0=OID (16 BITS) ,A1=MASK (16 BITS) * * MASK BITS OF ZERO ARE DONT CARES * * * ************************************************************************** *KILL A CLASS FROM THE BACKGROUND ;KILB2OBJ ; MMTM SP,A0,A2,A3,A4,A5 ; MOVI BAK2LST,A2,L ; JRUC KILGEN *KILL A CLASS FROM THE BACKGROUND KILBOBJ MMTM SP,A0,A2,A3,A4,A5 MOVI BAKLST,A2,L JRUC KILGEN *KILL A CLASS FROM THE OBJECT LIST KILOBJ: MMTM SP,A0,A2,A3,A4,A5 MOVI OBJLST,A2,L KILGEN AND A1,A0 ;FORM MATCH KILOBP: MOVE A2,A3 ;SAVE PREVIOUS MOVE *A2,A2,L ;GET NEXT JREQ KILOBX ;ALL DONE MOVE *A2(OID),A4 AND A1,A4 ;CAN DONT CARE BITS CMP A0,A4 ;MATCH? JRNE KILOBP ;NO MOVE *A2,*A3,L ;LINK AROUND IN ACTIVE LIST MOVE @OFREE,A5,L ;LINK INTO FREE LIST AT START MOVE A5,*A2,L MOVE A2,@OFREE,L ;POINT FREE TO CELL MOVE A3,A2 JRUC KILOBP ;KILL THE REST KILOBX: MMFM SP,A0,A2,A3,A4,A5 RETS ************************************************************************** * * * EXISTOBJ - DOES AN OBJECT FROM A CERTAIN CLASS EXIST? * * A0 = OID * * A1 = MASK(0'S DON'T CARE) * * RETURNS: * * Z BIT SET = NO OBJECT, A0 = 0 * * Z BIT CLR = YES OBJECT, A0 = PTR TO OBJECT * * * ************************************************************************** EXISTOBJ: MMTM SP,A2,A3 MOVI OBJLST,A2,L SEXT A0,W AND A1,A0 ;FORM MATCH EXISTOBP: MOVE *A2,A2,L ;GET NEXT JREQ EXISTOBX ;ALL DONE MOVE *A2(OID),A3 AND A1,A3 ;CAN DONT CARE BITS CMP A0,A3 ;MATCH? JRNE EXISTOBP ;NO EXISTOBX: MOVE A2,A0 MMFM SP,A2,A3 RETS ************************************************************************** * * * ISOBJ - IS AN OBJECT ON THE OBJECT LIST? * * A0 = PTR TO OBJECT * * RETURNS: * * Z BIT SET = NO OBJECT, A0 = 0 * * Z BIT CLR = NO OBJECT, A0 = PTR TO OBJECT * * * ************************************************************************** ISOBJ: PUSH A2 MOVI OBJLST,A2,L JRUC ISOBP ************************************************************************** * * * ISFREE - IS AN OBJECT ON THE FREE LIST? * * A0 = PTR TO OBJECT * * RETURNS: * * Z BIT SET = NO OBJECT, A0 = 0 * * Z BIT CLR = NO OBJECT, A0 = PTR TO OBJECT * * * ************************************************************************** ISFREE: PUSH A2 MOVI OFREE,A2,L JRUC ISOBP ISOBP: MOVE *A2,A2,L ;GET NEXT JREQ ISOBX ;ALL DONE CMP A0,A2 ;OBJECT? JRNE ISOBP ;NO MOVE A0,A0 ;CLR Z BIT ISOBX: PULL A2 RETS * *MAKE AN OBJECT *RETURN(S) *A0 = OBJECT BLOCK PTR *A14 = POINTS TO THE INITIALIZATION TABLE * MAKOBJ CALLA GETOBJ JRZ MAKOBX ;NONE LEFT CALLR STFOBJ CALLR INSOBJ MOVE A0,A0 ;RETURN NON-ZERO MAKOBX RETS ************************************************************************** * * * ADJSTWTL - ADJUST THE OBJECT'S COORDINATES IN RELATION TO THE * * WORLD. IT IS ASSUMED THAT THE CURRENT COORDINATES * * ARE SCREEN RELATIVE. * * A0 = PTR TO THE OBJECT BLOCK * * * ************************************************************************** ADJSTWTL MMTM SP,A3,A5 MOVE @WORLDTLX,A5,L MOVE *A0(OXVAL),A3,L ADD A5,A3 MOVE A3,*A0(OXVAL),L MOVE @WORLDTLY,A5,L MOVE *A0(OYVAL),A3,L ADD A5,A3 MOVE A3,*A0(OYVAL),L MMFM SP,A3,A5 RETS ************************************************************************** * * * ADJNEWTL - ADJUST AN OBJECT TO A NEW SET OF X,Y WORLD COORDINATES * * BEFORE THEY ARE STORED(TAKE EFFECT). * * NOTE: CURRENT OBJECT COORDS. MUST BE ABSOLUTE WORLD. * * A0 = PTR TO OBJECT * * A4 = NEW WTLX, 32 BITS * * A5 = NEW WTLY, 32 BITS * * * ************************************************************************** ADJNEWTL MMTM SP,A1,A2 CALLR GSCRNREL ;SCREEN RELATIVE PLEASE ADD A4,A1 ADD A5,A2 ;ADJUST MOVE A1,*A0(OXVAL),L MOVE A2,*A0(OYVAL),L ;STORE MMFM SP,A1,A2 RETS ************************************************************************** * * * GSCRNREL - GET THE SCREEN RELATIVE X,Y COORDINATES OF AN OBJECT * * IT IS ASSUMED THATE THE CURRENT X,Y COORDINATES ARE * * WORLD ABSOLUTE. * * A0 = PTR TO THE OBJECT BLOCK * * RETURNS * * A1 = X SCREEN RELATIVE, 32 BITS * * A2 = Y SCREEN RELATIVE, 32 BITS * * * ************************************************************************** GSCRNREL PUSH A5 MOVE @WORLDTLX,A5,L MOVE *A0(OXVAL),A1,L SUB A5,A1 MOVE @WORLDTLY,A5,L MOVE *A0(OYVAL),A2,L SUB A5,A2 PULL A5 RETS ************************************************************************** * * * SCRNRELV - MAKE THE X & Y VELOCITIES OF AN OBJECT RELATIVE TO THE * * SCREEN. IN OTHER WORDS, ADJUST THEM SO THAT THE CURRENT * * SCROLL RATE DOESN'T AFFECT THEM. * * A0 = PTR TO OBJECT * * * ************************************************************************** SCRNRELV MMTM SP,A1,A5 MOVE @SCROLLX,A5,L MOVE *A0(OXVEL),A1,L ADD A5,A1 MOVE A1,*A0(OXVEL),L MOVE @SCROLLY,A5,L MOVE *A0(OYVEL),A1,L ADD A5,A1 MOVE A1,*A0(OYVEL),L MMFM SP,A1,A5 RETS ************************************************************************** * * * GANISAG - ADJUST CURRENT OBJECT IMAGE WITH RESPECT TO IT'S * * ANIMATION PNT. AND FLIP FLAGS * * NOTE: CALL ONLY AFTER INITIALIZING WITH STFOBJ, OR SOMETHING. * * A0 = PTR TO OBJECT BLOCK * * A2 = NEW OYVAL * * A3 = NEW OXVAL * * A4 = NEW FLAGS * * RETURNS * * A2 = ADJUSTED OYVAL * * A3 = ADJUSTED OXVAL * * * ************************************************************************** GANISAG MMTM SP,A1,A4,A6,A7 MMTM SP,A2,A3 MOVE *A0(OIMG),A1,L CALLR GSAGOF MOVE A3,*A0(OSAG),L MOVE A2,*A0(OSIZE),L MOVE A4,*A0(OFLAGS),L CALLR GANIOF MMFM SP,A2,A3 SUB A6,A3 SUB A7,A2 ;ADJUST UPPER LEFT CORNER MOVE A3,*A0(OXVAL),L MOVE A2,*A0(OYVAL),L MMFM SP,A1,A4,A6,A7 RETS * *START AN OBJECT *A0=OXVAL *A1=OYVAL *A2=OIMG *A3=OZPOS *A4=OFLAGS *A5=OID *A6=XVEL *A7=YVEL * STRTOBJ MMTM SP,A1,A2,A3,A4,A6,A7,A9,A10 MOVE A0,A9 ;SAVE X,Y MOVE A1,A10 MOVE A2,A1 ;SAVE OIMG MOVE *A1(ICMAP),A0,L ;GET THE PALETTE NAME CALLA GETFPAL ;GET A PALETTE MOVE A0,@CURPAL,W ;STUFF THIS IN CURRENT PAL CALLA GETOBJ MOVE A3,*A0(OZPOS),W MOVE A5,*A0(OID),W MOVE A6,*A0(OXVEL),L MOVE A7,*A0(OYVEL),L JRUC STFOBJ0 BEGINOBJ MOVE @WORLDTLX,A8,L ;ADJUST FOR WORLD COORD ADD A8,A0 MOVE @WORLDTLY,A8,L ADD A8,A1 BEGINOBJ2 CALLR STRTOBJ MOVE A13,*A0(OPLINK),L CALLA INSOBJ ;INSERT OBJECT INTO LIST MOVE A0,A8 RETS ************************************************************************** * * * STFOBJ - STUFF AN OBJECT USING AN INITIALIZATION TABLE * * A0 = PTR TO THE IMAGE * * A14 = PTR TO INIT. TABLE * * INIT. TABLE: * * .LONG OXVEL,OYVEL,OXVAL,XYVAL * * .WORD OZVEL,OZPOS * * .LONG OIMG,OZSIZ,OCVECT * * .WORD OFLAGS,OID * ; .LONG OXVAL,OYVAL,OIMG ; .WORD OZPOS,OFLAGS,OID ; .LONG OXVEL,OYVEL,OCVECT * RETURNS * * A14 = POINTING TO WORD AFTER INIT TAB * * * ************************************************************************** ;STFOBJ ; MMTM SP,A1,A2,A3,A4,A6,A7,A9,A10 ; ; MOVE *A14+,A1,L ;XVEL ; MOVE A1,*A0(OXVEL),L ; MOVE *A14+,A1,L ;YVEL ; MOVE A1,*A0(OYVEL),L ; ; MOVE *A14+,A9,L ;XVAL ; MOVE *A14+,A10,L ;YVAL ; ; MOVE *A14+,A1,L ;ZVEL:ZPOS ; ; CLR A2 ;SPLIT UP OZPOS:OZVEL ; MOVY A1,A2 ; SLL 16,A1 ; MOVE A1,*A0(OZVEL),L ; MOVE A2,*A0(OZVAL),L ; ; MOVE *A14+,A1,L ;IMG ; MOVE A1,*A0(OIMG),L ; MOVE *A14+,A2,L ;ZSIZE ; MOVE A2,*A0(OZSIZ),L ; MOVE *A14+,A2,L ;CVECT ; MOVE A2,*A0(OCVECT),L ; MOVE *A14+,A4,W ;FLAGS ; MOVE *A14+,A2,W ;OID ; MOVE A2,*A0(OID),W ; ; MOVE @CURPAL,A2,W ;OCONST:OPAL ; MOVE A2,*A0(OPAL),W ; ; CALLR GSAGOF ; CALLR GANIOF ;ADJUST ANIMATION OFFSET ; SUB A6,A9 ;SUBTRACT X ANIOFF ; SUB A7,A10 ;SUBTRACT Y ANIOFF ; MOVE A9,*A0(OXVAL),L ; MOVE A10,*A0(OYVAL),L ; MOVE A1,*A0(OIMG),L ; MOVE A3,*A0(OSAG),L ; MOVE A2,*A0(OSIZE),L ; MOVE A4,*A0(OFLAGS),L ; MMFM SP,A1,A2,A3,A4,A6,A7,A9,A10 ; RETS STFOBJ MMTM SP,A1,A2,A3,A4,A6,A7,A9,A10 MOVE *A14+,A9,L ;XVAL MOVE *A14+,A10,L ;YVAL MOVE *A14+,A1,L ;IMG (A1) MOVE *A14+,A2,W ;ZPOS MOVE A2,*A0(OZPOS),W MOVE *A14+,A4,W ;FLAGS (A4) MOVE *A14+,A2,W ;OID MOVE A2,*A0(OID),W MOVE *A14+,A2,L ;XVEL MOVE A2,*A0(OXVEL),L MOVE *A14+,A2,L ;YVEL MOVE A2,*A0(OYVEL),L ; MOVE *A14+,A2,L ;CVECT ; MOVE A2,*A0(OCVECT),L STFOBJ0 MOVE @CURPAL,A2,W ;OCONST:OPAL MOVE A2,*A0(OPAL),W CALLR GSAGOF CALLR GANIOF ;ADJUST ANIMATION OFFSET SUB A6,A9 ;SUBTRACT X ANIOFF SUB A7,A10 ;SUBTRACT Y ANIOFF MOVE A9,*A0(OXVAL),L MOVE A10,*A0(OYVAL),L MOVE A1,*A0(OIMG),L MOVE A3,*A0(OSAG),L MOVE A2,*A0(OSIZE),L MOVE A4,*A0(OFLAGS),L MMFM SP,A1,A2,A3,A4,A6,A7,A9,A10 RETS * *GET SAG FOR OBJECT - ADJUSTS SAG FOR FLIP *CALLING PARAMETERS: *A1=PTR TO IMAGE HEADER (OIMG) *A4=OBJECT FLAGS *RETURNS: *A2=RETURNED WITH NEW OSIZE *A3=RETURNED WITH NEW SAG *A4=RETURNED WITH NEW OFFSET:OFLAGS * BKGSAGOF: MMTM SP,A5,A6,A7 MOVE *A1(ISAG->20),A3,L ;GET TOP LEFT SAG (-20 -> no ani off) JRUC GSAGOF_G GSAGOF: MMTM SP,A5,A6,A7 MOVE *A1(ISAG),A3,L ;GET TOP LEFT SAG GSAGOF_G: ZEXT A4,W ;ZERO OFFSET IN A4 MOVE *A1(ISIZE),A2,L CLR A5 MOVX A2,A5 ADDK 3,A5 ;ADJUST HOR SIZE FOR MORSEL SRL 2,A5 SLL 2,A5 MOVX A5,A2 SLL 3,A5 ;ADJUST FOR BYTE ADDRESS *HORIZONTAL FLIP CASE GSAGH: BTST B_FLIPH,A4 JREQ GSAGV ;NO H FLIP, TRY VERT FLIP MOVE A5,A6 SUBK 8,A6 ADD A6,A3 ;ADD THS-1 TO SAG MOVX A2,A6 SLL 1,A6 DEC A6 ;2*THS-1 TO OFFSET SLL 16,A6 ;ADJUST FOR B16-31 ADDXY A6,A4 *VERTICAL FLIP CASE GSAGV: BTST B_FLIPV,A4 JREQ GSAGX ;NO VERT FLIP MOVY A2,A6 ;GET HEIGHT SRL 16,A6 DEC A6 ;FIRST ENTRY LAST ROW MOVE A5,A7 ;GET THS MPYS A6,A7 ;THS*(TVS-1) ADD A7,A3 ;ADD TO SAG MOVX A2,A6 SLL 1,A6 NEG A6 ;-2*THS SLL 16,A6 ;ADJUST FOR B16-31 ADDXY A6,A4 ;ADD TO OFFSET GSAGX: MMFM SP,A5,A6,A7 RETS ************************************************************************** * * * ANI - ANIMATION SUBROUTINE * * A1=NEW IMAGE POINTER * * A4=NEW OFLAGS * * A8=OBJECT STRUCTURE POINTER TO BE UPDATED * * * ************************************************************************** ANI: MMTM SP,A0,A2,A3,A4,A5,A6,A7,A9 ANIG .IF DEBUG CMPI 0FFC00000H,A1 ;FFE .ELSE CMPI 0FFE00000H,A1 ;FFE .ENDIF ; CMPI >FFC00000,A1 ;CHECK FOR BOGUS IMAGE ;FFE JRHS ANIG0 .IF DEBUG LOCKUP EINT .ELSE CALLERR 2,8 .ENDIF JRUC ANIGX ANIG0 MOVE *A8(OFLAGS),A5,W MOVE *A8(OIMG),A3,L CMP A1,A3 JRNE ANIG1 ;BR = NOT THE SAME IMAGE AS LAST TIME ZEXT A4 ZEXT A5 CMP A4,A5 JREQ ANIGX ;BR = EVERY THING IS THE SAME ANIG1 SWAP A4,A5 SWAP A1,A3 MOVE *A8(OSIZE),A2,L CALLR GANIOF ;GET OLD ANIMATION OFFSET MMTM SP,A6,A7 MOVE A5,A4 ;NEW OFLAGS MOVE A3,A1 ;NEW OIMG CALLR GSAGOF ;GET SAG, OFFSET, HW CALLR GANIOF ;GET NEW ANIMATION OFFSET MMFM SP,A0,A5 ;BRING BACK OLD ANIMATION DELTA SUB A6,A0 ;SUBTRACT NEW FROM OLD SUB A7,A5 MOVE A8,A9 ;GET PUSH ADDRESS OF OFLAGS,OSAG,OSIZE ADDI OFLAGS+>60,A9 CLR A7 MOVE A7,*A8(OXCLIP),W ;CLEAR PRECLIP MMTM A9,A2,A3,A4 ;BLOW THIS STUFF OUT MOVE A1,*A8(OIMG),L MOVE *A8(OYVAL),A6,L ADD A5,A6 ;ADJUST OYVAL, OXVAL FOR DELTA X MOVE A6,*A8(OYVAL),L MOVE *A8(OXVAL),A7,L ADD A0,A7 MOVE A7,*A8(OXVAL),L ANIGX MMFM SP,A0,A2,A3,A4,A5,A6,A7,A9 RETS ************************************************************************** * * * GETANIXY - GET THE X AND Y POSITIONS OF AN OBJECTS ANIMATION * * POINT. * * A8 = OBLOCK PTR. * * RETURNS * * A2 = APOINT OYVAL, 32 BITS * * A3 = APOINT OXVAL, 32 BITS * * * ************************************************************************** GETANIXY MMTM SP,A1,A4,A6,A7 MOVE *A8(OIMG),A1,L MOVE *A8(OSIZE),A2,L MOVE *A8(OFLAGS),A4,W CALLR GANIOF MOVE *A8(OXVAL),A3,L MOVE *A8(OYVAL),A2,L ADD A6,A3 ADD A7,A2 MMFM SP,A1,A4,A6,A7 RETS * *GET ANIMATION OFFSET *A1=OIMG, A2=H:W, A4=OFLAGS * *OUTPUT: *A6=X ANIMATION OFFSET X 64K *A7=Y ANIMATION OFFSET X 64K GANIOF: MMTM SP,A2,A3 MOVE *A1(IANIOFF),A6,L CMPI IROM,A6 JRLT GANIOF_OK CLR A6 GANIOF_OK: CLR A7 ;MAKE SURE A7 IS 0 MOVY A6,A7 SLL 16,A6 ;MOVE TO UPPER WORD SUBI >00010001,A2 ;ADJUST FOR -1 CLR A3 MOVY A2,A3 SLL 16,A2 ;MOVE TO UPPER WORD BTST B_FLIPH,A4 JRZ GANI1 NEG A6 ADD A2,A6 ;SUB THS-1 FOR H-FLIP GANI1: BTST B_FLIPV,A4 JRZ GANI2 NEG A7 ADD A3,A7 ;SUB TVS-1 FOR V-FLIP GANI2: MMFM SP,A2,A3 RETS .END