__fi bool WriteFifoSingleWord() { // There's some data ready to transfer into the fifo.. SIF_LOG("Write Single word to SIF2 Fifo"); sif2.fifo.write((u32*)&psxHu32(HW_PS1_GPU_DATA), 1); if (sif2.fifo.size > 0) psxHu32(0x1000f300) &= ~0x4000000; return true; }
void psxBranchTest() { if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter) psxRcntUpdate(); if (psxHu32(0x1070) & psxHu32(0x1074)) { if ((psxRegs.CP0.n.Status & 0x401) == 0x401) { psxException(0x400, 0); } } }
void psxHwWrite32(u32 add, u32 value) { switch (add) { case 0x1f801070: psxHu32(0x1070) &= BFLIP32(BFLIP32(psxHu32(0x1074)) & value); return; case 0x1f8010c8: HW_DMA4_CHCR = BFLIP32(value); // DMA4 chcr (SPU DMA) DmaExec(4); return; case 0x1f8010f4: { u32 tmp = (~value) & BFLIP32(HW_DMA_ICR); HW_DMA_ICR = BFLIP32(((tmp ^ value) & 0xffffff) ^ tmp); return; } case 0x1f801100: psxRcntWcount(0, value & 0xffff); return; case 0x1f801104: psxRcntWmode(0, value); return; case 0x1f801108: psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= (~value)&0xff000000; case 0x1f801110: psxRcntWcount(1, value & 0xffff); return; case 0x1f801114: psxRcntWmode(1, value); return; case 0x1f801118: psxRcntWtarget(1, value & 0xffff); return; case 0x1f801120: psxRcntWcount(2, value & 0xffff); return; case 0x1f801124: psxRcntWmode(2, value); return; case 0x1f801128: psxRcntWtarget(2, value & 0xffff); return; default: psxHu32(add) = BFLIP32(value); return; } psxHu32(add) = BFLIP32(value); }
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 psxRcntUpdate() { if ((upse_r3000_cpu_regs.cycle - psxCounters[3].sCycle) >= psxCounters[3].Cycle) { //printf("%d\n",(upse_r3000_cpu_regs.cycle - psxCounters[3].sCycle)- psxCounters[3].Cycle); psxRcntUpd(3); psxHu32(0x1070) |= BFLIP32(1); } if ((upse_r3000_cpu_regs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) { psxRcntReset(0); } if ((upse_r3000_cpu_regs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) { psxRcntReset(1); } if ((upse_r3000_cpu_regs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) { psxRcntReset(2); } psxRcntSet(); }
void psxRcntUpdate(upse_module_instance_t *ins) { upse_psx_counter_state_t *ctrstate = ins->ctrstate; if ((ins->cpustate.cycle - ctrstate->psxCounters[3].sCycle) >= ctrstate->psxCounters[3].Cycle) { psxRcntUpd(ins, 3); psxHu32(ins, 0x1070) |= BFLIP32(1); } if ((ins->cpustate.cycle - ctrstate->psxCounters[0].sCycle) >= ctrstate->psxCounters[0].Cycle) { psxRcntReset(ins, 0); } if ((ins->cpustate.cycle - ctrstate->psxCounters[1].sCycle) >= ctrstate->psxCounters[1].Cycle) { psxRcntReset(ins, 1); } if ((ins->cpustate.cycle - ctrstate->psxCounters[2].sCycle) >= ctrstate->psxCounters[2].Cycle) { psxRcntReset(ins, 2); } psxRcntSet(ins); }
static void __fastcall _rcntTestTarget( int i ) { if( psxCounters[i].count < psxCounters[i].target ) return; PSXCNT_LOG("IOP Counter[%d] target 0x%I64x >= 0x%I64x (mode: %x)\n", i, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode); if (psxCounters[i].mode & IOPCNT_INT_TARGET) { // Target interrupt if(psxCounters[i].mode & 0x80) psxCounters[i].mode &= ~0x0400; // Interrupt flag psxCounters[i].mode |= 0x0800; // Target flag psxHu32(0x1070) |= psxCounters[i].interrupt; } if (psxCounters[i].mode & 0x08) { // Reset on target psxCounters[i].count -= psxCounters[i].target; if(!(psxCounters[i].mode & 0x40)) { SysPrintf("Counter %x repeat intr not set on zero ret, ignoring target\n", i); psxCounters[i].target |= IOPCNT_FUTURE_TARGET; } } else psxCounters[i].target |= IOPCNT_FUTURE_TARGET; }
static __forceinline void _rcntTestOverflow( int i ) { u64 maxTarget = ( i < 3 ) ? 0xffff : 0xfffffffful; if( psxCounters[i].count <= maxTarget ) return; PSXCNT_LOG("IOP Counter[%d] overflow 0x%I64x >= 0x%I64x (mode: %x)\n", i, psxCounters[i].count, maxTarget, psxCounters[i].mode ); if(psxCounters[i].mode & IOPCNT_INT_OVERFLOW) { // Overflow interrupt psxHu32(0x1070) |= psxCounters[i].interrupt; psxCounters[i].mode |= 0x1000; // Overflow flag if(psxCounters[i].mode & 0x80) psxCounters[i].mode &= ~0x0400; // Interrupt flag } // Update count and target. // Count wraps around back to zero, while the target is restored (if needed). // (high bit of the target gets set by rcntWtarget when the target is behind // the counter value, and thus should not be flagged until after an overflow) psxCounters[i].count &= maxTarget; psxCounters[i].target &= maxTarget; }
void psxVBlankStart() { cdvdVsync(); psxHu32(0x1070) |= 1; if(psxvblankgate & (1 << 1)) psxCheckStartGate16(1); if(psxvblankgate & (1 << 3)) psxCheckStartGate32(3); }
static bool __fastcall _rcntFireInterrupt(int i, bool isOverflow) { bool ret; if ((psxCounters[i].mode & 0x400)) { //IRQ fired //DevCon.Warning("Counter %d %s IRQ Fired count %x", i, isOverflow ? "Overflow" : "Target", psxCounters[i].count); psxHu32(0x1070) |= psxCounters[i].interrupt; iopTestIntc(); ret = true; } else { //DevCon.Warning("Counter %d IRQ not fired count %x", i, psxCounters[i].count); ret = false; if (!(psxCounters[i].mode & 0x40)) //One shot { Console.WriteLn("Counter %x repeat intr not set on zero ret, ignoring target", i); return ret; } } if (psxCounters[i].mode & 0x80) { //Toggle mode psxCounters[i].mode ^= 0x400; // Interrupt flag inverted } else { psxCounters[i].mode &= ~0x0400; // Interrupt flag set low } return ret; }
static void psxRcntReset(u32 index) { psxCounters[index].count = 0; psxRcntUpd(index); psxHu32(0x1070)|= BFLIP32(psxCounters[index].interrupt); if (!(psxCounters[index].mode & 0x40)) { // Only 1 interrupt psxCounters[index].Cycle = 0xffffffff; } }
static void psxRcntReset(upse_module_instance_t *ins, u32 index) { upse_psx_counter_state_t *ctrstate = ins->ctrstate; ctrstate->psxCounters[index].count = 0; psxRcntUpd(ins, index); psxHu32(ins, 0x1070) |= BFLIP32(ctrstate->psxCounters[index].interrupt); if (!(ctrstate->psxCounters[index].mode & 0x40)) { // Only 1 interrupt ctrstate->psxCounters[index].Cycle = 0xffffffff; } }
__fi bool ReadFifoSingleWord() { u32 ptag[4]; //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif2dma.madr); SIF_LOG("Read Fifo SIF2 Single Word IOP Busy %x Fifo Size %x SIF2 CHCR %x", sif2.iop.busy, sif2.fifo.size, HW_DMA2_CHCR); sif2.fifo.read((u32*)&ptag[0], 1); psHu32(0x1000f3e0) = ptag[0]; if (sif2.fifo.size == 0) psxHu32(0x1000f300) |= 0x4000000; if (sif2.iop.busy && sif2.fifo.size <= 8)SIF2Dma(); return true; }
// Write IOP to Fifo. static __fi bool WriteIOPtoFifo() { // There's some data ready to transfer into the fifo.. const int writeSize = std::min(sif2.iop.counter, sif2.fifo.sif_free()); SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif2.iop.counter); sif2.fifo.write((u32*)iopPhysMem(hw_dma2.madr), writeSize); hw_dma2.madr += writeSize << 2; // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords). sif2.iop.cycles += (writeSize >> 2)/* * BIAS*/; // fixme : should be >> 4 sif2.iop.counter -= writeSize; //PSX_INT(IopEvt_SIF2, sif2.iop.cycles); if (sif2.iop.counter == 0) hw_dma2.madr = sif2data & 0xffffff; if (sif2.fifo.size > 0) psxHu32(0x1000f300) &= ~0x4000000; return true; }
static __forceinline T _HwRead_16or32_Page1( u32 addr ) { HwAddrPrep( 1 ); // all addresses should be aligned to the data operand size: jASSUME( ( sizeof(T) == 2 && (addr & 1) == 0 ) || ( sizeof(T) == 4 && (addr & 3) == 0 ) ); u32 masked_addr = pgmsk( addr ); T ret; // ------------------------------------------------------------------------ // Counters, 16-bit varieties! // // Note: word reads/writes to the uppoer halfword of the 16 bit registers should // just map to the HW memory map (tested on real IOP) -- ie, a write to the upper // halfword of 0xcccc will have those upper values return 0xcccc always. // if( masked_addr >= 0x100 && masked_addr < 0x130 ) { int cntidx = ( masked_addr >> 4 ) & 0xf; switch( masked_addr & 0xf ) { case 0x0: ret = (T)IopCounters::ReadCount16( cntidx ); break; case 0x4: ret = IopCounters::ReadMode( cntidx ); break; case 0x8: ret = (T)IopCounters::ReadTarget16( cntidx ); break; default: ret = psxHu32(addr); break; } }
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; } } }
u32 psxHwRead32(u32 add) { u32 hard; switch (add) { // time for rootcounters :) case 0x1f801100: hard = psxRcntRcount(0); return hard; case 0x1f801104: hard = psxCounters[0].mode; return hard; case 0x1f801108: hard = psxCounters[0].target; return hard; case 0x1f801110: hard = psxRcntRcount(1); return hard; case 0x1f801114: hard = psxCounters[1].mode; return hard; case 0x1f801118: hard = psxCounters[1].target; return hard; case 0x1f801120: hard = psxRcntRcount(2); return hard; case 0x1f801124: hard = psxCounters[2].mode; return hard; case 0x1f801128: hard = psxCounters[2].target; return hard; default: hard = BFLIP32(psxHu32(add)); return hard; } return hard; }
void sexySPUirq(void) { // TODO - check this ... // Is this 0x200 or 0x100 : 1 << 8 = 0x100 psxHu32(0x1070)|=BFLIP32(0x200); }
void psxVBlankEnd() { psxHu32(0x1070) |= 0x800; if(psxvblankgate & (1 << 1)) psxCheckEndGate16(1); if(psxvblankgate & (1 << 3)) psxCheckEndGate32(3); }
static void io_write_ireg32(u32 value) { if (Config.Sio) psxHu32ref(0x1070) |= 0x80; if (Config.SpuIrq) psxHu32ref(0x1070) |= 0x200; psxHu32ref(0x1070) &= psxHu32(0x1074) & value; }
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; }
void cdrInterrupt() { cdvdTD trackInfo; int i; u8 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; 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.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; cdr.StatP|= 0x82; 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); 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; 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] = cdr.Transfer[i]; cdr.Stat = Acknowledge; break; case CdlGetlocP: SetResultSize(8); 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]; cdr.Result[5] = cdr.Prev[0]; cdr.Result[6] = cdr.Prev[1]; cdr.Result[7] = cdr.Prev[2]; cdr.Stat = Acknowledge; break; case CdlGetTN: cdr.CmdProcess = 0; SetResultSize(3); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; if (CDVD->getTN(&cdr.ResultTN) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { cdr.Stat = Acknowledge; cdr.Result[1] = itob(cdr.ResultTN.strack); cdr.Result[2] = itob(cdr.ResultTN.etrack); } break; case CdlGetTD: cdr.CmdProcess = 0; cdr.Track = btoi(cdr.Param[0]); SetResultSize(4); cdr.StatP|= 0x2; if (CDVD->getTD(cdr.Track, &trackInfo) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { lsn_to_msf(cdr.ResultTD, trackInfo.lsn); cdr.Stat = Acknowledge; cdr.Result[0] = cdr.StatP; cdr.Result[1] = cdr.ResultTD[2]; cdr.Result[2] = cdr.ResultTD[1]; cdr.Result[3] = cdr.ResultTD[0]; } break; case CdlSeekL: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlSeekL + 0x20, 0x800); break; case CdlSeekL + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlSeekP: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlSeekP + 0x20, 0x800); break; case CdlSeekP + 0x20: SetResultSize(1); cdr.StatP|= 0x2; 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); *(int*)cdr.Result = *(int*)Test20; break; case 0x22: SetResultSize(8); *(int*)cdr.Result = *(int*)Test22; break; case 0x23: case 0x24: SetResultSize(8); *(int*)cdr.Result = *(int*)Test23; 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); cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD if (!LoadCdBios) cdr.Result[1] |= 0x80; cdr.Result[2] = 0x00; cdr.Result[3] = 0x00; strncpy((char *)&cdr.Result[4], "PCSX", 4); 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; AddIrqQueue(CdlPause, 0x400); break; case READ_ACK: if (!cdr.Reading) return; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); 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; break; case 0xff: return; default: cdr.Stat = Complete; break; } if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) psxHu32(0x1070)|= 0x4; CDVD_LOG("Cdr Interrupt %x\n", Irq); }
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 cdrReadInterrupt() { u8 *buf; if (!cdr.Reading) return; if (cdr.Stat) { CDREAD_INT(0x800); return; } CDR_LOG("KEY END"); cdr.OCUP = 1; SetResultSize(1); cdr.StatP|= 0x22; cdr.Result[0] = cdr.StatP; SysPrintf("Reading From CDR"); buf = CDVDgetBuffer(); if (buf == NULL) cdr.RErr = -1; if (cdr.RErr == -1) { CDR_LOG(" err\n"); memzero_ptr<2340>(cdr.Transfer); cdr.Stat = DiskError; cdr.Result[0]|= 0x01; ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; } memcpy_fast(cdr.Transfer, buf+12, 2340); cdr.Stat = DataReady; CDR_LOG(" %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); 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 CDR_LOG("AutoPausing Read\n"); AddIrqQueue(CdlPause, 0x800); } else { ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); } psxHu32(0x1070)|= 0x4; 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; }
void cdrReadInterrupt() { if (!cdr.Reading) return; if (cdr.Stat) { CDREAD_INT(0x800); return; } CDVD_LOG("KEY END"); cdr.OCUP = 1; SetResultSize(1); cdr.StatP|= 0x22; cdr.Result[0] = cdr.StatP; if( cdr.RErr == 0 ) { while( (cdr.RErr = DoCDVDgetBuffer(cdr.Transfer)), cdr.RErr == -2 ) { // not finished yet ... block on the read until it finishes. Threading::Sleep( 0 ); Threading::SpinWait(); } } if (cdr.RErr == -1) { CDVD_LOG(" err\n"); memzero(cdr.Transfer); cdr.Stat = DiskError; cdr.Result[0] |= 0x01; ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; } cdr.Stat = DataReady; CDVD_LOG(" %x:%x:%x", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); 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 CDVD_LOG("AutoPausing Read"); AddIrqQueue(CdlPause, 0x800); } else { ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); } psxHu32(0x1070)|= 0x4; return; }
void psxBranchTest() { if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter) psxRcntUpdate(); if (psxRegs.interrupt) { if ((psxRegs.interrupt & (1 << PSXINT_SIO)) && !Config.Sio) { // sio if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_SIO].sCycle) >= psxRegs.intCycle[PSXINT_SIO].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_SIO); sioInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_CDR)) { // cdr if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDR].sCycle) >= psxRegs.intCycle[PSXINT_CDR].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_CDR); cdrInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_CDREAD)) { // cdr read if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDREAD].sCycle) >= psxRegs.intCycle[PSXINT_CDREAD].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_CDREAD); cdrReadInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_GPUDMA)) { // gpu dma if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_GPUDMA].sCycle) >= psxRegs.intCycle[PSXINT_GPUDMA].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_GPUDMA); gpuInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_MDECOUTDMA)) { // mdec out dma if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle) >= psxRegs.intCycle[PSXINT_MDECOUTDMA].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_MDECOUTDMA); mdec1Interrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_SPUDMA)) { // spu dma if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_SPUDMA].sCycle) >= psxRegs.intCycle[PSXINT_SPUDMA].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_SPUDMA); spuInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_MDECINDMA)) { // mdec in if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_MDECINDMA].sCycle) >= psxRegs.intCycle[PSXINT_MDECINDMA].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_MDECINDMA); mdec0Interrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_GPUOTCDMA)) { // gpu otc if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_GPUOTCDMA].sCycle) >= psxRegs.intCycle[PSXINT_GPUOTCDMA].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_GPUOTCDMA); gpuotcInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_CDRDMA)) { // cdrom if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDRDMA].sCycle) >= psxRegs.intCycle[PSXINT_CDRDMA].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_CDRDMA); cdrDmaInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_CDRPLAY)) { // cdr play timing if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDRPLAY].sCycle) >= psxRegs.intCycle[PSXINT_CDRPLAY].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_CDRPLAY); cdrPlayInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_CDRDBUF)) { // cdr decoded buffer if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDRDBUF].sCycle) >= psxRegs.intCycle[PSXINT_CDRDBUF].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_CDRDBUF); cdrDecodedBufferInterrupt(); } } if (psxRegs.interrupt & (1 << PSXINT_CDRLID)) { // cdr lid states if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDRLID].sCycle) >= psxRegs.intCycle[PSXINT_CDRLID].cycle) { psxRegs.interrupt &= ~(1 << PSXINT_CDRLID); cdrLidSeekInterrupt(); } } } if (psxHu32(0x1070) & psxHu32(0x1074)) { if ((psxRegs.CP0.n.Status & 0x401) == 0x401) { #ifdef PSXCPU_LOG PSXCPU_LOG("Interrupt: %x %x\n", psxHu32(0x1070), psxHu32(0x1074)); #endif psxException(0x400, 0); } } }