Главная » Ассемблер, Железо » Работа с принтером через интерфейс USB

0

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

Принтеры являются счастливым исключением из общего правила: интерфейс USB для принтеров разработан таким образом, чтобы имитировать работу с принтером через параллельный порт, и полностью стандартизирован. Описание интерфейса принтеров приводится в спецификации Universal Serial Bus Device Class Definition for Printing Devices [93].

Для управления процессом печати используются командные языки фирм-изготовителей принтеров, поэтому создать единый универсальный драйвер практически невозможно. Существуют, однако, достаточно крупные группы изделий, для которых можно создать специфические драйверы, используя открытые (опубликованные) спецификации на командные языки. Например, как уже было указано в главе «Принтеры: печать в растровом режиме», для лазерных принтеров фактическим стандартом является язык HP PCL, а все струйные принтеры EPSON поддерживают язык Epson raster. Многие модели лазерных принтеров поддерживают также язык PostScript.

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

Любой принтер с интерфейсом USB должен поддерживать по крайней мере один из двух возможных интерфейсов:

•    однонаправленный интерфейс (Unidirectional Interface) поддерживает только передачу данных с хоста на принтер через выходную точку. Данные о состоянии принтера передаются через Основной канал сообщений по запросу GET_PORT_STATUS;

•    двунаправленный интерфейс (Bi-directional Interface) поддерживает передачу данных с хоста на принтер через выходную точку и позволяет хосту получать информацию о принтере и состоянии процесса печати через входную точку. Данные о текущем состоянии принтера можно также получить через Основной канал сообщений по запросу GET_PORT_STATUS.

Обычно используется только двунаправленный интерфейс. Если принтер поддерживает одновременно оба интерфейса, они должны быть реализованы как альтернативные. Тип интерфейса указывается в поле протокола дескриптора интерфейса: однонаправленному интерфейсу соответствует код Olh, двунаправленному — код 02h.

Принтеры поддерживают все стандартные запросы к устройству USB, а также несколько специфических (для своего класса) запросов:

•     Get Device ID – получить идентификатор устройства;

•     Get Port Status – получить информацию о текущем состоянии принтера;

•         Soft Reset – произвести программный сброс принтера. Запрос Get Device ID позволяет получить строку-идентификатор принтера. Запрос имеет следующие параметры:

•     bmRequestType = 10100001b;

•     bRequest = 0;

•     wVal ue — индекс конфигурации (нумерация конфигураций начинается с нуля);

•     wlndex — код интерфейса (в старшем байте — индекс интерфейса, в младшем байте — индекс варианта настройки; индексация начинается с нуля);

•     wLength — предельная длина возвращаемой строки в байтах (ограничитель на длину строки).

По запросу Get Device ID принтер передает хосту строку-идентификатор (Device ID) в формате, соответствующем стандарту IEEE- 1284: первые два байта содержат 16-разрядное слово, задающее общую длину идентификатора в байтах, а вслед за ними размещается собственно строка-идентификатор в коде ASCII.

ПРИМЕЧАНИЕ

При расчете размера идентификатора в байтах учитываются длина поля размера (2 байта) и длина текстовой строки (строка не имеет оконечного ограничителя и состоит исключительно из символов ASCII).

По запросу Get Port Status принтер передает хосту байт состояния, который имеет формат, аналогичный изображенному на рис. 7.2 формату регистра состояния параллельного порта. Байт состояния имеет следующую структуру:

•    биты 0-2 не используются, установлены в 0;

•    бит 3 — признак ошибки ввода-вывода (0 — ошибка, 1 — нет ошибки);

•    бит 4 — признак выбора принтера (0 — принтер в автономном режиме, 1 — принтер в режиме подключения);

•    бит 5 — контроль наличия бумаги (0 — бумага вставлена, 1 — нет бумаги);

•    биты 6 и 7 не используются, установлены в 0.

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

По запросу Soft Reset производится программный сброс принтера. Запрос имеет следующие параметры:

•    bmRequestType = 0010001 lb;

•    bRequest = 2;

•    wValue = 0;

•    wlndex — индекс интерфейса;

•    wLength = 0.

Передача данных при выполнении запроса не производится. Запрос Soft Reset вызывает очистку всех буферов данных принтера и сброс входного (Bulk IN) и выходного (Bulk OUT) каналов передачи массивов данных; все признаки ошибок и сбоев также сбрасываются. На USB-адрес и конфигурацию устройства программный сброс не влияет.

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

