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?
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 routine—the 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