The following example program shows the use of many of the functions available through the INT 16 BIOS service. The program displays everything passed to it via the command line, instructs the user to press the A or B button, and returns an errorlevel to DOS which reflects the choice made by the user.
;============================================================================ ; ASK.COM - DOS-mode batch file enhancer for Zoomer-class PDAs ; ; Author: Jeff Lee ; Date: 30 July 1995 ; Assembler: Microsoft Assembler (MASM) v3.00 ; ; After assembly and linking, convert to a .COM file with EXE2BIN. ; ;---------------------------------------------------------------------------- @SetHandler macro _segment, _offset pushf push dx push cx mov dx, _segment mov cx, _offset call SetKbdProc pop cx pop dx popf ENDM code segment byte public 'CODE' .radix 16 org 0100h assume cs:code, ds:code, es:code begin: jmp start savedata dw 0 OldKbdSeg dw 0 OldKbdOfs dw 0 result dw 0 Question db 0dh, 0a, 'Press A for yes, B for no: $' Yes db 'Yes', 0dh, 0a, '$' No db 'No', 0dh, 0a, '$' FirstInit proc near mov ax, 5001 xor bh, bh int 16h mov savedata, bx ret FirstInit endp GetKbdProc proc near mov ax, 5003h ; Get/set keyboard handler xor bh, bh ; BH = 0 : get address int 16h ; Call BIOS routine mov OldKbdSeg, dx ; Old address segment mov OldKbdOfs, cx ; Old address offset ret ; Return from procedure GetKbdProc endp ; Call with dx:cx as the segment:offset of the new handler. ; SetKbdProc proc near mov ax, 5003 ; Get/set keyboard handler mov bh, 01 ; BH = 1 : set address int 16 ; Call BIOS routine ret ; Return from routine SetKbdProc endp FinalInit proc near mov ax, 5001 mov bx, 0101 int 16 ret FinalInit endp NewHandler proc far or al, al ; Anything in AL? je nhend ; If not, just ignore it... push ds ; Save registers mung'd. push dx ; mov dx, cs ; Put CS into the DS register mov ds, dx ; mov result, ax ; Store the result. pop dx ; Restore registers mung'd. pop ds ; nhend: ret ; Return from handler. NewHandler endp ;---------------------------------------------------------------------------- ; Main program starts here. ;---------------------------------------------------------------------------- start: mov ax, cs ; set Data/Extra segments to the mov ds, ax ; code segment. mov es, ax mov di, 82h ; Point DI at the command line text xor ch, ch ; Clear out high byte of CX mov cl, [di-2] ; CX = length of command line or cl, cl ; Is there a command line? jz endprint ; If not, don't print it! print: mov dl, [di] ; Get a character to output to screen mov ah, 2 ; display a character int 21 ; Call the DOS interrupt inc di ; Point at next character of cmdline loop print ; Go back for more. endprint: mov ah, 9 ; Print the "Press A for yes..." mov dx, offset question ; message. int 21 call FirstInit ; Don't know what it does yet. call GetKbdProc ; Get old keyboard handler @SetHandler cs,<offset NewHandler> ; Set new kbd handler call FinalInit ; Don't know what it does yet. WaitForResponse: xor ax, ax ; Clear out AX mov result, ax ; Store it in the result variable WaitLoop: cmp result, 0 ; Something in "result"? je WaitLoop ; No, so loop back mov ax, result ; Yes, so get the value and al, 3 ; Mask out all but A/B bits cmp al, 2 ; Is it A? je GotYes ; Yes, so handle that. cmp al, 1 ; Is it B? je GotNo ; Yes, so handle that. jmp WaitForResponse ; Got neither (or both); go back. GotYes: mov dx, offset Yes ; Print "Yes" for feedback. xor al, al ; Return zero (0) for Yes response. jmp Finish ; Go to exit code. GotNo: mov dx, offset No ; Print "No" for feedback. mov al, 1 ; Return one (1) for No response. Finish: push ax ; Save exit code mov ah, 09 ; Print the feedback message. int 21h stc ; (Not entirely sure why...) @SetHandler OldKbdSeg, OldKbdOfs ; Restore old kbd handler pop ax ; Get exit code mov ah, 4c ; Exit. int 21 code ends end begin