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