;=====================================================================
; CLICK.COM clicks the PC's speaker each time a key is pressed.
; Assemble and link with:
;
;	MASM CLICK;
;	LINK CLICK;
;	EXE2BIN CLICK CLICK.EXE
;
; Copyright (c) 1990 Ziff-Davis Publishing Company
;=====================================================================

code	segment	para public 'code'
	assume	cs:code
	org	100h

begin:	jmp	init			;Jump to initialization code

intvec	dd	?			;Old interrupt 09H vector

;---------------------------------------------------------------------
; KBINT intercepts interrupt 09H and calls CLICK when a key is pressed.
;---------------------------------------------------------------------
kbint	proc	far
	pushf				;Save flags
	push	ax			;Save AX
	in	al,60h			;Read scan code
	test	al,80h			;Check for break code
	jnz	exit			;Exit on break
	call	click			;Click on make code
exit:	pop	ax			;Restore AX
	popf				;Restore flags
	jmp	intvec			;Jump to BIOS handler
kbint	endp

;---------------------------------------------------------------------
; CLICK programs the speaker to produce a short click.
;---------------------------------------------------------------------
click	proc	near
	sti				;Interrupts on
	mov	al,0B6h			;Program timer 2 to generate
	out	43h,al			;  pulses
	jmp	short $+2
	mov	al,0			;Send low byte of the 16-bit
	out	42h,al			;  value that will determine
	jmp	short $+2		;  the pulse frequency
	mov	al,6			;Then send the high byte
	out	42h,al
	jmp	short $+2
	in	al,61h			;Speaker on
	jmp	short $+2
	or	al,3
	out	61h,al
	push	cx			;Save CX
	mov	cx,1000h		;Timing delay
here:	loop	here
	pop	cx			;Restore CX
	in	al,61h			;Speaker off
	jmp	short $+2
	and	al,0FCh
	out	61h,al
	ret				;Return to caller
click	endp

;*********************************************************************
; End of resident code -- start of initialization code.  Everything from
; here on is discarded when the program becomes memory-resident.
;*********************************************************************

init	proc	near
	assume	cs:code,ds:code
	mov	ax,3509h		;Get the current interrupt
	int	21h			;  09H vector and store it
	mov	word ptr intvec,bx
	mov	word ptr intvec[2],es
	mov	ax,2509h		;Point interrupt 09H to
	mov	dx,offset kbint		;  the KBINT routine
	int	21h
	mov	dx,offset init		;Use interrupt 27H to
	int	27h			;  terminate and stay
init	endp				;  resident

code	ends
	end	begin
