+/*
+static void tr_PM0_to_r0(void)
+{
+}
+*/
+
+static int tr_PM4_to_r0(void)
+{
+ int reg = 4;
+ u32 pmcv = known_regs.pmac_read[reg];
+
+ if ((known_regb & KRREG_PMC) && (known_regs.emu_status & SSP_PMC_SET))
+ {
+ known_regs.pmac_read[reg] = known_regs.pmc;
+ known_regs.emu_status &= ~SSP_PMC_SET;
+ return 0;
+ }
+
+ if (known_regb & (1 << (20+4)))
+ {
+ int mode = known_regs.pmac_read[reg]>>16;
+ if ((mode & 0xfff0) == 0x0800)
+ {
+ known_regs.pmac_read[reg] += 1;
+ EOP_LDR_IMM(1,7,0x488); // rom_ptr
+ emit_mov_const(A_COND_AL, 0, (pmcv&0xfffff)<<1);
+ EOP_LDRH_REG(0,1,0); // ldrh r0, [r1, r0]
+ hostreg_r[0] = hostreg_r[1] = -1;
+ }
+ else if ((mode & 0x47ff) == 0x0018) // DRAM
+ {
+ int inc = get_inc(mode);
+ ssp->pmac_read[reg] += inc;
+ EOP_LDR_IMM(1,7,0x490); // dram_ptr
+ emit_mov_const(A_COND_AL, 0, (pmcv&0xffff)<<1);
+ EOP_LDRH_REG(0,1,0); // ldrh r0, [r1, r0]
+ if (pmcv == 0x187f03 || pmcv == 0x187f04) // wait loop detection
+ {
+ int flag = (pmcv == 0x187f03) ? SSP_WAIT_30FE06 : SSP_WAIT_30FE08;
+ tr_flush_dirty_ST();
+ EOP_LDR_IMM(1,7,0x484); // ldr r1, [r7, #0x484] // emu_status
+ EOP_TST_REG_SIMPLE(0,0);
+ EOP_C_DOP_IMM(A_COND_EQ,A_OP_ADD,0,11,11,22/2,1); // add r11, r11, #1024
+ EOP_C_DOP_IMM(A_COND_EQ,A_OP_ORR,0, 1, 1,24/2,flag>>8); // orr r1, r1, #SSP_WAIT_30FE08
+ EOP_STR_IMM(1,7,0x484); // str r1, [r7, #0x484] // emu_status
+ }
+ hostreg_r[0] = hostreg_r[1] = -1;
+ }
+ else
+ {
+ tr_unhandled();
+ }
+ known_regs.pmc = known_regs.pmac_read[reg];
+ known_regb |= KRREG_PMC;
+
+ return 0;
+ }
+ return -1;
+}
+