Листинг программы, окончание


;_—-== ДАННЫЕ ==—-

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

Загрузка...