Русификация принтеров: практические советы

Нередко единственная реальная возможность русификации новой модели принтера - это написание для него собственного драйвера, при проектировании которого у программиста может возникнуть ряд проблем. Их обсуждению и посвящается данная статья.
В общем случае "нерусифицированный" принтер - принтер, в ПЗУ знакогенератора которого нет русских букв или их расположение в верхней половине таблицы ASCII кодов иное, чем в принтерах с общепризнанной кодировкой (например, CPF-136H или CPF-80H). Но несмотря на существующий стандарт, на советский рынок и в дальнейшем будут поступать принтеры с другими кодировками. Например, во втором номере журнала "Компьютер" было опубликовано сообщение об ожидающихся поставках STAR LC-15 с основной кодировкой знакогенератора.
Рассмотрим задачу адаптации кодировок (она очень актуальна из-за увеличивающегося объема поставок подобных принтеров) и общие вопросы русификации принтеров.
Драйверы-перекодировщики создаются для устранения несовпадения кодировок. Их удобнее выполнить в виде резидентной программы, получающей управление по прерыванию 17,6. Это не означает, что нельзя написать драйвер в виде устанавливаемого драйвера устройства для PRN или LPT1, просто в этом случае вы будете лишены возможности распечатки текстов из редакторов или других прикладных программ, напрямую обращающихся к вектору 17,6.
Драйвер-перекодировщик обычно проектируется состоящим из двух частей: резидентной и инициализирующей.
Инициализирующая часть выполняет следующие действия:
-    выводит на экран свое название;
-    переустанавливает вектор 17t6 на один из векторов, зарезервированных в DOS для пользователя (например, 60,6) (В дальнейшем для удобства будем называть этот вектор "теневым.");
-    устанавливает в нем указатель на свою резидентную часть;
-    передает управление DOS, оставляя резидентную часть в памяти.
Резидентная часть драйвера-перекодировщика должна выполнять следующее:
-    разрешать прерывания командой STI (если этого не сделать, то конечным итогом будет зависание машины при печати) ;
-    анализировать тип запроса к принтеру: печать символа, инициализация или опрос состояния; если производится инициализация или опрос состояния, то передавать управление "теневому" вектору с последующим выходом из прерывания;
-    анализировать, к верхней или нижней половине таблицы ASCII относится выводимый символ, и если к верхней, то, используя заранее подготовленную таблицу, которая также относится к резидентной части, перекодировать символ;
-    передавать управление "теневому" вектору с последующим выходом из прерывания.
Таблица перекодировки ориентирована на использование команды XLATB. Объем таблицы 128 байт. Она построена по следующему принципу: содержимое байта таблицы с номером
<код символа верхней половины таблицы ASCII> - 128 равно коду символа в кодировке принтера. Например, для перекодировки символа "р" в 97-й элемент таблицы надо поместить число 176, которое соответствует коду данного принтера в прошивке CPF - 136Н.
Изложенный набор действий - минимально необходимый для перекодировщика; он обеспечивает правильную печать только текстовой информации. А если программа (например, GRAPHICS) будет воспринята как русские буквы, а следовательно, перекодируется, в результате на бумаге получится искаженное изображение.
В приложении приведен исходный текст драйвера-перски дировщика для CPF - 136Н, "прозрачного" для графических данных.
Распознавание графических данных в драйвере организо вано следующим образом. В резидентной части драйвера резервируется двухбайтная переменная, которая в старшем байте содержит предпоследний, в младшем последние выведенные символы. При очередном обращении к драйверу серией сравнений определяют, не являются ли два последних выведенных символа заголовком ESC-последовательности, задающей вывод графической информации.
Если такая последовательность распознана, то значения следующих двух выводимых символов задают значения младшего и старшего байтов счетчика графических данных, под который также необходимо зарезервировать слово в резидентной части. Ненулевое значение счетчика будет сообщать перекодировщику о том, что выводятся графические данные и перекодировку проводить не нужно. Единственное, что в этом случае должен делать перекодировщик, - декрементировать счетчик при выводе очередного байта.

