| 182 | //---------------------------------------------------------------------------- |
| 183 | |
| 184 | _vifT void vifUnpackSetup(const u32 *data) { |
| 185 | |
| 186 | vifStruct& vifX = GetVifX; |
| 187 | |
| 188 | GetVifX.unpackcalls++; |
| 189 | |
| 190 | if (GetVifX.unpackcalls > 3) |
| 191 | { |
| 192 | vifExecQueue(idx); |
| 193 | } |
| 194 | //if (!idx) vif0FLUSH(); // Only VU0? |
| 195 | |
| 196 | vifX.usn = (vifXRegs.code >> 14) & 0x01; |
| 197 | int vifNum = (vifXRegs.code >> 16) & 0xff; |
| 198 | |
| 199 | if (vifNum == 0) vifNum = 256; |
| 200 | vifXRegs.num = vifNum; |
| 201 | |
| 202 | // This is for use when XGKick is synced as VIF can overwrite XG Kick data as it's transferring out |
| 203 | // Test with Aggressive Inline Skating, or K-1 Premium 2005 Dynamite! |
| 204 | // VU currently flushes XGKICK on VU1 end so no need for this, yet |
| 205 | /*if (idx == 1 && VU1.xgkickenable && !(VU0.VI[REG_TPC].UL & 0x100)) |
| 206 | { |
| 207 | // Catch up first, then the unpack cycles |
| 208 | _vuXGKICKTransfer(cpuRegs.cycle - VU1.xgkicklastcycle, false); |
| 209 | _vuXGKICKTransfer(vifNum * 2, false); |
| 210 | }*/ |
| 211 | |
| 212 | // Traditional-style way of calculating the gsize, based on VN/VL parameters. |
| 213 | // Useful when VN/VL are known template params, but currently they are not so we use |
| 214 | // the LUT instead (for now). |
| 215 | //uint vl = vifX.cmd & 0x03; |
| 216 | //uint vn = (vifX.cmd >> 2) & 0x3; |
| 217 | //uint gsize = ((32 >> vl) * (vn+1)) / 8; |
| 218 | |
| 219 | const u8& gsize = nVifT[vifX.cmd & 0x0f]; |
| 220 | |
| 221 | uint wl = vifXRegs.cycle.wl ? vifXRegs.cycle.wl : 256; |
| 222 | |
| 223 | if (wl <= vifXRegs.cycle.cl) { //Skipping write |
| 224 | vifX.tag.size = ((vifNum * gsize) + 3) / 4; |
| 225 | } |
| 226 | else { //Filling write |
| 227 | int n = vifXRegs.cycle.cl * (vifNum / wl) + |
| 228 | _limit(vifNum % wl, vifXRegs.cycle.cl); |
| 229 | |
| 230 | vifX.tag.size = ((n * gsize) + 3) >> 2; |
| 231 | } |
| 232 | |
| 233 | u32 addr = vifXRegs.code; |
| 234 | if (idx && ((addr>>15)&1)) addr += vif1Regs.tops; |
| 235 | vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0); |
| 236 | |
| 237 | VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vifX.tag.size); |
| 238 | |
| 239 | vifX.cl = 0; |
| 240 | vifX.tag.cmd = vifX.cmd; |
| 241 | GetVifX.pass = 1; |
nothing calls this directly
no test coverage detected