Vif: Finished combining all the duplicated vif0/vif1 command functions.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2494 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2010-01-23 09:55:57 +00:00
parent 2f33f163a4
commit 26c25a2537
4 changed files with 258 additions and 445 deletions

View File

@ -1,174 +0,0 @@
/* 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 "Vif_Dma.h"
#include "VUmicro.h"
//------------------------------------------------------------------
// Vif0 Data Transfer Commands
//------------------------------------------------------------------
static int __fastcall Vif0TransNull(u32 *data) // Shouldnt go here
{
Console.WriteLn("VIF0 Shouldn't go here CMD = %x", vif0Regs->code);
vif0.cmd = 0;
return 0;
}
static int __fastcall Vif0TransSTMask(u32 *data) // STMASK
{
vif0Regs->mask = data[0];
VIF_LOG("STMASK == %x", vif0Regs->mask);
vif0.tag.size = 0;
vif0.cmd = 0;
return 1;
}
static int __fastcall Vif0TransSTRow(u32 *data) // STROW
{
int ret;
u32* pmem = &vif0Regs->r0 + (vif0.tag.addr << 2);
u32* pmem2 = g_vifmask.Row0 + vif0.tag.addr;
pxAssume(vif0.tag.addr < 4);
ret = min(4 - vif0.tag.addr, vif0.vifpacketsize);
pxAssume(ret > 0);
switch (ret)
{
case 4:
pmem[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT
}
vif0.tag.addr += ret;
vif0.tag.size -= ret;
if (vif0.tag.size == 0) vif0.cmd = 0;
return ret;
}
static int __fastcall Vif0TransSTCol(u32 *data) // STCOL
{
int ret;
u32* pmem = &vif0Regs->c0 + (vif0.tag.addr << 2);
u32* pmem2 = g_vifmask.Col0 + vif0.tag.addr;
ret = min(4 - vif0.tag.addr, vif0.vifpacketsize);
switch (ret)
{
case 4:
pmem[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT
}
vif0.tag.addr += ret;
vif0.tag.size -= ret;
if (vif0.tag.size == 0) vif0.cmd = 0;
return ret;
}
static __forceinline void vif0mpgTransfer(u32 addr, u32 *data, int size)
{
if (memcmp(VU0.Micro + addr, data, size << 2))
{
CpuVU0->Clear(addr, size << 2); // Clear before writing! :/ (cottonvibes)
memcpy_fast(VU0.Micro + addr, data, size << 2);
}
}
static int __fastcall Vif0TransMPG(u32 *data) // MPG
{
if (vif0.vifpacketsize < vif0.tag.size)
{
if((vif0.tag.addr + vif0.vifpacketsize) > 0x1000) DevCon.Warning("Vif0 MPG Split Overflow");
vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize);
vif0.tag.addr += vif0.vifpacketsize << 2;
vif0.tag.size -= vif0.vifpacketsize;
return vif0.vifpacketsize;
}
else
{
int ret;
if((vif0.tag.addr + vif0.tag.size) > 0x1000) DevCon.Warning("Vif0 MPG Overflow");
vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size);
ret = vif0.tag.size;
vif0.tag.size = 0;
vif0.cmd = 0;
return ret;
}
}
static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK
{
return nVifUnpack(0, (u8*)data);
}
//------------------------------------------------------------------
// Vif0 Data Transfer Table
//------------------------------------------------------------------
int (__fastcall *Vif0TransTLB[128])(u32 *data) =
{
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x7*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0xF*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x17*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x1F*/
Vif0TransSTMask , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x27*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x2F*/
Vif0TransSTRow , Vif0TransSTCol , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x37*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x3F*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x47*/
Vif0TransNull , Vif0TransNull , Vif0TransMPG , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x4F*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x57*/
Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x5F*/
Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , /*0x67*/
Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , /*0x6F*/
Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , /*0x77*/
Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack /*0x7F*/
};

View File

