void sound_stop() { int totalsound = 0; while (totalsound < Machine.drv.sound.Count && Machine.drv.sound[totalsound].sound_type != 0 && totalsound < MAX_SOUND) { sndintf[Machine.drv.sound[totalsound].sound_type].stop(); totalsound++; } streams_sh_stop(); mixer_sh_stop(); if (sound_update_timer != null) { Timer.timer_remove(sound_update_timer); sound_update_timer = null; } /* free audio samples */ freesamples(ref Machine.samples); Machine.samples = null; }
int sound_start() { int totalsound = 0; /* Verify the order of entries in the sndintf[] array */ for (int i = 0; i < SOUND_COUNT; i++) { if (sndintf[i].sound_num != i) { printf("Sound #%d wrong ID %d: check enum SOUND_... in src/sndintrf.h!\n", i, sndintf[i].sound_num); return 1; } } /* samples will be read later if needed */ Machine.samples = null; snd_refresh_period = Timer.TIME_IN_HZ(Machine.drv.frames_per_second); refresh_period_inv = 1.0 / refresh_period; sound_update_timer = Timer.timer_set(Timer.TIME_NEVER, 0, null); if (mixer_sh_start() != 0) return 1; if (streams_sh_start() != 0) return 1; while (totalsound < Machine.drv.sound.Count && Machine.drv.sound[totalsound].sound_type != 0 && totalsound < MAX_SOUND) { if (Machine.drv.sound[totalsound].sound_type == SOUND_CUSTOM) { ((CustomSoundInterface)sndintf[SOUND_CUSTOM]).SoundStart = ((snd_interface)Machine.drv.sound[totalsound].sound_interface).start; ((CustomSoundInterface)sndintf[SOUND_CUSTOM]).SoundStop = ((snd_interface)Machine.drv.sound[totalsound].sound_interface).stop; ((CustomSoundInterface)sndintf[SOUND_CUSTOM]).SoundUpdate = ((snd_interface)Machine.drv.sound[totalsound].sound_interface).update; } if ((sndintf[Machine.drv.sound[totalsound].sound_type].start)(Machine.drv.sound[totalsound]) != 0) goto getout; totalsound++; } return 0; getout: /* TODO: should also free the resources allocated before */ return 1; }
void cpu_inittimers() { double first_time; int i, max, ipf; /* remove old timers */ if (timeslice_timer != null) Timer.timer_remove(timeslice_timer); if (refresh_timer != null) Timer.timer_remove(refresh_timer); if (vblank_timer != null) Timer.timer_remove(vblank_timer); /* allocate a dummy timer at the minimum frequency to break things up */ ipf = Machine.drv.cpu_slices_per_frame; if (ipf <= 0) ipf = 1; timeslice_period = Timer.TIME_IN_HZ(Machine.drv.frames_per_second * ipf); timeslice_timer = Timer.timer_pulse(timeslice_period, 0, cpu_timeslicecallback); /* allocate an infinite timer to track elapsed time since the last refresh */ refresh_period = Timer.TIME_IN_HZ(Machine.drv.frames_per_second); refresh_period_inv = 1.0 / refresh_period; refresh_timer = Timer.timer_set(Timer.TIME_NEVER, 0, null); /* while we're at it, compute the scanline times */ if (Machine.drv.vblank_duration != 0) scanline_period = (refresh_period - Timer.TIME_IN_USEC(Machine.drv.vblank_duration)) / (double)(Machine.drv.visible_area.max_y - Machine.drv.visible_area.min_y + 1); else scanline_period = refresh_period / (double)Machine.drv.screen_height; scanline_period_inv = 1.0 / scanline_period; /* * The following code finds all the CPUs that are interrupting in sync with the VBLANK * and sets up the VBLANK timer to run at the minimum number of cycles per frame in * order to service all the synced interrupts */ /* find the CPU with the maximum interrupts per frame */ max = 1; for (i = 0; i < totalcpu; i++) { ipf = Machine.drv.cpu[i].vblank_interrupts_per_frame; if (ipf > max) max = ipf; } /* now find the LCD with the rest of the CPUs (brute force - these numbers aren't huge) */ vblank_multiplier = max; while (true) { for (i = 0; i < totalcpu; i++) { ipf = Machine.drv.cpu[i].vblank_interrupts_per_frame; if (ipf > 0 && (vblank_multiplier % ipf) != 0) break; } if (i == totalcpu) break; vblank_multiplier += max; } /* initialize the countdown timers and intervals */ for (i = 0; i < totalcpu; i++) { ipf = Machine.drv.cpu[i].vblank_interrupts_per_frame; if (ipf > 0) cpu[i].vblankint_countdown = cpu[i].vblankint_multiplier = vblank_multiplier / ipf; else cpu[i].vblankint_countdown = cpu[i].vblankint_multiplier = -1; } /* allocate a vblank timer at the frame rate * the LCD number of interrupts per frame */ vblank_period = Timer.TIME_IN_HZ(Machine.drv.frames_per_second * vblank_multiplier); vblank_timer = Timer.timer_pulse(vblank_period, 0, cpu_vblankcallback); vblank_countdown = vblank_multiplier; /* * The following code creates individual timers for each CPU whose interrupts are not * synced to the VBLANK, and computes the typical number of cycles per interrupt */ /* start the CPU interrupt timers */ for (i = 0; i < totalcpu; i++) { ipf = Machine.drv.cpu[i].vblank_interrupts_per_frame; /* remove old timers */ if (cpu[i].vblankint_timer != null) Timer.timer_remove(cpu[i].vblankint_timer); if (cpu[i].timedint_timer != null) Timer.timer_remove(cpu[i].timedint_timer); /* compute the average number of cycles per interrupt */ if (ipf <= 0) ipf = 1; cpu[i].vblankint_period = Timer.TIME_IN_HZ(Machine.drv.frames_per_second * ipf); cpu[i].vblankint_timer = Timer.timer_set(Timer.TIME_NEVER, 0, null); /* see if we need to allocate a CPU timer */ ipf = Machine.drv.cpu[i].timed_interrupts_per_second; if (ipf != 0) { cpu[i].timedint_period = cpu_computerate(ipf); cpu[i].timedint_timer = Timer.timer_pulse(cpu[i].timedint_period, i, cpu_timedintcallback); } } /* note that since we start the first frame on the refresh, we can't pulse starting immediately; instead, we back up one VBLANK period, and inch forward until we hit positive time. That time will be the time of the first VBLANK timer callback */ Timer.timer_remove(vblank_timer); first_time = -Timer.TIME_IN_USEC(Machine.drv.vblank_duration) + vblank_period; while (first_time < 0) { cpu_vblankcallback(-1); first_time += vblank_period; } vblank_timer = Timer.timer_set(first_time, 0, cpu_firstvblankcallback); }
void cpu_firstvblankcallback(int param) { /* now that we're synced up, pulse from here on out */ vblank_timer = Timer.timer_pulse(vblank_period, param, cpu_vblankcallback); /* but we need to call the standard routine as well */ cpu_vblankcallback(param); }
void cpu_init() { int i; /* Verify the order of entries in the cpuintf[] array */ for (i = 0; i < CPU_COUNT; i++) { if (cpuintf[i].cpu_num != i) { printf("CPU #%d [%s] wrong ID %d: check enum CPU_... in src/driver.h!\n", i, cputype_name(i), cpuintf[i].cpu_num); throw new Exception(); } } /* count how many CPUs we have to emulate */ totalcpu = 0; while (totalcpu < MAX_CPU) { if (CPU_TYPE(totalcpu) == CPU_DUMMY) break; totalcpu++; } /* zap the CPU data structure */ //memset(cpu, 0, sizeof(cpu)); cpu.Clear(); /* Set up the interface functions */ for (i = 0; i < MAX_CPU; i++) cpu.Add(new cpuinfo(cpuintf[CPU_TYPE(i)])); /* reset the timer system */ Timer.timer_init(); timeslice_timer = refresh_timer = vblank_timer = null; }