initial commit
This commit is contained in:
parent
1b2094c0d3
commit
0a6669dc01
38
arm11u/Makefile
Normal file
38
arm11u/Makefile
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
CC = arm-none-eabi-gcc
|
||||||
|
LINK = arm-none-eabi-ld
|
||||||
|
OBJCOPY = arm-none-eabi-objcopy
|
||||||
|
CTRULIB = "../libctru"
|
||||||
|
CFLAGS += -Wall -std=c99 -march=armv6 -O0 -I"$(CTRULIB)/include"
|
||||||
|
LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
|
||||||
|
|
||||||
|
CFILES = $(wildcard source/*.c)
|
||||||
|
OFILES = $(CFILES:source/%.c=build/%.o)
|
||||||
|
DFILES = $(CFILES:source/%.c=build/%.d)
|
||||||
|
SFILES = $(wildcard source/*.s)
|
||||||
|
OFILES += $(SFILES:source/%.s=build/%.o)
|
||||||
|
PROJECTNAME = ${shell basename "$(CURDIR)"}
|
||||||
|
|
||||||
|
.PHONY:=all
|
||||||
|
|
||||||
|
all: $(PROJECTNAME).bin
|
||||||
|
|
||||||
|
$(PROJECTNAME).bin: $(PROJECTNAME).elf
|
||||||
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
$(PROJECTNAME).elf: $(OFILES)
|
||||||
|
$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES)) -lctru -lc
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f build/*.o build/*.d
|
||||||
|
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin
|
||||||
|
@echo "all cleaned up !"
|
||||||
|
|
||||||
|
-include $(DFILES)
|
||||||
|
|
||||||
|
build/%.o: source/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
@$(CC) -MM $< > build/$*.d
|
||||||
|
|
||||||
|
build/%.o: source/%.s
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
@$(CC) -MM $< > build/$*.d
|
12
arm11u/source/crt0.s
Normal file
12
arm11u/source/crt0.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.section ".text"
|
||||||
|
.arm
|
||||||
|
.align 4
|
||||||
|
.global _init
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
blx __libc_init_array
|
||||||
|
blx main
|
||||||
|
|
||||||
|
_init:
|
||||||
|
bx lr
|
101
arm11u/source/main.c
Normal file
101
arm11u/source/main.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#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>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Handle srvHandle, aptuHandle;
|
||||||
|
|
||||||
|
getSrvHandle(&srvHandle);
|
||||||
|
|
||||||
|
//initialize APT stuff, escape load screen
|
||||||
|
srv_getServiceHandle(srvHandle, &aptuHandle, "APT:U");
|
||||||
|
APT_GetLockHandle(aptuHandle, 0x0, NULL);
|
||||||
|
svc_closeHandle(aptuHandle);
|
||||||
|
svc_sleepThread(0x50000);
|
||||||
|
|
||||||
|
Handle hmEvent;
|
||||||
|
srv_getServiceHandle(srvHandle, &aptuHandle, "APT:U");
|
||||||
|
APT_Initialize(aptuHandle, 0x300, &hmEvent, NULL);
|
||||||
|
svc_closeHandle(aptuHandle);
|
||||||
|
svc_sleepThread(0x50000);
|
||||||
|
|
||||||
|
srv_getServiceHandle(srvHandle, &aptuHandle, "APT:U");
|
||||||
|
APT_Enable(aptuHandle, 0x0);
|
||||||
|
svc_closeHandle(aptuHandle);
|
||||||
|
svc_sleepThread(0x50000);
|
||||||
|
|
||||||
|
//do stuff with GPU...
|
||||||
|
Handle gspGpuHandle;
|
||||||
|
srv_getServiceHandle(srvHandle, &gspGpuHandle, "gsp::Gpu");
|
||||||
|
|
||||||
|
GSPGPU_AcquireRight(gspGpuHandle, 0x0);
|
||||||
|
GSPGPU_SetLcdForceBlack(gspGpuHandle, 0x0);
|
||||||
|
|
||||||
|
//set subscreen to blue
|
||||||
|
u32 regData=0x01FF0000;
|
||||||
|
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4);
|
||||||
|
|
||||||
|
//grab main left screen framebuffer addresses
|
||||||
|
u8* topLeftFramebuffers[2];
|
||||||
|
GSPGPU_ReadHWRegs(gspGpuHandle, 0x400468, (u8*)&topLeftFramebuffers, 8);
|
||||||
|
|
||||||
|
//convert PA to VA (assuming FB in VRAM)
|
||||||
|
topLeftFramebuffers[0]+=0x7000000;
|
||||||
|
topLeftFramebuffers[1]+=0x7000000;
|
||||||
|
|
||||||
|
//setup our gsp shared mem section
|
||||||
|
u8 threadID;
|
||||||
|
Handle gspEvent, gspSharedMemHandle;
|
||||||
|
svc_createEvent(&gspEvent, 0x0);
|
||||||
|
GSPGPU_RegisterInterruptRelayQueue(gspGpuHandle, gspEvent, 0x1, &gspSharedMemHandle, &threadID);
|
||||||
|
svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000);
|
||||||
|
|
||||||
|
//map GSP heap
|
||||||
|
u8* gspHeap;
|
||||||
|
svc_controlMemory((u32*)&gspHeap, 0x0, 0x0, 0x2000000, 0x10003, 0x3);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i=1;i<0x600000;i++)
|
||||||
|
{
|
||||||
|
gspHeap[i]=0xFF^gspHeap[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//wait until we can write stuff to it
|
||||||
|
svc_waitSynchronization1(gspEvent, 0x55bcb0);
|
||||||
|
|
||||||
|
// //GSP shared mem : 0x2779F000
|
||||||
|
// //write GX command ! (to GSP shared mem, at 0x10002000)
|
||||||
|
u32* gxCmdBuf=(u32*)(0x10002000+0x800+threadID*0x200);
|
||||||
|
u32 gxCommand[0x8];
|
||||||
|
|
||||||
|
//GX RequestDma
|
||||||
|
gxCommand[0]=0x00; //CommandID
|
||||||
|
gxCommand[1]=(u32)gspHeap; //source address
|
||||||
|
// gxCommand[2]=(u32)topLeftFramebuffers[0]; //destination address
|
||||||
|
gxCommand[2]=0x1F000000; //destination address
|
||||||
|
// gxCommand[3]=0x5DC00*2; //size
|
||||||
|
gxCommand[3]=0x600000; //size
|
||||||
|
gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0;
|
||||||
|
|
||||||
|
GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, gspGpuHandle);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
regData=0x010000FF;
|
||||||
|
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4);
|
||||||
|
|
||||||
|
svc_waitSynchronization1(hmEvent, 0xffffffffffffffff);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
regData=0x0100FFFF;
|
||||||
|
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4);
|
||||||
|
|
||||||
|
while(1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
36
libctru/Makefile
Normal file
36
libctru/Makefile
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
CC = arm-none-eabi-gcc
|
||||||
|
AR = arm-none-eabi-ar
|
||||||
|
CFLAGS += -Wall -std=c99 -march=armv6 -O0 -I"$(CURDIR)/include/"
|
||||||
|
|
||||||
|
CFILES = $(wildcard source/*.c)
|
||||||
|
OFILES = $(CFILES:source/%.c=build/%.o)
|
||||||
|
DFILES = $(CFILES:source/%.c=build/%.d)
|
||||||
|
SFILES = $(wildcard source/*.s)
|
||||||
|
OFILES += $(SFILES:source/%.s=build/%.o)
|
||||||
|
PROJECTNAME = "libctru"
|
||||||
|
|
||||||
|
.PHONY:=all dir
|
||||||
|
|
||||||
|
all: dir lib/$(PROJECTNAME).a
|
||||||
|
|
||||||
|
dir:
|
||||||
|
mkdir -p build
|
||||||
|
mkdir -p lib
|
||||||
|
|
||||||
|
lib/$(PROJECTNAME).a: $(OFILES)
|
||||||
|
$(AR) rvs $@ $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f build/*.o build/*.d
|
||||||
|
@rm -f $(PROJECTNAME).a
|
||||||
|
@echo "all cleaned up !"
|
||||||
|
|
||||||
|
-include $(DFILES)
|
||||||
|
|
||||||
|
build/%.o: source/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
@$(CC) -MM $< > build/$*.d
|
||||||
|
|
||||||
|
build/%.o: source/%.s
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
@$(CC) -MM $< > build/$*.d
|
10
libctru/include/ctr/APT.h
Normal file
10
libctru/include/ctr/APT.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef APT_H
|
||||||
|
#define APT_H
|
||||||
|
|
||||||
|
void APT_GetLockHandle(Handle handle, u16 flags, Handle* lockHandle);
|
||||||
|
void APT_Initialize(Handle handle, u32 a, 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);
|
||||||
|
|
||||||
|
#endif
|
12
libctru/include/ctr/GSP.h
Normal file
12
libctru/include/ctr/GSP.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef GSP_H
|
||||||
|
#define GSP_H
|
||||||
|
|
||||||
|
void GSPGPU_AcquireRight(Handle handle, u8 flags);
|
||||||
|
void GSPGPU_SetLcdForceBlack(Handle handle, u8 flags);
|
||||||
|
void GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size);
|
||||||
|
void GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size);
|
||||||
|
void 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
|
9
libctru/include/ctr/srv.h
Normal file
9
libctru/include/ctr/srv.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef SRV_H
|
||||||
|
#define SRV_H
|
||||||
|
|
||||||
|
|
||||||
|
Result srv_10002(Handle handle);
|
||||||
|
void getSrvHandle(Handle* out);
|
||||||
|
void srv_getServiceHandle(Handle handle, Handle* out, char* server);
|
||||||
|
|
||||||
|
#endif
|
14
libctru/include/ctr/svc.h
Normal file
14
libctru/include/ctr/svc.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef SVC_H
|
||||||
|
#define SVC_H
|
||||||
|
|
||||||
|
u32* svc_getData(void);
|
||||||
|
void svc_sleepThread(s64 ns);
|
||||||
|
Result svc_controlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions); //(outaddr is usually the same as the input addr0)
|
||||||
|
Result svc_createEvent(Handle* event, u8 resettype);
|
||||||
|
Result svc_mapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission);
|
||||||
|
Result svc_waitSynchronization1(Handle handle, s64 nanoseconds);
|
||||||
|
Result svc_closeHandle(Handle handle);
|
||||||
|
Result svc_connectToPort(volatile Handle* out, const char* portName);
|
||||||
|
Result svc_sendSyncRequest(Handle session);
|
||||||
|
|
||||||
|
#endif
|
19
libctru/include/ctr/types.h
Normal file
19
libctru/include/ctr/types.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef TYPES_H
|
||||||
|
#define TYPES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
|
typedef signed char s8;
|
||||||
|
typedef signed short s16;
|
||||||
|
typedef signed int s32;
|
||||||
|
typedef signed long long s64;
|
||||||
|
|
||||||
|
typedef u32 Handle;
|
||||||
|
typedef u32 Result;
|
||||||
|
|
||||||
|
#endif
|
55
libctru/source/APT.c
Normal file
55
libctru/source/APT.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctr/types.h>
|
||||||
|
#include <ctr/APT.h>
|
||||||
|
#include <ctr/svc.h>
|
||||||
|
|
||||||
|
void APT_GetLockHandle(Handle handle, u16 flags, Handle* lockHandle)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x10040; //request header code
|
||||||
|
svcData[1]=flags;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
if(lockHandle)*lockHandle=svcData[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void APT_Initialize(Handle handle, u32 a, Handle* eventHandle1, Handle* eventHandle2)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x20080; //request header code
|
||||||
|
svcData[1]=a;
|
||||||
|
svcData[2]=0x0;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
if(eventHandle1)*eventHandle1=svcData[3]; //return to menu event ?
|
||||||
|
if(eventHandle2)*eventHandle2=svcData[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result APT_Enable(Handle handle, u32 a)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x30040; //request header code
|
||||||
|
svcData[1]=a;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
return svcData[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result APT_PrepareToJumpToHomeMenu(Handle handle)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x2b0000; //request header code
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
return svcData[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x2C0044; //request header code
|
||||||
|
svcData[1]=a;
|
||||||
|
svcData[2]=b;
|
||||||
|
svcData[3]=c;
|
||||||
|
svcData[4]=(b<<14)|2;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
return svcData[1];
|
||||||
|
}
|
114
libctru/source/GSP.c
Normal file
114
libctru/source/GSP.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctr/types.h>
|
||||||
|
#include <ctr/GSP.h>
|
||||||
|
#include <ctr/svc.h>
|
||||||
|
|
||||||
|
|
||||||
|
void GSPGPU_AcquireRight(Handle handle, u8 flags)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x160042; //request header code
|
||||||
|
svcData[1]=flags;
|
||||||
|
svcData[2]=0x0;
|
||||||
|
svcData[3]=0xffff8001;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSPGPU_SetLcdForceBlack(Handle handle, u8 flags)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0xB0040; //request header code
|
||||||
|
svcData[1]=flags;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size)
|
||||||
|
{
|
||||||
|
if(size>0x80 || !data)return;
|
||||||
|
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x10082; //request header code
|
||||||
|
svcData[1]=regAddr;
|
||||||
|
svcData[2]=size;
|
||||||
|
svcData[3]=(size<<14)|2;
|
||||||
|
svcData[4]=(u32)data;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size)
|
||||||
|
{
|
||||||
|
if(size>0x80 || !data)return;
|
||||||
|
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x40080; //request header code
|
||||||
|
svcData[1]=regAddr;
|
||||||
|
svcData[2]=size;
|
||||||
|
svcData[0x40]=(size<<14)|2;
|
||||||
|
svcData[0x40+1]=(u32)data;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x130042; //request header code
|
||||||
|
svcData[1]=flags;
|
||||||
|
svcData[2]=0x0;
|
||||||
|
svcData[3]=eventHandle;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
if(threadID)*threadID=svcData[2];
|
||||||
|
if(outMemHandle)*outMemHandle=svcData[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GSPGPU_TriggerCmdReqQueue(Handle handle)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0xC0000; //request header code
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
return svcData[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//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)
|
||||||
|
{
|
||||||
|
if(!sharedGspCmdBuf || !gxCommand)return -1;
|
||||||
|
|
||||||
|
u32 cmdBufHeader;
|
||||||
|
__asm__ ("ldrex %[result], [%[adr]]" : [result] "=r" (cmdBufHeader) : [adr] "r" (sharedGspCmdBuf));
|
||||||
|
|
||||||
|
u8 commandIndex=cmdBufHeader&0xFF;
|
||||||
|
u8 totalCommands=(cmdBufHeader>>8)&0xFF;
|
||||||
|
|
||||||
|
if(totalCommands>15)return -2;
|
||||||
|
|
||||||
|
u8 nextCmd=(commandIndex+totalCommands)%15; //there are 15 command slots
|
||||||
|
u32* dst=&sharedGspCmdBuf[8*(1+nextCmd)];
|
||||||
|
memcpy(dst, gxCommand, 0x20);
|
||||||
|
|
||||||
|
u32 mcrVal=0x0;
|
||||||
|
__asm__ ("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (mcrVal)); //Data Synchronization Barrier Register
|
||||||
|
totalCommands++;
|
||||||
|
cmdBufHeader=((cmdBufHeader)&0xFFFF00FF)|(((u32)totalCommands)<<8);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
u32 strexResult;
|
||||||
|
__asm__ ("strex %[result], %[val], [%[adr]]" : [result] "=r" (strexResult) : [adr] "r" (sharedGspCmdBuf), [val] "r" (cmdBufHeader));
|
||||||
|
if(!strexResult)break;
|
||||||
|
|
||||||
|
__asm__ ("ldrex %[result], [%[adr]]" : [result] "=r" (cmdBufHeader) : [adr] "r" (sharedGspCmdBuf));
|
||||||
|
totalCommands=((cmdBufHeader&0xFF00)>>8)+1;
|
||||||
|
cmdBufHeader=((cmdBufHeader)&0xFFFF00FF)|((totalCommands<<8)|0xFF00);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(totalCommands==1)
|
||||||
|
{
|
||||||
|
GSPGPU_TriggerCmdReqQueue(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
36
libctru/source/srv.c
Normal file
36
libctru/source/srv.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctr/types.h>
|
||||||
|
#include <ctr/srv.h>
|
||||||
|
#include <ctr/svc.h>
|
||||||
|
|
||||||
|
Result srv_10002(Handle handle)
|
||||||
|
{
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x10002; //request header code
|
||||||
|
svcData[1]=0x20;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
return svcData[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void getSrvHandle(Handle* out)
|
||||||
|
{
|
||||||
|
if(!out)return;
|
||||||
|
|
||||||
|
svc_connectToPort(out, "srv:");
|
||||||
|
srv_10002(*out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_getServiceHandle(Handle handle, Handle* out, char* server)
|
||||||
|
{
|
||||||
|
u8 l=strlen(server);
|
||||||
|
if(!out || !server || l>8)return;
|
||||||
|
u32* svcData=svc_getData();
|
||||||
|
svcData[0]=0x50100; //request header code
|
||||||
|
strcpy((char*)&svcData[1], server);
|
||||||
|
svcData[3]=l;
|
||||||
|
svcData[4]=0x0;
|
||||||
|
svc_sendSyncRequest(handle); //check return value...
|
||||||
|
*out=svcData[3];
|
||||||
|
}
|
72
libctru/source/svc.s
Normal file
72
libctru/source/svc.s
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
.arm
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
.global svc_getData
|
||||||
|
.type svc_getData, %function
|
||||||
|
svc_getData:
|
||||||
|
mrc p15, 0, r0, c13, c0, 3
|
||||||
|
add r0, #0x80
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
.global svc_controlMemory
|
||||||
|
.type svc_controlMemory, %function
|
||||||
|
svc_controlMemory:
|
||||||
|
stmfd sp!, {r0, r4}
|
||||||
|
ldr R0, [sp, #0x8]
|
||||||
|
ldr r4, [sp, #0x8+0x4]
|
||||||
|
svc 0x01
|
||||||
|
ldr r2, [sp]
|
||||||
|
str r1, [r2]
|
||||||
|
ldr r4, [sp, #4]!
|
||||||
|
add sp, sp, #4
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_sleepThread
|
||||||
|
.type svc_sleepThread, %function
|
||||||
|
svc_sleepThread:
|
||||||
|
svc 0x0A
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_createEvent
|
||||||
|
.type svc_createEvent, %function
|
||||||
|
svc_createEvent:
|
||||||
|
str r0, [sp,#-4]!
|
||||||
|
svc 0x17
|
||||||
|
ldr r2, [sp], #4
|
||||||
|
str r1, [r2]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_mapMemoryBlock
|
||||||
|
.type svc_mapMemoryBlock, %function
|
||||||
|
svc_mapMemoryBlock:
|
||||||
|
svc 0x1F
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_closeHandle
|
||||||
|
.type svc_closeHandle, %function
|
||||||
|
svc_closeHandle:
|
||||||
|
svc 0x23
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_waitSynchronization1
|
||||||
|
.type svc_waitSynchronization1, %function
|
||||||
|
svc_waitSynchronization1:
|
||||||
|
svc 0x24
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_connectToPort
|
||||||
|
.type svc_connectToPort, %function
|
||||||
|
svc_connectToPort:
|
||||||
|
str r0, [sp,#-0x4]!
|
||||||
|
svc 0x2D
|
||||||
|
ldr r3, [sp], #4
|
||||||
|
str r1, [r3]
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global svc_sendSyncRequest
|
||||||
|
.type svc_sendSyncRequest, %function
|
||||||
|
svc_sendSyncRequest:
|
||||||
|
svc 0x32
|
||||||
|
bx lr
|
Loading…
Reference in New Issue
Block a user