4. Розрахунки та експеріментальні матеріали, що підтверджують вірність програмних рішень
Насправді, програма не має в собі ніяких математичних розрахунків, тільки простіші. Складність написання програми полягала у технічній реалізації поставленої задачі. Тому підтвердити вірність програмних рішень можливо було тільки експеріментально. Були проведені тести на можливу недостачу пам`яті, роботу у версіях DOS 3.2 й вище, також під емуляцією DOS у системі WINDOWS`95. Також програма пройшла тести на правильність друку, загальну роботу з принтером. Результати тестів підтверджують правильність роботи програми. Тести проводилися з EPSON-сумісними принтерами.
5. Основні висновки
Програма TXTPRINT.COM - програма для вибіркового друку тексту з екрану. Для того, щоб получити готовий COM - файл з тексту програми, треба виконати: TASM TXTPRINT.ASM, потім TLINK TXTPRINT.OBJ /T. Після цього запустити програму TXTPRINT.COM. Під час просмотру інформації на екрані, яку треба розпечатати треба натиснути ScrollLock. Після цього, користуючись клавишами курсору і ENTER помітити необхідний фрагмент тексту. Потім для розпечатки натиснути клавишу BackSpace, щоб почати розпечатувати, або ESC в разі, якщо текст був помічений неправильно. Після цього програма завершує своє роботу до наступного виклику по ScrollLock. Коли роботу з розпечаткою закінчено взагалі, можна вилучити програму TXTPRINT.COM з пам`яті за допомогою комбинації клавиш Ctrl+Alt+Esc. Програма повідомить про закінчення своєї роботи, і для того, щоб розпочати роботу програми знов, треба заново завантажувати TXTPRINT.COM.
Програма в процесі роботи змінює вектори преривань 08H, 09H, 28H, 2FH, 23H і 24H. Тому якщо після завантаження TXTPRINT.COM були також завантажені інші програми, використовуючи хоча б одне з цих преривань, то цю програму неможна буде вилучити з пам`яті доти, доки не будуть вилучені ті програми, а отже востановлені вектори цих преривань.
Перелiк скороченнь, символiв та спецiальних термiнiв
i т.д. - i так далi
i т.i. - i таке iнше
та iн. - та iншi
т.я. - так як
п. - пункт
ОС - операцiйна система
popup - резидентні програми, які викликаються користувачем
DOS - дискова операцiйна система
BIOS - базова система вводу/виводу
INT - переривання
PC - персональний комп'ютер
WINDOWS - операцiйна система
Список літератури
1. Р. Джордейн «Справочник программиста персональных компьютеров типа IBM PC» М: Мир, 1991р.
2. П. Абель «Мова асемблера для IBM PC та програмування.» М.: Вища школа,1992.
3. Р. Лей та "Уейт-Груп" «Написання драйверів для MS-DOS.» М.: Мир, 1995р.
4. Електронний спавочник «TeachHelp»
5. Конспект лекцій по системному програмуванню
Анотація
Програма TXTPRINT.COM - програма для вибіркового друку тексту з екрану. Для того, щоб получити готовий COM - файл з тексту програми, треба виконати: TASM TXTPRINT.ASM, потім TLINK TXTPRINT.OBJ /T. Після цього запустити програму TXTPRINT.COM. Під час просмотру інформації на екрані, яку треба розпечатати треба натиснути ScrollLock. Після цього, користуючись клавишами курсору і ENTER помітити необхідний фрагмент тексту. Потім для розпечатки натиснути клавишу BackSpace, щоб почати розпечатувати, або ESC в разі, якщо текст був помічений неправильно. Після цього програма завершує своє роботу до наступного виклику по ScrollLock. Коли роботу з розпечаткою закінчено взагалі, можна вилучити програму TXTPRINT.COM з пам`яті за допомогою комбинації клавиш Ctrl+Alt+Esc. Програма повідомить про закінчення своєї роботи, і для того, щоб розпочати роботу програми знов, треба заново завантажувати TXTPRINT.COM.
Програма в процесі роботи змінює вектори преривань 08H, 09H, 28H, 2FH, 23H і 24H. Тому якщо після завантаження TXTPRINT.COM були також завантажені інші програми, використовуючи хоча б одне з цих преривань, то цю програму неможна буде вилучити з пам`яті доти, доки не будуть вилучені ті програми, а отже востановлені вектори цих преривань.
Текст програми має дев`ять модулів. Їх текст, краткий опис та пояснення приводяться у додатках.
Додатки
Текст програми
; Файл TXTPRINT.ASM - основна програма
; Для створення готового продукту необхідно
; виповнити слідуючі команди:
; TASM TXTPRINT.ASM
; TLINK /t TXTPRINT.OBJ
;**************************************************
cr equ 13 ; символ "Возврат каретки".
lf equ 10 ; символ "Перевод строки".
start_offset equ 0b8h ; сміщення початку резидентної
; порції у сегменті команд
; і вершина внутрішнього стеку.
internal_flags record Sf:1,Rf:1,Af:1,Tf:1,Pf:1 ; набор прапорців
; 1=печать дозволена
; 1=Int_08h активна
; 1=программа активна
; 1=команда "удалити"
; 1=команда "стартувати"
.model tiny
.code
org 100h
entry:
jmp boot ; перейти на процедуру загрузки резиденту.
shift = offset callvideo - start_offset ; Величина
; сдвигу резидентної порції.
flags_offset = offset resident_sign - shift ; Сміщення прапорців
callvideo proc
; Обернутися до відео-BIOS.
push di
push si
push bp
int 10h
pop bp
pop si
pop di
ret
callvideo endp
sethandler proc
; Встановити обробник преривання.
push ax
mov ah,35h
int 21h
mov word ptr [di],bx
mov word ptr [di+2],es
pop ax
mov ah,25h
int 21h
ret
sethandler endp
resethandler proc
; Восстановити минулий обробник преривань.
push ds
mov dx,word ptr [di]
mov ds,word ptr [di+2]
mov ah,25h
int 21h
pop ds
ret
resethandler endp
include beep.asm
include typestr.asm
include message.asm
include remove.asm
include main.asm
include prepare.asm
include take&prn.asm
int_28h proc far
test byte ptr cs:[flags_offset],mask Sf or mask Rf
jz pass_28h ; Якщо небуло команди, то вихід.
test byte ptr cs:[flags_offset],mask Af or mask Tf
jnz pass_28h ; Якщо активна, то вихід.
or byte ptr cs:[flags_offset],mask Af
call prepare ; Запуск.
and byte ptr cs:[flags_offset],not(mask Sf or mask Rf or mask Af)
pass_28h: ; Передати управління ісходному обробнику.
jmp dword ptr cs:[int_28h_vect-shift]
int_28h_vect dd ?
int_28h endp
int_08h proc far
test byte ptr cs:[flags_offset],mask Tf or mask Af; or mask Df
jnz pass_08h ; Якщо активна, то вихід.
or byte ptr cs:[flags_offset],mask Tf ; Встановити
; признак активнисті Int_08h.
pushf ; Викликати ісходний
call dword ptr cs:[int_08h_vect-shift] ; обробник.
test byte ptr cs:[flags_offset],mask Sf or mask Rf
jz end_08h ; Якщо не було команды, то вихід.
push di ; Перевірити признак активности DOS.
push es
mov es,word ptr cs:[dos_flag_seg-shift]
mov di,word ptr cs:[dos_flag_off-shift]
test byte ptr es:[di],0ffh
pop es
pop di
jnz end_08h ; Якщо DOS активна, то вихід.
or byte ptr cs:[flags_offset],mask Af ; Встановити признак
; активности START.
call prepare ; Запуск.
and byte ptr cs:[flags_offset],not(mask Sf or mask Rf or mask Af)
end_08h:
and byte ptr cs:[flags_offset],not mask Tf ; Сбросити
iret ; признак активністи Int_08h.
pass_08h: ; Передати управління ісходному
jmp dword ptr cs:[int_08h_vect-shift] ; обробнику.
int_08h_vect dd ?
int_08h endp
int_09h proc far
push ax ; Сохранити регістр AX.
in al,60h ; Ввести код натиснутої клавиши.
cmp al,70 ; клавиша ScrollLock.
jne remove_test
mov ah,2 ; Перевірити Shift state.
int 16h
and al,0h
cmp al,0h
jne pass_09h
or byte ptr cs:[flags_offset],mask Sf
jmp short end_09h
remove_test:
cmp al,1 ; Клавиша Esc ?
jne pass_09h
mov ah,2 ; Перевірити Shift state.
int 16h
and al,0ch
cmp al,0ch
jne pass_09h
or byte ptr cs:[flags_offset],mask Rf
end_09h:
in al,61h ; Обробити апаратне преривання.
push ax
or al,80h
out 61h,al
pop ax
out 61h,al
mov al,20h
out 20h,al
pop ax
iret
pass_09h:
pop ax ; Восстановити регістри і передати управління по старому
jmp dword ptr cs:[int_09h_vect-shift]; вектору преривання Int_09h.
int_09h_vect dd ?
int_09h endp
int_2fh proc far
cmp ax,8900h ; Якщо запитуєтся установка процесу
jne pass_2fh ; з номером 89Н, то запретити установку.
mov al,0ffh ; Інакше передати управління
iret ; ісходному обробнику.
pass_2fh:
jmp dword ptr cs:[int_2fh_vect-shift]
int_2fh_vect dd ?
int_2fh endp
exeptions proc far
int_24h: mov al,3 ; Команда "Зняти системний визов".
int_23h: iret ; Вийти з преривання.
int_24h_vect dd ?
int_23h_vect dd ?
exeptions endp
dos_flag_off dw ?
dos_flag_seg dw ?
resident_sign internal_flags <>
;----- Ця частина програми використовується для загрузки резидента
boot: ; ( сама не є резидентною ).
mov si,offset start_string
call teletype
multiplex_test:
mov ax,8900h ; Тест на подвійну
int 2fh ; установку.
cmp al,0
je install ; Якщо не встановлен, то встановить.
mov si,offset reboot_message ; Інакше
call teletype ; видати повідомлення про подвійну
call teletype_keys ; загрузку, "гарячих" клавишах
int 20h ; і завершитись.
install:
call teletype_keys ; Видати повідомлення про "гарячі" клавиши
cld ; Сдвинути резидентну
mov di,start_offset ; порцію в PSP.
mov si,offset callvideo
mov cx,boot-callvideo
rep movsb
mov cx,sethandler-shift
mov al,09h ; Встановити новий обробник
mov dx,int_09h-shift ; преривання Int09h.
mov di,int_09h_vect-shift
call cx
mov al,2fh ; Встановити новий обробник
mov dx,int_2fh-shift ; преривання Int2fh.
mov di,int_2fh_vect-shift
call cx
mov al,28h ; Встановити новий обробник
mov dx,int_28h-shift ; преривання Int28h.
mov di,int_28h_vect-shift
call cx
mov al,08h ; Встановити новий обробник
mov dx,int_08h-shift ; преривання Int08h.
mov di,int_08h_vect-shift
call cx
mov ah,34h ; Прочитати і сохранити адресу
int 21h ; прапорця активністи DOS.
mov word ptr ds:[dos_flag_off-shift],bx
mov word ptr ds:[dos_flag_seg-shift],es
mov es,word ptr ds:[002ch] ; Освободити
mov ah,49h ; окруженіе DOS.
int 21h
mov dx,boot-shift ; Завершитись, оставив
int 27h ; резидента.
include teletype.asm
teletype_keys proc near
; Виводить повідомлення про гарячі клавиши.
mov si,offset hot_keys_mess1
call teletype
mov si,offset hot_keys_mess2
call teletype
mov si,offset hot_keys_mess3
call teletype
mov si,offset hot_keys_mess4
call teletype
mov si,offset hot_keys_mess5
call teletype
mov si,offset hot_keys_mess6
call teletype
mov si,offset hot_keys_mess7
call teletype
ret
teletype_keys endp
start_string db "Screen text printer. Version 1.0.",cr,lf,0
hot_keys_mess1 db "Use ",0
hot_keys_mess2 db "ScrollLock",40 dup (0)
hot_keys_mess3 db " to activate text printer and",cr,lf,0
hot_keys_mess4 db "Ctrl + Alt + Esc ",34 dup(0)
hot_keys_mess5 db " to remove it from memory.",cr,lf,lf,0
hot_keys_mess6 db "Use Enter to label text and",cr,lf,0
hot_keys_mess7 db "BackSpace to print it. Use Esc to cancel.",cr,lf,0
reboot_message db cr,lf,"Text Taker has already"
db " been installed !",7,cr,lf,lf,0
io_error_mess db "I/O failure.",cr,lf,lf,lf,0
end_entry:
END entry
;****************** Кінець файлу TXTPRINT.ASM ************************
; Файл PREPARE.ASM
; Модуль основної програми.
;*************************************************************
prepare proc
cli ; Ініціализувати стек.
mov word ptr cs:[stack_offset-shift],sp
mov word ptr cs:[stack_seg-shift],ss
push cs
pop ss
mov sp,start_offset
sti
push ax ; Сохранити регістри.
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push cs
pop ds
mov al,23h ; Встановити новий обробник преривання Int23h.
mov dx,int_23h-shift
mov di,int_23h_vect-shift
call sethandler
mov al,24h ; Встановити новий обробник прерывання Int24h.
mov dx,int_24h-shift
mov di,int_24h_vect-shift
call sethandler
mov ah,15 ; Визначити поточний відеорежим і
call callvideo ; номер відеосторінки.
cmp al,2
je set_param
cmp al,3
je set_param
cmp al,7
jne end_prepare ; Якщо графічний режим, то вихід.
set_param: ; Сохранити номер відеосторінки.
mov byte ptr ds:[current_video_page-shift],bh
mov ah,03h ; Сохранити позицію курсору.
call callvideo
mov word ptr ds:[cursor_loc-shift],dx
test byte ptr ds:[flags_offset],mask Sf
jz begin_remove
call start
jmp short restore_cursor
begin_remove:
call remove
restore_cursor:
mov bh,byte ptr ds:[current_video_page-shift]
mov dx,word ptr ds:[cursor_loc-shift] ; Восстановити
mov ah,2 ; положення курсору.
call callvideo
end_prepare:
mov al,23h ; Восстановити вектор преривання Int 23h.
mov di,int_23h_vect-shift
call resethandler
mov al,24h ; Восстановити вектор преривання Int 24h.
mov di,int_24h_vect-shift
call resethandler
pop es ; Восстановити регістри.
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
cli ; Переключитись на стек прерваної програми.
mov ss,word ptr cs:[stack_seg-shift]
mov sp,word ptr cs:[stack_offset-shift]
ret
prepare endp
stack_offset dw ?
stack_seg dw ?
cursor_loc dw ?
current_video_page db ?
;******************* Кінець файлу PREPARE.ASM *************************
; Файл MAIN.ASM
; Модуль основної програми
;*************************************************************
start proc
mov bp,sp ; Зарезервирувати місто
sub sp,13 ; в пам`яти для змінних.
mov byte ptr ds:[flag-shift],0 ; Обнулить всі прапорці.
mov byte ptr ds:[fl2-shift],0
mov byte ptr ds:[xx-shift],dl
mov byte ptr ds:[yy-shift],dh
rd:
call kurpos ; Встановити курсор.
call delay ; Визвать затримку.
in al,60h ; Взяти символ.
cmp al,14 ; BackSpace ?
jne nn ; Якщо ні - далі.
or byte ptr ds:[flags_offset],mask Pf ; Іначе дозволити печать,
mov ah,01h ; ініціализувати 0 порт,
mov dx,0
int 17h
call unlabel ; розпечатать
jmp hi ; й вийти.
nn:
cmp al,28 ; ENTER ?
jne n0 ; Якщо ні - далі.
call here
n0:
cmp al,72 ; UP ?
jne n1 ; Якщо ні - далі.
cmp byte ptr ds:[yy-shift],0 ; Перевірити позицію курсора.
jne n00
mov byte ptr ds:[yy-shift],25
jmp n00
rd1:
call keybuf
jmp rd
n00:
dec byte ptr ds:[yy-shift] ; Уменьшить Y на 1.
call kurpos ; Встановити курсор.
n1:
cmp al,80 ; DOWN ?
jne n2 ; Якщо ні - далі.
cmp byte ptr ds:[yy-shift],25 ; Перевірити позицію курсору.
jne n11
mov byte ptr ds:[yy-shift],0
n11:
inc byte ptr ds:[yy-shift] ; Увеличити Y на 1.
call kurpos ; Встановити курсор.
n2:
cmp al,75 ; LEFT ?
jne n3 ; Якщо ні - далі.
cmp byte ptr ds:[xx-shift],0 ; Преревірити позицію курсору.
jne n22
mov byte ptr ds:[xx-shift],80
dec byte ptr ds:[yy-shift]
n22:
dec byte ptr ds:[xx-shift] ; Уменьшить X на 1.
call kurpos ; Встановити курсор.
n3:
cmp al,77 ; RIGHT ?
jne n4 ; Якщо ні - далі.
cmp byte ptr ds:[xx-shift],80 ; Перевірити позицію курсору.
jne n33
mov byte ptr ds:[xx-shift],0
inc byte ptr ds:[yy-shift]
n33:
inc byte ptr ds:[xx-shift] ; Увеличить X на 1.
call kurpos ; Встановити курсор.
n4:
cmp al,1 ; ESC ?
jne rd1 ; Якщо ні - далі.
cmp byte ptr ds:[fl2-shift],0 ; Інакше восстановити колір
je hi ; й вийти.
call unlabel
; Вихід.
hi:
call keybuf ; Очистити буфер клавіатури.
mov sp,bp
ret ; Завершитись.
start endp
; Опис змінних:
scrr db ?
xx db ?
yy db ?
x1 db ?
y1 db ?
tx db ?
ty db ?
wx db 2
wy db 2
fl2 db 0
flag db 0
;******************** Кінець файлу MAIN.ASM **************************
; Файл TAKE&PRN.ASM
; Модуль основної програми.
;*************************************************************
keybuf proc
; Очищає буфер клавіатури.
push es
push ax
sub ax,ax
mov es,ax
mov al,es:[41ah] ; Взяти кінець буферу
mov es:[41ch],al ; і записати в початок.
pop ax
pop es
ret
keybuf endp
delay proc
; Ініціірує затримку.
push cx
mov cx,60
l1:
push cx
mov cx,20000
l2:
loop l2
pop cx
loop l1
pop cx
ret
delay endp
del2 proc
; Ініціірує затримку.
push cx
mov cx,6000
a2:
loop a2
pop cx
ret
del2 endp
here proc
; Обробка виділення тексту.
push ax
cmp byte ptr ds:[flag-shift],0
je nh
mov al,byte ptr ds:[wx-shift]
cmp byte ptr ds:[xx-shift],al
jne lab
mov al,byte ptr ds:[wy-shift]
cmp byte ptr ds:[yy-shift],al
je rr
lab:
call labela ; Виділити.
jmp rr
nh:
mov al,byte ptr ds:[xx-shift]
mov byte ptr ds:[x1-shift],al
mov al,byte ptr ds:[yy-shift]
mov byte ptr ds:[y1-shift],al
rr:
pop ax
mov byte ptr ds:[flag-shift],1
ret
here endp
kurpos proc
; Встановлює курсор.
push ax
mov ah,02h
mov dh,byte ptr ds:[yy-shift]
mov dl,byte ptr ds:[xx-shift]
mov bh,0
call callvideo
pop ax
ret
kurpos endp
labela proc
; Змінює колір поміченого тексту.
cmp byte ptr ds:[fl2-shift],0
je f0
call unlabel
call ifswap
jmp f1
f0:
mov al,byte ptr ds:[x1-shift]
mov byte ptr ds:[wx-shift],al
mov al,byte ptr ds:[y1-shift]
mov byte ptr ds:[wy-shift],al
call ifswap
f1:
mov byte ptr ds:[fl2-shift],1
mov al,byte ptr ds:[x1-shift]
mov byte ptr ds:[tx-shift],al
mov al,byte ptr ds:[y1-shift]
mov byte ptr ds:[ty-shift],al
hh:
push cx
push dx
mov ah,02h ; Змінити позицію курсору.
mov dh,byte ptr ds:[ty-shift]
mov dl,byte ptr ds:[tx-shift]
mov bh,0
call callvideo
mov ah,08h ; Считати символ/атрибут.
mov bh,0
call callvideo
mov byte ptr ds:[scrr-shift],ah
mov ah,09h ; Записати символ з ізмененим атрибутом.
mov bl,byte ptr ds:[scrr-shift]
add bl,15
mov cx,1
mov bh,0
call callvideo
pop dx
pop cx
mov dl,byte ptr ds:[tx-shift]
cmp dl,byte ptr ds:[xx-shift]
je ok
as:
inc byte ptr ds:[tx-shift]
cmp byte ptr ds:[tx-shift],80
jne hh
mov byte ptr ds:[tx-shift],0
inc byte ptr ds:[ty-shift]
jmp hh
ok:
mov al,byte ptr ds:[yy-shift]
cmp byte ptr ds:[ty-shift],al
je rro ; Якщо кінець, то вийти,
jmp as ; інакше оброблювати наступний символ.
rro:
mov al,byte ptr ds:[xx-shift]
mov byte ptr ds:[wx-shift],al
mov al,byte ptr ds:[yy-shift]
mov byte ptr ds:[wy-shift],al
ret
labela endp
unlabel proc
; Встановлює колір поміченого тексту.
push ax
push dx
push cx
mov al,byte ptr ds:[x1-shift]
mov byte ptr ds:[tx-shift],al
mov al,byte ptr ds:[y1-shift]
mov byte ptr ds:[ty-shift],al
tl:
mov ah,02h ; Змінити позицію курсору.
mov dh,byte ptr ds:[ty-shift]
mov dl,byte ptr ds:[tx-shift]
mov bh,0
call callvideo
mov ah,08h ; Считати символ/атрибут.
mov bh,0
call callvideo
mov byte ptr ds:[scrr-shift],ah
call ToPrn
mov ah,09h ; Записати символ з востановленим атрибутом.
mov bl,byte ptr ds:[scrr-shift]
sub bl,15
mov cx,1
mov bh,0
call callvideo
mov al,byte ptr ds:[wx-shift]
cmp byte ptr ds:[tx-shift],al
je don
nt:
inc byte ptr ds:[tx-shift]
cmp byte ptr ds:[tx-shift],80
jne tl
call PrnEnt
mov byte ptr ds:[tx-shift],0
inc byte ptr ds:[ty-shift]
jmp tl
don:
mov al,byte ptr ds:[wy-shift]
cmp byte ptr ds:[ty-shift],al
je ex ; Якщо кінець, то вийти,
jmp nt ; інакше оброблювати наступний символ.
ex:
pop ax
pop cx
pop dx
ret
unlabel endp
ToPrn proc
; Печатает символ.
test byte ptr ds:[flags_offset],mask Pf ; Перевірити прапорець печаті.
jz outp ; Якщо не дозволено - вийти.
mov ah,00h
mov dx,0
int 17h ; Печатать.
call del2
outp:
ret
ToPrn endp
PrnEnt proc
; Печатает ENTER
test byte ptr ds:[flags_offset],mask Pf ; Перевірити прапорець печаті.
jz notp ; Якщо не дозволено - вийти.
mov ah,0
mov dx,0
mov al,0ah ; Печатати CR.
int 17h
mov ah,0
mov dx,0
mov al,0dh ; Печатать LF.
int 17h
notp:
ret
PrnEnt endp
ifswap proc
push ax
mov al,byte ptr ds:[y1-shift] ; Порівняти координати Y1 и YY
cmp al,byte ptr ds:[yy-shift]
jg zq
jl qw
mov al,byte ptr ds:[x1-shift] ; Порівняти координати X1 и XX
cmp al,byte ptr ds:[xx-shift]
jng qw
zq: ; Якщо треба змінити,
mov al,byte ptr ds:[yy-shift] ; змінюєм.
mov byte ptr ds:[y1-shift],al
mov al,byte ptr ds:[xx-shift]
mov byte ptr ds:[x1-shift],al
mov al,byte ptr ds:[wx-shift]
mov byte ptr ds:[xx-shift],al
mov al,byte ptr ds:[wy-shift]
mov byte ptr ds:[yy-shift],al
qw:
pop ax
ret ; Выход
ifswap endp
;******************* Кінець файлу TAKE&PRN.ASM ***********************
; Файл REMOVE.ASM
; Модуль основної програми
;*************************************************************
test_vector proc
; Перевірити вектор преривання.
mov ah,35h
int 21h
cmp bx,dx
jne exit
mov dx,es
cmp cx,dx
exit:
ret
test_vector endp
remove proc
mov cx,cs
mov di,test_vector-shift
mov al,09h ; Перевірити вектор преривання Int09h.
mov dx,int_09h-shift
call di
jne not_remove
mov al,2fh ; Перевірити вектор преривання Int2fh.
mov dx,int_2fh-shift
call di
jne not_remove
mov al,28h ; Перевірити вектор преривання Int28h.
mov dx,int_28h-shift
call di
jne not_remove
mov al,08h ; Перевірити вектор преривання Int08h.
mov dx,int_08h-shift
call di
je uninstall
not_remove:
mov ax,notremove_mess-shift
push ax
push ax
call mess
ret
uninstall:
mov ax,remove_mess-shift
push ax
xor ax,ax
push ax
call mess
mov cx,resethandler-shift
mov al,09h ; Восстановити вектор преривання Int09h.
mov di,int_09h_vect-shift
call cx
mov al,2fh ; Восстановити вектор преривання Int2fh.
mov di,int_2fh_vect-shift
call cx
mov al,28h ; Восстановити вектор преривання Int28h.
mov di,int_28h_vect-shift
call cx
mov al,08h ; Восстановити вектор преривання Int08h.
mov di,int_08h_vect-shift
call cx
cli
push cs
pop es
mov ah,49h ; Освободити займаєму пам`ять.
int 21h
ret
remove_mess db ' has been',0,'REMOVED form memory. ',0
notremove_mess db ' UNABLE to',0,'remove. Not on the top. ',0
remove endp
;********************* Кінець файлу REMOVE.ASM ***********************
; Файл MESSAGE.ASM
; Модуль основної програми.
;*************************************************************
xchgmess proc
mov di,code_table-shift ; Загрузити сміщення
mov si,attribute_table-shift ; таблиць кодів і
; атрибутів вікна повідомлення.
mov cx,6
mov dh,10
loop_1: ; Цикл по строках.
push cx
mov cx,30
mov dl,25
loop_2: ; Цикл по стовбцях.
push cx
mov ah,2
call callvideo
mov ah,8
call callvideo
cmp dh,15
jb lab_1
cmp dl,27
jb exch_noth
jmp short exch_attr
lab_1:
cmp dh,11
jb lab_2
cmp dl,52
ja exch_attr
jmp short exch_code
lab_2:
cmp dl,52
ja exch_noth
exch_code:
xchg al,byte ptr [di] ; Заменити код символа.
inc di
exch_attr:
xchg ah,byte ptr [si] ; Заменити атрибут.
inc si
exch_noth:
mov bl,ah ; Вивести символ.
mov cx,1
mov ah,9
call callvideo
inc dx
pop cx
loop loop_2
inc dh
pop cx
loop loop_1
mov dx,1900h ; Убрати курсор.
mov ah,02h
call callvideo
ret ; Вийти з процедури.
xchgmess endp
mess proc
push bp
mov bp,sp
push bx
mov bh,byte ptr ds:[current_video_page-shift]
mov bl,byte ptr ds:[attribute_table-shift]
push bx ; Вивести вікно повідомлення.
call xchgmess
pop bx
mov dx,0b29h ; Вивести текст повідомлення.
mov si,word ptr [bp+6]
call typestr
mov dx,0c1bh
call typestr
push bx ; Подати звуковий сигнал.
mov cx,2
mess_loop:
mov di,550
mov bx,30
call beep
mov di,1100
call beep
loop mess_loop
pop bx
wait_mess:
mov ah,0 ; Ждати натиснення клавиши.
int 16h
call xchgmess ; Восстановити екран.
pop bx
pop bp
ret 4 ; Вийти з процедури.
mess endp
; Таблиця атрибутів вікна повідомлення.
attribute_table db 29 dup(4eh),14 dup (206),13 dup (4eh)
db 07h,07h
db 28 dup (4eh)
db 07h,07h
db 4eh,26 dup (206),4eh
db 07h,07h
db 28 dup (4eh)
db 30 dup (07h)
; Образ атрибутів вікна повідомлення.
code_table db '============================'
db '!Screen Printer: !'
db '! !'
db '! press any key... !'
db '============================'
;****************** Кінець файлу MESSAGE.ASM *************************
; Файл TYPESTR.ASM
; Модуль основної програми.
;*************************************************************
typestr proc
typestr_loop:
mov ah,2 ; Встановити курсор в нужну позицию.
call callvideo
lodsb
or al,al ; Якщо зустрився кінець строки,
jz end_typestr ; то вихід.
mov cx,1
mov ah,9
call callvideo
inc dx ; Определити позицію для вивода
jmp short typestr_loop ; следуючого символу.
end_typestr:
push dx ; Убрати курсор.
mov dx,1900h
mov ah,2
call callvideo
pop dx
ret ; Вийти з процедури.
typestr endp
;******************** Кінець файлу TYPESTR.ASM ************************
; Файл BEEP.ASM
; Модуль основної програми.
;*************************************************************
beep proc
; Подає звуковой сигнал заданої частоти і тривання.
push bx ; Сохранити регістри.
push cx
push di
mov di,1000
mov al,0b6h ; Записати у регістр режим таймеру.
out 43h,al
mov dx,14h ; Делитель часу равен
mov ax,4f38h ; 1331000/частота.
div di
out 42h,al ; Записати молодший байт лічильника таймера 2.
mov al,ah
out 42h,al ; Записати молодший байт лічильника таймера 2.
in al,61h ; Считати поточну установку порта В
push ax ; й сохранити її.
or al,3
out 61h,al ; Включити динамик.
wait_beep:
mov cx,01fffh
speaker_on:
loop speaker_on
dec bx ; Лічильник тривалісті ісчерпан ?
jnz wait_beep ; Ні. Продовжити звучання.
pop ax ; Да. Восстановити похідну установку
out 61h,al ; Порта В.
pop di ; Восстановити всі регистри.
pop cx
pop bx
ret ; Вийти з процедури.
beep endp
;********************* Кінець файлу BEEP.ASM *************************
; Файл TELETYPE.ASM
; Модуль основної програми.
;*************************************************************
teletype proc
mov bh,0 ; Обрати нулеву відеосторінку.
cld
type_next_char:
lodsb ; Загрузити наступний символ в AL.
mov ah,0eh
cmp al,0 ; Якщо кінець строки, то вихід.
je end_teletype
call callvideo ; Вивести символ.
jmp short type_next_char
end_teletype:
ret
teletype endp
;******************** Кінець файлу TELETYPE.ASM **********************
0 комментариев