From a2a6971ef2e51cc5012ad2f97e7e66d626ba1179 Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Fri, 4 Apr 2014 09:58:00 +0000 Subject: [PATCH] upd3301: devcb2 & delegate. (nw) --- src/emu/delegate.h | 75 +++++++-- src/emu/video/upd3301.c | 328 ++++++++++++++++++------------------- src/emu/video/upd3301.h | 97 ++++++----- src/mess/drivers/pc8001.c | 30 ++-- src/mess/includes/pc8001.h | 1 + 5 files changed, 276 insertions(+), 255 deletions(-) diff --git a/src/emu/delegate.h b/src/emu/delegate.h index 6740e0a769d..4bf3573a370 100644 --- a/src/emu/delegate.h +++ b/src/emu/delegate.h @@ -160,56 +160,72 @@ public: // dummy class used to indicate a non-existant parameter class _noparam { }; -template +// specialization for 12 parameters +template struct delegate_traits +{ + typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type); + typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type); + typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type); +}; + +// specialization for 11 parameters +template +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type); typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type); }; +// specialization for 10 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type); typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type); }; +// specialization for 9 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type); typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type); }; +// specialization for 8 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type); typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type); }; +// specialization for 7 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type); typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type); }; +// specialization for 6 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type); typedef _ReturnType (_ClassType::*member_func_type)(_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type); }; +// specialization for 5 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type); @@ -218,7 +234,7 @@ struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Ty // specialization for 4 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type, _P4Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type, _P4Type); @@ -227,7 +243,7 @@ struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Ty // specialization for 3 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type, _P3Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type, _P3Type); @@ -236,7 +252,7 @@ struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _P3Type, _nopa // specialization for 2 parameters template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type, _P2Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type, _P2Type); @@ -245,7 +261,7 @@ struct delegate_traits<_ClassType, _ReturnType, _P1Type, _P2Type, _noparam, _nop // specialization for 1 parameter template -struct delegate_traits<_ClassType, _ReturnType, _P1Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _P1Type, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *, _P1Type); typedef _ReturnType (*static_ref_func_type)(_ClassType &, _P1Type); @@ -254,7 +270,7 @@ struct delegate_traits<_ClassType, _ReturnType, _P1Type, _noparam, _noparam, _no // specialization for no parameters template -struct delegate_traits<_ClassType, _ReturnType, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> +struct delegate_traits<_ClassType, _ReturnType, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam, _noparam> { typedef _ReturnType (*static_func_type)(_ClassType *); typedef _ReturnType (*static_ref_func_type)(_ClassType &); @@ -427,6 +443,14 @@ private: return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + template + static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5, _P6Type p6, _P7Type p7, _P8Type p8, _P9Type p9, _P10Type p10, _P11Type p11, _P12Type p12) + { + delegate_mfp *_this = reinterpret_cast(object); + typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5, _P6Type p6, _P7Type p7, _P8Type p8, _P9Type p9, _P10Type p10, _P11Type p11, _P12Type p12); + mfptype &mfp = *reinterpret_cast(&_this->m_rawdata); + return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); + } // helper to convert a function of a given type to a generic function, forcing template // instantiation to match the source type template @@ -515,7 +539,7 @@ private: // ======================> delegate_base // general delegate class template supporting up to 5 parameters -template +template class delegate_base { public: @@ -523,9 +547,9 @@ public: template struct traits { - typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type>::member_func_type member_func_type; - typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type>::static_func_type static_func_type; - typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type>::static_ref_func_type static_ref_func_type; + typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type>::member_func_type member_func_type; + typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type>::static_func_type static_func_type; + typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type>::static_ref_func_type static_ref_func_type; }; typedef typename traits::static_func_type generic_static_func; @@ -633,6 +657,7 @@ public: _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5, _P6Type p6, _P7Type p7, _P8Type p8, _P9Type p9) const { return (*m_function)(m_object, p1, p2, p3, p4, p5, p6, p7, p8, p9); } _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5, _P6Type p6, _P7Type p7, _P8Type p8, _P9Type p9, _P10Type p10) const { return (*m_function)(m_object, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5, _P6Type p6, _P7Type p7, _P8Type p8, _P9Type p9, _P10Type p10, _P11Type p11) const { return (*m_function)(m_object, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5, _P6Type p6, _P7Type p7, _P8Type p8, _P9Type p9, _P10Type p10, _P11Type p11, _P12Type p12) const { return (*m_function)(m_object, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } // getters bool has_object() const { return (object() != NULL); } @@ -896,4 +921,22 @@ public: template delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } delegate &operator=(const basetype &src) { *static_cast(this) = src; return *this; } }; + +// specialize for 12 parameters +template +class delegate<_ReturnType (_P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type)> : public delegate_base<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type> +{ + typedef delegate_base<_ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type, _P6Type, _P7Type, _P8Type, _P9Type, _P10Type, _P11Type, _P12Type> basetype; + +public: + // create a standard set of constructors + delegate() : basetype() { } + delegate(const basetype &src) : basetype(src) { } + delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object) { } + template delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } + template delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } + template delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } + delegate &operator=(const basetype &src) { *static_cast(this) = src; return *this; } +}; + #endif /* __DELEGATE_H__ */ diff --git a/src/emu/video/upd3301.c b/src/emu/video/upd3301.c index af320281977..f59438a6e50 100644 --- a/src/emu/video/upd3301.c +++ b/src/emu/video/upd3301.c @@ -22,13 +22,9 @@ */ -#include "emu.h" #include "upd3301.h" -// device type definition -const device_type UPD3301 = &device_creator; - //************************************************************************** // MACROS / CONSTANTS @@ -66,123 +62,10 @@ enum //************************************************************************** -// INLINE HELPERS +// DEVICE DEFINITIONS //************************************************************************** -//------------------------------------------------- -// set_interrupt - -//------------------------------------------------- - -inline void upd3301_device::set_interrupt(int state) -{ - if (LOG) logerror("UPD3301 '%s' Interrupt: %u\n", tag(), state); - - m_out_int_func(state); - - if (!state) - { - m_status &= ~(STATUS_N | STATUS_E); - } -} - - -//------------------------------------------------- -// set_drq - -//------------------------------------------------- - -inline void upd3301_device::set_drq(int state) -{ - if (LOG) logerror("UPD3301 '%s' DRQ: %u\n", tag(), state); - - m_out_drq_func(state); -} - - -//------------------------------------------------- -// set_display - -//------------------------------------------------- - -inline void upd3301_device::set_display(int state) -{ - if (state) - { - m_status |= STATUS_VE; - } - else - { - m_status &= ~STATUS_VE; - } -} - - -//------------------------------------------------- -// reset_counters - -//------------------------------------------------- - -inline void upd3301_device::reset_counters() -{ - set_interrupt(0); - set_drq(0); -} - - -//------------------------------------------------- -// update_hrtc_timer - -//------------------------------------------------- - -inline void upd3301_device::update_hrtc_timer(int state) -{ - int y = m_screen->vpos(); - - int next_x = state ? m_h : 0; - int next_y = state ? y : ((y + 1) % ((m_l + m_v) * m_width)); - - attotime duration = m_screen->time_until_pos(next_y, next_x); - - m_hrtc_timer->adjust(duration, !state); -} - - -//------------------------------------------------- -// update_vrtc_timer - -//------------------------------------------------- - -inline void upd3301_device::update_vrtc_timer(int state) -{ - int next_y = state ? (m_l * m_r) : 0; - - attotime duration = m_screen->time_until_pos(next_y, 0); - - m_vrtc_timer->adjust(duration, !state); -} - - -//------------------------------------------------- -// recompute_parameters - -//------------------------------------------------- - -inline void upd3301_device::recompute_parameters() -{ - int horiz_pix_total = (m_h + m_z) * m_width; - int vert_pix_total = (m_l + m_v) * m_r; - - attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock()) * horiz_pix_total * vert_pix_total; - - rectangle visarea; - - visarea.set(0, (m_h * m_width) - 1, 0, (m_l * m_r) - 1); - - if (LOG) - { - if (LOG) logerror("UPD3301 '%s' Screen: %u x %u @ %f Hz\n", tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); - if (LOG) logerror("UPD3301 '%s' Visible Area: (%u, %u) - (%u, %u)\n", tag(), visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y); - } - - m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh); - - update_hrtc_timer(0); - update_vrtc_timer(0); -} +const device_type UPD3301 = &device_creator; @@ -194,72 +77,54 @@ inline void upd3301_device::recompute_parameters() // upd3301_device - constructor //------------------------------------------------- -upd3301_device::upd3301_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, UPD3301, "UPD3301", tag, owner, clock, "upd3301", __FILE__), - device_video_interface(mconfig, *this), - m_status(0), - m_param_count(0), - m_data_fifo_pos(0), - m_attr_fifo_pos(0), - m_input_fifo(0), - m_me(0), - m_h(80), - m_l(20), - m_r(10), - m_v(6), - m_z(32), - m_attr_blink(0), - m_attr_frame(0), - m_cm(0), - m_cx(0), - m_cy(0), - m_cursor_blink(0), - m_cursor_frame(0) +upd3301_device::upd3301_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, UPD3301, "UPD3301", tag, owner, clock, "upd3301", __FILE__), + device_video_interface(mconfig, *this), + m_write_int(*this), + m_write_drq(*this), + m_write_hrtc(*this), + m_write_vrtc(*this), + m_width(0), + m_status(0), + m_param_count(0), + m_data_fifo_pos(0), + m_attr_fifo_pos(0), + m_input_fifo(0), + m_me(0), + m_h(80), + m_l(20), + m_r(10), + m_v(6), + m_z(32), + m_attr_blink(0), + m_attr_frame(0), + m_cm(0), + m_cx(0), + m_cy(0), + m_cursor_blink(0), + m_cursor_frame(0) { } -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void upd3301_device::device_config_complete() -{ - // inherit a copy of the static data - const upd3301_interface *intf = reinterpret_cast(static_config()); - if (intf != NULL) - *static_cast(this) = *intf; - - // or initialize to defaults if none provided - else - { - memset(&m_out_int_cb, 0, sizeof(m_out_int_cb)); - memset(&m_out_drq_cb, 0, sizeof(m_out_drq_cb)); - memset(&m_out_hrtc_cb, 0, sizeof(m_out_hrtc_cb)); - memset(&m_out_vrtc_cb, 0, sizeof(m_out_vrtc_cb)); - } -} - - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void upd3301_device::device_start() { + // resolve callbacks + m_display_cb.bind_relative_to(*owner()); + m_write_drq.resolve_safe(); + m_write_int.resolve_safe(); + m_write_hrtc.resolve_safe(); + m_write_vrtc.resolve_safe(); + // allocate timers m_hrtc_timer = timer_alloc(TIMER_HRTC); m_vrtc_timer = timer_alloc(TIMER_VRTC); m_drq_timer = timer_alloc(TIMER_DRQ); - // resolve callbacks - m_out_int_func.resolve(m_out_int_cb, *this); - m_out_drq_func.resolve(m_out_drq_cb, *this); - m_out_hrtc_func.resolve(m_out_hrtc_cb, *this); - m_out_vrtc_func.resolve(m_out_vrtc_cb, *this); - // state saving save_item(NAME(m_y)); save_item(NAME(m_hrtc)); @@ -329,7 +194,7 @@ void upd3301_device::device_timer(emu_timer &timer, device_timer_id id, int para case TIMER_HRTC: if (LOG) logerror("UPD3301 '%s' HRTC: %u\n", tag(), param); - m_out_hrtc_func(param); + m_write_hrtc(param); m_hrtc = param; update_hrtc_timer(param); @@ -338,7 +203,7 @@ void upd3301_device::device_timer(emu_timer &timer, device_timer_id id, int para case TIMER_VRTC: if (LOG) logerror("UPD3301 '%s' VRTC: %u\n", tag(), param); - m_out_vrtc_func(param); + m_write_vrtc(param); m_vrtc = param; if (param && !m_me) @@ -609,7 +474,7 @@ void upd3301_device::draw_scanline() int csr = m_cm && m_cursor_blink && ((y / m_r) == m_cy) && (sx == m_cx); int gpa = 0; // TODO - m_display_cb(this, *m_bitmap, y, sx, cc, lc, hlgt, rvv, vsp, sl0, sl12, csr, gpa); + m_display_cb(*m_bitmap, y, sx, cc, lc, hlgt, rvv, vsp, sl0, sl12, csr, gpa); } } @@ -655,3 +520,120 @@ UINT32 upd3301_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap } return 0; } + + +//------------------------------------------------- +// set_interrupt - +//------------------------------------------------- + +void upd3301_device::set_interrupt(int state) +{ + if (LOG) logerror("UPD3301 '%s' Interrupt: %u\n", tag(), state); + + m_write_int(state); + + if (!state) + { + m_status &= ~(STATUS_N | STATUS_E); + } +} + + +//------------------------------------------------- +// set_drq - +//------------------------------------------------- + +void upd3301_device::set_drq(int state) +{ + if (LOG) logerror("UPD3301 '%s' DRQ: %u\n", tag(), state); + + m_write_drq(state); +} + + +//------------------------------------------------- +// set_display - +//------------------------------------------------- + +void upd3301_device::set_display(int state) +{ + if (state) + { + m_status |= STATUS_VE; + } + else + { + m_status &= ~STATUS_VE; + } +} + + +//------------------------------------------------- +// reset_counters - +//------------------------------------------------- + +void upd3301_device::reset_counters() +{ + set_interrupt(0); + set_drq(0); +} + + +//------------------------------------------------- +// update_hrtc_timer - +//------------------------------------------------- + +void upd3301_device::update_hrtc_timer(int state) +{ + int y = m_screen->vpos(); + + int next_x = state ? m_h : 0; + int next_y = state ? y : ((y + 1) % ((m_l + m_v) * m_width)); + + attotime duration = m_screen->time_until_pos(next_y, next_x); + + m_hrtc_timer->adjust(duration, !state); +} + + +//------------------------------------------------- +// update_vrtc_timer - +//------------------------------------------------- + +void upd3301_device::update_vrtc_timer(int state) +{ + int next_y = state ? (m_l * m_r) : 0; + + attotime duration = m_screen->time_until_pos(next_y, 0); + + m_vrtc_timer->adjust(duration, !state); +} + + +//------------------------------------------------- +// recompute_parameters - +//------------------------------------------------- + +void upd3301_device::recompute_parameters() +{ + int horiz_pix_total = (m_h + m_z) * m_width; + int vert_pix_total = (m_l + m_v) * m_r; + + attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock()) * horiz_pix_total * vert_pix_total; + + rectangle visarea; + + visarea.set(0, (m_h * m_width) - 1, 0, (m_l * m_r) - 1); + + if (LOG) + { + if (LOG) logerror("UPD3301 '%s' Screen: %u x %u @ %f Hz\n", tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); + if (LOG) logerror("UPD3301 '%s' Visible Area: (%u, %u) - (%u, %u)\n", tag(), visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y); + } + + m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh); + + update_hrtc_timer(0); + update_vrtc_timer(0); +} + diff --git a/src/emu/video/upd3301.h b/src/emu/video/upd3301.h index 70be59eaec0..81ab1026383 100644 --- a/src/emu/video/upd3301.h +++ b/src/emu/video/upd3301.h @@ -41,24 +41,30 @@ -//************************************************************************** -// MACROS / CONSTANTS -//************************************************************************** - - - - //************************************************************************** // INTERFACE CONFIGURATION MACROS //************************************************************************** -#define MCFG_UPD3301_ADD(_tag, _clock, _intrf) \ - MCFG_DEVICE_ADD(_tag, UPD3301, _clock) \ - MCFG_DEVICE_CONFIG(_intrf) +#define UPD3301_DRAW_CHARACTER_MEMBER(_name) void _name(bitmap_rgb32 &bitmap, int y, int sx, UINT8 cc, UINT8 lc, int hlgt, int rvv, int vsp, int sl0, int sl12, int csr, int gpa) -#define UPD3301_INTERFACE(name) \ - const upd3301_interface (name) = +#define MCFG_UPD3301_CHARACTER_WIDTH(_value) \ + upd3301_device::static_set_character_width(*device, _value); + +#define MCFG_UPD3301_DRAW_CHARACTER_CALLBACK_OWNER(_class, _method) \ + upd3301_device::static_set_display_callback(*device, upd3301_draw_character_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); + +#define MCFG_UPD3301_DRQ_CALLBACK(_write) \ + devcb = &upd3301_device::set_drq_wr_callback(*device, DEVCB2_##_write); + +#define MCFG_UPD3301_INT_CALLBACK(_write) \ + devcb = &upd3301_device::set_int_wr_callback(*device, DEVCB2_##_write); + +#define MCFG_UPD3301_HRTC_CALLBACK(_write) \ + devcb = &upd3301_device::set_hrtc_wr_callback(*device, DEVCB2_##_write); + +#define MCFG_UPD3301_VRTC_CALLBACK(_write) \ + devcb = &upd3301_device::set_vrtc_wr_callback(*device, DEVCB2_##_write); @@ -66,38 +72,26 @@ // TYPE DEFINITIONS //************************************************************************** -// ======================> upd3301_display_pixels_func - -typedef void (*upd3301_display_pixels_func)(device_t *device, bitmap_rgb32 &bitmap, int y, int sx, UINT8 cc, UINT8 lc, int hlgt, int rvv, int vsp, int sl0, int sl12, int csr, int gpa); -#define UPD3301_DISPLAY_PIXELS(name) void name(device_t *device, bitmap_rgb32 &bitmap, int y, int sx, UINT8 cc, UINT8 lc, int hlgt, int rvv, int vsp, int sl0, int sl12, int csr, int gpa) - - -// ======================> upd3301_interface - -struct upd3301_interface -{ - int m_width; // char width in pixels - - upd3301_display_pixels_func m_display_cb; - - devcb_write_line m_out_int_cb; - devcb_write_line m_out_drq_cb; - devcb_write_line m_out_hrtc_cb; - devcb_write_line m_out_vrtc_cb; -}; - +typedef device_delegate upd3301_draw_character_delegate; // ======================> upd3301_device class upd3301_device : public device_t, - public device_video_interface, - public upd3301_interface + public device_video_interface { public: // construction/destruction upd3301_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + static void static_set_character_width(device_t &device, int value) { downcast(device).m_width = value; } + static void static_set_display_callback(device_t &device, upd3301_draw_character_delegate callback) { downcast(device).m_display_cb = callback; } + + template static devcb2_base &set_drq_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_drq.set_callback(object); } + template static devcb2_base &set_int_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_int.set_callback(object); } + template static devcb2_base &set_hrtc_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_hrtc.set_callback(object); } + template static devcb2_base &set_vrtc_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_vrtc.set_callback(object); } + DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); DECLARE_WRITE8_MEMBER( dack_w ); @@ -109,31 +103,36 @@ public: protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); virtual void device_reset(); virtual void device_clock_changed(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); private: - static const device_timer_id TIMER_HRTC = 0; - static const device_timer_id TIMER_VRTC = 1; - static const device_timer_id TIMER_DRQ = 2; + enum + { + TIMER_HRTC, + TIMER_VRTC, + TIMER_DRQ + }; - inline void set_interrupt(int state); - inline void set_drq(int state); - inline void set_display(int state); - inline void reset_counters(); - inline void update_hrtc_timer(int state); - inline void update_vrtc_timer(int state); - inline void recompute_parameters(); + void set_interrupt(int state); + void set_drq(int state); + void set_display(int state); + void reset_counters(); + void update_hrtc_timer(int state); + void update_vrtc_timer(int state); + void recompute_parameters(); void draw_scanline(); - devcb_resolved_write_line m_out_int_func; - devcb_resolved_write_line m_out_drq_func; - devcb_resolved_write_line m_out_hrtc_func; - devcb_resolved_write_line m_out_vrtc_func; + devcb2_write_line m_write_int; + devcb2_write_line m_write_drq; + devcb2_write_line m_write_hrtc; + devcb2_write_line m_write_vrtc; + + upd3301_draw_character_delegate m_display_cb; + int m_width; // screen drawing bitmap_rgb32 *m_bitmap; // bitmap diff --git a/src/mess/drivers/pc8001.c b/src/mess/drivers/pc8001.c index 11f235882a8..7bd0558209a 100644 --- a/src/mess/drivers/pc8001.c +++ b/src/mess/drivers/pc8001.c @@ -364,17 +364,15 @@ static const rgb_t PALETTE_PC8001[] = rgb_t::white }; -static UPD3301_DISPLAY_PIXELS( pc8001_display_pixels ) +UPD3301_DRAW_CHARACTER_MEMBER( pc8001_state::pc8001_display_pixels ) { - pc8001_state *state = device->machine().driver_data(); - - UINT8 data = state->m_char_rom->base()[(cc << 3) | lc]; + UINT8 data = m_char_rom->base()[(cc << 3) | lc]; int i; if (lc >= 8) return; if (csr) data = 0xff; - if (state->m_width80) + if (m_width80) { for (i = 0; i < 8; i++) { @@ -401,16 +399,6 @@ static UPD3301_DISPLAY_PIXELS( pc8001_display_pixels ) } } -static UPD3301_INTERFACE( pc8001_upd3301_intf ) -{ - 8, - pc8001_display_pixels, - DEVCB_NULL, - DEVCB_DEVICE_LINE_MEMBER(I8257_TAG, i8257_device, i8257_drq2_w), - DEVCB_NULL, - DEVCB_NULL -}; - /* 8255 Interface */ static I8255A_INTERFACE( ppi_intf ) @@ -559,7 +547,11 @@ static MACHINE_CONFIG_START( pc8001, pc8001_state ) MCFG_I8255A_ADD(I8255A_TAG, ppi_intf) MCFG_I8257_ADD(I8257_TAG, 4000000, dmac_intf) MCFG_UPD1990A_ADD(UPD1990A_TAG, XTAL_32_768kHz, NULL, NULL) - MCFG_UPD3301_ADD(UPD3301_TAG, 14318180, pc8001_upd3301_intf) + + MCFG_DEVICE_ADD(UPD3301_TAG, UPD3301, 14318180) + MCFG_UPD3301_CHARACTER_WIDTH(8) + MCFG_UPD3301_DRAW_CHARACTER_CALLBACK_OWNER(pc8001_state, pc8001_display_pixels) + MCFG_UPD3301_VRTC_CALLBACK(DEVWRITELINE(I8257_TAG, i8257_device, i8257_drq2_w)) MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_printers, "image") MCFG_CENTRONICS_ACK_HANDLER(WRITELINE(pc8001_state, write_centronics_ack)) @@ -599,7 +591,11 @@ static MACHINE_CONFIG_START( pc8001mk2, pc8001mk2_state ) MCFG_I8255A_ADD(I8255A_TAG, ppi_intf) MCFG_I8257_ADD(I8257_TAG, 4000000, dmac_intf) MCFG_UPD1990A_ADD(UPD1990A_TAG, XTAL_32_768kHz, NULL, NULL) - MCFG_UPD3301_ADD(UPD3301_TAG, 14318180, pc8001_upd3301_intf) + + MCFG_DEVICE_ADD(UPD3301_TAG, UPD3301, 14318180) + MCFG_UPD3301_CHARACTER_WIDTH(8) + MCFG_UPD3301_DRAW_CHARACTER_CALLBACK_OWNER(pc8001_state, pc8001_display_pixels) + MCFG_UPD3301_VRTC_CALLBACK(DEVWRITELINE(I8257_TAG, i8257_device, i8257_drq2_w)) MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_printers, "image") diff --git a/src/mess/includes/pc8001.h b/src/mess/includes/pc8001.h index aa01ebb81bb..32da0098a7e 100644 --- a/src/mess/includes/pc8001.h +++ b/src/mess/includes/pc8001.h @@ -79,6 +79,7 @@ public: DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); DECLARE_WRITE_LINE_MEMBER(write_centronics_ack); + UPD3301_DRAW_CHARACTER_MEMBER( pc8001_display_pixels ); }; class pc8001mk2_state : public pc8001_state