- /* loop 488 downto 0 in steps of PS_STEP */
- for (cycn = (488<<16)-PS_STEP_M68K; cycn >= 0; cycn -= PS_STEP_M68K)
- {
- cycn_s68k = (cycn + cycn/2 + cycn/8) >> 16;
- if ((cyc_do = SekCycleAim-SekCycleCnt-(cycn>>16)) > 0) {
-#if defined(EMU_C68K)
- PicoCpuCM68k.cycles = cyc_do;
- CycloneRun(&PicoCpuCM68k);
- SekCycleCnt += cyc_do - PicoCpuCM68k.cycles;
-#elif defined(EMU_M68K)
- m68k_set_context(&PicoCpuMM68k);
- SekCycleCnt += m68k_execute(cyc_do);
-#elif defined(EMU_F68K)
- g_m68kcontext = &PicoCpuFM68k;
- SekCycleCnt += fm68k_emulate(cyc_do, 0, 0);
-#endif
+typedef void (event_cb)(unsigned int now);
+
+/* times are in s68k (12.5MHz) cycles */
+unsigned int pcd_event_times[PCD_EVENT_COUNT];
+static unsigned int event_time_next;
+static event_cb *pcd_event_cbs[PCD_EVENT_COUNT] = {
+ [PCD_EVENT_CDC] = pcd_cdc_event,
+ [PCD_EVENT_TIMER3] = pcd_int3_timer_event,
+ [PCD_EVENT_GFX] = pcd_gfx_event,
+ [PCD_EVENT_DMA] = pcd_dma_event,
+};
+
+void pcd_event_schedule(unsigned int now, enum pcd_event event, int after)
+{
+ unsigned int when;
+
+ when = now + after;
+ if (when == 0) {
+ // event cancelled
+ pcd_event_times[event] = 0;
+ return;
+ }
+
+ when |= 1;
+
+ elprintf(EL_CD, "cd: new event #%u %u->%u", event, now, when);
+ pcd_event_times[event] = when;
+
+ if (event_time_next == 0 || CYCLES_GT(event_time_next, when))
+ event_time_next = when;
+}
+
+void pcd_event_schedule_s68k(enum pcd_event event, int after)
+{
+ if (SekCyclesLeftS68k > after)
+ SekEndRunS68k(after);
+
+ pcd_event_schedule(SekCyclesDoneS68k(), event, after);
+}
+
+static void pcd_run_events(unsigned int until)
+{
+ int oldest, oldest_diff, time;
+ int i, diff;
+
+ while (1) {
+ oldest = -1, oldest_diff = 0x7fffffff;
+
+ for (i = 0; i < PCD_EVENT_COUNT; i++) {
+ if (pcd_event_times[i]) {
+ diff = pcd_event_times[i] - until;
+ if (diff < oldest_diff) {
+ oldest_diff = diff;
+ oldest = i;
+ }
+ }