PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
meme.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 "acmeme_internal.h"
12
13static int meme_op_xfer(struct meme_softc *memec, struct ac_memsif_reply *rpl, const void *arg, int size);
14static int meme_op_init(struct meme_softc *memec, struct ac_memsif_reply *rpl, const void *arg, int size);
15
16static meme_ops_t ops_48[3] = {NULL, &meme_op_init, &meme_op_xfer};
17static struct meme_softc Memec;
18
19static int meme_jv_read(acMemAddr addr, void *buf, int size)
20{
21 return acJvRead(addr, buf, size);
22}
23
24static int meme_jv_write(acMemAddr addr, void *buf, int size)
25{
26 return acJvWrite(addr, buf, size);
27}
28
29static void meme_ram_done(acRamT ram, struct meme_ram *arg, int result)
30{
31 (void)ram;
32 if ( arg )
33 {
34 int thid;
35
36 thid = arg->mr_thid;
37 arg->mr_thid = 0;
38 arg->mr_result = result;
39 if ( thid )
40 WakeupThread(thid);
41 }
42}
43
44static int meme_ram_read(acMemAddr addr, void *buf, int size)
45{
46 acRamT ret;
47 int ret_v1;
48 int thid;
49 struct meme_ram mram_data;
50
51 mram_data.mr_thid = GetThreadId();
52 mram_data.mr_result = 0;
53 ret = acRamSetup(&mram_data.mr_ram, (acRamDone)meme_ram_done, &mram_data, 1000000);
54 ret_v1 = acRamRead(ret, addr, buf, size);
55 if ( ret_v1 < 0 )
56 {
57 return ret_v1;
58 }
59 thid = GetThreadId();
60 while ( thid == mram_data.mr_thid )
61 SleepThread();
62 return mram_data.mr_result;
63}
64
65static int meme_ram_write(acMemAddr addr, void *buf, int size)
66{
67 int ret_v1;
68 int thid;
69 struct meme_ram mram_data;
70
71 mram_data.mr_thid = GetThreadId();
72 mram_data.mr_result = 0;
73 ret_v1 = acRamWrite(acRamSetup(&mram_data.mr_ram, (acRamDone)meme_ram_done, &mram_data, 1000000), addr, buf, size);
74 if ( ret_v1 < 0 )
75 {
76 return ret_v1;
77 }
78 thid = GetThreadId();
79 while ( thid == mram_data.mr_thid )
80 SleepThread();
81 return mram_data.mr_result;
82}
83
84int meme_sram_read(acMemAddr addr, void *buf, int size)
85{
86 return acSramRead(addr, buf, size);
87}
88
89int meme_sram_write(acMemAddr addr, void *buf, int size)
90{
91 return acSramWrite(addr, buf, size);
92}
93
94static int meme_xfer_eetodev(struct meme_softc *memec, acMemVecT mvec, meme_xfer_t xfer)
95{
96 int v5;
97 int mv_size;
98 void *buf;
99 acMemAddr dst;
100 acMemAddr src;
101 int v11;
102 acMemData mem_data;
103
104 v5 = 0;
105 mv_size = mvec->mv_size;
106 buf = memec->buf;
107 dst = mvec->mv_dst & 0xFFFFFFE;
108 src = mvec->mv_src & 0xFFFFFFE;
109 acMemSetup(&mem_data, buf, memec->size);
110 for ( ; mv_size > 0; dst += v11 )
111 {
112 int v10;
113
114 v10 = acMemReceive(&mem_data, src, mv_size);
115 v5 = v10;
116 v11 = v10;
117 if ( v10 <= 0 )
118 break;
119 v5 = xfer(dst, buf, v10);
120 src += v11;
121 if ( v5 <= 0 )
122 break;
123 mv_size -= v11;
124 }
125 mvec->mv_result = mvec->mv_size - mv_size;
126 return v5;
127}
128
129static int meme_xfer_ioptodev(struct meme_softc *memec, acMemVecT mvec, meme_xfer_t xfer)
130{
131 int ret;
132 signed int mv_size;
133 acMemAddr dst;
134 acUint8 *src;
135 int v9;
136
137 (void)memec;
138 ret = 0;
139 mv_size = mvec->mv_size;
140 dst = mvec->mv_dst & 0xFFFFFFE;
141 for ( src = (acUint8 *)(mvec->mv_src & 0xFFFFFFE); mv_size > 0; src += v9 )
142 {
143 v9 = 0x20000;
144 if ( mv_size <= 0x20000 )
145 v9 = mv_size;
146 ret = xfer(dst, src, v9);
147 dst += v9;
148 if ( ret <= 0 )
149 break;
150 mv_size -= v9;
151 }
152 mvec->mv_result = mvec->mv_size - mv_size;
153 return ret;
154}
155
156static int meme_op_xfer(struct meme_softc *memec, struct ac_memsif_reply *rpl, const void *arg, int size)
157{
158 int ret;
159 int v5;
160 acMemVecT mvec;
161 acMemAddr v8;
162 meme_xfer_t xfer_src;
163 acMemAddr v10;
164 meme_xfer_t xfer_dst;
165 int v12;
166 acMemAddr mv_dst;
167 int v14;
168 acUint8 *dst;
169 signed int mv_size;
170 acMemAddr src;
171 int ret_v14;
172 acMemAddr dst_v15;
173 acMemAddr src_v16;
174 int pos;
175 int bsize;
176 signed int v23;
177 int xlen;
178 acMemT v25;
179 acMemT size_v22;
180 int v27;
181 acMemT size_v24;
182 int v29;
183 int reply;
184 acInt32 v31;
185 acMemData mem_data;
186 acMemData mem_data_v29[2];
187 acMemVecT addr;
188 int v36;
189 int v37;
190 int v40;
191 acUint8 *buf;
192 struct ac_memsif_xfer *argt;
193
194 (void)size;
195 argt = (struct ac_memsif_xfer *)arg;
196 addr = argt->mvec;
197 v36 = argt->item;
198 acMemSetup(&mem_data, memec->mvec, 256);
199 rpl->error = 0;
200 ret = 0;
201 v37 = v36;
202 v40 = 0xFFFFFFE;
203 v5 = v37;
204 while ( v37 > 0 )
205 {
206 int v6;
207 int buf_vectors;
208 int pos_v35;
209
210 v6 = acMemReceive(&mem_data, (acMemEEaddr)addr, 16 * v5);
211 ret = v6;
212 if ( v6 < 0 )
213 break;
214 pos_v35 = 0;
215 buf_vectors = v6 >> 4;
216 while ( pos_v35 < buf_vectors )
217 {
218 mvec = &memec->mvec[pos_v35];
219 v8 = memec->mvec[pos_v35].mv_src & 0xF0000000;
220 if ( v8 == 1342177280 )
221 {
222 xfer_src = meme_sram_read;
223 }
224 else if ( v8 > 0x50000000 )
225 {
226 xfer_src = 0;
227 if ( v8 == 0x60000000 )
228 xfer_src = meme_jv_read;
229 }
230 else
231 {
232 xfer_src = 0;
233 if ( v8 == 0x40000000 )
234 xfer_src = meme_ram_read;
235 }
236 v10 = memec->mvec[pos_v35].mv_dst & 0xF0000000;
237 if ( v10 == 0x50000000 )
238 {
239 xfer_dst = meme_sram_write;
240 }
241 else if ( v10 > 0x50000000 )
242 {
243 xfer_dst = 0;
244 if ( v10 == 0x60000000 )
245 xfer_dst = meme_jv_write;
246 }
247 else
248 {
249 xfer_dst = 0;
250 if ( v10 == 0x40000000 )
251 xfer_dst = meme_ram_write;
252 }
253 ret = 0;
254 if ( xfer_src )
255 {
256 v12 = -134;
257 if ( xfer_dst )
258 {
259 mvec->mv_result = -134;
260 ret = v12;
261 }
262 }
263 else
264 {
265 v12 = -134;
266 if ( !xfer_dst )
267 {
268 mvec->mv_result = -134;
269 ret = v12;
270 }
271 }
272 if ( ret >= 0 )
273 {
274 if ( !memec->mvec[pos_v35].mv_size )
275 {
276 mvec->mv_result = 0;
277 }
278 else
279 {
280 if ( xfer_src )
281 {
282 mv_dst = memec->mvec[pos_v35].mv_dst;
283 v14 = 0;
284 if ( (mv_dst & 1) != 0 )
285 {
286 dst = (acUint8 *)(mv_dst & v40);
287 mv_size = memec->mvec[pos_v35].mv_size;
288 for ( src = memec->mvec[pos_v35].mv_src & v40; mv_size > 0; src += ret_v14 )
289 {
290 ret_v14 = 0x20000;
291 if ( mv_size <= 0x20000 )
292 ret_v14 = mv_size;
293 v14 = xfer_src(src, dst, ret_v14);
294 dst += ret_v14;
295 if ( v14 <= 0 )
296 break;
297 mv_size -= ret_v14;
298 }
299 ret = v14;
300 mvec->mv_result = mvec->mv_size - mv_size;
301 }
302 else
303 {
304 dst_v15 = mv_dst & v40;
305 src_v16 = memec->mvec[pos_v35].mv_src & v40;
306 pos = 0;
307 buf = (acUint8 *)memec->buf;
308 bsize = (memec->size / 2) & 0xFFFFFFFC;
309 acMemSetup(mem_data_v29, buf, bsize);
310 acMemSetup(&mem_data_v29[1], &buf[bsize], bsize);
311 v23 = mvec->mv_size;
312 for ( ret = 0; v23 > 0; dst_v15 += v27 )
313 {
314 xlen = v23;
315 if ( bsize < v23 )
316 xlen = bsize;
317 ret = xfer_src(src_v16, &buf[pos], xlen);
318 if ( ret <= 0 )
319 break;
320 v25 = mem_data_v29;
321 if ( !pos )
322 v25 = &mem_data_v29[1];
323 ret = acMemWait(v25, 100, 110);
324 if ( ret < 0 )
325 break;
326 size_v22 = mem_data_v29;
327 if ( pos )
328 size_v22 = &mem_data_v29[1];
329 v27 = acMemSend(size_v22, dst_v15, xlen, 10);
330 ret = v27;
331 if ( v27 <= 0 )
332 break;
333 pos ^= bsize;
334 src_v16 += v27;
335 v23 -= v27;
336 }
337 size_v24 = mem_data_v29;
338 if ( !pos )
339 size_v24 = &mem_data_v29[1];
340 acMemWait(size_v24, 100, 110);
341 mvec->mv_result = mvec->mv_size - v23;
342 }
343 }
344 else
345 {
346 if ( (memec->mvec[pos_v35].mv_src & 1) != 0 )
347 {
348 ret = meme_xfer_ioptodev(memec, &memec->mvec[pos_v35], xfer_dst);
349 }
350 else
351 {
352 v12 = meme_xfer_eetodev(memec, &memec->mvec[pos_v35], xfer_dst);
353 ret = v12;
354 }
355 }
356 }
357 }
358 if ( ret < 0 )
359 break;
360 pos_v35 += 1;
361 }
362 if ( pos_v35 > 0 )
363 {
364 v29 = 16 * pos_v35;
365 reply = acMemSend(&mem_data, (acMemEEaddr)addr, 16 * pos_v35, 10);
366 if ( reply < 0 )
367 {
368 if ( ret < 0 )
369 break;
370 ret = reply;
371 }
372 else
373 {
374 addr = (acMemVecT)((char *)addr + v29);
375 v37 -= pos_v35;
376 acMemWait(&mem_data, 100, 110);
377 }
378 }
379 if ( ret < 0 )
380 break;
381 v5 = v37;
382 }
383 v31 = ret;
384 if ( v31 > 0 )
385 v31 = 0;
386 rpl->error = v31;
387 return v36 - v37;
388}
389
390static int meme_op_init(struct meme_softc *memec, struct ac_memsif_reply *rpl, const void *arg, int size)
391{
392 acInt32 v4;
393 void *buf_v3;
394 void *oldbuf;
395 const struct ac_memsif_init *argt;
396
397 (void)rpl;
398 (void)size;
399 argt = (const struct ac_memsif_init *)arg;
400 v4 = argt->size;
401 if ( argt->start == 0 )
402 {
403 void *buf_v1;
404
405 buf_v1 = memec->buf;
406 memec->buf = 0;
407 if ( buf_v1 )
408 FreeSysMemory(buf_v1);
409 return 0;
410 }
411 if ( v4 == 0 )
412 {
413 if ( memec->buf == 0 )
414 return -6;
415 return memec->size;
416 }
417 buf_v3 = AllocSysMemory(0, argt->size, 0);
418 if ( buf_v3 == 0 )
419 {
420 return -12;
421 }
422 oldbuf = memec->buf;
423 memec->buf = buf_v3;
424 if ( oldbuf )
425 FreeSysMemory(oldbuf);
426 memec->size = v4;
427 return v4;
428}
429
430static void *meme_request(unsigned int fno, struct meme_softc *data, int size)
431{
432 int v5;
433 meme_ops_t op;
434
435 data->status = 2;
436 data->pkt.rpl.error = 0;
437 if ( size != 16 )
438 {
439 v5 = -122;
440 }
441 else
442 {
443 if ( fno >= 3 || (op = ops_48[fno]) == 0 )
444 v5 = -88;
445 else
446 v5 = op(data, &data->pkt.rpl, data, 16);
447 }
448 if ( v5 < 0 )
449 {
450 data->pkt.rpl.error = -v5;
451 }
452 data->pkt.rpl.result = v5;
453 data->status = 1;
454 return data;
455}
456
457static void meme_thread(void *arg)
458{
459 int thid;
460 SifRpcDataQueue_t queue_data;
461 SifRpcServerData_t serv_data;
462 struct meme_softc *argt;
463
464 argt = (struct meme_softc *)arg;
465 thid = GetThreadId();
466 sceSifSetRpcQueue(&queue_data, thid);
467 sceSifRegisterRpc(&serv_data, 0x76500001, (SifRpcFunc_t)meme_request, argt, 0, 0, &queue_data);
468 argt->thid = thid;
469 while ( 1 )
470 {
472
473 s = sceSifGetNextRequest(&queue_data);
474 if ( s )
475 {
476 sceSifExecRequest(s);
477 }
478 else
479 {
480 SleepThread();
481 if ( thid != argt->thid )
482 ExitThread();
483 }
484 }
485}
486
487static int meme_thread_init(struct meme_softc *memec, int prio)
488{
489 int th;
490 iop_thread_t param;
491
492 param.attr = 0x2000000;
493 param.thread = meme_thread;
494 param.priority = prio;
495 param.stacksize = 4096;
496 param.option = 0;
497 th = CreateThread(&param);
498 if ( th > 0 )
499 StartThread(th, memec);
500 return th;
501}
502
503int acMemeModuleStatus()
504{
505 return Memec.status;
506}
507
508int acMemeModuleStart(int argc, char **argv)
509{
510 int index;
511 int prio;
512 char **v8;
513 char *opt;
514 int v10;
515 const char *opt_v7;
516 int value;
517 int ret;
518 int v14;
519 char *next;
520
521 if ( acMemeModuleStatus() == 0 )
522 {
523 return -16;
524 }
525 index = 1;
526 prio = 84;
527 v8 = argv + 1;
528 while ( index < argc )
529 {
530 opt = *v8;
531 if ( **v8 == 45 )
532 {
533 v10 = opt[1];
534 opt_v7 = opt + 2;
535 if ( v10 == 112 )
536 {
537 value = strtol(opt_v7, &next, 0);
538 if ( next != opt_v7 )
539 prio = value;
540 }
541 }
542 ++index;
543 ++v8;
544 }
545 memset(&Memec, 0, sizeof(Memec));
546 ret = meme_thread_init(&Memec, prio);
547 v14 = -6;
548 if ( ret > 0 )
549 {
550 v14 = 0;
551 Memec.thid = ret;
552 Memec.buf = 0;
553 Memec.size = 0;
554 Memec.status = 1;
555 }
556 return v14;
557}
558
559int acMemeModuleStop()
560{
561 int thid;
562 void *buf;
563
564 if ( acMemeModuleStatus() == 0 )
565 {
566 return 0;
567 }
568 thid = Memec.thid;
569 if ( Memec.thid > 0 )
570 {
571 int retry;
572 int ret;
573
574 Memec.thid = 0;
575 WakeupThread(thid);
576 DelayThread(1000);
577 for ( retry = 9; retry >= 0; --retry )
578 {
579 ret = DeleteThread(thid);
580 if ( !ret )
581 break;
582 DelayThread(1000000);
583 }
584 if ( retry < 0 )
585 printf("acmeme:thread:term: TIMEDOUT %d\n", ret);
586 }
587 buf = Memec.buf;
588 Memec.size = 0;
589 Memec.buf = 0;
590 if ( buf )
591 FreeSysMemory(buf);
592 Memec.status = 0;
593 return 0;
594}
595
596int acMemeModuleRestart(int argc, char **argv)
597{
598 (void)argc;
599 (void)argv;
600
601 return -88;
602}
Definition acmem.h:17
Definition acram.h:23