//[module] KERNEL //[processor] EE //[type] RAW //[size] 80880(0x13BF0) //[bios] 10000(0xB3200-0xC6DF0) //[iopboot] NA //[loaded @] 80000000 //[name] NA //[version] NA //[memory map] [too many, see mem.txt] //[handlers] //[entry point] ENTRYPOINT @ 0x80001000 //[made by] [RO]man, zerofrog & others #include #include #include "eekernel.h" #include "eeinit.h" #include "eedebug.h" #include "romdir.h" #define PS2_LOADADDR 0x82000 // internal functions int InitPgifHandler(); int InitPgifHandler2(); struct ll* LL_unlink(struct ll *l); struct ll* LL_rotate(struct ll *l); struct ll *LL_unlinkthis(struct ll *l); void LL_add(struct ll *l, struct ll *new); extern int (*table_GetCop0[32])(int reg); // 124E8-12564 extern int (*table_SetCop0[32])(int reg, int val); // 12568-125E4 void DefaultCPUTimerHandler(); void _excepRet(u32 eretpc, u32 v1, u32 a, u32 a1, u32 a2); int __ExitThread(); int __ExitDeleteThread(); int __SleepThread(); int _iWaitSema(int sid); void saveContext(); void restoreContext(); int _SemasInit(); void _ThreadHandler(u32 epc, u32 stack); void _ChangeThread(u32 entry, u32 stack_res, int waitSema); int __DeleteThread(int tid); int __StartThread(int tid, void *arg); int __load_module(char *name, void (*entry)(void*), void *stack_res, int prio); void* __ExecPS2(void * entry, void * gp, int argc, char ** argv); void releaseTCB(int tid); void unsetTCB(int tid); void thread_2_ready(int tid); void FlushInstructionCache(); void FlushDataCache(); void FlushSecondaryCache(); void SifDmaInit(); u32 excepRetPc=0;//124E4 int threadId=0; // 125EC int threadPrio=0; // 125F0 int threadStatus=0; // 125F4 char threadArgStrBuffer[256]; // 12608 u64 hvParam; u32 machineType; u64 gsIMR; u32 memorySize; u8 g_kernelstack[0x2000] __attribute((aligned(128))); u32 g_kernelstackend; // hopefully this is right after g_kernelstack int _HandlersCount; int VSyncFlag0; int VSyncFlag1; struct ll handler_ll_free, *ihandlers_last=NULL, *ihandlers_first=NULL; struct HCinfo intcs_array[14]; struct ll *dhandlers_last=NULL, *dhandlers_first=NULL; struct HCinfo dmacs_array[15]; struct IDhandl pgifhandlers_array[161]; void (*sbus_handlers[32])(int ca); void (*CPUTimerHandler)() = DefaultCPUTimerHandler; //12480 u64 _alarm_unk = 0; u64 rcnt3Valid=0;//16A68 int rcnt3Count = 0; //16A70 u32 dword_80016A78, dword_80016A7C, dword_80016A84, dword_80016A88; //u32 rcnt3gp; //16A80 //u32 rcnt3Mode; //16A84 int rcnt3TargetTable[0x142]={0};//16A80 u8 rcnt3TargetNum[0x40];//16F78 int threads_count=0; u32 excepRA=0;//16FC0 u32 excepSP=0;//16FD0 struct ll thread_ll_free; struct ll thread_ll_priorities[128]; int semas_count=0; struct kSema* semas_last=0; struct TCB threads_array[256]; struct kSema semas_array[256]; char tagindex=0;//1E104 short transferscount=0;//1E106 struct TAG tadrptr[31] __attribute((aligned(16)));//1E140 int extrastorage[(16/4) * 8][31] __attribute((aligned(16)));//1E340 int osdConfigParam;//1F340 u32 sifEEbuff[32] __attribute((aligned(16))); u32 sifRegs[32] __attribute((aligned(16))); u32 sifIOPbuff; u32 sif1tagdata; void _eret() { __asm__("mfc0 $26, $12\n" "ori $26, 0x13\n" "mtc0 $26, $12\n" "sync\n" "eret\n" "nop\n"); } #define eret() __asm__("j _eret\nnop\n"); //////////////////////////////////////////////////////////////////// //800006C0 SYSCALL 116 RFU116_SetSYSCALL //////////////////////////////////////////////////////////////////// void _SetSYSCALL(int num, int address) { table_SYSCALL[num] = (void (*)())address; } //////////////////////////////////////////////////////////////////// //80000740 SYSCALL 114 SetPgifHandler //////////////////////////////////////////////////////////////////// void _SetPgifHandler(void (*handler)(int)) { INTCTable[15] = handler; } //////////////////////////////////////////////////////////////////// //800007C0 SYSCALL 108 SetCPUTimerHandler //////////////////////////////////////////////////////////////////// void _SetCPUTimerHandler(void (*handler)()) { CPUTimerHandler = handler; } //////////////////////////////////////////////////////////////////// //80000800 SYSCALL 109 SetCPUTimer //////////////////////////////////////////////////////////////////// void _SetCPUTimer(int compval) { if( compval < 0 ) { u32 status; __asm__("mfc0 %0, $12\n" : "=r"(status) : ); __asm__("mtc0 %0, $12\n" "mtc0 $0, $9\n" : : "r"(status|0x18001)); } else if( compval == 0 ) { u32 compare, status; __asm__("mfc0 %0, $12\n" "mfc0 %1, $11\n" : "=r"(status), "=r"(compare) : ); __asm__("mtc0 %0, $12\n" "mtc0 $0, $9\n" "mtc0 %1, $11\n" : : "r"(status&~0x8000), "r"(compare) ); } else { __asm__("mtc0 $0, $9\n" // count "mtc0 %0, $11\n" // compare : : "r"(compval)); } } //////////////////////////////////////////////////////////////////// //800008C0 SYSCALL 020 EnableIntc //////////////////////////////////////////////////////////////////// int __EnableIntc(int ch) { int intbit; intbit = 0x1 << ch; if ((INTC_MASK & intbit) != 0) return 0; INTC_MASK = intbit; return 1; } //////////////////////////////////////////////////////////////////// //80000900 SYSCALL 021 DisableIntc //////////////////////////////////////////////////////////////////// int __DisableIntc(int ch) { int intbit; intbit = 0x1 << ch; if ((INTC_MASK & intbit) == 0) return 0; INTC_MASK = intbit; return 1; } //////////////////////////////////////////////////////////////////// //80000940 SYSCALL 022 EnableDmac //////////////////////////////////////////////////////////////////// int __EnableDmac(int ch) { int dmabit; dmabit = 0x10000 << ch; if ((DMAC_STAT & dmabit) != 0) return 0; DMAC_STAT = dmabit; return 1; } //////////////////////////////////////////////////////////////////// //80000980 SYSCALL 023 DisableDmac //////////////////////////////////////////////////////////////////// int __DisableDmac(int ch) { int dmabit; dmabit = 0x10000 << ch; if ((DMAC_STAT & dmabit) == 0) return 0; DMAC_STAT = dmabit; return 1; } //////////////////////////////////////////////////////////////////// //800009C0 SYSCALL 013 SetVTLBRefillHandler //////////////////////////////////////////////////////////////////// void* _SetVTLBRefillHandler(int cause, void (*handler)()) { if ((cause-1) >= 3) return 0; VCRTable[cause] = handler; return handler; } //////////////////////////////////////////////////////////////////// //80000A00 SYSCALL 014 SetVCommonHandler //////////////////////////////////////////////////////////////////// void* _SetVCommonHandler(int cause, void (*handler)()) { if ((cause-4) >= 10) return 0; VCRTable[cause] = handler; return handler; } //////////////////////////////////////////////////////////////////// //80000A40 SYSCALL 015 SetVInterruptHandler //////////////////////////////////////////////////////////////////// void* _SetVInterruptHandler(int cause, void (*handler)()) { if (cause >= 8) return 0; VIntTable[cause] = handler; // no return value... } //////////////////////////////////////////////////////////////////// //80000A80 SYSCALL 102,106 CpuConfig //////////////////////////////////////////////////////////////////// u32 _CpuConfig(u32 op) { u32 cfg; __asm__("mfc0 %0, $16\n" : "=r"(cfg) : ); return table_CpuConfig[op](cfg); } //////////////////////////////////////////////////////////////////// //80000AB8 //////////////////////////////////////////////////////////////////// u32 _CpuConfig_0(u32 cfg) { cfg |= 0x40000; __asm__("mtc0 %0, $16\n" "sync\n": : "r"(cfg)); return cfg; } //////////////////////////////////////////////////////////////////// //80000AD0 //////////////////////////////////////////////////////////////////// u32 _CpuConfig_1(u32 cfg) { cfg |= 0x2000; __asm__("mtc0 %0, $16\n" "sync\n": : "r"(cfg)); return cfg; } //////////////////////////////////////////////////////////////////// //80000AEC //////////////////////////////////////////////////////////////////// u32 _CpuConfig_2(u32 cfg) { cfg |= 0x1000; __asm__("mtc0 %0, $16\n" "sync\n": : "r"(cfg)); return cfg; } //////////////////////////////////////////////////////////////////// //80000B04 //////////////////////////////////////////////////////////////////// u32 _CpuConfig_3(u32 cfg) { cfg &= ~0x40000; __asm__("mtc0 %0, $16\n" "sync\n": : "r"(cfg)); return cfg; } //////////////////////////////////////////////////////////////////// //80000B20 //////////////////////////////////////////////////////////////////// u32 _CpuConfig_4(u32 cfg) { cfg &= ~0x2000; __asm__("mtc0 %0, $16\n" "sync\n": : "r"(cfg)); return cfg; } //////////////////////////////////////////////////////////////////// //80000B40 //////////////////////////////////////////////////////////////////// u32 _CpuConfig_5(u32 cfg) { cfg &= ~0x1000; __asm__("mtc0 %0, $16\n" "sync\n": : "r"(cfg)); return cfg; } //////////////////////////////////////////////////////////////////// //80000B80 SYSCALL 125 PSMode //////////////////////////////////////////////////////////////////// void _PSMode() { machineType|= 0x8000; } //////////////////////////////////////////////////////////////////// //80000BC0 SYSCALL 126 MachineType //////////////////////////////////////////////////////////////////// u32 _MachineType() { return machineType; } //////////////////////////////////////////////////////////////////// //80000C00 //////////////////////////////////////////////////////////////////// u32 _SetMemorySize(u32 size) { memorySize = size; return size; } //////////////////////////////////////////////////////////////////// //80000C40 SYSCALL 127 GetMemorySize //////////////////////////////////////////////////////////////////// u32 _GetMemorySize() { return memorySize; } //////////////////////////////////////////////////////////////////// //80000D00 SYSCALL 112 GsGetIMR //////////////////////////////////////////////////////////////////// u64 _GsGetIMR() { return gsIMR; } //////////////////////////////////////////////////////////////////// //80000D40 SYSCALL 113 GsPutIMR //////////////////////////////////////////////////////////////////// u64 _GsPutIMR(u64 val) { GS_IMR = val; gsIMR = val; return val; } //////////////////////////////////////////////////////////////////// //80000D80 SYSCALL 002 Exit //////////////////////////////////////////////////////////////////// int _Exit() { return _RFU004_Exit(); } //////////////////////////////////////////////////////////////////// //80001000 ENTRYPOINT //////////////////////////////////////////////////////////////////// void __attribute__((noreturn)) _start() { __asm__("lui $sp, %hi(g_kernelstackend)\n" "addiu $sp, %lo(g_kernelstackend)\n"); __puts("EEKERNEL start\n"); memorySize = 32*1024*1024; machineType = 0; //memorySize = *(int*)0x70003FF0; //machineType = machine_type; __printf("TlbInit\n"); TlbInit(); __printf("InitPgifHandler\n"); InitPgifHandler(); __printf("Initialize\n"); Initialize(); // __load_module_EENULL(); __asm__ ( "li $26, %0\n" "lw $26, 0($26)\n" "mtc0 $26, $12\n" "li $26, %1\n" "lw $26, 0($26)\n" "mtc0 $26, $16\n" : : "i"(SRInitVal), "i"(ConfigInitVal) ); // ee_deci2_manager_init(); SifDmaInit(); // __init_unk(0x81FE0); SetVSyncFlag(0, 0); // call directly instread of loading module, might need to // set thread0 as used since soem code assumes thread 0 is always // main thread //eeload_start(); //launch_thread(__load_module("EELOAD", 0x82000, 0x81000, 0)); for (;;); } //////////////////////////////////////////////////////////////////// //80001300 //////////////////////////////////////////////////////////////////// void saveContext2() { __asm__ ( ".set noat\n" "lui $26, %hi(SavedRegs)\n" "sq $2, %lo(SavedRegs+0x000)($26)\n" "sq $3, %lo(SavedRegs+0x010)($26)\n" "sq $4, %lo(SavedRegs+0x020)($26)\n" "sq $5, %lo(SavedRegs+0x030)($26)\n" "sq $6, %lo(SavedRegs+0x040)($26)\n" "sq $7, %lo(SavedRegs+0x050)($26)\n" "sq $8, %lo(SavedRegs+0x060)($26)\n" "sq $9, %lo(SavedRegs+0x070)($26)\n" "sq $10, %lo(SavedRegs+0x080)($26)\n" "sq $11, %lo(SavedRegs+0x090)($26)\n" "sq $12, %lo(SavedRegs+0x0A0)($26)\n" "sq $13, %lo(SavedRegs+0x0B0)($26)\n" "sq $14, %lo(SavedRegs+0x0C0)($26)\n" "sq $15, %lo(SavedRegs+0x0D0)($26)\n" "sq $16, %lo(SavedRegs+0x0E0)($26)\n" "sq $17, %lo(SavedRegs+0x0F0)($26)\n" "sq $18, %lo(SavedRegs+0x100)($26)\n" "sq $19, %lo(SavedRegs+0x110)($26)\n" "sq $20, %lo(SavedRegs+0x120)($26)\n" "sq $21, %lo(SavedRegs+0x130)($26)\n" "sq $22, %lo(SavedRegs+0x140)($26)\n" "sq $23, %lo(SavedRegs+0x150)($26)\n" "sq $24, %lo(SavedRegs+0x160)($26)\n" "sq $25, %lo(SavedRegs+0x170)($26)\n" "sq $gp, %lo(SavedRegs+0x180)($26)\n" "sq $fp, %lo(SavedRegs+0x190)($26)\n" "mfhi $2\n" "sd $2, %lo(SavedRegs+0x1A0)($26)\n" "mfhi1 $2\n" "sd $2, %lo(SavedRegs+0x1A8)($26)\n" "mflo $2\n" "sd $2, %lo(SavedRegs+0x1B0)($26)\n" "mflo1 $2\n" "sd $2, %lo(SavedRegs+0x1B8)($26)\n" "mfsa $2\n" "sd $2, %lo(SavedRegs+0x1C0)($26)\n" "jr $31\n" "nop\n" ".set at\n" ); } //////////////////////////////////////////////////////////////////// //800013C0 //////////////////////////////////////////////////////////////////// void restoreContext2() { __asm__ ( ".set noat\n" "lui $26, %hi(SavedRegs)\n" "lq $2, %lo(SavedRegs+0x000)($26)\n" "lq $3, %lo(SavedRegs+0x010)($26)\n" "lq $4, %lo(SavedRegs+0x020)($26)\n" "lq $5, %lo(SavedRegs+0x030)($26)\n" "lq $6, %lo(SavedRegs+0x040)($26)\n" "lq $7, %lo(SavedRegs+0x050)($26)\n" "lq $8, %lo(SavedRegs+0x060)($26)\n" "lq $9, %lo(SavedRegs+0x070)($26)\n" "lq $10, %lo(SavedRegs+0x080)($26)\n" "lq $11, %lo(SavedRegs+0x090)($26)\n" "lq $12, %lo(SavedRegs+0x0A0)($26)\n" "lq $13, %lo(SavedRegs+0x0B0)($26)\n" "lq $14, %lo(SavedRegs+0x0C0)($26)\n" "lq $15, %lo(SavedRegs+0x0D0)($26)\n" "lq $16, %lo(SavedRegs+0x0E0)($26)\n" "lq $17, %lo(SavedRegs+0x0F0)($26)\n" "lq $18, %lo(SavedRegs+0x100)($26)\n" "lq $19, %lo(SavedRegs+0x110)($26)\n" "lq $20, %lo(SavedRegs+0x120)($26)\n" "lq $21, %lo(SavedRegs+0x130)($26)\n" "lq $22, %lo(SavedRegs+0x140)($26)\n" "lq $23, %lo(SavedRegs+0x150)($26)\n" "lq $24, %lo(SavedRegs+0x160)($26)\n" "lq $25, %lo(SavedRegs+0x170)($26)\n" "lq $gp, %lo(SavedRegs+0x180)($26)\n" "lq $fp, %lo(SavedRegs+0x190)($26)\n" "ld $1, %lo(SavedRegs+0x1A0)($26)\n" "mthi $1\n" "ld $1, %lo(SavedRegs+0x1A8)($26)\n" "mthi1 $1\n" "ld $1, %lo(SavedRegs+0x1B0)($26)\n" "mtlo $1\n" "ld $1, %lo(SavedRegs+0x1B8)($26)\n" "mtlo1 $1\n" "ld $1, %lo(SavedRegs+0x1C0)($26)\n" "mtsa $1\n" "jr $31\n" "nop\n" ".set at\n" ); } //////////////////////////////////////////////////////////////////// //80001460 //////////////////////////////////////////////////////////////////// void erase_cpu_regs() { __asm__( ".set noat\n" "padduw $1, $0, $0\n" "padduw $2, $0, $0\n" "padduw $3, $0, $0\n" "padduw $4, $0, $0\n" "padduw $5, $0, $0\n" "padduw $6, $0, $0\n" "padduw $7, $0, $0\n" "padduw $8, $0, $0\n" "padduw $9, $0, $0\n" "padduw $10, $0, $0\n" "padduw $11, $0, $0\n" "padduw $12, $0, $0\n" "padduw $13, $0, $0\n" "padduw $14, $0, $0\n" "padduw $15, $0, $0\n" "padduw $16, $0, $0\n" "padduw $17, $0, $0\n" "padduw $18, $0, $0\n" "padduw $19, $0, $0\n" "padduw $20, $0, $0\n" "padduw $21, $0, $0\n" "padduw $22, $0, $0\n" "padduw $23, $0, $0\n" "padduw $24, $0, $0\n" "padduw $25, $0, $0\n" "padduw $gp, $0, $0\n" "jr $31\n" "padduw $fp, $0, $0\n" ".set at\n" ); } //////////////////////////////////////////////////////////////////// //800014D8 dummy intc handler //////////////////////////////////////////////////////////////////// void _DummyINTCHandler(int n) { __printf("# INT: INTC (%d)\n", n); while(1) { __asm__ ("nop\nnop\nnop\nnop\n"); } } //////////////////////////////////////////////////////////////////// //80001508 dummy dmac handler //////////////////////////////////////////////////////////////////// void _DummyDMACHandler(int n) { __printf("# INT: DMAC (%d)\n", n); while(1) { __asm__ ("nop\nnop\nnop\nnop\n"); } } //////////////////////////////////////////////////////////////////// //80001508 //////////////////////////////////////////////////////////////////// void DefaultCPUTimerHandler() { __printf("# INT: CPU Timer\n"); } //////////////////////////////////////////////////////////////////// //80001564 SYSCALL 000 RFU000_FullReset //80001564 SYSCALL 003 RFU003 (also) //80001564 SYSCALL 008 RFU008 (too) //////////////////////////////////////////////////////////////////// void _RFU___() { register int syscnum __asm__("$3"); __printf("# Syscall: undefined (%d)\n", syscnum>>2); } //////////////////////////////////////////////////////////////////// //80001588 //////////////////////////////////////////////////////////////////// void _SetVSyncFlag(int flag0, int flag1) { VSyncFlag0 = flag0; VSyncFlag1 = flag1; } //////////////////////////////////////////////////////////////////// //800015A0 //////////////////////////////////////////////////////////////////// struct ll* _AddHandler() { struct ll *l; l = LL_unlink(&handler_ll_free); if (l == NULL) return NULL; _HandlersCount++; return l; } //////////////////////////////////////////////////////////////////// //800015E8 //////////////////////////////////////////////////////////////////// void _RemoveHandler(int n) { LL_add(&handler_ll_free, (struct ll*)&pgifhandlers_array[n]); _HandlersCount--; } //////////////////////////////////////////////////////////////////// //80001630 //////////////////////////////////////////////////////////////////// void DefaultINTCHandler(int n) { //TODO } //////////////////////////////////////////////////////////////////// //80001798 //////////////////////////////////////////////////////////////////// void DefaultDMACHandler(int n) { //TODO } //////////////////////////////////////////////////////////////////// //800018B0 //////////////////////////////////////////////////////////////////// int __AddIntcHandler(int cause, int (*handler)(int), int next, void *arg, int flag) { struct IDhandl *idh; if ((flag != 0) && (cause == INTC_SBUS)) return -1; if (cause >= 15) return -1; idh = (struct IDhandl *)_AddHandler(); if (idh == 0) return -1; idh->handler = handler; __asm__ ("sw $gp, %0\n" : "=m"(idh->gp) : ); idh->arg = arg; idh->flag = flag; if (next==-1) //register_last LL_add(&ihandlers_last[cause*12], (struct ll*)idh); else if (next==0) //register_first LL_add(&ihandlers_first[cause*12], (struct ll*)idh); else{ if (next>128) return -1; if (pgifhandlers_array[next].flag==3) return -1; LL_add((struct ll*)&pgifhandlers_array[next], (struct ll*)idh); } intcs_array[cause].count++; return (((u32)idh-(u32)&pgifhandlers_array) * 0xAAAAAAAB) / 8; } //////////////////////////////////////////////////////////////////// //80001A30 SYSCALL 016 AddIntcHandler //////////////////////////////////////////////////////////////////// int _AddIntcHandler(int cause, int (*handler)(int), int next, void *arg) { __AddIntcHandler(cause, handler, next, arg, 2); } //////////////////////////////////////////////////////////////////// //80001A50 //////////////////////////////////////////////////////////////////// int _AddIntcHandler2(int cause, int (*handler)(int), int next, void *arg) { __AddIntcHandler(cause, handler, next, arg, 0); } //////////////////////////////////////////////////////////////////// //80001AC8 SYSCALL 017 RemoveIntcHandler //////////////////////////////////////////////////////////////////// int _RemoveIntcHandler(int cause, int hid) { if (hid >= 128) return -1; if (pgifhandlers_array[hid].flag == 3) return -1; pgifhandlers_array[hid].flag = 3; pgifhandlers_array[hid].handler = 0; LL_unlinkthis((struct ll*)&pgifhandlers_array[hid]); _RemoveHandler(hid); intcs_array[cause].count--; } //////////////////////////////////////////////////////////////////// //80001B10 //////////////////////////////////////////////////////////////////// int __AddDmacHandler(int cause, int (*handler)(int), int next, void *arg, int flag) { struct IDhandl *idh; register int temp; if (cause >= 16) return -1; idh = (struct IDhandl *)_AddHandler(); if (idh == 0) return -1; idh->handler = handler; __asm__ ("sw $gp, %0\n" : "=m"(idh->gp) : ); idh->arg = arg; idh->flag = flag; if (next==-1) //register_last LL_add(&dhandlers_last[cause*12], (struct ll*)idh); else if (next==0) //register_first LL_add(&dhandlers_first[cause*12], (struct ll*)idh); else{ if (next>128) return -1; if (pgifhandlers_array[next].flag==3) return -1; LL_add((struct ll*)&pgifhandlers_array[next], (struct ll*)idh); } dmacs_array[cause].count++; return (((u32)idh-(u32)&pgifhandlers_array) * 0xAAAAAAAB) / 8; } //////////////////////////////////////////////////////////////////// //80001C78 SYSCALL 018 AddDmacHandler //////////////////////////////////////////////////////////////////// int _AddDmacHandler(int cause, int (*handler)(int), int next, void *arg) { __AddDmacHandler(cause, handler, next, arg, 2); } //////////////////////////////////////////////////////////////////// //80001C98 //////////////////////////////////////////////////////////////////// int _AddDmacHandler2(int cause, int (*handler)(int), int next, void *arg) { __AddDmacHandler(cause, handler, next, arg, 0); } //////////////////////////////////////////////////////////////////// //80001CB8 SYSCALL 019 RemoveDmacHandler //////////////////////////////////////////////////////////////////// int _RemoveDmacHandler(int cause, int hid) { if (hid >= 128) return -1; if (pgifhandlers_array[hid].flag == 3) return -1; pgifhandlers_array[hid].flag = 3; pgifhandlers_array[hid].handler = 0; LL_unlinkthis((struct ll*)&pgifhandlers_array[hid]); _RemoveHandler(hid); dmacs_array[cause].count--; } //////////////////////////////////////////////////////////////////// //80001D58 //////////////////////////////////////////////////////////////////// void sbusHandler() { //TODO } //////////////////////////////////////////////////////////////////// //80001E38 //////////////////////////////////////////////////////////////////// int __AddSbusIntcHandler(int cause, void (*handler)(int ca)) { if (cause >= 32) return -1; if (sbus_handlers[cause] != 0) return -1; sbus_handlers[cause] = handler; return cause; } //////////////////////////////////////////////////////////////////// //80001E78 SYSCALL 010 AddSbusIntcHandler //////////////////////////////////////////////////////////////////// int _AddSbusIntcHandler(int cause, void (*handler)(int ca)) { if (cause < 16) return __AddSbusIntcHandler(cause, handler); return -1; } //////////////////////////////////////////////////////////////////// //80001EA8 //////////////////////////////////////////////////////////////////// int __RemoveSbusIntcHandler(int cause) { if (cause >= 32) return -1; sbus_handlers[cause] = 0; return cause; } //////////////////////////////////////////////////////////////////// //80001ED0 SYSCALL 011 RemoveSbusIntcHandler //////////////////////////////////////////////////////////////////// int _RemoveSbusIntcHandler(int cause) { if (cause < 16) return __RemoveSbusIntcHandler(cause); return -1; } //////////////////////////////////////////////////////////////////// //80001F00 //////////////////////////////////////////////////////////////////// int __Interrupt2Iop(int cause) { if (cause >= 32) { return -1; } SBUS_MSFLG = 1 << cause; SBUS_F240 = 0x100; SBUS_F240 = 0x100; SBUS_F240 = 0x100; SBUS_F240 = 0x100; SBUS_F240 = 0x100; SBUS_F240 = 0x100; SBUS_F240 = 0x100; SBUS_F240 = 0x100; // eight times SBUS_F240 = 0x40100; return cause; } //////////////////////////////////////////////////////////////////// //80001F70 SYSCALL 012 Interrupt2Iop //////////////////////////////////////////////////////////////////// int _Interrupt2Iop(int cause) { if (cause < 16) { return _Interrupt2Iop(cause); } else { return -1; } } //////////////////////////////////////////////////////////////////// //80001FA0 SYSCALL 092 EnableIntcHandler //////////////////////////////////////////////////////////////////// void _EnableIntcHandler(u32 id) { pgifhandlers_array[id].flag = 2; } //////////////////////////////////////////////////////////////////// //80001FA0 SYSCALL 093 DisableIntcHandler //////////////////////////////////////////////////////////////////// void _DisableIntcHandler(u32 id) { pgifhandlers_array[id].flag = 1; } //////////////////////////////////////////////////////////////////// //80001FA0 SYSCALL 094 EnableDmacHandler //////////////////////////////////////////////////////////////////// void _EnableDmacHandler(u32 id) { pgifhandlers_array[id].flag = 2; } //////////////////////////////////////////////////////////////////// //80001FA0 SYSCALL 095 DisableDmacHandler //////////////////////////////////////////////////////////////////// void _DisableDmacHandler(u32 id) { pgifhandlers_array[id].flag = 1; } //////////////////////////////////////////////////////////////////// //80002040 SYSCALL 083 iSetEventFlag //////////////////////////////////////////////////////////////////// int _iSetEventFlag(int ef, u32 bits) { return _HandlersCount; //? } //////////////////////////////////////////////////////////////////// //800022D8 SYSCALL 24,30 //////////////////////////////////////////////////////////////////// int _SetAlarm(short a0, int a1, int a2) { int mode = _alarm_unk & 0x1; int i; i = 0; while (mode) { mode = (_alarm_unk >> i++) & 0x1; if (i >= 64) { return -1; } } _alarm_unk|= mode << i; __asm__("move %0, $gp\n" : "=r"(rcnt3TargetTable[0]) : ); dword_80016A78 = a1; dword_80016A7C = a2; rcnt3TargetTable[1] = RCNT3_MODE; i = RCNT3_MODE + a0; if (i < -1) i&= 0xffff; dword_80016A88 = i; if (RCNT3_MODE < i) { if (rcnt3Count <= 0) { } } } //////////////////////////////////////////////////////////////////// //80002570 SYSCALL 25,31 ReleaseAlarm //////////////////////////////////////////////////////////////////// void _ReleaseAlarm() { //TODO } //////////////////////////////////////////////////////////////////// //80002650 //////////////////////////////////////////////////////////////////// void rcnt3Handler() { unsigned int i; u32* ptr; u32 storegp; u32 addr; if (rcnt3Count < 2) { RCNT3_MODE = 0x483; } else { RCNT3_MODE = 0x583; RCNT3_TARGET = rcnt3TargetTable[2+rcnt3TargetNum[1] * 5]; } for (;;) { u32 id = (u32)rcnt3TargetNum[0]; if (--rcnt3Count >= 0) { // shift one down for (i=0; i= 0) { if (addr != rcnt3TargetTable[rcnt3TargetNum[0] * 5 + 2]) { break; } } else break; } } //////////////////////////////////////////////////////////////////// //800027F8 SYSCALL 082 SetEventFlag //////////////////////////////////////////////////////////////////// int _SetEventFlag(int ef, u32 bits) { return rcnt3Count; //? } //////////////////////////////////////////////////////////////////// //800027F8 //////////////////////////////////////////////////////////////////// void _InitRCNT3() { int i; rcnt3Count = 0; rcnt3Valid = 0; _alarm_unk = 0; for (i=0; i<0x40; i++) rcnt3TargetNum[i] = 0; __EnableIntc(INTC_TIM3); } //////////////////////////////////////////////////////////////////// //80002840 //////////////////////////////////////////////////////////////////// void _excepRet(u32 eretpc, u32 v1, u32 a, u32 a1, u32 a2) { __asm__("sw $31, %0\n" "sw $sp, %1\n" : "=m"(excepRA), "=m"(excepSP) : ); __asm__("mtc0 $4, $14\n" "sync\n" "daddu $3, $5, $0\n" "daddu $4, $6, $0\n" "daddu $5, $7, $0\n" "daddu $6, $8, $0\n" "mfc0 $26, $12\n" "ori $26, 0x12\n" "mtc0 $26, $12\n" "sync\n" "eret\n" "nop\n"); } //////////////////////////////////////////////////////////////////// //80002880 SYSCALL 005 RFU005 //////////////////////////////////////////////////////////////////// void _RFU005() { __asm__ ( ".set noat\n" "mfc0 $26, $12\n" "ori $1, $0, 0xFFE4\n" "and $26, $1\n" "mtc0 $26, $12\n" "sync\n" "lw $ra, excepRA\n" "lw $sp, excepSP\n" "jr $ra\n" "nop\n" ".set at\n"); } //////////////////////////////////////////////////////////////////// //A00028C0 SYSCALL 097 EnableCache //////////////////////////////////////////////////////////////////// int _EnableCache(int cache) { u32 cfg; __asm__("mfc0 %0, $16\n" : "=r"(cfg) : ); cfg |= ((cache&3)<<16); __asm__("mtc0 %0, $16\n" "sync\n" : : "r"(cfg) ); } //////////////////////////////////////////////////////////////////// //A0002980 SYSCALL 098 DisableCache //////////////////////////////////////////////////////////////////// int _DisableCache(int cache) { u32 cfg; __asm__("mfc0 %0, $16\n" : "=r"(cfg) : ); cfg &= ~((cache&3)<<16); __asm__("mtc0 %0, $16\n" "sync\n" : : "r"(cfg) ); } //////////////////////////////////////////////////////////////////// //A0002A40 SYSCALL 100 FlushCache //////////////////////////////////////////////////////////////////// void _FlushCache(int op) { if( op == 0 ) FlushInstructionCache(); else if ( op == 1 ) FlushSecondaryCache(); else if( op == 2 ) FlushDataCache(); else { FlushSecondaryCache(); FlushDataCache(); } } //////////////////////////////////////////////////////////////////// //80002AC0 //////////////////////////////////////////////////////////////////// void FlushInstructionCache() { } //////////////////////////////////////////////////////////////////// //80002A80 //////////////////////////////////////////////////////////////////// void FlushDataCache() { } //////////////////////////////////////////////////////////////////// //80002B00 //////////////////////////////////////////////////////////////////// void FlushSecondaryCache() { } //////////////////////////////////////////////////////////////////// //A0002B40 SYSCALL 101,105 _105 //////////////////////////////////////////////////////////////////// void _105(int op1, int op2) { // flushing caches again } //////////////////////////////////////////////////////////////////// //A0002C00 SYSCALL 096 KSeg0 //////////////////////////////////////////////////////////////////// void _KSeg0(u32 arg) { u32 cfg; __asm__("mfc0 %0, $16\n" : "=r"(cfg) : ); cfg = (arg&3)&((cfg>>3)<<3); // yes it is 0, don't ask __asm__("mtc0 %0, $16\n" "sync\n" : : "r"(cfg) ); } //////////////////////////////////////////////////////////////////// //80002C40 SYSCALL 099 GetCop0 //////////////////////////////////////////////////////////////////// int _GetCop0(int reg) { return table_GetCop0[reg](reg); } //////////////////////////////////////////////////////////////////// //80002C58-80002D50 calls for table_GetCop0 //////////////////////////////////////////////////////////////////// int GetCop0_Index(int reg) { __asm__(" mfc0 $2, $0\n"); } int GetCop0_Random(int reg) { __asm__(" mfc0 $2, $1\n"); } int GetCop0_EntryLo0(int reg) { __asm__(" mfc0 $2, $2\n"); } int GetCop0_EntryLo1(int reg) { __asm__(" mfc0 $2, $3\n"); } int GetCop0_Context(int reg) { __asm__(" mfc0 $2, $4\n"); } int GetCop0_PageMask(int reg) { __asm__(" mfc0 $2, $5\n"); } int GetCop0_Wired(int reg) { __asm__(" mfc0 $2, $6\n"); } int GetCop0_Reg7(int reg) { return; } int GetCop0_BadVAddr(int reg) { __asm__(" mfc0 $2, $8\n"); } int GetCop0_Count(int reg) { __asm__(" mfc0 $2, $9\n"); } int GetCop0_EntryHi(int reg) { __asm__(" mfc0 $2, $10\n"); } int GetCop0_Compare(int reg) { __asm__(" mfc0 $2, $11\n"); } int GetCop0_Status(int reg) { __asm__(" mfc0 $2, $12\n"); } int GetCop0_Cause(int reg) { __asm__(" mfc0 $2, $13\n"); } int GetCop0_ExceptPC(int reg) { __asm__(" mfc0 $2, $14\n"); } int GetCop0_PRevID(int reg) { __asm__(" mfc0 $2, $15\n"); } int GetCop0_Config(int reg) { __asm__(" mfc0 $2, $16\n"); } int GetCop0_Reg17(int reg) { return; } int GetCop0_Reg18(int reg) { return; } int GetCop0_Reg19(int reg) { return; } int GetCop0_Reg20(int reg) { return; } int GetCop0_Reg21(int reg) { return; } int GetCop0_Reg22(int reg) { return; } int GetCop0_Reg23(int reg) { __asm__(" mfc0 $2, $23\n"); } int GetCop0_DebugReg24(int reg) { __asm__(" mfc0 $2, $24\n"); } int GetCop0_Perf(int reg) { __asm__(" mfc0 $2, $25\n"); } int GetCop0_Reg26(int reg) { return; } int GetCop0_Reg27(int reg) { return; } int GetCop0_TagLo(int reg) { __asm__(" mfc0 $2, $28\n"); } int GetCop0_TagHi(int reg) { __asm__(" mfc0 $2, $29\n"); } int GetCop0_ErrorPC(int reg) { __asm__(" mfc0 $2, $30\n"); } int GetCop0_Reg31(int reg) { return; } int (*table_GetCop0[32])(int reg) = { // 800124E8 GetCop0_Index, GetCop0_Random, GetCop0_EntryLo0, GetCop0_EntryLo1, GetCop0_Context, GetCop0_PageMask, GetCop0_Wired, GetCop0_Reg7, GetCop0_BadVAddr, GetCop0_Count, GetCop0_EntryHi, GetCop0_Compare, GetCop0_Status, GetCop0_Cause, GetCop0_ExceptPC, GetCop0_PRevID, GetCop0_Config, GetCop0_Reg17, GetCop0_Reg18, GetCop0_Reg19, GetCop0_Reg20, GetCop0_Reg21, GetCop0_Reg22, GetCop0_Reg23, GetCop0_DebugReg24, GetCop0_Perf, GetCop0_Reg26, GetCop0_Reg27, GetCop0_TagLo, GetCop0_TagHi, GetCop0_ErrorPC, GetCop0_Reg31 }; //////////////////////////////////////////////////////////////////// //80002D80 //////////////////////////////////////////////////////////////////// int SetCop0(int reg, int val) { return table_SetCop0[reg](reg, val); } //////////////////////////////////////////////////////////////////// //80002D98-80002F74 calls for table_SetCop0 //////////////////////////////////////////////////////////////////// int SetCop0_Index(int reg, int val) { __asm__(" mfc0 $2, $0\nmtc0 %0, $0\nsync\n" : : "r"(val)); } int SetCop0_Random(int reg, int val) { return -1; } int SetCop0_EntryLo0(int reg, int val) { __asm__(" mfc0 $2, $2\nmtc0 %0, $2\nsync\n" : : "r"(val)); } int SetCop0_EntryLo1(int reg, int val) { __asm__(" mfc0 $2, $3\nmtc0 %0, $3\nsync\n" : : "r"(val)); } int SetCop0_Context(int reg, int val) { __asm__(" mfc0 $2, $4\nmtc0 %0, $4\nsync\n" : : "r"(val)); } int SetCop0_PageMask(int reg, int val) { __asm__(" mfc0 $2, $5\nmtc0 %0, $5\nsync\n" : : "r"(val)); } int SetCop0_Wired(int reg, int val) { __asm__(" mfc0 $2, $6\nmtc0 %0, $6\nsync\n" : : "r"(val)); } int SetCop0_Reg7(int reg, int val) { return -1; } int SetCop0_BadVAddr(int reg, int val) { return -1; } int SetCop0_Count(int reg, int val) { __asm__(" mfc0 $2, $9\nmtc0 %0, $9\nsync\n" : : "r"(val)); } int SetCop0_EntryHi(int reg, int val) { __asm__(" mfc0 $2, $10\nmtc0 %0, $10\nsync\n" : : "r"(val)); } int SetCop0_Compare(int reg, int val) { __asm__(" mfc0 $2, $11\nmtc0 %0, $11\nsync\n" : : "r"(val)); } int SetCop0_Status(int reg, int val) { __asm__(" mfc0 $2, $12\nmtc0 %0, $12\nsync\n" : : "r"(val)); } int SetCop0_Cause(int reg, int val) { return -1; } int SetCop0_ExceptPC(int reg, int val) { __asm__(" mfc0 $2, $14\nmtc0 %0, $14\nsync\n" : : "r"(val)); } int SetCop0_PRevID(int reg, int val) { return -1; } int SetCop0_Config(int reg, int val) { __asm__(" mfc0 $2, $16\nmtc0 %0, $16\nsync\n" : : "r"(val)); } int SetCop0_Reg17(int reg, int val) { return -1; } int SetCop0_Reg18(int reg, int val) { return -1; } int SetCop0_Reg19(int reg, int val) { return -1; } int SetCop0_Reg20(int reg, int val) { return -1; } int SetCop0_Reg21(int reg, int val) { return -1; } int SetCop0_Reg22(int reg, int val) { return -1; } int SetCop0_Reg23(int reg, int val) { __asm__(" mfc0 $2, $23\nmtc0 %0, $23\nsync\n" : : "r"(val)); } int SetCop0_DebugReg24(int reg, int val){ __asm__(" mfc0 $2, $24\nmtc0 %0, $24\nsync\n" : : "r"(val)); } int SetCop0_Perf(int reg, int val) { __asm__(" mfc0 $2, $25\nmtc0 %0, $25\nsync\n" : : "r"(val)); } int SetCop0_Reg26(int reg, int val) { return -1; } int SetCop0_Reg27(int reg, int val) { return -1; } int SetCop0_TagLo(int reg, int val) { __asm__(" mfc0 $2, $28\nmtc0 %0, $28\nsync\n" : : "r"(val)); } int SetCop0_TagHi(int reg, int val) { __asm__(" mfc0 $2, $29\nmtc0 %0, $29\nsync\n" : : "r"(val)); } int SetCop0_ErrorPC(int reg, int val) { __asm__(" mfc0 $2, $30\nmtc0 %0, $30\nsync\n" : : "r"(val)); } int SetCop0_Reg31(int reg, int val) { return -1; } int (*table_SetCop0[32])(int reg, int val) = { // 80012568 SetCop0_Index, SetCop0_Random, SetCop0_EntryLo0, SetCop0_EntryLo1, SetCop0_Context, SetCop0_PageMask, SetCop0_Wired, SetCop0_Reg7, SetCop0_BadVAddr, SetCop0_Count, SetCop0_EntryHi, SetCop0_Compare, SetCop0_Status, SetCop0_Cause, SetCop0_ExceptPC, SetCop0_PRevID, SetCop0_Config, SetCop0_Reg17, SetCop0_Reg18, SetCop0_Reg19, SetCop0_Reg20, SetCop0_Reg21, SetCop0_Reg22, SetCop0_Reg23, SetCop0_DebugReg24, SetCop0_Perf, SetCop0_Reg26, SetCop0_Reg27, SetCop0_TagLo, SetCop0_TagHi, SetCop0_ErrorPC, SetCop0_Reg31 }; //////////////////////////////////////////////////////////////////// //80002F80 SYSCALL 007 ExecPS2 //////////////////////////////////////////////////////////////////// int _ExecPS2(void * entry, void * gp, int argc, char ** argv) { saveContext(); __ExecPS2(entry, gp, argc, argv); __asm__("mtc0 $2, $14\n" "move $sp, %0\n" "sd $2, 0x20($sp)\n" : : "r"(SavedSP)); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80002FC0 SYSCALL 033 DeleteThread //////////////////////////////////////////////////////////////////// int _DeleteThread(int tid) { register int ret __asm__("$2"); register u32 curepc __asm__("$4"); saveContext(); ret = __DeleteThread(tid); if (ret < 0) { __asm__("lw $sp, %0\n" : : "m"(SavedSP)); // make sure the return value is also stored __asm__("sd $2, 0x20($sp)\n"); restoreContext(); eret(); } __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4 __asm__("mtc0 $2, $14\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003040 SYSCALL 034 StartThread //////////////////////////////////////////////////////////////////// int _StartThread(int tid, void *arg) { register int ret __asm__("$2"); register u32 curepc __asm__("$4"); saveContext(); ret = __StartThread(tid, arg); if (ret < 0) { __asm__("lw $sp, %0\n" : : "m"(SavedSP)); // make sure the return value is also stored __asm__("sd $2, 0x20($sp)\n"); restoreContext(); eret(); } __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4 __asm__("mtc0 $2, $14\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //800030C0 SYSCALL 035 ExitThread //////////////////////////////////////////////////////////////////// int _ExitThread() { saveContext(); __ExitThread(); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003100 SYSCALL 036 ExitDeleteThread //////////////////////////////////////////////////////////////////// int _ExitDeleteThread() { saveContext(); __ExitDeleteThread(); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003140 SYSCALL 037 TerminateThread //////////////////////////////////////////////////////////////////// int _TerminateThread(int tid) { register int ret __asm__("$2"); register u32 curepc __asm__("$4"); saveContext(); ret = _iTerminateThread(tid); if( ret < 0 ) { __asm__("lw $sp, %0\n" : : "m"(SavedSP)); // make sure the return value is also stored __asm__("sd $2, 0x20($sp)\n"); restoreContext(); eret(); } __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4 __asm__("mtc0 $2, $14\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //800031C0 SYSCALL 043 RotateThreadReadyQueue //////////////////////////////////////////////////////////////////// void _RotateThreadReadyQueue(int pri) { register int ret __asm__("$2"); register u32 curepc __asm__("$4"); ret = pri; saveContext(); ret = _iRotateThreadReadyQueue(pri); if( ret < 0 ) { __asm__("lw $sp, %0\n" : : "m"(SavedSP)); // make sure the return value is also stored __asm__("sd $2, 0x20($sp)\n"); restoreContext(); eret(); } __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4 __asm__("mtc0 $2, $14\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003240 SYSCALL 045 ReleaseWaitThread //////////////////////////////////////////////////////////////////// void _ReleaseWaitThread(int tid) { register int ret __asm__("$2"); register u32 curepc __asm__("$4"); ret = tid; saveContext(); ret = _iReleaseWaitThread(tid); if( ret < 0 ) { __asm__("lw $sp, %0\n" : : "m"(SavedSP)); // make sure the return value is also stored __asm__("sd $2, 0x20($sp)\n"); restoreContext(); eret(); } __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // EPC _ThreadHandler(curepc, SavedSP); // returns entry in $3, stack in $4 __asm__("mtc0 $2, $14\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //800032C0 SYSCALL 052 SleepThread //////////////////////////////////////////////////////////////////// int _SleepThread() { register int ret __asm__("$2"); ret = threadId; saveContext(); ret = __SleepThread(); if (ret < 0) { register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ChangeThread(curepc, SavedSP, 1); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } __asm__("lw $sp, %0\n" "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) ); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003340 SYSCALL 051 WakeupThread //////////////////////////////////////////////////////////////////// int _WakeupThread(int tid) { register int ret __asm__("$2"); ret = tid; saveContext(); ret = iWakeupThread(tid); if( ret >= 0 ) { register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ThreadHandler(curepc, SavedSP); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } __asm__("lw $sp, %0\n" "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) ); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //800033C0 SYSCALL 057 ResumeThread //////////////////////////////////////////////////////////////////// int _ResumeThread(int tid) { register int ret __asm__("$2"); ret = tid; saveContext(); ret = _iResumeThread(tid); if( ret >= 0 ) { register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ThreadHandler(curepc, SavedSP); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } __asm__("lw $sp, %0\n" "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) ); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003440 SYSCALL 068 WaitSema //////////////////////////////////////////////////////////////////// int _WaitSema(int sid) { register int ret __asm__("$2"); ret = sid; saveContext(); ret = _iWaitSema(sid); if( ret == 0xFFFFFFFE ) { register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ChangeThread(curepc, SavedSP, 2); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } __asm__("lw $sp, %0\n" : : "m"(SavedSP)); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //800034C0 SYSCALL 066 SignalSema //////////////////////////////////////////////////////////////////// void _SignalSema(int sid) { register int ret __asm__("$2"); ret = sid; saveContext(); ret = _iSignalSema(sid); if( ret >= 0 ) { register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ThreadHandler(curepc, SavedSP); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } __asm__("lw $sp, %0\n" "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) ); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003540 SYSCALL 065 DeleteSema //////////////////////////////////////////////////////////////////// int _DeleteSema(int sid) { register int ret __asm__("$2"); ret = sid; saveContext(); ret = _iDeleteSema(sid); if( ret >= 0 ) { register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ThreadHandler(curepc, SavedSP); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } __asm__("lw $sp, %0\n" "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) ); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //800035C0 SYSCALL 041 ChangeThreadPriority //return has to be void (even though it fills in v0) //////////////////////////////////////////////////////////////////// void _ChangeThreadPriority(int tid, int prio) { register int ret __asm__("$2"); saveContext(); ret = _iChangeThreadPriority(tid, prio); __asm__("lw $26, %0\n" "sd %1, 0x20($26)\n" : : "m"(SavedSP), "r"(ret) ); if (ret>=0){ register int curepc __asm__("$4"); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ThreadHandler(curepc, SavedSP); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } // why twice? __asm__("lw $sp, %0\n" "sd %1, 0x20($sp)\n" : : "m"(SavedSP), "r"(ret) ); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //8000363C //////////////////////////////////////////////////////////////////// void __ThreadHandler() { register int curepc __asm__("$4"); saveContext(); __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); _ThreadHandler(curepc, SavedSP); __asm__("mtc0 $2, $14\n" "sync\n" "move $sp, $3\n"); restoreContext(); eret(); } //////////////////////////////////////////////////////////////////// //80003680 //////////////////////////////////////////////////////////////////// void saveContext() { __asm__ ( "lui $26, %hi(SavedSP)\n" "lq $26, %lo(SavedSP)($26)\n" ); __asm__ ( "addiu $26, %0\n" : : "i"(-sizeof(struct threadCtx)) ); __asm__ ( ".set noat\n" "lui $1, %hi(SavedAT)\n" "lq $1, %lo(SavedAT)($1)\n" "sq $1, 0x000($26)\n" "sq $2, 0x010($26)\n" "sq $3, 0x020($26)\n" "sq $4, 0x030($26)\n" "sq $5, 0x040($26)\n" "sq $6, 0x050($26)\n" "sq $7, 0x060($26)\n" "sq $8, 0x070($26)\n" "sq $9, 0x080($26)\n" "sq $10, 0x090($26)\n" "sq $11, 0x0A0($26)\n" "sq $12, 0x0B0($26)\n" "sq $13, 0x0C0($26)\n" "sq $14, 0x0D0($26)\n" "sq $15, 0x0E0($26)\n" "sq $16, 0x0F0($26)\n" "sq $17, 0x100($26)\n" "sq $18, 0x110($26)\n" "sq $19, 0x120($26)\n" "sq $20, 0x130($26)\n" "sq $21, 0x140($26)\n" "sq $22, 0x150($26)\n" "sq $23, 0x160($26)\n" "sq $24, 0x170($26)\n" "sq $25, 0x180($26)\n" "sq $gp, 0x190($26)\n" "lui $1, %hi(SavedSP)\n" "lq $sp, %lo(SavedSP)($1)\n" "sq $sp, 0x1A0($26)\n" "sq $fp, 0x1B0($26)\n" "lui $1, %hi(SavedRA)\n" "lq $1, %lo(SavedRA)($1)\n" "sq $1, 0x1C0($26)\n" "swc1 $0, 0x200($26)\n" "swc1 $1, 0x204($26)\n" "swc1 $2, 0x208($26)\n" "swc1 $3, 0x20C($26)\n" "swc1 $4, 0x210($26)\n" "swc1 $5, 0x214($26)\n" "swc1 $6, 0x218($26)\n" "swc1 $7, 0x21C($26)\n" "swc1 $8, 0x220($26)\n" "swc1 $9, 0x224($26)\n" "swc1 $10, 0x228($26)\n" "swc1 $11, 0x22C($26)\n" "swc1 $12, 0x230($26)\n" "swc1 $13, 0x234($26)\n" "swc1 $14, 0x238($26)\n" "swc1 $15, 0x23C($26)\n" "swc1 $16, 0x240($26)\n" "swc1 $17, 0x244($26)\n" "swc1 $18, 0x248($26)\n" "swc1 $19, 0x24C($26)\n" "swc1 $20, 0x250($26)\n" "swc1 $21, 0x254($26)\n" "swc1 $22, 0x258($26)\n" "swc1 $23, 0x25C($26)\n" "swc1 $24, 0x260($26)\n" "swc1 $25, 0x264($26)\n" "swc1 $26, 0x268($26)\n" "swc1 $27, 0x26C($26)\n" "swc1 $28, 0x270($26)\n" "swc1 $29, 0x274($26)\n" "swc1 $30, 0x278($26)\n" "swc1 $31, 0x27C($26)\n" "mfsa $1\n" "sw $1, 0x1F0($26)\n" "cfc1 $1, $31\n" "sw $1, 0x1F4($26)\n" "lui $1, 0x8000\n" "mtc1 $1, $1\n" "mtc1 $1, $0\n" "madd.s $f0, $f0, $f1\n" "swc1 $0, 0x1F8($26)\n" "mfhi $1\n" "sd $1, 0x1D0($26)\n" "mfhi1 $1\n" "sd $1, 0x1D8($26)\n" "mflo $1\n" "sd $1, 0x1E0($26)\n" "mflo1 $1\n" "sd $1, 0x1E8($26)\n" "lui $1, %hi(SavedSP)\n" "sw $26, %lo(SavedSP)($1)\n" "jr $31\n" "lui $1, 0x8000\n" ".set at\n" ); } //////////////////////////////////////////////////////////////////// //80003800 //////////////////////////////////////////////////////////////////// void restoreContext() { __asm__ ( ".set noat\n" "lui $26, 0x8000\n" "mtc1 $26, $1\n" "lwc1 $0, 0x1F8($sp)\n" "adda.s $f0, $f1\n" "lw $26, 0x1F0($sp)\n" "mtsa $26\n" "lw $26, 0x1F4($sp)\n" "ctc1 $26, $31\n" "ld $26, 0x1D0($sp)\n" "mthi $26\n" "ld $26, 0x1D8($sp)\n" "mthi1 $26\n" "ld $26, 0x1E0($sp)\n" "mtlo $26\n" "ld $26, 0x1E8($sp)\n" "mtlo1 $26\n" "lq $1, 0x000($sp)\n" "lq $2, 0x010($sp)\n" "lq $3, 0x020($sp)\n" "lq $4, 0x030($sp)\n" "lq $5, 0x040($sp)\n" "lq $6, 0x050($sp)\n" "lq $7, 0x060($sp)\n" "lq $8, 0x070($sp)\n" "lq $9, 0x080($sp)\n" "lq $10, 0x090($sp)\n" "lq $11, 0x0A0($sp)\n" "lq $12, 0x0B0($sp)\n" "lq $13, 0x0C0($sp)\n" "lq $14, 0x0D0($sp)\n" "lq $15, 0x0E0($sp)\n" "lq $16, 0x0F0($sp)\n" "lq $17, 0x100($sp)\n" "lq $18, 0x110($sp)\n" "lq $19, 0x120($sp)\n" "lq $20, 0x130($sp)\n" "lq $21, 0x140($sp)\n" "lq $22, 0x150($sp)\n" "lq $23, 0x160($sp)\n" "lq $24, 0x170($sp)\n" "lq $25, 0x180($sp)\n" "lq $gp, 0x190($sp)\n" "lq $fp, 0x1B0($sp)\n" "lwc1 $0, 0x200($sp)\n" "lwc1 $1, 0x204($sp)\n" "lwc1 $2, 0x208($sp)\n" "lwc1 $3, 0x20C($sp)\n" "lwc1 $4, 0x210($sp)\n" "lwc1 $5, 0x214($sp)\n" "lwc1 $6, 0x218($sp)\n" "lwc1 $7, 0x21C($sp)\n" "lwc1 $8, 0x220($sp)\n" "lwc1 $9, 0x224($sp)\n" "lwc1 $10, 0x228($sp)\n" "lwc1 $11, 0x22C($sp)\n" "lwc1 $12, 0x230($sp)\n" "lwc1 $13, 0x234($sp)\n" "lwc1 $14, 0x238($sp)\n" "lwc1 $15, 0x23C($sp)\n" "lwc1 $16, 0x240($sp)\n" "lwc1 $17, 0x244($sp)\n" "lwc1 $18, 0x248($sp)\n" "lwc1 $19, 0x24C($sp)\n" "lwc1 $20, 0x250($sp)\n" "lwc1 $21, 0x254($sp)\n" "lwc1 $22, 0x258($sp)\n" "lwc1 $23, 0x25C($sp)\n" "lwc1 $24, 0x260($sp)\n" "lwc1 $25, 0x264($sp)\n" "lwc1 $26, 0x268($sp)\n" "lwc1 $27, 0x26C($sp)\n" "lwc1 $28, 0x270($sp)\n" "lwc1 $29, 0x274($sp)\n" "lwc1 $30, 0x278($sp)\n" "lwc1 $31, 0x27C($sp)\n" "daddu $26, $31, $0\n" "lq $31, 0x1C0($sp)\n" "jr $26\n" "lq $sp, 0x1A0($sp)\n" ".set at\n" ); } //////////////////////////////////////////////////////////////////// //80003940 //////////////////////////////////////////////////////////////////// void _ThreadHandler(u32 epc, u32 stack) { register int tid; threads_array[threadId].entry =(void*)epc; threads_array[threadId].status =THS_READY; threads_array[threadId].stack_res =(void*)stack; for ( ; threadPrio < 129; threadPrio++) if ((thread_ll_priorities[threadPrio].next != &thread_ll_priorities[threadPrio]) || (thread_ll_priorities[threadPrio].prev != &thread_ll_priorities[threadPrio])){ tid=threadId=(( (u32)thread_ll_priorities[threadPrio].prev - (u32)threads_array)*0x286BCA1B)>>2; break; } if (threadPrio>=129){ __printf("# No active threads\n"); Exit(1); tid=0; } threads_array[tid].status=THS_RUN; if (threads_array[tid].waitSema){ threads_array[tid].waitSema=0; *(u32*)((u32)threads_array[tid].stack_res + 0x20) = -1; } __asm__("move $2, %0\n" "move $3, %1\n" : : "r"(threads_array[tid].entry), "r"(threads_array[tid].stack_res) ); } //////////////////////////////////////////////////////////////////// //80003A78 //////////////////////////////////////////////////////////////////// void _ChangeThread(u32 entry, u32 stack_res, int waitSema) { struct TCB *th; struct ll *l, *p; int prio; th = &threads_array[threadId]; th->status = THS_WAIT; th->waitSema = waitSema; th->entry = (void (*)(void*))entry; th->stack_res = (void*)stack_res; prio = threadPrio; for (l = &thread_ll_priorities[prio]; ; l++, prio++) { if (prio >= 129) { __printf("# No active threads\n"); Exit(1); l = 0; break; } if (l->next != l) { p = l->next; break; } if (l->prev == l) continue; p = l->prev; break; } if (l) { threadPrio = prio; threadId = (((u32)p - (u32)threads_array) * 0x286BCA1B) / 4; } th = &threads_array[threadId]; th->status = THS_RUN; if (th->waitSema) { th->waitSema = 0; *(s64*)((u32)th->stack_res+0x20) = -1; } __asm__("move $2, %0\n" "move $3, %1\n" : : "r"(th->entry), "r"(th->stack_res) ); } //////////////////////////////////////////////////////////////////// //80003C50 SYSCALL 032 CreateThread //////////////////////////////////////////////////////////////////// int _CreateThread(struct ThreadParam *param) { struct TCB *th; struct threadCtx *thctx; int index; int *ptr; th = (struct TCB *)LL_unlink((struct ll*)&thread_ll_free); if (th == NULL) { __printf("%s: failed to get free thread\n", __FUNCTION__); return -1; } threads_count++; index=(((u32)th-(u32)threads_array) * 0x286BCA1B)/4; th->entry = param->entry; th->stack_res = param->stack + param->stackSize - STACK_RES; th->status = THS_DORMANT; th->gpReg = param->gpReg; th->initPriority = param->initPriority; th->argstring = 0; th->wakeupCount = 0; th->semaId = 0; th->stack = param->stack; th->argc = 0; th->entry_ = param->entry; th->heap_base = threads_array[threadId].heap_base; th->stackSize = param->stackSize; th->currentPriority = param->initPriority; th->waitSema = 0; th->root = threads_array[threadId].root; thctx = th->stack_res; thctx->gp = (u32)param->gpReg; thctx->sp = (u32)&thctx[1]; thctx->fp = (u32)&thctx[1]; thctx->ra = (u32)threads_array[threadId].root; return index; } //////////////////////////////////////////////////////////////////// //80003E00 SYSCALL 37 iTerminateThread //////////////////////////////////////////////////////////////////// int _iTerminateThread(int tid) { //TODO } //////////////////////////////////////////////////////////////////// //80003F00 //////////////////////////////////////////////////////////////////// int __DeleteThread(int tid) { if ((tid>=256) || (tid==threadId) || (threads_array[tid].status!=THS_DORMANT)) return -1; releaseTCB(tid); return tid; } //////////////////////////////////////////////////////////////////// //80003F70 //////////////////////////////////////////////////////////////////// int __StartThread(int tid, void *arg) { if ((tid>=256) || (tid==threadId) || (threads_array[tid].status!=THS_DORMANT)) return -1; threads_array[tid].argstring = arg; ((void**)threads_array[tid].stack_res)[0x10] = arg; //a0 thread_2_ready(tid); return tid; } //////////////////////////////////////////////////////////////////// //80003FF8 //////////////////////////////////////////////////////////////////// int __ExitThread() { //TODO } //////////////////////////////////////////////////////////////////// //80004110 //////////////////////////////////////////////////////////////////// int __ExitDeleteThread() { //TODO } //////////////////////////////////////////////////////////////////// //80004228 SYSCALL 39 DisableDispatchThread //////////////////////////////////////////////////////////////////// int _DisableDispatchThread() { __printf("# DisableDispatchThread is not supported in this version\n"); return threadId; } //////////////////////////////////////////////////////////////////// //80004258 SYSCALL 40 EnableDispatchThread //////////////////////////////////////////////////////////////////// int _EnableDispatchThread() { __printf("# EnableDispatchThread is not supported in this version\n"); return threadId; } //////////////////////////////////////////////////////////////////// //80004288 SYSCALL 042 iChangeThreadPriority //////////////////////////////////////////////////////////////////// int _iChangeThreadPriority(int tid, int prio) { short oldPrio; if ((tid >= 256) || (prio < 0) || (prio >= 128)) return -1; if (tid == 0) tid = threadId; if (threads_array[tid].status == 0) return -1; if ((0 < (threads_array[tid].status ^ 0x10)) == 0) return -1; oldPrio = threads_array[tid].currentPriority; if ((tid != threadId) && (threads_array[tid].status != THS_READY)) { threads_array[tid].currentPriority = prio; return oldPrio; } if (threadPrio < prio) threadStatus = 1; unsetTCB(tid); threads_array[tid].currentPriority = prio; thread_2_ready(tid); return oldPrio; } //////////////////////////////////////////////////////////////////// //80004388 SYSCALL 044 iRotateThreadReadyQueue //////////////////////////////////////////////////////////////////// int _iRotateThreadReadyQueue(int prio) { if (prio >= 128) return -1; LL_rotate(&thread_ll_priorities[prio]); return prio; } //////////////////////////////////////////////////////////////////// //800043D0 SYSCALL 046 iReleaseWaitThread //////////////////////////////////////////////////////////////////// int _iReleaseWaitThread(int tid) { if( (u32)(tid-1) >= 255 ) return -1; if( (u32)threads_array[tid].status >= 17 ) return tid; switch(threads_array[tid].status) { case 0: return -1; case THS_WAIT: { //443C if( threads_array[tid].waitSema == 2 ) { LL_unlinkthis((struct ll*)&threads_array[tid]); semas_array[threads_array[tid].semaId].wait_threads--; } int threadPrioOld = threadPrio; threads_array[tid].status = THS_READY; thread_2_ready(tid); if( threadPrio < threadPrioOld ) { threadStatus = 1; } break; } case (THS_WAIT|THS_SUSPEND): threads_array[tid].status = THS_SUSPEND; if( threads_array[tid].waitSema != 2 ) return tid; LL_unlinkthis((struct ll*)&threads_array[tid]); semas_array[threads_array[tid].semaId].wait_threads--; break; } return tid; } //////////////////////////////////////////////////////////////////// //80004548 SYSCALL 047 GetThreadId //////////////////////////////////////////////////////////////////// int _GetThreadId() { return threadId; } //////////////////////////////////////////////////////////////////// //80004558 SYSCALL 048 ReferThreadStatus //////////////////////////////////////////////////////////////////// int _ReferThreadStatus(int tid, struct ThreadParam *info) { if (tid >= 256) return -1; if (tid == 0) tid = threadId; if (info != NULL) { info->entry = threads_array[tid].entry; info->status = threads_array[tid].status; info->stack = threads_array[tid].stack; info->stackSize = threads_array[tid].stackSize; info->gpReg = threads_array[tid].gpReg; info->initPriority = threads_array[tid].initPriority; info->currentPriority = threads_array[tid].currentPriority; info->attr = threads_array[tid].attr; info->waitSema = threads_array[tid].waitSema; info->option = threads_array[tid].option; info->waitId = threads_array[tid].semaId; info->wakeupCount = threads_array[tid].wakeupCount; } return threads_array[tid].status; } //////////////////////////////////////////////////////////////////// //80004658 //////////////////////////////////////////////////////////////////// int __SleepThread() { if (threads_array[threadId].wakeupCount <= 0) { unsetTCB(threadId); return -1; } threads_array[threadId].wakeupCount--; return threadId; } //////////////////////////////////////////////////////////////////// //800046B0 SYSCALL 052 iWakeupThread //////////////////////////////////////////////////////////////////// int _iWakeupThread(int tid) { register int prio; if (tid>=256) return -1; if (tid==0) tid = threadId; switch (threads_array[tid].status){ case THS_WAIT: if (threads_array[tid].waitSema=1){ prio=threadPrio; thread_2_ready(tid); if (threadPrio=256) return -1; tid = tid ? tid : threadId; ret=threads_array[tid].wakeupCount; threads_array[tid].wakeupCount=0; return ret; } //////////////////////////////////////////////////////////////////// //800049B0 SYSCALL 080 RFU080_CreateEventFlag //////////////////////////////////////////////////////////////////// int _CreateEventFlag() { return threads_count; // CreateEventFlag, why!?! } //////////////////////////////////////////////////////////////////// //800049C0 SYSCALL 064 CreateSema //////////////////////////////////////////////////////////////////// int _CreateSema(struct SemaParam *sema) { register struct kSema *crt=semas_last; if ((crt==NULL) || (sema->init_count<0)) return -1; crt->wait_prev = (struct TCB*)&crt->wait_next; semas_count++; crt->count =sema->init_count; crt->wait_next =(struct TCB*)&crt->wait_next; semas_last = crt->free; crt->max_count =sema->max_count; crt->free =NULL; crt->attr =sema->attr; crt->wait_threads=0; crt->option =sema->option; return (crt-semas_array); //sizeof(kSema)==32 } //////////////////////////////////////////////////////////////////// //80004A48 SYSCALL 073 iDeleteSema //////////////////////////////////////////////////////////////////// int _iDeleteSema(int sid) { register thid, thprio; if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1; semas_count--; while (semas_array[sid].wait_threads>0){ thid=(((u32)LL_unlink((struct ll*)&semas_array[sid].wait_next)-(u32)threads_array) * 0x286BCA1B)/4; LL_unlinkthis((struct ll*)&threads_array[thid]); semas_array[sid].wait_threads--; if (threads_array[thid].status==THS_WAIT){ thprio=threadPrio; thread_2_ready(thid); if (threadPrio=MAX_SEMAS) || (semas_array[sid].count<0)) return -1; if (semas_array[sid].wait_threads>0){ thid=(((u32)LL_unlink((struct ll*)&semas_array[sid].wait_next)-(u32)threads_array)*0x286BCA1B)/4; LL_unlinkthis((struct ll*)&threads_array[thid]); semas_array[sid].wait_threads--; if (threads_array[thid].status==THS_WAIT){ prio=threadPrio; thread_2_ready(thid); if (threadPrio < prio) threadStatus=THS_RUN; threads_array[thid].waitSema=0; //just a guess:P } else if (threads_array[thid].status==(THS_WAIT|THS_SUSPEND)){ threads_array[thid].status =THS_SUSPEND; threads_array[thid].waitSema=0; } }else semas_array[sid].count++; return sid; } //////////////////////////////////////////////////////////////////// //80004CF8 //////////////////////////////////////////////////////////////////// int _iWaitSema(int sid) { if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1; if (semas_array[sid].count>0){ semas_array[sid].count--; return sid; } semas_array[sid].wait_threads++; unsetTCB(threadId); LL_add((struct ll*)&semas_array[sid].wait_next, (struct ll*)&threads_array[threadId]); threads_array[threadId].semaId=sid; return -2; } //////////////////////////////////////////////////////////////////// //80004DC8 SYSCALL 069 PollSema, 070 iPollSema //////////////////////////////////////////////////////////////////// int _PollSema(int sid) { if ((sid>=MAX_SEMAS) || (semas_array[sid].count<=0)) return -1; semas_array[sid].count--; return sid; } //////////////////////////////////////////////////////////////////// //80004E00 SYSCALL 071 ReferSemaStatus, 072 iReferSemaStatus //////////////////////////////////////////////////////////////////// int _ReferSemaStatus(int sid, struct SemaParam *sema) { if ((sid>=MAX_SEMAS) || (semas_array[sid].count<0)) return -1; sema->count =semas_array[sid].count; sema->max_count =semas_array[sid].max_count; sema->wait_threads =semas_array[sid].wait_threads; sema->attr =semas_array[sid].attr; sema->option =semas_array[sid].option; return sid; } //////////////////////////////////////////////////////////////////// //80004E58 SYSCALL 081 RFU081_DeleteEventFlag //////////////////////////////////////////////////////////////////// int _DeleteEventFlag() { return semas_count; // DeleteEventFlag, why!?! } //////////////////////////////////////////////////////////////////// //80004E68 //////////////////////////////////////////////////////////////////// int _SemasInit() { int i; for (i=0; i<256; i++) { semas_array[i].free = &semas_array[i+1]; semas_array[i].count = -1; semas_array[i].wait_threads = 0; semas_array[i].wait_next = (struct TCB*)&semas_array[i].wait_next; semas_array[i].wait_prev = (struct TCB*)&semas_array[i].wait_next; } semas_array[255].free = 0; semas_last = semas_array; semas_count = 0; return 256; } //////////////////////////////////////////////////////////////////// //80004EC8 //////////////////////////////////////////////////////////////////// void __load_module_EENULL() { int i; thread_ll_free.prev = &thread_ll_free; thread_ll_free.next = &thread_ll_free; for (i=0; i<128; i++) { thread_ll_priorities[i].prev = &thread_ll_priorities[i]; thread_ll_priorities[i].next = &thread_ll_priorities[i]; } threads_count = 0; threadId = 0; threadPrio = 0; for (i=0; i<256; i++) { threads_array[i].status = 0; LL_add(&thread_ll_free, (struct ll*)&threads_array[i]); } _SemasInit(); threadStatus = 0; __load_module("EENULL", (void (*)(void*))0x81FC0, (void*)0x81000, 0x80); } //////////////////////////////////////////////////////////////////// //80004FB0 // makes the args from argc & argstring; args is in bss of program //////////////////////////////////////////////////////////////////// void _InitArgs(char *argstring, ARGS *args, int argc) { int i; char *p = args->args; args->argc = argc; for (i=0; iargv[i] = p; //copy string pointer while (*argstring) //copy the string itself *p++ = *argstring++; *p++ = *argstring++; //copy the '\0' } } //////////////////////////////////////////////////////////////////// //80005198 SYSCALL 060 _InitializeMainThread //////////////////////////////////////////////////////////////////// void *_InitializeMainThread(u32 gp, void *stack, int stack_size, char *args, int root) { struct TCB *th; struct threadCtx *ctx; if ((int)stack == -1) stack = (void*)((_GetMemorySize() - 4*1024) - stack_size); ctx = (struct threadCtx*)((u32)stack + stack_size - STACK_RES/4); ctx->gp = gp; //+1C0 ctx->ra = root; //+1F0 ctx->fp = (u32)ctx+0x280; //+1E0 <- &280 ctx->sp = (u32)ctx+0x280; //+1D0 <- &280 th = &threads_array[threadId]; th->gpReg = (void*)gp; th->stackSize = stack_size; th->stack_res = ctx; th->stack = stack; th->root = (void*)root; _InitArgs(th->argstring, (ARGS*)args, th->argc); th->argstring = args; return ctx; } //////////////////////////////////////////////////////////////////// //800052A0 SYSCALL 061 RFU061_InitializeHeapArea //////////////////////////////////////////////////////////////////// void* _InitializeHeapArea(void *heap_base, int heap_size) { void *ret; if (heap_size < 0) { ret = threads_array[threadId].stack; } else { ret = heap_base + heap_size; } threads_array[threadId].heap_base = ret; return ret; } //////////////////////////////////////////////////////////////////// //800052D8 SYSCALL 062 RFU062_EndOfHeap //////////////////////////////////////////////////////////////////// void* _EndOfHeap() { return threads_array[threadId].heap_base; } //////////////////////////////////////////////////////////////////// //80005390 //////////////////////////////////////////////////////////////////// int __load_module(char *name, void (*entry)(void*), void *stack_res, int prio) { struct TCB *th; int index; int *ptr; struct rominfo ri; th = (struct TCB*)LL_unlink(&thread_ll_free); if (th) { threads_count++; index = (((u32)th-(u32)threads_array) * 0x286BCA1B)/4; } else { index = -1; } threadId = index; th->wakeupCount = 0; th->semaId = 0; th->attr = 0; th->stack_res = stack_res; th->option = 0; th->entry = entry; th->gpReg = 0; th->currentPriority = prio; th->status = THS_DORMANT; th->waitSema = 0; th->entry_ = entry; th->argc = 0; th->argstring = 0; th->initPriority = prio; thread_2_ready(index); if (romdirGetFile(name, &ri) == NULL) { __printf("# panic ! '%s' not found\n", name); _Exit(1); } if (ri.fileSize > 0) { int i; int *src = (int*)(0xbfc00000+ri.fileOffset); int *dst = (int*)entry; for (i=0; i 0 ) { int i; for(i = 0; i < argc; ++i) pbuf = strcpy(pbuf, argv[i]); } threads_array[threadId].argc = argc+2; threads_array[threadId].argstring = threadArgStrBuffer; _CancelWakeupThread(threadId); _iChangeThreadPriority(threadId, 0); // search for RESET // search for filename romdir entry if( romdirGetFile(filename, &ri) == NULL ) { __printf("# panic ! '%s' not found\n", filename); _Exit(); } // terminate threads curthreadid = 1; // skip main thread? curtcb = &threads_array[curthreadid]; while(curthreadid < 256) { if( curtcb->status && threadId != curthreadid ) { if( curtcb->status == THS_DORMANT ) { _DeleteThread(curthreadid); } else { iTerminateThread(curthreadid); _DeleteThread(curthreadid); } } ++curthreadid; ++curtcb; } _SemasInit(); threadStatus = 0; InitPgifHandler2(); Restart(); if( ri.fileSize > 0 ) { // copy to PS2_LOADADDR int i; u32* psrc = (u32*)(0xbfc00000+ri.fileOffset); u32* pdst = (u32*)PS2_LOADADDR; for(i = 0; i < ri.fileSize; i += 4) *pdst++ = *psrc++; } FlushInstructionCache(); FlushDataCache(); __asm__("mtc0 %0, $14\n" "sync\n" : : "r"(PS2_LOADADDR)); erase_cpu_regs(); __asm__("di\n" "eret\n"); } //////////////////////////////////////////////////////////////////// //800057E8 //////////////////////////////////////////////////////////////////// void* __ExecPS2(void * entry, void * gp, int argc, char ** argv) { char* pbuf = threadArgStrBuffer; int i; if( argc > 0 ) { for(i = 0; i < argc; ++i) pbuf = eestrcpy(pbuf, argv[i]); } threads_array[threadId].entry = entry; //0C threads_array[threadId].wakeupCount = 0; //24 threads_array[threadId].gpReg = gp; //14 threads_array[threadId].semaId = 0; //20 threads_array[threadId].argstring = threadArgStrBuffer; //38 threads_array[threadId].argc = argc; //34 threads_array[threadId].entry_ = entry; //30 threads_array[threadId].currentPriority = 0; //18 threads_array[threadId].waitSema = 0; //1C threads_array[threadId].initPriority = 0; FlushInstructionCache(); FlushDataCache(); return entry; } //////////////////////////////////////////////////////////////////// //800058E8 //////////////////////////////////////////////////////////////////// int _ExecOSD(int argc, char **argv) { return _LoadPS2Exe("rom0:OSDSYS", argc, argv); } //////////////////////////////////////////////////////////////////// //80005900 //////////////////////////////////////////////////////////////////// int _RFU004_Exit() { char *bb = "BootBrowser"; return _LoadPS2Exe("rom0:OSDSYS", 1, &bb); } //////////////////////////////////////////////////////////////////// //80005938 //////////////////////////////////////////////////////////////////// void releaseTCB(int tid) { threads_count--; threads_array[tid].status=0; LL_add(&thread_ll_free, (struct ll*)&threads_array[tid]); } //////////////////////////////////////////////////////////////////// //80005978 //////////////////////////////////////////////////////////////////// void unsetTCB(int tid) { if ((threads_array[tid].status) <= THS_READY) LL_unlinkthis((struct ll*)&threads_array[tid]); } //////////////////////////////////////////////////////////////////// //800059B8 //////////////////////////////////////////////////////////////////// void thread_2_ready(int tid) { threads_array[tid].status=THS_READY; if (threads_array[tid].initPriority < threadPrio) threadPrio=(short)threads_array[tid].initPriority; LL_add( &thread_ll_priorities[threads_array[tid].initPriority], (struct ll*)&threads_array[tid] ); } //////////////////////////////////////////////////////////////////// //80005A58 //////////////////////////////////////////////////////////////////// struct ll* LL_unlink(struct ll *l) { struct ll *p; if ((l==l->next) && (l==l->prev)) return 0; p=l->prev; p->prev->next=p->next; p->next->prev=p->prev; return p; } //////////////////////////////////////////////////////////////////// //80005A98 //////////////////////////////////////////////////////////////////// struct ll* LL_rotate(struct ll *l) { struct ll *p; if (p=LL_unlink(l)){ p->prev=l; p->next=l->next; l->next->prev=p; l->next=p; return l->prev; } return NULL; } //////////////////////////////////////////////////////////////////// //80005AE8 //////////////////////////////////////////////////////////////////// struct ll *LL_unlinkthis(struct ll *l) { l->prev->next=l->next; l->next->prev=l->prev; return l->next; } //////////////////////////////////////////////////////////////////// //80005B08 //////////////////////////////////////////////////////////////////// void LL_add(struct ll *l, struct ll *new) { new->prev=l; new->next=l->next; l->next->prev=new; l->next=new; } //////////////////////////////////////////////////////////////////// //80005B28 SYSCALL 9 (0x09) TlbWriteRandom //////////////////////////////////////////////////////////////////// int _TlbWriteRandom(u32 PageMask, u32 EntryHi, u32 EntryLo0, u32 EntryLo1) { if ((EntryHi >> 24) != 4) return -1; __asm__ ( "mfc0 $2, $1\n" "mtc0 $2, $0\n" "mtc0 $4, $5\n" "mtc0 $5, $10\n" "mtc0 $6, $2\n" "mtc0 $7, $3\n" "sync\n" "tlbwi\n" "sync\n" ); } int _sifGetMSFLG() { u32 msflg; for (;;) { msflg = SBUS_MSFLG; __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"); __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"); __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"); if (msflg == SBUS_MSFLG) return msflg; } } //////////////////////////////////////////////////////////////////// //80005E58 //////////////////////////////////////////////////////////////////// int _sifGetSMFLG() { u32 smflg; for (;;) { smflg = SBUS_SMFLG; __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"); __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"); __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"); if (smflg == SBUS_SMFLG) return smflg; } } int _ResetSif1() { sif1tagdata = 0xFFFF001E; //*(int*)0xa0001e330 = 0x20000000; //*(int*)0xa0001e334 = (u32)ptag&0x0fffffff; D6_QWC = 0; D6_TAG = (u32)&sif1tagdata&0x0fffffff; } //////////////////////////////////////////////////////////////////// //80006198 //////////////////////////////////////////////////////////////////// void SifDmaInit() { int msflg; memset(sifEEbuff, 0, sizeof(sifEEbuff)); memset(sifRegs, 0, sizeof(sifRegs)); *(u32*)0xB000F260 = 0xFF; D5_CHCR = 0; D6_CHCR = 0; _SifSetDChain(); *(u32*)0xB000F200 = (u32)sifEEbuff; __printf("MSFLG = 0x10000\n"); SBUS_MSFLG = 0x10000; msflg = SBUS_MSFLG; _ResetSif1(); _SifSetReg(1, 0); while (!(_SifGetReg(4) & 0x10000)) { __asm__ ("nop\nnop\nnop\nnop\n"); } sifIOPbuff = *(u32*)0xB000F210; SBUS_MSFLG = 0x20000; SBUS_MSFLG; } //////////////////////////////////////////////////////////////////// //800062A0 SYSCALL 120 (0x78) SifSetDChain //////////////////////////////////////////////////////////////////// void _SifSetDChain(){ int var_10; D5_CHCR = 0; D5_QWC = 0; D5_CHCR = 0x184; // 0001 1000 0100 var_10 = D5_CHCR; // read? } //////////////////////////////////////////////////////////////////// //800062D8 SYSCALL 107 (0x6B) SifStopDma //////////////////////////////////////////////////////////////////// void _SifStopDma(){ int var_10; D5_CHCR = 0; D5_QWC = 0; var_10 = D5_CHCR; // read? } //////////////////////////////////////////////////////////////////// //80006370 //////////////////////////////////////////////////////////////////// void _SifDmaSend(void *src, void *dest, int size, int attr, int id) { int qwc; struct TAG* t1; int *t3; int tocopy; if (((++tagindex) & 0xFF) == 31){ tagindex=0; transferscount++; } qwc=(size+15)/16; //rount up t1=(struct TAG*)KSEG1_ADDR(&tadrptr[tagindex]); if (attr & SIF_DMA_TAG) { t1->id_qwc = (id << 16) | qwc | ((attr & SIF_DMA_INT_I) ? 0x80000000 : 0); //IRQ t1->addr=(u32)src & 0x1FFFFFFF; t3=(int*)KSEG1_ADDR(src); qwc--; } else { if (qwc >= 8){ //two transfers tocopy=7; t1->id_qwc=0x30000008; //(id)REF | (qwc)8; t1->addr=(u32)&extrastorage[tagindex] | 0x1FFFFFFF; t3=(int*)KSEG1_ADDR(&extrastorage[tagindex]); if (((++tagindex) & 0xff) == 31){ tagindex=0; transferscount++; } t1=(struct TAG*)KSEG1_ADDR(&tadrptr[tagindex]); t1->id_qwc=(id << 16) | (qwc - 7) | ((attr & SIF_DMA_INT_I) ? 0x80000000 : 0);//IRQ t1->addr=(u32)(src+112) | 0x1FFFFFFF; } else { tocopy=qwc; t1->id_qwc=(id << 16) | (qwc+1) | ((attr & SIF_DMA_INT_I) ? 0x80000000 : 0);//IRQ t1->addr=(u32)&extrastorage[tagindex] & 0x1FFFFFFF; t3=(int*)KSEG1_ADDR(&extrastorage[tagindex]); } memcpy((char*)t3+16, (void*)KSEG1_ADDR(src), tocopy*16);//inline with qwords } t3[1]=qwc * 4; t3[0]=(u32)((u32)dest & 0x00FFFFFF) | ((((u32)(attr & SIF_DMA_INT_O)) ? 0x40000000 : 0) | (((u32)(attr & SIF_DMA_ERT)) ? 0x80000000 : 0)); } //////////////////////////////////////////////////////////////////// //800065C8 //////////////////////////////////////////////////////////////////// int _SifDmaCount() { register int count; count=((D6_TAG-(u32)tadrptr) & 0x1FFFFFFF) >> 4; count=count>0? count-1:30; if (count == tagindex) return (D6_QWC ? 30 : 31); if (count < tagindex) return count + 30 - tagindex; return count-tagindex-1; } //////////////////////////////////////////////////////////////////// //80006650 //////////////////////////////////////////////////////////////////// void _SifDmaPrepare(int count) { register struct TAG *t0; if (count==31) return; t0=(struct TAG*)KSEG1_ADDR(&tadrptr[tagindex]); if (count == 30){ t0->id_qwc &= DMA_TAG_IRQ|DMA_TAG_PCE; //keep PCE|REFE|IRQ t0->id_qwc |= DMA_TAG_REF<<28; t0->id_qwc |= D6_QWC; t0->addr = D6_MADR; D6_QWC = 0; D6_TAG = KUSEG_ADDR(t0); }else t0->id_qwc |= DMA_TAG_REF<<28; } //////////////////////////////////////////////////////////////////// //800066F8 SYSCALL 119 (0x77) SifSetDma //////////////////////////////////////////////////////////////////// u32 _SifSetDma(SifDmaTransfer_t *sdd, int len) { int var_10; int count, tmp; int i, c, _len = len; int nextindex; DMAC_ENABLEW = DMAC_ENABLER | 0x10000; //suspend D6_CHCR = 0; //kill any previous transfer?!? var_10 = D6_CHCR; // read? DMAC_ENABLEW = DMAC_ENABLER & ~0x10000; //enable count = _SifDmaCount(); lenloop: i=0; c=0; while (_len > 0) { if (!(sdd[i].attr & SIF_DMA_TAG)) { if (sdd[i].size <= 112) c++; else c+=2; } else c++; _len--; i++; } if (count < c) { count = 0; goto lenloop; } nextindex = ((tagindex+1) % 31) & 0xff; if (nextindex == 0) tmp = (transferscount + 1) & 0xFFFF; else tmp = transferscount; _SifDmaPrepare(count); while (len > 0) { _SifDmaSend(sdd->src, sdd->dest, sdd->size, sdd->attr, DMA_TAG_REF<<12);//REF >> 16 sdd++; len--; } _SifDmaSend(sdd->src, sdd->dest, sdd->size, sdd->attr, DMA_TAG_REFE<<12);//REFE >> 16 D6_CHCR|= 0x184; var_10 = D6_CHCR; // read? return (tmp<<16)|(nextindex<<8)|c; } //////////////////////////////////////////////////////////////////// //800068B0 SYSCALL 118 (0x76) SifDmaStat //////////////////////////////////////////////////////////////////// int _SifDmaStat(int id) { //TODO return 0; } //////////////////////////////////////////////////////////////////// //80006B60 SYSCALL 121 (0x79) SifSetDma //////////////////////////////////////////////////////////////////// int _SifSetReg(int reg, u32 val) { __printf("%s: reg=%d; val=%x\n", __FUNCTION__, reg, val); if (reg == 1) { *(u32*)0xB000F200 = val; return *(u32*)0xB000F200; } else if (reg == 3) { SBUS_MSFLG = val; return _sifGetMSFLG(); } else if (reg == 4) { SBUS_SMFLG = val; return _sifGetSMFLG(); } else if (reg >= 0) { return 0; } reg&= 0x7FFFFFFF; if (reg >= 32) return 0; sifRegs[reg] = val; return val; } //////////////////////////////////////////////////////////////////// //80006C18 SYSCALL 122 (0x7A) SifSetDma //////////////////////////////////////////////////////////////////// int _SifGetReg(int reg) { //__printf("%s: reg=%x\n", __FUNCTION__, reg); if (reg == 1) { return *(u32*)0xB000F200; } else if (reg == 2) { return *(u32*)0xB000F210; } else if (reg == 3) { return _sifGetMSFLG(); } else if (reg == 4) { return _sifGetSMFLG(); } else if (reg >= 0) { return 0; } reg&= 0x7FFFFFFF; if (reg >= 32) return 0; //__printf("ret=%x\n", sifRegs[reg]); return sifRegs[reg]; } //////////////////////////////////////////////////////////////////// //80007428 SYSCALL 117 print //////////////////////////////////////////////////////////////////// void _print() { } //////////////////////////////////////////////////////////////////// //800074D8 //////////////////////////////////////////////////////////////////// void _SetGsCrt2() { u32 tmp; tmp = *(int*)0x8001F344; if (tmp == 0x40 || tmp == 0x60 || tmp == 0x61) { *(char*)0xbf803218 = 0; *(char*)0xbf803218 = 2; return; } *(short*)0xbf801470 = 0; *(short*)0xbf801472 = 0; *(short*)0xbf801472 = 1; } //////////////////////////////////////////////////////////////////// //800076B0 //////////////////////////////////////////////////////////////////// void _iJoinThread(int param) { //TODO } //////////////////////////////////////////////////////////////////// //80008A60 //////////////////////////////////////////////////////////////////// void _SetGsCrt3(short arg0, short arg1, short arg2) { __printf("_SetGsCrt3 unimplemented\n"); } //////////////////////////////////////////////////////////////////// //80009CE0 //////////////////////////////////////////////////////////////////// void _SetGsCrt4(short arg0, short arg1, short arg2) { __printf("_SetGsCrt4 unimplemented\n"); } //////////////////////////////////////////////////////////////////// //8000A060 SYSCALL 002 SetGsCrt //////////////////////////////////////////////////////////////////// void _SetGsCrt(short arg0, short arg1, short arg2) { u64 val, val2; u64 tmp; int count; if (arg1 == 0) { tmp = (hvParam >> 3) & 0x7; tmp^= 0x2; if (tmp == 0) arg1 = 3; else arg1 = 2; } for (count=0x270f; count >= 0; count--) { __asm__ ("nop\nnop\nnop\nnop\nnop\nnop\n"); } *(int*)0x8001F344 = 0; if (arg1 == 2) { if (arg0 != 0) { val = 0x740834504LL; val2 = 0x740814504LL; tmp = (hvParam & 0x1) << 25; val|= tmp; val2|= tmp; GS_SMODE1 = val; GS_SYNCH1 = 0x7F5B61F06F040LL; GS_SYNCH2 = 0x33A4D8; GS_SYNCV = 0xC7800601A01801LL; GS_SMODE2 = (arg2 << 1) | 1; GS_SRFSH = 8; GS_SMODE1 = val2; } else { val = 0x740834504LL; val2 = 0x740814504LL; tmp = (hvParam & 0x2) << 35; val|= tmp; val2|= tmp; tmp = (hvParam & 0x1) << 25; val|= tmp; val2|= tmp; GS_SMODE1 = val; GS_SYNCH1 = 0x7F5B61F06F040LL; GS_SYNCH2 = 0x33A4D8; GS_SYNCV = 0xC7800601A01802LL; GS_SMODE2 = 0; GS_SRFSH = 8; GS_SMODE1 = val2; } _SetGsCrt2(); return; } if (arg1 == 3) { if (arg0 != 0) { val = 0x740836504LL; val2 = 0x740816504LL; tmp = (hvParam & 0x1) << 25; val|= tmp; val2|= tmp; GS_SMODE1 = val; GS_SYNCH1 = 0x7F5C21FC83030LL; GS_SYNCH2 = 0x3484BC; GS_SYNCV = 0xA9000502101401LL; GS_SMODE2 = (arg2 << 1) | 1; GS_SRFSH = 8; GS_SMODE1 = val2; } else { val = 0x740836504LL; val2 = 0x740816504LL; tmp = (hvParam & 0x2) << 35; val|= tmp; val2|= tmp; tmp = (hvParam & 0x1) << 25; val|= tmp; val2|= tmp; GS_SMODE1 = val; GS_SYNCH1 = 0x7F5C21F683030LL; GS_SYNCH2 = 0x3484BC; GS_SYNCV = 0xA9000502101404LL; GS_SMODE2 = 0; GS_SRFSH = 8; GS_SMODE1 = val2; } _SetGsCrt2(); return; } if (arg1 == 0x72) { if (arg0 != 0) { val = 0x740814504LL; val|= (hvParam & 0x1) << 25; GS_SYNCH1 = 0x7F5B61F06F040LL; GS_SYNCH2 = 0x33A4D8; GS_SYNCV = 0xC7800601A01801LL; GS_SMODE2 = (arg2 << 1) | 1; GS_SRFSH = 8; GS_SMODE1 = val; } else { val = 0x740814504LL; val|= (hvParam & 0x2) << 35; val|= (hvParam & 0x1) << 25; GS_SYNCH1 = 0x7F5B61F06F040LL; GS_SYNCH2 = 0x33A4D8; GS_SYNCV = 0xC7800601A01802LL; GS_SMODE2 = 0; GS_SRFSH = 8; GS_SMODE1 = val; } return; } if (arg1 == 0x73) { if (arg0 != 0) { val = 0x740816504LL; val|= (hvParam & 0x1) << 25; GS_SYNCH1 = 0x7F5C21FC83030LL; GS_SYNCH2 = 0x3484BC; GS_SYNCV = 0xA9000502101401LL; GS_SMODE2 = (arg2 << 1) | 1; GS_SRFSH = 8; GS_SMODE1 = val; } else { val = 0x740816504; val|= (hvParam & 0x2) << 35; val|= (hvParam & 0x1) << 25; GS_SYNCH1 = 0x7F5C21FC83030LL; GS_SYNCH2 = 0x3484BC; GS_SYNCV = 0xA9000502101404LL; GS_SMODE2 = 0; GS_SRFSH = 8; GS_SMODE1 = val; } return; } if ((u32)(arg1 - 26) >= 0x38) { _SetGsCrt3(arg0, arg1, arg2); return; } if (arg1 == 0x52) { _SetGsCrt3(arg0, arg1, arg2); return; } _SetGsCrt4(arg0, arg1, arg2); } //////////////////////////////////////////////////////////////////// //8000A768 SYSCALL 076 GetGsHParam //////////////////////////////////////////////////////////////////// void _GetGsHParam(int *p0, int *p1, int *p2, int *p3) { u32 _hvParam = (u32)hvParam; *p0 = _hvParam >> 12; *p1 = _hvParam >> 24; *p2 = _hvParam >> 18; *p3 = _hvParam >> 28; } //////////////////////////////////////////////////////////////////// //8000A7D0 SYSCALL 077 GetGsVParam //////////////////////////////////////////////////////////////////// int _GetGsVParam() { return hvParam & 0x3; } //////////////////////////////////////////////////////////////////// //8000A800 SYSCALL 059 JoinThread //////////////////////////////////////////////////////////////////// void _JoinThread() { _iJoinThread(0x87); } //////////////////////////////////////////////////////////////////// //8000A820 SYSCALL 078 SetGsHParam //////////////////////////////////////////////////////////////////// void _SetGsHParam(int a0, int a1, int a2, int a3) { __printf("SetGsHParam(%x,%x,%x,%x)... probably will never be supported\n", a0, a1, a2, a3); //write hvParam&1 to 12000010? } //////////////////////////////////////////////////////////////////// //8000A8F8 SYSCALL 079 SetGsVParam //////////////////////////////////////////////////////////////////// void _SetGsVParam(int VParam) { hvParam&= ~0x1; hvParam|= VParam & 0x1; } //////////////////////////////////////////////////////////////////// //8000A920 SYSCALL 075 GetOsdConfigParam //////////////////////////////////////////////////////////////////// void _GetOsdConfigParam(int *result) { *result= (*result & 0xFFFFFFFE) | (osdConfigParam & 1); *result= (*result & 0xFFFFFFF9) | (osdConfigParam & 6); *result= (*result & 0xFFFFFFF7) | (osdConfigParam & 8); *result= (*result & 0xFFFFFFEF) | (osdConfigParam & 0x10); *result=((*result & 0xFFFFE01F) | (osdConfigParam & 0x1FE0)) & 0xFFFF1FFF; ((u16*)result)[1]=((u16*)&osdConfigParam)[1]; } //////////////////////////////////////////////////////////////////// //8000A9C0 SYSCALL 074 SetOsdConfigParam //////////////////////////////////////////////////////////////////// void _SetOsdConfigParam(int *param) { osdConfigParam= (osdConfigParam & 0xFFFFFFFE) | (*param & 1); osdConfigParam= (osdConfigParam & 0xFFFFFFF9) | (*param & 6); osdConfigParam= (osdConfigParam & 0xFFFFFFF7) | (*param & 8); osdConfigParam= (osdConfigParam & 0xFFFFFFEF) | (*param & 0x10); osdConfigParam=((osdConfigParam & 0xFFFFE01F) | (*param & 0x1FE0)) & 0xFFFF1FFF; ((u16*)&osdConfigParam)[1]=((u16*)param)[1]; } //////////////////////////////////////////////////////////////////// //8000FCE8 //////////////////////////////////////////////////////////////////// void __exhandler(int a0) { } //////////////////////////////////////////////////////////////////// //80010F34 //////////////////////////////////////////////////////////////////// void __disableInterrupts() { __asm__("mtc0 $0, $25\n" "mtc0 $0, $24\n" "li $3, 0xFFFFFFE0\n" "mfc0 $2, $12\n" "and $2, $3\n" "mtc0 $2, $12\n" "sync\n"); } //////////////////////////////////////////////////////////////////// //80010F58 //////////////////////////////////////////////////////////////////// void kSaveContext() { } //////////////////////////////////////////////////////////////////// //80011030 //////////////////////////////////////////////////////////////////// void kLoadContext() { } //////////////////////////////////////////////////////////////////// //800110F4 //////////////////////////////////////////////////////////////////// void kLoadDebug() { kLoadContext(); // lq $31, 0x1F0($27) // lq $27, 0x1B0($27) // j 80005020 - probably load debug services or restore prev program state } //////////////////////////////////////////////////////////////////// //80011108 //////////////////////////////////////////////////////////////////// int __exception() { register u32 curepc __asm__("$2"); int ret; __asm__("mfc0 %0, $14\n" : "=r"(curepc) : ); // check if epc is currently in the except handlers: // _Deci2Handler, __exception1, and __exception if (curepc >= (u32)__exception && curepc < (u32)__exception+0x300) { __asm__("mfc0 %0, $13\n" : "=r"(ret) : ); return (ret & 0x7C) >> 2; } kSaveContext(); __disableInterrupts(); __exhandler(1); kLoadContext(); __asm__("eret\n"); } //////////////////////////////////////////////////////////////////// //800111F0 //////////////////////////////////////////////////////////////////// void __exception1() { kSaveContext(); __disableInterrupts(); //sub_8000CF68 kLoadContext(); __asm__("eret\n"); }