Поля bDeviceClass, bDevI ceSubCl ass, bDeviceProtocol в дескрипторе устройства содержат нули и не могут использоваться для проверки принадлежности устройства к классу принтеров. Поля idVendor и id- Product пригодны для идентификации устройства только в том случае, если программисту известно значение этих полей для принтеров данного типа: списки числовых идентификаторов для изделий известных фирм можно найти в Интернете; идентификатор устройства также иногда указывается в фирменной документации по программированию.

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

В дескрипторе интерфейса требуется проверить значение полей класса и подкласса устройства: для принтеров код базового класса имеет значение 07h, код подкласса — Olh. Тип интерфейса (однонаправленный или двунаправленный) особой роли не играет, так как программист обычно может работать только с Основным каналом сообщений и выходным каналом: структура информации о принтере, которую хост получает от входной точки, известна только фирме- разработчику устройства (открыто не публикуется). Из дескриптора выходной конечной точки (Bulk OUT) нужно извлечь значение поля bEndpoi ntAddress, содержащего адрес этой конечной точки, и значение поля wMaxPacketSi ze, задающего максимальный размер пакета при передаче данных на принтер. Опознать дескриптор конечной точки можно по значению полей bLength (поле должно содержать значение 07h), bDescri ptorType (поле должно содержать значение 05h), bEndpoi ntAddress (поле должно содержать 0 в старшем разряде) и Ьш Attributes (поле должно содержать значение 02h).

В листинге 8.3 приведена программа USB_EpsonStylus_Test, осуществляющая печать заштрихованного квадрата на струйном принтере EPSON Stylus в растровом черно-белом режиме с разрешением 360×360 точек/дюйм. Программа использует следующие процедуры:

•    процедура BulkOUT_Transaction передает на принтер команды и растровое изображение в режиме передачи массивов данных;

•    процедура OutCha rToPrn осуществляет вывод байта данных в промежуточный буфер (во избежание переполнения накопленную в буфере информацию нужно периодически сбрасывать на принтер при помощи процедуры BulkOUTJransaction);

•    процедура OutCommandToPrn использует подпрограмму OutCharTo- Prn для подачи на принтер командной последовательности символов;

•    процедура Show_Ident выводит на экран строку-идентификатор принтера.

Кроме того, программа USB_EpsonStylus_Test использует универсальные процедуры ввода-вывода из листинга 1.2, процедуру переключения в линейный режим адресации из листинга 2.1 и набор процедур для работы с контроллером и устройствами USB из листинга 8.1.

ПРИМЕЧАНИЕ

Программа USB_EpsonStylus_Test осуществляет поиск принтера только непосредственно по портам хост-контроллера, поэтому перед запуском теста нужно подсоединить принтер к одному из USB-портов системного блока.

Листинг 8.3. Печать заштрихованного квадрата на струйном принтере EPSON Stylus с интерфейсом USB

IDEAL

Р386

LOCALS

MODEL MEDIUM

: Физический адрес области памяти для списка кадров USB FrameListBaseAddr equ 200000h

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

Include "listl_03.inc"

; Подключить файл макросов

Include "listl_04.inc"

DATASEG

: Текстовые сообщения TxtO

DB LIGHTMAGENTA,0,22

DB "ПОИСК И ТЕСТИРОВАНИЕ ПРИНТЕРА EPSON".О

DB YELLOW,11.19

DB "Включите принтер, установите лист бумаги в",0

DB YELLOW.12,13,"приемный лоток и нажмите "

DB "любую клавишу на клавиатуре.".0 Txtl

DB LIGHTGREEN.il,0,"Идентификатор принтера:",0

DB YELLOW,24,9,"Нажмите любую клавишу на "

DB "клавиатуре и ждите завершения печати",0 : Сообщения об ошибках

NoPrn

DB 12,22,"Струйный принтер EPSON не обнаружен",0 PrnEr

DB 12,27,"Принтер не готов к работе".0 : Номер печатаемой строки изображения PrintingString DW ? : Номер печатаемого байта PrintingByte DW ?

; КОМАНДЫ ДЛЯ ПРИНТЕРА : Выйти из "Packet Mode" ExitPacketMode

DB lBh.0,0,0.1Bh.l

