X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fr3000a.h;h=32538e584849a15938f4349c5112b3772f4b12f9;hp=399f9b63f9abe54b81b7210ef308f74feb3d661f;hb=HEAD;hpb=41e82ad46e60f9c3291ff81ebe4a07512b1194c5 diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 399f9b63..03aeee19 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -25,16 +25,40 @@ extern "C" { #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)(); - 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 (*Notify)(enum R3000Anote note, void *data); + void (*ApplyConfig)(); void (*Shutdown)(); } R3000Acpu; @@ -43,7 +67,7 @@ extern R3000Acpu psxInt; extern R3000Acpu psxRec; 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; @@ -61,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, - 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; -typedef union { +typedef union psxCP0Regs_ { 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]; @@ -142,23 +163,12 @@ typedef union { 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_SPU_UPDATE, - 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 { @@ -167,6 +177,8 @@ typedef struct psxCP2Regs { } psxCP2Regs; 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 */ union { @@ -176,115 +188,44 @@ typedef struct { }; psxCP2Regs CP2; }; - u32 pc; /* Program counter */ - u32 code; /* The instruction */ + u32 pc; /* Program counter */ + u32 code; /* The instruction */ 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 */ -extern u32 event_cycles[PSXINT_COUNT]; -extern u32 next_interupt; - -void new_dyna_before_save(void); -void new_dyna_after_save(void); void new_dyna_freeze(void *f, int mode); -#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 - 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(); -int psxTestLoadDelay(int reg, u32 tmp); -void psxDelayTest(int reg, u32 bpc); -void psxTestSWInts(); void psxJumpTest(); +void irq10Interrupt(); +void psxScheduleIrq10(int irq_count, int x_cycles, int y); + #ifdef __cplusplus } #endif