Skip to content

Commit 58450a4

Browse files
committed
ee: Implement INTC/CSR spin skip
1 parent ad8b08b commit 58450a4

File tree

4 files changed

+77
-27
lines changed

4 files changed

+77
-27
lines changed

src/ee/ee.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ uint32_t ee_get_pc(struct ee_state* ee);
143143
struct ps2_ram* ee_get_spr(struct ee_state* ee);
144144
int ee_run_block(struct ee_state* ee, int cycles);
145145
void ee_set_fmv_skip(struct ee_state* ee, int v);
146+
void ee_reset_intc_reads(struct ee_state* ee);
147+
void ee_reset_csr_reads(struct ee_state* ee);
146148

147149
#undef EE_ALIGNED16
148150

src/ee/ee_cached.cpp

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
#endif
3636

3737
// file = fopen("vu.dump", "a"); fprintf(file, #ins "\n"); fclose(file);
38-
#define VU_LOWER(ins) { ee->vu0->lower = i.opcode; vu_i_ ## ins(ee->vu0); }
39-
#define VU_UPPER(ins) { ee->vu0->upper = i.opcode; vu_i_ ## ins(ee->vu0); }
38+
#define VU_LOWER(ins) { ps2_vu_decode_lower(ee->vu0, i.opcode); vu_i_ ## ins(ee->vu0, &ee->vu0->lower); }
39+
#define VU_UPPER(ins) { ps2_vu_decode_upper(ee->vu0, i.opcode); vu_i_ ## ins(ee->vu0, &ee->vu0->upper); }
4040

