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

Программа DISKINFO


Для иллюстрации описанных выше приемов определения конфигурации дисковой системы компьютера приведем исходные тексты программы DISKINFO (листинг 1.1). Она определяет конфигурацию дисковой подсистемы и отображает основные характеристики используемых дисководов. Программа DISKINFO обращается к таблицам параметров НГМД и НМД.

В процессе своей работы программа вызывает функцию disk_cfg, которая заполняет поля структуры DISK_CONFIG сведениями о конфигурации дисковой системы:



Имя поля Описание
n_floppy Количество НГМД, установленных в системе
n_hard Количество НМД, установленных в системе
t_floppy1 Тип первого НГМД
t_floppy2 Тип второго НГМД
t_hard1 Тип первого НМД
t_hard2 Тип второго НМД

Листинг 1.1. Файл diskinfo\diskinfo.cpp

#include <stdio.h> #include <dos.h>

typedef struct _DISK_CONFIG_ { int n_floppy; int n_hard; int t_floppy1; int t_floppy2; int t_hard1; int t_hard2; } DISK_CONFIG;

typedef struct _DPT _ { unsigned char srt_hut; unsigned char dma_hlt; unsigned char motor_w; unsigned char sec_size; unsigned char eot; unsigned char gap_rw; unsigned char dtl; unsigned char gap_f; unsigned char fill_char; unsigned char hst; unsigned char mot_start; } DPT ;

typedef struct _HDPT _ { unsigned max_cyl; unsigned char max_head; unsigned srwcc; unsigned swpc; unsigned char max_ecc; unsigned char dstopt; unsigned char st_del; unsigned char fm_del; unsigned char chk_del; char reserve[4]; } HDPT ;

void disk_cfg(DISK_CONFIG* cfg); DPT far *get_dpt(void); HDPT far *get_hdp1(void); HDPT far *get_hdp2(void);

void main(void) { DISK_CONFIG cfg; DPT far *dpt_ptr; HDPT far *hdpt1_ptr; HDPT far *hdpt2_ptr;

printf("\n" "\nКонфигурация дисковой подсистемы" "\n (C)Фролов А., 1995\n");

// Определяем конфигурацию дисковой подсистемы disk_cfg(&cfg);

printf("\nУстановлено:" "\n НГМД: %d" "\n НМД: %d", cfg.n_floppy, cfg.n_hard);

printf("\nТип НГМД: A: - %d, B: - %d" "\nТип НМД: C: - %d, D: - %d", cfg.t_floppy1, cfg.t_floppy2, cfg.t_hard1, cfg.t_hard2);


// Получаем адрес таблицы параметров дискеты dpt_ptr = get_dpt();

printf("\n" "\nКод размера сектора дискеты: %d" "\nЗаполняющий символ для форматирования: %2.2X", dpt_ptr->sec_size, dpt_ptr->fill_char);

// Получаем адреса первой и второй таблицы // параметров жесткого диска hdpt1_ptr = get_hdp1(); hdpt2_ptr = get_hdp2();

printf("\n" "\nПараметры первого НМД:" "\n Количество дорожек: %d" "\n Количество головок: %d" "\n" "\nПараметры второго диска:" "\n Количество дорожек: %d" "\n Количество головок: %d", hdpt1_ptr->max_cyl, hdpt1_ptr->max_head, hdpt2_ptr->max_cyl, hdpt2_ptr->max_head); }

/** * disk_cfg * * Определить конфигурацию дисковой подсистемы * * Функция заполняет структуру, описывающую * конфигурацию дисковой подсистемы: * * typedef struct _DISK_CONFIG_ * { * int n_floppy; * int n_hard; * int t_floppy1; * int t_floppy2; * int t_hard1; * int t_hard2; * } DISK_CONFIG; * **/

