Орион-Про/Примеры использования подпрограмм BIOS

Материал из Emuverse
Перейти к: навигация, поиск
Red copyright.png Данный материал защищён авторскими правами!

Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей.

Автор: (C) 1990-1996 ORIONSOFT

1. Аннотация

В данном руководстве описан порядок и рассмотрены примеры использования некоторых стандартных подпрограмм BIOS в режиме «Orion-Pro». Значительная часть вопросов касается применения драйвера дисплея «TV-PRO». Работоспособность приведенных фрагментов программ проверена на ассемблере TASM фирмы «OrionSoft».

2. Общие положения

Описываемые подпрограммы BIOS доступны только в режиме «Orion-Pro», поэтому программа пользователя при старте должна проверять, установлен ли данный режим. Указанную проверку можно выполнить с помощью следующих команд:

START:IN A,(0AH)    ;ЧИТАТЬ ПОРТ ДИСПЕТЧЕРА
       RLCA          ;"CY" - РЕЖИМ "O-128"
       JP NC,...     ;НОРМАЛЬНОЕ ПРОДОЛЖЕНИЕ ПРОГРАММЫ
       LD HL,PROREQ
       CALL 0F818H
       JP ...        ;ВЫХОД ИЗ ПРОГРАММЫ 
       ;
PROREQ:DB 1FH,07H,1BH,'Y',2BH,31H
       DB '"ORION-PRO" MODE IS REQUIRED!',0

Если программу, начинающаяся с такой проверки, запустить в режиме «Orion-128», то на экран будет выведено сообщение:

"ORION-PRO" MODE IS REQUIRED!
(Требуется режим «Orion-Pro»)

Обращаем Ваше внимание на то, что сообщение выводится заглавными латинскими буквами, так как коды этих букв одинаковы в любой кодировке (КОИ7, КОИ8, ALT).

В BIOS предусмотрена возможность входа в режим «Orion-Pro» из режима «Orion-128», однако этот вопрос требует особого рассмотрения и здесь не обсуждается.

В некоторых управляющих векторах BIOS (в частности 0F806H, 0F80CH, 0F80FH, 0F82AH) имеются парные («зеркальные») подпрограммы: для установки определенных параметров и для получения их значений. Если разрабатываемая программа не предназначена для резидентной (постоянной) настройки каких-либо параметров, то их прежние значения должны быть возвращены при выходе из программы. Пусть, например, Ваша программа временно изменяет коды цветов фона и изображения, тогда последовательность вызова соответствующих стандартных подпрограмм должна быть следующей:

      . . .
      LD A,11
      CALL 0F80CH   ;(C) - ТЕКУЩИЙ ЦВЕТ ФОНА
      LD B,C
      LD A,13
      CALL 0F80CH   ;(C) - ТЕКУЩИЙ ЦВЕТ ИЗОБРАЖЕНИЯ
      ;
      PUSH BC       ;СОХРАНИТЬ КОДЫ ЦВЕТОВ
      . . .
      ;ДАЛЕЕ МОЖНО МЕНЯТЬ КОДЫ ЦВЕТОВ С ПОМОЩЬЮ
      ;ФУНКЦИЙ A=10, A=12 ВЕКТОРА 0F80CH
      . . .
      POP BC
      ;
      LD A,12
      CALL 0F80CH   ;ВЕРНУТЬ ЦВЕТ ИЗОБРАЖЕНИЯ
      LD C,B
      LD A,10
      CALL 0F80CH   ;ВЕРНУТЬ ЦВЕТ ФОНА
      . . .
      ;КОНЕЦ ПРОГРАММЫ

Специальные программы резидентной установки параметров, например, загрузки шрифтов пользователя или настройки таблиц функциональных клавиш, могут «безвозвратно» изменять требуемые значения. Перечень сохраняемых и несохраняемых параметров определяет сам программист, исходя из того, что должна делать программа.

3. Ответы на вопросы

В данном разделе мы попытаемся в простой форме ответить на наиболее актуальные вопросы, связанные с применением стандартных подпрограмм BIOS, в частности драйвера «TV-PRO».

ВОПРОС 1
«В таблице векторов BIOS появилось много новых подпрограмм. Я не знаю, с чего начать их изучение, не понимаю, как их использовать».

ОТВЕТ 1:

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

Каждая из стандартных подпрограмм BIOS имеет определенное функциональное назначение и служит для выполнения элементарной функции, действие которой описано в документации. Если Вы с чем-то не можете разобраться — обращайтесь с вопросом к нам.

Заметим, что фирмой «OrionSoft» разработана библиотека подпрограмм для популярного компилятора TURBO PASCAL V3.0, обеспечивающая реализацию всех возможностей BIOS «Orion-Pro», в том числе драйвера «TV-PRO». При наличии этой библиотеки процесс создания качественных программ для «Pro» становится простым и естественным, и программист освобождается от необходимости учета той массы тонкостей, которые возникают при работе с ассемблером. Если же Вы решили проявить упорство и детально разобраться с нашими подпрограммами BIOS, прочтите настоящее руководство, и многие вопросы отпадут сами собой.

Для начала рассмотрим назначение управляющих кодов и последовательностей в подпрограмме вывода символа 0F809H. Чтобы проверить их действие, наберите простую программу (здесь и далее мы будем подразумевать, что каждая программа начинается с блока проверки, описанного в П.2):

      . . .         ;БЛОК ПРОВЕРКИ ИЗ П.2
      ;
   M1:CALL 0F803H   ;ВВОД СИМВОЛА С КЛАВИАТУРЫ
      LD C,A
      CALL 0F809H   ;ВЫВОД СИМВОЛА НА ЭКРАН
      JR M1

После ассемблирования и запуска программы на экране появится мигающий курсор. Возьмите описание управляющих кодов «TV-PRO» и проверьте их работу, нажимая на соответствующие клавиши (заметим, что обычно управляющие коды и ESC-последовательности поступают на вход подпрограммы 0F809H не напрямую с клавиатуры, а формируются программно). Ниже предлагается ориентировочный порядок освоения управляющих кодов. Для обозначения нажатия символьной клавиши одновременно с клавишей <УПР> будем использовать значок ^ («крышечка»). Например, комбинация ^P соответствует управляющему коду 10H и означает, что сначала необходимо нажать клавишу <УПР>, а затем, не отпуская ее, клавишу <P> (лат).

Попробуйте нажать клавиши управления курсором — курсор будет перемещаться по экрану, в том числе при нажатии клавиш <ВК>, <ТАБ>.

Клавиша <ПС>, нажатая при нахождении курсора в нижней строке экрана, вызывает его «прокрутку» (скроллинг).

Клавиша <СТР> очищает экран и устанавливает его в левый верхний угол (Home). Аналогично действует клавиша <Угол>.

Для проверки вывода символов с кодами 00H..1FH нажмите последовательно комбинацию ^P, а затем второй управляющий символ, например, ^E (05H). На экране появится изображение символа с кодом 05H.

Действие управляющих ESC-последовательностей можно проверить, нажимая в начале клавишу <АР2>, а затем последовательно вводя символы, которые следуют за кодом ESC.

<АР2><6> — после последовательного нажатия клавиш <АР2> и <6> символы будут выводиться в инверсном виде. Для отключения инверсии введите <АР2><7>.

<АР2><8> — включает режим подчеркивания выводимых символов символом курсора, <АР2><9> — выключает режим подчеркивания.

<АР2><R>^J — устанавливает курсор в виде прямоугольника высотой 10 пикселей (комбинации ^J соответствует код 0AH=10). Попробуйте теперь включить режим подчеркивания с помощью <АР2><8> - символы будут «забиваться». Поэтому подчеркивание можно использовать только со стандартным курсором в виде черточки: попробуйте набрать <АР2><R>^A.

Заполните экран любыми символами. Подведите курсор в середину экрана и проверьте работу последовательностей <АР2><L> и <АР2><M>, которые соответственно вставляют и удаляют строку.

Проверьте также действие <АР2><K> и <АР2><J> (стирание текста от курсора до конца строки и стирание текста от курсора до конца экрана).

Нажатие <АР2><E> приведет к очистке экрана без изменения позиции курсора, а <АР2><H> — к установке курсора в позицию «Home» без очистки экрана.

Можете поэкспериментировать с режимами отображения курсора, нажимая <АР2><:>, <АР2><;>, <АР2>< < >, <АР2><=>. Действие последовательностей <АР2><:> и <АР2><=> будет выглядеть одинаково, но на самом деле это не так. В первом случае курсор отображается при выводе любого символа, во втором — только при вводе с клавиатуры.

Теперь можно проверить работу «TV-PRO» в различных цветовых режимах и с различными экранами.

Для перехода в 4-цветный режим нажмите <АР2><U><4>. На экране появится цветной «мусор». Установите альтернативную палитру нажатием клавиш <АР2><T><1>. Задайте цвета фона и изображения с помощью последовательности <АР2><F><1><0> (символы будут выводиться белыми на синем фоне). Для очистки экрана нажмите клавишу <СТР>.

Напомним, что при переключении цветового режима программист должен всегда устанавливать требуемые цвета фона и изображения, так как коды цветов в различных режимах разные.

Попробуйте поменять цвета с помощью нажатия клавиш <АР2><F><3><2> и других комбинаций.

Переключите номер экрана, нажав <АР2><S><1>. Всего доступно 4 экрана, и на каждый Вы можете попробовать вывести информацию, как было описано выше. Однако, если Ваша программа находится в странице 0 или 1 ОЗУ, будьте осторожны: выводимые на экран данные могут «затереть» коды программы. Чтобы этого избежать, разместите свою проверочную программу по адресу ORG = 0F000H, и Вы получите возможность «поиграть» со всеми 4мя экранами.

Аналогично можно проверить работу драйвера в 8-цветном и 16-цветном режимах, а также с широким экраном (номера цветовых режимов нечетные).

Для выхода из программы нажмите «Сброс».

ВОПРОС 2
«Работая на 'Орион-128' я заметил, что существующие драйверы клавиатуры не совсем удобны, особенно для среды CP/M-80: коды клавиш управления курсором (да и другие) не соответствуют общепринятым. Изменилось ли что-нибудь в компьютере 'Orion-Pro' ?»

ОТВЕТ 2:

Драйвер клавиатуры в режиме «Orion-Pro» имеет гораздо более широкие возможности, чем в режиме «Orion-128». Эти возможности описаны в документации. Здесь мы коснемся проблемы замены кодов клавиш, генерируемых клавиатурой.

Вариант А. Замена кодов клавиш управления курсором

Пусть необходимо получить следующие коды клавиш курсора:

    <влево>         - 08H (^H)
    <вправо>        - 04H (^D)
    <вверх>         - 05H (^E)
    <вниз>          - 18H (^X)
    <УПР>+<влево>   - 01H (^A)
    <УПР>+<вправо>  - 06H (^F)
    <УПР>+<вверх>   - 12H (^R)
    <УПР>+<вниз>    - 03H (^C)

Такая замена выполняется с помощью фрагмента программы:

      . . .
      LD BC,0408H
      LD DE,1805H
      LD A,4
      CALL 0F806H
      ;
      LD BC,0601H
      LD DE 0312H
      LD A,6
      CALL 0F806H
      . . .

При всех последующих вызовах подпрограмм KBRD (0F803H) и INKEY (0F81BH) для указанных клавиш будут формироваться заданные коды.

Вариант B. Настройка функциональных клавиш

Рассмотрим пример, в котором необходимо получить функциональные клавиши со следующими генерируемыми кодами:

     <влево>         - 08H (^H)
     <вправо>        - 04H (^D)
     <вверх>         - 05H (^E)
     <вниз>          - 18H (^X)
     <СТР>           - 0BH,04H (^K^D)
     <ИСП>           - 50H,55H,52H,42H,4FH,0DH,59H ('TURBO')
     <K5>            - 19H (^Y)
 
     <УПР>+<K5>      - 11H,19H (^Q^Y)
     <УПР>+<DEL>     - 07H (^G)
 
     <SHIFT>+<влево> - 11H,13H (^Q^S)
     <SHIFT>+<вправо>- 11H,04H (^Q^D)
     <SHIFT>+<вверх> - 11H,12H (^Q^R)
     <SHIFT>+<вниз>  - 11H,03H (^Q^C)

Настройка функциональных клавиш выполняется с помощью специальных таблиц, которые могут быть размещены в одном из сегментов ОЗУ, например с номером 17 (по адресу 4000H в 4й странице памяти). Приводим фрагмент программы:

       . . .
       ;ЗАКАЧКА ТАБЛИЦ В СЕГМЕНТ 17
       IN A,(08H)      ;ТЕКУЩАЯ СТРАНИЦА ОЗУ
       RLCA
       RLCA
       RLCA
       RLCA
       AND 0F0H        ;СТРАНИЦА "ОТКУДА"
       OR 04H          ;СТРАНИЦА "КУДА"
       LD HL,TAB1      ;АДРЕС "ОТКУДА"
       LD DE,4000H     ;АДРЕС "КУДА"
       LD BC,TAB4-TAB1 ;ДЛИНА ТАБЛИЦ
       CALL 0F833H     ;ПЕРЕСЫЛКА (MOVBL)
       ;
       ;УСТАНОВКА АДРЕСОВ ТАБЛИЦ ФУНКЦИОНАЛЬНЫХ КЛАВИШ
       LD C,17         ;N СЕГМЕНТА
       LD HL,4000H     ;АДРЕС НАЧАЛА ТАБЛИЦЫ 1
       LD A,10
       CALL 0F806H
       ;
       LD DE,TAB2-TAB1 ;ДЛИНА ТАБЛИЦЫ 1
       ADD HL,DE       ;АДРЕС НАЧАЛА ТАБЛИЦЫ 2
       LD A,12
       CALL 0F806H
       ;
       LD DE,TAB3-TAB2 ;ДЛИНА ТАБЛИЦЫ 2
       ADD HL,DE       ;АДРЕС НАЧАЛА ТАБЛИЦЫ 3
       LD A,14
       CALL 0F806H
 
       . . .           ;ВЫХОД В ОПЕРАЦИОННУЮ СИСТЕМУ
 
       ;ТАБЛИЦА ОДИНОЧНЫХ ФУНКЦИОНАЛЬНЫХ КЛАВИШ
  TAB1:DB 7     ;ЧИСЛО КЛАВИШ
       DB 4CH,35H,3EH,3DH,40H,27H,2EH ;КОДЫ СКАНИРОВАНИЯ
       DB 01H,08H                     ;<ВЛЕВО>
       DB 01H,04H                     ;<ВПРАВО>
       DB 01H,05H                     ;<ВВЕРХ>
       DB 01H,18H                     ;<ВНИЗ>
       DB 01H,19H                     ;<K5>
       DB 02H,0BH,04H                 ;<СТР>
       DB 06H,'TURBO',0DH,'Y'         ;<ИСП>
       ;
       ;ТАБЛИЦА ФУНКЦИОНАЛЬНЫХ КЛАВИШ ПРИ НАЖАТОЙ <УПР>
  TAB2:DB 2
       DB 2DH,40H                      ;КОДЫ СКАНИРОВАНИЯ
       DB 01H,07H                      ;<УПР>+<DEL>
       DB 02H,11H,19H                  ;<УПР>+<K5>
       ;
       ;ТАБЛИЦА ФУНКЦИОНАЛЬНЫХ КЛАВИШ ПРИ НАЖАТОЙ <SHIFT>
  TAB3:DB 4
       DB 4CH,35H,3EH,3DH              ;КОДЫ СКАНИРОВАНИЯ
       DB 02H,11H,13H                  ;<SHIFT>+<ВЛЕВО>
       DB 02H,11H,04H                  ;<SHIFT>+<ВПРАВО>
       DB 02H,11H,12H                  ;<SHIFT>+<ВВЕРХ>
       DB 02H,11H,03H                  ;<SHIFT>+<ВНИЗ>
       ;
  TAB4:;КОНЕЦ ТАБЛИЦ
       ;
       . . .

После запуска такой программы функциональные клавиши будут настроены до очередного перезапуска компьютера. Для проверки действия настроенных клавиш можно использовать простую программу, описанную при ответе на Вопрос 1 (вместо подпрограммы 0F809H попробуйте подставить 0F815H).

Функциональные клавиши, установленные по варианту «B», в том числе и клавиши управления курсором, будут действовать только при вызове подпрограммы KBRD (0F803H). Допускается смешанное применение вариантов «A» и «B».

Для «закачки» таблиц функциональных клавиш в приведенном примере использовалась подпрограмма 0F833H, выполняющая пересылку блока кодов из одной страницы памяти в другую. Так как область ОЗУ 0F000H..0FFFFH находится в непереключаемом режиме, то доступ к адресам 3000H..3FFFH в пределах сегментов 3, 7, 11, 15, 19, 23, 27, 31 напрямую невозможен. Данная проблема решается включением указанных сегментов в одном из окон ОЗУ.

В следующей программе для хранения таблиц функциональных клавиш используется часть сегмента 19, начиная с адреса 3000H.

       ORG 100H        ;КОДЫ ПРОГРАММЫ НЕ ДОЛЖНЫ БЫТЬ В ОКНЕ 1
       . . .
       ;ЗАКАЧКА ТАБЛИЦ В СЕГМЕНТ 19
       LD HL,WNDBUF    ;АДРЕС БУФЕРА С СОСТОЯНИЕМ ДИСПЕТЧЕРА
       PUSH HL
       CALL 0F842H     ;СОХРАНИТЬ ПОРТЫ ДИСПЕТЧЕРА (RDWIN)
       ;
       IN A,(0AH)
       SET 1,A         ;ВКЛЮЧИТЬ ОКНО "RAM1"
       OUT (0AH),A
       ;
       LD A,19
       OUT (05H),A     ;УСТАНОВИТЬ НОМЕР СЕГМЕНТА В ОКНЕ
       ;
       LD HL,TAB1      ;"ОТКУДА"
       LD DE,7000H     ;"КУДА" - СЕГМЕНТ 19 В ОКНЕ 1
       LD BC,TAB4-TAB1 ;ДЛИНА ТАБЛИЦ
       ;
       PUSH DE
       LDIR            ;ПЕРЕСЫЛКА
       POP HL          ;АДРЕС НАЧАЛА ТАБЛИЦ
       ;
       ;УСТАНОВКА АДРЕСОВ ТАБЛИЦ ФУНКЦИОНАЛЬНЫХ КЛАВИШ
       LD C,19         ;N СЕГМЕНТА
       LD A,10
       CALL 0F806H
       ;
       LD DE,TAB2-TAB1
       ADD HL,DE
       LD A,12
       CALL 0F806H
       ;
       LD DE,TAB3-TAB2
       ADD HL,DE
       LD A,14
       CALL 0F806H
       ;
       POP HL          ;АДРЕС БУФЕРА С СОСТОЯНИЕМ ДИСПЕТЧЕРА
       CALL 0F845H     ;ВОССТАНОВИТЬ ПОРТЫ ДИСПЕТЧЕРА (WRWIN)
       ;
 
       . . .
 
       ;
WNDBUF:DS 6            ;БУФЕР ДЛЯ СОХРАНЕНИЯ ПОРТОВ ДИСПЕТЧЕРА
       ;

