public function EINT_16H as boolean : result=true : dim w as word

//DEBUG.ON 'uncomment to enable debug messages (can be slow for hi-freq events)

 ?? "INT 16H AH=";Hex(cpu.AH);"h"

select case true

'*****************************************************************************
'* INT 16H AH=00h,10h (BIOS) WAIT KEY IN BUFFER
'* Params: -
'* Result: AL - scancode
'*         AH - ASCII code
'*****************************************************************************

case (cpu.AH=0) or (cpu.AH=0x10) 'waiting hardcoded in int 16h handler

 'Read keyboard buffer start address from BIOS data area (40h:1Ah..1Bh)
  w=mem.Word(0x41A) 

 'Compare it with buffer tail and exit if no key available
 if w=mem.Word(0x41C) then exit
 
 'Read scan and ASCII code from buffer to AX
 cpu.AX=mem.Word(w)

 'Increment keyboard buffer start address and store it
 w=w+2 : if w>=0x43D then w=0x41E : mem.Word(0x41A)=w 

'*****************************************************************************
'* INT 16H AH=01h,11h (BIOS) CHECK KEY IN BUFFER
'* Params: -
'* Result: ZF - set if no key, clear if key available
'*         AL - scancode
'*         AH - ASCII code
'*****************************************************************************

case (cpu.AH=1) or (cpu.AH=0x11) 'without waiting

 'Read keyboard buffer start address from BIOS data area (40h:1Ah..1Bh)
 w=mem.Word(0x41A) 

 'Compare it with buffer tail and exit if no key available
 if w=mem.Word(0x41C) then : cpu.FLAGS.ZF=true : ?? "NO" : exit : end if
 
 'Read scan and ASCII code from buffer to AX (without increment)
 cpu.AX=mem.Word(w) : cpu.FLAGS.ZF=false : ?? "YES"

'*****************************************************************************
'* INT 16H AH=02h (BIOS) READ CONTROL KEYS STATE
'* Params: -
'* Result: AL - state byte
'*****************************************************************************

case (cpu.AH=2) 'without waiting

 'Read state byte from BIOS data area (40h:17h)
 cpu.AL=mem.Byte(0x417)

case else : result=false : end select : end function
