diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
| commit | 379a8879f7dae1a9074317c0270e12dd203b32c0 (patch) | |
| tree | 348efb7ecd4f7cbc030f4b5db6683a857f2ae6cf /libpcsxcore/r3000a.h | |
| parent | d34b4220bde29d7937d927e9d17a50470a36c500 (diff) | |
Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/r3000a.h')
| -rw-r--r-- | libpcsxcore/r3000a.h | 795 |
1 files changed, 339 insertions, 456 deletions
diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 2c4e57f5..b34a30f2 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -1,456 +1,339 @@ -/*************************************************************************** - * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX 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 02111-1307 USA. * - ***************************************************************************/ - -#ifndef __R3000A_H__ -#define __R3000A_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "psxcommon.h" -#include "psxmem.h" -#include "psxcounters.h" -#include "psxbios.h" - -typedef struct { - int (*Init)(); - void (*Reset)(); - void (*Execute)(); /* executes up to a break */ - void (*ExecuteBlock)(); /* executes up to a jump */ - void (*Clear)(u32 Addr, u32 Size); - void (*Shutdown)(); -} R3000Acpu; - -extern R3000Acpu *psxCpu; -extern R3000Acpu psxInt; -#if (defined(__x86_64__) || defined(__i386__) || defined(__sh__) || defined(__ppc__)) && !defined(NOPSXREC) -extern R3000Acpu psxRec; -#define PSXREC -#endif - -typedef union { -#if defined(__BIGENDIAN__) - struct { u8 h3, h2, h, l; } b; - struct { s8 h3, h2, h, l; } sb; - struct { u16 h, l; } w; - struct { s16 h, l; } sw; -#else - struct { u8 l, h, h2, h3; } b; - struct { u16 l, h; } w; - struct { s8 l, h, h2, h3; } sb; - struct { s16 l, h; } sw; -#endif -} PAIR; - -typedef union { - struct { - u32 r0, at, v0, v1, a0, a1, a2, a3, - t0, t1, t2, t3, t4, t5, t6, t7, - s0, s1, s2, s3, s4, s5, s6, s7, - t8, t9, k0, k1, gp, sp, s8, ra, lo, hi; - } n; - u32 r[34]; /* Lo, Hi in r[32] and r[33] */ - PAIR p[34]; -} psxGPRRegs; - -typedef union { - struct { - u32 Index, Random, EntryLo0, BPC, - Context, BDA, PIDMask, DCIC, - BadVAddr, BDAM, EntryHi, BPCM, - Status, Cause, EPC, PRid, - Config, LLAddr, WatchLO, WatchHI, - XContext, Reserved1, Reserved2, Reserved3, - Reserved4, Reserved5, ECC, CacheErr, - TagLo, TagHi, ErrorEPC, Reserved6; - } n; - u32 r[32]; -} psxCP0Regs; - -typedef struct { - short x, y; -} SVector2D; - -typedef struct { - short z, pad; -} SVector2Dz; - -typedef struct { - short x, y, z, pad; -} SVector3D; - -typedef struct { - short x, y, z, pad; -} LVector3D; - -typedef struct { - unsigned char r, g, b, c; -} CBGR; - -typedef struct { - short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad; -} SMatrix3D; - -typedef union { - struct { - SVector3D v0, v1, v2; - CBGR rgb; - s32 otz; - s32 ir0, ir1, ir2, ir3; - SVector2D sxy0, sxy1, sxy2, sxyp; - SVector2Dz sz0, sz1, sz2, sz3; - CBGR rgb0, rgb1, rgb2; - s32 reserved; - s32 mac0, mac1, mac2, mac3; - u32 irgb, orgb; - s32 lzcs, lzcr; - } n; - u32 r[32]; - PAIR p[32]; -} psxCP2Data; - -typedef union { - struct { - SMatrix3D rMatrix; - s32 trX, trY, trZ; - SMatrix3D lMatrix; - s32 rbk, gbk, bbk; - SMatrix3D cMatrix; - s32 rfc, gfc, bfc; - s32 ofx, ofy; - s32 h; - s32 dqa, dqb; - s32 zsf3, zsf4; - s32 flag; - } n; - u32 r[32]; - PAIR p[32]; -} psxCP2Ctrl; - -enum { - PSXINT_SIO = 0, - PSXINT_CDR, - PSXINT_CDREAD, - PSXINT_GPUDMA, - PSXINT_MDECOUTDMA, - PSXINT_SPUDMA, - PSXINT_GPUBUSY, - PSXINT_MDECINDMA, - PSXINT_GPUOTCDMA, - PSXINT_CDRDMA, - PSXINT_SPUASYNC, - PSXINT_CDRDBUF, - PSXINT_CDRLID, - PSXINT_CDRPLAY -}; - -typedef struct { - psxGPRRegs GPR; /* General Purpose Registers */ - psxCP0Regs CP0; /* Coprocessor0 Registers */ - psxCP2Data CP2D; /* Cop2 data registers */ - psxCP2Ctrl CP2C; /* Cop2 control registers */ - u32 pc; /* Program counter */ - u32 code; /* The instruction */ - u32 cycle; - u32 interrupt; - struct { u32 sCycle, cycle; } intCycle[32]; - u8 ICache_Addr[0x1000]; - u8 ICache_Code[0x1000]; - boolean ICache_valid; -} psxRegisters; - -extern psxRegisters psxRegs; - -/* -Formula One 2001 -- Use old CPU cache code when the RAM location is - updated with new code (affects in-game racing) - -TODO: -- I-cache / D-cache swapping -- Isolate D-cache from RAM -*/ - -static inline u32 *Read_ICache(u32 pc, boolean isolate) { - u32 pc_bank, pc_offset, pc_cache; - u8 *IAddr, *ICode; - - pc_bank = pc >> 24; - pc_offset = pc & 0xffffff; - pc_cache = pc & 0xfff; - - IAddr = psxRegs.ICache_Addr; - ICode = psxRegs.ICache_Code; - - // clear I-cache - if (!psxRegs.ICache_valid) { - memset(psxRegs.ICache_Addr, 0xff, sizeof(psxRegs.ICache_Addr)); - memset(psxRegs.ICache_Code, 0xff, sizeof(psxRegs.ICache_Code)); - - psxRegs.ICache_valid = TRUE; - } - - // uncached - if (pc_bank >= 0xa0) - return (u32 *)PSXM(pc); - - // cached - RAM - if (pc_bank == 0x80 || pc_bank == 0x00) { - if (SWAP32(*(u32 *)(IAddr + pc_cache)) == pc_offset) { - // Cache hit - return last opcode used - return (u32 *)(ICode + pc_cache); - } else { - // Cache miss - addresses don't match - // - default: 0xffffffff (not init) - - if (!isolate) { - // cache line is 4 bytes wide - pc_offset &= ~0xf; - pc_cache &= ~0xf; - - // address line - *(u32 *)(IAddr + pc_cache + 0x0) = SWAP32(pc_offset + 0x0); - *(u32 *)(IAddr + pc_cache + 0x4) = SWAP32(pc_offset + 0x4); - *(u32 *)(IAddr + pc_cache + 0x8) = SWAP32(pc_offset + 0x8); - *(u32 *)(IAddr + pc_cache + 0xc) = SWAP32(pc_offset + 0xc); - - // opcode line - pc_offset = pc & ~0xf; - *(u32 *)(ICode + pc_cache + 0x0) = psxMu32ref(pc_offset + 0x0); - *(u32 *)(ICode + pc_cache + 0x4) = psxMu32ref(pc_offset + 0x4); - *(u32 *)(ICode + pc_cache + 0x8) = psxMu32ref(pc_offset + 0x8); - *(u32 *)(ICode + pc_cache + 0xc) = psxMu32ref(pc_offset + 0xc); - } - - // normal code - return (u32 *)PSXM(pc); - } - } - - /* - TODO: Probably should add cached BIOS - */ - - // default - return (u32 *)PSXM(pc); -} - -#if defined(__BIGENDIAN__) - -#define _i32(x) *(s32 *)&x -#define _u32(x) x - -#define _i16(x) (((short *)&x)[1]) -#define _u16(x) (((unsigned short *)&x)[1]) - -#define _i8(x) (((char *)&x)[3]) -#define _u8(x) (((unsigned char *)&x)[3]) - -#else - -#define _i32(x) *(s32 *)&x -#define _u32(x) x - -#define _i16(x) *(short *)&x -#define _u16(x) *(unsigned short *)&x - -#define _i8(x) *(char *)&x -#define _u8(x) *(unsigned char *)&x - -#endif - -/**** R3000A Instruction Macros ****/ -#define _PC_ psxRegs.pc // The next PC to be executed - -#define _fOp_(code) ((code >> 26) ) // The opcode part of the instruction register -#define _fFunct_(code) ((code ) & 0x3F) // The funct part of the instruction register -#define _fRd_(code) ((code >> 11) & 0x1F) // The rd part of the instruction register -#define _fRt_(code) ((code >> 16) & 0x1F) // The rt part of the instruction register -#define _fRs_(code) ((code >> 21) & 0x1F) // The rs part of the instruction register -#define _fSa_(code) ((code >> 6) & 0x1F) // The sa part of the instruction register -#define _fIm_(code) ((u16)code) // The immediate part of the instruction register -#define _fTarget_(code) (code & 0x03ffffff) // The target part of the instruction register - -#define _fImm_(code) ((s16)code) // sign-extended immediate -#define _fImmU_(code) (code&0xffff) // zero-extended immediate - -#define _Op_ _fOp_(psxRegs.code) -#define _Funct_ _fFunct_(psxRegs.code) -#define _Rd_ _fRd_(psxRegs.code) -#define _Rt_ _fRt_(psxRegs.code) -#define _Rs_ _fRs_(psxRegs.code) -#define _Sa_ _fSa_(psxRegs.code) -#define _Im_ _fIm_(psxRegs.code) -#define _Target_ _fTarget_(psxRegs.code) - -#define _Imm_ _fImm_(psxRegs.code) -#define _ImmU_ _fImmU_(psxRegs.code) - -#define _rRs_ psxRegs.GPR.r[_Rs_] // Rs register -#define _rRt_ psxRegs.GPR.r[_Rt_] // Rt register -#define _rRd_ psxRegs.GPR.r[_Rd_] // Rd register -#define _rSa_ psxRegs.GPR.r[_Sa_] // Sa register -#define _rFs_ psxRegs.CP0.r[_Rd_] // Fs register - -#define _c2dRs_ psxRegs.CP2D.r[_Rs_] // Rs cop2 data register -#define _c2dRt_ psxRegs.CP2D.r[_Rt_] // Rt cop2 data register -#define _c2dRd_ psxRegs.CP2D.r[_Rd_] // Rd cop2 data register -#define _c2dSa_ psxRegs.CP2D.r[_Sa_] // Sa cop2 data register - -#define _rHi_ psxRegs.GPR.n.hi // The HI register -#define _rLo_ psxRegs.GPR.n.lo // The LO register - -#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction -#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction - -#define _SetLink(x) psxRegs.GPR.r[x] = _PC_ + 4; // Sets the return address in the link register - -int psxInit(); -void psxReset(); -void psxShutdown(); -void psxException(u32 code, u32 bd); -void psxBranchTest(); -void psxExecuteBios(); -int psxTestLoadDelay(int reg, u32 tmp); -void psxDelayTest(int reg, u32 bpc); -void psxTestSWInts(); -void psxJumpTest(); - -/* psxinterpreter for rec fallbacks */ -void psxNULL(void); -void psxSPECIAL(void); -void psxREGIMM(void); -void psxJ(void); -void psxJAL(void); -void psxBEQ(void); -void psxBNE(void); -void psxBLEZ(void); -void psxBGTZ(void); -void psxADDI(void); -void psxADDIU(void); -void psxSLTI(void); -void psxSLTIU(void); -void psxANDI(void); -void psxORI(void); -void psxXORI(void); -void psxLUI(void); -void psxCOP0(void); -void psxCOP2(void); -void psxLB(void); -void psxLH(void); -void psxLWL(void); -void psxLW(void); -void psxLBU(void); -void psxLHU(void); -void psxLWR(void); -void psxSB(void); -void psxSH(void); -void psxSWL(void); -void psxSW(void); -void psxSWR(void); -void psxNULL(void); -void gteLWC2(void); -void psxNULL(void); -void gteSWC2(void); -void psxHLE(void); -void psxSLL(void); -void psxSRL(void); -void psxSRA(void); -void psxSLLV(void); -void psxSRLV(void); -void psxSRAV(void); -void psxJR(void); -void psxJALR(void); -void psxSYSCALL(void); -void psxBREAK(void); -void psxMFHI(void); -void psxMTHI(void); -void psxMFLO(void); -void psxMTLO(void); -void psxMULT(void); -void psxMULTU(void); -void psxDIV(void); -void psxDIVU(void); -void psxADD(void); -void psxADDU(void); -void psxSUB(void); -void psxSUBU(void); -void psxAND(void); -void psxOR(void); -void psxXOR(void); -void psxNOR(void); -void psxNULL(void); -void psxSLT(void); -void psxSLTU(void); -void psxBLTZ(void); -void psxBGEZ(void); -void psxBLTZAL(void); -void psxBGEZAL(void); -void psxMFC0(void); -void psxCFC0(void); -void psxMTC0(void); -void psxCTC0(void); -void psxRFE(void); -void psxBASIC(void); -void gteRTPS(void); -void gteNCLIP(void); -void psxNULL(void); -void gteOP(void); -void gteDPCS(void); -void gteINTPL(void); -void gteMVMVA(void); -void gteNCDS(void); -void gteCDP(void); -void gteNCDT(void); -void psxNULL(void); -void gteNCCS(void); -void gteCC(void); -void gteNCS(void); -void gteNCT(void); -void gteSQR(void); -void gteDCPL(void); -void gteDPCT(void); -void gteAVSZ3(void); -void gteAVSZ4(void); -void gteRTPT(void); -void psxNULL(void); -void gteGPF(void); -void gteGPL(void); -void gteNCCT(void); -void psxMFC2(void); -void psxCFC2(void); -void gteMTC2(void); -void gteCTC2(void); -extern void (*psxBSC[])(); - -/* for table-based unaligned access implementations */ -extern u32 LWL_MASK[4]; -extern u32 LWL_SHIFT[4]; -extern u32 LWR_MASK[4]; -extern u32 LWR_SHIFT[4]; -extern u32 SWL_MASK[4]; -extern u32 SWL_SHIFT[4]; -extern u32 SWR_MASK[4]; -extern u32 SWR_SHIFT[4]; - -#ifdef __cplusplus -} -#endif -#endif +/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX 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 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __R3000A_H__
+#define __R3000A_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "psxcommon.h"
+#include "psxmem.h"
+#include "psxcounters.h"
+#include "psxbios.h"
+
+typedef struct {
+ int (*Init)();
+ void (*Reset)();
+ void (*Execute)(); /* executes up to a break */
+ void (*ExecuteBlock)(); /* executes up to a jump */
+ void (*Clear)(u32 Addr, u32 Size);
+ void (*Shutdown)();
+} R3000Acpu;
+
+extern R3000Acpu *psxCpu;
+extern R3000Acpu psxInt;
+#if (defined(__x86_64__) || defined(__i386__) || defined(__sh__) || defined(__ppc__)) && !defined(NOPSXREC)
+extern R3000Acpu psxRec;
+#define PSXREC
+#endif
+
+typedef union {
+#if defined(__BIGENDIAN__)
+ struct { u8 h3, h2, h, l; } b;
+ struct { s8 h3, h2, h, l; } sb;
+ struct { u16 h, l; } w;
+ struct { s16 h, l; } sw;
+#else
+ struct { u8 l, h, h2, h3; } b;
+ struct { u16 l, h; } w;
+ struct { s8 l, h, h2, h3; } sb;
+ struct { s16 l, h; } sw;
+#endif
+} PAIR;
+
+typedef union {
+ struct {
+ u32 r0, at, v0, v1, a0, a1, a2, a3,
+ t0, t1, t2, t3, t4, t5, t6, t7,
+ s0, s1, s2, s3, s4, s5, s6, s7,
+ t8, t9, k0, k1, gp, sp, s8, ra, lo, hi;
+ } n;
+ u32 r[34]; /* Lo, Hi in r[32] and r[33] */
+ PAIR p[34];
+} psxGPRRegs;
+
+typedef union {
+ struct {
+ u32 Index, Random, EntryLo0, BPC,
+ Context, BDA, PIDMask, DCIC,
+ BadVAddr, BDAM, EntryHi, BPCM,
+ Status, Cause, EPC, PRid,
+ Config, LLAddr, WatchLO, WatchHI,
+ XContext, Reserved1, Reserved2, Reserved3,
+ Reserved4, Reserved5, ECC, CacheErr,
+ TagLo, TagHi, ErrorEPC, Reserved6;
+ } n;
+ u32 r[32];
+} psxCP0Regs;
+
+typedef struct {
+ short x, y;
+} SVector2D;
+
+typedef struct {
+ short z, pad;
+} SVector2Dz;
+
+typedef struct {
+ short x, y, z, pad;
+} SVector3D;
+
+typedef struct {
+ short x, y, z, pad;
+} LVector3D;
+
+typedef struct {
+ unsigned char r, g, b, c;
+} CBGR;
+
+typedef struct {
+ short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
+} SMatrix3D;
+
+typedef union {
+ struct {
+ SVector3D v0, v1, v2;
+ CBGR rgb;
+ s32 otz;
+ s32 ir0, ir1, ir2, ir3;
+ SVector2D sxy0, sxy1, sxy2, sxyp;
+ SVector2Dz sz0, sz1, sz2, sz3;
+ CBGR rgb0, rgb1, rgb2;
+ s32 reserved;
+ s32 mac0, mac1, mac2, mac3;
+ u32 irgb, orgb;
+ s32 lzcs, lzcr;
+ } n;
+ u32 r[32];
+ PAIR p[32];
+} psxCP2Data;
+
+typedef union {
+ struct {
+ SMatrix3D rMatrix;
+ s32 trX, trY, trZ;
+ SMatrix3D lMatrix;
+ s32 rbk, gbk, bbk;
+ SMatrix3D cMatrix;
+ s32 rfc, gfc, bfc;
+ s32 ofx, ofy;
+ s32 h;
+ s32 dqa, dqb;
+ s32 zsf3, zsf4;
+ s32 flag;
+ } n;
+ u32 r[32];
+ PAIR p[32];
+} psxCP2Ctrl;
+
+enum {
+ PSXINT_SIO = 0,
+ PSXINT_CDR,
+ PSXINT_CDREAD,
+ PSXINT_GPUDMA,
+ PSXINT_MDECOUTDMA,
+ PSXINT_SPUDMA,
+ PSXINT_GPUBUSY,
+ PSXINT_MDECINDMA,
+ PSXINT_GPUOTCDMA,
+ PSXINT_CDRDMA,
+ PSXINT_SPUASYNC,
+ PSXINT_CDRDBUF,
+ PSXINT_CDRLID,
+ PSXINT_CDRPLAY
+};
+
+typedef struct {
+ psxGPRRegs GPR; /* General Purpose Registers */
+ psxCP0Regs CP0; /* Coprocessor0 Registers */
+ psxCP2Data CP2D; /* Cop2 data registers */
+ psxCP2Ctrl CP2C; /* Cop2 control registers */
+ u32 pc; /* Program counter */
+ u32 code; /* The instruction */
+ u32 cycle;
+ u32 interrupt;
+ struct { u32 sCycle, cycle; } intCycle[32];
+ u8 ICache_Addr[0x1000];
+ u8 ICache_Code[0x1000];
+ boolean ICache_valid;
+} psxRegisters;
+
+extern psxRegisters psxRegs;
+
+/*
+Formula One 2001
+- Use old CPU cache code when the RAM location is
+ updated with new code (affects in-game racing)
+
+TODO:
+- I-cache / D-cache swapping
+- Isolate D-cache from RAM
+*/
+
+static inline u32 *Read_ICache(u32 pc, boolean isolate) {
+ u32 pc_bank, pc_offset, pc_cache;
+ u8 *IAddr, *ICode;
+
+ pc_bank = pc >> 24;
+ pc_offset = pc & 0xffffff;
+ pc_cache = pc & 0xfff;
+
+ IAddr = psxRegs.ICache_Addr;
+ ICode = psxRegs.ICache_Code;
+
+ // clear I-cache
+ if (!psxRegs.ICache_valid) {
+ memset(psxRegs.ICache_Addr, 0xff, sizeof(psxRegs.ICache_Addr));
+ memset(psxRegs.ICache_Code, 0xff, sizeof(psxRegs.ICache_Code));
+
+ psxRegs.ICache_valid = TRUE;
+ }
+
+ // uncached
+ if (pc_bank >= 0xa0)
+ return (u32 *)PSXM(pc);
+
+ // cached - RAM
+ if (pc_bank == 0x80 || pc_bank == 0x00) {
+ if (SWAP32(*(u32 *)(IAddr + pc_cache)) == pc_offset) {
+ // Cache hit - return last opcode used
+ return (u32 *)(ICode + pc_cache);
+ } else {
+ // Cache miss - addresses don't match
+ // - default: 0xffffffff (not init)
+
+ if (!isolate) {
+ // cache line is 4 bytes wide
+ pc_offset &= ~0xf;
+ pc_cache &= ~0xf;
+
+ // address line
+ *(u32 *)(IAddr + pc_cache + 0x0) = SWAP32(pc_offset + 0x0);
+ *(u32 *)(IAddr + pc_cache + 0x4) = SWAP32(pc_offset + 0x4);
+ *(u32 *)(IAddr + pc_cache + 0x8) = SWAP32(pc_offset + 0x8);
+ *(u32 *)(IAddr + pc_cache + 0xc) = SWAP32(pc_offset + 0xc);
+
+ // opcode line
+ pc_offset = pc & ~0xf;
+ *(u32 *)(ICode + pc_cache + 0x0) = psxMu32ref(pc_offset + 0x0);
+ *(u32 *)(ICode + pc_cache + 0x4) = psxMu32ref(pc_offset + 0x4);
+ *(u32 *)(ICode + pc_cache + 0x8) = psxMu32ref(pc_offset + 0x8);
+ *(u32 *)(ICode + pc_cache + 0xc) = psxMu32ref(pc_offset + 0xc);
+ }
+
+ // normal code
+ return (u32 *)PSXM(pc);
+ }
+ }
+
+ /*
+ TODO: Probably should add cached BIOS
+ */
+
+ // default
+ return (u32 *)PSXM(pc);
+}
+
+#if defined(__BIGENDIAN__)
+
+#define _i32(x) *(s32 *)&x
+#define _u32(x) x
+
+#define _i16(x) (((short *)&x)[1])
+#define _u16(x) (((unsigned short *)&x)[1])
+
+#define _i8(x) (((char *)&x)[3])
+#define _u8(x) (((unsigned char *)&x)[3])
+
+#else
+
+#define _i32(x) *(s32 *)&x
+#define _u32(x) x
+
+#define _i16(x) *(short *)&x
+#define _u16(x) *(unsigned short *)&x
+
+#define _i8(x) *(char *)&x
+#define _u8(x) *(unsigned char *)&x
+
+#endif
+
+/**** R3000A Instruction Macros ****/
+#define _PC_ psxRegs.pc // The next PC to be executed
+
+#define _fOp_(code) ((code >> 26) ) // The opcode part of the instruction register
+#define _fFunct_(code) ((code ) & 0x3F) // The funct part of the instruction register
+#define _fRd_(code) ((code >> 11) & 0x1F) // The rd part of the instruction register
+#define _fRt_(code) ((code >> 16) & 0x1F) // The rt part of the instruction register
+#define _fRs_(code) ((code >> 21) & 0x1F) // The rs part of the instruction register
+#define _fSa_(code) ((code >> 6) & 0x1F) // The sa part of the instruction register
+#define _fIm_(code) ((u16)code) // The immediate part of the instruction register
+#define _fTarget_(code) (code & 0x03ffffff) // The target part of the instruction register
+
+#define _fImm_(code) ((s16)code) // sign-extended immediate
+#define _fImmU_(code) (code&0xffff) // zero-extended immediate
+
+#define _Op_ _fOp_(psxRegs.code)
+#define _Funct_ _fFunct_(psxRegs.code)
+#define _Rd_ _fRd_(psxRegs.code)
+#define _Rt_ _fRt_(psxRegs.code)
+#define _Rs_ _fRs_(psxRegs.code)
+#define _Sa_ _fSa_(psxRegs.code)
+#define _Im_ _fIm_(psxRegs.code)
+#define _Target_ _fTarget_(psxRegs.code)
+
+#define _Imm_ _fImm_(psxRegs.code)
+#define _ImmU_ _fImmU_(psxRegs.code)
+
+#define _rRs_ psxRegs.GPR.r[_Rs_] // Rs register
+#define _rRt_ psxRegs.GPR.r[_Rt_] // Rt register
+#define _rRd_ psxRegs.GPR.r[_Rd_] // Rd register
+#define _rSa_ psxRegs.GPR.r[_Sa_] // Sa register
+#define _rFs_ psxRegs.CP0.r[_Rd_] // Fs register
+
+#define _c2dRs_ psxRegs.CP2D.r[_Rs_] // Rs cop2 data register
+#define _c2dRt_ psxRegs.CP2D.r[_Rt_] // Rt cop2 data register
+#define _c2dRd_ psxRegs.CP2D.r[_Rd_] // Rd cop2 data register
+#define _c2dSa_ psxRegs.CP2D.r[_Sa_] // Sa cop2 data register
+
+#define _rHi_ psxRegs.GPR.n.hi // The HI register
+#define _rLo_ psxRegs.GPR.n.lo // The LO register
+
+#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction
+#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction
+
+#define _SetLink(x) psxRegs.GPR.r[x] = _PC_ + 4; // Sets the return address in the link register
+
+int psxInit();
+void psxReset();
+void psxShutdown();
+void psxException(u32 code, u32 bd);
+void psxBranchTest();
+void psxExecuteBios();
+int psxTestLoadDelay(int reg, u32 tmp);
+void psxDelayTest(int reg, u32 bpc);
+void psxTestSWInts();
+void psxJumpTest();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
|
