示例#1
0
        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;
        }
示例#2
0
        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;
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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;
        }