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