DB "PEJL 1284.4",OAh,"PEJL ",0Ah

; Выйти из "Remote Mode" TerminateRemoteMode

DB 4, lBh.0,0.0

; Инициализировать принтер Prnlnitialization

DB 2, lBh,’0′

Листинг 8.3 (продолжение)

: Установить графический режин SelectGraphicsMode

DB 6. lBh,'(‘.’G’,1,0.1

; Выбор монохронного режина MonochromeSelection

DB 7, lBh,'(‘.’К’.1,0,0,1

; Печать растровой графики (320 точек в строке) PrintRasterData

DB 8. lBh.V,0,10,10,1.64.1 : Перевод строки

SetRelVertPosition

DB 7. lBh.’ С,’V .2,0,1,0

; ДЕСКРИПТОРЫ КОМАНД

: Дескриптор конанды "Get Device Descriptor" GetDevDesc

DB 80h,6

DW 100h.0,8

; Дескриптор конанды "Set Address" SetAddrDesc

DB 0,5 DW 1,0,0

: Дескриптор конанды "Get Configuration Descriptor" GetConfDesc

DB 80h,6

DW 200h,0,8 : Дескриптор конанды "Set Configuration" SetConfigur

DB OOh.9 DW 1,0,0

; Дескриптор конанды "Get Port Status" GetPortStatus

DB OAlh.l DW 0,0,1

: Дескриптор конанды "Get Device ID" GetDevicelD D8 OAlh.O DW 0,0,8

ENDS

; Область паняти для хранения дескрипторов передачи SEGMENT USB_DESCR para public ‘DATA’

; Заголовок очереди дескрипторов QH_Descriptor DD 00000003h :единственный заголовок DD OOOOOOOOh указатель на первый TD DD 0,0,0,0,0,0 ;область данных ПО : Список дескрипторов для одной транзакции TD_Array DD 8*64 DUP(?) ENDS

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS

CODESEG

;* Основной нодуль програнны * PROC USB EpsonStyl us_Test

mov AX.DGR0UP

mov DS.AX

mov [CS:Mai nDataSeg].AX : Установить текстовый режим и очистить экран

mov АХ.З int 10h

: Скрыть курсор – убрать за нижнюю границу экрана

mov [ScreenString],25

mov [ScreenColumn].О call SetCursorPosition : Проверить наличие PCI BIDS

mov AX.OBlOlh int lAh

jc

@@PCIBIDSNotFound cmp EDX.20494350h jne

@@PCIBIDSNotFound : Вывести текстовые сообщения на экран MShowColorText 3.TxtO call GetChar

; Установить режим прямой адресации памяти

call Initialization

; Инициализировать дескрипторы USB

call InitializeDeascriptors

; ЦИКЛ ПОИСКА ХОСТ-КОНТРОЛЛЕРОВ

mov [SearchResult],0

mov [USB_HostIndex],0

@@NextHost:

; Найти контроллер USB

call FindUSBController cmp [SearchResult],0 jne

@@NoHost : Произвести глобальный сброс контроллера

mov DX.[USB_BaseAddr]

mov AX.100bустановить сигнал сброса

out DX.AX

; Ожидать не менее 10 не call Wait05s

; Снять сигнал сброса

mov АХ,0 out DX.AX : Ожидать не менее 10 не call Wait05s

; Обнулить счетчик номеров

mov [USBDevi ceNumber], 0

; Загрузить указатель на список кадров в регистр

; адреса списка кадров

mov DX.[USB_BaseAddr]

add DX.6

mov AX,0 out DX.AX

Листинг 8.3 (продолжение)

add DX,2

mov EAX.FrameListBaseAddr out DX.EAX

; Активизировать хост-контроллер

mov DX,[USB_BaseAddr]

mov AX,1 out DX.AX

; Проверить регистр состояния порта 1

mov [USB_PortNum].1

; Вычислить адрес регистра состояния порта

mov DX,[USB_BaseAddr]

add DX.lOh

; Запомнить адрес регистра состояния порта

mov [USB_PortReg],DX

; Проверить наличие устройства in AX.DX test AX.OOOFh jz P@TestPort2

; Присвоить устройству порядковый номер call Enumeration

; Получить дескриптор конфигурации call GetConfigurationDescriptor : Устройство является принтером? cmp [word ptr DataBuffer+9+5],0107h

je@@PrinterFound

