upd3301: devcb2 & delegate. (nw)

This commit is contained in:
Curt Coder 2014-04-04 09:58:00 +00:00
parent 44b66958fc
commit a2a6971ef2
5 changed files with 276 additions and 255 deletions

View File

@ -160,56 +160,72 @@ public:
// dummy class used to indicate a non-existant parameter
class _noparam { };
template<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type, typename _P10Type, typename _P11Type>
// specialization for 12 parameters
template<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type, typename _P10Type, typename _P11Type, typename _P12Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type, typename _P10Type, typename _P11Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type, typename _P10Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type, typename _P2Type>
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<typename _ClassType, typename _ReturnType, typename _P1Type>
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<typename _ClassType, typename _ReturnType>
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<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type, typename _P10Type, typename _P11Type, typename _P12Type>
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<delegate_mfp *>(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<mfptype *>(&_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 <typename _SourceType>
@ -515,7 +539,7 @@ private:
// ======================> delegate_base
// general delegate class template supporting up to 5 parameters
template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam, typename _P6Type = _noparam, typename _P7Type = _noparam, typename _P8Type = _noparam, typename _P9Type = _noparam, typename _P10Type = _noparam, typename _P11Type = _noparam>
template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam, typename _P6Type = _noparam, typename _P7Type = _noparam, typename _P8Type = _noparam, typename _P9Type = _noparam, typename _P10Type = _noparam, typename _P11Type = _noparam, typename _P12Type = _noparam>
class delegate_base
{
public:
@ -523,9 +547,9 @@ public:
template<class _FunctionClass>
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<delegate_generic_class>::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<class _FunctionClass> 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<basetype *>(this) = src; return *this; }
};
// specialize for 12 parameters
template<typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type, typename _P6Type, typename _P7Type, typename _P8Type, typename _P9Type, typename _P10Type, typename _P11Type, typename _P12Type>
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<class _FunctionClass> delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { }
template<class _FunctionClass> delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { }
template<class _FunctionClass> 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<basetype *>(this) = src; return *this; }
};
#endif /* __DELEGATE_H__ */

View File

@ -22,13 +22,9 @@
*/
#include "emu.h"
#include "upd3301.h"
// device type definition
const device_type UPD3301 = &device_creator<upd3301_device>;
//**************************************************************************
// 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<upd3301_device>;
@ -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<const upd3301_interface *>(static_config());
if (intf != NULL)
*static_cast<upd3301_interface *>(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);
}

View File

@ -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<void (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_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<upd3301_device &>(device).m_width = value; }
static void static_set_display_callback(device_t &device, upd3301_draw_character_delegate callback) { downcast<upd3301_device &>(device).m_display_cb = callback; }
template<class _Object> static devcb2_base &set_drq_wr_callback(device_t &device, _Object object) { return downcast<upd3301_device &>(device).m_write_drq.set_callback(object); }
template<class _Object> static devcb2_base &set_int_wr_callback(device_t &device, _Object object) { return downcast<upd3301_device &>(device).m_write_int.set_callback(object); }
template<class _Object> static devcb2_base &set_hrtc_wr_callback(device_t &device, _Object object) { return downcast<upd3301_device &>(device).m_write_hrtc.set_callback(object); }
template<class _Object> static devcb2_base &set_vrtc_wr_callback(device_t &device, _Object object) { return downcast<upd3301_device &>(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

View File

@ -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<pc8001_state>();
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")

View File

@ -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