-- File: TedOut.mesa, Last Edit: HGM August 23, 1980 7:24 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY InlineDefs USING [COPY], CommUtilDefs USING [GetTicks], TedDefs, AltoEthernetDefs, DriverDefs USING [Glitch, GetInputBuffer, PutOnGlobalInputQueue], BufferDefs, DriverTypes USING [pupEthernetPacket, ethernetBroadcastHost]; TedOut: MONITOR LOCKS TedDefs.lock IMPORTS InlineDefs, CommUtilDefs, DriverDefs, BufferDefs, AltoEthernetDefs, TedDefs EXPORTS TedDefs SHARES BufferDefs, DriverTypes = BEGIN OPEN BufferDefs, DriverDefs, AltoEthernetDefs, TedDefs; DriverNotActive: PUBLIC ERROR = CODE; EncapsulateRpp: PUBLIC PROCEDURE [RppBuffer, PupHostID] = LOOPHOLE[EncapsulatePup]; EncapsulatePup: PUBLIC PROCEDURE [b: PupBuffer, destination: PupHostID] = BEGIN b.encapsulation ← [ ethernet [ etherSpare1:, etherSpare2:, etherSpare3:, etherSpare4:, etherDest: destination, etherSource: TedDefs.myNetwork.hostNumber, ethernetType: DriverTypes.pupEthernetPacket ] ]; b.length ← (b.pupLength+1+ethernetEncapsulationBytes)/2; END; SendBuffer: PUBLIC ENTRY PROCEDURE [b: Buffer] = BEGIN copy: Buffer; IF tedPleaseStop THEN Glitch[DriverNotActive]; b.device ← ethernet; IF b.encapsulation.etherDest=TedDefs.myNetwork.hostNumber OR b.encapsulation.etherDest=DriverTypes.ethernetBroadcastHost THEN BEGIN -- sending to ourself, copy it over copy ← GetInputBuffer[]; IF copy#NIL THEN BEGIN copy.device ← ethernet; InlineDefs.COPY[ from: @b.encapsulation+ethernetEncapsulationOffset, nwords: b.length, to: @copy.encapsulation+ethernetEncapsulationOffset ]; copy.length ← b.length; copy.network ← @TedDefs.myNetwork; PutOnGlobalInputQueue[copy]; END; END; IF currentOutputBuffer=NIL THEN BEGIN currentOutputBuffer ← b; timeSendStarted ← CommUtilDefs.GetTicks[]; IF myDevice.inputBuffer.pointer↑#0 THEN GOTO PouringIn; myDevice.interruptBit ← 0; -- inhibit interrupts for reset myDevice.postData ← EthernetNotPosted; -- beware of hardware/microcode screwup -- it seems to hang while sending, after a collision, until a gateway packet arrives UNTIL myDevice.postData#EthernetNotPosted DO StartIO[resetCommand]; ENDLOOP; myDevice.interruptBit ← interruptBit; --interrupts back on myDevice.postData ← EthernetNotPosted; myDevice.retransmissionMask ← 0; -- zero the load for new packet myDevice.outputBuffer.count ← b.length; myDevice.outputBuffer.pointer ← ShortenData[ @b.encapsulation+ethernetEncapsulationOffset]; StartIO[outputCommand]; EXITS PouringIn =>NULL; END ELSE Enqueue[@outputQueue,b]; -- output already in progress, don't klobber it END; END. -- TedOut