| 169 | } |
| 170 | |
| 171 | void _SPR0interleave() |
| 172 | { |
| 173 | int qwc = spr0ch.qwc; |
| 174 | int tqwc = dmacRegs.sqwc.TQWC; |
| 175 | const int sqwc = dmacRegs.sqwc.SQWC; |
| 176 | tDMA_TAG *pMem; |
| 177 | |
| 178 | if (tqwc == 0) tqwc = qwc; |
| 179 | //Console.WriteLn("dmaSPR0 interleave"); |
| 180 | SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx", |
| 181 | spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr); |
| 182 | |
| 183 | CPU_INT(DMAC_FROM_SPR, qwc * BIAS); |
| 184 | |
| 185 | while (qwc > 0) |
| 186 | { |
| 187 | spr0ch.qwc = std::min(tqwc, qwc); |
| 188 | qwc -= spr0ch.qwc; |
| 189 | pMem = SPRdmaGetAddr(spr0ch.madr, true); |
| 190 | |
| 191 | if(spr0ch.qwc > (0x400 - ((spr0ch.sadr & 0x3fff) >> 4))) |
| 192 | DevCon.Warning("Warning! Interleave on SPR0 going outside of SPR memory!"); |
| 193 | |
| 194 | switch (dmacRegs.ctrl.MFD) |
| 195 | { |
| 196 | case MFD_VIF1: |
| 197 | case MFD_GIF: |
| 198 | hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc); |
| 199 | break; |
| 200 | |
| 201 | case NO_MFD: |
| 202 | case MFD_RESERVED: |
| 203 | // Clear VU mem also! |
| 204 | TestClearVUs(spr0ch.madr, spr0ch.qwc, true); |
| 205 | memcpy_from_spr((u8*)pMem, spr0ch.sadr, spr0ch.qwc*16); |
| 206 | break; |
| 207 | } |
| 208 | spr0ch.sadr += spr0ch.qwc * 16; |
| 209 | spr0ch.sadr &= 0x3FFF; // Limited to 16K |
| 210 | spr0ch.madr += (sqwc + spr0ch.qwc) * 16; |
| 211 | } |
| 212 | if (dmacRegs.ctrl.STS == STS_fromSPR) |
| 213 | { |
| 214 | //DevCon.Warning("SPR0 Interleave Stall Control"); |
| 215 | dmacRegs.stadr.ADDR = spr0ch.madr; // Copy MADR to DMAC_STADR stall addr register |
| 216 | } |
| 217 | spr0ch.qwc = 0; |
| 218 | } |
| 219 | |
| 220 | static __fi void _dmaSPR0() |
| 221 | { |
no test coverage detected