PS2SDK
PS2 Homebrew Libraries
fpgald.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include <accore.h>
12 #include <irx_imports.h>
13 
14 #define MODNAME "FPGA_loader"
15 IRX_ID(MODNAME, 1, 1);
16 // Text section hash:
17 // 3555dfa26ee67afededdfa0d981cd68f
18 // Known titles:
19 // NM00005
20 // NM00006
21 // NM00008
22 // Path strings:
23 // /home/ueda/tmp/psalm-0.1.3/fpgald-iop-0.1.4/src/
24 // TODO: diff with module text hash fb29cec4461e70e3f6efd1d7259278cb
25 
26 typedef char *(*fpga_strop_t)(char *name);
27 
28 static char *fpgald_path(char *name);
29 static char *fpgald_basename(char *name);
30 
31 static fpga_strop_t ops_12[2] = {&fpgald_path, &fpgald_basename};
32 static char buf_17[8192];
33 
34 static int fpgald_wait(acC448Reg c448, acUint32 flag, int verbose)
35 {
36  int errors;
37  acUint32 fbit;
38  int sr;
39 
40  errors = 0;
41  fbit = 32;
42  while ( fbit )
43  {
44  int count;
45 
46  if ( !flag )
47  break;
48  count = 0xFFFF;
49  if ( (flag & fbit) != 0 )
50  {
51  flag ^= fbit;
52  while ( count >= 0 )
53  {
54  sr = (c448[0x3800] & 0xFF00) >> 8;
55  if ( (sr & fbit) != 0 )
56  break;
57  --count;
58  }
59  if ( count < 0 && verbose )
60  {
61  printf("acfpgald:wait: TIMEDOUT %02x %02x\n", sr, (unsigned int)fbit);
62  ++errors;
63  }
64  }
65  fbit >>= 1;
66  }
67  return errors;
68 }
69 
70 static char *fpgald_path(char *name)
71 {
72  char *str;
73 
74  str = strchr(name, ':');
75  if ( str == 0 )
76  return name;
77  return str + 1;
78 }
79 
80 static char *fpgald_basename(char *name)
81 {
82  char *str;
83  char *str_v3;
84  char *str_v4;
85  char *str_v5;
86  char *str_v6;
87 
88  str = strchr(name, ':');
89  if ( str == 0 )
90  return name;
91  str_v3 = str + 1;
92  str_v4 = strrchr(str_v3, '/');
93  if ( str_v4 == 0 )
94  {
95  str_v6 = strrchr(str_v3, '\\');
96  if ( str_v6 == 0 )
97  return str_v3;
98  str_v5 = str_v6 + 1;
99  }
100  else
101  {
102  str_v5 = str_v4 + 1;
103  }
104  return str_v5;
105 }
106 
107 #define acFpgaLoader _start
108 
109 int acFpgaLoader(int argc, char **argv)
110 {
111  char *prog;
112  int ret;
113  char *name;
114  int fd;
115 
116  prog = 0;
117  if ( argv )
118  prog = *argv;
119  if ( argc < 2 )
120  return -22;
121  name = argv[1];
122  if ( fpgald_path(name) == name )
123  {
124  fd = -6;
125  }
126  else
127  {
128  fd = open(name, 1);
129  if ( fd < 0 && prog )
130  {
131  int index;
132 
133  index = 0;
134  while ( (unsigned int)index < 2 )
135  {
136  fpga_strop_t op;
137  const char *v9;
138 
139  op = ops_12[index];
140  v9 = (char *)op(prog);
141  if ( v9 != prog )
142  {
143  memcpy(buf_17, prog, v9 - prog);
144  strcpy(&buf_17[v9 - prog], op(name));
145  fd = open(buf_17, 1);
146  if ( fd >= 0 )
147  break;
148  }
149  index++;
150  }
151  }
152  }
153  if ( fd < 0 )
154  {
155  printf("acfpgald:open: error %d\n", fd);
156  ret = fd;
157  }
158  else
159  {
160  int size;
161  int errors;
162  int ret_v13;
163 
164  *((volatile acUint16 *)0xB2416008) = 0;
165  fpgald_wait((acC448Reg)0xB2415000, 0x30u, 0);
166  *((volatile acUint16 *)0xB241600A) = 0;
167  size = 0;
168  errors = fpgald_wait((acC448Reg)0xB2415000, 0x20u, 1);
169  DelayThread(1000);
170  while ( 1 )
171  {
172  int xlen;
173  const acUint8 *ptr;
174 
175  ret_v13 = read(fd, buf_17, 0x2000);
176  xlen = ret_v13 - 1;
177  if ( ret_v13 <= 0 )
178  break;
179  ptr = (acUint8 *)buf_17;
180  size += ret_v13;
181  while ( xlen >= 0 )
182  {
183  int value;
184  int bytecount;
185 
186  value = *ptr++;
187  bytecount = 7;
188  while ( bytecount >= 0 )
189  {
190  int ret_v18;
191 
192  ret_v18 = value & 1;
193  value >>= 1;
194  --bytecount;
195  *((volatile acUint16 *)0xB2416014) = 0;
196  *(acUint16 *)(2 * ret_v18 + 0xB2415000 + 0x1018) = 0;
197  *((volatile acUint16 *)0xB2416016) = 0;
198  }
199  --xlen;
200  }
201  }
202  *((volatile acUint16 *)0xB2416014) = 0;
203  if ( ret_v13 < 0 )
204  {
205  ret = -5;
206  }
207  else
208  {
209  if ( errors + fpgald_wait((acC448Reg)0xB2415000, 0x10u, 1) > 0 )
210  {
211  ret = -116;
212  }
213  else
214  {
215  int ret_v19;
216 
217  ret_v19 = 38;
218  while ( ret_v19 >= 0 )
219  {
220  ret_v19--;
221  *((volatile acUint16 *)0xB2416016) = 0;
222  *((volatile acUint16 *)0xB2416014) = 0;
223  }
224  DelayThread(1000);
225  *((volatile acUint16 *)0xB2416012) = 0;
226  ret = size;
227  }
228  }
229  close(fd);
230  }
231  if ( ret >= 0 )
232  return 1;
233  return ret;
234 }
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3