diff --git a/libctru/include/ctr/FS.h b/libctru/include/ctr/FS.h index 73d9e64..2d5da64 100644 --- a/libctru/include/ctr/FS.h +++ b/libctru/include/ctr/FS.h @@ -5,6 +5,7 @@ #define FS_OPEN_WRITE (1<<1) #define FS_OPEN_CREATE (1<<2) +#define FS_ATTRIBUTE_NONE (0x00000000) #define FS_ATTRIBUTE_READONLY (0x00000001) #define FS_ATTRIBUTE_ARCHIVE (0x00000100) #define FS_ATTRIBUTE_HIDDEN (0x00010000) @@ -27,11 +28,13 @@ typedef struct{ typedef struct{ u32 id; FS_path lowPath; + Handle handleLow, handleHigh; }FS_archive; Result FSUSER_Initialize(Handle handle); -Result FSUSER_OpenFile(Handle handle, Handle* out, u32 archiveid, FS_archive archive, FS_path fileLowPath, u32 openflags, u32 attributes); +Result FSUSER_OpenArchive(Handle handle, FS_archive* archive); +Result FSUSER_OpenFileDirectly(Handle handle, Handle* out, FS_archive archive, FS_path fileLowPath, u32 openflags, u32 attributes); Result FSFILE_Close(Handle handle); Result FSFILE_Read(Handle handle, u32 *bytesRead, u64 offset, u32 *buffer, u32 size); diff --git a/libctru/source/FS.c b/libctru/source/FS.c index e025a6f..7a91c22 100644 --- a/libctru/source/FS.c +++ b/libctru/source/FS.c @@ -17,7 +17,7 @@ Result FSUSER_Initialize(Handle handle) return cmdbuf[1]; } -Result FSUSER_OpenFile(Handle handle, Handle* out, u32 archiveid, 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) { u32* cmdbuf=getThreadCommandBuffer(); @@ -43,6 +43,27 @@ Result FSUSER_OpenFile(Handle handle, Handle* out, u32 archiveid, FS_archive arc return cmdbuf[1]; } +Result FSUSER_OpenArchive(Handle handle, FS_archive* archive) +{ + if(!archive)return -2; + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=0x080C00C2; + cmdbuf[1]=archive->id; + cmdbuf[2]=archive->lowPath.type; + cmdbuf[3]=archive->lowPath.size; + cmdbuf[4]=(archive->lowPath.size<<14)|0x2; + cmdbuf[5]=(u32)archive->lowPath.data; + + Result ret=0; + if((ret=svc_sendSyncRequest(handle)))return ret; + + archive->handleLow=cmdbuf[2]; + archive->handleHigh=cmdbuf[3]; + + return cmdbuf[1]; +} + Result FSFILE_Close(Handle handle) { u32* cmdbuf=getThreadCommandBuffer(); diff --git a/sdmc/Makefile b/sdmc/Makefile new file mode 100644 index 0000000..4065b70 --- /dev/null +++ b/sdmc/Makefile @@ -0,0 +1,60 @@ +CC = arm-none-eabi-gcc +LINK = arm-none-eabi-ld +AS = arm-none-eabi-as +OBJCOPY = arm-none-eabi-objcopy +CTRULIB = "../libctru" +CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" +LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib" + +CFILES = $(wildcard source/*.c) +BINFILES = $(wildcard data/*.bin) +OFILES = $(BINFILES:data/%.bin=build/%.bin.o) +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)"} +CWD = "$(CURDIR)"" + +#--------------------------------------------------------------------------------- +# canned command sequence for binary data, taken from devkitARM +#--------------------------------------------------------------------------------- +define bin2o + bin2s $< | $(AS) -o $(@) + echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( build/$*.d + +build/%.o: source/%.s + $(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo $(notdir $<) + @$(bin2o) + diff --git a/sdmc/source/costable.h b/sdmc/source/costable.h new file mode 100644 index 0000000..1c9b8ec --- /dev/null +++ b/sdmc/source/costable.h @@ -0,0 +1,6 @@ +#ifndef COSTABLE_H +#define COSTABLE_H + +s32 costable[] = {4096, 4095, 4094, 4093, 4091, 4088, 4084, 4080, 4076, 4071, 4065, 4058, 4051, 4044, 4035, 4026, 4017, 4007, 3996, 3985, 3973, 3960, 3947, 3934, 3919, 3904, 3889, 3873, 3856, 3839, 3821, 3803, 3784, 3765, 3744, 3724, 3703, 3681, 3659, 3636, 3612, 3588, 3564, 3539, 3513, 3487, 3461, 3434, 3406, 3378, 3349, 3320, 3290, 3260, 3229, 3198, 3167, 3135, 3102, 3069, 3035, 3002, 2967, 2932, 2897, 2861, 2825, 2788, 2751, 2714, 2676, 2638, 2599, 2560, 2521, 2481, 2441, 2401, 2360, 2318, 2277, 2235, 2193, 2150, 2107, 2064, 2020, 1976, 1932, 1888, 1843, 1798, 1753, 1707, 1662, 1616, 1569, 1523, 1476, 1429, 1382, 1334, 1287, 1239, 1191, 1143, 1095, 1046, 997, 949, 900, 851, 801, 752, 703, 653, 603, 554, 504, 454, 404, 354, 304, 254, 204, 153, 103, 53, 3, -46, -97, -147, -197, -247, -297, -347, -398, -448, -497, -547, -597, -647, -696, -746, -795, -844, -893, -942, -991, -1040, -1088, -1137, -1185, -1233, -1281, -1328, -1376, -1423, -1470, -1517, -1563, -1610, -1656, -1701, -1747, -1792, -1837, -1882, -1927, -1971, -2015, -2058, -2102, -2144, -2187, -2229, -2271, -2313, -2354, -2395, -2436, -2476, -2516, -2555, -2594, -2633, -2671, -2709, -2747, -2784, -2820, -2857, -2892, -2928, -2963, -2997, -3031, -3065, -3098, -3130, -3163, -3194, -3225, -3256, -3286, -3316, -3345, -3374, -3402, -3430, -3457, -3484, -3510, -3536, -3561, -3585, -3609, -3633, -3656, -3678, -3700, -3721, -3742, -3762, -3782, -3801, -3819, -3837, -3854, -3871, -3887, -3902, -3917, -3932, -3946, -3959, -3971, -3983, -3995, -4005, -4016, -4025, -4034, -4042, -4050, -4057, -4064, -4070, -4075, -4080, -4084, -4087, -4090, -4092, -4094, -4095, -4095, -4095, -4094, -4093, -4091, -4088, -4085, -4081, -4076, -4071, -4066, -4059, -4052, -4045, -4036, -4028, -4018, -4008, -3997, -3986, -3974, -3962, -3949, -3935, -3921, -3906, -3891, -3875, -3858, -3841, -3824, -3805, -3787, -3767, -3747, -3727, -3705, -3684, -3662, -3639, -3615, -3592, -3567, -3542, -3517, -3491, -3464, -3437, -3409, -3381, -3353, -3324, -3294, -3264, -3233, -3202, -3171, -3139, -3106, -3073, -3040, -3006, -2972, -2937, -2902, -2866, -2830, -2793, -2756, -2719, -2681, -2643, -2604, -2565, -2526, -2486, -2446, -2406, -2365, -2324, -2282, -2240, -2198, -2156, -2113, -2069, -2026, -1982, -1938, -1894, -1849, -1804, -1759, -1713, -1668, -1622, -1575, -1529, -1482, -1435, -1388, -1341, -1293, -1245, -1197, -1149, -1101, -1052, -1004, -955, -906, -857, -808, -758, -709, -660, -610, -560, -510, -460, -411, -360, -310, -260, -210, -160, -110, -60, -9, 40, 90, 140, 191, 241, 291, 341, 391, 441, 491, 541, 591, 640, 690, 739, 789, 838, 887, 936, 985, 1033, 1082, 1130, 1179, 1227, 1274, 1322, 1370, 1417, 1464, 1511, 1557, 1604, 1650, 1695, 1741, 1786, 1831, 1876, 1921, 1965, 2009, 2053, 2096, 2139, 2182, 2224, 2266, 2308, 2349, 2390, 2431, 2471, 2511, 2550, 2589, 2628, 2666, 2704, 2742, 2779, 2816, 2852, 2888, 2923, 2958, 2993, 3027, 3060, 3093, 3126, 3158, 3190, 3221, 3252, 3282, 3312, 3342, 3370, 3399, 3426, 3454, 3480, 3507, 3532, 3557, 3582, 3606, 3630, 3653, 3675, 3697, 3718, 3739, 3759, 3779, 3798, 3817, 3835, 3852, 3869, 3885, 3900, 3915, 3930, 3944, 3957, 3970, 3982, 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4063, 4069, 4074, 4079, 4083, 4087, 4090, 4092, 4094, 4095}; + +#endif diff --git a/sdmc/source/crt0.s b/sdmc/source/crt0.s new file mode 100644 index 0000000..6463bc2 --- /dev/null +++ b/sdmc/source/crt0.s @@ -0,0 +1,12 @@ +.section ".text" +.arm +.align 4 +.global _init +.global _start + +_start: + blx __libc_init_array + blx main + +_init: + bx lr diff --git a/sdmc/source/main.c b/sdmc/source/main.c new file mode 100644 index 0000000..06ffa03 --- /dev/null +++ b/sdmc/source/main.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "costable.h" + +Handle srvHandle; +Handle APTevents[2]; +Handle aptLockHandle; + +void aptInit() +{ + Handle aptuHandle; + + //initialize APT stuff, escape load screen + srv_getServiceHandle(srvHandle, &aptuHandle, "APT:U"); + APT_GetLockHandle(aptuHandle, 0x0, &aptLockHandle); + svc_closeHandle(aptuHandle); + + svc_waitSynchronization1(aptLockHandle, U64_MAX); + srv_getServiceHandle(srvHandle, &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(srvHandle, &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(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 + 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 + svc_controlMemory((u32*)&gspHeap, 0x0, 0x0, 0x2000000, 0x10003, 0x3); + + //wait until we can write stuff to it + svc_waitSynchronization1(gspEvent, 0x55bcb0); + + //GSP shared mem : 0x2779F000 + gxCmdBuf=(u32*)(0x10002000+0x800+threadID*0x200); + + currentBuffer=0; +} + +void swapBuffers() +{ + u32 regData; + GSPGPU_ReadHWRegs(gspGpuHandle, 0x400478, (u8*)®Data, 4); + regData^=1; + currentBuffer=regData&1; + GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)®Data, 4); +} + +void copyBuffer() +{ + //copy topleft FB + u8 copiedBuffer=currentBuffer^1; + u8* bufAdr=&gspHeap[0x46500*copiedBuffer]; + GSPGPU_FlushDataCache(gspGpuHandle, bufAdr, 0x46500); + //GX RequestDma + u32 gxCommand[0x8]; + gxCommand[0]=0x00; //CommandID + gxCommand[1]=(u32)bufAdr; //source address + gxCommand[2]=(u32)topLeftFramebuffers[copiedBuffer]; //destination address + gxCommand[3]=0x46500; //size + gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; + + GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, gspGpuHandle); +} + +s32 pcCos(u16 v) +{ + return costable[v&0x1FF]; +} + +void renderEffect() +{ + u8* bufAdr=&gspHeap[0x46500*currentBuffer]; + + if(!currentBuffer)return; + int i, j; + for(i=1;i<400;i++) + { + 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; + } + } +} + +int main() +{ + getSrvHandle(&srvHandle); + + aptInit(); + + gspGpuInit(); + + Handle hidHandle; + Handle hidMemHandle; + srv_getServiceHandle(srvHandle, &hidHandle, "hid:USER"); + HIDUSER_GetInfo(hidHandle, &hidMemHandle); + svc_mapMemoryBlock(hidMemHandle, 0x10000000, 0x1, 0x10000000); + + HIDUSER_Init(hidHandle); + + Handle fsuHandle; + srv_getServiceHandle(srvHandle, &fsuHandle, "fs:USER"); + FSUSER_Initialize(fsuHandle); + + Handle fileHandle; + u32 bytesRead; + FS_archive sdmcArchive=(FS_archive){0x9, (FS_path){PATH_EMPTY, 1, (u8*)""}}; + 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); + + while(1) + { + u32 PAD=((u32*)0x10000000)[7]; + renderEffect(); + swapBuffers(); + copyBuffer(); + u32 regData=PAD|0x01000000; + GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)®Data, 4); + svc_sleepThread(1000000000); + } + + svc_exitProcess(); + return 0; +}