1 // license:BSD-3-Clause 2 // copyright-holders:Antoine Mine 3 /********************************************************************** 4 5 Copyright (C) Antoine Mine' 2006 6 7 Motorola 6854 emulation (network interface). 8 9 **********************************************************************/ 10 11 #ifndef MAME_MACHINE_MC6854_H 12 #define MAME_MACHINE_MC6854_H 13 14 #pragma once 15 16 17 class mc6854_device : public device_t 18 { 19 public: 20 static constexpr unsigned MAX_FRAME_LENGTH = 65536; // arbitrary value, you may need to enlarge it if you get truncated frames 21 22 typedef device_delegate<void (uint8_t *data, int length)> out_frame_delegate; 23 24 mc6854_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); 25 out_irq_cb()26 auto out_irq_cb() { return m_out_irq_cb.bind(); } out_rdsr_cb()27 auto out_rdsr_cb() { return m_out_rdsr_cb.bind(); } out_tdsr_cb()28 auto out_tdsr_cb() { return m_out_tdsr_cb.bind(); } out_txd_cb()29 auto out_txd_cb() { return m_out_txd_cb.bind(); } out_rts_cb()30 auto out_rts_cb() { return m_out_rts_cb.bind(); } out_dtr_cb()31 auto out_dtr_cb() { return m_out_dtr_cb.bind(); } 32 set_out_frame_callback(T &&...args)33 template <typename... T> void set_out_frame_callback(T &&... args) { m_out_frame_cb.set(std::forward<T>(args)...); } 34 35 /* interface to CPU via address/data bus*/ 36 uint8_t read(offs_t offset); 37 void write(offs_t offset, uint8_t data); dma_r()38 uint8_t dma_r(){ return read(2); } 39 40 /* low-level, bit-based interface */ 41 DECLARE_WRITE_LINE_MEMBER( set_rx ); 42 43 /* high-level, frame-based interface */ 44 int send_frame( uint8_t* data, int length ); /* ret -1 if busy */ 45 46 /* control lines */ 47 DECLARE_WRITE_LINE_MEMBER( set_cts ); /* 1 = clear-to-send, 0 = busy */ 48 DECLARE_WRITE_LINE_MEMBER( set_dcd ); /* 1 = carrier, 0 = no carrier */ 49 50 /* clock */ 51 DECLARE_WRITE_LINE_MEMBER( rxc_w ); 52 DECLARE_WRITE_LINE_MEMBER( txc_w ); 53 54 protected: 55 // device-level overrides 56 virtual void device_start() override; 57 virtual void device_reset() override; 58 bool receive_allowed() const; 59 60 private: 61 static constexpr unsigned FIFO_SIZE = 3; // hardcoded size of the 6854 FIFO (this is a hardware limit) 62 63 // internal state 64 devcb_write_line m_out_irq_cb; /* interrupt request */ 65 devcb_write_line m_out_rdsr_cb; /* Rx fifo DMA request */ 66 devcb_write_line m_out_tdsr_cb; /* Tx fifo DMA request */ 67 68 /* low-level, bit-based interface */ 69 devcb_write_line m_out_txd_cb; /* transmit bit */ 70 71 /* high-level, frame-based interface */ 72 out_frame_delegate m_out_frame_cb; 73 74 /* control lines */ 75 devcb_write_line m_out_rts_cb; /* 1 = transmitting, 0 = idle */ 76 devcb_write_line m_out_dtr_cb; /* 1 = data transmit ready, 0 = busy */ 77 78 /* registers */ 79 uint8_t m_cr1, m_cr2, m_cr3, m_cr4; /* control registers */ 80 uint8_t m_sr1, m_sr2; /* status registers */ 81 82 uint8_t m_cts, m_dcd; 83 84 /* transmit state */ 85 uint8_t m_tstate; 86 uint16_t m_tfifo[FIFO_SIZE]; /* X x 8-bit FIFO + full & last marker bits */ 87 uint8_t m_tones; /* counter for zero-insertion */ 88 emu_timer *m_ttimer; /* when to ask for more data */ 89 90 /* receive state */ 91 uint8_t m_rstate; 92 uint32_t m_rreg; /* shift register */ 93 uint8_t m_rones; /* count '1 bits */ 94 uint8_t m_rsize; /* bits in the shift register */ 95 uint16_t m_rfifo[FIFO_SIZE]; /* X x 8-bit FIFO + full & addr marker bits */ 96 bool m_rxd; 97 bool m_rxc; 98 99 /* frame-based interface*/ 100 uint8_t m_frame[MAX_FRAME_LENGTH]; 101 uint32_t m_flen, m_fpos; 102 103 104 /* meaning of tstate / rtate: 105 0 = idle / waiting for frame flag 106 1 = flag sync 107 2 = 8-bit address field(s) 108 3-4 = 8-bit control field(s) 109 5 = 8-bit logical control field(s) 110 6 = variable-length data field(s) 111 */ 112 113 void send_bits( uint32_t data, int len, int zi ); 114 void tfifo_push( uint8_t data ); 115 void tfifo_terminate( ); 116 TIMER_CALLBACK_MEMBER(tfifo_cb); 117 void tfifo_clear( ); 118 119 void rfifo_push( uint8_t d ); 120 void rfifo_terminate( ); 121 uint8_t rfifo_pop( ); 122 void rfifo_clear( ); 123 124 void update_sr2( ); 125 void update_sr1( ); 126 }; 127 128 DECLARE_DEVICE_TYPE(MC6854, mc6854_device) 129 130 131 /* we provide two interfaces: 132 - a bit-based interface: out_tx, set_rx 133 - a frame-based interface: out_frame, send_frame 134 135 The bit-based interface is low-level and slow. 136 Use it to simulate the actual bits sent into the wires, e.g., to connect 137 the emulator to another bit-based emulated network device, or an actual 138 device. 139 140 The frame-based interface is higher-level and faster. 141 It passes bytes directly from one end to the other without bothering with 142 the actual bit-encoding, synchronization, and CRC. 143 144 Once completed, a frame is sent through out_frame. Aborted frames are not 145 transmitted at all. No start flag, stop flag, or crc bits are transmitted. 146 send_frame makes a frame available to the CPU through the 6854 (it may 147 fail and return -1 if the 6854 is not ready to accept the frame; even 148 if the frame is accepted and 0 is returned, the CPU may abort it). Ony 149 full frames are accepted. 150 */ 151 152 #endif // MAME_MACHINE_MC6854_H 153