revolution-x/GXBGND.ASM

1117 lines
26 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.

.MLIB "GXMACS.LIB"
.FILE "GXBGND.ASM"
.TITLE " <<< GENERATION X -- BACKGROUND MAINTENANCE >>>"
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
**************************************************************************
* *
* COPYRIGHT (C) 1992 MIDWAY MANUFACTURING COMPANY. *
* ALL RIGHTS RESERVED. *
* *
**************************************************************************
.INCLUDE "GX.INC"
;*** EXTERNAL GLOBAL SYMBOLS
.ref BAKPLANE,BAKTL,BAKBITS,BAKMODS
;*** GLOBAL SYMBOLS IN THIS FILE
.def BGND_UD1,BAK_STRT,BAK_END,CLRBBIT
.IF IMGBGND
.def InitBTbl,DnLdMods
.ENDIF
************* Local Constants for UPD **************
DISP_PAD .set 00300030h ; Y:X
WIDEST_BLOCK .set 250
;* Must keep the size of these structures a multiple of 16
map_zflagspal .set 0
map_pal .set 0 ;size 4 - palette select
map_flags .set 4 ;size 4 - bit 0 hflip, bit 1 yflip
map_z .set 8 ;size 8
map_x .set 16 ;size 16
map_y .set 32 ;size 16
map_hdr .set 48 ;size 16 - offset in long words from block_hdr_tbl
; bits 12-15 are bits 4-7 of pal
; map_hdr set to 0FFFFh if block is not allocated
block_size .set 64 ;* if changed must get rid of shifts by 6
;* Offsets for a BLOCK HDR structure
map_size .set 0
map_w .set 0 ;size 16 ; These fields can't be changed
map_h .set 16 ;size 16 ; because they are used as the
map_animoff .set 32 ;size 32 ; OIMG block header
map_dataptr .set 64 ;size 32 ;
block_hdr_size .set 96
BSIZE .set 0
BSAG .set 20h
BCTRL .set 40h
;* Offsets for a MODULE definition
.IF IMGBGND
mod_w .set 0 ;UHW width of module
mod_h .set 010h ;UHW height of module
mod_blkct .set 020h ;UHW # blocks in module
mod_bindx .set 030h ;UHW index into BLKTBLPTRS
mod_hindx .set 040h ;UHW index into HDRTBLPTRS
mod_pals .set 050h ;UHL ptr to table of pals
.ELSE
mod_w .set 0 ;UHW width of module
mod_h .set 010h ;UHW height of module
mod_blkct .set 020h ;UHW # blocks in module
mod_blks .set 030h ;UHL ptr to BLOCKS
mod_hdrs .set 050h ;UHL ptr to HDRS
mod_pals .set 070h ;UHL ptr to table of pals
.ENDIF
MAXHDRTBLS .set 50
MAXBLKTBLS .set 200
BGNDTBLWORDS .set 1000*4+150*4
;1000 Block table entries + 150 Block Headers
.IF IMGBGND
.ref BLKTBLPTRS,HDRTBLPTRS
.BSS TMPWORD,010h
.BSS BgdTIndx,020h
.BSS HdrTPtrs,MAXHDRTBLS*020h
.BSS BlkTPtrs,MAXBLKTBLS*020h
.BSS BgndTbls,BGNDTBLWORDS*010h
.BSS BgndTblX,0
.ENDIF
************************************************************************
BGNDHGHT:
;Parms A0 - XPOS for which height of BackGround needs to be determined
;Returns A0 -
; Minimum YPOS (max height) of PRIMARY background which overlaps
; specified XPOS
; A0 = 0 if XPOS is invalid
;* Scan a Module list to find out which module contains blocks
;* which need to be checked
mmtm SP,A1,A2,A3,A4,A7,A8,A9,A10,A11
move A0,A1
clr A10 ;init packed y:x starting position
clr A11
move @BAKMODS,A0,L ;* A0- ptr to the module list
ModLp0:
move *A0+,A8,L ;load module ptr
cmpi 0FFFFFFFFh,A8
jrz ModX0 ;end of the module tbl
move *A8+,A9,L ;load packed y:x size
move *A0+,A3,W ;X start position
zext A3,W
cmpi BLSTSTRT,A3
jrnz NotLstStrtX
move A11,A3
subxy A9,A3
jruc GotNewX0
NotLstStrtX:
cmpi BLSTEND,A3
jrnz GotNewX0
move A11,A3
GotNewX0:
move *A0+,A4,W ;Y start position
zext A4,W
cmpi BLSTSTRT,A4
jrnz NotLstStrtY
move A11,A4
subxy A9,A4
jruc GotNewY0
NotLstStrtY:
cmpi BLSTEND,A4
jrnz NotLstEndY
move A11,A4
jruc GotNewY0
NotLstEndY:
sll 16,A4
GotNewY0:
movy A4,A3
move A3,A10
; cmpxy A10,A1
; jrv ModX0 ;jump to exit loop if Mod start X > X sought
;if Mod end X < X sought keep searching mod list
move A10,A11
addxy A9,A11 ;A11 is module y:x end
move *A8+,A9,W ;load # of blocks
add A9,A7 ;A7 is new BAKBITS ptr
cmpxy A11,A1
jrnv ModLp0 ;skip if Ax < Bx
move A10,A0
srl 16,A0
jruc GotHGHT
ModX0:
clr A0
GotHGHT:
mmfm SP,A1,A2,A3,A4,A7,A8,A9,A10,A11
rets
************************************************************************
**************************** BSrch1stXB ********************************
BSrch1stXB:
;*** PARMS
; A0 - x coordinate of a block
; A1 - Start of background block table
; A2 - end of block table
;*** Returns
; A0 - address of first block with x coordinate >= parm
; if new x is highest returns next empty block
; if no blocks with >= X, return 0
;* A0 = X val being searched for
;* A1 = Block Table Base + offset to X val
;* A14 - Threshhold for switching from binary to linear search
;* A9 = Low # -- # greatest background block
;* A10 = Mid # -- (High + Low) >> 1
;* A2 = High # -- # of lowest background block
mmtm SP,A1,A2,A8,A9,A10
clr A9 ;* set low = 0
sub A1,A2
srl 6,A2 ;* div by size of block (64)
addi map_x,A1 ;* block tbl base + X offset
movk 5,A14 ;* threshhold for switching from binary to linear search
BSRCH:
move A2,A10
sub A9,A10 ;* if (high - low) <= 5 finish with linear search
cmp A14,A10
jrle LSRCH
srl 1,A10
add A9,A10
;* get mid->x
move A10,A8
sll 6,A8 ;* multiply by block size (64)
add A1,A8
move *A8,A8,W ;* get x coor of the block
cmp A0,A8
jrlt Blow
move A10,A2 ;* high = mid
jruc BSRCH
Blow:
move A10,A9 ;* low = mid
jruc BSRCH
LSRCH:
;* finish with a linear search of block table from low to high
;* ending with first block x coor that is >= A0
;* A0 = X val being searched for
;* A9 = Low Address -- pts to X offset of block
;* A2 = High Address -- pts to X offset of block
sll 6,A9 ;* low block # to low block offset
sll 6,A2 ;* high block # to high block offset
add A1,A9
add A1,A2
movi block_size,A8
LSRCHLP:
move *A9,A10,W ;* X coor
cmp A0,A10
jrge GotB ;* if low->x >= A0 goto found
add A8,A9
cmp A2,A9
jrle LSRCHLP
;* block not found, return 0
clr A0
jruc BSrchDone
GotB:
;* return a ptr to the block
move A9,A0
subi map_x,A0
BSrchDone:
mmfm SP,A1,A2,A8,A9,A10
rets
**************************** BSrch1stXB ********************************
*********************** BAK END *******************************
;* Scan a Module list and return the packed Y:X end point
;PARMS
;A0 - Module list
;RETURNS
;A0 - PACKED Y:X end of wave
BAK_END:
mmtm SP,A3,A4,A8,A9,A10,A11
clr A10 ;clr packed y:x starting position
clr A11
WEModLp:
move *A0+,A8,L ;load module ptr
cmpi 0FFFFFFFFh,A8
jrz WEModX ;end of the module tbl
move *A8+,A9,L ;load packed y:x size
move *A0+,A3,W ;X start position
zext A3,W
cmpi BLSTSTRT,A3
jrnz WENotLastStartX
move A11,A3
subxy A9,A3
jruc WEGotNewX
WENotLastStartX:
cmpi BLSTEND,A3
jrnz WEGotNewX
move A11,A3
WEGotNewX:
move *A0+,A4,W ;Y start position
zext A4,W
cmpi BLSTSTRT,A4
jrnz WENotLastStartY
move A11,A4
subxy A9,A4
jruc WEGotNewY
WENotLastStartY:
cmpi BLSTEND,A4
jrnz WENotLastEndY
move A11,A4
jruc WEGotNewY
WENotLastEndY:
sll 16,A4
WEGotNewY:
movy A4,A3
move A3,A10
move A10,A11
addxy A9,A11 ;A11 is module y:x end
jruc WEModLp
WEModX:
move A11,A0
mmfm SP,A3,A4,A8,A9,A10,A11
rets
***********************************************************************
*********************** BAK START *******************************
;* Scan a Module list and return the packed Y:X starting point
;PARMS
;A0 - Module list
;RETURNS
;A0 - PACKED Y:X start of wave
BAK_STRT:
mmtm SP,A3,A4,A8,A9,A11
clr A11
move *A0+,A8,L ;load module ptr
cmpi 0FFFFFFFFh,A8
jrz WSModX ;end of the module tbl
move *A8+,A9,L ;load packed y:x size
move *A0+,A3,W ;X start position
zext A3,W
cmpi BLSTSTRT,A3
jrnz WSNotLastStartX
move A11,A3
subxy A9,A3
jruc WSGotNewX
WSNotLastStartX:
cmpi BLSTEND,A3
jrnz WSGotNewX
move A11,A3
WSGotNewX:
move *A0+,A4,W ;Y start position
zext A4,W
cmpi BLSTSTRT,A4
jrnz WSNotLastStartY
move A11,A4
subxy A9,A4
jruc WSGotNewY
WSNotLastStartY:
cmpi BLSTEND,A4
jrnz WSNotLastEndY
move A11,A4
jruc WSGotNewY
WSNotLastEndY:
sll 16,A4
WSGotNewY:
movy A4,A3
move A3,A0
WSModX:
mmfm SP,A3,A4,A8,A9,A11
rets
***********************************************************************
**************** U P D A T E D I S P L I S T **********************
;* deletes all display objects which are not on the screen
;* insures all background blocks on screen are on the disp list
BGND_UD1: ;* call to update main background
;* input, SCRNTL, SCRNBR, BAKBITS, BAKMODS
; BAKTL, BAKPLANE
; A8-PLANE PTR
;* this protects DISP_MOD and DISP_DEL TOO!
; mmtm SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
; mmtm SP,B0
mmtm SP,A8,A9,A10,A11,A12,A13
move A8,B0 ;B0 - plane ptr
;* Get coors of area to be put on display list.
move @BAKTL,A3,1
move A3,A4
move @SCRNTL,A0,1
addxy A0,A3
move @SCRNBR,A0,1
addxy A0,A4
movi DISP_PAD,A0
subxy A0,A3 ;A3 - disp_tl
addxy A0,A4 ;A4 - disp_lr
callr DSP_DEL ;SCREEN DOESN'T WRAP MAX/MIN DISCONTINUITY
AddEm:
;* determine which module
move @BAKMODS,A0,L ;A0- ptr to the module list
move @BAKBITS,A7,L ;A7 - bit table for block being on disp list
callr DISP_MOD
mmfm SP,A8,A9,A10,A11,A12,A13
; mmfm SP,B0
; mmfm SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
rets
***********************************************************************
*********************** D I S P M O D *******************************
;* Scan a Module list to find out which modules contain blocks
;* which need to be checked for addition to the display list.
; B0 - plane ptr
; A0 - Module list
; A3 - disp_tl
; A4 - disp_lr
; A7 - BAKBITS ;A7 - bit table for block being on disp list
;PARMS For DISP_ADD
; A1 - Background Block table
; A2 - End of Background Block table
; A5 - Background hdr table
; A9 - Module Start Position Y:X
; A10 - ptr to palette table for new block
; ;passed from above
; A3 - disp_tl
; A4 - disp_lr
; A6 - which bakground insert routine primary|secondary
; A7 - bit table for block being on disp list
;* caller is responsible for pushing and popping all A-registers
DISP_MOD:
mmtm SP,A0,A3,A4,A7
clr A9 ;init y:x starting position
clr A11 ;ending y:x pos
move A7,A6 ;A6 will point to BakBits after Mod
ModLp:
SkDAdd:
move A6,A7
move *A0+,A8,L ;load module ptr
cmpi 0FFFFFFFFh,A8
jrz ModX ;end of the module tbl
move *A8+,A10,L ;load y:x size
move *A0+,A14,W ;X start position
zext A14,W
cmpi BLSTSTRT,A14
jrnz NotLastStartX
move A11,A14
subxy A10,A14
jruc GotNewX
NotLastStartX:
cmpi BLSTEND,A14
jrnz GotNewX
move A11,A14
GotNewX:
move *A0+,A5,W ;Y start position
zext A5,W
cmpi BLSTSTRT,A5
jrnz NotLastStartY
move A11,A5
subxy A10,A5
jruc GotNewY
NotLastStartY:
cmpi BLSTEND,A5
jrnz NotLastEndY
move A11,A5
jruc GotNewY
NotLastEndY:
MOVE @HORIZON_BASE,A9,W ;GET THE HORIZON LINE
ADD A9,A5 ;ADD IT TO THE GIVEN OFFSET
sll 16,A5
SUBXY A10,A5 ;SUBTRACT HEIGHT OF THIS MODULE
GotNewY:
movy A5,A14
move A14,A9
move A9,A11
addxy A10,A11 ;A11 is module y:x end
move *A8+,A10,W ;load # of blocks
add A10,A6 ;A6 is new BAKBITS ptr
move A9,B1
move A4,B2
sext B1,W
sext B2,W
cmp B1,B2
jrle ModX ;jump to exit loop if Mod start X > Screen End X
cmpxy A9,A4
; jrxle ModX ;jump to exit loop if Mod start X > Screen End X
jrylt SkDAdd ;skip if Mod Y Start > BR Y
move A3,B1
move A11,B2
sext B1,W
sext B2,W
cmp B1,B2
jrlt SkDAdd ;jump to exit loop if Mod start X > Screen End X
cmpxy A3,A11
; jrxlt SkDAdd ;skip if Mod X End < TL X
jrylt SkDAdd ;skip if Mod Y End < TL Y
; cmpxy A9,A4
; jrxlt SkDAdd ;use this if modules aren't sorted left to right
;jump to if Mod start X > Screen End X
; jrylt SkDAdd ;skip if Mod Y Start > BR Y
.IF IMGBGND
move *A8+,A1,W ;A1-index into block ptr table
sll 5,A1
addi BlkTPtrs,A1
move *A1,A1,L
.ELSE
move *A8+,A1,L ;A1-ptr to block table
.ENDIF
move A10,A2
sll 6,A2 ;each block is 4 words long
add A1,A2 ;A2-block table end
.IF IMGBGND
move *A8+,A5,W ;A5-index into hdr ptr table
sll 5,A5
addi HdrTPtrs,A5
move *A5,A5,L
.ELSE
move *A8+,A5,L ;A5-Hdrs
.ENDIF
move *A8+,A10,L ;A10-Pal tbl
subxy A9,A3
subxy A9,A4
callr DISP_ADD
addxy A9,A3
addxy A9,A4
jruc ModLp
ModX:
mmfm SP,A0,A3,A4,A7
rets
***********************************************************************
*********************** D I S P A D D *******************************
;* This function adds all module blocks in the given range of Module
;* relative coors to the display list.
;* The boundries are included in the group to add.
DISP_ADD:
;*** PARMS:
; B0 - plane ptr
; A5 - Background hdr table
; A7 - bit table for block being on disp list
; A9 - Module Start Position Y:X
; A10 - ptr to palette table for new block
; A1 - Background Block table
; A2 - End of Background Block table
; A3 - disp_tl - relative to the Module start POS
; A4 - disp_lr - "
;*** RETURNS nothing
;thrashes A1,A14
mmtm SP,A0,A6,A7,A8,A11
;* Find first universe block with an X coor >= A9
movx A3,A0
sext A0,W
subi WIDEST_BLOCK,A0
;A0 - x coordinate of a block
;A1 - Start of background block table
;A2 - end of block table
callr BSrch1stXB
;A0 is now the address of a block
jrz DADONE ;* no blocks with gtr Xcoor
movi block_size,A6
move A0,A8
sub A1,A8 ;* subtract off start of table
srl 6,A8 ;* divide by block size (64)
add A7,A8 ;* A8 - ptr to bit which indicates block on list
subk 8,A8 ;* after inc A8, use movb *A8 to load sign bit
sub A6,A0 ;subtract block size
BScanLP0:
inc A8
add A6,A0 ;* get next block
;* check if there are no more bgnd blocks
cmp A2,A0
jrge DADONE
;* if block already on display list try again
movb *A8,A11
jrn BScanLP0
;* check if x to big
move *A0(map_x),A11,W
cmpxy A3,A11
jrxge BScan1 ;* Jump if BlockX >= TL X
;* load map header
move *A0(map_hdr),A14,W
sll 20,A14 ;* only want bottom 12 bits, top 4 are pal bits
srl 14,A14 ;* leaves B9 << 5 == double long word offset
MOVE A14,A1
add A5,A14 ;* A14 now almost points to block header
SRL 2,A1 ;We must add another word
ADD A1,A14 ;* A14 now points to block header
;* check if right end of block hangs onto screen
move *A14,A1,W ;A1 is now the width of the block
add A11,A1
cmpxy A3,A1 ;* right end of block doesn't hang on to screen
jrxlt BScanLP0 ;* jump if Block X+W < TL X
;* if ycoor to big try again
move *A0(map_y),A1,0
sll 16,A1
cmpxy A1,A4
jrylt BScanLP0 ;* Jump if Block Y > BR Y
;* if ycoor+height to small try again
move *A14(map_h),A11,0
sll 16,A11
add A11,A1
cmpxy A3,A1
jrylt BScanLP0 ;* Jump if Block Y+H < TL Y
move A0,A7
callr ADDBLOCK ;Thrashes A1,A14
jrnc BScanLP0
jruc DADONE ;* was unable to add block - no blocks left
BScan1:
dec A8 ;* bit ptr for block on disp list
sub A6,A0 ;subtract off block size
BScanLP1:
inc A8
add A6,A0 ;Get next block
;* check if there are no more bgnd blocks
cmp A2,A0
jrge DADONE
;* if block already on display list try again
movb *A8,A11
jrn BScanLP1
;* if ycoor to big try again
move *A0(map_y),A1,W
sll 16,A1
cmpxy A1,A4
jrylt BScanLP1 ;* Jump if Block Y > BR Y
;* if ycoor+height to small try again
move *A0(map_hdr),A14,W
sll 20,A14 ;* only want bottom 12 bits, top 4 are pal bits
srl 14,A14 ;* leaves A14 << 6 == double long word offset
MOVE A14,A11
add A5,A14 ;* A14 now almost points to block hdr
SRL 2,A11 ;We must add another word
ADD A11,A14 ;* A14 now points to block hdr
move *A14(map_h),A11,W
sll 16,A11
add A11,A1
cmpxy A3,A1
jrylt BScanLP1 ;* Jump if Block Y+H < TL Y
;* if xcoor to big quit
move *A0(map_x),A1,W
cmpxy A1,A4
jrxlt DADONE ;* Jump if Block X > BR X
move A0,A7
callr ADDBLOCK
jrnc BScanLP1
DADONE:
mmfm SP,A0,A6,A7,A8,A11
rets
***********************************************************************
***********************************************************************
ADDBLOCK:
;* PARMS
; B0 - plane ptr
; A5 - base of background block hdr
; A7 - ptr to background block
; A8 - ptr to bit map for block on disp list
; A9 - Module Start Position Y:X
; A10 - ptr to palette table for new block
;* Returns carry set if GETOBJ fails...
;* Also Destroys A1,A14 but they are used as temps in DISP_ADD
mmtm SP,A0,A2,A3,A4,A5,A6,A7,A8
calla GETOBJ
jrz ADDX
;* set bit in bitmap for block on list
movb *A8,A14
ori 080h,A14
movb A14,*A8
move A8,*A0(OPLINK),L ;set OPLINK to be a ptr to the disp list bit
MOVE B0,A1 ;Grab the plane ptr
MOVE *A1(P_YPOS),A3,L
MOVE *A1(P_XPOS),A14,L
SRL 16,A14
MOVX A14,A3 ;WORLD TOP LEFT [Y,X]
move *A7(map_x),A1,L ;A1 ypos:xpos of block from Mod Base
addxy A9,A1 ;Add in Module Base Position
MOVE A1,A6 ;TEMP COMBINATION FOR THE DAG-SKI
SUBXY A3,A6 ;DAG is correct for initial viewing
move A1,*A0(OXPOS),W
srl 16,A1
move A1,*A0(OYPOS),W
move *A7(map_zflagspal),A4,W ;A4 - map_z,8:map_flags,4:map_pal,4
move A4,A3
srl 8,A3
sll 24,A3
srl 8,A3
move @ZBASE,a14,L
add a14,a3
move A3,*A0(OZVAL),L
move *A7(map_hdr),A1,W
movx A1,A14
sll 16,A14
srl 28,A14
sll 4,A14 ;* bits 12-15 are bits 4-7 of pal index
sll 20,A1 ;* bits 0-11 are hdr ptr;
srl 14,A1 ;* A1 = double long word offset into block hdr tbl
MOVE A1,A3
add A5,A1 ;* A1 = Almost ptr to header
SRL 2,A3 ;We must add another word for to make 50H
ADD A3,A1 ;Now we've got it
;A4 - map_z,8:map_DMA_flags,4:map_pal,4
move A4,A3
sll 28,A4 ;* last four bits for pal
srl 28,A4
add A14,A4
sll 5,A4 ;* A4 is lword ptr from pal tbl
add A10,A4 ;* add in pal tbl
move A0,A2 ;save A0
move *A4,A0,L ;* get palette
; calla GETBPAL
CALLA GETFPAL
jrnz BSetPal
clr A0
MOVE A0,A5
CALLA INC_PALCNT
BSetPal:
; move A0,*A2(OPAL),W
*GET FLIP BITS
movi 08002h,A8 ;08000h DMA GO, 2
srl 4,A3 ;* remove palette bits
sll 30,A3
jrc SKIP0 ;* carry bit is the transparency bit
addk 1,A8
SKIP0:
srl 26,A3 ;* line up flip h,v bits
add A3,A8 ;A8 - Flags for DMA OP
MOVE A0,A3
move A2,A0 ;restore A0
;just for now...
clr A2
move A2,*A0(OID),W
MOVE *A1(BSIZE),A5,L ;GRAB THE UNSCALED SIZE
MOVE A5,A4 ;MAKE IT THE SCALED SIZE ALSO
MOVE *A1(BCTRL),A14,W ;GET BPP AND COMPRESSION
OR A14,A8
MOVI 001000100H,A2 ;NEED THAT SCALE FACTOR
MOVE *A1(BSAG),A7,L ;GET THE STARTING ADDRESS
SLL 16,A8 ;A8 IS IN FULL CONTROL, BOYEEE!
*A1 = OIMG
*A2 = OSCALE
*A3 = OCONST:OPAL
*A4 = OSIZE
*A5 = OUSIZE
*A6 = ODAG
*A7 = OSAG
*A8 = OCTRL:OFSET
move A0,A14
addi OIMG+020h,A14
mmtm A14,A1,A2,A3,A4,A5,A6,A7,A8 ;STUFF IT ALL THE WAY IN
MOVIM M_SCRNOBJ,*A0(OFLAGS),W ;WE'LL WORK OUT HIS POSITION
MOVIM DUMRETS,*A0(OGUNVECT),L ;TEMPORARY GUN VECTOR FOR NOW
movb @BAKPLANE,A14
; movb A14,*A0(OPLANE) ;INSPLANE DOES NOT SET OPLANE
calla INSPLANE ;B0 plane ptr
clrc
MMFM SP,A0,A2,A3,A4,A5,A6,A7,A8
rets
ADDX: ;failure to get object
setc
MMFM SP,A0,A2,A3,A4,A5,A6,A7,A8
rets
**********************************************************************
**********************************************************************
CLRBBIT
;CLR THE BGND BLOCK BIT
mmtm SP,A0,A14
move *A8(OPLINK),A0,L
LOCKON Z
movb *A0,A14
andi 07Fh,A14
movb A14,*A0
clr A14
move A14,*A8(OPLINK),L
mmfm SP,A0,A14
rets
**********************************************************************
************************ D I S P D E L *****************************
;* This function deletes all objs outside the given range
;* of coors from the display list.
;* The boundries are not included in the group to delete.
;*** PARMS:
; A8 - bak list
; A3 - disp_tl
; A4 - disp_lr
;*** RETURNS nothing
;Thrashes A0,A1,A2,A5,A6,A7,A8,A9,A13,A14 ;all of which are pushed by caller
DSP_DEL:
;* USES SIGNED ARITHMETIC
;*** THE SCREEN WRAPS THE -/+ DISCONTINUITY
move A3,A13
sext A13,W
move A4,A2
sext A2,W
move A8,A5 ;A5 ptr to start of list
del_loop:
move A8,A9 ; ptr to PREV in A9
move *A9,A8,L ; ptr to NEXT in A8
cmp A8,A5
jreq del_done ;QUIT if at end of list
movb *A8(OFLAGS+B_BNODEL-7),A7
jrn del_loop
;if X > Xmax continue
move *A8(OXPOS),A7,W
cmp A7,A2
jrlt DEL_IT ;* jump if BR X < Block X
move *A8(OIMG),A1,L
move *a8(OIHOFF),a14 ; NEW
add a14,a1 ; NEW
;if X+width < Xmin continue
move *A1(map_w),A6,W ;A6 block width
add A6,A7
cmp A13,A7
jrlt DEL_IT ;* jump if TL X > Block X+W
;if Y > Ymax continue
move *A8(OYPOS),A0,W
sll 16,A0
cmpxy A0,A4
jrylt DEL_IT ;* jump if BR Y < Block y
;if Y+height < Ymin continue
move *A1(map_h),A7,0 ;A7 block height
sll 16,A7
add A7,A0
cmpxy A3,A0
jrylt DEL_IT ;* jump if TL Y > Block Y+H
jruc del_loop
DEL_IT: ;* DELETE the OBJ
;* unset the on display list bit
move *A8(OPLINK),A0,L
movb *A0,A7
andi 07Fh,A7
movb A7,*A0
CALLA ZAP_OBJ ;DO IT MULTI-STYLE
move A9,A8 ;A9- points to last obj
CMP A9,A5 ;Are we stuck at the head?
JRNE DEL_TRY_NEXT ;BR = No
MOVE *A9,A7,L ;Then get the next real object
CMP A7,A5 ;List empty?
JREQ del_done ;BR = Yes
MOVB *A7(OFLAGS+B_INUSE-7),A7 ;SOMETHING HAPPEN TO OBJECT?
JRN del_loop ;BR = no, everyting gonna be alright
JRUC del_done
DEL_TRY_NEXT
movb *A8(OFLAGS+B_INUSE-7),A7 ;SOMETHING HAPPEN TO OBJECT?
jrn del_loop ;BR = NO, KEEP GOING
del_done:
rets
.IF IMGBGND
************************************************************************
BLOWADR .set 254*010000h ;line 254 is a dead line that is not displayed
BLOWADD .set 254*01000h ;or used in any fashion..
ROMTORAM
*A0 - Start of image ROM memory to read
*A1 - Number of WORDs to read
*A2 - RAM target address
* rets A0 pointing right after the end
MMTM SP,A1,A2,A3,A4,A5,A6
MOVE A1,A1
JRZ WORMX
PUSHST
DINT
;*** SAVE THE STUFF
MOVE @DISPLAYON,A3,W
MOVE @GAMERASE,A4,W
; MOVE @NOPGFLIP,A5,W
MOVE @STARSON,A6,W
; MMTM SP,A3,A4,A5,A6
MMTM SP,A3,A4,A6
;*** SET THE STUFF
CLR A3
MOVE A3,@DISPLAYON,W
MOVE A3,@GAMERASE,W
; MOVK 1,A3
; MOVE A3,@NOPGFLIP,W
; PUSH A0
; CALLA SwapPgA
; PULLQ A0
CALLA DMAQWAIT ;ALLOW Q TO BE BLOWN
;A0 - ROM
;A1 - words to read
;A2 - RAM
NEXTWRM CMPI 127,A1 ;find out how much we should decode
JRGE REGDMP ;127 because 127*4 < 511 (max dma width)
MOVE A1,A4
JRUC IREGDMP
REGDMP MOVI 127,A4
IREGDMP SUB A4,A1 ;words remaining after this iteration
MOVE A4,A5
SLL 2,A5 ;WORD CT -> BYTE CT * 2 for YUNIT
MOVI BLOWADR,A3
MOVE A3,@DMAHORIZ,L ;set the destination
MOVE A5,@DMAHSIZE,W ;length of 2*#words to read (#bytes)
MOVK 1,A3
MOVE A3,@DMAVSIZE,W ;thickness of 1
MOVE A0,@DMASAGL,L ;set the origin
;DMACMAP is dont care
;DMACONST is dont care
CLR A3
MOVE A3,@DMAOFFST,W ;offset must be clear
MOVI DMAWAL,A3,W ;set control word
MOVE A3,@DMACTRL,W ;fire it off
MOVE A4,A5
SLL 5,A5 ;increment ROM ptr by length of last
ADD A5,A0 ;iteration (twice as long)
DMWTA MOVE @DMACTRL,A3,W ;wait for it to finish
JRN DMWTA
PUSH A0
MOVI BLOWADD,A0 ;get a new destination
WORMLP MOVE *A0+,A3,L
MOVE A3,A5 ;decode routine
ANDI 00Fh,A5
MOVE A3,A6
ANDI 0F00h,A6
OR A6,A5
MOVE A3,A6
SRL 12,A6
ANDI 00F0h,A6
OR A6,A5
SRL 12,A3
ANDI 0F000h,A3
OR A3,A5
MOVE A5,*A2+,W
DSJ A4,WORMLP ;decrement on amount decoded
PULL A0
MOVE A1,A1 ;do we still have words left?
JRGT NEXTWRM
;*** RESTORE THE LOST SOUL
; MMFM SP,A3,A4,A5,A6
MMFM SP,A3,A4,A6
MOVE A3,@DISPLAYON,W
MOVE A4,@GAMERASE,W
; MOVE A5,@NOPGFLIP,W
MOVE A6,@STARSON,W
POPST
WORMX
MMFM SP,A1,A2,A3,A4,A5,A6
RETS
************************************************************************
************************************************************************
InitBTbl:
mmtm SP,A0,A1,A2
;*** INITIALIZE BGNDTBL INDEX AND CLEAR OUT BLK+HDR PTR TABLES
movi BgndTbls,A0
move A0,@BgdTIndx,L
clr A1
movi HdrTPtrs,A0
movi MAXHDRTBLS,A2
ClrHdrs move A1,*A0+,L
dsjs A2,ClrHdrs
movi BlkTPtrs,A0
movi MAXBLKTBLS,A2
ClrBlks move A1,*A0+,L
dsjs A2,ClrBlks
mmfm SP,A0,A1,A2
rets
************************************************************************
************************************************************************
AlocBTbl:
;A1 # words -> A2 ptr to ram space alloced
PUSH A1
move @BgdTIndx,A2,L
sll 4,A1
add A2,A1
cmpi BgndTblX,A1
LOCKON GE
move A1,@BgdTIndx,L
PULLQ A1
rets
************************************************************************
************************************************************************
DnLdMod:
;A0 ptr to a MODULE
;DOWN LOADS from IMAGE ROM to RAM: HEADER TABLE, BLOCK TABLE
mmtm SP,A0,A1,A2,A3,A4,A5
move A0,A3
;**** CHECK TO DOWN LOAD THE HEADERS ****
move *A3(mod_hindx),A4,W
cmpi MAXHDRTBLS,A4
LOCKON GE
sll 5,A4
move A4,A5
addi HdrTPtrs,A5,L
move *A5,A2,L
jrnz SkLdHdrT ;IF HdrTPtr SET, HDRS ALREADY LOADED
addi HDRTBLPTRS,A4 ;hdr table pointers
move *A4,A0,L ;Get Ptr to hdr tbl in IMAGE ROM
movk 1,A1 ;JUST READ THE COUNT
movi TMPWORD,A2
callr ROMTORAM ;get total # of headers
move *A2,A1,W ;
;ALLOCATE SPACE IN BGNDTBLS
sll 2,A1 ;A HEADER IS 4 WORDS LONG
callr AlocBTbl ;A1 # words -> A2 ptr to ram space alloced
move A2,*A5,L ;STORE PTR TO RAM IN HdrTPtrs
callr ROMTORAM ;download the headers
SkLdHdrT
;**** CHECK TO DOWN LOAD THE BLOCKS ****
move *A3(mod_bindx),A4,W
cmpi MAXBLKTBLS,A4
LOCKON GE
sll 5,A4
move A4,A5
addi BlkTPtrs,A5,L
move *A5,A2,L
jrnz SkLdBlkT ;IF BlkTPtr SET, HDRS ALREADY LOADED
addi BLKTBLPTRS,A4 ;block table pointers
move *A4,A0,L ;Get Ptr to blk tbl IMAGE ROM
;ALLOCATE SPACE IN BGNDTBLS
move *A3(mod_blkct),A1,W
sll 2,A1 ;A BLOCK IS 4 WORDS LONG
callr AlocBTbl ;A2 # words -> A2 ptr to ram space alloced
move A2,*A5,L ;STORE PTR TO RAM IN HdrTPtrs
callr ROMTORAM ;download the headers
SkLdBlkT
mmfm SP,A0,A1,A2,A3,A4,A5
rets
************************************************************************
DnLdMods:
;A0 ptr to a MODULE LIST
;* find end of module list
mmtm SP,A0,A1
move A0,A1
DnLdLp:
move *A1,A0,L
cmpi -1,A0 ;looking for 0FFFFFFFFh
jreq DLModsX
callr DnLdMod
addi 64,A1 ;Look at next Module
jruc DnLdLp
DLModsX
mmfm SP,A0,A1
rets
************************************************************************
.ENDIF
.END