2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
2010-05-03 14:08:02 +00:00
|
|
|
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
2009-09-17 23:04:02 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* 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.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* 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/>.
|
2009-02-09 21:15:56 +00:00
|
|
|
*/
|
|
|
|
|
2009-09-08 12:08:10 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "PrecompiledHeader.h"
|
|
|
|
#include "Common.h"
|
|
|
|
|
2010-05-09 16:13:27 +00:00
|
|
|
#include "Gif.h"
|
2009-09-27 00:11:09 +00:00
|
|
|
#include "GS.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "Vif.h"
|
2010-05-09 19:02:06 +00:00
|
|
|
#include "Vif_Dma.h"
|
2009-09-27 00:11:09 +00:00
|
|
|
#include "IPU/IPU.h"
|
2010-02-04 12:19:34 +00:00
|
|
|
#include "IPU/IPU_Fifo.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// ** NOTE: cannot use XMM/MMX regs **
|
|
|
|
|
|
|
|
// Notes on FIFO implementation
|
|
|
|
//
|
|
|
|
// The FIFO consists of four separate pages of HW register memory, each mapped to a
|
|
|
|
// PS2 device. They are listed as follows:
|
|
|
|
//
|
|
|
|
// 0x4000 - 0x5000 : VIF0 (all registers map to 0x4000)
|
|
|
|
// 0x5000 - 0x6000 : VIF1 (all registers map to 0x5000)
|
|
|
|
// 0x6000 - 0x7000 : GS (all registers map to 0x6000)
|
|
|
|
// 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively)
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// ReadFIFO Pages
|
|
|
|
|
|
|
|
void __fastcall ReadFIFO_page_4(u32 mem, u64 *out)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) );
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2009-03-27 06:34:51 +00:00
|
|
|
VIF_LOG("ReadFIFO/VIF0 0x%08X", mem);
|
2009-11-27 13:49:37 +00:00
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
out[0] = psHu64(VIF0_FIFO);
|
|
|
|
out[1] = psHu64(VIF0_FIFO + 8);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __fastcall ReadFIFO_page_5(u32 mem, u64 *out)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-27 06:34:51 +00:00
|
|
|
VIF_LOG("ReadFIFO/VIF1, addr=0x%08X", mem);
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.Warning( "Reading from vif1 fifo when stalled" );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2010-04-15 00:32:58 +00:00
|
|
|
if(vif1Regs->stat.FQC == 0) Console.Warning("FQC = 0 on VIF FIFO READ!");
|
2009-10-05 21:24:22 +00:00
|
|
|
if (vif1Regs->stat.FDR)
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2010-05-09 19:02:06 +00:00
|
|
|
if(vif1Regs->stat.FQC > vif1.GSLastDownloadSize)
|
|
|
|
{
|
|
|
|
DevCon.Warning("Warning! GS Download size < FIFO count!");
|
|
|
|
}
|
2010-04-15 00:32:58 +00:00
|
|
|
if (vif1Regs->stat.FQC > 0)
|
|
|
|
{
|
|
|
|
GetMTGS().WaitGS();
|
|
|
|
GSreadFIFO(&psHu64(VIF1_FIFO));
|
|
|
|
}
|
2010-05-09 19:02:06 +00:00
|
|
|
if(vif1Regs->stat.FQC > 0)
|
|
|
|
{
|
|
|
|
--vif1.GSLastDownloadSize;
|
|
|
|
vif1Regs->stat.FQC = min((u32)16, vif1.GSLastDownloadSize);
|
|
|
|
}
|
2010-05-09 16:15:22 +00:00
|
|
|
|
|
|
|
if(vif1Regs->stat.FQC == 0) //We're out of data now so clear this..
|
|
|
|
gifRegs->stat.OPH = false;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
out[0] = psHu64(VIF1_FIFO);
|
|
|
|
out[1] = psHu64(VIF1_FIFO + 8);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __fastcall ReadFIFO_page_6(u32 mem, u64 *out)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.Warning( "ReadFIFO/GIF, addr=0x%x", mem );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
out[0] = psHu64(GIF_FIFO);
|
|
|
|
out[1] = psHu64(GIF_FIFO + 8);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __fastcall ReadFIFO_page_7(u32 mem, u64 *out)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= IPUout_FIFO) && (mem < D0_CHCR) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
// All addresses in this page map to 0x7000 and 0x7010:
|
|
|
|
mem &= 0x10;
|
|
|
|
|
2010-02-07 06:29:58 +00:00
|
|
|
if( mem == 0 ) // IPUout_FIFO
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
|
|
|
if( g_nIPU0Data > 0 )
|
|
|
|
{
|
|
|
|
out[0] = *(u64*)(g_pIPU0Pointer);
|
|
|
|
out[1] = *(u64*)(g_pIPU0Pointer+8);
|
2010-02-04 12:19:34 +00:00
|
|
|
ipu_fifo.out.readpos = (ipu_fifo.out.readpos + 4) & 31;
|
2009-02-09 21:15:56 +00:00
|
|
|
g_nIPU0Data--;
|
|
|
|
g_pIPU0Pointer += 16;
|
|
|
|
}
|
|
|
|
}
|
2010-02-07 06:29:58 +00:00
|
|
|
else // IPUin_FIFO
|
2010-02-04 12:19:34 +00:00
|
|
|
ipu_fifo.out.readsingle((void*)out);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// WriteFIFO Pages
|
|
|
|
|
|
|
|
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-27 06:34:51 +00:00
|
|
|
VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem);
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
psHu64(VIF0_FIFO) = value[0];
|
|
|
|
psHu64(VIF0_FIFO + 8) = value[1];
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
vif0ch->qwc += 1;
|
2009-11-27 13:49:37 +00:00
|
|
|
bool ret = VIF0transfer((u32*)value, 4, true);
|
|
|
|
pxAssertDev( ret, "vif stall code not implemented" );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-03-27 06:34:51 +00:00
|
|
|
VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem);
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
psHu64(VIF1_FIFO) = value[0];
|
|
|
|
psHu64(VIF1_FIFO + 8) = value[1];
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-05 21:24:22 +00:00
|
|
|
if (vif1Regs->stat.FDR)
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.Warning("writing to fifo when fdr is set!");
|
2009-10-06 09:08:36 +00:00
|
|
|
if (vif1Regs->stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) )
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.Warning("writing to vif1 fifo when stalled");
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
vif1ch->qwc += 1;
|
2009-11-27 13:49:37 +00:00
|
|
|
bool ret = VIF1transfer((u32*)value, 4, false);
|
|
|
|
pxAssertDev( ret, "vif stall code not implemented" );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 06:24:41 +00:00
|
|
|
// Dummy GIF-TAG Packet to Guarantee Count = 1
|
2009-10-05 02:15:49 +00:00
|
|
|
__aligned16 u32 nloop0_packet[4] = {0x8000, 0, 0, 0};
|
2009-09-15 06:24:41 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= GIF_FIFO) && (mem < IPUout_FIFO) );
|
2009-03-27 06:34:51 +00:00
|
|
|
GIF_LOG("WriteFIFO/GIF, addr=0x%08X", mem);
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-06 09:08:36 +00:00
|
|
|
psHu64(GIF_FIFO) = value[0];
|
|
|
|
psHu64(GIF_FIFO + 8) = value[1];
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-22 01:20:22 +00:00
|
|
|
Registers::Freeze();
|
2009-11-23 06:54:24 +00:00
|
|
|
GetMTGS().PrepDataPacket(GIF_PATH_3, nloop0_packet, 1);
|
|
|
|
u64* data = (u64*)GetMTGS().GetDataPacketPtr();
|
2009-08-02 16:48:03 +00:00
|
|
|
data[0] = value[0];
|
|
|
|
data[1] = value[1];
|
2009-11-23 06:54:24 +00:00
|
|
|
GetMTGS().SendDataPacket();
|
2009-10-22 01:20:22 +00:00
|
|
|
Registers::Thaw();
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value)
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
pxAssert( (mem >= IPUout_FIFO) && (mem < D0_CHCR) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
// All addresses in this page map to 0x7000 and 0x7010:
|
|
|
|
mem &= 0x10;
|
|
|
|
|
2009-09-08 05:37:40 +00:00
|
|
|
IPU_LOG( "WriteFIFO/IPU, addr=0x%x", mem );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
if( mem == 0 )
|
|
|
|
{
|
|
|
|
// Should this raise a PS2 exception or just ignore silently?
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.Warning( "WriteFIFO/IPUout (ignored)" );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-03-27 06:34:51 +00:00
|
|
|
IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X",
|
2009-02-09 21:15:56 +00:00
|
|
|
mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
|
|
|
|
|
|
|
|
//committing every 16 bytes
|
2010-02-04 12:19:34 +00:00
|
|
|
while( ipu_fifo.in.write((u32*)value, 1) == 0 )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.WriteLn("IPU sleeping");
|
2009-02-09 21:15:56 +00:00
|
|
|
Threading::Timeslice();
|
|
|
|
}
|
|
|
|
}
|
2010-04-15 00:32:58 +00:00
|
|
|
}
|