Реферат: Програма Txtprint.com - резидентна програма для швидкого і зручного друкування виборчого тексту з екрану

Міністерствоосвіти та науки України

Кіровоградський Державний Технічний університет

Кафедрапрограмного забезпечення

Курсоваробота

здисципліни “Програмування на мові ASM-86” на тему:

ПрограмаTXTPRINT.COM — резидентна програма для швидкого і зручного друкування виборчоготексту з екрану


Зміст

Вступ.

1. Призначення та областьвикористання системи.

2. Огляд iснуючих систем. Обґрунтування вибору принципу розробки та методики побудови системи. Постановка задачіпо реалізації технічногозавдання

3. Опис та обґрунтування проектних рішень по проектуванню системи.

4. Разрахунки та експерементальніматеріали які підтверджують вірністьпрограмних рішень

5. Основнi висновки

Перелiк скорочень, символiв таспецiальних термiнiв.

Список лiтератури.

Анотацiя.

Додатки.

Текст програми.


Вступ

Програма txtprint.com — резидентна програма, яка предназначена для того, щоб швидко ізручно надрукувати виборчий текст з екрану. Це може бути корисним, колидоводиться аналізувати в водночас багато текстової інформаціі, наприклад різніфайли-помічники, текст іншої програми, та багато ін. Також ця програма можестати у пригоді тоді, коли треба надрукувати текстовий файл, але не повністю,окремими епізодами. Програма дуже зручна для її використання, займає усього 2килобайти DOS — пам`яті, також її можна вилучити з пам`яті в будь-який час. Просто ізрозуміло оформлен інтерфейс з користувачем, отже навчитись роботі з програмою TXTPRINT.COM можна за хвилину.

Також в програмівстановлено тест на подвійну загрузку, отже при спробі завантажити її вдругекористувач отримає повідомлення про це, а також програма нагадае про «гарячі» клавіші, таким чином запобігаючи подвійного завантаження.Програма не конфліктує з іншими резидентними програмами (якщо, звісно, вонипрацюють коректно), але в разі змінення ними хочаб одного з векторів преривань INT 08H, INT 09H, INT 28H, INT 2FH програма TXTPRINT.COM не в змозі буде вилучитись з пам`ятіпо вимозі користувача. Про це програма видасть повідомлення, і нагадає пропричину цього (не на вершині). Але після вилучення з пам`яті тієї програми, щозмінила вище перечислених векторів преривань, при подальшої вимоги користувачапрограму TXTPRINT.COM теж буде вилучено з пам`яті.


1.Призначення та область використання системи

Програма TXTPRINT.COM призначена для друку на принтерівибіркового тексту з екрану. Також її можна використовувати в учбових закладахдля полегчення і прискорення засвоєння потрібної документації з комп`ютера (різні HELP-програми, завдання задач та ін.).Для цього користувачу потрібно перед переглядом документації на комп`ютері завантажити програму TXTPRINT.COM і в потрібний час викликати її задопомогою «гарячих» клавиш. Потім помітити потрібну частину тексту і датикоманду «печатати». Після чого цей текст розпечатається на принтері, і будебільш зручнішим для прочитання та багаторазового перегляду під час виконанняроботи (лабораторної тощо). Програма має дуже простий і зручний інтерфейс, щодуже полегшує роботу з нею, займає усього 2 кілобайти DOS-пам`яті.

Також ця програмадуже цікава з точки зору вивчення резидентних програм. На її прикладі можнаобучати студентів по роботі з функціями DOS в резидентних програмах.

2. Огляд існуючих систем, обґрунтування виборупринципу розробки та методики побудовисистеми. Постановка задачі пореалізації технічного завдання

Існує багатосистем, у яких можна зробити вибіркову розпечатку тексту (усіпрограми-редактори, та багато ін.), але їх недолік у тому, що вони нерезидентні, і можуть розпечатувати тільки текст, редагуванням якого вонизаймаються.

Програма TXTPRINT.COM повинна бути резидентною, працюватишвидко та надійно при різних процесорах, а також займати якомога менше пам`яті. Тому задача розроблялась на мовіасемблера (ASM-86) для TASM версії не нижче 2.0.

Програма повинна:

n бути резидентною і не конфліктувати зопераційною системою та іншими програмами;

n викликатись по натисненню «гарячих»клавиш; мати дружній інтерфейс з користувачем;

n розпечатувати помічений текст зекрану;

n не завантажуватись в друге;

n займати якомога менше пам`яті;

