Pull the IPU Fifo code out of IPU.cpp into its own file.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2556 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2010-02-04 12:19:34 +00:00
parent 06db5bba38
commit ca3679a3e0
15 changed files with 327 additions and 181 deletions

View File

@ -365,6 +365,7 @@ set(pcsx2GuiHeaders
set(pcsx2IPUSources set(pcsx2IPUSources
IPU/coroutine.cpp IPU/coroutine.cpp
IPU/IPU.cpp IPU/IPU.cpp
IPU/IPU_Fifo.cpp
IPU/mpeg2lib/Idct.cpp IPU/mpeg2lib/Idct.cpp
IPU/mpeg2lib/Mpeg.cpp IPU/mpeg2lib/Mpeg.cpp
IPU/yuv2rgb.cpp) IPU/yuv2rgb.cpp)
@ -373,6 +374,7 @@ set(pcsx2IPUSources
set(pcsx2IPUHeaders set(pcsx2IPUHeaders
IPU/coroutine.h IPU/coroutine.h
IPU/IPU.h IPU/IPU.h
IPU/IPU_Fifo.h
IPU/yuv2rgb.h) IPU/yuv2rgb.h)
# Linux sources # Linux sources

View File

@ -29,9 +29,6 @@ using namespace R5900;
//#define TEST_BROKEN_DUMP_ROUTINES //#define TEST_BROKEN_DUMP_ROUTINES
#ifdef TEST_BROKEN_DUMP_ROUTINES #ifdef TEST_BROKEN_DUMP_ROUTINES
//extern u32 psxdump;
//extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX
//extern int rdram_sdevid;
extern tIPU_BP g_BP; extern tIPU_BP g_BP;
#define VF_VAL(x) ((x==0x80000000)?0:(x)) #define VF_VAL(x) ((x==0x80000000)?0:(x))
@ -45,7 +42,7 @@ extern u32 s_nEndBlock; // what pc the current block ends
void iDumpPsxRegisters(u32 startpc, u32 temp) void iDumpPsxRegisters(u32 startpc, u32 temp)
{ {
// [TODO] fixme : thie code is broken and has no labels. Needs a rewrite to be useful. // [TODO] fixme : this code is broken and has no labels. Needs a rewrite to be useful.
#ifdef TEST_BROKEN_DUMP_ROUTINES #ifdef TEST_BROKEN_DUMP_ROUTINES
int i; int i;
@ -56,22 +53,22 @@ void iDumpPsxRegisters(u32 startpc, u32 temp)
for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]); for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]);
__Log("%scycle: %x %x %x; counters %x %x", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle, DbgCon.WriteLn("%scycle: %x %x %x; counters %x %x", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle,
psxNextsCounter, psxNextCounter); psxNextsCounter, psxNextCounter);
__Log("psxdma%d c%x b%x m%x t%x", 2, HW_DMA2_CHCR, HW_DMA2_BCR, HW_DMA2_MADR, HW_DMA2_TADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 2) + hw_dma(2).desc());
__Log("psxdma%d c%x b%x m%x", 3, HW_DMA3_CHCR, HW_DMA3_BCR, HW_DMA3_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 3) + hw_dma(3).desc());
__Log("psxdma%d c%x b%x m%x t%x", 4, HW_DMA4_CHCR, HW_DMA4_BCR, HW_DMA4_MADR, HW_DMA4_TADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 4) + hw_dma(4).desc());
__Log("psxdma%d c%x b%x m%x", 6, HW_DMA6_CHCR, HW_DMA6_BCR, HW_DMA6_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 6) + hw_dma(6).desc());
__Log("psxdma%d c%x b%x m%x", 7, HW_DMA7_CHCR, HW_DMA7_BCR, HW_DMA7_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 7) + hw_dma(7).desc());
__Log("psxdma%d c%x b%x m%x", 8, HW_DMA8_CHCR, HW_DMA8_BCR, HW_DMA8_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 8) + hw_dma(8).desc());
__Log("psxdma%d c%x b%x m%x t%x", 9, HW_DMA9_CHCR, HW_DMA9_BCR, HW_DMA9_MADR, HW_DMA9_TADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 9) + hw_dma(9).desc());
__Log("psxdma%d c%x b%x m%x", 10, HW_DMA10_CHCR, HW_DMA10_BCR, HW_DMA10_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 10) + hw_dma(10).desc());
__Log("psxdma%d c%x b%x m%x", 11, HW_DMA11_CHCR, HW_DMA11_BCR, HW_DMA11_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 11) + hw_dma(11).desc());
__Log("psxdma%d c%x b%x m%x", 12, HW_DMA12_CHCR, HW_DMA12_BCR, HW_DMA12_MADR); DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 12) + hw_dma(12).desc());
for(i = 0; i < 7; ++i) for(i = 0; i < 7; ++i)
__Log("%scounter%d: mode %x count %I64x rate %x scycle %x target %I64x", pstr, i, psxCounters[i].mode, psxCounters[i].count, psxCounters[i].rate, psxCounters[i].sCycleT, psxCounters[i].target); DbgCon.WriteLn("%scounter%d: mode %x count %I64x rate %x scycle %x target %I64x", pstr, i, psxCounters[i].mode, psxCounters[i].count, psxCounters[i].rate, psxCounters[i].sCycleT, psxCounters[i].target);
#endif #endif
} }

