;_—-== ДАННЫЕ ==—-
old_1Ch dw 2 dup(?) ; вектор 1Ch
cur_pos dw 1680 ;начальный адресс в видеопамяти
ev_len db 0 ;ближайшее четное число для mes_long
message db 50 DUP (0) ;сюда поместим сообщение
db ‘$’
count dw 0
clck dw 0
mes_off dw offset message ;смещение выводимой строки
mes_long db 0 ;длина сообщения
attrib db 79
tim dw ?
set_msg db ‘Новое время установлено’,13,10,’$’
titl db ‘Резидентная программа — будильник’,13,10,’$’
inv_msg db ‘Неверная командная строка.’,13,10,’Использование: hs!alarm [r] <hh:mm> [message]’,13,10
db ‘ где hh — часы, mm — минуты’,13,10
db ‘ message — сообщение’,13,10
db ‘ r — выгрузить будильник из памяти’,13,10
db ‘Пример: hs!alarm 12:00 Время пить херши’,13,10,’$’
remove_msg db ‘Программа успешно выгружена из памяти…’,13,10,’$’
nim_msg db ‘Будильник не загружен’,13,10,’$’
savescr dw 240 dup(0)
;_____________________________________________________________________________
;_—-== ИНИЦИАЛИЗАЦИЯ ==—-
init:
@DisStr titl ;заголовок
;_——== Проверка командной строки на время ==——
mov SI,80h ;PSP — коммандная строка,размер
mov CH,0
mov CL,[SI] ;дать длину
; cmp CL,1
; jle inv_time
jcxz inv_time
call com_time ;данные из командной строки запоминаются там, где надо
jnc no_probl
cmp dl,’r’ ;выкинуть нас из памяти ?
je remove_from_mem
jmp inv_time
no_probl:
;_——== Поймаем прерывание ==——
mov AX,351Ch ;поймаем 1Ch прерывание;
int 21h
cmp bx,offset int_1Ch ;мы уже есть в памяти ?
jne set_resid
;_—-== Установим новое время ==—-
mov ax,ds:tim ;получим новое время
mov es:tim,ax ;установим его
mov ax,ds:count ;количество символов
mov es:count,ax
mov al,ds:mes_long
mov es:mes_long,al
cld ;двигаемся вперед
lea si,ds:message ;откуда
lea di,es:message ;куда
mov cx,ds:count ;50 символов
rep movsb
@DisStr set_msg
jmp no_load ;после изменения данных выйдем
;запомним старый вектор
set_resid:
mov word ptr cs:old_1Ch,bx ;запомним старый адрес
mov word ptr cs:old_1Ch+2,es
;_——== освободим environment ==——
push es
mov AX,DS:[2ch]
mov ES,AX
mov AH,49h
int 21h
pop ES
;_——== установка 1Ch прерывания ==——
mov AX,251Ch ;повесим свою заплатку
lea DX,int_1Ch
int 21h
;_——== установим резидент ==——
mov AX,3100H
mov DX,(init-start+10FH)/16
int 21H
; mov DX, offset init
; int 21h
;_——== Invalid Time ==——
inv_time:
@DisStr inv_msg
jmp no_load
; Программа не загружена в память
notinmem:
@DisStr nim_msg
jmp no_load
;_——== Remove from memory ==——
remove_from_mem:
mov AX,351Ch ; !! поймаем 1Ch прерывание;
int 21h ; !!
cmp bx,offset int_1Ch ; !! мы уже есть в памяти ?
jne notinmem ; !!
@DisStr remove_msg
mov ax,351Ch
int 21h
mov ax,word ptr es:old_1Ch ; восстановление вектора
mov dx,word ptr es:old_1Ch+2 ; 1Ch
push es ; в ES сохранено CS резидентной пр-мы
cli
xor bx,bx
mov es,bx
mov bx,1Ch*4
mov es:[bx],ax ; восстановление старого
mov es:[bx+2],dx ; вектора 1Ch
sti
mov ah,49h
pop es
int 21h
;_____________________________________________________________________________
;_——== Exit ==—-
no_load:
mov ah,4Ch
int 21h
code ENDS
;_____________________________________________________________________________
END start
