wwf-wrestlemania/MPROC.ASM

682 lines
12 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.

**************************************************************
* GSP MULTI-PROCESSING SYSTEM
*
* Software: Eugene P Jarvis, Shawn Liptak
* Initiated: 1988?
*
* Modified: Shawn Liptak, 7/?/91 -New KILL stuff (Total carnage)
* Shawn Liptak, 8/12/91 -KOP code
* Shawn Liptak, 10/27/91 -Shawn.hdr
* Shawn Liptak, 2/18/92 -Basketball (cleanup)
* Shawn Liptak, 7/1/92 -Slowmotion
* Jason Skiles, 2/23/94 -Super-procs
*
* COPYRIGHT (C) 1992 WILLIAMS ELECTRONICS GAMES, INC.
*
*.Last mod - 2/23/94 11:45
**************************************************************
.file "mproc.asm"
.title "GSP multi-processing system"
.width 132
.option b,d,l,t
.mnolist
.include "gsp.equ"
.include "sys.equ"
.include "mproc.equ"
.include "display.equ"
.include "macros.h"
******************************************************************************
* EXTERNAL REFERENCES
.ref dirqtimer
.ref L_TIMER
******************************************************************************
.bss PRCSTR ,NPROC*PRCSIZ ;Process data blocks
; Note: A super-proc is spotted by comparing its address to SPRCSTR.
; Make SURE that SPRCSTR always rests higher in RAM than PRCSTR.
; It would be A Bad Thing were this test to become unreliable.
.bss SPRCSTR ,SNPROC*SPRCSIZ ;Super-process data blocks
.sect "FIXED"
ACTIVE .long 0
FREE .long 0
SFREE .long 0
.text
********************************
* Process list initialize
* >A13=*Process active list
* Trashes scratch
SUBR process_init
movi ACTIVE,a13 ;Init A13
clr a0
move a0,*a13,L ;Empty list
movi PRCSTR,a1
move a1,@FREE,L ;Full free list
movi NPROC,b0 ;# of processes
#lp move a1,a14
addi PRCSIZ,a1
move a1,*a14,L ;Set link
dsj b0,#lp
move a0,*a14,L ;Null last link
;initialize the super-proc list
movi SPRCSTR,a1
move a1,@SFREE,L
movi SNPROC,b0 ;# of processes
#slp move a1,a14
addi SPRCSIZ,a1
move a1,*a14,L ;Set link
dsj b0,#slp
move a0,*a14,L ;Null last link
rets
#*******************************
* Process dispatch
SUBR process_dispatch
.if 0
movi 31*32,a0 ;Proc usage
move a0,@ERASELOC
#dmawt move b13,b13
jrge #dmawt
movk 6,a0 ;DMA usage
move a0,@ERASELOC
#noline
.endif
.if DEBUG
.ref slowmotion
move @slowmotion,a0
#smlp move @dirqtimer,a1
cmp a1,a0
jrge #smlp
.endif
movi ACTIVE,a13 ;*Proc list
clr a0
move a0,@dirqtimer ;Tell DIRQ to flip and draw
#lp
;inlined obj_yzsort
movi OBJLST,a0
movk 1,a1 ;Lowest Z
sll 31,a1 ;Make >80000000
clr a8
jruc yzlp
.align
yz0
move *a2(OZPOS),a6 ;Get Z
move *a2(OYPOS),a7 ;Get Y
cmp a1,a6
jrgt priok ;Next Z > Current Z?
jrlt priswap
cmp a5,a7
jrge priok ;Next Y > Current Y?
priswap dint ;>Make current after next
movk 1,a8
move a2,*a4,L ;Point last to next
move *a2,*a0,L ;Point current to block after next
move a0,*a2,L ;Point next to current
movk 1,a8
eint
move a2,a4
jruc yzlp ;Continue sort of current obj
priok move a0,a4 ;A4=*Last obj
move a2,a0 ;A0=*Current obj
move a6,a1 ;A1=Current Z
move a7,a5 ;A5=Current Y
yzlp move *a0,a2,L ;A2=*Next obj
jrnz yz0
move a8,a8
jrnz #lp
#lp2
move @dirqtimer,a0
jrz #lp2 ;Wait?
calla L_TIMER ;Linky timer (FIX so BOG time is OK!)
jruc prcd1
********************************
* Process sleep
* Stack=*Wakeup
* A0=Sleep time
PRCSLP
PULL a7 ;Get *Wakeup
.if DEBUG
cmpi >FF800000,a7
jrhs #psok
LOCKUP ;bad wake address!
#psok
.endif
PRCLSP move a13,a1
addi PDATA,a1
mmtm a1,a7,a8,a9,a10,a11,a12 ;*Wakeup, regs, *stack
move a0,-*a1 ;sleep
.if DEBUG
move a13,a0
cmpi SPRCSTR,a13 ;is it a superproc?
jrge #super_stkchk
addi PSDATA,a0
cmp a0,a12
jrlt $ ;stick on stack overflow
addi PRCSIZ-PSDATA,a0
cmp a0,a12
jrgt $ ;stick on stack underflow
jruc prcd1
#super_stkchk
addi SPSDATA,a0
cmp a0,a12
jrlt $ ;stick on stack overflow
addi SPRCSIZ-SPSDATA,a0
cmp a0,a12
jrgt $ ;stick on stack underflow
jruc prcd1
.endif
prcd1
move *a13,a13,L
jrz prcdx ;End?
move *a13(PTIME),a0 ;Get count
subk 1,a0
move a0,*a13(PTIME) ;Put it back
jrgt prcd1 ;Not ready?
move a13,a1 ;>Dispatch
addi >40,a1
mmfm a1,a7,a8,a9,a10,a11,a12 ;*Wake, regs, *stack
#go
.if DEBUG
cmpi >FF800000,a7
jrhs #wake_ok
LOCKUP ;bad wake address!
#wake_ok
.endif
jump a7 ;Do process
prcdx
rets
********************************
* Process kills itself
SUCIDE
movi ACTIVE,a1
suclp move a1,a2 ;save previous
move *a1,a1,L
jrz sucerr
cmp a1,a13
jrne suclp ;!Us
move *a1,*a2,L ;Unlink
cmpi SPRCSTR,a1
jrge #suclink_sproc
move @FREE,*a1+,L ;Link into free list at start
subk 32,a1
move a1,@FREE,L
move a2,a13 ;Set current process to previous
jruc prcd1 ;Continue with dispatch
#suclink_sproc
move @SFREE,*a1+,L ;Link into super-proc free list at start
subk 32,a1
move a1,@SFREE,L
move a2,a13 ;Continue with dispatch
jruc prcd1
sucerr
.if DEBUG
LOCKUP
eint
.else
CALLERR 5,0
.endif
movi ACTIVE,a13 ;*Proc list
jruc prcd1
#*******************************
* Kill process (won't kill self)
* A0=*Process to kill
* Trashes scratch
KILL
cmp a0,a13
jreq #x ;Killing self?
movi ACTIVE,a1
#lp move a1,a14 ;Save previous
move *a1,a1,L
jrz killerr ;Can't find?
cmp a1,a0
jrne #lp ;Not the one?
move *a0,*a14,L ;Unlink from active
cmpi SPRCSTR,a0
jrge #kill_super
move @FREE,*a0+,L ;Link into free list at start
subk 32,a0
move a0,@FREE,L
jruc #x
#kill_super
move @SFREE,*a0+,L ;Link into free list at start
subk 32,a0
move a0,@SFREE,L
jruc #x
#x rets
killerr
.if DEBUG
LOCKUP
eint
.else
CALLERR 6,0
.endif
jruc #x
********************************
* Create a process
* A1=PID, A7=PC, A8,A9,A10,A11 Passed parameters
* A13=*Current process
* >A0=*Created process (Flags invalid!)
* Trashes A14,B0-B1
GETPRC
move a12,b0
move @FREE,a0,L
jrz nonelft ;No more?
move *a0,a14,L
move a14,@FREE,L ;Unlink from free list
move *a13,*a0,L ;Link into active list after current process
move a0,*a13,L
jruc xferprc0
nonelft
.if DEBUG
LOCKUP
eint
.else
CALLERR 4,2
.endif
jruc getpx
********************************
*
* Identical to GETPRC, except that the created process is placed in the
* process list immediately BEFORE the parent process, not after.
*
* A1=PID, A7=PC, A8,A9,A10,A11 Passed parameters
* A13=*Current process
* >A0=*Created process (Flags invalid!)
* Trashes A14,B0-B1
GETPRC_INSERT
move a12,b0
move @FREE,a0,L
jrz nonelft ;No more?
move *a0,a14,L
move a14,@FREE,L ;Unlink from free list
;find the process that's immediately before the parent.
PUSH a1,a2
movi ACTIVE,a1
move *a1,a2,L
#search
cmp a13,a2
jreq #found
move a2,a1
move *a1,a2,L
jrnz #search
;We've been called by a nonexistent process. How odd.
.if DEBUG
LOCKUP
.endif
PULL a1,a2
jruc getpx
#found
;a2 is parent proc, a1 is before that. slip in between.
move a0,*a1,L
move a2,*a0,L
PULL a1,a2
jruc xferprc0
; move *a13,*a0,L ;Link into active list after current process
; move a0,*a13,L
; jruc xferprc0
********************************
* Create a super-process
* A1=PID, A7=PC, A8,A9,A10,A11 Passed parameters
* A13=*Current process
* >A0=*Created process (Flags invalid!)
* Trashes A14,B0-B1
SUBR GETSPRC
move a12,b0
move @SFREE,a0,L
jrz nonelft ;No more?
move *a0,a14,L
move a14,@SFREE,L ;Unlink from free list
move *a13,*a0,L ;Link into active list after current process
move a0,*a13,L
jruc xferprc0
********************************
* Transfer control of an existing process
* A0=*Process to be xfer'd
* A1=New PID
* A7=*Wake address
* A8-A11=Passed to the xfer'd proc
* Trashes A14,B0-B1
XFERPROC
move a12,b0
xferprc0
cmpi ROM,a7
jrlo procwakeerr ;Error?
move a0,a14
addi PDATA,a14
move a0,a12 ;Reset process stack pointer
addi SPRCSIZ,a12
cmpi SPRCSTR,a0
jrge #superproc
addi PRCSIZ-SPRCSIZ,a12
#superproc
mmtm a14,a7,a8,a9,a10,a11,a12 ;Stuff wake, regs, p stack ptr
movk 1,a12
move a12,-*a14 ;Wakeup next time
move a1,-*a14 ;ID
getpx move b0,a12
rets ;Flags are trashed!!!
procwakeerr
.if DEBUG
LOCKUP
eint
.else
CALLERR 7,0
.endif
jruc getpx
********************************
* Kill a class of processes except for self
* A0=PID
* A1=Mask (bits to keep)
* Trashes scratch
KILALL
not a1
jruc KILALLN
********************************
* Kill one class of processes
* A0=PID
* Trashes scratch
KIL1C
clr a1
#*******************************
* Kill a class of processes
* A0=PID
* A1=!Mask (bits to remove)
* Trashes scratch
KILALLN
move a2,b0
move a3,b1
zext a1 ;Won't kill PIDS >8000+
andn a1,a0 ;Form match
movi ACTIVE,a2
#lp move a2,a3 ;Save previous
move *a2,a2,L
jrz #x ;Done?
move *a2(PROCID),a14
JRN #lp ;ALLOW INDESTRUCTABLES (ANYTHING 8000h+)
; jrnn #ok
; LOCKUP
;#ok
andn a1,a14 ;Apply mask
cmp a0,a14
jrne #lp ;No match?
cmp a2,a13
jreq #lp ;Current proecess?
move *a2,*a3,L ;Unlink
cmpi SPRCSTR,a2
jrge #spr
move @FREE,a14,L ;Link into free list at start
move a14,*a2,L
move a2,@FREE,L
move a3,a2
jruc #lp
#spr
move @SFREE,a14,L ;Link into super-proc free list at start
move a14,*a2,L
move a2,@SFREE,L
move a3,a2
jruc #lp
#x move b0,a2
move b1,a3
rets
********************************
* Kill one class of indestructable processes
*
* NOTE - BE EXTEMELY CAREFUL WITH THIS FUNCTION (IT KILLS INDESTRUCTABLES)
*
* A0=PID
* Trashes scratch
SUBR IKIL1C
clr a1
#*******************************
* Kill a class of indestructable processes
*
* NOTE - BE EXTEMELY CAREFUL WITH THIS FUNCTION (IT KILLS INDESTRUCTABLES)
*
* A0=PID
* A1=!Mask (bits to remove)
* Trashes scratch
SUBR IKILALLN
move a2,b0
move a3,b1
sext a0
andn a1,a0 ;Form match
movi ACTIVE,a2
#lp move a2,a3 ;Save previous
move *a2,a2,L
jrz #x ;Done?
move *a2(PROCID),a14
andn a1,a14 ;Apply mask
cmp a0,a14
jrne #lp ;No match?
cmp a2,a13
jreq #lp ;Current proecess?
move *a2,*a3,L ;Unlink
cmpi SPRCSTR,a2
jrge #spr
move @FREE,a14,L ;Link into free list at start
move a14,*a2,L
move a2,@FREE,L
move a3,a2
jruc #lp
#spr
move @SFREE,a14,L ;Link into super-proc free list at start
move a14,*a2,L
move a2,@SFREE,L
move a3,a2
jruc #lp
#x move b0,a2
move b1,a3
rets
;********************************
;* Knock out one class of processes
;* A0=PID, A2=Time to add
;* Trashes scratch
;
;KOP_1C
; clr a1
;
;#*******************************
;* Knock out a class of processes
;* A0=PID, A1=!Mask (Bits to remove), A2=Time to add
;* Trashes scratch
;
;KOP_ALL
; move a3,b0
; andn a1,a0 ;Form match
; movi ACTIVE,a3,L
;
;#lp move *a3,a3,L ;Get next
; jrz #x ;End?
; move *a3(PROCID),a14
; andn a1,a14 ;Mask
; cmp a0,a14
; jrnz #lp ;No match?
;
; move *a3(PTIME),a14 ;Add sleep
; add a2,a14
; move a14,*a3(PTIME)
; jruc #lp
;
;#x move b0,a3
; rets
#*******************************
* Check to see if process exists
* A0=*Process
* Rets: Z=Not found, NZ=Found
* Trashes scratch
process_exist
movi ACTIVE,a1
#lp move *a1,a1,L
jrz #x ;End?
cmp a0,a1
jrne #lp ;!Match?
move a0,a0 ;Clr Z
#x rets
#*******************************
* Find if at least one process, other than calling process, exists
* A0=PROCID
* A1=Mask
* Rets: A0=*Process or 0 (Z)
EXISTP
PUSH a1,a2,a4
sext a0
and a1,a0 ;form match
movi ACTIVE,a2
#lp move *a2,a2,L
jrz #x ;End?
move *a2(PROCID),a4
and a1,a4
cmp a0,a4
jrne #lp ;!Match?
cmp a2,a13
jreq #lp ;Self?
#x move a2,a0
PULL a1,a2,a4
rets
******************************************************************************
.end