smashtv/NDSP1.ASM

1681 lines
40 KiB
NASM
Raw Normal View History

2021-04-06 15:09:56 -07:00
.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