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

Contents of /trunk/pcsx2/HwWrite.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 4 months ago) by william
File size: 10145 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 #include "Hardware.h"
20
21 #include "ps2/HwInternal.h"
22 #include "ps2/eeHwTraceLog.inl"
23
24 using namespace R5900;
25
26 // Shift the middle 8 bits (bits 4-12) into the lower 8 bits.
27 // This helps the compiler optimize the switch statement into a lookup table. :)
28
29 #define HELPSWITCH(m) (((m)>>4) & 0xff)
30 #define mcase(src) case HELPSWITCH(src)
31
32 template< uint page > void __fastcall _hwWrite8(u32 mem, u8 value);
33 template< uint page > void __fastcall _hwWrite16(u32 mem, u8 value);
34 template< uint page > void __fastcall _hwWrite128(u32 mem, u8 value);
35
36
37 template<uint page>
38 void __fastcall _hwWrite32( u32 mem, u32 value )
39 {
40 pxAssume( (mem & 0x03) == 0 );
41
42 // Notes:
43 // All unknown registers on the EE are "reserved" as discarded writes and indeterminate
44 // reads. Bus error is only generated for registers outside the first 16k of mapped
45 // register space (which is handled by the VTLB mapping, so no need for checks here).
46
47 switch (page)
48 {
49 case 0x00: if (!rcntWrite32<0x00>(mem, value)) return; break;
50 case 0x01: if (!rcntWrite32<0x01>(mem, value)) return; break;
51
52 case 0x02:
53 if (!ipuWrite32(mem, value)) return;
54 break;
55
56 case 0x04:
57 case 0x05:
58 case 0x06:
59 case 0x07:
60 {
61 // [Ps2Confirm] Direct FIFO read/write behavior. We need to create a test that writes
62 // data to one of the FIFOs and determine the result. I'm not quite sure offhand a good
63 // way to do that --air
64 // Current assumption is that 32-bit and 64-bit writes likely do 128-bit zero-filled
65 // writes (upper 96 bits are 0, lower 32 bits are effective).
66
67 u128 zerofill = u128::From32(0);
68 zerofill._u32[(mem >> 2) & 0x03] = value;
69
70 DevCon.WriteLn( Color_Cyan, "Writing 32-bit FIFO data (zero-extended to 128 bits)" );
71 _hwWrite128<page>(mem & ~0x0f, &zerofill);
72 }
73 return;
74
75 case 0x03:
76 if (mem >= EEMemoryMap::VIF0_Start)
77 {
78 if(mem >= EEMemoryMap::VIF1_Start)
79 {
80 if (!vifWrite32<1>(mem, value)) return;
81 }
82 else
83 {
84 if (!vifWrite32<0>(mem, value)) return;
85 }
86 }
87 else iswitch(mem)
88 {
89 icase(GIF_CTRL)
90 {
91 psHu32(mem) = value & 0x8;
92
93 if (value & 0x1)
94 gsGIFReset();
95
96 if (value & 8)
97 gifRegs.stat.PSE = true;
98 else
99 gifRegs.stat.PSE = false;
100
101 return;
102 }
103
104 icase(GIF_MODE)
105 {
106 // need to set GIF_MODE (hamster ball)
107 gifRegs.mode.write(value);
108
109 // set/clear bits 0 and 2 as per the GIF_MODE value.
110 const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT;
111 psHu32(GIF_STAT) &= ~bitmask;
112 psHu32(GIF_STAT) |= (u32)value & bitmask;
113
114 return;
115 }
116 }
117 break;
118
119 case 0x08:
120 case 0x09:
121 case 0x0a:
122 case 0x0b:
123 case 0x0c:
124 case 0x0d:
125 case 0x0e:
126 if (!dmacWrite32<page>(mem, value)) return;
127 break;
128
129 case 0x0f:
130 {
131 switch( HELPSWITCH(mem) )
132 {
133 mcase(INTC_STAT):
134 psHu32(INTC_STAT) &= ~value;
135 //cpuTestINTCInts();
136 return;
137
138 mcase(INTC_MASK):
139 psHu32(INTC_MASK) ^= (u16)value;
140 cpuTestINTCInts();
141 return;
142
143 mcase(SIO_TXFIFO):
144 {
145 u8* woot = (u8*)&value;
146 // [Ps2Confirm] What happens when we write 32 bit values to SIO_TXFIFO?
147 // If it works like the IOP, then all 32 bits are written to the FIFO in
148 // order. PCSX2 up to this point simply ignored non-8bit writes to this port.
149 _hwWrite8<0x0f>(SIO_TXFIFO, woot[0]);
150 _hwWrite8<0x0f>(SIO_TXFIFO, woot[1]);
151 _hwWrite8<0x0f>(SIO_TXFIFO, woot[2]);
152 _hwWrite8<0x0f>(SIO_TXFIFO, woot[3]);
153 }
154 return;
155
156 mcase(SBUS_F200):
157 // Performs a standard psHu32 assignment (which is the default action anyway).
158 //psHu32(mem) = value;
159 break;
160
161 mcase(SBUS_F220):
162 psHu32(mem) |= value;
163 return;
164
165 mcase(SBUS_F230):
166 psHu32(mem) &= ~value;
167 return;
168
169 mcase(SBUS_F240):
170 if(!(value & 0x100))
171 psHu32(mem) &= ~0x100;
172 else
173 psHu32(mem) |= 0x100;
174 return;
175
176 mcase(SBUS_F260):
177 psHu32(mem) = 0;
178 return;
179
180 mcase(MCH_RICM)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
181 if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0
182 rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid
183 psHu32(mem) = value & ~0x80000000; //kill the busy bit
184 return;
185
186 mcase(MCH_DRD):
187 // Performs a standard psHu32 assignment (which is the default action anyway).
188 //psHu32(mem) = value;
189 break;
190
191 mcase(DMAC_ENABLEW):
192 if (!dmacWrite32<0x0f>(DMAC_ENABLEW, value)) return;
193
194 //mcase(SIO_ISR):
195 //mcase(0x1000f410):
196 // Mystery Regs! No one knows!?
197 // (unhandled so fall through to default)
198
199 }
200 }
201 break;
202 }
203
204 psHu32(mem) = value;
205 }
206
207 template<uint page>
208 void __fastcall hwWrite32( u32 mem, u32 value )
209 {
210 eeHwTraceLog( mem, value, false );
211 _hwWrite32<page>( mem, value );
212 }
213
214 // --------------------------------------------------------------------------------------
215 // hwWrite8 / hwWrite16 / hwWrite64 / hwWrite128
216 // --------------------------------------------------------------------------------------
217
218 template< uint page >
219 void __fastcall _hwWrite8(u32 mem, u8 value)
220 {
221 iswitch (mem)
222 icase(SIO_TXFIFO)
223 {
224 static bool iggy_newline = false;
225 static char sio_buffer[1024];
226 static int sio_count;
227
228 if (value == '\r')
229 {
230 iggy_newline = true;
231 sio_buffer[sio_count++] = '\n';
232 }
233 else if (!iggy_newline || (value != '\n'))
234 {
235 iggy_newline = false;
236 sio_buffer[sio_count++] = value;
237 }
238
239 if ((sio_count == ArraySize(sio_buffer)-1) || (sio_buffer[sio_count-1] == '\n'))
240 {
241 sio_buffer[sio_count] = 0;
242 eeConLog( ShiftJIS_ConvertString(sio_buffer) );
243 sio_count = 0;
244 }
245 return;
246 }
247
248 u32 merged = _hwRead32<page,false>(mem & ~0x03);
249 ((u8*)&merged)[mem & 0x3] = value;
250
251 _hwWrite32<page>(mem & ~0x03, merged);
252 }
253
254 template< uint page >
255 void __fastcall hwWrite8(u32 mem, u8 value)
256 {
257 eeHwTraceLog( mem, value, false );
258 _hwWrite8<page>(mem, value);
259 }
260
261 template< uint page >
262 void __fastcall _hwWrite16(u32 mem, u16 value)
263 {
264 pxAssume( (mem & 0x01) == 0 );
265
266 u32 merged = _hwRead32<page,false>(mem & ~0x03);
267 ((u16*)&merged)[(mem>>1) & 0x1] = value;
268
269 hwWrite32<page>(mem & ~0x03, merged);
270 }
271
272 template< uint page >
273 void __fastcall hwWrite16(u32 mem, u16 value)
274 {
275 eeHwTraceLog( mem, value, false );
276 _hwWrite16<page>(mem, value);
277 }
278
279 template<uint page>
280 void __fastcall _hwWrite64( u32 mem, const mem64_t* srcval )
281 {
282 pxAssume( (mem & 0x07) == 0 );
283
284 // * Only the IPU has true 64 bit registers.
285 // * FIFOs have 128 bit registers that are probably zero-fill.
286 // * All other registers likely disregard the upper 32-bits and simply act as normal
287 // 32-bit writes.
288
289 switch (page)
290 {
291 case 0x02:
292 if (!ipuWrite64(mem, *srcval)) return;
293 break;
294
295 case 0x04:
296 case 0x05:
297 case 0x06:
298 case 0x07:
299 {
300 DevCon.WriteLn( Color_Cyan, "Writing 64-bit FIFO data (zero-extended to 128 bits)" );
301
302 u128 zerofill = u128::From32(0);
303 zerofill._u64[(mem >> 3) & 0x01] = *srcval;
304 hwWrite128<page>(mem & ~0x0f, &zerofill);
305 }
306 return;
307
308 default:
309 // disregard everything except the lower 32 bits.
310 // ... and skip the 64 bit writeback since the 32-bit one will suffice.
311 hwWrite32<page>( mem, ((u32*)srcval)[0] );
312 return;
313 }
314
315 psHu64(mem) = *srcval;
316 }
317
318 template<uint page>
319 void __fastcall hwWrite64( u32 mem, const mem64_t* srcval )
320 {
321 eeHwTraceLog( mem, *srcval, false );
322 _hwWrite64<page>(mem, srcval);
323 }
324
325 template< uint page >
326 void __fastcall _hwWrite128(u32 mem, const mem128_t* srcval)
327 {
328 pxAssume( (mem & 0x0f) == 0 );
329
330 // FIFOs are the only "legal" 128 bit registers. Handle them first.
331 // all other registers fall back on the 64-bit handler (and from there
332 // most of them fall back to the 32-bit handler).
333
334 switch (page)
335 {
336 case 0x04:
337 WriteFIFO_VIF0(srcval);
338 return;
339
340 case 0x05:
341 WriteFIFO_VIF1(srcval);
342 return;
343
344 case 0x06:
345 WriteFIFO_GIF(srcval);
346 return;
347
348 case 0x07:
349 if (mem & 0x10)
350 {
351 WriteFIFO_IPUin(srcval);
352 }
353 else
354 {
355 // [Ps2Confirm] Most likely writes to IPUout will be silently discarded. A test
356 // to confirm such would be easy -- just dump some data to FIFO_IPUout and see
357 // if the program causes BUSERR or something on the PS2.
358
359 //WriteFIFO_IPUout(srcval);
360 }
361
362 return;
363 }
364
365 // All upper bits of all non-FIFO 128-bit HW writes are almost certainly disregarded. --air
366 hwWrite64<page>(mem, (mem64_t*)srcval);
367
368 //CopyQWC(&psHu128(mem), srcval);
369 }
370
371 template< uint page >
372 void __fastcall hwWrite128(u32 mem, const mem128_t* srcval)
373 {
374 eeHwTraceLog( mem, *srcval, false );
375 _hwWrite128<page>(mem, srcval);
376 }
377
378 #define InstantizeHwWrite(pageidx) \
379 template void __fastcall hwWrite8<pageidx>(u32 mem, mem8_t value); \
380 template void __fastcall hwWrite16<pageidx>(u32 mem, mem16_t value); \
381 template void __fastcall hwWrite32<pageidx>(u32 mem, mem32_t value); \
382 template void __fastcall hwWrite64<pageidx>(u32 mem, const mem64_t* srcval); \
383 template void __fastcall hwWrite128<pageidx>(u32 mem, const mem128_t* srcval);
384
385 InstantizeHwWrite(0x00); InstantizeHwWrite(0x08);
386 InstantizeHwWrite(0x01); InstantizeHwWrite(0x09);
387 InstantizeHwWrite(0x02); InstantizeHwWrite(0x0a);
388 InstantizeHwWrite(0x03); InstantizeHwWrite(0x0b);
389 InstantizeHwWrite(0x04); InstantizeHwWrite(0x0c);
390 InstantizeHwWrite(0x05); InstantizeHwWrite(0x0d);
391 InstantizeHwWrite(0x06); InstantizeHwWrite(0x0e);
392 InstantizeHwWrite(0x07); InstantizeHwWrite(0x0f);

  ViewVC Help
Powered by ViewVC 1.1.22