diff options
Diffstat (limited to 'src/devices/machine/edlc.h')
-rw-r--r-- | src/devices/machine/edlc.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/devices/machine/edlc.h b/src/devices/machine/edlc.h new file mode 100644 index 00000000000..91bd37010d3 --- /dev/null +++ b/src/devices/machine/edlc.h @@ -0,0 +1,125 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_MACHINE_EDLC_H +#define MAME_MACHINE_EDLC_H + +#pragma once + +class seeq8003_device : + public device_t, + public device_network_interface +{ +public: + // callback configuration + auto out_int_cb() { return m_out_int.bind(); } + auto out_rxrdy_cb() { return m_out_rxrdy.bind(); } + auto out_txrdy_cb() { return m_out_txrdy.bind(); } + + seeq8003_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + // host interface + void map(address_map &map); + u8 fifo_r(); + int rxeof_r(); + void fifo_w(u8 data); + void txeof_w(int state); + +protected: + // device_t overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_network_interface overrides + virtual int recv_start_cb(u8 *buf, int length) override; + + // command/status interface + template <unsigned N> void station_address_w(u8 data) { m_station_address[N] = data; } + u8 rx_status_r(); + u8 tx_status_r(); + void rx_command_w(u8 data) { m_rx_command = data; } + void tx_command_w(u8 data) { m_tx_command = data & TXC_M; } + + // helpers + void transmit(void *ptr, int param); + int receive(u8 *buf, int length); + void interrupt(void *ptr = nullptr, int param = 0); + bool address_filter(u8 *address); + void dump_bytes(u8 *buf, int length); + + // constants and masks + static const unsigned MAX_FRAME_SIZE = 1518; + static const u32 FCS_RESIDUE = 0xdebb20e3; + + enum rx_status_mask : u8 + { + RXS_V = 0x01, // received frame with overflow error + RXS_C = 0x02, // received frame with crc error + RXS_D = 0x04, // received frame with dribble error + RXS_S = 0x08, // received short frame + RXS_E = 0x10, // received end of frame + RXS_G = 0x20, // received good frame + RXS_O = 0x80, // old/new status + + RXS_M = 0x3f, // mask + }; + enum rx_command_mask : u8 + { + RXC_V = 0x01, // interrupt on receive overflow error + RXC_C = 0x02, // interrupt on receive crc error + RXC_D = 0x04, // interrupt on receive dribble error + RXC_S = 0x08, // interrupt on short frame + RXC_E = 0x10, // interrupt on end of frame + RXC_G = 0x20, // interrupt on good frame + RXC_M = 0xc0, // match mode + }; + enum rx_match_mask : u8 + { + RXC_M0 = 0x00, // receiver disable + RXC_M1 = 0x40, // receive all frames + RXC_M2 = 0x80, // receive station or broadcast frames + RXC_M3 = 0xc0, // receive station, broadcast/multicast frames + }; + enum tx_status_mask : u8 + { + TXS_U = 0x01, // transmit underflow + TXS_C = 0x02, // transmit collision + TXS_R = 0x04, // 16 transmission attempts + TXS_S = 0x08, // transmission successful + TXS_O = 0x80, // old/new status + + TXS_M = 0x0f, // mask + }; + enum tx_command_mask : u8 + { + TXC_U = 0x01, // interrupt on transmit underflow + TXC_C = 0x02, // interrupt on transmit collision + TXC_R = 0x04, // interrupt on 16 transmission attempts + TXC_S = 0x08, // interrupt on transmit success + + TXC_M = 0x0f, // write mask + }; + +private: + emu_timer *m_tx_timer; + emu_timer *m_int_timer; + + // device state + devcb_write_line m_out_int; + devcb_write_line m_out_rxrdy; + devcb_write_line m_out_txrdy; + + int m_int_state; + u8 m_station_address[6]; + u8 m_rx_status; + u8 m_tx_status; + u8 m_rx_command; + u8 m_tx_command; + + util::fifo<u8, MAX_FRAME_SIZE> m_rx_fifo; + util::fifo<u8, MAX_FRAME_SIZE> m_tx_fifo; +}; + +DECLARE_DEVICE_TYPE(SEEQ8003, seeq8003_device) + +#endif // MAME_MACHINE_EDLC_H |