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

Contents of /trunk/pcsx2/VU0microInterp.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (10 years, 2 months ago) by william
File size: 4716 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
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 #include "PrecompiledHeader.h"
18 #include "Common.h"
19
20 #include "VUmicro.h"
21
22 extern void _vuFlushAll(VURegs* VU);
23
24 static void _vu0ExecUpper(VURegs* VU, u32 *ptr) {
25 VU->code = ptr[1];
26 IdebugUPPER(VU0);
27 VU0_UPPER_OPCODE[VU->code & 0x3f]();
28 }
29
30 static void _vu0ExecLower(VURegs* VU, u32 *ptr) {
31 VU->code = ptr[0];
32 IdebugLOWER(VU0);
33 VU0_LOWER_OPCODE[VU->code >> 25]();
34 }
35
36 int vu0branch = 0;
37 static void _vu0Exec(VURegs* VU)
38 {
39 _VURegsNum lregs;
40 _VURegsNum uregs;
41 VECTOR _VF;
42 VECTOR _VFc;
43 REG_VI _VI;
44 REG_VI _VIc;
45 u32 *ptr;
46 int vfreg;
47 int vireg;
48 int discard=0;
49
50 ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
51 VU->VI[REG_TPC].UL+=8;
52
53 if (ptr[1] & 0x40000000) {
54 VU->ebit = 2;
55 }
56 if (ptr[1] & 0x20000000) { /* M flag */
57 VU->flags|= VUFLAG_MFLAGSET;
58 // Console.WriteLn("fixme: M flag set");
59 }
60 if (ptr[1] & 0x10000000) { /* D flag */
61 if (VU0.VI[REG_FBRST].UL & 0x4) {
62 VU0.VI[REG_VPU_STAT].UL|= 0x2;
63 hwIntcIrq(INTC_VU0);
64 }
65 }
66 if (ptr[1] & 0x08000000) { /* T flag */
67 if (VU0.VI[REG_FBRST].UL & 0x8) {
68 VU0.VI[REG_VPU_STAT].UL|= 0x4;
69 hwIntcIrq(INTC_VU0);
70 }
71 }
72
73 VU->code = ptr[1];
74 VU0regs_UPPER_OPCODE[VU->code & 0x3f](&uregs);
75 #ifndef INT_VUSTALLHACK
76 _vuTestUpperStalls(VU, &uregs);
77 #endif
78
79 /* check upper flags */
80 if (ptr[1] & 0x80000000) { /* I flag */
81 _vu0ExecUpper(VU, ptr);
82
83 VU->VI[REG_I].UL = ptr[0];
84 memset(&lregs, 0, sizeof(lregs));
85 } else {
86 VU->code = ptr[0];
87 VU0regs_LOWER_OPCODE[VU->code >> 25](&lregs);
88 #ifndef INT_VUSTALLHACK
89 _vuTestLowerStalls(VU, &lregs);
90 #endif
91
92 vu0branch = lregs.pipe == VUPIPE_BRANCH;
93
94 vfreg = 0; vireg = 0;
95 if (uregs.VFwrite) {
96 if (lregs.VFwrite == uregs.VFwrite) {
97 // Console.Warning("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle");
98 discard = 1;
99 }
100 if (lregs.VFread0 == uregs.VFwrite ||
101 lregs.VFread1 == uregs.VFwrite) {
102 // Console.WriteLn("saving reg %d at pc=%x", i, VU->VI[REG_TPC].UL);
103 _VF = VU->VF[uregs.VFwrite];
104 vfreg = uregs.VFwrite;
105 }
106 }
107 if (uregs.VIread & (1 << REG_CLIP_FLAG)) {
108 if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) {
109 Console.Warning("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle");
110 discard = 1;
111 }
112 if (lregs.VIread & (1 << REG_CLIP_FLAG)) {
113 _VI = VU0.VI[REG_CLIP_FLAG];
114 vireg = REG_CLIP_FLAG;
115 }
116 }
117
118 _vu0ExecUpper(VU, ptr);
119
120 if (discard == 0) {
121 if (vfreg) {
122 _VFc = VU->VF[vfreg];
123 VU->VF[vfreg] = _VF;
124 }
125 if (vireg) {
126 _VIc = VU->VI[vireg];
127 VU->VI[vireg] = _VI;
128 }
129
130 _vu0ExecLower(VU, ptr);
131
132 if (vfreg) {
133 VU->VF[vfreg] = _VFc;
134 }
135 if (vireg) {
136 VU->VI[vireg] = _VIc;
137 }
138 }
139 }
140 _vuAddUpperStalls(VU, &uregs);
141
142 if (!(ptr[1] & 0x80000000))
143 _vuAddLowerStalls(VU, &lregs);
144
145 _vuTestPipes(VU);
146
147 if (VU->branch > 0) {
148 VU->branch--;
149 if (VU->branch == 0) {
150 VU->VI[REG_TPC].UL = VU->branchpc;
151 }
152 }
153
154 if( VU->ebit > 0 ) {
155 if( VU->ebit-- == 1 ) {
156 _vuFlushAll(VU);
157 VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */
158 vif0Regs.stat.VEW = false;
159 }
160 }
161 }
162
163 void vu0Exec(VURegs* VU)
164 {
165 VU0.VI[REG_TPC].UL &= VU0_PROGMASK;
166 _vu0Exec(VU);
167 VU->cycle++;
168
169 if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n");
170 if (VU->VF[0].f.x != 0.0f) DbgCon.Error("VF[0].x != 0.0!!!!\n");
171 if (VU->VF[0].f.y != 0.0f) DbgCon.Error("VF[0].y != 0.0!!!!\n");
172 if (VU->VF[0].f.z != 0.0f) DbgCon.Error("VF[0].z != 0.0!!!!\n");
173 if (VU->VF[0].f.w != 1.0f) DbgCon.Error("VF[0].w != 1.0!!!!\n");
174 }
175
176 // --------------------------------------------------------------------------------------
177 // VU0microInterpreter
178 // --------------------------------------------------------------------------------------
179 InterpVU0::InterpVU0()
180 {
181 m_Idx = 0;
182 IsInterpreter = true;
183 }
184
185 void InterpVU0::Step()
186 {
187 vu0Exec( &VU0 );
188 }
189
190 void InterpVU0::Execute(u32 cycles)
191 {
192 for (int i = (int)cycles; i > 0 ; i--) {
193 if (!(VU0.VI[REG_VPU_STAT].UL & 0x1)) {
194 if (VU0.branch || VU0.ebit) {
195 vu0Exec(&VU0); // run branch delay slot?
196 }
197 break;
198 }
199 vu0Exec(&VU0);
200 }
201 }
202

  ViewVC Help
Powered by ViewVC 1.1.22