drc: don't clear ARM caches on whole translation cache - it's very slow
[pcsx_rearmed.git] / libpcsxcore / psxdma.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 * Handles PSX DMA functions.
22 */
23
24 #include "psxdma.h"
25
26 // Dma0/1 in Mdec.c
27 // Dma3   in CdRom.c
28
29 void spuInterrupt() {
30         HW_DMA4_CHCR &= SWAP32(~0x01000000);
31         DMA_INTERRUPT(4);
32 }
33
34 void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
35         u16 *ptr;
36         u32 size;
37
38         switch (chcr) {
39                 case 0x01000201: //cpu to spu transfer
40 #ifdef PSXDMA_LOG
41                         PSXDMA_LOG("*** DMA4 SPU - mem2spu *** %x addr = %x size = %x\n", chcr, madr, bcr);
42 #endif
43                         ptr = (u16 *)PSXM(madr);
44                         if (ptr == NULL) {
45 #ifdef CPU_LOG
46                                 CPU_LOG("*** DMA4 SPU - mem2spu *** NULL Pointer!!!\n");
47 #endif
48                                 break;
49                         }
50                         SPU_writeDMAMem(ptr, (bcr >> 16) * (bcr & 0xffff) * 2);
51                         SPUDMA_INT((bcr >> 16) * (bcr & 0xffff) / 2);
52                         return;
53
54                 case 0x01000200: //spu to cpu transfer
55 #ifdef PSXDMA_LOG
56                         PSXDMA_LOG("*** DMA4 SPU - spu2mem *** %x addr = %x size = %x\n", chcr, madr, bcr);
57 #endif
58                         ptr = (u16 *)PSXM(madr);
59                         if (ptr == NULL) {
60 #ifdef CPU_LOG
61                                 CPU_LOG("*** DMA4 SPU - spu2mem *** NULL Pointer!!!\n");
62 #endif
63                                 break;
64                         }
65                         size = (bcr >> 16) * (bcr & 0xffff) * 2;
66                         SPU_readDMAMem(ptr, size);
67                         psxCpu->Clear(madr, size);
68                         break;
69
70 #ifdef PSXDMA_LOG
71                 default:
72                         PSXDMA_LOG("*** DMA4 SPU - unknown *** %x addr = %x size = %x\n", chcr, madr, bcr);
73                         break;
74 #endif
75         }
76
77         HW_DMA4_CHCR &= SWAP32(~0x01000000);
78         DMA_INTERRUPT(4);
79 }
80
81 void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
82         u32 *ptr;
83         u32 size;
84
85         switch(chcr) {
86                 case 0x01000200: // vram2mem
87 #ifdef PSXDMA_LOG
88                         PSXDMA_LOG("*** DMA2 GPU - vram2mem *** %x addr = %x size = %x\n", chcr, madr, bcr);
89 #endif
90                         ptr = (u32 *)PSXM(madr);
91                         if (ptr == NULL) {
92 #ifdef CPU_LOG
93                                 CPU_LOG("*** DMA2 GPU - vram2mem *** NULL Pointer!!!\n");
94 #endif
95                                 break;
96                         }
97                         size = (bcr >> 16) * (bcr & 0xffff);
98                         GPU_readDataMem(ptr, size);
99                         psxCpu->Clear(madr, size);
100                         break;
101
102                 case 0x01000201: // mem2vram
103 #ifdef PSXDMA_LOG
104                         PSXDMA_LOG("*** DMA 2 - GPU mem2vram *** %x addr = %x size = %x\n", chcr, madr, bcr);
105 #endif
106                         ptr = (u32 *)PSXM(madr);
107                         if (ptr == NULL) {
108 #ifdef CPU_LOG
109                                 CPU_LOG("*** DMA2 GPU - mem2vram *** NULL Pointer!!!\n");
110 #endif
111                                 break;
112                         }
113                         size = (bcr >> 16) * (bcr & 0xffff);
114                         GPU_writeDataMem(ptr, size);
115                         GPUDMA_INT(size / 4);
116                         return;
117
118                 case 0x01000401: // dma chain
119 #ifdef PSXDMA_LOG
120                         PSXDMA_LOG("*** DMA 2 - GPU dma chain *** %x addr = %x size = %x\n", chcr, madr, bcr);
121 #endif
122                         GPU_dmaChain((u32 *)psxM, madr & 0x1fffff);
123                         break;
124
125 #ifdef PSXDMA_LOG
126                 default:
127                         PSXDMA_LOG("*** DMA 2 - GPU unknown *** %x addr = %x size = %x\n", chcr, madr, bcr);
128                         break;
129 #endif
130         }
131
132         HW_DMA2_CHCR &= SWAP32(~0x01000000);
133         DMA_INTERRUPT(2);
134 }
135
136 void gpuInterrupt() {
137         HW_DMA2_CHCR &= SWAP32(~0x01000000);
138         DMA_INTERRUPT(2);
139 }
140
141 void psxDma6(u32 madr, u32 bcr, u32 chcr) {
142         u32 *mem = (u32 *)PSXM(madr);
143
144 #ifdef PSXDMA_LOG
145         PSXDMA_LOG("*** DMA6 OT *** %x addr = %x size = %x\n", chcr, madr, bcr);
146 #endif
147
148         if (chcr == 0x11000002) {
149                 if (mem == NULL) {
150 #ifdef CPU_LOG
151                         CPU_LOG("*** DMA6 OT *** NULL Pointer!!!\n");
152 #endif
153                         HW_DMA6_CHCR &= SWAP32(~0x01000000);
154                         DMA_INTERRUPT(6);
155                         return;
156                 }
157
158                 while (bcr--) {
159                         *mem-- = SWAP32((madr - 4) & 0xffffff);
160                         madr -= 4;
161                 }
162                 mem++; *mem = 0xffffff;
163         }
164 #ifdef PSXDMA_LOG
165         else {
166                 // Unknown option
167                 PSXDMA_LOG("*** DMA6 OT - unknown *** %x addr = %x size = %x\n", chcr, madr, bcr);
168         }
169 #endif
170
171         HW_DMA6_CHCR &= SWAP32(~0x01000000);
172         DMA_INTERRUPT(6);
173 }
174