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