.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 * * * FILES REQUIRED FOR ASSEMBLY * .INCLUDE \VIDEO\SYS\GSP.INC ;GSP ASSEMBLER EQUATES .INCLUDE \VIDEO\SYS\SYS.INC ;ZUNIT SYSTEM EQUATES .INCLUDE \VIDEO\SYS\MACROS.HDR ;MACROS .INCLUDE MPROC.EQU ;MPROC EQUATES .INCLUDE DISP.EQU * * SET UP FIXED PARAMETERS AT THE BEGINNING OF SCRATCHPAD * .REF L_TIMER ;AUDIT .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 ;linky timer CLR A0 MOVE A0,@TIMER JRUC PRCD1 * *PROCESS SLEEP *TOS IS WAKEUP ADDR ,A0 = SLEEP TIME * PRCSLP: move *SP+,A7,L ;CALLING PC->A7 PRCLSP: move A13,A1 addi PDATA,A1 mmtm A1,A7,A8,A9,A10,A11,A12 ;wakeup, regs, stack ptr move A0,-*A1,W ;sleep .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 @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,A1 addi >40,A1 mmfm A1,A7,A8,A9,A10,A11,A12 ;wake, regs, stack ptr jump A7 ;fire off proc *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 EINT .ELSE CALLERR 5,0 .endif JRUC PRCDSP ;RESOLVE? 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 .IF DEBUG LOCKUP EINT .ELSE CALLERR 6,2 .ENDIF * 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,A12 MOVE @FREE,A0,L JREQ NONELFT ;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 JRUC XFERPRC0 * 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 mmtm SP,A2,A12 XFERPRC0 .IF DEBUG CMPI 0FFC00000H,A7 ;FFE .ELSE CMPI 0FFE00000H,A7 ;FFE .ENDIF JRHS OK .IF DEBUG LOCKUP EINT .ELSE CALLERR 7,2 .ENDIF JRUC GETPX OK MOVE A0,A2 ADDI PDATA,A2 move A0,A12 ;RESET PROCESS STACK POINTER addi PRCSIZ,A12 MMTM A2,A7,A8,A9,A10,A11,A12 ;STUFF wake, regs, p stack ptr movk 1,A12 move A12,-*A2,W ;WAKE UP AS SOON AS POSSIBLE move A1,-*A2,W ;ID GETPX mmfm SP,A2,A12 RETS NONELFT: .IF DEBUG LOCKUP EINT .ELSE CALLERR 4,2 .ENDIF JRUC GETPX * *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 SEXT A0,W 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 *A0(PA11),A11,L RETS GETA10 move *A0(PA10),A10,L RETS GETA9 move *A0(PA9),A9,L RETS GETREGS move *A0(PA11),A11,L move *A0(PA10),A10,L move *A0(PA9),A9,L GETA8 move *A0(PA8),A8,L RETS GETWAKE move *A0(PWAKE),A7,L RETS PUTA11 move A11,*A0(PA11),L RETS PUTA10 move A10,*A0(PA10),L RETS PUTA9 move A9,*A0(PA9),L RETS PUTREGS move A11,*A0(PA11),L move A10,*A0(PA10),L move A9,*A0(PA9),L PUTA8 move A8,*A0(PA8),L RETS PUTA7 PUTWAKE move A7,*A0(PWAKE),L RETS .END