/[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 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 11 months ago) by william
File size: 4567 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 /* 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 void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();}
48 void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();}
49
50 void COP2_SPECIAL2() {
51 Int_COP2SPECIAL2PrintTable[(cpuRegs.code & 0x3) | ((cpuRegs.code >> 4) & 0x7c)]();
52 }
53
54 void COP2_Unknown()
55 {
56 CPU_LOG("Unknown COP2 opcode called");
57 }
58
59 //****************************************************************************
60
61 __fi void _vu0run(bool breakOnMbit, bool addCycles) {
62
63 if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
64
65 int startcycle = VU0.cycle;
66 u32 runCycles = breakOnMbit ? vu0RunCycles : 0x7fffffff;
67 VU0.flags &= ~VUFLAG_MFLAGSET;
68
69 do { // Run VU until it finishes or M-Bit
70 CpuVU0->Execute(runCycles);
71 } while ((VU0.VI[REG_VPU_STAT].UL & 1) // E-bit Termination
72 && (!breakOnMbit || !(VU0.flags & VUFLAG_MFLAGSET))); // M-bit Break
73
74 // Add cycles if called from EE's COP2
75 if (addCycles) cpuRegs.cycle += (VU0.cycle-startcycle)*2;
76 }
77
78 void _vu0WaitMicro() { _vu0run(1, 1); } // Runs VU0 Micro Until E-bit or M-Bit End
79 void _vu0FinishMicro() { _vu0run(0, 1); } // Runs VU0 Micro Until E-Bit End
80 void vu0Finish() { _vu0run(0, 0); } // Runs VU0 Micro Until E-Bit End (doesn't stall EE)
81
82 namespace R5900 {
83 namespace Interpreter{
84 namespace OpcodeImpl
85 {
86 void LQC2() {
87 u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
88 if (_Ft_) {
89 memRead128(addr, VU0.VF[_Ft_].UQ);
90 } else {
91 u128 val;
92 memRead128(addr, val);
93 }
94 }
95
96 // Asadr.Changed
97 //TODO: check this
98 // HUH why ? doesn't make any sense ...
99 void SQC2() {
100 u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
101 memWrite128(addr, VU0.VF[_Ft_].UQ);
102 }
103 }}}
104
105
106 void QMFC2() {
107 if (cpuRegs.code & 1) {
108 _vu0WaitMicro();
109 }
110 if (_Rt_ == 0) return;
111 cpuRegs.GPR.r[_Rt_].UD[0] = VU0.VF[_Fs_].UD[0];
112 cpuRegs.GPR.r[_Rt_].UD[1] = VU0.VF[_Fs_].UD[1];
113 }
114
115 void QMTC2() {
116 if (cpuRegs.code & 1) {
117 _vu0WaitMicro();
118 }
119 if (_Fs_ == 0) return;
120 VU0.VF[_Fs_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0];
121 VU0.VF[_Fs_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1];
122 }
123
124 void CFC2() {
125 if (cpuRegs.code & 1) {
126 _vu0WaitMicro();
127 }
128 if (_Rt_ == 0) return;
129 cpuRegs.GPR.r[_Rt_].UL[0] = VU0.VI[_Fs_].UL;
130 if(VU0.VI[_Fs_].UL & 0x80000000)
131 cpuRegs.GPR.r[_Rt_].UL[1] = 0xffffffff;
132 else
133 cpuRegs.GPR.r[_Rt_].UL[1] = 0;
134 }
135
136 void CTC2() {
137 if (cpuRegs.code & 1) {
138 _vu0WaitMicro();
139 }
140 if (_Fs_ == 0) return;
141
142 switch(_Fs_) {
143 case REG_MAC_FLAG: // read-only
144 case REG_TPC: // read-only
145 case REG_VPU_STAT: // read-only
146 break;
147 case REG_FBRST:
148 VU0.VI[REG_FBRST].UL = cpuRegs.GPR.r[_Rt_].UL[0] & 0x0C0C;
149 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x1) { // VU0 Force Break
150 Console.Error("fixme: VU0 Force Break");
151 }
152 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x2) { // VU0 Reset
153 //Console.WriteLn("fixme: VU0 Reset");
154 vu0ResetRegs();
155 }
156 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x100) { // VU1 Force Break
157 Console.Error("fixme: VU1 Force Break");
158 }
159 if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x200) { // VU1 Reset
160 // Console.WriteLn("fixme: VU1 Reset");
161 vu1ResetRegs();
162 }
163 break;
164 case REG_CMSAR1: // REG_CMSAR1
165 if (!(VU0.VI[REG_VPU_STAT].UL & 0x100) ) {
166 vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0]); // Execute VU1 Micro SubRoutine
167 }
168 break;
169 default:
170 VU0.VI[_Fs_].UL = cpuRegs.GPR.r[_Rt_].UL[0];
171 break;
172 }
173 }

  ViewVC Help
Powered by ViewVC 1.1.22