Created
July 17, 2014 23:59
-
-
Save mateusmedeiros/bf647ae9bbcde0b690e2 to your computer and use it in GitHub Desktop.
excerpt smealum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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/HID.h> | |
#include <ctr/SOC.h> | |
#include <ctr/FS.h> | |
#include <ctr/svc.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <netdb.h> | |
#include "costable.h" | |
#include "text.h" | |
#define NUM_FILES (12) | |
s64 DEBUGVAL[5]; | |
u8* gspHeap; | |
u32* gxCmdBuf; | |
u8 currentBuffer; | |
u8* topLeftFramebuffers[2]; | |
Handle gspEvent, gspSharedMemHandle; | |
void gspGpuInit() | |
{ | |
gspInit(); | |
GSPGPU_AcquireRight(NULL, 0x0); | |
GSPGPU_SetLcdForceBlack(NULL, 0x0); | |
//set subscreen to blue | |
u32 regData=0x01FF0000; | |
GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)®Data, 4); | |
//grab main left screen framebuffer addresses | |
GSPGPU_ReadHWRegs(NULL, 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; | |
svc_createEvent(&gspEvent, 0x0); | |
GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID); | |
svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); | |
//commit 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 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; | |
GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)®Data, 4); | |
regData^=1; | |
currentBuffer=regData&1; | |
GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)®Data, 4); | |
} | |
void copyBuffer() | |
{ | |
//copy topleft FB | |
u8 copiedBuffer=currentBuffer^1; | |
u8* bufAdr=&gspHeap[0x46500*copiedBuffer]; | |
GSPGPU_FlushDataCache(NULL, 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, NULL); | |
} | |
s32 pcCos(u16 v) | |
{ | |
return costable[v&0x1FF]; | |
} | |
u32 cnt; | |
char superStr[8192]; | |
char testOutput[4096]; | |
void renderEffect() | |
{ | |
u8* bufAdr=&gspHeap[0x46500*currentBuffer]; | |
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+cnt)+4096)/32; | |
bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64; | |
bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32; | |
} | |
} | |
drawString(bufAdr, superStr, 0, 0); | |
cnt++; | |
} | |
s32 debugValue=0x0; | |
void outputMenuString() | |
{ | |
siprintf(superStr, "crappy FTP 2000 (%08X = %d)\n",debugValue,debugValue); | |
strcat(superStr, testOutput); | |
} | |
typedef void* (*frameHandler)(void); | |
void* menuHandler(); | |
Handle fsuHandle; | |
FS_archive sdmcArchive; | |
u32 testBuffer[0x1000/4]; | |
bool draw=true; | |
u32 debugBuffer[4]; | |
u32 oldPAD=0; | |
void* menuHandler() | |
{ | |
// u32 PAD=hidSharedMem[7]; | |
s64 BASE; | |
svc_getSystemInfo(&BASE,0,3); | |
siprintf(testOutput,"\n%08X, %08X, %08X, %08X, %08X\nBASE : %08X", (u32)DEBUGVAL[0], (u32)DEBUGVAL[1], (u32)DEBUGVAL[2], (u32)DEBUGVAL[3], (u32)DEBUGVAL[4], (u32)BASE); | |
outputMenuString(); | |
// oldPAD=PAD; | |
return menuHandler; | |
} | |
unsigned long htonl(unsigned long v) | |
{ | |
u8* v2=(u8*)&v; | |
return (v2[0]<<24)|(v2[1]<<16)|(v2[2]<<8)|(v2[3]); | |
} | |
unsigned short htons(unsigned short v) | |
{ | |
u8* v2=(u8*)&v; | |
return (v2[0]<<8)|(v2[1]); | |
} | |
char tmpBuffer[512]; | |
const int commandPort=5000; | |
const int dataPort=5001; | |
#define DATA_BUFFER_SIZE (512*1024) | |
char currentPath[4096]; | |
char tmpStr[4096]; | |
u32 dataBuffer[DATA_BUFFER_SIZE/4]; | |
int ftp_openCommandChannel() | |
{ | |
int listenfd; | |
struct sockaddr_in serv_addr; | |
listenfd = socket(AF_INET, SOCK_STREAM, 0); | |
memset(&serv_addr, '0', sizeof(serv_addr)); | |
serv_addr.sin_family = AF_INET; | |
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
serv_addr.sin_port = htons(commandPort); | |
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); | |
listen(listenfd, 10); | |
int ret=accept(listenfd, (struct sockaddr*)NULL, NULL); | |
closesocket(listenfd); | |
return ret; | |
} | |
int ftp_openDataChannel() | |
{ | |
int listenfd; | |
struct sockaddr_in serv_addr; | |
listenfd = socket(AF_INET, SOCK_STREAM, 0); | |
memset(&serv_addr, '0', sizeof(serv_addr)); | |
serv_addr.sin_family = AF_INET; | |
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
serv_addr.sin_port = htons(dataPort); | |
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); | |
listen(listenfd, 10); | |
int ret=accept(listenfd, (struct sockaddr*)NULL, NULL); | |
closesocket(listenfd); | |
return ret; | |
} | |
int ftp_sendResponse(int s, int n, char* mes) | |
{ | |
char data[128]; | |
sprintf(data, "%d %s\r\n", n, mes); | |
return send(s,data,strlen(data)+1,0); | |
} | |
void unicodeToChar(char* dst, u16* src) | |
{ | |
if(!src || !dst)return; | |
while(*src)*(dst++)=(*(src++))&0xFF; | |
*dst=0x00; | |
} | |
int linelen(char* str) | |
{ | |
int i=0; while(*str && *str!='\n' && *str!='\r'){i++;str++;} | |
*str=0x0; | |
return i; | |
} | |
int ftp_processCommand(int s, char* data) | |
{ | |
if(!data)return -1; | |
int n=linelen(data); | |
char cmd[5]; | |
char arg[256]=""; | |
if(n>2 && (!data[3] || data[3]==' ' || data[3]=='\n' || data[3]=='\r')){memcpy(cmd,data,3);cmd[3]=0x0; if(n>3)memcpy(arg, &data[4], n-4);} | |
else if(n>3 && (!data[4] || data[4]==' ' || data[4]=='\r' || data[4]=='\n')){memcpy(cmd,data,4);cmd[4]=0x0; if(n>4)memcpy(arg, &data[5], n-5);} | |
else return -1; | |
sprintf(tmpBuffer,"\nreceived command : %s (%s)",cmd,arg); | |
strcat(testOutput, tmpBuffer); | |
outputMenuString(); | |
renderEffect(); | |
swapBuffers(); | |
copyBuffer(); | |
renderEffect(); | |
swapBuffers(); | |
copyBuffer(); | |
renderEffect(); | |
swapBuffers(); | |
copyBuffer(); | |
if(!strcmp(cmd, "PWD")){ | |
siprintf(tmpStr, "\"%s\"",currentPath); | |
ftp_sendResponse(s, 257, tmpStr); | |
}else if(!strcmp(cmd, "PASV")){ | |
char response[32]; | |
sprintf(response, "Entering Passive Mode (192,168,0,17,%d,%d)",(dataPort-(dataPort%256))/256,dataPort%256); | |
ftp_sendResponse(s, 200, response); | |
}else if(!strcmp(cmd, "LIST")){ | |
int data_s=ftp_openDataChannel(); | |
ftp_sendResponse(s, 150, "opening ASCII data channel"); | |
//send LIST data | |
Handle dirHandle; | |
FS_path dirPath=FS_makePath(PATH_CHAR, currentPath); | |
FSUSER_OpenDirectory(fsuHandle, &dirHandle, sdmcArchive, dirPath); | |
u32 entriesRead=0; | |
do{ | |
u16 entryBuffer[512]; | |
char data[256]; | |
FSDIR_Read(dirHandle, &entriesRead, 1, entryBuffer); | |
if(!entriesRead)break; | |
unicodeToChar(data, entryBuffer); | |
siprintf((char*)entryBuffer, "%crwxrwxrwx 2 3DS %d Feb 1 2009 %s\r\n",entryBuffer[0x21c/2]?'d':'-',entryBuffer[0x220/2]|(entryBuffer[0x222/2]<<16),data); | |
send(data_s, entryBuffer, strlen((char*)entryBuffer), 0); | |
}while(entriesRead>0); | |
u8 endByte=0x0; | |
send(data_s, &endByte, 1, 0); | |
FSDIR_Close(dirHandle); | |
closesocket(data_s); | |
ftp_sendResponse(s, 226, "transfer complete"); | |
}else if(!strcmp(cmd, "STOR")){ | |
ftp_sendResponse(s, 150, "opening binary data channel"); | |
int data_s=ftp_openDataChannel(); | |
sprintf(tmpStr, "%s%s",currentPath,arg); | |
Handle fileHandle; | |
FSUSER_OpenFile(fsuHandle, &fileHandle, sdmcArchive, FS_makePath(PATH_CHAR, tmpStr), FS_OPEN_WRITE|FS_OPEN_CREATE, 0); | |
int ret; | |
u32 totalSize=0; | |
while((ret=recv(data_s, dataBuffer, DATA_BUFFER_SIZE, 0))>0){FSFILE_Write(fileHandle, (u32*)&ret, totalSize, (u32*)dataBuffer, ret, 0x10001);totalSize+=ret;} | |
FSFILE_Close(fileHandle); | |
closesocket(data_s); | |
ftp_sendResponse(s, 226, "transfer complete"); | |
}else if(!strcmp(cmd, "RETR")){ | |
ftp_sendResponse(s, 150, "opening binary data channel"); | |
int data_s=ftp_openDataChannel(); | |
sprintf(tmpStr, "%s%s",currentPath,arg); | |
sprintf(testOutput, "\n%s",tmpStr); | |
Handle fileHandle; | |
FSUSER_OpenFile(fsuHandle, &fileHandle, sdmcArchive, FS_makePath(PATH_CHAR, tmpStr), FS_OPEN_READ, 0); | |
int ret; | |
u32 readSize=0; | |
u32 totalSize=0; | |
do{ | |
ret=FSFILE_Read(fileHandle, (u32*)&readSize, totalSize, (u32*)dataBuffer, DATA_BUFFER_SIZE); | |
if(ret || !readSize)break; | |
ret=send(data_s, dataBuffer, readSize, 0); | |
totalSize+=readSize; | |
}while(readSize && ret>0); | |
FSFILE_Close(fileHandle); | |
debugValue=ret; | |
closesocket(data_s); | |
ftp_sendResponse(s, 226, "transfer complete"); | |
}else if(!strcmp(cmd, "USER")){ | |
ftp_sendResponse(s, 200, "password ?"); | |
}else if(!strcmp(cmd, "PASS")){ | |
ftp_sendResponse(s, 200, "ok"); | |
}else if(!strcmp(cmd, "CWD")){ | |
if(arg[0]=='/')strcpy(currentPath,arg); | |
else strcat(currentPath,arg); | |
strcat(currentPath,"/"); | |
ftp_sendResponse(s, 200, "ok"); | |
}else if(!strcmp(cmd, "RETR")){ | |
ftp_sendResponse(s, 200, "ok"); | |
}else if(!strcmp(cmd, "TYPE")){ | |
ftp_sendResponse(s, 200, "changed type"); | |
}else if(!strcmp(cmd, "QUIT")){ | |
ftp_sendResponse(s, 221, "disconnecting"); | |
}else{ | |
ftp_sendResponse(s, 502, "invalid command"); | |
} | |
return 0; | |
} | |
int ftp_frame(int s) | |
{ | |
char buffer[512]; | |
memset(buffer, 0, 512); | |
recv(s,buffer,512,0); | |
return ftp_processCommand(s,buffer); | |
} | |
int main() | |
{ | |
svc_getSystemInfo(&DEBUGVAL[0],0,1); | |
initSrv(); | |
svc_getSystemInfo(&DEBUGVAL[1],0,1); | |
aptInit(APPID_APPLICATION); | |
svc_getSystemInfo(&DEBUGVAL[2],0,1); | |
gspGpuInit(); | |
svc_getSystemInfo(&DEBUGVAL[3],0,1); | |
hidInit(NULL); | |
srv_getServiceHandle(NULL, &fsuHandle, "fs:USER"); | |
FSUSER_Initialize(fsuHandle); | |
sdmcArchive=(FS_archive){0x9, (FS_path){PATH_EMPTY, 1, (u8*)""}}; | |
FSUSER_OpenArchive(fsuHandle, &sdmcArchive); | |
u32 blockAddr; | |
svc_controlMemory(&blockAddr, 0x8000000, 0x0, 0x1910000, MEMOP_COMMIT, 0x3); | |
debugValue=SOC_Initialize((u32*)0x8bae000, 0x100000); | |
aptSetupEventHandler(); | |
svc_getSystemInfo(&DEBUGVAL[4],0,1); | |
sprintf(currentPath, "/"); | |
int connfd = ftp_openCommandChannel(); | |
sprintf(tmpBuffer,"received connection ! %d\ngreeting...",connfd); | |
strcat(testOutput, tmpBuffer); | |
ftp_sendResponse(connfd, 200, "hello"); | |
APP_STATUS status; | |
frameHandler curHandler=menuHandler; | |
while((status=aptGetStatus())!=APP_EXITING) | |
{ | |
if(status==APP_RUNNING) | |
{ | |
ftp_frame(connfd); | |
if(curHandler)curHandler=(frameHandler)curHandler(); | |
renderEffect(); | |
swapBuffers(); | |
copyBuffer(); | |
// renderEffect(); | |
// swapBuffers(); | |
// copyBuffer(); | |
// renderEffect(); | |
// swapBuffers(); | |
// copyBuffer(); | |
} | |
svc_sleepThread(16666666); | |
} | |
// closesocket(connfd); | |
// GSPGPU_ReleaseRight(NULL); | |
svc_controlMemory(&blockAddr, (u32)blockAddr, 0x0, 0x1910000, MEMOP_FREE, 0x0); | |
FSUSER_CloseArchive(fsuHandle, &sdmcArchive); | |
SOC_Shutdown(); | |
svc_closeHandle(fsuHandle); | |
hidExit(); | |
gspGpuExit(); | |
aptExit(); | |
// exitSrv(); | |
*((u32*)0x58000000) = 4; | |
// svc_exitProcess(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment