cruisin-usa/MPROC.ASM

630 lines
11 KiB
NASM
Executable File

.FILE "MPROC.ASM"
*----------------------------------------------------------------------------
*MULTIPROCESS SYSTEM
*
*COPYRIGHT (C) 1994 BY TV GAMES, INC.
*ALL RIGHTS RESERVED
*
*
.include MPROC.EQU
.include MACS.EQU
.include C30.EQU
.include VUNIT.EQU
.include ERROR.EQU
.if DEBUG
.bss NUM_PROCS_ACTIVE,1
.bss NUM_PROCS_IDLE,1
.endif
.bss CURRENT_PROC,1 ;CURRENT PROCESS POINTER (DEBUG ONLY!)
.bss OLDSP,1 ;SAVE OLD STACK POINTER
.globl PRINTER_LOG,PRINTER_LOG_SYMBOLIC
.bss PACTIVE,1 ;ACTIVE PROCESS LIST POINTER
.bss PFREE,1 ;FREE PROCESS LIST POINTER
hibss PRCSTR,PRCSIZ*NUMPROC ;PROCESS STORE AREA
.text
PACTIVEI .word PACTIVE
PFREEI .word PFREE
PRCSTRI .word PRCSTR
*----------------------------------------------------------------------------
PRC_DEBUG_CHECK:
.if DEBUG
PUSH R0
LDI @NUM_PROCS_ACTIVE,R0
ADDI @NUM_PROCS_IDLE,R0
CMPI NUMPROC,R0
BNE $
POP R0
.endif
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*GET A PROCESS
*
* START UP A PROCESS AT FUNCTION_NAME.
* -FIND AN AVAILABLE PROCESS SPACE
* -SETUP STORED VARIABLES (AR7-3,R4-7) AND START ADDRESS
* -SETUP LSP POSITION (LOCAL STACK POINTER)
* -SET SLEEP TIKS TO ZERO
*
*PARAMETERS
* R2 PID
* AR2 START ADDRESS
*RETURNS
* (IF PROCESS IS AVAILABLE)
* CARRY CLEAR
* AR0 POINTER TO PROCESS BLOCK
* (IF NO PROCESSES AVAILABLE)
* CARRY SET
*
PRC_CREATE:
PUSH R0
LDI @PFREE,R0 ;TAKE OFF THE TOP OF PROCESS FREE LIST
BNZ GETPROC0
ERRON U,EC_PROC|ET_ALLOC ;OUT OF PROCESSES ERROR
SETC
B GETPROCX
GETPROC0
LDI R0,AR0
LDI *AR0,R0
STI R0,@PFREE ;AND UPDATE FREE LIST
LDI @PACTIVE,R0 ;INSERT TO HEAD OF PROCESS ACTIVE LIST
STI R0,*AR0
STI AR0,@PACTIVE
LDI 0,R0
STI R0,*+AR0(PTIME) ;PLACE SLEEP TIME
STI AR2,*+AR0(PWAKE) ;START ADDRESS OF PROCESS
; STI AR2,*+AR0(PSADDR) ;START ADDRESS OF PROCESS (SAVE FOR DEBUG & ID)
STI R2,*+AR0(PID) ;SET PROCESS TYPE
LDI AR0,R0
ADDI PSDATA,R0 ;WHERE LOCAL STACK POINTER ACTUALLY IS
STI R0,*+AR0(PSPTR) ;STORE LOCAL STACK POINTER (LSP)
STI AR4,*+AR0(PAR4)
STI AR5,*+AR0(PAR5)
STI AR6,*+AR0(PAR6)
STI R4,*+AR0(PR4)
STI R5,*+AR0(PR5)
STF R6,*+AR0(PR6)
STF R7,*+AR0(PR7)
.if DEBUG
LDI @NUM_PROCS_ACTIVE,R0
INC R0
STI R0,@NUM_PROCS_ACTIVE
LDI @NUM_PROCS_IDLE,R0
DEC R0
STI R0,@NUM_PROCS_IDLE
.endif
CLRC
GETPROCX
POP R0
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*GET A CHILD PROCESS
*LINKED AFTER AR7 (CALLING PROC) ON LIST
*RETURNS
* AR0 POINTER TO PROCESS
*
PRC_CREATE_CHILD:
CALL PRC_CREATE
RETSC
PUSH R0
LDI *AR0,R0 ;PULL HIM FROM FRONT OF LIST
STI R0,@PACTIVE
LDI *AR7,R0 ;PUT HIM AFTER CREATING PROCESS
STI R0,*AR0
STI AR0,*AR7
POP R0
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*DISPPROC
*
* Dispatch current process list.
*
*
*REGISTER ALLOCATION (WITHIN PROCESSES) AS FOLLOWS:
*
*ALL REGISTERS TRASHED EXCEPT THE FOLLOWING:
*
*AR4 SAVED (OBJECT POINTER)
*AR5 SAVED (CAR BLOCK POINTER W/DRONES/PLAYER)
*AR6 SAVED
*AR7 PROCESS POINTER
*
*R4 SAVED AS INT
*R5 SAVED AS INT
*R6 SAVED AS FLOAT
*R7 SAVED AS FLOAT
*
*
PRC_DISPATCH:
DISPPROC
LDI @PACTIVEI,AR7
B NEXTPRC
*
*SLEEP
* SEND CURRENT PROCESS TO SLEEP.
* SAVE RETURN ADDRESS
* GO GET NEXT PROCESS
*PASSED
* AR2 SLEEP TIME x 16MSEC.
*
PRC_SLEEP:
SLEEP
POP R0
STI R0,*+AR7(PWAKE) ;SAVE WAKEUP ADDRESS
.if DEBUG
CALL PRC_DEBUG_CHECK
.endif
.if DEBUG
CMPI 0,DP
BNE $
CMPI @OLDSP,SP ;PROC IN AR7
SLOCKON NE,"_sleep OLDSP != SP *FATAL*"
LDI @CURRENT_PROC,R0
CMPI R0,AR7 ;AR7 HAS BEEN TRASHED!
SLOCKON NE,"_sleep CURRENT_PROC != AR7 *FATAL*"
; LDP @TIMER_CNTR1
; LDI @TIMER_CNTR1,R0
; STI R0,*+AR7(PDBGTIM)
; SETDP
.endif
SETDP
LDI @OLDSP,SP ;PROC IN AR7
LDI @CURRENT_PROC,AR7
STI R4,*+AR7(PR4)
STI R5,*+AR7(PR5)
STF R6,*+AR7(PR6)
STF R7,*+AR7(PR7)
STI AR2,*+AR7(PTIME) ;SAVE SLEEP TIME
STI AR4,*+AR7(PAR4)
STI AR5,*+AR7(PAR5)
STI AR6,*+AR7(PAR6)
NEXTPRC LDI *AR7,R0 ;GET NEXT PROC, SET Z FLAG
NP1 BZD DISPPRCX
LDI R0,AR7 ;PUT IT IN AR7
LDI *+AR7(PTIME),R0 ;IS SLEEP TIME ZERO?
SUBI 1,R0
;---->BZ DISPPRCX
BGTD NP1
STI R0,*+AR7(PTIME)
LDI *AR7,R0 ;GET NEXT PROC
NOP ;FOR DELAYED BRANCH
;---->BGT NP1
EXEC
STI SP,@OLDSP
STI AR7,@CURRENT_PROC ;SAVE CURRENT PROCESS POINTER
LDI *+AR7(PAR6),AR6
LDI *+AR7(PAR5),AR5
LDI *+AR7(PAR4),AR4
LDF *+AR7(PR7),R7
LDI *+AR7(PWAKE),R0
BUD R0
LDF *+AR7(PR6),R6
LDI *+AR7(PR5),R5
LDI *+AR7(PR4),R4
;---->BU R0 DELAYED BRANCH HERE
DISPPRCX
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*SUICIDE
*
*REMOVE CURRENT PROCESS FROM ACTIVE LIST
*
*PROCESSES MUST BRANCH TO SUICIDE
*
PRC_SUICIDE:
SUICIDE
.if DEBUG
PUSH R0
LDI @NUM_PROCS_ACTIVE,R0
DEC R0
STI R0,@NUM_PROCS_ACTIVE
LDI @NUM_PROCS_IDLE,R0
INC R0
STI R0,@NUM_PROCS_IDLE
POP R0
CALL PRC_DEBUG_CHECK
.endif
.if DEBUG
CMPI 0,DP
BNE $
CMPI @OLDSP,SP
SLOCKON NE,"SUICIDE OLD != SP *FATAL*"
BNE $ ;PROC IN AR7
LDI @CURRENT_PROC,R0
CMPI R0,AR7
SLOCKON NE,"SUICIDE CURRENT_PROC != AR7 *FATAL*"
.endif
LDI *AR7,R0 ;LINK TO NEXT PROC
LDI @PFREE,AR1 ;LINK TO START OF FREE
STI AR1,*AR7
STI AR7,@PFREE
LDI @PACTIVEI,R1 ;WE MUST FIND DEAD PROCESS TO LINK AROUND
DIELP LDI R1,AR1
LDI *AR1,R1
ERRON Z,EC_PROC|ET_DELETE ;SUICIDE PROCESS NOT FOUND??? *FATAL*"
BZ NEXTPRC
CMPI R1,AR7
BNE DIELP
BUD NEXTPRC
STI R0,*AR1 ;LINK AROUND DEAD PROCESS
LDI AR1,AR7 ;SO SOMETHING IS POINTING TO NEXT PROC
NOP
;--->BR NEXTPRC
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*KILL A PROCESS
*
*FIND AND REMOVE PROCESS FROM ACTIVE LIST
*
*PARAMETERS
* AR2 POINTER TO PROCESS TO KILL
*
PRC_KILL:
PUSH R1
PUSH AR1
CMPI AR2,AR7
ERRON Z,EC_PROC|ET_DELETE|3 ;KILL ATTEMPTED ON SELF"
BEQ SUICIDE
LDI @PACTIVEI,R1 ;WE MUST FIND DEAD PROCESS TO LINK AROUND
KILLP
LDI R1,AR1
LDI *AR1,R1
ERRON Z,EC_PROC|ET_DELETE|4 ;LOCKUP ON END OF LIST FOUND"
BZ KILL_X
CMPI R1,AR2
BNE KILLP
LDI *AR2,R1
STI R1,*AR1 ;LINK AROUND
LDI @PFREEI,AR1
LDI *AR1,R1
STI R1,*AR2
STI AR2,*AR1
KILL_X
.if DEBUG
PUSH R0
LDI @NUM_PROCS_ACTIVE,R0
DEC R0
STI R0,@NUM_PROCS_ACTIVE
LDI @NUM_PROCS_IDLE,R0
INC R0
STI R0,@NUM_PROCS_IDLE
POP R0
.endif
POP AR1
POP R1
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*KILLALL
*KILL CLASS OF PROCESSES
*
*PARAMETERS
* R0 PID
* R1 MASK
*
PRC_KILLALL:
PUSH AR1
PUSH AR2
AND R1,R0
LDI @PACTIVEI,AR2 ;WE MUST FIND DEAD PROCESS TO LINK AROUND
KILLALLP
LDI AR2,AR1
KLP0
LDI *AR1,R2
BZ KADONE ;WE'RE DONE
LDI R2,AR2
LDI *+AR2(PID),R2
AND R1,R2
CMPI R2,R0
BNZ KILLALLP
CMPI AR7,AR2
BZ KILLALLP ;DONT KILL YOURSELF
LDI *AR2,R2
STI R2,*AR1 ;LINK AROUND
LDI @PFREE,R2
STI R2,*AR2
STI AR2,@PFREE
.if DEBUG
PUSH R0
LDI @NUM_PROCS_ACTIVE,R0
DEC R0
STI R0,@NUM_PROCS_ACTIVE
LDI @NUM_PROCS_IDLE,R0
INC R0
STI R0,@NUM_PROCS_IDLE
POP R0
.endif
BR KLP0
KADONE
.if DEBUG
CALL PRC_DEBUG_CHECK
.endif
POP AR2
POP AR1
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*PRC_EXISTP DOES A PROCESS EXIST
*
*PARAMETERS
* AR2 PID
* R2 MASK
*RETURNS
* (IF FOUND)
* C=1 IF FOUND
* R0 POINTING TO PROCESS
* (IF NOT FOUND)
* C=0
* R0=0 IF PROCESS NOT FOUND
*
PRC_EXISTP:
CLRC ;CLEAR CARRY
PUSH AR2
LDI AR2,RC
AND R2,RC
LDI @PACTIVEI,AR2
EXPL
LDI *AR2,R0
BZ EXDONE ;WE'RE DONE, ITS NOT HERE
LDI R0,AR2
LDI *+AR2(PID),RS
AND R2,RS
CMPI RC,RS
BNZ EXPL
SETC ;WE FOUND IT DUDES!!!
EXDONE
POP AR2
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*INITIALIZE PROCESS DATA STRUCTURES
*
PRC_INIT:
PUSH R0
PUSH AR0
PUSH AR1
LDI @PACTIVEI,AR0 ;ZERO ACTIVE POINTER
LDI 0,R0
STI R0,*AR0
LDI @PFREEI,AR0 ;GET FREE POINTER
LDI @PRCSTRI,AR1
LDI NUMPROC-1,RC
RPTB PINITL
STI AR1,*AR0
LDI AR1,AR0
PINITL ADDI PRCSIZ,AR1
LDI 0,R0
STI R0,*AR0
.if DEBUG
STI R0,@NUM_PROCS_ACTIVE
LDI NUMPROC,R0
STI R0,@NUM_PROCS_IDLE
.endif
POP AR1
POP AR0
POP R0
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*XFERPROC
*
*TRANSFER A PROCESS TO A DIFFERENT WAKEUP ADDRESS. WAKEUP WILL BE NEXT
*POSSIBLE
*
*PARAMETERS
* AR0 POINTER TO PROCESS
* AR1 POINTER TO ADDRESS TO WAKE UP
*
PRC_XFER:
PUSH AR1
.if DEBUG
CMPI AR0,AR7 ;ARE WE ATTEMPTING TO XFER OURSELVES?
SLOCKON Z,"XFERPROC ATTEMPT TO XFER OURSELF"
.endif
STI AR1,*+AR0(PWAKE) ;SAVE WAKEUP ADDRESS
LDI 1,R0
STI R0,*+AR0(PTIME) ;WAKEUP ASAP
;someday it might be nessesary to re-initialize the
;processes stack. for now this is ignored.
POP AR1
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*PRC_FIND
* FIND PROCESS FROM ACTIVE LIST
*
*PARAMETERS
* R0 PID
* R1 PID MASK
*RETURNS
* AR0 POINTER TO PROCESS IF FOUND OR ZERO IF NONE FOUND
*
*
*PRC_FINDNEXT
*
*
*PARAMETERS
* AR0 POINTER TO LIST
*
PRC_FINDNEXT:
BUD FINDE
PUSH R2
AND R1,R0
NOP
;----> BUD FINDE
PRC_FIND:
BUD FINDE
PUSH R2
AND R1,R0
LDI @PACTIVEI,AR0 ;WE MUST FIND DEAD PROCESS TO LINK AROUND
;----> BUD FINDE
FINDLP
CMPI R2,R0
BEQ FINDPROCX
FINDE LDI *AR0,R2 ;SET CONDITION CODE
BNZD FINDLP
LDI R2,AR0
LDI *+AR0(PID),R2
AND R1,R2
;----> BNZD FINDLP
FINDPROCX
POP R2
RETS
*----------------------------------------------------------------------------
*----------------------------------------------------------------------------
*SET THIS PROCESS TO FOLLOW SPECIFIED PROCESS
* (ASSERT ME AS A CHILD OF THE SPECIFIED PROCESS)
*
*PARAMETERS
* AR2 PROCESS TO FOLLOW
* AR7 !THIS PROCESS!
*
*
PRC_FOLLOW:
PUSH R1
PUSH AR1
PUSH AR2
PUSH AR7
LDI @PACTIVEI,R1 ;WE MUST FIND DEAD PROCESS TO LINK AROUND
PFOLLP
LDI R1,AR1
LDI *AR1,R1
ERRON Z,EC_PROC|6 ;LOCKUP ON END OF LIST FOUND
BZ PROC_FOLLOW_X
CMPI R1,AR7
BNE PFOLLP
LDI *AR7,R1
STI R1,*AR1 ;LINK AROUND
LDI *AR2,R1
STI R1,*AR7
STI AR7,*AR2
PROC_FOLLOW_X
POP AR7
POP AR2
POP AR1
POP R1
RETS
*----------------------------------------------------------------------------
.END