summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-10-07 18:52:18 +0000
committerSND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-10-07 18:52:18 +0000
commit1a8ed308f320fac97b8c3dbc549b92c5b1d0c642 (patch)
tree64537f08f78d4ea0c18a0ae133cdf92f0bdd4189
parentaac9f1d0588286845f627cf2e564f1ec850d8505 (diff)
downloadpcsxr-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.c185
-rw-r--r--libpcsxcore/cdrom.h1
-rw-r--r--libpcsxcore/psxdma.h7
-rw-r--r--libpcsxcore/r3000a.c14
-rw-r--r--libpcsxcore/r3000a.h4
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 {