Вернуться на ГЛАВНУЮ страницу
Вернуться к СПИСКУ СТАТЕЙ


Автор: Максим Тимонин aka Максагор
Дата:
19.11.2018 г. (дата публикации в газете)
Примечание: опубликовано в электронной газете "ALCO News" №72


Утилита-просмотрщик ANSI-графики ANSI VIEWER v1.00

*     *     *

Системные требования:

Исключительно  OS TASiS. При запуске в иных версиях iS-DOS сработает распознавание и утилита выйдет обратно в систему без каких-то действий.  При  этом  утилита для совместимости с иными версиями  системы грузится  по адресу 24000 dec (#5DC0), но определив,  что находится в OS TASiS, перекидывает себя по адресу 16384 dec (#4000) и работает оттуда, тем самым почти на 8 килобайт  увеличивая свободное пространство под рабочий буфер.

ANSIVIEW  -  это  просмотрщик  текстовых   файлов  ANSI-графики (создаваемых      посредством     использования     управляющих ESC-последовательностей),  широко  распространенных в прошлом в среде MS-DOS, UNIX и прочих текстовых ОСей и повсеместно применявшихся  в  ранних  сетях, а именно в FIDOnet и BBS'ках. Собственно и создана данная утилита в рамках проекта по программной поддержке имеющегося на борту АТМ COM-порта для связи с внешним миром,  а  это - как минимум терминалка, большинство из которых "могут  в  ANSI".  А данная утилита построена на основе универсального  многофункционального ANSI-драйвера, описание и исходники которого идут отдельно и который как раз предназначен для использования в терминальной программе.

На создание данной утилиты я был  вдохновлен созданными в "Ведре"  (ANSI-редактор "The Draw") картинками Юлии Монаенковой aka MATiSHA,  увидев которые я однозначно решил, что ANSI-утилите в OS TASiS - быть.

Само  создание  утилиты  проходило  под  влиянием программы под систему TR-DOS  "ANSI  v0.6" за авторством Дмитрия Быстрова aka Alone Coder,  а  также  PC-просмотрщика ACiDview, на которых я проводил  сравнение вывода картинки с картинкой, получающейся в результате работы данной утилиты. При этом приоритетом, в случае расхождений результатов пользовалась PC-утилита как "конечный"  эталон. Отдельные моменты управляющих последовательностей тестировались также в PC-терминалке TELEMAX под MS-DOS.

*     *     *

Основные  различия между ANSI v0.6 от Alone Coder и данной утилитой:

1.  ANSI  v0.6  -  "вещь в себе" - написанная под TR-DOS в виде программы  с  собственным  "оконным"  интерфейсом,  она годится только  для просмотра текстовой графики (в том числе, в режиме 640x200) и всё, тогда как ANSIVIEW - утилита, работающая из командной  строки, управляющаяся посредством ключей, подходит не только  для просмотра графики, но и использования в BAT-никах и иных  пакетных  и настроечных  текстовых  файлах, например для оформления  экрана, вывода заставок (в том числе анимированных) и проч. При этом, так как ANSIVIEW создан на основе универсального ANSI-драйвера, написанного для создания терминалки, данная утилита поддерживает обработку гораздо большего набора ESC-последовательностей (их описание ниже). Для  использования  утилиты ее желательно поставить в соответствие  с  расширением  какого-либо  файла  (опционально - ans) в настроечном файле extent.txt или подвесить на "горячую клавишу" в extkey.txt.

2.  ANSI  v0.6 работает только на флопиках (или их эмуляции), а ANSIVIEW из-под любого физического  или логического устройства, под который сподобятся написать дрова.

3.  ANSI  v0.6  не умеет работать с длинными файлами - встретив такой,  он  загрузит  столько, сколько вместится в ОЗУ (порядка 40-45Кб)  и выведет  только  загруженную часть, оборвав, таким образом,  вывод  картинки  на середине. ANSIVIEW может выводить файлы  любой длины,  ограниченной только свойствами конкретной файловой системы iS-DOS, т.е. до 5.2Мб, подгружая в буфер и выводя  его  на  экран  по частям. Таким образом, именно ANSIVIEW можно считать действительно полноценной ANSI-утилитой.

4. ANSI v0.6 работает с экранной областью и с портами доступа к ее  страницам  напрямую,  через специально написанные процедуры вывода,  а ANSIVIEW целенаправленно написан ИСКЛЮЧИТЕЛЬНО с использованием  системных рестартов и процедур OS TASiS - во всей программе  нет  ни одной команды OUT или IN или вывода байтов в экранную  область  АТМ.  Поэтому, как плата за универсальность, ANSIVIEW  раза  в  2-2.5 проигрывает  по скорости (особенно при скроллинге) программе Дмитрия Быстрова в ее режиме максимальной скорости отображения, однако заметно быстрее отображения в ANSI v0.6  в режиме эмуляции скорости терминала 14400 бод. Т.е. скорость отображения в ANSIVIEW не является рекордной (и, естественно,  зависит  также от числа встречающихся при выводе текста ESC последовательностей,  требующих  обработки),  но  более чем достаточной для комфортного восприятия.

*     *     *

Формат использования утилиты в командной строке:

[путь\]ansiview [/keys][путь\][filename]

где /keys - следующие ключи:

/k  - (Key) ждать нажатия клавиши перед выходом в систему после окончания  вывода  текста.  Если  нет ключа - выходит сразу как только "докрутит" файл.

/c  -  (Cls) очищать экран перед началом вывода файла. Если нет ключа  -  то  печатается поверх того, что уже есть на экране. В данной  версии утилиты  очистка  поисходит атрибутами PAPER=0, INK=7, BRIGHT=0.

/w - (Wrap) Если есть такой ключ, то при достижении края экрана строчка  не  переносится  на строку вниз, а продолжается дальше "вне  поля зрения"  либо  до 255-го столбца, либо до встречи символом Carriage Return (#0D) - возврат каретки. Соответственно,  если  такого ключа нет, то текст по достижению края экрана переносится на начало следующей строки.

/p[n] - (Palette)  Установка (и тип установки) одной из палитр, опреледяемых параметром "n":

Параметр  из диапазона 0-3 включает т.н. "режим предварительной установки палитры", когда палитра устанавливается перед выводом текста:

   n=0  - текущая системная палитра OS TASiS. Как правило, совпадает  с  ZX-палитрой,  но не обязательно. Зависит от настроек юзера.

   n=1  - стандартная для ANSI-текстов EGA-палитра.

   n=2 - т.н. ZX/EGA-палитра(цвета ZX-палитры, но расположенные в порядке EGA-палитры).

   n=3 - стандартная ZX-палитра.

Параметры  из диапазона 4-7 включают режим, при котором сначала палитра полностью гасится (черный экран), при погашенной палитре выводится текст, после чего включается одна из палитр, определяемых  параметром.  При этом параметры соответствуют таковым параметрам из первого диапазона + 4, а именно:

n=4 - n=0
n=5 - n=1
n=6 - n=2
n=7 - n=3

Отсутствие ключа /p вообще - приравнивается к /p1,а присутствие ключа  /p без параметра или с неверным параметром соответствует ключу /p0.

/h  -  (Help)  Вывод на экран копирайтов и номеров версий ANSI-драйвера  и  собственно  утилиты, а  также краткий хелп по формату командной строки и использованию ключей. Из остальных ключей  при  этом обрабатывается только /k, а вывод хелпа на экран осуществляется  в  ANSI формате  с  предустановленными очисткой экрана  в  черный, EGA-палитрой и т.н."режимом полной обработки управляющих ASCII-кодов" (об этом ниже).

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

При выводе текста также обрабатываются следующие клавиши:

ESC или Ctrl+c  - прерывание вывода текста и выход в систему.

Ctrl+s  -  временная приостановка вывода текста до последующего нажатия любой значащей клавиши.

На механической клавиатуре ESC=CS+1, а Ctrl=CS+SS=EXT.

Текст в данной версии утилиты выводится в alt-кодировке(cp866).

                      *     *     *

Форматы отображения управляющих кодов 0-31 dec (#00-#1F):

Как  известно, коды 0-31 обычно считаются управляющими, т.е. на экране  они  отображаться  не  должны,  а влиять на те или иные функции системы  при выводе на печать (управление координатами курсора, цветом и проч.). Тем не менее, в полной 256-символьной таблице им в соответствие поставлены свои изображения, есть немало  программ  под  тот же MS-DOS, где используются символы из этого диапазона. Встретились некоторые "нижние" символы и в ряде  ANSI-файлов.  Поэтому  встала задача совместить возможность вывода  "нижних" кодов на экран как символов, и как управляющих кодов  с  максимальной совместимостью с имеющимся на PC софтом. Чтение справочного материала в сети дало информацию о самом широком  наборе  функций  практически  всех управляющих кодов. Но часть  из  них  устарела еще во времена MS-DOS и, как показали исследования  DOS-терминалки  TELEMAX и все того же ACiDview, в качестве  управляющих используются только некоторые коды, а остальные просто выводятся на экран в виде отображаемых символов.

В  итоге я пошел по пути комбинированного подхода, реализовав в ANSI-драйвере  несколько  переключаемых режимов отображения управляющих кодов. Это режим полного отключения управляющих кодов - все  печатается  на  экран, "максимальный" набор - это когда почти все  "нижние" коды, кроме откровенно устаревших или нестандартных  расцениваются  как управляющие, и "минимальный" набор, где только самые необходимые символы расцениваются как управляющие,  а остальные выводятся на экран. "Минимальный" набор создавался  с ориентацией  на TELEMAX и ACiDview, у которых он практически совпадает.
Что  же касается собственно утилиты ANSIVIEW, то вывод хелпа по ключу /h выводится в режиме полного набора - так, звуковой сигнал выводится  посредством  "печати" кода #07(Bell), который в минимальном режиме просто выводится на экран. Но это только вывод  хелпа. Во всех остальных случаях утилита использует ИСКЛЮЧИТЕЛЬНО  режим  минимального набора управляющих кодов. Поэтому описание всех режимов отображения следует читать в инструкции к ANSI-драйверу,  а здесь приводятся данные по их отображению при работе собственно утилиты ANSIVIEW. А именно:

Код #00 (0 dec) - NULL или "пустой" символ. В разных местах или как  управляющий код означает отсутствие любой реакции, или как отображаемый символ эквивалентен пробелу (т.е.никакое изображение  символа  ему в соответствие не поставлено). В TELEMAX он и означает "ничего", а в ACiDview реализован как пробел. При этом мне встретились ANSI-тексты, где NULL используется как пробел и в ином случае картинка разваливается. Это и предопределило использование  в утилите данного кода в виде "дублера пробела". В собственно же драйвере можно настраивать NULL на разные варианты.

Код  #08 (8 dec) - Backspace. Перемещает позицию вывода символа на один символ назад (влево). В различных терминалках есть возможность  настроить  этот  код так, чтобы при перемещении назад предыдущее  знакоместо  затиралось пробелом. Т.е. Backspace используется в таком случае как удаление текста. Есть такая функция  настройки и в ANSI-драйвере, но собственно в утилите Backspace настроен  только  на  перемещение позиции курсора, как в просмотрщике AciDView.

Код #09 (9 dec) - TAB или табуляция. Перемещение курсора вправо на ближайшую позицию, кратную восьми. В ряде описаний и у Alone Coder предупреждается, что  не  является  стандартным, и в ANSI-драйвере MS-DOS не поддержан. Однако и в терминалке TELEMAX, и в просмотрщике ACiDview и собственно в ANSI v0.6 от Alone Coder табуляция поддержана. Поэтому реализована и здесь.

Пара  кодов #0D (13 dec - Carraige return (CR)) и #0A (10 dec - Line  Feed  (LF)).  Именно пара, так как почти всегда они и используются  парой, причем  сначала принято ставить CR (перевод позиции печати на начало строчки), а потом LF - перевод позиции печати  на  строку вниз. Таким образом эта парочка используется для разделения текста на строчки практически везде во всех ОС и платформах. Однако иногда встречаются тексты,  где используется в  конце строки только CR, который исполняет одновременно функцию себя и LF. В частности именно такой формат поддерживается в стандартных  редакторах  и просмотрщиках iS-DOS/TASiS на уровне системных  вызовов. Тексты с "неполной" парой могут неправильно отображаться незнающими об этом просмотрщиками на PC. Поэтому в той же терминалке TELEMAX есть возможность настройки функционала CR и LF. Это предопределило введение такой настройки и в ANSI-драйвере  здесь.  Конкретно  в  утилите ANSIVIEW он настроен так,  что  CR  выполняется ка CR+LF, а собственно реакция на LF отключена. Это  позволяет просмотрщику "безболезненно" выводить правильно  на  экран тексты обоих стандартов одновременно. Но в случае создания на основе  данного драйвера терминалки настройки могут быть другими.

Код #1A  (26 dec) - в CP/M и MS-DOS, если верить описаниям, использовался  для обозначения конца текстовых файлов. В ACiDview прекращал вывод текста (все, что шло после этого кода больше не выводится).  Этот  код встречен в ряде ANSI-текстов для скрытых после основного изображения комментариев, копирайтов и проч., а посему  реализован  и  в  утилите  ANSIVIEW,  хотя собственно в ANSI-драйвере может быть отключен по желанию.

Код  #1B (27 dec) - ESC. Означает, что следующие за ним в определенном порядке символы имеют какое-то иное значение, отличное от того, которое определено в ASCII.  Другими словами - это основа для управляющих ANSI-последовательностей.  Им посвящен соответствующий раздел.

Остальные, не упомянутые здесь коды из диапазона 0-31 в текущих настройках  утилиты  ANIVIEW являются отображаемыми и выводятся на экран наравне с любыми другими буквами.

*     *     *

Управляющие ESC-последовательности ANSI-стандарта

Под  ESC-последовательностями понимается ряд символов, начинающихся с управлядщего кода 27 dec (#1B), в совокупности выполняющий определенную  функцию.  Далее  этот  символ  при описании ESC-последовательностей будет обозначаться как "Esc". Большинство  таких последовательностей запускается идущими друг за другом  символами  Esc и "[" (т.е. Esc[). Для сокращения далее эта последовательноать будет обозначаться ка CSI  (Control Sequence Introducer).  Подставляемые  параметры обозначаются ниже в виде символа  "#". Один или несколько символов в квадратных скобках, наприме  [;#;#;  ... #]. означает, что таковых параметров может быть в одной ESC последовательности несколько, но не обязательно.  При этом символ ";" является разграничителем этих параметров и в обязательном порядке является частью ESC-последовательности, а не приводится тут только как знак пунктуации в тексте. Как правило, подставляемый параметр "#" может вообще отсутствовать в управляющей последовательности. В этом случае вместо него  обычно подставляется значение по умолчанию, что обговаривается в описании. Все подставляемые параметры являются числовыми в  виде ASCII-символов. Например, параметр "5" является не байтом   со значением "5", а символом "5", а параметр "31" не байтом со значением "31", а именно двумя символами "3" и "1".

В утилите ANSIVIEW версии v1.00 реализованы следующие управляющие последовательности:

CSI #A   - Cursor Up (CUU)
Перемещает курсор на n (по умолчанию на 1) позиций вверх.

CSI #B   - Cursor Down (CUD)
Перемещает курсор на n (по умолчанию на 1) позиций вниз.

CSI #C   - Cursor Forward (CUF)
Перемещает  курсор  на  n  (по  умолчанию  на 1) позиций вперед (вправо).

CSI #D   - Cursor Back (CUB)
Перемещает  курсор на n (по умолчанию на 1) позиций назад (влево).

CSI #E   - Cursor Next Line (CNL)
Перемещает  курсор  в  начало  n-ной  (по умолчанию 1-й) строки снизу относительно текущей.

CSI #F   - Cursor Previous Line (CPL)
Перемещает  курсор  в  начало  n-ной  (по умолчанию 1-й) строки сверху относительно текущей.

CSI #G   - Cursor Horizontal Absolute (CHA)
Перемещает  курсор в столбец n (по умолчанию в 1 - самый левый, первый по счету).

CSI #;#H   - Cursor Position (CUP)
Перемещает  курсор в строку n (первый #), столбец m (второй #). Значения  n и m по умолчанию 1 (левый верхний угол - т.е. нумерация в параметре не с 0, а с 1), если указан только один параметр  без  точки  с запятой, например, CSI 15H, то это параметр n  и  он эквивалентен CSI 15;1H, а если с точкой с запятой (CSI ;15H), то это параметр m (эквивалентно CSI 1;15H).

CSI #J   - Erase Data (ED)
Очищает часть окна терминала. При этом:
   # = 0  или  отсутствует (значение  по умолчанию) - очищается все от курсора до конца окна терминала.
   # = 1 - очищается все от курсора до начала окна терминала.
   # = 2 - очищает все окно терминала и перемещает курсор в левый верхний угол.

CSI #K   - Erase in Line (EL)
Удаляет часть строки.
   # = 0  или  отсутствует (значение  по умолчанию) - очищается все от курсора до конца строки.
   # = 1 - очищается все от курсора до начала строки.
   #  = 2 - очищается вся строка. При этом положение курсора не меняется.

CSI #S   - Scroll Up (SU)
Прокручивает  текущую страницу терминала вверх на n (по умолчанию  1) строк. Новые строки добавляются снизу, строки в верхней части текущей страницы затираются.

CSI #T   - Scroll Down (SD)
Прокручивает  текущую  страницу терминала вниз на n (по умолчанию  1) строк. Новые строки добавляются сверху, строки в нижней части текущей страницы затираются.

CSI #;#f   - Horizontal and Vertical Position (HVP)
Полностью аналогичен CSI #,#H (CUP).

CSI #[;# ... ;#]m   - Select Graphic Rendition (SGR)
Установка  параметров отображения цветов тона (INK) и фона (PAPER)  печатаемых  символов. ПосМле SCI могут находиться ноль или более  (в текущей версии ANSI-драйвера - до десяти) параметров, разделенных  точками с запятыми. Если параметры не указаны, CSI m ведет себя как CSI 0m. Подробней о формате и значениях цветовых параметров данной управляющей последовательности приводится ниже в разделе "Формат цветовых(SGR)-параметров  в ANSI-драйвере".

CSI s   - Save Cursor Position (SCP)
Сохраняет  последние  координаты  положения  курсора. Сохраняет именно последние - никакой вложенности,буфера сохранения нет. Подмечено,  что последовательности из длинных цепочек из данных ESC-команд  используются в ряде ANSI-текстов для искусственного замедления  и  даже временной приостановки вывода текста на экран, так как каждая такая ESC-команда ничего на экране не меняет, но расходует определенное количество времени на обработку.

CSI u   - Restore Cursor Position (RCP)
Соответственно,  восстанавливает ранее сохраненную позицию курсора.

*     *     *

Формат цветовых(SGR)-параметров кода "CSI m" в ANSI-драйвере

0  -  Reset/Normal: Сброс всех атрибутов в исходные цвета (цвет тона INK - 7(белый), цвет фона PAPER - 0(черный),  яркость выключена, инверсия и мигание выключены.

1  -  BRIGHT ON: Включение яркости INK.

2-4  -  НЕ ПОДДЕРЖИВАЕТСЯ (в том числе во всех протестированных программах,  упомянутых в тексте - далее данное в скобках пояснение подразумевается).

5  - FLASH: В оригинале должно быть мигание (вкл/выкл) букв. На ATM  ввиду аппаратной невозможности  и программной трудоемкости реализации данного режима, этот параметр означает включение яркости  PAPER  (каковая, как правило, не поддерживается в ANSI). На удивление оказалось, что в ACiDview тоже нет мигания, а раздельная  яркость  поддержана, хотя  почему-то срабатывает не во всех  случаях, но, тем не менее, есть ANSI-файлы, ориентированные на повышенную яркость PAPER.

6  -  НЕ ПОДДЕРЖИВАЕТСЯ.

7  - INVERSE: Инвертирует/меняет места цвета INK и PAPER (но не яркость!  Если  изначально были цвета, к примеру, PAPER синий и INK  - белый с яркостью, то при включении режима инверсии получим на экране PAPER белый и INK - синий с яркостью).

8 - HIDDEN: Скрытый. Символы на экран не выводятся (в АТМ заменяются пробелами).Выводятся только атрибуты.

9  -  НЕ ПОДДЕРЖИВАЕТСЯ.

10-19  -  НЕ ПОДДЕРЖИВАЕТСЯ.

20  -  НЕ ПОДДЕРЖИВАЕТСЯ.

21  -  BRIGHT OFF: Выключение яркости INK.

22  - NORMAL: обычный цвет и яркость.

23-24  -  НЕ ПОДДЕРЖИВАЕТСЯ.

25  -  FLASH OFF: Выключение режима мигания, а в случае с АТМ - выключение BRIGHT PAPER.

26  -  НЕ ПОДДЕРЖИВАЕТСЯ.

27  -  INVERSE OFF: выключение режима инвертирования атрибутов.

28  -  HIDDEN OFF: выключение режима скрытия символов.

29  -  НЕ ПОДДЕРЖИВАЕТСЯ.

30-37  -  INK Colours: установка цвета тона в формате 30+n, где n = цвет из таблицы цветов ниже.

38  -  НЕ ПОДДЕРЖИВАЕТСЯ.

39  - Default INK: цвет текста по умолчанию (который установлен при очистке экрана в случае реализации на АТМ).

40-47 - PAPER Colours: установка цвета тона в формате 40+n, где n = цвет из таблицы цветов ниже.

48  -  НЕ ПОДДЕРЖИВАЕТСЯ.

49  - Default PAPER: цвет фона по умолчанию (который установлен при очистке экрана в случае реализации на АТМ).

50 и выше  - НЕ ПОДДЕРЖИВАЕТСЯ.

*     *     *

Таблица цветов по стандарту ANSI/EGA:

Intensity 0 1 2 3 4 5 6 7
Normal Black Red Green Yellow Blue Magenta Cyan White
Bright Black Red Green Yellow Blue Magenta Cyan White

*     *     *

Постскриптум:

Весь  код  данной программы и прилагаемой инструкции написаны и отлажены  исключительно  на  реальном  ATM-turbo 2+ в iS-Word и iS-ассемблере соответствено, в среде OS TASiS.

===============================================================
  (c)Тимонин Максим aka Maksagor/NedoPC group, 08.09.2018г.
===============================================================