PDA

View Full Version : pcsx and yaroze games


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

zenogais
April 10th, 2004, 00:59
Your code is missing a very important point. You are not setting any of the CPU registers, at least not from what I can tell. This is a mistake as the CPU registers used for loading data need some sort of values to start execution. I'll research some more into the COFF file format and see about this.

PeterC
April 10th, 2004, 20:18
I am actually setting one of the registers (PC) to the value found in the COFF AOUT "optional" header. Also the other 'important' registers (GP, SP afaict) are being set when libps.exe is loaded, via the "normal" Load code. I could not find a suitable field for these registers in the COFF format.

However there was an additional 28 bytes (the "??? data" as mentioned in the code) I found that was added to the end of the AOUT header in every Yaroze COFF file I could find. I couldn't find a reference as to the values of these fields online though, so maybe one of these fields needs to be loaded into a register.

zenogais
April 10th, 2004, 20:22
I am actually setting one of the registers (PC) to the value found in the COFF AOUT "optional" header. Also the other 'important' registers (GP, SP afaict) are being set when libps.exe is loaded, via the "normal" Load code. I could not find a suitable field for these registers in the COFF format.

However there was an additional 28 bytes (the "??? data" as mentioned in the code) I found that was added to the end of the AOUT header in every Yaroze COFF file I could find. I couldn't find a reference as to the values of these fields online though, so maybe one of these fields needs to be loaded into a register.

Could very well be. I have been looking into the coff format and have found no more information than that which you presented here.

PeterC
April 10th, 2004, 20:41
Newsflash: I just found the meanings of the mystery coff header fields.... http://www.ida.liu.se/~TDDB72/material/begguide/htmlref/structaouthdr.html

I can see what the gp_value is (the value of gp...) but I am not sure of what to make of gprmask and cprmask... according to some additional digging they are the "general-purpose register mask" and "co-processor register masks". I have no idea what that means :) but first I will try and add the GP register setting to the code and see if that has any effect.

(update: it had no effect, games still stall with CD-related error messages and I still have no controller or sound).