diff options
Diffstat (limited to 'src/devices/bus/hp_dio/hp98643.cpp')
-rw-r--r-- | src/devices/bus/hp_dio/hp98643.cpp | 125 |
1 files changed, 99 insertions, 26 deletions
diff --git a/src/devices/bus/hp_dio/hp98643.cpp b/src/devices/bus/hp_dio/hp98643.cpp index 57bc4d1a283..04e08abbee1 100644 --- a/src/devices/bus/hp_dio/hp98643.cpp +++ b/src/devices/bus/hp_dio/hp98643.cpp @@ -13,9 +13,80 @@ //#define VERBOSE 1 #include "logmacro.h" -DEFINE_DEVICE_TYPE_NS(HPDIO_98643, bus::hp_dio, dio16_98643_device, "dio98643", "HP98643A LANIC Ethernet card") -namespace bus { namespace hp_dio { +namespace { + +static constexpr int REG_SWITCHES_REMOTE = 0x80; + +static constexpr int REG_SWITCHES_SELECT_CODE_MASK = 0x1f; +static constexpr int REG_SWITCHES_SELECT_CODE_SHIFT = 0x00; + +static constexpr int REG_SWITCHES_INT_LEVEL_MASK = 0x03; +static constexpr int REG_SWITCHES_INT_LEVEL_SHIFT = 0x05; + +static constexpr uint16_t REG_ID = 0x15; + +static constexpr uint16_t REG_STATUS_ACK = 0x04; + +static constexpr uint16_t REG_SC_REV = 0x01; +static constexpr uint16_t REG_SC_LOCK = 0x08; +static constexpr uint16_t REG_SC_IP = 0x40; +static constexpr uint16_t REG_SC_IE = 0x80; + +class dio16_98643_device : + public device_t, + public bus::hp_dio::device_dio16_card_interface +{ +public: + // construction/destruction + dio16_98643_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + dio16_98643_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + + // device-level overrides + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + +private: + required_device<am7990_device> m_lance; + required_ioport m_switches; + + void addrmap(address_map &map) ATTR_COLD; + void update_int(); + int get_irq_line(); + + uint16_t sc_r(); + void sc_w(uint16_t data); + uint16_t id_r(); + void id_w(uint16_t data); + uint16_t novram_r(offs_t offset); + void novram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + void lance_int_w(int state); + void lance_dma_out(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t lance_dma_in(offs_t offset); + + uint16_t m_novram[32] = { + 0xfff0, 0xfff0, 0xfff0, 0xfff0, + 0xfff0, 0xfff8, 0xfff0, 0xfff0, + 0xfff0, 0xfff9, 0xfff0, 0xfff6, + 0xfffa, 0xfff1, 0xffff, 0xfff1, + 0xfff0, 0xfff0, 0xfff0, 0xfff0, + 0xfff0, 0xfff0, 0xfff0, 0xfff0, + 0xfff0, 0xfff0, 0xfff0, 0xfff0, + 0xfff0, 0xfff0, 0xfffa, 0xfff9, + }; + + std::array<uint16_t, 8192> m_ram; + + uint16_t m_sc; + bool m_installed_io; +}; void dio16_98643_device::device_add_mconfig(machine_config &config) { @@ -95,6 +166,7 @@ void dio16_98643_device::device_start() save_item(NAME(m_sc)); save_item(NAME(m_installed_io)); save_item(NAME(m_ram)); + m_installed_io = false; } void dio16_98643_device::device_reset() @@ -113,7 +185,7 @@ void dio16_98643_device::device_reset() m_sc |= get_irq_line() << 4; } -WRITE_LINE_MEMBER(dio16_98643_device::lance_int_w) +void dio16_98643_device::lance_int_w(int state) { if (state) m_sc &= ~REG_SC_IP; @@ -122,7 +194,7 @@ WRITE_LINE_MEMBER(dio16_98643_device::lance_int_w) update_int(); } -WRITE16_MEMBER(dio16_98643_device::sc_w) +void dio16_98643_device::sc_w(uint16_t data) { LOG("%s: %02x\n", __func__, data); data &= (REG_SC_LOCK|REG_SC_IE); @@ -135,38 +207,38 @@ WRITE16_MEMBER(dio16_98643_device::sc_w) update_int(); } -READ16_MEMBER(dio16_98643_device::sc_r) +uint16_t dio16_98643_device::sc_r() { LOG("%s: %02x\n", __func__, m_sc); return m_sc; } -READ16_MEMBER(dio16_98643_device::id_r) +uint16_t dio16_98643_device::id_r() { return (REG_ID | (m_switches->read() & REG_SWITCHES_REMOTE)); } -WRITE16_MEMBER(dio16_98643_device::id_w) +void dio16_98643_device::id_w(uint16_t data) { reset(); } -READ16_MEMBER(dio16_98643_device::novram_r) +uint16_t dio16_98643_device::novram_r(offs_t offset) { return m_novram[offset]; } -WRITE16_MEMBER(dio16_98643_device::novram_w) +void dio16_98643_device::novram_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&m_novram[offset & 0x3f]); } -WRITE16_MEMBER(dio16_98643_device::lance_dma_out) +void dio16_98643_device::lance_dma_out(offs_t offset, uint16_t data, uint16_t mem_mask) { LOG("%s: offset=%04x, data=%d\n", __func__, offset, data); COMBINE_DATA(&m_ram[(offset >> 1) & 0x1fff]); } -READ16_MEMBER(dio16_98643_device::lance_dma_in) +uint16_t dio16_98643_device::lance_dma_in(offs_t offset) { uint16_t ret = m_ram[(offset >> 1) & 0x1fff]; @@ -194,22 +266,23 @@ void dio16_98643_device::addrmap(address_map &map) { map(0x0000, 0x0001).rw(FUNC(dio16_98643_device::id_r), FUNC(dio16_98643_device::id_w)); map(0x0002, 0x0003).rw(FUNC(dio16_98643_device::sc_r), FUNC(dio16_98643_device::sc_w)); - map(0x4000, 0x4003).lrw16("lance", - [this](address_space &space, offs_t offset, u16 mem_mask) -> u16 { - m_sc |= REG_STATUS_ACK; - return m_lance->regs_r(space, offset, mem_mask); - }, - [this](address_space &space, offs_t offset, u16 data, u16 mem_mask) { - m_sc |= REG_STATUS_ACK; - return m_lance->regs_w(space, offset, data, mem_mask); - }); - - map(0x8000, 0xbfff).lrw16("lanceram", - [this](offs_t offset) -> u16 { return m_ram[offset]; }, - [this](offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_ram[offset]); }); + map(0x4000, 0x4003).lrw16( + [this] (address_space &space, offs_t offset) -> u16 { + m_sc |= REG_STATUS_ACK; + return m_lance->regs_r(space, offset); + }, "lance_r", + [this] (offs_t offset, u16 data) { + m_sc |= REG_STATUS_ACK; + return m_lance->regs_w(offset, data); + }, "lance_w"); + + map(0x8000, 0xbfff).lrw16( + NAME([this] (offs_t offset) -> u16 { return m_ram[offset]; }), + NAME([this] (offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_ram[offset]); })); map(0xc000, 0xffff).rw(FUNC(dio16_98643_device::novram_r), FUNC(dio16_98643_device::novram_w)); } -} // namespace bus::hp_dio -} // namespace bus +} // anonymous namespace + +DEFINE_DEVICE_TYPE_PRIVATE(HPDIO_98643, bus::hp_dio::device_dio16_card_interface, dio16_98643_device, "dio98643", "HP98643A LANIC Ethernet card") |