| 70 | } |
| 71 | |
| 72 | static __fi void vuExecMicro(int idx, u32 addr, bool requires_wait) |
| 73 | { |
| 74 | VIFregisters& vifRegs = vifXRegs; |
| 75 | |
| 76 | vifFlush(idx); |
| 77 | if (GetVifX.waitforvu) |
| 78 | { |
| 79 | CPU_SET_DMASTALL(idx ? vif1InternalIrq() : DMAC_VIF0, true); |
| 80 | return; |
| 81 | } |
| 82 | |
| 83 | if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) |
| 84 | { |
| 85 | Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops); |
| 86 | vifRegs.itops &= (idx ? 0x3ffu : 0xffu); |
| 87 | } |
| 88 | |
| 89 | vifRegs.itop = vifRegs.itops; |
| 90 | |
| 91 | if (idx) |
| 92 | { |
| 93 | // in case we're handling a VIF1 execMicro, set the top with the tops value |
| 94 | vifRegs.top = vifRegs.tops & 0x3ff; |
| 95 | |
| 96 | // is DBF flag set in VIF_STAT? |
| 97 | if (vifRegs.stat.DBF) |
| 98 | { |
| 99 | // it is, so set tops with base, and clear the stat DBF flag |
| 100 | vifRegs.tops = vifRegs.base; |
| 101 | vifRegs.stat.DBF = false; |
| 102 | } |
| 103 | else |
| 104 | { |
| 105 | // it is not, so set tops with base + offset, and set stat DBF flag |
| 106 | vifRegs.tops = vifRegs.base + vifRegs.ofst; |
| 107 | vifRegs.stat.DBF = true; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | GetVifX.queued_program = true; |
| 112 | if (static_cast<s32>(addr) == -1) |
| 113 | GetVifX.queued_pc = addr; |
| 114 | else |
| 115 | GetVifX.queued_pc = addr & (idx ? 0x7ffu : 0x1ffu); |
| 116 | GetVifX.unpackcalls = 0; |
| 117 | |
| 118 | GetVifX.queued_gif_wait = requires_wait; |
| 119 | |
| 120 | if (!idx || (!THREAD_VU1 && !INSTANT_VU1)) |
| 121 | vifExecQueue(idx); |
| 122 | } |
| 123 | |
| 124 | //------------------------------------------------------------------ |
| 125 | // Vif0/Vif1 Code Implementations |
no test coverage detected