1 |
/* |
/* |
2 |
* Copyright (C) 2003-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: lk201.c,v 1.25 2005/12/26 14:14:38 debug Exp $ |
* $Id: lk201.c,v 1.29 2007/06/15 20:11:27 debug Exp $ |
29 |
* |
* |
30 |
* LK201 keyboard and mouse specifics, used by the dc7085 and scc serial |
* COMMENT: LK201 keyboard and mouse, used by the dc7085 and scc controllers |
|
* controller devices. |
|
31 |
*/ |
*/ |
32 |
|
|
33 |
#include <stdio.h> |
#include <stdio.h> |
36 |
|
|
37 |
#include "console.h" |
#include "console.h" |
38 |
#include "devices.h" |
#include "devices.h" |
39 |
|
#include "machine.h" |
40 |
#include "misc.h" |
#include "misc.h" |
41 |
|
|
42 |
#include "dc7085.h" /* for port names */ |
#include "dc7085.h" /* for port names */ |
151 |
/* |
/* |
152 |
* lk201_send_mouse_update_sequence(): |
* lk201_send_mouse_update_sequence(): |
153 |
* |
* |
154 |
* mouse_x,y,buttons contains the coordinates on the host's display, the |
* mouse_x, _y, _buttons contains the coordinates on the host's display, the |
155 |
* "goal" of where we want to move. d->mouse_* contains the current state. |
* "goal" of where we want to move. |
156 |
* |
* |
157 |
* TODO: Comment this better. |
* d->mouse_x, _y, _buttons contain the last values transmitted to the |
158 |
|
* emulated machine. |
159 |
*/ |
*/ |
160 |
void lk201_send_mouse_update_sequence(struct lk201_data *d, int mouse_x, |
static int lk201_send_mouse_update_sequence(struct lk201_data *d, int mouse_x, |
161 |
int mouse_y, int mouse_buttons, int mouse_fb_nr) |
int mouse_y, int mouse_buttons, int mouse_fb_nr) |
162 |
{ |
{ |
163 |
int xsign, xdelta, ysign, ydelta, m; |
int xsign, xdelta, ysign, ydelta, m; |
|
int framebuffer_nr; |
|
|
|
|
|
if (d->old_host_mouse_x == mouse_x && |
|
|
d->old_host_mouse_y == mouse_y) |
|
|
d->old_host_mouse_stays_put ++; |
|
|
else |
|
|
d->old_host_mouse_stays_put = 0; |
|
|
|
|
|
d->old_host_mouse_x = mouse_x; |
|
|
d->old_host_mouse_y = mouse_y; |
|
|
|
|
|
if (d->old_host_mouse_stays_put > 400 && |
|
|
d->mouse_buttons == mouse_buttons) |
|
|
return; |
|
|
|
|
|
console_get_framebuffer_mouse(&d->mouse_x, &d->mouse_y, |
|
|
&framebuffer_nr); |
|
164 |
|
|
165 |
xdelta = mouse_x - d->mouse_x; |
xdelta = mouse_x - d->mouse_x; |
166 |
ydelta = mouse_y - d->mouse_y; |
ydelta = mouse_y - d->mouse_y; |
167 |
|
|
|
/* |
|
|
* If the last framebuffer cursor placement was not in the |
|
|
* same window as the last host cursor movement, then we |
|
|
* we have to move to the leftmost extreme or rightmost |
|
|
* extreme: |
|
|
*/ |
|
|
if (framebuffer_nr != mouse_fb_nr) { |
|
|
if (mouse_fb_nr > framebuffer_nr) |
|
|
xdelta = 2000; |
|
|
if (mouse_fb_nr < framebuffer_nr) |
|
|
xdelta = -2000; |
|
|
} |
|
|
|
|
168 |
/* If no change, then don't send any update! */ |
/* If no change, then don't send any update! */ |
169 |
if (xdelta == 0 && ydelta == 0 && d->mouse_buttons == mouse_buttons) |
if (xdelta == 0 && ydelta == 0 && d->mouse_buttons == mouse_buttons) |
170 |
return; |
return 0; |
171 |
|
|
172 |
m = 4 >> (d->old_host_mouse_stays_put / 30); |
m = 20; |
|
if (m < 1) |
|
|
m = 1; |
|
173 |
|
|
174 |
if (xdelta > m) |
if (xdelta > m) |
175 |
xdelta = m; |
xdelta = m; |
180 |
if (ydelta < -m) |
if (ydelta < -m) |
181 |
ydelta = -m; |
ydelta = -m; |
182 |
|
|
|
xsign = xdelta < 0? 1 : 0; |
|
|
ysign = ydelta < 0? 1 : 0; |
|
|
|
|
183 |
d->mouse_x += xdelta; |
d->mouse_x += xdelta; |
184 |
d->mouse_y += ydelta; |
d->mouse_y += ydelta; |
185 |
d->mouse_buttons = mouse_buttons; |
d->mouse_buttons = mouse_buttons; |
186 |
|
|
187 |
|
/* |
188 |
|
* TODO: Update d->mouse_framebuffer_nr some way! |
189 |
|
*/ |
190 |
|
|
191 |
|
xsign = xdelta < 0? 1 : 0; |
192 |
|
ysign = ydelta < 0? 1 : 0; |
193 |
|
|
194 |
switch (d->mouse_mode) { |
switch (d->mouse_mode) { |
195 |
|
|
196 |
case 0: |
case 0: |
197 |
/* Do nothing (before the mouse is initialized) */ |
/* Do nothing (before the mouse is initialized) */ |
198 |
break; |
return 0; |
199 |
|
|
200 |
case MOUSE_INCREMENTAL: |
case MOUSE_INCREMENTAL: |
201 |
if (xdelta < 0) |
if (xdelta < 0) |
202 |
xdelta = -xdelta; |
xdelta = -xdelta; |
212 |
d->add_to_rx_queue(d->add_data, xdelta, DCMOUSE_PORT); |
d->add_to_rx_queue(d->add_data, xdelta, DCMOUSE_PORT); |
213 |
d->add_to_rx_queue(d->add_data, ydelta, DCMOUSE_PORT); |
d->add_to_rx_queue(d->add_data, ydelta, DCMOUSE_PORT); |
214 |
break; |
break; |
215 |
|
|
216 |
default: |
default: |
217 |
/* TODO: prompt mode and perhaps more stuff */ |
/* TODO: prompt mode and perhaps more stuff */ |
218 |
fatal("[ lk201: mouse mode 0x%02x unknown: TODO ]\n", |
fatal("[ lk201: mouse mode 0x%02x unknown: TODO ]\n", |
219 |
d->mouse_mode); |
d->mouse_mode); |
220 |
|
exit(1); |
221 |
} |
} |
222 |
|
|
223 |
|
return 1; |
224 |
} |
} |
225 |
|
|
226 |
|
|
231 |
* If a key is available from the keyboard, add it to the rx queue. |
* If a key is available from the keyboard, add it to the rx queue. |
232 |
* If other bits are set, an interrupt might need to be caused. |
* If other bits are set, an interrupt might need to be caused. |
233 |
*/ |
*/ |
234 |
void lk201_tick(struct lk201_data *d) |
void lk201_tick(struct machine *machine, struct lk201_data *d) |
235 |
{ |
{ |
236 |
int mouse_x, mouse_y, mouse_buttons, mouse_fb_nr; |
int mouse_x, mouse_y, mouse_buttons, mouse_fb_nr; |
237 |
|
|
246 |
* serial console: |
* serial console: |
247 |
* |
* |
248 |
* DEC MIPSMATE 5100 uses the keyboard port. |
* DEC MIPSMATE 5100 uses the keyboard port. |
249 |
* DECstation 3100 (PMAX) uses the printer port. |
* DECstation 3100 (PMAX) and 5000/2000 (3MAX) use |
250 |
* All others seem to use the comm port. |
* the printer port. |
251 |
|
* Others seem to use the comm port. |
252 |
*/ |
*/ |
253 |
d->add_to_rx_queue(d->add_data, ch, DCKBD_PORT); |
if (machine->machine_type == MACHINE_PMAX) { |
254 |
d->add_to_rx_queue(d->add_data, ch, DCCOMM_PORT); |
switch (machine->machine_subtype) { |
255 |
d->add_to_rx_queue(d->add_data, ch, DCPRINTER_PORT); |
case MACHINE_DEC_MIPSMATE_5100: |
256 |
|
d->add_to_rx_queue(d->add_data, |
257 |
|
ch, DCKBD_PORT); |
258 |
|
break; |
259 |
|
case MACHINE_DEC_PMAX_3100: |
260 |
|
case MACHINE_DEC_3MAX_5000: |
261 |
|
d->add_to_rx_queue(d->add_data, |
262 |
|
ch, DCPRINTER_PORT); |
263 |
|
break; |
264 |
|
default: |
265 |
|
d->add_to_rx_queue(d->add_data, |
266 |
|
ch, DCCOMM_PORT); |
267 |
|
} |
268 |
|
} else { |
269 |
|
d->add_to_rx_queue(d->add_data, |
270 |
|
ch, DCCOMM_PORT); |
271 |
|
} |
272 |
} |
} |
273 |
} |
} |
274 |
|
|
276 |
if (!d->use_fb) |
if (!d->use_fb) |
277 |
return; |
return; |
278 |
|
|
279 |
d->mouse_check_interval --; |
console_getmouse(&mouse_x, &mouse_y, &mouse_buttons, |
280 |
if (d->mouse_check_interval <= 0) { |
&mouse_fb_nr); |
281 |
d->mouse_check_interval = |
|
282 |
d->mouse_check_interval_reset; |
lk201_send_mouse_update_sequence(d, mouse_x, mouse_y, |
283 |
|
mouse_buttons, mouse_fb_nr); |
|
/* |
|
|
* Check for mouse updates: |
|
|
* |
|
|
* Note: mouse_{x,y} are where the mouse is |
|
|
* on the host's display. |
|
|
*/ |
|
|
console_getmouse(&mouse_x, &mouse_y, &mouse_buttons, |
|
|
&mouse_fb_nr); |
|
|
|
|
|
if (mouse_x != d->mouse_x || mouse_y != d->mouse_y || |
|
|
mouse_buttons != d->mouse_buttons) |
|
|
lk201_send_mouse_update_sequence(d, mouse_x, mouse_y, |
|
|
mouse_buttons, mouse_fb_nr); |
|
|
} |
|
284 |
} |
} |
285 |
|
|
286 |
|
|
397 |
d->mouse_mode = 0; |
d->mouse_mode = 0; |
398 |
d->mouse_revision = 0; /* 0..15 */ |
d->mouse_revision = 0; /* 0..15 */ |
399 |
d->console_handle = console_handle; |
d->console_handle = console_handle; |
|
|
|
|
d->mouse_check_interval_reset = 1 << 3; |
|
400 |
} |
} |
401 |
|
|