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