Remove empty lines

This commit is contained in:
ABelliqueux 2021-05-24 16:26:25 +02:00
parent 55a09d5c38
commit f7c89f7094
4 changed files with 0 additions and 1108 deletions

View File

@ -1,26 +1,14 @@
/* ovl-upload.c, by ABelliqueux, 04-2021 license GNU General Public License v3.0
This example code demonstrates how to use the companion 'ovl-upload.py' script that should be provided with this file.
Once the code is loaded on a unirom enabled PSX via a serial/USB cable, 'ovl-upload.py' listens for a specific command
to load an overlay file on demand.
For an explanation about overlays, see http://psx.arthus.net/sdk/Psy-Q/DOCS/TRAINING/FALL96/overlay.pdf
For a basic example see @JaberwockySeamonstah's https://github.com/JaberwockySeamonstah/PSXOverlayExample
Unirom can be found here : https://github.com/JonathanDotCel/unirom8_bootdisc_and_firmware_for_ps1
with it's companion pc side software : https://github.com/JonathanDotCel/NOTPSXSerial
Thanks to @JaberwockySeamonstah, @JonathanDotCel, @nicolasnoble, @Lameguy64 for their help and patience.
Demonstrates:
* Using overlays to store different data and loading them in memory as needed.
Controls:
Select - Load alternative overlay
*/
@ -32,489 +20,273 @@
#include <stdio.h>
#include <libsio.h>
#include <string.h>
#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 :
// $ mkpsxiso -y config/OverlayExample.xml
//~ #define USECD
#ifdef USECD
#include <libcd.h>
#endif
// Sample vector models
#include "tritex.h"
#include "cubetex.h"
#define VMODE 0
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define OTLEN 2048 // Maximum number of OT entries
#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN] = {0}; // Primitive list // That's our prim buffer
//~ int primcnt=0; // Primitive counter
char * nextpri = primbuff[0]; // Primitive counter
short db = 0; // Current buffer counter
// Texture image
extern unsigned long _binary_TIM_cubetex_tim_start[];
extern unsigned long _binary_TIM_cubetex_tim_end[];
extern unsigned long _binary_TIM_cubetex_tim_length;
TIM_IMAGE tim_cube;
// OVERLAYS CONFIG
// These symbols name are defined in 'overlay.ld', l.8, l.24 and l.41
// Use &load_all_overlays_here to get the memory adress where the overlay files are loaded.
// Those adresses you can check in the generated .map file at compile time.
extern u_long load_all_overlays_here;
extern u_long __lvl0_end; // Use &__lvl0_end to get end address of corresponding overlay.
extern u_long __lvl1_end;
//~ u_long overlaySize = 0;
char * overlayFile; // Will hold the name of the file to load.
char * ptrToChar[8]; // Will hold the name of the file to load.
u_char overlayFileID = 0, loadFileIDwas = 0;
// Timer for the pad
u_short timer = 0;
// pcdrv protocol
u_char escape = 0x00; // Hypothetical Escape char for unirom
u_char protocol = 0x01; // Hypothetical ID number for the pcdrv protocol in unirom
u_char command = LOAD; // We're loading the data here
uint32_t checkSum = 0;
volatile u_char inBuffer[BUFFER_LEN] = {0};
volatile u_char dataBuffer[64] = "DEBOUTLESENFANTS";
// Prototypes
void init(void);
void display(void);
void LoadTexture(u_long * tim, TIM_IMAGE * tparam);
void init(){
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
setRGB0(&draw[0], 0, 0, 255);
setRGB0(&draw[1], 0, 0, 255);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Init font system
FntLoad(960, 0);
FntOpen(16, 16, 196, 196, 0, 512);
}
void display(void){
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
SetDispMask(1);
DrawOTag(ot[db] + OTLEN - 1);
db = !db;
nextpri = primbuff[db];
}
void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous
OpenTIM(tim); // Open the tim binary data, feed it the address of the data in memory
ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure
LoadImage(tparam->prect, tparam->paddr); // Transfer the data from memory to VRAM at position prect.x, prect.y
DrawSync(0); // Wait for the drawing to end
if (tparam->mode & 0x8){ // check 4th bit // If 4th bit == 1, TIM has a CLUT
LoadImage(tparam->crect, tparam->caddr); // Load it to VRAM at position crect.x, crect.y
DrawSync(0); // Wait for drawing to end
}
}
int fileDesc = 0;
int fileRead = 0;
int filePos = 0;
int fileCreated = 0;
int main() {
// Update this value to avoid trigger at launch
loadFileIDwas = overlayFileID;
if ( overlayFileID == 0 ){
overlayFile = "\\cube.bin;1";
} else if ( overlayFileID == 1) {
overlayFile = "\\tri.bin;1";
}
// Load overlay from CD if definde
#ifdef USECD
CdInit();
int cdread = 0, cdsync = 1;
cdread = CdReadFile( (char *)(overlayFile), &load_all_overlays_here, 0);
cdsync = CdReadSync(0, 0);
#endif
int i;
int PadStatus;
int TPressed=0;
int AutoRotate=1;
long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143
MESH * model = &Tri;
POLY_GT3 *poly = {0}; // pointer to a POLY_GT3
SVECTOR Rotate={ 0 }; // Rotation coordinates
VECTOR Trans={ 0, 0, CENTERX, 0 }; // Translation coordinates
VECTOR Scale={ ONE, ONE, ONE, 0 }; // ONE == 4096
MATRIX Matrix={0}; // Matrix data for the GTE
// Texture window
DR_MODE * dr_mode; // Pointer to dr_mode prim
RECT tws = {0, 0, 32, 32}; // Texture window coordinates : x, y, w, h
init();
LoadTexture(_binary_TIM_cubetex_tim_start, &tim_cube);
// Main loop
while (1) {
FntPrint("%02d - %04d - %02d", fileDesc, filePos, fileRead );
// If filedescriptor is not null and not -1, try to open the file
if ( fileDesc > 0 ){
switch (fileRead){
case 0: PCwrite( fileDesc, filePos, 7, dataBuffer, inBuffer);
fileRead = 1;
break;
case 1: PCseek( fileDesc, 7, 3, 1, inBuffer);
fileRead = 2;
break;
case 2: PCwrite( fileDesc, 10, 7, dataBuffer + 7, inBuffer);
fileRead = 3;
break;
default:
//~ PCclose(fileDesc, inBuffer);
PCinit(inBuffer);
fileDesc = 0;
fileRead = 0;
}
}
// Overlay switch
if ( overlayFileID != loadFileIDwas ){
// Change file to load
switch ( overlayFileID ){
case 0:
overlayFile = "\\cube.bin;1";
//~ overlayFileID = 0;
break;
case 1:
overlayFile = "\\tri.bin;1";
//~ overlayFileID = 1;
break;
default:
overlayFile = "\\cube.bin;1";
//~ overlayFileID = 0;
break;
}
#ifndef USECD
if(!fileRead){
fileDesc = PCopen("HELLO.WD", O_RDWR, inBuffer);
//~ fileDesc = PCcreate("HELLO.WD", 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 ( fileDesc ){
loadFileIDwas = overlayFileID;
}
}
#endif
#ifdef USECD
cdread = CdReadFile( (char *)(overlayFile), &load_all_overlays_here, 0);
if ( CdReadSync(0, 0) == 0 ){
loadFileIDwas = overlayFileID;
}
#endif
}
// Pad button timer
while ( timer > 0 ) {
timer --;
}
// Read pad status
PadStatus = PadRead(0);
// If select is pressed, change overlay
if ( ( PadStatus & PADselect ) && !timer ) {
overlayFileID = !overlayFileID;
timer = 150;
}
if (AutoRotate) {
Rotate.vy += 8; // Pan
Rotate.vx += 8; // Tilt
}
// Clear the current OT
ClearOTagR(ot[db], OTLEN);
// Convert and set the matrixes
RotMatrix(&Rotate, &Matrix);
TransMatrix(&Matrix, &Trans);
ScaleMatrix(&Matrix, &Scale);
SetRotMatrix(&Matrix);
SetTransMatrix(&Matrix);
// Render the sample vector model
t=0;
// modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
for (i = 0; i < (model->tmesh->len*3); i += 3) {
poly = (POLY_GT3 *)nextpri;
// Initialize the primitive and set its color values
SetPolyGT3(poly);
((POLY_GT3 *)poly)->tpage = getTPage(tim_cube.mode&0x3, 0,
tim_cube.prect->x,
tim_cube.prect->y
);
setRGB0(poly, model->tmesh->c[i].r , model->tmesh->c[i].g , model->tmesh->c[i].b);
setRGB1(poly, model->tmesh->c[i+1].r, model->tmesh->c[i+1].g, model->tmesh->c[i+1].b);
setRGB2(poly, model->tmesh->c[i+2].r, model->tmesh->c[i+2].g, model->tmesh->c[i+2].b);
setUV3(poly, model->tmesh->u[i].vx , model->tmesh->u[i].vy,
model->tmesh->u[i+1].vx, model->tmesh->u[i+1].vy,
model->tmesh->u[i+2].vx, model->tmesh->u[i+2].vy);
// Rotate, translate, and project the vectors and output the results into a primitive
OTz = RotTransPers(&model->tmesh->v[model->index[t]] , (long*)&poly->x0, &p, &Flag);
OTz += RotTransPers(&model->tmesh->v[model->index[t+1]], (long*)&poly->x1, &p, &Flag);
OTz += RotTransPers(&model->tmesh->v[model->index[t+2]], (long*)&poly->x2, &p, &Flag);
// Sort the primitive into the OT
OTz /= 3;
if ((OTz > 0) && (OTz < OTLEN))
AddPrim(&ot[db][OTz-2], poly);
nextpri += sizeof(POLY_GT3);
t+=3;
}
dr_mode = (DR_MODE *)nextpri;
setDrawMode(dr_mode,1,0, getTPage(tim_cube.mode&0x3, 0,
tim_cube.prect->x,
tim_cube.prect->y), &tws); //set texture window
AddPrim(&ot[db], dr_mode);
nextpri += sizeof(DR_MODE);
FntPrint("Hello overlay!\n");
#ifndef USECD
FntPrint("loadFileIDwas : %d\n", loadFileIDwas);
FntPrint("Overlay with id %d loaded at 0x%08x\n", overlayFileID, &load_all_overlays_here );
FntPrint("buffer at %08x : %s\n", inBuffer, inBuffer);
FntPrint("dataBuffer at %08x : \n %s", dataBuffer, dataBuffer);
#endif
#ifdef USECD
FntPrint("File: %s\n", overlayFile);
FntPrint("Bytes read: %d", cdread);
#endif
FntFlush(-1);
display();
}
return 0;
}

File diff suppressed because it is too large Load Diff

238
pcdrv.c
View File

@ -1,531 +1,293 @@
#include "pcdrv.h"
void wait(){
for(u_int wait = 0; wait < 60; wait++){
wait = wait;
}
};
/*
static char sio_read(){
char c;
c = getchar();
return c;
};
u_int strLen( const char * str){
u_int l = 0;
while ( * str++ ){
l++;
}
return l;
};
*/
// Hashing algorythm from @nicolasnoble : https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h
static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n) {
return n ? djbProcess ( ( ( hash << 5 ) + hash ) ^ str[0], str + 1, n - 1) : hash;
}
static inline uint32_t djbHash( const char* str, unsigned n ){
return djbProcess( 5381, str, n);
};
/*
uint32_t charsToU32 ( char * byte ) {
unsigned int packet = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | (byte[3]);
return packet;
};
u_char U32ToChars( u_int memoryAddress, u_int byteNbr){
// This one I found on my own )'u'(
u_char byte = { 0 };
byte = ( (u_int) memoryAddress >> ( 24 - (byteNbr << 3) ) ) & 0xFF;
return byte;
};
void sendU32(uint32_t data) {
putchar(data & 0xff);
data >>= 8;
putchar(data & 0xff);
data >>= 8;
putchar(data & 0xff);
data >>= 8;
putchar(data & 0xff);
};
void sendRU32(uint32_t data) {
putchar((data >> 24) & 0xff);
putchar((data >> 16) & 0xff);
putchar((data >> 8) & 0xff);
putchar(data & 0xff);
};
*/
int waitForSIODone( 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";
// 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){
// Continually get the content at &bufferAddress
const char * buffer = ( const char * )bufferAddress;
// Rolling buffer
if( strlen( buffer ) > BUFFER_LEN){
memmove( ( char * ) buffer, buffer + 1, strlen(buffer));
}
// Check inBuffer for answer
// 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 > 3000 ){
// empty buffer
for ( short i; i < BUFFER_LEN;i++ ){ bufferAddress[i] = 0; }
// Get out of function after X iterations
return 0;
}
}
// Should never be reached, but just to be sure
return 0;
};
u_short PCload( u_long * loadAddress, volatile u_char * bufferAddress, u_char * overlayFileID ) {
// Send filename , load address, and flag address
// Returns 1 if ok, 0 else
// 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];
// 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);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
// Need delay ?
wait();
return waitForSIODone( answer , bufferAddress );
};
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 = 16;
char commandBuffer[ bufferLen ];
sprintf(commandBuffer, "%02u%02u%02u08%08x", ESCAPE, PROTOCOL, INIT, bufferAddress);
u_int cmdChecksum = djbHash( commandBuffer, bufferLen);
printf("%s%*u", commandBuffer, CHECKSUM_LEN, cmdChecksum);
wait();
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 + 1];
// 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 + len;
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
u_char escape = 0x00; // Hypothetical Escape char for unirom
u_char protocol = 0x01; // Hypothetical protocol indicator for unirom
// Command is 18 B data + 10 B checksum
char commandBuffer[28] = {0};
u_char checkSumLen = 10;
short i = 0;
u_long * loadAddress;
u_char * flagAddress;
// FntPrint("%x\n", loadAddress);
while( i < sizeof( commandBuffer) - checkSumLen ){
if( i == 0 ){
commandBuffer[0] = escape;
commandBuffer[1] = protocol;
i = 2;
}
if( i == 2 ){
commandBuffer[i] = LOAD;
i ++;
}
commandBuffer[i] = sizeof(&loadAddress);
i ++;
for( u_int b = 0; b < sizeof(&loadAddress); b++ ){
commandBuffer[i] = U32ToChars( ( u_int ) loadAddress, b );
// FntPrint("i: %d b: %d, %02x\n", i, b, commandBuffer[i]);
i++;
}
commandBuffer[i] = sizeof(&flagAddress);
i ++;
for( u_int b = 0; b < sizeof(&flagAddress); b++ ){
commandBuffer[i] = U32ToChars( ( u_int ) flagAddress, b );
// FntPrint("i: %d b: %d, %02x\n", i, b, commandBuffer[i]);
i++;
}
// commandBuffer[i] = overlayFileID;
i++;
for(short c = 0; c < sizeof(commandBuffer) - checkSumLen; c++){
// FntPrint("%x", commandBuffer[c]);
}
// FntPrint("\n%d, %d", i, sizeof(commandBuffer) );
}
for(u_int b = 0; b < sizeof(commandBuffer)-3; b+=4 ){
u_char bytes[4] = {0};
bytes[0] = commandBuffer[b + 0];
bytes[1] = commandBuffer[b + 1];
bytes[2] = commandBuffer[b + 2];
bytes[3] = commandBuffer[b + 3];
sendU32( charsToU32(bytes) );
}
// u_int cmdChecksum = djbHash((const char * )commandBuffer, sizeof(commandBuffer) - checkSumLen);
// FntPrint("\n%d\n", cmdChecksum);
}
*/

