#include #include #include #include // Отключаем Word Aligment #pragma option -a- // Информация о VBE и видеоадаптере typedef struct { char cSignature[4]; unsigned short usVersion; char far *fpInfoOEM; unsigned char ucCapabilities[4]; unsigned short far *fpModeTable; // Поддерживается VBE v1.2 unsigned short usTotalMemory, // Поддерживается VBE версии 2.0 usRevVersion; char far *fpOEMName, *fpOEMProductName, *fpOEMRevVersion; char cReserv[222], cOEMData[256]; } VESAINFO; // Характеристика режима видеоадаптера typedef struct { unsigned short usModeAttr; unsigned char ucWinAAttr, ucWinBAttr; unsigned short usWinGranularity, usWinSize, usBegSegA, usBegSegB; void far *fpWinFunc; unsigned short usBytesPerScanLine, // Поддерживается VBE v1.2 usSizeX, usSizeY; unsigned char ucCharSizeX, ucCharSizeY, ucNumPlanes, ucNumPixelBits, ucBanksNum, ucTypeMemModel, ucBankSize, ucPageNum, ucReserv1, ucRedSize, ucRedField, ucGreenSize, ucGreenField, ucBlueSize, ucBlueField, ucResSize, ucResField, ucDACInfo; // Поддерживается VBE v2.0 unsigned char far *VideoBuff, *ScrOffset; unsigned short usScrSize; unsigned char ucReserv2[206]; } VESAMODEINFO; int GetBaseVESAInfo(FILE *); int AnalyseResult(REGS); // Главная функция int main(int argc, char *argv[]) { FILE *fileVesaReport; int iResult; // Проверка командной строки программы if( argc != 2 ) { printf("\nФормат вызова: VESAINFO <имя файла>"); return -1; } // Открываем файл fileVesaReport = fopen(argv[1], "w+"); // Записываем в файл fileVesaReport информацию о VBE // и видеоадаптере iResult = GetBaseVESAInfo(fileVesaReport); fclose( fileVesaReport ); // Закрываем файл return !iResult ? 0 : -1; } int GetBaseVESAInfo(FILE *file) { union REGS regs; struct SREGS segregs; int iResult, i; // Структуры для получения информации о VBE VESAINFO vesaInfo; VESAMODEINFO modeInfo; // Подготавливаем буфер для VBE версии 2.0 strcpy(vesaInfo.cSignature, "VBE2"); // Получаем данные о реализации VBE regs.h.ah = 0x4F; regs.h.al = 0; segregs.es = FP_SEG((void far *) &vesaInfo); regs.x.di = FP_OFF((void far *) &vesaInfo); int86x(0x10, ®s, ®s, &segregs); // Проверяем результат вызова функции VBE iResult = AnalyseResult(regs); if( iResult ) return -1; // Записываем в файл информацию из структуры // vesaInfo fprintf(file, "Сигнатура: '%4.4s'\n", vesaInfo.cSignature); fprintf(file, "Информация фирмы-производителя: " "'%s'\n", vesaInfo.fpInfoOEM); fprintf(file, "Версия VBE: %Xh \n", vesaInfo.usVersion); fprintf(file, "Возможности видеоадаптера: " "'%x%x%x%x' \n", vesaInfo.ucCapabilities[0], vesaInfo.ucCapabilities[1], vesaInfo.ucCapabilities[2], vesaInfo.ucCapabilities[3]); fprintf(file, "Поддерживаются следующие режимы " "VESA: \n"); for(i = 0; i < 50; i++) { if( vesaInfo.fpModeTable[i] == 0xFFFF ) break; fprintf(file, " %Xh \n", vesaInfo.fpModeTable[i]); } // Объем видеопамяти определяется VBE версии не // меньше 1.2 if( vesaInfo.usVersion >= 0x102 ) fprintf(file, "Объем видеопамяти %d Кбайт\n", vesaInfo.usTotalMemory * 64); // Следующая информация доступна только для VBE v2.0 // и больше if( vesaInfo.usVersion >= 200 ) { fprintf(file, "Дополнительный номер версии: " "%04Xh\n", vesaInfo.usRevVersion); fprintf(file, "Дополнительный номер версии " "видеоадаптера : '%s'\n", vesaInfo.fpInfoOEM); fprintf(file, "Имя фирмы-разработчика: '%s'\n", vesaInfo.fpOEMName); fprintf(file, "Название видеоадаптера: '%s'\n", vesaInfo.fpOEMProductName); } // Теперь получаем информацию для каждого доступного // режима VESA for(i = 0; i < 50; i++) { // Получаем очередной номер режима VESA if( vesaInfo.fpModeTable[i] == 0xFFFF ) break; fprintf(file, "\n\nРежим %Xh \n", vesaInfo.fpModeTable[i]); // Получаем информацию о режиме // vesaInfo.fpModeTable[i] regs.h.ah = 0x4F; regs.h.al = 1; regs.x.cx = vesaInfo.fpModeTable[i]; segregs.es = FP_SEG((void far *) &modeInfo); regs.x.di = FP_OFF((void far *) &modeInfo); int86x(0x10, ®s, ®s, &segregs); // Проверяем результат вызова функции VBE iResult = AnalyseResult(regs); if( iResult ) return -1; // Записываем в файл информацию из структуры // modeInfo fprintf(file, "Атрибуты режима: %04Xh \n", modeInfo.usModeAttr); fprintf(file, "Атрибуты окна: A %02Xh \n", modeInfo.ucWinAAttr); fprintf(file, "Атрибуты окна: B %02Xh \n", modeInfo.ucWinBAttr); fprintf(file, "Шаг позиционирования окна: %d " "Кбайт \n", modeInfo.usWinGranularity); fprintf(file, "Размер окна, Кбайт: %d \n", modeInfo.usWinSize); fprintf(file, "Начало сегмента окна A: %04Xh \n", modeInfo.usBegSegA); fprintf(file, "Начало сегмента окна B: %04Xh \n", modeInfo.usBegSegB); fprintf(file, "Функция перемещения окна: %p \n", modeInfo.fpWinFunc); fprintf(file, "Байт на линию сканирования: %d " "\n", modeInfo.usBytesPerScanLine); // Объем видеопамяти определяется VBE версии не // меньше 1.2 if( vesaInfo.usVersion >= 0x102 ) { fprintf(file, "Разрешение по горизонтали: %d " "\n", modeInfo.usSizeX); fprintf(file, "Разрешение по вертикали: %d \n", modeInfo.usSizeY); fprintf(file, "Ширина символа: %02Xh \n", modeInfo.ucCharSizeX); fprintf(file, "Высота символа: %02Xh \n", modeInfo.ucCharSizeY); fprintf(file, "Количество слоев видеопамяти: " "%02Xh \n", modeInfo.ucNumPlanes); fprintf(file, "Количество бит на пиксель: " "%02Xh \n", modeInfo.ucNumPixelBits); fprintf(file, "Количество банков памяти: " "%02Xh \n", modeInfo.ucBanksNum); fprintf(file, "Тип модели памяти: %02Xh \n", modeInfo.ucTypeMemModel); fprintf(file, "Размер банка памяти: %02Xh \n", modeInfo.ucBankSize); fprintf(file, "Количество доступных страниц " "видеопамяти: %02Xh \n", modeInfo.ucPageNum); fprintf(file, "Размер поля красной компоненты " "цвета: %02Xh\n", modeInfo.ucRedSize); fprintf(file, "Положение красного поля: %02Xh " "\n", modeInfo.ucRedField); fprintf(file, "Размер поля зеленой компоненты " "цвета: %02Xh \n", modeInfo.ucGreenSize); fprintf(file, "Положение зеленого поля: %02Xh " "\n", modeInfo.ucGreenField); fprintf(file, "Размер поля синей компоненты " "цвета: %02Xh \n", modeInfo.ucBlueSize); fprintf(file, "Положение синего поля: %02Xh " "\n", modeInfo.ucBlueField); fprintf(file, "Размер резервной области: %02Xh" " \n", modeInfo.ucResSize); fprintf(file, "Положение резервного поля: " "%02Xh \n", modeInfo.ucResField); fprintf(file, "Режим ЦАП: %02X \n", modeInfo.ucDACInfo); } } return iResult; } int AnalyseResult(union REGS regs) { int iResult; if( regs.h.al == 0x4F && !regs.h.ah ) iResult = 0; else if( regs.h.al != 0x4F ) iResult = -1; else iResult = 1; return iResult; }