-- File: PupJuniper.mesa, Last Edit: HGM October 16, 1979 7:28 PM
DIRECTORY
CommUtilDefs: FROM "CommUtilDefs" USING [GetEthernetHostNumber, Yield],
DriverDefs: FROM "DriverDefs" USING [
firstBuffer, dataWordsPerBuffer, numberOfBuffers,
doDebug, useCount, firstNetwork, Glitch],
PupJuniperDefs: FROM "PupJuniperDefs", -- EXPORTS
BufferDefs: FROM "BufferDefs" USING [Buffer, BufferObject],
PupTypes: FROM "PupTypes" USING [PupAddress, PupSocketID],
MachineIDDefs: FROM "MachineIDDefs" USING [ProcessorID, ethernetSeries];
PupJuniper: MONITOR
IMPORTS CommUtilDefs, DriverDefs
EXPORTS PupJuniperDefs, BufferDefs, MachineIDDefs
SHARES MachineIDDefs =
BEGIN OPEN PupTypes;
MachineID: TYPE = MachineIDDefs.ProcessorID;
CommPackageNotActive: PUBLIC ERROR = CODE;
FirstDriverNeitherLocalNorEthernet: PUBLIC ERROR = CODE;
FreeQueueNotInitialized: PUBLIC ERROR = CODE;
MachineIDFromPupAddress: PUBLIC PROCEDURE [a: PupAddress] RETURNS [MachineID] =
BEGIN
RETURN[ [
[ethernet [ net: a.net, host: a.host ]],
MachineIDDefs.ethernetSeries] ];
END;
PupAddressFromMachineID: PUBLIC PROCEDURE [m: MachineID, soc: PupSocketID]
RETURNS [PupAddress] =
BEGIN
WITH em: m.element SELECT ethernet FROM
ethernet => RETURN [ [net: [em.net], host: [em.host], socket: soc] ];
ENDCASE;
ERROR; -- can’t happen
END;
-- For now, we do not have a hard-wired ProcessorID, so we use one derived from our Ethernet Address. That brings up the problem of which Ethernet Address should be used, since in general we may be connected to multiple networks. The answer, for now, is to use the address from the first device on the chain, which will normally be the standard Ethernet board.
GetMyMachineID: PUBLIC PROCEDURE RETURNS [MachineIDDefs.ProcessorID] =
BEGIN OPEN DriverDefs;
IF doDebug AND useCount=0 THEN Glitch[CommPackageNotActive];
IF firstNetwork=NIL THEN Glitch[CommPackageNotActive];
SELECT firstNetwork.device FROM
local =>
RETURN [ [
[ethernet [ net: 0, host: CommUtilDefs.GetEthernetHostNumber[] ]],
MachineIDDefs.ethernetSeries] ];
ethernet =>
BEGIN
UNTIL firstNetwork.netNumber#0 DO CommUtilDefs.Yield[]; ENDLOOP;
RETURN[ [
[ethernet [ net: firstNetwork.netNumber, host: firstNetwork.hostNumber ]],
MachineIDDefs.ethernetSeries] ];
END;
ENDCASE => Glitch[FirstDriverNeitherLocalNorEthernet];
ERROR;
END;
-- 1 extra for checksum
overhead: CARDINAL = MAX[
SIZE[pupWords pup BufferDefs.BufferObject]+1,
SIZE[rppWords rpp BufferDefs.BufferObject]+1];
-- Used to build a set of parallel tables
EnumerateBuffers: PUBLIC PROCEDURE [proc: PROCEDURE[BufferDefs.Buffer]] =
BEGIN OPEN DriverDefs;
i: CARDINAL;
wordsPerBuffer: CARDINAL;
b: BufferDefs.Buffer ← DriverDefs.firstBuffer;
IF doDebug AND firstBuffer=NIL THEN Glitch[FreeQueueNotInitialized];
wordsPerBuffer ← DriverDefs.dataWordsPerBuffer+overhead;
UNTIL (wordsPerBuffer MOD 4)=0 DO wordsPerBuffer ← wordsPerBuffer+1; ENDLOOP;
FOR i IN [0..numberOfBuffers) DO
proc[b];
b ← b+wordsPerBuffer;
ENDLOOP;
END;
-- initialization
END. -- PupJuniper