Рассмотрим проблемы русификации принтеров, в знакогенераторе которых нет русских букв. Их можно разделить на три группы:
1.    Загружаемые (downlodable) принтеры. В них предусмотрена загрузка образов букв, задаваемых пользователем, в оперативную память принтера с последующим выводом в текстовом режиме.
2.    Частично загружаемые. К ним относятся принтеры с маленьким объемом буферной памяти, поэтому в отличие от принтеров первой группы, позволяющих загружать от 96 до 256 символов, в принтеры этой группы одновременно можно загрузить около 30 символов. Для преодоления этого ограничения при написании драйвера в принтер загружаются образы только тех букв, которые по начертанию не совпадают ни с одним из латинских символов. К этой группе относятся также те из загружаемых принтеров, которые вследствие конструктивных ограничений не позволяют загружать символы с кодами, пересекающимися с кодами русских букв в альтернативной кодировке. Драйверы этой группы принтеров в отличие от драйверов загружаемых принтеров содержат резидентную часть - перекодировщик.
3.    Незагружаемые принтеры, "рисующие" русские буквы в графическом режиме. Текст на таких принтерах выводится медленнее, чем на загружаемых, и отсутствует возможность выбора между черновым и качественным режимами печати.
Основная проблема для всех принтеров, не имеющих (строенной знакогенерации русских букв, - формирование матричного представления символов. В |1] и [2] рассмотрены 1ринципы формирования образа загружаемого символа, кото- )ый, если рассматривать только матрицу, отбросив формирова- ше управляющих байтов, можно использовать для незагружа- :мых принтеров. Этот принцип - общий как для 9-, так и для 14-иголочных принтеров. Помимо 9- и 24-иголочных принте- юв, существуют 18-иголочные, которые по способу формиро- зания и кодировке матрицы символов совпадают с 9-иголоч- аыми.
Для формирования образов загружаемых символов существуют специальные утилиты. Автором, например, используется утилита DJfont фирмы Jirapol Pobukadee Megachomp Company, формирующая дисковые файлы с кодом загружаемого шрифта в стандарте EPSON, который применяется для загрузки EPSON-совместимых принтеров. В отличие от них для IBM-совместимых принтеров есть свой стандарт загрузки.
Эти два стандарта различаются количеством и значением байтов, описывающих матрицу образа символа, совпадая по способу кодировки самой матрицы. Если сравнивать более широко, то IBM-стандарт позволяет формировать и использовать символы псевдографики и так называемые символы оттенения, что нельзя сделать для EPSON-совместимых принтеров. Зато EPSON-стандарт более "универсальный", т. е. один и тот же драйвер можно использовать для русификации принтеров различных моделей.
Простейший драйвер для загружаемых принтеров должен выполнять следущее:
-    проверять готовность принтера. Если он не готов, сообщать об этом пользователю (Коды, соответствующие значениям "готов", "не готов", приходится определять экспериментально с помощью отладчика, так как на коды, возвращаемые при опросе состояния, не существует определенного стандарта.);
-    открывать файл, содержащий код образа шрифта, и считывать его содержимое в подготовленную область, состоящую из буфера, окаймленного необходимыми ESC-последователь- ностями.
-    выводить содержимое этой области в принтер;
-    закрывать файл.
Драйверы частично загружаемых принтеров - объединение драйвера-перекодировщика и драйвера-загрузчика. Для принтеров, у которых возможна загрузка только в нижнюю половину таблицы символов (например, EPSON LQ-1500), резидентная часть их драйверов (помимо вышеизложенных действий) должна обеспечивать переключение между ОЗУ и ПЗУ знакогенератора. В качестве другого примера можно привести принтер EPSON LQ-1050, у которого верхняя половина таблицы символов может содержать либо псевдографику (ПЗУ), либо загружаемый шрифт (ОЗУ), поэтому драйвер такого принтера должен обеспечивать их переключение при печати.
У драйверов незагружаемых принтеров буфер приема образа шрифта находится в резидентной части, что позволяет загружать драйвер и при выключенном принтере. Поскольку количество байтов образа одинаково для всех символов, при печати драйвер легко находит образ нужного символа в буфере. Как правило, найденный образ не выводится сразу на печать, а помещается в специальный буфер, в котором формируется целиком одна строка. Такой прием применяют, чтобы избежать челночного движения головки при побуквенной печати.
Отладка драйверов, содержащих резидентную часть, ведется с помощью вспомогательной программы, которая выводит на печать несколько символов. Просматривая отладчиком эту программу, вы попадете на прерывание 17t<s и исследуете, как реагирует ваш драйвер на тот или иной символ.
Рассмотренные выше приемы написания драйверов-русификаторов охватывают особенности некоторых имеющихся принтеров. Как видно из обзора, функции драйверов можно определенным образом стандартизовать, что приводит к упрощению процедуры написания, а следовательно, и к удешевлению стоимости драйверов. Последнее замечание относится к потенциальным покупателям принтеров. В некоторых случаях лучше (и дешевле) приобрести хороший принтер с хорошим драйвером, чем плохой с русскими буквами в ПЗУ знакогенератора.

