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

Annotation of /trunk/pcsx2/VU0.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (hide annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 5 months ago) by william
File size: 4567 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
1 william 31 /* 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 william 62 __fi void _vu0run(bool breakOnMbit, bool addCycles) {
62 william 31
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 william 62 memRead128(addr, VU0.VF[_Ft_].UQ);
90 william 31 } else {
91 william 62 u128 val;
92     memRead128(addr, val);
93 william 31 }
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 william 62 memWrite128(addr, VU0.VF[_Ft_].UQ);
102 william 31 }
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