| 212 | } |
| 213 | |
| 214 | __fi void gifInterrupt() |
| 215 | { |
| 216 | GIF_LOG("gifInterrupt caught qwc=%d fifo=%d(%d) apath=%d oph=%d state=%d!", gifch.qwc, gifRegs.stat.FQC, gif_fifo.fifoSize, gifRegs.stat.APATH, gifRegs.stat.OPH, gifUnit.gifPath[GIF_PATH_3].state); |
| 217 | gifCheckPathStatus(false); |
| 218 | |
| 219 | if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE) |
| 220 | { |
| 221 | if (vif1Regs.stat.VGW) |
| 222 | { |
| 223 | // Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back. |
| 224 | if (!(cpuRegs.interrupt & (1 << DMAC_VIF1))) |
| 225 | CPU_INT(DMAC_VIF1, 1); |
| 226 | |
| 227 | // Make sure it loops if the GIF packet is empty to prepare for the next packet |
| 228 | // or end if it was the end of a packet. |
| 229 | // This must trigger after VIF retriggers as VIf might instantly mask Path3 |
| 230 | if (!gifUnit.Path3Masked() || gifch.qwc == 0) |
| 231 | { |
| 232 | GifDMAInt(16); |
| 233 | } |
| 234 | CPU_SET_DMASTALL(DMAC_GIF, gifUnit.Path3Masked() || !gifUnit.CanDoPath3()); |
| 235 | return; |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | if (dmacRegs.ctrl.MFD == MFD_GIF) |
| 240 | { // GIF MFIFO |
| 241 | //Console.WriteLn("GIF MFIFO"); |
| 242 | gifMFIFOInterrupt(); |
| 243 | return; |
| 244 | } |
| 245 | |
| 246 | if (gifUnit.gsSIGNAL.queued) |
| 247 | { |
| 248 | GIF_LOG("Path 3 Paused"); |
| 249 | GifDMAInt(128); |
| 250 | CPU_SET_DMASTALL(DMAC_GIF, true); |
| 251 | if (gif_fifo.fifoSize == 16) |
| 252 | return; |
| 253 | } |
| 254 | |
| 255 | // If there's something in the FIFO and we can do PATH3, empty the FIFO. |
| 256 | if (gif_fifo.fifoSize > 0) |
| 257 | { |
| 258 | const int readSize = gif_fifo.read_fifo(); |
| 259 | |
| 260 | if (readSize) |
| 261 | GifDMAInt(readSize * BIAS); |
| 262 | |
| 263 | // The following is quite timing sensitive so we need to pause/resume the DMA in these certain scenarios |
| 264 | // If the DMA is masked/blocked and the fifo is full, no need to run the DMA |
| 265 | // If we just read from the fifo, we want to loop and not read more DMA |
| 266 | // If there is no DMA data waiting and the DMA is active, let the DMA progress until there is |
| 267 | if ((!CheckPaths() && gif_fifo.fifoSize == 16) || readSize) |
| 268 | { |
| 269 | CPU_SET_DMASTALL(DMAC_GIF, gifUnit.Path3Masked() || !gifUnit.CanDoPath3()); |
| 270 | return; |
| 271 | } |
no test coverage detected