koreth@ssyx.ucsc.edu.ucsc.edu (Steven Grimm) (12/27/88)
Submitted-by: madsen@sask.usask.ca (Jorgen Madsen) Posting-number: Volume 1, Issue 81 Archive-name: mx2v230/part01 [The binaries have been posted to comp.binaries.atari.st. -sg] #!/bin/sh # shar: Shell Archiver (v1.22) # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # Run the following text with /bin/sh to create: # ACC.MOD # ATOMIC.DEF # ATOMIC.MOD # BITSTUFF.DEF # BITSTUFF.MOD # CLI.MOD # COM.MOD # KILLLP.MOD # LOGIN.DEF # LOGIN.MOD # LP.MOD # MX2.MOD # MX2LIB.C # MX2NET.MOD # MX2NOTES.TXT # NETAUX.MOD # NETMIDI.MOD # NETWORK.DEF # NETWORK.MOD # NEWSYS.DEF # NEWSYS.MOD # PASSWD.MOD # PIPE.DEF # PIPE.MOD # PS.MOD # REDIR.MOD # RUN.MOD # SCANNER.DEF # SCANNER.MOD # SPAWN.MOD # SPOOLER.MOD # SQ.MOD # SUBMIT.MOD # SUBMITA.MOD # SUBMITM.MOD # SYS.MOD # SYSCALL.DEF # SYSCALL.MOD # XA.MOD # XMODEM.DEF # XMODEM.MOD # XMODEMR.MOD # XMODEMT.MOD # XS.MOD # if test -r s2_seq_.tmp then echo "Must unpack archives in sequence!" next=`cat s2_seq_.tmp`; echo "Please unpack part $next next" exit 1; fi sed 's/^X//' << 'SHAR_EOF' > ACC.MOD && X X(* Copyright 1987,1988 fred brooks LogicTek *) X(* *) X(* *) X(* First Release 12/8/87-FGB *) X(* Added code to tell the context switcher the value of the *) X(* ACC Super Stack to help it with multitasking gem programs *) X(* 3/9/88-FGB *) X(* *) X XMODULE acc; X(*$T-,$S-*) XFROM ATOMIC IMPORT VERSION; XFROM SYSTEM IMPORT ADDRESS,ADR; XFROM GEMDOS IMPORT Super,ConOut; XFROM AESApplications IMPORT ApplInitialise; XFROM AESMenus IMPORT MenuRegister; XFROM AESEvents IMPORT EventMultiple; XFROM GEMAESbase IMPORT AccessoryOpen; XFROM AESForms IMPORT FormAlert; X XVAR X applID : INTEGER; (* desk application ID *) X menuID,waittime : INTEGER; (* menu ID *) X Msg : ARRAY [0..16] OF INTEGER; X handle, events, x,emask,b : INTEGER; X ssv,stacksave : ADDRESS; X superstack [144H] : ADDRESS; X mx2run : BOOLEAN; X X XBEGIN X (* initialise application & install desk accessory *) X applID := ApplInitialise(); X menuID := MenuRegister(applID,VERSION); X emask:=48; (* timer and message *) X waittime:=10000; (* check every 10 seconds to see if mx2 is running *) X mx2run:=FALSE; X X ssv:=0; X Super(ssv); (* in super mode *) X superstack:=ssv; (* save superstack value for context switcher *) X stacksave:=ssv; X Super(ssv); (* return to gem stack space *) X LOOP X events := EventMultiple(emask,0,0,0, X 0,0,0,0,0, X 0,0,0,0,0, X ADR(Msg), X waittime,0, X x,x,x,x, X x,x); X IF NOT mx2run THEN X ssv:=0; X Super(ssv); (* in super mode *) X IF superstack#stacksave THEN X waittime:=0; (* set timer to zero *) X mx2run:=TRUE; X END; X Super(ssv); (* return to gem stack space *) X END; X IF Msg[0]=AccessoryOpen THEN X IF emask=48 THEN b:=1 ELSE b:=2 END; X ConOut(7c); X x:=FormAlert(b,"[2][Fred Brooks LogicTek| | Switch|MX2 Desk Accessory][ON|OFF]"); X Msg[0]:=0; X IF x=1 THEN X emask:=48; (* message and timer *) X ELSE X emask:=16; (* just message *) X END; X END; X END; XEND acc. SHAR_EOF chmod 0600 ACC.MOD || echo "restore of ACC.MOD fails" sed 's/^X//' << 'SHAR_EOF' > ATOMIC.DEF && XDEFINITION MODULE ATOMIC; X X(* Copyright 1987,1988 fred brooks LogicTek *) X(* *) X(* *) X(* First Release 12/8/87-FGB *) X(* Added variable parm to StartProcess to pass info to process *) X(* in currentprocess.gemsave[15] 1/1/88-FGB *) X(* *) X(* Remove monitor priority. Each routine the switches processes *) X(* must be protected from all interrupts by the IntEnd and *) X(* IntBegin calls. If this is not done correctly the system *) X(* system will bomb. 4/4/88-FGB *) X(* *) X XFROM SYSTEM IMPORT ADDRESS,BYTE; XFROM NEWSYS IMPORT PROCESS; XFROM Strings IMPORT String; X XCONST MAGIC = 22261; (* somebodys b-day *) X buflength = 1024; X OTOS = LONGCARD(602CH); (* Old rom TOS *) X MTOS = LONGCARD(87CEH); (* New rom MEGA TOS *) X OLDDATE = 11201985H; X NEWDATE = 04221987H; X VERSION = " MX2 V2.3.0"; (* mx2 version number *) XTYPE X Gvectype = POINTER TO ADDRESS; X buffer = ARRAY [0..buflength] OF BYTE; X PIPE = RECORD X pipename: String; X buf : buffer; X bufsize : CARDINAL; X bufhead : CARDINAL; X buftail : CARDINAL; X cnt : CARDINAL; X END; X pipeptr = POINTER TO PIPE; X(* these devices are defined for use with the MX2 port command X dev0 thru dev7 are user defineable device drivers. By loading X the addresses of the correct procedures into the DeviceTable for X in, out and status custom devices may be defined. X DeviceTable[dev0].bconstat:=Mybconstat; X DeviceTable[dev0].bcostat:=Mybcostat; X DeviceTable[dev0].bconin:=Mybconin; X DeviceTable[dev0].bconout:=Mybconout; X Will setup dev0 for use with the port command. X X sys port 4 -0 -0 X will cause the process with the PID of 4 to use dev0 X*) X devicetype = (printer,aux,con,midi,null,dev0,dev1,dev2,dev3, X dev4,dev5,dev6,dev7); X devstattype = PROCEDURE(): BOOLEAN; X devintype = PROCEDURE(): LONGCARD; X devouttype = PROCEDURE(CHAR); X X devblocktype = RECORD X bconstat : devstattype; X bcostat : devstattype; X bconin : devintype; X bconout : devouttype; X END; X devtabletype = ARRAY [ORD(dev0)..ORD(dev7)] OF devblocktype; X XTYPE SIGNAL = POINTER TO ProcessDescriptor; X GEMTYPE = ARRAY [0..0FFH] OF ADDRESS; X pipetype = ARRAY [0..31] OF pipeptr; X (* pipe names starting with mx2 or MX2 are reserved by the X system *) X(* This is the control record for all system process. Variable X "currentprocess" points to the currently running process. The ready X queue is implemented as a linked list round robin. *) X X(* The gemsave array contains important system vectors that are switched X with every process. This allows programs to intercept trap vectors X such as the GEMDOS TRAP 1 and still to allow the other programs X to run correctly. current vectors saved are X gemsave[0] gem workspace pointer X gemsave[1] LINEA VECTOR 28H X gemsave[2] GEMDOS TRAP 1 84H X gemsave[3] GSX,GEM TRAP 2 88H X gemsave[4] BIOS TRAP 13 B4H X gemsave[5] XBIOS TRAP 14 B8H X gemsave[6] linef VECTOR 2CH X gemsave[7] level2 VECTOR 68H X gemsave[8] level4 VECTOR 70H X gemsave[9] _shell_p 4F6H X gemsave[11] wait value (* V2.2.0 *) X gemsave[12] wait mask (* V2.2.0 *) X gemsave[13] sleep timer variable X gemsave[14] timer flag variable X gemsave[15] init parameter for process X X misc[0] priority work variable X*) X X ProcessDescriptor = X RECORD X name : String; (* process name *) X pid : INTEGER; (* process id *) X cor : PROCESS; (* process coroutine *) X pc : ADDRESS; (* process PC *) X sr : CARDINAL; (* process SR *) X ssp : ADDRESS; (* process super SR *) X biosval : ADDRESS; (* bios call save ptr *) X retval : ADDRESS; X biosave : ARRAY [0..225] OF CARDINAL; X gemsave : ARRAY [0..15] OF ADDRESS; X termvec : ADDRESS; X wsp : ADDRESS; (* process work space *) X wspsize : LONGCARD; (* size of work space *) X next : SIGNAL; (* ptr to next process *) X ppid : INTEGER; (* parent id *) X tmpcor : PROCESS; (* cor save variable *) X ready : BOOLEAN; (* process run flag *) X active : BOOLEAN; (* process alive flag *) X intflag : BOOLEAN; (* process switched *) X date : CARDINAL; (* date started *) X time : CARDINAL; (* time started *) X tick : LONGCARD; (* total 200hz clocks *) X slice : LONGCARD; (* restart time 200hz *) X pri : INTEGER; (* set length of run *) X flags : ARRAY [0..2] OF LONGCARD; (* var *) X(* flags[0] is default drive of process that called the kernel X flags[1] is address of process to be added to ready list of kernel X flags[2] is size of process stack or workspace X*) X ipname : String; (* program name *) X iptail : String; (* program command *) X ipenvstr : String; (* program env string *) X return : INTEGER; (* function return *) X errno : INTEGER; (* error number *) X bpsave : GEMTYPE; (* save for gemdos *) X Iport : devicetype; X Oport : devicetype; X waitloc : POINTER TO LONGCARD; (* V2.2.0 *) X misc : ARRAY [0..8] OF INTEGER; X END; X X(* Vector 144H points to variable that contains this record *) X(* look at SYS.MOD for an example of use of these variables *) X X sysrequesttype = X RECORD X req : BOOLEAN; X pid : INTEGER; X magic : LONGCARD; X END; X X spinttype = X RECORD X proc : PROC; X pid : INTEGER; X data : ADDRESS; X END; X X StartProcesstype = PROCEDURE(VAR PROC,VAR LONGCARD, X VAR INTEGER,VAR String, X VAR ADDRESS); X SwapProcesstype = PROCEDURE; X TermProcesstype = PROCEDURE(VAR INTEGER); X NextPidtype = PROCEDURE(): INTEGER; X SleepProcesstype = PROCEDURE(VAR INTEGER); X WakeupProcesstype = PROCEDURE(VAR INTEGER); X ChangeProcessPrioritytype = PROCEDURE(VAR INTEGER,VAR INTEGER); X MultiBegintype = PROCEDURE; X MultiEndtype = PROCEDURE; X DozeProcesstype = PROCEDURE(VAR INTEGER,VAR LONGCARD); X WaitProcesstype = PROCEDURE(VAR INTEGER,VAR ADDRESS, X VAR LONGCARD, VAR LONGCARD, X VAR LONGCARD); X X sysvariable = X RECORD X currentprocess : POINTER TO SIGNAL; X MULTI : POINTER TO BOOLEAN; X slicebegin : POINTER TO LONGCARD; X contextswitch : POINTER TO LONGCARD; X command : POINTER TO String; X request : POINTER TO sysrequesttype; X CRON : POINTER TO PROC; X spintenable : POINTER TO BITSET; X spintmask : POINTER TO BITSET; X spint : POINTER TO ARRAY [0..15] OF spinttype; X bpsave : POINTER TO GEMTYPE; X pipes : POINTER TO pipetype; X sysmemsize : POINTER TO LONGCARD; X gemsaveGvec : POINTER TO Gvectype; X StartProcess : StartProcesstype; X SwapProcess : SwapProcesstype; X TermProcess : TermProcesstype; X NextPid : NextPidtype; X SleepProcess : SleepProcesstype; X WakeupProcess : WakeupProcesstype; X ChangeProcessPriority : ChangeProcessPrioritytype; X MultiBegin : MultiBegintype; X MultiEnd : MultiEndtype; X DozeProcess : DozeProcesstype; X WaitProcess : WaitProcesstype; X CronActive : POINTER TO BOOLEAN; X DeviceTable : POINTER TO devtabletype; X END; X XVAR currentprocess : SIGNAL; X MULTI : BOOLEAN; X slicebegin : LONGCARD; X contextswitch : LONGCARD; X command : String; X request : sysrequesttype; X CRON : PROC; X spintenable : BITSET; X spintmask : BITSET; X spint : ARRAY [0..15] OF spinttype; X bpsave : GEMTYPE; X pipes : pipetype; X sysmemsize : LONGCARD; X ROMDATE [0fc0018H] : LONGCARD; X gemsaveGvec : Gvectype; X CronActive : BOOLEAN; X DeviceTable : devtabletype; X (* A spint is a software interrupt. It is called by X setting it's bit in the spint enable mask. Spints X 0-3 are reserved by the system *) X (* The CRON procedure variable is here to put your X own procedure into the init scheduler in MX2 this X procedure will be run every 30 seconds. It is setup to X the dummy procedure at first. to setup your own X get sysvar then (sysvar.CRON:='your procedure') *) X X(* start the master context switch interrupt and setup system variables *) XPROCEDURE Initsked; X X(* setup kernal to begin the system startup setup all buffers and X procedures for MX2 *) XPROCEDURE InitProcesses; X X(* shutdown kernal and restore to normal gem state *) X(* this currently does not work *) XPROCEDURE EndProcesses; X X(* create a process for the MX2 system, place in the scheduler ready X list, start new process *) XPROCEDURE StartProcess(VAR P: PROC; X VAR n: LONGCARD; X VAR priority: INTEGER; X VAR pn: String; X VAR parm: ADDRESS); X (* parm is the init parameter to be placed in X gemsave[15] *) X X(* store the currentprocess and switch to next process in ready list *) XPROCEDURE SwapProcess; X X(* end process and remove it from the ready list, free memory used by X process *) XPROCEDURE TermProcess(VAR id: INTEGER); X X(* return the next pid the system will use for a new process *) XPROCEDURE NextPid(): INTEGER; X X(* tell scheduler not to run this process but keep in memory *) XPROCEDURE SleepProcess(VAR id: INTEGER); X X(* tell scheduler to sleep for msec 1000th of a second *) XPROCEDURE DozeProcess(VAR id: INTEGER; VAR msec: LONGCARD); X X(* Sleep process until the contents of 'loc' equals 'value AND mask'. Xmsec is the timeout value in milliseconds if set the 0 it waits forever *) XPROCEDURE WaitProcess(VAR id: INTEGER; VAR loc: ADDRESS; X VAR value,mask,msec: LONGCARD); X X(* tell scheduler to start running this process again if it was sleeping X before *) XPROCEDURE WakeupProcess(VAR id: INTEGER); X X(* V0.7 change process priority *) XPROCEDURE ChangeProcessPriority(VAR id: INTEGER; VAR pri: INTEGER); X X(* turn on the scheduler interrupt, and start normal process switching *) XPROCEDURE MultiBegin; X X(* turn off the scheduler interrupt, used to stop process switching in X section of code that should not be swapped out *) XPROCEDURE MultiEnd; X X(* check if flag is TRUE and lock out other process from changing it's X state until procedure is over *) XPROCEDURE CheckFlag(VAR flag: BOOLEAN): BOOLEAN; X X(* set flag to TRUE and lock out other process from changing it's X state until procedure is over *) XPROCEDURE SetFlag(VAR flag: BOOLEAN); X X(* set flag to FALSE and lock out other process from changing it's X state until procedure is over *) XPROCEDURE ResetFlag(VAR flag: BOOLEAN); X X(* check if flag is TRUE then set flag to FALSE while locking out other X process from changing it's state until procedure is over *) XPROCEDURE CheckResetFlag(VAR flag: BOOLEAN): BOOLEAN; X XEND ATOMIC. X SHAR_EOF chmod 0600 ATOMIC.DEF || echo "restore of ATOMIC.DEF fails" sed 's/^X//' << 'SHAR_EOF' > ATOMIC.MOD && X X(* Copyright 1987,1988 fred brooks LogicTek *) X(* *) X(* *) X(* First Release 12/8/87-FGB *) X(* *) X(* Modified TermProcess to also kill all the children processes *) X(* of the parent. Changed FindProcess not to find zombies *) X(* 12/11/87-FGB *) X(* *) X(* Added variable parm to StartProcess to pass info to process *) X(* in currentprocess.gemsave[15] 1/1/88-FGB *) X(* The PID of the new process will be returned in variable parm *) X(* 2/24/88-FGB *) X(* *) X(* Added DozeProcess to allow timed a sleep of processes *) X(* 2/21/88-FGB *) X(* *) X(* Remove monitor priority. Each routine the switches processes *) X(* must be protected from all interrupts by the IntEnd and *) X(* IntBegin calls. If this is not done correctly the system *) X(* system will bomb. 4/4/88-FGB *) X(* *) X X X(*$T-,$S-,$A+ *) XIMPLEMENTATION MODULE ATOMIC; X XFROM SYSTEM IMPORT ADR,TSIZE, X CODE,SETREG,ADDRESS,REGISTER; XFROM NEWSYS IMPORT NEWPROCESS,PROCESS,TRANSFER,IOTRANSFER; XFROM XBIOS IMPORT SuperExec; XFROM BitStuff IMPORT LAnd; X XFROM GEMDOS IMPORT GetTime,GetDate,Super; X XFROM Storage IMPORT ALLOCATE,DEALLOCATE; X XFROM Strings IMPORT String; X XTYPE workspace = ARRAY [0..254] OF CARDINAL; X savetype = POINTER TO ARRAY [0..22] OF CARDINAL; X sigs = (sleep,wakeup,terminate,trace,routine, X program,wait,gem,tos); X CPFlagtype = SET OF sigs; X CPFlagptrtype = POINTER TO CPFlagtype; X XCONST trapvec = 110H; (* vector on IOTRANSFER *) X offsetvec = 140H; (* offset IOTRANSFER vector *) X intnum = 4; (* interrupt number on MFP *) X XVAR s0,s1,s2,schedproc,s, X initproc,lastproc : SIGNAL; X kin : ARRAY [0..32] OF INTEGER; X wsp0,wsp1,wsp2,wsp3 : workspace; X wsp,bios : ADDRESS; X etimer [400H] : ADDRESS; X biospointer [4a2H] : ADDRESS; X ptermvec [408H] : ADDRESS; X trap [trapvec] : ADDRESS; X memtop [436H] : ADDRESS; X flock [43eH] : CARDINAL; X hz200 [4baH] : LONGCARD; X temphz200,TICKS : LONGCARD; X sysvector [144H] : POINTER TO sysvariable; X accsuperstack : ADDRESS; X sysvar : sysvariable; X linea [28H] : ADDRESS; X gemdos [84H] : ADDRESS; X gsxgem [88H] : ADDRESS; X tbios [0b4H] : ADDRESS; X xbios [0b8H] : ADDRESS; X linef [2cH] : ADDRESS; X level2 [68H] : ADDRESS; X level4 [70H] : ADDRESS; X shellp [4F6H] : ADDRESS; X oldtrap,oldtermvec : ADDRESS; X OldEtimer,sspval : ADDRESS; X p,cotick,x,t,temp : PROCESS; X processesid,I : INTEGER; X zombie : BOOLEAN; X children,highpri : INTEGER; X savefrom,saveto : savetype; X CPFlagptr : CPFlagptrtype; X X (* -------------- BEGIN -------------- *) X XPROCEDURE StartProcess(VAR P : PROC; X VAR n : LONGCARD; X VAR priority : INTEGER; X VAR pn : String; X VAR parm : ADDRESS); XBEGIN X IntEnd; X SuperExec(UpdatecurrentProc); X ALLOCATE(wsp,n); X IF wsp=NIL THEN X currentprocess^.errno:=12; X IntBegin; X RETURN; X END; X DEC(sysmemsize,n); X s1:=currentprocess; X s0:=currentprocess; X X IF processesid>0 THEN (* search only after setup of SCHED *) X s0:=schedproc; (* set to sched process *) X LOOP (* find zombie process *) X s0:=s0^.next; X IF s0^.pid=1 THEN (* zombie not found in list *) X EXIT; X END; X FindZombieProcess(zombie); X IF zombie THEN EXIT END; X END; X END; (* if processesid>1 *) X X IF zombie THEN X currentprocess:=s0; X ELSE X ALLOCATE(currentprocess,TSIZE(ProcessDescriptor)); X IF currentprocess=NIL THEN X s1^.errno:=12; X IntBegin; X RETURN; X END; X DEC(sysmemsize,TSIZE(ProcessDescriptor)); X INC(processesid); X currentprocess^.pid:=processesid; X currentprocess^.next:=initproc; lastproc^.next:=currentprocess; X lastproc:=currentprocess; X END; X X WITH currentprocess^ DO X name:=pn; X ppid:=request.pid; X ready:=TRUE; active:=TRUE; X tick:=0; X IF priority<1 THEN priority:=1 END; X IF priority>10 THEN priority:=10 END; X pri:=priority; X misc[0]:=pri; X IF pri>highpri THEN highpri:=pri END; X GetTime(time); X GetDate(date); X gemsave[13]:=0; (* set timer to zero *) X gemsave[14]:=0; (* set all flags to zero *) X gemsave[15]:=parm; X parm:=ADDRESS(currentprocess^.pid); X Iport:=s1^.Iport; X Oport:=s1^.Oport; X END; X IF currentprocess^.pid>1 THEN X FindProcess(request.pid,s2); X s2^.return:=currentprocess^.pid; X ELSE X currentprocess^.return:=0; X END; X SuperExec(SetSlice); X currentprocess^.slice:=temphz200; X currentprocess^.wsp:=wsp; X currentprocess^.wspsize:=n; X NEWPROCESS(P,wsp,n,currentprocess^.cor); X SuperExec(intbiosptr); X s1^.errno:=0; X INC(contextswitch); (* update switch counter *) X TRANSFER(s1^.cor,currentprocess^.cor); X IntBegin; XEND StartProcess; X XPROCEDURE TermProcess(VAR id: INTEGER); XBEGIN X IF id<2 THEN RETURN END; X IntEnd; X X FindProcess(id,s2); X IF s2=NIL THEN X currentprocess^.errno:=3; X IntBegin; X RETURN; X END; X currentprocess^.errno:=0; X X s2^.active:=FALSE; (* set flag *) X IF s2^.wsp#NIL THEN X DEALLOCATE(s2^.wsp,s2^.wspsize); X INC(sysmemsize,s2^.wspsize); X END; X s2^.wsp:=NIL; (* set TO NIL to make zombie process *) X s0:=currentprocess; (* set to the parent process *) X X kin[0]:=id; X REPEAT (* loop thru process list and find all related processes *) X FindChildProcess(kin[0],s1); X WHILE s1#NIL DO X INC(children); X kin[children]:=s1^.pid; X s1^.active:=FALSE; (* set flag *) X s1^.gemsave[14]:=0; (* reset all flags *) X IF s1^.wsp#NIL THEN X DEALLOCATE(s1^.wsp,s1^.wspsize); X INC(sysmemsize,s1^.wspsize); X END; X s1^.wsp:=NIL; (* set TO NIL to make zombie process *) X currentprocess:=s1; (* set currentprocess to terminated *) X SuperExec(IncSlice); (* update cpu time for terminated *) X FindChildProcess(kin[0],s1); X END; X kin[0]:=kin[children]; X DEC(children); X UNTIL children<0; X currentprocess:=s0; X X currentprocess^.errno:=0; X s1:=currentprocess; (* save currentprocess *) X currentprocess:=s2; (* set currentprocess to terminated *) X SuperExec(UpdatecurrentProc); (* update cpu time for terminated *) X X X currentprocess:=schedproc; (* set to transfer to the sched *) X X IF s1^.pid#id THEN X temp:=s1^.cor; (* currentprocess different than terminated *) X ELSE X temp:=t; (* process the same so set up dummy process *) X END; X X IF s1^.pid#1 THEN X SuperExec(UpdateProc); X TRANSFER(temp,currentprocess^.cor); (* do context switch *) X END; X IntBegin; XEND TermProcess; X XPROCEDURE NextPid(): INTEGER; XBEGIN X s1:=currentprocess; X s0:=currentprocess; X X IF processesid>0 THEN (* search only after setup of SCHED *) X s0:=schedproc; (* set to sched process *) X LOOP (* find zombie process *) X s0:=s0^.next; X IF s0^.pid=1 THEN (* zombie not found in list *) X EXIT; X END; X FindZombieProcess(zombie); X IF zombie THEN EXIT END; X END; X END; (* if processesid>1 *) X X IF zombie THEN X RETURN s0^.pid; X ELSE X RETURN processesid+1; X END; XEND NextPid; X XPROCEDURE SleepProcess(VAR id: INTEGER); XBEGIN X IF id<2 THEN RETURN END; X X IntEnd; X FindProcess(id,s2); X IF s2=NIL THEN X currentprocess^.errno:=3; X IntBegin; X RETURN; X END; X currentprocess^.errno:=0; X X IF (s2^.wsp#NIL) AND (NOT s2^.active) THEN IntBegin; RETURN END; X IF s2^.wsp#NIL THEN X s2^.active:=FALSE; (* set flag *) X CPFlagptr:=ADR(s2^.gemsave[14]); X INCL(CPFlagptr^,sleep); X s2^.gemsave[13]:=0; X END; X X s1:=currentprocess; (* save currentprocess *) X SuperExec(UpdatecurrentProc); (* update cpu time for sleeper *) X X currentprocess:=schedproc; (* set to transfer to the sched *) X X IF s1^.pid#1 THEN X s1^.ready:=FALSE; currentprocess^.ready:=TRUE; X SuperExec(UpdateProc); X TRANSFER(s1^.cor,currentprocess^.cor); (* do context switch *) X END; X IntBegin; XEND SleepProcess; X XPROCEDURE DozeProcess(VAR id: INTEGER; VAR msec : LONGCARD); XBEGIN X IF id<2 THEN RETURN END; X X IntEnd; X FindProcess(id,s2); X IF s2=NIL THEN X currentprocess^.errno:=3; X IntBegin; X RETURN; X END; X currentprocess^.errno:=0; X X IF (s2^.wsp#NIL) AND (NOT s2^.active) THEN X IntBegin; X RETURN; X END; X IF s2^.wsp#NIL THEN X s2^.active:=FALSE; (* set flag *) X CPFlagptr:=ADR(s2^.gemsave[14]); X INCL(CPFlagptr^,sleep); X IF msec#0 THEN X SuperExec(SetSlice); X s2^.gemsave[13]:=ADDRESS(temphz200+(msec DIV 5)); X ELSE X s2^.gemsave[13]:=0; X END; X END; X X s1:=currentprocess; (* save currentprocess *) X SuperExec(getbiosptr); X SuperExec(UpdatecurrentProc); (* update cpu time for sleeper *) X X currentprocess:=schedproc; (* set to transfer to the sched *) X X IF s1^.pid#1 THEN X s1^.ready:=FALSE; currentprocess^.ready:=TRUE; X SuperExec(UpdateProc); X TRANSFER(s1^.cor,currentprocess^.cor); (* do context switch *) X END; X IntBegin; XEND DozeProcess; X XPROCEDURE WaitProcess(VAR id: INTEGER; VAR loc: ADDRESS; X VAR value,mask,msec : LONGCARD); XBEGIN X IF id<2 THEN RETURN END; X X IntEnd; X FindProcess(id,s2); X IF s2=NIL THEN X currentprocess^.errno:=3; X IntBegin; X RETURN; X END; X currentprocess^.errno:=0; X X IF (s2^.wsp#NIL) AND (NOT s2^.active) THEN X IntBegin; X RETURN; X END; X IF s2^.wsp#NIL THEN X s2^.active:=FALSE; (* set flag *) X CPFlagptr:=ADR(s2^.gemsave[14]); X INCL(CPFlagptr^,sleep); X INCL(CPFlagptr^,wait); X s2^.waitloc:=loc; X s2^.gemsave[11]:=ADDRESS(value); X s2^.gemsave[12]:=ADDRESS(mask); X IF msec#0 THEN X SuperExec(SetSlice); X s2^.gemsave[13]:=ADDRESS(temphz200+(msec DIV 5)); X ELSE X s2^.gemsave[13]:=0; X END; X END; X X s1:=currentprocess; (* save currentprocess *) X SuperExec(UpdatecurrentProc); (* update cpu time for sleeper *) X X currentprocess:=schedproc; (* set to transfer to the sched *) X X IF s1^.pid#1 THEN X s1^.ready:=FALSE; currentprocess^.ready:=TRUE; X SuperExec(UpdateProc); X TRANSFER(s1^.cor,currentprocess^.cor); (* do context switch *) X END; X IntBegin; XEND WaitProcess; X XPROCEDURE WakeupProcess(VAR id: INTEGER); XBEGIN X IF id<2 THEN RETURN END; X X IntEnd; X FindProcess(id,s2); X IF s2=NIL THEN X currentprocess^.errno:=3; X IntBegin; X RETURN; X END; X X IF (s2^.wsp#NIL) AND s2^.active THEN X currentprocess^.errno:=0; X IntBegin; X RETURN; (* already awake *) X END; X X IF s2^.wsp#NIL THEN X s2^.active:=TRUE; (* set flag *) X CPFlagptr:=ADR(s2^.gemsave[14]); X EXCL(CPFlagptr^,sleep); X currentprocess^.errno:=0; X ELSE X currentprocess^.errno:=3; X END; X IntBegin; XEND WakeupProcess; X X(* V0.7 *) XPROCEDURE ChangeProcessPriority(VAR id: INTEGER; VAR pri: INTEGER); XBEGIN X IF id<2 THEN RETURN END; X X IntEnd; X FindProcess(id,s2); X IF s2=NIL THEN X currentprocess^.errno:=3; X IntBegin; X RETURN; X END; X X IF pri<1 THEN pri:=1 END; X IF pri>10 THEN pri:=10 END; X s2^.pri:=pri; X IntBegin; XEND ChangeProcessPriority; X XPROCEDURE InitProcesses; XBEGIN X CRON:=dummy; X ALLOCATE(currentprocess,TSIZE(ProcessDescriptor)); X DEC(sysmemsize,TSIZE(ProcessDescriptor)); X processesid:=0; X initproc:=currentprocess; X lastproc:=initproc; X WITH currentprocess^ DO X next:=currentprocess; X ready:=FALSE; X active:=FALSE; X name:="INIT"; X GetTime(time); X GetDate(date); SHAR_EOF echo "End of part 1, continue with part 2" echo "2" > s2_seq_.tmp exit 0