1 /***************************************************************************
2 dma.c - description
3 -------------------
4 begin : Wed May 15 2002
5 copyright : (C) 2002 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. See also the license.txt file for *
15 * additional informations. *
16 * *
17 ***************************************************************************/
18
19 //*************************************************************************//
20 // History of changes:
21 //
22 // 2004/04/04 - Pete
23 // - changed plugin to emulate PS2 spu
24 //
25 // 2002/05/15 - Pete
26 // - generic cleanup for the Peops release
27 //
28 //*************************************************************************//
29
30 #include "../peops2/stdafx.h"
31
32 #define _IN_DMA
33
34 #include "../peops2/externals.h"
35 #include "../peops2/registers.h"
36 //#include "debug.h"
37 #include "../psx.h"
38 #include "../peops2/spu.h"
39
40 //extern uint32 psx_ram[(2*1024*1024)/4];
41
42 ////////////////////////////////////////////////////////////////////////
43 // READ DMA (many values)
44 ////////////////////////////////////////////////////////////////////////
45
SPU2readDMA4Mem(mips_cpu_context * cpu,u32 usPSXMem,int iSize)46 EXPORT_GCC void CALLBACK SPU2readDMA4Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize)
47 {
48 spu2_state_t *spu = cpu->spu2;
49 int i;
50 u16 *ram16 = (u16 *)&cpu->psx_ram[0];
51
52 for(i=0;i<iSize;i++)
53 {
54 ram16[usPSXMem>>1]=spu->spuMem[spu->spuAddr2[0]]; // spu addr 0 got by writeregister
55 usPSXMem+=2;
56 spu->spuAddr2[0]++; // inc spu addr
57 if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; // wrap
58 }
59
60 spu->spuAddr2[0]+=0x20; //?????
61
62
63 spu->iSpuAsyncWait=0;
64
65 // got from J.F. and Kanodin... is it needed?
66 spu->regArea[(PS2_C0_ADMAS)>>1]=0; // Auto DMA complete
67 spu->spuStat2[0]=0x80; // DMA complete
68 }
69
SPU2readDMA7Mem(mips_cpu_context * cpu,u32 usPSXMem,int iSize)70 EXPORT_GCC void CALLBACK SPU2readDMA7Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize)
71 {
72 spu2_state_t *spu = cpu->spu2;
73 int i;
74 u16 *ram16 = (u16 *)&cpu->psx_ram[0];
75
76 for(i=0;i<iSize;i++)
77 {
78 ram16[usPSXMem>>1]=spu->spuMem[spu->spuAddr2[1]]; // spu addr 1 got by writeregister
79 usPSXMem+=2;
80 spu->spuAddr2[1]++; // inc spu addr
81 if(spu->spuAddr2[1]>0xfffff) spu->spuAddr2[1]=0; // wrap
82 }
83
84 spu->spuAddr2[1]+=0x20; //?????
85
86 spu->iSpuAsyncWait=0;
87
88 // got from J.F. and Kanodin... is it needed?
89 spu->regArea[(PS2_C1_ADMAS)>>1]=0; // Auto DMA complete
90 spu->spuStat2[1]=0x80; // DMA complete
91 }
92
93 ////////////////////////////////////////////////////////////////////////
94 ////////////////////////////////////////////////////////////////////////
95 ////////////////////////////////////////////////////////////////////////
96
97 // to investigate: do sound data updates by writedma affect spu
98 // irqs? Will an irq be triggered, if new data is written to
99 // the memory irq address?
100
101 ////////////////////////////////////////////////////////////////////////
102 // WRITE DMA (many values)
103 ////////////////////////////////////////////////////////////////////////
104
SPU2writeDMA4Mem(mips_cpu_context * cpu,u32 usPSXMem,int iSize)105 EXPORT_GCC void CALLBACK SPU2writeDMA4Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize)
106 {
107 spu2_state_t *spu = cpu->spu2;
108 int i;
109 u16 *ram16 = (u16 *)&cpu->psx_ram[0];
110
111 for(i=0;i<iSize;i++)
112 {
113 spu->spuMem[spu->spuAddr2[0]] = ram16[usPSXMem>>1]; // spu addr 0 got by writeregister
114 usPSXMem+=2;
115 spu->spuAddr2[0]++; // inc spu addr
116 if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; // wrap
117 }
118
119 spu->iSpuAsyncWait=0;
120
121 // got from J.F. and Kanodin... is it needed?
122 spu->spuStat2[0]=0x80; // DMA complete
123 }
124
SPU2writeDMA7Mem(mips_cpu_context * cpu,u32 usPSXMem,int iSize)125 EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize)
126 {
127 spu2_state_t *spu = cpu->spu2;
128 int i;
129 u16 *ram16 = (u16 *)&cpu->psx_ram[0];
130
131 for(i=0;i<iSize;i++)
132 {
133 spu->spuMem[spu->spuAddr2[1]] = ram16[usPSXMem>>1]; // spu addr 1 got by writeregister
134 spu->spuAddr2[1]++; // inc spu addr
135 if(spu->spuAddr2[1]>0xfffff) spu->spuAddr2[1]=0; // wrap
136 }
137
138 spu->iSpuAsyncWait=0;
139
140 // got from J.F. and Kanodin... is it needed?
141 spu->spuStat2[1]=0x80; // DMA complete
142 }
143
144 ////////////////////////////////////////////////////////////////////////
145 // INTERRUPTS
146 ////////////////////////////////////////////////////////////////////////
147
InterruptDMA4(mips_cpu_context * cpu)148 void InterruptDMA4(mips_cpu_context *cpu)
149 {
150 spu2_state_t *spu = cpu->spu2;
151 // taken from linuzappz NULL spu2
152 // spu2Rs16(CORE0_ATTR)&= ~0x30;
153 // spu2Rs16(REG__1B0) = 0;
154 // spu2Rs16(SPU2_STATX_WRDY_M)|= 0x80;
155
156 spu->spuCtrl2[0]&=~0x30;
157 spu->regArea[(PS2_C0_ADMAS)>>1]=0;
158 spu->spuStat2[0]|=0x80;
159 }
160
SPU2interruptDMA4(mips_cpu_context * cpu)161 EXPORT_GCC void CALLBACK SPU2interruptDMA4(mips_cpu_context *cpu)
162 {
163 InterruptDMA4(cpu);
164 }
165
InterruptDMA7(mips_cpu_context * cpu)166 void InterruptDMA7(mips_cpu_context *cpu)
167 {
168 spu2_state_t *spu = cpu->spu2;
169 // taken from linuzappz NULL spu2
170 // spu2Rs16(CORE1_ATTR)&= ~0x30;
171 // spu2Rs16(REG__5B0) = 0;
172 // spu2Rs16(SPU2_STATX_DREQ)|= 0x80;
173
174 spu->spuCtrl2[1]&=~0x30;
175 spu->regArea[(PS2_C1_ADMAS)>>1]=0;
176 spu->spuStat2[1]|=0x80;
177 }
178
SPU2interruptDMA7(mips_cpu_context * cpu)179 EXPORT_GCC void CALLBACK SPU2interruptDMA7(mips_cpu_context *cpu)
180 {
181 InterruptDMA7(cpu);
182 }
183
184