wxGui: performing maintenance merge before weekend departure.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1120 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-05-02 14:06:06 +00:00
commit 0238815248
168 changed files with 8514 additions and 6176 deletions

View File

@ -6,13 +6,13 @@
# Uncomment if building by itself, rather then with all the plugins
#Normal
#export PCSX2OPTIONS="--enable-sse3 --enable-sse4 --prefix `pwd`"
#export PCSX2OPTIONS="--prefix `pwd`"
#Optimized, but a devbuild
export PCSX2OPTIONS="--enable-sse3 --enable-sse4 --enable-devbuild --prefix `pwd`"
export PCSX2OPTIONS="--enable-devbuild --prefix `pwd`"
#Debug / Devbuild version
#export PCSX2OPTIONS="--enable-debug --enable-devbuild --enable-sse3 --prefix `pwd`"
#export PCSX2OPTIONS="--enable-debug --enable-devbuild --prefix `pwd`"
#ZeroGS Normal mode
export ZEROGSOPTIONS="--enable-sse2"

View File

@ -48,13 +48,7 @@
*/
#include "PS2Etypes.h"
/* common defines */
#ifndef C_ASSERT
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#endif
#include "Pcsx2Defs.h"
#if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) || \
defined(SPU2defs) || defined(CDVDdefs) || defined(DEV9defs) || \

View File

@ -15,223 +15,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
// This file is just for backwards compatability.
#ifndef __PS2ETYPES_H__
#define __PS2ETYPES_H__
#include <stddef.h>
#if defined (__linux__) && !defined(__LINUX__) // some distributions are lower case
#define __LINUX__
#endif
#ifdef __CYGWIN__
#define __LINUX__
#endif
// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air)
#ifndef ArraySize
#define ArraySize(x) (sizeof(x)/sizeof((x)[0]))
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// jASSUME - give hints to the optimizer
// This is primarily useful for the default case switch optimizer, which enables VC to
// generate more compact switches.
#ifdef NDEBUG
# define jBREAKPOINT() ((void) 0)
# ifdef _MSC_VER
# define jASSUME(exp) (__assume(exp))
# else
# define jASSUME(exp) ((void) sizeof(exp))
# endif
#else
# if defined(_MSC_VER)
# define jBREAKPOINT() do { __asm int 3 } while(0)
# else
# define jBREAKPOINT() ((void) *(volatile char *) 0)
# endif
# define jASSUME(exp) if(exp) ; else jBREAKPOINT()
#endif
// disable the default case in a switch
#define jNO_DEFAULT \
{ \
default: \
jASSUME(0); \
break; \
}
//////////////////////////////////////////////////////////////////////////////////////////
// Basic Atomic Types
#if defined(_MSC_VER)
typedef __int8 s8;
typedef __int16 s16;
typedef __int32 s32;
typedef __int64 s64;
typedef unsigned __int8 u8;
typedef unsigned __int16 u16;
typedef unsigned __int32 u32;
typedef unsigned __int64 u64;
typedef unsigned int uint;
// Note: building the 'extern' into PCSX2_ALIGNED16_DECL fixes Visual Assist X's intellisense.
#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
#define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
#define __naked __declspec(naked)
#define __unused /*unused*/
#define __noinline __declspec(noinline)
#define CALLBACK __stdcall
#else // _MSC_VER
#ifdef __LINUX__
#ifdef HAVE_STDINT_H
#include "stdint.h"
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef uintptr_t uptr;
typedef intptr_t sptr;
#else // HAVE_STDINT_H
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
#endif // HAVE_STDINT_H
typedef unsigned int uint;
#define LONG long
typedef union _LARGE_INTEGER
{
long long QuadPart;
} LARGE_INTEGER;
#define __fastcall __attribute__((fastcall))
#define __unused __attribute__((unused))
#define _inline __inline__ __attribute__((unused))
#define __forceinline __attribute__((always_inline,unused))
#define __noinline __attribute__((noinline))
#define __naked // GCC lacks the naked specifier
#define CALLBACK // CALLBACK is win32-specific mess
#endif // __LINUX__
#define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig)))
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
// fixme - is this needed for recent versions of GCC? Or can we just use the macros
// above instead for both definitions (implementations) and declarations (includes)? -- air
#define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig)))
#define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16)))
#endif // _MSC_VER
#if !defined(__LINUX__) || !defined(HAVE_STDINT_H)
#if defined(__x86_64__)
typedef u64 uptr;
typedef s64 sptr;
#else
typedef u32 uptr;
typedef s32 sptr;
#endif
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// A rough-and-ready cross platform 128-bit datatype, Non-SSE style.
#ifdef __cplusplus
struct u128
{
u64 lo;
u64 hi;
// Implicit conversion from u64
u128( u64 src ) :
lo( src )
, hi( 0 ) {}
// Implicit conversion from u32
u128( u32 src ) :
lo( src )
, hi( 0 ) {}
};
struct s128
{
s64 lo;
s64 hi;
// Implicit conversion from u64
s128( s64 src ) :
lo( src )
, hi( 0 ) {}
// Implicit conversion from u32
s128( s32 src ) :
lo( src )
, hi( 0 ) {}
};
#else
typedef union _u128_t
{
u64 lo;
u64 hi;
} u128;
typedef union _s128_t
{
s64 lo;
s64 hi;
} s128;
#endif
typedef struct {
int size;
s8 *data;
} freezeData;
// event values:
#define KEYPRESS 1
#define KEYRELEASE 2
typedef struct _keyEvent {
u32 key;
u32 evt;
} keyEvent;
/* common defines */
#ifndef C_ASSERT
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#endif
// This brings in both all the things that used to be in PS2types.h that weren't type related,
// and also brings Pcsx2Types in.
#include "Pcsx2Defs.h"
#endif /* __PS2ETYPES_H__ */

View File

@ -54,7 +54,6 @@ extern SessionOverrideFlags g_Session;
#define PCSX2_FRAMELIMIT_NORMAL 0x000
#define PCSX2_FRAMELIMIT_LIMIT 0x400
#define PCSX2_FRAMELIMIT_SKIP 0x800
#define PCSX2_FRAMELIMIT_VUSKIP 0xc00
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK)

View File

