mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
cd sync improvements
This commit is contained in:
parent
add51c49ec
commit
bc3c13d329
5 changed files with 65 additions and 22 deletions
|
@ -73,6 +73,26 @@ static void remap_word_ram(int r3);
|
|||
#define POLL_CYCLES 124
|
||||
unsigned int s68k_poll_adclk, s68k_poll_cnt;
|
||||
|
||||
void m68k_comm_check(u32 a)
|
||||
{
|
||||
pcd_sync_s68k(SekCyclesDone());
|
||||
/*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) {
|
||||
Pico_mcd->m.m68k_poll_a = a;
|
||||
Pico_mcd->m.m68k_poll_cnt = 0;
|
||||
return;
|
||||
}
|
||||
if (++Pico_mcd->m.m68k_poll_cnt > 5)
|
||||
SekCyclesBurnRun(122);
|
||||
|
||||
elprintf(EL_CDPOLL, "m68k poll [%02x] %d %u", a,
|
||||
Pico_mcd->m.m68k_poll_cnt, SekCyclesDone());*/
|
||||
}
|
||||
|
||||
#ifndef _ASM_CD_MEMORY_C
|
||||
static u32 m68k_reg_read16(u32 a)
|
||||
{
|
||||
|
@ -84,6 +104,7 @@ 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
|
||||
goto end;
|
||||
case 2:
|
||||
m68k_comm_check(a);
|
||||
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);
|
||||
goto end;
|
||||
|
@ -110,6 +131,7 @@ static u32 m68k_reg_read16(u32 a)
|
|||
|
||||
if (a < 0x30) {
|
||||
// comm flag/cmd/status (0xE-0x2F)
|
||||
m68k_comm_check(a);
|
||||
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
|
||||
goto end;
|
||||
}
|
||||
|
@ -130,6 +152,8 @@ void m68k_reg_write8(u32 a, u32 d)
|
|||
u32 dold;
|
||||
a &= 0x3f;
|
||||
|
||||
Pico_mcd->m.m68k_poll_a = 0;
|
||||
|
||||
switch (a) {
|
||||
case 0:
|
||||
d &= 1;
|
||||
|
@ -137,18 +161,24 @@ void m68k_reg_write8(u32 a, u32 d)
|
|||
return;
|
||||
case 1:
|
||||
d &= 3;
|
||||
if (!(d&1)) Pico_mcd->m.state_flags |= 1; // reset pending, needed to be sure we fetch the right vectors on reset
|
||||
if ( (Pico_mcd->m.busreq&1) != (d&1)) elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1));
|
||||
if ( (Pico_mcd->m.busreq&2) != (d&2)) elprintf(EL_INTSW, "m68k: s68k brq %i", (d&2)>>1);
|
||||
if ((Pico_mcd->m.state_flags&1) && (d&3)==1) {
|
||||
SekResetS68k(); // S68k comes out of RESET or BRQ state
|
||||
Pico_mcd->m.state_flags&=~1;
|
||||
elprintf(EL_CDREGS, "m68k: resetting s68k, cycles=%i", SekCyclesLeft);
|
||||
}
|
||||
elprintf(EL_CDREGS, "d m.busreq %u %u", d, Pico_mcd->m.busreq);
|
||||
if (d == Pico_mcd->m.busreq)
|
||||
return;
|
||||
pcd_sync_s68k(SekCyclesDone());
|
||||
|
||||
if ((Pico_mcd->m.busreq ^ d) & 1) {
|
||||
elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1));
|
||||
if (!(d & 1))
|
||||
d |= 2; // verified: reset also gives bus
|
||||
if ((d ^ Pico_mcd->m.busreq) & 2)
|
||||
else {
|
||||
elprintf(EL_CDREGS, "m68k: resetting s68k");
|
||||
SekResetS68k();
|
||||
}
|
||||
}
|
||||
if ((Pico_mcd->m.busreq ^ d) & 2) {
|
||||
elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1);
|
||||
remap_prg_window();
|
||||
}
|
||||
Pico_mcd->m.busreq = d;
|
||||
return;
|
||||
case 2:
|
||||
|
@ -193,8 +223,10 @@ void m68k_reg_write8(u32 a, u32 d)
|
|||
case 0xf:
|
||||
d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)
|
||||
case 0xe:
|
||||
//dprintf("m68k: comm flag: %02x", d);
|
||||
if (d != Pico_mcd->s68k_regs[0xe]) {
|
||||
pcd_sync_s68k(SekCyclesDone());
|
||||
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;
|
||||
|
@ -374,8 +406,8 @@ void s68k_reg_write8(u32 a, u32 d)
|
|||
Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();
|
||||
return;
|
||||
case 0xe:
|
||||
Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair
|
||||
return;
|
||||
d = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair
|
||||
break;
|
||||
case 0x31: // 384 cycle int3 timer
|
||||
d &= 0xff;
|
||||
elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d);
|
||||
|
@ -418,6 +450,9 @@ void s68k_reg_write8(u32 a, u32 d)
|
|||
return;
|
||||
}
|
||||
|
||||
if (a < 0x30)
|
||||
Pico_mcd->m.m68k_comm_dirty |= (1 << a/2);
|
||||
|
||||
Pico_mcd->s68k_regs[a] = (u8) d;
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,9 @@ m_m68k_read8_r0d:
|
|||
mov r0, r0, lsr #16
|
||||
bx lr
|
||||
m_m68k_read8_hi:
|
||||
push {r0,r1,lr}
|
||||
bl m68k_comm_check
|
||||
pop {r0,r1,lr}
|
||||
cmp r0, #0x30
|
||||
movge r0, #0
|
||||
bxeq lr
|
||||
|
|
|
@ -45,7 +45,7 @@ PICO_INTERNAL int PicoResetMCD(void)
|
|||
memset(&Pico_mcd->m, 0, sizeof(Pico_mcd->m));
|
||||
|
||||
memset(Pico_mcd->bios + 0x70, 0xff, 4); // reset hint vector (simplest way to implement reg6)
|
||||
Pico_mcd->m.state_flags |= 1; // s68k reset pending
|
||||
Pico_mcd->m.state_flags = 0;
|
||||
Pico_mcd->s68k_regs[3] = 1; // 2M word RAM mode with m68k access after reset
|
||||
|
||||
Reset_CD();
|
||||
|
@ -219,7 +219,7 @@ static void pcd_run_events(unsigned int until)
|
|||
oldest, event_time_next);
|
||||
}
|
||||
|
||||
static void pcd_sync_s68k(unsigned int m68k_target)
|
||||
void pcd_sync_s68k(unsigned int m68k_target)
|
||||
{
|
||||
#define now SekCycleCntS68k
|
||||
unsigned int s68k_target =
|
||||
|
|
|
@ -45,9 +45,6 @@ char *PDebugMain(void)
|
|||
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP;
|
||||
sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i, cycles: %i\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count, SekCyclesDone()); MVP;
|
||||
sprintf(dstrp, "M68k: PC: %06x, SR: %04x, irql: %i\n", SekPc, SekSr, SekIrqLevel); MVP;
|
||||
#if defined(EMU_C68K)
|
||||
sprintf(dstrp - 1, ", st_flg: %x\n", PicoCpuCM68k.state_flags); MVP;
|
||||
#endif
|
||||
for (r = 0; r < 8; r++) {
|
||||
sprintf(dstrp, "d%i=%08x, a%i=%08x\n", r, SekDar(r), r, SekDar(r+8)); MVP;
|
||||
}
|
||||
|
|
|
@ -132,7 +132,11 @@ extern unsigned int SekCycleAim;
|
|||
|
||||
// burn cycles while not in SekRun() and while in
|
||||
#define SekCyclesBurn(c) SekCycleCnt += c
|
||||
#define SekCyclesBurnRun(c) SekCyclesLeft -= c
|
||||
#define SekCyclesBurnRun(c) { \
|
||||
SekCyclesLeft -= c; \
|
||||
if (SekCyclesLeft < 0) \
|
||||
SekCyclesLeft = 0; \
|
||||
}
|
||||
|
||||
// note: sometimes may extend timeslice to delay an irq
|
||||
#define SekEndRun(after) { \
|
||||
|
@ -383,9 +387,12 @@ struct mcd_misc
|
|||
unsigned short hint_vector;
|
||||
unsigned char busreq;
|
||||
unsigned char s68k_pend_ints;
|
||||
unsigned int state_flags; // 04: emu state: reset_pending
|
||||
unsigned int state_flags; // 04
|
||||
unsigned int stopwatch_base_c;
|
||||
unsigned int pad[3];
|
||||
unsigned int m68k_comm_dirty;
|
||||
unsigned short m68k_poll_a;
|
||||
unsigned short m68k_poll_cnt;
|
||||
unsigned int pad;
|
||||
unsigned char bcram_reg; // 18: battery-backed RAM cart register
|
||||
unsigned char pad2;
|
||||
unsigned short pad3;
|
||||
|
@ -624,6 +631,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_s68k(enum pcd_event event, int after);
|
||||
unsigned int pcd_cycles_m68k_to_s68k(unsigned int c);
|
||||
void pcd_sync_s68k(unsigned int m68k_target);
|
||||
void pcd_state_loaded(void);
|
||||
|
||||
// pico/pico.c
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue