#include <ctr/svc.h>
#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;
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
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()
//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
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)
HIDUSER_Init(hidHandle);
+ aptSetupEventHandler();
+
while(1)
{
u32 PAD=((u32*)0x10000000)[7];
swapBuffers();
copyBuffer();
u32 regData=PAD|0x01000000;
- GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4);
+ GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4);
svc_sleepThread(1000000000);
}
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
#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
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)
typedef u32 Handle;
typedef s32 Result;
+ typedef void (*ThreadFunc)(u32);
#endif
#include <stdio.h>
#include <string.h>
#include <ctr/types.h>
+#include <ctr/srv.h>
#include <ctr/APT.h>
+#include <ctr/GSP.h>
#include <ctr/svc.h>
-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];
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;
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_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)
+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;
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;
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];
#include <ctr/GSP.h>
#include <ctr/svc.h>
+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;
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;
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();
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();
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;
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];
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];
}
//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;
.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
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:
#include <ctr/svc.h>
#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;
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
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()
//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
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)
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];
swapBuffers();
copyBuffer();
u32 regData=PAD|0x01000000;
- GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4);
+ GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4);
svc_sleepThread(1000000000);
}