vt100_kbd: Rewrite as UART-based serial device

This commit is contained in:
AJR 2018-03-09 20:30:29 -05:00
parent e6e3804ce8
commit b4a7ef663d
6 changed files with 190 additions and 134 deletions

View File

@ -533,7 +533,7 @@ MACHINES["ROC10937"] = true
MACHINES["RP5C01"] = true
MACHINES["RP5C15"] = true
MACHINES["RP5H01"] = true
--MACHINES["RSTBUF"] = true
MACHINES["RSTBUF"] = true
MACHINES["RTC4543"] = true
MACHINES["RTC65271"] = true
MACHINES["RTC9701"] = true

View File

@ -23,9 +23,11 @@
#include "bus/rs232/rs232.h"
#include "cpu/i8085/i8085.h"
#include "cpu/z80/z80.h"
#include "machine/ay31015.h"
#include "machine/com8116.h"
#include "machine/er1400.h"
#include "machine/i8251.h"
#include "machine/rstbuf.h"
#include "machine/vt100_kbd.h"
#include "video/vtvideo.h"
#include "screen.h"
@ -43,8 +45,10 @@ public:
m_maincpu(*this, "maincpu"),
m_crtc(*this, "vt100_video"),
m_keyboard(*this, "keyboard"),
m_kbduart(*this, "kbduart"),
m_dbrg(*this, "dbrg"),
m_nvr(*this, "nvr"),
m_rstbuf(*this, "rstbuf"),
m_p_ram(*this, "p_ram")
{
}
@ -52,24 +56,20 @@ public:
required_device<cpu_device> m_maincpu;
required_device<vt100_video_device> m_crtc;
required_device<vt100_keyboard_device> m_keyboard;
required_device<ay31015_device> m_kbduart;
required_device<com8116_device> m_dbrg;
required_device<er1400_device> m_nvr;
required_device<rst_pos_buffer_device> m_rstbuf;
DECLARE_READ8_MEMBER(vt100_flags_r);
DECLARE_WRITE_LINE_MEMBER(keyboard_int_w);
DECLARE_WRITE8_MEMBER(vt100_keyboard_w);
DECLARE_READ8_MEMBER(vt100_keyboard_r);
DECLARE_WRITE8_MEMBER(vt100_baud_rate_w);
DECLARE_WRITE8_MEMBER(vt100_nvr_latch_w);
DECLARE_READ8_MEMBER(vt100_read_video_ram_r);
DECLARE_WRITE_LINE_MEMBER(vert_freq_intr_w);
DECLARE_WRITE8_MEMBER(uart_clock_w);
required_shared_ptr<uint8_t> m_p_ram;
bool m_keyboard_int;
bool m_receiver_int;
bool m_vertical_int;
virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update_vt100(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
IRQ_CALLBACK_MEMBER(vt100_irq_callback);
IRQ_CALLBACK_MEMBER(vt102_irq_callback);
void vt102(machine_config &config);
void vt100(machine_config &config);
void vt180(machine_config &config);
@ -119,27 +119,10 @@ READ8_MEMBER( vt100_state::vt100_flags_r )
ret |= !m_nvr->data_r() << 5;
ret |= m_crtc->lba7_r() << 6;
ret |= m_keyboard_int << 7;
ret |= m_kbduart->tbmt_r() << 7;
return ret;
}
WRITE_LINE_MEMBER(vt100_state::keyboard_int_w)
{
m_keyboard_int = state;
if (state)
m_maincpu->set_input_line(0, HOLD_LINE);
}
WRITE8_MEMBER( vt100_state::vt100_keyboard_w )
{
m_keyboard->control_w(data);
}
READ8_MEMBER( vt100_state::vt100_keyboard_r )
{
return m_keyboard->key_code_r();
}
WRITE8_MEMBER( vt100_state::vt100_baud_rate_w )
{
m_dbrg->str_w(data & 0x0f);
@ -173,10 +156,8 @@ ADDRESS_MAP_START(vt100_state::vt100_io)
AM_RANGE (0x42, 0x42) AM_DEVWRITE("vt100_video", vt100_video_device, brightness_w)
// 0x62 NVR latch
AM_RANGE (0x62, 0x62) AM_WRITE(vt100_nvr_latch_w)
// 0x82 Keyboard UART data output
AM_RANGE (0x82, 0x82) AM_READ(vt100_keyboard_r)
// 0x82 Keyboard UART data input
AM_RANGE (0x82, 0x82) AM_WRITE(vt100_keyboard_w)
// 0x82 Keyboard UART data
AM_RANGE (0x82, 0x82) AM_DEVREADWRITE("kbduart", ay31015_device, receive, transmit)
// 0xA2 Video processor DC012
AM_RANGE (0xa2, 0xa2) AM_DEVWRITE("vt100_video", vt100_video_device, dc012_w)
// 0xC2 Video processor DC011
@ -201,30 +182,27 @@ uint32_t vt100_state::screen_update_vt100(screen_device &screen, bitmap_ind16 &b
// A4 - receiver
// A5 - vertical frequency
// all other set to 1
IRQ_CALLBACK_MEMBER(vt100_state::vt100_irq_callback)
IRQ_CALLBACK_MEMBER(vt100_state::vt102_irq_callback)
{
uint8_t ret = 0xc7 | (m_keyboard_int << 3) | (m_receiver_int << 4) | (m_vertical_int << 5);
m_receiver_int = 0;
return ret;
if (irqline == 0)
return m_rstbuf->inta_cb(device, 0);
else
return 0xff;
}
void vt100_state::machine_start()
{
m_kbduart->write_tsb(0);
m_kbduart->write_eps(1);
m_kbduart->write_np(1);
m_kbduart->write_nb1(1);
m_kbduart->write_nb2(1);
m_kbduart->write_cs(1);
m_kbduart->write_swe(0);
}
void vt100_state::machine_reset()
{
m_keyboard_int = 0;
m_receiver_int = 0;
m_vertical_int = 0;
output().set_value("online_led",1);
output().set_value("local_led", 0);
output().set_value("locked_led",1);
output().set_value("l1_led", 1);
output().set_value("l2_led", 1);
output().set_value("l3_led", 1);
output().set_value("l4_led", 1);
vt100_nvr_latch_w(machine().dummy_space(), 0, 0);
}
@ -233,11 +211,15 @@ READ8_MEMBER( vt100_state::vt100_read_video_ram_r )
return m_p_ram[offset];
}
WRITE_LINE_MEMBER( vt100_state::vert_freq_intr_w )
WRITE8_MEMBER(vt100_state::uart_clock_w)
{
m_vertical_int = (state == ASSERT_LINE) ? 1 : 0;
if (state)
m_maincpu->set_input_line(0, HOLD_LINE);
m_kbduart->write_tcp(BIT(data, 1));
m_kbduart->write_rcp(BIT(data, 1));
if (data == 0 || data == 3)
m_keyboard->signal_line_w(m_kbduart->so_r());
else
m_keyboard->signal_line_w(BIT(data, 0));
}
/* F4 Character Displayer */
@ -263,7 +245,7 @@ MACHINE_CONFIG_START(vt100_state::vt100)
MCFG_CPU_ADD("maincpu", I8080, XTAL(24'883'200) / 9)
MCFG_CPU_PROGRAM_MAP(vt100_mem)
MCFG_CPU_IO_MAP(vt100_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(vt100_state,vt100_irq_callback)
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("rstbuf", rst_pos_buffer_device, inta_cb)
/* video hardware */
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
@ -281,13 +263,15 @@ MACHINE_CONFIG_START(vt100_state::vt100)
MCFG_VT_SET_SCREEN("screen")
MCFG_VT_CHARGEN("chargen")
MCFG_VT_VIDEO_RAM_CALLBACK(READ8(vt100_state, vt100_read_video_ram_r))
MCFG_VT_VIDEO_VERT_FREQ_INTR_CALLBACK(WRITELINE(vt100_state, vert_freq_intr_w))
MCFG_VT_VIDEO_VERT_FREQ_INTR_CALLBACK(DEVWRITELINE("rstbuf", rst_pos_buffer_device, rst4_w))
MCFG_VT_VIDEO_LBA3_LBA4_CALLBACK(WRITE8(vt100_state, uart_clock_w))
MCFG_VT_VIDEO_LBA7_CALLBACK(DEVWRITELINE("nvr", er1400_device, clock_w))
MCFG_DEVICE_ADD("pusart", I8251, XTAL(24'883'200) / 9)
MCFG_I8251_TXD_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_txd))
MCFG_I8251_DTR_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_dtr))
MCFG_I8251_RTS_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_rts))
MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("rstbuf", rst_pos_buffer_device, rst2_w))
MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("pusart", i8251_device, write_rxd))
@ -300,7 +284,14 @@ MACHINE_CONFIG_START(vt100_state::vt100)
MCFG_DEVICE_ADD("nvr", ER1400, 0)
MCFG_DEVICE_ADD("keyboard", VT100_KEYBOARD, 0)
MCFG_VT100_KEYBOARD_INT_CALLBACK(WRITELINE(vt100_state, keyboard_int_w))
MCFG_VT100_KEYBOARD_SIGNAL_OUT_CALLBACK(DEVWRITELINE("kbduart", ay31015_device, write_si))
MCFG_DEVICE_ADD("kbduart", AY31015, 0)
MCFG_AY31015_WRITE_DAV_CB(DEVWRITELINE("rstbuf", rst_pos_buffer_device, rst1_w))
MCFG_AY31015_AUTO_RDAV(true)
MCFG_DEVICE_ADD("rstbuf", RST_POS_BUFFER, 0)
MCFG_RST_BUFFER_INT_CALLBACK(INPUTLINE("maincpu", 0))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(vt100_state::vt180)
@ -315,14 +306,18 @@ MACHINE_CONFIG_START(vt100_state::vt102)
MCFG_CPU_REPLACE("maincpu", I8085A, XTAL(24'073'400) / 4)
MCFG_CPU_PROGRAM_MAP(vt100_mem)
MCFG_CPU_IO_MAP(vt100_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(vt100_state,vt100_irq_callback)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(vt100_state, vt102_irq_callback)
MCFG_DEVICE_MODIFY("pusart")
MCFG_DEVICE_CLOCK(XTAL(24'073'400) / 8)
MCFG_I8251_TXRDY_HANDLER(INPUTLINE("maincpu", I8085_RST75_LINE))
MCFG_DEVICE_REPLACE("dbrg", COM8116_003, XTAL(24'073'400) / 4)
MCFG_COM8116_FR_HANDLER(DEVWRITELINE("pusart", i8251_device, write_rxc))
MCFG_COM8116_FT_HANDLER(DEVWRITELINE("pusart", i8251_device, write_txc))
MCFG_DEVICE_MODIFY("kbduart")
MCFG_AY31015_WRITE_TBMT_CB(INPUTLINE("maincpu", I8085_RST65_LINE))
MACHINE_CONFIG_END
/* VT1xx models:

View File

@ -1,10 +1,12 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu
// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu, AJR
/***************************************************************************
DEC VT100 keyboard emulation
TODO: rewrite as externally clocked serial device
All data to and from the keyboard is transmitted over a single
bidirectional wire. The clock that runs the keyboard's UART and
scan counters is multiplexed with the serial data signal.
***************************************************************************/
@ -157,11 +159,14 @@ INPUT_PORTS_END
vt100_keyboard_device::vt100_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, VT100_KEYBOARD, tag, owner, clock)
, m_int_cb(*this)
, m_signal_out_cb(*this)
, m_uart(*this, "uart")
, m_speaker(*this, "beeper")
, m_scan_counter(*this, "counter")
, m_key_row(*this, "LINE%X", 0)
, m_key_scan(false)
, m_key_code(0)
, m_signal_line(true)
, m_last_signal_change(attotime::zero)
, m_last_scan(0)
{
}
@ -175,7 +180,12 @@ MACHINE_CONFIG_START(vt100_keyboard_device::device_add_mconfig)
MCFG_SOUND_ADD("beeper", BEEP, 786) // 7.945us per serial clock = ~125865.324hz, / 160 clocks per char = ~ 786 hz
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MCFG_TIMER_DRIVER_ADD_PERIODIC("scan_timer", vt100_keyboard_device, scan_callback, attotime::from_hz(800))
MCFG_DEVICE_ADD("uart", AY31015, 0)
MCFG_AY31015_WRITE_SO_CB(WRITELINE(vt100_keyboard_device, signal_out_w))
MCFG_DEVICE_ADD("counter", RIPPLE_COUNTER, 0) // 2x 74LS93
MCFG_RIPPLE_COUNTER_STAGES(8)
MCFG_RIPPLE_COUNTER_COUNT_OUT_CB(WRITE8(vt100_keyboard_device, key_scan_w))
MACHINE_CONFIG_END
@ -197,7 +207,7 @@ ioport_constructor vt100_keyboard_device::device_input_ports() const
void vt100_keyboard_device::device_resolve_objects()
{
m_int_cb.resolve_safe();
m_signal_out_cb.resolve_safe();
}
@ -207,76 +217,100 @@ void vt100_keyboard_device::device_resolve_objects()
void vt100_keyboard_device::device_start()
{
save_item(NAME(m_key_scan));
save_item(NAME(m_key_code));
if (!m_uart->started())
throw device_missing_dependencies();
m_uart->write_tsb(0);
m_uart->write_eps(1);
m_uart->write_np(1);
m_uart->write_nb1(1);
m_uart->write_nb2(1);
m_uart->write_cs(1);
m_uart->write_swe(0);
machine().output().set_value("online_led",1);
machine().output().set_value("local_led", 0);
machine().output().set_value("locked_led",1);
machine().output().set_value("l1_led", 1);
machine().output().set_value("l2_led", 1);
machine().output().set_value("l3_led", 1);
machine().output().set_value("l4_led", 1);
save_item(NAME(m_signal_line));
save_item(NAME(m_last_signal_change));
save_item(NAME(m_last_scan));
}
//-------------------------------------------------
// control_w - handle data from CPU to keyboard
// (FIXME: this is received through a UART)
// signal_line_w - handle external serial input
//-------------------------------------------------
void vt100_keyboard_device::control_w(u8 data)
WRITE_LINE_MEMBER(vt100_keyboard_device::signal_line_w)
{
machine().output().set_value("online_led",BIT(data, 5) ? 0 : 1);
machine().output().set_value("local_led", BIT(data, 5));
machine().output().set_value("locked_led",BIT(data, 4) ? 0 : 1);
machine().output().set_value("l1_led", BIT(data, 3) ? 0 : 1);
machine().output().set_value("l2_led", BIT(data, 2) ? 0 : 1);
machine().output().set_value("l3_led", BIT(data, 1) ? 0 : 1);
machine().output().set_value("l4_led", BIT(data, 0) ? 0 : 1);
m_key_scan = BIT(data, 6);
m_speaker->set_state(BIT(data, 7));
}
if (m_signal_line == bool(state))
return;
if (machine().time() > m_last_signal_change + attotime::from_usec(5))
m_uart->write_si(m_signal_line);
//-------------------------------------------------
// key_code_r - return the code of the active key
// (FIXME: this is delivered through a UART)
//-------------------------------------------------
if (m_uart->tbmt_r())
m_scan_counter->clock_w(state);
u8 vt100_keyboard_device::key_code_r()
{
return m_key_code;
}
//-------------------------------------------------
// bit_sel -
//-------------------------------------------------
u8 vt100_keyboard_device::bit_sel(u8 data)
{
if (!BIT(data,7)) return 0x70;
if (!BIT(data,6)) return 0x60;
if (!BIT(data,5)) return 0x50;
if (!BIT(data,4)) return 0x40;
if (!BIT(data,3)) return 0x30;
if (!BIT(data,2)) return 0x20;
if (!BIT(data,1)) return 0x10;
if (!BIT(data,0)) return 0x00;
return 0;
}
//-------------------------------------------------
// scan_callback - handle the key scan timer
//-------------------------------------------------
TIMER_DEVICE_CALLBACK_MEMBER(vt100_keyboard_device::scan_callback)
{
if (m_key_scan)
if (state)
{
for (int i = 0; i < 16; i++)
bool dav = m_uart->dav_r();
m_uart->write_rdav(!dav);
if (dav)
{
u8 code = m_key_row[i]->read();
if (code < 0xff)
{
m_key_code = i | bit_sel(code);
m_int_cb(1);
break;
}
u8 data = m_uart->get_received_data();
machine().output().set_value("online_led",BIT(data, 5) ? 0 : 1);
machine().output().set_value("local_led", BIT(data, 5));
machine().output().set_value("locked_led",BIT(data, 4) ? 0 : 1);
machine().output().set_value("l1_led", BIT(data, 3) ? 0 : 1);
machine().output().set_value("l2_led", BIT(data, 2) ? 0 : 1);
machine().output().set_value("l3_led", BIT(data, 1) ? 0 : 1);
machine().output().set_value("l4_led", BIT(data, 0) ? 0 : 1);
m_speaker->set_state(BIT(data, 7));
if (BIT(data, 6))
m_scan_counter->reset_w(0);
}
}
m_uart->write_rcp(state);
m_uart->write_tcp(state);
m_signal_line = bool(state);
m_last_signal_change = machine().time();
}
//-------------------------------------------------
// signal_out_w - transmit serial keyboard output
//-------------------------------------------------
WRITE_LINE_MEMBER(vt100_keyboard_device::signal_out_w)
{
m_signal_out_cb(state);
}
//-------------------------------------------------
// key_scan_w - handle scan counter outputs
//-------------------------------------------------
WRITE8_MEMBER(vt100_keyboard_device::key_scan_w)
{
if (BIT(data, 0))
{
u8 input_row = m_key_row[(data >> 1) & 15]->read();
if (!BIT(input_row, (data >> 5) & 7))
m_uart->set_transmit_data((data >> 1) & 0x7f);
}
else if (!BIT(data, 7) && BIT(m_last_scan, 7))
m_scan_counter->reset_w(1);
m_last_scan = data;
}

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu
// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu, AJR
/***************************************************************************
DEC VT100 keyboard emulation
@ -11,7 +11,8 @@
#pragma once
#include "machine/timer.h"
#include "machine/ay31015.h"
#include "machine/ripple_counter.h"
#include "sound/beep.h"
#include "speaker.h"
@ -20,8 +21,8 @@
// CONFIGURATION MACROS
//**************************************************************************
#define MCFG_VT100_KEYBOARD_INT_CALLBACK(_devcb) \
devcb = &downcast<vt100_keyboard_device &>(*device).set_int_callback(DEVCB_##_devcb);
#define MCFG_VT100_KEYBOARD_SIGNAL_OUT_CALLBACK(_devcb) \
devcb = &downcast<vt100_keyboard_device &>(*device).set_signal_out_callback(DEVCB_##_devcb);
//**************************************************************************
@ -37,11 +38,9 @@ public:
vt100_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration
template <class Object> devcb_base &set_int_callback(Object &&cb) { return m_int_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_signal_out_callback(Object &&cb) { return m_signal_out_cb.set_callback(std::forward<Object>(cb)); }
// accessors (for now)
void control_w(u8 data);
u8 key_code_r();
DECLARE_WRITE_LINE_MEMBER(signal_line_w);
protected:
virtual void device_resolve_objects() override;
@ -51,16 +50,19 @@ protected:
private:
// internal helpers
static u8 bit_sel(u8 data);
DECLARE_WRITE_LINE_MEMBER(signal_out_w);
DECLARE_WRITE8_MEMBER(key_scan_w);
TIMER_DEVICE_CALLBACK_MEMBER(scan_callback);
devcb_write_line m_int_cb;
devcb_write_line m_signal_out_cb;
required_device<ay31015_device> m_uart;
required_device<beep_device> m_speaker;
required_device<ripple_counter_device> m_scan_counter;
required_ioport_array<16> m_key_row;
bool m_key_scan;
u8 m_key_code;
bool m_signal_line;
attotime m_last_signal_change;
u8 m_last_scan;
};
// device type definition

View File

@ -78,6 +78,7 @@ vt100_video_device::vt100_video_device(const machine_config &mconfig, device_typ
, device_video_interface(mconfig, *this)
, m_read_ram(*this)
, m_write_vert_freq_intr(*this)
, m_write_lba3_lba4(*this)
, m_write_lba7(*this)
, m_char_rom(*this, finder_base::DUMMY_TAG)
, m_palette(*this, "palette")
@ -106,12 +107,15 @@ void vt100_video_device::device_start()
/* resolve callbacks */
m_read_ram.resolve_safe(0);
m_write_vert_freq_intr.resolve_safe();
m_write_lba3_lba4.resolve();
m_write_lba7.resolve_safe();
// LBA7 is scan line frequency update
m_lba7_change_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vt100_video_device::lba7_change), this));
m_lba7_change_timer->adjust(clocks_to_attotime(765), 0, clocks_to_attotime(765));
m_lba3_change_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vt100_video_device::lba3_change), this));
screen().register_vblank_callback(vblank_state_delegate(&vt100_video_device::vblank_callback, this));
save_item(NAME(m_lba7));
@ -892,6 +896,20 @@ TIMER_CALLBACK_MEMBER(vt100_video_device::lba7_change)
{
m_lba7 = (m_lba7) ? 0 : 1;
m_write_lba7(m_lba7);
if (!m_write_lba3_lba4.isnull())
{
// The first of every eight low periods of LBA 3 is twice as long
m_write_lba3_lba4(2);
m_lba3_change_timer->adjust(clocks_to_attotime(90), 3);
}
}
TIMER_CALLBACK_MEMBER(vt100_video_device::lba3_change)
{
m_write_lba3_lba4(param & 3);
if (param <= 16)
m_lba3_change_timer->adjust(clocks_to_attotime(45), param + 1);
}

View File

@ -23,6 +23,7 @@ public:
template <class Object> devcb_base &set_ram_rd_callback(Object &&cb) { return m_read_ram.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_vert_freq_intr_wr_callback(Object &&cb) { return m_write_vert_freq_intr.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_lba3_lba4_wr_callback(Object &&cb) { return m_write_lba3_lba4.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_lba7_wr_callback(Object &&cb) { return m_write_lba7.set_callback(std::forward<Object>(cb)); }
void set_chargen_tag(const char *tag) { m_char_rom.set_tag(tag); }
@ -46,11 +47,13 @@ protected:
void recompute_parameters();
void vblank_callback(screen_device &screen, bool state);
virtual void display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type);
TIMER_CALLBACK_MEMBER(lba3_change);
TIMER_CALLBACK_MEMBER(lba7_change);
virtual void notify_vblank(bool choice) { }
devcb_read8 m_read_ram;
devcb_write_line m_write_vert_freq_intr;
devcb_write8 m_write_lba3_lba4;
devcb_write_line m_write_lba7;
int m_lba7;
@ -71,7 +74,8 @@ protected:
uint8_t m_fill_lines;
bool m_is_50hz;
bool m_interlaced;
emu_timer * m_lba7_change_timer;
emu_timer *m_lba3_change_timer;
emu_timer *m_lba7_change_timer;
required_region_ptr<uint8_t> m_char_rom; /* character rom region */
required_device<palette_device> m_palette;
@ -116,6 +120,9 @@ DECLARE_DEVICE_TYPE(RAINBOW_VIDEO, rainbow_video_device)
#define MCFG_VT_VIDEO_VERT_FREQ_INTR_CALLBACK(_write) \
devcb = &downcast<vt100_video_device &>(*device).set_vert_freq_intr_wr_callback(DEVCB_##_write);
#define MCFG_VT_VIDEO_LBA3_LBA4_CALLBACK(_write) \
devcb = &downcast<vt100_video_device &>(*device).set_lba3_lba4_wr_callback(DEVCB_##_write);
#define MCFG_VT_VIDEO_LBA7_CALLBACK(_write) \
devcb = &downcast<vt100_video_device &>(*device).set_lba7_wr_callback(DEVCB_##_write);