예제 #1
0
        public void ctrl_w(uint8_t data)
        {
            m_control = data;

            // The upper 3 control bits are the clock divider.
            if ((m_control & 0xe0) == 0)
            {
                m_nmi_timer.adjust(attotime.never);
                set_nmi(CLEAR_LINE);
                m_chipsel[0].op_s32(0, CLEAR_LINE);
                m_chipsel[1].op_s32(0, CLEAR_LINE);
                m_chipsel[2].op_s32(0, CLEAR_LINE);
                m_chipsel[3].op_s32(0, CLEAR_LINE);
                // Setting this to true makes the next RW change not stretch.
                m_next_timer_state = true;
            }
            else
            {
                m_rw_stretch       = !m_next_timer_state;
                m_rw_change        = true;
                m_next_timer_state = true;
                m_nmi_stretch      = BIT(m_control, 4) != 0;
                // NMI is cleared immediately if its to be stretched.
                if (m_nmi_stretch)
                {
                    set_nmi(CLEAR_LINE);
                }

                uint8_t num_shifts = (uint8_t)((m_control & 0xe0) >> 5);
                uint8_t divisor    = (uint8_t)(1U << num_shifts);
                // The next change should happen on the next clock falling edge.
                // Xevious' race causes this to bootloopsif it isn't 0.
                m_nmi_timer.adjust(attotime.zero, 0, attotime.from_hz(clock() / divisor) / 2);
            }
        }
예제 #2
0
        // watchdog control

        //-------------------------------------------------
        //  watchdog_reset - reset the watchdog timer
        //-------------------------------------------------
        public void watchdog_reset()
        {
            // if we're not enabled, skip it
            if (!m_enabled)
            {
                m_timer.adjust(attotime.never);
            }

            // VBLANK-based watchdog?
            else if (m_vblank_count != 0)
            {
                m_counter = m_vblank_count;
            }

            // timer-based watchdog?
            else if (m_time != attotime.zero)
            {
                m_timer.adjust(m_time);
            }

            // default to an obscene amount of time (3 seconds)
            else
            {
                m_timer.adjust(attotime.from_seconds(3));
            }
        }
예제 #3
0
        protected virtual void set_rmcr(uint8_t data)
        {
            if (m_rmcr == data)
            {
                return;
            }

            m_rmcr = data;

            switch ((m_rmcr & M6801_RMCR_CC_MASK) >> 2)
            {
            case 0:
                LOGSER("SCI: Using external serial clock: false\n");
                m_sci_timer.enable(false);
                m_use_ext_serclock = false;
                break;

            case 3: // external clock
                LOGSER("SCI: Using external serial clock: true\n");
                m_use_ext_serclock = true;
                m_sci_timer.enable(false);
                break;

            case 1:
            case 2:
            {
                int      divisor = M6801_RMCR_SS[m_rmcr & M6801_RMCR_SS_MASK];
                attotime period  = cycles_to_attotime((uint64_t)divisor);
                LOGSER("SCI: Setting serial rate, Divisor: {0} Hz: {1}\n", divisor, period.as_hz());
                m_sci_timer.adjust(period, 0, period);
                m_use_ext_serclock = false;
            }
            break;
            }
        }
예제 #4
0
        //-------------------------------------------------
        //  interface_post_reset - work to be done after a
        //  device is reset
        //-------------------------------------------------
        public override void interface_post_reset()
        {
            // reset the interrupt vectors and queues
            for (int line = 0; line < m_input.Length; line++)
            {
                m_input[line].reset();
            }

            // reconfingure VBLANK interrupts
            if (!string.IsNullOrEmpty(m_vblank_interrupt_screen))
            {
                // get the screen that will trigger the VBLANK
                screen_device screen = device().siblingdevice <screen_device>(m_vblank_interrupt_screen);

                //assert(screen != NULL);
                screen.register_vblank_callback(on_vblank);
            }

            // reconfigure periodic interrupts
            if (m_timed_interrupt_period != attotime.zero)
            {
                attotime timedint_period = m_timed_interrupt_period;
                //assert(m_timedint_timer != NULL);
                m_timedint_timer.adjust(timedint_period, 0, timedint_period);
            }
        }
예제 #5
0
        //-------------------------------------------------
        //  interface_post_reset - work to be done after a
        //  device is reset
        //-------------------------------------------------
        public override void interface_post_reset()
        {
            // reset the interrupt vectors and queues
            foreach (var elem in m_input)
            {
                elem.reset();
            }

            // reconfingure VBLANK interrupts
            if (!string.IsNullOrEmpty(m_vblank_interrupt_screen))
            {
                // get the screen that will trigger the VBLANK
                screen_device screen = device().siblingdevice <screen_device>(m_vblank_interrupt_screen);

                //throw new emu_unimplemented();
#if false
                assert(screen != nullptr);
#endif

                screen.register_vblank_callback(on_vblank);
            }

            // reconfigure periodic interrupts
            if (m_timed_interrupt_period != attotime.zero)
            {
                attotime timedint_period = m_timed_interrupt_period;

                //throw new emu_unimplemented();
#if false
                assert(m_timedint_timer != nullptr);
#endif

                m_timedint_timer.adjust(timedint_period, 0, timedint_period);
            }
        }
예제 #6
0
파일: m6801.cs 프로젝트: kwanboy/mcs
        void set_rmcr(uint8_t data)
        {
            if (m_rmcr == data)
            {
                return;
            }

            m_rmcr = data;

            switch ((m_rmcr & M6801_RMCR_CC_MASK) >> 2)
            {
            case 0:
                m_sci_timer.enable(false);
                m_use_ext_serclock = false;
                break;

            case 3: // external clock
                m_use_ext_serclock = true;
                m_sci_timer.enable(false);
                break;

            case 1:
            case 2:
            {
                int      divisor = M6801_RMCR_SS[m_rmcr & M6801_RMCR_SS_MASK];
                attotime period  = cycles_to_attotime((u64)divisor);

                m_sci_timer.adjust(period, 0, period);
                m_use_ext_serclock = false;
            }
            break;
            }
        }
