summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-01-04 17:12:22 +0100
committer couriersud <couriersud@gmx.org>2019-01-04 17:12:22 +0100
commitee115932f8f2106588a06cd43b51d329ddef6ef1 (patch)
tree8b2e5518c3e272c0ee758618c10b126885887439
parent793f3230da39ccbf8ee01e228345adf4da41f5f3 (diff)
FixFreq code maintenance and add rgb channel functionality. (nw)
-rw-r--r--src/devices/video/fixfreq.cpp246
-rw-r--r--src/devices/video/fixfreq.h42
-rw-r--r--src/mame/drivers/atarittl.cpp2
-rw-r--r--src/mame/drivers/pong.cpp6
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")