u32 psxMemRead32(u32 mem) { char *p; u32 t; psxRegs.cycle += 1; t = mem >> 16; if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) { if ((mem & 0xffff) < 0x400) return psxHu32(mem); else return psxHwRead32(mem); } else { p = (char *)(psxMemRLUT[t]); if (p != NULL) { if (Config.Debug) DebugCheckBP((mem & 0xffffff) | 0x80000000, BR4); return SWAPu32(*(u32 *)(p + (mem & 0xffff))); } else { #ifdef PSXMEM_LOG if (writeok) { PSXMEM_LOG("err lw %8.8lx\n", mem); } #endif return 0; } } }
void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif // SysPrintf("Sio Interrupt\n"); StatReg|= IRQ; psxHu32ref(0x1070)|= SWAPu32(0x80); }
void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif if (!(StatReg & IRQ)) { StatReg |= IRQ; psxHu32ref(0x1070) |= SWAPu32(0x80); } }
void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif // SysPrintf("Sio Interrupt\n"); StatReg |= IRQ; psxHu32ref(0x1070) |= SWAPu32(0x80); #if 0 // Rhapsody: fixes input problems // Twisted Metal 2: breaks intro StatReg |= TX_RDY; StatReg |= RX_RDY; #endif }
u32 psxMemRead32(u32 mem) { u32 t; t = mem >> 16; if (t == 0x1f80) { if (mem < 0x1f801000) return psxHu32(mem); else return psxHwRead32(mem); } else { char *p = (char *)(psxMemRLUT[t]); if (p != NULL) { return SWAPu32(*(u32 *)(p + (mem & 0xffff))); } else { #ifdef PSXMEM_LOG if (writeok) { PSXMEM_LOG("err lw %8.8lx\n", mem); } #endif return 0; } } }
void CALLBACK SIO1irq(void) { psxHu32ref(0x1070) |= SWAPu32(0x100); }
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 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; }
void psxHwWrite32(u32 add, u32 value) { switch (add) { case 0x1f801040: sioWrite8((unsigned char)value); sioWrite8((unsigned char)((value&0xff) >> 8)); sioWrite8((unsigned char)((value&0xff) >> 16)); sioWrite8((unsigned char)((value&0xff) >> 24)); #ifdef PAD_LOG PAD_LOG("sio write32 %x\n", value); #endif return; #ifdef ENABLE_SIO1API case 0x1f801050: SIO1_writeData32(value); return; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size write %x\n", value); psxHu32ref(add) = SWAPu32(value); return; // Ram size #endif case 0x1f801070: #ifdef PSXHW_LOG PSXHW_LOG("IREG 32bit write %x\n", value); #endif if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80); if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200); psxHu32ref(0x1070) &= SWAPu32((psxHu32(0x1074) & value)); return; case 0x1f801074: #ifdef PSXHW_LOG PSXHW_LOG("IMASK 32bit write %x\n", value); #endif psxHu32ref(0x1074) = SWAPu32(value); if (psxHu32ref(0x1070) & value) new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1); return; #ifdef PSXHW_LOG case 0x1f801080: PSXHW_LOG("DMA0 MADR 32bit write %x\n", value); HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr case 0x1f801084: PSXHW_LOG("DMA0 BCR 32bit write %x\n", value); HW_DMA0_BCR = SWAPu32(value); return; // DMA0 bcr #endif case 0x1f801088: #ifdef PSXHW_LOG PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value); #endif DmaExec(0); // DMA0 chcr (MDEC in DMA) return; #ifdef PSXHW_LOG case 0x1f801090: PSXHW_LOG("DMA1 MADR 32bit write %x\n", value); HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr case 0x1f801094: PSXHW_LOG("DMA1 BCR 32bit write %x\n", value); HW_DMA1_BCR = SWAPu32(value); return; // DMA1 bcr #endif case 0x1f801098: #ifdef PSXHW_LOG PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value); #endif DmaExec(1); // DMA1 chcr (MDEC out DMA) return; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit write %x\n", value); HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit write %x\n", value); HW_DMA2_BCR = SWAPu32(value); return; // DMA2 bcr #endif case 0x1f8010a8: #ifdef PSXHW_LOG PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value); #endif DmaExec(2); // DMA2 chcr (GPU DMA) return; #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit write %x\n", value); HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit write %x\n", value); HW_DMA3_BCR = SWAPu32(value); return; // DMA3 bcr #endif case 0x1f8010b8: #ifdef PSXHW_LOG PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value); #endif DmaExec(3); // DMA3 chcr (CDROM DMA) return; #ifdef PSXHW_LOG case 0x1f8010c0: PSXHW_LOG("DMA4 MADR 32bit write %x\n", value); HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr case 0x1f8010c4: PSXHW_LOG("DMA4 BCR 32bit write %x\n", value); HW_DMA4_BCR = SWAPu32(value); return; // DMA4 bcr #endif case 0x1f8010c8: #ifdef PSXHW_LOG PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value); #endif DmaExec(4); // DMA4 chcr (SPU DMA) return; #if 0 case 0x1f8010d0: break; //DMA5write_madr(); case 0x1f8010d4: break; //DMA5write_bcr(); case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed #endif #ifdef PSXHW_LOG case 0x1f8010e0: PSXHW_LOG("DMA6 MADR 32bit write %x\n", value); HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr case 0x1f8010e4: PSXHW_LOG("DMA6 BCR 32bit write %x\n", value); HW_DMA6_BCR = SWAPu32(value); return; // DMA6 bcr #endif case 0x1f8010e8: #ifdef PSXHW_LOG PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value); #endif DmaExec(6); // DMA6 chcr (OT clear) return; #ifdef PSXHW_LOG case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit write %x\n", value); HW_DMA_PCR = SWAPu32(value); return; #endif case 0x1f8010f4: #ifdef PSXHW_LOG PSXHW_LOG("DMA ICR 32bit write %x\n", value); #endif { u32 tmp = value & 0x00ff803f; tmp |= (SWAPu32(HW_DMA_ICR) & ~value) & 0x7f000000; if ((tmp & HW_DMA_ICR_GLOBAL_ENABLE && tmp & 0x7f000000) || tmp & HW_DMA_ICR_BUS_ERROR) { if (!(SWAPu32(HW_DMA_ICR) & HW_DMA_ICR_IRQ_SENT)) psxHu32ref(0x1070) |= SWAP32(8); tmp |= HW_DMA_ICR_IRQ_SENT; } HW_DMA_ICR = SWAPu32(tmp); return; } case 0x1f801810: #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit write %x\n", value); #endif GPU_writeData(value); return; case 0x1f801814: #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit write %x\n", value); #endif GPU_writeStatus(value); gpuSyncPluginSR(); return; case 0x1f801820: mdecWrite0(value); break; case 0x1f801824: mdecWrite1(value); break; case 0x1f801100: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value); #endif psxRcntWcount(0, value & 0xffff); return; case 0x1f801104: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value); #endif psxRcntWmode(0, value); return; case 0x1f801108: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= SWAP32((~value)&0xff000000); case 0x1f801110: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value); #endif psxRcntWcount(1, value & 0xffff); return; case 0x1f801114: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value); #endif psxRcntWmode(1, value); return; case 0x1f801118: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(1, value & 0xffff); return; case 0x1f801120: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value); #endif psxRcntWcount(2, value & 0xffff); return; case 0x1f801124: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value); #endif psxRcntWmode(2, value); return; case 0x1f801128: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(2, value & 0xffff); return; default: // Dukes of Hazard 2 - car engine noise if (add>=0x1f801c00 && add<0x1f801e00) { SPU_writeRegister(add, value&0xffff); SPU_writeRegister(add + 2, value>>16); return; } psxHu32ref(add) = SWAPu32(value); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value); #endif return; }
u32 psxHwRead32(u32 add) { u32 hard; switch (add) { case 0x1f801040: hard = sioRead8(); hard |= sioRead8() << 8; hard |= sioRead8() << 16; hard |= sioRead8() << 24; #ifdef PAD_LOG PAD_LOG("sio read32 ;ret = %x\n", hard); #endif return hard; #ifdef ENABLE_SIO1API case 0x1f801050: hard = SIO1_readData32(); return hard; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060)); return psxHu32(0x1060); #endif #ifdef PSXHW_LOG case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070)); return psxHu32(0x1070); #endif #ifdef PSXHW_LOG case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074)); return psxHu32(0x1074); #endif case 0x1f801810: hard = GPU_readData(); #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit read %x\n", hard); #endif return hard; case 0x1f801814: gpuSyncPluginSR(); hard = HW_GPU_STATUS; if (hSyncCount < 240 && (HW_GPU_STATUS & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS) hard |= PSXGPU_LCF & (psxRegs.cycle << 20); #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit read %x\n", hard); #endif return hard; case 0x1f801820: hard = mdecRead0(); break; case 0x1f801824: hard = mdecRead1(); break; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0)); return SWAPu32(HW_DMA2_MADR); case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4)); return SWAPu32(HW_DMA2_BCR); case 0x1f8010a8: PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8)); return SWAPu32(HW_DMA2_CHCR); #endif #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0)); return SWAPu32(HW_DMA3_MADR); case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4)); return SWAPu32(HW_DMA3_BCR); case 0x1f8010b8: PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8)); return SWAPu32(HW_DMA3_CHCR); #endif #ifdef PSXHW_LOG /* case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0)); return SWAPu32(HW_DMA_PCR); // dma rest channel case 0x1f8010f4: PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4)); return SWAPu32(HW_DMA_ICR); // interrupt enabler?*/ #endif // time for rootcounters :) case 0x1f801100: hard = psxRcntRcount(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read32: %x\n", hard); #endif return hard; case 0x1f801104: hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read32: %x\n", hard); #endif return hard; case 0x1f801108: hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read32: %x\n", hard); #endif return hard; case 0x1f801110: hard = psxRcntRcount(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read32: %x\n", hard); #endif return hard; case 0x1f801114: hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read32: %x\n", hard); #endif return hard; case 0x1f801118: hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read32: %x\n", hard); #endif return hard; case 0x1f801120: hard = psxRcntRcount(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read32: %x\n", hard); #endif return hard; case 0x1f801124: hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read32: %x\n", hard); #endif return hard; case 0x1f801128: hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read32: %x\n", hard); #endif return hard; default: hard = psxHu32(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unkwnown 32bit read at address %x\n", add); #endif return hard; } #ifdef PSXHW_LOG PSXHW_LOG("*Known 32bit read at address %x\n", add); #endif return hard; }
//senquack - A generic function SPU plugins can use to acknowledge SPU interrupts: void CALLBACK AcknowledgeSPUIRQ(void) { psxHu32ref(0x1070) |= SWAPu32(0x200); }
void psxMemWrite32(u32 mem, u32 value) { char *p; u32 t; psxRegs.cycle += 1; // if ((mem&0x1fffff) == 0x71E18 || value == 0x48088800) SysPrintf("t2fix!!\n"); t = mem >> 16; if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) { if ((mem & 0xffff) < 0x400) psxHu32ref(mem) = SWAPu32(value); else psxHwWrite32(mem, value); } else { p = (char *)(psxMemWLUT[t]); if (p != NULL) { if (Config.Debug) DebugCheckBP((mem & 0xffffff) | 0x80000000, BW4); *(u32 *)(p + (mem & 0xffff)) = SWAPu32(value); #ifdef PSXREC psxCpu->Clear(mem, 1); #endif } else { if (mem != 0xfffe0130) { #ifdef PSXREC if (!writeok) psxCpu->Clear(mem, 1); #endif #ifdef PSXMEM_LOG if (writeok) { PSXMEM_LOG("err sw %8.8lx\n", mem); } #endif } else { int i; // a0-44: used for cache flushing switch (value) { case 0x800: case 0x804: if (writeok == 0) break; writeok = 0; memset(psxMemWLUT + 0x0000, 0, 0x80 * sizeof(void *)); memset(psxMemWLUT + 0x8000, 0, 0x80 * sizeof(void *)); memset(psxMemWLUT + 0xa000, 0, 0x80 * sizeof(void *)); psxRegs.ICache_valid = FALSE; break; case 0x00: case 0x1e988: if (writeok == 1) break; writeok = 1; for (i = 0; i < 0x80; i++) psxMemWLUT[i + 0x0000] = (void *)&psxM[(i & 0x1f) << 16]; memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void *)); memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void *)); break; default: #ifdef PSXMEM_LOG PSXMEM_LOG("unk %8.8lx = %x\n", mem, value); #endif break; } } } } }
void psxHwWrite32(u32 add, u32 value) { switch (add) { case 0x1f801040: sioWrite8((unsigned char)value); sioWrite8((unsigned char)((value&0xff) >> 8)); sioWrite8((unsigned char)((value&0xff) >> 16)); sioWrite8((unsigned char)((value&0xff) >> 24)); #ifdef PAD_LOG PAD_LOG("sio write32 %x\n", value); #endif return; #ifdef ENABLE_SIO1API case 0x1f801050: SIO1_writeData32(value); #ifdef SIO1_LOG SIO1_LOG("sio1 write32 %x\n", value); #endif return; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size write %x\n", value); psxHu32ref(add) = SWAPu32(value); return; // Ram size #endif case 0x1f801070: #ifdef PSXHW_LOG PSXHW_LOG("IREG 32bit write %x\n", value); #endif if (Config.SioIrq) psxHu32ref(0x1070) |= SWAPu32(0x80); if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200); psxHu32ref(0x1070) &= SWAPu32(value); return; case 0x1f801074: #ifdef PSXHW_LOG PSXHW_LOG("IMASK 32bit write %x\n", value); #endif psxHu32ref(0x1074) = SWAPu32(value); return; #ifdef PSXHW_LOG case 0x1f801080: PSXHW_LOG("DMA0 MADR 32bit write %x\n", value); HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr case 0x1f801084: PSXHW_LOG("DMA0 BCR 32bit write %x\n", value); HW_DMA0_BCR = SWAPu32(value); return; // DMA0 bcr #endif case 0x1f801088: #ifdef PSXHW_LOG PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value); #endif DmaExec(0); // DMA0 chcr (MDEC in DMA) return; #ifdef PSXHW_LOG case 0x1f801090: PSXHW_LOG("DMA1 MADR 32bit write %x\n", value); HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr case 0x1f801094: PSXHW_LOG("DMA1 BCR 32bit write %x\n", value); HW_DMA1_BCR = SWAPu32(value); return; // DMA1 bcr #endif case 0x1f801098: #ifdef PSXHW_LOG PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value); #endif DmaExec(1); // DMA1 chcr (MDEC out DMA) return; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit write %x\n", value); HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit write %x\n", value); HW_DMA2_BCR = SWAPu32(value); return; // DMA2 bcr #endif case 0x1f8010a8: #ifdef PSXHW_LOG PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value); #endif /* A hack that makes Vampire Hunter D title screen visible, /* but makes Tomb Raider II water effect to stay opaque /* Root cause for this problem is that when DMA2 is issued /* it is incompletele and still beign built by the game. /* Maybe it is ready when some signal comes in or within given delay? */ if (dmaGpuListHackEn && value == 0x00000401 && HW_DMA2_BCR == 0x0) { psxDma2(SWAPu32(HW_DMA2_MADR), SWAPu32(HW_DMA2_BCR), SWAPu32(value)); return; } DmaExec(2); // DMA2 chcr (GPU DMA) if (HW_DMA2_CHCR == 0x1000401) dmaGpuListHackEn=TRUE; return; #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit write %x\n", value); HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit write %x\n", value); HW_DMA3_BCR = SWAPu32(value); return; // DMA3 bcr #endif case 0x1f8010b8: #ifdef PSXHW_LOG PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value); #endif DmaExec(3); // DMA3 chcr (CDROM DMA) return; #ifdef PSXHW_LOG case 0x1f8010c0: PSXHW_LOG("DMA4 MADR 32bit write %x\n", value); HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr case 0x1f8010c4: PSXHW_LOG("DMA4 BCR 32bit write %x\n", value); HW_DMA4_BCR = SWAPu32(value); return; // DMA4 bcr #endif case 0x1f8010c8: #ifdef PSXHW_LOG PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value); #endif DmaExec(4); // DMA4 chcr (SPU DMA) return; #if 0 case 0x1f8010d0: break; //DMA5write_madr(); case 0x1f8010d4: break; //DMA5write_bcr(); case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed #endif #ifdef PSXHW_LOG case 0x1f8010e0: PSXHW_LOG("DMA6 MADR 32bit write %x\n", value); HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr case 0x1f8010e4: PSXHW_LOG("DMA6 BCR 32bit write %x\n", value); HW_DMA6_BCR = SWAPu32(value); return; // DMA6 bcr #endif case 0x1f8010e8: #ifdef PSXHW_LOG PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value); #endif DmaExec(6); // DMA6 chcr (OT clear) return; #ifdef PSXHW_LOG case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit write %x\n", value); HW_DMA_PCR = SWAPu32(value); return; #endif case 0x1f8010f4: #ifdef PSXHW_LOG PSXHW_LOG("DMA ICR 32bit write %x\n", value); #endif { u32 tmp = (~value) & SWAPu32(HW_DMA_ICR); HW_DMA_ICR = SWAPu32(((tmp ^ value) & 0xffffff) ^ tmp); return; } case 0x1f801014: #ifdef PSXHW_LOG PSXHW_LOG("SPU delay [0x1014] write32: %8.8lx\n", value); #endif psxHu32ref(add) = SWAPu32(value); return; case 0x1f801810: #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit write %x\n", value); #endif GPU_writeData(value); return; case 0x1f801814: #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit write %x\n", value); #endif if (value & 0x8000000) dmaGpuListHackEn=FALSE; GPU_writeStatus(value); return; case 0x1f801820: mdecWrite0(value); break; case 0x1f801824: mdecWrite1(value); break; case 0x1f801100: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value); #endif psxRcntWcount(0, value & 0xffff); return; case 0x1f801104: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value); #endif psxRcntWmode(0, value); return; case 0x1f801108: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= SWAP32((~value)&0xff000000); case 0x1f801110: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value); #endif psxRcntWcount(1, value & 0xffff); return; case 0x1f801114: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value); #endif psxRcntWmode(1, value); return; case 0x1f801118: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(1, value & 0xffff); return; case 0x1f801120: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value); #endif psxRcntWcount(2, value & 0xffff); return; case 0x1f801124: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value); #endif psxRcntWmode(2, value); return; case 0x1f801128: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(2, value & 0xffff); return; default: // Dukes of Hazard 2 - car engine noise if (add>=0x1f801c00 && add<0x1f801e00) { SPU_writeRegister(add, value&0xffff); add += 2; value >>= 16; if (add>=0x1f801c00 && add<0x1f801e00) SPU_writeRegister(add, value&0xffff); return; } psxHu32ref(add) = SWAPu32(value); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value); #endif return; }
u32 psxHwRead32(u32 add) { u32 hard; switch (add) { case 0x1f801040: hard = sioRead8(); hard |= sioRead8() << 8; hard |= sioRead8() << 16; hard |= sioRead8() << 24; #ifdef PAD_LOG PAD_LOG("sio read32 ;ret = %x\n", hard); #endif return hard; #ifdef ENABLE_SIO1API case 0x1f801050: hard = SIO1_readData32(); #ifdef SIO1_LOG SIO1_LOG("sio1 read32 ;ret = %x\n", hard); #endif return hard; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060)); return psxHu32(0x1060); #endif #ifdef PSXHW_LOG case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070)); return psxHu32(0x1070); #endif #ifdef PSXHW_LOG case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074)); return psxHu32(0x1074); #endif case 0x1f801810: hard = GPU_readData(); #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit read %x\n", hard); #endif return hard; case 0x1f801814: hard = gpuReadStatus(); #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit read %x\n", hard); #endif return hard; case 0x1f801820: hard = mdecRead0(); break; case 0x1f801824: hard = mdecRead1(); break; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0)); return SWAPu32(HW_DMA2_MADR); case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4)); return SWAPu32(HW_DMA2_BCR); case 0x1f8010a8: PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8)); return SWAPu32(HW_DMA2_CHCR); #endif #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0)); return SWAPu32(HW_DMA3_MADR); case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4)); return SWAPu32(HW_DMA3_BCR); case 0x1f8010b8: PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8)); return SWAPu32(HW_DMA3_CHCR); #endif #ifdef PSXHW_LOG case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit read %x\n", HW_DMA_PCR); return SWAPu32(HW_DMA_PCR); // DMA control register case 0x1f8010f4: PSXHW_LOG("DMA ICR 32bit read %x\n", HW_DMA_ICR); return SWAPu32(HW_DMA_ICR); // DMA interrupt register (enable/ack) #endif // time for rootcounters :) case 0x1f801100: hard = psxRcntRcount(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read32: %x\n", hard); #endif return hard; case 0x1f801104: hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read32: %x\n", hard); #endif return hard; case 0x1f801108: hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read32: %x\n", hard); #endif return hard; case 0x1f801110: hard = psxRcntRcount(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read32: %x\n", hard); #endif return hard; case 0x1f801114: hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read32: %x\n", hard); #endif return hard; case 0x1f801118: hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read32: %x\n", hard); #endif return hard; case 0x1f801120: hard = psxRcntRcount(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read32: %x\n", hard); #endif return hard; case 0x1f801124: hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read32: %x\n", hard); #endif return hard; case 0x1f801128: hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read32: %x\n", hard); #endif return hard; case 0x1f801014: hard = psxHu32(add); #ifdef PSXHW_LOG PSXHW_LOG("SPU delay [0x1014] read32: %8.8lx\n", hard); #endif return hard; default: hard = psxHu32(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit read at address %x (0x%8.8lx)\n", add, hard); #endif return hard; } #ifdef PSXHW_LOG PSXHW_LOG("*Known 32bit read at address %x\n", add); #endif return hard; }
static inline void setIrq( u32 irq ) { psxHu32ref(0x1070) |= SWAPu32(irq); }
psxRcntWmode(2, value); return; case 0x1f801128: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(2, value & 0xffff); return; default: // Dukes of Hazard 2 - car engine noise if (add>=0x1f801c00 && add<0x1f801e00) { SPU_writeRegister(add, value&0xffff); SPU_writeRegister(add + 2, value>>16); return; } psxHu32ref(add) = SWAPu32(value); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value); #endif return; } psxHu32ref(add) = SWAPu32(value); #ifdef PSXHW_LOG PSXHW_LOG("*Known 32bit write at address %x value %x\n", add, value); #endif } int psxHwFreeze(gzFile f, int Mode) { return 0; }
void CALLBACK SPUirq(void) { psxHu32ref(0x1070)|= SWAPu32(0x200); psxRegs.interrupt|= 0x80000000; }
INLINE void setIrq( u32 irq ) { psxHu32ref(0x1070) |= SWAPu32(irq); // CHUI: Añado ResetIoCycle para permite que en el proximo salto entre en psxBranchTest ResetIoCycle(); }