/[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 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 5 months ago) by william
File size: 35309 byte(s)
committing r3113 initial commit again...
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
20 #include "Hardware.h"
21
22 using namespace R5900;
23
24 /////////////////////////////////////////////////////////////////////////
25 // DMA Execution Interfaces
26
27 static bool QuickDmaExec( void (*func)(), u32 mem)
28 {
29 bool ret = false;
30 DMACh *reg = &psH_DMACh(mem);
31
32 if (reg->chcr.STR && dmacRegs->ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
33 {
34 Registers::Freeze();
35 func();
36 Registers::Thaw();
37 ret = true;
38 }
39
40
41 return ret;
42 }
43
44
45 tDMAC_QUEUE QueuedDMA(0);
46 u32 oldvalue = 0;
47
48 void __fastcall StartQueuedDMA()
49 {
50 if (QueuedDMA.VIF0) { DMA_LOG("Resuming DMA for VIF0"); if(QuickDmaExec(dmaVIF0, D0_CHCR) == true) QueuedDMA.VIF0 = false; }
51 if (QueuedDMA.VIF1) { DMA_LOG("Resuming DMA for VIF1"); if(QuickDmaExec(dmaVIF1, D1_CHCR) == true) QueuedDMA.VIF1 = false; }
52 if (QueuedDMA.GIF ) { DMA_LOG("Resuming DMA for GIF" ); if(QuickDmaExec(dmaGIF , D2_CHCR) == true) QueuedDMA.GIF = false; }
53 if (QueuedDMA.IPU0) { DMA_LOG("Resuming DMA for IPU0"); if(QuickDmaExec(dmaIPU0, D3_CHCR) == true) QueuedDMA.IPU0 = false; }
54 if (QueuedDMA.IPU1) { DMA_LOG("Resuming DMA for IPU1"); if(QuickDmaExec(dmaIPU1, D4_CHCR) == true) QueuedDMA.IPU1 = false; }
55 if (QueuedDMA.SIF0) { DMA_LOG("Resuming DMA for SIF0"); if(QuickDmaExec(dmaSIF0, D5_CHCR) == true) QueuedDMA.SIF0 = false; }
56 if (QueuedDMA.SIF1) { DMA_LOG("Resuming DMA for SIF1"); if(QuickDmaExec(dmaSIF1, D6_CHCR) == true) QueuedDMA.SIF1 = false; }
57 if (QueuedDMA.SIF2) { DMA_LOG("Resuming DMA for SIF2"); if(QuickDmaExec(dmaSIF2, D7_CHCR) == true) QueuedDMA.SIF2 = false; }
58 if (QueuedDMA.SPR0) { DMA_LOG("Resuming DMA for SPR0"); if(QuickDmaExec(dmaSPR0, D8_CHCR) == true) QueuedDMA.SPR0 = false; }
59 if (QueuedDMA.SPR1) { DMA_LOG("Resuming DMA for SPR1"); if(QuickDmaExec(dmaSPR1, D9_CHCR) == true) QueuedDMA.SPR1 = false; }
60 }
61
62 // dark cloud2 uses 8 bit DMAs register writes
63 static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value )
64 {
65 DMACh *reg = &psH_DMACh(mem & ~0xf);
66
67 //The only thing we can do in an 8bit write is set the CHCR, so lets just do checks for that
68
69 //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
70 if (reg->chcr.STR)
71 {
72 if(psHu8(DMAC_ENABLER+2) == 1) //DMA is suspended so we can allow writes to anything
73 {
74 //If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue.
75 if(value == 0)
76 {
77 //DevCon.Warning(L"8bit %s DMA Stopped on Suspend", ChcrName(mem & ~0xf));
78 cpuClearInt( ChannelNumber(mem & ~0xf) );
79 QueuedDMA._u16 &= ~(1 << ChannelNumber(mem & ~0xf));
80 }
81 //Here we update the CHCR STR (Busy) bit, we don't touch anything else.
82 reg->chcr.STR = value;
83 return;
84 }
85 else //Else the DMA is running (Not Suspended), so we cant touch it!
86 {
87 //As the manual states "Fields other than STR can only be written to when the DMA is stopped"
88 //Also "The DMA may not stop properly just by writing 0 to STR"
89 //So the presumption is that STR can be written to (ala force stop the DMA) but nothing else
90
91 if(value == 0)
92 {
93 //DevCon.Warning(L"8bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem & ~0xf), reg->chcr._u32, value);
94 reg->chcr.STR = value;
95 //We need to clear any existing DMA loops that are in progress else they will continue!
96 cpuClearInt( ChannelNumber(mem&~0xf) );
97 QueuedDMA._u16 &= ~(1 << ChannelNumber(mem&~0xf)); //Clear any queued DMA requests for this channel
98 }
99 //else DevCon.Warning(L"8bit Attempted to stop %s DMA without suspend, ignoring", ChcrName(mem & ~0xf));
100 return;
101 }
102
103 }
104
105 reg->chcr.STR = value;
106
107 if (reg->chcr.STR && dmacRegs->ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
108 {
109 Registers::Freeze();
110 func();
111 Registers::Thaw();
112 }
113 else if(reg->chcr.STR)
114 {
115 //DevCon.Warning(L"8bit %s DMA Start while DMAC Disabled\n",ChcrName(mem));
116 QueuedDMA._u16 |= (1 << ChannelNumber(mem & ~0xf)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted
117 }
118 }
119
120 static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
121 {
122
123 DMACh *reg = &psH_DMACh(mem);
124 tDMA_CHCR chcr(value);
125
126 //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
127 if (reg->chcr.STR)
128 {
129 if(psHu8(DMAC_ENABLER+2) == 1) //DMA is suspended so we can allow writes to anything
130 {
131 //If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue.
132 if(chcr.STR == 0)
133 {
134 //DevCon.Warning(L"16bit %s DMA Stopped on Suspend", ChcrName(mem));
135 cpuClearInt( ChannelNumber(mem) );
136 QueuedDMA._u16 &= ~(1 << ChannelNumber(mem)); //Clear any queued DMA requests for this channel
137 }
138 //Here we update the lower part of the CHCR, we dont touch the tag as it is only a 16bit value
139 reg->chcr.set((reg->chcr.TAG << 16) | chcr.lower());
140 return;
141 }
142 else //Else the DMA is running (Not Suspended), so we cant touch it!
143 {
144 //As the manual states "Fields other than STR can only be written to when the DMA is stopped"
145 //Also "The DMA may not stop properly just by writing 0 to STR"
146 //So the presumption is that STR can be written to (ala force stop the DMA) but nothing else
147
148 if(chcr.STR == 0)
149 {
150 //DevCon.Warning(L"16bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg->chcr._u32, chcr._u32);
151 reg->chcr.STR = 0;
152 //We need to clear any existing DMA loops that are in progress else they will continue!
153 cpuClearInt( ChannelNumber(mem) );
154 QueuedDMA._u16 &= ~(1 << ChannelNumber(mem)); //Clear any queued DMA requests for this channel
155 }
156 //else DevCon.Warning(L"16bit Attempted to change %s modes while DMA active, ignoring", ChcrName(mem));
157 return;
158 }
159
160 }
161
162 reg->chcr.set((reg->chcr.TAG << 16) | chcr.lower());
163
164 if (reg->chcr.STR && dmacRegs->ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
165 {
166 Registers::Freeze();
167 func();
168 Registers::Thaw();
169 }
170 else if(reg->chcr.STR)
171 {
172 //DevCon.Warning(L"16bit %s DMA Start while DMAC Disabled\n",ChcrName(mem));
173 QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted
174 }
175 }
176
177 static void DmaExec( void (*func)(), u32 mem, u32 value )
178 {
179
180 DMACh *reg = &psH_DMACh(mem);
181 tDMA_CHCR chcr(value);
182
183 //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
184 if (reg->chcr.STR)
185 {
186 if(psHu8(DMAC_ENABLER+2) == 1) //DMA is suspended so we can allow writes to anything
187 {
188 //If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue.
189 if(chcr.STR == 0)
190 {
191 //DevCon.Warning(L"32bit %s DMA Stopped on Suspend", ChcrName(mem));
192 QueuedDMA._u16 &= ~(1 << ChannelNumber(mem)); //Clear any queued DMA requests for this channel
193 cpuClearInt( ChannelNumber(mem) );
194 }
195 //Sanity Check for possible future bug fix0rs ;p
196 //Spams on Persona 4 opening.
197 //if(reg->chcr.TAG != chcr.TAG) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Active", ChcrName(mem), chcr.TAG, reg->chcr.TAG, reg->qwc);
198 //Here we update the LOWER CHCR, if a chain is stopped half way through, it can be manipulated in to a different mode
199 //But we need to preserve the existing tag for now
200 reg->chcr.set((reg->chcr.TAG << 16) | chcr.lower());
201 return;
202 }
203 else //Else the DMA is running (Not Suspended), so we cant touch it!
204 {
205 //As the manual states "Fields other than STR can only be written to when the DMA is stopped"
206 //Also "The DMA may not stop properly just by writing 0 to STR"
207 //So the presumption is that STR can be written to (ala force stop the DMA) but nothing else
208
209 if(chcr.STR == 0)
210 {
211 //DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg->chcr._u32, chcr._u32);
212 reg->chcr.STR = 0;
213 //We need to clear any existing DMA loops that are in progress else they will continue!
214 cpuClearInt( ChannelNumber(mem) );
215 QueuedDMA._u16 &= ~(1 << ChannelNumber(mem)); //Clear any queued DMA requests for this channel
216 }
217 //else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg->chcr._u32, chcr._u32, reg->qwc);
218 return;
219 }
220
221 }
222
223 //if(reg->chcr.TAG != chcr.TAG && chcr.MOD == CHAIN_MODE) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Not Active", ChcrName(mem), chcr.TAG, reg->chcr.TAG, reg->qwc);
224
225 reg->chcr.set(value);
226
227 if (reg->chcr.STR && dmacRegs->ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
228 {
229 Registers::Freeze();
230 func();
231 Registers::Thaw();
232 }
233 else if(reg->chcr.STR)
234 {
235 //DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem));
236 QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted
237 } //else QueuedDMA._u16 &~= (1 << ChannelNumber(mem)); //
238 }
239
240 /////////////////////////////////////////////////////////////////////////
241 // Hardware WRITE 8 bit
242
243 char sio_buffer[1024];
244 int sio_count;
245
246
247 void hwWrite8(u32 mem, u8 value)
248 {
249 if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) {
250 u32 bytemod = mem & 0x3;
251 u32 bitpos = 8 * bytemod;
252 u32 oldval = ~(0xff << bitpos) & psHu32(mem);
253 u32 newval = (value << bitpos) | oldval;
254 if (mem < VIF1_STAT) vif0Write32(mem & ~0x3, newval);
255 else vif1Write32(mem & ~0x3, newval);
256 return;
257 }
258
259 if( mem >= IPU_CMD && mem < D0_CHCR )
260 DevCon.Warning( "hwWrite8 to 0x%x = 0x%x", mem, value );
261
262 switch (mem) {
263 case RCNT0_COUNT: rcntWcount(0, value); break;
264 case RCNT0_MODE: rcntWmode(0, (counters[0].modeval & 0xff00) | value); break;
265 case RCNT0_MODE + 1: rcntWmode(0, (counters[0].modeval & 0xff) | value << 8); break;
266 case RCNT0_TARGET: rcntWtarget(0, value); break;
267 case RCNT0_HOLD: rcntWhold(0, value); break;
268
269 case RCNT1_COUNT: rcntWcount(1, value); break;
270 case RCNT1_MODE: rcntWmode(1, (counters[1].modeval & 0xff00) | value); break;
271 case RCNT1_MODE + 1: rcntWmode(1, (counters[1].modeval & 0xff) | value << 8); break;
272 case RCNT1_TARGET: rcntWtarget(1, value); break;
273 case RCNT1_HOLD: rcntWhold(1, value); break;
274
275 case RCNT2_COUNT: rcntWcount(2, value); break;
276 case RCNT2_MODE: rcntWmode(2, (counters[2].modeval & 0xff00) | value); break;
277 case RCNT2_MODE + 1: rcntWmode(2, (counters[2].modeval & 0xff) | value << 8); break;
278 case RCNT2_TARGET: rcntWtarget(2, value); break;
279
280 case RCNT3_COUNT: rcntWcount(3, value); break;
281 case RCNT3_MODE: rcntWmode(3, (counters[3].modeval & 0xff00) | value); break;
282 case RCNT3_MODE + 1: rcntWmode(3, (counters[3].modeval & 0xff) | value << 8); break;
283 case RCNT3_TARGET: rcntWtarget(3, value); break;
284
285 case SIO_TXFIFO:
286 {
287 // Terminate lines on CR or full buffers, and ignore \n's if the string contents
288 // are empty (otherwise terminate on \n too!)
289 if (( value == '\r' ) || ( sio_count == 1023 ) ||
290 ( value == '\n' && sio_count != 0 ))
291 {
292 // Use "%s" below even though it feels indirect -- it's necessary to avoid
293 // errors if/when games use printf formatting control chars.
294
295 sio_buffer[sio_count] = 0;
296 Console.WriteLn( ConColor_EE, L"%s", ShiftJIS_ConvertString(sio_buffer).c_str() );
297 sio_count = 0;
298 }
299 else if( value != '\n' )
300 {
301 sio_buffer[sio_count++] = value;
302 }
303 }
304 break;
305
306 //case 0x10003c02: //Tony Hawks Project 8 uses this
307 // vif1Write32(mem & ~0x2, value << 16);
308 // break;
309 case D0_CHCR + 1: // dma0 - vif0
310 DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
311 DmaExec8(dmaVIF0, mem, value);
312 break;
313
314 case D1_CHCR + 1: // dma1 - vif1
315 DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
316 DmaExec8(dmaVIF1, mem, value);
317 break;
318
319 case D2_CHCR + 1: // dma2 - gif
320 DMA_LOG("GSdma EXECUTE, value=0x%x", value);
321 DmaExec8(dmaGIF, mem, value);
322 break;
323
324 case D3_CHCR + 1: // dma3 - fromIPU
325 DMA_LOG("IPU0dma EXECUTE, value=0x%x", value);
326 DmaExec8(dmaIPU0, mem, value);
327 break;
328
329 case D4_CHCR + 1: // dma4 - toIPU
330 DMA_LOG("IPU1dma EXECUTE, value=0x%x", value);
331 DmaExec8(dmaIPU1, mem, value);
332 break;
333
334 case D5_CHCR + 1: // dma5 - sif0
335 DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
336 // if (value == 0) psxSu32(0x30) = 0x40000;
337 DmaExec8(dmaSIF0, mem, value);
338 break;
339
340 case D6_CHCR + 1: // dma6 - sif1
341 DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
342 DmaExec8(dmaSIF1, mem, value);
343 break;
344
345 case D7_CHCR + 1: // dma7 - sif2
346 DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
347 DmaExec8(dmaSIF2, mem, value);
348 break;
349
350 case D8_CHCR + 1: // dma8 - fromSPR
351 DMA_LOG("fromSPRdma8 EXECUTE, value=0x%x", value);
352 DmaExec8(dmaSPR0, mem, value);
353 break;
354
355 case D9_CHCR + 1: // dma9 - toSPR
356 DMA_LOG("toSPRdma8 EXECUTE, value=0x%x", value);
357 DmaExec8(dmaSPR1, mem, value);
358 break;
359 case D0_CHCR: // dma0 - vif0
360 case D1_CHCR: // dma1 - vif1
361 case D2_CHCR: // dma2 - gif
362 case D3_CHCR: // dma3 - fromIPU
363 case D4_CHCR: // dma4 - toIPU
364 case D5_CHCR: // dma5 - sif0
365 case D6_CHCR: // dma6 - sif1
366 case D7_CHCR: // dma7 - sif2
367 case D8_CHCR: // dma8 - fromSPR
368 case D9_CHCR: // dma9 - toSPR
369 //DevCon.Warning(L"8bit lower CHCR changed to %x from %x on %s DMA", value, psHu32(mem), ChcrName(mem));
370 psHu8(mem) = value;
371 break;
372
373 case D0_CHCR + 2: // dma0 - vif0
374 case D0_CHCR + 3: // dma0 - vif0
375 case D1_CHCR + 2: // dma1 - vif1
376 case D1_CHCR + 3: // dma1 - vif1
377 case D2_CHCR + 2: // dma2 - gif
378 case D2_CHCR + 3: // dma2 - gif
379 case D3_CHCR + 2: // dma3 - fromIPU
380 case D3_CHCR + 3: // dma3 - fromIPU
381 case D4_CHCR + 2: // dma4 - toIPU
382 case D4_CHCR + 3: // dma4 - toIPU
383 case D5_CHCR + 2: // dma5 - sif0
384 case D5_CHCR + 3: // dma5 - sif0
385 case D6_CHCR + 2: // dma6 - sif1
386 case D6_CHCR + 3: // dma6 - sif1
387 case D7_CHCR + 2: // dma7 - sif2
388 case D7_CHCR + 3: // dma7 - sif2
389 case D8_CHCR + 2: // dma8 - fromSPR
390 case D8_CHCR + 3: // dma8 - fromSPR
391 case D9_CHCR + 2: // dma9 - toSPR
392 case D9_CHCR + 3: // dma9 - toSPR
393 //DevCon.Warning(L"8bit CHCR TAG changed to %x from %x on %s DMA", value, psHu32(mem), ChcrName(mem & ~0xf));
394 psHu8(mem) = value;
395 break;
396
397 case DMAC_ENABLEW + 2:
398 oldvalue = psHu8(DMAC_ENABLEW + 2);
399 psHu8(DMAC_ENABLEW + 2) = value;
400 psHu8(DMAC_ENABLER + 2) = value;
401 if (((oldvalue & 0x1) == 1) && ((value & 0x1) == 0))
402 {
403 if (!QueuedDMA.empty()) StartQueuedDMA();
404 }
405 break;
406
407 case SBUS_F200: // SIF(?)
408 psHu8(mem) = value;
409 break;
410
411 case SBUS_F210:
412 psHu8(mem) = value;
413 break;
414
415 case SBUS_F220:
416 psHu8(mem) = value;
417 break;
418
419 case SBUS_F230:
420 psHu8(mem) = value;
421 break;
422
423 case SBUS_F240:
424 if (!(value & 0x100)) psHu32(mem) &= ~0x100;
425 break;
426
427 case SBUS_F250:
428 psHu8(mem) = value;
429 break;
430
431 case SBUS_F260:
432 psHu8(mem) = value;
433 break;
434
435 default:
436 pxAssert( (mem & 0xff0f) != 0xf200 );
437
438 switch(mem&~3) {
439 case SIO_ISR:
440 case 0x1000f410:
441 case MCH_RICM:
442 break;
443
444 default:
445 psHu8(mem) = value;
446 }
447 HW_LOG("Unknown Hardware write 8 at %x with value %x", mem, value);
448 break;
449 }
450 }
451
452 __forceinline void hwWrite16(u32 mem, u16 value)
453 {
454 if( mem >= IPU_CMD && mem < D0_CHCR )
455 Console.Warning( "hwWrite16 to %x", mem );
456
457 switch(mem)
458 {
459 case RCNT0_COUNT: rcntWcount(0, value); break;
460 case RCNT0_MODE: rcntWmode(0, value); break;
461 case RCNT0_TARGET: rcntWtarget(0, value); break;
462 case RCNT0_HOLD: rcntWhold(0, value); break;
463
464 case RCNT1_COUNT: rcntWcount(1, value); break;
465 case RCNT1_MODE: rcntWmode(1, value); break;
466 case RCNT1_TARGET: rcntWtarget(1, value); break;
467 case RCNT1_HOLD: rcntWhold(1, value); break;
468
469 case RCNT2_COUNT: rcntWcount(2, value); break;
470 case RCNT2_MODE: rcntWmode(2, value); break;
471 case RCNT2_TARGET: rcntWtarget(2, value); break;
472
473 case RCNT3_COUNT: rcntWcount(3, value); break;
474 case RCNT3_MODE: rcntWmode(3, value); break;
475 case RCNT3_TARGET: rcntWtarget(3, value); break;
476
477 case D0_CHCR: // dma0 - vif0
478 DMA_LOG("VIF0dma %lx", value);
479 DmaExec16(dmaVIF0, mem, value);
480 break;
481
482 case D1_CHCR: // dma1 - vif1 - chcr
483 DMA_LOG("VIF1dma CHCR %lx", value);
484 DmaExec16(dmaVIF1, mem, value);
485 break;
486
487 #ifdef PCSX2_DEVBUILD
488 case D1_MADR: // dma1 - vif1 - madr
489 HW_LOG("VIF1dma Madr %lx", value);
490 psHu16(mem) = value;//dma1 madr
491 break;
492
493 case D1_QWC: // dma1 - vif1 - qwc
494 HW_LOG("VIF1dma QWC %lx", value);
495 psHu16(mem) = value;//dma1 qwc
496 break;
497
498 case D1_TADR: // dma1 - vif1 - tadr
499 HW_LOG("VIF1dma TADR %lx", value);
500 psHu16(mem) = value;//dma1 tadr
501 break;
502
503 case D1_ASR0: // dma1 - vif1 - asr0
504 HW_LOG("VIF1dma ASR0 %lx", value);
505 psHu16(mem) = value;//dma1 asr0
506 break;
507
508 case D1_ASR1: // dma1 - vif1 - asr1
509 HW_LOG("VIF1dma ASR1 %lx", value);
510 psHu16(mem) = value;//dma1 asr1
511 break;
512
513 case D1_SADR: // dma1 - vif1 - sadr
514 HW_LOG("VIF1dma SADR %lx", value);
515 psHu16(mem) = value;//dma1 sadr
516 break;
517 #endif
518 // ---------------------------------------------------
519
520 case D2_CHCR: // dma2 - gif
521 DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value);
522 DmaExec16(dmaGIF, mem, value);
523 break;
524
525 #ifdef PCSX2_DEVBUILD
526 case D2_MADR:
527 psHu16(mem) = value;//dma2 madr
528 HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value);
529 break;
530
531 case D2_QWC:
532 psHu16(mem) = value;//dma2 qwc
533 HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
534 break;
535
536 case D2_TADR:
537 psHu16(mem) = value;//dma2 taddr
538 HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
539 break;
540
541 case D2_ASR0:
542 psHu16(mem) = value;//dma2 asr0
543 HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
544 break;
545
546 case D2_ASR1:
547 psHu16(mem) = value;//dma2 asr1
548 HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
549 break;
550
551 case D2_SADR:
552 psHu16(mem) = value;//dma2 saddr
553 HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
554 break;
555 #endif
556
557 case D3_CHCR: // dma3 - fromIPU
558 DMA_LOG("IPU0dma %lx", value);
559 DmaExec16(dmaIPU0, mem, value);
560 break;
561
562 #ifdef PCSX2_DEVBUILD
563 case D3_MADR:
564 psHu16(mem) = value;//dma2 madr
565 HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value);
566 break;
567
568 case D3_QWC:
569 psHu16(mem) = value;//dma2 madr
570 HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value);
571 break;
572
573 case D3_TADR:
574 psHu16(mem) = value;//dma2 tadr
575 HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value);
576 break;
577
578 case D3_SADR:
579 psHu16(mem) = value;//dma2 saddr
580 HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value);
581 break;
582 #endif
583
584 case D4_CHCR: // dma4 - toIPU
585 DMA_LOG("IPU1dma %lx", value);
586 DmaExec16(dmaIPU1, mem, value);
587 break;
588
589 #ifdef PCSX2_DEVBUILD
590 case D4_MADR:
591 psHu16(mem) = value;//dma2 madr
592 HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value);
593 break;
594
595 case D4_QWC:
596 psHu16(mem) = value;//dma2 madr
597 HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value);
598 break;
599
600 case D4_TADR:
601 psHu16(mem) = value;//dma2 tadr
602 HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value);
603 break;
604
605 case D4_SADR:
606 psHu16(mem) = value;//dma2 saddr
607 HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value);
608 break;
609 #endif
610 case D5_CHCR: // dma5 - sif0
611 DMA_LOG("SIF0dma %lx", value);
612 DmaExec16(dmaSIF0, mem, value);
613 break;
614
615 case D6_CHCR: // dma6 - sif1
616 DMA_LOG("SIF1dma %lx", value);
617 DmaExec16(dmaSIF1, mem, value);
618 break;
619
620 // Given the other values here, perhaps something like this is in order?
621 /*case 0x1000C402: // D6_CHCR + 2
622 //?
623 break;*/
624
625 #ifdef PCSX2_DEVBUILD
626 case D6_MADR: // dma6 - sif1 - madr
627 HW_LOG("SIF1dma MADR = %lx", value);
628 psHu16(mem) = value;
629 break;
630
631 case D6_QWC: // dma6 - sif1 - qwc
632 HW_LOG("SIF1dma QWC = %lx", value);
633 psHu16(mem) = value;
634 break;
635
636 case D6_TADR: // dma6 - sif1 - tadr
637 HW_LOG("SIF1dma TADR = %lx", value);
638 psHu16(mem) = value;
639 break;
640 #endif
641
642 case D7_CHCR: // dma7 - sif2
643 DMA_LOG("SIF2dma %lx", value);
644 DmaExec16(dmaSIF2, mem, value);
645 break;
646
647 case D8_CHCR: // dma8 - fromSPR
648 DMA_LOG("fromSPRdma %lx", value);
649 DmaExec16(dmaSPR0, mem, value);
650 break;
651
652 case D9_CHCR: // dma9 - toSPR
653 DMA_LOG("toSPRdma %lx", value);
654 DmaExec16(dmaSPR1, mem, value);
655 break;
656
657 case D0_CHCR + 2: // dma0 - vif0
658 case D1_CHCR + 2: // dma1 - vif1
659 case D2_CHCR + 2: // dma2 - gif
660 case D3_CHCR + 2: // dma3 - fromIPU
661 case D4_CHCR + 2: // dma4 - toIPU
662 case D5_CHCR + 2: // dma5 - sif0
663 case D6_CHCR + 2: // dma6 - sif1
664 case D7_CHCR + 2: // dma7 - sif2
665 case D8_CHCR + 2: // dma8 - fromSPR
666 case D9_CHCR + 2: // dma9 - toSPR
667 //DevCon.Warning(L"16bit CHCR TAG changed to %x from %x on %s DMA", value, psHu32(mem), ChcrName(mem & ~0xf));
668 psHu16(mem) = value;
669 break;
670
671 case DMAC_ENABLEW + 2:
672 oldvalue = psHu8(DMAC_ENABLEW + 2);
673 psHu16(DMAC_ENABLEW + 2) = value;
674 psHu16(DMAC_ENABLER + 2) = value;
675 if (((oldvalue & 0x1) == 1) && ((value & 0x1) == 0))
676 {
677 if (!QueuedDMA.empty()) StartQueuedDMA();
678 }
679 break;
680
681 case SIO_ISR:
682 case SIO_ISR + 2:
683 case 0x1000f410:
684 case 0x1000f410 + 2:
685 case MCH_RICM:
686 case MCH_RICM + 2:
687 break;
688
689 case SBUS_F200:
690 psHu16(mem) = value;
691 break;
692
693 case SBUS_F210:
694 psHu16(mem) = value;
695 break;
696
697 case SBUS_F220:
698 psHu16(mem) |= value;
699 break;
700
701 case SBUS_F230:
702 psHu16(mem) &= ~value;
703 break;
704
705 case SBUS_F240:
706 if (!(value & 0x100))
707 psHu16(mem) &= ~0x100;
708 else
709 psHu16(mem) |= 0x100;
710 break;
711
712 case SBUS_F250:
713 psHu16(mem) = value;
714 break;
715
716 case SBUS_F260:
717 psHu16(mem) = 0;
718 break;
719
720 default:
721 psHu16(mem) = value;
722 UnknownHW_LOG("Unknown Hardware write 16 at %x with value %x",mem,value);
723 }
724 }
725
726 // Page 0 of HW memory houses registers for Counters 0 and 1
727 void __fastcall hwWrite32_page_00( u32 mem, u32 value )
728 {
729 mem &= 0xffff;
730 switch (mem)
731 {
732 case 0x000: rcntWcount(0, value); return;
733 case 0x010: rcntWmode(0, value); return;
734 case 0x020: rcntWtarget(0, value); return;
735 case 0x030: rcntWhold(0, value); return;
736
737 case 0x800: rcntWcount(1, value); return;
738 case 0x810: rcntWmode(1, value); return;
739 case 0x820: rcntWtarget(1, value); return;
740 case 0x830: rcntWhold(1, value); return;
741 }
742
743 *((u32*)&PS2MEM_HW[mem]) = value;
744 }
745
746 // Page 1 of HW memory houses registers for Counters 2 and 3
747 void __fastcall hwWrite32_page_01( u32 mem, u32 value )
748 {
749 mem &= 0xffff;
750 switch (mem)
751 {
752 case 0x1000: rcntWcount(2, value); return;
753 case 0x1010: rcntWmode(2, value); return;
754 case 0x1020: rcntWtarget(2, value); return;
755
756 case 0x1800: rcntWcount(3, value); return;
757 case 0x1810: rcntWmode(3, value); return;
758 case 0x1820: rcntWtarget(3, value); return;
759 }
760
761 *((u32*)&PS2MEM_HW[mem]) = value;
762 }
763
764 // page 2 is the IPU register space!
765 void __fastcall hwWrite32_page_02( u32 mem, u32 value )
766 {
767 ipuWrite32(mem, value);
768 }
769
770 // Page 3 contains writes to vif0 and vif1 registers, plus some GIF stuff!
771 void __fastcall hwWrite32_page_03( u32 mem, u32 value )
772 {
773 if (mem >= VIF0_STAT)
774 {
775 if(mem < VIF1_STAT)
776 vif0Write32(mem, value);
777 else
778 vif1Write32(mem, value);
779 return;
780 }
781
782 switch (mem)
783 {
784 case GIF_CTRL:
785 psHu32(mem) = value & 0x8;
786
787 if (value & 0x1)
788 gsGIFReset();
789 else if ( value & 8 )
790 gifRegs->stat.PSE = true;
791 else
792 gifRegs->stat.PSE = false;
793 break;
794
795 case GIF_MODE:
796 {
797 // need to set GIF_MODE (hamster ball)
798 gifRegs->mode.write(value);
799
800 // set/clear bits 0 and 2 as per the GIF_MODE value.
801 const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT;
802 psHu32(GIF_STAT) &= ~bitmask;
803 psHu32(GIF_STAT) |= (u32)value & bitmask;
804
805 }
806 break;
807
808 case GIF_STAT: // stat is readonly
809 DevCon.Warning("*PCSX2* GIFSTAT write value = 0x%x (readonly, ignored)", value);
810 break;
811
812 default:
813 psHu32(mem) = value;
814 }
815 }
816
817 void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
818 {
819 // Used for developer logging -- optimized away in Public Release.
820 const char* regName = "Unknown";
821
822 switch( mem )
823 {
824 case D3_CHCR: // dma3 - fromIPU
825 DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value);
826 DmaExec(dmaIPU0, mem, value);
827 return;
828
829 case D3_MADR: regName = "IPU0DMA_MADR"; break;
830 case D3_QWC: regName = "IPU0DMA_QWC"; break;
831 case D3_TADR: regName = "IPU0DMA_TADR"; break;
832 case D3_SADR: regName = "IPU0DMA_SADDR"; break;
833
834 //------------------------------------------------------------------
835
836 case D4_CHCR: // dma4 - toIPU
837 DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value);
838 DmaExec(dmaIPU1, mem, value);
839 return;
840
841 case D4_MADR: regName = "IPU1DMA_MADR"; break;
842 case D4_QWC: regName = "IPU1DMA_QWC"; break;
843 case D4_TADR: regName = "IPU1DMA_TADR"; break;
844 case D4_SADR: regName = "IPU1DMA_SADDR"; break;
845 }
846
847 HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x", mem, regName, value );
848 psHu32(mem) = value;
849 }
850
851
852
853 void __fastcall hwWrite32_page_0E( u32 mem, u32 value )
854 {
855 switch (mem)
856 {
857 case DMAC_CTRL:
858 {
859 u32 oldvalue = psHu32(mem);
860
861 HW_LOG("DMAC_CTRL Write 32bit %x", value);
862
863 psHu32(mem) = value;
864 //Check for DMAS that were started while the DMAC was disabled
865 if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1))
866 {
867 if (!QueuedDMA.empty()) StartQueuedDMA();
868 }
869 break;
870 }
871
872 case DMAC_STAT:
873 HW_LOG("DMAC_STAT Write 32bit %x", value);
874
875 // lower 16 bits: clear on 1
876 // upper 16 bits: reverse on 1
877
878 psHu16(0xe010) &= ~(value & 0xffff);
879 psHu16(0xe012) ^= (u16)(value >> 16);
880
881 cpuTestDMACInts();
882 break;
883
884 default:
885 psHu32(mem) = value;
886 break;
887 }
888 }
889
890 void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
891 {
892 // Shift the middle 8 bits (bits 4-12) into the lower 8 bits.
893 // This helps the compiler optimize the switch statement into a lookup table. :)
894
895 #define HELPSWITCH(m) (((m)>>4) & 0xff)
896
897 switch( HELPSWITCH(mem) )
898 {
899 case HELPSWITCH(INTC_STAT):
900 HW_LOG("INTC_STAT Write 32bit %x", value);
901 psHu32(INTC_STAT) &= ~value;
902 //cpuTestINTCInts();
903 break;
904
905 case HELPSWITCH(INTC_MASK):
906 HW_LOG("INTC_MASK Write 32bit %x", value);
907 psHu32(INTC_MASK) ^= (u16)value;
908 cpuTestINTCInts();
909 break;
910
911 //------------------------------------------------------------------
912 case HELPSWITCH(MCH_RICM)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
913 if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0
914 rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid
915 psHu32(mem) = value & ~0x80000000; //kill the busy bit
916 break;
917
918 case HELPSWITCH(SBUS_F200):
919 psHu32(mem) = value;
920 break;
921
922 case HELPSWITCH(SBUS_F220):
923 psHu32(mem) |= value;
924 break;
925
926 case HELPSWITCH(SBUS_F230):
927 psHu32(mem) &= ~value;
928 break;
929
930 case HELPSWITCH(SBUS_F240):
931 if(!(value & 0x100))
932 psHu32(mem) &= ~0x100;
933 else
934 psHu32(mem) |= 0x100;
935 break;
936
937 case HELPSWITCH(SBUS_F260):
938 psHu32(mem) = 0;
939 break;
940
941 case HELPSWITCH(MCH_DRD)://MCH_DRD:
942 psHu32(mem) = value;
943 break;
944
945 case HELPSWITCH(DMAC_ENABLEW):
946 HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
947 oldvalue = psHu8(DMAC_ENABLEW + 2);
948 psHu32(DMAC_ENABLEW) = value;
949 psHu32(DMAC_ENABLER) = value;
950 if (((oldvalue & 0x1) == 1) && (((value >> 16) & 0x1) == 0))
951 {
952 if (!QueuedDMA.empty()) StartQueuedDMA();
953 }
954 break;
955
956 //------------------------------------------------------------------
957 case HELPSWITCH(SIO_ISR):
958 case HELPSWITCH(0x1000f410):
959 UnknownHW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val);
960 break;
961
962 default:
963 psHu32(mem) = value;
964 }
965 }
966
967 void __fastcall hwWrite32_generic( u32 mem, u32 value )
968 {
969 // Used for developer logging -- optimized away in Public Release.
970 const char* regName = "Unknown";
971
972 switch (mem)
973 {
974 case D0_CHCR: // dma0 - vif0
975 DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
976 DmaExec(dmaVIF0, mem, value);
977 return;
978
979 //------------------------------------------------------------------
980 case D1_CHCR: // dma1 - vif1 - chcr
981 DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
982 DmaExec(dmaVIF1, mem, value);
983 return;
984
985 case D1_MADR: regName = "VIF1dma MADR"; break;
986 case D1_QWC: regName = "VIF1dma QWC"; break;
987 case D1_TADR: regName = "VIF1dma TADR"; break;
988 case D1_ASR0: regName = "VIF1dma ASR0"; break;
989 case D1_ASR1: regName = "VIF1dma ASR1"; break;
990 case D1_SADR: regName = "VIF1dma SADR"; break;
991
992 //------------------------------------------------------------------
993 case D2_CHCR: // dma2 - gif
994 DMA_LOG("GIFdma EXECUTE, value=0x%x", value);
995 DmaExec(dmaGIF, mem, value);
996 return;
997
998 case D2_MADR: regName = "GIFdma MADR"; break;
999 case D2_QWC: regName = "GIFdma QWC"; break;
1000 case D2_TADR: regName = "GIFdma TADDR"; break;
1001 case D2_ASR0: regName = "GIFdma ASR0"; break;
1002 case D2_ASR1: regName = "GIFdma ASR1"; break;
1003 case D2_SADR: regName = "GIFdma SADDR"; break;
1004
1005 //------------------------------------------------------------------
1006 case D5_CHCR: // dma5 - sif0
1007 DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
1008 DmaExec(dmaSIF0, mem, value);
1009 return;
1010 //------------------------------------------------------------------
1011 case D6_CHCR: // dma6 - sif1
1012 DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
1013 DmaExec(dmaSIF1, mem, value);
1014 return;
1015
1016 case D6_MADR: regName = "SIF1dma MADR"; break;
1017 case D6_QWC: regName = "SIF1dma QWC"; break;
1018 case D6_TADR: regName = "SIF1dma TADR"; break;
1019
1020 //------------------------------------------------------------------
1021 case D7_CHCR: // dma7 - sif2
1022 DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
1023 DmaExec(dmaSIF2, mem, value);
1024 return;
1025 //------------------------------------------------------------------
1026 case D8_CHCR: // dma8 - fromSPR
1027 DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
1028 DmaExec(dmaSPR0, mem, value);
1029 return;
1030 //------------------------------------------------------------------
1031 case D9_CHCR: // dma9 - toSPR
1032 DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value);
1033 DmaExec(dmaSPR1, mem, value);
1034 return;
1035 }
1036 HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x", mem, regName, value );
1037 psHu32(mem) = value;
1038 }
1039
1040 /////////////////////////////////////////////////////////////////////////
1041 // HW Write 64 bit
1042
1043 // Page 0 of HW memory houses registers for Counters 0 and 1
1044 void __fastcall hwWrite64_page_00( u32 mem, const mem64_t* srcval )
1045 {
1046 hwWrite32_page_00( mem, (u32)*srcval ); // just ignore upper 32 bits.
1047 psHu64(mem) = *srcval;
1048 }
1049
1050 // Page 1 of HW memory houses registers for Counters 2 and 3
1051 void __fastcall hwWrite64_page_01( u32 mem, const mem64_t* srcval )
1052 {
1053 hwWrite32_page_01( mem, (u32)*srcval ); // just ignore upper 32 bits.
1054 psHu64(mem) = *srcval;
1055 }
1056
1057 void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval )
1058 {
1059 //hwWrite64( mem, *srcval ); return;
1060 ipuWrite64( mem, *srcval );
1061 }
1062
1063 void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval )
1064 {
1065 //hwWrite64( mem, *srcval ); return;
1066 const u64 value = *srcval;
1067
1068 if (mem >= VIF0_STAT)
1069 {
1070 if (mem < VIF1_STAT)
1071 vif0Write32(mem, value);
1072 else
1073 vif1Write32(mem, value);
1074 return;
1075 }
1076
1077 switch (mem)
1078 {
1079 case GIF_CTRL:
1080 DevCon.WriteLn("GIF_CTRL write 64", value);
1081 psHu32(mem) = value & 0x8;
1082 if(value & 0x1)
1083 gsGIFReset();
1084 else
1085 {
1086 if( value & 8 )
1087 gifRegs->stat.PSE = true;
1088 else
1089 gifRegs->stat.PSE = false;
1090 }
1091 break;
1092
1093 case GIF_MODE:
1094 {
1095 // set/clear bits 0 and 2 as per the GIF_MODE value.
1096 const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT;
1097
1098 Console.WriteLn("GIFMODE64 %x", value);
1099
1100 psHu64(GIF_MODE) = value;
1101 psHu32(GIF_STAT) &= ~bitmask;
1102 psHu32(GIF_STAT) |= (u32)value & bitmask;
1103 break;
1104 }
1105
1106 case GIF_STAT: // stat is readonly
1107 break;
1108 }
1109 }
1110
1111 void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval )
1112 {
1113 //hwWrite64( mem, *srcval ); return;
1114
1115 const u64 value = *srcval;
1116
1117 switch (mem)
1118 {
1119 case DMAC_CTRL:
1120 {
1121 u32 oldvalue = psHu32(mem);
1122 psHu64(mem) = value;
1123
1124 HW_LOG("DMAC_CTRL Write 64bit %x", value);
1125
1126 if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1))
1127 {
1128 if (!QueuedDMA.empty()) StartQueuedDMA();
1129 }
1130 break;
1131 }
1132
1133 case DMAC_STAT:
1134 HW_LOG("DMAC_STAT Write 64bit %x", value);
1135
1136 // lower 16 bits: clear on 1
1137 // upper 16 bits: reverse on 1
1138
1139 psHu16(0xe010) &= ~(value & 0xffff);
1140 psHu16(0xe012) ^= (u16)(value >> 16);
1141
1142 cpuTestDMACInts();
1143 break;
1144
1145 default:
1146 psHu64(mem) = value;
1147 break;
1148 }
1149 }
1150
1151 void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
1152 {
1153 const u64 value = *srcval;
1154
1155 switch (mem)
1156 {
1157 case D2_CHCR: // dma2 - gif
1158 DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value);
1159 DmaExec(dmaGIF, mem, value);
1160 break;
1161
1162 case INTC_STAT:
1163 HW_LOG("INTC_STAT Write 64bit %x", (u32)value);
1164 psHu32(INTC_STAT) &= ~value;
1165 //cpuTestINTCInts();
1166 break;
1167
1168 case INTC_MASK:
1169 HW_LOG("INTC_MASK Write 64bit %x", (u32)value);
1170 psHu32(INTC_MASK) ^= (u16)value;
1171 cpuTestINTCInts();
1172 break;
1173
1174 case SIO_ISR:
1175 case 0x1000f410:
1176 case MCH_RICM:
1177 break;
1178
1179 case DMAC_ENABLEW: // DMAC_ENABLEW
1180 oldvalue = psHu8(DMAC_ENABLEW + 2);
1181 psHu32(DMAC_ENABLEW) = value;
1182 psHu32(DMAC_ENABLER) = value;
1183 if (((oldvalue & 0x1) == 1) && (((value >> 16) & 0x1) == 0))
1184 {
1185 if (!QueuedDMA.empty()) StartQueuedDMA();
1186 }
1187 break;
1188
1189 default:
1190 psHu64(mem) = value;
1191 UnknownHW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)",mem,value, cpuRegs.CP0.n.Status.val);
1192 break;
1193 }
1194 }
1195
1196 /////////////////////////////////////////////////////////////////////////
1197 // HW Write 128 bit
1198
1199 void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval)
1200 {
1201 //hwWrite128( mem, srcval ); return;
1202
1203 switch (mem)
1204 {
1205 case INTC_STAT:
1206 HW_LOG("INTC_STAT Write 64bit %x", (u32)srcval[0]);
1207 psHu32(INTC_STAT) &= ~srcval[0];
1208 //cpuTestINTCInts();
1209 break;
1210
1211 case INTC_MASK:
1212 HW_LOG("INTC_MASK Write 64bit %x", (u32)srcval[0]);
1213 psHu32(INTC_MASK) ^= (u16)srcval[0];
1214 cpuTestINTCInts();
1215 break;
1216
1217 case DMAC_ENABLEW: // DMAC_ENABLEW
1218 oldvalue = psHu8(DMAC_ENABLEW + 2);
1219 psHu32(DMAC_ENABLEW) = srcval[0];
1220 psHu32(DMAC_ENABLER) = srcval[0];
1221 if (((oldvalue & 0x1) == 1) && (((srcval[0] >> 16) & 0x1) == 0))
1222 {
1223 if (!QueuedDMA.empty()) StartQueuedDMA();
1224 }
1225 break;
1226
1227 case SIO_ISR:
1228 case 0x1000f410:
1229 case MCH_RICM:
1230 break;
1231
1232 default:
1233 psHu64(mem ) = srcval[0];
1234 psHu64(mem+8) = srcval[1];
1235
1236 UnknownHW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)", mem, srcval[1], srcval[0], cpuRegs.CP0.n.Status.val);
1237 break;
1238 }
1239 }

  ViewVC Help
Powered by ViewVC 1.1.22