hds200: Preliminary keyboard, video improvements, hook up NVRAM

This commit is contained in:
Dirk Best 2021-12-18 14:05:20 +01:00
parent 9eccbfde84
commit ddfc9b908c
4 changed files with 521 additions and 9 deletions

View File

@ -2572,6 +2572,8 @@ files {
createMESSProjects(_target, _subtarget, "hds")
files {
MAME_DIR .. "src/mame/drivers/hds200.cpp",
MAME_DIR .. "src/mame/machine/hds200_kbd.cpp",
MAME_DIR .. "src/mame/machine/hds200_kbd.h",
}
createMESSProjects(_target, _subtarget, "heathkit")

View File

@ -21,9 +21,8 @@
TODO:
- Fix SCN2674/Z80DMA hookup
- Keyboard
- Missing keyboard keys
- RS232 control lines
- Sound? (on keyboard?)
Notes:
- The PCB has a large unpopulated area. Possibly this is used for the
@ -33,6 +32,7 @@
#include "emu.h"
#include "cpu/z80/z80.h"
#include "machine/hds200_kbd.h"
#include "machine/input_merger.h"
#include "machine/mc68681.h"
#include "machine/nvram.h"
@ -102,6 +102,7 @@ private:
void duart0_out_w(uint8_t data);
void duart1_out_w(uint8_t data);
bool m_reverse_video;
bool m_nmi_enabled;
};
@ -114,7 +115,7 @@ void hds200_state::mem_map(address_map &map)
{
map(0x0000, 0x3fff).rom().region("maincpu", 0);
map(0x4000, 0x5fff).bankr(m_rombank);
map(0x6800, 0x6fff).ram(); // nvram?
map(0x6800, 0x6fff).ram().share("nvram");
map(0x7000, 0x77ff).ram().share("vram");
map(0x8000, 0xbfff).ram();
map(0xc000, 0xffff).noprw(); // expansion ram
@ -163,6 +164,31 @@ SCN2674_DRAW_CHARACTER_MEMBER( hds200_state::draw_character )
uint16_t data = m_chargen[charcode << 4 | linecount];
const pen_t *const pen = m_palette->pens();
// 7------- invert
// -6------ bold
// --5----- unknown
// ---4---- underline
// ----3--- blink
// -----2-- conceal
// ------1- unknown
// -------0 unknown
if (ul && (BIT(attrcode, 4)))
data = 0x1ff;
if (blink && (BIT(attrcode, 3)))
data = 0x000;
// invert
if (BIT(attrcode, 7))
data = ~data;
if (cursor)
data = ~data;
if (m_reverse_video)
data = ~data;
// foreground/background colors
rgb_t fg = pen[1];
rgb_t bg = pen[0];
@ -212,9 +238,12 @@ void hds200_state::duart0_out_w(uint8_t data)
{
// 765----- unknown
// ---4---- 80/132 column switch (1 = 80)
// ----3210 unknown
// ----3--- reverse video
// -----210 unknown
logerror("duart0_out_w: %02x\n", data);
//logerror("duart0_out_w: %02x\n", data);
m_reverse_video = bool(BIT(data, 3));
}
void hds200_state::duart1_out_w(uint8_t data)
@ -225,9 +254,9 @@ void hds200_state::duart1_out_w(uint8_t data)
// -----2-- rombank
// ------10 unknown
logerror("duart1_out_w: %02x\n", data);
//logerror("duart1_out_w: %02x\n", data);
m_nmi_enabled = BIT(data, 4);
m_nmi_enabled = bool(BIT(data, 4));
m_rombank->set_entry(!BIT(data, 2));
}
@ -236,12 +265,15 @@ void hds200_state::machine_start()
m_rombank->configure_entries(0, 2, memregion("maincpu")->base() + 0x4000, 0x2000);
// register for save states
save_item(NAME(m_reverse_video));
save_item(NAME(m_nmi_enabled));
}
void hds200_state::machine_reset()
{
m_reverse_video = false;
m_nmi_enabled = false;
m_rombank->set_entry(0);
// no duart irq active
@ -262,7 +294,7 @@ void hds200_state::hds200(machine_config &config)
input_merger_device &z80_irq(INPUT_MERGER_ANY_HIGH(config, "z80_irq"));
z80_irq.output_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
// NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
Z80DMA(config, m_dma, 8_MHz_XTAL / 2); // divider not verified
m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
@ -301,6 +333,7 @@ void hds200_state::hds200(machine_config &config)
m_duart[1]->irq_cb().set("duart_irq", FUNC(input_merger_device::in_w<1>));
m_duart[1]->outport_cb().set(FUNC(hds200_state::duart1_out_w));
m_duart[1]->a_tx_cb().set("line3", FUNC(rs232_port_device::write_txd));
m_duart[1]->b_tx_cb().set("kbd", FUNC(hds200_kbd_hle_device::rx_w));
rs232_port_device &rs232_line1(RS232_PORT(config, "line1", default_rs232_devices, nullptr));
rs232_line1.rxd_handler().set(m_duart[0], FUNC(scn2681_device::rx_a_w));
@ -313,6 +346,9 @@ void hds200_state::hds200(machine_config &config)
rs232_port_device &rs232_line3(RS232_PORT(config, "line3", default_rs232_devices, nullptr));
rs232_line3.rxd_handler().set(m_duart[1], FUNC(scn2681_device::rx_a_w));
rs232_line3.cts_handler().set(m_duart[1], FUNC(scn2681_device::ip0_w));
hds200_kbd_hle_device &kbd(HDS200_KBD_HLE(config, "kbd"));
kbd.tx_handler().set(m_duart[1], FUNC(scn2681_device::rx_b_w));
}
@ -340,4 +376,4 @@ ROM_END
//**************************************************************************
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 198?, hds200, 0, 0, hds200, 0, hds200_state, empty_init, "Human Designed Systems", "HDS200", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
COMP( 1985, hds200, 0, 0, hds200, 0, hds200_state, empty_init, "Human Designed Systems", "HDS200", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE )

View File

@ -0,0 +1,408 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
HDS200 Keyboard (HLE)
TODO:
- Add missing keycodes, verify existing
- LEDs
- Keyclick
Notes:
- No clear picture of the keyboard available, everything guessed
***************************************************************************/
#include "emu.h"
#include "hds200_kbd.h"
#include "machine/keyboard.ipp"
#include "speaker.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(HDS200_KBD_HLE, hds200_kbd_hle_device, "hds200_kbd_hle", "HDS200 Keyboard (HLE)")
namespace {
uint8_t const TRANSLATION_TABLE[4][7][22] =
{
// unshift
{ // main control number pad
{ 0x00, 0xb0, 0x00, 0xf0, 0xa8, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0
{ 0x1b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2d, 0x3d, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 1
{ 0x09, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6f, 0x70, 0x5b, 0x5d, 0x0d, 0x08, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, 0x9c }, // 2
{ 0x00, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6c, 0x3b, 0x27, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0xa2, 0xa3, 0xa4, 0x9b }, // 3
{ 0x00, 0x00, 0x7a, 0x78, 0x63, 0x76, 0x62, 0x6e, 0x6d, 0x2c, 0x2e, 0x2f, 0x00, 0x00, 0x0a, 0xab, 0xad, 0xaa, 0x9f, 0xa0, 0xa1, 0x0d }, // 4
{ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x9d, 0x00 } // 5
},
// shift
{ // main control number pad
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0
{ 0x00, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5e, 0x26, 0x2a, 0x28, 0x29, 0x5f, 0x2b, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 1
{ 0x00, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4f, 0x50, 0x7b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 2
{ 0x00, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x3a, 0x22, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3
{ 0x00, 0x00, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d, 0x3c, 0x3e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // 5
},
// unshift-control
{ // main control number pad
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 1
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 2
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // 5
},
// shift-control
{ // main control number pad
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 1
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 2
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // 5
}
};
} // anonymous namespace
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( keyboard )
PORT_START("mod")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
PORT_START("row_0")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Hold Scrn") PORT_CODE(KEYCODE_SCRLOCK)
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Setup") PORT_CODE(KEYCODE_F1) // ? (mapped to 'Setup' for now)
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Status") PORT_CODE(KEYCODE_F2) // ? (mapped to 'Status' for now)
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Next Line") PORT_CODE(KEYCODE_F3) // ? (mapped to 'Next Line' for now)
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Next Value") PORT_CODE(KEYCODE_F4) // ? (mapped to 'Next Value' for now)
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6)
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7)
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8)
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9)
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10)
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11)
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F12)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F13)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F14)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Save") PORT_CODE(KEYCODE_F5) // ? (mapped to 'Save' [code ac or b1?] for now)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F17)
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F18)
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F19)
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F20)
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("row_1")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC)
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1)
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2)
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3)
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4)
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5)
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6)
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7)
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8)
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9)
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0)
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS)
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // "erase"?
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // PF1?
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // PF2?
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // PF3?
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // PF4?
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("row_2")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB)
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q)
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W)
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E)
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R)
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T)
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y)
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U)
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I)
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O)
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P)
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE)
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) // ?
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD)
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD)
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("row_3")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_UNUSED) // Ctrl (handled elsewhere)
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A)
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S)
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D)
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F)
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G)
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H)
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J)
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K)
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L)
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON)
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE)
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP)
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA_PAD)
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("row_4")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_UNUSED) // Left Shift (handled elsewhere)
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z)
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X)
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C)
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V)
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B)
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N)
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M)
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA)
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP)
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH)
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_UNUSED) // Right Shift (handled elsewhere)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Line Feed")
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN)
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD)
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("row_5")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Comp Char")
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE)
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_UNUSED) // Lock
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD)
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD)
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END
ioport_constructor hds200_kbd_hle_device::device_input_ports() const
{
return INPUT_PORTS_NAME( keyboard );
}
void hds200_kbd_hle_device::device_add_mconfig(machine_config &config)
{
SPEAKER(config, "mono").front_center();
BEEP(config, m_bell, 786).add_route(ALL_OUTPUTS, "mono", 0.5); // unknown frequency
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// hds200_kbd_hle_device - constructor
//-------------------------------------------------
hds200_kbd_hle_device::hds200_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, HDS200_KBD_HLE, tag, owner, clock),
device_buffered_serial_interface(mconfig, *this),
device_matrix_keyboard_interface(mconfig, *this, "row_0", "row_1", "row_2", "row_3", "row_4", "row_5"),
m_bell(*this, "bell"),
m_modifiers(*this, "mod"),
m_tx_handler(*this)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void hds200_kbd_hle_device::device_start()
{
// resolve callbacks
m_tx_handler.resolve_safe();
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void hds200_kbd_hle_device::device_reset()
{
clear_fifo();
receive_register_reset();
transmit_register_reset();
set_data_frame(1, 8, PARITY_EVEN, STOP_BITS_2);
set_rcv_rate(2400);
set_tra_rate(2400);
reset_key_state();
start_processing(attotime::from_hz(2400));
typematic_stop();
}
//-------------------------------------------------
// tra_callback - send bit to host
//-------------------------------------------------
void hds200_kbd_hle_device::tra_callback()
{
m_tx_handler(transmit_register_get_data_bit());
}
//-------------------------------------------------
// received_byte - handle received byte
//-------------------------------------------------
void hds200_kbd_hle_device::received_byte(uint8_t byte)
{
logerror("Received from host: %02x\n", byte);
switch (byte & 0xc0)
{
// state
case 0x00:
// 76------ 00
// --5----- caps lock led
// ---43--- unknown
// -----2-- insert mode
// ------1- led l1
// -------0 bell
m_bell->set_state(BIT(byte, 0));
break;
// volume
case 0xc0:
// 76------ 11
// --543--- bell volume
// -----210 keyclick volume
int bell_vol = (byte >> 3) & 0x07;
m_bell->set_output_gain(0, bell_vol / 7.0);
break;
}
}
//-------------------------------------------------
// key_make - handle a key being pressed
//-------------------------------------------------
void hds200_kbd_hle_device::key_make(uint8_t row, uint8_t column)
{
uint8_t code = translate(row, column);
// send the code
if (code != 0x00)
{
transmit_byte(code);
typematic_start(row, column, attotime::from_msec(750), attotime::from_msec(50));
}
}
//-------------------------------------------------
// key_break - handle a key being released
//-------------------------------------------------
void hds200_kbd_hle_device::key_break(uint8_t row, uint8_t column)
{
if (typematic_is(row, column))
typematic_stop();
}
//-------------------------------------------------
// key_repeat - handle a key being repeated
//-------------------------------------------------
void hds200_kbd_hle_device::key_repeat(u8 row, u8 column)
{
uint8_t code = translate(row, column);
if (code != 0x00)
transmit_byte(code);
}
//-------------------------------------------------
// rx_w - receive bit from host
//-------------------------------------------------
void hds200_kbd_hle_device::rx_w(int state)
{
device_buffered_serial_interface::rx_w(state);
}
//-------------------------------------------------
// translate - row and column to key code
//-------------------------------------------------
uint8_t hds200_kbd_hle_device::translate(uint8_t row, uint8_t column)
{
uint8_t const modifiers(m_modifiers->read());
bool const ctrl(modifiers & 0x01);
bool const shift(bool(modifiers & 0x02) || bool(modifiers & 0x04) || bool(modifiers & 0x08));
bool const ctrl_shift(ctrl && shift);
unsigned const map(ctrl_shift? 3 : ctrl ? 2 : shift ? 1 : 0);
return TRANSLATION_TABLE[map][row][column];
}

View File

@ -0,0 +1,66 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
HDS200 Keyboard (HLE)
***************************************************************************/
#ifndef MAME_MACHINE_HDS200_KBD_H
#define MAME_MACHINE_HDS200_KBD_H
#pragma once
#include "machine/keyboard.h"
#include "sound/beep.h"
#include "diserial.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> hds200_kbd_hle_device
class hds200_kbd_hle_device : public device_t,
public device_buffered_serial_interface<16>,
protected device_matrix_keyboard_interface<6>
{
public:
// construction/destruction
hds200_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
// callbacks
auto tx_handler() { return m_tx_handler.bind(); }
// from host
void rx_w(int state);
protected:
// device_t overrides
virtual ioport_constructor device_input_ports() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
// device_buffered_serial_interface overrides
virtual void tra_callback() override;
virtual void received_byte(uint8_t byte) override;
// device_matrix_keyboard_interface overrides
virtual void key_make(uint8_t row, uint8_t column) override;
virtual void key_break(uint8_t row, uint8_t column) override;
virtual void key_repeat(uint8_t row, uint8_t column) override;
private:
required_device<beep_device> m_bell;
required_ioport m_modifiers;
devcb_write_line m_tx_handler;
uint8_t translate(uint8_t row, uint8_t column);
};
// device type definition
DECLARE_DEVICE_TYPE(HDS200_KBD_HLE, hds200_kbd_hle_device)
#endif // MAME_MACHINE_HDS200_KBD_H