4141
static inline int fast_abs32(int a) {
4242
uint32_t m = a >> 31;
@@ -357,11 +357,9 @@ static inline int ee_translate_virt(struct ee_state* ee, uint32_t virt, uint32_t
357357
if ((addr & 0xf0000000) == 0x70000000) \
358358
return ps2_ram_read ## b(ee->scratchpad, addr & 0x3fff); \
359359
uint32_t phys; \
360-
if (ee_translate_virt(ee, addr, &phys)) { \
361-
printf("ee: TLB mapping error\n"); \
362-
exit(1); \
363-
return 0; \
364-
} \
360+
ee_translate_virt(ee, addr, &phys); \
361+
if (phys == 0x1000f000) ee->intc_reads++; \
362+
if (phys == 0x12001000) ee->csr_reads++; \
365363
return ee->bus.read ## b(ee->bus.udata, phys); \
366364
}
367365

@@ -370,11 +368,7 @@ static inline int ee_translate_virt(struct ee_state* ee, uint32_t virt, uint32_t
370368
if ((addr & 0xf0000000) == 0x70000000) \
371369
{ ps2_ram_write ## b(ee->scratchpad, addr & 0x3fff, data); return; } \
372370
uint32_t phys; \
373-
if (ee_translate_virt(ee, addr, &phys)) { \
374-
printf("ee: TLB mapping error\n"); \
375-
exit(1); \
376-
return; \
377-
} \
371+
ee_translate_virt(ee, addr, &phys); \
378372
ee->bus.write ## b(ee->bus.udata, phys, data); \
379373
}
380374

@@ -543,6 +537,8 @@ static inline int ee_check_irq(struct ee_state* ee) {
543537
// ee->delay_slot
544538
// );
545539

540+
ee->intc_reads = 0;
541+
546542
ee_exception_level1(ee, CAUSE_EXC1_INT);
547543

548544
return 1;
@@ -642,16 +638,16 @@ static inline void ee_i_bc0tl(struct ee_state* ee, const ee_instruction& i) {
642638
BRANCH_LIKELY(ee->cpcond0, EE_D_SI16);
643639
}
644640
static inline void ee_i_bc1f(struct ee_state* ee, const ee_instruction& i) {
645-
BRANCH((ee->fcr & (1 << 23)) == 0, EE_D_SI16);
641+
BRANCH((ee->fcr & FPU_FLG_C) == 0, EE_D_SI16);
646642
}
647643
static inline void ee_i_bc1fl(struct ee_state* ee, const ee_instruction& i) {
648-
BRANCH_LIKELY((ee->fcr & (1 << 23)) == 0, EE_D_SI16);
644+
BRANCH_LIKELY((ee->fcr & FPU_FLG_C) == 0, EE_D_SI16);
649645
}
650646
static inline void ee_i_bc1t(struct ee_state* ee, const ee_instruction& i) {
651-
BRANCH((ee->fcr & (1 << 23)) != 0, EE_D_SI16);
647+
BRANCH((ee->fcr & FPU_FLG_C) != 0, EE_D_SI16);
652648
}
653649
static inline void ee_i_bc1tl(struct ee_state* ee, const ee_instruction& i) {
654-
BRANCH_LIKELY((ee->fcr & (1 << 23)) != 0, EE_D_SI16);
650+
BRANCH_LIKELY((ee->fcr & FPU_FLG_C) != 0, EE_D_SI16);
655651
}
656652
static inline void ee_i_bc2f(struct ee_state* ee, const ee_instruction& i) { BRANCH(1, EE_D_SI16); }
657653
static inline void ee_i_bc2fl(struct ee_state* ee, const ee_instruction& i) { BRANCH_LIKELY(1, EE_D_SI16); }
@@ -721,39 +717,39 @@ static inline void ee_i_cache(struct ee_state* ee, const ee_instruction& i) {
721717
}
722718
static inline void ee_i_ceq(struct ee_state* ee, const ee_instruction& i) {
723719
if (EE_FS == EE_FT) {
724-
ee->fcr |= 1 << 23;
720+
ee->fcr |= FPU_FLG_C;
725721
} else {
726-
ee->fcr &= ~(1 << 23);
722+
ee->fcr &= ~FPU_FLG_C;
727723
}
728724
}
729725
static inline void ee_i_cf(struct ee_state* ee, const ee_instruction& i) {
730-
ee->fcr &= ~(1 << 23);
726+
ee->fcr &= ~FPU_FLG_C;
731727
}
732728
static inline void ee_i_cfc1(struct ee_state* ee, const ee_instruction& i) {
733-
EE_RT = (EE_D_FS >= 16) ? ee->fcr : 0x2e30;
729+
EE_RT = SE6432((EE_D_FS >= 16) ? ee->fcr : 0x2e30);
734730
}
735731
static inline void ee_i_cfc2(struct ee_state* ee, const ee_instruction& i) {
736732
EE_RT = SE6432(ps2_vu_read_vi(ee->vu0, EE_D_RD));
737733
}
738734
static inline void ee_i_cle(struct ee_state* ee, const ee_instruction& i) {
739735
if (EE_FS <= EE_FT) {
740-
ee->fcr |= 1 << 23;
736+
ee->fcr |= FPU_FLG_C;
741737
} else {
742-
ee->fcr &= ~(1 << 23);
738+
ee->fcr &= ~FPU_FLG_C;
743739
}
744740
}
745741
static inline void ee_i_clt(struct ee_state* ee, const ee_instruction& i) {
746742
if (EE_FS < EE_FT) {
747-
ee->fcr |= 1 << 23;
743+
ee->fcr |= FPU_FLG_C;
748744
} else {
749-
ee->fcr &= ~(1 << 23);
745+
ee->fcr &= ~FPU_FLG_C;
750746
}
751747
}
752748
static inline void ee_i_ctc1(struct ee_state* ee, const ee_instruction& i) {
753749
if (EE_D_FS < 16)
754750
return;
755751

756-
ee->fcr = (ee->fcr & ~(0x83c078)) | (EE_RT & 0x83c078);
752+
ee->fcr = EE_RT32; // (ee->fcr & ~(0x83c078)) | (EE_RT & 0x83c078);
757753
}
758754
static inline void ee_i_ctc2(struct ee_state* ee, const ee_instruction& i) {
759755
// To-do: Handle FBRST, VPU_STAT, CMSAR1
@@ -3189,6 +3185,8 @@ void ee_reset(struct ee_state* ee) {
31893185
ee->prid = 0x2e20;
31903186
ee->pc = EE_VEC_RESET;
31913187
ee->next_pc = ee->pc + 4;
3188+
ee->intc_reads = 0;
3189+
ee->csr_reads = 0;
31923190

31933191
ee->block_cache.clear();
31943192

@@ -3725,8 +3723,21 @@ int ee_run_block(struct ee_state* ee, int max_cycles) {
37253723
if (ee->pc == 0x81fc0) {
37263724
ee_check_irq(ee);
37273725

3728-
ee->total_cycles += 1024;
3729-
ee->count += 1024;
3726+
ee->total_cycles += 8 * 128;
3727+
ee->count += 8 * 128;
3728+
// ee->eenull_counter += 8 * 64;
3729+
3730+
return 8 * 128;
3731+
}
3732+
3733+
if (ee->intc_reads >= 10000) {
3734+
ee_check_irq(ee);
3735+
3736+
return 1024;
3737+
}
3738+
3739+
if (ee->csr_reads >= 1000) {
3740+
ee_check_irq(ee);
37303741

37313742
return 1024;
37323743
}
@@ -3746,6 +3757,10 @@ int ee_run_block(struct ee_state* ee, int max_cycles) {
37463757
if (ee_check_irq(ee))
37473758
break;
37483759

3760+
// if (ee->pc >= 0x81fc0 && ee->pc <= 0x81fdc) {
3761+
// ee->eenull_counter++;
3762+
// }
3763+
37493764
ee->pc = ee->next_pc;
37503765
ee->next_pc += 4;
37513766

@@ -3820,4 +3835,12 @@ struct ps2_ram* ee_get_spr(struct ee_state* ee) {
38203835

38213836
void ee_set_fmv_skip(struct ee_state* ee, int v) {
38223837
ee->fmv_skip = v;
3838+
}
3839+
3840+
void ee_reset_intc_reads(struct ee_state* ee) {
3841+
ee->intc_reads = 0;
3842+
}
3843+
3844+
void ee_reset_csr_reads(struct ee_state* ee) {
3845+
ee->csr_reads = 0;
38233846
}

src/ee/ee_def.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ struct ee_state {
138138
struct vu_state* vu1;
139139

140140
struct ee_vtlb_entry vtlb[48];
141+
142+
int eenull_counter;
143+
int csr_reads;
144+
int intc_reads;
141145
};
142146

143147
#define THS_RUN 0x01

src/ee/intc.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,33 @@ void ps2_intc_write64(struct ps2_intc* intc, uint32_t addr, uint64_t data) {
101101
void ps2_intc_irq(struct ps2_intc* intc, int dev) {
102102
intc->stat |= 1 << dev;
103103

104+
static const char* dev_names[] = {
105+
"GS",
106+
"SBUS",
107+
"VBLANK_IN",
108+
"VBLANK_OUT",
109+
"VIF0",
110+
"VIF1",
111+
"VU0",
112+
"VU1",
113+
"IPU",
114+
"TIMER0",
115+
"TIMER1",
116+
"TIMER2",
117+
"TIMER3",
118+
"SFIFO",
119+
"VU0_WD"
120+
};
121+
104122
struct sched_event event;
105123

106124
event.callback = intc_check_irq_event;
107125
event.cycles = 64;
108126
event.name = "INTC IRQ check";
109127
event.udata = intc;
110128

129+
// Notify EE that an interrupt has occurred
130+
ee_reset_intc_reads(intc->ee);
131+
111132
sched_schedule(intc->sched, event);
112133
}

0 commit comments

Comments
 (0)