mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
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 <svens@stackframe.org>
This commit is contained in:
parent
49a7303d0f
commit
2d993a7b5d
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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<hp_hil_mlc_device *>(m_hp_hil_mlc_dev);
|
||||
m_hp_hil_mlc->add_hp_hil_device(this);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user