VAXStations: Improvements and bug fixes to keyboard and mouse devices
Whilst working on a new video device I ran into a few problems with the LKxxx keyboard and I noticed there are already some open issues against the keyboard and mouse devices. These changes should resolve #320 and may help with #272 (although I think that is an SDL issue). I've tested these changes with VWS, UWS and DECwindows with both captured and uncaptured input modes.
This commit is contained in:
parent
168d0d9c47
commit
c94edb6b2d
10 changed files with 594 additions and 315 deletions
361
VAX/vax_lk.c
361
VAX/vax_lk.c
|
@ -1,6 +1,6 @@
|
||||||
/* vax_lk.c: DEC Keyboard (LK201)
|
/* vax_lk.c: DEC Keyboard (LK201)
|
||||||
|
|
||||||
Copyright (c) 2011-2013, Matt Burke
|
Copyright (c) 2013-2017, Matt Burke
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -26,12 +26,15 @@
|
||||||
lk LK201 keyboard
|
lk LK201 keyboard
|
||||||
|
|
||||||
11-Jun-2013 MB First version
|
11-Jun-2013 MB First version
|
||||||
|
|
||||||
|
Related documents:
|
||||||
|
|
||||||
|
EK-104AA-TM-001 - VCB02 Technical Manual (chapter B.5)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(VAX_620)
|
#if !defined(VAX_620)
|
||||||
|
|
||||||
#include "vax_defs.h"
|
#include "vax_lk.h"
|
||||||
#include "sim_video.h"
|
|
||||||
|
|
||||||
/* States */
|
/* States */
|
||||||
|
|
||||||
|
@ -46,10 +49,21 @@
|
||||||
#define LK_MODE_NONE 2
|
#define LK_MODE_NONE 2
|
||||||
#define LK_MODE_DOWNUP 3
|
#define LK_MODE_DOWNUP 3
|
||||||
|
|
||||||
|
#define LK_BUF_LEN 100
|
||||||
|
|
||||||
|
#define LK_SEND_CHAR(c) lk_put_fifo (&lk_sndf, c)
|
||||||
|
|
||||||
static const char *lk_modes[] = {"DOWN", "AUTODOWN", "NONE", "DOWNUP"};
|
static const char *lk_modes[] = {"DOWN", "AUTODOWN", "NONE", "DOWNUP"};
|
||||||
|
|
||||||
static const char *lk_states[] = {"DOWN", "UP", "REPEAT"};
|
static const char *lk_states[] = {"DOWN", "UP", "REPEAT"};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32 head;
|
||||||
|
int32 tail;
|
||||||
|
int32 count;
|
||||||
|
uint8 buf[LK_BUF_LEN];
|
||||||
|
} LK_FIFO;
|
||||||
|
|
||||||
/* Scan codes */
|
/* Scan codes */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -57,107 +71,102 @@ typedef struct {
|
||||||
uint8 code;
|
uint8 code;
|
||||||
} LK_KEYDATA;
|
} LK_KEYDATA;
|
||||||
|
|
||||||
LK_KEYDATA LK_KEY_UNKNOWN = { 0, 0 };
|
LK_KEYDATA LK_KEY_UNKNOWN = { 0, LK_UNKNOWN };
|
||||||
LK_KEYDATA LK_KEY_TR_0 = { 1, 0xEF };
|
LK_KEYDATA LK_KEY_TR_0 = { 1, LK_TR_0 };
|
||||||
LK_KEYDATA LK_KEY_TR_1 = { 1, 0xC0 };
|
LK_KEYDATA LK_KEY_TR_1 = { 1, LK_TR_1 };
|
||||||
LK_KEYDATA LK_KEY_TR_2 = { 1, 0xC5 };
|
LK_KEYDATA LK_KEY_TR_2 = { 1, LK_TR_2 };
|
||||||
LK_KEYDATA LK_KEY_TR_3 = { 1, 0xCB };
|
LK_KEYDATA LK_KEY_TR_3 = { 1, LK_TR_3 };
|
||||||
LK_KEYDATA LK_KEY_TR_4 = { 1, 0xD0 };
|
LK_KEYDATA LK_KEY_TR_4 = { 1, LK_TR_4 };
|
||||||
LK_KEYDATA LK_KEY_TR_5 = { 1, 0xD6 };
|
LK_KEYDATA LK_KEY_TR_5 = { 1, LK_TR_5 };
|
||||||
LK_KEYDATA LK_KEY_TR_6 = { 1, 0xDB };
|
LK_KEYDATA LK_KEY_TR_6 = { 1, LK_TR_6 };
|
||||||
LK_KEYDATA LK_KEY_TR_7 = { 1, 0xE0 };
|
LK_KEYDATA LK_KEY_TR_7 = { 1, LK_TR_7 };
|
||||||
LK_KEYDATA LK_KEY_TR_8 = { 1, 0xE5 };
|
LK_KEYDATA LK_KEY_TR_8 = { 1, LK_TR_8 };
|
||||||
LK_KEYDATA LK_KEY_TR_9 = { 1, 0xEA };
|
LK_KEYDATA LK_KEY_TR_9 = { 1, LK_TR_9 };
|
||||||
LK_KEYDATA LK_KEY_A = { 1, 0xC2 };
|
LK_KEYDATA LK_KEY_A = { 1, LK_A };
|
||||||
LK_KEYDATA LK_KEY_B = { 1, 0xD9 };
|
LK_KEYDATA LK_KEY_B = { 1, LK_B };
|
||||||
LK_KEYDATA LK_KEY_C = { 1, 0xCE };
|
LK_KEYDATA LK_KEY_C = { 1, LK_C };
|
||||||
LK_KEYDATA LK_KEY_D = { 1, 0xCD };
|
LK_KEYDATA LK_KEY_D = { 1, LK_D };
|
||||||
LK_KEYDATA LK_KEY_E = { 1, 0xCC };
|
LK_KEYDATA LK_KEY_E = { 1, LK_E };
|
||||||
LK_KEYDATA LK_KEY_F = { 1, 0xD2 };
|
LK_KEYDATA LK_KEY_F = { 1, LK_F };
|
||||||
LK_KEYDATA LK_KEY_G = { 1, 0xD8 };
|
LK_KEYDATA LK_KEY_G = { 1, LK_G };
|
||||||
LK_KEYDATA LK_KEY_H = { 1, 0xDD };
|
LK_KEYDATA LK_KEY_H = { 1, LK_H };
|
||||||
LK_KEYDATA LK_KEY_I = { 1, 0xE6 };
|
LK_KEYDATA LK_KEY_I = { 1, LK_I };
|
||||||
LK_KEYDATA LK_KEY_J = { 1, 0xE2 };
|
LK_KEYDATA LK_KEY_J = { 1, LK_J };
|
||||||
LK_KEYDATA LK_KEY_K = { 1, 0xE7 };
|
LK_KEYDATA LK_KEY_K = { 1, LK_K };
|
||||||
LK_KEYDATA LK_KEY_L = { 1, 0xEC };
|
LK_KEYDATA LK_KEY_L = { 1, LK_L };
|
||||||
LK_KEYDATA LK_KEY_M = { 1, 0xE3 };
|
LK_KEYDATA LK_KEY_M = { 1, LK_M };
|
||||||
LK_KEYDATA LK_KEY_N = { 1, 0xDE };
|
LK_KEYDATA LK_KEY_N = { 1, LK_N };
|
||||||
LK_KEYDATA LK_KEY_O = { 1, 0xEB };
|
LK_KEYDATA LK_KEY_O = { 1, LK_O };
|
||||||
LK_KEYDATA LK_KEY_P = { 1, 0xF0 };
|
LK_KEYDATA LK_KEY_P = { 1, LK_P };
|
||||||
LK_KEYDATA LK_KEY_Q = { 1, 0xC1 };
|
LK_KEYDATA LK_KEY_Q = { 1, LK_Q };
|
||||||
LK_KEYDATA LK_KEY_R = { 1, 0xD1 };
|
LK_KEYDATA LK_KEY_R = { 1, LK_R };
|
||||||
LK_KEYDATA LK_KEY_S = { 1, 0xC7 };
|
LK_KEYDATA LK_KEY_S = { 1, LK_S };
|
||||||
LK_KEYDATA LK_KEY_T = { 1, 0xD7 };
|
LK_KEYDATA LK_KEY_T = { 1, LK_T };
|
||||||
LK_KEYDATA LK_KEY_U = { 1, 0xE1 };
|
LK_KEYDATA LK_KEY_U = { 1, LK_U };
|
||||||
LK_KEYDATA LK_KEY_V = { 1, 0xD3 };
|
LK_KEYDATA LK_KEY_V = { 1, LK_V };
|
||||||
LK_KEYDATA LK_KEY_W = { 1, 0xC6 };
|
LK_KEYDATA LK_KEY_W = { 1, LK_W };
|
||||||
LK_KEYDATA LK_KEY_X = { 1, 0xC8 };
|
LK_KEYDATA LK_KEY_X = { 1, LK_X };
|
||||||
LK_KEYDATA LK_KEY_Y = { 1, 0xDC };
|
LK_KEYDATA LK_KEY_Y = { 1, LK_Y };
|
||||||
LK_KEYDATA LK_KEY_Z = { 1, 0xC3 };
|
LK_KEYDATA LK_KEY_Z = { 1, LK_Z };
|
||||||
LK_KEYDATA LK_KEY_SPACE = { 1, 0xD4 };
|
LK_KEYDATA LK_KEY_SPACE = { 1, LK_SPACE };
|
||||||
LK_KEYDATA LK_KEY_SEMICOLON = { 1, 0xF2 };
|
LK_KEYDATA LK_KEY_SEMICOLON = { 1, LK_SEMICOLON };
|
||||||
LK_KEYDATA LK_KEY_PLUS = { 1, 0xF5 };
|
LK_KEYDATA LK_KEY_PLUS = { 1, LK_PLUS };
|
||||||
LK_KEYDATA LK_KEY_COMMA = { 1, 0xE8 };
|
LK_KEYDATA LK_KEY_COMMA = { 1, LK_COMMA };
|
||||||
LK_KEYDATA LK_KEY_UBAR = { 1, 0xF9 };
|
LK_KEYDATA LK_KEY_UBAR = { 1, LK_UBAR };
|
||||||
LK_KEYDATA LK_KEY_PERIOD = { 1, 0xED };
|
LK_KEYDATA LK_KEY_PERIOD = { 1, LK_PERIOD };
|
||||||
LK_KEYDATA LK_KEY_QMARK = { 1, 0xF3 };
|
LK_KEYDATA LK_KEY_QMARK = { 1, LK_QMARK };
|
||||||
LK_KEYDATA LK_KEY_QUOTE = { 1, 0xFB };
|
LK_KEYDATA LK_KEY_QUOTE = { 1, LK_QUOTE };
|
||||||
LK_KEYDATA LK_KEY_LBRACE = { 1, 0xFA };
|
LK_KEYDATA LK_KEY_LBRACE = { 1, LK_LBRACE };
|
||||||
LK_KEYDATA LK_KEY_RBRACE = { 1, 0xF6 };
|
LK_KEYDATA LK_KEY_RBRACE = { 1, LK_RBRACE };
|
||||||
LK_KEYDATA LK_KEY_VBAR = { 1, 0xF7 };
|
LK_KEYDATA LK_KEY_VBAR = { 1, LK_VBAR };
|
||||||
LK_KEYDATA LK_KEY_TILDE = { 1, 0xBF };
|
LK_KEYDATA LK_KEY_TILDE = { 1, LK_TILDE };
|
||||||
LK_KEYDATA LK_KEY_KP_0 = { 2, 0x92 };
|
LK_KEYDATA LK_KEY_KP_0 = { 2, LK_KP_0 };
|
||||||
LK_KEYDATA LK_KEY_KP_1 = { 2, 0x96 };
|
LK_KEYDATA LK_KEY_KP_1 = { 2, LK_KP_1 };
|
||||||
LK_KEYDATA LK_KEY_KP_2 = { 2, 0x97 };
|
LK_KEYDATA LK_KEY_KP_2 = { 2, LK_KP_2 };
|
||||||
LK_KEYDATA LK_KEY_KP_3 = { 2, 0x98 };
|
LK_KEYDATA LK_KEY_KP_3 = { 2, LK_KP_3 };
|
||||||
LK_KEYDATA LK_KEY_KP_4 = { 2, 0x99 };
|
LK_KEYDATA LK_KEY_KP_4 = { 2, LK_KP_4 };
|
||||||
LK_KEYDATA LK_KEY_KP_5 = { 2, 0x9A };
|
LK_KEYDATA LK_KEY_KP_5 = { 2, LK_KP_5 };
|
||||||
LK_KEYDATA LK_KEY_KP_6 = { 2, 0x9B };
|
LK_KEYDATA LK_KEY_KP_6 = { 2, LK_KP_6 };
|
||||||
LK_KEYDATA LK_KEY_KP_7 = { 2, 0x9D };
|
LK_KEYDATA LK_KEY_KP_7 = { 2, LK_KP_7 };
|
||||||
LK_KEYDATA LK_KEY_KP_8 = { 2, 0x9E };
|
LK_KEYDATA LK_KEY_KP_8 = { 2, LK_KP_8 };
|
||||||
LK_KEYDATA LK_KEY_KP_9 = { 2, 0x9F };
|
LK_KEYDATA LK_KEY_KP_9 = { 2, LK_KP_9 };
|
||||||
LK_KEYDATA LK_KEY_KP_PF1 = { 2, 0xA1 };
|
LK_KEYDATA LK_KEY_KP_PF1 = { 2, LK_KP_PF1 };
|
||||||
LK_KEYDATA LK_KEY_KP_PF2 = { 2, 0xA2 };
|
LK_KEYDATA LK_KEY_KP_PF2 = { 2, LK_KP_PF2 };
|
||||||
LK_KEYDATA LK_KEY_KP_PF3 = { 2, 0xA3 };
|
LK_KEYDATA LK_KEY_KP_PF3 = { 2, LK_KP_PF3 };
|
||||||
LK_KEYDATA LK_KEY_KP_PF4 = { 2, 0xA4 };
|
LK_KEYDATA LK_KEY_KP_PF4 = { 2, LK_KP_PF4 };
|
||||||
LK_KEYDATA LK_KEY_KP_HYPHEN = { 2, 0xA0 };
|
LK_KEYDATA LK_KEY_KP_HYPHEN = { 2, LK_KP_HYPHEN };
|
||||||
LK_KEYDATA LK_KEY_KP_COMMA = { 2, 0x9C };
|
LK_KEYDATA LK_KEY_KP_COMMA = { 2, LK_KP_COMMA };
|
||||||
LK_KEYDATA LK_KEY_KP_PERIOD = { 2, 0x94 };
|
LK_KEYDATA LK_KEY_KP_PERIOD = { 2, LK_KP_PERIOD };
|
||||||
LK_KEYDATA LK_KEY_KP_ENTER = { 2, 0x95 };
|
LK_KEYDATA LK_KEY_KP_ENTER = { 2, LK_KP_ENTER };
|
||||||
LK_KEYDATA LK_KEY_DELETE = { 3, 0xBC };
|
LK_KEYDATA LK_KEY_DELETE = { 3, LK_DELETE };
|
||||||
LK_KEYDATA LK_KEY_TAB = { 3, 0xBE };
|
LK_KEYDATA LK_KEY_TAB = { 3, LK_TAB };
|
||||||
LK_KEYDATA LK_KEY_RETURN = { 4, 0xBD };
|
LK_KEYDATA LK_KEY_RETURN = { 4, LK_RETURN };
|
||||||
LK_KEYDATA LK_KEY_META = { 5, 0xB1 };
|
LK_KEYDATA LK_KEY_META = { 5, LK_META };
|
||||||
LK_KEYDATA LK_KEY_LOCK = { 5, 0xB0 };
|
LK_KEYDATA LK_KEY_LOCK = { 5, LK_LOCK };
|
||||||
LK_KEYDATA LK_KEY_SHIFT = { 6, 0xAE };
|
LK_KEYDATA LK_KEY_SHIFT = { 6, LK_SHIFT };
|
||||||
LK_KEYDATA LK_KEY_CTRL = { 6, 0xAF };
|
LK_KEYDATA LK_KEY_CTRL = { 6, LK_CTRL };
|
||||||
LK_KEYDATA LK_KEY_LEFT = { 7, 0xA7 };
|
LK_KEYDATA LK_KEY_LEFT = { 7, LK_LEFT };
|
||||||
LK_KEYDATA LK_KEY_RIGHT = { 7, 0xA8 };
|
LK_KEYDATA LK_KEY_RIGHT = { 7, LK_RIGHT };
|
||||||
LK_KEYDATA LK_KEY_UP = { 8, 0xAA };
|
LK_KEYDATA LK_KEY_UP = { 8, LK_UP };
|
||||||
LK_KEYDATA LK_KEY_DOWN = { 8, 0xA9 };
|
LK_KEYDATA LK_KEY_DOWN = { 8, LK_DOWN };
|
||||||
LK_KEYDATA LK_KEY_REMOVE = { 9, 0x8C };
|
LK_KEYDATA LK_KEY_REMOVE = { 9, LK_REMOVE };
|
||||||
LK_KEYDATA LK_KEY_NEXT_SCREEN= { 9, 0x8F };
|
LK_KEYDATA LK_KEY_NEXT_SCREEN= { 9, LK_NEXT_SCREEN };
|
||||||
LK_KEYDATA LK_KEY_PREV_SCREEN= { 9, 0x8E };
|
LK_KEYDATA LK_KEY_PREV_SCREEN= { 9, LK_PREV_SCREEN };
|
||||||
LK_KEYDATA LK_KEY_INSERT_HERE= { 9, 0x8B };
|
LK_KEYDATA LK_KEY_INSERT_HERE= { 9, LK_INSERT_HERE };
|
||||||
LK_KEYDATA LK_KEY_FIND = { 9, 0x8A };
|
LK_KEYDATA LK_KEY_FIND = { 9, LK_FIND };
|
||||||
LK_KEYDATA LK_KEY_SELECT = { 9, 0x8D };
|
LK_KEYDATA LK_KEY_SELECT = { 9, LK_SELECT };
|
||||||
LK_KEYDATA LK_KEY_F1 = { 10, 0x56 };
|
LK_KEYDATA LK_KEY_F1 = { 10, LK_F1 };
|
||||||
LK_KEYDATA LK_KEY_F2 = { 10, 0x57 };
|
LK_KEYDATA LK_KEY_F2 = { 10, LK_F2 };
|
||||||
LK_KEYDATA LK_KEY_F3 = { 10, 0x58 };
|
LK_KEYDATA LK_KEY_F3 = { 10, LK_F3 };
|
||||||
LK_KEYDATA LK_KEY_F4 = { 10, 0x59 };
|
LK_KEYDATA LK_KEY_F4 = { 10, LK_F4 };
|
||||||
LK_KEYDATA LK_KEY_F5 = { 10, 0x5A };
|
LK_KEYDATA LK_KEY_F5 = { 10, LK_F5 };
|
||||||
LK_KEYDATA LK_KEY_F6 = { 11, 0x64 };
|
LK_KEYDATA LK_KEY_F6 = { 11, LK_F6 };
|
||||||
LK_KEYDATA LK_KEY_F7 = { 11, 0x65 };
|
LK_KEYDATA LK_KEY_F7 = { 11, LK_F7 };
|
||||||
LK_KEYDATA LK_KEY_F8 = { 11, 0x66 };
|
LK_KEYDATA LK_KEY_F8 = { 11, LK_F8 };
|
||||||
LK_KEYDATA LK_KEY_F9 = { 11, 0x67 };
|
LK_KEYDATA LK_KEY_F9 = { 11, LK_F9 };
|
||||||
LK_KEYDATA LK_KEY_F10 = { 11, 0x68 };
|
LK_KEYDATA LK_KEY_F10 = { 11, LK_F10 };
|
||||||
LK_KEYDATA LK_KEY_F11 = { 12, 0x71 };
|
LK_KEYDATA LK_KEY_F11 = { 12, LK_F11 };
|
||||||
LK_KEYDATA LK_KEY_F12 = { 12, 0x72 };
|
LK_KEYDATA LK_KEY_F12 = { 12, LK_F12 };
|
||||||
|
|
||||||
#define LK_BUF_LEN 100
|
|
||||||
|
|
||||||
#define LK_SEND_CHAR(c) lk_sbuf[lk_stptr++] = c; \
|
|
||||||
if (lk_stptr == LK_BUF_LEN) lk_stptr = 0
|
|
||||||
|
|
||||||
/* Debugging Bitmaps */
|
/* Debugging Bitmaps */
|
||||||
|
|
||||||
|
@ -167,11 +176,8 @@ LK_KEYDATA LK_KEY_F12 = { 12, 0x72 };
|
||||||
t_bool lk_repeat = TRUE; /* autorepeat flag */
|
t_bool lk_repeat = TRUE; /* autorepeat flag */
|
||||||
t_bool lk_trpti = FALSE; /* temp repeat inhibit */
|
t_bool lk_trpti = FALSE; /* temp repeat inhibit */
|
||||||
int32 lk_keysdown = 0; /* no of keys held down */
|
int32 lk_keysdown = 0; /* no of keys held down */
|
||||||
uint8 lk_sbuf[LK_BUF_LEN]; /* send buffer */
|
LK_FIFO lk_sndf; /* send FIFO */
|
||||||
int32 lk_shptr = 0; /* send buf head ptr */
|
LK_FIFO lk_rcvf; /* receive FIFO */
|
||||||
int32 lk_stptr = 0; /* send buf tail ptr */
|
|
||||||
uint8 lk_rbuf[10]; /* receive buffer */
|
|
||||||
int32 lk_rbuf_p = 0; /* receive buffer ptr */
|
|
||||||
int32 lk_mode[16]; /* mode of each key group */
|
int32 lk_mode[16]; /* mode of each key group */
|
||||||
|
|
||||||
t_stat lk_wr (uint8 c);
|
t_stat lk_wr (uint8 c);
|
||||||
|
@ -179,8 +185,10 @@ t_stat lk_rd (uint8 *c);
|
||||||
t_stat lk_reset (DEVICE *dptr);
|
t_stat lk_reset (DEVICE *dptr);
|
||||||
void lk_reset_mode (void);
|
void lk_reset_mode (void);
|
||||||
void lk_cmd (void);
|
void lk_cmd (void);
|
||||||
void lk_poll (void);
|
|
||||||
const char *lk_description (DEVICE *dptr);
|
const char *lk_description (DEVICE *dptr);
|
||||||
|
t_stat lk_put_fifo (LK_FIFO *fifo, uint8 data);
|
||||||
|
t_stat lk_get_fifo (LK_FIFO *fifo, uint8 *data);
|
||||||
|
void lk_clear_fifo (LK_FIFO *fifo);
|
||||||
|
|
||||||
/* LK data structures
|
/* LK data structures
|
||||||
|
|
||||||
|
@ -213,7 +221,7 @@ DEVICE lk_dev = {
|
||||||
NULL, NULL, &lk_reset,
|
NULL, NULL, &lk_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
NULL, DEV_DIS | DEV_DEBUG, 0,
|
NULL, DEV_DIS | DEV_DEBUG, 0,
|
||||||
lk_debug, NULL, NULL, NULL, NULL, NULL,
|
lk_debug, NULL, NULL, NULL, NULL, NULL,
|
||||||
&lk_description
|
&lk_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -224,10 +232,9 @@ t_stat lk_wr (uint8 c)
|
||||||
sim_debug (DBG_SERIAL, &lk_dev, "vax -> lk: %02X\n", c);
|
sim_debug (DBG_SERIAL, &lk_dev, "vax -> lk: %02X\n", c);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
lk_rbuf[lk_rbuf_p++] = c;
|
if (lk_put_fifo (&lk_rcvf, c) != SCPE_OK) { /* too long? */
|
||||||
if (lk_rbuf_p == sizeof(lk_rbuf)) { /* too long? */
|
lk_clear_fifo (&lk_rcvf);
|
||||||
lk_rbuf_p = 0;
|
LK_SEND_CHAR(LK_INERR); /* input error */
|
||||||
LK_SEND_CHAR(0xB6); /* input error */
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
if (c & 0x80) /* cmd terminator? */
|
if (c & 0x80) /* cmd terminator? */
|
||||||
|
@ -239,28 +246,57 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat lk_rd (uint8 *c)
|
t_stat lk_rd (uint8 *c)
|
||||||
{
|
{
|
||||||
if (lk_shptr == lk_stptr)
|
t_stat r;
|
||||||
lk_poll ();
|
|
||||||
if (lk_shptr == lk_stptr) {
|
r = lk_get_fifo (&lk_sndf, c);
|
||||||
*c = 0;
|
if (r == SCPE_OK)
|
||||||
return SCPE_EOF;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*c = lk_sbuf[lk_shptr++];
|
|
||||||
if (lk_shptr == LK_BUF_LEN)
|
|
||||||
lk_shptr = 0; /* ring buffer wrap */
|
|
||||||
sim_debug (DBG_SERIAL, &lk_dev, "lk -> vax: %02X (%s)\n", *c,
|
sim_debug (DBG_SERIAL, &lk_dev, "lk -> vax: %02X (%s)\n", *c,
|
||||||
(lk_shptr != lk_stptr) ? "more" : "end");
|
(lk_sndf.count > 0) ? "more" : "end");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat lk_put_fifo (LK_FIFO *fifo, uint8 data)
|
||||||
|
{
|
||||||
|
if (fifo->count < LK_BUF_LEN) {
|
||||||
|
fifo->buf[fifo->head++] = data;
|
||||||
|
if (fifo->head == LK_BUF_LEN)
|
||||||
|
fifo->head = 0;
|
||||||
|
fifo->count++;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return SCPE_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat lk_get_fifo (LK_FIFO *fifo, uint8 *data)
|
||||||
|
{
|
||||||
|
if (fifo->count > 0) {
|
||||||
|
*data = fifo->buf[fifo->tail++];
|
||||||
|
if (fifo->tail == LK_BUF_LEN)
|
||||||
|
fifo->tail = 0;
|
||||||
|
fifo->count--;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SCPE_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lk_clear_fifo (LK_FIFO *fifo)
|
||||||
|
{
|
||||||
|
fifo->head = 0;
|
||||||
|
fifo->tail = 0;
|
||||||
|
fifo->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lk_cmd ()
|
void lk_cmd ()
|
||||||
{
|
{
|
||||||
int32 i, group, mode;
|
int32 i, group, mode;
|
||||||
|
uint8 data;
|
||||||
|
|
||||||
if (lk_rbuf[0] & 1) { /* peripheral command */
|
lk_get_fifo (&lk_rcvf, &data);
|
||||||
switch (lk_rbuf[0]) {
|
|
||||||
|
if (data & 1) { /* peripheral command */
|
||||||
|
switch (data) {
|
||||||
|
|
||||||
case 0x11:
|
case 0x11:
|
||||||
sim_debug (DBG_CMD, &lk_dev, "LED on\n");
|
sim_debug (DBG_CMD, &lk_dev, "LED on\n");
|
||||||
|
@ -276,7 +312,7 @@ if (lk_rbuf[0] & 1) { /* peripheral command */
|
||||||
|
|
||||||
case 0x8B:
|
case 0x8B:
|
||||||
sim_debug (DBG_CMD, &lk_dev, "resume keyboard transmission\n");
|
sim_debug (DBG_CMD, &lk_dev, "resume keyboard transmission\n");
|
||||||
lk_shptr = lk_stptr = 0;
|
lk_clear_fifo (&lk_sndf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x99:
|
case 0x99:
|
||||||
|
@ -358,26 +394,26 @@ if (lk_rbuf[0] & 1) { /* peripheral command */
|
||||||
lk_reset_mode ();
|
lk_reset_mode ();
|
||||||
lk_repeat = TRUE;
|
lk_repeat = TRUE;
|
||||||
lk_trpti = FALSE;
|
lk_trpti = FALSE;
|
||||||
LK_SEND_CHAR (0xBA); /* Mode change ACK */
|
LK_SEND_CHAR (LK_MODEACK); /* Mode change ACK */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sim_printf ("lk: unknown cmd %02X\n", lk_rbuf[0]);
|
sim_printf ("lk: unknown cmd %02X\n", data);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
group = (lk_rbuf[0] >> 3) & 0xF;
|
|
||||||
if (group < 15) {
|
|
||||||
mode = (lk_rbuf[0] >> 1) & 0x3;
|
|
||||||
sim_debug (DBG_CMD, &lk_dev, "set group %d, mode = %s\n", group, lk_modes[mode]);
|
|
||||||
lk_mode[group] = mode;
|
|
||||||
LK_SEND_CHAR (0xBA); /* Mode change ACK */
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
sim_debug (DBG_CMD, &lk_dev, "set auto-repeat timing\n");
|
else {
|
||||||
|
group = (data >> 3) & 0xF;
|
||||||
|
if (group < 15) {
|
||||||
|
mode = (data >> 1) & 0x3;
|
||||||
|
sim_debug (DBG_CMD, &lk_dev, "set group %d, mode = %s\n", group, lk_modes[mode]);
|
||||||
|
lk_mode[group] = mode;
|
||||||
|
LK_SEND_CHAR (LK_MODEACK); /* Mode change ACK */
|
||||||
}
|
}
|
||||||
lk_rbuf_p = 0;
|
else
|
||||||
|
sim_debug (DBG_CMD, &lk_dev, "set auto-repeat timing\n");
|
||||||
|
}
|
||||||
|
lk_clear_fifo (&lk_rcvf);
|
||||||
}
|
}
|
||||||
|
|
||||||
LK_KEYDATA lk_map_key (int key)
|
LK_KEYDATA lk_map_key (int key)
|
||||||
|
@ -609,7 +645,7 @@ switch (key) {
|
||||||
case SIM_KEY_BACKSLASH:
|
case SIM_KEY_BACKSLASH:
|
||||||
lk_key = LK_KEY_VBAR;
|
lk_key = LK_KEY_VBAR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIM_KEY_LEFT_BACKSLASH:
|
case SIM_KEY_LEFT_BACKSLASH:
|
||||||
case SIM_KEY_COMMA:
|
case SIM_KEY_COMMA:
|
||||||
lk_key = LK_KEY_COMMA;
|
lk_key = LK_KEY_COMMA;
|
||||||
|
@ -626,7 +662,7 @@ switch (key) {
|
||||||
/* case SIM_KEY_PRINT: */
|
/* case SIM_KEY_PRINT: */
|
||||||
/* case SIM_KEY_PAUSE: */
|
/* case SIM_KEY_PAUSE: */
|
||||||
/* case SIM_KEY_ESC: */
|
/* case SIM_KEY_ESC: */
|
||||||
|
|
||||||
case SIM_KEY_BACKSPACE:
|
case SIM_KEY_BACKSPACE:
|
||||||
lk_key = LK_KEY_DELETE;
|
lk_key = LK_KEY_DELETE;
|
||||||
break;
|
break;
|
||||||
|
@ -762,66 +798,61 @@ lk_mode[14] = LK_MODE_AUTODOWN; /* 14 = function keys: f
|
||||||
|
|
||||||
t_stat lk_reset (DEVICE *dptr)
|
t_stat lk_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
lk_rbuf_p = 0;
|
lk_clear_fifo (&lk_sndf);
|
||||||
|
lk_clear_fifo (&lk_rcvf);
|
||||||
lk_keysdown = 0;
|
lk_keysdown = 0;
|
||||||
lk_repeat = TRUE;
|
lk_repeat = TRUE;
|
||||||
lk_trpti = FALSE;
|
lk_trpti = FALSE;
|
||||||
lk_shptr = 0;
|
|
||||||
lk_stptr = 0;
|
|
||||||
lk_reset_mode ();
|
lk_reset_mode ();
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lk_poll (void)
|
void lk_event (SIM_KEY_EVENT *ev)
|
||||||
{
|
{
|
||||||
SIM_KEY_EVENT ev;
|
|
||||||
LK_KEYDATA lk_key;
|
LK_KEYDATA lk_key;
|
||||||
int32 mode;
|
int32 mode;
|
||||||
|
|
||||||
if (vid_poll_kb (&ev) != SCPE_OK)
|
lk_key = lk_map_key (ev->key);
|
||||||
return;
|
|
||||||
|
|
||||||
lk_key = lk_map_key (ev.key);
|
|
||||||
mode = lk_mode[lk_key.group];
|
mode = lk_mode[lk_key.group];
|
||||||
|
|
||||||
sim_debug (DBG_SERIAL, &lk_dev, "lk_poll() Event - Key: (group=%d, code=%02X), Mode: %s - auto-repeat inhibit: %s - state: %s\n", lk_key.group, lk_key.code, lk_modes[mode], lk_trpti ? "TRUE" : "FALSE", lk_states[ev.state]);
|
sim_debug (DBG_SERIAL, &lk_dev, "lk_poll() Event - Key: (group=%d, code=%02X), Mode: %s - auto-repeat inhibit: %s - state: %s\n", lk_key.group, lk_key.code, lk_modes[mode], lk_trpti ? "TRUE" : "FALSE", lk_states[ev->state]);
|
||||||
|
|
||||||
if (lk_trpti && (ev.state != SIM_KEYPRESS_REPEAT))
|
if (lk_trpti && (ev->state != SIM_KEYPRESS_REPEAT))
|
||||||
lk_trpti = FALSE;
|
lk_trpti = FALSE;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
||||||
case LK_MODE_DOWN:
|
case LK_MODE_DOWN:
|
||||||
if (ev.state == SIM_KEYPRESS_DOWN) {
|
if (ev->state == SIM_KEYPRESS_DOWN) {
|
||||||
LK_SEND_CHAR (lk_key.code);
|
LK_SEND_CHAR (lk_key.code);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LK_MODE_AUTODOWN:
|
case LK_MODE_AUTODOWN:
|
||||||
if (ev.state == SIM_KEYPRESS_DOWN) {
|
if (ev->state == SIM_KEYPRESS_DOWN) {
|
||||||
LK_SEND_CHAR (lk_key.code);
|
LK_SEND_CHAR (lk_key.code);
|
||||||
}
|
}
|
||||||
else if ((ev.state == SIM_KEYPRESS_REPEAT) && lk_repeat && !lk_trpti) {
|
else if ((ev->state == SIM_KEYPRESS_REPEAT) && lk_repeat && !lk_trpti) {
|
||||||
LK_SEND_CHAR (0xB4);
|
LK_SEND_CHAR (LK_METRONOME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LK_MODE_DOWNUP:
|
case LK_MODE_DOWNUP:
|
||||||
if (ev.state == SIM_KEYPRESS_DOWN) {
|
if (ev->state == SIM_KEYPRESS_DOWN) {
|
||||||
lk_keysdown++;
|
lk_keysdown++;
|
||||||
LK_SEND_CHAR (lk_key.code);
|
LK_SEND_CHAR (lk_key.code);
|
||||||
}
|
}
|
||||||
else {
|
else if (ev->state == SIM_KEYPRESS_UP) {
|
||||||
lk_keysdown--;
|
lk_keysdown--;
|
||||||
if (lk_keysdown > 0) {
|
if (lk_keysdown > 0) {
|
||||||
LK_SEND_CHAR (lk_key.code);
|
LK_SEND_CHAR (lk_key.code);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LK_SEND_CHAR (0xB3); /* LK_ALLUP */
|
LK_SEND_CHAR (LK_ALLUP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *lk_description (DEVICE *dptr)
|
const char *lk_description (DEVICE *dptr)
|
||||||
|
|
152
VAX/vax_lk.h
Normal file
152
VAX/vax_lk.h
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/* vax_lk.h: DEC Keyboard (LK201)
|
||||||
|
|
||||||
|
Copyright (c) 2017, Matt Burke
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the author shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the author.
|
||||||
|
|
||||||
|
lk LK201 keyboard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VAX_LK_H_
|
||||||
|
#define _VAX_LK_H_
|
||||||
|
|
||||||
|
#include "vax_defs.h"
|
||||||
|
#include "sim_video.h"
|
||||||
|
|
||||||
|
/* standard key codes */
|
||||||
|
|
||||||
|
#define LK_UNKNOWN 0x00
|
||||||
|
|
||||||
|
#define LK_TR_0 0xEF
|
||||||
|
#define LK_TR_1 0xC0
|
||||||
|
#define LK_TR_2 0xC5
|
||||||
|
#define LK_TR_3 0xCB
|
||||||
|
#define LK_TR_4 0xD0
|
||||||
|
#define LK_TR_5 0xD6
|
||||||
|
#define LK_TR_6 0xDB
|
||||||
|
#define LK_TR_7 0xE0
|
||||||
|
#define LK_TR_8 0xE5
|
||||||
|
#define LK_TR_9 0xEA
|
||||||
|
#define LK_A 0xC2
|
||||||
|
#define LK_B 0xD9
|
||||||
|
#define LK_C 0xCE
|
||||||
|
#define LK_D 0xCD
|
||||||
|
#define LK_E 0xCC
|
||||||
|
#define LK_F 0xD2
|
||||||
|
#define LK_G 0xD8
|
||||||
|
#define LK_H 0xDD
|
||||||
|
#define LK_I 0xE6
|
||||||
|
#define LK_J 0xE2
|
||||||
|
#define LK_K 0xE7
|
||||||
|
#define LK_L 0xEC
|
||||||
|
#define LK_M 0xE3
|
||||||
|
#define LK_N 0xDE
|
||||||
|
#define LK_O 0xEB
|
||||||
|
#define LK_P 0xF0
|
||||||
|
#define LK_Q 0xC1
|
||||||
|
#define LK_R 0xD1
|
||||||
|
#define LK_S 0xC7
|
||||||
|
#define LK_T 0xD7
|
||||||
|
#define LK_U 0xE1
|
||||||
|
#define LK_V 0xD3
|
||||||
|
#define LK_W 0xC6
|
||||||
|
#define LK_X 0xC8
|
||||||
|
#define LK_Y 0xDC
|
||||||
|
#define LK_Z 0xC3
|
||||||
|
#define LK_SPACE 0xD4
|
||||||
|
#define LK_SEMICOLON 0xF2
|
||||||
|
#define LK_PLUS 0xF5
|
||||||
|
#define LK_COMMA 0xE8
|
||||||
|
#define LK_UBAR 0xF9
|
||||||
|
#define LK_PERIOD 0xED
|
||||||
|
#define LK_QMARK 0xF3
|
||||||
|
#define LK_QUOTE 0xFB
|
||||||
|
#define LK_LBRACE 0xFA
|
||||||
|
#define LK_RBRACE 0xF6
|
||||||
|
#define LK_VBAR 0xF7
|
||||||
|
#define LK_TILDE 0xBF
|
||||||
|
#define LK_KP_0 0x92
|
||||||
|
#define LK_KP_1 0x96
|
||||||
|
#define LK_KP_2 0x97
|
||||||
|
#define LK_KP_3 0x98
|
||||||
|
#define LK_KP_4 0x99
|
||||||
|
#define LK_KP_5 0x9A
|
||||||
|
#define LK_KP_6 0x9B
|
||||||
|
#define LK_KP_7 0x9D
|
||||||
|
#define LK_KP_8 0x9E
|
||||||
|
#define LK_KP_9 0x9F
|
||||||
|
#define LK_KP_PF1 0xA1
|
||||||
|
#define LK_KP_PF2 0xA2
|
||||||
|
#define LK_KP_PF3 0xA3
|
||||||
|
#define LK_KP_PF4 0xA4
|
||||||
|
#define LK_KP_HYPHEN 0xA0
|
||||||
|
#define LK_KP_COMMA 0x9C
|
||||||
|
#define LK_KP_PERIOD 0x94
|
||||||
|
#define LK_KP_ENTER 0x95
|
||||||
|
#define LK_DELETE 0xBC
|
||||||
|
#define LK_TAB 0xBE
|
||||||
|
#define LK_RETURN 0xBD
|
||||||
|
#define LK_META 0xB1
|
||||||
|
#define LK_LOCK 0xB0
|
||||||
|
#define LK_SHIFT 0xAE
|
||||||
|
#define LK_CTRL 0xAF
|
||||||
|
#define LK_LEFT 0xA7
|
||||||
|
#define LK_RIGHT 0xA8
|
||||||
|
#define LK_UP 0xAA
|
||||||
|
#define LK_DOWN 0xA9
|
||||||
|
#define LK_REMOVE 0x8C
|
||||||
|
#define LK_NEXT_SCREEN 0x8F
|
||||||
|
#define LK_PREV_SCREEN 0x8E
|
||||||
|
#define LK_INSERT_HERE 0x8B
|
||||||
|
#define LK_FIND 0x8A
|
||||||
|
#define LK_SELECT 0x8D
|
||||||
|
#define LK_F1 0x56
|
||||||
|
#define LK_F2 0x57
|
||||||
|
#define LK_F3 0x58
|
||||||
|
#define LK_F4 0x59
|
||||||
|
#define LK_F5 0x5A
|
||||||
|
#define LK_F6 0x64
|
||||||
|
#define LK_F7 0x65
|
||||||
|
#define LK_F8 0x66
|
||||||
|
#define LK_F9 0x67
|
||||||
|
#define LK_F10 0x68
|
||||||
|
#define LK_F11 0x71
|
||||||
|
#define LK_F12 0x72
|
||||||
|
|
||||||
|
/* special codes */
|
||||||
|
|
||||||
|
#define LK_ALLUP 0xB3 /* all up */
|
||||||
|
#define LK_METRONOME 0xB4 /* metronome code */
|
||||||
|
#define LK_OUTERR 0xB5 /* output error */
|
||||||
|
#define LK_INERR 0xB6 /* input error */
|
||||||
|
#define LK_LOCKACK 0xB7 /* kbd locked ack */
|
||||||
|
#define LK_TESTACK 0xB8 /* test mode ack */
|
||||||
|
#define LK_PREDOWN 0xB9 /* prefix to keys down */
|
||||||
|
#define LK_MODEACK 0xBA /* mode change ack */
|
||||||
|
|
||||||
|
/* interface functions */
|
||||||
|
|
||||||
|
t_stat lk_wr (uint8 c);
|
||||||
|
t_stat lk_rd (uint8 *c);
|
||||||
|
void lk_event (SIM_KEY_EVENT *ev);
|
||||||
|
|
||||||
|
#endif
|
65
VAX/vax_vc.c
65
VAX/vax_vc.c
|
@ -29,6 +29,10 @@
|
||||||
06-Nov-2013 MB Increased the speed of v-sync interrupts, which
|
06-Nov-2013 MB Increased the speed of v-sync interrupts, which
|
||||||
was too slow for some O/S drivers.
|
was too slow for some O/S drivers.
|
||||||
11-Jun-2013 MB First version
|
11-Jun-2013 MB First version
|
||||||
|
|
||||||
|
Related documents:
|
||||||
|
|
||||||
|
AZ-GLFAB-MN - VAXstation II Technical Manual, BA23 Enclosure (Appendix C)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(VAX_620)
|
#if !defined(VAX_620)
|
||||||
|
@ -36,6 +40,8 @@
|
||||||
#include "vax_defs.h"
|
#include "vax_defs.h"
|
||||||
#include "sim_video.h"
|
#include "sim_video.h"
|
||||||
#include "vax_2681.h"
|
#include "vax_2681.h"
|
||||||
|
#include "vax_lk.h"
|
||||||
|
#include "vax_vs.h"
|
||||||
|
|
||||||
/* CSR - control/status register */
|
/* CSR - control/status register */
|
||||||
|
|
||||||
|
@ -195,11 +201,6 @@ BITFIELD vc_ic_mode_bits[] = {
|
||||||
|
|
||||||
extern int32 tmxr_poll; /* calibrated delay */
|
extern int32 tmxr_poll; /* calibrated delay */
|
||||||
|
|
||||||
extern t_stat lk_wr (uint8 c);
|
|
||||||
extern t_stat lk_rd (uint8 *c);
|
|
||||||
extern t_stat vs_wr (uint8 c);
|
|
||||||
extern t_stat vs_rd (uint8 *c);
|
|
||||||
|
|
||||||
struct vc_int_t {
|
struct vc_int_t {
|
||||||
uint32 ptr;
|
uint32 ptr;
|
||||||
uint32 vec[8]; /* Interrupt vectors */
|
uint32 vec[8]; /* Interrupt vectors */
|
||||||
|
@ -875,6 +876,8 @@ return 0; /* no intr req */
|
||||||
|
|
||||||
t_stat vc_svc (UNIT *uptr)
|
t_stat vc_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
SIM_MOUSE_EVENT mev;
|
||||||
|
SIM_KEY_EVENT kev;
|
||||||
t_bool updated = FALSE; /* flag for refresh */
|
t_bool updated = FALSE; /* flag for refresh */
|
||||||
uint32 lines;
|
uint32 lines;
|
||||||
uint32 ln, col, off;
|
uint32 ln, col, off;
|
||||||
|
@ -914,31 +917,35 @@ vc_cur_v = CUR_V;
|
||||||
vc_cur_f = CUR_F;
|
vc_cur_f = CUR_F;
|
||||||
vc_cur_new_data = FALSE;
|
vc_cur_new_data = FALSE;
|
||||||
|
|
||||||
xpos = vc_mpos & 0xFF; /* get current mouse position */
|
if (vid_poll_kb (&kev) == SCPE_OK) /* poll keyboard */
|
||||||
ypos = (vc_mpos >> 8) & 0xFF;
|
lk_event (&kev); /* push event */
|
||||||
dx = vid_mouse_xrel; /* get relative movement */
|
if (vid_poll_mouse (&mev) == SCPE_OK) { /* poll mouse */
|
||||||
dy = -vid_mouse_yrel;
|
xpos = vc_mpos & 0xFF; /* get current mouse position */
|
||||||
if (dx > VC_MOVE_MAX) /* limit movement */
|
ypos = (vc_mpos >> 8) & 0xFF;
|
||||||
dx = VC_MOVE_MAX;
|
dx = mev.x_rel; /* get relative movement */
|
||||||
else if (dx < -VC_MOVE_MAX)
|
dy = -mev.y_rel;
|
||||||
dx = -VC_MOVE_MAX;
|
if (dx > VC_MOVE_MAX) /* limit movement */
|
||||||
if (dy > VC_MOVE_MAX)
|
dx = VC_MOVE_MAX;
|
||||||
dy = VC_MOVE_MAX;
|
else if (dx < -VC_MOVE_MAX)
|
||||||
else if (dy < -VC_MOVE_MAX)
|
dx = -VC_MOVE_MAX;
|
||||||
dy = -VC_MOVE_MAX;
|
if (dy > VC_MOVE_MAX)
|
||||||
xpos += dx; /* add to counters */
|
dy = VC_MOVE_MAX;
|
||||||
ypos += dy;
|
else if (dy < -VC_MOVE_MAX)
|
||||||
vc_mpos = ((ypos & 0xFF) << 8) | (xpos & 0xFF); /* update register */
|
dy = -VC_MOVE_MAX;
|
||||||
vid_mouse_xrel -= dx; /* reset counters for next poll */
|
xpos += dx; /* add to counters */
|
||||||
vid_mouse_yrel += dy;
|
ypos += dy;
|
||||||
|
vc_mpos = ((ypos & 0xFF) << 8) | (xpos & 0xFF); /* update register */
|
||||||
|
|
||||||
vc_csr |= (CSR_MSA | CSR_MSB | CSR_MSC); /* reset button states */
|
vc_csr |= (CSR_MSA | CSR_MSB | CSR_MSC); /* reset button states */
|
||||||
if (vid_mouse_b3) /* set new button states */
|
if (mev.b3_state) /* set new button states */
|
||||||
vc_csr &= ~CSR_MSA;
|
vc_csr &= ~CSR_MSA;
|
||||||
if (vid_mouse_b2)
|
if (mev.b2_state)
|
||||||
vc_csr &= ~CSR_MSB;
|
vc_csr &= ~CSR_MSB;
|
||||||
if (vid_mouse_b1)
|
if (mev.b1_state)
|
||||||
vc_csr &= ~CSR_MSC;
|
vc_csr &= ~CSR_MSC;
|
||||||
|
|
||||||
|
vs_event (&mev); /* push event */
|
||||||
|
}
|
||||||
|
|
||||||
lines = 0;
|
lines = 0;
|
||||||
for (ln = 0; ln < VC_YSIZE; ln++) {
|
for (ln = 0; ln < VC_YSIZE; ln++) {
|
||||||
|
|
220
VAX/vax_vs.c
220
VAX/vax_vs.c
|
@ -1,6 +1,6 @@
|
||||||
/* vax_vs.c: DEC Mouse/Tablet (VSXXX)
|
/* vax_vs.c: DEC Mouse/Tablet (VSXXX)
|
||||||
|
|
||||||
Copyright (c) 2011-2013, Matt Burke
|
Copyright (c) 2013-2017, Matt Burke
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -27,58 +27,52 @@
|
||||||
|
|
||||||
09-Aug-2013 MB Added definitions for self test report
|
09-Aug-2013 MB Added definitions for self test report
|
||||||
11-Jun-2013 MB First version
|
11-Jun-2013 MB First version
|
||||||
|
|
||||||
|
Related documents:
|
||||||
|
|
||||||
|
EK-104AA-TM-001 - VCB02 Technical Manual (chapter C.6)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(VAX_620)
|
#if !defined(VAX_620)
|
||||||
|
|
||||||
#include "vax_defs.h"
|
#include "vax_vs.h"
|
||||||
#include "sim_video.h"
|
|
||||||
|
|
||||||
#define VSXXX_IDLE 0
|
|
||||||
#define VSXXX_RECV 1
|
|
||||||
#define VSXXX_SEND 2
|
|
||||||
#define VSXXX_TEST 3
|
|
||||||
|
|
||||||
#define VSXXX_PROMPT 0
|
#define VSXXX_PROMPT 0
|
||||||
#define VSXXX_INC 1
|
#define VSXXX_INC 1
|
||||||
|
|
||||||
#define VSXXX_REV 0 /* hardware revision */
|
#define VSXXX_REV 0 /* hardware revision */
|
||||||
|
|
||||||
/* Report bit definitions */
|
|
||||||
|
|
||||||
#define RPT_SYNC 0x80 /* synchronise */
|
|
||||||
#define RPT_TABP 0x40 /* tablet position */
|
|
||||||
#define RPT_TEST 0x20 /* self test */
|
|
||||||
#define RPT_TAB 0x4 /* tablet device */
|
|
||||||
#define RPT_MOU 0x2 /* mouse device */
|
|
||||||
#define RPT_V_MFR 4 /* manufacturer location ID */
|
|
||||||
#define RPT_REV 0xF /* revision number */
|
|
||||||
#define RPT_BC 0x7 /* button code */
|
|
||||||
#define RPT_EC 0x7F /* error code */
|
|
||||||
|
|
||||||
/* Debugging Bitmaps */
|
/* Debugging Bitmaps */
|
||||||
|
|
||||||
#define DBG_SERIAL 0x0001 /* serial port data */
|
#define DBG_SERIAL 0x0001 /* serial port data */
|
||||||
#define DBG_CMD 0x0002 /* commands */
|
#define DBG_CMD 0x0002 /* commands */
|
||||||
|
|
||||||
int32 vs_state = VSXXX_IDLE;
|
#define VS_BUF_LEN 100
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32 head;
|
||||||
|
int32 tail;
|
||||||
|
int32 count;
|
||||||
|
uint8 buf[VS_BUF_LEN];
|
||||||
|
} VS_FIFO;
|
||||||
|
|
||||||
int32 vs_mode = VSXXX_PROMPT;
|
int32 vs_mode = VSXXX_PROMPT;
|
||||||
int32 vs_bptr = 0;
|
|
||||||
int32 vs_datalen = 0;
|
|
||||||
int32 vs_x = 0; /* X-axis motion */
|
int32 vs_x = 0; /* X-axis motion */
|
||||||
int32 vs_y = 0; /* Y-axis motion */
|
int32 vs_y = 0; /* Y-axis motion */
|
||||||
t_bool vs_l = 0; /* Left button state */
|
t_bool vs_l = FALSE; /* Left button state */
|
||||||
t_bool vs_m = 0; /* Middle button state */
|
t_bool vs_m = FALSE; /* Middle button state */
|
||||||
t_bool vs_r = 0; /* Right button state */
|
t_bool vs_r = FALSE; /* Right button state */
|
||||||
uint8 vs_buf[10];
|
VS_FIFO vs_sndf; /* send FIFO */
|
||||||
|
|
||||||
t_stat vs_wr (uint8 c);
|
t_stat vs_wr (uint8 c);
|
||||||
t_stat vs_rd (uint8 *c);
|
t_stat vs_rd (uint8 *c);
|
||||||
t_stat vs_reset (DEVICE *dptr);
|
t_stat vs_reset (DEVICE *dptr);
|
||||||
void vs_cmd (int32 c);
|
void vs_cmd (int32 c);
|
||||||
void vs_sendupd (void);
|
void vs_sendupd (void);
|
||||||
void vs_poll (void);
|
|
||||||
const char *vs_description (DEVICE *dptr);
|
const char *vs_description (DEVICE *dptr);
|
||||||
|
t_stat vs_put_fifo (VS_FIFO *fifo, uint8 data);
|
||||||
|
t_stat vs_get_fifo (VS_FIFO *fifo, uint8 *data);
|
||||||
|
void vs_clear_fifo (VS_FIFO *fifo);
|
||||||
|
|
||||||
|
|
||||||
/* VS data structures
|
/* VS data structures
|
||||||
|
@ -112,133 +106,155 @@ DEVICE vs_dev = {
|
||||||
NULL, NULL, &vs_reset,
|
NULL, NULL, &vs_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
NULL, DEV_DIS | DEV_DEBUG, 0,
|
NULL, DEV_DIS | DEV_DEBUG, 0,
|
||||||
vs_debug, NULL, NULL, NULL, NULL, NULL,
|
vs_debug, NULL, NULL, NULL, NULL, NULL,
|
||||||
&vs_description
|
&vs_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
t_stat vs_wr (uint8 c)
|
t_stat vs_wr (uint8 c)
|
||||||
{
|
{
|
||||||
if (vs_state != VSXXX_TEST) {
|
vs_clear_fifo (&vs_sndf);
|
||||||
vs_bptr = 0;
|
vs_cmd (c);
|
||||||
vs_state = VSXXX_IDLE;
|
|
||||||
vs_datalen = 0;
|
|
||||||
vs_cmd (c);
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat vs_rd (uint8 *c)
|
t_stat vs_rd (uint8 *c)
|
||||||
{
|
{
|
||||||
if (vs_state == VSXXX_IDLE)
|
t_stat r;
|
||||||
vs_poll ();
|
|
||||||
switch (vs_state) {
|
|
||||||
|
|
||||||
case VSXXX_IDLE:
|
r = vs_get_fifo (&vs_sndf, c);
|
||||||
*c = 0;
|
if (r == SCPE_OK)
|
||||||
return SCPE_EOF;
|
sim_debug (DBG_SERIAL, &vs_dev, "mouse -> vax: 0x%02X\n", *c);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
case VSXXX_SEND:
|
t_stat vs_put_fifo (VS_FIFO *fifo, uint8 data)
|
||||||
case VSXXX_TEST:
|
{
|
||||||
*c = vs_buf[vs_bptr++];
|
if (fifo->count < VS_BUF_LEN) {
|
||||||
sim_debug (DBG_SERIAL, &vs_dev, "mouse -> vax: 0x%02X\n", *c);
|
fifo->buf[fifo->head++] = data;
|
||||||
if (vs_bptr == vs_datalen) {
|
if (fifo->head == VS_BUF_LEN)
|
||||||
vs_state = VSXXX_IDLE;
|
fifo->head = 0;
|
||||||
}
|
fifo->count++;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
return SCPE_EOF;
|
else
|
||||||
|
return SCPE_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat vs_get_fifo (VS_FIFO *fifo, uint8 *data)
|
||||||
|
{
|
||||||
|
if (fifo->count > 0) {
|
||||||
|
*data = fifo->buf[fifo->tail++];
|
||||||
|
if (fifo->tail == VS_BUF_LEN)
|
||||||
|
fifo->tail = 0;
|
||||||
|
fifo->count--;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SCPE_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vs_clear_fifo (VS_FIFO *fifo)
|
||||||
|
{
|
||||||
|
fifo->head = 0;
|
||||||
|
fifo->tail = 0;
|
||||||
|
fifo->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vs_cmd (int32 c)
|
void vs_cmd (int32 c)
|
||||||
{
|
{
|
||||||
|
uint8 data;
|
||||||
|
|
||||||
sim_debug (DBG_SERIAL, &vs_dev, "vax -> mouse: %c\n", c);
|
sim_debug (DBG_SERIAL, &vs_dev, "vax -> mouse: %c\n", c);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
case 0x52: /* R */
|
case VS_INCR: /* R */
|
||||||
sim_debug (DBG_CMD, &vs_dev, "set mode incremental(%c)\n", c);
|
sim_debug (DBG_CMD, &vs_dev, "set mode incremental(%c)\n", c);
|
||||||
vs_mode = VSXXX_INC;
|
vs_mode = VSXXX_INC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x44: /* D */
|
case VS_PROMPT: /* D */
|
||||||
sim_debug (DBG_CMD, &vs_dev, "set mode prompt(%c)\n", c);
|
sim_debug (DBG_CMD, &vs_dev, "set mode prompt(%c)\n", c);
|
||||||
vs_mode = VSXXX_PROMPT;
|
vs_mode = VSXXX_PROMPT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x50: /* P */
|
case VS_POLL: /* P */
|
||||||
sim_debug (DBG_CMD, &vs_dev, "poll(%c)\n", c);
|
sim_debug (DBG_CMD, &vs_dev, "poll(%c)\n", c);
|
||||||
vs_mode = VSXXX_PROMPT;
|
vs_mode = VSXXX_PROMPT;
|
||||||
vs_sendupd ();
|
vs_sendupd ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x54: /* T */
|
case VS_TEST: /* T */
|
||||||
sim_debug (DBG_CMD, &vs_dev, "test(%c)\n", c);
|
sim_debug (DBG_CMD, &vs_dev, "test(%c)\n", c);
|
||||||
vs_reset (&vs_dev);
|
vs_reset (&vs_dev);
|
||||||
vs_state = VSXXX_TEST; /* send self test report */
|
data = RPT_TEST | RPT_SYNC | (VSXXX_REV & RPT_REV);
|
||||||
vs_buf[0] = RPT_TEST | RPT_SYNC | (VSXXX_REV & RPT_REV);
|
vs_put_fifo (&vs_sndf, data);
|
||||||
vs_buf[1] = (1 << RPT_V_MFR) | RPT_MOU; /* device type, build location */
|
data = (1 << RPT_V_MFR) | RPT_MOU; /* device type, build location */
|
||||||
vs_buf[2] = 0; /* error code <6:0> (0 = OK) */
|
vs_put_fifo (&vs_sndf, data);
|
||||||
vs_buf[3] = 0; /* button code <2:0> (0 = OK) */
|
data = 0; /* error code <6:0> (0 = OK) */
|
||||||
vs_bptr = 0;
|
vs_put_fifo (&vs_sndf, data);
|
||||||
vs_state = VSXXX_SEND;
|
data = 0; /* button code <2:0> (0 = OK) */
|
||||||
vs_datalen = 4;
|
vs_put_fifo (&vs_sndf, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat vs_reset (DEVICE *dptr)
|
t_stat vs_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
vs_bptr = 0;
|
vs_x = 0;
|
||||||
vs_state = VSXXX_IDLE;
|
vs_y = 0;
|
||||||
vs_datalen = 0;
|
vs_l = FALSE;
|
||||||
|
vs_m = FALSE;
|
||||||
|
vs_r = FALSE;
|
||||||
|
vs_clear_fifo (&vs_sndf);
|
||||||
vs_mode = VSXXX_PROMPT;
|
vs_mode = VSXXX_PROMPT;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vs_sendupd (void)
|
void vs_sendupd (void)
|
||||||
{
|
{
|
||||||
vs_buf[0] = RPT_SYNC;
|
uint8 b0, b1, b2;
|
||||||
vs_buf[0] |= (((vs_x > 0) ? 1 : 0) << 4); /* sign bits */
|
|
||||||
vs_buf[0] |= (((vs_y >= 0) ? 0 : 1) << 3);
|
do {
|
||||||
vs_buf[0] |= (((vs_l) ? 1 : 0) << 2); /* button states */
|
if (vs_sndf.count == VS_BUF_LEN) /* fifo full? */
|
||||||
vs_buf[0] |= (((vs_m) ? 1 : 0) << 1);
|
return;
|
||||||
vs_buf[0] |= ((vs_r) ? 1 : 0);
|
b0 = RPT_SYNC;
|
||||||
vs_buf[1] = (abs(vs_x) > 0x3F) ? 0x3F : abs(vs_x); /* motion (limited to 63 pixels in any direction) */
|
b0 |= (((vs_x > 0) ? 1 : 0) << 4); /* sign bits */
|
||||||
if (vs_x > 0)
|
b0 |= (((vs_y >= 0) ? 0 : 1) << 3);
|
||||||
vs_x -= vs_buf[1];
|
b0 |= (((vs_l) ? 1 : 0) << 2); /* button states */
|
||||||
else
|
b0 |= (((vs_m) ? 1 : 0) << 1);
|
||||||
vs_x += vs_buf[1];
|
b0 |= ((vs_r) ? 1 : 0);
|
||||||
vs_buf[2] = (abs(vs_y) > 0x3F) ? 0x3F : abs(vs_y);
|
vs_put_fifo (&vs_sndf, b0);
|
||||||
if (vs_y > 0)
|
b1 = (abs(vs_x) > 0x3F) ? 0x3F : abs(vs_x); /* motion (limited to 63 pixels in any direction) */
|
||||||
vs_y -= vs_buf[2];
|
if (vs_x > 0)
|
||||||
else
|
vs_x -= b1;
|
||||||
vs_y += vs_buf[2];
|
else
|
||||||
vs_bptr = 0;
|
vs_x += b1;
|
||||||
vs_state = VSXXX_SEND;
|
vs_put_fifo (&vs_sndf, b1);
|
||||||
vs_datalen = 3;
|
b2 = (abs(vs_y) > 0x3F) ? 0x3F : abs(vs_y);
|
||||||
sim_debug (DBG_SERIAL, &vs_dev, "mouse motion queued for delivery: Motion:(%s%d,%s%d), Buttons:(%s,%s,%s) Remnant skipped:(%d,%d)\n",
|
if (vs_y > 0)
|
||||||
(vs_buf[0]&0x10) ? "s" : "", vs_buf[1], (vs_buf[0]&0x08) ? "s" : "", vs_buf[2], (vs_buf[0]&0x04) ? "L" : "l", (vs_buf[0]&0x02) ? "M" : "m", (vs_buf[0]&0x01) ? "R" : "r", vs_x, vs_y);
|
vs_y -= b2;
|
||||||
|
else
|
||||||
|
vs_y += b2;
|
||||||
|
vs_put_fifo (&vs_sndf, b2);
|
||||||
|
sim_debug (DBG_SERIAL, &vs_dev, "mouse motion queued for delivery: Motion:(%s%d,%s%d), Buttons:(%s,%s,%s) Remnant skipped:(%d,%d)\n",
|
||||||
|
(b0 & 0x10) ? "s" : "", b1, (b0 & 0x08) ? "s" : "", b2, (b0 & 0x04) ? "L" : "l", (b0 & 0x02) ? "M" : "m", (b0 & 0x01) ? "R" : "r", vs_x, vs_y);
|
||||||
|
} while ((vs_x != 0) && (vs_y != 0));
|
||||||
vs_x = vs_y = 0;
|
vs_x = vs_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vs_poll (void)
|
void vs_event (SIM_MOUSE_EVENT *ev)
|
||||||
{
|
{
|
||||||
SIM_MOUSE_EVENT ev;
|
if ((ev->x_rel == 0) && (ev->y_rel == 0) &&
|
||||||
|
(vs_l == ev->b1_state) && (vs_m == ev->b2_state) && (vs_r == ev->b3_state))
|
||||||
if (vid_poll_mouse (&ev) != SCPE_OK)
|
|
||||||
return;
|
return;
|
||||||
if (vs_state == VSXXX_IDLE) {
|
vs_x += ev->x_rel;
|
||||||
if ((ev.x_rel == 0) && (ev.y_rel == 0) &&
|
vs_y += ev->y_rel;
|
||||||
(vs_l == ev.b1_state) && (vs_m == ev.b2_state) && (vs_r == ev.b3_state))
|
vs_l = ev->b1_state;
|
||||||
return;
|
vs_m = ev->b2_state;
|
||||||
vs_x = ev.x_rel;
|
vs_r = ev->b3_state;
|
||||||
vs_y = ev.y_rel;
|
if (vs_mode == VSXXX_INC)
|
||||||
vs_l = ev.b1_state;
|
vs_sendupd ();
|
||||||
vs_m = ev.b2_state;
|
|
||||||
vs_r = ev.b3_state;
|
|
||||||
if (vs_mode == VSXXX_INC)
|
|
||||||
vs_sendupd ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *vs_description (DEVICE *dptr)
|
const char *vs_description (DEVICE *dptr)
|
||||||
|
|
58
VAX/vax_vs.h
Normal file
58
VAX/vax_vs.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/* vax_vs.h: DEC Mouse/Tablet (VSXXX)
|
||||||
|
|
||||||
|
Copyright (c) 2017, Matt Burke
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the author shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the author.
|
||||||
|
|
||||||
|
vs VSXXX-nn pointing device
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VAX_VS_H_
|
||||||
|
#define _VAX_VS_H_
|
||||||
|
|
||||||
|
#include "vax_defs.h"
|
||||||
|
#include "sim_video.h"
|
||||||
|
|
||||||
|
/* command definitions */
|
||||||
|
|
||||||
|
#define VS_INCR 0x52 /* set mode incremental */
|
||||||
|
#define VS_PROMPT 0x44 /* set mode prompt */
|
||||||
|
#define VS_POLL 0x50 /* poll */
|
||||||
|
#define VS_TEST 0x54 /* test */
|
||||||
|
|
||||||
|
/* Report bit definitions */
|
||||||
|
|
||||||
|
#define RPT_SYNC 0x80 /* synchronise */
|
||||||
|
#define RPT_TABP 0x40 /* tablet position */
|
||||||
|
#define RPT_TEST 0x20 /* self test */
|
||||||
|
#define RPT_TAB 0x4 /* tablet device */
|
||||||
|
#define RPT_MOU 0x2 /* mouse device */
|
||||||
|
#define RPT_V_MFR 4 /* manufacturer location ID */
|
||||||
|
#define RPT_REV 0xF /* revision number */
|
||||||
|
#define RPT_BC 0x7 /* button code */
|
||||||
|
#define RPT_EC 0x7F /* error code */
|
||||||
|
|
||||||
|
t_stat vs_wr (uint8 c);
|
||||||
|
t_stat vs_rd (uint8 *c);
|
||||||
|
void vs_event (SIM_MOUSE_EVENT *ev);
|
||||||
|
|
||||||
|
#endif
|
|
@ -640,10 +640,18 @@
|
||||||
RelativePath="..\VAX\vax_defs.h"
|
RelativePath="..\VAX\vax_defs.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\VAX\vax_lk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\VAX\vax_mmu.h"
|
RelativePath="..\VAX\vax_mmu.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\VAX\vax_vs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
|
|
|
@ -640,10 +640,18 @@
|
||||||
RelativePath="..\VAX\vax_defs.h"
|
RelativePath="..\VAX\vax_defs.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\VAX\vax_lk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\VAX\vax_mmu.h"
|
RelativePath="..\VAX\vax_mmu.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\VAX\vax_vs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
|
|
|
@ -636,10 +636,18 @@
|
||||||
RelativePath="..\VAX\vax_defs.h"
|
RelativePath="..\VAX\vax_defs.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\VAX\vax_lk.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\VAX\vax_mmu.h"
|
RelativePath="..\VAX\vax_mmu.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\VAX\vax_vs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\VAX\vaxmod_defs.h"
|
RelativePath="..\VAX\vaxmod_defs.h"
|
||||||
>
|
>
|
||||||
|
|
24
sim_video.c
24
sim_video.c
|
@ -31,8 +31,6 @@
|
||||||
#include "scp.h"
|
#include "scp.h"
|
||||||
|
|
||||||
t_bool vid_active = FALSE;
|
t_bool vid_active = FALSE;
|
||||||
int32 vid_mouse_xrel;
|
|
||||||
int32 vid_mouse_yrel;
|
|
||||||
int32 vid_cursor_x;
|
int32 vid_cursor_x;
|
||||||
int32 vid_cursor_y;
|
int32 vid_cursor_y;
|
||||||
t_bool vid_mouse_b1 = FALSE;
|
t_bool vid_mouse_b1 = FALSE;
|
||||||
|
@ -523,8 +521,6 @@ if (!vid_active) {
|
||||||
vid_height = height;
|
vid_height = height;
|
||||||
vid_mouse_captured = FALSE;
|
vid_mouse_captured = FALSE;
|
||||||
vid_cursor_visible = (vid_flags & SIM_VID_INPUTCAPTURED);
|
vid_cursor_visible = (vid_flags & SIM_VID_INPUTCAPTURED);
|
||||||
vid_mouse_xrel = 0;
|
|
||||||
vid_mouse_yrel = 0;
|
|
||||||
|
|
||||||
vid_key_events.head = 0;
|
vid_key_events.head = 0;
|
||||||
vid_key_events.tail = 0;
|
vid_key_events.tail = 0;
|
||||||
|
@ -717,6 +713,9 @@ void vid_set_cursor_position (int32 x, int32 y)
|
||||||
int32 x_delta = vid_cursor_x - x;
|
int32 x_delta = vid_cursor_x - x;
|
||||||
int32 y_delta = vid_cursor_y - y;
|
int32 y_delta = vid_cursor_y - y;
|
||||||
|
|
||||||
|
if (vid_flags & SIM_VID_INPUTCAPTURED)
|
||||||
|
return;
|
||||||
|
|
||||||
if ((x_delta) || (y_delta)) {
|
if ((x_delta) || (y_delta)) {
|
||||||
sim_debug (SIM_VID_DBG_CURSOR, vid_dev, "vid_set_cursor_position(%d, %d) - Cursor position changed\n", x, y);
|
sim_debug (SIM_VID_DBG_CURSOR, vid_dev, "vid_set_cursor_position(%d, %d) - Cursor position changed\n", x, y);
|
||||||
/* Any queued mouse motion events need to have their relative
|
/* Any queued mouse motion events need to have their relative
|
||||||
|
@ -728,12 +727,8 @@ if ((x_delta) || (y_delta)) {
|
||||||
for (i=0; i<vid_mouse_events.count; i++) {
|
for (i=0; i<vid_mouse_events.count; i++) {
|
||||||
ev = &vid_mouse_events.events[(vid_mouse_events.head + i)%MAX_EVENTS];
|
ev = &vid_mouse_events.events[(vid_mouse_events.head + i)%MAX_EVENTS];
|
||||||
sim_debug (SIM_VID_DBG_CURSOR, vid_dev, "Pending Mouse Motion Event Adjusted from: (%d, %d) to (%d, %d)\n", ev->x_rel, ev->y_rel, ev->x_rel + x_delta, ev->y_rel + y_delta);
|
sim_debug (SIM_VID_DBG_CURSOR, vid_dev, "Pending Mouse Motion Event Adjusted from: (%d, %d) to (%d, %d)\n", ev->x_rel, ev->y_rel, ev->x_rel + x_delta, ev->y_rel + y_delta);
|
||||||
vid_mouse_xrel -= ev->x_rel; /* remove previously accumulated relative position */
|
|
||||||
vid_mouse_yrel -= ev->y_rel;
|
|
||||||
ev->x_rel += x_delta;
|
ev->x_rel += x_delta;
|
||||||
ev->y_rel += y_delta;
|
ev->y_rel += y_delta;
|
||||||
vid_mouse_xrel += ev->x_rel; /* update cumulative x & y rel */
|
|
||||||
vid_mouse_yrel += ev->y_rel;
|
|
||||||
}
|
}
|
||||||
if (SDL_SemPost (vid_mouse_events.sem))
|
if (SDL_SemPost (vid_mouse_events.sem))
|
||||||
sim_printf ("%s: vid_set_cursor_position(): SDL_SemPost error: %s\n", vid_dev ? sim_dname(vid_dev) : "Video Device", SDL_GetError());
|
sim_printf ("%s: vid_set_cursor_position(): SDL_SemPost error: %s\n", vid_dev ? sim_dname(vid_dev) : "Video Device", SDL_GetError());
|
||||||
|
@ -1250,13 +1245,11 @@ if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
||||||
event->xrel = (event->x - vid_cursor_x);
|
event->xrel = (event->x - vid_cursor_x);
|
||||||
event->yrel = (event->y - vid_cursor_y);
|
event->yrel = (event->y - vid_cursor_y);
|
||||||
}
|
}
|
||||||
vid_mouse_xrel += event->xrel; /* update cumulative x rel */
|
|
||||||
vid_mouse_yrel += event->yrel; /* update cumulative y rel */
|
|
||||||
vid_mouse_b1 = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
|
vid_mouse_b1 = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
|
||||||
vid_mouse_b2 = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE;
|
vid_mouse_b2 = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE;
|
||||||
vid_mouse_b3 = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE;
|
vid_mouse_b3 = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE;
|
||||||
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d) - Count: %d vid_mouse_rel:(%d,%d), vid_cursor:(%d,%d)\n",
|
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d) - Count: %d vid_cursor:(%d,%d)\n",
|
||||||
event->x, event->y, event->xrel, event->yrel, (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0, vid_mouse_events.count, vid_mouse_xrel, vid_mouse_yrel, vid_cursor_x, vid_cursor_y);
|
event->x, event->y, event->xrel, event->yrel, (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0, vid_mouse_events.count, vid_cursor_x, vid_cursor_y);
|
||||||
if (vid_mouse_events.count < MAX_EVENTS) {
|
if (vid_mouse_events.count < MAX_EVENTS) {
|
||||||
SIM_MOUSE_EVENT *tail = &vid_mouse_events.events[(vid_mouse_events.tail+MAX_EVENTS-1)%MAX_EVENTS];
|
SIM_MOUSE_EVENT *tail = &vid_mouse_events.events[(vid_mouse_events.tail+MAX_EVENTS-1)%MAX_EVENTS];
|
||||||
|
|
||||||
|
@ -1275,8 +1268,8 @@ if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
||||||
tail->y_rel += ev.y_rel;
|
tail->y_rel += ev.y_rel;
|
||||||
tail->x_pos = ev.x_pos;
|
tail->x_pos = ev.x_pos;
|
||||||
tail->y_pos = ev.y_pos;
|
tail->y_pos = ev.y_pos;
|
||||||
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: Coalesced into pending event: (%d,%d) vid_mouse_rel:(%d,%d)\n",
|
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: Coalesced into pending event: (%d,%d)\n",
|
||||||
tail->x_rel, tail->y_rel, vid_mouse_xrel, vid_mouse_yrel);
|
tail->x_rel, tail->y_rel);
|
||||||
}
|
}
|
||||||
else { /* Add a new event */
|
else { /* Add a new event */
|
||||||
vid_mouse_events.events[vid_mouse_events.tail++] = ev;
|
vid_mouse_events.events[vid_mouse_events.tail++] = ev;
|
||||||
|
@ -1705,6 +1698,9 @@ while (vid_active) {
|
||||||
if (vid_flags & SIM_VID_INPUTCAPTURED)
|
if (vid_flags & SIM_VID_INPUTCAPTURED)
|
||||||
SDL_WarpMouseInWindow (NULL, vid_width/2, vid_height/2); /* center position */
|
SDL_WarpMouseInWindow (NULL, vid_width/2, vid_height/2); /* center position */
|
||||||
break;
|
break;
|
||||||
|
case SDL_WINDOWEVENT_EXPOSED:
|
||||||
|
vid_update ();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -197,11 +197,6 @@ t_stat vid_screenshot (const char *filename);
|
||||||
|
|
||||||
extern t_bool vid_active;
|
extern t_bool vid_active;
|
||||||
extern uint32 vid_mono_palette[2];
|
extern uint32 vid_mono_palette[2];
|
||||||
extern int32 vid_mouse_xrel; /* mouse cumulative x rel */
|
|
||||||
extern int32 vid_mouse_yrel; /* mouse cumulative y rel */
|
|
||||||
extern t_bool vid_mouse_b1; /* mouse button 1 state */
|
|
||||||
extern t_bool vid_mouse_b2; /* mouse button 2 state */
|
|
||||||
extern t_bool vid_mouse_b3; /* mouse button 3 state */
|
|
||||||
void vid_set_cursor_position (int32 x, int32 y); /* cursor position (set by calling code) */
|
void vid_set_cursor_position (int32 x, int32 y); /* cursor position (set by calling code) */
|
||||||
|
|
||||||
#define SIM_VID_DBG_MOUSE 0x01000000
|
#define SIM_VID_DBG_MOUSE 0x01000000
|
||||||
|
|
Loading…
Add table
Reference in a new issue