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

Annotation of /trunk/pcsx2/HwWrite.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (hide annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (10 years, 2 months ago) by william
File size: 10145 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     #include "PrecompiledHeader.h"
18     #include "Common.h"
19     #include "Hardware.h"
20    
21 william 62 #include "ps2/HwInternal.h"
22     #include "ps2/eeHwTraceLog.inl"
23    
24 william 31 using namespace R5900;
25    
26 william 62 // 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 william 31
29 william 62 #define HELPSWITCH(m) (((m)>>4) & 0xff)
30     #define mcase(src) case HELPSWITCH(src)
31 william 31
32 william 62 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 william 31
36    
37 william 62 template<uint page>
38     void __fastcall _hwWrite32( u32 mem, u32 value )
39 william 31 {
40 william 62 pxAssume( (mem & 0x03) == 0 );
41 william 31
42 william 62 // 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 william 31
47 william 62 switch (page)
48 william 31 {
49 william 62 case 0x00: if (!rcntWrite32<0x00>(mem, value)) return; break;
50     case 0x01: if (!rcntWrite32<0x01>(mem, value)) return; break;
51 william 31
52 william 62 case 0x02:
53     if (!ipuWrite32(mem, value)) return;
54     break;
55 william 31
56 william 62 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 william 31
67 william 62 u128 zerofill = u128::From32(0);
68     zerofill._u32[(mem >> 2) & 0x03] = value;
69 william 31
70 william 62 DevCon.WriteLn( Color_Cyan, "Writing 32-bit FIFO data (zero-extended to 128 bits)" );
71     _hwWrite128<page>(mem & ~0x0f, &zerofill);
72 william 31 }
73 william 62 return;
74 william 31
75 william 62 case 0x03:
76     if (mem >= EEMemoryMap::VIF0_Start)
77 william 31 {
78 william 62 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 william 31 }
87 william 62 else iswitch(mem)
88 william 31 {
89 william 62 icase(GIF_CTRL)
90     {
91     psHu32(mem) = value & 0x8;
92 william 31
93 william 62 if (value & 0x1)
94     gsGIFReset();
95 william 31
96 william 62 if (value & 8)
97     gifRegs.stat.PSE = true;
98     else
99     gifRegs.stat.PSE = false;
100 william 31
101 william 62 return;
102     }
103 william 31
104 william 62 icase(GIF_MODE)
105     {
106     // need to set GIF_MODE (hamster ball)
107     gifRegs.mode.write(value);
108 william 31
109 william 62 // 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 william 31
114 william 62 return;
115     }
116 william 31 }
117     break;
118    
119 william 62 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 william 31 {
133 william 62 mcase(INTC_STAT):
134     psHu32(INTC_STAT) &= ~value;
135     //cpuTestINTCInts();
136     return;
137 william 31
138 william 62 mcase(INTC_MASK):
139     psHu32(INTC_MASK) ^= (u16)value;
140     cpuTestINTCInts();
141     return;
142 william 31
143 william 62 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 william 31
156 william 62 mcase(SBUS_F200):
157     // Performs a standard psHu32 assignment (which is the default action anyway).
158     //psHu32(mem) = value;
159     break;
160 william 31
161 william 62 mcase(SBUS_F220):
162     psHu32(mem) |= value;
163     return;
164 william 31
165 william 62 mcase(SBUS_F230):
166     psHu32(mem) &= ~value;
167     return;
168 william 31
169 william 62 mcase(SBUS_F240):
170     if(!(value & 0x100))
171     psHu32(mem) &= ~0x100;
172     else
173     psHu32(mem) |= 0x100;
174     return;
175 william 31
176 william 62 mcase(SBUS_F260):
177     psHu32(mem) = 0;
178     return;
179 william 31
180 william 62 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 william 31
186 william 62 mcase(MCH_DRD):
187     // Performs a standard psHu32 assignment (which is the default action anyway).
188     //psHu32(mem) = value;
189     break;
190 william 31
191 william 62 mcase(DMAC_ENABLEW):
192     if (!dmacWrite32<0x0f>(DMAC_ENABLEW, value)) return;
193 william 31
194 william 62 //mcase(SIO_ISR):
195     //mcase(0x1000f410):
196     // Mystery Regs! No one knows!?
197     // (unhandled so fall through to default)
198 william 31
199     }
200 william 62 }
201     break;
202 william 31 }
203 william 62
204     psHu32(mem) = value;
205 william 31 }
206    
207 william 62 template<uint page>
208     void __fastcall hwWrite32( u32 mem, u32 value )
209 william 31 {
210 william 62 eeHwTraceLog( mem, value, false );
211     _hwWrite32<page>( mem, value );
212 william 31 }
213    
214 william 62 // --------------------------------------------------------------------------------------
215     // hwWrite8 / hwWrite16 / hwWrite64 / hwWrite128
216     // --------------------------------------------------------------------------------------
217 william 31
218 william 62 template< uint page >
219     void __fastcall _hwWrite8(u32 mem, u8 value)
220 william 31 {
221 william 62 iswitch (mem)
222     icase(SIO_TXFIFO)
223 william 31 {
224 william 62 static bool iggy_newline = false;
225     static char sio_buffer[1024];
226     static int sio_count;
227 william 31
228 william 62 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 william 31
239 william 62 if ((sio_count == ArraySize(sio_buffer)-1) || (sio_buffer[sio_count-1] == '\n'))
240 william 31 {
241 william 62 sio_buffer[sio_count] = 0;
242     eeConLog( ShiftJIS_ConvertString(sio_buffer) );
243     sio_count = 0;
244 william 31 }
245 william 62 return;
246     }
247 william 31
248 william 62 u32 merged = _hwRead32<page,false>(mem & ~0x03);
249     ((u8*)&merged)[mem & 0x3] = value;
250 william 31
251 william 62 _hwWrite32<page>(mem & ~0x03, merged);
252 william 31 }
253    
254 william 62 template< uint page >
255     void __fastcall hwWrite8(u32 mem, u8 value)
256 william 31 {
257 william 62 eeHwTraceLog( mem, value, false );
258     _hwWrite8<page>(mem, value);
259     }
260 william 31
261 william 62 template< uint page >
262     void __fastcall _hwWrite16(u32 mem, u16 value)
263     {
264     pxAssume( (mem & 0x01) == 0 );
265 william 31
266 william 62 u32 merged = _hwRead32<page,false>(mem & ~0x03);
267     ((u16*)&merged)[(mem>>1) & 0x1] = value;
268 william 31
269 william 62 hwWrite32<page>(mem & ~0x03, merged);
270 william 31 }
271    
272 william 62 template< uint page >
273     void __fastcall hwWrite16(u32 mem, u16 value)
274 william 31 {
275 william 62 eeHwTraceLog( mem, value, false );
276     _hwWrite16<page>(mem, value);
277 william 31 }
278    
279 william 62 template<uint page>
280     void __fastcall _hwWrite64( u32 mem, const mem64_t* srcval )
281 william 31 {
282 william 62 pxAssume( (mem & 0x07) == 0 );
283 william 31
284 william 62 // * 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 william 31
289 william 62 switch (page)
290 william 31 {
291 william 62 case 0x02:
292     if (!ipuWrite64(mem, *srcval)) return;
293     break;
294 william 31
295 william 62 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 william 31
302 william 62 u128 zerofill = u128::From32(0);
303     zerofill._u64[(mem >> 3) & 0x01] = *srcval;
304     hwWrite128<page>(mem & ~0x0f, &zerofill);
305     }
306     return;
307    
308 william 31 default:
309 william 62 // 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 william 31 }
314    
315     psHu64(mem) = *srcval;
316     }
317    
318 william 62 template<uint page>
319     void __fastcall hwWrite64( u32 mem, const mem64_t* srcval )
320 william 31 {
321 william 62 eeHwTraceLog( mem, *srcval, false );
322     _hwWrite64<page>(mem, srcval);
323 william 31 }
324    
325 william 62 template< uint page >
326     void __fastcall _hwWrite128(u32 mem, const mem128_t* srcval)
327 william 31 {
328 william 62 pxAssume( (mem & 0x0f) == 0 );
329 william 31
330 william 62 // 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 william 31
334 william 62 switch (page)
335 william 31 {
336 william 62 case 0x04:
337     WriteFIFO_VIF0(srcval);
338 william 31 return;
339    
340 william 62 case 0x05:
341     WriteFIFO_VIF1(srcval);
342     return;
343 william 31
344 william 62 case 0x06:
345     WriteFIFO_GIF(srcval);
346     return;
347 william 31
348 william 62 case 0x07:
349     if (mem & 0x10)
350 william 31 {
351 william 62 WriteFIFO_IPUin(srcval);
352 william 31 }
353 william 62 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 william 31
359 william 62 //WriteFIFO_IPUout(srcval);
360     }
361    
362     return;
363     }
364 william 31
365 william 62 // All upper bits of all non-FIFO 128-bit HW writes are almost certainly disregarded. --air
366     hwWrite64<page>(mem, (mem64_t*)srcval);
367 william 31
368 william 62 //CopyQWC(&psHu128(mem), srcval);
369 william 31 }
370    
371 william 62 template< uint page >
372     void __fastcall hwWrite128(u32 mem, const mem128_t* srcval)
373 william 31 {
374 william 62 eeHwTraceLog( mem, *srcval, false );
375     _hwWrite128<page>(mem, srcval);
376 william 31 }
377    
378 william 62 #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 william 31
385 william 62 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