trog/TROGPROC.ASM

634 lines
16 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.

.MLIB "TROGMACS.LIB"
.FILE 'TROGPROC.ASM'
.TITLE "<<< T R O G -- MULTI-TASKING SYSTEM VER. 2.0 >>>"
**************************************************************************
* *
* COPYRIGHT (C) 1990 MIDWAY MANUFACTURING COMPANY, *
* MANUFACTURERS OF BALLY/MIDWAY AMUSEMENT GAMES. *
* ALL RIGHTS RESERVED. *
* *
**************************************************************************
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
*
*GSP MULTI-TASKING SYSTEM
*VERSION 1.0 BY EUGENE P. JARVIS
*VERSION 2.0 BY GEORGE N. PETRO
*
*FILES REQUIRED FOR ASSEMBLY
*
.INCLUDE GSPINC.ASM ;GSP Assembler Equates
.INCLUDE SYSINC.ASM ;Zunit System Equates
.INCLUDE MPROCEQU.ASM ;MPROC Equates
.INCLUDE DISPEQU.ASM
.GLOBAL DUMPPRINT
.REF TIMEINT
*
* 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 TIMEINT ; UPDATE TIMER THINGS
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
.if DEBUG ;this is for DEBUG only
MOVE A13,A0
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 *A13,A13,L
JREQ PRCDX ;NULL LIST, EXIT
MOVE @PAUSE_GAME,A0,W ;IS THE GAME IN PAUSE MODE?
JRZ PRCD1A ;BR = NO, CONTINUE AS NORMAL
MOVE *A13(PROCID),A0,W ;ANY DESTRUCTIBLE PROCESSES WILL
ZEXT A0 ;BE PAUSED BY THIS FLAG
SRL 13,A0 ;IN THE TOP THREE?
JRZ PRCD1 ;BR = NO, THEN YOU ARE PAUSE SUCKA
PRCD1A:
MOVE *A13(PTIME),A0 ;GET COUNT
DEC A0 ;DECREMENT COUNT
MOVE A0,*A13(PTIME) ;PUT IT BACK
JRGT PRCD1 ;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
JRNE SUCLP1
.if DEBUG ;this is for DEBUG only
LOCKUP
.endif
SUCLP1:
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
LOCKUP
* CALLERR 2 ;LOG THE ERROR
JRUC KILLX
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)
CLR A2
MOVE A2,*A0(PCOMM),W ;CLEAR THE COMMUNICATION LINE ON INIT
MOVE A0,A0 ;SET FLAGS
GETPX:
MMFM SP,A2
RETS
**************************************************************************
* *
* XFERPROC_ID - TRANSFER CONTROL OF AN EXISTING PROCESS KEEPING THE *
* SAME PROCID. *
* A0 = PTR TO PROCESS TO BE XFER'D *
* A7 = NEW WAKE UP *
* A8 - A11 = PASSED TO THE PROCESS *
* *
**************************************************************************
XFERPROC_ID:
PUSH A1
MOVE *A0(PROCID),A1,W
CALLR XFERPROC
PULL A1
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 A12
MOVE A0,A0 ;CHECK FOR VALID PTR JUST IN CASE
JRNE XFEROK
LOCKUP
JRUC XFERPROC_X
XFEROK:
MOVE A1,*A0(PROCID),W
MOVK 1,A12
MOVE A12,*A0(PTIME),W ;WAKE UP AS SOON AS POSSIBLE
MOVE A0,A12
ADDI PRCSIZ,A12 ;RESET PROCESS STACK POINTER
MMTM A12,A7,A8,A9,A10,A11 ;STUFF THE SHIT
MOVE A12,*A0(PSPTR),L
XFERPROC_X:
PULL A12
RETS
**************************************************************************
* *
* OBJPROC_KILL - KILL PROCESS CONTROLLING AN OBJECT. *
* A8 = PTR TO OBJECT *
* NOTE: IF NO PROCESS IS ASSOCIATED, NOTHING IS DONE. *
* YOU MUST USE SUCIDE IF YOU ARE THE CONTROLLING PROCESS. *
* *
**************************************************************************
OBJPROC_KILL:
PUSH A0
MOVE *A8(OPLINK),A0,L
JRZ OBJPROC_NOK
CALLR KILL
CLR A0
MOVE A0,*A8(OPLINK),L ;MARK IT GONE
OBJPROC_NOK:
PULL A0
RETS
**************************************************************************
* *
* OBJPROC_XFER - TRANSFER OBJECT CONTROL PROCESS TO NEW PROCESS *
* A1 = NEW PROC I.D. *
* A7 = NEW PROC ADDRESS *
* A8 = PTR TO OBJECT *
* *
**************************************************************************
OBJPROC_XFER:
MMTM SP,A0,A9,A10,A11
MOVE *A8(OPLINK),A0,L
JRZ OBJPROC_XFERX ;BR = NO CONTROL
CALLR GETA9
CALLR GETA10
CALLR GETA11
CALLR XFERPROC
OBJPROC_XFERX:
MMFM SP,A0,A9,A10,A11
RETS
**************************************************************************
* *
* KILLPROC_ALL - KILL ALL OF THE PROCESSES WITH GIVEN I.D. *
* EXCEPT CALLING PROCESS. *
* A0 = PROCESS I.D. TO KILL *
* *
**************************************************************************
KILLPROC_ALL
PUSH A1
CLR A1
NOT A1
CALLR KILLPROC_CLASS
PULL A1
RETS
**************************************************************************
* *
* KILALL - KILL A CLASS OF PROCESSES *
* A0 = PROCID (16 BITS) *
* A1 = MASK (16 BITS) *
* A8 = REGISTER TO MATCH *
* RETURNS: *
* NOTHING *
* *
* NOTES: *
* - MASK BITS OF ZERO ARE DONT CARES *
* - WILL NOT KILL CALLING PROCESS (A13) *
* *
**************************************************************************
KILLPROC_CLASS
KILALL:
MMTM SP,A0,A1,A2,A3,A4,A5
ZEXT A1 ;MAKE SURE WE MASK OFF THE HIGH WORD
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,W
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
**************************************************************************
* *
* KILALLA8 - KILL A CLASS OF PROCESSES WITH GIVEN I.D. AND MATCHING A8'S *
* A0 = PROCID (16 BITS) *
* A1 = MASK (16 BITS) *
* A8 = REGISTER TO MATCH *
* RETURNS: *
* NOTHING *
* *
* NOTES: *
* - MASK BITS OF ZERO ARE DONT CARES *
* - WILL NOT KILL CALLING PROCESS (A13) *
* *
**************************************************************************
KILALLA8:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8
ZEXT A1 ;MAKE SURE WE MASK OFF THE HIGH WORD
MOVE A0,A7
AND A1,A7 ;FORM MATCH
MOVI ACTIVE,A0,L
MOVE A8,A6 ;KEEP CURRENT A8 HERE
KILALA8_LP:
MOVE A0,A3 ;SAVE PREVIOUS
MOVE *A0,A0,L ;GET NEXT
JREQ KILALA8_X ;ALL DONE
MOVE *A0(PROCID),A4,W
AND A1,A4 ;CAN DONT CARE BITS
CMP A7,A4 ;MATCH?
JRNE KILALA8_LP ;BR = NO
CMP A0,A13 ;CURRENT PROCESS?
JREQ KILALA8_LP ;BR = YES DONT KILL
CALLR GETA8
CMP A6,A8 ;MATCHING A8'S?
JRNE KILALA8_LP ;BR = YES
MOVE *A0,*A3,L ;LINK AROUND IN ACTIVE LIST
MOVE @FREE,A5,L ;LINK INTO FREE LIST AT START
MOVE A5,*A0,L
MOVE A0,@FREE,L ;POINT FREE TO CELL
MOVE A3,A0
JRUC KILALA8_LP ;KILL THE REST
KILALA8_X:
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8
RETS
**************************************************************************
* *
* EXISTP - LOOK FOR AN ACTIVE PROCESS OF GIVEN I.D. OTHER THAN THE *
* CALLING PROCESS. *
* A0=PROCID (16 BITS) *
* A1=MASK (16 BITS) *
* MASK BITS OF ZERO ARE DONT CARES *
* RETURNS: *
* Z = NOT FOUND (A0 = 0) *
* NZ = FOUND (A0 = PTR TO PROCESS) *
* *
**************************************************************************
EXISTP:
MMTM SP,A1,A2,A4
ZEXT A1
AND A1,A0 ;FORM MATCH
MOVI ACTIVE,A2,L
EXNXT:
MOVE *A2,A2,L ;GET NEXT
JREQ EXSC ;ALL DONE
MOVE *A2(PROCID),A4,W
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
**************************************************************************
* *
* COUNT_PROCESSES - COUNT THE NUMBER OF PROCESSES OF A GIVEN I.D. *
* CURRENTLY ACTIVE. *
* INCLUDES CALLING PROCESS IN COUNT, IF IT MATCHES. *
* A1 = PROCESS I.D. TO COUNT *
* RETURNS: *
* A0 = COUNT *
* Z BIT REFLECTS VALUE IN A0 *
* *
**************************************************************************
COUNT_PROCESSES
MMTM SP,A2,A4
CLR A0 ;CLEAR COUNT
MOVE @ACTIVE,A2,L ;GRAB THE PROCESS LIST
JRZ CP_X ;BR = EMPTY
CP_LOOP
MOVE *A2(PROCID),A4,W
CMP A1,A4 ;SHALL WE COUNT THIS ONE?
JRNE CP_NEXT ;BR = NO
INC A0 ;TALLY ANOTHER
CP_NEXT
MOVE *A2,A2,L ;GET NEXT
JRNE CP_LOOP ;BR = DEFINITELY MORE TO DO
MOVE A0,A0
CP_X
MMFM SP,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
**************************************************************************
* *
* SEND_COMM - SEND COMMUNICATION TO THIS PROCESS (VIA PCOMM). *
* A1 = SEND WORD *
* A11 = PTR TO RECEIVING PROCESS (IF = 0 THEN NO ACTION) *
* A13 = PTR TO SENDING PROCESS *
* *
**************************************************************************
SEND_COMM:
MOVE A11,A11
JRZ SEND_COMM_X
MOVE A1,*A11(PCOMM),W
SEND_COMM_X:
RETS
**************************************************************************
* *
* COMM_WAIT - WAIT FOR A COMMUNICATION FROM A PROCESS (VIA PCOMM). *
* A2 = WORD TO WAIT FOR *
* A3 = TIME OUT (IN TICKS) *
* A13 = PTR TO PROCESS WAITING FOR DATA *
* RETURNS: *
* Z = COMMUNICATION RECIEVED *
* NZ = TIME OUT *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
COMM_WAIT:
MMTM A12,A8,A9
MOVE A2,A8
MOVE A3,A9
COMM_WAIT_LP:
SLEEP 1
MOVE *A13(PCOMM),A2,W
CMP A2,A8
JREQ COMM_WAIT_X
DSJS A9,COMM_WAIT_LP
CLRZ
COMM_WAIT_X:
MMFM A12,A8,A9
RETP
**************************************************************************
* *
* COMM_WAIT_REMOTE - WAIT FOR A COMMUNICATION FROM A REMOTE PROCESS *
* (VIA PCOMM). *
* A2 = WORD TO WAIT FOR *
* A3 = TIME OUT (IN TICKS) *
* A11 = PTR TO REMOTE PROCESS *
* RETURNS: *
* Z = COMMUNICATION RECIEVED *
* NZ = TIME OUT *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
COMM_WAIT_REMOTE:
MMTM A12,A8,A9
MOVE A2,A8
MOVE A3,A9
CWR_LP:
SLEEP 1
MOVE *A11(PCOMM),A2,W
CMP A2,A8
JREQ CWR_X
DSJS A9,CWR_LP
CLRZ
CWR_X:
MMFM A12,A8,A9
RETP
**************************************************************************
* *
* SEND_COMM_WAIT - SEND COMMUNICATION AND WAIT FOR A REPLY. *
* A1 = DATA TO SEND *
* A2 = DATA TO WAIT FOR *
* A3 = TIME OUT ON WAIT *
* A11 = PTR TO RECEIVING PROCESS *
* A13 = PTR TO SENDING PROCESS *
* RETURNS *
* Z = DATA SENT, REPLY RECEIVED *
* NZ = TIME OUT ERROR *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
SEND_COMM_WAIT:
CALLR SEND_COMM
JSRP COMM_WAIT
RETP
.END