void PicoWriteS68k16_dec_m2b1(u32 a, u32 d);\r
#endif\r
\r
-static void remap_prg_window(void);\r
+static void remap_prg_window(int r3);\r
static void remap_word_ram(int r3);\r
\r
// poller detection\r
#define POLL_LIMIT 16\r
#define POLL_CYCLES 124\r
-unsigned int s68k_poll_adclk, s68k_poll_cnt;\r
\r
-void m68k_comm_check(u32 a)\r
+u32 m68k_comm_check(u32 a, u32 d)\r
{\r
- pcd_sync_s68k(SekCyclesDone());\r
- /*if (Pico_mcd->m.m68k_comm_dirty & (1 << a/2)) {\r
- Pico_mcd->m.m68k_comm_dirty &= ~(1 << a/2);\r
- Pico_mcd->m.m68k_poll_a = Pico_mcd->m.m68k_poll_cnt = 0;\r
- return;\r
- }\r
+ pcd_sync_s68k(SekCyclesDone(), 0);\r
if (a != Pico_mcd->m.m68k_poll_a) {\r
Pico_mcd->m.m68k_poll_a = a;\r
Pico_mcd->m.m68k_poll_cnt = 0;\r
- return;\r
+ return d;\r
}\r
- if (++Pico_mcd->m.m68k_poll_cnt > 5)\r
- SekCyclesBurnRun(122);\r
-\r
- elprintf(EL_CDPOLL, "m68k poll [%02x] %d %u", a,\r
- Pico_mcd->m.m68k_poll_cnt, SekCyclesDone());*/\r
+ Pico_mcd->m.m68k_poll_cnt++;\r
+ return d;\r
}\r
\r
#ifndef _ASM_CD_MEMORY_C\r
d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens\r
goto end;\r
case 2:\r
- m68k_comm_check(a);\r
d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
- goto end;\r
+ goto end_comm;\r
case 4:\r
d = Pico_mcd->s68k_regs[4]<<8;\r
goto end;\r
\r
if (a < 0x30) {\r
// comm flag/cmd/status (0xE-0x2F)\r
- m68k_comm_check(a);\r
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
- goto end;\r
+ goto end_comm;\r
}\r
\r
elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);\r
\r
end:\r
-\r
return d;\r
+\r
+end_comm:\r
+ return m68k_comm_check(a, d);\r
}\r
#endif\r
\r
u32 dold;\r
a &= 0x3f;\r
\r
- Pico_mcd->m.m68k_poll_a = 0;\r
+ Pico_mcd->m.m68k_poll_a =\r
+ Pico_mcd->m.m68k_poll_cnt = 0;\r
\r
switch (a) {\r
case 0:\r
d &= 1;\r
- if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { elprintf(EL_INTS, "m68k: s68k irq 2"); SekInterruptS68k(2); }\r
+ if (d && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN2)) {\r
+ elprintf(EL_INTS, "m68k: s68k irq 2");\r
+ pcd_sync_s68k(SekCyclesDone(), 0);\r
+ SekInterruptS68k(2);\r
+ }\r
return;\r
case 1:\r
d &= 3;\r
elprintf(EL_CDREGS, "d m.busreq %u %u", d, Pico_mcd->m.busreq);\r
if (d == Pico_mcd->m.busreq)\r
return;\r
- pcd_sync_s68k(SekCyclesDone());\r
+ pcd_sync_s68k(SekCyclesDone(), 0);\r
\r
if ((Pico_mcd->m.busreq ^ d) & 1) {\r
elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1));\r
}\r
if ((Pico_mcd->m.busreq ^ d) & 2) {\r
elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1);\r
- remap_prg_window();\r
+ remap_prg_window(Pico_mcd->s68k_regs[3]);\r
}\r
Pico_mcd->m.busreq = d;\r
return;\r
if (dold & 4) { // 1M mode\r
d ^= 2; // writing 0 to DMNA actually sets it, 1 does nothing\r
} else {\r
- if ((d ^ dold) & d & 2) { // DMNA is being set\r
+ if ((d ^ dold) & d & 2) { // DMNA is being set\r
dold &= ~1; // return word RAM to s68k\r
/* Silpheed hack: bset(w3), r3, btst, bne, r3 */\r
SekEndRun(20+16+10+12+16);\r
}\r
}\r
- Pico_mcd->s68k_regs[3] = (d & 0xc2) | (dold & 0x1f);\r
+ d = (d & 0xc2) | (dold & 0x1f);\r
if ((d ^ dold) & 0xc0) {\r
- elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
- remap_prg_window();\r
- }\r
-#ifdef USE_POLL_DETECT\r
- if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {\r
- SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);\r
+ elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i",\r
+ (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
+ remap_prg_window(d);\r
}\r
-#endif\r
- return;\r
+ goto write_comm;\r
case 6:\r
Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
return;\r
elprintf(EL_CDREGS, "hint vector set to %04x%04x",\r
((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);\r
return;\r
- case 0xf:\r
+ case 0x0f:\r
d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
- case 0xe:\r
- if (d != Pico_mcd->s68k_regs[0xe]) {\r
- pcd_sync_s68k(SekCyclesDone());\r
- Pico_mcd->s68k_regs[0xe] = d;\r
- }\r
-#ifdef USE_POLL_DETECT\r
- if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
- SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);\r
- }\r
-#endif\r
- return;\r
+ a = 0x0e;\r
+ case 0x0e:\r
+ goto write_comm;\r
}\r
\r
- if ((a&0xf0) == 0x10) {\r
- Pico_mcd->s68k_regs[a] = d;\r
-#ifdef USE_POLL_DETECT\r
- if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {\r
- SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);\r
- }\r
-#endif\r
- return;\r
- }\r
+ if ((a&0xf0) == 0x10)\r
+ goto write_comm;\r
\r
elprintf(EL_UIO, "m68k FIXME: invalid write? [%02x] %02x", a, d);\r
+ return;\r
+\r
+write_comm:\r
+ if (d == Pico_mcd->s68k_regs[a])\r
+ return;\r
+\r
+ Pico_mcd->s68k_regs[a] = d;\r
+ pcd_sync_s68k(SekCyclesDone(), 0);\r
+ if (Pico_mcd->m.s68k_poll_a == a && Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) {\r
+ SekSetStopS68k(0);\r
+ Pico_mcd->m.s68k_poll_a = 0;\r
+ elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);\r
+ }\r
}\r
\r
#ifndef _ASM_CD_MEMORY_C\r
u32 s68k_poll_detect(u32 a, u32 d)\r
{\r
#ifdef USE_POLL_DETECT\r
- // needed mostly for Cyclone, which doesn't always check it's cycle counter\r
- if (SekIsStoppedS68k()) return d;\r
- // polling detection\r
- if (a == (s68k_poll_adclk&0xff)) {\r
- unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\r
+ u32 cycles, cnt = 0;\r
+ if (SekIsStoppedS68k())\r
+ return d;\r
+\r
+ cycles = SekCyclesDoneS68k();\r
+ if (a == Pico_mcd->m.s68k_poll_a) {\r
+ u32 clkdiff = cycles - Pico_mcd->m.s68k_poll_clk;\r
if (clkdiff <= POLL_CYCLES) {\r
- s68k_poll_cnt++;\r
- //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);\r
- if (s68k_poll_cnt > POLL_LIMIT) {\r
+ cnt = Pico_mcd->m.s68k_poll_cnt + 1;\r
+ //printf("-- diff: %u, cnt = %i\n", clkdiff, cnt);\r
+ if (Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) {\r
SekSetStopS68k(1);\r
- elprintf(EL_CDPOLL, "s68k poll detected @ %06x, a=%02x", SekPcS68k, a);\r
+ elprintf(EL_CDPOLL, "s68k poll detected @ %06x, a=%02x",\r
+ SekPcS68k, a);\r
}\r
- s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
- return d;\r
}\r
}\r
- s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
- s68k_poll_cnt = 0;\r
+ Pico_mcd->m.s68k_poll_a = a;\r
+ Pico_mcd->m.s68k_poll_clk = cycles;\r
+ Pico_mcd->m.s68k_poll_cnt = cnt;\r
#endif\r
return d;\r
}\r
if (d & 1)\r
d &= ~2; // DMNA clears\r
}\r
- break;\r
+ goto write_comm;\r
}\r
case 4:\r
elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7);\r
// does this also reset internal 384 cycle counter?\r
Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();\r
return;\r
- case 0xe:\r
+ case 0x0e:\r
+ d &= 0xff;\r
d = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
- break;\r
+ a = 0x0f;\r
+ case 0x0f:\r
+ goto write_comm;\r
case 0x31: // 384 cycle int3 timer\r
d &= 0xff;\r
elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d);\r
return;\r
}\r
\r
+ if ((a&0x1f0) == 0x20)\r
+ goto write_comm;\r
+\r
if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
{\r
elprintf(EL_UIO, "s68k FIXME: invalid write @ %02x?", a);\r
return;\r
}\r
\r
- if (a < 0x30)\r
- Pico_mcd->m.m68k_comm_dirty |= (1 << a/2);\r
+ Pico_mcd->s68k_regs[a] = (u8) d;\r
+ return;\r
\r
+write_comm:\r
Pico_mcd->s68k_regs[a] = (u8) d;\r
+ if (Pico_mcd->m.m68k_poll_cnt)\r
+ SekEndRunS68k(0);\r
+ Pico_mcd->m.m68k_poll_cnt = 0;\r
}\r
\r
// -----------------------------------------------------------------\r
{\r
if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
-/* TODO FIXME?\r
- if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
- Pico_mcd->s68k_regs[0xe] = d >> 8;\r
-#ifdef USE_POLL_DETECT\r
- if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
- SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);\r
- }\r
-#endif\r
- return;\r
- }\r
-*/\r
+\r
m68k_reg_write8(a, d >> 8);\r
- m68k_reg_write8(a + 1, d & 0xff);\r
+ if ((a & 0x3e) != 0x0e) // special case\r
+ m68k_reg_write8(a + 1, d & 0xff);\r
return;\r
}\r
\r
\r
// -----------------------------------------------------------------\r
\r
-static void remap_prg_window(void)\r
+static void remap_prg_window(int r3)\r
{\r
// PRG RAM\r
if (Pico_mcd->m.busreq & 2) {\r
- void *bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3] >> 6];\r
+ void *bank = Pico_mcd->prg_ram_b[r3 >> 6];\r
cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0);\r
}\r
else {\r
if (r3 & 4) // 1M mode?\r
wram_2M_to_1M(Pico_mcd->word_ram2M);\r
remap_word_ram(r3);\r
- remap_prg_window();\r
+ remap_prg_window(r3);\r
\r
// restore hint vector\r
*(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;\r
#ifdef EMU_M68K\r
m68k_mem_setup_cd();\r
#endif\r
-\r
- // m68k_poll_addr = m68k_poll_cnt = 0;\r
- s68k_poll_adclk = s68k_poll_cnt = 0;\r
}\r
\r
\r
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }\r
#define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1)\r
#define SekIsStoppedS68k() (PicoCpuCS68k.state_flags&1)\r
-#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))\r
+#define SekShouldInterrupt() (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))\r
\r
#define SekInterrupt(i) PicoCpuCM68k.irq=i\r
#define SekIrqLevel PicoCpuCM68k.irq\r
}\r
#define SekIsStoppedM68k() (PicoCpuFM68k.execinfo&FM68K_HALTED)\r
#define SekIsStoppedS68k() (PicoCpuFS68k.execinfo&FM68K_HALTED)\r
-#define SekShouldInterrupt fm68k_would_interrupt()\r
+#define SekShouldInterrupt() fm68k_would_interrupt()\r
\r
#define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq\r
#define SekIrqLevel PicoCpuFM68k.interrupts[0]\r
}\r
#define SekIsStoppedM68k() (PicoCpuMM68k.stopped==STOP_LEVEL_STOP)\r
#define SekIsStoppedS68k() (PicoCpuMS68k.stopped==STOP_LEVEL_STOP)\r
-#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)\r
+#define SekShouldInterrupt() (CPU_INT_LEVEL > FLAG_INT_MASK)\r
\r
#define SekInterrupt(irq) { \\r
void *oldcontext = m68ki_cpu_p; \\r
unsigned char s68k_pend_ints;\r
unsigned int state_flags; // 04\r
unsigned int stopwatch_base_c;\r
- unsigned int m68k_comm_dirty;\r
unsigned short m68k_poll_a;\r
unsigned short m68k_poll_cnt;\r
- unsigned int pad;\r
+ unsigned short s68k_poll_a;\r
+ unsigned short s68k_poll_cnt;\r
+ unsigned int s68k_poll_clk;\r
unsigned char bcram_reg; // 18: battery-backed RAM cart register\r
unsigned char pad2;\r
unsigned short pad3;\r
void pcd_event_schedule(unsigned int now, enum pcd_event event, int after);\r
void pcd_event_schedule_s68k(enum pcd_event event, int after);\r
unsigned int pcd_cycles_m68k_to_s68k(unsigned int c);\r
-void pcd_sync_s68k(unsigned int m68k_target);\r
+int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync);\r
void pcd_state_loaded(void);\r
\r
// pico/pico.c\r
void pevt_dump(void);\r
\r
#define pevt_log_m68k(e) \\r
- pevt_log(SekCyclesDoneT(), EVT_M68K, e)\r
+ pevt_log(SekCyclesDone(), EVT_M68K, e)\r
#define pevt_log_m68k_o(e) \\r
- pevt_log(SekCyclesDoneT2(), EVT_M68K, e)\r
+ pevt_log(SekCyclesDone(), EVT_M68K, e)\r
#define pevt_log_sh2(sh2, e) \\r
pevt_log(sh2_cycles_done_m68k(sh2), EVT_MSH2 + (sh2)->is_slave, e)\r
#define pevt_log_sh2_o(sh2, e) \\r