📄 keyxlat.asm
字号:
;*
;* CW : Character Windows Drivers
;*
;* keyxlat.asm : Key translation
;*****************************************************************************
;********** VwFromSc **********
;* entry : CH = sc (scan code)
;* CL = ch (character)
;* BX = mpscvw = pointer to MPSCVW array (in CS)
;* * convert scan code to virtual key
;* * return virtual key
;* exit : BL = vw
;* Z flag set if (vw == 0)
;* * TRASHES BX and AX only
cProc VwFromSc, <NEAR, ATOMIC, PUBLIC>
cBegin nogen ;VwFromSc
;{{
; Assert(sc != 0 && sc != 0xe0);
; while (mpscvw->sc != 0)
; {
; if (mpscvw->sc == sc (DH))
; return mpscvw->vw; // in bl
; mpscvw++;
; }
; return 0;
;}}
IFDEF DEBUG
cmp ch,0
jnz ok1
int 3
ok1:
cmp ch,0e0h
jnz ok2
int 3
ok2:
ENDIF
tovw_loop:
mov al,CS:[bx].scMp
or al,al
jz fail_tovw
add bx,SIZE MPSCVW
cmp al,ch
jne tovw_loop
mov bl,CS:[bx].(vwMp - SIZE MPSCVW)
or bl,bl ;* set nz
ret
fail_tovw: ;* no match
xor bl,bl ;* set z
ret
cEnd nogen ;VwFromSc
;********* XlateKey **********
;* entry: DI => driver data
;* AL = char, AH = scan code
;* DX = shift states
;* * translate into character with shifts
;* * call UpdateShiftKk and KeyboardMessage with any results
cProc XlateKey,<NEAR, PUBLIC, ATOMIC>,<SI, DI>
localW ssOn
localW ssTemp
ssOff EQU SI ;* ssOff register variable
cBegin XlateKey
AssertEQ di,OFF_lpwDataKbd
mov cx,ax ;* AL = CL = ch, AH = CH = sc
mov ssTemp,dx ;* WARNING ch is in cl !!!!
;{{
; vw (bl) = 0;
; ssOn = ssOff = 0
;}}
xor bx,bx ;* vw = 0, can assume bh == 0
mov ssOn,bx
xor ssOff,ssOff ; ssOff = 0
;{{
; if (sc == 0)
; {
; if (ch != 0)
; {
; /*
; ch is a character entered numerically using the
; Alt key in combination with the numeric key pad.
; (e.g. The user typed Alt-down 1 2 3 Alt-Up the enter
; the char with decimal value 123)
; */
; vw = 0; /* already */
; ssOff = SS_ALT | SS_SHIFT | SS_CONTROL;
; }
; }
;}}
or ch,ch
jnz real_scan_code
;* * no real scan code (probably from alt-numpad)
jcxz done_xlat_4 ;* just update shift states
mov ssOff,(SS_ALT OR SS_SHIFT OR SS_CONTROL)
jmp short done_xlat_4
real_scan_code:
;{{ /* check for some RT extended keys ('/' and ENTER) */
; else if (sc == 0xe0)
; {
; ssOn = SS_EXTENDED;
; if (ch == 13 || ch == 10) /* ENTER or CTRL-ENTER */
; vw = VwOfVk(VK_RETURN);
; }
;}}
cmp ch,0e0h
jne not_ext_ascii
cmp cl, 13
je is_enter
cmp cl, 10
jne is_ext_ascii
or ssOn, SS_CONTROL
is_enter:
mov bl, VwOfVk(VK_RETURN)
is_ext_ascii:
mov ssOn, SS_EXTENDED
jmp short done_xlat_4
not_ext_ascii:
;{{ /* special ITL keyboard check */
; // ITL keyboards can use ALT-CTRL and ALT for special characters.
; // the normal BIOS will never return a (non-itl) character if the ALT
; // key is down. Therefore if we get a real character with the ALT
; // key down we will assume it is an international character and
; // turn off the ALT(MENU) and CONTROL bits.
; // there are a few exceptions, where we diddled the BIOS to let
; // some unusual ALT keys through (BS, '=', '+', '-')
; else if ((ss & SS_ALT) && ch != 0 && ch != 0xe0 &&
; ch != ' ' &&
; ch != 8 & ch != '=' &&
; sc != '+' && sc != '-')
; {
; ssOff = SS_ALT | SS_CONTROL
; }
;}}
test ssTemp,SS_ALT
jz no_itl_char
or cl,cl
jz no_itl_char
cmp cl,0e0h
je no_itl_char
cmp cl, 8
je no_itl_char
cmp cl, '='
je no_itl_char
cmp cl, '+'
je no_itl_char
cmp cl, '-'
je no_itl_char
cmp cl, ' '
je no_itl_char
mov ssOff,SS_ALT OR SS_CONTROL ;* turn off special states
done_xlat_4:
jmp done_xlat
no_itl_char:
;{{ /* simple cases */
; else if (sc == SC_MULTIPLY)
; ssOn = SS_EXTENDED, vw = VwOfVk(VK_MULTIPLY);
; else if (sc == SC_ADD)
; ssOn = SS_EXTENDED, vw = VwOfVk(VK_ADD);
; else if (sc == SC_SUBTRACT)
; ssOn = SS_EXTENDED, vw = VwOfVk(VK_SUBTRACT);
;}}
mov al, VwOfVk(VK_MULTIPLY)
cmp ch, SC_MULTIPLY
je done_xlat_x
mov al, VwOfVk(VK_ADD)
cmp ch, SC_ADD
je done_xlat_x
mov al, VwOfVk(VK_SUBTRACT)
cmp ch, SC_SUBTRACT
jne not_greyminus
done_xlat_x:
mov ssOn, SS_EXTENDED
jmp done_xlat_al
not_greyminus:
;{{ /* more simple cases */
; else if (sc == SC_ENTER)
; vw = VwOfVk(VK_RETURN);
; else if (sc == SC_ESC)
; vw = VwOfVk(VK_ESCAPE);
; else if (sc == SC_BACKSPACE)
; vw = VwOfVk(VK_BACK);
;}}
mov al,VwOfVk(VK_RETURN)
cmp ch,SC_ENTER
jz done_xlat_al
mov al,VwOfVk(VK_ESCAPE)
cmp ch,SC_ESC
jz done_xlat_al
mov al,VwOfVk(VK_BACK)
cmp ch,SC_BACKSPACE
jz done_xlat_al
ifdef KANJI
mov al, VwOfVk(VK_KANJI)
cmp ch, SC_KANJI
jz done_xlat_al
endif
;* * More complicated cases
;{{
; else if (sc == SC_TAB)
; ch = vw = VwOfVk(VK_TAB);
;}}
cmp ch,SC_TAB
jnz not_tab
mov bl,VwOfVk(VK_TAB)
mov cl, bl
jmp short done_xlat_1
not_tab:
;{{
; else if (ch == ' ')
; vw = 0;
;}}
cmp cl,' '
je done_xlat_1
jmp short not_space
;************************************************************************
;* * done_xlat_al : al = vw ;* located here for near jumps !!
done_xlat_al:
mov bl,al
done_xlat_1:
jmp done_xlat
;************************************************************************
not_space:
;{{ /* Alphas */
; else if (ch >= 'A' && ch <= 'Z') /* special jump for control */
; {
; vw = ch;
; ssOff = SS_ALT SS_CONTROL;
; }
; else if (ch >= 'a' && ch <= 'z')
; {
; vw = 'A' + (ch - 'a');
; ssOff = SS_ALT | SS_CONTROL;
; }
;}}
mov ax,cx
cmp al,'A'
jb maybe_control ;* maybe a control char ??
cmp al,'Z'
ja not_upper_alpha
;* * upper case alpha
mov ssOff,SS_ALT OR SS_CONTROL
jmp done_xlat_al
not_upper_alpha:
cmp al,'a'
jb not_alpha
cmp al,'z'
ja not_alpha
;* * lower case alpha
sub al,20H ;* to upper
mov ssOff,SS_ALT OR SS_CONTROL
jmp done_xlat_al
maybe_control:
;{{ /* test for control alpha characters */
; else if (ch >= 1 && ch <= 26)
; {
; vw = 'A' + (ch - 1);
; ssOff = SS_ALT;
; ssOn = SS_CONTROL;
; }
cmp al,1
jb not_alpha
cmp al,26
ja not_alpha
add al,40H
mov ssOff,SS_ALT
mov ssOn,SS_CONTROL
jmp done_xlat_al
not_alpha:
;{{ /* Check peculiar Ctrl keys (6 and -) */
; else if (sc == SC_MINUS && ch == 0x1F)
; ch = '-', ssOn |= SS_CONTROL;
; else if (sc == SC_6 && ch == 0x1E)
; ch = 0, vw = VwOfVk(VK_6), ssOn |= SS_CONTROL;
;}}
cmp cx, (SC_MINUS shl 8) + 1Fh
jne not_ctl_minus
mov cl, '-'
jmp short done_xlat_ctl
not_ctl_minus:
cmp cx, (SC_6 shl 8) + 1Eh
jne not_weirdctl
xor cl, cl
mov bl, VwOfVk(VK_6)
done_xlat_ctl:
or ssOn, SS_CONTROL
jmp short done_xlat_1
not_weirdctl:
;{{ /* Numpad exceptions */
; else if (sc >= SC_NUMPAD_MIN && sc < SC_NUMPAD_MAX)
; {
; /*
; At this point we know the user typed a key on the numeric
; keypad (but NOT ctrl+numpad that's handled farther down).
; We must figure out how the keystoke is to be interpreted.
; If ch == 0 then we interpret the keystroke as an arrow key.
; */
; if (sc != SC_INSERT)
; ssOff = SS_CONTROL;
; ivw (bx) = sc - SC_NUMPAD_MIN
; vw = rgvwNumpad[ivw];
; if (ch == 0xe0)
; {
; ch = 0;
; ssOn = SS_EXTENDED;
; }
; else if (ch == 0)
; {
; if (ss & SS_NUMLOCK)
; ssOff |= SS_SHIFT;
; }
; else if ((ss & SS_SHIFT) ||
; (sc == SC_NUMPAD5 &&
; !(ss & SS_CONTROL) && (ss & SS_NUMLOCK)))
; ch = 0;
; else
; {
; vw = rgvwNumeric[ivw];
; ssOn = SS_EXTENDED;
; }
; if (ch == 0 && sc == SC_DELETE)
; ch = (char) 0x7f;
; }
; }
;}}
cmp ch,SC_NUMPAD_MIN
jb not_num_pad
cmp ch,SC_NUMPAD_MAX
jae not_num_pad
IFDEF DOS5
test ssTemp, SS_ALT ;* ignore alt-numpad keystrokes
jz @F
jmp exit_xlat
@@:
ENDIF ;DOS5
;* * NUMPAD
mov bl,ch
;; xor bh,bh ;; not needed
mov bl,(rgvwNumpad-SC_NUMPAD_MIN)[BX]
cmp cl,0E0H
jne not_E0
xor cl,cl
mov ssOn, SS_EXTENDED
jmp num_pad_fin
not_E0:
or cl,cl
jnz num_pad_2
test ssTemp,SS_NUMLOCK
jz num_pad_fin
or ssOff,SS_SHIFT
jmp short num_pad_fin
num_pad_2:
IFDEF STD_NUMPAD
cmp ch, 76 ;numpad 5
jnz num_pad_normal
test ssTemp, SS_NUMLOCK
jz num_pad_fun
test ssTemp, SS_CONTROL
jnz num_pad_fun
test ssTemp, SS_SHIFT
jz num_pad_num
or ssOff, SS_SHIFT
jmp short num_pad_fun
ENDIF ; STD_NUMPAD
IFDEF TOSHIBA_NUMPAD
test ssTemp, SS_NUMLOCK
jz num_pad_fun
test ssTemp, SS_CONTROL
jnz num_pad_fun
test ssTemp, SS_SHIFT
jz num_pad_num
or ssOff, SS_SHIFT
ELSE ;TOSHIBA_NUMPAD
num_pad_normal:
test ssTemp, SS_SHIFT
jnz num_pad_fun
test ssTemp,SS_NUMLOCK
jnz num_pad_num
ENDIF ;TOSHIBA_NUMPAD
num_pad_fun:
mov cl,0
jmp short num_pad_fin
num_pad_num:
mov bl,ch
;; xor bh,bh ;; not needed
mov bl,(rgvwNumeric-SC_NUMPAD_MIN)[BX]
mov ssOn, SS_EXTENDED
num_pad_fin: ;* test delete case
or cl,cl
jnz done_xlat_2
cmp ch,SC_DELETE
jnz done_xlat_2
mov cl,07FH
done_xlat_2:
jmp done_xlat
not_num_pad:
;{{ /* check for number keys */
; else if (ch >= '0' && ch <= '9')
; {
; vw = ch;
; if (ss & SS_CONTROL)
; ch = 0;
; }
;}}
cmp cl,'0'
jb not_num
cmp cl,'9'
ja not_num
mov bl,cl
test ssTemp, SS_CONTROL
jz done_xlat_2
xor cl, cl
jmp done_xlat_2
not_num:
;{{ /* F1..F10 and ALT-1..9 */
; else if (ch == 0 || ch = 0xe0)
; {
; ch = 0;
; ssOff = SS_SHIFT | SS_CONTROL | SS_ALT;
; /* special cases */
; if (sc >= 59 && sc <= 68) /* Fn */
; {
; /* normal key */
; vw = VwOfVk(VK_F1) + (sc - 59);
; }
; else if (sc >= 84 && sc <= 93) /* SHIFT Fn */
; {
; vw = VwOfVk(VK_F1) + (sc - 84);
; ssOn = SS_LSHIFT;
; }
; else if (sc >= 94 && sc <= 103) /* CTRL Fn */
; {
; vw = VwOfVk(VK_F1) + (sc - 94);
; ssOn = SS_CONTROL;
; ssOff = SS_ALT; // allow SHIFT
; }
; else if (sc >= 104 && sc <= 113) /* ALT Fn */
; {
; vw = VwOfVk(VK_F1) + (sc - 104);
; ssOn = SS_ALT;
; ssOff = 0; // allow SHIFT/CONTROL
; }
; else if (sc >= 120 && sc <= 128)
; {
; vw = '1' + (sc - 120);
; ssOn = SS_ALT;
; ssOff = 0; // allow SHIFT/CONTROL
; }
;}}
or cl,cl
jz is_special
cmp cl, 0e0h
jnz done_xlat_3
xor cl, cl
mov ssOn, SS_EXTENDED
is_special:
xor dx, dx ;* additional shift states
mov ssOff,SS_SHIFT OR SS_CONTROL OR SS_ALT
mov ah,VwOfVk(VK_F1) ;* base vw
mov al,59 ;* al = base sc
cmp ch,al
jb not_special
cmp ch,68
jbe do_special
mov al,84
mov dx,SS_LSHIFT
cmp ch,al
jb not_special
cmp ch,93
jbe do_special
mov ssOff,SS_ALT ;* menu is the only thing overridden
mov al,94
mov dx,SS_CONTROL
cmp ch,al
jb not_special
cmp ch,103
jbe do_special
xor ssOff,ssOff ;* allow everything
mov al,104
mov dx,SS_ALT
cmp ch,al
jb not_special
cmp ch,113
jbe do_special
mov al,120
mov dx,SS_ALT
cmp ch,al
jb not_special
cmp ch,128
ja not_special
mov ah,'1'
do_special:
; * ah = base key, ch = sc, al = base scan code, dx = ssOn
neg al
add al,ch
add al,ah
mov bl,al
or ssOn,dx
done_xlat_3:
jmp done_xlat
not_special:
;{{ /* last default case */
; else
; {
; if (vw == 0)
; vw = VwFromSc(sc, pmpscvwPlain);
; if (vw == 0)
; {
; if (vw = VwFromSc(sc, pmpscvwAltRonco))
; {
; /* Extended keypad Alt */
; ssOn |= SS_ALT | SS_EXTENDED;
; }
; if (vw = VwFromSc(sc, pmpscvwAlt))
; {
; /* normal ALT */
; ssOn |= SS_ALT;
; }
; else if (ch == 0 && vw = VwFromSc(sc, pmpscvwAltNoChar))
; {
; /* special ALT */
; ssOn |= SS_ALT;
; ch = vw;
; vw = 0;
; }
; else if (vw = VwFromSc(sc, mpscvwCtrl))
; {
; ssOff = 0;
; ssOn |= SS_CONTROL;
; }
; else if (vw = VwFromSc(sc, pmpscvwShift))
; {
; ssOff = 0;
; ssOn |= SS_LSHIFT;
; }
; }
; }
; } /*end of major if*/
;}}
mov bx,[di].pmpscvwPlain
cCall VwFromSc
jnz done_xlat
mov bx,drvOffset mpscvwAltRonco
cCall VwFromSc
jz not_extalt
or ssOn, SS_ALT OR SS_EXTENDED
jmp short done_xlat
not_extalt:
mov bx,drvOffset mpscvwAlt
cCall VwFromSc
jz not_alt1
yes_alt:
or ssOn,SS_ALT
jmp short done_xlat
not_alt1:
or cl,cl
jnz not_alt2
mov bx,drvOffset mpscvwAltNoChar
cCall VwFromSc
jz not_alt2
xchg cl, bl ;* actually it's a CH, not a VW
jmp short yes_alt
not_alt2:
mov bx,drvOffset mpscvwCtrl
cCall VwFromSc
jz not_control
;* * control
xor ssOff,ssOff
or ssOn,SS_CONTROL
jmp short done_xlat
not_control:
mov bx,[di].pmpscvwShift
cCall VwFromSc
jz done_xlat
xor ssOff,ssOff
or ssOn,SS_LSHIFT
done_xlat: ;* CX == sc:ch, ssTemp == ss, BL = vw
;{{
; ssNew = (ss & ~ssOff) | ssOn;
;}}
mov ax,ssOff
not ax
and ax,ssTemp ;* ss & ~ssOff
or ax,ssOn
mov dx, ax ;* ssNew
;{{
; if (vw | ch)
; {
; /* 1 message for WM_CHAR only !! */
; KeyboardMessage(vw, ch, KkOfSs(ssNew), FALSE);
; }
mov al,bl
or al,cl
jz no_key_event
mov al,ch ;* sc
IFDEF KANJI
xor ah,ah
push ax ;* sc
ENDIF ; KANJI
Assert <?PLM>
push bx ;* vw
xor ch,ch
or cl,cl
jnz we_have_char
;* * no char -- put in the VK
Assert <VwOfVk(155H) EQ 55H>
mov cl,bl
inc ch ;* ch == 1
we_have_char:
push cx ;* ch
cCall KkOfSs, <dx>
push ax
xor bx,bx
push bx ;* FALSE
mov bx,[di].pinkbCur
cCall [bx].lpfnKeyboardMessageInkb
no_key_event:
;{{ /* restore shift states */
; DoShift(ss);
;}}
cCall DoShift,<ssTemp>
exit_xlat:
cEnd XlateKey
;*********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -