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

  ViewVC Help
Powered by ViewVC 1.1.22