mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
cd sync improvements, part2
This commit is contained in:
parent
bc3c13d329
commit
08769494e8
6 changed files with 159 additions and 161 deletions
178
pico/cd/memory.c
178
pico/cd/memory.c
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue