Смекни!
smekni.com

Програма Txtprintcom - резидентна програма для швидкого і зручного друкування виборчого тексту (стр. 3 из 4)

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]