Add read/write/seek/open/close functions handler
This commit is contained in:
parent
362bdb244b
commit
2371e8fa32
51
ovl-upload.c
51
ovl-upload.c
@ -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,11 +127,9 @@ 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] = " ";
|
||||
|
||||
//~ char byte;
|
||||
volatile u_char dataBuffer[64] = "ALLEZONYVALESENFANTS";
|
||||
|
||||
// Prototypes
|
||||
|
||||
@ -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,13 +326,17 @@ 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);
|
||||
|
||||
overlayFileID = !overlayFileID;
|
||||
if ( returnVal ){
|
||||
|
||||
loadFileIDwas = !loadFileIDwas;
|
||||
loadFileIDwas = overlayFileID;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -329,7 +344,11 @@ int main() {
|
||||
|
||||
cdread = CdReadFile( (char *)(overlayFile), &load_all_overlays_here, 0);
|
||||
|
||||
CdReadSync(0, 0);
|
||||
if ( CdReadSync(0, 0) == 0 ){
|
||||
|
||||
loadFileIDwas = overlayFileID;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -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
|
||||
|
491
ovl-upload.py
491
ovl-upload.py
@ -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'
|
||||
|
||||
loadParams = {'memAddr':-1,'bufferAddr':-1, 'loadFile':-1}
|
||||
# Param sets
|
||||
|
||||
openParams = {'fileName':-1,'bufferAddr':-1,'mode':-1}
|
||||
loadParams = {'memAddr':-1, 'loadFile':-1, 'bufferAddr':-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,6 +553,8 @@ def resetListener():
|
||||
|
||||
def main(args):
|
||||
|
||||
files = openFiles()
|
||||
|
||||
while True:
|
||||
|
||||
global checkSum, checkSumLen, data, Listen, Transfer, dataSize, loadFile, paramBuffer
|
||||
@ -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
|
||||
|
||||
@ -630,6 +678,46 @@ def main(args):
|
||||
|
||||
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] )
|
||||
@ -675,14 +763,6 @@ def main(args):
|
||||
|
||||
break
|
||||
|
||||
# ~ else:
|
||||
|
||||
# ~ ser.reset_input_buffer()
|
||||
|
||||
# ~ inputBuffer = ""
|
||||
|
||||
# ~ break
|
||||
|
||||
if len(paramBuffer):
|
||||
|
||||
# Check that no param is undefined ( != -1 )
|
||||
@ -695,8 +775,44 @@ 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:
|
||||
|
||||
print("Received addresses and file ID : " + paramBuffer['memAddr'] + " - " + paramBuffer['bufferAddr'] + " - " + paramBuffer['loadFile'] )
|
||||
@ -749,16 +865,62 @@ 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). See `pcdrv.h` l.52
|
||||
|
||||
osMode = os.O_RDONLY
|
||||
|
||||
if int(paramBuffer['mode']) == 1:
|
||||
|
||||
osMode = os.O_WRONLY
|
||||
|
||||
else:
|
||||
|
||||
osMode = os.O_RDWR
|
||||
|
||||
# ~ if os.path.isfile( 'work/' + paramBuffer['fileName']):
|
||||
|
||||
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'])
|
||||
|
||||
# ~ else:
|
||||
except OSError as errMsg:
|
||||
|
||||
SendBin( b'-1', paramBuffer['bufferAddr'])
|
||||
|
||||
print(errMsg + " - Try using PCcreate()")
|
||||
|
||||
return 0
|
||||
|
||||
resetListener()
|
||||
|
||||
print("DONE!")
|
||||
|
||||
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
|
||||
@ -771,25 +933,296 @@ def main(args):
|
||||
|
||||
osMode = os.O_RDWR
|
||||
|
||||
if os.path.isfile( 'work/' + paramBuffer['fileName']):
|
||||
# We're using osMode | os.O_CREAT as open mode here.
|
||||
|
||||
localFile = os.open( 'work/' + paramBuffer['fileName'], osMode )
|
||||
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'])
|
||||
|
||||
# ~ time.sleep( sleepTime )
|
||||
|
||||
# ~ SendBin( bytes( str(localFile), 'ascii' ), paramBuffer['bufferAddr'])
|
||||
|
||||
else:
|
||||
|
||||
SendBin( b'-1', paramBuffer['bufferAddr'])
|
||||
|
||||
print("File exists ! Use PCopen.")
|
||||
|
||||
resetListener()
|
||||
|
||||
print("DONE!")
|
||||
|
||||
# ~ break
|
||||
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
|
||||
|
||||
|
297
pcdrv.c
297
pcdrv.c
@ -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,37 +95,85 @@ void sendRU32(uint32_t data) {
|
||||
putchar(data & 0xff);
|
||||
|
||||
};
|
||||
*/
|
||||
int waitForSIODone( const char * answer, volatile char * bufferAddress){
|
||||
|
||||
u_short waitForSIODone( volatile u_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.
|
||||
|
||||
// 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";
|
||||
// Return value
|
||||
|
||||
u_char SIOdone = 0;
|
||||
int SIOdone = 0;
|
||||
|
||||
// Error code sent by the PC
|
||||
|
||||
const char * error = "-1";
|
||||
|
||||
// Mini buffer for the data when two first chars are DT
|
||||
|
||||
char returnValue[BUFFER_LEN] = {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 ){
|
||||
// If buffer does not contain "-1"
|
||||
|
||||
SIOdone = 1;
|
||||
if ( buffer[0] != error[0] && buffer[1] != error[1] ){
|
||||
|
||||
break;
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
@ -131,17 +181,24 @@ u_short waitForSIODone( volatile u_char * bufferAddress){
|
||||
|
||||
// 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 PCinit( volatile u_char * bufferAddress ){
|
||||
|
||||
int PCopen( const char * filename, u_char mode, 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
|
||||
|
||||
// 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
|
||||
const char * answer = "OK";
|
||||
|
||||
u_int bufferLen = 10 + strlen( filename );
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
30
pcdrv.h
30
pcdrv.h
@ -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
|
||||
@ -44,6 +47,7 @@
|
||||
#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
BIN
pcdrv.h.gch
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user