예제 #7
0
파일: msm5205.cs 프로젝트: kwanboy/mcs
        protected override void device_clock_changed()
        {
            int prescaler = get_prescaler();

            if (prescaler != 0)
            {
                logerror("/{0} prescaler selected\n", prescaler);

                attotime half_period = clocks_to_attotime((u64)(prescaler / 2));
                m_vck_timer.adjust(half_period, 0, half_period);
            }
            else
            {
                logerror("VCK slave mode selected\n");
                m_vck_timer.adjust(attotime.never);
            }
        }
예제 #8
0
        public void device_scheduler_after_ctor(running_machine machine)
        {
            // ED: there's a circular dependency with device_scheduler.  it creates a emu_timer, which calls machine.time().  so we null check here to fix that.


            // append a single never-expiring timer so there is always one in the list
            m_timer_list = m_timer_allocator.alloc().init(machine, null, null, true);
            m_timer_list.adjust(attotime.never);
        }
예제 #9
0
        public void go_w(u8 data = 0)
        {
            vggo();

            if (m_sync_halt != 0 && (m_nvect > 10))
            {
                /*
                 * This is a good time to start a new frame. Major Havoc
                 * sometimes sets VGGO after a very short vector list. That's
                 * why we ignore frames with less than 10 vectors.
                 */
                m_vector.op0.clear_list();
            }

            vg_flush();

            vg_set_halt(0);
            m_vg_run_timer.adjust(attotime.zero);
        }
예제 #10
0
파일: namco06.cs 프로젝트: kwanboy/mcs
        //WRITE8_MEMBER( namco_06xx_device::ctrl_w )
        public void ctrl_w(address_space space, offs_t offset, u8 data, u8 mem_mask = 0xff)
        {
            LOG("{0}: 06XX '{1}' control {2}\n", machine().describe_context(), tag(), data);

            m_control = data;

            if ((m_control & 0x0f) == 0)
            {
                LOG("disabling nmi generate timer\n");
                m_nmi_timer.adjust(attotime.never);
            }
            else
            {
                LOG("setting nmi generate timer to 200us\n");

                // this timing is critical. Due to a bug, Bosconian will stop responding to
                // inputs if a transfer terminates at the wrong time.
                // On the other hand, the time cannot be too short otherwise the 54XX will
                // not have enough time to process the incoming controls.
                m_nmi_timer.adjust(attotime.from_usec(200), 0, attotime.from_usec(200));

                if ((m_control & 0x10) != 0)
                {
                    if (BIT(m_control, 0) != 0)
                    {
                        m_readreq[0].op(space, 0);
                    }
                    if (BIT(m_control, 1) != 0)
                    {
                        m_readreq[1].op(space, 0);
                    }
                    if (BIT(m_control, 2) != 0)
                    {
                        m_readreq[2].op(space, 0);
                    }
                    if (BIT(m_control, 3) != 0)
                    {
                        m_readreq[3].op(space, 0);
                    }
                }
            }
        }
예제 #11
0
파일: namco50.cs 프로젝트: kwanboy/mcs
        void irq_set()
        {
            m_cpu.target.set_input_line(0, ASSERT_LINE);

            // The execution time of one instruction is ~4us, so we must make sure to
            // give the cpu time to poll the /IRQ input before we clear it.
            // The input clock to the 06XX interface chip is 64H, that is
            // 18432000/6/64 = 48kHz, so it makes sense for the irq line to be
            // asserted for one clock cycle ~= 21us.
            m_irq_cleared_timer.adjust(attotime.from_usec(21), 0);
        }
예제 #12
0
        //-------------------------------------------------
        //  device_reset - reset the device
        //-------------------------------------------------
        protected override void device_reset()
        {
            // type based configuration
            switch (m_type)
            {
            case timer_type.TIMER_TYPE_GENERIC:
            case timer_type.TIMER_TYPE_PERIODIC:
            {
                // convert the period into attotime
                attotime period;
                if (m_period > attotime.zero)
                {
                    period = m_period;

                    // convert the start_delay into attotime
                    attotime start_delay = attotime.zero;
                    if (m_start_delay > attotime.zero)
                    {
                        start_delay = m_start_delay;
                    }

                    // allocate and start the backing timer
                    m_timer.adjust(start_delay, m_param, period);
                }
                break;
            }

            case timer_type.TIMER_TYPE_SCANLINE:
                if (m_screen == null)
                {
                    fatalerror("timer '{0}': unable to find screen '{1}'\n", tag(), m_screen.finder_tag());
                }

                // set the timer to fire immediately
                m_first_time = true;
                m_timer.adjust(attotime.zero, m_param);
                break;
            }
        }
예제 #13
0
        attotime m_last_update;                                                    // last update time


        // construction/destruction

        //-------------------------------------------------
        //  sound_manager - constructor
        //-------------------------------------------------
        public sound_manager(running_machine machine)
        {
            m_machine            = machine;
            m_update_timer       = null;
            m_finalmix_leftover  = 0;
            m_finalmix           = new std.vector <s16>(machine.sample_rate());
            m_leftmix            = new std.vector <s32>(machine.sample_rate());
            m_rightmix           = new std.vector <s32>(machine.sample_rate());
            m_nosound_mode       = machine.osd().no_sound() ? 1 : 0;
            m_wavfile            = null;
            m_update_attoseconds = STREAMS_UPDATE_ATTOTIME.attoseconds();
            m_last_update        = attotime.zero;


            // get filename for WAV file or AVI file if specified
            string wavfile = machine.options().wav_write();
            string avifile = machine.options().avi_write();

            // handle -nosound and lower sample rate if not recording WAV or AVI
            if (m_nosound_mode != 0 && string.IsNullOrEmpty(wavfile) && string.IsNullOrEmpty(avifile))
            {
                machine.sample_rate_set(11025);
            }

            // count the mixers
            if (sound_global.VERBOSE)
            {
                mixer_interface_iterator iter = new mixer_interface_iterator(machine.root_device());
                sound_global.VPRINTF("total mixers = {0}\n", iter.count());
            }

            // register callbacks
            machine.configuration().config_register("mixer", config_load, config_save);
            machine.add_notifier(machine_notification.MACHINE_NOTIFY_PAUSE, pause);
            machine.add_notifier(machine_notification.MACHINE_NOTIFY_RESUME, resume);
            machine.add_notifier(machine_notification.MACHINE_NOTIFY_RESET, reset);
            machine.add_notifier(machine_notification.MACHINE_NOTIFY_EXIT, stop_recording);

            // register global states
            machine.save().save_item(m_last_update, "m_last_update");

            // set the starting attenuation
            set_attenuation(machine.options().volume());

            // start the periodic update flushing timer
            m_update_timer = machine.scheduler().timer_alloc(update, this);
            m_update_timer.adjust(STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME);
        }
