narc/SYS/MPROC.ASM

362 lines
8.3 KiB
NASM
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.

.FILE 'MPROC.ASM'
.TITLE "GSP MULTI-PROCESSING SYSTEM VERSION 1.0 EUGENE P. JARVIS"
**************************************************************************
* *
* COPYRIGHT (C) 1988 WILLIAMS ELECTRONICS GAMES, INC. *
* ALL RIGHTS RESERVED. *
* *
**************************************************************************
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
*
*FILES REQUIRED FOR ASSEMBLY
*
.INCLUDE \video\GSP.INC ;GSP Assembler Equates
.INCLUDE \video\SYS.INC ;Zunit System Equates
.INCLUDE \video\MPROCEQU.ASM ;MPROC Equates
.INCLUDE \video\DISPEQU.ASM
*
* SET UP FIXED PARAMETERS AT THE BEGINNING OF SCRATCHPAD
*
.SECT "FIXED"
ACTIVE .LONG 0
FREE .LONG 0
*
*GLOBAL PROCESS VARIABLES
*
.BSS TIMER,16 ;IRQ TIMER 16 MSEC.
.BSS TIMETEMP,16 ;LAST TIMER VALUE
.BSS OVERLOAD,16 ;OVERLOAD CHECKER
.BSS PRCSTR,NPROC*PRCSIZ ;PROCESS STORE ALLOCATION
*
*MULTI-PROCESSING PROGRAM
*
.TEXT ;STORE IN PROGRAM ROM
*
*PROCESS DISPATCH
*
PRCDSP:
MOVI ACTIVE,A13,L ;LONG WORD INIT SCAN PROCESS LIST
PRCWTSRT
CALLA YZSORT ;SORT DISPLAY LIST
MOVE @TIMER,A0
JREQ PRCWTSRT ;BR = WAIT FOR TIMING FROM INTERRUPT, SORT
MOVE A0,@TIMETEMP,W ;SAVE
SLL 1,A0
MOVE @OVERLOAD,A1,W
ADD A0,A1
SRL 1,A1
MOVE A1,@OVERLOAD,W
CALLA L_TIMER
CLR A0
MOVE A0,@TIMER
JRUC PRCD1
*
*PROCESS SLEEP
*TOS IS WAKEUP ADDR ,A0 = SLEEP TIME
*
PRCSLP:
MMFM SP,A7 ;CALLING PC->A7
PRCLSP:
MMTM A12,A7,A8,A9,A10,A11 ;SAVE REGS
MOVE A0,*A13(PTIME) ;SAVE SLEEP TIME
MOVE A12,*A13(PSPTR),L ;SAVE STACK POINTER
MOVE A13,A0
.if DEBUG ;this is for DEBUG only
ADDI PSDATA,A0
CMP A0,A12
JRLT $ ;Stick on Stack overflow
ADDI PRCSIZ-PSDATA,A0
CMP A0,A12
JRGT $ ;Stick on Stack underflow
.endif
PRCD1:
MOVE @TIMETEMP,A1,W ;GET THE LAST TIMER VALUE
PRCD1A
MOVE *A13,A13,L
JREQ PRCDX ;NULL LIST, EXIT
MOVE *A13(PTIME),A0 ;GET COUNT
SUB A1,A0
**************************************************************************
* *
* DEC A0 ;DECREMENT COUNT *
* *
**************************************************************************
MOVE A0,*A13(PTIME) ;PUT IT BACK
JRGT PRCD1A ;NOT READY, LOOP FOR NEXT
*PROCESS IS READY FOR DISPATCH
PRCD2:
MOVE *A13(PSPTR),A12,L ;SET UP STACK POINTER
MMFM A12,A7,A8,A9,A10,A11 ;GET SAVED REGS
JUMP A7 ;GO DO IT
*DONE WITH THE SCAN
PRCDX: RETS
*
*PROCESS SUICIDE
*
SUCIDE:
MOVI ACTIVE,A1,L
SUCLP:
MOVE A1,A2 ;SAVE PREVIOUS
MOVE *A1,A1,L
SUCERR:
JREQ SUCERR ;PROCESS DOES NOT EXIST, ERROR
CMP A1,A13 ;CHECK FOR MATCH TO CURRENT PROCESS
JRNE SUCLP ;NOT FOUND KEEP LOOKING
MOVE *A1,*A2,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A0,L ;GET FREE POINTER
MOVE A0,*A1,L ;LINK INTO FREE LIST AT START
MOVE A1,@FREE,L
MOVE A2,A13 ;SET CURRENT PROCESS TO PREVIOUS
JRUC PRCD1 ;CONTINUE WITH DISPATCH
*
*PROCESS LIST INITIALIZE
*A13 RETURNED POINTING TO ACTIVE LIST (CRPROC)
PINIT:
MMTM SP,A0,A1,A2,A3 ;SAVE REG
MOVI NPROC,A3,W ;# OF PROCESSES TO INIT
CLR A0
MOVE A0,@ACTIVE,L ;NULL ACTIVE LIST
MOVI PRCSTR,A1,L
MOVE A1,@FREE,L ;SETUP FREE LIST
PINITL:
MOVE A1,A2
ADDI PRCSIZ,A1,W
MOVE A1,*A2,L ;LINK EM UP
DSJS A3,PINITL ;CONTINUE FOR NPROC
MOVE A0,*A2,L ;ZERO LAST LINK
MOVI ACTIVE,A13,L ;INIT CURRENT PROCESS
MMFM SP,A0,A1,A2,A3 ;RESTORE REGS
RETS
*
*KILL PROCESS
*A0 POINTS TO PROCESS TO KILL
*IF PROCESS NOT PRESENT, CAUSES ERROR
*TO KILL YOURSELF SUCIDE MUST BE USED,
*IF YOU ATTEMPT TO KILL YOURSELF IT WILL JUST RETURN
*
KILL:
CMP A0,A13 ;KILLING YOURSELF?
JREQ KILLXXX ;BR = YES, JUST ESCAPE
MMTM SP,A1,A2
MOVI ACTIVE,A1,L
KILLP:
MOVE A1,A2 ;SAVE PREVIOUS
MOVE *A1,A1,L
JRNZ KILLCHK
CALLERR 2 ;LOG THE ERROR
JRUC KILLX
**** .if DEBUG ;this is for DEBUG only
**** JREQ $ ;PROCESS DOES NOT EXIST, ERROR
**** .endif
KILLCHK
CMP A1,A0
JRNE KILLP ;NOT FOUND KEEP LOOKING
MOVE *A0,*A2,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A1,L ;LINK INTO FREE LIST AT START
MOVE A1,*A0,L
MOVE A0,@FREE,L
KILLX
MMFM SP,A1,A2
KILLXXX
RETS
*
*CREATE A PROCESS
*A1=ID,A7=PC,A8,A9,A10,A11 PASSED PARAMETERS
*A13=CURRENT PROCESS
*A0 IS RETURNED POINTING TO CREATED PROCESS
*
GETPRC:
MMTM SP,A2
MOVE @FREE,A0,L
JREQ GETPX ;NONE AVAILABLE
MOVE *A0,A2,L
MOVE A2,@FREE,L ;REMOVE FROM FREE LIST
MOVE *A13,*A0,L ;LINK INTO ACTIVE LIST AFTER CURRENT PROCESS
MOVE A0,*A13,L ;CRPROC>>NEW PROC
MOVE A1,*A0(PROCID)
MOVE A0,A2
ADDI PRCSIZ,A2 ;FORM PROCESS STACK POINTER
MMTM A2,A7,A8,A9,A10,A11
MOVE A2,*A0(PSPTR),L ;PUT IN STACK POINTER
MOVK 1,A2 ;INIT SLEEP TIME
MOVE A2,*A0(PTIME)
GETPX:
MMFM SP,A2
RETS
**************************************************************************
* *
* XFERPROC - TRANSFER CONTROL OF AN EXISTING PROCESS *
* A0 = PTR OF PROCESS TO BE XFER'D *
* A1 = NEW I.D. *
* A7 = WAKE UP *
* A8 - A11 = PASSED TO THE XFER'D PROC *
* *
**************************************************************************
XFERPROC
PUSH A14
MOVE A1,*A0(PROCID),W
MOVK 1,A14
MOVE A14,*A0(PTIME),W ;WAKE UP AS SOON AS POSSIBLE
MOVE A0,A14
ADDI PRCSIZ,A14 ;RESET PROCESS STACK POINTER
MMTM A14,A7,A8,A9,A10,A11 ;STUFF THE SHIT
MOVE A14,*A0(PSPTR),L
PULL A14
RETS
*
*KILL A CLASS OF PROCESSES
*A0=PROCID (16 BITS) ,A1=MASK (16 BITS)
*MASK BITS OF ZERO ARE DONT CARES
*WILL NOT KILL CALLING PROCESS (A13)
*
KILALL:
MMTM SP,A0,A1,A2,A3,A4,A5
AND A1,A0 ;FORM MATCH
MOVI ACTIVE,A2,L
KILALP:
MOVE A2,A3 ;SAVE PREVIOUS
MOVE *A2,A2,L ;GET NEXT
JREQ KILALX ;ALL DONE
MOVE *A2(PROCID),A4
AND A1,A4 ;CAN DONT CARE BITS
CMP A0,A4 ;MATCH?
JRNE KILALP ;NO
CMP A2,A13 ;CURRENT PROCESS?
JREQ KILALP ;YES DONT KILL
MOVE *A2,*A3,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A5,L ;LINK INTO FREE LIST AT START
MOVE A5,*A2,L
MOVE A2,@FREE,L ;POINT FREE TO CELL
MOVE A3,A2
JRUC KILALP ;KILL THE REST
KILALX:
MMFM SP,A0,A1,A2,A3,A4,A5
RETS
*
*FIND IF AT LEAST ONE PROCESS, OTHER THAN CALLING PROCESS,
*EXISTS.
*A0=PROCID (16 BITS) ,A1=MASK (16 BITS)
*MASK BITS OF ZERO ARE DONT CARES
*RETURNS:
* Z BIT SET = NO MATCH, A0 = 0
* Z BIT CLR = MATCH, A0 = PTR TO PROCESS
*
EXISTP:
MMTM SP,A1,A2,A4
AND A1,A0 ;FORM MATCH
MOVI ACTIVE,A2,L
EXNXT:
MOVE *A2,A2,L ;GET NEXT
JREQ EXSC ;ALL DONE
MOVE *A2(PROCID),A4
AND A1,A4 ;CAN DONT CARE BITS
CMP A0,A4 ;MATCH?
JRNE EXNXT ;NO
CMP A2,A13 ;CURRENT PROCESS?
JREQ EXNXT ;YES, THEN WE DON'T CARE
EXSC
MOVE A2,A0
MMFM SP,A1,A2,A4
RETS
*GET A PRESERVED REGISTER FROM A SLEEPING PROCESS
*A0 = PTR TO SLEEPER
GETA11 MOVE A1,-*SP,L
CLR A1
CALLR GETSLW
MOVE A1,A11
MMFM SP,A1
RETS
GETA10 MOVE A1,-*SP,L
MOVI 20H,A1
CALLR GETSLW
MOVE A1,A10
MMFM SP,A1
RETS
GETA9 MOVE A1,-*SP,L
MOVI 40H,A1
CALLR GETSLW
MOVE A1,A9
MMFM SP,A1
RETS
GETA8 MOVE A1,-*SP,L
MOVI 60H,A1
CALLR GETSLW
MOVE A1,A8
MMFM SP,A1
RETS
*GET A LONG WORD FROM THE STACK OF A SLEEPING PROCESS
*A0 = PTR TO SLEEPING PROC
*A1 = OFFSET OF WORD FROM STACK POINTER
*A2 = CURRENT STACK PTR
*RETURN(S)
*A1 = LONG WORD
GETSLW MOVE A2,-*SP,L
MOVE *A0(PSPTR),A2,L ;GET THE STACK POINTER
ADD A1,A2 ;ADD THE OFFSET
MOVE *A2,A1,L ;MOVE IN THE LONG WORD
MOVE *SP+,A2,L
RETS
*PUT A REGISTER(A8-A11) INTO A SLEEPING PROCESS
*A0 = PTR TO SLEEPER
PUTA11 MMTM SP,A1,A2
CLR A1
MOVE A11,A2
JRUC PUTSLW
PUTA10 MMTM SP,A1,A2
MOVI 20H,A1
MOVE A10,A2
JRUC PUTSLW
PUTA9 MMTM SP,A1,A2
MOVI 40H,A1
MOVE A9,A2
JRUC PUTSLW
PUTA8 MMTM SP,A1,A2
MOVI 60H,A1
MOVE A8,A2
*PUT A LONG WORD INTO THE STACK OF A SLEEPING PROCESS
*A0 = PTR TO SLEEPING PROC
*A1 = INDEX INTO STACK
*A2 = VALUE TO PUT
PUTSLW MMTM SP,A3
MOVE *A0(PSPTR),A3,L ;GET THE STACK POINTER
ADD A1,A3 ;ADD THE OFFSET
MOVE A2,*A3,L
MMFM SP,A1,A2,A3
RETS
.END