private void SendFrames()
        {
            this.Log(LogLevel.Noisy, "Sending frame");
            var transmitDescriptor = new TxDescriptor(machine.SystemBus);
            var packetData         = new List <byte>();

            transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            while (!transmitDescriptor.IsUsed)
            {
                transmitDescriptor.IsUsed = true;
                this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length);
                packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length));
                if (!transmitDescriptor.IsNextDescriptorChained)
                {
                    packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length));
                }

                transmitDescriptor.WriteBack();

                if (transmitDescriptor.IsEndOfRing)
                {
                    dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin;
                }
                else if (transmitDescriptor.IsNextDescriptorChained)
                {
                    dmaTransmitDescriptorListAddress = transmitDescriptor.Address2;
                }
                else
                {
                    dmaTransmitDescriptorListAddress += 8;
                }
                if (transmitDescriptor.IsLast)
                {
                    this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count);
                    if (Link.IsConnected)
                    {
                        var frame = EthernetFrame.CreateEthernetFrameWithoutCRC(packetData.ToArray());

                        if (transmitDescriptor.ChecksumInstertionControl > 0)
                        {
                            this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl);
                            if (transmitDescriptor.ChecksumInstertionControl == 1)
                            {
                                //IP only
                                frame.FillWithChecksums(supportedEtherChecksums, null);
                            }
                            else
                            {
                                //IP and payload
                                frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums);
                            }
                        }
                        this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine));

                        packetSent = true;
                        //We recreate the EthernetFrame because the CRC should be appended after creating inner checksums.
                        var frameWithCrc = EthernetFrame.CreateEthernetFrameWithCRC(frame.Bytes);
                        Link.TransmitFrameFromInterface(frameWithCrc);
                    }
                }
                transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            }

            //set TransmitBufferUnavailable
            dmaStatus |= TransmitBufferUnavailableStatus;
            if ((dmaInterruptEnable & (StartStopTransmission)) == 0)
            {
                IRQ.Set();
            }
            this.Log(LogLevel.Noisy, "Frame sent.");
        }
Exemple #2
0
        private void SendFrames()
        {
            this.Log(LogLevel.Noisy, "Sending frame");
            var transmitDescriptor = new TxDescriptor(machine.SystemBus);
            var packetData         = new List <byte>();

            transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            while (!transmitDescriptor.IsUsed)
            {
                transmitDescriptor.IsUsed = true;
                this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length);
                packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length));
                if (!transmitDescriptor.IsNextDescriptorChained)
                {
                    packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length));
                }

                transmitDescriptor.WriteBack();

                if (transmitDescriptor.IsEndOfRing)
                {
                    dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin;
                }
                else if (transmitDescriptor.IsNextDescriptorChained)
                {
                    dmaTransmitDescriptorListAddress = transmitDescriptor.Address2;
                }
                else
                {
                    dmaTransmitDescriptorListAddress += 8;
                }
                if (transmitDescriptor.IsLast)
                {
                    this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count);

                    if (!Misc.TryCreateFrameOrLogWarning(this, packetData.ToArray(), out var frame, addCrc: false))
                    {
                        continue;
                    }
                    if (transmitDescriptor.ChecksumInstertionControl > 0)
                    {
                        this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl);
                        if (transmitDescriptor.ChecksumInstertionControl == 1)
                        {
                            //IP only
                            frame.FillWithChecksums(supportedEtherChecksums, null);
                        }
                        else
                        {
                            //IP and payload
                            frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums);
                        }
                    }
                    this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine));

                    packetSent = true;
                    FrameReady?.Invoke(frame);
                }
                transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            }

            //set TransmitBufferUnavailable
            dmaStatus |= TransmitBufferUnavailableStatus;
            dmaStatus |= TransmitStatus;
            if ((dmaInterruptEnable & (StartStopTransmission)) == 0)
            {
                IRQ.Set();
            }
            this.Log(LogLevel.Noisy, "Frame sent.");
        }
Exemple #3
0
        private void SendFrames()
        {
            this.Log(LogLevel.Noisy, "Sending frame");
            var transmitDescriptor = new TxDescriptor(machine.SystemBus);
            var packetData = new List<byte>();

            transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            while(!transmitDescriptor.IsUsed)
            {
                transmitDescriptor.IsUsed = true;
                this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length);
                packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length));
                if(!transmitDescriptor.IsNextDescriptorChained)
                {
                    packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length));
                }

                transmitDescriptor.WriteBack();

                if(transmitDescriptor.IsEndOfRing)
                {
                    dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin;
                }
                else if(transmitDescriptor.IsNextDescriptorChained)
                {
                    dmaTransmitDescriptorListAddress = transmitDescriptor.Address2;
                }
                else
                {
                    dmaTransmitDescriptorListAddress += 8;
                }
                if(transmitDescriptor.IsLast)
                {
                    this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count);
                    if(Link.IsConnected)
                    {
                        var frame = new EthernetFrame(packetData.ToArray());

                        if(transmitDescriptor.ChecksumInstertionControl > 0)
                        {
                            this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl);
                            if(transmitDescriptor.ChecksumInstertionControl == 1)
                            {
                                //IP only
                                frame.FillWithChecksums(supportedEtherChecksums, null);
                            }
                            else
                            {
                                //IP and payload
                                frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums);
                            }
                        }
                        this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine));

                        packetSent = true;
                        Link.TransmitFrameFromInterface(frame);
                    }
                }
                transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            }

            //set TransmitBufferUnavailable
            dmaStatus |= TransmitBufferUnavailableStatus;
            if((dmaInterruptEnable & (StartStopTransmission)) == 0)
            {
                IRQ.Set();
            }
            this.Log(LogLevel.Noisy, "Frame sent.");
        }