data segment public
start_message: db 'reset no longer possible',0dh,0ah,'$'
buffer:   db 40d                ;length of input buffer
          db 40 dup (0)         ;buffer
old_int9  dd 0                  ;old interrupt handler
data ends

code segment public
assume cs:code,ds:data
handler9 proc near              ;new interrupt 9 handler
  push ax                       ;store used register
  push bx
  push ds
  push es
  mov ax,data                   ;load ds
  mov ds,ax

  in al,60h                     ;read characters from keyboard in al

  xor bx,bx                     ;es to segment 0
  mov es,bx
  mov bl,byte ptr es:[417h]     ;load keyboard status in bl

  cmp al,83d                    ;scan code of  Del key ?
  jne no_reset                  ;no, then no reset

  and bl,0ch                    ;mask Ctrl and Alt
  cmp bl,0ch                    ;both pressed ?
  jne no_reset                  ;no, then no reset

block:                          ;reset or break, so block
  mov al,20h                    ;send EoI to interrupt controller
  out 20h,al
  jmp finished                  ;and exit interrupt

no_reset:                       ;no reset, now check Break
  cmp al,224d                   ;extended key ?
  je poss_Break                 ;yes -> Break possibly triggered
  cmp al,46d                    ;'C' key ?
  jne legal                     ;no -> legal key
poss_Break:
  test bl,4                     ;test keyboard status for Ctrl
  jne block                     ;pressed, then block


legal:                          ;legal key -> call old handler
  pushf
  call dword ptr [old_int9]     ;call original handler
finished:
  pop es
  pop ds                        ;get back register
  pop bx
  pop ax
  iret
handler9 endp

start proc near
  mov ax,data                   ;load ds
  mov ds,ax
  mov dx,offset start_message   ;load dx with offset of message
  mov ah,09h                    ;output message
  int 21h

  mov ax,3509h                  ;read old interrupt vector
  int 21h
  mov word ptr old_int9,bx      ;and store
  mov word ptr old_int9 + 2, es

  push ds                       ;store ds
  mov ax,cs                     ;load with cs
  mov ds,ax
  mov dx,offset handler9        ;load offset of handler also
  mov ax,2509h                  ;set vector
  int 21h
  pop ds

;-------------------------------------------------------------------------
;instead of the DOS call, you can also call your main program here

  mov ah,0ah                    ;input character string
  lea dx,buffer                 ;as sample main program
  int 21h
;-------------------------------------------------------------------------

  push ds
  lds dx,old_int9               ;set old vector again
  mov ax,2509h
  int 21h
  pop ds

  mov ax,4c00h                  ;end program
  int 21h
start endp

code ends
end start
