Disabled PCH for IPU.cpp -- it was causing problems that crashed FFXII vids among others.

Moved Dynarec-related IPU const mem reads/writes to iIPU.cpp, and added some __fastcall directives to various relevant functions and function pointers (very small speedup).

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@586 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2009-01-13 20:42:32 +00:00 committed by Gregory Hainaut
parent 52952bce92
commit 28e4ac4079
14 changed files with 319 additions and 553 deletions

View File

@ -18,20 +18,14 @@
#include "PrecompiledHeader.h"
#include "Common.h"
#include "IPU.h"
#include "R5900.h"
#include "mpeg2lib/Mpeg.h"
#include "yuv2rgb.h"
#include <time.h>
#include "iR5900.h"
#include "coroutine.h"
using namespace std; // for min / max
using namespace Dynarec;
using namespace Dynarec::R5900;
using R5900::cpuRegs;
// Zero cycle IRQ schedules aren't really good, but the IPU uses them.
// Better to throw the IRQ inline:
@ -74,12 +68,6 @@ u8* g_pIPU0Pointer = NULL;
int g_nCmdPos[2] = {0}, g_nCmdIndex = 0;
int ipuCurCmd = 0xffffffff;
// returns number of qw read
int FIFOfrom_write(u32 * value, int size);
void FIFOfrom_read(void *value,int size);
int FIFOto_read(void *value);
int FIFOto_write(u32* pMem, int size);
void FIFOto_clear();
int FOreadpos = 0, FOwritepos = 0;
static int FIreadpos = 0, FIwritepos = 0;
@ -303,108 +291,6 @@ u64 ipuRead64(u32 mem)
return *(u64*)(((u8*)ipuRegs)+(mem&0xff));
}
int ipuConstRead32(u32 x86reg, u32 mem)
{
int workingreg, tempreg, tempreg2;
iFlushCall(0);
CALLFunc((u32)IPUProcessInterrupt);
// if( !(x86reg&(MEM_XMMTAG|MEM_MMXTAG)) ) {
// if( x86reg == EAX ) {
// tempreg = ECX;
// tempreg2 = EDX;
// }
// else if( x86reg == ECX ) {
// tempreg = EAX;
// tempreg2 = EDX;
// }
// else if( x86reg == EDX ) {
// tempreg = EAX;
// tempreg2 = ECX;
// }
//
// workingreg = x86reg;
// }
// else {
workingreg = EAX;
tempreg = ECX;
tempreg2 = EDX;
// }
switch (mem){
case 0x10002010: // IPU_CTRL
MOV32MtoR(workingreg, (u32)&ipuRegs->ctrl._u32);
AND32ItoR(workingreg, ~0x3f0f); // save OFC
OR8MtoR(workingreg, (u32)&g_BP.IFC);
OR8MtoR(workingreg+4, (u32)&coded_block_pattern); // or ah, mem
// MOV32MtoR(workingreg, (u32)&ipuRegs->ctrl._u32);
// AND32ItoR(workingreg, ~0x3fff);
// MOV32MtoR(tempreg, (u32)&g_nIPU0Data);
// MOV8MtoR(workingreg, (u32)&g_BP.IFC);
//
// CMP32ItoR(tempreg, 8);
// j8Ptr[5] = JLE8(0);
// MOV32ItoR(tempreg, 8);
// x86SetJ8( j8Ptr[5] );
// SHL32ItoR(tempreg, 4);
//
// OR8MtoR(workingreg+4, (u32)&coded_block_pattern); // or ah, mem
// OR8RtoR(workingreg, tempreg);
#ifdef _DEBUG
MOV32RtoM((u32)&ipuRegs->ctrl._u32, workingreg);
#endif
// NOTE: not updating ipuRegs->ctrl
// if( x86reg & MEM_XMMTAG ) SSE2_MOVD_R_to_XMM(x86reg&0xf, workingreg);
// else if( x86reg & MEM_MMXTAG ) MOVD32RtoMMX(x86reg&0xf, workingreg);
return 1;
case 0x10002020: // IPU_BP
assert( (u32)&g_BP.FP + 1 == (u32)&g_BP.bufferhasnew );
MOVZX32M8toR(workingreg, (u32)&g_BP.BP);
MOVZX32M8toR(tempreg, (u32)&g_BP.FP);
AND8ItoR(workingreg, 0x7f);
ADD8MtoR(tempreg, (u32)&g_BP.bufferhasnew);
MOV8MtoR(workingreg+4, (u32)&g_BP.IFC);
SHL32ItoR(tempreg, 16);
OR32RtoR(workingreg, tempreg);
#ifdef _DEBUG
MOV32RtoM((u32)&ipuRegs->ipubp, workingreg);
#endif
// NOTE: not updating ipuRegs->ipubp
// if( x86reg & MEM_XMMTAG ) SSE2_MOVD_R_to_XMM(x86reg&0xf, workingreg);
// else if( x86reg & MEM_MMXTAG ) MOVD32RtoMMX(x86reg&0xf, workingreg);
return 1;
default:
// ipu repeats every 0x100
_eeReadConstMem32(x86reg, (u32)(((u8*)ipuRegs)+(mem&0xff)));
return 0;
}
return 0;
}
void ipuConstRead64(u32 mem, int mmreg)
{
iFlushCall(0);
CALLFunc((u32)IPUProcessInterrupt);
if( IS_XMMREG(mmreg) ) SSE_MOVLPS_M64_to_XMM(mmreg&0xff, (u32)(((u8*)ipuRegs)+(mem&0xff)));
else {
MOVQMtoR(mmreg, (u32)(((u8*)ipuRegs)+(mem&0xff)));
SetMMXstate();
}
}
void ipuSoftReset()
{
if (!mpeg2_inited){
@ -451,7 +337,7 @@ void ipuWrite32(u32 mem,u32 value)
case 0x10002010: // IPU_CTRL
ipuRegs->ctrl._u32 = (value&0x47f30000)|(ipuRegs->ctrl._u32&0x8000ffff);
if( ipuRegs->ctrl.IDP == 3 ) {
SysPrintf("IPU Invaild Intra DC Precision, switching to 9 bits\n");
SysPrintf("IPU Invalid Intra DC Precision, switching to 9 bits\n");
ipuRegs->ctrl.IDP = 1;
}
if (ipuRegs->ctrl.RST & 0x1) { // RESET
@ -485,77 +371,8 @@ void ipuWrite64(u32 mem, u64 value)
}
}
void ipuConstWrite32(u32 mem, int mmreg)
{
iFlushCall(0);
if( !(mmreg & (MEM_XMMTAG|MEM_MMXTAG|MEM_EECONSTTAG)) ) PUSH32R(mmreg);
CALLFunc((u32)IPUProcessInterrupt);
switch (mem){
case 0x10002000: // IPU_CMD
if( (mmreg & (MEM_XMMTAG|MEM_MMXTAG|MEM_EECONSTTAG)) ) _recPushReg(mmreg);
CALLFunc((u32)IPUCMD_WRITE);
ADD32ItoR(ESP, 4);
break;
case 0x10002010: // IPU_CTRL
if( mmreg & MEM_EECONSTTAG ) {
u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]&0x47f30000;
if( c & 0x40000000 ) {
CALLFunc((u32)ipuSoftReset);
}
else {
AND32ItoM((u32)&ipuRegs->ctrl._u32, 0x8000ffff);
OR32ItoM((u32)&ipuRegs->ctrl._u32, c);
}
}
else {
if( mmreg & MEM_XMMTAG ) SSE2_MOVD_XMM_to_R(EAX, mmreg&0xf);
else if( mmreg & MEM_MMXTAG ) MOVD32MMXtoR(EAX, mmreg&0xf);
else POP32R(EAX);
MOV32MtoR(ECX, (u32)&ipuRegs->ctrl._u32);
AND32ItoR(EAX, 0x47f30000);
AND32ItoR(ECX, 0x8000ffff);
OR32RtoR(EAX, ECX);
MOV32RtoM((u32)&ipuRegs->ctrl._u32, EAX);
TEST32ItoR(EAX, 0x40000000);
j8Ptr[5] = JZ8(0);
// reset
CALLFunc((u32)ipuSoftReset);
x86SetJ8( j8Ptr[5] );
}
break;
default:
if( !(mmreg & (MEM_XMMTAG|MEM_MMXTAG|MEM_EECONSTTAG)) ) POP32R(mmreg);
_eeWriteConstMem32((u32)((u8*)ipuRegs + (mem&0xfff)), mmreg);
break;
}
}
void ipuConstWrite64(u32 mem, int mmreg)
{
iFlushCall(0);
CALLFunc((u32)IPUProcessInterrupt);
switch (mem){
case 0x10002000:
_recPushReg(mmreg);
CALLFunc((u32)IPUCMD_WRITE);
ADD32ItoR(ESP, 4);
break;
default:
_eeWriteConstMem64( (u32)((u8*)ipuRegs + (mem&0xfff)), mmreg);
break;
}
}
///////////////////////////////////////////
//////////////////////////////////////////////////////
// IPU Commands (exec on worker thread only)
static void ipuBCLR(u32 val) {
@ -570,12 +387,11 @@ static void ipuBCLR(u32 val) {
IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X\n", g_BP.BP);
}
static BOOL ipuIDEC(u32 val)
static __forceinline BOOL ipuIDEC(u32 val)
{
tIPU_CMD_IDEC idec={0, 0, 0, 0, 0, 0, 0, 0, 0};
*(u32*)&idec=val;
#ifdef IPU_LOG
IPU_LOG("IPU IDEC command.\n");
if (idec.FB){ IPU_LOG(" Skip %d bits.",idec.FB);}
IPU_LOG(" Quantizer step code=0x%X.",idec.QSC);
@ -587,7 +403,6 @@ static BOOL ipuIDEC(u32 val)
if (idec.OFM==0){ IPU_LOG(" Output format is RGB32.");
}else{ IPU_LOG(" Output format is RGB16.");}
IPU_LOG("\n");
#endif
g_BP.BP+= idec.FB;//skip FB bits
//from IPU_CTRL
@ -622,12 +437,11 @@ static int s_bdec=0;
#define s_bdec 0
#endif
static BOOL ipuBDEC(u32 val)
static __forceinline BOOL ipuBDEC(u32 val)
{
tIPU_CMD_BDEC bdec={0, 0, 0, 0, 0, 0, 0, 0};
*(u32*)&bdec=val;
#ifdef IPU_LOG
IPU_LOG("IPU BDEC(macroblock decode) command %x, num: 0x%x\n",cpuRegs.pc, s_bdec);
if (bdec.FB){ IPU_LOG(" Skip 0x%X bits.", bdec.FB);}
if (bdec.MBI){ IPU_LOG(" Intra MB.");}
@ -637,8 +451,6 @@ static BOOL ipuBDEC(u32 val)
if (bdec.DT){ IPU_LOG(" Use field DCT.");}
else{ IPU_LOG(" Use frame DCT.");}
IPU_LOG(" Quantiser step=0x%X\n",bdec.QSC);
#endif
#ifdef _DEBUG
s_bdec++;
#endif
@ -668,7 +480,7 @@ static BOOL ipuBDEC(u32 val)
return s_RoutineDone;
}
static BOOL ipuVDEC(u32 val) {
static BOOL __fastcall ipuVDEC(u32 val) {
switch( g_nCmdPos[0] ) {
case 0:
@ -721,9 +533,10 @@ static BOOL ipuVDEC(u32 val) {
((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")),ipuRegs->ctrl.PCT);
return TRUE;
jNO_DEFAULT
}
assert(0);
return FALSE;
}
@ -740,37 +553,33 @@ static BOOL ipuFDEC(u32 val)
return TRUE;
}
static BOOL ipuSETIQ(u32 val)
static __forceinline BOOL ipuSETIQ(u32 val)
{
int i;
if ((val >> 27) & 1){
g_nCmdPos[0] += getBits((u8*)niq + g_nCmdPos[0], 512-8*g_nCmdPos[0], 1); // 8*8*8
#ifdef IPU_LOG
IPU_LOG("Read non-intra quantisation matrix from IPU FIFO.\n");
IPU_LOG("Read non-intra quantization matrix from IPU FIFO.\n");
for (i=0; i<8; i++){
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X\n",
niq[i*8+0], niq[i*8+1], niq[i*8+2], niq[i*8+3],
niq[i*8+4], niq[i*8+5], niq[i*8+6], niq[i*8+7]);
}
#endif
}else{
g_nCmdPos[0] += getBits((u8*)iq+8*g_nCmdPos[0], 512-8*g_nCmdPos[0], 1);
#ifdef IPU_LOG
IPU_LOG("Read intra quantisation matrix from IPU FIFO.\n");
IPU_LOG("Read intra quantization matrix from IPU FIFO.\n");
for (i=0; i<8; i++){
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X\n",
iq[i*8+0], iq[i*8+1], iq[i*8+2], iq[i*8+3],
iq[i*8+4], iq[i*8+5], iq[i*8+6], iq[i*8+7]);
}
#endif
}
return g_nCmdPos[0] == 64;
}
static BOOL ipuSETVQ(u32 val)
static __forceinline BOOL ipuSETVQ(u32 val)
{
g_nCmdPos[0] += getBits((u8*)vqclut+g_nCmdPos[0], 256-8*g_nCmdPos[0], 1); // 16*2*8
@ -804,17 +613,16 @@ static BOOL ipuSETVQ(u32 val)
}
// IPU Transfers are split into 8Qwords so we need to send ALL the data
static BOOL ipuCSC(u32 val)
static BOOL __fastcall ipuCSC(u32 val)
{
tIPU_CMD_CSC csc ={0, 0, 0, 0, 0};
*(u32*)&csc=val;
#ifdef IPU_LOG
IPU_LOG("IPU CSC(Colorspace conversion from YCbCr) command (%d).\n",csc.MBC);
if (csc.OFM){ IPU_LOG("Output format is RGB16. ");}
else{ IPU_LOG("Output format is RGB32. ");}
if (csc.DTE){ IPU_LOG("Dithering enabled."); }
#endif
//SysPrintf("CSC\n");
for (;g_nCmdIndex<(int)csc.MBC; g_nCmdIndex++){
@ -861,13 +669,13 @@ static BOOL ipuPACK(u32 val) {
tIPU_CMD_CSC csc ={0, 0, 0, 0, 0};
*(u32*)&csc=val;
#ifdef IPU_LOG
IPU_LOG("IPU PACK (Colorspace conversion from RGB32) command.\n");
if (csc.OFM){ IPU_LOG("Output format is RGB16. ");}
else{ IPU_LOG("Output format is INDX4. ");}
if (csc.DTE){ IPU_LOG("Dithering enabled."); }
IPU_LOG("Number of macroblocks to be converted: %d\n", csc.MBC);
#endif
for (;g_nCmdIndex<(int)csc.MBC; g_nCmdIndex++){
if( g_nCmdPos[0] < 512 ) {
@ -1409,9 +1217,8 @@ int getBits(u8 *address, u32 size, u32 advance)
case 1: address[0] = readmem[0];
case 0:
break;
#ifdef _MSC_VER
default: __assume(0);
#endif
jNO_DEFAULT
}
address += howmuch;
@ -1479,7 +1286,7 @@ void ipu_dither(struct macroblock_8 *mb8, struct macroblock_rgb16 *rgb16, int dt
}
void ipu_vq(struct macroblock_rgb16 *rgb16, u8* indx4){
SysPrintf("IPU: VQ not implemented");
Console::Error("IPU: VQ not implemented");
}
void ipu_copy(struct macroblock_8 *mb8, struct macroblock_16 *mb16) {

View File

@ -19,8 +19,6 @@
#ifndef __IPU_H__
#define __IPU_H__
#include "Common.h"
// IPU_INLINE_IRQS
// Scheduling ints into the future is a purist approach to emulation, and
// is mostly cosmetic since the emulator itself performs all actions instantly
@ -88,7 +86,7 @@ typedef union {
//
// Bitfield Structure
//
typedef union {
union tIPU_CTRL {
struct {
u32 IFC : 4; // Input FIFO counter
u32 OFC : 4; // Output FIFO counter
@ -107,7 +105,7 @@ typedef union {
u32 BUSY : 1; // Busy
};
u32 _u32;
} tIPU_CTRL;
};
#define IPU_BP_BP_M (0x7f<< 0)
#define IPU_BP_IFC_M (0x0f<< 8)
@ -188,6 +186,13 @@ struct IPUregisters {
#define ipuRegs ((IPUregisters*)(PS2MEM_HW+0x2000))
extern tIPU_BP g_BP;
extern int coded_block_pattern;
extern u16 FillInternalBuffer(u32 * pointer, u32 advance, u32 size);
extern int g_nIPU0Data; // or 0x80000000 whenever transferring
extern u8* g_pIPU0Pointer;
void dmaIPU0();
void dmaIPU1();
@ -197,18 +202,24 @@ void ipuShutdown();
int ipuFreeze(gzFile f, int Mode);
bool ipuCanFreeze();
void IPUCMD_WRITE(u32 val);
void ipuSoftReset();
u32 ipuRead32(u32 mem);
int ipuConstRead32(u32 x86reg, u32 mem);
u64 ipuRead64(u32 mem);
void ipuConstRead64(u32 mem, int mmreg);
void ipuWrite32(u32 mem,u32 value);
void ipuConstWrite32(u32 mem, int mmreg);
void ipuWrite64(u32 mem,u64 value);
void ipuConstWrite64(u32 mem, int mmreg);
namespace Dynarec
{
int ipuConstRead32(u32 x86reg, u32 mem);
void ipuConstRead64(u32 mem, int mmreg);
void ipuConstWrite32(u32 mem, int mmreg);
void ipuConstWrite64(u32 mem, int mmreg);
}
extern void IPUProcessInterrupt();
extern void ipu0Interrupt();
extern void ipu1Interrupt();
@ -217,4 +228,11 @@ u8 getBits16(u8 *address, u32 advance);
u8 getBits8(u8 *address, u32 advance);
int getBits(u8 *address, u32 size, u32 advance);
// returns number of qw read
int FIFOfrom_write(u32 * value, int size);
void FIFOfrom_read(void *value,int size);
int FIFOto_read(void *value);
int FIFOto_write(u32* pMem, int size);
void FIFOto_clear();
#endif

View File

@ -16,11 +16,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "PrecompiledHeader.h"
#include "PS2Etypes.h"
#include "coroutine.h"
struct coroutine {

View File

@ -32,13 +32,11 @@
#include "Vlc.h"
#include "coroutine.h"
extern void (* mpeg2_idct_copy) (s16 * block, u8* dest, int stride);
extern void (* __fastcall mpeg2_idct_copy) (s16 * block, u8* dest, int stride);
/* JayteeMaster: changed dest to 16 bit signed */
extern void (* mpeg2_idct_add) (int last, s16 * block,
extern void (* __fastcall mpeg2_idct_add) (int last, s16 * block,
/*u8*/s16* dest, int stride);
extern int FIFOfrom_write(u32* value, int size);
/* JayteeMaster: remove static attribute */
/*static */int non_linear_quantizer_scale [] = {
0, 1, 2, 3, 4, 5, 6, 7,
@ -47,8 +45,6 @@ extern int FIFOfrom_write(u32* value, int size);
56, 64, 72, 80, 88, 96, 104, 112
};
extern tIPU_BP g_BP;
/* Bitstream and buffer needs to be realocated inorder for sucessful
reading of the old data. Here the old data stored in the 2nd slot
of the internal buffer is copied to 1st slot, and the new data read
@ -907,12 +903,6 @@ static void slice_non_intra_DCT (decoder_t * const decoder,
mpeg2_idct_add (last, decoder->DCTblock, dest, stride);
}
extern int coded_block_pattern;
extern u16 FillInternalBuffer(u32 * pointer, u32 advance, u32 size);
extern decoder_t g_decoder;
extern int g_nIPU0Data; // or 0x80000000 whenever transferring
extern u8* g_pIPU0Pointer;
#if defined(_MSC_VER)
#pragma pack(push, 1)
#endif

View File

@ -25,7 +25,7 @@
#ifndef __MPEG_H__
#define __MPEG_H__
#include "PS2Etypes.h"
#include "Common.h"
/* macroblock modes */
#define MACROBLOCK_INTRA 1
@ -171,6 +171,7 @@ extern int get_motion_delta (decoder_t * const decoder, const int f_code);
extern int get_dmv (decoder_t * const decoder);
extern int non_linear_quantizer_scale[]; // JayteeMaster: it is needed in Ipu.c
extern decoder_t g_decoder;
void ipu_csc(struct macroblock_8 *mb8, struct macroblock_rgb32 *rgb32, int sgn);
void ipu_dither(struct macroblock_8 *mb8, struct macroblock_rgb16 *rgb16, int dte);

View File

@ -22,8 +22,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include "PrecompiledHeader.h"
#include "mpeg2lib/Mpeg.h"
#include "yuv2rgb.h"
@ -34,16 +33,16 @@ struct convert_rgb_t {
int width;
int uv_stride, uv_stride_frame;
int rgb_stride, rgb_stride_frame;
void (* yuv2rgb) (u8 *, u8 *, u8 *, u8 *,
void (__fastcall * yuv2rgb) (u8 *, u8 *, u8 *, u8 *,
void *, void *, int);
};
typedef void yuv2rgb_copy (void * id, u8 * const * src,
typedef void __fastcall yuv2rgb_copy (void * id, u8 * const * src,
unsigned int v_offset);
yuv2rgb_copy * yuv2rgb_init_mmxext (int bpp, int mode);
yuv2rgb_copy * yuv2rgb_init_mmx (int bpp, int mode);
yuv2rgb_copy * yuv2rgb_init_mlib (int bpp, int mode);
yuv2rgb_copy __fastcall * yuv2rgb_init_mmxext (int bpp, int mode);
yuv2rgb_copy __fastcall * yuv2rgb_init_mmx (int bpp, int mode);
yuv2rgb_copy __fastcall * yuv2rgb_init_mlib (int bpp, int mode);
//#include "convert_internal.h" //END
static u32 matrix_coefficients = 6;
@ -59,7 +58,7 @@ const s32 Inverse_Table_6_9[8][4] = {
{117579, 136230, 16907, 35559} /*7 SMPTE 240M (1987) */
};
typedef void yuv2rgb_c_internal (u8 *, u8 *, u8 *, u8 *,
typedef void __fastcall yuv2rgb_c_internal (u8 *, u8 *, u8 *, u8 *,
void *, void *, int);
void * table_rV[256];
@ -92,7 +91,7 @@ void * table_bU[256];
Y = py[2*i+1]; \
dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];
static void yuv2rgb_c_32 (u8 * py_1, u8 * py_2,
static void __fastcall yuv2rgb_c_32 (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
@ -131,7 +130,7 @@ static void yuv2rgb_c_32 (u8 * py_1, u8 * py_2,
}
/* This is very near from the yuv2rgb_c_32 code */
static void yuv2rgb_c_24_rgb (u8 * py_1, u8 * py_2,
static void __fastcall yuv2rgb_c_24_rgb (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
@ -170,7 +169,7 @@ static void yuv2rgb_c_24_rgb (u8 * py_1, u8 * py_2,
}
/* only trivial mods from yuv2rgb_c_24_rgb */
static void yuv2rgb_c_24_bgr (u8 * py_1, u8 * py_2,
static void __fastcall yuv2rgb_c_24_bgr (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
@ -210,7 +209,7 @@ static void yuv2rgb_c_24_bgr (u8 * py_1, u8 * py_2,
/* This is exactly the same code as yuv2rgb_c_32 except for the types of */
/* r, g, b, dst_1, dst_2 */
static void yuv2rgb_c_16 (u8 * py_1, u8 * py_2,
static void __fastcall yuv2rgb_c_16 (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
@ -256,7 +255,7 @@ static int div_round (int dividend, int divisor)
return -((-dividend + (divisor>>1)) / divisor);
}
static yuv2rgb_c_internal * yuv2rgb_c_init (int order, int bpp)
static yuv2rgb_c_internal __fastcall * yuv2rgb_c_init (int order, int bpp)
{
int i;
u8 table_Y[1024];
@ -369,7 +368,7 @@ static yuv2rgb_c_internal * yuv2rgb_c_init (int order, int bpp)
return yuv2rgb;
}
static void convert_yuv2rgb_c (void * _id, u8 * Y, u8 * Cr, u8 * Cb,
static void __fastcall convert_yuv2rgb_c (void * _id, u8 * Y, u8 * Cr, u8 * Cb,
unsigned int v_offset)
{
convert_rgb_t * id = (convert_rgb_t *) _id;
@ -393,7 +392,7 @@ static void convert_yuv2rgb_c (void * _id, u8 * Y, u8 * Cr, u8 * Cb,
} while (--loop);
}
static void convert_start (void * _id, u8 * dest, int flags)
static void __fastcall convert_start (void * _id, u8 * dest, int flags)
{
convert_rgb_t * id = (convert_rgb_t *) _id;
id->rgb_ptr = dest;
@ -411,7 +410,7 @@ static void convert_start (void * _id, u8 * dest, int flags)
}
}
static void convert_internal (int order, int bpp, int width, int height,
static void __fastcall convert_internal (int order, int bpp, int width, int height,
u32 accel, void * arg,
convert_init_t * result)
{
@ -449,55 +448,55 @@ static void convert_internal (int order, int bpp, int width, int height,
}
}
void convert_rgb32 (int width, int height, u32 accel, void * arg,
void __fastcall convert_rgb32 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 32, width, height, accel, arg, result);
}
void convert_rgb24 (int width, int height, u32 accel, void * arg,
void __fastcall convert_rgb24 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 24, width, height, accel, arg, result);
}
void convert_rgb16 (int width, int height, u32 accel, void * arg,
void __fastcall convert_rgb16 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 16, width, height, accel, arg, result);
}
void convert_rgb15 (int width, int height, u32 accel, void * arg,
void __fastcall convert_rgb15 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 15, width, height, accel, arg, result);
}
void convert_bgr32 (int width, int height, u32 accel, void * arg,
void __fastcall convert_bgr32 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 32, width, height, accel, arg, result);
}
void convert_bgr24 (int width, int height, u32 accel, void * arg,
void __fastcall convert_bgr24 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 24, width, height, accel, arg, result);
}
void convert_bgr16 (int width, int height, u32 accel, void * arg,
void __fastcall convert_bgr16 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 16, width, height, accel, arg, result);
}
void convert_bgr15 (int width, int height, u32 accel, void * arg,
void __fastcall convert_bgr15 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 15, width, height, accel, arg, result);
}
convert_t* convert_rgb (int order, int bpp)
convert_t __fastcall * convert_rgb (int order, int bpp)
{
if (order == CONVERT_RGB || order == CONVERT_BGR)
switch (bpp) {

View File

@ -34,11 +34,11 @@ struct convert_init_t {
void * id;
int id_size;
int buf_size[3];
void (* start) (void * id, u8 * dest, int flags);
void (* copy) (void * id, u8 * Y, u8 * Cr, u8 * Cb, unsigned int v_offset);
void (__fastcall* start) (void * id, u8 * dest, int flags);
void (__fastcall* copy) (void * id, u8 * Y, u8 * Cr, u8 * Cb, unsigned int v_offset);
};
typedef void convert_t (int width, int height, u32 accel, void * arg,
typedef void __fastcall convert_t (int width, int height, u32 accel, void * arg,
convert_init_t * result);
convert_t convert_rgb32;
@ -52,6 +52,6 @@ convert_t convert_bgr15;
#define CONVERT_RGB 0
#define CONVERT_BGR 1
convert_t * convert_rgb (int order, int bpp);
convert_t __fastcall * convert_rgb (int order, int bpp);
#endif /* YUV2RGB_H */

View File

@ -18,6 +18,7 @@
//all tables for R5900 are define here..
#include "PrecompiledHeader.h"
#include "InterTables.h"
#include "R5900.h"

View File

@ -605,23 +605,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -630,7 +613,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -639,7 +621,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -648,7 +629,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
@ -661,7 +641,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -670,7 +649,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -679,7 +657,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
@ -688,7 +665,6 @@
<Tool
Name="VCCLCompilerTool"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
@ -756,47 +732,6 @@
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (dev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vm (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
</File>
@ -1235,14 +1170,6 @@
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\x86\ix86\ix86.h"
@ -1291,14 +1218,6 @@
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\x86\ix86\ix86_cpudetect.cpp"
@ -1379,14 +1298,6 @@
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\x86\ix86\ix86_mmx.cpp"
@ -1431,14 +1342,6 @@
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\x86\ix86\ix86_sse.cpp"
@ -1483,14 +1386,6 @@
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\x86\ix86\ix86_tools.cpp"
@ -2405,47 +2300,6 @@
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (dev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vm (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
@ -2785,47 +2639,6 @@
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (dev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vm (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
@ -2840,14 +2653,6 @@
<File
RelativePath="..\..\Ipu\IPU.cpp"
>
</File>
<File
RelativePath="..\..\Ipu\IPU.h"
>
</File>
<File
RelativePath="..\..\Ipu\yuv2rgb.cpp"
>
<FileConfiguration
Name="Release vm (dev)|Win32"
>
@ -2897,6 +2702,21 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\Ipu\IPU.h"
>
</File>
<File
RelativePath="..\..\Ipu\yuv2rgb.cpp"
>
<FileConfiguration
Name="Release vm (dev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\Ipu\yuv2rgb.h"
>
@ -2912,47 +2732,6 @@
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (dev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vm (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
@ -2964,47 +2743,6 @@
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (dev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vm (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (nondev)|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
@ -3017,6 +2755,14 @@
>
</File>
</Filter>
<Filter
Name="Dynarec"
>
<File
RelativePath="..\..\x86\iIPU.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="memory"

208
pcsx2/x86/iIPU.cpp Normal file
View File

@ -0,0 +1,208 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2008 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "iR5900.h"
#include "IPU.h"
namespace Dynarec
{
using namespace Dynarec::R5900;
///////////////////////////////////////////////////////////////////////
// IPU Register Reads
int ipuConstRead32(u32 x86reg, u32 mem)
{
int workingreg, tempreg, tempreg2;
iFlushCall(0);
CALLFunc((u32)IPUProcessInterrupt);
// if( !(x86reg&(MEM_XMMTAG|MEM_MMXTAG)) ) {
// if( x86reg == EAX ) {
// tempreg = ECX;
// tempreg2 = EDX;
// }
// else if( x86reg == ECX ) {
// tempreg = EAX;
// tempreg2 = EDX;
// }
// else if( x86reg == EDX ) {
// tempreg = EAX;
// tempreg2 = ECX;
// }
//
// workingreg = x86reg;
// }
// else {
workingreg = EAX;
tempreg = ECX;
tempreg2 = EDX;
// }
switch (mem){
case 0x10002010: // IPU_CTRL
MOV32MtoR(workingreg, (u32)&ipuRegs->ctrl._u32);
AND32ItoR(workingreg, ~0x3f0f); // save OFC
OR8MtoR(workingreg, (u32)&g_BP.IFC);
OR8MtoR(workingreg+4, (u32)&coded_block_pattern); // or ah, mem
// MOV32MtoR(workingreg, (u32)&ipuRegs->ctrl._u32);
// AND32ItoR(workingreg, ~0x3fff);
// MOV32MtoR(tempreg, (u32)&g_nIPU0Data);
// MOV8MtoR(workingreg, (u32)&g_BP.IFC);
//
// CMP32ItoR(tempreg, 8);
// j8Ptr[5] = JLE8(0);
// MOV32ItoR(tempreg, 8);
// x86SetJ8( j8Ptr[5] );
// SHL32ItoR(tempreg, 4);
//
// OR8MtoR(workingreg+4, (u32)&coded_block_pattern); // or ah, mem
// OR8RtoR(workingreg, tempreg);
#ifdef _DEBUG
MOV32RtoM((u32)&ipuRegs->ctrl._u32, workingreg);
#endif
// NOTE: not updating ipuRegs->ctrl
// if( x86reg & MEM_XMMTAG ) SSE2_MOVD_R_to_XMM(x86reg&0xf, workingreg);
// else if( x86reg & MEM_MMXTAG ) MOVD32RtoMMX(x86reg&0xf, workingreg);
return 1;
case 0x10002020: // IPU_BP
assert( (u32)&g_BP.FP + 1 == (u32)&g_BP.bufferhasnew );
MOVZX32M8toR(workingreg, (u32)&g_BP.BP);
MOVZX32M8toR(tempreg, (u32)&g_BP.FP);
AND8ItoR(workingreg, 0x7f);
ADD8MtoR(tempreg, (u32)&g_BP.bufferhasnew);
MOV8MtoR(workingreg+4, (u32)&g_BP.IFC);
SHL32ItoR(tempreg, 16);
OR32RtoR(workingreg, tempreg);
#ifdef _DEBUG
MOV32RtoM((u32)&ipuRegs->ipubp, workingreg);
#endif
// NOTE: not updating ipuRegs->ipubp
// if( x86reg & MEM_XMMTAG ) SSE2_MOVD_R_to_XMM(x86reg&0xf, workingreg);
// else if( x86reg & MEM_MMXTAG ) MOVD32RtoMMX(x86reg&0xf, workingreg);
return 1;
default:
// ipu repeats every 0x100
_eeReadConstMem32(x86reg, (u32)(((u8*)ipuRegs)+(mem&0xff)));
return 0;
}
return 0;
}
void ipuConstRead64(u32 mem, int mmreg)
{
iFlushCall(0);
CALLFunc((u32)IPUProcessInterrupt);
if( IS_XMMREG(mmreg) ) SSE_MOVLPS_M64_to_XMM(mmreg&0xff, (u32)(((u8*)ipuRegs)+(mem&0xff)));
else {
MOVQMtoR(mmreg, (u32)(((u8*)ipuRegs)+(mem&0xff)));
SetMMXstate();
}
}
///////////////////////////////////////////////////////////////////////
// IPU Register Writes!
void ipuConstWrite32(u32 mem, int mmreg)
{
iFlushCall(0);
if( !(mmreg & (MEM_XMMTAG|MEM_MMXTAG|MEM_EECONSTTAG)) ) PUSH32R(mmreg);
CALLFunc((u32)IPUProcessInterrupt);
switch (mem){
case 0x10002000: // IPU_CMD
if( (mmreg & (MEM_XMMTAG|MEM_MMXTAG|MEM_EECONSTTAG)) ) _recPushReg(mmreg);
CALLFunc((u32)IPUCMD_WRITE);
ADD32ItoR(ESP, 4);
break;
case 0x10002010: // IPU_CTRL
if( mmreg & MEM_EECONSTTAG ) {
u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]&0x47f30000;
if( c & 0x40000000 ) {
CALLFunc((u32)ipuSoftReset);
}
else {
AND32ItoM((u32)&ipuRegs->ctrl._u32, 0x8000ffff);
OR32ItoM((u32)&ipuRegs->ctrl._u32, c);
}
}
else {
if( mmreg & MEM_XMMTAG ) SSE2_MOVD_XMM_to_R(EAX, mmreg&0xf);
else if( mmreg & MEM_MMXTAG ) MOVD32MMXtoR(EAX, mmreg&0xf);
else POP32R(EAX);
MOV32MtoR(ECX, (u32)&ipuRegs->ctrl._u32);
AND32ItoR(EAX, 0x47f30000);
AND32ItoR(ECX, 0x8000ffff);
OR32RtoR(EAX, ECX);
MOV32RtoM((u32)&ipuRegs->ctrl._u32, EAX);
TEST32ItoR(EAX, 0x40000000);
j8Ptr[5] = JZ8(0);
// reset
CALLFunc((u32)ipuSoftReset);
x86SetJ8( j8Ptr[5] );
}
break;
default:
if( !(mmreg & (MEM_XMMTAG|MEM_MMXTAG|MEM_EECONSTTAG)) ) POP32R(mmreg);
_eeWriteConstMem32((u32)((u8*)ipuRegs + (mem&0xfff)), mmreg);
break;
}
}
void ipuConstWrite64(u32 mem, int mmreg)
{
iFlushCall(0);
CALLFunc((u32)IPUProcessInterrupt);
switch (mem){
case 0x10002000:
_recPushReg(mmreg);
CALLFunc((u32)IPUCMD_WRITE);
ADD32ItoR(ESP, 4);
break;
default:
_eeWriteConstMem64( (u32)((u8*)ipuRegs + (mem&0xfff)), mmreg);
break;
}
}
}

View File

@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "ix86.h"
/**********************/

View File

@ -16,8 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <string.h>
#include "PrecompiledHeader.h"
#include "ix86.h"
/********************/

View File

@ -16,10 +16,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "ix86.h"
#include <assert.h>
/********************/
/* MMX instructions */
/********************/

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "PrecompiledHeader.h"
#include "ix86.h"
PCSX2_ALIGNED16(unsigned int p[4]);