Обращаем Ваше внимание на ряд моментов:

  1. Программист должен следить за тем, чтобы коды программы не попали в открываемое окно памяти.
  2. Каждая таблица функциональных клавиш должна полностью размещаться в пределах сегмента ОЗУ с учетом длины таблицы и адреса ее начала.
  3. При вызове вектора 0F806H с номерами функций A=10, A=12, A=14 входное значение адреса HL начала таблицы может указываться как в пределах сегмента, так и в пределах страницы ОЗУ, поскольку два старшие бита адреса не используются. В нашем случае адрес начала первой таблицы в окне 1 равен 7000H, что соответствует адресу 0F000H в пределах страницы 2 или 3000H в пределах сегмента 19.
ВОПРОС 3
«Меня не устраивает действие некоторых специальных клавиш (АЛФ, ГРАФ, ФИКС) на клавиатуре МС7007. В 'Орион-128' было лучше. Можно ли это исправить?»

ОТВЕТ 3:

Можно сделать так, чтобы клавиатура МС7007 работала в «старом» режиме аналогично РК-86. Для переключения клавиатуры МС7007 в этот режим достаточно запустить простую программу:

      . . .
      LD A,1
      CALL 0F806H   ;E - РЕЖИМ КЛАВИАТУРЫ
      SET 7,E       ;УСТАНОВКА ПРИЗНАКА "СТАРОГО" РЕЖИМА
      LD A,0
      CALL 0F806H   ;ПЕРЕУСТАНОВИТЬ РЕЖИМ КЛАВИАТУРЫ
      . . .
ВОПРОС 4
«Как изменить кодировку клавиатуры и дисплея?»

ОТВЕТ 4:

В качестве основной для режима «Orion-Pro» принята альтернативная кодировка. Однако по выбору программиста можно включить КОИ8 или КОИ7. При условии использования стандартного шрифта с матрицей 6x10 пискелей это можно сделать с помощью следующей подпрограммы:

       ;(A) - НОМЕР КОДИРОВКИ:
       ; 0  - АЛЬТЕРНАТИВНАЯ
       ; 1  - КОИ-8
       ; 2  - КОИ-7/Н2
       ; 3  - КОИ-7/Н1
SETCOD:
       AND 03H
       LD B,A
       ;
       LD A,1
       CALL 0F806H  ;E - РЕЖИМ КЛАВИАТУРЫ
       LD A,E
       AND 0FCH
       OR B
       LD E,A       ;НОВЫЙ КОД РЕЖИМА
       LD A,0
       CALL 0F806H  ;УСТАНОВИТЬ РЕЖИМ КЛАВИАТУРЫ
       ;
       LD A,12
       CALL 0F80FH  ;ПОЛУЧИТЬ ТЕКУЩИЙ АДРЕС ЗГ
       SET 7,B      ;ПРИЗНАК АКТИВИЗАЦИИ ЗГ
       LD A,13
       CALL 0F80FH  ;РАСПАКОВАТЬ СТАНДАРТНЫЙ ШРИФТ
       RET

Для проверки работоспособности данной подпрограммы наберите программу:

      . . .
   X1:CALL 0F803H  ;ВВОД СИМВОЛА
      CP 4         ;КЛАВИШИ K1-K4 ?
      JR NC,X2     ;НЕТ
      ;
      CALL SETCOD  ;ИЗМЕНИТЬ КОДИРОВКУ
      JR X1
   X2:LD C,A
      CALL 0F809H  ;ВЫВЕСТИ СИМВОЛ
      JR X1

Эта программа выводит на экран символ, соответствующий нажатой клавише и переключает кодировку при нажатии клавиш <K1>, <K2>, <K3>, <K4> (соответственно ALT, КОИ8, КОИ7/Н2, КОИ7/Н1).

Если Вы планируете использовать загружаемый (нестандартный) шрифт, то Вам надо позаботиться о создании нескольких соответствующих знакогенераторов для каждого типа кодировки, при этом их можно хранить в отдельных файлах и загружать требуемый файл с помощью специальной программы. Другой возможностью является предварительная загрузка всех используемых знакогенераторов в выбранные сегменты ОЗУ с последующим переключением адреса знакогенератора.

ВОПРОС 5
«Как распаковать стандартный шрифт в режиме широких букв?»

ОТВЕТ 5:

Подпрограмма распаковки знакогенератора (функция 13 вектора 0F80FH) формирует стандартный шрифт по указанному адресу. Если заданное значение адреса знакогенератора некорректно (знакогенератор не помещается в сегменте), то распаковка не производится.

Стандартный шрифт с размером знакоместа 6x10 пикселей по умолчанию размещается в сегменте 1FH ОЗУ в пределах адресов 0D000H..D9FFH (1000H..19FFH), однако адрес знакогенератора может быть изменен по усмотрению программиста. Ниже приведен фрагмент программы, выводящей сообщение широкими буквами (с установкой соответствующего курсора) с возвратом к прежнему шрифту. Чтобы восстановить размер курсора, необходимо дополнительно воспользоваться функциями 16, 17, 18, 19 вектора 0F80FH.

                                 . . .
      ;СОХРАНЕНИЕ ПАРАМЕТРОВ ТЕКУЩЕГО ШРИФТА
      LD A,12
      CALL 0F80FH   ;ПОЛУЧИТЬ АДРЕС ЗНАКОГЕНЕРАТОРА
      PUSH BC       ;N СЕГМЕНТА
      PUSH DE       ;ШАГ ШАБЛОНОВ
      PUSH HL       ;НАЧАЛЬНЫЙ АДРЕС
      ;
      LD A,10
      CALL 0F80FH   ;ПОЛУЧИТЬ РАЗМЕРЫ СИМВОЛОВ
      PUSH BC       ;ШАГ ВЫВОДА СИМВОЛОВ
      PUSH DE       ;РАЗМЕРЫ СИМВОЛОВ
      PUSH HL       ;СМЕЩЕНИЕ ШАБЛОНА
      ;
      ;УСТАНОВКА НОВОГО ШРИФТА
      LD B,0C4H     ;КОД РАСПАКОВКИ
      LD C,16       ;НОМЕР СЕГМЕНТА
      LD HL,0       ;АДРЕС В СЕГМЕНТЕ
      LD A,13
      CALL 0F80FH   ;РАСПАКОВКА
      ;
      ;ВЫВОД СООБЩЕНИЯ
      LD HL,WIDE
      CALL 0F818H
      CALL 0F803H
      ;
      ;ВОЗВРАТ ПРЕЖНЕГО ШРИФТА
      POP HL
      POP DE
      POP BC
      LD A,9        ;ВЕРНУТЬ РАЗМЕРЫ СИМВОЛОВ
      CALL 0F80FH
      ;
      POP HL
      POP DE
      POP BC
      LD A,11       ;ВЕРНУТЬ АДРЕС ЗГ
      CALL 0F80FH
      ;
      . . .         ;ВЫХОД В ОПЕРАЦИОННУЮ СИСТЕМУ
      ;
 WIDE:DB 'WIDE LETTERS ',0
      ;
      . . .
ВОПРОС 6
«Как установить собственный шрифт?»

ОТВЕТ 6:

Установка нестандартного шрифта может выполняться как в программе пользователя, так и с помощью специальной системной программы, предназначенной для загрузки шрифтов.

В любом случае знакогенератор с шаблонами символов должен быть задан последовательностью байтов с учетом требований, описанных в документации на драйвер «TV-PRO», и занесен в один из сегментов ОЗУ. Кроме того, знакогенератор необходимо «подключить», указав:

а) размеры символа (с помощью функции A=9 вектора 0F80FH):

  • D — ширина в пикселях;
  • E — высота в пикселях;
  • B — шаг вывода символов по X;
  • C — шаг вывода символов по Y;
  • L — смещение левого столбца битов шаблона в левом столбце байтов;

б) адрес знакогенератора (с помощью функции A=11 вектора 0F80FH):

  • C — номер сегмента ОЗУ;
  • HL — начальный адрес ЗГ в пределах сегмента или в пределах страницы ОЗУ;
  • DE — число байтов между соседними шаблонами в ЗГ (шаг следования шаблонов).

Функции A=10 и A=12 являются обратными по отношению к A=9 и A=11. Используя их, можно включить нужный шрифт только на время работы программы пользователя.

Размеры, шаблон и форма курсора должны устанавливаться отдельно.

ВОПРОС 7
«Как изменить форму курсора?»

ОТВЕТ 7:

При использовании стандартного курсора, который формируется функцией распаковки знакогенератора (A=13 в векторе 0F80FH), его форма может варьироваться от черточки до прямоугольника без изменения шаблона (шаблон стандартного курсора состоит из соответствующего числа байтов 0FFH). Данная возможность реализуется с помощью управляющей последовательности ESC 'R',Byte, которая выдается через подпрограмму TVC (0F809H) и изменяет высоту курсора и его смещение по Y (соответственно значения регистров E и C в функциях A=16, A=17).

