APT : preliminary/experimental return to menu support

This commit is contained in:
smea 2014-02-01 00:23:59 +01:00
parent 08afa38c10
commit 4250f91d55
9 changed files with 303 additions and 130 deletions

View File

@ -9,52 +9,25 @@
#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*)&regData, 4);
GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 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*)&regData, 4);
GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)&regData, 4);
regData^=1;
currentBuffer=regData&1;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)&regData, 4);
GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)&regData, 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*)&regData, 4);
GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 4);
svc_sleepThread(1000000000);
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -30,5 +30,6 @@
typedef u32 Handle;
typedef s32 Result;
typedef void (*ThreadFunc)(u32);
#endif

View File

@ -2,32 +2,161 @@
#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];
@ -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];

View File

@ -5,9 +5,18 @@
#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;
@ -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;

View File

@ -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:

View File

@ -10,52 +10,25 @@
#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*)&regData, 4);
GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 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*)&regData, 4);
GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)&regData, 4);
regData^=1;
currentBuffer=regData&1;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)&regData, 4);
GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)&regData, 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*)&regData, 4);
GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 4);
svc_sleepThread(1000000000);
}