diff options
author | 2019-01-04 17:12:22 +0100 | |
---|---|---|
committer | 2019-01-04 17:12:22 +0100 | |
commit | ee115932f8f2106588a06cd43b51d329ddef6ef1 (patch) | |
tree | 8b2e5518c3e272c0ee758618c10b126885887439 | |
parent | 793f3230da39ccbf8ee01e228345adf4da41f5f3 (diff) |
FixFreq code maintenance and add rgb channel functionality. (nw)
-rw-r--r-- | src/devices/video/fixfreq.cpp | 246 | ||||
-rw-r--r-- | src/devices/video/fixfreq.h | 42 | ||||
-rw-r--r-- | src/mame/drivers/atarittl.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/pong.cpp | 6 |
4 files changed, 165 insertions, 131 deletions
diff --git a/src/devices/video/fixfreq.cpp b/src/devices/video/fixfreq.cpp index a64c6d812b3..d0c2e2b4a5d 100644 --- a/src/devices/video/fixfreq.cpp +++ b/src/devices/video/fixfreq.cpp @@ -31,7 +31,7 @@ DEFINE_DEVICE_TYPE(FIXFREQ, fixedfreq_device, "fixfreq", "Fixed-Frequency Monoch fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), device_video_interface(mconfig, *this, false), - m_htotal(0), m_vtotal(0), m_vid(0), m_last_x(0), m_last_y(0), m_cur_bm(0), + m_htotal(0), m_vtotal(0), m_sync_signal(0), m_last_x(0), m_last_y(0), m_cur_bm(0), // default to NTSC "704x480@30i" m_monitor_clock(13500000), m_hvisible(704), @@ -45,7 +45,7 @@ fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type ty m_fieldcount(2), m_sync_threshold(0.3), m_gain(1.0 / 3.7), - m_vint(0), m_int_trig(0), m_mult(0), m_sig_vsync(0), m_sig_composite(0), m_sig_field(0) + m_vsync_filter(0), m_vsync_threshold(0), m_vsync_filter_timeconst(0), m_sig_vsync(0), m_sig_composite(0), m_sig_field(0) { } @@ -59,22 +59,23 @@ void fixedfreq_device::device_start() m_htotal = 0; m_vtotal = 0; - m_vid = 0.0; + m_sync_signal = 0.0; + m_col = rgb_t(0,0,0); m_last_x = 0; m_last_y = 0; - m_last_time = attotime::zero; - m_line_time = attotime::zero; - m_last_hsync_time = attotime::zero; - m_last_vsync_time = attotime::zero; - m_refresh = attotime::zero; - m_clock_period = attotime::zero; + m_last_sync_time = time_type(0); + m_line_time = time_type(0); + m_last_hsync_time = time_type(0); + m_last_vsync_time = time_type(0); + m_refresh_period = time_type(0); + m_clock_period = time_type(0); //bitmap_rgb32 *m_bitmap[2]; m_cur_bm = 0; /* sync separator */ - m_vint = 0.0; - m_int_trig = 0.0; - m_mult = 0.0; + m_vsync_filter = 0.0; + m_vsync_threshold = 0.0; + m_vsync_filter_timeconst = 0.0; m_sig_vsync = 0; m_sig_composite = 0; @@ -83,25 +84,25 @@ void fixedfreq_device::device_start() m_bitmap[0] = nullptr; m_bitmap[1] = nullptr; //m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vga_device::vblank_timer_cb),this)); - recompute_parameters(false); + recompute_parameters(); - save_item(NAME(m_vid)); + save_item(NAME(m_sync_signal)); save_item(NAME(m_last_x)); save_item(NAME(m_last_y)); - save_item(NAME(m_last_time)); + save_item(NAME(m_last_sync_time)); save_item(NAME(m_line_time)); save_item(NAME(m_last_hsync_time)); save_item(NAME(m_last_vsync_time)); - save_item(NAME(m_refresh)); + save_item(NAME(m_refresh_period)); save_item(NAME(m_clock_period)); //save_item(NAME(m_bitmap[0])); //save_item(NAME(m_bitmap[1])); save_item(NAME(m_cur_bm)); /* sync separator */ - save_item(NAME(m_vint)); - save_item(NAME(m_int_trig)); - save_item(NAME(m_mult)); + save_item(NAME(m_vsync_filter)); + save_item(NAME(m_vsync_threshold)); + save_item(NAME(m_vsync_filter_timeconst)); save_item(NAME(m_sig_vsync)); save_item(NAME(m_sig_composite)); @@ -113,21 +114,21 @@ void fixedfreq_device::device_start() void fixedfreq_device::device_reset() { - m_last_time = attotime::zero; - m_line_time = attotime::zero; - m_last_hsync_time = attotime::zero; - m_last_vsync_time = attotime::zero; - m_vint = 0; + m_last_sync_time = time_type(0); + m_line_time = time_type(0); + m_last_hsync_time = time_type(0); + m_last_vsync_time = time_type(0); + m_vsync_filter = 0; } void fixedfreq_device::device_post_load() { - //recompute_parameters(true); + //recompute_parameters(); } -void fixedfreq_device::recompute_parameters(bool postload) +void fixedfreq_device::recompute_parameters() { bool needs_realloc = (m_htotal != m_hbackporch) && (m_vtotal != m_vbackporch); @@ -141,72 +142,98 @@ void fixedfreq_device::recompute_parameters(bool postload) /* sync separator */ - m_int_trig = (exp(- 3.0/(3.0+3.0))) - exp(-1.0); - m_mult = (double) (m_monitor_clock) / (double) m_htotal * 1.0; // / (3.0 + 3.0); - LOG("trigger %f with len %f\n", m_int_trig, 1e6 / m_mult); + m_vsync_threshold = (exp(- 3.0/(3.0+3.0))) - exp(-1.0); + m_vsync_filter_timeconst = (double) (m_monitor_clock) / (double) m_htotal * 1.0; // / (3.0 + 3.0); + LOG("trigger %f with len %f\n", m_vsync_threshold, 1e6 / m_vsync_filter_timeconst); m_bitmap[0] = std::make_unique<bitmap_rgb32>(m_htotal, m_vtotal); m_bitmap[1] = std::make_unique<bitmap_rgb32>(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()); + m_clock_period = 1.0 / m_monitor_clock; + update_screen_parameters(m_clock_period * m_vtotal * m_htotal); } -void fixedfreq_device::update_screen_parameters(const attotime &refresh) +void fixedfreq_device::update_screen_parameters(const time_type &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()); + m_refresh_period = refresh; + screen().configure(m_htotal, m_vtotal, visarea, DOUBLE_TO_ATTOSECONDS(m_refresh_period)); } -int fixedfreq_device::sync_separator(const attotime &time, double newval) +void fixedfreq_device::update_sync_channel(const time_type &time, const double newval) { - int last_vsync = m_sig_vsync; - int last_comp = m_sig_composite; - int ret = 0; + const time_type delta_time = time - m_last_sync_time; - m_vint += ((double) last_comp - m_vint) * (1.0 - exp(-time.as_double() * m_mult)); + const int last_vsync = m_sig_vsync; + const int last_comp = m_sig_composite; + + m_vsync_filter += ((double) last_comp - m_vsync_filter) * (1.0 - exp(-delta_time * m_vsync_filter_timeconst)); m_sig_composite = (newval < m_sync_threshold) ? 1 : 0 ; - m_sig_vsync = (m_vint > m_int_trig) ? 1 : 0; + m_sig_vsync = (m_vsync_filter > m_vsync_threshold) ? 1 : 0; if (!last_vsync && m_sig_vsync) { - /* TODO - time since last hsync and field detection */ - ret |= 1; + LOG("VSYNC %d %d\n", m_last_x, m_last_y + m_sig_field); + m_last_y = m_vbackporch - m_vsync; + // toggle bitmap + m_cur_bm ^= 1; + update_screen_parameters(time - m_last_vsync_time); + m_last_vsync_time = time; } - if (last_vsync && !m_sig_vsync) + else 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 */ LOG("Field: %d\n", m_sig_field); } + if (!last_comp && m_sig_composite) { /* TODO - time since last hsync and field detection */ - ret |= 2; + LOG("HSYNC up %d\n", m_last_x); + // FIXME: pixels > 50 filters some spurious hysnc on line 27 in breakout + if (!m_sig_vsync && (m_last_x > 100)) + { + m_last_y += m_fieldcount; + m_last_x = 0; + m_line_time = time; + } + //if (m_last_y == 27) printf("HSYNC up %d %d\n", m_last_y, pixels); } - if (last_comp && !m_sig_composite) + else if (last_comp && !m_sig_composite) { /* falling composite */ - ret |= 4; + LOG("HSYNC down %f %d %f\n", time * 1e6, m_last_x, m_sync_signal); + } + + m_sync_signal = newval; + m_last_sync_time = time; +} + +void fixedfreq_device::update_bm(const time_type &time) +{ + const int pixels = round((time - m_line_time) / m_clock_period); + const int has_fields = (m_fieldcount > 1) ? 1: 0; + + bitmap_rgb32 *bm = m_bitmap[m_cur_bm].get(); + + if (m_last_y < bm->height()) + { + rgb_t col(255, 0, 0); // Mark sync areas + + if (m_sync_signal >= m_sync_threshold) + { + col = m_col; + } + bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, 1, col); + m_last_x = pixels; } - return ret; } uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -216,72 +243,69 @@ uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bi return 0; } -NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_vid) +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_composite_monochrome) { - bitmap_rgb32 *bm = m_bitmap[m_cur_bm].get(); - const int has_fields = (m_fieldcount > 1) ? 1: 0; + // double is good enough for this exercise; - int pixels = round((time - m_line_time).as_double() / m_clock_period.as_double()); - attotime delta_time = (time - m_last_time); + const time_type ctime = time.as_double(); + update_bm(ctime); + update_sync_channel(ctime, data); - if (data == m_vid) - return; + int colv = (int) ((data - m_sync_threshold) * m_gain * 255.0); + if (colv > 255) + colv = 255; + m_col = rgb_t(colv, colv, colv); +} - ATTR_UNUSED int sync = sync_separator(delta_time, data); +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_red) +{ + // double is good enough for this exercise; - if (m_last_y < bm->height()) - { - rgb_t col; + const time_type ctime = time.as_double(); + update_bm(ctime); + //update_sync_channel(ctime, data); - if (m_vid < m_sync_threshold) - // Mark sync areas - col = rgb_t(255, 0, 0); - else - { - int colv = (int) ((m_vid - m_sync_threshold) * m_gain * 255.0); - if (colv > 255) - colv = 255; - col = rgb_t(colv, colv, colv); - } + int colv = (int) ((data - m_sync_threshold) * m_gain * 255.0); + if (colv > 255) + colv = 255; + m_col.set_r(colv); +} - bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, 1, col); - m_last_x = pixels; - } - if (sync & 1) - { - LOG("VSYNC %d %d\n", pixels, m_last_y + m_sig_field); - } - if (sync & 2) - { - LOG("HSYNC up %d\n", pixels); - //if (m_last_y == 27) printf("HSYNC up %d %d\n", m_last_y, pixels); - } - if (sync & 4) - { - LOG("HSYNC down %f %d %f\n", time.as_double()* 1e6, pixels, m_vid); - } +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_green) +{ + // double is good enough for this exercise; - if (sync & 1) - { - m_last_y = m_vbackporch - m_vsync; - // toggle bitmap - m_cur_bm ^= 1; - update_screen_parameters(time - m_last_vsync_time); - m_last_vsync_time = time; - } + const time_type ctime = time.as_double(); + update_bm(ctime); + //update_sync_channel(ctime, data); - // FIXME: pixels > 50 filters some spurious hysnc on line 27 in breakout - if ((sync & 2) && !m_sig_vsync && (pixels > 100)) - { - m_last_y += m_fieldcount; - m_last_x = 0; - m_line_time = time; - } + int colv = (int) ((data - m_sync_threshold) * m_gain * 255.0); + if (colv > 255) + colv = 255; + m_col.set_g(colv); +} + +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_blue) +{ + // double is good enough for this exercise; - m_last_time = time; - m_vid = data; + const time_type ctime = time.as_double(); + update_bm(ctime); + //update_sync_channel(ctime, data); + int colv = (int) ((data - m_sync_threshold) * m_gain * 255.0); + if (colv > 255) + colv = 255; + m_col.set_b(colv); } +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_sync) +{ + // double is good enough for this exercise; + + const time_type ctime = time.as_double(); + update_bm(ctime); + update_sync_channel(ctime, data); +} /***************************************************************************/ diff --git a/src/devices/video/fixfreq.h b/src/devices/video/fixfreq.h index 10c52217e82..d6c5424a027 100644 --- a/src/devices/video/fixfreq.h +++ b/src/devices/video/fixfreq.h @@ -29,7 +29,7 @@ MCFG_VIDEO_SET_SCREEN(_screen_tag) #define MCFG_FIXFREQ_MONITOR_CLOCK(_clock) \ - downcast<fixedfreq_device &>(*device).set_minitor_clock(_clock); + downcast<fixedfreq_device &>(*device).set_monitor_clock(_clock); #define MCFG_FIXFREQ_HORZ_PARAMS(_visible, _frontporch, _sync, _backporch) \ downcast<fixedfreq_device &>(*device).set_horz_params(_visible, _frontporch, _sync, _backporch); @@ -74,7 +74,7 @@ public: fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // inline configuration helpers - void set_minitor_clock(uint32_t clock) { m_monitor_clock = clock; } + void set_monitor_clock(uint32_t clock) { m_monitor_clock = clock; } void set_fieldcount(int count) { m_fieldcount = count; } void set_threshold(double threshold) { m_sync_threshold = threshold; } void set_gain(double gain) { m_gain = gain; } @@ -95,9 +95,17 @@ public: virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - NETDEV_ANALOG_CALLBACK_MEMBER(update_vid); + NETDEV_ANALOG_CALLBACK_MEMBER(update_composite_monochrome); + NETDEV_ANALOG_CALLBACK_MEMBER(update_red); + NETDEV_ANALOG_CALLBACK_MEMBER(update_green); + NETDEV_ANALOG_CALLBACK_MEMBER(update_blue); + NETDEV_ANALOG_CALLBACK_MEMBER(update_sync); + protected: + + typedef double time_type; + fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides @@ -106,25 +114,27 @@ protected: virtual void device_post_load() override; //virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); - void recompute_parameters(bool postload); - void update_screen_parameters(const attotime &refresh); + void update_screen_parameters(const time_type &refresh); private: - int sync_separator(const attotime &time, double newval); + void update_sync_channel(const time_type &time, const double newval); + void update_bm(const time_type &time); + void recompute_parameters(); int m_htotal; int m_vtotal; - double m_vid; + double m_sync_signal; + rgb_t m_col; int m_last_x; int m_last_y; - attotime m_last_time; - attotime m_line_time; - attotime m_last_hsync_time; - attotime m_last_vsync_time; - attotime m_refresh; - attotime m_clock_period; + time_type m_last_sync_time; + time_type m_line_time; + time_type m_last_hsync_time; + time_type m_last_vsync_time; + time_type m_refresh_period; + time_type m_clock_period; std::unique_ptr<bitmap_rgb32> m_bitmap[2]; int m_cur_bm; @@ -143,9 +153,9 @@ private: double m_gain; /* sync separator */ - double m_vint; - double m_int_trig; - double m_mult; + double m_vsync_filter; + double m_vsync_threshold; + double m_vsync_filter_timeconst; int m_sig_vsync; int m_sig_composite; diff --git a/src/mame/drivers/atarittl.cpp b/src/mame/drivers/atarittl.cpp index 3d969530dce..51e99579760 100644 --- a/src/mame/drivers/atarittl.cpp +++ b/src/mame/drivers/atarittl.cpp @@ -373,7 +373,7 @@ MACHINE_CONFIG_START(gtrak10_state::gtrak10) MCFG_DEVICE_ADD("maincpu", NETLIST_CPU, NETLIST_CLOCK) MCFG_NETLIST_SETUP(gtrak10) - MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "VIDEO_OUT", fixedfreq_device, update_vid, "fixfreq") + MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "VIDEO_OUT", fixedfreq_device, update_composite_monochrome, "fixfreq") /* video hardware */ diff --git a/src/mame/drivers/pong.cpp b/src/mame/drivers/pong.cpp index 0f7c0b87957..f00249b0ecb 100644 --- a/src/mame/drivers/pong.cpp +++ b/src/mame/drivers/pong.cpp @@ -393,7 +393,7 @@ MACHINE_CONFIG_START(pong_state::pong) MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0) MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "snd0", "sound", pong_state, sound_cb, "") - MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_vid, "fixfreq") + MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_composite_monochrome, "fixfreq") /* video hardware */ MCFG_FIXFREQ_ADD("fixfreq", "screen") @@ -435,7 +435,7 @@ MACHINE_CONFIG_START(breakout_state::breakout) MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0) MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "snd0", "sound", breakout_state, sound_cb, "") - MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_vid, "fixfreq") + MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_composite_monochrome, "fixfreq") // Leds and lamps @@ -491,7 +491,7 @@ MACHINE_CONFIG_START(pong_state::pongd) #endif MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "snd0", "AUDIO", pong_state, sound_cb, "") - MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_vid, "fixfreq") + MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_composite_monochrome, "fixfreq") /* video hardware */ MCFG_FIXFREQ_ADD("fixfreq", "screen") |