Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Описание алгоритма программы. Текст программы. Текст программы



Алгоритм основной программы может быть разбито на 5 частей.

Часть 1 предназначена для определения типа компьютера. Для этого прочитаем байт, записанный в ПЗУ BIOS по адресу FF00:0FFE. В зависимости от значения этого байта сделаем вывод о типе ПЭВМ. Так, например, компьютеру типа АТ соответствует код OxFC.

Часть 2 предназначена для определения конфигурации ПЭВМ. Для этого прочитаем из области данных BIOS список оборудования. Для определения количества дисководов (если бит 0 установлен в 1) необходимо выделить биты 6 и 7 (маска 00С0h) и сместить их вправо на 6 разрядов, а потом добавить 1.

Для определения количества 16- Кбайтных блоков ОЗУ на системной плате необходимо выделить биты 2 и 3 с помощью маски 00С0h, сместить вправо на 2 разряды и добавить 1.

Для определения количества последовательных портов RS-232 выделить с помощью маски 0Еh биты 9-11 и сместить вправо на 9 разрядов.

Для определения наличия математического сопроцессора - проверить установку бита 1 маской 0002h.

Для определения наличия джойстика - бита 12 с помощью маски 1000h.

Определить количество параллельных принтеров можно, выделив биты 14 и 15 маской С000h и сместив их вправо на 14 разрядов.

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

Видеоадаптер обслуживается прерыванием BIOS 10h. Для новых типов адаптеров список его функций расширяется. Эти новые функции и используются для определения типу адаптера.

Функция lАh доступна только при наличии расширения BIOS, ориентированного на обслуживание VGA. В этом случае функция возвращает в регистре AL код lАh - свою «визитную карточку», а в BL - код активного видеоадаптера. В случае, если функция lАh поддерживается, обратимся еще к функции lВh - последняя заполняет 70-байтныйблок информации про состояние, из которого мы выбираемо объем видеопамяти.

Если lАh не поддерживается, это означает, что VGA у нас нет, в этом случае можно обратиться к функции 12h - получение информации про EGA. При наличии расширения, ориентированного на EGA, эта функция изменяет содержимое BL (перед обращением он должен быть 10h) на 0 (цветной режим) или на 1 (монохромный режим) а в ВН возвращает объем видеопамяти.

Если же ни lАh, ни 12 не поддерживаются, то список оборудования BIOS содержит достаточную информацию про видеоадаптер и, выделивши биты 4, 5 мы можем сделать окончательный вывод про тип адаптера, который у нас есть.

В третьей части программы определим объем оперативной памяти, наличие и объем еxtеndеd-памяти. Объем оперативной памяти для АТ может быть прочитан из регистров 15h (младший байт) и 16h (старший байт) СМОS-памяти или из области памяти BIOS по адресу 0040:0013 (2-байтное слово). Кроме того, в ПЭВМ может быть еще и дополнительная (expanded) память свыше 1 Мбайту. Ее объем можно получит из регистров 17h (младший байт) и 18h (старший байт) СМОS-памяти. Для чтения регистра СМОS-памяти необходимо видать в порт 70h байт номера регистра, а потом из порта 71h прочитать байт содержимого этого регистра.

В следующей части программы определим наличие и объем дополнительных ПЗУ. В адресному пространстве от C000:0000 по F600:0000 размещаются расширения ПЗУ (эта память не обязательно присутствует в ПЭВМ). для определения наличия дополнительного ПЗУ будем читать первое слово из каждых 2 Кбайт, начиная с адреса C000:0000 в поисках маркера расширения ПЗУ: 55ААh. Если такой маркер найден, то следующий байт содержит длину модуля ПЗУ.

В заключительной части программы определим версию DOS, установленную на ПЭВМ. Для этого воспользуемся функцией DOS 30h, которая возвращает в регистре AL старшее число номера версии, а в регистре АН - младшее число.

 



Текст программы

/ **************"Проверка состава оборудования"********** /

/* Подключение стандартных заголовков */

#include <dos.h>

#include <conio.h>

#include <stdio.h>

/*------------------------------------------------------------------- */

void main()

