Example #1
0
void psxDma0(u32 adr, u32 bcr, u32 chcr) {
	int cmd = mdec.command;

	MDEC_LOG("DMA0 %lx %lx %lx", adr, bcr, chcr);

	if (chcr != 0x01000201) return;

	// bcr LSBs are the blocksize in words
	// bcr MSBs are the number of block
	int size = (bcr >> 16)*(bcr & 0xffff);
	if (size < 0) {
		// Need to investigate what happen if the transfer is huge
		Console.Error("psxDma0 DMA transfer overflow !");
		return;
	}

	for (int i = 0; i<(size); i++) {
		*(u32*)PSXM(((i + 0) * 4)) = iopMemRead32(adr + ((i + 0) * 4));
		if (i <20)
			MDEC_LOG(" data %08X  %08X ", iopMemRead32((adr & 0x00FFFFFF) + (i * 4)), *(u32*)PSXM((i * 4)));
	}


	if (cmd == 0x40000001) {
		u8 *p = (u8*)PSXM(0); //u8 *p = (u8*)PSXM(adr);
		iqtab_init(iq_y, p);
		iqtab_init(iq_uv, p + 64);
	}
	else if ((cmd & 0xf5ff0000) == 0x30000000) {
		mdec.rl = (u16*)PSXM(0); //mdec.rl = (u16*)PSXM(adr);
	}

	HW_DMA0_CHCR &= ~0x01000000;
	psxDmaInterrupt(0);
}
Example #2
0
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:
    		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;
}
Example #3
0
void psxDma3(u32 madr, u32 bcr, u32 chcr) {
	u32 cdsize;

	CDR_LOG("*** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);

	switch (chcr) {
		case 0x11000000:
		case 0x11400100:
			if (cdr.Readed == 0) {
				CDR_LOG("*** DMA 3 *** NOT READY\n");
				return;
			}

			cdsize = (bcr & 0xffff) * 4;
			memcpy_fast((u8*)PSXM(madr), cdr.pTransfer, cdsize);
			psxCpu->Clear(madr, cdsize/4);
			cdr.pTransfer+=cdsize;

			break;
		case 0x41000200:
			//SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr);
			return;

		default:
			CDR_LOG("Unknown cddma %lx\n", chcr);
			break;
	}
	HW_DMA3_CHCR &= ~0x01000000;
	psxDmaInterrupt(3);
}
Example #4
0
void inline execI()
{
	u32 *code;
	if (!iPause || iFrameAdvance)
	{
		if (iVSyncFlag) {
			if (iGpuHasUpdated) {
				if (iFrameAdvance || iDoPauseAtVSync) {
					iPause = 1;
					iDoPauseAtVSync = 0;
					iFrameAdvance = 0;
				}
				iGpuHasUpdated = 0;
			}
			iVSyncFlag = 0;
			if (iSaveStateTo) {
					WIN32_SaveState(iSaveStateTo-1);
					iSaveStateTo = 0;
			}
			PCSX_LuaFrameBoundary();
			iJoysToPoll = 2;
		}

		code = PSXM(psxRegs.pc);
		psxRegs.code = code == NULL ? 0 : *code;
		debugI();
		psxRegs.pc+= 4; psxRegs.cycle++;
		psxBSC[psxRegs.code >> 26]();
	}
	else {
Example #5
0
void mdecInit(void) {

	Config.Mdec = 0; //XXXXXXXXXXXXXXXXX  0 or 1 // 1 is black and white decoding

	mdec.rl = (u16*)PSXM(0);
	//mdec.rl = (u16*)&psxM[0x100000];
	mdec.command = 0;
	mdec.status = 0;
	round_init();
}
void upse_ps1_spu_dma_read_memory(upse_spu_state_t *spu, u32 usPSXMem, int iSize)
{
    int i;

    for (i = 0; i < iSize; i++)
    {
	*(u16 *) PSXM(spu->ins, usPSXMem) = spu_lh(spu->pCore, 0x1F801DA8);	// spu addr got by writeregister
	usPSXMem += 2;
	}
}
void upse_ps1_spu_dma_write_memory(upse_spu_state_t *spu, u32 usPSXMem, int iSize)
{
    int i;

    for (i = 0; i < iSize; i++)
    {
	spu_sh(spu->pCore, 0x1F801DA8, *(u16 *) PSXM(spu->ins, usPSXMem));
	usPSXMem += 2;		// spu addr got by writeregister
	}
}
Example #8
0
int LoadCdromFile(const char *filename, EXE_HEADER *head) {
	struct iso_directory_record *dir;
	u8 time[4],*buf;
	u8 mdir[4096], exename[256];
	u32 size, addr;
	void *psxaddr;

	if (sscanf(filename, "cdrom:\\%255s", exename) <= 0)
	{
		// Some games omit backslash (NFS4)
		if (sscanf(filename, "cdrom:%255s", exename) <= 0)
		{
			SysPrintf("LoadCdromFile: EXE NAME PARSING ERROR (%s (%u))\n", filename, strlen(filename));
			exit (1);
		}
	}

	time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);

	READTRACK();

	// skip head and sub, and go to the root directory record
	dir = (struct iso_directory_record *)&buf[12 + 156]; 

	mmssdd(dir->extent, (char*)time);

	READDIR(mdir);

	if (GetCdromFile(mdir, time, exename) == -1) return -1;

	READTRACK();

	memcpy(head, buf + 12, sizeof(EXE_HEADER));
	size = head->t_size;
	addr = head->t_addr;

	// Cache clear/invalidate dynarec/int. Fixes startup of Casper/X-Files and possibly others.
	psxCpu->Clear(addr, size / 4);
	psxRegs.ICache_valid = FALSE;

	while (size) {
		incTime();
		READTRACK();

		psxaddr = (void *)PSXM(addr);
		assert(psxaddr != NULL);
		memcpy(psxaddr, buf + 12, 2048);

		size -= 2048;
		addr += 2048;
	}

	return 0;
}
Example #9
0
void SPUwriteDMAMem(u32 usPSXMem,int iSize)
{
    int i;

    for(i=0; i<iSize; i++)
    {
        spuMem[spuAddr>>1] = *(u16 *)PSXM(usPSXMem);
        usPSXMem+=2;                  			// spu addr got by writeregister
        spuAddr+=2;                                         // inc spu addr
        if(spuAddr>0x7ffff) spuAddr=0;                      // wrap
    }
}
Example #10
0
static void hleExecRet() {
	EXEC *header = (EXEC*)PSXM(psxRegs.GPR.n.s0);

	//SysPrintf("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret);

	psxRegs.GPR.n.ra = BFLIP32(header->ret);
	psxRegs.GPR.n.sp = BFLIP32(header->_sp);
	psxRegs.GPR.n.s8 = BFLIP32(header->_fp);
	psxRegs.GPR.n.gp = BFLIP32(header->_gp);
	psxRegs.GPR.n.s0 = BFLIP32(header->base);

	psxRegs.GPR.n.v0 = 1;
	psxRegs.pc = psxRegs.GPR.n.ra;
}
Example #11
0
static void hleExecRet() {
	EXEC *header = (EXEC*)PSXM(psxRegs.GPR.n.s0);

	SysPrintf("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret);

	psxRegs.GPR.n.ra = header->ret;
	psxRegs.GPR.n.sp = header->_sp;
	psxRegs.GPR.n.s8 = header->_fp;
	psxRegs.GPR.n.gp = header->_gp;
	psxRegs.GPR.n.s0 = header->base;

	psxRegs.GPR.n.v0 = 1;
	psxRegs.pc = psxRegs.GPR.n.ra;
}
Example #12
0
int LoadCdromFile(const char *filename, EXE_HEADER *head) {
	struct iso_directory_record *dir;
	u8 time[4],*buf;
	u8 mdir[4096];
	char exename[256];
	u32 size, addr;
	void *mem;

	sscanf(filename, "cdrom:\\%256s", exename);

	time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);

	READTRACK();

	// skip head and sub, and go to the root directory record
	dir = (struct iso_directory_record *)&buf[12 + 156]; 

	mmssdd(dir->extent, (char*)time);

	READDIR(mdir);

	if (GetCdromFile(mdir, time, exename) == -1) return -1;

	READTRACK();

	memcpy(head, buf + 12, sizeof(EXE_HEADER));
	size = head->t_size;
	addr = head->t_addr;

	psxCpu->Clear(addr, size / 4);

	while (size & ~2047) {
		incTime();
		READTRACK();

		mem = PSXM(addr);
		if (mem)
			memcpy(mem, buf + 12, 2048);

		size -= 2048;
		addr += 2048;
	}

	return 0;
}
Example #13
0
void psxDma3(u32 madr, u32 bcr, u32 chcr) {
	u32 cdsize;
	u8 *ptr;

#ifdef CDR_LOG
	CDR_LOG("psxDma3() Log: *** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
#endif

	switch (chcr) {
		case 0x11000000:
		case 0x11400100:
			if (cdr.Readed == 0) {
#ifdef CDR_LOG
				CDR_LOG("psxDma3() Log: *** DMA 3 *** NOT READY\n");
#endif
				break;
			}

			cdsize = (bcr & 0xffff) * 4;

			ptr = (u8*)PSXM(madr);
			if (ptr == NULL) {
#ifdef CPU_LOG
				CDR_LOG("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n");
#endif
				break;
			}
			memcpy(ptr, cdr.pTransfer, cdsize);
			psxCpu->Clear(madr, cdsize/4);
			cdr.pTransfer+= cdsize;

			break;
		default:
#ifdef CDR_LOG
			CDR_LOG("psxDma3() Log: Unknown cddma %lx\n", chcr);
#endif
			break;
	}

	HW_DMA3_CHCR &= SWAP32(~0x01000000);
	DMA_INTERRUPT(3);
}
Example #14
0
static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr)
{
    u32 *ptr, code, bPC = 0;
    int i, use, reguse = 0;

    for (i=0; i<numInstr; ) {
        // load current instruction
		  ptr = PSXM(pc);
		  if (ptr==NULL) {
				// going nowhere... might as well assume a write, since we will hopefully never reach here
				reguse = REGUSE_WRITE;
				break;
		  }
		  code = SWAP32(*ptr);
		  // get usage patterns for instruction
		  use = getRegUse(code);
		  // find the use of psxreg in the instruction
        reguse = useOfPsxReg(code, use, psxreg);
        
		  // return if we have found a use
        if (reguse != REGUSE_NONE)
				break;
        
		  // goto next instruction
        pc += 4;
		  i++;
		  
		  // check for code branches/jumps
		  if (i != numInstr) {
			  if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) {
#ifndef NOREGUSE_FOLLOW
					// check delay slot
					reguse = _nextPsxRegUse(pc, psxreg, 1);
					if (reguse != REGUSE_NONE) break;
					
					bPC = _fImm_(code) * 4 + pc;
					reguse = _nextPsxRegUse(pc+4, psxreg, (numInstr-i-1)/2);
					if (reguse != REGUSE_NONE) {
						int reguse2 = _nextPsxRegUse(bPC, psxreg, (numInstr-i-1)/2);
						if (reguse2 != REGUSE_NONE)
							reguse |= reguse2;
						else
							reguse = REGUSE_NONE;
					}
#endif
					break;
			  } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) {
#ifndef NOREGUSE_FOLLOW
					// check delay slot
					reguse = _nextPsxRegUse(pc, psxreg, 1);
					if (reguse != REGUSE_NONE) break;
					
					bPC = _fTarget_(code) * 4 + (pc & 0xf0000000);
					reguse = _nextPsxRegUse(bPC, psxreg, numInstr-i-1);
#endif
					break;
			  } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR) {
#ifndef NOREGUSE_FOLLOW
					// jump to unknown location - bail after checking delay slot
					reguse = _nextPsxRegUse(pc, psxreg, 1);
#endif
					break;
			  } else if ((use & REGUSE_TYPEM) == REGUSE_SYS) {
					break;
			  }
		  }
    }
    
    return reguse;
}
Example #15
0
int LoadCdrom() {
	EXE_HEADER tmpHead;
	struct iso_directory_record *dir;
	u8 time[4],*buf;
	u8 mdir[4096];
	s8 exename[256];
	int i;

	if (!Config.HLE) {
		psxRegs.pc = psxRegs.GPR.n.ra;
		return 0;
	}

	time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);

	READTRACK();

	// skip head and sub, and go to the root directory record
	dir = (struct iso_directory_record*) &buf[12+156]; 

	mmssdd(dir->extent, (char*)time);

	READDIR(mdir);

	if (GetCdromFile(mdir, time, "SYSTEM.CNF;1") == -1) {
		if (GetCdromFile(mdir, time, "PSX.EXE;1") == -1) return -1;

		READTRACK();
	}
	else {
		READTRACK();

		sscanf((char*)buf+12, "BOOT = cdrom:\\%s", exename);
		if (GetCdromFile(mdir, time, exename) == -1) {
			sscanf((char*)buf+12, "BOOT = cdrom:%s", exename);
			if (GetCdromFile(mdir, time, exename) == -1) {
				char *ptr = strstr(buf+12, "cdrom:");
				for (i=0; i<32; i++) {
					if (ptr[i] == ' ') continue;
					if (ptr[i] == '\\') continue;
				}
				strcpy(exename, ptr);
				if (GetCdromFile(mdir, time, exename) == -1)
					return -1;
			}
		}

		READTRACK();
	}

	memcpy(&tmpHead, buf+12, sizeof(EXE_HEADER));

