[comp.sys.ibm.pc] Making BREAK = ON more powerful

mcdonald@uxe.cso.uiuc.edu (09/06/87)

A recent poster asked how to stop a process with <cntl>break while it
is doing no IO at all, like maybe it was doing a long calculation.
I have solved this by writing the following TSR routine, which you put
into your autoexec.bat file along with BREAK = ON.
    It is to be assembled woth MASM and then it MUST be converted to
a .COM file with EXE2BIN.

...............cut here..................................................

	;Resident program to enable cntl-break even if no DOS call is made
	;This is done by doing a dummy DOS call when break key is let up
	;THIS WON'T WORK WITHOUT DOING A break on STATEMENT IN DOS
	;If cntl-break fails you may try CNTL-ALT-4 (the 4 on the top row)
	;which is somewhat more powerful. If you break out of BASIC this way
	;the NEXT time BASIC is run, it will hang, requiring a reboot
	;Other programs (games?) may or may not respond. If they do respond,
	;they may hang up DOS. 
cseg	segment para public 'code'
	org	100h
BREAKL	proc far
	assume cs:cseg,ds:cseg	
	jmp install		;this installation code used only once
oldint9	dd	0		;storage for old int 9 vector
int9loc	equ	9h*4		;location of int 9
kbflag	equ	417h		;keyboard "held down" status address
ctrl	equ	04		;bit in kbflag for cntl
alt	equ	08		;bit in kbflag for alt
brkup	equ	0c6h		;scan code for release of scroll lock
cntl4   equ     05h		;scan code for 4
newint9:			;comes here from the hardware int 9
	sti			;restart interrupt
	push	es		;save registers
	push	di
	push	ax
	push	cx
	push	dx
	pushf
	mov	ax,0		;get cntl and alt status into ah
	mov	es,ax
	mov	di,kbflag
	mov	ah,es:[di]
	test	ah,ctrl		;test for cntl held down
	jz	return		;if cntl is up, go to previous handler code
	in	al,60h		;get scan code into al
	cmp	al,brkup	;if not release of scroll lock or...
	je	doit
	cmp	al,cntl4	;4 key, go to previous code
	jne	return
	test	ah,alt		;if alt not down with cntl-4
	jz	return		;go to previous code

doit:
	mov	cl,al		;put a pulse in interrupt port
	in	al,61h		;for some obscure reason
	mov	ah,al		;copied form BIOS listing
	or	al,80h
	out	61h,al
	mov	al,ah
	out	61h,al

	cli			;stop interrupt
	mov	al,20h		;clear keyboard
	out	20h,al

	sti			;restart interrupts

	cmp	cl,cntl4	;test for cntl-alt-4
	je	fun4c		;if it is cntl-alt-4 go to code for that
	mov	ah,19h		;DOS func call for read default disk. This
	int	21h		;is a dummy call to make DOS look for break
	popf			;restore registers in case DOS break 
	pop	dx		;didn't work
	pop	cx
	pop	ax
	pop	di
	pop	es
	iret			;this may never be used

fun4c:
	mov	al,01h		;error code for cntl-break
	mov	ah,4ch		;DOS func call to terminate program
	int	21h
	iret

return:	
	popf			;this code simply passes control to the
	pop	dx		;keyboard handler present before this 
	pop	cx		;resident program was loaded
	pop	ax
	pop	di
	pop	es
	jmp	cs:[oldint9]	;this jump doesn't change stack
install:
	mov	ax,0		;get old int 9 vector into 
	mov	es,ax
	mov	di,int9loc
	mov	ax,es:[di]	;ax and bx
	mov	bx,es:[di+2]
	mov	si,offset oldint9	;then put them into
	mov	[si],ax		;location "oldint9" in this program
	mov	[si+2],bx
	mov	ax,0
	mov	es,ax	
	mov	bx,ds
	cli			;stop inteppupts
	mov	di,int9loc		;put pointer to this program into
	mov	ax,offset newint9	;int 9 vector
	mov	es:[di],ax
	mov	es:[di+2],bx
	sti			;restore interrupts												
	mov	dx,offset install	;don't keep the install code
	int	27h		;terminate and stay resident
BREAKL	endp
cseg	ends
end	BREAKL

...........................cut here...........................

Doug McDonald


A