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]