All pastes #1454268 Raw Edit

Stuff

public text v1 · immutable
#1454268 ·published 2009-06-09 20:16 UTC
rendered paste body
TITLE	kb_handler
DOSSEG

.MODEL	SMALL
.STACK	100h
.DATA
	b_khoff	dw 	?			;Backup keyboard handler offset
	b_khseg	dw 	?			;Backup keyboard handler segment
	b_thoff	dw 	?			;Backup time handler offset
	b_thseg	dw 	?			;Backup time handler segment
	f_stop	db 	0h			;Flag to stop the handler
	f_shcap	db 	00h			;Flag Shift&Caps pressed
	c_time	db 	0h			;Counter time
	buff	db 	0h			;Last Scan Code buffer
	endl	db 	10,13,"$"		;Endline

.CODE
		EXTRN 	scan2a:PROC	;Scan to ascii
					;
	start:	mov 	ax, @DATA	;Initialize
		mov	ds, ax		;DS
		sub 	ax, ax		;Clear ax
		;------------------------
		;Saving Current Keyboard Handler
		;------------------------
		mov	ax, 3509h 	;ah=35:Get handler adress for int 09h (al=09)
		int	21h		;call Dos function
		mov	b_khoff, bx	;Save Handler offset
		mov	b_khseg, es	;Save Handler segment
		;------------------------
		;Saving Current Time Handler
		;------------------------
		mov	ax, 3508h 	;ah=35:Get handler adress for int 08h (al=08)
		int	21h		;call Dos function
		mov	b_thoff, bx	;Save Handler offset
		mov	b_thseg, es	;Save Handler segment
					;
		push	ds		;Saving Current DS
		mov	ax, cs		;
		mov	ds, ax		;DS<-CS
		;------------------------
		;Replacing Keyboard Handler
		;------------------------
		mov	dx, OFFSET KBHANDLER
		mov	ax, 2509h	;ah=25:Set handler adress for int 09h (al=09) at DS:DX
		int	21h		;Call Dos function
		;------------------------
		;Replacing Time Handler
		;------------------------
		mov	dx, OFFSET TMHANDLER
		mov	ax, 2508h	;ah=25:Set handler adress for int 08h (al=08) at DS:DX
		int	21h		;Call Dos function
		;------------------------
		pop	ds		;Restoring ds
		;------------------------
	main:	mov	cl, f_stop	;Check if Stop pressed
		cmp	cl, 1h		;1h=Stop program
		jne	main		;Loop
		;------------------------
	term:	;Restoring DOS Keyboard Handler
		;------------------------
		push	ds		;Saving Current DS
		mov	dx, b_khoff	;DX<-Default handler Offset
		mov	ds, b_khseg	;DS<-Default handler Segment
		mov	ax, 2509h	;ah=25:Set handler adress for int 09h (al=09) at DS:DX
		int	21h		;Call Dos function
		pop	ds		;Restoring ds
		;------------------------
		;Restoring DOS Time Handler
		;------------------------
		push	ds		;Saving Current DS
		mov	dx, b_thoff	;DX<-Default handler Offset
		mov	ds, b_thseg	;DS<-Default handler Segment
		mov	ax, 2508h	;ah=25:Set handler adress for int 08h (al=08) at DS:DX
		int	21h		;Call Dos function
		pop	ds		;Restoring ds	
		;------------------------
		;End program	
		;------------------------
		mov 	ax, 4C00h	;Dos END program arg
		int 	21h		;Call function


