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