nba-jam/UTIL.ASM

2480 lines
46 KiB
NASM
Executable File
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.

**************************************************************
*
* Owner: none
*
* Software: ? and Shawn Liptak
* Initiated: ?
*
* Modified: Shawn Liptak, 7/?/91 -Improved FLASHME, added FRANIMQ
* Shawn Liptak, 7/?/91 -New and improved random stuff
* Shawn Liptak, 9/13/91 -Fixed various junk (STRINGER)
* Shawn Liptak, 10/5/91 -Added DELTAY to FRANIMQ
* Shawn Liptak, 10/20/91 -Improved GETCPNT
* Shawn Liptak, 1/4/92 -QDMAN mods
* Shawn Liptak, 2/11/92 -Started basketball (cleanup)
* Shawn Liptak, 12/10/92 -Added security code
* Shawn Liptak, 3/16/93 -Fixed coin misses from wipeout
* Jeff Johnson, 4/12/95 -Updated for WWF hardware
*
* COPYRIGHT (C) 1992 WILLIAMS ELECTRONICS GAMES, INC.
*
*.Last mod - 3/22/93 16:25
*.Last mod - 4/12/95 11:02am
**************************************************************
.file "util.asm"
.title "utility subroutines"
.width 132
.option b,d,l,t
.mnolist
.include "mproc.equ"
.include "disp.equ"
.include "gsp.equ"
.include "sys.equ"
.include "game.equ"
.include "audit.equ"
.include "macros.hdr" ;Macros
;utility subroutine equates
.def SCRCLR
.def OBJOFF,OBJON
.def STRLNRM,STRCNRM,STRCNRMO,STRLNRMO,STRCNRMO_1,CYCLE_TABLE
.def BLNKAREA
.def FRANIM,FRANIMQ
.def STRNGLEN
.def STRRNRM,FILLAREA
.ref pal_init,pal_getf,pal_find,pal_set,PALRAM,WFLG
.ref plyrobj_t,plyrproc_t
.ref P1CTRL,P1DATA
.ref SOUNDSUP,WSPEED
.ref gndstat
.ref COLRTEMP,GAMSTATE
.ref display_init
.ref dirqtimer
.ref SYSCOPY
.ref dpageflip,IRQSKYE
.ref BAKBITS
.ref GET_ADJ
.ref tvpanelon
.ref DMAQCUR,DMAQ,QDMAN
.def STRNGRAM,HEXTOASC,GETANIX,WRLD
.def COLCYC,CYCLE_TABLE,FLASHME
BSSX RAND ,32 ;Last random #
.bss STRNGRAM ,20*16
.bss WRLD ,16
BSSX LOWZ ,16
.text
********************************
* Flash screen white
SUBR flash_white
movi [0909h,0000h],a1 ;[color,pal]
movi [256,400],a2 ;[Ysz,Xsz]
clr a3 ;[Ypos,Xpos]
clr a4 ;SAG
movi DMACAL,a5 ;[offset,ctrl]
calla QDMAN
rets
********************************
* Kill all background objects
SUBR KILBGND
MMTM SP,A0,A2,A3,A4,A5
MOVI BAKLST,A2,L ;ACTIVE BACKGROUND OBJECTS LIST
MOVE *A2,A0,L
JREQ KILOBX ;BR=NO MORE OBJECTS ON LIST
FREEB
MOVE A2,A3 ;SAVE PREVIOUS
MOVE *A2,A2,L ;GET NEXT BLOCK
JREQ KILOBX ;BR=ALL DONE
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 ;UPDATE FREE LIST POINTER
MOVE A3,A2
JRUC FREEB ;KILL ALL OBJECTS ON BACKGROUND LIST
KILOBX
CALLR ZERO_BITS
MOVE A0,@BAKLST,L
MMFM SP,A0,A2,A3,A4,A5
RETS
********************************
SUBR ZERO_BITS
CLR A0
MOVI 10000/16,A2 ;SIZE OF BAKBITS IN WORDS
MOVI BAKBITS,A1
KILUP
MOVE A0,*A1+,W
DSJS A2,KILUP
RETS
; SUBR SPECIAL_WIPEOUT
; CALLR WIPEOUT2
; JAUC SPECIAL_DISPLAY_INIT
**************************************************************************
* Wipes the system clear of all other processes, objects
* and coordinates. It returns with display processor disabled
* color ram cleared, and the bit map wiped clean.
SUBR WIPEOUT
callr dirq_wait
calla display_init
pushst
dint
calla pal_init
POPST
SUBR WIPEOUT2
; callr security_chk ;Rets: A0=0 if OK!
movi plyrproc_t,a1 ;These must be cleared!
movi plyrobj_t,a2
movi P1CTRL,a3
movk 4,a7
#l1 move a0,*a1+,L
move a0,*a2+,L
move a0,*a3+
dsj a7,#l1
clr a0
move a0,@gndstat
move a0,@dtype
move a0,@tvpanelon
move a0,@WFLG
movk OWSPD,a1
move a1,@WSPEED
move a0,a1
calla KILALL ;Kill all processes
callr ZERO_BITS
callr dpageflip_off
clr a0
move a0,@SOUNDSUP ;Allow sounds
move a0,@IRQSKYE
; move a0,@DISPLAYON ;TURN THE DISPLAY PROCESSOR OFF
pushst
dint
move @SYSCOPY,a0 ;>Init sysctrl
.if WWFUNIT
movi SYSCINIT,a1
.else
srl 8,a0
sll 8,a0
movi SYSCINIT&>ff,a1 ;Don't touch 7seg LED
.endif
or a1,a0
move a0,@SYSCOPY
move a0,@SYSCTRL
popst
callr dirq_wait ;Now wait for vblank to zap color map
rets
#*******************************
* Save display/process lists and variables of active game
* A13=*Process that stays running
* Trashes scratch, A2-A7
.bss sysstate_t ,16*50 ;Mem for state save
.bss svproc_p ,32 ;*Saved proc list
.bss pal_t ,32*NMFPAL ;Mem for pal save
SSS .macro a
move @:a:,*a1+
.endm
SSSL .macro a
move @:a:,*a1+,L
.endm
SUBR system_savegame
movi sysstate_t,a1
SSSL OBJLST
SSSL BAKLST
SSSL WORLDTLX
SSSL WORLDTLY
SSS IRQSKYE
SSSL COLRTEMP
SSS dtype
SSS dpageflip
SSS gndstat
SSS GAMSTATE
movi plyrproc_t,a2
movi plyrobj_t,a3
movi P1CTRL,a4
movk 4,b0
#lp move *a2+,*a1+,L
move *a3+,*a1+,L
move *a4+,*a1+
dsj b0,#lp
movi ACTIVE,a2
movi svproc_p,a4
jruc #prnxt
#prlp cmp a13,a2
jreq #prnxt ;Me?
move *a2(PROCID),a14
jrn #prnxt ;Indestructible?
move *a2,*a3,L ;Unlink
move a2,*a4,L ;Add it to save list
move a2,a4
move a3,a2
#prnxt
move a2,a3
move *a2,a2,L
jrnz #prlp
clr a0
move a0,*a3,L
move a0,*a4,L
move a0,@OBJLST,L ;Null lists
move a0,@BAKLST,L
move a0,@gndstat
callr ZERO_BITS
movi PALRAM,a0 ;>Save pal ptrs
movi pal_t,a1
movi NMFPAL,b0
#plp move *a0+,*a1+,L
dsj b0,#plp
calla pal_init
rets
#*******************************
* Restore state of system_savegame
* Trashes scratch, A2-A8
SRS .macro a
move *a1+,a0
move a0,@:a:
.endm
SRSL .macro a
move *a1+,a0,L
move a0,@:a:,L
.endm
SUBR system_restoregame
clr a0
move a0,@DISPLAYON
clr a1
calla KILALL ;Kill all processes
calla KILBGND ;Kill old background
movi -1,a1
calla obj_delc ;Kill all objs
calla pal_init
movi pal_t,a3 ;>Restore pal ptrs
movi PALRAM,a4
clr a5
movi NMFPAL,a7
#plp
move *a3+,a0,L ;Get * pal
move a0,*a4+,L
jrz #nxtp
move a5,a1
sll 8,a1 ;Pal offset
move *a0+,a2 ;Get # colors in pal
calla pal_set ;Setup pal transfer
#nxtp addk 1,a5
cmpi NMFPAL/2,a7
jrne #skipslp
PUSHP a3,a4,a5,a7
PULL a8 ;Get our rets addr so we can sleep
SLEEPK 1 ;Split the transfer
PUSH a8
PULLP a3,a4,a5,a7
#skipslp
dsj a7,#plp
movi sysstate_t,a1
SRSL OBJLST
SRSL BAKLST
SRSL WORLDTLX
SRSL WORLDTLY
SRS IRQSKYE
SRSL COLRTEMP
SRS dtype
SRS dpageflip
SRS gndstat
SRS GAMSTATE
movi plyrproc_t,a2
movi plyrobj_t,a3
movi P1CTRL,a4
movk 4,b0
#lp move *a1+,*a2+,L
move *a1+,*a3+,L
move *a1+,*a4+
dsj b0,#lp
movi ACTIVE,a2 ;>Find end of list
#prlp
move a2,a3
move *a2,a2,L
jrnz #prlp
move @svproc_p,*a3+,L ;Link
movk 1,a0
move a0,@DISPLAYON
rets
********************************
* Clear all world coordinates and scroll velocities
; SUBRP world_clr
;
; clr a0
; move a0,@SCROLLX,L ;X SCROLL VALUE
; move a0,@SCROLLY,L ;Y SCROLL VALUE
; move a0,@WORLDTLX,L ;TOP LEFT X SCREEN COORD (WORLD)
; move a0,@WORLDTLY,L ;TOP LEFT Y SCREEN COORD (WORLD)
; move a0,@WORLDTL,L
; movi SCRNST,a0
; move a0,@SCRNTL,L
; movi SCRNEND,a0
; move a0,@SCRNLR,L
; rets
****************************************************************
*
* Animation script code by SL
*
****************************************************************
********************************
* Run an animation script (Process)
BSSX animscnt ,16 ;# anim scripts running
STRUCTPD
APTR animslobj_p ;*Last obj created
LONG animsv ;Temp value
WORD animsbx ;Base X
WORD animsby ;Base Y
WORD animsfnum ;# FRANIMs running
APTR animslp_p ;*Loop point table pos
;Careful!
APTR animslp_t ;(*Loop point, Loop cnt)*5
SUBR anim_script ;A8=*Script
clr a9
SUBRP anim_script2 ;A8=*Script, A9=Base Y:X
move a9,*a13(animsbx),L ;Save XY
move *a13(PROCID),a11
subi ANIMPID,a11
srl 8,a11
sll 8,a11 ;A11=ID offset (0->300)
clr a1
move a1,*a13(animsfnum)
move a13,a1
addi animslp_t,a1
move a1,*a13(animslp_p),L
anslp move *a8+,a1 ;Get command
addi anims_t,a1
move *a1,a1,L
jump a1
.long asEND
anims_t .long asNEW,asDEL,asDELM,asFRA
.long asANI,asHIDE,asSHOW,asPAL
.long asXY,asXYRNG,asYA,asXYV
.long asXYVA,asXYV0,asZ,asBXY
.long asSLP,asSLP1,asSLPR
.long asWAIT,asTXT
.long asTXTR,asTXTK,asLAB,asLABR
.long asDSJ,asDSJS1,asJMP,asJMPR,asJMPEQ
.long asJMPNE,asRUN,asRUNI,asCRE
.long asKIL,asASM,asSND,asSNDD
.long asADDW
.long asADDWO,asADDLO,asADLVO,asSVRL
.long asSVRLT,asSVL
asNEW ;>New objects
move *a8+,a9,L ;Get data
PUSH a8
ans100 move *a9+,a2,L ;*Image
move *a9+,a0,L ;Get XY
move *a13(animsbx),a3,L
addxy a3,a0 ;Add base
clr a1
movy a0,a1
sll 16,a0
move *a9+,a3 ;Z
move *a9+,a4 ;Flags
addi M_NOCOLL,a4
move *a9+,a5 ;ID
addi CLSANIM,a5
add a11,a5 ;+offset
clr a6
clr a7
calla BEGINOBJ
move *a9,a0
cmpi -1000,a0
jrne ans100 ;End?
move a8,*a13(animslobj_p),L ;Save * to last one
PULL a8
jruc anslp
asFRA ;>FRANIM
move a11,a6 ;Save a11
move *a8+,a9,L ;Get data
move *a13(PROCID),a1 ;Inherit same ID+1
addk 1,a1
move *a8+,a10 ;OID
jrn ans250 ;No ID?
addi CLSANIM,a10
add a11,a10 ;+offset
move *a8+,a11 ;#Loops
jrn ans220
move *a13(animsfnum),a2 ;+1 FRANIM cnt
addk 1,a2
move a2,*a13(animsfnum)
ans220 movi anims_franim,a7
calla GETPRC
move a13,*a0(anfc_p),L
move a6,a11
jruc anslp
ans250 addk 16,a8 ;Skip #loops
move a8,a10
move *a13(animslobj_p),a8,L ;Get * to last one
movi FRQDELDIE,a7
calla GETPRC
move a10,a8
jruc anslp
asSLP ;>SLEEP
move *a8+,a0 ;Get time
calla PRCSLP
jruc anslp
asSLP1 ;>SLEEP 1
movk 1,a0
calla PRCSLP
jruc anslp
asSLPR ;>Sleep random
move *a8+,a0 ;Get time
move *a8+,a1
callr RNDRNG
calla PRCSLP
jruc anslp
asWAIT ;>Wait on FRANIMs
SLEEPK 2
move *a13(animsfnum),a1
jrnz asWAIT
jruc anslp
asXY ;>New XY rel to current pos
move *a8+,a1 ;Get ID
move *a8+,a2
move *a8+,a4
move *a8+,a5
asxyhs ;Entry for HIDE/SHOW
asxyr addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
ans720 callr obj_find
jrz anslp
move *a0(OXPOS),a6 ;New X
add a4,a6
move a6,*a0(OXPOS)
move *a0(OYPOS),a6 ;New Y
add a5,a6
move a6,*a0(OYPOS)
move *a0,a0,L
jrnz ans720
jruc anslp
asXYRNG ;>New XY rel to current pos in rndrng
move *a8+,a0
move *a8+,a1
callr RNDRNG
move a0,a4
move *a8+,a0
move *a8+,a1
callr RNDRNG
move a0,a5
move *a8+,a1
jrn asxyr5 ;No ID?
move *a8+,a2
jruc asxyr
asxyr5 addk 16,a8 ;Skip mask
move *a13(animslobj_p),a0,L ;Get * to last one
move *a0(OXPOS),a6 ;New X
add a4,a6
move a6,*a0(OXPOS)
move *a0(OYPOS),a6 ;New Y
add a5,a6
move a6,*a0(OYPOS)
jruc anslp
asYA ;>Set Y ani pt world relative
move *a8+,a1
move *a8+,a2 ;Mask
move *a8+,a5 ;
sll 16,a5
move @WORLDTLY,a0,L
add a0,a5
addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
asya10 callr obj_find
jrz asya90
PUSH a1,a2
move *a0(OIMG),a1,L
move *a0(OSIZE),a2,L
move *a0(OCTRL),a4
calla GANIOF
move *a0(OXVAL),a3,L
add a6,a3 ;Old X
move a5,a2 ;New Y
calla GANISAG
PULL a1,a2
move *a0,a0,L
jrnz asya10
asya90 jruc anslp
asXYV ;>Set XYVel
move *a8+,a4,L
move *a8+,a5,L
move *a8+,a1
move *a8+,a2
addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
ans920 callr obj_find
jrz anslp
move *a0(OXVEL),a6,L
add a4,a6
move a6,*a0(OXVEL),L
move *a0(OYVEL),a6,L
add a5,a6
move a6,*a0(OYVEL),L
move *a0,a0,L
jrnz ans920
jruc anslp
asXYVA ;>Set XYVel absolute
move *a8+,a4,L
move *a8+,a5,L
move *a8+,a1
move *a8+,a2
addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
ans1020 callr obj_find
jrz anslp
move a4,*a0(OXVEL),L
move a5,*a0(OYVEL),L
move *a0,a0,L
jrnz ans1020
jruc anslp
asXYV0 ;>XYVel = 0
move *a13(animslobj_p),a0,L ;Get * to last one
clr a1
move a1,*a0(OXVEL),L
move a1,*a0(OYVEL),L
jruc anslp
asZ ;>Set Z pos
move *a8+,a1
move *a8+,a2
move *a8+,a4
addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
ans1120 callr obj_find
jrz anslp
move a4,*a0(OZPOS)
move *a0,a0,L
jrnz ans1120
jruc anslp
asLAB ;>Set label
move *a8+,a0
anslab move *a13(animslp_p),a2,L
move a8,*a2+,L ;Save *
move a0,*a2+
move a2,*a13(animslp_p)
jruc anslp
asLABR ;>Set label randomly
move *a8+,a0
move *a8+,a1
callr RNDRNG
jruc anslab
asDSJS1 ;>Sleep 1, dec and loop to label
SLEEPK 1
asDSJ ;>Decrement and loop to label
move *a13(animslp_p),a1,L
move -*a1,a2
subk 1,a2
move a2,*a1
jrz ans1330
move -*a1,a8,L ;Get *Loop
jruc anslp
ans1330 subk 32,a1 ;Del loop entry
move a1,*a13(animslp_p),L
jruc anslp
asPAL ;>Set palette
move *a13(animsv),a0,L ;Get *Pal
calla pal_getf
move a0,a4
move *a8+,a1
jrn ans1450
addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
clr a2 ;No mask
ans1420 callr obj_find
jrz anslp
move a4,*a0(OPAL)
move *a0,a0,L
jrnz ans1420 ;More?
jruc anslp
ans1450 move *a13(animslobj_p),a0,L ;Get * to last obj
move a4,*a0(OPAL)
jruc anslp
asANI ;>Do ANI on OID
move *a8+,a5,L
move *a8+,a1 ;OID
addi CLSANIM,a1
add a11,a1 ;+offset
move @OBJLST,a0,L
clr a2 ;No mask
ans1620 callr obj_find
jrz anslp
move a8,a9
move a1,a3
move a5,a1 ;*Img
move a0,a8 ;*Obj
move *a8(OCTRL),a4 ;Same flags
calla ANI
move a3,a1
move a8,a0
move a9,a8
move *a0,a0,L
jrnz ans1620 ;More?
jruc anslp
asDEL ;>Delete obj
move *a8+,a0
clr a1
asdel5 addi CLSANIM,a0
add a11,a0 ;+offset
calla obj_delc
jruc anslp
asDELM ;>Delete obj with mask
move *a8+,a0
move *a8+,a1
jruc asdel5
asRUN ;>Run a new anim script
move *a8+,a0,L
move *a13(PROCID),a1 ;Inherit same ID
asrun5 move a8,a10
move a0,a8 ;*Script
move *a13(animsbx),a9,L ;Get base XY
movi anim_script2,a7
calla GETPRC
move a10,a8
jruc anslp
asRUNI ;>Run a new anim script with ID
move *a8+,a0,L
move *a8+,a1
addi ANIMPID,a1
add a11,a1 ;+offset
jruc asrun5
asCRE ;>Create a process
move *a8+,a7,L
move *a8+,a9,L ;Pass A9 to process
movi ANIMPID+>ff,a1
add a11,a1 ;+offset
calla GETPRC
jruc anslp
asKIL ;>Kill processes with mask
move *a8+,a0
addi ANIMPID,a0
add a11,a0 ;+offset
move *a8+,a1
calla KILALLN
jruc anslp
asJMP ;>Jump to new location
move *a8+,a8,L
jruc anslp
asJMPR ;>Jump to new location if RND<#
move *a8+,a4,L
movi 999,a0 ;.1 % resolution
callr RNDRNG0
move *a8+,a1
cmp a1,a0
jrhs anslp
move a4,a8 ;Do jmp
jruc anslp
asJMPEQ ;>Jump to new location if = to mem
move *a8+,a0,L
move *a0,a0 ;Get value
move *a8+,a2,L
move *a8+,a1
cmp a1,a0
jrne anslp ;Not same?
move a2,a8 ;Do jmp
jruc anslp
asJMPNE ;>Jump to new location if != to mem
move *a8+,a0,L
move *a0,a0 ;Get value
move *a8+,a2,L
move *a8+,a1
cmp a1,a0
jreq anslp ;Same?
move a2,a8 ;Do jmp
jruc anslp
asSNDD ;>Do a snd call in demo
movk ADJMUSIC,a0 ;Get demo music ON/OFF
calla GET_ADJ
jrz asSND ;Do sounds?
addk 32,a8
jruc anslp
asSND ;>Do a snd call
move *a8+,a0,L
calla snd_play1
jruc anslp
asASM ;>Inline code
exgpc a8
jruc anslp
asHIDE ;>Hide an OID (X+5000)
movi 5000,a4
ashide2 move *a8+,a1
clr a2
clr a5
jruc asxyhs
asSHOW ;>Show an OID (X-5000)
movi -5000,a4
jruc ashide2
asADDW ;>Add WORD to mem
move *a8+,a0,L
move *a8+,a1
move *a0,a2
add a1,a2
move a2,*a0
jruc anslp
asADDWO ;>Add WORD to last obj+offset
move *a8+,a0
move *a13(animslobj_p),a1,L ;Get * to last one
move *a8+,a2 ;Offset
add a2,a1
move *a1,a2
add a0,a2
move a2,*a1
jruc anslp
asADDLO ;>Add LONG # to last obj+offset
move *a8+,a0,L
move *a13(animslobj_p),a1,L ;Get * to last one
move *a8+,a2 ;Offset
add a2,a1
move *a1,a2,L
add a0,a2
move a2,*a1,L
jruc anslp
asADLVO ;>Add LONG value to last obj+offset
move *a8+,a0
move *a13(animslobj_p),a1,L ;Get * to last one
add a0,a1 ;+Offset
move *a13(animsv),a0,L ;Get value
move *a1,a2,L
add a0,a2
move a2,*a1,L
jruc anslp
asSVRL ;>Set value to rnd long
move *a8+,a0,L
move *a8+,a1,L
callr RNDRNG
move a0,*a13(animsv),L
jruc anslp
asSVRLT ;>Set value to rnd long from a table
move *a8+,a4,L
move *a4+,a0 ;#Table entries
subk 1,a0
callr RNDRNG0
sll 5,a0 ;*32
add a0,a4
move *a4,a0,L
move a0,*a13(animsv),L
jruc anslp
asSVL ;>Set value to long
move *a8+,a0,L
move a0,*a13(animsv),L
jruc anslp
asBXY ;>Add # to BaseXY
move *a8+,a0,L
move *a13(animsbx),a1,L
addxy a0,a1
move a1,*a13(animsbx),L
jruc anslp
asTXTR ;>Print rnd text from table
move *a8+,a4,L
move *a4+,a0 ;#Table entries
subk 1,a0
callr RNDRNG0
sll 5,a0 ;*32
add a0,a4
move *a4,a0,L
jruc astxt5
asTXT ;>Print text
move *a8+,a0,L
astxt5
; calla prt0_xy
jruc anslp
asTXTK ;>Kill text
PUSHP a8
callr ERASE_TXT
; movk 4,a11 ;Save A11!
; JSRP text_shrink ;Sleeps
PULLP a8
jruc anslp
asEND SLEEPK 1 ;>Wait on FRANIMs before exit
move *a13(animsfnum),a1
jrnz asEND
DIE
********************************
* Animation of a part (Process)
STRUCTPD
APTR anfc_p ;*AnimScrpt process that made me, set by AS
APTR anfl ;*Franim list
SUBRP anims_franim ;A9=*FRAN list, A10=OID, A11=# Loops
move @OBJLST,a8,L ;>Find object
anf100 move *a8(OID),a0
cmp a10,a0
jreq anf300
move *a8,a8,L
jrnz anf100
jruc anf700 ;No match!
anf300 move a9,*a13(anfl),L
anf340 JSRP FRANIMQ
move *a13(anfl),a9,L ;Go to 1st
move a11,a11
jrn anf340 ;-=Infinite
dsj a11,anf340
anf700 move a11,a11
jrn anf800
move *a13(anfc_p),a0,L ;Get *Creator
move *a0(animsfnum),a2 ;#Frans-1
subk 1,a2
move a2,*a0(animsfnum)
anf800 DIE
********************************
* Wait for animation processes to finish
SUBR anim_wait
anw10 SLEEPK 3
move @animscnt,a1
jrgt anw10
RETP
********************************
* Wait 50 and kill anim stuff (Process)
SUBR anim_kilslp
SLEEP 50
callr anim_killall
DIE
********************************
* Kill all animation processes and objects
SUBR anim_killall
clr a0
move a0,@animscnt
movi ANIMPID,a0 ;>Kill processes
movi >3ff,a1
calla KILALLN
movi CLSANIM,a0 ;>Delete objs
movi >3ff,a1
jauc obj_delc
********************************
* Find an object by OID
* A0=*1st obj
* A1=OID
* A2=!Mask
* >A0=*Obj or 0 (Z)
* Trashes A1,A3
SUBRP obj_find
andn a2,a1
of20 move *a0(OID),a3
andn a2,a3 ;Remove bits
cmp a1,a3
jreq of50
move *a0,a0,L
jrnz of20
of50 move a0,a0 ;A0=*Obj or 0
rets ;Pass CC
#***************************************************************
* Reset autoerase color for fixing scrn glitches
* Trashes scratch
SUBR autoerase_set
pushst
dint
callr dma_wait ;Wait on dma
clr a0
move a0,@DMACMAP
movi ERASECOL,a0 ;Color pair
movi 510*512*8,a1 ;Store to last 2 lines of bitmap
movi 512*8*2/16,b0
#lp move a0,*a1+
dsj b0,#lp
popst
rets
#*******************************
* Flash an image by making a constant color
* A8=*Image to flash
* A9=Color to flash with (Ex. 0202h,a9)
FLASHME
move *a8(OCONST),a0
jrnz #x ;Flashing?
move a9,*a8(OCONST)
setf 4,0,0
movk M_CONNON,a0 ;Replace non-zero data with constant
move a0,*a8(OCTRL) ;Write 4 low bits
setf 16,1,0
SLEEPK 2
clr a0
move a0,*a8(OCONST) ;Clr color
setf 4,0,0
movk M_WRNONZ,a0
move a0,*a8(OCTRL) ;Write 4 low bits
setf 16,1,0
#x DIE
.if 0
#*******************************
* Flash an image by making a constant color
* A8=*Image to flash
* A9=Color to flash with *64K
FLASHME
move *a8(OCONST),a10
jrnz #x ;Flashing?
srl 16,a9
move a9,*a8(OCONST) ;Set color
move *a8(OCTRL),a0
movk 8,a1
or a1,a0 ;Set constant
move a0,*a8(OCTRL)
SLEEPK 2
clr a0
move a0,*a8(OCONST) ;Clr color
move *a8(OCTRL),a0
andi >fff5,a0 ;Clr constant & nonzero
addk 2,a0 ;Set nonzero
move a0,*a8(OCTRL)
#x DIE
.endif
********************************
*CHEAP COLOR CYCLER
*CYCLES ANY NUMBER OF COLORS
*A8=PALETTE NAME
*A9=RAM STORAGE AREA
*A10=MSW START COLOR, LSW END COLOR
*A11=SPEED, A11=NEGATIVE FOR REVERSE CYCLER
COLCYC
SLEEPK 4
MOVE A8,A0
calla pal_find
JRZ COLCYC ;WAIT TILL IT SHOWS UP FOLKS...
CLR A1 ;GET THE COLORS INTO RAM
MOVX A10,A1 ;GET END COLOR
SRL 16,A10 ;ADJUST START COLOR
SUB A10,A1 ;GET COUNT
MOVE A1,*A13(PDATA) ;SAVE COUNT
MOVE A1,A4
SLL 4,A1 ;COUNT IN WORDS
MOVE A10,A5
SLL 4,A5 ;OFFSET INTO PALETTE
ADD A8,A5
ADDK 16,A5 ;SKIP PALETTE WORD COUNT
MOVE A9,A3
MOVE A9,A6
ADD A1,A6
MOVE A6,A8
COLCYC1 MOVE *A5+,A7 ;TRANSFER IT TWICE
MOVE A7,*A3+
MOVE A7,*A6+
DSJS A4,COLCYC1
SRL 8,A0
SLL 8,A0
ADD A0,A10 ;COLRAM DESTINATION
COLCYCB
MOVE A8,*A13(PDATA+>20),L ;SAVE RAM ADDRESS
COLCYCBL
MOVE A8,A0 ;GET SOURCE ADDRESS
MOVE A10,A1 ;GET DESTINATION CONSTANT
MOVE *A13(PDATA),A2,W ;GET COUNT
calla pal_set
SUBK 16,A8
CMP A8,A9
JRLO CCYCBSLP
MOVE *A13(PDATA+>20),A8,L ;GET SOURCE TABLE START
CCYCBSLP
MOVE A11,A0 ;GET SLEEP TIME
CALLA PRCSLP
JRUC COLCYCBL
#*******************************
* CYCLE A PAL WITH A FIXED ROM COLOR TABLE
* A8= [COLOR # TO START AT,# TO CYCLE]
* A9= PAL NAME TO CYCLE
* A10=TABLE TO CYCLE IT WITH
* A11=RATE OF CYCLE IN TICKS
CYC0 SLEEP 60
CYCLE_TABLE
MOVE A9,A0 ;PAL NAME TO CYCLE
calla pal_find
jrz CYC0
SRL 8,A0
SLL 8,A0
MOVY A8,A1
SRL 16,A1 ;A1=COLOR # TO START WITH
MOVE A8,*A13(PDATA) ;PDATA WILL HAVE # TO CYCLE (CNT)
MOVE *A10,A2,W
MOVE A2,*A13(PDATA+16) ;VALUE IN TABLE TO STOP AT
MOVE A0,A8 ;A8=[PAL #,0]
ADD A1,A8 ;A8=[PAL #,COLOR TO START AT]
MOVE A10,A9 ;A10=ROM TABLE TO CYCLE WITH
#loop move a8,a1
MOVE A9,A0 ;A0=TABLE POSITION
MOVE *A13(PDATA),A2 ;A2=COLOR COUNT
calla pal_set ;do the transfer
MOVE A11,A0
CALLA PRCSLP
ADDK >10,A9
MOVE *A9,A0
JRN RESTUFF
MOVE *A13(PDATA+16),A1 ;PDATA+16=ENTRY WE STOP AT
CMP A0,A1
jrne #loop
RESTUFF MOVE A10,A9 ;REACHED END OF TABLE, RESTUFF
jruc #loop
****************************************************************
* Converts a 32 bit hex # to a null terminated ascii string
* A8=#
* >A8=*String
HEXTOASC
PUSH a1,a2,a9
clr a1
move a1,-*sp ;Push the null terminator
movk 10,a1 ;Divisor for decimal
move a8,a9
hexta1 movk 3,a2 ;Comma count
hexta2 clr a8
divu a1,a8
addi '0',a9 ;Make the remainder ascii
move a9,-*sp ;Save here
move a8,a9
jrz hexta3 ;Done?
dsj a2,hexta2
movi ',',a2
move a2,-*sp ;Stuff a comma
jruc hexta1
hexta3 movi STRNGRAM,a1 ;Store here for blow out
move a1,a8
hexta4 move *sp+,a9
movb a9,*a1
addk 8,a1
move a9,a9
jrnz hexta4
PULL a1,a2,a9
rets
********************************
* Erase all text objects
SUBR ERASE_TXT
movi CLSNEUT|TYPTEXT|SUBTXT,a0
jauc obj_del1c
**************************************************************************
*
* STRINGER - OUTPUT A TEXT STRING, THIS IS A PROCESS!
* A0 = SLEEP TIME BETWEEN CHARACTERS
* A4 = DMA CONTROL
* A6 = COLOR (16 BITS)
* A8 = PTR TO STRING
* A9 = [Y,X] SCREEN ADDRESS OF STRING
* A10 = [Y,X] SPACING
* A11 = POINTER TO FONT TABLE
* A14 = FLAGS:JUSTIFY
* BIT 16 = 1 INSERT ON OBJECT LIST, 0 JUST QUEUE THE DMA
* JUSTIFY = 0 LEFT JUSTIFY
* 1 CENTER JUSTIFY
* 2 RIGHT JUSTIFY
* WRLD = ADJUST FOR WORLD COORDINATES
* LOWZ+20000=ZPOS
*
* RETURNS:
* A8 = POINTS TO NEXT BYTE AFTER STRING TERMINATOR
* A9 = NEXT CURSOR POSITION AFTER THE STRING
* NOTE: CALL WITH JSRP
*
**************************************************************************
;LEFT JUSTIFY, NORMAL, NOT PUT ON THE OBJECT LIST
STRLNRM
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMACNZ|M_NOCOLL,a4
clr a14
jruc stringr1
;CENTER JUSTIFY, NORMAL, NOT ON THE OBJECT LIST
STRCNRM
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMACNZ|M_NOCOLL,a4
movk 1,a14
jruc stringr1
;CENTER JUSTIFY, NORMAL, DMA, MULTIPLE COLORS
SUBR STRCNRM_1
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMAWNZ|M_NOCOLL,a4
movk 1,a14
move a6,a5
jruc stringr1_1
;RIGHT JUSTIFY, NORMAL, NOT PUT ON THE OBJECT LIST
STRRNRM
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMACNZ|M_NOCOLL,a4
movk 2,a14
jruc stringr1
;LEFT JUSTIFY, INVERTED, NOT ON THE OBJECT LIST
;STRLINV
; mmtm a12,a1,a2,a3,a4,a6,a14
; MOVI DMACZ,A4
; clr a14
; jruc stringr1
;CENTER JUSTIFY, INVERTED, NOT ON THE OBJECT LIST
;STRCINV
; mmtm a12,a1,a2,a3,a4,a6,a14
; MOVI DMACZ,A4
; movk 1,a14
; jruc stringr1
;
;LEFT JUSTIFY, NORMAL, OBJECT LIST
STRLNRMO
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMACNZ|M_NOCOLL,a4
movi >10000,a14
jruc stringr1
;CENTER JUSTIFY, NORMAL, OBJECT LIST
STRCNRMO
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMACNZ|M_NOCOLL,a4
movi >10001,a14
jruc stringr1
;CENTER JUSTIFY, NORMAL, OBJECT LIST, MULTIPLE COLORS!
STRCNRMO_1
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMAWNZ|M_NOCOLL,a4
movi >10001,a14
move a6,a5
jruc stringr1_1
;LEFT JUSTIFY, NORMAL, OBJECT LIST, MULTIPLE COLORS!
SUBR STRLNRMO_1
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMAWNZ|M_NOCOLL,a4
movi >10000,a14
move a6,a5
jruc stringr1_1
STRINGER
mmtm a12,a1,a2,a3,a4,a6,a14
stringr1
move a6,a5
sll 16,a5 ;Setup constant color in fixed palette
stringr1_1
clr a7
movx a14,a7
subk 1,a7
jrn strr10 ;Normal left justify
jrz strrc
callr STRNGLEN ;Right justify
jruc strra
strrc callr STRNGLEN ;Center justify
srl 1,a7 ;STRNGLEN/2
strra subxy a7,a9 ;Adjust string starting position
jruc strr10 ;Start loop
strr1 addk 5,a9 ;Add a space
strr5 addxy a10,a9 ;Add spacing
strr10 movb *a8,a1 ;Get a character
jrle strrx ;Done?
addk 8,a8 ;Next byte
subk 32,a1
jrle strr1 ;Space?
;Save sleep time
strr20 PUSH a0
subk 1,a1 ;>Calc table offset
sll 5,a1 ;*32
add a11,a1
move *a1,a1,L ;Get * image header
move *a1(ICTRL),a3
PUSH a1,a14
btst 16,a14
jrz strrdma ;Only do DMA?
move a1,a2
calla GETOBJ ;Create the character as an object
jrz strrdun ;No object?
move a2,*a0(OIMG),L
move *a2(ISAG),*a0(OSAG),L
move a4,*a0(OFLAGS) ;FIX!!!!!
move a5,*a0(OPAL),L ;&CONST
movi 01000100h,a1
move a1,*a0(OSCALE),L
move a4,a1
andi >803f,a1 ;Kill mode bits
or a1,a3
move a3,*a0(OCTRL),L ;&OFSET
movi CLSNEUT|TYPTEXT|SUBTXT,a14
move a14,*a0(OID)
move @LOWZ,a14
addi 20000,a14
move a14,*a0(OZPOS)
clr a2
move a2,*a0(OXVEL),L
move a2,*a0(OYVEL),L
move a2,*a0(OZVEL),L
movy a9,a2 ;Y
move a9,a3
sll 16,a3 ;X
calla GANISAG
move @WRLD,a2
jrnz strr100
calla obj_addworldxy ;Put us in the world
strr100 calla INSOBJ
jruc strrdun
strrdma PUSH a3 ;>Simple DMA
move *a1,a2,L ;ISIZE
move *a1(ISAG),a3,L ;Get top left sag
calla GANIOF
move a5,a1 ;Constant:Palette
PULL a5
PUSH a4
andi >803f,a4
or a4,a5 ;Offset:Control
move a3,a4 ;SAG
move a9,a3 ;A3=Y:X
srl 16,a6
movx a6,a7
subxy a7,a3 ;Sub anioffset
calla QDMAN
PULL a4
move a1,a5
strrdun PULL a1,a14
move *a1,a1 ;Get ISIZEX
addxy a1,a9 ;Add X size
move *sp+,a0,L
jrz strr5 ;No sleep?
mmtm a12,a0,a4,a5,a14
calla PRCSLP
mmfm a12,a0,a4,a5,a14
jruc strr5
strrx clr a1
move a1,@LOWZ
addk 8,a8 ;Next byte
mmfm a12,a1,a2,a3,a4,a6,a14
RETP
**************************************************************************
* STRNGLEN - RETURNS THE LENGTH, IN PIXELS, OF A GIVEN STRING
* A8 = PTR TO STRING
* A10 = [Y,X] SPACING OF STRING
* A11 = PTR TO FONT TABLE
* RETURNS:
* A7 = LENGTH OF STRING
* Z BIT SET IF LENGTH IS ZERO
**************************************************************************
STRNGLEN
PUSH a8,a14
clr a7 ;A7=Length
jruc stl60
stl10 addk 8,a8 ;Point to next
subk 32,a14
jrgt stl20 ;Good char?
addk 5,a7 ;Hard code a space
jruc stl40
stl20 subk 1,a14
sll 5,a14 ;*32
add a11,a14 ;A14=*Correct character header
move *a14,a14,L
move *a14,a14 ;Get ISIZEX
addxy a14,a7 ;Add char length
stl40 addxy a10,a7 ;Add space length
stl60 movb *a8,a14
jrgt stl10 ;Next character?
PULL a8,a14
zext a7
rets
**************************************************************************
* *
* OBJOFF - TURN AN OBJECT "OFF" I.E. SET DMA OUTPUT TO 0 *
* A0 = PTR TO OBJECT BLOCK *
* *
**************************************************************************
OBJOFF
PUSH A4
MOVE *A0(OCTRL),A4
SRL 4,A4
SLL 4,A4
MOVE A4,*A0(OCTRL)
move *sp+,a4,L
RETS
**************************************************************************
* *
* OBJON - TURN AN OBJECT "ON" I.E. SET DMA OUTPUT TO WRITE <> 0 *
* A0 = PTR TO OBJECT BLOCK *
* *
**************************************************************************
OBJON
PUSH A4
MOVE *A0(OCTRL),A4
SRL 4,A4
SLL 4,A4
ADDK 2,A4
MOVE A4,*A0(OCTRL)
move *sp+,a4,L
RETS
**************************************************************************
* *
* CLRPDATA - CLEAR THE PDATA AREA OF A PROCESS BLOCK *
* A13 = PTR TO PROCESS BLOCK *
* *
**************************************************************************
;CLRPDATA
; MMTM SP,A1,A6,A14
; MOVE A13,A14
; CLR A1
; ADDI PDATA,A14
; MOVI (PSDATA-PDATA)/16,A6
;CLRSHL
; SRL 1,A6
; JRNC CLRPDL
; MOVE A1,*A14+,W ;STUFF THE ODD WORD
;CLRPDL
; MOVE A1,*A14+,L
; DSJS A6,CLRPDL
; MMFM SP,A1,A6,A14
; RETS
**************************************************************************
* *
* DFRMGRND - RETURNS THE DISTANCE FROM THE BOTTOM OF *
* AN OBJECT TO THE "GROUND." *
* A8 = OBJECT BLOCK *
* RETURN(S) *
* A1 = DISTANCE FROM GROUND (16 BITS) *
* STATUS BITS SET ACCORDING TO THE SIGN OF A1 *
* NOTE: MAX ACCEPTABLE Y = +32K, MIN ACCEPTABLE Y = -32K *
* *
**************************************************************************
;ZORIGIN EQU 200 ;Y COORDINATE OF THE Z ORIGIN
;DFRMGRND
; PUSH A2
; MOVE *A8(OYPOS),A1,W
; MOVE *A8(OSIZEY),A2,W
; ADD A1,A2 ;A2 = BOTTOM Y
; MOVE *A8(OZPOS),A1,W
; SUB A2,A1
; ADDI ZORIGIN,A1
; MMFM SP,A2
; RETS
**************************************************************************
* *
* GET BOTTOM Y OF AN OBJECT *
* A8 = OBJECT BLOCK PTR *
* RETURN(S) *
* A1 = 16 BIT BOTTOM Y IN LSW *
* STATUS SET ACCORDING TO THE BOTTOM Y *
*NOTE: MAKE SURE OBLOCK IS INIT'D WITH GSAGOF BEFORE CALLING *
* *
**************************************************************************
;GETBOTY
; PUSH A2
; MOVE *A8(OYPOS),A1,W ;GET Y POSITION
; MOVE *A8(OSIZEY),A2,W ;GET THE CURRENT SIZE
; ADD A2,A1 ;A1 = BOTTOM Y
; MMFM SP,A2
; RETS
********************************
* GETCPNT - Get the center xy position of an object
* A8=*Object
* >A0=Center Y:Center X
SUBR GETCPNT
move *a8(OYVAL),a1,L
move *a8(OXPOS),a0
movx a0,a1
move *a8(OSIZE),a0,L
srl 1,a0 ;/2
andi >7fff7fff,a0 ;Clr bit 15
addxy a1,a0
rets
********************************
*GETANIX - GET ANIMATION POINT X COORD
*CALLING PARMS: A8=OBJECT
*RETURNS A0=16 BIT WORLD COORD OF UPPER LEFT
GETANIX
MMTM SP,A1,A2
MOVE *A8(OIMG),A1,L
MOVE *A1(IANIOFF),A2
MOVE *A8(OCTRL),A0
BTST B_FLIPH,A0
JRZ GETAX1
MOVE *A1,A0 ;ISIZEX
SUB A2,A0
DEC A0
MOVE A0,A2
GETAX1 MOVE *A8(OXPOS),A0
ADD A2,A0
MMFM SP,A1,A2
RETS
****************************************************************
* Quickly produce a random # in range -X to +X
* A0=+X
* >A0=Random # (-A0 to +A0) (CC)
* Trashes scratch
SUBR RNDRNGS
move a0,a1
neg a0
********************************
* Quickly produce a random # in a given range
* A0=Lower bound
* A1=Upper bound
* >A0=Random # (A0 to A1) (CC)
* Trashes scratch
SUBR RNDRNG
sub a0,a1 ;Normalize the range
addk 1,a1
move a0,b0
move @RAND,a0,L
rl a0,a0
move @HCOUNT,a14
rl a14,a0
add sp,a0
move a0,@RAND,L
mpyu a1,a0
move b0,a1
add a1,a0
rets
********************************
* Quickly produce a random # in range 0-X
* A0=X
* >A0=Random # (0 to A0) (No CC)
* Trashes scratch
SUBR RNDRNG0
move @RAND,a1,L
rl a1,a1
move @HCOUNT,a14
rl a14,a1
add sp,a1
move a1,@RAND,L
addk 1,a0
mpyu a1,a0 ;Condition codes not valid!
rets
********************************
* Random % routine
* A0=Probability of event (0-1000) (0=0%, 1000=100%)
* >A0=0-999 (CC) (jrls nope, jrhi happened)
* Trashes scratch
SUBR RNDPER
move @RAND,a1,L
rl a1,a1
move @HCOUNT,a14
rl a14,a1
add sp,a1
move a1,@RAND,L
move a0,a14
movi 1000,a0
mpyu a1,a0 ;0-999
cmp a0,a14
rets
**************************************************************************
* *
* FILLAREA - FILL A GIVEN SQUARE AREA ON THE SCREEN WITH A COLOR *
* A1 = [COLOR,PALETTE] *
* A3 = DAG OF AREA [YPOS,XPOS] *
* A4 = [Y,X] SIZE OF AREA *
* *
**************************************************************************
FILLAREA
PUSH a0,a1,a2,a4,a5,a14
jruc areacon
**************************************************************************
* *
* BLNKAREA - BLANK A GIVEN SQUARE AREA ON THE SCREEN *
* A3 = DAG OF AREA [YPOS,XPOS] *
* A4 = [Y,X] SIZE OF AREA *
* *
**************************************************************************
BLNKAREA
PUSH a0,a1,a2,a4,a5,a14
clr a1 ;constant 0:palette 0
areacon
move a4,a2
movi IROM,a4 ;Somewhere in image rom
movi DMACAL,a5
calla QDMAN
PULL a0,a1,a2,a4,a5,a14
rets
********************************
* Wait till DIRQ
* Trashes A0-A1
SUBR dirq_wait
move @dirqtimer,a0
dirqwlp move @dirqtimer,a1
cmp a0,a1
jreq dirqwlp
rets
********************************
* Wait on the DMA busy bit to clear
* Preserves A1
SUBRP dma_wait
dwlp move @DMACTRL,b0
jrn dwlp ;Busy?
rets
********************************
* Wait for dma queue to empty, then wait for dma to finish
* the last one. Turn displayon off.
SUBR dmaq_wait
move @DISPLAYON,a1
clr a0
move a0,@DISPLAYON ;Display off
move @DMACTRL,b0
jrnn dqw20
dqw10 move b13,b13
jrge dqw10
dqw20 callr dma_wait
move a1,@DISPLAYON
rets
********************************
* Turn page flipping and erasure off. Setup for page0
* Trashes scratch
SUBR dpageflip_off
clr a0
move a0,@dpageflip
not a0
move a0,@dpage
movi -4,a0 ;Page0
move a0,@DPYSTRT
rets
#*******************************
* Blank display by using HEBLNK
* Trashes scratch
SUBRP display_blank
dint
#lp move @VCOUNT,a0
cmpi EOSINT,a0
jrlt #lp
move @HSBLNK,a0 ;Blank screen
move a0,@HEBLNK
eint
rets
#*******************************
* Unblank display by resetting HEBLNK
* Trashes scratch
SUBRP display_unblank
dint
#lp move @VCOUNT,a0
cmpi EOSINT,a0
jrlt #lp
movi HEBLNKINIT,a0
move a0,@HEBLNK
eint
rets
**************************************************************************
* *
* CRINIT - COLOR RAM INITIALIZATION, FIRST CLEAR ALL COLOR RAM, THEN *
* FILL WITH PALETTES. *
* *
**************************************************************************
CRINIT
MMTM SP,A0,A1,A2,A6
MOVI COLRAM,A1
CLR A0
MOVI 10000H,A6,L
*CLEAR ALL COLOR PALETTES
CRINIT1
MOVE A0,*A1+,L ;STUFF TWO WORDS AT A TIME
DSJS A6,CRINIT1
MMFM SP,A0,A1,A2,A6
RETS
**************************************************************************
* *
* CRLOAD - LOAD COLOR RAM FROM A ROM TABLE *
* A1 = START OF ROM TABLE *
* A2 = COLOR RAM START ADDRESS *
* A6 = PALETTE COUNT *
* *
**************************************************************************
CRLOAD
MMTM SP,A0,A1,A2
CRLOAD1
MOVE *A1+,A0,W ;GRAB FIRST COLOR FROM THIS TABLE
JRN CRLOAD4 ;BR = NULL PALETTE
CRLOAD3
MOVE A0,*A2,W ;STUFF COLOR
MOVE *A1+,A0,W ;GRAB NEXT COLOR FROM THIS TABLE
JRN CRLOAD4 ;BR = NEXT PALETTE
ADDK 16,A2 ;INC THIS WAY SO WE DON'T OVERRUN PALETTES
JRUC CRLOAD3
CRLOAD4
ADDI 1000H,A2 ;NEXT PALETTE
SRL 12,A2
SLL 12,A2 ;MASK OFF LOW BULLSHIT
DSJ A6,CRLOAD1
MMFM SP,A0,A1,A2
RETS
********************************
* CLEAR THE SCREEN (Kill this, only used by diagnostics)
* only call with interrupts disabled and the dma shut down, otherwise
* use clr_scrn
SCRCLR CLR A0
MMTM SP,A1,A2
CLR A1
MOVE A1,@CMAPSEL ;SELECT COLOR MAP 0
MOVI SCREEN,A1
MOVI (SCRNE-SCREEN)/32,A2
SCRLP MOVE A0,*A1+,L
DSJS A2,SCRLP
MMFM SP,A1,A2
RETS
********************************
* Clear screen routine
SUBR CLR_SCRN
mmtm sp,a1,a2,a3
move @DISPLAYON,a3
; clr a1
; move a1,@DISPLAYON
callr dmaq_wait ;wait on dma
clr a0
move a0,@CMAPSEL ;Select color map 0
movi SCREEN,a1,L
movi ((SCRNE-2000H)-SCREEN)/32,a2,L
clrlp move a0,*a1+,L
dsjs a2,clrlp
move a3,@DISPLAYON
mmfm sp,a1,a2,a3
rets
********************************
* Animation list processor (JSRP)
* A1=Mode: 0=Process current frame
* 1=Process to end of list
* 4=Process current frame, no sleep (time retrn'd in a0)
* A8=*Object
* A9=*Ani list
* Rets:
* C set if end of animation list was hit
* A9=* to next frame or end of list
* Trashes scratch
*
* Animation script format
* .long *Image header or 0 if end
* .word Sleep time <-- BITS 0 - 7 ARE THE SLEEP TIME
* <-- BITS 8 -15 ARE THE FLAGS:
* Bit # Flag
* ----- ----
* 8-12 Unused
*BNEWPAL equ 13 13 New palette address is specified
*BFLIPBIT equ 14 14 New flip bits are specified
* Flag hierarchy: 15-8
* Options should follow in this order
FRANIM
PUSHP a3,a4
cmpi ROM,a9 ;Check for bogus script pointer
jrlo franerr
move a1,a3 ;A3=Mode
franl move *a9+,a1,L
jrz frannd ;End?
move *a8(OCTRL),a4 ;Current flags
move *a9+,a0 ;Sleep time
cmpi >100,a0
jrlo fran2 ;Just sleep?
PUSH a1,a2,a7
btst BFLIPBIT,a0
jrz frannobi ;No flip?
move *a9+,a2 ;Get the new flip flags
andni (M_FLIPV|M_FLIPH),a4 ;Clear the current flip status
or a2,a4 ;Set flag bits
frannobi
btst BNEWPAL,a0
jrz frannopa ;No pal?
move a0,a7
move *a9+,a0,L ;Get *pal
calla pal_getf
jrz fran10 ;No palette available?
move a0,*a8(OPAL) ;Store new palette
fran10
move a7,a0
frannopa
PULL a1,a2,a7
sll 32-8,a0 ;Kill special bits
srl 32-8,a0
fran2
calla ANI ;Setup new animation
cmpi 4,a3
jreq fran3 ;One frame, no sleep?
move a3,-*a12
calla PRCSLP ;Sleep
move *a12+,a3
jrnz franl ;Loop til end of list?
fran3
PULLP a3,a4
clrc ;Clear end flag
RETP
frannd
PULLP a3,a4
setc ;Return with end flag set
RETP
franerr
.if DEBUG
LOCKUP
eint
.else
CALLERR 8,0 ;Bad franim list
.endif
jruc frannd
#***************************************************************
* Animation list processor (Quick list version) (JSRP)
* A8=*Object
* A9=*FRANIM List
* Trashes A0-A4,A14,B0-B1
*
* Script format
* .long *Image hdr or 0 if end
* .word Sleep time <-- BITS 0 - 7 ARE THE SLEEP TIME
* <-- BITS 8 -15 ARE THE FLAGS:
* BIT # FLAG
* ----- ----
* 8-10,12 UNUSED
*BDELTAY equ 11 Word is added into YPOS
*BNEWPAL equ 13 New palette address is specified
*BFLIPBIT equ 14 New flip bits are specified
* Flag hierarchy: 15-8 Options should follow in this order
FRANIMQ
cmpi ROM,a9
jrhs frq80 ;Franim list OK?
.if DEBUG
LOCKUP
eint
.else
CALLERR 8,0 ;Bad franim list
.endif
jruc #x
#lp move *a8(OCTRL),a4 ;Current flags
move *a9+,a0 ;Sleep time
cmpi >100,a0
jrlo frq70 ;No special bits?
btst BFLIPBIT,a0 ;New flip?
jrz frq40
move *a9+,a2 ;Get the new flip flags
andni (M_FLIPV|M_FLIPH),a4 ;Clear the current flip status
or a2,a4 ;Set desired bits
frq40 btst BNEWPAL,a0 ;New palette ?
jrz frq60
move a0,a2
move a1,a3
move *a9+,a0,L ;Get the palette address
calla pal_getf ;Get a color map assignment
jrz frq50 ;No palette available?
move a0,*a8(OPAL) ;Set new palette
frq50 move a2,a0
move a3,a1
frq60 btst BDELTAY,a0
jrz frq65
move *a9+,a2 ;Get DY
move *a8(OYPOS),a3
add a2,a3
move a3,*a8(OYPOS)
frq65 sll 32-8,a0 ;Kill special bits
srl 32-8,a0
frq70 calla ANI
calla PRCSLP ;Sleep
frq80 move *a9+,a1,L ;Get frame
jrnz #lp
#x RETP
#***************************************************************
* Hardware security check code (1b00000 & 1b80000)
* >A0=0 if OK
* Trashes scratch
;OFF .equ >69d2
;SEC .equ >1b15f50-OFF
;FAKEO .equ ->b00050+OFF
;SECDB .equ 0
OFF .equ >7db0
SEC .equ >1b14030-OFF
FAKEO .equ ->b00030+OFF
SUBR security_chk
PUSH a2,a3,a4
clr a0
movi 63,a3
#lp move a3,a14
callr #sc
or a2,a0
subk 1,a3
jrge #lp
PULL a2,a3,a4
rets
#sc
movi SEC+FAKEO,a1
sll 15-5,a14
add a14,a1 ;Add a bogus offset
subi FAKEO,a1
move a14,*a1(OFF) ;Write 1 of 64 to sec
sub a14,a1 ;Sub offset so we read a different address
move *a1(OFF),a2 ;Read 1st sec value
sll 32-15,a2
srl 32-6,a2
sll 9,a2 ;Move to bits 9-14
xor a14,a2
sll 32-15,a2 ;Remove top bits
jrnz #x ;Bad value?
add a14,a1
srl 2+3,a14
add a14,a1
pushst
setf 6,0,0
move *a1(OFF+9),a2 ;Read 2nd sec value
move a2,b1
sll 24,b1
getpc a4
addi #sec_t-$,a4,W
add a4,a14
move *a1(OFF+>19),a2 ;Read 3rd sec value
move a2,b0
sll 16,b0
or b0,b1
move *a1(OFF+>29),a2 ;Read 4th sec value
move a2,b0
sll 8,b0
or b0,b1
move *a1(OFF+>39),a2 ;Read 5th sec value
move a2,b0
or b0,b1
popst
move *a14+,a2,L
move b1,a1
andi >3f3f3f3f,a1
xor a1,a2 ;A2=0 if OK
#x rets
#sec_t .long >21283b3b ;0
.long >2439383b
.long >31283b3b
.long >302b3938
.long >31283b3b
.long >302b3938
.long >232f2f2f
.long >26383b3b
.long >21283b3b ;20
.long >2439383b
.long >312a1224
.long >302b1120
.long >312a1224
.long >302b1120
.long >232d283b
.long >26383b3b
.long >2b3b3b3b ;40
.long >2e2e2e2e
.long >39383b1b
.long >383b3b1b
.long >3b3b3b1b
.long >3a3a3a1a
.long >2b3b3b3b
.long >2e2e2e2e
.long >2b39383b ;60
.long >2e2e2e2e
.long >393a1a18
.long >383b1b1b
.long >3b3b1b1b
.long >3a3a1a18
.long >2b39383b
.long >2e2e2e2e
.long >01202b3b ;80
.long >0431283b
.long >11202b3b
.long >1021283b
.long >11202b3b
.long >1021283b
.long >03273b3b
.long >06302b39
.long >09302b39 ;A0
.long >0c232f2f
.long >19322e06
.long >18312a12
.long >19322e06
.long >18312a12
.long >0b31283b
.long >0e26383b
.long >03273b3b ;C0
.long >06302b39
.long >11202b3b
.long >1021283b
.long >13273938
.long >12243938
.long >03273b3b
.long >06302b39
.long >0b31283b ;E0
.long >0e26383b
.long >19322e06
.long >18312a12
.long >1b332f05
.long >1a302b11
.long >0b31283b
.long >0e26383b
.def secend
secend
; .if SECDB
; clr a0
; rets
; movi SCRATCH,a5
; clr a0
; clr a3
;#tlp move a3,a14
; callr #sc
; move a1,*a5+,L
; addk 1,a3
; cmpi 128,a3
; jrlt #tlp
;
; .else
;;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; PUSH a2,a3,a4
; clr a0
; movi 128-1,a3
;#lp move a3,a14
; callr #sc
; or a2,a0
; subk 1,a3
; jrge #lp
; PULL a2,a3,a4
;
; .endif
; rets
;
;;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;#sc
; move a3,a1
; srl 6,a1 ;Use bit 7 for security range (0 or 1)
; sll 19,a1
; addi SEC+FAKEO,a1
; sll 16-6,a14
; add a14,a1 ;Add a bogus offset
; subi FAKEO,a1
; move a14,*a1(OFF) ;Write 1 of 64 to sec
; sub a14,a1 ;Sub offset so we read a different address
; move *a1(OFF),a2 ;Read 1st sec value
; sll 32-15,a2
; srl 32-6,a2
; sll 9,a2 ;Move to bits 10-15
; xor a14,a2
; sll 32-15,a2 ;Remove top bits
; jrnz #x ;Bad value?
;
; add a14,a1
; srl 5,a14
; add a14,a1
; pushst
; setf 6,0,0
; move *a1(OFF+9),a2 ;Read 2nd sec value
; move a2,b1
; sll 24,b1
; getpc a4
; addi #sec_t-$,a4,W
; add a4,a14
; move *a1(OFF+>49),a2 ;Read 3rd sec value
; move a2,b0
; sll 16,b0
; or b0,b1
; move *a1(OFF+>89),a2 ;Read 4th sec value
; move a2,b0
; sll 8,b0
; or b0,b1
; move *a1(OFF+>c9),a2 ;Read 5th sec value
; move a2,b0
; or b0,b1
; popst
; move *a14+,a2,L
; move b1,a1
;
; xor a1,a2 ;A2=0 if OK
;
;#x rets
;#sec_t
; .long >00000000
; .long >04081020
; .long >08102000
; .long >0C183122
; .long >10200000
; .long >14281020
; .long >18312204
; .long >1C393326
; .long >20000001
; .long >24081021
; .long >28102000
; .long >2C183122
; .long >30200001
; .long >34281021
; .long >38312204
; .long >3C393326
; .long >00000102
; .long >04081122
; .long >08102102
; .long >0C183122
; .long >10200000
; .long >14281020
; .long >18312204
; .long >1C393326
; .long >20000103
; .long >24081123
; .long >28102102
; .long >2C183122
; .long >30200001
; .long >34281021
; .long >38312204
; .long >3C393326
; .long >00010204
; .long >04091224
; .long >08112204
; .long >0C193326
; .long >10210204
; .long >14291224
; .long >18312204
; .long >1C393326
; .long >20000001
; .long >24081021
; .long >28102000
; .long >2C183122
; .long >30200001
; .long >34281021
; .long >38312204
; .long >3C393326
; .long >00010306
; .long >04091326
; .long >08112306
; .long >0C193326
; .long >10210204
; .long >14291224
; .long >18312204
; .long >1C393326
; .long >20000103
; .long >24081123
; .long >28102102
; .long >2C183122
; .long >30200001
; .long >34281021
; .long >38312204
; .long >3C393326
; .long >00000000
; .long >01201028
; .long >02213018
; .long >03012030
; .long >04223138
; .long >05022110
; .long >06030120
; .long >07231108
; .long >08042231
; .long >09243219
; .long >0A251229
; .long >0B050201
; .long >0C261309
; .long >0D060321
; .long >0E072311
; .long >0F273339
; .long >10080422
; .long >1128140A
; .long >1229343A
; .long >13092412
; .long >142A351A
; .long >150A2532
; .long >160B0502
; .long >172B152A
; .long >180C2613
; .long >192C363B
; .long >1A2D160B
; .long >1B0D0623
; .long >1C2E172B
; .long >1D0E0703
; .long >1E0F2733
; .long >1F2F371B
; .long >20100804
; .long >2130182C
; .long >2231381C
; .long >23112834
; .long >2432393C
; .long >25122914
; .long >26130924
; .long >2733190C
; .long >28142A35
; .long >29343A1D
; .long >2A351A2D
; .long >2B150A05
; .long >2C361B0D
; .long >2D160B25
; .long >2E172B15
; .long >2F373B3D
; .long >30180C26
; .long >31381C0E
; .long >32393C3E
; .long >33192C16
; .long >343A3D1E
; .long >351A2D36
; .long >361B0D06
; .long >373B1D2E
; .long >381C2E17
; .long >393C3E3F
; .long >3A3D1E0F
; .long >3B1D0E27
; .long >3C3E1F2F
; .long >3D1E0F07
; .long >3E1F2F37
; .long >3F3F3F1F
;
; .def secend
;secend
.end