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

Contents of /trunk/pcsx2/VU1microInterp.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 5 months ago) by william
File size: 4426 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 void _vu1ExecUpper(VURegs* VU, u32 *ptr) {
25 VU->code = ptr[1];
26 IdebugUPPER(VU1);
27 VU1_UPPER_OPCODE[VU->code & 0x3f]();
28 }
29
30 void _vu1ExecLower(VURegs* VU, u32 *ptr) {
31 VU->code = ptr[0];
32 IdebugLOWER(VU1);
33 VU1_LOWER_OPCODE[VU->code >> 25]();
34 }
35
36 int vu1branch = 0;
37
38 static void _vu1Exec(VURegs* VU)
39 {
40 _VURegsNum lregs;
41 _VURegsNum uregs;
42 VECTOR _VF;
43 VECTOR _VFc;
44 REG_VI _VI;
45 REG_VI _VIc;
46 u32 *ptr;
47 int vfreg;
48 int vireg;
49 int discard=0;
50
51 ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
52 VU->VI[REG_TPC].UL+=8;
53
54 if (ptr[1] & 0x40000000) { /* E flag */
55 VU->ebit = 2;
56 }
57 if (ptr[1] & 0x10000000) { /* D flag */
58 if (VU0.VI[REG_FBRST].UL & 0x400) {
59 VU0.VI[REG_VPU_STAT].UL|= 0x200;
60 hwIntcIrq(INTC_VU1);
61 }
62 }
63 if (ptr[1] & 0x08000000) { /* T flag */
64 if (VU0.VI[REG_FBRST].UL & 0x800) {
65 VU0.VI[REG_VPU_STAT].UL|= 0x400;
66 hwIntcIrq(INTC_VU1);
67 }
68 }
69
70 VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F);
71
72 VU->code = ptr[1];
73 VU1regs_UPPER_OPCODE[VU->code & 0x3f](&uregs);
74 #ifndef INT_VUSTALLHACK
75 _vuTestUpperStalls(VU, &uregs);
76 #endif
77
78 /* check upper flags */
79 if (ptr[1] & 0x80000000) { /* I flag */
80 _vu1ExecUpper(VU, ptr);
81
82 VU->VI[REG_I].UL = ptr[0];
83 } else {
84 VU->code = ptr[0];
85 VU1regs_LOWER_OPCODE[VU->code >> 25](&lregs);
86 #ifndef INT_VUSTALLHACK
87 _vuTestLowerStalls(VU, &lregs);
88 #endif
89
90 vu1branch = lregs.pipe == VUPIPE_BRANCH;
91
92 vfreg = 0; vireg = 0;
93 if (uregs.VFwrite) {
94 if (lregs.VFwrite == uregs.VFwrite) {
95 // Console.Warning("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle");
96 discard = 1;
97 }
98 if (lregs.VFread0 == uregs.VFwrite ||
99 lregs.VFread1 == uregs.VFwrite) {
100 // Console.WriteLn("saving reg %d at pc=%x", i, VU->VI[REG_TPC].UL);
101 _VF = VU->VF[uregs.VFwrite];
102 vfreg = uregs.VFwrite;
103 }
104 }
105 if (uregs.VIread & (1 << REG_CLIP_FLAG)) {
106 if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) {
107 Console.Warning("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle");
108 discard = 1;
109 }
110 if (lregs.VIread & (1 << REG_CLIP_FLAG)) {
111 _VI = VU->VI[REG_CLIP_FLAG];
112 vireg = REG_CLIP_FLAG;
113 }
114 }
115
116 _vu1ExecUpper(VU, ptr);
117
118 if (discard == 0) {
119 if (vfreg) {
120 _VFc = VU->VF[vfreg];
121 VU->VF[vfreg] = _VF;
122 }
123 if (vireg) {
124 _VIc = VU->VI[vireg];
125 VU->VI[vireg] = _VI;
126 }
127
128 _vu1ExecLower(VU, ptr);
129
130 if (vfreg) {
131 VU->VF[vfreg] = _VFc;
132 }
133 if (vireg) {
134 VU->VI[vireg] = _VIc;
135 }
136 }
137 }
138 _vuAddUpperStalls(VU, &uregs);
139 _vuAddLowerStalls(VU, &lregs);
140
141 _vuTestPipes(VU);
142
143 if (VU->branch > 0) {
144 if (VU->branch-- == 1) {
145 VU->VI[REG_TPC].UL = VU->branchpc;
146 }
147 }
148
149 if( VU->ebit > 0 ) {
150 if( VU->ebit-- == 1 ) {
151 _vuFlushAll(VU);
152 VU0.VI[REG_VPU_STAT].UL &= ~0x100;
153 vif1Regs.stat.VEW = false;
154 }
155 }
156 }
157
158 void vu1Exec(VURegs* VU)
159 {
160 _vu1Exec(VU);
161 VU->cycle++;
162
163 if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n");
164 if (VU->VF[0].f.x != 0.0f) DbgCon.Error("VF[0].x != 0.0!!!!\n");
165 if (VU->VF[0].f.y != 0.0f) DbgCon.Error("VF[0].y != 0.0!!!!\n");
166 if (VU->VF[0].f.z != 0.0f) DbgCon.Error("VF[0].z != 0.0!!!!\n");
167 if (VU->VF[0].f.w != 1.0f) DbgCon.Error("VF[0].w != 1.0!!!!\n");
168 }
169
170 InterpVU1::InterpVU1()
171 {
172 m_Idx = 1;
173 IsInterpreter = true;
174 }
175
176 void InterpVU1::Step()
177 {
178 VU1.VI[REG_TPC].UL &= VU1_PROGMASK;
179 vu1Exec( &VU1 );
180 }
181
182 void InterpVU1::Execute(u32 cycles)
183 {
184 for (int i = (int)cycles; i > 0 ; i--) {
185 if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) {
186 if (VU1.branch || VU1.ebit) {
187 Step(); // run branch delay slot?
188 }
189 break;
190 }
191 Step();
192 }
193 }
194

  ViewVC Help
Powered by ViewVC 1.1.22