Pico32x.regs[6 / 2] &= ~P32XS_68S; // transfer complete
if (dmac0->tcr0 == 0)
dmac0->chcr0 |= 2; // DMA has ended normally
- p32x_poll_undetect(&m68k_poll, 0);
}
// ------------------------------------------------------------------
if ((a & 0x30) == 0x20)
return sh2_comm_faker(a);
#else
- if (p32x_poll_detect(&m68k_poll, a, SekPc, 0)) {
+ if ((a & 0x30) == 0x20 && p32x_poll_detect(&m68k_poll, a, SekPc, 0)) {
SekEndRun(16);
}
#endif
if (a == 0x24 || a == 0x26)
return sh2_comm_faker(a);
#endif
+ if ((a & 0x30) == 0x30)
+ return p32x_pwm_read16(a);
return Pico32x.regs[a / 2];
}
u16 *r = Pico32x.regs;
a &= 0x3f;
+ // for things like bset on comm port
+ m68k_poll.cnt = 0;
+
if (a == 1 && !(r[0] & 1)) {
r[0] |= 1;
Pico32xStartup();
}
break;
case 7: // DREQ ctl
- r[6 / 2] = (r[6 / 2] & P32XS_FULL) | (d & (P32XS_68S|P32XS_RV));
+ r[6 / 2] = (r[6 / 2] & P32XS_FULL) | (d & (P32XS_68S|P32XS_DMA|P32XS_RV));
break;
}
}
u16 *r = Pico32x.regs;
a &= 0x3e;
- // for write loops with FIFO checks..
+ // for things like bset on comm port
m68k_poll.cnt = 0;
switch (a) {
SekEndRun(16);
return;
}
+ // PWM
+ else if ((a & 0x30) == 0x30) {
+ p32x_pwm_write16(a, d);
+ return;
+ }
p32x_reg_write8(a + 1, d);
}
return r[a / 2];
}
- // DREQ src, dst; comm port
- if ((a & 0x38) == 0x08 || (a & 0x30) == 0x20)
+ // DREQ src, dst
+ if ((a & 0x38) == 0x08)
+ return r[a / 2];
+ // comm port
+ if ((a & 0x30) == 0x20) {
+ if (p32x_poll_detect(&sh2_poll[cpuid], a, sh2_pc(cpuid), 0))
+ ash2_end_run(8);
return r[a / 2];
+ }
+ if ((a & 0x30) == 0x30) {
+ sh2_poll[cpuid].cnt = 0;
+ return p32x_pwm_read16(a);
+ }
return 0;
}
{
a &= 0xfe;
+ // comm
if ((a & 0x30) == 0x20 && Pico32x.regs[a/2] != d) {
Pico32x.regs[a / 2] = d;
p32x_poll_undetect(&m68k_poll, 0);
p32x_poll_undetect(&sh2_poll[cpuid ^ 1], 0);
return;
}
+ // PWM
+ else if ((a & 0x30) == 0x30) {
+ p32x_pwm_write16(a, d);
+ return;
+ }
switch (a) {
case 0x14: Pico32x.sh2irqs &= ~P32XI_VRES; goto irls;
{
u32 d;
a &= 0x1fc;
- d = Pico32xMem->sh2_peri_regs[0][a / 4];
+ d = Pico32xMem->sh2_peri_regs[id][a / 4];
- elprintf(EL_32X, "%csh2 peri r32 [%08x] %08x @%06x", id ? 's' : 'm', a, d, sh2_pc(id));
+ elprintf(EL_32X, "%csh2 peri r32 [%08x] %08x @%06x", id ? 's' : 'm', a | ~0x1ff, d, sh2_pc(id));
return d;
}
static void sh2_peripheral_write(u32 a, u32 d, int id)
{
- unsigned int *r = Pico32xMem->sh2_peri_regs[0];
+ unsigned int *r = Pico32xMem->sh2_peri_regs[id];
elprintf(EL_32X, "%csh2 peri w32 [%08x] %08x @%06x", id ? 's' : 'm', a, d, sh2_pc(id));
a &= 0x1fc;
r[a / 4] = d;
+ switch (a) {
+ // division unit:
+ case 0x104: // DVDNT: divident L, starts divide
+ elprintf(EL_32X, "%csh2 divide %08x / %08x", id ? 's' : 'm', d, r[0x100 / 4]);
+ if (r[0x100 / 4]) {
+ r[0x118 / 4] = r[0x110 / 4] = d % r[0x100 / 4];
+ r[0x11c / 4] = r[0x114 / 4] = d / r[0x100 / 4];
+ }
+ break;
+ case 0x114:
+ elprintf(EL_32X, "%csh2 divide %08x%08x / %08x @%08x",
+ id ? 's' : 'm', r[0x110 / 4], d, r[0x100 / 4], sh2_pc(id));
+ if (r[0x100 / 4]) {
+ long long divident = (long long)r[0x110 / 4] << 32 | d;
+ // XXX: undocumented mirroring to 0x118,0x11c?
+ r[0x118 / 4] = r[0x110 / 4] = divident % r[0x100 / 4];
+ r[0x11c / 4] = r[0x114 / 4] = divident / r[0x100 / 4];
+ }
+ break;
+ }
+
if ((a == 0x1b0 || a == 0x18c) && (dmac0->chcr0 & 3) == 1 && (dmac0->dmaor & 1)) {
elprintf(EL_32X, "sh2 DMA %08x -> %08x, cnt %d, chcr %04x @%06x",
dmac0->sar0, dmac0->dar0, dmac0->tcr0, dmac0->chcr0, sh2_pc(id));
u32 p32x_sh2_read8(u32 a, int id)
{
- int pd_vdp = 0;
u32 d = 0;
if (id == 0 && a < sizeof(Pico32xMem->sh2_rom_m))
if ((a & ~0xfff) == 0xc0000000)
return Pico32xMem->data_array[id][(a & 0xfff) ^ 1];
+ if ((a & 0x0ffe0000) == 0x04000000) {
+ u8 *dram = (u8 *)Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1];
+ return dram[(a & 0x1ffff) ^ 1];
+ }
+
if ((a & 0x0fffff00) == 0x4000) {
d = p32x_sh2reg_read16(a, id);
- goto out_pd;
+ goto out_16to8;
}
if ((a & 0x0fffff00) == 0x4100) {
d = p32x_vdp_read16(a);
- pd_vdp = 1;
- goto out_pd;
+ if (p32x_poll_detect(&sh2_poll[id], a, sh2_pc(id), 1))
+ ash2_end_run(8);
+ goto out_16to8;
}
if ((a & 0x0fffff00) == 0x4200) {
id ? 's' : 'm', a, d, sh2_pc(id));
return d;
-out_pd:
- if (p32x_poll_detect(&sh2_poll[id], a, sh2_pc(id), pd_vdp))
- ash2_end_run(8);
-
out_16to8:
if (a & 1)
d &= 0xff;
u32 p32x_sh2_read16(u32 a, int id)
{
- int pd_vdp = 0;
u32 d = 0;
if (id == 0 && a < sizeof(Pico32xMem->sh2_rom_m))
if ((a & ~0xfff) == 0xc0000000)
return ((u16 *)Pico32xMem->data_array[id])[(a & 0xfff) / 2];
+ if ((a & 0x0ffe0000) == 0x04000000)
+ return Pico32xMem->dram[(Pico32x.vdp_regs[0x0a/2] & P32XV_FS) ^ 1][(a & 0x1ffff) / 2];
+
if ((a & 0x0fffff00) == 0x4000) {
d = p32x_sh2reg_read16(a, id);
- goto out_pd;
+ goto out;
}
if ((a & 0x0fffff00) == 0x4100) {
d = p32x_vdp_read16(a);
- pd_vdp = 1;
- goto out_pd;
+ if (p32x_poll_detect(&sh2_poll[id], a, sh2_pc(id), 1))
+ ash2_end_run(8);
+ goto out;
}
if ((a & 0x0fffff00) == 0x4200) {
id ? 's' : 'm', a, d, sh2_pc(id));
return d;
-out_pd:
- if (p32x_poll_detect(&sh2_poll[id], a, sh2_pc(id), pd_vdp))
- ash2_end_run(8);
-
out:
elprintf(EL_32X, "%csh2 r16 [%08x] %04x @%06x",
id ? 's' : 'm', a, d, sh2_pc(id));