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