cdrom: change pause timing again
[pcsx_rearmed.git] / libpcsxcore / r3000a.h
index 76f42bc..03aeee1 100644 (file)
@@ -25,28 +25,49 @@ extern "C" {
 #endif
 
 #include "psxcommon.h"
 #endif
 
 #include "psxcommon.h"
-#include "psxmem.h"
-#include "psxcounters.h"
-#include "psxbios.h"
+
+enum R3000Aexception {
+       R3000E_Int = 0,      // Interrupt
+       R3000E_AdEL = 4,     // Address error (on load/I-fetch)
+       R3000E_AdES = 5,     // Address error (on store)
+       R3000E_IBE = 6,      // Bus error (instruction fetch)
+       R3000E_DBE = 7,      // Bus error (data load/store)
+       R3000E_Syscall = 8,  // syscall instruction
+       R3000E_Bp = 9,       // Breakpoint - a break instruction
+       R3000E_RI = 10,      // reserved instruction
+       R3000E_CpU = 11,     // Co-Processor unusable
+       R3000E_Ov = 12       // arithmetic overflow
+};
+
+enum R3000Anote {
+       R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
+       R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
+       R3000ACPU_NOTIFY_BEFORE_SAVE,  // data arg - hle if non-null
+       R3000ACPU_NOTIFY_AFTER_LOAD,
+};
+
+enum blockExecCaller {
+       EXEC_CALLER_BOOT,
+       EXEC_CALLER_HLE,
+};
 
 typedef struct {
        int  (*Init)();
        void (*Reset)();
 
 typedef struct {
        int  (*Init)();
        void (*Reset)();
-       void (*Execute)();              /* executes up to a break */
-       void (*ExecuteBlock)(); /* executes up to a jump */
+       void (*Execute)();
+       void (*ExecuteBlock)(enum blockExecCaller caller); /* executes up to a jump */
        void (*Clear)(u32 Addr, u32 Size);
        void (*Clear)(u32 Addr, u32 Size);
+       void (*Notify)(enum R3000Anote note, void *data);
+       void (*ApplyConfig)();
        void (*Shutdown)();
 } R3000Acpu;
 
 extern R3000Acpu *psxCpu;
 extern R3000Acpu psxInt;
        void (*Shutdown)();
 } R3000Acpu;
 
 extern R3000Acpu *psxCpu;
 extern R3000Acpu psxInt;
-#if (defined(__x86_64__) || defined(__i386__) || defined(__sh__) || defined(__ppc__) || defined(__arm__)) && !defined(NOPSXREC)
 extern R3000Acpu psxRec;
 extern R3000Acpu psxRec;
-#define PSXREC
-#endif
 
 typedef union {
 
 typedef union {
-#if defined(__BIGENDIAN__)
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
        struct { u8 h3, h2, h, l; } b;
        struct { s8 h3, h2, h, l; } sb;
        struct { u16 h, l; } w;
        struct { u8 h3, h2, h, l; } b;
        struct { s8 h3, h2, h, l; } sb;
        struct { u16 h, l; } w;
@@ -64,22 +85,19 @@ typedef union {
                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,
                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;
+                                               t8, t9, k0, k1, gp, sp, fp, ra, lo, hi;
        } n;
        u32 r[34]; /* Lo, Hi in r[32] and r[33] */
        PAIR p[34];
 } psxGPRRegs;
 
        } n;
        u32 r[34]; /* Lo, Hi in r[32] and r[33] */
        PAIR p[34];
 } psxGPRRegs;
 