#ifdef __MACOSX__
	swapEXE_HEADER(&tmpHead);
#endif

	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;

	while (tmpHead.t_size) {
		void *ptr = (void *)PSXM(tmpHead.t_addr);

		incTime();
		READTRACK();

		if (ptr != NULL) memcpy(ptr, buf+12, 2048);

		tmpHead.t_size -= 2048;
		tmpHead.t_addr += 2048;
	}

	return 0;
}
Example #16
0
int Load(const char *ExePath) {
	FILE *tmpFile;
	EXE_HEADER tmpHead;
	int type;
	int retval = 0;
	u8 opcode;
	u32 section_address, section_size;
	void *mem;

	strncpy(CdromId, "SLUS99999", 9);
	strncpy(CdromLabel, "SLUS_999.99", 11);

	tmpFile = fopen(ExePath, "rb");
	if (tmpFile == NULL) {
		SysPrintf(_("Error opening file: %s.\n"), ExePath);
		retval = -1;
	} else {
		type = PSXGetFileType(tmpFile);
		switch (type) {
			case PSX_EXE:
				fread(&tmpHead,sizeof(EXE_HEADER),1,tmpFile);
				section_address = SWAP32(tmpHead.t_addr);
				section_size = SWAP32(tmpHead.t_size);
				mem = PSXM(section_address);
				if (mem != NULL) {
					fseek(tmpFile, 0x800, SEEK_SET);		
					fread_to_ram(mem, section_size, 1, tmpFile);
					psxCpu->Clear(section_address, section_size / 4);
				}
				fclose(tmpFile);
				psxRegs.pc = SWAP32(tmpHead.pc0);
				psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
				psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr); 
				if (psxRegs.GPR.n.sp == 0)
					psxRegs.GPR.n.sp = 0x801fff00;
				retval = 0;
				break;
			case CPE_EXE:
				fseek(tmpFile, 6, SEEK_SET); /* Something tells me we should go to 4 and read the "08 00" here... */
				do {
					fread(&opcode, 1, 1, tmpFile);
					switch (opcode) {
						case 1: /* Section loading */
							fread(&section_address, 4, 1, tmpFile);
							fread(&section_size, 4, 1, tmpFile);
							section_address = SWAPu32(section_address);
							section_size = SWAPu32(section_size);
#ifdef EMU_LOG
							EMU_LOG("Loading %08X bytes from %08X to %08X\n", section_size, ftell(tmpFile), section_address);
#endif
							mem = PSXM(section_address);
							if (mem != NULL) {
								fread_to_ram(mem, section_size, 1, tmpFile);
								psxCpu->Clear(section_address, section_size / 4);
							}
							break;
						case 3: /* register loading (PC only?) */
							fseek(tmpFile, 2, SEEK_CUR); /* unknown field */
							fread(&psxRegs.pc, 4, 1, tmpFile);
							psxRegs.pc = SWAPu32(psxRegs.pc);
							break;
						case 0: /* End of file */
							break;
						default:
							SysPrintf(_("Unknown CPE opcode %02x at position %08x.\n"), opcode, ftell(tmpFile) - 1);
							retval = -1;
							break;
					}
				} while (opcode != 0 && retval == 0);
				break;
			case COFF_EXE:
				SysPrintf(_("COFF files not supported.\n"));
				retval = -1;
				break;
			case INVALID_EXE:
				SysPrintf(_("This file does not appear to be a valid PSX EXE file.\n"));
				SysPrintf(_("(did you forget -cdfile ?)\n"));
				retval = -1;
				break;
		}
	}

	if (retval != 0) {
		CdromId[0] = '\0';
		CdromLabel[0] = '\0';
	}

	return retval;
}
Example #17
0
int Load(const char *ExePath) {
	FILE *tmpFile;
	EXE_HEADER tmpHead;
	FILHDR coffHead;
	AOUTHDR optHead;
	SCNHDR section;
	int type, i;
	int retval = 0;
	u8 opcode;
	u32 section_address, section_size;
	void* psxmaddr;

	strncpy(CdromId, "SLUS99999", 9);
	strncpy(CdromLabel, "SLUS_999.99", 11);

	tmpFile = fopen(ExePath, "rb");
	if (tmpFile == NULL) {
		SysPrintf(_("Error opening file: %s.\n"), ExePath);
		retval = -1;
	} else {
		LoadLibPS();

		type = PSXGetFileType(tmpFile);
		switch (type) {
			case PSX_EXE:
				fread(&tmpHead, sizeof(EXE_HEADER), 1, tmpFile);
				fseek(tmpFile, 0x800, SEEK_SET);		
				fread(PSXM(SWAP32(tmpHead.t_addr)), SWAP32(tmpHead.t_size), 1, tmpFile);
				fclose(tmpFile);
				psxRegs.pc = SWAP32(tmpHead.pc0);
				psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
				psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr); 
				if (psxRegs.GPR.n.sp == 0)
					psxRegs.GPR.n.sp = 0x801fff00;
				retval = 0;
				break;

			case CPE_EXE:
				fseek(tmpFile, 6, SEEK_SET); /* Something tells me we should go to 4 and read the "08 00" here... */
				do {
					fread(&opcode, 1, 1, tmpFile);
					switch (opcode) {
						case 1: /* Section loading */
							fread(&section_address, 4, 1, tmpFile);
							fread(&section_size, 4, 1, tmpFile);
							section_address = SWAPu32(section_address);
							section_size = SWAPu32(section_size);
#ifdef EMU_LOG
							EMU_LOG("Loading %08X bytes from %08X to %08X\n", section_size, ftell(tmpFile), section_address);
#endif
							fread(PSXM(section_address), section_size, 1, tmpFile);
							break;
						case 3: /* register loading (PC only?) */
							fseek(tmpFile, 2, SEEK_CUR); /* unknown field */
							fread(&psxRegs.pc, 4, 1, tmpFile);
							psxRegs.pc = SWAPu32(psxRegs.pc);
							break;
						case 0: /* End of file */
							break;
						default:
							SysPrintf(_("Unknown CPE opcode %02x at position %08x.\n"), opcode, ftell(tmpFile) - 1);
							retval = -1;
							break;
					}
				} while (opcode != 0 && retval == 0);
				break;

			case COFF_EXE:
				fread(&coffHead, sizeof(coffHead), 1, tmpFile);
				fread(&optHead, sizeof(optHead), 1, tmpFile);

				psxRegs.pc = SWAP32(optHead.entry);
				psxRegs.GPR.n.sp = 0x801fff00;

				for (i = 0; i < SWAP16(coffHead.f_nscns); i++) {
					fseek(tmpFile, sizeof(FILHDR) + SWAP16(coffHead.f_opthdr) + sizeof(section) * i, SEEK_SET);
					fread(&section, sizeof(section), 1, tmpFile);

					if (section.s_scnptr != 0) {
						fseek(tmpFile, SWAP32(section.s_scnptr), SEEK_SET);
						fread(PSXM(SWAP32(section.s_paddr)), SWAP32(section.s_size), 1, tmpFile);
					} else {
						psxmaddr = PSXM(SWAP32(section.s_paddr));
						assert(psxmaddr != NULL);
						memset(psxmaddr, 0, SWAP32(section.s_size));
					}
				}
				break;

			case INVALID_EXE:
				SysPrintf("%s", _("This file does not appear to be a valid PSX file.\n"));
				retval = -1;
				break;
		}
	}

	if (retval != 0) {
		CdromId[0] = '\0';
		CdromLabel[0] = '\0';
	}

	return retval;
}
Example #18
0
int LoadCdrom() {
	EXE_HEADER tmpHead;
	struct iso_directory_record *dir;
	u8 time[4], *buf;
	u8 mdir[4096];
	s8 exename[256];

	if (!Config.HLE) {
		if (!Config.SlowBoot) psxRegs.pc = psxRegs.GPR.n.ra;
		return 0;
	}

	time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);

	READTRACK();

	// skip head and sub, and go to the root directory record
	dir = (struct iso_directory_record*) &buf[12+156]; 

	mmssdd(dir->extent, (char*)time);

	READDIR(mdir);

	// Load SYSTEM.CNF and scan for the main executable
	if (GetCdromFile(mdir, time, "SYSTEM.CNF;1") == -1) {
		// if SYSTEM.CNF is missing, start an existing PSX.EXE
		if (GetCdromFile(mdir, time, "PSX.EXE;1") == -1) return -1;

		READTRACK();
	}
	else {
		// read the SYSTEM.CNF
		READTRACK();

		sscanf((char *)buf + 12, "BOOT = cdrom:\\%255s", exename);
		if (GetCdromFile(mdir, time, exename) == -1) {
			sscanf((char *)buf + 12, "BOOT = cdrom:%255s", exename);
			if (GetCdromFile(mdir, time, exename) == -1) {
				char *ptr = strstr(buf + 12, "cdrom:");
				if (ptr != NULL) {
					ptr += 6;
					while (*ptr == '\\' || *ptr == '/') ptr++;
					strncpy(exename, ptr, 255);
					exename[255] = '\0';
					ptr = exename;
					while (*ptr != '\0' && *ptr != '\r' && *ptr != '\n') ptr++;
					*ptr = '\0';
					if (GetCdromFile(mdir, time, exename) == -1)
						return -1;
				} else
					return -1;
			}
		}

		// Read the EXE-Header
		READTRACK();
	}

	memcpy(&tmpHead, buf + 12, sizeof(EXE_HEADER));

	psxRegs.pc = SWAP32(tmpHead.pc0);
	psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
	psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr); 
	if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;

	tmpHead.t_size = SWAP32(tmpHead.t_size);
	tmpHead.t_addr = SWAP32(tmpHead.t_addr);

	// Read the rest of the main executable
	while (tmpHead.t_size) {
		void *ptr = (void *)PSXM(tmpHead.t_addr);

		incTime();
		READTRACK();

		if (ptr != NULL) memcpy(ptr, buf+12, 2048);

		tmpHead.t_size -= 2048;
		tmpHead.t_addr += 2048;
	}

	return 0;
}