Программист может установить свой шаблон курсора, исходя из размеров используемого шрифта или по другой причине. Ниже приведен фрагмент программы, устанавливающей курсор в виде рамочки размером 6x8 пикселей (шаблон курсора для примера помещается в сегмент 17 по адресу 4800H):

      . . .
      ;ЗАКАЧКА ШАБЛОНА КУРСОРА В СЕГМЕНТ 17
      IN A,(08H)    ;ТЕКУЩАЯ СТРАНИЦА ОЗУ
      RLCA
      RLCA
      RLCA
      RLCA
      AND 0F0H      ;СТРАНИЦА "ОТКУДА"
      OR 04H        ;СТРАНИЦА "КУДА"
      LD HL,CUR     ;АДРЕС "ОТКУДА"
      LD DE,4800H   ;АДРЕС "КУДА"
      LD BC,8       ;ДЛИНА ШАБЛОНА
      CALL 0F833H   ;ПЕРЕСЫЛКА (MOVBL)
      ;
      ;УСТАНОВКА ПАРАМЕТРОВ ШАБЛОНА КУРСОРА
      LD C,17       ;НОМЕР СЕГМЕНТА
      LD HL,4800H   ;АДРЕС НАЧАЛА ШАБЛОНА
      LD A,18
      CALL 0F80FH   ;УСТАНОВКА АДРЕСА ШАБЛОНА
      ;
      LD BC,0000H   ;СМЕЩЕНИЕ КУРСОРА ПО X И Y НА ЭКРАНЕ
      LD DE,0608H   ;РАЗМЕРЫ КУРСОРА
      LD L,2        ;СМЕЩЕНИЕ ШАБЛОНА В ЛЕВОМ СТОЛБЦЕ БАЙТОВ
      LD A,16
      CALL 0F80FH   ;УСТАНОВИТЬ РАЗМЕРЫ КУРСОРА
      ;
      ;УСТАНОВКА РЕЖИМА ВЫВОДА КУРСОРА
      ;(НАЛОЖЕНИЕ ПО ИЛИ С СОХРАНЕНИЕМ ИНФОРМАЦИИ)
      LD C,39H      ;КОД РЕЖИМА КУРСОРА
      LD A,14
      CALL 0F80FH
      ;
      CALL 0F803H   ;ВВОД СИМВОЛА С МИГАНИЕМ КУРСОРА
      . . .
      ;ШАБЛОН КУРСОРА
  CUR:DB 3FH,21H,21H,21H,21H,21H,21H,3FH
      ;
      . . .
ВОПРОС 8
«Как сделать так, чтобы количество символов, выводимых на экран по горизонтали и вертикали, было равно заданному?»

ОТВЕТ 8:

Количество символов, которое помещается на экране при выводе с помощью подпрограммы TVC (0F809H), зависит от размеров символов и параметров текущего окна вывода. Соотношения, связывающие эти величины, приведены в документации на драйвер «TV-PRO».

Пусть, например, размеры символов составляют 6x10 пикселей, шаг вывода символов по X и Y равен соответственно 6 и 10. Тогда ширина окна для вывода 80 символов в строке должна быть 6+6*79 = 480 точек, высота окна для вывода 25 строк: 8+24*8 = 200 точек.

Установка окна (должен быть назначен широкий экран 512 точек) может быть выполнена так:

      . . .
      LD B,200      ;ВЫСОТА ОКНА
      LD HL,480     ;ШИРИНА ОКНА
      LD DE,16      ;СМЕЩЕНИЕ ОКНА ПО X
      LD C,28       ;СМЕЩЕНИЕ ОКНА ПО Y
      LD A,16
      CALL 0F80CH   ;УСТАНОВИТЬ ОКНО
      JP C,...      ;ОШИБКА ПАРАМЕТРОВ
      . . .

Установку окна можно выполнить также, используя подфункцию (4/9) функции (4) в векторе 0F80FH. В этом случае размеры и смещение окна указываются в количестве символов:

      . . .
      LD H,25       ;ВЫСОТА
      LD L,80       ;ШИРИНА
      LD D,3        ;СМЕЩЕНИЕ ПО Y
      LD E,3        ;СМЕЩЕНИЕ ПО X
      LD C,9        ;НОМЕР ПОДФУНКЦИИ
      LD A,4        ;НОМЕР ФУНКЦИИ
      CALL 0F80FH   ;УСТАНОВИТЬ ОКНО
      JP C,...      ;ОШИБКА ПАРАМЕТРОВ
      . . .

Очевидно, что установка вторым способом более удобна, так как вычисление ширины и высоты окна в пикселях выполняется автоматически с учетом размеров символов. Однако, смещение окна по X и по Y в пикселях также зависит от размеров символов, что не всегда удобно.

Можно предложить альтернативный вариант: сначала установить окно с помощью подфункции (4/9) вектора 0F80FH, получить его размеры в пикселях с помощью функции (17) вектора 0F80CH, а затем переустановить окно с теми же размерами, но с требуемыми смещениями по X и по Y путем вызова функции (16) вектора 0F80FH.

Для нашего примера:

      . . .
      LD H,25      ;ВЫСОТА В СИМВОЛАХ
      LD L,80      ;ШИРИНА В СИМВОЛАХ
      LD D,0       ;СМЕЩЕНИЕ (ФИКТИВНОЕ)
      LD C,9
      LD A,4
      CALL 0F80FH  ;УСТАНОВИТЬ СИМВОЛЬНОЕ ОКНО
      JP C,...     ;ОШИБКА
      ;
      LD A,17
      CALL 0F80CH  ;B,HL - РАЗМЕРЫ ОКНА В ПИКСЕЛЯХ
      ;
      LD DE,16     ;СМЕЩЕНИЕ ПО X
      LD C,28      ;СМЕЩЕНИЕ ПО Y
      LD A,16
      CALL 0F80CH  ;ПЕРЕУСТАНОВКА ОКНА
      JP C,...     ;ОШИБКА
      . . .
ВОПРОС 9
«Как установить окно размером с полный экран?»

ОТВЕТ 9:

Самый простой способ — последовательно вызвать функции получения и установки номера доступного экрана:

      . . .
      LD A,7
      CALL 0F80CH
      LD A,6
      CALL 0F80CH
      . . .
ВОПРОС 10
«Могу ли я переключить номер доступного экрана или его режим с сохранением параметров текущего окна?»

ОТВЕТ 10:

Это можно сделать следующим образом:

      . . .
      LD A,17
      CALL 0F80CH   ;ПОЛУЧЕНИЕ ПАРАМЕТРОВ ОКНА
      PUSH BC
      PUSH DE
      PUSH HL       ;СОХРАНЕНИЕ ПАРАМЕТРОВ
      ;
      LD C,9        ;НОМЕР РЕЖИМА ЭКРАНА
      LD A,0
      CALL 0F80CH   ;УСТАНОВИТЬ РЕЖИМ ДОСТУПНОГО ЭКРАНА
      ;
      POP HL
      POP DE
      POP BC
      ;
      LD A,16
      CALL 0F80CH   ;ВЕРНУТЬ ОКНО
      . . .
ВОПРОС 11
«Каким образом можно сохранить и восстановить окно экрана?»

ОТВЕТ 11:

Это делается с помощью функций A=19,20,21,22,23 вектора 0F80CH.

Процесс распределения буферной памяти для сохранения окон возлагается на программу пользователя: при каждом сохранении окна адрес буфера в пределах сегментов должен увеличиваться на длину сохраняемых данных, а в случае выхода адреса за пределы 0..3FFFH (16 К) должны выбираться очередные свободные сегменты. Количество сегментов, одновременно необходимых для сохранения одного окна (размерность буфера) зависит от числа экранных плоскостей и определяется текущим цветовым режимом доступного экрана.

Может быть предложен следующий порядок вызова функций для сохранения окна:

  1. Определить адрес начала буфера HL, свободного для сохранения окна, с помощью функции A=20;
  2. Определить необходимую длину буфера DE для размещения данных с помощью функции A=21;
  3. Проверить возможность сохранения окна: HL+DE < 4000H;
  4. Если условие не выполнено, выбрать свободные сегменты и установить адрес начала буфера HL=0 с помощью функции A=19; перейти в начало;
  5. Сохранить окно путем вызова функции A=22 (без параметров).
  6. Сохранить параметры текущего окна и адрес буфера — в стеке или специальных ячейках;
  7. Увеличить адрес начала буфера на длину сохраняемых данных и переустановить его с помощью функции A=19.

Заметим, что пункты 1)4) можно опустить, добавив в конец пункта 5) действия, указанные в пункте 4). Эти действия должны выполняться, если после вызова функции A=22 установлен флаг «CY».

Процесс восстановления последнего сохраненного окна включает следующие пункты:

  1. Получить параметры последнего сохраненного окна и адрес его буфера — из стека или специальных рабочих ячеек;
  2. Установить текущее окно с помощью функции A=16;
  3. Установить адрес буфера с помощью функции A=19;
  4. Восстановить окно с помощью функции A=23.

Приводим фрагмент демонстрационной программы, выполняющей операции сохранения и восстановления окна без контроля переполнения буфера и без организации стековой структуры.

      . . .
      LD A,4
      LD C,9        ;ПОДФУНКЦИЯ УСТАНОВКИ ОКНА
      LD DE,0305H   ;СМЕЩЕНИЕ ОКНА
      LD HL,0810H   ;РАЗМЕРЫ ОКНА
      CALL 0F80FH   ;УСТАНОВИТЬ ОКНО
      ;
      LD A,22
      LD C,0        ;БЕЗ СДВИГА БУФЕРА
      CALL 0F80CH   ;СОХРАНИТЬ ОКНО
      ;
      LD A,18
      CALL 0F80CH   ;ОЧИСТИТЬ ОКНО
      ;
      CALL 0F803H
      ;
      LD A,23
      LD C,0        ;БЕЗ СДВИГА БУФЕРА - НА ТО ЖЕ МЕСТО
      CALL 0F80CH   ;ВОССТАНОВИТЬ ОКНО
      ;
      CALL 0F803H
      . . .
ВОПРОС 12
«Каким образом изменить цвет отображаемых данных ?»

ОТВЕТ 12:

Для управления цветом в текущем цветовом режиме используются функции A=11,12,13,14,15,16 вектора 0F80CH, причем две последние управляют аппаратной палитрой видимого экрана, а остальные — цветами данных, формируемых в доступном экране.

