diff --git a/arm11u/source/main.c b/arm11u/source/main.c index f05288b..b28cac4 100644 --- a/arm11u/source/main.c +++ b/arm11u/source/main.c @@ -9,52 +9,25 @@ #include #include "costable.h" -Handle APTevents[2]; -Handle aptLockHandle; - -void aptInit() -{ - Handle aptuHandle; - - //initialize APT stuff, escape load screen - srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); - APT_GetLockHandle(aptuHandle, 0x0, &aptLockHandle); - svc_closeHandle(aptuHandle); - - svc_waitSynchronization1(aptLockHandle, U64_MAX); //APT lock handle is used because we need to wait for NS to be ready for us - srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); - APT_Initialize(aptuHandle, APPID_APPLICATION, &APTevents[0], &APTevents[1]); - svc_closeHandle(aptuHandle); - svc_releaseMutex(aptLockHandle); //release the lock - - svc_waitSynchronization1(aptLockHandle, U64_MAX); - srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); - APT_Enable(aptuHandle, 0x0); - svc_closeHandle(aptuHandle); - svc_releaseMutex(aptLockHandle); -} - u8* gspHeap; u32* gxCmdBuf; -Handle gspGpuHandle; u8 currentBuffer; u8* topLeftFramebuffers[2]; void gspGpuInit() { - //do stuff with GPU... - srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu"); + gspInit(); - GSPGPU_AcquireRight(gspGpuHandle, 0x0); - GSPGPU_SetLcdForceBlack(gspGpuHandle, 0x0); + GSPGPU_AcquireRight(NULL, 0x0); + GSPGPU_SetLcdForceBlack(NULL, 0x0); //set subscreen to blue u32 regData=0x01FF0000; - GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4); + GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); //grab main left screen framebuffer addresses - GSPGPU_ReadHWRegs(gspGpuHandle, 0x400468, (u8*)&topLeftFramebuffers, 8); + GSPGPU_ReadHWRegs(NULL, 0x400468, (u8*)&topLeftFramebuffers, 8); //convert PA to VA (assuming FB in VRAM) topLeftFramebuffers[0]+=0x7000000; @@ -64,7 +37,7 @@ void gspGpuInit() u8 threadID; Handle gspEvent, gspSharedMemHandle; svc_createEvent(&gspEvent, 0x0); - GSPGPU_RegisterInterruptRelayQueue(gspGpuHandle, gspEvent, 0x1, &gspSharedMemHandle, &threadID); + GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID); svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); //map GSP heap @@ -82,10 +55,10 @@ void gspGpuInit() void swapBuffers() { u32 regData; - GSPGPU_ReadHWRegs(gspGpuHandle, 0x400478, (u8*)®Data, 4); + GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)®Data, 4); regData^=1; currentBuffer=regData&1; - GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)®Data, 4); + GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)®Data, 4); } void copyBuffer() @@ -93,7 +66,7 @@ void copyBuffer() //copy topleft FB u8 copiedBuffer=currentBuffer^1; u8* bufAdr=&gspHeap[0x46500*copiedBuffer]; - GSPGPU_FlushDataCache(gspGpuHandle, bufAdr, 0x46500); + GSPGPU_FlushDataCache(NULL, bufAdr, 0x46500); //GX RequestDma u32 gxCommand[0x8]; gxCommand[0]=0x00; //CommandID @@ -102,7 +75,7 @@ void copyBuffer() gxCommand[3]=0x46500; //size gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; - GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, gspGpuHandle); + GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, NULL); } s32 pcCos(u16 v) @@ -143,6 +116,8 @@ int main() HIDUSER_Init(hidHandle); + aptSetupEventHandler(); + while(1) { u32 PAD=((u32*)0x10000000)[7]; @@ -150,7 +125,7 @@ int main() swapBuffers(); copyBuffer(); u32 regData=PAD|0x01000000; - GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4); + GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); svc_sleepThread(1000000000); } diff --git a/libctru/include/ctr/APT.h b/libctru/include/ctr/APT.h index c5dfc0d..32feef6 100644 --- a/libctru/include/ctr/APT.h +++ b/libctru/include/ctr/APT.h @@ -8,14 +8,22 @@ typedef enum{ APPID_APPLICATION = 0x300, // Application }NS_APPID; // cf http://3dbrew.org/wiki/NS#AppIDs -Result APT_GetLockHandle(Handle handle, u16 flags, Handle* lockHandle); -Result APT_Initialize(Handle handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2); -Result APT_Enable(Handle handle, u32 a); -Result APT_PrepareToJumpToHomeMenu(Handle handle); -Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c); -Result APT_InquireNotification(Handle handle, u32 appID, u8* signalType); -Result APT_NotifyToWait(Handle handle, NS_APPID appID); -Result APT_GlanceParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize); -Result APT_ReceiveParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize); +extern Handle aptEvents[3]; + +void aptInit(); +void aptOpenSession(); +void aptCloseSession(); +void aptSetupEventHandler(); + +Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle); +Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2); +Result APT_Enable(Handle* handle, u32 a); +Result APT_PrepareToJumpToHomeMenu(Handle* handle); +Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c); +Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType); +Result APT_NotifyToWait(Handle* handle, NS_APPID appID); +Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2); +Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize); +Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize); #endif diff --git a/libctru/include/ctr/GSP.h b/libctru/include/ctr/GSP.h index e713132..154e046 100644 --- a/libctru/include/ctr/GSP.h +++ b/libctru/include/ctr/GSP.h @@ -1,13 +1,16 @@ #ifndef GSP_H #define GSP_H -Result GSPGPU_AcquireRight(Handle handle, u8 flags); -Result GSPGPU_SetLcdForceBlack(Handle handle, u8 flags); -Result GSPGPU_FlushDataCache(Handle handle, u8* adr, u32 size); -Result GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size); -Result GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size); -Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID); -Result GSPGPU_TriggerCmdReqQueue(Handle handle); -Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x20], Handle handle); +void gspInit(); + +Result GSPGPU_AcquireRight(Handle *handle, u8 flags); +Result GSPGPU_ReleaseRight(Handle *handle); +Result GSPGPU_SetLcdForceBlack(Handle *handle, u8 flags); +Result GSPGPU_FlushDataCache(Handle *handle, u8* adr, u32 size); +Result GSPGPU_WriteHWRegs(Handle *handle, u32 regAddr, u8* data, u8 size); +Result GSPGPU_ReadHWRegs(Handle *handle, u32 regAddr, u8* data, u8 size); +Result GSPGPU_RegisterInterruptRelayQueue(Handle *handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID); +Result GSPGPU_TriggerCmdReqQueue(Handle *handle); +Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x20], Handle* handle); #endif diff --git a/libctru/include/ctr/svc.h b/libctru/include/ctr/svc.h index 30e9b57..dbf3a1e 100644 --- a/libctru/include/ctr/svc.h +++ b/libctru/include/ctr/svc.h @@ -4,6 +4,8 @@ u32* getThreadCommandBuffer(void); void svc_exitProcess(void); + Result svc_createThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stacktop, s32 threadpriority, s32 processorid); + void svc_exitThread(); void svc_sleepThread(s64 ns); Result svc_releaseMutex(Handle handle); Result svc_controlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions); //(outaddr is usually the same as the input addr0) diff --git a/libctru/include/ctr/types.h b/libctru/include/ctr/types.h index a6832e1..70f2688 100644 --- a/libctru/include/ctr/types.h +++ b/libctru/include/ctr/types.h @@ -30,5 +30,6 @@ typedef u32 Handle; typedef s32 Result; + typedef void (*ThreadFunc)(u32); #endif diff --git a/libctru/source/APT.c b/libctru/source/APT.c index d1e87e4..57c24e1 100644 --- a/libctru/source/APT.c +++ b/libctru/source/APT.c @@ -2,32 +2,161 @@ #include #include #include +#include #include +#include #include -Result APT_GetLockHandle(Handle handle, u16 flags, Handle* lockHandle) +#define APT_HANDLER_STACKSIZE (0x10000) + +Handle aptLockHandle; +Handle aptuHandle; +Handle aptEvents[3]; + +Handle aptEventHandlerThread; +u64 aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]; //u64 so that it's 8-byte aligned + +u32 aptParameters[0x1000/4]; //TEMP + +void aptEventHandler(u32 arg) { + bool runThread=true; + while(runThread) + { + s32 syncedID=0x0; + svc_waitSynchronizationN(&syncedID, aptEvents, 2, 0, U64_MAX); + svc_clearEvent(aptEvents[syncedID]); + + switch(syncedID) + { + case 0x0: //event 0 means we got a signal from NS (home button, power button etc) + { + u8 signalType; + + aptOpenSession(); + APT_InquireNotification(NULL, APPID_APPLICATION, &signalType); //check signal type + aptCloseSession(); + + switch(signalType) + { + case 0x1: //home menu button got pressed + aptOpenSession(); + APT_PrepareToJumpToHomeMenu(NULL); //prepare for return to menu + aptCloseSession(); + + GSPGPU_ReleaseRight(NULL); //disable GSP module access + + aptOpenSession(); + APT_JumpToHomeMenu(NULL, 0x0, 0x0, 0x0); //jump ! + aptCloseSession(); + break; + } + } + break; + case 0x1: //event 1 means app just started or we're returning to app + { + aptOpenSession(); + APT_ReceiveParameter(NULL, APPID_APPLICATION, 0x1000, aptParameters, NULL); + aptCloseSession(); + + // if(!draw)GSPGPU_AcquireRight(NULL, 0x0); + } + break; + case 0x2: //event 2 means we should exit the thread + runThread=false; + break; + } + } + svc_exitThread(); +} + +void aptInit() +{ + //initialize APT stuff, escape load screen + srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); + APT_GetLockHandle(&aptuHandle, 0x0, &aptLockHandle); + svc_closeHandle(aptuHandle); + + aptOpenSession(); + APT_Initialize(NULL, APPID_APPLICATION, &aptEvents[0], &aptEvents[1]); + aptCloseSession(); + + aptOpenSession(); + APT_Enable(NULL, 0x0); + aptCloseSession(); + + aptOpenSession(); + APT_NotifyToWait(NULL, APPID_APPLICATION); + aptCloseSession(); +} + +void aptSetupEventHandler() +{ + u8 buf1[4], buf2[4]; + + buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; buf1[3]=0x04; + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2); + aptCloseSession(); + + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + + buf1[0]=0x13; buf1[1]=0x00; buf1[2]=0x10; buf1[3]=0x00; + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2); + aptCloseSession(); + + aptOpenSession(); + APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2); + aptCloseSession(); + + //create thread for stuff handling APT events + svc_createThread(&aptEventHandlerThread, aptEventHandler, 0x0, (u32*)(&aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]), 0x31, 0xfffffffe); +} + +void aptOpenSession() +{ + svc_waitSynchronization1(aptLockHandle, U64_MAX); + srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); +} + +void aptCloseSession() +{ + svc_closeHandle(aptuHandle); + svc_releaseMutex(aptLockHandle); +} + +Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle) +{ + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x10040; //request header code cmdbuf[1]=flags; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; if(lockHandle)*lockHandle=cmdbuf[5]; return cmdbuf[1]; } -Result APT_Initialize(Handle handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2) +Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x20080; //request header code cmdbuf[1]=appId; cmdbuf[2]=0x0; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; if(eventHandle1)*eventHandle1=cmdbuf[3]; //return to menu event ? if(eventHandle2)*eventHandle2=cmdbuf[4]; @@ -35,45 +164,49 @@ Result APT_Initialize(Handle handle, NS_APPID appId, Handle* eventHandle1, Handl return cmdbuf[1]; } -Result APT_Enable(Handle handle, u32 a) +Result APT_Enable(Handle* handle, u32 a) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x30040; //request header code cmdbuf[1]=a; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result APT_InquireNotification(Handle handle, u32 appID, u8* signalType) +Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0xB0040; //request header code cmdbuf[1]=appID; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; if(signalType)*signalType=cmdbuf[2]; return cmdbuf[1]; } -Result APT_PrepareToJumpToHomeMenu(Handle handle) +Result APT_PrepareToJumpToHomeMenu(Handle* handle) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x2b0000; //request header code Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c) +Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x2C0044; //request header code cmdbuf[1]=a; @@ -82,25 +215,49 @@ Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c) cmdbuf[4]=(b<<14)|2; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result APT_NotifyToWait(Handle handle, NS_APPID appID) +Result APT_NotifyToWait(Handle* handle, NS_APPID appID) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x430040; //request header code cmdbuf[1]=appID; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result APT_GlanceParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize) +Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2) { + if(!handle)handle=&aptuHandle; + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x4B00C2; //request header code + cmdbuf[1]=a; + cmdbuf[2]=size1; + cmdbuf[3]=size2; + cmdbuf[4]=(size1<<14)|0x402; + cmdbuf[5]=(u32)buf1; + + cmdbuf[0+0x100/4]=(size2<<14)|2; + cmdbuf[1+0x100/4]=(u32)buf2; + + Result ret=0; + if((ret=svc_sendSyncRequest(*handle)))return ret; + + if(out)*out=cmdbuf[2]; + + return cmdbuf[1]; +} + +Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize) +{ + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0xE0080; //request header code cmdbuf[1]=appID; @@ -110,15 +267,16 @@ Result APT_GlanceParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* b cmdbuf[1+0x100/4]=(u32)buffer; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; if(actualSize)*actualSize=cmdbuf[4]; return cmdbuf[1]; } -Result APT_ReceiveParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize) +Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize) { + if(!handle)handle=&aptuHandle; u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0xD0080; //request header code cmdbuf[1]=appID; @@ -128,7 +286,7 @@ Result APT_ReceiveParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* cmdbuf[1+0x100/4]=(u32)buffer; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; if(actualSize)*actualSize=cmdbuf[4]; diff --git a/libctru/source/GSP.c b/libctru/source/GSP.c index 5499b25..9375b6f 100644 --- a/libctru/source/GSP.c +++ b/libctru/source/GSP.c @@ -5,9 +5,18 @@ #include #include +Handle gspGpuHandle; -Result GSPGPU_AcquireRight(Handle handle, u8 flags) +void gspInit() { + //do stuff with GPU... + srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu"); +} + +Result GSPGPU_AcquireRight(Handle* handle, u8 flags) +{ + if(!handle)handle=&gspGpuHandle; + u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x160042; //request header code cmdbuf[1]=flags; @@ -15,25 +24,42 @@ Result GSPGPU_AcquireRight(Handle handle, u8 flags) cmdbuf[3]=0xffff8001; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result GSPGPU_SetLcdForceBlack(Handle handle, u8 flags) +Result GSPGPU_ReleaseRight(Handle* handle) { + if(!handle)handle=&gspGpuHandle; + + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x170000; //request header code + + Result ret=0; + if((ret=svc_sendSyncRequest(*handle)))return ret; + + return cmdbuf[1]; +} + +Result GSPGPU_SetLcdForceBlack(Handle* handle, u8 flags) +{ + if(!handle)handle=&gspGpuHandle; + u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0xB0040; //request header code cmdbuf[1]=flags; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result GSPGPU_FlushDataCache(Handle handle, u8* adr, u32 size) +Result GSPGPU_FlushDataCache(Handle* handle, u8* adr, u32 size) { + if(!handle)handle=&gspGpuHandle; + u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x80082; //request header code cmdbuf[1]=(u32)adr; @@ -42,13 +68,15 @@ Result GSPGPU_FlushDataCache(Handle handle, u8* adr, u32 size) cmdbuf[4]=0xffff8001; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size) +Result GSPGPU_WriteHWRegs(Handle* handle, u32 regAddr, u8* data, u8 size) { + if(!handle)handle=&gspGpuHandle; + if(size>0x80 || !data)return -1; u32* cmdbuf=getThreadCommandBuffer(); @@ -59,13 +87,15 @@ Result GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size) cmdbuf[4]=(u32)data; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size) +Result GSPGPU_ReadHWRegs(Handle* handle, u32 regAddr, u8* data, u8 size) { + if(!handle)handle=&gspGpuHandle; + if(size>0x80 || !data)return -1; u32* cmdbuf=getThreadCommandBuffer(); @@ -76,13 +106,15 @@ Result GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size) cmdbuf[0x40+1]=(u32)data; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } -Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID) +Result GSPGPU_RegisterInterruptRelayQueue(Handle* handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID) { + if(!handle)handle=&gspGpuHandle; + u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0x130042; //request header code cmdbuf[1]=flags; @@ -90,7 +122,7 @@ Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 cmdbuf[3]=eventHandle; Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; if(threadID)*threadID=cmdbuf[2]; if(outMemHandle)*outMemHandle=cmdbuf[4]; @@ -98,13 +130,15 @@ Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 return cmdbuf[1]; } -Result GSPGPU_TriggerCmdReqQueue(Handle handle) +Result GSPGPU_TriggerCmdReqQueue(Handle* handle) { + if(!handle)handle=&gspGpuHandle; + u32* cmdbuf=getThreadCommandBuffer(); cmdbuf[0]=0xC0000; //request header code Result ret=0; - if((ret=svc_sendSyncRequest(handle)))return ret; + if((ret=svc_sendSyncRequest(*handle)))return ret; return cmdbuf[1]; } @@ -112,7 +146,7 @@ Result GSPGPU_TriggerCmdReqQueue(Handle handle) //essentially : get commandIndex and totalCommands, calculate offset of new command, copy command and update totalCommands //use LDREX/STREX because this data may also be accessed by the GSP module and we don't want to break stuff //(mostly, we could overwrite the buffer header with wrong data and make the GSP module reexecute old commands) -Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8], Handle handle) +Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8], Handle* handle) { if(!sharedGspCmdBuf || !gxCommand)return -1; diff --git a/libctru/source/svc.s b/libctru/source/svc.s index ff6f4a3..f5e5ffc 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -14,13 +14,12 @@ getThreadCommandBuffer: .type svc_controlMemory, %function svc_controlMemory: stmfd sp!, {r0, r4} - ldr R0, [sp, #0x8] + ldr r0, [sp, #0x8] ldr r4, [sp, #0x8+0x4] svc 0x01 - ldr r2, [sp] + ldr r2, [sp], #4 str r1, [r2] - ldr r4, [sp, #4]! - add sp, sp, #4 + ldr r4, [sp], #4 bx lr .global svc_exitProcess @@ -29,6 +28,24 @@ svc_exitProcess: svc 0x03 bx lr +.global svc_createThread +.type svc_createThread, %function +svc_createThread: + stmfd sp!, {r0, r4} + ldr r0, [sp, #0x8] + ldr r4, [sp, #0x8+0x4] + svc 0x08 + ldr r2, [sp], #4 + str r1, [r2] + ldr r4, [sp], #4 + bx lr + +.global svc_exitThread +.type svc_exitThread, %function +svc_exitThread: + svc 0x09 + bx lr + .global svc_sleepThread .type svc_sleepThread, %function svc_sleepThread: diff --git a/sdmc/source/main.c b/sdmc/source/main.c index cac0c30..74c6bb8 100644 --- a/sdmc/source/main.c +++ b/sdmc/source/main.c @@ -10,52 +10,25 @@ #include #include "costable.h" -Handle APTevents[2]; -Handle aptLockHandle; - -void aptInit() -{ - Handle aptuHandle; - - //initialize APT stuff, escape load screen - srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); - APT_GetLockHandle(aptuHandle, 0x0, &aptLockHandle); - svc_closeHandle(aptuHandle); - - svc_waitSynchronization1(aptLockHandle, U64_MAX); - srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); - APT_Initialize(aptuHandle, APPID_APPLICATION, &APTevents[0], &APTevents[1]); - svc_closeHandle(aptuHandle); - svc_releaseMutex(aptLockHandle); - - svc_waitSynchronization1(aptLockHandle, U64_MAX); - srv_getServiceHandle(NULL, &aptuHandle, "APT:U"); - APT_Enable(aptuHandle, 0x0); - svc_closeHandle(aptuHandle); - svc_releaseMutex(aptLockHandle); -} - u8* gspHeap; u32* gxCmdBuf; -Handle gspGpuHandle; u8 currentBuffer; u8* topLeftFramebuffers[2]; void gspGpuInit() { - //do stuff with GPU... - srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu"); + gspInit(); - GSPGPU_AcquireRight(gspGpuHandle, 0x0); - GSPGPU_SetLcdForceBlack(gspGpuHandle, 0x0); + GSPGPU_AcquireRight(NULL, 0x0); + GSPGPU_SetLcdForceBlack(NULL, 0x0); //set subscreen to blue u32 regData=0x01FF0000; - GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4); + GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); //grab main left screen framebuffer addresses - GSPGPU_ReadHWRegs(gspGpuHandle, 0x400468, (u8*)&topLeftFramebuffers, 8); + GSPGPU_ReadHWRegs(NULL, 0x400468, (u8*)&topLeftFramebuffers, 8); //convert PA to VA (assuming FB in VRAM) topLeftFramebuffers[0]+=0x7000000; @@ -65,7 +38,7 @@ void gspGpuInit() u8 threadID; Handle gspEvent, gspSharedMemHandle; svc_createEvent(&gspEvent, 0x0); - GSPGPU_RegisterInterruptRelayQueue(gspGpuHandle, gspEvent, 0x1, &gspSharedMemHandle, &threadID); + GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID); svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); //map GSP heap @@ -83,10 +56,10 @@ void gspGpuInit() void swapBuffers() { u32 regData; - GSPGPU_ReadHWRegs(gspGpuHandle, 0x400478, (u8*)®Data, 4); + GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)®Data, 4); regData^=1; currentBuffer=regData&1; - GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)®Data, 4); + GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)®Data, 4); } void copyBuffer() @@ -94,7 +67,7 @@ void copyBuffer() //copy topleft FB u8 copiedBuffer=currentBuffer^1; u8* bufAdr=&gspHeap[0x46500*copiedBuffer]; - GSPGPU_FlushDataCache(gspGpuHandle, bufAdr, 0x46500); + GSPGPU_FlushDataCache(NULL, bufAdr, 0x46500); //GX RequestDma u32 gxCommand[0x8]; gxCommand[0]=0x00; //CommandID @@ -103,7 +76,7 @@ void copyBuffer() gxCommand[3]=0x46500; //size gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; - GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, gspGpuHandle); + GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, NULL); } s32 pcCos(u16 v) @@ -156,6 +129,8 @@ int main() FSUSER_OpenFileDirectly(fsuHandle, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSFILE_Read(fileHandle, &bytesRead, 0x0, (u32*)gspHeap, 0x46500); + aptSetupEventHandler(); + while(1) { u32 PAD=((u32*)0x10000000)[7]; @@ -163,7 +138,7 @@ int main() swapBuffers(); copyBuffer(); u32 regData=PAD|0x01000000; - GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4); + GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); svc_sleepThread(1000000000); }