Add read/write/seek/open/close functions handler

This commit is contained in:
ABelliqueux 2021-05-20 10:56:34 +02:00
parent 362bdb244b
commit 2371e8fa32
5 changed files with 805 additions and 106 deletions

View File

@ -36,7 +36,8 @@
#include "pcdrv.h"
// If USECD is defined, files will be loaded from the CD. Use this method for testing in an emulator.
// Additionaly, generate the bin/cue with mkpsxiso.
// Additionaly, generate the bin/cue with mkpsxiso :
// $ mkpsxiso -y config/OverlayExample.xml
//~ #define USECD
@ -126,12 +127,10 @@ u_char command = LOAD; // We're loading the data here
uint32_t checkSum = 0;
//~ const char OKAY[4] = "OKYA";
volatile u_char inBuffer[BUFFER_LEN] = {0};
volatile u_char inBuffer[4] = " ";
volatile u_char dataBuffer[64] = "ALLEZONYVALESENFANTS";
//~ char byte;
// Prototypes
void init(void);
@ -176,7 +175,7 @@ void init(){
// Init font system
FntLoad(960, 0);
FntOpen(16, 16, 196, 96, 0, 356);
FntOpen(16, 16, 196, 196, 0, 512);
}
@ -213,6 +212,10 @@ void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lam
}
int returnVal = 0;
int fileCreated = 0;
int main() {
// Update this value to avoid trigger at launch
@ -273,16 +276,24 @@ int main() {
LoadTexture(_binary_TIM_cubetex_tim_start, &tim_cube);
// Main loop
while (1) {
FntPrint("%08d - ", returnVal);
//~ if ( returnVal > 0 ){
//~ returnVal = PCopen("HELO.WLD", O_RDWR, inBuffer);
//~ fileCreated = returnVal;
//~ returnVal = 0;
//~ }
// Overlay switch
if ( overlayFileID != loadFileIDwas ){
// Update previous file value
loadFileIDwas = overlayFileID;
// Change file to load
switch ( overlayFileID ){
@ -315,22 +326,30 @@ int main() {
#ifndef USECD
if (! PCload( &load_all_overlays_here, inBuffer, &overlayFileID ) ){
//~ returnVal = PCopen("HELO.WLD", O_RDWR, inBuffer);
//~ returnVal = PCcreate("HELO.WLD", O_RDWR, inBuffer);
//~ returnVal = PCseek(1, 0, 369, 1, inBuffer);
//~ returnVal = PCread(88, 369, 16, dataBuffer, inBuffer);
returnVal = PCwrite(88, 10, 5, dataBuffer, inBuffer);
if ( returnVal ){
overlayFileID = !overlayFileID;
loadFileIDwas = overlayFileID;
loadFileIDwas = !loadFileIDwas;
};
}
#endif
#ifdef USECD
cdread = CdReadFile( (char *)(overlayFile), &load_all_overlays_here, 0);
CdReadSync(0, 0);
if ( CdReadSync(0, 0) == 0 ){
loadFileIDwas = overlayFileID;
}
#endif
}
@ -352,7 +371,7 @@ int main() {
if ( ( PadStatus & PADselect ) && !timer ) {
overlayFileID = !overlayFileID;
timer = 150;
}
@ -446,6 +465,8 @@ int main() {
FntPrint("buffer at %08x : %s\n", inBuffer, inBuffer);
FntPrint("dataBuffer at %08x : \n %s", dataBuffer, dataBuffer);
#endif
#ifdef USECD

View File

@ -40,13 +40,30 @@ pcdrvProtocol = '01'
# Commands
LOAD = '06'
OPEN = '00'
CLOSE = '01'
SEEK = '02'
READ = '03'
WRITE = '04'
CREAT = '05'
LOAD = '06'
INIT = '07'
OPEN = '00'
# Param sets
loadParams = {'memAddr':-1,'bufferAddr':-1, 'loadFile':-1}
loadParams = {'memAddr':-1, 'loadFile':-1, 'bufferAddr':-1}
openParams = {'fileName':-1,'bufferAddr':-1,'mode':-1}
creatParams = {'fileName':-1, 'bufferAddr':-1, 'mode':-1}
openParams = {'fileName':-1, 'bufferAddr':-1,'mode':-1 }
closeParams = {'fileDesc':-1, 'bufferAddr':-1}
seekParams = {'fileDesc':-1,'curPos': -1,'offset':-1, 'bufferAddr':-1, 'accessMode':-1}
readParams = {'fileDesc':-1,'pos': -1, 'length':-1, 'dataAddr':-1, 'bufferAddr':-1}
writeParams = {'fileDesc':-1,'pos': -1, 'length':-1, 'data':-1, 'bufferAddr':-1}
paramBuffer = {}
@ -101,6 +118,26 @@ Transfer = 0
sleepTime = 0.08 # Seems like safe minimum
# https://www.tutorialspoint.com/How-to-close-all-the-opened-files-using-Python
class openFiles():
def __init__(self):
self.files = []
def open(self, file_name, mode):
f = os.open(file_name, mode)
self.files.append(f)
return f
def close(self):
list( map( lambda f : os.close(f), self.files ) )
def setDEBG():
global sleepTime, ser, uniDebugMode
@ -122,7 +159,6 @@ def setDEBG():
uniDebugMode = 1
# stole it here : https://gist.github.com/amakukha/7854a3e910cb5866b53bf4b2af1af968
# TODO : fixit to have the same results as https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h
def hash_djb2(s):
@ -235,13 +271,15 @@ def getData(dataInBuffer):
# Get data length byte
# If only 2 bytes left, dont't bother
if len(dataInBuffer) == 2:
parsedData = dataInBuffer
dataInBuffer = ""
return [dataInBuffer, parsedData] # does it break ?
return [dataInBuffer, parsedData]
dataLen = int( dataInBuffer[:2] )
@ -515,10 +553,12 @@ def resetListener():
def main(args):
files = openFiles()
while True:
global checkSum, checkSumLen, data, Listen, Transfer, dataSize, loadFile, paramBuffer
# Flush serial buffers to avoid residual data
ser.reset_input_buffer()
@ -573,7 +613,6 @@ def main(args):
# Remove checksum from data
# ~ inputBuffer = inputBuffer[:28]
inputBuffer = inputBuffer[:-checkSumLen]
dataCheckSum = hash_djb2(bytes(inputBuffer, 'ascii'))
@ -612,9 +651,18 @@ def main(args):
print( "Received Cmd: " + inputBuffer[:2] )
# Command butes are OPEN == 00
if inputBuffer[:2] == INIT:
paramTmp = {}
Command = INIT
# Command bytes are LOAD == 06
if inputBuffer[:2] == LOAD:
elif inputBuffer[:2] == LOAD:
# Set corresponding parameters and mode
@ -629,7 +677,47 @@ def main(args):
paramTmp = openParams
Command = OPEN
# Command butes are OPEN == 00
elif inputBuffer[:2] == CLOSE:
paramTmp = closeParams
Command = CLOSE
# Command butes are OPEN == 00
elif inputBuffer[:2] == SEEK:
paramTmp = seekParams
Command = SEEK
# Command butes are OPEN == 00
elif inputBuffer[:2] == READ:
paramTmp = readParams
Command = READ
# Command butes are OPEN == 00
elif inputBuffer[:2] == WRITE:
paramTmp = writeParams
Command = WRITE
# Command butes are OPEN == 00
elif inputBuffer[:2] == CREAT:
paramTmp = creatParams
Command = CREAT
else:
print("Command not recognized : got " + inputBuffer[:2] )
@ -661,7 +749,7 @@ def main(args):
ser.reset_input_buffer()
inputBuffer = ""
Listen = 0
break
@ -674,14 +762,6 @@ def main(args):
inputBuffer = ""
break
# ~ else:
# ~ ser.reset_input_buffer()
# ~ inputBuffer = ""
# ~ break
if len(paramBuffer):
@ -695,7 +775,43 @@ def main(args):
break
if Command == INIT:
# Close all opened files
files.close()
# Send OK
SendBin( b'OKYA' , paramBuffer['bufferAddr'])
if Command == CLOSE:
fileDesc = paramBuffer['fileDesc']
# Close all opened files
try:
os.close(fileDesc)
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print(errMsg)
return 0
# Send OK
SendBin( b'OKYA' , paramBuffer['bufferAddr'])
if Command == LOAD:
# Load file
print("Received LOAD.")
if DEBUG > 1:
@ -749,17 +865,13 @@ def main(args):
print("DONE!")
# ~ else:
# ~ print(" No filename provided, doing nothing. ")
# ~ resetListener()
if Command == OPEN:
# Open file
print("Received OPEN.")
# paramBuffer['mode'] can be 0 (RO), 1(WO), 2 (RW)
# paramBuffer['mode'] can be 0 (RO), 1(WO), 2 (RW). See `pcdrv.h` l.52
osMode = os.O_RDONLY
@ -771,26 +883,347 @@ def main(args):
osMode = os.O_RDWR
if os.path.isfile( 'work/' + paramBuffer['fileName']):
# ~ if os.path.isfile( 'work/' + paramBuffer['fileName']):
localFile = os.open( 'work/' + paramBuffer['fileName'], osMode )
try:
# Open file in osMode.
localFile = files.open( 'work/' + paramBuffer['fileName'], osMode )
if DEBUG:
print("File opened. FD : " + str(localFile))
# Return fd.
SendBin( b'DT' + bytes( str(localFile), 'ascii' ), paramBuffer['bufferAddr'])
# ~ time.sleep( sleepTime )
# ~ SendBin( bytes( str(localFile), 'ascii' ), paramBuffer['bufferAddr'])
else:
# ~ else:
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print(errMsg + " - Try using PCcreate()")
return 0
resetListener()
print("DONE!")
# ~ break
if Command == CREAT:
# Create and open file
print("Received CREAT.")
# Should we return an error if file exists ?
if not os.path.isfile( 'work/' + paramBuffer['fileName']):
# paramBuffer['mode'] can be 0 (RO), 1(WO), 2 (RW)
osMode = os.O_RDONLY
if int(paramBuffer['mode']) == 1:
osMode = os.O_WRONLY
else:
osMode = os.O_RDWR
# We're using osMode | os.O_CREAT as open mode here.
localFile = files.open( 'work/' + paramBuffer['fileName'], osMode | os.O_CREAT )
if DEBUG:
print("File created. FD : " + str(localFile))
# Return fd.
SendBin( b'DT' + bytes( str(localFile), 'ascii' ), paramBuffer['bufferAddr'])
else:
SendBin( b'-1', paramBuffer['bufferAddr'])
print("File exists ! Use PCopen.")
resetListener()
print("DONE!")
if Command == SEEK:
# Seek pos in open file
print("Received SEEK.")
# mode can be 0 (rel to start), 1(rel to cur pos), 2 (rel to end)
# ~ fd = int( paramBuffer['fileDesc'] )
fd = files.open("work/" + 'HELO.WLD', os.O_RDWR)
mode = int( paramBuffer['accessMode'] )
offset = int( paramBuffer['offset'] )
curPos = int( paramBuffer['curPos'] )
# get filesize in bytes
try:
# fileEnd corresponds to file size in bytes
fileEnd = os.stat(fd).st_size
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print( errMsg )
resetListener()
return 0
# by default, use mode 0
pos = offset
if mode == 1:
pos = curPos + offset
if mode == 2:
pos = fileEnd - offset
# avoid overflow
if pos > fileEnd:
pos = fileEnd
if pos < 0:
pos = 0
if DEBUG :
print( "Fd : " + str(fd) + "\n" +
"Mode : " + str(mode) + "\n" +
"Ofst : " + str(offset) + "\n" +
"curPos: "+ str(curPos) + "\n" +
"Pos : " + str(pos)
)
try:
# TODO : replace os.lseek() with file.lseek
curPos = os.lseek( fd, pos, mode )
if DEBUG:
print( "File seeked. CP : " + str(curPos) )
# Return fd.
SendBin( b'DT' + bytes( str(curPos), 'ascii' ), paramBuffer['bufferAddr'])
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print( errMsg )
resetListener()
return 0
resetListener()
print("DONE!")
if Command == READ:
# Read from pos in open file
print("Received READ.")
# ~ fd = int( paramBuffer['fileDesc'] )
fd = files.open("work/" + 'HELO.WLD', os.O_RDWR)
length = int( paramBuffer['length'] )
pos = int( paramBuffer['pos'] )
# get filesize in bytes
try:
# fileEnd corresponds to file size in bytes
fileEnd = os.stat(fd).st_size
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print( errMsg )
resetListener()
return 0
if DEBUG :
print( "Fd : " + str(fd) + "\n" +
"Length : " + str(length) + "\n" +
"Pos : " + str(pos) + "\n" +
"dataBuffer : " + paramBuffer['dataAddr']
)
# Avoid overflow
if pos + length > fileEnd:
length = fileEnd - pos
if pos == fileEnd:
print("End of file reached. Doing nothing")
SendBin( b'OKYA', paramBuffer['bufferAddr'])
resetListener()
return 0
try:
# TODO : replace os.pread() with file.pread
readBytes = os.pread( fd, length, pos )
if DEBUG:
print( "File read. Bytes : " + str( readBytes ) )
# Send data to data buffer
dataSent = SendBin( readBytes, paramBuffer['dataAddr'])
# ~ time.sleep(sleepTime)
# Send OK if all went well
if dataSent:
SendBin( b'OKYA', paramBuffer['bufferAddr'])
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print( errMsg )
resetListener()
return 0
resetListener()
print("DONE!")
if Command == WRITE:
# Write to pos in open file
print("Received WRITE.")
# ~ fd = int( paramBuffer['fileDesc'] )
fd = files.open("work/" + 'HELO.WLD', os.O_RDWR)
length = int( paramBuffer['length'] )
pos = int( paramBuffer['pos'] )
data = paramBuffer['data']
# ~ # Avoid overflow
# ~ if pos + length > bufferLength:
# ~ length = bufferLength - pos
# ~ if pos == bufferLength:
# ~ print("End of buffer reached. Doing nothing")
# ~ SendBin( b'OKYA', paramBuffer['bufferAddr'])
# ~ resetListener()
# ~ return 0
if DEBUG :
print( "Fd : " + str(fd) + "\n" +
"Length : " + str(length) + "\n" +
"Pos : " + str(pos) + "\n" +
"data : " + data
)
try:
# TODO : replace os.pread() with file.pread
writeBytes = os.pwrite( fd, bytes( data, 'ascii' ), pos )
if DEBUG:
print( "Buffer write. Bytes : " + str( writeBytes ) )
# Send OK if all went well
if writeBytes == length:
SendBin( b'OKYA', paramBuffer['bufferAddr'])
except OSError as errMsg:
SendBin( b'-1', paramBuffer['bufferAddr'])
print( errMsg )
resetListener()
return 0
resetListener()
print("DONE!")
return 0
if __name__ == '__main__':

317
pcdrv.c
View File

@ -3,13 +3,13 @@
void wait(){
for(u_int wait = 0; wait < 100; wait++){
for(u_int wait = 0; wait < 60; wait++){
wait = wait;
}
};
/*
static char sio_read(){
char c;
@ -30,6 +30,7 @@ u_int strLen( const char * str){
return l;
};
*/
// Hashing algorythm from @nicolasnoble : https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h
@ -44,6 +45,7 @@ static inline uint32_t djbHash( const char* str, unsigned n ){
};
/*
uint32_t charsToU32 ( char * byte ) {
unsigned int packet = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | (byte[3]);
@ -93,55 +95,110 @@ void sendRU32(uint32_t data) {
putchar(data & 0xff);
};
*/
int waitForSIODone( const char * answer, volatile char * bufferAddress){
// This watches the buffer at &bufferAddress and waits for it to contain the first two chars of answer,
// which is sent by the server when PC->PSX data upload is over.
// If answer is OK, act as ACK. If answer is DT, the next 2 chars contains data.
// Returns 1 if ok, 0 else.
// Return value
int SIOdone = 0;
// Error code sent by the PC
const char * error = "-1";
u_short waitForSIODone( volatile u_char * bufferAddress){
// Mini buffer for the data when two first chars are DT
char returnValue[BUFFER_LEN] = {0};
// This should wait for a signal from the SIO to tell when it's done
// Returns 1 if ok, 0 else
const char * OKYA = "OKYA";
u_char SIOdone = 0;
// Counter to avoid infinite loop
int i = 0;
while(1){
const u_char * buffer = ( const u_char * )bufferAddress;
// Continually get the content at &bufferAddress
const char * buffer = ( const char * )bufferAddress;
// Rolling buffer
if( strlen( buffer ) > 4){
if( strlen( buffer ) > BUFFER_LEN){
memmove( ( u_char * ) buffer, buffer + 1, strlen(buffer));
memmove( ( char * ) buffer, buffer + 1, strlen(buffer));
}
// Check inBuffer for answer
if( strcmp(buffer, OKYA) == 0 ){
SIOdone = 1;
break;
// If buffer does not contain "-1"
if ( buffer[0] != error[0] && buffer[1] != error[1] ){
// If two first chars == answer
if( (buffer[0] == answer[0]) &&
(buffer[1] == answer[1]) ){ // "DT369000"
memmove( ( char * ) buffer, buffer + 2, strlen(buffer)); // "36900000"
//~ returnValue[0] = buffer[0];
//~ returnValue[1] = buffer[1];
for(short i = 0; i < BUFFER_LEN; i++){ // "00000000" >
returnValue[i] = buffer[i];
}
//~ returnValue[0] = buffer[2];
//~ returnValue[1] = buffer[3];
//~ returnValue[2] = buffer[4];
// Get data as int
SIOdone = atoi(returnValue);
// Empty buffer
for (short i; i < BUFFER_LEN; i++ ){ bufferAddress[i] = 0; }
// Return data
return SIOdone;
}
} else {
return -1;
}
i++;
// Avoid infinite loop
if ( i > 1000 ){
if ( i > 2000 ){
break;
// empty buffer
for ( short i; i < BUFFER_LEN;i++ ){ bufferAddress[i] = 0; }
// Get out of function after X iterations
return 0;
}
}
for (short i; i < 4;i++){ bufferAddress[i] = 0; }
// Should never be reached, but just to be sure
return SIOdone;
return 0;
};
@ -152,9 +209,19 @@ u_short PCload( u_long * loadAddress, volatile u_char * bufferAddress, u_char *
// E.G : 00 01 06 04 80010000 08 80010001 01 + 0000000000 <- cmd checksum
// 00 01 06 08 8003edf8 08 8001f0f0 00 2439964735 -> 38 Bytes
// Expected answer
const char * answer = "OK";
// Using hardcoded length of 28 B
char commandBuffer[28];
sprintf(commandBuffer, "%02u%02u%02u%02u%08x%02u%08x%02u", ESCAPE, PROTOCOL, LOAD, sizeof(loadAddress), loadAddress,sizeof(bufferAddress), bufferAddress, *overlayFileID);
// pointer is 4 B, but represented here by 8 B / chars.
u_short addLenInChar = sizeof(loadAddress) * 2;
sprintf(commandBuffer, "%02u%02u%02u%02u%08x%02u%08x%02u", ESCAPE, PROTOCOL, LOAD, addLenInChar, loadAddress, addLenInChar, bufferAddress, *overlayFileID);
u_int cmdChecksum = djbHash(commandBuffer, 28);
@ -163,22 +230,23 @@ u_short PCload( u_long * loadAddress, volatile u_char * bufferAddress, u_char *
// Need delay ?
wait();
return waitForSIODone(bufferAddress);
return waitForSIODone( answer , bufferAddress );
};
int PCopen( const char * filename, u_char mode, volatile u_char * bufferAddress ){
// Open filename in mode
// Returns file descriptor or -1 if fail
// E.G : 00 01 00 04 48454C4F 00 + 0000000000 <- cmd checksum 18 + CHECKSUM_LEN B
u_int bufferLen = 10 + strlen( filename );
int PCinit( volatile u_char * bufferAddress ){
// Close all the files on the PC.
// Returns OK if success, -1 if fail
// E.G : 00 01 07 + 00 00 00 00 00
const char * answer = "OK";
u_int bufferLen = 6;
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u%02u%*s%02u", ESCAPE, PROTOCOL, OPEN, strlen( filename ), strlen( filename ), filename, mode);
sprintf(commandBuffer, "%02u%02u%02u", ESCAPE, PROTOCOL, INIT);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
@ -186,12 +254,180 @@ int PCopen( const char * filename, u_char mode, volatile u_char * bufferAddress
wait();
return waitForSIODone(bufferAddress);
}
return waitForSIODone( answer, bufferAddress );
};
int PCclose( int fileDesc, volatile u_char * bufferAddress ){
// Close file corresponding to fileDesc
// Returns OK if success, -1 if fail
// E.G : 00 01 01 16 + 00 00 00 00 00
const char * answer = "OK";
u_int bufferLen = 8;
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u%02u", ESCAPE, PROTOCOL, CLOSE, fileDesc);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
return waitForSIODone( answer, bufferAddress );
};
int PCopen( const char * filename, u_char mode, volatile u_char * bufferAddress ){
// Open filename in mode
// Returns file descriptor or -1 if fail
// Mode can be 00 (RO), 01(WO), 02 (RW) (see pcdrv.h, l.52)
// E.G : 00 01 00 08 48454C4F 00 + 0000000000 <- cmd checksum 18 + CHECKSUM_LEN B
// Expected answer DaTa + 2 chars of data
const char * answer = "DT";
// Should we allow names > 8 chars ? If so, use strlen() to determine buffer length
u_int bufferLen = 20 + strlen( filename ); // else use a length of 28
u_short addLenInChar = sizeof(bufferAddress) * 2;
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u%02u%*s%02u%08x%02u", ESCAPE, PROTOCOL, OPEN, strlen( filename ), strlen( filename ), filename, addLenInChar, bufferAddress, mode);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
return waitForSIODone( answer, bufferAddress );
};
int PCcreate( const char * filename, u_char mode, volatile u_char * bufferAddress ){
// Create and open file with filename in mode
// Returns file descriptor or -1 if fail
// Mode can be 00 (RO), 01(WO), 02 (RW) (see pcdrv.h, l.52)
// E.G : 00 01 00 08 48454C4F 00 + 0000000000 <- cmd checksum 18 + CHECKSUM_LEN B
// Expected answer DaTa + 2 chars of data
const char * answer = "DT";
u_int bufferLen = 20 + strlen( filename );
u_short addLenInChar = sizeof(bufferAddress) * 2;
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u%02u%*s%02u%08x%02u", ESCAPE, PROTOCOL, CREATE, strlen( filename ), strlen( filename ), filename, addLenInChar, bufferAddress, mode);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
return waitForSIODone( answer, bufferAddress );
};
int PCseek( int fd, int curPos, int offset, int accessMode, volatile u_char * bufferAddress ){
// Seek offset in file
// Return new position or -1 if fail
// accessMode can be relative to start : 0 , relative to current pos : 1 , relative to end of file : 2
// E.G : 00 01 02 02 09 08 00000000 08 00000369 08 80025808 01 1907502951
const char * answer = "DT";
u_int bufferLen = 42; // Will we need file desc > 99 ?
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u02%02u08%08d08%08d08%08x%02u", ESCAPE, PROTOCOL, SEEK, fd, curPos, offset, bufferAddress, accessMode);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
return waitForSIODone( answer, bufferAddress );
};
int PCread( int fd, int pos, int len, volatile char * dataBuffer, volatile char * bufferAddress ){
// Read and returns len bytes at pos on file fd
// Send read bytes to dataBuffer
// Return OK or -1 if fail
// E.G : 00 01 03 02 88 08 00000369 08 00000016 08 80025808 08 80025848 1841163114
const char * answer = "OK";
u_int bufferLen = 50;
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u02%02u08%08d08%08d08%08x08%08x", ESCAPE, PROTOCOL, READ, fd, pos, len, dataBuffer, bufferAddress);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
return waitForSIODone( answer, bufferAddress );
};
int PCwrite( int fd, int pos, int len, volatile u_char * dataBuffer, volatile u_char * bufferAddress ){
// Send len bytes from dataBuffer to be written in file fd at pos
// Return OK or -1 if fail
// E.G : 00 01 04 02 88 08 00000000 08 00000016 16 ALLEZONYVALESENF 08 80025808 4060903934
const char * answer = "OK";
// Add space for null terminator
u_char tempBuffer[len];
// Fill tempBuffer with data at dataBuffer
for( int b = 0; b < len; b++ ){
tempBuffer[b] = dataBuffer[b];
}
// Set null terminator
//~ tempBuffer[len] = 0;
u_int bufferLen = 42 + sizeof(tempBuffer);
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u02%02u08%08d08%08d%02u%*s08%08x", ESCAPE, PROTOCOL, WRITE, fd, pos, len, len, len, tempBuffer, bufferAddress);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
return waitForSIODone( answer, bufferAddress );
};
// WIP : Build command for use with putchar instead of printf
/*
void BuildCmd(){
// Build command in the buffer
@ -261,13 +497,13 @@ void BuildCmd(){
}
//~ commandBuffer[i] = overlayFileID;
// commandBuffer[i] = overlayFileID;
i++;
for(short c = 0; c < sizeof(commandBuffer) - checkSumLen; c++){
//~ FntPrint("%x", commandBuffer[c]);
// FntPrint("%x", commandBuffer[c]);
}
// FntPrint("\n%d, %d", i, sizeof(commandBuffer) );
@ -292,3 +528,4 @@ void BuildCmd(){
// FntPrint("\n%d\n", cmdChecksum);
}
*/

32
pcdrv.h
View File

@ -27,10 +27,13 @@
#include <sys/types.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
//~ #include <libsio.h>
#include <string.h>
#define BUFFER_LEN 8
#define ESCAPE 0x00 // Hypothetical Escape char for unirom
#define PROTOCOL 0x01
@ -38,12 +41,13 @@
//pcdrv commands
#define OPEN 0x00
#define CLOSE 0x01
#define CLOSE 0x01
#define SEEK 0x02
#define READ 0x03
#define WRITE 0x04
#define CREATE 0x05
#define LOAD 0x06
#define INIT 0x07
// flags parameters
@ -51,32 +55,36 @@
#define O_WRONLY 0x01
#define O_RDWR 0x02
#define CHECKSUM_LEN 9
#define CHECKSUM_LEN 10
static char sio_read();
//~ static char sio_read();
u_short waitForSIODone( volatile u_char * bufferAddress);
int waitForSIODone( const char * answer, volatile char * bufferAddress);
static inline uint32_t djbHash( const char* str, unsigned n );
static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n);
uint32_t charsToU32 ( char * byte );
//~ uint32_t charsToU32 ( char * byte );
u_char U32ToChars( u_int memoryAddress, u_int byteNbr);
//~ u_char U32ToChars( u_int memoryAddress, u_int byteNbr);
void sendU32(uint32_t data);
//~ void sendU32(uint32_t data);
void sendRU32(uint32_t data);
//~ void sendRU32(uint32_t data);
u_short PCload( u_long * loadAddress, volatile u_char * bufferAddress, u_char * overlayFileID );
int PCinit( volatile u_char * bufferAddress );
int PCclose( int fileDesc, volatile u_char * bufferAddress );
int PCopen( const char * filename, u_char mode, volatile u_char * bufferAddress );
int PCcreate(const char * filename, int attributes );
int PCcreate( const char * filename, u_char mode, volatile u_char * bufferAddress );
int PCclose( int fd );
int PCseek( int fd, int curPos, int offset, int accessMode, volatile u_char * bufferAddress );
int PCseek( int fd, int offset, int accessMode );
int PCread( int fd, int pos, int len, volatile char * dataBuffer, volatile char * bufferAddress );
int PCread( int fd, int len, char * buffer );
int PCwrite( int fd, int pos, int len, volatile u_char * dataBuffer, volatile u_char * bufferAddress );

BIN
pcdrv.h.gch Normal file

Binary file not shown.