{

unsigned char type_PC, /* Тип компьютера */

а,b; /* Переменные для определения характеристик памяти ПЭВМ */

unsigned int konf_b; /* Байт конфигурации из BIOS */

char *type[]={"AT", "PCj r", "ХТ", "IBM РС", "unknown"};

unsigned char typ1A[]={0, 1,2,4,5,6,7,8, 10, 11, 12,Oxff};

char *types1A[]={"нет дисплея","МDА, MOHO","CGA, цв.",

"EGA, ЦВ.","ЕGА, MOHO","PGA, цв.",

"VGA, моно, анал.", "VGA, кол., анал.",

"MCGA, кол., цифр.", "MCGA, моно, анал."

"MCGA, кол., анал.", "неизвестный тип",

"непредусмотренный код"};

unsigned int j; /* Вспомогательная переменная */

unsigned int seg;    /* Сегмент ПЗУ */

unsigned int mark=0xAA55; /* Маркер ПЗУ */

unsigned char bufVGA[64]; /* Буфер данных VGA */

union REGS rr;

struct SREGS sr;

textbackground(0);

clrscr();

textattr(0x0a);

срrintf (" Лабораторная работа ");

cprintf( "\nПроверка состава оборудования");

/* Определения типа компьютера */

type_PC=peekb(0xF000,0xFFFE);

if( (type_PC-=0хFС)>4)

type_PC=4;

textattr(0x0b) ;

срrintf("\nТип компьютера: ");

textattr(0x0f);

cprintf("%s\n\r",type[type_PC]);

/* Конфигурация*/

konf_b=peek(0x40,0x10); /* Чтение байта оборудования из памяти BIOS */

textattr(0x0b);

cprintf( "Конфигурация :\n\r");

/* Количество дисководов */

textattr (0х0е ) ;

cprintf(" Дисководов ГМД:                       ");

textattr(0x0f);

if(konf_b&0x0001)

cprintf( "%d\n\r" , (( konf _b&0х000C0 )>>6 )+1);

else

cprintf( "нет\n\r");

textattr ( 0х0е);

cprintf(" Математич. сопроцессор: ");

textattr (0x0f) ;

if(konf_b&0x0002)

cprintf( "есть\n\r");

else

cprintf( "нет\n\r");

textattr (0х0е) ;

cprintf(" Тип дисплейного адаптера: ");

textattr(0x0f);

/* Определение активного адаптера */

/* Предположим наличие VGA */

rr.h.ah=0x1a;

rr.h.al=0;

int86(0x10,&rr,&rr);

if(rr.h.al= =0x1a) /* Поддерживается функция 1Ah прерывания 10h * /

for(j=0;j<12;j++)

if(rr.h.bl= =typ1A[j])

break;

cprintf( "%s", types1A[j]);

if(j>O && j<12)

{

rr.h.ah=0x1b;

гг.х.bх=0;

sr.es=FP_SEG(bufVGA);

rr.x.di=FP_OFF(bufVGA);

int86x(0x10,&rr,&rr,&sr);

cprintf(", %d Кбайт\n\r", ((int)bufVGA[49]+1)*64);

}

else

cprintf("\n\r");

}

else

{

/* Предположим наличие EGA */

rr.h.ah=0x12;

rr.h.bl=0x10;

int86(0x10,&rr,&rr);

if(rr.h.bl!=0x10) /* Поддерживается функция 12h прерывания 10h */

{

cprintf( "EGA");

if(rr.h.bh)

cprintf(" моно");

else

cprintf(" кол. ");

cprintfc(", %d Кбайт\n\r" , ((int)rr.h.bl+1)*64);

}

else

{

/* CGA или MDA */

switсh(kопf_b&0х0030)

{

case 0: cprintf( "EGA/VGA\n\r"); break;

case 0х10: cprintf("CGA, 40\n\r"); break;

case 0х20: cprintf("CGA, 80\n\r"); break;

case 0х30: cprintf( "MDA"); break;

}

}

}

/* Блоки ОЗУ на системной плате */

textattr(0x0e) ;

cprintf("\n\r Первичный блок памяти: ");

textattr(0x0f);

switch (konf_b&0x000C)

{

case 0 : cprintf("16 Кбайт\n\r"); break;

case 4:срrintf("З2 Кбайт\n\r");brеаk;

case 8:cprintf("48 Кбайт\n\r"); break;

case 12: cprintf( "64 Кбайт или больше\n\r"); break;

/* Количество последовательных портов RS-232 */

textattr (0х0е);

cprintf(" Портов RS2З2:      ");

textattr(0x0f);

cprintf( "%d\n\r", (konf _b&0х0Е00)>>9);

/* Наличие джойстика */

textattr(0x0e);

cprintf(" Джойстик: ") ;

 textattr (0x0f);

if(konf_b&0x1000 )

cprintf( "есть \n\r");

else

cprintf( "нет\n\r");

/* Количество параллельных принтеров */

textattr (0х0е);

cprintf(" Принтеров: ");

textattr(0x0f) ;

cprintf( "%d\n\n\r", (konf _b&0хС000)>>14);

/* Объем оперативной памяти */

textattr( 0х0е);

сргintf("Объем оперативной памяти: ");

textattr(0x0f) ;

cprintf("%d Кбайт\n\r", peek(0x40, 0х1З));

textattr (0х0е);

/* Наличие и объем ехtеndеd-памяти */

outportb(0x70,0x17);

a=inport(0x71) ;

outportb(0x70,0x18);

b=inport(0x71);

cprintf( "Объем ехtеndеd-памяти: ");

textattr(0x0f) ;

cprintf("%6d Кбайт\n\n\r", (b<<8) |a);

/* Наличие дополнительных ПЗУ */

for( seg=0xC000;seg<0xFFB0;seg+=0x40)

/* Просмотр памяти от C000:0 с шагом 2 К */

if(peek(seg,0)= =mark) /* Маркер найден */

{

textattr( 0х0а);

cprintf( "Адрес ПЗУ =");

textattr( 0x0f);

cprintf(" %04x",seg);

textattr(0x0a) ;

cprintf(" Длина модуля = ");

textattr(0x0f) ;

cprintf ("%d", 512*peekb(seg, 2));

textattr (0х0а) ;

cprintf(" байт\n\r",рееkb(sеg,2));

}

/* Определение версии операционной системы */

rr.h.ah=0x30;

intdos(&rr,&rr);

textatt r (0х0с) ;

cprintf ("\n\rВерсия MS-DOS ");

textatt r (0x0f);

cprintf("'%d. %d\n\r", rr. h. а1, rr. h. ah);

textatt r (0х0а ) ;

gоtоху(30, 24);

cprintf ("'Нажмите любую клавишу");

textattr(0x07) ;

getch();

c1rscr();

}

 


Поделиться:



Последнее изменение этой страницы: 2019-05-08; Просмотров: 191; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.047 с.)
Главная | Случайная страница | Обратная связь