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); }
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; }
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); }
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 {
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 } }
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; }
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 } }
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; }
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; }
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; }
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); }
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; }
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; }
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(§ion_address, 4, 1, tmpFile); fread(§ion_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; }
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(§ion_address, 4, 1, tmpFile); fread(§ion_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(§ion, 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; }
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; }