@ -1,254 +0,0 @@
/* 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 "Vif_Dma.h"
#include "GS.h"
#include "Gif.h"
#include "VUmicro.h"
//------------------------------------------------------------------
// Vif1 Data Transfer Commands
//------------------------------------------------------------------
static int __fastcall Vif1TransNull(u32 *data) // Shouldnt go here
{
Console.WriteLn("VIF1 Shouldn't go here CMD = %x", vif1Regs->code);
vif1.cmd = 0;
return 0;
}
static int __fastcall Vif1TransSTMask(u32 *data) // STMASK
{
vif1Regs->mask = data[0];
VIF_LOG("STMASK == %x", vif1Regs->mask);
vif1.tag.size = 0;
vif1.cmd = 0;
return 1;
}
static int __fastcall Vif1TransSTRow(u32 *data) // STROW
{
int ret;
u32* pmem = &vif1Regs->r0 + (vif1.tag.addr << 2);
u32* pmem2 = g_vifmask.Row1 + vif1.tag.addr;
pxAssume(vif1.tag.addr < 4);
ret = min(4 - vif1.tag.addr, vif1.vifpacketsize);
pxAssume(ret > 0);
switch (ret)
{
case 4:
pmem[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT;
}
vif1.tag.addr += ret;
vif1.tag.size -= ret;
if (vif1.tag.size == 0) vif1.cmd = 0;
return ret;
}
static int __fastcall Vif1TransSTCol(u32 *data)
{
int ret;
u32* pmem = &vif1Regs->c0 + (vif1.tag.addr << 2);
u32* pmem2 = g_vifmask.Col1 + vif1.tag.addr;
ret = min(4 - vif1.tag.addr, vif1.vifpacketsize);
switch (ret)
{
case 4:
pmem[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT;
}
vif1.tag.addr += ret;
vif1.tag.size -= ret;
if (vif1.tag.size == 0) vif1.cmd = 0;
return ret;
}
static __forceinline void vif1mpgTransfer(u32 addr, u32 *data, int size)
{
pxAssume(VU1.Micro > 0);
if (memcmp(VU1.Micro + addr, data, size << 2))
{
CpuVU1->Clear(addr, size << 2); // Clear before writing! :/
memcpy_fast(VU1.Micro + addr, data, size << 2);
}
}
static int __fastcall Vif1TransMPG(u32 *data)
{
if (vif1.vifpacketsize < vif1.tag.size)
{
if((vif1.tag.addr + vif1.vifpacketsize) > 0x4000) DevCon.Warning("Vif1 MPG Split Overflow");
vif1mpgTransfer(vif1.tag.addr, data, vif1.vifpacketsize);
vif1.tag.addr += vif1.vifpacketsize << 2;
vif1.tag.size -= vif1.vifpacketsize;
return vif1.vifpacketsize;
}
else
{
int ret;
if((vif1.tag.addr + vif1.tag.size) > 0x4000) DevCon.Warning("Vif1 MPG Overflow");
vif1mpgTransfer(vif1.tag.addr, data, vif1.tag.size);
ret = vif1.tag.size;
vif1.tag.size = 0;
vif1.cmd = 0;
return ret;
}
}
// Dummy GIF-TAG Packet to Guarantee Count = 1
extern __aligned16 u32 nloop0_packet[4];
static __aligned16 u32 splittransfer[4];
static u32 splitptr = 0;
static int __fastcall Vif1TransDirectHL(u32 *data)
{
int ret = 0;
if ((vif1.cmd & 0x7f) == 0x51)
{
if (gif->chcr.STR && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer
{
vif1Regs->stat.VGW = true;
return 0;
}
}
gifRegs->stat.APATH |= GIF_APATH2;
gifRegs->stat.OPH = true;
if (splitptr > 0) //Leftover data from the last packet, filling the rest and sending to the GS
{
if ((splitptr < 4) && (vif1.vifpacketsize >= (4 - splitptr)))
{
while (splitptr < 4)
{
splittransfer[splitptr++] = (u32)data++;
ret++;
vif1.tag.size--;
}
}
Registers::Freeze();
// copy 16 bytes the fast way:
const u64* src = (u64*)splittransfer[0];
GetMTGS().PrepDataPacket(GIF_PATH_2, nloop0_packet, 1);
u64* dst = (u64*)GetMTGS().GetDataPacketPtr();
dst[0] = src[0];
dst[1] = src[1];
GetMTGS().SendDataPacket();
Registers::Thaw();
if (vif1.tag.size == 0) vif1.cmd = 0;
splitptr = 0;
return ret;
}
if (vif1.vifpacketsize < vif1.tag.size)
{
if (vif1.vifpacketsize < 4 && splitptr != 4) //Not a full QW left in the buffer, saving left over data
{
ret = vif1.vifpacketsize;
while (ret > 0)
{
splittransfer[splitptr++] = (u32)data++;
vif1.tag.size--;
ret--;
}
return vif1.vifpacketsize;
}
vif1.tag.size -= vif1.vifpacketsize;
ret = vif1.vifpacketsize;
}
else
{
gifRegs->stat.clear_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
ret = vif1.tag.size;
vif1.tag.size = 0;
vif1.cmd = 0;
}
//TODO: ret is guaranteed to be qword aligned ?
Registers::Freeze();
// Round ret up, just in case it's not 128bit aligned.
const uint count = GetMTGS().PrepDataPacket(GIF_PATH_2, data, (ret + 3) >> 2);
memcpy_fast(GetMTGS().GetDataPacketPtr(), data, count << 4);
GetMTGS().SendDataPacket();
Registers::Thaw();
return ret;
}
static int __fastcall Vif1TransUnpack(u32 *data)
{
return nVifUnpack(1, (u8*)data);
}
//------------------------------------------------------------------
// Vif1 Data Transfer Table
//------------------------------------------------------------------
int (__fastcall *Vif1TransTLB[128])(u32 *data) =
{
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x7*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0xF*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x17*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x1F*/
Vif1TransSTMask , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x27*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x2F*/
Vif1TransSTRow , Vif1TransSTCol , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x37*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x3F*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x47*/
Vif1TransNull , Vif1TransNull , Vif1TransMPG , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x4F*/
Vif1TransDirectHL, Vif1TransDirectHL, Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x57*/
Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x5F*/
Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , /*0x67*/
Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , /*0x6F*/
Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , /*0x77*/
Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack /*0x7F*/
};