-typedef union {
+typedef union psxCP0Regs_ {
        struct {
        struct {
-               u32     Index,     Random,    EntryLo0,  EntryLo1,
-                                               Context,   PageMask,  Wired,     Reserved0,
-                                               BadVAddr,  Count,     EntryHi,   Compare,
-                                               Status,    Cause,     EPC,       PRid,
-                                               Config,    LLAddr,    WatchLO,   WatchHI,
-                                               XContext,  Reserved1, Reserved2, Reserved3,
-                                               Reserved4, Reserved5, ECC,       CacheErr,
-                                               TagLo,     TagHi,     ErrorEPC,  Reserved6;
+               u32 Reserved0, Reserved1, Reserved2,  BPC,
+                   Reserved4, BDA,       Target,     DCIC,
+                   BadVAddr,  BDAM,      Reserved10, BPCM,
+                   SR,        Cause,     EPC,        PRid,
+                   Reserved16[16];
        } n;
        u32 r[32];
        PAIR p[32];
        } n;
        u32 r[32];
        PAIR p[32];
@@ -145,138 +163,69 @@ typedef union {
        PAIR p[32];
 } psxCP2Ctrl;
 
        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_NEWDRC_CHECK,
-       PSXINT_RCNT,
-       PSXINT_CDRLID,
-       PSXINT_CDRPLAY,
-       PSXINT_COUNT
+enum R3000Abdt {
+       // corresponds to bits 31,30 of Cause reg
+       R3000A_BRANCH_TAKEN = 3,
+       R3000A_BRANCH_NOT_TAKEN = 2,
+       // none or tells that there was an exception in DS back to doBranch
+       R3000A_BRANCH_NONE_OR_EXCEPTION = 0,
 };
 
 };
 
+typedef struct psxCP2Regs {
+       psxCP2Data CP2D;        /* Cop2 data registers */
+       psxCP2Ctrl CP2C;        /* Cop2 control registers */
+} psxCP2Regs;
+
 typedef struct {
 typedef struct {
+       // note: some cores like lightrec don't keep their data here,
+       // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
        psxGPRRegs GPR;         /* General Purpose Registers */
        psxCP0Regs CP0;         /* Coprocessor0 Registers */
        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 */
+       union {
+               struct {
+                       psxCP2Data CP2D;        /* Cop2 data registers */
+                       psxCP2Ctrl CP2C;        /* Cop2 control registers */
+               };
+               psxCP2Regs CP2;
+       };
+       u32 pc;                         /* Program counter */
+       u32 code;                       /* The instruction */
        u32 cycle;
        u32 interrupt;
        struct { u32 sCycle, cycle; } intCycle[32];
        u32 cycle;
        u32 interrupt;
        struct { u32 sCycle, cycle; } intCycle[32];
+       u32 gteBusyCycle;
+       u32 muldivBusyCycle;
+       u32 subCycle;       /* interpreter cycle counting */
+       u32 subCycleStep;
+       u32 biuReg;
+       u8  branching;      /* interp. R3000A_BRANCH_TAKEN / not, 0 if not branch */
+       u8  dloadSel;       /* interp. delay load state */
+       u8  dloadReg[2];
+       u32 dloadVal[2];
+       u32 biosBranchCheck;
+       u32 cpuInRecursion;
+       u32 gpuIdleAfter;
+       u32 reserved[1];
+       // warning: changing anything in psxRegisters requires update of all
+       // asm in libpcsxcore/new_dynarec/
 } psxRegisters;
 
 extern psxRegisters psxRegs;
 
 /* new_dynarec stuff */
 } psxRegisters;
 
 extern psxRegisters psxRegs;
 
 /* new_dynarec stuff */
-extern u32 event_cycles[PSXINT_COUNT];
-extern u32 next_interupt;
-
-void new_dyna_save(void);
-void new_dyna_after_save(void);
-void new_dyna_restore(void);
-
-#define new_dyna_set_event(e, c) { \
-       s32 c_ = c; \
-       u32 abs_ = psxRegs.cycle + c_; \
-       s32 odi_ = next_interupt - psxRegs.cycle; \
-       event_cycles[e] = abs_; \
-       if (c_ < odi_) { \
-               /*printf("%u: next_interupt %d -> %d (%u)\n", psxRegs.cycle, odi_, c_, abs_);*/ \
-               next_interupt = abs_; \
-       } \
-}
-
-#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
+void new_dyna_freeze(void *f, int mode);
 
 int  psxInit();
 void psxReset();
 void psxShutdown();
 
 int  psxInit();
 void psxReset();
 void psxShutdown();
-void psxException(u32 code, u32 bd);
+void psxException(u32 code, enum R3000Abdt bdt, psxCP0Regs *cp0);
 void psxBranchTest();
 void psxExecuteBios();
 void psxBranchTest();
 void psxExecuteBios();
-int  psxTestLoadDelay(int reg, u32 tmp);
-void psxDelayTest(int reg, u32 bpc);
-void psxTestSWInts();
 void psxJumpTest();
 
 void psxJumpTest();
 
+void irq10Interrupt();
+void psxScheduleIrq10(int irq_count, int x_cycles, int y);
+
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif