/[pcsx2_0.9.7]/trunk/pcsx2/VU0.cpp
ViewVC logotype

Contents of /trunk/pcsx2/VU0.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 5 months ago) by william
File size: 14249 byte(s)
committing r3113 initial commit again...
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16
17 /* TODO
18 -Fix the flags Proper as they aren't handle now..
19 -Add BC Table opcodes
20 -Add Interlock in QMFC2,QMTC2,CFC2,CTC2
21 -Finish instruction set
22 -Bug Fixes!!!
23 */
24
25 #include "PrecompiledHeader.h"
26 #include "Common.h"
27
28 #include <cmath>
29
30 #include "R5900OpcodeTables.h"
31 #include "VUmicro.h"
32
33 #define _Ft_ _Rt_
34 #define _Fs_ _Rd_
35 #define _Fd_ _Sa_
36
37 #define _X (cpuRegs.code>>24) & 0x1
38 #define _Y (cpuRegs.code>>23) & 0x1
39 #define _Z (cpuRegs.code>>22) & 0x1
40 #define _W (cpuRegs.code>>21) & 0x1
41
42 #define _Fsf_ ((cpuRegs.code >> 21) & 0x03)
43 #define _Ftf_ ((cpuRegs.code >> 23) & 0x03)
44
45 using namespace R5900;
46
47 __aligned16 VURegs VU0;
48
49 void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();}
50 void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();}
51
52 void COP2_SPECIAL2() {
53 Int_COP2SPECIAL2PrintTable[(cpuRegs.code & 0x3) | ((cpuRegs.code >> 4) & 0x7c)]();
54 }
55
56 void COP2_Unknown()
57 {
58 CPU_LOG("Unknown COP2 opcode called");
59 }
60
61 //****************************************************************************
62
63 __forceinline void _vu0run(bool breakOnMbit, bool addCycles) {
64
65 if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
66
67 int startcycle = VU0.cycle;
68 u32 runCycles = breakOnMbit ? vu0RunCycles : 0x7fffffff;
69 VU0.flags &= ~VUFLAG_MFLAGSET;
70
71 do { // Run VU until it finishes or M-Bit
72 CpuVU0->Execute(runCycles);
73 } while ((VU0.VI[REG_VPU_STAT].UL & 1) // E-bit Termination
74 && (!breakOnMbit || !(VU0.flags & VUFLAG_MFLAGSET))); // M-bit Break
75
76 // Add cycles if called from EE's COP2
77 if (addCycles) cpuRegs.cycle += (VU0.cycle-startcycle)*2;
78 }
79
80 void _vu0WaitMicro() { _vu0run(1, 1); } // Runs VU0 Micro Until E-bit or M-Bit End
81 void _vu0FinishMicro() { _vu0run(0, 1); } // Runs VU0 Micro Until E-Bit End
82 void vu0Finish() { _vu0run(0, 0); } // Runs VU0 Micro Until E-Bit End (doesn't stall EE)
83
84 namespace R5900 {
85 namespace Interpreter{
86 namespace OpcodeImpl
87 {
88 void LQC2() {
89 u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
90 if (_Ft_) {
91 memRead128(addr, &VU0.VF[_Ft_].UD[0]);
92 } else {
93 u64 val[2];
94 memRead128(addr, val);
95 }
96 }
97
98 // Asadr.Changed
99 //TODO: check this
100 // HUH why ? doesn't make any sense ...
101 void SQC2() {
102 u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
103 //memWrite64(addr, VU0.VF[_Ft_].UD[0]);
104 //memWrite64(addr+8,VU0.VF[_Ft_].UD[1]);
105 memWrite128(addr, &VU0.VF[_Ft_].UD[0]);
106 }
107 }}}
108
109
110 void QMFC2() {
111 if (cpuRegs.code & 1) {
112 _vu0WaitMicro();
113 }
114 if (_Rt_ == 0) return;
115 cpuRegs.GPR.r[_Rt_].UD[0] = VU0.VF[_Fs_].UD[0];
116 cpuRegs.GPR.r[_Rt_].UD[1] = VU0.VF[_Fs_].UD[1];
117 }
118
119 void QMTC2() {
120 if (cpuRegs.code & 1) {
121 _vu0WaitMicro();
122 }
123 if (_Fs_ == 0) return;
124 VU0.VF[_Fs_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0];
125 VU0.VF[_Fs_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1];
126 }
127
128 void CFC2() {
129 if (cpuRegs.code & 1) {
130 _vu0WaitMicro();
131 }
132 if (_Rt_ == 0) return;
133 cpuRegs.GPR.r[_Rt_].UL[0] = VU0.VI[_Fs_].UL;
134 if(VU0.VI[_Fs_].UL & 0x80000000)
135 cpuRegs.GPR.r[_Rt_].UL[1] = 0xffffffff;
136 else
137 cpuRegs.GPR.r[_Rt_].UL[1] = 0;
138 }
139
140 void CTC2() {
141 if (cpuRegs.code & 1) {
142 _vu0WaitMicro();
143 }
144 if (_Fs_ == 0) return;
145
146 switch(_Fs_) {
147 case REG_MAC_FLAG: // read-only
148 case REG_TPC: // read-only
149 case REG_VPU_STAT: // read-only
150 break;
151 case REG_FBRST:
152 VU0.VI[REG_FBRST].UL = cpuRegs.GPR.r[_Rt_].UL[0] & 0x0C0C;
153 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x1) { // VU0 Force Break
154 Console.Error("fixme: VU0 Force Break");
155 }
156 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x2) { // VU0 Reset
157 //Console.WriteLn("fixme: VU0 Reset");
158 vu0ResetRegs();
159 }
160 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x100) { // VU1 Force Break
161 Console.Error("fixme: VU1 Force Break");
162 }
163 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x200) { // VU1 Reset
164 // Console.WriteLn("fixme: VU1 Reset");
165 vu1ResetRegs();
166 }
167 break;
168 case REG_CMSAR1: // REG_CMSAR1
169 if (!(VU0.VI[REG_VPU_STAT].UL & 0x100) ) {
170 vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0]); // Execute VU1 Micro SubRoutine
171 }
172 break;
173 default:
174 VU0.VI[_Fs_].UL = cpuRegs.GPR.r[_Rt_].UL[0];
175 break;
176 }
177 }
178
179 //---------------------------------------------------------------------------------------
180
181
182 __forceinline void SYNCMSFLAGS()
183 {
184 VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag;
185 VU0.VI[REG_MAC_FLAG].UL = VU0.macflag;
186 }
187
188 __forceinline void SYNCFDIV()
189 {
190 VU0.VI[REG_Q].UL = VU0.q.UL;
191 VU0.VI[REG_STATUS_FLAG].UL = VU0.statusflag;
192 }
193
194 void VABS() { VU0.code = cpuRegs.code; _vuABS(&VU0); }
195 void VADD() { VU0.code = cpuRegs.code; _vuADD(&VU0); SYNCMSFLAGS(); }
196 void VADDi() { VU0.code = cpuRegs.code; _vuADDi(&VU0); SYNCMSFLAGS(); }
197 void VADDq() { VU0.code = cpuRegs.code; _vuADDq(&VU0); SYNCMSFLAGS(); }
198 void VADDx() { VU0.code = cpuRegs.code; _vuADDx(&VU0); SYNCMSFLAGS(); }
199 void VADDy() { VU0.code = cpuRegs.code; _vuADDy(&VU0); SYNCMSFLAGS(); }
200 void VADDz() { VU0.code = cpuRegs.code; _vuADDz(&VU0); SYNCMSFLAGS(); }
201 void VADDw() { VU0.code = cpuRegs.code; _vuADDw(&VU0); SYNCMSFLAGS(); }
202 void VADDA() { VU0.code = cpuRegs.code; _vuADDA(&VU0); SYNCMSFLAGS(); }
203 void VADDAi() { VU0.code = cpuRegs.code; _vuADDAi(&VU0); SYNCMSFLAGS(); }
204 void VADDAq() { VU0.code = cpuRegs.code; _vuADDAq(&VU0); SYNCMSFLAGS(); }
205 void VADDAx() { VU0.code = cpuRegs.code; _vuADDAx(&VU0); SYNCMSFLAGS(); }
206 void VADDAy() { VU0.code = cpuRegs.code; _vuADDAy(&VU0); SYNCMSFLAGS(); }
207 void VADDAz() { VU0.code = cpuRegs.code; _vuADDAz(&VU0); SYNCMSFLAGS(); }
208 void VADDAw() { VU0.code = cpuRegs.code; _vuADDAw(&VU0); SYNCMSFLAGS(); }
209 void VSUB() { VU0.code = cpuRegs.code; _vuSUB(&VU0); SYNCMSFLAGS(); }
210 void VSUBi() { VU0.code = cpuRegs.code; _vuSUBi(&VU0); SYNCMSFLAGS(); }
211 void VSUBq() { VU0.code = cpuRegs.code; _vuSUBq(&VU0); SYNCMSFLAGS(); }
212 void VSUBx() { VU0.code = cpuRegs.code; _vuSUBx(&VU0); SYNCMSFLAGS(); }
213 void VSUBy() { VU0.code = cpuRegs.code; _vuSUBy(&VU0); SYNCMSFLAGS(); }
214 void VSUBz() { VU0.code = cpuRegs.code; _vuSUBz(&VU0); SYNCMSFLAGS(); }
215 void VSUBw() { VU0.code = cpuRegs.code; _vuSUBw(&VU0); SYNCMSFLAGS(); }
216 void VSUBA() { VU0.code = cpuRegs.code; _vuSUBA(&VU0); SYNCMSFLAGS(); }
217 void VSUBAi() { VU0.code = cpuRegs.code; _vuSUBAi(&VU0); SYNCMSFLAGS(); }
218 void VSUBAq() { VU0.code = cpuRegs.code; _vuSUBAq(&VU0); SYNCMSFLAGS(); }
219 void VSUBAx() { VU0.code = cpuRegs.code; _vuSUBAx(&VU0); SYNCMSFLAGS(); }
220 void VSUBAy() { VU0.code = cpuRegs.code; _vuSUBAy(&VU0); SYNCMSFLAGS(); }
221 void VSUBAz() { VU0.code = cpuRegs.code; _vuSUBAz(&VU0); SYNCMSFLAGS(); }
222 void VSUBAw() { VU0.code = cpuRegs.code; _vuSUBAw(&VU0); SYNCMSFLAGS(); }
223 void VMUL() { VU0.code = cpuRegs.code; _vuMUL(&VU0); SYNCMSFLAGS(); }
224 void VMULi() { VU0.code = cpuRegs.code; _vuMULi(&VU0); SYNCMSFLAGS(); }
225 void VMULq() { VU0.code = cpuRegs.code; _vuMULq(&VU0); SYNCMSFLAGS(); }
226 void VMULx() { VU0.code = cpuRegs.code; _vuMULx(&VU0); SYNCMSFLAGS(); }
227 void VMULy() { VU0.code = cpuRegs.code; _vuMULy(&VU0); SYNCMSFLAGS(); }
228 void VMULz() { VU0.code = cpuRegs.code; _vuMULz(&VU0); SYNCMSFLAGS(); }
229 void VMULw() { VU0.code = cpuRegs.code; _vuMULw(&VU0); SYNCMSFLAGS(); }
230 void VMULA() { VU0.code = cpuRegs.code; _vuMULA(&VU0); SYNCMSFLAGS(); }
231 void VMULAi() { VU0.code = cpuRegs.code; _vuMULAi(&VU0); SYNCMSFLAGS(); }
232 void VMULAq() { VU0.code = cpuRegs.code; _vuMULAq(&VU0); SYNCMSFLAGS(); }
233 void VMULAx() { VU0.code = cpuRegs.code; _vuMULAx(&VU0); SYNCMSFLAGS(); }
234 void VMULAy() { VU0.code = cpuRegs.code; _vuMULAy(&VU0); SYNCMSFLAGS(); }
235 void VMULAz() { VU0.code = cpuRegs.code; _vuMULAz(&VU0); SYNCMSFLAGS(); }
236 void VMULAw() { VU0.code = cpuRegs.code; _vuMULAw(&VU0); SYNCMSFLAGS(); }
237 void VMADD() { VU0.code = cpuRegs.code; _vuMADD(&VU0); SYNCMSFLAGS(); }
238 void VMADDi() { VU0.code = cpuRegs.code; _vuMADDi(&VU0); SYNCMSFLAGS(); }
239 void VMADDq() { VU0.code = cpuRegs.code; _vuMADDq(&VU0); SYNCMSFLAGS(); }
240 void VMADDx() { VU0.code = cpuRegs.code; _vuMADDx(&VU0); SYNCMSFLAGS(); }
241 void VMADDy() { VU0.code = cpuRegs.code; _vuMADDy(&VU0); SYNCMSFLAGS(); }
242 void VMADDz() { VU0.code = cpuRegs.code; _vuMADDz(&VU0); SYNCMSFLAGS(); }
243 void VMADDw() { VU0.code = cpuRegs.code; _vuMADDw(&VU0); SYNCMSFLAGS(); }
244 void VMADDA() { VU0.code = cpuRegs.code; _vuMADDA(&VU0); SYNCMSFLAGS(); }
245 void VMADDAi() { VU0.code = cpuRegs.code; _vuMADDAi(&VU0); SYNCMSFLAGS(); }
246 void VMADDAq() { VU0.code = cpuRegs.code; _vuMADDAq(&VU0); SYNCMSFLAGS(); }
247 void VMADDAx() { VU0.code = cpuRegs.code; _vuMADDAx(&VU0); SYNCMSFLAGS(); }
248 void VMADDAy() { VU0.code = cpuRegs.code; _vuMADDAy(&VU0); SYNCMSFLAGS(); }
249 void VMADDAz() { VU0.code = cpuRegs.code; _vuMADDAz(&VU0); SYNCMSFLAGS(); }
250 void VMADDAw() { VU0.code = cpuRegs.code; _vuMADDAw(&VU0); SYNCMSFLAGS(); }
251 void VMSUB() { VU0.code = cpuRegs.code; _vuMSUB(&VU0); SYNCMSFLAGS(); }
252 void VMSUBi() { VU0.code = cpuRegs.code; _vuMSUBi(&VU0); SYNCMSFLAGS(); }
253 void VMSUBq() { VU0.code = cpuRegs.code; _vuMSUBq(&VU0); SYNCMSFLAGS(); }
254 void VMSUBx() { VU0.code = cpuRegs.code; _vuMSUBx(&VU0); SYNCMSFLAGS(); }
255 void VMSUBy() { VU0.code = cpuRegs.code; _vuMSUBy(&VU0); SYNCMSFLAGS(); }
256 void VMSUBz() { VU0.code = cpuRegs.code; _vuMSUBz(&VU0); SYNCMSFLAGS(); }
257 void VMSUBw() { VU0.code = cpuRegs.code; _vuMSUBw(&VU0); SYNCMSFLAGS(); }
258 void VMSUBA() { VU0.code = cpuRegs.code; _vuMSUBA(&VU0); SYNCMSFLAGS(); }
259 void VMSUBAi() { VU0.code = cpuRegs.code; _vuMSUBAi(&VU0); SYNCMSFLAGS(); }
260 void VMSUBAq() { VU0.code = cpuRegs.code; _vuMSUBAq(&VU0); SYNCMSFLAGS(); }
261 void VMSUBAx() { VU0.code = cpuRegs.code; _vuMSUBAx(&VU0); SYNCMSFLAGS(); }
262 void VMSUBAy() { VU0.code = cpuRegs.code; _vuMSUBAy(&VU0); SYNCMSFLAGS(); }
263 void VMSUBAz() { VU0.code = cpuRegs.code; _vuMSUBAz(&VU0); SYNCMSFLAGS(); }
264 void VMSUBAw() { VU0.code = cpuRegs.code; _vuMSUBAw(&VU0); SYNCMSFLAGS(); }
265 void VMAX() { VU0.code = cpuRegs.code; _vuMAX(&VU0); }
266 void VMAXi() { VU0.code = cpuRegs.code; _vuMAXi(&VU0); }
267 void VMAXx() { VU0.code = cpuRegs.code; _vuMAXx(&VU0); }
268 void VMAXy() { VU0.code = cpuRegs.code; _vuMAXy(&VU0); }
269 void VMAXz() { VU0.code = cpuRegs.code; _vuMAXz(&VU0); }
270 void VMAXw() { VU0.code = cpuRegs.code; _vuMAXw(&VU0); }
271 void VMINI() { VU0.code = cpuRegs.code; _vuMINI(&VU0); }
272 void VMINIi() { VU0.code = cpuRegs.code; _vuMINIi(&VU0); }
273 void VMINIx() { VU0.code = cpuRegs.code; _vuMINIx(&VU0); }
274 void VMINIy() { VU0.code = cpuRegs.code; _vuMINIy(&VU0); }
275 void VMINIz() { VU0.code = cpuRegs.code; _vuMINIz(&VU0); }
276 void VMINIw() { VU0.code = cpuRegs.code; _vuMINIw(&VU0); }
277 void VOPMULA() { VU0.code = cpuRegs.code; _vuOPMULA(&VU0); SYNCMSFLAGS(); }
278 void VOPMSUB() { VU0.code = cpuRegs.code; _vuOPMSUB(&VU0); SYNCMSFLAGS(); }
279 void VNOP() { VU0.code = cpuRegs.code; _vuNOP(&VU0); }
280 void VFTOI0() { VU0.code = cpuRegs.code; _vuFTOI0(&VU0); }
281 void VFTOI4() { VU0.code = cpuRegs.code; _vuFTOI4(&VU0); }
282 void VFTOI12() { VU0.code = cpuRegs.code; _vuFTOI12(&VU0); }
283 void VFTOI15() { VU0.code = cpuRegs.code; _vuFTOI15(&VU0); }
284 void VITOF0() { VU0.code = cpuRegs.code; _vuITOF0(&VU0); }
285 void VITOF4() { VU0.code = cpuRegs.code; _vuITOF4(&VU0); }
286 void VITOF12() { VU0.code = cpuRegs.code; _vuITOF12(&VU0); }
287 void VITOF15() { VU0.code = cpuRegs.code; _vuITOF15(&VU0); }
288 void VCLIPw() { VU0.code = cpuRegs.code; _vuCLIP(&VU0); VU0.VI[REG_CLIP_FLAG].UL = VU0.clipflag; }
289
290 void VDIV() { VU0.code = cpuRegs.code; _vuDIV(&VU0); SYNCFDIV(); }
291 void VSQRT() { VU0.code = cpuRegs.code; _vuSQRT(&VU0); SYNCFDIV(); }
292 void VRSQRT() { VU0.code = cpuRegs.code; _vuRSQRT(&VU0); SYNCFDIV(); }
293 void VIADD() { VU0.code = cpuRegs.code; _vuIADD(&VU0); }
294 void VIADDI() { VU0.code = cpuRegs.code; _vuIADDI(&VU0); }
295 void VIADDIU() { VU0.code = cpuRegs.code; _vuIADDIU(&VU0); }
296 void VIAND() { VU0.code = cpuRegs.code; _vuIAND(&VU0); }
297 void VIOR() { VU0.code = cpuRegs.code; _vuIOR(&VU0); }
298 void VISUB() { VU0.code = cpuRegs.code; _vuISUB(&VU0); }
299 void VISUBIU() { VU0.code = cpuRegs.code; _vuISUBIU(&VU0); }
300 void VMOVE() { VU0.code = cpuRegs.code; _vuMOVE(&VU0); }
301 void VMFIR() { VU0.code = cpuRegs.code; _vuMFIR(&VU0); }
302 void VMTIR() { VU0.code = cpuRegs.code; _vuMTIR(&VU0); }
303 void VMR32() { VU0.code = cpuRegs.code; _vuMR32(&VU0); }
304 void VLQ() { VU0.code = cpuRegs.code; _vuLQ(&VU0); }
305 void VLQD() { VU0.code = cpuRegs.code; _vuLQD(&VU0); }
306 void VLQI() { VU0.code = cpuRegs.code; _vuLQI(&VU0); }
307 void VSQ() { VU0.code = cpuRegs.code; _vuSQ(&VU0); }
308 void VSQD() { VU0.code = cpuRegs.code; _vuSQD(&VU0); }
309 void VSQI() { VU0.code = cpuRegs.code; _vuSQI(&VU0); }
310 void VILW() { VU0.code = cpuRegs.code; _vuILW(&VU0); }
311 void VISW() { VU0.code = cpuRegs.code; _vuISW(&VU0); }
312 void VILWR() { VU0.code = cpuRegs.code; _vuILWR(&VU0); }
313 void VISWR() { VU0.code = cpuRegs.code; _vuISWR(&VU0); }
314 void VRINIT() { VU0.code = cpuRegs.code; _vuRINIT(&VU0); }
315 void VRGET() { VU0.code = cpuRegs.code; _vuRGET(&VU0); }
316 void VRNEXT() { VU0.code = cpuRegs.code; _vuRNEXT(&VU0); }
317 void VRXOR() { VU0.code = cpuRegs.code; _vuRXOR(&VU0); }
318 void VWAITQ() { VU0.code = cpuRegs.code; _vuWAITQ(&VU0); }
319 void VFSAND() { VU0.code = cpuRegs.code; _vuFSAND(&VU0); }
320 void VFSEQ() { VU0.code = cpuRegs.code; _vuFSEQ(&VU0); }
321 void VFSOR() { VU0.code = cpuRegs.code; _vuFSOR(&VU0); }
322 void VFSSET() { VU0.code = cpuRegs.code; _vuFSSET(&VU0); }
323 void VFMAND() { VU0.code = cpuRegs.code; _vuFMAND(&VU0); }
324 void VFMEQ() { VU0.code = cpuRegs.code; _vuFMEQ(&VU0); }
325 void VFMOR() { VU0.code = cpuRegs.code; _vuFMOR(&VU0); }
326 void VFCAND() { VU0.code = cpuRegs.code; _vuFCAND(&VU0); }
327 void VFCEQ() { VU0.code = cpuRegs.code; _vuFCEQ(&VU0); }
328 void VFCOR() { VU0.code = cpuRegs.code; _vuFCOR(&VU0); }
329 void VFCSET() { VU0.code = cpuRegs.code; _vuFCSET(&VU0); }
330 void VFCGET() { VU0.code = cpuRegs.code; _vuFCGET(&VU0); }
331 void VXITOP() { VU0.code = cpuRegs.code; _vuXITOP(&VU0); }
332

  ViewVC Help
Powered by ViewVC 1.1.22