PS2SDK
PS2 Homebrew Libraries
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 
20 volatile u16 VoiceTransComplete[2];
21 u32 VoiceTransStatus[2];
22 u32 VoiceTransIoMode[2];
23 
24 extern void SetDmaWrite(s32 chan);
25 extern void SetDmaRead(s32 chan);
26 extern IntrData TransIntrData[2];
27 extern void DmaStop(u32 core);
28 
29 s32 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 
71 s32 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 
122 int 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 
150 u32 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 }
sifman.h
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3
irx.h
IntrData
Definition: freesd.h:6
spu2regs.h