From 2d993a7b5d945cf26c8ebad6820ee1315154b152 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Sun, 3 Sep 2017 21:12:12 +0200 Subject: HP HIL: passthrough commands between devices The old code didn't loopback commands that are sent to a non-existing HIL address. Unfortunately the HP 9000/300 Boot ROM does that: it send a IDD command to every possible address and fails if it's not looped back. This also changes the API. HIL devices are now able to return true if the command should be passed on to the next devices, or false it it shouldn't. This is required for initial configuration of the Bus and various other commands like POLL, which are sent to the global address. Signed-off-by: Sven Schnelle --- src/devices/bus/hp_hil/hlekbd.cpp | 69 ++++++++++++++++++++++++++------------- src/devices/bus/hp_hil/hlekbd.h | 2 +- src/devices/bus/hp_hil/hp_hil.cpp | 31 ++++++++---------- src/devices/bus/hp_hil/hp_hil.h | 2 +- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/devices/bus/hp_hil/hlekbd.cpp b/src/devices/bus/hp_hil/hlekbd.cpp index 48289063ee7..ea12473df70 100644 --- a/src/devices/bus/hp_hil/hlekbd.cpp +++ b/src/devices/bus/hp_hil/hlekbd.cpp @@ -4,7 +4,7 @@ #include "machine/keyboard.ipp" - +#define LOG 0 /*************************************************************************** DEVICE TYPE GLOBALS ***************************************************************************/ @@ -276,13 +276,25 @@ void hle_device_base::device_reset() 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; -// 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 (LOG) { + logerror("rx from mlc %04X (%s addr %d, data %02X)\n", *pdata, \ + command ? "command" : "data", addr, data); + } + if (!command) + goto out; - if (BIT(data, 11)) switch (data & 255) + if (addr != 0 && addr != m_device_id) + goto out; + + switch (data) { case HPHIL_IFC: m_powerup = false; @@ -296,27 +308,35 @@ void hle_device_base::hil_write(uint16_t data) m_passthru = false; break; - case HPHIL_ACF+1: - m_device_id = data & 7; - m_device_id16 = m_device_id << 8; - m_hp_hil_mlc->hil_write((data & ~7) | ((data + 1) & 7)); - return; + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + m_device_id = data - 8; + m_device_id16 = (data - 8) << 8; + *pdata &= ~7; + *pdata += (data - 7); break; case HPHIL_POL: if (!m_fifo.empty()) { - m_hp_hil_mlc->hil_write(m_device_id16 | 0x40); // Keycode Set 1, no coordinate data + frames = 1; + m_hp_hil_mlc->hil_write(m_device_id16 | 0x40); // Keycode Set 1, no coordinate data while (!m_fifo.empty()) { m_hp_hil_mlc->hil_write(m_device_id16 | m_fifo.dequeue()); frames++; } } - m_hp_hil_mlc->hil_write(HPMLC_W1_C | m_device_id16 | HPHIL_POL | ((data + frames) & 7)); - return; - break; + m_hp_hil_mlc->hil_write(HPMLC_W1_C | (addr << 8) | HPHIL_POL | (frames)); + *pdata &= ~7; + *pdata += frames; + return true; case HPHIL_DSR: m_device_id = m_device_id16 = 0; @@ -324,30 +344,33 @@ void hle_device_base::hil_write(uint16_t data) break; 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); break; case HPHIL_DHR: + m_powerup = true; + m_passthru = false; device_reset(); - return; + return true; break; default: - logerror("command %02X unknown\n", data & 255); + logerror("command %02X unknown\n", data); break; } - - if (!m_passthru) - m_hp_hil_mlc->hil_write(data); -// else -// m_next->hil_write(data); +out: + if (!m_passthru) { + m_hp_hil_mlc->hil_write(*pdata); + return false; + } + return true; } void hle_device_base::transmit_byte(uint8_t byte) { if (!m_fifo.full()) { -// printf("queuing %02X\n", byte); m_fifo.enqueue(byte); } // else diff --git a/src/devices/bus/hp_hil/hlekbd.h b/src/devices/bus/hp_hil/hlekbd.h index a92e5a29581..31204435f2b 100644 --- a/src/devices/bus/hp_hil/hlekbd.h +++ b/src/devices/bus/hp_hil/hlekbd.h @@ -34,7 +34,7 @@ protected: virtual void key_break(uint8_t row, uint8_t column) override; // device_hp_hil_interface overrides - virtual void hil_write(uint16_t data) override; + virtual bool hil_write(uint16_t *data) override; private: void transmit_byte(uint8_t byte); diff --git a/src/devices/bus/hp_hil/hp_hil.cpp b/src/devices/bus/hp_hil/hp_hil.cpp index 653e4766842..1e6d343f17a 100644 --- a/src/devices/bus/hp_hil/hp_hil.cpp +++ b/src/devices/bus/hp_hil/hp_hil.cpp @@ -78,6 +78,7 @@ hp_hil_mlc_device::hp_hil_mlc_device(const machine_config &mconfig, const char * , int_cb(*this) , nmi_cb(*this) { + m_loop = 1; } 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) { 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)); switch (offset) { case 0: 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 return; if (m_loop == 0) @@ -130,21 +134,13 @@ WRITE8_MEMBER(hp_hil_mlc_device::write) } return; } - if ((m_w1 & 7) == 0) // broadcast - { - while (entry) - { - entry->hil_write(data | (m_w1 << 8)); - entry = entry->next(); - } - } else + + + while (entry) { - while (entry) - { - if (entry->device_id() == (m_w1 & 7)) - entry->hil_write(data | (m_w1 << 8)); - entry = entry->next(); - } + if (!entry->hil_write(&tmp)) + break; + entry = entry->next(); } break; @@ -228,13 +224,15 @@ void hp_hil_mlc_device::hil_write(uint16_t data) WRITE_LINE_MEMBER(hp_hil_mlc_device::ap_w) { + uint16_t data = HPMLC_W1_C | HPHIL_POL; if (state && (m_w3 & HPMLC_W3_APE)) { device_hp_hil_interface *entry = m_device_list.first(); while (entry) { - entry->hil_write(HPMLC_W1_C | HPHIL_POL); + if (!(entry->hil_write(&data))) + break; entry = entry->next(); } } @@ -279,4 +277,3 @@ void device_hp_hil_interface::set_hp_hil_mlc_device() m_hp_hil_mlc = dynamic_cast(m_hp_hil_mlc_dev); m_hp_hil_mlc->add_hp_hil_device(this); } - diff --git a/src/devices/bus/hp_hil/hp_hil.h b/src/devices/bus/hp_hil/hp_hil.h index 178f512e350..11724382968 100644 --- a/src/devices/bus/hp_hil/hp_hil.h +++ b/src/devices/bus/hp_hil/hp_hil.h @@ -177,7 +177,7 @@ public: // inline configuration 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; }; protected: -- cgit v1.2.3 From eead79aea8f1b8180f0e23b2d9dfd2729cfc7039 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Sun, 3 Sep 2017 22:06:01 +0200 Subject: HP9000/300: Add HIL keyboard support Signed-off-by: Sven Schnelle --- src/devices/bus/hp_hil/hp_hil.h | 1 + src/mame/drivers/hp9k_3xx.cpp | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/devices/bus/hp_hil/hp_hil.h b/src/devices/bus/hp_hil/hp_hil.h index 11724382968..e43d71d6cfd 100644 --- a/src/devices/bus/hp_hil/hp_hil.h +++ b/src/devices/bus/hp_hil/hp_hil.h @@ -133,6 +133,7 @@ public: template static devcb_base &set_nmi_callback(device_t &device, Object &&cb) { return downcast(device).nmi_cb.set_callback(std::forward(cb)); } void add_hp_hil_device(device_hp_hil_interface *device); + bool get_int(void) { return m_r3 & 1; } DECLARE_READ8_MEMBER(read); DECLARE_WRITE8_MEMBER(write); diff --git a/src/mame/drivers/hp9k_3xx.cpp b/src/mame/drivers/hp9k_3xx.cpp index 042e1585949..b5a26be8e8e 100644 --- a/src/mame/drivers/hp9k_3xx.cpp +++ b/src/mame/drivers/hp9k_3xx.cpp @@ -60,11 +60,14 @@ #include "machine/6840ptm.h" #include "bus/hp_dio/hp_dio.h" #include "bus/hp_dio/hp98544.h" +#include "bus/hp_hil/hp_hil.h" +#include "bus/hp_hil/hil_devices.h" #include "screen.h" #define MAINCPU_TAG "maincpu" #define IOCPU_TAG "iocpu" #define PTM6840_TAG "ptm" +#define MLC_TAG "mlc" class hp9k3xx_state : public driver_device { @@ -73,12 +76,14 @@ public: : driver_device(mconfig, type, tag), m_maincpu(*this, MAINCPU_TAG), m_iocpu(*this, IOCPU_TAG), + m_mlc(*this, MLC_TAG), m_vram16(*this, "vram16"), m_vram(*this, "vram") { } required_device m_maincpu; optional_device m_iocpu; + optional_device m_mlc; virtual void machine_reset() override; optional_shared_ptr m_vram16; @@ -91,6 +96,13 @@ public: DECLARE_WRITE16_MEMBER(buserror16_w); DECLARE_READ32_MEMBER(buserror_r); 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) { if (mem_mask != 0x000000ff) @@ -117,6 +129,10 @@ public: private: bool m_in_buserr; uint32_t m_last_buserr_pc; + + 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) @@ -161,6 +177,8 @@ ADDRESS_MAP_END 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(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(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 @@ -315,6 +333,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) SLOT_INTERFACE("98544", HPDIO_98544) /* 98544 High Resolution Monochrome Card */ SLOT_INTERFACE_END @@ -326,6 +379,13 @@ static MACHINE_CONFIG_START( hp9k310 ) MCFG_CPU_ADD(IOCPU_TAG, I8042, 5000000) 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_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) @@ -343,6 +403,13 @@ static MACHINE_CONFIG_START( hp9k320 ) MCFG_CPU_ADD(IOCPU_TAG, I8042, 5000000) 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_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) -- cgit v1.2.3