1 |
/* |
/* |
2 |
* Copyright (C) 2003-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2006 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.27 2006/09/06 04:55:35 debug Exp $ |
29 |
* |
* |
30 |
* LK201 keyboard and mouse specifics, used by the dc7085 and scc serial |
* LK201 keyboard and mouse specifics, used by the dc7085 and scc serial |
31 |
* controller devices. |
* controller devices. |
37 |
|
|
38 |
#include "console.h" |
#include "console.h" |
39 |
#include "devices.h" |
#include "devices.h" |
40 |
|
#include "machine.h" |
41 |
#include "misc.h" |
#include "misc.h" |
42 |
|
|
43 |
#include "dc7085.h" /* for port names */ |
#include "dc7085.h" /* for port names */ |
152 |
/* |
/* |
153 |
* lk201_send_mouse_update_sequence(): |
* lk201_send_mouse_update_sequence(): |
154 |
* |
* |
155 |
* 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 |
156 |
* "goal" of where we want to move. d->mouse_* contains the current state. |
* "goal" of where we want to move. |
157 |
* |
* |
158 |
* TODO: Comment this better. |
* d->mouse_x, _y, _buttons contain the last values transmitted to the |
159 |
|
* emulated machine. |
160 |
*/ |
*/ |
161 |
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, |
162 |
int mouse_y, int mouse_buttons, int mouse_fb_nr) |
int mouse_y, int mouse_buttons, int mouse_fb_nr) |
163 |
{ |
{ |
164 |
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); |
|
165 |
|
|
166 |
xdelta = mouse_x - d->mouse_x; |
xdelta = mouse_x - d->mouse_x; |
167 |
ydelta = mouse_y - d->mouse_y; |
ydelta = mouse_y - d->mouse_y; |
168 |
|
|
|
/* |
|
|
* 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; |
|
|
} |
|
|
|
|
169 |
/* If no change, then don't send any update! */ |
/* If no change, then don't send any update! */ |
170 |
if (xdelta == 0 && ydelta == 0 && d->mouse_buttons == mouse_buttons) |
if (xdelta == 0 && ydelta == 0 && d->mouse_buttons == mouse_buttons) |
171 |
return; |
return 0; |
172 |
|
|
173 |
m = 4 >> (d->old_host_mouse_stays_put / 30); |
m = 20; |
|
if (m < 1) |
|
|
m = 1; |
|
174 |
|
|
175 |
if (xdelta > m) |
if (xdelta > m) |
176 |
xdelta = m; |
xdelta = m; |
181 |
if (ydelta < -m) |
if (ydelta < -m) |
182 |
ydelta = -m; |
ydelta = -m; |
183 |
|
|
|
xsign = xdelta < 0? 1 : 0; |
|
|
ysign = ydelta < 0? 1 : 0; |
|
|
|
|
184 |
d->mouse_x += xdelta; |
d->mouse_x += xdelta; |
185 |
d->mouse_y += ydelta; |
d->mouse_y += ydelta; |
186 |
d->mouse_buttons = mouse_buttons; |
d->mouse_buttons = mouse_buttons; |
187 |
|
|
188 |
|
/* |
189 |
|
* TODO: Update d->mouse_framebuffer_nr some way! |
190 |
|
*/ |
191 |
|
|
192 |
|
xsign = xdelta < 0? 1 : 0; |
193 |
|
ysign = ydelta < 0? 1 : 0; |
194 |
|
|
195 |
switch (d->mouse_mode) { |
switch (d->mouse_mode) { |
196 |
|
|
197 |
case 0: |
case 0: |
198 |
/* Do nothing (before the mouse is initialized) */ |
/* Do nothing (before the mouse is initialized) */ |
199 |
break; |
return 0; |
200 |
|
|
201 |
case MOUSE_INCREMENTAL: |
case MOUSE_INCREMENTAL: |
202 |
if (xdelta < 0) |
if (xdelta < 0) |
203 |
xdelta = -xdelta; |
xdelta = -xdelta; |
213 |
d->add_to_rx_queue(d->add_data, xdelta, DCMOUSE_PORT); |
d->add_to_rx_queue(d->add_data, xdelta, DCMOUSE_PORT); |
214 |
d->add_to_rx_queue(d->add_data, ydelta, DCMOUSE_PORT); |
d->add_to_rx_queue(d->add_data, ydelta, DCMOUSE_PORT); |
215 |
break; |
break; |
216 |
|
|
217 |
default: |
default: |
218 |
/* TODO: prompt mode and perhaps more stuff */ |
/* TODO: prompt mode and perhaps more stuff */ |
219 |
fatal("[ lk201: mouse mode 0x%02x unknown: TODO ]\n", |
fatal("[ lk201: mouse mode 0x%02x unknown: TODO ]\n", |
220 |
d->mouse_mode); |
d->mouse_mode); |
221 |
|
exit(1); |
222 |
} |
} |
223 |
|
|
224 |
|
return 1; |
225 |
} |
} |
226 |
|
|
227 |
|
|
232 |
* 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. |
233 |
* If other bits are set, an interrupt might need to be caused. |
* If other bits are set, an interrupt might need to be caused. |
234 |
*/ |
*/ |
235 |
void lk201_tick(struct lk201_data *d) |
void lk201_tick(struct machine *machine, struct lk201_data *d) |
236 |
{ |
{ |
237 |
int mouse_x, mouse_y, mouse_buttons, mouse_fb_nr; |
int mouse_x, mouse_y, mouse_buttons, mouse_fb_nr; |
238 |
|
|
247 |
* serial console: |
* serial console: |
248 |
* |
* |
249 |
* DEC MIPSMATE 5100 uses the keyboard port. |
* DEC MIPSMATE 5100 uses the keyboard port. |
250 |
* DECstation 3100 (PMAX) uses the printer port. |
* DECstation 3100 (PMAX) and 5000/2000 (3MAX) use |
251 |
* All others seem to use the comm port. |
* the printer port. |
252 |
|
* Others seem to use the comm port. |
253 |
*/ |
*/ |
254 |
d->add_to_rx_queue(d->add_data, ch, DCKBD_PORT); |
if (machine->machine_type == MACHINE_PMAX) { |
255 |
d->add_to_rx_queue(d->add_data, ch, DCCOMM_PORT); |
switch (machine->machine_subtype) { |
256 |
d->add_to_rx_queue(d->add_data, ch, DCPRINTER_PORT); |
case MACHINE_DEC_MIPSMATE_5100: |
257 |
|
d->add_to_rx_queue(d->add_data, |
258 |
|
ch, DCKBD_PORT); |
259 |
|
break; |
260 |
|
case MACHINE_DEC_PMAX_3100: |
261 |
|
case MACHINE_DEC_3MAX_5000: |
262 |
|
d->add_to_rx_queue(d->add_data, |
263 |
|
ch, DCPRINTER_PORT); |
264 |
|
break; |
265 |
|
default: |
266 |
|
d->add_to_rx_queue(d->add_data, |
267 |
|
ch, DCCOMM_PORT); |
268 |
|
} |
269 |
|
} else { |
270 |
|
d->add_to_rx_queue(d->add_data, |
271 |
|
ch, DCCOMM_PORT); |
272 |
|
} |
273 |
} |
} |
274 |
} |
} |
275 |
|
|
277 |
if (!d->use_fb) |
if (!d->use_fb) |
278 |
return; |
return; |
279 |
|
|
280 |
d->mouse_check_interval --; |
console_getmouse(&mouse_x, &mouse_y, &mouse_buttons, |
281 |
if (d->mouse_check_interval <= 0) { |
&mouse_fb_nr); |
282 |
d->mouse_check_interval = |
|
283 |
d->mouse_check_interval_reset; |
lk201_send_mouse_update_sequence(d, mouse_x, mouse_y, |
284 |
|
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); |
|
|
} |
|
285 |
} |
} |
286 |
|
|
287 |
|
|
398 |
d->mouse_mode = 0; |
d->mouse_mode = 0; |
399 |
d->mouse_revision = 0; /* 0..15 */ |
d->mouse_revision = 0; /* 0..15 */ |
400 |
d->console_handle = console_handle; |
d->console_handle = console_handle; |
|
|
|
|
d->mouse_check_interval_reset = 1 << 3; |
|
401 |
} |
} |
402 |
|
|