Цитата:
Цитата:
qwe113Насчет LFB. Его можно узнать из VESA в свойствах видео режимах.
//qwe113
Я спросил как его установить на определенный участок памяти(желательно, при 32-битной адресации). Из твоего ответа я понял, что уже все установлено, необходимо только посмотреть "в свойствах видео режима", разве это так?
//"Pavia"Да, так. Вот пример из моей ОС.
Код:
//Get Video Info
UCHAR* pBuf = pSysInfo->pDiskBuf + g0MegPtr;
memset4(pBuf, 0, 0x200 / 4);
pBuf[0] = 'V'; pBuf[1] = 'B'; pBuf[2] = 'E'; pBuf[3] = '2';
_ThreadRegs BiosRegs;
BiosRegs.eax = 0x4F00; //GET SuperVGA INFORMATION
BiosRegs.es = pSysInfo->segDiskBuf;
BiosRegs.edi = 0;
syscall2(SYSCALL::BiosIntCall, 0x10, (UINT)&BiosRegs);
if((USHORT)BiosRegs.eax == 0x4F)
{
pSysInfo->VesaCapab = pBuf[0xA];
pSysInfo->VesaVbeVer = *(USHORT*)&pBuf[0x22];
pSysInfo->VesaModes[0] = 0xFFFF;
USHORT* pModes = (USHORT*)(*(USHORT*)&pBuf[0x10] * 0x10 + *(USHORT*)&pBuf[0xE]);
for(UINT iSrc = 0, iDst = 0;; iSrc++)
{
if(pModes[iSrc] < 0x100u) { continue; }
pSysInfo->VesaModes[iDst] = pModes[iSrc];
if(pModes[iSrc] == 0xFFFF || iDst == 0xFF) { break; }
iDst++;
}
}
//Set Graphic mode
USHORT* pModes = pSysInfo->VesaModes;
for(UINT i = 0; i < 0x100u && pModes[i] != 0xFFFF; i++)
{
BiosRegs.eax = 0x4F01; //GET SuperVGA MODE INFORMATION
BiosRegs.ecx = pModes[i];
BiosRegs.es = pSysInfo->segDiskBuf;
BiosRegs.edi = 0;
syscall2(SYSCALL::BiosIntCall, 0x10, (UINT)&BiosRegs);
if((USHORT)BiosRegs.eax != 0x4F) { break; }
if((pBuf[0] & 2) &&
*(USHORT*)&pBuf[0x12] == 800 && *(USHORT*)&pBuf[0x14] == 600 && pBuf[0x19] == 16 &&
pBuf[0x21] == 6)
{
UINT ConfigMode = pModes[i];
if(pSysInfo->VesaCapab & 8) { ConfigMode |= 0x2000; } //Init VBE/AF
pSysInfo->VesaConfigMode = ConfigMode;
pSysInfo->VesaPixelsX = *(USHORT*)&pBuf[0x12];
pSysInfo->VesaPixelsY = *(USHORT*)&pBuf[0x14];
pSysInfo->VesaPixelBits = pBuf[0x19];
pSysInfo->VesaLineBytes = *(USHORT*)&pBuf[0x10];
if(pBuf[0] & 0x80) //With LFB
{
ConfigMode |= 0x4000; //Enable LFB
ULONG VesaPhysLfb = *(ULONG*)&pBuf[0x28];
pSysInfo->VesaPhysLfb = VesaPhysLfb;
pSysInfo->VesaLfb = K_MapPhysMem(VesaPhysLfb, pSysInfo->VesaPixelsX * pSysInfo->VesaPixelsY * 2);
}
BiosRegs.eax = 0x4F02; //SET SuperVGA MODE
BiosRegs.ebx = ConfigMode;
syscall2(SYSCALL::BiosIntCall, 0x10, (UINT)&BiosRegs);
break;
}
}
Поскольку номера поддерживаемых режимов и сами параметры режимов нам заранее не известны, то сначала запрашивается список всех имеющихся режимов в буфер. Используется вызов BIOS в режиме VM86, заполняется массив значений pSysInfo->VesaModes.
Затем после (//Set Graphic mode) в цикле запрашиваются параметры каждого номера режима, чтобы найти подходящее разрешение и цветность. В данном примере выбирается 800x600x16, у которого зелёный компонент составляет 6 бит (pBuf[0x21] == 6). Адрес LFB считывается из *(ULONG*)&pBuf[0x28].