Рассмотрим пример, показывающий, как назначить 4-цветный режим доступного и видимого экранов с установкой белых символов на синем фоне:

      . . .
      LD A,8
      CALL 0F80CH   ;ОТКЛЮЧИТЬ ВИДЕОСИГНАЛ
      ;
      LD C,4        ;КОД РЕЖИМА
      LD A,0
      CALL 0F80CH   ;УСТАНОВИТЬ РЕЖИМ ДОСТУПНОГО ЭКРАНА
      LD A,2
      CALL 0F80CH   ;УСТАНОВИТЬ РЕЖИМ ВИДИМОГО ЭКРАНА
      ;
      LD C,1        ;КОД ПАЛИТРЫ
      LD A,14
      CALL 0F80CH   ;УСТАНОВИТЬ ПАЛИТРУ
      ;
      LD C,1        ;ЦВЕТ ФОНА - СИНИЙ
      LD A,10
      CALL 0F80CH   ;УСТАНОВИТЬ ЦВЕТ ФОНА
      ;
      LD C,0        ;ЦВЕТ ИЗОБРАЖЕНИЯ - БЕЛЫЙ
      LD A,12
      CALL 0F80CH   ;УСТАНОВИТЬ ЦВЕТ ИЗОБРАЖЕНИЯ
      ;
      LD A,18
      CALL 0F80CH   ;ОЧИСТИТЬ ОКНО
      ;
      LD A,9
      CALL 0F80CH   ;ВКЛЮЧИТЬ ВИДЕОСИГНАЛ
      ;
      LD HL,TEXT
      CALL 0F818H   ;ВЫВОД СООБЩЕНИЯ
      CALL 0F803H
      . . .

 TEXT:DB 'БЕЛОЕ НА СИНЕМ ',1BH,'F03'
      DB 'КРАСНОЕ НА БЕЛОМ ',1BH,'F32'
      DB 'ЗЕЛЕНОЕ НА КРАСНОМ ',0
      . . .
ВОПРОС 13
«Как изменить режим вывода символов?»

ОТВЕТ 13:

Режим вывода символов можно изменить последовательным выводом функций A=8, A=7 вектора 0F80FH, скорректировав требуемые разряды регистра (C). Например, для запрета скроллинга окна можно поступить так:

      . . .
      LD A,8
      CALL 0F80FH   ;ПОЛУЧИТЬ РЕЖИМ ВЫВОДА В РЕГИСТРЕ  (C)
      RES 6,C       ;СБРОСИТЬ БИТ 6
      LD A,7
      CALL 0F80FH   ;УСТАНОВИТЬ НОВЫЙ РЕЖИМ
      . . .

Для установки режима наложения символов, например по «OR», над значением регистра (C) в промежутке между вызовами функций (8) и (7) необходимо выполнить следующие операции:

      . . .
      RES 1,C
      SET 0,C
      . . .
ВОПРОС 14
«Как пользоваться функциями вектора вывода графики?»

ОТВЕТ 14:

Функции вектора 0F82AH используются аналогично функциям других векторов 'TV-PRO'.

Пример вывода окружности:

    . . .
    LD BC,128       ;Y
    LD DE,192       ;X
    LD H,80H        ;РАДИУС ПО X
    LD L,3          ;КОД ЦВЕТА
    LD A,15
    CALL 0F82AH     ;ВЫВОД ОКРУЖНОСТИ
    . . .
ВОПРОС 15
«Как пользоваться драйвером мыши?»

ОТВЕТ 15:

В таблице векторов BIOS имеется два вектора обслуживания мыши:

  • 0F84EH — опрос порта мыши;
  • 0F851H — управление мышью.

Подпрограмма 0F851H - многофункциональная и обеспечивает пользователя минимальным набором средств для работы с мышью. Основная функция данной подпрограммы — перемещение указателя мыши в пределах окна экрана до нажатия одной из ее кнопок (номер функции: A=0). Эта функция вызывает вектор 0F84EH определения состояния мыши.

Остальные функции подпрограммы 0F851H (с номерами A=1.. A=10) введены для поддержки функции A=0 и позволяют изменять режим отображения указателя мыши, его форму, размеры, шаг перемещения, а также проверять факт попадания координат указателя мыши в одну из заданных областей экрана.

Приведем пример совместного использования функций A=0 и A=10:

       . . .

       LD BC,0     ;НАЧАЛЬНЫЕ КООРДИНАТЫ МЫШИ
       LD DE,0
       ;
   CYC:LD A,0
       CALL 0F851H ;ОТОБРАЗИТЬ И ПЕРЕМЕЩАТЬ МЫШЬ
       JP C,...    ;ОШИБКА: X,Y ВНЕ ОКНА ИЛИ ПЕРЕПОЛН. БУФЕРА
       ;
       BIT 6,A     ;НАЖАТА ПРАВАЯ КНОПКА ?
       JP NZ,...   ;ДА - ВЫХОД ИЗ ПРОГРАММЫ
       ;
       ;ПОИСК X,Y В ТАБЛИЦЕ ОБЪЕКТОВ
       LD HL,TAB   ;АДРЕС ТАБЛИЦЫ
       LD A,10
       CALL 0F851H ;ПОИСК
       JR C,CYC    ;НЕ НАШЛИ
       ;
       CALL 0F815H ;ОТОБРАЗИТЬ НОМЕР ОБЪЕКТА
       JR CYC
       ;
       ;ОПИСАНИЕ ТАБЛИЦЫ ОБЪЕКТОВ
   TAB:DB [ EOFTAB - TAB - 1 ] / 6 ;ЧИСЛО ОБЪЕКТОВ
       ;
       ;ОПИСАНИЕ ОБЪЕКТА 0
       DW 0        ;X1
       DB 0        ;Y1
       DW 10       ;DX1
       DB 10       ;DY1
       ;
       ;ОПИСАНИЕ ОБЪЕКТА 1
       DW 384-10   ;X2
       DB 256-10   ;Y2
       DW 10       ;DX2
       DB 10       ;DY2
EOFTAB:
       ;КОНЕЦ ТАБЛИЦЫ
       ;

