public DMAController(IOProcessor iop) { _iop = iop; for (int i = 0; i < _channels.Length; i++) { _channels[i] = new DMAChannel(); } }
/// <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; } }