Previous 199869 Revisions Next

r32153 Wednesday 17th September, 2014 at 13:58:02 UTC by smf
NS8250 Fixes [smf]
Loopback: tx goes high and data is clocked at the correct rate instead of appearing instantly
Modem status register: don't lose track of external signals when starting, resetting, switching loopback off, writing to register
Handshaking: active low for consistency (RS232 port now defaults handshaking lines high and serial mouse dtr/rts handling has been adjusted).
[src/emu/bus/rs232]rs232.c ser_mouse.c ser_mouse.h
[src/emu/machine]ins8250.c ins8250.h

trunk/src/emu/bus/rs232/ser_mouse.h
r32152r32153
2121
2222protected:
2323   virtual void device_start();
24   virtual void device_reset();
2524   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
2625   virtual void mouse_trans(int dx, int dy, int nb, int mbc) = 0;
2726   virtual void set_frame() = 0;
r32152r32153
3029   UINT8 unqueue_data() {UINT8 ret = m_queue[m_tail]; ++m_tail %= 256; return ret;}
3130   virtual void tra_complete();
3231   virtual void tra_callback();
32   void reset_mouse();
33
34   virtual WRITE_LINE_MEMBER(input_dtr);
35   virtual WRITE_LINE_MEMBER(input_rts);
36   int m_dtr;
37   int m_rts;
38
3339private:
3440   UINT8 m_queue[256];
3541   UINT8 m_head, m_tail, m_mb;
r32152r32153
4046   required_ioport m_x;
4147   required_ioport m_y;
4248   required_ioport m_btn;
49
50   void check_state() { set_mouse_enable(!m_dtr && !m_rts); }
4351};
4452
4553class microsoft_mouse_device : public serial_mouse_device
4654{
4755public:
4856   microsoft_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
49   virtual DECLARE_WRITE_LINE_MEMBER( input_dtr ) { m_dtr = state; check_state(); }
50   virtual DECLARE_WRITE_LINE_MEMBER( input_rts ) { m_rts = state; check_state(); m_old_rts = state; }
5157
5258protected:
59   virtual WRITE_LINE_MEMBER(input_rts);
60
5361   virtual void set_frame() { set_data_frame(1, 7, PARITY_NONE, STOP_BITS_2); }
5462   virtual void mouse_trans(int dx, int dy, int nb, int mbc);
55   virtual void device_reset() {m_old_rts = 0; serial_mouse_device::device_reset();}
56
57private:
58   void check_state();
59   int m_dtr;
60   int m_rts;
61   int m_old_rts;
6263};
6364
6465extern const device_type MSFT_SERIAL_MOUSE;
r32152r32153
6768{
6869public:
6970   mouse_systems_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
70   virtual DECLARE_WRITE_LINE_MEMBER( input_dtr ) { m_dtr = state; check_state(); }
71   virtual DECLARE_WRITE_LINE_MEMBER( input_rts ) { m_rts = state; check_state(); }
7271
7372protected:
7473   virtual void set_frame() { set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2); }
7574   virtual void mouse_trans(int dx, int dy, int nb, int mbc);
76
77private:
78   void check_state() { set_mouse_enable((m_dtr && m_rts)?true:false); }
79   int m_dtr;
80   int m_rts;
8175};
8276
8377extern const device_type MSYSTEM_SERIAL_MOUSE;
trunk/src/emu/bus/rs232/rs232.c
r32152r32153
5050   save_item(NAME(m_cts));
5151
5252   m_rxd = 1;
53   m_dcd = 0;
54   m_dsr = 0;
55   m_ri = 0;
56   m_cts = 0;
53   m_dcd = 1;
54   m_dsr = 1;
55   m_ri = 1;
56   m_cts = 1;
5757
5858   m_rxd_handler(1);
59   m_dcd_handler(0);
60   m_dsr_handler(0);
61   m_ri_handler(0);
62   m_cts_handler(0);
59   m_dcd_handler(1);
60   m_dsr_handler(1);
61   m_ri_handler(1);
62   m_cts_handler(1);
6363}
6464
6565WRITE_LINE_MEMBER( rs232_port_device::write_txd )
trunk/src/emu/bus/rs232/ser_mouse.c
r32152r32153
1313   : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
1414   device_rs232_port_interface(mconfig, *this),
1515   device_serial_interface(mconfig, *this),
16   m_dtr(1),
17   m_rts(1),
1618   m_x(*this, "ser_mouse_x"),
1719   m_y(*this, "ser_mouse_y"),
1820   m_btn(*this, "ser_mouse_btn")
r32152r32153
2325
2426microsoft_mouse_device::microsoft_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2527   : serial_mouse_device(mconfig, MSFT_SERIAL_MOUSE, "Microsoft Serial Mouse", tag, owner, clock, "microsoft_mouse", __FILE__)
26   , m_dtr(0)
2728{
2829}
2930
r32152r32153
4041   m_enabled = false;
4142   set_frame();
4243   set_tra_rate(1200);
44   reset_mouse();
45
46   save_item(NAME(m_dtr));
47   save_item(NAME(m_rts));
48   save_item(NAME(m_queue));
49   save_item(NAME(m_head));
50   save_item(NAME(m_tail));
51   save_item(NAME(m_mb));
52   save_item(NAME(m_enabled));
4353}
4454
45void serial_mouse_device::device_reset()
55void serial_mouse_device::reset_mouse()
4656{
4757   m_head = m_tail = 0;
4858   output_rxd(1);
r32152r32153
202212
203213}
204214
205void microsoft_mouse_device::check_state()
215
216WRITE_LINE_MEMBER(serial_mouse_device::input_dtr)
206217{
207   if (m_dtr && m_rts)
218   m_dtr = state;
219   check_state();
220}
221
222WRITE_LINE_MEMBER(serial_mouse_device::input_rts)
223{
224   m_rts = state;
225   check_state();
226}
227
228WRITE_LINE_MEMBER(microsoft_mouse_device::input_rts)
229{
230   if (!m_dtr && m_rts && !state)
208231   {
209      /* RTS toggled */
210      if (!m_old_rts && m_rts)
211      {
212         /* reset mouse */
213         serial_mouse_device::device_reset();
214         /* Identify as Microsoft 3 Button Mouse */
215         queue_data('M');
216         queue_data('3');
217      }
218      /* start a timer to scan the mouse input */
219      set_mouse_enable(true);
232      reset_mouse();
233      /* Identify as Microsoft 3 Button Mouse */
234      queue_data('M');
235      queue_data('3');
220236   }
221   else
222      set_mouse_enable(false);
237
238   serial_mouse_device::input_rts(state);
223239}
224240
225241
trunk/src/emu/machine/ins8250.c
r32152r32153
9797         m_out_rts_cb(*this),
9898         m_out_int_cb(*this),
9999         m_out_out1_cb(*this),
100         m_out_out2_cb(*this)
100         m_out_out2_cb(*this),
101         m_rxd(1),
102         m_dcd(1),
103         m_dsr(1),
104         m_ri(1),
105         m_cts(1)
101106{
102107}
103108
r32152r32153
212217         {
213218            m_regs.thr = data;
214219            m_regs.lsr &= ~0x20;
215            if ( m_regs.mcr & 0x10 )
216            {
217               m_regs.lsr |= 0x61;
218               m_regs.rbr = data;
219               trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
220            }
221            else
222            {
223               if((m_device_type >= TYPE_NS16550) && (m_regs.fcr & 1))
224                  push_tx(data);
225               clear_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
226               if(m_regs.lsr & 0x40)
227                  tra_complete();
228            }
220            if((m_device_type >= TYPE_NS16550) && (m_regs.fcr & 1))
221               push_tx(data);
222            clear_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
223            if(m_regs.lsr & 0x40)
224               tra_complete();
229225         }
230226         break;
231227      case 1:
r32152r32153
289285         {
290286            m_regs.mcr = data & 0x1f;
291287
292            if ( m_regs.mcr & 0x10 )        /* loopback test */
288            update_msr();
289
290            if (m_regs.mcr & 0x10)        /* loopback test */
293291            {
294               data = ( ( m_regs.mcr & 0x0c ) << 4 ) | ( ( m_regs.mcr & 0x01 ) << 5 ) | ( ( m_regs.mcr & 0x02 ) << 3 );
295               if ( ( m_regs.msr & 0x20 ) != ( data & 0x20 ) )
296                  data |= 0x02;
297               if ( ( m_regs.msr & 0x10 ) != ( data & 0x10 ) )
298                  data |= 0x01;
299               if ( ( m_regs.msr & 0x40 ) && ! ( data & 0x40 ) )
300                  data |= 0x04;
301               if ( ( m_regs.msr & 0x80 ) != ( data & 0x80 ) )
302                  data |= 0x08;
303               m_regs.msr = data;
292               m_out_tx_cb(1);
293               device_serial_interface::rx_w(m_txd);
294               m_out_dtr_cb(1);
295               m_out_rts_cb(1);
296               m_out_out1_cb(1);
297               m_out_out2_cb(1);
304298            }
305299            else
306300            {
307               m_out_dtr_cb((m_regs.mcr & 1) ? 1 : 0);
308               m_out_rts_cb((m_regs.mcr & 2) ? 1 : 0);
309               m_out_out1_cb((m_regs.mcr & 4) ? 1 : 0);
310               m_out_out2_cb((m_regs.mcr & 8) ? 1 : 0);
301               m_out_tx_cb(m_txd);
302               device_serial_interface::rx_w(m_rxd);
303               m_out_dtr_cb((m_regs.mcr & 1) ? 0 : 1);
304               m_out_rts_cb((m_regs.mcr & 2) ? 0 : 1);
305               m_out_out1_cb((m_regs.mcr & 4) ? 0 : 1);
306               m_out_out2_cb((m_regs.mcr & 8) ? 0 : 1);
311307            }
312308         }
313309         break;
r32152r32153
327323
328324         break;
329325      case 6:
330         /*
331           This register can be written, but if you write a 1 bit into any of
332           bits 3 - 0, you could cause an interrupt if the appropriate IER bit
333           is set.
334          */
335         m_regs.msr = data;
336
337         if ( m_regs.msr & 0x0f )
338            trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
326         // modem status register is read only
339327         break;
340328      case 7:
341329         m_regs.scr = data;
r32152r32153
354342            data = (m_regs.dl & 0xff);
355343         else
356344         {
357            if((m_device_type >= TYPE_NS16550) && (m_regs.fcr & 1) && !(m_regs.mcr & 0x10))
345            if((m_device_type >= TYPE_NS16550) && (m_regs.fcr & 1))
358346               m_regs.rbr = pop_rx();
359347            else
360348            {
r32152r32153
482470
483471void ins8250_uart_device::tra_callback()
484472{
485   m_out_tx_cb(transmit_register_get_data_bit());
473   m_txd = transmit_register_get_data_bit();
474   if (m_regs.mcr & 0x10)
475   {
476      device_serial_interface::rx_w(m_txd);
477   }
478   else
479   {
480      m_out_tx_cb(m_txd);
481   }
486482}
487483
488void ins8250_uart_device::update_msr(int bit, UINT8 state)
484void ins8250_uart_device::update_msr()
489485{
490   UINT8 mask = (1<<bit);
491   if((m_regs.msr & mask) == (state<<bit))
492      return;
493   m_regs.msr |= mask;
494   m_regs.msr = (m_regs.msr & ~(mask << 4)) | (state<<(bit+4));
495   trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
486   UINT8 data;
487
488   if (m_regs.mcr & 0x10)
489      data = ((m_regs.mcr & 0x0c) << 4) | ((m_regs.mcr & 0x01) << 5) | ((m_regs.mcr & 0x02) << 3);
490   else
491      data = (!m_dcd << 7) | (!m_ri << 6) | (!m_dsr << 5) | (!m_cts << 4);
492
493   int change = (m_regs.msr ^ data) >> 4;
494
495   if (change)
496   {
497      m_regs.msr = data | (m_regs.msr & 0xf) | change;
498
499      trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
500   }
496501}
497502
498503WRITE_LINE_MEMBER(ins8250_uart_device::dcd_w)
499504{
500   update_msr(3, (state ? 1 : 0));
505   m_dcd = state;
506   update_msr();
501507}
502508
503509WRITE_LINE_MEMBER(ins8250_uart_device::dsr_w)
504510{
505   update_msr(1, (state ? 1 : 0));
511   m_dsr = state;
512   update_msr();
506513}
507514
508515WRITE_LINE_MEMBER(ins8250_uart_device::ri_w)
509516{
510   update_msr(2, (state ? 1 : 0));
517   m_ri = state;
518   update_msr();
511519}
512520
513521WRITE_LINE_MEMBER(ins8250_uart_device::cts_w)
514522{
515   update_msr(0, (state ? 1 : 0));
523   m_cts = state;
524   update_msr();
516525}
517526
527WRITE_LINE_MEMBER(ins8250_uart_device::rx_w)
528{
529   m_rxd = state;
530
531   if (!(m_regs.mcr & 0x10))
532      device_serial_interface::rx_w(m_rxd);
533}
534
518535void ins8250_uart_device::device_start()
519536{
520537   m_out_tx_cb.resolve_safe();
r32152r32153
525542   m_out_out2_cb.resolve_safe();
526543   set_tra_rate(0);
527544   set_rcv_rate(0);
528   memset(&m_regs, 0x00, sizeof(m_regs));
529545
530546   device_serial_interface::register_save_state(machine().save(), name(), tag());
531547   save_item(NAME(m_regs.thr));
r32152r32153
540556   save_item(NAME(m_regs.msr));
541557   save_item(NAME(m_regs.scr));
542558   save_item(NAME(m_int_pending));
559   save_item(NAME(m_txd));
560   save_item(NAME(m_rxd));
561   save_item(NAME(m_dcd));
562   save_item(NAME(m_dsr));
563   save_item(NAME(m_ri));
564   save_item(NAME(m_cts));
543565}
544566
545567void ins8250_uart_device::device_reset()
546568{
547   memset(&m_regs, 0x00, sizeof(m_regs));
548569   m_regs.ier = 0;
549570   m_regs.iir = 1;
550571   m_regs.lcr = 0;
551572   m_regs.mcr = 0;
552573   m_regs.lsr = (1<<5) | (1<<6);
574   update_msr();
575   m_regs.msr &= 0xf0;
553576   m_int_pending = 0;
554577   receive_register_reset();
555578   transmit_register_reset();
556   m_out_rts_cb(0);
557   m_out_dtr_cb(0);
558   m_out_out1_cb(0);
559   m_out_out2_cb(0);
579   m_txd = 1;
560580   m_out_tx_cb(1);
581   m_out_rts_cb(1);
582   m_out_dtr_cb(1);
583   m_out_out1_cb(1);
584   m_out_out2_cb(1);
561585}
562586
563587void ins8250_uart_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
trunk/src/emu/machine/ins8250.h
r32152r32153
3232   DECLARE_WRITE_LINE_MEMBER( dsr_w );
3333   DECLARE_WRITE_LINE_MEMBER( ri_w );
3434   DECLARE_WRITE_LINE_MEMBER( cts_w );
35   DECLARE_WRITE_LINE_MEMBER( rx_w ) { device_serial_interface::rx_w(state); }
35   DECLARE_WRITE_LINE_MEMBER( rx_w );
3636
3737protected:
3838   virtual void device_start();
r32152r32153
8181   devcb_write_line    m_out_out2_cb;
8282
8383   void update_interrupt();
84   void update_msr(int bit, UINT8 state);
84   void update_msr();
85
86   int m_txd;
87   int m_rxd;
88   int m_dcd;
89   int m_dsr;
90   int m_ri;
91   int m_cts;
8592};
8693
8794class ins8250_device : public ins8250_uart_device

Previous 199869 Revisions Next


© 1997-2024 The MAME Team