trunk/src/emu/machine/mos6551.c
| r20996 | r20997 | |
| 55 | 55 | mos6551_device::mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 56 | 56 | : device_t(mconfig, MOS6551, "MOS6551", tag, owner, clock), |
| 57 | 57 | device_serial_interface(mconfig, *this), |
| 58 | | m_irq_handler(*this), |
| 58 | m_write_irq(*this), |
| 59 | m_read_rxd(*this), |
| 60 | m_write_txd(*this), |
| 61 | m_write_rts(*this), |
| 62 | m_write_dtr(*this), |
| 59 | 63 | m_ctrl(0), |
| 60 | 64 | m_cmd(CMD_RIE), |
| 61 | 65 | m_st(ST_TDRE), |
| 62 | | m_ext_rxc(0) |
| 66 | m_ext_rxc(0), |
| 67 | m_cts(1), |
| 68 | m_dsr(1), |
| 69 | m_dcd(1) |
| 63 | 70 | { |
| 64 | 71 | } |
| 65 | 72 | |
| r20996 | r20997 | |
| 70 | 77 | |
| 71 | 78 | void mos6551_device::device_start() |
| 72 | 79 | { |
| 73 | | m_irq_handler.resolve_safe(); |
| 80 | // resolve callbacks |
| 81 | m_write_irq.resolve_safe(); |
| 82 | m_read_rxd.resolve_safe(1); |
| 83 | m_write_txd.resolve_safe(); |
| 84 | m_write_rts.resolve_safe(); |
| 85 | m_write_dtr.resolve_safe(); |
| 74 | 86 | |
| 75 | | transmit_register_reset(); |
| 76 | | receive_register_reset(); |
| 87 | // state saving |
| 88 | save_item(NAME(m_ctrl)); |
| 89 | save_item(NAME(m_cmd)); |
| 90 | save_item(NAME(m_st)); |
| 91 | save_item(NAME(m_tdr)); |
| 92 | save_item(NAME(m_ext_rxc)); |
| 93 | save_item(NAME(m_cts)); |
| 94 | save_item(NAME(m_dsr)); |
| 95 | save_item(NAME(m_dcd)); |
| 77 | 96 | } |
| 78 | 97 | |
| 79 | 98 | |
| r20996 | r20997 | |
| 86 | 105 | m_ctrl = 0; |
| 87 | 106 | m_cmd = CMD_RIE; |
| 88 | 107 | |
| 108 | transmit_register_reset(); |
| 109 | receive_register_reset(); |
| 110 | |
| 89 | 111 | update_serial(); |
| 90 | 112 | } |
| 91 | 113 | |
| 92 | 114 | |
| 93 | 115 | //------------------------------------------------- |
| 116 | // tra_callback - |
| 117 | //------------------------------------------------- |
| 118 | |
| 119 | void mos6551_device::tra_callback() |
| 120 | { |
| 121 | m_write_txd(transmit_register_get_data_bit()); |
| 122 | } |
| 123 | |
| 124 | |
| 125 | //------------------------------------------------- |
| 94 | 126 | // tra_complete - |
| 95 | 127 | //------------------------------------------------- |
| 96 | 128 | |
| r20996 | r20997 | |
| 104 | 136 | if ((m_cmd & CMD_TC_MASK) == CMD_TC_TIE_RTS_LO) |
| 105 | 137 | { |
| 106 | 138 | m_st |= ST_IRQ; |
| 107 | | m_irq_handler(ASSERT_LINE); |
| 139 | m_write_irq(ASSERT_LINE); |
| 108 | 140 | } |
| 109 | 141 | } |
| 110 | 142 | } |
| 111 | 143 | |
| 112 | 144 | |
| 113 | 145 | //------------------------------------------------- |
| 146 | // rcv_callback - |
| 147 | //------------------------------------------------- |
| 148 | |
| 149 | void mos6551_device::rcv_callback() |
| 150 | { |
| 151 | if (m_read_rxd.isnull()) |
| 152 | receive_register_update_bit(get_in_data_bit()); |
| 153 | else |
| 154 | receive_register_update_bit(m_read_rxd()); |
| 155 | } |
| 156 | |
| 157 | |
| 158 | //------------------------------------------------- |
| 114 | 159 | // rcv_complete - |
| 115 | 160 | //------------------------------------------------- |
| 116 | 161 | |
| r20996 | r20997 | |
| 128 | 173 | if (!(m_cmd & CMD_RIE)) |
| 129 | 174 | { |
| 130 | 175 | m_st |= ST_IRQ; |
| 131 | | m_irq_handler(ASSERT_LINE); |
| 176 | m_write_irq(ASSERT_LINE); |
| 132 | 177 | } |
| 133 | 178 | } |
| 134 | 179 | |
| r20996 | r20997 | |
| 191 | 236 | else |
| 192 | 237 | m_connection_state &= ~SERIAL_STATE_DTR; |
| 193 | 238 | |
| 239 | m_write_dtr((m_connection_state & SERIAL_STATE_DTR) ? 0 : 1); |
| 240 | |
| 194 | 241 | if ((m_cmd & CMD_TC_MASK) == CMD_TC_RTS_HI) |
| 195 | 242 | m_connection_state &= ~SERIAL_STATE_RTS; |
| 196 | 243 | else |
| 197 | 244 | m_connection_state |= SERIAL_STATE_RTS; |
| 245 | |
| 246 | m_write_rts((m_connection_state & SERIAL_STATE_RTS) ? 0 : 1); |
| 198 | 247 | |
| 199 | 248 | serial_connection_out(); |
| 200 | 249 | } |
| r20996 | r20997 | |
| 221 | 270 | break; |
| 222 | 271 | |
| 223 | 272 | case 1: |
| 224 | | data = m_st; |
| 273 | data = (m_dsr << 6) | (m_dcd << 5) | m_st; |
| 225 | 274 | m_st &= ~ST_IRQ; |
| 226 | | m_irq_handler(CLEAR_LINE); |
| 275 | m_write_irq(CLEAR_LINE); |
| 227 | 276 | break; |
| 228 | 277 | |
| 229 | 278 | case 2: |
| r20996 | r20997 | |
| 259 | 308 | if ((m_cmd & CMD_TC_MASK) == CMD_TC_TIE_RTS_LO) |
| 260 | 309 | { |
| 261 | 310 | m_st |= ST_IRQ; |
| 262 | | m_irq_handler(ASSERT_LINE); |
| 311 | m_write_irq(ASSERT_LINE); |
| 263 | 312 | } |
| 264 | 313 | } |
| 265 | 314 | break; |
| r20996 | r20997 | |
| 294 | 343 | |
| 295 | 344 | update_serial(); |
| 296 | 345 | } |
| 346 | |
| 347 | |
| 348 | //------------------------------------------------- |
| 349 | // rxc_w - receive clock write |
| 350 | //------------------------------------------------- |
| 351 | |
| 352 | WRITE_LINE_MEMBER( mos6551_device::rxc_w ) |
| 353 | { |
| 354 | // TODO |
| 355 | } |
| 356 | |
| 357 | |
| 358 | //------------------------------------------------- |
| 359 | // cts_w - clear to send write |
| 360 | //------------------------------------------------- |
| 361 | |
| 362 | WRITE_LINE_MEMBER( mos6551_device::cts_w ) |
| 363 | { |
| 364 | m_cts = state; |
| 365 | } |
| 366 | |
| 367 | |
| 368 | //------------------------------------------------- |
| 369 | // dsr_w - data set ready write |
| 370 | //------------------------------------------------- |
| 371 | |
| 372 | WRITE_LINE_MEMBER( mos6551_device::dsr_w ) |
| 373 | { |
| 374 | if (m_dsr != state) |
| 375 | { |
| 376 | m_st |= ST_IRQ; |
| 377 | m_write_irq(ASSERT_LINE); |
| 378 | } |
| 379 | |
| 380 | m_dsr = state; |
| 381 | } |
| 382 | |
| 383 | |
| 384 | //------------------------------------------------- |
| 385 | // dcd_w - data carrier detect write |
| 386 | //------------------------------------------------- |
| 387 | |
| 388 | WRITE_LINE_MEMBER( mos6551_device::dcd_w ) |
| 389 | { |
| 390 | if (m_dcd != state) |
| 391 | { |
| 392 | m_st |= ST_IRQ; |
| 393 | m_write_irq(ASSERT_LINE); |
| 394 | } |
| 395 | |
| 396 | m_dcd = state; |
| 397 | } |
trunk/src/emu/machine/mos6551.h
| r20996 | r20997 | |
| 39 | 39 | |
| 40 | 40 | #define MCFG_MOS6551_ADD(_tag, _clock, _irq) \ |
| 41 | 41 | MCFG_DEVICE_ADD(_tag, MOS6551, _clock) \ |
| 42 | | devcb = &mos6551_device::set_irq_handler(*device, DEVCB2_##_irq); |
| 42 | downcast<mos6551_device *>(device)->set_irq_callback(DEVCB2_##_rxd, DEVCB2_##_irq); |
| 43 | 43 | |
| 44 | #define MCFG_MOS6551_RXD_TXD_CALLBACKS(_rxd, _txd) \ |
| 45 | downcast<mos6551_device *>(device)->set_rxd_txd_callbacks(DEVCB2_##_rxd, DEVCB2_##_txd); |
| 44 | 46 | |
| 47 | #define MCFG_MOS6551_RTS_CALLBACK(_rts) \ |
| 48 | downcast<mos6551_device *>(device)->set_rts_callback(DEVCB2_##_rts); |
| 45 | 49 | |
| 50 | #define MCFG_MOS6551_DTR_CALLBACK(_dtr) \ |
| 51 | downcast<mos6551_device *>(device)->set_dtr_callback(DEVCB2_##_dtr); |
| 52 | |
| 53 | |
| 54 | |
| 46 | 55 | //************************************************************************** |
| 47 | 56 | // TYPE DEFINITIONS |
| 48 | 57 | //************************************************************************** |
| r20996 | r20997 | |
| 56 | 65 | // construction/destruction |
| 57 | 66 | mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 58 | 67 | |
| 59 | | // static configuration helpers |
| 60 | | template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<mos6551_device &>(device).m_irq_handler.set_callback(object); } |
| 68 | template<class _irq> void set_irq_callback(_irq irq) { m_write_irq.set_callback(irq); } |
| 69 | template<class _rxd, class _txd> void set_rxd_txd_callbacks(_rxd rxd, _txd txd) { |
| 70 | m_read_rxd.set_callback(rxd); |
| 71 | m_write_txd.set_callback(txd); |
| 72 | } |
| 73 | template<class _rts> void set_rts_callback(_rts rts) { m_write_rts.set_callback(rts); } |
| 74 | template<class _dtr> void set_dtr_callback(_dtr dtr) { m_write_dtr.set_callback(dtr); } |
| 61 | 75 | |
| 62 | 76 | DECLARE_READ8_MEMBER( read ); |
| 63 | 77 | DECLARE_WRITE8_MEMBER( write ); |
| 64 | 78 | |
| 79 | DECLARE_WRITE_LINE_MEMBER( rxc_w ); |
| 80 | DECLARE_WRITE_LINE_MEMBER( cts_w ); |
| 81 | DECLARE_WRITE_LINE_MEMBER( dsr_w ); |
| 82 | DECLARE_WRITE_LINE_MEMBER( dcd_w ); |
| 83 | |
| 65 | 84 | void set_rxc(int clock); |
| 66 | 85 | |
| 67 | 86 | protected: |
| r20996 | r20997 | |
| 70 | 89 | virtual void device_reset(); |
| 71 | 90 | |
| 72 | 91 | // device_serial_interface overrides |
| 92 | virtual void tra_callback(); |
| 73 | 93 | virtual void tra_complete(); |
| 94 | virtual void rcv_callback(); |
| 74 | 95 | virtual void rcv_complete(); |
| 75 | 96 | virtual void input_callback(UINT8 state); |
| 76 | 97 | |
| r20996 | r20997 | |
| 145 | 166 | |
| 146 | 167 | void update_serial(); |
| 147 | 168 | |
| 148 | | devcb2_write_line m_irq_handler; |
| 169 | devcb2_write_line m_write_irq; |
| 170 | devcb2_read_line m_read_rxd; |
| 171 | devcb2_write_line m_write_txd; |
| 172 | devcb2_write_line m_write_rts; |
| 173 | devcb2_write_line m_write_dtr; |
| 149 | 174 | |
| 150 | 175 | UINT8 m_ctrl; |
| 151 | 176 | UINT8 m_cmd; |
| r20996 | r20997 | |
| 153 | 178 | UINT8 m_tdr; |
| 154 | 179 | |
| 155 | 180 | int m_ext_rxc; |
| 181 | int m_cts; |
| 182 | int m_dsr; |
| 183 | int m_dcd; |
| 156 | 184 | |
| 157 | 185 | static const int brg_divider[16]; |
| 158 | 186 | }; |