TITLE KEYBOARD --- Keyboard I/O test 
;  and prints out scan code and ASCII of any key
;-----------------------------------------------------
display	equ	2h	;display character fuc
doscall	equ	21h	;DOS interruot routine
;-----------------------------------------------------
data 	segment
mess	db	0dh,0ah,'    SCAN  ASCII  CHAR$'
mess1	db	'     $'
data 	ends
;-----------------------------------------------------
stack   segment  para stack 'stack'
	db 64 dup (?)
stack	ends
;*****************************************************
pro_nam	segment			;define code segment
;-----------------------------------------------------
main	proc	far		;main part of program
	assume	cs:pro_nam, ds:data
start:
	push	ds
	xor	ax,ax
	push	ax

	mov	ax,data
	mov	ds,ax

        mov	dx,offset mess
	mov	ah,9h
	int	doscall	  ;print title of output table

	mov	dl,0dh		;print CR
	mov	ah,display
	int	doscall

	mov	dl,0ah		;print LF
	mov	ah,display
	int	21h
again:	
	mov	ah,0		;read character funct
	int	16h		;keyboard I/O ROM call
	cmp	al,03h		;is ctrl_C ?
	jz	exit		;yes,exit
	
	mov	bx,ax		;move scan & char to BX
	call	binihex		;print scancode & char
	mov	dx,offset mess1    ;print space
	mov	ah,9h
	int	doscall

	mov	dl,bl		;print character
	mov	ah,display	;  in ASCII
	int	doscall
	mov	dl,0dh		;print return
	mov	ah,display
	int	doscall
	mov	dl,0ah		;print linefeed
	mov	ah,display
	int	doscall

	jmp	again		;get another one
exit:	ret		;return form program to DOS
main	endp		;end of main part of program
;-----------------------------------------------------
binihex	proc	near
;subroutine to convert binnary in BX
;  to hex on console screen
	mov	ch,4	         ;number of digits
rot1:
	push	ax 
	mov	dx,offset mess1  ;print 5 blanks between
	mov	ah,9h		 ;  each two columns
	int	doscall
	pop	ax
rotate:	mov	cl,4		;set count to 4 bits
	rol	bx,cl		;left digit to right
	mov	al,bl		;move to AL
	and	al,0fh		;mask off left digit
	add	al,30h		;convert hex to ASCII
	cmp	al,3ah		;is it > 9?
	jl	printit		;no,so 0 to 9 digit
	add	al,7h		;yes,so A to F digit
printit:
	mov	dl,al		;put ASCII char in DL
	mov	ah,display	;display output funct.
	int	doscall		;call DOS
	dec	ch	
	cmp	ch,2    	;done 2 digits?
	jg	rotate		;not yet
	jz	rot1
	cmp	ch,0    	;done 4 digits?
	jnz	rotate
	ret			;done subroutine
binihex endp
;-----------------------------------------------------
pro_nam ends			;end of code segment
;*****************************************************
	end	start   	;end assembly
 