n по вимозі користувача вилучатись зпам`яті.

По обґрунтуваннюта реалізації цього завдання см. розділ 3.

3. Опис та обґрунтуванняпроектних рішень по проектуванню системи

Усе, щоприводиться у цьому параграфi вiдноситься тiльки до «випригуючих»(popup) резидентних програм.

Реентабельною(повторно входимою) програмою називаеться програма чи процедура, одна копiяякої в пам`ятi може бути одночасно викликатись кiлькома процесами, при чьомурiзноманiтнi виповнювання цiєї процедури не впливають одна на одну.

НереентабильністьMS-DOS проявляеться в неможливiстi звертання к функцiям DOS, якщо вжевиповнюеться яка-небудь iнша функцiя DOS. Порушення цiєї вимоги призведе дозруйнування системного стеку i краху операцiйної системи. Саме знереентабильнiстю DOS пов`язанi основнi труднощi розработки popup — програм.Справа в тому, що цi резидентнi програми використовують для свого запускуаппаратнi преривания, якi можуть статися в будь-який час, у тому числi й тодi,коли виповнюється функцiя DOS.

Найпростiшерiшення цiєї проблеми складається у повнiй вiдмовi вiд використання системногосервiсу DOS в резидентних програмах. Iнколи це не дуже складно. Так, для виводуна дiсплей можна користуватись прериванням BIOS 10H чи прямим записом увiдеобуфер, для вводу символiв з клавiатури приємлимо користуватись прериванням16H, при роботi з принтером i послiдовними портами також неважко працювати нарiвнi BIOS. Але у разi, коли потрiбен дисковий ввод — вивод, це вже стає дужепроблематичним.

Працювати здисками средствами BIOS — дiйсно дуже хлопотна справа.

Iснують i iншiситуацiї, коли зручнiше було б використовувати функцiї DOS. Отже, требанавчитися перемагати нереентабiльнiсть DOS. Для цього iснує багато можливостей.

Почнем з того, щоіснує простий (хоча й недокументований) спосiб запобiгнути конфлiктiв з операційноюсистемою. При активiзацiї програма може перевiрити байтовий прапорець активнiстiDOS i, якщо вiн вiдмiнний вiд нуля (сервiс DOS недоступний), повернутись допасивного стану. Адресу цього прапорця повiдомляє функцiя DOS 34H.

/>


Функція 34H. Дає адресу прапорця активністі DOS

/>Виклик: AH = 34H

/>Повертає: ES:BX — адреса прапорця

Нажаль, якщовибрати цей путь, така резидентна программа, скоріше за все, взагалі буде невзмозі стартувати. Це пов`язано з тим, що COMMAND.COM та багато інших програм проводятьбагато часу в очикуванні ввода строки з клавіатури посредством функції DOS 0AH, і, отже, прапорець активністі DOS майже завжди взведений. Ця обставинавикористовується у диспетчері функцій DOS, який може мати вигляд на зразок цього:


          Int_21h PROC far

                   sti

                   pushf

                   cmpah,0Ah        ;якщо номер функції не рівний 0ah,

                   jnz Exec               ; то приступити квиконанню.

          Fn0Ah:

                   push ax               ; якщо функція 0ah, то затримати

                   mov ah,0bh; їївиповнення до тіх пір, поки у

                   int 21h                 ; буфері клавіатурине з`явиться

                   cmp al,0              ; хочаб один символ.

                   pop ax

                   jnzExec

                   pushcx

                   movcx,4000h

          Delay:         loopDelay ; зробитипаузу

                   popcx

                   jmpshort Fn0Ah; іповторити перевірка буфера.

          Exec:

                   orbyte ptr cs:DOS_busy,01h; встановити признак

;                                                         зайнятостіDOS.

                   Popf           ; визвати початковийобробник.

                   pushf

                   calldword ptr cs:[Int_21h_vect]

                   pushf

                   andbyte ptr cs:DOS_busy,0feh       ; скинути признак

;                                                         зайнятості.

                   popf

                   ret2

          Int_21h_vectdd ?

          Dos_busy   db 0

          Int_21hENDP

Запит навиконання функції 0AH не передається одразу до операційноїсистеми. Замість цього периодично перевіряється стан буфера вводу (функція DOS 0BH або функція 01H преривання 16H). І вже тільки після того як буферпочав заповниватися, визивається функція 0AH.Оберніть увагу на те, як оформлен возврат у програму — це викликано тим, що DOS використовує прапорець CF в якості признаку помилки.

Важливо те, що вописаному прикладі можна відмовитись від перевірки недокументованого прапорцяактивністі DOS. Замість того диспетчервстановлює свій власний прапорець, який дотого ж бітовий, отже він може бути об`єднан з іншими прапорцями резидентноїпрограми.

