diff options
author | notaz | 2011-01-14 17:43:22 +0200 |
---|---|---|
committer | notaz | 2011-01-16 00:03:53 +0200 |
commit | fca1aef29ed173264919b7a0b35f92dbe0d4e521 (patch) | |
tree | 24029e840f38f4a7e85672d7d766b86343cb90d9 /libpcsxcore/new_dynarec | |
parent | b5e7e49a59450877fbeb6f9a6721b73fa065e7a2 (diff) | |
download | pcsx_rearmed-fca1aef29ed173264919b7a0b35f92dbe0d4e521.tar.gz pcsx_rearmed-fca1aef29ed173264919b7a0b35f92dbe0d4e521.tar.bz2 pcsx_rearmed-fca1aef29ed173264919b7a0b35f92dbe0d4e521.zip |
drc: handle MTC0 in delay slot
also refactor MTC0 code a bit.
Diffstat (limited to 'libpcsxcore/new_dynarec')
-rw-r--r-- | libpcsxcore/new_dynarec/assem_arm.c | 24 | ||||
-rw-r--r-- | libpcsxcore/new_dynarec/emu_if.c | 17 | ||||
-rw-r--r-- | libpcsxcore/new_dynarec/emu_if.h | 4 | ||||
-rw-r--r-- | libpcsxcore/new_dynarec/linkage_arm.s | 6 |
4 files changed, 34 insertions, 17 deletions
diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index f3f89e1..56b0c1a 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -3405,16 +3405,12 @@ void cop0_assemble(int i,struct regstat *i_regs) assert(s>=0); emit_writeword(s,(int)&readmem_dword); wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->is32); -#ifdef MUPEN64 /// FIXME +#ifdef MUPEN64 emit_addimm(FP,(int)&fake_pc-(int)&dynarec_local,0); emit_movimm((source[i]>>11)&0x1f,1); emit_writeword(0,(int)&PC); emit_writebyte(1,(int)&(fake_pc.f.r.nrd)); #endif -#ifdef PCSX - emit_movimm(source[i],0); - emit_writeword(0,(int)&psxRegs.code); -#endif if(copr==9||copr==11||copr==12||copr==13) { emit_readword((int)&last_count,ECX); emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc @@ -3427,6 +3423,19 @@ void cop0_assemble(int i,struct regstat *i_regs) // The interrupt must be taken immediately, because a subsequent // instruction might disable interrupts again. if(copr==12||copr==13) { +#ifdef PCSX + if (is_delayslot) { + // burn cycles to cause cc_interrupt, which will + // reschedule next_interupt. Relies on CCREG from above. + assem_debug("MTC0 DS %d\n", copr); + emit_writeword(HOST_CCREG,(int)&last_count); + emit_movimm(0,HOST_CCREG); + emit_storereg(CCREG,HOST_CCREG); + emit_movimm(copr,0); + emit_call((int)pcsx_mtc0_ds); + return; + } +#endif emit_movimm(start+i*4+4,0); emit_movimm(0,1); emit_writeword(0,(int)&pcaddr); @@ -3434,7 +3443,12 @@ void cop0_assemble(int i,struct regstat *i_regs) } //else if(copr==12&&is_delayslot) emit_call((int)MTC0_R12); //else +#ifdef PCSX + emit_movimm(copr,0); + emit_call((int)pcsx_mtc0); +#else emit_call((int)MTC0); +#endif if(copr==9||copr==11||copr==12||copr==13) { emit_readword((int)&Count,HOST_CCREG); emit_readword((int)&next_interupt,ECX); diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index 897791f..d2ff36a 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -109,13 +109,20 @@ void gen_interupt() next_interupt, next_interupt - psxRegs.cycle); } -void MTC0_() +// from interpreter +extern void MTC0(int reg, u32 val); + +void pcsx_mtc0(u32 reg) { - extern void psxMTC0(); + evprintf("MTC0 %d #%x @%08x %u\n", reg, readmem_word, psxRegs.pc, psxRegs.cycle); + MTC0(reg, readmem_word); + gen_interupt(); +} - evprintf("ari64 MTC0 %08x %08x %u\n", psxRegs.code, psxRegs.pc, psxRegs.cycle); - psxMTC0(); - gen_interupt(); /* FIXME: checking pending irqs should be enough */ +void pcsx_mtc0_ds(u32 reg) +{ + evprintf("MTC0 %d #%x @%08x %u\n", reg, readmem_word, psxRegs.pc, psxRegs.cycle); + MTC0(reg, readmem_word); } void new_dyna_save(void) diff --git a/libpcsxcore/new_dynarec/emu_if.h b/libpcsxcore/new_dynarec/emu_if.h index e93fabd..9e7f710 100644 --- a/libpcsxcore/new_dynarec/emu_if.h +++ b/libpcsxcore/new_dynarec/emu_if.h @@ -50,8 +50,8 @@ extern unsigned int next_interupt; extern int pending_exception; /* called by drc */ -void MTC0_(); -#define MTC0 MTC0_ /* don't call interpreter with wrong args */ +void pcsx_mtc0(u32 reg); +void pcsx_mtc0_ds(u32 reg); /* misc */ extern void (*psxHLEt[])(); diff --git a/libpcsxcore/new_dynarec/linkage_arm.s b/libpcsxcore/new_dynarec/linkage_arm.s index f8bdca2..70836df 100644 --- a/libpcsxcore/new_dynarec/linkage_arm.s +++ b/libpcsxcore/new_dynarec/linkage_arm.s @@ -624,16 +624,12 @@ cc_interrupt: .global do_interrupt .type do_interrupt, %function do_interrupt: - /* FIXME: cycles already calculated, not needed? */ ldr r0, [fp, #pcaddr-dynarec_local] bl get_addr_ht - ldr r1, [fp, #next_interupt-dynarec_local] - ldr r10, [fp, #cycle-dynarec_local] - str r1, [fp, #last_count-dynarec_local] - sub r10, r10, r1 add r10, r10, #2 mov pc, r0 .size do_interrupt, .-do_interrupt + .align 2 .global fp_exception .type fp_exception, %function |