/[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 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 2 months ago) by william
File size: 35309 byte(s)
committing r3113 initial commit again...
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    
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