27
pcdrv.h
View File

@ -20,26 +20,18 @@
// https://discord.com/channels/642647820683444236/646765703143227394/837416216640618558
// So like we'd have, say,
// 00 01 00 03 58 58 58 01 xx for pcdrv' file open to open the file name "XXX" and attribute 1
// (escape) (pcdrv command) (pcdrv open) (filename with length as prefix) (attributes) (checksum)
#pragma once
#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
//pcdrv commands
#define OPEN 0x00
#define CLOSE 0x01
#define SEEK 0x02
@ -48,43 +40,24 @@
#define CREATE 0x05
#define LOAD 0x06
#define INIT 0x07
// flags parameters
#define O_RDONLY 0x00
#define O_WRONLY 0x01
#define O_RDWR 0x02
#define CHECKSUM_LEN 10
//~ static char sio_read();
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 );
//~ u_char U32ToChars( u_int memoryAddress, u_int byteNbr);
//~ void sendU32(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, u_char mode, volatile u_char * bufferAddress );
int PCseek( int fd, int curPos, int offset, int accessMode, volatile u_char * bufferAddress );
int PCread( int fd, int pos, int len, volatile char * dataBuffer, volatile char * bufferAddress );
int PCwrite( int fd, int pos, int len, volatile u_char * dataBuffer, volatile u_char * bufferAddress );