refactor OSD code and PCNT stuff
[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                         if (psxHu16ref(0x1070) & value)
435                                 new_dyna_set_event(6, 1);
436                         return;
437
438                 case 0x1f801100:
439 #ifdef PSXHW_LOG
440                         PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value);
441 #endif
442                         psxRcntWcount(0, value); return;
443                 case 0x1f801104:
444 #ifdef PSXHW_LOG
445                         PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value);
446 #endif
447                         psxRcntWmode(0, value); return;
448                 case 0x1f801108:
449 #ifdef PSXHW_LOG
450                         PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value);
451 #endif
452                         psxRcntWtarget(0, value); return;
453
454                 case 0x1f801110:
455 #ifdef PSXHW_LOG
456                         PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value);
457 #endif
458                         psxRcntWcount(1, value); return;
459                 case 0x1f801114:
460 #ifdef PSXHW_LOG
461                         PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value);
462 #endif
463                         psxRcntWmode(1, value); return;
464                 case 0x1f801118:
465 #ifdef PSXHW_LOG
466                         PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value);
467 #endif
468                         psxRcntWtarget(1, value); return;
469
470                 case 0x1f801120:
471 #ifdef PSXHW_LOG
472                         PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value);
473 #endif
474                         psxRcntWcount(2, value); return;
475                 case 0x1f801124:
476 #ifdef PSXHW_LOG
477                         PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value);
478 #endif
479                         psxRcntWmode(2, value); return;
480                 case 0x1f801128:
481 #ifdef PSXHW_LOG
482                         PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value);
483 #endif
484                         psxRcntWtarget(2, value); return;
485
486                 default:
487                         if (add>=0x1f801c00 && add<0x1f801e00) {
488                 SPU_writeRegister(add, value);
489                                 return;
490                         }
491
492                         psxHu16ref(add) = SWAPu16(value);
493 #ifdef PSXHW_LOG
494                         PSXHW_LOG("*Unknown 16bit write at address %x value %x\n", add, value);
495 #endif
496                         return;
497         }
498         psxHu16ref(add) = SWAPu16(value);
499 #ifdef PSXHW_LOG
500         PSXHW_LOG("*Known 16bit write at address %x value %x\n", add, value);
501 #endif
502 }
503
504 #define DmaExec(n) { \
505         HW_DMA##n##_CHCR = SWAPu32(value); \
506 \
507         if (SWAPu32(HW_DMA##n##_CHCR) & 0x01000000 && SWAPu32(HW_DMA_PCR) & (8 << (n * 4))) { \
508                 psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), SWAPu32(HW_DMA##n##_CHCR)); \
509         } \
510 }
511
512 void psxHwWrite32(u32 add, u32 value) {
513         switch (add) {
514             case 0x1f801040:
515                         sioWrite8((unsigned char)value);
516                         sioWrite8((unsigned char)((value&0xff) >>  8));
517                         sioWrite8((unsigned char)((value&0xff) >> 16));
518                         sioWrite8((unsigned char)((value&0xff) >> 24));
519 #ifdef PAD_LOG
520                         PAD_LOG("sio write32 %x\n", value);
521 #endif
522                         return;\r
523 #ifdef ENABLE_SIO1API
524                 case 0x1f801050:
525                         SIO1_writeData32(value);
526                         return;\r
527 #endif
528 #ifdef PSXHW_LOG
529                 case 0x1f801060:
530                         PSXHW_LOG("RAM size write %x\n", value);
531                         psxHu32ref(add) = SWAPu32(value);
532                         return; // Ram size
533 #endif
534
535                 case 0x1f801070: 
536 #ifdef PSXHW_LOG
537                         PSXHW_LOG("IREG 32bit write %x\n", value);
538 #endif
539                         if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80);
540                         if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200);
541                         psxHu32ref(0x1070) &= SWAPu32((psxHu32(0x1074) & value));
542                         return;
543                 case 0x1f801074:
544 #ifdef PSXHW_LOG
545                         PSXHW_LOG("IMASK 32bit write %x\n", value);
546 #endif
547                         psxHu32ref(0x1074) = SWAPu32(value);
548                         if (psxHu32ref(0x1070) & value)
549                                 new_dyna_set_event(6, 1);
550                         return;
551
552 #ifdef PSXHW_LOG
553                 case 0x1f801080:
554                         PSXHW_LOG("DMA0 MADR 32bit write %x\n", value);
555                         HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr
556                 case 0x1f801084:
557                         PSXHW_LOG("DMA0 BCR 32bit write %x\n", value);
558                         HW_DMA0_BCR  = SWAPu32(value); return; // DMA0 bcr
559 #endif
560                 case 0x1f801088:
561 #ifdef PSXHW_LOG
562                         PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value);
563 #endif
564                         DmaExec(0);                      // DMA0 chcr (MDEC in DMA)
565                         return;
566
567 #ifdef PSXHW_LOG
568                 case 0x1f801090:
569                         PSXHW_LOG("DMA1 MADR 32bit write %x\n", value);
570                         HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr
571                 case 0x1f801094:
572                         PSXHW_LOG("DMA1 BCR 32bit write %x\n", value);
573                         HW_DMA1_BCR  = SWAPu32(value); return; // DMA1 bcr
574 #endif
575                 case 0x1f801098:
576 #ifdef PSXHW_LOG
577                         PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value);
578 #endif
579                         DmaExec(1);                  // DMA1 chcr (MDEC out DMA)
580                         return;
581
582 #ifdef PSXHW_LOG
583                 case 0x1f8010a0:
584                         PSXHW_LOG("DMA2 MADR 32bit write %x\n", value);
585                         HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr
586                 case 0x1f8010a4:
587                         PSXHW_LOG("DMA2 BCR 32bit write %x\n", value);
588                         HW_DMA2_BCR  = SWAPu32(value); return; // DMA2 bcr
589 #endif
590                 case 0x1f8010a8:
591 #ifdef PSXHW_LOG
592                         PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value);
593 #endif
594                         DmaExec(2);                  // DMA2 chcr (GPU DMA)
595                         return;
596
597 #ifdef PSXHW_LOG
598                 case 0x1f8010b0:
599                         PSXHW_LOG("DMA3 MADR 32bit write %x\n", value);
600                         HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr
601                 case 0x1f8010b4:
602                         PSXHW_LOG("DMA3 BCR 32bit write %x\n", value);
603                         HW_DMA3_BCR  = SWAPu32(value); return; // DMA3 bcr
604 #endif
605                 case 0x1f8010b8:
606 #ifdef PSXHW_LOG
607                         PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value);
608 #endif
609                         DmaExec(3);                  // DMA3 chcr (CDROM DMA)
610                         
611                         return;
612
613 #ifdef PSXHW_LOG
614                 case 0x1f8010c0:
615                         PSXHW_LOG("DMA4 MADR 32bit write %x\n", value);
616                         HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr
617                 case 0x1f8010c4:
618                         PSXHW_LOG("DMA4 BCR 32bit write %x\n", value);
619                         HW_DMA4_BCR  = SWAPu32(value); return; // DMA4 bcr
620 #endif
621                 case 0x1f8010c8:
622 #ifdef PSXHW_LOG
623                         PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value);
624 #endif
625                         DmaExec(4);                  // DMA4 chcr (SPU DMA)
626                         return;
627
628 #if 0
629                 case 0x1f8010d0: break; //DMA5write_madr();
630                 case 0x1f8010d4: break; //DMA5write_bcr();
631                 case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed
632 #endif
633
634 #ifdef PSXHW_LOG
635                 case 0x1f8010e0:
636                         PSXHW_LOG("DMA6 MADR 32bit write %x\n", value);
637                         HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr
638                 case 0x1f8010e4:
639                         PSXHW_LOG("DMA6 BCR 32bit write %x\n", value);
640                         HW_DMA6_BCR  = SWAPu32(value); return; // DMA6 bcr
641 #endif
642                 case 0x1f8010e8:
643 #ifdef PSXHW_LOG
644                         PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value);
645 #endif
646                         DmaExec(6);                   // DMA6 chcr (OT clear)
647                         return;
648
649 #ifdef PSXHW_LOG
650                 case 0x1f8010f0:
651                         PSXHW_LOG("DMA PCR 32bit write %x\n", value);
652                         HW_DMA_PCR = SWAPu32(value);
653                         return;
654 #endif
655
656                 case 0x1f8010f4:
657 #ifdef PSXHW_LOG
658                         PSXHW_LOG("DMA ICR 32bit write %x\n", value);
659 #endif
660                 {
661                         u32 tmp = (~value) & SWAPu32(HW_DMA_ICR);
662                         HW_DMA_ICR = SWAPu32(((tmp ^ value) & 0xffffff) ^ tmp);
663                         return;
664                 }
665
666                 case 0x1f801810:
667 #ifdef PSXHW_LOG
668                         PSXHW_LOG("GPU DATA 32bit write %x\n", value);
669 #endif
670                         GPU_writeData(value); return;
671                 case 0x1f801814:
672 #ifdef PSXHW_LOG
673                         PSXHW_LOG("GPU STATUS 32bit write %x\n", value);
674 #endif
675                         GPU_writeStatus(value); return;
676
677                 case 0x1f801820:
678                         mdecWrite0(value); break;
679                 case 0x1f801824:
680                         mdecWrite1(value); break;
681
682                 case 0x1f801100:
683 #ifdef PSXHW_LOG
684                         PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value);
685 #endif
686                         psxRcntWcount(0, value & 0xffff); return;
687                 case 0x1f801104:
688 #ifdef PSXHW_LOG
689                         PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value);
690 #endif
691                         psxRcntWmode(0, value); return;
692                 case 0x1f801108:
693 #ifdef PSXHW_LOG
694                         PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value);
695 #endif
696                         psxRcntWtarget(0, value & 0xffff); return; //  HW_DMA_ICR&= SWAP32((~value)&0xff000000);
697
698                 case 0x1f801110:
699 #ifdef PSXHW_LOG
700                         PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value);
701 #endif
702                         psxRcntWcount(1, value & 0xffff); return;
703                 case 0x1f801114:
704 #ifdef PSXHW_LOG
705                         PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value);
706 #endif
707                         psxRcntWmode(1, value); return;
708                 case 0x1f801118:
709 #ifdef PSXHW_LOG
710                         PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value);
711 #endif
712                         psxRcntWtarget(1, value & 0xffff); return;
713
714                 case 0x1f801120:
715 #ifdef PSXHW_LOG
716                         PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value);
717 #endif
718                         psxRcntWcount(2, value & 0xffff); return;
719                 case 0x1f801124:
720 #ifdef PSXHW_LOG
721                         PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value);
722 #endif
723                         psxRcntWmode(2, value); return;
724                 case 0x1f801128:
725 #ifdef PSXHW_LOG
726                         PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value);
727 #endif
728                         psxRcntWtarget(2, value & 0xffff); return;
729
730                 default:
731                         psxHu32ref(add) = SWAPu32(value);
732 #ifdef PSXHW_LOG
733                         PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value);
734 #endif
735                         return;
736         }
737         psxHu32ref(add) = SWAPu32(value);
738 #ifdef PSXHW_LOG
739         PSXHW_LOG("*Known 32bit write at address %x value %x\n", add, value);
740 #endif
741 }
742
743 int psxHwFreeze(gzFile f, int Mode) {
744         return 0;
745 }