From 0e62ff6dcd5764e2846fe39ac8cdac9fcbbe01ce Mon Sep 17 00:00:00 2001 From: Mark Garlanger Date: Thu, 28 Nov 2024 11:46:25 -0600 Subject: heathzenith/h89.cpp: Convert SigmaSoft parallel port into an h89 left card. (#13024) --- scripts/src/bus.lua | 14 + src/devices/bus/heathzenith/h19/tlb.cpp | 2032 ++++++++++++++++++++ src/devices/bus/heathzenith/h19/tlb.h | 477 +++++ src/devices/bus/heathzenith/h89/cards.cpp | 2 + src/devices/bus/heathzenith/h89/h89bus.cpp | 81 +- .../heathzenith/h89/sigmasoft_parallel_port.cpp | 245 +++ .../bus/heathzenith/h89/sigmasoft_parallel_port.h | 18 + src/mame/heathzenith/h19.cpp | 2 +- src/mame/heathzenith/h89.cpp | 60 +- src/mame/heathzenith/sigmasoft_parallel_port.cpp | 165 -- src/mame/heathzenith/sigmasoft_parallel_port.h | 67 - src/mame/heathzenith/tlb.cpp | 2032 -------------------- src/mame/heathzenith/tlb.h | 477 ----- 13 files changed, 2828 insertions(+), 2844 deletions(-) create mode 100644 src/devices/bus/heathzenith/h19/tlb.cpp create mode 100644 src/devices/bus/heathzenith/h19/tlb.h create mode 100644 src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.cpp create mode 100644 src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.h delete mode 100644 src/mame/heathzenith/sigmasoft_parallel_port.cpp delete mode 100644 src/mame/heathzenith/sigmasoft_parallel_port.h delete mode 100644 src/mame/heathzenith/tlb.cpp delete mode 100644 src/mame/heathzenith/tlb.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index bfbaffc229e..764abec93ac 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -5765,9 +5765,23 @@ if (BUSES["H89BUS"]~=null) then MAME_DIR .. "src/devices/bus/heathzenith/h89/mms77316_fdc.h", MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_sound.cpp", MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_sound.h", + MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.cpp", + MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.h", MAME_DIR .. "src/devices/bus/heathzenith/h89/we_pullup.cpp", MAME_DIR .. "src/devices/bus/heathzenith/h89/we_pullup.h", MAME_DIR .. "src/devices/bus/heathzenith/h89/z37_fdc.cpp", MAME_DIR .. "src/devices/bus/heathzenith/h89/z37_fdc.h", } end + +--------------------------------------------------- +-- +--@src/devices/bus/heathzenith/h19/tlb.h,BUSES["HEATH_TLB_CONNECTOR"] = true +--------------------------------------------------- + +if (BUSES["HEATH_TLB_CONNECTOR"]~=null) then + files { + MAME_DIR .. "src/devices/bus/heathzenith/h19/tlb.cpp", + MAME_DIR .. "src/devices/bus/heathzenith/h19/tlb.h", + } +end diff --git a/src/devices/bus/heathzenith/h19/tlb.cpp b/src/devices/bus/heathzenith/h19/tlb.cpp new file mode 100644 index 00000000000..10b384b22cb --- /dev/null +++ b/src/devices/bus/heathzenith/h19/tlb.cpp @@ -0,0 +1,2032 @@ +// license:BSD-3-Clause +// copyright-holders:Mark Garlanger +/*************************************************************************** + + Heathkit Terminal Logic Board (TLB) + + The board used in the H19 smart terminal designed and manufactured + by Heath Company. (and the identical Z19 sold by Zenith Data Systems) + This board is also used the Heath's H89 / H88, and ZDS's Z-89 and Z-90. + + The keyboard consists of a 9x10 matrix connected to a MM5740AAC/N + mask-programmed keyboard controller. The output of this passes + through a rom. + + Input can also come from the serial port. + + Known Issues: + - With gp19 + - 49/50 row mode only shows half the screen. + - In 49/50 row mode, character descenders are cut off. + - Screen saver does not disable the screen + - With Superset + - Screensaver freezes the screen instead of blanking the screen + + Not Currently Implemented + - With Imaginator I-100 + - Support for Tektronics Emulation (missing ROM image) + - With SigmaSoft IGC + - Interlace video support (with higher resolution) + - Joystick support + - Centronics support + - Lightpen support + - Alternate Font ROM support (missing ROM image) + - With Super19 + - Interlace video + - Alternate Font19 alt 128 mode and extended 256 mode (missing ROM images) + - ANSI character set selection (missing ROM image) + - light pen support + - With UltraROM + - Interace mode + +****************************************************************************/ +/*************************************************************************** + + Memory Layout + + The U435 three-to-eight line decoder uses A14 and A15 to generate + three memory address spaces: + + Address Description + ---------------------------------------------------- + 0x0000 Program ROM + 0x4000 Scratchpad RAM + 0xF800 (0xC000) Display Memory + + + Port Layout + + Only address lines A5, A6, A7 are used by the U442 three-to-eight + line decoder + + Address Description + ---------------------------------------------------- + 0x00 Power-up configuration (primary - SW401) + 0x20 Power-up configuration (secondary - SW402) + 0x40 INS8250 ACE (communications) + 0x60 MC6845 CRT controller + 0x80 MM5740 Keyboard encoder + 0xA0 Keyboard status + 0xC0 Trigger key click + 0xE0 Trigger bell + +****************************************************************************/ + +#include "emu.h" + +#include "tlb.h" + +#include + +#define LOG_REG (1U << 1) // Shows register setup + +//#define VERBOSE (LOG_REG) + +#include "logmacro.h" + +#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif + +// Clocks +static constexpr XTAL MASTER_CLOCK = XTAL(12'288'000); + +// DOT clocks +static constexpr XTAL BASE_DOT_CLOCK = MASTER_CLOCK; +static constexpr XTAL GP19_DOT_CLOCK_1 = XTAL(20'282'000); // 132 columns +static constexpr XTAL GP19_DOT_CLOCK_2 = XTAL(12'292'000); // 80 columns +static constexpr XTAL GP19_DOT_CLOCK_3 = XTAL(10'644'000); // Graphics mode + +// Standard H19 used a 2.048 MHz clock for Z80 +static constexpr XTAL H19_CLOCK = MASTER_CLOCK / 6; +static constexpr XTAL H19_3MHZ = MASTER_CLOCK / 4; +static constexpr XTAL H19_4MHZ = MASTER_CLOCK / 3; +static constexpr XTAL H19_6MHZ = MASTER_CLOCK / 2; + +static constexpr XTAL INS8250_CLOCK = MASTER_CLOCK / 4; + +// Beep Frequency is 1 KHz +static constexpr XTAL H19_BEEP_FRQ = (H19_CLOCK / 2048); + +// Capacitor value in pF +static constexpr u32 H19_KEY_DEBOUNCE_CAPACITOR = 5000; +static const u32 MM5740_CLOCK = mm5740_device::calc_effective_clock_key_debounce(H19_KEY_DEBOUNCE_CAPACITOR); + +// Keyboard flag masks +static constexpr u8 KB_STATUS_SHIFT_KEYS_MASK = 0x01; +static constexpr u8 KB_STATUS_CONTROL_KEY_MASK = 0x10; +static constexpr u8 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") +DEFINE_DEVICE_TYPE(HEATH_SUPERSET, heath_superset_tlb_device, "heath_superset_tlb", "Heath Terminal Logic Board w/Superset ROM") +DEFINE_DEVICE_TYPE(HEATH_ULTRA, heath_ultra_tlb_device, "heath_ultra_tlb", "Heath Terminal Logic Board w/Ultra ROM") +DEFINE_DEVICE_TYPE(HEATH_WATZ, heath_watz_tlb_device, "heath_watz_tlb", "Heath Terminal Logic Board w/Watzman ROM") +DEFINE_DEVICE_TYPE(HEATH_GP19, heath_gp19_tlb_device, "heath_gp19_tlb", "Heath Terminal Logic Board plus Northwest Digital Systems GP-19") +DEFINE_DEVICE_TYPE(HEATH_IMAGINATOR, heath_imaginator_tlb_device, "heath_imaginator_tlb", "Heath Terminal Logic Board plus Cleveland Codonics Imaginator I-100") + +// Devices for the terminal boards compatible with SigmaSoft IGC +DEFINE_DEVICE_TYPE(HEATH_IGC, heath_igc_tlb_device, "heath_igc_tlb_device", "Heath Terminal Logic Board plus SigmaSoft Interactive Graphics Controller") +DEFINE_DEVICE_TYPE(HEATH_IGC_SUPER19, heath_igc_super19_tlb_device, "heath_igc_super19_tlb_device", "Heath Terminal Logic Board w/ Super19 ROM plus SigmaSoft Interactive Graphics Controller") +DEFINE_DEVICE_TYPE(HEATH_IGC_ULTRA, heath_igc_ultra_tlb_device, "heath_igc_ultra_tlb_device", "Heath Terminal Logic Board w/ Ultra ROM plus SigmaSoft Interactive Graphics Controller") +DEFINE_DEVICE_TYPE(HEATH_IGC_WATZ, heath_igc_watz_tlb_device, "heath_igc_watz_tlb_device", "Heath Terminal Logic Board w/Watzman ROM plus SigmaSoft Interactive Graphics Controller") + + +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())) +{ +} + + +/** + * original Heath H19 functionality + */ +heath_tlb_device::heath_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_TLB, tag, owner, clock) +{ +} + +heath_tlb_device::heath_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 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_config(*this, "CONFIG"), + m_ace(*this, "ins8250"), + m_beep(*this, "beeper"), + m_mm5740(*this, "mm5740"), + m_kbdrom(*this, "keyboard"), + m_kbspecial(*this, "MODIFIERS"), + m_repeat_clock(*this, "repeatclock") +{ +} + +void heath_tlb_device::check_beep_state() +{ + if (!m_key_click_active && !m_bell_active) + { + m_beep->set_state(0); + } +} + +TIMER_CALLBACK_MEMBER(heath_tlb_device::key_click_off) +{ + m_key_click_active = false; + + check_beep_state(); +} + +TIMER_CALLBACK_MEMBER(heath_tlb_device::bell_off) +{ + m_bell_active = false; + + check_beep_state(); +} + +void heath_tlb_device::mem_map(address_map &map) +{ + map.unmap_value_high(); + + // H19 ROM + map(0x0000, 0x0fff).mirror(0x3000).rom(); + + // Scratchpad memory + map(0x4000, 0x40ff).mirror(0x3f00).ram(); + + // Video Memory + map(0xc000, 0xc7ff).mirror(0x3800).ram().share(m_p_videoram); +} + +void heath_tlb_device::io_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xff); + map(0x00, 0x00).mirror(0x1f).portr("SW401"); + map(0x20, 0x20).mirror(0x1f).portr("SW402"); + 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)); + map(0xe0, 0xe0).mirror(0x1f).w(FUNC(heath_tlb_device::bell_w)); +} + +void heath_tlb_device::device_start() +{ + save_item(NAME(m_transchar)); + save_item(NAME(m_strobe)); + save_item(NAME(m_key_click_active)); + save_item(NAME(m_bell_active)); + save_item(NAME(m_reset_pending)); + save_item(NAME(m_right_shift)); + save_item(NAME(m_reset_key)); + save_item(NAME(m_keyboard_irq_raised)); + save_item(NAME(m_serial_irq_raised)); + save_item(NAME(m_break_key_irq_raised)); + save_item(NAME(m_allow_vsync_nmi)); + + m_strobe = false; + m_key_click_active = false; + m_bell_active = false; + m_reset_pending = false; + m_right_shift = false; + m_reset_key = false; + m_keyboard_irq_raised = false; + m_serial_irq_raised = false; + m_break_key_irq_raised = false; + m_allow_vsync_nmi = false; + + m_key_click_timer = timer_alloc(FUNC(heath_tlb_device::key_click_off), this); + m_bell_timer = timer_alloc(FUNC(heath_tlb_device::bell_off), this); + + // Flip bits in font ROM to avoid having to flip them during scan out since some + // boards with graphics has the pixel graphic reversed from the font layout. Doing + // it for all devices for consistency. + for (size_t i = 0; i < m_p_chargen.length(); i++) + { + m_p_chargen[i] = bitswap<8>(m_p_chargen[i], 0, 1, 2, 3, 4, 5, 6, 7); + } +} + +void heath_tlb_device::device_reset() +{ + m_strobe = false; + m_key_click_active = false; + m_bell_active = false; + m_allow_vsync_nmi = false; + + ioport_value const cfg(m_config->read()); + + // CPU clock speed + switch (BIT(cfg, 0, 2)) + { + case 0x01: + m_maincpu->set_clock(H19_3MHZ); + break; + case 0x02: + m_maincpu->set_clock(H19_4MHZ); + break; + case 0x03: + m_maincpu->set_clock(H19_6MHZ); + break; + case 0x00: + default: + // Standard Clock + m_maincpu->set_clock(H19_CLOCK); + break; + } + + // Set screen color + switch (BIT(cfg, 2, 2)) + { + case 0x01: + m_screen->set_color(rgb_t::white()); + break; + case 0x02: + m_screen->set_color(rgb_t::amber()); + break; + case 0x00: + default: + m_screen->set_color(rgb_t::green()); + break; + } +} + +void heath_tlb_device::key_click_w(u8 data) +{ + // Keyclick - 6 mSec + m_beep->set_state(1); + m_key_click_active = true; + m_key_click_timer->adjust(attotime::from_msec(6)); +} + +void heath_tlb_device::bell_w(u8 data) +{ + // Bell (^G) - 200 mSec + m_beep->set_state(1); + m_bell_active = true; + m_bell_timer->adjust(attotime::from_msec(200)); +} + +/** + * MM5740 B Mapping to the ROM address + */ +u16 heath_tlb_device::translate_mm5740_b(u16 b) +{ + return bitswap<9>(b, 7, 6, 8, 5, 4, 3, 2, 1, 0); +} + +u8 heath_tlb_device::kbd_key_r() +{ + 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. + return m_transchar; +} + +u8 heath_tlb_device::kbd_flags_r() +{ + u16 modifiers = m_kbspecial->read(); + u8 rv = modifiers & 0x7e; + + // check both shifts + if ((modifiers & 0x120) != 0x120) + { + rv |= KB_STATUS_SHIFT_KEYS_MASK; + } + + if (!m_strobe) + { + rv |= KB_STATUS_KEYBOARD_STROBE_MASK; + } + + return rv; +} + +int heath_tlb_device::mm5740_shift_r() +{ + return ((m_kbspecial->read() & 0x120) != 0x120) ? 1 : 0; +} + +int heath_tlb_device::mm5740_control_r() +{ + return (m_kbspecial->read() & KB_STATUS_CONTROL_KEY_MASK) ? 0 : 1; +} + +void heath_tlb_device::mm5740_data_ready_w(int state) +{ + if (state) + { + u8 *decode = m_kbdrom->base(); + + m_transchar = decode[translate_mm5740_b(m_mm5740->b_r())]; + m_strobe = true; + m_keyboard_irq_raised = true; + + set_irq_line(); + } +} + +void heath_tlb_device::crtc_addr_w(offs_t reg, u8 val) +{ + m_allow_vsync_nmi = bool(BIT(reg, 2)); + + m_crtc->address_w(val); +} + +u8 heath_tlb_device::crtc_reg_r(offs_t reg) +{ + if (!machine().side_effects_disabled()) + { + m_allow_vsync_nmi = bool(BIT(reg, 2)); + } + + return m_crtc->register_r(); +} + +void heath_tlb_device::crtc_reg_w(offs_t reg, u8 val) +{ + m_allow_vsync_nmi = bool(BIT(reg, 2)); + + m_crtc->register_w(val); +} + +void heath_tlb_device::crtc_vsync_w(int val) +{ + m_maincpu->set_input_line(INPUT_LINE_NMI, m_allow_vsync_nmi ? val : CLEAR_LINE); +} + +void heath_tlb_device::serial_irq_w(int state) +{ + m_serial_irq_raised = bool(state); + + set_irq_line(); +} + +void heath_tlb_device::set_irq_line() +{ + m_maincpu->set_input_line(INPUT_LINE_IRQ0, + (m_keyboard_irq_raised || m_serial_irq_raised || m_break_key_irq_raised) ? + ASSERT_LINE : CLEAR_LINE); +} + +void heath_tlb_device::check_for_reset() +{ + if (m_reset_key && m_right_shift) + { + m_reset_pending = true; + m_slot->reset_out(1); + m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + } + else if (m_reset_pending) + { + m_reset_pending = false; + reset(); + m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + m_slot->reset_out(0); + } +} + +void heath_tlb_device::reset_key_w(int state) +{ + m_reset_key = (state == 0); + + check_for_reset(); +} + +void heath_tlb_device::right_shift_w(int state) +{ + m_right_shift = (state == 0); + + check_for_reset(); +} + +void heath_tlb_device::repeat_key_w(int state) +{ + // when repeat key pressed, set duty cycle to 50%, else 0%. + m_repeat_clock->set_duty_cycle(state == 0 ? 0.5 : 0); +} + +void heath_tlb_device::break_key_w(int state) +{ + m_break_key_irq_raised = (state == 0); + + set_irq_line(); +} + +MC6845_UPDATE_ROW(heath_tlb_device::crtc_update_row) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + + if (de) + { + for (int x = 0; x < x_count; x++) + { + u8 inv = (x == cursor_x) ? 0xff : 0; + u8 chr = m_p_videoram[(ma + x) & 0x7ff]; + + if (chr & 0x80) + { + inv ^= 0xff; + chr &= 0x7f; + } + + // get pattern of pixels for that character scanline + u8 const gfx = m_p_chargen[(chr << 4) | ra] ^ inv; + + // Display a scanline of a character (8 pixels) + for (int b = 0; 8 > b; ++b) + { + *p++ = palette[BIT(gfx, b)]; + } + } + } + else + { + std::fill_n(p, x_count * 8, palette[0]); + } +} + + +// F4 Character Displayer +static const gfx_layout h19_charlayout = +{ + 8, 10, // 8 x 10 characters + 128, // 128 characters + 1, // 1 bits per pixel + { 0 }, // no bitplanes + // x offsets + { 0, 1, 2, 3, 4, 5, 6, 7 }, + // y offsets + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 }, + 8*16 // every char takes 16 bytes +}; + +static GFXDECODE_START( gfx_h19 ) + GFXDECODE_ENTRY("chargen", 0x0000, h19_charlayout, 0, 1) +GFXDECODE_END + + +// Input ports +static INPUT_PORTS_START( tlb ) + + PORT_START("MODIFIERS") + // bit 0 - 0x001 connects to B8 of MM5740 - low if either shift key is + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_PAUSE) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::break_key_w)) + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("OffLine") PORT_CODE(KEYCODE_F12) PORT_TOGGLE + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LeftShift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Repeat") PORT_CODE(KEYCODE_RALT) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::repeat_key_w)) + // bit 7 - 0x080 is low if any key is pressed + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RightShift") PORT_CODE(KEYCODE_RSHIFT) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::right_shift_w)) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F10) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::reset_key_w)) + + PORT_START("X1") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X2") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-.") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-Enter") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) + + 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(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) + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-1 IL") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-2 Down") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-3 DL") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X3") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ ]") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_RWIN) PORT_CHAR(10) + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(127) + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-4 LEFT") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-5 HOME") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-6 RIGHT") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X4") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X1") + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-7 IC") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-8 UP") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-9 DC") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X5") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Blue") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Red") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gray") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X6") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("X7") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll") PORT_CODE(KEYCODE_F11) + + PORT_START("X8") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + + PORT_START("X9") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + + PORT_START("SW401") + PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") + PORT_DIPSETTING( 0x01, "110") + PORT_DIPSETTING( 0x02, "150") + PORT_DIPSETTING( 0x03, "300") + PORT_DIPSETTING( 0x04, "600") + PORT_DIPSETTING( 0x05, "1200") + PORT_DIPSETTING( 0x06, "1800") + PORT_DIPSETTING( 0x07, "2000") + PORT_DIPSETTING( 0x08, "2400") + PORT_DIPSETTING( 0x09, "3600") + PORT_DIPSETTING( 0x0a, "4800") + PORT_DIPSETTING( 0x0b, "7200") + 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( 0x10, "Odd") + 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( 0x40, "Stick") + PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") + PORT_DIPSETTING( 0x00, "Half") + PORT_DIPSETTING( 0x80, "Full") + + PORT_START("SW402") + PORT_DIPNAME( 0x01, 0x00, "Cursor") PORT_DIPLOCATION("SW402:1") + 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_DIPNAME( 0x04, 0x00, "Wrap at EOL") PORT_DIPLOCATION("SW402:3") + 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_DIPNAME( 0x10, 0x00, "Auto CR on LF") PORT_DIPLOCATION("SW402:5") + 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_DIPNAME( 0x80, 0x00, "Refresh") PORT_DIPLOCATION("SW402:8") + PORT_DIPSETTING( 0x00, "60Hz") + PORT_DIPSETTING( 0x80, "50Hz") + + PORT_START("CONFIG") + PORT_CONFNAME(0x03, 0x00, "CPU Clock") + PORT_CONFSETTING( 0x00, "2 MHz") + PORT_CONFSETTING( 0x01, "3 MHz") + PORT_CONFSETTING( 0x02, "4 MHz") + PORT_CONFSETTING( 0x03, "6 MHz") + PORT_CONFNAME(0x0C, 0x00, "CRT Color") + PORT_CONFSETTING( 0x00, "Green") + PORT_CONFSETTING( 0x04, "White") + PORT_CONFSETTING( 0x08, "Amber") +INPUT_PORTS_END + + +static INPUT_PORTS_START( super19 ) + PORT_INCLUDE( tlb ) + + PORT_MODIFY("SW401") + PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") + PORT_DIPSETTING( 0x01, "110") + PORT_DIPSETTING( 0x02, "150") + PORT_DIPSETTING( 0x03, "300") + PORT_DIPSETTING( 0x04, "600") + PORT_DIPSETTING( 0x05, "1200") + PORT_DIPSETTING( 0x06, "1800") + PORT_DIPSETTING( 0x07, "2000") + PORT_DIPSETTING( 0x08, "2400") + PORT_DIPSETTING( 0x09, "3600") + PORT_DIPSETTING( 0x0a, "4800") + PORT_DIPSETTING( 0x0b, "7200") + PORT_DIPSETTING( 0x0c, "9600") + PORT_DIPSETTING( 0x0d, "19200") + PORT_DIPSETTING( 0x0e, "38400") + PORT_DIPNAME( 0x70, 0x00, "8 bit mode") PORT_DIPLOCATION("SW401:5,6,7") + PORT_DIPSETTING( 0x00, "Mode A/0 - 8th bit ignored, sent as 0") + PORT_DIPSETTING( 0x10, "Mode B/1 - 8th bit ignored, sent as 1") + PORT_DIPSETTING( 0x20, "Mode C/2 - 8 bit escape mode") + PORT_DIPSETTING( 0x30, "Mode D/3 - 8 bit escape mode, invert 8th bit") + PORT_DIPSETTING( 0x40, "Mode E/4 - 8 bit data mode") + PORT_DIPSETTING( 0x50, "Mode F/5 - 8 bit data mode, invert 8th bit") + PORT_DIPSETTING( 0x60, "7 bit data with odd parity, 8th bit ignored on input") + PORT_DIPSETTING( 0x70, "7 bit data with even parity, 8th bit ignored on input") + PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") + PORT_DIPSETTING( 0x00, "Half") + PORT_DIPSETTING( 0x80, "Full") + + PORT_MODIFY("SW402") + PORT_DIPNAME( 0x02, 0x00, "Transmit mode") PORT_DIPLOCATION("SW402:2") + PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x02, "Slow") + PORT_DIPNAME( 0x80, 0x00, "DEC Keypad Codes") PORT_DIPLOCATION("SW402:8") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x80, DEF_STR( On ) ) +INPUT_PORTS_END + + +static INPUT_PORTS_START( superset ) + PORT_INCLUDE( tlb ) + + PORT_MODIFY("SW401") + PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") + PORT_DIPSETTING( 0x00, "75") + PORT_DIPSETTING( 0x01, "110") + PORT_DIPSETTING( 0x02, "150") + PORT_DIPSETTING( 0x03, "300") + PORT_DIPSETTING( 0x04, "600") + PORT_DIPSETTING( 0x05, "1200") + PORT_DIPSETTING( 0x06, "1800") + PORT_DIPSETTING( 0x07, "2000") + PORT_DIPSETTING( 0x08, "2400") + PORT_DIPSETTING( 0x09, "3600") + PORT_DIPSETTING( 0x0a, "4800") + PORT_DIPSETTING( 0x0b, "7200") + PORT_DIPSETTING( 0x0c, "9600") + PORT_DIPSETTING( 0x0d, "19200") + PORT_DIPSETTING( 0x0e, "38400") + PORT_DIPSETTING( 0x0f, "134.5") + PORT_DIPNAME( 0x10, 0x10, "Duplex") PORT_DIPLOCATION("SW401:5") + PORT_DIPSETTING( 0x00, "Half") + PORT_DIPSETTING( 0x80, "Full") + PORT_DIPNAME( 0x20, 0x00, "Word Length") PORT_DIPLOCATION("SW401:6") + PORT_DIPSETTING( 0x00, "8-bit" ) + PORT_DIPSETTING( 0x20, "7-bit" ) + PORT_DIPNAME( 0x40, 0x00, "Parity Type") PORT_DIPLOCATION("SW401:7") + PORT_DIPSETTING( 0x00, DEF_STR( None ) ) + PORT_DIPSETTING( 0x40, "Even") + PORT_DIPNAME( 0x80, 0x80, "Parity") PORT_DIPLOCATION("SW401:8") + PORT_DIPSETTING( 0x00, "Disabled") + PORT_DIPSETTING( 0x80, "Enabled") +INPUT_PORTS_END + + +static INPUT_PORTS_START( ultra19 ) + PORT_INCLUDE( tlb ) + + PORT_MODIFY("SW401") + PORT_DIPNAME( 0x07, 0x05, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3") + PORT_DIPSETTING( 0x00, "110") + PORT_DIPSETTING( 0x01, "300") + PORT_DIPSETTING( 0x02, "1200") + PORT_DIPSETTING( 0x03, "2400") + PORT_DIPSETTING( 0x04, "4800") + PORT_DIPSETTING( 0x05, "9600") + PORT_DIPSETTING( 0x06, "19200") + PORT_DIPSETTING( 0x07, "38400") + PORT_DIPNAME( 0x08, 0x00, "Parity") PORT_DIPLOCATION("SW401:4") + PORT_DIPSETTING( 0x00, "Disabled") + PORT_DIPSETTING( 0x08, "Enabled") + PORT_DIPNAME( 0x10, 0x00, "Parity Type") PORT_DIPLOCATION("SW401:5") + PORT_DIPSETTING( 0x00, "Odd") + PORT_DIPSETTING( 0x10, "Even") + PORT_DIPNAME( 0x20, 0x00, "Data Size") PORT_DIPLOCATION("SW401:6") + PORT_DIPSETTING( 0x00, "8-bit") + PORT_DIPSETTING( 0x20, "7-bit") + PORT_DIPNAME( 0x40, 0x40, "Duplex") PORT_DIPLOCATION("SW401:7") + PORT_DIPSETTING( 0x00, "Half") + PORT_DIPSETTING( 0x40, "Full") + PORT_DIPNAME( 0x80, 0x80, "Software Handshaking") PORT_DIPLOCATION("SW401:8") + PORT_DIPSETTING( 0x00, "Enabled") + PORT_DIPSETTING( 0x80, "Disabled") + + 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_DIPNAME( 0x10, 0x00, "Default Key Values") PORT_DIPLOCATION("SW402:5") + PORT_DIPSETTING( 0x00, "HDOS Values") + PORT_DIPSETTING( 0x10, "CP/M Values") + PORT_DIPNAME( 0x60, 0x60, "Cursor Blink") PORT_DIPLOCATION("SW402:6,7") + PORT_DIPSETTING( 0x00, "Steady") + PORT_DIPSETTING( 0x20, "Invisible") + PORT_DIPSETTING( 0x40, "Fast Blink") + PORT_DIPSETTING( 0x60, "Slow Blink") + PORT_DIPNAME( 0x80, 0x00, "Interlace Scan Mode") PORT_DIPLOCATION("SW402:8") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x80, DEF_STR( On ) ) +INPUT_PORTS_END + + +static INPUT_PORTS_START( watz19 ) + PORT_INCLUDE( tlb ) + + PORT_MODIFY("SW401") + PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") + PORT_DIPSETTING( 0x00, "75") + PORT_DIPSETTING( 0x01, "110") + PORT_DIPSETTING( 0x02, "150") + PORT_DIPSETTING( 0x03, "300") + PORT_DIPSETTING( 0x04, "600") + PORT_DIPSETTING( 0x05, "1200") + PORT_DIPSETTING( 0x06, "1800") + PORT_DIPSETTING( 0x07, "2000") + PORT_DIPSETTING( 0x08, "2400") + PORT_DIPSETTING( 0x09, "3600") + PORT_DIPSETTING( 0x0a, "4800") + PORT_DIPSETTING( 0x0b, "7200") + PORT_DIPSETTING( 0x0c, "9600") + PORT_DIPSETTING( 0x0d, "19200") + PORT_DIPSETTING( 0x0e, "38400") + PORT_DIPSETTING( 0x0f, "134.5") + PORT_DIPNAME( 0x40, 0x00, "Word Size") PORT_DIPLOCATION("SW401:7") + PORT_DIPSETTING( 0x00, "8-bit Word") + PORT_DIPSETTING( 0x40, "7-bit Word") + PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") + PORT_DIPSETTING( 0x00, "Half") + PORT_DIPSETTING( 0x80, "Full") +INPUT_PORTS_END + + +static INPUT_PORTS_START( gp19 ) + PORT_INCLUDE( tlb ) + + PORT_MODIFY("SW402") + PORT_DIPNAME( 0x80, 0x00, "Automatic Holdscreen") PORT_DIPLOCATION("SW402:8") + PORT_DIPSETTING( 0x00, "Disabled (VT100 mode)") + PORT_DIPSETTING( 0x80, "Enabled (Z19 mode)") + + PORT_START("SW1") + PORT_DIPNAME( 0x03, 0x01, "Trailing Characters for Tektronix Message") PORT_DIPLOCATION("SW1:1,2") + PORT_DIPSETTING( 0x00, DEF_STR( None ) ) + PORT_DIPSETTING( 0x01, "CR") + PORT_DIPSETTING( 0x02, DEF_STR( None ) ) + PORT_DIPSETTING( 0x03, "CR,EOT") + PORT_DIPNAME( 0x04, 0x01, "Shift Key") PORT_DIPLOCATION("SW1:3") + 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") + PORT_DIPSETTING( 0x08, "One character per 16.7 msec") + PORT_DIPNAME( 0x10, 0x10, "Character Set") PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING( 0x00, "VT100") + PORT_DIPSETTING( 0x10, "Zenith") + PORT_DIPNAME( 0x20, 0x00, "ANSI Mode") PORT_DIPLOCATION("SW1:6") + PORT_DIPSETTING( 0x00, "Zenith ANSI") + PORT_DIPSETTING( 0x20, "EDT compatible") + PORT_DIPNAME( 0x40, 0x00, "Tektronix Character Wrap") PORT_DIPLOCATION("SW1:7") + PORT_DIPSETTING( 0x00, "Column 74") + PORT_DIPSETTING( 0x40, "Column 73") + PORT_DIPNAME( 0x80, 0x00, "Blank Screen") PORT_DIPLOCATION("SW1:8") + PORT_DIPSETTING( 0x00, "After 10 mins") + PORT_DIPSETTING( 0x80, "Never") +INPUT_PORTS_END + + +ROM_START( h19 ) + // Original terminal code + ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "2732_444-46_h19code.u437", 0x0000, 0x1000, CRC(f4447da0) SHA1(fb4093d5b763be21a9580a0defebed664b1f7a7b)) + + // Original font + ROM_REGION( 0x0800, "chargen", 0 ) + ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) + + // Original keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) +ROM_END + +ROM_START( super19 ) + // Super-19 ROM + ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "2732_super19_h447.u437", 0x0000, 0x1000, CRC(6c51aaa6) SHA1(5e368b39fe2f1af44a905dc474663198ab630117)) + + // Original font + ROM_REGION( 0x0800, "chargen", 0 ) + ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) + + // Original keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) +ROM_END + +ROM_START( superset ) + // SuperSet ROM + ROM_REGION( 0x4000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "27256_101-402_superset_code.u437", 0x0000, 0x2000, CRC(a6896076) SHA1(a4e2d25028dc75a665c3f5a830a4e8cdecbd481c)) + // 1st 8k is unused, so overwrite it, with the next 16k (but only first 8k is valid) + ROM_CONTINUE(0x0000, 0x4000) + // overwrite at 8k starting address with the last 8k of the chip. + ROM_CONTINUE(0x2000, 0x2000) + + // Superset SUPERFONT + ROM_REGION( 0x8000, "chargen", 0 ) + ROM_LOAD( "27256_101-431_superset_font.u420", 0x0000, 0x8000, CRC(4c0688f6) SHA1(be6059913420ad66f5c839d619fdcb164ffae85a)) + + // Superset Keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "2716_101-422_superset_kbd.u445", 0x0000, 0x0800, CRC(549d15b3) SHA1(981962e5e05bbdc5a66b0e86870853ce5596e877)) +ROM_END + +ROM_START( watz19 ) + ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) + ROM_DEFAULT_BIOS("watzman-a") + + // Watzman ROM + ROM_SYSTEM_BIOS(0, "watzman", "Watzman") + ROMX_LOAD("watzman.u437", 0x0000, 0x1000, CRC(8168b6dc) SHA1(bfaebb9d766edbe545d24bc2b6630be4f3aa0ce9), ROM_BIOS(0)) + + ROM_SYSTEM_BIOS(1, "watzman-a", "Watzman w/clock persists after reset") + ROMX_LOAD("watzman-a.u437", 0x0000, 0x1000, CRC(1f7553e9) SHA1(ac6ddb12b4fb46c1a0ad08ee43978ad3153b51aa), ROM_BIOS(1)) + + // Original font + ROM_REGION( 0x0800, "chargen", 0 ) + ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) + + // Watzman keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "keybd.u445", 0x0000, 0x0800, CRC(58dc8217) SHA1(1b23705290bdf9fc6342065c6a528c04bff67b13)) +ROM_END + +ROM_START( ultra19 ) + // Ultra ROM + ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "2532_h19_ultra_firmware.u437", 0x0000, 0x1000, CRC(8ad4cdb4) SHA1(d6e1fc37a1f52abfce5e9adb1819e0030bed1df3)) + + // Original font + ROM_REGION( 0x0800, "chargen", 0 ) + ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) + + // Ultra keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "2716_h19_ultra_keyboard.u445", 0x0000, 0x0800, CRC(76130c92) SHA1(ca39c602af48505139d2750a084b5f8f0e662ff7)) +ROM_END + +ROM_START( gp19 ) + // GP-19 ROMs + ROM_REGION( 0x3000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "gp19_rom_1_ver_1_1.u26", 0x0000, 0x1000, CRC(7cbe8e0d) SHA1(977df895b067fa4e4646b4518cffb08d4e6bb6e0)) + ROM_LOAD( "gp19_rom_2_ver_1_1.u25", 0x1000, 0x1000, CRC(a85e3bc4) SHA1(f64e851c5d3ef98a9a48e0fc482baa576773ff43)) + ROM_LOAD( "gp19_rom_3_ver_1_1.u24", 0x2000, 0x1000, CRC(878f577c) SHA1(0756435914dcfb981de4e40d5f81af3e0f5bb1c5)) + + // GP-19 font + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD( "gp19_char_gen_cg_1.u21", 0x0000, 0x1000, CRC(49ec9242) SHA1(770a8c7b5b15bcfe465fd84326d0ae3dcaa85311)) + + // Original keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) +ROM_END + +ROM_START( imaginator ) + // Program code + ROM_REGION( 0x4000, "maincpu", ROMREGION_ERASEFF ) + // Original terminal code + ROM_LOAD( "2732_444-46_h19code.u437", 0x0000, 0x1000, CRC(f4447da0) SHA1(fb4093d5b763be21a9580a0defebed664b1f7a7b)) + // Imaginator ROMs + ROM_LOAD( "2732_imaginator_gpc_rev_1.2_pn_9000_0002.u9a", 0x2000, 0x1000, CRC(507bb13f) SHA1(5b210f8d77e22fdf063f611eb5c29636cdb01250)) + + // Original font + ROM_REGION( 0x0800, "chargen", 0 ) + ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) + + // Original keyboard + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) +ROM_END + + +ioport_constructor heath_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tlb); +} + +const tiny_rom_entry *heath_tlb_device::device_rom_region() const +{ + return ROM_NAME(h19); +} + +void heath_tlb_device::serial_out_b(int data) +{ + m_slot->serial_out_b(data); +} + +void heath_tlb_device::dtr_out(int data) +{ + m_slot->dtr_out(data); +} + +void heath_tlb_device::rts_out(int data) +{ + m_slot->rts_out(data); +} + +void heath_tlb_device::serial_in_w(int state) +{ + m_ace->rx_w(state); +} + +void heath_tlb_device::rlsd_in_w(int state) +{ + m_ace->dcd_w(state); +} + +void heath_tlb_device::dsr_in_w(int state) +{ + m_ace->dsr_w(state); +} + +void heath_tlb_device::cts_in_w(int state) +{ + m_ace->cts_w(state); +} + +void heath_tlb_device::device_add_mconfig(machine_config &config) +{ + // basic machine hardware + Z80(config, m_maincpu, H19_CLOCK); + m_maincpu->set_addrmap(AS_PROGRAM, &heath_tlb_device::mem_map); + m_maincpu->set_addrmap(AS_IO, &heath_tlb_device::io_map); + + // video hardware + SCREEN(config, m_screen, SCREEN_TYPE_RASTER, rgb_t::green()); + // based on the H19 ROM code for 60 Hz + m_screen->set_raw(BASE_DOT_CLOCK, 768, 32, 672, 270, 0, 250); + m_screen->set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + GFXDECODE(config, "gfxdecode", m_palette, gfx_h19); + PALETTE(config, "palette", palette_device::MONOCHROME); + + // MC 6845 uses a character clock, divide the DOT clock by 8. + MC6845(config, m_crtc, BASE_DOT_CLOCK / 8); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(heath_tlb_device::crtc_update_row)); + // frame pulse + m_crtc->out_vsync_callback().set(FUNC(heath_tlb_device::crtc_vsync_w)); + + // serial port + INS8250(config, m_ace, INS8250_CLOCK); + m_ace->out_int_callback().set(FUNC(heath_tlb_device::serial_irq_w)); + m_ace->out_tx_callback().set(FUNC(heath_tlb_device::serial_out_b)); + m_ace->out_dtr_callback().set(FUNC(heath_tlb_device::dtr_out)); + m_ace->out_rts_callback().set(FUNC(heath_tlb_device::rts_out)); + + // keyboard + MM5740(config, m_mm5740, MM5740_CLOCK); + m_mm5740->x_cb<1>().set_ioport("X1"); + m_mm5740->x_cb<2>().set_ioport("X2"); + m_mm5740->x_cb<3>().set_ioport("X3"); + m_mm5740->x_cb<4>().set_ioport("X4"); + m_mm5740->x_cb<5>().set_ioport("X5"); + m_mm5740->x_cb<6>().set_ioport("X6"); + m_mm5740->x_cb<7>().set_ioport("X7"); + m_mm5740->x_cb<8>().set_ioport("X8"); + m_mm5740->x_cb<9>().set_ioport("X9"); + m_mm5740->shift_cb().set(FUNC(heath_tlb_device::mm5740_shift_r)); + m_mm5740->control_cb().set(FUNC(heath_tlb_device::mm5740_control_r)); + m_mm5740->data_ready_cb().set(FUNC(heath_tlb_device::mm5740_data_ready_w)); + + // sound hardware + SPEAKER(config, "mono").front_center(); + BEEP(config, m_beep, H19_BEEP_FRQ).add_route(ALL_OUTPUTS, "mono", 0.05); + + // clock for repeat key + CLOCK(config, m_repeat_clock, 40); + m_repeat_clock->set_duty_cycle(0); + m_repeat_clock->signal_handler().set(m_mm5740, FUNC(mm5740_device::repeat_line_w)); +} + + +/** + * Super-19 ROM + * + * Developed by ATG Systems + */ +heath_super19_tlb_device::heath_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_SUPER19, tag, owner, clock) +{ +} + +const tiny_rom_entry *heath_super19_tlb_device::device_rom_region() const +{ + return ROM_NAME(super19); +} + +ioport_constructor heath_super19_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(super19); +} + + +/** + * Superset ROM + * + * Developed by TMSI + */ +heath_superset_tlb_device::heath_superset_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_SUPERSET, tag, owner, clock), + m_selected_char_set(0) +{ +} + +void heath_superset_tlb_device::device_add_mconfig(machine_config &config) +{ + heath_tlb_device::device_add_mconfig(config); + + // part of the Superset upgrade was to upgrade the CPU to 3 MHz. + m_maincpu->set_clock(H19_3MHZ); + m_maincpu->set_addrmap(AS_PROGRAM, &heath_superset_tlb_device::mem_map); + m_maincpu->set_addrmap(AS_IO, &heath_superset_tlb_device::io_map); + + // per line updates are needed for onscreen menu to display properly + m_screen->set_video_attributes(VIDEO_UPDATE_SCANLINE); + + m_crtc->set_update_row_callback(FUNC(heath_superset_tlb_device::crtc_update_row)); + + // link up the serial port outputs to font chip. + m_ace->out_dtr_callback().set(FUNC(heath_superset_tlb_device::dtr_internal)); + m_ace->out_out1_callback().set(FUNC(heath_superset_tlb_device::out1_internal)); + m_ace->out_out2_callback().set(FUNC(heath_superset_tlb_device::out2_internal)); +} + +void heath_superset_tlb_device::device_start() +{ + heath_tlb_device::device_start(); + + save_item(NAME(m_selected_char_set)); + + m_selected_char_set = 0; +} + +void heath_superset_tlb_device::mem_map(address_map &map) +{ + heath_tlb_device::mem_map(map); + + // update rom space for the 16k ROM. + map(0x0000, 0x3fff).rom(); + + // page 2 memory + map(0x8000, 0x87ff).ram(); +} + +void heath_superset_tlb_device::io_map(address_map &map) +{ + heath_tlb_device::io_map(map); + + map(0x61, 0x61).mirror(0x12).select(0x0c).rw(FUNC(heath_superset_tlb_device::crtc_reg_r), FUNC(heath_superset_tlb_device::crtc_reg_w)); +} + +const tiny_rom_entry *heath_superset_tlb_device::device_rom_region() const +{ + return ROM_NAME(superset); +} + +ioport_constructor heath_superset_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(superset); +} + +u8 heath_superset_tlb_device::crtc_reg_r(offs_t reg) +{ + if (!machine().side_effects_disabled()) + { + m_reverse_video_disabled = bool(BIT(reg, 3)); + } + + return heath_tlb_device::crtc_reg_r(reg); +} + +void heath_superset_tlb_device::crtc_reg_w(offs_t reg, u8 val) +{ + m_reverse_video_disabled = bool(BIT(reg, 3)); + + heath_tlb_device::crtc_reg_w(reg, val); +} + +MC6845_UPDATE_ROW(heath_superset_tlb_device::crtc_update_row) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + + if (de) + { + for (int x = 0; x < x_count; x++) + { + u8 inv = (x == cursor_x) ? 0xff : 0; + u8 chr = m_p_videoram[(ma + x) & 0x7ff]; + u16 char_set_base_offset = (m_selected_char_set << 11); + + if (chr & 0x80) + { + if (m_reverse_video_disabled) + { + // set A13 + char_set_base_offset |= 0x2000; + } + else + { + inv ^= 0xff; + } + + chr &= 0x7f; + } + + // get pattern of pixels for the character scanline + u8 const gfx = m_p_chargen[char_set_base_offset | (chr << 4) | ra] ^ inv; + + // Display a scanline of a character (8 pixels) + for (int b = 0; 8 > b; ++b) + { + *p++ = palette[BIT(gfx, b)]; + } + } + } + else + { + std::fill_n(p, bitmap.rowpixels(), palette[0]); + } +} + +// DTR (pin 33) to A14 (pin 27) of 27256 ROM +void heath_superset_tlb_device::dtr_internal(int data) +{ + m_selected_char_set = (m_selected_char_set & 0x03) | ((data & 0x01) << 3); +} + +// OUT1 (pin 34) to A12 (pin 2) of 27256 ROM +void heath_superset_tlb_device::out1_internal(int data) +{ + m_selected_char_set = (m_selected_char_set & 0x09) | ((data & 0x01) << 1); +} + +// OUT2 (pin 31) to A11? on board +void heath_superset_tlb_device::out2_internal(int data) +{ + m_selected_char_set = (m_selected_char_set & 0x0a) | (data & 0x01); +} + + +/** + * Watzman ROM + * + * Developed by Barry Watzman, sold by HUG (Heath Users Group) +*/ +heath_watz_tlb_device::heath_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_WATZ, tag, owner, clock) +{ +} + +const tiny_rom_entry *heath_watz_tlb_device::device_rom_region() const +{ + return ROM_NAME(watz19); +} + +ioport_constructor heath_watz_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(watz19); +} + + +/** + * UltraROM + * + * Developed by William G. Parrott, III, sold by Software Wizardry, Inc. + */ +heath_ultra_tlb_device::heath_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_ULTRA, tag, owner, clock) +{ +} + +void heath_ultra_tlb_device::device_add_mconfig(machine_config &config) +{ + heath_tlb_device::device_add_mconfig(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &heath_ultra_tlb_device::mem_map); +} + +void heath_ultra_tlb_device::mem_map(address_map &map) +{ + heath_tlb_device::mem_map(map); + + // update rom mirror setting to allow page 2 memory + map(0x0000, 0x0fff).mirror(0x2000).rom(); + + // Page 2 memory + map(0x1000, 0x1fff).mirror(0x2000).ram(); +} + +const tiny_rom_entry *heath_ultra_tlb_device::device_rom_region() const +{ + return ROM_NAME(ultra19); +} + +ioport_constructor heath_ultra_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(ultra19); +} + + +/** + * Northwest Digital Systems GP-19 add-in board + */ +heath_gp19_tlb_device::heath_gp19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_GP19, tag, owner, clock) +{ +} + +void heath_gp19_tlb_device::device_add_mconfig(machine_config &config) +{ + heath_tlb_device::device_add_mconfig(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &heath_gp19_tlb_device::mem_map); + m_maincpu->set_addrmap(AS_IO, &heath_gp19_tlb_device::io_map); + + m_crtc->set_update_row_callback(FUNC(heath_gp19_tlb_device::crtc_update_row)); + m_crtc->set_clock(GP19_DOT_CLOCK_2 / 8); + + m_screen->set_raw(GP19_DOT_CLOCK_2, 776, 32, 672, 264, 10, 250); +} + +void heath_gp19_tlb_device::device_start() +{ + heath_tlb_device::device_start(); + + save_item(NAME(m_char_gen_a11)); + save_item(NAME(m_graphic_mode)); + save_item(NAME(m_col_132)); + save_item(NAME(m_reverse_video)); + + m_char_gen_a11 = false; + m_graphic_mode = false; + m_col_132 = false; + m_reverse_video = false; +} + +void heath_gp19_tlb_device::mem_map(address_map &map) +{ + // ROMs 1, 2, 3 + map(0x0000, 0x02fff).rom(); + + // Optional external board - Program ROM 4(not aware if any ever existed), external I/O + // map(0x3000, 0x03fff).rom(); + + map(0x4000, 0x40ff).mirror(0x3f00).ram(); + map(0x6000, 0x67ff).mirror(0x1800).ram(); + map(0x8000, 0xbfff).mirror(0x4000).ram().share(m_p_videoram); +} + +void heath_gp19_tlb_device::io_map(address_map &map) +{ + heath_tlb_device::io_map(map); + + // Latch U5 + map(0x68, 0x68).mirror(0x07).w(FUNC(heath_gp19_tlb_device::latch_u5_w)); + + // Switch on GP-19 board + map(0x70, 0x70).mirror(0x07).portr("SW1"); + + // Optional Auxiliary I/O connector(not aware if any ever existed) + // map(0x78, 0x78).mirror(0x07); +} + +/** + * U5 Latch + * + * Q0 Graph/character H + * Q1 132/80 columns H + * Q2 Reverse Screen H + * Q3 Alt Character L + * Q4-Q7 LED indicators (debug LEDs on circuit board) + */ +void heath_gp19_tlb_device::latch_u5_w(u8 data) +{ + m_graphic_mode = bool(BIT(data, 0)); + m_col_132 = bool(BIT(data, 1)); + m_reverse_video = bool(BIT(data, 2)); + m_char_gen_a11 = bool(BIT(data, 3)); + + // TODO handle LED indicators + + if (m_graphic_mode) + { + m_crtc->set_clock(GP19_DOT_CLOCK_3 / 8); + } + else if (m_col_132) + { + m_crtc->set_clock(GP19_DOT_CLOCK_1 / 8); + } + else + { + m_crtc->set_clock(GP19_DOT_CLOCK_2 / 8); + } +} + +MC6845_UPDATE_ROW(heath_gp19_tlb_device::crtc_update_row) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + + if (de) + { + u8 screen_inv = m_reverse_video ? 0xff : 0x00; + + if (m_graphic_mode) + { + for (int x = 0; x < x_count; x++) + { + u8 const gfx = m_p_videoram[((ma << 1) + (ra * x_count) + x) & 0x3fff] ^ screen_inv; + + for (int b = 0; 8 > b; ++b) + { + *p++ = palette[BIT(gfx, b)]; + } + } + } + else + { + u16 const base = m_char_gen_a11 ? 0x800 : 0x0; + + for (int x = 0; x < x_count; x++) + { + u8 inv = (x == cursor_x) ? 0xff : 0; + u8 chr = m_p_videoram[(ma + x) & 0x3fff]; + + if (chr & 0x80) + { + inv ^= 0xff; + chr &= 0x7f; + } + + inv ^= screen_inv; + + // select proper character set + u8 const gfx = m_p_chargen[base | (chr << 4) | ra] ^ inv; + + // Display a scanline of a character (8 pixels) + for (int b = 0; 8 > b; ++b) + { + *p++ = palette[BIT(gfx, b)]; + } + } + } + } + else + { + std::fill_n(p, x_count * 8, palette[0]); + } +} + +const tiny_rom_entry *heath_gp19_tlb_device::device_rom_region() const +{ + return ROM_NAME(gp19); +} + +ioport_constructor heath_gp19_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(gp19); +} + + +/** + * Cleveland Codonics Imaginator-100 (I-100) add-in board + * + * Memory Range Description + * ----------------------------------------------------------------- + * 0x0000-0x1fff Program ROM (Heath TLB board) + * 0x2000-0x3fff Graphics Command Processor(GCP) ROM (I-100) + * 0x4000-0x5fff Scratchpad RAM (Heath TLB board) + * 0x6000-0x7fff Graphics Scratchpad R/W RAM (I-100) + * 0x8000-0xbfff Graphics Display R/W RAM(I-100) + * 0xc000-0xdfff Optional Graphics Command Processor memory (I-100) + * 0xe000-0xffff Display Memory (Heath TLB board) + * + * New interrupt source + * - horizontal retrace interrupt + * + */ +heath_imaginator_tlb_device::heath_imaginator_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_IMAGINATOR, tag, owner, clock), + m_mem_bank(*this, "membank"), + m_p_graphic_ram(*this, "graphicram") +{ +} + +void heath_imaginator_tlb_device::device_add_mconfig(machine_config &config) +{ + heath_tlb_device::device_add_mconfig(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &heath_imaginator_tlb_device::mem_map); + m_maincpu->set_addrmap(AS_IO, &heath_imaginator_tlb_device::io_map); + m_maincpu->set_irq_acknowledge_callback(FUNC(heath_imaginator_tlb_device::irq_ack_cb)); + + m_crtc->out_hsync_callback().set(FUNC(heath_imaginator_tlb_device::crtc_hsync_w)); +} + +void heath_imaginator_tlb_device::device_start() +{ + heath_tlb_device::device_start(); + + save_item(NAME(m_im2_val)); + save_item(NAME(m_alphanumeric_mode_active)); + save_item(NAME(m_graphics_mode_active)); + save_item(NAME(m_allow_tlb_interrupts)); + save_item(NAME(m_allow_imaginator_interrupts)); + save_item(NAME(m_hsync_irq_raised)); + + m_mem_bank->configure_entries(0, 2, memregion("maincpu")->base(), 0x2000); + + m_maincpu->space(AS_PROGRAM).install_readwrite_tap(0x8000, 0xbfff, "irq_update", + [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_8000h(); } }, + [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_8000h(); } }); +} + +void heath_imaginator_tlb_device::device_reset() +{ + heath_tlb_device::device_reset(); + + m_mem_bank->set_entry(1); + m_tap_6000h.remove(); + m_tap_6000h = m_maincpu->space(AS_PROGRAM).install_readwrite_tap(0x6000, 0x7fff, "mem_map_update", + [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_6000h(); } }, + [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_6000h(); } }); + + m_alphanumeric_mode_active = true; + m_graphics_mode_active = false; + + m_hsync_irq_raised = false; + + allow_tlb_intr(); +} + +void heath_imaginator_tlb_device::mem_map(address_map &map) +{ + map.unmap_value_high(); + + map(0x0000, 0x1fff).bankr(m_mem_bank); + + // Normal spot of the GCP ROM + map(0x2000, 0x3fff).rom(); + + // TLB Scratchpad + map(0x4000, 0x40ff).mirror(0x1f00).ram(); + + // GCP Scratchpad + map(0x6000, 0x607f).mirror(0x1f80).ram(); + + // Graphics RAM + map(0x8000, 0xbfff).ram().share(m_p_graphic_ram); + + // optional Graphics Command Processor (GCP) + // map(0xc000, 0xdfff); + + // Alphanumeric RAM + map(0xe000, 0xe7ff).mirror(0x1800).ram().share(m_p_videoram); +} + +void heath_imaginator_tlb_device::tap_6000h() +{ + m_mem_bank->set_entry(0); + m_tap_6000h.remove(); +} + +void heath_imaginator_tlb_device::tap_8000h() +{ + if (!m_allow_tlb_interrupts) + { + allow_tlb_intr(); + + set_irq_line(); + } +} + +void heath_imaginator_tlb_device::allow_tlb_intr() +{ + m_allow_tlb_interrupts = true; + m_allow_imaginator_interrupts = false; + m_im2_val = 0x02; +} + +void heath_imaginator_tlb_device::allow_hsync_intr() +{ + m_allow_tlb_interrupts = false; + m_allow_imaginator_interrupts = true; + m_im2_val = 0x00; +} + +/** + * An input/output request (IORQ) is sent to the TERMINAL LOGIC board only when + * both IORQ (pin 20 of U7) AND A4 are low. + */ +void heath_imaginator_tlb_device::io_map(address_map &map) +{ + heath_tlb_device::io_map(map); + + // interrupt routing + map(0x10, 0x10).select(0x08).mirror(0x07).w(FUNC(heath_imaginator_tlb_device::config_irq_w)); + + // display enabling (graphics or alphanumeric) + map(0x30, 0x30).select(0xc0).mirror(0x0f).w(FUNC(heath_imaginator_tlb_device::display_enable_w)); + + // Avoids writes to TLB when a4 is high on unused + map(0x50, 0x50).select(0x80).mirror(0x0f).w(FUNC(heath_imaginator_tlb_device::nop_w)); +} + +IRQ_CALLBACK_MEMBER(heath_imaginator_tlb_device::irq_ack_cb) +{ + return m_im2_val; +} + +void heath_imaginator_tlb_device::config_irq_w(offs_t reg, u8 val) +{ + if (BIT(reg, 3)) + { + allow_tlb_intr(); + } + else + { + allow_hsync_intr(); + } + + set_irq_line(); +} + +void heath_imaginator_tlb_device::display_enable_w(offs_t reg, u8 val) +{ + m_alphanumeric_mode_active = bool(BIT(reg, 7)); + m_graphics_mode_active = bool(BIT(reg, 6)); +} + +void heath_imaginator_tlb_device::nop_w(offs_t, u8) +{ +} + +const tiny_rom_entry *heath_imaginator_tlb_device::device_rom_region() const +{ + return ROM_NAME(imaginator); +} + +MC6845_UPDATE_ROW(heath_imaginator_tlb_device::crtc_update_row) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + + if (de) + { + for (int x = 0; x < x_count; x++) + { + u8 output = 0x00; + + if (m_alphanumeric_mode_active) + { + u8 inv = (x == cursor_x) ? 0xff : 0; + u8 chr = m_p_videoram[(ma + x) & 0x7ff]; + + if (chr & 0x80) + { + inv ^= 0xff; + chr &= 0x7f; + } + + output |= m_p_chargen[(chr << 4) | ra] ^ inv; + } + + if (m_graphics_mode_active && (x > 7 ) && (x < 73)) + { + output |= m_p_graphic_ram[((y * 64) + (x - 8)) & 0x3fff]; + } + + for (int b = 0; 8 > b; ++b) + { + *p++ = palette[BIT(output, b)]; + } + } + } + else + { + std::fill_n(p, x_count * 8, palette[0]); + } +} + +void heath_imaginator_tlb_device::crtc_hsync_w(int val) +{ + m_hsync_irq_raised = bool(val); + + set_irq_line(); +} + +void heath_imaginator_tlb_device::set_irq_line() +{ + m_maincpu->set_input_line(INPUT_LINE_IRQ0, + (m_allow_imaginator_interrupts && m_hsync_irq_raised) || + (m_allow_tlb_interrupts && (m_keyboard_irq_raised || m_serial_irq_raised || m_break_key_irq_raised)) ? + ASSERT_LINE : CLEAR_LINE); +} + + +/** + * SigmaSoft Interactive Graphics Controller (IGC) + * + * + */ +heath_igc_tlb_device::heath_igc_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, HEATH_IGC, tag, owner, clock) +{ +} + +heath_igc_tlb_device::heath_igc_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + heath_tlb_device(mconfig, type, tag, owner, clock) +{ +} + +void heath_igc_tlb_device::device_add_mconfig(machine_config &config) +{ + heath_tlb_device::device_add_mconfig(config); + + m_crtc->set_update_row_callback(FUNC(heath_igc_tlb_device::crtc_update_row)); +} + +void heath_igc_tlb_device::device_start() +{ + heath_tlb_device::device_start(); + + m_p_graphic_ram = make_unique_clear(0x3ffff); + save_pointer(NAME(m_p_graphic_ram), 0x3ffff); + + save_item(NAME(m_data_reg)); + save_item(NAME(m_pixel_video_enabled)); + save_item(NAME(m_character_video_disabled)); + save_item(NAME(m_video_invert_enabled)); + save_item(NAME(m_alternate_character_set_enabled)); + save_item(NAME(m_video_fill_enabled)); + save_item(NAME(m_read_address_increment_disabled)); + save_item(NAME(m_memory_bank_select)); + save_item(NAME(m_io_address)); + save_item(NAME(m_window_address)); +} + +void heath_igc_tlb_device::device_reset() +{ + heath_tlb_device::device_reset(); + + sigma_ctrl_w(0); + m_data_reg = 0x00; + m_io_address = 0x0000; + m_window_address = 0x0000; +} + +void heath_igc_tlb_device::sigma_ctrl_w(u8 data) +{ + LOGREG("%s: data: %02x\n", FUNCNAME, data); + + m_pixel_video_enabled = bool(BIT(data, 0)); + m_character_video_disabled = bool(BIT(data, 1)); + m_video_invert_enabled = bool(BIT(data, 2)); + m_alternate_character_set_enabled = bool(BIT(data, 3)); + m_video_fill_enabled = bool(BIT(data, 4)); + m_read_address_increment_disabled = bool(BIT(data, 5)); + + m_memory_bank_select = bitswap<2>(data, 6, 7); + + if (m_video_fill_enabled) + { + std::fill_n(&m_p_graphic_ram[(m_memory_bank_select << 16) & 0x3ffff], 0x10000, m_data_reg); + } +} + +u8 heath_igc_tlb_device::sigma_ctrl_r() +{ + u8 ret_val = 0x00; + + ret_val |= m_pixel_video_enabled ? 0x01 : 0x00; + ret_val |= m_character_video_disabled ? 0x02 : 0x00; + ret_val |= m_video_invert_enabled ? 0x04 : 0x00; + ret_val |= m_alternate_character_set_enabled ? 0x08 : 0x00; + ret_val |= m_video_fill_enabled ? 0x10 : 0x00; + ret_val |= m_read_address_increment_disabled ? 0x20 : 0x00; + + ret_val |= bitswap<2>(m_memory_bank_select, 0, 1) << 6; + + LOGREG("%s: ret_val: %02x\n", FUNCNAME, ret_val); + + return ret_val; +} + +void heath_igc_tlb_device::sigma_video_mem_w(u8 data) +{ + LOGREG("%s: data: %02x\n", FUNCNAME, data); + + m_data_reg = data; + + m_p_graphic_ram[(m_memory_bank_select << 16) + m_io_address++] = data; +} + +u8 heath_igc_tlb_device::sigma_video_mem_r() +{ + // control whether m_io_address is incremented during a read + u32 addr = (m_read_address_increment_disabled || machine().side_effects_disabled()) ? + ((m_memory_bank_select << 16) + m_io_address) : + ((m_memory_bank_select << 16) + m_io_address++); + + return m_p_graphic_ram[addr]; +} + +void heath_igc_tlb_device::sigma_io_lo_addr_w(u8 data) +{ + LOGREG("%s: data: %02x\n", FUNCNAME, data); + + m_io_address = (m_io_address & 0xff00) | data; +} + +void heath_igc_tlb_device::sigma_io_hi_addr_w(u8 data) +{ + LOGREG("%s: data: %02x\n", FUNCNAME, data); + + m_io_address = (data << 8) | (m_io_address & 0x00ff); +} + +void heath_igc_tlb_device::sigma_window_lo_addr_w(u8 data) +{ + LOGREG("%s: data: %02x\n", FUNCNAME, data); + + m_window_address = (m_window_address & 0xff00) | data; +} + +void heath_igc_tlb_device::sigma_window_hi_addr_w(u8 data) +{ + LOGREG("%s: data: %02x\n", FUNCNAME, data); + + m_window_address = (data << 8) | (m_window_address & 0x00ff); +} + +MC6845_UPDATE_ROW(heath_igc_tlb_device::crtc_update_row) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + + if (de) + { + u8 video_invert = m_video_invert_enabled ? 0xff : 0; + + for (int x = 0; x < x_count; x++) + { + u8 output = 0x00; + + if (!m_character_video_disabled) + { + u8 inv = (x == cursor_x) ? 0xff : 0; + u8 chr = m_p_videoram[(ma + x) & 0x7ff]; + + if (chr & 0x80) + { + inv ^= 0xff; + chr &= 0x7f; + } + + // TODO handle alt font + output |= m_p_chargen[(chr << 4) | ra] ^ inv; + } + + if (m_pixel_video_enabled) + { + output |= m_p_graphic_ram[(((y * 80) + x) + m_window_address) & 0xffff]; + } + + output ^= video_invert; + + for (int b = 0; 8 > b; ++b) + { + *p++ = palette[BIT(output, b)]; + } + } + } + else + { + std::fill_n(p, x_count * 8, palette[0]); + } +} + + +/** + * SigmaSoft and Systems IGC plus TLB with Super-19 ROM + * + */ +heath_igc_super19_tlb_device::heath_igc_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_igc_tlb_device(mconfig, HEATH_IGC_SUPER19, tag, owner, clock) +{ +} + +const tiny_rom_entry *heath_igc_super19_tlb_device::device_rom_region() const +{ + return ROM_NAME(super19); +} + +ioport_constructor heath_igc_super19_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(super19); +} + + +/** + * SigmaSoft and Systems IGC plus TLB with UltraROM + * + */ +heath_igc_ultra_tlb_device::heath_igc_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_igc_tlb_device(mconfig, HEATH_IGC_ULTRA, tag, owner, clock) +{ +} + +void heath_igc_ultra_tlb_device::device_add_mconfig(machine_config &config) +{ + heath_tlb_device::device_add_mconfig(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &heath_igc_ultra_tlb_device::mem_map); +} + +void heath_igc_ultra_tlb_device::mem_map(address_map &map) +{ + heath_tlb_device::mem_map(map); + + // update rom mirror setting to allow page 2 memory + map(0x0000, 0x0fff).mirror(0x2000).rom(); + + // Page 2 memory + map(0x1000, 0x1fff).mirror(0x2000).ram(); +} + +const tiny_rom_entry *heath_igc_ultra_tlb_device::device_rom_region() const +{ + return ROM_NAME(ultra19); +} + +ioport_constructor heath_igc_ultra_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(ultra19); +} + + +/** + * SigmaSoft and Systems IGC plus TLB with Watzman ROM + * + */ +heath_igc_watz_tlb_device::heath_igc_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + heath_igc_tlb_device(mconfig, HEATH_IGC_WATZ, tag, owner, clock) +{ +} + +const tiny_rom_entry *heath_igc_watz_tlb_device::device_rom_region() const +{ + return ROM_NAME(watz19); +} + +ioport_constructor heath_igc_watz_tlb_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(watz19); +} + + +/** + * Terminal Logic Board Connector + * + */ +heath_tlb_connector::heath_tlb_connector(const machine_config &mconfig, const char *tag, device_t *owner, u32 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/devices/bus/heathzenith/h19/tlb.h b/src/devices/bus/heathzenith/h19/tlb.h new file mode 100644 index 00000000000..b0ed5ba31ef --- /dev/null +++ b/src/devices/bus/heathzenith/h19/tlb.h @@ -0,0 +1,477 @@ +// license:BSD-3-Clause +// copyright-holders:Mark Garlanger +/*************************************************************************** + + Heathkit Terminal Logic Board (TLB) + +****************************************************************************/ + +#ifndef MAME_HEATHZENITH_TLB_H +#define MAME_HEATHZENITH_TLB_H + +#pragma once + +#include "cpu/z80/z80.h" +#include "machine/clock.h" +#include "machine/ins8250.h" +#include "machine/mm5740.h" +#include "sound/beep.h" +#include "video/mc6845.h" + +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + + +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) {} + + // optional SigmaSet operations + virtual void sigma_ctrl_w(u8 data) {} + virtual u8 sigma_ctrl_r() { return 0x00; } + virtual u8 sigma_video_mem_r() { return 0x00; } + virtual void sigma_video_mem_w(u8 val) {} + virtual void sigma_io_lo_addr_w(u8 val) {} + virtual void sigma_io_hi_addr_w(u8 val) {} + virtual void sigma_window_lo_addr_w(u8 val) {} + virtual void sigma_window_hi_addr_w(u8 val) {} + +protected: + 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, u32 clock = 0); + + // 8250 UART + 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 serial_irq_w(int state); + + // Keyboard + void reset_key_w(int state); + void right_shift_w(int state); + void repeat_key_w(int state); + void break_key_w(int state); + +protected: + heath_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); + + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + void mem_map(address_map &map) ATTR_COLD; + void io_map(address_map &map) ATTR_COLD; + + + // interrupt related + virtual void set_irq_line(); + + // reset + void check_for_reset(); + + // sound/speaker + void check_beep_state(); + void key_click_w(u8 data); + void bell_w(u8 data); + TIMER_CALLBACK_MEMBER(key_click_off); + TIMER_CALLBACK_MEMBER(bell_off); + + // keyboard + u8 kbd_key_r(); + u8 kbd_flags_r(); + u16 translate_mm5740_b(u16 b); + int mm5740_shift_r(); + int mm5740_control_r(); + void mm5740_data_ready_w(int state); + + // serial port + void serial_out_b(int data); + void dtr_out(int data); + void rts_out(int data); + + // crtc + void crtc_addr_w(offs_t reg, u8 val); + virtual u8 crtc_reg_r(offs_t reg); + virtual void crtc_reg_w(offs_t reg, u8 val); + void crtc_vsync_w(int val); + virtual MC6845_UPDATE_ROW(crtc_update_row); + + required_device m_maincpu; + required_device m_screen; + required_device m_palette; + required_device m_crtc; + required_shared_ptr m_p_videoram; + required_region_ptr m_p_chargen; + required_ioport m_config; + required_device m_ace; + required_device m_beep; + required_device m_mm5740; + required_memory_region m_kbdrom; + required_ioport m_kbspecial; + required_device m_repeat_clock; + + emu_timer *m_key_click_timer; + emu_timer *m_bell_timer; + + u8 m_transchar; + bool m_strobe; + bool m_key_click_active; + bool m_bell_active; + bool m_reset_pending; + bool m_right_shift; + bool m_reset_key; + bool m_keyboard_irq_raised; + bool m_serial_irq_raised; + bool m_break_key_irq_raised; + bool m_allow_vsync_nmi; +}; + +/** + * Heath TLB with Super19 ROM + */ +class heath_super19_tlb_device : public heath_tlb_device +{ +public: + heath_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; +}; + +/** + * Heath TLB with Superset ROM + */ +class heath_superset_tlb_device : public heath_tlb_device +{ +public: + heath_superset_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + + virtual void device_start() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + void mem_map(address_map &map) ATTR_COLD; + void io_map(address_map &map) ATTR_COLD; + + virtual MC6845_UPDATE_ROW(crtc_update_row) override; + + void dtr_internal(int data); + void out1_internal(int data); + void out2_internal(int data); + + virtual u8 crtc_reg_r(offs_t reg) override; + virtual void crtc_reg_w(offs_t reg, u8 val) override; + + u8 m_selected_char_set; + bool m_reverse_video_disabled; +}; + +/** + * Heath TLB with Watzman (HUG) ROM + */ +class heath_watz_tlb_device : public heath_tlb_device +{ +public: + heath_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; +}; + +/** + * Heath TLB with Ultra ROM + */ +class heath_ultra_tlb_device : public heath_tlb_device +{ +public: + heath_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + void mem_map(address_map &map) ATTR_COLD; +}; + +/** + * 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, u32 clock = 0); + + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + + virtual void device_start() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + void mem_map(address_map &map) ATTR_COLD; + void io_map(address_map &map) ATTR_COLD; + + void latch_u5_w(u8 data); + + virtual MC6845_UPDATE_ROW(crtc_update_row) override; + + bool m_char_gen_a11; + bool m_graphic_mode; + bool m_col_132; + bool m_reverse_video; +}; + +/** + * Heath TLB plus Cleveland Codonics Imaginator-100 + */ +class heath_imaginator_tlb_device : public heath_tlb_device +{ +public: + heath_imaginator_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + void mem_map(address_map &map) ATTR_COLD; + void io_map(address_map &map) ATTR_COLD; + + virtual MC6845_UPDATE_ROW(crtc_update_row) override; + void crtc_hsync_w(int val); + + IRQ_CALLBACK_MEMBER(irq_ack_cb); + + void tap_6000h(); + void tap_8000h(); + + void allow_tlb_intr(); + void allow_hsync_intr(); + + void display_enable_w(offs_t reg, u8 val); + void config_irq_w(offs_t reg, u8 val); + void nop_w(offs_t reg, u8 val); + virtual void set_irq_line() override; + + required_memory_bank m_mem_bank; + required_shared_ptr m_p_graphic_ram; + memory_passthrough_handler m_tap_6000h; + + u8 m_im2_val; + + bool m_alphanumeric_mode_active; + bool m_graphics_mode_active; + + bool m_allow_tlb_interrupts; + bool m_allow_imaginator_interrupts; + + bool m_hsync_irq_raised; +}; + +/** + * Heath TLB plus SigmaSoft Interactive Graphics Controller + */ +class heath_igc_tlb_device : public heath_tlb_device +{ +public: + heath_igc_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + virtual void sigma_ctrl_w(u8 data) override; + virtual u8 sigma_ctrl_r() override; + + virtual u8 sigma_video_mem_r() override; + virtual void sigma_video_mem_w(u8 val) override; + + virtual void sigma_io_lo_addr_w(u8 val) override; + virtual void sigma_io_hi_addr_w(u8 val) override; + + virtual void sigma_window_lo_addr_w(u8 val) override; + virtual void sigma_window_hi_addr_w(u8 val) override; + +protected: + heath_igc_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); + + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + virtual MC6845_UPDATE_ROW(crtc_update_row) override; + + std::unique_ptr m_p_graphic_ram; + + // Control Register + bool m_pixel_video_enabled; + bool m_character_video_disabled; + bool m_video_invert_enabled; + bool m_alternate_character_set_enabled; + bool m_video_fill_enabled; + bool m_read_address_increment_disabled; + u8 m_memory_bank_select; + + u8 m_data_reg; + + u16 m_io_address; + u16 m_window_address; +}; + +/** + * Heath TLB with the super19 ROM plus SigmaSoft Interactive Graphics Controller + */ +class heath_igc_super19_tlb_device : public heath_igc_tlb_device +{ +public: + heath_igc_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; +}; + +/** + * Heath TLB with the ultrarom plus SigmaSoft Interactive Graphics Controller + */ +class heath_igc_ultra_tlb_device : public heath_igc_tlb_device +{ +public: + heath_igc_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + + void mem_map(address_map &map) ATTR_COLD; +}; + +/** + * Heath TLB with the watzman ROM plus SigmaSoft Interactive Graphics Controller + */ +class heath_igc_watz_tlb_device : public heath_igc_tlb_device +{ +public: + heath_igc_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; +}; + +// Options for the standard H89 class of systems +DECLARE_DEVICE_TYPE(HEATH_TLB, heath_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_GP19, heath_gp19_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_IMAGINATOR, heath_imaginator_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_SUPER19, heath_super19_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_SUPERSET, heath_superset_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_WATZ, heath_watz_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_ULTRA, heath_ultra_tlb_device) + +// Options for the H89 with the SigmaSoft IGC graphics installed +DECLARE_DEVICE_TYPE(HEATH_IGC, heath_igc_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_IGC_SUPER19, heath_igc_super19_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_IGC_ULTRA, heath_igc_ultra_tlb_device) +DECLARE_DEVICE_TYPE(HEATH_IGC_WATZ, heath_igc_watz_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, u32 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); } + + // signals out from the tlb + 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); } + + // optional SigmaSet IGC operations + u8 sigma_ctrl_r() { return (m_tlb) ? m_tlb->sigma_ctrl_r() : 0x00; } + void sigma_ctrl_w(u8 data) { if (m_tlb) m_tlb->sigma_ctrl_w(data); } + + u8 sigma_video_mem_r() { return (m_tlb) ? m_tlb->sigma_video_mem_r() : 0x00; } + void sigma_video_mem_w(u8 val) { if (m_tlb) m_tlb->sigma_video_mem_w(val); } + + void sigma_io_lo_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_io_lo_addr_w(val); } + void sigma_io_hi_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_io_hi_addr_w(val); } + + void sigma_window_lo_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_window_lo_addr_w(val); } + void sigma_window_hi_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_window_hi_addr_w(val); } + +protected: + virtual void device_start() override ATTR_COLD; + + 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_HEATHZENITH_TLB_H diff --git a/src/devices/bus/heathzenith/h89/cards.cpp b/src/devices/bus/heathzenith/h89/cards.cpp index 22f379601b1..618f07d4f6a 100644 --- a/src/devices/bus/heathzenith/h89/cards.cpp +++ b/src/devices/bus/heathzenith/h89/cards.cpp @@ -12,12 +12,14 @@ #include "h_88_3.h" #include "h_88_5.h" #include "mms77316_fdc.h" +#include "sigmasoft_parallel_port.h" #include "sigmasoft_sound.h" #include "we_pullup.h" #include "z37_fdc.h" void h89_left_cards(device_slot_interface &device) { + device.option_add("ss_parallel", H89BUS_SIGMASOFT_PARALLEL); } void h89_right_cards(device_slot_interface &device) diff --git a/src/devices/bus/heathzenith/h89/h89bus.cpp b/src/devices/bus/heathzenith/h89/h89bus.cpp index 848713aa76d..17a6fab2dd6 100644 --- a/src/devices/bus/heathzenith/h89/h89bus.cpp +++ b/src/devices/bus/heathzenith/h89/h89bus.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:R. Belmont +// copyright-holders:R. Belmont, Mark Garlanger /*************************************************************************** h89bus.cpp - Heath/Zenith H-89/Z-90 bus @@ -175,8 +175,7 @@ const tiny_rom_entry *h89bus_device::device_rom_region() const void h89bus_device::device_start() { - // don't claim I/O below 0x10 for now - m_io_space->install_readwrite_handler(0x0010, 0x00ff, emu::rw_delegate(*this, FUNC(h89bus_device::io_dispatch_r)), emu::rw_delegate(*this, FUNC(h89bus_device::io_dispatch_w))); + m_io_space->install_readwrite_handler(0x0000, 0x00ff, emu::rw_delegate(*this, FUNC(h89bus_device::io_dispatch_r)), emu::rw_delegate(*this, FUNC(h89bus_device::io_dispatch_w))); } void h89bus_device::add_h89bus_left_card(device_h89bus_left_card_interface &card) @@ -242,37 +241,33 @@ u8 h89bus_device::io_dispatch_r(offs_t offset) { u8 retval = 0; - offset += 0x10; - if (m_decode_prom[offset] != 0xff) - { - u16 decode = m_decode_prom[offset] ^ 0xff; + u16 decode = m_decode_prom[offset] ^ 0xff; + if (decode) + { if ((decode & H89_GPP) && ((offset & 7) == 2)) return m_in_gpp_cb(offset); if (decode & H89_NMI) return m_in_nmi_cb(offset); if (decode & H89_TERM) return m_in_tlb_cb(offset & 7); - if (decode) + for (device_h89bus_right_card_interface &entry : m_right_device_list) { - for (device_h89bus_right_card_interface &entry : m_right_device_list) + if (entry.m_p506_signals) + { + // p506 does not have CASS or LP + retval |= entry.read(decode & ~(H89_CASS | H89_LP), offset & 7); + } + else { - if (entry.m_p506_signals) - { - // p506 does not have CASS or LP - retval |= entry.read(decode & ~(H89_CASS | H89_LP), offset & 7); - } - else - { - // p504/p505 does not have FLPY - retval |= entry.read(decode & ~H89_FLPY , offset & 7); - } + // p504/p505 does not have FLPY + retval |= entry.read(decode & ~H89_FLPY , offset & 7); } } + } - // service left-slot cards that have a motherboard connection to snoop the I/O space - for (device_h89bus_left_card_interface &entry : m_left_device_list) - { - retval |= entry.read(H89_IO, offset); - } + // service left-slot cards that have a motherboard connection to snoop the I/O space + for (device_h89bus_left_card_interface &entry : m_left_device_list) + { + retval |= entry.read(H89_IO, offset & 0x1fff); } return retval; @@ -280,37 +275,33 @@ u8 h89bus_device::io_dispatch_r(offs_t offset) void h89bus_device::io_dispatch_w(offs_t offset, u8 data) { - offset += 0x10; - if (m_decode_prom[offset] != 0xff) - { - u16 decode = m_decode_prom[offset] ^ 0xff; + u16 decode = m_decode_prom[offset] ^ 0xff; + if (decode) + { if (decode & H89_GPP) m_out_gpp_cb(offset, data); if (decode & H89_NMI) { m_out_nmi_cb(offset, data); return; } if (decode & H89_TERM) { m_out_tlb_cb(offset & 7, data); return; } - if (decode) + for (device_h89bus_right_card_interface &entry : m_right_device_list) { - for (device_h89bus_right_card_interface &entry : m_right_device_list) + if (entry.m_p506_signals) + { + // p506 does not have CASS or LP + entry.write(decode & ~(H89_CASS | H89_LP), offset & 7, data); + } + else { - if (entry.m_p506_signals) - { - // p506 does not have CASS or LP - entry.write(decode & ~(H89_CASS | H89_LP), offset & 7, data); - } - else - { - // p504/p505 does not have FLPY - entry.write(decode & ~H89_FLPY, offset & 7, data); - } + // p504/p505 does not have FLPY + entry.write(decode & ~H89_FLPY, offset & 7, data); } } + } - // service left-slot cards that have a motherboard connection to snoop the I/O space - for (device_h89bus_left_card_interface &entry : m_left_device_list) - { - entry.write(H89_IO, offset, data); - } + // service left-slot cards that have a motherboard connection to snoop the I/O space + for (device_h89bus_left_card_interface &entry : m_left_device_list) + { + entry.write(H89_IO, offset, data); } } diff --git a/src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.cpp b/src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.cpp new file mode 100644 index 00000000000..9f47f999198 --- /dev/null +++ b/src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.cpp @@ -0,0 +1,245 @@ +// license:BSD-3-Clause +// copyright-holders:Mark Garlanger +/*************************************************************************** + + SigmaSoft Universal Parallel Interface Board + + +****************************************************************************/ + +#include "emu.h" + +#include "bus/heathzenith/h19/tlb.h" + +#include "sigmasoft_parallel_port.h" + +// +// Logging defines +// +#define LOG_REG (1U << 1) // Shows register setup +#define LOG_FUNC (1U << 2) // Function calls + +#define VERBOSE (0) + +#include "logmacro.h" + +#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__) +#define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif + +// TODO make this configurable with jumper config +static constexpr u8 BASE_ADDR = 0x08; + +class sigmasoft_parallel_port : public device_t, public device_h89bus_left_card_interface +{ +public: + sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + virtual u8 read(u8 select_lines, u16 offset) override; + virtual void write(u8 select_lines, u16 offset, u8 data) override; + + auto ctrl_r_cb() { return m_ctrl_r.bind(); } + auto video_mem_r_cb() { return m_video_mem_r.bind(); } + + auto video_mem_cb() { return m_video_mem_w.bind(); } + auto io_lo_cb() { return m_io_lo_addr.bind(); } + auto io_hi_cb() { return m_io_hi_addr.bind(); } + auto window_lo_cb() { return m_window_lo_addr.bind(); } + auto window_hi_cb() { return m_window_hi_addr.bind(); } + auto ctrl_cb() { return m_ctrl_w.bind(); } + +protected: + + virtual void device_start() override ATTR_COLD; + virtual void device_add_mconfig(machine_config& config) override ATTR_COLD;; + + u8 video_mem_r(); + void video_mem_w(u8 val); + + void io_lo_addr_w(u8 val); + void io_hi_addr_w(u8 val); + + void window_lo_addr_w(u8 val); + void window_hi_addr_w(u8 val); + + void ctrl_w(u8 val); + u8 ctrl_r(); + +private: + + // Reads + devcb_read8 m_ctrl_r; + devcb_read8 m_video_mem_r; + + // Writes + devcb_write8 m_video_mem_w; + devcb_write8 m_io_lo_addr; + devcb_write8 m_io_hi_addr; + devcb_write8 m_window_lo_addr; + devcb_write8 m_window_hi_addr; + devcb_write8 m_ctrl_w; +}; + + +sigmasoft_parallel_port::sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock): + device_t(mconfig, H89BUS_SIGMASOFT_PARALLEL, tag, owner, clock), + device_h89bus_left_card_interface(mconfig, *this), + m_ctrl_r(*this, 0x00), + m_video_mem_r(*this, 0x00), + m_video_mem_w(*this), + m_io_lo_addr(*this), + m_io_hi_addr(*this), + m_window_lo_addr(*this), + m_window_hi_addr(*this), + m_ctrl_w(*this) +{ +} + +void sigmasoft_parallel_port::video_mem_w(u8 val) +{ + m_video_mem_w(val); +} + +void sigmasoft_parallel_port::io_lo_addr_w(u8 val) +{ + m_io_lo_addr(val); +} + +void sigmasoft_parallel_port::io_hi_addr_w(u8 val) +{ + m_io_hi_addr(val); +} + +void sigmasoft_parallel_port::window_lo_addr_w(u8 val) +{ + m_window_lo_addr(val); +} + +void sigmasoft_parallel_port::window_hi_addr_w(u8 val) +{ + m_window_hi_addr(val); +} + +void sigmasoft_parallel_port::ctrl_w(u8 val) +{ + m_ctrl_w(val); +} + +void sigmasoft_parallel_port::write(u8 select_lines, u16 offset, u8 data) +{ + offset -= BASE_ADDR; + if (!(select_lines & h89bus_device::H89_IO) || offset >= 8) + { + return; + } + + LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, offset, data); + + switch (offset) + { + case 0: + video_mem_w(data); + break; + case 1: + io_lo_addr_w(data); + break; + case 2: + io_hi_addr_w(data); + break; + case 3: + window_lo_addr_w(data); + break; + case 4: + window_hi_addr_w(data); + break; + case 5: + ctrl_w(data); + break; + case 6: + // TODO - Centronics interface + break; + case 7: + // TODO - Centronics interface + break; + } +} + +u8 sigmasoft_parallel_port::video_mem_r() +{ + // get video memory value from igc device + return m_video_mem_r(); +} + +u8 sigmasoft_parallel_port::ctrl_r() +{ + // get control register from igc device + return m_ctrl_r(); +} + +u8 sigmasoft_parallel_port::read(u8 select_lines, u16 offset) +{ + offset -= BASE_ADDR; + u8 value = 0x00; + + if (!(select_lines & h89bus_device::H89_IO) || offset >= 8) + { + return value; + } + + switch (offset) + { + case 0: + value = video_mem_r(); + break; + case 1: + // TODO - Light Pen Low address + break; + case 2: + // TODO - Light Pen High address + break; + case 3: + // TODO - Left input device + break; + case 4: + // TODO - Right input device + break; + case 5: + // Control Register + value = ctrl_r(); + break; + case 6: + // TODO - Centronics interface + break; + case 7: + // TODO - Centronics interface + break; + } + + LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, offset, value); + + return value; +} + +void sigmasoft_parallel_port::device_start() +{ +} + +void sigmasoft_parallel_port::device_add_mconfig(machine_config &config) +{ + // connect callbacks to TLB + ctrl_r_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_ctrl_r)); + video_mem_r_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_video_mem_r)); + video_mem_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_video_mem_w)); + io_lo_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_io_lo_addr_w)); + io_hi_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_io_hi_addr_w)); + window_lo_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_window_lo_addr_w)); + window_hi_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_window_hi_addr_w)); + ctrl_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_ctrl_w)); +} + +DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_SIGMASOFT_PARALLEL, device_h89bus_left_card_interface, sigmasoft_parallel_port, "sigmasoft_parallel_port", "SigmaSoft Universal Parallel Board"); diff --git a/src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.h b/src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.h new file mode 100644 index 00000000000..e35cdec5de6 --- /dev/null +++ b/src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.h @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Mark Garlanger +/*************************************************************************** + + SigmaSoft Universal Parallel Interface Board + +****************************************************************************/ + +#ifndef MAME_BUS_HEATHZENITH_H89_SIGMASOFT_PARALLEL_PORT_H +#define MAME_BUS_HEATHZENITH_H89_SIGMASOFT_PARALLEL_PORT_H + +#pragma once + +#include "h89bus.h" + +DECLARE_DEVICE_TYPE(H89BUS_SIGMASOFT_PARALLEL, device_h89bus_left_card_interface) + +#endif // MAME_BUS_HEATHZENITH_H89_SIGMASOFT_PARALLEL_PORT_H diff --git a/src/mame/heathzenith/h19.cpp b/src/mame/heathzenith/h19.cpp index a3b0fe21fa7..acbed68032d 100644 --- a/src/mame/heathzenith/h19.cpp +++ b/src/mame/heathzenith/h19.cpp @@ -12,7 +12,7 @@ #include "emu.h" -#include "tlb.h" +#include "bus/heathzenith/h19/tlb.h" #include "bus/rs232/rs232.h" #include "h19.lh" diff --git a/src/mame/heathzenith/h89.cpp b/src/mame/heathzenith/h89.cpp index ca3bb725ccd..0412404811b 100644 --- a/src/mame/heathzenith/h89.cpp +++ b/src/mame/heathzenith/h89.cpp @@ -44,9 +44,8 @@ #include "emu.h" #include "intr_cntrl.h" -#include "sigmasoft_parallel_port.h" -#include "tlb.h" +#include "bus/heathzenith/h19/tlb.h" #include "bus/heathzenith/h89/h89bus.h" #include "bus/heathzenith/h89/cards.h" #include "cpu/z80/z80.h" @@ -198,17 +197,11 @@ class h89_sigmasoft_state : public h89_state { public: h89_sigmasoft_state(const machine_config &mconfig, device_type type, const char *tag): - h89_state(mconfig, type, tag), - m_sigma_parallel(*this, "sigma_parallel") + h89_state(mconfig, type, tag) { } void h89_sigmasoft(machine_config &config); - -protected: - required_device m_sigma_parallel; - - void h89_sigmasoft_io(address_map &map); }; @@ -377,44 +370,6 @@ void h89_base_state::h89_base_io(address_map &map) map.global_mask(0xff); } -void h89_sigmasoft_state::h89_sigmasoft_io(address_map &map) -{ - h89_base_io(map); - - // Add SigmaSoft parallel port board, required for IGC graphics - map(0x08,0x0f).rw(m_sigma_parallel, FUNC(sigmasoft_parallel_port::read), FUNC(sigmasoft_parallel_port::write)); -} - -/* - Memory Map for MMS 444-61C PROM - - PORT - Use | Hex | - ----------------------------+-------+ - Not specified, available | 0-37 | - MMS 77316 | 38-3F | - MMS Internal test fixtures | 40-47 | - MMS 77317 ACT/XCOMP I/O | 48-4F | - MMS 77315 CAMEO I/O | 50-56 | - Unused | 57 | - MMS 77314 Corvus I/O | 58-59 | - MMS 77314 REMEX I/O | 5A-5B | - MMS 77314,15,17 Conf Port | 5C | - Unused | 5D-77 | - Disk I/O #1 | 78-7B | - Disk I/O #2 | 7C-7F | - HDOS reserved | 80-CF | - DCE Serial I/O | D0-D7 | - DTE Serial I/O | D8-DF | - DCE Serial I/O | EO-E7 | - Console I/O | E8-EF | - NMI | F0-F1 | - General purpose port | F2 | - Unused | F8-F9 | - NMI | FA-FB | - Unused | FC-FF | - */ - // Input ports static INPUT_PORTS_START( h88 ) @@ -1032,19 +987,10 @@ void h89_sigmasoft_state::h89_sigmasoft(machine_config &config) { h89(config); m_h89bus->set_default_bios_tag("444-61"); - m_maincpu->set_addrmap(AS_IO, &h89_sigmasoft_state::h89_sigmasoft_io); sigma_tlb_options(m_tlbc); - SIGMASOFT_PARALLEL_PORT(config, m_sigma_parallel); - m_sigma_parallel->ctrl_r_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_ctrl_r)); - m_sigma_parallel->video_mem_r_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_video_mem_r)); - m_sigma_parallel->video_mem_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_video_mem_w)); - m_sigma_parallel->io_lo_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_io_lo_addr_w)); - m_sigma_parallel->io_hi_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_io_hi_addr_w)); - m_sigma_parallel->window_lo_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_window_lo_addr_w)); - m_sigma_parallel->window_hi_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_window_hi_addr_w)); - m_sigma_parallel->ctrl_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_ctrl_w)); + H89BUS_LEFT_SLOT(config.replace(), "p501", "h89bus", h89_left_cards, "ss_parallel"); } void h89_mms_state::h89_mms(machine_config &config) diff --git a/src/mame/heathzenith/sigmasoft_parallel_port.cpp b/src/mame/heathzenith/sigmasoft_parallel_port.cpp deleted file mode 100644 index a412f204245..00000000000 --- a/src/mame/heathzenith/sigmasoft_parallel_port.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mark Garlanger -/*************************************************************************** - - SigmaSoft Universal Parallel Interface Board - - -****************************************************************************/ - -#include "emu.h" - -#include "sigmasoft_parallel_port.h" - -// -// Logging defines -// -#define LOG_REG (1U << 1) // Shows register setup -#define LOG_FUNC (1U << 2) // Function calls - -#define VERBOSE (0) - -#include "logmacro.h" - -#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__) -#define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__) - -#ifdef _MSC_VER -#define FUNCNAME __func__ -#else -#define FUNCNAME __PRETTY_FUNCTION__ -#endif - - -DEFINE_DEVICE_TYPE(SIGMASOFT_PARALLEL_PORT, sigmasoft_parallel_port, "sigmasoft_parallel_port", "SigmaSoft Universal Parallel Board"); - -sigmasoft_parallel_port::sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock): - device_t(mconfig, SIGMASOFT_PARALLEL_PORT, tag, owner, clock), - m_ctrl_r(*this, 0x00), - m_video_mem_r(*this, 0x00), - m_video_mem_w(*this), - m_io_lo_addr(*this), - m_io_hi_addr(*this), - m_window_lo_addr(*this), - m_window_hi_addr(*this), - m_ctrl_w(*this) -{ -} - -void sigmasoft_parallel_port::video_mem_w(u8 val) -{ - m_video_mem_w(val); -} - -void sigmasoft_parallel_port::io_lo_addr_w(u8 val) -{ - m_io_lo_addr(val); -} - -void sigmasoft_parallel_port::io_hi_addr_w(u8 val) -{ - m_io_hi_addr(val); -} - -void sigmasoft_parallel_port::window_lo_addr_w(u8 val) -{ - m_window_lo_addr(val); -} - -void sigmasoft_parallel_port::window_hi_addr_w(u8 val) -{ - m_window_hi_addr(val); -} - -void sigmasoft_parallel_port::ctrl_w(u8 val) -{ - m_ctrl_w(val); -} - -void sigmasoft_parallel_port::write(offs_t reg, u8 val) -{ - LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, reg, val); - - switch (reg) - { - case 0: - video_mem_w(val); - break; - case 1: - io_lo_addr_w(val); - break; - case 2: - io_hi_addr_w(val); - break; - case 3: - window_lo_addr_w(val); - break; - case 4: - window_hi_addr_w(val); - break; - case 5: - ctrl_w(val); - break; - case 6: - // TODO - Centronics interface - break; - case 7: - // TODO - Centronics interface - break; - } -} - -u8 sigmasoft_parallel_port::video_mem_r() -{ - // get video memory value from igc device - return m_video_mem_r(); -} - -u8 sigmasoft_parallel_port::ctrl_r() -{ - // get control register from igc device - return m_ctrl_r(); -} - -u8 sigmasoft_parallel_port::read(offs_t reg) -{ - // default return for the h89 - u8 value = 0xff; - - switch (reg) - { - case 0: - value = video_mem_r(); - break; - case 1: - // TODO - Light Pen Low address - break; - case 2: - // TODO - Light Pen High address - break; - case 3: - // TODO - Left input device - break; - case 4: - // TODO - Right input device - break; - case 5: - // Control Register - value = ctrl_r(); - break; - case 6: - // TODO - Centronics interface - break; - case 7: - // TODO - Centronics interface - break; - } - - LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, reg, value); - - return value; -} - -void sigmasoft_parallel_port::device_start() -{ -} diff --git a/src/mame/heathzenith/sigmasoft_parallel_port.h b/src/mame/heathzenith/sigmasoft_parallel_port.h deleted file mode 100644 index 60030b2647b..00000000000 --- a/src/mame/heathzenith/sigmasoft_parallel_port.h +++ /dev/null @@ -1,67 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mark Garlanger -/*************************************************************************** - - SigmaSoft Universal Parallel Interface Board - -****************************************************************************/ - -#ifndef MAME_HEATHZENITH_SIGMASOFT_PARALLEL_PORT_H -#define MAME_HEATHZENITH_SIGMASOFT_PARALLEL_PORT_H - -#pragma once - - -class sigmasoft_parallel_port : public device_t -{ -public: - sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - - void write(offs_t reg, u8 val); - u8 read(offs_t reg); - - auto ctrl_r_cb() { return m_ctrl_r.bind(); } - auto video_mem_r_cb() { return m_video_mem_r.bind(); } - - auto video_mem_cb() { return m_video_mem_w.bind(); } - auto io_lo_cb() { return m_io_lo_addr.bind(); } - auto io_hi_cb() { return m_io_hi_addr.bind(); } - auto window_lo_cb() { return m_window_lo_addr.bind(); } - auto window_hi_cb() { return m_window_hi_addr.bind(); } - auto ctrl_cb() { return m_ctrl_w.bind(); } - -protected: - - virtual void device_start() override ATTR_COLD; - - u8 video_mem_r(); - void video_mem_w(u8 val); - - void io_lo_addr_w(u8 val); - void io_hi_addr_w(u8 val); - - void window_lo_addr_w(u8 val); - void window_hi_addr_w(u8 val); - - void ctrl_w(u8 val); - u8 ctrl_r(); - -private: - - // Reads - devcb_read8 m_ctrl_r; - devcb_read8 m_video_mem_r; - - // Writes - devcb_write8 m_video_mem_w; - devcb_write8 m_io_lo_addr; - devcb_write8 m_io_hi_addr; - devcb_write8 m_window_lo_addr; - devcb_write8 m_window_hi_addr; - devcb_write8 m_ctrl_w; -}; - -DECLARE_DEVICE_TYPE(SIGMASOFT_PARALLEL_PORT, sigmasoft_parallel_port) - - -#endif // MAME_HEATHZENITH_SIGMASOFT_PARALLEL_PORT_H diff --git a/src/mame/heathzenith/tlb.cpp b/src/mame/heathzenith/tlb.cpp deleted file mode 100644 index 10b384b22cb..00000000000 --- a/src/mame/heathzenith/tlb.cpp +++ /dev/null @@ -1,2032 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mark Garlanger -/*************************************************************************** - - Heathkit Terminal Logic Board (TLB) - - The board used in the H19 smart terminal designed and manufactured - by Heath Company. (and the identical Z19 sold by Zenith Data Systems) - This board is also used the Heath's H89 / H88, and ZDS's Z-89 and Z-90. - - The keyboard consists of a 9x10 matrix connected to a MM5740AAC/N - mask-programmed keyboard controller. The output of this passes - through a rom. - - Input can also come from the serial port. - - Known Issues: - - With gp19 - - 49/50 row mode only shows half the screen. - - In 49/50 row mode, character descenders are cut off. - - Screen saver does not disable the screen - - With Superset - - Screensaver freezes the screen instead of blanking the screen - - Not Currently Implemented - - With Imaginator I-100 - - Support for Tektronics Emulation (missing ROM image) - - With SigmaSoft IGC - - Interlace video support (with higher resolution) - - Joystick support - - Centronics support - - Lightpen support - - Alternate Font ROM support (missing ROM image) - - With Super19 - - Interlace video - - Alternate Font19 alt 128 mode and extended 256 mode (missing ROM images) - - ANSI character set selection (missing ROM image) - - light pen support - - With UltraROM - - Interace mode - -****************************************************************************/ -/*************************************************************************** - - Memory Layout - - The U435 three-to-eight line decoder uses A14 and A15 to generate - three memory address spaces: - - Address Description - ---------------------------------------------------- - 0x0000 Program ROM - 0x4000 Scratchpad RAM - 0xF800 (0xC000) Display Memory - - - Port Layout - - Only address lines A5, A6, A7 are used by the U442 three-to-eight - line decoder - - Address Description - ---------------------------------------------------- - 0x00 Power-up configuration (primary - SW401) - 0x20 Power-up configuration (secondary - SW402) - 0x40 INS8250 ACE (communications) - 0x60 MC6845 CRT controller - 0x80 MM5740 Keyboard encoder - 0xA0 Keyboard status - 0xC0 Trigger key click - 0xE0 Trigger bell - -****************************************************************************/ - -#include "emu.h" - -#include "tlb.h" - -#include - -#define LOG_REG (1U << 1) // Shows register setup - -//#define VERBOSE (LOG_REG) - -#include "logmacro.h" - -#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__) - -#ifdef _MSC_VER -#define FUNCNAME __func__ -#else -#define FUNCNAME __PRETTY_FUNCTION__ -#endif - -// Clocks -static constexpr XTAL MASTER_CLOCK = XTAL(12'288'000); - -// DOT clocks -static constexpr XTAL BASE_DOT_CLOCK = MASTER_CLOCK; -static constexpr XTAL GP19_DOT_CLOCK_1 = XTAL(20'282'000); // 132 columns -static constexpr XTAL GP19_DOT_CLOCK_2 = XTAL(12'292'000); // 80 columns -static constexpr XTAL GP19_DOT_CLOCK_3 = XTAL(10'644'000); // Graphics mode - -// Standard H19 used a 2.048 MHz clock for Z80 -static constexpr XTAL H19_CLOCK = MASTER_CLOCK / 6; -static constexpr XTAL H19_3MHZ = MASTER_CLOCK / 4; -static constexpr XTAL H19_4MHZ = MASTER_CLOCK / 3; -static constexpr XTAL H19_6MHZ = MASTER_CLOCK / 2; - -static constexpr XTAL INS8250_CLOCK = MASTER_CLOCK / 4; - -// Beep Frequency is 1 KHz -static constexpr XTAL H19_BEEP_FRQ = (H19_CLOCK / 2048); - -// Capacitor value in pF -static constexpr u32 H19_KEY_DEBOUNCE_CAPACITOR = 5000; -static const u32 MM5740_CLOCK = mm5740_device::calc_effective_clock_key_debounce(H19_KEY_DEBOUNCE_CAPACITOR); - -// Keyboard flag masks -static constexpr u8 KB_STATUS_SHIFT_KEYS_MASK = 0x01; -static constexpr u8 KB_STATUS_CONTROL_KEY_MASK = 0x10; -static constexpr u8 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") -DEFINE_DEVICE_TYPE(HEATH_SUPERSET, heath_superset_tlb_device, "heath_superset_tlb", "Heath Terminal Logic Board w/Superset ROM") -DEFINE_DEVICE_TYPE(HEATH_ULTRA, heath_ultra_tlb_device, "heath_ultra_tlb", "Heath Terminal Logic Board w/Ultra ROM") -DEFINE_DEVICE_TYPE(HEATH_WATZ, heath_watz_tlb_device, "heath_watz_tlb", "Heath Terminal Logic Board w/Watzman ROM") -DEFINE_DEVICE_TYPE(HEATH_GP19, heath_gp19_tlb_device, "heath_gp19_tlb", "Heath Terminal Logic Board plus Northwest Digital Systems GP-19") -DEFINE_DEVICE_TYPE(HEATH_IMAGINATOR, heath_imaginator_tlb_device, "heath_imaginator_tlb", "Heath Terminal Logic Board plus Cleveland Codonics Imaginator I-100") - -// Devices for the terminal boards compatible with SigmaSoft IGC -DEFINE_DEVICE_TYPE(HEATH_IGC, heath_igc_tlb_device, "heath_igc_tlb_device", "Heath Terminal Logic Board plus SigmaSoft Interactive Graphics Controller") -DEFINE_DEVICE_TYPE(HEATH_IGC_SUPER19, heath_igc_super19_tlb_device, "heath_igc_super19_tlb_device", "Heath Terminal Logic Board w/ Super19 ROM plus SigmaSoft Interactive Graphics Controller") -DEFINE_DEVICE_TYPE(HEATH_IGC_ULTRA, heath_igc_ultra_tlb_device, "heath_igc_ultra_tlb_device", "Heath Terminal Logic Board w/ Ultra ROM plus SigmaSoft Interactive Graphics Controller") -DEFINE_DEVICE_TYPE(HEATH_IGC_WATZ, heath_igc_watz_tlb_device, "heath_igc_watz_tlb_device", "Heath Terminal Logic Board w/Watzman ROM plus SigmaSoft Interactive Graphics Controller") - - -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())) -{ -} - - -/** - * original Heath H19 functionality - */ -heath_tlb_device::heath_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_TLB, tag, owner, clock) -{ -} - -heath_tlb_device::heath_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 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_config(*this, "CONFIG"), - m_ace(*this, "ins8250"), - m_beep(*this, "beeper"), - m_mm5740(*this, "mm5740"), - m_kbdrom(*this, "keyboard"), - m_kbspecial(*this, "MODIFIERS"), - m_repeat_clock(*this, "repeatclock") -{ -} - -void heath_tlb_device::check_beep_state() -{ - if (!m_key_click_active && !m_bell_active) - { - m_beep->set_state(0); - } -} - -TIMER_CALLBACK_MEMBER(heath_tlb_device::key_click_off) -{ - m_key_click_active = false; - - check_beep_state(); -} - -TIMER_CALLBACK_MEMBER(heath_tlb_device::bell_off) -{ - m_bell_active = false; - - check_beep_state(); -} - -void heath_tlb_device::mem_map(address_map &map) -{ - map.unmap_value_high(); - - // H19 ROM - map(0x0000, 0x0fff).mirror(0x3000).rom(); - - // Scratchpad memory - map(0x4000, 0x40ff).mirror(0x3f00).ram(); - - // Video Memory - map(0xc000, 0xc7ff).mirror(0x3800).ram().share(m_p_videoram); -} - -void heath_tlb_device::io_map(address_map &map) -{ - map.unmap_value_high(); - map.global_mask(0xff); - map(0x00, 0x00).mirror(0x1f).portr("SW401"); - map(0x20, 0x20).mirror(0x1f).portr("SW402"); - 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)); - map(0xe0, 0xe0).mirror(0x1f).w(FUNC(heath_tlb_device::bell_w)); -} - -void heath_tlb_device::device_start() -{ - save_item(NAME(m_transchar)); - save_item(NAME(m_strobe)); - save_item(NAME(m_key_click_active)); - save_item(NAME(m_bell_active)); - save_item(NAME(m_reset_pending)); - save_item(NAME(m_right_shift)); - save_item(NAME(m_reset_key)); - save_item(NAME(m_keyboard_irq_raised)); - save_item(NAME(m_serial_irq_raised)); - save_item(NAME(m_break_key_irq_raised)); - save_item(NAME(m_allow_vsync_nmi)); - - m_strobe = false; - m_key_click_active = false; - m_bell_active = false; - m_reset_pending = false; - m_right_shift = false; - m_reset_key = false; - m_keyboard_irq_raised = false; - m_serial_irq_raised = false; - m_break_key_irq_raised = false; - m_allow_vsync_nmi = false; - - m_key_click_timer = timer_alloc(FUNC(heath_tlb_device::key_click_off), this); - m_bell_timer = timer_alloc(FUNC(heath_tlb_device::bell_off), this); - - // Flip bits in font ROM to avoid having to flip them during scan out since some - // boards with graphics has the pixel graphic reversed from the font layout. Doing - // it for all devices for consistency. - for (size_t i = 0; i < m_p_chargen.length(); i++) - { - m_p_chargen[i] = bitswap<8>(m_p_chargen[i], 0, 1, 2, 3, 4, 5, 6, 7); - } -} - -void heath_tlb_device::device_reset() -{ - m_strobe = false; - m_key_click_active = false; - m_bell_active = false; - m_allow_vsync_nmi = false; - - ioport_value const cfg(m_config->read()); - - // CPU clock speed - switch (BIT(cfg, 0, 2)) - { - case 0x01: - m_maincpu->set_clock(H19_3MHZ); - break; - case 0x02: - m_maincpu->set_clock(H19_4MHZ); - break; - case 0x03: - m_maincpu->set_clock(H19_6MHZ); - break; - case 0x00: - default: - // Standard Clock - m_maincpu->set_clock(H19_CLOCK); - break; - } - - // Set screen color - switch (BIT(cfg, 2, 2)) - { - case 0x01: - m_screen->set_color(rgb_t::white()); - break; - case 0x02: - m_screen->set_color(rgb_t::amber()); - break; - case 0x00: - default: - m_screen->set_color(rgb_t::green()); - break; - } -} - -void heath_tlb_device::key_click_w(u8 data) -{ - // Keyclick - 6 mSec - m_beep->set_state(1); - m_key_click_active = true; - m_key_click_timer->adjust(attotime::from_msec(6)); -} - -void heath_tlb_device::bell_w(u8 data) -{ - // Bell (^G) - 200 mSec - m_beep->set_state(1); - m_bell_active = true; - m_bell_timer->adjust(attotime::from_msec(200)); -} - -/** - * MM5740 B Mapping to the ROM address - */ -u16 heath_tlb_device::translate_mm5740_b(u16 b) -{ - return bitswap<9>(b, 7, 6, 8, 5, 4, 3, 2, 1, 0); -} - -u8 heath_tlb_device::kbd_key_r() -{ - 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. - return m_transchar; -} - -u8 heath_tlb_device::kbd_flags_r() -{ - u16 modifiers = m_kbspecial->read(); - u8 rv = modifiers & 0x7e; - - // check both shifts - if ((modifiers & 0x120) != 0x120) - { - rv |= KB_STATUS_SHIFT_KEYS_MASK; - } - - if (!m_strobe) - { - rv |= KB_STATUS_KEYBOARD_STROBE_MASK; - } - - return rv; -} - -int heath_tlb_device::mm5740_shift_r() -{ - return ((m_kbspecial->read() & 0x120) != 0x120) ? 1 : 0; -} - -int heath_tlb_device::mm5740_control_r() -{ - return (m_kbspecial->read() & KB_STATUS_CONTROL_KEY_MASK) ? 0 : 1; -} - -void heath_tlb_device::mm5740_data_ready_w(int state) -{ - if (state) - { - u8 *decode = m_kbdrom->base(); - - m_transchar = decode[translate_mm5740_b(m_mm5740->b_r())]; - m_strobe = true; - m_keyboard_irq_raised = true; - - set_irq_line(); - } -} - -void heath_tlb_device::crtc_addr_w(offs_t reg, u8 val) -{ - m_allow_vsync_nmi = bool(BIT(reg, 2)); - - m_crtc->address_w(val); -} - -u8 heath_tlb_device::crtc_reg_r(offs_t reg) -{ - if (!machine().side_effects_disabled()) - { - m_allow_vsync_nmi = bool(BIT(reg, 2)); - } - - return m_crtc->register_r(); -} - -void heath_tlb_device::crtc_reg_w(offs_t reg, u8 val) -{ - m_allow_vsync_nmi = bool(BIT(reg, 2)); - - m_crtc->register_w(val); -} - -void heath_tlb_device::crtc_vsync_w(int val) -{ - m_maincpu->set_input_line(INPUT_LINE_NMI, m_allow_vsync_nmi ? val : CLEAR_LINE); -} - -void heath_tlb_device::serial_irq_w(int state) -{ - m_serial_irq_raised = bool(state); - - set_irq_line(); -} - -void heath_tlb_device::set_irq_line() -{ - m_maincpu->set_input_line(INPUT_LINE_IRQ0, - (m_keyboard_irq_raised || m_serial_irq_raised || m_break_key_irq_raised) ? - ASSERT_LINE : CLEAR_LINE); -} - -void heath_tlb_device::check_for_reset() -{ - if (m_reset_key && m_right_shift) - { - m_reset_pending = true; - m_slot->reset_out(1); - m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - } - else if (m_reset_pending) - { - m_reset_pending = false; - reset(); - m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - m_slot->reset_out(0); - } -} - -void heath_tlb_device::reset_key_w(int state) -{ - m_reset_key = (state == 0); - - check_for_reset(); -} - -void heath_tlb_device::right_shift_w(int state) -{ - m_right_shift = (state == 0); - - check_for_reset(); -} - -void heath_tlb_device::repeat_key_w(int state) -{ - // when repeat key pressed, set duty cycle to 50%, else 0%. - m_repeat_clock->set_duty_cycle(state == 0 ? 0.5 : 0); -} - -void heath_tlb_device::break_key_w(int state) -{ - m_break_key_irq_raised = (state == 0); - - set_irq_line(); -} - -MC6845_UPDATE_ROW(heath_tlb_device::crtc_update_row) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - - if (de) - { - for (int x = 0; x < x_count; x++) - { - u8 inv = (x == cursor_x) ? 0xff : 0; - u8 chr = m_p_videoram[(ma + x) & 0x7ff]; - - if (chr & 0x80) - { - inv ^= 0xff; - chr &= 0x7f; - } - - // get pattern of pixels for that character scanline - u8 const gfx = m_p_chargen[(chr << 4) | ra] ^ inv; - - // Display a scanline of a character (8 pixels) - for (int b = 0; 8 > b; ++b) - { - *p++ = palette[BIT(gfx, b)]; - } - } - } - else - { - std::fill_n(p, x_count * 8, palette[0]); - } -} - - -// F4 Character Displayer -static const gfx_layout h19_charlayout = -{ - 8, 10, // 8 x 10 characters - 128, // 128 characters - 1, // 1 bits per pixel - { 0 }, // no bitplanes - // x offsets - { 0, 1, 2, 3, 4, 5, 6, 7 }, - // y offsets - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 }, - 8*16 // every char takes 16 bytes -}; - -static GFXDECODE_START( gfx_h19 ) - GFXDECODE_ENTRY("chargen", 0x0000, h19_charlayout, 0, 1) -GFXDECODE_END - - -// Input ports -static INPUT_PORTS_START( tlb ) - - PORT_START("MODIFIERS") - // bit 0 - 0x001 connects to B8 of MM5740 - low if either shift key is - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_PAUSE) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::break_key_w)) - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("OffLine") PORT_CODE(KEYCODE_F12) PORT_TOGGLE - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LeftShift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Repeat") PORT_CODE(KEYCODE_RALT) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::repeat_key_w)) - // bit 7 - 0x080 is low if any key is pressed - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RightShift") PORT_CODE(KEYCODE_RSHIFT) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::right_shift_w)) - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F10) PORT_WRITE_LINE_MEMBER(FUNC(heath_tlb_device::reset_key_w)) - - PORT_START("X1") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X2") - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-.") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-Enter") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) - - 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(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) - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-1 IL") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-2 Down") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-3 DL") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("X3") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ ]") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']') - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_RWIN) PORT_CHAR(10) - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(127) - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-4 LEFT") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-5 HOME") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-6 RIGHT") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("X4") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X1") - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-7 IC") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-8 UP") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("KP-9 DC") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("X5") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Blue") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Red") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gray") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("X6") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - - PORT_START("X7") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll") PORT_CODE(KEYCODE_F11) - - PORT_START("X8") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) - - PORT_START("X9") - PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') - PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') - PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') - PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') - PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') - PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - - PORT_START("SW401") - PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") - PORT_DIPSETTING( 0x01, "110") - PORT_DIPSETTING( 0x02, "150") - PORT_DIPSETTING( 0x03, "300") - PORT_DIPSETTING( 0x04, "600") - PORT_DIPSETTING( 0x05, "1200") - PORT_DIPSETTING( 0x06, "1800") - PORT_DIPSETTING( 0x07, "2000") - PORT_DIPSETTING( 0x08, "2400") - PORT_DIPSETTING( 0x09, "3600") - PORT_DIPSETTING( 0x0a, "4800") - PORT_DIPSETTING( 0x0b, "7200") - 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( 0x10, "Odd") - 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( 0x40, "Stick") - PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") - PORT_DIPSETTING( 0x00, "Half") - PORT_DIPSETTING( 0x80, "Full") - - PORT_START("SW402") - PORT_DIPNAME( 0x01, 0x00, "Cursor") PORT_DIPLOCATION("SW402:1") - 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_DIPNAME( 0x04, 0x00, "Wrap at EOL") PORT_DIPLOCATION("SW402:3") - 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_DIPNAME( 0x10, 0x00, "Auto CR on LF") PORT_DIPLOCATION("SW402:5") - 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_DIPNAME( 0x80, 0x00, "Refresh") PORT_DIPLOCATION("SW402:8") - PORT_DIPSETTING( 0x00, "60Hz") - PORT_DIPSETTING( 0x80, "50Hz") - - PORT_START("CONFIG") - PORT_CONFNAME(0x03, 0x00, "CPU Clock") - PORT_CONFSETTING( 0x00, "2 MHz") - PORT_CONFSETTING( 0x01, "3 MHz") - PORT_CONFSETTING( 0x02, "4 MHz") - PORT_CONFSETTING( 0x03, "6 MHz") - PORT_CONFNAME(0x0C, 0x00, "CRT Color") - PORT_CONFSETTING( 0x00, "Green") - PORT_CONFSETTING( 0x04, "White") - PORT_CONFSETTING( 0x08, "Amber") -INPUT_PORTS_END - - -static INPUT_PORTS_START( super19 ) - PORT_INCLUDE( tlb ) - - PORT_MODIFY("SW401") - PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") - PORT_DIPSETTING( 0x01, "110") - PORT_DIPSETTING( 0x02, "150") - PORT_DIPSETTING( 0x03, "300") - PORT_DIPSETTING( 0x04, "600") - PORT_DIPSETTING( 0x05, "1200") - PORT_DIPSETTING( 0x06, "1800") - PORT_DIPSETTING( 0x07, "2000") - PORT_DIPSETTING( 0x08, "2400") - PORT_DIPSETTING( 0x09, "3600") - PORT_DIPSETTING( 0x0a, "4800") - PORT_DIPSETTING( 0x0b, "7200") - PORT_DIPSETTING( 0x0c, "9600") - PORT_DIPSETTING( 0x0d, "19200") - PORT_DIPSETTING( 0x0e, "38400") - PORT_DIPNAME( 0x70, 0x00, "8 bit mode") PORT_DIPLOCATION("SW401:5,6,7") - PORT_DIPSETTING( 0x00, "Mode A/0 - 8th bit ignored, sent as 0") - PORT_DIPSETTING( 0x10, "Mode B/1 - 8th bit ignored, sent as 1") - PORT_DIPSETTING( 0x20, "Mode C/2 - 8 bit escape mode") - PORT_DIPSETTING( 0x30, "Mode D/3 - 8 bit escape mode, invert 8th bit") - PORT_DIPSETTING( 0x40, "Mode E/4 - 8 bit data mode") - PORT_DIPSETTING( 0x50, "Mode F/5 - 8 bit data mode, invert 8th bit") - PORT_DIPSETTING( 0x60, "7 bit data with odd parity, 8th bit ignored on input") - PORT_DIPSETTING( 0x70, "7 bit data with even parity, 8th bit ignored on input") - PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") - PORT_DIPSETTING( 0x00, "Half") - PORT_DIPSETTING( 0x80, "Full") - - PORT_MODIFY("SW402") - PORT_DIPNAME( 0x02, 0x00, "Transmit mode") PORT_DIPLOCATION("SW402:2") - PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) - PORT_DIPSETTING( 0x02, "Slow") - PORT_DIPNAME( 0x80, 0x00, "DEC Keypad Codes") PORT_DIPLOCATION("SW402:8") - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) -INPUT_PORTS_END - - -static INPUT_PORTS_START( superset ) - PORT_INCLUDE( tlb ) - - PORT_MODIFY("SW401") - PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") - PORT_DIPSETTING( 0x00, "75") - PORT_DIPSETTING( 0x01, "110") - PORT_DIPSETTING( 0x02, "150") - PORT_DIPSETTING( 0x03, "300") - PORT_DIPSETTING( 0x04, "600") - PORT_DIPSETTING( 0x05, "1200") - PORT_DIPSETTING( 0x06, "1800") - PORT_DIPSETTING( 0x07, "2000") - PORT_DIPSETTING( 0x08, "2400") - PORT_DIPSETTING( 0x09, "3600") - PORT_DIPSETTING( 0x0a, "4800") - PORT_DIPSETTING( 0x0b, "7200") - PORT_DIPSETTING( 0x0c, "9600") - PORT_DIPSETTING( 0x0d, "19200") - PORT_DIPSETTING( 0x0e, "38400") - PORT_DIPSETTING( 0x0f, "134.5") - PORT_DIPNAME( 0x10, 0x10, "Duplex") PORT_DIPLOCATION("SW401:5") - PORT_DIPSETTING( 0x00, "Half") - PORT_DIPSETTING( 0x80, "Full") - PORT_DIPNAME( 0x20, 0x00, "Word Length") PORT_DIPLOCATION("SW401:6") - PORT_DIPSETTING( 0x00, "8-bit" ) - PORT_DIPSETTING( 0x20, "7-bit" ) - PORT_DIPNAME( 0x40, 0x00, "Parity Type") PORT_DIPLOCATION("SW401:7") - PORT_DIPSETTING( 0x00, DEF_STR( None ) ) - PORT_DIPSETTING( 0x40, "Even") - PORT_DIPNAME( 0x80, 0x80, "Parity") PORT_DIPLOCATION("SW401:8") - PORT_DIPSETTING( 0x00, "Disabled") - PORT_DIPSETTING( 0x80, "Enabled") -INPUT_PORTS_END - - -static INPUT_PORTS_START( ultra19 ) - PORT_INCLUDE( tlb ) - - PORT_MODIFY("SW401") - PORT_DIPNAME( 0x07, 0x05, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3") - PORT_DIPSETTING( 0x00, "110") - PORT_DIPSETTING( 0x01, "300") - PORT_DIPSETTING( 0x02, "1200") - PORT_DIPSETTING( 0x03, "2400") - PORT_DIPSETTING( 0x04, "4800") - PORT_DIPSETTING( 0x05, "9600") - PORT_DIPSETTING( 0x06, "19200") - PORT_DIPSETTING( 0x07, "38400") - PORT_DIPNAME( 0x08, 0x00, "Parity") PORT_DIPLOCATION("SW401:4") - PORT_DIPSETTING( 0x00, "Disabled") - PORT_DIPSETTING( 0x08, "Enabled") - PORT_DIPNAME( 0x10, 0x00, "Parity Type") PORT_DIPLOCATION("SW401:5") - PORT_DIPSETTING( 0x00, "Odd") - PORT_DIPSETTING( 0x10, "Even") - PORT_DIPNAME( 0x20, 0x00, "Data Size") PORT_DIPLOCATION("SW401:6") - PORT_DIPSETTING( 0x00, "8-bit") - PORT_DIPSETTING( 0x20, "7-bit") - PORT_DIPNAME( 0x40, 0x40, "Duplex") PORT_DIPLOCATION("SW401:7") - PORT_DIPSETTING( 0x00, "Half") - PORT_DIPSETTING( 0x40, "Full") - PORT_DIPNAME( 0x80, 0x80, "Software Handshaking") PORT_DIPLOCATION("SW401:8") - PORT_DIPSETTING( 0x00, "Enabled") - PORT_DIPSETTING( 0x80, "Disabled") - - 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_DIPNAME( 0x10, 0x00, "Default Key Values") PORT_DIPLOCATION("SW402:5") - PORT_DIPSETTING( 0x00, "HDOS Values") - PORT_DIPSETTING( 0x10, "CP/M Values") - PORT_DIPNAME( 0x60, 0x60, "Cursor Blink") PORT_DIPLOCATION("SW402:6,7") - PORT_DIPSETTING( 0x00, "Steady") - PORT_DIPSETTING( 0x20, "Invisible") - PORT_DIPSETTING( 0x40, "Fast Blink") - PORT_DIPSETTING( 0x60, "Slow Blink") - PORT_DIPNAME( 0x80, 0x00, "Interlace Scan Mode") PORT_DIPLOCATION("SW402:8") - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) -INPUT_PORTS_END - - -static INPUT_PORTS_START( watz19 ) - PORT_INCLUDE( tlb ) - - PORT_MODIFY("SW401") - PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate") PORT_DIPLOCATION("SW401:1,2,3,4") - PORT_DIPSETTING( 0x00, "75") - PORT_DIPSETTING( 0x01, "110") - PORT_DIPSETTING( 0x02, "150") - PORT_DIPSETTING( 0x03, "300") - PORT_DIPSETTING( 0x04, "600") - PORT_DIPSETTING( 0x05, "1200") - PORT_DIPSETTING( 0x06, "1800") - PORT_DIPSETTING( 0x07, "2000") - PORT_DIPSETTING( 0x08, "2400") - PORT_DIPSETTING( 0x09, "3600") - PORT_DIPSETTING( 0x0a, "4800") - PORT_DIPSETTING( 0x0b, "7200") - PORT_DIPSETTING( 0x0c, "9600") - PORT_DIPSETTING( 0x0d, "19200") - PORT_DIPSETTING( 0x0e, "38400") - PORT_DIPSETTING( 0x0f, "134.5") - PORT_DIPNAME( 0x40, 0x00, "Word Size") PORT_DIPLOCATION("SW401:7") - PORT_DIPSETTING( 0x00, "8-bit Word") - PORT_DIPSETTING( 0x40, "7-bit Word") - PORT_DIPNAME( 0x80, 0x80, "Duplex") PORT_DIPLOCATION("SW401:8") - PORT_DIPSETTING( 0x00, "Half") - PORT_DIPSETTING( 0x80, "Full") -INPUT_PORTS_END - - -static INPUT_PORTS_START( gp19 ) - PORT_INCLUDE( tlb ) - - PORT_MODIFY("SW402") - PORT_DIPNAME( 0x80, 0x00, "Automatic Holdscreen") PORT_DIPLOCATION("SW402:8") - PORT_DIPSETTING( 0x00, "Disabled (VT100 mode)") - PORT_DIPSETTING( 0x80, "Enabled (Z19 mode)") - - PORT_START("SW1") - PORT_DIPNAME( 0x03, 0x01, "Trailing Characters for Tektronix Message") PORT_DIPLOCATION("SW1:1,2") - PORT_DIPSETTING( 0x00, DEF_STR( None ) ) - PORT_DIPSETTING( 0x01, "CR") - PORT_DIPSETTING( 0x02, DEF_STR( None ) ) - PORT_DIPSETTING( 0x03, "CR,EOT") - PORT_DIPNAME( 0x04, 0x01, "Shift Key") PORT_DIPLOCATION("SW1:3") - 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") - PORT_DIPSETTING( 0x08, "One character per 16.7 msec") - PORT_DIPNAME( 0x10, 0x10, "Character Set") PORT_DIPLOCATION("SW1:5") - PORT_DIPSETTING( 0x00, "VT100") - PORT_DIPSETTING( 0x10, "Zenith") - PORT_DIPNAME( 0x20, 0x00, "ANSI Mode") PORT_DIPLOCATION("SW1:6") - PORT_DIPSETTING( 0x00, "Zenith ANSI") - PORT_DIPSETTING( 0x20, "EDT compatible") - PORT_DIPNAME( 0x40, 0x00, "Tektronix Character Wrap") PORT_DIPLOCATION("SW1:7") - PORT_DIPSETTING( 0x00, "Column 74") - PORT_DIPSETTING( 0x40, "Column 73") - PORT_DIPNAME( 0x80, 0x00, "Blank Screen") PORT_DIPLOCATION("SW1:8") - PORT_DIPSETTING( 0x00, "After 10 mins") - PORT_DIPSETTING( 0x80, "Never") -INPUT_PORTS_END - - -ROM_START( h19 ) - // Original terminal code - ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "2732_444-46_h19code.u437", 0x0000, 0x1000, CRC(f4447da0) SHA1(fb4093d5b763be21a9580a0defebed664b1f7a7b)) - - // Original font - ROM_REGION( 0x0800, "chargen", 0 ) - ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) - - // Original keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) -ROM_END - -ROM_START( super19 ) - // Super-19 ROM - ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "2732_super19_h447.u437", 0x0000, 0x1000, CRC(6c51aaa6) SHA1(5e368b39fe2f1af44a905dc474663198ab630117)) - - // Original font - ROM_REGION( 0x0800, "chargen", 0 ) - ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) - - // Original keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) -ROM_END - -ROM_START( superset ) - // SuperSet ROM - ROM_REGION( 0x4000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "27256_101-402_superset_code.u437", 0x0000, 0x2000, CRC(a6896076) SHA1(a4e2d25028dc75a665c3f5a830a4e8cdecbd481c)) - // 1st 8k is unused, so overwrite it, with the next 16k (but only first 8k is valid) - ROM_CONTINUE(0x0000, 0x4000) - // overwrite at 8k starting address with the last 8k of the chip. - ROM_CONTINUE(0x2000, 0x2000) - - // Superset SUPERFONT - ROM_REGION( 0x8000, "chargen", 0 ) - ROM_LOAD( "27256_101-431_superset_font.u420", 0x0000, 0x8000, CRC(4c0688f6) SHA1(be6059913420ad66f5c839d619fdcb164ffae85a)) - - // Superset Keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "2716_101-422_superset_kbd.u445", 0x0000, 0x0800, CRC(549d15b3) SHA1(981962e5e05bbdc5a66b0e86870853ce5596e877)) -ROM_END - -ROM_START( watz19 ) - ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) - ROM_DEFAULT_BIOS("watzman-a") - - // Watzman ROM - ROM_SYSTEM_BIOS(0, "watzman", "Watzman") - ROMX_LOAD("watzman.u437", 0x0000, 0x1000, CRC(8168b6dc) SHA1(bfaebb9d766edbe545d24bc2b6630be4f3aa0ce9), ROM_BIOS(0)) - - ROM_SYSTEM_BIOS(1, "watzman-a", "Watzman w/clock persists after reset") - ROMX_LOAD("watzman-a.u437", 0x0000, 0x1000, CRC(1f7553e9) SHA1(ac6ddb12b4fb46c1a0ad08ee43978ad3153b51aa), ROM_BIOS(1)) - - // Original font - ROM_REGION( 0x0800, "chargen", 0 ) - ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) - - // Watzman keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "keybd.u445", 0x0000, 0x0800, CRC(58dc8217) SHA1(1b23705290bdf9fc6342065c6a528c04bff67b13)) -ROM_END - -ROM_START( ultra19 ) - // Ultra ROM - ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "2532_h19_ultra_firmware.u437", 0x0000, 0x1000, CRC(8ad4cdb4) SHA1(d6e1fc37a1f52abfce5e9adb1819e0030bed1df3)) - - // Original font - ROM_REGION( 0x0800, "chargen", 0 ) - ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) - - // Ultra keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "2716_h19_ultra_keyboard.u445", 0x0000, 0x0800, CRC(76130c92) SHA1(ca39c602af48505139d2750a084b5f8f0e662ff7)) -ROM_END - -ROM_START( gp19 ) - // GP-19 ROMs - ROM_REGION( 0x3000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "gp19_rom_1_ver_1_1.u26", 0x0000, 0x1000, CRC(7cbe8e0d) SHA1(977df895b067fa4e4646b4518cffb08d4e6bb6e0)) - ROM_LOAD( "gp19_rom_2_ver_1_1.u25", 0x1000, 0x1000, CRC(a85e3bc4) SHA1(f64e851c5d3ef98a9a48e0fc482baa576773ff43)) - ROM_LOAD( "gp19_rom_3_ver_1_1.u24", 0x2000, 0x1000, CRC(878f577c) SHA1(0756435914dcfb981de4e40d5f81af3e0f5bb1c5)) - - // GP-19 font - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "gp19_char_gen_cg_1.u21", 0x0000, 0x1000, CRC(49ec9242) SHA1(770a8c7b5b15bcfe465fd84326d0ae3dcaa85311)) - - // Original keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) -ROM_END - -ROM_START( imaginator ) - // Program code - ROM_REGION( 0x4000, "maincpu", ROMREGION_ERASEFF ) - // Original terminal code - ROM_LOAD( "2732_444-46_h19code.u437", 0x0000, 0x1000, CRC(f4447da0) SHA1(fb4093d5b763be21a9580a0defebed664b1f7a7b)) - // Imaginator ROMs - ROM_LOAD( "2732_imaginator_gpc_rev_1.2_pn_9000_0002.u9a", 0x2000, 0x1000, CRC(507bb13f) SHA1(5b210f8d77e22fdf063f611eb5c29636cdb01250)) - - // Original font - ROM_REGION( 0x0800, "chargen", 0 ) - ROM_LOAD( "2716_444-29_h19font.u420", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) - - // Original keyboard - ROM_REGION( 0x0800, "keyboard", 0 ) - ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) -ROM_END - - -ioport_constructor heath_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(tlb); -} - -const tiny_rom_entry *heath_tlb_device::device_rom_region() const -{ - return ROM_NAME(h19); -} - -void heath_tlb_device::serial_out_b(int data) -{ - m_slot->serial_out_b(data); -} - -void heath_tlb_device::dtr_out(int data) -{ - m_slot->dtr_out(data); -} - -void heath_tlb_device::rts_out(int data) -{ - m_slot->rts_out(data); -} - -void heath_tlb_device::serial_in_w(int state) -{ - m_ace->rx_w(state); -} - -void heath_tlb_device::rlsd_in_w(int state) -{ - m_ace->dcd_w(state); -} - -void heath_tlb_device::dsr_in_w(int state) -{ - m_ace->dsr_w(state); -} - -void heath_tlb_device::cts_in_w(int state) -{ - m_ace->cts_w(state); -} - -void heath_tlb_device::device_add_mconfig(machine_config &config) -{ - // basic machine hardware - Z80(config, m_maincpu, H19_CLOCK); - m_maincpu->set_addrmap(AS_PROGRAM, &heath_tlb_device::mem_map); - m_maincpu->set_addrmap(AS_IO, &heath_tlb_device::io_map); - - // video hardware - SCREEN(config, m_screen, SCREEN_TYPE_RASTER, rgb_t::green()); - // based on the H19 ROM code for 60 Hz - m_screen->set_raw(BASE_DOT_CLOCK, 768, 32, 672, 270, 0, 250); - m_screen->set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - - GFXDECODE(config, "gfxdecode", m_palette, gfx_h19); - PALETTE(config, "palette", palette_device::MONOCHROME); - - // MC 6845 uses a character clock, divide the DOT clock by 8. - MC6845(config, m_crtc, BASE_DOT_CLOCK / 8); - m_crtc->set_screen("screen"); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(8); - m_crtc->set_update_row_callback(FUNC(heath_tlb_device::crtc_update_row)); - // frame pulse - m_crtc->out_vsync_callback().set(FUNC(heath_tlb_device::crtc_vsync_w)); - - // serial port - INS8250(config, m_ace, INS8250_CLOCK); - m_ace->out_int_callback().set(FUNC(heath_tlb_device::serial_irq_w)); - m_ace->out_tx_callback().set(FUNC(heath_tlb_device::serial_out_b)); - m_ace->out_dtr_callback().set(FUNC(heath_tlb_device::dtr_out)); - m_ace->out_rts_callback().set(FUNC(heath_tlb_device::rts_out)); - - // keyboard - MM5740(config, m_mm5740, MM5740_CLOCK); - m_mm5740->x_cb<1>().set_ioport("X1"); - m_mm5740->x_cb<2>().set_ioport("X2"); - m_mm5740->x_cb<3>().set_ioport("X3"); - m_mm5740->x_cb<4>().set_ioport("X4"); - m_mm5740->x_cb<5>().set_ioport("X5"); - m_mm5740->x_cb<6>().set_ioport("X6"); - m_mm5740->x_cb<7>().set_ioport("X7"); - m_mm5740->x_cb<8>().set_ioport("X8"); - m_mm5740->x_cb<9>().set_ioport("X9"); - m_mm5740->shift_cb().set(FUNC(heath_tlb_device::mm5740_shift_r)); - m_mm5740->control_cb().set(FUNC(heath_tlb_device::mm5740_control_r)); - m_mm5740->data_ready_cb().set(FUNC(heath_tlb_device::mm5740_data_ready_w)); - - // sound hardware - SPEAKER(config, "mono").front_center(); - BEEP(config, m_beep, H19_BEEP_FRQ).add_route(ALL_OUTPUTS, "mono", 0.05); - - // clock for repeat key - CLOCK(config, m_repeat_clock, 40); - m_repeat_clock->set_duty_cycle(0); - m_repeat_clock->signal_handler().set(m_mm5740, FUNC(mm5740_device::repeat_line_w)); -} - - -/** - * Super-19 ROM - * - * Developed by ATG Systems - */ -heath_super19_tlb_device::heath_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_SUPER19, tag, owner, clock) -{ -} - -const tiny_rom_entry *heath_super19_tlb_device::device_rom_region() const -{ - return ROM_NAME(super19); -} - -ioport_constructor heath_super19_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(super19); -} - - -/** - * Superset ROM - * - * Developed by TMSI - */ -heath_superset_tlb_device::heath_superset_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_SUPERSET, tag, owner, clock), - m_selected_char_set(0) -{ -} - -void heath_superset_tlb_device::device_add_mconfig(machine_config &config) -{ - heath_tlb_device::device_add_mconfig(config); - - // part of the Superset upgrade was to upgrade the CPU to 3 MHz. - m_maincpu->set_clock(H19_3MHZ); - m_maincpu->set_addrmap(AS_PROGRAM, &heath_superset_tlb_device::mem_map); - m_maincpu->set_addrmap(AS_IO, &heath_superset_tlb_device::io_map); - - // per line updates are needed for onscreen menu to display properly - m_screen->set_video_attributes(VIDEO_UPDATE_SCANLINE); - - m_crtc->set_update_row_callback(FUNC(heath_superset_tlb_device::crtc_update_row)); - - // link up the serial port outputs to font chip. - m_ace->out_dtr_callback().set(FUNC(heath_superset_tlb_device::dtr_internal)); - m_ace->out_out1_callback().set(FUNC(heath_superset_tlb_device::out1_internal)); - m_ace->out_out2_callback().set(FUNC(heath_superset_tlb_device::out2_internal)); -} - -void heath_superset_tlb_device::device_start() -{ - heath_tlb_device::device_start(); - - save_item(NAME(m_selected_char_set)); - - m_selected_char_set = 0; -} - -void heath_superset_tlb_device::mem_map(address_map &map) -{ - heath_tlb_device::mem_map(map); - - // update rom space for the 16k ROM. - map(0x0000, 0x3fff).rom(); - - // page 2 memory - map(0x8000, 0x87ff).ram(); -} - -void heath_superset_tlb_device::io_map(address_map &map) -{ - heath_tlb_device::io_map(map); - - map(0x61, 0x61).mirror(0x12).select(0x0c).rw(FUNC(heath_superset_tlb_device::crtc_reg_r), FUNC(heath_superset_tlb_device::crtc_reg_w)); -} - -const tiny_rom_entry *heath_superset_tlb_device::device_rom_region() const -{ - return ROM_NAME(superset); -} - -ioport_constructor heath_superset_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(superset); -} - -u8 heath_superset_tlb_device::crtc_reg_r(offs_t reg) -{ - if (!machine().side_effects_disabled()) - { - m_reverse_video_disabled = bool(BIT(reg, 3)); - } - - return heath_tlb_device::crtc_reg_r(reg); -} - -void heath_superset_tlb_device::crtc_reg_w(offs_t reg, u8 val) -{ - m_reverse_video_disabled = bool(BIT(reg, 3)); - - heath_tlb_device::crtc_reg_w(reg, val); -} - -MC6845_UPDATE_ROW(heath_superset_tlb_device::crtc_update_row) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - - if (de) - { - for (int x = 0; x < x_count; x++) - { - u8 inv = (x == cursor_x) ? 0xff : 0; - u8 chr = m_p_videoram[(ma + x) & 0x7ff]; - u16 char_set_base_offset = (m_selected_char_set << 11); - - if (chr & 0x80) - { - if (m_reverse_video_disabled) - { - // set A13 - char_set_base_offset |= 0x2000; - } - else - { - inv ^= 0xff; - } - - chr &= 0x7f; - } - - // get pattern of pixels for the character scanline - u8 const gfx = m_p_chargen[char_set_base_offset | (chr << 4) | ra] ^ inv; - - // Display a scanline of a character (8 pixels) - for (int b = 0; 8 > b; ++b) - { - *p++ = palette[BIT(gfx, b)]; - } - } - } - else - { - std::fill_n(p, bitmap.rowpixels(), palette[0]); - } -} - -// DTR (pin 33) to A14 (pin 27) of 27256 ROM -void heath_superset_tlb_device::dtr_internal(int data) -{ - m_selected_char_set = (m_selected_char_set & 0x03) | ((data & 0x01) << 3); -} - -// OUT1 (pin 34) to A12 (pin 2) of 27256 ROM -void heath_superset_tlb_device::out1_internal(int data) -{ - m_selected_char_set = (m_selected_char_set & 0x09) | ((data & 0x01) << 1); -} - -// OUT2 (pin 31) to A11? on board -void heath_superset_tlb_device::out2_internal(int data) -{ - m_selected_char_set = (m_selected_char_set & 0x0a) | (data & 0x01); -} - - -/** - * Watzman ROM - * - * Developed by Barry Watzman, sold by HUG (Heath Users Group) -*/ -heath_watz_tlb_device::heath_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_WATZ, tag, owner, clock) -{ -} - -const tiny_rom_entry *heath_watz_tlb_device::device_rom_region() const -{ - return ROM_NAME(watz19); -} - -ioport_constructor heath_watz_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(watz19); -} - - -/** - * UltraROM - * - * Developed by William G. Parrott, III, sold by Software Wizardry, Inc. - */ -heath_ultra_tlb_device::heath_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_ULTRA, tag, owner, clock) -{ -} - -void heath_ultra_tlb_device::device_add_mconfig(machine_config &config) -{ - heath_tlb_device::device_add_mconfig(config); - - m_maincpu->set_addrmap(AS_PROGRAM, &heath_ultra_tlb_device::mem_map); -} - -void heath_ultra_tlb_device::mem_map(address_map &map) -{ - heath_tlb_device::mem_map(map); - - // update rom mirror setting to allow page 2 memory - map(0x0000, 0x0fff).mirror(0x2000).rom(); - - // Page 2 memory - map(0x1000, 0x1fff).mirror(0x2000).ram(); -} - -const tiny_rom_entry *heath_ultra_tlb_device::device_rom_region() const -{ - return ROM_NAME(ultra19); -} - -ioport_constructor heath_ultra_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(ultra19); -} - - -/** - * Northwest Digital Systems GP-19 add-in board - */ -heath_gp19_tlb_device::heath_gp19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_GP19, tag, owner, clock) -{ -} - -void heath_gp19_tlb_device::device_add_mconfig(machine_config &config) -{ - heath_tlb_device::device_add_mconfig(config); - - m_maincpu->set_addrmap(AS_PROGRAM, &heath_gp19_tlb_device::mem_map); - m_maincpu->set_addrmap(AS_IO, &heath_gp19_tlb_device::io_map); - - m_crtc->set_update_row_callback(FUNC(heath_gp19_tlb_device::crtc_update_row)); - m_crtc->set_clock(GP19_DOT_CLOCK_2 / 8); - - m_screen->set_raw(GP19_DOT_CLOCK_2, 776, 32, 672, 264, 10, 250); -} - -void heath_gp19_tlb_device::device_start() -{ - heath_tlb_device::device_start(); - - save_item(NAME(m_char_gen_a11)); - save_item(NAME(m_graphic_mode)); - save_item(NAME(m_col_132)); - save_item(NAME(m_reverse_video)); - - m_char_gen_a11 = false; - m_graphic_mode = false; - m_col_132 = false; - m_reverse_video = false; -} - -void heath_gp19_tlb_device::mem_map(address_map &map) -{ - // ROMs 1, 2, 3 - map(0x0000, 0x02fff).rom(); - - // Optional external board - Program ROM 4(not aware if any ever existed), external I/O - // map(0x3000, 0x03fff).rom(); - - map(0x4000, 0x40ff).mirror(0x3f00).ram(); - map(0x6000, 0x67ff).mirror(0x1800).ram(); - map(0x8000, 0xbfff).mirror(0x4000).ram().share(m_p_videoram); -} - -void heath_gp19_tlb_device::io_map(address_map &map) -{ - heath_tlb_device::io_map(map); - - // Latch U5 - map(0x68, 0x68).mirror(0x07).w(FUNC(heath_gp19_tlb_device::latch_u5_w)); - - // Switch on GP-19 board - map(0x70, 0x70).mirror(0x07).portr("SW1"); - - // Optional Auxiliary I/O connector(not aware if any ever existed) - // map(0x78, 0x78).mirror(0x07); -} - -/** - * U5 Latch - * - * Q0 Graph/character H - * Q1 132/80 columns H - * Q2 Reverse Screen H - * Q3 Alt Character L - * Q4-Q7 LED indicators (debug LEDs on circuit board) - */ -void heath_gp19_tlb_device::latch_u5_w(u8 data) -{ - m_graphic_mode = bool(BIT(data, 0)); - m_col_132 = bool(BIT(data, 1)); - m_reverse_video = bool(BIT(data, 2)); - m_char_gen_a11 = bool(BIT(data, 3)); - - // TODO handle LED indicators - - if (m_graphic_mode) - { - m_crtc->set_clock(GP19_DOT_CLOCK_3 / 8); - } - else if (m_col_132) - { - m_crtc->set_clock(GP19_DOT_CLOCK_1 / 8); - } - else - { - m_crtc->set_clock(GP19_DOT_CLOCK_2 / 8); - } -} - -MC6845_UPDATE_ROW(heath_gp19_tlb_device::crtc_update_row) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - - if (de) - { - u8 screen_inv = m_reverse_video ? 0xff : 0x00; - - if (m_graphic_mode) - { - for (int x = 0; x < x_count; x++) - { - u8 const gfx = m_p_videoram[((ma << 1) + (ra * x_count) + x) & 0x3fff] ^ screen_inv; - - for (int b = 0; 8 > b; ++b) - { - *p++ = palette[BIT(gfx, b)]; - } - } - } - else - { - u16 const base = m_char_gen_a11 ? 0x800 : 0x0; - - for (int x = 0; x < x_count; x++) - { - u8 inv = (x == cursor_x) ? 0xff : 0; - u8 chr = m_p_videoram[(ma + x) & 0x3fff]; - - if (chr & 0x80) - { - inv ^= 0xff; - chr &= 0x7f; - } - - inv ^= screen_inv; - - // select proper character set - u8 const gfx = m_p_chargen[base | (chr << 4) | ra] ^ inv; - - // Display a scanline of a character (8 pixels) - for (int b = 0; 8 > b; ++b) - { - *p++ = palette[BIT(gfx, b)]; - } - } - } - } - else - { - std::fill_n(p, x_count * 8, palette[0]); - } -} - -const tiny_rom_entry *heath_gp19_tlb_device::device_rom_region() const -{ - return ROM_NAME(gp19); -} - -ioport_constructor heath_gp19_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(gp19); -} - - -/** - * Cleveland Codonics Imaginator-100 (I-100) add-in board - * - * Memory Range Description - * ----------------------------------------------------------------- - * 0x0000-0x1fff Program ROM (Heath TLB board) - * 0x2000-0x3fff Graphics Command Processor(GCP) ROM (I-100) - * 0x4000-0x5fff Scratchpad RAM (Heath TLB board) - * 0x6000-0x7fff Graphics Scratchpad R/W RAM (I-100) - * 0x8000-0xbfff Graphics Display R/W RAM(I-100) - * 0xc000-0xdfff Optional Graphics Command Processor memory (I-100) - * 0xe000-0xffff Display Memory (Heath TLB board) - * - * New interrupt source - * - horizontal retrace interrupt - * - */ -heath_imaginator_tlb_device::heath_imaginator_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_IMAGINATOR, tag, owner, clock), - m_mem_bank(*this, "membank"), - m_p_graphic_ram(*this, "graphicram") -{ -} - -void heath_imaginator_tlb_device::device_add_mconfig(machine_config &config) -{ - heath_tlb_device::device_add_mconfig(config); - - m_maincpu->set_addrmap(AS_PROGRAM, &heath_imaginator_tlb_device::mem_map); - m_maincpu->set_addrmap(AS_IO, &heath_imaginator_tlb_device::io_map); - m_maincpu->set_irq_acknowledge_callback(FUNC(heath_imaginator_tlb_device::irq_ack_cb)); - - m_crtc->out_hsync_callback().set(FUNC(heath_imaginator_tlb_device::crtc_hsync_w)); -} - -void heath_imaginator_tlb_device::device_start() -{ - heath_tlb_device::device_start(); - - save_item(NAME(m_im2_val)); - save_item(NAME(m_alphanumeric_mode_active)); - save_item(NAME(m_graphics_mode_active)); - save_item(NAME(m_allow_tlb_interrupts)); - save_item(NAME(m_allow_imaginator_interrupts)); - save_item(NAME(m_hsync_irq_raised)); - - m_mem_bank->configure_entries(0, 2, memregion("maincpu")->base(), 0x2000); - - m_maincpu->space(AS_PROGRAM).install_readwrite_tap(0x8000, 0xbfff, "irq_update", - [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_8000h(); } }, - [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_8000h(); } }); -} - -void heath_imaginator_tlb_device::device_reset() -{ - heath_tlb_device::device_reset(); - - m_mem_bank->set_entry(1); - m_tap_6000h.remove(); - m_tap_6000h = m_maincpu->space(AS_PROGRAM).install_readwrite_tap(0x6000, 0x7fff, "mem_map_update", - [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_6000h(); } }, - [this] (offs_t offset, u8 &data, u8 mem_mask) { if (!machine().side_effects_disabled()) { tap_6000h(); } }); - - m_alphanumeric_mode_active = true; - m_graphics_mode_active = false; - - m_hsync_irq_raised = false; - - allow_tlb_intr(); -} - -void heath_imaginator_tlb_device::mem_map(address_map &map) -{ - map.unmap_value_high(); - - map(0x0000, 0x1fff).bankr(m_mem_bank); - - // Normal spot of the GCP ROM - map(0x2000, 0x3fff).rom(); - - // TLB Scratchpad - map(0x4000, 0x40ff).mirror(0x1f00).ram(); - - // GCP Scratchpad - map(0x6000, 0x607f).mirror(0x1f80).ram(); - - // Graphics RAM - map(0x8000, 0xbfff).ram().share(m_p_graphic_ram); - - // optional Graphics Command Processor (GCP) - // map(0xc000, 0xdfff); - - // Alphanumeric RAM - map(0xe000, 0xe7ff).mirror(0x1800).ram().share(m_p_videoram); -} - -void heath_imaginator_tlb_device::tap_6000h() -{ - m_mem_bank->set_entry(0); - m_tap_6000h.remove(); -} - -void heath_imaginator_tlb_device::tap_8000h() -{ - if (!m_allow_tlb_interrupts) - { - allow_tlb_intr(); - - set_irq_line(); - } -} - -void heath_imaginator_tlb_device::allow_tlb_intr() -{ - m_allow_tlb_interrupts = true; - m_allow_imaginator_interrupts = false; - m_im2_val = 0x02; -} - -void heath_imaginator_tlb_device::allow_hsync_intr() -{ - m_allow_tlb_interrupts = false; - m_allow_imaginator_interrupts = true; - m_im2_val = 0x00; -} - -/** - * An input/output request (IORQ) is sent to the TERMINAL LOGIC board only when - * both IORQ (pin 20 of U7) AND A4 are low. - */ -void heath_imaginator_tlb_device::io_map(address_map &map) -{ - heath_tlb_device::io_map(map); - - // interrupt routing - map(0x10, 0x10).select(0x08).mirror(0x07).w(FUNC(heath_imaginator_tlb_device::config_irq_w)); - - // display enabling (graphics or alphanumeric) - map(0x30, 0x30).select(0xc0).mirror(0x0f).w(FUNC(heath_imaginator_tlb_device::display_enable_w)); - - // Avoids writes to TLB when a4 is high on unused - map(0x50, 0x50).select(0x80).mirror(0x0f).w(FUNC(heath_imaginator_tlb_device::nop_w)); -} - -IRQ_CALLBACK_MEMBER(heath_imaginator_tlb_device::irq_ack_cb) -{ - return m_im2_val; -} - -void heath_imaginator_tlb_device::config_irq_w(offs_t reg, u8 val) -{ - if (BIT(reg, 3)) - { - allow_tlb_intr(); - } - else - { - allow_hsync_intr(); - } - - set_irq_line(); -} - -void heath_imaginator_tlb_device::display_enable_w(offs_t reg, u8 val) -{ - m_alphanumeric_mode_active = bool(BIT(reg, 7)); - m_graphics_mode_active = bool(BIT(reg, 6)); -} - -void heath_imaginator_tlb_device::nop_w(offs_t, u8) -{ -} - -const tiny_rom_entry *heath_imaginator_tlb_device::device_rom_region() const -{ - return ROM_NAME(imaginator); -} - -MC6845_UPDATE_ROW(heath_imaginator_tlb_device::crtc_update_row) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - - if (de) - { - for (int x = 0; x < x_count; x++) - { - u8 output = 0x00; - - if (m_alphanumeric_mode_active) - { - u8 inv = (x == cursor_x) ? 0xff : 0; - u8 chr = m_p_videoram[(ma + x) & 0x7ff]; - - if (chr & 0x80) - { - inv ^= 0xff; - chr &= 0x7f; - } - - output |= m_p_chargen[(chr << 4) | ra] ^ inv; - } - - if (m_graphics_mode_active && (x > 7 ) && (x < 73)) - { - output |= m_p_graphic_ram[((y * 64) + (x - 8)) & 0x3fff]; - } - - for (int b = 0; 8 > b; ++b) - { - *p++ = palette[BIT(output, b)]; - } - } - } - else - { - std::fill_n(p, x_count * 8, palette[0]); - } -} - -void heath_imaginator_tlb_device::crtc_hsync_w(int val) -{ - m_hsync_irq_raised = bool(val); - - set_irq_line(); -} - -void heath_imaginator_tlb_device::set_irq_line() -{ - m_maincpu->set_input_line(INPUT_LINE_IRQ0, - (m_allow_imaginator_interrupts && m_hsync_irq_raised) || - (m_allow_tlb_interrupts && (m_keyboard_irq_raised || m_serial_irq_raised || m_break_key_irq_raised)) ? - ASSERT_LINE : CLEAR_LINE); -} - - -/** - * SigmaSoft Interactive Graphics Controller (IGC) - * - * - */ -heath_igc_tlb_device::heath_igc_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, HEATH_IGC, tag, owner, clock) -{ -} - -heath_igc_tlb_device::heath_igc_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : - heath_tlb_device(mconfig, type, tag, owner, clock) -{ -} - -void heath_igc_tlb_device::device_add_mconfig(machine_config &config) -{ - heath_tlb_device::device_add_mconfig(config); - - m_crtc->set_update_row_callback(FUNC(heath_igc_tlb_device::crtc_update_row)); -} - -void heath_igc_tlb_device::device_start() -{ - heath_tlb_device::device_start(); - - m_p_graphic_ram = make_unique_clear(0x3ffff); - save_pointer(NAME(m_p_graphic_ram), 0x3ffff); - - save_item(NAME(m_data_reg)); - save_item(NAME(m_pixel_video_enabled)); - save_item(NAME(m_character_video_disabled)); - save_item(NAME(m_video_invert_enabled)); - save_item(NAME(m_alternate_character_set_enabled)); - save_item(NAME(m_video_fill_enabled)); - save_item(NAME(m_read_address_increment_disabled)); - save_item(NAME(m_memory_bank_select)); - save_item(NAME(m_io_address)); - save_item(NAME(m_window_address)); -} - -void heath_igc_tlb_device::device_reset() -{ - heath_tlb_device::device_reset(); - - sigma_ctrl_w(0); - m_data_reg = 0x00; - m_io_address = 0x0000; - m_window_address = 0x0000; -} - -void heath_igc_tlb_device::sigma_ctrl_w(u8 data) -{ - LOGREG("%s: data: %02x\n", FUNCNAME, data); - - m_pixel_video_enabled = bool(BIT(data, 0)); - m_character_video_disabled = bool(BIT(data, 1)); - m_video_invert_enabled = bool(BIT(data, 2)); - m_alternate_character_set_enabled = bool(BIT(data, 3)); - m_video_fill_enabled = bool(BIT(data, 4)); - m_read_address_increment_disabled = bool(BIT(data, 5)); - - m_memory_bank_select = bitswap<2>(data, 6, 7); - - if (m_video_fill_enabled) - { - std::fill_n(&m_p_graphic_ram[(m_memory_bank_select << 16) & 0x3ffff], 0x10000, m_data_reg); - } -} - -u8 heath_igc_tlb_device::sigma_ctrl_r() -{ - u8 ret_val = 0x00; - - ret_val |= m_pixel_video_enabled ? 0x01 : 0x00; - ret_val |= m_character_video_disabled ? 0x02 : 0x00; - ret_val |= m_video_invert_enabled ? 0x04 : 0x00; - ret_val |= m_alternate_character_set_enabled ? 0x08 : 0x00; - ret_val |= m_video_fill_enabled ? 0x10 : 0x00; - ret_val |= m_read_address_increment_disabled ? 0x20 : 0x00; - - ret_val |= bitswap<2>(m_memory_bank_select, 0, 1) << 6; - - LOGREG("%s: ret_val: %02x\n", FUNCNAME, ret_val); - - return ret_val; -} - -void heath_igc_tlb_device::sigma_video_mem_w(u8 data) -{ - LOGREG("%s: data: %02x\n", FUNCNAME, data); - - m_data_reg = data; - - m_p_graphic_ram[(m_memory_bank_select << 16) + m_io_address++] = data; -} - -u8 heath_igc_tlb_device::sigma_video_mem_r() -{ - // control whether m_io_address is incremented during a read - u32 addr = (m_read_address_increment_disabled || machine().side_effects_disabled()) ? - ((m_memory_bank_select << 16) + m_io_address) : - ((m_memory_bank_select << 16) + m_io_address++); - - return m_p_graphic_ram[addr]; -} - -void heath_igc_tlb_device::sigma_io_lo_addr_w(u8 data) -{ - LOGREG("%s: data: %02x\n", FUNCNAME, data); - - m_io_address = (m_io_address & 0xff00) | data; -} - -void heath_igc_tlb_device::sigma_io_hi_addr_w(u8 data) -{ - LOGREG("%s: data: %02x\n", FUNCNAME, data); - - m_io_address = (data << 8) | (m_io_address & 0x00ff); -} - -void heath_igc_tlb_device::sigma_window_lo_addr_w(u8 data) -{ - LOGREG("%s: data: %02x\n", FUNCNAME, data); - - m_window_address = (m_window_address & 0xff00) | data; -} - -void heath_igc_tlb_device::sigma_window_hi_addr_w(u8 data) -{ - LOGREG("%s: data: %02x\n", FUNCNAME, data); - - m_window_address = (data << 8) | (m_window_address & 0x00ff); -} - -MC6845_UPDATE_ROW(heath_igc_tlb_device::crtc_update_row) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - - if (de) - { - u8 video_invert = m_video_invert_enabled ? 0xff : 0; - - for (int x = 0; x < x_count; x++) - { - u8 output = 0x00; - - if (!m_character_video_disabled) - { - u8 inv = (x == cursor_x) ? 0xff : 0; - u8 chr = m_p_videoram[(ma + x) & 0x7ff]; - - if (chr & 0x80) - { - inv ^= 0xff; - chr &= 0x7f; - } - - // TODO handle alt font - output |= m_p_chargen[(chr << 4) | ra] ^ inv; - } - - if (m_pixel_video_enabled) - { - output |= m_p_graphic_ram[(((y * 80) + x) + m_window_address) & 0xffff]; - } - - output ^= video_invert; - - for (int b = 0; 8 > b; ++b) - { - *p++ = palette[BIT(output, b)]; - } - } - } - else - { - std::fill_n(p, x_count * 8, palette[0]); - } -} - - -/** - * SigmaSoft and Systems IGC plus TLB with Super-19 ROM - * - */ -heath_igc_super19_tlb_device::heath_igc_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_igc_tlb_device(mconfig, HEATH_IGC_SUPER19, tag, owner, clock) -{ -} - -const tiny_rom_entry *heath_igc_super19_tlb_device::device_rom_region() const -{ - return ROM_NAME(super19); -} - -ioport_constructor heath_igc_super19_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(super19); -} - - -/** - * SigmaSoft and Systems IGC plus TLB with UltraROM - * - */ -heath_igc_ultra_tlb_device::heath_igc_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_igc_tlb_device(mconfig, HEATH_IGC_ULTRA, tag, owner, clock) -{ -} - -void heath_igc_ultra_tlb_device::device_add_mconfig(machine_config &config) -{ - heath_tlb_device::device_add_mconfig(config); - - m_maincpu->set_addrmap(AS_PROGRAM, &heath_igc_ultra_tlb_device::mem_map); -} - -void heath_igc_ultra_tlb_device::mem_map(address_map &map) -{ - heath_tlb_device::mem_map(map); - - // update rom mirror setting to allow page 2 memory - map(0x0000, 0x0fff).mirror(0x2000).rom(); - - // Page 2 memory - map(0x1000, 0x1fff).mirror(0x2000).ram(); -} - -const tiny_rom_entry *heath_igc_ultra_tlb_device::device_rom_region() const -{ - return ROM_NAME(ultra19); -} - -ioport_constructor heath_igc_ultra_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(ultra19); -} - - -/** - * SigmaSoft and Systems IGC plus TLB with Watzman ROM - * - */ -heath_igc_watz_tlb_device::heath_igc_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - heath_igc_tlb_device(mconfig, HEATH_IGC_WATZ, tag, owner, clock) -{ -} - -const tiny_rom_entry *heath_igc_watz_tlb_device::device_rom_region() const -{ - return ROM_NAME(watz19); -} - -ioport_constructor heath_igc_watz_tlb_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(watz19); -} - - -/** - * Terminal Logic Board Connector - * - */ -heath_tlb_connector::heath_tlb_connector(const machine_config &mconfig, const char *tag, device_t *owner, u32 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/heathzenith/tlb.h b/src/mame/heathzenith/tlb.h deleted file mode 100644 index b0ed5ba31ef..00000000000 --- a/src/mame/heathzenith/tlb.h +++ /dev/null @@ -1,477 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mark Garlanger -/*************************************************************************** - - Heathkit Terminal Logic Board (TLB) - -****************************************************************************/ - -#ifndef MAME_HEATHZENITH_TLB_H -#define MAME_HEATHZENITH_TLB_H - -#pragma once - -#include "cpu/z80/z80.h" -#include "machine/clock.h" -#include "machine/ins8250.h" -#include "machine/mm5740.h" -#include "sound/beep.h" -#include "video/mc6845.h" - -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - - -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) {} - - // optional SigmaSet operations - virtual void sigma_ctrl_w(u8 data) {} - virtual u8 sigma_ctrl_r() { return 0x00; } - virtual u8 sigma_video_mem_r() { return 0x00; } - virtual void sigma_video_mem_w(u8 val) {} - virtual void sigma_io_lo_addr_w(u8 val) {} - virtual void sigma_io_hi_addr_w(u8 val) {} - virtual void sigma_window_lo_addr_w(u8 val) {} - virtual void sigma_window_hi_addr_w(u8 val) {} - -protected: - 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, u32 clock = 0); - - // 8250 UART - 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 serial_irq_w(int state); - - // Keyboard - void reset_key_w(int state); - void right_shift_w(int state); - void repeat_key_w(int state); - void break_key_w(int state); - -protected: - heath_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); - - virtual ioport_constructor device_input_ports() const override ATTR_COLD; - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - void mem_map(address_map &map) ATTR_COLD; - void io_map(address_map &map) ATTR_COLD; - - - // interrupt related - virtual void set_irq_line(); - - // reset - void check_for_reset(); - - // sound/speaker - void check_beep_state(); - void key_click_w(u8 data); - void bell_w(u8 data); - TIMER_CALLBACK_MEMBER(key_click_off); - TIMER_CALLBACK_MEMBER(bell_off); - - // keyboard - u8 kbd_key_r(); - u8 kbd_flags_r(); - u16 translate_mm5740_b(u16 b); - int mm5740_shift_r(); - int mm5740_control_r(); - void mm5740_data_ready_w(int state); - - // serial port - void serial_out_b(int data); - void dtr_out(int data); - void rts_out(int data); - - // crtc - void crtc_addr_w(offs_t reg, u8 val); - virtual u8 crtc_reg_r(offs_t reg); - virtual void crtc_reg_w(offs_t reg, u8 val); - void crtc_vsync_w(int val); - virtual MC6845_UPDATE_ROW(crtc_update_row); - - required_device m_maincpu; - required_device m_screen; - required_device m_palette; - required_device m_crtc; - required_shared_ptr m_p_videoram; - required_region_ptr m_p_chargen; - required_ioport m_config; - required_device m_ace; - required_device m_beep; - required_device m_mm5740; - required_memory_region m_kbdrom; - required_ioport m_kbspecial; - required_device m_repeat_clock; - - emu_timer *m_key_click_timer; - emu_timer *m_bell_timer; - - u8 m_transchar; - bool m_strobe; - bool m_key_click_active; - bool m_bell_active; - bool m_reset_pending; - bool m_right_shift; - bool m_reset_key; - bool m_keyboard_irq_raised; - bool m_serial_irq_raised; - bool m_break_key_irq_raised; - bool m_allow_vsync_nmi; -}; - -/** - * Heath TLB with Super19 ROM - */ -class heath_super19_tlb_device : public heath_tlb_device -{ -public: - heath_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; -}; - -/** - * Heath TLB with Superset ROM - */ -class heath_superset_tlb_device : public heath_tlb_device -{ -public: - heath_superset_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; - - virtual void device_start() override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - void mem_map(address_map &map) ATTR_COLD; - void io_map(address_map &map) ATTR_COLD; - - virtual MC6845_UPDATE_ROW(crtc_update_row) override; - - void dtr_internal(int data); - void out1_internal(int data); - void out2_internal(int data); - - virtual u8 crtc_reg_r(offs_t reg) override; - virtual void crtc_reg_w(offs_t reg, u8 val) override; - - u8 m_selected_char_set; - bool m_reverse_video_disabled; -}; - -/** - * Heath TLB with Watzman (HUG) ROM - */ -class heath_watz_tlb_device : public heath_tlb_device -{ -public: - heath_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; -}; - -/** - * Heath TLB with Ultra ROM - */ -class heath_ultra_tlb_device : public heath_tlb_device -{ -public: - heath_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - void mem_map(address_map &map) ATTR_COLD; -}; - -/** - * 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, u32 clock = 0); - - static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; - - virtual void device_start() override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - void mem_map(address_map &map) ATTR_COLD; - void io_map(address_map &map) ATTR_COLD; - - void latch_u5_w(u8 data); - - virtual MC6845_UPDATE_ROW(crtc_update_row) override; - - bool m_char_gen_a11; - bool m_graphic_mode; - bool m_col_132; - bool m_reverse_video; -}; - -/** - * Heath TLB plus Cleveland Codonics Imaginator-100 - */ -class heath_imaginator_tlb_device : public heath_tlb_device -{ -public: - heath_imaginator_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - void mem_map(address_map &map) ATTR_COLD; - void io_map(address_map &map) ATTR_COLD; - - virtual MC6845_UPDATE_ROW(crtc_update_row) override; - void crtc_hsync_w(int val); - - IRQ_CALLBACK_MEMBER(irq_ack_cb); - - void tap_6000h(); - void tap_8000h(); - - void allow_tlb_intr(); - void allow_hsync_intr(); - - void display_enable_w(offs_t reg, u8 val); - void config_irq_w(offs_t reg, u8 val); - void nop_w(offs_t reg, u8 val); - virtual void set_irq_line() override; - - required_memory_bank m_mem_bank; - required_shared_ptr m_p_graphic_ram; - memory_passthrough_handler m_tap_6000h; - - u8 m_im2_val; - - bool m_alphanumeric_mode_active; - bool m_graphics_mode_active; - - bool m_allow_tlb_interrupts; - bool m_allow_imaginator_interrupts; - - bool m_hsync_irq_raised; -}; - -/** - * Heath TLB plus SigmaSoft Interactive Graphics Controller - */ -class heath_igc_tlb_device : public heath_tlb_device -{ -public: - heath_igc_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - - virtual void sigma_ctrl_w(u8 data) override; - virtual u8 sigma_ctrl_r() override; - - virtual u8 sigma_video_mem_r() override; - virtual void sigma_video_mem_w(u8 val) override; - - virtual void sigma_io_lo_addr_w(u8 val) override; - virtual void sigma_io_hi_addr_w(u8 val) override; - - virtual void sigma_window_lo_addr_w(u8 val) override; - virtual void sigma_window_hi_addr_w(u8 val) override; - -protected: - heath_igc_tlb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); - - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - virtual MC6845_UPDATE_ROW(crtc_update_row) override; - - std::unique_ptr m_p_graphic_ram; - - // Control Register - bool m_pixel_video_enabled; - bool m_character_video_disabled; - bool m_video_invert_enabled; - bool m_alternate_character_set_enabled; - bool m_video_fill_enabled; - bool m_read_address_increment_disabled; - u8 m_memory_bank_select; - - u8 m_data_reg; - - u16 m_io_address; - u16 m_window_address; -}; - -/** - * Heath TLB with the super19 ROM plus SigmaSoft Interactive Graphics Controller - */ -class heath_igc_super19_tlb_device : public heath_igc_tlb_device -{ -public: - heath_igc_super19_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; -}; - -/** - * Heath TLB with the ultrarom plus SigmaSoft Interactive Graphics Controller - */ -class heath_igc_ultra_tlb_device : public heath_igc_tlb_device -{ -public: - heath_igc_ultra_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; - virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - - void mem_map(address_map &map) ATTR_COLD; -}; - -/** - * Heath TLB with the watzman ROM plus SigmaSoft Interactive Graphics Controller - */ -class heath_igc_watz_tlb_device : public heath_igc_tlb_device -{ -public: - heath_igc_watz_tlb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - -protected: - virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; - virtual ioport_constructor device_input_ports() const override ATTR_COLD; -}; - -// Options for the standard H89 class of systems -DECLARE_DEVICE_TYPE(HEATH_TLB, heath_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_GP19, heath_gp19_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_IMAGINATOR, heath_imaginator_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_SUPER19, heath_super19_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_SUPERSET, heath_superset_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_WATZ, heath_watz_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_ULTRA, heath_ultra_tlb_device) - -// Options for the H89 with the SigmaSoft IGC graphics installed -DECLARE_DEVICE_TYPE(HEATH_IGC, heath_igc_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_IGC_SUPER19, heath_igc_super19_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_IGC_ULTRA, heath_igc_ultra_tlb_device) -DECLARE_DEVICE_TYPE(HEATH_IGC_WATZ, heath_igc_watz_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, u32 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); } - - // signals out from the tlb - 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); } - - // optional SigmaSet IGC operations - u8 sigma_ctrl_r() { return (m_tlb) ? m_tlb->sigma_ctrl_r() : 0x00; } - void sigma_ctrl_w(u8 data) { if (m_tlb) m_tlb->sigma_ctrl_w(data); } - - u8 sigma_video_mem_r() { return (m_tlb) ? m_tlb->sigma_video_mem_r() : 0x00; } - void sigma_video_mem_w(u8 val) { if (m_tlb) m_tlb->sigma_video_mem_w(val); } - - void sigma_io_lo_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_io_lo_addr_w(val); } - void sigma_io_hi_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_io_hi_addr_w(val); } - - void sigma_window_lo_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_window_lo_addr_w(val); } - void sigma_window_hi_addr_w(u8 val) { if (m_tlb) m_tlb->sigma_window_hi_addr_w(val); } - -protected: - virtual void device_start() override ATTR_COLD; - - 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_HEATHZENITH_TLB_H -- cgit v1.2.3