250 lines
5.1 KiB
C
250 lines
5.1 KiB
C
#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) {
|
|
|
|
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);
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
//~ char result = 0;
|
|
|
|
//~ while(1){
|
|
|
|
//~ char byte = getchar();
|
|
|
|
//~ inBuffer += byte;
|
|
|
|
//~ if(inBuffer == "DONE"){
|
|
|
|
//~ FntPrint("inBuffer : %s", inBuffer);
|
|
|
|
//~ break;
|
|
|
|
//~ }
|
|
|
|
//~ }
|
|
|
|
//~ 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
|
|
|
|
char commandBuffer[28];
|
|
|
|
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);
|
|
}
|