Отправляет email-рассылки с помощью сервиса Sendsay

Все обо всем

  Все выпуски  

Все обо всем


Информационный Канал Subscribe.Ru


Все обо всем
№2 15.04.2003


Сегодня я решил поговорить с Вами на счет такой сложной вещи в компьютере как видеоадаптер. Возможно, у Вас уже возникала необходимость смены текущего видеорежима в своей программе. Посмотрим, что можно выжать из обыкновенного монитора VGA при помощи языка Assembler.

Итак, для начала исследуем наш видеоадаптер и аппаратуру в целом на поддержку стандарта VESA (VESA BIOS EXTENSION - VBE).

Вход:
AH=4Fh
AL=00h
ES:DI - указатель на буфер размером 256 байт, куда будет записана информация о реализации VBE (для версии 1.0)
ES:DI - указатель на буфер размером 512 байт, куда будет записана информация о реализации VBE (для версии 2.0, первые 4 байта должны содержать строку "VBE2")
Int 10h

Выход:
AL = 4Fh
AH = 00h - успех
   = 01h - ошибка

Теперь берем в руки Assembler (C, Pascal) и начинаем писать программу. После получения результата попытаемся его разложить "по полочкам".

Формат буфера:
Смещение   Размер   Описание
00h        4 байта  В случае успешного завершения здесь будет строка "VESA"
04h        DW       Номер версии, сразу младший, потом старший байт
06h        DD       Указатель на строку с описанием видеоадаптера, заканчивающуюся символом 0
0Ah        DD       Возможности видеоадаптера (битовая маска)
0Eh        DD       Указатель на список поддерживаемых видеорежимов, список заканчивается 0FFFFh и содержит 16-битовые значения

только для VBE 1.2 и старше
12h        DW       Объем видеопамяти в страницах по 64Кб

только для VBE 2.0 и старше
14h        DW       Дополнительный номер версии
16h        DD       Указатель на строку, заканчивающуюся символом 0. Строка содержит имя фирмы-разработчика
1Ah        DD       Указатель на строку, заканчивающуюся символом 0. Строка содержит название видеоадаптера
 ....
100h       256 байт Дополнительная информация от производителя

Я не стал приводить полный формат этой структуры, так как нам этого вполне достаточно.

Вот тепреь мы подошли к теме нашего разговора. Используя таблицу поддерживаемых видеорежимов установим необходимый нам режим.

Вход: AH=4Fh AL=02h BX=номер режима VESA Int 10h Выход: AL = 4Fh AH = 00h - успех = 01h - ошибка

Таблица основных режимов VESA
Режим    Тип            Количество цветов   Разрешение
100h     Графический    256                 640x400
101h     цветной        256                 640x480
102h     --             16                  800x600
103h     --             256                 800x600
104h     --             16                  1024x768
105h     --             256                 1024x768
106h     --             16                  1280x1024
107h     --             256                 1280x1024
108h     Текстовый      16                  80x60
109h     цветной        16                  132x25
10Ah     --             16                  132x43
10Bh     --             16                  132x50
10Ch     --             16                  132x60
10Dh     Графический    32768               320x200
10Eh     цветной        65536               320x200
10Fh     --             16777216            320x200
110h     --             32768               640x480
111h     --             65536               640x480
112h     --             16777216            640x480
113h     --             32768               800x600
114h     --             65536               800x600
115h     --             16777216            800x600
116h     --             32768               1024x768
117h     --             65536               1024x768
118h     --             16777216            1024x768
119h     --             32768               1280x1024
11Ah     --             65536               1280x1024

Надеюсь, что этого для начала достаточно, есть с чем провести эксперименты. В следующий раз рассмотрим как на экране вывести рисунок в одном из таких режимов...

Пример программы

#include 
#include 

typedef struct
  {
  char cSignature[4];               // 00
  char VerLo;                       // 04
  char VerHi;                       // 05
  char far* OEMInfo;                // 06
  unsigned char Capabilities[4];    // 0A
  unsigned short far* ModeTable;    // 0E
  // VESA 1.2
  unsigned int VRAM;                // 12
  // VESA 2.0
  char RevVerLo;                    // 14
  char RevVerHi;                    // 15
  char far* OEMName;                // 16
  char far* Product;                // 1A
  char far* sRevVer;                // 1E
  unsigned char Reserv[222];        // 22
  char OEMData[256];                //100
  } vesa;

vesa Buf;

main()
{
  char Res;
  int i;

  asm {
    mov AX, 0x0003
    int 0x10
  }

  strcpy(Buf.cSignature, "VBE2");
  printf("%s", "Check VBE: ");
  asm {
    mov  AX, 0x4F00
    push DS
    pop  ES
    lea  DI, Buf
    int  0x10
    mov  Res, AH
    }
  if (Res == 1)
    goto NoVBE;

  printf("OK!\n\r--- VBE INFO ---\n\r%4s %d.%d\n\rOEM info:\t%s\n\rCapabilities:\t%4Xh\n\rMode table:\n\r", Buf.cSignature, Buf.VerHi, Buf.VerLo, Buf.OEMInfo, Buf.Capabilities);
  i = 0;
  while(Buf.ModeTable[i] != 0xFFFF)
    {
    printf("%4Xh\t", Buf.ModeTable[i]);
    i++;
    }
  printf("\n\r");
  if (((Buf.VerHi == 1) && (Buf.VerLo >= 2))  || (Buf.VerHi > 1))
    {
    printf("VideoRAM:\t%dMb (or more...)\n\r", 64*Buf.VRAM / 1024);
    }
  if (Buf.VerHi >= 2)
    {
    printf("Revision:\t%d.%d\n\rOEM name:\t%s\n\rProduct:\t%s\n\rRevision info:\t%s\n\rReserv:\n\r", Buf.RevVerHi, Buf.RevVerLo, Buf.OEMName, Buf.Product, Buf.sRevVer);
    for (i=0; i<222; i++)
      printf("%c", Buf.Reserv[i]);
//    printf("\n\r");
//    for (i=0; i<222; i++)
//      printf("%02Xh ", Buf.Reserv[i]);

    printf("\n\rOEM strings:\n\r");
    for (i=0; i<256; i++)
      printf("%c", Buf.OEMData[i]);
    }

  goto Quit;

NoVBE:
  printf("ERROR!\n\r");

Quit:
  printf("\n\r");
  return 0;
}

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное