wwf-wrestlemania/MPROC.ASM

682 lines
12 KiB
NASM
Raw Normal View History

2021-04-06 15:21:54 -07:00
**************************************************************
* 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