@ -29,6 +29,8 @@
# endif
#endif
#include "Pcsx2Types.h"
// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air)
#ifndef ArraySize
#define ArraySize(x) (sizeof(x)/sizeof((x)[0]))
@ -58,8 +60,6 @@
// disable the default case in a switch
#define jNO_DEFAULT \
{ \
break; \
\
default: \
jASSUME(0); \
break; \
@ -79,6 +79,8 @@ default: \
#define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
#define __naked __declspec(naked)
#define __unused /*unused*/
#define __noinline __declspec(noinline)
#define CALLBACK __stdcall
#else
@ -98,6 +100,7 @@ default: \
#define __unused __attribute__((unused))
#define _inline __inline__ __attribute__((unused))
#define __forceinline __attribute__((always_inline,unused))
#define __noinline __attribute__((noinline))
#endif
typedef struct {

View File

@ -19,8 +19,6 @@
#ifndef __PCSX2TYPES_H__
#define __PCSX2TYPES_H__
// Note; this header is experamental, and will be a shifting target. Only use this if you are willing to repeatedly fix breakage.
/*
* Based on PS2E Definitions by
linuzappz@hotmail.com,
@ -45,12 +43,10 @@ typedef unsigned __int32 u32;
typedef unsigned __int64 u64;
typedef unsigned int uint;
typedef u32 uptr;
typedef s32 sptr;
#else // _MSC_VER
#else // _MSC_VER*/
#ifdef __LINUX__
#ifdef __LINUX__
#ifdef HAVE_STDINT_H
#include "stdint.h"
@ -86,9 +82,6 @@ typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef u32 uptr;
typedef s32 sptr;
#endif // HAVE_STDINT_H
typedef unsigned int uint;
@ -102,6 +95,15 @@ typedef union _LARGE_INTEGER
#endif // __LINUX__
#endif //_MSC_VER
#if !defined(__LINUX__) || !defined(HAVE_STDINT_H)
#if defined(__x86_64__)
typedef u64 uptr;
typedef s64 sptr;
#else
typedef u32 uptr;
typedef s32 sptr;
#endif
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// A rough-and-ready cross platform 128-bit datatype, Non-SSE style.
@ -154,4 +156,4 @@ typedef union _s128_t
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -62,8 +62,8 @@ struct cdvdStruct {
u32 Sector;
int nSectors;
int Readed;
int Reading;
int Readed; // change to bool. --arcum42
int Reading; // same here.
int ReadMode;
int BlockSize; // Total bytes transfered at 1x speed
int Speed;
@ -89,56 +89,227 @@ struct cdvdStruct {
bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay
};
/*
Interrupts - values are flag bits.
0x00 No interrupt
0x01 Data Ready
0x02 Command Complete
0x03 Acknowledge (reserved)
0x04 End of Data Detected
0x05 Error Detected
0x06 Drive Not Ready
In limited experimentation I found that PS2 apps respond actively to use of the
'Data Ready' flag -- in that they'll almost immediately initiate a DMA transfer
after receiving an Irq with that as the cause. But the question is, of course,
*when* to use it. Adding it into some locations of CDVD reading only slowed
games down and broke things.
Using Drive Not Ready also invokes basic error handling from the Iop Bios, but
without proper emulation of the cdvd status flag it also tends to break things.
*/
enum CdvdIrqId
{
Irq_None = 0
, Irq_DataReady = 0
, Irq_CommandComplete
, Irq_Acknowledge
, Irq_EndOfData
, Irq_Error
, Irq_NotReady
};
/* is cdvd.Status only for NCMDS? (linuzappz) */
enum cdvdStatus
{
CDVD_STATUS_NONE = 0x00, // not sure ;)
CDVD_STATUS_SEEK_COMPLETE = 0x0A,
};
enum cdvdready
{
CDVD_NOTREADY = 0x00,
CDVD_READY1 = 0x40,
CDVD_READY2 = 0x4e // This is used in a few places for some reason.
//It would be worth checking if this was just a typo made at some point.
};
// Cdvd actions tell the emulator how and when to respond to certain requests.
// Actions are handled by the cdvdInterrupt()
enum cdvdActions
{
cdvdAction_None = 0
, cdvdAction_Seek
, cdvdAction_Standby
, cdvdAction_Stop
, cdvdAction_Break
, cdvdAction_Read // note: not used yet.
};
//////////////////////////////////////////////////////////////////////////////////////////
// Cdvd Block Read Cycle Timings
//
// The PS2 CDVD effectively has two seek modes -- the normal/slow one (est. avg seeks being
// around 120-160ms), and a faster seek which has an estimated seek time of about 35-40ms.
// Fast seeks happen when the destination sector is within a certain range of the starting
// point, such that abs(start-dest) is less than the value in the tbl_FastSeekDelta.
//
// CDVDs also have a secondary seeking method used when the destination is close enough
// that a contiguous sector read can reach the sector faster than initiating a full seek.
// Typically this value is very low.
enum CDVD_MODE_TYPE
{
MODE_CDROM = 0,
MODE_DVDROM,
};
static const uint tbl_FastSeekDelta[3] =
{
4371, // CD-ROM
14764, // Single-layer DVD-ROM
13360 // dual-layer DVD-ROM [currently unused]
};
// if a seek is within this many blocks, read instead of seek.
// These values are arbitrary assumptions. Not sure what the real PS2 uses.
static const uint tbl_ContigiousSeekDelta[3] =
{
8, // CD-ROM
16, // single-layer DVD-ROM
16, // dual-layer DVD-ROM [currently unused]
};
// Note: DVD read times are modified to be faster, because games seem to be a lot more
// concerned with accurate(ish) seek delays and less concerned with actual block read speeds.
// Translation: it's a minor speedhack :D
static const uint PSX_CD_READSPEED = 153600; // 1 Byte Time @ x1 (150KB = cd x 1)
static const uint PSX_DVD_READSPEED = 1382400 + 256000; // normal is 1 Byte Time @ x1 (1350KB = dvd x 1).
// Legacy Note: FullSeek timing causes many games to load very slow, but it likely not the real problem.
// Games breaking with it set to PSXCLK*40 : "wrath unleashed" and "Shijou Saikyou no Deshi Kenichi".
static const uint Cdvd_FullSeek_Cycles = (PSXCLK*100) / 1000; // average number of cycles per fullseek (100ms)
static const uint Cdvd_FastSeek_Cycles = (PSXCLK*30) / 1000; // average number of cycles per fastseek (37ms)
static const __unused char *mg_zones[8] = {"Japan", "USA", "Europe", "Oceania", "Asia", "Russia", "China", "Mexico"};
static const __unused char *nCmdName[0x100]= {
"CdSync",
"CdNop",
"CdStandby",
"CdStop",
"CdPause",
"CdSeek",
"CdRead",
"CdReadCDDA",
"CdReadDVDV",
"CdGetToc",
"",
"NCMD_B",
"CdReadKey",
"",
"sceCdReadXCDDA",
"sceCdChgSpdlCtrl",
};
enum nCmds
{
N_CD_SYNC = 0x00, // CdSync
N_CD_NOP = 0x01, // CdNop
N_CD_STANDBY = 0x02, // CdStandby
N_CD_STOP = 0x03, // CdStop
N_CD_PAUSE = 0x04, // CdPause
N_CD_SEEK = 0x05, // CdSeek
N_CD_READ = 0x06, // CdRead
N_CD_READ_CDDA = 0x07, // CdReadCDDA
N_DVD_READ = 0x08, // DvdRead
N_CD_GET_TOC = 0x09, // CdGetToc & cdvdman_call19
N_CMD_B = 0x0B, // CdReadKey
N_CD_READ_KEY = 0x0C, // CdReadKey
N_CD_READ_XCDDA = 0x0E, // CdReadXCDDA
N_CD_CHG_SPDL_CTRL = 0x0F, // CdChgSpdlCtrl
};
static const __unused char *sCmdName[0x100]= {
"", "sceCdGetDiscType", "sceCdReadSubQ", "subcommands",//sceCdGetMecaconVersion, read/write console id, read renewal date
"", "sceCdTrayState", "sceCdTrayCtrl", "",
"sceCdReadClock", "sceCdWriteClock", "sceCdReadNVM", "sceCdWriteNVM",
"sceCdSetHDMode", "", "", "sceCdPowerOff",
"", "", "sceCdReadILinkID", "sceCdWriteILinkID", /*10*/
"sceAudioDigitalOut", "sceForbidDVDP", "sceAutoAdjustCtrl", "sceCdReadModelNumber",
"sceWriteModelNumber", "sceCdForbidCD", "sceCdBootCertify", "sceCdCancelPOffRdy",
"sceCdBlueLEDCtl", "", "sceRm2Read", "sceRemote2_7",//Rm2PortGetConnection?
"sceRemote2_6", "sceCdWriteWakeUpTime", "sceCdReadWakeUpTime", "", /*20*/
"sceCdRcBypassCtl", "", "", "",
"", "sceCdNoticeGameStart", "", "",
"sceCdXBSPowerCtl", "sceCdXLEDCtl", "sceCdBuzzerCtl", "",
"", "sceCdSetMediumRemoval", "sceCdGetMediumRemoval", "sceCdXDVRPReset", /*30*/
"", "", "__sceCdReadRegionParams", "__sceCdReadMAC",
"__sceCdWriteMAC", "", "", "",
"", "", "__sceCdWriteRegionParams", "",
"sceCdOpenConfig", "sceCdReadConfig", "sceCdWriteConfig", "sceCdCloseConfig", /*40*/
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "", /*50*/
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "", /*60*/
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "", /*70*/
"", "", "", "",
"", "", "", "",
"", "", "", "",
"mechacon_auth_0x80", "mechacon_auth_0x81", "mechacon_auth_0x82", "mechacon_auth_0x83", /*80*/
"mechacon_auth_0x84", "mechacon_auth_0x85", "mechacon_auth_0x86", "mechacon_auth_0x87",
"mechacon_auth_0x88", "", "", "",
"", "sceMgWriteData", "sceMgReadData", "mechacon_auth_0x8F",
"sceMgWriteHeaderStart", "sceMgReadBITLength", "sceMgWriteDatainLength", "sceMgWriteDataoutLength", /*90*/
"sceMgReadKbit", "sceMgReadKbit2", "sceMgReadKcon", "sceMgReadKcon2",
"sceMgReadIcvPs2", "", "", "",
"", "", "", "",
/*A0, no sCmds above?*/
};
// NVM (eeprom) layout info
struct NVMLayout {
u32 biosVer; // bios version that this eeprom layout is for
s32 config0; // offset of 1st config block
s32 config1; // offset of 2nd config block
s32 config2; // offset of 3rd config block
s32 consoleId; // offset of console id (?)
s32 ilinkId; // offset of ilink id (ilink mac address)
s32 modelNum; // offset of ps2 model number (eg "SCPH-70002")
s32 regparams; // offset of RegionParams for PStwo
s32 mac; // offset of the value written to 0xFFFE0188 and 0xFFFE018C on PStwo
};
#define NVM_FORMAT_MAX 2
static NVMLayout nvmlayouts[NVM_FORMAT_MAX] =
{
{0x000, 0x280, 0x300, 0x200, 0x1C8, 0x1C0, 0x1A0, 0x180, 0x198}, // eeproms from bios v0.00 and up
{0x146, 0x270, 0x2B0, 0x200, 0x1C8, 0x1E0, 0x1B0, 0x180, 0x198}, // eeproms from bios v1.70 and up
};
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
void cdvdReset();
void cdvdVsync();
extern void cdvdActionInterrupt();
extern void cdvdReadInterrupt();
void cdvdNewDiskCB();
u8 cdvdRead04(void);
u8 cdvdRead05(void);
u8 cdvdRead06(void);
u8 cdvdRead07(void);
u8 cdvdRead08(void);
u8 cdvdRead0A(void);
u8 cdvdRead0B(void);
u8 cdvdRead0C(void);
u8 cdvdRead0D(void);
u8 cdvdRead0E(void);
u8 cdvdRead0F(void);
u8 cdvdRead13(void);
u8 cdvdRead15(void);
u8 cdvdRead16(void);
u8 cdvdRead17(void);
u8 cdvdRead18(void);
u8 cdvdRead20(void);
u8 cdvdRead21(void);
u8 cdvdRead22(void);
u8 cdvdRead23(void);
u8 cdvdRead24(void);
u8 cdvdRead28(void);
u8 cdvdRead29(void);
u8 cdvdRead2A(void);
u8 cdvdRead2B(void);
u8 cdvdRead2C(void);
u8 cdvdRead30(void);
u8 cdvdRead31(void);
u8 cdvdRead32(void);
u8 cdvdRead33(void);
u8 cdvdRead34(void);
u8 cdvdRead38(void);
u8 cdvdRead39(void);
u8 cdvdRead3A(void);
void cdvdWrite04(u8 rt);
void cdvdWrite05(u8 rt);
void cdvdWrite06(u8 rt);
void cdvdWrite07(u8 rt);
void cdvdWrite08(u8 rt);
void cdvdWrite0A(u8 rt);
void cdvdWrite0F(u8 rt);
void cdvdWrite14(u8 rt);
void cdvdWrite16(u8 rt);
void cdvdWrite17(u8 rt);
void cdvdWrite18(u8 rt);
void cdvdWrite3A(u8 rt);
u8 cdvdRead(u8 key);
void cdvdWrite(u8 key, u8 rt);
#endif /* __CDVD_H__ */

View File

@ -85,9 +85,6 @@ u8 Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 };
//#define cdReadTime ((PSXCLK / 75) / BIAS)
unsigned long cdReadTime;// = ((PSXCLK / 75) / BIAS);
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
#define CDR_INT(eCycle) PSX_INT(IopEvt_Cdrom, eCycle)
#define CDREAD_INT(eCycle) PSX_INT(IopEvt_CdromRead, eCycle)
@ -112,13 +109,13 @@ static __forceinline void StopCdda() {
}
}
__forceinline void SetResultSize(u8 size) {
static __forceinline void SetResultSize(u8 size) {
cdr.ResultP = 0;
cdr.ResultC = size;
cdr.ResultReady = 1;
}
__forceinline s32 MSFtoLSN(u8 *Time) {
static __forceinline s32 MSFtoLSN(u8 *Time) {
u32 lsn;
lsn = Time[2];
@ -127,7 +124,7 @@ __forceinline s32 MSFtoLSN(u8 *Time) {
return lsn;
}
void LSNtoMSF(u8 *Time, s32 lsn) {
static __forceinline void LSNtoMSF(u8 *Time, s32 lsn) {
lsn += 150;
Time[2] = lsn / 4500; // minuten
lsn = lsn - Time[2] * 4500; // minuten rest
@ -135,7 +132,7 @@ void LSNtoMSF(u8 *Time, s32 lsn) {
Time[0] = lsn - Time[1] * 75; // sekunden rest
}
void ReadTrack() {
static void ReadTrack() {
cdr.Prev[0] = itob(cdr.SetSector[0]);
cdr.Prev[1] = itob(cdr.SetSector[1]);
cdr.Prev[2] = itob(cdr.SetSector[2]);
@ -152,7 +149,7 @@ void ReadTrack() {
#define DataEnd 4
#define DiskError 5
void AddIrqQueue(u8 irq, unsigned long ecycle) {
static void AddIrqQueue(u8 irq, unsigned long ecycle) {
cdr.Irq = irq;
if (cdr.Stat) {
cdr.eCycle = ecycle;

View File

@ -72,12 +72,10 @@ struct cdrStruct
char Unused[4087];
};
extern cdrStruct cdr;
s32 MSFtoLSN(u8 *Time);
void LSNtoMSF(u8 *Time, s32 lsn);
void AddIrqQueue(u8 irq, unsigned long ecycle);
extern cdrStruct cdr;
void cdrReset();
void cdrInterrupt();
void cdrReadInterrupt();

View File

@ -19,7 +19,7 @@
#ifndef __COMMON_H__
#define __COMMON_H__
#include "PS2Etypes.h"
#include "Pcsx2Defs.h"
#define BIAS 2 // Bus is half of the actual ps2 speed
//#define PS2CLK 36864000 /* 294.912 mhz */

View File

@ -77,7 +77,7 @@ namespace Console
if( FrameHandle != NULL )
FrameHandle->Write( fmt );
fwrite( fmt, 1, strlen( fmt ), emuLog );
fputs( fmt, emuLog );
return false;
}

View File

@ -32,7 +32,6 @@
using namespace Threading;
extern u8 psxhblankgate;
u32 g_vu1SkipCount; // number of frames to disable/skip VU1
static const uint EECNT_FUTURE_TARGET = 0x10000000;
@ -50,8 +49,6 @@ SyncCounter vsyncCounter;
u32 nextsCounter; // records the cpuRegs.cycle value of the last call to rcntUpdate()
s32 nextCounter; // delta from nextsCounter, in cycles, until the next rcntUpdate()
// VUSkip Locals and Globals
void rcntReset(int index) {
counters[index].count = 0;
counters[index].sCycleT = cpuRegs.cycle;
@ -264,9 +261,6 @@ u32 UpdateVSyncRate()
m_iStart = GetCPUTicks();
cpuRcntSet();
// Initialize VU Skip Stuff...
g_vu1SkipCount = 0;
return (u32)m_iTicks;
}
@ -363,17 +357,7 @@ static __forceinline void VSyncEnd(u32 sCycle)
iFrame++;
if( g_vu1SkipCount > 0 )
{
gsPostVsyncEnd( false );
AtomicDecrement( g_vu1SkipCount );
vu1MicroEnableSkip();
}
else
{
gsPostVsyncEnd( true );
vu1MicroDisableSkip();
}
gsPostVsyncEnd( true );
hwIntcIrq(INTC_VBLANK_E); // HW Irq
psxVBlankEnd(); // psxCounters vBlank End

View File

@ -1,40 +0,0 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 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
*/
#ifndef __EEREGS_H__
#define __EEREGS_H__
#define at cpuRegs.GPR.n.at
#define k0 cpuRegs.GPR.n.k0
#define k1 cpuRegs.GPR.n.k1
#define v0 cpuRegs.GPR.n.v0
#define v1 cpuRegs.GPR.n.v1
#define a0 cpuRegs.GPR.n.a0
#define a1 cpuRegs.GPR.n.a1
#define a2 cpuRegs.GPR.n.a2
#define a3 cpuRegs.GPR.n.a3
#define t0 cpuRegs.GPR.n.t0
#define s0 cpuRegs.GPR.n.s0
#define gp cpuRegs.GPR.n.gp
#define fp cpuRegs.GPR.n.s8
#define sp cpuRegs.GPR.n.sp
#define ra cpuRegs.GPR.n.ra
#define pc0 cpuRegs.pc
#endif /* __EEREGS_H__ */

View File

@ -165,16 +165,10 @@ void gsSetVideoRegionType( u32 isPal )
// Make sure framelimiter options are in sync with the plugin's capabilities.
void gsInit()
{
switch(CHECK_FRAMELIMIT)
if( (CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_SKIP) && (GSsetFrameSkip == NULL) )
{
case PCSX2_FRAMELIMIT_SKIP:
case PCSX2_FRAMELIMIT_VUSKIP:
if( GSsetFrameSkip == NULL )
{
Config.Options &= ~PCSX2_FRAMELIMIT_MASK;
Console::WriteLn("Notice: Disabling frameskip -- GS plugin does not support it.");
}
break;
Config.Options &= ~PCSX2_FRAMELIMIT_MASK;
Console::WriteLn("Notice: Disabling frameskip -- GS plugin does not support it.");
}
}
@ -619,8 +613,7 @@ __forceinline void gsFrameSkip( bool forceskip )
static u8 FramesToRender = 0;
static u8 FramesToSkip = 0;
if( CHECK_FRAMELIMIT != PCSX2_FRAMELIMIT_SKIP &&
CHECK_FRAMELIMIT != PCSX2_FRAMELIMIT_VUSKIP ) return;
if( CHECK_FRAMELIMIT != PCSX2_FRAMELIMIT_SKIP ) return;
// FrameSkip and VU-Skip Magic!
// Skips a sequence of consecutive frames after a sequence of rendered frames
@ -652,14 +645,6 @@ __forceinline void gsFrameSkip( bool forceskip )
return;
}
// if we've already given the EE a skipcount assignment then don't do anything more.
// Otherwise we could start compounding the issue and skips would be too long.
if( g_vu1SkipCount > 0 )
{
//Console::Status("- Already Assigned a Skipcount.. %d", params g_vu1SkipCount );
return;
}
if( FramesToRender == 0 )
{
// -- Standard operation section --
@ -680,20 +665,9 @@ __forceinline void gsFrameSkip( bool forceskip )
if( (m_justSkipped && (sSlowDeltaTime > m_iSlowTicks)) ||
(sSlowDeltaTime > m_iSlowTicks*2) )
{
//Console::Status( "Frameskip Initiated! Lateness: %d", params (int)( (sSlowDeltaTime*100) / m_iSlowTicks ) );
if( CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_VUSKIP )
{
// For best results we have to wait for the EE to
// tell us when to skip, so that VU skips are synched with GS skips.
AtomicExchangeAdd( g_vu1SkipCount, yesSkipFrames+1 );
}
else
{
GSsetFrameSkip(1);
FramesToRender = noSkipFrames+1;
FramesToSkip = yesSkipFrames;
}
GSsetFrameSkip(1);
FramesToRender = noSkipFrames+1;
FramesToSkip = yesSkipFrames;
}
}
else
@ -771,7 +745,6 @@ void gsPostVsyncEnd( bool updategs )
void _gs_ResetFrameskip()
{
g_vu1SkipCount = 0; // set to 0 so that EE will re-enable the VU at the next vblank.
GSsetFrameSkip( 0 );
}

View File

@ -331,7 +331,6 @@ void mfifoGIFtransfer(int qwc);
int _GIFchain();
void gifMFIFOInterrupt();
extern u32 g_vu1SkipCount;
extern u32 CSRw;
extern u64 m_iSlowStart;

View File

@ -168,16 +168,24 @@ void hwWrite8(u32 mem, u8 value) {
case RCNT3_TARGET: rcntWtarget(3, value); break;
case 0x1000f180:
if (value == '\n') {
{
bool flush = false;
// Terminate lines on CR or full buffers, and ignore \n's if the string contents
// are empty (otherwise terminate on \n too!)
if( ( value == '\r' ) || ( sio_count == 1023 ) ||
( value == '\n' && sio_count != 0 ) )
{
sio_buffer[sio_count] = 0;
Console::WriteLn( Color_Cyan, sio_buffer );
sio_count = 0;
} else {
if (sio_count < 1023) {
sio_buffer[sio_count++] = value;
}
}
break;
else if( value != '\n' )
{
sio_buffer[sio_count++] = value;
}
}
break;
//case 0x10003c02: //Tony Hawks Project 8 uses this
// vif1Write32(mem & ~0x2, value << 16);

View File

@ -133,7 +133,9 @@ namespace OpcodeImpl {
* Jump to target *
* Format: OP target *
*********************************************************/
// fixme: looking at the other branching code, shouldn't those _SetLinks in BGEZAL and such only be set
// if the condition is true? --arcum42
void J()
{
doBranch(_JumpTarget_);
@ -181,10 +183,10 @@ void BGEZ() // Branch if Rs >= 0
void BGEZAL() // Branch if Rs >= 0 and link
{
_SetLink(31);
if (cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
{
_SetLink(31);
doBranch(_BranchTarget_);
}
}
@ -215,9 +217,9 @@ void BLTZ() // Branch if Rs < 0
void BLTZAL() // Branch if Rs < 0 and link
{
_SetLink(31); \
if (cpuRegs.GPR.r[_Rs_].SD[0] < 0)
{
_SetLink(31);
doBranch(_BranchTarget_);
}
}
@ -308,10 +310,10 @@ void BGEZL() // Branch if Rs >= 0
void BLTZALL() // Branch if Rs < 0 and link
{
_SetLink(31);
if(cpuRegs.GPR.r[_Rs_].SD[0] < 0)
{
_SetLink(31);
doBranch(_BranchTarget_);
}
else
@ -323,10 +325,10 @@ void BLTZALL() // Branch if Rs < 0 and link
void BGEZALL() // Branch if Rs >= 0 and link
{
_SetLink(31);
if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
{
_SetLink(31);
doBranch(_BranchTarget_);
}
else

View File

@ -171,31 +171,34 @@ const char *biosC0n[256] = {
#define Rv0 (iopVirtMemR<char>(v0))
#define Rsp (iopVirtMemR<char>(sp))
void bios_write() { // 0x35/0x03
if (a0 == 1) { // stdout
void bios_write() // 0x35/0x03
{
if (a0 == 1) // stdout
{
const char *ptr = Ra1;
// fixme: This should use %s with a length parameter (but I forget the exact syntax
// offhand, so maybe do it later).
while (a2 > 0) {
Console::Write("%c", params *ptr++); a2--;
while (a2 > 0)
{
Console::Write("%c", params *ptr++);
a2--;
}
pc0 = ra; return;
}
PSXBIOS_LOG("bios_%s: %x,%x,%x", biosB0n[0x35], a0, a1, a2);
}
else
{
PSXBIOS_LOG("bios_%s: %x,%x,%x", biosB0n[0x35], a0, a1, a2);
v0 = -1;
v0 = -1;
}
pc0 = ra;
}
void bios_printf() { // 3f
char tmp[1024];
char tmp2[1024];
unsigned long save[4];
void bios_printf() // 3f
{
char tmp[1024], tmp2[1024];
u32 save[4];
char *ptmp = tmp;
int n=1, i=0, j;
int n=1, i=0, j = 0;
memcpy(save, iopVirtMemR<void>(sp), 4*4);
@ -203,58 +206,86 @@ void bios_printf() { // 3f
iopMemWrite32(sp + 4, a1);
iopMemWrite32(sp + 8, a2);
iopMemWrite32(sp + 12, a3);
// old code used phys... is iopMemRead32 more correct?
//psxMu32(sp) = a0;
//psxMu32(sp + 4) = a1;
//psxMu32(sp + 8) = a2;
//psxMu32(sp + 12) = a3;
//psxMu32(sp + 12) = a3;+
while (Ra0[i]) {
switch (Ra0[i]) {
while (Ra0[i])
{
switch (Ra0[i])
{
case '%':
j = 0;
tmp2[j++] = '%';
_start:
switch (Ra0[++i]) {
switch (Ra0[++i])
{
case '.':
case 'l':
tmp2[j++] = Ra0[i]; goto _start;
tmp2[j++] = Ra0[i];
goto _start;
default:
if (Ra0[i] >= '0' && Ra0[i] <= '9') {
if (Ra0[i] >= '0' && Ra0[i] <= '9')
{
tmp2[j++] = Ra0[i];
goto _start;
}
break;
}
tmp2[j++] = Ra0[i];
tmp2[j] = 0;
switch (Ra0[i]) {
switch (Ra0[i])
{
case 'f': case 'F':
ptmp+= sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4));
n++;
break;
case 'a': case 'A':
case 'e': case 'E':
case 'g': case 'G':
ptmp+= sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4));
n++;
break;
case 'p':
case 'i':
case 'd': case 'D':
case 'o': case 'O':
case 'x': case 'X':
ptmp+= sprintf(ptmp, tmp2, (unsigned int)iopMemRead32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (u32)iopMemRead32(sp + n * 4));
n++;
break;
case 'c':
ptmp+= sprintf(ptmp, tmp2, (unsigned char)iopMemRead32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (u8)iopMemRead32(sp + n * 4));
n++;
break;
case 's':
ptmp+= sprintf(ptmp, tmp2, iopVirtMemR<char>(iopMemRead32(sp + n * 4))); n++; break;
ptmp+= sprintf(ptmp, tmp2, iopVirtMemR<char>(iopMemRead32(sp + n * 4)));
n++;
break;
case '%':
*ptmp++ = Ra0[i]; break;
*ptmp++ = Ra0[i];
break;
default:
break;
}
i++;
break;
default:
*ptmp++ = Ra0[i++];
break;
}
}
*ptmp = 0;
@ -262,18 +293,18 @@ _start:
// Note: Use Read to obtain a write pointer here, since we're just writing back the
// temp buffer we saved earlier.
memcpy( (void*)iopVirtMemR<void>(sp), save, 4*4);
Console::Write( Color_Cyan, "%s", params tmp);
pc0 = ra;
}
void bios_putchar () { // 3d
void bios_putchar () // 3d
{
Console::Write( Color_Cyan, "%c", params a0 );
pc0 = ra;
}
void bios_puts () { // 3e/3f
void bios_puts () // 3e/3f
{
Console::Write( Color_Cyan, Ra0 );
pc0 = ra;
}
@ -282,10 +313,12 @@ void (*biosA0[256])();
void (*biosB0[256])();
void (*biosC0[256])();
void psxBiosInit() {
void psxBiosInit()
{
int i;
for(i = 0; i < 256; i++) {
for(i = 0; i < 256; i++)
{
biosA0[i] = NULL;
biosB0[i] = NULL;
biosC0[i] = NULL;
@ -298,7 +331,8 @@ void psxBiosInit() {
}
void psxBiosShutdown() {
void psxBiosShutdown()
{
}
} // end namespace R3000A

View File

@ -479,7 +479,9 @@ void psxRcntUpdate()
for (i=0; i<6; i++) _rcntSet( i );
}
void psxRcntWcount16(int index, u32 value)
//////////////////////////////////////////////////////////////////////////////////////////
//
void psxRcntWcount16(int index, u16 value)
{
u32 change;
@ -500,6 +502,8 @@ void psxRcntWcount16(int index, u32 value)
_rcntSet( index );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void psxRcntWcount32(int index, u32 value)
{
u32 change;
@ -521,159 +525,119 @@ void psxRcntWcount32(int index, u32 value)
_rcntSet( index );
}
void psxRcnt0Wmode(u32 value)
//////////////////////////////////////////////////////////////////////////////////////////
//
__forceinline void psxRcntWmode16( int index, u32 value )
{
PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value);
PSXCNT_LOG( "IOP Counter[%d] writeMode = 0x%04X", index, value );
psxCounters[0].mode = value;
psxCounters[0].mode|= 0x0400;
psxCounters[0].rate = 1;
jASSUME( index >= 0 && index < 3 );
psxCounter& counter = psxCounters[index];
if(value & IOPCNT_ALT_SOURCE)
psxCounters[0].rate = PSXPIXEL;
if(psxCounters[0].mode & IOPCNT_ENABLE_GATE)
counter.mode = value;
counter.mode |= 0x0400;
if( index == 2 )
{
// gated counters are added up as per the h/vblank timers.
PSXCNT_LOG("IOP Counter[0] Gate Check set, value = %x", value);
psxhblankgate |= 1;
}
else psxhblankgate &= ~1;
psxCounters[0].count = 0;
psxCounters[0].sCycleT = psxRegs.cycle;
psxCounters[0].target &= 0xffff;
_rcntSet( 0 );
}
void psxRcnt1Wmode(u32 value)
{
PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value);
psxCounters[1].mode = value;
psxCounters[1].mode|= 0x0400;
psxCounters[1].rate = 1;
if(value & IOPCNT_ALT_SOURCE)
psxCounters[1].rate = PSXHBLANK;
if(psxCounters[1].mode & IOPCNT_ENABLE_GATE)
{
PSXCNT_LOG("IOP Counter[1] Gate Check set, value = %x", value);
psxvblankgate |= 1<<1;
}
else psxvblankgate &= ~(1<<1);
psxCounters[1].count = 0;
psxCounters[1].sCycleT = psxRegs.cycle;
psxCounters[1].target &= 0xffff;
_rcntSet( 1 );
}
void psxRcnt2Wmode(u32 value)
{
PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value);
psxCounters[2].mode = value;
psxCounters[2].mode|= 0x0400;
switch(value & 0x200)
{
case 0x200: psxCounters[2].rate = 8; break;
switch(value & 0x200)
{
case 0x000: psxCounters[2].rate = 1; break;
case 0x200: psxCounters[2].rate = 8; break;
jNO_DEFAULT;
}
if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
{
counter.mode |= IOPCNT_STOPPED;
}
}
else
{
// Counters 0 and 1 can select PIXEL or HSYNC as an alternate source:
counter.rate = 1;
if(value & IOPCNT_ALT_SOURCE)
counter.rate = (index==0) ? PSXPIXEL : PSXHBLANK;
if(counter.mode & IOPCNT_ENABLE_GATE)
{
// gated counters are added up as per the h/vblank timers.
// (the PIXEL alt source becomes a vsync gate)
PSXCNT_LOG( "IOP Counter[%d] Gate Check set, value = 0x%04X", index, value );
if( index == 0 )
psxhblankgate |= 1; // fixme: these gate flags should be one var >_<
else
psxvblankgate |= 1<<1;
}
else
{
if( index == 0 )
psxhblankgate &= ~1;
else
psxvblankgate &= ~(1<<1);
}
}
if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1)
{
//Console::WriteLn("Gate set on IOP C2, disabling");
psxCounters[2].mode |= IOPCNT_STOPPED;
}
psxCounters[2].count = 0;
psxCounters[2].sCycleT = psxRegs.cycle;
psxCounters[2].target &= 0xffff;
_rcntSet( 2 );
counter.count = 0;
counter.sCycleT = psxRegs.cycle;
counter.target &= 0xffff;
_rcntSet( index );
}
void psxRcnt3Wmode(u32 value)
//////////////////////////////////////////////////////////////////////////////////////////
//
__forceinline void psxRcntWmode32( int index, u32 value )
{
PSXCNT_LOG("IOP Counter[3] writeMode = %lx", value);
PSXCNT_LOG( "IOP Counter[%d] writeMode = 0x%04x", index, value );
psxCounters[3].mode = value;
psxCounters[3].rate = 1;
psxCounters[3].mode|= 0x0400;
jASSUME( index >= 3 && index < 6 );
psxCounter& counter = psxCounters[index];
if(value & IOPCNT_ALT_SOURCE)
psxCounters[3].rate = PSXHBLANK;
if(psxCounters[3].mode & IOPCNT_ENABLE_GATE)
counter.mode = value;
counter.mode |= 0x0400;
if( index == 3 )
{
PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
psxvblankgate |= 1<<3;
}
else psxvblankgate &= ~(1<<3);
// Counter 3 has the HBlank as an alternate source.
counter.rate = 1;
if(value & IOPCNT_ALT_SOURCE)
counter.rate = PSXHBLANK;
psxCounters[3].count = 0;
psxCounters[3].sCycleT = psxRegs.cycle;
psxCounters[3].target &= 0xffffffff;
_rcntSet( 3 );
}
void psxRcnt4Wmode(u32 value)
{
PSXCNT_LOG("IOP Counter[4] writeMode = %lx", value);
psxCounters[4].mode = value;
psxCounters[4].mode|= 0x0400;
switch(value & 0x6000)
{
case 0x0000: psxCounters[4].rate = 1; break;
case 0x2000: psxCounters[4].rate = 8; break;
case 0x4000: psxCounters[4].rate = 16; break;
case 0x6000: psxCounters[4].rate = 256; break;
}
// Need to set a rate and target
if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1)
{
Console::WriteLn("Gate set on IOP C4, disabling");
psxCounters[4].mode |= IOPCNT_STOPPED;
}
psxCounters[4].count = 0;
psxCounters[4].sCycleT = psxRegs.cycle;
psxCounters[4].target &= 0xffffffff;
_rcntSet( 4 );
}
void psxRcnt5Wmode(u32 value)
{
PSXCNT_LOG("IOP Counter[5] writeMode = %lx", value);
psxCounters[5].mode = value;
psxCounters[5].mode|= 0x0400;
switch(value & 0x6000)
{
case 0x0000: psxCounters[5].rate = 1; break;
case 0x2000: psxCounters[5].rate = 8; break;
case 0x4000: psxCounters[5].rate = 16; break;
case 0x6000: psxCounters[5].rate = 256; break;
}
// Need to set a rate and target
if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1)
{
Console::WriteLn("Gate set on IOP C5, disabling");
psxCounters[5].mode |= IOPCNT_STOPPED;
}
psxCounters[5].count = 0;
psxCounters[5].sCycleT = psxRegs.cycle;
psxCounters[5].target &= 0xffffffff;
_rcntSet( 5 );
if(counter.mode & IOPCNT_ENABLE_GATE)
{
PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
psxvblankgate |= 1<<3;
}
else psxvblankgate &= ~(1<<3);
}
else
{
switch(value & 0x6000)
{
case 0x0000: counter.rate = 1; break;
case 0x2000: counter.rate = 8; break;
case 0x4000: counter.rate = 16; break;
case 0x6000: counter.rate = 256; break;
}
// Need to set a rate and target
if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
{
Console::WriteLn( "Gate set on IOP Counter %d, disabling", params index );
counter.mode |= IOPCNT_STOPPED;
}
}
counter.count = 0;
counter.sCycleT = psxRegs.cycle;
counter.target &= 0xffffffff;
_rcntSet( index );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void psxRcntWtarget16(int index, u32 value)
{
assert( index < 3 );

View File

@ -34,30 +34,24 @@ struct psxCounter {
#endif
extern psxCounter psxCounters[NUM_COUNTERS];
extern s32 psxNextCounter;
extern u32 psxNextsCounter;
void psxRcntInit();
void psxRcntUpdate();
void cntspu2async();
void psxRcntWcount16(int index, u32 value);
void psxRcntWcount32(int index, u32 value);
void psxRcnt0Wmode(u32 value);
void psxRcnt1Wmode(u32 value);
void psxRcnt2Wmode(u32 value);
void psxRcnt3Wmode(u32 value);
void psxRcnt4Wmode(u32 value);
void psxRcnt5Wmode(u32 value);
void psxRcntWtarget16(int index, u32 value);
void psxRcntWtarget32(int index, u32 value);
u16 psxRcntRcount16(int index);
u32 psxRcntRcount32(int index);
u64 psxRcntCycles(int index);
extern void psxRcntInit();
extern void psxRcntUpdate();
extern void cntspu2async();
extern void psxRcntWcount16(int index, u16 value);
extern void psxRcntWcount32(int index, u32 value);
extern void psxRcntWmode16(int index, u32 value);
extern void psxRcntWmode32(int index, u32 value);
extern void psxRcntWtarget16(int index, u32 value);
extern void psxRcntWtarget32(int index, u32 value);
extern u16 psxRcntRcount16(int index);
extern u32 psxRcntRcount32(int index);
extern u64 psxRcntCycles(int index);
void psxVBlankStart();
void psxVBlankEnd();
void psxCheckStartGate16(int i);
void psxCheckEndGate16(int i);
extern void psxVBlankStart();
extern void psxVBlankEnd();
extern void psxCheckStartGate16(int i);
extern void psxCheckEndGate16(int i);
//static void psxCheckStartGate32(int i);
//static void psxCheckEndGate32(int i);

View File

@ -560,7 +560,7 @@ u32 psxHwRead32(u32 add) {
case 0x1F808240:
case 0x1F808248:
case 0x1F808250:
case 0x1F80825C:
case 0x1F808258:
hard=sio2_getSend1((add-0x1F808240)/8);
PSXHW_LOG("SIO2 read send1[%d] (%lx)", (add-0x1F808240)/8, hard);
return hard;
@ -568,7 +568,7 @@ u32 psxHwRead32(u32 add) {
case 0x1F808244:
case 0x1F80824C:
case 0x1F808254:
case 0x1F808258:
case 0x1F80825C:
hard=sio2_getSend2((add-0x1F808244)/8);
PSXHW_LOG("SIO2 read send2[%d] (%lx)", (add-0x1F808244)/8, hard);
return hard;
@ -618,8 +618,8 @@ u32 psxHwRead32(u32 add) {
}
// A buffer that stores messages until it gets a /n or the number of chars (g_pbufi) is more then 1023.
char g_pbuf[1024];
int g_pbufi;
static s8 g_pbuf[1024];
static int g_pbufi;
void psxHwWrite8(u32 add, u8 value) {
if (add >= HW_USB_START && add < HW_USB_END) {
USBwrite8(add, value); return;
@ -666,14 +666,24 @@ void psxHwWrite8(u32 add, u8 value) {
case 0x1f801803: cdrWrite3(value); break;
case 0x1f80380c:
if (value == '\r') break;
if (value == '\n' || g_pbufi >= 1023) { // A line break, or the buffer is about to overflow.
g_pbuf[g_pbufi++] = 0;
g_pbufi = 0;
{
bool flush = false;
// Terminate lines on CR or full buffers, and ignore \n's if the string contents
// are empty (otherwise terminate on \n too!)
if( ( value == '\r' ) || ( g_pbufi == 1023 ) ||
( value == '\n' && g_pbufi != 0 ) )
{
g_pbuf[g_pbufi] = 0;
DevCon::WriteLn( Color_Cyan, "%s", params g_pbuf );
g_pbufi = 0;
}
else if( value != '\n' )
{
g_pbuf[g_pbufi++] = value;
}
else g_pbuf[g_pbufi++] = value;
psxHu8(add) = value;
}
return;
case 0x1F808260:
@ -758,7 +768,7 @@ void psxHwWrite16(u32 add, u16 value) {
psxRcntWcount16(0, value); return;
case IOP_T0_MODE:
PSXCNT_LOG("COUNTER 0 MODE 16bit write %x", value);
psxRcnt0Wmode(value); return;
psxRcntWmode16(0, value); return;
case IOP_T0_TARGET:
PSXCNT_LOG("COUNTER 0 TARGET 16bit write %x", value);
psxRcntWtarget16(0, value); return;
@ -768,7 +778,7 @@ void psxHwWrite16(u32 add, u16 value) {
psxRcntWcount16(1, value); return;
case IOP_T1_MODE:
PSXCNT_LOG("COUNTER 1 MODE 16bit write %x", value);
psxRcnt1Wmode(value); return;
psxRcntWmode16(1, value); return;
case IOP_T1_TARGET:
PSXCNT_LOG("COUNTER 1 TARGET 16bit write %x", value);
psxRcntWtarget16(1, value); return;
@ -778,7 +788,7 @@ void psxHwWrite16(u32 add, u16 value) {
psxRcntWcount16(2, value); return;
case IOP_T2_MODE:
PSXCNT_LOG("COUNTER 2 MODE 16bit write %x", value);
psxRcnt2Wmode(value); return;
psxRcntWmode16(2, value); return;
case IOP_T2_TARGET:
PSXCNT_LOG("COUNTER 2 TARGET 16bit write %x", value);
psxRcntWtarget16(2, value); return;
@ -793,7 +803,7 @@ void psxHwWrite16(u32 add, u16 value) {
psxRcntWcount32(3, value); return;
case IOP_T3_MODE:
PSXCNT_LOG("COUNTER 3 MODE 16bit write %lx", value);
psxRcnt3Wmode(value); return;
psxRcntWmode32(3, value); return;
case IOP_T3_TARGET:
PSXCNT_LOG("COUNTER 3 TARGET 16bit write %lx", value);
psxRcntWtarget32(3, value); return;
@ -803,7 +813,7 @@ void psxHwWrite16(u32 add, u16 value) {
psxRcntWcount32(4, value); return;
case IOP_T4_MODE:
PSXCNT_LOG("COUNTER 4 MODE 16bit write %lx", value);
psxRcnt4Wmode(value); return;
psxRcntWmode32(4, value); return;
case IOP_T4_TARGET:
PSXCNT_LOG("COUNTER 4 TARGET 16bit write %lx", value);
psxRcntWtarget32(4, value); return;
@ -813,7 +823,7 @@ void psxHwWrite16(u32 add, u16 value) {
psxRcntWcount32(5, value); return;
case IOP_T5_MODE:
PSXCNT_LOG("COUNTER 5 MODE 16bit write %lx", value);
psxRcnt5Wmode(value); return;
psxRcntWmode32(5, value); return;
case IOP_T5_TARGET:
PSXCNT_LOG("COUNTER 5 TARGET 16bit write %lx", value);
psxRcntWtarget32(5, value); return;
@ -1170,7 +1180,7 @@ void psxHwWrite32(u32 add, u32 value) {
psxRcntWcount16(0, value ); return;
case IOP_T0_MODE:
PSXCNT_LOG("COUNTER 0 MODE 32bit write %lx", value);
psxRcnt0Wmode(value); return;
psxRcntWmode16(0, value); return;
case IOP_T0_TARGET:
PSXCNT_LOG("COUNTER 0 TARGET 32bit write %lx", value);
psxRcntWtarget16(0, value ); return;
@ -1180,7 +1190,7 @@ void psxHwWrite32(u32 add, u32 value) {
psxRcntWcount16(1, value ); return;
case IOP_T1_MODE:
PSXCNT_LOG("COUNTER 1 MODE 32bit write %lx", value);
psxRcnt1Wmode(value); return;
psxRcntWmode16(1, value); return;
case IOP_T1_TARGET:
PSXCNT_LOG("COUNTER 1 TARGET 32bit write %lx", value);
psxRcntWtarget16(1, value ); return;
@ -1190,7 +1200,7 @@ void psxHwWrite32(u32 add, u32 value) {
psxRcntWcount16(2, value ); return;
case IOP_T2_MODE:
PSXCNT_LOG("COUNTER 2 MODE 32bit write %lx", value);
psxRcnt2Wmode(value); return;
psxRcntWmode16(0, value); return;
case IOP_T2_TARGET:
PSXCNT_LOG("COUNTER 2 TARGET 32bit write %lx", value);
psxRcntWtarget16(2, value); return;
@ -1200,7 +1210,7 @@ void psxHwWrite32(u32 add, u32 value) {
psxRcntWcount32(3, value); return;
case IOP_T3_MODE:
PSXCNT_LOG("COUNTER 3 MODE 32bit write %lx", value);
psxRcnt3Wmode(value); return;
psxRcntWmode32(3, value); return;
case IOP_T3_TARGET:
PSXCNT_LOG("COUNTER 3 TARGET 32bit write %lx", value);
psxRcntWtarget32(3, value); return;
@ -1210,7 +1220,7 @@ void psxHwWrite32(u32 add, u32 value) {
psxRcntWcount32(4, value); return;
case IOP_T4_MODE:
PSXCNT_LOG("COUNTER 4 MODE 32bit write %lx", value);
psxRcnt4Wmode(value); return;
psxRcntWmode32(4, value); return;
case IOP_T4_TARGET:
PSXCNT_LOG("COUNTER 4 TARGET 32bit write %lx", value);
psxRcntWtarget32(4, value); return;
@ -1220,7 +1230,7 @@ void psxHwWrite32(u32 add, u32 value) {
psxRcntWcount32(5, value); return;
case IOP_T5_MODE:
PSXCNT_LOG("COUNTER 5 MODE 32bit write %lx", value);
psxRcnt5Wmode(value); return;
psxRcntWmode32(5, value); return;
case IOP_T5_TARGET:
PSXCNT_LOG("COUNTER 5 TARGET 32bit write %lx", value);
psxRcntWtarget32(5, value); return;
@ -1303,89 +1313,42 @@ void psxHwWrite32(u32 add, u32 value) {
PSXHW_LOG("*Known 32bit write at address %lx value %lx", add, value);
}
u8 psxHw4Read8(u32 add) {
u8 hard;
switch (add) {
case 0x1f402004: return cdvdRead04();
case 0x1f402005: return cdvdRead05();
case 0x1f402006: return cdvdRead06();
case 0x1f402007: return cdvdRead07();
case 0x1f402008: return cdvdRead08();
case 0x1f40200A: return cdvdRead0A();
case 0x1f40200B: return cdvdRead0B();
case 0x1f40200C: return cdvdRead0C();
case 0x1f40200D: return cdvdRead0D();
case 0x1f40200E: return cdvdRead0E();
case 0x1f40200F: return cdvdRead0F();
case 0x1f402013: return cdvdRead13();
case 0x1f402015: return cdvdRead15();
case 0x1f402016: return cdvdRead16();
case 0x1f402017: return cdvdRead17();
case 0x1f402018: return cdvdRead18();
case 0x1f402020: return cdvdRead20();
case 0x1f402021: return cdvdRead21();
case 0x1f402022: return cdvdRead22();
case 0x1f402023: return cdvdRead23();
case 0x1f402024: return cdvdRead24();
case 0x1f402028: return cdvdRead28();
case 0x1f402029: return cdvdRead29();
case 0x1f40202A: return cdvdRead2A();
case 0x1f40202B: return cdvdRead2B();
case 0x1f40202C: return cdvdRead2C();
case 0x1f402030: return cdvdRead30();
case 0x1f402031: return cdvdRead31();
case 0x1f402032: return cdvdRead32();
case 0x1f402033: return cdvdRead33();
case 0x1f402034: return cdvdRead34();
case 0x1f402038: return cdvdRead38();
case 0x1f402039: return cdvdRead39();
case 0x1f40203A: return cdvdRead3A();
default:
// note: notify the console since this is a potentially serious emulation problem:
PSXHW_LOG("*Unknown 8bit read at address 0x%x", add);
Console::Error( "IOP Unknown 8bit read from addr 0x%x", params add );
return 0;
}
u8 psxHw4Read8(u32 add)
{
//u8 hard;
u16 mem = add & 0xFF;
PSXHW_LOG( "Known 8bit read from addr 0x%x = 0x%x", add, hard );
//Console::WriteLn("psxHw4Read8 0x%x, %x", params add, mem);
return cdvdRead(mem);
//PSXHW_LOG( "Known 8bit read from addr 0x%x = 0x%x", add, hard );
return hard;
//return hard;
}
void psxHw4Write8(u32 add, u8 value) {
void psxHw4Write8(u32 add, u8 value)
{
switch (add) {
case 0x1f402004: cdvdWrite04(value); return;
case 0x1f402005: cdvdWrite05(value); return;
case 0x1f402006: cdvdWrite06(value); return;
case 0x1f402007: cdvdWrite07(value); return;
case 0x1f402008: cdvdWrite08(value); return;
case 0x1f40200A: cdvdWrite0A(value); return;
case 0x1f40200F: cdvdWrite0F(value); return;
case 0x1f402014: cdvdWrite14(value); return;
case 0x1f402016: cdvdWrite16(value); return;
case 0x1f402017: cdvdWrite17(value); return;
case 0x1f402018: cdvdWrite18(value); return;
case 0x1f40203A: cdvdWrite3A(value); return;
default:
//PSXHW_LOG("*Unknown 8bit write at address %lx value %x", add, value);
Console::Notice("IOP Unknown 8bit write to addr 0x%x = 0x%x", params add, value);
return;
}
u16 mem = add & 0xFF;
//Console::WriteLn("psxHw4Write8 0x%x, %x", params add, mem);
cdvdWrite(mem, value);
PSXHW_LOG("Known 8bit write to addr 0x%x = 0x%x", add, value);
}
void psxDmaInterrupt(int n) {
if (HW_DMA_ICR & (1 << (16 + n))) {
void psxDmaInterrupt(int n)
{
if (HW_DMA_ICR & (1 << (16 + n)))
{
HW_DMA_ICR|= (1 << (24 + n));
psxRegs.CP0.n.Cause |= 1 << (9 + n);
iopIntcIrq( 3 );
}
}
void psxDmaInterrupt2(int n) {
if (HW_DMA_ICR2 & (1 << (16 + n))) {
void psxDmaInterrupt2(int n)
{
if (HW_DMA_ICR2 & (1 << (16 + n)))
{
/* if (HW_DMA_ICR2 & (1 << (24 + n))) {
Console::WriteLn("*PCSX2*: HW_DMA_ICR2 n=%d already set", params n);
}

View File

@ -16,18 +16,69 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __PSXHW_H__
#define __PSXHW_H__
#pragma once
#include "R3000A.h"
#include "IopMem.h"
#define HW_USB_START 0x1f801600
#define HW_USB_END 0x1f801700
#define HW_FW_START 0x1f808400
#define HW_FW_END 0x1f808550
#define HW_SPU2_START 0x1f801c00
#define HW_SPU2_END 0x1f801e00
static const u32
HW_USB_START = 0x1f801600,
HW_USB_END = 0x1f801700,
HW_FW_START = 0x1f808400,
HW_FW_END = 0x1f808550, // end addr for FW is a guess...
HW_SPU2_START = 0x1f801c00,
HW_SPU2_END = 0x1f801e00;
static const u32
HW_SSBUS_SPD_ADDR = 0x1f801000,
HW_SSBUS_PIO_ADDR = 0x1f801004,
HW_SSBUS_SPD_DELAY = 0x1f801008,
HW_SSBUS_DEV1_DELAY = 0x1f80100C,
HW_SSBUS_ROM_DELAY = 0x1f801010,
HW_SSBUS_SPU_DELAY = 0x1f801014,
HW_SSBUS_DEV5_DELAY = 0x1f801018,
HW_SSBUS_PIO_DELAY = 0x1f80101c,
HW_SSBUS_COM_DELAY = 0x1f801020,
HW_SIO_DATA = 0x1f801040, // SIO read/write register
HW_SIO_STAT = 0x1f801044,
HW_SIO_MODE = 0x1f801048,
HW_SIO_CTRL = 0x1f80104a,
HW_SIO_BAUD = 0x1f80104e,
HW_IREG = 0x1f801070,
HW_IMASK = 0x1f801074,
HW_ICTRL = 0x1f801078,
HW_SSBUS_DEV1_ADDR = 0x1f801400,
HW_SSBUS_SPU_ADDR = 0x1f801404,
HW_SSBUS_DEV5_ADDR = 0x1f801408,
HW_SSBUS_SPU1_ADDR = 0x1f80140c,
HW_SSBUS_DEV9_ADDR3 = 0x1f801410,
HW_SSBUS_SPU1_DELAY = 0x1f801414,
HW_SSBUS_DEV9_DELAY2= 0x1f801418,
HW_SSBUS_DEV9_DELAY3= 0x1f80141c,
HW_SSBUS_DEV9_DELAY1= 0x1f801420,
HW_ICFG = 0x1f801450,
HW_DEV9_DATA = 0x1f80146e, // DEV9 read/write register
// CDRom registers are used for various command, status, and data stuff.
HW_CDR_DATA0 = 0x1f801800, // CDROM multipurpose data register 1
HW_CDR_DATA1 = 0x1f801801, // CDROM multipurpose data register 2
HW_CDR_DATA2 = 0x1f801802, // CDROM multipurpose data register 3
HW_CDR_DATA3 = 0x1f801803, // CDROM multipurpose data register 4
// SIO2 is a DMA interface for the SIO.
HW_SIO2_DATAIN = 0x1F808260,
HW_SIO2_FIFO = 0x1f808264,
HW_SIO2_CTRL = 0x1f808268,
HW_SIO2_RECV1 = 0x1f80826c,
HW_SIO2_RECV2 = 0x1f808270,
HW_SIO2_RECV3 = 0x1f808274,
HW_SIO2_INTR = 0x1f808280;
/* Registers for the IOP Counters */
enum IOPCountRegs
@ -37,7 +88,7 @@ enum IOPCountRegs
IOP_T2_COUNT = 0x1f801120,
IOP_T3_COUNT = 0x1f801480,
IOP_T4_COUNT = 0x1f801490,
IOP_T5_COUNT = 0x1f8014a0,
IOP_T5_COUNT = 0x1f8014a0,
IOP_T0_MODE = 0x1f801104,
IOP_T1_MODE = 0x1f801114,
@ -46,7 +97,7 @@ enum IOPCountRegs
IOP_T4_MODE = 0x1f801494,
IOP_T5_MODE = 0x1f8014a4,
IOP_T0_TARGET= 0x1f801108,
IOP_T0_TARGET = 0x1f801108,
IOP_T1_TARGET = 0x1f801118,
IOP_T2_TARGET = 0x1f801128,
IOP_T3_TARGET = 0x1f801488,
@ -166,6 +217,8 @@ extern void PSX_INT( IopEventId n, s32 ecycle);
extern void psxSetNextBranch( u32 startCycle, s32 delta );
extern void psxSetNextBranchDelta( s32 delta );
extern int iopTestCycle( u32 startCycle, s32 delta );
extern void _iopTestInterrupts();
void psxHwReset();
u8 psxHwRead8 (u32 add);
@ -192,5 +245,3 @@ void psxHwConstWrite16(u32 add, int mmreg);
void psxHwConstWrite32(u32 add, int mmreg);
int psxHw4ConstRead8 (u32 x86reg, u32 add, u32 sign);
void psxHw4ConstWrite8(u32 add, int mmreg);
#endif /* __PSXHW_H__ */

View File

@ -37,7 +37,7 @@ static const uint m_psxMemSize =
void psxMemAlloc()
{
if( m_psxAllMem == NULL )
m_psxAllMem = vtlb_malloc( m_psxMemSize, 4096, 0x21000000 );
m_psxAllMem = vtlb_malloc( m_psxMemSize, 4096 );
if( m_psxAllMem == NULL)
throw Exception::OutOfMemory( "psxMemAlloc > failed allocating memory for the IOP processor." );
@ -72,13 +72,9 @@ void psxMemReset()
for (int i=0; i<0x0080; i++)
{
psxMemWLUT[i + 0x0000] = (uptr)&psxM[(i & 0x1f) << 16];
//psxMemWLUT[i + 0x8000] = (uptr)&psxM[(i & 0x1f) << 16];
//psxMemWLUT[i + 0xa000] = (uptr)&psxM[(i & 0x1f) << 16];
// RLUTs, accessed through WLUT.
psxMemWLUT[i + 0x2000] = (uptr)&psxM[(i & 0x1f) << 16];
//psxMemWLUT[i + 0x18000] = (uptr)&psxM[(i & 0x1f) << 16];
//psxMemWLUT[i + 0x1a000] = (uptr)&psxM[(i & 0x1f) << 16];
}
// A few single-page allocations for things we store in special locations.
@ -94,25 +90,17 @@ void psxMemReset()
for (int i=0; i<0x0040; i++)
{
psxMemWLUT[i + 0x2000 + 0x1fc0] = (uptr)&PS2MEM_ROM[i << 16];
//psxMemWLUT[i + 0x19fc0] = (uptr)&PS2MEM_ROM[i << 16];
//psxMemWLUT[i + 0x1bfc0] = (uptr)&PS2MEM_ROM[i << 16];
}
for (int i=0; i<0x0004; i++)
{
psxMemWLUT[i + 0x2000 + 0x1e00] = (uptr)&PS2MEM_ROM1[i << 16];
//psxMemWLUT[i + 0x19e00] = (uptr)&PS2MEM_ROM1[i << 16];
//psxMemWLUT[i + 0x1be00] = (uptr)&PS2MEM_ROM1[i << 16];
}
// sif!! (which is read only? (air))
psxMemWLUT[0x2000 + 0x1d00] = (uptr)psxS;
//psxMemWLUT[0x1bd00] = (uptr)psxS;
// why isn't scratchpad read/write? (air)
//for (i=0; i<0x0001; i++) psxMemWLUT[i + 0x1d00] = (uptr)&psxS[i << 16];
//for (i=0; i<0x0001; i++) psxMemWLUT[i + 0xbd00] = (uptr)&psxS[i << 16];
// this one looks like an old hack for some special write-only memory area,
// but leaving it in for reference (air)
//for (i=0; i<0x0008; i++) psxMemWLUT[i + 0xbfc0] = (uptr)&psR[i << 16];
@ -136,10 +124,21 @@ u8 iopMemRead8(u32 mem)
if (t == 0x1f80)
{
if (mem < 0x1f801000)
return psxHu8(mem);
else
return psxHwRead8(mem);
switch( mem & 0xf000 )
{
case 0x1000: return IopMemory::iopHwRead8_Page1(mem);
case 0x3000: return IopMemory::iopHwRead8_Page3(mem);
case 0x8000: return IopMemory::iopHwRead8_Page8(mem);
// code for regression testing -- selectively enable these to help narrow out
// which register became buggy with the new Hw handlers.
//case 0x1000: return psxHwRead8(mem);
//case 0x3000: return psxHwRead8(mem);
//case 0x8000: return psxHwRead8(mem);
default:
return psxHu8(mem);
}
}
else if (t == 0x1f40)
{
@ -169,10 +168,21 @@ u16 iopMemRead16(u32 mem)
if (t == 0x1f80)
{
if (mem < 0x1f801000)
return psxHu16(mem);
else
return psxHwRead16(mem);
switch( mem & 0xf000 )
{
case 0x1000: return IopMemory::iopHwRead16_Page1(mem);
case 0x3000: return IopMemory::iopHwRead16_Page3(mem);
case 0x8000: return IopMemory::iopHwRead16_Page8(mem);
// code for regression testing -- selectively enable these to help narrow out
// which register became buggy with the new Hw handlers.
//case 0x1000: return psxHwRead16(mem);
//case 0x3000: return psxHwRead16(mem);
//case 0x8000: return psxHwRead16(mem);
default:
return psxHu16(mem);
}
}
else
{
@ -224,10 +234,21 @@ u32 iopMemRead32(u32 mem)
if (t == 0x1f80)
{
if (mem < 0x1f801000)
return psxHu32(mem);
else
return psxHwRead32(mem);
switch( mem & 0xf000 )
{
case 0x1000: return IopMemory::iopHwRead32_Page1(mem);
case 0x3000: return IopMemory::iopHwRead32_Page3(mem);
case 0x8000: return IopMemory::iopHwRead32_Page8(mem);
// code for regression testing -- selectively enable these to help narrow out
// which register became buggy with the new Hw handlers.
//case 0x1000: return psxHwRead32(mem);
//case 0x3000: return psxHwRead32(mem);
//case 0x8000: return psxHwRead32(mem);
default:
return psxHu32(mem);
}
} else
{
//see also Hw.c
@ -282,10 +303,31 @@ void iopMemWrite8(u32 mem, u8 value)
if (t == 0x1f80)
{
if (mem < 0x1f801000)
psxHu8(mem) = value;
else
psxHwWrite8(mem, value);
switch( mem & 0xf000 )
{
// Regression testing: selectively pass ranges of registers to new or old
// handlers. Helps narrow out which area of registers is erroring out.
/*case 0x1000:
if( mem >= 0x1f801000 )
psxHwWrite8( mem, value );
else
IopMemory::iopHwWrite8_Page1(mem,value);
break;*/
case 0x1000: IopMemory::iopHwWrite8_Page1(mem,value); break;
case 0x3000: IopMemory::iopHwWrite8_Page3(mem,value); break;
case 0x8000: IopMemory::iopHwWrite8_Page8(mem,value); break;
// code for regression testing -- selectively enable these to help narrow out
// which register became buggy with the new Hw handlers.
//case 0x1000: psxHwWrite8(mem,value); break;
//case 0x3000: psxHwWrite8(mem,value); break;
//case 0x8000: psxHwWrite8(mem,value); break;
default:
psxHu8(mem) = value;
break;
}
}
else if (t == 0x1f40)
{
@ -323,10 +365,29 @@ void iopMemWrite16(u32 mem, u16 value)
if (t == 0x1f80)
{
if (mem < 0x1f801000)
psxHu16(mem) = value;
else
psxHwWrite16(mem, value);
switch( mem & 0xf000 )
{
// Regression testing: selectively pass ranges of registers to new or old
// handlers. Helps narrow out which area of registers is erroring out.
/*case 0x1000:
if( mem >= 0x1f801000 )
psxHwWrite16( mem, value );
else
IopMemory::iopHwWrite16_Page1(mem,value);
break;*/
case 0x1000: IopMemory::iopHwWrite16_Page1(mem,value); break;
case 0x3000: IopMemory::iopHwWrite16_Page3(mem,value); break;
case 0x8000: IopMemory::iopHwWrite16_Page8(mem,value); break;
//case 0x1000: psxHwWrite16(mem,value); break;
//case 0x3000: psxHwWrite16(mem,value); break;
//case 0x8000: psxHwWrite16(mem,value); break;
default:
psxHu16(mem) = value;
break;
}
} else
{
u8* p = (u8 *)(psxMemWLUT[mem >> 16]);
@ -386,10 +447,29 @@ void iopMemWrite32(u32 mem, u32 value)
if (t == 0x1f80)
{
if (mem < 0x1f801000)
psxHu32(mem) = value;
else
psxHwWrite32(mem, value);
switch( mem & 0xf000 )
{
// Regression testing: selectively pass ranges of registers to new or old
// handlers. Helps narrow out which area of registers is erroring out.
/*case 0x1000:
if( mem >= 0x1f801528 )
psxHwWrite32( mem, value );
else
IopMemory::iopHwWrite32_Page1(mem,value);
break;*/
case 0x1000: IopMemory::iopHwWrite32_Page1(mem,value); break;
case 0x3000: IopMemory::iopHwWrite32_Page3(mem,value); break;
case 0x8000: IopMemory::iopHwWrite32_Page8(mem,value); break;
//case 0x1000: psxHwWrite32(mem,value); break;
//case 0x3000: psxHwWrite32(mem,value); break;
//case 0x8000: psxHwWrite32(mem,value); break;
default:
psxHu32(mem) = value;
break;
}
} else
{
//see also Hw.c

View File

@ -16,8 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __PSXMEMORY_H__
#define __PSXMEMORY_H__
#pragma once
extern u8 *psxM;
extern u8 *psxP;
@ -90,21 +89,40 @@ void iopMemWrite32(u32 mem, u32 value);
// x86reg and mmreg are always x86 regs
void psxRecMemRead8();
int psxRecMemConstRead8(u32 x86reg, u32 mem, u32 sign);
void psxRecMemRead16();
int psxRecMemConstRead16(u32 x86reg, u32 mem, u32 sign);
void psxRecMemRead32();
int psxRecMemConstRead32(u32 x86reg, u32 mem);
void psxRecMemWrite8();
int psxRecMemConstWrite8(u32 mem, int mmreg);
void psxRecMemWrite16();
int psxRecMemConstWrite16(u32 mem, int mmreg);
void psxRecMemWrite32();
int psxRecMemConstWrite32(u32 mem, int mmreg);
#endif /* __PSXMEMORY_H__ */
namespace IopMemory
{
// Sif functions not made yet (will for future Iop improvements):
extern u8 __fastcall SifRead8( u32 iopaddr );
extern u16 __fastcall SifRead16( u32 iopaddr );
extern u32 __fastcall SifRead32( u32 iopaddr );
extern void __fastcall SifWrite8( u32 iopaddr, u8 data );
extern void __fastcall SifWrite16( u32 iopaddr, u16 data );
extern void __fastcall SifWrite32( u32 iopaddr, u32 data );
extern u8 __fastcall iopHwRead8_Page1( u32 iopaddr );
extern u8 __fastcall iopHwRead8_Page3( u32 iopaddr );
extern u8 __fastcall iopHwRead8_Page8( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page1( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page3( u32 iopaddr );
extern u16 __fastcall iopHwRead16_Page8( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page1( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page3( u32 iopaddr );
extern u32 __fastcall iopHwRead32_Page8( u32 iopaddr );
extern void __fastcall iopHwWrite8_Page1( u32 iopaddr, u8 data );
extern void __fastcall iopHwWrite8_Page3( u32 iopaddr, u8 data );
extern void __fastcall iopHwWrite8_Page8( u32 iopaddr, u8 data );
extern void __fastcall iopHwWrite16_Page1( u32 iopaddr, u16 data );
extern void __fastcall iopHwWrite16_Page3( u32 iopaddr, u16 data );
extern void __fastcall iopHwWrite16_Page8( u32 iopaddr, u16 data );
extern void __fastcall iopHwWrite32_Page1( u32 iopaddr, u32 data );
extern void __fastcall iopHwWrite32_Page3( u32 iopaddr, u32 data );
extern void __fastcall iopHwWrite32_Page8( u32 iopaddr, u32 data );
}

View File

@ -39,8 +39,6 @@ void OnCpu_Ok(GtkButton *button, gpointer user_data)
newopts |= PCSX2_FRAMELIMIT_LIMIT;
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitFS"))))
newopts |= PCSX2_FRAMELIMIT_SKIP;
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_VUSkip"))))
newopts |= PCSX2_FRAMELIMIT_VUSKIP;
Config.CustomFps = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(CpuDlg, "CustomFPSLimit")));
Config.CustomFrameSkip = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(CpuDlg, "FrameThreshold")));
@ -88,7 +86,6 @@ void OnConf_Cpu(GtkMenuItem *menuitem, gpointer user_data)
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitNormal")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_NORMAL);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitLimit")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_LIMIT);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_LimitFS")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_SKIP);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(CpuDlg, "GtkRadioButton_VUSkip")), CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_VUSKIP);
sprintf(str, "Cpu Vendor: %s", cpuinfo.x86ID);
gtk_label_set_text(GTK_LABEL(lookup_widget(CpuDlg, "GtkLabel_CpuVendor")), str);

View File

@ -3859,7 +3859,6 @@ create_CpuDlg (void)
GSList *GtkRadioButton_LimitNormal_group = NULL;
GtkWidget *GtkRadioButton_LimitLimit;
GtkWidget *GtkRadioButton_LimitFS;
GtkWidget *GtkRadioButton_VUSkip;
GtkWidget *label41;
GtkWidget *frame23;
GtkWidget *alignment18;
@ -4028,13 +4027,6 @@ create_CpuDlg (void)
gtk_radio_button_set_group (GTK_RADIO_BUTTON (GtkRadioButton_LimitFS), GtkRadioButton_LimitNormal_group);
GtkRadioButton_LimitNormal_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (GtkRadioButton_LimitFS));
GtkRadioButton_VUSkip = gtk_radio_button_new_with_mnemonic (NULL, _("VU Skip - Same as Frame Skip, but tried to skip more. \n Artifacts might be present, but will be faster"));
gtk_widget_set_name (GtkRadioButton_VUSkip, "GtkRadioButton_VUSkip");
gtk_widget_show (GtkRadioButton_VUSkip);
gtk_box_pack_start (GTK_BOX (vbox29), GtkRadioButton_VUSkip, FALSE, FALSE, 0);
gtk_radio_button_set_group (GTK_RADIO_BUTTON (GtkRadioButton_VUSkip), GtkRadioButton_LimitNormal_group);
GtkRadioButton_LimitNormal_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (GtkRadioButton_VUSkip));
label41 = gtk_label_new (_("Frame Limiting (F4 switches in-game)"));
gtk_widget_set_name (label41, "label41");
gtk_widget_show (label41);
@ -4198,7 +4190,6 @@ create_CpuDlg (void)
GLADE_HOOKUP_OBJECT (CpuDlg, GtkRadioButton_LimitNormal, "GtkRadioButton_LimitNormal");
GLADE_HOOKUP_OBJECT (CpuDlg, GtkRadioButton_LimitLimit, "GtkRadioButton_LimitLimit");
GLADE_HOOKUP_OBJECT (CpuDlg, GtkRadioButton_LimitFS, "GtkRadioButton_LimitFS");
GLADE_HOOKUP_OBJECT (CpuDlg, GtkRadioButton_VUSkip, "GtkRadioButton_VUSkip");
GLADE_HOOKUP_OBJECT (CpuDlg, label41, "label41");
GLADE_HOOKUP_OBJECT (CpuDlg, frame23, "frame23");
GLADE_HOOKUP_OBJECT (CpuDlg, alignment18, "alignment18");

View File

@ -6859,27 +6859,6 @@ Version x.x</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="GtkRadioButton_VUSkip">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">VU Skip - Same as Frame Skip, but tried to skip more.
Artifacts might be present, but will be faster</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">GtkRadioButton_LimitNormal</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>

View File

@ -13,8 +13,11 @@ VU0.cpp VU0micro.cpp VU0microInterp.cpp VU1micro.cpp VU1microInterp.cpp VUflags.
Vif.cpp VifDma.cpp vssprintf.cpp vtlb.cpp xmlpatchloader.cpp AlignedMalloc.cpp \
RecoverySystem.cpp Saveslots.cpp Dump.cpp
libpcsx2_a_SOURCES += \
ps2/Iop/IopHwRead.cpp ps2/Iop/IopHwWrite.cpp ps2/Iop/IopHw_Internal.h
libpcsx2_a_SOURCES += \
CDVD.h CDVDiso.h CDVDisodrv.h CDVDlib.h COP0.h Cache.h CdRom.h Common.h Counters.h Decode_XA.h EEregs.h \
CDVD.h CDVDiso.h CDVDisodrv.h CDVDlib.h COP0.h Cache.h CdRom.h Common.h Counters.h Decode_XA.h \
Elfheader.h Exceptions.h GS.h Hw.h IopBios.h IopBios2.h IopCounters.h IopDma.h IopHw.h IopMem.h IopSio2.h Memcpyfast.h \
Memory.h MemoryCard.h Misc.h Patch.h Paths.h Plugins.h PrecompiledHeader.h IopCommon.h R3000A.h R5900.h R5900OpcodeTables.h \
SPR.h SamplProf.h SaveState.h Sif.h Sifcmd.h Sio.h SafeArray.h Stats.h StringUtils.h System.h Threading.h \

View File

@ -618,7 +618,7 @@ static u8* m_psAllMem = NULL;
void memAlloc()
{
if( m_psAllMem == NULL )
m_psAllMem = vtlb_malloc( m_allMemSize, 4096, 0x2400000 );
m_psAllMem = vtlb_malloc( m_allMemSize, 4096 );
if( m_psAllMem == NULL)
throw Exception::OutOfMemory( "memAlloc > failed to allocate PS2's base ram/rom/scratchpad." );

View File

@ -370,12 +370,19 @@ void CycleFrameLimit(int dir)
newFrameLimit = 0;
} else
newFrameLimit = oldFrameLimit;
} else if (dir > 0) {
// next
newFrameLimit = (curFrameLimit + PCSX2_FRAMELIMIT_LIMIT) & PCSX2_FRAMELIMIT_MASK;
} else {
// previous
newFrameLimit = (curFrameLimit + PCSX2_FRAMELIMIT_VUSKIP) & PCSX2_FRAMELIMIT_MASK;
}
else if (dir > 0) // next
{
newFrameLimit = curFrameLimit + PCSX2_FRAMELIMIT_LIMIT;
if( newFrameLimit > PCSX2_FRAMELIMIT_SKIP )
newFrameLimit = 0;
}
else // previous
{
if( newFrameLimit == 0 )
newFrameLimit = PCSX2_FRAMELIMIT_SKIP;
else
newFrameLimit = curFrameLimit - PCSX2_FRAMELIMIT_LIMIT;
}
newOptions = (Config.Options & ~PCSX2_FRAMELIMIT_MASK) | newFrameLimit;
@ -390,7 +397,6 @@ void CycleFrameLimit(int dir)
limitMsg = "Limit";
break;
case PCSX2_FRAMELIMIT_SKIP:
case PCSX2_FRAMELIMIT_VUSKIP:
if( GSsetFrameSkip == NULL )
{
newOptions &= ~PCSX2_FRAMELIMIT_MASK;
@ -402,7 +408,7 @@ void CycleFrameLimit(int dir)
// When enabling Skipping we have to make sure Skipper (GS) and Limiter (EE)
// are properly synchronized.
gsDynamicSkipEnable();
limitMsg = ((newOptions & PCSX2_FRAMELIMIT_MASK) == PCSX2_FRAMELIMIT_SKIP) ? "Skip" : "VUSkip";
limitMsg = "Skip";
}
break;

View File

@ -18,7 +18,7 @@
#ifndef __PATCH_H__
#define __PATCH_H__
#include "PS2Etypes.h"
#include "Pcsx2Defs.h"
//
// Defines

View File

@ -86,8 +86,7 @@ typedef int BOOL;
// need a full recompile anyway, when modified (etc)
#include "zlib/zlib.h"
#include "PS2Etypes.h"
#include "Pcsx2Defs.h"
#include "Paths.h"
#include "Config.h"
#include "StringUtils.h"
@ -152,35 +151,20 @@ static __forceinline u32 timeGetTime()
# define __releaseinline __forceinline
#endif
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Dev / Debug conditionals --
// Consts for using if() statements instead of uglier #ifdef macros.
// Abbreviated macros for dev/debug only consoles and msgboxes.
#ifdef PCSX2_DEVBUILD
# define DevCon Console
# define DevMsg MsgBox
static const bool IsDevBuild = true;
static const bool IsDevBuild = true;
#else
# define DevCon 0&&Console
# define DevMsg
static const bool IsDevBuild = false;
static const bool IsDevBuild = false;
#endif
#ifdef _DEBUG
# define DbgCon Console
static const bool IsDebugBuild = true;
static const bool IsDebugBuild = true;
#else
# define DbgCon 0&&Console
static const bool IsDebugBuild = false;
static const bool IsDebugBuild = false;
#endif
#endif
#endif

View File

@ -335,43 +335,96 @@ void spyFunctions(){
}
}
*/
/*********************************************************
* Register branch logic *
* Format: OP rs, offset *
*********************************************************/
#define RepZBranchi32(op) if(_i32(_rRs_) op 0) doBranch(_BranchTarget_);
#define RepZBranchLinki32(op) if(_i32(_rRs_) op 0) { _SetLink(31); doBranch(_BranchTarget_); }
void psxBGEZ() { RepZBranchi32(>=) } // Branch if Rs >= 0
void psxBGEZAL() { RepZBranchLinki32(>=) } // Branch if Rs >= 0 and link
void psxBGTZ() { RepZBranchi32(>) } // Branch if Rs > 0
void psxBLEZ() { RepZBranchi32(<=) } // Branch if Rs <= 0
void psxBLTZ() { RepZBranchi32(<) } // Branch if Rs < 0
void psxBLTZAL() { RepZBranchLinki32(<) } // Branch if Rs < 0 and link
void psxBGEZ() // Branch if Rs >= 0
{
if (_i32(_rRs_) >= 0) doBranch(_BranchTarget_);
}
void psxBGEZAL() // Branch if Rs >= 0 and link
{
if (_i32(_rRs_) >= 0)
{
_SetLink(31);
doBranch(_BranchTarget_);
}
}
void psxBGTZ() // Branch if Rs > 0
{
if (_i32(_rRs_) > 0) doBranch(_BranchTarget_);
}
void psxBLEZ() // Branch if Rs <= 0
{
if (_i32(_rRs_) <= 0) doBranch(_BranchTarget_);
}
void psxBLTZ() // Branch if Rs < 0
{
if (_i32(_rRs_) < 0) doBranch(_BranchTarget_);
}
void psxBLTZAL() // Branch if Rs < 0 and link
{
if (_i32(_rRs_) < 0)
{
_SetLink(31);
doBranch(_BranchTarget_);
}
}
/*********************************************************
* Register branch logic *
* Format: OP rs, rt, offset *
*********************************************************/
#define RepBranchi32(op) if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_);
void psxBEQ() { RepBranchi32(==) } // Branch if Rs == Rt
void psxBNE() { RepBranchi32(!=) } // Branch if Rs != Rt
void psxBEQ() // Branch if Rs == Rt
{
if (_i32(_rRs_) == _i32(_rRt_)) doBranch(_BranchTarget_);
}
void psxBNE() // Branch if Rs != Rt
{
if (_i32(_rRs_) != _i32(_rRt_)) doBranch(_BranchTarget_);
}
/*********************************************************
* Jump to target *
* Format: OP target *
*********************************************************/
void psxJ() { doBranch(_JumpTarget_); }
void psxJAL() { _SetLink(31); doBranch(_JumpTarget_); /*spyFunctions();*/ }
void psxJ()
{
doBranch(_JumpTarget_);
}
void psxJAL()
{
_SetLink(31);
doBranch(_JumpTarget_);
/*spyFunctions();*/
}
/*********************************************************
* Register jump *
* Format: OP rs, rd *
*********************************************************/
void psxJR() { doBranch(_u32(_rRs_)); }
void psxJALR() { if (_Rd_) { _SetLink(_Rd_); } doBranch(_u32(_rRs_)); }
void psxJR()
{
doBranch(_u32(_rRs_));
}
void psxJALR()
{
if (_Rd_)
{
_SetLink(_Rd_);
}
doBranch(_u32(_rRs_));
}
///////////////////////////////////////////
// These macros are used to assemble the repassembler functions

View File

@ -18,7 +18,7 @@
#ifndef _R5900_OPCODETABLES_H
#define _R5900_OPCODETABLES_H
#include "PS2Etypes.h"
#include "Pcsx2Defs.h"
// TODO : Move these into the OpcodeTables namespace
extern void (*Int_COP2PrintTable[32])();

View File

@ -129,13 +129,15 @@ void SysDetect()
"\t%sDetected SSE2\n"
"\t%sDetected SSE3\n"
"\t%sDetected SSSE3\n"
"\t%sDetected SSE4.1\n", params
"\t%sDetected SSE4.1\n"
"\t%sDetected SSE4.2\n", params
cpucaps.hasMultimediaExtensions ? "" : "Not ",
cpucaps.hasStreamingSIMDExtensions ? "" : "Not ",
cpucaps.hasStreamingSIMD2Extensions ? "" : "Not ",
cpucaps.hasStreamingSIMD3Extensions ? "" : "Not ",
cpucaps.hasSupplementalStreamingSIMD3Extensions ? "" : "Not ",
cpucaps.hasStreamingSIMD4Extensions ? "" : "Not "
cpucaps.hasStreamingSIMD4Extensions ? "" : "Not ",
cpucaps.hasStreamingSIMD4Extensions2 ? "" : "Not "
);
if ( cpuinfo.x86ID[0] == 'A' ) //AMD cpu
@ -144,10 +146,12 @@ void SysDetect()
WriteLn(
"\t%sDetected MMX2\n"
"\t%sDetected 3DNOW\n"
"\t%sDetected 3DNOW2\n", params
"\t%sDetected 3DNOW2\n"
"\t%sDetected SSE4a\n", params
cpucaps.hasMultimediaExtensionsExt ? "" : "Not ",
cpucaps.has3DNOWInstructionExtensions ? "" : "Not ",
cpucaps.has3DNOWInstructionExtensionsExt ? "" : "Not "
cpucaps.has3DNOWInstructionExtensionsExt ? "" : "Not ",
cpucaps.hasStreamingSIMD4ExtensionsA ? "" : "Not "
);
}
@ -162,6 +166,7 @@ bool SysAllocateMem()
try
{
vtlb_Core_Alloc();
memAlloc();
psxMemAlloc();
vuMicroMemAlloc();
@ -278,6 +283,7 @@ void SysShutdownMem()
vuMicroMemShutdown();
psxMemShutdown();
memShutdown();
vtlb_Core_Shutdown();
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -320,9 +326,6 @@ void SysClearExecutionCache()
psxCpu->Reset();
vuMicroCpuReset();
// make sure the VU1 doesn't have lingering "skip" enabled.
vu1MicroDisableSkip();
}
__forceinline void SysUpdate()

View File

@ -18,6 +18,8 @@
#pragma once
#include "Pcsx2Defs.h"
#include "Paths.h"
#include "Pcsx2Config.h"
#include "SafeArray.h"
#include "Misc.h"
@ -199,3 +201,23 @@ using Console::Color_Magenta;
using Console::Color_Cyan;
using Console::Color_Yellow;
using Console::Color_White;
//////////////////////////////////////////////////////////////////////////////////////////
// Dev / Debug conditionals --
// Consts for using if() statements instead of uglier #ifdef macros.
// Abbreviated macros for dev/debug only consoles and msgboxes.
#ifdef PCSX2_DEVBUILD
# define DevCon Console
# define DevMsg MsgBox
#else
# define DevCon 0&&Console
# define DevMsg
#endif
#ifdef _DEBUG
# define DbgCon Console
#else
# define DbgCon 0&&Console
#endif

View File

@ -22,7 +22,7 @@
#include <errno.h> // EBUSY
#include <semaphore.h>
#include "PS2Etypes.h"
#include "Pcsx2Defs.h"
namespace Threading
{

View File

@ -123,10 +123,6 @@ extern void vu1ResetRegs();
extern void vu1ExecMicro(u32 addr);
extern void vu1Exec(VURegs* VU);
extern void vu1MicroEnableSkip();
extern void vu1MicroDisableSkip();
extern bool vu1MicroIsSkipping();
void VU0_UPPER_FD_00();
void VU0_UPPER_FD_01();
void VU0_UPPER_FD_10();

View File

@ -38,21 +38,6 @@ static void DummyExecuteVU1Block(void)
VU1.vifRegs->stat &= ~4; // also reset the bit (grandia 3 works)
}
void vu1MicroEnableSkip()
{
CpuVU1.ExecuteBlock = DummyExecuteVU1Block;
}
void vu1MicroDisableSkip()
{
CpuVU1.ExecuteBlock = CHECK_VU1REC ? recVU1.ExecuteBlock : intVU1.ExecuteBlock;
}
bool vu1MicroIsSkipping()
{
return CpuVU1.ExecuteBlock == DummyExecuteVU1Block;
}
void vuMicroCpuReset()
{
CpuVU0 = CHECK_VU0REC ? recVU0 : intVU0;
@ -83,7 +68,7 @@ static const uint m_vuMemSize =
void vuMicroMemAlloc()
{
if( m_vuAllMem == NULL )
m_vuAllMem = vtlb_malloc( m_vuMemSize, 16, 0x28000000 );
m_vuAllMem = vtlb_malloc( m_vuMemSize, 16 );
if( m_vuAllMem == NULL )
throw Exception::OutOfMemory( "vuMicroMemInit > Failed to allocate VUmicro memory." );

View File

@ -295,7 +295,7 @@ static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int
break;
case 0xC:
vif->tag.addr += size;
VIFUNPACK_LOG("Processing V4-32 skip, size = %d, CL = %d, WL = %d", size, vif1Regs->cycle.cl, vif1Regs->cycle.wl);
VIFUNPACK_LOG("Processing V4-32 skip, size = %d, CL = %d, WL = %d", size, vifRegs->cycle.cl, vifRegs->cycle.wl);
break;
case 0xD:
vif->tag.addr += (size / unpack->gsize) * 16;
@ -350,12 +350,18 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
{
VU = &VU0;
vifRegs = vif0Regs;
vifMaskRegs = g_vif0Masks;
vif = &vif0;
vifRow = g_vifRow0;
assert(v->addr < memsize);
}
else
{
VU = &VU1;
vifRegs = vif1Regs;
vifMaskRegs = g_vif1Masks;
vif = &vif1;
vifRow = g_vifRow1;
assert(v->addr < memsize);
}
@ -376,7 +382,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
memsize = size;
#endif
if(vif1Regs->offset != 0)
if(vifRegs->offset != 0)
{
int unpacksize;
@ -411,29 +417,46 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
if (vifRegs->cycle.cl != vifRegs->cycle.wl)
{
vif->tag.addr += (((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + ((4 - ft->qsize) + unpacksize)) * 4;
//dest += ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + destinc;
dest += ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + (4 - ft->qsize) + unpacksize;
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
}
else
{
vif->tag.addr += ((4 - ft->qsize) + unpacksize) * 4;
//dest += destinc;
dest += (4 - ft->qsize) + unpacksize;
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
}
cdata += unpacksize * ft->dsize;
vif->cl = 0;
VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
return size >> 2;
if((size & 0xf) == 0)return size >> 2;
}
else
{
vif->tag.addr += ((4 - ft->qsize) + unpacksize) * 4;
dest += (4 - ft->qsize) + unpacksize;
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
cdata += unpacksize * ft->dsize;
VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
}
}
if (vif->cl != 0) //Check alignment for SSE unpacks
if (vif->cl != 0 || (size & 0xf)) //Check alignment for SSE unpacks
{
#ifdef _DEBUG
@ -444,8 +467,13 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write
{
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
// continuation from last stream
VIFUNPACK_LOG("Continuing last stream size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr);
incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4;
while ((size >= ft->gsize) && (vifRegs->num > 0))
@ -460,12 +488,20 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
{
dest += incdest;
vif->tag.addr += incdest * 4;
vif->cl = 0;
break;
if((size & 0xf) == 0)break;
}
else
{
dest += 4;
vif->tag.addr += 16;
}
if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
dest += 4;
vif->tag.addr += 16;
}
if(vifRegs->mode == 2)
@ -479,6 +515,32 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
}
}
if (size >= ft->dsize && vifRegs->num > 0 && ((size & 0xf) != 0 || vif->cl != 0))
{
//VIF_LOG("warning, end with size = %d", size);
/* unpack one qword */
if(vif->tag.addr + ((size / ft->dsize) * 4) >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
//DevCon::Notice("Overflow");
vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
vif->tag.addr += (size / ft->dsize) * 4;
func(dest, (u32*)cdata, size / ft->dsize);
size = 0;
if(vifRegs->mode == 2)
{
//Update the reg rows for SSE
vifRow[0] = vifRegs->r0;
vifRow[1] = vifRegs->r1;
vifRow[2] = vifRegs->r2;
vifRow[3] = vifRegs->r3;
}
VIFUNPACK_LOG("leftover done, size %d, vifnum %d, addr %x", size, vifRegs->num, vif->tag.addr);
}
}
return size>>2;
}
@ -504,6 +566,9 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
{
VU = &VU0;
vifRegs = vif0Regs;
vifMaskRegs = g_vif0Masks;
vif = &vif0;
vifRow = g_vifRow0;
assert(v->addr < memsize);
}
else
@ -511,14 +576,10 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
VU = &VU1;
vifRegs = vif1Regs;
vifMaskRegs = g_vif1Masks;
vif = &vif1;
vifRow = g_vifRow1;
assert(v->addr < memsize);
if (vu1MicroIsSkipping())
{
// don't process since the frame is dummy
vif->tag.addr += (size / (VIFfuncTable[ vif->cmd & 0xf ].gsize * vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16);
return;
}
}
dest = (u32*)(VU->Mem + v->addr);
@ -548,9 +609,16 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
#ifdef _DEBUG
static int s_count = 0;
#endif
if(v->addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
//DevCon::Notice("Overflown at the start");
v->addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
tempsize = min(vifRegs->num, (size / ft->gsize));
tempsize = (vif->tag.addr + (size / (ft->gsize * vifRegs->cycle.wl)) *
((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16)) + ((size / ft->gsize) * 16);
((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16)) + (tempsize * 16);
//Sanity Check (memory overflow)
if(tempsize > (u32)(VIFdmanum ? 0x4000 : 0x1000))
@ -671,11 +739,18 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
{
int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4;
size = 0;
if((tempsize >> 2) != vif->tag.size) DevCon::Notice("split when size != tagsize");
VIFUNPACK_LOG("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, vif->tag.addr);
while ((tempsize >= ft->gsize) && (vifRegs->num > 0))
{
//VIFUNPACK_LOG("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, vif->tag.addr);
if(v->addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
v->addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
func(dest, (u32*)cdata, ft->qsize);
cdata += ft->gsize;
tempsize -= ft->gsize;
@ -685,15 +760,13 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
if (vif->cl == vifRegs->cycle.wl)
{
dest += incdest;
v->addr = (v->addr + (incdest * 4)) & (VIFdmanum ? 0x3fff : 0xfff);
if(v->addr <= (u32)(VIFdmanum ? 0x3000 : 0x500)) dest = (u32*)(VU->Mem + v->addr);
v->addr += (incdest * 4);
vif->cl = 0;
}
else
{
dest += 4;
v->addr = (v->addr + 16) & (VIFdmanum ? 0x3fff : 0xfff);
if(v->addr <= (u32)(VIFdmanum ? 0x3000 : 0x500)) dest = (u32*)(VU->Mem + v->addr);
v->addr += 16;
}
}
@ -705,6 +778,11 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
vifRow[2] = vifRegs->r2;
vifRow[3] = vifRegs->r3;
}
if(v->addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000))
{
v->addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff);
dest = (u32*)(VU->Mem + v->addr);
}
if(tempsize > 0) size = tempsize;
}
@ -735,7 +813,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
if((u32)(((size / ft->gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num)
DevCon::Notice("Filling write warning! %x < %x and CL = %x WL = %x", params (size / ft->gsize), vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl);
VIFUNPACK_LOG("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType);
DevCon::Notice("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", params vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType, vif->tag.addr);
while (vifRegs->num > 0)
{
if (vif->cl == vifRegs->cycle.wl)
@ -872,9 +950,7 @@ static __forceinline void vif0UNPACK(u32 *data)
vif0.tag.size = len;
vif0Regs->offset = 0;
vifMaskRegs = g_vif0Masks;
vif = &vif0;
vifRow = g_vifRow0;
}
static __forceinline void vif0mpgTransfer(u32 addr, u32 *data, int size)
@ -983,6 +1059,7 @@ static int __fastcall Vif0TransMPG(u32 *data) // MPG
{
if (vif0.vifpacketsize < vif0.tag.size)
{
if((vif0.tag.addr + vif0.vifpacketsize) > 0x1000) DevCon::Notice("Vif0 MPG Split Overflow");
vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize);
vif0.tag.addr += vif0.vifpacketsize << 2;
vif0.tag.size -= vif0.vifpacketsize;
@ -991,7 +1068,7 @@ static int __fastcall Vif0TransMPG(u32 *data) // MPG
else
{
int ret;
if((vif0.tag.addr + vif0.tag.size) > 0x1000) DevCon::Notice("Vif0 MPG Overflow");
vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size);
ret = vif0.tag.size;
vif0.tag.size = 0;
@ -1633,9 +1710,6 @@ static __forceinline void vif1UNPACK(u32 *data)
vif1.tag.addr <<= 4;
vif1.tag.cmd = vif1.cmd;
vifMaskRegs = g_vif1Masks;
vif = &vif1;
vifRow = g_vifRow1;
}
static __forceinline void vif1mpgTransfer(u32 addr, u32 *data, int size)
@ -1742,6 +1816,7 @@ static int __fastcall Vif1TransMPG(u32 *data)
{
if (vif1.vifpacketsize < vif1.tag.size)
{
if((vif1.tag.addr + vif1.vifpacketsize) > 0x4000) DevCon::Notice("Vif1 MPG Split Overflow");
vif1mpgTransfer(vif1.tag.addr, data, vif1.vifpacketsize);
vif1.tag.addr += vif1.vifpacketsize << 2;
vif1.tag.size -= vif1.vifpacketsize;
@ -1750,6 +1825,7 @@ static int __fastcall Vif1TransMPG(u32 *data)
else
{
int ret;
if((vif1.tag.addr + vif1.tag.size) > 0x4000) DevCon::Notice("Vif1 MPG Overflow");
vif1mpgTransfer(vif1.tag.addr, data, vif1.tag.size);
ret = vif1.tag.size;
vif1.tag.size = 0;

View File

@ -38,7 +38,7 @@ fi
WARNING_FLAGS="-Wno-format -Wno-unused-parameter -Wno-unused-value -Wunused-variable "
EXTRA_WARNING_FLAGS="-Wall -Wextra"
NORMAL_FLAGS=" -pipe -msse -msse2 -O2 ${WARNING_FLAGS}"
# These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off.
# These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off. Comment if not on 4.3+
NORMAL_FLAGS+=" -fno-guess-branch-probability -fno-dse -fno-tree-dse "
DEBUG_FLAGS+=" -g -msse -msse2 ${EXTRA_WARNING_FLAGS} ${WARNING_FLAGS} "
@ -93,24 +93,6 @@ then
fi
AC_MSG_RESULT($devbuild)
AC_MSG_CHECKING(force sse3 instructions)
AC_ARG_ENABLE(sse3, AC_HELP_STRING([--enable-sse3], [Forces sse3 detection on CPUs]),
sse3=$enableval,sse3=no)
if test "x$sse3" == xyes
then
AC_DEFINE(PCSX2_FORCESSE3,1,[PCSX2_FORCESSE3])
fi
AC_MSG_RESULT(sse3)
AC_MSG_CHECKING(force sse4 instructions)
AC_ARG_ENABLE(sse4, AC_HELP_STRING([--enable-sse4], [Forces sse4 detection on CPUs]),
sse4=$enableval,sse4=no)
if test "x$sse4" == xyes
then
AC_DEFINE(PCSX2_FORCESSE4,1,[PCSX2_FORCESSE4])
fi
AC_MSG_RESULT(sse4)
dnl gtk
AC_MSG_CHECKING(gtk+)
AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config)
@ -178,7 +160,6 @@ echo "Configuration:"
echo " Target system type: $target"
echo " Debug build? $debug"
echo " Dev build? $devbuild"
echo " Force sse3? $sse3"
echo " nls support? $nls"
echo " local plugin inis? $localinis"
echo " custom cflags? $customcflags"

445
pcsx2/ps2/Iop/IopHwRead.cpp Normal file
View File

@ -0,0 +1,445 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 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 "IopHw_Internal.h"
namespace IopMemory
{
using namespace Internal;
//////////////////////////////////////////////////////////////////////////////////////////
//
u8 __fastcall iopHwRead8_Page1( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 );
u32 masked_addr = addr & 0x0fff;
u8 ret; // using a return var can be helpful in debugging.
switch( masked_addr )
{
mcase(HW_SIO_DATA): ret = sioRead8(); break;
// for use of serial port ignore for now
//case 0x50: ret = serial_read8(); break;
mcase(HW_DEV9_DATA): ret = DEV9read8( addr ); break;
mcase(HW_CDR_DATA0): ret = cdrRead0(); break;
mcase(HW_CDR_DATA1): ret = cdrRead1(); break;
mcase(HW_CDR_DATA2): ret = cdrRead2(); break;
mcase(HW_CDR_DATA3): ret = cdrRead3(); break;
default:
if( masked_addr >= 0x100 && masked_addr < 0x130 )
{
DevCon::Notice( "*Hardware Read8 from Counter16 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) );
ret = psxHu8( addr );
}
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
{
DevCon::Notice( "*Hardware Read8 from Counter32 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) );
ret = psxHu8( addr );
}
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
{
ret = USBread8( addr );
PSXHW_LOG( "Hardware Read8 from USB: addr 0x%08x = 0x%02x", addr, ret );
}
else
{
ret = psxHu8(addr);
PSXHW_LOG( "*Unknown Hardware Read8 from addr 0x%08x = 0x%02x", addr, ret );
}
return ret;
}
PSXHW_LOG( "*Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u8 __fastcall iopHwRead8_Page3( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
u8 ret;
if( addr == 0x1f803100 ) // PS/EE/IOP conf related
ret = 0x10; // Dram 2M
else
ret = psxHu8( addr );
PSXHW_LOG( "Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>( addr ), addr, psxHu8(addr) );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u8 __fastcall iopHwRead8_Page8( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u8 ret;
if( addr == HW_SIO2_FIFO )
ret = sio2_fifoOut();//sio2 serial data feed/fifo_out
else
ret = psxHu8( addr );
PSXHW_LOG( "Hardware Read8 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>( addr ), addr, psxHu8(addr) );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
template< typename T >
static __forceinline T _HwRead_16or32_Page1( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 );
// all addresses should be aligned to the data operand size:
jASSUME(
( sizeof(T) == 2 && (addr & 1) == 0 ) ||
( sizeof(T) == 4 && (addr & 3) == 0 )
);
u32 masked_addr = pgmsk( addr );
T ret;
// ------------------------------------------------------------------------
// Counters, 16-bit varieties!
//
if( masked_addr >= 0x100 && masked_addr < 0x130 )
{
int cntidx = ( masked_addr >> 4 ) & 0xf;
switch( masked_addr & 0xf )
{
case 0x0:
ret = (T)psxRcntRcount16( cntidx );
break;
case 0x4:
ret = psxCounters[cntidx].mode;
// hmm! The old code only did this bitwise math for 16 bit reads.
// Logic indicates it should do the math consistently. Question is,
// should it do the logic for both 16 and 32, or not do logic at all?
psxCounters[cntidx].mode &= ~0x1800;
psxCounters[cntidx].mode |= 0x400;
break;
case 0x8:
ret = psxCounters[cntidx].target;
break;
default:
ret = psxHu32(addr);
break;
}
}
// ------------------------------------------------------------------------
// Counters, 32-bit varieties!
//
else if( masked_addr >= 0x480 && masked_addr < 0x4b0 )
{
int cntidx = (( masked_addr >> 4 ) & 0xf) - 5;
switch( masked_addr & 0xf )
{
case 0x0:
ret = (T)psxRcntRcount32( cntidx );
break;
case 0x2:
ret = (T)(psxRcntRcount32( cntidx ) >> 16);
break;
case 0x4:
ret = psxCounters[cntidx].mode;
// hmm! The old code only did the following bitwise math for 16 bit reads.
// Logic indicates it should do the math consistently. Question is,
// should it do the logic for both 16 and 32, or not do logic at all?
psxCounters[cntidx].mode &= ~0x1800;
psxCounters[cntidx].mode |= 0x400;
break;
case 0x8:
ret = psxCounters[cntidx].target;
break;
case 0xa:
ret = psxCounters[cntidx].target >> 16;
break;
default:
ret = psxHu32(addr);
break;
}
}
// ------------------------------------------------------------------------
// USB, with both 16 and 32 bit interfaces
//
else if( masked_addr >= pgmsk(HW_USB_START) && masked_addr < pgmsk(HW_USB_END) )
{
ret = (sizeof(T) == 2) ? USBread16( addr ) : USBread32( addr );
}
// ------------------------------------------------------------------------
// SPU2, accessible in 16 bit mode only!
//
else if( masked_addr >= pgmsk(HW_SPU2_START) && masked_addr < pgmsk(HW_SPU2_END) )
{
if( sizeof(T) == 2 )
ret = SPU2read( addr );
else
{
DevCon::Notice( "*PCSX2* SPU2 Hardware Read32 (addr=0x%08X)? What manner of trickery is this?!", params addr );
ret = psxHu32(addr);
}
}
else
{
switch( masked_addr )
{
// ------------------------------------------------------------------------
mcase(HW_SIO_DATA):
ret = sioRead8();
ret |= sioRead8() << 8;
if( sizeof(T) == 4 )
{
ret |= sioRead8() << 16;
ret |= sioRead8() << 24;
}
break;
mcase(HW_SIO_STAT):
ret = sio.StatReg;
break;
mcase(HW_SIO_MODE):
ret = sio.ModeReg;
if( sizeof(T) == 4 )
{
// My guess on 32-bit accesses. Dunno yet what the real hardware does. --air
ret |= sio.CtrlReg << 16;
}
break;
mcase(HW_SIO_CTRL):
ret = sio.CtrlReg;
break;
mcase(HW_SIO_BAUD):
ret = sio.BaudReg;
break;
// ------------------------------------------------------------------------
//Serial port stuff not support now ;P
// case 0x050: hard = serial_read32(); break;
// case 0x054: hard = serial_status_read(); break;
// case 0x05a: hard = serial_control_read(); break;
// case 0x05e: hard = serial_baud_read(); break;
mcase(HW_ICTRL):
ret = psxHu32(0x1078);
psxHu32(0x1078) = 0;
break;
mcase(HW_ICTRL+2):
ret = psxHu16(0x107a);
psxHu32(0x1078) = 0; // most likely should clear all 32 bits here.
break;
// ------------------------------------------------------------------------
// Soon-to-be outdated SPU2 DMA hack (spu2 manages its own DMA MADR).
//
mcase(0x1f8010C0):
ret = SPU2ReadMemAddr(0);
break;
mcase(0x1f801500):
ret = SPU2ReadMemAddr(1);
break;
// ------------------------------------------------------------------------
// Legacy GPU emulation (not needed).
// The IOP emulates the GPU itself through the EE's hardware.
/*case 0x810:
PSXHW_LOG("GPU DATA 32bit write %lx", value);
GPU_writeData(value); return;
case 0x814:
PSXHW_LOG("GPU STATUS 32bit write %lx", value);
GPU_writeStatus(value); return;
case 0x820:
mdecWrite0(value); break;
case 0x824:
mdecWrite1(value); break;*/
// ------------------------------------------------------------------------
mcase(0x1f80146e):
ret = DEV9read16( addr );
break;
default:
ret = psxHu32(addr);
break;
}
}
PSXHW_LOG( "Hardware Read%s from %s, addr 0x%08x = 0x%04x",
(sizeof(T) == 2) ? "16" : "32", _log_GetIopHwName<T>( addr ), addr, ret
);
return ret;
}
// Some Page 2 mess? I love random question marks for comments!
//case 0x1f802030: hard = //int_2000????
//case 0x1f802040: hard =//dip switches...??
//////////////////////////////////////////////////////////////////////////////////////////
//
u16 __fastcall iopHwRead16_Page1( u32 addr )
{
return _HwRead_16or32_Page1<u16>( addr );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u16 __fastcall iopHwRead16_Page3( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
u16 ret = psxHu16(addr);
PSXHW_LOG( "Hardware Read16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u16 __fastcall iopHwRead16_Page8( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u16 ret = psxHu16(addr);
PSXHW_LOG( "Hardware Read16 from %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u32 __fastcall iopHwRead32_Page1( u32 addr )
{
return _HwRead_16or32_Page1<u32>( addr );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u32 __fastcall iopHwRead32_Page3( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
const u32 ret = psxHu32(addr);
PSXHW_LOG( "Hardware Read32 from %s, addr 0x%08x = 0x%08x", _log_GetIopHwName<u32>( addr ), addr, ret );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
u32 __fastcall iopHwRead32_Page8( u32 addr )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u32 masked_addr = addr & 0x0fff;
u32 ret;
if( masked_addr >= 0x200 )
{
if( masked_addr < 0x240 )
{
const int parm = (masked_addr-0x200) / 4;
ret = sio2_getSend3( parm );
}
else if( masked_addr < 0x260 )
{
// SIO2 Send commands alternate registers. First reg maps to Send1, second
// to Send2, third to Send1, etc. And the following clever code does this:
const int parm = (masked_addr-0x240) / 8;
ret = (masked_addr & 4) ? sio2_getSend2( parm ) : sio2_getSend1( parm );
}
else
{
switch( masked_addr )
{
mcase(0x1f801264): // unknown / reserved.
ret = psxHu32(addr);
break;
mcase(HW_SIO2_CTRL):
ret = sio2_getCtrl();
break;
mcase(HW_SIO2_RECV1):
ret = sio2_getRecv1();
break;
mcase(HW_SIO2_RECV2):
ret = sio2_getRecv2();
break;
mcase(HW_SIO2_RECV3):
ret = sio2_getRecv3();
break;
mcase(0x1f808278):
ret = sio2_get8278();
break;
mcase(0x1f80827C):
ret = sio2_get827C();
break;
mcase(HW_SIO2_INTR):
ret = sio2_getIntr();
break;
jNO_DEFAULT;
}
}
}
else ret = psxHu32(addr);
PSXHW_LOG( "Hardware Read32 from %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u32>( addr ), addr, ret );
return ret;
}
}

View File

@ -0,0 +1,529 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 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 "IopHw_Internal.h"
namespace IopMemory {
using namespace Internal;
//////////////////////////////////////////////////////////////////////////////////////////
//
void __fastcall iopHwWrite8_Page1( u32 addr, u8 val )
{
// all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 );
u32 masked_addr = pgmsk( addr );
switch( masked_addr )
{
mcase(HW_SIO_DATA): sioWrite8( val ); break;
// for use of serial port ignore for now
//case 0x50: serial_write8( val ); break;
mcase(HW_DEV9_DATA): DEV9write8( addr, val ); break;
mcase(HW_CDR_DATA0): cdrWrite0( val ); break;
mcase(HW_CDR_DATA1): cdrWrite1( val ); break;
mcase(HW_CDR_DATA2): cdrWrite2( val ); break;
mcase(HW_CDR_DATA3): cdrWrite3( val ); break;
default:
if( masked_addr >= 0x100 && masked_addr < 0x130 )
{
DevCon::Notice( "*Hardware Write8 to Counter16 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) );
psxHu8( addr ) = val;
}
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
{
DevCon::Notice( "*Hardware Write8 to Counter32 [ignored] [addr=0x%02x]", params addr, psxHu8(addr) );
psxHu8( addr ) = val;
}
else if( masked_addr >= pgmsk(HW_USB_START) && masked_addr < pgmsk(HW_USB_END) )
{
USBwrite8( addr, val );
}
else
{
psxHu8(addr) = val;
}
break;
}
PSXHW_LOG( "*Hardware Write8 to %s, addr 0x%08x = 0x%02x\n", _log_GetIopHwName<u8>(addr), addr, val );
}
static char g_pbuf[1024];
static int g_pbufi;
void __fastcall iopHwWrite8_Page3( u32 addr, u8 val )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
if( addr == 0x1f80380c ) // STDOUT
{
bool flush = false;
// Terminate lines on CR or full buffers, and ignore \n's if the string contents
// are empty (otherwise terminate on \n too!)
if( ( val == '\r' ) || ( g_pbufi == 1023 ) ||
( val == '\n' && g_pbufi != 0 ) )
{
g_pbuf[g_pbufi] = 0;
DevCon::WriteLn( Color_Cyan, g_pbuf );
g_pbufi = 0;
}
else if( val != '\n' )
{
g_pbuf[g_pbufi++] = val;
}
}
PSXHW_LOG( "Hardware Write8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>(addr), addr, psxHu8(addr) );
psxHu8( addr ) = val;
}
void __fastcall iopHwWrite8_Page8( u32 addr, u8 val )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
if( addr == HW_SIO2_DATAIN ) // sio2 serial data feed input
sio2_serialIn( val );
else
psxHu8( addr ) = val;
PSXHW_LOG( "Hardware Write8 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u8>(addr), addr, psxHu8(addr) );
}
// Template-compatible version of the psxHu macro. Used for writing.
#define psxHu(mem) (*(u32*)&psxH[(mem) & 0xffff])
//////////////////////////////////////////////////////////////////////////////////////////
// Templated handler for both 32 and 16 bit write operations, to Page 1 registers.
//
template< typename T >
static __forceinline void _HwWrite_16or32_Page1( u32 addr, T val )
{
// all addresses are assumed to be prefixed with 0x1f801xxx:
jASSUME( (addr >> 12) == 0x1f801 );
// all addresses should be aligned to the data operand size:
jASSUME(
( sizeof(T) == 2 && (addr & 1) == 0 ) ||
( sizeof(T) == 4 && (addr & 3) == 0 )
);
u32 masked_addr = addr & 0x0fff;
// ------------------------------------------------------------------------
// Counters, 16-bit varieties!
//
if( masked_addr >= 0x100 && masked_addr < 0x130 )
{
int cntidx = ( masked_addr >> 4 ) & 0xf;
switch( masked_addr & 0xf )
{
case 0x0:
psxRcntWcount16( cntidx, val );
break;
case 0x4:
psxRcntWmode16( cntidx, val );
break;
case 0x8:
psxRcntWtarget16( cntidx, val );
break;
default:
psxHu(addr) = val;
break;
}
}
// ------------------------------------------------------------------------
// Counters, 32-bit varieties!
//
else if( masked_addr >= 0x480 && masked_addr < 0x4b0 )
{
int cntidx = (( masked_addr >> 4 ) & 0xf) - 5;
switch( masked_addr & 0xf )
{
case 0x0:
psxRcntWcount32( cntidx, val );
break;
case 0x2: // Count HiWord
psxRcntWcount32( cntidx, (u32)val << 16 );
break;
case 0x4:
psxRcntWmode32( cntidx, val );
break;
case 0x8:
psxRcntWtarget32( cntidx, val );
break;
case 0xa: // Target HiWord
psxRcntWtarget32( cntidx, (u32)val << 16);
break;
default:
psxHu(addr) = val;
break;
}
}
// ------------------------------------------------------------------------
// USB, with both 16 and 32 bit interfaces
//
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
{
if( sizeof(T) == 2 ) USBwrite16( addr, val ); else USBwrite32( addr, val );
}
// ------------------------------------------------------------------------
// SPU2, accessible in 16 bit mode only!
//
else if( (masked_addr >= pgmsk(HW_SPU2_START)) && (masked_addr < pgmsk(HW_SPU2_END)) )
{
if( sizeof(T) == 2 )
SPU2write( addr, val );
else
{
DevCon::Notice( "*PCSX2* SPU2 Hardware Write32 (addr=0x%08X)? What manner of trickery is this?!", params addr );
//psxHu(addr) = val;
}
}
else
{
switch( masked_addr )
{
// ------------------------------------------------------------------------
mcase(HW_SIO_DATA):
sioWrite8( (u8)val );
sioWrite8( (u8)(val >> 8) );
if( sizeof(T) == 4 )
{
// u32 gets rid of compiler warnings when using the u16 version of this template
sioWrite8( (u8)((u32)val >> 16) );
sioWrite8( (u8)((u32)val >> 24) );
}
break;
mcase(HW_SIO_STAT): // read-only?
//regname = "SIO_STAT (read-only?)";
//sio.StatReg;
break;
mcase(HW_SIO_MODE):
sio.ModeReg = (u16)val;
if( sizeof(T) == 4 )
{
// My guess on 32-bit accesses. Dunno yet what the real hardware does. --air
sio.CtrlReg = (u16)((u32)val >> 16);
}
break;
mcase(HW_SIO_CTRL):
sio.CtrlReg = (u16)val;
break;
mcase(HW_SIO_BAUD):
sio.BaudReg = (u16)val;
break;
// ------------------------------------------------------------------------
//Serial port stuff not support now ;P
// case 0x050: serial_write16( val ); break;
// case 0x054: serial_status_write( val ); break;
// case 0x05a: serial_control_write( val ); break;
// case 0x05e: serial_baud_write( val ); break;
mcase(HW_IREG):
psxHu(addr) &= val;
break;
mcase(HW_IREG+2):
psxHu(addr) &= val;
break;
mcase(HW_IMASK):
psxHu(addr) = val;
iopTestIntc();
break;
mcase(HW_IMASK+2):
psxHu(addr) = val;
iopTestIntc();
break;
mcase(HW_ICTRL):
psxHu(addr) = val;
iopTestIntc();
break;
mcase(HW_ICTRL+2):
psxHu(addr) = val;
iopTestIntc();
break;
// ------------------------------------------------------------------------
// Soon-to-be outdated SPU2 DMA hack (spu2 manages its own DMA MADR currently,
// as asinine as that may seem).
//
mcase(0x1f8010C0):
SPU2WriteMemAddr( 0, val );
HW_DMA4_MADR = val;
break;
mcase(0x1f801500):
SPU2WriteMemAddr( 1, val );
HW_DMA7_MADR = val;
break;
// ------------------------------------------------------------------------
//
/*
mcase(0x1f801088): // DMA0 CHCR -- MDEC IN [ignored]
DmaExec(0);
break;
mcase(0x1f801098): // DMA1 CHCR -- MDEC OUT [ignored]
DmaExec(1);
break;
mcase(0x1f8010a8): // DMA2 CHCR -- GPU [ignored]
DmaExec(2);
break;*/
mcase(0x1f8010b8): // DMA3 CHCR -- CDROM
psxHu(addr) = val;
DmaExec(3);
break;
mcase(0x1f8010c8): // DMA4 CHCR -- SPU2 Core 1
psxHu(addr) = val;
DmaExecNew(4);
break;
mcase(0x1f8010e8): // DMA6 CHCR -- OT clear
psxHu(addr) = val;
DmaExec(6);
break;
mcase(0x1f801508): // DMA7 CHCR -- SPU2 core 2
psxHu(addr) = val;
DmaExecNew2(7);
break;
mcase(0x1f801518): // DMA8 CHCR -- DEV9
psxHu(addr) = val;
DmaExec2(8);
break;
mcase(0x1f801528): // DMA9 CHCR -- SIF0
psxHu(addr) = val;
DmaExec2(9);
break;
mcase(0x1f801538): // DMA10 CHCR -- SIF1
psxHu(addr) = val;
DmaExec2(10);
break;
mcase(0x1f801548): // DMA11 CHCR -- SIO2 IN
psxHu(addr) = val;
DmaExec2(11);
break;
mcase(0x1f801558): // DMA12 CHCR -- SIO2 OUT
psxHu(addr) = val;
DmaExec2(12);
break;
// ------------------------------------------------------------------------
// DMA ICR handlers -- General XOR behavior!
mcase(0x1f8010f4):
{
u32 tmp = (~val) & HW_DMA_ICR;
psxHu(addr) = ((tmp ^ val) & 0xffffff) ^ tmp;
}
break;
mcase(0x1f8010f6): // ICR_hi (16 bit?) [dunno if it ever happens]
{
const u32 val2 = (u32)val << 16;
const u32 tmp = (~val2) & HW_DMA_ICR;
psxHu(addr) = (((tmp ^ val2) & 0xffffff) ^ tmp) >> 16;
}
break;
mcase(0x1f801574):
{
u32 tmp = (~val) & HW_DMA_ICR2;
psxHu(addr) = ((tmp ^ val) & 0xffffff) ^ tmp;
}
break;
mcase(0x1f801576): // ICR2_hi (16 bit?) [dunno if it ever happens]
{
const u32 val2 = (u32)val << 16;
const u32 tmp = (~val2) & HW_DMA_ICR2;
psxHu(addr) = (((tmp ^ val2) & 0xffffff) ^ tmp) >> 16;
}
break;
// ------------------------------------------------------------------------
// Legacy GPU emulation (not needed).
// The IOP emulates the GPU itself through the EE's hardware.
/*case 0x810:
PSXHW_LOG("GPU DATA 32bit write %lx", value);
GPU_writeData(value); return;
case 0x814:
PSXHW_LOG("GPU STATUS 32bit write %lx", value);
GPU_writeStatus(value); return;
case 0x820:
mdecWrite0(value); break;
case 0x824:
mdecWrite1(value); break;*/
// ------------------------------------------------------------------------
mcase(HW_DEV9_DATA):
DEV9write16( addr, val );
psxHu(addr) = val;
break;
default:
psxHu(addr) = val;
break;
}
}
PSXHW_LOG( "Hardware Write%s to %s, addr 0x%08x = 0x%04x",
sizeof(T) == 2 ? "16" : "32", _log_GetIopHwName<T>( addr ), addr, val
);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void __fastcall iopHwWrite16_Page1( u32 addr, u16 val )
{
_HwWrite_16or32_Page1<u16>( addr, val );
}
void __fastcall iopHwWrite16_Page3( u32 addr, u16 val )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
psxHu16(addr) = val;
PSXHW_LOG( "Hardware Write16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, val );
}
void __fastcall iopHwWrite16_Page8( u32 addr, u16 val )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
psxHu16(addr) = val;
PSXHW_LOG( "Hardware Write16 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, val );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void __fastcall iopHwWrite32_Page1( u32 addr, u32 val )
{
_HwWrite_16or32_Page1<u32>( addr, val );
}
void __fastcall iopHwWrite32_Page3( u32 addr, u32 val )
{
// all addresses are assumed to be prefixed with 0x1f803xxx:
jASSUME( (addr >> 12) == 0x1f803 );
psxHu16(addr) = val;
PSXHW_LOG( "Hardware Write32 to %s, addr 0x%08x = 0x%04x", _log_GetIopHwName<u16>( addr ), addr, val );
}
void __fastcall iopHwWrite32_Page8( u32 addr, u32 val )
{
// all addresses are assumed to be prefixed with 0x1f808xxx:
jASSUME( (addr >> 12) == 0x1f808 );
u32 masked_addr = addr & 0x0fff;
if( masked_addr >= 0x200 )
{
if( masked_addr < 0x240 )
{
const int parm = (masked_addr-0x200) / 4;
sio2_setSend3( parm, val );
}
else if( masked_addr < 0x260 )
{
// SIO2 Send commands alternate registers. First reg maps to Send1, second
// to Send2, third to Send1, etc. And the following clever code does this:
const int parm = (masked_addr-0x240) / 8;
if(masked_addr & 4) sio2_setSend2( parm, val ); else sio2_setSend1( parm, val );
}
else
{
switch( masked_addr )
{
case 0x264: // unknown / reserved.
case 0x26C: // recv1 [read-only]
case 0x270: // recv2 [read-only]
case 0x274: // recv3 [read-only]
psxHu32(addr) = val;
break;
case 0x268:
sio2_setCtrl( val );
break;
case 0x278:
sio2_set8278( val );
break;
case 0x27C:
sio2_set827C( val );
break;
case 0x280:
sio2_setIntr( val );
break;
jNO_DEFAULT;
}
}
}
else psxHu32(addr) = val;
PSXHW_LOG( "Hardware Write32 to %s, addr 0x%08x = 0x%02x", _log_GetIopHwName<u32>( addr ), addr, val );
}
}

View File

@ -0,0 +1,204 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 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
*/
#pragma once
#include "IopCommon.h"
namespace IopMemory {
namespace Internal {
//////////////////////////////////////////////////////////////////////////////////////////
// Masking helper so that I can use the fully qualified address for case statements.
// Switches are based on the bottom 12 bits only, since MSVC tends to optimize switches
// better when it has a limited width operand to work with. :)
//
#define pgmsk( src ) ( (src) & 0x0fff )
#define mcase( src ) case pgmsk(src)
//////////////////////////////////////////////////////////////////////////////////////////
// Helper for debug logging of IOP Registers. Takes an input address and retuns a
// register name.
//
// This list is not yet exhaustive. If you spot something that's missing, feel free to
// fill it in any time. :)
//
template< typename T>
static __forceinline const char* _log_GetIopHwName( u32 addr )
{
switch( addr )
{
// ------------------------------------------------------------------------
// SSBUS -- Two Ess'es?
case HW_SSBUS_SPD_ADDR: return "SSBUS spd_addr";
case HW_SSBUS_PIO_ADDR: return "SSBUS pio_addr";
case HW_SSBUS_SPD_DELAY: return "SSBUS spd_delay";
case HW_SSBUS_DEV1_DELAY: return "SSBUS dev1_delay";
case HW_SSBUS_ROM_DELAY: return "SSBUS rom_delay";
case HW_SSBUS_SPU_DELAY: return "SSBUS spu_delay";
case HW_SSBUS_DEV5_DELAY: return "SSBUS dev5_delay";
case HW_SSBUS_PIO_DELAY: return "SSBUS pio_delay";
case HW_SSBUS_COM_DELAY: return "SSBUS com_delay";
case HW_SSBUS_DEV1_ADDR: return "SSBUS dev1_addr";
case HW_SSBUS_SPU_ADDR: return "SSBUS spu_addr";
case HW_SSBUS_DEV5_ADDR: return "SSBUS dev5_addr";
case HW_SSBUS_SPU1_ADDR: return "SSBUS spu1_addr";
case HW_SSBUS_DEV9_ADDR3: return "SSBUS dev9_addr3";
case HW_SSBUS_SPU1_DELAY: return "SSBUS spu1_delay";
case HW_SSBUS_DEV9_DELAY2: return "SSBUS dev9_delay2";
case HW_SSBUS_DEV9_DELAY3: return "SSBUS dev9_delay3";
case HW_SSBUS_DEV9_DELAY1: return "SSBUS dev9_delay1";
// ------------------------------------------------------------------------
case 0x1f801060:return "RAM_SIZE";
case HW_IREG: return "IREG";
case HW_IREG+2: return "IREG_hi";
case HW_IMASK: return "IMASK";
case HW_IMASK+2:return "IMASK_hi";
case HW_ICTRL: return "ICTRL";
case HW_ICTRL+2:return "ICTRL_hi";
case HW_ICFG: return "ICFG";
case HW_SIO_DATA: return "SIO";
case HW_SIO_STAT: return "SIO STAT";
case HW_SIO_MODE: return ( sizeof(T) == 4 ) ? "SIO_MODE+CTRL" : "SIO MODE";
case HW_SIO_CTRL: return "SIO CTRL";
case HW_SIO_BAUD: return "SIO BAUD";
case 0x1f8014c0: return "RTC_HOLDMODE";
case HW_DEV9_DATA: return "DEV9_R_REV/DATA";
// ------------------------------------------------------------------------
// BCR_LABEL -- Selects label for BCR depending on operand size (BCR has hi
// and low values of count and size, respectively)
#define BCR_LABEL( dma ) (sizeof(T)==4) ? dma" BCR" : dma" BCR_size";
case 0x1f8010a0: return "DMA2 MADR";
case 0x1f8010a4: return BCR_LABEL( "DMA2" );
case 0x1f8010a6: return "DMA2 BCR_count";
case 0x1f8010a8: return "DMA2 CHCR";
case 0x1f8010ac: return "DMA2 TADR";
case 0x1f8010b0: return "DMA3 MADR";
case 0x1f8010b4: return BCR_LABEL( "DMA3" );
case 0x1f8010b6: return "DMA3 BCR_count";
case 0x1f8010b8: return "DMA3 CHCR";
case 0x1f8010bc: return "DMA3 TADR";
case 0x1f8010c0: return "[SPU]DMA4 MADR";
case 0x1f8010c4: return BCR_LABEL( "DMA4" );
case 0x1f8010c6: return "[SPU]DMA4 BCR_count";
case 0x1f8010c8: return "[SPU]DMA4 CHCR";
case 0x1f8010cc: return "[SPU]DMA4 TADR";
case 0x1f8010f0: return "DMA PCR";
case 0x1f8010f4: return "DMA ICR";
case 0x1f8010f6: return "DMA ICR_hi";
case 0x1f801500: return "[SPU2]DMA7 MADR";
case 0x1f801504: return BCR_LABEL( "DMA7" );
case 0x1f801506: return "[SPU2]DMA7 BCR_count";
case 0x1f801508: return "[SPU2]DMA7 CHCR";
case 0x1f80150C: return "[SPU2]DMA7 TADR";
case 0x1f801520: return "DMA9 MADR";
case 0x1f801524: return BCR_LABEL( "DMA9" );
case 0x1f801526: return "DMA9 BCR_count";
case 0x1f801528: return "DMA9 CHCR";
case 0x1f80152C: return "DMA9 TADR";
case 0x1f801530: return "DMA10 MADR";
case 0x1f801534: return BCR_LABEL( "DMA10" );
case 0x1f801536: return "DMA10 BCR_count";
case 0x1f801538: return "DMA10 CHCR";
case 0x1f80153c: return "DMA10 TADR";
case 0x1f801570: return "DMA PCR2";
case 0x1f801574: return "DMA ICR2";
case 0x1f801576: return "DMA ICR2_hi";
case HW_CDR_DATA0: return "CDROM DATA0";
case HW_CDR_DATA1: return "CDROM DATA1";
case HW_CDR_DATA2: return "CDROM DATA2";
case HW_CDR_DATA3: return "CDROM DATA3";
case 0x1f80380c: return "STDOUT";
// ------------------------------------------------------------------------
case HW_SIO2_FIFO: return "SIO2 FIFO";
case HW_SIO2_CTRL: return "SIO2 CTRL";
case HW_SIO2_RECV1: return "SIO2 RECV1";
case HW_SIO2_RECV2: return "SIO2 RECV2";
case HW_SIO2_RECV3: return "SIO2 RECV3";
case HW_SIO2_INTR: return "SIO2 INTR";
case 0x1f808278: return "SIO2 8278";
case 0x1f80827C: return "SIO2 827C";
// ------------------------------------------------------------------------
// Check for "zoned" registers in the default case.
// And if all that fails, return "unknown"! :)
default:
if( addr >= 0x1f801100 && addr < 0x1f801130 )
{
switch( addr & 0xf )
{
case 0x0: return "CNT16_COUNT";
case 0x4: return "CNT16_MODE";
case 0x8: return "CNT16_TARGET";
default: return "Invalid Counter";
}
}
else if( addr >= 0x1f801480 && addr < 0x1f8014b0 )
{
switch( addr & 0xf )
{
case 0x0: return "CNT32_COUNT";
case 0x2: return "CNT32_COUNT_hi";
case 0x4: return "CNT32_MODE";
case 0x8: return "CNT32_TARGET";
case 0xa: return "CNT32_TARGET_hi";
default: return "Invalid Counter";
}
}
else if( (addr >= HW_USB_START) && (addr < HW_USB_END) )
{
return "USB";
}
else if( (addr >= HW_SPU2_START) && (addr < HW_SPU2_END) )
{
return "SPU2";
}
else if( addr >= 0x1f808200 )
{
if( addr < 0x1f808240 )
return "SIO2 param";
else if( addr < 0x260 )
return "SIO2 send";
}
return "Unknown";
}
}
} };

View File

@ -61,7 +61,6 @@ vtlbHandler UnmappedVirtHandler1;
vtlbHandler UnmappedPhyHandler0;
vtlbHandler UnmappedPhyHandler1;
/*
__asm
{
@ -87,7 +86,7 @@ callfunction:
jmp [readfunctions8-0x800000+eax];
}*/
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Interpreter Implementations of VTLB Memory Operations.
// See recVTLB.cpp for the dynarec versions.
@ -117,6 +116,7 @@ __forceinline DataType __fastcall MemOp_r0(u32 addr)
}
}
// ------------------------------------------------------------------------
// Interpreterd VTLB lookup for 64 and 128 bit accesses.
template<int DataSize,typename DataType>
__forceinline void __fastcall MemOp_r1(u32 addr, DataType* data)
@ -148,6 +148,7 @@ __forceinline void __fastcall MemOp_r1(u32 addr, DataType* data)
}
}
// ------------------------------------------------------------------------
template<int DataSize,typename DataType>
__forceinline void __fastcall MemOp_w0(u32 addr, DataType data)
{
@ -174,6 +175,8 @@ __forceinline void __fastcall MemOp_w0(u32 addr, DataType data)
}
}
}
// ------------------------------------------------------------------------
template<int DataSize,typename DataType>
__forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)
{
@ -202,7 +205,6 @@ __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)
}
}
mem8_t __fastcall vtlb_memRead8(u32 mem)
{
return MemOp_r0<8,mem8_t>(mem);
@ -328,7 +330,7 @@ void __fastcall vtlbDefaultPhyWrite64(u32 addr,const mem64_t* data) { Console::E
void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data) { Console::Error("vtlbDefaultPhyWrite128: 0x%X",params addr); verify(false); }
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// VTLB Public API -- Init/Term/RegisterHandler stuff
//
@ -361,6 +363,7 @@ vtlbHandler vtlb_RegisterHandler( vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP
return rv;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Maps the given hander (created with vtlb_RegisterHandler) to the specified memory region.
// New mappings always assume priority over previous mappings, so place "generic" mappings for
// large areas of memory first, and then specialize specific small regions of memory afterward.
@ -500,7 +503,8 @@ void vtlb_VMapUnmap(u32 vaddr,u32 sz)
}
}
// Clears vtlb handlers and memory mappings.
//////////////////////////////////////////////////////////////////////////////////////////
// vtlb_init -- Clears vtlb handlers and memory mappings.
void vtlb_Init()
{
vtlbHandlerCount=0;
@ -540,7 +544,8 @@ void vtlb_Init()
vtlb_VMapUnmap((VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE,VTLB_PAGE_SIZE);
}
// Performs a COP0-level reset of the PS2's TLB.
//////////////////////////////////////////////////////////////////////////////////////////
// vtlb_Reset -- Performs a COP0-level reset of the PS2's TLB.
// This function should probably be part of the COP0 rather than here in VTLB.
void vtlb_Reset()
{
@ -552,30 +557,65 @@ void vtlb_Term()
//nothing to do for now
}
//////////////////////////////////////////////////////////////////////////////////////////
// Reserves the vtlb core allocation used by various emulation components!
//
void vtlb_Core_Alloc()
{
if( vtlbdata.alloc_base != NULL ) return;
vtlbdata.alloc_current = 0;
#ifdef __LINUX__
vtlbdata.alloc_base = SysMmapEx( 0x16000000, VTLB_ALLOC_SIZE, 0x80000000, "Vtlb" );
#else
// Win32 just needs this, since malloc always maps below 2GB.
vtlbdata.alloc_base = (u8*)_aligned_malloc( VTLB_ALLOC_SIZE, 4096 );
if( vtlbdata.alloc_base == NULL )
throw Exception::OutOfMemory( "Fatal Error: could not allocate 42Meg buffer for PS2's mappable system ram." );
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void vtlb_Core_Shutdown()
{
if( vtlbdata.alloc_base == NULL ) return;
#ifdef __LINUX__
SafeSysMunmap( vtlbdata.alloc_base, VTLB_ALLOC_SIZE );
#else
// Make sure and unprotect memory first, since CrtDebug will try to write to it.
HostSys::MemProtect( vtlbdata.alloc_base, VTLB_ALLOC_SIZE, Protect_ReadWrite );
safe_aligned_free( vtlbdata.alloc_base );
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
// This function allocates memory block with are compatible with the Vtlb's requirements
// for memory locations. The Vtlb requires the topmost bit (Sign bit) of the memory
// pointer to be cleared. Some operating systems and/or implementations of malloc do that,
// but others do not. So use this instead to allocate the memory correctly for your
// platform.
u8* vtlb_malloc( uint size, uint align, uptr tryBaseAddress )
//
u8* vtlb_malloc( uint size, uint align )
{
#ifdef __LINUX__
return SysMmapEx( tryBaseAddress, size, 0x80000000, "Vtlb" );
#else
// Win32 just needs this, since malloc always maps below 2GB.
return (u8*)_aligned_malloc(size, align);
#endif
vtlbdata.alloc_current += align-1;
vtlbdata.alloc_current &= ~(align-1);
int rv = vtlbdata.alloc_current;
vtlbdata.alloc_current += size;
return &vtlbdata.alloc_base[rv];
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void vtlb_free( void* pmem, uint size )
{
if( pmem == NULL ) return;
#ifdef __LINUX__
SafeSysMunmap( pmem, size );
#else
// Make sure and unprotect memory first, since CrtDebug will try to write to it.
HostSys::MemProtect( pmem, size, Protect_ReadWrite );
safe_aligned_free( pmem );
#endif
// Does nothing anymore! Alloc/dealloc is now handled by vtlb_Core_Alloc /
// vtlb_Core_Shutdown. Placebo is left in place in case it becomes useful again
// at a later date.
return;
}

View File

@ -23,10 +23,12 @@ typedef void __fastcall vtlbMemW128FP(u32 addr,const mem128_t* data);
typedef u32 vtlbHandler;
extern void vtlb_Core_Alloc();
extern void vtlb_Core_Shutdown();
extern void vtlb_Init();
extern void vtlb_Reset();
extern void vtlb_Term();
extern u8* vtlb_malloc( uint size, uint align, uptr tryBaseAddress );
extern u8* vtlb_malloc( uint size, uint align );
extern void vtlb_free( void* pmem, uint size );
@ -67,6 +69,8 @@ extern void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const );
namespace vtlb_private
{
static const uint VTLB_ALLOC_SIZE = 0x2900000; //this is a bit more than required
static const uint VTLB_PAGE_BITS = 12;
static const uint VTLB_PAGE_MASK = 4095;
static const uint VTLB_PAGE_SIZE = 4096;
@ -77,6 +81,9 @@ namespace vtlb_private
struct MapData
{
u8* alloc_base; //base of the memory array
int alloc_current; //current base
s32 pmap[VTLB_PMAP_ITEMS]; //512KB
s32 vmap[VTLB_VMAP_ITEMS]; //4MB

View File

@ -134,7 +134,6 @@ BOOL CALLBACK CpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
if( SendDlgItemMessage(hW,IDC_CPU_FL_NORMAL,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_NORMAL;
else if( SendDlgItemMessage(hW,IDC_CPU_FL_LIMIT,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_LIMIT;
else if( SendDlgItemMessage(hW,IDC_CPU_FL_SKIP,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_SKIP;
else if( SendDlgItemMessage(hW,IDC_CPU_FL_SKIPVU,BM_GETCHECK,0,0) ) newopts |= PCSX2_FRAMELIMIT_VUSKIP;
GetDlgItemText(hW, IDC_CUSTOMFPS, cfps, 20);
Config.CustomFps = atoi(cfps);

View File

@ -1625,6 +1625,22 @@
>
</File>
</Filter>
<Filter
Name="Hardware"
>
<File
RelativePath="..\..\ps2\Iop\IopHw_Internal.h"
>
</File>
<File
RelativePath="..\..\ps2\Iop\IopHwRead.cpp"
>
</File>
<File
RelativePath="..\..\ps2\Iop\IopHwWrite.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="IPU"
@ -2536,6 +2552,14 @@
RelativePath="..\..\NewGUI\LogOptionsDialog.h"
>
</File>
<File
RelativePath="..\..\NewGUI\SpeedHacksDialog.cpp"
>
</File>
<File
RelativePath="..\..\NewGUI\SpeedHacksDialog.h"
>
</File>
</Filter>
<Filter
Name="Resources"

View File

@ -196,10 +196,8 @@ void WinRun()
_doPluginOverride( "DEV9", g_Startup.dev9dll, Config.DEV9 );
#ifndef _DEBUG
if( Config.Profiler )
ProfilerInit();
#endif
InitCPUTicks();
@ -798,7 +796,6 @@ LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
SaveConfig();
break;
#ifndef _DEBUG
case ID_PROFILER:
Config.Profiler = !Config.Profiler;
if( Config.Profiler )
@ -813,7 +810,6 @@ LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
SaveConfig();
break;
#endif
default:
if (LOWORD(wParam) >= ID_LANGS && LOWORD(wParam) <= (ID_LANGS + langsMax))
@ -987,9 +983,7 @@ void CreateMainMenu() {
ADDMENUITEM(0,_("Print cdvd &Info"), ID_CDVDPRINT);
ADDMENUITEM(0,_("Close GS Window on Esc"), ID_CLOSEGS);
ADDSEPARATOR(0);
#ifndef _DEBUG
ADDMENUITEM(0,_("Enable &Profiler"), ID_PROFILER);
#endif
ADDMENUITEM(0,_("Enable &Patches"), ID_PATCHES);
ADDMENUITEM(0,_("Enable &Console"), ID_CONSOLE);
ADDSEPARATOR(0);

View File

@ -7,7 +7,8 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxresmw.h"
#include "afxresmw.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@ -899,7 +900,8 @@ END
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -828,7 +828,7 @@ BEGIN
CONTROL "EE Counters log",IDC_EECNTLOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,140,64,11
END
IDD_CPUDLG DIALOGEX 0, 0, 563, 321
IDD_CPUDLG DIALOGEX 0, 0, 563, 305
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
@ -843,13 +843,11 @@ BEGIN
CONTROL "Normal - All frames are rendered as fast as possible.",IDC_CPU_FL_NORMAL,
"Button",BS_AUTORADIOBUTTON | BS_MULTILINE | WS_GROUP,309,17,221,17
CONTROL "Limit - Force frames to normal speeds if too fast.\n (You can set a custom FPS limit below.)",IDC_CPU_FL_LIMIT,
"Button",BS_AUTORADIOBUTTON | BS_MULTILINE,309,33,222,15
"Button",BS_AUTORADIOBUTTON | BS_MULTILINE,309,37,222,15
CONTROL "Frame Skip - In order to achieve normal speeds,\n some frames are skipped (fast).\n Fps displayed counts skipped frames too.",IDC_CPU_FL_SKIP,
"Button",BS_AUTORADIOBUTTON | BS_MULTILINE,309,48,221,28
CONTROL "VU Skip - Same as 'Frame Skip', but tries to skip more.\n Artifacts might be present, but will be faster.",IDC_CPU_FL_SKIPVU,
"Button",BS_AUTORADIOBUTTON | BS_MULTILINE,309,75,220,25
DEFPUSHBUTTON "OK",IDOK,210,298,61,14
PUSHBUTTON "Cancel",IDCANCEL,282,298,61,14,NOT WS_TABSTOP
"Button",BS_AUTORADIOBUTTON | BS_MULTILINE,309,56,221,28
DEFPUSHBUTTON "OK",IDOK,210,287,61,14
PUSHBUTTON "Cancel",IDCANCEL,282,287,61,14,NOT WS_TABSTOP
LTEXT "CPU Vendor",IDC_VENDORNAME,12,23,88,8
LTEXT "Family",IDC_FAMILYNAME,12,41,88,8
LTEXT "Cpu Speed",IDC_CPUSPEEDNAME,12,60,88,8
@ -860,19 +858,19 @@ BEGIN
GROUPBOX "VU Recompilers - All options are set by default",IDC_CPU_VUGROUP,7,119,265,46
LTEXT "Features",IDC_FEATURESNAME,12,78,88,8
GROUPBOX "",IDC_STATIC,7,7,265,90
LTEXT "Custom FPS Limit (0=auto):",IDC_CUSTOM_FPS,327,113,124,12
EDITTEXT IDC_CUSTOMFPS,456,113,53,13,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_CUSTOM_FRAMESKIP,456,130,53,13,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_CUSTOM_CONSECUTIVE_FRAMES,456,148,53,13,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Skip Frames when slower than:\n(See Note 1)",IDC_FRAMESKIP_LABEL1,327,129,106,20
LTEXT "Consecutive Frames before skipping:\n(See Note 2)",IDC_FRAMESKIP_LABEL2,327,149,121,17
GROUPBOX "Frame Limiting (F4 key switches the mode in-game!)",IDC_FRAMELIMIT,301,7,250,280
GROUPBOX "Detailed Settings",IDC_FRAMELIMIT_OPTIONS,310,99,234,185
LTEXT "*Note 1: Will only skip when slower than this fps number.\n (0 = Auto) ; (9999 = Forced-Frameskip regardless of speed.)\n (e.g. If set to 45, will only skip when slower than 45fps.)",IDC_FRAMESKIP_LABEL3,318,189,217,26
LTEXT "*Note 2: Will render this number of consecutive frames before\n skipping the next frame. (0=default)\n (e.g. If set to 2, will render 2 frames before skipping 1.)",IDC_FRAMESKIP_LABEL4,318,216,217,25
EDITTEXT IDC_CUSTOM_CONSECUTIVE_SKIP,456,166,53,13,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Consecutive Frames to skip:\n(See Note 3)",IDC_FRAMESKIP_LABEL5,327,167,121,17
LTEXT "*Note 3: Will skip this number of frames before\n rendering the next sequence of frames. (0=default)\n (e.g. If set to 2, will skip 2 consecutive frames whenever its time\n to skip.)",IDC_FRAMESKIP_LABEL6,318,244,217,32
LTEXT "Custom FPS Limit (0=auto):",IDC_CUSTOM_FPS,327,103,124,12
EDITTEXT IDC_CUSTOMFPS,456,103,53,13,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_CUSTOM_FRAMESKIP,456,121,53,13,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_CUSTOM_CONSECUTIVE_FRAMES,456,139,53,13,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Skip Frames when slower than:\n(See Note 1)",IDC_FRAMESKIP_LABEL1,327,119,106,20
LTEXT "Consecutive Frames before skipping:\n(See Note 2)",IDC_FRAMESKIP_LABEL2,327,139,121,17
GROUPBOX "Frame Limiting (F4 key switches the mode in-game!)",IDC_FRAMELIMIT,301,7,250,274
GROUPBOX "Detailed Settings",IDC_FRAMELIMIT_OPTIONS,310,89,234,185
LTEXT "*Note 1: Will only skip when slower than this fps number.\n (0 = Auto) ; (9999 = Forced-Frameskip regardless of speed.)\n (e.g. If set to 45, will only skip when slower than 45fps.)",IDC_FRAMESKIP_LABEL3,318,179,217,26
LTEXT "*Note 2: Will render this number of consecutive frames before\n skipping the next frame. (0=default)\n (e.g. If set to 2, will render 2 frames before skipping 1.)",IDC_FRAMESKIP_LABEL4,318,206,217,25
EDITTEXT IDC_CUSTOM_CONSECUTIVE_SKIP,456,157,53,13,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Consecutive Frames to skip:\n(See Note 3)",IDC_FRAMESKIP_LABEL5,327,157,121,17
LTEXT "*Note 3: Will skip this number of frames before\n rendering the next sequence of frames. (0=default)\n (e.g. If set to 2, will skip 2 consecutive frames whenever its time\n to skip.)",IDC_FRAMESKIP_LABEL6,318,234,217,32
END

View File

@ -70,7 +70,7 @@ public:
int LastIndex (u32 startpc) const;
BASEBLOCKEX* GetByX86(uptr ip);
inline int Index (u32 startpc) const
__forceinline int Index (u32 startpc) const
{
int idx = LastIndex(startpc);
// fixme: I changed the parenthesis to be unambiguous, but this needs to be checked to see if ((x or y or z) and w)
@ -83,31 +83,43 @@ public:
return idx;
}
inline BASEBLOCKEX* operator[](int idx)
__forceinline BASEBLOCKEX* operator[](int idx)
{
if (idx < 0 || idx >= (int)blocks.size())
return 0;
return &blocks[idx];
}
inline BASEBLOCKEX* Get(u32 startpc)
__forceinline BASEBLOCKEX* Get(u32 startpc)
{
return (*this)[Index(startpc)];
}
inline void Remove(int idx)
__forceinline void Remove(int idx)
{
//u32 startpc = blocks[idx].startpc;
std::pair<linkiter_t, linkiter_t> range = links.equal_range(blocks[idx].startpc);
for (linkiter_t i = range.first; i != range.second; ++i)
*(u32*)i->second = recompiler - (i->second + 4);
if( IsDevBuild )
{
// Clear the first instruction to 0xcc (breakpoint), as a way to assert if some
// static jumps get left behind to this block. Note: Do not clear more than the
// first byte, since this code is called during exception handlers and event handlers
// both of which expect to be able to return to the recompiled code.
BASEBLOCKEX effu( blocks[idx] );
memset( (void*)effu.fnptr, 0xcc, 1 );
}
// TODO: remove links from this block?
blocks.erase(blocks.begin() + idx);
}
void Link(u32 pc, uptr jumpptr);
inline void Reset()
__forceinline void Reset()
{
blocks.clear();
links.clear();

View File

@ -417,15 +417,20 @@ static void recAlloc()
x86FpuState = FPU_STATE;
}
PCSX2_ALIGNED16( static u16 manual_page[Ps2MemSize::Base >> 12] );
PCSX2_ALIGNED16( static u8 manual_counter[Ps2MemSize::Base >> 12] );
////////////////////////////////////////////////////
void recResetEE( void )
{
DbgCon::Status( "iR5900-32 > Resetting recompiler memory and structures." );
Console::Status( "Issuing EE/iR5900-32 Recompiler Reset [mem/structure cleanup]" );
maxrecmem = 0;
memset_8<0xcc, REC_CACHEMEM>(recMem); // 0xcc is INT3
memzero_ptr<m_recBlockAllocSize>( m_recBlockAlloc );
memzero_obj( manual_page );
memzero_obj( manual_counter );
ClearRecLUT((BASEBLOCK*)m_recBlockAlloc,
(((Ps2MemSize::Base + Ps2MemSize::Rom + Ps2MemSize::Rom1) / 4)));
@ -719,7 +724,6 @@ static void ClearRecLUT(BASEBLOCK* base, int count)
base[i].SetFnptr((uptr)JITCompile);
}
// Returns the offset to the next instruction after any cleared memory
void recClear(u32 addr, u32 size)
{
BASEBLOCKEX* pexblock;
@ -1085,10 +1089,8 @@ void recompileNextInstruction(int delayslot)
s_pCode = (int *)PSM( pc );
assert(s_pCode);
// why?
#ifdef _DEBUG
MOV32ItoR(EAX, pc);
#endif
if( IsDebugBuild )
MOV32ItoR(EAX, pc); // acts as a tag for delimiting recompiled instructions when viewing x86 disasm.
cpuRegs.code = *(int *)s_pCode;
pc += 4;
@ -1137,63 +1139,33 @@ void recompileNextInstruction(int delayslot)
const OPCODE& opcode = GetCurrentInstruction();
// peephole optimizations
#ifdef PCSX2_VM_COISSUE
if( g_pCurInstInfo->info & EEINSTINFO_COREC ) {
//assert( !(g_pCurInstInfo->info & EEINSTINFO_NOREC) );
if( g_pCurInstInfo->numpeeps > 1 ) {
switch(_Opcode_) {
case 30: recLQ_coX(g_pCurInstInfo->numpeeps); break;
case 31: recSQ_coX(g_pCurInstInfo->numpeeps); break;
case 49: recLWC1_coX(g_pCurInstInfo->numpeeps); break;
case 57: recSWC1_coX(g_pCurInstInfo->numpeeps); break;
case 55: recLD_coX(g_pCurInstInfo->numpeeps); break;
case 63: recSD_coX(g_pCurInstInfo->numpeeps, 1); break; //not sure if should be set to 1 or 0; looks like "1" handles alignment, so i'm going with that for now
// if this instruction is a jump or a branch, exit right away
if( delayslot ) {
switch(_Opcode_) {
case 1:
switch(_Rt_) {
case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13:
Console::Notice("branch %x in delay slot!", params cpuRegs.code);
_clearNeededX86regs();
_clearNeededMMXregs();
_clearNeededXMMregs();
return;
}
break;
jNO_DEFAULT
}
pc += g_pCurInstInfo->numpeeps*4;
s_nBlockCycles += (g_pCurInstInfo->numpeeps+1) * opcode.cycles;
g_pCurInstInfo += g_pCurInstInfo->numpeeps;
}
else {
recBSC_co[_Opcode_]();
pc += 4;
g_pCurInstInfo++;
s_nBlockCycles += opcode.cycles*2;
case 2: case 3: case 4: case 5: case 6: case 7: case 0x14: case 0x15: case 0x16: case 0x17:
Console::Notice("branch %x in delay slot!", params cpuRegs.code);
_clearNeededX86regs();
_clearNeededMMXregs();
_clearNeededXMMregs();
return;
}
}
else
#endif
{
//assert( !(g_pCurInstInfo->info & EEINSTINFO_NOREC) );
// if this instruction is a jump or a branch, exit right away
if( delayslot ) {
switch(_Opcode_) {
case 1:
switch(_Rt_) {
case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13:
Console::Notice("branch %x in delay slot!", params cpuRegs.code);
_clearNeededX86regs();
_clearNeededMMXregs();
_clearNeededXMMregs();
return;
}
break;
case 2: case 3: case 4: case 5: case 6: case 7: case 0x14: case 0x15: case 0x16: case 0x17:
Console::Notice("branch %x in delay slot!", params cpuRegs.code);
_clearNeededX86regs();
_clearNeededMMXregs();
_clearNeededXMMregs();
return;
}
}
//If thh COP0 DIE bit is disabled, double the cycles. Happens rarely.
s_nBlockCycles += opcode.cycles * (2 - ((cpuRegs.CP0.n.Config >> 18) & 0x1));
opcode.recompile();
}
//If thh COP0 DIE bit is disabled, double the cycles. Happens rarely.
s_nBlockCycles += opcode.cycles * (2 - ((cpuRegs.CP0.n.Config >> 18) & 0x1));
opcode.recompile();
if( !delayslot ) {
if( s_bFlushReg ) {
@ -1255,14 +1227,16 @@ void badespfn() {
void __fastcall dyna_block_discard(u32 start,u32 sz)
{
DevCon::WriteLn("dyna_block_discard %08X , count %d", params start,sz);
Cpu->Clear(start,sz);
DevCon::WriteLn("dyna_block_discard .. start: %08X count=%d", params start,sz);
Cpu->Clear(start, sz);
}
void __fastcall dyna_block_reset(u32 start,u32 sz)
void __fastcall dyna_page_reset(u32 start,u32 sz)
{
DevCon::WriteLn("dyna_block_reset %08X , count %d", params start,sz);
DevCon::WriteLn("dyna_page_reset .. start=%08X size=%d", params start,sz*4);
Cpu->Clear(start & ~0xfffUL, 0x400);
manual_counter[start >> 12]++;
mmap_MarkCountedRamPage(PSM(start), start & ~0xfffUL);
}
@ -1283,7 +1257,6 @@ void recRecompile( const u32 startpc )
// if recPtr reached the mem limit reset whole mem
if ( ( (uptr)recPtr - (uptr)recMem ) >= REC_CACHEMEM-0x40000 || dumplog == 0xffffffff) {
DevCon::WriteLn( "EE Recompiler data reset" );
recResetEE();
}
if ( ( (uptr)recStackPtr - (uptr)recStack ) >= RECSTACK_SIZE-0x100 ) {
@ -1351,25 +1324,38 @@ void recRecompile( const u32 startpc )
while(1) {
BASEBLOCK* pblock = PC_GETBLOCK(i);
if (i != startpc && pblock->GetFnptr() != (uptr)JITCompile && pblock->GetFnptr() != (uptr)JITCompileInBlock) {
// branch = 3
willbranch3 = 1;
s_nEndBlock = i;
break;
if(i != startpc) // Block size truncation checks.
{
if( (i & 0xffc) == 0x0 ) // breaks blocks at 4k page boundaries
{
willbranch3 = 1;
s_nEndBlock = i;
//DevCon::Notice( "Pagesplit @ %08X : size=%d insts", params startpc, (i-startpc) / 4 );
break;
}
if (pblock->GetFnptr() != (uptr)JITCompile && pblock->GetFnptr() != (uptr)JITCompileInBlock)
{
willbranch3 = 1;
s_nEndBlock = i;
break;
}
}
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
cpuRegs.code = *(int *)PSM(i);
switch(cpuRegs.code >> 26) {
case 0: // special
if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR
s_nEndBlock = i + 8;
s_nHasDelay = 1;
goto StartRecomp;
}
break;
case 1: // regimm
if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) {
@ -1383,7 +1369,6 @@ void recRecompile( const u32 startpc )
goto StartRecomp;
}
break;
case 2: // J
@ -1489,98 +1474,6 @@ StartRecomp:
// instruction being analyzed.
if( usecop2 ) vucycle++;
// peephole optimizations //
#ifdef PCSX2_VM_COISSUE
if( i < s_nEndBlock-4 && recompileCodeSafe(i) ) {
u32 curcode = cpuRegs.code;
u32 nextcode = *(u32*)PSM(i+4);
if( _eeIsLoadStoreCoIssue(curcode, nextcode) && recBSC_co[curcode>>26] != NULL ) {
// rs has to be the same, and cannot be just written
if( ((curcode >> 21) & 0x1F) == ((nextcode >> 21) & 0x1F) && !_eeLoadWritesRs(curcode) ) {
if( _eeIsLoadStoreCoX(curcode) && ((nextcode>>16)&0x1f) != ((curcode>>21)&0x1f) ) {
// see how many stores there are
u32 j;
// use xmmregs since only supporting lwc1,lq,swc1,sq
for(j = i+8; j < s_nEndBlock && j < i+4*iREGCNT_XMM; j += 4 ) {
u32 nncode = *(u32*)PSM(j);
if( (nncode>>26) != (curcode>>26) || ((curcode>>21)&0x1f) != ((nncode>>21)&0x1f) ||
_eeLoadWritesRs(nncode))
break;
}
if( j > i+8 ) {
u32 num = (j-i)>>2; // number of stores that can coissue
assert( num <= iREGCNT_XMM );
g_pCurInstInfo[0].numpeeps = num-1;
g_pCurInstInfo[0].info |= EEINSTINFO_COREC;
while(i < j-4) {
g_pCurInstInfo++;
g_pCurInstInfo[0].info |= EEINSTINFO_NOREC;
i += 4;
}
continue;
}
// fall through
}
// unaligned loadstores
// if LWL, check if LWR and that offsets are +3 away
switch(curcode >> 26) {
case 0x22: // LWL
if( (nextcode>>26) != 0x26 || ((s16)nextcode)+3 != (s16)curcode )
continue;
break;
case 0x26: // LWR
if( (nextcode>>26) != 0x22 || ((s16)nextcode) != (s16)curcode+3 )
continue;
break;
case 0x2a: // SWL
if( (nextcode>>26) != 0x2e || ((s16)nextcode)+3 != (s16)curcode )
continue;
break;
case 0x2e: // SWR
if( (nextcode>>26) != 0x2a || ((s16)nextcode) != (s16)curcode+3 )
continue;
break;
case 0x1a: // LDL
if( (nextcode>>26) != 0x1b || ((s16)nextcode)+7 != (s16)curcode )
continue;
break;
case 0x1b: // LWR
if( (nextcode>>26) != 0x1aa || ((s16)nextcode) != (s16)curcode+7 )
continue;
break;
case 0x2c: // SWL
if( (nextcode>>26) != 0x2d || ((s16)nextcode)+7 != (s16)curcode )
continue;
break;
case 0x2d: // SWR
if( (nextcode>>26) != 0x2c || ((s16)nextcode) != (s16)curcode+7 )
continue;
break;
}
// good enough
g_pCurInstInfo[0].info |= EEINSTINFO_COREC;
g_pCurInstInfo[0].numpeeps = 1;
g_pCurInstInfo[1].info |= EEINSTINFO_NOREC;
g_pCurInstInfo++;
i += 4;
continue;
}
}
}
#endif // end peephole
}
// This *is* important because g_pCurInstInfo is checked a bit later on and
// if it's not equal to s_pInstCache it handles recompilation differently.
@ -1610,57 +1503,86 @@ StartRecomp:
iDumpBlock(startpc, recPtr);
#endif
static u16 manual_page[Ps2MemSize::Base >> 12];
u32 sz=(s_nEndBlock-startpc)>>2;
u32 sz = (s_nEndBlock-startpc) >> 2;
u32 inpage_ptr = HWADDR(startpc);
u32 inpage_sz = sz*4;
u32 inpage_ptr=HWADDR(startpc);
u32 inpage_sz=sz*4;
// note: blocks are guaranteed to reside within the confines of a single page.
while(inpage_sz)
const int PageType = mmap_GetRamPageInfo((u32*)PSM(inpage_ptr));
const u32 inpage_offs = inpage_ptr & 0xFFF;
//const u32 pgsz = std::min(0x1000 - inpage_offs, inpage_sz);
const u32 pgsz = inpage_sz;
if(PageType!=-1)
{
int PageType = mmap_GetRamPageInfo((u32*)PSM(inpage_ptr));
u32 inpage_offs = inpage_ptr & 0xFFF;
u32 pgsz = std::min(0x1000 - inpage_offs, inpage_sz);
if(PageType!=-1)
if (PageType==0) {
mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF);
manual_page[inpage_ptr >> 12] = 0;
}
else
{
if (PageType==0) {
mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF);
manual_page[inpage_ptr >> 12] = 0;
xMOV( ecx, inpage_ptr );
xMOV( edx, pgsz / 4 );
//xMOV( eax, startpc ); // uncomment this to access startpc (as eax) in dyna_block_discard
u32 lpc = inpage_ptr;
u32 stg = pgsz;
while(stg>0)
{
xCMP( ptr32[PSM(lpc)], *(u32*)PSM(lpc) );
xJNE( dyna_block_discard );
stg -= 4;
lpc += 4;
}
// Tweakpoint! 3 is a 'magic' number representing the number of times a counted block
// is re-protected before the recompiler gives up and sets it up as an uncounted (permanent)
// manual block. Higher thresholds result in more recompilations for blocks that share code
// and data on the same page. Side effects of a lower threshold: over extended gameplay
// with several map changes, a game's overall performance could degrade.
// (ideally, perhaps, manual_counter should be reset to 0 every few minutes?)
if (startpc != 0x81fc0 && manual_counter[inpage_ptr >> 12] <= 3) {
// Counted blocks add a weighted (by block size) value into manual_page each time they're
// run. If the block gets run a lot, it resets and re-protects itself in the hope
// that whatever forced it to be manually-checked before was a 1-time deal.
// Counted blocks have a secondary threshold check in manual_counter, which forces a block
// to 'uncounted' mode if it's recompiled several time. This protects against excessive
// recompilation of blocks that reside on the same codepage as data.
// fixme? Currently this algo is kinda dumb and results in the forced recompilation of a
// lot of blocks before it decides to mark a 'busy' page as uncounted. There might be
// be a more clever approach that could streamline this process, by doing a first-pass
// test using the vtlb memory protection (without recompilation!) to reprotect a counted
// block. But unless a new also is relatively simple in implementation, it's probably
// not worth the effort (tests show that we have lots of recompiler memory to spare, and
// that the current amount of recompilation is fairly cheap).
xADD(ptr16[&manual_page[inpage_ptr >> 12]], sz);
xJC( dyna_page_reset );
// note: clearcnt is measured per-page, not per-block!
DbgCon::WriteLn( "Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d clearcnt=%d",
params startpc, sz, inpage_ptr>>12, inpage_offs, inpage_sz, manual_counter[inpage_ptr >> 12] );
}
else
{
MOV32ItoR(ECX, inpage_ptr);
MOV32ItoR(EDX, pgsz);
u32 lpc=inpage_ptr;
u32 stg=pgsz;
while(stg>0)
{
// was dyna_block_discard_recmem. See note in recResetEE for details.
CMP32ItoM((uptr)PSM(lpc),*(u32*)PSM(lpc));
JNE32(((u32)&dyna_block_discard)- ( (u32)x86Ptr + 6 ));
stg-=4;
lpc+=4;
}
if (startpc != 0x81fc0) {
xADD(ptr16[&manual_page[inpage_ptr >> 12]], 1);
xJC( dyna_block_reset );
}
DbgCon::WriteLn("Manual block @ %08X : %08X %d %d %d %d", params
startpc,inpage_ptr,pgsz,0x1000-inpage_offs,inpage_sz,sz*4);
DbgCon::Notice( "Uncounted Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d",
params startpc, sz, inpage_ptr>>12, inpage_offs, pgsz, inpage_sz );
}
}
inpage_ptr+=pgsz;
inpage_sz-=pgsz;
}
// finally recompile //
}
}
// Finally: Generate x86 recompiled code!
g_pCurInstInfo = s_pInstCache;
while (!branch && pc < s_nEndBlock) {
recompileNextInstruction(0);
recompileNextInstruction(0); // For the love of recursion, batman!
}
#ifdef _DEBUG
@ -1725,8 +1647,20 @@ StartRecomp:
ADD32ItoM((int)&cpuRegs.cycle, eeScaleBlockCycles() );
if( willbranch3 || !branch) {
iFlushCall(FLUSH_EVERYTHING);
iBranchTest(pc);
// Split Block concatenation mode.
// This code is run when blocks are split either to keep block sizes manageable
// or because we're crossing a 4k page protection boundary in ps2 mem. The latter
// case can result in very short blocks which should not issue branch tests for
// performance reasons.
int numinsts = (pc - startpc) / 4;
if( numinsts > 12 )
iBranchTest(pc);
else
iBranch(pc,0); // unconditional static link
}
}

View File

@ -27,27 +27,83 @@
using namespace vtlb_private;
using namespace x86Emitter;
// NOTICE: This function *destroys* EAX!!
// Moves 128 bits of memory from the source register ptr to the dest register ptr.
// (used as an equivalent to movaps, when a free XMM register is unavailable for some reason)
void MOV128_MtoM( x86IntRegType destRm, x86IntRegType srcRm )
//////////////////////////////////////////////////////////////////////////////////////////
// iAllocRegSSE -- allocates an xmm register. If no xmm register is available, xmm0 is
// saved into g_globalXMMData and returned as a free register.
//
class iAllocRegSSE
{
// (this is one of my test cases for the new emitter --air)
protected:
xRegisterSSE m_reg;
bool m_free;
xAddressReg src( srcRm );
xAddressReg dest( destRm );
public:
iAllocRegSSE() :
m_reg( xmm0 ),
m_free( !!_hasFreeXMMreg() )
{
if( m_free )
m_reg = xRegisterSSE( _allocTempXMMreg( XMMT_INT, -1 ) );
else
xStoreReg( m_reg );
}
xMOV( eax, ptr[src] );
xMOV( ptr[dest], eax );
~iAllocRegSSE()
{
if( m_free )
_freeXMMreg( m_reg.Id );
else
xRestoreReg( m_reg );
}
operator xRegisterSSE() const { return m_reg; }
};
xMOV( eax, ptr[src+4] );
xMOV( ptr[dest+4], eax );
//////////////////////////////////////////////////////////////////////////////////////////
// Moves 128 bits from point B to point A, using SSE's MOVAPS (or MOVDQA).
// This instruction always uses an SSE register, even if all registers are allocated! It
// saves an SSE register to memory first, performs the copy, and restores the register.
//
void iMOV128_SSE( const ModSibBase& destRm, const ModSibBase& srcRm )
{
iAllocRegSSE reg;
xMOVDQA( reg, srcRm );
xMOVDQA( destRm, reg );
}
xMOV( eax, ptr[src+8] );
xMOV( ptr[dest+8], eax );
//////////////////////////////////////////////////////////////////////////////////////////
// Moves 64 bits of data from point B to point A, using either MMX, SSE, or x86 registers
// if neither MMX nor SSE is available to the task.
//
// Optimizations: This method uses MMX is the cpu is in MMX mode, or SSE if it's in FPU
// mode (saving on potential EMMS uses).
//
void iMOV64_Smart( const ModSibBase& destRm, const ModSibBase& srcRm )
{
if( (x86FpuState == FPU_STATE) && _hasFreeXMMreg() )
{
// Move things using MOVLPS:
xRegisterSSE reg( _allocTempXMMreg( XMMT_INT, -1 ) );
xMOVL.PS( reg, srcRm );
xMOVL.PS( destRm, reg );
_freeXMMreg( reg.Id );
return;
}
xMOV( eax, ptr[src+12] );
xMOV( ptr[dest+12], eax );
if( _hasFreeMMXreg() )
{
xRegisterMMX reg( _allocMMXreg(-1, MMX_TEMP, 0) );
xMOVQ( reg, srcRm );
xMOVQ( destRm, reg );
_freeMMXreg( reg.Id );
}
else
{
xMOV( eax, srcRm );
xMOV( destRm, eax );
xMOV( eax, srcRm+4 );
xMOV( destRm+4, eax );
}
}
/*
@ -127,38 +183,11 @@ static void _vtlb_DynGen_DirectRead( u32 bits, bool sign )
break;
case 64:
if( _hasFreeMMXreg() )
{
const int freereg = _allocMMXreg(-1, MMX_TEMP, 0);
MOVQRmtoR(freereg,ECX);
MOVQRtoRm(EDX,freereg);
_freeMMXreg(freereg);
}
else
{
MOV32RmtoR(EAX,ECX);
MOV32RtoRm(EDX,EAX);
MOV32RmtoR(EAX,ECX,4);
MOV32RtoRm(EDX,EAX,4);
}
iMOV64_Smart(ptr[edx],ptr[ecx]);
break;
case 128:
if( _hasFreeXMMreg() )
{
const int freereg = _allocTempXMMreg( XMMT_INT, -1 );
SSE2_MOVDQARmtoR(freereg,ECX);
SSE2_MOVDQARtoRm(EDX,freereg);
_freeXMMreg(freereg);
}
else
{
// Could put in an MMX optimization here as well, but no point really.
// It's almost never used since there's almost always a free XMM reg.
MOV128_MtoM( EDX, ECX ); // dest <- src!
}
iMOV128_SSE(ptr[edx],ptr[ecx]);
break;
jNO_DEFAULT
@ -262,39 +291,11 @@ void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const )
switch( bits )
{
case 64:
if( _hasFreeMMXreg() )
{
const int freereg = _allocMMXreg(-1, MMX_TEMP, 0);
MOVQMtoR(freereg,ppf);
MOVQRtoRm(EDX,freereg);
_freeMMXreg(freereg);
}
else
{
MOV32MtoR(EAX,ppf);
MOV32RtoRm(EDX,EAX);
MOV32MtoR(EAX,ppf+4);
MOV32RtoRm(EDX,EAX,4);
}
iMOV64_Smart(ptr[edx],ptr[ppf]);
break;
case 128:
if( _hasFreeXMMreg() )
{
const int freereg = _allocTempXMMreg( XMMT_INT, -1 );
SSE2_MOVDQA_M128_to_XMM( freereg, ppf );
SSE2_MOVDQARtoRm(EDX,freereg);
_freeXMMreg(freereg);
}
else
{
// Could put in an MMX optimization here as well, but no point really.
// It's almost never used since there's almost always a free XMM reg.
MOV32ItoR( ECX, ppf );
MOV128_MtoM( EDX, ECX ); // dest <- src!
}
iMOV128_SSE(ptr[edx],ptr[ppf]);
break;
jNO_DEFAULT
@ -415,38 +416,11 @@ static void _vtlb_DynGen_DirectWrite( u32 bits )
break;
case 64:
if( _hasFreeMMXreg() )
{
const int freereg = _allocMMXreg(-1, MMX_TEMP, 0);
MOVQRmtoR(freereg,EDX);
MOVQRtoRm(ECX,freereg);
_freeMMXreg( freereg );
}
else
{
MOV32RmtoR(EAX,EDX);
MOV32RtoRm(ECX,EAX);
MOV32RmtoR(EAX,EDX,4);
MOV32RtoRm(ECX,EAX,4);
}
iMOV64_Smart(ptr[ecx],ptr[edx]);
break;
case 128:
if( _hasFreeXMMreg() )
{
const int freereg = _allocTempXMMreg( XMMT_INT, -1 );
SSE2_MOVDQARmtoR(freereg,EDX);
SSE2_MOVDQARtoRm(ECX,freereg);
_freeXMMreg( freereg );
}
else
{
// Could put in an MMX optimization here as well, but no point really.
// It's almost never used since there's almost always a free XMM reg.
MOV128_MtoM( ECX, EDX ); // dest <- src!
}
iMOV128_SSE(ptr[ecx],ptr[edx]);
break;
}
}
@ -514,39 +488,11 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const )
break;
case 64:
if( _hasFreeMMXreg() )
{
const int freereg = _allocMMXreg(-1, MMX_TEMP, 0);
MOVQRmtoR(freereg,EDX);
MOVQRtoM(ppf,freereg);
_freeMMXreg( freereg );
}
else
{
MOV32RmtoR(EAX,EDX);
MOV32RtoM(ppf,EAX);
MOV32RmtoR(EAX,EDX,4);
MOV32RtoM(ppf+4,EAX);
}
iMOV64_Smart( ptr[ppf], ptr[edx] );
break;
case 128:
if( _hasFreeXMMreg() )
{
const int freereg = _allocTempXMMreg( XMMT_INT, -1 );
SSE2_MOVDQARmtoR(freereg,EDX);
SSE2_MOVDQA_XMM_to_M128(ppf,freereg);
_freeXMMreg( freereg );
}
else
{
// Could put in an MMX optimization here as well, but no point really.
// It's almost never used since there's almost always a free XMM reg.
MOV32ItoR( ECX, ppf );
MOV128_MtoM( ECX, EDX ); // dest <- src!
}
iMOV128_SSE( ptr[ppf], ptr[edx] );
break;
}
@ -571,3 +517,4 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const )
CALLFunc( (int)vtlbdata.RWFT[szidx][1][handler] );
}
}

View File

@ -96,15 +96,23 @@ public:
// Bit Test Instructions - Valid on 16/32 bit instructions only.
//
template< G8Type InstType >
class xImpl_Group8 : public xImpl_BitScan<0xa3 | (InstType << 2)>
class xImpl_Group8
{
static const uint RegFormOp = 0xa3 | (InstType << 3);
public:
using xImpl_BitScan<0xa3 | (InstType << 2)>::operator();
__forceinline void operator()( const xRegister32& bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( RegFormOp, bitbase, bitoffset ); }
__forceinline void operator()( const xRegister16& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitbase, bitoffset ); }
__forceinline void operator()( const ModSibBase& bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( RegFormOp, bitoffset, bitbase ); }
__forceinline void operator()( const ModSibBase& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitoffset, bitbase ); }
__forceinline void operator()( const void* bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( 0xab, bitoffset, bitbase ); }
__forceinline void operator()( const void* bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitoffset, bitbase ); }
__forceinline void operator()( const ModSibStrict<u32>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const ModSibStrict<u16>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
void operator()( const xRegister<u32>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
void operator()( const xRegister<u16>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const ModSibStrict<u32>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const ModSibStrict<u16>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const u32* bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const u16* bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const xRegister<u32>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
__forceinline void operator()( const xRegister<u16>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
xImpl_Group8() {}
};

View File

@ -23,6 +23,8 @@
#include "RedtapeWindows.h"
using namespace x86Emitter;
#if defined (_MSC_VER) && _MSC_VER >= 1400
extern "C"
@ -148,31 +150,29 @@ u64 GetCPUTick( void )
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
// Note: This function doesn't support GCC/Linux. Looking online it seems the only
// way to simulate the Micrsoft SEH model is to use unix signals, and the 'sigaction'
// function specifically. Maybe a project for a linux developer at a later date. :)
void cpudetectSSE3(void* pfnCallSSE3)
{
cpucaps.hasStreamingSIMD3Extensions = 1;
#ifdef _MSC_VER
static bool _test_instruction( void* pfnCall )
{
__try {
((void (*)())pfnCallSSE3)();
((void (*)())pfnCall)();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
cpucaps.hasStreamingSIMD3Extensions = 0;
return false;
}
#else // linux
#ifdef PCSX2_FORCESSE3
cpucaps.hasStreamingSIMD3Extensions = 1;
#else
// exception handling doesn't work, so disable for x86 builds of linux
cpucaps.hasStreamingSIMD3Extensions = 0;
#endif
#endif
return true;
}
static char* bool_to_char( bool testcond )
{
return testcond ? "true" : "false";
}
#endif
#if defined __LINUX__
#include <sys/time.h>
@ -180,48 +180,41 @@ void cpudetectSSE3(void* pfnCallSSE3)
#endif
s64 CPUSpeedHz( unsigned int time )
//////////////////////////////////////////////////////////////////////////////////////////
//
s64 CPUSpeedHz( int time )
{
s64 timeStart,
int timeStart,
timeStop;
s64 startTick,
endTick;
s64 overhead;
if( ! cpucaps.hasTimeStampCounter )
{
return 0; //check if function is supported
}
overhead = GetCPUTick() - GetCPUTick();
timeStart = timeGetTime( );
while( timeGetTime( ) == timeStart )
{
timeStart = timeGetTime( );
}
for(;;)
// Align the cpu execution to a timeGetTime boundary.
// Without this the result could be skewed by up to several milliseconds.
do { timeStart = timeGetTime( );
} while( timeGetTime( ) == timeStart );
do
{
timeStop = timeGetTime( );
if ( ( timeStop - timeStart ) > 1 )
{
startTick = GetCPUTick( );
break;
}
}
startTick = GetCPUTick( );
} while( ( timeStop - timeStart ) < 1 );
timeStart = timeStop;
for(;;)
do
{
timeStop = timeGetTime( );
if ( ( timeStop - timeStart ) > time )
{
endTick = GetCPUTick( );
break;
}
timeStop = timeGetTime();
endTick = GetCPUTick();
}
while( ( timeStop - timeStart ) < time );
return (s64)( ( endTick - startTick ) + ( overhead ) );
return (s64)( endTick - startTick );
}
////////////////////////////////////////////////////
@ -294,6 +287,7 @@ void cpudetectInit()
if ( iCpuId( 0x80000001, regs ) != -1 )
{
x86_64_12BITBRANDID = regs[1] & 0xfff;
cpuinfo.x86EFlags2 = regs[ 2 ];
cpuinfo.x86EFlags = regs[ 3 ];
}
@ -364,40 +358,85 @@ void cpudetectInit()
cpucaps.hasMultiThreading = ( cpuinfo.x86Flags >> 28 ) & 1;
cpucaps.hasThermalMonitor = ( cpuinfo.x86Flags >> 29 ) & 1;
cpucaps.hasIntel64BitArchitecture = ( cpuinfo.x86Flags >> 30 ) & 1;
//that is only for AMDs
cpucaps.hasMultimediaExtensionsExt = ( cpuinfo.x86EFlags >> 22 ) & 1; //mmx2
cpucaps.hasAMD64BitArchitecture = ( cpuinfo.x86EFlags >> 29 ) & 1; //64bit cpu
cpucaps.has3DNOWInstructionExtensionsExt = ( cpuinfo.x86EFlags >> 30 ) & 1; //3dnow+
cpucaps.has3DNOWInstructionExtensions = ( cpuinfo.x86EFlags >> 31 ) & 1; //3dnow
cpucaps.hasStreamingSIMD4ExtensionsA = ( cpuinfo.x86EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT
cpuinfo.cpuspeed = (u32)(CPUSpeedHz( 1000 ) / 1000000);
// --> SSE 4.1 detection <--
// We don't care about the small subset of CPUs using SSE4 (which is also hard to
// detect, in addition to being of limited use due to the abbreviated instruction set).
// So we'll just leave it at SSE 4.1. SSE4 cpu detection is ignored.
cpuinfo.cpuspeed = (u32)(CPUSpeedHz( 400 ) / 400000 );
cpucaps.hasStreamingSIMD4Extensions = ( cpuinfo.x86Flags2 >> 19 ) & 1; //sse4.1
// --> SSSE3 detection <--
// --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <--
cpucaps.hasStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 0 ) & 1; //sse3
cpucaps.hasSupplementalStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 9 ) & 1; //ssse3
cpucaps.hasStreamingSIMD4Extensions = ( cpuinfo.x86Flags2 >> 19 ) & 1; //sse4.1
cpucaps.hasStreamingSIMD4Extensions2 = ( cpuinfo.x86Flags2 >> 20 ) & 1; //sse4.2
// --> SSE3 detection <--
// These instructions may not be recognized by some compilers, or may not have
// intrinsic equivalents available. So we use our own ix86 emitter to generate
// some code and run it that way. :)
// Can the SSE3 / SSE4.1 bits be trusted? Using an instruction test is a very "complete"
// approach to ensuring the bit is accurate, and at least one reported case of a Q9550 not
// having SSE 4.1 set but still supporting it properly is fixed by this --air
#ifdef _MSC_VER
u8* recSSE = (u8*)HostSys::Mmap( NULL, 0x1000 );
if( recSSE != NULL )
{
x86SetPtr(recSSE);
SSE3_MOVSLDUP_XMM_to_XMM(XMM0, XMM0);
xSetPtr( recSSE );
xMOVSLDUP( xmm1, xmm0 );
RET();
cpudetectSSE3(recSSE);
u8* funcSSSE3 = xGetPtr();
xPABS.W( xmm0, xmm1 );
RET();
u8* funcSSE41 = xGetPtr();
xBLEND.VPD( xmm1, xmm0 );
RET();
bool sse3_result = _test_instruction( recSSE ); // sse3
bool ssse3_result = _test_instruction( funcSSSE3 );
bool sse41_result = _test_instruction( funcSSE41 );
HostSys::Munmap( recSSE, 0x1000 );
// Test for and log any irregularities here.
// We take the instruction test result over cpuid since (in theory) it should be a
// more reliable gauge of the cpu's actual ability.
if( sse3_result != !!cpucaps.hasStreamingSIMD3Extensions )
{
Console::Notice( "SSE3 Detection Inconsistency: cpuid=%s, test_result=%s",
params bool_to_char( !!cpucaps.hasStreamingSIMD3Extensions ), bool_to_char( sse3_result ) );
cpucaps.hasStreamingSIMD3Extensions = sse3_result;
}
if( ssse3_result != !!cpucaps.hasSupplementalStreamingSIMD3Extensions )
{
Console::Notice( "SSSE3 Detection Inconsistency: cpuid=%s, test_result=%s",
params bool_to_char( !!cpucaps.hasSupplementalStreamingSIMD3Extensions ), bool_to_char( ssse3_result ) );
cpucaps.hasSupplementalStreamingSIMD3Extensions = ssse3_result;
}
if( sse41_result != !!cpucaps.hasStreamingSIMD4Extensions )
{
Console::Notice( "SSE4 Detection Inconsistency: cpuid=%s, test_result=%s",
params bool_to_char( !!cpucaps.hasStreamingSIMD4Extensions ), bool_to_char( sse41_result ) );
cpucaps.hasStreamingSIMD4Extensions = sse41_result;
}
}
else { Console::Error("Error: Failed to allocate memory for SSE3 State detection."); }
else
Console::Notice(
"Notice: Could not allocate memory for SSE3/4 detection.\n"
"\tRelying on CPUID results. [this is not an error]"
);
#endif
//////////////////////////////////////
// Core Counting!

View File

@ -35,6 +35,9 @@
namespace x86Emitter
{
extern void xStoreReg( const xRegisterSSE& src );
extern void xRestoreReg( const xRegisterSSE& dest );
// ------------------------------------------------------------------------
// Group 1 Instruction Class

View File

@ -677,8 +677,6 @@ extern void CDQE( void );
extern void LAHF();
extern void SAHF();
extern void BT32ItoR( x86IntRegType to, u8 from );
extern void BTR32ItoR( x86IntRegType to, u8 from );
extern void BSRRtoR(x86IntRegType to, x86IntRegType from);
extern void BSWAP32R( x86IntRegType to );

View File

@ -30,9 +30,22 @@ u8 g_globalXMMSaved = 0;
PCSX2_ALIGNED16( static u64 g_globalMMXData[8] );
PCSX2_ALIGNED16( static u64 g_globalXMMData[2*iREGCNT_XMM] );
namespace x86Emitter
{
void xStoreReg( const xRegisterSSE& src )
{
xMOVDQA( &g_globalXMMData[src.Id*2], src );
}
void xRestoreReg( const xRegisterSSE& dest )
{
xMOVDQA( dest, &g_globalXMMData[dest.Id*2] );
}
}
/////////////////////////////////////////////////////////////////////
// SetCPUState -- for assugnment of SSE roundmodes and clampmodes.
// SetCPUState -- for assignment of SSE roundmodes and clampmodes.
u32 g_sseMXCSR = DEFAULT_sseMXCSR;
u32 g_sseVUMXCSR = DEFAULT_sseVUMXCSR;

View File

@ -54,12 +54,14 @@ struct CAPABILITIES
u32 hasStreamingSIMD3Extensions;
u32 hasSupplementalStreamingSIMD3Extensions;
u32 hasStreamingSIMD4Extensions;
u32 hasStreamingSIMD4Extensions2;
// AMD-specific CPU Features
u32 hasMultimediaExtensionsExt;
u32 hasAMD64BitArchitecture;
u32 has3DNOWInstructionExtensionsExt;
u32 has3DNOWInstructionExtensions;
u32 hasStreamingSIMD4ExtensionsA;
};
extern CAPABILITIES cpucaps;
@ -73,6 +75,7 @@ struct CPUINFO
u32 x86Flags; // Feature Flags
u32 x86Flags2; // More Feature Flags
u32 x86EFlags; // Extended Feature Flags
u32 x86EFlags2; // Extended Feature Flags pg2
u32 PhysicalCores;
u32 LogicalCores;

View File

@ -28,7 +28,6 @@
PCSX2_ALIGNED16(microVU microVU0);
PCSX2_ALIGNED16(microVU microVU1);
FILE *mVUlogFile[2] = {NULL, NULL};
declareAllVariables // Declares All Global Variables :D
//------------------------------------------------------------------
@ -46,7 +45,6 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr) {
mVU->cache = NULL;
memset(&mVU->prog, 0, sizeof(mVU->prog));
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
mVUsetupLog();
mVUreset<vuIndex>();
}
@ -84,6 +82,7 @@ microVUt(void) mVUreset() {
mVU->prog.cleared = 1;
mVU->prog.cur = -1;
mVU->prog.total = -1;
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
//mVU->prog.lpState = &mVU->prog.prog[15].allocInfo.block.pState; // Blank Pipeline State (ToDo: finish implementation)
// Setup Dynarec Cache Limits for Each Program
@ -151,21 +150,21 @@ microVUt(int) mVUfindLeastUsedProg() {
if (mVU->prog.total < mVU->prog.max) {
mVU->prog.total++;
mVUcacheProg<vuIndex>(mVU->prog.total); // Cache Micro Program
Console::Notice("microVU: Program Total = %d", params mVU->prog.total);
Console::Notice("microVU%d: Cached MicroPrograms = %d", params vuIndex, mVU->prog.total+1);
return mVU->prog.total;
}
else {
int j = 0;
u32 smallest = mVU->prog.prog[0].used;
for (int i = 1; i <= mVU->prog.total; i++) {
int j = (mVU->prog.cur + 1) & mVU->prog.max;
/*u32 smallest = mVU->prog.prog[j].used;
for (int i = ((j+1)&mVU->prog.max), z = 0; z < mVU->prog.max; i = (i+1)&mVU->prog.max, z++) {
if (smallest > mVU->prog.prog[i].used) {
smallest = mVU->prog.prog[i].used;
j = i;
}
}
}*/
mVUclearProg<vuIndex>(j); // Clear old data if overwriting old program
mVUcacheProg<vuIndex>(j); // Cache Micro Program
Console::Notice("microVU: Program Cache got Full!");
Console::Notice("microVU%d: MicroProgram Cache Full!", params vuIndex);
return j;
}
}
@ -175,9 +174,7 @@ microVUt(int) mVUsearchProg() {
microVU* mVU = mVUx;
if (mVU->prog.cleared) { // If cleared, we need to search for new program
for (int i = 0; i <= mVU->prog.total; i++) {
//if (i == mVU->prog.cur) continue; // We can skip the current program. (ToDo: Verify that games don't clear, and send the same microprogram :/)
if (!memcmp_mmx(mVU->prog.prog[i].data, mVU->regs->Micro, mVU->microSize)) {
//if (i == mVU->prog.cur) { mVUprint("microVU: Same micro program sent!"); }
mVU->prog.cur = i;
mVU->prog.cleared = 0;
mVU->prog.prog[i].used++;

View File

@ -41,7 +41,7 @@ public:
microBlock* thisBlock = search(&pBlock->pState);
if (!thisBlock) {
listSize++;
listSize &= MaxBlocks;
if (listSize > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listSize &= MaxBlocks; }
memcpy_fast(&blockList[listSize], pBlock, sizeof(microBlock));
thisBlock = &blockList[listSize];
}
@ -94,6 +94,7 @@ struct microVU {
microProgManager<0x4000> prog; // Micro Program Data
FILE* logFile; // Log File Pointer
VURegs* regs; // VU Regs Struct
u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to)
u8* startFunct; // Ptr Function to the Start code for recompiled programs
@ -109,6 +110,8 @@ struct microVU {
u32 espBackup; // Temp Backup for ESP
u32 totalCycles;
u32 cycles;
PCSX2_ALIGNED16(u32 xmmPQb[4]); // Backup for xmmPQ
};
// microVU rec structs
@ -119,9 +122,6 @@ extern PCSX2_ALIGNED16(microVU microVU1);
extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info );
extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info );
// Used for logging microPrograms
extern FILE *mVUlogFile[2];
// Main Functions
microVUt(void) mVUinit(VURegs*);
microVUt(void) mVUreset();

View File

@ -72,7 +72,7 @@ microVUt(void) mVUallocFMAC2a(int& Fs, int& Ft) {
microVUt(void) mVUallocFMAC2b(int& Ft) {
microVU* mVU = mVUx;
if (!_Ft_) { SysPrintf("microVU: If a game does this, its retarded...\n"); return; }
if (!_Ft_) return;
//if (CHECK_VU_OVERFLOW) mVUclamp1<vuIndex>(Ft, xmmT1, _X_Y_Z_W);
mVUsaveReg<vuIndex>(Ft, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1);
}
@ -533,7 +533,7 @@ microVUt(void) mVUallocFMAC18b(int& ACC, int& Fs) {
}
//------------------------------------------------------------------
// FMAC19 - OPMULA FMAC Opcode
// FMAC19 - OPMSUB FMAC Opcode
//------------------------------------------------------------------
microVUt(void) mVUallocFMAC19a(int& Fd, int& ACC, int& Fs, int& Ft) {
@ -714,9 +714,9 @@ microVUt(void) mVUallocCFLAGb(int reg, int fInstance) {
microVUt(void) mVUallocVIa(int GPRreg, int _reg_) {
microVU* mVU = mVUx;
if (_reg_ == 0) { XOR32RtoR(GPRreg, GPRreg); }
else if (_reg_ < 9) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); }
else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); }
if (!_reg_ || _reg_>15) { XOR32RtoR(GPRreg, GPRreg); }
else if (isMMX(_reg_)) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); }
else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); }
}
microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
@ -727,9 +727,9 @@ microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
MOV32RtoM((uptr)&mVU->VIbackup[0], GPRreg);
MOV32MtoR(GPRreg, (uptr)&mVU->VIbackup[1]);
}
if (_reg_ == 0) { return; }
else if (_reg_ < 9) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
else { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); }
if (_reg_ == 0) { return; }
else if (isMMX(_reg_)) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
else if (_reg_ < 16) { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); }
}
//------------------------------------------------------------------

View File

@ -146,7 +146,6 @@ microVUt(void) mVUanalyzeIALU2(int Is, int It) {
microVUt(void) mVUanalyzeMR32(int Fs, int Ft) {
microVU* mVU = mVUx;
mVUprint("microVU: MR32 Opcode");
if (!Ft) { mVUinfo |= _isNOP; }
analyzeReg6(Fs);
analyzeReg2(Ft);
@ -202,7 +201,6 @@ microVUt(void) mVUanalyzeEFU2(int Fs, u8 xCycles) {
microVUt(void) mVUanalyzeMFP(int Ft) {
microVU* mVU = mVUx;
mVUprint("microVU: MFP Opcode");
if (!Ft) { mVUinfo |= _isNOP; }
analyzeReg2(Ft);
}
@ -239,14 +237,12 @@ microVUt(void) mVUanalyzeSQ(int Fs, int It, bool writeIt) {
microVUt(void) mVUanalyzeR1(int Fs, int Fsf) {
microVU* mVU = mVUx;
mVUprint("microVU: R-reg Opcode");
analyzeReg5(Fs, Fsf);
analyzeRreg();
}
microVUt(void) mVUanalyzeR2(int Ft, bool canBeNOP) {
microVU* mVU = mVUx;
mVUprint("microVU: R-reg Opcode");
if (!Ft) { mVUinfo |= ((canBeNOP) ? _isNOP : _noWriteVF); }
analyzeReg2(Ft);
analyzeRreg();
@ -258,7 +254,6 @@ microVUt(void) mVUanalyzeR2(int Ft, bool canBeNOP) {
microVUt(void) mVUanalyzeSflag(int It) {
microVU* mVU = mVUx;
mVUprint("microVU: Sflag Opcode");
if (!It) { mVUinfo |= _isNOP; }
else { // Sets _isSflag at instruction that FSxxx opcode reads it's status flag from
mVUinfo |= _swapOps;
@ -274,7 +269,6 @@ microVUt(void) mVUanalyzeSflag(int It) {
microVUt(void) mVUanalyzeFSSET() {
microVU* mVU = mVUx;
mVUinfo |= _isFSSET;
mVUprint("microVU: FSSET Opcode");
// mVUinfo &= ~_doStatus;
// Note: I'm not entirely sure if the non-sticky flags
// should be taken from the current upper instruction
@ -288,7 +282,6 @@ microVUt(void) mVUanalyzeFSSET() {
microVUt(void) mVUanalyzeMflag(int Is, int It) {
microVU* mVU = mVUx;
mVUprint("microVU: Mflag Opcode");
if (!It) { mVUinfo |= _isNOP; }
else { // Need set _doMac for 4 previous Ops (need to do all 4 because stalls could change the result needed)
mVUinfo |= _swapOps;
@ -324,26 +317,26 @@ microVUt(void) mVUanalyzeXGkick(int Fs, int xCycles) {
#define analyzeBranchVI(reg, infoVal) { \
if (reg && (mVUcount > 0)) { /* Ensures branch is not first opcode in block */ \
incPC(-2); \
incPC2(-2); \
if (writesVI && (reg == mVU->VIbackup[0])) { /* If prev Op modified VI reg */ \
mVUinfo |= _backupVI; \
incPC(2); \
incPC2(2); \
mVUinfo |= infoVal; \
} \
else { incPC(2); } \
else { incPC2(2); } \
} \
}
microVUt(void) mVUanalyzeBranch1(int Is) {
microVU* mVU = mVUx;
if (mVUregs.VI[Is]) { analyzeVIreg1(Is); }
else { analyzeBranchVI(Is, _memReadIs); }
if (mVUregs.VI[Is] || mVUstall) { analyzeVIreg1(Is); }
else { analyzeBranchVI(Is, _memReadIs); }
}
microVUt(void) mVUanalyzeBranch2(int Is, int It) {
microVU* mVU = mVUx;
if (mVUregs.VI[Is] || mVUregs.VI[It]) { analyzeVIreg1(Is); analyzeVIreg1(It); }
else { analyzeBranchVI(Is, _memReadIs); analyzeBranchVI(It, _memReadIt);}
if (mVUregs.VI[Is] || mVUregs.VI[It] || mVUstall) { analyzeVIreg1(Is); analyzeVIreg1(It); }
else { analyzeBranchVI(Is, _memReadIs); analyzeBranchVI(It, _memReadIt);}
}
#endif //PCSX2_MICROVU

View File

@ -34,6 +34,7 @@
else { ajmp = JMPcc((uptr)0); } \
break
// ToDo: Fix this properly.
#define flagSetMacro(xFlag, pFlag, xF, yF, zF) { \
yF += (mVUstall > 3) ? 3 : mVUstall; \
if (yF > zF) { \
@ -49,6 +50,7 @@
#define startLoop() { mVUdebug1(); mVUstall = 0; memset(&mVUregsTemp, 0, sizeof(mVUregsTemp)); }
#define calcCycles(reg, x) { reg = ((reg > x) ? (reg - x) : 0); }
#define tCycles(dest, src) { dest = aMax(dest, src); }
#define incP() { mVU->p = (mVU->p+1) & 1; }
#define incQ() { mVU->q = (mVU->q+1) & 1; }
#define doUpperOp() { mVUopU<vuIndex, 1>(); mVUdivSet<vuIndex>(); }
@ -211,18 +213,26 @@ microVUt(void) mVUsetCycles() {
incCycles(mVUstall);
if (mVUregsTemp.VFreg[0] == mVUregsTemp.VFreg[1] && mVUregsTemp.VFreg[0]) { // If upper Op && lower Op write to same VF reg
mVUinfo |= (mVUregsTemp.r || mVUregsTemp.VI) ? _noWriteVF : _isNOP; // If lower Op doesn't modify anything else, then make it a NOP
mVUregsTemp.VF[1].x = aMax(mVUregsTemp.VF[0].x, mVUregsTemp.VF[1].x); // Use max cycles from each vector
mVUregsTemp.VF[1].y = aMax(mVUregsTemp.VF[0].y, mVUregsTemp.VF[1].y);
mVUregsTemp.VF[1].z = aMax(mVUregsTemp.VF[0].z, mVUregsTemp.VF[1].z);
mVUregsTemp.VF[1].w = aMax(mVUregsTemp.VF[0].w, mVUregsTemp.VF[1].w);
tCycles(mVUregsTemp.VF[1].x, mVUregsTemp.VF[0].x) // Use max cycles from each vector
tCycles(mVUregsTemp.VF[1].y, mVUregsTemp.VF[0].y)
tCycles(mVUregsTemp.VF[1].z, mVUregsTemp.VF[0].z)
tCycles(mVUregsTemp.VF[1].w, mVUregsTemp.VF[0].w)
}
mVUregs.VF[mVUregsTemp.VFreg[0]].reg = mVUregsTemp.VF[0].reg;
mVUregs.VF[mVUregsTemp.VFreg[1]].reg = mVUregsTemp.VF[1].reg;
mVUregs.VI[mVUregsTemp.VIreg] = mVUregsTemp.VI;
mVUregs.q = mVUregsTemp.q;
mVUregs.p = mVUregsTemp.p;
mVUregs.r = mVUregsTemp.r;
mVUregs.xgkick = mVUregsTemp.xgkick;
tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].x, mVUregsTemp.VF[0].x);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].y, mVUregsTemp.VF[0].y);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].z, mVUregsTemp.VF[0].z);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[0]].w, mVUregsTemp.VF[0].w);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[1]].x, mVUregsTemp.VF[1].x);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[1]].y, mVUregsTemp.VF[1].y);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[1]].z, mVUregsTemp.VF[1].z);
tCycles(mVUregs.VF[mVUregsTemp.VFreg[1]].w, mVUregsTemp.VF[1].w);
tCycles(mVUregs.VI[mVUregsTemp.VIreg], mVUregsTemp.VI);
tCycles(mVUregs.q, mVUregsTemp.q);
tCycles(mVUregs.p, mVUregsTemp.p);
tCycles(mVUregs.r, mVUregsTemp.r);
tCycles(mVUregs.xgkick, mVUregsTemp.xgkick);
}
microVUt(void) mVUdivSet() {
@ -358,14 +368,14 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo));
mVUsetupBranch<vuIndex>(bStatus, bMac);
PUSH32R(gprR); // Backup EDX
mVUbackupRegs<vuIndex>();
MOV32MtoR(gprT2, (uptr)&mVU->branch); // Get startPC (ECX first argument for __fastcall)
//AND32ItoR(gprT2, (vuIndex)?0x3ff8:0xff8); // Ensure valid jump address
MOV32ItoR(gprR, (u32)&pBlock->pStateEnd); // Get pState (EDX second argument for __fastcall)
if (!vuIndex) CALLFunc((uptr)mVUcompileVU0); //(u32 startPC, uptr pState)
else CALLFunc((uptr)mVUcompileVU1);
POP32R(gprR); // Restore EDX
mVUrestoreRegs<vuIndex>();
JMPR(gprT1); // Jump to rec-code address
return thisPtr;
}

View File

@ -56,8 +56,8 @@ microVUt(void) mVUdispatcherA() {
MOV32RtoR(gprF2, gprF0);
MOV32RtoR(gprF3, gprF0);
for (int i = 0; i < 8; i++) {
MOVQMtoR(i, (uptr)&mVU->regs->VI[i+1].UL);
for (int i = 1; i < 16; i++) {
if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); }
}
SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]);
@ -99,7 +99,10 @@ microVUt(void) mVUdispatcherB() {
MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprF0);
for (int i = 0; i < 8; i++) {
MOVDMMXtoM((uptr)&mVU->regs->VI[i+1].UL, i);
}
for (int i = 1; i < 16; i++) {
if (isMMX(i)) { MOVDMMXtoM((uptr)&mVU->regs->VI[i].UL, mmVI(i)); }
}
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC);
@ -112,7 +115,7 @@ microVUt(void) mVUdispatcherB() {
//write8(0xcc);
EMMS();
if (isMMX(1)) EMMS();
RET();
mVUcacheCheck(x86Ptr, mVU->cache, 512);
@ -144,6 +147,8 @@ microVUt(void*) __fastcall mVUexecute(u32 startPC, u32 cycles) {
microVUt(void) mVUcleanUp() {
microVU* mVU = mVUx;
//mVUprint("microVU: Program exited successfully!");
//mVUprint("microVU: VF0 = {%x,%x,%x,%x}", params mVU->regs->VF[0].UL[0], mVU->regs->VF[0].UL[1], mVU->regs->VF[0].UL[2], mVU->regs->VF[0].UL[3]);
//mVUprint("microVU: VI0 = %x", params mVU->regs->VI[0].UL);
mVUcurProg.x86ptr = x86Ptr;
mVUcacheCheck(x86Ptr, mVUcurProg.x86start, (uptr)(mVUcurProg.x86end - mVUcurProg.x86start));
}

View File

@ -19,13 +19,9 @@
#pragma once
#ifdef PCSX2_MICROVU
microVUt(void) __mVUsetupLog() {
if (!vuIndex) { if (!mVUlogFile[0]) mVUlogFile[0] = fopen(LOGS_DIR "\\microVU0.txt", "w"); }
else { if (!mVUlogFile[1]) mVUlogFile[1] = fopen(LOGS_DIR "\\microVU1.txt", "w"); }
}
// writes text directly to the microVU.txt, no newlines appended.
microVUx(void) __mVULog(const char* fmt, ...) {
microVU* mVU = mVUx;
char tmp[2024];
va_list list;
@ -35,10 +31,9 @@ microVUx(void) __mVULog(const char* fmt, ...) {
int length = vsprintf(tmp, fmt, list);
va_end(list);
if (mVUlogFile[vuIndex]) {
fputs(tmp, mVUlogFile[vuIndex]);
//fputs("\n", mVUlogFile[vuIndex]);
fflush(mVUlogFile[vuIndex]);
if (mVU->logFile) {
fputs(tmp, mVU->logFile);
fflush(mVU->logFile);
}
}
@ -46,15 +41,30 @@ microVUx(void) __mVULog(const char* fmt, ...) {
microVUt(void) __mVUdumpProgram(int progIndex) {
microVU* mVU = mVUx;
bool bitX[7];
//mVU->prog.cur = progIndex; // Needed in order to set iPC
mVUlog("*********************\n", progIndex);
mVUlog("* Micro-Program #%02d *\n", progIndex);
mVUlog("*********************\n\n", progIndex);
bool bitX[9];
char str[30];
int delay = 0;
mVUbranch = 0;
sprintf(str, "%s\\microVU%d prog - %02d.html", LOGS_DIR, vuIndex, progIndex);
mVU->logFile = fopen(str, "w");
mVUlog("<html>\n");
mVUlog("<title>microVU%d MicroProgram Log</title>\n", vuIndex);
mVUlog("<body bgcolor=\"#000000\" LINK=\"#1111ff\" VLINK=\"#1111ff\">\n");
mVUlog("<font face=\"Courier New\" color=\"#ffffff\">\n");
mVUlog("<font size=\"5\" color=\"#7099ff\">");
mVUlog("*********************\n<br>", progIndex);
mVUlog("* Micro-Program #%02d *\n<br>", progIndex);
mVUlog("*********************\n\n<br><br>", progIndex);
mVUlog("</font>");
for (u32 i = 0; i < mVU->progSize; i+=2) {
if (delay) { delay--; mVUlog("</font>"); if (!delay) mVUlog("<hr/>"); }
if (mVUbranch) { delay = 1; mVUbranch = 0; }
mVU->code = mVU->prog.prog[progIndex].data[i+1];
mVUlog("[%04x] (%08x) ", i*4, mVU->code);
bitX[0] = 0;
bitX[1] = 0;
@ -63,14 +73,21 @@ microVUt(void) __mVUdumpProgram(int progIndex) {
bitX[4] = 0;
bitX[5] = 0;
bitX[6] = 0;
bitX[7] = 0;
bitX[8] = 0;
if (mVU->code & _Ibit_) {bitX[0] = 1; bitX[5] = 1;}
if (mVU->code & _Ebit_) {bitX[1] = 1; bitX[5] = 1;}
if (mVU->code & _Mbit_) {bitX[2] = 1; bitX[5] = 1;}
if (mVU->code & _Dbit_) {bitX[3] = 1; bitX[5] = 1;}
if (mVU->code & _Tbit_) {bitX[4] = 1; bitX[5] = 1;}
if (mVU->code & _Ibit_) { bitX[0] = 1; bitX[5] = 1; bitX[7] = 1; }
if (mVU->code & _Ebit_) { bitX[1] = 1; bitX[5] = 1; delay = 2; }
if (mVU->code & _Mbit_) { bitX[2] = 1; bitX[5] = 1; }
if (mVU->code & _Dbit_) { bitX[3] = 1; bitX[5] = 1; }
if (mVU->code & _Tbit_) { bitX[4] = 1; bitX[5] = 1; }
iPC = (i+1)/4;
if (delay == 2) { mVUlog("<font color=\"#FFFF00\">"); }
if (delay == 1) { mVUlog("<font color=\"#999999\">"); }
iPC = (i+1);
mVUlog("<a name=\"addr%04x\">", i*4);
mVUlog("[%04x] (%08x)</a> ", i*4, mVU->code);
mVUopU<vuIndex, 2>();
if (bitX[5]) {
@ -83,12 +100,18 @@ microVUt(void) __mVUdumpProgram(int progIndex) {
mVUlog(")");
}
iPC = i/4;
iPC = i;
if (bitX[7]) { mVUlog("<font color=\"#0070ff\">"); }
mVU->code = mVU->prog.prog[progIndex].data[i];
mVUlog("\n[%04x] (%08x) ", i*4, mVU->code);
mVUlog("<br>\n[%04x] (%08x) ", i*4, mVU->code);
mVUopL<vuIndex, 2>();
mVUlog("\n\n");
mVUlog("\n\n<br><br>");
if (bitX[7]) { mVUlog("</font>"); }
}
mVUlog("</font>\n");
mVUlog("</body>\n");
mVUlog("</html>\n");
fclose(mVU->logFile);
}
#endif //PCSX2_MICROVU

View File

@ -76,7 +76,7 @@ microVUf(void) mVU_DIV() {
mVUunpack_xyzw<vuIndex>(xmmFs, xmmFs, 0);
mVUmergeRegs<vuIndex>(xmmPQ, xmmFs, writeQ ? 4 : 8);
}
pass3 { mVUlog("DIV"); }
pass3 { mVUlog("DIV Q, vf%02d%s, vf%02d%s", _Fs_, _Fsf_String, _Ft_, _Ftf_String); }
}
microVUf(void) mVU_SQRT() {
@ -94,7 +94,7 @@ microVUf(void) mVU_SQRT() {
mVUunpack_xyzw<vuIndex>(xmmFt, xmmFt, 0);
mVUmergeRegs<vuIndex>(xmmPQ, xmmFt, writeQ ? 4 : 8);
}
pass3 { mVUlog("SQRT"); }
pass3 { mVUlog("SQRT Q, vf%02d%s", _Ft_, _Ftf_String); }
}
microVUf(void) mVU_RSQRT() {
@ -132,7 +132,7 @@ microVUf(void) mVU_RSQRT() {
mVUunpack_xyzw<vuIndex>(xmmFs, xmmFs, 0);
mVUmergeRegs<vuIndex>(xmmPQ, xmmFs, writeQ ? 4 : 8);
}
pass3 { mVUlog("RSQRT"); }
pass3 { mVUlog("RSQRT Q, vf%02d%s, vf%02d%s", _Fs_, _Fsf_String, _Ft_, _Ftf_String); }
}
//------------------------------------------------------------------
@ -181,7 +181,7 @@ microVUf(void) mVU_EATAN() {
mVU_EATAN_<vuIndex>();
}
pass3 { mVUlog("EATAN"); }
pass3 { mVUlog("EATAN P"); }
}
microVUf(void) mVU_EATANxy() {
@ -199,7 +199,7 @@ microVUf(void) mVU_EATANxy() {
mVU_EATAN_<vuIndex>();
}
pass3 { mVUlog("EATANxy"); }
pass3 { mVUlog("EATANxy P"); }
}
microVUf(void) mVU_EATANxz() {
@ -217,7 +217,7 @@ microVUf(void) mVU_EATANxz() {
mVU_EATAN_<vuIndex>();
}
pass3 { mVUlog("EATANxz"); }
pass3 { mVUlog("EATANxz P"); }
}
#define eexpHelper(addr) { \
@ -257,7 +257,7 @@ microVUf(void) mVU_EEXP() {
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmT1);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("EEXP"); }
pass3 { mVUlog("EEXP P"); }
}
microVUt(void) mVU_sumXYZ() {
@ -286,7 +286,7 @@ microVUf(void) mVU_ELENG() {
SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmPQ);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ELENG"); }
pass3 { mVUlog("ELENG P"); }
}
microVUf(void) mVU_ERCPR() {
@ -301,7 +301,7 @@ microVUf(void) mVU_ERCPR() {
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ERCPR"); }
pass3 { mVUlog("ERCPR P"); }
}
microVUf(void) mVU_ERLENG() {
@ -317,7 +317,7 @@ microVUf(void) mVU_ERLENG() {
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ERLENG"); }
pass3 { mVUlog("ERLENG P"); }
}
microVUf(void) mVU_ERSADD() {
@ -333,7 +333,7 @@ microVUf(void) mVU_ERSADD() {
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ERSADD"); }
pass3 { mVUlog("ERSADD P"); }
}
microVUf(void) mVU_ERSQRT() {
@ -348,7 +348,7 @@ microVUf(void) mVU_ERSQRT() {
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ERSQRT"); }
pass3 { mVUlog("ERSQRT P"); }
}
microVUf(void) mVU_ESADD() {
@ -360,7 +360,7 @@ microVUf(void) mVU_ESADD() {
mVU_sumXYZ<vuIndex>();
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ESADD"); }
pass3 { mVUlog("ESADD P"); }
}
#define esinHelper(addr) { \
@ -394,7 +394,7 @@ microVUf(void) mVU_ESIN() {
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmT1);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ESIN"); }
pass3 { mVUlog("ESIN P"); }
}
microVUf(void) mVU_ESQRT() {
@ -406,7 +406,7 @@ microVUf(void) mVU_ESQRT() {
SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ESQRT"); }
pass3 { mVUlog("ESQRT P"); }
}
microVUf(void) mVU_ESUM() {
@ -422,7 +422,7 @@ microVUf(void) mVU_ESUM() {
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
pass3 { mVUlog("ESUM"); }
pass3 { mVUlog("ESUM P"); }
}
//------------------------------------------------------------------
@ -438,7 +438,7 @@ microVUf(void) mVU_FCAND() {
SHR32ItoR(gprT1, 24);
mVUallocVIb<vuIndex>(gprT1, 1);
}
pass3 { mVUlog("FCAND"); }
pass3 { mVUlog("FCAND vi01, $%x", _Imm24_); }
}
microVUf(void) mVU_FCEQ() {
@ -450,7 +450,7 @@ microVUf(void) mVU_FCEQ() {
SHR32ItoR(gprT1, 31);
mVUallocVIb<vuIndex>(gprT1, 1);
}
pass3 { mVUlog("FCEQ"); }
pass3 { mVUlog("FCEQ vi01, $%x", _Imm24_); }
}
microVUf(void) mVU_FCGET() {
@ -460,7 +460,7 @@ microVUf(void) mVU_FCGET() {
AND32ItoR(gprT1, 0xfff);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FCGET"); }
pass3 { mVUlog("FCGET vi%02d", _Ft_); }
}
microVUf(void) mVU_FCOR() {
@ -472,7 +472,7 @@ microVUf(void) mVU_FCOR() {
SHR32ItoR(gprT1, 24); // Get the 25th bit (also clears the rest of the garbage in the reg)
mVUallocVIb<vuIndex>(gprT1, 1);
}
pass3 { mVUlog("FCOR"); }
pass3 { mVUlog("FCOR vi01, $%x", _Imm24_); }
}
microVUf(void) mVU_FCSET() {
@ -482,7 +482,7 @@ microVUf(void) mVU_FCSET() {
MOV32ItoR(gprT1, _Imm24_);
mVUallocCFLAGb<vuIndex>(gprT1, fcInstance);
}
pass3 { mVUlog("FCSET"); }
pass3 { mVUlog("FCSET $%x", _Imm24_); }
}
//------------------------------------------------------------------
@ -498,7 +498,7 @@ microVUf(void) mVU_FMAND() {
AND16RtoR(gprT1, gprT2);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FMAND"); }
pass3 { mVUlog("FMAND vi%02d, vi%02d", _Ft_, _Fs_); }
}
microVUf(void) mVU_FMEQ() {
@ -512,7 +512,7 @@ microVUf(void) mVU_FMEQ() {
SHR32ItoR(gprT1, 31);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FMEQ"); }
pass3 { mVUlog("FMEQ vi%02d, vi%02d", _Ft_, _Fs_); }
}
microVUf(void) mVU_FMOR() {
@ -524,7 +524,7 @@ microVUf(void) mVU_FMOR() {
OR16RtoR(gprT1, gprT2);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FMOR"); }
pass3 { mVUlog("FMOR vi%02d, vi%02d", _Ft_, _Fs_); }
}
//------------------------------------------------------------------
@ -539,7 +539,7 @@ microVUf(void) mVU_FSAND() {
AND16ItoR(gprT1, _Imm12_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FSAND"); }
pass3 { mVUlog("FSAND vi%02d, $%x", _Ft_, _Imm12_); }
}
microVUf(void) mVU_FSEQ() {
@ -552,7 +552,7 @@ microVUf(void) mVU_FSEQ() {
SHR16ItoR(gprT1, 15);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FSEQ"); }
pass3 { mVUlog("FSEQ vi%02d, $%x", _Ft_, _Imm12_); }
}
microVUf(void) mVU_FSOR() {
@ -563,7 +563,7 @@ microVUf(void) mVU_FSOR() {
OR16ItoR(gprT1, _Imm12_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("FSOR"); }
pass3 { mVUlog("FSOR vi%02d, $%x", _Ft_, _Imm12_); }
}
microVUf(void) mVU_FSSET() {
@ -576,7 +576,7 @@ microVUf(void) mVU_FSSET() {
AND16ItoR(flagReg1, 0x03f); // Remember not to modify upper 16 bits because of mac flag
OR16ItoR (flagReg1, (_Imm12_ & 0xfc0));
}
pass3 { mVUlog("FSSET"); }
pass3 { mVUlog("FSSET $%x", _Imm12_); }
}
//------------------------------------------------------------------
@ -595,7 +595,7 @@ microVUf(void) mVU_IADD() {
else ADD16RtoR(gprT1, gprT1);
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
pass3 { mVUlog("IADD"); }
pass3 { mVUlog("IADD vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); }
}
microVUf(void) mVU_IADDI() {
@ -606,7 +606,7 @@ microVUf(void) mVU_IADDI() {
ADD16ItoR(gprT1, _Imm5_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("IADDI"); }
pass3 { mVUlog("IADDI vi%02d, vi%02d, %d", _Ft_, _Fs_, _Imm5_); }
}
microVUf(void) mVU_IADDIU() {
@ -617,7 +617,7 @@ microVUf(void) mVU_IADDIU() {
ADD16ItoR(gprT1, _Imm15_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("IADDIU"); }
pass3 { mVUlog("IADDIU vi%02d, vi%02d, %d", _Ft_, _Fs_, _Imm15_); }
}
microVUf(void) mVU_IAND() {
@ -631,7 +631,7 @@ microVUf(void) mVU_IAND() {
}
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
pass3 { mVUlog("IAND"); }
pass3 { mVUlog("IAND vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); }
}
microVUf(void) mVU_IOR() {
@ -645,7 +645,7 @@ microVUf(void) mVU_IOR() {
}
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
pass3 { mVUlog("IOR"); }
pass3 { mVUlog("IOR vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); }
}
microVUf(void) mVU_ISUB() {
@ -664,7 +664,7 @@ microVUf(void) mVU_ISUB() {
}
else { PXORRtoR(mmVI(_Fd_), mmVI(_Fd_)); }
}
pass3 { mVUlog("ISUB"); }
pass3 { mVUlog("ISUB vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); }
}
microVUf(void) mVU_ISUBIU() {
@ -675,7 +675,7 @@ microVUf(void) mVU_ISUBIU() {
SUB16ItoR(gprT1, _Imm15_);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("ISUBIU"); }
pass3 { mVUlog("ISUBIU vi%02d, vi%02d, %d", _Ft_, _Fs_, _Imm15_); }
}
//------------------------------------------------------------------
@ -692,7 +692,7 @@ microVUf(void) mVU_MFIR() {
if (!_XYZW_SS) { mVUunpack_xyzw<vuIndex>(xmmT1, xmmT1, 0); }
mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1);
}
pass3 { mVUlog("MFIR"); }
pass3 { mVUlog("MFIR.%s vf%02d, vi%02d", _XYZW_String, _Ft_, _Fs_); }
}
microVUf(void) mVU_MFP() {
@ -702,7 +702,7 @@ microVUf(void) mVU_MFP() {
getPreg(xmmFt);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1);
}
pass3 { mVUlog("MFP"); }
pass3 { mVUlog("MFP.%s vf%02d, P", _XYZW_String, _Ft_); }
}
microVUf(void) mVU_MOVE() {
@ -712,7 +712,7 @@ microVUf(void) mVU_MOVE() {
mVUloadReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1);
}
pass3 { mVUlog("MOVE"); }
pass3 { mVUlog("MOVE.%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); }
}
microVUf(void) mVU_MR32() {
@ -723,7 +723,7 @@ microVUf(void) mVU_MR32() {
if (_X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x39); }
mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 0);
}
pass3 { mVUlog("MR32"); }
pass3 { mVUlog("MR32.%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); }
}
microVUf(void) mVU_MTIR() {
@ -733,7 +733,7 @@ microVUf(void) mVU_MTIR() {
MOVZX32M16toR(gprT1, (uptr)&mVU->regs->VF[_Fs_].UL[_Fsf_]);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("MTIR"); }
pass3 { mVUlog("MTIR vi%02d, vf%02d%s", _Ft_, _Fs_, _Fsf_String); }
}
//------------------------------------------------------------------
@ -752,12 +752,11 @@ microVUf(void) mVU_ILW() {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
ADD32ItoR(gprT1, _Imm11_);
mVUaddrFix<vuIndex>(gprT1);
MOV32RmtoR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS);
if (isMMX(_Ft_)) AND32ItoR(gprT1, 0xffff);
MOVZX32Rm16toR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
pass3 { mVUlog("ILW"); }
pass3 { mVUlog("ILW.%s vi%02d, vi%02d + %d", _XYZW_String, _Ft_, _Fs_, _Imm11_); }
}
microVUf(void) mVU_ILWR() {
@ -771,12 +770,11 @@ microVUf(void) mVU_ILWR() {
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUaddrFix<vuIndex>(gprT1);
MOV32RmtoR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS);
if (isMMX(_Ft_)) AND32ItoR(gprT1, 0xffff);
MOVZX32Rm16toR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
pass3 { mVUlog("ILWR"); }
pass3 { mVUlog("ILWR.%s vi%02d, vi%02d", _XYZW_String, _Ft_, _Fs_); }
}
//------------------------------------------------------------------
@ -806,7 +804,7 @@ microVUf(void) mVU_ISW() {
if (_W) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem+12);
}
}
pass3 { mVUlog("ISW"); }
pass3 { mVUlog("ISW.%s vi%02d, vi%02d + %d", _XYZW_String, _Ft_, _Fs_, _Imm11_); }
}
microVUf(void) mVU_ISWR() {
@ -830,7 +828,7 @@ microVUf(void) mVU_ISWR() {
if (_W) MOV32RtoRm(gprT1, gprT2, (uptr)mVU->regs->Mem+12);
}
}
pass3 { mVUlog("ISWR"); }
pass3 { mVUlog("ISWR.%s vi%02d, vi%02d", _XYZW_String, _Ft_, _Fs_); }
}
//------------------------------------------------------------------
@ -1081,6 +1079,7 @@ microVUf(void) mVU_XITOP() {
//------------------------------------------------------------------
void __fastcall mVU_XGKICK_(u32 addr) {
addr = (addr<<4) & 0x3fff; // Multiply addr by 16 to get real address
u32 *data = (u32*)(microVU1.regs->Mem + (addr&0x3fff));
u32 size = mtgsThread->PrepDataPacket( GIF_PATH_1, data, (0x4000-(addr&0x3fff)) >> 4);
u8 *pDest = mtgsThread->GetDataPacketPtr();
@ -1088,15 +1087,20 @@ void __fastcall mVU_XGKICK_(u32 addr) {
mtgsThread->SendDataPacket();
}
void __fastcall mVU_XGKICK__(u32 addr) {
GSGIFTRANSFER1((u32*)microVU1.regs->Mem, ((addr<<4)&0x3fff));
}
microVUf(void) mVU_XGKICK() {
microVU* mVU = mVUx;
pass1 { mVUanalyzeXGkick<vuIndex>(_Fs_, 4); }
pass2 {
mVUprint("XGkick");
mVUallocVIa<vuIndex>(gprT2, _Fs_); // gprT2 = ECX for __fastcall
PUSH32R(gprR); // gprR = EDX is volatile so backup
CALLFunc((uptr)mVU_XGKICK_);
POP32R(gprR); // Restore
mVUbackupRegs<vuIndex>();
if (mtgsThread != NULL) CALLFunc((uptr)mVU_XGKICK_);
else CALLFunc((uptr)mVU_XGKICK__);
mVUrestoreRegs<vuIndex>();
}
pass3 { mVUlog("XGKICK vi%02d", _Fs_); }
}
@ -1108,7 +1112,7 @@ microVUf(void) mVU_XGKICK() {
microVUf(void) mVU_B() {
microVU* mVU = mVUx;
mVUbranch = 1;
pass3 { mVUlog("B [%04x]", branchAddr); }
pass3 { mVUlog("B [<a href=\"#addr%04x\">%04x</a>]", branchAddr, branchAddr); }
}
microVUf(void) mVU_BAL() {
microVU* mVU = mVUx;
@ -1118,7 +1122,7 @@ microVUf(void) mVU_BAL() {
MOV32ItoR(gprT1, bSaveAddr);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
pass3 { mVUlog("BAL vi%02d [%04x]", _Ft_, branchAddr); }
pass3 { mVUlog("BAL vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBEQ() {
microVU* mVU = mVUx;
@ -1131,7 +1135,7 @@ microVUf(void) mVU_IBEQ() {
else { mVUallocVIa<vuIndex>(gprT2, _Ft_); XOR32RtoR(gprT1, gprT2); }
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBEQ vi%02d, vi%02d [%04x]", _Ft_, _Fs_, branchAddr); }
pass3 { mVUlog("IBEQ vi%02d, vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBGEZ() {
microVU* mVU = mVUx;
@ -1142,7 +1146,7 @@ microVUf(void) mVU_IBGEZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBGEZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBGEZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBGTZ() {
microVU* mVU = mVUx;
@ -1153,7 +1157,7 @@ microVUf(void) mVU_IBGTZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBGTZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBGTZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBLEZ() {
microVU* mVU = mVUx;
@ -1164,7 +1168,7 @@ microVUf(void) mVU_IBLEZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBLEZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBLEZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBLTZ() {
microVU* mVU = mVUx;
@ -1175,7 +1179,7 @@ microVUf(void) mVU_IBLTZ() {
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBLTZ vi%02d [%04x]", _Fs_, branchAddr); }
pass3 { mVUlog("IBLTZ vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_IBNE() {
microVU* mVU = mVUx;
@ -1188,7 +1192,7 @@ microVUf(void) mVU_IBNE() {
else { mVUallocVIa<vuIndex>(gprT2, _Ft_); XOR32RtoR(gprT1, gprT2); }
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("IBNE vi%02d, vi%02d [%04x]", _Ft_, _Fs_, branchAddr); }
pass3 { mVUlog("IBNE vi%02d, vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, _Fs_, branchAddr, branchAddr); }
}
microVUf(void) mVU_JR() {
microVU* mVU = mVUx;
@ -1197,6 +1201,8 @@ microVUf(void) mVU_JR() {
pass2 {
if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]);
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
SHL32ItoR(gprT1, 3);
AND32ItoR(gprT1, vuIndex ? 0x3ff8 : 0xff8);
MOV32RtoM((uptr)&mVU->branch, gprT1);
}
pass3 { mVUlog("JR [vi%02d]", _Fs_); }
@ -1208,6 +1214,8 @@ microVUf(void) mVU_JALR() {
pass2 {
if (memReadIs) MOV32MtoR(gprT1, (uptr)&mVU->VIbackup[0]);
else mVUallocVIa<vuIndex>(gprT1, _Fs_);
SHL32ItoR(gprT1, 3);
AND32ItoR(gprT1, vuIndex ? 0x3ff8 : 0xff8);
MOV32RtoM((uptr)&mVU->branch, gprT1);
MOV32ItoR(gprT1, bSaveAddr);
mVUallocVIb<vuIndex>(gprT1, _Ft_);

View File

@ -88,7 +88,7 @@ declareAllVariables
#define _Fsf_ ((mVU->code >> 21) & 0x03)
#define _Ftf_ ((mVU->code >> 23) & 0x03)
#define _Imm5_ (((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf))
#define _Imm5_ (s16)(((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf))
#define _Imm11_ (s32)((mVU->code & 0x400) ? (0xfffffc00 | (mVU->code & 0x3ff)) : mVU->code & 0x3ff)
#define _Imm12_ (((mVU->code >> 21) & 0x1) << 11) | (mVU->code & 0x7ff)
#define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff))
@ -161,13 +161,14 @@ declareAllVariables
#define incPC(x) { iPC = ((iPC + x) & (mVU->progSize-1)); setCode(); }
#define incPC2(x) { iPC = ((iPC + x) & (mVU->progSize-1)); }
#define incCycles(x) { mVUincCycles<vuIndex>(x); }
#define bSaveAddr ((xPC + (2 * 8)) & ((vuIndex) ? 0x3ff8:0xff8))
#define bSaveAddr (((xPC + (2 * 8)) & ((vuIndex) ? 0x3ff8:0xff8)) / 8)
#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & ((vuIndex) ? 0x3ff8:0xff8))
#define shufflePQ (((mVU->q) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04))
#define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04))
#define _Fsf_String ((_Fsf_ == 3) ? "w" : ((_Fsf_ == 2) ? "z" : ((_Fsf_ == 1) ? "y" : "x")))
#define _Ftf_String ((_Ftf_ == 3) ? "w" : ((_Ftf_ == 2) ? "z" : ((_Ftf_ == 1) ? "y" : "x")))
#define xyzwStr(x,s) (_X_Y_Z_W == x) ? s :
#define _XYZW_String (xyzwStr(1, "w") (xyzwStr(2, "z") (xyzwStr(3, "zw") (xyzwStr(4, "y") (xyzwStr(5, "yw") (xyzwStr(6, "yz") (xyzwStr(7, "yzw") (xyzwStr(8, "x") (xyzwStr(9, "xw") (xyzwStr(10, "xz") (xyzwStr(11, "xzw") (xyzwStr(12, "xy") (xyzwStr(13, "xyw") (xyzwStr(14, "xyz") "xyzw"))))))))))))))
#define _BC_String (_bc_x ? "x" : (_bc_y ? "y" : (_bc_z ? "z" : "w")))
#define _isNOP (1<<0) // Skip Lower Instruction
@ -230,7 +231,7 @@ declareAllVariables
#define doDivFlag (mVUinfo & (1<<28))
#define doClip (mVUinfo & (1<<29))
#define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9)
#define isMMX(_VIreg_) 0//(_VIreg_ >= 1 && _VIreg_ <=8)
#define mmVI(_VIreg_) (_VIreg_ - 1)
#ifdef mVUdebug
@ -249,11 +250,9 @@ declareAllVariables
#ifdef mVUlogProg
#define mVUlog __mVULog<vuIndex>
#define mVUsetupLog __mVUsetupLog<vuIndex>
#define mVUdumpProg __mVUdumpProgram<vuIndex>
#else
#define mVUlog 0&&
#define mVUsetupLog()
#define mVUdumpProg 0&&
#endif

View File

@ -264,7 +264,7 @@ microVUx(void) mVUmergeRegs(int dest, int src, int xyzw) {
// Transforms the Address in gprReg to valid VU0/VU1 Address
microVUt(void) mVUaddrFix(int gprReg) {
if ( vuIndex == 1 ) {
if (vuIndex) {
AND32ItoR(gprReg, 0x3ff); // wrap around
SHL32ItoR(gprReg, 4);
}
@ -281,4 +281,22 @@ microVUt(void) mVUaddrFix(int gprReg) {
}
}
// Backup Volatile Regs (EAX, ECX, EDX, MM0~7, XMM0~7, are all volatile according to 32bit Win/Linux ABI)
microVUt(void) mVUbackupRegs() {
microVU* mVU = mVUx;
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC);
SSE_MOVAPS_XMM_to_M128((uptr)&mVU->xmmPQb[0], xmmPQ);
PUSH32R(gprR); // Backup EDX
}
// Restore Volatile Regs
microVUt(void) mVUrestoreRegs() {
microVU* mVU = mVUx;
SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]);
SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->xmmPQb[0]);
SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals);
SSE_MOVAPS_M128_to_XMM(xmmMin, (uptr)mVU_minvals);
POP32R(gprR); // Restore EDX
}
#endif //PCSX2_MICROVU

View File

@ -78,6 +78,15 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
// Helper Macros
//------------------------------------------------------------------
#define mVUlogFtFs() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Ft_, _Fs_); }
#define mVUlogFd() { mVUlog(".%s vf%02d, vf%02d", _XYZW_String, _Fd_, _Fs_); }
#define mVUlogACC() { mVUlog(".%s ACC, vf%02d", _XYZW_String, _Fs_); }
#define mVUlogFt() { mVUlog(", vf%02d", _Ft_); }
#define mVUlogBC() { mVUlog(", vf%02d%s", _Ft_, _BC_String); }
#define mVUlogI() { mVUlog(", I"); }
#define mVUlogQ() { mVUlog(", Q"); }
#define mVUlogCLIP() { mVUlog("w.xyz vf%02d, vf%02dw", _Fs_, _Ft_); }
// FMAC1 - Normal FMAC Opcodes
#define mVU_FMAC1(operation, OPname) { \
microVU* mVU = mVUx; \
@ -90,7 +99,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \
mVUallocFMAC1b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \
}
// FMAC3 - BC(xyzw) FMAC Opcodes
#define mVU_FMAC3(operation, OPname) { \
@ -104,7 +113,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \
mVUallocFMAC3b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \
}
// FMAC4 - FMAC Opcodes Storing Result to ACC
#define mVU_FMAC4(operation, OPname) { \
@ -118,7 +127,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC4b<vuIndex>(ACC, Fs); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \
}
// FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC
#define mVU_FMAC5(operation, OPname) { \
@ -132,7 +141,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC5b<vuIndex>(ACC, Fs); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogBC(); } \
}
// FMAC6 - Normal FMAC Opcodes (I Reg)
#define mVU_FMAC6(operation, OPname) { \
@ -146,7 +155,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \
mVUallocFMAC6b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \
}
// FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg)
#define mVU_FMAC7(operation, OPname) { \
@ -160,7 +169,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC7b<vuIndex>(ACC, Fs); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogI(); } \
}
// FMAC8 - MADD FMAC Opcode Storing Result to Fd
#define mVU_FMAC8(operation, OPname) { \
@ -180,7 +189,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC8b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \
}
// FMAC9 - MSUB FMAC Opcode Storing Result to Fd
#define mVU_FMAC9(operation, OPname) { \
@ -200,7 +209,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC9b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \
}
// FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd
#define mVU_FMAC10(operation, OPname) { \
@ -220,7 +229,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC10b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \
}
// FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd
#define mVU_FMAC11(operation, OPname) { \
@ -240,7 +249,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC11b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \
}
// FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg)
#define mVU_FMAC12(operation, OPname) { \
@ -260,7 +269,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC12b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \
}
// FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg)
#define mVU_FMAC13(operation, OPname) { \
@ -280,7 +289,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC13b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \
}
// FMAC14 - MADDA/MSUBA FMAC Opcode
#define mVU_FMAC14(operation, OPname) { \
@ -300,7 +309,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC14b<vuIndex>(ACCw, ACCr); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \
}
// FMAC15 - MADDA/MSUBA BC(xyzw) FMAC Opcode
#define mVU_FMAC15(operation, OPname) { \
@ -320,7 +329,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC15b<vuIndex>(ACCw, ACCr); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogBC(); } \
}
// FMAC16 - MADDA/MSUBA FMAC Opcode (I Reg)
#define mVU_FMAC16(operation, OPname) { \
@ -340,7 +349,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC16b<vuIndex>(ACCw, ACCr); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogI(); } \
}
// FMAC18 - OPMULA FMAC Opcode
#define mVU_FMAC18(operation, OPname) { \
@ -353,9 +362,9 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC18b<vuIndex>(ACC, Fs); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \
}
// FMAC19 - OPMULA FMAC Opcode
// FMAC19 - OPMSUB FMAC Opcode
#define mVU_FMAC19(operation, OPname) { \
microVU* mVU = mVUx; \
pass1 { mVUanalyzeFMAC1<vuIndex>(_Fd_, _Fs_, _Ft_); } \
@ -367,7 +376,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC19b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \
}
// FMAC22 - Normal FMAC Opcodes (Q Reg)
#define mVU_FMAC22(operation, OPname) { \
@ -381,7 +390,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \
mVUallocFMAC22b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \
}
// FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg)
#define mVU_FMAC23(operation, OPname) { \
@ -395,7 +404,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC23b<vuIndex>(ACC, Fs); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogQ();} \
}
// FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg)
#define mVU_FMAC24(operation, OPname) { \
@ -415,7 +424,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC24b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \
}
// FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg)
#define mVU_FMAC25(operation, OPname) { \
@ -435,7 +444,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(Fd, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC25b<vuIndex>(Fd); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \
}
// FMAC26 - MADDA/MSUBA FMAC Opcode (Q Reg)
#define mVU_FMAC26(operation, OPname) { \
@ -455,7 +464,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUupdateFlags<vuIndex>(ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \
mVUallocFMAC26b<vuIndex>(ACCw, ACCr); \
} \
pass3 { mVUlog(OPname); } \
pass3 { mVUlog(OPname); mVUlogACC(); mVUlogQ(); } \
}
//------------------------------------------------------------------
@ -471,7 +480,7 @@ microVUf(void) mVU_ABS() {
SSE_ANDPS_M128_to_XMM(Fs, (uptr)mVU_absclip);
mVUallocFMAC2b<vuIndex>(Ft);
}
pass3 { mVUlog("ABS"); }
pass3 { mVUlog("ABS"); mVUlogFtFs(); }
}
microVUf(void) mVU_ADD() { mVU_FMAC1 (ADD, "ADD"); }
microVUf(void) mVU_ADDi() { mVU_FMAC6 (ADD, "ADDi"); }
@ -545,7 +554,7 @@ microVUf(void) mVU_MSUBAz() { mVU_FMAC15(SUB, "MSUBAz"); }
microVUf(void) mVU_MSUBAw() { mVU_FMAC15(SUB, "MSUBAw"); }
microVUf(void) mVU_MAX() { mVU_FMAC1 (MAX, "MAX"); }
microVUf(void) mVU_MAXi() { mVU_FMAC6 (MAX, "MAXi"); }
microVUf(void) mVU_MAXx() { mVU_FMAC3 (MAX, "MAXq"); }
microVUf(void) mVU_MAXx() { mVU_FMAC3 (MAX, "MAXx"); }
microVUf(void) mVU_MAXy() { mVU_FMAC3 (MAX, "MAXy"); }
microVUf(void) mVU_MAXz() { mVU_FMAC3 (MAX, "MAXz"); }
microVUf(void) mVU_MAXw() { mVU_FMAC3 (MAX, "MAXw"); }
@ -579,10 +588,10 @@ microVUq(void) mVU_FTOIx(uptr addr) {
mVUallocFMAC2b<vuIndex>(Ft);
}
}
microVUf(void) mVU_FTOI0() { mVU_FTOIx<vuIndex, recPass>((uptr)0); pass3 { mVUlog("FTOI0"); } }
microVUf(void) mVU_FTOI4() { mVU_FTOIx<vuIndex, recPass>((uptr)mVU_FTOI_4); pass3 { mVUlog("FTOI4"); } }
microVUf(void) mVU_FTOI12() { mVU_FTOIx<vuIndex, recPass>((uptr)mVU_FTOI_12); pass3 { mVUlog("FTOI12"); } }
microVUf(void) mVU_FTOI15() { mVU_FTOIx<vuIndex, recPass>((uptr)mVU_FTOI_15); pass3 { mVUlog("FTOI15"); } }
microVUf(void) mVU_FTOI0() { mVU_FTOIx<vuIndex, recPass>((uptr)0); pass3 { microVU* mVU = mVUx; mVUlog("FTOI0"); mVUlogFtFs(); } }
microVUf(void) mVU_FTOI4() { mVU_FTOIx<vuIndex, recPass>((uptr)mVU_FTOI_4); pass3 { microVU* mVU = mVUx; mVUlog("FTOI4"); mVUlogFtFs(); } }
microVUf(void) mVU_FTOI12() { mVU_FTOIx<vuIndex, recPass>((uptr)mVU_FTOI_12); pass3 { microVU* mVU = mVUx; mVUlog("FTOI12"); mVUlogFtFs(); } }
microVUf(void) mVU_FTOI15() { mVU_FTOIx<vuIndex, recPass>((uptr)mVU_FTOI_15); pass3 { microVU* mVU = mVUx; mVUlog("FTOI15"); mVUlogFtFs(); } }
microVUq(void) mVU_ITOFx(uptr addr) {
microVU* mVU = mVUx;
pass1 { mVUanalyzeFMAC2<vuIndex>(_Fs_, _Ft_); }
@ -597,10 +606,10 @@ microVUq(void) mVU_ITOFx(uptr addr) {
mVUallocFMAC2b<vuIndex>(Ft);
}
}
microVUf(void) mVU_ITOF0() { mVU_ITOFx<vuIndex, recPass>((uptr)0); pass3 { mVUlog("ITOF0"); } }
microVUf(void) mVU_ITOF4() { mVU_ITOFx<vuIndex, recPass>((uptr)mVU_ITOF_4); pass3 { mVUlog("ITOF4"); } }
microVUf(void) mVU_ITOF12() { mVU_ITOFx<vuIndex, recPass>((uptr)mVU_ITOF_12); pass3 { mVUlog("ITOF12"); } }
microVUf(void) mVU_ITOF15() { mVU_ITOFx<vuIndex, recPass>((uptr)mVU_ITOF_15); pass3 { mVUlog("ITOF15"); } }
microVUf(void) mVU_ITOF0() { mVU_ITOFx<vuIndex, recPass>((uptr)0); pass3 { microVU* mVU = mVUx; mVUlog("ITOF0"); mVUlogFtFs(); } }
microVUf(void) mVU_ITOF4() { mVU_ITOFx<vuIndex, recPass>((uptr)mVU_ITOF_4); pass3 { microVU* mVU = mVUx; mVUlog("ITOF4"); mVUlogFtFs(); } }
microVUf(void) mVU_ITOF12() { mVU_ITOFx<vuIndex, recPass>((uptr)mVU_ITOF_12); pass3 { microVU* mVU = mVUx; mVUlog("ITOF12"); mVUlogFtFs(); } }
microVUf(void) mVU_ITOF15() { mVU_ITOFx<vuIndex, recPass>((uptr)mVU_ITOF_15); pass3 { microVU* mVU = mVUx; mVUlog("ITOF15"); mVUlogFtFs(); } }
microVUf(void) mVU_CLIP() {
microVU* mVU = mVUx;
pass1 { mVUanalyzeFMAC4<vuIndex>(_Fs_, _Ft_); }
@ -633,6 +642,6 @@ microVUf(void) mVU_CLIP() {
mVUallocCFLAGb<vuIndex>(gprT1, fcInstance);
}
pass3 { mVUlog("CLIP"); }
pass3 { mVUlog("CLIP"); mVUlogCLIP(); }
}
#endif //PCSX2_MICROVU

View File

@ -47,13 +47,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xpad", "plugins\xpad\xpad_v
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDVDolio", "plugins\CDVDolio\cdvd_vs2008.vcproj", "{FCDF5AE2-EA47-4CC6-9F20-23A0517FEBCB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDVDnull", "plugins\CDVDnull\Src\CDVDnull_vs2008.vcproj", "{F38D9DF0-F68D-49D9-B3A0-932E74FB74A0}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDVDnull", "plugins\CDVDnull\Windows\CDVDnull_vs2008.vcproj", "{F38D9DF0-F68D-49D9-B3A0-932E74FB74A0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "USBnull", "plugins\USBnull\Windows\USBnull_vc2008.vcproj", "{BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FWnull", "plugins\FWnull\Windows\FWnull_vc2008.vcproj", "{3D0EB14D-32F3-4D82-9C6D-B806ADBB859C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DEV9null", "plugins\dev9null\src\DEV9null_vc2008.vcproj", "{04439C5F-05FB-4A9C-AAD1-5388C25377DB}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DEV9null", "plugins\dev9null\Windows\DEV9null_vc2008.vcproj", "{04439C5F-05FB-4A9C-AAD1-5388C25377DB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nulls", "Nulls", "{E1828E40-2FBB-48FE-AE7F-5587755DCE0E}"
EndProject

140
plugins/CDVDnull/CDVD.cpp Normal file
View File

@ -0,0 +1,140 @@
/* CDVDnull
* Copyright (C) 2002-2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include "CDVD.h"
const char *LibName = "CDVDnull Driver";
const unsigned char version = PS2E_CDVD_VERSION;
const unsigned char revision = 0;
const unsigned char build = 6;
EXPORT_C_(char*) PS2EgetLibName()
{
return (char *)LibName;
}
EXPORT_C_(u32) PS2EgetLibType()
{
return PS2E_LT_CDVD;
}
EXPORT_C_(u32) CALLBACK PS2EgetLibVersion2(u32 type)
{
return (version << 16) | (revision << 8) | build;
}
#ifdef _WIN32
void SysMessage(const char *fmt, ...)
{
va_list list;
char tmp[512];
va_start(list, fmt);
vsprintf(tmp, fmt, list);
va_end(list);
MessageBox(0, tmp, "CDVDnull Msg", 0);
}
#endif
EXPORT_C_(s32) CDVDinit()
{
return 0;
}
EXPORT_C_(s32) CDVDopen(const char* pTitle)
{
return 0;
}
EXPORT_C_(void) CDVDclose()
{
}
EXPORT_C_(void) CDVDshutdown()
{
}
EXPORT_C_(s32) CDVDreadTrack(u32 lsn, int mode)
{
return -1;
}
// return can be NULL (for async modes)
EXPORT_C_(u8*) CDVDgetBuffer()
{
return NULL;
}
EXPORT_C_(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq)
{
return -1;
}
EXPORT_C_(s32) CDVDgetTN(cdvdTN *Buffer)
{
return -1;
}
EXPORT_C_(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer)
{
return -1;
}
EXPORT_C_(s32) CDVDgetTOC(void* toc)
{
return -1;
}
EXPORT_C_(s32) CDVDgetDiskType()
{
return CDVD_TYPE_NODISC;
}
EXPORT_C_(s32) CDVDgetTrayStatus()
{
return CDVD_TRAY_CLOSE;
}
EXPORT_C_(s32) CDVDctrlTrayOpen()
{
return 0;
}
EXPORT_C_(s32) CDVDctrlTrayClose()
{
return 0;
}
EXPORT_C_(void) CDVDconfigure()
{
SysMessage("Nothing to Configure");
}
EXPORT_C_(void) CDVDabout()
{
SysMessage("%s %d.%d", LibName, revision, build);
}
EXPORT_C_(s32) CDVDtest()
{
return 0;
}

58
plugins/CDVDnull/CDVD.h Normal file
View File

@ -0,0 +1,58 @@
/* CDVDnull
* Copyright (C) 2002-2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __CDVD_H__
#define __CDVD_H__
#ifdef _WIN32
#include <windows.h>
#endif
extern "C"
{
#define CDVDdefs
#include "PS2Edefs.h"
}
#ifdef __LINUX__
#include <gtk/gtk.h>
#else
#include <windows.h>
#include <windowsx.h>
#endif
/*#ifdef _MSC_VER
#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK
#else
#define EXPORT_C_(type) extern "C" type
#endif*/
#ifdef _MSC_VER
#define EXPORT_C_(type) extern "C" type CALLBACK
#else
#define EXPORT_C_(type) extern "C" type
#endif
extern const unsigned char version;
extern const unsigned char revision;
extern const unsigned char build;
extern const unsigned int minor;
extern const char *LibName;
extern void SysMessage(const char *fmt, ...);
#endif /* __CDVD_H__ */

View File

@ -0,0 +1,78 @@
/* CDVDnull
* Copyright (C) 2002-2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CDVD.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
GtkWidget *MsgDlg;
void OnMsg_Ok()
{
gtk_widget_destroy(MsgDlg);
gtk_main_quit();
}
void SysMessage(const char *fmt, ...)
{
GtkWidget *Ok, *Txt;
GtkWidget *Box, *Box1;
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
MsgDlg = gtk_window_new(GTK_WINDOW_POPUP);
gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(MsgDlg), "SPU2null Msg");
gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5);
Box = gtk_vbox_new(5, 0);
gtk_container_add(GTK_CONTAINER(MsgDlg), Box);
gtk_widget_show(Box);
Txt = gtk_label_new(msg);
gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5);
gtk_widget_show(Txt);
Box1 = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0);
gtk_widget_show(Box1);
Ok = gtk_button_new_with_label("Ok");
gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL);
gtk_container_add(GTK_CONTAINER(Box1), Ok);
GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT);
gtk_widget_show(Ok);
gtk_widget_show(MsgDlg);
gtk_main();
}
void LoadConfig()
{
}

View File

@ -0,0 +1,27 @@
# Create a shared library libCDVDnull
AUTOMAKE_OPTIONS = foreign
noinst_LIBRARIES = libCDVDnull.a
INCLUDES = -I@srcdir@/../../common/include -I@srcdir@/../../3rdparty -I@srcdir@/Linux
libCDVDnull_a_CXXFLAGS = $(shell pkg-config --cflags gtk+-2.0)
libCDVDnull_a_CFLAGS = $(shell pkg-config --cflags gtk+-2.0)
# Create a shared object by faking an exe (thanks to ODE makefiles)
traplibdir=$(prefix)
if DEBUGBUILD
preext=d
endif
EXEEXT=$(preext)@so_ext@
traplib_PROGRAMS=libCDVDnull
libCDVDnull_SOURCES=
libCDVDnull_DEPENDENCIES = libCDVDnull.a
libCDVDnull_LDFLAGS= @SHARED_LDFLAGS@
libCDVDnull_LDFLAGS+=-Wl,-soname,@libCDVDnull_SONAME@
libCDVDnull_LDADD=$(libCDVDnull_a_OBJECTS)
libCDVDnull_a_SOURCES = CDVD.cpp CDVD.h Linux/Config.cpp
#SUBDIRS = Linux

View File

@ -1,145 +0,0 @@
#include <stdio.h>
#include "CDVD.h"
char *LibName = "CDVDnull Driver";
const unsigned char version = PS2E_CDVD_VERSION;
const unsigned char revision = 0;
const unsigned char build = 6;
char* CALLBACK PS2EgetLibName() {
return LibName;
}
u32 CALLBACK PS2EgetLibType() {
return PS2E_LT_CDVD;
}
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
return (version << 16) | (revision << 8) | build;
}
#ifdef _WIN32
void SysMessage(char *fmt, ...) {
va_list list;
char tmp[512];
va_start(list,fmt);
vsprintf(tmp,fmt,list);
va_end(list);
MessageBox(0, tmp, "CDVDnull Msg", 0);
}
#else
void SysMessage(char *fmt, ...) {
/*GtkWidget *Ok,*Txt;
GtkWidget *Box,*Box1;
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
MsgDlg = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(MsgDlg), "GSsoft Msg");
gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5);
Box = gtk_vbox_new(5, 0);
gtk_container_add(GTK_CONTAINER(MsgDlg), Box);
gtk_widget_show(Box);
Txt = gtk_label_new(msg);
gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5);
gtk_widget_show(Txt);
Box1 = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0);
gtk_widget_show(Box1);
Ok = gtk_button_new_with_label("Ok");
gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL);
gtk_container_add(GTK_CONTAINER(Box1), Ok);
GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT);
gtk_widget_show(Ok);
gtk_widget_show(MsgDlg);
gtk_main();*/
}
#endif
s32 CALLBACK CDVDinit() {
return 0;
}
s32 CALLBACK CDVDopen(const char* pTitle) {
return 0;
}
void CALLBACK CDVDclose() {
}
void CALLBACK CDVDshutdown() {
}
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode) {
return -1;
}
// return can be NULL (for async modes)
u8* CALLBACK CDVDgetBuffer() {
return NULL;
}
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq) {
return -1;
}
s32 CALLBACK CDVDgetTN(cdvdTN *Buffer) {
return -1;
}
s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer) {
return -1;
}
s32 CALLBACK CDVDgetTOC(void* toc) {
return -1;
}
s32 CALLBACK CDVDgetDiskType() {
return CDVD_TYPE_NODISC;
}
s32 CALLBACK CDVDgetTrayStatus() {
return CDVD_TRAY_CLOSE;
}
s32 CALLBACK CDVDctrlTrayOpen() {
return 0;
}
s32 CALLBACK CDVDctrlTrayClose() {
return 0;
}
void CALLBACK CDVDconfigure() {
SysMessage("Nothing to Configure");
}
void CALLBACK CDVDabout() {
SysMessage("%s %d.%d", LibName, revision, build);
}
s32 CALLBACK CDVDtest() {
return 0;
}

View File

@ -1,11 +0,0 @@
#ifndef __CDVD_H__
#define __CDVD_H__
#ifdef _WIN32
#include <windows.h>
#endif
#define CDVDdefs
#include "PS2Edefs.h"
#endif /* __CDVD_H__ */

View File

@ -1,48 +0,0 @@
#
# Makefile for MINGW32
#
all: cdvdnull
install: all
PLUGIN = libCDVDnull.so
CC = gcc
NASM = nasmw
RM = rm -f
AR = ar
STRIP = strip
RC = windres
OPTIMIZE = -O2 -fomit-frame-pointer -finline-functions -ffast-math -fno-strict-aliasing
FLAGS = -DENABLE_NLS -DPACKAGE=\"pcsx2\"
RC1FLAGS =
LIBS =
RESOBJ = cdvdnull.o
OBJS = CDVD.o
DEPS:= $(OBJS:.o=.d)
CFLAGS = -Wall ${OPTIMIZE} -I../../../common/include -I. -I/usr/local/include ${FLAGS} -fPIC
cdvdnull: ${OBJS}
# dllwrap --def plugin.def -o ${PLUGIN} ${OBJS} ${LIBS}
${CC} -shared -Wl,-soname,${PLUGIN} ${CFLAGS} ${OBJS} -o ${PLUGIN} ${LIBS}
${STRIP} ${PLUGIN}
.PHONY: clean cdvdnull
clean:
${RM} ${OBJS} ${DEPS} ${PCSX2}
%.o: %.asm
${NASM} ${ASMFLAGS} -o $@ $<
%.o: %.c
${CC} ${CFLAGS} -c -o $@ $< -MD -MF $(patsubst %.o,%.d,$@)
${RESOBJ}: CDVDnull.rc
${RC} -D__MINGW32__ -I rc -O coff -o $@ -i $<
-include ${DEPS}

View File

@ -102,11 +102,11 @@
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath=".\CDVD.c"
RelativePath="..\CDVD.cpp"
>
</File>
<File
RelativePath=".\CDVD.h"
RelativePath="..\CDVD.h"
>
</File>
<File

View File

@ -1,13 +1,32 @@
#!/bin/sh
echo ---------------
echo Building CDVDnull
echo ---------------
curdir=`pwd`
echo -----------------
echo Building CDVDnull
echo -----------------
cd ${curdir}/Src
make clean
make $@
# copy the files
cp libCDVDnull.so ${PCSX2PLUGINS}
if test "${CDVDnullOPTIONS+set}" != set ; then
export CDVDnullOPTIONS=""
fi
if [ $# -gt 0 ] && [ $1 = "all" ]
then
aclocal
automake -a
autoconf
./configure ${CDVDnullOPTIONS} --prefix=${PCSX2PLUGINS}
make clean
make install
else
make $@
fi
if [ $? -ne 0 ]
then
exit 1
fi

View File

@ -0,0 +1,80 @@
AC_INIT(CDVDnull, 0.6,arcum42@gmail.com)
AM_INIT_AUTOMAKE(CDVDnull,0.6)
AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++])
AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++])
AC_PROG_CPP([gcc g++ cl KCC CC cxx cc++ xlC aCC c++])
AC_PROG_INSTALL
AC_PROG_RANLIB
dnl necessary for compiling assembly
AM_PROG_AS
AC_SUBST(CDVDnull_CURRENT, 0)
AC_SUBST(CDVDnull_REVISION, 8)
AC_SUBST(CDVDnull_AGE, 0)
AC_SUBST(CDVDnull_RELEASE,[$CDVDnull_CURRENT].[$CDVDnull_REVISION].[$CDVDnull_AGE])
AC_SUBST(CDVDnull_SONAME,libCDVDnull.so.[$CDVDnull_CURRENT].[$CDVDnull_REVISION].[$CDVDnull_AGE])
CFLAGS=
CPPFLAGS=
CXXFLAGS=
dnl Check for debug build
AC_MSG_CHECKING(debug build)
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [debug build]),
debug=$enableval,debug=no)
if test "x$debug" == xyes
then
AC_DEFINE(_DEBUG,1,[_DEBUG])
CFLAGS+="-g -fPIC -Wall -Wno-unused-value "
CPPFLAGS+="-g -fPIC -Wall -Wno-unused-value "
CXXFLAGS+="-g -fPIC -Wall -Wno-unused-value "
else
AC_DEFINE(NDEBUG,1,[NDEBUG])
CFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value "
CPPFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value "
CXXFLAGS+="-O3 -fomit-frame-pointer -fPIC -Wall -Wno-unused-value "
fi
AM_CONDITIONAL(DEBUGBUILD, test x$debug = xyes)
AC_MSG_RESULT($debug)
AC_DEFINE(__LINUX__,1,[__LINUX__])
dnl Check for dev build
AC_MSG_CHECKING(for development build...)
AC_ARG_ENABLE(devbuild, AC_HELP_STRING([--enable-devbuild], [Special Build for developers that simplifies testing and adds extra checks]),
devbuild=$enableval,devbuild=no)
if test "x$devbuild" == xyes
then
AC_DEFINE(CDVDnull_DEVBUILD,1,[CDVDnull_DEVBUILD])
fi
AC_MSG_RESULT($devbuild)
AM_CONDITIONAL(RELEASE_TO_PUBLIC, test x$devbuild = xno)
AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC))
dnl gtk
AC_MSG_CHECKING(gtk2+)
AC_CHECK_PROG(GTK_CONFIG, pkg-config, pkg-config)
LIBS+=$(pkg-config --libs gtk+-2.0)
dnl bindir = pcsx2exe
dnl assuming linux environment
so_ext=".so.$CDVDnull_RELEASE"
SHARED_LDFLAGS="-shared"
AC_SUBST(so_ext)
AC_SUBST(SHARED_LDFLAGS)
AC_CHECK_LIB(stdc++,main,[LIBS="$LIBS -lstdc++"])
AC_OUTPUT([
Makefile
])
echo "Configuration:"
echo " Debug build? $debug"
echo " Dev build? $devbuild"

1
plugins/CDVDnull/install-sh Symbolic link
View File

@ -0,0 +1 @@
/usr/share/automake-1.10/install-sh

1
plugins/CDVDnull/missing Symbolic link
View File

@ -0,0 +1 @@
/usr/share/automake-1.10/missing

View File

@ -1,5 +1,5 @@
/* FWnull
* Copyright (C) 2004-2005 PCSX2 Team
* Copyright (C) 2004-2009 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
@ -19,34 +19,39 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <string>
using namespace std;
#include "FW.h"
const unsigned char version = PS2E_FW_VERSION;
const unsigned char revision = 0;
const unsigned char build = 4; // increase that with each version
static char *libraryName = "FWnull Driver";
const unsigned char build = 5; // increase that with each version
static char *libraryName = "FWnull Driver";
s8 *fwregs;
FILE *fwLog;
Config conf;
string s_strIniPath="inis/FWnull.ini";
void (*FWirq)();
#define fwRs32(mem) (*(s32*)&fwregs[(mem) & 0xffff])
#define fwRu32(mem) (*(u32*)&fwregs[(mem) & 0xffff])
u32 CALLBACK PS2EgetLibType() {
EXPORT_C_(u32) PS2EgetLibType()
{
return PS2E_LT_FW;
}
char* CALLBACK PS2EgetLibName() {
EXPORT_C_(char*) PS2EgetLibName()
{
return libraryName;
}
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
EXPORT_C_(u32) PS2EgetLibVersion2(u32 type)
{
return (version<<16) | (revision<<8) | build;
}
void __Log(char *fmt, ...) {
void __Log(char *fmt, ...)
{
va_list list;
if (!conf.Log || fwLog == NULL) return;
@ -56,8 +61,10 @@ void __Log(char *fmt, ...) {
va_end(list);
}
s32 CALLBACK FWinit() {
LoadConfig();
EXPORT_C_(s32) FWinit()
{
LoadConfig();
#ifdef FW_LOG
fwLog = fopen("logs/fwLog.txt", "w");
if (fwLog) setvbuf(fwLog, NULL, _IONBF, 0);
@ -66,14 +73,17 @@ s32 CALLBACK FWinit() {
#endif
fwregs = (s8*)malloc(0x10000);
if (fwregs == NULL) {
SysMessage("Error allocating Memory\n"); return -1;
if (fwregs == NULL)
{
SysMessage("Error allocating Memory\n");
return -1;
}
return 0;
}
void CALLBACK FWshutdown() {
EXPORT_C_(void) FWshutdown()
{
free(fwregs);
#ifdef FW_LOG
@ -81,67 +91,61 @@ void CALLBACK FWshutdown() {
#endif
}
s32 CALLBACK FWopen(void *pDsp) {
EXPORT_C_(s32) FWopen(void *pDsp)
{
#ifdef FW_LOG
FW_LOG("FW open\n");
#endif
#ifdef _WIN32
#else
//Display* dsp = *(Display**)pDsp;
#endif
return 0;
}
void CALLBACK FWclose() {
EXPORT_C_(void) FWclose()
{
}
EXPORT_C_(u32) FWread32(u32 addr)
{
u32 ret = 0;
u32 CALLBACK FWread32(u32 addr) {
u32 ret=0;
switch (addr) {
switch (addr)
{
case 0x1f808410:
ret = 0x8;
break;
default:
ret = fwRu32(addr);
break;
}
#ifdef FW_LOG
FW_LOG("FW read mem 0x%x: 0x%x\n", addr, ret);
#endif
return ret;
}
void CALLBACK FWwrite32(u32 addr, u32 value) {
switch (addr) {
EXPORT_C_(void) FWwrite32(u32 addr, u32 value)
{
switch (addr)
{
default:
fwRu32(addr) = value;
break;
}
#ifdef FW_LOG
FW_LOG("FW write mem 0x%x: 0x%x\n", addr, value);
#endif
}
void CALLBACK FWirqCallback(void (*callback)()) {
EXPORT_C_(void) FWirqCallback(void (*callback)())
{
FWirq = callback;
}
s32 CALLBACK FWfreeze(int mode, freezeData *data) {
EXPORT_C_(s32) FWfreeze(int mode, freezeData *data)
{
return 0;
}
s32 CALLBACK FWtest() {
EXPORT_C_(s32) FWtest()
{
return 0;
}

View File

@ -1,5 +1,5 @@
/* FWnull
* Copyright (C) 2004-2005 PCSX2 Team
/* FWnull
* Copyright (C) 2004-2009 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
@ -15,15 +15,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __FW_H__
#define __FW_H__
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define FWdefs
#include "PS2Edefs.h"
#ifdef __cplusplus
}
#endif
#ifdef _WIN32
@ -35,25 +41,38 @@
#include <gtk/gtk.h>
#include <X11/Xlib.h>
#define __inline inline
#endif
/*#ifdef _MSC_VER
#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK
#else
#define EXPORT_C_(type) extern "C" type
#endif*/
#ifdef _MSC_VER
#define EXPORT_C_(type) extern "C" type CALLBACK
#else
#define EXPORT_C_(type) extern "C" type
#endif
#define FW_LOG __Log
typedef struct {
int Log;
#define fwRs32(mem) (*(s32*)&fwregs[(mem) & 0xffff])
#define fwRu32(mem) (*(u32*)&fwregs[(mem) & 0xffff])
typedef struct
{
int Log;
} Config;
Config conf;
void (*FWirq)();
extern Config conf;
extern FILE *fwLog;
void SaveConfig();
void LoadConfig();
extern void (*FWirq)();
FILE *fwLog;
void __Log(char *fmt, ...);
void SysMessage(char *fmt, ...);
extern void __Log(char *fmt, ...);
extern void SysMessage(char *fmt, ...);
extern void SaveConfig();
extern void LoadConfig();
#endif

View File

@ -1,134 +1,179 @@
/* FireWire
* Copyright (C) 2002-2004 FireWire 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gtk/gtk.h>
#include <signal.h>
#include "interface.h"
#include "support.h"
#include "callbacks.h"
#include "FW.h"
#include "Config.h"
GtkWidget *MsgDlg;
void OnMsg_Ok() {
gtk_widget_destroy(MsgDlg);
gtk_main_quit();
}
void cfgSysMessage(char *fmt, ...) {
GtkWidget *Ok,*Txt;
GtkWidget *Box,*Box1;
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
MsgDlg = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(MsgDlg), "FireWire Msg");
gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5);
Box = gtk_vbox_new(5, 0);
gtk_container_add(GTK_CONTAINER(MsgDlg), Box);
gtk_widget_show(Box);
Txt = gtk_label_new(msg);
gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5);
gtk_widget_show(Txt);
Box1 = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0);
gtk_widget_show(Box1);
Ok = gtk_button_new_with_label("Ok");
gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL);
gtk_container_add(GTK_CONTAINER(Box1), Ok);
GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT);
gtk_widget_show(Ok);
gtk_widget_show(MsgDlg);
gtk_main();
}
GtkWidget *About;
void OnAbout_Ok(GtkButton *button, gpointer user_data) {
gtk_widget_destroy(About);
gtk_main_quit();
}
void CFGabout() {
About = create_About();
gtk_widget_show_all(About);
gtk_main();
}
GtkWidget *Conf;
void OnConf_Ok(GtkButton *button, gpointer user_data) {
SaveConfig();
gtk_widget_destroy(Conf);
gtk_main_quit();
}
void OnConf_Cancel(GtkButton *button, gpointer user_data) {
gtk_widget_destroy(Conf);
gtk_main_quit();
}
void CFGconfigure() {
Conf = create_Config();
LoadConfig();
gtk_widget_show_all(Conf);
gtk_main();
}
long CFGmessage(char *msg) {
cfgSysMessage(msg);
return 0;
}
int main(int argc, char *argv[]) {
gtk_init(NULL, NULL);
if (!strcmp(argv[1], "configure")) {
CFGconfigure();
} else if (!strcmp(argv[1], "about")) {
CFGabout();
} else if (!strcmp(argv[1], "message")) {
CFGmessage(argv[2]);
}
return 0;
}
/* FWnull
* Copyright (C) 2004-2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include <signal.h>
#include <string>
using namespace std;
#include "FW.h"
#include "Config.h"
extern "C"
{
#include "interface.h"
#include "support.h"
//#include "callbacks.h"
}
GtkWidget *MsgDlg, *About, *Conf;
extern string s_strIniPath;
void OnMsg_Ok()
{
gtk_widget_destroy(MsgDlg);
gtk_main_quit();
}
void cfgSysMessage(char *fmt, ...)
{
GtkWidget *Ok,*Txt;
GtkWidget *Box,*Box1;
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg) - 1] == '\n') msg[strlen(msg)-1] = 0;
MsgDlg = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(MsgDlg), "FireWire Msg");
gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5);
Box = gtk_vbox_new(5, 0);
gtk_container_add(GTK_CONTAINER(MsgDlg), Box);
gtk_widget_show(Box);
Txt = gtk_label_new(msg);
gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5);
gtk_widget_show(Txt);
Box1 = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0);
gtk_widget_show(Box1);
Ok = gtk_button_new_with_label("Ok");
gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL);
gtk_container_add(GTK_CONTAINER(Box1), Ok);
GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT);
gtk_widget_show(Ok);
gtk_widget_show(MsgDlg);
gtk_main();
}
void OnAbout_Ok(GtkButton *button, gpointer user_data)
{
gtk_widget_destroy(About);
gtk_main_quit();
}
void CFGabout()
{
About = create_About();
gtk_widget_show_all(About);
gtk_main();
}
void OnConf_Ok(GtkButton *button, gpointer user_data) {
SaveConfig();
gtk_widget_destroy(Conf);
gtk_main_quit();
}
void OnConf_Cancel(GtkButton *button, gpointer user_data)
{
gtk_widget_destroy(Conf);
gtk_main_quit();
}
void CFGconfigure()
{
Conf = create_Config();
LoadConfig();
gtk_widget_show_all(Conf);
gtk_main();
}
long CFGmessage(char *msg) {
cfgSysMessage(msg);
return 0;
}
/*int main(int argc, char *argv[]) {
gtk_init(NULL, NULL);
if (!strcmp(argv[1], "configure")) {
CFGconfigure();
} else if (!strcmp(argv[1], "about")) {
CFGabout();
} else if (!strcmp(argv[1], "message")) {
CFGmessage(argv[2]);
}
return 0;
}*/
void LoadConfig()
{
FILE *f;
char cfg[255];
strcpy(cfg, s_strIniPath.c_str());
f = fopen(cfg, "r");
if (f == NULL)
{
printf("failed to open %s\n", s_strIniPath.c_str());
SaveConfig();//save and return
return;
}
//fscanf(f, "options = %hhx\n", &confOptions);
fclose(f);
}
void SaveConfig()
{
FILE *f;
char cfg[255];
strcpy(cfg, s_strIniPath.c_str());
f = fopen(cfg,"w");
if (f == NULL)
{
printf("failed to open %s\n", s_strIniPath.c_str());
return;
}
//fprintf(f, "options = %hhx\n", confOptions);
fclose(f);
}

View File

@ -1,5 +1,5 @@
/* USBlinuz
* Copyright (C) 2002-2004 USBlinuz Team
/* FWnull
* Copyright (C) 2004-2009 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
@ -18,3 +18,8 @@
void SaveConf();
void LoadConf();
extern long CFGmessage(char *msg);
extern void CFGconfigure();
extern void cfgSysMessage(char *fmt, ...);
extern void CFGabout();

View File

@ -1,98 +0,0 @@
/* FireWire
* Copyright (C) 2002-2004 FireWire 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <unistd.h>
#include "FW.h"
int ExecCfg(char *arg)
{
char cfg[256];
struct stat buf;
strcpy(cfg, "./cfgFWnull");
if (stat(cfg, &buf) != -1)
{
sprintf(cfg, "%s %s", cfg, arg);
return system(cfg);
}
strcpy(cfg, "./plugins/cfgFWnull");
if (stat(cfg, &buf) != -1)
{
sprintf(cfg, "%s %s", cfg, arg);
return system(cfg);
}
strcpy(cfg, "./cfg/cfgFWnull");
if (stat(cfg, &buf) != -1)
{
sprintf(cfg, "%s %s", cfg, arg);
return system(cfg);
}
sprintf(cfg, "%s/cfgFWnull", getenv("HOME"));
if (stat(cfg, &buf) != -1)
{
sprintf(cfg, "%s %s", cfg, arg);
return system(cfg);
}
printf("cfgFWnull file not found!\n");
return -1;
}
void SysMessage(char *fmt, ...)
{
va_list list;
char msg[512];
char cmd[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
sprintf(cmd, "message \"%s\"", msg);
ExecCfg(cmd);
}
void FWconfigure()
{
char *file;
getcwd(file, ArraySize(file));
chdir("plugins");
ExecCfg("configure");
chdir(file);
}
void FWabout()
{
char *file;
getcwd(file, ArraySize(file));
chdir("plugins");
ExecCfg("about");
chdir(file);
}

View File

@ -1,5 +1,5 @@
/* FireWire
* Copyright (C) 2002-2004 USBlinuz Team
/* FWnull
* Copyright (C) 2004-2009 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
@ -17,35 +17,37 @@
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <unistd.h>
#include "FW.h"
#include "Config.h"
void LoadConfig() {
FILE *f;
char cfg[256];
void SysMessage(char *fmt, ...)
{
va_list list;
char msg[512];
char cmd[512];
sprintf(cfg, "%s/.PS2E/FWnull.cfg", getenv("HOME"));
f = fopen(cfg, "r");
if (f == NULL) {
return;
}
fclose(f);
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
cfgSysMessage(msg);
}
void SaveConfig() {
FILE *f;
char cfg[256];
sprintf(cfg, "%s/.PS2E", getenv("HOME"));
mkdir(cfg, 0755);
sprintf(cfg, "%s/.PS2E/FWnull.cfg", getenv("HOME"));
f = fopen(cfg, "w");
if (f == NULL)
return;
fclose(f);
void FWconfigure()
{
CFGconfigure();
}
void FWabout()
{
CFGabout();
}

View File

@ -0,0 +1,17 @@
/* FWnull
* Copyright (C) 2004-2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

View File

@ -1,35 +0,0 @@
PLUGIN = libFWnull.so
CFG = cfgFWnull
CFLAGS+= -fPIC -Wall -I. -I.. -I../../../common/include -O3 -fomit-frame-pointer -fno-strict-aliasing
OBJS = ../FW.o
OBJS+= Linux.o Config.o
CFGOBJS = conf.o interface.o support.o Config.o
DEPS:= $(OBJS:.o=.d)
CFGDEPS:= $(CFGOBJS:.o=.d)
LIBS = -lpthread
CFLAGS+= $(shell pkg-config --cflags gtk+-2.0) -D__LINUX__
CFGLIBS = $(shell pkg-config --libs gtk+-2.0)
CC = gcc
all: plugin cfg
install: all
plugin: ${OBJS}
rm -f ${PLUGIN}
${CC} -shared -Wl,-soname,${PLUGIN} ${CFLAGS} ${OBJS} -o ${PLUGIN} ${LIBS}
strip --strip-unneeded --strip-debug ${PLUGIN}
cfg: ${CFGOBJS}
rm -f ${CFG}
${CC} ${CFLAGS} ${CFGOBJS} -o ${CFG} ${CFGLIBS}
strip ${CFG}
clean:
rm -f ${OBJS} ${DEPS} ${CFGOBJS} ${CFGDEPS} ${PLUGIN} ${CFG}
%.o: %.c
${CC} ${CFLAGS} -c -o $@ $< -MD -MF $(patsubst %.o,%.d,$@)
-include ${DEPS}

View File

@ -1,34 +1,34 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include "callbacks.h"
#include "interface.h"
#include "support.h"
void
OnConf_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnConf_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnAbout_Ok (GtkButton *button,
gpointer user_data)
{
}
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include "callbacks.h"
#include "interface.h"
#include "support.h"
void
OnConf_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnConf_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnAbout_Ok (GtkButton *button,
gpointer user_data)
{
}

View File

@ -1,300 +1,443 @@
<?xml version="1.0"?>
<GTK-Interface>
<project>
<name>FireWire</name>
<program_name>dev9linuz</program_name>
<directory></directory>
<source_directory></source_directory>
<pixmaps_directory>pixmaps</pixmaps_directory>
<language>C</language>
<gnome_support>False</gnome_support>
<gettext_support>False</gettext_support>
<output_main_file>False</output_main_file>
<output_build_files>False</output_build_files>
<backup_source_files>False</backup_source_files>
</project>
<widget>
<class>GtkWindow</class>
<name>Config</name>
<border_width>5</border_width>
<title>DEV9config</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_CENTER</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<widget>
<class>GtkVBox</class>
<name>vbox1</name>
<border_width>5</border_width>
<homogeneous>False</homogeneous>
<spacing>5</spacing>
<widget>
<class>GtkFrame</class>
<name>frame2</name>
<label>Ethernet</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox1</name>
<border_width>5</border_width>
<homogeneous>True</homogeneous>
<spacing>5</spacing>
<widget>
<class>GtkLabel</class>
<name>label4</name>
<label>Device:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkCombo</class>
<name>GtkCombo_Eth</name>
<width>130</width>
<value_in_list>False</value_in_list>
<ok_if_empty>True</ok_if_empty>
<case_sensitive>False</case_sensitive>
<use_arrows>True</use_arrows>
<use_arrows_always>False</use_arrows_always>
<items></items>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>combo-entry1</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>frame3</name>
<label>Hdd</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox2</name>
<border_width>5</border_width>
<homogeneous>True</homogeneous>
<spacing>5</spacing>
<widget>
<class>GtkLabel</class>
<name>label5</name>
<label>Device:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkCombo</class>
<name>GtkCombo_Hdd</name>
<width>130</width>
<value_in_list>False</value_in_list>
<ok_if_empty>True</ok_if_empty>
<case_sensitive>False</case_sensitive>
<use_arrows>True</use_arrows>
<use_arrows_always>False</use_arrows_always>
<items></items>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>entry1</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkHButtonBox</class>
<name>hbuttonbox1</name>
<layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
<spacing>30</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<name>button1</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>OnConf_Ok</handler>
<last_modification_time>Sat, 06 Apr 2002 17:07:56 GMT</last_modification_time>
</signal>
<label>Ok</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>button2</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>OnConf_Cancel</handler>
<last_modification_time>Sat, 06 Apr 2002 17:08:08 GMT</last_modification_time>
</signal>
<label>Cancel</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkWindow</class>
<name>About</name>
<border_width>5</border_width>
<title>DEV9about</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_CENTER</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<widget>
<class>GtkVBox</class>
<name>vbox2</name>
<border_width>5</border_width>
<homogeneous>False</homogeneous>
<spacing>5</spacing>
<widget>
<class>GtkLabel</class>
<name>label2</name>
<label>FireWire Driver</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label3</name>
<label>Author: linuzappz &lt;linuzappz@hotmail.com&gt;</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkHButtonBox</class>
<name>hbuttonbox2</name>
<layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
<spacing>30</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<name>button3</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>OnAbout_Ok</handler>
<last_modification_time>Sun, 07 Apr 2002 03:43:49 GMT</last_modification_time>
</signal>
<label>Ok</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
</widget>
</widget>
</widget>
</GTK-Interface>
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="Config">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="title" translatable="yes">DEV9config</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<child>
<widget class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">5</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">Device:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCombo" id="GtkCombo_Eth">
<property name="visible">True</property>
<property name="value_in_list">False</property>
<property name="allow_empty">True</property>
<property name="case_sensitive">False</property>
<property name="enable_arrow_keys">True</property>
<property name="enable_arrows_always">False</property>
<child internal-child="entry">
<widget class="GtkEntry" id="combo-entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
</child>
<child internal-child="list">
<widget class="GtkList" id="convertwidget1">
<property name="visible">True</property>
<property name="selection_mode">GTK_SELECTION_BROWSE</property>
<child>
<widget class="GtkListItem" id="convertwidget2">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="convertwidget3">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Ethernet</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">5</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">Device:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCombo" id="GtkCombo_Hdd">
<property name="visible">True</property>
<property name="value_in_list">False</property>
<property name="allow_empty">True</property>
<property name="case_sensitive">False</property>
<property name="enable_arrow_keys">True</property>
<property name="enable_arrows_always">False</property>
<child internal-child="entry">
<widget class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
</child>
<child internal-child="list">
<widget class="GtkList" id="convertwidget4">
<property name="visible">True</property>
<property name="selection_mode">GTK_SELECTION_BROWSE</property>
<child>
<widget class="GtkListItem" id="convertwidget5">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="convertwidget6">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="label" translatable="yes">Hdd</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
<property name="spacing">30</property>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Ok</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="OnConf_Ok"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="button2">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Cancel</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="OnConf_Cancel"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkWindow" id="About">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="title" translatable="yes">DEV9about</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">FireWire Driver</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">Author: linuzappz &lt;linuzappz@hotmail.com&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
<property name="spacing">30</property>
<child>
<widget class="GtkButton" id="button3">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Ok</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="OnAbout_Ok"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -10,6 +10,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
@ -18,6 +19,13 @@
#include "interface.h"
#include "support.h"
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
g_object_set_data (G_OBJECT (component), name, widget)
GtkWidget*
create_Config (void)
{
@ -27,131 +35,146 @@ create_Config (void)
GtkWidget *hbox1;
GtkWidget *label4;
GtkWidget *GtkCombo_Eth;
GList *GtkCombo_Eth_items = NULL;
GtkWidget *combo_entry1;
GtkWidget *label1;
GtkWidget *frame3;
GtkWidget *hbox2;
GtkWidget *label5;
GtkWidget *GtkCombo_Hdd;
GList *GtkCombo_Hdd_items = NULL;
GtkWidget *entry1;
GtkWidget *label15;
GtkWidget *hbuttonbox1;
GtkWidget *button1;
GtkWidget *button2;
Config = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_object_set_data (GTK_OBJECT (Config), "Config", Config);
gtk_widget_set_name (Config, "Config");
gtk_container_set_border_width (GTK_CONTAINER (Config), 5);
gtk_window_set_title (GTK_WINDOW (Config), "DEV9config");
gtk_window_set_position (GTK_WINDOW (Config), GTK_WIN_POS_CENTER);
gtk_window_set_title (GTK_WINDOW (Config), _("DEV9config"));
vbox1 = gtk_vbox_new (FALSE, 5);
gtk_widget_ref (vbox1);
gtk_object_set_data_full (GTK_OBJECT (Config), "vbox1", vbox1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (vbox1, "vbox1");
gtk_widget_show (vbox1);
gtk_container_add (GTK_CONTAINER (Config), vbox1);
gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5);
frame2 = gtk_frame_new ("Ethernet");
gtk_widget_ref (frame2);
gtk_object_set_data_full (GTK_OBJECT (Config), "frame2", frame2,
(GtkDestroyNotify) gtk_widget_unref);
frame2 = gtk_frame_new (NULL);
gtk_widget_set_name (frame2, "frame2");
gtk_widget_show (frame2);
gtk_box_pack_start (GTK_BOX (vbox1), frame2, TRUE, TRUE, 0);
hbox1 = gtk_hbox_new (TRUE, 5);
gtk_widget_ref (hbox1);
gtk_object_set_data_full (GTK_OBJECT (Config), "hbox1", hbox1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (hbox1, "hbox1");
gtk_widget_show (hbox1);
gtk_container_add (GTK_CONTAINER (frame2), hbox1);
gtk_container_set_border_width (GTK_CONTAINER (hbox1), 5);
label4 = gtk_label_new ("Device:");
gtk_widget_ref (label4);
gtk_object_set_data_full (GTK_OBJECT (Config), "label4", label4,
(GtkDestroyNotify) gtk_widget_unref);
label4 = gtk_label_new (_("Device:"));
gtk_widget_set_name (label4, "label4");
gtk_widget_show (label4);
gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0);
gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER);
GtkCombo_Eth = gtk_combo_new ();
gtk_widget_ref (GtkCombo_Eth);
gtk_object_set_data_full (GTK_OBJECT (Config), "GtkCombo_Eth", GtkCombo_Eth,
(GtkDestroyNotify) gtk_widget_unref);
g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Eth)->popwin),
"GladeParentKey", GtkCombo_Eth);
gtk_widget_set_name (GtkCombo_Eth, "GtkCombo_Eth");
gtk_widget_show (GtkCombo_Eth);
gtk_box_pack_start (GTK_BOX (hbox1), GtkCombo_Eth, FALSE, FALSE, 0);
gtk_widget_set_usize (GtkCombo_Eth, 130, -2);
GtkCombo_Eth_items = g_list_append (GtkCombo_Eth_items, (gpointer) "");
gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Eth), GtkCombo_Eth_items);
g_list_free (GtkCombo_Eth_items);
combo_entry1 = GTK_COMBO (GtkCombo_Eth)->entry;
gtk_widget_ref (combo_entry1);
gtk_object_set_data_full (GTK_OBJECT (Config), "combo_entry1", combo_entry1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (combo_entry1, "combo_entry1");
gtk_widget_show (combo_entry1);
frame3 = gtk_frame_new ("Hdd");
gtk_widget_ref (frame3);
gtk_object_set_data_full (GTK_OBJECT (Config), "frame3", frame3,
(GtkDestroyNotify) gtk_widget_unref);
label1 = gtk_label_new (_("Ethernet"));
gtk_widget_set_name (label1, "label1");
gtk_widget_show (label1);
gtk_frame_set_label_widget (GTK_FRAME (frame2), label1);
frame3 = gtk_frame_new (NULL);
gtk_widget_set_name (frame3, "frame3");
gtk_widget_show (frame3);
gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0);
hbox2 = gtk_hbox_new (TRUE, 5);
gtk_widget_ref (hbox2);
gtk_object_set_data_full (GTK_OBJECT (Config), "hbox2", hbox2,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (hbox2, "hbox2");
gtk_widget_show (hbox2);
gtk_container_add (GTK_CONTAINER (frame3), hbox2);
gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);
label5 = gtk_label_new ("Device:");
gtk_widget_ref (label5);
gtk_object_set_data_full (GTK_OBJECT (Config), "label5", label5,
(GtkDestroyNotify) gtk_widget_unref);
label5 = gtk_label_new (_("Device:"));
gtk_widget_set_name (label5, "label5");
gtk_widget_show (label5);
gtk_box_pack_start (GTK_BOX (hbox2), label5, FALSE, FALSE, 0);
gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_CENTER);
GtkCombo_Hdd = gtk_combo_new ();
gtk_widget_ref (GtkCombo_Hdd);
gtk_object_set_data_full (GTK_OBJECT (Config), "GtkCombo_Hdd", GtkCombo_Hdd,
(GtkDestroyNotify) gtk_widget_unref);
g_object_set_data (G_OBJECT (GTK_COMBO (GtkCombo_Hdd)->popwin),
"GladeParentKey", GtkCombo_Hdd);
gtk_widget_set_name (GtkCombo_Hdd, "GtkCombo_Hdd");
gtk_widget_show (GtkCombo_Hdd);
gtk_box_pack_start (GTK_BOX (hbox2), GtkCombo_Hdd, FALSE, FALSE, 0);
gtk_widget_set_usize (GtkCombo_Hdd, 130, -2);
GtkCombo_Hdd_items = g_list_append (GtkCombo_Hdd_items, (gpointer) "");
gtk_combo_set_popdown_strings (GTK_COMBO (GtkCombo_Hdd), GtkCombo_Hdd_items);
g_list_free (GtkCombo_Hdd_items);
entry1 = GTK_COMBO (GtkCombo_Hdd)->entry;
gtk_widget_ref (entry1);
gtk_object_set_data_full (GTK_OBJECT (Config), "entry1", entry1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (entry1, "entry1");
gtk_widget_show (entry1);
label15 = gtk_label_new (_("Hdd"));
gtk_widget_set_name (label15, "label15");
gtk_widget_show (label15);
gtk_frame_set_label_widget (GTK_FRAME (frame3), label15);
hbuttonbox1 = gtk_hbutton_box_new ();
gtk_widget_ref (hbuttonbox1);
gtk_object_set_data_full (GTK_OBJECT (Config), "hbuttonbox1", hbuttonbox1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (hbuttonbox1, "hbuttonbox1");
gtk_widget_show (hbuttonbox1);
gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0);
gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30);
button1 = gtk_button_new_with_label ("Ok");
gtk_widget_ref (button1);
gtk_object_set_data_full (GTK_OBJECT (Config), "button1", button1,
(GtkDestroyNotify) gtk_widget_unref);
button1 = gtk_button_new_with_mnemonic (_("Ok"));
gtk_widget_set_name (button1, "button1");
gtk_widget_show (button1);
gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1);
GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
button2 = gtk_button_new_with_label ("Cancel");
gtk_widget_ref (button2);
gtk_object_set_data_full (GTK_OBJECT (Config), "button2", button2,
(GtkDestroyNotify) gtk_widget_unref);
button2 = gtk_button_new_with_mnemonic (_("Cancel"));
gtk_widget_set_name (button2, "button2");
gtk_widget_show (button2);
gtk_container_add (GTK_CONTAINER (hbuttonbox1), button2);
GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button1), "clicked",
GTK_SIGNAL_FUNC (OnConf_Ok),
NULL);
gtk_signal_connect (GTK_OBJECT (button2), "clicked",
GTK_SIGNAL_FUNC (OnConf_Cancel),
NULL);
g_signal_connect ((gpointer) button1, "clicked",
G_CALLBACK (OnConf_Ok),
NULL);
g_signal_connect ((gpointer) button2, "clicked",
G_CALLBACK (OnConf_Cancel),
NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (Config, Config, "Config");
GLADE_HOOKUP_OBJECT (Config, vbox1, "vbox1");
GLADE_HOOKUP_OBJECT (Config, frame2, "frame2");
GLADE_HOOKUP_OBJECT (Config, hbox1, "hbox1");
GLADE_HOOKUP_OBJECT (Config, label4, "label4");
GLADE_HOOKUP_OBJECT (Config, GtkCombo_Eth, "GtkCombo_Eth");
GLADE_HOOKUP_OBJECT (Config, combo_entry1, "combo_entry1");
GLADE_HOOKUP_OBJECT (Config, label1, "label1");
GLADE_HOOKUP_OBJECT (Config, frame3, "frame3");
GLADE_HOOKUP_OBJECT (Config, hbox2, "hbox2");
GLADE_HOOKUP_OBJECT (Config, label5, "label5");
GLADE_HOOKUP_OBJECT (Config, GtkCombo_Hdd, "GtkCombo_Hdd");
GLADE_HOOKUP_OBJECT (Config, entry1, "entry1");
GLADE_HOOKUP_OBJECT (Config, label15, "label15");
GLADE_HOOKUP_OBJECT (Config, hbuttonbox1, "hbuttonbox1");
GLADE_HOOKUP_OBJECT (Config, button1, "button1");
GLADE_HOOKUP_OBJECT (Config, button2, "button2");
return Config;
}
@ -167,52 +190,50 @@ create_About (void)
GtkWidget *button3;
About = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_object_set_data (GTK_OBJECT (About), "About", About);
gtk_widget_set_name (About, "About");
gtk_container_set_border_width (GTK_CONTAINER (About), 5);
gtk_window_set_title (GTK_WINDOW (About), "DEV9about");
gtk_window_set_position (GTK_WINDOW (About), GTK_WIN_POS_CENTER);
gtk_window_set_title (GTK_WINDOW (About), _("DEV9about"));
vbox2 = gtk_vbox_new (FALSE, 5);
gtk_widget_ref (vbox2);
gtk_object_set_data_full (GTK_OBJECT (About), "vbox2", vbox2,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (vbox2, "vbox2");
gtk_widget_show (vbox2);
gtk_container_add (GTK_CONTAINER (About), vbox2);
gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
label2 = gtk_label_new ("DEV9linuz Driver");
gtk_widget_ref (label2);
gtk_object_set_data_full (GTK_OBJECT (About), "label2", label2,
(GtkDestroyNotify) gtk_widget_unref);
label2 = gtk_label_new (_("FireWire Driver"));
gtk_widget_set_name (label2, "label2");
gtk_widget_show (label2);
gtk_box_pack_start (GTK_BOX (vbox2), label2, FALSE, FALSE, 0);
gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER);
label3 = gtk_label_new ("Author: linuzappz <linuzappz@hotmail.com>");
gtk_widget_ref (label3);
gtk_object_set_data_full (GTK_OBJECT (About), "label3", label3,
(GtkDestroyNotify) gtk_widget_unref);
label3 = gtk_label_new (_("Author: linuzappz <linuzappz@hotmail.com>"));
gtk_widget_set_name (label3, "label3");
gtk_widget_show (label3);
gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0);
gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_LEFT);
hbuttonbox2 = gtk_hbutton_box_new ();
gtk_widget_ref (hbuttonbox2);
gtk_object_set_data_full (GTK_OBJECT (About), "hbuttonbox2", hbuttonbox2,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_set_name (hbuttonbox2, "hbuttonbox2");
gtk_widget_show (hbuttonbox2);
gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0);
gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 30);
button3 = gtk_button_new_with_label ("Ok");
gtk_widget_ref (button3);
gtk_object_set_data_full (GTK_OBJECT (About), "button3", button3,
(GtkDestroyNotify) gtk_widget_unref);
button3 = gtk_button_new_with_mnemonic (_("Ok"));
gtk_widget_set_name (button3, "button3");
gtk_widget_show (button3);
gtk_container_add (GTK_CONTAINER (hbuttonbox2), button3);
GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button3), "clicked",
GTK_SIGNAL_FUNC (OnAbout_Ok),
NULL);
g_signal_connect ((gpointer) button3, "clicked",
G_CALLBACK (OnAbout_Ok),
NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (About, About, "About");
GLADE_HOOKUP_OBJECT (About, vbox2, "vbox2");
GLADE_HOOKUP_OBJECT (About, label2, "label2");
GLADE_HOOKUP_OBJECT (About, label3, "label3");
GLADE_HOOKUP_OBJECT (About, hbuttonbox2, "hbuttonbox2");
GLADE_HOOKUP_OBJECT (About, button3, "button3");
return About;
}

View File

@ -10,18 +10,12 @@
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include "support.h"
/* This is an internally used function to check if a pixmap file exists. */
static gchar* check_file_exists (const gchar *directory,
const gchar *filename);
/* This is an internally used function to create pixmaps. */
static GtkWidget* create_dummy_pixmap (GtkWidget *widget);
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
@ -34,47 +28,20 @@ lookup_widget (GtkWidget *widget,
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (!parent)
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
widget_name);
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
/* This is a dummy pixmap we use when a pixmap can't be found. */
static char *dummy_pixmap_xpm[] = {
/* columns rows colors chars-per-pixel */
"1 1 1 1",
" c None",
/* pixels */
" "
};
/* This is an internally used function to create pixmaps. */
static GtkWidget*
create_dummy_pixmap (GtkWidget *widget)
{
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
NULL, dummy_pixmap_xpm);
if (gdkpixmap == NULL)
g_error ("Couldn't create replacement pixmap.");
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
static GList *pixmaps_directories = NULL;
/* Use this function to set the directory containing installed pixmaps. */
@ -85,78 +52,93 @@ add_pixmap_directory (const gchar *directory)
g_strdup (directory));
}
/* This is an internally used function to find pixmap files. */
static gchar*
find_pixmap_file (const gchar *filename)
{
GList *elem;
/* We step through each of the pixmaps directory to find it. */
elem = pixmaps_directories;
while (elem)
{
gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
G_DIR_SEPARATOR_S, filename);
if (g_file_test (pathname, G_FILE_TEST_EXISTS))
return pathname;
g_free (pathname);
elem = elem->next;
}
return NULL;
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename)
{
gchar *found_filename = NULL;
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
gchar *pathname = NULL;
GtkWidget *pixmap;
GList *elem;
if (!filename || !filename[0])
return create_dummy_pixmap (widget);
return gtk_image_new ();
/* We first try any pixmaps directories set by the application. */
elem = pixmaps_directories;
while (elem)
pathname = find_pixmap_file (filename);
if (!pathname)
{
found_filename = check_file_exists ((gchar*)elem->data, filename);
if (found_filename)
break;
elem = elem->next;
g_warning (_("Couldn't find pixmap file: %s"), filename);
return gtk_image_new ();
}
/* If we haven't found the pixmap, try the source directory. */
if (!found_filename)
{
found_filename = check_file_exists ("pixmaps", filename);
}
if (!found_filename)
{
g_warning ("Couldn't find pixmap file: %s", filename);
return create_dummy_pixmap (widget);
}
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
NULL, found_filename);
if (gdkpixmap == NULL)
{
g_warning ("Error loading pixmap file: %s", found_filename);
g_free (found_filename);
return create_dummy_pixmap (widget);
}
g_free (found_filename);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
pixmap = gtk_image_new_from_file (pathname);
g_free (pathname);
return pixmap;
}
/* This is an internally used function to check if a pixmap file exists. */
static gchar*
check_file_exists (const gchar *directory,
const gchar *filename)
/* This is an internally used function to create pixmaps. */
GdkPixbuf*
create_pixbuf (const gchar *filename)
{
gchar *full_filename;
struct stat s;
gint status;
gchar *pathname = NULL;
GdkPixbuf *pixbuf;
GError *error = NULL;
full_filename = (gchar*) g_malloc (strlen (directory) + 1
+ strlen (filename) + 1);
strcpy (full_filename, directory);
strcat (full_filename, G_DIR_SEPARATOR_S);
strcat (full_filename, filename);
if (!filename || !filename[0])
return NULL;
status = stat (full_filename, &s);
if (status == 0 && S_ISREG (s.st_mode))
return full_filename;
g_free (full_filename);
return NULL;
pathname = find_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return NULL;
}
pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
if (!pixbuf)
{
fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
pathname, error->message);
g_error_free (error);
}
g_free (pathname);
return pixbuf;
}
/* This is used to set ATK action descriptions. */
void
glade_set_atk_action_description (AtkAction *action,
const gchar *action_name,
const gchar *description)
{
gint n_actions, i;
n_actions = atk_action_get_n_actions (action);
for (i = 0; i < n_actions; i++)
{
if (!strcmp (atk_action_get_name (action, i), action_name))
atk_action_set_description (action, i, description);
}
}

Some files were not shown because too many files have changed in this diff Show More