mirror of https://github.com/PCSX2/pcsx2.git
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:
commit
0238815248
6
build.sh
6
build.sh
|
@ -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"
|
||||
|
|
|
@ -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) || \
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
1311
pcsx2/CDVD.cpp
1311
pcsx2/CDVD.cpp
File diff suppressed because it is too large
Load Diff
267
pcsx2/CDVD.h
267
pcsx2/CDVD.h
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Console
|
|||
if( FrameHandle != NULL )
|
||||
FrameHandle->Write( fmt );
|
||||
|
||||
fwrite( fmt, 1, strlen( fmt ), emuLog );
|
||||
fputs( fmt, emuLog );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ */
|
41
pcsx2/GS.cpp
41
pcsx2/GS.cpp
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -331,7 +331,6 @@ void mfifoGIFtransfer(int qwc);
|
|||
int _GIFchain();
|
||||
void gifMFIFOInterrupt();
|
||||
|
||||
extern u32 g_vu1SkipCount;
|
||||
extern u32 CSRw;
|
||||
extern u64 m_iSlowStart;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
143
pcsx2/IopHw.cpp
143
pcsx2/IopHw.cpp
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
154
pcsx2/IopMem.cpp
154
pcsx2/IopMem.cpp
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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." );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef __PATCH_H__
|
||||
#define __PATCH_H__
|
||||
|
||||
#include "PS2Etypes.h"
|
||||
#include "Pcsx2Defs.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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])();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <errno.h> // EBUSY
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "PS2Etypes.h"
|
||||
#include "Pcsx2Defs.h"
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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." );
|
||||
|
|
142
pcsx2/VifDma.cpp
142
pcsx2/VifDma.cpp
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
} };
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {}
|
||||
};
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
namespace x86Emitter
|
||||
{
|
||||
extern void xStoreReg( const xRegisterSSE& src );
|
||||
extern void xRestoreReg( const xRegisterSSE& dest );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Group 1 Instruction Class
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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); }
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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()
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef __CDVD_H__
|
||||
#define __CDVD_H__
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define CDVDdefs
|
||||
#include "PS2Edefs.h"
|
||||
|
||||
#endif /* __CDVD_H__ */
|
|
@ -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}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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"
|
|
@ -0,0 +1 @@
|
|||
/usr/share/automake-1.10/install-sh
|
|
@ -0,0 +1 @@
|
|||
/usr/share/automake-1.10/missing
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
*/
|
|
@ -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}
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <linuzappz@hotmail.com></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 <linuzappz@hotmail.com></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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue