diff --git a/Contralto/AltoSystem.cs b/Contralto/AltoSystem.cs index 38ff51f..5380cc7 100644 --- a/Contralto/AltoSystem.cs +++ b/Contralto/AltoSystem.cs @@ -172,7 +172,7 @@ namespace Contralto private void T_Elapsed(object sender, ElapsedEventArgs e) { - System.Console.WriteLine("{0} CPU clocks/sec %{1}. {2} fields/sec", _clocks, ((double)_clocks / 5882353.0) * 100.0, _displayController.Fields); + //System.Console.WriteLine("{0} CPU clocks/sec %{1}. {2} fields/sec", _clocks, ((double)_clocks / 5882353.0) * 100.0, _displayController.Fields); _clocks = 0; _displayController.Fields = 0; } diff --git a/Contralto/Disk/games.dsk b/Contralto/Disk/games.dsk index a2b05df..a8af94b 100644 Binary files a/Contralto/Disk/games.dsk and b/Contralto/Disk/games.dsk differ diff --git a/Contralto/Disk/gamesb.dsk b/Contralto/Disk/gamesb.dsk index e3f86b3..e73ba3e 100644 Binary files a/Contralto/Disk/gamesb.dsk and b/Contralto/Disk/gamesb.dsk differ diff --git a/Contralto/Disk/tdisk8.dsk b/Contralto/Disk/tdisk8.dsk index ee0cf5e..c777d99 100644 Binary files a/Contralto/Disk/tdisk8.dsk and b/Contralto/Disk/tdisk8.dsk differ diff --git a/Contralto/IO/EthernetController.cs b/Contralto/IO/EthernetController.cs index 891e26e..1032b87 100644 --- a/Contralto/IO/EthernetController.cs +++ b/Contralto/IO/EthernetController.cs @@ -33,6 +33,8 @@ namespace Contralto.IO // More words than the Alto will ever send. _outputData = new ushort[4096]; + + _nextPackets = new Queue(); } public void Reset() @@ -115,7 +117,9 @@ namespace Contralto.IO _incomingPacketLength = 0; _inGone = false; //_packetReady = false; - + + _system.Scheduler.CancelEvent(_fifoReceiveWakeupEvent); + if (_system.CPU != null) { _system.CPU.BlockTask(TaskType.Ethernet); @@ -341,23 +345,20 @@ namespace Contralto.IO /// private void OnHostPacketReceived(MemoryStream data) { - _receiverLock.EnterWriteLock(); - _packetReady = true; - _nextPacket = data; + _receiverLock.EnterWriteLock(); + _nextPackets.Enqueue(data); _receiverLock.ExitWriteLock(); } private void PacketPoll(ulong timeNsec, ulong skewNsec, object context) { _receiverLock.EnterUpgradeableReadLock(); - if (_packetReady) + if (_nextPackets.Count > 0) { - // Schedule the next word of data. - Console.WriteLine("**** hack *****"); - + // Schedule the next word of data. if (_iBusy && _incomingPacket == null) { - _incomingPacket = _nextPacket; + _incomingPacket = _nextPackets.Dequeue(); // Read the packet length (in words) (first word of the packet). Convert to bytes. // @@ -369,7 +370,9 @@ namespace Contralto.IO throw new InvalidOperationException("Invalid 3mbit packet length header."); } - Log.Write(LogComponent.EthernetController, "Accepting incoming packet (length {0}).", _incomingPacketLength); + Log.Write(LogComponent.EthernetPacket, "Accepting incoming packet (length {0}).", _incomingPacketLength); + + LogPacket(_incomingPacketLength, _incomingPacket); // From uCode: // "Interface will generate a data wakeup when the first word of the next @@ -386,16 +389,16 @@ namespace Contralto.IO _fifoReceiveWakeupEvent.TimestampNsec = _fifoReceiveDuration; _system.Scheduler.Schedule(_fifoReceiveWakeupEvent); } - else + else if (!_iBusy) { - // Drop, we're either already busy with a packet or we're not listening right now. - Log.Write(LogComponent.EthernetController, "Dropping incoming packet; controller is currently busy or not active (ibusy {0}, packet {1})", _iBusy, _incomingPacket != null); - } + // Drop, the receiver is not active. + Log.Write(LogComponent.EthernetPacket, "Dropping incoming packet; controller is currently not active."); - _receiverLock.EnterWriteLock(); - _packetReady = false; - _nextPacket = null; - _receiverLock.ExitWriteLock(); + MemoryStream discPacket = _nextPackets.Dequeue(); + int discPacketLength = ((discPacket.ReadByte()) | (discPacket.ReadByte() << 8)) * 2; + LogPacket(discPacketLength, discPacket); + + } } _receiverLock.ExitUpgradeableReadLock(); @@ -414,6 +417,7 @@ namespace Contralto.IO Log.Write(LogComponent.EthernetController, "FIFO callback after reset, abandoning input."); _incomingPacket = null; _incomingPacketLength = 0; + _inGone = false; _receiverLock.ExitUpgradeableReadLock(); return; } @@ -475,6 +479,17 @@ namespace Contralto.IO _receiverLock.ExitUpgradeableReadLock(); } + private void LogPacket(int length, MemoryStream packet) + { + Log.Write(LogComponent.EthernetPacket, + " - Packet src {0}, dest {1}, length {2}", + packet.ReadByte(), packet.ReadByte(), length); + + + // Return to top of packet + packet.Position = 2; + } + private Queue _fifo; // Bits in Status register @@ -502,7 +517,7 @@ namespace Contralto.IO private Event _fifoReceiveWakeupEvent; // Polling (hack) - private ulong _pollPeriod = 23000; + private ulong _pollPeriod = 10000; private Event _pollEvent; private bool _packetReady; @@ -514,8 +529,8 @@ namespace Contralto.IO int _outputIndex; // Incoming data and locking - private MemoryStream _incomingPacket; - private MemoryStream _nextPacket; + private MemoryStream _incomingPacket; + private Queue _nextPackets; private int _incomingPacketLength; private System.Threading.ReaderWriterLockSlim _receiverLock; diff --git a/Contralto/IO/HostEthernet.cs b/Contralto/IO/HostEthernet.cs index 16bc28c..f26812e 100644 --- a/Contralto/IO/HostEthernet.cs +++ b/Contralto/IO/HostEthernet.cs @@ -132,8 +132,8 @@ namespace Contralto.IO // Grab the source and destination host addresses from the packet we're sending // and build 10mbit versions. // - byte destinationHost = packetBytes[0]; - byte sourceHost = packetBytes[1]; + byte destinationHost = packetBytes[3]; + byte sourceHost = packetBytes[2]; Log.Write(LogComponent.HostEthernet, "Sending packet; source {0} destination {1}, length {2} words.", Conversion.ToOctal(sourceHost), @@ -141,7 +141,7 @@ namespace Contralto.IO length); MacAddress destinationMac = new MacAddress((UInt48)(_10mbitMACPrefix | destinationHost)); - MacAddress sourceMac = new MacAddress((UInt48)(_10mbitMACPrefix | sourceHost)); + MacAddress sourceMac = new MacAddress((UInt48)(_10mbitMACPrefix | Configuration.HostAddress)); // Build the outgoing packet; place the source/dest addresses, type field and the raw data. EthernetLayer ethernetLayer = new EthernetLayer @@ -170,7 +170,8 @@ namespace Contralto.IO // Filter out packets intended for the emulator, forward them on, drop everything else. // if ((int)p.Ethernet.EtherType == _3mbitFrameType && - (p.Ethernet.Destination.ToValue() & 0xffffffffff00) == _10mbitMACPrefix ) + (p.Ethernet.Destination.ToValue() & 0xffffffffff00) == _10mbitMACPrefix && + (p.Ethernet.Source.ToValue() & 0xff) != Configuration.HostAddress) // drop packets sent by ourselves { Log.Write(LogComponent.HostEthernet, "Received encapsulated 3mbit packet."); _callback(p.Ethernet.Payload.ToMemoryStream()); @@ -205,7 +206,7 @@ namespace Contralto.IO private void Open(bool promiscuous, int timeout) { - _communicator = _interface.Open(65536, promiscuous ? PacketDeviceOpenAttributes.Promiscuous | PacketDeviceOpenAttributes.NoCaptureLocal : PacketDeviceOpenAttributes.NoCaptureLocal, timeout); + _communicator = _interface.Open(65536, promiscuous ? PacketDeviceOpenAttributes.MaximumResponsiveness | PacketDeviceOpenAttributes.Promiscuous : PacketDeviceOpenAttributes.MaximumResponsiveness, timeout); // Set this to 1 so we'll get packets as soon as they arrive, no buffering. _communicator.SetKernelMinimumBytesToCopy(1); diff --git a/Contralto/Logging/Log.cs b/Contralto/Logging/Log.cs index ca878a4..c409644 100644 --- a/Contralto/Logging/Log.cs +++ b/Contralto/Logging/Log.cs @@ -26,6 +26,7 @@ namespace Contralto.Logging EthernetTask = 0x800, TaskSwitch = 0x1000, HostEthernet = 0x2000, + EthernetPacket = 0x4000, Debug = 0x40000000, All = 0x7fffffff @@ -53,10 +54,10 @@ namespace Contralto.Logging static Log() { // TODO: make configurable - _components = LogComponent.HostEthernet | LogComponent.EthernetController; // LogComponent.DiskController | LogComponent.DiskSectorTask | LogComponent.Debug | LogComponent.CPU; // LogComponent.EthernetController; // | LogComponent.Microcode | LogComponent.Memory | LogComponent.CPU; + _components = LogComponent.EthernetPacket | LogComponent.HostEthernet | LogComponent.EthernetController; // LogComponent.DiskController | LogComponent.DiskSectorTask | LogComponent.Debug | LogComponent.CPU; // LogComponent.EthernetController; // | LogComponent.Microcode | LogComponent.Memory | LogComponent.CPU; _type = LogType.Normal | LogType.Warning | LogType.Error | LogType.Verbose; - _logStream = new StreamWriter("log.txt"); + //_logStream = new StreamWriter("log.txt"); } public static LogComponent LogComponents