;----------------------------------------
;The Keyboard Handler proccess

	KBHANDLER proc far		;Handlers are FAR processes
		push	ds		;
		push	ax		;Saving the registers
		push	bx		;which we ll use
		push	cx		;
		push	dx		;
		;------------------------
		;Preparations
		;------------------------
		mov 	ax, @DATA	;Initialize DS
		mov	ds, ax		;we ll use DATA segment
		sub 	ax, ax		;Clear ax
					;
		sti			;Set Interrupt Flag (Enable Interrupts)
		;------------------------
		;THE HANDLER code
		;------------------------
	handle:	in 	al, 60h		;Read Scan Code (port 60h=kb)
					;
		call	CHECK		;Checking the code
		cmp	ah,00h		;if Didnt pass the check
		je	skip		;Skip the procedure
		;------------------------
		;Cheking for special keys
		;------------------------
		cmp	al, 1h		;Escape key press
		je	escape		;
		cmp	al, 2Ah		;Shift key press
		je	shiftp		;
		cmp	al, 10101010b	;Shift key release
		je	shiftr		;
		cmp	al, 3Ah		;Caps key press
		je	capsp		;
		cmp	al, 1Ch		;Enter key press
		je	enter		;
		cmp	al, 80h 	;Code of Release key, if above, ignore
		jae	skip		;skips procedure
		;------------------------
	conv:	push	ax		;Saving Scan code
		mov	dl, al		;Parameters Scancode
		mov	al, f_shcap	;Caps etc
		call	scan2a		;Convert to ascii
		;------------------------
		mov	dl, al		;Giving the ascii as argument
		mov	ah, 02h		;Print letter
		int	21h		;Call function
		;------------------------
		pop	ax		;Restore scan code
		;------------------------
		;Saving cursor position
		;------------------------
		mov	ah, 03h		;"Get Cursor"
		mov	bh, 0		;"Display page"
		int	10h		;Call the function
		push	dx		;Saving Coors
		;------------------------
		;Going to the corner
		;------------------------
		mov	ah, 02h		;"Set Cursor position"
		mov	bh, 0		;"Display page"
		mov	dh, 0		;"Row"
		mov	dl, 78		;"Column"
		int	10h		;Call function
		;------------------------
		;al remained untouched, it has the Scan code
		;------------------------
		mov	dx, ax		;Disphex arg
		call	Disphex		;Printing Scan code
		;------------------------
		pop	dx		;Restoring Cursor pos 
		mov	ah, 02h		;Set Cursor Position
		mov	bh, 0		;Display page
		int	10h		;Call funtion
		;------------------------
		cmp	dl, 80d		;Check if EndOfLine
		jne	skip		;Finish procedure
	enter:	lea	dx, endl	;Change Line
		mov	ah, 09h		;
		int	21h		;
		;------------------------
	skip:	mov	al, 20h		;Signal to stop Handle
		out	20h, al		;
		;------------------------
		pop	dx		;
		pop	cx		;Restoring Used
		pop	bx		;Registers
		pop	ax		;
		pop	ds		;
		iret			;IRET
		;------------------------
		;Special Keys
		;------------------------
	escape: mov	cl, 1h		;
		mov	f_stop, cl 	;Flag to terminate handler
		jmp	skip		;goto end
		;------------------------
	shiftp:	push	ax		;Saving
		mov	al, f_shcap	;
		or 	al, 00000001b	;Parameters
		mov	f_shcap, al	;
		pop	ax		;Restore
		jmp	skip		;goto end
		;------------------------
	shiftr:	push	ax		;Saving
		mov	al, f_shcap	;
		and 	al, 11111110b	;Parameters
		mov	f_shcap, al	;
		pop	ax		;Restore
		jmp	skip		;goto end
		;------------------------	
	capsp:	push	ax		;Saving
		mov	al, f_shcap	;
		mov	ah, al		;
		not	ah		;Switch all bits
		and 	ah, 00000010b	;Keep the 2nd bit of ah
		and	al, 11111101b	;Keep all others of al as they were
		add	al, ah		;add the 2nd bit of ah
		mov	f_shcap, al	;pass the arg.
		pop	ax		;Restore
		jmp	skip		;goto end
		;------------------------
	KBHANDLER endp


;----------------------------------------
;The Time Handler proccess

	TMHANDLER	proc	far	;Handlers are FAR processes
		push	ds		;Saving the registers
		push	ax		;which we ll use
		;------------------------
		;Preparations
		;------------------------
		mov 	ax, @DATA	;Initialize DS
		mov	ds, ax		;we ll use DATA segment
		sub 	ax, ax		;Clear ax
		;------------------------
		inc	c_time		;Increase the counter
		;------------------------
		mov	al, 20h		;Signal to stop Handle
		out	20h, al		;
		;------------------------
		pop ax			;Restoring the
		pop ds			;registers
		iret			;IRET
	TMHANDLER endp

;----------------------------------------
;The CHECK proccess 	Checks if same scan code and for how long pressed
;			and lets Or not the character to pass to the handler

	CHECK	proc	near
	;Input: 	al : scan code
	;Output: 	ah : 1h to continue or 0h not to
		cmp	al, buff 	;Compare Scan code and Last scan code
		je	stp2 		;If equal, check time pressed
		jmp 	succ 		;Else, pass
		;------------------------
	stp2:	mov 	ah, c_time	;Check Time that its pressed
		cmp 	ah, 09h		;
		jae 	succ 		;If >9 pass
		;------------------------
	fail:	mov 	ah, 00h 	;Failure
		retn			;Ending
	succ:	mov	buff, al 	;Refreshing "buff" to the new Scan code
		mov	c_time,00h 	;Refreshing timer (to 0)
		mov	ah, 01h		;Success
		retn 			;Ending
	CHECK 	endp


;----------------------------------------
;The disphex function

	DispHex PROC NEAR
	
	; Displays two hex digits
	
	; Input:  Byte to be displayed in DL (An integer mn)
	; Output: None
	; Uses:   AX, CL, DX
	
		push	ax
		push	cx
		push	dx	
	
		mov cl, 4
		xor dh, dh	; DX = 00mn
		ror dx, cl	; DX = n00m
		ror dh, cl	; DX = 0n0m
		add dx, 3030h	; Convert m and n to ASCII (ASCII of "0" is 30h)
	
		cmp dl, "9"	; if m>9 ...
		jbe disp1
		add dl, 7	; ...then add 7 (ASCII of "A" is 41h = 3Ah + 7)
	disp1:	mov ah, 2
		int 21h		; Display m
	
		mov dl, dh	; Do the same for n
		cmp dl, "9"
		jbe disp2
		add dl, 7
	disp2:	int 21h
	
		pop	dx
		pop	cx
		pop	ax
		
		ret
	
	DispHex ENDP

	end start