		.MODEL tiny
		.CODE
		.STARTUP
  
		jmp begin

old_int13h_off  dw 0  ; Адрес старого обработчика
old_int13h_seg  dw 0  ; прерывания 13h

old_int2Fh_off  dw 0  ; Адрес старого обработчика
old_int2Fh_seg  dw 0  ; прерывания 2Fh

; Новый обработчик прерывания 2Fh нужен
; для проверки наличия программы в памяти
; при ее запуске для предохранения
; от повторного запуска

new_int2Fh  proc  far
		cmp   ax,0FF00h
		jz    installed

		jmp   dword ptr cs:old_int2Fh_off

; Если код функции 0FF00h, то возвращаем
; в регистре AX значение 00FFh. Это признак
; того, что программа уже загружена в память

installed:
		mov   ax,00FFh
		iret

new_int2Fh  endp

; Новый обработчик прерывания 13h. Для команд записи
; на жесткий диск выполняет проверку содержимого
; компоненты смещения вектора прерывания FFh.
; Эта ячейка служит для триггерного переключения
; режима работы прерывания 13h - включения/выключения
; защиты записи.

new_int13h  proc  far

		cmp   ah,3 ; запись сектора
		je protect
		cmp   ah,5 ; форматирование трека
		je protect
		jmp   dword ptr cs:old_int13h_off

old_int13h:

		pop   es
		pop   bx
		pop   ax

		jmp   dword ptr cs:old_int13h_off

protect:

		push  ax
		push  bx
		push  es

; Проверяем значение триггерного флага защиты

		xor   ax,ax
		mov   es,ax
		mov   bx,0F0h*4
		mov   ax,WORD PTR es:[bx]
		cmp   ax,0FFFFh

		jne   old_int13h

; Для флоппи-дисков защиту не включаем

		cmp   dl,0
		je old_int13h
		cmp	dl,1
		je old_int13h

		pop   es
		pop   bx
		pop   ax

; Имитируем ошибку записи при попытке
; записать данные на защищенный от записи диск

		mov   ah,3
		stc
		ret 2

new_int13h  endp
  
;==============================

; Точка входа в программу

begin proc  far

; Проверяем, не загружена ли уже программа
; в память

		mov   ax,0FF00h
		int   2Fh

		cmp   ax,00FFh
		jne   first_start

		jmp   invert_protect_flag

; Первоначальный запуск программы

first_start:

; Устанавливаем триггерный флаг защиты записи
; в состояние, соответствующее включенной защите

		xor   ax,ax
		mov   es,ax
		mov   bx,0F0h*4
		mov   WORD PTR es:[bx],0FFFFh

; Запоминаем адрес старого обработчика прерывания 13h

		mov   ax,3513h
		int   21h
		mov   cs:old_int13h_off,bx
		mov   cs:old_int13h_seg,es

; Запоминаем адрес старого обработчика прерывания 2Fh

		mov   ax,352Fh
		int   21h
		mov   cs:old_int2Fh_off,bx
		mov   cs:old_int2Fh_seg,es


		push  cs
		pop	ds

; Выводим сообщение о включении защиты

		mov   dx,offset msg_on
		mov	ah,9
		int   21h

; Устанавливаем новые обработчики прерываний 13h и 2Fh

		mov   dx,OFFSET new_int13h
		mov	ax,2513h
		int   21h

		mov   dx,OFFSET new_int2Fh
		mov   ax,252Fh
		int   21h

; Завершаем программу и оставляем резидентно
; в памяти часть программы, содержащую новые
; обработчики прерываний

		mov   dx,OFFSET begin
		int   27h

; Если это не первый запуск программы,
; инвертируем содержимое триггерного флага защиты

invert_protect_flag:

		xor   ax,ax
		mov   es,ax
		mov   bx,0F0h*4

		mov   ax,WORD PTR es:[bx]
		not   ax
		mov   WORD PTR es:[bx],ax
		mov   cx,ax

		cmp   cx,0FFFFh
		je prot_on

; Выводим сообщение о выключении защиты

		mov   dx,OFFSET msg_off
		jmp   short send_msg

prot_on:

; Выводим сообщение о включении защиты

		mov   dx,OFFSET msg_on
send_msg:
		mov	ah,9
		push	cs
		pop	ds
		int   21h

		.EXIT

begin endp

msg_on      db 'Защита диска включена$'
msg_off     db 'Защита диска ВЫКЛЮЧЕНА$'

		end
