diff --git a/.gitattributes b/.gitattributes index ea16688364c..b92a9bd3ab7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1886,6 +1886,8 @@ src/emu/video/dm9368.h svneol=native#text/plain src/emu/video/ef9340_1.c svneol=native#text/plain src/emu/video/ef9340_1.h svneol=native#text/plain src/emu/video/ef9341_chargen.h svneol=native#text/plain +src/emu/video/fixfreq.c svneol=native#text/plain +src/emu/video/fixfreq.h svneol=native#text/plain src/emu/video/generic.c svneol=native#text/plain src/emu/video/generic.h svneol=native#text/plain src/emu/video/h63484.c svneol=native#text/plain diff --git a/src/emu/video/fixfreq.c b/src/emu/video/fixfreq.c new file mode 100644 index 00000000000..eb9c47ecd7c --- /dev/null +++ b/src/emu/video/fixfreq.c @@ -0,0 +1,276 @@ +/*************************************************************************** + + fixfreq.h + + 2013 Couriersud + + Fixed frequency monochrome monitor emulation + + The driver is intended for drivers which provide an analog video signal. + VSYNC and HSYNC levels are used to create the bitmap. + +***************************************************************************/ + +#include "emu.h" +#include "fixfreq.h" + +/*************************************************************************** + + Local variables + +***************************************************************************/ + +//#define VERBOSE_OUT(x) printf x +#define VERBOSE_OUT(x) + +/*************************************************************************** + + Static declarations + +***************************************************************************/ + +//ModeLine "720x480@30i" 13.5 720 736 799 858 480 486 492 525 interlace -hsync -vsync +fixedfreq_interface fixedfreq_mode_ntsc720 = { + 13500000, + 720,736,799,858, + 480,486,492,525, + 2, /* interlaced */ + 0.3 +}; + +//ModeLine "704x480@30i" 13.5 704 728 791 858 480 486 492 525 +fixedfreq_interface fixedfreq_mode_ntsc704 = { + 13500000, + 704,728,791,858, + 480,486,492,525, + 2, /* interlaced */ + 0.3 +}; + +/*************************************************************************** + + Fixed frequency monitor + +***************************************************************************/ +// device type definition +const device_type FIXFREQ = &device_creator; + +fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_video_interface(mconfig, *this, false) +{ +} + +fixedfreq_device::fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, FIXFREQ, "FIXFREQ", tag, owner, clock, "fixfreq", __FILE__), + device_video_interface(mconfig, *this, false) +{ +} + +void fixedfreq_device::device_config_complete() +{ + const fixedfreq_interface *intf = reinterpret_cast(static_config()); + + if ( intf != NULL ) + { + *static_cast(this) = *intf; + } + else + { + *static_cast(this) = fixedfreq_mode_ntsc704; + } + +} + + +void fixedfreq_device::device_start() +{ + m_cur_bm = 0; + m_vid = 0.0; + m_vint = 0.0; + m_last_x = 0; + m_last_y = 0; + m_refresh = attotime::zero; + m_bitmap[0] = NULL; + m_bitmap[1] = NULL; + m_last_time = attotime::zero; + m_last_hsync_time = attotime::zero; + m_last_vsync_time = attotime::zero; + //m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vga_device::vblank_timer_cb),this)); + recompute_parameters(false); + + m_sig_vsync = 0; + m_sig_composite = 0; + m_sig_field = 0; +} + +void fixedfreq_device::device_reset() +{ +} + + +void fixedfreq_device::device_post_load() +{ + //recompute_parameters(true); +} + +void fixedfreq_device::recompute_parameters(bool postload) +{ + bool needs_realloc = (m_htotal != m_hbackporch) && (m_vtotal != m_vbackporch); + + if (m_bitmap[0] != NULL || needs_realloc) + auto_free(machine(), m_bitmap[0]); + if (m_bitmap[1] != NULL || needs_realloc) + auto_free(machine(), m_bitmap[0]); + + m_htotal = m_hbackporch; + m_vtotal = m_vbackporch; + + /* sync separator */ + + m_int_trig = (exp(- 3.0/(3.0+3.0))) - exp(-1.0); + m_mult = (double) (m_monitor_clock) / m_htotal; // / (3.0 + 3.0); + VERBOSE_OUT(("trigger %f with len %f\n", m_int_trig, 1e6 / m_mult)); + + m_bitmap[0] = auto_bitmap_rgb32_alloc(machine(),m_htotal, m_vtotal); + m_bitmap[1] = auto_bitmap_rgb32_alloc(machine(),m_htotal, m_vtotal); + + rectangle visarea( + m_hbackporch - m_hfrontporch, + m_hbackporch - m_hfrontporch + m_hvisible - 1, + m_vbackporch - m_vfrontporch, + m_vbackporch - m_vfrontporch + m_vvisible - 1); + + m_clock_period = attotime::from_hz(m_monitor_clock); + + m_refresh = attotime::from_hz(m_monitor_clock) * m_vtotal * m_htotal; + screen().configure(m_htotal, m_vtotal, visarea, m_refresh.as_attoseconds()); +} + +void fixedfreq_device::update_screen_parameters(attotime refresh) +{ + rectangle visarea( +// m_hsync - m_hvisible, +// m_hsync - 1 , + m_hbackporch - m_hfrontporch, + m_hbackporch - m_hfrontporch + m_hvisible - 1, + m_vbackporch - m_vfrontporch, + m_vbackporch - m_vfrontporch + m_vvisible - 1); + + m_refresh = refresh; + screen().configure(m_htotal, m_vtotal, visarea, m_refresh.as_attoseconds()); +} + +int fixedfreq_device::sync_separator(attotime time, double newval) +{ + int last_vsync = m_sig_vsync; + int last_comp = m_sig_composite; + int ret = 0; + + m_vint += ((double) m_sig_composite - m_vint) * (1.0 - exp(-time.as_double() * m_mult)); + m_sig_composite = (newval < m_sync_threshold) ? 1 : 0 ; + + m_sig_vsync = (m_vint > m_int_trig) ? 1 : 0; + + if (!last_vsync && m_sig_vsync) + { + /* TODO - time since last hsync and field detection */ + ret |= 1; + } + if (last_vsync && !m_sig_vsync) + { + m_sig_field = last_comp; /* force false-progressive */ + m_sig_field = (m_sig_field ^ 1) ^ last_comp; /* if there is no field switch, auto switch */ + VERBOSE_OUT(("Field: %d\n", m_sig_field)); + } + if (!last_comp && m_sig_composite) + { + /* TODO - time since last hsync and field detection */ + ret |= 2; + } + if (last_comp && !m_sig_composite) + { + /* falling composite */ + ret |= 4; + } + return ret; +} + +UINT32 fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + copybitmap(bitmap, *m_bitmap[!m_cur_bm], 0, 0, 0, 0, cliprect); + + return 0; +} + +void fixedfreq_device::update_vid(double newval, attotime cur_time) +{ + + static attotime m_last_time = attotime(0,0); + static attotime m_line_time = attotime(0,0); + + + bitmap_rgb32 *bm = m_bitmap[m_cur_bm]; + + int pixels = round((cur_time - m_line_time).as_double() / m_clock_period.as_double()); + attotime time = (cur_time - m_last_time); + + if ((newval == m_vid)) + return; + + ATTR_UNUSED int sync = sync_separator(time, newval); + + if (m_last_y < bm->height()) + { + rgb_t col; + if (m_vid < m_sync_threshold) + col = MAKE_RGB(255, 0, 0); + else + { + int colv = (int) ((m_vid - m_sync_threshold) / 3.2 * 255.0); + col = MAKE_RGB(colv, colv, colv); + } + + if (m_vid < m_sync_threshold) + + while (0 && pixels >= m_htotal) + { + bm->plot_box(m_last_x, m_last_y + m_sig_field, m_htotal - 1 - m_last_x, 1, col); + pixels -= m_htotal; + m_last_x = 0; + } + bm->plot_box(m_last_x, m_last_y + m_sig_field, pixels - m_last_x, 1, col); + m_last_x = pixels; + } + if (sync & 1) VERBOSE_OUT(("VSYNC %d %d\n", pixels, m_last_y + m_sig_field)); + if (sync & 2) + VERBOSE_OUT(("HSYNC up %d\n", pixels)); + if (sync & 4) + VERBOSE_OUT(("HSYNC down %f %d %f\n", time.as_double()* 1e6, pixels, m_vid)); + //VERBOSE_OUT(("%d\n", m_last_x); + + if (sync & 1) + { + m_last_y = 0; + // toggle bitmap + m_cur_bm ^= 1; + update_screen_parameters(cur_time - m_last_vsync_time); + m_last_vsync_time = cur_time; + } + + if (sync & 2) + { + m_last_y += m_fieldcount; + m_last_x = 0; + m_line_time = cur_time; + } + + m_last_time = cur_time; + m_vid = newval; + +} + + +/***************************************************************************/ + + diff --git a/src/emu/video/fixfreq.h b/src/emu/video/fixfreq.h new file mode 100644 index 00000000000..365a5322dd1 --- /dev/null +++ b/src/emu/video/fixfreq.h @@ -0,0 +1,108 @@ +/*************************************************************************** + + fixfreq.h + + Fixed frequency monochrome monitor emulation + + The driver is intended for drivers which provide an analog video signal. + VSYNC and HSYNC levels are used to create the bitmap. + +***************************************************************************/ + +#ifndef FIXFREQ_H +#define FIXFREQ_H + +#include "emu.h" + +#define FIXFREQ_INTERFACE(name) \ + const fixedfreq_interface (name) = + +#define MCFG_FIXFREQ_ADD(_tag, _screen_tag, _config) \ + MCFG_SCREEN_ADD(_screen_tag, RASTER) \ + MCFG_SCREEN_RAW_PARAMS(13500000, 858, 0, 858, 525, 0, 525) \ + MCFG_SCREEN_UPDATE_DEVICE(_tag, fixedfreq_device, screen_update) \ + MCFG_DEVICE_ADD(_tag, FIXFREQ, 0) \ + MCFG_VIDEO_SET_SCREEN(_screen_tag) \ + MCFG_DEVICE_CONFIG(_config) + +struct fixedfreq_interface { + UINT32 m_monitor_clock; + int m_hvisible; + int m_hfrontporch; + int m_hsync; + int m_hbackporch; + int m_vvisible; + int m_vfrontporch; + int m_vsync; + int m_vbackporch; + int m_fieldcount; + double m_sync_threshold; +}; + +extern fixedfreq_interface fixedfreq_mode_ntsc704; +extern fixedfreq_interface fixedfreq_mode_ntsc720; + +// ======================> vga_device + +class fixedfreq_device : public device_t, + public device_video_interface, + public fixedfreq_interface +{ + +public: + // construction/destruction + fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + fixedfreq_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + + virtual UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void update_vid(const double newval, const attotime cur_time); + +protected: + // device-level overrides + virtual void device_config_complete(); + virtual void device_start(); + virtual void device_reset(); + virtual void device_post_load(); + //virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + void recompute_parameters(bool postload); + void update_screen_parameters(attotime refresh); + +private: + + int sync_separator(attotime time, double newval); + + int m_htotal; + int m_vtotal; + + double m_vid; + int m_last_x; + int m_last_y; + attotime m_last_time; + attotime m_last_hsync_time; + attotime m_last_vsync_time; + attotime m_refresh; + attotime m_clock_period; + bitmap_rgb32 *m_bitmap[2]; + int m_cur_bm; + + /* sync separator */ + double m_vint; + double m_int_trig; + double m_mult; + + int m_sig_vsync; + int m_sig_composite; + int m_sig_field; + +protected: + +}; + + +// device type definition +extern const device_type FIXFREQ; + +#endif /* FIXFREQ_H */ diff --git a/src/emu/video/video.mak b/src/emu/video/video.mak index 4a488026dcd..5f35737d4f6 100644 --- a/src/emu/video/video.mak +++ b/src/emu/video/video.mak @@ -104,6 +104,15 @@ ifneq ($(filter EF9340_1,$(VIDEOS)),) VIDEOOBJS+= $(VIDEOOBJ)/ef9340_1.o endif +#------------------------------------------------- +# +#@src/emu/video/fixfreq.h,VIDEOS += FIXFREQ +#------------------------------------------------- + +ifneq ($(filter FIXFREQ,$(VIDEOS)),) +VIDEOOBJS+= $(VIDEOOBJ)/fixfreq.o +endif + #------------------------------------------------- # #@src/emu/video/h63484.h,VIDEOS += H63484