diff options
| author | SND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-10-07 18:52:18 +0000 |
|---|---|---|
| committer | SND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-10-07 18:52:18 +0000 |
| commit | 1a8ed308f320fac97b8c3dbc549b92c5b1d0c642 (patch) | |
| tree | 64537f08f78d4ea0c18a0ae133cdf92f0bdd4189 | |
| parent | aac9f1d0588286845f627cf2e564f1ec850d8505 (diff) | |
| download | pcsxr-1a8ed308f320fac97b8c3dbc549b92c5b1d0c642.tar.gz | |
Wild 9: cdrom, r3000a, dma
- give Repplay its own interrupt handler
- add DMA3 busy times
- fixes music
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@58184 e17a0e51-4ae3-4d35-97c3-1a29b211df97
| -rw-r--r-- | libpcsxcore/cdrom.c | 185 | ||||
| -rw-r--r-- | libpcsxcore/cdrom.h | 1 | ||||
| -rw-r--r-- | libpcsxcore/psxdma.h | 7 | ||||
| -rw-r--r-- | libpcsxcore/r3000a.c | 14 | ||||
| -rw-r--r-- | libpcsxcore/r3000a.h | 4 |
5 files changed, 136 insertions, 75 deletions
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index f5602af0..c81097b5 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -103,6 +103,12 @@ static struct SubQ *subq; psxRegs.intCycle[PSXINT_CDREAD].sCycle = psxRegs.cycle; \ } +#define CDREPPLAY_INT(eCycle) { \
+ psxRegs.interrupt |= (1 << PSXINT_CDREPPLAY); \
+ psxRegs.intCycle[PSXINT_CDREPPLAY].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_CDREPPLAY].sCycle = psxRegs.cycle; \
+}
+
#define StartReading(type, eCycle) { \ cdr.Reading = type; \ cdr.FirstSector = 1; \ @@ -193,6 +199,94 @@ void AddIrqQueue(unsigned char irq, unsigned long ecycle) { } } +void cdrRepplayInterrupt()
+{
+ // Wait for IRQ to be acknowledged
+ if (cdr.Stat) {
+ CDREAD_INT(0x1000);
+ return;
+ }
+
+#ifdef CDR_LOG
+ CDR_LOG("cdrRepplayInterrupt() Log: KEY END\n");
+#endif
+
+ if ((cdr.Mode & 5) != 5) return;
+
+ memset( cdr.Result, 0, 8 );
+ if( CDR_getStatus(&stat) != -1) {
+ // BIOS - HACK: Switch between local / absolute times
+ static u8 report_time = 1;
+
+
+ subq = (struct SubQ *)CDR_getBufferSub();
+
+ if (subq != NULL ) {
+#ifdef CDR_LOG
+ CDR_LOG( "REPPLAY IRQ - %X:%X:%X\n",
+ subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] );
+#endif
+
+
+ /*
+ skip subQ integrity check (audio playback)
+ - mainly useful for DATA LibCrypt checking
+ */
+ //if( SWAP16(subq->CRC) != calcCrc((unsigned char *)subq + 12, 10) )
+
+ cdr.Result[0] = cdr.StatP;
+
+
+ // Rayman: audio pregap flag / track change
+ // - not all CDs will use PREGAPs, so we track it manually
+ if( cdr.CurTrack < btoi( subq->TrackNumber ) ) {
+ cdr.Result[0] |= 0x10;
+
+ cdr.CurTrack = btoi( subq->TrackNumber );
+ }
+
+
+ // BIOS CD Player: data already BCD format
+ cdr.Result[1] = subq->TrackNumber;
+ cdr.Result[2] = subq->IndexNumber;
+
+
+ // BIOS CD Player: switch between local / absolute times
+ if( report_time == 0 ) {
+ cdr.Result[3] = subq->AbsoluteAddress[0];
+ cdr.Result[4] = subq->AbsoluteAddress[1];
+ cdr.Result[5] = subq->AbsoluteAddress[2];
+
+ report_time = 1;
+ }
+ else {
+ cdr.Result[3] = subq->TrackRelativeAddress[0];
+ cdr.Result[4] = subq->TrackRelativeAddress[1];
+ cdr.Result[5] = subq->TrackRelativeAddress[2];
+
+ cdr.Result[4] |= 0x80;
+
+ report_time = 0;
+ }
+ }
+ }
+
+ // Rayman: Logo freeze
+ cdr.ResultReady = 1;
+
+ cdr.Stat = DataReady;
+ SetResultSize(8);
+
+
+ // Wild 9: Do not use REPPLAY_ACK
+ // - must use faster times for reporting
+ CDREPPLAY_INT(cdReadTime / 2);
+
+
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+ psxRegs.interrupt |= 0x80000000;
+}
+
void cdrInterrupt() { int i; unsigned char Irq = cdr.Irq; @@ -235,7 +329,11 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; cdr.StatP |= 0x80; - if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime); +
+ // Lemmings: report play times
+ if ((cdr.Mode & 0x5) == 0x5) {
+ CDREPPLAY_INT( cdReadTime );
+ }
break; case CdlForward: @@ -620,7 +718,7 @@ void cdrInterrupt() { cdr.Stat = DataEnd; */ AddIrqQueue(CdlPause, 0x800); break; - +
case READ_ACK: if (!cdr.Reading) return; @@ -638,76 +736,6 @@ void cdrInterrupt() { CDREAD_INT(0x80000); 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;
-
- memset( cdr.Result, 0, 8 );
- if( CDR_getStatus(&stat) != -1) {
- // HACK: Switch between local / absolute times
- static u8 report_time = 1;
-
-
- subq = (struct SubQ *)CDR_getBufferSub();
-
- if (subq != NULL ) {
- /*
- skip subQ integrity check (audio playback)
- mainly useful for DATA LibCrypt checking
- */
- //if( SWAP16(subq->CRC) != calcCrc((unsigned char *)subq + 12, 10) )
-
- cdr.Result[0] = cdr.StatP;
-
-
- // Rayman: audio pregap flag / track change
- // - not all CDs will use PREGAPs, so we track it manually
- if( cdr.CurTrack < btoi( subq->TrackNumber ) ) {
- cdr.Result[0] |= 0x10;
-
- cdr.CurTrack = btoi( subq->TrackNumber );
- }
-
-
- // BIOS CD Player: data already BCD format
- cdr.Result[1] = subq->TrackNumber;
- cdr.Result[2] = subq->IndexNumber;
-
-
- // BIOS CD Player: switch between local / absolute times
- if( report_time == 0 ) {
- cdr.Result[3] = subq->AbsoluteAddress[0];
- cdr.Result[4] = subq->AbsoluteAddress[1];
- cdr.Result[5] = subq->AbsoluteAddress[2];
-
- report_time = 1;
- }
- else {
- cdr.Result[3] = subq->TrackRelativeAddress[0];
- cdr.Result[4] = subq->TrackRelativeAddress[1];
- cdr.Result[5] = subq->TrackRelativeAddress[2];
-
- cdr.Result[4] |= 0x80;
-
- report_time = 0;
- }
- }
- }
-
- // Rayman: Logo freeze
- cdr.ResultReady = 1;
-
- cdr.Stat = 1;
- SetResultSize(8);
- AddIrqQueue(REPPLAY_ACK, cdReadTime);
- break;
- case 0xff: return; @@ -1439,8 +1467,11 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { } psxCpu->Clear(madr, cdsize / 4); - cdr.pTransfer += cdsize; - break; + cdr.pTransfer += cdsize;
+ + CDRDMA_INT( cdsize / 4 );
+ return;
+
default: #ifdef CDR_LOG CDR_LOG("psxDma3() Log: Unknown cddma %x\n", chcr); @@ -1452,6 +1483,12 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { DMA_INTERRUPT(3); } +void cdrDmaInterrupt()
+{
+ HW_DMA3_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(3);
+}
+
void cdrReset() { memset(&cdr, 0, sizeof(cdr)); cdr.CurTrack = 1; diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h index 1ce1f5f2..44b3a830 100644 --- a/libpcsxcore/cdrom.h +++ b/libpcsxcore/cdrom.h @@ -99,6 +99,7 @@ extern cdrStruct cdr; void cdrReset(); void cdrInterrupt(); void cdrReadInterrupt(); +void cdrRepplayInterrupt();
unsigned char cdrRead0(void); unsigned char cdrRead1(void); unsigned char cdrRead2(void); diff --git a/libpcsxcore/psxdma.h b/libpcsxcore/psxdma.h index d356995d..63618ada 100644 --- a/libpcsxcore/psxdma.h +++ b/libpcsxcore/psxdma.h @@ -59,6 +59,12 @@ extern "C" { psxRegs.intCycle[PSXINT_GPUOTCDMA].sCycle = psxRegs.cycle; \
}
+#define CDRDMA_INT(eCycle) { \
+ psxRegs.interrupt |= (1 << PSXINT_CDRDMA); \
+ psxRegs.intCycle[PSXINT_CDRDMA].cycle = eCycle; \
+ psxRegs.intCycle[PSXINT_CDRDMA].sCycle = psxRegs.cycle; \
+}
+
/*
DMA5 = N/A (PIO)
*/
@@ -69,6 +75,7 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr); void spuInterrupt(); void mdec0Interrupt();
void gpuotcInterrupt();
+void cdrDmaInterrupt();
#ifdef __cplusplus } diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index c6efc6f9..39bf7e78 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -186,6 +186,20 @@ void psxBranchTest() { 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_CDREPPLAY)) { // cdr report play
+ if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_CDREPPLAY].sCycle) >= psxRegs.intCycle[PSXINT_CDREPPLAY].cycle) {
+ psxRegs.interrupt &= ~(1 << PSXINT_CDREPPLAY);
+ cdrRepplayInterrupt();
+ }
+ }
} } diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 19363afe..4c6946e1 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -153,7 +153,9 @@ enum { PSXINT_SPUDMA, PSXINT_GPUBUSY, PSXINT_MDECINDMA, - PSXINT_GPUOTCDMA + PSXINT_GPUOTCDMA,
+ PSXINT_CDRDMA,
+ PSXINT_CDREPPLAY
}; typedef struct { |
