PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
voice.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004 TyRaNiD <tiraniddo@hotmail.com>
3 * Copyright (c) 2004,2007,2008 Lukasz Bruun <mail@lukasz.dk>
4 *
5 * See the file LICENSE included with this distribution for licensing terms.
6 */
7
13#include "types.h"
14#include "irx.h"
15#include "sifman.h"
16#include "freesd.h"
17#include "spu2regs.h"
18
19
20volatile u16 VoiceTransComplete[2];
21u32 VoiceTransStatus[2];
22u32 VoiceTransIoMode[2];
23
24extern void SetDmaWrite(s32 chan);
25extern void SetDmaRead(s32 chan);
26extern IntrData TransIntrData[2];
27extern void DmaStop(u32 core);
28
29s32 VoiceTransDma(s16 chan, u16 mode, u8 *iop_addr, u32 *spu_addr, u32 size)
30{
31 u32 direction;
32
33 if(U16_REGISTER_READ(SD_CORE_ATTR(chan)) & SD_DMA_IN_PROCESS)
34 return -1;
35
36 if(U32_REGISTER_READ(SD_DMA_CHCR(chan)) & SD_DMA_START)
37 return -1;
38
39 U16_REGISTER_WRITE(SD_A_TSA_HI(chan), (u32)spu_addr >> 17);
40 U16_REGISTER_WRITE(SD_A_TSA_LO(chan), (u32)spu_addr >> 1);
41
42 if(mode == SD_TRANS_WRITE)
43 {
44 TransIntrData[chan].mode = chan;
45 direction = SD_DMA_DIR_IOP2SPU;
46 U16_REGISTER_WRITE(SD_CORE_ATTR(chan), (U16_REGISTER_READ(SD_CORE_ATTR(chan)) & ~SD_CORE_DMA) | SD_DMA_WRITE);
47 SetDmaWrite(chan);
48 }
49 else
50 {
51 if(mode == SD_TRANS_READ)
52 {
53 TransIntrData[chan].mode = (chan << 2) | 0x200;
54 direction = SD_DMA_DIR_SPU2IOP;
55 U16_REGISTER_WRITE(SD_CORE_ATTR(chan), (U16_REGISTER_READ(SD_CORE_ATTR(chan)) & ~SD_CORE_DMA) | SD_DMA_READ);
56 SetDmaRead(chan);
57 }
58 else
59 {
60 return -1;
61 }
62 }
63
64 U32_REGISTER_WRITE(SD_DMA_ADDR(chan), (u32)iop_addr);
65 U32_REGISTER_WRITE(SD_DMA_MSIZE(chan), (((size+63)/64) << 16) | 0x10);
66 U32_REGISTER_WRITE(SD_DMA_CHCR(chan), SD_DMA_CS | SD_DMA_START | direction);
67
68 return size;
69}
70
71s32 VoiceTrans_Write_IOMode(u32 iopaddr, u32 spu_addr, s32 size, s16 chan)
72{
73 if(U16_REGISTER_READ(SD_CORE_ATTR(chan)) & SD_DMA_IN_PROCESS)
74 return -1;
75
76 if(U32_REGISTER_READ(SD_DMA_CHCR(chan)) & SD_DMA_START)
77 return -1;
78
79 U16_REGISTER_WRITE(SD_A_TSA_HI(chan), (u16)spu_addr >> 17);
80 U16_REGISTER_WRITE(SD_A_TSA_LO(chan), (u16)spu_addr >> 1);
81
82 TransIntrData[chan].mode = chan;
83
84 if(size)
85 {
86 s32 loop, count;
87 volatile u16* iop_mem = (volatile u16 *) iopaddr;
88
89 while(size > 0)
90 {
91 volatile u16 *statx;
92
93 if(size > 64)
94 count = 64;
95 else
96 count = size;
97
98 if(count > 0)
99 {
100 for(loop = 0; loop < count; loop += 2)
101 U16_REGISTER_WRITE(SD_A_STD(chan), *iop_mem++);
102 }
103
104 // Set Transfer mode to IO
105 U16_REGISTER_WRITE(SD_CORE_ATTR(chan), (U16_REGISTER_READ(SD_CORE_ATTR(chan)) & ~SD_CORE_DMA) | SD_DMA_IO);
106
107 statx = U16_REGISTER(0x344 + (chan << 10));
108
109 // Wait for transfer to complete;
110 while(U16_REGISTER_READ(statx) & SD_IO_IN_PROCESS);
111
112 size -= count;
113 }
114 }
115
116 // Reset DMA settings
117 U16_REGISTER_WRITEAND(SD_CORE_ATTR(chan), ~SD_CORE_DMA);
118
119 return 0;
120}
121
122int sceSdVoiceTrans(s16 chan, u16 mode, u8 *iopaddr, u32 *spuaddr, u32 size)
123{
124 s32 res = size;
125
126 chan &= 1;
127
128 if(mode & SD_TRANS_MODE_IO)
129 VoiceTransIoMode[chan] = 1;
130 else
131 VoiceTransIoMode[chan] = 0;
132
133 if(VoiceTransIoMode[chan] == 0)
134 {
135 res = VoiceTransDma(chan, mode & 3, iopaddr, spuaddr, size);
136 }
137 else
138 {
139 if((mode & 3) == SD_TRANS_WRITE)
140 {
141 res = VoiceTrans_Write_IOMode( (u32)iopaddr, (u32)spuaddr, size, chan);
142 }
143 }
144
145 VoiceTransStatus[chan] = 0;
146
147 return res;
148}
149
150u32 sceSdVoiceTransStatus(s16 chan, s16 flag)
151{
152 chan &= 1;
153 flag &= 1;
154
155 if((VoiceTransIoMode[chan] == 1) || (VoiceTransStatus[chan] == 1))
156 return 1;
157
158 if(flag)
159 {
160 while(!VoiceTransComplete[chan]);
161 VoiceTransStatus[chan] = 1;
162 VoiceTransComplete[chan] = 0;
163
164 return 1;
165 }
166 else
167 {
168 if(VoiceTransComplete[chan] == 0) return 0;
169 VoiceTransStatus[chan] = 1;
170 VoiceTransComplete[chan] = 0;
171 }
172
173 return 0;
174}
u32 count
start sector of fragmented bd/file