Диспетчер функційDOS — приємлимий, але ненайбільш вдалий спосіб перевагання нереєнтабільності DOS. Програмам, використовуючим його,далеко не завжди вдається стартувати. Крім того, їм приходиться аналогічнимчином відслежувати ще й преривання 25H (читати сектор), 26H (писатисектор) DOS, а також преривання 13H BIOS.

Обробникипреривань 25H і 26H виявляються звичайними функціями — під час повернення управління вони залишають в стеці регистр прапорців. А цекласичний приклад помилки, якій в наслідок увішов у документацію.

Найбільш цікавимиможливостями преодоління нереєнтабільністі DOS пов`язані з використовуванням недокументованого преривання 28H. Це преривання використовуєтьсярезидентними процесами самої операційної системи, наприклад, PRINT, та генерується як раз під часвиконання функцій DOS, колипрапорець активністі DOS взведений, але система знаходиться у безпечному стані.

За допомогоюпреривання 28H можна досягнути потрясаючихрезультатів. Отже, така програма може стартувати, наприклад, під час копіюванняфайлів, а іноді при форматуванні диску.

При натисканні на«гарячу» клавишу не відбувається негайна активізація програми, а лишевстановлюється битовий прапорець, повідомляючий, що поступила командастартувати. Обробник преривання 28H перевіряє стан прапорця, і, якщо прапорець встановлен, апрограма ще не активна, активізує її. На прикінці роботи управління завждипередається завжди повинне передаватись початковому обробнику. Програми, яківиконуються усередині преривання 28H, неповинні користуватись функціями DOS з номерами 00H — 0CH.

А як буть, колидовгий час не відбувається звертання до функцій DOS і, отже, не вироблялось преривання28H? ПроРграмазнов не в змозі стартувать. Щоб запобігнути цього, буде потрібна ще одна точкавходу, в якісті якої зручно буде обрати обробник якогось часто возникаючогопреривання, наприклад, від таймеру. Тоді перед активізацією програми требаперевіряти прапорець активністі DOS, чи свій власний прапорець.

Реакція навиключні випадки.

Іноді врезультаті збоїв апаратної частини або неправильних дій користувача можескластися ситуація, коли подальша робота програми виявляється неможливою. Вцьому випадку управління дістає спеціальна процедура обробки критичної помилки,адреса якої знаходиться у векторі преривання 24H. Користувач може також сам прерватипрограму, натиснувши комбинацію клавиш Ctrl+Break. При цьому MS-DOS передає управління до процедуризавершення, яка починається по адресі обробника преривання 23H.

Цей сервіс DOS, неодмінно, дуже корисний, алеорієнтован на звичайні програми і не може правильно працювати в резидентнихпрограмах. Тому вам слід передбачити власну оброботку виключних випадків абовідключити існуючу.

Почнемо зпреривання Ctrl+Break. Реакція системи на це прериваннязалежить від стану прапорця перевірки по Ctrl+Break. Якщо прапорець скинутий, то перевірка натиснення Ctrl+Break і завершення програми відбуваєтьсятільки при виконанні функції DOS з номерами 00H — 0CH, а якщо прапорець встановлен, привиконанні будь-яких функцій. Тому, якщо в програмі не використовуються функції DOS 00H-0CH, тодідостатньо скинути прапорець перевірки по Ctrl+Break при активізації резидентної програми і встановити його початковезначення перед поверненням у пасивний стан.

/>


Функція 33H. Прапорець перевірки по Ctrl+Break

/>Виклик: AH = 33H

AL = 0 — отримати стан прапорця

1 — змінити станпрапорця.

DL (якщо AL=1) = 0 — скинути прапорець

1 — встановитипрапорець

/>Повертає: DL ( якщо AL дорівнював 0) -

стан прапорця:

0 — скинут

1 — встановлен

Для перевірки абозміни стану прапорця зручно застосовувати функцію DOS 33H.

Другий можливийпуть — просто відмінити оброботку преривання 23H, тобто змінити його вектор так, щоб він вказував на інструкцію IRET.

При виникниннікритичної помилки (звично це помилка диску) MS-DOS завантажує у регістри AX, DI, SI, BP інформацію про помилку ініцируєпреривання 24H. Стандартний системнийобробоник преривання веде себе слідуючим чином: видає на дісплей повідомленняпро помилку і запит користувача — «Abort, Retry, File or Ignore?» («Прервати, Повторити, Зняти або Ігнорувати»), чекаєвідповіді і повертає управління функції DOS, при виконанні якої виникла помилка.Подальші дії операційної системи визначається змістом регістру AL(відповідь користувача).

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 /tTXTPRINT.OBJ

;**************************************************

cr equ 13         ;символ «Возврат каретки».

lf equ 10         ;символ «Перевод строки».

start_offset equ0b8h   ; сміщення початку резидентної

;              порціїу сегменті команд

;              і вершинавнутрішнього стеку.

internal_flagsrecord 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 = offsetcallvideo — 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

sethandlerproc

;  Встановитиобробник преривання.

    push ax

    mov ah,35h

    int 21h

    mov wordptr [di],bx

    mov wordptr [di+2],es

    pop ax

    mov ah,25h

    int 21h

    ret

sethandlerendp

resethandlerproc

;  Восстановити минулий обробник преривань.

    push ds

    movdx,word ptr [di]

    movds,word ptr [di+2]

    mov ah,25h

    int 21h

    pop ds

    ret

resethandlerendp

includebeep.asm

includetypestr.asm

includemessage.asm

includeremove.asm

includemain.asm

includeprepare.asm

includetake&prn.asm

int_28h procfar

    test byteptr cs:[flags_offset],mask Sf or mask Rf

    jz pass_28h    ; Якщо небулокоманди, то вихід.

    test byte ptrcs:[flags_offset],mask Af or mask Tf

    jnz pass_28h     ; Якщоактивна, то вихід.

    or byte ptrcs:[flags_offset],mask Af

    callprepare     ; Запуск.

    and byteptr cs:[flags_offset],not(mask Sf or mask Rf or mask Af)

pass_28h:    ;Передати управління ісходному обробнику.

    jmp dword ptrcs:[int_28h_vect-shift]

int_28h_vectdd ?

int_28h endp

int_08h procfar

    test byteptr cs:[flags_offset],mask Tf or mask Af; or mask Df

    jnz pass_08h     ; Якщоактивна, то вихід.

    or byte ptrcs:[flags_offset],mask Tf  ; Встановити

;                     признак активнисті Int_08h.

    pushf                  ; Викликати ісходний

    call dword ptrcs:[int_08h_vect-shift]   ; обробник.

    test byteptr cs:[flags_offset],mask Sf or mask Rf

    jz end_08h      ; Якщо небуло команды, то вихід.

    push di      ; Перевірити признак активности DOS.

    push es

    moves,word ptr cs:[dos_flag_seg-shift]

    movdi,word ptr cs:[dos_flag_off-shift]

    test byteptr es:[di],0ffh

    pop es

    pop di

    jnzend_08h    ; Якщо DOS активна, то вихід.

    or byteptr cs:[flags_offset],mask Af  ; Встановити признак

;                         активности START.

    callprepare                ; Запуск.

    and byteptr cs:[flags_offset],not(mask Sf or mask Rf or mask Af)

end_08h:

    and byteptr cs:[flags_offset],not mask Tf; Сбросити

    iret               ; признакактивністи Int_08h.

pass_08h:                 ; Передати управління ісходному

    jmp dword ptrcs:[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.

    jneremove_test

    mov ah,2         ; Перевірити Shift state.

    int 16h

    and al,0h

    cmp al,0h

    jne pass_09h

    or byte ptrcs:[flags_offset],mask Sf

    jmp shortend_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 ptrcs:[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 ptrcs:[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 ptrcs:[int_2fh_vect-shift]

int_2fh_vect dd ?

int_2fh endp

exeptions procfar

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_signinternal_flags <>

;----- Ця частинапрограми використовується для загрузки резидента

boot:   ; ( самане є резидентною ).

    mov si,offsetstart_string

    call teletype

multiplex_test:

    mov ax,8900h   ; Тест на подвійну

    int 2fh         ; установку.

    cmp al,0

    je install       ; Якщо не встановлен, то встановить.

    mov si,offsetreboot_message  ; Інакше

    call teletype     ; видати повідомлення про подвійну

    callteletype_keys; загрузку, «гарячих» клавишах

    int 20h         ; і завершитись.

install:

    callteletype_keys; Видати повідомлення про «гарячі» клавиши

    cld           ; Сдвинути резидентну

    movdi,start_offset; порцію в PSP.

    mov si,offsetcallvideo

    movcx,boot-callvideo

    rep movsb

    movcx,sethandler-shift

    mov al,09h           ; Встановити новий обробник

    movdx,int_09h-shift     ; преривання Int09h.

    mov di,int_09h_vect-shift

    call cx

    mov al,2fh           ; Встановити новий обробник

    movdx,int_2fh-shift     ; преривання Int2fh.

    movdi,int_2fh_vect-shift

    call cx

    mov al,28h           ; Встановити новий обробник

    movdx,int_28h-shift     ; преривання Int28h.

    movdi,int_28h_vect-shift

    call cx

    mov al,08h           ; Встановити новий обробник

    movdx,int_08h-shift     ; преривання Int08h.

    movdi,int_08h_vect-shift

    call cx

    mov ah,34h    ; Прочитати і сохранити адресу

    int 21h       ; прапорця активністи DOS.

    mov word ptrds:[dos_flag_off-shift],bx

    mov word ptrds:[dos_flag_seg-shift],es

    mov es,wordptr ds:[002ch]    ; Освободити

    mov ah,49h           ; окруженіе DOS.

    int 21h

    movdx,boot-shift   ; Завершитись, оставив

    int 27h           ; резидента.

includeteletype.asm

teletype_keysproc near

;  Виводитьповідомлення про гарячі клавиши.

    mov si,offsethot_keys_mess1

    call teletype

    mov si,offsethot_keys_mess2

    call teletype

    mov si,offsethot_keys_mess3

    call teletype

    mov si,offsethot_keys_mess4

    call teletype

    mov si,offsethot_keys_mess5

    call teletype

    mov si,offsethot_keys_mess6

    call teletype

    mov si,offsethot_keys_mess7

    call teletype

    ret

teletype_keysendp

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 dbcr,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 ptrcs:[stack_offset-shift],sp

    mov word ptrcs:[stack_seg-shift],ss

    push cs

    pop ss

    movsp,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.

    movdx,int_23h-shift

    movdi,int_23h_vect-shift

    callsethandler

    mov al,24h  ;Встановити новий обробник прерывання Int24h.

    movdx,int_24h-shift

    movdi,int_24h_vect-shift

    callsethandler

    mov ah,15    ;Визначити поточний відеорежим і

    callcallvideo; номер відеосторінки.

    cmp al,2

    je set_param

    cmp al,3

    je set_param

    cmp al,7

    jneend_prepare ; Якщо графічний режим, то вихід.

set_param:        ; Сохранити номер відеосторінки.

    mov byte ptrds:[current_video_page-shift],bh

    mov ah,03h    ; Сохранити позицію курсору.

    callcallvideo

    mov word ptrds:[cursor_loc-shift],dx

    test byte ptrds:[flags_offset],mask Sf

    jzbegin_remove

    call start

    jmp shortrestore_cursor

begin_remove:

    call remove

restore_cursor:

    mov bh,byteptr ds:[current_video_page-shift]

    mov dx,wordptr ds:[cursor_loc-shift]  ; Восстановити

    mov ah,2            ; положення курсору.

    callcallvideo

end_prepare:

    mov al,23h    ; Восстановити вектор преривання Int 23h.

    movdi,int_23h_vect-shift

    callresethandler

    mov al,24h    ; Восстановити вектор преривання Int 24h.

    movdi,int_24h_vect-shift

    callresethandler

    pop es       ;Восстановити регістри.

    pop ds

    pop bp

    pop si

    pop di

    pop dx

    pop cx

    pop bx

    pop ax

    cli       ;Переключитись на стек прерваної програми.

    mov ss,wordptr cs:[stack_seg-shift]

    mov sp,wordptr cs:[stack_offset-shift]

    ret

prepare endp

stack_offset dw ?

stack_seg dw ?

cursor_loc dw ?

current_video_pagedb ?

;*******************Кінець файлу PREPARE.ASM *************************

; Файл MAIN.ASM

; Модуль основноїпрограми

;*************************************************************

start proc

    mov bp,sp       ; Зарезервирувати місто

    sub sp,13       ; в пам`яти для змінних.

    mov byte ptrds:[flag-shift],0   ; Обнулить всі прапорці.

    mov byte ptrds:[fl2-shift],0

    mov byte ptrds:[xx-shift],dl

    mov byte ptrds:[yy-shift],dh

