#define SekCyclesLeftNoMCD PicoCpu.cycles // cycles left for this run\r
#define SekCyclesLeft \\r
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)\r
+#define SekCyclesLeftS68k \\r
+ ((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuS68k.cycles)\r
#define SekSetCyclesLeftNoMCD(c) PicoCpu.cycles=c\r
#define SekSetCyclesLeft(c) { \\r
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \\r
}\r
#define SekPc (PicoCpu.pc-PicoCpu.membase)\r
#define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase)\r
+#define SekSetStop(x) { PicoCpu.stopped=x; if (x) PicoCpu.cycles=0; }\r
+#define SekSetStopS68k(x) { PicoCpuS68k.stopped=x; if (x) PicoCpuS68k.cycles=0; }\r
#endif\r
\r
#ifdef EMU_A68K\r
extern m68ki_cpu_core PicoM68kCPU; // MD's CPU\r
extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU\r
#ifndef SekCyclesLeft\r
-#define SekCyclesLeftNoMCD m68k_cycles_remaining()\r
+#define SekCyclesLeftNoMCD PicoM68kCPU.cyc_remaining_cycles\r
#define SekCyclesLeft \\r
(((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)\r
+#define SekCyclesLeftS68k \\r
+ ((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoS68kCPU.cyc_remaining_cycles)\r
#define SekSetCyclesLeftNoMCD(c) SET_CYCLES(c)\r
#define SekSetCyclesLeft(c) { \\r
if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SET_CYCLES(c); \\r
}\r
#define SekPc m68k_get_reg(&PicoM68kCPU, M68K_REG_PC)\r
#define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC)\r
+#define SekSetStop(x) { \\r
+ if(x) { SET_CYCLES(0); PicoM68kCPU.stopped=STOP_LEVEL_STOP; } \\r
+ else PicoM68kCPU.stopped=0; \\r
+}\r
+#define SekSetStopS68k(x) { \\r
+ if(x) { SET_CYCLES(0); PicoS68kCPU.stopped=STOP_LEVEL_STOP; } \\r
+ else PicoS68kCPU.stopped=0; \\r
+}\r
#endif\r
#endif\r
\r
extern int SekCycleAimS68k;\r
\r
#define SekCyclesResetS68k() {SekCycleCntS68k=SekCycleAimS68k=0;}\r
+#define SekCyclesDoneS68k() (SekCycleAimS68k-SekCyclesLeftS68k)\r
\r
// does not work as expected\r
//extern int z80ExtraCycles; // extra z80 cycles, used when z80 is [en|dis]abled\r
\r
// -----------------------------------------------------------------\r
\r
+// poller detection\r
+#define USE_POLL_DETECT\r
+#define POLL_LIMIT 16\r
+#define POLL_CYCLES 124\r
+// int m68k_poll_addr, m68k_poll_cnt;\r
+unsigned int s68k_poll_adclk, s68k_poll_cnt;\r
\r
#ifndef _ASM_CD_MEMORY_C\r
static u32 m68k_reg_read16(u32 a)\r
if (d & 2) dold &= ~1; // return word RAM to s68k in 2M mode\r
}\r
Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register\r
-\r
-/*\r
- d |= Pico_mcd->s68k_regs[3]&0x1d;\r
- if (!(d & 4) && (d & 2)) d &= ~1; // return word RAM to s68k in 2M mode\r
- Pico_mcd->s68k_regs[3] = d; // really use s68k side register\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
+ //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ }\r
+#endif\r
return;\r
}\r
case 6:\r
Pico_mcd->bios[0x72] = d;\r
dprintf("hint vector set to %08x", PicoRead32(0x70));\r
return;\r
+ case 0xf:\r
+ d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
case 0xe:\r
//dprintf("m68k: comm flag: %02x", d);\r
Pico_mcd->s68k_regs[0xe] = d;\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
+ //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ }\r
+#endif\r
return;\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
+ //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ }\r
+#endif\r
return;\r
}\r
\r
\r
switch (a) {\r
case 0:\r
- d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
- goto end;\r
+ return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
case 2:\r
d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
- goto end;\r
+ goto poll_detect;\r
case 6:\r
- d = CDC_Read_Reg();\r
- goto end;\r
+ return CDC_Read_Reg();\r
case 8:\r
- d = Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
- goto end;\r
+ return Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
case 0xC:\r
d = Pico_mcd->m.timer_stopwatch >> 16;\r
dprintf("s68k stopwatch timer read (%04x)", d);\r
- goto end;\r
+ return d;\r
case 0x30:\r
- dprintf("s68k int3 timer read (%02x%02x)", Pico_mcd->s68k_regs[30], Pico_mcd->s68k_regs[31]);\r
- break;\r
+ dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
+ return Pico_mcd->s68k_regs[31];\r
case 0x34: // fader\r
- d = 0; // no busy bit\r
- goto end;\r
+ return 0; // no busy bit\r
case 0x50: // font data (check: Lunar 2, Silpheed)\r
READ_FONT_DATA(0x00100000);\r
- goto end;\r
+ return d;\r
case 0x52:\r
READ_FONT_DATA(0x00010000);\r
- goto end;\r
+ return d;\r
case 0x54:\r
READ_FONT_DATA(0x10000000);\r
- goto end;\r
+ return d;\r
case 0x56:\r
READ_FONT_DATA(0x01000000);\r
- goto end;\r
+ return d;\r
}\r
\r
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
\r
-end:\r
+ if (a >= 0x0e && a < 0x30) goto poll_detect;\r
\r
- // dprintf("ret = %04x", d);\r
+ return d;\r
\r
+poll_detect:\r
+#ifdef USE_POLL_DETECT\r
+ // polling detection\r
+ if (a == (s68k_poll_adclk&0xfe)) {\r
+ unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\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
+ SekSetStopS68k(1);\r
+ //printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, 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
+\r
+#endif\r
return d;\r
}\r
\r
Pico_mcd->m.timer_stopwatch = 0;\r
return;\r
case 0xe:\r
- Pico_mcd->s68k_regs[0Xf] = (d>>1) | (d<<7); // ror8, Gens note: Dragons lair\r
- Pico_mcd->m.timer_stopwatch = 0;\r
+ Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
return;\r
case 0x31:\r
dprintf("s68k set int3 timer: %02x", d);\r
return;\r
}\r
\r
- if ((a&0xffffc0)==0xa12000)\r
+ // regs\r
+ if ((a&0xffffc0)==0xa12000) {\r
rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\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 = -1;\r
+ //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ }\r
+#endif\r
+ return;\r
+ }\r
+ m68k_reg_write8(a, d>>8);\r
+ m68k_reg_write8(a+1,d&0xff);\r
+ return;\r
+ }\r
\r
OtherWrite16(a,d);\r
}\r
PicoCpuS68k.write16=PicoWriteS68k16;\r
PicoCpuS68k.write32=PicoWriteS68k32;\r
#endif\r
+ // m68k_poll_addr = m68k_poll_cnt = 0;\r
+ s68k_poll_adclk = s68k_poll_cnt = 0;\r
}\r
\r
\r