На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 7 / Листинг 7-7. EMMEXIST.C Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Листинг 7-7. EMMEXIST.C

                    Листинг 7-7. EMMEXIST.C
        ------------------------------------------------------------------
        #include 
        #include 
        #include 
        #include 
        #include "emmconst"

        #define DOS_INT           0x21     /*диспетчер функций DOS*/
        #define DOS_IOCTL         0x44     /*функция IOCTL DOS*/
        #define IOCTL_GETINFO     0x00     /*подфункция "Получить информа-
                                                 цию об устройстве" IOCTL*/
        #define IOCTL_OUTSTAT     0x07     /*подфункция "Получить состояние
                                                        вывода" IOCTL*/
        #define READY_OUTPUT      0xFF     /*устройство готово к выводу*/
        #define IS_DEVICE         0x0080   /*обработчик принадлежит устрой-
                                                                    ству*/
        static char device_name[9] = EMM_DEVICE;

             /*
             Контролируется наличие расширенной памяти с помощью метода
             "открытого обработчика". Устанавливает emm_present в '1',
             если расширенная память присутствует, в '0' - если нет.
             Функция возвращает '0', если тест наличия завершился успеш-
             но. В противном случае возвращается код ошибки DOS вызова
             функции DOS, которая не выполнилась во время теста наличия
             расширенной памяти.
             */

        emm_exists(emm_present)
        int *emm_present;               /*указатель на индикатор наличия
                                             менеджера расширенной памяти*/
        {
             int return_code;            /*код возврата операции с файлом*/
             int handle;                 /*обработчик файлов*/
             unsigned int dev_attr;       /*атрибуты драйвера устройства*/
             unsigned int dev_status;     /*выходное состояние устройства*/

             if (_dos_open(device_name, O_RDONLY, &handle))  {
                                                /*не удалось открыть файл*/
                if (errno == ENOENT)  {              /*файл не существует*/
                   return_code = 0;             /*мы ожидали, что это могло
                                                               случиться*/
                   *emm_present = 0;          /*менеджер расширенной памяти
                                                  определенно отсутствует*/
                } else
                   return_code = errno;       /*тест наличия завершился
                                                               безуспешно*/
             } else
                if (!(return_code = ioctl_getattr(handle, &dev_attr))) {
                                                       /*получен атрибут*/
                   if (!(return_code = ioctl_outstat(handle, &dev_status)))
                                            /*получено выходное состояние*/
                                  /*менеджер расширенной памяти присутству-
                                    ет, если обработчик принадлежит устрой-
                                             ству и готов к выводу*/
                *emm_present = ((dev_status == READY_OUTPUT) && (dev_attr
                                           & IS_DEVICE)) ? 1 : 0;
                close(handle);             /*закрывается обработчик файла*/
             }
             return(return_code);
        }

             /*
             Получается слово атрибутов DOS для открытого обpаботчика,
             связанного с открытым файлом или устройством. Возвращает 0,
             если функция завершилась успешно, в противном случае воз-
             вращает код ошибки DOS
             */

        ioctl_getattr(handle, attrib)
        int handle;                /*открытый обpаботчик файла/устройства*/
        unsigned int *attrib; /* -> возвращенная информация об устройстве*/
        {
             int rc;
             union REGS regs;
             regs.h.ah = DOS_IOCTL;  /*управление вводом/выводом  DOS  для
                                                                устройств*/
             regs.h.al = IOCTL_GETINFO;  /*получить информацию об устройс-
                                                                     тве*/
             regs.x.bx = handle;
             int86(DOS_INT, ®s, ®s);            /*вызов функции DOS*/
             if (!regs.x.cflag)  {             /*если не произошло ошибки*/
                *attrib = regs.x.dx;               /*возвращаются атрибуты
                                                         файла/устройства*/
                rc = 0;                     /*функция выполнилась успешно*/
             } else
                rc = regs.x.ax;             /*возвращается код ошибки*/
             return(rc);
        }

             /*
             Получает выходное состояние файла или устройства. Возвра-
             щенное состояние 0 означает, что устройство неготово для
             вывода; состояние 0xFF00 означает, что устройство готово
             для вывода. Возвращается 0, если функция завершилась ус-
             пешно. В противном случае возвращается код ошибки DOS.
             */

        ioctl_outstat(handle, status)
        int handle;                /*открытый обpаботчик файла/устройства*/
        unsigned int *status;                /* -> слово состояния вывода*/
        {
             int rc;
             union REGS regs;
             regs.h.ah = DOS_IOCTL;  /*управление вводом/выводом  DOS  для
                                                                устройств*/
             regs.h.al = IOCTL_OUTSTAT;       /*получить состояние вывода*/
             regs.x.bx = handle;
             int86(DOS_INT, ®s, ®s);            /*вызов функции DOS*/
             if (!regs.x.cflag)  {             /*если не произошло ошибки*/
                *status = regs.h.al;               /*возвращается состояние
                                                                   вывода*/
                rc = 0;                     /*функция выполнилась успешно*/
             } else
                rc = regs.x.ax;             /*возвращается код ошибки*/
             return(rc);
        }

             /*
             Проверяет наличие pасшиpенной памяти с помощью метода
             "получить вектор". Устанавливает emm_present в '1', если
             расширенная память присутствует, '0' - если нет. Данная
             функция всегда возвращает '0'.
             */

        emm_exists2(emm_present)
        int *emm_present;
        {
             int len;
             char far *device_name;        /*указатель на имя символьного
                                                               устройства*/
             char *np;
             unsigned int get_int_seg();

             FP_SEG(dev_name) = get_int_seg(EMM_INT);   /*сегмент драйвера
                                  устройства менеджеpа pасшиpенной памяти*/

             FP_OFF(dev_name) = 10;      /*смещение имени драйвера символь-
                                                          ного устройства*/

             /*увидеть, находится ли имя менеджеpа pасшиpенной памяти
                       по смещению 10 в сегменте EMM_INT*/

             for (len  = 8, np = device_name; len && *dev_name++ == *np++;
                                                               len--);

             *emm_present = (len) ? 0 : 1;       /*если все символы совпа-
                              ли менеджеp pасшиpенной памяти присутствует*/
             return(0);                      /*всегда завершается успешно*/
        }

             /*
             Возвращает адрес сегмента вектора прерываний "intno"
             */

        unsigned int get_int_seg(intno)
        int intno;
        {
             union REGS regs;
             struct SREGS segregs;

             regs.h.al = (unsigned char) intno;
             regs.h.ah = 0x35;            /*функция "Получить вектор" DOS*/
             intdosx(®s, ®s, &segregs);
             return((unsigned) segregs.es);
        }
        -------------------------------------------------------------------

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz