From bc5e287a9e11d74a0c6f1560c1b4668d69d0dab4 Mon Sep 17 00:00:00 2001 From: Josh Dersch Date: Thu, 28 Mar 2019 15:49:12 -0700 Subject: [PATCH] Fix for lost word on received Ethernet packets; <-EIData on non-c2 cycles returns last dequeued word from rcv FIFO. --- D/CP/Microinstruction.cs | 2 ++ D/Ethernet/EthernetController.cs | 53 +++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/D/CP/Microinstruction.cs b/D/CP/Microinstruction.cs index 111637f..4cad5e3 100644 --- a/D/CP/Microinstruction.cs +++ b/D/CP/Microinstruction.cs @@ -1103,6 +1103,8 @@ namespace D.CP { memWrite = "{MAR/MDR/MD} "; } + + yBusIsSourceForDestination = true; } // diff --git a/D/Ethernet/EthernetController.cs b/D/Ethernet/EthernetController.cs index 3922315..ed3421b 100644 --- a/D/Ethernet/EthernetController.cs +++ b/D/Ethernet/EthernetController.cs @@ -78,7 +78,7 @@ namespace D.Ethernet _readerLock = new ReaderWriterLockSlim(); - // Start the ethernet reciever poll event, this will run forever. + // Start the ethernet reciever poll event, this will run forever. _system.Scheduler.Schedule(_receiverPollInterval, ReceiverPollCallback); Reset(); @@ -111,6 +111,7 @@ namespace D.Ethernet _outputData = 0; _outputDataLatched = false; _fifo.Clear(); + _fifoHead = 0; _inputPacket.Clear(); _crc32.Reset(); } @@ -208,6 +209,7 @@ namespace D.Ethernet if (!_enableTx) { _fifo.Clear(); + _fifoHead = 0; StopTransmitter(); } @@ -245,6 +247,7 @@ namespace D.Ethernet if (!_loopBack) { _fifo.Clear(); + _fifoHead = 0; } _inputPacket.Clear(); @@ -315,6 +318,7 @@ namespace D.Ethernet // Throw out input data and stop the receiver _inputPacket.Clear(); _fifo.Clear(); + _fifoHead = 0; _inAttn = false; _lastRWord = false; _rxMode_ = true; @@ -332,7 +336,20 @@ namespace D.Ethernet // if (_fifo.Count > 0) { - value = _fifo.Dequeue(); + //ss + // if cycle == 2 we dequeue the next item from the FIFO; + // otherwise the last-dequeued item is returned. + // (See OPT schematic, sheet 6: + // "<-EIData not in Cycle2 is rereading EIData in the case + // of a uCode PageCross.") + // + if (cycle == 2) + { + _fifoHead = _fifo.Dequeue(); + } + + value = _fifoHead; + if (Log.Enabled) Log.Write(LogComponent.EthernetReceive, " <-EIData: Returning FIFO word 0x{0:x4}. FIFO count is now {1}", value, _fifo.Count); @@ -741,6 +758,7 @@ namespace D.Ethernet } _fifo.Clear(); + _fifoHead = 0; // // Skip the preamble state (only used in loopback) @@ -834,7 +852,14 @@ namespace D.Ethernet private void UpdateWakeup() { // - // See schematic, pg 2; ethernet requests (wakeups) generated by: // TxMode & BufIR & Defer' & LastWord' (i.e.transmit on, fifo buffer not full, not deferring, not the last word) // OR // Defer & TickElapsed (microcode asked for the transmission to be deferred, and that deferral time has elapsed) // OR // RcvMode & BufOR & Purge' (i.e. rcv on, fifo data ready, not purging fifo) // OR // Attn (i.e.hardware has a a status to report) + // See schematic, pg 2; ethernet requests (wakeups) generated by: + // TxMode & BufIR & Defer' & LastWord' (i.e.transmit on, fifo buffer not full, not deferring, not the last word) + // OR + // Defer & TickElapsed (microcode asked for the transmission to be deferred, and that deferral time has elapsed) + // OR + // RcvMode & BufOR & Purge' (i.e. rcv on, fifo data ready, not purging fifo) + // OR + // Attn (i.e.hardware has a a status to report) // bool txWakeup = _enableTx && _fifo.Count < 16 && !_defer && !_lastWord; bool deferWakeup = _defer & _tickElapsed; @@ -859,6 +884,7 @@ namespace D.Ethernet private bool _outputDataLatched; private ushort _outputData; private Queue _fifo; + private ushort _fifoHead; // Last word dequeued from the FIFO via <-EIData during c2. // Input data private Queue _inputPacket; @@ -896,7 +922,19 @@ namespace D.Ethernet // DiagVideoData : 2 // VideoClock : 1 // Used by LSEP // DiagLineSync : 0 - private bool _turnOff_; private bool _rxEvenLen; private bool _rxGoodCRC; private bool _rxOverrun_; private bool _rxGoodAlign; private bool _txUnderrun; private bool _txCollision_; private bool _rxMode_; private bool _enableTx; private bool _lastWord; private bool _enableRcv; private bool _localLoop; private bool _loopBack; + private bool _turnOff_; + private bool _rxEvenLen; + private bool _rxGoodCRC; + private bool _rxOverrun_; + private bool _rxGoodAlign; + private bool _txUnderrun; + private bool _txCollision_; + private bool _rxMode_; + private bool _enableTx; + private bool _lastWord; + private bool _enableRcv; + private bool _localLoop; + private bool _loopBack; // EOCtl: Bit(etc) // ---------------------------- @@ -906,7 +944,12 @@ namespace D.Ethernet private bool _defer; - // EICtl: Bit(xerox order) // ------------------------------------ // EnableRcv 15 // TurnOff' 14 // LocalLoop 13 // LoopBack 12 + // EICtl: Bit(xerox order) + // ------------------------------------ + // EnableRcv 15 + // TurnOff' 14 + // LocalLoop 13 + // LoopBack 12 // (See above) //