PeterC
April 7th, 2004, 03:32
Hello
I wanted to play some yaroze games on PCSX but I found out that there was no COFF image support. So I did what came naturally and hacked COFF support into the source code. I also added support for 'auto' files so all the necessary binary data is loaded into the right place (of course I am loading libps.exe first). The problem is that very few games work - I usually get a message along the lines of:
CD_sync:(CdlSync) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
No TOC found: please use CD-DA disc...
and in the few games that do work, sound doesn't work and neither does the controller. It makes me think that there is some initialisation code that I must call before running the game. Anybody experienced in this area?
Oh and by the way here is my Load function:
int Load(char *ExePath) {
FILE *tmpFile;
EXE_HEADER tmpHead;
int type;
strncpy(CdromId, "SLUS99999", 9);
strncpy(CdromLabel, "SLUS_999.99", 11);
tmpFile = fopen(ExePath,"rb");
if (tmpFile == NULL) { SysMessage(_("Error opening file: %s"), ExePath); return 0; }
type = PSXGetFileType(tmpFile);
switch (type) {
case PSX_EXE:
fread(&tmpHead,sizeof(EXE_HEADER),1,tmpFile);
fseek(tmpFile, 0x800, SEEK_SET);
fread((void *)PSXM(tmpHead.t_addr), tmpHead.t_size,1,tmpFile);
fclose(tmpFile);
psxRegs.pc = tmpHead.pc0;
psxRegs.GPR.n.gp = tmpHead.gp0;
psxRegs.GPR.n.sp = tmpHead.s_addr;
if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;
break;
case CPE_EXE:
SysMessage(_("Pcsx found that you wanna use a CPE file. CPE files not supported"));
break;
case COFF_EXE: {
FILHDR h;
AOUTHDR a;
int i;
Load("libps.exe");
fread(&h, sizeof(h), 1, tmpFile);
fread(&a, sizeof(a), 1, tmpFile);
psxRegs.pc = a.entry;
fseek(tmpFile, h.f_opthdr - sizeof(a), SEEK_CUR); /* Skip ??? data */
for (i = 0; i < h.f_nscns; i++) {
SCNHDR s;
fread(&s, sizeof(s), 1, tmpFile);
printf("At 0x%x loading ", s.s_paddr);
if (s.s_scnptr == 0) { /* bss segment */
printf("bss");
memset((void *)PSXM(s.s_paddr), 0, s.s_size);
} else {
long oldPos = ftell(tmpFile);
printf("text");
fseek(tmpFile, s.s_scnptr, SEEK_SET);
fread((void *)PSXM(s.s_paddr), s.s_size, 1, tmpFile);
fseek(tmpFile, oldPos, SEEK_SET);
}
printf(" size %d bytes\n", s.s_size);
}
fclose(tmpFile);
}
/* SysMessage(_("Pcsx found that you wanna use a COFF file. COFF files not supported")); */
break;
case INVALID_EXE:
SysMessage(_("This file is not a psx file"));
break;
}
return 1;
}
and this is the LoadAuto function I use to load 'auto' files:
#ifdef unix
#define SEP '/'
#else
#define SEP '\\'
#endif
#define IS_WHITESPACE(c) (((c) == '\0') || ((c) == ' ') || ((c) == '\n') || ((c)== '\r') || ((c) == '\t'))
int LoadAuto(char* AutoPath) {
char AutoFile[1024];
FILE* aut;
char* AutoFile_File;
Load("libps.exe");
strcpy(AutoFile, AutoPath);
AutoFile_File = strrchr(AutoFile, SEP) + 1;
aut = fopen(AutoPath, "r");
while (!feof(aut)) {
char line[256];
unsigned int addr = 0;
fgets(line, 256, aut);
if (strncmp(line, "local dload ", 12) == 0) {
char* ptr = line+12;
char* AutoFile_ptr = AutoFile_File;
FILE* binfile;
int size;
while (IS_WHITESPACE(*ptr)) ptr++;
do {
*AutoFile_ptr = *ptr;
AutoFile_ptr++; ptr++;
} while (!IS_WHITESPACE(*ptr));
*AutoFile_ptr = '\0';
while (IS_WHITESPACE(*ptr)) ptr++;
while (!IS_WHITESPACE(*ptr)) {
if (((*ptr) >= 'a') && ((*ptr) <= 'f')) {
addr = (addr*16) + ((*ptr) + 10 - 'a');
} else if (((*ptr) >= 'A') && ((*ptr) <= 'F')) {
addr = (addr*16) + ((*ptr) + 10 - 'A');
} else if (((*ptr) >= '0') && ((*ptr) <= '9')) {
addr = (addr*16) + ((*ptr) - '0');
} else {
printf("Character read was '%c'\n", *ptr);
SysMessage("Invalid format");
return 0;
}
ptr++;
}
printf("DLoading %s at %x\n", AutoFile, addr);
binfile = fopen(AutoFile, "rb");
if (!binfile) {
SysMessage("Error opening file!");
return 0;
}
fseek(binfile, 0, SEEK_END);
size = ftell(binfile);
printf("size = %x\n", size);
fseek(binfile, 0, SEEK_SET);
if (!PSXM(addr)) {
SysMessage("Nowhere to copy to!");
return 0;
}
printf("For some strange reason, PSXM(addr) = %x\n", PSXM(addr));
printf("Doing...\n");
PSXMu8(addr) = 123;
printf("Set dummy\n");
fread((void *)PSXM(addr), size, 1, binfile);
printf("Done\n");
} else if (strncmp(line, "local load ", 11) == 0) {
char* ptr = line+11;
char* AutoFile_ptr = AutoFile_File;
while (IS_WHITESPACE(*ptr)) ptr++;
do {
*AutoFile_ptr = *ptr;
AutoFile_ptr++; ptr++;
} while (!IS_WHITESPACE(*ptr));
*AutoFile_ptr = '\0';
printf("Loading %s\n", AutoFile);
Load(AutoFile);
}
}
return 1;
}
Note: the LoadAuto function is called from the GUI code in the same way as the Load function.
P.S. I am using Linux
I wanted to play some yaroze games on PCSX but I found out that there was no COFF image support. So I did what came naturally and hacked COFF support into the source code. I also added support for 'auto' files so all the necessary binary data is loaded into the right place (of course I am loading libps.exe first). The problem is that very few games work - I usually get a message along the lines of:
CD_sync:(CdlSync) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
CD_cw:(CdlGetTN) Sync=NoIntr, Ready=NoIntr
No TOC found: please use CD-DA disc...
and in the few games that do work, sound doesn't work and neither does the controller. It makes me think that there is some initialisation code that I must call before running the game. Anybody experienced in this area?
Oh and by the way here is my Load function:
int Load(char *ExePath) {
FILE *tmpFile;
EXE_HEADER tmpHead;
int type;
strncpy(CdromId, "SLUS99999", 9);
strncpy(CdromLabel, "SLUS_999.99", 11);
tmpFile = fopen(ExePath,"rb");
if (tmpFile == NULL) { SysMessage(_("Error opening file: %s"), ExePath); return 0; }
type = PSXGetFileType(tmpFile);
switch (type) {
case PSX_EXE:
fread(&tmpHead,sizeof(EXE_HEADER),1,tmpFile);
fseek(tmpFile, 0x800, SEEK_SET);
fread((void *)PSXM(tmpHead.t_addr), tmpHead.t_size,1,tmpFile);
fclose(tmpFile);
psxRegs.pc = tmpHead.pc0;
psxRegs.GPR.n.gp = tmpHead.gp0;
psxRegs.GPR.n.sp = tmpHead.s_addr;
if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;
break;
case CPE_EXE:
SysMessage(_("Pcsx found that you wanna use a CPE file. CPE files not supported"));
break;
case COFF_EXE: {
FILHDR h;
AOUTHDR a;
int i;
Load("libps.exe");
fread(&h, sizeof(h), 1, tmpFile);
fread(&a, sizeof(a), 1, tmpFile);
psxRegs.pc = a.entry;
fseek(tmpFile, h.f_opthdr - sizeof(a), SEEK_CUR); /* Skip ??? data */
for (i = 0; i < h.f_nscns; i++) {
SCNHDR s;
fread(&s, sizeof(s), 1, tmpFile);
printf("At 0x%x loading ", s.s_paddr);
if (s.s_scnptr == 0) { /* bss segment */
printf("bss");
memset((void *)PSXM(s.s_paddr), 0, s.s_size);
} else {
long oldPos = ftell(tmpFile);
printf("text");
fseek(tmpFile, s.s_scnptr, SEEK_SET);
fread((void *)PSXM(s.s_paddr), s.s_size, 1, tmpFile);
fseek(tmpFile, oldPos, SEEK_SET);
}
printf(" size %d bytes\n", s.s_size);
}
fclose(tmpFile);
}
/* SysMessage(_("Pcsx found that you wanna use a COFF file. COFF files not supported")); */
break;
case INVALID_EXE:
SysMessage(_("This file is not a psx file"));
break;
}
return 1;
}
and this is the LoadAuto function I use to load 'auto' files:
#ifdef unix
#define SEP '/'
#else
#define SEP '\\'
#endif
#define IS_WHITESPACE(c) (((c) == '\0') || ((c) == ' ') || ((c) == '\n') || ((c)== '\r') || ((c) == '\t'))
int LoadAuto(char* AutoPath) {
char AutoFile[1024];
FILE* aut;
char* AutoFile_File;
Load("libps.exe");
strcpy(AutoFile, AutoPath);
AutoFile_File = strrchr(AutoFile, SEP) + 1;
aut = fopen(AutoPath, "r");
while (!feof(aut)) {
char line[256];
unsigned int addr = 0;
fgets(line, 256, aut);
if (strncmp(line, "local dload ", 12) == 0) {
char* ptr = line+12;
char* AutoFile_ptr = AutoFile_File;
FILE* binfile;
int size;
while (IS_WHITESPACE(*ptr)) ptr++;
do {
*AutoFile_ptr = *ptr;
AutoFile_ptr++; ptr++;
} while (!IS_WHITESPACE(*ptr));
*AutoFile_ptr = '\0';
while (IS_WHITESPACE(*ptr)) ptr++;
while (!IS_WHITESPACE(*ptr)) {
if (((*ptr) >= 'a') && ((*ptr) <= 'f')) {
addr = (addr*16) + ((*ptr) + 10 - 'a');
} else if (((*ptr) >= 'A') && ((*ptr) <= 'F')) {
addr = (addr*16) + ((*ptr) + 10 - 'A');
} else if (((*ptr) >= '0') && ((*ptr) <= '9')) {
addr = (addr*16) + ((*ptr) - '0');
} else {
printf("Character read was '%c'\n", *ptr);
SysMessage("Invalid format");
return 0;
}
ptr++;
}
printf("DLoading %s at %x\n", AutoFile, addr);
binfile = fopen(AutoFile, "rb");
if (!binfile) {
SysMessage("Error opening file!");
return 0;
}
fseek(binfile, 0, SEEK_END);
size = ftell(binfile);
printf("size = %x\n", size);
fseek(binfile, 0, SEEK_SET);
if (!PSXM(addr)) {
SysMessage("Nowhere to copy to!");
return 0;
}
printf("For some strange reason, PSXM(addr) = %x\n", PSXM(addr));
printf("Doing...\n");
PSXMu8(addr) = 123;
printf("Set dummy\n");
fread((void *)PSXM(addr), size, 1, binfile);
printf("Done\n");
} else if (strncmp(line, "local load ", 11) == 0) {
char* ptr = line+11;
char* AutoFile_ptr = AutoFile_File;
while (IS_WHITESPACE(*ptr)) ptr++;
do {
*AutoFile_ptr = *ptr;
AutoFile_ptr++; ptr++;
} while (!IS_WHITESPACE(*ptr));
*AutoFile_ptr = '\0';
printf("Loading %s\n", AutoFile);
Load(AutoFile);
}
}
return 1;
}
Note: the LoadAuto function is called from the GUI code in the same way as the Load function.
P.S. I am using Linux