From 2d993a7b5d945cf26c8ebad6820ee1315154b152 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Sun, 3 Sep 2017 21:12:12 +0200 Subject: [PATCH] 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 (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: 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) { - while (entry) - { - entry->hil_write(data | (m_w1 << 8)); - entry = entry->next(); - } - } else - { - 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: