Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаб11_ЮСБ.doc
Скачиваний:
13
Добавлен:
21.12.2018
Размер:
1.78 Mб
Скачать

Листинг программы: печать заштрихованного квадрата на струйном принтере epson Stylus с интерфейсом usb.

IDEAL

P386

LOCALS

MODEL MEDIUM

; Физический адрес области памяти для списка кадров USB

FrameListBaseAddr equ 200000h

; Подключить файл мнемонических обозначений

; кодов управляющих клавиш и цветовых кодов

include "list1_03.inc"

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

include "list1_04.inc"

DATASEG

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

Txt0 DB LIGHTMAGENTA,0,22

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

DB YELLOW,11,19

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

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

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

Txt1 DB LIGHTGREEN,11,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 1Bh,0,0,0,1Bh,1

DB "@EJL 1284.4",0Ah,"@EJL ",0Ah

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

TerminateRemoteMode DB 4, 1Bh,0,0,0

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

PrnInitialization DB 2, 1Bh,'@'

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

SelectGraphicsMode DB 6, 1Bh,'(','G',1,0,1

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

MonochromeSelection DB 7, 1Bh,'(','K',1,0,0,1

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

PrintRasterData DB 8, 1Bh,'.',0,10,10,1,64,1

; Перевод строки

SetRelVertPosition DB 7, 1Bh,'(','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 00h,9

DW 1,0,0

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

GetPortStatus DB 0A1h,1

DW 0,0,1

; Дескриптор команды "Get Device ID"

GetDeviceID DB 0A1h,0

DW 0,0,8

ENDS

; Область памяти для хранения дескрипторов передачи

SEGMENT USB_DESCR para public 'DATA'

; Заголовок очереди дескрипторов

QH_Descriptor DD 00000003h ;единственный заголовок

DD 00000000h ;указатель на первый 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_EpsonStylus_Test

mov AX,DGROUP

mov DS,AX

mov [CS:MainDataSeg],AX

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

mov AX,3

int 10h

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

mov [ScreenString],25

mov [ScreenColumn],0

call SetCursorPosition

; Проверить наличие PCI BIOS

mov AX,0B101h

int 1Ah

jc @@PCIBIOSNotFound

cmp EDX,20494350h

jne @@PCIBIOSNotFound

; Вывести текстовые сообщения на экран

MShowColorText 3,Txt0

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 AX,0

out DX,AX

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

call Wait05s

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

mov [USB_Device_Number],0

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

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

mov DX,[USB_BaseAddr]

add DX,6

mov AX,0

out DX,AX

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,10h

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

mov [USB_PortReg],DX

; Проверить наличие устройства

in AX,DX

test AX,000Fh

jz @@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 [USB_PortReg],DX

; Проверить наличие устройства

in AX,DX

test AX,000Fh

jz @@ContrStop

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

call Enumeration

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

call GetConfigurationDescriptor

; Устройство является принтером?

cmp [word ptr DataBuffer+9+5],0107h

je @@PrinterFound

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

@@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 GetDeviceID

call StatusIN_Transaction

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

mov AX,[word ptr DataBuffer]

xchg AL,AH ;переставить байты

mov [word ptr GetDeviceID+6],AX

; Подать команду "Get Device ID" повторно

mov SI,offset GetDeviceID

call StatusIN_Transaction

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

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"

@@SearchStyl:

cmp EAX,[SI]

je @@ShowDeviceID

inc SI

loop @@SearchStyl

jmp @@DeviceNotFound

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

@@ShowDeviceID:

call ClearScreen

MShowColorString Txt0

MShowColorText 2,Txt1

mov [ScreenString],19

mov CX,[word ptr GetDeviceID+6]

call Show_Ident

call GetChar

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

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

mov [dword ptr DataTrigger],0

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

mov SI,offset ExitPacketMode

call OutCommandToPrn

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

mov SI,offset PrnInitialization

call OutCommandToPrn

; Включить графический режим печати

mov SI,offset SelectGraphicsMode

call OutCommandToPrn

; Выборать монохромный режим

mov SI,offset MonochromeSelection

call OutCommandToPrn

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

call BulkOUT_Transaction

; ОСНОВНОЙ ЦИКЛ (ПО ПЕЧАТАЕМЫМ СТРОКАМ)

; Сбросить счетчик строк растра

mov [PrintingString],0

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

mov DL,80h

@@P0:

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

mov SI,offset PrintRasterData

call OutCommandToPrn

; Верхнюю и нижнюю строки закрасить полностью

cmp [PrintingString],0

je @@TopOrBottomLine

cmp [PrintingString],319

jne @@Shade

@@TopOrBottomLine:

mov CX,40

mov AL,0FFh ;сплошная линия

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

@@P1: call OutCharToPrn

loop @@P1

jmp @@LF

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

@@Shade:

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

mov AL,DL

or AL,80h

call OutCharToPrn

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

mov CX,38

mov AL,DL

@@P2: call OutCharToPrn

loop @@P2

; Правая граница

mov AL,DL

or AL,01h

call OutCharToPrn

; Повернуть байт штриховки влево

rol DL,1

; Перейти на следующую строку растра принтера

@@LF: mov SI,offset SetRelVertPosition

call OutCommandToPrn

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

mov AL,0Dh

call OutCharToPrn

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

