From 4b2e873aaf1e3984e1ca819d4b0268e76c807aa5 Mon Sep 17 00:00:00 2001 From: Mark Garlanger Date: Thu, 24 Aug 2023 01:22:36 -0500 Subject: [PATCH] heathkit/tlb.cpp, heathkit/intr_cntrl.cpp: Converted Heathkit terminal board and interrupt controller to slot devices. (#11494) * This removes the H-19 clones with different terminal boards and allows the H-89 terminal to be selected. * When using the Z-89-37 soft-sectored floppy controller, the Z-37 interrupt controller must be selected. --- src/mame/heathkit/h19.cpp | 90 ++++------------ src/mame/heathkit/h89.cpp | 178 ++++++++++++++++--------------- src/mame/heathkit/intr_cntrl.cpp | 105 ++++++++++++------ src/mame/heathkit/intr_cntrl.h | 93 +++++++++++++--- src/mame/heathkit/tlb.cpp | 110 ++++++++++++------- src/mame/heathkit/tlb.h | 117 ++++++++++++++++---- src/mame/mame.lst | 6 +- 7 files changed, 429 insertions(+), 270 deletions(-) diff --git a/src/mame/heathkit/h19.cpp b/src/mame/heathkit/h19.cpp index cbf4fa5716f..dd932b00c7f 100644 --- a/src/mame/heathkit/h19.cpp +++ b/src/mame/heathkit/h19.cpp @@ -21,97 +21,45 @@ class h19_state : public driver_device public: h19_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_tlb(*this, "tlb") + m_tlbc(*this, "tlbc") { } - // original h19 void h19(machine_config &config); - // replacement ROMs - void h19_superh19(machine_config &config); - void h19_watzh19(machine_config &config); - void h19_ultrah19(machine_config &config); - - // add-on graphics boards - void h19_gp19(machine_config &config); - - private: - required_device m_tlb; + required_device m_tlbc; }; +static void tlb_options(device_slot_interface &device) +{ + device.option_add("heath", HEATH_TLB); + device.option_add("gp19", HEATH_GP19); + device.option_add("super19", HEATH_SUPER19); + device.option_add("ultrarom", HEATH_ULTRA); + device.option_add("watzman", HEATH_WATZ); +} + void h19_state::h19(machine_config &config) { - HEATH_TLB(config, m_tlb); - m_tlb->serial_data_callback().set("dte", FUNC(rs232_port_device::write_txd)); + HEATH_TLB_CONNECTOR(config, m_tlbc, tlb_options, "heath"); + m_tlbc->serial_data_callback().set("dte", FUNC(rs232_port_device::write_txd)); + m_tlbc->dtr_callback().set("dte", FUNC(rs232_port_device::write_dtr)); + m_tlbc->rts_callback().set("dte", FUNC(rs232_port_device::write_rts)); rs232_port_device &dte(RS232_PORT(config, "dte", default_rs232_devices, "loopback")); - dte.rxd_handler().set(m_tlb, FUNC(heath_tlb_device::serial_in_w)); -} - -void h19_state::h19_superh19(machine_config &config) -{ - HEATH_SUPER19(config, m_tlb); - m_tlb->serial_data_callback().set("dte", FUNC(rs232_port_device::write_txd)); - - rs232_port_device &dte(RS232_PORT(config, "dte", default_rs232_devices, "loopback")); - dte.rxd_handler().set(m_tlb, FUNC(heath_tlb_device::serial_in_w)); -} - -void h19_state::h19_watzh19(machine_config &config) -{ - HEATH_WATZ(config, m_tlb); - m_tlb->serial_data_callback().set("dte", FUNC(rs232_port_device::write_txd)); - - rs232_port_device &dte(RS232_PORT(config, "dte", default_rs232_devices, "loopback")); - dte.rxd_handler().set(m_tlb, FUNC(heath_tlb_device::serial_in_w)); -} - -void h19_state::h19_ultrah19(machine_config &config) -{ - HEATH_ULTRA(config, m_tlb); - m_tlb->serial_data_callback().set("dte", FUNC(rs232_port_device::write_txd)); - - rs232_port_device &dte(RS232_PORT(config, "dte", default_rs232_devices, "loopback")); - dte.rxd_handler().set(m_tlb, FUNC(heath_tlb_device::serial_in_w)); -} - -void h19_state::h19_gp19(machine_config &config) -{ - HEATH_GP19(config, m_tlb); - m_tlb->serial_data_callback().set("dte", FUNC(rs232_port_device::write_txd)); - - rs232_port_device &dte(RS232_PORT(config, "dte", default_rs232_devices, "loopback")); - dte.rxd_handler().set(m_tlb, FUNC(heath_tlb_device::serial_in_w)); + dte.rxd_handler().set(m_tlbc, FUNC(heath_tlb_connector::serial_in_w)); + dte.dcd_handler().set(m_tlbc, FUNC(heath_tlb_connector::rlsd_in_w)); + dte.dsr_handler().set(m_tlbc, FUNC(heath_tlb_connector::dsr_in_w)); + dte.cts_handler().set(m_tlbc, FUNC(heath_tlb_connector::cts_in_w)); } // ROM definition ROM_START( h19 ) ROM_END -ROM_START( super19 ) -ROM_END - -ROM_START( watz19 ) -ROM_END - -ROM_START( ultra19 ) -ROM_END - -ROM_START( gp19 ) -ROM_END - } // anonymous namespace // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS COMP( 1979, h19, 0, 0, h19, 0, h19_state, empty_init, "Heath Company", "Heathkit H-19", MACHINE_SUPPORTS_SAVE ) -//Super-19 ROM - ATG Systems, Inc - Adv in Sextant Issue 4, Winter 1983. With the magazine lead-time, likely released late 1982. -COMP( 1982, super19, h19, 0, h19_superh19, 0, h19_state, empty_init, "Heath Company", "Heathkit H-19 w/ Super-19 ROM", MACHINE_SUPPORTS_SAVE ) -// Watzman ROM - HUG p/n 885-1121, announced in REMark Issue 33, Oct. 1982 -COMP( 1982, watz19, h19, 0, h19_watzh19, 0, h19_state, empty_init, "Heath Company", "Heathkit H-19 w/ Watzman ROM", MACHINE_SUPPORTS_SAVE ) -// ULTRA ROM - Software Wizardry, Inc., (c) 1983 William G. Parrott, III -COMP( 1983, ultra19, h19, 0, h19_ultrah19, 0, h19_state, empty_init, "Heath Company", "Heathkit H-19 w/ ULTRA ROM", MACHINE_SUPPORTS_SAVE ) -// GP-19 - Northwest Digital Systems, (c) 1983 -COMP( 1983, gp19, h19, 0, h19_gp19, 0, h19_state, empty_init, "Heath Company", "Heathkit H-19 w/ GP-19", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/heathkit/h89.cpp b/src/mame/heathkit/h89.cpp index d879fccdefa..9622444b785 100644 --- a/src/mame/heathkit/h89.cpp +++ b/src/mame/heathkit/h89.cpp @@ -65,9 +65,9 @@ public: m_mem_view(*this, "rom_bank"), m_ram(*this, RAM_TAG), m_floppy_ram(*this, "floppyram"), - m_tlb(*this, "tlb"), + m_tlbc(*this, "tlbc"), m_h37(*this, "h37"), - m_intr_cntrl(*this, "intr_cntrl"), + m_intr_socket(*this, "intr_socket"), m_console(*this, "console"), m_serial1(*this, "serial1"), m_serial2(*this, "serial2"), @@ -85,9 +85,9 @@ private: memory_view m_mem_view; required_device m_ram; required_shared_ptr m_floppy_ram; - required_device m_tlb; + required_device m_tlbc; required_device m_h37; - required_device m_intr_cntrl; + required_device m_intr_socket; required_device m_console; required_device m_serial1; required_device m_serial2; @@ -181,7 +181,6 @@ void h89_state::h89_mem(address_map &map) // Floppy ROM m_mem_view[0](0x1800, 0x1fff).rom().region("maincpu", 0x1800).unmapw(); m_mem_view[1](0x1800, 0x1fff).rom().region("maincpu", 0x1800).unmapw(); - } /* PORT @@ -243,42 +242,42 @@ void h89_state::h89_io(address_map &map) // Input ports static INPUT_PORTS_START( h89 ) /* - // Settings with the MTR-88 ROM (#444-40) - PORT_START("MTR88_SW501") - PORT_DIPNAME( 0x1f, 0x00, "Unused" ) PORT_DIPLOCATION("S1:1,2,3,4,5") - PORT_DIPNAME( 0x20, 0x20, "Perform memory test at start" ) PORT_DIPLOCATION("S1:6") - PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0xc0, 0x00, "Console Baud rate" ) PORT_DIPLOCATION("S1:7,8") - PORT_DIPSETTING( 0x00, "9600" ) - PORT_DIPSETTING( 0x40, "19200" ) - PORT_DIPSETTING( 0x80, "38400" ) - PORT_DIPSETTING( 0xc0, "57600" ) + // Settings with the MTR-88 ROM (#444-40) + PORT_START("MTR88_SW501") + PORT_DIPNAME( 0x1f, 0x00, "Unused" ) PORT_DIPLOCATION("S1:1,2,3,4,5") + PORT_DIPNAME( 0x20, 0x20, "Perform memory test at start" ) PORT_DIPLOCATION("S1:6") + PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0xc0, 0x00, "Console Baud rate" ) PORT_DIPLOCATION("S1:7,8") + PORT_DIPSETTING( 0x00, "9600" ) + PORT_DIPSETTING( 0x40, "19200" ) + PORT_DIPSETTING( 0x80, "38400" ) + PORT_DIPSETTING( 0xc0, "57600" ) - // Settings with the MTR-89 ROM (#444-62) - PORT_START("MTR89_SW501") - PORT_DIPNAME( 0x03, 0x00, "Disk I/O #2" ) PORT_DIPLOCATION("S1:1,2") - PORT_DIPSETTING( 0x00, "H-88-1" ) - PORT_DIPSETTING( 0x01, "H/Z-47" ) - PORT_DIPSETTING( 0x02, "Undefined" ) - PORT_DIPSETTING( 0x03, "Undefined" ) - PORT_DIPNAME( 0x0c, 0x00, "Disk I/O #1" ) PORT_DIPLOCATION("S1:3,4") - PORT_DIPSETTING( 0x00, "Unused" ) - PORT_DIPSETTING( 0x04, "H/Z-47" ) - PORT_DIPSETTING( 0x08, "Undefined" ) - PORT_DIPSETTING( 0x0c, "Undefined" ) - PORT_DIPNAME( 0x10, 0x00, "Primary Boot from" ) PORT_DIPLOCATION("S1:5") - PORT_DIPSETTING( 0x00, "Disk I/O #2" ) - PORT_DIPSETTING( 0x10, "Disk I/O #1" ) - PORT_DIPNAME( 0x20, 0x20, "Perform memory test at start" ) PORT_DIPLOCATION("S1:6") - PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, "Console Baud rate" ) PORT_DIPLOCATION("S1:7") - PORT_DIPSETTING( 0x00, "9600" ) - PORT_DIPSETTING( 0x40, "19200" ) - PORT_DIPNAME( 0x80, 0x00, "Boot mode" ) PORT_DIPLOCATION("S1:8") - PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) - PORT_DIPSETTING( 0x80, "Auto" ) + // Settings with the MTR-89 ROM (#444-62) + PORT_START("MTR89_SW501") + PORT_DIPNAME( 0x03, 0x00, "Disk I/O #2" ) PORT_DIPLOCATION("S1:1,2") + PORT_DIPSETTING( 0x00, "H-88-1" ) + PORT_DIPSETTING( 0x01, "H/Z-47" ) + PORT_DIPSETTING( 0x02, "Undefined" ) + PORT_DIPSETTING( 0x03, "Undefined" ) + PORT_DIPNAME( 0x0c, 0x00, "Disk I/O #1" ) PORT_DIPLOCATION("S1:3,4") + PORT_DIPSETTING( 0x00, "Unused" ) + PORT_DIPSETTING( 0x04, "H/Z-47" ) + PORT_DIPSETTING( 0x08, "Undefined" ) + PORT_DIPSETTING( 0x0c, "Undefined" ) + PORT_DIPNAME( 0x10, 0x00, "Primary Boot from" ) PORT_DIPLOCATION("S1:5") + PORT_DIPSETTING( 0x00, "Disk I/O #2" ) + PORT_DIPSETTING( 0x10, "Disk I/O #1" ) + PORT_DIPNAME( 0x20, 0x20, "Perform memory test at start" ) PORT_DIPLOCATION("S1:6") + PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x40, 0x00, "Console Baud rate" ) PORT_DIPLOCATION("S1:7") + PORT_DIPSETTING( 0x00, "9600" ) + PORT_DIPSETTING( 0x40, "19200" ) + PORT_DIPNAME( 0x80, 0x00, "Boot mode" ) PORT_DIPLOCATION("S1:8") + PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x80, "Auto" ) */ // Settings with the MTR-90 ROM (#444-84 or 444-142) PORT_START("MTR90_SW501") @@ -305,30 +304,30 @@ static INPUT_PORTS_START( h89 ) PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x80, "Auto" ) /* - // Settings with the MMS 84-B - PORT_START("MMS84B_SW501") - PORT_DIPNAME( 0x03, 0x00, "Disk I/O #2" ) PORT_DIPLOCATION("S1:1,2") - PORT_DIPSETTING( 0x00, "H-88-1" ) - PORT_DIPSETTING( 0x01, "H/Z-47 (Not yet implemented)" ) - PORT_DIPSETTING( 0x02, "MMS 77320 SASI or Z-67 (Not yet implemented)" ) - PORT_DIPSETTING( 0x03, "MMS 77422 Network Controller" ) - PORT_DIPNAME( 0x0c, 0x00, "Disk I/O #1" ) PORT_DIPLOCATION("S1:3,4") - PORT_DIPSETTING( 0x00, "H-89-37" ) - PORT_DIPSETTING( 0x04, "H/Z-47 (Not yet implemented)" ) - PORT_DIPSETTING( 0x08, "MMS 77320 SASI or Z-67 (Not yet implemented)" ) - PORT_DIPSETTING( 0x0c, "MMS 77422 Network Controller" ) - PORT_DIPNAME( 0x70, 0x00, "Default Boot Device" ) PORT_DIPLOCATION("S1:5,6,7") - PORT_DIPSETTING( 0x00, "MMS 77316 Dbl Den 5\"" ) - PORT_DIPSETTING( 0x10, "MMS 77316 Dbl Den 8\"" ) - PORT_DIPSETTING( 0x20, "Disk Device at 0x7C" ) - PORT_DIPSETTING( 0x30, "Disk Device at 0x78" ) - PORT_DIPSETTING( 0x40, "reserved for future use" ) - PORT_DIPSETTING( 0x50, "reserved for future use" ) - PORT_DIPSETTING( 0x60, "MMS Network (77422)" ) - PORT_DIPSETTING( 0x70, "Use MMS I/O board Config Port" ) - PORT_DIPNAME( 0x80, 0x00, "Boot mode" ) PORT_DIPLOCATION("S1:8") - PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) - PORT_DIPSETTING( 0x80, "Auto" ) + // Settings with the MMS 84-B + PORT_START("MMS84B_SW501") + PORT_DIPNAME( 0x03, 0x00, "Disk I/O #2" ) PORT_DIPLOCATION("S1:1,2") + PORT_DIPSETTING( 0x00, "H-88-1" ) + PORT_DIPSETTING( 0x01, "H/Z-47 (Not yet implemented)" ) + PORT_DIPSETTING( 0x02, "MMS 77320 SASI or Z-67 (Not yet implemented)" ) + PORT_DIPSETTING( 0x03, "MMS 77422 Network Controller" ) + PORT_DIPNAME( 0x0c, 0x00, "Disk I/O #1" ) PORT_DIPLOCATION("S1:3,4") + PORT_DIPSETTING( 0x00, "H-89-37" ) + PORT_DIPSETTING( 0x04, "H/Z-47 (Not yet implemented)" ) + PORT_DIPSETTING( 0x08, "MMS 77320 SASI or Z-67 (Not yet implemented)" ) + PORT_DIPSETTING( 0x0c, "MMS 77422 Network Controller" ) + PORT_DIPNAME( 0x70, 0x00, "Default Boot Device" ) PORT_DIPLOCATION("S1:5,6,7") + PORT_DIPSETTING( 0x00, "MMS 77316 Dbl Den 5\"" ) + PORT_DIPSETTING( 0x10, "MMS 77316 Dbl Den 8\"" ) + PORT_DIPSETTING( 0x20, "Disk Device at 0x7C" ) + PORT_DIPSETTING( 0x30, "Disk Device at 0x78" ) + PORT_DIPSETTING( 0x40, "reserved for future use" ) + PORT_DIPSETTING( 0x50, "reserved for future use" ) + PORT_DIPSETTING( 0x60, "MMS Network (77422)" ) + PORT_DIPSETTING( 0x70, "Use MMS I/O board Config Port" ) + PORT_DIPNAME( 0x80, 0x00, "Boot mode" ) PORT_DIPLOCATION("S1:8") + PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x80, "Auto" ) */ INPUT_PORTS_END @@ -375,6 +374,7 @@ void h89_state::machine_start() m_rom_enabled = true; m_timer_intr_enabled = true; m_floppy_ram_wp = false; + update_gpp(0); update_mem_view(); } @@ -404,14 +404,7 @@ void h89_state::raise_NMI_w(uint8_t) void h89_state::console_intr(uint8_t data) { - if (bool(data)) - { - m_intr_cntrl->raise_irq(3); - } - else - { - m_intr_cntrl->lower_irq(3); - } + m_intr_socket->set_irq_level(3, data); } void h89_state::reset_line(int data) @@ -427,7 +420,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(h89_state::h89_irq_timer) { if (m_timer_intr_enabled) { - m_intr_cntrl->raise_irq(1); + m_intr_socket->set_irq_level(1, ASSERT_LINE); } } @@ -457,7 +450,22 @@ void h89_state::port_f2_w(uint8_t data) { update_gpp(data); - m_intr_cntrl->lower_irq(1); + m_intr_socket->set_irq_level(1, CLEAR_LINE); +} + +static void tlb_options(device_slot_interface &device) +{ + device.option_add("heath", HEATH_TLB); + device.option_add("gp19", HEATH_GP19); + device.option_add("super19", HEATH_SUPER19); + device.option_add("ultrarom", HEATH_ULTRA); + device.option_add("watzman", HEATH_WATZ); +} + +static void intr_ctrl_options(device_slot_interface &device) +{ + device.option_add("original", HEATH_INTR_CNTRL); + device.option_add("h37", HEATH_Z37_INTR_CNTRL); } void h89_state::h89(machine_config & config) @@ -466,28 +474,28 @@ void h89_state::h89(machine_config & config) Z80(config, m_maincpu, H89_CLOCK); m_maincpu->set_addrmap(AS_PROGRAM, &h89_state::h89_mem); m_maincpu->set_addrmap(AS_IO, &h89_state::h89_io); - m_maincpu->set_irq_acknowledge_callback("intr_cntrl", FUNC(heath_intr_cntrl::irq_callback)); + m_maincpu->set_irq_acknowledge_callback("intr_socket", FUNC(heath_intr_socket::irq_callback)); - HEATH_Z37_INTR_CNTRL(config, m_intr_cntrl); - m_intr_cntrl->irq_line_cb().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + HEATH_INTR_SOCKET(config, m_intr_socket, intr_ctrl_options, "h37"); + m_intr_socket->irq_line_cb().set_inputline(m_maincpu, INPUT_LINE_IRQ0); RAM(config, m_ram).set_default_size("64K").set_extra_options("16K,32K,48K").set_default_value(0x00); INS8250(config, m_console, INS8250_CLOCK); m_console->out_int_callback().set(FUNC(h89_state::console_intr)); - HEATH_TLB(config, m_tlb); + HEATH_TLB_CONNECTOR(config, m_tlbc, tlb_options, "heath"); - // Connect the console port on CPU board to serial port on TLB - m_console->out_tx_callback().set(m_tlb, FUNC(heath_tlb_device::serial_in_w)); - m_tlb->serial_data_callback().set(m_console, FUNC(ins8250_uart_device::rx_w)); + // Connect the console port on CPU board to TLB connector + m_console->out_tx_callback().set(m_tlbc, FUNC(heath_tlb_connector::serial_in_w)); + m_tlbc->serial_data_callback().set(m_console, FUNC(ins8250_uart_device::rx_w)); - m_tlb->reset_cb().set(FUNC(h89_state::reset_line)); + m_tlbc->reset_cb().set(FUNC(h89_state::reset_line)); HEATH_Z37_FDC(config, m_h37); - m_h37->drq_cb().set(m_intr_cntrl, FUNC(z37_intr_cntrl::set_drq)); - m_h37->irq_cb().set(m_intr_cntrl, FUNC(z37_intr_cntrl::set_irq)); - m_h37->block_interrupt_cb().set(m_intr_cntrl, FUNC(z37_intr_cntrl::block_interrupts)); + m_h37->drq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_drq)); + m_h37->irq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_irq)); + m_h37->block_interrupt_cb().set(m_intr_socket, FUNC(heath_intr_socket::block_interrupts)); // H-88-3 3-port serial board INS8250(config, m_serial1, INS8250_CLOCK); diff --git a/src/mame/heathkit/intr_cntrl.cpp b/src/mame/heathkit/intr_cntrl.cpp index 1831fa203e5..1957acf6e10 100644 --- a/src/mame/heathkit/intr_cntrl.cpp +++ b/src/mame/heathkit/intr_cntrl.cpp @@ -13,6 +13,21 @@ DEFINE_DEVICE_TYPE(HEATH_INTR_CNTRL, heath_intr_cntrl, "heath_intr_cntrl", "Heath H/Z-89 Interrupt Controller"); DEFINE_DEVICE_TYPE(HEATH_Z37_INTR_CNTRL, z37_intr_cntrl, "heath_z37_intr_cntrl", "Heath H/Z-89 with Z-37 Interrupt Controller"); +DEFINE_DEVICE_TYPE(HEATH_INTR_SOCKET, heath_intr_socket, "heath_intr_socket", "Heath Interrupt Socket"); + +/** + * Heath interrupt interface + */ +device_heath_intr_interface::device_heath_intr_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "heathintrdevice"), + m_socket(dynamic_cast(device.owner())) +{ +} + +/** + * Original Heath interrrupt controller + * + */ heath_intr_cntrl::heath_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): heath_intr_cntrl(mconfig, HEATH_INTR_CNTRL, tag, owner, clock) { @@ -20,7 +35,7 @@ heath_intr_cntrl::heath_intr_cntrl(const machine_config &mconfig, const char *ta heath_intr_cntrl::heath_intr_cntrl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock): device_t(mconfig, type, tag, owner, 0), - m_irq_line(*this) + device_heath_intr_interface(mconfig, *this) { } @@ -31,30 +46,27 @@ void heath_intr_cntrl::device_start() m_intr_lines = 0; } -void heath_intr_cntrl::device_reset() -{ -} - void heath_intr_cntrl::update_intr_line() { - - m_irq_line((m_intr_lines == 0) ? 0 : 1); + if (m_socket) + { + m_socket->raise_irq((m_intr_lines == 0) ? 0 : 1); + } } -void heath_intr_cntrl::raise_irq(uint8_t level) +void heath_intr_cntrl::set_irq_level(uint8_t level, int data) { // only 0 to 7 is valid level &= 0x7; - m_intr_lines |= 1 << level; - update_intr_line(); -} - -void heath_intr_cntrl::lower_irq(uint8_t level) -{ - // only 0 to 7 is valid - level &= 0x7; - m_intr_lines &= ~(1 << level); + if (data == 0) + { + m_intr_lines &= ~(1 << level); + } + else + { + m_intr_lines |= 1 << level; + } update_intr_line(); } @@ -72,6 +84,7 @@ uint8_t heath_intr_cntrl::get_instruction() return 0x00; } + // ideally this would be handled with a function like ffs() uint8_t level = 0; uint8_t mask = 0x01; @@ -94,22 +107,20 @@ uint8_t heath_intr_cntrl::get_instruction() return 0xc7 | ((level & 0x7) << 3); } -IRQ_CALLBACK_MEMBER(heath_intr_cntrl::irq_callback) -{ - return get_instruction(); -} - +/** + * Interrupt controller for the Z37 soft-sectored controller. + * + * It will take control of the interrupt system and block all other + * interrupts while it is waiting for Z37 events. + */ z37_intr_cntrl::z37_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): heath_intr_cntrl(mconfig, HEATH_Z37_INTR_CNTRL, tag, owner, clock) { - m_intr_blocked = false; - m_drq_raised = false; - m_irq_raised = false; } void z37_intr_cntrl::update_intr_line() { - m_irq_line( + m_socket->raise_irq( (m_irq_raised || m_drq_raised || (!m_intr_blocked && (m_intr_lines != 0))) ? 1 : 0); } @@ -129,7 +140,6 @@ uint8_t z37_intr_cntrl::get_instruction() return 0xe7; } - if (!m_intr_blocked) { return heath_intr_cntrl::get_instruction(); @@ -168,14 +178,45 @@ void z37_intr_cntrl::device_start() m_irq_raised = false; } -void z37_intr_cntrl::device_reset() -{ - heath_intr_cntrl::device_reset(); -} - void z37_intr_cntrl::block_interrupts(uint8_t data) { m_intr_blocked = bool(data); update_intr_line(); } + + +/** + * Heath Interrupt socket + * + * Allows choice of interrupt controllers for Heath 8-bit computers. + */ +heath_intr_socket::heath_intr_socket(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, HEATH_INTR_SOCKET, tag, owner, clock), + device_single_card_slot_interface(mconfig, *this), + m_irq_line(*this), + m_cntrl(nullptr) +{ +} + +heath_intr_socket::~heath_intr_socket() +{ +} + +void heath_intr_socket::device_start() +{ + m_cntrl = get_card_device(); +} + +IRQ_CALLBACK_MEMBER(heath_intr_socket::irq_callback) +{ + // assume NO-OP + uint8_t instr = 0x00; + + if (m_cntrl) + { + instr = m_cntrl->get_instruction(); + } + + return instr; +} diff --git a/src/mame/heathkit/intr_cntrl.h b/src/mame/heathkit/intr_cntrl.h index f5972e41750..a7ea6247baf 100644 --- a/src/mame/heathkit/intr_cntrl.h +++ b/src/mame/heathkit/intr_cntrl.h @@ -13,32 +13,49 @@ #pragma once +class heath_intr_socket; + +class device_heath_intr_interface : public device_interface +{ +public: + // required operation + virtual void set_irq_level(uint8_t level, int state) = 0; + + virtual void set_drq(int state) {} + virtual void set_irq(int state) {} + virtual void block_interrupts(uint8_t data) {} + +protected: + // construction/destruction + device_heath_intr_interface(const machine_config &mconfig, device_t &device); + + virtual uint8_t get_instruction() = 0; + + heath_intr_socket * const m_socket; + + friend heath_intr_socket; +}; + + /** - * Heath H89 interrupt controller + * Heath interrupt controller * */ -class heath_intr_cntrl : public device_t +class heath_intr_cntrl : public device_t, + public device_heath_intr_interface { public: heath_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - virtual void raise_irq(uint8_t level); - virtual void lower_irq(uint8_t level); - - IRQ_CALLBACK_MEMBER(irq_callback); - - auto irq_line_cb() { return m_irq_line.bind(); } + virtual void set_irq_level(uint8_t level, int state) override; protected: heath_intr_cntrl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); - virtual uint8_t get_instruction(); + virtual uint8_t get_instruction() override; virtual void update_intr_line(); virtual void device_start() override; - virtual void device_reset() override; - - devcb_write8 m_irq_line; uint8_t m_intr_lines; }; @@ -52,17 +69,15 @@ class z37_intr_cntrl : public heath_intr_cntrl public: z37_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - virtual void set_drq(int state); - virtual void set_irq(int state); - virtual void block_interrupts(uint8_t data); + virtual void set_drq(int state) override; + virtual void set_irq(int state) override; + virtual void block_interrupts(uint8_t data) override; protected: - virtual uint8_t get_instruction() override; virtual void update_intr_line() override; virtual void device_start() override; - virtual void device_reset() override; private: bool m_intr_blocked; @@ -73,4 +88,48 @@ private: DECLARE_DEVICE_TYPE(HEATH_INTR_CNTRL, heath_intr_cntrl) DECLARE_DEVICE_TYPE(HEATH_Z37_INTR_CNTRL, z37_intr_cntrl) + +class heath_intr_socket : public device_t, + public device_single_card_slot_interface +{ +public: + + template + heath_intr_socket(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt, bool fixed = false) : + heath_intr_socket(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + + heath_intr_socket(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~heath_intr_socket(); + + auto irq_line_cb() { return m_irq_line.bind(); } + + // required operation + void set_irq_level(uint8_t level, int state) { if (m_cntrl) { m_cntrl->set_irq_level(level, state); }} + + IRQ_CALLBACK_MEMBER(irq_callback); + + void raise_irq(int state) { m_irq_line(state); } + + void set_irq(int state) { if (m_cntrl) { m_cntrl->set_irq(state); }} + void set_drq(int state) { if (m_cntrl) { m_cntrl->set_drq(state); }} + void block_interrupts(uint8_t data) { if (m_cntrl) { m_cntrl->block_interrupts(data); }} + +protected: + + virtual void device_start() override; + + devcb_write8 m_irq_line; + + device_heath_intr_interface *m_cntrl; +}; + + +DECLARE_DEVICE_TYPE(HEATH_INTR_SOCKET, heath_intr_socket) + #endif // MAME_HEATHKIT_H89_INTR_CNTRL_H diff --git a/src/mame/heathkit/tlb.cpp b/src/mame/heathkit/tlb.cpp index fcf6c7a9322..2cf42c18d80 100644 --- a/src/mame/heathkit/tlb.cpp +++ b/src/mame/heathkit/tlb.cpp @@ -85,6 +85,7 @@ static constexpr uint8_t KB_STATUS_SHIFT_KEYS_MASK = 0x01; static constexpr uint8_t KB_STATUS_CONTROL_KEY_MASK = 0x10; static constexpr uint8_t KB_STATUS_KEYBOARD_STROBE_MASK = 0x80; +DEFINE_DEVICE_TYPE(HEATH_TLB_CONNECTOR, heath_tlb_connector, "heath_tlb_connector", "Heath Terminal Logic board connector abstraction") DEFINE_DEVICE_TYPE(HEATH_TLB, heath_tlb_device, "heath_tlb", "Heath Terminal Logic Board"); DEFINE_DEVICE_TYPE(HEATH_SUPER19, heath_super19_tlb_device, "heath_super19_tlb", "Heath Terminal Logic Board w/Super19 ROM"); @@ -93,6 +94,14 @@ DEFINE_DEVICE_TYPE(HEATH_ULTRA, heath_ultra_tlb_device, "heath_ultra_tlb", "Heat DEFINE_DEVICE_TYPE(HEATH_GP19, heath_gp19_tlb_device, "heath_gp19_tlb", "Heath Terminal Logic Board plus Northwest Digital Systems GP-19") + +device_heath_tlb_card_interface::device_heath_tlb_card_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "heathtlbdevice"), + m_slot(dynamic_cast(device.owner())) +{ +} + + /** * base Heath h19 functionality */ @@ -103,16 +112,13 @@ heath_tlb_device::heath_tlb_device(const machine_config &mconfig, const char *ta heath_tlb_device::heath_tlb_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_heath_tlb_card_interface(mconfig, *this), m_maincpu(*this, "maincpu"), m_screen(*this, "screen"), m_palette(*this, "palette"), m_crtc(*this, "crtc"), m_p_videoram(*this, "videoram"), m_p_chargen(*this, "chargen"), - m_write_sd(*this), - m_dtr_cb(*this), - m_rts_cb(*this), - m_reset(*this), m_ace(*this, "ins8250"), m_beep(*this, "beeper"), m_mm5740(*this, "mm5740"), @@ -161,7 +167,6 @@ void heath_tlb_device::io_map(address_map &map) map(0x40, 0x47).mirror(0x18).rw(m_ace, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w)); map(0x60, 0x60).mirror(0x1a).select(0x04).w(FUNC(heath_tlb_device::crtc_addr_w)); map(0x61, 0x61).mirror(0x1a).select(0x04).rw(FUNC(heath_tlb_device::crtc_reg_r), FUNC(heath_tlb_device::crtc_reg_w)); - map(0x80, 0x80).mirror(0x1f).r(FUNC(heath_tlb_device::kbd_key_r)); map(0xa0, 0xa0).mirror(0x1f).r(FUNC(heath_tlb_device::kbd_flags_r)); map(0xc0, 0xc0).mirror(0x1f).w(FUNC(heath_tlb_device::key_click_w)); @@ -231,9 +236,10 @@ uint16_t heath_tlb_device::translate_mm5740_b(uint16_t b) uint8_t heath_tlb_device::kbd_key_r() { - m_keyboard_irq_raised = false; - set_irq_line(); m_strobe = false; + m_keyboard_irq_raised = false; + + set_irq_line(); // high bit is for control key pressed, this is handled in the ROM, // no processing needed. @@ -278,6 +284,7 @@ void heath_tlb_device::mm5740_data_ready_w(int state) m_transchar = decode[translate_mm5740_b(m_mm5740->b_r())]; m_strobe = true; m_keyboard_irq_raised = true; + set_irq_line(); } } @@ -311,6 +318,7 @@ void heath_tlb_device::crtc_vsync_w(int val) void heath_tlb_device::serial_irq_w(int state) { m_serial_irq_raised = bool(state); + set_irq_line(); } @@ -326,7 +334,7 @@ void heath_tlb_device::check_for_reset() if (m_reset_key && m_right_shift) { m_reset_pending = true; - m_reset(1); + m_slot->reset_out(1); m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); } else if (m_reset_pending) @@ -334,7 +342,7 @@ void heath_tlb_device::check_for_reset() m_reset_pending = false; reset(); m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - m_reset(0); + m_slot->reset_out(0); } } @@ -354,7 +362,7 @@ void heath_tlb_device::right_shift_w(int state) void heath_tlb_device::repeat_key_w(int state) { - // when repeat key pressed, set duty cycle to 0.5, else 0. + // when repeat key pressed, set duty cycle to 50%, else 0%. m_repeat_clock->set_duty_cycle(state == 0 ? 0.5 : 0); } @@ -384,7 +392,7 @@ MC6845_UPDATE_ROW(heath_tlb_device::crtc_update_row) } // get pattern of pixels for that character scanline - uint8_t const gfx = m_p_chargen[(chr<<4) | ra] ^ inv; + uint8_t const gfx = m_p_chargen[(chr << 4) | ra] ^ inv; // Display a scanline of a character (8 pixels) for (int b = 0; 8 > b; ++b) @@ -414,7 +422,7 @@ static const gfx_layout h19_charlayout = 8*16 // every char takes 16 bytes }; -static GFXDECODE_START(gfx_h19) +static GFXDECODE_START( gfx_h19 ) GFXDECODE_ENTRY("chargen", 0x0000, h19_charlayout, 0, 1) GFXDECODE_END @@ -448,7 +456,7 @@ static INPUT_PORTS_START( tlb ) PORT_START("X2") PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("{ }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('{') PORT_CHAR('}') PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_UNUSED) @@ -558,12 +566,12 @@ static INPUT_PORTS_START( tlb ) PORT_DIPSETTING( 0x0c, "9600") PORT_DIPSETTING( 0x0d, "19200") PORT_DIPNAME( 0x30, 0x00, "Parity") PORT_DIPLOCATION("SW401:5,6") - PORT_DIPSETTING( 0x00, DEF_STR(None)) + PORT_DIPSETTING( 0x00, DEF_STR( None ) ) PORT_DIPSETTING( 0x10, "Odd") - PORT_DIPSETTING( 0x20, "None") + PORT_DIPSETTING( 0x20, DEF_STR( None ) ) PORT_DIPSETTING( 0x30, "Even") PORT_DIPNAME( 0x40, 0x00, "Parity Type") PORT_DIPLOCATION("SW401:7") - PORT_DIPSETTING( 0x00, DEF_STR(Normal)) + PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x40, "Stick") PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") PORT_DIPSETTING( 0x00, "Half") @@ -574,23 +582,23 @@ static INPUT_PORTS_START( tlb ) PORT_DIPSETTING( 0x00, "Underline") PORT_DIPSETTING( 0x01, "Block") PORT_DIPNAME( 0x02, 0x00, "Keyclick") PORT_DIPLOCATION("SW402:2") - PORT_DIPSETTING( 0x02, DEF_STR(No)) - PORT_DIPSETTING( 0x00, DEF_STR(Yes)) + PORT_DIPSETTING( 0x02, DEF_STR( No ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) PORT_DIPNAME( 0x04, 0x00, "Wrap at EOL") PORT_DIPLOCATION("SW402:3") - PORT_DIPSETTING( 0x00, DEF_STR(No)) - PORT_DIPSETTING( 0x04, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) PORT_DIPNAME( 0x08, 0x00, "Auto LF on CR") PORT_DIPLOCATION("SW402:4") - PORT_DIPSETTING( 0x00, DEF_STR(No)) - PORT_DIPSETTING( 0x08, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x08, DEF_STR( Yes ) ) PORT_DIPNAME( 0x10, 0x00, "Auto CR on LF") PORT_DIPLOCATION("SW402:5") - PORT_DIPSETTING( 0x00, DEF_STR(No)) - PORT_DIPSETTING( 0x10, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x10, DEF_STR( Yes ) ) PORT_DIPNAME( 0x20, 0x00, "Mode") PORT_DIPLOCATION("SW402:6") PORT_DIPSETTING( 0x00, "Heath/VT52") PORT_DIPSETTING( 0x20, "ANSI") PORT_DIPNAME( 0x40, 0x00, "Keypad Shifted") PORT_DIPLOCATION("SW402:7") - PORT_DIPSETTING( 0x00, DEF_STR(No)) - PORT_DIPSETTING( 0x40, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x40, DEF_STR( Yes ) ) PORT_DIPNAME( 0x80, 0x00, "Refresh") PORT_DIPLOCATION("SW402:8") PORT_DIPSETTING( 0x00, "60Hz") PORT_DIPSETTING( 0x80, "50Hz") @@ -631,11 +639,11 @@ static INPUT_PORTS_START( super19 ) PORT_MODIFY("SW402") PORT_DIPNAME( 0x02, 0x00, "Transmit mode") PORT_DIPLOCATION("SW402:2") - PORT_DIPSETTING( 0x00, DEF_STR(Normal)) + PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x02, "Slow") PORT_DIPNAME( 0x80, 0x00, "DEC Keypad Codes") PORT_DIPLOCATION("SW402:8") - PORT_DIPSETTING( 0x00, "Off") - PORT_DIPSETTING( 0x80, "On") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x80, DEF_STR( On ) ) INPUT_PORTS_END @@ -670,8 +678,8 @@ static INPUT_PORTS_START( ultra19 ) PORT_MODIFY("SW402") PORT_DIPNAME( 0x08, 0x00, "Keypad Shifted") PORT_DIPLOCATION("SW402:4") - PORT_DIPSETTING( 0x00, DEF_STR(No)) - PORT_DIPSETTING( 0x08, DEF_STR(Yes)) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x08, DEF_STR( Yes ) ) PORT_DIPNAME( 0x10, 0x00, "Default Key Values") PORT_DIPLOCATION("SW402:5") PORT_DIPSETTING( 0x00, "HDOS Values") PORT_DIPSETTING( 0x10, "CP/M Values") @@ -681,8 +689,8 @@ static INPUT_PORTS_START( ultra19 ) PORT_DIPSETTING( 0x40, "Fast Blink") PORT_DIPSETTING( 0x60, "Slow Blink") PORT_DIPNAME( 0x80, 0x00, "Interlace Scan Mode") PORT_DIPLOCATION("SW402:8") - PORT_DIPSETTING( 0x00, "Off") - PORT_DIPSETTING( 0x80, "On") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x80, DEF_STR( On ) ) INPUT_PORTS_END @@ -726,12 +734,12 @@ static INPUT_PORTS_START( gp19 ) PORT_START("SW1") PORT_DIPNAME( 0x03, 0x01, "Trailing Characters for Tektronix Message") PORT_DIPLOCATION("SW1:1,2") - PORT_DIPSETTING( 0x00, "None") + PORT_DIPSETTING( 0x00, DEF_STR( None ) ) PORT_DIPSETTING( 0x01, "CR") - PORT_DIPSETTING( 0x02, "None") + PORT_DIPSETTING( 0x02, DEF_STR( None ) ) PORT_DIPSETTING( 0x03, "CR,EOT") PORT_DIPNAME( 0x04, 0x01, "Shift Key") PORT_DIPLOCATION("SW1:3") - PORT_DIPSETTING( 0x00, "Normal") + PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x04, "Shift key inverts CAPS LOCK") PORT_DIPNAME( 0x08, 0x00, "Terminal Transmission Rate") PORT_DIPLOCATION("SW1:4") PORT_DIPSETTING( 0x00, "Only limited by baud rate") @@ -842,17 +850,17 @@ const tiny_rom_entry *heath_tlb_device::device_rom_region() const void heath_tlb_device::serial_out_b(int data) { - m_write_sd(data); + m_slot->serial_out_b(data); } void heath_tlb_device::dtr_out(int data) { - m_dtr_cb(data); + m_slot->dtr_out(data); } void heath_tlb_device::rts_out(int data) { - m_rts_cb(data); + m_slot->rts_out(data); } void heath_tlb_device::serial_in_w(int state) @@ -870,7 +878,7 @@ void heath_tlb_device::dsr_in_w(int state) m_ace->dsr_w(state); } -void heath_tlb_device::cts_int_w(int state) +void heath_tlb_device::cts_in_w(int state) { m_ace->cts_w(state); } @@ -1174,3 +1182,25 @@ ioport_constructor heath_gp19_tlb_device::device_input_ports() const { return INPUT_PORTS_NAME(gp19); } + + +heath_tlb_connector::heath_tlb_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, HEATH_TLB_CONNECTOR, tag, owner, clock), + device_single_card_slot_interface(mconfig, *this), + m_write_sd(*this), + m_dtr_cb(*this), + m_rts_cb(*this), + m_reset(*this), + m_tlb(nullptr) +{ +} + + +heath_tlb_connector::~heath_tlb_connector() +{ +} + +void heath_tlb_connector::device_start() +{ + m_tlb = get_card_device(); +} diff --git a/src/mame/heathkit/tlb.h b/src/mame/heathkit/tlb.h index 5b11b6c8ad7..2954530a666 100644 --- a/src/mame/heathkit/tlb.h +++ b/src/mame/heathkit/tlb.h @@ -22,22 +22,42 @@ #include "speaker.h" -// Standard Heath Terminal logic board -class heath_tlb_device : public device_t +class heath_tlb_connector; + +class device_heath_tlb_card_interface : public device_interface +{ +public: + + // required operation + virtual void serial_in_w(int state) = 0; + + // optional operations + virtual void rlsd_in_w(int state) {} + virtual void dsr_in_w(int state) {} + virtual void cts_in_w(int state) {} + +protected: + // construction/destruction + device_heath_tlb_card_interface(const machine_config &mconfig, device_t &device); + + heath_tlb_connector * const m_slot; +}; + + + +/** + * Standard Heath Terminal logic board + */ +class heath_tlb_device : public device_t, + public device_heath_tlb_card_interface { public: heath_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - // interface routines - auto serial_data_callback() { return m_write_sd.bind(); } - auto dtr_callback() { return m_dtr_cb.bind(); } - auto rts_callback() { return m_rts_cb.bind(); } - auto reset_cb() { return m_reset.bind(); } - - void serial_in_w(int state); - void rlsd_in_w(int state); - void dsr_in_w(int state); - void cts_int_w(int state); + virtual void serial_in_w(int state) override; + virtual void rlsd_in_w(int state) override; + virtual void dsr_in_w(int state) override; + virtual void cts_in_w(int state) override; void reset_key_w(int state); void right_shift_w(int state); @@ -97,11 +117,6 @@ private: emu_timer *m_key_click_timer; emu_timer *m_bell_timer; - devcb_write_line m_write_sd; - devcb_write_line m_dtr_cb; - devcb_write_line m_rts_cb; - devcb_write_line m_reset; - required_device m_ace; required_device m_beep; required_device m_mm5740; @@ -122,7 +137,9 @@ private: bool m_allow_vsync_nmi; }; -// Heath TLB with Super19 ROM +/** + * Heath TLB with Super19 ROM + */ class heath_super19_tlb_device : public heath_tlb_device { public: @@ -144,7 +161,9 @@ protected: virtual ioport_constructor device_input_ports() const override; }; -// Heath TLB with Ultra ROM +/** + * Heath TLB with Ultra ROM + */ class heath_ultra_tlb_device : public heath_tlb_device { public: @@ -158,12 +177,16 @@ protected: void mem_map(address_map &map); }; -// Heath TLB plus Northwest Digital Systems GP-19 +/** + * Heath TLB plus Northwest Digital Systems GP-19 + */ class heath_gp19_tlb_device : public heath_tlb_device { public: heath_gp19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + protected: virtual const tiny_rom_entry *device_rom_region() const override; virtual ioport_constructor device_input_ports() const override; @@ -190,4 +213,58 @@ DECLARE_DEVICE_TYPE(HEATH_SUPER19, heath_super19_tlb_device) DECLARE_DEVICE_TYPE(HEATH_WATZ, heath_watz_tlb_device) DECLARE_DEVICE_TYPE(HEATH_ULTRA, heath_ultra_tlb_device) + +/** + * Connector for the Terminal Logic Board in an H-89 class computer + */ +class heath_tlb_connector : public device_t, + public device_single_card_slot_interface +{ +public: + + template + heath_tlb_connector(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt, bool fixed = false) : + heath_tlb_connector(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + + heath_tlb_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~heath_tlb_connector(); + + // computer interface + auto serial_data_callback() { return m_write_sd.bind(); } + auto dtr_callback() { return m_dtr_cb.bind(); } + auto rts_callback() { return m_rts_cb.bind(); } + auto reset_cb() { return m_reset.bind(); } + + // card interface + void serial_in_w(int state) { if (m_tlb) m_tlb->serial_in_w(state); } + void rlsd_in_w(int state) { if (m_tlb) m_tlb->rlsd_in_w(state); } + void dsr_in_w(int state) { if (m_tlb) m_tlb->dsr_in_w(state); } + void cts_in_w(int state) { if (m_tlb) m_tlb->cts_in_w(state); } + + void serial_out_b(int data) { m_write_sd(data); } + void dtr_out(int data) { m_dtr_cb(data); } + void rts_out(int data) { m_rts_cb(data); } + void reset_out(int data) { m_reset(data); } + +protected: + virtual void device_start() override; + + devcb_write_line m_write_sd; + devcb_write_line m_dtr_cb; + devcb_write_line m_rts_cb; + devcb_write_line m_reset; + + device_heath_tlb_card_interface *m_tlb; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(HEATH_TLB_CONNECTOR, heath_tlb_connector) + #endif // MAME_HEATHKIT_TLB_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c44c0c82a6d..3da9d7cf990 100755 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -19194,13 +19194,9 @@ h8 // @source:heathkit/h19.cpp h19 // Heath H19 (Zenith Z-19) -gp19 // H19 with Northwest Digital Systems GP-19 -super19 // Super19 replacement ROMS for H19 -ultra19 // ULTRA ROM replacement ROMS for H19 -watz19 // Watzman replacement ROMS for H19 @source:heathkit/h89.cpp -h89 // +h89 // Heath H89 (H88, Zenith Z-89, Z-90) @source:hec2hrp/hec2hrp.cpp hec2hr //