mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
Revert 4ec1247
as it cause more troubles than it solves
This commit is contained in:
parent
aa9c5aa559
commit
35821b373c
6 changed files with 33 additions and 48 deletions
|
@ -3836,6 +3836,8 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
||||||
u = FETCH32(opd->imm);
|
u = FETCH32(opd->imm);
|
||||||
else
|
else
|
||||||
u = (s16)FETCH_OP(opd->imm);
|
u = (s16)FETCH_OP(opd->imm);
|
||||||
|
// tweak for Blackthorne: avoid stack overwriting
|
||||||
|
if (GET_Rn() == SHR_SP && u == 0x0603f800) u = 0x0603f900;
|
||||||
gconst_new(GET_Rn(), u);
|
gconst_new(GET_Rn(), u);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -52,7 +52,6 @@ typedef struct SH2_
|
||||||
#define SH2_STATE_RPOLL (1 << 4) // polling address in SDRAM
|
#define SH2_STATE_RPOLL (1 << 4) // polling address in SDRAM
|
||||||
#define SH2_TIMER_RUN (1 << 6) // SOC WDT timer is running
|
#define SH2_TIMER_RUN (1 << 6) // SOC WDT timer is running
|
||||||
#define SH2_IN_DRC (1 << 7) // DRC in use
|
#define SH2_IN_DRC (1 << 7) // DRC in use
|
||||||
#define SH2_PWM_IRQ (1 << 8) // entering IRQ
|
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
uint32_t poll_addr;
|
uint32_t poll_addr;
|
||||||
int poll_cycles;
|
int poll_cycles;
|
||||||
|
|
|
@ -19,11 +19,6 @@ static int REGPARM(2) sh2_irq_cb(SH2 *sh2, int level)
|
||||||
if (sh2->pending_irl > sh2->pending_int_irq) {
|
if (sh2->pending_irl > sh2->pending_int_irq) {
|
||||||
elprintf_sh2(sh2, EL_32X, "ack/irl %d @ %08x",
|
elprintf_sh2(sh2, EL_32X, "ack/irl %d @ %08x",
|
||||||
level, sh2_pc(sh2));
|
level, sh2_pc(sh2));
|
||||||
// tweak for Blackthorne, part 1: master SH2 overwrites stack of slave SH2 being
|
|
||||||
// in pwm interrupt. On real hardware, nothing happens since slave fetches the
|
|
||||||
// values it has written from its cache, but picodrive doesn't emulate caching.
|
|
||||||
if ((1<<sh2->pending_irl/2) == P32XI_PWM && sh2->is_slave)
|
|
||||||
sh2->state |= SH2_PWM_IRQ;
|
|
||||||
return 64 + sh2->pending_irl / 2;
|
return 64 + sh2->pending_irl / 2;
|
||||||
} else {
|
} else {
|
||||||
elprintf_sh2(sh2, EL_32X, "ack/int %d/%d @ %08x",
|
elprintf_sh2(sh2, EL_32X, "ack/int %d/%d @ %08x",
|
||||||
|
@ -60,13 +55,15 @@ void p32x_update_irls(SH2 *active_sh2, unsigned int m68k_cycles)
|
||||||
mrun = sh2_irl_irq(&msh2, mlvl, msh2.state & SH2_STATE_RUN);
|
mrun = sh2_irl_irq(&msh2, mlvl, msh2.state & SH2_STATE_RUN);
|
||||||
if (mrun) {
|
if (mrun) {
|
||||||
p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES & ~SH2_STATE_SLEEP, m68k_cycles);
|
p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES & ~SH2_STATE_SLEEP, m68k_cycles);
|
||||||
p32x_sync_other_sh2(&msh2, m68k_cycles);
|
if (msh2.state & SH2_STATE_RUN)
|
||||||
|
sh2_end_run(&msh2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
srun = sh2_irl_irq(&ssh2, slvl, ssh2.state & SH2_STATE_RUN);
|
srun = sh2_irl_irq(&ssh2, slvl, ssh2.state & SH2_STATE_RUN);
|
||||||
if (srun) {
|
if (srun) {
|
||||||
p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES & ~SH2_STATE_SLEEP, m68k_cycles);
|
p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES & ~SH2_STATE_SLEEP, m68k_cycles);
|
||||||
p32x_sync_other_sh2(&ssh2, m68k_cycles);
|
if (ssh2.state & SH2_STATE_RUN)
|
||||||
|
sh2_end_run(&ssh2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
elprintf(EL_32X, "update_irls: m %d/%d, s %d/%d", mlvl, mrun, slvl, srun);
|
elprintf(EL_32X, "update_irls: m %d/%d, s %d/%d", mlvl, mrun, slvl, srun);
|
||||||
|
@ -389,18 +386,10 @@ static void p32x_run_events(unsigned int until)
|
||||||
static void run_sh2(SH2 *sh2, unsigned int m68k_cycles)
|
static void run_sh2(SH2 *sh2, unsigned int m68k_cycles)
|
||||||
{
|
{
|
||||||
unsigned int cycles, done;
|
unsigned int cycles, done;
|
||||||
unsigned int cpwm = 1400, m68k_cpwm = C_SH2_TO_M68K(sh2, cpwm);
|
|
||||||
|
|
||||||
pevt_log_sh2_o(sh2, EVT_RUN_START);
|
pevt_log_sh2_o(sh2, EVT_RUN_START);
|
||||||
sh2->state |= SH2_STATE_RUN;
|
sh2->state |= SH2_STATE_RUN;
|
||||||
cycles = C_M68K_TO_SH2(sh2, m68k_cycles);
|
cycles = C_M68K_TO_SH2(sh2, m68k_cycles);
|
||||||
// tweak for Blackthorne, part 2: try to ensure that the PWM irq completes before
|
|
||||||
// switching to the other SH2. This irq can run up to about 1400 cycles.
|
|
||||||
// NB, may delay hint/vint interrupts on the same SH2, might cause sync problems.
|
|
||||||
if (unlikely(sh2->state & SH2_PWM_IRQ) && cycles < cpwm &&
|
|
||||||
CYCLES_GT(p32x_event_times[P32X_EVENT_PWM], sh2->m68krcycles_done+m68k_cpwm))
|
|
||||||
cycles = 1400;
|
|
||||||
sh2->state &= ~SH2_PWM_IRQ;
|
|
||||||
elprintf_sh2(sh2, EL_32X, "+run %u %d @%08x",
|
elprintf_sh2(sh2, EL_32X, "+run %u %d @%08x",
|
||||||
sh2->m68krcycles_done, cycles, sh2->pc);
|
sh2->m68krcycles_done, cycles, sh2->pc);
|
||||||
|
|
||||||
|
|
|
@ -816,7 +816,7 @@ static void p32x_sh2reg_write8(u32 a, u32 d, SH2 *sh2)
|
||||||
Pico32x.sh2_regs[0] &= ~0x80;
|
Pico32x.sh2_regs[0] &= ~0x80;
|
||||||
Pico32x.sh2_regs[0] |= d & 0x80;
|
Pico32x.sh2_regs[0] |= d & 0x80;
|
||||||
|
|
||||||
if ((old ^ d) & 1)
|
if ((d ^ old) & 1)
|
||||||
p32x_pwm_schedule_sh2(sh2);
|
p32x_pwm_schedule_sh2(sh2);
|
||||||
if ((old ^ d) & 2)
|
if ((old ^ d) & 2)
|
||||||
p32x_update_cmd_irq(sh2, 0);
|
p32x_update_cmd_irq(sh2, 0);
|
||||||
|
|
|
@ -41,13 +41,13 @@ void p32x_pwm_ctl_changed(void)
|
||||||
pwm.irq_reload = pwm.irq_timer;
|
pwm.irq_reload = pwm.irq_timer;
|
||||||
pwm.irq_state = pwm_irq_opt ? PWM_IRQ_STOPPED: PWM_IRQ_LOCKED;
|
pwm.irq_state = pwm_irq_opt ? PWM_IRQ_STOPPED: PWM_IRQ_LOCKED;
|
||||||
|
|
||||||
if (Pico32x.pwm_irq_cnt <= 0)
|
if (Pico32x.pwm_irq_cnt == 0)
|
||||||
Pico32x.pwm_irq_cnt = pwm.irq_reload;
|
Pico32x.pwm_irq_cnt = pwm.irq_reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_pwm_irq(SH2 *sh2, unsigned int m68k_cycles)
|
static void do_pwm_irq(SH2 *sh2, unsigned int m68k_cycles)
|
||||||
{
|
{
|
||||||
p32x_trigger_irq(NULL, m68k_cycles, P32XI_PWM);
|
p32x_trigger_irq(sh2, m68k_cycles, P32XI_PWM);
|
||||||
|
|
||||||
if (Pico32x.regs[0x30 / 2] & P32XP_RTP) {
|
if (Pico32x.regs[0x30 / 2] & P32XP_RTP) {
|
||||||
p32x_event_schedule(m68k_cycles, P32X_EVENT_PWM, pwm.cycles / 3 + 1);
|
p32x_event_schedule(m68k_cycles, P32X_EVENT_PWM, pwm.cycles / 3 + 1);
|
||||||
|
@ -110,7 +110,7 @@ static void consume_fifo_do(SH2 *sh2, unsigned int m68k_cycles,
|
||||||
mem->pwm[pwm.ptr * 2 + 1] = pwm.current[1];
|
mem->pwm[pwm.ptr * 2 + 1] = pwm.current[1];
|
||||||
pwm.ptr = (pwm.ptr + 1) & (PWM_BUFF_LEN - 1);
|
pwm.ptr = (pwm.ptr + 1) & (PWM_BUFF_LEN - 1);
|
||||||
|
|
||||||
if (--Pico32x.pwm_irq_cnt <= 0) {
|
if (--Pico32x.pwm_irq_cnt == 0) {
|
||||||
Pico32x.pwm_irq_cnt = pwm.irq_reload;
|
Pico32x.pwm_irq_cnt = pwm.irq_reload;
|
||||||
do_pwm_irq(sh2, m68k_cycles);
|
do_pwm_irq(sh2, m68k_cycles);
|
||||||
} else if (Pico32x.pwm_p[1] == 0 && pwm.irq_state >= PWM_IRQ_LOW) {
|
} else if (Pico32x.pwm_p[1] == 0 && pwm.irq_state >= PWM_IRQ_LOW) {
|
||||||
|
|
|
@ -270,7 +270,6 @@ u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2)
|
||||||
u8 *r = (void *)sh2->peri_regs;
|
u8 *r = (void *)sh2->peri_regs;
|
||||||
u32 d;
|
u32 d;
|
||||||
|
|
||||||
DRC_SAVE_SR(sh2);
|
|
||||||
a &= 0x1ff;
|
a &= 0x1ff;
|
||||||
d = PREG8(r, a);
|
d = PREG8(r, a);
|
||||||
|
|
||||||
|
@ -278,9 +277,10 @@ u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2)
|
||||||
a | ~0x1ff, d, sh2_pc(sh2));
|
a | ~0x1ff, d, sh2_pc(sh2));
|
||||||
if ((a & 0x1c0) == 0x140) {
|
if ((a & 0x1c0) == 0x140) {
|
||||||
// abused as comm area
|
// abused as comm area
|
||||||
|
DRC_SAVE_SR(sh2);
|
||||||
p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
|
p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
|
||||||
}
|
|
||||||
DRC_RESTORE_SR(sh2);
|
DRC_RESTORE_SR(sh2);
|
||||||
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +289,6 @@ u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2)
|
||||||
u16 *r = (void *)sh2->peri_regs;
|
u16 *r = (void *)sh2->peri_regs;
|
||||||
u32 d;
|
u32 d;
|
||||||
|
|
||||||
DRC_SAVE_SR(sh2);
|
|
||||||
a &= 0x1fe;
|
a &= 0x1fe;
|
||||||
d = r[MEM_BE2(a / 2)];
|
d = r[MEM_BE2(a / 2)];
|
||||||
|
|
||||||
|
@ -297,9 +296,10 @@ u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2)
|
||||||
a | ~0x1ff, d, sh2_pc(sh2));
|
a | ~0x1ff, d, sh2_pc(sh2));
|
||||||
if ((a & 0x1c0) == 0x140) {
|
if ((a & 0x1c0) == 0x140) {
|
||||||
// abused as comm area
|
// abused as comm area
|
||||||
|
DRC_SAVE_SR(sh2);
|
||||||
p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
|
p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
|
||||||
}
|
|
||||||
DRC_RESTORE_SR(sh2);
|
DRC_RESTORE_SR(sh2);
|
||||||
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +307,6 @@ u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2)
|
||||||
{
|
{
|
||||||
u32 d;
|
u32 d;
|
||||||
|
|
||||||
DRC_SAVE_SR(sh2);
|
|
||||||
a &= 0x1fc;
|
a &= 0x1fc;
|
||||||
d = sh2->peri_regs[a / 4];
|
d = sh2->peri_regs[a / 4];
|
||||||
|
|
||||||
|
@ -318,9 +317,10 @@ u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2)
|
||||||
sh2->poll_cnt = 0;
|
sh2->poll_cnt = 0;
|
||||||
else if ((a & 0x1c0) == 0x140) {
|
else if ((a & 0x1c0) == 0x140) {
|
||||||
// abused as comm area
|
// abused as comm area
|
||||||
|
DRC_SAVE_SR(sh2);
|
||||||
p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
|
p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
|
||||||
}
|
|
||||||
DRC_RESTORE_SR(sh2);
|
DRC_RESTORE_SR(sh2);
|
||||||
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,18 +364,18 @@ void REGPARM(3) sh2_peripheral_write8(u32 a, u32 d, SH2 *sh2)
|
||||||
u8 *r = (void *)sh2->peri_regs;
|
u8 *r = (void *)sh2->peri_regs;
|
||||||
u8 old;
|
u8 old;
|
||||||
|
|
||||||
DRC_SAVE_SR(sh2);
|
|
||||||
elprintf_sh2(sh2, EL_32XP, "peri w8 [%08x] %02x @%06x",
|
elprintf_sh2(sh2, EL_32XP, "peri w8 [%08x] %02x @%06x",
|
||||||
a, d, sh2_pc(sh2));
|
a, d, sh2_pc(sh2));
|
||||||
|
|
||||||
a &= 0x1ff;
|
a &= 0x1ff;
|
||||||
old = PREG8(r, a);
|
old = PREG8(r, a);
|
||||||
PREG8(r, a) = d;
|
|
||||||
|
|
||||||
switch (a) {
|
switch (a) {
|
||||||
case 0x002: // SCR - serial control
|
case 0x002: // SCR - serial control
|
||||||
if (!(old & 0x20) && (d & 0x20)) // TE being set
|
if (!(PREG8(r, a) & 0x20) && (d & 0x20)) { // TE being set
|
||||||
|
PREG8(r, a) = d;
|
||||||
sci_trigger(sh2, r);
|
sci_trigger(sh2, r);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x003: // TDR - transmit data
|
case 0x003: // TDR - transmit data
|
||||||
break;
|
break;
|
||||||
|
@ -383,31 +383,27 @@ void REGPARM(3) sh2_peripheral_write8(u32 a, u32 d, SH2 *sh2)
|
||||||
d = (old & (d | 0x06)) | (d & 1);
|
d = (old & (d | 0x06)) | (d & 1);
|
||||||
PREG8(r, a) = d;
|
PREG8(r, a) = d;
|
||||||
sci_trigger(sh2, r);
|
sci_trigger(sh2, r);
|
||||||
break;
|
return;
|
||||||
case 0x005: // RDR - receive data
|
case 0x005: // RDR - receive data
|
||||||
break;
|
break;
|
||||||
case 0x010: // TIER
|
case 0x010: // TIER
|
||||||
if (d & 0x8e)
|
if (d & 0x8e)
|
||||||
elprintf(EL_32XP|EL_ANOMALY, "TIER: %02x", d);
|
elprintf(EL_32XP|EL_ANOMALY, "TIER: %02x", d);
|
||||||
d = (d & 0x8e) | 1;
|
d = (d & 0x8e) | 1;
|
||||||
PREG8(r, a) = d;
|
|
||||||
break;
|
break;
|
||||||
case 0x017: // TOCR
|
case 0x017: // TOCR
|
||||||
d |= 0xe0;
|
d |= 0xe0;
|
||||||
PREG8(r, a) = d;
|
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
PREG8(r, a) = d;
|
||||||
|
|
||||||
if ((a & 0x1c0) == 0x140)
|
if ((a & 0x1c0) == 0x140)
|
||||||
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
|
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
|
||||||
}
|
}
|
||||||
DRC_RESTORE_SR(sh2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2)
|
void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2)
|
||||||
{
|
{
|
||||||
u16 *r = (void *)sh2->peri_regs;
|
u16 *r = (void *)sh2->peri_regs;
|
||||||
|
|
||||||
DRC_SAVE_SR(sh2);
|
|
||||||
elprintf_sh2(sh2, EL_32XP, "peri w16 [%08x] %04x @%06x",
|
elprintf_sh2(sh2, EL_32XP, "peri w16 [%08x] %04x @%06x",
|
||||||
a, d, sh2_pc(sh2));
|
a, d, sh2_pc(sh2));
|
||||||
|
|
||||||
|
@ -421,13 +417,13 @@ void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2)
|
||||||
}
|
}
|
||||||
if ((d & 0xff00) == 0x5a00) // WTCNT
|
if ((d & 0xff00) == 0x5a00) // WTCNT
|
||||||
PREG8(r, 0x81) = d;
|
PREG8(r, 0x81) = d;
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
r[MEM_BE2(a / 2)] = d;
|
r[MEM_BE2(a / 2)] = d;
|
||||||
if ((a & 0x1c0) == 0x140)
|
if ((a & 0x1c0) == 0x140)
|
||||||
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
|
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
|
||||||
}
|
}
|
||||||
DRC_RESTORE_SR(sh2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
|
void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
|
||||||
{
|
{
|
||||||
|
@ -435,7 +431,6 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
|
||||||
u32 old;
|
u32 old;
|
||||||
struct dmac *dmac;
|
struct dmac *dmac;
|
||||||
|
|
||||||
DRC_SAVE_SR(sh2);
|
|
||||||
elprintf_sh2(sh2, EL_32XP, "peri w32 [%08x] %08x @%06x",
|
elprintf_sh2(sh2, EL_32XP, "peri w32 [%08x] %08x @%06x",
|
||||||
a, d, sh2_pc(sh2));
|
a, d, sh2_pc(sh2));
|
||||||
|
|
||||||
|
@ -485,17 +480,17 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
|
||||||
if (!(dmac->dmaor & DMA_DME))
|
if (!(dmac->dmaor & DMA_DME))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
DRC_SAVE_SR(sh2);
|
||||||
if ((dmac->chan[0].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
|
if ((dmac->chan[0].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
|
||||||
dmac_trigger(sh2, &dmac->chan[0]);
|
dmac_trigger(sh2, &dmac->chan[0]);
|
||||||
if ((dmac->chan[1].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
|
if ((dmac->chan[1].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
|
||||||
dmac_trigger(sh2, &dmac->chan[1]);
|
dmac_trigger(sh2, &dmac->chan[1]);
|
||||||
|
DRC_RESTORE_SR(sh2);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
if ((a & 0x1c0) == 0x140)
|
|
||||||
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DRC_RESTORE_SR(sh2);
|
if ((a & 0x1c0) == 0x140)
|
||||||
|
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 32X specific */
|
/* 32X specific */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue