smashtv/NDSP1.ASM

1681 lines
40 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

.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