#include "r3000a.h"
#include "gte.h"
#include "psxhle.h"
+#include "debug.h"
static int branch = 0;
static int branch2 = 0;
#define debugI()
#endif
-inline void execI();
+void execI();
// Subsets
void (*psxBSC[64])();
void (*psxSPC[64])();
void (*psxREG[32])();
void (*psxCP0[32])();
-void (*psxCP2[64])();
+void (*psxCP2[64])(struct psxCP2Regs *regs);
void (*psxCP2BSC[32])();
static void delayRead(int reg, u32 bpc) {
return psxDelayBranchExec(tmp2);
}
-__inline void doBranch(u32 tar) {
+static void doBranch(u32 tar) {
u32 *code;
u32 tmp;
* Format: OP rs, rt *
*********************************************************/
void psxDIV() {
- if (_i32(_rRt_) != 0) {
- _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_);
- _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_);
- }
- else {
- _i32(_rLo_) = _i32(_rRs_) >= 0 ? 0xffffffff : 1;
- _i32(_rHi_) = _i32(_rRs_);
- }
+ if (!_i32(_rRt_)) {
+ _i32(_rHi_) = _i32(_rRs_);
+ if (_i32(_rRs_) & 0x80000000) {
+ _i32(_rLo_) = 1;
+ } else {
+ _i32(_rLo_) = 0xFFFFFFFF;
+ }
+/*
+ * Notaz said that this was "not needed" for ARM platforms and could slow it down so let's disable for ARM.
+ * This fixes a crash issue that can happen when running Amidog's CPU test.
+ * (It still stays stuck to a black screen but at least it doesn't crash anymore)
+ */
+#if !defined(__arm__) && !defined(__aarch64__)
+ } else if (_i32(_rRs_) == 0x80000000 && _i32(_rRt_) == 0xFFFFFFFF) {
+ _i32(_rLo_) = 0x80000000;
+ _i32(_rHi_) = 0;
+#endif
+ } else {
+ _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_);
+ _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_);
+ }
}
void psxDIVU() {
*/
}
-void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); }
-void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); }
-void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); }
+void psxSB() { psxMemWrite8 (_oB_, _rRt_ & 0xff); }
+void psxSH() { psxMemWrite16(_oB_, _rRt_ & 0xffff); }
+void psxSW() { psxMemWrite32(_oB_, _rRt_); }
u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 };
u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
void psxCFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
void psxTestSWInts() {
- // the next code is untested, if u know please
- // tell me if it works ok or not (linuzappz)
if (psxRegs.CP0.n.Cause & psxRegs.CP0.n.Status & 0x0300 &&
- psxRegs.CP0.n.Status & 0x1) {
+ psxRegs.CP0.n.Status & 0x1) {
+ psxRegs.CP0.n.Cause &= ~0x7c;
psxException(psxRegs.CP0.n.Cause, branch);
}
}
-__inline void MTC0(int reg, u32 val) {
+void MTC0(int reg, u32 val) {
// SysPrintf("MTC0 %d: %x\n", reg, val);
switch (reg) {
case 12: // Status
break;
case 13: // Cause
- psxRegs.CP0.n.Cause = val & ~(0xfc00);
+ psxRegs.CP0.n.Cause &= ~0x0300;
+ psxRegs.CP0.n.Cause |= val & 0x0300;
psxTestSWInts();
break;
}
void psxCOP2() {
- psxCP2[_Funct_]();
+ psxCP2[_Funct_]((struct psxCP2Regs *)&psxRegs.CP2D);
}
-void psxBASIC() {
+void psxBASIC(struct psxCP2Regs *regs) {
psxCP2BSC[_Rs_]();
}
void psxHLE() {
// psxHLEt[psxRegs.code & 0xffff]();
- psxHLEt[psxRegs.code & 0x07](); // HDHOSHY experimental patch
+// psxHLEt[psxRegs.code & 0x07](); // HDHOSHY experimental patch
+ uint32_t hleCode = psxRegs.code & 0x03ffffff;
+ if (hleCode >= (sizeof(psxHLEt) / sizeof(psxHLEt[0]))) {
+ psxNULL();
+ } else {
+ psxHLEt[hleCode]();
+ }
}
void (*psxBSC[64])() = {
psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
};
-void (*psxCP2[64])() = {
+void (*psxCP2[64])(struct psxCP2Regs *regs) = {
psxBASIC, gteRTPS , psxNULL , psxNULL, psxNULL, psxNULL , gteNCLIP, psxNULL, // 00
psxNULL , psxNULL , psxNULL , psxNULL, gteOP , psxNULL , psxNULL , psxNULL, // 08
gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , psxNULL , gteNCDT , psxNULL, // 10
}
// interpreter execution
-inline void execI() {
+void execI() {
u32 *code = (u32 *)PSXM(psxRegs.pc);
psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));