summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/edlc.h
blob: 57e52b6159a96ed6354b45e90e38a86f4d5f4336 (plain) (tree)



















                                                                                                        
                                   
                                   




                                           












                                                                
                                   


























                                                                                              
                                               

























                                                                             
                                               




















                                                                      
                          












                                                 
// 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);

	// command/status interface
	void map(address_map &map);
	u8 read(offs_t offset);
	void write(offs_t offset, u8 data);
	void reset_w(int state);

	// data interface
	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 registers
	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, // interrupt 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, // interrupt 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;
	int m_reset_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