-- File: Boss.mesa, Last Edit: -- MAS April 17, 1980 11:02 PM -- HGM November 12, 1979 5:33 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY StatsDefs: FROM "StatsDefs" USING [StatIncr, StatsGetCounters, StatsGetText], CommUtilDefs: FROM "CommUtilDefs" USING [ AllocateLockedNode, LockCode, UnlockCode, SetDebuggingPointer], DriverDefs: FROM "DriverDefs" USING [ doDebug, doStats, Glitch, GiantVector, pupRouter, wordsPerIocb, PutOnGlobalDoneQueue, GetInputBuffer, FreeQueueDestroy, FreeQueueMake, CreateDefaultEthernetDriver, Network, DispatcherOff, DispatcherOn, DispatcherCold, QueueCold], PupDefs: FROM "PupDefs"; -- EXPORTs Boss: MONITOR IMPORTS StatsDefs, CommUtilDefs, DriverDefs EXPORTS DriverDefs, PupDefs SHARES DriverDefs = BEGIN OPEN CommUtilDefs, DriverDefs; -- SemiPublic things for others firstNetwork: PUBLIC Network _ NIL; giantVector: PUBLIC LONG POINTER TO GiantVector; useCount: PUBLIC CARDINAL _ 0; state: {off, ready} _ off; IocbNotBigEnough: PUBLIC ERROR = CODE; CommPackageNotActive: PUBLIC ERROR = CODE; GetDoStats: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN RETURN[doStats]; END; -- This code is a bit delicate. There are probably many funny cases that won't work correctly. In particular, there is a race condition between adding/deleting a driver and adding/deleting a router. AddDeviceToChain: PUBLIC PROCEDURE [ network: Network, iocbSize: CARDINAL ] = BEGIN -- Add new drivers to the end of the chain so that the normal Ethernet driver will be network zero. tail: Network _ firstNetwork; i: CARDINAL _ 1; UNTIL (iocbSize MOD 4)=0 DO iocbSize _ iocbSize+1; ENDLOOP; IF state=off THEN wordsPerIocb _ MAX[wordsPerIocb,iocbSize] ELSE IF iocbSize>wordsPerIocb THEN Glitch[IocbNotBigEnough]; IF state=ready THEN LockCode[network.interrupt]; IF useCount>0 THEN BEGIN network.activateDriver[]; DriverDefs.pupRouter.addNetwork[network]; END; IF firstNetwork=NIL THEN BEGIN firstNetwork _ network; network.index _ 1; RETURN; END; UNTIL tail.next=NIL DO tail _ tail.next; i _ i+1; ENDLOOP; tail.next _ network; network.index _ i+1; END; RemoveDeviceFromChain: PUBLIC ENTRY PROCEDURE [ network: Network ] = BEGIN tail: Network _ firstNetwork; IF useCount>0 THEN BEGIN DriverDefs.pupRouter.removeNetwork[network]; network.deactivateDriver[]; END; IF state=ready THEN UnlockCode[network.interrupt]; IF firstNetwork=network THEN firstNetwork_network.next ELSE BEGIN UNTIL tail.next=network DO tail_tail.next; ENDLOOP; tail.next _ network.next; END; -- network.index is not updated. It is used only to collect Gateway statistics. END; GetDeviceChain: PUBLIC PROCEDURE RETURNS [ Network ] = BEGIN IF state#ready THEN Glitch[CommPackageNotActive]; RETURN[firstNetwork]; END; -- This may be called at any time. It does nothing if already ready. PupPackageReady: PUBLIC ENTRY PROCEDURE = BEGIN CommPackageReady[]; END; CommPackageReady: INTERNAL PROCEDURE = BEGIN network: Network; IF useCount=0 AND firstNetwork=NIL THEN [] _ CreateDefaultEthernetDriver[]; IF state=ready THEN RETURN; -- On the Alto, MakeImage forgets low memory IF doDebug THEN CommUtilDefs.SetDebuggingPointer[giantVector]; IF doStats THEN LockCode[StatsDefs.StatIncr]; LockCode[DriverDefs.GetInputBuffer]; -- QueueLocked(Tiny) LockCode[DriverDefs.PutOnGlobalDoneQueue]; -- DispatcherLocked(Fast) FreeQueueMake[]; DispatcherOn[]; FOR network_firstNetwork,network.next UNTIL network=NIL DO LockCode[network.interrupt]; ENDLOOP; state _ ready; END; CommPackageGo: PUBLIC ENTRY PROCEDURE = BEGIN network: Network; -- On the Alto, MakeImage forgets low memory IF doDebug THEN CommUtilDefs.SetDebuggingPointer[giantVector]; CommPackageReady[]; IF (useCount_useCount+1)>1 THEN RETURN; FOR network_firstNetwork,network.next UNTIL network=NIL DO network.activateDriver[]; ENDLOOP; END; CommPackageOff: PUBLIC ENTRY PROCEDURE = BEGIN network: Network; IF (useCount_useCount-1)#0 THEN RETURN; FOR network_firstNetwork,network.next UNTIL network=NIL DO network.deactivateDriver[]; UnlockCode[network.interrupt]; ENDLOOP; DispatcherOff[]; FreeQueueDestroy[]; IF doStats THEN UnlockCode[StatsDefs.StatIncr]; UnlockCode[DriverDefs.GetInputBuffer]; -- QueueLocked(Tiny) UnlockCode[DriverDefs.PutOnGlobalDoneQueue]; -- DispatcherLocked(Tiny) state _ off; END; -- initialization IF doDebug THEN BEGIN giantVector _ CommUtilDefs.AllocateLockedNode[SIZE[GiantVector]]; CommUtilDefs.SetDebuggingPointer[giantVector]; giantVector.statCounters _ IF doStats THEN StatsDefs.StatsGetCounters[] ELSE NIL; giantVector.statStrings _ IF doStats THEN StatsDefs.StatsGetText[] ELSE NIL; giantVector.slaThings _ giantVector.prThings _ NIL; END; START DriverDefs.DispatcherCold; START DriverDefs.QueueCold; END. -- Boss(2048)\1055b10B75i202bI16B70i102I613b21B522b14B204b15B65b16B621b13B343b14B488b1B