mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-10-12 02:09:34 +00:00
beep boop more wip changes
This commit is contained in:
+4
-4
@@ -65,7 +65,7 @@ void poweron_cp0(struct cp0* cp0)
|
||||
cp0_regs[CP0_COUNT_REG] = UINT32_C(0x5000);
|
||||
cp0_regs[CP0_CAUSE_REG] = UINT32_C(0x5c);
|
||||
cp0_regs[CP0_CONTEXT_REG] = UINT32_C(0x7ffff0);
|
||||
cp0_regs[CP0_EPC_REG] = UINT32_C(0xffffffff);
|
||||
cp0_regs[CP0_EPC_REG] = UINT64_C(0xffffffffffffffff);
|
||||
cp0_regs[CP0_BADVADDR_REG] = UINT32_C(0xffffffff);
|
||||
cp0_regs[CP0_ERROREPC_REG] = UINT32_C(0xffffffff);
|
||||
|
||||
@@ -246,8 +246,8 @@ void TLB_refill_exception(struct r4300_core* r4300, uint32_t address, int w)
|
||||
if (r4300->emumode != EMUMODE_PURE_INTERPRETER)
|
||||
{
|
||||
cp0_regs[CP0_EPC_REG] = (w != 2)
|
||||
? *r4300_pc(r4300)
|
||||
: address;
|
||||
? SE32(*r4300_pc(r4300))
|
||||
: SE32(address);
|
||||
}
|
||||
else {
|
||||
cp0_regs[CP0_EPC_REG] = *r4300_pc(r4300);
|
||||
@@ -302,7 +302,7 @@ void exception_general(struct r4300_core* r4300)
|
||||
cp0_update_count(r4300);
|
||||
cp0_regs[CP0_STATUS_REG] |= CP0_STATUS_EXL;
|
||||
|
||||
cp0_regs[CP0_EPC_REG] = *r4300_pc(r4300);
|
||||
cp0_regs[CP0_EPC_REG] = SE32(*r4300_pc(r4300));
|
||||
|
||||
if (r4300->delay_slot == 1 || r4300->delay_slot == 3)
|
||||
{
|
||||
|
||||
+146
-290
@@ -227,8 +227,9 @@ DECLARE_INSTRUCTION(LW)
|
||||
|
||||
if (lsaddr & 3) {
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
cp0_regs[CP0_CONTEXT_REG] = (lsaddr >> 9 & 0x00000000007FFFF0);
|
||||
cp0_regs[CP0_XCONTEXT_REG] = (lsaddr >> 9 & 0x7FFFFFF0) | (lsaddr >> 31 & 0x80000000);
|
||||
//
|
||||
cp0_regs[CP0_CONTEXT_REG] = (cp0_regs[CP0_CONTEXT_REG] & 0xffffffffff800000) | (lsaddr >> 9 & 0x00000000007FFFF0);
|
||||
cp0_regs[CP0_XCONTEXT_REG] = (cp0_regs[CP0_CONTEXT_REG] & 0xffffffffff800000) | (lsaddr >> 9 & 0x7FFFFFF0) | (lsaddr >> 31 & 0x80000000) | ((int64_t)1 << 32);
|
||||
cp0_regs[CP0_BADVADDR_REG] = lsaddr;
|
||||
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_ADEL;
|
||||
exception_general(r4300);
|
||||
@@ -391,7 +392,7 @@ DECLARE_INSTRUCTION(SW)
|
||||
if (lsaddr & 3) {
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
cp0_regs[CP0_CONTEXT_REG] = (lsaddr >> 9 & 0x007FFFF0);
|
||||
cp0_regs[CP0_XCONTEXT_REG] = (lsaddr >> 9 & 0x7FFFFFF0) | (lsaddr >> 31 & 0x80000000);
|
||||
cp0_regs[CP0_XCONTEXT_REG] = (lsaddr >> 9 & 0x7FFFFFF0) | (lsaddr >> 31 & 0x80000000) | ((int64_t)1 << 32);
|
||||
cp0_regs[CP0_BADVADDR_REG] = lsaddr;
|
||||
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_ADES;
|
||||
exception_general(r4300);
|
||||
@@ -1258,24 +1259,25 @@ DECLARE_INSTRUCTION(TLBWI)
|
||||
}
|
||||
|
||||
/* CP0 load/store instructions */
|
||||
#include <stdio.h>
|
||||
|
||||
DECLARE_INSTRUCTION(MFC0)
|
||||
static osal_inline uint64_t get_cp0_register(struct r4300_core* r4300, uint8_t reg)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
|
||||
|
||||
switch(rfs)
|
||||
uint64_t data;
|
||||
switch (reg)
|
||||
{
|
||||
case CP0_RANDOM_REG:
|
||||
cp0_update_count(r4300);
|
||||
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
|
||||
+ cp0_regs[CP0_WIRED_REG];
|
||||
rrt = SE32(cp0_regs[rfs]);
|
||||
data = cp0_regs[reg];
|
||||
break;
|
||||
case CP0_COUNT_REG:
|
||||
cp0_update_count(r4300);
|
||||
rrt = SE32(cp0_regs[rfs]);
|
||||
data = cp0_regs[reg];
|
||||
break;
|
||||
case CP0_UNUSED_7:
|
||||
case CP0_UNUSED_21:
|
||||
@@ -1284,313 +1286,167 @@ DECLARE_INSTRUCTION(MFC0)
|
||||
case CP0_UNUSED_24:
|
||||
case CP0_UNUSED_25:
|
||||
case CP0_UNUSED_31:
|
||||
rrt = (*cp0_latch);
|
||||
data = (*cp0_latch);
|
||||
break;
|
||||
default:
|
||||
rrt = SE32(cp0_regs[rfs]);
|
||||
data = cp0_regs[reg];
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static osal_inline void set_cp0_register(struct r4300_core* r4300, uint8_t reg, uint64_t value)
|
||||
{
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
(*cp0_latch) = value;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case CP0_INDEX_REG:
|
||||
cp0_regs[CP0_INDEX_REG] = value & UINT32_C(0x8000003F);
|
||||
if ((cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
|
||||
{
|
||||
//DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
|
||||
//*r4300_stop(r4300)=1;
|
||||
}
|
||||
break;
|
||||
case CP0_RANDOM_REG:
|
||||
break;
|
||||
case CP0_ENTRYLO0_REG:
|
||||
cp0_regs[CP0_ENTRYLO0_REG] = value & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_ENTRYLO1_REG:
|
||||
cp0_regs[CP0_ENTRYLO1_REG] = value & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_CONTEXT_REG:
|
||||
// 0xffffffffff800000
|
||||
cp0_regs[CP0_CONTEXT_REG] = value & UINT64_C(0xffffffffff800000);
|
||||
break;
|
||||
case CP0_XCONTEXT_REG:
|
||||
//cp0_regs[CP0_XCONTEXT_REG] = value & UINT64_C(0xffffffffff800000);
|
||||
break;
|
||||
case CP0_PAGEMASK_REG:
|
||||
cp0_regs[CP0_PAGEMASK_REG] = value & UINT32_C(0x01FFE000);
|
||||
break;
|
||||
case CP0_WIRED_REG:
|
||||
cp0_regs[CP0_WIRED_REG] = value & UINT32_C(0x0000003F);
|
||||
cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
|
||||
break;
|
||||
case CP0_BADVADDR_REG:
|
||||
break;
|
||||
case CP0_COUNT_REG:
|
||||
cp0_update_count(r4300);
|
||||
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
|
||||
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
|
||||
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
|
||||
translate_event_queue(&r4300->cp0, value);
|
||||
break;
|
||||
case CP0_ENTRYHI_REG:
|
||||
cp0_regs[CP0_ENTRYHI_REG] = value & UINT32_C(0xFFFFE0FF);
|
||||
break;
|
||||
case CP0_COMPARE_REG:
|
||||
cp0_update_count(r4300);
|
||||
remove_event(&r4300->cp0.q, COMPARE_INT);
|
||||
|
||||
/* Add count_per_op to avoid wrong event order in case CP0_COUNT_REG == CP0_COMPARE_REG */
|
||||
cp0_regs[CP0_COUNT_REG] += r4300->cp0.count_per_op;
|
||||
*cp0_cycle_count += r4300->cp0.count_per_op;
|
||||
add_interrupt_event_count(&r4300->cp0, COMPARE_INT, value);
|
||||
cp0_regs[CP0_COUNT_REG] -= r4300->cp0.count_per_op;
|
||||
|
||||
/* Update next interrupt in case first event is COMPARE_INT */
|
||||
*cp0_cycle_count = cp0_regs[CP0_COUNT_REG] - r4300->cp0.q.first->data.count;
|
||||
cp0_regs[CP0_COMPARE_REG] = value;
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
|
||||
break;
|
||||
case CP0_STATUS_REG:
|
||||
value &= ~UINT32_C(0x080000); /* 19th bit isn't writable */
|
||||
|
||||
if((value & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
|
||||
set_fpr_pointers(&r4300->cp1, value);
|
||||
|
||||
cp0_regs[CP0_STATUS_REG] = value;
|
||||
ADD_TO_PC(1);
|
||||
cp0_update_count(r4300);
|
||||
r4300_check_interrupt(r4300, CP0_CAUSE_IP2, r4300->mi->regs[MI_INTR_REG] & r4300->mi->regs[MI_INTR_MASK_REG]); // ???
|
||||
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
|
||||
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
|
||||
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
|
||||
return;
|
||||
case CP0_CAUSE_REG:
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~(CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
cp0_regs[CP0_CAUSE_REG] |= value & (CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
break;
|
||||
case CP0_EPC_REG:
|
||||
cp0_regs[CP0_EPC_REG] = value;
|
||||
break;
|
||||
case CP0_PREVID_REG:
|
||||
break;
|
||||
case CP0_CONFIG_REG:
|
||||
cp0_regs[CP0_CONFIG_REG] = (value & UINT32_C(0x0000000F))
|
||||
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x00008000))
|
||||
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x7FFFFFFF));
|
||||
break;
|
||||
case CP0_LLADDR_REG:
|
||||
cp0_regs[CP0_LLADDR_REG] = value;
|
||||
break;
|
||||
case CP0_WATCHLO_REG:
|
||||
cp0_regs[CP0_WATCHLO_REG] = value;
|
||||
break;
|
||||
case CP0_WATCHHI_REG:
|
||||
cp0_regs[CP0_WATCHHI_REG] = value;
|
||||
break;
|
||||
case CP0_CACHEERR_REG:
|
||||
break;
|
||||
case CP0_PARITYERR_REG:
|
||||
cp0_regs[CP0_PARITYERR_REG] = value & UINT32_C(0x000000FF);
|
||||
break;
|
||||
case CP0_TAGLO_REG:
|
||||
cp0_regs[CP0_TAGLO_REG] = value & UINT32_C(0x0FFFFFC0);
|
||||
break;
|
||||
case CP0_TAGHI_REG:
|
||||
cp0_regs[CP0_TAGHI_REG] = 0;
|
||||
break;
|
||||
case CP0_ERROREPC_REG:
|
||||
cp0_regs[CP0_ERROREPC_REG] = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(MFC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
rrt32 = SE32(get_cp0_register(r4300, rfs));
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(DMFC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
|
||||
|
||||
switch(rfs)
|
||||
{
|
||||
case CP0_RANDOM_REG:
|
||||
cp0_update_count(r4300);
|
||||
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
|
||||
+ cp0_regs[CP0_WIRED_REG];
|
||||
rrt = cp0_regs[rfs];
|
||||
break;
|
||||
case CP0_COUNT_REG:
|
||||
cp0_update_count(r4300);
|
||||
rrt = cp0_regs[rfs];
|
||||
break;
|
||||
case CP0_EPC_REG:
|
||||
rrt = SE32(cp0_regs[rfs]);
|
||||
break;
|
||||
case CP0_UNUSED_7:
|
||||
case CP0_UNUSED_21:
|
||||
case CP0_UNUSED_22:
|
||||
case CP0_UNUSED_23:
|
||||
case CP0_UNUSED_24:
|
||||
case CP0_UNUSED_25:
|
||||
case CP0_UNUSED_31:
|
||||
rrt = (*cp0_latch);
|
||||
break;
|
||||
case CP0_BADVADDR_REG:
|
||||
rrt32 = cp0_regs[CP0_BADVADDR_REG];
|
||||
break;
|
||||
case CP0_XCONTEXT_REG:
|
||||
rrt = cp0_regs[CP0_XCONTEXT_REG] | ((int64_t)1 << 32);
|
||||
break;
|
||||
case CP0_CONTEXT_REG:
|
||||
rrt = cp0_regs[CP0_CONTEXT_REG];
|
||||
break;
|
||||
default:
|
||||
rrt = cp0_regs[rfs];
|
||||
break;
|
||||
}
|
||||
|
||||
rrt = get_cp0_register(r4300, rfs);
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(MTC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
(*cp0_latch) = rrt32;
|
||||
|
||||
switch(rfs)
|
||||
{
|
||||
case CP0_INDEX_REG:
|
||||
cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
|
||||
if ((cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
|
||||
{
|
||||
DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
|
||||
*r4300_stop(r4300)=1;
|
||||
}
|
||||
break;
|
||||
case CP0_RANDOM_REG:
|
||||
break;
|
||||
case CP0_ENTRYLO0_REG:
|
||||
cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_ENTRYLO1_REG:
|
||||
cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_CONTEXT_REG:
|
||||
cp0_regs[CP0_CONTEXT_REG] = rrt32;
|
||||
break;
|
||||
case CP0_PAGEMASK_REG:
|
||||
cp0_regs[CP0_PAGEMASK_REG] = rrt32 & UINT32_C(0x01FFE000);
|
||||
break;
|
||||
case CP0_WIRED_REG:
|
||||
cp0_regs[CP0_WIRED_REG] = rrt32 & UINT32_C(0x0000003F);
|
||||
cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
|
||||
break;
|
||||
case CP0_BADVADDR_REG:
|
||||
break;
|
||||
case CP0_COUNT_REG:
|
||||
cp0_update_count(r4300);
|
||||
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
|
||||
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
|
||||
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
|
||||
translate_event_queue(&r4300->cp0, rrt32);
|
||||
break;
|
||||
case CP0_ENTRYHI_REG:
|
||||
cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF);
|
||||
break;
|
||||
case CP0_COMPARE_REG:
|
||||
cp0_update_count(r4300);
|
||||
remove_event(&r4300->cp0.q, COMPARE_INT);
|
||||
|
||||
/* Add count_per_op to avoid wrong event order in case CP0_COUNT_REG == CP0_COMPARE_REG */
|
||||
cp0_regs[CP0_COUNT_REG] += r4300->cp0.count_per_op;
|
||||
*cp0_cycle_count += r4300->cp0.count_per_op;
|
||||
add_interrupt_event_count(&r4300->cp0, COMPARE_INT, rrt32);
|
||||
cp0_regs[CP0_COUNT_REG] -= r4300->cp0.count_per_op;
|
||||
|
||||
/* Update next interrupt in case first event is COMPARE_INT */
|
||||
*cp0_cycle_count = cp0_regs[CP0_COUNT_REG] - r4300->cp0.q.first->data.count;
|
||||
cp0_regs[CP0_COMPARE_REG] = rrt32;
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
|
||||
break;
|
||||
case CP0_STATUS_REG:
|
||||
rrt32 &= ~UINT32_C(0x080000); /* 19th bit isn't writable */
|
||||
|
||||
if((rrt32 & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
|
||||
set_fpr_pointers(&r4300->cp1, rrt32);
|
||||
|
||||
cp0_regs[CP0_STATUS_REG] = rrt32;
|
||||
ADD_TO_PC(1);
|
||||
cp0_update_count(r4300);
|
||||
r4300_check_interrupt(r4300, CP0_CAUSE_IP2, r4300->mi->regs[MI_INTR_REG] & r4300->mi->regs[MI_INTR_MASK_REG]); // ???
|
||||
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
|
||||
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
|
||||
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
|
||||
set_cp0_register(r4300, rfs, rrt32);
|
||||
if (rfs == CP0_STATUS_REG)
|
||||
return;
|
||||
case CP0_CAUSE_REG:
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~(CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
cp0_regs[CP0_CAUSE_REG] |= rrt32 & (CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
break;
|
||||
case CP0_EPC_REG:
|
||||
cp0_regs[CP0_EPC_REG] = rrt32;
|
||||
break;
|
||||
case CP0_PREVID_REG:
|
||||
break;
|
||||
case CP0_CONFIG_REG:
|
||||
cp0_regs[CP0_CONFIG_REG] = (rrt32 & UINT32_C(0x0000000F))
|
||||
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x00008000))
|
||||
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x7FFFFFFF));
|
||||
break;
|
||||
case CP0_LLADDR_REG:
|
||||
cp0_regs[CP0_LLADDR_REG] = rrt32;
|
||||
break;
|
||||
case CP0_WATCHLO_REG:
|
||||
cp0_regs[CP0_WATCHLO_REG] = rrt32;
|
||||
break;
|
||||
case CP0_WATCHHI_REG:
|
||||
cp0_regs[CP0_WATCHHI_REG] = rrt32;
|
||||
break;
|
||||
case CP0_XCONTEXT_REG:
|
||||
break;
|
||||
case CP0_CACHEERR_REG:
|
||||
break;
|
||||
case CP0_PARITYERR_REG:
|
||||
cp0_regs[CP0_PARITYERR_REG] = rrt32 & UINT32_C(0x000000FF);
|
||||
break;
|
||||
case CP0_TAGLO_REG:
|
||||
cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0);
|
||||
break;
|
||||
case CP0_TAGHI_REG:
|
||||
cp0_regs[CP0_TAGHI_REG] = 0;
|
||||
break;
|
||||
case CP0_ERROREPC_REG:
|
||||
cp0_regs[CP0_ERROREPC_REG] = rrt32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
DECLARE_INSTRUCTION(DMTC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
(*cp0_latch) = rrt;
|
||||
|
||||
switch(rfs)
|
||||
{
|
||||
case CP0_INDEX_REG:
|
||||
cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
|
||||
if ((cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
|
||||
{
|
||||
DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
|
||||
*r4300_stop(r4300)=1;
|
||||
}
|
||||
break;
|
||||
case CP0_RANDOM_REG:
|
||||
break;
|
||||
case CP0_ENTRYLO0_REG:
|
||||
cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_ENTRYLO1_REG:
|
||||
cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_CONTEXT_REG:
|
||||
printf("setting context reg to 0x%16lX\n", rrt);
|
||||
cp0_regs[CP0_CONTEXT_REG] = rrt;
|
||||
break;
|
||||
case CP0_PAGEMASK_REG:
|
||||
cp0_regs[CP0_PAGEMASK_REG] = rrt32 & UINT32_C(0x01FFE000);
|
||||
break;
|
||||
case CP0_WIRED_REG:
|
||||
cp0_regs[CP0_WIRED_REG] = rrt32 & UINT32_C(0x0000003F);
|
||||
cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
|
||||
break;
|
||||
case CP0_BADVADDR_REG:
|
||||
break;
|
||||
case CP0_COUNT_REG:
|
||||
cp0_update_count(r4300);
|
||||
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
|
||||
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
|
||||
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
|
||||
translate_event_queue(&r4300->cp0, rrt32);
|
||||
break;
|
||||
case CP0_ENTRYHI_REG:
|
||||
cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF);
|
||||
break;
|
||||
case CP0_COMPARE_REG:
|
||||
cp0_update_count(r4300);
|
||||
remove_event(&r4300->cp0.q, COMPARE_INT);
|
||||
|
||||
/* Add count_per_op to avoid wrong event order in case CP0_COUNT_REG == CP0_COMPARE_REG */
|
||||
cp0_regs[CP0_COUNT_REG] += r4300->cp0.count_per_op;
|
||||
*cp0_cycle_count += r4300->cp0.count_per_op;
|
||||
add_interrupt_event_count(&r4300->cp0, COMPARE_INT, rrt32);
|
||||
cp0_regs[CP0_COUNT_REG] -= r4300->cp0.count_per_op;
|
||||
|
||||
/* Update next interrupt in case first event is COMPARE_INT */
|
||||
*cp0_cycle_count = cp0_regs[CP0_COUNT_REG] - r4300->cp0.q.first->data.count;
|
||||
cp0_regs[CP0_COMPARE_REG] = rrt32;
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
|
||||
break;
|
||||
case CP0_STATUS_REG:
|
||||
rrt32 &= ~UINT32_C(0x080000); /* 19th bit isn't writable */
|
||||
|
||||
if((rrt32 & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
|
||||
set_fpr_pointers(&r4300->cp1, rrt32);
|
||||
|
||||
cp0_regs[CP0_STATUS_REG] = rrt32;
|
||||
ADD_TO_PC(1);
|
||||
cp0_update_count(r4300);
|
||||
r4300_check_interrupt(r4300, CP0_CAUSE_IP2, r4300->mi->regs[MI_INTR_REG] & r4300->mi->regs[MI_INTR_MASK_REG]); // ???
|
||||
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
|
||||
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
|
||||
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
|
||||
set_cp0_register(r4300, rfs, rrt);
|
||||
if (rfs == CP0_STATUS_REG)
|
||||
return;
|
||||
case CP0_CAUSE_REG:
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~(CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
cp0_regs[CP0_CAUSE_REG] |= rrt32 & (CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
break;
|
||||
case CP0_EPC_REG:
|
||||
cp0_regs[CP0_EPC_REG] = rrt32;
|
||||
break;
|
||||
case CP0_PREVID_REG:
|
||||
break;
|
||||
case CP0_CONFIG_REG:
|
||||
cp0_regs[CP0_CONFIG_REG] = (rrt32 & UINT32_C(0x0000000F))
|
||||
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x00008000))
|
||||
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x7FFFFFFF));
|
||||
break;
|
||||
case CP0_LLADDR_REG:
|
||||
cp0_regs[CP0_LLADDR_REG] = rrt32;
|
||||
break;
|
||||
case CP0_WATCHLO_REG:
|
||||
cp0_regs[CP0_WATCHLO_REG] = rrt32;
|
||||
break;
|
||||
case CP0_WATCHHI_REG:
|
||||
cp0_regs[CP0_WATCHHI_REG] = rrt32;
|
||||
break;
|
||||
//case CP0_CONTEXT_REG:
|
||||
// cp0_regs[CP0_CONTEXT_REG] = rrt;
|
||||
case CP0_XCONTEXT_REG:
|
||||
cp0_regs[CP0_XCONTEXT_REG] = rrt;
|
||||
break;
|
||||
case CP0_CACHEERR_REG:
|
||||
break;
|
||||
case CP0_PARITYERR_REG:
|
||||
cp0_regs[CP0_PARITYERR_REG] = rrt32 & UINT32_C(0x000000FF);
|
||||
break;
|
||||
case CP0_TAGLO_REG:
|
||||
cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0);
|
||||
break;
|
||||
case CP0_TAGHI_REG:
|
||||
cp0_regs[CP0_TAGHI_REG] = 0;
|
||||
break;
|
||||
case CP0_ERROREPC_REG:
|
||||
cp0_regs[CP0_ERROREPC_REG] = rrt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user