;
; keyboard.asm - Test different key combinations.
;
; Jason Hood, 2 to 4 December, 2000.
; Public Domain.
;
; Currently it does not handle Pause correctly - it generates E1 1D 45 on make
; and E1 9D C5 immediately after. I simply ignore the E1 1D and so the Numlock
; key is flashed.
;
; 031013, v1.00:
; display scancodes using a hexadecimal matrix.
;
.model tiny
.code
org 100h
LEFTSHIFT equ 2ah
RIGHTSHIFT equ 36h
ESCAPE equ 01h
RELEASED equ
esc_on equ 01b
shift_on equ 10b
esc_off equ
shift_off equ
exit_state equ esc_on or shift_on
COL_UNPRESSED equ 112 ; Black on grey
COL_PRESSED equ 123 ; Bright cyan on grey
COL_PREFIX equ 122 ; Bright green on grey
KEY_DISP equ 0602h ; Adjustment for keyboard position
HEX_DISP equ 1516h ; Adjustment for hex matrix position
begin:
jmp start
db 8, 8, 8
helpmsg db 'Keyboard by Jason Hood .',13,10
db 'Version 1.00 (14 October, 2003). Public Domain.',13,10
db 'http://misc.adoxa.cjb.net/',13,10
db 13,10
db 'Display a keyboard layout and highlight each key as it',13,10
db 'is pressed and released. It is particularly useful for',13,10
db 'determining which keys can be pressed together without',13,10
db 'interfering with each other (for games).',13,10
db 13,10
db 'It also shows the key''s hexadecimal scancode. Prefixed',13,10
db 'keys show up in green.',13,10
db 26, 8, ' $'
help:
mov dx, offset helpmsg
mov ah, 9
int 21h
ret
start:
cmp word ptr [ds:81h],'?/'
je help
cmp word ptr [ds:82h],'?/' ; Assume a space before it
je help
mov ax,3 ; 80 x 25 colour
int 10h
mov ah,1 ; Hide the cursor
mov cx,2000h
int 10h
mov ah,9 ; Clear the screen
mov al,' '
mov bh,0
mov bl,COL_UNPRESSED
mov cx,80*25
int 10h
mov bx,offset title_msg
call print
mov bx,offset exit_msg
call print
mov bx,offset hex_msg
push bx
call print
pop bx
mov byte ptr [bx],42 ; Adjust for second half
add byte ptr [bx+38],4
add byte ptr [bx+41],4
add byte ptr [bx+44],4
add byte ptr [bx+47],4
call print
call key_lens
call display_keys
mov ax,3515h ; Get the original Int15
int 21h
mov word ptr int15,bx ; Preserve it
mov word ptr int15+2,es
mov dx,offset scancode ; Point to my new one
mov ax,2515h ; Set it
int 21h
continue: ; Wait for termination
cmp done,exit_state
jne continue
lds dx,int15 ; Point to the original Int15
mov ax,2515h ; Restore it
int 21h
mov ax,3 ; Clear screen and restore cursor
int 10h
ret ; Finished
; Print a string using BIOS.
; BX - pointer to x, y, length and string.
print proc
mov dx,[bx]
mov ch,0
mov cl,[bx+2]
lea bp,[bx+3]
mov bx,COL_UNPRESSED
mov ax,1300h
int 10h
ret
print endp
title_msg db 36, 1, 8, 'KEYBOARD'
exit_msg db 28, 3, 24, 'Press Shift+Esc to exit.'
hex_msg db 21, 20, 45, ' 0123456789abcdef', 17 dup (8)
db 10, '0', 8
db 10, '1', 8
db 10, '2', 8
db 10, '3'
int15 dd 0 ; Original Int15 vector
done db 0 ; Termination flag
prefix db 0 ; For the E0 and E1 prefixed codes
old_code dw 0 ; Prevent repeat
scancode proc far
pushf
sti ; Okay to interrupt
cmp ah,4fh ; Intercept function?
je okay
popf
jmp cs:[int15]
okay:
push ax dx ds
push cs
pop ds
xor ah,ah
xchg prefix,ah
or ah,ah ; Have we seen a prefix?
jne prefixed_code ; Yes
cmp al,0e0h ; Test for prefix
je prefix_found
cmp al,0e1h ; Second prefix (Pause only)
jne no_prefix
prefix_found:
mov prefix,al ; Remember the prefix
jmp short exit ; and get out
no_prefix:
prefixed_code:
cmp ax,old_code ; Same as the previous key?
je exit ; Yep, get out
mov old_code,ax
test_escape: ; Test for certain keys
cmp ax,ESCAPE
jne test_shift
or done,esc_on
jmp short print_key
test_shift:
cmp ax,LEFTSHIFT
je shift_pressed
cmp ax,RIGHTSHIFT
jne test_esc_release
shift_pressed:
or done,shift_on
jmp short print_key
test_esc_release:
cmp ax,ESCAPE RELEASED
jne test_shift_release
and done,esc_off
jmp short print_key
test_shift_release:
cmp ax,LEFTSHIFT RELEASED
je shift_released
cmp ax,RIGHTSHIFT RELEASED
jne print_key
shift_released:
and done,shift_off
print_key:
call display_key
exit:
pop ds dx ax
popf
clc ; Ignore the key
ret 2 ; and the interrupted flags
scancode endp
; Display a key
; In: AX - key code (AH = prefix, AL = scan code)
display_key proc
push ax bx cx dx bp si
push es
push cs
pop es
mov si,offset normal_keys
or ah,ah
jz is_normal
cmp ah,0e0h
jne display_exit
mov si,offset prefix_keys
is_normal:
mov bx,COL_PRESSED ; BH = 0 for page
cmp al,128
jb is_pressed
mov bl,COL_UNPRESSED
sub al,128
is_pressed:
push ax
mov dh,size _key
mul dh
add si,ax
mov ch,0
cmp byte ptr [si],ch ; Unknown key - ignore it
je display_hex
mov ax,1300h
mov dx,word ptr [si.x]
add dx,KEY_DISP
mov bp,si
mov cl,es:[bp+nlen]
int 10h
display_hex:
pop ax
or ah,ah ; Display prefixed keys
jz d_no_p ; using a different colour
cmp bl,COL_UNPRESSED
je d_no_p
mov bl,COL_PREFIX
d_no_p:
mov dh,al ; Split AL into DH and DL
mov cl,4
shr dh,cl
mov dl,al
and dl,0fh
cmp dh,4 ; If it's the second half
jb d_h
add dl,21 ; move across to the right
and dh,3
d_h:
add dx,HEX_DISP
mov ax,1300h
mov bp,offset asterisk
mov cl,1
int 10h
display_exit:
pop es
pop si bp dx cx bx ax
ret
display_key endp
; Calculate the length of the key names.
key_lens proc
mov cx,256 ; 128 normal, 128 prefix
mov bx,offset normal_keys
key_len:
mov si,-1
len:
inc si
cmp byte ptr [bx+si],0
jne len
mov ax,si
mov [bx+nlen],al
add bx,size _key
loop key_len
ret
key_lens endp
; Display all keys.
display_keys proc
mov ax,128 ; Unpressed keys
call disp
mov ax,0e080h ; Unpressed prefixed keys
disp:
mov cx,128
another_key:
call display_key
inc ax
loop another_key
ret
display_keys endp
_key struc
n db 7 dup (0)
x db 0
y db 0
_key ends
nlen equ 6 ; Don't want another field
normal_keys label _key
_key<> ; 0
_key< "Esc", 0, 0 > ; 1
_key< "1", 4, 3 > ; 2
_key< "2", 7, 3 > ; 3
_key< "3", 10, 3 > ; 4
_key< "4", 13, 3 > ; 5
_key< "5", 16, 3 > ; 6
_key< "6", 19, 3 > ; 7
_key< "7", 22, 3 > ; 8
_key< "8", 25, 3 > ; 9
_key< "9", 28, 3 > ; 10
_key< "0", 31, 3 > ; 11
_key< "-", 34, 3 > ; 12
_key< "=", 37, 3 > ; 13
_key< 27, 43, 3 > ; 14
_key< "Tab", 0, 5 > ; 15
_key< "Q", 5, 5 > ; 16
_key< "W", 8, 5 > ; 17
_key< "E", 11, 5 > ; 18
_key< "R", 14, 5 > ; 19
_key< "T", 17, 5 > ; 20
_key< "Y", 20, 5 > ; 21
_key< "U", 23, 5 > ; 22
_key< "I", 26, 5 > ; 23
_key< "O", 29, 5 > ; 24
_key< "P", 32, 5 > ; 25
_key< "[", 35, 5 > ; 26
_key< "]", 38, 5 > ; 27
db 17, "ÄÙ"
org $ - 3
_key< ?, 41, 7 > ; 28
_key< "Ctrl", 0, 11 > ; 29
_key< "A", 6, 7 > ; 30
_key< "S", 9, 7 > ; 31
_key< "D", 12, 7 > ; 32
_key< "F", 15, 7 > ; 33
_key< "G", 18, 7 > ; 34
_key< "H", 21, 7 > ; 35
_key< "J", 24, 7 > ; 36
_key< "K", 27, 7 > ; 37
_key< "L", 30, 7 > ; 38
_key< ";", 33, 7 > ; 39
_key< "'", 36, 7 > ; 40
_key< "`", 1, 3 > ; 41
_key< "Shift", 0, 9 > ; 42
_key< "\", 40, 3 > ; 43
_key< "Z", 7, 9 > ; 44
_key< "X", 10, 9 > ; 45
_key< "C", 13, 9 > ; 46
_key< "V", 16, 9 > ; 47
_key< "B", 19, 9 > ; 48
_key< "N", 22, 9 > ; 49
_key< "M", 25, 9 > ; 50
_key< ",", 28, 9 > ; 51
_key< ".", 31, 9 > ; 52
_key< "/", 34, 9 > ; 53
_key< "Shift", 39, 9 > ; 54
asterisk label byte ; For the matrix
_key< "*", 72, 3 > ; 55
_key< "Alt", 11, 11 > ; 56
_key< "Space", 17, 11 > ; 57
_key< "Caps", 0, 7 > ; 58
_key< "F1", 5, 0 > ; 59
_key< "F2", 8, 0 > ; 60
_key< "F3", 11, 0 > ; 61
_key< "F4", 14, 0 > ; 62
_key< "F5", 18, 0 > ; 63
_key< "F6", 21, 0 > ; 64
_key< "F7", 24, 0 > ; 65
_key< "F8", 27, 0 > ; 66
_key< "F9", 31, 0 > ; 67
_key< "F10", 34, 0 > ; 68
_key< "Num", 64, 3 > ; 69
_key< "Scroll",53, 0 > ; 70
_key< "7", 66, 5 > ; 71
_key< "8", 69, 5 > ; 72
_key< "9", 72, 5 > ; 73
_key< "-", 75, 3 > ; 74
_key< "4", 66, 7 > ; 75
_key< "5", 69, 7 > ; 76
_key< "6", 72, 7 > ; 77
_key< "+", 75, 5 > ; 78
_key< "1", 66, 9 > ; 79
_key< "2", 69, 9 > ; 80
_key< "3", 72, 9 > ; 81
_key< "0", 66, 11 > ; 82
_key< ".", 72, 11 > ; 83
_key< "PrSc", 48, 0 > ; 84 (Actually SysRq - Alt+PrSc)
_key<> ; 85
_key<> ; 86
_key< "F11", 38, 0 > ; 87
_key< "F12", 42, 0 > ; 88
_key<> ; 89
_key<> ; 90
_key<> ; 91
_key<> ; 92
_key<> ; 93
_key<> ; 94
_key<> ; 95
_key<> ; 96
_key<> ; 97
_key<> ; 98
_key<> ; 99
_key<> ; 100
_key<> ; 101
_key<> ; 102
_key<> ; 103
_key<> ; 104
_key<> ; 105
_key<> ; 106
_key<> ; 107
_key<> ; 108
_key<> ; 109
_key<> ; 110
_key<> ; 111
_key<> ; 112
_key<> ; 113
_key<> ; 114
_key<> ; 115
_key<> ; 116
_key<> ; 117
_key<> ; 118
_key<> ; 119
_key<> ; 120
_key<> ; 121
_key<> ; 122
_key<> ; 123
_key<> ; 124
_key<> ; 125
_key<> ; 126
_key<> ; 127
prefix_keys label _key
_key<> ; 0
_key<> ; 1
_key<> ; 2
_key<> ; 3
_key<> ; 4
_key<> ; 5
_key<> ; 6
_key<> ; 7
_key<> ; 8
_key<> ; 9
_key<> ; 10
_key<> ; 11
_key<> ; 12
_key<> ; 13
_key<> ; 14
_key<> ; 15
_key<> ; 16
_key<> ; 17
_key<> ; 18
_key<> ; 19
_key<> ; 20
_key<> ; 21
_key<> ; 22
_key<> ; 23
_key<> ; 24
_key<> ; 25
_key<> ; 26
_key<> ; 27
_key< "Ù", 75, 11 > ; 28
_key< "Ctrl", 40, 11 > ; 29
_key<> ; 30
_key<> ; 31
_key<> ; 32
_key<> ; 33
_key<> ; 34
_key<> ; 35
_key<> ; 36
_key<> ; 37
_key<> ; 38
_key<> ; 39
_key<> ; 40
_key<> ; 41
_key<> ; 42
_key<> ; 43
_key<> ; 44
_key<> ; 45
_key<> ; 46
_key<> ; 47
_key<> ; 48
_key<> ; 49
_key<> ; 50
_key<> ; 51
_key<> ; 52
_key< "/", 69, 3 > ; 53
_key<> ; 54
_key< "PrSc", 48, 0 > ; 55
_key< "Alt", 25, 11 > ; 56
_key<> ; 57
_key<> ; 58
_key<> ; 59
_key<> ; 60
_key<> ; 61
_key<> ; 62
_key<> ; 63
_key<> ; 64
_key<> ; 65
_key<> ; 66
_key<> ; 67
_key<> ; 68
_key<> ; 69
_key< "Pause", 60, 0 > ; 70
_key< "Home", 52, 3 > ; 71
_key< 24, 54, 9 > ; 72
_key< "PgUp", 57, 3 > ; 73
_key<> ; 74
db 27, "Ä"
org $ - 2
_key< ?, 50, 11 > ; 75
_key<> ; 76
db "Ä", 26
org $ - 2
_key< ?, 57, 11 > ; 77
_key<> ; 78
_key< "End", 52, 5 > ; 79
_key< 25, 54, 11 > ; 80
_key< "PgDn", 57, 5 > ; 81
_key< "Ins", 48, 3 > ; 82
_key< "Del", 48, 5 > ; 83
_key<> ; 84
_key<> ; 85
_key<> ; 86
_key<> ; 87
_key<> ; 88
_key<> ; 89
_key<> ; 90
_key< "Win", 6, 11 > ; 91
_key< "Win", 30, 11 > ; 92
_key< "Mnu", 35, 11 > ; 93
_key< "Slp", 48, 7 > ; 94
_key< "Sus", 52, 7 > ; 95
_key<> ; 96
_key<> ; 97
_key<> ; 98
_key< "Wake", 57, 7 > ; 99
_key<> ; 100
_key<> ; 101
_key<> ; 102
_key<> ; 103
_key<> ; 104
_key<> ; 105
_key<> ; 106
_key<> ; 107
_key<> ; 108
_key<> ; 109
_key<> ; 110
_key<> ; 111
_key<> ; 112
_key<> ; 113
_key<> ; 114
_key<> ; 115
_key<> ; 116
_key<> ; 117
_key<> ; 118
_key<> ; 119
_key<> ; 120
_key<> ; 121
_key<> ; 122
_key<> ; 123
_key<> ; 124
_key<> ; 125
_key<> ; 126
_key<> ; 127
end begin
               (
geocities.com/jadoxa)