; Проверить регистр состояния порта 2

@@TestPort2:

mov [USB_PortNum],2

; Вычислить адрес регистра состояния порта

mov DX,[USB_BaseAddr]

add DX,12h

; Запомнить адрес регистра состояния порта

mov [USBPortReg], DX

; Проверить наличие устройства in AX.DX test AX.OOOFh jz

@@ContrStop

; Присвоить устройству порядковый номер call Enumeration

; Получить дескриптор конфигурации call GetConfigurationDescriptor

; Устройство является принтером? cmp [word ptr DataBuffer+9+5],0107h

je

@@PrinterFound

; Остановить контроллер e@ContrStop:

mov DX,[USB_BaseAddr]

mov AX,0 out DX.AX

jmp

@@NextHost

@@PrinterFound:

; СКОНФИГУРИРОВАТЬ УСТРОЙСТВО : Подать команду "Set Configuration"

mov SI.offset SetConfigur call Setup_Transaction : Подать команду "Get Port Status"

mov SI.offset GetPortStatus call StatusIN_Transaction : Проверить состояние принтера

cmp [byte ptr DataBuffer],18h jne

@@printerError

: ИДЕНТИФИЦИРОВАТЬ УСТРОЙСТВО : Подать команду "Get Device ID"

mov SI,offset GetDevicelD call StatusINTransaction

; Определить полную длину дескриптора

mov АХ,[word ptr DataBuffer] xchg AL.AH переставить байты

mov [word ptr GetDeviceID+6],AX : Подать команду "Get Device ID" повторно

mov SI,offset GetDevicelD call StatusINTransaction

; Проверить тип принтера по идентификатору

mov SI,offset DataBuffer

mov CX,[SI] загрузить длину строки xchg CL.CH переставить байты

add SI,2 cmp CX.4

jbe

@@DeviceNotFound sub CX,4

; Цикл поиска слова "EPSON"

mov EAX."OSPE"

@@SearchEPSO:

cmp EAX.[SI]

je

@@SearchStyl

inc SI

loop

@@SearchEPSO jmp

@@DeviceNotFound : Цикл поиска слова "Stylus"

mov EAX."lytS" @CSearchStyl:

cmp EAX.[SI]

je

@@ShowDeviceID

inc SI

loop

@@SearchStyl jmp

@@DeviceNotFound : Показать полученный дескриптор

Листинг 8.3 (продолжение)

@@ShowDeviceID:

call ClearScreen

MShowColorString TxtO

MShowColorText 2,Txtl

mov [ScreenString],19

mov CX,[word ptr GetDeviceID+6]

call Showldent

call GetChar

: ПОДГОТОВКА К НАЧАЛУ ПЕЧАТИ ИЗОБРАЖЕНИЯ

; Сбросить триггер данных

mov [dword ptr DataTrigger],0

; Выйти из "Packet Mode"

mov SI.offset ExitPacketMode call OutCommandToPrn : Инициализировать принтер

mov SI.offset Prnlnitialization cal1 OutCommandToPrn : Включить графический режим печати

mov SI,offset SelectGraphicsMode cal1 OutCommandToPrn : Выбрать монохромный режим

mov SI,offset MonochromeSelection call OutCommandToPrn

; Передать команды на принтер

call BulkOUT_Transaction

; ОСНОВНОЙ ЦИКЛ (ПО ПЕЧАТАЕМЫМ СТРОКАМ) , : Сбросить счетчик строк растра

mov [PrintingString],0

; Задать начальное значение байта штриховки

mov DL,80h

№Р0:

: Задать длину строки 40 байт (320/В)

mov SI,offset PrintRasterData call OutCommandToPrn : Верхнюю и нижнюю строки закрасить полностью cmp [PrintingString],0

je

@@TopOrBottomLine cmp [PrintingString],319 jne

@@Shade

@@TopOrBottomLi ne:

mov CX.40

mov AL.OFFh :сплошная линия

; Цикл по печатаемым байтам

