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/dma.h"
35 #include "../peops2/externals.h"
36 #include "../peops2/registers.h"
37 //#include "debug.h"
38
39 extern uint32_t psx_ram[(2*1024*1024)/4+4];
40
41 ////////////////////////////////////////////////////////////////////////
42 // READ DMA (many values)
43 ////////////////////////////////////////////////////////////////////////
44
SPU2readDMA4Mem(u32 usPSXMem,int iSize)45 EXPORT_GCC void CALLBACK SPU2readDMA4Mem(u32 usPSXMem,int iSize)
46 {
47 int i;
48 u16 *ram16 = (u16 *)&psx_ram[0];
49
50 for(i=0;i<iSize;i++)
51 {
52 ram16[usPSXMem>>1]=spuMem[spuAddr2[0]]; // spu addr 0 got by writeregister
53 usPSXMem+=2;
54 spuAddr2[0]++; // inc spu addr
55 if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
56 }
57
58 spuAddr2[0]+=0x20; //?????
59
60
61 iSpuAsyncWait=0;
62
63 // got from J.F. and Kanodin... is it needed?
64 regArea[(PS2_C0_ADMAS)>>1]=0; // Auto DMA complete
65 spuStat2[0]=0x80; // DMA complete
66 }
67
SPU2readDMA7Mem(u32 usPSXMem,int iSize)68 EXPORT_GCC void CALLBACK SPU2readDMA7Mem(u32 usPSXMem,int iSize)
69 {
70 int i;
71 u16 *ram16 = (u16 *)&psx_ram[0];
72
73 for(i=0;i<iSize;i++)
74 {
75 ram16[usPSXMem>>1]=spuMem[spuAddr2[1]]; // spu addr 1 got by writeregister
76 usPSXMem+=2;
77 spuAddr2[1]++; // inc spu addr
78 if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
79 }
80
81 spuAddr2[1]+=0x20; //?????
82
83 iSpuAsyncWait=0;
84
85 // got from J.F. and Kanodin... is it needed?
86 regArea[(PS2_C1_ADMAS)>>1]=0; // Auto DMA complete
87 spuStat2[1]=0x80; // DMA complete
88 }
89
90 ////////////////////////////////////////////////////////////////////////
91 ////////////////////////////////////////////////////////////////////////
92 ////////////////////////////////////////////////////////////////////////
93
94 // to investigate: do sound data updates by writedma affect spu
95 // irqs? Will an irq be triggered, if new data is written to
96 // the memory irq address?
97
98 ////////////////////////////////////////////////////////////////////////
99 // WRITE DMA (many values)
100 ////////////////////////////////////////////////////////////////////////
101
SPU2writeDMA4Mem(u32 usPSXMem,int iSize)102 EXPORT_GCC void CALLBACK SPU2writeDMA4Mem(u32 usPSXMem,int iSize)
103 {
104 int i;
105 u16 *ram16 = (u16 *)&psx_ram[0];
106
107 for(i=0;i<iSize;i++)
108 {
109 spuMem[spuAddr2[0]] = ram16[usPSXMem>>1]; // spu addr 0 got by writeregister
110 usPSXMem+=2;
111 spuAddr2[0]++; // inc spu addr
112 if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
113 }
114
115 iSpuAsyncWait=0;
116
117 // got from J.F. and Kanodin... is it needed?
118 spuStat2[0]=0x80; // DMA complete
119 }
120
SPU2writeDMA7Mem(u32 usPSXMem,int iSize)121 EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(u32 usPSXMem,int iSize)
122 {
123 int i;
124 u16 *ram16 = (u16 *)&psx_ram[0];
125
126 for(i=0;i<iSize;i++)
127 {
128 spuMem[spuAddr2[1]] = ram16[usPSXMem>>1]; // spu addr 1 got by writeregister
129 spuAddr2[1]++; // inc spu addr
130 if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
131 }
132
133 iSpuAsyncWait=0;
134
135 // got from J.F. and Kanodin... is it needed?
136 spuStat2[1]=0x80; // DMA complete
137 }
138
139 ////////////////////////////////////////////////////////////////////////
140 // INTERRUPTS
141 ////////////////////////////////////////////////////////////////////////
142
InterruptDMA4(void)143 void InterruptDMA4(void)
144 {
145 // taken from linuzappz nullptr spu2
146 // spu2Rs16(CORE0_ATTR)&= ~0x30;
147 // spu2Rs16(REG__1B0) = 0;
148 // spu2Rs16(SPU2_STATX_WRDY_M)|= 0x80;
149
150 spuCtrl2[0]&=~0x30;
151 regArea[(PS2_C0_ADMAS)>>1]=0;
152 spuStat2[0]|=0x80;
153 }
154
SPU2interruptDMA4(void)155 EXPORT_GCC void CALLBACK SPU2interruptDMA4(void)
156 {
157 InterruptDMA4();
158 }
159
InterruptDMA7(void)160 void InterruptDMA7(void)
161 {
162 // taken from linuzappz nullptr spu2
163 // spu2Rs16(CORE1_ATTR)&= ~0x30;
164 // spu2Rs16(REG__5B0) = 0;
165 // spu2Rs16(SPU2_STATX_DREQ)|= 0x80;
166
167 spuCtrl2[1]&=~0x30;
168 regArea[(PS2_C1_ADMAS)>>1]=0;
169 spuStat2[1]|=0x80;
170 }
171
SPU2interruptDMA7(void)172 EXPORT_GCC void CALLBACK SPU2interruptDMA7(void)
173 {
174 InterruptDMA7();
175 }
176
177