Zoomer INT 16h example program

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.ASM

;============================================================================
; 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

Send questions, comments, suggestions, more information, or errors to Jeff Lee at <godfrey@shipbrook.net>.