; ; scancode.asm - display key scan codes. ; ; Jason Hood, 4 & 5 June, 1998. ; Public Domain. ; ; 13 July, 1998: rewrote using the Int15 intercept function; ; used LeftShift-LeftCtrl-Esc to exit. ; 30 November, 1998: "b" option to display break codes as well. ; ; 14 October, 2003, v1.00: ; just use either Shift with Esc to exit. ; .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 begin: jmp start db 8, 8, 8 helpmsg db 'Scancode 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 the hexadecimal scancode of each key pressed.',13,10 db 'Add a "b" argument to display the release (break) code.',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 dx,offset intro ;Display an introductory message mov ah,9 int 21h 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 cmp word ptr ds:[81h], 'b ' ;Scancodes only? (include space to jne continue ; prevent garbage from previous inc break ; execution) 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 dl,10 ;Add a blank line (DOS does the CR) call print_char ret ;Finished intro db 'Press Shift+Esc to exit.' db 13, 10, 10, '$' int15 dd 0 ;Original Int15 vector done db 0 ;Termination flag break db 0 ;1 to display break codes 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 xor ah,ah xchg cs: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 cs:prefix,al ;Remember the prefix jmp short exit ; and get out no_prefix: prefixed_code: cmp ax,cs:old_code ;Same as the previous key? je exit ;Yep, get out mov cs:old_code,ax test_escape: ;Test for certain keys cmp ax,ESCAPE jne test_shift or cs:done,esc_on jmp short print_code test_shift: cmp ax,LEFTSHIFT je shift_pressed cmp ax,RIGHTSHIFT jne test_esc_release shift_pressed: or cs:done,shift_on jmp short print_code test_esc_release: cmp ax,ESCAPE RELEASED jne test_shift_release and cs:done,esc_off jmp short print_code test_shift_release: cmp ax,LEFTSHIFT RELEASED je shift_released cmp ax,RIGHTSHIFT RELEASED jne print_code shift_released: and cs:done,shift_off print_code: cmp cs:break,0 jne display_all test al,80h ;Is it a break code? jnz exit ;Yes, don't display it display_all: call ax2hex ;Display the scancode mov dl,' ' ; and separate codes with a space call print_char exit: pop dx ax popf clc ;Ignore the key ret 2 ; and the interrupted flags scancode endp ax2hex proc near or ah,ah ;If there's no prefix... jnz ah2hex push ax mov dl,' ' ;...just display spaces call print_char int 21h pop ax jmp short al2hex ah2hex: push ax mov al,ah call al2hex pop ax al2hex: push ax shr al,4 ;High nibble first call nibble pop ax and al,0fh ;Low nibble second nibble: cmp al,0ah ;From Programming Tips & Tricks sbb al,69h ; Issue 1, "Binary to Hex Conversion" das ; by Tenie Remmel mov dl,al print_char label near mov ah,2 ;DOS service display char in DL int 21h ret ax2hex endp end begin