mirror of https://github.com/PCSX2/pcsx2.git
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
This commit is contained in:
parent
fa5ba9fc29
commit
47d9ba5c7a
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue