mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
New working systems
------------------- IBM 5100 [Christian Corti, Tom Stepleton]
This commit is contained in:
parent
34b7c397c1
commit
85a3c394d2
4 changed files with 839 additions and 0 deletions
488
src/mame/ibm/ibm5100.cpp
Normal file
488
src/mame/ibm/ibm5100.cpp
Normal file
|
@ -0,0 +1,488 @@
|
|||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* IBM 5100.
|
||||
*
|
||||
* Sources:
|
||||
* - IBM 5100 Maintenance Information Manual, SY31-0405-3, Fourth Edition (October 1979), International Business Machines Corporation
|
||||
*
|
||||
* TODO:
|
||||
* - display registers
|
||||
* - device address f
|
||||
* - tape controller
|
||||
* - printer
|
||||
* - communications cards
|
||||
* - expansion feature
|
||||
* - later models (5110, 5120, 5130)
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "ibm5100_kbd.h"
|
||||
|
||||
#include "cpu/palm/palm.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL)
|
||||
#include "logmacro.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class ibm5100_state : public driver_device
|
||||
{
|
||||
public:
|
||||
ibm5100_state(machine_config const &mconfig, device_type type, char const *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_cpu(*this, "cpu")
|
||||
, m_screen(*this, "screen")
|
||||
, m_kbd(*this, "kbd")
|
||||
, m_nxr(*this, { "apl", "basic" })
|
||||
, m_j2(*this, "j2")
|
||||
, m_conf(*this, "CONF")
|
||||
, m_disp(*this, "DISP")
|
||||
, m_lang(*this, "LANG")
|
||||
, m_ros(*this, "ros")
|
||||
{
|
||||
}
|
||||
|
||||
void ibm5100(machine_config &config);
|
||||
|
||||
protected:
|
||||
// driver_device implementation
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
void cpu_ros_map(address_map &map);
|
||||
void cpu_rws_map(address_map &map);
|
||||
void cpu_ioc_map(address_map &map);
|
||||
void cpu_iod_map(address_map &map);
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect);
|
||||
|
||||
// e2 - ros control card
|
||||
u8 e2_sts_r();
|
||||
void e2_ctl_w(u8 data);
|
||||
u8 e2_r();
|
||||
void e2_w(u8 data);
|
||||
|
||||
// f2 - base i/o card
|
||||
u8 f2_kbd_sts_r();
|
||||
void f2_kbd_ctl_w(u8 data);
|
||||
void da0_ctl_w(u8 data);
|
||||
void daf_ctl_w(u8 data);
|
||||
|
||||
private:
|
||||
required_device<palm_device> m_cpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<ibm5100_keyboard_device> m_kbd;
|
||||
|
||||
required_region_ptr_array<u16, 2> m_nxr;
|
||||
required_region_ptr<u8> m_j2;
|
||||
|
||||
required_ioport m_conf;
|
||||
required_ioport m_disp;
|
||||
required_ioport m_lang;
|
||||
|
||||
memory_view m_ros;
|
||||
|
||||
u8 m_getb_bus;
|
||||
|
||||
u8 m_e2_ff; // e2 card flip-flops
|
||||
u8 m_f2_ff; // f2 card flip-flops
|
||||
u16 m_e2_address;
|
||||
|
||||
std::unique_ptr<u16[]> m_rws;
|
||||
};
|
||||
|
||||
enum e2_ff_mask : u8
|
||||
{
|
||||
E2_RS = 0x01, // ROS select (0=APL, 1=BASIC/common)
|
||||
E2_PS = 0x02, // put strobe
|
||||
E2_B0 = 0x04, // data address bit 0
|
||||
};
|
||||
|
||||
enum f2_ff_mask : u8
|
||||
{
|
||||
F2_KIE = 0x01, // keyboard interrupt enable
|
||||
F2_DO = 0x10, // display off
|
||||
};
|
||||
|
||||
void ibm5100_state::machine_start()
|
||||
{
|
||||
// for simplicity allocate maximum 64KiB
|
||||
m_rws = std::make_unique<u16[]>(0x8000);
|
||||
|
||||
save_item(NAME(m_getb_bus));
|
||||
|
||||
save_item(NAME(m_e2_ff));
|
||||
save_item(NAME(m_f2_ff));
|
||||
save_item(NAME(m_e2_address));
|
||||
|
||||
save_pointer(NAME(m_rws), 0x8000);
|
||||
}
|
||||
|
||||
void ibm5100_state::machine_reset()
|
||||
{
|
||||
m_e2_ff = 0;
|
||||
m_f2_ff = 0;
|
||||
|
||||
m_e2_address = 0;
|
||||
|
||||
// install configured rws
|
||||
unsigned const rws_cards = (m_conf->read() & 3) + 1;
|
||||
m_cpu->space(palm_device::AS_RWS).install_ram(0x80, 0x4000 * rws_cards - 1, &m_rws[0x40]);
|
||||
m_ros[1].install_ram(0x80, 0x4000 * rws_cards - 1, &m_rws[0x40]);
|
||||
}
|
||||
|
||||
void ibm5100_state::cpu_ros_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).view(m_ros);
|
||||
m_ros[0](0x0000, 0xffff).rom().region("ros", 0);
|
||||
}
|
||||
|
||||
void ibm5100_state::cpu_rws_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
}
|
||||
|
||||
void ibm5100_state::cpu_ioc_map(address_map &map)
|
||||
{
|
||||
map(0x0, 0x0).w(FUNC(ibm5100_state::da0_ctl_w));
|
||||
map(0x1, 0x1).rw(FUNC(ibm5100_state::e2_sts_r), FUNC(ibm5100_state::e2_ctl_w));
|
||||
map(0x2, 0x3).noprw();
|
||||
map(0x4, 0x4).rw(FUNC(ibm5100_state::f2_kbd_sts_r), FUNC(ibm5100_state::f2_kbd_ctl_w));
|
||||
// 5 printer r:not used w:control
|
||||
map(0x6, 0x7).noprw();
|
||||
// 8 expansion r:status w:control
|
||||
map(0x9, 0xd).noprw();
|
||||
// e tape r:status w:control
|
||||
map(0xf, 0xf).nopr().w(FUNC(ibm5100_state::daf_ctl_w));
|
||||
}
|
||||
|
||||
void ibm5100_state::cpu_iod_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
|
||||
map(0x0, 0x0).noprw();
|
||||
map(0x1, 0x1).rw(FUNC(ibm5100_state::e2_r), FUNC(ibm5100_state::e2_w));
|
||||
map(0x2, 0x3).noprw();
|
||||
map(0x4, 0x4).r(m_kbd, FUNC(ibm5100_keyboard_device::read)).nopw();
|
||||
// 5 r:printer w:print data
|
||||
map(0x6, 0x7).noprw();
|
||||
// 8 expansion r:not used w:data
|
||||
map(0x9, 0xd).noprw();
|
||||
// e r:tape data w:tape
|
||||
map(0xf, 0xf).noprw();
|
||||
}
|
||||
|
||||
void ibm5100_state::ibm5100(machine_config &config)
|
||||
{
|
||||
PALM(config, m_cpu, 15'091'200);
|
||||
m_cpu->set_addrmap(palm_device::AS_ROS, &ibm5100_state::cpu_ros_map);
|
||||
m_cpu->set_addrmap(palm_device::AS_RWS, &ibm5100_state::cpu_rws_map);
|
||||
m_cpu->set_addrmap(palm_device::AS_IOC, &ibm5100_state::cpu_ioc_map);
|
||||
m_cpu->set_addrmap(palm_device::AS_IOD, &ibm5100_state::cpu_iod_map);
|
||||
m_cpu->getb_bus().set([this](offs_t offset, u8 data) { m_getb_bus = data; });
|
||||
m_cpu->select_ros().set([this](int state) { m_ros.select(state); });
|
||||
|
||||
/*
|
||||
* Display output is 16 rows of 64 characters. Each character cell is 10x12
|
||||
* pixels with 8x12 driven from character ROS data. The last two horizontal
|
||||
* pixels of each character cell line and every other scan line are blank.
|
||||
*/
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(15'091'200, 64*10, 0, 64*10, 16*12*2, 0, 16*12*2);
|
||||
m_screen->set_screen_update(FUNC(ibm5100_state::screen_update));
|
||||
|
||||
IBM5100_KEYBOARD(config, m_kbd);
|
||||
m_kbd->strobe().set(
|
||||
[this](int state)
|
||||
{
|
||||
if ((m_f2_ff & F2_KIE) && !state)
|
||||
m_cpu->set_input_line(palm_device::IRPT_REQ3, 0);
|
||||
});
|
||||
}
|
||||
|
||||
u32 ibm5100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect)
|
||||
{
|
||||
static rgb_t const c[] = { rgb_t::white(), rgb_t::black() };
|
||||
|
||||
// read display switches
|
||||
u8 const disp = m_disp->read();
|
||||
|
||||
bool const reverse = BIT(disp, 0);
|
||||
bool const n64 = !BIT(disp, 2);
|
||||
bool const r32 = BIT(disp, 3);
|
||||
|
||||
// start with a blank screen
|
||||
bitmap.fill(c[reverse]);
|
||||
|
||||
// then generate characters
|
||||
auto const rws = util::big_endian_cast<u8 const>(m_rws.get());
|
||||
for (unsigned char_y = 0; char_y < 16; char_y++)
|
||||
{
|
||||
// every other scan line is blank
|
||||
int const y = screen.visible_area().min_y + char_y * 12 * 2;
|
||||
|
||||
// compute offset into rws for each row
|
||||
offs_t offset = 0x200 + char_y * 64 + (r32 ? 32 : 0);
|
||||
|
||||
for (unsigned char_x = 0; char_x < 64; char_x++)
|
||||
{
|
||||
int const x = screen.visible_area().min_x + char_x * 10;
|
||||
|
||||
// read next character if display is on and normal mode or even column
|
||||
u8 char_data = 0;
|
||||
if (!(m_f2_ff & F2_DO) && (n64 || !(char_x & 1)))
|
||||
char_data = rws[offset++];
|
||||
|
||||
// draw 8x12 character cell
|
||||
for (unsigned cell_y = 0; cell_y < 12; cell_y++)
|
||||
{
|
||||
// index into character font data
|
||||
unsigned const underline = ((cell_y > 7) && BIT(char_data, 7)) ? 4 : 0;
|
||||
u8 const cell_data = m_j2[(char_data & 0x7f) * 16 + cell_y + underline];
|
||||
|
||||
bitmap.pix(y + cell_y * 2, x + 0) = c[BIT(cell_data, 7) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 1) = c[BIT(cell_data, 6) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 2) = c[BIT(cell_data, 5) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 3) = c[BIT(cell_data, 4) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 4) = c[BIT(cell_data, 3) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 5) = c[BIT(cell_data, 2) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 6) = c[BIT(cell_data, 1) ^ reverse];
|
||||
bitmap.pix(y + cell_y * 2, x + 7) = c[BIT(cell_data, 0) ^ reverse];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ibm5100_state::da0_ctl_w(u8 data)
|
||||
{
|
||||
LOG("da0_ctl_w 0x%02x (%s)\n", data, machine().describe_context());
|
||||
|
||||
// bit 4: 0=display off
|
||||
if (!BIT(data, 4))
|
||||
m_f2_ff |= F2_DO;
|
||||
else
|
||||
m_f2_ff &= ~F2_DO;
|
||||
}
|
||||
|
||||
u8 ibm5100_state::e2_sts_r()
|
||||
{
|
||||
u8 data = 0xff;
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
data = (m_e2_ff & E2_PS) ? u8(m_e2_address) : (m_e2_address >> 8);
|
||||
|
||||
m_e2_ff ^= E2_PS;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ibm5100_state::e2_ctl_w(u8 data)
|
||||
{
|
||||
LOG("e2_ctl_w 0x%02x (%s)\n", data, machine().describe_context());
|
||||
|
||||
if (!BIT(data, 3))
|
||||
m_e2_ff &= ~E2_RS;
|
||||
else if (!BIT(data, 2))
|
||||
m_e2_ff |= E2_RS;
|
||||
|
||||
m_e2_ff &= ~(E2_B0 | E2_PS);
|
||||
m_e2_address = 0;
|
||||
}
|
||||
|
||||
u8 ibm5100_state::e2_r()
|
||||
{
|
||||
u8 data = 0xff;
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
bool const basic = m_e2_ff & E2_RS;
|
||||
|
||||
// check model has selected ROS (all models have common)
|
||||
if (BIT(m_conf->read(), 2 + basic) || (basic && m_e2_address >= 0x9000))
|
||||
{
|
||||
/*
|
||||
* APL non-executable ROS is addressed with an unshifted 16-bit
|
||||
* address, giving a 128KiB range; BASIC uses a shifted address,
|
||||
* giving 64KiB. Even and odd bytes are selected by a flip-flop
|
||||
* which is toggled with each read.
|
||||
*/
|
||||
data = BIT(m_nxr[basic][m_e2_address >> basic], (m_e2_ff & E2_B0) ? 0 : 8, 8);
|
||||
}
|
||||
|
||||
// always increment address for BASIC, only on odd bytes for APL
|
||||
if (basic || (m_e2_ff & E2_B0))
|
||||
m_e2_address++;
|
||||
|
||||
// toggle even/odd byte flip-flop
|
||||
m_e2_ff ^= E2_B0;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ibm5100_state::e2_w(u8 data)
|
||||
{
|
||||
m_e2_address = (m_e2_address << 8) | data;
|
||||
|
||||
if (m_e2_ff & E2_PS)
|
||||
{
|
||||
LOG("e2_address 0x%04x (%s)\n", m_e2_address, machine().describe_context());
|
||||
|
||||
// data byte even/odd flip-flop is cleared except when BASIC is
|
||||
// selected and the address is odd
|
||||
if ((m_e2_ff & E2_RS) && (m_e2_address & 1))
|
||||
m_e2_ff |= E2_B0;
|
||||
else
|
||||
m_e2_ff &= ~E2_B0;
|
||||
}
|
||||
|
||||
// toggle put strobe flip-flop
|
||||
m_e2_ff ^= E2_PS;
|
||||
}
|
||||
|
||||
u8 ibm5100_state::f2_kbd_sts_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (m_getb_bus)
|
||||
{
|
||||
case 0x40:
|
||||
// keyboard data gate
|
||||
return m_kbd->read();
|
||||
case 0x80:
|
||||
// keyboard status gate
|
||||
return m_lang->read();
|
||||
default:
|
||||
LOG("f2_kbd_sts_r: unknown 0x%02x (%s)\n", m_getb_bus, machine().describe_context());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void ibm5100_state::f2_kbd_ctl_w(u8 data)
|
||||
{
|
||||
LOG("f2_kbd_ctl_w 0x%02x (%s)\n", data, machine().describe_context());
|
||||
|
||||
// bit 6: 0=reset and disable keyboard interrupts
|
||||
if (!BIT(data, 6))
|
||||
{
|
||||
m_f2_ff &= ~F2_KIE;
|
||||
|
||||
m_cpu->set_input_line(palm_device::IRPT_REQ3, 1);
|
||||
}
|
||||
|
||||
// bit 4: 0=lock keyboard
|
||||
m_kbd->lock_w(BIT(data, 4));
|
||||
|
||||
// bit 1: 0=enable typamatic
|
||||
// FIXME: inverted?
|
||||
m_kbd->typamatic_w(BIT(data, 1));
|
||||
|
||||
// bit 0: 0=enable keyboard interrupt
|
||||
if (!BIT(data, 0))
|
||||
m_f2_ff |= F2_KIE;
|
||||
else
|
||||
m_f2_ff &= ~F2_KIE;
|
||||
}
|
||||
|
||||
void ibm5100_state::daf_ctl_w(u8 data)
|
||||
{
|
||||
LOG("daf_ctl_w 0x%02x (%s)\n", data, machine().describe_context());
|
||||
|
||||
// bit function
|
||||
// 7 expansion da=8
|
||||
// 6 tape da=e
|
||||
// 5 keyboard da=4
|
||||
// 4 printer da=5
|
||||
// 3 enable cycle steal
|
||||
// 2 reset da=b
|
||||
// 1 reset da=c
|
||||
// 0 reset da=d
|
||||
}
|
||||
|
||||
ROM_START(ibm5100)
|
||||
// Executable ROS
|
||||
ROM_REGION16_BE(0x10000, "ros", 0)
|
||||
ROM_LOAD("h2.ros", 0x0000, 0x8000, CRC(36d11e3d) SHA1(6be2c0728b88debcd557879c25781a9c7afc5224))
|
||||
ROM_LOAD("h4.ros", 0x8000, 0x8000, CRC(5d3eceb7) SHA1(e5412914d74e8149ea8a250a6560d1738555ec7e))
|
||||
|
||||
// BASIC + Common and Language non-executable ROS
|
||||
/*
|
||||
* The common ROS is physically located on the E2 card, and not on the C4
|
||||
* BASIC card, however it is selected together with the BASIC ROS and
|
||||
* logically appended to the address space.
|
||||
*/
|
||||
ROM_REGION16_BE(0x10000, "basic", 0)
|
||||
ROM_LOAD("c4.ros", 0x0000, 0x9000, CRC(b1abeb4a) SHA1(e0151fefe63c43c8912599615ddfb7c06f111c72))
|
||||
ROM_LOAD("e2.ros", 0x9000, 0x4800, CRC(be4289c3) SHA1(008ea7bb25fda94540bf5e02eff5a59bb1c86aac))
|
||||
ROM_FILL(0xd800, 0x2800, 0xff)
|
||||
|
||||
// APL non-executable ROS
|
||||
ROM_REGION16_BE(0x20000, "apl", 0)
|
||||
ROM_LOAD("c2.ros", 0x00000, 0x8000, CRC(fba01c70) SHA1(a7dd9b60ba33021d830751df2de5513e0de452f2))
|
||||
ROM_LOAD("d2.ros", 0x08000, 0x8000, CRC(afb3ba33) SHA1(15292d1082a2d6211fbdbbb0781466506d310954))
|
||||
ROM_LOAD("d4.ros", 0x10000, 0x8000, CRC(a03570c9) SHA1(5a6e7a5b38b96c8ff47be2572272f8ed0cd31efd))
|
||||
ROM_FILL(0x18000, 0x8000, 0xff)
|
||||
|
||||
// Display Adapter ROS
|
||||
/*
|
||||
* This data was hand-made based on the character map in the documentation.
|
||||
* It was assumed that the first 8 bytes of each character store the upper
|
||||
* 8x8 cell, then 2x4 byte entries contain the normal and underlined lower
|
||||
* 4 rows of the total 8x12 cell respectively.
|
||||
*/
|
||||
ROM_REGION(0x800, "j2", 0)
|
||||
ROM_LOAD("j2.ros", 0x000, 0x800, CRC(428e5b66) SHA1(9def68eed9dc2b8f08581387f8b74b49b3faf7e7) BAD_DUMP)
|
||||
ROM_END
|
||||
|
||||
static INPUT_PORTS_START(ibm5100)
|
||||
PORT_START("CONF")
|
||||
PORT_CONFNAME(0x0f, 0x0f, "Model")
|
||||
PORT_CONFSETTING(0x04, "A1 - APL 16K")
|
||||
PORT_CONFSETTING(0x05, "A2 - APL 32K")
|
||||
PORT_CONFSETTING(0x06, "A3 - APL 48K")
|
||||
PORT_CONFSETTING(0x07, "A4 - APL 64K")
|
||||
|
||||
PORT_CONFSETTING(0x08, "B1 - BASIC 16K")
|
||||
PORT_CONFSETTING(0x09, "B2 - BASIC 32K")
|
||||
PORT_CONFSETTING(0x0a, "B3 - BASIC 48K")
|
||||
PORT_CONFSETTING(0x0b, "B4 - BASIC 64K")
|
||||
|
||||
PORT_CONFSETTING(0x0c, "C1 - APL/BASIC 16K")
|
||||
PORT_CONFSETTING(0x0d, "C2 - APL/BASIC 32K")
|
||||
PORT_CONFSETTING(0x0e, "C3 - APL/BASIC 48K")
|
||||
PORT_CONFSETTING(0x0f, "C4 - APL/BASIC 64K")
|
||||
|
||||
PORT_START("DISP")
|
||||
PORT_CONFNAME(0x01, 0x00, "Reverse")
|
||||
PORT_CONFSETTING(0x00, "Black on White")
|
||||
PORT_CONFSETTING(0x01, "White on Black")
|
||||
PORT_CONFNAME(0x02, 0x00, "Display")
|
||||
PORT_CONFSETTING(0x00, "Normal")
|
||||
PORT_CONFSETTING(0x02, "Registers")
|
||||
PORT_CONFNAME(0x0c, 0x00, "Columns")
|
||||
PORT_CONFSETTING(0x04, "L32")
|
||||
PORT_CONFSETTING(0x00, "64")
|
||||
PORT_CONFSETTING(0x0c, "R32")
|
||||
|
||||
PORT_START("LANG")
|
||||
PORT_CONFNAME(0x40, 0x40, "Language")
|
||||
PORT_CONFSETTING(0x00, "APL") PORT_CONDITION("CONF", 0x04, EQUALS, 0x04)
|
||||
PORT_CONFSETTING(0x40, "BASIC") PORT_CONDITION("CONF", 0x08, EQUALS, 0x08)
|
||||
INPUT_PORTS_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
COMP(1975, ibm5100, 0, 0, ibm5100, ibm5100, ibm5100_state, empty_init, "International Business Machines", "IBM 5100", MACHINE_NO_SOUND_HW)
|
299
src/mame/ibm/ibm5100_kbd.cpp
Normal file
299
src/mame/ibm/ibm5100_kbd.cpp
Normal file
|
@ -0,0 +1,299 @@
|
|||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* A high level emulation of the IBM 5100 keyboard.
|
||||
*
|
||||
* Sources:
|
||||
* - IBM 5100 Maintenance Information Manual, SY31-0405-3, Fourth Edition (October 1979), International Business Machines Corporation
|
||||
*
|
||||
* TODO:
|
||||
* - missing key names and chars
|
||||
*
|
||||
* For columns 0..15, the scan code format is SrrCcccc where:
|
||||
*
|
||||
* S = shift modifier (1=active)
|
||||
* rr = matrix row number
|
||||
* C = command modifier (1=active)
|
||||
* cccc = matrix column number
|
||||
*
|
||||
* For columns > 15, the scan code format is 1rrccCSc where:
|
||||
*
|
||||
* S = shift modifier (0=active)
|
||||
* rr = matrix row number
|
||||
* C = command modifier (1=active)
|
||||
* cc..c = matrix column number
|
||||
*
|
||||
* This scheme disallows modifier combinations, with shift taking priority over
|
||||
* command. Bits 5 and 6 of the scan code are swapped when output.
|
||||
*
|
||||
* Regular alpha, numeric and keypad keys are easily mapped 1:1 with a standard
|
||||
* modern keyboard. Additional keys are mapped by default as follows:
|
||||
*
|
||||
* 5100 Key Mapping Rationale
|
||||
* -------- ------- ---------
|
||||
* +/- - closest key position, matching shifted symbol
|
||||
* ×/÷ = closest key position
|
||||
* ←/→ ; moved to row with two non-alpha keys
|
||||
* = ' moved to row with two non-alpha keys
|
||||
* [/( [ moved to row with three non-alpha keys, matching unshifted symbol
|
||||
* ]/) ] moved to row with three non-alpha keys, matching unshifted symbol
|
||||
* #/@ \ moved to row with three non-alpha keys
|
||||
* &/$ ` available standard symbol key
|
||||
*
|
||||
* l/r/u/d arrow keys conceptual match
|
||||
* Attention Delete available non-symbol, non-modal key
|
||||
* Hold Backspace available non-symbol, non-modal key
|
||||
* Execute Enter conceptual match
|
||||
* Command L/R Control conceptual match
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ibm5100_kbd.h"
|
||||
|
||||
#include "machine/keyboard.ipp"
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(IBM5100_KEYBOARD, ibm5100_keyboard_device, "ibm5100_keyboard", "IBM 5100 Keyboard")
|
||||
|
||||
INPUT_PORTS_START(ibm5100_keyboard)
|
||||
PORT_START("modifiers")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT)
|
||||
PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL)
|
||||
PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Command") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
|
||||
|
||||
PORT_START("col.0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_NAME(u8"9 \u2228") PORT_CHAR('9')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_NAME(u8"I \u2373") PORT_CHAR('I')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_NAME(u8"K '") PORT_CHAR('K') PORT_CHAR('\'')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';')
|
||||
|
||||
PORT_START("col.1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_NAME(u8"8 \u2260") PORT_CHAR('8')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_NAME(u8"U \u2193") PORT_CHAR('U')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_NAME(u8"J \u2218") PORT_CHAR('J')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_NAME(u8"M \u2223") PORT_CHAR('M')
|
||||
|
||||
PORT_START("col.2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_NAME(u8"× ÷") // FIXME: PORT_CHAR?
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_NAME(u8"\u2190 \u2192") // FIXME: PORT_CHAR?
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR(')')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('\\')
|
||||
|
||||
PORT_START("col.3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_CHAR('-')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_NAME(u8"P \u22c6") PORT_CHAR('P')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('(')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Space") PORT_CHAR(UCHAR_MAMEKEY(SPACE))
|
||||
|
||||
PORT_START("col.4")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") PORT_CHAR(UCHAR_MAMEKEY(UP))
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
|
||||
|
||||
PORT_START("col.5")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
|
||||
|
||||
PORT_START("col.6")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD))
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME("Keypad *") PORT_CHAR(UCHAR_MAMEKEY(ASTERISK))
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD))
|
||||
|
||||
PORT_START("col.7")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Keypad .") PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
|
||||
|
||||
PORT_START("col.8")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_NAME(u8"6 \u2265") PORT_CHAR('6')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_NAME(u8"T \u223c") PORT_CHAR('T')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_NAME(u8"G \u2207") PORT_CHAR('G')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_NAME(u8"B \u22a5") PORT_CHAR('B')
|
||||
|
||||
PORT_START("col.9")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_NAME(u8"7 >") PORT_CHAR('7') PORT_CHAR('>')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_NAME(u8"Y \u2191") PORT_CHAR('Y')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_NAME(u8"H \u2206") PORT_CHAR('H')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_NAME(u8"N \u22a4") PORT_CHAR('N')
|
||||
|
||||
PORT_START("col.a")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_NAME(u8"4 \u2264") PORT_CHAR('4')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_NAME(u8"E \u220a") PORT_CHAR('E')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_NAME(u8"D \u230a") PORT_CHAR('D')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_NAME(u8"C \u2229") PORT_CHAR('C')
|
||||
|
||||
PORT_START("col.b")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_NAME(u8"5 =") PORT_CHAR('5')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_NAME(u8"R \u2374") PORT_CHAR('R')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_NAME(u8"F _") PORT_CHAR('F') PORT_CHAR('_')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_NAME(u8"V \u222a") PORT_CHAR('V')
|
||||
|
||||
PORT_START("col.c")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_NAME(u8"3 <") PORT_CHAR('3') PORT_CHAR('<')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_NAME(u8"W \u2375") PORT_CHAR('W')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_NAME(u8"S \u2308") PORT_CHAR('S')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_NAME(u8"X \u2283") PORT_CHAR('X')
|
||||
|
||||
PORT_START("col.d")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_NAME(u8"1 ¨") PORT_CHAR('1')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_NAME("&") PORT_CHAR('&') PORT_CHAR('$')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("col.e")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_NAME(u8"0 \u2227") PORT_CHAR('0')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_NAME(u8"O \u25cb") PORT_CHAR('O')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_NAME(u8"L \u2395") PORT_CHAR('L')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':')
|
||||
|
||||
PORT_START("col.f")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_NAME(u8"2 \u203e") PORT_CHAR('2')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_NAME(u8"Q ?") PORT_CHAR('Q') PORT_CHAR('?')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_NAME(u8"A \u237a") PORT_CHAR('A')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_NAME(u8"Z \u2282") PORT_CHAR('Z')
|
||||
|
||||
PORT_START("col.10")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Attention") PORT_CHAR(UCHAR_MAMEKEY(DEL))
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER)
|
||||
PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Execute") PORT_CHAR(13)
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("col.11")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Hold") PORT_CHAR(8)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_NAME("Equals") PORT_CHAR('=')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_NAME("# @") PORT_CHAR('#') PORT_CHAR('@')
|
||||
INPUT_PORTS_END
|
||||
|
||||
static const std::pair<u8, u8>typamatic_keys[] =
|
||||
{
|
||||
std::make_pair( 3, 3), // space
|
||||
std::make_pair( 4, 0), // cursor up
|
||||
std::make_pair(13, 0), // cursor down
|
||||
std::make_pair(16, 1), // cursor right
|
||||
std::make_pair(17, 1), // cursor left
|
||||
};
|
||||
|
||||
ibm5100_keyboard_device::ibm5100_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, IBM5100_KEYBOARD, tag, owner, clock)
|
||||
, device_matrix_keyboard_interface(mconfig, *this
|
||||
, "col.0", "col.1", "col.2", "col.3", "col.4", "col.5", "col.6", "col.7"
|
||||
, "col.8", "col.9", "col.a", "col.b", "col.c", "col.d", "col.e", "col.f"
|
||||
, "col.10", "col.11")
|
||||
, m_strobe(*this)
|
||||
, m_modifiers(*this, "modifiers")
|
||||
, m_lock(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_scan));
|
||||
save_item(NAME(m_typamatic));
|
||||
save_item(NAME(m_lock));
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::device_reset()
|
||||
{
|
||||
m_scan = 0;
|
||||
m_strobe(1);
|
||||
m_typamatic = false;
|
||||
|
||||
reset_key_state();
|
||||
start_processing(attotime::from_hz(25'000));
|
||||
typematic_stop();
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::key_make(u8 row, u8 column)
|
||||
{
|
||||
if (m_lock)
|
||||
return;
|
||||
|
||||
m_scan = translate(row, column);
|
||||
|
||||
LOG("key_make row %d column %d scan 0x%02x\n", row, column, m_scan);
|
||||
|
||||
m_strobe(0);
|
||||
m_strobe(1);
|
||||
|
||||
// only some keys have typamatic action
|
||||
if (std::find(std::begin(typamatic_keys), std::end(typamatic_keys), std::make_pair(row, column)) != std::end(typamatic_keys))
|
||||
typematic_start(row, column, attotime::from_msec(700), attotime::from_msec(100));
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::key_break(u8 row, u8 column)
|
||||
{
|
||||
if (typematic_is(row, column))
|
||||
typematic_stop();
|
||||
|
||||
m_scan = 0;
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::key_repeat(u8 row, u8 column)
|
||||
{
|
||||
if (m_typamatic)
|
||||
{
|
||||
m_scan = translate(row, column);
|
||||
|
||||
m_strobe(0);
|
||||
m_strobe(1);
|
||||
}
|
||||
}
|
||||
|
||||
// column and row are swapped with respect device_matrix_keyboard_interface arguments
|
||||
u8 ibm5100_keyboard_device::translate(u8 column, u8 row)
|
||||
{
|
||||
// compute basic scan code with bits 5 and 6 swapped
|
||||
u8 data = bitswap<8>(row << 5 | column, 7, 5, 6, 4, 3, 2, 1, 0);
|
||||
|
||||
u8 const modifiers = m_modifiers->read();
|
||||
|
||||
// modifiers are applied differently for columns > 15
|
||||
if (column < 16)
|
||||
{
|
||||
if (BIT(modifiers, 0))
|
||||
// shift
|
||||
data |= 0x80;
|
||||
else if (BIT(modifiers, 1))
|
||||
// command
|
||||
data |= 0x10;
|
||||
}
|
||||
else
|
||||
{
|
||||
data |= 0x82;
|
||||
|
||||
if (BIT(modifiers, 0))
|
||||
// shift
|
||||
data &= ~0x02;
|
||||
else if (BIT(modifiers, 1))
|
||||
// command
|
||||
data |= 0x04;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::typamatic_w(int state)
|
||||
{
|
||||
m_typamatic = state;
|
||||
}
|
||||
|
||||
void ibm5100_keyboard_device::lock_w(int state)
|
||||
{
|
||||
m_lock = !state;
|
||||
}
|
||||
|
||||
ioport_constructor ibm5100_keyboard_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(ibm5100_keyboard);
|
||||
}
|
49
src/mame/ibm/ibm5100_kbd.h
Normal file
49
src/mame/ibm/ibm5100_kbd.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_IBM_IBM5100_KBD_H
|
||||
#define MAME_IBM_IBM5100_KBD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/keyboard.h"
|
||||
|
||||
class ibm5100_keyboard_device
|
||||
: public device_t
|
||||
, protected device_matrix_keyboard_interface<18U>
|
||||
{
|
||||
public:
|
||||
auto strobe() { return m_strobe.bind(); }
|
||||
|
||||
ibm5100_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
u8 read() { return m_scan; }
|
||||
void typamatic_w(int state);
|
||||
void lock_w(int state);
|
||||
|
||||
protected:
|
||||
// device_t implementation
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_matrix_keyboard_interface implementation
|
||||
virtual void key_make(u8 row, u8 column) override;
|
||||
virtual void key_break(u8 row, u8 column) override;
|
||||
virtual void key_repeat(u8 row, u8 column) override;
|
||||
|
||||
u8 translate(u8 column, u8 row);
|
||||
|
||||
private:
|
||||
devcb_write_line m_strobe;
|
||||
|
||||
required_ioport m_modifiers;
|
||||
|
||||
u8 m_scan;
|
||||
bool m_typamatic;
|
||||
bool m_lock;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(IBM5100_KEYBOARD, ibm5100_keyboard_device)
|
||||
|
||||
#endif // MAME_IBM_IBM5100_KBD_H
|
|
@ -19798,6 +19798,9 @@ husky // DVW Husky
|
|||
@source:ibm/ibm3153.cpp
|
||||
ibm3153 //
|
||||
|
||||
@source:ibm/ibm5100.cpp
|
||||
ibm5100
|
||||
|
||||
@source:ibm/ibm5550.cpp
|
||||
ibm5550 //
|
||||
|
||||
|
|
Loading…
Reference in a new issue