Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Аппаратное обеспечение персонального компьютера

© Александр Фролов, Григорий Фролов
Том 33, М.: Диалог-МИФИ, 1997, 304 стр.

[Назад] [Содеожание] [Дальше]

Функции BIOS для работы с принтером

В BIOS есть ряд функций, предназначенных для работы с принтером, подключенным через параллельный адаптер. Это функции 00h, 01h, 02h прерывания INT 17h.

Печать символа

Функция 00h предназначена для печати одного символа:

Регистры на входе:

AH = 00h;

AL = код ASCII символа, который нужно напечатать;

DX = номер параллельного адаптера: 0 – LPT1, 1 – LPT2, 2 – LPT3

Регистры на выходе:

AH = слово состояния принтера

Эта функция выводит на принтер один символ, заданный в регистре AL. В регистре DX необходимо записать номер используемого параллельного адаптера. Для адаптера LPT1 это 0, для LPT2 - 1 и так далее.

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

Поле

Описание

0

Истекло время ожидания при выполнении операции печати, возможно, что принтер неисправен

1-2

Не используются

3

Ошибка ввода/вывода

4

1 - принтер выбран для работы;

0 - принтер находится в состоянии offline

5

Конец бумаги

6

Подтверждение

7

1 - принтер готов к работе;

0 - принтер занят

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

Если принтер неисправен, программа должна предоставить пользователю возможность отменить печать.

Обратите внимание на бит 1 байта состояния. Если принтер находится в состоянии offline, функция 00h прерывания INT 17h ожидает некоторое время готовности принтера, после чего, если принтер так и не перешел в состояние готовности, устанавливает бит 1 в байте состояния. Область данных BIOS по адресу 0000h:0478h содержит четыре байта, которые используются в качестве счетчика времени при ожидании готовности принтера.

Инициализация принтера

Функция 01h инициализирует принтер:

Регистры на входе:

AH = 01h;

DX = номер параллельного адаптера: 0 – LPT1, 1 – LPT2, 2 – LPT3

Регистры на выходе:

AH = слово состояния принтера

Эта функция выполняет аппаратный сброс принтера. Если вы загрузили в принтер какой-либо шрифт (например, с символами кириллицы), после сброса загрузку шрифта придется выполнять заново. Поэтому не следует выполнять без необходимости сброс принтера. Обычно принтер приходится сбрасывать либо перед настройкой его на заданный режим работы, которая выполняется один раз, либо при изменении этого режима.

Определение состояния принтера

Слово состояния принтера может быть получено с помощью функции 02h:

Регистры на входе:

AH = 02h;

DX = номер параллельного адаптера: 0 – LPT1, 1 – LPT2, 2 – LPT3

Регистры на выходе:

AH = слово состояния принтера

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

Программа PRINTFL

Приведем исходный текст программы PRINTFL, которая распечатывает содержимое файла с использованием функции 0 прерывания INT 17h (листинг 7.1).

Листинг 7.1. Файл printfl\printfl.с


// =====================================================
// Печать на принтере с помощью функций BIOS
//
// (C) Фролов А.В, 1997
//
// E-mail: frolov@glas.apc.org
// WWW:    http://www.glasnet.ru/~frolov
//            или
//         http://www.dials.ccas.ru/frolov
// =====================================================
#include <dos.h>
#include <stdio.h>
#include <conio.h>

union REGS rg;
int printchar(int chr);
int error(char chr, int status);

int main(int argc, char *argv[]) 
{
  FILE *srcfile;

  // Открываем файл, заданный первым параметром
  // в командной строке.
  // Если при запуске программы оператор забыл
  // указать имя файла, выводим напоминающее сообщение
  if( (srcfile = fopen( argv[1], "rb" )) == NULL ) 
  {
    printf("\nЗадайте имя файла в качестве параметра");
    return (-1);
  }

  // Читаем файл по одному символу, полученный из файла
  // символ выводим на принтер при помощи функции printchar
  for(;;) 
  {
    printchar(fgetc(srcfile));
    if(feof(srcfile)) 
      break;
  }

  // Закрываем файл
  fclose(srcfile);
  
  return 0;
}

// ------------------------------------
// Эта функция выводит один символ
// на первый принтер (LPT1)
// ------------------------------------
int printchar(int chr) 
{
  int status;

  // Повторяем в цикле выдачу символа на принтер
  // до тех пор, пока он не будет выведен без
  // ошибок, либо пока оператор не отменит
  // распечатку файла
  for(;;) 
  {
    // Дублируем распечатываемый символ на экране
    putch(chr);

    // Вызываем функцию 00h прерывания INT 17h -
    // распечатка символа на принтере.
    // В регистре DX задаем номер принтера LPT1 - это 0
    rg.h.ah = 0;
    rg.h.al = chr;
    rg.x.dx = 0;

    int86(0x17, &rg, &rg);

    // Запоминаем байт состояния принтера
    // после вывода символа
    status = rg.h.ah;

    // Проверяем наличие ошибок. Нас интересуют биты:
    //
    //    0 - задержка при печати
    //    3 - ошибка ввода/вывода
    //    4 - принтер в состоянии ONLINE (1) или OFFLINE (0)
    //    5 - конец бумаги
    if((status & 0x39) != 0x10) 
    {
      // Вызываем функцию обработки ошибки error(). Эта
      // функция возвращает 0, если оператор желает
      // повторить печать символа, или 1 - если
      // оператор отменяет печать
      if(error(chr, status)) 
      {
        printf("\nПечать завершилась аварийно");
        return -1;
      }
    }
    else 
      break;
  }
}

// ------------------------------------
// Функция выводит на экран состояние
// принтера и запрашивает у оператора
// требуемые действия - повторить
// печать символа или отменить печать
// ------------------------------------
int error(char chr, int status) 
{
  // Выводим состояние принтера после ошибки
  printf("\nОшибка принтера %02.2X"
       "\n\nСостояние принтера:"
       "\n-------------------", status);

  if(status & 1)
    printf("\nТаймаут при печати");

  if(status & 8)
    printf("\nОшибка ввода/вывода");

  if(!(status & 0x10))
    printf("\nПринтер находится в состоянии OFFLINE");

  if(status & 0x20)
    printf("\nКонец бумаги");

  printf("\n\nДля отмены печати нажмите клавишу ESC,"
    "\nдля повтора - любую другую клавишу\n");

  if(getch() == 27) 
    return 1;
  else 
    return 0;
}

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

После вызова прерывания INT 17h функция printchar проверяет состояние принтера. При возникновении ошибки ввода/вывода вызывается обработчик - функция error. Эта функция выводит на экран состояние принтера (в развернутом виде с объяснением каждого бита в байте состояния), а также запрашивает пользователя о дальнейших действиях.

Если пользователь может устранить причину ошибки (перевести принтер в состояние online, вставить бумагу, если она кончилась и так далее), он нажимает любую клавишу, кроме <Esc>. В этом случае функция error возвращает 0. Иначе возвращается значение 1.

Если пользователь решил повторить печать, и, соответственно, если функция error возвратила значение 0, функция printchar повторяет печать символа. При отмене печати выдается сообщение об ошибке и работа программы завершается.

[Назад] [Содеожание] [Дальше]