void disk_cfg(DISK_CONFIG* cfg) { char unsigned far *modptr; char unsigned pc_type; char cfg_byte; int cfg_word;

union REGS inregs, outregs;

// Определяем тип компьютера modptr = (char unsigned far*)MK_FP(0xf000, 0xfffe); pc_type = *modptr;

// В зависимости от типа компьютера выбираем // способ определения конфигурации дисковой // подсистемы switch (pc_type) { case 0xfc:

// Для IBM AT считываем конфигурацию дисковой // подсистемы из CMOS-памяти

// Считываем байт конфигурации outp(0x70, 0x14); cfg_byte = inp(0x71);

// Определяем количество установленных НГМД if((cfg_byte & 1) == 0) { // Если младший бит байта конфигурации равен 0, // НГМД отсутствуют cfg->n_floppy = 0; cfg->t_floppy1 = 0; cfg->t_floppy2 = 0; } else { // Определяем количество установленных НГМД cfg->n_floppy = ((cfg_byte >> 6) & 3) + 1;

// Определяем типы НГМД outp(0x70, 0x10); cfg_byte = inp(0x71);

cfg->t_floppy2 = cfg_byte & 0xf; cfg->t_floppy1 = (cfg_byte >> 4) & 0xf; }



// Определяем конфигурацию НМД outp(0x70, 0x12); cfg_byte = inp(0x71);

if(cfg_byte == 0) { // Если обе тетрады равны нулю, система // не содержит НМД cfg->n_hard = 0; cfg->t_hard1 = 0; cfg->t_hard2 = 0; } else { // Определяем тип первого диска - диска C: if((cfg_byte & 0xf) != 0xf) cfg->t_hard1 = cfg_byte & 0xf; else { outp(0x70, 0x19); cfg->t_hard1 = inp(0x71); }

// Определяем тип второго диска - диска D: if((cfg_byte & 0xf0) != 0xf0) cfg->t_hard2 = (cfg_byte >> 4) & 0xf; else { outp(0x70, 0x1a); cfg->t_hard2 = inp(0x71); } }

// Вычисляем количество НМД, установленных // в системе cfg->n_hard = 0; if(cfg->t_hard1 != 0) cfg->n_hard++; if(cfg->t_hard2 != 0) cfg->n_hard++;

// Для некоторых совместимых с IBM AT машин невозможно // определить тип диска, так как в CMOS-памяти для // типа диска установлено значение 0, несмотря на то, // что диск имеется. В таких случаях можно определить // наличие жесткого диска, используя слово // конфигурации, возвращаемое прерыванием INT 11h.

if(cfg->n_hard == 0) { int86(0x11, &inregs, &outregs); cfg_word = outregs.x.ax;

// Проверяем, есть ли НМД if((cfg_word & 1) != 0) { cfg->n_hard = 1;

// Считаем, что тип используемого жесткого // диска неопределен cfg->t_hard1 = 0; cfg->t_hard2 = 0; } } break;

default:

// Для остальных типов компьютеров вызываем // прерывание INT 11h, используем возвращаемый // этим прерыванием байт конфигурации int86(0x11, &inregs, &outregs); cfg_word = outregs.x.ax;

// Определяем количество установленных // НГМД cfg->n_floppy = ((cfg_word >> 6) & 3) + 1;

// Считаем, что тип используемого НГМД // неопределен cfg->t_floppy1 = 0; cfg->t_floppy2 = 0;

// Определяем наличие НМД if((cfg_word & 1) != 0) { cfg->n_hard = 1;

// Считаем, что тип используемого НМД // неопределен cfg->t_hard1 = 0; cfg->t_hard2 = 0; } break; } }

/** * get_dpt * * Вычислить адрес таблицы параметров дискеты * * Функция возвращает указатель на таблицу * параметров дискеты * **/

DPT far *get_dpt(void) { void far * far *ptr;

ptr = (void far * far *)MK_FP(0x0, 0x78); return(DPT far*)(*ptr); }

/** * get_hdp1 * * Вычислить адрес первой таблицы параметров диска * * Функция возвращает указатель на первую таблицу * параметров диска * **/

HDPT far *get_hdp1(void) { void far * far *ptr;

ptr = (void far * far *)MK_FP(0x0, 0x104); return(HDPT far*)(*ptr); }

/** * get_hdp2 * * Вычислить адрес второй таблицы параметров диска * * Функция возвращает указатель на вторую таблицу * параметров диска * **/

HDPT far *get_hdp2(void) { void far * far *ptr;

ptr = (void far * far *)MK_FP(0x0, 0x118); return(HDPT far*)(*ptr); }


Содержание раздела