예제 #14
0
        //TIMER_CALLBACK_MEMBER(run_state_machine);
        void run_state_machine(object ptr, int param)
        {
            int cycles = 0;

            while (cycles < VGSLICE)
            {
                // Get next state
                m_state_latch = (u8)((m_state_latch & 0x10) | (m_prom.op[state_addr()] & 0xf));

                if (ST3() != 0)
                {
                    // Read vector RAM/ROM
                    update_databus();

                    // Decode state and call the corresponding handler
                    switch (m_state_latch & 7)
                    {
                    case 0: cycles += handler_0(); break;

                    case 1: cycles += handler_1(); break;

                    case 2: cycles += handler_2(); break;

                    case 3: cycles += handler_3(); break;

                    case 4: cycles += handler_4(); break;

                    case 5: cycles += handler_5(); break;

                    case 6: cycles += handler_6(); break;

                    case 7: cycles += handler_7(); break;
                    }
                }

                // If halt flag was set, let CPU catch up before we make halt visible
                if (m_halt != 0 && (m_state_latch & 0x10) == 0)
                {
                    m_vg_halt_timer.adjust(attotime.from_hz(MASTER_CLOCK) * (u32)cycles, 1);
                }

                m_state_latch = (u8)((m_halt << 4) | (m_state_latch & 0xf));
                cycles       += 8;
            }

            m_vg_run_timer.adjust(attotime.from_hz(MASTER_CLOCK) * (u32)cycles);
        }
예제 #15
0
 //-------------------------------------------------
 //  device_timer: Handle device-specific timer
 //  calbacks
 //-------------------------------------------------
 protected override void device_timer(emu_timer timer, device_timer_id id, int param, object ptr)
 {
     switch (id)
     {
     case TID_FORCE_UPDATE:
         if (param > 0)
         {
             m_divideo.screen().update_partial(param - 1);
         }
         param += 64;
         if (param >= m_divideo.screen().visible_area().bottom())
         {
             param = 0;
         }
         timer.adjust(m_divideo.screen().time_until_pos(param), param);
         break;
     }
 }
예제 #16
0
파일: msm5205.cs 프로젝트: kwanboy/mcs
        protected override void device_timer(emu_timer timer, device_timer_id id, int param, object ptr)
        {
            switch (id)
            {
            case TIMER_VCK:
                m_vck = !m_vck;
                m_vck_cb.op(m_vck ? 1 : 0);
                if (!m_vck)
                {
                    m_capture_timer.adjust(attotime.from_nsec(15600));
                }
                break;

            case TIMER_ADPCM_CAPTURE:
                update_adpcm();
                break;
            }
        }
예제 #17
0
        protected override void device_timer(emu_timer timer, device_timer_id id, int param, object ptr)
        {
            switch (id)
            {
            case TIMER_VCK:
                m_vck = !m_vck;
                m_vck_cb.op_s32(m_vck ? 1 : 0);
                if (!m_vck)
                {
                    m_capture_timer.adjust(attotime.from_hz(clock() / 6));     // 15.6 usec at 384KHz
                }
                break;

            case TIMER_ADPCM_CAPTURE:
                update_adpcm();
                break;
            }
        }
예제 #18
0
        //void address_data_start_w(u8 data); // start and ale connected, address to the data bus


        // device-level overrides
        protected override void device_start()
        {
            // resolve callbacks
            m_eoc_cb.resolve_safe();
            m_eoc_ff_cb.resolve_safe();
            m_in_cb.resolve_all_safe_u8(0xff);

            // allocate timers
            m_cycle_timer = timer_alloc();
            m_cycle_timer.adjust(attotime.zero, 0, attotime.from_hz(clock()));

            // register for save states
            save_item(NAME(new { m_state }));
            save_item(NAME(new { m_start }));
            save_item(NAME(new { m_address }));
            save_item(NAME(new { m_sar }));
            save_item(NAME(new { m_eoc }));
        }
예제 #19
0
        //WRITE_LINE_MEMBER( adc0808_device::start_w )
        void start_w(int state_)
        {
            if (m_start == state_)
            {
                return;
            }

            if (state_ != 0 && m_start == 0)
            {
                m_state = state.STATE_CONVERSION_START;
                m_cycle_timer.adjust(attotime.from_hz(clock()));
            }
            else if (state_ == 0 && m_start != 0)
            {
                m_cycle_timer.adjust(attotime.from_hz(clock()));
            }

            m_start = state_;
        }
예제 #20
0
파일: natkeyboard.cs 프로젝트: kwanboy/mcs
        //void internal_post(char32_t ch);


        //-------------------------------------------------
        //  timer - timer callback to keep things flowing
        //  when posting a string of characters
        //-------------------------------------------------
        void timer(object ptr, int param)
        {
            if (m_queue_chars != null)
            {
                // the driver has a queue_chars handler
                while (!empty() && m_queue_chars(m_buffer, m_bufbegin, 1) != 0)
                {
                    m_bufbegin = (m_bufbegin + 1) % (UInt32)m_buffer.size();
                    if (m_current_rate != attotime.zero)
                    {
                        break;
                    }
                }
            }
            else
            {
                // the driver does not have a queue_chars handler

                // loop through this character's component codes
                keycode_map_entry code = find_code(m_buffer[(int)m_bufbegin]);
                bool advance;
                if (code != null)
                {
                    do
                    {
                        assert(m_fieldnum < code.field.Length);

                        ioport_field field = code.field[m_fieldnum];
                        if (field != null)
                        {
                            // special handling for toggle fields
                            if (!field.live().toggle)
                            {
                                field.set_value(!m_status_keydown ? (UInt32)1 : 0);
                            }
                            else if (!m_status_keydown)
                            {
                                field.set_value(!field.digital_value() ? (UInt32)1 : 0);
                            }
                        }
                    }while (code.field[m_fieldnum] != null && (++m_fieldnum < code.field.Length) && m_status_keydown);
                    advance = (m_fieldnum >= code.field.Length) || code.field[m_fieldnum] == null;
                }
                else
                {
                    advance = true;
                }

                if (advance)
                {
                    m_fieldnum       = 0;
                    m_status_keydown = !m_status_keydown;

                    // proceed to next character when keydown expires
                    if (!m_status_keydown)
                    {
                        m_bufbegin = (m_bufbegin + 1) % (UInt32)m_buffer.size();
                    }
                }
            }

            // need to make sure timerproc is called again if buffer not empty
            if (!empty())
            {
                m_timer.adjust(choose_delay(m_buffer[(int)m_bufbegin]));
            }
        }
예제 #21
0
 void reset(running_machine machine)
 {
     // setup autoboot if needed
     m_autoboot_timer.adjust(new attotime(options().autoboot_delay(), 0), 0);
 }
예제 #22
0
        //void apply_stain(bitmap_ind16 &bitmap, uint16_t *pf, uint16_t *mo, int x, int y);

        // memory access
        //uint16_t &slipram(int offset) { return m_slipram[offset]; }


        // device-level overrides

        //-------------------------------------------------
        //  device_start: Start up the device
        //-------------------------------------------------
        protected override void device_start()
        {
            // call parent
            base.device_start();

            // verify configuration
            gfx_element gfx = m_gfxdecode.op0.gfx(m_atari_motion_objects_config.m_gfxindex);

            if (gfx == null)
            {
                throw new emu_fatalerror("No gfxelement #{0}!", m_atari_motion_objects_config.m_gfxindex);
            }

            // determine the masks
            m_linkmask.set(m_atari_motion_objects_config.m_link_entry);
            m_codemask.set(m_atari_motion_objects_config.m_code_entry);
            m_colormask.set(m_atari_motion_objects_config.m_color_entry);
            m_xposmask.set(m_atari_motion_objects_config.m_xpos_entry);
            m_yposmask.set(m_atari_motion_objects_config.m_ypos_entry);
            m_widthmask.set(m_atari_motion_objects_config.m_width_entry);
            m_heightmask.set(m_atari_motion_objects_config.m_height_entry);
            m_hflipmask.set(m_atari_motion_objects_config.m_hflip_entry);
            m_vflipmask.set(m_atari_motion_objects_config.m_vflip_entry);
            m_prioritymask.set(m_atari_motion_objects_config.m_priority_entry);
            m_neighbormask.set(m_atari_motion_objects_config.m_neighbor_entry);
            m_absolutemask.set(m_atari_motion_objects_config.m_absolute_entry);

            // derive tile information
            m_tilewidth  = gfx.width();
            m_tileheight = gfx.height();
            m_tilexshift = compute_log(m_tilewidth);
            m_tileyshift = compute_log(m_tileheight);

            // derive bitmap information
            m_bitmapwidth  = round_to_powerof2(m_xposmask.mask());
            m_bitmapheight = round_to_powerof2(m_yposmask.mask());
            m_bitmapxmask  = m_bitmapwidth - 1;
            m_bitmapymask  = m_bitmapheight - 1;

            // derive sprite information
            m_entrycount    = round_to_powerof2(m_linkmask.mask());
            m_entrybits     = compute_log(m_entrycount);
            m_spriteramsize = m_atari_motion_objects_config.m_bankcount * m_entrycount;
            m_spriterammask = m_spriteramsize - 1;
            m_slipshift     = (m_atari_motion_objects_config.m_slipheight != 0) ? compute_log(m_atari_motion_objects_config.m_slipheight) : 0;
            m_slipramsize   = m_bitmapheight >> m_slipshift;
            m_sliprammask   = m_slipramsize - 1;
            if (m_atari_motion_objects_config.m_maxperline == 0)
            {
                m_atari_motion_objects_config.m_maxperline = MAX_PER_BANK;
            }

            // Get the slipram from the share if not already explicitly set
            if (m_slipram == null)
            {
                m_slipram = new Pointer <u16>(m_slipramshare.op);
            }

            // allocate and initialize the code lookup
            int codesize = round_to_powerof2((int)m_codemask.mask());

            m_codelookup.resize((size_t)codesize);
            for (int i = 0; i < codesize; i++)
            {
                m_codelookup[i] = (uint32_t)i;
            }

            // allocate and initialize the color lookup
            int colorsize = round_to_powerof2((int)m_colormask.mask());

            m_colorlookup.resize((size_t)colorsize);
            for (int i = 0; i < colorsize; i++)
            {
                m_colorlookup[i] = (uint8_t)i;
            }

            // allocate and the gfx lookup
            int gfxsize = codesize / 256;

            m_gfxlookup.resize((size_t)gfxsize);
            for (int i = 0; i < gfxsize; i++)
            {
                m_gfxlookup[i] = m_atari_motion_objects_config.m_gfxindex;
            }

            // allocate a timer to periodically force update
            m_force_update_timer = timer_alloc(TID_FORCE_UPDATE);
            m_force_update_timer.adjust(m_divideo.screen().time_until_pos(0));

            // register for save states
            save_item(NAME(new { m_bank }));
            save_item(NAME(new { m_xscroll }));
            save_item(NAME(new { m_yscroll }));
        }
