Add read/write/seek/open/close functions handler
This commit is contained in:
parent
362bdb244b
commit
2371e8fa32
59
ovl-upload.c
59
ovl-upload.c
|
@ -36,7 +36,8 @@
|
||||||
#include "pcdrv.h"
|
#include "pcdrv.h"
|
||||||
|
|
||||||
// If USECD is defined, files will be loaded from the CD. Use this method for testing in an emulator.
|
// 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
|
//~ #define USECD
|
||||||
|
|
||||||
|
@ -126,12 +127,10 @@ u_char command = LOAD; // We're loading the data here
|
||||||
|
|
||||||
uint32_t checkSum = 0;
|
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
|
// Prototypes
|
||||||
|
|
||||||
void init(void);
|
void init(void);
|
||||||
|
@ -176,7 +175,7 @@ void init(){
|
||||||
|
|
||||||
// Init font system
|
// Init font system
|
||||||
FntLoad(960, 0);
|
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() {
|
int main() {
|
||||||
|
|
||||||
// Update this value to avoid trigger at launch
|
// Update this value to avoid trigger at launch
|
||||||
|
@ -273,16 +276,24 @@ int main() {
|
||||||
LoadTexture(_binary_TIM_cubetex_tim_start, &tim_cube);
|
LoadTexture(_binary_TIM_cubetex_tim_start, &tim_cube);
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
|
FntPrint("%08d - ", returnVal);
|
||||||
|
|
||||||
|
//~ if ( returnVal > 0 ){
|
||||||
|
|
||||||
|
//~ returnVal = PCopen("HELO.WLD", O_RDWR, inBuffer);
|
||||||
|
|
||||||
|
//~ fileCreated = returnVal;
|
||||||
|
|
||||||
|
//~ returnVal = 0;
|
||||||
|
//~ }
|
||||||
|
|
||||||
// Overlay switch
|
// Overlay switch
|
||||||
|
|
||||||
if ( overlayFileID != loadFileIDwas ){
|
if ( overlayFileID != loadFileIDwas ){
|
||||||
|
|
||||||
// Update previous file value
|
|
||||||
|
|
||||||
loadFileIDwas = overlayFileID;
|
|
||||||
|
|
||||||
// Change file to load
|
// Change file to load
|
||||||
|
|
||||||
switch ( overlayFileID ){
|
switch ( overlayFileID ){
|
||||||
|
@ -315,22 +326,30 @@ int main() {
|
||||||
|
|
||||||
#ifndef USECD
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef USECD
|
#ifdef USECD
|
||||||
|
|
||||||
cdread = CdReadFile( (char *)(overlayFile), &load_all_overlays_here, 0);
|
cdread = CdReadFile( (char *)(overlayFile), &load_all_overlays_here, 0);
|
||||||
|
|
||||||
CdReadSync(0, 0);
|
|
||||||
|
|
||||||
|
if ( CdReadSync(0, 0) == 0 ){
|
||||||
|
|
||||||
|
loadFileIDwas = overlayFileID;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -352,7 +371,7 @@ int main() {
|
||||||
if ( ( PadStatus & PADselect ) && !timer ) {
|
if ( ( PadStatus & PADselect ) && !timer ) {
|
||||||
|
|
||||||
overlayFileID = !overlayFileID;
|
overlayFileID = !overlayFileID;
|
||||||
|
|
||||||
timer = 150;
|
timer = 150;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -446,6 +465,8 @@ int main() {
|
||||||
|
|
||||||
FntPrint("buffer at %08x : %s\n", inBuffer, inBuffer);
|
FntPrint("buffer at %08x : %s\n", inBuffer, inBuffer);
|
||||||
|
|
||||||
|
FntPrint("dataBuffer at %08x : \n %s", dataBuffer, dataBuffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USECD
|
#ifdef USECD
|
||||||
|
|
503
ovl-upload.py
503
ovl-upload.py
|
@ -40,13 +40,30 @@ pcdrvProtocol = '01'
|
||||||
|
|
||||||
# Commands
|
# 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 = {}
|
paramBuffer = {}
|
||||||
|
|
||||||
|
@ -101,6 +118,26 @@ Transfer = 0
|
||||||
|
|
||||||
sleepTime = 0.08 # Seems like safe minimum
|
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():
|
def setDEBG():
|
||||||
|
|
||||||
global sleepTime, ser, uniDebugMode
|
global sleepTime, ser, uniDebugMode
|
||||||
|
@ -122,7 +159,6 @@ def setDEBG():
|
||||||
uniDebugMode = 1
|
uniDebugMode = 1
|
||||||
|
|
||||||
# stole it here : https://gist.github.com/amakukha/7854a3e910cb5866b53bf4b2af1af968
|
# 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):
|
def hash_djb2(s):
|
||||||
|
|
||||||
|
@ -235,13 +271,15 @@ def getData(dataInBuffer):
|
||||||
|
|
||||||
# Get data length byte
|
# Get data length byte
|
||||||
|
|
||||||
|
# If only 2 bytes left, dont't bother
|
||||||
|
|
||||||
if len(dataInBuffer) == 2:
|
if len(dataInBuffer) == 2:
|
||||||
|
|
||||||
parsedData = dataInBuffer
|
parsedData = dataInBuffer
|
||||||
|
|
||||||
dataInBuffer = ""
|
dataInBuffer = ""
|
||||||
|
|
||||||
return [dataInBuffer, parsedData] # does it break ?
|
return [dataInBuffer, parsedData]
|
||||||
|
|
||||||
dataLen = int( dataInBuffer[:2] )
|
dataLen = int( dataInBuffer[:2] )
|
||||||
|
|
||||||
|
@ -515,10 +553,12 @@ def resetListener():
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
|
|
||||||
|
files = openFiles()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
global checkSum, checkSumLen, data, Listen, Transfer, dataSize, loadFile, paramBuffer
|
global checkSum, checkSumLen, data, Listen, Transfer, dataSize, loadFile, paramBuffer
|
||||||
|
|
||||||
# Flush serial buffers to avoid residual data
|
# Flush serial buffers to avoid residual data
|
||||||
|
|
||||||
ser.reset_input_buffer()
|
ser.reset_input_buffer()
|
||||||
|
@ -573,7 +613,6 @@ def main(args):
|
||||||
|
|
||||||
# Remove checksum from data
|
# Remove checksum from data
|
||||||
|
|
||||||
# ~ inputBuffer = inputBuffer[:28]
|
|
||||||
inputBuffer = inputBuffer[:-checkSumLen]
|
inputBuffer = inputBuffer[:-checkSumLen]
|
||||||
|
|
||||||
dataCheckSum = hash_djb2(bytes(inputBuffer, 'ascii'))
|
dataCheckSum = hash_djb2(bytes(inputBuffer, 'ascii'))
|
||||||
|
@ -612,9 +651,18 @@ def main(args):
|
||||||
|
|
||||||
print( "Received Cmd: " + inputBuffer[:2] )
|
print( "Received Cmd: " + inputBuffer[:2] )
|
||||||
|
|
||||||
|
|
||||||
|
# Command butes are OPEN == 00
|
||||||
|
|
||||||
|
if inputBuffer[:2] == INIT:
|
||||||
|
|
||||||
|
paramTmp = {}
|
||||||
|
|
||||||
|
Command = INIT
|
||||||
|
|
||||||
# Command bytes are LOAD == 06
|
# Command bytes are LOAD == 06
|
||||||
|
|
||||||
if inputBuffer[:2] == LOAD:
|
elif inputBuffer[:2] == LOAD:
|
||||||
|
|
||||||
# Set corresponding parameters and mode
|
# Set corresponding parameters and mode
|
||||||
|
|
||||||
|
@ -629,7 +677,47 @@ def main(args):
|
||||||
paramTmp = openParams
|
paramTmp = openParams
|
||||||
|
|
||||||
Command = OPEN
|
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:
|
else:
|
||||||
|
|
||||||
print("Command not recognized : got " + inputBuffer[:2] )
|
print("Command not recognized : got " + inputBuffer[:2] )
|
||||||
|
@ -661,7 +749,7 @@ def main(args):
|
||||||
ser.reset_input_buffer()
|
ser.reset_input_buffer()
|
||||||
|
|
||||||
inputBuffer = ""
|
inputBuffer = ""
|
||||||
|
|
||||||
Listen = 0
|
Listen = 0
|
||||||
|
|
||||||
break
|
break
|
||||||
|
@ -674,14 +762,6 @@ def main(args):
|
||||||
inputBuffer = ""
|
inputBuffer = ""
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
# ~ else:
|
|
||||||
|
|
||||||
# ~ ser.reset_input_buffer()
|
|
||||||
|
|
||||||
# ~ inputBuffer = ""
|
|
||||||
|
|
||||||
# ~ break
|
|
||||||
|
|
||||||
if len(paramBuffer):
|
if len(paramBuffer):
|
||||||
|
|
||||||
|
@ -695,7 +775,43 @@ def main(args):
|
||||||
|
|
||||||
break
|
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:
|
if Command == LOAD:
|
||||||
|
|
||||||
|
# Load file
|
||||||
|
|
||||||
|
print("Received LOAD.")
|
||||||
|
|
||||||
if DEBUG > 1:
|
if DEBUG > 1:
|
||||||
|
|
||||||
|
@ -749,17 +865,13 @@ def main(args):
|
||||||
|
|
||||||
print("DONE!")
|
print("DONE!")
|
||||||
|
|
||||||
# ~ else:
|
|
||||||
|
|
||||||
# ~ print(" No filename provided, doing nothing. ")
|
|
||||||
|
|
||||||
# ~ resetListener()
|
|
||||||
|
|
||||||
if Command == OPEN:
|
if Command == OPEN:
|
||||||
|
|
||||||
|
# Open file
|
||||||
|
|
||||||
print("Received OPEN.")
|
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
|
osMode = os.O_RDONLY
|
||||||
|
|
||||||
|
@ -771,26 +883,347 @@ def main(args):
|
||||||
|
|
||||||
osMode = os.O_RDWR
|
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'])
|
SendBin( b'DT' + bytes( str(localFile), 'ascii' ), paramBuffer['bufferAddr'])
|
||||||
|
|
||||||
# ~ time.sleep( sleepTime )
|
# ~ else:
|
||||||
|
except OSError as errMsg:
|
||||||
# ~ SendBin( bytes( str(localFile), 'ascii' ), paramBuffer['bufferAddr'])
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
SendBin( b'-1', paramBuffer['bufferAddr'])
|
SendBin( b'-1', paramBuffer['bufferAddr'])
|
||||||
|
|
||||||
|
print(errMsg + " - Try using PCcreate()")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
resetListener()
|
resetListener()
|
||||||
|
|
||||||
print("DONE!")
|
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
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
317
pcdrv.c
317
pcdrv.c
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
void wait(){
|
void wait(){
|
||||||
|
|
||||||
for(u_int wait = 0; wait < 100; wait++){
|
for(u_int wait = 0; wait < 60; wait++){
|
||||||
|
|
||||||
wait = wait;
|
wait = wait;
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
static char sio_read(){
|
static char sio_read(){
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
|
@ -30,6 +30,7 @@ u_int strLen( const char * str){
|
||||||
return l;
|
return l;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// Hashing algorythm from @nicolasnoble : https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h
|
// 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 ) {
|
uint32_t charsToU32 ( char * byte ) {
|
||||||
|
|
||||||
unsigned int packet = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | (byte[3]);
|
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);
|
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
|
// Counter to avoid infinite loop
|
||||||
// Returns 1 if ok, 0 else
|
|
||||||
|
|
||||||
const char * OKYA = "OKYA";
|
|
||||||
|
|
||||||
u_char SIOdone = 0;
|
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
|
|
||||||
const u_char * buffer = ( const u_char * )bufferAddress;
|
// Continually get the content at &bufferAddress
|
||||||
|
|
||||||
|
const char * buffer = ( const char * )bufferAddress;
|
||||||
|
|
||||||
// Rolling buffer
|
// 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
|
// 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++;
|
i++;
|
||||||
|
|
||||||
// Avoid infinite loop
|
// 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
|
// E.G : 00 01 06 04 80010000 08 80010001 01 + 0000000000 <- cmd checksum
|
||||||
// 00 01 06 08 8003edf8 08 8001f0f0 00 2439964735 -> 38 Bytes
|
// 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];
|
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);
|
u_int cmdChecksum = djbHash(commandBuffer, 28);
|
||||||
|
|
||||||
|
@ -163,22 +230,23 @@ u_short PCload( u_long * loadAddress, volatile u_char * bufferAddress, u_char *
|
||||||
// Need delay ?
|
// Need delay ?
|
||||||
wait();
|
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.
|
||||||
// Open filename in mode
|
// Returns OK if success, -1 if fail
|
||||||
// Returns file descriptor or -1 if fail
|
// E.G : 00 01 07 + 00 00 00 00 00
|
||||||
// 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 ];
|
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);
|
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
|
||||||
|
|
||||||
|
@ -186,12 +254,180 @@ int PCopen( const char * filename, u_char mode, volatile u_char * bufferAddress
|
||||||
|
|
||||||
wait();
|
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
|
// WIP : Build command for use with putchar instead of printf
|
||||||
|
/*
|
||||||
void BuildCmd(){
|
void BuildCmd(){
|
||||||
|
|
||||||
// Build command in the buffer
|
// Build command in the buffer
|
||||||
|
@ -261,13 +497,13 @@ void BuildCmd(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ commandBuffer[i] = overlayFileID;
|
// commandBuffer[i] = overlayFileID;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
for(short c = 0; c < sizeof(commandBuffer) - checkSumLen; c++){
|
for(short c = 0; c < sizeof(commandBuffer) - checkSumLen; c++){
|
||||||
|
|
||||||
//~ FntPrint("%x", commandBuffer[c]);
|
// FntPrint("%x", commandBuffer[c]);
|
||||||
}
|
}
|
||||||
// FntPrint("\n%d, %d", i, sizeof(commandBuffer) );
|
// FntPrint("\n%d, %d", i, sizeof(commandBuffer) );
|
||||||
|
|
||||||
|
@ -292,3 +528,4 @@ void BuildCmd(){
|
||||||
|
|
||||||
// FntPrint("\n%d\n", cmdChecksum);
|
// FntPrint("\n%d\n", cmdChecksum);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
32
pcdrv.h
32
pcdrv.h
|
@ -27,10 +27,13 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
//~ #include <libsio.h>
|
//~ #include <libsio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BUFFER_LEN 8
|
||||||
|
|
||||||
#define ESCAPE 0x00 // Hypothetical Escape char for unirom
|
#define ESCAPE 0x00 // Hypothetical Escape char for unirom
|
||||||
|
|
||||||
#define PROTOCOL 0x01
|
#define PROTOCOL 0x01
|
||||||
|
@ -38,12 +41,13 @@
|
||||||
//pcdrv commands
|
//pcdrv commands
|
||||||
|
|
||||||
#define OPEN 0x00
|
#define OPEN 0x00
|
||||||
#define CLOSE 0x01
|
#define CLOSE 0x01
|
||||||
#define SEEK 0x02
|
#define SEEK 0x02
|
||||||
#define READ 0x03
|
#define READ 0x03
|
||||||
#define WRITE 0x04
|
#define WRITE 0x04
|
||||||
#define CREATE 0x05
|
#define CREATE 0x05
|
||||||
#define LOAD 0x06
|
#define LOAD 0x06
|
||||||
|
#define INIT 0x07
|
||||||
|
|
||||||
// flags parameters
|
// flags parameters
|
||||||
|
|
||||||
|
@ -51,32 +55,36 @@
|
||||||
#define O_WRONLY 0x01
|
#define O_WRONLY 0x01
|
||||||
#define O_RDWR 0x02
|
#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 djbHash( const char* str, unsigned n );
|
||||||
|
|
||||||
static inline uint32_t djbProcess(uint32_t hash, 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 );
|
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 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 );
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue