diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 9550ce5b735..a32c6225fb9 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -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 diff --git a/src/mame/drivers/vt100.cpp b/src/mame/drivers/vt100.cpp index 92f222537cc..354a4bb3dc6 100644 --- a/src/mame/drivers/vt100.cpp +++ b/src/mame/drivers/vt100.cpp @@ -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 m_maincpu; required_device m_crtc; required_device m_keyboard; + required_device m_kbduart; required_device m_dbrg; required_device m_nvr; + required_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 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: diff --git a/src/mame/machine/vt100_kbd.cpp b/src/mame/machine/vt100_kbd.cpp index d9882423fb0..d080c87ff64 100644 --- a/src/mame/machine/vt100_kbd.cpp +++ b/src/mame/machine/vt100_kbd.cpp @@ -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; } diff --git a/src/mame/machine/vt100_kbd.h b/src/mame/machine/vt100_kbd.h index f43bf075961..99c33a5aa29 100644 --- a/src/mame/machine/vt100_kbd.h +++ b/src/mame/machine/vt100_kbd.h @@ -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(*device).set_int_callback(DEVCB_##_devcb); +#define MCFG_VT100_KEYBOARD_SIGNAL_OUT_CALLBACK(_devcb) \ + devcb = &downcast(*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 devcb_base &set_int_callback(Object &&cb) { return m_int_cb.set_callback(std::forward(cb)); } + template devcb_base &set_signal_out_callback(Object &&cb) { return m_signal_out_cb.set_callback(std::forward(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 m_uart; required_device m_speaker; + required_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 diff --git a/src/mame/video/vtvideo.cpp b/src/mame/video/vtvideo.cpp index 87305255a9a..ff677075692 100644 --- a/src/mame/video/vtvideo.cpp +++ b/src/mame/video/vtvideo.cpp @@ -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); } diff --git a/src/mame/video/vtvideo.h b/src/mame/video/vtvideo.h index e89459ae7a4..5752f0bdc70 100644 --- a/src/mame/video/vtvideo.h +++ b/src/mame/video/vtvideo.h @@ -23,6 +23,7 @@ public: template devcb_base &set_ram_rd_callback(Object &&cb) { return m_read_ram.set_callback(std::forward(cb)); } template devcb_base &set_vert_freq_intr_wr_callback(Object &&cb) { return m_write_vert_freq_intr.set_callback(std::forward(cb)); } + template devcb_base &set_lba3_lba4_wr_callback(Object &&cb) { return m_write_lba3_lba4.set_callback(std::forward(cb)); } template devcb_base &set_lba7_wr_callback(Object &&cb) { return m_write_lba7.set_callback(std::forward(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 m_char_rom; /* character rom region */ required_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(*device).set_vert_freq_intr_wr_callback(DEVCB_##_write); +#define MCFG_VT_VIDEO_LBA3_LBA4_CALLBACK(_write) \ + devcb = &downcast(*device).set_lba3_lba4_wr_callback(DEVCB_##_write); + #define MCFG_VT_VIDEO_LBA7_CALLBACK(_write) \ devcb = &downcast(*device).set_lba7_wr_callback(DEVCB_##_write);