PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
s147link.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 "irx_imports.h"
12#include <s147_mmio_hwport.h>
13
14IRX_ID("S147LINK", 2, 7);
15// Text section hash:
16// f409cc0329bb98d776c9aacef6573aa9
17
18typedef struct CL_COM_
19{
20 unsigned int mynode;
21 unsigned int maxnode;
22 unsigned int nodemask;
23 u8 *R_top;
24 unsigned int R_in;
25 unsigned int R_out;
26 unsigned int R_remain;
27 u8 R_number[16];
28 unsigned int R_lost[16];
29 unsigned int R_pd[16];
30 unsigned int R_count;
31 u8 *T_top;
32 unsigned int T_in;
33 unsigned int T_out;
34 unsigned int T_remain;
35 unsigned int T_node;
36 int T_error[16];
37 unsigned int T_pd[16];
38 unsigned int T_time[16];
39 u8 T_number;
40 unsigned int timeout;
41 unsigned int online;
42 unsigned int ontimer;
43 unsigned int offtimer;
44 unsigned int rbfix;
45 iop_sys_clock_t sys_clock;
46} CL_COM;
47
48static int InitS147link(int maxnode, int mynode, int priority);
49static unsigned int alarm_handler(void *userdata);
50static void s147link_loop(void *userdata);
51static void *dispatch(int fno, void *buf, int size);
52
53static int gbBRE;
54static u8 rpc_buf[32784];
55static u8 rx_buff[512][64];
56static u8 tx_buff[256][64];
57static CL_COM cl_info;
58
59int _start(int argc, char **argv)
60{
61 int maxnode;
62 int mynode;
63 int priority;
64
65 maxnode = (argc >= 2) ? strtol(argv[1], 0, 10) : 0;
66 if ( maxnode < 2 || maxnode >= 16 )
67 maxnode = 2;
68 mynode = (argc >= 3) ? strtol(argv[2], 0, 10) : 0;
69 if ( mynode <= 0 || maxnode < mynode )
70 mynode = 1;
71 priority = (argc >= 4) ? strtol(argv[3], 0, 10) : 0;
72 if ( priority < 9 || priority >= 124 )
73 priority = 28;
74 gbBRE = (argc >= 5 && toupper(*argv[4]) == 'N' && toupper(argv[4][1]) == 'B' && toupper(argv[4][2]) == 'R') ? 0 : 1;
75 printf("== S147LINK (%d/%d)@%d ", mynode, maxnode, priority);
76 if ( !gbBRE )
77 printf("NBR ");
78 printf("v2.07 ==\n");
79 if ( InitS147link(maxnode, mynode, priority) )
80 {
81 printf("S147LINK: Can't Initialize driver thread.\n");
82 return MODULE_NO_RESIDENT_END;
83 }
84 return MODULE_RESIDENT_END;
85}
86
87static void T_fix(CL_COM *io_pCommon)
88{
89 if ( io_pCommon->T_remain >= 0x101 )
90 {
91 io_pCommon->T_remain = 0x100;
92 io_pCommon->T_out = 0;
93 io_pCommon->T_in = io_pCommon->T_out;
94 io_pCommon->rbfix += 1;
95 if ( !io_pCommon->rbfix )
96 io_pCommon->rbfix -= 1;
97 }
98 if ( io_pCommon->T_remain == 0x100 && io_pCommon->T_in != io_pCommon->T_out )
99 {
100 io_pCommon->T_out = 0;
101 io_pCommon->T_in = io_pCommon->T_out;
102 io_pCommon->rbfix += 1;
103 if ( !io_pCommon->rbfix )
104 io_pCommon->rbfix -= 1;
105 }
106}
107
108static int clink_InterruptHandler(void *userdata)
109{
110 u8 *bufptr;
111 unsigned int i;
112 u8 stsH;
113 u8 stsL;
114 unsigned int rxfs;
115 unsigned int rxfc;
116 unsigned int tflag;
117 int state;
118 CL_COM *io_pCommon;
119 USE_S147LINK_DEV9_MEM_MMIO();
120
121 io_pCommon = (CL_COM *)userdata;
122 stsH = s147link_dev9_mem_mmio->m_stsH_unk12;
123 stsL = s147link_dev9_mem_mmio->m_stsL_unk13;
124 if ( (stsL & 8) != 0 )
125 {
126 if ( (s147link_dev9_mem_mmio->m_unk03 & 8) != 0 )
127 {
128 s147link_dev9_mem_mmio->m_unk17 = 1;
129 s147link_dev9_mem_mmio->m_unk17 = 0xE;
130 }
131 if ( (s147link_dev9_mem_mmio->m_unk01 & 4) != 0 )
132 {
133 s147link_dev9_mem_mmio->m_unk17 = 0x16;
134 if ( !io_pCommon->ontimer )
135 io_pCommon->offtimer = 1;
136 io_pCommon->ontimer = 1;
137 }
138 }
139 rxfc = 0;
140 rxfs =
141 ((s147link_dev9_mem_mmio->m_rxfc_hi_unk1E << 8) | s147link_dev9_mem_mmio->m_rxfc_lo_unk1F) & io_pCommon->nodemask;
142 if ( rxfs )
143 {
144 for ( i = 1; io_pCommon->maxnode >= i; i += 1 )
145 {
146 if ( i != io_pCommon->mynode )
147 {
148 u8 unk09_tmp;
149
150 if ( (rxfs & (1 << i)) == 0 )
151 {
152 continue;
153 }
154 s147link_dev9_mem_mmio->m_node_unk05 = i | 0xC0;
155 s147link_dev9_mem_mmio->m_unk07 = 0;
156 unk09_tmp = s147link_dev9_mem_mmio->m_unk09;
157 if ( unk09_tmp == io_pCommon->mynode )
158 {
159 // cppcheck-suppress incorrectLogicOperator
160 if ( s147link_dev9_mem_mmio->m_unk09 == 4 && !s147link_dev9_mem_mmio->m_unk09 )
161 {
162 u8 rnum;
163
164 rnum = s147link_dev9_mem_mmio->m_unk09;
165 if ( io_pCommon->R_number[i] != rnum )
166 {
167 unk09_tmp = s147link_dev9_mem_mmio->m_unk09;
168 if ( io_pCommon->R_remain )
169 {
170 unsigned int j;
171
172 bufptr = &io_pCommon->R_top[0x40 * io_pCommon->R_in];
173 bufptr[0] = i;
174 bufptr[1] = io_pCommon->mynode;
175 bufptr[2] = 4;
176 bufptr[3] = 0;
177 bufptr[4] = rnum;
178 bufptr[5] = unk09_tmp;
179 for ( j = 0; j < 0x3A; j += 1 )
180 bufptr[j + 6] = s147link_dev9_mem_mmio->m_unk09;
181 io_pCommon->R_remain -= 1;
182 io_pCommon->R_in += 1;
183 io_pCommon->R_in &= 0x1FF;
184 io_pCommon->R_number[i] = rnum;
185 }
186 else if ( io_pCommon->R_pd[i] )
187 {
188 io_pCommon->R_lost[i] += 1;
189 if ( !io_pCommon->R_lost[i] )
190 io_pCommon->R_lost[i] += 1;
191 }
192 else
193 {
194 continue;
195 }
196 }
197 }
198 }
199 else if ( !unk09_tmp )
200 {
201 if ( s147link_dev9_mem_mmio->m_unk09 == 0x38 )
202 {
203 s147link_dev9_mem_mmio->m_node_unk05 = i | 0xC0;
204 s147link_dev9_mem_mmio->m_unk07 = 0x38;
205 unk09_tmp = s147link_dev9_mem_mmio->m_unk09;
206 if ( (unk09_tmp & 0xE0) == 0x20 || (unk09_tmp & 0xE0) == 0x60 )
207 {
208 if ( io_pCommon->R_remain )
209 {
210 bufptr = &io_pCommon->R_top[0x40 * io_pCommon->R_in];
211 bufptr[0] = i;
212 bufptr[1] = 0;
213 bufptr[2] = 56;
214 bufptr[56] = unk09_tmp;
215 bufptr[57] = s147link_dev9_mem_mmio->m_unk09;
216 bufptr[58] = s147link_dev9_mem_mmio->m_unk09;
217 bufptr[59] = s147link_dev9_mem_mmio->m_unk09;
218 bufptr[60] = s147link_dev9_mem_mmio->m_unk09;
219 bufptr[61] = s147link_dev9_mem_mmio->m_unk09;
220 bufptr[62] = s147link_dev9_mem_mmio->m_unk09;
221 bufptr[63] = s147link_dev9_mem_mmio->m_unk09;
222 io_pCommon->R_remain -= 1;
223 io_pCommon->R_in += 1;
224 io_pCommon->R_in &= 0x1FF;
225 }
226 else if ( io_pCommon->R_pd[i] )
227 {
228 io_pCommon->R_lost[i] += 1;
229 if ( !io_pCommon->R_lost[i] )
230 io_pCommon->R_lost[i] += 1;
231 }
232 else
233 {
234 continue;
235 }
236 }
237 }
238 }
239 }
240 rxfc |= 1 << i;
241 }
242 }
243 tflag = 0;
244 if ( (stsL & 0x10) != 0 )
245 {
246 s147link_dev9_mem_mmio->m_unk17 = 1;
247 s147link_dev9_mem_mmio->m_unk17 = 0xE;
248 }
249 if ( (stsL & 2) != 0 && (stsL & 4) == 0 && io_pCommon->timeout )
250 {
251 tflag = 1;
252 }
253 else if ( (stsL & 1) != 0 )
254 {
255 io_pCommon->timeout = 0;
256 while ( 1 )
257 {
258 if ( io_pCommon->T_remain == 0x100 )
259 {
260 s147link_dev9_mem_mmio->m_unk15 = 0x1A;
261 break;
262 }
263 bufptr = &io_pCommon->T_top[0x40 * io_pCommon->T_out];
264 if ( *bufptr == io_pCommon->mynode )
265 {
266 io_pCommon->T_node = bufptr[1];
267 if ( !io_pCommon->T_error[io_pCommon->T_node] || !io_pCommon->T_pd[io_pCommon->T_node] )
268 {
269 s147link_dev9_mem_mmio->m_node_unk05 = (io_pCommon->mynode & 0xFF) | 0x40;
270 s147link_dev9_mem_mmio->m_unk07 = 0;
271 for ( i = 0; i < 0x40; i += 1 )
272 s147link_dev9_mem_mmio->m_unk09 = bufptr[i];
273 io_pCommon->T_remain += 1;
274 io_pCommon->T_out += 1;
275 io_pCommon->T_out &= 0xFF;
276 T_fix(io_pCommon);
277 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
278 tflag = 1;
279 io_pCommon->timeout = 1;
280 break;
281 }
282 }
283 io_pCommon->T_remain += 1;
284 io_pCommon->T_out += 1;
285 io_pCommon->T_out &= 0xFF;
286 T_fix(io_pCommon);
287 }
288 }
289 CpuSuspendIntr(&state);
290 if ( tflag )
291 s147link_dev9_mem_mmio->m_unk17 = 3;
292 if ( rxfc )
293 {
294 s147link_dev9_mem_mmio->m_rxfc_hi_unk1E = (rxfc >> 8) & 0xFF;
295 s147link_dev9_mem_mmio->m_rxfc_lo_unk1F = rxfc;
296 }
297 s147link_dev9_mem_mmio->m_stsH_unk12 = stsH;
298 s147link_dev9_mem_mmio->m_stsL_unk13 = stsL;
299 CpuResumeIntr(state);
300 return 1;
301}
302
303static int cl_mread(void *dstptr, int count)
304{
305 int state;
306 int size;
307 int packs;
308
309 CpuSuspendIntr(&state);
310 size = 0x200 - cl_info.R_remain;
311 if ( cl_info.R_remain == 0x200 )
312 {
313 CpuResumeIntr(state);
314 return 0;
315 }
316 if ( count >= size )
317 count = size;
318 else
319 size = count;
320 packs = cl_info.R_out + size - 0x200;
321 if ( packs > 0 )
322 {
323 size -= packs;
324 size <<= 6;
325 memcpy(dstptr, rx_buff[cl_info.R_out], size);
326 memcpy((char *)dstptr + size, rx_buff, packs << 6);
327 }
328 else
329 {
330 memcpy(dstptr, rx_buff[cl_info.R_out], size << 6);
331 }
332 cl_info.R_remain += count;
333 cl_info.R_out += count;
334 cl_info.R_out &= 0x1FF;
335 if ( cl_info.R_remain >= 0x201 )
336 {
337 cl_info.R_remain = 0x200;
338 cl_info.R_out = 0;
339 cl_info.R_in = 0;
340 cl_info.rbfix += 1;
341 if ( !cl_info.rbfix )
342 cl_info.rbfix -= 1;
343 count = 0;
344 }
345 if ( cl_info.R_remain == 512 && cl_info.R_in != cl_info.R_out )
346 {
347 cl_info.R_out = 0;
348 cl_info.R_in = 0;
349 cl_info.rbfix += 1;
350 if ( !cl_info.rbfix )
351 cl_info.rbfix -= 1;
352 count = 0;
353 }
354 CpuResumeIntr(state);
355 return count;
356}
357
358static int cl_write(int node, u8 *srcptr, int size)
359{
360 int state;
361 USE_S147LINK_DEV9_MEM_MMIO();
362
363 CpuSuspendIntr(&state);
364 if ( !cl_info.T_remain || size >= 0x41 )
365 {
366 CpuResumeIntr(state);
367 return 0;
368 }
369 memcpy(tx_buff[cl_info.T_in], srcptr, size);
370 tx_buff[cl_info.T_in][0] = cl_info.mynode;
371 tx_buff[cl_info.T_in][1] = node & 0xFF;
372 tx_buff[cl_info.T_in][2] = 4;
373 tx_buff[cl_info.T_in][3] = 0;
374 cl_info.T_number += 1;
375 tx_buff[cl_info.T_in][4] = cl_info.T_number;
376 cl_info.T_remain -= 1;
377 cl_info.T_in += 1;
378 cl_info.T_in &= 0xFF;
379 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
380 clink_InterruptHandler(&cl_info);
381 CpuResumeIntr(state);
382 return size;
383}
384
385static int cl_write_custom(int node, u8 *srcptr, int cpVal)
386{
387 int state;
388 USE_S147LINK_DEV9_MEM_MMIO();
389
390 CpuSuspendIntr(&state);
391 if ( !cl_info.T_remain )
392 {
393 CpuResumeIntr(state);
394 return 0;
395 }
396 memcpy(tx_buff[cl_info.T_in], srcptr, sizeof(u8[64]));
397 tx_buff[cl_info.T_in][0] = cl_info.mynode;
398 tx_buff[cl_info.T_in][1] = node & 0xFF;
399 tx_buff[cl_info.T_in][2] = cpVal & 0xFF;
400 cl_info.T_remain -= 1;
401 cl_info.T_in += 1;
402 cl_info.T_in &= 0xFF;
403 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
404 clink_InterruptHandler(&cl_info);
405 CpuResumeIntr(state);
406 return 64;
407}
408
409static int cl_mwrite(u8 *srcptr, int count)
410{
411 int state;
412 int i;
413 int packs;
414 USE_S147LINK_DEV9_MEM_MMIO();
415
416 if ( cl_info.T_remain < (unsigned int)count )
417 return 0;
418 if ( count >= 0x101 )
419 return 0;
420 for ( i = 0; i < count; i += 1 )
421 {
422 srcptr[(i * 0x40)] = cl_info.mynode;
423 srcptr[(i * 0x40) + 2] = 4;
424 srcptr[(i * 0x40) + 3] = 0;
425 srcptr[(i * 0x40) + 4] = cl_info.T_number + i + 1;
426 }
427 cl_info.T_number += i;
428 CpuSuspendIntr(&state);
429 if ( cl_info.T_remain < (unsigned int)count )
430 {
431 CpuResumeIntr(state);
432 return 0;
433 }
434 packs = cl_info.T_in + count - 0x100;
435 if ( packs > 0 )
436 {
437 memcpy(tx_buff[cl_info.T_in], srcptr, (count - packs) << 6);
438 memcpy(tx_buff, &srcptr[0x40 * (count - packs)], packs << 6);
439 }
440 else
441 {
442 memcpy(tx_buff[cl_info.T_in], srcptr, count << 6);
443 }
444 cl_info.T_remain -= count;
445 cl_info.T_in += count;
446 cl_info.T_in &= 0xFF;
447 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
448 clink_InterruptHandler(&cl_info);
449 CpuResumeIntr(state);
450 return count;
451}
452
453static int InitS147link(int maxnode, int mynode, int priority)
454{
455 iop_thread_t param;
456 int thid;
457 int i;
458 int j;
459 int state;
460 u8 stsH;
461 u8 stsL;
462 USE_S147LINK_DEV9_MEM_MMIO();
463
464 s147link_dev9_mem_mmio->m_unk0D |= 0x80;
465 s147link_dev9_mem_mmio->m_unk22 = 2;
466 s147link_dev9_mem_mmio->m_unk23 = gbBRE ? 0x51 : 0x11;
467 s147link_dev9_mem_mmio->m_maxnode_unk2B = maxnode;
468 s147link_dev9_mem_mmio->m_mynode_unk2D = mynode;
469 s147link_dev9_mem_mmio->m_unk31 = 0;
470 s147link_dev9_mem_mmio->m_unk2F = 2;
471 for ( i = 0; i < 4; i += 1 )
472 {
473 s147link_dev9_mem_mmio->m_node_unk05 = i | 0x40;
474 s147link_dev9_mem_mmio->m_unk07 = 0;
475 for ( j = 0; j < 256; j += 1 )
476 s147link_dev9_mem_mmio->m_unk09 = 0;
477 }
478 s147link_dev9_mem_mmio->m_unk28 = 0;
479 s147link_dev9_mem_mmio->m_unk29 = 0;
480 s147link_dev9_mem_mmio->m_unk21 = 0;
481 s147link_dev9_mem_mmio->m_unk24 = 0;
482 s147link_dev9_mem_mmio->m_unk25 = 0xFF;
483 s147link_dev9_mem_mmio->m_unk0D &= 0x7F;
484 s147link_dev9_mem_mmio->m_unk22 |= 1;
485 s147link_dev9_mem_mmio->m_node_unk05 = mynode | 0x40;
486 s147link_dev9_mem_mmio->m_unk07 = 0;
487 s147link_dev9_mem_mmio->m_unk09 = mynode;
488 s147link_dev9_mem_mmio->m_unk09 = 2;
489 s147link_dev9_mem_mmio->m_unk09 = 4;
490 cl_info.mynode = mynode;
491 cl_info.maxnode = maxnode;
492 j = 1;
493 for ( i = 0; i < maxnode; i += 1 )
494 {
495 j = (j << 1) | 1;
496 }
497 cl_info.nodemask = j;
498 cl_info.R_top = rx_buff[0];
499 cl_info.R_remain = 0x200;
500 cl_info.R_out = 0;
501 cl_info.R_in = 0;
502 for ( i = 0; i < 16; i += 1 )
503 {
504 cl_info.R_number[i] = 0;
505 cl_info.T_error[i] = 0;
506 cl_info.R_lost[i] = 0;
507 cl_info.T_pd[i] = 1;
508 cl_info.R_pd[i] = 1;
509 cl_info.T_time[i] = 2;
510 }
511 cl_info.T_top = tx_buff[0];
512 cl_info.T_remain = 0x100;
513 cl_info.offtimer = 0;
514 cl_info.ontimer = 0;
515 cl_info.online = 0;
516 cl_info.timeout = 0;
517 cl_info.T_out = 0;
518 cl_info.T_in = 0;
519 cl_info.T_number = 0;
520 cl_info.T_node = 2;
521 cl_info.rbfix = 0;
522 CpuSuspendIntr(&state);
524 RegisterIntrHandler(13, 1, clink_InterruptHandler, &cl_info);
525 s147link_dev9_mem_mmio->m_unk01 = 0xC;
526 s147link_dev9_mem_mmio->m_unk14 = 0x8E;
527 s147link_dev9_mem_mmio->m_unk15 = 0x1A;
528 s147link_dev9_mem_mmio->m_unk1C = 0xFF;
529 s147link_dev9_mem_mmio->m_unk1D = 0xFF;
530 s147link_dev9_mem_mmio->m_rxfc_hi_unk1E = 0xFF;
531 s147link_dev9_mem_mmio->m_rxfc_lo_unk1F = 0xFF;
532 stsH = s147link_dev9_mem_mmio->m_stsH_unk12;
533 stsL = s147link_dev9_mem_mmio->m_stsL_unk13;
534 s147link_dev9_mem_mmio->m_stsH_unk12 = stsH;
535 s147link_dev9_mem_mmio->m_stsL_unk13 = stsL;
536 CpuResumeIntr(state);
537 EnableIntr(13);
538 sceSifInitRpc(0);
539 param.attr = TH_C;
540 param.thread = s147link_loop;
541 param.priority = priority;
542 param.stacksize = 0x800;
543 param.option = 0;
544 thid = CreateThread(&param);
545 if ( thid <= 0 )
546 {
547 printf("S147LINK: Cannot create RPC server thread ...\n");
548 return -1;
549 }
550 if ( StartThread(thid, 0) )
551 {
552 printf("S147LINK: Cannot start RPC server thread ...\n");
553 DeleteThread(thid);
554 return -2;
555 }
556 USec2SysClock(0x7D0, &cl_info.sys_clock);
557 if ( SetAlarm(&cl_info.sys_clock, alarm_handler, &cl_info) )
558 {
559 printf("S147LINK: Cannot set alarm handler ...\n");
560 DeleteThread(thid);
561 return -3;
562 }
563 return 0;
564}
565
566#ifdef UNUSED_FUNC
567static void reset_circlink(void)
568{
569 u8 stsH;
570 u8 stsL;
571 int i;
572 int j;
573 USE_S147LINK_DEV9_MEM_MMIO();
574
575 s147link_dev9_mem_mmio->m_unk0D |= 0x80;
576 s147link_dev9_mem_mmio->m_unk22 = 2;
577 s147link_dev9_mem_mmio->m_unk23 = gbBRE ? 0x51 : 0x11;
578 s147link_dev9_mem_mmio->m_maxnode_unk2B = cl_info.maxnode;
579 s147link_dev9_mem_mmio->m_mynode_unk2D = cl_info.mynode;
580 s147link_dev9_mem_mmio->m_unk31 = 0;
581 s147link_dev9_mem_mmio->m_unk2F = 2;
582 for ( i = 0; i < 4; i += 1 )
583 {
584 s147link_dev9_mem_mmio->m_node_unk05 = i | 0x40;
585 s147link_dev9_mem_mmio->m_unk07 = 0;
586 for ( j = 0; j < 256; j += 1 )
587 s147link_dev9_mem_mmio->m_unk09 = 0;
588 }
589 s147link_dev9_mem_mmio->m_unk28 = 0;
590 s147link_dev9_mem_mmio->m_unk29 = 0;
591 s147link_dev9_mem_mmio->m_unk21 = 0;
592 s147link_dev9_mem_mmio->m_unk24 = 0;
593 s147link_dev9_mem_mmio->m_unk25 = 0xFF;
594 s147link_dev9_mem_mmio->m_unk0D &= 0x7F;
595 s147link_dev9_mem_mmio->m_unk22 |= 1;
596 s147link_dev9_mem_mmio->m_node_unk05 = (cl_info.mynode & 0xFF) | 0x40;
597 s147link_dev9_mem_mmio->m_unk07 = 0;
598 s147link_dev9_mem_mmio->m_unk09 = cl_info.mynode;
599 s147link_dev9_mem_mmio->m_unk09 = 2;
600 s147link_dev9_mem_mmio->m_unk09 = 4;
601 s147link_dev9_mem_mmio->m_unk01 = 0xC;
602 s147link_dev9_mem_mmio->m_unk14 = 0x8E;
603 s147link_dev9_mem_mmio->m_unk15 = 0x1A;
604 s147link_dev9_mem_mmio->m_unk1C = 0xFF;
605 s147link_dev9_mem_mmio->m_unk1D = 0xFF;
606 s147link_dev9_mem_mmio->m_rxfc_hi_unk1E = 0xFF;
607 s147link_dev9_mem_mmio->m_rxfc_lo_unk1F = 0xFF;
608 stsH = s147link_dev9_mem_mmio->m_stsH_unk12;
609 stsL = s147link_dev9_mem_mmio->m_stsL_unk13;
610 s147link_dev9_mem_mmio->m_stsH_unk12 = stsH;
611 s147link_dev9_mem_mmio->m_stsL_unk13 = stsL;
612}
613#endif
614
615static unsigned int alarm_handler(void *userdata)
616{
617 int state;
618 CL_COM *io_pCommon;
619 USE_S147LINK_DEV9_MEM_MMIO();
620
621 io_pCommon = (CL_COM *)userdata;
622 if ( io_pCommon->timeout )
623 {
624 if ( io_pCommon->T_time[io_pCommon->T_node] )
625 {
626 if ( io_pCommon->T_time[io_pCommon->T_node] >= io_pCommon->timeout )
627 {
628 io_pCommon->timeout += 1;
629 }
630 else
631 {
632 CpuSuspendIntr(&state);
633 (void)s147link_dev9_mem_mmio->m_stsL_unk13;
634 io_pCommon->timeout = 0;
635 s147link_dev9_mem_mmio->m_unk17 = 1;
636 s147link_dev9_mem_mmio->m_unk17 = 0xE;
637 cl_info.T_error[cl_info.T_node] = 0xFFFFFFFE;
638 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
639 clink_InterruptHandler(&cl_info);
640 CpuResumeIntr(state);
641 }
642 }
643 else
644 {
645 io_pCommon->timeout = 0;
646 }
647 }
648 if ( io_pCommon->ontimer )
649 {
650 if ( io_pCommon->ontimer < 0xFA )
651 {
652 io_pCommon->ontimer += 1;
653 }
654 else
655 {
656 io_pCommon->online = 1;
657 io_pCommon->offtimer = 0;
658 io_pCommon->ontimer = io_pCommon->offtimer;
659 }
660 }
661 if ( io_pCommon->offtimer )
662 {
663 if ( io_pCommon->offtimer < 0xFA )
664 io_pCommon->offtimer += 1;
665 else
666 io_pCommon->online = 0;
667 }
668 return io_pCommon->sys_clock.lo;
669}
670
671static void s147link_loop(void *userdata)
672{
675
676 (void)userdata;
677 sceSifSetRpcQueue(&qd, GetThreadId());
678 sceSifRegisterRpc(&sd, 0x14799, dispatch, rpc_buf, 0, 0, &qd);
679 sceSifRpcLoop(&qd);
680}
681
682static void *dispatch(int fno, void *buf, int size)
683{
684 int state;
685 int node;
686 int sizeb;
687 unsigned int i;
688 USE_S147LINK_DEV9_MEM_MMIO();
689
690 (void)size;
691 FlushDcache();
692 node = fno & 0xFF;
693 sizeb = (fno & 0xFFFF00) >> 8;
694 switch ( fno >> 24 )
695 {
696 case 0x00:
697 *(u32 *)buf = 1;
698 break;
699 case 0x01:
700 cl_info.R_pd[node] = *(u32 *)buf;
701 cl_info.T_pd[node] = *((u32 *)buf + 1);
702 cl_info.T_time[node] = *((u32 *)buf + 2);
703 break;
704 case 0x10:
705 CpuSuspendIntr(&state);
706 cl_info.T_out = 0;
707 cl_info.T_in = 0;
708 cl_info.T_remain = 0x100;
709 s147link_dev9_mem_mmio->m_unk17 = 1;
710 s147link_dev9_mem_mmio->m_unk17 = 0xE;
711 cl_info.T_error[cl_info.T_node] = 0xFFFFFFFD;
712 *(u32 *)buf = cl_info.T_node;
713 CpuResumeIntr(state);
714 break;
715 case 0x11:
716 *(u32 *)buf = cl_info.rbfix;
717 break;
718 case 0x20:
719 *(u32 *)buf = cl_mread((char *)buf + 4, *(u32 *)buf);
720 CpuSuspendIntr(&state);
721 clink_InterruptHandler(&cl_info);
722 CpuResumeIntr(state);
723 break;
724 case 0x30:
725 *(u32 *)buf = cl_write(node, (u8 *)buf, sizeb);
726 break;
727 case 0x40:
728 *(u32 *)buf = cl_mwrite((u8 *)buf, sizeb);
729 break;
730 case 0x50:
731 CpuSuspendIntr(&state);
732 cl_info.R_out = 0;
733 cl_info.R_in = 0;
734 cl_info.R_remain = 0x200;
735 CpuResumeIntr(state);
736 break;
737 case 0x60:
738 *(u32 *)buf = cl_info.R_remain;
739 break;
740 case 0x70:
741 *(u32 *)buf = cl_info.T_remain;
742 break;
743 case 0x80:
744 *(u32 *)buf = cl_info.online;
745 break;
746 case 0x90:
747 *(u32 *)buf = cl_info.T_error[node];
748 break;
749 case 0xA0:
750 CpuSuspendIntr(&state);
751 cl_info.T_error[node] = 0;
752 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
753 clink_InterruptHandler(&cl_info);
754 CpuResumeIntr(state);
755 break;
756 case 0xB0:
757 CpuSuspendIntr(&state);
758 s147link_dev9_mem_mmio->m_unk17 = 1;
759 s147link_dev9_mem_mmio->m_unk17 = 0xE;
760 cl_info.T_error[cl_info.T_node] = 0xFFFFFFFD;
761 *(u32 *)buf = cl_info.T_node;
762 s147link_dev9_mem_mmio->m_unk15 = 0x1B;
763 clink_InterruptHandler(&cl_info);
764 CpuResumeIntr(state);
765 break;
766 case 0xC0:
767 *(u32 *)buf = cl_info.R_lost[node];
768 cl_info.R_lost[node] = 0;
769 break;
770 case 0xD0:
771 *(u32 *)buf = cl_write_custom(node, (u8 *)buf, sizeb);
772 break;
773 case 0xF0:
774 CpuSuspendIntr(&state);
775 clink_InterruptHandler(&cl_info);
776 CpuResumeIntr(state);
777 break;
778 default:
779 printf("S147LINK: Unknown RPC command (%X)\n", fno);
780 break;
781 }
782 *(u32 *)buf |= (cl_info.online ? 0x10000 : 0);
783 for ( i = 1; i < cl_info.maxnode; i += 1 )
784 {
785 if ( cl_info.T_error[i] )
786 *(u32 *)buf |= 0x10000 << i;
787 if ( cl_info.R_lost[i] )
788 *(u32 *)buf |= 0x10000 << i;
789 }
790 FlushDcache();
791 return buf;
792}
int CpuResumeIntr(int state)
Definition intrman.c:227
int ReleaseIntrHandler(int irq)
Definition intrman.c:167
int CpuSuspendIntr(int *state)
Definition intrman.c:205
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition intrman.c:125
int EnableIntr(int irq)
Definition intrman.c:346
u32 count
start sector of fragmented bd/file