void psxHwReset() { if (Config.SioIrq) psxHu32ref(0x1070) |= SWAP32(0x80); if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAP32(0x200); memset(psxH, 0, 0x10000); mdecInit(); // initialize mdec decoder cdrReset(); psxRcntInit(); }
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 psxMemWrite32(u32 mem, u32 value) { char *p; u32 t; // 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, W4); *(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; 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 *)); 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 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); } }
static void io_write_dma_icr32(u32 value) { 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); }
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 }
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; }
void cdrWrite1(unsigned char rt) { int i; #ifdef CDR_LOG CDR_LOG("cdrWrite1() Log: CD1 write: %x (%s)\n", rt, CmdName[rt]); #endif // psxHu8(0x1801) = rt; cdr.Cmd = rt; cdr.OCUP = 0; #ifdef CDRCMD_DEBUG SysPrintf("cdrWrite1() Log: CD1 write: %x (%s)", rt, CmdName[rt]); if (cdr.ParamC) { SysPrintf(" Param[%d] = {", cdr.ParamC); for (i=0;i<cdr.ParamC;i++) SysPrintf(" %x,", cdr.Param[i]); SysPrintf("}\n"); } else SysPrintf("\n"); #endif if (cdr.Ctrl & 0x1) return; switch(cdr.Cmd) { case CdlSync: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlNop: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSetloc: StopReading(); cdr.Seeked = 0; for (i=0; i<3; i++) cdr.SetSector[i] = btoi(cdr.Param[i]); cdr.SetSector[3] = 0; /* if ((cdr.SetSector[0] | cdr.SetSector[1] | cdr.SetSector[2]) == 0) { *(u32 *)cdr.SetSector = *(u32 *)cdr.SetSectorSeek; }*/ cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlPlay: if (!cdr.SetSector[0] && !cdr.SetSector[1] && !cdr.SetSector[2]) { if (CDR_getTN(cdr.ResultTN) != -1) { if (cdr.CurTrack > cdr.ResultTN[1]) cdr.CurTrack = cdr.ResultTN[1]; if (CDR_getTD((unsigned char)(cdr.CurTrack), cdr.ResultTD) != -1) { int tmp = cdr.ResultTD[2]; cdr.ResultTD[2] = cdr.ResultTD[0]; cdr.ResultTD[0] = tmp; if (!Config.Cdda) CDR_play(cdr.ResultTD); } } } else if (!Config.Cdda) CDR_play(cdr.SetSector); cdr.Play = 1; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlForward: if (cdr.CurTrack < 0xaa) cdr.CurTrack++; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlBackward: if (cdr.CurTrack > 1) cdr.CurTrack--; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlReadN: cdr.Irq = 0; StopReading(); cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; StartReading(1); break; case CdlStandby: StopCdda(); StopReading(); cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlStop: StopCdda(); StopReading(); cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlPause: StopCdda(); StopReading(); cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x40000); break; case CdlReset: case CdlInit: StopCdda(); StopReading(); cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlMute: cdr.Muted = 0; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlDemute: cdr.Muted = 1; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSetfilter: cdr.File = cdr.Param[0]; cdr.Channel = cdr.Param[1]; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSetmode: #ifdef CDR_LOG CDR_LOG("cdrWrite1() Log: Setmode %x\n", cdr.Param[0]); #endif cdr.Mode = cdr.Param[0]; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlGetmode: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlGetlocL: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlGetlocP: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlGetTN: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlGetTD: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSeekL: // ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0]; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSeekP: // ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0]; cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlTest: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlID: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; case CdlReadS: cdr.Irq = 0; StopReading(); cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; StartReading(2); break; case CdlReadToc: cdr.Ctrl|= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); break; default: #ifdef CDR_LOG CDR_LOG("cdrWrite1() Log: Unknown command: %x\n", cdr.Cmd); #endif return; } if (cdr.Stat != NoIntr) { psxHu32ref(0x1070)|= SWAP32((u32)0x4); psxRegs.interrupt|= 0x80000000; } }
void cdrReadInterrupt() { u8 *buf; if (!cdr.Reading) return; if (cdr.Stat) { CDREAD_INT(0x800); return; } #ifdef CDR_LOG CDR_LOG("cdrReadInterrupt() Log: KEY END"); #endif cdr.OCUP = 1; SetResultSize(1); cdr.StatP|= 0x22; cdr.StatP&=~0x40; cdr.Result[0] = cdr.StatP; buf = CDR_getBuffer(); if (buf == NULL) { cdr.RErr = -1; #ifdef CDR_LOG fprintf(emuLog, "cdrReadInterrupt() Log: err\n"); #endif memset(cdr.Transfer, 0, 2340); cdr.Stat = DiskError; cdr.Result[0]|= 0x01; ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; } memcpy(cdr.Transfer, buf, 2340); cdr.Stat = DataReady; #ifdef CDR_LOG fprintf(emuLog, "cdrReadInterrupt() Log: cdr.Transfer %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); #endif if ((cdr.Muted == 1) && (cdr.Mode & 0x40) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA if ((cdr.Transfer[4+2] & 0x4) && ((cdr.Mode&0x8) ? (cdr.Transfer[4+1] == cdr.Channel) : 1) && (cdr.Transfer[4+0] == cdr.File)) { int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); if (!ret) { SPU_playADPCMchannel(&cdr.Xa); cdr.FirstSector = 0; } else cdr.FirstSector = -1; } } cdr.SetSector[2]++; if (cdr.SetSector[2] == 75) { cdr.SetSector[2] = 0; cdr.SetSector[1]++; if (cdr.SetSector[1] == 60) { cdr.SetSector[1] = 0; cdr.SetSector[0]++; } } cdr.Readed = 0; if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF #ifdef CDR_LOG CDR_LOG("cdrReadInterrupt() Log: Autopausing read\n"); #endif // AddIrqQueue(AUTOPAUSE, 0x800); AddIrqQueue(CdlPause, 0x800); } else { ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); } psxHu32ref(0x1070)|= SWAP32((u32)0x4); psxRegs.interrupt|= 0x80000000; }
void cdrInterrupt() { int i; unsigned char Irq = cdr.Irq; if (cdr.Stat) { CDR_INT(0x800); return; } cdr.Irq = 0xff; cdr.Ctrl&=~0x80; switch (Irq) { case CdlSync: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlNop: SetResultSize(1); cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; i = stat.Status; if (CDR_getStatus(&stat) != -1) { if (stat.Type == 0xff) cdr.Stat = DiskError; if (stat.Status & 0x10) { cdr.Stat = DiskError; cdr.Result[0]|= 0x11; cdr.Result[0]&=~0x02; } else if (i & 0x10) { cdr.StatP |= 0x2; cdr.Result[0]|= 0x2; CheckCdrom(); } } break; case CdlSetloc: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlPlay: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; cdr.StatP|= 0x80; // if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime); break; case CdlForward: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlBackward: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlStandby: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlStop: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP&=~0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; // cdr.Stat = Acknowledge; break; case CdlPause: SetResultSize(1); cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlPause + 0x20, 0x800); cdr.Ctrl|= 0x80; break; case CdlPause + 0x20: SetResultSize(1); cdr.StatP&=~0x20; cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlInit: SetResultSize(1); cdr.StatP = 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; // if (!cdr.Init) { AddIrqQueue(CdlInit + 0x20, 0x800); // } break; case CdlInit + 0x20: SetResultSize(1); cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; cdr.Init = 1; break; case CdlMute: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlDemute: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlSetfilter: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlSetmode: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlGetmode: SetResultSize(6); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Result[1] = cdr.Mode; cdr.Result[2] = cdr.File; cdr.Result[3] = cdr.Channel; cdr.Result[4] = 0; cdr.Result[5] = 0; cdr.Stat = Acknowledge; break; case CdlGetlocL: SetResultSize(8); // for (i=0; i<8; i++) cdr.Result[i] = itob(cdr.Transfer[i]); for (i=0; i<8; i++) cdr.Result[i] = cdr.Transfer[i]; cdr.Stat = Acknowledge; break; case CdlGetlocP: SetResultSize(8); subq = (struct SubQ*) CDR_getBufferSub(); if (subq != NULL) { cdr.Result[0] = subq->TrackNumber; cdr.Result[1] = subq->IndexNumber; memcpy(cdr.Result+2, subq->TrackRelativeAddress, 3); memcpy(cdr.Result+5, subq->AbsoluteAddress, 3); } else { cdr.Result[0] = 1; cdr.Result[1] = 1; cdr.Result[2] = cdr.Prev[0]; cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2); cdr.Result[4] = cdr.Prev[2]; memcpy(cdr.Result+5, cdr.Prev, 3); } cdr.Stat = Acknowledge; break; case CdlGetTN: cdr.CmdProcess = 0; SetResultSize(3); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; if (CDR_getTN(cdr.ResultTN) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { cdr.Stat = Acknowledge; cdr.Result[1] = itob(cdr.ResultTN[0]); cdr.Result[2] = itob(cdr.ResultTN[1]); } break; case CdlGetTD: cdr.CmdProcess = 0; cdr.Track = btoi(cdr.Param[0]); SetResultSize(4); cdr.StatP|= 0x2; if (CDR_getTD(cdr.Track, cdr.ResultTD) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { cdr.Stat = Acknowledge; cdr.Result[0] = cdr.StatP; cdr.Result[1] = itob(cdr.ResultTD[2]); cdr.Result[2] = itob(cdr.ResultTD[1]); cdr.Result[3] = itob(cdr.ResultTD[0]); } break; case CdlSeekL: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.StatP|= 0x40; cdr.Stat = Acknowledge; cdr.Seeked = 1; AddIrqQueue(CdlSeekL + 0x20, 0x800); break; case CdlSeekL + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.StatP&=~0x40; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlSeekP: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.StatP|= 0x40; cdr.Stat = Acknowledge; AddIrqQueue(CdlSeekP + 0x20, 0x800); break; case CdlSeekP + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.StatP&=~0x40; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlTest: cdr.Stat = Acknowledge; switch (cdr.Param[0]) { case 0x20: // System Controller ROM Version SetResultSize(4); memcpy(cdr.Result, Test20, 4); break; case 0x22: SetResultSize(8); memcpy(cdr.Result, Test22, 4); break; case 0x23: case 0x24: SetResultSize(8); memcpy(cdr.Result, Test23, 4); break; } break; case CdlID: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlID + 0x20, 0x800); break; case CdlID + 0x20: SetResultSize(8); if (CDR_getStatus(&stat) == -1) { cdr.Result[0] = 0x00; // 0x00 Game CD cdr.Result[1] = 0x00; // 0x00 loads CD } else { if (stat.Type == 2) { cdr.Result[0] = 0x08; // 0x08 audio cd cdr.Result[1] = 0x10; // 0x10 enter cd player } else { cdr.Result[0] = 0x00; // 0x00 game CD cdr.Result[1] = 0x00; // 0x00 loads CD } } if (!LoadCdBios) cdr.Result[1] |= 0x80; //0x80 leads to the menu in the bios cdr.Result[2] = 0x00; cdr.Result[3] = 0x00; // strncpy((char *)&cdr.Result[4], "PCSX", 4); #ifdef HW_RVL strncpy((char *)&cdr.Result[4], "WSX ", 4); #else strncpy((char *)&cdr.Result[4], "GCSX", 4); #endif cdr.Stat = Complete; break; case CdlReset: SetResultSize(1); cdr.StatP = 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlReadToc: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlReadToc + 0x20, 0x800); break; case CdlReadToc + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case AUTOPAUSE: cdr.OCUP = 0; /* SetResultSize(1); StopCdda(); StopReading(); cdr.OCUP = 0; cdr.StatP&=~0x20; cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = DataEnd; */ AddIrqQueue(CdlPause, 0x400); break; case READ_ACK: if (!cdr.Reading) return; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; if (cdr.Seeked == 0) { cdr.Seeked = 1; cdr.StatP|= 0x40; } cdr.StatP|= 0x20; cdr.Stat = Acknowledge; ReadTrack(); // CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); CDREAD_INT(0x40000); break; case REPPLAY_ACK: cdr.Stat = Acknowledge; cdr.Result[0] = cdr.StatP; SetResultSize(1); AddIrqQueue(REPPLAY, cdReadTime); break; case REPPLAY: if ((cdr.Mode & 5) != 5) break; /* if (CDR_getStatus(&stat) == -1) { cdr.Result[0] = 0; cdr.Result[1] = 0; cdr.Result[2] = 0; cdr.Result[3] = 0; cdr.Result[4] = 0; cdr.Result[5] = 0; cdr.Result[6] = 0; cdr.Result[7] = 0; } else memcpy(cdr.Result, &stat.Track, 8); cdr.Stat = 1; SetResultSize(8); AddIrqQueue(REPPLAY_ACK, cdReadTime); */ break; case 0xff: return; default: cdr.Stat = Complete; break; } if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) { psxHu32ref(0x1070)|= SWAP32((u32)0x4); psxRegs.interrupt|= 0x80000000; } #ifdef CDR_LOG CDR_LOG("cdrInterrupt() Log: CDR Interrupt IRQ %x\n", Irq); #endif }
//senquack - A generic function SPU plugins can use to acknowledge SPU interrupts: void CALLBACK AcknowledgeSPUIRQ(void) { psxHu32ref(0x1070) |= SWAPu32(0x200); }
static inline void setIrq( u32 irq ) { psxHu32ref(0x1070) |= SWAPu32(irq); }
static void io_write_imask32(u32 value) { psxHu32ref(0x1074) = value; if (psxHu32ref(0x1070) & value) new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1); }
static void io_write_ireg32(u32 value) { if (Config.Sio) psxHu32ref(0x1070) |= 0x80; if (Config.SpuIrq) psxHu32ref(0x1070) |= 0x200; psxHu32ref(0x1070) &= psxHu32(0x1074) & value; }
static void setIrq(void) { if (cdr.Stat & cdr.Reg2) psxHu32ref(0x1070) |= SWAP32((u32)0x4); }
void CALLBACK SIO1irq(void) { psxHu32ref(0x1070) |= SWAPu32(0x100); }
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; }
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(); }