Приложение
Текст драйвера-перекодировщика для принтера CPF-136H
.MODEL TINY .CODE
cr    EQU    ODh    ; возврат каретки
if    EQU    OAh    ; перевод строки
ORG    lOOh
start:    jmp    Init
; Резидентная часть драйвера
; При передаче управления этой части драйвера от 17-го вектора прерывания ; АН содержит тип обращения к принтеру, DX - номер печатающего устройст- ; ва. Если ЛН содержит О, то содержимое AL рассматривается как выводимый ; символ.
Vector 17h:
sti
;    Определение типа запроса к принтеру               
сшр    ah,О
jne    Print_quit
push    bx ds cs
pop    ds
;    Распознавание заголовка ESC-последовательности   
cmp    word ptr Last__chars, 1 B5Ah
je    Graphics
cmp    word ptr Last_chars, I B59h
je    Graphics
cmp    word ptr Last_chars, 1 B4Ch
je    Graphics
cmp    word ptr Last_chars, 1 B4Bh
je    Graphics
;    Происходит вывод текстовой информации?    
cmp    word ptr Counter,0
je    Text_byte
dec    word ptr Counter
jmp    Print_Exit
Text_byte:
;    Сохранить последний выводимый символ   
mov    bx,Last_chars
mov    bh.al
xchg    bh,bl
mov    Last_chars,bx
;    Определение, к какой половине таблицы ASCII относится символ    
test    al,80h
je    Print_exit
;    Перекодировка символа           
mov    bx,offset Table
xlatb
;    Восстановление используемых регистров    
Print_exit:
pop    ds bx
Print_quit:
int    60h
iret
;    Оформление счетчика количества байтов графических данных    
Graphics:
cmp    byte ptr Counter,О jne    Second_byte
mov    byte ptr Counter,al
jmp    Print__Exit
Second_byte:
mov    byte ptr Counterp],al
mov    word prt Last_Chars,0
jmp    Print_Exit
; Таблица перекодировки
Table    db    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142.143
db    144,145,146,147,148,149.150,151,152,153,154.155,156,157.158,159
db    160,161,162,163,164J65,166,167,168,169.170,171,172,173.174,175
db    224,225,226,227,228,229,230,231,232,233.234.235,236,237.238.239
db    192,193,194,195,196,197,198,199,200,201.202.203.204,205.206.207
db    208,209,210,211,212,213,214,215,216,217,218,219,220,221.222,223
db    176.177,178,179,180,181,182,183.184.185,186.187.188.189,190.191
db    240,241,242,243,244,245.246,247,248,249,250.251.252,253,254.255
; Вспомогательные переменные для распознавания ; вывода графической информации
; Last_chars    dw    0    ; Два последних символа в текстовом
режиме
Counter    dw    О    ; Счетчик количества байтов графических
данных
; Инициализация драйвера lnit:
;    Вывод имени программы            
    mov    ah ,9
    mov    dx, offset My_name
    -    int         21h
;    Получение и сохранение в стеке адресов 17-го вектора    
    mov    ax,35l7h
    -    -    int            21 h
    push    es
    push    bx
;    Вычисление адреса 60-го вектора           
    mov    ах,О
    mov    es,ax
    mov    di,60h
    shl    di. 1
    -    shl    di, 1
;    Копирование 17-го вектора в 60-й вектор   
            pop    ах
    mov    es: [di] ,ах
    pop    ах
            mov    es:2[dij ,ax
;    Переустановка 17-го вектора на резидентную часть драйвера    
    mov    dx,offset Vector 17h
    mov    ax,25l7h
        - int        21 h
;    Выход в DOS            -       
mov    dx,OFFSET lnit
int    2!h
My_name db    ' Драйвер-перекодировщик для CPF-136H\cr,lf.lf
db    * Драйвер создан Д. И. Правиковым, ' , cr. If
db    " Институт Проблем управления ,cr,If.'$'
END    start
 


Обсудить вопрос в студенческом форуме

 

Сайт содержит информацию о учебном заведении и студенческой общине и не является официальным