Для формирования указателя мыши при вызове функции A=0 используются функции обслуживания курсора драйвера 'TV-PRO'. Ниже приводится пример подпрограммы, выполняющей отображение и перемещение указателя мыши примерно также, как это сделано в функции A=0 вектора 0F851H. Используя этот пример, Вы сможете написать свою подпрограмму вывода и перемещения указателя мыши, исходя из конкретных требований.

       ;
       ;-- ВЫВОД УКАЗАТЕЛЯ МЫШИ И ПЕРЕМЕЩЕНИЕ --
       ;НА ВХОДЕ:
       ;   BC = Y,  DE = X
       ;НА ВЫХОДЕ:
       ;  "CY" - УКАЗАТЕЛЬ МЫШИ НАХОДИЛСЯ ВНЕ ОКНА, ИЛИ БУФЕР
       ;         СОХРАНЕНИЯ ИНФОРМАЦИИ ЭКРАНА ПЕРЕПОЛНЕН
       ;   ИНАЧЕ:
       ;   BC = Y,  DE = X
       ;   A - КОД НАЖАТОЙ КНОПКИ:
       ;       80H - ЛЕВАЯ КНОПКА,
       ;       40H - ПРАВАЯ КНОПКА;
       ;ОСОБЕННОСТЬ:
       ;   ИСПОЛЬЗУЮТСЯ 28 БАЙТ ДЛЯ РАБОЧИХ ЯЧЕЕК MS1..MS14.
 MSWND:
       LD (MS1),BC    ;СОХРАНИТЬ ИСХОДНЫЕ X,Y
       LD (MS2),DE
       PUSH HL        ;#### СОХРАНИТЬ HL
       ;
       ;СОХРАНЕНИЕ И ПЕРЕУСТАНОВКА ПАРАМЕТРОВ ОКНА
       CALL 0F81EH    ;СОХР.ПОЗ.КУРСОРА ПЕРЕД ПЕРЕУСТ.ОКНА
       PUSH HL        ;###
       ;
       LD A,17
       CALL 0F80CH    ;ПОЛУЧИТЬ ПАРАМЕТРЫ ОКНА
       ;
       PUSH BC        ;##   СОХРАНИТЬ ПАРАМЕТРЫ ОКНА
       PUSH DE
       PUSH HL
       ;
       LD A,5
       CALL 0F80CH    ;ПОЛУЧИТЬ НОМЕР ЭКРАНА -> (C)
       ;
       PUSH BC
       LD A,2
       CALL 0F851H    ;ПОЛУЧИТЬ РЕЖИМ МЫШИ -> (C)
       BIT 7,C        ;"NZ" - МЫШЬ НА ВЕСЬ ЭКРАН
       POP BC         ;НОМЕР ДОСТУПНОГО ЭКРАНА
       ;
       LD A,4         ;ПЕРЕУСТАНОВИТЬ N ЭКРАНА
       CALL NZ,0F80CH ;(УСТАНОВКА ОКНА НА ВЕСЬ ЭКРАН)
       ;
       ;СОХРАНЕНИЕ ПАРАМЕТРОВ КУРСОРА
       LD A,15
       CALL 0F80FH    ;ПОЛУЧИТЬ РЕЖИМ КУРСОРА -> (C)
       LD H,C
       ;
       LD A,17
       CALL 0F80FH    ;ПОЛУЧИТЬ РАЗМЕРЫ КУРСОРА
       ;
       LD (MS3),BC    ;СОХРАНИТЬ РАЗМЕРЫ И РЕЖИМ КУРСОРА
       LD (MS4),DE
       LD (MS5),HL
       ;
       LD A,19
       CALL 0F80FH    ;АДРЕС ШАБЛОНА КУРСОРА
       ;
       LD (MS6),BC
       LD (MS7),HL    ;СОХРАНИТЬ АДРЕС ШАБЛОНА КУРСОРА
       ;
       LD A,21
       CALL 0F80FH    ;ПОЛУЧИТЬ АДРЕС БУФЕРА СОХР.ДЛЯ КУРСОРА
       ;
       LD (MS8),BC    ;СОХРАНИТЬ
       LD (MS9),DE
       LD (MS10),HL
       ;
       ;УСТАНОВКА ПАРАМЕТРОВ СТРЕЛКИ МЫШИ
       LD A,2
       CALL 0F851H    ;ПОЛУЧИТЬ РЕЖИМ МЫШИ
       ;
       LD A,14
       CALL 0F80FH    ;УСТАНОВИТЬ НОВЫЙ РЕЖИМ КУРСОРА
       ;
       LD A,4
       CALL 0F851H    ;ПОЛУЧИТЬ РАЗМЕРЫ МЫШИ
       PUSH BC        ;#    СОХРАНИТЬ ШАГ ПЕРЕМЕЩЕНИЯ МЫШИ
       ;
       LD A,16
       LD BC,0
       CALL 0F80FH    ;УСТАНОВИТЬ НОВЫЕ РАЗМЕРЫ КУРСОРА
       ;
       LD A,6
       CALL 0F851H    ;ПОЛУЧИТЬ АДРЕС ШАБЛОНА МЫШИ
       ;
       LD A,18
       CALL 0F80FH    ;УСТАНОВИТЬ НОВЫЙ АДРЕС ШАБЛОНА КУРСОРА
       ;
       LD A,8
       CALL 0F851H    ;ПОЛУЧИТЬ АДРЕС БУФЕРА СОХР.ДЛЯ МЫШИ
       ;
       LD A,20
       CALL 0F80FH    ;УСТАНОВИТЬ НОВЫЙ АДРЕС БУФЕРА КУРСОРА
       ;
       POP HL         ;#    ШАГ ПЕРЕМЕЩЕНИЯ УКАЗАТЕЛЯ МЫШИ
       ;
       ;ВЫЧИСЛЕНИЕ ШАГОВ ПРИРАЩЕНИЯ КООРДИНАТ
       PUSH HL
       LD H,0
       LD (MS11),HL   ;ШАГ ПО Y
       LD A,L
       DEC H
       NEG
       LD L,A
       LD (MS12),HL   ; - ШАГ ПО Y
       POP HL
       ;
       LD L,H         ;H=L=ШАГ ПО X
       LD H,0
       LD (MS13),HL   ;ШАГ ПО X
       LD A,L
       DEC H
       NEG
       LD L,A
       LD (MS14),HL   ; - ШАГ ПО X
       ;
       ;ОТОБРАЖЕНИЕ УКАЗАТЕЛЯ МЫШИ
       LD BC,(MS1)
       LD DE,(MS2)
       ;
       LD A,2
       CALL 0F80FH
       JR NC,MSW1     ;НОРМА
       ;
       ;ВНЕ ОКНА ИЛИ ПЕРЕПОЛНЕНИЕ БУФЕРА
       LD A,3
       CALL 0F80FH    ;ПОГАСИТЬ УКАЗАТЕЛЬ
       STC
       JR MSW7        ;ВЫХОД, "CY"=1 - ПРИЗНАК ОШИБКИ
       ;
       ;ОЖИДАНИЕ ОТПУСКАНИЯ КНОПОК MOUSE
  MSW1:CALL 0F84EH    ;ОПРОС ПОРТА МЫШИ
       BIT 4,A        ;ЛЕВАЯ КНОПКА
       JR Z,MSW1
       BIT 5,A        ;ПРАВАЯ КНОПКА
       JR Z,MSW1
       ;
       ;ДВИЖЕНИЕ МЫШИ ДО НАЖАТИЯ ЛЮБОЙ КНОПКИ
  MSW2:CALL 0F84EH    ;ОПРОС ПОРТА МЫШИ
       AND 3FH
       CP 3FH
       JR Z,MSW2      ;НЕТ ИЗМЕНЕНИЙ
       ;
       PUSH AF
       LD A,3
       CALL 0F80FH    ;ПОГАСИТЬ УКАЗАТЕЛЬ МЫШИ
       POP AF
       ;
       LD L,A         ;БАЙТ МЫШИ
       AND 30H
       CP 30H
       JR NZ,MSW4     ;НАЖАТА ХОТЯ БЫ ОДНА КНОПКА
       ;
       LD A,L
       LD (MS1),BC    ;СОХРАНИТЬ ТЕКУЩИЕ X,Y
       LD (MS2),DE
       ;
       BIT 0,A
       CALL Z,MSW8    ;ВЛЕВО
       BIT 1,A
       CALL Z,MSW9    ;ВПРАВО
       BIT 2,A
       CALL Z,MSW10   ;ВНИЗ
       BIT 3,A
       CALL Z,MSW11   ;ВВЕРХ
       ;
       LD A,2
       CALL 0F80FH    ;ОТОБРАЗИТЬ МЫШЬ
       JR NC,MSW2     ;В ОКНЕ (НОРМА)
       ;
       ;ВЫХОД ЗА ПРЕДЕЛЫ ОКНА
       LD BC,(MS1)
       LD DE,(MS2)    ;ВОССТАНОВИТЬ ПРЕЖНИЕ X,Y
       ;
       LD A,2
       CALL 0F80FH    ;ОТОБРАЗИТЬ МЫШЬ НА СТАРОМ МЕСТЕ
       JR MSW2
       ;
  MSW4:XOR A          ;ФОРМИРОВАНИЕ КОДА НАЖАТЫХ КНОПОК
       BIT 4,L
       JR NZ,MSW5
       SET 7,A
  MSW5:BIT 5,L
       JR NZ,MSW6
       SET 6,A
  MSW6:OR A           ;"NC"
       ;
       ;ВОССТАНОВЛЕНИЕ ПАРАМЕТРОВ КУРСОРА
  MSW7:PUSH AF
       LD BC,(MS8)
       LD DE,(MS9)
       LD HL,(MS10)
       LD A,20
       CALL 0F80FH    ;АДРЕС БУФЕРА КУРСОРА
       ;
       LD BC,(MS6)
       LD DE,(MS7)
       LD A,18
       CALL 0F80FH    ;АДРЕС ШАБЛОНА КУРСОРА
       ;
       LD BC,(MS3)
       LD DE,(MS4)
       LD HL,(MS5)
       LD A,16
       CALL 0F80FH    ;РАЗМЕРЫ КУРСОРА
       ;
       LD C,H
       LD A,14
       CALL 0F80FH    ;РЕЖИМ КУРСОРА
       ;
       POP AF
       ;
       POP HL         ;##   ПАРАМЕТРЫ ИСХОДНОГО ОКНА
       POP DE
       POP BC
       ;
       PUSH AF
       LD A,16
       CALL 0F80CH    ;ВЕРНУТЬ ОКНО
       POP AF
       ;
       POP HL         ;###  КООРДИНАТЫ КУРСОРА
       ;
       PUSH AF
       CALL 0F83CH    ;ВЕРНУТЬ ПОЗИЦИЮ КУРСОРА
       POP AF
       ;
       POP HL         ;#### ВЕРНУТЬ HL
       ;
       LD BC,(MS1)    ;ВЫХОДНЫЕ X,Y
       LD DE,(MS2)
       RET
       ;
       ;МЫШЬ ВЛЕВО
  MSW8:LD HL,(MS14)   ; - ШАГ ПО X
       ADD HL,DE
       EX DE,HL
       RET
       ;
       ;МЫШЬ ВПРАВО
  MSW9:LD HL,(MS13)   ;ШАГ ПО X
       ADD HL,DE
       EX DE,HL
       RET
       ;
       ;МЫШЬ ВНИЗ
 MSW10:LD HL,(MS11)   ;ШАГ ПО Y
       ADD HL,BC
       LD B,H
       LD C,L
       RET
       ;
       ;МЫШЬ ВВЕРХ
 MSW11:LD HL,(MS12)   ; - ШАГ ПО Y
       ADD HL,BC
       LD B,H
       LD C,L
       RET
       ;
       ;ВРЕМЕННЫЕ ЯЧЕЙКИ
   MS1:DS 2
   MS2:DS 2
   MS3:DS 2
       . . .
  MS13:DS 2
  MS14:DS 2
       ;
       ;
ВОПРОС 16
«Меня не устраивают управляющие коды и ESC-последовательности драйвера 'TV-PRO'. Могу ли я их изменить?»

ОТВЕТ 16:

Для изменения действия управляющих кодов и последовательностей необходимо написать новую подпрограмму обработки вектора 0F809H. Ниже приведен пример такой подпрограммы, которая основана на использовании функции (0) вектора 0F80FH и имеет практически такое же быстродействие.

Данная подпрограмма реализует все управляющие коды и ESC-последовательности, имеющиеся в стандартном варианте 0F809H, за исключением ESC 'A'..'D' (перемещение курсора). Управляющая последовательность ESC ':' работает подругому: она включает отображение курсора только в подпрограмме KBRD (0F803H), так как режим непрерывного вывода курсора не реализован. Добавлена последовательность ESC 'W',Y,X,dY,dX для установки символьного окна экрана.

Перед применением описываемой подпрограммы должны быть выполнены следующие установки:

1). Значение бита 4 в байте режима вывода символов должно быть нулевым, то есть обработка управляющих кодов в функции (0) запрещена:

      . . .
      LD A,8
      CALL 0F80FH   ;C - РЕЖИМ ВЫВОДА СИМВОЛОВ
      RES 4,C
      LD A,7
      CALL 0F80FH   ;ПЕРЕУСТАНОВИТЬ РЕЖИМ
      . . .

Данное условие необходимо для обработки управляющего кода ^P (10H).

2). Значение бита 6 в байте режима вывода курсора должно быть нулевым, то есть непрерывный вывод курсора в функции (0) отключен:

      . . .
      LD A,15
      CALL 0F80FH   ;C - РЕЖИМ ВЫВОДА КУРСОРА
      RES 6,C
      LD A,14
      CALL 0F80FH   ;ПЕРЕУСТАНОВИТЬ РЕЖИМ
      . . .

При невыполнении этого условия «непрерывный» курсор будет выводиться неправильно, так как на момент изменения координат и формы курсора он должен удаляться, что обеспечивается внутри функции (0) при единичном значении бита 6.

