From 179a080b3dd1324b83ad3c71f1782489a3c7fd67 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Tue, 4 May 2021 17:26:44 +0200 Subject: [PATCH] libsio stuff --- ovl-upload.c | 110 +++++++++++++++++++++++- ovl-upload.py | 12 +++ pcdrv.c | 231 +++++++++++++++++++++++++++++++++++++++++++++----- pcdrv.h | 39 ++++++--- 4 files changed, 358 insertions(+), 34 deletions(-) diff --git a/ovl-upload.c b/ovl-upload.c index b53193b..6d431b4 100644 --- a/ovl-upload.c +++ b/ovl-upload.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "pcdrv.h" @@ -118,14 +120,18 @@ u_short timer = 0; // pcdrv protocol -u_char escape = 0; // Hypothetical Escape char for unirom +u_char escape = 0x00; // Hypothetical Escape char for unirom -u_char protocol = 1; // Hypothetical ID number for the pcdrv protocol in unirom +u_char protocol = 0x01; // Hypothetical ID number for the pcdrv protocol in unirom u_char command = LOAD; // We're loading the data here uint32_t checkSum = 0; +const char * inBuffer = ""; + +char byte; + // Prototypes void init(void); @@ -207,6 +213,17 @@ void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lam } +//~ static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n) { + + //~ return n ? djbProcess ( ( ( hash << 5 ) + hash ) ^ str[0], str + 1, n - 1) : hash; +//~ } + +//~ static inline uint32_t djbHash( const char* str, unsigned n ){ + + //~ return djbProcess( 5381, str, n); + +//~ } + int main() { // Update this value to avoid trigger at launch @@ -266,6 +283,10 @@ int main() { LoadTexture(_binary_TIM_cubetex_tim_start, &tim_cube); + //~ static u_char SIOinit = 0; + + //~ static u_char SIO = 0; + // Main loop while (1) { @@ -325,6 +346,87 @@ int main() { } + // SIO FUN : USELESS as it hijacks unirom's SIO implementation... Keeping it for ref + + //~ static char * ok = "OKAY"; + + //~ static char * buffer = " "; + + //static u_char clearFlag = 1; + + //~ if( SIO ){ + + //~ // Is SIO is not init, dot it + + //~ if( ! SIOinit ){ + + //~ ResetCallback(); + + //~ AddSIO(115200); + + //~ ResetGraph(0); + + //~ SIO_CLEAR; + + //~ SIOinit = 1; + + //~ } + + //if ( clearFlag ){ + + //SIO_CLEAR; + + //clearFlag = 0; + + //} + + //~ if( strlen(buffer) > 4){ + + //~ memmove(buffer, buffer + 1, strlen(buffer)); + + //~ } + + //~ // Clears driver status error-related bits + + //~ // Check if sio driver is able to write communications data + + //~ if( SIO_STATUS & SR_RXRDY ){ + + //~ // Read byte + + //~ char c = SIO_READB; + + //~ // Add to buffer + + //~ strncat(buffer, &c, 1); + + //~ } + + //~ // Compare buffer to string + + //~ if( strcmp(ok, buffer) == 0) { + + //~ loadFileID = !loadFileID; + + //~ DelSIO(); + + //~ SIO = 0; + + //~ SIOinit = 0; + + //clearFlag = 1; + + //~ } + + //~ if( buffer ){ + + //~ FntPrint("%s", buffer); + + //~ } + //~ } + + // END SIO FUN + // Read pad status PadStatus = PadRead(0); @@ -339,6 +441,8 @@ int main() { PCload( &load_all_overlays_here, &loadFileID, overlayFileID ); + //~ SIO = 1; + #ifdef USECD // We can do that because we only have two files @@ -430,8 +534,6 @@ int main() { nextpri += sizeof(DR_MODE); - - FntPrint("Hello overlay!\n"); #ifndef USECD diff --git a/ovl-upload.py b/ovl-upload.py index 8ccae06..0acd471 100755 --- a/ovl-upload.py +++ b/ovl-upload.py @@ -340,6 +340,8 @@ def WriteBytes( inData ): print("ERROR ! Retrying...") + # ~ ser.write(b'ERR!') + raise Exception() if DEBUG: @@ -356,6 +358,12 @@ def WriteBytes( inData ): # END TRY/EXCEPT + # ~ ser.write(b'OKAY'); + + if DEBUG: + + print("Sending OKAY") + break # END WHILE TRUE @@ -500,6 +508,10 @@ def main(args): while ser.in_waiting: inputBuffer += ser.read().decode('ascii') + + if DEBUG > 2: + + print( "Raw data : " + inputBuffer ) if inputBuffer: diff --git a/pcdrv.c b/pcdrv.c index 4fc64de..a17b12c 100644 --- a/pcdrv.c +++ b/pcdrv.c @@ -1,5 +1,27 @@ #include "pcdrv.h" + +static char sio_read(){ + + char c; + + c = getchar(); + + return c; +}; + +u_int strLen( const char * str){ + + u_int l = 0; + + while ( * str++ ){ + + l++; + } + return l; + +}; + // Hashing algorythm from @nicolasnoble : https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n) { @@ -13,46 +35,215 @@ static inline uint32_t djbHash( const char* str, unsigned n ){ }; -int waitForSIODone( int * flag ){ +uint32_t charsToU32 ( char * byte ) { + + unsigned int packet = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | (byte[3]); + + return packet; + +}; + +u_char U32ToChars( u_int memoryAddress, u_int byteNbr){ + + // This one I found on my own )'u'( + + u_char byte = { 0 }; + + byte = ( (u_int) memoryAddress >> ( 24 - (byteNbr << 3) ) ) & 0xFF; + + return byte; + +}; + +void sendU32(uint32_t data) { + + putchar(data & 0xff); + + data >>= 8; + + putchar(data & 0xff); + + data >>= 8; + + putchar(data & 0xff); + + data >>= 8; + + putchar(data & 0xff); + +}; + +void sendRU32(uint32_t data) { + + putchar((data >> 24) & 0xff); + + putchar((data >> 16) & 0xff); + + putchar((data >> 8) & 0xff); + + putchar(data & 0xff); + +}; + +//~ int waitForSIODone(){ // This should wait for a signal from the SIO to tell when it's done // Returns val < 0 if wrong + //~ const char * inBuffer = ""; - uint16_t timeOut = 1000; + //~ uint16_t timeOut = 1000; - char result = 0; + //~ char result = 0; - for ( uint t = 0; t < timeOut; t ++){ + //~ while(1){ - if ( * flag == 1 ){ - - result = * flag; - - break; - } + //~ char byte = getchar(); - } + //~ inBuffer += byte; + + //~ if(inBuffer == "DONE"){ + + //~ FntPrint("inBuffer : %s", inBuffer); + + //~ break; + + //~ } + + //~ } - return result; + //~ return 1; -}; +//~ }; void PCload( u_long * loadAddress, volatile u_char * flagAddress, u_char overlayFileID ) { // Send filename , load address, and flag address + // E.G : 00 01 06 04 8001000 04 80010001 01 + 0000000000 <- cmd checksum - u_char escape = 0; // Hypothetical Escape char for unirom - - u_char protocol = 1; // Hypothetical protocol indicator for unirom - - //~ u_char cmdChecksum = 0; // Not using that yet, ideally, should allow to check that the received command on the pc is the same as the one sent by the psx - char commandBuffer[28]; - sprintf(commandBuffer, "%02u%02u%02u08%08x08%08x%02u", escape, protocol, LOAD, loadAddress, flagAddress, overlayFileID); + sprintf(commandBuffer, "%02u%02u%02u08%08x08%08x%02u", ESCAPE, PROTOCOL, LOAD, loadAddress, flagAddress, overlayFileID); u_int cmdChecksum = djbHash(commandBuffer, 28); printf("%s%10u", commandBuffer, cmdChecksum); + //~ waitForSIODone(); + }; + + +int PCopen( const char * filename, int mode ){ + + // Open filename in mode + // Returns file descriptor or -1 if fail + + u_int bufferLen = 10 + strLen( filename ); + + char commandBuffer[ bufferLen ]; + + sprintf(commandBuffer, "%02u%02u%02u%02u%s%02u", ESCAPE, PROTOCOL, OPEN, bufferLen, filename, mode); + + u_int cmdChecksum = djbHash( commandBuffer, bufferLen); + + printf("%s%10u", commandBuffer, cmdChecksum); + +} + + +// WIP : Build command for use with putchar instead of printf + +void BuildCmd(){ + //~ // Build command in the buffer + + u_char escape = 0; // Hypothetical Escape char for unirom + + u_char protocol = 1; // Hypothetical protocol indicator for unirom + + //~ // Command is 14 B data + 5 B checksum + + u_char commandBuffer[19] = {0}; + + u_char checkSumLen = 5; + + short i = 0; + + u_long * loadAddress; + + u_char * flagAddress; + + // FntPrint("%x\n", loadAddress); + + + while( i < sizeof( commandBuffer) - checkSumLen ){ + + if( i == 0 ){ + commandBuffer[0] = escape; + commandBuffer[1] = protocol; + i = 2; + } + + if( i == 2 ){ + commandBuffer[i] = LOAD; + i ++; + } + + commandBuffer[i] = sizeof(&loadAddress); + + i ++; + + for( u_int b = 0; b < sizeof(&loadAddress); b++ ){ + + commandBuffer[i] = U32ToChars( ( u_int ) loadAddress, b ); + + // FntPrint("i: %d b: %d, %02x\n", i, b, commandBuffer[i]); + + i++; + + } + + commandBuffer[i] = sizeof(&flagAddress); + + i ++; + + for( u_int b = 0; b < sizeof(&flagAddress); b++ ){ + + commandBuffer[i] = U32ToChars( ( u_int ) flagAddress, b ); + + // FntPrint("i: %d b: %d, %02x\n", i, b, commandBuffer[i]); + + i++; + + } + + //~ commandBuffer[i] = overlayFileID; + + i++; + + for(short c = 0; c < sizeof(commandBuffer) - checkSumLen; c++){ + + //~ FntPrint("%x", commandBuffer[c]); + } + // FntPrint("\n%d, %d", i, sizeof(commandBuffer) ); + + + + } + + for(u_int b = 0; b < sizeof(commandBuffer)-3; b+=4 ){ + + u_char bytes[4] = {0}; + + bytes[0] = commandBuffer[b + 0]; + bytes[1] = commandBuffer[b + 1]; + bytes[2] = commandBuffer[b + 2]; + bytes[3] = commandBuffer[b + 3]; + + sendU32( charsToU32(bytes) ); + + } + + // u_int cmdChecksum = djbHash((const char * )commandBuffer, sizeof(commandBuffer) - checkSumLen); + + // FntPrint("\n%d\n", cmdChecksum); +} diff --git a/pcdrv.h b/pcdrv.h index a735b6a..3adb6eb 100644 --- a/pcdrv.h +++ b/pcdrv.h @@ -23,33 +23,52 @@ // (escape) (pcdrv command) (pcdrv open) (filename with length as prefix) (attributes) (checksum) - #pragma once #include #include #include +#include +#define SIO_CLEAR _sio_control(2,1,0) +#define SIO_STATUS _sio_control(0,0,0) +#define SIO_CONTROL _sio_control(0,1,0) +#define SIO_READB _sio_control(0,4,0) + + +#define ESCAPE 00 // Hypothetical Escape char for unirom + +#define PROTOCOL 01 //pcdrv commands -#define OPEN 0 -#define CLOSE 1 -#define SEEK 2 -#define READ 3 -#define WRITE 4 -#define CREATE 5 -#define LOAD 6 +#define OPEN 00 +#define CLOSE 01 +#define SEEK 02 +#define READ 03 +#define WRITE 04 +#define CREATE 05 +#define LOAD 06 + +static char sio_read(); static inline uint32_t djbHash( const char* str, unsigned n ); static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n); -int waitForSIODone( int * flag ); +uint32_t charsToU32 ( char * byte ); + +u_char U32ToChars( u_int memoryAddress, u_int byteNbr); + +void sendU32(uint32_t data); + +void sendRU32(uint32_t data); + +int waitForSIODone(); void PCload( u_long * loadAddress, volatile u_char * flagAddress, u_char overlayFileID ); -int PCopen( const char * filename, int attributes ); +int PCopen( const char * filename, int mode ); int PCcreate(const char * filename, int attributes );