View File

@ -20,6 +20,7 @@
#include "GS.h" #include "GS.h"
#include "Vif.h" #include "Vif.h"
#include "IPU/IPU.h" #include "IPU/IPU.h"
#include "IPU/IPU_Fifo.h"
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
/////////////////////////// Quick & dirty FIFO :D //////////////////////// /////////////////////////// Quick & dirty FIFO :D ////////////////////////
@ -92,13 +93,13 @@ void __fastcall ReadFIFO_page_7(u32 mem, u64 *out)
{ {
out[0] = *(u64*)(g_pIPU0Pointer); out[0] = *(u64*)(g_pIPU0Pointer);
out[1] = *(u64*)(g_pIPU0Pointer+8); out[1] = *(u64*)(g_pIPU0Pointer+8);
FOreadpos = (FOreadpos + 4) & 31; ipu_fifo.out.readpos = (ipu_fifo.out.readpos + 4) & 31;
g_nIPU0Data--; g_nIPU0Data--;
g_pIPU0Pointer += 16; g_pIPU0Pointer += 16;
} }
} }
else else
FIFOfrom_readsingle((void*)out); ipu_fifo.out.readsingle((void*)out);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -177,7 +178,7 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value)
mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]); mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
//committing every 16 bytes //committing every 16 bytes
while( FIFOto_write((u32*)value, 1) == 0 ) while( ipu_fifo.in.write((u32*)value, 1) == 0 )
{ {
Console.WriteLn("IPU sleeping"); Console.WriteLn("IPU sleeping");
Threading::Timeslice(); Threading::Timeslice();

View File

@ -56,11 +56,6 @@ u8* g_pIPU0Pointer = NULL;
int g_nCmdPos[2] = {0}, g_nCmdIndex = 0; int g_nCmdPos[2] = {0}, g_nCmdIndex = 0;
int ipuCurCmd = 0xffffffff; int ipuCurCmd = 0xffffffff;
int FOreadpos = 0, FOwritepos = 0;
static int FIreadpos = 0, FIwritepos = 0;
__aligned16 u32 fifo_input[32];
__aligned16 u32 fifo_output[32];
void ReorderBitstream(); void ReorderBitstream();
// the BP doesn't advance and returns -1 if there is no data to be read // the BP doesn't advance and returns -1 if there is no data to be read
@ -70,8 +65,6 @@ static int s_RoutineDone = 0;
static u32 s_tempstack[0x4000]; // 64k static u32 s_tempstack[0x4000]; // 64k
void IPUWorker(); void IPUWorker();
int IPU0dma();
int IPU1dma();
// Color conversion stuff, the memory layout is a total hack // Color conversion stuff, the memory layout is a total hack
// convert_data_buffer is a pointer to the internal rgb struct (the first param in convert_init_t) // convert_data_buffer is a pointer to the internal rgb struct (the first param in convert_init_t)
@ -146,7 +139,7 @@ int ipuInit()
memzero(g_BP); memzero(g_BP);
init_g_decoder(); init_g_decoder();
g_nDMATransfer.reset(); g_nDMATransfer.reset();
ipu_fifo.init();
return 0; return 0;
} }
@ -163,10 +156,8 @@ void ipuShutdown()
void ReportIPU() void ReportIPU()
{ {
Console.WriteLn("g_nDMATransfer = 0x%x.", g_nDMATransfer._u32); Console.WriteLn("g_nDMATransfer = 0x%x.", g_nDMATransfer._u32);
Console.WriteLn("FIreadpos = 0x%x, FIwritepos = 0x%x.", FIreadpos, FIwritepos); ipu_fifo.in.print();
Console.WriteLn("fifo_input = 0x%x.", fifo_input); ipu_fifo.out.print();
Console.WriteLn("FOreadpos = 0x%x, FOwritepos = 0x%x.", FOreadpos, FOwritepos);
Console.WriteLn("fifo_output = 0x%x.", fifo_output);
Console.WriteLn("g_BP = 0x%x.", g_BP); Console.WriteLn("g_BP = 0x%x.", g_BP);
Console.WriteLn("niq = 0x%x, iq = 0x%x.", niq, iq); Console.WriteLn("niq = 0x%x, iq = 0x%x.", niq, iq);
Console.WriteLn("vqclut = 0x%x.", vqclut); Console.WriteLn("vqclut = 0x%x.", vqclut);
@ -193,12 +184,13 @@ void SaveStateBase::ipuFreeze()
//FreezeMem(ipuRegs, sizeof(IPUregisters)); //FreezeMem(ipuRegs, sizeof(IPUregisters));
Freeze(g_nDMATransfer._u32); Freeze(g_nDMATransfer._u32);
Freeze(FIreadpos); //Freeze(ipu_fifo);
Freeze(FIwritepos); Freeze(ipu_fifo.in.readpos);
Freeze(fifo_input); Freeze(ipu_fifo.in.writepos);
Freeze(FOreadpos); Freeze(ipu_fifo.in.data);
Freeze(FOwritepos); Freeze(ipu_fifo.out.readpos);
Freeze(fifo_output); Freeze(ipu_fifo.out.writepos);
Freeze(ipu_fifo.out.data);
Freeze(g_BP); Freeze(g_BP);
Freeze(niq); Freeze(niq);
Freeze(iq); Freeze(iq);
@ -302,8 +294,8 @@ __forceinline u64 ipuRead64(u32 mem)
void ipuSoftReset() void ipuSoftReset()
{ {
mpeg2_init(); mpeg2_init();
FIFOto_clear(); ipu_fifo.in.clear();
FIFOfrom_clear(); ipu_fifo.out.clear();
coded_block_pattern = 0; coded_block_pattern = 0;
@ -389,7 +381,7 @@ __forceinline void ipuWrite64(u32 mem, u64 value)
static void ipuBCLR(u32 val) static void ipuBCLR(u32 val)
{ {
FIFOto_clear(); ipu_fifo.in.clear();
g_BP.BP = val & 0x7F; g_BP.BP = val & 0x7F;
g_BP.FP = 0; g_BP.FP = 0;
@ -684,7 +676,7 @@ static BOOL __fastcall ipuCSC(u32 val)
{ {
while (g_nCmdPos[1] < 32) while (g_nCmdPos[1] < 32)
{ {
g_nCmdPos[1] += FIFOfrom_write(((u32*) & rgb16) + 4 * g_nCmdPos[1], 32 - g_nCmdPos[1]); g_nCmdPos[1] += ipu_fifo.out.write(((u32*) & rgb16) + 4 * g_nCmdPos[1], 32 - g_nCmdPos[1]);
if (g_nCmdPos[1] <= 0) return FALSE; if (g_nCmdPos[1] <= 0) return FALSE;
} }
@ -693,7 +685,7 @@ static BOOL __fastcall ipuCSC(u32 val)
{ {
while (g_nCmdPos[1] < 64) while (g_nCmdPos[1] < 64)
{ {
g_nCmdPos[1] += FIFOfrom_write(((u32*) & rgb32) + 4 * g_nCmdPos[1], 64 - g_nCmdPos[1]); g_nCmdPos[1] += ipu_fifo.out.write(((u32*) & rgb32) + 4 * g_nCmdPos[1], 64 - g_nCmdPos[1]);
if (g_nCmdPos[1] <= 0) return FALSE; if (g_nCmdPos[1] <= 0) return FALSE;
} }
@ -738,13 +730,13 @@ static BOOL ipuPACK(u32 val)
if (csc.OFM) if (csc.OFM)
{ {
g_nCmdPos[1] += FIFOfrom_write(((u32*) & rgb16) + 4 * g_nCmdPos[1], 32 - g_nCmdPos[1]); g_nCmdPos[1] += ipu_fifo.out.write(((u32*) & rgb16) + 4 * g_nCmdPos[1], 32 - g_nCmdPos[1]);
if (g_nCmdPos[1] < 32) return FALSE; if (g_nCmdPos[1] < 32) return FALSE;
} }
else else
{ {
g_nCmdPos[1] += FIFOfrom_write(((u32*)indx4) + 4 * g_nCmdPos[1], 8 - g_nCmdPos[1]); g_nCmdPos[1] += ipu_fifo.out.write(((u32*)indx4) + 4 * g_nCmdPos[1], 8 - g_nCmdPos[1]);
if (g_nCmdPos[1] < 8) return FALSE; if (g_nCmdPos[1] < 8) return FALSE;
} }
@ -1023,14 +1015,14 @@ u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size)
{ {
if (g_BP.FP == 0) if (g_BP.FP == 0)
{ {
if (FIFOto_read(next_readbits()) == 0) return 0; if (ipu_fifo.in.read(next_readbits()) == 0) return 0;
inc_readbits(); inc_readbits();
g_BP.FP = 1; g_BP.FP = 1;
} }
else if ((g_BP.FP < 2) && (*(int*)pointer + size) >= 128) else if ((g_BP.FP < 2) && (*(int*)pointer + size) >= 128)
{ {
if (FIFOto_read(next_readbits())) g_BP.FP += 1; if (ipu_fifo.in.read(next_readbits())) g_BP.FP += 1;
} }
if (*(int*)pointer >= 128) if (*(int*)pointer >= 128)
@ -1298,59 +1290,6 @@ void __fastcall ipu_copy(const macroblock_8 *mb8, macroblock_16 *mb16)
for (i = 0; i < 64; i++) *d++ = *s++; //Cb bias - 128 for (i = 0; i < 64; i++) *d++ = *s++; //Cb bias - 128
} }
///////////////////// IPU DMA ////////////////////////
void FIFOto_clear()
{
memzero(fifo_input);
g_BP.IFC = 0;
ipuRegs->ctrl.IFC = 0;
FIreadpos = 0;
FIwritepos = 0;
}
int FIFOto_read(void *value)
{
// wait until enough data
if (g_BP.IFC == 0)
{
// This is the only spot that wants a return value for IPU1dma.
if (IPU1dma() == 0) return 0;
pxAssert(g_BP.IFC > 0);
}
// transfer 1 qword, split into two transfers
for (int i = 0; i <= 3; i++)
{
((u32*)value)[i] = fifo_input[FIreadpos + i];
fifo_input[FIreadpos + i] = 0;
}
FIreadpos = (FIreadpos + 4) & 31;
g_BP.IFC--;
return 1;
}
int FIFOto_write(u32* pMem, int size)
{
int transsize;
int firsttrans = min(size, 8 - (int)g_BP.IFC);
g_BP.IFC += firsttrans;
transsize = firsttrans;
while (transsize-- > 0)
{
for (int i = 0; i <= 3; i++)
{
fifo_input[FIwritepos + i] = pMem[i];
}
FIwritepos = (FIwritepos + 4) & 31;
pMem += 4;
}
return firsttrans;
}
static __forceinline bool IPU1chain(int &totalqwc) static __forceinline bool IPU1chain(int &totalqwc)
{ {
if (ipu1dma->qwc > 0) if (ipu1dma->qwc > 0)
@ -1366,7 +1305,7 @@ static __forceinline bool IPU1chain(int &totalqwc)
return true; return true;
} }
qwc = FIFOto_write((u32*)pMem, qwc); qwc = ipu_fifo.in.write((u32*)pMem, qwc);
ipu1dma->madr += qwc<< 4; ipu1dma->madr += qwc<< 4;
ipu1dma->qwc -= qwc; ipu1dma->qwc -= qwc;
totalqwc += qwc; totalqwc += qwc;
@ -1452,6 +1391,15 @@ int IPU1dma()
bool done = false; bool done = false;
int ipu1cycles = 0, totalqwc = 0; int ipu1cycles = 0, totalqwc = 0;
// Note: pad is the padding right above qwc, so we're testing whether qwc
// has overflowed into pad.
// if (ipu1dma->pad != 0)
// {
// DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1dma->pad);
// //ipu1dma->qwc = ipu1dma->pad = 0;
// return 0;
// }
pxAssert(!ipu1dma->chcr.TTE); pxAssert(!ipu1dma->chcr.TTE);
if (!(ipu1dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0; if (!(ipu1dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0;
@ -1590,77 +1538,21 @@ int IPU1dma()
return totalqwc; return totalqwc;
} }
void FIFOfrom_clear()
{
memzero(fifo_output);
ipuRegs->ctrl.OFC = 0;
FOreadpos = 0;
FOwritepos = 0;
}
int FIFOfrom_write(const u32 *value, int size)
{
int transsize, firsttrans;
if ((int)ipuRegs->ctrl.OFC >= 8) IPU0dma();
transsize = min(size, 8 - (int)ipuRegs->ctrl.OFC);
firsttrans = transsize;
while (transsize-- > 0)
{
for (int i = 0; i <= 3; i++)
{
fifo_output[FOwritepos + i] = ((u32*)value)[i];
}
FOwritepos = (FOwritepos + 4) & 31;
value += 4;
}
ipuRegs->ctrl.OFC += firsttrans;
IPU0dma();
//Console.WriteLn("Written %d qwords, %d", firsttrans,ipuRegs->ctrl.OFC);
return firsttrans;
}
static __forceinline void _FIFOfrom_readsingle(void *value)
{
// transfer 1 qword, split into two transfers
for (int i = 0; i <= 3; i++)
{
((u32*)value)[i] = fifo_output[FOreadpos + i];
fifo_output[FOreadpos + i] = 0;
}
FOreadpos = (FOreadpos + 4) & 31;
}
void FIFOfrom_readsingle(void *value)
{
if (ipuRegs->ctrl.OFC > 0)
{
ipuRegs->ctrl.OFC--;
_FIFOfrom_readsingle(value);
}
}
void FIFOfrom_read(void *value, int size)
{
ipuRegs->ctrl.OFC -= size;
while (size > 0)
{
_FIFOfrom_readsingle(value);
value = (u32*)value + 4;
size--;
}
}
int IPU0dma() int IPU0dma()
{ {
int readsize; int readsize;
static int totalsize = 0; static int totalsize = 0;
tDMA_TAG* pMem; tDMA_TAG* pMem;
// Note: pad is the padding right above qwc, so we're testing whether qwc
// has overflowed into pad.
// if (ipu0dma->pad != 0)
// {
// DevCon.Warning(L"IPU0dma's upper 16 bits set to %x\n", ipu0dma->pad);
// //ipu0dma->qwc = ipu0dma->pad = 0;
// return 0;
// }
if ((!(ipu0dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0)) if ((!(ipu0dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0))
return 0; return 0;
@ -1675,7 +1567,7 @@ int IPU0dma()
readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC); readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC);
totalsize+=readsize; totalsize+=readsize;
FIFOfrom_read(pMem, readsize); ipu_fifo.out.read(pMem, readsize);
ipu0dma->madr += readsize << 4; ipu0dma->madr += readsize << 4;
ipu0dma->qwc -= readsize; // note: qwc is u16 ipu0dma->qwc -= readsize; // note: qwc is u16

View File

@ -18,6 +18,7 @@
#include "mpeg2lib/Mpeg.h" #include "mpeg2lib/Mpeg.h"
#include "coroutine.h" #include "coroutine.h"
#include "IPU_Fifo.h"
// IPU_INLINE_IRQS // IPU_INLINE_IRQS
// Scheduling ints into the future is a purist approach to emulation, and // Scheduling ints into the future is a purist approach to emulation, and
@ -224,8 +225,6 @@ extern tIPU_BP g_BP;
extern int coded_block_pattern; extern int coded_block_pattern;
extern int g_nIPU0Data; // or 0x80000000 whenever transferring extern int g_nIPU0Data; // or 0x80000000 whenever transferring
extern u8* g_pIPU0Pointer; extern u8* g_pIPU0Pointer;
extern int FOreadpos;
extern void FIFOfrom_readsingle(void *value);
// The IPU can only do one task at once and never uses other buffers so these // The IPU can only do one task at once and never uses other buffers so these
// should be made available to functions in other modules to save registers. // should be made available to functions in other modules to save registers.
@ -251,18 +250,14 @@ extern void ipu1Interrupt();
extern void dmaIPU0(); extern void dmaIPU0();
extern void dmaIPU1(); extern void dmaIPU1();
extern int IPU0dma();
extern int IPU1dma();
extern u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size); extern u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size);
extern u8 __fastcall getBits32(u8 *address, u32 advance); extern u8 __fastcall getBits32(u8 *address, u32 advance);
extern u8 __fastcall getBits16(u8 *address, u32 advance); extern u8 __fastcall getBits16(u8 *address, u32 advance);
extern u8 __fastcall getBits8(u8 *address, u32 advance); extern u8 __fastcall getBits8(u8 *address, u32 advance);
extern int __fastcall getBits(u8 *address, u32 size, u32 advance); extern int __fastcall getBits(u8 *address, u32 size, u32 advance);
// returns number of qw read
extern int FIFOfrom_write(const u32 * value, int size);
extern void FIFOfrom_read(void *value,int size);
extern int FIFOto_read(void *value);
extern int FIFOto_write(u32* pMem, int size);
extern void FIFOto_clear();
extern void FIFOfrom_clear();
#endif #endif

158
pcsx2/IPU/IPU_Fifo.cpp Normal file
View File

@ -0,0 +1,158 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "IPU_Fifo.h"
#include "IPU.h"
IPU_Fifo ipu_fifo;
void IPU_Fifo::init()
{
out.readpos = 0;
out.writepos = 0;
in.readpos = 0;
in.writepos = 0;
memzero(in.data);
memzero(out.data);
}
void IPU_Fifo_Input::clear()
{
memzero(data);
g_BP.IFC = 0;
ipuRegs->ctrl.IFC = 0;
readpos = 0;
writepos = 0;
}
void IPU_Fifo_Output::clear()
{
memzero(data);
ipuRegs->ctrl.OFC = 0;
readpos = 0;
writepos = 0;
}
void IPU_Fifo_Input::print()
{
Console.WriteLn("IPU Fifo Input: readpos = 0x%x, writepos = 0x%x, data = 0x%x", readpos, writepos, data);
}
void IPU_Fifo_Output::print()
{
Console.WriteLn("IPU Fifo Output: readpos = 0x%x, writepos = 0x%x, data = 0x%x", readpos, writepos, data);
}
int IPU_Fifo_Input::write(u32* pMem, int size)
{
int transsize;
int firsttrans = min(size, 8 - (int)g_BP.IFC);
g_BP.IFC += firsttrans;
transsize = firsttrans;
while (transsize-- > 0)
{
for (int i = 0; i <= 3; i++)
{
data[writepos + i] = pMem[i];
}
writepos = (writepos + 4) & 31;
pMem += 4;
}
return firsttrans;
}
int IPU_Fifo_Output::write(const u32 *value, int size)
{
int transsize, firsttrans;
if ((int)ipuRegs->ctrl.OFC >= 8) IPU0dma();
transsize = min(size, 8 - (int)ipuRegs->ctrl.OFC);
firsttrans = transsize;
while (transsize-- > 0)
{
for (int i = 0; i <= 3; i++)
{
data[writepos + i] = ((u32*)value)[i];
}
writepos = (writepos + 4) & 31;
value += 4;
}
ipuRegs->ctrl.OFC += firsttrans;
IPU0dma();
//Console.WriteLn("Written %d qwords, %d", firsttrans,ipuRegs->ctrl.OFC);
return firsttrans;
}
int IPU_Fifo_Input::read(void *value)
{
// wait until enough data
if (g_BP.IFC == 0)
{
// This is the only spot that wants a return value for IPU1dma.
if (IPU1dma() == 0) return 0;
pxAssert(g_BP.IFC > 0);
}
// transfer 1 qword, split into two transfers
for (int i = 0; i <= 3; i++)
{
((u32*)value)[i] = data[readpos + i];
data[readpos + i] = 0;
}
readpos = (readpos + 4) & 31;
g_BP.IFC--;
return 1;
}
void IPU_Fifo_Output::_readsingle(void *value)
{
// transfer 1 qword, split into two transfers
for (int i = 0; i <= 3; i++)
{
((u32*)value)[i] = data[readpos + i];
data[readpos + i] = 0;
}
readpos = (readpos + 4) & 31;
}
void IPU_Fifo_Output::read(void *value, int size)
{
ipuRegs->ctrl.OFC -= size;
while (size > 0)
{
_readsingle(value);
value = (u32*)value + 4;
size--;
}
}
void IPU_Fifo_Output::readsingle(void *value)
{
if (ipuRegs->ctrl.OFC > 0)
{
ipuRegs->ctrl.OFC--;
_readsingle(value);
}
}

60
pcsx2/IPU/IPU_Fifo.h Normal file
View File

@ -0,0 +1,60 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef IPU_FIFO_H_INCLUDED
#define IPU_FIFO_H_INCLUDED
class IPU_Fifo_Input
{
public:
int readpos, writepos;
__aligned16 u32 data[32];
int write(u32* pMem, int size);
int read(void *value);
void clear();
void print();
};
class IPU_Fifo_Output
{
public:
int readpos, writepos;
__aligned16 u32 data[32];
// returns number of qw read
int write(const u32 * value, int size);
void read(void *value,int size);
void readsingle(void *value);
void clear();
void print();
private:
void _readsingle(void *value);
};
class IPU_Fifo
{
public:
IPU_Fifo_Input in;
IPU_Fifo_Output out;
void init();
};
extern IPU_Fifo ipu_fifo;
#endif // IPU_FIFO_H_INCLUDED

View File

@ -1213,7 +1213,7 @@ void mpeg2sliceIDEC(void* pdone)
while (g_nIPU0Data > 0) while (g_nIPU0Data > 0)
{ {
read = FIFOfrom_write((u32*)g_pIPU0Pointer, g_nIPU0Data); read = ipu_fifo.out.write((u32*)g_pIPU0Pointer, g_nIPU0Data);
if (read == 0) if (read == 0)
{ {
@ -1389,7 +1389,7 @@ void mpeg2_slice(void* pdone)
while (g_nIPU0Data > 0) while (g_nIPU0Data > 0)
{ {
size = FIFOfrom_write((u32*)g_pIPU0Pointer, g_nIPU0Data); size = ipu_fifo.out.write((u32*)g_pIPU0Pointer, g_nIPU0Data);
if (size == 0) if (size == 0)
{ {

View File

@ -208,6 +208,7 @@ struct dma_mbc
{ {
return (bcr >> 16); return (bcr >> 16);
} }
wxString desc() const { return wxsFormat(L"madr: 0x%x bcr: 0x%x chcr: 0x%x", madr, bcr, chcr); }
}; };
struct dma_mbct struct dma_mbct
@ -225,6 +226,7 @@ struct dma_mbct
{ {
return (bcr >> 16); return (bcr >> 16);
} }
wxString desc() const { return wxsFormat(L"madr: 0x%x bcr: 0x%x chcr: 0x%x tadr: 0x%x", madr, bcr, chcr, tadr); }
}; };
#define hw_dma0 (*(dma_mbc*) &psxH[0x1080]) #define hw_dma0 (*(dma_mbc*) &psxH[0x1080])

View File

@ -237,6 +237,8 @@
<Unit filename="../HwWrite.cpp" /> <Unit filename="../HwWrite.cpp" />
<Unit filename="../IPU/IPU.cpp" /> <Unit filename="../IPU/IPU.cpp" />
<Unit filename="../IPU/IPU.h" /> <Unit filename="../IPU/IPU.h" />
<Unit filename="../IPU/IPU_Fifo.cpp" />
<Unit filename="../IPU/IPU_Fifo.h" />
<Unit filename="../IPU/acoroutine.S" /> <Unit filename="../IPU/acoroutine.S" />
<Unit filename="../IPU/coroutine.cpp" /> <Unit filename="../IPU/coroutine.cpp" />
<Unit filename="../IPU/coroutine.h" /> <Unit filename="../IPU/coroutine.h" />

View File

@ -166,6 +166,7 @@ static __forceinline bool SIFIOPReadTag()
{ {
// Read a tag. // Read a tag.
sif1.fifo.read((u32*)&sif1.data, 4); sif1.fifo.read((u32*)&sif1.data, 4);
//sif1.data.words = (sif1.data.words + 3) & 0xfffffffc; // Round up to nearest 4.
SIF_LOG("SIF 1 IOP: dest chain tag madr:%08X wc:%04X id:%X irq:%d", SIF_LOG("SIF 1 IOP: dest chain tag madr:%08X wc:%04X id:%X irq:%d",
sif1.data.data & 0xffffff, sif1.data.words, sif1tag.ID, sif1tag.IRQ); sif1.data.data & 0xffffff, sif1.data.words, sif1tag.ID, sif1tag.IRQ);

View File

@ -128,6 +128,7 @@
<ClCompile Include="..\..\IopSio2.cpp" /> <ClCompile Include="..\..\IopSio2.cpp" />
<ClCompile Include="..\..\IPU\coroutine.cpp" /> <ClCompile Include="..\..\IPU\coroutine.cpp" />
<ClCompile Include="..\..\Ipu\IPU.cpp" /> <ClCompile Include="..\..\Ipu\IPU.cpp" />
<ClCompile Include="..\..\Ipu\IPU_Fifo.cpp" />
<ClCompile Include="..\..\Ipu\mpeg2lib\Idct.cpp" /> <ClCompile Include="..\..\Ipu\mpeg2lib\Idct.cpp" />
<ClCompile Include="..\..\Ipu\mpeg2lib\Mpeg.cpp" /> <ClCompile Include="..\..\Ipu\mpeg2lib\Mpeg.cpp" />
<ClCompile Include="..\..\Ipu\yuv2rgb.cpp" /> <ClCompile Include="..\..\Ipu\yuv2rgb.cpp" />
@ -611,6 +612,7 @@
<ClInclude Include="..\..\IopSio2.h" /> <ClInclude Include="..\..\IopSio2.h" />
<ClInclude Include="..\..\IPU\coroutine.h" /> <ClInclude Include="..\..\IPU\coroutine.h" />
<ClInclude Include="..\..\Ipu\IPU.h" /> <ClInclude Include="..\..\Ipu\IPU.h" />
<ClInclude Include="..\..\Ipu\IPU_Fifo.h" />
<ClInclude Include="..\..\Ipu\mpeg2lib\Mpeg.h" /> <ClInclude Include="..\..\Ipu\mpeg2lib\Mpeg.h" />
<ClInclude Include="..\..\Ipu\mpeg2lib\Vlc.h" /> <ClInclude Include="..\..\Ipu\mpeg2lib\Vlc.h" />
<ClInclude Include="..\..\Ipu\yuv2rgb.h" /> <ClInclude Include="..\..\Ipu\yuv2rgb.h" />

View File

@ -1278,10 +1278,42 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath="..\..\Ipu\IPU_Fifo.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Devel|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\..\Ipu\IPU.h" RelativePath="..\..\Ipu\IPU.h"
> >
</File> </File>
<File
RelativePath="..\..\Ipu\IPU_Fifo.h"
>
</File>
<File <File
RelativePath="..\..\Ipu\yuv2rgb.cpp" RelativePath="..\..\Ipu\yuv2rgb.cpp"
> >

View File

@ -1275,7 +1275,9 @@ static void printfn()
} }
} }
#ifdef PCSX2_DEBUG
static u32 s_recblocks[] = {0}; static u32 s_recblocks[] = {0};
#endif
// Called when a block under manual protection fails it's pre-execution integrity check. // Called when a block under manual protection fails it's pre-execution integrity check.
void __fastcall dyna_block_discard(u32 start,u32 sz) void __fastcall dyna_block_discard(u32 start,u32 sz)

View File

@ -21,7 +21,7 @@
#include "newVif_UnpackSSE.h" #include "newVif_UnpackSSE.h"
static __aligned16 nVifBlock _vBlock = {0}; static __aligned16 nVifBlock _vBlock = {0};
static __pagealigned u8 nVifMemCmp[__pagesize]; //static __pagealigned u8 nVifMemCmp[__pagesize];
void dVifInit(int idx) { void dVifInit(int idx) {
nVif[idx].numBlocks = 0; nVif[idx].numBlocks = 0;
@ -124,14 +124,14 @@ static void ShiftDisplacementWindow( xAddressInfo& addr, const xRegister32& modR
} }
if(addImm) xADD(modReg, addImm); if(addImm) xADD(modReg, addImm);
} }
static bool UsesTwoRegs[] = /*static bool UsesTwoRegs[] =
{ {
true, true, true, true, true, true, true, true,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, true, false, false, false, true,
}; };*/
void VifUnpackSSE_Dynarec::CompileRoutine() { void VifUnpackSSE_Dynarec::CompileRoutine() {
const int upkNum = v.vif->cmd & 0xf; const int upkNum = v.vif->cmd & 0xf;
@ -220,7 +220,7 @@ _f void dVifUnpack(int idx, u8 *data, u32 size, bool isFill) {
const int doMask = v.vif->cmd & 0x10; const int doMask = v.vif->cmd & 0x10;
const int cycle_cl = v.vifRegs->cycle.cl; const int cycle_cl = v.vifRegs->cycle.cl;
const int cycle_wl = v.vifRegs->cycle.wl; const int cycle_wl = v.vifRegs->cycle.wl;
const int cycleSize = isFill ? cycle_cl : cycle_wl; // const int cycleSize = isFill ? cycle_cl : cycle_wl;
const int blockSize = isFill ? cycle_wl : cycle_cl; const int blockSize = isFill ? cycle_wl : cycle_cl;
if (v.vif->cl >= blockSize) v.vif->cl = 0; if (v.vif->cl >= blockSize) v.vif->cl = 0;