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

MS-DOS для программиста

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

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

6.6. Драйвер системных часов CLOCK$

Операционная система содержит в своем составе драйвер системных часов. Это драйвер символьного устройства, имя устройства - CLOCK$.

Символ "$" используется для того, чтобы это имя не конфликтовало с именем файла clock. Дело в том, что пользователь может создать файл с именем clock, но с именем clock$ - едва ли (разве лишь он пожелает закодировать в этом имени фразу "время - деньги").

Характерный признак драйвера системных часов - бит 3 слова атрибутов устройства установлен в 1. Именно этот признак используется MS-DOS для обнаружения драйвера часов.

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

Смещение Длина Назначение
0 2 Количество дней, прошедших после 1 января 1980 года
2 1 Счетчик минут
3 1 Счетчик часов
4 1 Счетчик сотых долей секунды
5 1 Счетчик секунд

Приведем исходный текст программы gettime (листинг 6.1). Эта программа открывает устройство CLOCK$ , задает двоичный режим обмена данных и вводит 6 байт, имеющих только что описанную структуру. Определенные таким способом показания часов выводятся на экран.


Листинг 6.1. Файл gettime\gettime.cpp


#include <io.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno .h>
#include <dos.h>

union REGS  inregs, outregs;
struct SREGS  segregs;

int main(void)
{
  int io_handle;

  struct
  {
    unsigned days;
    unsigned char min;
    unsigned char hours;
    unsigned char sec_per_100;
    unsigned char sec;
  } clock_buf;

  // Открываем устройство с именем CLOCK$ 
  if((io_handle = open("CLOCK$ ", O_RDWR)) == - 1)
  {
    // Если открыть устройство не удалось, выводим
    // код ошибки
    printf("Open: ошибка %d", errno );
    return errno ;
  }

  // Определяем конфигурацию устройства
  inregs.h.ah = 0x44;
  inregs.h.al = 0;
  inregs.x.bx = io_handle;
  intdos (&inregs, &outregs);

  if(outregs.x.cflag == 1)
  {
    // При возникновении ошибки выводим ее код
    printf("IOCTL : ошибка %x\n", &outregs.x.ax);
    return(-1);
  }

  // Устанавливаем бит 5 (переключаем драйвер
  // в двоичный режим обмена данными)
  inregs.x.dx = (outregs.x.dx | 0x0020) & 0x00ff;

  // Устанавливаем слово конфигурации устройства
  inregs.h.ah = 0x44;
  inregs.h.al = 1;
  inregs.x.bx = io_handle;
  intdos ( &inregs, &outregs );

  if(outregs.x.cflag == 1)
  {
    // При возникновении ошибки выводим ее код
    printf("IOCTL : ошибка %x\n", &outregs.x.ax);
    return(-1);
  }

  // Выводим слово конфигурации устройства
  printf("\nКонфигурация устройства:  %04X\n",
     outregs.x.dx);

  // Читаем 6 байт из устройства в буфер buf
  // Обмен выполняется в двоичном режиме
  if(read(io_handle, &clock_buf, 6) == -1)
  {
    // Если при чтении произошла ошибка,
    // выводим ее код
    printf("Read: ошибка %d",errno );
    return errno ;
  }

  printf("\nПолучено от драйвера часов CLOCK$ :"
   "\n"
   "\nПрошло дней после 01.01.80:  %d"
   "\nМинуты:                      %d"
   "\nЧасы:                        %d"
   "\nСекунды:                     %d"
   "\nСотые доли секунды:          %d"
   "\n",
   clock_buf.days, clock_buf.min, clock_buf.hours,
   clock_buf.sec,  clock_buf.sec_per_100);

   // Закрываем устройство
   close(io_handle);

   return(0);
}

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