@@Р1: call OutCharToPrn loop (а@Р1 jmp

@@LF

; Заштриховать квадрат

@@Shade:

: Левая граница

mov AL.DL or AL.80h cal1 OutCharToPrn

; внутренняя часть

mov CX.38

mov AL.DL №2: call OutCharToPrn loop

@@P2 : Правая граница

mov AL.DL or AL.Olh cal1 OutCharToPrn : Повернуть байт штриховки влево rol DL.l : Перейти на следующую строку растра принтера

@@LF:

mov SI.offset SetRelVertPosition

call OutCommandToPrn : Послать на принтер команду возврата каретки

mov AL.ODh call OutCharToPrn : Передать данные на принтер

call BulkOUT_Transaction : Перейти на следующую строку экранного изображения

inc [PrintingString] cmp [PrintingString],320 jl

@@P0

; Послать на принтер коды завершения страницы

movAL.OCh ;перевод формата

callOutCharToPrn

; Инициализировать принтер

movSI.offset Prnlnitialization

callOutCommandToPrn

callBulkOUTTransaction

; Остановить контроллер

mov DX,[USBBaseAddr]

mov AX.O out DX.AX

; Переустановить текстовый режин и очистить экран

mov АХ.З int 10h

; Выход в DOS

mov AH,4Ch int 21h

: Обработка ошибок

@@NoHost:

Листинг 8.3 (продолжение)

cmp [USBHostlndex] ,0

je

@@HostNotFound

jmp short

@@DeviceNotFound

; He поддерживается PCI BIOS (a@PCIBIOSNotFound:

MFatalError NoPCI : Неверный нонер регистра

@@BadRegi sterNumber:

MFatalError BadRg

; Нет ни одного контроллера USB

@@HostNotFound:

MFatalError NoUSB

; Устройство USB не найдено

@@DeviceNotFound:

: Остановить контроллер

mov DX, [USBBaseAddr]

mov AX.O out DX.AX MFatalError NoPrn : Принтер не готов к печати

@@PrinterError:

; Остановить контроллер

mov DX,[USB_BaseAddr]

mov AX.O out DX.AX MFatalError PrnEr ENDP USB_EpsonStylus_Test

;* ПЕРЕДАТЬ МАССИВ ДАННЫХ УСТРОЙСТВУ USB * ;* Передаваемые параметры:*

;* BULKDataSize – объем передаваемых данных. *

PROC BulkOUT Transaction near pushad

; Загрузить в ESI указатель на массив дескрипторов

mov ESI, [AddrTDArray]

; Загрузить в ЕВХ указатель на буфер данных

mov ЕВХ, [AddrDataDescr]

; Вычислить количество полных (64-байтных) блоков

mov СХ, [BULKDataSize] shr СХ.6количество 64-байтных блоков

cmp СХ,0

je

@@ShortDataBlock

@@NextDataBlock:

: Сформировать дескриптор данных

; Указатель на следующий TD

mov ЕАХ,ESI

add ЕАХ.32 mov[GS:ESI],ЕАХ

; Слово управления

movЕАХ,[ShDevType] ;тип устройства

orEAX,00800000h ;признак активности

mov[GS:ESI+4].EAX : Маркер

movЕАХ.[ShFuncNum] ;нонер функции

orEAX,07E000Elh ;передать 64 байта

orEAX,[DataTrigger] ;триггер данных

orЕАХ.00008000h конечная точка 1

mov[GS:ESI+8],ЕАХ

xor[dword ptr DataTrigger],80000h

mov[GS:ESI+12],EBX ;буфер данных

addЕВХ,64

xorEAX,EAX

mov[GS:ESI+16] ,EAX

mov[GS:ESI+20],EAX

mov[GS: ESI+24], EAX

mov[GS:ESI+28].EAX

addESI,32

loop@@NextDataBlock

: Формирование неполного блока

@@ShortDataBlock:

: Вычислить размер последнего (неполного) блока

mov DX,[BULK_DataSize] and EDX,111111b

cmp DX,0;разнер больше нуля?

je@@NoShortBlock

; Сформировать дескриптор данных короткого блока

mov[dword ptr GS: ESI]. lb последний TD

; Слово управления

movEAX.[ShDevType] :тип устройства

orEAX,00800000h ;признак активности

mov[GS:ESI+4],EAX

; Маркер

movEAX,[ShFuncNum] ;номер функции

decDX

shlEDX,21

orEAX,EDX:размер блока

orEAX.[DataTrigger] :триггер данных

orEAX.OOOOBOOOh конечная точка 1

or’EAX.OElh

mov[GS:ESI+8],EAX

xor[dword ptr DataTrigger].80000h

mov[GS:ESI+12],EBX

xorEAX, EAX

mov[GS:ESI+16],EAX

mov[GS:ESI+20].EAX

mov[GS.-ESI+24] ,EAX

25-231

Листинг 8.3(продолжение)

V

mov [GS:ESI+28],EAX

jmp short

@@Start

; Нет короткого блока, пометить последний полный блок : как конечный

@@NoShortB1ock:

sub ESI,32

mov [dword ptr GS:ESI],lb ;последний TO

@@Start:

; Установить указатель на список дескрипторов

; (контроллер начинает передачу данных)

mov ЕАХ, [AddrTOArray]

mov ESI,[Addr_QH]

add ESI,4

mov [GS:ESI].EAX

; Ожидать завершения операции

@@Wai t_OpComplete:

cmp [dword ptr GS:ESI].lb jne

@@Wait_OpComplete

mov [BULKDataSize] ,0 popad ret

: Переполнен массив дескрипторов

@@TD_Array_Error:

: Остановить контроллер

mov DX, [USBBaseAddr]

mov AX.O out DX.AX MFatalError DsErr ENDP BulkOUT Transaction

;* ВЫВЕСТИ СИМВОЛ НА ПРИНТЕР * ;* Параметры:*

;* AL  код символа.*

PROC OutCharToPrn near push BX

cmp [BULKDataSize] ,4096 jae

@@Data_BufferFul1

mov BX,offset DataBuffer

add BX, [BULKDataSize]

mov [BX],AL

inc [BULK_DataSize] pop BX ret

: Переполнен буфер данных

@@Data_Buffer_Ful1:

; Остановить контроллер

mov DX,[USB_BaseAddr]

mov AX.O out DX,АХ MFatalError BfErr ENDP OutCharToPrn

;* ПОСЛАТЬ КОМАНДУ НА ПРИНТЕР * ;* Параметры:*

;* DS:SI – указатель на строку команды. * ;* Первый байт строки содержит количество * ;* байтов команды, посылаемых на принтер. *

PROC OutCommandToPrn near pusha eld

: Загрузить счетчик байтов команды в СХ lodsb

xor СХ.СХ

mov CL.AL POOutNextByte: lodsb

cal 1 OutCharToPrn 1 oop

@@OutNextByte popa ret

ENDP OutCommandToPrn

;* ОТОБРАЗИТЬ СОДЕРЖИМОЕ ИДЕНТИФИКАТОРА ПРИНТЕРА *

PROC Showjdent near pusha

mov [ScreenString],12

mov [ScreenColumn].0

mov SI,offset DataBuffer

mov CX,[SI] загрузить длину строки xchg CL.CH переставить байты

add SI.2

@@NextByte:

lodsb

call ShowASCIIChar 1 oop

@@NextByte popa ret

ENDP Showjdent ENDS

: Подключить процедуры ввода данных и вывода на экран : в текстовом режиме inrlurlp "list! f)?.inr"

Листинг 8.3 (продолжение)

; Подключить подпрограмму, переводящую сегментный

; регистр GS в режим линейной адресации

Include "list2_01.inc"

; Подключить процедуры для работы с контроллером USB

include "list8_01.inc"

END

В приведенном примере используется набор команд Epson raster, описанный в главе 7 «Принтеры: печать в растровом режиме». Следует отметить, что при подключении принтера через интерфейс USB сразу после завершения процесса конфигурирования устройству требуется подать специальную команду «Exit Packet Mode», предназначенную для переключения принтера из некоего «пакетного режима Epson» (в открытой документации этот режим не описан) в обычный режим работы. Командная ESC-последовательностьдля выхода из пакетного режима очень длинная:

OOh. OOh. OOh. lBh, Olh. "@EJL", 20h. "1284.4". OAh. "PEJL", 20h, 20h. 20h, 20h, 20h, OAh

i

Проверка принадлежности принтера к группе моделей EPSON Stylus осуществляется по полученному от принтера идентификатору устройства: строка должна содержать слова «EPSON» и «Stylus».

ВНИМАНИЕ

Программа из листинга 8.3 не предназначена для тестирования принтеров серий С20 и С40, которые используют специфические значения параметров в команде передачи растровой строки.

Источник: Кулаков В. К90 Программирование на аппаратном уровне: специальный справочник (+дискета). 2-е издание. — СПб.: Питер, 2003. — 847 е.: ил.

По теме:

  • Комментарии