Merge pull request #2620 from sschnelle/hil_keyboard

Hil keyboard support for HP9000/300
This commit is contained in:
R. Belmont 2017-09-03 20:16:15 -04:00 committed by GitHub
commit fa70750a58
5 changed files with 129 additions and 42 deletions

View File

@ -4,7 +4,7 @@
#include "machine/keyboard.ipp" #include "machine/keyboard.ipp"
#define LOG 0
/*************************************************************************** /***************************************************************************
DEVICE TYPE GLOBALS DEVICE TYPE GLOBALS
***************************************************************************/ ***************************************************************************/
@ -276,13 +276,25 @@ void hle_device_base::device_reset()
start_processing(attotime::from_hz(1'200)); start_processing(attotime::from_hz(1'200));
} }
// '
void hle_device_base::hil_write(uint16_t data) bool hle_device_base::hil_write(uint16_t *pdata)
{ {
int frames = 0; int frames = 0;
// printf("rx from mlc %04X (%s %02X)\n", data, BIT(data, 11) ? "command" : "data", data & 255); uint8_t addr = (*pdata >> 8) & 7;
uint8_t data = *pdata & 0xff;
bool command = BIT(*pdata, 11);
if (BIT(data, 11)) switch (data & 255) if (LOG) {
logerror("rx from mlc %04X (%s addr %d, data %02X)\n", *pdata, \
command ? "command" : "data", addr, data);
}
if (!command)
goto out;
if (addr != 0 && addr != m_device_id)
goto out;
switch (data)
{ {
case HPHIL_IFC: case HPHIL_IFC:
m_powerup = false; m_powerup = false;
@ -296,27 +308,35 @@ void hle_device_base::hil_write(uint16_t data)
m_passthru = false; m_passthru = false;
break; break;
case HPHIL_ACF+1: case 0x09:
m_device_id = data & 7; case 0x0a:
m_device_id16 = m_device_id << 8; case 0x0b:
m_hp_hil_mlc->hil_write((data & ~7) | ((data + 1) & 7)); case 0x0c:
return; case 0x0d:
case 0x0e:
case 0x0f:
m_device_id = data - 8;
m_device_id16 = (data - 8) << 8;
*pdata &= ~7;
*pdata += (data - 7);
break; break;
case HPHIL_POL: case HPHIL_POL:
if (!m_fifo.empty()) if (!m_fifo.empty())
{ {
m_hp_hil_mlc->hil_write(m_device_id16 | 0x40); // Keycode Set 1, no coordinate data
frames = 1; frames = 1;
m_hp_hil_mlc->hil_write(m_device_id16 | 0x40); // Keycode Set 1, no coordinate data
while (!m_fifo.empty()) while (!m_fifo.empty())
{ {
m_hp_hil_mlc->hil_write(m_device_id16 | m_fifo.dequeue()); m_hp_hil_mlc->hil_write(m_device_id16 | m_fifo.dequeue());
frames++; frames++;
} }
} }
m_hp_hil_mlc->hil_write(HPMLC_W1_C | m_device_id16 | HPHIL_POL | ((data + frames) & 7)); m_hp_hil_mlc->hil_write(HPMLC_W1_C | (addr << 8) | HPHIL_POL | (frames));
return; *pdata &= ~7;
break; *pdata += frames;
return true;
case HPHIL_DSR: case HPHIL_DSR:
m_device_id = m_device_id16 = 0; m_device_id = m_device_id16 = 0;
@ -324,30 +344,33 @@ void hle_device_base::hil_write(uint16_t data)
break; break;
case HPHIL_IDD: case HPHIL_IDD:
m_hp_hil_mlc->hil_write(m_device_id16 | ioport("COL0")->read()); logerror("IDD\n");
m_hp_hil_mlc->hil_write(0x01cf);
m_hp_hil_mlc->hil_write(m_device_id16 | 0); m_hp_hil_mlc->hil_write(m_device_id16 | 0);
break; break;
case HPHIL_DHR: case HPHIL_DHR:
m_powerup = true;
m_passthru = false;
device_reset(); device_reset();
return; return true;
break; break;
default: default:
logerror("command %02X unknown\n", data & 255); logerror("command %02X unknown\n", data);
break; break;
} }
out:
if (!m_passthru) if (!m_passthru) {
m_hp_hil_mlc->hil_write(data); m_hp_hil_mlc->hil_write(*pdata);
// else return false;
// m_next->hil_write(data); }
return true;
} }
void hle_device_base::transmit_byte(uint8_t byte) void hle_device_base::transmit_byte(uint8_t byte)
{ {
if (!m_fifo.full()) { if (!m_fifo.full()) {
// printf("queuing %02X\n", byte);
m_fifo.enqueue(byte); m_fifo.enqueue(byte);
} }
// else // else

View File

@ -34,7 +34,7 @@ protected:
virtual void key_break(uint8_t row, uint8_t column) override; virtual void key_break(uint8_t row, uint8_t column) override;
// device_hp_hil_interface overrides // device_hp_hil_interface overrides
virtual void hil_write(uint16_t data) override; virtual bool hil_write(uint16_t *data) override;
private: private:
void transmit_byte(uint8_t byte); void transmit_byte(uint8_t byte);

View File

@ -78,6 +78,7 @@ hp_hil_mlc_device::hp_hil_mlc_device(const machine_config &mconfig, const char *
, int_cb(*this) , int_cb(*this)
, nmi_cb(*this) , nmi_cb(*this)
{ {
m_loop = 1;
} }
void hp_hil_mlc_device::add_hp_hil_device( device_hp_hil_interface *device ) void hp_hil_mlc_device::add_hp_hil_device( device_hp_hil_interface *device )
@ -112,13 +113,16 @@ void hp_hil_mlc_device::device_reset()
WRITE8_MEMBER(hp_hil_mlc_device::write) WRITE8_MEMBER(hp_hil_mlc_device::write)
{ {
device_hp_hil_interface *entry = m_device_list.first(); device_hp_hil_interface *entry = m_device_list.first();
uint16_t tmp = data | (m_w1 << 8);
DBG_LOG(2,"Write", ("%d <- %02x\n", offset, data)); DBG_LOG(2,"Write", ("%d <- %02x\n", offset, data));
switch (offset) switch (offset)
{ {
case 0: case 0:
DBG_LOG(1,"Transmit", ("%scommand 0x%02x to device %d\n", !m_loop?"loopback ":"", data, m_w1 & 7)); DBG_LOG(1,"Transmit", ("%scommand 0x%02x to device %d\n", !m_loop?"loopback ":"", data, m_w1 & 7));
m_fifo.clear();
if (m_loop & 2) // no devices on 2nd link loop if (m_loop & 2) // no devices on 2nd link loop
return; return;
if (m_loop == 0) if (m_loop == 0)
@ -130,22 +134,14 @@ WRITE8_MEMBER(hp_hil_mlc_device::write)
} }
return; return;
} }
if ((m_w1 & 7) == 0) // broadcast
{
while (entry) while (entry)
{ {
entry->hil_write(data | (m_w1 << 8)); if (!entry->hil_write(&tmp))
break;
entry = entry->next(); entry = entry->next();
} }
} else
{
while (entry)
{
if (entry->device_id() == (m_w1 & 7))
entry->hil_write(data | (m_w1 << 8));
entry = entry->next();
}
}
break; break;
case 1: case 1:
@ -228,13 +224,15 @@ void hp_hil_mlc_device::hil_write(uint16_t data)
WRITE_LINE_MEMBER(hp_hil_mlc_device::ap_w) WRITE_LINE_MEMBER(hp_hil_mlc_device::ap_w)
{ {
uint16_t data = HPMLC_W1_C | HPHIL_POL;
if (state && (m_w3 & HPMLC_W3_APE)) if (state && (m_w3 & HPMLC_W3_APE))
{ {
device_hp_hil_interface *entry = m_device_list.first(); device_hp_hil_interface *entry = m_device_list.first();
while (entry) while (entry)
{ {
entry->hil_write(HPMLC_W1_C | HPHIL_POL); if (!(entry->hil_write(&data)))
break;
entry = entry->next(); entry = entry->next();
} }
} }
@ -279,4 +277,3 @@ void device_hp_hil_interface::set_hp_hil_mlc_device()
m_hp_hil_mlc = dynamic_cast<hp_hil_mlc_device *>(m_hp_hil_mlc_dev); m_hp_hil_mlc = dynamic_cast<hp_hil_mlc_device *>(m_hp_hil_mlc_dev);
m_hp_hil_mlc->add_hp_hil_device(this); m_hp_hil_mlc->add_hp_hil_device(this);
} }

View File

@ -133,6 +133,7 @@ public:
template <class Object> static devcb_base &set_nmi_callback(device_t &device, Object &&cb) { return downcast<hp_hil_mlc_device &>(device).nmi_cb.set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_nmi_callback(device_t &device, Object &&cb) { return downcast<hp_hil_mlc_device &>(device).nmi_cb.set_callback(std::forward<Object>(cb)); }
void add_hp_hil_device(device_hp_hil_interface *device); void add_hp_hil_device(device_hp_hil_interface *device);
bool get_int(void) { return m_r3 & 1; }
DECLARE_READ8_MEMBER(read); DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write); DECLARE_WRITE8_MEMBER(write);
@ -177,7 +178,7 @@ public:
// inline configuration // inline configuration
static void static_set_hp_hil_mlc(device_t &device, device_t *mlc_device); static void static_set_hp_hil_mlc(device_t &device, device_t *mlc_device);
virtual void hil_write(uint16_t data) { }; virtual bool hil_write(uint16_t *data) { return true; };
int device_id() { return m_device_id; }; int device_id() { return m_device_id; };
protected: protected:

View File

@ -60,11 +60,14 @@
#include "machine/6840ptm.h" #include "machine/6840ptm.h"
#include "bus/hp_dio/hp_dio.h" #include "bus/hp_dio/hp_dio.h"
#include "bus/hp_dio/hp98544.h" #include "bus/hp_dio/hp98544.h"
#include "bus/hp_hil/hp_hil.h"
#include "bus/hp_hil/hil_devices.h"
#include "screen.h" #include "screen.h"
#define MAINCPU_TAG "maincpu" #define MAINCPU_TAG "maincpu"
#define IOCPU_TAG "iocpu" #define IOCPU_TAG "iocpu"
#define PTM6840_TAG "ptm" #define PTM6840_TAG "ptm"
#define MLC_TAG "mlc"
class hp9k3xx_state : public driver_device class hp9k3xx_state : public driver_device
{ {
@ -73,12 +76,14 @@ public:
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_maincpu(*this, MAINCPU_TAG), m_maincpu(*this, MAINCPU_TAG),
m_iocpu(*this, IOCPU_TAG), m_iocpu(*this, IOCPU_TAG),
m_mlc(*this, MLC_TAG),
m_vram16(*this, "vram16"), m_vram16(*this, "vram16"),
m_vram(*this, "vram") m_vram(*this, "vram")
{ } { }
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
optional_device<i8042_device> m_iocpu; optional_device<i8042_device> m_iocpu;
optional_device<hp_hil_mlc_device> m_mlc;
virtual void machine_reset() override; virtual void machine_reset() override;
optional_shared_ptr<uint16_t> m_vram16; optional_shared_ptr<uint16_t> m_vram16;
@ -91,6 +96,13 @@ public:
DECLARE_WRITE16_MEMBER(buserror16_w); DECLARE_WRITE16_MEMBER(buserror16_w);
DECLARE_READ32_MEMBER(buserror_r); DECLARE_READ32_MEMBER(buserror_r);
DECLARE_WRITE32_MEMBER(buserror_w); DECLARE_WRITE32_MEMBER(buserror_w);
/* 8042 interface */
DECLARE_WRITE8_MEMBER(iocpu_port1_w);
DECLARE_WRITE8_MEMBER(iocpu_port2_w);
DECLARE_READ8_MEMBER(iocpu_port1_r);
DECLARE_READ8_MEMBER(iocpu_test0_r);
DECLARE_WRITE32_MEMBER(led_w) DECLARE_WRITE32_MEMBER(led_w)
{ {
if (mem_mask != 0x000000ff) if (mem_mask != 0x000000ff)
@ -116,6 +128,9 @@ public:
private: private:
bool m_in_buserr; bool m_in_buserr;
bool m_hil_read;
uint8_t m_hil_data;
uint8_t m_latch_data;
}; };
uint32_t hp9k3xx_state::hp_medres_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) uint32_t hp9k3xx_state::hp_medres_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@ -162,6 +177,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(hp9k310_map, AS_PROGRAM, 16, hp9k3xx_state) static ADDRESS_MAP_START(hp9k310_map, AS_PROGRAM, 16, hp9k3xx_state)
AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_REGION("maincpu",0) AM_WRITENOP // writes to 1fffc are the LED AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_REGION("maincpu",0) AM_WRITENOP // writes to 1fffc are the LED
AM_RANGE(0x00428000, 0x00428003) AM_DEVREADWRITE8(IOCPU_TAG, upi41_cpu_device, upi41_master_r, upi41_master_w, 0x00ff)
AM_RANGE(0x510000, 0x510003) AM_READWRITE(buserror16_r, buserror16_w) // no "Alpha display" AM_RANGE(0x510000, 0x510003) AM_READWRITE(buserror16_r, buserror16_w) // no "Alpha display"
AM_RANGE(0x538000, 0x538003) AM_READWRITE(buserror16_r, buserror16_w) // no "Graphics" AM_RANGE(0x538000, 0x538003) AM_READWRITE(buserror16_r, buserror16_w) // no "Graphics"
AM_RANGE(0x5c0000, 0x5c0003) AM_READWRITE(buserror16_r, buserror16_w) // no add-on FP coprocessor AM_RANGE(0x5c0000, 0x5c0003) AM_READWRITE(buserror16_r, buserror16_w) // no add-on FP coprocessor
@ -291,6 +308,41 @@ WRITE32_MEMBER(hp9k3xx_state::buserror_w)
} }
} }
WRITE8_MEMBER(hp9k3xx_state::iocpu_port1_w)
{
m_hil_data = data;
}
static constexpr uint8_t HIL_CS = 0x01;
static constexpr uint8_t HIL_WE = 0x02;
static constexpr uint8_t HIL_OE = 0x04;
static constexpr uint8_t LATCH_EN = 0x08;
WRITE8_MEMBER(hp9k3xx_state::iocpu_port2_w)
{
if ((data & (HIL_CS|HIL_WE)) == 0)
m_mlc->write(space, (m_latch_data & 0xc0) >> 6, m_hil_data, 0xff);
m_hil_read = ((data & (HIL_CS|HIL_OE)) == 0);
if (!(data & LATCH_EN))
m_latch_data = m_hil_data;
m_maincpu->set_input_line(M68K_IRQ_1, data & 0x10 ? ASSERT_LINE : CLEAR_LINE);
}
READ8_MEMBER(hp9k3xx_state::iocpu_port1_r)
{
if (m_hil_read)
return m_mlc->read(space, (m_latch_data & 0xc0) >> 6, 0xff);
return 0xff;
}
READ8_MEMBER(hp9k3xx_state::iocpu_test0_r)
{
return !m_mlc->get_int();
}
static SLOT_INTERFACE_START(dio16_cards) static SLOT_INTERFACE_START(dio16_cards)
SLOT_INTERFACE("98544", HPDIO_98544) /* 98544 High Resolution Monochrome Card */ SLOT_INTERFACE("98544", HPDIO_98544) /* 98544 High Resolution Monochrome Card */
SLOT_INTERFACE_END SLOT_INTERFACE_END
@ -302,6 +354,13 @@ static MACHINE_CONFIG_START( hp9k310 )
MCFG_CPU_ADD(IOCPU_TAG, I8042, 5000000) MCFG_CPU_ADD(IOCPU_TAG, I8042, 5000000)
MCFG_CPU_PROGRAM_MAP(iocpu_map) MCFG_CPU_PROGRAM_MAP(iocpu_map)
MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(hp9k3xx_state, iocpu_port1_w))
MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(hp9k3xx_state, iocpu_port2_w))
MCFG_MCS48_PORT_P1_IN_CB(READ8(hp9k3xx_state, iocpu_port1_r))
MCFG_MCS48_PORT_T0_IN_CB(READ8(hp9k3xx_state, iocpu_test0_r))
MCFG_DEVICE_ADD(MLC_TAG, HP_HIL_MLC, XTAL_15_92MHz/2)
MCFG_HP_HIL_SLOT_ADD(MLC_TAG, "hil1", hp_hil_devices, "hp_ipc_kbd")
MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 250000) // from oscillator module next to the 6840 MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 250000) // from oscillator module next to the 6840
MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f)
@ -319,6 +378,13 @@ static MACHINE_CONFIG_START( hp9k320 )
MCFG_CPU_ADD(IOCPU_TAG, I8042, 5000000) MCFG_CPU_ADD(IOCPU_TAG, I8042, 5000000)
MCFG_CPU_PROGRAM_MAP(iocpu_map) MCFG_CPU_PROGRAM_MAP(iocpu_map)
MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(hp9k3xx_state, iocpu_port1_w))
MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(hp9k3xx_state, iocpu_port2_w))
MCFG_MCS48_PORT_P1_IN_CB(READ8(hp9k3xx_state, iocpu_port1_r))
MCFG_MCS48_PORT_T0_IN_CB(READ8(hp9k3xx_state, iocpu_test0_r))
MCFG_DEVICE_ADD(MLC_TAG, HP_HIL_MLC, XTAL_15_92MHz/2)
MCFG_HP_HIL_SLOT_ADD(MLC_TAG, "hil1", hp_hil_devices, "hp_ipc_kbd")
MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 250000) // from oscillator module next to the 6840 MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 250000) // from oscillator module next to the 6840
MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f)