rd:

    call kurpos      ; Встановити курсор.

    call delay      ; Визвать затримку.

    in al,60h       ; Взяти символ.

    cmp al,14       ; BackSpace ?

    jne nn        ; Якщо ні — далі.

    or byte ptrds:[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 ptrds:[yy-shift],0    ; Перевірити позицію курсора.

    jne n00

    mov byte ptrds:[yy-shift],25

    jmp n00

rd1:

    call keybuf

    jmp rd

n00:

    dec byte ptrds:[yy-shift]     ; Уменьшить Y на 1.

    call kurpos             ; Встановити курсор.

n1:

    cmp al,80       ; DOWN ?

    jne n2        ; Якщо ні — далі.

    cmp byte ptrds:[yy-shift],25     ; Перевірити позицію курсору.

    jne n11

    mov byte ptrds:[yy-shift],0

n11:

    inc byte ptrds:[yy-shift]     ; Увеличити Y на 1.

    call kurpos             ; Встановити курсор.

n2:

    cmp al,75       ; LEFT ?

    jne n3        ; Якщо ні — далі.

    cmp byte ptrds:[xx-shift],0    ; Преревірити позицію курсору.

    jne n22

    mov byte ptrds:[xx-shift],80

    dec byte ptrds:[yy-shift]

n22:

    dec byte ptrds:[xx-shift]     ; Уменьшить X на 1.

    call kurpos             ; Встановити курсор.

n3:

    cmp al,77       ; RIGHT ?

    jne n4        ; Якщо ні — далі.

    cmp byte ptrds:[xx-shift],80     ; Перевірити позицію курсору.

    jne n33

    mov byte ptrds:[xx-shift],0

    inc byte ptrds:[yy-shift]

n33:

    inc byte ptrds:[xx-shift]     ; Увеличить X на 1.

    call kurpos             ; Встановити курсор.

n4:

    cmp al,1       ; ESC ?

    jne rd1        ; Якщо ні — далі.

    cmp byte ptrds:[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

    moval,es:[41ah]    ; Взяти кінець буферу

    moves:[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 ptrds:[flag-shift],0

    je nh

    mov al,byteptr ds:[wx-shift]

    cmp byte ptrds:[xx-shift],al

    jne lab

    mov al,byteptr ds:[wy-shift]

    cmp byte ptrds:[yy-shift],al

    je rr

lab:

    call labela   ; Виділити.

    jmp rr

nh:

    mov al,byteptr ds:[xx-shift]

    mov byte ptrds:[x1-shift],al

    mov al,byteptr ds:[yy-shift]

    mov byte ptrds:[y1-shift],al

rr:

    pop ax

    mov byte ptrds:[flag-shift],1

    ret

here endp

kurpos proc

;  Встановлюєкурсор.

    push ax

    mov ah,02h

    mov dh,byteptr ds:[yy-shift]

    mov dl,byteptr ds:[xx-shift]

    mov bh,0

    callcallvideo

    pop ax

    ret

kurpos endp

labela proc

; Змінює колірпоміченого тексту.

    cmp byte ptrds:[fl2-shift],0

    je f0

    call unlabel

    call ifswap

    jmp f1

f0:

    mov al,byteptr ds:[x1-shift]

    mov byte ptrds:[wx-shift],al

    mov al,byteptr ds:[y1-shift]

    mov byte ptrds:[wy-shift],al

    call ifswap

f1:

    mov byte ptrds:[fl2-shift],1

    mov al,byteptr ds:[x1-shift]

    mov byte ptrds:[tx-shift],al

    mov al,byteptr ds:[y1-shift]

    mov byte ptrds:[ty-shift],al

hh:

    push cx

    push dx

    mov ah,02h  ;Змінити позицію курсору.

    mov dh,byteptr ds:[ty-shift]

    mov dl,byteptr ds:[tx-shift]

    mov bh,0

    callcallvideo

    mov ah,08h  ;Считати символ/атрибут.

    mov bh,0

    callcallvideo

    mov byte ptrds:[scrr-shift],ah

    mov ah,09h  ;Записати символ з ізмененим атрибутом.

    mov bl,byteptr ds:[scrr-shift]

    add bl,15

    mov cx,1

    mov bh,0

    callcallvideo

    pop dx

    pop cx

    mov dl,byteptr ds:[tx-shift]

    cmp dl,byteptr ds:[xx-shift]

    je ok

as:

    inc byte ptrds:[tx-shift]

    cmp byte ptrds:[tx-shift],80

    jne hh

    mov byte ptrds:[tx-shift],0

    inc byte ptrds:[ty-shift]

    jmp hh

ok:

    mov al,byteptr ds:[yy-shift]

    cmp byte ptrds:[ty-shift],al

    je rro      ;Якщо кінець, то вийти,

    jmp as      ;інакше оброблювати наступний символ.

rro:

    mov al,byteptr ds:[xx-shift]

    mov byte ptrds:[wx-shift],al

    mov al,byteptr ds:[yy-shift]

    mov byte ptrds:[wy-shift],al

    ret

labela endp

unlabel proc

; Встановлюєколір поміченого тексту.

    push ax

    push dx

    push cx

    mov al,byteptr ds:[x1-shift]

    mov byte ptrds:[tx-shift],al

    mov al,byteptr ds:[y1-shift]

    mov byte ptrds:[ty-shift],al

tl:

    mov ah,02h     ; Змінити позицію курсору.

    mov dh,byteptr ds:[ty-shift]

    mov dl,byteptr ds:[tx-shift]

    mov bh,0

    callcallvideo

    mov ah,08h     ; Считати символ/атрибут.

    mov bh,0

    callcallvideo

    mov byte ptrds:[scrr-shift],ah

    call ToPrn

    mov ah,09h     ; Записати символ з востановленим атрибутом.

    mov bl,byteptr ds:[scrr-shift]

    sub bl,15

    mov cx,1

    mov bh,0

    callcallvideo

    mov al,byteptr ds:[wx-shift]

    cmp byte ptrds:[tx-shift],al

    je don

nt:

    inc byte ptrds:[tx-shift]

    cmp byte ptrds:[tx-shift],80

    jne tl

    call PrnEnt

    mov byte ptrds:[tx-shift],0

    inc byte ptrds:[ty-shift]

    jmp tl

don:

    mov al,byteptr ds:[wy-shift]

    cmp byte ptrds:[ty-shift],al

    je ex      ;Якщо кінець, то вийти,

    jmp nt       ;інакше оброблювати наступний символ.

ex:

    pop ax

    pop cx

    pop dx

    ret

unlabel endp

ToPrn proc

;  Печатаетсимвол.

    test byte ptrds:[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 ptrds:[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,byteptr ds:[y1-shift] ; Порівняти координати Y1 и YY

    cmp al,byteptr ds:[yy-shift]

    jg zq

    jl qw

    mov al,byteptr ds:[x1-shift] ; Порівняти координати X1 и XX

    cmp al,byteptr ds:[xx-shift]

    jng qw

zq:                   ; Якщо треба змінити,

    mov al,byteptr ds:[yy-shift]   ; змінюєм.

    mov byte ptrds:[y1-shift],al

    mov al,byteptr ds:[xx-shift]

    mov byte ptrds:[x1-shift],al

    mov al,byteptr ds:[wx-shift]

    mov byte ptrds:[xx-shift],al

    mov al,byteptr ds:[wy-shift]

    mov byte ptrds:[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

    movdi,test_vector-shift

    mov al,09h      ; Перевірити вектор преривання Int09h.

    movdx,int_09h-shift

    call di

    jnenot_remove

    mov al,2fh      ; Перевірити вектор преривання Int2fh.

    movdx,int_2fh-shift

    call di

    jnenot_remove

    mov al,28h      ; Перевірити вектор преривання Int28h.

    movdx,int_28h-shift

    call di

    jnenot_remove

    mov al,08h      ; Перевірити вектор преривання Int08h.

    movdx,int_08h-shift

    call di

    je uninstall

not_remove:

    movax,notremove_mess-shift

    push ax

    push ax

    call mess

    ret

uninstall:

    movax,remove_mess-shift

    push ax

    xor ax,ax

    push ax

    call mess

    movcx,resethandler-shift

    mov al,09h       ; Восстановити вектор преривання Int09h.

    movdi,int_09h_vect-shift

    call cx

    mov al,2fh       ; Восстановити вектор преривання Int2fh.

    movdi,int_2fh_vect-shift

    call cx

    mov al,28h       ; Восстановити вектор преривання Int28h.

    movdi,int_28h_vect-shift

    call cx

    mov al,08h       ; Восстановити вектор преривання Int08h.

    movdi,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

    movdi,code_table-shift     ; Загрузити сміщення

    movsi,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

    callcallvideo

    mov ah,8

    callcallvideo

    cmp dh,15

    jb lab_1

    cmp dl,27

    jb exch_noth

    jmp shortexch_attr

lab_1:

    cmp dh,11

    jb lab_2

    cmp dl,52

    ja exch_attr

    jmp shortexch_code

lab_2:

    cmp dl,52

    ja exch_noth

exch_code:

    xchg al,byteptr [di]   ; Заменити код символа.

    inc di

exch_attr:

    xchg ah,byteptr [si]   ; Заменити атрибут.

    inc si

exch_noth:

    mov bl,ah         ; Вивести символ.

    mov cx,1

    mov ah,9

    callcallvideo

    inc dx

    pop cx

    loop loop_2

    inc dh

    pop cx

    loop loop_1

    mov dx,1900h        ; Убрати курсор.

    mov ah,02h

    callcallvideo

    ret            ; Вийти з процедури.

xchgmess endp

mess proc

    push bp

    mov bp,sp

    push bx

    mov bh,byteptr ds:[current_video_page-shift]

    mov bl,byteptr ds:[attribute_table-shift]

    push bx          ; Вивести вікно повідомлення.

    call xchgmess

    pop bx

    mov dx,0b29h        ; Вивести текст повідомлення.

    mov si,wordptr [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

    loopmess_loop

    pop bx

wait_mess:

    mov ah,0          ; Ждати натиснення клавиши.

    int 16h

    call xchgmess       ; Восстановити екран.

    pop bx

    pop bp

    ret 4           ; Вийти з процедури.

mess endp

;         Таблицяатрибутів вікна повідомлення.

attribute_tabledb 29 dup(4eh),14 dup (206),13 dup (4eh)

        db07h,07h

        db 28 dup(4eh)

        db07h,07h

        db 4eh,26dup (206),4eh

        db07h,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       ; Встановити курсор в нужну позицию.

    callcallvideo

    lodsb

    or al,al       ; Якщо зустрився кінець строки,

    jzend_typestr    ; то вихід.

    mov cx,1

    mov ah,9

    callcallvideo

    inc dx        ; Определити позицію для вивода

    jmp shorttypestr_loop; следуючого символу.

end_typestr:

    push dx        ; Убрати курсор.

    mov dx,1900h

    mov ah,2

    callcallvideo

    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:

    loopspeaker_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   ;Якщо кінець строки, то вихід.

    jeend_teletype

    callcallvideo; Вивести символ.

    jmp shorttype_next_char

end_teletype:

    ret

teletype endp

;********************Кінець файлу TELETYPE.ASM **********************

еще рефераты
Еще работы по информатике, программированию