easier logging of unhandled stuff
[pcsx_rearmed.git] / libpcsxcore / psxhw.c
1 /***************************************************************************
2  *   Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
18  ***************************************************************************/
19
20 /*
21 * Functions for PSX hardware control.
22 */
23
24 #include "psxhw.h"
25 #include "mdec.h"
26 #include "cdrom.h"
27 #include "gpu.h"
28
29 //#undef PSXHW_LOG
30 //#define PSXHW_LOG printf
31
32 void psxHwReset() {
33         if (Config.Sio) psxHu32ref(0x1070) |= SWAP32(0x80);
34         if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAP32(0x200);
35
36         memset(psxH, 0, 0x10000);
37
38         mdecInit(); // initialize mdec decoder
39         cdrReset();
40         psxRcntInit();
41         HW_GPU_STATUS = SWAP32(0x14802000);
42 }
43
44 u8 psxHwRead8(u32 add) {
45         unsigned char hard;
46
47         switch (add & 0x1fffffff) {
48                 case 0x1f801040: hard = sioRead8();break; \r
49 #ifdef ENABLE_SIO1API
50                 case 0x1f801050: hard = SIO1_readData8(); break;\r
51 #endif
52                 case 0x1f801800: hard = cdrRead0(); break;
53                 case 0x1f801801: hard = cdrRead1(); break;
54                 case 0x1f801802: hard = cdrRead2(); break;
55                 case 0x1f801803: hard = cdrRead3(); break;
56                 default:
57                         hard = psxHu8(add); 
58 #ifdef PSXHW_LOG
59                         PSXHW_LOG("*Unkwnown 8bit read at address %x\n", add);
60 #endif
61                         return hard;
62         }
63
64 #ifdef PSXHW_LOG
65         PSXHW_LOG("*Known 8bit read at address %x value %x\n", add, hard);
66 #endif
67         return hard;
68 }
69
70 u16 psxHwRead16(u32 add) {
71         unsigned short hard;
72
73         switch (add & 0x1fffffff) {
74 #ifdef PSXHW_LOG
75                 case 0x1f801070: PSXHW_LOG("IREG 16bit read %x\n", psxHu16(0x1070));
76                         return psxHu16(0x1070);
77 #endif
78 #ifdef PSXHW_LOG
79                 case 0x1f801074: PSXHW_LOG("IMASK 16bit read %x\n", psxHu16(0x1074));
80                         return psxHu16(0x1074);
81 #endif
82
83                 case 0x1f801040:
84                         hard = sioRead8();
85                         hard|= sioRead8() << 8;
86 #ifdef PAD_LOG
87                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
88 #endif
89                         return hard;
90                 case 0x1f801044:
91                         hard = sioReadStat16();
92 #ifdef PAD_LOG
93                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
94 #endif
95                         return hard;
96                 case 0x1f801048:
97                         hard = sioReadMode16();
98 #ifdef PAD_LOG
99                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
100 #endif
101                         return hard;
102                 case 0x1f80104a:
103                         hard = sioReadCtrl16();
104 #ifdef PAD_LOG
105                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
106 #endif
107                         return hard;
108                 case 0x1f80104e:
109                         hard = sioReadBaud16();
110 #ifdef PAD_LOG
111                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
112 #endif
113                         return hard;\r
114 #ifdef ENABLE_SIO1API
115                 case 0x1f801050:
116                         hard = SIO1_readData16();
117                         return hard;
118                 case 0x1f801054:
119                         hard = SIO1_readStat16();
120                         return hard;
121                 case 0x1f80105a:
122                         hard = SIO1_readCtrl16();
123                         return hard;
124                 case 0x1f80105e:
125                         hard = SIO1_readBaud16();
126                         return hard;
127 #else
128                 /* Fixes Armored Core misdetecting the Link cable being detected.
129                  * We want to turn that thing off and force it to do local multiplayer instead.
130                  * Thanks Sony for the fix, they fixed it in their PS Classic fork.
131                  */
132                 case 0x1f801054:
133                         return 0x80;\r
134 #endif
135                 case 0x1f801100:
136                         hard = psxRcntRcount(0);
137 #ifdef PSXHW_LOG
138                         PSXHW_LOG("T0 count read16: %x\n", hard);
139 #endif
140                         return hard;
141                 case 0x1f801104:
142                         hard = psxRcntRmode(0);
143 #ifdef PSXHW_LOG
144                         PSXHW_LOG("T0 mode read16: %x\n", hard);
145 #endif
146                         return hard;
147                 case 0x1f801108:
148                         hard = psxRcntRtarget(0);
149 #ifdef PSXHW_LOG
150                         PSXHW_LOG("T0 target read16: %x\n", hard);
151 #endif
152                         return hard;
153                 case 0x1f801110:
154                         hard = psxRcntRcount(1);
155 #ifdef PSXHW_LOG
156                         PSXHW_LOG("T1 count read16: %x\n", hard);
157 #endif
158                         return hard;
159                 case 0x1f801114:
160                         hard = psxRcntRmode(1);
161 #ifdef PSXHW_LOG
162                         PSXHW_LOG("T1 mode read16: %x\n", hard);
163 #endif
164                         return hard;
165                 case 0x1f801118:
166                         hard = psxRcntRtarget(1);
167 #ifdef PSXHW_LOG
168                         PSXHW_LOG("T1 target read16: %x\n", hard);
169 #endif
170                         return hard;
171                 case 0x1f801120:
172                         hard = psxRcntRcount(2);
173 #ifdef PSXHW_LOG
174                         PSXHW_LOG("T2 count read16: %x\n", hard);
175 #endif
176                         return hard;
177                 case 0x1f801124:
178                         hard = psxRcntRmode(2);
179 #ifdef PSXHW_LOG
180                         PSXHW_LOG("T2 mode read16: %x\n", hard);
181 #endif
182                         return hard;
183                 case 0x1f801128:
184                         hard = psxRcntRtarget(2);
185 #ifdef PSXHW_LOG
186                         PSXHW_LOG("T2 target read16: %x\n", hard);
187 #endif
188                         return hard;
189
190                 //case 0x1f802030: hard =   //int_2000????
191                 //case 0x1f802040: hard =//dip switches...??
192
193                 case 0x1f801800:
194                 case 0x1f801802:
195                         log_unhandled("cdrom r16 %x\n", add);
196                         // falthrough
197                 default:
198                         if (add >= 0x1f801c00 && add < 0x1f801e00) {
199                 hard = SPU_readRegister(add);
200                         } else {
201                                 hard = psxHu16(add); 
202 #ifdef PSXHW_LOG
203                                 PSXHW_LOG("*Unkwnown 16bit read at address %x\n", add);
204 #endif
205                         }
206             return hard;
207         }
208         
209 #ifdef PSXHW_LOG
210         PSXHW_LOG("*Known 16bit read at address %x value %x\n", add, hard);
211 #endif
212         return hard;
213 }
214
215 u32 psxHwRead32(u32 add) {
216         u32 hard;
217
218         switch (add & 0x1fffffff) {
219                 case 0x1f801040:
220                         hard = sioRead8();
221                         hard |= sioRead8() << 8;
222                         hard |= sioRead8() << 16;
223                         hard |= sioRead8() << 24;
224 #ifdef PAD_LOG
225                         PAD_LOG("sio read32 ;ret = %x\n", hard);
226 #endif
227                         return hard;\r
228 #ifdef ENABLE_SIO1API
229                 case 0x1f801050:
230                         hard = SIO1_readData32();
231                         return hard;\r
232 #endif
233 #ifdef PSXHW_LOG
234                 case 0x1f801060:
235                         PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060));
236                         return psxHu32(0x1060);
237 #endif
238 #ifdef PSXHW_LOG
239                 case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070));
240                         return psxHu32(0x1070);
241 #endif
242 #ifdef PSXHW_LOG
243                 case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074));
244                         return psxHu32(0x1074);
245 #endif
246
247                 case 0x1f801810:
248                         hard = GPU_readData();
249 #ifdef PSXHW_LOG
250                         PSXHW_LOG("GPU DATA 32bit read %x\n", hard);
251 #endif
252                         return hard;
253                 case 0x1f801814:
254                         gpuSyncPluginSR();
255                         hard = SWAP32(HW_GPU_STATUS);
256                         if (hSyncCount < 240 && (hard & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS)
257                                 hard |= PSXGPU_LCF & (psxRegs.cycle << 20);
258 #ifdef PSXHW_LOG
259                         PSXHW_LOG("GPU STATUS 32bit read %x\n", hard);
260 #endif
261                         return hard;
262
263                 case 0x1f801820: hard = mdecRead0(); break;
264                 case 0x1f801824: hard = mdecRead1(); break;
265
266 #ifdef PSXHW_LOG
267                 case 0x1f8010a0:
268                         PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0));
269                         return SWAPu32(HW_DMA2_MADR);
270                 case 0x1f8010a4:
271                         PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4));
272                         return SWAPu32(HW_DMA2_BCR);
273                 case 0x1f8010a8:
274                         PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8));
275                         return SWAPu32(HW_DMA2_CHCR);
276 #endif
277
278 #ifdef PSXHW_LOG
279                 case 0x1f8010b0:
280                         PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0));
281                         return SWAPu32(HW_DMA3_MADR);
282                 case 0x1f8010b4:
283                         PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4));
284                         return SWAPu32(HW_DMA3_BCR);
285                 case 0x1f8010b8:
286                         PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8));
287                         return SWAPu32(HW_DMA3_CHCR);
288 #endif
289
290 #ifdef PSXHW_LOG
291 /*              case 0x1f8010f0:
292                         PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0));
293                         return SWAPu32(HW_DMA_PCR); // dma rest channel
294                 case 0x1f8010f4:
295                         PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4));
296                         return SWAPu32(HW_DMA_ICR); // interrupt enabler?*/
297 #endif
298
299                 // time for rootcounters :)
300                 case 0x1f801100:
301                         hard = psxRcntRcount(0);
302 #ifdef PSXHW_LOG
303                         PSXHW_LOG("T0 count read32: %x\n", hard);
304 #endif
305                         return hard;
306                 case 0x1f801104:
307                         hard = psxRcntRmode(0);
308 #ifdef PSXHW_LOG
309                         PSXHW_LOG("T0 mode read32: %x\n", hard);
310 #endif
311                         return hard;
312                 case 0x1f801108:
313                         hard = psxRcntRtarget(0);
314 #ifdef PSXHW_LOG
315                         PSXHW_LOG("T0 target read32: %x\n", hard);
316 #endif
317                         return hard;
318                 case 0x1f801110:
319                         hard = psxRcntRcount(1);
320 #ifdef PSXHW_LOG
321                         PSXHW_LOG("T1 count read32: %x\n", hard);
322 #endif
323                         return hard;
324                 case 0x1f801114:
325                         hard = psxRcntRmode(1);
326 #ifdef PSXHW_LOG
327                         PSXHW_LOG("T1 mode read32: %x\n", hard);
328 #endif
329                         return hard;
330                 case 0x1f801118:
331                         hard = psxRcntRtarget(1);
332 #ifdef PSXHW_LOG
333                         PSXHW_LOG("T1 target read32: %x\n", hard);
334 #endif
335                         return hard;
336                 case 0x1f801120:
337                         hard = psxRcntRcount(2);
338 #ifdef PSXHW_LOG
339                         PSXHW_LOG("T2 count read32: %x\n", hard);
340 #endif
341                         return hard;
342                 case 0x1f801124:
343                         hard = psxRcntRmode(2);
344 #ifdef PSXHW_LOG
345                         PSXHW_LOG("T2 mode read32: %x\n", hard);
346 #endif
347                         return hard;
348                 case 0x1f801128:
349                         hard = psxRcntRtarget(2);
350 #ifdef PSXHW_LOG
351                         PSXHW_LOG("T2 target read32: %x\n", hard);
352 #endif
353                         return hard;
354
355                 case 0x1f801800:
356                         log_unhandled("cdrom r32 %x\n", add);
357                         // falthrough
358                 default:
359                         hard = psxHu32(add); 
360 #ifdef PSXHW_LOG
361                         PSXHW_LOG("*Unkwnown 32bit read at address %x\n", add);
362 #endif
363                         return hard;
364         }
365 #ifdef PSXHW_LOG
366         PSXHW_LOG("*Known 32bit read at address %x\n", add);
367 #endif
368         return hard;
369 }
370
371 void psxHwWrite8(u32 add, u8 value) {
372         switch (add & 0x1fffffff) {
373                 case 0x1f801040: sioWrite8(value); break;\r
374 #ifdef ENABLE_SIO1API
375                 case 0x1f801050: SIO1_writeData8(value); break;\r
376 #endif
377                 case 0x1f801800: cdrWrite0(value); break;
378                 case 0x1f801801: cdrWrite1(value); break;
379                 case 0x1f801802: cdrWrite2(value); break;
380                 case 0x1f801803: cdrWrite3(value); break;
381
382                 default:
383                         psxHu8(add) = value;
384 #ifdef PSXHW_LOG
385                         PSXHW_LOG("*Unknown 8bit write at address %x value %x\n", add, value);
386 #endif
387                         return;
388         }
389         psxHu8(add) = value;
390 #ifdef PSXHW_LOG
391         PSXHW_LOG("*Known 8bit write at address %x value %x\n", add, value);
392 #endif
393 }
394
395 void psxHwWrite16(u32 add, u16 value) {
396         switch (add & 0x1fffffff) {
397                 case 0x1f801040:
398                         sioWrite8((unsigned char)value);
399                         sioWrite8((unsigned char)(value>>8));
400 #ifdef PAD_LOG
401                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
402 #endif
403                         return;
404                 case 0x1f801044:
405                         sioWriteStat16(value);
406 #ifdef PAD_LOG
407                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
408 #endif
409                         return;
410                 case 0x1f801048:
411             sioWriteMode16(value);
412 #ifdef PAD_LOG
413                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
414 #endif
415                         return;
416                 case 0x1f80104a: // control register
417                         sioWriteCtrl16(value);
418 #ifdef PAD_LOG
419                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
420 #endif
421                         return;
422                 case 0x1f80104e: // baudrate register
423             sioWriteBaud16(value);
424 #ifdef PAD_LOG
425                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
426 #endif
427                         return;\r
428 #ifdef ENABLE_SIO1API
429                 case 0x1f801050:
430                         SIO1_writeData16(value);
431                         return;
432                 case 0x1f801054:
433                         SIO1_writeStat16(value);
434                         return;
435                 case 0x1f80105a:
436                         SIO1_writeCtrl16(value);
437                         return;
438                 case 0x1f80105e:
439                         SIO1_writeBaud16(value);
440                         return;\r
441 #endif
442                 case 0x1f801070: 
443 #ifdef PSXHW_LOG
444                         PSXHW_LOG("IREG 16bit write %x\n", value);
445 #endif
446                         if (Config.Sio) psxHu16ref(0x1070) |= SWAPu16(0x80);
447                         if (Config.SpuIrq) psxHu16ref(0x1070) |= SWAPu16(0x200);
448                         psxHu16ref(0x1070) &= SWAPu16(value);
449                         return;
450
451                 case 0x1f801074:
452 #ifdef PSXHW_LOG
453                         PSXHW_LOG("IMASK 16bit write %x\n", value);
454 #endif
455                         psxHu16ref(0x1074) = SWAPu16(value);
456                         if (psxHu16ref(0x1070) & SWAPu16(value))
457                                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
458                         return;
459
460                 case 0x1f801100:
461 #ifdef PSXHW_LOG
462                         PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value);
463 #endif
464                         psxRcntWcount(0, value); return;
465                 case 0x1f801104:
466 #ifdef PSXHW_LOG
467                         PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value);
468 #endif
469                         psxRcntWmode(0, value); return;
470                 case 0x1f801108:
471 #ifdef PSXHW_LOG
472                         PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value);
473 #endif
474                         psxRcntWtarget(0, value); return;
475
476                 case 0x1f801110:
477 #ifdef PSXHW_LOG
478                         PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value);
479 #endif
480                         psxRcntWcount(1, value); return;
481                 case 0x1f801114:
482 #ifdef PSXHW_LOG
483                         PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value);
484 #endif
485                         psxRcntWmode(1, value); return;
486                 case 0x1f801118:
487 #ifdef PSXHW_LOG
488                         PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value);
489 #endif
490                         psxRcntWtarget(1, value); return;
491
492                 case 0x1f801120:
493 #ifdef PSXHW_LOG
494                         PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value);
495 #endif
496                         psxRcntWcount(2, value); return;
497                 case 0x1f801124:
498 #ifdef PSXHW_LOG
499                         PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value);
500 #endif
501                         psxRcntWmode(2, value); return;
502                 case 0x1f801128:
503 #ifdef PSXHW_LOG
504                         PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value);
505 #endif
506                         psxRcntWtarget(2, value); return;
507
508                 default:
509                         if (add>=0x1f801c00 && add<0x1f801e00) {
510                                 SPU_writeRegister(add, value, psxRegs.cycle);
511                                 return;
512                         }
513
514                         psxHu16ref(add) = SWAPu16(value);
515 #ifdef PSXHW_LOG
516                         PSXHW_LOG("*Unknown 16bit write at address %x value %x\n", add, value);
517 #endif
518                         return;
519         }
520         psxHu16ref(add) = SWAPu16(value);
521 #ifdef PSXHW_LOG
522         PSXHW_LOG("*Known 16bit write at address %x value %x\n", add, value);
523 #endif
524 }
525
526 #define DmaExec(n) { \
527         HW_DMA##n##_CHCR = SWAPu32(value); \
528 \
529         if (SWAPu32(HW_DMA##n##_CHCR) & 0x01000000 && SWAPu32(HW_DMA_PCR) & (8 << (n * 4))) { \
530                 psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), SWAPu32(HW_DMA##n##_CHCR)); \
531         } \
532 }
533
534 void psxHwWrite32(u32 add, u32 value) {
535         switch (add & 0x1fffffff) {
536             case 0x1f801040:
537                         sioWrite8((unsigned char)value);
538                         sioWrite8((unsigned char)((value&0xff) >>  8));
539                         sioWrite8((unsigned char)((value&0xff) >> 16));
540                         sioWrite8((unsigned char)((value&0xff) >> 24));
541 #ifdef PAD_LOG
542                         PAD_LOG("sio write32 %x\n", value);
543 #endif
544                         return;\r
545 #ifdef ENABLE_SIO1API
546                 case 0x1f801050:
547                         SIO1_writeData32(value);
548                         return;\r
549 #endif
550 #ifdef PSXHW_LOG
551                 case 0x1f801060:
552                         PSXHW_LOG("RAM size write %x\n", value);
553                         psxHu32ref(add) = SWAPu32(value);
554                         return; // Ram size
555 #endif
556
557                 case 0x1f801070: 
558 #ifdef PSXHW_LOG
559                         PSXHW_LOG("IREG 32bit write %x\n", value);
560 #endif
561                         if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80);
562                         if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200);
563                         psxHu32ref(0x1070) &= SWAPu32(value);
564                         return;
565                 case 0x1f801074:
566 #ifdef PSXHW_LOG
567                         PSXHW_LOG("IMASK 32bit write %x\n", value);
568 #endif
569                         psxHu32ref(0x1074) = SWAPu32(value);
570                         if (psxHu32ref(0x1070) & SWAPu32(value))
571                                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
572                         return;
573
574 #ifdef PSXHW_LOG
575                 case 0x1f801080:
576                         PSXHW_LOG("DMA0 MADR 32bit write %x\n", value);
577                         HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr
578                 case 0x1f801084:
579                         PSXHW_LOG("DMA0 BCR 32bit write %x\n", value);
580                         HW_DMA0_BCR  = SWAPu32(value); return; // DMA0 bcr
581 #endif
582                 case 0x1f801088:
583 #ifdef PSXHW_LOG
584                         PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value);
585 #endif
586                         DmaExec(0);                      // DMA0 chcr (MDEC in DMA)
587                         return;
588
589 #ifdef PSXHW_LOG
590                 case 0x1f801090:
591                         PSXHW_LOG("DMA1 MADR 32bit write %x\n", value);
592                         HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr
593                 case 0x1f801094:
594                         PSXHW_LOG("DMA1 BCR 32bit write %x\n", value);
595                         HW_DMA1_BCR  = SWAPu32(value); return; // DMA1 bcr
596 #endif
597                 case 0x1f801098:
598 #ifdef PSXHW_LOG
599                         PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value);
600 #endif
601                         DmaExec(1);                  // DMA1 chcr (MDEC out DMA)
602                         return;
603
604 #ifdef PSXHW_LOG
605                 case 0x1f8010a0:
606                         PSXHW_LOG("DMA2 MADR 32bit write %x\n", value);
607                         HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr
608                 case 0x1f8010a4:
609                         PSXHW_LOG("DMA2 BCR 32bit write %x\n", value);
610                         HW_DMA2_BCR  = SWAPu32(value); return; // DMA2 bcr
611 #endif
612                 case 0x1f8010a8:
613 #ifdef PSXHW_LOG
614                         PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value);
615 #endif
616                         DmaExec(2);                  // DMA2 chcr (GPU DMA)
617                         return;
618
619 #ifdef PSXHW_LOG
620                 case 0x1f8010b0:
621                         PSXHW_LOG("DMA3 MADR 32bit write %x\n", value);
622                         HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr
623                 case 0x1f8010b4:
624                         PSXHW_LOG("DMA3 BCR 32bit write %x\n", value);
625                         HW_DMA3_BCR  = SWAPu32(value); return; // DMA3 bcr
626 #endif
627                 case 0x1f8010b8:
628 #ifdef PSXHW_LOG
629                         PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value);
630 #endif
631                         DmaExec(3);                  // DMA3 chcr (CDROM DMA)
632                         
633                         return;
634
635 #ifdef PSXHW_LOG
636                 case 0x1f8010c0:
637                         PSXHW_LOG("DMA4 MADR 32bit write %x\n", value);
638                         HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr
639                 case 0x1f8010c4:
640                         PSXHW_LOG("DMA4 BCR 32bit write %x\n", value);
641                         HW_DMA4_BCR  = SWAPu32(value); return; // DMA4 bcr
642 #endif
643                 case 0x1f8010c8:
644 #ifdef PSXHW_LOG
645                         PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value);
646 #endif
647                         DmaExec(4);                  // DMA4 chcr (SPU DMA)
648                         return;
649
650 #if 0
651                 case 0x1f8010d0: break; //DMA5write_madr();
652                 case 0x1f8010d4: break; //DMA5write_bcr();
653                 case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed
654 #endif
655
656 #ifdef PSXHW_LOG
657                 case 0x1f8010e0:
658                         PSXHW_LOG("DMA6 MADR 32bit write %x\n", value);
659                         HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr
660                 case 0x1f8010e4:
661                         PSXHW_LOG("DMA6 BCR 32bit write %x\n", value);
662                         HW_DMA6_BCR  = SWAPu32(value); return; // DMA6 bcr
663 #endif
664                 case 0x1f8010e8:
665 #ifdef PSXHW_LOG
666                         PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value);
667 #endif
668                         DmaExec(6);                   // DMA6 chcr (OT clear)
669                         return;
670
671 #ifdef PSXHW_LOG
672                 case 0x1f8010f0:
673                         PSXHW_LOG("DMA PCR 32bit write %x\n", value);
674                         HW_DMA_PCR = SWAPu32(value);
675                         return;
676 #endif
677
678                 case 0x1f8010f4:
679 #ifdef PSXHW_LOG
680                         PSXHW_LOG("DMA ICR 32bit write %x\n", value);
681 #endif
682                 {
683                         u32 tmp = value & 0x00ff803f;
684                         tmp |= (SWAPu32(HW_DMA_ICR) & ~value) & 0x7f000000;
685                         if ((tmp & HW_DMA_ICR_GLOBAL_ENABLE && tmp & 0x7f000000)
686                             || tmp & HW_DMA_ICR_BUS_ERROR) {
687                                 if (!(SWAPu32(HW_DMA_ICR) & HW_DMA_ICR_IRQ_SENT))
688                                         psxHu32ref(0x1070) |= SWAP32(8);
689                                 tmp |= HW_DMA_ICR_IRQ_SENT;
690                         }
691                         HW_DMA_ICR = SWAPu32(tmp);
692                         return;
693                 }
694
695                 case 0x1f801810:
696 #ifdef PSXHW_LOG
697                         PSXHW_LOG("GPU DATA 32bit write %x\n", value);
698 #endif
699                         GPU_writeData(value); return;
700                 case 0x1f801814:
701 #ifdef PSXHW_LOG
702                         PSXHW_LOG("GPU STATUS 32bit write %x\n", value);
703 #endif
704                         GPU_writeStatus(value);
705                         gpuSyncPluginSR();
706                         return;
707
708                 case 0x1f801820:
709                         mdecWrite0(value); break;
710                 case 0x1f801824:
711                         mdecWrite1(value); break;
712
713                 case 0x1f801100:
714 #ifdef PSXHW_LOG
715                         PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value);
716 #endif
717                         psxRcntWcount(0, value & 0xffff); return;
718                 case 0x1f801104:
719 #ifdef PSXHW_LOG
720                         PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value);
721 #endif
722                         psxRcntWmode(0, value); return;
723                 case 0x1f801108:
724 #ifdef PSXHW_LOG
725                         PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value);
726 #endif
727                         psxRcntWtarget(0, value & 0xffff); return; //  HW_DMA_ICR&= SWAP32((~value)&0xff000000);
728
729                 case 0x1f801110:
730 #ifdef PSXHW_LOG
731                         PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value);
732 #endif
733                         psxRcntWcount(1, value & 0xffff); return;
734                 case 0x1f801114:
735 #ifdef PSXHW_LOG
736                         PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value);
737 #endif
738                         psxRcntWmode(1, value); return;
739                 case 0x1f801118:
740 #ifdef PSXHW_LOG
741                         PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value);
742 #endif
743                         psxRcntWtarget(1, value & 0xffff); return;
744
745                 case 0x1f801120:
746 #ifdef PSXHW_LOG
747                         PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value);
748 #endif
749                         psxRcntWcount(2, value & 0xffff); return;
750                 case 0x1f801124:
751 #ifdef PSXHW_LOG
752                         PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value);
753 #endif
754                         psxRcntWmode(2, value); return;
755                 case 0x1f801128:
756 #ifdef PSXHW_LOG
757                         PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value);
758 #endif
759                         psxRcntWtarget(2, value & 0xffff); return;
760
761                 default:
762                         // Dukes of Hazard 2 - car engine noise
763                         if (add>=0x1f801c00 && add<0x1f801e00) {
764                                 SPU_writeRegister(add, value&0xffff, psxRegs.cycle);
765                                 SPU_writeRegister(add + 2, value>>16, psxRegs.cycle);
766                                 return;
767                         }
768
769                         psxHu32ref(add) = SWAPu32(value);
770 #ifdef PSXHW_LOG
771                         PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value);
772 #endif
773                         return;
774         }
775         psxHu32ref(add) = SWAPu32(value);
776 #ifdef PSXHW_LOG
777         PSXHW_LOG("*Known 32bit write at address %x value %x\n", add, value);
778 #endif
779 }
780
781 int psxHwFreeze(void *f, int Mode) {
782         return 0;
783 }