wwf-wrestlemania/UTIL.ASM

3085 lines
58 KiB
NASM
Raw Permalink Normal View History

2021-04-06 15:21:54 -07:00
**************************************************************
*
* 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
*
* COPYRIGHT (C) 1992 WILLIAMS ELECTRONICS GAMES, INC.
*
*.Last mod - 3/22/93 16:25
**************************************************************
.file "util.asm"
.title "utility subroutines"
.width 132
.option b,d,l,t
.mnolist
.include "mproc.equ"
.include "display.equ"
.include "gsp.equ"
.include "sys.equ"
.include "game.equ"
.include "audit.equ"
.include "macros.h"
;utility subroutine equates
.def SCRCLR
.def OBJOFF,OBJON
.def STRLNRM,STRCNRM,STRCNRMO,STRLNRMO,STRCNRMO_1,CYCLE_TABLE
.def STRCNRMO_2
.def BLNKAREA
.def FRANIM,FRANIMQ
.def STRNGLEN
.def STRRNRM,FILLAREA
.DEF SPECIAL_WIPEOUT
******************************************************************************
* EXTERNAL REFERENCES
.ref IGNORE_CHAR_WIDTH,debris_count,are_we_waiting_f
.ref SPECIAL_DISPLAY_INIT,switches_cur,dirqtimer,pal_set
.ref SYSCOPY,GET_ADJ,display_init,GAMSTATE,pal_find
.ref pal_getf,dpageflip,SOUNDSUP,IRQSKYE,PSTATUS,PALRAM
.ref switches_down,gndstat,pal_init,BAKBITS,WFLG,WSPEED
.ref COLRTEMP,ENDLESS_SOUND,get_but_val_cur,get_but_val_down
.ref get_stick_val_cur,get_stick_val_down
******************************************************************************
.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
********************************
* 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!
clr a0
move a0,@gndstat
move a0,@dtype
move a0,@are_we_waiting_f
move a0,@IGNORE_CHAR_WIDTH
MOVE A0,@ENDLESS_SOUND
move a0,@debris_count
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
;* A13=*Process
;* 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
.if 0
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 BEGINOBJW
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
.endif
********************************
* 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
.if 0
********************************
* 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
.endif
********************************
* 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
SUBI 32,A14
MOVE *A14,A1,L
PUSHP A14,A1
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
PULLP A1,A14
PUSHP A1,A14
MOVE *A1,A0,L
CMP A0,A14
JRNE KILL_US
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
KILL_US
DIE
****************************************************************
* 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
;CENTER JUSTIFY, NORMAL, OBJECT LIST, CONSTANT NON-ZERO
STRCNRMO_2
mmtm a12,a1,a2,a3,a4,a6,a14
movi DMACNZ|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
move a2,*a0(ODOFF),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
* >A0=0 if OK
* Trashes scratch
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
#***************************************************************
* Shake screen as if an earthquake is in effect (horizontally)
* A10 = # ticks to shake and power of shake
* Note: time to shake must be more than 6 ticks
BSSX #SHK_ON,16 ;is a shake in progress?
BSSX #X_ADJ,32 ;current deviation from rest
SUBR HORZ_SHAKER2
;check for a valid a10
move a10,a10
jrn #done
jrz #done
move @#SHK_ON,a0
jrz #no_shake
;abort shake currently in progress
movi HZSHAKE_PID,a0
calla KIL1C
move @#X_ADJ,a14
move @WORLDTLX,a0,L
sub a14,a0
move a0,@WORLDTLX,L
#no_shake
;set the 'in progress' flag
movk 1,a14
move a14,@#SHK_ON
;create the shaker process
CREATE HZSHAKE_PID,#shaker
#done
rets
#shaker
;a9 = index into sine table
;a10 = time left
;a11 = original time left
;initialize
movi #last_entry,a9
move a10,a11
#loop
;calculate the new offset
;get the cosine
move a9,a14
X16 a14
addi #sine_table,a14
move *a14,a0,W
;get the exp (index is 64 - (64 * a10 / a11)
move a10,a1
X64 a1
divu a11,a1
neg a1
addi 64,a1
X16 a1
addi #exp_table,a1
move *a1,a1,W
;multiply
mpys a0,a1
;scale
sra 5,a1
mpyu a11,a1
move a1,@#X_ADJ,L
;update the table pointer
dsj a9,#table_ok
movi #last_entry,a9
#table_ok
;apply it
move @WORLDTLX,a14,L
add a14,a1
move a1,@WORLDTLX,L
;nap
SLEEPK 1
;undo it
move @#X_ADJ,a14,L
move @WORLDTLX,a1,L
sub a14,a1
move a1,@WORLDTLX,L
;loop
dsj a10,#loop
;all done
clr a14
move a14,@#SHK_ON
move a14,@#X_ADJ
DIE
#sine_table ;deg
.word -601 ;324
.word -973 ;288
.word -973 ;252
.word -601 ;216
.word 0 ;180
.word 602 ;144
.word 974 ;108
.word 974 ;72
.word 602 ;36
.word 0 ;0
#last_entry equ 9
;values of e^(-x) for values from 0 to 7, in 64 divisions
; e.g. e^-1.5 is the 32nd entry
; all values are multiplied by 1024
#exp_table ;damps at speed 5
.word 1024,945,873,807,745,688,636,587
.word 542,501,463,427,395,364,337,311
.word 287,265,245,226,209,193,178,165
.word 152,140,130,120,110,102,94,87
.word 80,74,68,63,58,54,50,46
.word 42,39,36,33,31,28,26,24
.word 22,20,19,17,16,15,14,13
.word 12,11,10,9,8,8,7,6
#***************************************************************
* Shake screen as if an earthquake is in effect
* A10 = # ticks to shake and power of shake
* Note: time to shake must be more than 6 ticks
BSSX #SHK_ON,16 ;is a shake in progress?
BSSX #Y_ADJ,32 ;current deviation from rest
SUBR SHAKER2
;check for a valid a10
move a10,a10
jrn #done
jrz #done
move @#SHK_ON,a0
jrz #no_shake
;abort shake currently in progress
movi SHAKE_PID,a0
calla KIL1C
move @#Y_ADJ,a14
move @WORLDTLY,a0,L
sub a14,a0
move a0,@WORLDTLY,L
#no_shake
;set the 'in progress' flag
movk 1,a14
move a14,@#SHK_ON
;create the shaker process
CREATE SHAKE_PID,#shaker
#done
rets
#shaker
;a9 = index into sine table
;a10 = time left
;a11 = original time left
;initialize
movi #last_entry,a9
move a10,a11
#loop
;calculate the new offset
;get the cosine
move a9,a14
X16 a14
; addi #cosine_table,a14
addi #sine_table,a14
move *a14,a0,W
;get the exp (index is 64 - (64 * a10 / a11)
move a10,a1
X64 a1
divu a11,a1
neg a1
addi 64,a1
X16 a1
addi #exp_table,a1
move *a1,a1,W
;multiply
mpys a0,a1
;scale
sra 5,a1
mpyu a11,a1
move a1,@#Y_ADJ,L
;update the table pointer
dsj a9,#table_ok
movi #last_entry,a9
#table_ok
;apply it
move @WORLDTLY,a14,L
add a14,a1
move a1,@WORLDTLY,L
;nap
SLEEPK 1
;undo it
move @#Y_ADJ,a14,L
move @WORLDTLY,a1,L
sub a14,a1
move a1,@WORLDTLY,L
;loop
dsj a10,#loop
;all done
clr a14
move a14,@#SHK_ON
move a14,@#Y_ADJ
DIE
;45-degree increments
;#cosine_table ;deg
; .word 724 ;315
; .word 0 ;270
;#sine_table ;deg
; .word -723 ;225 ;315
; .word -1023 ;180 ;270
; .word -723 ;135 ;225
; .word 0 ;90 ;180
; .word 724 ;45 ;135
; .word 1024 ;0 ;90
; .word 724 ;45
; .word 0 ;0
;#last_entry equ 7
;36-degree increments
#cosine_table ;deg
.word 828 ;324
.word 316 ;288
.word -315 ;252
.word -827 ;216
.word -102 ;180
.word -827 ;144
.word -315 ;108
.word 316 ;72
.word 828 ;36
.word 1024 ;0
#sine_table ;deg
.word -601 ;324
.word -973 ;288
.word -973 ;252
.word -601 ;216
.word 0 ;180
.word 602 ;144
.word 974 ;108
.word 974 ;72
.word 602 ;36
.word 0 ;0
#last_entry equ 9
;30-degree increments
;#cosine_table ;deg
; .word 887 ;330
; .word 512 ;300
; .word 0 ;270
;#sine_table ;deg
; .word -511 ;240 ;330
; .word -886 ;210 ;300
; .word -1023 ;180 ;270
; .word -886 ;150 ;240
; .word -511 ;120 ;210
; .word 0 ;90 ;180
; .word 512 ;60 ;150
; .word 887 ;30 ;120
; .word 1024 ;0 ;90
; .word 887 ;60
; .word 512 ;30
; .word 0 ;0
;#last_entry equ 11
;values of e^(-x) for values from 0 to 7, in 64 divisions
; e.g. e^-1.5 is the 32nd entry
; all values are multiplied by 1024
;#exp_table ;damps at speed 7
; .word 1024,916,819,733,656,587,525,470
; .word 420,376,337,301,269,241,216,193
; .word 173,154,138,124,110,99,88,79
; .word 71,63,56,50,45,40,36,32
; .word 29,26,23,20,18,16,15,13
; .word 12,10,9,8,7,6,6,5
; .word 4,4,3,3,3,2,2,2
; .word 2,1,1,1,1,1,1,0
;#exp_table ;damps at speed 6
; .word 1024,930,846,769,699,636,578,525
; .word 477,434,395,359,326,296,269,245
; .word 223,202,184,167,152,138,125,114
; .word 104,94,86,78,71,64,58,53
; .word 48,44,40,36,33,30,27,24
; .word 22,20,18,17,15,14,12,11
; .word 10,9,8,7,7,6,5,5
; .word 4,4,4,3,3,3,2,2
#exp_table ;damps at speed 5
.word 1024,945,873,807,745,688,636,587
.word 542,501,463,427,395,364,337,311
.word 287,265,245,226,209,193,178,165
.word 152,140,130,120,110,102,94,87
.word 80,74,68,63,58,54,50,46
.word 42,39,36,33,31,28,26,24
.word 22,20,19,17,16,15,14,13
.word 12,11,10,9,8,8,7,6
;#exp_table ;damps at speed 2
; .word 1024,992,961,930,901,873,846,819
; .word 794,769,745,722,699,677,656,636
; .word 616,596,578,560,542,525,509,493
; .word 477,463,448,434,420,407,395,382
; .word 370,359,347,337,326,316,306,296
; .word 287,278,269,261,253,245,237,230
; .word 223,216,209,202,196,190,184,178
; .word 173,167,162,157,152,147,143,138
;original Shawn shaker
.BSS AMP,16
.BSS AMPCNT,16
.BSS XSET,16
.BSS YSET,16
.BSS SHK_ON,16
SUBR SHAKER
move @SHK_ON,a0
jrnz #x
move a10,a11
movk 2,a0
move a0,@SHK_ON
divs a0,a11
movk 6,a0
move a0,@AMP
move a11,@AMPCNT
CREATE0 shakelp
#x RETS
;only shake vertically
shakelp
.if 0
move @AMP,a0
calla RNDRNG0
move a0,@XSET
move @AMP,a0
calla RNDRNG0
move a0,@YSET
move @HCOUNT,a14
btst 0,a14
jrz #shakey
move @XSET,a1
move @WORLDTLX,a0,L
sll 16,a1
add a1,a0
move a0,@WORLDTLX,L
SLEEPK 1
move @XSET,a1
move @WORLDTLX,a0,L
sll 16,a1
sub a1,a0
move a0,@WORLDTLX,L
jruc shakelp
.endif
#shakey
move @AMP,a0
calla RNDRNG0
move a0,@YSET
move @YSET,a1
move @WORLDTLY,a0,L
sll 16,a1
add a1,a0
move a0,@WORLDTLY,L
SLEEPK 1
move @YSET,a1
move @WORLDTLY,a0,L
sll 16,a1
sub a1,a0
move a0,@WORLDTLY,L
move @AMPCNT,a2
dec a2
move a2,@AMPCNT
jrnz #ampok
move a11,@AMPCNT
move @AMP,a0
cmpi 1,a0
jrz #ampok
dec a0
move a0,@AMP
#ampok
dsj a10,shakelp
move a10,@SHK_ON
DIE
#*****************************************************************************
*
* RETURN: a0 = start button bits
*-----------------------------------------------------------------------------
SUBR get_all_starts_cur
clr a1
move @PSTATUS,a2
btst 0,a2
jrz #no_player1
clr a0 ;player 1
calla get_start_cur
or a0,a1
#no_player1
btst 1,a2
jrz #no_player2
movk 1,a0 ;player 2
calla get_start_cur
or a0,a1
#no_player2
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = start button bits
*-----------------------------------------------------------------------------
SUBR get_all_starts_down
clr a1
move @PSTATUS,a2
btst 0,a2
jrz #no_player1
clr a0 ;player 1
calla get_start_down
or a0,a1
#no_player1
btst 1,a2
jrz #no_player2
movk 1,a0 ;player 2
calla get_start_down
or a0,a1
#no_player2
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = start bit
*-----------------------------------------------------------------------------
SUBR get_start_cur
sll 4,a0 ;x 16 bits
addi start_offs,a0
move *a0,a0
addi switches_cur,a0
move *a0,a0
andi 1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = start bit
*-----------------------------------------------------------------------------
SUBR get_start_down
sll 4,a0 ;x 16 bits
addi start_offs,a0
move *a0,a0
addi switches_down,a0
move *a0,a0
andi 1,a0
rets
start_offs .word 12h,15h
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_sticks_cur
clr a1
move @PSTATUS,a2
btst 0,a2
jrz #no_player1
clr a0 ;player 1
calla get_stick_val_cur
or a0,a1
#no_player1
btst 1,a2
jrz #no_player2
movk 1,a0 ;player 2
calla get_stick_val_cur
or a0,a1
#no_player2
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_sticks_cur2
clr a1
clr a0 ;player 1
calla get_stick_val_cur
or a0,a1
movk 1,a0 ;player 2
calla get_stick_val_cur
or a0,a1
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_sticks_down
clr a1
move @PSTATUS,a2
btst 0,a2
jrz #no_player1
clr a0 ;player 1
calla get_stick_val_down
or a0,a1
#no_player1
btst 1,a2
jrz #no_player2
movk 1,a0 ;player 2
calla get_stick_val_down
or a0,a1
#no_player2
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_sticks_down2
clr a1
clr a0 ;player 1
calla get_stick_val_down
or a0,a1
movk 1,a0
calla get_stick_val_down ;player 2
or a0,a1
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_buttons_cur
clr a1
move @PSTATUS,a2
btst 0,a2
jrz #no_player1
clr a0 ;player 1
calla get_but_val_cur
or a0,a1
#no_player1
btst 1,a2
jrz #no_player2
movk 1,a0 ;player 2
calla get_but_val_cur
or a0,a1
#no_player2
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_buttons_cur2
clr a1
clr a0 ;player 1
calla get_but_val_cur
or a0,a1
movk 1,a0 ;player 2
calla get_but_val_cur
or a0,a1
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_buttons_down
clr a1
move @PSTATUS,a2
btst 0,a2
jrz #no_player1
clr a0 ;player 1
calla get_but_val_down
or a0,a1
#no_player1
btst 1,a2
jrz #no_player2
movk 1,a0 ;player 2
calla get_but_val_down
or a0,a1
#no_player2
move a1,a0
rets
#*****************************************************************************
*
* RETURN: a0 = joy switch bits
*-----------------------------------------------------------------------------
SUBR get_all_buttons_down2
clr a1
clr a0 ;player 1
calla get_but_val_down
or a0,a1
movk 1,a0 ;player 2
calla get_but_val_down
or a0,a1
move a1,a0
rets
#*****************************************************************************
* Get random # with mask
* A0=Mask
* >A0=Rnd # (Pass CC)
* Trashes scratch
SUBRP rnd
move @RAND,a1,L
rl a1,a1
move @HCOUNT,a14
rl a14,a1
add sp,a1
move a1,@RAND,L
and 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
.if DEBUG
#*****************************************************************************
SUBR tint_on
PUSH a0,a1
movi 07fffh,a0 ;all bits on (5 bits RGB (white))
movi COLRAM,a1 ;base address of colour ram
move a0,*a1 ;restore colour
PULL a0,a1
rets
#*****************************************************************************
SUBR tint_off
PUSH a0,a1
clr a0 ;all bits off (black)
movi 8<<10+8<<5+8,a0 ;grey
movi COLRAM,a1 ;base address of colour ram
move a0,*a1 ;restore colour
PULL a0,a1
rets
.endif
#*****************************************************************************
* Change an objects image (Doesn't check VFLIP)
* A0=*New image
* A1=New flip flags & const
* A8=*Obj
* Trashes scratch
SUBR civanic
move *a8(OCTRL),a1,W
SUBR civani
cmpi ROM,a0
jrlo #anierr
;set new anim points
move *a0(IANIOFFX),*a8(ODXOFF),W
move *a0(IANIOFFY),*a8(ODYOFF),W
move a0,*a8(OIMG),L
move *a0(0),*a8(OSIZE),L
move *a0(ISAG),*a8(OSAG),L
setf 5,0,0
move *a0(ICTRL+7),*a8(OCTRL+7) ;Write 5 z comp bits
setf 6,0,0
move a1,*a8(OCTRL) ;Write 6 low bits
setf 16,1,0
#x rets
#anierr
.if DEBUG
LOCKUP
eint
.else
CALLERR 2,2
.endif
jruc #x
******************************************************************************
.end