mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-07-11 09:34:00 +02:00
Compare commits
3 Commits
master
...
n64-systemtest
| Author | SHA1 | Date | |
|---|---|---|---|
| cd89473f7e | |||
| b89fed20e8 | |||
| 28af6a436e |
@@ -58,7 +58,7 @@ void pif_bootrom_hle_execute(struct r4300_core* r4300)
|
||||
unsigned int tv_type = get_tv_type(); /* 0:PAL, 1:NTSC, 2:MPAL */
|
||||
|
||||
int64_t* r4300_gpregs = r4300_regs(r4300);
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
/* setup CP0 registers */
|
||||
cp0_regs[CP0_STATUS_REG] = 0x34000000;
|
||||
|
||||
@@ -136,7 +136,7 @@ void cached_interp_##name##_OUT(void) \
|
||||
void cached_interp_##name##_IDLE(void) \
|
||||
{ \
|
||||
DECLARE_R4300 \
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0); \
|
||||
const int take_jump = (condition); \
|
||||
if (cop1 && check_cop1_unusable(r4300)) return; \
|
||||
|
||||
+11
-11
@@ -49,7 +49,7 @@ void init_cp0(struct cp0* cp0, unsigned int count_per_op, unsigned int count_per
|
||||
|
||||
void poweron_cp0(struct cp0* cp0)
|
||||
{
|
||||
uint32_t* cp0_regs;
|
||||
uint64_t* cp0_regs;
|
||||
unsigned int* cp0_next_interrupt;
|
||||
int* cp0_cycle_count;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -81,7 +81,7 @@ void poweron_cp0(struct cp0* cp0)
|
||||
}
|
||||
|
||||
|
||||
uint32_t* r4300_cp0_regs(struct cp0* cp0)
|
||||
uint64_t* r4300_cp0_regs(struct cp0* cp0)
|
||||
{
|
||||
#ifndef NEW_DYNAREC
|
||||
return cp0->regs;
|
||||
@@ -124,7 +124,7 @@ int* r4300_cp0_cycle_count(struct cp0* cp0)
|
||||
|
||||
int check_cop1_unusable(struct r4300_core* r4300)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
if (!(cp0_regs[CP0_STATUS_REG] & CP0_STATUS_CU1))
|
||||
{
|
||||
@@ -137,7 +137,7 @@ int check_cop1_unusable(struct r4300_core* r4300)
|
||||
|
||||
int check_cop2_unusable(struct r4300_core* r4300)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
if (!(cp0_regs[CP0_STATUS_REG] & CP0_STATUS_CU2))
|
||||
{
|
||||
@@ -151,7 +151,7 @@ int check_cop2_unusable(struct r4300_core* r4300)
|
||||
void cp0_update_count(struct r4300_core* r4300)
|
||||
{
|
||||
struct cp0* cp0 = &r4300->cp0;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
|
||||
#ifdef NEW_DYNAREC
|
||||
if (r4300->emumode != EMUMODE_DYNAREC)
|
||||
@@ -213,7 +213,7 @@ static void exception_epilog(struct r4300_core* r4300)
|
||||
|
||||
void TLB_refill_exception(struct r4300_core* r4300, uint32_t address, int w)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
int usual_handler = 0, i;
|
||||
|
||||
if (r4300->emumode != EMUMODE_DYNAREC && w != 2) {
|
||||
@@ -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);
|
||||
@@ -297,12 +297,12 @@ void TLB_refill_exception(struct r4300_core* r4300, uint32_t address, int w)
|
||||
|
||||
void exception_general(struct r4300_core* r4300)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
+2
-2
@@ -184,7 +184,7 @@ struct cp0
|
||||
{
|
||||
#ifndef NEW_DYNAREC
|
||||
/* New dynarec uses a different memory layout */
|
||||
uint32_t regs[CP0_REGS_COUNT];
|
||||
uint64_t regs[CP0_REGS_COUNT];
|
||||
uint64_t latch;
|
||||
#endif
|
||||
|
||||
@@ -227,7 +227,7 @@ struct cp0
|
||||
void init_cp0(struct cp0* cp0, unsigned int count_per_op, unsigned int count_per_op_denom_pot, struct new_dynarec_hot_state* new_dynarec_hot_state, const struct interrupt_handler* interrupt_handlers);
|
||||
void poweron_cp0(struct cp0* cp0);
|
||||
|
||||
uint32_t* r4300_cp0_regs(struct cp0* cp0);
|
||||
uint64_t* r4300_cp0_regs(struct cp0* cp0);
|
||||
uint64_t* r4300_cp0_latch(struct cp0* cp0);
|
||||
uint32_t* r4300_cp0_last_addr(struct cp0* cp0);
|
||||
unsigned int* r4300_cp0_next_interrupt(struct cp0* cp0);
|
||||
|
||||
+12
-12
@@ -100,7 +100,7 @@ static void clear_queue(struct interrupt_queue* q)
|
||||
|
||||
static int before_event(const struct cp0* cp0, unsigned int evt1, unsigned int evt2, int type2)
|
||||
{
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs((struct cp0*)cp0); /* OK to cast away const qualifier */
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs((struct cp0*)cp0); /* OK to cast away const qualifier */
|
||||
uint32_t count = cp0_regs[CP0_COUNT_REG];
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count((struct cp0*)cp0);
|
||||
|
||||
@@ -128,7 +128,7 @@ unsigned int add_random_interrupt_time(struct r4300_core* r4300)
|
||||
|
||||
void add_interrupt_event(struct cp0* cp0, int type, unsigned int delay)
|
||||
{
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
add_interrupt_event_count(cp0, type, cp0_regs[CP0_COUNT_REG] + delay);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ void add_interrupt_event_count(struct cp0* cp0, int type, unsigned int count)
|
||||
{
|
||||
struct node* event;
|
||||
struct node* e;
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(cp0);
|
||||
|
||||
@@ -191,7 +191,7 @@ void add_interrupt_event_count(struct cp0* cp0, int type, unsigned int count)
|
||||
void remove_interrupt_event(struct cp0* cp0)
|
||||
{
|
||||
struct node* e;
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(cp0);
|
||||
|
||||
@@ -264,7 +264,7 @@ void remove_event(struct interrupt_queue* q, int type)
|
||||
void translate_event_queue(struct cp0* cp0, unsigned int base)
|
||||
{
|
||||
struct node* e;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(cp0);
|
||||
|
||||
remove_event(&cp0->q, COMPARE_INT);
|
||||
@@ -309,7 +309,7 @@ int save_eventqueue_infos(const struct cp0* cp0, char *buf)
|
||||
void load_eventqueue_infos(struct cp0* cp0, const char *buf)
|
||||
{
|
||||
int len = 0;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
|
||||
clear_queue(&cp0->q);
|
||||
|
||||
@@ -335,7 +335,7 @@ void init_interrupt(struct cp0* cp0)
|
||||
void r4300_check_interrupt(struct r4300_core* r4300, uint32_t cause_ip, int set_cause)
|
||||
{
|
||||
struct node* event;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
@@ -379,7 +379,7 @@ void r4300_check_interrupt(struct r4300_core* r4300, uint32_t cause_ip, int set_
|
||||
|
||||
void raise_maskable_interrupt(struct r4300_core* r4300, uint32_t cause_ip)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
cp0_regs[CP0_CAUSE_REG] = (cp0_regs[CP0_CAUSE_REG] | cause_ip) & ~CP0_CAUSE_EXCCODE_MASK;
|
||||
|
||||
if (!(cp0_regs[CP0_STATUS_REG] & cp0_regs[CP0_CAUSE_REG] & UINT32_C(0xff00))) {
|
||||
@@ -396,7 +396,7 @@ void raise_maskable_interrupt(struct r4300_core* r4300, uint32_t cause_ip)
|
||||
void compare_int_handler(void* opaque)
|
||||
{
|
||||
struct r4300_core* r4300 = (struct r4300_core*)opaque;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
/* Add count_per_op to avoid wrong event order in case CP0_COUNT_REG == CP0_COMPARE_REG */
|
||||
@@ -422,7 +422,7 @@ void check_int_handler(void* opaque)
|
||||
void special_int_handler(void* opaque)
|
||||
{
|
||||
struct cp0* cp0 = (struct cp0*)opaque;
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
|
||||
remove_interrupt_event(cp0);
|
||||
add_interrupt_event_count(cp0, SPECIAL_INT, ((cp0_regs[CP0_COUNT_REG] & UINT32_C(0x80000000)) ^ UINT32_C(0x80000000)));
|
||||
@@ -434,7 +434,7 @@ void nmi_int_handler(void* opaque)
|
||||
{
|
||||
struct device* dev = (struct device*)opaque;
|
||||
struct r4300_core* r4300 = &dev->r4300;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
reset_pif(&dev->pif, 1);
|
||||
|
||||
@@ -537,7 +537,7 @@ static void call_interrupt_handler(const struct cp0* cp0, size_t index)
|
||||
|
||||
void gen_interrupt(struct r4300_core* r4300)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ DECLARE_INSTRUCTION(RESERVED)
|
||||
{
|
||||
DECLARE_R4300
|
||||
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
DebugMessage(M64MSG_ERROR, "reserved opcode: %" PRIX32 ":%" PRIX32, PCADDR, *fast_mem_access(r4300, PCADDR));
|
||||
|
||||
@@ -127,7 +127,7 @@ DECLARE_INSTRUCTION(RESERVED_COP2)
|
||||
{
|
||||
DECLARE_R4300
|
||||
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
if (check_cop2_unusable(r4300)) { return; }
|
||||
|
||||
@@ -140,7 +140,7 @@ DECLARE_INSTRUCTION(RESERVED_COP2)
|
||||
DECLARE_INSTRUCTION(BREAK)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_BP;
|
||||
exception_general(r4300);
|
||||
@@ -221,11 +221,23 @@ DECLARE_INSTRUCTION(LL)
|
||||
DECLARE_INSTRUCTION(LW)
|
||||
{
|
||||
DECLARE_R4300
|
||||
const uint32_t lsaddr = (uint32_t) irs32 + (uint32_t) iimmediate;
|
||||
const uint64_t lsaddr = (int64_t) irs + (int16_t) iimmediate;
|
||||
int64_t *lsrtp = &irt;
|
||||
ADD_TO_PC(1);
|
||||
uint32_t value;
|
||||
|
||||
if (lsaddr & 3) {
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
//
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
ADD_TO_PC(1);
|
||||
|
||||
if (r4300_read_aligned_word(r4300, lsaddr, &value)) {
|
||||
*lsrtp = SE32(value);
|
||||
}
|
||||
@@ -374,8 +386,19 @@ DECLARE_INSTRUCTION(SC)
|
||||
DECLARE_INSTRUCTION(SW)
|
||||
{
|
||||
DECLARE_R4300
|
||||
const uint32_t lsaddr = (uint32_t) irs32 + (uint32_t) iimmediate;
|
||||
const uint64_t lsaddr = (int64_t) irs + (int16_t) iimmediate;
|
||||
int64_t *lsrtp = &irt;
|
||||
|
||||
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) | ((int64_t)1 << 32);
|
||||
cp0_regs[CP0_BADVADDR_REG] = lsaddr;
|
||||
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_ADES;
|
||||
exception_general(r4300);
|
||||
return;
|
||||
}
|
||||
|
||||
ADD_TO_PC(1);
|
||||
|
||||
r4300_write_aligned_word(r4300, lsaddr, (uint32_t)*lsrtp, ~UINT32_C(0));
|
||||
@@ -993,7 +1016,7 @@ DECLARE_INSTRUCTION(CACHE)
|
||||
DECLARE_INSTRUCTION(ERET)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
|
||||
|
||||
cp0_update_count(r4300);
|
||||
@@ -1022,7 +1045,7 @@ DECLARE_INSTRUCTION(SYNC)
|
||||
DECLARE_INSTRUCTION(SYSCALL)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_SYS;
|
||||
exception_general(r4300);
|
||||
@@ -1034,7 +1057,7 @@ DECLARE_INSTRUCTION(SYSCALL)
|
||||
DECLARE_INSTRUCTION(name) \
|
||||
{ \
|
||||
DECLARE_R4300 \
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
|
||||
if (cond) \
|
||||
{ \
|
||||
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_TR; \
|
||||
@@ -1067,7 +1090,7 @@ DECLARE_INSTRUCTION(TLBP)
|
||||
{
|
||||
DECLARE_R4300
|
||||
int i;
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
cp0_regs[CP0_INDEX_REG] |= UINT32_C(0x80000000);
|
||||
for (i = 0; i < 32; ++i)
|
||||
@@ -1087,7 +1110,7 @@ DECLARE_INSTRUCTION(TLBP)
|
||||
DECLARE_INSTRUCTION(TLBR)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
int index;
|
||||
index = cp0_regs[CP0_INDEX_REG] & UINT32_C(0x1F);
|
||||
@@ -1104,7 +1127,7 @@ DECLARE_INSTRUCTION(TLBR)
|
||||
|
||||
static void TLBWrite(struct r4300_core* r4300, unsigned int idx)
|
||||
{
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint32_t pc_addr = *r4300_pc(r4300);
|
||||
|
||||
if (pc_addr >= r4300->cp0.tlb.entries[idx].start_even && pc_addr < r4300->cp0.tlb.entries[idx].end_even && r4300->cp0.tlb.entries[idx].v_even)
|
||||
@@ -1218,7 +1241,7 @@ static void TLBWrite(struct r4300_core* r4300, unsigned int idx)
|
||||
DECLARE_INSTRUCTION(TLBWR)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
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];
|
||||
@@ -1229,31 +1252,32 @@ DECLARE_INSTRUCTION(TLBWR)
|
||||
DECLARE_INSTRUCTION(TLBWI)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
TLBWrite(r4300, cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F));
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
/* 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
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
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:
|
||||
@@ -1262,90 +1286,53 @@ 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;
|
||||
}
|
||||
|
||||
ADD_TO_PC(1);
|
||||
return data;
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(DMFC0)
|
||||
static osal_inline void set_cp0_register(struct r4300_core* r4300, uint8_t reg, uint64_t value)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_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;
|
||||
default:
|
||||
rrt = cp0_regs[rfs];
|
||||
break;
|
||||
}
|
||||
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(MTC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
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;
|
||||
(*cp0_latch) = value;
|
||||
|
||||
switch(rfs)
|
||||
switch (reg)
|
||||
{
|
||||
case CP0_INDEX_REG:
|
||||
cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
|
||||
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;
|
||||
//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);
|
||||
cp0_regs[CP0_ENTRYLO0_REG] = value & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_ENTRYLO1_REG:
|
||||
cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
|
||||
cp0_regs[CP0_ENTRYLO1_REG] = value & UINT32_C(0x3FFFFFFF);
|
||||
break;
|
||||
case CP0_CONTEXT_REG:
|
||||
cp0_regs[CP0_CONTEXT_REG] = (rrt32 & UINT32_C(0xFF800000))
|
||||
| (cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0x007FFFF0));
|
||||
// 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] = rrt32 & UINT32_C(0x01FFE000);
|
||||
cp0_regs[CP0_PAGEMASK_REG] = value & UINT32_C(0x01FFE000);
|
||||
break;
|
||||
case CP0_WIRED_REG:
|
||||
cp0_regs[CP0_WIRED_REG] = rrt32 & UINT32_C(0x0000003F);
|
||||
cp0_regs[CP0_WIRED_REG] = value & UINT32_C(0x0000003F);
|
||||
cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
|
||||
break;
|
||||
case CP0_BADVADDR_REG:
|
||||
@@ -1355,10 +1342,10 @@ DECLARE_INSTRUCTION(MTC0)
|
||||
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);
|
||||
translate_event_queue(&r4300->cp0, value);
|
||||
break;
|
||||
case CP0_ENTRYHI_REG:
|
||||
cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF);
|
||||
cp0_regs[CP0_ENTRYHI_REG] = value & UINT32_C(0xFFFFE0FF);
|
||||
break;
|
||||
case CP0_COMPARE_REG:
|
||||
cp0_update_count(r4300);
|
||||
@@ -1367,21 +1354,21 @@ DECLARE_INSTRUCTION(MTC0)
|
||||
/* 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);
|
||||
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] = rrt32;
|
||||
cp0_regs[CP0_COMPARE_REG] = value;
|
||||
cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
|
||||
break;
|
||||
case CP0_STATUS_REG:
|
||||
rrt32 &= ~UINT32_C(0x080000); /* 19th bit isn't writable */
|
||||
value &= ~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);
|
||||
if((value & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
|
||||
set_fpr_pointers(&r4300->cp1, value);
|
||||
|
||||
cp0_regs[CP0_STATUS_REG] = rrt32;
|
||||
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]); // ???
|
||||
@@ -1391,50 +1378,79 @@ DECLARE_INSTRUCTION(MTC0)
|
||||
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);
|
||||
cp0_regs[CP0_CAUSE_REG] |= value & (CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
|
||||
break;
|
||||
case CP0_EPC_REG:
|
||||
cp0_regs[CP0_EPC_REG] = rrt32;
|
||||
cp0_regs[CP0_EPC_REG] = value;
|
||||
break;
|
||||
case CP0_PREVID_REG:
|
||||
break;
|
||||
case CP0_CONFIG_REG:
|
||||
cp0_regs[CP0_CONFIG_REG] = (rrt32 & UINT32_C(0x0000000F))
|
||||
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] = rrt32;
|
||||
cp0_regs[CP0_LLADDR_REG] = value;
|
||||
break;
|
||||
case CP0_WATCHLO_REG:
|
||||
cp0_regs[CP0_WATCHLO_REG] = rrt32;
|
||||
cp0_regs[CP0_WATCHLO_REG] = value;
|
||||
break;
|
||||
case CP0_WATCHHI_REG:
|
||||
cp0_regs[CP0_WATCHHI_REG] = rrt32;
|
||||
break;
|
||||
case CP0_XCONTEXT_REG:
|
||||
cp0_regs[CP0_WATCHHI_REG] = value;
|
||||
break;
|
||||
case CP0_CACHEERR_REG:
|
||||
break;
|
||||
case CP0_PARITYERR_REG:
|
||||
cp0_regs[CP0_PARITYERR_REG] = rrt32 & UINT32_C(0x000000FF);
|
||||
cp0_regs[CP0_PARITYERR_REG] = value & UINT32_C(0x000000FF);
|
||||
break;
|
||||
case CP0_TAGLO_REG:
|
||||
cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0);
|
||||
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] = rrt32;
|
||||
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
|
||||
rrt = get_cp0_register(r4300, rfs);
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(MTC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
set_cp0_register(r4300, rfs, rrt32);
|
||||
if (rfs == CP0_STATUS_REG)
|
||||
return;
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
DECLARE_INSTRUCTION(DMTC0)
|
||||
{
|
||||
DECLARE_R4300
|
||||
set_cp0_register(r4300, rfs, rrt);
|
||||
if (rfs == CP0_STATUS_REG)
|
||||
return;
|
||||
ADD_TO_PC(1);
|
||||
}
|
||||
|
||||
|
||||
/* CP1 load/store instructions */
|
||||
|
||||
DECLARE_INSTRUCTION(LWC1)
|
||||
@@ -1517,7 +1533,7 @@ DECLARE_INSTRUCTION(DCFC1)
|
||||
DECLARE_R4300
|
||||
if (check_cop1_unusable(r4300)) { return; }
|
||||
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
fpu_reset_cause(r4300_cp1_fcr31(&r4300->cp1));
|
||||
|
||||
@@ -1563,7 +1579,7 @@ DECLARE_INSTRUCTION(DCTC1)
|
||||
DECLARE_R4300
|
||||
if (check_cop1_unusable(r4300)) { return; }
|
||||
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
|
||||
|
||||
fpu_reset_cause(r4300_cp1_fcr31(&r4300->cp1));
|
||||
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ struct new_dynarec_hot_state
|
||||
int64_t regs[32];
|
||||
int64_t hi;
|
||||
int64_t lo;
|
||||
uint32_t cp0_regs[32];
|
||||
uint64_t cp0_regs[32];
|
||||
uint64_t cp0_latch;
|
||||
float* cp1_regs_simple[32];
|
||||
double* cp1_regs_double[32];
|
||||
|
||||
@@ -76,7 +76,7 @@ static void InterpretOpcode(struct r4300_core* r4300);
|
||||
} \
|
||||
static void name##_IDLE(struct r4300_core* r4300, uint32_t op) \
|
||||
{ \
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
|
||||
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0); \
|
||||
const int take_jump = (condition); \
|
||||
if (cop1 && check_cop1_unusable(r4300)) return; \
|
||||
@@ -443,9 +443,11 @@ void InterpretOpcode(struct r4300_core* r4300)
|
||||
else NOP(r4300, 0);
|
||||
break;
|
||||
case 4: /* Coprocessor 0 opcode 4: MTC0 */
|
||||
case 5: /* Coprocessor 0 opcode 5: DMTC0 */
|
||||
MTC0(r4300, op);
|
||||
break;
|
||||
case 5: /* Coprocessor 0 opcode 5: DMTC0 */
|
||||
DMTC0(r4300, op);
|
||||
break;
|
||||
case 16: /* Coprocessor 0 opcode 16: TLB */
|
||||
switch (op & 0x3F) {
|
||||
case 1: TLBR(r4300, op); break;
|
||||
@@ -686,8 +688,7 @@ void InterpretOpcode(struct r4300_core* r4300)
|
||||
else NOP(r4300, 0);
|
||||
break;
|
||||
case 35: /* Major opcode 35: LW */
|
||||
if (RT_OF(op) != 0) LW(r4300, op);
|
||||
else NOP(r4300, 0);
|
||||
LW(r4300, op);
|
||||
break;
|
||||
case 36: /* Major opcode 36: LBU */
|
||||
if (RT_OF(op) != 0) LBU(r4300, op);
|
||||
|
||||
@@ -40,7 +40,7 @@ static uint32_t get_remaining_dma_length(struct ai_controller* ai)
|
||||
{
|
||||
unsigned int* next_ai_event;
|
||||
unsigned int remaining_dma_duration;
|
||||
const uint32_t* cp0_regs;
|
||||
const uint64_t* cp0_regs;
|
||||
|
||||
if (ai->fifo[0].duration == 0)
|
||||
return 0;
|
||||
|
||||
@@ -87,7 +87,7 @@ void read_vi_regs(void* opaque, uint32_t address, uint32_t* value)
|
||||
{
|
||||
struct vi_controller* vi = (struct vi_controller*)opaque;
|
||||
uint32_t reg = vi_reg(address);
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs(&vi->mi->r4300->cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs(&vi->mi->r4300->cp0);
|
||||
|
||||
if (reg == VI_CURRENT_REG)
|
||||
{
|
||||
|
||||
+1
-1
@@ -818,7 +818,7 @@ void netplay_check_sync(struct cp0* cp0)
|
||||
|
||||
if (l_vi_counter % 600 == 0)
|
||||
{
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
|
||||
|
||||
l_check_sync_packet->data[0] = UDP_SYNC_DATA;
|
||||
netplay_write32(l_vi_counter, &l_check_sync_packet->data[1]); //current VI count
|
||||
|
||||
+4
-4
@@ -208,7 +208,7 @@ static int savestates_load_m64p(struct device* dev, char *filepath)
|
||||
unsigned char using_tlb_data[4];
|
||||
unsigned char data_0001_0200[4096]; // 4k for extra state from v1.2
|
||||
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
|
||||
|
||||
SDL_LockMutex(savestates_lock);
|
||||
|
||||
@@ -990,7 +990,7 @@ static int savestates_load_pj64(struct device* dev,
|
||||
size_t savestateSize;
|
||||
unsigned char *savestateData, *curr;
|
||||
|
||||
uint32_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
|
||||
uint64_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
|
||||
|
||||
/* Read and check Project64 magic number. */
|
||||
if (!read_func(handle, header, 8))
|
||||
@@ -1543,7 +1543,7 @@ static int savestates_save_m64p(const struct device* dev, char *filepath)
|
||||
char *curr;
|
||||
|
||||
/* OK to cast away const qualifier */
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
|
||||
|
||||
save = malloc(sizeof(*save));
|
||||
if (!save) {
|
||||
@@ -1951,7 +1951,7 @@ static int savestates_save_pj64(const struct device* dev,
|
||||
size_t savestateSize;
|
||||
unsigned char *savestateData, *curr;
|
||||
|
||||
const uint32_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
|
||||
const uint64_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
|
||||
|
||||
// Allocate memory for the save state data
|
||||
savestateSize = 8 + SaveRDRAMSize + 0x2754;
|
||||
|
||||
Reference in New Issue
Block a user