/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/fps2bios/kernel/eeload/eekernel.c
ViewVC logotype

Contents of /branch/r3113_0.9.7_beta/fps2bios/kernel/eeload/eekernel.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years, 10 months ago) by william
File MIME type: text/plain
File size: 97951 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 //[module] KERNEL
2 //[processor] EE
3 //[type] RAW
4 //[size] 80880(0x13BF0)
5 //[bios] 10000(0xB3200-0xC6DF0)
6 //[iopboot] NA
7 //[loaded @] 80000000
8 //[name] NA
9 //[version] NA
10 //[memory map] [too many, see mem.txt]
11 //[handlers]
12 //[entry point] ENTRYPOINT @ 0x80001000
13 //[made by] [RO]man, zerofrog & others
14 #include <tamtypes.h>
15 #include <stdio.h>
16
17 #include "eekernel.h"
18 #include "eeinit.h"
19 #include "eedebug.h"
20 #include "romdir.h"
21
22 #define PS2_LOADADDR 0x82000
23
24 // internal functions
25 int InitPgifHandler();
26 int InitPgifHandler2();
27
28 struct ll* LL_unlink(struct ll *l);
29 struct ll* LL_rotate(struct ll *l);
30 struct ll *LL_unlinkthis(struct ll *l);
31 void LL_add(struct ll *l, struct ll *new);
32
33 extern int (*table_GetCop0[32])(int reg); // 124E8-12564
34 extern int (*table_SetCop0[32])(int reg, int val); // 12568-125E4
35
36 void DefaultCPUTimerHandler();
37 void _excepRet(u32 eretpc, u32 v1, u32 a, u32 a1, u32 a2);
38 int __ExitThread();
39 int __ExitDeleteThread();
40 int __SleepThread();
41 int _iWaitSema(int sid);
42
43 void saveContext();
44 void restoreContext();
45
46 int _SemasInit();
47
48 void _ThreadHandler(u32 epc, u32 stack);
49 void _ChangeThread(u32 entry, u32 stack_res, int waitSema);
50
51 int __DeleteThread(int tid);
52 int __StartThread(int tid, void *arg);
53 int __load_module(char *name, void (*entry)(void*), void *stack_res, int prio);
54 void* __ExecPS2(void * entry, void * gp, int argc, char ** argv);
55
56 void releaseTCB(int tid);
57 void unsetTCB(int tid);
58 void thread_2_ready(int tid);
59
60 void FlushInstructionCache();
61 void FlushDataCache();
62 void FlushSecondaryCache();
63
64 void SifDmaInit();
65
66 u32 excepRetPc=0;//124E4
67 int threadId=0; // 125EC
68 int threadPrio=0; // 125F0
69 int threadStatus=0; // 125F4
70
71 char threadArgStrBuffer[256]; // 12608
72 u64 hvParam;
73
74 u32 machineType;
75 u64 gsIMR;
76 u32 memorySize;
77
78 u8 g_kernelstack[0x2000] __attribute((aligned(128)));
79 u32 g_kernelstackend; // hopefully this is right after g_kernelstack
80
81 int _HandlersCount;
82
83 int VSyncFlag0;
84 int VSyncFlag1;
85
86 struct ll handler_ll_free, *ihandlers_last=NULL, *ihandlers_first=NULL;
87 struct HCinfo intcs_array[14];
88 struct ll *dhandlers_last=NULL, *dhandlers_first=NULL;
89 struct HCinfo dmacs_array[15];
90 struct IDhandl pgifhandlers_array[161];
91 void (*sbus_handlers[32])(int ca);
92 void (*CPUTimerHandler)() = DefaultCPUTimerHandler; //12480
93
94 u64 _alarm_unk = 0;
95 u64 rcnt3Valid=0;//16A68
96 int rcnt3Count = 0; //16A70
97 u32 dword_80016A78, dword_80016A7C, dword_80016A84, dword_80016A88;
98 //u32 rcnt3gp; //16A80
99 //u32 rcnt3Mode; //16A84
100 int rcnt3TargetTable[0x142]={0};//16A80
101 u8 rcnt3TargetNum[0x40];//16F78
102 int threads_count=0;
103
104 u32 excepRA=0;//16FC0
105 u32 excepSP=0;//16FD0
106
107 struct ll thread_ll_free;
108 struct ll thread_ll_priorities[128];
109 int semas_count=0;
110 struct kSema* semas_last=0;
111
112 struct TCB threads_array[256];
113 struct kSema semas_array[256];
114
115 char tagindex=0;//1E104
116 short transferscount=0;//1E106
117 struct TAG tadrptr[31] __attribute((aligned(16)));//1E140
118 int extrastorage[(16/4) * 8][31] __attribute((aligned(16)));//1E340
119
120 int osdConfigParam;//1F340
121
122 u32 sifEEbuff[32] __attribute((aligned(16)));
123 u32 sifRegs[32] __attribute((aligned(16)));
124 u32 sifIOPbuff;
125 u32 sif1tagdata;
126
127 void _eret()
128 {
129 __asm__("mfc0 $26, $12\n"
130 "ori $26, 0x13\n"
131 "mtc0 $26, $12\n"
132 "sync\n"
133 "eret\n"
134 "nop\n");
135 }
136
137 #define eret() __asm__("j _eret\nnop\n");
138
139 ////////////////////////////////////////////////////////////////////
140 //800006C0 SYSCALL 116 RFU116_SetSYSCALL
141 ////////////////////////////////////////////////////////////////////
142 void _SetSYSCALL(int num, int address)
143 {
144 table_SYSCALL[num] = (void (*)())address;
145 }
146
147 ////////////////////////////////////////////////////////////////////
148 //80000740 SYSCALL 114 SetPgifHandler
149 ////////////////////////////////////////////////////////////////////
150 void _SetPgifHandler(void (*handler)(int))
151 {
152 INTCTable[15] = handler;
153 }
154
155 ////////////////////////////////////////////////////////////////////
156 //800007C0 SYSCALL 108 SetCPUTimerHandler
157 ////////////////////////////////////////////////////////////////////
158 void _SetCPUTimerHandler(void (*handler)())
159 {
160 CPUTimerHandler = handler;
161 }
162
163 ////////////////////////////////////////////////////////////////////
164 //80000800 SYSCALL 109 SetCPUTimer
165 ////////////////////////////////////////////////////////////////////
166 void _SetCPUTimer(int compval)
167 {
168 if( compval < 0 ) {
169 u32 status;
170 __asm__("mfc0 %0, $12\n" : "=r"(status) : );
171 __asm__("mtc0 %0, $12\n"
172 "mtc0 $0, $9\n" : : "r"(status|0x18001));
173 }
174 else if( compval == 0 ) {
175 u32 compare, status;
176 __asm__("mfc0 %0, $12\n"
177 "mfc0 %1, $11\n"
178 : "=r"(status), "=r"(compare) : );
179 __asm__("mtc0 %0, $12\n"
180 "mtc0 $0, $9\n"
181 "mtc0 %1, $11\n"
182 : : "r"(status&~0x8000), "r"(compare) );
183 }
184 else {
185 __asm__("mtc0 $0, $9\n" // count
186 "mtc0 %0, $11\n" // compare
187 : : "r"(compval));
188 }
189 }
190
191 ////////////////////////////////////////////////////////////////////
192 //800008C0 SYSCALL 020 EnableIntc
193 ////////////////////////////////////////////////////////////////////
194 int __EnableIntc(int ch)
195 {
196 int intbit;
197
198 intbit = 0x1 << ch;
199 if ((INTC_MASK & intbit) != 0) return 0;
200
201 INTC_MASK = intbit;
202
203 return 1;
204 }
205
206 ////////////////////////////////////////////////////////////////////
207 //80000900 SYSCALL 021 DisableIntc
208 ////////////////////////////////////////////////////////////////////
209 int __DisableIntc(int ch)
210 {
211 int intbit;
212
213 intbit = 0x1 << ch;
214 if ((INTC_MASK & intbit) == 0) return 0;
215
216 INTC_MASK = intbit;
217
218 return 1;
219 }
220
221 ////////////////////////////////////////////////////////////////////
222 //80000940 SYSCALL 022 EnableDmac
223 ////////////////////////////////////////////////////////////////////
224 int __EnableDmac(int ch)
225 {
226 int dmabit;
227
228 dmabit = 0x10000 << ch;
229 if ((DMAC_STAT & dmabit) != 0) return 0;
230
231 DMAC_STAT = dmabit;
232
233 return 1;
234 }
235
236 ////////////////////////////////////////////////////////////////////
237 //80000980 SYSCALL 023 DisableDmac
238 ////////////////////////////////////////////////////////////////////
239 int __DisableDmac(int ch)
240 {
241 int dmabit;
242
243 dmabit = 0x10000 << ch;
244 if ((DMAC_STAT & dmabit) == 0) return 0;
245
246 DMAC_STAT = dmabit;
247
248 return 1;
249 }
250
251 ////////////////////////////////////////////////////////////////////
252 //800009C0 SYSCALL 013 SetVTLBRefillHandler
253 ////////////////////////////////////////////////////////////////////
254 void* _SetVTLBRefillHandler(int cause, void (*handler)())
255 {
256 if ((cause-1) >= 3) return 0;
257
258 VCRTable[cause] = handler;
259
260 return handler;
261 }
262
263 ////////////////////////////////////////////////////////////////////
264 //80000A00 SYSCALL 014 SetVCommonHandler
265 ////////////////////////////////////////////////////////////////////
266 void* _SetVCommonHandler(int cause, void (*handler)())
267 {
268 if ((cause-4) >= 10) return 0;
269
270 VCRTable[cause] = handler;
271
272 return handler;
273 }
274
275 ////////////////////////////////////////////////////////////////////
276 //80000A40 SYSCALL 015 SetVInterruptHandler
277 ////////////////////////////////////////////////////////////////////
278 void* _SetVInterruptHandler(int cause, void (*handler)())
279 {
280 if (cause >= 8) return 0;
281
282 VIntTable[cause] = handler;
283 // no return value...
284 }
285
286 ////////////////////////////////////////////////////////////////////
287 //80000A80 SYSCALL 102,106 CpuConfig
288 ////////////////////////////////////////////////////////////////////
289 u32 _CpuConfig(u32 op)
290 {
291 u32 cfg;
292 __asm__("mfc0 %0, $16\n" : "=r"(cfg) : );
293 return table_CpuConfig[op](cfg);
294 }
295
296 ////////////////////////////////////////////////////////////////////
297 //80000AB8
298 ////////////////////////////////////////////////////////////////////
299 u32 _CpuConfig_0(u32 cfg)
300 {
301 cfg |= 0x40000;
302 __asm__("mtc0 %0, $16\n"
303 "sync\n": : "r"(cfg));
304 return cfg;
305 }
306
307 ////////////////////////////////////////////////////////////////////
308 //80000AD0
309 ////////////////////////////////////////////////////////////////////
310 u32 _CpuConfig_1(u32 cfg)
311 {
312 cfg |= 0x2000;
313 __asm__("mtc0 %0, $16\n"
314 "sync\n": : "r"(cfg));
315 return cfg;
316 }
317
318 ////////////////////////////////////////////////////////////////////
319 //80000AEC
320 ////////////////////////////////////////////////////////////////////
321 u32 _CpuConfig_2(u32 cfg)
322 {
323 cfg |= 0x1000;
324 __asm__("mtc0 %0, $16\n"
325 "sync\n": : "r"(cfg));
326 return cfg;
327 }
328
329 ////////////////////////////////////////////////////////////////////
330 //80000B04
331 ////////////////////////////////////////////////////////////////////
332 u32 _CpuConfig_3(u32 cfg)
333 {
334 cfg &= ~0x40000;
335 __asm__("mtc0 %0, $16\n"
336 "sync\n": : "r"(cfg));
337 return cfg;
338 }
339
340 ////////////////////////////////////////////////////////////////////
341 //80000B20
342 ////////////////////////////////////////////////////////////////////
343 u32 _CpuConfig_4(u32 cfg)
344 {
345 cfg &= ~0x2000;
346 __asm__("mtc0 %0, $16\n"
347 "sync\n": : "r"(cfg));
348 return cfg;
349 }
350
351 ////////////////////////////////////////////////////////////////////
352 //80000B40
353 ////////////////////////////////////////////////////////////////////
354 u32 _CpuConfig_5(u32 cfg)
355 {
356 cfg &= ~0x1000;
357 __asm__("mtc0 %0, $16\n"
358 "sync\n": : "r"(cfg));
359 return cfg;
360 }
361
362 ////////////////////////////////////////////////////////////////////
363 //80000B80 SYSCALL 125 PSMode
364 ////////////////////////////////////////////////////////////////////
365 void _PSMode()
366 {
367 machineType|= 0x8000;
368 }
369
370 ////////////////////////////////////////////////////////////////////
371 //80000BC0 SYSCALL 126 MachineType
372 ////////////////////////////////////////////////////////////////////
373 u32 _MachineType()
374 {
375 return machineType;
376 }
377
378 ////////////////////////////////////////////////////////////////////
379 //80000C00
380 ////////////////////////////////////////////////////////////////////
381 u32 _SetMemorySize(u32 size)
382 {
383 memorySize = size;
384 return size;
385 }
386
387 ////////////////////////////////////////////////////////////////////
388 //80000C40 SYSCALL 127 GetMemorySize
389 ////////////////////////////////////////////////////////////////////
390 u32 _GetMemorySize()
391 {
392 return memorySize;
393 }
394
395 ////////////////////////////////////////////////////////////////////
396 //80000D00 SYSCALL 112 GsGetIMR
397 ////////////////////////////////////////////////////////////////////
398 u64 _GsGetIMR()
399 {
400 return gsIMR;
401 }
402
403 ////////////////////////////////////////////////////////////////////
404 //80000D40 SYSCALL 113 GsPutIMR
405 ////////////////////////////////////////////////////////////////////
406 u64 _GsPutIMR(u64 val)
407 {
408 GS_IMR = val;
409 gsIMR = val;
410 return val;
411 }
412
413 ////////////////////////////////////////////////////////////////////
414 //80000D80 SYSCALL 002 Exit
415 ////////////////////////////////////////////////////////////////////
416 int _Exit()
417 {
418 return _RFU004_Exit();
419 }
420
421 ////////////////////////////////////////////////////////////////////
422 //80001000 ENTRYPOINT
423 ////////////////////////////////////////////////////////////////////
424 void __attribute__((noreturn)) _start()
425 {
426 __asm__("lui $sp, %hi(g_kernelstackend)\n"
427 "addiu $sp, %lo(g_kernelstackend)\n");
428
429 __puts("EEKERNEL start\n");
430
431 memorySize = 32*1024*1024;
432 machineType = 0;
433 //memorySize = *(int*)0x70003FF0;
434 //machineType = machine_type;
435
436 __printf("TlbInit\n");
437 TlbInit();
438 __printf("InitPgifHandler\n");
439 InitPgifHandler();
440 __printf("Initialize\n");
441 Initialize();
442 // __load_module_EENULL();
443
444 __asm__ (
445 "li $26, %0\n"
446 "lw $26, 0($26)\n"
447 "mtc0 $26, $12\n"
448 "li $26, %1\n"
449 "lw $26, 0($26)\n"
450 "mtc0 $26, $16\n"
451 : : "i"(SRInitVal), "i"(ConfigInitVal)
452 );
453
454 // ee_deci2_manager_init();
455 SifDmaInit();
456 // __init_unk(0x81FE0);
457 SetVSyncFlag(0, 0);
458
459 // call directly instread of loading module, might need to
460 // set thread0 as used since soem code assumes thread 0 is always
461 // main thread
462 //eeload_start();
463 //launch_thread(__load_module("EELOAD", 0x82000, 0x81000, 0));
464
465 for (;;);
466 }
467
468 ////////////////////////////////////////////////////////////////////
469 //80001300
470 ////////////////////////////////////////////////////////////////////
471 void saveContext2() {
472 __asm__ (
473 ".set noat\n"
474 "lui $26, %hi(SavedRegs)\n"
475 "sq $2, %lo(SavedRegs+0x000)($26)\n"
476 "sq $3, %lo(SavedRegs+0x010)($26)\n"
477 "sq $4, %lo(SavedRegs+0x020)($26)\n"
478 "sq $5, %lo(SavedRegs+0x030)($26)\n"
479 "sq $6, %lo(SavedRegs+0x040)($26)\n"
480 "sq $7, %lo(SavedRegs+0x050)($26)\n"
481 "sq $8, %lo(SavedRegs+0x060)($26)\n"
482 "sq $9, %lo(SavedRegs+0x070)($26)\n"
483 "sq $10, %lo(SavedRegs+0x080)($26)\n"
484 "sq $11, %lo(SavedRegs+0x090)($26)\n"
485 "sq $12, %lo(SavedRegs+0x0A0)($26)\n"
486 "sq $13, %lo(SavedRegs+0x0B0)($26)\n"
487 "sq $14, %lo(SavedRegs+0x0C0)($26)\n"
488 "sq $15, %lo(SavedRegs+0x0D0)($26)\n"
489 "sq $16, %lo(SavedRegs+0x0E0)($26)\n"
490 "sq $17, %lo(SavedRegs+0x0F0)($26)\n"
491 "sq $18, %lo(SavedRegs+0x100)($26)\n"
492 "sq $19, %lo(SavedRegs+0x110)($26)\n"
493 "sq $20, %lo(SavedRegs+0x120)($26)\n"
494 "sq $21, %lo(SavedRegs+0x130)($26)\n"
495 "sq $22, %lo(SavedRegs+0x140)($26)\n"
496 "sq $23, %lo(SavedRegs+0x150)($26)\n"
497 "sq $24, %lo(SavedRegs+0x160)($26)\n"
498 "sq $25, %lo(SavedRegs+0x170)($26)\n"
499 "sq $gp, %lo(SavedRegs+0x180)($26)\n"
500 "sq $fp, %lo(SavedRegs+0x190)($26)\n"
501
502 "mfhi $2\n"
503 "sd $2, %lo(SavedRegs+0x1A0)($26)\n"
504 "mfhi1 $2\n"
505 "sd $2, %lo(SavedRegs+0x1A8)($26)\n"
506
507 "mflo $2\n"
508 "sd $2, %lo(SavedRegs+0x1B0)($26)\n"
509 "mflo1 $2\n"
510 "sd $2, %lo(SavedRegs+0x1B8)($26)\n"
511
512 "mfsa $2\n"
513 "sd $2, %lo(SavedRegs+0x1C0)($26)\n"
514 "jr $31\n"
515 "nop\n"
516 ".set at\n"
517 );
518 }
519
520 ////////////////////////////////////////////////////////////////////
521 //800013C0
522 ////////////////////////////////////////////////////////////////////
523 void restoreContext2() {
524 __asm__ (
525 ".set noat\n"
526 "lui $26, %hi(SavedRegs)\n"
527 "lq $2, %lo(SavedRegs+0x000)($26)\n"
528 "lq $3, %lo(SavedRegs+0x010)($26)\n"
529 "lq $4, %lo(SavedRegs+0x020)($26)\n"
530 "lq $5, %lo(SavedRegs+0x030)($26)\n"
531 "lq $6, %lo(SavedRegs+0x040)($26)\n"
532 "lq $7, %lo(SavedRegs+0x050)($26)\n"
533 "lq $8, %lo(SavedRegs+0x060)($26)\n"
534 "lq $9, %lo(SavedRegs+0x070)($26)\n"
535 "lq $10, %lo(SavedRegs+0x080)($26)\n"
536 "lq $11, %lo(SavedRegs+0x090)($26)\n"
537 "lq $12, %lo(SavedRegs+0x0A0)($26)\n"
538 "lq $13, %lo(SavedRegs+0x0B0)($26)\n"
539 "lq $14, %lo(SavedRegs+0x0C0)($26)\n"
540 "lq $15, %lo(SavedRegs+0x0D0)($26)\n"
541 "lq $16, %lo(SavedRegs+0x0E0)($26)\n"
542 "lq $17, %lo(SavedRegs+0x0F0)($26)\n"
543 "lq $18, %lo(SavedRegs+0x100)($26)\n"
544 "lq $19, %lo(SavedRegs+0x110)($26)\n"
545 "lq $20, %lo(SavedRegs+0x120)($26)\n"
546 "lq $21, %lo(SavedRegs+0x130)($26)\n"
547 "lq $22, %lo(SavedRegs+0x140)($26)\n"
548 "lq $23, %lo(SavedRegs+0x150)($26)\n"
549 "lq $24, %lo(SavedRegs+0x160)($26)\n"
550 "lq $25, %lo(SavedRegs+0x170)($26)\n"
551 "lq $gp, %lo(SavedRegs+0x180)($26)\n"
552 "lq $fp, %lo(SavedRegs+0x190)($26)\n"
553
554 "ld $1, %lo(SavedRegs+0x1A0)($26)\n"
555 "mthi $1\n"
556 "ld $1, %lo(SavedRegs+0x1A8)($26)\n"
557 "mthi1 $1\n"
558
559 "ld $1, %lo(SavedRegs+0x1B0)($26)\n"
560 "mtlo $1\n"
561 "ld $1, %lo(SavedRegs+0x1B8)($26)\n"
562 "mtlo1 $1\n"
563
564 "ld $1, %lo(SavedRegs+0x1C0)($26)\n"
565 "mtsa $1\n"
566
567 "jr $31\n"
568 "nop\n"
569 ".set at\n"
570 );
571 }
572
573 ////////////////////////////////////////////////////////////////////
574 //80001460
575 ////////////////////////////////////////////////////////////////////
576 void erase_cpu_regs()
577 {
578 __asm__(
579 ".set noat\n"
580 "padduw $1, $0, $0\n"
581 "padduw $2, $0, $0\n"
582 "padduw $3, $0, $0\n"
583 "padduw $4, $0, $0\n"
584 "padduw $5, $0, $0\n"
585 "padduw $6, $0, $0\n"
586 "padduw $7, $0, $0\n"
587 "padduw $8, $0, $0\n"
588 "padduw $9, $0, $0\n"
589 "padduw $10, $0, $0\n"
590 "padduw $11, $0, $0\n"
591 "padduw $12, $0, $0\n"
592 "padduw $13, $0, $0\n"
593 "padduw $14, $0, $0\n"
594 "padduw $15, $0, $0\n"
595 "padduw $16, $0, $0\n"
596 "padduw $17, $0, $0\n"
597 "padduw $18, $0, $0\n"
598 "padduw $19, $0, $0\n"
599 "padduw $20, $0, $0\n"
600 "padduw $21, $0, $0\n"
601 "padduw $22, $0, $0\n"
602 "padduw $23, $0, $0\n"
603 "padduw $24, $0, $0\n"
604 "padduw $25, $0, $0\n"
605 "padduw $gp, $0, $0\n"
606 "jr $31\n"
607 "padduw $fp, $0, $0\n"
608 ".set at\n"
609 );
610 }
611
612 ////////////////////////////////////////////////////////////////////
613 //800014D8 dummy intc handler
614 ////////////////////////////////////////////////////////////////////
615 void _DummyINTCHandler(int n)
616 {
617 __printf("# INT: INTC (%d)\n", n);
618 while(1) { __asm__ ("nop\nnop\nnop\nnop\n"); }
619 }
620
621 ////////////////////////////////////////////////////////////////////
622 //80001508 dummy dmac handler
623 ////////////////////////////////////////////////////////////////////
624 void _DummyDMACHandler(int n)
625 {
626 __printf("# INT: DMAC (%d)\n", n);
627 while(1) { __asm__ ("nop\nnop\nnop\nnop\n"); }
628 }
629
630 ////////////////////////////////////////////////////////////////////
631 //80001508
632 ////////////////////////////////////////////////////////////////////
633 void DefaultCPUTimerHandler()
634 {
635 __printf("# INT: CPU Timer\n");
636 }
637
638 ////////////////////////////////////////////////////////////////////
639 //80001564 SYSCALL 000 RFU000_FullReset
640 //80001564 SYSCALL 003 RFU003 (also)
641 //80001564 SYSCALL 008 RFU008 (too)
642 ////////////////////////////////////////////////////////////////////
643 void _RFU___()
644 {
645 register int syscnum __asm__("$3");
646 __printf("# Syscall: undefined (%d)\n", syscnum>>2);
647 }
648
649 ////////////////////////////////////////////////////////////////////
650 //80001588
651 ////////////////////////////////////////////////////////////////////
652 void _SetVSyncFlag(int flag0, int flag1)
653 {
654 VSyncFlag0 = flag0;
655 VSyncFlag1 = flag1;
656 }
657
658 ////////////////////////////////////////////////////////////////////
659 //800015A0
660 ////////////////////////////////////////////////////////////////////
661 struct ll* _AddHandler()
662 {
663 struct ll *l;
664
665 l = LL_unlink(&handler_ll_free);
666 if (l == NULL) return NULL;
667
668 _HandlersCount++;
669 return l;
670 }
671
672 ////////////////////////////////////////////////////////////////////
673 //800015E8
674 ////////////////////////////////////////////////////////////////////
675 void _RemoveHandler(int n)
676 {
677 LL_add(&handler_ll_free, (struct ll*)&pgifhandlers_array[n]);
678 _HandlersCount--;
679 }
680
681 ////////////////////////////////////////////////////////////////////
682 //80001630
683 ////////////////////////////////////////////////////////////////////
684 void DefaultINTCHandler(int n)
685 {
686 //TODO
687 }
688
689 ////////////////////////////////////////////////////////////////////
690 //80001798
691 ////////////////////////////////////////////////////////////////////
692 void DefaultDMACHandler(int n)
693 {
694 //TODO
695 }
696
697 ////////////////////////////////////////////////////////////////////
698 //800018B0
699 ////////////////////////////////////////////////////////////////////
700 int __AddIntcHandler(int cause, int (*handler)(int), int next, void *arg, int flag)
701 {
702 struct IDhandl *idh;
703
704 if ((flag != 0) && (cause == INTC_SBUS)) return -1;
705 if (cause >= 15) return -1;
706
707 idh = (struct IDhandl *)_AddHandler();
708 if (idh == 0) return -1;
709
710 idh->handler = handler;
711 __asm__ ("sw $gp, %0\n" : "=m"(idh->gp) : );
712 idh->arg = arg;
713 idh->flag = flag;
714
715 if (next==-1) //register_last
716 LL_add(&ihandlers_last[cause*12], (struct ll*)idh);
717 else if (next==0) //register_first
718 LL_add(&ihandlers_first[cause*12], (struct ll*)idh);
719 else{
720 if (next>128) return -1;
721 if (pgifhandlers_array[next].flag==3) return -1;
722 LL_add((struct ll*)&pgifhandlers_array[next], (struct ll*)idh);
723 }
724
725 intcs_array[cause].count++;
726 return (((u32)idh-(u32)&pgifhandlers_array) * 0xAAAAAAAB) / 8;
727 }
728
729 ////////////////////////////////////////////////////////////////////
730 //80001A30 SYSCALL 016 AddIntcHandler
731 ////////////////////////////////////////////////////////////////////
732 int _AddIntcHandler(int cause, int (*handler)(int), int next, void *arg)
733 {
734 __AddIntcHandler(cause, handler, next, arg, 2);
735 }
736
737 ////////////////////////////////////////////////////////////////////
738 //80001A50
739 ////////////////////////////////////////////////////////////////////
740 int _AddIntcHandler2(int cause, int (*handler)(int), int next, void *arg)
741 {
742 __AddIntcHandler(cause, handler, next, arg, 0);
743 }
744
745 ////////////////////////////////////////////////////////////////////
746 //80001AC8 SYSCALL 017 RemoveIntcHandler
747 ////////////////////////////////////////////////////////////////////
748 int _RemoveIntcHandler(int cause, int hid)
749 {
750 if (hid >= 128) return -1;
751
752 if (pgifhandlers_array[hid].flag == 3) return -1;
753 pgifhandlers_array[hid].flag = 3;
754 pgifhandlers_array[hid].handler = 0;
755
756 LL_unlinkthis((struct ll*)&pgifhandlers_array[hid]);
757 _RemoveHandler(hid);
758
759 intcs_array[cause].count--;
760 }
761
762 ////////////////////////////////////////////////////////////////////
763 //80001B10
764 ////////////////////////////////////////////////////////////////////
765 int __AddDmacHandler(int cause, int (*handler)(int), int next, void *arg, int flag)
766 {
767 struct IDhandl *idh;
768 register int temp;
769
770 if (cause >= 16) return -1;
771
772 idh = (struct IDhandl *)_AddHandler();
773 if (idh == 0) return -1;
774
775 idh->handler = handler;
776 __asm__ ("sw $gp, %0\n" : "=m"(idh->gp) : );
777 idh->arg = arg;
778 idh->flag = flag;
779
780 if (next==-1) //register_last
781 LL_add(&dhandlers_last[cause*12], (struct ll*)idh);
782 else if (next==0) //register_first
783 LL_add(&dhandlers_first[cause*12], (struct ll*)idh);
784 else{
785 if (next>128) return -1;
786 if (pgifhandlers_array[next].flag==3) return -1;
787 LL_add((struct ll*)&pgifhandlers_array[next], (struct ll*)idh);
788 }
789
790 dmacs_array[cause].count++;
791 return (((u32)idh-(u32)&pgifhandlers_array) * 0xAAAAAAAB) / 8;
792 }
793
794 ////////////////////////////////////////////////////////////////////
795 //80001C78 SYSCALL 018 AddDmacHandler
796 ////////////////////////////////////////////////////////////////////
797 int _AddDmacHandler(int cause, int (*handler)(int), int next, void *arg)
798 {
799 __AddDmacHandler(cause, handler, next, arg, 2);
800 }
801
802 ////////////////////////////////////////////////////////////////////
803 //80001C98
804 ////////////////////////////////////////////////////////////////////
805 int _AddDmacHandler2(int cause, int (*handler)(int), int next, void *arg)
806 {
807 __AddDmacHandler(cause, handler, next, arg, 0);
808 }
809
810 ////////////////////////////////////////////////////////////////////
811 //80001CB8 SYSCALL 019 RemoveDmacHandler
812 ////////////////////////////////////////////////////////////////////
813 int _RemoveDmacHandler(int cause, int hid)
814 {
815 if (hid >= 128) return -1;
816
817 if (pgifhandlers_array[hid].flag == 3) return -1;
818 pgifhandlers_array[hid].flag = 3;
819 pgifhandlers_array[hid].handler = 0;
820
821 LL_unlinkthis((struct ll*)&pgifhandlers_array[hid]);
822 _RemoveHandler(hid);
823
824 dmacs_array[cause].count--;
825 }
826
827 ////////////////////////////////////////////////////////////////////
828 //80001D58
829 ////////////////////////////////////////////////////////////////////
830 void sbusHandler()
831 {
832 //TODO
833 }
834
835 ////////////////////////////////////////////////////////////////////
836 //80001E38
837 ////////////////////////////////////////////////////////////////////
838 int __AddSbusIntcHandler(int cause, void (*handler)(int ca))
839 {
840 if (cause >= 32) return -1;
841
842 if (sbus_handlers[cause] != 0) return -1;
843
844 sbus_handlers[cause] = handler;
845 return cause;
846 }
847
848 ////////////////////////////////////////////////////////////////////
849 //80001E78 SYSCALL 010 AddSbusIntcHandler
850 ////////////////////////////////////////////////////////////////////
851 int _AddSbusIntcHandler(int cause, void (*handler)(int ca))
852 {
853 if (cause < 16) return __AddSbusIntcHandler(cause, handler);
854
855 return -1;
856 }
857
858 ////////////////////////////////////////////////////////////////////
859 //80001EA8
860 ////////////////////////////////////////////////////////////////////
861 int __RemoveSbusIntcHandler(int cause)
862 {
863 if (cause >= 32) return -1;
864
865 sbus_handlers[cause] = 0;
866 return cause;
867 }
868
869 ////////////////////////////////////////////////////////////////////
870 //80001ED0 SYSCALL 011 RemoveSbusIntcHandler
871 ////////////////////////////////////////////////////////////////////
872 int _RemoveSbusIntcHandler(int cause)
873 {
874 if (cause < 16) return __RemoveSbusIntcHandler(cause);
875
876 return -1;
877 }
878
879 ////////////////////////////////////////////////////////////////////
880 //80001F00
881 ////////////////////////////////////////////////////////////////////
882 int __Interrupt2Iop(int cause)
883 {
884 if (cause >= 32) {
885 return -1;
886 }
887
888 SBUS_MSFLG = 1 << cause;
889
890 SBUS_F240 = 0x100;
891 SBUS_F240 = 0x100;
892 SBUS_F240 = 0x100;
893 SBUS_F240 = 0x100;
894 SBUS_F240 = 0x100;
895 SBUS_F240 = 0x100;
896 SBUS_F240 = 0x100;
897 SBUS_F240 = 0x100; // eight times
898
899 SBUS_F240 = 0x40100;
900
901 return cause;
902 }
903
904 ////////////////////////////////////////////////////////////////////
905 //80001F70 SYSCALL 012 Interrupt2Iop
906 ////////////////////////////////////////////////////////////////////
907 int _Interrupt2Iop(int cause)
908 {
909 if (cause < 16) {
910 return _Interrupt2Iop(cause);
911 } else {
912 return -1;
913 }
914 }
915
916 ////////////////////////////////////////////////////////////////////
917 //80001FA0 SYSCALL 092 EnableIntcHandler
918 ////////////////////////////////////////////////////////////////////
919 void _EnableIntcHandler(u32 id)
920 {
921 pgifhandlers_array[id].flag = 2;
922 }
923
924 ////////////////////////////////////////////////////////////////////
925 //80001FA0 SYSCALL 093 DisableIntcHandler
926 ////////////////////////////////////////////////////////////////////
927 void _DisableIntcHandler(u32 id)
928 {
929 pgifhandlers_array[id].flag = 1;
930 }
931
932 ////////////////////////////////////////////////////////////////////
933 //80001FA0 SYSCALL 094 EnableDmacHandler
934 ////////////////////////////////////////////////////////////////////
935 void _EnableDmacHandler(u32 id)
936 {
937 pgifhandlers_array[id].flag = 2;
938 }
939
940 ////////////////////////////////////////////////////////////////////
941 //80001FA0 SYSCALL 095 DisableDmacHandler
942 ////////////////////////////////////////////////////////////////////
943 void _DisableDmacHandler(u32 id)
944 {
945 pgifhandlers_array[id].flag = 1;
946 }
947
948 ////////////////////////////////////////////////////////////////////
949 //80002040 SYSCALL 083 iSetEventFlag
950 ////////////////////////////////////////////////////////////////////
951 int _iSetEventFlag(int ef, u32 bits)
952 {
953 return _HandlersCount; //?
954 }
955
956 ////////////////////////////////////////////////////////////////////
957 //800022D8 SYSCALL 24,30
958 ////////////////////////////////////////////////////////////////////
959 int _SetAlarm(short a0, int a1, int a2)
960 {
961 int mode = _alarm_unk & 0x1;
962 int i;
963
964 i = 0;
965 while (mode) {
966 mode = (_alarm_unk >> i++) & 0x1;
967 if (i >= 64) {
968 return -1;
969 }
970 }
971
972 _alarm_unk|= mode << i;
973
974 __asm__("move %0, $gp\n" : "=r"(rcnt3TargetTable[0]) : );
975 dword_80016A78 = a1;
976 dword_80016A7C = a2;
977 rcnt3TargetTable[1] = RCNT3_MODE;
978 i = RCNT3_MODE + a0;
979 if (i < -1)
980 i&= 0xffff;
981 dword_80016A88 = i;
982
983 if (RCNT3_MODE < i) {
984 if (rcnt3Count <= 0) {
985
986 }
987 }
988 }
989
990 ////////////////////////////////////////////////////////////////////
991 //80002570 SYSCALL 25,31 ReleaseAlarm
992 ////////////////////////////////////////////////////////////////////
993 void _ReleaseAlarm()
994 {
995 //TODO
996 }
997
998 ////////////////////////////////////////////////////////////////////
999 //80002650
1000 ////////////////////////////////////////////////////////////////////
1001 void rcnt3Handler()
1002 {
1003 unsigned int i;
1004 u32* ptr;
1005 u32 storegp;
1006 u32 addr;
1007
1008 if (rcnt3Count < 2) {
1009 RCNT3_MODE = 0x483;
1010 } else {
1011 RCNT3_MODE = 0x583;
1012 RCNT3_TARGET = rcnt3TargetTable[2+rcnt3TargetNum[1] * 5];
1013 }
1014
1015 for (;;) {
1016 u32 id = (u32)rcnt3TargetNum[0];
1017 if (--rcnt3Count >= 0) {
1018 // shift one down
1019 for (i=0; i<rcnt3Count; i++) {
1020 rcnt3TargetNum[i] = rcnt3TargetNum[i+1];
1021 }
1022 }
1023
1024 rcnt3Valid &= ~(1 << id);
1025 ptr = &rcnt3TargetTable[id * 5];
1026 addr = (u32)*(u16*)(ptr+2);
1027 __asm__("move %0, $gp\n" : "=r"(storegp) : );
1028 __asm__("move $gp, %0\n" : : "r"(ptr[0]) );
1029
1030 _excepRet(excepRetPc, ptr[-2], id, addr, ptr[-1]);
1031
1032 __asm__("move $gp, %0\n" : : "r"(storegp) );
1033
1034 if (rcnt3Count >= 0) {
1035 if (addr != rcnt3TargetTable[rcnt3TargetNum[0] * 5 + 2]) {
1036 break;
1037 }
1038 } else break;
1039 }
1040 }
1041
1042 ////////////////////////////////////////////////////////////////////
1043 //800027F8 SYSCALL 082 SetEventFlag
1044 ////////////////////////////////////////////////////////////////////
1045 int _SetEventFlag(int ef, u32 bits)
1046 {
1047 return rcnt3Count; //?
1048 }
1049
1050 ////////////////////////////////////////////////////////////////////
1051 //800027F8
1052 ////////////////////////////////////////////////////////////////////
1053 void _InitRCNT3()
1054 {
1055 int i;
1056
1057 rcnt3Count = 0;
1058 rcnt3Valid = 0;
1059 _alarm_unk = 0;
1060 for (i=0; i<0x40; i++) rcnt3TargetNum[i] = 0;
1061
1062 __EnableIntc(INTC_TIM3);
1063 }
1064
1065 ////////////////////////////////////////////////////////////////////
1066 //80002840
1067 ////////////////////////////////////////////////////////////////////
1068 void _excepRet(u32 eretpc, u32 v1, u32 a, u32 a1, u32 a2)
1069 {
1070 __asm__("sw $31, %0\n"
1071 "sw $sp, %1\n"
1072 : "=m"(excepRA), "=m"(excepSP) : );
1073 __asm__("mtc0 $4, $14\n"
1074 "sync\n"
1075 "daddu $3, $5, $0\n"
1076 "daddu $4, $6, $0\n"
1077 "daddu $5, $7, $0\n"
1078 "daddu $6, $8, $0\n"
1079 "mfc0 $26, $12\n"
1080 "ori $26, 0x12\n"
1081 "mtc0 $26, $12\n"
1082 "sync\n"
1083 "eret\n"
1084 "nop\n");
1085 }
1086
1087 ////////////////////////////////////////////////////////////////////
1088 //80002880 SYSCALL 005 RFU005
1089 ////////////////////////////////////////////////////////////////////
1090 void _RFU005()
1091 {
1092 __asm__ (
1093 ".set noat\n"
1094
1095 "mfc0 $26, $12\n"
1096 "ori $1, $0, 0xFFE4\n"
1097 "and $26, $1\n"
1098 "mtc0 $26, $12\n"
1099 "sync\n"
1100
1101 "lw $ra, excepRA\n"
1102 "lw $sp, excepSP\n"
1103 "jr $ra\n"
1104 "nop\n"
1105
1106 ".set at\n");
1107 }
1108
1109 ////////////////////////////////////////////////////////////////////
1110 //A00028C0 SYSCALL 097 EnableCache
1111 ////////////////////////////////////////////////////////////////////
1112 int _EnableCache(int cache)
1113 {
1114 u32 cfg;
1115 __asm__("mfc0 %0, $16\n" : "=r"(cfg) : );
1116 cfg |= ((cache&3)<<16);
1117 __asm__("mtc0 %0, $16\n"
1118 "sync\n" : : "r"(cfg) );
1119 }
1120
1121 ////////////////////////////////////////////////////////////////////
1122 //A0002980 SYSCALL 098 DisableCache
1123 ////////////////////////////////////////////////////////////////////
1124 int _DisableCache(int cache)
1125 {
1126 u32 cfg;
1127 __asm__("mfc0 %0, $16\n" : "=r"(cfg) : );
1128 cfg &= ~((cache&3)<<16);
1129 __asm__("mtc0 %0, $16\n"
1130 "sync\n" : : "r"(cfg) );
1131 }
1132
1133 ////////////////////////////////////////////////////////////////////
1134 //A0002A40 SYSCALL 100 FlushCache
1135 ////////////////////////////////////////////////////////////////////
1136 void _FlushCache(int op)
1137 {
1138 if( op == 0 ) FlushInstructionCache();
1139 else if ( op == 1 ) FlushSecondaryCache();
1140 else if( op == 2 ) FlushDataCache();
1141 else {
1142 FlushSecondaryCache();
1143 FlushDataCache();
1144 }
1145 }
1146
1147 ////////////////////////////////////////////////////////////////////
1148 //80002AC0
1149 ////////////////////////////////////////////////////////////////////
1150 void FlushInstructionCache()
1151 {
1152 }
1153
1154 ////////////////////////////////////////////////////////////////////
1155 //80002A80
1156 ////////////////////////////////////////////////////////////////////
1157 void FlushDataCache()
1158 {
1159 }
1160
1161 ////////////////////////////////////////////////////////////////////
1162 //80002B00
1163 ////////////////////////////////////////////////////////////////////
1164 void FlushSecondaryCache()
1165 {
1166 }
1167
1168 ////////////////////////////////////////////////////////////////////
1169 //A0002B40 SYSCALL 101,105 _105
1170 ////////////////////////////////////////////////////////////////////
1171 void _105(int op1, int op2)
1172 {
1173 // flushing caches again
1174 }
1175
1176 ////////////////////////////////////////////////////////////////////
1177 //A0002C00 SYSCALL 096 KSeg0
1178 ////////////////////////////////////////////////////////////////////
1179 void _KSeg0(u32 arg)
1180 {
1181 u32 cfg;
1182 __asm__("mfc0 %0, $16\n" : "=r"(cfg) : );
1183 cfg = (arg&3)&((cfg>>3)<<3); // yes it is 0, don't ask
1184 __asm__("mtc0 %0, $16\n"
1185 "sync\n" : : "r"(cfg) );
1186 }
1187
1188 ////////////////////////////////////////////////////////////////////
1189 //80002C40 SYSCALL 099 GetCop0
1190 ////////////////////////////////////////////////////////////////////
1191 int _GetCop0(int reg)
1192 {
1193 return table_GetCop0[reg](reg);
1194 }
1195
1196 ////////////////////////////////////////////////////////////////////
1197 //80002C58-80002D50 calls for table_GetCop0
1198 ////////////////////////////////////////////////////////////////////
1199 int GetCop0_Index(int reg) { __asm__(" mfc0 $2, $0\n"); }
1200 int GetCop0_Random(int reg) { __asm__(" mfc0 $2, $1\n"); }
1201 int GetCop0_EntryLo0(int reg) { __asm__(" mfc0 $2, $2\n"); }
1202 int GetCop0_EntryLo1(int reg) { __asm__(" mfc0 $2, $3\n"); }
1203
1204 int GetCop0_Context(int reg) { __asm__(" mfc0 $2, $4\n"); }
1205 int GetCop0_PageMask(int reg) { __asm__(" mfc0 $2, $5\n"); }
1206 int GetCop0_Wired(int reg) { __asm__(" mfc0 $2, $6\n"); }
1207 int GetCop0_Reg7(int reg) { return; }
1208
1209 int GetCop0_BadVAddr(int reg) { __asm__(" mfc0 $2, $8\n"); }
1210 int GetCop0_Count(int reg) { __asm__(" mfc0 $2, $9\n"); }
1211 int GetCop0_EntryHi(int reg) { __asm__(" mfc0 $2, $10\n"); }
1212 int GetCop0_Compare(int reg) { __asm__(" mfc0 $2, $11\n"); }
1213
1214 int GetCop0_Status(int reg) { __asm__(" mfc0 $2, $12\n"); }
1215 int GetCop0_Cause(int reg) { __asm__(" mfc0 $2, $13\n"); }
1216 int GetCop0_ExceptPC(int reg) { __asm__(" mfc0 $2, $14\n"); }
1217 int GetCop0_PRevID(int reg) { __asm__(" mfc0 $2, $15\n"); }
1218
1219 int GetCop0_Config(int reg) { __asm__(" mfc0 $2, $16\n"); }
1220 int GetCop0_Reg17(int reg) { return; }
1221 int GetCop0_Reg18(int reg) { return; }
1222 int GetCop0_Reg19(int reg) { return; }
1223
1224 int GetCop0_Reg20(int reg) { return; }
1225 int GetCop0_Reg21(int reg) { return; }
1226 int GetCop0_Reg22(int reg) { return; }
1227 int GetCop0_Reg23(int reg) { __asm__(" mfc0 $2, $23\n"); }
1228
1229 int GetCop0_DebugReg24(int reg) { __asm__(" mfc0 $2, $24\n"); }
1230 int GetCop0_Perf(int reg) { __asm__(" mfc0 $2, $25\n"); }
1231 int GetCop0_Reg26(int reg) { return; }
1232 int GetCop0_Reg27(int reg) { return; }
1233
1234 int GetCop0_TagLo(int reg) { __asm__(" mfc0 $2, $28\n"); }
1235 int GetCop0_TagHi(int reg) { __asm__(" mfc0 $2, $29\n"); }
1236 int GetCop0_ErrorPC(int reg) { __asm__(" mfc0 $2, $30\n"); }
1237 int GetCop0_Reg31(int reg) { return; }
1238
1239 int (*table_GetCop0[32])(int reg) = { // 800124E8
1240 GetCop0_Index, GetCop0_Random, GetCop0_EntryLo0, GetCop0_EntryLo1,
1241 GetCop0_Context, GetCop0_PageMask, GetCop0_Wired, GetCop0_Reg7,
1242 GetCop0_BadVAddr, GetCop0_Count, GetCop0_EntryHi, GetCop0_Compare,
1243 GetCop0_Status, GetCop0_Cause, GetCop0_ExceptPC, GetCop0_PRevID,
1244 GetCop0_Config, GetCop0_Reg17, GetCop0_Reg18, GetCop0_Reg19,
1245 GetCop0_Reg20, GetCop0_Reg21, GetCop0_Reg22, GetCop0_Reg23,
1246 GetCop0_DebugReg24, GetCop0_Perf, GetCop0_Reg26, GetCop0_Reg27,
1247 GetCop0_TagLo, GetCop0_TagHi, GetCop0_ErrorPC, GetCop0_Reg31
1248 };
1249
1250 ////////////////////////////////////////////////////////////////////
1251 //80002D80
1252 ////////////////////////////////////////////////////////////////////
1253 int SetCop0(int reg, int val)
1254 {
1255 return table_SetCop0[reg](reg, val);
1256 }
1257
1258 ////////////////////////////////////////////////////////////////////
1259 //80002D98-80002F74 calls for table_SetCop0
1260 ////////////////////////////////////////////////////////////////////
1261 int SetCop0_Index(int reg, int val) { __asm__(" mfc0 $2, $0\nmtc0 %0, $0\nsync\n" : : "r"(val)); }
1262 int SetCop0_Random(int reg, int val) { return -1; }
1263 int SetCop0_EntryLo0(int reg, int val) { __asm__(" mfc0 $2, $2\nmtc0 %0, $2\nsync\n" : : "r"(val)); }
1264 int SetCop0_EntryLo1(int reg, int val) { __asm__(" mfc0 $2, $3\nmtc0 %0, $3\nsync\n" : : "r"(val)); }
1265
1266 int SetCop0_Context(int reg, int val) { __asm__(" mfc0 $2, $4\nmtc0 %0, $4\nsync\n" : : "r"(val)); }
1267 int SetCop0_PageMask(int reg, int val) { __asm__(" mfc0 $2, $5\nmtc0 %0, $5\nsync\n" : : "r"(val)); }
1268 int SetCop0_Wired(int reg, int val) { __asm__(" mfc0 $2, $6\nmtc0 %0, $6\nsync\n" : : "r"(val)); }
1269 int SetCop0_Reg7(int reg, int val) { return -1; }
1270
1271 int SetCop0_BadVAddr(int reg, int val) { return -1; }
1272 int SetCop0_Count(int reg, int val) { __asm__(" mfc0 $2, $9\nmtc0 %0, $9\nsync\n" : : "r"(val)); }
1273 int SetCop0_EntryHi(int reg, int val) { __asm__(" mfc0 $2, $10\nmtc0 %0, $10\nsync\n" : : "r"(val)); }
1274 int SetCop0_Compare(int reg, int val) { __asm__(" mfc0 $2, $11\nmtc0 %0, $11\nsync\n" : : "r"(val)); }
1275
1276 int SetCop0_Status(int reg, int val) { __asm__(" mfc0 $2, $12\nmtc0 %0, $12\nsync\n" : : "r"(val)); }
1277 int SetCop0_Cause(int reg, int val) { return -1; }
1278 int SetCop0_ExceptPC(int reg, int val) { __asm__(" mfc0 $2, $14\nmtc0 %0, $14\nsync\n" : : "r"(val)); }
1279 int SetCop0_PRevID(int reg, int val) { return -1; }
1280
1281 int SetCop0_Config(int reg, int val) { __asm__(" mfc0 $2, $16\nmtc0 %0, $16\nsync\n" : : "r"(val)); }
1282 int SetCop0_Reg17(int reg, int val) { return -1; }
1283 int SetCop0_Reg18(int reg, int val) { return -1; }
1284 int SetCop0_Reg19(int reg, int val) { return -1; }
1285
1286 int SetCop0_Reg20(int reg, int val) { return -1; }
1287 int SetCop0_Reg21(int reg, int val) { return -1; }
1288 int SetCop0_Reg22(int reg, int val) { return -1; }
1289 int SetCop0_Reg23(int reg, int val) { __asm__(" mfc0 $2, $23\nmtc0 %0, $23\nsync\n" : : "r"(val)); }
1290
1291 int SetCop0_DebugReg24(int reg, int val){ __asm__(" mfc0 $2, $24\nmtc0 %0, $24\nsync\n" : : "r"(val)); }
1292 int SetCop0_Perf(int reg, int val) { __asm__(" mfc0 $2, $25\nmtc0 %0, $25\nsync\n" : : "r"(val)); }
1293 int SetCop0_Reg26(int reg, int val) { return -1; }
1294 int SetCop0_Reg27(int reg, int val) { return -1; }
1295
1296 int SetCop0_TagLo(int reg, int val) { __asm__(" mfc0 $2, $28\nmtc0 %0, $28\nsync\n" : : "r"(val)); }
1297 int SetCop0_TagHi(int reg, int val) { __asm__(" mfc0 $2, $29\nmtc0 %0, $29\nsync\n" : : "r"(val)); }
1298 int SetCop0_ErrorPC(int reg, int val) { __asm__(" mfc0 $2, $30\nmtc0 %0, $30\nsync\n" : : "r"(val)); }
1299 int SetCop0_Reg31(int reg, int val) { return -1; }
1300
1301 int (*table_SetCop0[32])(int reg, int val) = { // 80012568
1302 SetCop0_Index, SetCop0_Random, SetCop0_EntryLo0, SetCop0_EntryLo1,
1303 SetCop0_Context, SetCop0_PageMask, SetCop0_Wired, SetCop0_Reg7,
1304 SetCop0_BadVAddr, SetCop0_Count, SetCop0_EntryHi, SetCop0_Compare,
1305 SetCop0_Status, SetCop0_Cause, SetCop0_ExceptPC, SetCop0_PRevID,
1306 SetCop0_Config, SetCop0_Reg17, SetCop0_Reg18, SetCop0_Reg19,
1307 SetCop0_Reg20, SetCop0_Reg21, SetCop0_Reg22, SetCop0_Reg23,
1308 SetCop0_DebugReg24, SetCop0_Perf, SetCop0_Reg26, SetCop0_Reg27,
1309 SetCop0_TagLo, SetCop0_TagHi, SetCop0_ErrorPC, SetCop0_Reg31
1310 };
1311
1312 ////////////////////////////////////////////////////////////////////
1313 //80002F80 SYSCALL 007 ExecPS2
1314 ////////////////////////////////////////////////////////////////////
1315 int _ExecPS2(void * entry, void * gp, int argc, char ** argv)
1316 {
1317 saveContext();
1318 __ExecPS2(entry, gp, argc, argv);
1319 __asm__("mtc0 $2, $14\n"
1320 "move $sp, %0\n"
1321 "sd $2, 0x20($sp)\n"
1322 : : "r"(SavedSP));
1323
1324 restoreContext();
1325 eret();
1326 }
1327
1328 ////////////////////////////////////////////////////////////////////
1329 //80002FC0 SYSCALL 033 DeleteThread
1330 ////////////////////////////////////////////////////////////////////
1331 int _DeleteThread(int tid)
1332 {
1333 register int ret __asm__("$2");
1334 register u32 curepc __asm__("$4");
1335
1336 saveContext();
1337
1338 ret = __DeleteThread(tid);
1339 if (ret < 0) {
1340 __asm__("lw $sp, %0\n" : : "m"(SavedSP));
1341 // make sure the return value is also stored
1342 __asm__("sd $2, 0x20($sp)\n");
1343
1344 restoreContext();
1345 eret();
1346 }
1347
1348
1349 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC
1350 _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4
1351
1352 __asm__("mtc0 $2, $14\n"
1353 "move $sp, $3\n");
1354
1355 restoreContext();
1356 eret();
1357 }
1358
1359 ////////////////////////////////////////////////////////////////////
1360 //80003040 SYSCALL 034 StartThread
1361 ////////////////////////////////////////////////////////////////////
1362 int _StartThread(int tid, void *arg)
1363 {
1364 register int ret __asm__("$2");
1365 register u32 curepc __asm__("$4");
1366
1367 saveContext();
1368
1369 ret = __StartThread(tid, arg);
1370
1371 if (ret < 0) {
1372 __asm__("lw $sp, %0\n" : : "m"(SavedSP));
1373 // make sure the return value is also stored
1374 __asm__("sd $2, 0x20($sp)\n");
1375
1376 restoreContext();
1377 eret();
1378 }
1379
1380
1381 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC
1382 _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4
1383
1384 __asm__("mtc0 $2, $14\n"
1385 "move $sp, $3\n");
1386
1387 restoreContext();
1388 eret();
1389 }
1390
1391 ////////////////////////////////////////////////////////////////////
1392 //800030C0 SYSCALL 035 ExitThread
1393 ////////////////////////////////////////////////////////////////////
1394 int _ExitThread()
1395 {
1396 saveContext();
1397
1398 __ExitThread();
1399 __asm__("mtc0 $2, $14\n"
1400 "sync\n"
1401 "move $sp, $3\n");
1402
1403 restoreContext();
1404 eret();
1405 }
1406
1407 ////////////////////////////////////////////////////////////////////
1408 //80003100 SYSCALL 036 ExitDeleteThread
1409 ////////////////////////////////////////////////////////////////////
1410 int _ExitDeleteThread()
1411 {
1412 saveContext();
1413
1414 __ExitDeleteThread();
1415 __asm__("mtc0 $2, $14\n"
1416 "sync\n"
1417 "move $sp, $3\n");
1418
1419 restoreContext();
1420 eret();
1421 }
1422
1423 ////////////////////////////////////////////////////////////////////
1424 //80003140 SYSCALL 037 TerminateThread
1425 ////////////////////////////////////////////////////////////////////
1426 int _TerminateThread(int tid)
1427 {
1428 register int ret __asm__("$2");
1429 register u32 curepc __asm__("$4");
1430
1431 saveContext();
1432
1433 ret = _iTerminateThread(tid);
1434
1435 if( ret < 0 ) {
1436 __asm__("lw $sp, %0\n" : : "m"(SavedSP));
1437 // make sure the return value is also stored
1438 __asm__("sd $2, 0x20($sp)\n");
1439
1440 restoreContext();
1441 eret();
1442 }
1443
1444 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC
1445 _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4
1446
1447 __asm__("mtc0 $2, $14\n"
1448 "move $sp, $3\n");
1449
1450 restoreContext();
1451 eret();
1452 }
1453
1454 ////////////////////////////////////////////////////////////////////
1455 //800031C0 SYSCALL 043 RotateThreadReadyQueue
1456 ////////////////////////////////////////////////////////////////////
1457 void _RotateThreadReadyQueue(int pri)
1458 {
1459 register int ret __asm__("$2");
1460 register u32 curepc __asm__("$4");
1461
1462 ret = pri;
1463 saveContext();
1464
1465 ret = _iRotateThreadReadyQueue(pri);
1466
1467 if( ret < 0 ) {
1468 __asm__("lw $sp, %0\n" : : "m"(SavedSP));
1469 // make sure the return value is also stored
1470 __asm__("sd $2, 0x20($sp)\n");
1471
1472 restoreContext();
1473 eret();
1474 }
1475
1476 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC
1477 _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4
1478
1479 __asm__("mtc0 $2, $14\n"
1480 "move $sp, $3\n");
1481
1482 restoreContext();
1483 eret();
1484 }
1485
1486 ////////////////////////////////////////////////////////////////////
1487 //80003240 SYSCALL 045 ReleaseWaitThread
1488 ////////////////////////////////////////////////////////////////////
1489 void _ReleaseWaitThread(int tid)
1490 {
1491 register int ret __asm__("$2");
1492 register u32 curepc __asm__("$4");
1493
1494 ret = tid;
1495 saveContext();
1496
1497 ret = _iReleaseWaitThread(tid);
1498
1499 if( ret < 0 ) {
1500 __asm__("lw $sp, %0\n" : : "m"(SavedSP));
1501 // make sure the return value is also stored
1502 __asm__("sd $2, 0x20($sp)\n");
1503
1504 restoreContext();
1505 eret();
1506 }
1507
1508 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC
1509 _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4
1510
1511 __asm__("mtc0 $2, $14\n"
1512 "move $sp, $3\n");
1513
1514 restoreContext();
1515 eret();
1516 }
1517
1518 ////////////////////////////////////////////////////////////////////
1519 //800032C0 SYSCALL 052 SleepThread
1520 ////////////////////////////////////////////////////////////////////
1521 int _SleepThread()
1522 {
1523 register int ret __asm__("$2");
1524
1525 ret = threadId;
1526 saveContext();
1527
1528 ret = __SleepThread();
1529 if (ret < 0) {
1530 register int curepc __asm__("$4");
1531 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1532 _ChangeThread(curepc, SavedSP, 1);
1533
1534 __asm__("mtc0 $2, $14\n"
1535 "sync\n"
1536 "move $sp, $3\n");
1537 restoreContext();
1538 eret();
1539 }
1540
1541 __asm__("lw $sp, %0\n"
1542 "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) );
1543 restoreContext();
1544 eret();
1545 }
1546
1547 ////////////////////////////////////////////////////////////////////
1548 //80003340 SYSCALL 051 WakeupThread
1549 ////////////////////////////////////////////////////////////////////
1550 int _WakeupThread(int tid)
1551 {
1552 register int ret __asm__("$2");
1553
1554 ret = tid;
1555 saveContext();
1556
1557 ret = iWakeupThread(tid);
1558 if( ret >= 0 ) {
1559 register int curepc __asm__("$4");
1560 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1561 _ThreadHandler(curepc, SavedSP);
1562
1563 __asm__("mtc0 $2, $14\n"
1564 "sync\n"
1565 "move $sp, $3\n");
1566 restoreContext();
1567 eret();
1568 }
1569
1570 __asm__("lw $sp, %0\n"
1571 "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) );
1572 restoreContext();
1573 eret();
1574 }
1575
1576 ////////////////////////////////////////////////////////////////////
1577 //800033C0 SYSCALL 057 ResumeThread
1578 ////////////////////////////////////////////////////////////////////
1579 int _ResumeThread(int tid)
1580 {
1581 register int ret __asm__("$2");
1582
1583 ret = tid;
1584 saveContext();
1585
1586 ret = _iResumeThread(tid);
1587 if( ret >= 0 ) {
1588 register int curepc __asm__("$4");
1589 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1590 _ThreadHandler(curepc, SavedSP);
1591
1592 __asm__("mtc0 $2, $14\n"
1593 "sync\n"
1594 "move $sp, $3\n");
1595 restoreContext();
1596 eret();
1597 }
1598
1599 __asm__("lw $sp, %0\n"
1600 "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) );
1601 restoreContext();
1602 eret();
1603 }
1604
1605 ////////////////////////////////////////////////////////////////////
1606 //80003440 SYSCALL 068 WaitSema
1607 ////////////////////////////////////////////////////////////////////
1608 int _WaitSema(int sid)
1609 {
1610 register int ret __asm__("$2");
1611
1612 ret = sid;
1613 saveContext();
1614
1615 ret = _iWaitSema(sid);
1616 if( ret == 0xFFFFFFFE ) {
1617 register int curepc __asm__("$4");
1618 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1619 _ChangeThread(curepc, SavedSP, 2);
1620
1621 __asm__("mtc0 $2, $14\n"
1622 "sync\n"
1623 "move $sp, $3\n");
1624 restoreContext();
1625 eret();
1626 }
1627
1628 __asm__("lw $sp, %0\n" : : "m"(SavedSP));
1629 restoreContext();
1630 eret();
1631 }
1632
1633 ////////////////////////////////////////////////////////////////////
1634 //800034C0 SYSCALL 066 SignalSema
1635 ////////////////////////////////////////////////////////////////////
1636 void _SignalSema(int sid)
1637 {
1638 register int ret __asm__("$2");
1639
1640 ret = sid;
1641 saveContext();
1642
1643 ret = _iSignalSema(sid);
1644 if( ret >= 0 ) {
1645 register int curepc __asm__("$4");
1646 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1647 _ThreadHandler(curepc, SavedSP);
1648
1649 __asm__("mtc0 $2, $14\n"
1650 "sync\n"
1651 "move $sp, $3\n");
1652 restoreContext();
1653 eret();
1654 }
1655
1656 __asm__("lw $sp, %0\n"
1657 "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) );
1658 restoreContext();
1659 eret();
1660 }
1661
1662 ////////////////////////////////////////////////////////////////////
1663 //80003540 SYSCALL 065 DeleteSema
1664 ////////////////////////////////////////////////////////////////////
1665 int _DeleteSema(int sid)
1666 {
1667 register int ret __asm__("$2");
1668
1669 ret = sid;
1670 saveContext();
1671
1672 ret = _iDeleteSema(sid);
1673 if( ret >= 0 ) {
1674 register int curepc __asm__("$4");
1675 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1676 _ThreadHandler(curepc, SavedSP);
1677
1678 __asm__("mtc0 $2, $14\n"
1679 "sync\n"
1680 "move $sp, $3\n");
1681 restoreContext();
1682 eret();
1683 }
1684
1685 __asm__("lw $sp, %0\n"
1686 "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) );
1687 restoreContext();
1688 eret();
1689 }
1690
1691 ////////////////////////////////////////////////////////////////////
1692 //800035C0 SYSCALL 041 ChangeThreadPriority
1693 //return has to be void (even though it fills in v0)
1694 ////////////////////////////////////////////////////////////////////
1695 void _ChangeThreadPriority(int tid, int prio)
1696 {
1697 register int ret __asm__("$2");
1698
1699 saveContext();
1700 ret = _iChangeThreadPriority(tid, prio);
1701
1702 __asm__("lw $26, %0\n"
1703 "sd %1, 0x20($26)\n" : : "m"(SavedSP), "r"(ret) );
1704
1705 if (ret>=0){
1706 register int curepc __asm__("$4");
1707 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1708 _ThreadHandler(curepc, SavedSP);
1709
1710 __asm__("mtc0 $2, $14\n"
1711 "sync\n"
1712 "move $sp, $3\n");
1713 restoreContext();
1714 eret();
1715 }
1716
1717 // why twice?
1718 __asm__("lw $sp, %0\n"
1719 "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) );
1720 restoreContext();
1721 eret();
1722 }
1723
1724 ////////////////////////////////////////////////////////////////////
1725 //8000363C
1726 ////////////////////////////////////////////////////////////////////
1727 void __ThreadHandler()
1728 {
1729 register int curepc __asm__("$4");
1730
1731 saveContext();
1732
1733 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
1734 _ThreadHandler(curepc, SavedSP);
1735 __asm__("mtc0 $2, $14\n"
1736 "sync\n"
1737 "move $sp, $3\n");
1738 restoreContext();
1739 eret();
1740 }
1741
1742 ////////////////////////////////////////////////////////////////////
1743 //80003680
1744 ////////////////////////////////////////////////////////////////////
1745 void saveContext()
1746 {
1747 __asm__ (
1748 "lui $26, %hi(SavedSP)\n"
1749 "lq $26, %lo(SavedSP)($26)\n"
1750 );
1751 __asm__ (
1752 "addiu $26, %0\n"
1753 : : "i"(-sizeof(struct threadCtx))
1754 );
1755 __asm__ (
1756 ".set noat\n"
1757 "lui $1, %hi(SavedAT)\n"
1758 "lq $1, %lo(SavedAT)($1)\n"
1759 "sq $1, 0x000($26)\n"
1760 "sq $2, 0x010($26)\n"
1761 "sq $3, 0x020($26)\n"
1762 "sq $4, 0x030($26)\n"
1763 "sq $5, 0x040($26)\n"
1764 "sq $6, 0x050($26)\n"
1765 "sq $7, 0x060($26)\n"
1766 "sq $8, 0x070($26)\n"
1767 "sq $9, 0x080($26)\n"
1768 "sq $10, 0x090($26)\n"
1769 "sq $11, 0x0A0($26)\n"
1770 "sq $12, 0x0B0($26)\n"
1771 "sq $13, 0x0C0($26)\n"
1772 "sq $14, 0x0D0($26)\n"
1773 "sq $15, 0x0E0($26)\n"
1774 "sq $16, 0x0F0($26)\n"
1775 "sq $17, 0x100($26)\n"
1776 "sq $18, 0x110($26)\n"
1777 "sq $19, 0x120($26)\n"
1778 "sq $20, 0x130($26)\n"
1779 "sq $21, 0x140($26)\n"
1780 "sq $22, 0x150($26)\n"
1781 "sq $23, 0x160($26)\n"
1782 "sq $24, 0x170($26)\n"
1783 "sq $25, 0x180($26)\n"
1784 "sq $gp, 0x190($26)\n"
1785 "lui $1, %hi(SavedSP)\n"
1786 "lq $sp, %lo(SavedSP)($1)\n"
1787 "sq $sp, 0x1A0($26)\n"
1788 "sq $fp, 0x1B0($26)\n"
1789 "lui $1, %hi(SavedRA)\n"
1790 "lq $1, %lo(SavedRA)($1)\n"
1791 "sq $1, 0x1C0($26)\n"
1792
1793 "swc1 $0, 0x200($26)\n"
1794 "swc1 $1, 0x204($26)\n"
1795 "swc1 $2, 0x208($26)\n"
1796 "swc1 $3, 0x20C($26)\n"
1797 "swc1 $4, 0x210($26)\n"
1798 "swc1 $5, 0x214($26)\n"
1799 "swc1 $6, 0x218($26)\n"
1800 "swc1 $7, 0x21C($26)\n"
1801 "swc1 $8, 0x220($26)\n"
1802 "swc1 $9, 0x224($26)\n"
1803 "swc1 $10, 0x228($26)\n"
1804 "swc1 $11, 0x22C($26)\n"
1805 "swc1 $12, 0x230($26)\n"
1806 "swc1 $13, 0x234($26)\n"
1807 "swc1 $14, 0x238($26)\n"
1808 "swc1 $15, 0x23C($26)\n"
1809 "swc1 $16, 0x240($26)\n"
1810 "swc1 $17, 0x244($26)\n"
1811 "swc1 $18, 0x248($26)\n"
1812 "swc1 $19, 0x24C($26)\n"
1813 "swc1 $20, 0x250($26)\n"
1814 "swc1 $21, 0x254($26)\n"
1815 "swc1 $22, 0x258($26)\n"
1816 "swc1 $23, 0x25C($26)\n"
1817 "swc1 $24, 0x260($26)\n"
1818 "swc1 $25, 0x264($26)\n"
1819 "swc1 $26, 0x268($26)\n"
1820 "swc1 $27, 0x26C($26)\n"
1821 "swc1 $28, 0x270($26)\n"
1822 "swc1 $29, 0x274($26)\n"
1823 "swc1 $30, 0x278($26)\n"
1824 "swc1 $31, 0x27C($26)\n"
1825
1826 "mfsa $1\n"
1827 "sw $1, 0x1F0($26)\n"
1828
1829 "cfc1 $1, $31\n"
1830 "sw $1, 0x1F4($26)\n"
1831
1832 "lui $1, 0x8000\n"
1833 "mtc1 $1, $1\n"
1834 "mtc1 $1, $0\n"
1835 "madd.s $f0, $f0, $f1\n"
1836 "swc1 $0, 0x1F8($26)\n"
1837
1838 "mfhi $1\n"
1839 "sd $1, 0x1D0($26)\n"
1840 "mfhi1 $1\n"
1841 "sd $1, 0x1D8($26)\n"
1842
1843 "mflo $1\n"
1844 "sd $1, 0x1E0($26)\n"
1845 "mflo1 $1\n"
1846 "sd $1, 0x1E8($26)\n"
1847
1848 "lui $1, %hi(SavedSP)\n"
1849 "sw $26, %lo(SavedSP)($1)\n"
1850
1851 "jr $31\n"
1852 "lui $1, 0x8000\n"
1853 ".set at\n"
1854 );
1855 }
1856
1857 ////////////////////////////////////////////////////////////////////
1858 //80003800
1859 ////////////////////////////////////////////////////////////////////
1860 void restoreContext()
1861 {
1862 __asm__ (
1863 ".set noat\n"
1864
1865 "lui $26, 0x8000\n"
1866 "mtc1 $26, $1\n"
1867 "lwc1 $0, 0x1F8($sp)\n"
1868 "adda.s $f0, $f1\n"
1869
1870 "lw $26, 0x1F0($sp)\n"
1871 "mtsa $26\n"
1872
1873 "lw $26, 0x1F4($sp)\n"
1874 "ctc1 $26, $31\n"
1875
1876 "ld $26, 0x1D0($sp)\n"
1877 "mthi $26\n"
1878 "ld $26, 0x1D8($sp)\n"
1879 "mthi1 $26\n"
1880
1881 "ld $26, 0x1E0($sp)\n"
1882 "mtlo $26\n"
1883 "ld $26, 0x1E8($sp)\n"
1884 "mtlo1 $26\n"
1885
1886 "lq $1, 0x000($sp)\n"
1887 "lq $2, 0x010($sp)\n"
1888 "lq $3, 0x020($sp)\n"
1889 "lq $4, 0x030($sp)\n"
1890 "lq $5, 0x040($sp)\n"
1891 "lq $6, 0x050($sp)\n"
1892 "lq $7, 0x060($sp)\n"
1893 "lq $8, 0x070($sp)\n"
1894 "lq $9, 0x080($sp)\n"
1895 "lq $10, 0x090($sp)\n"
1896 "lq $11, 0x0A0($sp)\n"
1897 "lq $12, 0x0B0($sp)\n"
1898 "lq $13, 0x0C0($sp)\n"
1899 "lq $14, 0x0D0($sp)\n"
1900 "lq $15, 0x0E0($sp)\n"
1901 "lq $16, 0x0F0($sp)\n"
1902 "lq $17, 0x100($sp)\n"
1903 "lq $18, 0x110($sp)\n"
1904 "lq $19, 0x120($sp)\n"
1905 "lq $20, 0x130($sp)\n"
1906 "lq $21, 0x140($sp)\n"
1907 "lq $22, 0x150($sp)\n"
1908 "lq $23, 0x160($sp)\n"
1909 "lq $24, 0x170($sp)\n"
1910 "lq $25, 0x180($sp)\n"
1911 "lq $gp, 0x190($sp)\n"
1912 "lq $fp, 0x1B0($sp)\n"
1913
1914 "lwc1 $0, 0x200($sp)\n"
1915 "lwc1 $1, 0x204($sp)\n"
1916 "lwc1 $2, 0x208($sp)\n"
1917 "lwc1 $3, 0x20C($sp)\n"
1918 "lwc1 $4, 0x210($sp)\n"
1919 "lwc1 $5, 0x214($sp)\n"
1920 "lwc1 $6, 0x218($sp)\n"
1921 "lwc1 $7, 0x21C($sp)\n"
1922 "lwc1 $8, 0x220($sp)\n"
1923 "lwc1 $9, 0x224($sp)\n"
1924 "lwc1 $10, 0x228($sp)\n"
1925 "lwc1 $11, 0x22C($sp)\n"
1926 "lwc1 $12, 0x230($sp)\n"
1927 "lwc1 $13, 0x234($sp)\n"
1928 "lwc1 $14, 0x238($sp)\n"
1929 "lwc1 $15, 0x23C($sp)\n"
1930 "lwc1 $16, 0x240($sp)\n"
1931 "lwc1 $17, 0x244($sp)\n"
1932 "lwc1 $18, 0x248($sp)\n"
1933 "lwc1 $19, 0x24C($sp)\n"
1934 "lwc1 $20, 0x250($sp)\n"
1935 "lwc1 $21, 0x254($sp)\n"
1936 "lwc1 $22, 0x258($sp)\n"
1937 "lwc1 $23, 0x25C($sp)\n"
1938 "lwc1 $24, 0x260($sp)\n"
1939 "lwc1 $25, 0x264($sp)\n"
1940 "lwc1 $26, 0x268($sp)\n"
1941 "lwc1 $27, 0x26C($sp)\n"
1942 "lwc1 $28, 0x270($sp)\n"
1943 "lwc1 $29, 0x274($sp)\n"
1944 "lwc1 $30, 0x278($sp)\n"
1945 "lwc1 $31, 0x27C($sp)\n"
1946 "daddu $26, $31, $0\n"
1947 "lq $31, 0x1C0($sp)\n"
1948 "jr $26\n"
1949 "lq $sp, 0x1A0($sp)\n"
1950 ".set at\n"
1951 );
1952 }
1953
1954 ////////////////////////////////////////////////////////////////////
1955 //80003940
1956 ////////////////////////////////////////////////////////////////////
1957 void _ThreadHandler(u32 epc, u32 stack)
1958 {
1959 register int tid;
1960
1961 threads_array[threadId].entry =(void*)epc;
1962 threads_array[threadId].status =THS_READY;
1963 threads_array[threadId].stack_res =(void*)stack;
1964
1965 for ( ; threadPrio < 129; threadPrio++)
1966 if ((thread_ll_priorities[threadPrio].next !=
1967 &thread_ll_priorities[threadPrio]) ||
1968 (thread_ll_priorities[threadPrio].prev !=
1969 &thread_ll_priorities[threadPrio])){
1970 tid=threadId=(( (u32)thread_ll_priorities[threadPrio].prev -
1971 (u32)threads_array)*0x286BCA1B)>>2;
1972 break;
1973 }
1974
1975 if (threadPrio>=129){
1976 __printf("# <Thread> No active threads\n");
1977 Exit(1);
1978 tid=0;
1979 }
1980
1981 threads_array[tid].status=THS_RUN;
1982
1983 if (threads_array[tid].waitSema){
1984 threads_array[tid].waitSema=0;
1985 *(u32*)((u32)threads_array[tid].stack_res + 0x20) = -1;
1986 }
1987
1988 __asm__("move $2, %0\n"
1989 "move $3, %1\n"
1990 : : "r"(threads_array[tid].entry), "r"(threads_array[tid].stack_res) );
1991 }
1992
1993 ////////////////////////////////////////////////////////////////////
1994 //80003A78
1995 ////////////////////////////////////////////////////////////////////
1996 void _ChangeThread(u32 entry, u32 stack_res, int waitSema)
1997 {
1998 struct TCB *th;
1999 struct ll *l, *p;
2000 int prio;
2001
2002 th = &threads_array[threadId];
2003 th->status = THS_WAIT;
2004 th->waitSema = waitSema;
2005 th->entry = (void (*)(void*))entry;
2006 th->stack_res = (void*)stack_res;
2007
2008 prio = threadPrio;
2009 for (l = &thread_ll_priorities[prio]; ; l++, prio++) {
2010 if (prio >= 129) {
2011 __printf("# <Thread> No active threads\n");
2012 Exit(1); l = 0; break;
2013 }
2014
2015 if (l->next != l) { p = l->next; break; }
2016 if (l->prev == l) continue;
2017 p = l->prev; break;
2018 }
2019
2020 if (l) {
2021 threadPrio = prio;
2022 threadId = (((u32)p - (u32)threads_array) * 0x286BCA1B) / 4;
2023 }
2024
2025 th = &threads_array[threadId];
2026 th->status = THS_RUN;
2027 if (th->waitSema) {
2028 th->waitSema = 0;
2029 *(s64*)((u32)th->stack_res+0x20) = -1;
2030 }
2031
2032 __asm__("move $2, %0\n"
2033 "move $3, %1\n"
2034 : : "r"(th->entry), "r"(th->stack_res) );
2035 }
2036
2037 ////////////////////////////////////////////////////////////////////
2038 //80003C50 SYSCALL 032 CreateThread
2039 ////////////////////////////////////////////////////////////////////
2040 int _CreateThread(struct ThreadParam *param)
2041 {
2042 struct TCB *th;
2043 struct threadCtx *thctx;
2044 int index;
2045 int *ptr;
2046
2047 th = (struct TCB *)LL_unlink((struct ll*)&thread_ll_free);
2048 if (th == NULL) {
2049 __printf("%s: failed to get free thread\n", __FUNCTION__);
2050 return -1;
2051 }
2052
2053 threads_count++;
2054 index=(((u32)th-(u32)threads_array) * 0x286BCA1B)/4;
2055
2056 th->entry = param->entry;
2057 th->stack_res = param->stack + param->stackSize - STACK_RES;
2058 th->status = THS_DORMANT;
2059 th->gpReg = param->gpReg;
2060 th->initPriority = param->initPriority;
2061 th->argstring = 0;
2062 th->wakeupCount = 0;
2063 th->semaId = 0;
2064 th->stack = param->stack;
2065 th->argc = 0;
2066 th->entry_ = param->entry;
2067 th->heap_base = threads_array[threadId].heap_base;
2068 th->stackSize = param->stackSize;
2069 th->currentPriority = param->initPriority;
2070 th->waitSema = 0;
2071 th->root = threads_array[threadId].root;
2072
2073 thctx = th->stack_res;
2074 thctx->gp = (u32)param->gpReg;
2075 thctx->sp = (u32)&thctx[1];
2076 thctx->fp = (u32)&thctx[1];
2077 thctx->ra = (u32)threads_array[threadId].root;
2078
2079 return index;
2080 }
2081
2082 ////////////////////////////////////////////////////////////////////
2083 //80003E00 SYSCALL 37 iTerminateThread
2084 ////////////////////////////////////////////////////////////////////
2085 int _iTerminateThread(int tid)
2086 {
2087 //TODO
2088 }
2089
2090 ////////////////////////////////////////////////////////////////////
2091 //80003F00
2092 ////////////////////////////////////////////////////////////////////
2093 int __DeleteThread(int tid)
2094 {
2095 if ((tid>=256) || (tid==threadId) || (threads_array[tid].status!=THS_DORMANT))
2096 return -1;
2097
2098 releaseTCB(tid);
2099 return tid;
2100 }
2101
2102 ////////////////////////////////////////////////////////////////////
2103 //80003F70
2104 ////////////////////////////////////////////////////////////////////
2105 int __StartThread(int tid, void *arg)
2106 {
2107 if ((tid>=256) || (tid==threadId) || (threads_array[tid].status!=THS_DORMANT))
2108 return -1;
2109
2110 threads_array[tid].argstring = arg;
2111 ((void**)threads_array[tid].stack_res)[0x10] = arg; //a0
2112 thread_2_ready(tid);
2113 return tid;
2114 }
2115
2116 ////////////////////////////////////////////////////////////////////
2117 //80003FF8
2118 ////////////////////////////////////////////////////////////////////
2119 int __ExitThread()
2120 {
2121 //TODO
2122 }
2123
2124 ////////////////////////////////////////////////////////////////////
2125 //80004110
2126 ////////////////////////////////////////////////////////////////////
2127 int __ExitDeleteThread()
2128 {
2129 //TODO
2130 }
2131
2132 ////////////////////////////////////////////////////////////////////
2133 //80004228 SYSCALL 39 DisableDispatchThread
2134 ////////////////////////////////////////////////////////////////////
2135 int _DisableDispatchThread()
2136 {
2137 __printf("# DisableDispatchThread is not supported in this version\n");
2138 return threadId;
2139 }
2140
2141 ////////////////////////////////////////////////////////////////////
2142 //80004258 SYSCALL 40 EnableDispatchThread
2143 ////////////////////////////////////////////////////////////////////
2144 int _EnableDispatchThread()
2145 {
2146 __printf("# EnableDispatchThread is not supported in this version\n");
2147 return threadId;
2148 }
2149
2150 ////////////////////////////////////////////////////////////////////
2151 //80004288 SYSCALL 042 iChangeThreadPriority
2152 ////////////////////////////////////////////////////////////////////
2153 int _iChangeThreadPriority(int tid, int prio)
2154 {
2155 short oldPrio;
2156
2157 if ((tid >= 256) || (prio < 0) || (prio >= 128)) return -1;
2158
2159 if (tid == 0) tid = threadId;
2160 if (threads_array[tid].status == 0) return -1;
2161 if ((0 < (threads_array[tid].status ^ 0x10)) == 0) return -1;
2162
2163 oldPrio = threads_array[tid].currentPriority;
2164 if ((tid != threadId) && (threads_array[tid].status != THS_READY)) {
2165 threads_array[tid].currentPriority = prio;
2166 return oldPrio;
2167 }
2168
2169 if (threadPrio < prio) threadStatus = 1;
2170
2171 unsetTCB(tid);
2172 threads_array[tid].currentPriority = prio;
2173 thread_2_ready(tid);
2174
2175 return oldPrio;
2176 }
2177
2178 ////////////////////////////////////////////////////////////////////
2179 //80004388 SYSCALL 044 iRotateThreadReadyQueue
2180 ////////////////////////////////////////////////////////////////////
2181 int _iRotateThreadReadyQueue(int prio)
2182 {
2183 if (prio >= 128) return -1;
2184
2185 LL_rotate(&thread_ll_priorities[prio]);
2186 return prio;
2187 }
2188
2189 ////////////////////////////////////////////////////////////////////
2190 //800043D0 SYSCALL 046 iReleaseWaitThread
2191 ////////////////////////////////////////////////////////////////////
2192 int _iReleaseWaitThread(int tid)
2193 {
2194 if( (u32)(tid-1) >= 255 )
2195 return -1;
2196
2197 if( (u32)threads_array[tid].status >= 17 )
2198 return tid;
2199
2200 switch(threads_array[tid].status) {
2201 case 0:
2202 return -1;
2203 case THS_WAIT: {
2204 //443C
2205 if( threads_array[tid].waitSema == 2 ) {
2206 LL_unlinkthis((struct ll*)&threads_array[tid]);
2207 semas_array[threads_array[tid].semaId].wait_threads--;
2208 }
2209
2210 int threadPrioOld = threadPrio;
2211 threads_array[tid].status = THS_READY;
2212 thread_2_ready(tid);
2213
2214 if( threadPrio < threadPrioOld ) {
2215 threadStatus = 1;
2216 }
2217 break;
2218 }
2219 case (THS_WAIT|THS_SUSPEND):
2220 threads_array[tid].status = THS_SUSPEND;
2221 if( threads_array[tid].waitSema != 2 )
2222 return tid;
2223
2224 LL_unlinkthis((struct ll*)&threads_array[tid]);
2225 semas_array[threads_array[tid].semaId].wait_threads--;
2226 break;
2227 }
2228
2229 return tid;
2230 }
2231
2232 ////////////////////////////////////////////////////////////////////
2233 //80004548 SYSCALL 047 GetThreadId
2234 ////////////////////////////////////////////////////////////////////
2235 int _GetThreadId()
2236 {
2237 return threadId;
2238 }
2239
2240 ////////////////////////////////////////////////////////////////////
2241 //80004558 SYSCALL 048 ReferThreadStatus
2242 ////////////////////////////////////////////////////////////////////
2243 int _ReferThreadStatus(int tid, struct ThreadParam *info)
2244 {
2245 if (tid >= 256) return -1;
2246 if (tid == 0) tid = threadId;
2247
2248 if (info != NULL) {
2249 info->entry = threads_array[tid].entry;
2250 info->status = threads_array[tid].status;
2251 info->stack = threads_array[tid].stack;
2252 info->stackSize = threads_array[tid].stackSize;
2253 info->gpReg = threads_array[tid].gpReg;
2254 info->initPriority = threads_array[tid].initPriority;
2255 info->currentPriority = threads_array[tid].currentPriority;
2256 info->attr = threads_array[tid].attr;
2257 info->waitSema = threads_array[tid].waitSema;
2258 info->option = threads_array[tid].option;
2259 info->waitId = threads_array[tid].semaId;
2260 info->wakeupCount = threads_array[tid].wakeupCount;
2261 }
2262
2263 return threads_array[tid].status;
2264 }
2265
2266 ////////////////////////////////////////////////////////////////////
2267 //80004658
2268 ////////////////////////////////////////////////////////////////////
2269 int __SleepThread()
2270 {
2271 if (threads_array[threadId].wakeupCount <= 0) {
2272 unsetTCB(threadId);
2273 return -1;
2274 }
2275
2276 threads_array[threadId].wakeupCount--;
2277 return threadId;
2278 }
2279
2280 ////////////////////////////////////////////////////////////////////
2281 //800046B0 SYSCALL 052 iWakeupThread
2282 ////////////////////////////////////////////////////////////////////
2283 int _iWakeupThread(int tid)
2284 {
2285 register int prio;
2286
2287 if (tid>=256) return -1;
2288
2289 if (tid==0) tid = threadId;
2290
2291 switch (threads_array[tid].status){
2292 case THS_WAIT:
2293 if (threads_array[tid].waitSema=1){
2294 prio=threadPrio;
2295 thread_2_ready(tid);
2296 if (threadPrio<prio)
2297 threadStatus=THS_RUN;
2298 threads_array[tid].waitSema=0;
2299 }else
2300 threads_array[tid].wakeupCount++;
2301 break;
2302 case THS_READY:
2303 case THS_SUSPEND:
2304 threads_array[tid].wakeupCount++;
2305 break;
2306 case (THS_WAIT|THS_SUSPEND):
2307 if (threads_array[tid].waitSema==1){
2308 threads_array[tid].status=THS_SUSPEND;
2309 threads_array[tid].waitSema=0;
2310 }else
2311 threads_array[tid].wakeupCount++;
2312 break;
2313 default:
2314 return -1;
2315 }
2316
2317 return tid;
2318 }
2319
2320 ////////////////////////////////////////////////////////////////////
2321 //80004808 SYSCALL 055 SuspendThread
2322 //80004808 SYSCALL 056 iSuspendThread
2323 ////////////////////////////////////////////////////////////////////
2324 int _SuspendThread(int thid)
2325 {
2326 if (thid<256){
2327 if ((threads_array[thid].status==THS_READY) ||
2328 (threads_array[thid].status==THS_RUN)){
2329 unsetTCB(thid);
2330 threads_array[thid].status=THS_SUSPEND;
2331 return thid;
2332 }
2333 if (threads_array[thid].status==THS_WAIT){
2334 threads_array[thid].status=(THS_WAIT|THS_SUSPEND);
2335 return thid;
2336 }
2337 }
2338 return -1;
2339 }
2340
2341 ////////////////////////////////////////////////////////////////////
2342 //800048C0 SYSCALL 058 iResumeThread
2343 ////////////////////////////////////////////////////////////////////
2344 int _iResumeThread(int tid)
2345 {
2346 int tmp;
2347 if ((tid<256) && (threadId!=tid)) {
2348 if (threads_array[tid].status==THS_SUSPEND){
2349 tmp=threadPrio;
2350 thread_2_ready(tid);
2351 if (threadPrio < tmp)
2352 threadStatus=THS_RUN;
2353 }
2354 else if (threads_array[tid].status==(THS_WAIT|THS_SUSPEND))
2355 threads_array[tid].status=THS_WAIT;
2356 return tid;
2357 }
2358 return -1;
2359 }
2360
2361 ////////////////////////////////////////////////////////////////////
2362 //80004970 SYSCALL 053 CancelWakeupThread
2363 //80004970 SYSCALL 054 iCancelWakeupThread
2364 ////////////////////////////////////////////////////////////////////
2365 int _CancelWakeupThread(int tid)
2366 {
2367 register int ret;
2368
2369 if (tid>=256) return -1;
2370 tid = tid ? tid : threadId;
2371 ret=threads_array[tid].wakeupCount;
2372 threads_array[tid].wakeupCount=0;
2373 return ret;
2374 }
2375
2376 ////////////////////////////////////////////////////////////////////
2377 //800049B0 SYSCALL 080 RFU080_CreateEventFlag
2378 ////////////////////////////////////////////////////////////////////
2379 int _CreateEventFlag()
2380 {
2381 return threads_count; // CreateEventFlag, why!?!
2382 }
2383
2384 ////////////////////////////////////////////////////////////////////
2385 //800049C0 SYSCALL 064 CreateSema
2386 ////////////////////////////////////////////////////////////////////
2387 int _CreateSema(struct SemaParam *sema)
2388 {
2389 register struct kSema *crt=semas_last;
2390
2391 if ((crt==NULL) || (sema->init_count<0)) return -1;
2392
2393 crt->wait_prev = (struct TCB*)&crt->wait_next;
2394 semas_count++;
2395 crt->count =sema->init_count;
2396 crt->wait_next =(struct TCB*)&crt->wait_next;
2397 semas_last = crt->free;
2398 crt->max_count =sema->max_count;
2399 crt->free =NULL;
2400 crt->attr =sema->attr;
2401 crt->wait_threads=0;
2402 crt->option =sema->option;
2403
2404 return (crt-semas_array); //sizeof(kSema)==32
2405 }
2406
2407 ////////////////////////////////////////////////////////////////////
2408 //80004A48 SYSCALL 073 iDeleteSema
2409 ////////////////////////////////////////////////////////////////////
2410 int _iDeleteSema(int sid)
2411 {
2412 register thid, thprio;
2413 if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1;
2414
2415 semas_count--;
2416 while (semas_array[sid].wait_threads>0){
2417 thid=(((u32)LL_unlink((struct ll*)&semas_array[sid].wait_next)-(u32)threads_array) * 0x286BCA1B)/4;
2418 LL_unlinkthis((struct ll*)&threads_array[thid]);
2419 semas_array[sid].wait_threads--;
2420 if (threads_array[thid].status==THS_WAIT){
2421 thprio=threadPrio;
2422 thread_2_ready(thid);
2423 if (threadPrio<thprio)
2424 threadStatus=THS_RUN;
2425 }
2426 else if (threads_array[thid].status!=(THS_WAIT|THS_SUSPEND))
2427 threads_array[thid].status=THS_SUSPEND;
2428 }
2429 semas_array[sid].count =-1;
2430 semas_array[sid].free =semas_last;
2431 semas_last =&semas_array[sid];
2432 return sid;
2433 }
2434
2435 ////////////////////////////////////////////////////////////////////
2436 //80004BC8 SYSCALL 067 iSignalSema
2437 ////////////////////////////////////////////////////////////////////
2438 int _iSignalSema(int sid)
2439 {
2440 register int prio, thid;
2441 if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1;
2442
2443 if (semas_array[sid].wait_threads>0){
2444 thid=(((u32)LL_unlink((struct ll*)&semas_array[sid].wait_next)-(u32)threads_array)*0x286BCA1B)/4;
2445
2446 LL_unlinkthis((struct ll*)&threads_array[thid]);
2447
2448 semas_array[sid].wait_threads--;
2449
2450 if (threads_array[thid].status==THS_WAIT){
2451 prio=threadPrio;
2452 thread_2_ready(thid);
2453 if (threadPrio < prio)
2454 threadStatus=THS_RUN;
2455 threads_array[thid].waitSema=0; //just a guess:P
2456 }
2457 else if (threads_array[thid].status==(THS_WAIT|THS_SUSPEND)){
2458 threads_array[thid].status =THS_SUSPEND;
2459 threads_array[thid].waitSema=0;
2460 }
2461 }else
2462 semas_array[sid].count++;
2463 return sid;
2464 }
2465
2466 ////////////////////////////////////////////////////////////////////
2467 //80004CF8
2468 ////////////////////////////////////////////////////////////////////
2469 int _iWaitSema(int sid)
2470 {
2471 if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1;
2472
2473 if (semas_array[sid].count>0){
2474 semas_array[sid].count--;
2475 return sid;
2476 }
2477
2478 semas_array[sid].wait_threads++;
2479
2480 unsetTCB(threadId);
2481 LL_add((struct ll*)&semas_array[sid].wait_next, (struct ll*)&threads_array[threadId]);
2482 threads_array[threadId].semaId=sid;
2483
2484 return -2;
2485 }
2486
2487 ////////////////////////////////////////////////////////////////////
2488 //80004DC8 SYSCALL 069 PollSema, 070 iPollSema
2489 ////////////////////////////////////////////////////////////////////
2490 int _PollSema(int sid)
2491 {
2492 if ((sid>=MAX_SEMAS) || (semas_array[sid].count<=0)) return -1;
2493
2494 semas_array[sid].count--;
2495
2496 return sid;
2497 }
2498
2499 ////////////////////////////////////////////////////////////////////
2500 //80004E00 SYSCALL 071 ReferSemaStatus, 072 iReferSemaStatus
2501 ////////////////////////////////////////////////////////////////////
2502 int _ReferSemaStatus(int sid, struct SemaParam *sema)
2503 {
2504 if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1;
2505
2506 sema->count =semas_array[sid].count;
2507 sema->max_count =semas_array[sid].max_count;
2508 sema->wait_threads =semas_array[sid].wait_threads;
2509 sema->attr =semas_array[sid].attr;
2510 sema->option =semas_array[sid].option;
2511
2512 return sid;
2513 }
2514
2515 ////////////////////////////////////////////////////////////////////
2516 //80004E58 SYSCALL 081 RFU081_DeleteEventFlag
2517 ////////////////////////////////////////////////////////////////////
2518 int _DeleteEventFlag()
2519 {
2520 return semas_count; // DeleteEventFlag, why!?!
2521 }
2522
2523 ////////////////////////////////////////////////////////////////////
2524 //80004E68
2525 ////////////////////////////////////////////////////////////////////
2526 int _SemasInit()
2527 {
2528 int i;
2529
2530 for (i=0; i<256; i++) {
2531 semas_array[i].free = &semas_array[i+1];
2532 semas_array[i].count = -1;
2533 semas_array[i].wait_threads = 0;
2534 semas_array[i].wait_next = (struct TCB*)&semas_array[i].wait_next;
2535 semas_array[i].wait_prev = (struct TCB*)&semas_array[i].wait_next;
2536 }
2537 semas_array[255].free = 0;
2538
2539 semas_last = semas_array;
2540 semas_count = 0;
2541
2542 return 256;
2543 }
2544
2545 ////////////////////////////////////////////////////////////////////
2546 //80004EC8
2547 ////////////////////////////////////////////////////////////////////
2548 void __load_module_EENULL()
2549 {
2550 int i;
2551
2552 thread_ll_free.prev = &thread_ll_free;
2553 thread_ll_free.next = &thread_ll_free;
2554
2555 for (i=0; i<128; i++) {
2556 thread_ll_priorities[i].prev = &thread_ll_priorities[i];
2557 thread_ll_priorities[i].next = &thread_ll_priorities[i];
2558 }
2559
2560 threads_count = 0;
2561 threadId = 0;
2562 threadPrio = 0;
2563
2564 for (i=0; i<256; i++) {
2565 threads_array[i].status = 0;
2566 LL_add(&thread_ll_free, (struct ll*)&threads_array[i]);
2567 }
2568
2569 _SemasInit();
2570
2571 threadStatus = 0;
2572 __load_module("EENULL", (void (*)(void*))0x81FC0, (void*)0x81000, 0x80);
2573 }
2574
2575 ////////////////////////////////////////////////////////////////////
2576 //80004FB0
2577 // makes the args from argc & argstring; args is in bss of program
2578 ////////////////////////////////////////////////////////////////////
2579 void _InitArgs(char *argstring, ARGS *args, int argc)
2580 {
2581 int i;
2582 char *p = args->args;
2583
2584 args->argc = argc;
2585 for (i=0; i<argc; i++) {
2586 args->argv[i] = p; //copy string pointer
2587 while (*argstring) //copy the string itself
2588 *p++ = *argstring++;
2589 *p++ = *argstring++; //copy the '\0'
2590 }
2591 }
2592
2593 ////////////////////////////////////////////////////////////////////
2594 //80005198 SYSCALL 060 _InitializeMainThread
2595 ////////////////////////////////////////////////////////////////////
2596 void *_InitializeMainThread(u32 gp, void *stack, int stack_size, char *args, int root)
2597 {
2598 struct TCB *th;
2599 struct threadCtx *ctx;
2600
2601 if ((int)stack == -1)
2602 stack = (void*)((_GetMemorySize() - 4*1024) - stack_size);
2603
2604 ctx = (struct threadCtx*)((u32)stack + stack_size - STACK_RES/4);
2605 ctx->gp = gp; //+1C0
2606 ctx->ra = root; //+1F0
2607 ctx->fp = (u32)ctx+0x280; //+1E0 <- &280
2608 ctx->sp = (u32)ctx+0x280; //+1D0 <- &280
2609
2610 th = &threads_array[threadId];
2611 th->gpReg = (void*)gp;
2612 th->stackSize = stack_size;
2613 th->stack_res = ctx;
2614 th->stack = stack;
2615 th->root = (void*)root;
2616 _InitArgs(th->argstring, (ARGS*)args, th->argc);
2617 th->argstring = args;
2618
2619 return ctx;
2620 }
2621
2622 ////////////////////////////////////////////////////////////////////
2623 //800052A0 SYSCALL 061 RFU061_InitializeHeapArea
2624 ////////////////////////////////////////////////////////////////////
2625 void* _InitializeHeapArea(void *heap_base, int heap_size)
2626 {
2627 void *ret;
2628
2629 if (heap_size < 0) {
2630 ret = threads_array[threadId].stack;
2631 } else {
2632 ret = heap_base + heap_size;
2633 }
2634
2635 threads_array[threadId].heap_base = ret;
2636 return ret;
2637 }
2638
2639 ////////////////////////////////////////////////////////////////////
2640 //800052D8 SYSCALL 062 RFU062_EndOfHeap
2641 ////////////////////////////////////////////////////////////////////
2642 void* _EndOfHeap()
2643 {
2644 return threads_array[threadId].heap_base;
2645 }
2646
2647 ////////////////////////////////////////////////////////////////////
2648 //80005390
2649 ////////////////////////////////////////////////////////////////////
2650 int __load_module(char *name, void (*entry)(void*), void *stack_res, int prio)
2651 {
2652 struct TCB *th;
2653 int index;
2654 int *ptr;
2655 struct rominfo ri;
2656
2657 th = (struct TCB*)LL_unlink(&thread_ll_free);
2658 if (th) {
2659 threads_count++;
2660 index = (((u32)th-(u32)threads_array) * 0x286BCA1B)/4;
2661 } else {
2662 index = -1;
2663 }
2664
2665 threadId = index;
2666 th->wakeupCount = 0;
2667 th->semaId = 0;
2668 th->attr = 0;
2669 th->stack_res = stack_res;
2670 th->option = 0;
2671 th->entry = entry;
2672 th->gpReg = 0;
2673 th->currentPriority = prio;
2674 th->status = THS_DORMANT;
2675 th->waitSema = 0;
2676 th->entry_ = entry;
2677 th->argc = 0;
2678 th->argstring = 0;
2679 th->initPriority = prio;
2680
2681 thread_2_ready(index);
2682
2683 if (romdirGetFile(name, &ri) == NULL) {
2684 __printf("# panic ! '%s' not found\n", name);
2685 _Exit(1);
2686 }
2687
2688 if (ri.fileSize > 0) {
2689 int i;
2690 int *src = (int*)(0xbfc00000+ri.fileOffset);
2691 int *dst = (int*)entry;
2692
2693 for (i=0; i<ri.fileSize; i+=4) {
2694 *dst++ = *src++;
2695 }
2696 }
2697
2698 FlushInstructionCache();
2699 FlushDataCache();
2700
2701 return index;
2702 }
2703
2704 ////////////////////////////////////////////////////////////////////
2705 //80005560 eestrcpy
2706 ////////////////////////////////////////////////////////////////////
2707 char* eestrcpy(char* dst, const char* src)
2708 {
2709 while( *src )
2710 *dst++ = *src++;
2711
2712 *dst = 0;
2713 return dst+1;
2714 }
2715
2716 ////////////////////////////////////////////////////////////////////
2717 //800055A0 SYSCALL 6 LoadPS2Exe
2718 ////////////////////////////////////////////////////////////////////
2719 int _LoadPS2Exe(char *filename, int argc, char **argv)
2720 {
2721 char* pbuf;
2722 struct rominfo ri;
2723 struct TCB* curtcb;
2724 int curthreadid;
2725
2726 pbuf = eestrcpy(threadArgStrBuffer, "EELOAD");
2727 pbuf = eestrcpy(pbuf, filename);
2728
2729 if( argc > 0 ) {
2730 int i;
2731 for(i = 0; i < argc; ++i)
2732 pbuf = strcpy(pbuf, argv[i]);
2733 }
2734
2735 threads_array[threadId].argc = argc+2;
2736 threads_array[threadId].argstring = threadArgStrBuffer;
2737 _CancelWakeupThread(threadId);
2738 _iChangeThreadPriority(threadId, 0);
2739
2740 // search for RESET
2741 // search for filename romdir entry
2742 if( romdirGetFile(filename, &ri) == NULL ) {
2743 __printf("# panic ! '%s' not found\n", filename);
2744 _Exit();
2745 }
2746
2747 // terminate threads
2748 curthreadid = 1; // skip main thread?
2749 curtcb = &threads_array[curthreadid];
2750
2751 while(curthreadid < 256) {
2752 if( curtcb->status && threadId != curthreadid ) {
2753 if( curtcb->status == THS_DORMANT ) {
2754 _DeleteThread(curthreadid);
2755 }
2756 else {
2757 iTerminateThread(curthreadid);
2758 _DeleteThread(curthreadid);
2759 }
2760 }
2761 ++curthreadid;
2762 ++curtcb;
2763 }
2764
2765 _SemasInit();
2766 threadStatus = 0;
2767 InitPgifHandler2();
2768
2769 Restart();
2770
2771 if( ri.fileSize > 0 ) {
2772 // copy to PS2_LOADADDR
2773 int i;
2774 u32* psrc = (u32*)(0xbfc00000+ri.fileOffset);
2775 u32* pdst = (u32*)PS2_LOADADDR;
2776 for(i = 0; i < ri.fileSize; i += 4)
2777 *pdst++ = *psrc++;
2778 }
2779
2780 FlushInstructionCache();
2781 FlushDataCache();
2782
2783 __asm__("mtc0 %0, $14\n"
2784 "sync\n" : : "r"(PS2_LOADADDR));
2785 erase_cpu_regs();
2786 __asm__("di\n"
2787 "eret\n");
2788 }
2789
2790 ////////////////////////////////////////////////////////////////////
2791 //800057E8
2792 ////////////////////////////////////////////////////////////////////
2793 void* __ExecPS2(void * entry, void * gp, int argc, char ** argv)
2794 {
2795 char* pbuf = threadArgStrBuffer;
2796 int i;
2797
2798 if( argc > 0 ) {
2799 for(i = 0; i < argc; ++i)
2800 pbuf = eestrcpy(pbuf, argv[i]);
2801 }
2802
2803 threads_array[threadId].entry = entry; //0C
2804 threads_array[threadId].wakeupCount = 0; //24
2805 threads_array[threadId].gpReg = gp; //14
2806 threads_array[threadId].semaId = 0; //20
2807 threads_array[threadId].argstring = threadArgStrBuffer; //38
2808 threads_array[threadId].argc = argc; //34
2809 threads_array[threadId].entry_ = entry; //30
2810 threads_array[threadId].currentPriority = 0; //18
2811 threads_array[threadId].waitSema = 0; //1C
2812 threads_array[threadId].initPriority = 0;
2813 FlushInstructionCache();
2814 FlushDataCache();
2815
2816 return entry;
2817 }
2818
2819 ////////////////////////////////////////////////////////////////////
2820 //800058E8
2821 ////////////////////////////////////////////////////////////////////
2822 int _ExecOSD(int argc, char **argv)
2823 {
2824 return _LoadPS2Exe("rom0:OSDSYS", argc, argv);
2825 }
2826
2827 ////////////////////////////////////////////////////////////////////
2828 //80005900
2829 ////////////////////////////////////////////////////////////////////
2830 int _RFU004_Exit()
2831 {
2832 char *bb = "BootBrowser";
2833 return _LoadPS2Exe("rom0:OSDSYS", 1, &bb);
2834 }
2835
2836 ////////////////////////////////////////////////////////////////////
2837 //80005938
2838 ////////////////////////////////////////////////////////////////////
2839 void releaseTCB(int tid)
2840 {
2841 threads_count--;
2842 threads_array[tid].status=0;
2843 LL_add(&thread_ll_free, (struct ll*)&threads_array[tid]);
2844 }
2845
2846 ////////////////////////////////////////////////////////////////////
2847 //80005978
2848 ////////////////////////////////////////////////////////////////////
2849 void unsetTCB(int tid)
2850 {
2851 if ((threads_array[tid].status) <= THS_READY)
2852 LL_unlinkthis((struct ll*)&threads_array[tid]);
2853 }
2854
2855 ////////////////////////////////////////////////////////////////////
2856 //800059B8
2857 ////////////////////////////////////////////////////////////////////
2858 void thread_2_ready(int tid)
2859 {
2860 threads_array[tid].status=THS_READY;
2861 if (threads_array[tid].initPriority < threadPrio)
2862 threadPrio=(short)threads_array[tid].initPriority;
2863 LL_add( &thread_ll_priorities[threads_array[tid].initPriority], (struct ll*)&threads_array[tid] );
2864 }
2865
2866 ////////////////////////////////////////////////////////////////////
2867 //80005A58
2868 ////////////////////////////////////////////////////////////////////
2869 struct ll* LL_unlink(struct ll *l)
2870 {
2871 struct ll *p;
2872
2873 if ((l==l->next) && (l==l->prev))
2874 return 0;
2875 p=l->prev;
2876 p->prev->next=p->next;
2877 p->next->prev=p->prev;
2878 return p;
2879 }
2880
2881 ////////////////////////////////////////////////////////////////////
2882 //80005A98
2883 ////////////////////////////////////////////////////////////////////
2884 struct ll* LL_rotate(struct ll *l)
2885 {
2886 struct ll *p;
2887
2888 if (p=LL_unlink(l)){
2889 p->prev=l;
2890 p->next=l->next;
2891 l->next->prev=p;
2892 l->next=p;
2893 return l->prev;
2894 }
2895 return NULL;
2896 }
2897
2898 ////////////////////////////////////////////////////////////////////
2899 //80005AE8
2900 ////////////////////////////////////////////////////////////////////
2901 struct ll *LL_unlinkthis(struct ll *l)
2902 {
2903 l->prev->next=l->next;
2904 l->next->prev=l->prev;
2905 return l->next;
2906 }
2907
2908 ////////////////////////////////////////////////////////////////////
2909 //80005B08
2910 ////////////////////////////////////////////////////////////////////
2911 void LL_add(struct ll *l, struct ll *new)
2912 {
2913 new->prev=l;
2914 new->next=l->next;
2915 l->next->prev=new;
2916 l->next=new;
2917 }
2918
2919 ////////////////////////////////////////////////////////////////////
2920 //80005B28 SYSCALL 9 (0x09) TlbWriteRandom
2921 ////////////////////////////////////////////////////////////////////
2922 int _TlbWriteRandom(u32 PageMask, u32 EntryHi, u32 EntryLo0, u32 EntryLo1) {
2923 if ((EntryHi >> 24) != 4) return -1;
2924 __asm__ (
2925 "mfc0 $2, $1\n"
2926 "mtc0 $2, $0\n"
2927 "mtc0 $4, $5\n"
2928 "mtc0 $5, $10\n"
2929 "mtc0 $6, $2\n"
2930 "mtc0 $7, $3\n"
2931 "sync\n"
2932 "tlbwi\n"
2933 "sync\n"
2934 );
2935 }
2936
2937 int _sifGetMSFLG() {
2938 u32 msflg;
2939 for (;;) {
2940 msflg = SBUS_MSFLG;
2941 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
2942 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
2943 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
2944
2945 if (msflg == SBUS_MSFLG) return msflg;
2946 }
2947 }
2948
2949 ////////////////////////////////////////////////////////////////////
2950 //80005E58
2951 ////////////////////////////////////////////////////////////////////
2952 int _sifGetSMFLG() {
2953 u32 smflg;
2954 for (;;) {
2955 smflg = SBUS_SMFLG;
2956 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
2957 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
2958 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
2959
2960 if (smflg == SBUS_SMFLG) return smflg;
2961 }
2962 }
2963
2964 int _ResetSif1()
2965 {
2966 sif1tagdata = 0xFFFF001E;
2967 //*(int*)0xa0001e330 = 0x20000000;
2968 //*(int*)0xa0001e334 = (u32)ptag&0x0fffffff;
2969 D6_QWC = 0;
2970 D6_TAG = (u32)&sif1tagdata&0x0fffffff;
2971 }
2972
2973 ////////////////////////////////////////////////////////////////////
2974 //80006198
2975 ////////////////////////////////////////////////////////////////////
2976 void SifDmaInit()
2977 {
2978 int msflg;
2979 memset(sifEEbuff, 0, sizeof(sifEEbuff));
2980 memset(sifRegs, 0, sizeof(sifRegs));
2981
2982 *(u32*)0xB000F260 = 0xFF;
2983 D5_CHCR = 0;
2984 D6_CHCR = 0;
2985
2986 _SifSetDChain();
2987 *(u32*)0xB000F200 = (u32)sifEEbuff;
2988 __printf("MSFLG = 0x10000\n");
2989 SBUS_MSFLG = 0x10000;
2990 msflg = SBUS_MSFLG;
2991 _ResetSif1();
2992 _SifSetReg(1, 0);
2993
2994 while (!(_SifGetReg(4) & 0x10000)) { __asm__ ("nop\nnop\nnop\nnop\n"); }
2995
2996 sifIOPbuff = *(u32*)0xB000F210;
2997
2998 SBUS_MSFLG = 0x20000;
2999 SBUS_MSFLG;
3000 }
3001
3002 ////////////////////////////////////////////////////////////////////
3003 //800062A0 SYSCALL 120 (0x78) SifSetDChain
3004 ////////////////////////////////////////////////////////////////////
3005 void _SifSetDChain(){
3006 int var_10;
3007
3008 D5_CHCR = 0;
3009 D5_QWC = 0;
3010 D5_CHCR = 0x184; // 0001 1000 0100
3011 var_10 = D5_CHCR; // read?
3012 }
3013
3014 ////////////////////////////////////////////////////////////////////
3015 //800062D8 SYSCALL 107 (0x6B) SifStopDma
3016 ////////////////////////////////////////////////////////////////////
3017 void _SifStopDma(){
3018 int var_10;
3019
3020 D5_CHCR = 0;
3021 D5_QWC = 0;
3022 var_10 = D5_CHCR; // read?
3023 }
3024
3025 ////////////////////////////////////////////////////////////////////
3026 //80006370
3027 ////////////////////////////////////////////////////////////////////
3028 void _SifDmaSend(void *src, void *dest, int size, int attr, int id)
3029 {
3030 int qwc;
3031 struct TAG* t1;
3032 int *t3;
3033 int tocopy;
3034
3035 if (((++tagindex) & 0xFF) == 31){
3036 tagindex=0;
3037 transferscount++;
3038 }
3039
3040 qwc=(size+15)/16; //rount up
3041
3042 t1=(struct TAG*)KSEG1_ADDR(&tadrptr[tagindex]);
3043 if (attr & SIF_DMA_TAG) {
3044 t1->id_qwc = (id << 16) | qwc |
3045 ((attr & SIF_DMA_INT_I) ? 0x80000000 : 0); //IRQ
3046 t1->addr=(u32)src & 0x1FFFFFFF;
3047 t3=(int*)KSEG1_ADDR(src);
3048 qwc--;
3049 }
3050 else {
3051 if (qwc >= 8){ //two transfers
3052 tocopy=7;
3053 t1->id_qwc=0x30000008; //(id)REF | (qwc)8;
3054 t1->addr=(u32)&extrastorage[tagindex] | 0x1FFFFFFF;
3055 t3=(int*)KSEG1_ADDR(&extrastorage[tagindex]);
3056
3057 if (((++tagindex) & 0xff) == 31){
3058 tagindex=0;
3059 transferscount++;
3060 }
3061
3062 t1=(struct TAG*)KSEG1_ADDR(&tadrptr[tagindex]);
3063 t1->id_qwc=(id << 16) | (qwc - 7) |
3064 ((attr & SIF_DMA_INT_I) ? 0x80000000 : 0);//IRQ
3065 t1->addr=(u32)(src+112) | 0x1FFFFFFF;
3066 }
3067 else {
3068 tocopy=qwc;
3069 t1->id_qwc=(id << 16) | (qwc+1) |
3070 ((attr & SIF_DMA_INT_I) ? 0x80000000 : 0);//IRQ
3071 t1->addr=(u32)&extrastorage[tagindex] & 0x1FFFFFFF;
3072 t3=(int*)KSEG1_ADDR(&extrastorage[tagindex]);
3073 }
3074 memcpy((char*)t3+16, (void*)KSEG1_ADDR(src), tocopy*16);//inline with qwords
3075 }
3076 t3[1]=qwc * 4;
3077 t3[0]=(u32)((u32)dest & 0x00FFFFFF) |
3078 ((((u32)(attr & SIF_DMA_INT_O)) ? 0x40000000 : 0) |
3079 (((u32)(attr & SIF_DMA_ERT)) ? 0x80000000 : 0));
3080 }
3081
3082 ////////////////////////////////////////////////////////////////////
3083 //800065C8
3084 ////////////////////////////////////////////////////////////////////
3085 int _SifDmaCount()
3086 {
3087 register int count;
3088
3089 count=((D6_TAG-(u32)tadrptr) & 0x1FFFFFFF) >> 4;
3090
3091 count=count>0? count-1:30;
3092
3093 if (count == tagindex)
3094 return (D6_QWC ? 30 : 31);
3095
3096 if (count < tagindex)
3097 return count + 30 - tagindex;
3098
3099 return count-tagindex-1;
3100 }
3101
3102 ////////////////////////////////////////////////////////////////////
3103 //80006650
3104 ////////////////////////////////////////////////////////////////////
3105 void _SifDmaPrepare(int count)
3106 {
3107 register struct TAG *t0;
3108
3109 if (count==31) return;
3110
3111 t0=(struct TAG*)KSEG1_ADDR(&tadrptr[tagindex]);
3112 if (count == 30){
3113 t0->id_qwc &= DMA_TAG_IRQ|DMA_TAG_PCE; //keep PCE|REFE|IRQ
3114 t0->id_qwc |= DMA_TAG_REF<<28;
3115 t0->id_qwc |= D6_QWC;
3116 t0->addr = D6_MADR;
3117 D6_QWC = 0;
3118 D6_TAG = KUSEG_ADDR(t0);
3119 }else
3120 t0->id_qwc |= DMA_TAG_REF<<28;
3121 }
3122
3123 ////////////////////////////////////////////////////////////////////
3124 //800066F8 SYSCALL 119 (0x77) SifSetDma
3125 ////////////////////////////////////////////////////////////////////
3126 u32 _SifSetDma(SifDmaTransfer_t *sdd, int len)
3127 {
3128 int var_10;
3129 int count, tmp;
3130 int i, c, _len = len;
3131 int nextindex;
3132
3133 DMAC_ENABLEW = DMAC_ENABLER | 0x10000; //suspend
3134
3135 D6_CHCR = 0; //kill any previous transfer?!?
3136 var_10 = D6_CHCR; // read?
3137
3138 DMAC_ENABLEW = DMAC_ENABLER & ~0x10000; //enable
3139
3140 count = _SifDmaCount();
3141
3142 lenloop:
3143 i=0; c=0;
3144 while (_len > 0) {
3145 if (!(sdd[i].attr & SIF_DMA_TAG)) {
3146 if (sdd[i].size <= 112) c++;
3147 else c+=2;
3148 } else c++;
3149 _len--; i++;
3150 }
3151 if (count < c) { count = 0; goto lenloop; }
3152
3153 nextindex = ((tagindex+1) % 31) & 0xff;
3154 if (nextindex == 0)
3155 tmp = (transferscount + 1) & 0xFFFF;
3156 else
3157 tmp = transferscount;
3158
3159 _SifDmaPrepare(count);
3160
3161 while (len > 0) {
3162 _SifDmaSend(sdd->src, sdd->dest, sdd->size, sdd->attr, DMA_TAG_REF<<12);//REF >> 16
3163 sdd++; len--;
3164 }
3165
3166 _SifDmaSend(sdd->src, sdd->dest, sdd->size, sdd->attr, DMA_TAG_REFE<<12);//REFE >> 16
3167
3168 D6_CHCR|= 0x184;
3169 var_10 = D6_CHCR; // read?
3170 return (tmp<<16)|(nextindex<<8)|c;
3171 }
3172
3173 ////////////////////////////////////////////////////////////////////
3174 //800068B0 SYSCALL 118 (0x76) SifDmaStat
3175 ////////////////////////////////////////////////////////////////////
3176 int _SifDmaStat(int id)
3177 {
3178 //TODO
3179 return 0;
3180 }
3181
3182 ////////////////////////////////////////////////////////////////////
3183 //80006B60 SYSCALL 121 (0x79) SifSetDma
3184 ////////////////////////////////////////////////////////////////////
3185 int _SifSetReg(int reg, u32 val)
3186 {
3187 __printf("%s: reg=%d; val=%x\n", __FUNCTION__, reg, val);
3188
3189 if (reg == 1) {
3190 *(u32*)0xB000F200 = val;
3191 return *(u32*)0xB000F200;
3192 } else
3193 if (reg == 3) {
3194 SBUS_MSFLG = val;
3195 return _sifGetMSFLG();
3196 } else
3197 if (reg == 4) {
3198 SBUS_SMFLG = val;
3199 return _sifGetSMFLG();
3200 } else
3201 if (reg >= 0) {
3202 return 0;
3203 }
3204
3205 reg&= 0x7FFFFFFF;
3206 if (reg >= 32) return 0;
3207
3208 sifRegs[reg] = val;
3209 return val;
3210 }
3211
3212 ////////////////////////////////////////////////////////////////////
3213 //80006C18 SYSCALL 122 (0x7A) SifSetDma
3214 ////////////////////////////////////////////////////////////////////
3215 int _SifGetReg(int reg)
3216 {
3217 //__printf("%s: reg=%x\n", __FUNCTION__, reg);
3218
3219 if (reg == 1) {
3220 return *(u32*)0xB000F200;
3221 } else
3222 if (reg == 2) {
3223 return *(u32*)0xB000F210;
3224 } else
3225 if (reg == 3) {
3226 return _sifGetMSFLG();
3227 } else
3228 if (reg == 4) {
3229 return _sifGetSMFLG();
3230 } else
3231 if (reg >= 0) {
3232 return 0;
3233 }
3234
3235 reg&= 0x7FFFFFFF;
3236 if (reg >= 32) return 0;
3237
3238 //__printf("ret=%x\n", sifRegs[reg]);
3239 return sifRegs[reg];
3240 }
3241
3242 ////////////////////////////////////////////////////////////////////
3243 //80007428 SYSCALL 117 print
3244 ////////////////////////////////////////////////////////////////////
3245 void _print()
3246 {
3247 }
3248
3249 ////////////////////////////////////////////////////////////////////
3250 //800074D8
3251 ////////////////////////////////////////////////////////////////////
3252 void _SetGsCrt2()
3253 {
3254 u32 tmp;
3255
3256 tmp = *(int*)0x8001F344;
3257 if (tmp == 0x40 || tmp == 0x60 || tmp == 0x61) {
3258 *(char*)0xbf803218 = 0;
3259 *(char*)0xbf803218 = 2;
3260 return;
3261 }
3262
3263 *(short*)0xbf801470 = 0;
3264 *(short*)0xbf801472 = 0;
3265 *(short*)0xbf801472 = 1;
3266 }
3267
3268 ////////////////////////////////////////////////////////////////////
3269 //800076B0
3270 ////////////////////////////////////////////////////////////////////
3271 void _iJoinThread(int param)
3272 {
3273 //TODO
3274 }
3275
3276 ////////////////////////////////////////////////////////////////////
3277 //80008A60
3278 ////////////////////////////////////////////////////////////////////
3279 void _SetGsCrt3(short arg0, short arg1, short arg2)
3280 {
3281 __printf("_SetGsCrt3 unimplemented\n");
3282 }
3283
3284 ////////////////////////////////////////////////////////////////////
3285 //80009CE0
3286 ////////////////////////////////////////////////////////////////////
3287 void _SetGsCrt4(short arg0, short arg1, short arg2)
3288 {
3289 __printf("_SetGsCrt4 unimplemented\n");
3290 }
3291
3292 ////////////////////////////////////////////////////////////////////
3293 //8000A060 SYSCALL 002 SetGsCrt
3294 ////////////////////////////////////////////////////////////////////
3295 void _SetGsCrt(short arg0, short arg1, short arg2)
3296 {
3297 u64 val, val2;
3298 u64 tmp;
3299 int count;
3300
3301 if (arg1 == 0) {
3302 tmp = (hvParam >> 3) & 0x7;
3303 tmp^= 0x2;
3304 if (tmp == 0) arg1 = 3;
3305 else arg1 = 2;
3306 }
3307
3308 for (count=0x270f; count >= 0; count--) {
3309 __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\n");
3310 }
3311
3312 *(int*)0x8001F344 = 0;
3313
3314 if (arg1 == 2) {
3315 if (arg0 != 0) {
3316 val = 0x740834504LL;
3317 val2 = 0x740814504LL;
3318
3319 tmp = (hvParam & 0x1) << 25;
3320 val|= tmp;
3321 val2|= tmp;
3322
3323 GS_SMODE1 = val;
3324 GS_SYNCH1 = 0x7F5B61F06F040LL;
3325 GS_SYNCH2 = 0x33A4D8;
3326 GS_SYNCV = 0xC7800601A01801LL;
3327
3328 GS_SMODE2 = (arg2 << 1) | 1;
3329 GS_SRFSH = 8;
3330 GS_SMODE1 = val2;
3331 } else {
3332 val = 0x740834504LL;
3333 val2 = 0x740814504LL;
3334
3335 tmp = (hvParam & 0x2) << 35;
3336 val|= tmp;
3337 val2|= tmp;
3338
3339 tmp = (hvParam & 0x1) << 25;
3340 val|= tmp;
3341 val2|= tmp;
3342
3343 GS_SMODE1 = val;
3344 GS_SYNCH1 = 0x7F5B61F06F040LL;
3345 GS_SYNCH2 = 0x33A4D8;
3346 GS_SYNCV = 0xC7800601A01802LL;
3347 GS_SMODE2 = 0;
3348 GS_SRFSH = 8;
3349 GS_SMODE1 = val2;
3350 }
3351 _SetGsCrt2();
3352 return;
3353 }
3354
3355 if (arg1 == 3) {
3356 if (arg0 != 0) {
3357 val = 0x740836504LL;
3358 val2 = 0x740816504LL;
3359
3360 tmp = (hvParam & 0x1) << 25;
3361 val|= tmp;
3362 val2|= tmp;
3363
3364 GS_SMODE1 = val;
3365 GS_SYNCH1 = 0x7F5C21FC83030LL;
3366 GS_SYNCH2 = 0x3484BC;
3367 GS_SYNCV = 0xA9000502101401LL;
3368
3369 GS_SMODE2 = (arg2 << 1) | 1;
3370 GS_SRFSH = 8;
3371 GS_SMODE1 = val2;
3372 } else {
3373 val = 0x740836504LL;
3374 val2 = 0x740816504LL;
3375
3376 tmp = (hvParam & 0x2) << 35;
3377 val|= tmp;
3378 val2|= tmp;
3379
3380 tmp = (hvParam & 0x1) << 25;
3381 val|= tmp;
3382 val2|= tmp;
3383
3384 GS_SMODE1 = val;
3385 GS_SYNCH1 = 0x7F5C21F683030LL;
3386 GS_SYNCH2 = 0x3484BC;
3387 GS_SYNCV = 0xA9000502101404LL;
3388 GS_SMODE2 = 0;
3389 GS_SRFSH = 8;
3390 GS_SMODE1 = val2;
3391 }
3392 _SetGsCrt2();
3393 return;
3394 }
3395
3396 if (arg1 == 0x72) {
3397 if (arg0 != 0) {
3398 val = 0x740814504LL;
3399 val|= (hvParam & 0x1) << 25;
3400
3401 GS_SYNCH1 = 0x7F5B61F06F040LL;
3402 GS_SYNCH2 = 0x33A4D8;
3403 GS_SYNCV = 0xC7800601A01801LL;
3404
3405 GS_SMODE2 = (arg2 << 1) | 1;
3406 GS_SRFSH = 8;
3407 GS_SMODE1 = val;
3408 } else {
3409 val = 0x740814504LL;
3410
3411 val|= (hvParam & 0x2) << 35;
3412 val|= (hvParam & 0x1) << 25;
3413
3414 GS_SYNCH1 = 0x7F5B61F06F040LL;
3415 GS_SYNCH2 = 0x33A4D8;
3416 GS_SYNCV = 0xC7800601A01802LL;
3417 GS_SMODE2 = 0;
3418 GS_SRFSH = 8;
3419 GS_SMODE1 = val;
3420 }
3421 return;
3422 }
3423
3424 if (arg1 == 0x73) {
3425 if (arg0 != 0) {
3426 val = 0x740816504LL;
3427 val|= (hvParam & 0x1) << 25;
3428
3429 GS_SYNCH1 = 0x7F5C21FC83030LL;
3430 GS_SYNCH2 = 0x3484BC;
3431 GS_SYNCV = 0xA9000502101401LL;
3432
3433 GS_SMODE2 = (arg2 << 1) | 1;
3434 GS_SRFSH = 8;
3435 GS_SMODE1 = val;
3436 } else {
3437 val = 0x740816504;
3438
3439 val|= (hvParam & 0x2) << 35;
3440 val|= (hvParam & 0x1) << 25;
3441
3442 GS_SYNCH1 = 0x7F5C21FC83030LL;
3443 GS_SYNCH2 = 0x3484BC;
3444 GS_SYNCV = 0xA9000502101404LL;
3445 GS_SMODE2 = 0;
3446 GS_SRFSH = 8;
3447 GS_SMODE1 = val;
3448 }
3449 return;
3450 }
3451
3452 if ((u32)(arg1 - 26) >= 0x38) {
3453 _SetGsCrt3(arg0, arg1, arg2); return;
3454 }
3455
3456 if (arg1 == 0x52) {
3457 _SetGsCrt3(arg0, arg1, arg2); return;
3458 }
3459
3460 _SetGsCrt4(arg0, arg1, arg2);
3461 }
3462
3463 ////////////////////////////////////////////////////////////////////
3464 //8000A768 SYSCALL 076 GetGsHParam
3465 ////////////////////////////////////////////////////////////////////
3466 void _GetGsHParam(int *p0, int *p1, int *p2, int *p3)
3467 {
3468 u32 _hvParam = (u32)hvParam;
3469
3470 *p0 = _hvParam >> 12;
3471 *p1 = _hvParam >> 24;
3472 *p2 = _hvParam >> 18;
3473 *p3 = _hvParam >> 28;
3474 }
3475
3476 ////////////////////////////////////////////////////////////////////
3477 //8000A7D0 SYSCALL 077 GetGsVParam
3478 ////////////////////////////////////////////////////////////////////
3479 int _GetGsVParam()
3480 {
3481 return hvParam & 0x3;
3482 }
3483
3484 ////////////////////////////////////////////////////////////////////
3485 //8000A800 SYSCALL 059 JoinThread
3486 ////////////////////////////////////////////////////////////////////
3487 void _JoinThread()
3488 {
3489 _iJoinThread(0x87);
3490 }
3491
3492 ////////////////////////////////////////////////////////////////////
3493 //8000A820 SYSCALL 078 SetGsHParam
3494 ////////////////////////////////////////////////////////////////////
3495 void _SetGsHParam(int a0, int a1, int a2, int a3)
3496 {
3497 __printf("SetGsHParam(%x,%x,%x,%x)... probably will never be supported\n", a0, a1, a2, a3);
3498 //write hvParam&1 to 12000010?
3499 }
3500
3501 ////////////////////////////////////////////////////////////////////
3502 //8000A8F8 SYSCALL 079 SetGsVParam
3503 ////////////////////////////////////////////////////////////////////
3504 void _SetGsVParam(int VParam)
3505 {
3506 hvParam&= ~0x1;
3507 hvParam|= VParam & 0x1;
3508 }
3509
3510 ////////////////////////////////////////////////////////////////////
3511 //8000A920 SYSCALL 075 GetOsdConfigParam
3512 ////////////////////////////////////////////////////////////////////
3513 void _GetOsdConfigParam(int *result)
3514 {
3515 *result= (*result & 0xFFFFFFFE) | (osdConfigParam & 1);
3516 *result= (*result & 0xFFFFFFF9) | (osdConfigParam & 6);
3517 *result= (*result & 0xFFFFFFF7) | (osdConfigParam & 8);
3518 *result= (*result & 0xFFFFFFEF) | (osdConfigParam & 0x10);
3519 *result=((*result & 0xFFFFE01F) | (osdConfigParam & 0x1FE0)) & 0xFFFF1FFF;
3520 ((u16*)result)[1]=((u16*)&osdConfigParam)[1];
3521 }
3522
3523 ////////////////////////////////////////////////////////////////////
3524 //8000A9C0 SYSCALL 074 SetOsdConfigParam
3525 ////////////////////////////////////////////////////////////////////
3526 void _SetOsdConfigParam(int *param)
3527 {
3528 osdConfigParam= (osdConfigParam & 0xFFFFFFFE) | (*param & 1);
3529 osdConfigParam= (osdConfigParam & 0xFFFFFFF9) | (*param & 6);
3530 osdConfigParam= (osdConfigParam & 0xFFFFFFF7) | (*param & 8);
3531 osdConfigParam= (osdConfigParam & 0xFFFFFFEF) | (*param & 0x10);
3532 osdConfigParam=((osdConfigParam & 0xFFFFE01F) | (*param & 0x1FE0)) & 0xFFFF1FFF;
3533 ((u16*)&osdConfigParam)[1]=((u16*)param)[1];
3534 }
3535
3536 ////////////////////////////////////////////////////////////////////
3537 //8000FCE8
3538 ////////////////////////////////////////////////////////////////////
3539 void __exhandler(int a0)
3540 {
3541 }
3542
3543 ////////////////////////////////////////////////////////////////////
3544 //80010F34
3545 ////////////////////////////////////////////////////////////////////
3546 void __disableInterrupts()
3547 {
3548 __asm__("mtc0 $0, $25\n"
3549 "mtc0 $0, $24\n"
3550 "li $3, 0xFFFFFFE0\n"
3551 "mfc0 $2, $12\n"
3552 "and $2, $3\n"
3553 "mtc0 $2, $12\n"
3554 "sync\n");
3555 }
3556
3557 ////////////////////////////////////////////////////////////////////
3558 //80010F58
3559 ////////////////////////////////////////////////////////////////////
3560 void kSaveContext()
3561 {
3562 }
3563
3564 ////////////////////////////////////////////////////////////////////
3565 //80011030
3566 ////////////////////////////////////////////////////////////////////
3567 void kLoadContext()
3568 {
3569 }
3570
3571 ////////////////////////////////////////////////////////////////////
3572 //800110F4
3573 ////////////////////////////////////////////////////////////////////
3574 void kLoadDebug()
3575 {
3576 kLoadContext();
3577 // lq $31, 0x1F0($27)
3578 // lq $27, 0x1B0($27)
3579 // j 80005020 - probably load debug services or restore prev program state
3580 }
3581
3582 ////////////////////////////////////////////////////////////////////
3583 //80011108
3584 ////////////////////////////////////////////////////////////////////
3585 int __exception()
3586 {
3587 register u32 curepc __asm__("$2");
3588 int ret;
3589
3590 __asm__("mfc0 %0, $14\n" : "=r"(curepc) : );
3591
3592 // check if epc is currently in the except handlers:
3593 // _Deci2Handler, __exception1, and __exception
3594 if (curepc >= (u32)__exception && curepc < (u32)__exception+0x300) {
3595 __asm__("mfc0 %0, $13\n" : "=r"(ret) : );
3596 return (ret & 0x7C) >> 2;
3597 }
3598
3599 kSaveContext();
3600
3601 __disableInterrupts();
3602 __exhandler(1);
3603
3604 kLoadContext();
3605
3606 __asm__("eret\n");
3607 }
3608
3609 ////////////////////////////////////////////////////////////////////
3610 //800111F0
3611 ////////////////////////////////////////////////////////////////////
3612 void __exception1()
3613 {
3614 kSaveContext();
3615 __disableInterrupts();
3616 //sub_8000CF68
3617 kLoadContext();
3618 __asm__("eret\n");
3619 }

  ViewVC Help
Powered by ViewVC 1.1.22