View File

@ -21,12 +21,13 @@
#include "newVif.h"
#include "VUmicro.h"
#define _vifT template <int idx>
#define vifX (idx ? vif1 : vif0)
#define vifXRegs (idx ? (vif1Regs) : (vif0Regs))
#define vif1Only() { if (!idx) { vifCMD_Null<idx>(); return; } }
_vifT void vifCMD_Null();
#define _vifT template <int idx>
#define vifX (idx ? vif1 : vif0)
#define vifXRegs (idx ? (vif1Regs) : (vif0Regs))
#define vif1Only() { if (!idx) { vifCMD_Null<idx>(); return; } }
#define vif1Only_() { if (!idx) { return vifTrans_Null<idx>(NULL); } }
_vifT void vifCMD_Null();
_f void vuExecMicro(int idx, u32 addr) {
VURegs* VU = nVif[idx].VU;
@ -86,18 +87,224 @@ void Vif1MskPath3() {
schedulepath3msk = 0;
}
//------------------------------------------------------------------
// Vif0/Vif1 Data Transfer Commands
//------------------------------------------------------------------
_vifT int __fastcall vifTrans_Null(u32 *data)
{
Console.WriteLn("VIF%d Shouldn't go here CMD = %x", idx, vifXRegs->code);
vifX.cmd = 0;
return 0;
}
_vifT int __fastcall vifTrans_STMask(u32 *data)
{
vifXRegs->mask = data[0];
VIF_LOG("STMASK == %x", vifXRegs->mask);
vifX.tag.size = 0;
vifX.cmd = 0;
return 1;
}
_vifT int __fastcall vifTrans_STRow(u32 *data)
{
int ret;
u32* rows = idx ? g_vifmask.Row1 : g_vifmask.Row0;
u32* pmem = &vifXRegs->r0 + (vifX.tag.addr << 2);
u32* pmem2 = rows + vifX.tag.addr;
ret = min(4 - vifX.tag.addr, vifX.vifpacketsize);
pxAssume(vifX.tag.addr < 4);
pxAssume(ret > 0);
switch (ret) {
case 4:
pmem[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT
}
vifX.tag.addr += ret;
vifX.tag.size -= ret;
if (!vifX.tag.size) vifX.cmd = 0;
return ret;
}
_vifT int __fastcall vifTrans_STCol(u32 *data)
{
int ret;
u32* cols = idx ? g_vifmask.Col1 : g_vifmask.Col0;
u32* pmem = &vifXRegs->c0 + (vifX.tag.addr << 2);
u32* pmem2 = cols + vifX.tag.addr;
ret = min(4 - vifX.tag.addr, vifX.vifpacketsize);
switch (ret) {
case 4:
pmem[12] = data[3];
pmem2[3] = data[3];
case 3:
pmem[8] = data[2];
pmem2[2] = data[2];
case 2:
pmem[4] = data[1];
pmem2[1] = data[1];
case 1:
pmem[0] = data[0];
pmem2[0] = data[0];
break;
jNO_DEFAULT
}
vifX.tag.addr += ret;
vifX.tag.size -= ret;
if (!vifX.tag.size) vifX.cmd = 0;
return ret;
}
_f void _vifTrans_MPG(int idx, u32 addr, u32 *data, int size)
{
VURegs& VUx = idx ? VU1 : VU0;
pxAssume(VUx.Micro > 0);
if (memcmp(VUx.Micro + addr, data, size << 2)) {
if (!idx) CpuVU0->Clear(addr, size << 2); // Clear before writing!
else CpuVU1->Clear(addr, size << 2); // Clear before writing!
memcpy_fast(VUx.Micro + addr, data, size << 2);
}
}
_vifT int __fastcall vifTrans_MPG(u32 *data)
{
if (vifX.vifpacketsize < vifX.tag.size) {
if((vifX.tag.addr + vifX.vifpacketsize) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifTrans_MPG(idx, vifX.tag.addr, data, vifX.vifpacketsize);
vifX.tag.addr += vifX.vifpacketsize << 2;
vifX.tag.size -= vifX.vifpacketsize;
return vifX.vifpacketsize;
}
else {
int ret;
if((vifX.tag.addr + vifX.tag.size) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifTrans_MPG(idx, vifX.tag.addr, data, vifX.tag.size);
ret = vifX.tag.size;
vifX.tag.size = 0;
vifX.cmd = 0;
return ret;
}
}
_vifT int __fastcall vifTrans_Unpack(u32 *data)
{
return nVifUnpack(idx, (u8*)data);
}
// Dummy GIF-TAG Packet to Guarantee Count = 1
extern __aligned16 u32 nloop0_packet[4];
static __aligned16 u32 splittransfer[4];
static u32 splitptr = 0;
_vifT int __fastcall vifTrans_DirectHL(u32 *data)
{
vif1Only_();
int ret = 0;
if ((vif1.cmd & 0x7f) == 0x51) {
if (gif->chcr.STR && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) {
vif1Regs->stat.VGW = true; // PATH3 is in image mode, so wait for end of transfer
return 0;
}
}
gifRegs->stat.APATH |= GIF_APATH2;
gifRegs->stat.OPH = true;
if (splitptr > 0) { // Leftover data from the last packet, filling the rest and sending to the GS
if ((splitptr < 4) && (vif1.vifpacketsize >= (4 - splitptr))) {
while (splitptr < 4) {
splittransfer[splitptr++] = (u32)data++;
ret++;
vif1.tag.size--;
}
}
Registers::Freeze();
// copy 16 bytes the fast way:
const u64* src = (u64*)splittransfer[0];
GetMTGS().PrepDataPacket(GIF_PATH_2, nloop0_packet, 1);
u64* dst = (u64*)GetMTGS().GetDataPacketPtr();
dst[0] = src[0];
dst[1] = src[1];
GetMTGS().SendDataPacket();
Registers::Thaw();
if (vif1.tag.size == 0) vif1.cmd = 0;
splitptr = 0;
return ret;
}
if (vif1.vifpacketsize < vif1.tag.size) {
if (vif1.vifpacketsize < 4 && splitptr != 4) {
ret = vif1.vifpacketsize;
while (ret > 0) { // Not a full QW left in the buffer, saving left over data
splittransfer[splitptr++] = (u32)data++;
vif1.tag.size--;
ret--;
}
return vif1.vifpacketsize;
}
vif1.tag.size -= vif1.vifpacketsize;
ret = vif1.vifpacketsize;
}
else {
gifRegs->stat.clear_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
ret = vif1.tag.size;
vif1.tag.size = 0;
vif1.cmd = 0;
}
// ToDo: ret is guaranteed to be qword aligned ?
Registers::Freeze();
// Round ret up, just in case it's not 128bit aligned.
const uint count = GetMTGS().PrepDataPacket(GIF_PATH_2, data, (ret + 3) >> 2);
memcpy_fast(GetMTGS().GetDataPacketPtr(), data, count << 4);
GetMTGS().SendDataPacket();
Registers::Thaw();
return ret;
}
//------------------------------------------------------------------
// Vif0/Vif1 Commands (VifCodes)
//------------------------------------------------------------------
_vifT void vifCMD_Base() // BASE
_vifT void vifCMD_Base()
{
vif1Only();
vif1Regs->base = vif1Regs->code & 0x3ff;
vif1.cmd &= ~0x7f;
}
_vifT void vifCMD_DirectHL() // DIRECT/HL
_vifT void vifCMD_DirectHL()
{
vif1Only();
int vifImm = (u16)vif1Regs->code;
@ -192,7 +399,7 @@ _vifT void vifCMD_Null() // invalid opcode
// if ME1, then force the vif to interrupt
if (!(vifXRegs->err.ME1)) //Ignore vifcode and tag mismatch error
{
Console.WriteLn("UNKNOWN VifCmd: %x", vifX.cmd);
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
vifXRegs->stat.ER1 = true;
vifX.irq++;
}
@ -233,6 +440,48 @@ _vifT void vifCMD_STRowCol() // STROW / STCOL
vifX.tag.size = 4;
}
//------------------------------------------------------------------
// Vif0/Vif1 Data Transfer Tables
//------------------------------------------------------------------
int (__fastcall *Vif0TransTLB[128])(u32 *data) = {
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x00*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x08*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x10*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x18*/
vifTrans_STMask<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x20*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x28*/
vifTrans_STRow<0> , vifTrans_STCol<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x30*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x38*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x40*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_MPG<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x48*/
vifTrans_DirectHL<0>, vifTrans_DirectHL<0>, vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x50*/
vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0> , vifTrans_Null<0>, /*0x58*/
vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Null<0>, /*0x60*/
vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0>, /*0x68*/
vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Null<0>, /*0x70*/
vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Null<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> , vifTrans_Unpack<0> /*0x78*/
};
int (__fastcall *Vif1TransTLB[128])(u32 *data) = {
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x00*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x08*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x10*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x18*/
vifTrans_STMask<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x20*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x28*/
vifTrans_STRow<1> , vifTrans_STCol<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x30*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x38*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x40*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_MPG<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x48*/
vifTrans_DirectHL<1>, vifTrans_DirectHL<1>, vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x50*/
vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1> , vifTrans_Null<1>, /*0x58*/
vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Null<1>, /*0x60*/
vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1>, /*0x68*/
vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Null<1>, /*0x70*/
vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Null<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> , vifTrans_Unpack<1> /*0x78*/
};
//------------------------------------------------------------------
// Vif0/Vif1 CMD Tables
//------------------------------------------------------------------

View File

@ -804,18 +804,10 @@
RelativePath="..\..\Vif.h"
>
</File>
<File
RelativePath="..\..\Vif0_Commands.cpp"
>
</File>
<File
RelativePath="..\..\Vif0_Dma.cpp"
>
</File>
<File
RelativePath="..\..\Vif1_Commands.cpp"
>
</File>
<File
RelativePath="..\..\Vif1_Dma.cpp"
>