call BulkOUT_Transaction

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

inc [PrintingString]

cmp [PrintingString],320

jl @@P0

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

mov AL,0Ch ;перевод формата

call OutCharToPrn

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

mov SI,offset PrnInitialization

call OutCommandToPrn

call BulkOUT_Transaction

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

mov DX,[USB_BaseAddr]

mov AX,0

out DX,AX

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

mov AX,3

int 10h

; Выход в DOS

mov AH,4Ch

int 21h

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

@@NoHost:

cmp [USB_HostIndex],0

je @@HostNotFound

jmp short @@DeviceNotFound

; Не поддерживается PCI BIOS

@@PCIBIOSNotFound:

MFatalError NoPCI

; Неверный номер регистра

@@BadRegisterNumber:

MFatalError BadRg

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

@@HostNotFound:

MFatalError NoUSB

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

@@DeviceNotFound:

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

mov DX,[USB_BaseAddr]

mov AX,0

out DX,AX

MFatalError NoPrn

; Принтер не готов к печати

@@PrinterError:

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

mov DX,[USB_BaseAddr]

mov AX,0

out DX,AX

MFatalError PrnEr

ENDP USB_EpsonStylus_Test

;***********************************************

;* ПЕРЕДАТЬ МАССИВ ДАННЫХ УСТРОЙСТВУ USB *

;* Передаваемые параметры: *

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

;***********************************************

PROC BulkOUT_Transaction near

pushad

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

mov ESI,[Addr_TD_Array]

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

mov EBX,[Addr_DataDescr]

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

mov CX,[BULK_DataSize]

shr CX,6 ;количество 64-байтных блоков

cmp CX,64-1

ja @@TD_Array_Error

cmp CX,0

je @@ShortDataBlock

@@NextDataBlock:

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

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

mov EAX,ESI

add EAX,32

mov [GS:ESI],EAX

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

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

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

mov [GS:ESI+4],EAX

; Маркер

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

or EAX,07E000E1h ;передать 64 байта

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

or EAX,00008000h ;конечная точка 1

mov [GS:ESI+8],EAX

xor [dword ptr DataTrigger],80000h

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

add EBX,64

xor EAX,EAX

mov [GS:ESI+16],EAX

mov [GS:ESI+20],EAX

mov [GS:ESI+24],EAX

mov [GS:ESI+28],EAX

add ESI,32

loop @@NextDataBlock

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

@@ShortDataBlock:

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

mov DX,[BULK_DataSize]

and EDX,111111b

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

je @@NoShortBlock

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

mov [dword ptr GS:ESI],1b ;последний TD

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

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

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

mov [GS:ESI+4],EAX

; Маркер

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

dec DX

shl EDX,21

or EAX,EDX ;размер блока

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

or EAX,00008000h ;конечная точка 1

or EAX,0E1h

mov [GS:ESI+8],EAX

xor [dword ptr DataTrigger],80000h

mov [GS:ESI+12],EBX

xor EAX,EAX

mov [GS:ESI+16],EAX

mov [GS:ESI+20],EAX

mov [GS:ESI+24],EAX

mov [GS:ESI+28],EAX

jmp short @@Start

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

; как конечный

@@NoShortBlock:

sub ESI,32

mov [dword ptr GS:ESI],1b ;последний TD

@@Start:

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

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

mov EAX,[Addr_TD_Array]

mov ESI,[Addr_QH]

add ESI,4

mov [GS:ESI],EAX

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

@@Wait_OpComplete:

cmp [dword ptr GS:ESI],1b

jne @@Wait_OpComplete

mov [BULK_DataSize],0

popad

ret

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

@@TD_Array_Error:

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

mov DX,[USB_BaseAddr]

mov AX,0

out DX,AX

MFatalError DsErr

ENDP BulkOUT_Transaction

;*****************************

;* ВЫВЕСТИ СИМВОЛ НА ПРИНТЕР *

;* Параметры: *

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

;*****************************

PROC OutCharToPrn near

push BX

cmp [BULK_DataSize],4096

jae @@Data_Buffer_Full

mov BX,offset DataBuffer

add BX,[BULK_DataSize]

mov [BX],AL

inc [BULK_DataSize]

pop BX

ret

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

@@Data_Buffer_Full:

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

mov DX,[USB_BaseAddr]

mov AX,0

out DX,AX

MFatalError BfErr

ENDP OutCharToPrn

;******************************************

;* ПОСЛАТЬ КОМАНДУ НА ПРИНТЕР *

;* Параметры: *

;* DS:SI - указатель на строку команды. *

;* Первый байт строки содержит количество *

;* байтов команды, посылаемых на принтер. *

;******************************************

PROC OutCommandToPrn near

pusha

cld

; Загрузить счетчик байтов команды в CX

lodsb

xor CX,CX

mov CL,AL

@@OutNextByte:

lodsb

call OutCharToPrn

loop @@OutNextByte

popa

ret

ENDP OutCommandToPrn

;*************************************************

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

;*************************************************

PROC Show_Ident 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

loop @@NextByte

popa

ret

ENDP Show_Ident

ENDS

; Подключить процедуры ввода данных и вывода на экран

; в текстовом режиме

include "list1_02.inc"

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

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

include "list2_01.inc"

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

include "list8_01.inc"

END

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]