КАК СДЕЛАТЬ РЕЗИДЕНТНУЮ ЗАДАЧУ ФОНОВОЙ.
(С) Игорь Балацкий. г. Ток млк, 199S.
ТТЛ гп гпптгтгггп 1111гп пттггп
сделать резидентную програнну фоновой. Резидентная задача - это программа, постоянно находящаяся я памяти. Например, подпрограммы ядра системы !a-Dos также являются резидентными. Резидентную задачу можно запустить » любой момент времени. подав команду 9 и имя задачи. Но можно, при исобхо-диности. сделать ее фоновой (подпрогрвииа будет запускаться на выполнение каждые 20 ниллисе-кунд автоматически).
Например, мы хотии. чтобы в нижней строке экрана распечатывалось содержииое девяти ячеек па-ияти, начиная с адреса ADDR. Для этого напиаеи на ассеиблере подп-рограииу веаогу view reside, оттранслируем ее и скопируем на дискету в формате Ia-Doa.
|
ORG |
2S000 |
R0 |
DEFV |
START |
|
DEFV |
«0000 |
START |
LP |
HL.MV |
|
LD |
A.»FF ; |
|
LD |
C.»1E |
|
RST |
• 10 |
|
RET |
|
|
DEFV |
•0000 ; |
MV |
LD |
DE.MV-2 ; |
|
LD |
HL.tSOEO |
R7 |
LO |
{R9»1).HL |
R1 |
CALL |
HEX4 |
|
LD |
|
MNEXT |
LD |
A.' |
R2 |
CALL |
HEX0 ; |
|
LD |
A.(DS) ; |
|
INC |
DB |
R3 |
CALL |
HEX2 |
|
DJNZ |
MNEXT ; |
|
XOR |
A |
|
RET |
|
НЕХ4 |
LD |
A.D ; |
RS |
CALL |
HEX2 |
|
LD |
A.E ; |
НЕХ2 |
PUSH |
AF |
|
RRA |
|
|
RRA |
|
|
RRA |
|
|
RRA |
|
R6 |
CALL |
HBX1 |
|
POP |
AF |
НЕ XI |
AND |
•OF |
адрес инициализации при загрузке
7??
НЬ=адрес самого резидента А—код "установить" устаиов.-выключ. фоновую задачу рестарт Ib-Dos возврат в оболочку два байта для сохранения адреса следующей фонолой задачи DE«адрес деаяти распечатываемых ячеек ; HL-адрес нижней строки экрана ; сохранить в переиенной напечатать адрес иэ DE цикл на девять байт код пробела
печать кода иэ аккумулятора Ажбайт иэ (DE) увеличить DE
печать числа из аякуиулятора повторить для всех девяти байт сбросить флаг С возврат
А > число из D печать числа иэ А А « чисяо из Е сохранить А
разделить число а А иа 16
напечатать иладвий полуба!
восстановить А
выделить иладвий полубайт
j inn i п i n 111111 'АЧ'А'А'А'А'МЧ*" Ч'А'-'А'&'А'1111111111111111111
CP |
• ЗА |
преобразовать число |
JR |
С,НВХО |
/ |
ADD |
A,«07 |
/ |
PUSH |
DE |
сохранить DE |
PUSH |
ВС |
сохранить ВС |
CALL |
PR |
напечатать сиивол из А |
POP |
ВС |
восстановить ВС |
POP |
DE |
восстановить DE |
RET |
; возврат |
HL * 8 • A
i DE * адрес алфавита в ПЗУ HL в адрес символа в алфавит* ОЕ в адрес сиивола в алфавите
; HL в текущий адрес дда печ цикл для прорисовки сиивола
PUSH CALL EXX
LD
PUSH LD
LDIR
POP
EXX
LD
DI
OUT
LO
OCT
EXX
LS
LD
LDIR EX
LD
LD OUT
копировать байт ив / алфавита иа экраи
/
повторить для вс*го сиивола
; HL в текущий адрес печати сиивола HL • адрес печати сдедува|его сиивола ; сохранить В переменной ; адрес выхода из драйвера ; адрес инициализации драйвера ; выход
; В & длина файла в блоках ; DE в ноиер первого блока на диске ; HL в адрес выгрузки файла в паияти ОЕ : сохранить ноиер блока
ВАИК ; ОБ'a PORT1,PORT2; HI.'- адрес блока
; поиеиять регистры DE,ADR_B ; DE в адрес буфера ВС ; сохранить текущую длину
ВС,LEN_B I ВС в длина буфера
; скопировать блок из файла в буфер ВС ; В " текущая длина файла
; поиеиять регистры ВС.Й7ГРО ; ВС в адрес PORT!
j запретить прерывания (С).0 ; яыставить PORT1
В.аРГ ; ВС в адрес PORT2
(С).Е ; выставить PORT2
DE.HL ; DE в адрес блока иа диске
HL.ADR.В ; HL В адрес буфера ВС,LEN_B ; ВС в длина буфера
; скопировать блок на диск DE.HL ; HL в текущий адрес выгрузки
ВС.Я7ГР0 ; ВС в адрес PORT1 А.>10 ; нулевой банк
(С),А ; PORT1 в исходное состояние
H.tOO ; L.A } HL.HL : HL.HL ; HL,HL ; Г)Е.«ЗСОО HL.HL ; DE.HL ; HL,>50E0 B,»0S ; A,(DE) ; (HL),A ; HL i
DE J
CHAR : HL,(R9«1) L ;
(R9*1).HL AP A
LD
ID
ADD
ADD
ADD
LD
ADD
EX
LD
LD
LD
LD
INC
IMC
DJNZ
LD
IHC
LD
R9
CHAR
RIO
R4
QUIT IN 1С
j 11 nu 111 и hi 111 111I'j'-'&'A'l11" "1mti ||||п||г||
; маркер таблицы адресов настройки
m i ill п M11 ivi 11
DEFV |
•FFFF |
DEFV |
RO-1 |
DEFV |
START |
DEFV |
HV |
DFFV |
R 1 |
DEFV |
R2 |
DEFV |
R1 |
DEFV |
R4 |
DEFV |
RS |
DEFV |
R6 |
DKFW |
R7 |
DEFV |
R8 |
DEFV |
R9 |
DEFV |
RIO |
Переименуем полученный файл, назвав его ir«.t«t, загрузим в память компьютера и запустии на исполнение. В нижней строке экрана напечатается адрес и девять ячеек памяти, в первык двук будут нули. После этого иы вериеися в оболочку, теперь запустим любую програину (например. текстовый редактор - наведя курсор иа текстовый файл и накав <«> ). Мы /видим , что нижняя строка перепеча-тывается поверх окна редактора, а в первых двух ячейках будет записан адрес фоновой задачи иерцаиия курсора, то есть нава фоновая задача работает. Чтобы изменить адрес, с которого начинается вывод на экран, достаточно иэиенить содеркииое двух ячеек в резиденте по адресу загрузки ♦ 16 Эайт.
Напиаеи иа ассеиблере командный файл: аеяюгу view соювапЛег, которому поручим проверку - есть ли в памяти резидент Mvr.tes и, если его нет, то установить резидент и запустить на исполнение. Затеи вывести окно с надписью "ADRKSS:", ввести адрес с клавиатуры и передать его в ръэмдент. То есть, с помощью этого командного файпа мы сиокеи оперативно иэисиять начальный адрес ячеек, яыводииых на экран.
|
|
ORG |
24000 |
|
|
MVC |
LD RST |
C,»08 ; ожидает отпускания клавиши •10 ; рестарт Is-Doc |
|
|
LD |
ВС , • 10 D8 |
; В т иаксииальное количество резидентов С * начальный нонер резидента |
|
FIND |
PUSH |
ВС |
цика поиска резидента |
|
|
LO |
А,С |
А ■ текущий номер резидента |
I |
|
LO |
С.»16 |
atchn |
|
|
RST |
• 10 |
рестарт 1в-0о« |
|
|
JR |
NC.AD_N |
если резидент с таким номером есть, то переход на проверку ииени |
|
NOR |
POP |
ВС |
восстановить значение ВС |
| |
|
INC |
С |
С * новый иоиер резидента |
|
|
DJNZ |
FIND |
повторить поиск резидента |
< |
|
|
|
если резидент не найден, то установить его |
|
|
LD |
HL.com |
адрес коианды "aet avr.rea" |
|
|
LD |
С,MB |
RUN |
|
|
RST |
• 10 |
рестарт Is-Doe |
|
|
RET |
С |
ячход при оаибке |
|
|
LO |
HL,COM2 |
HL в адрес коианды зяпуска резидента |
|
|
LD |
С. «48 |
RUN |
|
|
RST |
• 10 |
рестарт 1я-0оя |
|
|
JR |
NVC |
повторить «се сначала |
J
inmrii 11 mjmiin 11mum 11 m i MI
LD ВС,>000A ; ВС * смещение для имени
ADD HL,ВС ; HL ■ ядрес имени резидента
LD DB,COM2*1 ; DB » адрес текста "avr"
LD В, «08 ; В я длина имени резидента
P1_N LD АЛОВ) ; считать байт эталона
CP (HL) ; сравнить с ииенем резидента
JR NZ.NO.R ; если иия не совпадает, то переход
INC Г5 ; следующий байт эталона
INC HL ; следующий байт имени
DJNZ xi_N ; повторить для всего имени
POP ВС ; восстановить регистры
LD С,«ОБ ; ВС а сиещение для адреса резидента
XOR А ; сбросить флаг С
SBC HL,ВС ; (HI.) ■ адрес avr.rea
LO В, ''HL) : В ■ иладаий байт адреса avr.rea
INC HL ;
LD D,(HL) ; d а старший байт адреса avr.res
LD HL,16 ; сиещение для адреса "вывода"
ADD HL.DE j HL ■ адрес адреса начала вывода
LD (BN»1),HL t сохранить
LD A. «01 ; А а код "без ранки"
LO IX.HIND ; IX а вектор окна
LD С,«61 , win (открыть окно)
RST «10 ; рестарт Ia-Doa
LO С,*66 ; prwln (печать текста окна)
RST «10 ; рестарт Ia-Doa
INPUT LD С,>07 ; Input key (оямдает наватия клааиви и
; возвращает ее код в регистре А)
RST «10 ; рестарт 1в-0оя
PUSH АГ ; сохранить код клавиши
LD С,«08 ; по key (онидает наватия клааиви)
RST «10 ; рестарт Ia-Doa
POP АГ ; восстановить в А код клавиши
CP «00 ; если "ENTBR", то
JR Z,ENTER ; переход на окончание ввода
CP '0' ;
JS С,INPUT ;
CP ' 91 *1 ;
JR C.NUM ; если ие код шестнадцатиричного
RES Ь .А ; числа, то переход на повторный
CP 'А' ; ввод символов
JR С,INPUT ; /
CP 'Г'»! ; /
JR НС.INPUT ; /
huh LD В,A ; В ■ код сиивола
LD HL.POS ; HL * адрес счетчика сииволоа числа
XOR А ; А а 0
С? (HL) ; сравнить со счетчиком
JB I,INPUT ; если введены все сииаолы, то
; переход на опрос клавиатуры
ВМС (HL) ; уменьшить счетчик
■1 LD HL.TXT1 ; HL я адрес числа в тексте окна
LD (HL),В ; сохранить в тексте введенный сиивол
INC HL ; HL » адрес следующего сиивола числа
LD (N*1),HL ; сохранить для следующего сиивола
LD С,«66 ; prwln (печать текста окна)
RST »10 ; рестарт Ia-Doa
I I I I 11 I 111111 I I Ч 11II
,.пттпЛт7т,п^Штпнптттттгтт
KNTER |
LD |
A.(POS) |
» |
|
|
AND |
A |
« |
если введены не все символы, то |
|
JR |
NZ,INPUT |
; / переход на ввод |
|
LD |
HL.TXTl |
! |
HL ■ адрес числа в тексте окна |
|
CALL |
AIR |
t |
расчет стараего байта числа |
|
LD |
D, A |
S |
D ■ стараий байт |
|
CALL |
ADR |
|
расчет иладаего байта числа |
|
LD |
*.A |
, |
Е а иладаий байт |
EN |
LD |
HL,<0000 |
; HL ■ адрес а резиденте для передачи |
|
|
|
• |
в него адреса вывода |
|
LD |
(HL).E |
|
|
|
INC |
HL |
г |
запись в резидент адреса вывода |
|
LD |
(HL).D |
» |
/ |
|
XOR |
A |
9 |
сбросить флаг С |
|
LD |
A,»F2 |
t |
код "обновить панель" |
|
RET |
|
i |
возврат а оболочку |
ADR |
CALL |
ADO |
9 |
символ из (HL) преобразуется а число |
|
SLA |
A |
i |
|
|
SLA |
A |
0 |
сдвинуть число а старший полубайт |
|
SLA |
A |
• |
/ |
|
SLA |
A |
• |
/ |
|
LD |
C.A |
0 |
С ■ старший полубайт числа |
|
CALL |
ADO |
i |
преобразовать сладуюя|ий сииаол |
|
OR |
С |
; |
словить со стараим полубайтом |
|
RRT |
|
: |
возврат |
ADO |
LD |
A.(HL) |
• |
|
|
SUB |
•О' |
• |
|
|
CP |
10 |
0 |
символ иэ (HL) преобразуется я число |
|
JR |
C.AD1 |
i |
/ |
|
SUB |
•07 |
I |
/ |
AD1 |
INC |
HL |
; |
увеличить адрес в HL |
|
RET |
|
i |
возврат |
POS |
DEFB |
•04 |
» |
счетчик введенных сииаолов |
com |
DEFM |
'S:RES*et S:RKSav.res' ; текст первой команды |
|
DEFB |
•0D |
• |
код "ENTER" |
С0И2 |
DEFM |
'tavr |
|
; текст второй коианды |
|
DEFB |
•0D |
# |
код "ENTER" |
MIND |
|
|
# |
вектор окна |
|
DEFB |
• OA |
J |
координата X (8*8) верхнего лев. угла окна |
|
DEFB |
•0B |
• |
координата У (8*8) верхнего лев. угла окна |
|
DEFB |
•03 |
0 |
высота окиа (8*8) |
|
DEFB |
•ОС |
: |
длина окиа (8*8) |
|
DEFB |
%01111000 |
; цветовые атрибуты окиа |
|
DEFB |
• FF |
9 |
??? |
|
DEFB |
• OE |
0 |
координата левой границы текста окна (6*8) |
|
DEFB |
• OE |
0 |
длина строки текста (6*8) |
TXT |
DEFM |
' Adross: |
; текст окна |
TXT1 |
DEFM |
• • |
0 |
место под аводииый' адрес |
♦айлы avc.coa и avr.res приведены иною в качестве примера и, хотя они япояие работоспособны, практическое применение их весьиа
неудобно. Но я и ие задавался
целые сделать хороямй интерфейс пользователю, а лишь хотел показать, как сделать резидентную задачу, работаацуг в фоновой режи-ие.