예제 #23
0
        // internal helpers

        //-------------------------------------------------
        //  recompute_sample_rate_data - recompute sample
        //  rate data, and all streams that are affected
        //  by this stream
        //-------------------------------------------------
        void recompute_sample_rate_data()
        {
            if (m_synchronous)
            {
                m_sample_rate = 0;
                // When synchronous, pick the sample rate for the inputs, if any
                for (int inputnum = 0; inputnum < m_input.size(); inputnum++)
                {
                    stream_input input = m_input[inputnum];
                    if (input.m_source != null)
                    {
                        if (m_sample_rate == 0)
                        {
                            m_sample_rate = input.m_source.m_stream.m_sample_rate;
                        }
                        else if (m_sample_rate != input.m_source.m_stream.m_sample_rate)
                        {
                            throw new emu_fatalerror("Incompatible sample rates as input of a synchronous stream: {0} and {1}\n", m_sample_rate, input.m_source.m_stream.m_sample_rate);
                        }
                    }
                }
            }


            // recompute the timing parameters
            attoseconds_t update_attoseconds = m_device.machine().sound().update_attoseconds();

            if (m_sample_rate != 0)
            {
                m_attoseconds_per_sample = attotime.ATTOSECONDS_PER_SECOND / m_sample_rate;
                m_max_samples_per_update = (int)((update_attoseconds + m_attoseconds_per_sample - 1) / m_attoseconds_per_sample);
            }
            else
            {
                m_attoseconds_per_sample = 0;
                m_max_samples_per_update = 0;
            }

            // update resample and output buffer sizes
            allocate_resample_buffers();
            allocate_output_buffers();

            // iterate over each input
            for (int inputnum = 0; inputnum < m_input.size(); inputnum++)  // for (auto & input : m_input)
            {
                var input = m_input[inputnum];

                // if we have a source, see if its sample rate changed
                if (input.m_source != null && input.m_source.m_stream.m_sample_rate != 0)
                {
                    // okay, we have a new sample rate; recompute the latency to be the maximum
                    // sample period between us and our input
                    attoseconds_t new_attosecs_per_sample = attotime.ATTOSECONDS_PER_SECOND / input.m_source.m_stream.m_sample_rate;
                    attoseconds_t latency = Math.Max(new_attosecs_per_sample, m_attoseconds_per_sample);

                    // if the input stream's sample rate is lower, we will use linear interpolation
                    // this requires an extra sample from the source
                    if (input.m_source.m_stream.m_sample_rate < m_sample_rate)
                    {
                        latency += new_attosecs_per_sample;
                    }

                    // if our sample rates match exactly, we don't need any latency
                    else if (input.m_source.m_stream.m_sample_rate == m_sample_rate)
                    {
                        latency = 0;
                    }

                    // we generally don't want to tweak the latency, so we just keep the greatest
                    // one we've computed thus far
                    input.m_latency_attoseconds = Math.Max(input.m_latency_attoseconds, latency);

                    //throw new emu_unimplemented();
#if false
                    assert(input.m_latency_attoseconds < update_attoseconds);
#endif
                }
                else
                {
                    input.m_latency_attoseconds = 0;
                }
            }

            // If synchronous, prime the timer
            if (m_synchronous)
            {
                attotime time = m_device.machine().time();
                if (m_attoseconds_per_sample != 0)
                {
                    attoseconds_t next_edge = m_attoseconds_per_sample - (time.attoseconds() % m_attoseconds_per_sample);
                    m_sync_timer.adjust(new attotime(0, next_edge));
                }
                else
                {
                    m_sync_timer.adjust(attotime.never);
                }
            }
        }
예제 #24
0
        // construction/destruction

        //-------------------------------------------------
        //  video_manager - constructor
        //-------------------------------------------------
        public video_manager(running_machine machine)
        {
            m_machine = machine;
            m_screenless_frame_timer = null;
            m_output_changed         = false;
            m_throttle_realtime      = attotime.zero;
            m_throttle_emutime       = attotime.zero;
            m_throttle_history       = 0;
            m_speed_last_realtime    = 0;
            m_speed_last_emutime     = attotime.zero;
            m_speed_percent          = 1.0;
            m_overall_real_seconds   = 0;
            m_overall_real_ticks     = 0;
            m_overall_emutime        = attotime.zero;
            m_overall_valid_counter  = 0;
            m_frame_update_counter   = 0;
            m_throttled           = true;
            m_throttle_rate       = 1.0f;
            m_fastforward         = false;
            m_seconds_to_run      = (u32)machine.options().seconds_to_run();
            m_auto_frameskip      = machine.options().auto_frameskip();
            m_speed               = (u32)original_speed_setting();
            m_low_latency         = machine.options().low_latency();
            m_empty_skip_count    = 0;
            m_frameskip_max       = m_auto_frameskip ? (u8)machine.options().frameskip() : (u8)0;
            m_frameskip_level     = m_auto_frameskip ? (u8)0 : (u8)machine.options().frameskip();
            m_frameskip_counter   = 0;
            m_frameskip_adjust    = 0;
            m_skipping_this_frame = false;
            m_average_oversleep   = 0;
            m_snap_target         = null;
            m_snap_native         = true;
            m_snap_width          = 0;
            m_snap_height         = 0;


            // request a callback upon exiting
            machine.add_notifier(machine_notification.MACHINE_NOTIFY_EXIT, exit);
            machine.save().register_postload(postload);

            // extract initial execution state from global configuration settings
            update_refresh_speed();

            unsigned screen_count = (unsigned)(new screen_device_enumerator(machine.root_device()).count());
            bool     no_screens   = screen_count == 0;

            // create a render target for snapshots
            string viewname = machine.options().snap_view();

            m_snap_native = !no_screens && std.strcmp(viewname, "native") == 0;

            // the native target is hard-coded to our internal layout and has all options disabled
            if (m_snap_native)
            {
                throw new emu_unimplemented();
            }
            else
            {
                // other targets select the specified view and turn off effects
                m_snap_target = machine.render().target_alloc(null, RENDER_CREATE_HIDDEN);
                m_snap_target.set_view(m_snap_target.configured_view(viewname, 0, 1));
                m_snap_target.set_screen_overlay_enabled(false);
            }

            // extract snap resolution if present
            //if (sscanf(machine.options().snap_size(), "%dx%d", &m_snap_width, &m_snap_height) != 2)
            var parts = machine.options().snap_size().Split('x');

            if (parts.Length == 2)
            {
                m_snap_width  = Convert.ToInt32(parts[0]);
                m_snap_height = Convert.ToInt32(parts[1]);
            }
            else
            {
                m_snap_width = m_snap_height = 0;
            }

            // if no screens, create a periodic timer to drive updates
            if (no_screens)
            {
                m_screenless_frame_timer = machine.scheduler().timer_alloc(screenless_update_callback, this);
                m_screenless_frame_timer.adjust(screen_device.DEFAULT_FRAME_PERIOD, 0, screen_device.DEFAULT_FRAME_PERIOD);
                machine.output().set_global_notifier(video_notifier_callback, this);
            }
        }
예제 #25
0
        // device_execute_interface overrides
        //virtual UINT32 execute_min_cycles() const { return 1; }
        //virtual UINT32 execute_max_cycles() const { return 3; }
        //virtual UINT32 execute_input_lines() const { return 1; }

        public void device_execute_interface_execute_run()
        {
            while (m_icountRef.i > 0)
            {
                byte opcode;
                byte arg;
                byte oc;

                /* fetch the opcode */
                debugger_instruction_hook(GETPC());
                opcode = READOP(GETPC());

                /* increment the PC */
                INCPC();

                /* start with instruction doing 1 cycle */
                oc = 1;

                switch (opcode)
                {
                case 0x00:     /* nop ZCS:...*/
                    m_st = 1;
                    break;

                case 0x01:     /* outO ZCS:...*/
                    m_write_o.op((byte)pla(m_A, TEST_CF()));
                    m_st = 1;
                    break;

                case 0x02:     /* outP ZCS:... */
                    m_write_p.op(m_A);
                    m_st = 1;
                    break;

                case 0x03:     /* outR ZCS:... */
                    arg = m_Y;
                    m_write_r[arg & 3].op(m_A);
                    m_st = 1;
                    break;

                case 0x04:     /* tay ZCS:... */
                    m_Y  = m_A;
                    m_st = 1;
                    break;

                case 0x05:     /* tath ZCS:... */
                    m_TH = m_A;
                    m_st = 1;
                    break;

                case 0x06:     /* tatl ZCS:... */
                    m_TL = m_A;
                    m_st = 1;
                    break;

                case 0x07:     /* tas ZCS:... */
                    m_SB = m_A;
                    m_st = 1;
                    break;

                case 0x08:     /* icy ZCS:x.x */
                    m_Y++;
                    UPDATE_ST_C(m_Y);
                    m_Y &= 0x0f;
                    UPDATE_ZF(m_Y);
                    break;

                case 0x09:     /* icm ZCS:x.x */
                    arg = RDMEM(GETEA());
                    arg++;
                    UPDATE_ST_C(arg);
                    arg &= 0x0f;
                    UPDATE_ZF(arg);
                    WRMEM(GETEA(), arg);
                    break;

                case 0x0a:     /* stic ZCS:x.x */
                    WRMEM(GETEA(), m_A);
                    m_Y++;
                    UPDATE_ST_C(m_Y);
                    m_Y &= 0x0f;
                    UPDATE_ZF(m_Y);
                    break;

                case 0x0b:     /* x ZCS:x.. */
                    arg = RDMEM(GETEA());
                    WRMEM(GETEA(), m_A);
                    m_A = arg;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x0c:     /* rol ZCS:xxx */
                    m_A <<= 1;
                    m_A  |= (byte)TEST_CF();
                    UPDATE_ST_C(m_A);
                    m_cf = (byte)(m_st ^ 1);
                    m_A &= 0x0f;
                    UPDATE_ZF(m_A);
                    break;

                case 0x0d:     /* l ZCS:x.. */
                    m_A = RDMEM(GETEA());
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x0e:     /* adc ZCS:xxx */
                    arg  = RDMEM(GETEA());
                    arg += m_A;
                    arg += (byte)TEST_CF();
                    UPDATE_ST_C(arg);
                    m_cf = (byte)(m_st ^ 1);
                    m_A  = (byte)(arg & 0x0f);
                    UPDATE_ZF(m_A);
                    break;

                case 0x0f:     /* and ZCS:x.x */
                    m_A &= RDMEM(GETEA());
                    UPDATE_ZF(m_A);
                    m_st = (byte)(m_zf ^ 1);
                    break;

                case 0x10:     /* daa ZCS:.xx */
                    if (TEST_CF() != 0 || m_A > 9)
                    {
                        m_A += 6;
                    }
                    UPDATE_ST_C(m_A);
                    m_cf = (byte)(m_st ^ 1);
                    m_A &= 0x0f;
                    break;

                case 0x11:     /* das ZCS:.xx */
                    if (TEST_CF() != 0 || m_A > 9)
                    {
                        m_A += 10;
                    }
                    UPDATE_ST_C(m_A);
                    m_cf = (byte)(m_st ^ 1);
                    m_A &= 0x0f;
                    break;

                case 0x12:     /* inK ZCS:x.. */
                    m_A = (byte)(m_read_k.op() & 0x0f);
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x13:     /* inR ZCS:x.. */
                    arg = m_Y;
                    m_A = (byte)(m_read_r[arg & 3].op() & 0x0f);
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x14:     /* tya ZCS:x.. */
                    m_A = m_Y;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x15:     /* ttha ZCS:x.. */
                    m_A = m_TH;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x16:     /* ttla ZCS:x.. */
                    m_A = m_TL;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x17:     /* tsa ZCS:x.. */
                    m_A = m_SB;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x18:     /* dcy ZCS:..x */
                    m_Y--;
                    UPDATE_ST_C(m_Y);
                    m_Y &= 0x0f;
                    break;

                case 0x19:     /* dcm ZCS:x.x */
                    arg = RDMEM(GETEA());
                    arg--;
                    UPDATE_ST_C(arg);
                    arg &= 0x0f;
                    UPDATE_ZF(arg);
                    WRMEM(GETEA(), arg);
                    break;

                case 0x1a:     /* stdc ZCS:x.x */
                    WRMEM(GETEA(), m_A);
                    m_Y--;
                    UPDATE_ST_C(m_Y);
                    m_Y &= 0x0f;
                    UPDATE_ZF(m_Y);
                    break;

                case 0x1b:     /* xx ZCS:x.. */
                    arg = m_X;
                    m_X = m_A;
                    m_A = arg;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x1c:     /* ror ZCS:xxx */
                    m_A |= (byte)(TEST_CF() << 4);
                    UPDATE_ST_C((byte)(m_A << 4));
                    m_cf  = (byte)(m_st ^ 1);
                    m_A >>= 1;
                    m_A  &= 0x0f;
                    UPDATE_ZF(m_A);
                    break;

                case 0x1d:     /* st ZCS:x.. */
                    WRMEM(GETEA(), m_A);
                    m_st = 1;
                    break;

                case 0x1e:     /* sbc ZCS:xxx */
                    arg  = RDMEM(GETEA());
                    arg -= m_A;
                    arg -= (byte)TEST_CF();
                    UPDATE_ST_C(arg);
                    m_cf = (byte)(m_st ^ 1);
                    m_A  = (byte)(arg & 0x0f);
                    UPDATE_ZF(m_A);
                    break;

                case 0x1f:     /* or ZCS:x.x */
                    m_A |= RDMEM(GETEA());
                    UPDATE_ZF(m_A);
                    m_st = (byte)(m_zf ^ 1);
                    break;

                case 0x20:     /* setR ZCS:... */
                    arg = m_read_r[m_Y / 4].op();
                    m_write_r[m_Y / 4].op((byte)(arg | (1 << (m_Y % 4))));
                    m_st = 1;
                    break;

                case 0x21:     /* setc ZCS:.xx */
                    m_cf = 1;
                    m_st = 1;
                    break;

                case 0x22:     /* rstR ZCS:... */
                    arg = m_read_r[m_Y / 4].op();
                    m_write_r[m_Y / 4].op((byte)(arg & ~(1 << (m_Y % 4))));
                    m_st = 1;
                    break;

                case 0x23:     /* rstc ZCS:.xx */
                    m_cf = 0;
                    m_st = 1;
                    break;

                case 0x24:     /* tstr ZCS:..x */
                    arg  = m_read_r[m_Y / 4].op();
                    m_st = (arg & (1 << (m_Y % 4))) != 0 ? (byte)0 : (byte)1;
                    break;

                case 0x25:     /* tsti ZCS:..x */
                    m_st = (byte)(m_nf ^ 1);
                    break;

                case 0x26:     /* tstv ZCS:..x */
                    m_st = (byte)(m_vf ^ 1);
                    m_vf = 0;
                    break;

                case 0x27:     /* tsts ZCS:..x */
                    m_st = (byte)(m_sf ^ 1);
                    if (m_sf != 0)
                    {
                        /* re-enable the timer if we disabled it previously */
                        if (m_SBcount >= mb88_cpu_device.SERIAL_DISABLE_THRESH)
                        {
                            m_serial.adjust(attotime.from_hz(clock() / mb88_cpu_device.SERIAL_PRESCALE), 0, attotime.from_hz(clock() / mb88_cpu_device.SERIAL_PRESCALE));
                        }
                        m_SBcount = 0;
                    }
                    m_sf = 0;
                    break;

                case 0x28:     /* tstc ZCS:..x */
                    m_st = (byte)(m_cf ^ 1);
                    break;

                case 0x29:     /* tstz ZCS:..x */
                    m_st = (byte)(m_zf ^ 1);
                    break;

                case 0x2a:     /* sts ZCS:x.. */
                    WRMEM(GETEA(), m_SB);
                    UPDATE_ZF(m_SB);
                    m_st = 1;
                    break;

                case 0x2b:     /* ls ZCS:x.. */
                    m_SB = RDMEM(GETEA());
                    UPDATE_ZF(m_SB);
                    m_st = 1;
                    break;

                case 0x2c:     /* rts ZCS:... */
                    m_SI = (byte)((m_SI - 1) & 3);
                    m_PC = (byte)(m_SP[m_SI] & 0x3f);
                    m_PA = (byte)((m_SP[m_SI] >> 6) & 0x1f);
                    m_st = 1;
                    break;

                case 0x2d:     /* neg ZCS: ..x */
                    m_A  = (byte)((~m_A) + 1);
                    m_A &= 0x0f;
                    UPDATE_ST_Z(m_A);
                    break;

                case 0x2e:     /* c ZCS:xxx */
                    arg  = RDMEM(GETEA());
                    arg -= m_A;
                    UPDATE_CF(arg);
                    arg &= 0x0f;
                    UPDATE_ST_Z(arg);
                    m_zf = (byte)(m_st ^ 1);
                    break;

                case 0x2f:     /* eor ZCS:x.x */
                    m_A ^= RDMEM(GETEA());
                    UPDATE_ST_Z(m_A);
                    m_zf = (byte)(m_st ^ 1);
                    break;

                case 0x30:
                case 0x31:
                case 0x32:
                case 0x33:                                      /* sbit ZCS:... */
                    arg = RDMEM(GETEA());
                    WRMEM(GETEA(), (byte)(arg | (1 << (opcode & 3))));
                    m_st = 1;
                    break;

                case 0x34:
                case 0x35:
                case 0x36:
                case 0x37:                                      /* rbit ZCS:... */
                    arg = RDMEM(GETEA());
                    WRMEM(GETEA(), (byte)(arg & ~(1 << (opcode & 3))));
                    m_st = 1;
                    break;

                case 0x38:
                case 0x39:
                case 0x3a:
                case 0x3b:                                      /* tbit ZCS:... */
                    arg  = RDMEM(GETEA());
                    m_st = (arg & (1 << (opcode & 3))) != 0 ? (byte)0 : (byte)1;
                    break;

                case 0x3c:     /* rti ZCS:... */
                    /* restore address and saved state flags on the top bits of the stack */
                    m_SI = (byte)((m_SI - 1) & 3);
                    m_PC = (byte)(m_SP[m_SI] & 0x3f);
                    m_PA = (byte)((m_SP[m_SI] >> 6) & 0x1f);
                    m_st = (byte)((m_SP[m_SI] >> 13) & 1);
                    m_zf = (byte)((m_SP[m_SI] >> 14) & 1);
                    m_cf = (byte)((m_SP[m_SI] >> 15) & 1);
                    break;

                case 0x3d:     /* jpa imm ZCS:..x */
                    m_PA = (byte)(READOP(GETPC()) & 0x1f);
                    m_PC = (byte)(m_A * 4);
                    oc   = 2;
                    m_st = 1;
                    break;

                case 0x3e:     /* en imm ZCS:... */
                    update_pio_enable((byte)(m_pio | READOP(GETPC())));
                    INCPC();
                    oc   = 2;
                    m_st = 1;
                    break;

                case 0x3f:     /* dis imm ZCS:... */
                    update_pio_enable((byte)(m_pio & ~(READOP(GETPC()))));
                    INCPC();
                    oc   = 2;
                    m_st = 1;
                    break;

                case 0x40:
                case 0x41:
                case 0x42:
                case 0x43:                                         /* setD ZCS:... */
                    arg  = m_read_r[0].op();
                    arg |= (byte)(1 << (opcode & 3));
                    m_write_r[0].op(arg);
                    m_st = 1;
                    break;

                case 0x44:
                case 0x45:
                case 0x46:
                case 0x47:                                         /* rstD ZCS:... */
                    arg  = m_read_r[0].op();
                    arg &= (byte)(~(1 << (opcode & 3)));
                    m_write_r[0].op(arg);
                    m_st = 1;
                    break;

                case 0x48:
                case 0x49:
                case 0x4a:
                case 0x4b:                                         /* tstD ZCS:..x */
                    arg  = m_read_r[2].op();
                    m_st = (arg & (1 << (opcode & 3))) != 0 ? (byte)0 : (byte)1;
                    break;

                case 0x4c:
                case 0x4d:
                case 0x4e:
                case 0x4f:                                         /* tba ZCS:..x */
                    m_st = (m_A & (1 << (opcode & 3))) != 0 ? (byte)0 : (byte)1;
                    break;

                case 0x50:
                case 0x51:
                case 0x52:
                case 0x53:                                         /* xd ZCS:x.. */
                    arg = RDMEM((UInt32)(opcode & 3));
                    WRMEM((UInt32)(opcode & 3), m_A);
                    m_A = arg;
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0x54:
                case 0x55:
                case 0x56:
                case 0x57:                                         /* xyd ZCS:x.. */
                    arg = RDMEM((UInt32)((opcode & 3) + 4));
                    WRMEM((UInt32)((opcode & 3) + 4), m_Y);
                    m_Y = arg;
                    UPDATE_ZF(m_Y);
                    m_st = 1;
                    break;

                case 0x58:
                case 0x59:
                case 0x5a:
                case 0x5b:
                case 0x5c:
                case 0x5d:
                case 0x5e:
                case 0x5f:                                         /* lxi ZCS:x.. */
                    m_X = (byte)(opcode & 7);
                    UPDATE_ZF(m_X);
                    m_st = 1;
                    break;

                case 0x60:
                case 0x61:
                case 0x62:
                case 0x63:
                case 0x64:
                case 0x65:
                case 0x66:
                case 0x67:                                         /* call imm ZCS:..x */
                    arg = READOP(GETPC());
                    INCPC();
                    oc = 2;
                    if (TEST_ST() != 0)
                    {
                        m_SP[m_SI] = GETPC();
                        m_SI       = (byte)((m_SI + 1) & 3);
                        m_PC       = (byte)(arg & 0x3f);
                        m_PA       = (byte)(((opcode & 7) << 2) | (arg >> 6));
                    }
                    m_st = 1;
                    break;

                case 0x68:
                case 0x69:
                case 0x6a:
                case 0x6b:
                case 0x6c:
                case 0x6d:
                case 0x6e:
                case 0x6f:                                         /* jpl imm ZCS:..x */
                    arg = READOP(GETPC());
                    INCPC();
                    oc = 2;
                    if (TEST_ST() != 0)
                    {
                        m_PC = (byte)(arg & 0x3f);
                        m_PA = (byte)(((opcode & 7) << 2) | (arg >> 6));
                    }
                    m_st = 1;
                    break;

                case 0x70:
                case 0x71:
                case 0x72:
                case 0x73:
                case 0x74:
                case 0x75:
                case 0x76:
                case 0x77:
                case 0x78:
                case 0x79:
                case 0x7a:
                case 0x7b:
                case 0x7c:
                case 0x7d:
                case 0x7e:
                case 0x7f:                                         /* ai ZCS:xxx */
                    arg  = (byte)(opcode & 0x0f);
                    arg += m_A;
                    UPDATE_ST_C(arg);
                    m_cf = (byte)(m_st ^ 1);
                    m_A  = (byte)(arg & 0x0f);
                    UPDATE_ZF(m_A);
                    break;

                case 0x80:
                case 0x81:
                case 0x82:
                case 0x83:
                case 0x84:
                case 0x85:
                case 0x86:
                case 0x87:
                case 0x88:
                case 0x89:
                case 0x8a:
                case 0x8b:
                case 0x8c:
                case 0x8d:
                case 0x8e:
                case 0x8f:                                         /* lxi ZCS:x.. */
                    m_Y = (byte)(opcode & 0x0f);
                    UPDATE_ZF(m_Y);
                    m_st = 1;
                    break;

                case 0x90:
                case 0x91:
                case 0x92:
                case 0x93:
                case 0x94:
                case 0x95:
                case 0x96:
                case 0x97:
                case 0x98:
                case 0x99:
                case 0x9a:
                case 0x9b:
                case 0x9c:
                case 0x9d:
                case 0x9e:
                case 0x9f:                                         /* li ZCS:x.. */
                    m_A = (byte)(opcode & 0x0f);
                    UPDATE_ZF(m_A);
                    m_st = 1;
                    break;

                case 0xa0:
                case 0xa1:
                case 0xa2:
                case 0xa3:
                case 0xa4:
                case 0xa5:
                case 0xa6:
                case 0xa7:
                case 0xa8:
                case 0xa9:
                case 0xaa:
                case 0xab:
                case 0xac:
                case 0xad:
                case 0xae:
                case 0xaf:                                         /* cyi ZCS:xxx */
                    arg = (byte)((opcode & 0x0f) - m_Y);
                    UPDATE_CF(arg);
                    arg &= 0x0f;
                    UPDATE_ST_Z(arg);
                    m_zf = (byte)(m_st ^ 1);
                    break;

                case 0xb0:
                case 0xb1:
                case 0xb2:
                case 0xb3:
                case 0xb4:
                case 0xb5:
                case 0xb6:
                case 0xb7:
                case 0xb8:
                case 0xb9:
                case 0xba:
                case 0xbb:
                case 0xbc:
                case 0xbd:
                case 0xbe:
                case 0xbf:                                         /* ci ZCS:xxx */
                    arg = (byte)((opcode & 0x0f) - m_A);
                    UPDATE_CF(arg);
                    arg &= 0x0f;
                    UPDATE_ST_Z(arg);
                    m_zf = (byte)(m_st ^ 1);
                    break;

                default:     /* jmp ZCS:..x */
                    if (TEST_ST() != 0)
                    {
                        m_PC = (byte)(opcode & 0x3f);
                    }
                    m_st = 1;
                    break;
                }

                /* update cycle counts */
                CYCLES(oc);

                /* update interrupts, serial and timer flags */
                update_pio(oc);
            }
        }