cseg  segment 'code'
assume cs:cseg,ds:cseg,es:cseg
org   100h
;
  start: 
lea   dx,help
mov   ah,9
int   21h
lea   dx,line
int   21h
mov   bx,4
xor   bp,bp

  key:
mov   ah,11h       
call  int16        ;check keyboard buffer
jz    key          ;no key pressed
cmp   ax,011bh     ;ESC?
je    quit         ;yes

lea   di,buff
call  wan          ;keybuffer output
mov   cl,' '
mov   sym,cl
cmp   al,0E0h      ;extended marker?
je    fkt_11       ;yes
or    al,al        ;no symbol?
je    fkt_11       ;yes
mov   sym,al       ;use symbol otherwise

  fkt_11:
mov   ah,11h
int   16h          ;extended report
lea   di,fkt11
call  wan          ;output

lea   di,fkt1
mov   ax,'  '
mov   [di],ax
mov   [di+2],ax
mov   ah,1       
int   16h          ;normal report
jz    print        ;nothing reported
call  wan          ;output otherwise

mov   ah,10h
call  int16        ;trough away key

  print:
lea   dx,scan
mov   ah,9 
int   21h          ;output one line
jmp   short key    ;loop endless

  quit:
lea   dx,line
mov   ah,9
int   21h
lea   dx,logo
int   21h
mov   ah,4ch       ;quit
int   21h

;---SUBROUTINE INT16------------------------------

;simulates INT16 interrupt bypassing light sleep.

;input:  ah=10h: wait for keypress (ax=scancode)
;        ah=11h: report if char is available
;                output: zf=0 scancode in ax
;                        zf=1 no key pressed
  int16:
push  bx
push  cx
push  es
mov   bx,40h
mov   es,bx
 int16_1:
mov   bx,es:[1ah]
cmp   bx,es:[1ch]
jne   int16_2
cmp   ah,11h
jne   int16_1
jmp   short int16_e
 int16_2:
mov   cx,es:[bx]
cmp   ah,10h
mov   ax,cx
jne   int16_e
add   bx,2
cmp   bx,es:[82h]
jb    int16_3
mov   bx,es:[80h]
 int16_3:
mov   es:[1ah],bx
 int16_e:
pop   es
pop   cx
pop   bx
ret

;---SUBROUTINE WAN--------------------------------

;store ax as [base] number with bx digits at es:di

;input: ax = number to convert
;       bx = number of output digits
;       di = start of output string
;       bp = 0: leading zeros, 1: leading blancs
;     base = 2,8,10 or 16 

  wan:
push   ax
push   bx
push   cx
push   dx
push   bp
push   si

push   di
xor    cx,cx
mov    cx,bx
  wan_1:
xor    dx,dx
div    base
push   dx
loop   wan_1
mov    cx,bx
  wan_2:
pop    ax
add    al,'0'
cmp    al,'9'
jna    wan_3
add    al,7
  wan_3:
stosb
loop   wan_2
pop    si
or     bp,bp
je     wan_e
  wan_4:
mov    cx,bx
dec    cx
jle    wan_e
  wan_5:
lodsb
cmp    al,'0'
jne    wan_e
mov    byte ptr [si-1],' '
loop   wan_4
  wan_e:
pop    si
pop    bp
pop    dx
pop    cx
pop    bx
pop    ax
ret

base   dw 16

;-------------------------------------------------

help  db 10,13
      db 'Press any key to see the scancode in HEX, press ESC to quit',10,13,'$'
line  db 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ',10,13,'$'
logo  db 'SCANCODE Ver1.0      (c) 1999 Stefan Peichl      Heidelberg',10,13,'$'
      db '             '
scan  db 'keybuffer: '                      
buff  db '       '
      db 'Int16-ext: '
fkt11 db '       '
      db 'Int16: '
fkt1  db '       '
      db 'Symbol: '
sym   db ' ',10,13,'$'

cseg  ends
      end start

