483f4962d7b7bb2b0ae394553de8dca0bfb47b72
[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         memset(psxH, 0, 0x10000);
34
35         mdecInit(); // initialize mdec decoder
36         cdrReset();
37         psxRcntInit();
38         HW_GPU_STATUS = SWAP32(0x14802000);
39 }
40
41 u8 psxHwRead8(u32 add) {
42         unsigned char hard;
43
44         switch (add & 0x1fffffff) {
45                 case 0x1f801040: hard = sioRead8();break; \r
46 #ifdef ENABLE_SIO1API
47                 case 0x1f801050: hard = SIO1_readData8(); break;\r
48 #endif
49                 case 0x1f801800: hard = cdrRead0(); break;
50                 case 0x1f801801: hard = cdrRead1(); break;
51                 case 0x1f801802: hard = cdrRead2(); break;
52                 case 0x1f801803: hard = cdrRead3(); break;
53                 default:
54                         hard = psxHu8(add); 
55 #ifdef PSXHW_LOG
56                         PSXHW_LOG("*Unkwnown 8bit read at address %x\n", add);
57 #endif
58                         return hard;
59         }
60
61 #ifdef PSXHW_LOG
62         PSXHW_LOG("*Known 8bit read at address %x value %x\n", add, hard);
63 #endif
64         return hard;
65 }
66
67 u16 psxHwRead16(u32 add) {
68         unsigned short hard;
69
70         switch (add & 0x1fffffff) {
71 #ifdef PSXHW_LOG
72                 case 0x1f801070: PSXHW_LOG("IREG 16bit read %x\n", psxHu16(0x1070));
73                         return psxHu16(0x1070);
74 #endif
75 #ifdef PSXHW_LOG
76                 case 0x1f801074: PSXHW_LOG("IMASK 16bit read %x\n", psxHu16(0x1074));
77                         return psxHu16(0x1074);
78 #endif
79
80                 case 0x1f801040:
81                         hard = sioRead8();
82                         hard|= sioRead8() << 8;
83 #ifdef PAD_LOG
84                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
85 #endif
86                         return hard;
87                 case 0x1f801044:
88                         hard = sioReadStat16();
89 #ifdef PAD_LOG
90                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
91 #endif
92                         return hard;
93                 case 0x1f801048:
94                         hard = sioReadMode16();
95 #ifdef PAD_LOG
96                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
97 #endif
98                         return hard;
99                 case 0x1f80104a:
100                         hard = sioReadCtrl16();
101 #ifdef PAD_LOG
102                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
103 #endif
104                         return hard;
105                 case 0x1f80104e:
106                         hard = sioReadBaud16();
107 #ifdef PAD_LOG
108                         PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard);
109 #endif
110                         return hard;\r
111 #ifdef ENABLE_SIO1API
112                 case 0x1f801050:
113                         hard = SIO1_readData16();
114                         return hard;
115                 case 0x1f801054:
116                         hard = SIO1_readStat16();
117                         return hard;
118                 case 0x1f80105a:
119                         hard = SIO1_readCtrl16();
120                         return hard;
121                 case 0x1f80105e:
122                         hard = SIO1_readBaud16();
123                         return hard;
124 #else
125                 /* Fixes Armored Core misdetecting the Link cable being detected.
126                  * We want to turn that thing off and force it to do local multiplayer instead.
127                  * Thanks Sony for the fix, they fixed it in their PS Classic fork.
128                  */
129                 case 0x1f801054:
130                         return 0x80;\r
131 #endif
132                 case 0x1f801100:
133                         hard = psxRcntRcount(0);
134 #ifdef PSXHW_LOG
135                         PSXHW_LOG("T0 count read16: %x\n", hard);
136 #endif
137                         return hard;
138                 case 0x1f801104:
139                         hard = psxRcntRmode(0);
140 #ifdef PSXHW_LOG
141                         PSXHW_LOG("T0 mode read16: %x\n", hard);
142 #endif
143                         return hard;
144                 case 0x1f801108:
145                         hard = psxRcntRtarget(0);
146 #ifdef PSXHW_LOG
147                         PSXHW_LOG("T0 target read16: %x\n", hard);
148 #endif
149                         return hard;
150                 case 0x1f801110:
151                         hard = psxRcntRcount(1);
152 #ifdef PSXHW_LOG
153                         PSXHW_LOG("T1 count read16: %x\n", hard);
154 #endif
155                         return hard;
156                 case 0x1f801114:
157                         hard = psxRcntRmode(1);
158 #ifdef PSXHW_LOG
159                         PSXHW_LOG("T1 mode read16: %x\n", hard);
160 #endif
161                         return hard;
162                 case 0x1f801118:
163                         hard = psxRcntRtarget(1);
164 #ifdef PSXHW_LOG
165                         PSXHW_LOG("T1 target read16: %x\n", hard);
166 #endif
167                         return hard;
168                 case 0x1f801120:
169                         hard = psxRcntRcount(2);
170 #ifdef PSXHW_LOG
171                         PSXHW_LOG("T2 count read16: %x\n", hard);
172 #endif
173                         return hard;
174                 case 0x1f801124:
175                         hard = psxRcntRmode(2);
176 #ifdef PSXHW_LOG
177                         PSXHW_LOG("T2 mode read16: %x\n", hard);
178 #endif
179                         return hard;
180                 case 0x1f801128:
181                         hard = psxRcntRtarget(2);
182 #ifdef PSXHW_LOG
183                         PSXHW_LOG("T2 target read16: %x\n", hard);
184 #endif
185                         return hard;
186
187                 //case 0x1f802030: hard =   //int_2000????
188                 //case 0x1f802040: hard =//dip switches...??
189
190                 case 0x1f801800:
191                 case 0x1f801802:
192                         log_unhandled("cdrom r16 %x\n", add);
193                         // falthrough
194                 default:
195                         if (add >= 0x1f801c00 && add < 0x1f801e00) {
196                 hard = SPU_readRegister(add);
197                         } else {
198                                 hard = psxHu16(add); 
199 #ifdef PSXHW_LOG
200                                 PSXHW_LOG("*Unkwnown 16bit read at address %x\n", add);
201 #endif
202                         }
203             return hard;
204         }
205         
206 #ifdef PSXHW_LOG
207         PSXHW_LOG("*Known 16bit read at address %x value %x\n", add, hard);
208 #endif
209         return hard;
210 }
211
212 u32 psxHwRead32(u32 add) {
213         u32 hard;
214
215         switch (add & 0x1fffffff) {
216                 case 0x1f801040:
217                         hard = sioRead8();
218                         hard |= sioRead8() << 8;
219                         hard |= sioRead8() << 16;
220                         hard |= sioRead8() << 24;
221 #ifdef PAD_LOG
222                         PAD_LOG("sio read32 ;ret = %x\n", hard);
223 #endif
224                         return hard;\r
225 #ifdef ENABLE_SIO1API
226                 case 0x1f801050:
227                         hard = SIO1_readData32();
228                         return hard;\r
229 #endif
230 #ifdef PSXHW_LOG
231                 case 0x1f801060:
232                         PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060));
233                         return psxHu32(0x1060);
234 #endif
235 #ifdef PSXHW_LOG
236                 case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070));
237                         return psxHu32(0x1070);
238 #endif
239 #ifdef PSXHW_LOG
240                 case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074));
241                         return psxHu32(0x1074);
242 #endif
243
244                 case 0x1f801810:
245                         hard = GPU_readData();
246 #ifdef PSXHW_LOG
247                         PSXHW_LOG("GPU DATA 32bit read %x\n", hard);
248 #endif
249                         return hard;
250                 case 0x1f801814:
251                         gpuSyncPluginSR();
252                         hard = SWAP32(HW_GPU_STATUS);
253                         if (hSyncCount < 240 && (hard & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS)
254                                 hard |= PSXGPU_LCF & (psxRegs.cycle << 20);
255 #ifdef PSXHW_LOG
256                         PSXHW_LOG("GPU STATUS 32bit read %x\n", hard);
257 #endif
258                         return hard;
259
260                 case 0x1f801820: hard = mdecRead0(); break;
261                 case 0x1f801824: hard = mdecRead1(); break;
262
263 #ifdef PSXHW_LOG
264                 case 0x1f8010a0:
265                         PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0));
266                         return SWAPu32(HW_DMA2_MADR);
267                 case 0x1f8010a4:
268                         PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4));
269                         return SWAPu32(HW_DMA2_BCR);
270                 case 0x1f8010a8:
271                         PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8));
272                         return SWAPu32(HW_DMA2_CHCR);
273 #endif
274
275 #ifdef PSXHW_LOG
276                 case 0x1f8010b0:
277                         PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0));
278                         return SWAPu32(HW_DMA3_MADR);
279                 case 0x1f8010b4:
280                         PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4));
281                         return SWAPu32(HW_DMA3_BCR);
282                 case 0x1f8010b8:
283                         PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8));
284                         return SWAPu32(HW_DMA3_CHCR);
285 #endif
286
287 #ifdef PSXHW_LOG
288 /*              case 0x1f8010f0:
289                         PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0));
290                         return SWAPu32(HW_DMA_PCR); // dma rest channel
291                 case 0x1f8010f4:
292                         PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4));
293                         return SWAPu32(HW_DMA_ICR); // interrupt enabler?*/
294 #endif
295
296                 // time for rootcounters :)
297                 case 0x1f801100:
298                         hard = psxRcntRcount(0);
299 #ifdef PSXHW_LOG
300                         PSXHW_LOG("T0 count read32: %x\n", hard);
301 #endif
302                         return hard;
303                 case 0x1f801104:
304                         hard = psxRcntRmode(0);
305 #ifdef PSXHW_LOG
306                         PSXHW_LOG("T0 mode read32: %x\n", hard);
307 #endif
308                         return hard;
309                 case 0x1f801108:
310                         hard = psxRcntRtarget(0);
311 #ifdef PSXHW_LOG
312                         PSXHW_LOG("T0 target read32: %x\n", hard);
313 #endif
314                         return hard;
315                 case 0x1f801110:
316                         hard = psxRcntRcount(1);
317 #ifdef PSXHW_LOG
318                         PSXHW_LOG("T1 count read32: %x\n", hard);
319 #endif
320                         return hard;
321                 case 0x1f801114:
322                         hard = psxRcntRmode(1);
323 #ifdef PSXHW_LOG
324                         PSXHW_LOG("T1 mode read32: %x\n", hard);
325 #endif
326                         return hard;
327                 case 0x1f801118:
328                         hard = psxRcntRtarget(1);
329 #ifdef PSXHW_LOG
330                         PSXHW_LOG("T1 target read32: %x\n", hard);
331 #endif
332                         return hard;
333                 case 0x1f801120:
334                         hard = psxRcntRcount(2);
335 #ifdef PSXHW_LOG
336                         PSXHW_LOG("T2 count read32: %x\n", hard);
337 #endif
338                         return hard;
339                 case 0x1f801124:
340                         hard = psxRcntRmode(2);
341 #ifdef PSXHW_LOG
342                         PSXHW_LOG("T2 mode read32: %x\n", hard);
343 #endif
344                         return hard;
345                 case 0x1f801128:
346                         hard = psxRcntRtarget(2);
347 #ifdef PSXHW_LOG
348                         PSXHW_LOG("T2 target read32: %x\n", hard);
349 #endif
350                         return hard;
351
352                 case 0x1f801800:
353                         log_unhandled("cdrom r32 %x\n", add);
354                         // falthrough
355                 default:
356                         hard = psxHu32(add); 
357 #ifdef PSXHW_LOG
358                         PSXHW_LOG("*Unkwnown 32bit read at address %x\n", add);
359 #endif
360                         return hard;
361         }
362 #ifdef PSXHW_LOG
363         PSXHW_LOG("*Known 32bit read at address %x\n", add);
364 #endif
365         return hard;
366 }
367
368 void psxHwWrite8(u32 add, u8 value) {
369         switch (add & 0x1fffffff) {
370                 case 0x1f801040: sioWrite8(value); break;\r
371 #ifdef ENABLE_SIO1API
372                 case 0x1f801050: SIO1_writeData8(value); break;\r
373 #endif
374                 case 0x1f801800: cdrWrite0(value); break;
375                 case 0x1f801801: cdrWrite1(value); break;
376                 case 0x1f801802: cdrWrite2(value); break;
377                 case 0x1f801803: cdrWrite3(value); break;
378
379                 default:
380                         psxHu8(add) = value;
381 #ifdef PSXHW_LOG
382                         PSXHW_LOG("*Unknown 8bit write at address %x value %x\n", add, value);
383 #endif
384                         return;
385         }
386         psxHu8(add) = value;
387 #ifdef PSXHW_LOG
388         PSXHW_LOG("*Known 8bit write at address %x value %x\n", add, value);
389 #endif
390 }
391
392 void psxHwWrite16(u32 add, u16 value) {
393         switch (add & 0x1fffffff) {
394                 case 0x1f801040:
395                         sioWrite8((unsigned char)value);
396                         sioWrite8((unsigned char)(value>>8));
397 #ifdef PAD_LOG
398                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
399 #endif
400                         return;
401                 case 0x1f801044:
402                         sioWriteStat16(value);
403 #ifdef PAD_LOG
404                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
405 #endif
406                         return;
407                 case 0x1f801048:
408             sioWriteMode16(value);
409 #ifdef PAD_LOG
410                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
411 #endif
412                         return;
413                 case 0x1f80104a: // control register
414                         sioWriteCtrl16(value);
415 #ifdef PAD_LOG
416                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
417 #endif
418                         return;
419                 case 0x1f80104e: // baudrate register
420             sioWriteBaud16(value);
421 #ifdef PAD_LOG
422                         PAD_LOG ("sio write16 %x, %x\n", add&0xf, value);
423 #endif
424                         return;\r
425 #ifdef ENABLE_SIO1API
426                 case 0x1f801050:
427                         SIO1_writeData16(value);
428                         return;
429                 case 0x1f801054:
430                         SIO1_writeStat16(value);
431                         return;
432                 case 0x1f80105a:
433                         SIO1_writeCtrl16(value);
434                         return;
435                 case 0x1f80105e:
436                         SIO1_writeBaud16(value);
437                         return;\r
438 #endif
439                 case 0x1f801070: 
440 #ifdef PSXHW_LOG
441                         PSXHW_LOG("IREG 16bit write %x\n", value);
442 #endif
443                         psxHu16ref(0x1070) &= SWAPu16(value);
444                         return;
445
446                 case 0x1f801074:
447 #ifdef PSXHW_LOG
448                         PSXHW_LOG("IMASK 16bit write %x\n", value);
449 #endif
450                         psxHu16ref(0x1074) = SWAPu16(value);
451                         if (psxHu16ref(0x1070) & SWAPu16(value))
452                                 new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1);
453                         return;
454
455                 case 0x1f801100:
456 #ifdef PSXHW_LOG
457                         PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value);
458 #endif
459                         psxRcntWcount(0, value); return;
460                 case 0x1f801104:
461 #ifdef PSXHW_LOG
462                         PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value);
463 #endif
464                         psxRcntWmode(0, value); return;
465                 case 0x1f801108:
466 #ifdef PSXHW_LOG
467                         PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value);
468 #endif
469                         psxRcntWtarget(0, value); return;
470
471                 case 0x1f801110:
472 #ifdef PSXHW_LOG
473                         PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value);
474 #endif
475                         psxRcntWcount(1, value); return;
476                 case 0x1f801114:
477 #ifdef PSXHW_LOG
478                         PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value);
479 #endif
480                         psxRcntWmode(1, value); return;
481                 case 0x1f801118:
482 #ifdef PSXHW_LOG
483                         PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value);
484 #endif
485                         psxRcntWtarget(1, value); return;
486
487                 case 0x1f801120:
488 #ifdef PSXHW_LOG
489                         PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value);
490 #endif
491                         psxRcntWcount(2, value); return;
492                 case 0x1f801124:
493 #ifdef PSXHW_LOG
494                         PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value);
495 #endif
496                         psxRcntWmode(2, value); return;
497                 case 0x1f801128:
498 #ifdef PSXHW_LOG
499                         PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value);
500 #endif
501                         psxRcntWtarget(2, value); return;
502
503                 default:
504                         if (add>=0x1f801c00 && add<0x1f801e00) {
505                                 SPU_writeRegister(add, value, psxRegs.cycle);
506                                 return;
507                         }
508
509                         psxHu16ref(add) = SWAPu16(value);
510 #ifdef PSXHW_LOG
511                         PSXHW_LOG("*Unknown 16bit write at address %x value %x\n", add, value);
512 #endif
513                         return;
514         }
515         psxHu16ref(add) = SWAPu16(value);
516 #ifdef PSXHW_LOG
517         PSXHW_LOG("*Known 16bit write at address %x value %x\n", add, value);
518 #endif
519 }
520
521 #define DmaExec(n) { \
522         HW_DMA##n##_CHCR = SWAPu32(value); \
523 \
524         if (SWAPu32(HW_DMA##n##_CHCR) & 0x01000000 && SWAPu32(HW_DMA_PCR) & (8 << (n * 4))) { \
525                 psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), SWAPu32(HW_DMA##n##_CHCR)); \
526         } \
527 }
528
529 void psxHwWrite32(u32 add, u32 value) {
530         switch (add & 0x1fffffff) {
531             case 0x1f801040:
532                         sioWrite8((unsigned char)value);
533                         sioWrite8((unsigned char)((value&0xff) >>  8));
534                         sioWrite8((unsigned char)((value&0xff) >> 16));
535                         sioWrite8((unsigned char)((value&0xff) >> 24));
536 #ifdef PAD_LOG
537                         PAD_LOG("sio write32 %x\n", value);
538 #endif
539                         return;\r
540 #ifdef ENABLE_SIO1API
541                 case 0x1f801050:
542                         SIO1_writeData32(value);
543                         return;\r
544 #endif
545 #ifdef PSXHW_LOG
546                 case 0x1f801060:
547                         PSXHW_LOG("RAM size write %x\n", value);
548                         psxHu32ref(add) = SWAPu32(value);
549                         return; // Ram size
550 #endif
551
552                 case 0x1f801070: 
553 #ifdef PSXHW_LOG
554                         PSXHW_LOG("IREG 32bit write %x\n", value);
555 #endif
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) & SWAPu32(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 }