fix x86 build
[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 = 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                 default:
194                         if (add >= 0x1f801c00 && add < 0x1f801e00) {
195                 hard = SPU_readRegister(add);
196                         } else {
197                                 hard = psxHu16(add); 
198 #ifdef PSXHW_LOG
199                                 PSXHW_LOG("*Unkwnown 16bit read at address %x\n", add);
200 #endif
201                         }
202             return hard;
203         }
204         
205 #ifdef PSXHW_LOG
206         PSXHW_LOG("*Known 16bit read at address %x value %x\n", add, hard);
207 #endif
208         return hard;
209 }
210
211 u32 psxHwRead32(u32 add) {
212         u32 hard;
213
214         switch (add & 0x1fffffff) {
215                 case 0x1f801040:
216                         hard = sioRead8();
217                         hard |= sioRead8() << 8;
218                         hard |= sioRead8() << 16;
219                         hard |= sioRead8() << 24;
220 #ifdef PAD_LOG
221                         PAD_LOG("sio read32 ;ret = %x\n", hard);
222 #endif
223                         return hard;\r
224 #ifdef ENABLE_SIO1API
225                 case 0x1f801050:
226                         hard = SIO1_readData32();
227                         return hard;\r
228 #endif
229 #ifdef PSXHW_LOG
230                 case 0x1f801060:
231                         PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060));
232                         return psxHu32(0x1060);
233 #endif
234 #ifdef PSXHW_LOG
235                 case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070));
236                         return psxHu32(0x1070);
237 #endif
238 #ifdef PSXHW_LOG
239                 case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074));
240                         return psxHu32(0x1074);
241 #endif
242
243                 case 0x1f801810:
244                         hard = GPU_readData();
245 #ifdef PSXHW_LOG
246                         PSXHW_LOG("GPU DATA 32bit read %x\n", hard);
247 #endif
248                         return hard;
249                 case 0x1f801814:
250                         gpuSyncPluginSR();
251                         hard = HW_GPU_STATUS;
252                         if (hSyncCount < 240 && (HW_GPU_STATUS & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS)
253                                 hard |= PSXGPU_LCF & (psxRegs.cycle << 20);
254 #ifdef PSXHW_LOG
255                         PSXHW_LOG("GPU STATUS 32bit read %x\n", hard);
256 #endif
257                         return hard;
258
259                 case 0x1f801820: hard = mdecRead0(); break;
260                 case 0x1f801824: hard = mdecRead1(); break;
261
262 #ifdef PSXHW_LOG
263                 case 0x1f8010a0:
264                         PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0));
265                         return SWAPu32(HW_DMA2_MADR);
266                 case 0x1f8010a4:
267                         PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4));
268                         return SWAPu32(HW_DMA2_BCR);
269                 case 0x1f8010a8:
270                         PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8));
271                         return SWAPu32(HW_DMA2_CHCR);
272 #endif
273
274 #ifdef PSXHW_LOG
275                 case 0x1f8010b0:
276                         PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0));
277                         return SWAPu32(HW_DMA3_MADR);
278                 case 0x1f8010b4:
279                         PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4));
280                         return SWAPu32(HW_DMA3_BCR);
281                 case 0x1f8010b8:
282                         PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8));
283                         return SWAPu32(HW_DMA3_CHCR);
284 #endif
285
286 #ifdef PSXHW_LOG
287 /*              case 0x1f8010f0:
288                         PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0));
289                         return SWAPu32(HW_DMA_PCR); // dma rest channel
290                 case 0x1f8010f4:
291                         PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4));
292                         return SWAPu32(HW_DMA_ICR); // interrupt enabler?*/
293 #endif
294
295                 // time for rootcounters :)
296                 case 0x1f801100:
297                         hard = psxRcntRcount(0);
298 #ifdef PSXHW_LOG
299                         PSXHW_LOG("T0 count read32: %x\n", hard);
300 #endif
301                         return hard;
302                 case 0x1f801104:
303                         hard = psxRcntRmode(0);
304 #ifdef PSXHW_LOG
305                         PSXHW_LOG("T0 mode read32: %x\n", hard);
306 #endif
307                         return hard;
308                 case 0x1f801108:
309                         hard = psxRcntRtarget(0);
310 #ifdef PSXHW_LOG
311                         PSXHW_LOG("T0 target read32: %x\n", hard);
312 #endif
313                         return hard;
314                 case 0x1f801110:
315                         hard = psxRcntRcount(1);
316 #ifdef PSXHW_LOG
317                         PSXHW_LOG("T1 count read32: %x\n", hard);
318 #endif
319                         return hard;
320                 case 0x1f801114:
321                         hard = psxRcntRmode(1);
322 #ifdef PSXHW_LOG
323                         PSXHW_LOG("T1 mode read32: %x\n", hard);
324 #endif
325                         return hard;
326                 case 0x1f801118:
327                         hard = psxRcntRtarget(1);
328 #ifdef PSXHW_LOG
329                         PSXHW_LOG("T1 target read32: %x\n", hard);
330 #endif
331                         return hard;
332                 case 0x1f801120:
333                         hard = psxRcntRcount(2);
334 #ifdef PSXHW_LOG
335                         PSXHW_LOG("T2 count read32: %x\n", hard);
336 #endif
337                         return hard;
338                 case 0x1f801124:
339                         hard = psxRcntRmode(2);
340 #ifdef PSXHW_LOG
341                         PSXHW_LOG("T2 mode read32: %x\n", hard);
342 #endif
343                         return hard;
344                 case 0x1f801128:
345                         hard = psxRcntRtarget(2);
346 #ifdef PSXHW_LOG
347                         PSXHW_LOG("T2 target read32: %x\n", hard);
348 #endif
349                         return hard;
350
351                 default:
352                         hard = psxHu32(add); 
353 #ifdef PSXHW_LOG
354                         PSXHW_LOG("*Unkwnown 32bit read at address %x\n", add);
355 #endif
356                         return hard;
357         }
358 #ifdef PSXHW_LOG
359         PSXHW_LOG("*Known 32bit read at address %x\n", add);
360 #endif
361         return hard;
362 }
363
364 void psxHwWrite8(u32 add, u8 value) {
365         switch (add & 0x1fffffff) {
366                 case 0x1f801040: sioWrite8(value); break;\r
367 #ifdef ENABLE_SIO1API
368                 case 0x1f801050: SIO1_writeData8(value); break;\r
369 #endif
370                 case 0x1f801800: cdrWrite0(value); break;
371                 case 0x1f801801: cdrWrite1(value); break;
372                 case 0x1f801802: cdrWrite2(value); break;
373                 case 0x1f801803: cdrWrite3(value); break;
374
375                 default:
376                         psxHu8(add) = value;
377 #ifdef PSXHW_LOG
378                         PSXHW_LOG("*Unknown 8bit write at address %x value %x\n", add, value);
379 #endif
380                         return;
381         }
382         psxHu8(add) = value;
383 #ifdef PSXHW_LOG
384         PSXHW_LOG("*Known 8bit write at address %x value %x\n", add, value);
385 #endif
386 }
387
388 void psxHwWrite16(u32 add, u16 value) {
389         switch (add & 0x1fffffff) {
390                 case 0x1f801040:
391                         sioWrite8((unsigned char)value);
392                         sioWrite8((unsigned char)(value>>8));
393 #ifdef PAD_LOG
394                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
395 #endif
396                         return;
397                 case 0x1f801044:
398                         sioWriteStat16(value);
399 #ifdef PAD_LOG
400                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
401 #endif
402                         return;
403                 case 0x1f801048:
404             sioWriteMode16(value);
405 #ifdef PAD_LOG
406                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
407 #endif
408                         return;
409                 case 0x1f80104a: // control register
410                         sioWriteCtrl16(value);
411 #ifdef PAD_LOG
412                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
413 #endif
414                         return;
415                 case 0x1f80104e: // baudrate register
416             sioWriteBaud16(value);
417 #ifdef PAD_LOG
418                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
419 #endif
420                         return;\r
421 #ifdef ENABLE_SIO1API
422                 case 0x1f801050:
423                         SIO1_writeData16(value);
424                         return;
425                 case 0x1f801054:
426                         SIO1_writeStat16(value);
427                         return;
428                 case 0x1f80105a:
429                         SIO1_writeCtrl16(value);
430                         return;
431                 case 0x1f80105e:
432                         SIO1_writeBaud16(value);
433                         return;\r
434 #endif
435                 case 0x1f801070: 
436 #ifdef PSXHW_LOG
437                         PSXHW_LOG("IREG 16bit write %x\n", value);
438 #endif
439                         if (Config.Sio) psxHu16ref(0x1070) |= SWAPu16(0x80);
440                         if (Config.SpuIrq) psxHu16ref(0x1070) |= SWAPu16(0x200);
441                         psxHu16ref(0x1070) &= SWAPu16(value);
442                         return;
443
444                 case 0x1f801074:
445 #ifdef PSXHW_LOG
446                         PSXHW_LOG("IMASK 16bit write %x\n", value);
447 #endif
448                         psxHu16ref(0x1074) = SWAPu16(value);
449                         if (psxHu16ref(0x1070) & value)
450                                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
451                         return;
452
453                 case 0x1f801100:
454 #ifdef PSXHW_LOG
455                         PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value);
456 #endif
457                         psxRcntWcount(0, value); return;
458                 case 0x1f801104:
459 #ifdef PSXHW_LOG
460                         PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value);
461 #endif
462                         psxRcntWmode(0, value); return;
463                 case 0x1f801108:
464 #ifdef PSXHW_LOG
465                         PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value);
466 #endif
467                         psxRcntWtarget(0, value); return;
468
469                 case 0x1f801110:
470 #ifdef PSXHW_LOG
471                         PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value);
472 #endif
473                         psxRcntWcount(1, value); return;
474                 case 0x1f801114:
475 #ifdef PSXHW_LOG
476                         PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value);
477 #endif
478                         psxRcntWmode(1, value); return;
479                 case 0x1f801118:
480 #ifdef PSXHW_LOG
481                         PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value);
482 #endif
483                         psxRcntWtarget(1, value); return;
484
485                 case 0x1f801120:
486 #ifdef PSXHW_LOG
487                         PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value);
488 #endif
489                         psxRcntWcount(2, value); return;
490                 case 0x1f801124:
491 #ifdef PSXHW_LOG
492                         PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value);
493 #endif
494                         psxRcntWmode(2, value); return;
495                 case 0x1f801128:
496 #ifdef PSXHW_LOG
497                         PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value);
498 #endif
499                         psxRcntWtarget(2, value); return;
500
501                 default:
502                         if (add>=0x1f801c00 && add<0x1f801e00) {
503                                 SPU_writeRegister(add, value, psxRegs.cycle);
504                                 return;
505                         }
506
507                         psxHu16ref(add) = SWAPu16(value);
508 #ifdef PSXHW_LOG
509                         PSXHW_LOG("*Unknown 16bit write at address %x value %x\n", add, value);
510 #endif
511                         return;
512         }
513         psxHu16ref(add) = SWAPu16(value);
514 #ifdef PSXHW_LOG
515         PSXHW_LOG("*Known 16bit write at address %x value %x\n", add, value);
516 #endif
517 }
518
519 #define DmaExec(n) { \
520         HW_DMA##n##_CHCR = SWAPu32(value); \
521 \
522         if (SWAPu32(HW_DMA##n##_CHCR) & 0x01000000 && SWAPu32(HW_DMA_PCR) & (8 << (n * 4))) { \
523                 psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), SWAPu32(HW_DMA##n##_CHCR)); \
524         } \
525 }
526
527 void psxHwWrite32(u32 add, u32 value) {
528         switch (add & 0x1fffffff) {
529             case 0x1f801040:
530                         sioWrite8((unsigned char)value);
531                         sioWrite8((unsigned char)((value&0xff) >>  8));
532                         sioWrite8((unsigned char)((value&0xff) >> 16));
533                         sioWrite8((unsigned char)((value&0xff) >> 24));
534 #ifdef PAD_LOG
535                         PAD_LOG("sio write32 %x\n", value);
536 #endif
537                         return;\r
538 #ifdef ENABLE_SIO1API
539                 case 0x1f801050:
540                         SIO1_writeData32(value);
541                         return;\r
542 #endif
543 #ifdef PSXHW_LOG
544                 case 0x1f801060:
545                         PSXHW_LOG("RAM size write %x\n", value);
546                         psxHu32ref(add) = SWAPu32(value);
547                         return; // Ram size
548 #endif
549
550                 case 0x1f801070: 
551 #ifdef PSXHW_LOG
552                         PSXHW_LOG("IREG 32bit write %x\n", value);
553 #endif
554                         if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80);
555                         if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200);
556                         psxHu32ref(0x1070) &= SWAPu32(value);
557                         return;
558                 case 0x1f801074:
559 #ifdef PSXHW_LOG
560                         PSXHW_LOG("IMASK 32bit write %x\n", value);
561 #endif
562                         psxHu32ref(0x1074) = SWAPu32(value);
563                         if (psxHu32ref(0x1070) & value)
564                                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
565                         return;
566
567 #ifdef PSXHW_LOG
568                 case 0x1f801080:
569                         PSXHW_LOG("DMA0 MADR 32bit write %x\n", value);
570                         HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr
571                 case 0x1f801084:
572                         PSXHW_LOG("DMA0 BCR 32bit write %x\n", value);
573                         HW_DMA0_BCR  = SWAPu32(value); return; // DMA0 bcr
574 #endif
575                 case 0x1f801088:
576 #ifdef PSXHW_LOG
577                         PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value);
578 #endif
579                         DmaExec(0);                      // DMA0 chcr (MDEC in DMA)
580                         return;
581
582 #ifdef PSXHW_LOG
583                 case 0x1f801090:
584                         PSXHW_LOG("DMA1 MADR 32bit write %x\n", value);
585                         HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr
586                 case 0x1f801094:
587                         PSXHW_LOG("DMA1 BCR 32bit write %x\n", value);
588                         HW_DMA1_BCR  = SWAPu32(value); return; // DMA1 bcr
589 #endif
590                 case 0x1f801098:
591 #ifdef PSXHW_LOG
592                         PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value);
593 #endif
594                         DmaExec(1);                  // DMA1 chcr (MDEC out DMA)
595                         return;
596
597 #ifdef PSXHW_LOG
598                 case 0x1f8010a0:
599                         PSXHW_LOG("DMA2 MADR 32bit write %x\n", value);
600                         HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr
601                 case 0x1f8010a4:
602                         PSXHW_LOG("DMA2 BCR 32bit write %x\n", value);
603                         HW_DMA2_BCR  = SWAPu32(value); return; // DMA2 bcr
604 #endif
605                 case 0x1f8010a8:
606 #ifdef PSXHW_LOG
607                         PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value);
608 #endif
609                         DmaExec(2);                  // DMA2 chcr (GPU DMA)
610                         return;
611
612 #ifdef PSXHW_LOG
613                 case 0x1f8010b0:
614                         PSXHW_LOG("DMA3 MADR 32bit write %x\n", value);
615                         HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr
616                 case 0x1f8010b4:
617                         PSXHW_LOG("DMA3 BCR 32bit write %x\n", value);
618                         HW_DMA3_BCR  = SWAPu32(value); return; // DMA3 bcr
619 #endif
620                 case 0x1f8010b8:
621 #ifdef PSXHW_LOG
622                         PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value);
623 #endif
624                         DmaExec(3);                  // DMA3 chcr (CDROM DMA)
625                         
626                         return;
627
628 #ifdef PSXHW_LOG
629                 case 0x1f8010c0:
630                         PSXHW_LOG("DMA4 MADR 32bit write %x\n", value);
631                         HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr
632                 case 0x1f8010c4:
633                         PSXHW_LOG("DMA4 BCR 32bit write %x\n", value);
634                         HW_DMA4_BCR  = SWAPu32(value); return; // DMA4 bcr
635 #endif
636                 case 0x1f8010c8:
637 #ifdef PSXHW_LOG
638                         PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value);
639 #endif
640                         DmaExec(4);                  // DMA4 chcr (SPU DMA)
641                         return;
642
643 #if 0
644                 case 0x1f8010d0: break; //DMA5write_madr();
645                 case 0x1f8010d4: break; //DMA5write_bcr();
646                 case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed
647 #endif
648
649 #ifdef PSXHW_LOG
650                 case 0x1f8010e0:
651                         PSXHW_LOG("DMA6 MADR 32bit write %x\n", value);
652                         HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr
653                 case 0x1f8010e4:
654                         PSXHW_LOG("DMA6 BCR 32bit write %x\n", value);
655                         HW_DMA6_BCR  = SWAPu32(value); return; // DMA6 bcr
656 #endif
657                 case 0x1f8010e8:
658 #ifdef PSXHW_LOG
659                         PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value);
660 #endif
661                         DmaExec(6);                   // DMA6 chcr (OT clear)
662                         return;
663
664 #ifdef PSXHW_LOG
665                 case 0x1f8010f0:
666                         PSXHW_LOG("DMA PCR 32bit write %x\n", value);
667                         HW_DMA_PCR = SWAPu32(value);
668                         return;
669 #endif
670
671                 case 0x1f8010f4:
672 #ifdef PSXHW_LOG
673                         PSXHW_LOG("DMA ICR 32bit write %x\n", value);
674 #endif
675                 {
676                         u32 tmp = value & 0x00ff803f;
677                         tmp |= (SWAPu32(HW_DMA_ICR) & ~value) & 0x7f000000;
678                         if ((tmp & HW_DMA_ICR_GLOBAL_ENABLE && tmp & 0x7f000000)
679                             || tmp & HW_DMA_ICR_BUS_ERROR) {
680                                 if (!(SWAPu32(HW_DMA_ICR) & HW_DMA_ICR_IRQ_SENT))
681                                         psxHu32ref(0x1070) |= SWAP32(8);
682                                 tmp |= HW_DMA_ICR_IRQ_SENT;
683                         }
684                         HW_DMA_ICR = SWAPu32(tmp);
685                         return;
686                 }
687
688                 case 0x1f801810:
689 #ifdef PSXHW_LOG
690                         PSXHW_LOG("GPU DATA 32bit write %x\n", value);
691 #endif
692                         GPU_writeData(value); return;
693                 case 0x1f801814:
694 #ifdef PSXHW_LOG
695                         PSXHW_LOG("GPU STATUS 32bit write %x\n", value);
696 #endif
697                         GPU_writeStatus(value);
698                         gpuSyncPluginSR();
699                         return;
700
701                 case 0x1f801820:
702                         mdecWrite0(value); break;
703                 case 0x1f801824:
704                         mdecWrite1(value); break;
705
706                 case 0x1f801100:
707 #ifdef PSXHW_LOG
708                         PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value);
709 #endif
710                         psxRcntWcount(0, value & 0xffff); return;
711                 case 0x1f801104:
712 #ifdef PSXHW_LOG
713                         PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value);
714 #endif
715                         psxRcntWmode(0, value); return;
716                 case 0x1f801108:
717 #ifdef PSXHW_LOG
718                         PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value);
719 #endif
720                         psxRcntWtarget(0, value & 0xffff); return; //  HW_DMA_ICR&= SWAP32((~value)&0xff000000);
721
722                 case 0x1f801110:
723 #ifdef PSXHW_LOG
724                         PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value);
725 #endif
726                         psxRcntWcount(1, value & 0xffff); return;
727                 case 0x1f801114:
728 #ifdef PSXHW_LOG
729                         PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value);
730 #endif
731                         psxRcntWmode(1, value); return;
732                 case 0x1f801118:
733 #ifdef PSXHW_LOG
734                         PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value);
735 #endif
736                         psxRcntWtarget(1, value & 0xffff); return;
737
738                 case 0x1f801120:
739 #ifdef PSXHW_LOG
740                         PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value);
741 #endif
742                         psxRcntWcount(2, value & 0xffff); return;
743                 case 0x1f801124:
744 #ifdef PSXHW_LOG
745                         PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value);
746 #endif
747                         psxRcntWmode(2, value); return;
748                 case 0x1f801128:
749 #ifdef PSXHW_LOG
750                         PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value);
751 #endif
752                         psxRcntWtarget(2, value & 0xffff); return;
753
754                 default:
755                         // Dukes of Hazard 2 - car engine noise
756                         if (add>=0x1f801c00 && add<0x1f801e00) {
757                                 SPU_writeRegister(add, value&0xffff, psxRegs.cycle);
758                                 SPU_writeRegister(add + 2, value>>16, psxRegs.cycle);
759                                 return;
760                         }
761
762                         psxHu32ref(add) = SWAPu32(value);
763 #ifdef PSXHW_LOG
764                         PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value);
765 #endif
766                         return;
767         }
768         psxHu32ref(add) = SWAPu32(value);
769 #ifdef PSXHW_LOG
770         PSXHW_LOG("*Known 32bit write at address %x value %x\n", add, value);
771 #endif
772 }
773
774 int psxHwFreeze(void *f, int Mode) {
775         return 0;
776 }