В случае необходимости режим непрерывного отображения курсора может быть реализован с использованием функций (2), (3) вектора 0F80CH при соблюдении условия 2).

0F809H:JP XXXX
      ;ВХОД В ВЕКТОР TVC
       . . .
       ;
       ;== НОВАЯ ПОДПРОГРАММА ОБРАБОТКИ ВЕКТОРА 0F809H ==
       ;  (С ИСПОЛЬЗОВАНИЕМ ФУНКЦИИ (0) ВЕКТОРА 0F80FH)
  XXXX:
       PUSH AF
       PUSH BC
       PUSH DE
       PUSH HL
       ;
       LD B,C         ;КОД СИМВОЛА
       LD HL,AR2ST
       LD A,(HL)
       OR A
       JP M,TVC01     ;ПРИЗНАК ^P - ВЫВЕСТИ СИМВОЛ 00..1FH
       JP NZ,TVC11    ;ОБРАБОТКА ESC - ПОСЛЕДОВАТЕЛЬНОСТИ
       ;
       LD A,C         ;КОД СИМВОЛА
       CP 20H
       JR C,TVC03     ;УПРАВЛЯЮЩИЙ СИМВОЛ
       ;
 TVC01:RES 7,(HL)     ;СБРОС ПРИЗНАКА ^P
       ;
       XOR A          ;ФУНКЦИЯ 0
       CALL 0F80FH    ;ВЫВОД СИМВОЛА В ПОЗИЦИЮ КУРСОРА
       ;
       CALL NC,UNDERL ;ПОДЧЕРКИВАНИЕ
 TVC02:
       POP HL
       POP DE
       POP BC
       POP AF
       RET
       ;
       ;
       ;- ЧАСТНАЯ П/П ПОДЧЕРКИВАНИЯ КУРСОРОМ -
UNDERL:LD A,(UNDRL)
       OR A           ;РЕЖИМ ПОДЧЕРКИВАНИЯ ?
       RET Z          ;НЕТ
       ;
       LD A,15
       CALL 0F80FH    ;C - РЕЖИМ ВЫВОДА КУРСОРА
       PUSH BC
       ;
       LD A,8
       CALL 0F80FH    ;C - РЕЖИМ ВЫВОДА СИМВОЛОВ
       LD A,C
       AND 07H
       LD C,A
       CALL TVC21     ;УСТАНОВИТЬ НОВЫЙ РЕЖИМ ВЫВОДА КУРСОРА
       ;
       LD A,4
       LD C,1
       CALL 0F80FH    ;КУРСОР ВЛЕВО
       LD A,6
       CALL 0F80FH    ;BC=Y, DE=X КУРСОРА
       LD A,2
       CALL 0F80FH    ;ВЫВЕСТИ КУРСОР
       LD A,4
       LD C,2
       CALL 0F80FH    ;КУРСОР ВПРАВО
       ;
       POP BC
       JP TVC21       ;ВЕРНУТЬ РЕЖИМ КУРСОРА
       ;
       ;
       ;ОБРАБОТКА УПРАВЛЯЮЩИХ ФУНКЦИЙ
 TVC03:LD DE,TVC02
       PUSH DE        ;АДРЕС ВОЗВРАТА
       ;
       SUB 07H        ;CP 07H
       JR NZ,TVC04
       ;
       ;BELL
       LD BC,300      ;MS
       LD DE,2048     ;HZ
       JP 0F83FH      ;SOUND
       ;
 TVC04:LD DE,TVC06    ;АДРЕС П/П ВЫПОЛНЕНИЯ УПР.ФУНКЦИЙ
       PUSH DE
       DEC A          ;CP 08H
       LD C,1
       RET Z          ;LEFT
       ;
       DEC A          ;CP 09H
       LD C,5
       RET Z          ;TAB
       ;
       DEC A          ;CP 0AH
       LD C,7
       RET Z          ;LF
       ;
       DEC A
       DEC A          ;CP 0CH
       JR NZ,TVC07
       ;
       ;CLS+HOME
       POP DE         ;БАЛАНС СТЕКА
 TVC05:LD C,10        ;CLS
       CALL TVC06
       LD C,0         ;HOME
       ;
 TVC06:LD A,4         ;ФУНКЦИЯ 4 - УПРАВЛЕНИЕ НОМЕР (C)
       JP 0F80FH
       ;
 TVC07:DEC A          ;CP 0DH
       LD C,6
       RET Z          ;CR
       ;
       SUB 3          ;CP 10H = ^P
       JR NZ,TVC08
       ;
       ;ПРЕФИКС УПРАВЛЯЮЩИХ СИМВОЛОВ
       POP DE
       SET 7,(HL)
       RET
       ;
 TVC08:SUB 08H        ;CP 18H
       LD C,2
       RET Z          ;RIGHT
       ;
       DEC A          ;CP 19H
       LD C,3
       RET Z          ;UP
       ;
       DEC A          ;CP 1AH
       LD C,4
       RET Z          ;DOWN
       ;
       POP DE         ;БАЛАНС СТЕКА
       DEC A          ;CP 1BH
       JR Z,TVC09     ;ESC
       ;
       SUB 04H        ;CP 1FH
       RET NZ
       ;
       ;CLS+HOME
       JR TVC05
       ;
 TVC09:INC (HL)       ;УСТАНОВИТЬ ПРИЗНАК ESC
       RET
       ;
       ;КОНЕЦ ESC - ПОСЛЕДОВАТЕЛЬНОСТИ
 TVC10:XOR A
       LD (AR2ST),A
       JP TVC02
       ;
       ;ОБРАБОТКА АР2-КОМАНД
 TVC11:LD DE,TVC10
       PUSH DE
       ;
       INC (HL)
       DEC A          ;1-Й СИМВОЛ ПОСЛЕ АР2 ?
       JP NZ,TVC28
       ;
       ;ОБРАБОТКА 1-ГО СИМВОЛА ПОСЛЕ АР2
       LD A,8
       CALL 0F80FH    ;C - РЕЖИМ ВЫВОДА СИМВОЛОВ
       LD A,B         ;КОД СИМВОЛА
       LD (AR2CD),A
       ;
       SUB '2'        ;CP '2'
       JR NZ,TVC13
       ;
       ;ВКЛЮЧИТЬ АВТОПЕРЕВОД СТРОКИ
       SET 5,C
       ;
       ;УСТАНОВКА РЕЖИМА ВЫВОДА СИМВОЛОВ (C)
 TVC12:LD A,7
       JP 0F80FH
       ;
 TVC13:DEC A          ;CP '3'
       JR NZ,TVC14
       ;
       ;ВЫКЛЮЧИТЬ АВТОПЕРЕВОД
       RES 5,C
       JR TVC12
       ;
 TVC14:DEC A          ;CP '4'
       JR NZ,TVC15
       ;
       ;РАЗРЕШЕНИЕ СКРОЛЛИНГА
       SET 6,C
       JR TVC12
       ;
 TVC15:DEC A          ;CP '5'
       JR NZ,TVC16
       ;
       ;ЗАПРЕТ СКРОЛЛИНГА
       RES 6,C
       JR TVC12
       ;
 TVC16:DEC A          ;CP '6'
       JR NZ,TVC17
       ;
       ;ВКЛЮЧИТЬ ИНВЕРСИЮ
       SET 2,C
       JR TVC12
       ;
 TVC17:DEC A          ;CP '7'
       JR NZ,TVC18
       ;
       ;ВЫКЛЮЧИТЬ ИНВЕРСИЮ
       RES 2,C
       JR TVC12
       ;
 TVC18:DEC A          ;CP '8'
       JR NZ,TVC19
       ;
       ;ВКЛЮЧИТЬ ПОДЧЕРКИВАНИЕ КУРСОРОМ
       LD A,0FFH
       LD (UNDRL),A
       RET
       ;
 TVC19:DEC A          ;CP '9'
       JR NZ,TVC20
       ;
       ;ВЫКЛЮЧИТЬ ПОДЧЕРКИВАНИЕ
       XOR A
       LD (UNDRL),A
       RET
       ;
 TVC20:PUSH AF
       LD A,15
       CALL 0F80FH    ;ПОЛУЧИТЬ РЕЖИМ ВЫВОДА КУРСОРА (C)
       POP AF
       ;
       DEC A          ;CP ':'
       JR NZ,TVC22
       ;
       ;ВКЛЮЧИТЬ КУРСОР
       SET 5,C
       ;
 TVC21:LD A,14
       JP 0F80FH      ;РЕЖИМ КУРСОРА
       ;
 TVC22:DEC A          ;CP ';'
       JR NZ,TVC23
       ;
       ;ВЫКЛЮЧИТЬ КУРСОР
       RES 5,C
       JR TVC21
       ;
 TVC23:DEC A          ;CP '<'
       JR NZ,TVC24
       ;
       ;ВКЛЮЧИТЬ МИГАНИЕ КУРСОРА
       SET 4,C
       JR TVC21
       ;
 TVC24:DEC A          ;CP '='
       JR NZ,TVC25
       ;
       ;ВЫКЛЮЧИТЬ МИГАНИЕ КУРСОРА
       RES 4,C
       JR TVC21
       ;
 TVC25:SUB 'E'-'='    ;CP 'E'
       LD C,10
       JP Z,TVC06     ;CLS
       ;
       DEC A          ;CP 'F'
       JR Z,TVC27
       ;
       DEC A
       DEC A          ;CP 'H'
       LD C,0
       JP Z,TVC06     ;HOME
       ;
       DEC A
       DEC A          ;CP 'J'
       LD C,11
       JP Z,TVC06     ;ОЧИСТИТЬ ДО КОНЦА ОКНА
       ;
       INC C
       DEC A          ;CP 'K'
       JP Z,TVC06     ;ДО КОНЦА СТРОКИ
       ;
       DEC A          ;CP 'L'
       LD C,15
       JP Z,TVC06     ;ВСТАВКА
       ;
       INC C
       DEC A          ;CP 'M'
       JP Z,TVC06     ;УДАЛЕНИЕ
       ;
       LD DE,TVC27
       PUSH DE
       ;
       SUB 'R'-'M'    ;CP 'R'
       RET Z
       ;
       DEC A          ;CP 'S'
       RET Z
       ;
       DEC A          ;CP 'T'
       RET
       ;
       DEC A          ;CP 'U'
       RET
       ;
       DEC A          ;CP 'V'
       RET
       ;
       DEC A          ;CP 'W'
       RET
       ;
       SUB 'Y'-'W'    ;CP 'Y'
       RET Z
       ;
       POP DE
       RET
       ;
       ;КОНЕЦ ОБРАБОТКИ 1-ГО СИМВОЛА
 TVC27:POP HL
       JP TVC02
       ;
 TVC28:DEC A
       JR NZ,TVC36
       ;
       ;2-Й СИМВОЛ ПОСЛЕ АР2
       LD A,(AR2CD)
       SUB 'R'        ;CP 'R'
       JR NZ,TVC29
       ;
       ;УСТАНОВКА ТОЛЩИНЫ КУРСОРА
       LD H,B         ;ЗАДАННАЯ ТОЛЩИНА
       LD A,17
       CALL 0F80FH    ;C-СМЕЩЕНИЕ,E-ВЫСОТА КУРСОРА
       LD A,C
       ADD A,E
       RET C
       SUB H          ;НОВОЕ СМЕЩЕНИЕ
       RET C
       LD C,A
       LD E,H
       LD A,16
       JP 0F80FH      ;УСТАНОВИТЬ НОВЫЕ РАЗМЕРЫ КУРСОРА
       ;
 TVC29:DEC A          ;CP 'S'
       JR NZ,TVC30
       ;
       ;УСТАНОВКА НОМЕРА ЭКРАНА
       LD C,B
       LD A,4
       CALL 0F80CH
       LD A,6
       JP 0F80CH
       ;
 TVC30:DEC A          ;CP 'T'
       JR NZ,TVC31
       ;
       LD C,B
       LD A,14
       JP 0F80CH      ;УСТАНОВКА ПАЛИТРЫ
       ;
 TVC31:DEC A          ;CP 'U'
       JR NZ,TVC32
       ;
       ;УСТАНОВКА РЕЖИМА ЭКРАНОВ
       LD C,B
       XOR A
       CALL 0F80CH
       LD A,2
       JP 0F80CH
       ;
 TVC32:DEC A          ;CP 'V'
       JR NZ,TVC33
       ;
       ;ВКЛЮЧИТЬ/ВЫКЛЮЧИТЬ ВИДЕО
       LD A,B
       RRCA
       LD A,9
       JP C,0F80CH    ;ON
       DEC A
       JP 0F80CH      ;OFF
       ;
 TVC33:POP HL
       LD HL,TVC02
       PUSH HL
       ;
       ADD A,'V'-'F'  ;CP 'F'
       JR NZ,TVC34
       ;
       LD A,10
       LD C,B
       JP 0F80CH      ;УСТАНОВИТЬ ЦВЕТ ФОНА
       ;
 TVC34:SUB 'W'-'F'    ;CP 'W'
       JR NZ,TVC35
       ;
       LD A,B
       LD (Y),A       ;СМЕЩЕНИЕ ОКНА ПО Y
       RET
       ;
 TVC35:SUB 'Y'-'W'    ;CP 'Y'
       RET NZ
       ;
       LD A,B
       SUB 20H        ;Y КУРСОРА
       LD (Y),A
       RET
       ;
 TVC36:DEC A
       JR NZ,TVC39
       ;
       ;3-Й СИМВОЛ ПОСЛЕ АР2
       LD A,(AR2CD)
       ;
       CP 'F'
       JR NZ,TVC37
       ;
       LD A,12
       LD C,B
       JP 0F80CH      ;УСТАНОВКА ЦВЕТА ИЗОБРАЖЕНИЯ
       ;
 TVC37:CP 'W'
       JR NZ,TVC38
       ;
       LD A,B
       LD (X),A       ;СМЕЩЕНИЕ ОКНА ПО X
 TVC26:POP HL
       JP TVC02
       ;
 TVC38:CP 'Y'
       RET NZ
       ;
       LD A,B
       SUB 20H        ;X КУРСОРА
       LD L,A
       LD A,(Y)
       LD H,A
       JP 0F83CH      ;УСТАНОВИТЬ КУРСОР
       ;
 TVC39:DEC A
       JR NZ,TVC40
       ;
       ;4-Й СИМВОЛ ПОСЛЕ АР2
       LD A,B
       LD (DY),A      ;ВЫСОТА ОКНА
       JR TVC26
       ;
 TVC40:DEC A
       RET NZ
       ;
       LD DE,(X)      ;E=X, D=Y - СМЕЩЕНИЕ ОКНА
       LD A,(DY)
       LD H,A         ;ВЫСОТА ОКНА
       LD L,B         ;ШИРИНА ОКНА
       LD C,9
       JP TVC06       ;УСТАНОВИТЬ ОКНО
       ;
       ;
       ;--- РАБОЧИЕ ЯЧЕЙКИ ---
 AR2ST:DB 0    ;СЧЕТЧИК СИМВОЛОВ ESC
 AR2CD:DB 0    ;КОД КОМАНДЫ ESC
     X:DB 0    ;СМЕЩЕНИЕ ОКНА ПО X
     Y:DB 0    ;СМЕЩЕНИЕ ОКНА ПО Y / КООРДИНАТА Y КУРСОРА
    DY:DB 0    ;ВЫСОТА ОКНА
 UNDRL:DB 0    ;ПРИЗНАК ПОДЧЕРКИВАНИЯ
       ;
       ;

