mirror of
https://github.com/holub/mame
synced 2025-04-19 07:00:31 +03:00
New working machines
-------------------- MDT 60 Video Display Terminal [Bitsavers, AJR] z29: Add skeleton for undumped keyboard; try (and fail) to make this work with the MDT 60 keyboard instead z22: Separate driver (nw)
This commit is contained in:
parent
b403d9be2d
commit
9556e3a5bd
@ -2198,6 +2198,23 @@ if (BUSES["WANGPC"]~=null) then
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/z29_kbd/keyboard.h,BUSES["Z29_KBD"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (BUSES["Z29_KBD"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/z29_kbd/keyboard.cpp",
|
||||
MAME_DIR .. "src/devices/bus/z29_kbd/keyboard.h",
|
||||
MAME_DIR .. "src/devices/bus/z29_kbd/he191_3425.cpp",
|
||||
MAME_DIR .. "src/devices/bus/z29_kbd/he191_3425.h",
|
||||
MAME_DIR .. "src/devices/bus/z29_kbd/md_kbd.cpp",
|
||||
MAME_DIR .. "src/devices/bus/z29_kbd/md_kbd.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/z88/z88.h,BUSES["Z88"] = true
|
||||
|
@ -918,6 +918,7 @@ BUSES["VTECH_MEMEXP"] = true
|
||||
BUSES["WANGPC"] = true
|
||||
BUSES["WSWAN"] = true
|
||||
BUSES["X68K"] = true
|
||||
BUSES["Z29_KBD"] = true
|
||||
BUSES["Z88"] = true
|
||||
BUSES["ZORRO"] = true
|
||||
|
||||
@ -4179,6 +4180,7 @@ createMESSProjects(_target, _subtarget, "zenith")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/mdt60.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/z100.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/z22.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/z29.cpp",
|
||||
}
|
||||
|
||||
|
240
src/devices/bus/z29_kbd/he191_3425.cpp
Normal file
240
src/devices/bus/z29_kbd/he191_3425.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Heath HE 191-3425 keyboard
|
||||
|
||||
This 91-key detached keyboard is standard issue for the H-29 (Z-29)
|
||||
terminal. It is also specified for the MDT 60 in its schematics.
|
||||
|
||||
Since the 8021 MCU is not dumped, emulation is more or less a stub.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "he191_3425.h"
|
||||
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "machine/rescap.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(HE191_3425, he191_3425_device, "he191_3425", "Heath HE 191-3425 Keyboard")
|
||||
|
||||
he191_3425_device::he191_3425_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, HE191_3425, tag, owner, clock)
|
||||
, device_z29_keyboard_interface(mconfig, *this)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_buzzer(*this, "buzzer")
|
||||
, m_matrix(*this, {"B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B11", "B13", "B14"})
|
||||
, m_modifiers(*this, "MODIFIERS")
|
||||
, m_leds(*this, "led%u", 1U)
|
||||
, m_select(0)
|
||||
, m_recv_data(true)
|
||||
{
|
||||
}
|
||||
|
||||
void he191_3425_device::device_resolve_objects()
|
||||
{
|
||||
m_leds.resolve();
|
||||
}
|
||||
|
||||
void he191_3425_device::device_start()
|
||||
{
|
||||
m_leds[0] = 1; // L1: Power
|
||||
|
||||
save_item(NAME(m_select));
|
||||
save_item(NAME(m_recv_data));
|
||||
}
|
||||
|
||||
void he191_3425_device::receive_data(bool state)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(he191_3425_device::receive_data_synced), this), state);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(he191_3425_device::receive_data_synced)
|
||||
{
|
||||
m_recv_data = param;
|
||||
}
|
||||
|
||||
u8 he191_3425_device::mcu_pa_r()
|
||||
{
|
||||
return m_select < 12 ? m_matrix[m_select]->read() : 0xff;
|
||||
}
|
||||
|
||||
void he191_3425_device::mcu_pb_w(u8 data)
|
||||
{
|
||||
transmit_data(!BIT(data, 3));
|
||||
m_leds[1] = !BIT(data, 4); // L2: Keyboard Lock
|
||||
m_leds[2] = !BIT(data, 5); // L3: Off/Line
|
||||
m_leds[3] = !BIT(data, 6); // L4: Caps Lock
|
||||
m_buzzer->set_state(BIT(data, 7));
|
||||
}
|
||||
|
||||
void he191_3425_device::mcu_pc_w(u8 data)
|
||||
{
|
||||
m_select = data & 0xf;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(he191_3425_device::mcu_t1_r)
|
||||
{
|
||||
return m_recv_data;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(he191_3425_device::shift_reset)
|
||||
{
|
||||
m_mcu->set_input_line(INPUT_LINE_RESET, (m_modifiers->read() & 0x06) != 0x00 ? CLEAR_LINE : ASSERT_LINE);
|
||||
reset_from_keyboard((m_modifiers->read() & 0x06) != 0x00);
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START(he191_3425)
|
||||
PORT_START("B1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('`') PORT_CHAR('~') PORT_CODE(KEYCODE_BACKSLASH)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR(')') PORT_CODE(KEYCODE_0)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH)
|
||||
|
||||
PORT_START("B2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 3 DL") PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 1 IL") PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CODE(KEYCODE_F9)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR('(') PORT_CODE(KEYCODE_9)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP)
|
||||
|
||||
PORT_START("B3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F8)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('<') PORT_CODE(KEYCODE_COMMA)
|
||||
|
||||
PORT_START("B4")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 9 DC") PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 7 IC") PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F7)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M)
|
||||
|
||||
PORT_START("B5")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Help") PORT_CODE(KEYCODE_F10)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CHAR(0x0a) PORT_CODE(KEYCODE_RALT)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space Bar") PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F6)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N)
|
||||
|
||||
PORT_START("B6")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('|') PORT_CODE(KEYCODE_RCONTROL) // to right of Return key
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F5)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B)
|
||||
|
||||
PORT_START("B7")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_CLOSEBRACE)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_OPENBRACE)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F4)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V)
|
||||
|
||||
PORT_START("B8")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Delete") PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_CODE(KEYCODE_DEL) // to right of `/~ key
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_CODE(KEYCODE_F11)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CODE(KEYCODE_DOWN) // between +/= and Back Space keys
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F3)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR('#') PORT_CODE(KEYCODE_3)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C)
|
||||
|
||||
PORT_START("B9")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_BACKSPACE)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F2)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('@') PORT_CODE(KEYCODE_2)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X)
|
||||
|
||||
PORT_START("B11")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CODE(KEYCODE_RIGHT)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CODE(KEYCODE_UP)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CODE(KEYCODE_LEFT) // to right of Home key
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR('\t') PORT_CODE(KEYCODE_TAB)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z)
|
||||
|
||||
PORT_START("B13")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PORT_CODE(KEYCODE_PLUS_PAD)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("No Scroll") PORT_CODE(KEYCODE_LALT)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Set Up") PORT_CODE(KEYCODE_ESC)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) PORT_CODE(KEYCODE_TILDE)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase") PORT_CODE(KEYCODE_F12)
|
||||
|
||||
PORT_START("B14")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_CAPSLOCK)
|
||||
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
|
||||
PORT_START("MODIFIERS")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_SHIFT_2) PORT_CODE(KEYCODE_LCONTROL)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_WRITE_LINE_MEMBER(he191_3425_device, shift_reset)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break Reset") PORT_CODE(KEYCODE_PAUSE) PORT_WRITE_LINE_MEMBER(he191_3425_device, shift_reset) // to right of Back Space key
|
||||
PORT_BIT(0xf8, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor he191_3425_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(he191_3425);
|
||||
}
|
||||
|
||||
void he191_3425_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
i8021_device &mcu(I8021(config, m_mcu, 3.579545_MHz_XTAL));
|
||||
mcu.bus_in_cb().set(FUNC(he191_3425_device::mcu_pa_r));
|
||||
mcu.p1_in_cb().set_ioport("MODIFIERS");
|
||||
mcu.p1_out_cb().set(FUNC(he191_3425_device::mcu_pb_w));
|
||||
mcu.p2_out_cb().set(FUNC(he191_3425_device::mcu_pc_w));
|
||||
mcu.t1_in_cb().set(FUNC(he191_3425_device::mcu_t1_r));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
BEEP(config, m_buzzer, 1'000'000'000 / PERIOD_OF_555_ASTABLE_NSEC(RES_R(510), RES_R(510), CAP_U(1)));
|
||||
m_buzzer->add_route(ALL_OUTPUTS, "speaker", 1.0);
|
||||
}
|
||||
|
||||
ROM_START(he191_3425)
|
||||
ROM_REGION(0x400, "mcu", ROMREGION_ERASE00)
|
||||
ROM_LOAD("p8021h-2155_444-100.z1", 0x000, 0x400, NO_DUMP)
|
||||
ROM_END
|
||||
|
||||
const tiny_rom_entry *he191_3425_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(he191_3425);
|
||||
}
|
58
src/devices/bus/z29_kbd/he191_3425.h
Normal file
58
src/devices/bus/z29_kbd/he191_3425.h
Normal file
@ -0,0 +1,58 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_BUS_Z29_KBD_HE191_3425_H
|
||||
#define MAME_BUS_Z29_KBD_HE191_3425_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bus/z29_kbd/keyboard.h"
|
||||
#include "sound/beep.h"
|
||||
|
||||
|
||||
class he191_3425_device : public device_t, public device_z29_keyboard_interface
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
he191_3425_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
// miscellanous handlers
|
||||
DECLARE_WRITE_LINE_MEMBER(shift_reset);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
// device_z29_keyboard_interface overrides
|
||||
virtual void receive_data(bool state) override;
|
||||
|
||||
private:
|
||||
// MCU port handlers
|
||||
u8 mcu_pa_r();
|
||||
void mcu_pb_w(u8 data);
|
||||
void mcu_pc_w(u8 data);
|
||||
DECLARE_READ_LINE_MEMBER(mcu_t1_r);
|
||||
|
||||
// misc. helpers
|
||||
TIMER_CALLBACK_MEMBER(receive_data_synced);
|
||||
|
||||
// object finders
|
||||
required_device<cpu_device> m_mcu;
|
||||
required_device<beep_device> m_buzzer;
|
||||
required_ioport_array<12> m_matrix;
|
||||
required_ioport m_modifiers;
|
||||
output_finder<4> m_leds;
|
||||
|
||||
// internal state
|
||||
u8 m_select;
|
||||
bool m_recv_data;
|
||||
};
|
||||
|
||||
// device type declaration
|
||||
DECLARE_DEVICE_TYPE(HE191_3425, he191_3425_device)
|
||||
|
||||
#endif // MAME_BUS_Z29_KBD_HE191_3425_H
|
117
src/devices/bus/z29_kbd/keyboard.cpp
Normal file
117
src/devices/bus/z29_kbd/keyboard.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Zenith Z-29 keyboard port
|
||||
|
||||
This supports the custom serial interface for the H-29/Z-29 and other
|
||||
early Heath/Zenith terminals with detachable keyboards. (Keyboards for
|
||||
later Zenith terminals such as the Z-49 use a standard asynchronous
|
||||
serial protocol.)
|
||||
|
||||
All printable characters outside of the numeric keypad use standard
|
||||
ASCII codes, as do Back Space, Line Feed, Return, Esc and Del. The
|
||||
following codes are assigned to other keys:
|
||||
|
||||
80 Up
|
||||
81 Down
|
||||
82 Left
|
||||
83 Right
|
||||
84 Home
|
||||
85 Erase
|
||||
86 Help
|
||||
87 No Scroll
|
||||
88 Set Up
|
||||
89 Break
|
||||
8A Caps Lock
|
||||
8B Tab
|
||||
8C Space Bar
|
||||
8F (Power On)
|
||||
90 0 (Keypad)
|
||||
91 1 (Keypad)
|
||||
92 2 (Keypad)
|
||||
93 3 (Keypad)
|
||||
94 4 (Keypad)
|
||||
95 5 (Keypad)
|
||||
96 6 (Keypad)
|
||||
97 7 (Keypad)
|
||||
98 8 (Keypad)
|
||||
99 9 (Keypad)
|
||||
9A . (Keypad)
|
||||
9B Enter (Keypad)
|
||||
9C - (Keypad)
|
||||
9D , (Keypad)
|
||||
9F 80 F1
|
||||
9F 81 F2
|
||||
9F 82 F3
|
||||
9F 83 F4
|
||||
9F 84 F5
|
||||
9F 85 F6
|
||||
9F 86 F7
|
||||
9F 87 F8
|
||||
9F 88 F9
|
||||
|
||||
Bit 6 is set in these codes when pressed with Shift, and bit 5 when
|
||||
pressed with Ctrl.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#include "he191_3425.h"
|
||||
#include "md_kbd.h"
|
||||
|
||||
//**************************************************************************
|
||||
// Z-29 KEYBOARD PORT DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(Z29_KEYBOARD, z29_keyboard_port_device, "z29_kbd", "Z-29 Keyboard Port")
|
||||
|
||||
z29_keyboard_port_device::z29_keyboard_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, Z29_KEYBOARD, tag, owner, clock)
|
||||
, device_single_card_slot_interface<device_z29_keyboard_interface>(mconfig, *this)
|
||||
, m_keyin_callback(*this)
|
||||
, m_reset_callback(*this)
|
||||
, m_kbd(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void z29_keyboard_port_device::device_config_complete()
|
||||
{
|
||||
m_kbd = get_card_device();
|
||||
}
|
||||
|
||||
void z29_keyboard_port_device::device_resolve_objects()
|
||||
{
|
||||
m_keyin_callback.resolve_safe();
|
||||
m_reset_callback.resolve_safe();
|
||||
}
|
||||
|
||||
void z29_keyboard_port_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// Z-29 KEYBOARD INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
device_z29_keyboard_interface::device_z29_keyboard_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_interface(device, "z29kbd")
|
||||
, m_port(device, DEVICE_SELF_OWNER)
|
||||
{
|
||||
}
|
||||
|
||||
device_z29_keyboard_interface::~device_z29_keyboard_interface()
|
||||
{
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// KEYBOARD OPTIONS
|
||||
//**************************************************************************
|
||||
|
||||
void z29_keyboards(device_slot_interface &slot)
|
||||
{
|
||||
slot.option_add("heath", HE191_3425);
|
||||
slot.option_add("md", MD_KEYBOARD);
|
||||
}
|
104
src/devices/bus/z29_kbd/keyboard.h
Normal file
104
src/devices/bus/z29_kbd/keyboard.h
Normal file
@ -0,0 +1,104 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Zenith Z-29 keyboard port
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_Z29_KBD_KEYBOARD_H
|
||||
#define MAME_BUS_Z29_KBD_KEYBOARD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// forward declaration
|
||||
class device_z29_keyboard_interface;
|
||||
|
||||
// ======================> z29_keyboard_port_device
|
||||
|
||||
class z29_keyboard_port_device : public device_t, public device_single_card_slot_interface<device_z29_keyboard_interface>
|
||||
{
|
||||
friend class device_z29_keyboard_interface;
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
z29_keyboard_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
template <typename T>
|
||||
z29_keyboard_port_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt)
|
||||
: z29_keyboard_port_device(mconfig, tag, owner, 0U)
|
||||
{
|
||||
option_reset();
|
||||
opts(*this);
|
||||
set_default_option(dflt);
|
||||
set_fixed(false);
|
||||
}
|
||||
|
||||
// callback configuration
|
||||
auto keyin_callback() { return m_keyin_callback.bind(); }
|
||||
auto reset_callback() { return m_reset_callback.bind(); }
|
||||
|
||||
// line handler
|
||||
inline DECLARE_WRITE_LINE_MEMBER(keyout_w);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete() override;
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
|
||||
// called from keyboard
|
||||
void transmit_data(bool state) { m_keyin_callback(state); }
|
||||
void reset_from_keyboard(bool state) { m_reset_callback(state); }
|
||||
|
||||
private:
|
||||
// line callbacks
|
||||
devcb_write_line m_keyin_callback;
|
||||
devcb_write_line m_reset_callback;
|
||||
|
||||
// selected keyboard
|
||||
device_z29_keyboard_interface *m_kbd;
|
||||
};
|
||||
|
||||
// ======================> device_z29_keyboard_interface
|
||||
|
||||
class device_z29_keyboard_interface : public device_interface
|
||||
{
|
||||
friend class z29_keyboard_port_device;
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
device_z29_keyboard_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_z29_keyboard_interface();
|
||||
|
||||
void transmit_data(bool state) { m_port->transmit_data(state); }
|
||||
void reset_from_keyboard(bool state) { m_port->reset_from_keyboard(state); }
|
||||
|
||||
virtual void receive_data(bool state) = 0;
|
||||
|
||||
private:
|
||||
// parent port
|
||||
required_device<z29_keyboard_port_device> m_port;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(Z29_KEYBOARD, z29_keyboard_port_device)
|
||||
|
||||
// standard options
|
||||
extern void z29_keyboards(device_slot_interface &slot);
|
||||
|
||||
//**************************************************************************
|
||||
// INLINE FUNCTIONS
|
||||
//**************************************************************************
|
||||
|
||||
WRITE_LINE_MEMBER(z29_keyboard_port_device::keyout_w)
|
||||
{
|
||||
if (m_kbd != nullptr)
|
||||
m_kbd->receive_data(state);
|
||||
}
|
||||
|
||||
#endif // MAME_BUS_Z29_KBD_KEYBOARD_H
|
277
src/devices/bus/z29_kbd/md_kbd.cpp
Normal file
277
src/devices/bus/z29_kbd/md_kbd.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Micro-Decision keyboard
|
||||
|
||||
This 93-key keyboard was obtained with a Morrow MD3-P. The unit part
|
||||
number is unknown, but "DEKU-0224-PHM-B" and "I/F PCB FOR 14515B" are
|
||||
silkscreened on the component board.
|
||||
|
||||
Like the original Z-29 keyboard, it may also have been designed by
|
||||
Heath/Zenith. It is missing the Erase, Set Up and Break keys (though
|
||||
the first two are still recognized by the program), but has five
|
||||
additional function keys instead.
|
||||
|
||||
Some clumsy coding suggests that the program was originally designed
|
||||
for an 8048 operating in single-chip mode, with the 14515B and LS175
|
||||
having being added to latch outputs also sent to the upper half of
|
||||
Port 2.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "md_kbd.h"
|
||||
|
||||
#include "machine/rescap.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(MD_KEYBOARD, md_keyboard_device, "md_kbd", "Micro-Decision Keyboard")
|
||||
|
||||
md_keyboard_device::md_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, MD_KEYBOARD, tag, owner, clock)
|
||||
, device_z29_keyboard_interface(mconfig, *this)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_buzzer(*this, "buzzer")
|
||||
, m_matrix(*this, "S%u", 0U)
|
||||
, m_leds(*this, "led%u", 1U)
|
||||
, m_14515b_select(0)
|
||||
, m_ls175_clock(true)
|
||||
, m_recv_data(true)
|
||||
{
|
||||
}
|
||||
|
||||
void md_keyboard_device::device_resolve_objects()
|
||||
{
|
||||
m_leds.resolve();
|
||||
}
|
||||
|
||||
void md_keyboard_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_14515b_select));
|
||||
save_item(NAME(m_ls175_clock));
|
||||
save_item(NAME(m_recv_data));
|
||||
}
|
||||
|
||||
void md_keyboard_device::device_reset()
|
||||
{
|
||||
ls175_w(0);
|
||||
}
|
||||
|
||||
void md_keyboard_device::receive_data(bool state)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(md_keyboard_device::receive_data_synced), this), state);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(md_keyboard_device::receive_data_synced)
|
||||
{
|
||||
m_recv_data = param;
|
||||
}
|
||||
|
||||
void md_keyboard_device::ls175_w(u8 data)
|
||||
{
|
||||
m_leds[0] = !BIT(data, 7); // Caps Lock
|
||||
m_leds[1] = !BIT(data, 5); // Keyboard lock?
|
||||
m_buzzer->set_state(BIT(data, 6));
|
||||
}
|
||||
|
||||
u8 md_keyboard_device::mcu_p1_r()
|
||||
{
|
||||
return 0xc0 | m_matrix[m_14515b_select]->read();
|
||||
}
|
||||
|
||||
void md_keyboard_device::mcu_p1_w(u8 data)
|
||||
{
|
||||
transmit_data(!BIT(data, 7));
|
||||
if (!m_ls175_clock && BIT(data, 6))
|
||||
ls175_w(m_mcu->p2_r());
|
||||
m_ls175_clock = BIT(data, 6);
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(md_keyboard_device::mcu_t1_r)
|
||||
{
|
||||
return m_recv_data;
|
||||
}
|
||||
|
||||
void md_keyboard_device::mcu_movx_w(u8 data)
|
||||
{
|
||||
m_14515b_select = (data >> 4) & 0x0f;
|
||||
}
|
||||
|
||||
void md_keyboard_device::prog_map(address_map &map)
|
||||
{
|
||||
map(0x000, 0xfff).rom().region("program", 0);
|
||||
}
|
||||
|
||||
void md_keyboard_device::ext_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0x00).mirror(0xff).w(FUNC(md_keyboard_device::mcu_movx_w));
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START(md_kbd)
|
||||
|
||||
PORT_START("S0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR(')') PORT_CODE(KEYCODE_0)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase") // not actually on keyboard?
|
||||
|
||||
PORT_START("S1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_CLOSEBRACE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR('(') PORT_CODE(KEYCODE_9)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Help") PORT_CODE(KEYCODE_F12)
|
||||
|
||||
PORT_START("S2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_OPENBRACE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Home Clear") PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_CODE(KEYCODE_F11)
|
||||
|
||||
PORT_START("S3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
|
||||
PORT_START("S4")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("No Scroll") PORT_CODE(KEYCODE_ESC)
|
||||
|
||||
PORT_START("S5")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('`') PORT_CHAR('~') PORT_CODE(KEYCODE_BACKSLASH) // to right of +/=
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_CAPSLOCK)
|
||||
|
||||
PORT_START("S6")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_CODE(KEYCODE_DEL)
|
||||
|
||||
PORT_START("S7")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR('#') PORT_CODE(KEYCODE_3)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CODE(KEYCODE_UP)
|
||||
|
||||
PORT_START("S8")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('@') PORT_CODE(KEYCODE_2)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CODE(KEYCODE_DOWN)
|
||||
|
||||
PORT_START("S9")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('|') PORT_CODE(KEYCODE_RCONTROL)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CODE(KEYCODE_RIGHT)
|
||||
|
||||
PORT_START("S10")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('<') PORT_CODE(KEYCODE_COMMA)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PORT_CODE(KEYCODE_PLUS_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) PORT_CODE(KEYCODE_TILDE)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CODE(KEYCODE_LEFT)
|
||||
|
||||
PORT_START("S11")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR('\t') PORT_CODE(KEYCODE_TAB)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH)
|
||||
|
||||
PORT_START("S12")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad Enter +") PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CHAR(0x0a) PORT_CODE(KEYCODE_RALT)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_BACKSPACE)
|
||||
|
||||
PORT_START("S13")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F2)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F3)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F4)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F5)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F6)
|
||||
|
||||
PORT_START("S14")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F7)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F8)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CODE(KEYCODE_F9)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CODE(KEYCODE_F10)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FA") PORT_CHAR(UCHAR_MAMEKEY(F11))
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FB") PORT_CHAR(UCHAR_MAMEKEY(F12))
|
||||
|
||||
PORT_START("S15")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Setup") // not actually on keyboard?
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FD") PORT_CHAR(UCHAR_MAMEKEY(F14))
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FC") PORT_CHAR(UCHAR_MAMEKEY(F13))
|
||||
|
||||
PORT_START("MODIFIERS")
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_SHIFT_2) PORT_CODE(KEYCODE_LCONTROL)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT)
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor md_keyboard_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(md_kbd);
|
||||
}
|
||||
|
||||
void md_keyboard_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
// U4 is M5L8048-052P (internal ROM likely unused), but location is silkscreened "8035"
|
||||
I8035(config, m_mcu, 3.579545_MHz_XTAL); // "CSA 3 58MT" resonator
|
||||
m_mcu->set_addrmap(AS_PROGRAM, &md_keyboard_device::prog_map);
|
||||
m_mcu->set_addrmap(AS_IO, &md_keyboard_device::ext_map);
|
||||
m_mcu->p1_in_cb().set(FUNC(md_keyboard_device::mcu_p1_r));
|
||||
m_mcu->p1_out_cb().set(FUNC(md_keyboard_device::mcu_p1_w));
|
||||
m_mcu->p2_in_cb().set_ioport("MODIFIERS");
|
||||
m_mcu->t1_in_cb().set(FUNC(md_keyboard_device::mcu_t1_r));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
BEEP(config, m_buzzer, 1'000'000'000 / PERIOD_OF_555_ASTABLE_NSEC(RES_R(510), RES_R(510), CAP_U(1)));
|
||||
m_buzzer->add_route(ALL_OUTPUTS, "speaker", 1.0);
|
||||
}
|
||||
|
||||
ROM_START(md_kbd)
|
||||
ROM_REGION(0x1000, "program", 0)
|
||||
ROM_LOAD("kb-rom_rev_3.4_27d4.u5", 0x0000, 0x1000, CRC(c34b606b) SHA1(20cf62fc31257b6c3e767152086f2604fead97bd)) // location marked "2716/2732"
|
||||
ROM_END
|
||||
|
||||
const tiny_rom_entry *md_keyboard_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(md_kbd);
|
||||
}
|
61
src/devices/bus/z29_kbd/md_kbd.h
Normal file
61
src/devices/bus/z29_kbd/md_kbd.h
Normal file
@ -0,0 +1,61 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_BUS_Z29_KBD_MD_KBD_H
|
||||
#define MAME_BUS_Z29_KBD_MD_KBD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "sound/beep.h"
|
||||
|
||||
class md_keyboard_device : public device_t, public device_z29_keyboard_interface
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
md_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
// device_z29_keyboard_interface overrides
|
||||
virtual void receive_data(bool state) override;
|
||||
|
||||
private:
|
||||
// MCU handlers
|
||||
u8 mcu_p1_r();
|
||||
void mcu_p1_w(u8 data);
|
||||
DECLARE_READ_LINE_MEMBER(mcu_t1_r);
|
||||
void mcu_movx_w(u8 data);
|
||||
|
||||
// misc. helpers
|
||||
TIMER_CALLBACK_MEMBER(receive_data_synced);
|
||||
void ls175_w(u8 data);
|
||||
|
||||
// address maps
|
||||
void prog_map(address_map &map);
|
||||
void ext_map(address_map &map);
|
||||
|
||||
// object finders
|
||||
required_device<mcs48_cpu_device> m_mcu;
|
||||
required_device<beep_device> m_buzzer;
|
||||
required_ioport_array<16> m_matrix;
|
||||
output_finder<2> m_leds;
|
||||
|
||||
// internal state
|
||||
u8 m_14515b_select;
|
||||
bool m_ls175_clock;
|
||||
bool m_recv_data;
|
||||
};
|
||||
|
||||
// device type declaration
|
||||
DECLARE_DEVICE_TYPE(MD_KEYBOARD, md_keyboard_device)
|
||||
|
||||
#endif // MAME_BUS_Z29_KBD_MD_KBD_H
|
@ -2,58 +2,41 @@
|
||||
// copyright-holders:AJR
|
||||
/**************************************************************************
|
||||
|
||||
Skeleton driver for MDT 60 and related Zenith terminals.
|
||||
|
||||
MDT 60 was designed by Zenith for use with Morrow's Micro-Decision
|
||||
computers as a low-cost terminal with limited features. It appears
|
||||
to be a stripped-down version of some previously designed terminal,
|
||||
with the auxiliary port omitted from the Morrow version even though
|
||||
the schematics published by Morrow include it. Morrow's schematics
|
||||
also include the same keyboard used by the Z-29, though the actual
|
||||
keyboard found with one unit was different.
|
||||
the schematics published in its service manual include it. These
|
||||
schematics also include the same keyboard used by the Z-29, though
|
||||
the actual keyboard found with one unit was different.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "bus/z29_kbd/keyboard.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "video/mc6845.h"
|
||||
#include "screen.h"
|
||||
|
||||
class mdt60_base_state : public driver_device
|
||||
{
|
||||
public:
|
||||
mdt60_base_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_crtc(*this, "crtc")
|
||||
, m_uart(*this, "uart%u", 0U)
|
||||
, m_charram(*this, "charram")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
MC6845_ON_UPDATE_ADDR_CHANGED(update_cb);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<r6545_1_device> m_crtc;
|
||||
optional_device_array<i8251_device, 2> m_uart;
|
||||
required_shared_ptr<u8> m_charram;
|
||||
};
|
||||
|
||||
class mdt60_state : public mdt60_base_state
|
||||
class mdt60_state : public driver_device
|
||||
{
|
||||
public:
|
||||
mdt60_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: mdt60_base_state(mconfig, type, tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_keyboard(*this, "keyboard")
|
||||
, m_crtc(*this, "crtc")
|
||||
, m_uart(*this, "uart%u", 0U)
|
||||
, m_charram(*this, "charram")
|
||||
, m_charrom(*this, "charrom")
|
||||
, m_attrram(*this, "attrram")
|
||||
, m_dip0(*this, "DIP0")
|
||||
, m_baud_timer(nullptr)
|
||||
, m_keyin(false)
|
||||
, m_reverse(false)
|
||||
, m_output_reg(0x3f)
|
||||
, m_timer_output(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -65,6 +48,8 @@ protected:
|
||||
|
||||
private:
|
||||
MC6845_UPDATE_ROW(update_row);
|
||||
MC6845_ON_UPDATE_ADDR_CHANGED(update_cb);
|
||||
TIMER_CALLBACK_MEMBER(baud_timer);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(keyin_w);
|
||||
u8 dip0_r(offs_t offset);
|
||||
@ -72,54 +57,30 @@ private:
|
||||
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<z29_keyboard_port_device> m_keyboard;
|
||||
required_device<r6545_1_device> m_crtc;
|
||||
optional_device_array<i8251_device, 2> m_uart;
|
||||
required_shared_ptr<u8> m_charram;
|
||||
required_region_ptr<u8> m_charrom;
|
||||
required_shared_ptr<u8> m_attrram;
|
||||
required_ioport m_dip0;
|
||||
|
||||
emu_timer *m_baud_timer;
|
||||
|
||||
bool m_keyin;
|
||||
bool m_reverse;
|
||||
};
|
||||
|
||||
class z22_state : public mdt60_base_state
|
||||
{
|
||||
public:
|
||||
z22_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: mdt60_base_state(mconfig, type, tag)
|
||||
, m_eeprom(*this, "eeprom")
|
||||
, m_fontram(*this, "fontram")
|
||||
, m_eeprom_clk(false)
|
||||
{
|
||||
}
|
||||
|
||||
void z22(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
MC6845_UPDATE_ROW(update_row);
|
||||
|
||||
u8 status_r();
|
||||
void control_w(u8 data);
|
||||
DECLARE_WRITE_LINE_MEMBER(eeprom_clock_w);
|
||||
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
required_shared_ptr<u8> m_fontram;
|
||||
|
||||
bool m_eeprom_clk;
|
||||
u8 m_output_reg;
|
||||
bool m_timer_output;
|
||||
};
|
||||
|
||||
void mdt60_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_keyin));
|
||||
save_item(NAME(m_reverse));
|
||||
}
|
||||
m_baud_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mdt60_state::baud_timer), this));
|
||||
m_baud_timer->adjust(attotime::zero);
|
||||
|
||||
void z22_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_eeprom_clk));
|
||||
save_item(NAME(m_keyin));
|
||||
save_item(NAME(m_output_reg));
|
||||
save_item(NAME(m_timer_output));
|
||||
}
|
||||
|
||||
void mdt60_state::machine_reset()
|
||||
@ -128,6 +89,23 @@ void mdt60_state::machine_reset()
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(mdt60_state::baud_timer)
|
||||
{
|
||||
m_timer_output = !m_timer_output;
|
||||
|
||||
// LS352 multiplexer has inverting outputs
|
||||
m_uart[0]->write_rxc(!m_timer_output);
|
||||
m_uart[0]->write_txc(!m_timer_output);
|
||||
|
||||
constexpr auto time_base = 16.5888_MHz_XTAL / 9;
|
||||
if ((m_output_reg & 0x06) == 0x00)
|
||||
m_baud_timer->adjust(attotime::from_ticks(m_timer_output ? 2 : 4, time_base));
|
||||
else if ((m_output_reg & 0x06) == 0x06)
|
||||
m_baud_timer->adjust(attotime::from_ticks(48, time_base));
|
||||
else
|
||||
m_baud_timer->adjust(attotime::from_ticks(3 * (m_output_reg & 0x06), time_base));
|
||||
}
|
||||
|
||||
MC6845_UPDATE_ROW(mdt60_state::update_row)
|
||||
{
|
||||
u32 *pix = &bitmap.pix32(y);
|
||||
@ -147,7 +125,7 @@ MC6845_UPDATE_ROW(mdt60_state::update_row)
|
||||
|
||||
rgb_t fg = BIT(adata, 1) ? rgb_t::white() : rgb_t(0xc0, 0xc0, 0xc0);
|
||||
rgb_t bg = rgb_t::black();
|
||||
if (m_reverse)
|
||||
if (BIT(m_output_reg, 5))
|
||||
std::swap(fg, bg);
|
||||
|
||||
for (int n = 8; n >= 0; n--)
|
||||
@ -155,27 +133,7 @@ MC6845_UPDATE_ROW(mdt60_state::update_row)
|
||||
}
|
||||
}
|
||||
|
||||
MC6845_UPDATE_ROW(z22_state::update_row)
|
||||
{
|
||||
u32 *pix = &bitmap.pix32(y);
|
||||
|
||||
for (unsigned x = 0; x < x_count; x++)
|
||||
{
|
||||
u8 cdata = m_charram[(ma + x) & 0x7ff];
|
||||
u16 dots = m_fontram[(cdata & 0x7f) << 4 | ra] << 1;
|
||||
|
||||
if (x == cursor_x)
|
||||
dots = ~dots;
|
||||
|
||||
rgb_t fg = rgb_t::white();
|
||||
rgb_t bg = rgb_t::black();
|
||||
|
||||
for (int n = 8; n >= 0; n--)
|
||||
*pix++ = BIT(dots, n) ? fg : bg;
|
||||
}
|
||||
}
|
||||
|
||||
MC6845_ON_UPDATE_ADDR_CHANGED(mdt60_base_state::update_cb)
|
||||
MC6845_ON_UPDATE_ADDR_CHANGED(mdt60_state::update_cb)
|
||||
{
|
||||
}
|
||||
|
||||
@ -190,9 +148,9 @@ u8 mdt60_state::dip0_r(offs_t offset)
|
||||
{
|
||||
u8 buffer = 0xff;
|
||||
if (!BIT(offset, 0))
|
||||
buffer &= m_dip0->read() | 0x80;
|
||||
buffer &= m_dip0->read() >> 1 | 0x80;
|
||||
if (!BIT(offset, 1))
|
||||
buffer &= m_dip0->read() >> 7 | 0xfe;
|
||||
buffer &= m_dip0->read() | 0xfe;
|
||||
if (!m_keyin)
|
||||
buffer &= 0x7f;
|
||||
return buffer;
|
||||
@ -200,29 +158,11 @@ u8 mdt60_state::dip0_r(offs_t offset)
|
||||
|
||||
void mdt60_state::reg_w(u8 data)
|
||||
{
|
||||
//m_keyboard->keyout_w(BIT(data, 0));
|
||||
m_reverse = BIT(data, 5);
|
||||
}
|
||||
if (BIT(data, 0) != BIT(m_output_reg, 0))
|
||||
m_keyboard->keyout_w(BIT(data, 0));
|
||||
|
||||
u8 z22_state::status_r()
|
||||
{
|
||||
u8 result = 0;
|
||||
if (m_eeprom_clk)
|
||||
result |= 0x02;
|
||||
if (!m_eeprom->do_read())
|
||||
result |= 0x01;
|
||||
return result;
|
||||
}
|
||||
|
||||
void z22_state::control_w(u8 data)
|
||||
{
|
||||
m_eeprom->di_write(!BIT(data, 7));
|
||||
m_eeprom->cs_write(BIT(data, 6));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(z22_state::eeprom_clock_w)
|
||||
{
|
||||
m_eeprom_clk = state;
|
||||
// Bits 1–2 & 3–4 select 1 of 4 baud rates for each UART; bit 5 selects inverse video
|
||||
m_output_reg = data & 0x3f;
|
||||
}
|
||||
|
||||
void mdt60_state::mem_map(address_map &map)
|
||||
@ -240,23 +180,9 @@ void mdt60_state::mem_map(address_map &map)
|
||||
map(0xe000, 0xefff).mirror(0x1000).rom().region("coderom", 0);
|
||||
}
|
||||
|
||||
void z22_state::mem_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x07ff).ram();
|
||||
map(0x2000, 0x27ff).ram().share("charram");
|
||||
map(0x4000, 0x4001).rw(m_uart[1], FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
map(0x6000, 0x67ff).ram().share("fontram");
|
||||
map(0x8000, 0x8001).rw(m_uart[0], FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
map(0x8800, 0x8800).rw(m_crtc, FUNC(r6545_1_device::status_r), FUNC(r6545_1_device::address_w));
|
||||
map(0x8801, 0x8801).rw(m_crtc, FUNC(r6545_1_device::register_r), FUNC(r6545_1_device::register_w));
|
||||
map(0x9000, 0x9003).w("pit", FUNC(pit8254_device::write));
|
||||
map(0xa000, 0xa000).rw(FUNC(z22_state::status_r), FUNC(z22_state::control_w));
|
||||
map(0xc000, 0xffff).rom().region("program", 0);
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START(mdt60)
|
||||
PORT_START("DIP0") // TODO: verify bit assignments
|
||||
PORT_START("DIP0")
|
||||
PORT_DIPNAME(0x03, 0x01, "Baud Rate") PORT_DIPLOCATION("SW1:1,2")
|
||||
PORT_DIPSETTING(0x03, "300")
|
||||
PORT_DIPSETTING(0x02, "1200")
|
||||
@ -284,9 +210,6 @@ static INPUT_PORTS_START(mdt60)
|
||||
PORT_BIT(0xff, 0xff, IPT_UNUSED) // SW2 is unpopulated
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START(z22)
|
||||
INPUT_PORTS_END
|
||||
|
||||
// XTAL frequency is specified as 16.589 MHz on actual parts as well as in MDT 60 schematics.
|
||||
// This has been assumed to be a lower-precision specification of the common 16.5888 MHz value.
|
||||
|
||||
@ -297,12 +220,15 @@ void mdt60_state::mdt60(machine_config &config)
|
||||
|
||||
I8251(config, m_uart[0], 16.5888_MHz_XTAL / 9); // TMP8251AP (U19)
|
||||
m_uart[0]->rxrdy_handler().set_inputline(m_maincpu, m6512_device::NMI_LINE);
|
||||
m_uart[0]->txd_handler().set("computer", FUNC(rs232_port_device::write_txd));
|
||||
m_uart[0]->dtr_handler().set("computer", FUNC(rs232_port_device::write_dtr));
|
||||
m_uart[0]->rts_handler().set("computer", FUNC(rs232_port_device::write_rts));
|
||||
m_uart[0]->txd_handler().set("comm", FUNC(rs232_port_device::write_txd));
|
||||
m_uart[0]->dtr_handler().set("comm", FUNC(rs232_port_device::write_dtr));
|
||||
m_uart[0]->rts_handler().set("comm", FUNC(rs232_port_device::write_rts));
|
||||
|
||||
// UART 1 (at U28) is unpopulated and not used by code
|
||||
|
||||
Z29_KEYBOARD(config, m_keyboard, z29_keyboards, "md");
|
||||
m_keyboard->keyin_callback().set(FUNC(mdt60_state::keyin_w)).invert();
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_color(rgb_t::amber());
|
||||
screen.set_raw(16.5888_MHz_XTAL, 918, 0, 720, 301, 0, 288);
|
||||
@ -314,54 +240,10 @@ void mdt60_state::mdt60(machine_config &config)
|
||||
m_crtc->set_char_width(9);
|
||||
m_crtc->set_update_row_callback(FUNC(mdt60_state::update_row));
|
||||
m_crtc->set_on_update_addr_change_callback(FUNC(mdt60_state::update_cb));
|
||||
// LPEN is tied to GND (code uses this to determine CRTC type)
|
||||
|
||||
rs232_port_device &computer(RS232_PORT(config, "computer", default_rs232_devices, nullptr));
|
||||
computer.rxd_handler().set(m_uart[0], FUNC(i8251_device::write_rxd));
|
||||
computer.dsr_handler().set(m_uart[0], FUNC(i8251_device::write_dsr));
|
||||
computer.cts_handler().set(m_uart[0], FUNC(i8251_device::write_cts));
|
||||
}
|
||||
|
||||
void z22_state::z22(machine_config &config)
|
||||
{
|
||||
M6512(config, m_maincpu, 16.5888_MHz_XTAL / 9); // R6512AP
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &z22_state::mem_map);
|
||||
|
||||
I8251(config, m_uart[0], 16.5888_MHz_XTAL / 9); // NEC D8251AC (U33) + Intel P8251A (U35)
|
||||
m_uart[0]->rxrdy_handler().set_inputline(m_maincpu, m6512_device::NMI_LINE);
|
||||
m_uart[0]->txd_handler().set("comm", FUNC(rs232_port_device::write_txd));
|
||||
m_uart[0]->dtr_handler().set("comm", FUNC(rs232_port_device::write_dtr));
|
||||
m_uart[0]->rts_handler().set("comm", FUNC(rs232_port_device::write_rts));
|
||||
|
||||
I8251(config, m_uart[1], 16.5888_MHz_XTAL / 9);
|
||||
|
||||
EEPROM_93C06_16BIT(config, m_eeprom); // NMC9306 (U27)
|
||||
|
||||
pit8254_device &pit(PIT8254(config, "pit")); // Intel P8254
|
||||
pit.set_clk<0>(16.5888_MHz_XTAL / 9);
|
||||
pit.set_clk<1>(16.5888_MHz_XTAL / 9);
|
||||
pit.set_clk<2>(16.5888_MHz_XTAL / 9);
|
||||
pit.out_handler<0>().set(m_uart[1], FUNC(i8251_device::write_rxc));
|
||||
pit.out_handler<0>().append(m_uart[1], FUNC(i8251_device::write_txc));
|
||||
pit.out_handler<0>().append(m_eeprom, FUNC(eeprom_serial_93cxx_device::clk_write)); // weird synchronous clocking
|
||||
pit.out_handler<0>().append(FUNC(z22_state::eeprom_clock_w));
|
||||
pit.out_handler<1>().set(m_uart[0], FUNC(i8251_device::write_rxc));
|
||||
pit.out_handler<2>().set(m_uart[0], FUNC(i8251_device::write_txc)); // or the other way around?
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_color(rgb_t::amber());
|
||||
screen.set_raw(16.5888_MHz_XTAL, 873, 0, 720, 317, 0, 300);
|
||||
screen.set_screen_update(m_crtc, FUNC(r6545_1_device::screen_update));
|
||||
|
||||
R6545_1(config, m_crtc, 16.5888_MHz_XTAL / 9); // R6545-1AP
|
||||
m_crtc->set_screen("screen");
|
||||
m_crtc->set_show_border_area(false);
|
||||
m_crtc->set_char_width(9);
|
||||
m_crtc->set_update_row_callback(FUNC(z22_state::update_row));
|
||||
m_crtc->set_on_update_addr_change_callback(FUNC(z22_state::update_cb));
|
||||
|
||||
// TODO: onboard buzzer
|
||||
|
||||
rs232_port_device &comm(RS232_PORT(config, "comm", default_rs232_devices, nullptr));
|
||||
rs232_port_device &comm(RS232_PORT(config, "comm", default_rs232_devices, "loopback"));
|
||||
// Service Manual suggests shorting pins with a bent paper clip if no DB-25 loopback connector is available ;-)
|
||||
comm.rxd_handler().set(m_uart[0], FUNC(i8251_device::write_rxd));
|
||||
comm.dsr_handler().set(m_uart[0], FUNC(i8251_device::write_dsr));
|
||||
comm.cts_handler().set(m_uart[0], FUNC(i8251_device::write_cts));
|
||||
@ -370,17 +252,11 @@ void z22_state::z22(machine_config &config)
|
||||
|
||||
ROM_START(mdt60)
|
||||
ROM_REGION(0x1000, "coderom", 0)
|
||||
// "ROM REV. 1.7 -- Copyright (C) 1983 by Morrow Designs, Inc."
|
||||
ROM_LOAD("vb-rom_1.7_bcfd.u9", 0x0000, 0x1000, CRC(3902f7b3) SHA1(ee0ce7f68efe20efe1ab8a44888e276f08fe2d07))
|
||||
|
||||
ROM_REGION(0x1000, "charrom", 0)
|
||||
ROM_LOAD("char_gen_b207.u6", 0x0000, 0x1000, CRC(b19432da) SHA1(fa73641c08b778f19a17676a7f4074f69b7b55dd))
|
||||
ROM_END
|
||||
|
||||
ROM_START(z22)
|
||||
ROM_REGION(0x4000, "program", 0)
|
||||
ROM_LOAD("u39.bin", 0x0000, 0x2000, CRC(2f62c1f8) SHA1(448581d987fee6b4303e481e78f46d3255baccbb)) // D2764A-3
|
||||
ROM_LOAD("u38.bin", 0x2000, 0x2000, CRC(f0bfe9b5) SHA1(8807841b28549d0ddf30275fc6035a66093f8768)) // D2764A-3
|
||||
ROM_END
|
||||
|
||||
SYST(1983, mdt60, 0, 0, mdt60, mdt60, mdt60_state, empty_init, "Morrow", "MDT 60 Video Display Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
SYST(1984, z22, 0, 0, z22, z22, z22_state, empty_init, "Zenith Data Systems", "Z-22 Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
SYST(1983, mdt60, 0, 0, mdt60, mdt60, mdt60_state, empty_init, "Morrow Designs", "MDT 60 Video Display Terminal", MACHINE_SUPPORTS_SAVE)
|
||||
|
215
src/mame/drivers/z22.cpp
Normal file
215
src/mame/drivers/z22.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**************************************************************************
|
||||
|
||||
Skeleton driver for Zenith Z-22 terminal.
|
||||
|
||||
Despite featuring much of the same hardware as the MDT 60, with the
|
||||
CPU, CRTC and UART types and even dot clock frequency being identical,
|
||||
much else is different: a serial EEPROM replaces DIP switches, an 8254
|
||||
generates baud rates, fonts are uploaded to RAM, and the serial
|
||||
keyboard protocol is incompatible.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "video/mc6845.h"
|
||||
#include "screen.h"
|
||||
|
||||
class z22_state : public driver_device
|
||||
{
|
||||
public:
|
||||
z22_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_crtc(*this, "crtc")
|
||||
, m_uart(*this, "uart%u", 0U)
|
||||
, m_eeprom(*this, "eeprom")
|
||||
, m_dispram(*this, "dispram")
|
||||
, m_fontram(*this, "fontram")
|
||||
, m_eeprom_clk(false)
|
||||
{
|
||||
}
|
||||
|
||||
void z22(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
MC6845_UPDATE_ROW(update_row);
|
||||
MC6845_ON_UPDATE_ADDR_CHANGED(update_cb);
|
||||
|
||||
u8 irq_ack_r();
|
||||
u8 status_r();
|
||||
void control_w(u8 data);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(eeprom_clock_w);
|
||||
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<r6545_1_device> m_crtc;
|
||||
optional_device_array<i8251_device, 2> m_uart;
|
||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
required_shared_ptr<u8> m_dispram;
|
||||
required_shared_ptr<u8> m_fontram;
|
||||
|
||||
bool m_eeprom_clk;
|
||||
};
|
||||
|
||||
void z22_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_eeprom_clk));
|
||||
}
|
||||
|
||||
void z22_state::machine_reset()
|
||||
{
|
||||
control_w(0);
|
||||
}
|
||||
|
||||
|
||||
MC6845_UPDATE_ROW(z22_state::update_row)
|
||||
{
|
||||
u32 *pix = &bitmap.pix32(y);
|
||||
|
||||
for (unsigned x = 0; x < x_count; x++)
|
||||
{
|
||||
u8 cdata = m_dispram[(ma + x) & 0x7ff];
|
||||
u16 dots = m_fontram[(cdata & 0x7f) << 4 | ra] << 1;
|
||||
|
||||
if (x == cursor_x)
|
||||
dots = ~dots;
|
||||
|
||||
rgb_t fg = rgb_t::white();
|
||||
rgb_t bg = rgb_t::black();
|
||||
|
||||
for (int n = 8; n >= 0; n--)
|
||||
*pix++ = BIT(dots, n) ? fg : bg;
|
||||
}
|
||||
}
|
||||
|
||||
MC6845_ON_UPDATE_ADDR_CHANGED(z22_state::update_cb)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
u8 z22_state::irq_ack_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->set_input_line(m6512_device::IRQ_LINE, CLEAR_LINE);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
u8 z22_state::status_r()
|
||||
{
|
||||
u8 result = 0;
|
||||
if (!m_eeprom->do_read())
|
||||
result |= 0x01;
|
||||
if (m_eeprom_clk)
|
||||
result |= 0x02;
|
||||
// TODO: bit 7 = received keyboard data
|
||||
return result;
|
||||
}
|
||||
|
||||
void z22_state::control_w(u8 data)
|
||||
{
|
||||
m_eeprom->di_write(!BIT(data, 7));
|
||||
m_eeprom->cs_write(BIT(data, 6));
|
||||
//m_keyboard->keyout_w(BIT(data, 0));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(z22_state::eeprom_clock_w)
|
||||
{
|
||||
m_eeprom_clk = state;
|
||||
if (state)
|
||||
m_maincpu->set_input_line(m6512_device::IRQ_LINE, ASSERT_LINE);
|
||||
}
|
||||
|
||||
void z22_state::mem_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x07ff).ram();
|
||||
map(0x2000, 0x27ff).ram().share("dispram");
|
||||
map(0x4000, 0x4001).rw(m_uart[1], FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
map(0x6000, 0x67ff).ram().share("fontram");
|
||||
map(0x8000, 0x8001).rw(m_uart[0], FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
map(0x8800, 0x8800).rw(m_crtc, FUNC(r6545_1_device::status_r), FUNC(r6545_1_device::address_w));
|
||||
map(0x8801, 0x8801).rw(m_crtc, FUNC(r6545_1_device::register_r), FUNC(r6545_1_device::register_w));
|
||||
map(0x9000, 0x9003).w("pit", FUNC(pit8254_device::write));
|
||||
map(0x9800, 0x9800).r(FUNC(z22_state::irq_ack_r));
|
||||
map(0xa000, 0xa000).rw(FUNC(z22_state::status_r), FUNC(z22_state::control_w));
|
||||
map(0xc000, 0xffff).rom().region("program", 0);
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START(z22)
|
||||
INPUT_PORTS_END
|
||||
|
||||
// XTAL frequency is specified as 16.589 MHz on actual parts. As with the MDT 60, this
|
||||
// has been assumed to be a lower-precision specification of the common 16.5888 MHz value.
|
||||
|
||||
void z22_state::z22(machine_config &config)
|
||||
{
|
||||
M6512(config, m_maincpu, 16.5888_MHz_XTAL / 9); // R6512AP
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &z22_state::mem_map);
|
||||
|
||||
I8251(config, m_uart[0], 16.5888_MHz_XTAL / 9); // NEC D8251AC (U33) + Intel P8251A (U35)
|
||||
m_uart[0]->rxrdy_handler().set_inputline(m_maincpu, m6512_device::NMI_LINE);
|
||||
m_uart[0]->txd_handler().set("comm", FUNC(rs232_port_device::write_txd));
|
||||
m_uart[0]->dtr_handler().set("comm", FUNC(rs232_port_device::write_dtr));
|
||||
m_uart[0]->rts_handler().set("comm", FUNC(rs232_port_device::write_rts));
|
||||
|
||||
I8251(config, m_uart[1], 16.5888_MHz_XTAL / 9);
|
||||
m_uart[1]->txd_handler().set("printer", FUNC(rs232_port_device::write_txd));
|
||||
|
||||
EEPROM_93C06_16BIT(config, m_eeprom); // NMC9306 (U27)
|
||||
|
||||
pit8254_device &pit(PIT8254(config, "pit")); // Intel P8254
|
||||
pit.set_clk<0>(16.5888_MHz_XTAL / 9);
|
||||
pit.set_clk<1>(16.5888_MHz_XTAL / 9);
|
||||
pit.set_clk<2>(16.5888_MHz_XTAL / 9);
|
||||
pit.out_handler<0>().set(m_eeprom, FUNC(eeprom_serial_93cxx_device::clk_write)); // weird synchronous clocking
|
||||
pit.out_handler<0>().append(FUNC(z22_state::eeprom_clock_w));
|
||||
pit.out_handler<1>().set(m_uart[0], FUNC(i8251_device::write_rxc));
|
||||
pit.out_handler<2>().set(m_uart[0], FUNC(i8251_device::write_txc)); // or the other way around?
|
||||
pit.out_handler<2>().append(m_uart[1], FUNC(i8251_device::write_txc));
|
||||
|
||||
// TODO: Keyboard (asynchronous serial, like Z-49?)
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_color(rgb_t::amber());
|
||||
screen.set_raw(16.5888_MHz_XTAL, 873, 0, 720, 317, 0, 300);
|
||||
screen.set_screen_update(m_crtc, FUNC(r6545_1_device::screen_update));
|
||||
|
||||
R6545_1(config, m_crtc, 16.5888_MHz_XTAL / 9); // R6545-1AP
|
||||
m_crtc->set_screen("screen");
|
||||
m_crtc->set_show_border_area(false);
|
||||
m_crtc->set_char_width(9);
|
||||
m_crtc->set_update_row_callback(FUNC(z22_state::update_row));
|
||||
m_crtc->set_on_update_addr_change_callback(FUNC(z22_state::update_cb));
|
||||
|
||||
// TODO: onboard buzzer
|
||||
|
||||
rs232_port_device &comm(RS232_PORT(config, "comm", default_rs232_devices, nullptr));
|
||||
comm.rxd_handler().set(m_uart[0], FUNC(i8251_device::write_rxd));
|
||||
comm.dsr_handler().set(m_uart[0], FUNC(i8251_device::write_dsr));
|
||||
comm.cts_handler().set(m_uart[0], FUNC(i8251_device::write_cts));
|
||||
|
||||
rs232_port_device &printer(RS232_PORT(config, "printer", default_rs232_devices, nullptr));
|
||||
printer.dsr_handler().set(m_uart[1], FUNC(i8251_device::write_dsr));
|
||||
}
|
||||
|
||||
|
||||
ROM_START(z22)
|
||||
ROM_REGION(0x4000, "program", 0)
|
||||
ROM_LOAD("u39.bin", 0x0000, 0x2000, CRC(2f62c1f8) SHA1(448581d987fee6b4303e481e78f46d3255baccbb)) // D2764A-3
|
||||
ROM_LOAD("u38.bin", 0x2000, 0x2000, CRC(f0bfe9b5) SHA1(8807841b28549d0ddf30275fc6035a66093f8768)) // D2764A-3
|
||||
ROM_END
|
||||
|
||||
SYST(1984, z22, 0, 0, z22, z22, z22_state, empty_init, "Zenith Data Systems", "Z-22 Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
@ -8,8 +8,8 @@
|
||||
|
||||
#include "emu.h"
|
||||
//#include "bus/rs232/rs232.h"
|
||||
#include "bus/z29_kbd/keyboard.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "machine/x2212.h"
|
||||
#include "video/i8275.h"
|
||||
#include "screen.h"
|
||||
@ -20,11 +20,14 @@ public:
|
||||
z29_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_keyboard(*this, "keyboard")
|
||||
, m_crtc(*this, "crtc%u", 1U)
|
||||
, m_nvram(*this, "nvram")
|
||||
, m_charmem(*this, "charmem")
|
||||
, m_attrmem(*this, "attrmem")
|
||||
, m_chargen(*this, "chargen")
|
||||
, m_dmatype(true)
|
||||
, m_keyin(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -34,8 +37,10 @@ protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
DECLARE_WRITE_LINE_MEMBER(keyin_w);
|
||||
u8 p1_r();
|
||||
void p3_w(u8 data);
|
||||
DECLARE_READ8_MEMBER(bs_24k_r);
|
||||
u8 bs_24k_r(offs_t offset);
|
||||
void crtc_w(offs_t offset, u8 data);
|
||||
void latch_12k_w(u8 data);
|
||||
|
||||
@ -43,6 +48,7 @@ private:
|
||||
void ext_map(address_map &map);
|
||||
|
||||
required_device<mcs51_cpu_device> m_maincpu;
|
||||
required_device<z29_keyboard_port_device> m_keyboard;
|
||||
required_device_array<i8276_device, 2> m_crtc;
|
||||
required_device<x2210_device> m_nvram;
|
||||
|
||||
@ -51,11 +57,23 @@ private:
|
||||
required_region_ptr<u8> m_chargen;
|
||||
|
||||
bool m_dmatype;
|
||||
bool m_keyin;
|
||||
};
|
||||
|
||||
void z29_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_dmatype));
|
||||
save_item(NAME(m_keyin));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(z29_state::keyin_w)
|
||||
{
|
||||
m_keyin = state;
|
||||
}
|
||||
|
||||
u8 z29_state::p1_r()
|
||||
{
|
||||
return m_keyin ? 0xfd : 0xff;
|
||||
}
|
||||
|
||||
void z29_state::p3_w(u8 data)
|
||||
@ -63,7 +81,7 @@ void z29_state::p3_w(u8 data)
|
||||
m_dmatype = BIT(data, 4);
|
||||
}
|
||||
|
||||
READ8_MEMBER(z29_state::bs_24k_r)
|
||||
u8 z29_state::bs_24k_r(offs_t offset)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
@ -122,11 +140,16 @@ void z29_state::z29(machine_config &config)
|
||||
I8031(config, m_maincpu, 14.784_MHz_XTAL / 2); // Intel P8031AH
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &z29_state::prg_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &z29_state::ext_map);
|
||||
m_maincpu->port_in_cb<1>().set_constant(0xfd); // hack around keyboard not working
|
||||
m_maincpu->port_in_cb<1>().set(FUNC(z29_state::p1_r));
|
||||
m_maincpu->port_out_cb<1>().set(m_keyboard, FUNC(z29_keyboard_port_device::keyout_w)).bit(0).invert();
|
||||
m_maincpu->port_out_cb<3>().set(FUNC(z29_state::p3_w));
|
||||
|
||||
X2210(config, m_nvram);
|
||||
|
||||
Z29_KEYBOARD(config, m_keyboard, z29_keyboards, /*"heath"*/ "md");
|
||||
m_keyboard->keyin_callback().set(FUNC(z29_state::keyin_w));
|
||||
m_keyboard->reset_callback().set_inputline(m_maincpu, INPUT_LINE_RESET).invert();
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(14.784_MHz_XTAL, 880, 0, 640, 280, 0, 250);
|
||||
screen.set_screen_update("crtc1", FUNC(i8276_device::screen_update));
|
||||
@ -136,8 +159,6 @@ void z29_state::z29(machine_config &config)
|
||||
m_crtc[0]->irq_wr_callback().set_inputline(m_maincpu, MCS51_INT1_LINE);
|
||||
|
||||
I8276(config, m_crtc[1], 14.784_MHz_XTAL / 8).set_character_width(8);
|
||||
|
||||
I8021(config, "kbdmcu", 3.579545_MHz_XTAL).set_disable();
|
||||
}
|
||||
|
||||
|
||||
@ -148,9 +169,6 @@ ROM_START(z29) // All EPROMs on 85-2835-1 terminal board are HN482732AG-30
|
||||
|
||||
ROM_REGION(0x1000, "chargen", 0)
|
||||
ROM_LOAD("u429.bin", 0x0000, 0x1000, CRC(5e3bc5bf) SHA1(18d73e3d74a9768bee8b063ea45891f955558ae7))
|
||||
|
||||
ROM_REGION(0x400, "kbdmcu", 0)
|
||||
ROM_LOAD("444-100.bin", 0x000, 0x400, NO_DUMP)
|
||||
ROM_END
|
||||
|
||||
|
||||
|
@ -21873,7 +21873,6 @@ fl100 // (c) 198? Grundig
|
||||
|
||||
@source:mdt60.cpp
|
||||
mdt60 //
|
||||
z22 //
|
||||
|
||||
@source:meadows.cpp
|
||||
bowl3d // [1978?]
|
||||
@ -41792,6 +41791,9 @@ z1013k69 //
|
||||
z1013k76 //
|
||||
z1013s60 //
|
||||
|
||||
@source:z22.cpp
|
||||
z22 //
|
||||
|
||||
@source:z29.cpp
|
||||
z29 //
|
||||
|
||||
|
@ -1075,6 +1075,7 @@ ymtx81z.cpp
|
||||
ymvl70.cpp
|
||||
z100.cpp
|
||||
z1013.cpp
|
||||
z22.cpp
|
||||
z29.cpp
|
||||
z80dev.cpp
|
||||
z80ne.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user