mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
tek410x: Add keyboard [AJR, Bitsavers]
* tek440x: Hook up 410X keyboard to pass boot test * mc68681: Wait until transmitter is actually empty to set TxEMT
This commit is contained in:
parent
da24cd8d9b
commit
57d621860c
@ -3908,6 +3908,8 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/tek440x.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/tekigw.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/tekxp33x.cpp",
|
||||
MAME_DIR .. "src/mame/machine/tek410x_kbd.cpp",
|
||||
MAME_DIR .. "src/mame/machine/tek410x_kbd.h",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "telenova")
|
||||
|
@ -1269,7 +1269,7 @@ void duart_channel::tra_complete()
|
||||
{
|
||||
//printf("%s ch %d Tx complete\n", tag(), m_ch);
|
||||
tx_ready = 1;
|
||||
SR |= STATUS_TRANSMITTER_READY;
|
||||
SR |= STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY;
|
||||
|
||||
if (m_ch == 0)
|
||||
m_uart->set_ISR_bits(INT_TXRDYA);
|
||||
@ -1319,24 +1319,13 @@ void duart_channel::update_interrupts()
|
||||
switch (MR2 & 0xc0) // what mode are we in?
|
||||
{
|
||||
case 0x00: // normal mode
|
||||
if (tx_enabled)
|
||||
SR |= STATUS_TRANSMITTER_EMPTY;
|
||||
else
|
||||
SR &= ~STATUS_TRANSMITTER_EMPTY;
|
||||
break;
|
||||
case 0x40: // automatic echo mode
|
||||
SR &= ~STATUS_TRANSMITTER_EMPTY;
|
||||
SR &= ~STATUS_TRANSMITTER_READY;
|
||||
break;
|
||||
case 0x80: // local loopback mode
|
||||
if (tx_enabled)
|
||||
SR |= STATUS_TRANSMITTER_EMPTY;
|
||||
else
|
||||
SR &= ~STATUS_TRANSMITTER_EMPTY;
|
||||
break;
|
||||
case 0xc0: // remote loopback mode
|
||||
// write me, what the txrdy/txemt regs do for remote loopback mode is undocumented afaik, for now just clear both
|
||||
SR &= ~STATUS_TRANSMITTER_EMPTY;
|
||||
SR &= ~STATUS_TRANSMITTER_READY;
|
||||
break;
|
||||
}
|
||||
@ -1571,7 +1560,8 @@ void duart_channel::write_CR(uint8_t data)
|
||||
break;
|
||||
case 3: /* Reset channel transmitter */
|
||||
tx_enabled = 0;
|
||||
SR &= ~STATUS_TRANSMITTER_READY;
|
||||
tx_ready = 0;
|
||||
SR &= ~(STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY);
|
||||
if (m_ch == 0)
|
||||
m_uart->clear_ISR_bits(INT_TXRDYA);
|
||||
else
|
||||
@ -1636,7 +1626,7 @@ void duart_channel::write_CR(uint8_t data)
|
||||
{
|
||||
tx_enabled = 1;
|
||||
tx_ready = 1;
|
||||
SR |= STATUS_TRANSMITTER_READY;
|
||||
SR |= STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY;
|
||||
if (m_ch == 0)
|
||||
m_uart->set_ISR_bits(INT_TXRDYA);
|
||||
else
|
||||
@ -1646,7 +1636,7 @@ void duart_channel::write_CR(uint8_t data)
|
||||
{
|
||||
tx_enabled = 0;
|
||||
tx_ready = 0;
|
||||
SR &= ~STATUS_TRANSMITTER_READY;
|
||||
SR &= ~(STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY);
|
||||
if (m_ch == 0)
|
||||
m_uart->clear_ISR_bits(INT_TXRDYA);
|
||||
else
|
||||
@ -1668,7 +1658,7 @@ void duart_channel::write_TX(uint8_t data)
|
||||
//printf("%s ch %d Tx %c [%02x]\n", tag(), m_ch, isprint(data) ? data : ' ', data);
|
||||
|
||||
tx_ready = 0;
|
||||
SR &= ~STATUS_TRANSMITTER_READY;
|
||||
SR &= ~(STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY);
|
||||
|
||||
if (m_ch == 0)
|
||||
m_uart->clear_ISR_bits(INT_TXRDYA);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
// copyright-holders:Curt Coder, AJR
|
||||
/***************************************************************************
|
||||
|
||||
Tektronix 4107A/4109A
|
||||
@ -8,19 +8,11 @@
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- everything
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/i86/i186.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/mc68681.h"
|
||||
#include "machine/tek410x_kbd.h"
|
||||
#include "video/crt9007.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
@ -31,7 +23,19 @@ class tek4107a_state : public driver_device
|
||||
public:
|
||||
tek4107a_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_duart(*this, "duart%u", 0U)
|
||||
, m_keyboard(*this, "keyboard")
|
||||
, m_vpac(*this, "vpac")
|
||||
, m_ppi_pc(0)
|
||||
, m_kb_rdata(true)
|
||||
, m_kb_tdata(true)
|
||||
, m_kb_rclamp(false)
|
||||
, m_graphics_control(0)
|
||||
, m_alpha_control(0)
|
||||
, m_x_position(0)
|
||||
, m_y_position(0)
|
||||
, m_x_cursor(0)
|
||||
, m_y_cursor(0)
|
||||
{ }
|
||||
|
||||
void tek4109a(machine_config &config);
|
||||
@ -46,10 +50,45 @@ private:
|
||||
|
||||
u8 vpac_r(offs_t offset);
|
||||
|
||||
u16 nmi_enable_r();
|
||||
u16 nmi_disable_r();
|
||||
u16 system_reset_r();
|
||||
|
||||
void ppi_pc_w(u8 data);
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_rdata_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_tdata_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_rclamp_w);
|
||||
|
||||
void xpos_w(u16 data);
|
||||
void ypos_w(u16 data);
|
||||
void xcur_w(u16 data);
|
||||
void ycur_w(u16 data);
|
||||
void tbwin_w(u16 data);
|
||||
u16 gcntl_r();
|
||||
void gcntl_w(u16 data);
|
||||
u16 acntl_r();
|
||||
void acntl_w(u16 data);
|
||||
u16 test_r();
|
||||
u8 font_r();
|
||||
|
||||
void tek4107a_io(address_map &map);
|
||||
void tek4107a_mem(address_map &map);
|
||||
|
||||
required_device_array<scn2681_device, 2> m_duart;
|
||||
required_device<tek410x_keyboard_device> m_keyboard;
|
||||
required_device<crt9007_device> m_vpac;
|
||||
|
||||
u8 m_ppi_pc;
|
||||
bool m_kb_rdata;
|
||||
bool m_kb_tdata;
|
||||
bool m_kb_rclamp;
|
||||
|
||||
u16 m_graphics_control;
|
||||
u16 m_alpha_control;
|
||||
u16 m_x_position;
|
||||
u16 m_y_position;
|
||||
u16 m_x_cursor;
|
||||
u16 m_y_cursor;
|
||||
};
|
||||
|
||||
u8 tek4107a_state::vpac_r(offs_t offset)
|
||||
@ -57,22 +96,150 @@ u8 tek4107a_state::vpac_r(offs_t offset)
|
||||
return m_vpac->read(offset + 0x20);
|
||||
}
|
||||
|
||||
u16 tek4107a_state::nmi_enable_r()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 tek4107a_state::nmi_disable_r()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 tek4107a_state::system_reset_r()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tek4107a_state::ppi_pc_w(u8 data)
|
||||
{
|
||||
if (!m_kb_rclamp && BIT(m_ppi_pc, 2) != BIT(data, 2))
|
||||
m_keyboard->kdo_w(!BIT(data, 2) || m_kb_tdata);
|
||||
|
||||
m_ppi_pc = data;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek4107a_state::kb_rdata_w)
|
||||
{
|
||||
m_kb_rdata = state;
|
||||
if (!m_kb_rclamp)
|
||||
m_duart[0]->rx_a_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek4107a_state::kb_rclamp_w)
|
||||
{
|
||||
if (m_kb_rclamp != !state)
|
||||
{
|
||||
m_kb_rclamp = !state;
|
||||
|
||||
// Clamp RXDA to 1 and KBRDATA to 0 when DUART asserts RxRDYA
|
||||
if (m_kb_tdata || !BIT(m_ppi_pc, 2))
|
||||
m_keyboard->kdo_w(state);
|
||||
m_duart[0]->rx_a_w(state ? m_kb_rdata : 1);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek4107a_state::kb_tdata_w)
|
||||
{
|
||||
if (m_kb_tdata != state)
|
||||
{
|
||||
m_kb_tdata = state;
|
||||
|
||||
m_duart[0]->ip4_w(!state);
|
||||
if (BIT(m_ppi_pc, 2) && m_kb_rdata && !m_kb_rclamp)
|
||||
m_keyboard->kdo_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
void tek4107a_state::xpos_w(u16 data)
|
||||
{
|
||||
m_x_position = data & 0x03ff;
|
||||
}
|
||||
|
||||
void tek4107a_state::ypos_w(u16 data)
|
||||
{
|
||||
m_y_position = data & 0x01ff;
|
||||
}
|
||||
|
||||
void tek4107a_state::xcur_w(u16 data)
|
||||
{
|
||||
m_x_cursor = data & 0x03ff;
|
||||
}
|
||||
|
||||
void tek4107a_state::ycur_w(u16 data)
|
||||
{
|
||||
m_y_cursor = data & 0x01ff;
|
||||
}
|
||||
|
||||
void tek4107a_state::tbwin_w(u16 data)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
u16 tek4107a_state::gcntl_r()
|
||||
{
|
||||
return m_graphics_control;
|
||||
}
|
||||
|
||||
void tek4107a_state::gcntl_w(u16 data)
|
||||
{
|
||||
m_graphics_control = data;
|
||||
}
|
||||
|
||||
u16 tek4107a_state::acntl_r()
|
||||
{
|
||||
return m_alpha_control;
|
||||
}
|
||||
|
||||
void tek4107a_state::acntl_w(u16 data)
|
||||
{
|
||||
m_alpha_control = data;
|
||||
}
|
||||
|
||||
u16 tek4107a_state::test_r()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 tek4107a_state::font_r()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Memory Maps */
|
||||
|
||||
void tek4107a_state::tek4107a_mem(address_map &map)
|
||||
{
|
||||
map(0x00000, 0x7ffff).ram();
|
||||
map(0x00000, 0x3ffff).ram();
|
||||
map(0x40000, 0x7ffff).ram().share("gfxram");
|
||||
map(0x80000, 0xbffff).rom().region("firmware", 0);
|
||||
map(0xf0000, 0xfffff).rom().region("firmware", 0x30000);
|
||||
}
|
||||
|
||||
void tek4107a_state::tek4107a_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x001f).rw("duart0", FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff);
|
||||
map(0x0000, 0x001f).rw("duart1", FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0xff00);
|
||||
map(0x0000, 0x001f).rw(m_duart[0], FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff);
|
||||
map(0x0000, 0x001f).rw(m_duart[1], FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0xff00);
|
||||
map(0x0080, 0x00bf).r(FUNC(tek4107a_state::vpac_r)).w(m_vpac, FUNC(crt9007_device::write)).umask16(0x00ff);
|
||||
map(0x00ce, 0x00cf).ram();
|
||||
map(0x00c0, 0x00c1).w(FUNC(tek4107a_state::xpos_w));
|
||||
map(0x00c2, 0x00c3).w(FUNC(tek4107a_state::ypos_w));
|
||||
map(0x00c4, 0x00c5).w(FUNC(tek4107a_state::xcur_w));
|
||||
map(0x00c6, 0x00c7).w(FUNC(tek4107a_state::ycur_w));
|
||||
map(0x00c8, 0x00c9).r(FUNC(tek4107a_state::test_r));
|
||||
map(0x00ca, 0x00ca).r(FUNC(tek4107a_state::font_r));
|
||||
map(0x00ca, 0x00cb).w(FUNC(tek4107a_state::tbwin_w));
|
||||
map(0x00cc, 0x00cd).rw(FUNC(tek4107a_state::gcntl_r), FUNC(tek4107a_state::gcntl_w));
|
||||
map(0x00ce, 0x00cf).rw(FUNC(tek4107a_state::acntl_r), FUNC(tek4107a_state::acntl_w));
|
||||
map(0x0100, 0x0107).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00);
|
||||
map(0x0200, 0x0201).r(FUNC(tek4107a_state::nmi_enable_r));
|
||||
map(0x0280, 0x0281).r(FUNC(tek4107a_state::system_reset_r));
|
||||
map(0x0300, 0x0301).r(FUNC(tek4107a_state::nmi_disable_r));
|
||||
}
|
||||
|
||||
/* Input Ports */
|
||||
@ -84,6 +251,12 @@ INPUT_PORTS_END
|
||||
|
||||
void tek4107a_state::video_start()
|
||||
{
|
||||
save_item(NAME(m_graphics_control));
|
||||
save_item(NAME(m_alpha_control));
|
||||
save_item(NAME(m_x_position));
|
||||
save_item(NAME(m_y_position));
|
||||
save_item(NAME(m_x_cursor));
|
||||
save_item(NAME(m_y_cursor));
|
||||
}
|
||||
|
||||
u32 tek4107a_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
@ -110,6 +283,10 @@ GFXDECODE_END
|
||||
|
||||
void tek4107a_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_ppi_pc));
|
||||
save_item(NAME(m_kb_rdata));
|
||||
save_item(NAME(m_kb_tdata));
|
||||
save_item(NAME(m_kb_rclamp));
|
||||
}
|
||||
|
||||
/* Machine Driver */
|
||||
@ -117,25 +294,34 @@ void tek4107a_state::machine_start()
|
||||
void tek4107a_state::tek4107a(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
i80186_cpu_device &maincpu(I80186(config, "maincpu", 21000000));
|
||||
i80186_cpu_device &maincpu(I80186(config, "maincpu", 14.7456_MHz_XTAL));
|
||||
maincpu.set_addrmap(AS_PROGRAM, &tek4107a_state::tek4107a_mem);
|
||||
maincpu.set_addrmap(AS_IO, &tek4107a_state::tek4107a_io);
|
||||
|
||||
SCN2681(config, m_duart[0], 14.7456_MHz_XTAL / 4);
|
||||
m_duart[0]->irq_cb().set("maincpu", FUNC(i80186_cpu_device::int0_w));
|
||||
m_duart[0]->outport_cb().set_inputline("maincpu", INPUT_LINE_NMI).bit(5).invert(); // RxRDYB
|
||||
m_duart[0]->outport_cb().append(FUNC(tek4107a_state::kb_rclamp_w)).bit(4);
|
||||
m_duart[0]->outport_cb().append(m_keyboard, FUNC(tek410x_keyboard_device::reset_w)).bit(3);
|
||||
m_duart[0]->a_tx_cb().set(m_keyboard, FUNC(tek410x_keyboard_device::kdi_w));
|
||||
|
||||
SCN2681(config, m_duart[1], 14.7456_MHz_XTAL / 4);
|
||||
m_duart[1]->irq_cb().set("maincpu", FUNC(i80186_cpu_device::int2_w));
|
||||
|
||||
i8255_device &ppi(I8255(config, "ppi"));
|
||||
ppi.in_pb_callback().set_constant(0x30);
|
||||
ppi.out_pc_callback().set(FUNC(tek4107a_state::ppi_pc_w));
|
||||
|
||||
TEK410X_KEYBOARD(config, m_keyboard);
|
||||
m_keyboard->tdata_callback().set(FUNC(tek4107a_state::kb_tdata_w));
|
||||
m_keyboard->rdata_callback().set(FUNC(tek4107a_state::kb_rdata_w));
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(25200000, 800, 0, 640, 525, 0, 480);
|
||||
screen.set_raw(25.2_MHz_XTAL, 800, 0, 640, 525, 0, 480);
|
||||
screen.set_screen_update(FUNC(tek4107a_state::screen_update));
|
||||
|
||||
scn2681_device &duart0(SCN2681(config, "duart0", 3686400));
|
||||
duart0.irq_cb().set("maincpu", FUNC(i80186_cpu_device::int0_w));
|
||||
duart0.outport_cb().set_inputline("maincpu", INPUT_LINE_NMI).bit(5).invert(); // RxRDYB
|
||||
|
||||
scn2681_device &duart1(SCN2681(config, "duart1", 3686400));
|
||||
duart1.irq_cb().set("maincpu", FUNC(i80186_cpu_device::int2_w));
|
||||
|
||||
I8255(config, "ppi").in_pb_callback().set_constant(0x30);
|
||||
|
||||
CRT9007(config, m_vpac, 25200000 / 8);
|
||||
CRT9007(config, m_vpac, 25.2_MHz_XTAL / 8);
|
||||
m_vpac->set_screen("screen");
|
||||
m_vpac->set_character_width(8);
|
||||
m_vpac->int_callback().set("maincpu", FUNC(i80186_cpu_device::int1_w));
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
// copyright-holders:R. Belmont, AJR
|
||||
/***************************************************************************
|
||||
|
||||
Tektronix 440x "AI Workstations"
|
||||
@ -45,12 +45,12 @@
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "machine/am9513.h"
|
||||
#include "machine/bankdev.h"
|
||||
#include "machine/mos6551.h" // debug tty
|
||||
#include "machine/mc146818.h"
|
||||
#include "machine/mc68681.h"
|
||||
#include "machine/tek410x_kbd.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
@ -65,10 +65,17 @@ public:
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_fdccpu(*this, "fdccpu"),
|
||||
m_vm(*this, "vm"),
|
||||
m_duart(*this, "duart"),
|
||||
m_keyboard(*this, "keyboard"),
|
||||
m_snsnd(*this, "snsnd"),
|
||||
m_prom(*this, "maincpu"),
|
||||
m_mainram(*this, "mainram"),
|
||||
m_vram(*this, "vram")
|
||||
m_vram(*this, "vram"),
|
||||
m_boot(false),
|
||||
m_kb_rdata(true),
|
||||
m_kb_tdata(true),
|
||||
m_kb_rclamp(false),
|
||||
m_kb_loop(false)
|
||||
{ }
|
||||
|
||||
void tek4404(machine_config &config);
|
||||
@ -81,6 +88,11 @@ private:
|
||||
u16 memory_r(offs_t offset, u16 mem_mask);
|
||||
void memory_w(offs_t offset, u16 data, u16 mem_mask);
|
||||
void sound_w(u8 data);
|
||||
void diag_w(u8 data);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_rdata_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_tdata_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(kb_rclamp_w);
|
||||
|
||||
void logical_map(address_map &map);
|
||||
void physical_map(address_map &map);
|
||||
@ -89,12 +101,18 @@ private:
|
||||
required_device<m68010_device> m_maincpu;
|
||||
required_device<m6502_device> m_fdccpu;
|
||||
required_device<address_map_bank_device> m_vm;
|
||||
required_device<mc68681_device> m_duart;
|
||||
required_device<tek410x_keyboard_device> m_keyboard;
|
||||
required_device<sn76496_device> m_snsnd;
|
||||
required_region_ptr<u16> m_prom;
|
||||
required_shared_ptr<u16> m_mainram;
|
||||
required_shared_ptr<u16> m_vram;
|
||||
|
||||
bool m_boot;
|
||||
bool m_kb_rdata;
|
||||
bool m_kb_tdata;
|
||||
bool m_kb_rclamp;
|
||||
bool m_kb_loop;
|
||||
};
|
||||
|
||||
/*************************************
|
||||
@ -106,6 +124,10 @@ private:
|
||||
void tek440x_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_boot));
|
||||
save_item(NAME(m_kb_rdata));
|
||||
save_item(NAME(m_kb_tdata));
|
||||
save_item(NAME(m_kb_rclamp));
|
||||
save_item(NAME(m_kb_loop));
|
||||
}
|
||||
|
||||
|
||||
@ -119,6 +141,8 @@ void tek440x_state::machine_start()
|
||||
void tek440x_state::machine_reset()
|
||||
{
|
||||
m_boot = true;
|
||||
diag_w(0);
|
||||
m_keyboard->kdo_w(1);
|
||||
}
|
||||
|
||||
|
||||
@ -178,6 +202,46 @@ void tek440x_state::sound_w(u8 data)
|
||||
m_boot = false;
|
||||
}
|
||||
|
||||
void tek440x_state::diag_w(u8 data)
|
||||
{
|
||||
if (!m_kb_rclamp && m_kb_loop != BIT(data, 7))
|
||||
m_keyboard->kdo_w(!BIT(data, 7) || m_kb_tdata);
|
||||
|
||||
m_kb_loop = BIT(data, 7);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek440x_state::kb_rdata_w)
|
||||
{
|
||||
m_kb_rdata = state;
|
||||
if (!m_kb_rclamp)
|
||||
m_duart->rx_a_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek440x_state::kb_rclamp_w)
|
||||
{
|
||||
if (m_kb_rclamp != !state)
|
||||
{
|
||||
m_kb_rclamp = !state;
|
||||
|
||||
// Clamp RXDA to 1 and KBRDATA to 0 when DUART asserts RxRDYA
|
||||
if (m_kb_tdata || !m_kb_loop)
|
||||
m_keyboard->kdo_w(state);
|
||||
m_duart->rx_a_w(state ? m_kb_rdata : 1);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek440x_state::kb_tdata_w)
|
||||
{
|
||||
if (m_kb_tdata != state)
|
||||
{
|
||||
m_kb_tdata = state;
|
||||
|
||||
m_duart->ip4_w(!state);
|
||||
if (m_kb_loop && m_kb_rdata && !m_kb_rclamp)
|
||||
m_keyboard->kdo_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
void tek440x_state::logical_map(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x7fffff).rw(FUNC(tek440x_state::memory_r), FUNC(tek440x_state::memory_w));
|
||||
@ -195,9 +259,10 @@ void tek440x_state::physical_map(address_map &map)
|
||||
map(0x788000, 0x788000).w(FUNC(tek440x_state::sound_w));
|
||||
// 78a000-78bfff: NS32081 FPU
|
||||
map(0x78c000, 0x78c007).rw("aica", FUNC(mos6551_device::read), FUNC(mos6551_device::write)).umask16(0xff00);
|
||||
map(0x7b0000, 0x7b0000).w(FUNC(tek440x_state::diag_w));
|
||||
// 7b1000-7b2fff: diagnostic registers
|
||||
// 7b2000-7b3fff: Centronics printer data
|
||||
map(0x7b4000, 0x7b401f).rw("duart", FUNC(mc68681_device::read), FUNC(mc68681_device::write)).umask16(0xff00);
|
||||
map(0x7b4000, 0x7b401f).rw(m_duart, FUNC(mc68681_device::read), FUNC(mc68681_device::write)).umask16(0xff00);
|
||||
// 7b6000-7b7fff: Mouse
|
||||
map(0x7b8000, 0x7b8003).mirror(0x100).rw("timer", FUNC(am9513_device::read16), FUNC(am9513_device::write16));
|
||||
// 7ba000-7bbfff: MC146818 RTC
|
||||
@ -254,10 +319,15 @@ void tek440x_state::tek4404(machine_config &config)
|
||||
aica.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
|
||||
aica.irq_handler().set_inputline(m_maincpu, M68K_IRQ_7);
|
||||
|
||||
mc68681_device &duart(MC68681(config, "duart", 3.6864_MHz_XTAL));
|
||||
duart.irq_cb().set_inputline(m_maincpu, M68K_IRQ_5);
|
||||
MC68681(config, m_duart, 3.6864_MHz_XTAL);
|
||||
m_duart->irq_cb().set_inputline(m_maincpu, M68K_IRQ_5); // auto-vectored
|
||||
m_duart->outport_cb().set(FUNC(tek440x_state::kb_rclamp_w)).bit(4);
|
||||
m_duart->outport_cb().append(m_keyboard, FUNC(tek410x_keyboard_device::reset_w)).bit(3);
|
||||
m_duart->a_tx_cb().set(m_keyboard, FUNC(tek410x_keyboard_device::kdi_w));
|
||||
|
||||
I8048(config, "kbdmcu", 4.608_MHz_XTAL).set_disable();
|
||||
TEK410X_KEYBOARD(config, m_keyboard);
|
||||
m_keyboard->tdata_callback().set(FUNC(tek440x_state::kb_tdata_w));
|
||||
m_keyboard->rdata_callback().set(FUNC(tek440x_state::kb_rdata_w));
|
||||
|
||||
AM9513(config, "timer", 40_MHz_XTAL / 4 / 10); // from CPU E output
|
||||
|
||||
@ -293,9 +363,6 @@ ROM_START( tek4404 )
|
||||
|
||||
ROM_REGION( 0x2000, "scsimfm", 0 )
|
||||
ROM_LOAD( "scsi_mfm.bin", 0x000000, 0x002000, CRC(b4293435) SHA1(5e2b96c19c4f5c63a5afa2de504d29fe64a4c908) )
|
||||
|
||||
ROM_REGION( 0x400, "kbdmcu", 0 )
|
||||
ROM_LOAD( "keytronic_8x48.bin", 0x000, 0x400, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
/*************************************
|
||||
|
385
src/mame/machine/tek410x_kbd.cpp
Normal file
385
src/mame/machine/tek410x_kbd.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
This emulates the standard serial keyboard used with Tektronix's
|
||||
4105, 4106, 4107 and 4109 terminals, including the trademark
|
||||
octagonal "joy disk". The 4404 keyboard is also compatible.
|
||||
|
||||
The hardware was designed by the Keytronic Corporation, and uses
|
||||
their 20-pin key strobe driver (22-0950-003) and input receiver
|
||||
(22-0908-003) ASICs.
|
||||
|
||||
The 8048/8748's DB pins are connected to drivers for up to 5 LEDs,
|
||||
but only one of these LEDs (CR9, on the Caps Lock key) is actually
|
||||
populated.
|
||||
|
||||
A different but apparently backward-compatible keyboard was used
|
||||
with the CX4107 and CX4109, based on a 8051 CPU with space for an
|
||||
external program ROM and adding an onboard speaker as well as many
|
||||
extra keys and an IBM 3279-style layout.
|
||||
|
||||
Hexadecimal table of press codes (release codes are the same + 80):
|
||||
|
||||
00 Caps Lock
|
||||
01 Left Shift
|
||||
02 Right Shift
|
||||
03 Ctrl
|
||||
04 DEras/SEras
|
||||
05 Break
|
||||
06 Back Space
|
||||
07 Tab
|
||||
08 Line Feed
|
||||
09 Return
|
||||
0A Esc
|
||||
0B Space Bar
|
||||
0C " '
|
||||
0D < ,
|
||||
0E _ -
|
||||
0F > .
|
||||
10 ? /
|
||||
11 ) 0
|
||||
12 ! 1
|
||||
13 @ 2
|
||||
14 # 3
|
||||
15 $ 4
|
||||
16 % 5
|
||||
17 ^ 6
|
||||
18 & 7
|
||||
19 * 8
|
||||
1A ( 9
|
||||
1B : ;
|
||||
1C =
|
||||
1D A
|
||||
1E B
|
||||
1F C
|
||||
20 D
|
||||
21 E
|
||||
22 F
|
||||
23 G
|
||||
24 H
|
||||
25 I
|
||||
26 J
|
||||
27 K
|
||||
28 L
|
||||
29 M
|
||||
2A N
|
||||
2B O
|
||||
2C P
|
||||
2D Q
|
||||
2E R
|
||||
2F S
|
||||
30 T
|
||||
31 U
|
||||
32 V
|
||||
33 W
|
||||
34 X
|
||||
35 Y
|
||||
36 Z
|
||||
37 { [
|
||||
38 ` \
|
||||
39 } ]
|
||||
3A ~ |
|
||||
3B Rub Out
|
||||
3C Enter (keypad)
|
||||
3D , (keypad)
|
||||
3E - (keypad)
|
||||
3F . (keypad)
|
||||
40 0 (keypad)
|
||||
41 1 (keypad)
|
||||
42 2 (keypad)
|
||||
43 3 (keypad)
|
||||
44 4 (keypad)
|
||||
45 5 (keypad)
|
||||
46 6 (keypad)
|
||||
47 7 (keypad)
|
||||
48 8 (keypad)
|
||||
49 9 (keypad)
|
||||
4A F1
|
||||
4B F2
|
||||
4C F3
|
||||
4D F4
|
||||
4E F5
|
||||
4F F6
|
||||
50 F7
|
||||
51 F8
|
||||
52 GEras/Dialog
|
||||
53 Cancel/Setup
|
||||
54 DCopy/SCopy
|
||||
55 Menu
|
||||
56 Cursor Right (joystick)
|
||||
57 Cursor Up (joystick)
|
||||
58 Cursor Left (joystick)
|
||||
59 Cursor Down (joystick)
|
||||
|
||||
Additional press codes for CX keyboard only:
|
||||
|
||||
5A Erase EOF
|
||||
5B Dup/PA1
|
||||
5C Reset/Dev Cncl
|
||||
5D Field Mark/PA2/_
|
||||
5E Attn Sys Req
|
||||
5F Cursr Sel/Clear
|
||||
60 < >
|
||||
61 Cursr Blink/Alt Cursr
|
||||
62 Ident
|
||||
63 Down Arrow
|
||||
64 Right Arrow/Right Double Arrow
|
||||
65 Left Arrow/Left Double Arrow
|
||||
66 Up Arrow
|
||||
67 Insert/Alpha
|
||||
68 Right Alt/Ctrl
|
||||
|
||||
The baud rate is 4800, with 8 data bits and no parity.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "tek410x_kbd.h"
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(TEK410X_KEYBOARD, tek410x_keyboard_device, "tek410x_kbd", "Tektronix 410X Standard Keyboard (119-1592-01)")
|
||||
|
||||
tek410x_keyboard_device::tek410x_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, TEK410X_KEYBOARD, tag, owner, clock)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_key_matrix(*this, "X%u", 0U)
|
||||
, m_config(*this, "CONFIG")
|
||||
, m_tdata_callback(*this)
|
||||
, m_rdata_callback(*this)
|
||||
, m_select(0)
|
||||
, m_p2_out(0)
|
||||
, m_kdi(true)
|
||||
, m_kdo(false)
|
||||
{
|
||||
}
|
||||
|
||||
void tek410x_keyboard_device::device_resolve_objects()
|
||||
{
|
||||
m_tdata_callback.resolve_safe();
|
||||
m_rdata_callback.resolve_safe();
|
||||
}
|
||||
|
||||
void tek410x_keyboard_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_select));
|
||||
save_item(NAME(m_p2_out));
|
||||
save_item(NAME(m_kdi));
|
||||
save_item(NAME(m_kdo));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek410x_keyboard_device::kdi_w)
|
||||
{
|
||||
m_kdi = state;
|
||||
if (BIT(m_p2_out, 7))
|
||||
{
|
||||
m_mcu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE);
|
||||
m_tdata_callback(state);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek410x_keyboard_device::kdo_w)
|
||||
{
|
||||
m_kdo = state;
|
||||
if (BIT(m_p2_out, 5))
|
||||
m_rdata_callback(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tek410x_keyboard_device::reset_w)
|
||||
{
|
||||
m_mcu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE);
|
||||
if (!state)
|
||||
p2_w(0xff);
|
||||
}
|
||||
|
||||
u8 tek410x_keyboard_device::p1_r()
|
||||
{
|
||||
if (m_select < 12)
|
||||
return m_key_matrix[m_select]->read();
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
u8 tek410x_keyboard_device::p2_r()
|
||||
{
|
||||
return 0xb0 | (m_kdo ? (m_p2_out & 0x20) << 1 : 0) | m_config->read();
|
||||
}
|
||||
|
||||
void tek410x_keyboard_device::p2_w(u8 data)
|
||||
{
|
||||
if (!BIT(data, 4))
|
||||
m_select = m_mcu->p1_r() & 0x0f;
|
||||
|
||||
if (m_kdi && BIT(data, 7) != BIT(m_p2_out, 7))
|
||||
{
|
||||
m_tdata_callback(BIT(data, 7));
|
||||
m_mcu->set_input_line(MCS48_INPUT_IRQ, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
if (m_kdo && BIT(data, 5) != BIT(m_p2_out, 5))
|
||||
m_rdata_callback(BIT(data, 5));
|
||||
|
||||
m_p2_out = data;
|
||||
}
|
||||
|
||||
void tek410x_keyboard_device::ext_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0xff).nopr();
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START(tek410x_keyboard)
|
||||
PORT_START("X0")
|
||||
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(COMMA_PAD)) PORT_CODE(KEYCODE_PLUS_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD)
|
||||
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(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD)
|
||||
|
||||
PORT_START("X1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD)
|
||||
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(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD)
|
||||
|
||||
PORT_START("X2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") //PORT_CODE(KEYCODE_XXX)
|
||||
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("Line Feed") PORT_CHAR(0x0a) //PORT_CODE(KEYCODE_XXX)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Rub Out") PORT_CODE(KEYCODE_BACKSPACE)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_BACKSLASH)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
|
||||
PORT_START("X3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT)
|
||||
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('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_CLOSEBRACE)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space Bar") PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE)
|
||||
|
||||
PORT_START("X4")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CODE(KEYCODE_DOWN)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CODE(KEYCODE_LEFT)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F11)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F6)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F10)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Setup Cancel") PORT_CODE(KEYCODE_F2)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F7)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SCopy DCopy") PORT_CODE(KEYCODE_F3)
|
||||
|
||||
PORT_START("X5")
|
||||
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(F8)) PORT_CODE(KEYCODE_F12)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F5)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F9)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dialog GEras") PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F8)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Menu") PORT_CODE(KEYCODE_F4)
|
||||
|
||||
PORT_START("X6")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q)
|
||||
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_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z)
|
||||
|
||||
PORT_START("X7")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_LCONTROL)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) //PORT_CODE(KEYCODE_XXX)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR(0x09) //PORT_CODE(KEYCODE_XXX)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('|') PORT_CHAR('~') PORT_CODE(KEYCODE_TAB)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SEras DEras") //PORT_CODE(KEYCODE_XXX)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_SHIFT_2) PORT_CODE(KEYCODE_CAPSLOCK)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_TILDE)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CHAR(UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT)
|
||||
|
||||
PORT_START("X8")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R)
|
||||
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_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V)
|
||||
|
||||
PORT_START("X9")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T)
|
||||
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("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B)
|
||||
|
||||
PORT_START("X10")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I)
|
||||
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_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('>') PORT_CODE(KEYCODE_COMMA)
|
||||
|
||||
PORT_START("X11")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P)
|
||||
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_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O)
|
||||
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("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR(')') PORT_CODE(KEYCODE_9)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP)
|
||||
|
||||
PORT_START("CONFIG")
|
||||
PORT_DIPNAME(0x0f, 0x00, "Keyboard Type") PORT_DIPLOCATION("E:1,2,3,4")
|
||||
PORT_DIPSETTING(0x00, "North America")
|
||||
PORT_DIPSETTING(0x08, "United Kingdom (4A)")
|
||||
PORT_DIPSETTING(0x04, "French (4B)")
|
||||
PORT_DIPSETTING(0x02, "Swedish (4C)")
|
||||
PORT_DIPSETTING(0x06, "Danish/Norwegian (4F)")
|
||||
PORT_DIPSETTING(0x07, "German (4G)")
|
||||
PORT_DIPSETTING(0x0a, "Katakana (4K)")
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor tek410x_keyboard_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(tek410x_keyboard);
|
||||
}
|
||||
|
||||
void tek410x_keyboard_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
I8748(config, m_mcu, 4.608_MHz_XTAL);
|
||||
m_mcu->set_addrmap(AS_IO, &tek410x_keyboard_device::ext_map);
|
||||
m_mcu->bus_out_cb().set_output("led0").bit(0);
|
||||
m_mcu->p1_in_cb().set(FUNC(tek410x_keyboard_device::p1_r));
|
||||
m_mcu->p2_in_cb().set(FUNC(tek410x_keyboard_device::p2_r));
|
||||
m_mcu->p2_out_cb().set(FUNC(tek410x_keyboard_device::p2_w));
|
||||
}
|
||||
|
||||
ROM_START(tek410x_kbd)
|
||||
ROM_REGION(0x400, "mcu", 0)
|
||||
ROM_LOAD("473_8748.bin", 0x000, 0x400, CRC(371553a8) SHA1(165ffc2c0775c1a3c2cc3ec86fb05adc8e8bb3eb))
|
||||
ROM_END
|
||||
|
||||
const tiny_rom_entry *tek410x_keyboard_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(tek410x_kbd);
|
||||
}
|
69
src/mame/machine/tek410x_kbd.h
Normal file
69
src/mame/machine/tek410x_kbd.h
Normal file
@ -0,0 +1,69 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_MACHINE_TEK410X_KEYBOARD_H
|
||||
#define MAME_MACHINE_TEK410X_KEYBOARD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> tek410x_keyboard_device
|
||||
|
||||
class tek410x_keyboard_device : public device_t
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
tek410x_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
// callback configuration
|
||||
auto tdata_callback() { return m_tdata_callback.bind(); }
|
||||
auto rdata_callback() { return m_rdata_callback.bind(); }
|
||||
|
||||
// line inputs
|
||||
DECLARE_WRITE_LINE_MEMBER(kdi_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(kdo_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(reset_w);
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
// MCU handlers
|
||||
u8 p1_r();
|
||||
u8 p2_r();
|
||||
void p2_w(u8 data);
|
||||
|
||||
// address maps
|
||||
void ext_map(address_map &map);
|
||||
|
||||
// object finders
|
||||
required_device<mcs48_cpu_device> m_mcu;
|
||||
required_ioport_array<12> m_key_matrix;
|
||||
required_ioport m_config;
|
||||
|
||||
// output callbacks
|
||||
devcb_write_line m_tdata_callback;
|
||||
devcb_write_line m_rdata_callback;
|
||||
|
||||
// internal state
|
||||
u8 m_select;
|
||||
u8 m_p2_out;
|
||||
bool m_kdi;
|
||||
bool m_kdo;
|
||||
};
|
||||
|
||||
// device type declaration
|
||||
DECLARE_DEVICE_TYPE(TEK410X_KEYBOARD, tek410x_keyboard_device)
|
||||
|
||||
#endif // MAME_MACHINE_TEK410X_KEYBOARD_H
|
Loading…
Reference in New Issue
Block a user