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

Contents of /trunk/pcsx2/HwRead.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 191 - (show annotations) (download)
Mon Sep 20 05:35:51 2010 UTC (9 years, 5 months ago) by william
File size: 8279 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.3795 local: v0.9.7.186-latest) 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 #include "Hardware.h"
20
21 #include "ps2/HwInternal.h"
22 #include "ps2/eeHwTraceLog.inl"
23
24 using namespace R5900;
25
26 static __fi void IntCHackCheck()
27 {
28 // Sanity check: To protect from accidentally "rewinding" the cyclecount
29 // on the few times nextBranchCycle can be behind our current cycle.
30 s32 diff = g_nextEventCycle - cpuRegs.cycle;
31 if( diff > 0 ) cpuRegs.cycle = g_nextEventCycle;
32 }
33
34 static const uint HwF_VerboseConLog = 1<<0;
35 static const uint HwF_IntcStatHack = 1<<1; // used for Reads only.
36
37 template< uint page > void __fastcall _hwRead128(u32 mem, mem128_t* result );
38
39 template< uint page, bool intcstathack >
40 mem32_t __fastcall _hwRead32(u32 mem)
41 {
42 pxAssume( (mem & 0x03) == 0 );
43
44 switch( page )
45 {
46 case 0x00: return rcntRead32<0x00>( mem );
47 case 0x01: return rcntRead32<0x01>( mem );
48
49 case 0x02: return ipuRead32( mem );
50
51 case 0x03:
52 if (mem >= EEMemoryMap::VIF0_Start)
53 {
54 if(mem >= EEMemoryMap::VIF1_Start)
55 return vifRead32<1>(mem);
56 else
57 return vifRead32<0>(mem);
58 }
59 return dmacRead32<0x03>( mem );
60
61 case 0x04:
62 case 0x05:
63 case 0x06:
64 case 0x07:
65 {
66 // [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery.
67 // No game is known to attempt such a thing (yay!), so probably nothing for us to
68 // worry about. Chances are, though, doing so is "legal" and yields some sort
69 // of reproducible behavior. Candidate for real hardware testing.
70
71 // Current assumption: Reads 128 bits and discards the unused portion.
72
73 DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" );
74
75 u128 out128;
76 _hwRead128<page>(mem & ~0x0f, &out128);
77 return out128._u32[(mem >> 2) & 0x3];
78 }
79 break;
80
81 case 0x0f:
82 {
83 // INTC_STAT shortcut for heavy spinning.
84 // Performance Note: Visual Studio handles this best if we just manually check for it here,
85 // outside the context of the switch statement below. This is likely fixed by PGO also,
86 // but it's an easy enough conditional to account for anyways.
87
88 if (mem == INTC_STAT)
89 {
90 if (intcstathack) IntCHackCheck();
91 return psHu32(INTC_STAT);
92 }
93
94 //if ((mem & 0x1000f200) == 0x1000f200)
95 // Console.Error("SBUS");
96
97 switch( mem )
98 {
99 case SIO_ISR:
100 case SBUS_F260:
101 case 0x1000f410:
102 case MCH_RICM:
103 return 0;
104
105 case SBUS_F240:
106 return psHu32(SBUS_F240) | 0xF0000102;
107
108 case MCH_DRD:
109 if( !((psHu32(MCH_RICM) >> 6) & 0xF) )
110 {
111 switch ((psHu32(MCH_RICM)>>16) & 0xFFF)
112 {
113 //MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
114
115 case 0x21://INIT
116 if(rdram_sdevid < rdram_devices)
117 {
118 rdram_sdevid++;
119 return 0x1F;
120 }
121 return 0;
122
123 case 0x23://CNFGA
124 return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5
125
126 case 0x24://CNFGB
127 //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0
128 return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0
129
130 case 0x40://DEVID
131 return psHu32(MCH_RICM) & 0x1F; // =SDEV
132 }
133 }
134 return 0;
135 }
136 }
137 break;
138 }
139
140 return psHu32(mem);
141 }
142
143 template< uint page >
144 mem32_t __fastcall hwRead32(u32 mem)
145 {
146 mem32_t retval = _hwRead32<page,false>(mem);
147 eeHwTraceLog( mem, retval, true );
148 return retval;
149 }
150
151 mem32_t __fastcall hwRead32_page_0F_INTC_HACK(u32 mem)
152 {
153 mem32_t retval = _hwRead32<0x0f,true>(mem);
154 eeHwTraceLog( mem, retval, true );
155 return retval;
156 }
157
158 // --------------------------------------------------------------------------------------
159 // hwRead8 / hwRead16 / hwRead64 / hwRead128
160 // --------------------------------------------------------------------------------------
161
162 template< uint page >
163 mem8_t __fastcall _hwRead8(u32 mem)
164 {
165 u32 ret32 = _hwRead32<page, false>(mem & ~0x03);
166 return ((u8*)&ret32)[mem & 0x03];
167 }
168
169 template< uint page >
170 mem8_t __fastcall hwRead8(u32 mem)
171 {
172 mem8_t ret8 = _hwRead8<0x0f>(mem);
173 eeHwTraceLog( mem, ret8, true );
174 return ret8;
175 }
176
177 template< uint page >
178 mem16_t __fastcall _hwRead16(u32 mem)
179 {
180 pxAssume( (mem & 0x01) == 0 );
181
182 u32 ret32 = _hwRead32<page, false>(mem & ~0x03);
183 return ((u16*)&ret32)[(mem>>1) & 0x01];
184 }
185
186 template< uint page >
187 mem16_t __fastcall hwRead16(u32 mem)
188 {
189 u16 ret16 = _hwRead16<page>(mem);
190 eeHwTraceLog( mem, ret16, true );
191 return ret16;
192 }
193
194 mem16_t __fastcall hwRead16_page_0F_INTC_HACK(u32 mem)
195 {
196 pxAssume( (mem & 0x01) == 0 );
197
198 u32 ret32 = _hwRead32<0x0f, true>(mem & ~0x03);
199 u16 ret16 = ((u16*)&ret32)[(mem>>1) & 0x01];
200
201 eeHwTraceLog( mem, ret16, "Read" );
202 return ret16;
203 }
204
205 template< uint page >
206 static void _hwRead64(u32 mem, mem64_t* result )
207 {
208 pxAssume( (mem & 0x07) == 0 );
209
210 switch (page)
211 {
212 case 0x02:
213 *result = ipuRead64(mem);
214 return;
215
216 case 0x04:
217 case 0x05:
218 case 0x06:
219 case 0x07:
220 {
221 // [Ps2Confirm] Reading from FIFOs using non-128 bit reads is a complete mystery.
222 // No game is known to attempt such a thing (yay!), so probably nothing for us to
223 // worry about. Chances are, though, doing so is "legal" and yields some sort
224 // of reproducible behavior. Candidate for real hardware testing.
225
226 // Current assumption: Reads 128 bits and discards the unused portion.
227
228 uint wordpart = (mem >> 3) & 0x1;
229 DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" );
230
231 u128 out128;
232 _hwRead128<page>(mem & ~0x0f, &out128);
233 *result = out128._u64[wordpart];
234 }
235 return;
236 }
237
238 *result = _hwRead32<page,false>( mem );
239 }
240
241 template< uint page >
242 void __fastcall hwRead64(u32 mem, mem64_t* result )
243 {
244 _hwRead64<page>( mem, result );
245 eeHwTraceLog( mem, *result, true );
246 }
247
248 template< uint page >
249 void __fastcall _hwRead128(u32 mem, mem128_t* result )
250 {
251 pxAssume( (mem & 0x0f) == 0 );
252
253 // FIFOs are the only "legal" 128 bit registers, so we Handle them first.
254 // All other registers fall back on the 64-bit handler (and from there
255 // all non-IPU reads fall back to the 32-bit handler).
256
257 switch (page)
258 {
259 case 0x05:
260 ReadFIFO_VIF1( result );
261 break;
262
263 case 0x07:
264 if (mem & 0x10)
265 ZeroQWC( result ); // IPUin is write-only
266 else
267 ReadFIFO_IPUout( result );
268 break;
269
270 case 0x04:
271 case 0x06:
272 // VIF0 and GIF are write-only.
273 // [Ps2Confirm] Reads from these FIFOs (and IPUin) do one of the following:
274 // return zero, leave contents of the dest register unchanged, or in some
275 // indeterminate state. The actual behavior probably isn't important.
276 ZeroQWC( result );
277 break;
278
279 default:
280 _hwRead64<page>( mem, &result->lo );
281 result->hi = 0;
282 break;
283 }
284 }
285
286 template< uint page >
287 void __fastcall hwRead128(u32 mem, mem128_t* result )
288 {
289 _hwRead128<page>( mem, result );
290 eeHwTraceLog( mem, *result, true );
291 }
292
293 #define InstantizeHwRead(pageidx) \
294 template mem8_t __fastcall hwRead8<pageidx>(u32 mem); \
295 template mem16_t __fastcall hwRead16<pageidx>(u32 mem); \
296 template mem32_t __fastcall hwRead32<pageidx>(u32 mem); \
297 template void __fastcall hwRead64<pageidx>(u32 mem, mem64_t* result ); \
298 template void __fastcall hwRead128<pageidx>(u32 mem, mem128_t* result ); \
299 template mem32_t __fastcall _hwRead32<pageidx, false>(u32 mem);
300
301 InstantizeHwRead(0x00); InstantizeHwRead(0x08);
302 InstantizeHwRead(0x01); InstantizeHwRead(0x09);
303 InstantizeHwRead(0x02); InstantizeHwRead(0x0a);
304 InstantizeHwRead(0x03); InstantizeHwRead(0x0b);
305 InstantizeHwRead(0x04); InstantizeHwRead(0x0c);
306 InstantizeHwRead(0x05); InstantizeHwRead(0x0d);
307 InstantizeHwRead(0x06); InstantizeHwRead(0x0e);
308 InstantizeHwRead(0x07); InstantizeHwRead(0x0f);

  ViewVC Help
Powered by ViewVC 1.1.22