Подпрограмма обработки вектора 0F809H может быть создана на основе функции (1) вектора 0F80FH, при этом состояние бита 4 в байте режима вывода символов и бита 6 в байте режима вывода курсора не имеют значения.

Ниже приведен начальный фрагмент такой подпрограммы (остальная часть аналогична предыдущему примеру). Быстродействие данной подпрограммы примерно в 1.2 раза хуже из-за использования функции (6) для получения координат курсора и функции (4) для перемещения курсора вправо. Устранить этот недостаток можно, если написать свои процедуры получения, установки и изменения координат курсора, отказавшись от функций (4), (5), (6).

       . . .
       ;
       ;== НОВАЯ ПОДПРОГРАММА ОБРАБОТКИ ВЕКТОРА 0F809H ==
       ;  (С ИСПОЛЬЗОВАНИЕМ ФУНКЦИИ (1) ВЕКТОРА 0F80FH)
  XXXX:
       PUSH AF
       PUSH BC
       PUSH DE
       PUSH HL
       ;
       LD B,C         ;КОД СИМВОЛА
       LD HL,AR2ST
       LD A,(HL)
       OR A
       JP M,TVC01     ;ПРИЗНАК ^P - ВЫВЕСТИ СИМВОЛ 00..1FH
       JP NZ,TVC11    ;ОБРАБОТКА ESC - ПОСЛЕДОВАТЕЛЬНОСТИ
       ;
       LD A,C         ;КОД СИМВОЛА
       CP 20H
       JR C,TVC03     ;УПРАВЛЯЮЩИЙ СИМВОЛ
       ;
 TVC01:RES 7,(HL)     ;СБРОС ПРИЗНАКА ^P
       ;
       PUSH BC        ;(C) - В СТЕК
       LD A,6
       CALL 0F80FH    ;BC=Y, DE=X
       POP HL         ;(L) - КОД СИМВОЛА
       LD A,1
       CALL 0F80FH    ;ВЫВОД СИМВОЛА В ПОЗИЦИЮ BC,DE
       ;
       CALL NC,UNDERL ;ПОДЧЕРКИВАНИЕ, ЕСЛИ В ОКНЕ
       LD A,4
       LD C,2
       CALL 0F80FH    ;КУРСОР ВПРАВО
       JR NC,TVC02    ;СКРОЛЛИНГ НЕ НУЖЕН
       ;
       LD C,3
       CALL TVC06     ;ВВЕРХ => В НАЧАЛО ПОСЛЕДНЕЙ СТРОКИ
       LD C,7
       CALL TVC06     ;ПС
 TVC02:
       POP HL
       POP DE
       POP BC
       POP AF
       RET
       ;
       ;
       ;- ЧАСТНАЯ П/П ПОДЧЕРКИВАНИЯ КУРСОРОМ -
       ;  BC = Y, DE = X
UNDERL:LD A,(UNDRL)
       OR A           ;РЕЖИМ ПОДЧЕРКИВАНИЯ ?
       RET Z          ;НЕТ
       ;
       PUSH BC
       ;
       LD A,15
       CALL 0F80FH    ;C - РЕЖИМ ВЫВОДА КУРСОРА
       LD L,C
       ;
       LD A,8
       CALL 0F80FH    ;C - РЕЖИМ ВЫВОДА СИМВОЛОВ
       LD A,C
       AND 07H
       LD C,A
       CALL TVC21     ;УСТАНОВИТЬ НОВЫЙ РЕЖИМ ВЫВОДА КУРСОРА
       ;
       POP BC
       ;
       LD A,2
       CALL 0F80FH    ;ВЫВЕСТИ КУРСОР
       ;
       LD C,L
       JP TVC21       ;ВЕРНУТЬ РЕЖИМ КУРСОРА
       ;
       ;
       ;ОБРАБОТКА УПРАВЛЯЮЩИХ ФУНКЦИЙ
 TVC03:LD DE,TVC02
       PUSH DE        ;АДРЕС ВОЗВРАТА
       ;
       . . .