cd sync improvements, part2

This commit is contained in:
notaz 2013-08-27 03:39:38 +03:00
parent bc3c13d329
commit 08769494e8
6 changed files with 159 additions and 161 deletions

View file

@ -65,32 +65,23 @@ void PicoWriteS68k16_dec_m1b1(u32 a, u32 d);
void PicoWriteS68k16_dec_m2b1(u32 a, u32 d); void PicoWriteS68k16_dec_m2b1(u32 a, u32 d);
#endif #endif
static void remap_prg_window(void); static void remap_prg_window(int r3);
static void remap_word_ram(int r3); static void remap_word_ram(int r3);
// poller detection // poller detection
#define POLL_LIMIT 16 #define POLL_LIMIT 16
#define POLL_CYCLES 124 #define POLL_CYCLES 124
unsigned int s68k_poll_adclk, s68k_poll_cnt;
void m68k_comm_check(u32 a) u32 m68k_comm_check(u32 a, u32 d)
{ {
pcd_sync_s68k(SekCyclesDone()); pcd_sync_s68k(SekCyclesDone(), 0);
/*if (Pico_mcd->m.m68k_comm_dirty & (1 << a/2)) {
Pico_mcd->m.m68k_comm_dirty &= ~(1 << a/2);
Pico_mcd->m.m68k_poll_a = Pico_mcd->m.m68k_poll_cnt = 0;
return;
}
if (a != Pico_mcd->m.m68k_poll_a) { if (a != Pico_mcd->m.m68k_poll_a) {
Pico_mcd->m.m68k_poll_a = a; Pico_mcd->m.m68k_poll_a = a;
Pico_mcd->m.m68k_poll_cnt = 0; Pico_mcd->m.m68k_poll_cnt = 0;
return; return d;
} }
if (++Pico_mcd->m.m68k_poll_cnt > 5) Pico_mcd->m.m68k_poll_cnt++;
SekCyclesBurnRun(122); return d;
elprintf(EL_CDPOLL, "m68k poll [%02x] %d %u", a,
Pico_mcd->m.m68k_poll_cnt, SekCyclesDone());*/
} }
#ifndef _ASM_CD_MEMORY_C #ifndef _ASM_CD_MEMORY_C
@ -104,10 +95,9 @@ static u32 m68k_reg_read16(u32 a)
d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens
goto end; goto end;
case 2: case 2:
m68k_comm_check(a);
d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7); d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);
elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc); elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc);
goto end; goto end_comm;
case 4: case 4:
d = Pico_mcd->s68k_regs[4]<<8; d = Pico_mcd->s68k_regs[4]<<8;
goto end; goto end;
@ -131,16 +121,17 @@ static u32 m68k_reg_read16(u32 a)
if (a < 0x30) { if (a < 0x30) {
// comm flag/cmd/status (0xE-0x2F) // comm flag/cmd/status (0xE-0x2F)
m68k_comm_check(a);
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1]; d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
goto end; goto end_comm;
} }
elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a); elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);
end: end:
return d; return d;
end_comm:
return m68k_comm_check(a, d);
} }
#endif #endif
@ -152,19 +143,24 @@ void m68k_reg_write8(u32 a, u32 d)
u32 dold; u32 dold;
a &= 0x3f; a &= 0x3f;
Pico_mcd->m.m68k_poll_a = 0; Pico_mcd->m.m68k_poll_a =
Pico_mcd->m.m68k_poll_cnt = 0;
switch (a) { switch (a) {
case 0: case 0:
d &= 1; d &= 1;
if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { elprintf(EL_INTS, "m68k: s68k irq 2"); SekInterruptS68k(2); } if (d && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN2)) {
elprintf(EL_INTS, "m68k: s68k irq 2");
pcd_sync_s68k(SekCyclesDone(), 0);
SekInterruptS68k(2);
}
return; return;
case 1: case 1:
d &= 3; d &= 3;
elprintf(EL_CDREGS, "d m.busreq %u %u", d, Pico_mcd->m.busreq); elprintf(EL_CDREGS, "d m.busreq %u %u", d, Pico_mcd->m.busreq);
if (d == Pico_mcd->m.busreq) if (d == Pico_mcd->m.busreq)
return; return;
pcd_sync_s68k(SekCyclesDone()); pcd_sync_s68k(SekCyclesDone(), 0);
if ((Pico_mcd->m.busreq ^ d) & 1) { if ((Pico_mcd->m.busreq ^ d) & 1) {
elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1)); elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1));
@ -177,7 +173,7 @@ void m68k_reg_write8(u32 a, u32 d)
} }
if ((Pico_mcd->m.busreq ^ d) & 2) { if ((Pico_mcd->m.busreq ^ d) & 2) {
elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1); elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1);
remap_prg_window(); remap_prg_window(Pico_mcd->s68k_regs[3]);
} }
Pico_mcd->m.busreq = d; Pico_mcd->m.busreq = d;
return; return;
@ -194,24 +190,19 @@ void m68k_reg_write8(u32 a, u32 d)
if (dold & 4) { // 1M mode if (dold & 4) { // 1M mode
d ^= 2; // writing 0 to DMNA actually sets it, 1 does nothing d ^= 2; // writing 0 to DMNA actually sets it, 1 does nothing
} else { } else {
if ((d ^ dold) & d & 2) { // DMNA is being set if ((d ^ dold) & d & 2) { // DMNA is being set
dold &= ~1; // return word RAM to s68k dold &= ~1; // return word RAM to s68k
/* Silpheed hack: bset(w3), r3, btst, bne, r3 */ /* Silpheed hack: bset(w3), r3, btst, bne, r3 */
SekEndRun(20+16+10+12+16); SekEndRun(20+16+10+12+16);
} }
} }
Pico_mcd->s68k_regs[3] = (d & 0xc2) | (dold & 0x1f); d = (d & 0xc2) | (dold & 0x1f);
if ((d ^ dold) & 0xc0) { if ((d ^ dold) & 0xc0) {
elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3)); elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i",
remap_prg_window(); (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));
remap_prg_window(d);
} }
#ifdef USE_POLL_DETECT goto write_comm;
if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
}
#endif
return;
case 6: case 6:
Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer
return; return;
@ -220,34 +211,30 @@ void m68k_reg_write8(u32 a, u32 d)
elprintf(EL_CDREGS, "hint vector set to %04x%04x", elprintf(EL_CDREGS, "hint vector set to %04x%04x",
((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]); ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);
return; return;
case 0xf: case 0x0f:
d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case) d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)
case 0xe: a = 0x0e;
if (d != Pico_mcd->s68k_regs[0xe]) { case 0x0e:
pcd_sync_s68k(SekCyclesDone()); goto write_comm;
Pico_mcd->s68k_regs[0xe] = d;
}
#ifdef USE_POLL_DETECT
if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
}
#endif
return;
} }
if ((a&0xf0) == 0x10) { if ((a&0xf0) == 0x10)
Pico_mcd->s68k_regs[a] = d; goto write_comm;
#ifdef USE_POLL_DETECT
if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
}
#endif
return;
}
elprintf(EL_UIO, "m68k FIXME: invalid write? [%02x] %02x", a, d); elprintf(EL_UIO, "m68k FIXME: invalid write? [%02x] %02x", a, d);
return;
write_comm:
if (d == Pico_mcd->s68k_regs[a])
return;
Pico_mcd->s68k_regs[a] = d;
pcd_sync_s68k(SekCyclesDone(), 0);
if (Pico_mcd->m.s68k_poll_a == a && Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0);
Pico_mcd->m.s68k_poll_a = 0;
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
}
} }
#ifndef _ASM_CD_MEMORY_C #ifndef _ASM_CD_MEMORY_C
@ -256,24 +243,26 @@ static
u32 s68k_poll_detect(u32 a, u32 d) u32 s68k_poll_detect(u32 a, u32 d)
{ {
#ifdef USE_POLL_DETECT #ifdef USE_POLL_DETECT
// needed mostly for Cyclone, which doesn't always check it's cycle counter u32 cycles, cnt = 0;
if (SekIsStoppedS68k()) return d; if (SekIsStoppedS68k())
// polling detection return d;
if (a == (s68k_poll_adclk&0xff)) {
unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8); cycles = SekCyclesDoneS68k();
if (a == Pico_mcd->m.s68k_poll_a) {
u32 clkdiff = cycles - Pico_mcd->m.s68k_poll_clk;
if (clkdiff <= POLL_CYCLES) { if (clkdiff <= POLL_CYCLES) {
s68k_poll_cnt++; cnt = Pico_mcd->m.s68k_poll_cnt + 1;
//printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt); //printf("-- diff: %u, cnt = %i\n", clkdiff, cnt);
if (s68k_poll_cnt > POLL_LIMIT) { if (Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(1); SekSetStopS68k(1);
elprintf(EL_CDPOLL, "s68k poll detected @ %06x, a=%02x", SekPcS68k, a); elprintf(EL_CDPOLL, "s68k poll detected @ %06x, a=%02x",
SekPcS68k, a);
} }
s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;
return d;
} }
} }
s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; Pico_mcd->m.s68k_poll_a = a;
s68k_poll_cnt = 0; Pico_mcd->m.s68k_poll_clk = cycles;
Pico_mcd->m.s68k_poll_cnt = cnt;
#endif #endif
return d; return d;
} }
@ -384,7 +373,7 @@ void s68k_reg_write8(u32 a, u32 d)
if (d & 1) if (d & 1)
d &= ~2; // DMNA clears d &= ~2; // DMNA clears
} }
break; goto write_comm;
} }
case 4: case 4:
elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7); elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7);
@ -405,9 +394,12 @@ void s68k_reg_write8(u32 a, u32 d)
// does this also reset internal 384 cycle counter? // does this also reset internal 384 cycle counter?
Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k(); Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();
return; return;
case 0xe: case 0x0e:
d &= 0xff;
d = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair d = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair
break; a = 0x0f;
case 0x0f:
goto write_comm;
case 0x31: // 384 cycle int3 timer case 0x31: // 384 cycle int3 timer
d &= 0xff; d &= 0xff;
elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d); elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d);
@ -444,16 +436,23 @@ void s68k_reg_write8(u32 a, u32 d)
return; return;
} }
if ((a&0x1f0) == 0x20)
goto write_comm;
if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42)) if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))
{ {
elprintf(EL_UIO, "s68k FIXME: invalid write @ %02x?", a); elprintf(EL_UIO, "s68k FIXME: invalid write @ %02x?", a);
return; return;
} }
if (a < 0x30)
Pico_mcd->m.m68k_comm_dirty |= (1 << a/2);
Pico_mcd->s68k_regs[a] = (u8) d; Pico_mcd->s68k_regs[a] = (u8) d;
return;
write_comm:
Pico_mcd->s68k_regs[a] = (u8) d;
if (Pico_mcd->m.m68k_poll_cnt)
SekEndRunS68k(0);
Pico_mcd->m.m68k_poll_cnt = 0;
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -611,20 +610,10 @@ static void PicoWriteM68k16_io(u32 a, u32 d)
{ {
if ((a & 0xff00) == 0x2000) { // a12000 - a120ff if ((a & 0xff00) == 0x2000) { // a12000 - a120ff
elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc); elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);
/* TODO FIXME?
if (a == 0xe) { // special case, 2 byte writes would be handled differently
Pico_mcd->s68k_regs[0xe] = d >> 8;
#ifdef USE_POLL_DETECT
if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
}
#endif
return;
}
*/
m68k_reg_write8(a, d >> 8); m68k_reg_write8(a, d >> 8);
m68k_reg_write8(a + 1, d & 0xff); if ((a & 0x3e) != 0x0e) // special case
m68k_reg_write8(a + 1, d & 0xff);
return; return;
} }
@ -965,11 +954,11 @@ static const void *s68k_dec_write16[2][4] = {
// ----------------------------------------------------------------- // -----------------------------------------------------------------
static void remap_prg_window(void) static void remap_prg_window(int r3)
{ {
// PRG RAM // PRG RAM
if (Pico_mcd->m.busreq & 2) { if (Pico_mcd->m.busreq & 2) {
void *bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3] >> 6]; void *bank = Pico_mcd->prg_ram_b[r3 >> 6];
cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0); cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0);
} }
else { else {
@ -1034,7 +1023,7 @@ void pcd_state_loaded_mem(void)
if (r3 & 4) // 1M mode? if (r3 & 4) // 1M mode?
wram_2M_to_1M(Pico_mcd->word_ram2M); wram_2M_to_1M(Pico_mcd->word_ram2M);
remap_word_ram(r3); remap_word_ram(r3);
remap_prg_window(); remap_prg_window(r3);
// restore hint vector // restore hint vector
*(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector; *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;
@ -1144,9 +1133,6 @@ PICO_INTERNAL void PicoMemSetupCD(void)
#ifdef EMU_M68K #ifdef EMU_M68K
m68k_mem_setup_cd(); m68k_mem_setup_cd();
#endif #endif
// m68k_poll_addr = m68k_poll_cnt = 0;
s68k_poll_adclk = s68k_poll_cnt = 0;
} }

View file

@ -53,7 +53,6 @@
.extern m68k_reg_write8 .extern m68k_reg_write8
.extern s68k_reg_read16 .extern s68k_reg_read16
.extern s68k_reg_write8 .extern s68k_reg_write8
.extern s68k_poll_adclk
.extern s68k_poll_detect .extern s68k_poll_detect
.extern gfx_cd_read .extern gfx_cd_read
.extern gfx_cd_write16 .extern gfx_cd_write16
@ -62,6 +61,7 @@
.extern PicoRead16_io .extern PicoRead16_io
.extern PicoWrite8_io .extern PicoWrite8_io
.extern PicoWrite16_io .extern PicoWrite16_io
.extern m68k_comm_check
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -174,17 +174,16 @@ m_m68k_read8_r02:
add r1, r1, #0x110000 add r1, r1, #0x110000
ldrb r0, [r1, #2] ldrb r0, [r1, #2]
bx lr bx lr
m_m68k_read8_r03: m_m68k_read8_r03: @ FIXME: sync with C
add r1, r1, #0x110000 add r2, r1, #0x110000
ldrb r0, [r1, #3] ldrb r1, [r2, #3]
add r1, r1, #0x002200 add r2, r2, #0x002200
ldr r1, [r1, #4] ldr r2, [r2, #4]
and r0, r0, #0xc7 and r1, r1, #0xc7
tst r1, #2 @ DMNA pending? tst r2, #2 @ DMNA pending?
bxeq lr bicne r1, r1, #1
bic r0, r0, #1 orrne r1, r1, #2
orr r0, r0, #2 b m68k_comm_check
bx lr
m_m68k_read8_r04: m_m68k_read8_r04:
add r1, r1, #0x110000 add r1, r1, #0x110000
ldrb r0, [r1, #4] ldrb r0, [r1, #4]
@ -216,15 +215,12 @@ m_m68k_read8_r0d:
mov r0, r0, lsr #16 mov r0, r0, lsr #16
bx lr bx lr
m_m68k_read8_hi: m_m68k_read8_hi:
push {r0,r1,lr}
bl m68k_comm_check
pop {r0,r1,lr}
cmp r0, #0x30 cmp r0, #0x30
movge r0, #0 movge r0, #0
bxeq lr bxeq lr
add r1, r1, #0x110000 add r1, r1, #0x110000
ldrb r0, [r1, r0] ldrb r1, [r1, r0]
bx lr b m68k_comm_check
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -273,19 +269,18 @@ m_m68k_read16_r00:
and r0, r0, #0x04000000 @ we need irq2 mask state and r0, r0, #0x04000000 @ we need irq2 mask state
orr r0, r1, r0, lsr #11 orr r0, r1, r0, lsr #11
bx lr bx lr
m_m68k_read16_r02: m_m68k_read16_r02: @ FIXME: out of sync from C
add r1, r1, #0x110000 add r3, r1, #0x110000
ldrb r0, [r1, #2] ldrb r1, [r3, #2]
ldrb r2, [r1, #3] ldrb r2, [r3, #3]
add r1, r1, #0x002200 add r3, r3, #0x002200
ldr r1, [r1, #4] ldr r3, [r3, #4]
and r2, r2, #0xc7 and r2, r2, #0xc7
orr r0, r2, r0, lsl #8 orr r1, r2, r1, lsl #8
tst r1, #2 @ DMNA pending? tst r3, #2 @ DMNA pending?
bxeq lr bicne r1, r1, #1
bic r0, r0, #1 orrne r1, r1, #2
orr r0, r0, #2 b m68k_comm_check
bx lr
m_m68k_read16_r04: m_m68k_read16_r04:
add r1, r1, #0x110000 add r1, r1, #0x110000
ldrb r0, [r1, #4] ldrb r0, [r1, #4]
@ -309,10 +304,10 @@ m_m68k_read16_hi:
ldrlth r1, [r1, r0] ldrlth r1, [r1, r0]
movge r0, #0 movge r0, #0
bxge lr bxge lr
mov r0, r1, lsr #8 mov r2, r1, lsr #8
and r1, r1, #0xff and r1, r1, #0xff
orr r0, r0, r1, lsl #8 orr r1, r2, r1, lsl #8
bx lr b m68k_comm_check
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -380,22 +375,8 @@ m_m68k_write16_regs:
b m68k_reg_write8 b m68k_reg_write8
m_m68k_write16_regs_spec: @ special case m_m68k_write16_regs_spec: @ special case
ldr r2, =(Pico+0x22200)
ldr r3, =s68k_poll_adclk
mov r0, #0x110000
ldr r2, [r2]
add r0, r0, #0x00000e
mov r1, r1, lsr #8 mov r1, r1, lsr #8
strb r1, [r2, r0] @ if (a == 0xe) s68k_regs[0x0e] = d >> 8; b m68k_reg_write8
ldr r2, [r3]
mov r1, #0
and r2, r2, #0xfe
cmp r2, #0x0e
bxne lr
ldr r0, =PicoCpuCS68k
str r1, [r0, #0x58] @ push s68k out of stopped state
str r1, [r3]
bx lr
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

View file

@ -219,19 +219,20 @@ static void pcd_run_events(unsigned int until)
oldest, event_time_next); oldest, event_time_next);
} }
void pcd_sync_s68k(unsigned int m68k_target) int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync)
{ {
#define now SekCycleCntS68k #define now SekCycleCntS68k
unsigned int s68k_target = unsigned int s68k_target =
(unsigned long long)m68k_target * m68k_cycle_mult >> 16; (unsigned long long)m68k_target * m68k_cycle_mult >> 16;
unsigned int target; unsigned int target;
elprintf(EL_CD, "s68k sync to %u/%u", m68k_target, s68k_target); elprintf(EL_CD, "s68k sync to %u, %u->%u",
m68k_target, now, s68k_target);
if ((Pico_mcd->m.busreq & 3) != 1) { /* busreq/reset */ if ((Pico_mcd->m.busreq & 3) != 1) { /* busreq/reset */
SekCycleCntS68k = SekCycleAimS68k = s68k_target; SekCycleCntS68k = SekCycleAimS68k = s68k_target;
pcd_run_events(m68k_target); pcd_run_events(m68k_target);
return; return 0;
} }
while (CYCLES_GT(s68k_target, now)) { while (CYCLES_GT(s68k_target, now)) {
@ -243,13 +244,36 @@ void pcd_sync_s68k(unsigned int m68k_target)
target = event_time_next; target = event_time_next;
SekRunS68k(target); SekRunS68k(target);
if (m68k_poll_sync && Pico_mcd->m.m68k_poll_cnt == 0)
break;
} }
return s68k_target - now;
#undef now #undef now
} }
static void SekSyncM68k(void);
static void pcd_run_cpus(int m68k_cycles)
{
SekCycleAim += m68k_cycles;
if (Pico_mcd->m.m68k_poll_cnt >= 16 && !SekShouldInterrupt()) {
int s68k_left = pcd_sync_s68k(SekCycleAim, 1);
if (s68k_left <= 0) {
elprintf(EL_CDPOLL, "m68k poll [%02x] %d @%06x",
Pico_mcd->m.m68k_poll_a, Pico_mcd->m.m68k_poll_cnt, SekPc);
SekCycleCnt = SekCycleAim;
return;
}
SekCycleCnt = SekCycleAim - (s68k_left * 40220 >> 16);
}
SekSyncM68k();
}
#define PICO_CD #define PICO_CD
#define CPUS_RUN(m68k_cycles) \ #define CPUS_RUN(m68k_cycles) \
SekRunM68k(m68k_cycles) pcd_run_cpus(m68k_cycles)
#include "../pico_cmn.c" #include "../pico_cmn.c"

View file

@ -22,13 +22,13 @@
SekRunM68k(m68k_cycles) SekRunM68k(m68k_cycles)
#endif #endif
static __inline void SekRunM68k(int cyc) // sync m68k to SekCycleAim
static void SekSyncM68k(void)
{ {
int cyc_do; int cyc_do;
pprof_start(m68k); pprof_start(m68k);
pevt_log_m68k_o(EVT_RUN_START); pevt_log_m68k_o(EVT_RUN_START);
SekCycleAim += cyc;
while ((cyc_do = SekCycleAim - SekCycleCnt) > 0) { while ((cyc_do = SekCycleAim - SekCycleCnt) > 0) {
SekCycleCnt += cyc_do; SekCycleCnt += cyc_do;
@ -50,6 +50,12 @@ static __inline void SekRunM68k(int cyc)
pprof_end(m68k); pprof_end(m68k);
} }
static inline void SekRunM68k(int cyc)
{
SekCycleAim += cyc;
SekSyncM68k();
}
static int PicoFrameHints(void) static int PicoFrameHints(void)
{ {
struct PicoVideo *pv=&Pico.video; struct PicoVideo *pv=&Pico.video;
@ -142,7 +148,7 @@ static int PicoFrameHints(void)
if (ym2612.dacen && PsndDacLine <= y) if (ym2612.dacen && PsndDacLine <= y)
PsndDoDAC(y); PsndDoDAC(y);
#ifdef PICO_CD #ifdef PICO_CD
pcd_sync_s68k(cycles); pcd_sync_s68k(cycles, 0);
#endif #endif
#ifdef PICO_32X #ifdef PICO_32X
p32x_sync_sh2s(cycles); p32x_sync_sh2s(cycles);
@ -210,7 +216,7 @@ static int PicoFrameHints(void)
} }
#ifdef PICO_CD #ifdef PICO_CD
pcd_sync_s68k(cycles); pcd_sync_s68k(cycles, 0);
#endif #endif
#ifdef PICO_32X #ifdef PICO_32X
p32x_sync_sh2s(cycles); p32x_sync_sh2s(cycles);
@ -262,7 +268,7 @@ static int PicoFrameHints(void)
PsndDoDAC(lines-1); PsndDoDAC(lines-1);
#ifdef PICO_CD #ifdef PICO_CD
pcd_sync_s68k(cycles); pcd_sync_s68k(cycles, 0);
#endif #endif
#ifdef PICO_32X #ifdef PICO_32X
p32x_sync_sh2s(cycles); p32x_sync_sh2s(cycles);

View file

@ -49,7 +49,7 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } } #define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
#define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1) #define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1)
#define SekIsStoppedS68k() (PicoCpuCS68k.state_flags&1) #define SekIsStoppedS68k() (PicoCpuCS68k.state_flags&1)
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7)) #define SekShouldInterrupt() (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))
#define SekInterrupt(i) PicoCpuCM68k.irq=i #define SekInterrupt(i) PicoCpuCM68k.irq=i
#define SekIrqLevel PicoCpuCM68k.irq #define SekIrqLevel PicoCpuCM68k.irq
@ -77,7 +77,7 @@ extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
} }
#define SekIsStoppedM68k() (PicoCpuFM68k.execinfo&FM68K_HALTED) #define SekIsStoppedM68k() (PicoCpuFM68k.execinfo&FM68K_HALTED)
#define SekIsStoppedS68k() (PicoCpuFS68k.execinfo&FM68K_HALTED) #define SekIsStoppedS68k() (PicoCpuFS68k.execinfo&FM68K_HALTED)
#define SekShouldInterrupt fm68k_would_interrupt() #define SekShouldInterrupt() fm68k_would_interrupt()
#define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq #define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq
#define SekIrqLevel PicoCpuFM68k.interrupts[0] #define SekIrqLevel PicoCpuFM68k.interrupts[0]
@ -106,7 +106,7 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
} }
#define SekIsStoppedM68k() (PicoCpuMM68k.stopped==STOP_LEVEL_STOP) #define SekIsStoppedM68k() (PicoCpuMM68k.stopped==STOP_LEVEL_STOP)
#define SekIsStoppedS68k() (PicoCpuMS68k.stopped==STOP_LEVEL_STOP) #define SekIsStoppedS68k() (PicoCpuMS68k.stopped==STOP_LEVEL_STOP)
#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK) #define SekShouldInterrupt() (CPU_INT_LEVEL > FLAG_INT_MASK)
#define SekInterrupt(irq) { \ #define SekInterrupt(irq) { \
void *oldcontext = m68ki_cpu_p; \ void *oldcontext = m68ki_cpu_p; \
@ -389,10 +389,11 @@ struct mcd_misc
unsigned char s68k_pend_ints; unsigned char s68k_pend_ints;
unsigned int state_flags; // 04 unsigned int state_flags; // 04
unsigned int stopwatch_base_c; unsigned int stopwatch_base_c;
unsigned int m68k_comm_dirty;
unsigned short m68k_poll_a; unsigned short m68k_poll_a;
unsigned short m68k_poll_cnt; unsigned short m68k_poll_cnt;
unsigned int pad; unsigned short s68k_poll_a;
unsigned short s68k_poll_cnt;
unsigned int s68k_poll_clk;
unsigned char bcram_reg; // 18: battery-backed RAM cart register unsigned char bcram_reg; // 18: battery-backed RAM cart register
unsigned char pad2; unsigned char pad2;
unsigned short pad3; unsigned short pad3;
@ -631,7 +632,7 @@ extern unsigned int pcd_event_times[PCD_EVENT_COUNT];
void pcd_event_schedule(unsigned int now, enum pcd_event event, int after); void pcd_event_schedule(unsigned int now, enum pcd_event event, int after);
void pcd_event_schedule_s68k(enum pcd_event event, int after); void pcd_event_schedule_s68k(enum pcd_event event, int after);
unsigned int pcd_cycles_m68k_to_s68k(unsigned int c); unsigned int pcd_cycles_m68k_to_s68k(unsigned int c);
void pcd_sync_s68k(unsigned int m68k_target); int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync);
void pcd_state_loaded(void); void pcd_state_loaded(void);
// pico/pico.c // pico/pico.c
@ -935,9 +936,9 @@ void pevt_log(unsigned int cycles, enum evt_cpu c, enum evt e);
void pevt_dump(void); void pevt_dump(void);
#define pevt_log_m68k(e) \ #define pevt_log_m68k(e) \
pevt_log(SekCyclesDoneT(), EVT_M68K, e) pevt_log(SekCyclesDone(), EVT_M68K, e)
#define pevt_log_m68k_o(e) \ #define pevt_log_m68k_o(e) \
pevt_log(SekCyclesDoneT2(), EVT_M68K, e) pevt_log(SekCyclesDone(), EVT_M68K, e)
#define pevt_log_sh2(sh2, e) \ #define pevt_log_sh2(sh2, e) \
pevt_log(sh2_cycles_done_m68k(sh2), EVT_MSH2 + (sh2)->is_slave, e) pevt_log(sh2_cycles_done_m68k(sh2), EVT_MSH2 + (sh2)->is_slave, e)
#define pevt_log_sh2_o(sh2, e) \ #define pevt_log_sh2_o(sh2, e) \

View file

@ -423,7 +423,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
update_irq: update_irq:
#ifndef EMU_CORE_DEBUG #ifndef EMU_CORE_DEBUG
// update IRQ level // update IRQ level
if (!SekShouldInterrupt) // hack if (!SekShouldInterrupt()) // hack
{ {
int lines, pints, irq=0; int lines, pints, irq=0;
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10); lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);