PS2SDK
PS2 Homebrew Libraries
block.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 TyRaNiD <tiraniddo@hotmail.com>
3  * Copyright (c) 2004,2007 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 <stdarg.h>
15 #include "freesd.h"
16 #include "spu2regs.h"
17 
18 u32 BlockTransBuff[2];
19 u32 BlockTransAddr[2];
20 u32 BlockTransSize[2];
21 
22 extern void SetDmaWrite(s32 chan);
23 extern void SetDmaRead(s32 chan);
24 extern IntrData TransIntrData[2];
25 extern u32 DmaStop(u32 core);
26 
27 
28 s32 BlockTransWriteFrom(u8 *iopaddr, u32 size, s32 chan, u16 mode, u8 *startaddr)
29 {
30  s32 core = chan & 1;
31  s32 offset;
32 
33  BlockTransBuff[core] = 0;
34  BlockTransSize[core] = size;
35  BlockTransAddr[core] = (u32)iopaddr;
36 
37  if(startaddr == 0)
38  startaddr = iopaddr;
39 
40  offset = startaddr - iopaddr;
41 
42  if((u32)offset > size)
43  {
44  if(mode & SD_TRANS_LOOP)
45  {
46  offset -= size;
47  BlockTransBuff[core] = 1;
48  }
49  else
50  {
51  return -1;
52  }
53  }
54 
55  if(offset & 1023) offset += 1024;
56 
57  iopaddr += (BlockTransSize[core] * BlockTransBuff[core]) + offset;
58 
59  if(U16_REGISTER_READ(SD_CORE_ATTR(core)) & SD_DMA_IN_PROCESS) return -1;
60  if(U32_REGISTER_READ(SD_DMA_CHCR(core)) & SD_DMA_START) return -1;
61 
62  U16_REGISTER_WRITEAND(SD_CORE_ATTR(core), 0xFFCF);
63 
64  U16_REGISTER_WRITE(SD_A_TSA_HI(core), 0);
65  U16_REGISTER_WRITE(SD_A_TSA_LO(core), 0);
66 
67  U16_REGISTER_WRITE(U16_REGISTER(0x1B0+(core*1024)), 1 << core);
68 
69  SetDmaWrite(core);
70 
71  U32_REGISTER_WRITE(SD_DMA_ADDR(core), (u32)iopaddr);
72  U16_REGISTER_WRITE(SD_DMA_MODE(core), 0x10);
73  U16_REGISTER_WRITE(SD_DMA_SIZE(core), (size/64)+((size&63)>0));
74  U32_REGISTER_WRITE(SD_DMA_CHCR(core), SD_DMA_CS | SD_DMA_START | SD_DMA_DIR_IOP2SPU);
75 
76  return 0;
77 }
78 
79 s32 BlockTransWrite(u8 *iopaddr, u32 size, s32 chan)
80 {
81  s32 core = chan & 1;
82 
83  BlockTransBuff[core] = 0;
84  BlockTransSize[core] = size;
85  BlockTransAddr[core] = (u32)iopaddr;
86 
87  if(U16_REGISTER_READ(SD_CORE_ATTR(core)) & SD_DMA_IN_PROCESS) return -1;
88  if(U32_REGISTER_READ(SD_DMA_CHCR(core)) & SD_DMA_START) return -1;
89 
90  U16_REGISTER_WRITEAND(SD_CORE_ATTR(core), 0xFFCF);
91 
92  U16_REGISTER_WRITE(SD_A_TSA_HI(core), 0);
93  U16_REGISTER_WRITE(SD_A_TSA_LO(core), 0);
94 
95  U16_REGISTER_WRITE(U16_REGISTER(0x1B0+(core*1024)), 1 << core);
96 
97  SetDmaWrite(core);
98 
99  U32_REGISTER_WRITE(SD_DMA_ADDR(core), (u32)iopaddr);
100  U16_REGISTER_WRITE(SD_DMA_MODE(core), 0x10);
101  U16_REGISTER_WRITE(SD_DMA_SIZE(core), (size/64)+((size&63)>0));
102  U32_REGISTER_WRITE(SD_DMA_CHCR(core), SD_DMA_CS | SD_DMA_START | SD_DMA_DIR_IOP2SPU);
103 
104  return 0;
105 }
106 
107 
108 s32 BlockTransRead(u8 *iopaddr, u32 size, s32 chan, s16 mode)
109 {
110  u32 i;
111 
112  s32 core = chan & 1;
113 
114  BlockTransBuff[core] = 0;
115  BlockTransSize[core] = size;
116  BlockTransAddr[core] = (u32)iopaddr;
117 
118  if(U16_REGISTER_READ(SD_CORE_ATTR(core)) & SD_DMA_IN_PROCESS) return -1;
119  if(U32_REGISTER_READ(SD_DMA_CHCR(core)) & SD_DMA_START) return -1;
120 
121  U16_REGISTER_WRITEAND(SD_CORE_ATTR(core), 0xFFCF);
122 
123  U16_REGISTER_WRITE(SD_A_TSA_HI(core), 0);
124  U16_REGISTER_WRITE(SD_A_TSA_LO(core), ((mode & 0xF00) << 1) + 0x400);
125 
126  U16_REGISTER_WRITE(U16_REGISTER(0x1AE + (core*1024)), (mode & 0xF000) >> 11);
127 
128  i = 0x4937;
129 
130  while(i--);
131 
132  U16_REGISTER_WRITE(U16_REGISTER(0x1B0+(core*1024)), 4);
133 
134  SetDmaRead(core);
135 
136  U32_REGISTER_WRITE(SD_DMA_ADDR(core), (u32)iopaddr);
137  U16_REGISTER_WRITE(SD_DMA_MODE(core), 0x10);
138  U16_REGISTER_WRITE(SD_DMA_SIZE(core), (size/64)+((size&63)>0));
139  U32_REGISTER_WRITE(SD_DMA_CHCR(core), SD_DMA_CS | SD_DMA_START | SD_DMA_DIR_SPU2IOP);
140 
141 
142  return 0;
143 }
144 
145 
146 int sceSdBlockTrans(s16 chan, u16 mode, u8 *iopaddr, u32 size, ...)
147 {
148  int transfer_dir = mode & 3;
149  int core = chan & 1;
150  int _size = size;
151 
152  switch(transfer_dir)
153  {
154  case SD_TRANS_WRITE:
155  {
156  TransIntrData[core].mode = 0x100 | core;
157 
158  if(mode & SD_TRANS_LOOP)
159  {
160  TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
161  _size /= 2;
162  }
163 
164  if(BlockTransWrite(iopaddr, _size, core) >= 0)
165  return 0;
166 
167  } break;
168 
169  case SD_TRANS_READ:
170  {
171  TransIntrData[core].mode = 0x300 | core;
172 
173  if(mode & SD_TRANS_LOOP)
174  {
175  TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
176  _size /= 2;
177  }
178 
179  if(BlockTransRead(iopaddr, _size, chan, mode) >= 0)
180  return 0;
181 
182  } break;
183 
184  case SD_TRANS_STOP:
185  {
186  return DmaStop(core);
187 
188  } //break; // Fix codacy issue: Consecutive return, break, continue, goto or throw statements are unnecessary.
189 
190  case SD_TRANS_WRITE_FROM:
191  {
192  va_list alist;
193  u8* startaddr;
194 
195  va_start(alist, size);
196  startaddr = va_arg(alist, u8*);
197  va_end(alist);
198 
199  TransIntrData[core].mode = 0x100 | core;
200 
201  if(mode & SD_TRANS_LOOP)
202  {
203  TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
204  _size /= 2;
205  }
206 
207  if(BlockTransWriteFrom(iopaddr, _size, core, mode, startaddr) >= 0)
208  return 0;
209 
210 
211  } break;
212 
213  }
214  return -1;
215 }
216 
217 u32 sceSdBlockTransStatus(s16 chan, s16 flag)
218 {
219  u32 retval;
220 
221  (void)flag;
222 
223  chan &= 1;
224 
225  if(U16_REGISTER_READ(U16_REGISTER(0x1B0 + (chan * 1024))) == 0)
226  retval = 0;
227  else
228  retval = U32_REGISTER_READ(SD_DMA_ADDR(chan));
229 
230  retval = (BlockTransBuff[chan] << 24) | (retval & 0xFFFFFF);
231 
232  return retval;
233 }
IntrData
Definition: freesd.h:6
spu2regs.h