The VT100 is now smarter about detecting the host machine's physical CAPS LOCK state (and is also capable of displaying that state now)
This commit is contained in:
parent
7f48221bca
commit
57d287f161
7 changed files with 239 additions and 30 deletions
|
|
@ -3,7 +3,7 @@
|
|||
<machine id="vt100" class="pc8080" border="1" pos="center" background="#FAEBD7">
|
||||
<name pos="center">VT100 Terminal</name>
|
||||
<computer id="computer" busWidth="16"/>
|
||||
<cpu id="cpu8080" model="8080" cycles="2764800"/>
|
||||
<cpu id="cpu8080" model="8080" cycles="2764800" autoStart="true"/>
|
||||
<rom id="rom" addr="0x0000" size="0x2000" file="/devices/pc8080/rom/vt100/VT100.json"/>
|
||||
<ram id="ram" addr="0x2000" size="0x0C00"/>
|
||||
<video id="video" screenWidth="1600" screenHeight="960" smoothing="false" interruptRate="60"
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
<control type="rled" label="L2" binding="l2" padLeft="8px"/>
|
||||
<control type="rled" label="L3" binding="l3" padLeft="8px"/>
|
||||
<control type="rled" label="L4" binding="l4" padLeft="8px"/>
|
||||
<control type="led" label="CAPS" binding="caps-lock" padLeft="8px"/>
|
||||
<control type="button" binding="fullScreen" padLeft="8px;line-height:1em">Full Screen</control>
|
||||
</control>
|
||||
</menu>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
<control type="rled" label="L2" binding="l2" padLeft="8px"/>
|
||||
<control type="rled" label="L3" binding="l3" padLeft="8px"/>
|
||||
<control type="rled" label="L4" binding="l4" padLeft="8px"/>
|
||||
<control type="led" label="CAPS" binding="caps-lock" padLeft="8px"/>
|
||||
<control type="button" binding="fullScreen" padLeft="8px;line-height:1em">Full Screen</control>
|
||||
</control>
|
||||
</menu>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ machines:
|
|||
connection: dl11->vt100.serialPort
|
||||
- id: vt100
|
||||
type: pc8080
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
debugger: true
|
||||
config: /devices/pc8080/machine/vt100/debugger/machine.xml
|
||||
connection: serialPort->test1170.dl11
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ on [bitsavers.org](http://bitsavers.trailing-edge.com/pdf/dec/pdp11/microfiche/f
|
|||
DATE CREATED: MAY, 1980
|
||||
MAINTAINER: DIAGNOSTIC ENGINEERING
|
||||
|
||||
The source code listing for TEST 40 appears to match the code above:
|
||||
The source code listing for TEST 40 matches the code above, and begins at the same address (020402):
|
||||
|
||||
;;***************************************************************
|
||||
;*TEST 40 RED ZONE TRAP
|
||||
|
|
@ -176,3 +176,86 @@ PDPjs was failing to trigger a RED stack violation on this instruction:
|
|||
so execution fell into `ERROR 241`. This was resolved by updating the *checkStackLimit1145()* function
|
||||
in [cpustate.js](/modules/pdp11/lib/cpustate.js) to include stack addresses >= 177776 in the RED stack
|
||||
overflow range test.
|
||||
|
||||
The next test that PDPjs failed was TEST 63, which also matches the source code listing in the above microfiche,
|
||||
and begins at the same address (031532):
|
||||
|
||||
;;***************************************************************
|
||||
;*TEST 63 WAIT
|
||||
;*
|
||||
;* THIS TEST ENSURES THAT THE WAIT INSTRUCTION WORKS PROPERLY.
|
||||
;* IT FIRST EXECUTES WITH A LEVEL 4 INTERRUPT.
|
||||
;* THEN THE T BIT IS ENABLED TO ENSURE THAT THE INTERRUPT
|
||||
;* OCCURS AND NOT THE T BIT TRAP.
|
||||
;;***************************************************************
|
||||
TST63: SCOPE
|
||||
MOV #TST64,NEXTTST ;SAVE ADDRESS OF NEXT TEST
|
||||
MOV #^D1990,$ICNT ;ADJUST ITTERATION COUNT
|
||||
MOV #10$,$LPADR ;SETUP LOOP ADR
|
||||
10$: MOV #2$,@#TPVEC ;SETUP TELEPRINTER VECTOR
|
||||
MOV #1$,$LPERR ;SETUP ERROR LOOP
|
||||
1$: MOV #STACK,SP ;INITIALIZE THE SP
|
||||
SPL 3
|
||||
MOV #BIT6,@$TPS ;SET PRINTER INTERRUPT FLAG
|
||||
MOV #15,@$TPB ;SEND CHARACTER
|
||||
WAIT ;EXECUTE INSTRUCTION UNDER TEST
|
||||
;FAILURE
|
||||
CLR @$TPS ;CLEAR INTERR ENABLE BIT
|
||||
ERROR 377 ;WAIT INSTRUCTION DID NOT
|
||||
BR 5$ ;WAIT FOR INTERRUPT
|
||||
|
||||
After setting and hitting a breakpoint at 031532, we can step through the instructions in this test:
|
||||
|
||||
bp 031532 hit
|
||||
stopped (37666352 instructions, 181205851 cycles, 27294 ms, 6639036 hz)
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=031532 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031532: 012767 032024 147530 MOV #32024,001270
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=031540 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031540: 012767 003706 147336 MOV #3706,001104 ;cycles=16
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=031546 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031546: 012767 031554 147332 MOV #31554,001106 ;cycles=16
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=031554 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031554: 012737 031624 000064 MOV #31624,@#64 ;cycles=16
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=031562 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031562: 012767 031570 147320 MOV #31570,001110 ;cycles=16
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=031570 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031570: 012706 001100 MOV #1100,SP ;cycles=16
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001100 PC=031574 PS=010340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031574: 000233 SPL 003 ;cycles=7
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001100 PC=031576 PS=010140 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031576: 012777 000100 147336 MOV #100,@001142 ;cycles=5
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001100 PC=031604 PS=010140 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
031604: 012777 000015 147332 MOV #15,@001144 ;cycles=20
|
||||
>> tr
|
||||
trapped to 100 (INTERRUPT)
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=026020 PS=000340 IR=000000 SL=000377 T0 N0 Z0 V0 C0
|
||||
026020: 005077 153212 CLR @001236 ;cycles=0
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=026024 PS=000344 IR=000000 SL=000377 T0 N0 Z1 V0 C0
|
||||
026024: 005037 177772 CLR @#177772 ;cycles=19
|
||||
>> tr
|
||||
R0=000000 R1=000102 R2=000000 R3=000000 R4=000000 R5=026642
|
||||
SP=001074 PC=026030 PS=000344 IR=000000 SL=000377 T0 N0 Z1 V0 C0
|
||||
026030: 104324 EMT 324 ;cycles=16
|
||||
|
||||
Vector 100 is for the KW11 Line Clock -- an interrupt that the test was apparently not expecting. It
|
||||
was instead looking for an interrupt from the DL11 "teleprinter" device.
|
||||
|
|
|
|||
|
|
@ -68,6 +68,6 @@ the PDF (p. 199 of the source code listing):
|
|||
;;***************************************************************
|
||||
|
||||
As noted in the *mapVirtualToPhysical()* function in [cpustate.js](/modules/pdp11/lib/cpustate.js), this test
|
||||
begins at PC 076060.
|
||||
begins at PC 076060, which is exactly 0100 bytes lower than the address shown in the source code listing (076160).
|
||||
|
||||
This diagnostic should run in any [PDP-11/70](/devices/pdp11/machine/1170/) ([Demo](/devices/pdp11/machine/1170/panel/debugger/xxdp/)).
|
||||
|
|
|
|||
|
|
@ -69,7 +69,34 @@ function Keyboard8080(parmsKbd)
|
|||
|
||||
Component.subclass(Keyboard8080);
|
||||
|
||||
Keyboard8080.MINPRESSTIME = 50; // minimum milliseconds to wait before auto-releasing keys
|
||||
/*
|
||||
* Now that we want to keep track of the physical (and simulated) state of modifier keys, I've
|
||||
* grabbed a copy of the same bit definitions used by /modules/pcx86/lib/keyboard.js, since it's
|
||||
* only important that we have a set of unique values; what the values are isn't critical.
|
||||
*/
|
||||
Keyboard8080.STATE = {
|
||||
RSHIFT: 0x0001,
|
||||
SHIFT: 0x0002,
|
||||
SHIFTS: 0x0003,
|
||||
RCTRL: 0x0004, // 101-key keyboard only
|
||||
CTRL: 0x0008,
|
||||
CTRLS: 0x000C,
|
||||
RALT: 0x0010, // 101-key keyboard only
|
||||
ALT: 0x0020,
|
||||
ALTS: 0x0030,
|
||||
RCMD: 0x0040, // 101-key keyboard only
|
||||
CMD: 0x0080, // 101-key keyboard only
|
||||
CMDS: 0x00C0,
|
||||
ALL_RIGHT: 0x0055, // RSHIFT | RCTRL | RALT | RCMD
|
||||
ALL_SHIFT: 0x00FF, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD
|
||||
INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any "insert" states)
|
||||
CAPS_LOCK: 0x0200,
|
||||
NUM_LOCK: 0x0400,
|
||||
SCROLL_LOCK: 0x0800,
|
||||
ALL_LOCKS: 0x0E00 // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK
|
||||
};
|
||||
|
||||
Keyboard8080.MINPRESSTIME = 50; // minimum milliseconds to wait before auto-releasing keys
|
||||
|
||||
/**
|
||||
* Alternate keyCode mappings to support popular "WASD"-style directional-key mappings.
|
||||
|
|
@ -255,7 +282,8 @@ Keyboard8080.VT100.LEDCODES = {
|
|||
'l1': Keyboard8080.VT100.STATUS.LED1,
|
||||
'locked': Keyboard8080.VT100.STATUS.LOCKED,
|
||||
'local': Keyboard8080.VT100.STATUS.LOCAL,
|
||||
'online': ~Keyboard8080.VT100.STATUS.LOCAL
|
||||
'online': ~Keyboard8080.VT100.STATUS.LOCAL,
|
||||
'caps-lock':Keyboard8080.STATE.CAPS_LOCK
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -322,6 +350,9 @@ Keyboard8080.prototype.setBinding = function(sHTMLType, sBinding, control, sValu
|
|||
control.onkeyup = function onKeyUp(event) {
|
||||
return kbd.onKeyDown(event, false);
|
||||
};
|
||||
control.onkeypress = function onKeyPress(event) {
|
||||
return kbd.onKeyPress(event);
|
||||
};
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
@ -458,6 +489,13 @@ Keyboard8080.prototype.reset = function()
|
|||
*/
|
||||
this.aKeysActive = [];
|
||||
|
||||
/*
|
||||
* The current (assumed) physical (and simulated) states of the various shift/lock keys.
|
||||
*
|
||||
* TODO: Determine how (or whether) we can query the browser's initial shift/lock key states.
|
||||
*/
|
||||
this.bitsState = 0;
|
||||
|
||||
if (this.config.INIT && !this.restore(this.config.INIT)) {
|
||||
this.notice("reset error");
|
||||
}
|
||||
|
|
@ -515,39 +553,80 @@ Keyboard8080.prototype.restore = function(data)
|
|||
};
|
||||
|
||||
/**
|
||||
* setLED(control, f)
|
||||
* setLED(control, f, color)
|
||||
*
|
||||
* TODO: Add support for user-definable LED colors
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} control is an HTML control DOM object
|
||||
* @param {boolean} f is true if the LED represented by control should be "on", false if "off"
|
||||
* @param {boolean|number} f is true if the LED represented by control should be "on", false if "off"
|
||||
* @param {number} color (ie, 0xff0000 for RED, or 0x00ff00 for GREEN)
|
||||
*/
|
||||
Keyboard8080.prototype.setLED = function(control, f)
|
||||
Keyboard8080.prototype.setLED = function(control, f, color)
|
||||
{
|
||||
/*
|
||||
* TODO: Add support for user-definable LED colors
|
||||
*/
|
||||
control.style.backgroundColor = (f? "#ff0000" : "#000000");
|
||||
control.style.backgroundColor = (f? ('#' + str.toHex(color, 6)) : "#000000");
|
||||
};
|
||||
|
||||
/**
|
||||
* updateLEDs(bLEDs)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {number} bLEDs
|
||||
* @param {number} [bLEDs]
|
||||
*/
|
||||
Keyboard8080.prototype.updateLEDs = function(bLEDs)
|
||||
{
|
||||
this.bLEDs = bLEDs;
|
||||
var id, control;
|
||||
if (bLEDs != null) {
|
||||
this.bLEDs = bLEDs;
|
||||
} else {
|
||||
bLEDs = this.bLEDs;
|
||||
}
|
||||
for (var sBinding in this.config.LEDCODES) {
|
||||
var id = "led-" + sBinding;
|
||||
var control = this.bindings[id];
|
||||
id = "led-" + sBinding;
|
||||
control = this.bindings[id];
|
||||
if (control) {
|
||||
var bitLED = this.config.LEDCODES[sBinding];
|
||||
var fOn = !!(bLEDs & bitLED);
|
||||
if (bitLED & (bitLED-1)) {
|
||||
fOn = !(bLEDs & ~bitLED);
|
||||
}
|
||||
this.setLED(control, fOn);
|
||||
this.setLED(control, fOn, 0xff0000);
|
||||
}
|
||||
}
|
||||
id = "led-caps-lock";
|
||||
control = this.bindings[id];
|
||||
if (control) {
|
||||
this.setLED(control, (this.bitsState & Keyboard8080.STATE.CAPS_LOCK), 0x00ff00);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* checkModifierKeys(softCode, fDown, fRight)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {number|string} softCode (ie, either a keycode or string ID)
|
||||
* @param {boolean} fDown (true if key going down, false if key going up)
|
||||
* @param {boolean} fRight (true if key is on the right, false if not or unknown or n/a)
|
||||
*/
|
||||
Keyboard8080.prototype.checkModifierKeys = function(softCode, fDown, fRight)
|
||||
{
|
||||
var bit = 0;
|
||||
switch(softCode) {
|
||||
case Keys.KEYCODE.CTRL:
|
||||
bit = fRight? Keyboard8080.STATE.RCTRL : Keyboard8080.STATE.CTRL;
|
||||
break;
|
||||
case Keys.KEYCODE.SHIFT:
|
||||
bit = fRight? Keyboard8080.STATE.RSHIFT : Keyboard8080.STATE.SHIFT;
|
||||
break;
|
||||
case Keys.KEYCODE.CAPS_LOCK:
|
||||
bit = Keyboard8080.STATE.CAPS_LOCK;
|
||||
break;
|
||||
}
|
||||
if (bit) {
|
||||
if (fDown) {
|
||||
this.bitsState |= bit;
|
||||
} else {
|
||||
this.bitsState &= ~bit;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -555,7 +634,7 @@ Keyboard8080.prototype.updateLEDs = function(bLEDs)
|
|||
/**
|
||||
* getSoftCode(keyCode)
|
||||
*
|
||||
* Returns a number if the keyCode exists in the KEYMAP, or a string if the keyCode has a soft-code string.
|
||||
* Returns a number if the keyCode exists in the KEYMAP, or a string if the keyCode has a string ID.
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @return {string|number|null}
|
||||
|
|
@ -589,8 +668,21 @@ Keyboard8080.prototype.onKeyDown = function(event, fDown)
|
|||
var softCode = this.getSoftCode(keyCode);
|
||||
|
||||
if (softCode) {
|
||||
/*
|
||||
* We now keep track of any physical keyboard modifier keys that also exist on the simulated
|
||||
* keyboard; in the case of the VT100, that means CTRL and SHIFT. This will make it possible
|
||||
* for a new pair of services to eventually be implemented: simulateKeysDown() and simulateKeysUp().
|
||||
*/
|
||||
this.checkModifierKeys(softCode, fDown, event.location == Keys.LOCATION.RIGHT);
|
||||
fPass = this.onSoftKeyDown(softCode, fDown);
|
||||
event.preventDefault();
|
||||
/*
|
||||
* As onKeyPress() explains, the only key presses we're interested in are letters, which provide
|
||||
* an important clue regarding the CAPS-LOCK state. For all other keys, we call preventDefault(),
|
||||
* which "suppresses" the keyPress event.
|
||||
*/
|
||||
if (softCode < Keys.ASCII.A || softCode > Keys.ASCII.Z) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {
|
||||
|
|
@ -600,6 +692,35 @@ Keyboard8080.prototype.onKeyDown = function(event, fDown)
|
|||
return fPass;
|
||||
};
|
||||
|
||||
/**
|
||||
* onKeyPress(event)
|
||||
*
|
||||
* For now, our only interest in keyPress events is letters, as a means of detecting the CAPS-LOCK state.
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} event
|
||||
* @return {boolean} true to pass the event along, false to consume it
|
||||
*/
|
||||
Keyboard8080.prototype.onKeyPress = function(event)
|
||||
{
|
||||
var keyCode = event.keyCode;
|
||||
if (keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {
|
||||
if (!(this.bitsState & (Keyboard8080.STATE.SHIFTS | Keyboard8080.STATE.CAPS_LOCK))) {
|
||||
this.bitsState |= Keyboard8080.STATE.CAPS_LOCK;
|
||||
this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, true);
|
||||
this.updateLEDs();
|
||||
}
|
||||
}
|
||||
else if (keyCode >= Keys.ASCII.a && keyCode <= Keys.ASCII.z) {
|
||||
if (this.bitsState & Keyboard8080.STATE.CAPS_LOCK) {
|
||||
this.bitsState &= ~Keyboard8080.STATE.CAPS_LOCK;
|
||||
this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, false);
|
||||
this.updateLEDs();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* indexOfSoftKey(softCode)
|
||||
*
|
||||
|
|
@ -609,35 +730,36 @@ Keyboard8080.prototype.onKeyDown = function(event, fDown)
|
|||
*/
|
||||
Keyboard8080.prototype.indexOfSoftKey = function(softCode)
|
||||
{
|
||||
var i;
|
||||
for (i = 0; i < this.aKeysActive.length; i++) {
|
||||
for (var i = 0; i < this.aKeysActive.length; i++) {
|
||||
if (this.aKeysActive[i].softCode == softCode) return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* onSoftKeyDown(softCode, fDown)
|
||||
* onSoftKeyDown(softCode, fDown, fAutoRelease)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {number|string} softCode
|
||||
* @param {boolean} fDown is true for a down event, false for up
|
||||
* @param {boolean} [fAutoRelease] is true only if we know we want the key to auto-release
|
||||
* @return {boolean} true to pass the event along, false to consume it
|
||||
*/
|
||||
Keyboard8080.prototype.onSoftKeyDown = function(softCode, fDown)
|
||||
Keyboard8080.prototype.onSoftKeyDown = function(softCode, fDown, fAutoRelease)
|
||||
{
|
||||
var i = this.indexOfSoftKey(softCode);
|
||||
if (fDown) {
|
||||
// this.println(softCode + " down");
|
||||
fAutoRelease = fAutoRelease || false;
|
||||
if (i < 0) {
|
||||
this.aKeysActive.push({
|
||||
softCode: softCode,
|
||||
msDown: Date.now(),
|
||||
fAutoRelease: false
|
||||
fAutoRelease: fAutoRelease
|
||||
});
|
||||
} else {
|
||||
this.aKeysActive[i].msDown = Date.now();
|
||||
this.aKeysActive[i].fAutoRelease = false;
|
||||
this.aKeysActive[i].fAutoRelease = fAutoRelease;
|
||||
}
|
||||
} else if (i >= 0) {
|
||||
// this.println(softCode + " up");
|
||||
|
|
|
|||
|
|
@ -331,22 +331,23 @@ Keyboard.SCANCODE = {
|
|||
Keyboard.STATE = {
|
||||
RSHIFT: 0x0001,
|
||||
SHIFT: 0x0002,
|
||||
SHIFTS: 0x0003,
|
||||
RCTRL: 0x0004, // 101-key keyboard only
|
||||
CTRL: 0x0008,
|
||||
CTRLS: 0x000c,
|
||||
CTRLS: 0x000C,
|
||||
RALT: 0x0010, // 101-key keyboard only
|
||||
ALT: 0x0020,
|
||||
ALTS: 0x0030,
|
||||
RCMD: 0x0040, // 101-key keyboard only
|
||||
CMD: 0x0080, // 101-key keyboard only
|
||||
CMDS: 0x00c0,
|
||||
CMDS: 0x00C0,
|
||||
ALL_RIGHT: 0x0055, // RSHIFT | RCTRL | RALT | RCMD
|
||||
ALL_SHIFT: 0x00ff, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD
|
||||
ALL_SHIFT: 0x00FF, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD
|
||||
INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any "insert" states)
|
||||
CAPS_LOCK: 0x0200,
|
||||
NUM_LOCK: 0x0400,
|
||||
SCROLL_LOCK: 0x0800,
|
||||
ALL_LOCKS: 0x0e00 // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK
|
||||
ALL_LOCKS: 0x0E00 // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue