diff --git a/arm11u/source/main.c b/arm11u/source/main.c index 1cfed16..74fe520 100644 --- a/arm11u/source/main.c +++ b/arm11u/source/main.c @@ -15,6 +15,8 @@ u32* gxCmdBuf; u8 currentBuffer; u8* topLeftFramebuffers[2]; +Handle gspEvent, gspSharedMemHandle; + void gspGpuInit() { gspInit(); @@ -35,7 +37,6 @@ void gspGpuInit() //setup our gsp shared mem section u8 threadID; - Handle gspEvent, gspSharedMemHandle; svc_createEvent(&gspEvent, 0x0); GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID); svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); @@ -52,6 +53,21 @@ void gspGpuInit() currentBuffer=0; } +void gspGpuExit() +{ + GSPGPU_UnregisterInterruptRelayQueue(NULL); + + //unmap GSP shared mem + svc_unmapMemoryBlock(gspSharedMemHandle, 0x10002000); + svc_closeHandle(gspSharedMemHandle); + svc_closeHandle(gspEvent); + + gspExit(); + + //free GSP heap + svc_controlMemory((u32*)&gspHeap, (u32)gspHeap, 0x0, 0x2000000, MEMOP_FREE, 0x0); +} + void swapBuffers() { u32 regData; @@ -83,6 +99,8 @@ s32 pcCos(u16 v) return costable[v&0x1FF]; } +u32 cnt; + void renderEffect() { u8* bufAdr=&gspHeap[0x46500*currentBuffer]; @@ -93,11 +111,31 @@ void renderEffect() for(j=1;j<240;j++) { u32 v=(j+i*240)*3; - bufAdr[v]=(pcCos(i)+4096)/32; - bufAdr[v+1]=0x00; - bufAdr[v+2]=0xFF*currentBuffer; + bufAdr[v]=(pcCos(i+cnt)+4096)/32; + bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64; + bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32; } } + cnt++; +} + +Handle hidHandle; +Handle hidMemHandle; + +void hidInit() +{ + srv_getServiceHandle(NULL, &hidHandle, "hid:USER"); + HIDUSER_GetInfo(hidHandle, &hidMemHandle); + svc_mapMemoryBlock(hidMemHandle, 0x10000000, 0x1, 0x10000000); + + HIDUSER_Init(hidHandle); +} + +void hidExit() +{ + svc_unmapMemoryBlock(hidMemHandle, 0x10000000); + svc_closeHandle(hidMemHandle); + svc_closeHandle(hidHandle); } int main() @@ -108,27 +146,29 @@ int main() gspGpuInit(); - Handle hidHandle; - Handle hidMemHandle; - srv_getServiceHandle(NULL, &hidHandle, "hid:USER"); - HIDUSER_GetInfo(hidHandle, &hidMemHandle); - svc_mapMemoryBlock(hidMemHandle, 0x10000000, 0x1, 0x10000000); - - HIDUSER_Init(hidHandle); + hidInit(); aptSetupEventHandler(); - while(!aptGetStatus()) + APP_STATUS status; + while((status=aptGetStatus())!=APP_EXITING) { - u32 PAD=((u32*)0x10000000)[7]; - renderEffect(); - swapBuffers(); - copyBuffer(); - u32 regData=PAD|0x01000000; - GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); - svc_sleepThread(1000000000); + if(status==APP_RUNNING) + { + u32 PAD=((u32*)0x10000000)[7]; + + u32 regData=PAD|0x01000000; + GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); + + renderEffect(); + swapBuffers(); + copyBuffer(); + } + svc_sleepThread(16666666); } + hidExit(); + gspGpuExit(); aptExit(); svc_exitProcess(); return 0; diff --git a/libctru/include/ctr/FS.h b/libctru/include/ctr/FS.h index e84e830..cc9f65b 100644 --- a/libctru/include/ctr/FS.h +++ b/libctru/include/ctr/FS.h @@ -41,6 +41,7 @@ Result FSUSER_OpenArchive(Handle handle, FS_archive* archive); Result FSUSER_OpenDirectory(Handle handle, Handle* out, FS_archive archive, FS_path dirLowPath); Result FSUSER_OpenFile(Handle handle, Handle* out, FS_archive archive, FS_path fileLowPath, u32 openflags, u32 attributes); Result FSUSER_OpenFileDirectly(Handle handle, Handle* out, FS_archive archive, FS_path fileLowPath, u32 openflags, u32 attributes); +Result FSUSER_CloseArchive(Handle handle, FS_archive* archive); Result FSFILE_Close(Handle handle); Result FSFILE_Read(Handle handle, u32 *bytesRead, u64 offset, u32 *buffer, u32 size); @@ -48,5 +49,6 @@ Result FSFILE_Write(Handle handle, u32 *bytesWritten, u64 offset, u32 *buffer, u Result FSFILE_GetSize(Handle handle, u64 *size); Result FSDIR_Read(Handle handle, u32 *entriesRead, u32 entrycount, u16 *buffer); +Result FSDIR_Close(Handle handle); #endif diff --git a/libctru/include/ctr/GSP.h b/libctru/include/ctr/GSP.h index 154e046..3f95dfc 100644 --- a/libctru/include/ctr/GSP.h +++ b/libctru/include/ctr/GSP.h @@ -2,6 +2,7 @@ #define GSP_H void gspInit(); +void gspExit(); Result GSPGPU_AcquireRight(Handle *handle, u8 flags); Result GSPGPU_ReleaseRight(Handle *handle); @@ -10,6 +11,7 @@ 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_UnregisterInterruptRelayQueue(Handle* handle); Result GSPGPU_TriggerCmdReqQueue(Handle *handle); Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x20], Handle* handle); diff --git a/libctru/include/ctr/srv.h b/libctru/include/ctr/srv.h index 0796a14..2ff4aa7 100644 --- a/libctru/include/ctr/srv.h +++ b/libctru/include/ctr/srv.h @@ -2,6 +2,7 @@ #define SRV_H Result initSrv(); +Result exitSrv(); Result srv_Initialize(Handle* handleptr); Result srv_getServiceHandle(Handle* handleptr, Handle* out, char* server); diff --git a/libctru/include/ctr/svc.h b/libctru/include/ctr/svc.h index e66fe78..e28cade 100644 --- a/libctru/include/ctr/svc.h +++ b/libctru/include/ctr/svc.h @@ -1,6 +1,19 @@ #ifndef SVC_H #define SVC_H +typedef enum{ + MEMOP_FREE = 1, + MEMOP_RESERVE = 2, + MEMOP_COMMIT = 3, + MEMOP_MAP = 4, + MEMOP_UNMAP = 5, + MEMOP_PROTECT = 6, + MEMOP_REGION_APP = 0x100, + MEMOP_REGION_SYSTEM = 0x200, + MEMOP_REGION_BASE = 0x300, + MEMOP_LINEAR = 0x1000, +}MEMORY_OPERATION; + u32* getThreadCommandBuffer(void); Result svc_controlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions); //(outaddr is usually the same as the input addr0) @@ -14,9 +27,11 @@ Result svc_clearEvent(Handle handle); Result svc_createMemoryBlock(Handle* memblock, u32 addr, u32 size, u32 mypermission, u32 otherpermission); Result svc_mapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission); + Result svc_unmapMemoryBlock(Handle memblock, u32 addr); Result svc_waitSynchronization1(Handle handle, s64 nanoseconds); Result svc_waitSynchronizationN(s32* out, Handle* handles, s32 handlecount, bool waitAll, s64 nanoseconds); Result svc_closeHandle(Handle handle); + Result svc_getSystemInfo(s64* out, u32 type, s32 param); Result svc_connectToPort(volatile Handle* out, const char* portName); Result svc_sendSyncRequest(Handle session); diff --git a/libctru/source/APT.c b/libctru/source/APT.c index e533fce..e02a380 100644 --- a/libctru/source/APT.c +++ b/libctru/source/APT.c @@ -86,7 +86,7 @@ void aptEventHandler(u32 arg) } } break; - case 0x2: //event 2 means we should exit the thread + case 0x2: //event 2 means we should exit the thread (event will be added later) runThread=false; break; } @@ -118,6 +118,27 @@ void aptInit(NS_APPID appID) void aptExit() { + u8 buf1[4], buf2[4]; + + buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; 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(); + + 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(); + + aptOpenSession(); APT_PrepareToCloseApplication(NULL, 0x1); aptCloseSession(); @@ -125,6 +146,9 @@ void aptExit() aptOpenSession(); APT_CloseApplication(NULL, 0x0, 0x0, 0x0); aptCloseSession(); + + svc_closeHandle(aptStatusMutex); + // svc_closeHandle(aptLockHandle); } void aptSetupEventHandler() diff --git a/libctru/source/FS.c b/libctru/source/FS.c index 1fcdd1f..53697e8 100644 --- a/libctru/source/FS.c +++ b/libctru/source/FS.c @@ -107,6 +107,21 @@ Result FSUSER_OpenDirectory(Handle handle, Handle* out, FS_archive archive, FS_p return cmdbuf[1]; } +Result FSUSER_CloseArchive(Handle handle, FS_archive* archive) +{ + if(!archive)return -2; + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=0x080E0080; + cmdbuf[1]=archive->handleLow; + cmdbuf[2]=archive->handleLow; + + Result ret=0; + if((ret=svc_sendSyncRequest(handle)))return ret; + + return cmdbuf[1]; +} + Result FSFILE_Close(Handle handle) { u32* cmdbuf=getThreadCommandBuffer(); @@ -190,3 +205,15 @@ Result FSDIR_Read(Handle handle, u32 *entriesRead, u32 entrycount, u16 *buffer) return cmdbuf[1]; } + +Result FSDIR_Close(Handle handle) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=0x08020000; + + Result ret=0; + if((ret=svc_sendSyncRequest(handle)))return ret; + + return cmdbuf[1]; +} diff --git a/libctru/source/GSP.c b/libctru/source/GSP.c index 9375b6f..b60bfb9 100644 --- a/libctru/source/GSP.c +++ b/libctru/source/GSP.c @@ -5,7 +5,7 @@ #include #include -Handle gspGpuHandle; +Handle gspGpuHandle=0; void gspInit() { @@ -13,6 +13,11 @@ void gspInit() srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu"); } +void gspExit() +{ + if(gspGpuHandle)svc_closeHandle(gspGpuHandle); +} + Result GSPGPU_AcquireRight(Handle* handle, u8 flags) { if(!handle)handle=&gspGpuHandle; @@ -130,6 +135,19 @@ Result GSPGPU_RegisterInterruptRelayQueue(Handle* handle, Handle eventHandle, u3 return cmdbuf[1]; } +Result GSPGPU_UnregisterInterruptRelayQueue(Handle* handle) +{ + if(!handle)handle=&gspGpuHandle; + + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x00140000; //request header code + + Result ret=0; + if((ret=svc_sendSyncRequest(*handle)))return ret; + + return cmdbuf[1]; +} + Result GSPGPU_TriggerCmdReqQueue(Handle* handle) { if(!handle)handle=&gspGpuHandle; diff --git a/libctru/source/srv.c b/libctru/source/srv.c index aec7941..cdc6af9 100644 --- a/libctru/source/srv.c +++ b/libctru/source/srv.c @@ -5,7 +5,7 @@ #include #include -Handle srvHandle; +Handle srvHandle=0; Result initSrv() { @@ -14,6 +14,11 @@ Result initSrv() return srv_Initialize(&srvHandle); } +Result exitSrv() +{ + if(srvHandle)svc_closeHandle(srvHandle); +} + Result srv_Initialize(Handle* handleptr) { if(!handleptr)handleptr=&srvHandle; diff --git a/libctru/source/svc.s b/libctru/source/svc.s index 15a667e..903ed31 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -98,6 +98,12 @@ svc_mapMemoryBlock: svc 0x1F bx lr +.global svc_unmapMemoryBlock +.type svc_unmapMemoryBlock, %function +svc_unmapMemoryBlock: + svc 0x20 + bx lr + .global svc_closeHandle .type svc_closeHandle, %function svc_closeHandle: @@ -122,6 +128,18 @@ svc_waitSynchronizationN: ldr r5, [sp], #4 bx lr +.global svc_getSystemInfo +.type svc_getSystemInfo, %function +svc_getSystemInfo: + stmfd sp!, {r0, r4} + svc 0x2A + ldr r4, [sp], #4 + str r1, [r4] + str r2, [r4, #4] + # str r3, [r4, #8] # ? + ldr r4, [sp], #4 + bx lr + .global svc_connectToPort .type svc_connectToPort, %function svc_connectToPort: diff --git a/sdmc/source/main.c b/sdmc/source/main.c index f842633..4d8d95f 100644 --- a/sdmc/source/main.c +++ b/sdmc/source/main.c @@ -16,6 +16,8 @@ u32* gxCmdBuf; u8 currentBuffer; u8* topLeftFramebuffers[2]; +Handle gspEvent, gspSharedMemHandle; + void gspGpuInit() { gspInit(); @@ -36,7 +38,6 @@ void gspGpuInit() //setup our gsp shared mem section u8 threadID; - Handle gspEvent, gspSharedMemHandle; svc_createEvent(&gspEvent, 0x0); GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID); svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); @@ -53,6 +54,22 @@ void gspGpuInit() currentBuffer=0; } +void gspGpuExit() +{ + GSPGPU_UnregisterInterruptRelayQueue(NULL); + + //unmap GSP shared mem + svc_unmapMemoryBlock(gspSharedMemHandle, 0x10002000); + svc_closeHandle(gspSharedMemHandle); + svc_closeHandle(gspEvent); + + gspExit(); + + //free GSP heap + svc_controlMemory((u32*)&gspHeap, (u32)gspHeap, 0x0, 0x2000000, MEMOP_FREE, 0x0); +} + + void swapBuffers() { u32 regData; @@ -102,6 +119,25 @@ void renderEffect() } } +Handle hidHandle; +Handle hidMemHandle; + +void hidInit() +{ + srv_getServiceHandle(NULL, &hidHandle, "hid:USER"); + HIDUSER_GetInfo(hidHandle, &hidMemHandle); + svc_mapMemoryBlock(hidMemHandle, 0x10000000, 0x1, 0x10000000); + + HIDUSER_Init(hidHandle); +} + +void hidExit() +{ + svc_unmapMemoryBlock(hidMemHandle, 0x10000000); + svc_closeHandle(hidMemHandle); + svc_closeHandle(hidHandle); +} + int main() { initSrv(); @@ -110,13 +146,7 @@ int main() gspGpuInit(); - Handle hidHandle; - Handle hidMemHandle; - srv_getServiceHandle(NULL, &hidHandle, "hid:USER"); - HIDUSER_GetInfo(hidHandle, &hidMemHandle); - svc_mapMemoryBlock(hidMemHandle, 0x10000000, 0x1, 0x10000000); - - HIDUSER_Init(hidHandle); + hidInit(); Handle fsuHandle; srv_getServiceHandle(NULL, &fsuHandle, "fs:USER"); @@ -128,6 +158,7 @@ int main() FS_path filePath=(FS_path){PATH_CHAR, 10, (u8*)"/test.bin"}; FSUSER_OpenFileDirectly(fsuHandle, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSFILE_Read(fileHandle, &bytesRead, 0x0, (u32*)gspHeap, 0x46500); + FSFILE_Close(fileHandle); aptSetupEventHandler(); @@ -142,6 +173,9 @@ int main() svc_sleepThread(1000000000); } + svc_closeHandle(fsuHandle); + hidExit(); + gspGpuInit(); aptExit(); svc_exitProcess(); return 0;