Classic Computer Magazine Archive COMPUTE! ISSUE 86 / JULY 1987 / PAGE 8

Disabling Control-Break On IBM PC And Clones

I have an IBM PCjr and I want to turn off the Fn-Break key combination so the machine ignores a break. Can you provide an assembly language routine to do this?

Kevin Neil

Like most IBM PC operating system functions, the Control-Break function (Fn-Break on the PCjr) is controlled by an interrupt service routine. Briefly, an interrupt occurs when a special pin on the microprocessor receives a signal. At this point, the computer ceases execution of the program it is running, and a support chip feeds it the ROM address of the appropriate machine language subroutine which it then executes. This routine ends with an IRET (RETurn from Interrupt) instruction. After it performs IRET, the processor returns to running the original program.

Every keypress on an IBM PC causes such an interrupt. Normally, the computer decodes the keypress and places its ASCII value in the keyboard buffer for use by the program currently running. However, an interrupt caused by Control-Break executes a special interrupt service routinethe effects of which are known to anyone who has ever pressed the Control-Break key combination.

One advantage of using interrupts is that you can change the address of the service routine. This allows a program to divert the address of a service routine to its own, custom-tailored routine. If you replace the address of the Control-Break service routine with the address of another routine, that routine executes every time Control-Break is pressed. The BASIC interpreter itself makes such a change when it loads, changing the Control-Break routine to a routine which breaks the operation of a BASIC program.

The easiest way to disable Control-Break is to divert the address of the Control-Break routine to a do-nothing routine that contains nothing but an IRET instruction. While IRETs abound in the ROM, the exact addresses where they may be found vary depending on the ROM and DOS version and the make of the computer. It is safest to put an IRET in memory, and to point Control-Break to this instruction. The following BASIC program changes the address of the service routine (located at $006C-$006F) to point to an IRET instruction which it places at address $0180, a normally unused location.

0 DEF SEG=0	'SET TO 0
SEGMENT
10 POKE &H180, &HCF	'POKE 180
WITH MACHINE INSTRUCTION FO
R IRET
20 POKE &H6C, &H80	'LOW BYTE
OF 180
30 POKE &H6D, &Hl	'HIGH BYTE
OF 180
40 POKE &H6E, 0	'0'S FOR
SEGMENT
50 POKE &H6F, 0
60 FOR I = 1 TO 1000:PRINT I:NEXT
'TRY AND BREAK IT

Here is an assembly language routine that does the same thing. It uses DOS service call $25 to change the address of the Control-Break interrupt $1B:

MOV AX, 0
MOV DS, AX	;	SET DATA SEG READ-WRITE TO 0
MOV BX, 0180h	;	CHANGE LOCATION 180h
MOV AX, 0CFh	;	TO OPCODE FOR IRET
MOV [BX], AX	;
XCHG BX, DX	;	DOS NEEDS LOCATION FOR IRET IN DX
MOV AH, 025h	;	SETUP FOR DOS INTERRUPT CHANGING SERVICE 25h
MOV AL, 01Bh	;	INTERRUPT NUMBER TO BE CHANGED
INT 21h	;	DOS INTERRUPT
INT 20	;	RETURN TO DOS