示例#1
0
        public DMAController(IOProcessor iop)
        {
            _iop = iop;

            for (int i = 0; i < _channels.Length; i++)
            {
                _channels[i] = new DMAChannel();
            }
        }
示例#2
0
        /// <summary>
        /// Executes a single DMA transfer (if there are
        /// any transfers pending).  This takes 4 clock
        /// cycles.
        /// </summary>
        public void Execute()
        {
            //
            // See if there's anything to do.
            //
            int nextChannel = SelectNextChannel();

            //
            // Raise HRQ if so.
            //
            _hrq = nextChannel != -1;

            if (_hrq)
            {
                DMAChannel c = _channels[nextChannel];

                if (Log.Enabled)
                {
                    Log.Write(LogComponent.IOPDMA, "Channel {0} selected.  {1} bytes to {2}, addr 0x{3:x4}.",
                              nextChannel, c.ChCount, c.Type, c.ChAddr);
                }

                switch (c.Type)
                {
                case DMAType.Verify:
                    throw new NotImplementedException("DMA Verify not implemented.");

                case DMAType.Read:
                    // Read byte from memory and transfer to device
                    byte dmaWrite = _iop.Memory.ReadByte(c.ChAddr);
                    c.Device.DMAWrite(dmaWrite);

                    if (Log.Enabled)
                    {
                        Log.Write(LogComponent.IOPDMA, "DMA read transfer of byte 0x{0:x2} from address 0x{1:x4}", dmaWrite, c.ChAddr);
                    }
                    break;

                case DMAType.Write:
                    // Read byte from device and transfer to memory.
                    byte dmaRead = c.Device.DMARead();
                    _iop.Memory.WriteByte(c.ChAddr, dmaRead);

                    if (Log.Enabled)
                    {
                        Log.Write(LogComponent.IOPDMA, "DMA write transfer of byte 0x{0:x2} to address 0x{1:x4}", dmaRead, c.ChAddr);
                    }
                    break;
                }

                // Increment address, decrement counter.
                c.ChAddr++;
                c.ChCount--;

                // If the counter runs out, stop the channel if so enabled.
                if (c.ChCount == 0)
                {
                    if (Log.Enabled)
                    {
                        Log.Write(LogComponent.IOPDMA, "Channel {0} completed.", nextChannel);
                    }
                    // Stop this crazy thing.
                    if (_tcStop)
                    {
                        c.Enabled = false;
                        if (Log.Enabled)
                        {
                            Log.Write(LogComponent.IOPDMA, "Channel {0} disabled.", nextChannel);
                        }
                    }

                    c.Completed = true;
                    c.Device.DMAComplete();
                }

                _lastSelectedChannel = nextChannel;
            }
        }