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