From 47d9ba5c7ad7a06c36f8af26cbbc6cfae6bf0bc2 Mon Sep 17 00:00:00 2001 From: gigaherz Date: Sat, 23 Jan 2010 04:00:55 +0000 Subject: [PATCH] Made the new iop dma use the hardware registers for MADR/BCR/CHCR, which lets the memcards and pads work, at least in the bios. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2488 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/IopDma.cpp | 64 +++++++++++++++++++++--------------- pcsx2/IopDma.h | 23 +++++++------ pcsx2/IopHw.h | 7 ++-- pcsx2/ps2/Iop/IopHwWrite.cpp | 8 ++--- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/pcsx2/IopDma.cpp b/pcsx2/IopDma.cpp index f7b959d416..ca906068da 100644 --- a/pcsx2/IopDma.cpp +++ b/pcsx2/IopDma.cpp @@ -305,26 +305,38 @@ extern void sio2DmaInterrupt(s32 channel); s32 errDmaWrite(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed); s32 errDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed); -DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; // I dont' knwo how many there are, 10? +//DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; + +#define MEM_BASE1 0x1f801080 +#define MEM_BASE2 0x1f801500 + +#define CHANNEL_BASE1(ch) (MEM_BASE1 + ((ch)<<4)) +#define CHANNEL_BASE2(ch) (MEM_BASE1 + ((ch)<<4)) + + +u32& DmaHandlerInfo::REG_MADR(void) { return psxHu32(DmacRegisterBase + 0x0); } +u32& DmaHandlerInfo::REG_BCR(void) { return psxHu32(DmacRegisterBase + 0x4); } +u32& DmaHandlerInfo::REG_CHCR(void) { return psxHu32(DmacRegisterBase + 0xC); } + DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] = { // First DMAC, same as PS1 - {"Ps1 Mdec", 0}, //0 - {"Ps1 Mdec", 0}, //1 - {"Ps1 Gpu", 0}, //2 - {"CDVD", cdvdDmaRead, errDmaWrite, cdvdDmaInterrupt}, //3: CDVD - {"SPU2 Core0", spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //4: Spu Core0 - {"?", 0}, //5 - {"OT", 0}, //6: OT? + {"Ps1 Mdec", CHANNEL_BASE1(0), 0}, //0 + {"Ps1 Mdec", CHANNEL_BASE1(1), 0}, //1 + {"Ps1 Gpu", CHANNEL_BASE1(2), 0}, //2 + {"CDVD", CHANNEL_BASE1(3), cdvdDmaRead, errDmaWrite, cdvdDmaInterrupt}, //3: CDVD + {"SPU2 Core0", CHANNEL_BASE1(4), spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //4: Spu Core0 + {"?", CHANNEL_BASE1(5), 0}, //5 + {"OT", CHANNEL_BASE1(6), 0}, //6: OT? // Second DMAC, new in PS2 IOP - {"SPU2 Core1", spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //7: Spu Core1 - {"Dev9", 0},//dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9 - {"Sif0", 0},//sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0 - {"Sif1", 0},//sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1 - {"Sio2 (writes)", errDmaRead, sio2DmaWrite, sio2DmaInterrupt}, //11: Sio2 - {"Sio2 (reads)", sio2DmaRead, errDmaWrite, sio2DmaInterrupt}, //12: Sio2 + {"SPU2 Core1", CHANNEL_BASE2(0), spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //7: Spu Core1 + {"Dev9", CHANNEL_BASE2(1), 0},//dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9 + {"Sif0", CHANNEL_BASE2(2), 0},//sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0 + {"Sif1", CHANNEL_BASE2(3), 0},//sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1 + {"Sio2 (writes)", CHANNEL_BASE2(4), errDmaRead, sio2DmaWrite, sio2DmaInterrupt}, //11: Sio2 + {"Sio2 (reads)", CHANNEL_BASE2(5), sio2DmaRead, errDmaWrite, sio2DmaInterrupt}, //12: Sio2 {"?", 0}, //13 // if each dmac has 7 channels, the list would end here, but i made it 16 cos I'm not sure :p {"?", 0}, //14 @@ -347,15 +359,15 @@ void RaiseDmaIrq(u32 channel) psxDmaInterrupt2(channel-7); } -void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr) +void IopDmaStart(int channel) { // I dont' really understand this, but it's used above. Is this BYTES OR WHAT? + int bcr = IopDmaHandlers[channel].REG_BCR(); int size = 4* (bcr >> 16) * (bcr & 0xFFFF); - IopChannels[channel].Control = chcr | DMA_CTRL_ACTIVE; - IopChannels[channel].MemAddr = madr; - IopChannels[channel].ByteCount = size; - IopChannels[channel].Target=0; + IopDmaHandlers[channel].REG_CHCR() |= DMA_CTRL_ACTIVE; + IopDmaHandlers[channel].ByteCount = size; + IopDmaHandlers[channel].Target=0; //SetDmaUpdateTarget(1); { @@ -379,9 +391,9 @@ void IopDmaUpdate(u32 elapsed) for (int i = 0;i < DMA_CHANNEL_MAX;i++) { - DmaStatusInfo *ch = IopChannels + i; + DmaHandlerInfo *ch = IopDmaHandlers + i; - if (ch->Control&DMA_CTRL_ACTIVE) + if (ch->REG_CHCR()&DMA_CTRL_ACTIVE) { ch->Target -= elapsed; if (ch->Target <= 0) @@ -390,20 +402,20 @@ void IopDmaUpdate(u32 elapsed) { ch->Target = 0x7fffffff; - ch->Control &= ~DMA_CTRL_ACTIVE; + ch->REG_CHCR() &= ~DMA_CTRL_ACTIVE; RaiseDmaIrq(i); IopDmaHandlers[i].Interrupt(i); } else { - DmaHandler handler = (ch->Control & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Write : IopDmaHandlers[i].Read; + DmaHandler handler = (ch->REG_CHCR() & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Write : IopDmaHandlers[i].Read; u32 BCount = 0; - s32 Target = (handler) ? handler(i, (u32*)iopPhysMem(ch->MemAddr), ch->ByteCount, &BCount) : 0; + s32 Target = (handler) ? handler(i, (u32*)iopPhysMem(ch->REG_MADR()), ch->ByteCount, &BCount) : 0; if(BCount>0) { - psxCpu->Clear(ch->MemAddr, BCount/4); + psxCpu->Clear(ch->REG_MADR(), BCount/4); } int TTarget = 100; @@ -413,7 +425,7 @@ void IopDmaUpdate(u32 elapsed) } else if (BCount > 0) { - ch->MemAddr += BCount; + ch->REG_MADR()+= BCount; ch->ByteCount -= BCount; TTarget = BCount/4; // / ch->Width; diff --git a/pcsx2/IopDma.h b/pcsx2/IopDma.h index 9994f5efe5..a2acabe18f 100644 --- a/pcsx2/IopDma.h +++ b/pcsx2/IopDma.h @@ -25,21 +25,22 @@ typedef s32(* DmaHandler)(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed); typedef void (* DmaIHandler)(s32 channel); -struct DmaHandlerInfo +class DmaHandlerInfo { +public: const char* Name; + u32 DmacRegisterBase; DmaHandler Read; DmaHandler Write; DmaIHandler Interrupt; -}; -struct DmaStatusInfo -{ - u32 Control; - u32 Width; // bytes/word, for timing purposes - u32 MemAddr; - s32 ByteCount; - s32 Target; + // runtime variables + u32 ByteCount; + u32 Target; + + u32& REG_MADR(void); + u32& REG_BCR(void); + u32& REG_CHCR(void); }; // FIXME: Dummy constants, to be "filled in" with proper values later @@ -48,9 +49,7 @@ struct DmaStatusInfo #define DMA_CHANNEL_MAX 16 /* ? */ -extern DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; - -extern void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr); +extern void IopDmaStart(int channel); extern void IopDmaUpdate(u32 elapsed); // external dma handlers diff --git a/pcsx2/IopHw.h b/pcsx2/IopHw.h index 04b4a8f983..f44ed90bf0 100644 --- a/pcsx2/IopHw.h +++ b/pcsx2/IopHw.h @@ -193,19 +193,16 @@ enum IOPCountRegs #define DmaExecNew(n) { \ if (HW_DMA##n##_CHCR & 0x01000000 && \ HW_DMA_PCR & (8 << (n * 4))) { \ - IopDmaStart(n, HW_DMA##n##_CHCR, HW_DMA##n##_MADR, HW_DMA##n##_BCR); \ + IopDmaStart(n); \ } \ } #define DmaExecNew2(n) { \ if (HW_DMA##n##_CHCR & 0x01000000 && \ HW_DMA_PCR2 & (8 << ((n-7) * 4))) { \ - IopDmaStart(n, HW_DMA##n##_CHCR, HW_DMA##n##_MADR, HW_DMA##n##_BCR); \ + IopDmaStart(n); \ } \ } -#else -#define DmaExecNew(n) DmaExec(n) -#define DmaExecNew2(n) DmaExec2(n) #endif #define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA diff --git a/pcsx2/ps2/Iop/IopHwWrite.cpp b/pcsx2/ps2/Iop/IopHwWrite.cpp index 2ed26233bd..c68575c026 100644 --- a/pcsx2/ps2/Iop/IopHwWrite.cpp +++ b/pcsx2/ps2/Iop/IopHwWrite.cpp @@ -321,18 +321,14 @@ static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val ) // as asinine as that may seem). // mcase(0x1f8010C0): -#ifdef ENABLE_NEW_IOPDMA_SPU2 - IopChannels[4].MemAddr = val; -#else +#ifndef ENABLE_NEW_IOPDMA_SPU2 SPU2WriteMemAddr( 0, val ); #endif HW_DMA4_MADR = val; break; mcase(0x1f801500): -#ifdef ENABLE_NEW_IOPDMA_SPU2 - IopChannels[7].MemAddr = val; -#else +#ifndef ENABLE_NEW_IOPDMA_SPU2 SPU2WriteMemAddr( 1, val ); #endif HW_DMA7_MADR = val;