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