mirror of https://github.com/PCSX2/pcsx2.git
So.. I got an "unlazy" day, and coded a bit more of my iop dma handler.
It's disabled in the code, so that it wont' affect normal users. The code isn't working properly yet. Only handlers for cdvd and spu2 are in it: - the cdvd one doesn't work because of the way pcsx2 handles cdvd currently - the spu2 one seems to work, but it's not implemented in the plugin interface, so ATM it's just "faking" it using the old functions. So really nothing worth testing, just commiting to let people know I'm actually working on it... with long pauses in between. xD git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1052 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
2ac355eb03
commit
e22a50a7c8
|
@ -937,6 +937,34 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
|
|||
psxDmaInterrupt(3);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
s32 cdvdDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed)
|
||||
{
|
||||
// hacked up from the code above
|
||||
|
||||
if (cdr.Readed == 0)
|
||||
{
|
||||
//CDR_LOG("*** DMA 3 *** NOT READY");
|
||||
wordsProcessed = 0;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
memcpy_fast(data, cdr.pTransfer, wordsLeft);
|
||||
//psxCpu->Clear(madr, cdsize/4);
|
||||
cdr.pTransfer+=wordsLeft;
|
||||
*wordsProcessed = wordsLeft;
|
||||
|
||||
Console::Status("New IOP DMA handled CDVD DMA: channel %d, data %p, remaining %08x, processed %08x.", params channel,data,wordsLeft, *wordsProcessed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cdvdDmaInterrupt(s32 channel)
|
||||
{
|
||||
cdrInterrupt();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void cdrReset() {
|
||||
memzero_obj(cdr);
|
||||
cdr.CurTrack=1;
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
#include "Sio.h"
|
||||
#include "Sif.h"
|
||||
|
||||
#include "IopDma.h"
|
||||
#include "IopMem.h"
|
||||
#include "IopHw.h"
|
||||
#include "IopBios.h"
|
||||
#include "IopDma.h"
|
||||
#include "IopCounters.h"
|
||||
#include "IopSio2.h"
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
#define PSXPIXEL ((int)(PSXCLK / 13500000))
|
||||
#define PSXSOUNDCLK ((int)(48000))
|
||||
|
||||
|
||||
psxCounter psxCounters[8];
|
||||
psxCounter psxCounters[NUM_COUNTERS];
|
||||
s32 psxNextCounter;
|
||||
u32 psxNextsCounter;
|
||||
u8 psxhblankgate = 0;
|
||||
|
@ -141,6 +140,12 @@ void psxRcntInit() {
|
|||
psxCounters[7].mode = 0x8;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
psxCounters[8].rate = 2000;
|
||||
psxCounters[8].CycleT = psxCounters[7].rate;
|
||||
psxCounters[8].mode = 0x8;
|
||||
#endif
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
psxCounters[i].sCycleT = psxRegs.cycle;
|
||||
|
||||
|
@ -453,6 +458,24 @@ void psxRcntUpdate()
|
|||
if (c < psxNextCounter) psxNextCounter = c;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
|
||||
// New Iop DMA handler WIP
|
||||
{
|
||||
const s32 difference = psxRegs.cycle - psxCounters[8].sCycleT;
|
||||
s32 c = psxCounters[8].CycleT;
|
||||
|
||||
if(difference >= psxCounters[8].CycleT)
|
||||
{
|
||||
psxCounters[8].sCycleT = psxRegs.cycle;
|
||||
psxCounters[8].CycleT = psxCounters[8].rate;
|
||||
IopDmaUpdate(difference);
|
||||
}
|
||||
else c -= difference;
|
||||
if (c < psxNextCounter) psxNextCounter = c;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i=0; i<6; i++) _rcntSet( i );
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,13 @@ struct psxCounter {
|
|||
s32 CycleT;
|
||||
};
|
||||
|
||||
extern psxCounter psxCounters[8];
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
# define NUM_COUNTERS 9
|
||||
#else
|
||||
# define NUM_COUNTERS 8
|
||||
#endif
|
||||
|
||||
extern psxCounter psxCounters[NUM_COUNTERS];
|
||||
extern s32 psxNextCounter;
|
||||
extern u32 psxNextsCounter;
|
||||
|
||||
|
|
170
pcsx2/IopDma.cpp
170
pcsx2/IopDma.cpp
|
@ -258,35 +258,96 @@ void iopIntcIrq(uint irqType)
|
|||
//
|
||||
|
||||
// fixme: Is this in progress?
|
||||
#if FALSE
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
|
||||
typedef s32(* DmaHandler)(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
|
||||
typedef void (* DmaIHandler)(s32 channel);
|
||||
|
||||
s32 errDmaWrite(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
|
||||
s32 errDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
|
||||
|
||||
struct DmaHandlerInfo
|
||||
s32 spu2DmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
|
||||
{
|
||||
DmaHandler Read;
|
||||
DmaHandler Write;
|
||||
DmaIHandler Interrupt;
|
||||
};
|
||||
// FIXME: change the plugin interfaces so that they are aware of this new dma handler
|
||||
|
||||
struct DmaStatusInfo
|
||||
/*
|
||||
u32 bytes = 1024;
|
||||
if(bytesLeft<1024)
|
||||
bytes=bytesLeft;
|
||||
*/
|
||||
u32 bytes=bytesLeft;
|
||||
|
||||
// Update the spu2 to the current cycle before initiating the DMA
|
||||
if (SPU2async)
|
||||
{
|
||||
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
|
||||
//Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
|
||||
|
||||
psxCounters[6].sCycleT = psxRegs.cycle;
|
||||
psxCounters[6].CycleT = bytes * 3;
|
||||
|
||||
psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
|
||||
psxNextsCounter = psxRegs.cycle;
|
||||
if (psxCounters[6].CycleT < psxNextCounter)
|
||||
psxNextCounter = psxCounters[6].CycleT;
|
||||
}
|
||||
|
||||
if(channel==7)
|
||||
SPU2readDMA7Mem((u16 *)data, bytes/2);
|
||||
else
|
||||
SPU2readDMA4Mem((u16 *)data, bytes/2);
|
||||
|
||||
*bytesProcessed = bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 spu2DmaWrite(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
|
||||
{
|
||||
u32 Control;
|
||||
u32 Width; // bytes/word, for timing purposes
|
||||
u32 MemAddr;
|
||||
u32 ByteCount;
|
||||
u32 Target;
|
||||
};
|
||||
// FIXME: change the plugin interfaces so that they are aware of this new dma handler
|
||||
|
||||
// FIXME: Dummy constants, to be "filled in" with proper values later
|
||||
#define DMA_CTRL_ACTIVE 0x80000000
|
||||
#define DMA_CTRL_DIRECTION 0x00000001
|
||||
|
||||
#define DMA_CHANNEL_MAX 16 /* ? */
|
||||
/*
|
||||
u32 bytes = 1024;
|
||||
if(bytesLeft<1024)
|
||||
bytes=bytesLeft;
|
||||
*/
|
||||
u32 bytes=bytesLeft;
|
||||
|
||||
|
||||
// Update the spu2 to the current cycle before initiating the DMA
|
||||
if (SPU2async)
|
||||
{
|
||||
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
|
||||
//Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
|
||||
|
||||
psxCounters[6].sCycleT = psxRegs.cycle;
|
||||
psxCounters[6].CycleT = bytes * 3;
|
||||
|
||||
psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
|
||||
psxNextsCounter = psxRegs.cycle;
|
||||
if (psxCounters[6].CycleT < psxNextCounter)
|
||||
psxNextCounter = psxCounters[6].CycleT;
|
||||
}
|
||||
|
||||
if(channel==7)
|
||||
SPU2writeDMA7Mem((u16 *)data, bytes/2);
|
||||
else
|
||||
SPU2writeDMA4Mem((u16 *)data, bytes/2);
|
||||
|
||||
|
||||
*bytesProcessed = bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spu2DmaInterrupt(s32 channel)
|
||||
{
|
||||
if(channel==7)
|
||||
SPU2interruptDMA7();
|
||||
else
|
||||
SPU2interruptDMA4();
|
||||
}
|
||||
|
||||
//typedef s32(* DmaHandler)(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
|
||||
//typedef void (* DmaIHandler)(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?
|
||||
|
||||
|
@ -300,9 +361,9 @@ DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] =
|
|||
{0}, //5
|
||||
{0}, //6: OT?
|
||||
{spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //7: Spu Core1
|
||||
{dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9
|
||||
{sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0
|
||||
{sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1
|
||||
{0},//{dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9
|
||||
{0},//{sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0
|
||||
{0},//{sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1
|
||||
{0}, // Sio2
|
||||
{0}, // Sio2
|
||||
};
|
||||
|
@ -324,26 +385,37 @@ const char* IopDmaNames[DMA_CHANNEL_MAX] =
|
|||
"Sio2",
|
||||
"?", "?", "?"
|
||||
};
|
||||
};
|
||||
|
||||
// Prototypes. To be implemented later (or in other parts of the emulator)
|
||||
void SetDmaUpdateTarget(u32 delay);
|
||||
void RaiseDmaIrq(u32 channel);
|
||||
void SetDmaUpdateTarget(u32 delay)
|
||||
{
|
||||
psxCounters[8].CycleT = delay;
|
||||
}
|
||||
|
||||
void RaiseDmaIrq(u32 channel)
|
||||
{
|
||||
if(channel<7)
|
||||
psxDmaInterrupt(channel);
|
||||
else
|
||||
psxDmaInterrupt2(channel-7);
|
||||
}
|
||||
|
||||
// WARNING: CALLER ****[MUST]**** CALL IopDmaUpdate RIGHT AFTER THIS!
|
||||
void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr)
|
||||
{
|
||||
// I dont' really understand this, but it's used above. Is this BYTES OR WHAT?
|
||||
int size = (bcr >> 16) * (bcr & 0xFFFF);
|
||||
int size = 4* (bcr >> 16) * (bcr & 0xFFFF);
|
||||
|
||||
IopChannels[channel].Control = chcr | DMA_CTRL_ACTIVE;
|
||||
IopChannels[channel].MemAddr = madr;
|
||||
IopChannels[channel].ByteCount = size;
|
||||
|
||||
SetDmaUpdateTarget(0);
|
||||
}
|
||||
|
||||
void IopDmaUpdate(u32 elapsed)
|
||||
{
|
||||
u32 MinDelay = 0xFFFFFFFF;
|
||||
s32 MinDelay = 0x7FFFFFFF;
|
||||
|
||||
for (int i = 0;i < DMA_CHANNEL_MAX;i++)
|
||||
{
|
||||
|
@ -363,12 +435,17 @@ void IopDmaUpdate(u32 elapsed)
|
|||
else
|
||||
{
|
||||
// TODO: Make sure it's the right order
|
||||
DmaHandler handler = (ch->Control & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Read : IopDmaHandlers[i].Write;
|
||||
DmaHandler handler = (ch->Control & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Write : IopDmaHandlers[i].Read;
|
||||
|
||||
u32 BCount = 0;
|
||||
s32 Target = (handler) ? handler(i, (u32*)PSXM(ch->MemAddr), ch->ByteCount, &BCount) : 0;
|
||||
s32 Target = (handler) ? handler(i, (u32*)iopPhysMem(ch->MemAddr), ch->ByteCount, &BCount) : 0;
|
||||
|
||||
ch->Target = 100;
|
||||
if(BCount>0)
|
||||
{
|
||||
psxCpu->Clear(ch->MemAddr, BCount/4);
|
||||
}
|
||||
|
||||
int TTarget = 100;
|
||||
if (Target < 0)
|
||||
{
|
||||
// TODO: ... What to do if the plugin errors? :P
|
||||
|
@ -378,29 +455,38 @@ void IopDmaUpdate(u32 elapsed)
|
|||
ch->MemAddr += BCount;
|
||||
ch->ByteCount -= BCount;
|
||||
|
||||
ch->Target = BCount / ch->Width;
|
||||
TTarget = BCount; // / ch->Width;
|
||||
}
|
||||
|
||||
if (Target != 0) ch->Target = Target;
|
||||
if (Target != 0) TTarget = Target;
|
||||
|
||||
if (ch->Target<MinDelay) MinDelay = TTarget;
|
||||
|
||||
ch->Target += TTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(MinDelay<0x7FFFFFFF)
|
||||
SetDmaUpdateTarget(MinDelay);
|
||||
else
|
||||
SetDmaUpdateTarget(10000);
|
||||
}
|
||||
|
||||
s32 errDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed)
|
||||
s32 errDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
|
||||
{
|
||||
Console::Error("ERROR: Tried to read using DMA %d (%s). Ignoring.", 0, channel, IopDmaNames[channel]);
|
||||
Console::Error("ERROR: Tried to read using DMA %d (%s). Ignoring.", params 0, channel, IopDmaNames[channel]);
|
||||
|
||||
*wordsProcessed = wordsLeft;
|
||||
*bytesProcessed = bytesLeft;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 errDmaWrite(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed)
|
||||
s32 errDmaWrite(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
|
||||
{
|
||||
Console::Error("ERROR: Tried to write using DMA %d (%s). Ignoring.", 0, channel, IopDmaNames[channel]);
|
||||
Console::Error("ERROR: Tried to write using DMA %d (%s). Ignoring.", params 0, channel, IopDmaNames[channel]);
|
||||
|
||||
*wordsProcessed = wordsLeft;
|
||||
*bytesProcessed = bytesLeft;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,46 @@
|
|||
|
||||
#include "PS2Edefs.h"
|
||||
|
||||
//#define ENABLE_NEW_IOPDMA
|
||||
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
|
||||
typedef s32(* DmaHandler)(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
|
||||
typedef void (* DmaIHandler)(s32 channel);
|
||||
|
||||
struct DmaHandlerInfo
|
||||
{
|
||||
DmaHandler Read;
|
||||
DmaHandler Write;
|
||||
DmaIHandler Interrupt;
|
||||
};
|
||||
|
||||
struct DmaStatusInfo
|
||||
{
|
||||
u32 Control;
|
||||
u32 Width; // bytes/word, for timing purposes
|
||||
u32 MemAddr;
|
||||
u32 ByteCount;
|
||||
s32 Target;
|
||||
};
|
||||
|
||||
// FIXME: Dummy constants, to be "filled in" with proper values later
|
||||
#define DMA_CTRL_ACTIVE 0x01000000
|
||||
#define DMA_CTRL_DIRECTION 0x00000001
|
||||
|
||||
#define DMA_CHANNEL_MAX 16 /* ? */
|
||||
|
||||
// WARNING: CALLER ****[MUST]**** CALL IopDmaUpdate RIGHT AFTER THIS!
|
||||
void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr);
|
||||
void IopDmaUpdate(u32 elapsed);
|
||||
|
||||
// external dma handlers
|
||||
extern s32 cdvdDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
|
||||
extern void cdvdDmaInterrupt(s32 channel);
|
||||
|
||||
//#else
|
||||
#endif
|
||||
|
||||
void psxDma2(u32 madr, u32 bcr, u32 chcr);
|
||||
void psxDma3(u32 madr, u32 bcr, u32 chcr);
|
||||
void psxDma4(u32 madr, u32 bcr, u32 chcr);
|
||||
|
|
|
@ -1020,7 +1020,7 @@ void psxHwWrite32(u32 add, u32 value) {
|
|||
case 0x1f8010c8:
|
||||
PSXHW_LOG("DMA4 CHCR 32bit write %lx", value);
|
||||
HW_DMA4_CHCR = value; // DMA4 chcr (SPU DMA)
|
||||
DmaExec(4);
|
||||
DmaExecNew(4);
|
||||
return;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -1053,7 +1053,7 @@ void psxHwWrite32(u32 add, u32 value) {
|
|||
case 0x1f801508:
|
||||
PSXHW_LOG("DMA7 CHCR 32bit write %lx", value);
|
||||
HW_DMA7_CHCR = value; // DMA7 chcr (SPU2)
|
||||
DmaExec2(7);
|
||||
DmaExecNew2(7);
|
||||
return;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -69,6 +69,25 @@ enum IOPCountRegs
|
|||
} \
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
#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); \
|
||||
} \
|
||||
}
|
||||
|
||||
#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); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define DmaExecNew(n) DmaExec(n)
|
||||
#define DmaExecNew2(n) DmaExec2(n)
|
||||
#endif
|
||||
|
||||
#define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA
|
||||
#define HW_DMA0_BCR (psxHu32(0x1084))
|
||||
#define HW_DMA0_CHCR (psxHu32(0x1088))
|
||||
|
|
Loading…
Reference in New Issue