-- 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