src/mess/machine/isa_com.c
| r14431 | r14432 | |
| 122 | 122 | }; |
| 123 | 123 | |
| 124 | 124 | static SLOT_INTERFACE_START(isa_com) |
| 125 | | SLOT_INTERFACE("mouse", SERIAL_MOUSE) |
| 125 | SLOT_INTERFACE("microsoft_mouse", MSFT_SERIAL_MOUSE) |
| 126 | SLOT_INTERFACE("mouse_systems_mouse", MSYSTEM_SERIAL_MOUSE) |
| 126 | 127 | SLOT_INTERFACE_END |
| 127 | 128 | |
| 128 | 129 | static MACHINE_CONFIG_FRAGMENT( com_config ) |
| r14431 | r14432 | |
| 130 | 131 | MCFG_INS8250_ADD( "uart_1", genpc_com_interface[1] ) |
| 131 | 132 | MCFG_INS8250_ADD( "uart_2", genpc_com_interface[2] ) |
| 132 | 133 | MCFG_INS8250_ADD( "uart_3", genpc_com_interface[3] ) |
| 133 | | MCFG_RS232_PORT_ADD( "serport0", serport_config[0], isa_com, "mouse", NULL ) |
| 134 | MCFG_RS232_PORT_ADD( "serport0", serport_config[0], isa_com, "microsoft_mouse", NULL ) |
| 134 | 135 | MCFG_RS232_PORT_ADD( "serport1", serport_config[1], isa_com, NULL, NULL ) |
| 135 | 136 | MCFG_RS232_PORT_ADD( "serport2", serport_config[3], isa_com, NULL, NULL ) |
| 136 | 137 | MCFG_RS232_PORT_ADD( "serport3", serport_config[4], isa_com, NULL, NULL ) |
| r14431 | r14432 | |
| 208 | 209 | MCFG_NS16450_ADD( "uart_1", genpc_com_interface[1] ) |
| 209 | 210 | MCFG_NS16450_ADD( "uart_2", genpc_com_interface[2] ) |
| 210 | 211 | MCFG_NS16450_ADD( "uart_3", genpc_com_interface[3] ) |
| 211 | | MCFG_RS232_PORT_ADD( "serport0", serport_config[0], isa_com, "mouse", NULL ) |
| 212 | MCFG_RS232_PORT_ADD( "serport0", serport_config[0], isa_com, "microsoft_mouse", NULL ) |
| 212 | 213 | MCFG_RS232_PORT_ADD( "serport1", serport_config[1], isa_com, NULL, NULL ) |
| 213 | 214 | MCFG_RS232_PORT_ADD( "serport2", serport_config[3], isa_com, NULL, NULL ) |
| 214 | 215 | MCFG_RS232_PORT_ADD( "serport3", serport_config[4], isa_com, NULL, NULL ) |
src/mess/machine/ser_mouse.c
| r14431 | r14432 | |
| 9 | 9 | #include "machine/ser_mouse.h" |
| 10 | 10 | |
| 11 | 11 | |
| 12 | | const device_type SERIAL_MOUSE = &device_creator<serial_mouse_device>; |
| 12 | const device_type MSFT_SERIAL_MOUSE = &device_creator<microsoft_mouse_device>; |
| 13 | const device_type MSYSTEM_SERIAL_MOUSE = &device_creator<mouse_systems_mouse_device>; |
| 13 | 14 | |
| 14 | | serial_mouse_device::serial_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 15 | | : device_t(mconfig, SERIAL_MOUSE, "Serial Mouse", tag, owner, clock), |
| 15 | serial_mouse_device::serial_mouse_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock) |
| 16 | : device_t(mconfig, type, name, tag, owner, clock), |
| 16 | 17 | device_rs232_port_interface(mconfig, *this) |
| 17 | 18 | { |
| 18 | 19 | } |
| 19 | 20 | |
| 21 | microsoft_mouse_device::microsoft_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 22 | : serial_mouse_device(mconfig, MSFT_SERIAL_MOUSE, "Microsoft Serial Mouse", tag, owner, clock) |
| 23 | { |
| 24 | } |
| 25 | |
| 26 | mouse_systems_mouse_device::mouse_systems_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 27 | : serial_mouse_device(mconfig, MSYSTEM_SERIAL_MOUSE, "Mouse Systems Serial Mouse", tag, owner, clock) |
| 28 | { |
| 29 | } |
| 30 | |
| 20 | 31 | void serial_mouse_device::device_start() |
| 21 | 32 | { |
| 22 | 33 | m_owner = dynamic_cast<rs232_port_device *>(owner()); |
| 34 | m_timer = timer_alloc(); |
| 35 | m_enabled = false; |
| 23 | 36 | } |
| 24 | 37 | |
| 25 | 38 | void serial_mouse_device::device_reset() |
| 26 | 39 | { |
| 27 | 40 | m_head = m_tail = 0; |
| 28 | | m_timer = timer_alloc(); |
| 29 | | m_old_dtr = m_old_rts = 0; |
| 30 | 41 | } |
| 31 | 42 | |
| 32 | | /* add data to queue */ |
| 33 | | void serial_mouse_device::queue_data(int data) |
| 34 | | { |
| 35 | | m_queue[m_head] = data; |
| 36 | | m_head++; |
| 37 | | m_head %= 256; |
| 38 | | } |
| 39 | | |
| 40 | 43 | /************************************************************************** |
| 41 | 44 | * Check for mouse moves and buttons. Build delta x/y packets |
| 42 | 45 | **************************************************************************/ |
| r14431 | r14432 | |
| 64 | 67 | if (dy>=0x800) dy = ny - 0x1000 - oy; |
| 65 | 68 | oy = ny; |
| 66 | 69 | |
| 67 | | nb = input_port_read(*this, "ser_mouse_misc"); |
| 68 | | if ((nb & 0x80) != 0) |
| 69 | | { |
| 70 | | m_protocol=TYPE_MOUSE_SYSTEMS; |
| 71 | | } |
| 72 | | else |
| 73 | | { |
| 74 | | m_protocol=TYPE_MICROSOFT_MOUSE; |
| 75 | | } |
| 70 | nb = input_port_read(*this, "ser_mouse_btn"); |
| 76 | 71 | mbc = nb^m_mb; |
| 77 | 72 | m_mb = nb; |
| 78 | 73 | |
| 79 | 74 | /* check if there is any delta or mouse buttons changed */ |
| 80 | 75 | if ( (dx!=0) || (dy!=0) || (mbc!=0) ) |
| 81 | | { |
| 82 | | switch (m_protocol) |
| 83 | | { |
| 76 | mouse_trans(dx, dy, nb, mbc); |
| 77 | } |
| 84 | 78 | |
| 85 | | default: |
| 86 | | case TYPE_MICROSOFT_MOUSE: |
| 87 | | { |
| 88 | | /* split deltas into packtes of -128..+127 max */ |
| 89 | | do |
| 90 | | { |
| 91 | | UINT8 m0, m1, m2; |
| 92 | | int ddx = (dx < -128) ? -128 : (dx > 127) ? 127 : dx; |
| 93 | | int ddy = (dy < -128) ? -128 : (dy > 127) ? 127 : dy; |
| 94 | | m0 = 0x40 | ((nb << 4) & 0x30) | ((ddx >> 6) & 0x03) | ((ddy >> 4) & 0x0c); |
| 95 | | m1 = ddx & 0x3f; |
| 96 | | m2 = ddy & 0x3f; |
| 79 | if( m_tail != m_head ) |
| 80 | { |
| 81 | UINT8 data = unqueue_data(); |
| 82 | m_rdata = data; |
| 83 | m_owner->out_rx8(data); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | void microsoft_mouse_device::mouse_trans(int dx, int dy, int nb, int mbc) |
| 88 | { |
| 89 | /* split deltas into packets of -128..+127 max */ |
| 90 | do |
| 91 | { |
| 92 | UINT8 m0, m1, m2; |
| 93 | int ddx = (dx < -128) ? -128 : (dx > 127) ? 127 : dx; |
| 94 | int ddy = (dy < -128) ? -128 : (dy > 127) ? 127 : dy; |
| 95 | m0 = 0x40 | ((nb << 4) & 0x30) | ((ddx >> 6) & 0x03) | ((ddy >> 4) & 0x0c); |
| 96 | m1 = ddx & 0x3f; |
| 97 | m2 = ddy & 0x3f; |
| 97 | 98 | |
| 98 | | /* KT - changed to use a function */ |
| 99 | | queue_data(m0 | 0x40); |
| 100 | | queue_data(m1 & 0x03f); |
| 101 | | queue_data(m2 & 0x03f); |
| 102 | | if ((mbc & 0x04) != 0) /* If button 3 changed send extra byte */ |
| 103 | | queue_data( (nb & 0x04) << 3); |
| 99 | /* KT - changed to use a function */ |
| 100 | queue_data(m0 | 0x40); |
| 101 | queue_data(m1 & 0x03f); |
| 102 | queue_data(m2 & 0x03f); |
| 103 | if ((mbc & 0x04) != 0) /* If button 3 changed send extra byte */ |
| 104 | queue_data( (nb & 0x04) << 3); |
| 104 | 105 | |
| 105 | | dx -= ddx; |
| 106 | | dy -= ddy; |
| 107 | | } while( dx || dy ); |
| 108 | | } |
| 109 | | break; |
| 106 | dx -= ddx; |
| 107 | dy -= ddy; |
| 108 | } while( dx || dy ); |
| 109 | } |
| 110 | 110 | |
| 111 | | /* mouse systems mouse |
| 112 | | from "PC Mouse information" by Tomi Engdahl */ |
| 111 | /* mouse systems mouse |
| 112 | from "PC Mouse information" by Tomi Engdahl */ |
| 113 | 113 | |
| 114 | | /* |
| 115 | | The data is sent in 5 byte packets in following format: |
| 116 | | D7 D6 D5 D4 D3 D2 D1 D0 |
| 114 | /* |
| 115 | The data is sent in 5 byte packets in following format: |
| 116 | D7 D6 D5 D4 D3 D2 D1 D0 |
| 117 | 117 | |
| 118 | | 1. 1 0 0 0 0 LB CB RB |
| 119 | | 2. X7 X6 X5 X4 X3 X2 X1 X0 |
| 120 | | 3. Y7 Y6 Y5 Y4 Y3 Y4 Y1 Y0 |
| 121 | | 4. X7' X6' X5' X4' X3' X2' X1' X0' |
| 122 | | 5. Y7' Y6' Y5' Y4' Y3' Y4' Y1' Y0' |
| 118 | 1. 1 0 0 0 0 LB CB RB |
| 119 | 2. X7 X6 X5 X4 X3 X2 X1 X0 |
| 120 | 3. Y7 Y6 Y5 Y4 Y3 Y4 Y1 Y0 |
| 121 | 4. X7' X6' X5' X4' X3' X2' X1' X0' |
| 122 | 5. Y7' Y6' Y5' Y4' Y3' Y4' Y1' Y0' |
| 123 | 123 | |
| 124 | | LB is left button state (0=pressed, 1=released) |
| 125 | | CB is center button state (0=pressed, 1=released) |
| 126 | | RB is right button state (0=pressed, 1=released) |
| 127 | | X7-X0 movement in X direction since last packet in signed byte |
| 128 | | format (-128..+127), positive direction right |
| 129 | | Y7-Y0 movement in Y direction since last packet in signed byte |
| 130 | | format (-128..+127), positive direction up |
| 131 | | X7'-X0' movement in X direction since sending of X7-X0 packet in signed byte |
| 132 | | format (-128..+127), positive direction right |
| 133 | | Y7'-Y0' movement in Y direction since sending of Y7-Y0 in signed byte |
| 134 | | format (-128..+127), positive direction up |
| 124 | LB is left button state (0=pressed, 1=released) |
| 125 | CB is center button state (0=pressed, 1=released) |
| 126 | RB is right button state (0=pressed, 1=released) |
| 127 | X7-X0 movement in X direction since last packet in signed byte |
| 128 | format (-128..+127), positive direction right |
| 129 | Y7-Y0 movement in Y direction since last packet in signed byte |
| 130 | format (-128..+127), positive direction up |
| 131 | X7'-X0' movement in X direction since sending of X7-X0 packet in signed byte |
| 132 | format (-128..+127), positive direction right |
| 133 | Y7'-Y0' movement in Y direction since sending of Y7-Y0 in signed byte |
| 134 | format (-128..+127), positive direction up |
| 135 | 135 | |
| 136 | | The last two bytes in the packet (bytes 4 and 5) contains information about movement data changes which have occurred after data butes 2 and 3 have been sent. */ |
| 136 | The last two bytes in the packet (bytes 4 and 5) contains information |
| 137 | about movement data changes which have occurred after data bytes 2 and 3 have been sent. */ |
| 137 | 138 | |
| 138 | | case TYPE_MOUSE_SYSTEMS: |
| 139 | | { |
| 139 | void mouse_systems_mouse_device::mouse_trans(int dx, int dy, int nb, int mbc) |
| 140 | { |
| 141 | dy =-dy; |
| 140 | 142 | |
| 141 | | dy =-dy; |
| 142 | | |
| 143 | | do |
| 144 | | { |
| 145 | | int ddx = (dx < -128) ? -128 : (dx > 127) ? 127 : dx; |
| 146 | | int ddy = (dy < -128) ? -128 : (dy > 127) ? 127 : dy; |
| 147 | | |
| 148 | | /* KT - changed to use a function */ |
| 149 | | queue_data(0x080 | ((((nb & 0x04) >> 1) + ((nb & 0x02) << 1) + (nb & 0x01)) ^ 0x07)); |
| 150 | | queue_data(ddx); |
| 151 | | queue_data(ddy); |
| 152 | | /* for now... */ |
| 153 | | queue_data(0); |
| 154 | | queue_data(0); |
| 155 | | dx -= ddx; |
| 156 | | dy -= ddy; |
| 157 | | } while( dx || dy ); |
| 158 | | |
| 159 | | } |
| 160 | | break; |
| 161 | | } |
| 162 | | } |
| 163 | | } |
| 164 | | |
| 165 | | /* Send any data from this scan or any pending data from a previous scan */ |
| 166 | | |
| 167 | | if( m_tail != m_head ) |
| 143 | do |
| 168 | 144 | { |
| 169 | | int data; |
| 145 | int ddx = (dx < -128) ? -128 : (dx > 127) ? 127 : dx; |
| 146 | int ddy = (dy < -128) ? -128 : (dy > 127) ? 127 : dy; |
| 170 | 147 | |
| 171 | | data = m_queue[m_tail]; |
| 172 | | m_rdata = data; |
| 173 | | m_owner->out_rx8(data); |
| 174 | | m_tail++; |
| 175 | | m_tail &= 255; |
| 176 | | } |
| 148 | /* KT - changed to use a function */ |
| 149 | queue_data(0x080 | ((((nb & 0x04) >> 1) + ((nb & 0x02) << 1) + (nb & 0x01)) ^ 0x07)); |
| 150 | queue_data(ddx); |
| 151 | queue_data(ddy); |
| 152 | /* for now... */ |
| 153 | queue_data(0); |
| 154 | queue_data(0); |
| 155 | dx -= ddx; |
| 156 | dy -= ddy; |
| 157 | } while( dx || dy ); |
| 177 | 158 | } |
| 178 | 159 | |
| 179 | | |
| 180 | | |
| 181 | 160 | /************************************************************************** |
| 182 | 161 | * Check for mouse control line changes and (de-)install timer |
| 183 | 162 | **************************************************************************/ |
| 184 | 163 | |
| 185 | | void serial_mouse_device::check_state() |
| 164 | void serial_mouse_device::set_mouse_enable(bool state) |
| 186 | 165 | { |
| 187 | | if((m_dtr == m_old_dtr) && (m_rts == m_old_rts)) return; |
| 166 | if(state && !m_enabled) |
| 167 | m_timer->adjust(attotime::zero, 0, attotime::from_hz(240)); |
| 168 | else if(!state && m_enabled) |
| 169 | { |
| 170 | m_timer->adjust(attotime::zero); |
| 171 | m_head = m_tail = 0; |
| 172 | } |
| 173 | m_enabled = state; |
| 188 | 174 | |
| 175 | } |
| 176 | |
| 177 | void microsoft_mouse_device::check_state() |
| 178 | { |
| 189 | 179 | if (m_dtr && m_rts) |
| 190 | 180 | { |
| 191 | 181 | /* RTS toggled */ |
| 192 | 182 | if (!m_old_rts && m_rts) |
| 193 | 183 | { |
| 194 | 184 | /* reset mouse */ |
| 195 | | m_head = m_tail = m_mb = 0; |
| 196 | | |
| 197 | | if ((input_port_read(*this, "ser_mouse_misc") & 0x80) == 0 ) |
| 198 | | { |
| 199 | | /* Identify as Microsoft 3 Button Mouse */ |
| 200 | | m_queue[m_head] = 'M'; |
| 201 | | m_head++; |
| 202 | | m_head %= 256; |
| 203 | | m_queue[m_head] = '3'; |
| 204 | | m_head++; |
| 205 | | m_head %= 256; |
| 206 | | } |
| 185 | serial_mouse_device::device_reset(); |
| 186 | /* Identify as Microsoft 3 Button Mouse */ |
| 187 | queue_data('M'); |
| 188 | queue_data('3'); |
| 207 | 189 | } |
| 208 | 190 | /* start a timer to scan the mouse input */ |
| 209 | | m_timer->adjust(attotime::zero, 0, attotime::from_hz(240)); |
| 191 | set_mouse_enable(true); |
| 210 | 192 | } |
| 211 | 193 | else |
| 212 | | { |
| 213 | | m_timer->adjust(attotime::zero); |
| 214 | | m_head = m_tail = 0; |
| 215 | | } |
| 194 | set_mouse_enable(false); |
| 216 | 195 | } |
| 217 | 196 | |
| 218 | 197 | |
| r14431 | r14432 | |
| 222 | 201 | **************************************************************************/ |
| 223 | 202 | |
| 224 | 203 | static INPUT_PORTS_START( ser_mouse ) |
| 225 | | PORT_START( "ser_mouse_misc" ) |
| 226 | | PORT_CONFNAME( 0x80, 0x80, "Mouse Protocol" ) |
| 227 | | PORT_CONFSETTING( 0x80, "Mouse Systems" ) |
| 228 | | PORT_CONFSETTING( 0x00, "Microsoft" ) |
| 204 | PORT_START( "ser_mouse_btn" ) |
| 229 | 205 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Mouse Left Button") PORT_CODE(MOUSECODE_BUTTON1) |
| 230 | 206 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Mouse Middle Button") PORT_CODE(MOUSECODE_BUTTON3) |
| 231 | 207 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Mouse Right Button") PORT_CODE(MOUSECODE_BUTTON2) |
src/mess/machine/ser_mouse.h
| r14431 | r14432 | |
| 15 | 15 | public device_rs232_port_interface |
| 16 | 16 | { |
| 17 | 17 | public: |
| 18 | | serial_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 18 | serial_mouse_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock); |
| 19 | 19 | |
| 20 | 20 | virtual ioport_constructor device_input_ports() const; |
| 21 | 21 | |
| 22 | | virtual void dtr_w(UINT8 state) { m_dtr = state; check_state(); m_old_dtr = state; } |
| 23 | | virtual void rts_w(UINT8 state) { m_rts = state; check_state(); m_old_rts = state; } |
| 24 | | |
| 25 | 22 | protected: |
| 26 | 23 | virtual void device_start(); |
| 27 | 24 | virtual void device_reset(); |
| 28 | 25 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 26 | virtual void mouse_trans(int dx, int dy, int nb, int mbc) = 0; |
| 27 | void set_mouse_enable(bool state); |
| 28 | void queue_data(UINT8 data) {m_queue[m_head] = data; ++m_head %= 256;} |
| 29 | UINT8 unqueue_data() {UINT8 ret = m_queue[m_tail]; ++m_tail %= 256; return ret;} |
| 29 | 30 | private: |
| 30 | | typedef enum |
| 31 | | { |
| 32 | | TYPE_MICROSOFT_MOUSE, |
| 33 | | TYPE_MOUSE_SYSTEMS |
| 34 | | } PC_MOUSE_PROTOCOL; |
| 35 | | |
| 36 | | void queue_data(int data); |
| 37 | | void check_state(); |
| 38 | | |
| 39 | | PC_MOUSE_PROTOCOL m_protocol; |
| 40 | | UINT8 m_old_dtr, m_old_rts; |
| 41 | | |
| 42 | 31 | UINT8 m_queue[256]; |
| 43 | 32 | UINT8 m_head, m_tail, m_mb; |
| 44 | 33 | |
| 45 | 34 | emu_timer *m_timer; |
| 46 | 35 | rs232_port_device *m_owner; |
| 36 | bool m_enabled; |
| 47 | 37 | }; |
| 48 | 38 | |
| 49 | | extern const device_type SERIAL_MOUSE; |
| 39 | class microsoft_mouse_device : public serial_mouse_device |
| 40 | { |
| 41 | public: |
| 42 | microsoft_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 43 | virtual void dtr_w(UINT8 state) { m_dtr = state; check_state(); } |
| 44 | virtual void rts_w(UINT8 state) { m_rts = state; check_state(); m_old_rts = state; } |
| 45 | protected: |
| 46 | virtual void mouse_trans(int dx, int dy, int nb, int mbc); |
| 47 | virtual void device_reset() {m_old_rts = 0; serial_mouse_device::device_reset();} |
| 48 | private: |
| 49 | void check_state(); |
| 50 | UINT8 m_old_rts; |
| 51 | }; |
| 52 | extern const device_type MSFT_SERIAL_MOUSE; |
| 50 | 53 | |
| 54 | class mouse_systems_mouse_device : public serial_mouse_device |
| 55 | { |
| 56 | public: |
| 57 | mouse_systems_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 58 | virtual void dtr_w(UINT8 state) { m_dtr = state; check_state(); } |
| 59 | virtual void rts_w(UINT8 state) { m_rts = state; check_state(); } |
| 60 | protected: |
| 61 | virtual void mouse_trans(int dx, int dy, int nb, int mbc); |
| 62 | private: |
| 63 | void check_state() { set_mouse_enable((m_dtr && m_rts)?true:false); } |
| 64 | }; |
| 65 | |
| 66 | extern const device_type MSYSTEM_SERIAL_MOUSE; |
| 67 | |
| 51 | 68 | #endif /* SER_MOUSE_H_ */ |