Index: vbe.c =================================================================== RCS file: /sources/vgabios/vgabios/vbe.c,v retrieving revision 1.64 diff -u -r1.64 vbe.c --- vbe.c 19 Jul 2011 18:25:05 -0000 1.64 +++ vbe.c 26 Jun 2013 02:21:07 -0000 @@ -754,6 +754,29 @@ ret ASM_END +ASM_START +_size64: + push bp + mov bp, sp + push dx + +; multiply bbp by yres first as results fit in 16bits +; then multiply by xres + mov ax, 8[bp] + mul word 6[bp] + mul word 4[bp] +; divide by 2^19 ceiling result + add ax, #0xffff + adc dx, #7 + mov ax, dx + shr ax, #3 + + pop dx + pop bp + ret +ASM_END + + /** Function 00h - Return VBE Controller Information * * Input: @@ -857,7 +880,7 @@ do { - size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; + Bit16u size_64k = size64(cur_info->info.XResolution, cur_info->info.YResolution, cur_info->info.BitsPerPixel); if ((cur_info->info.XResolution <= dispi_get_max_xres()) && (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && @@ -917,14 +940,25 @@ if (cur_info != 0) { + Bit16u max_bpp = dispi_get_max_bpp(); + Bit16u size_64k; + Bit16u totalMemory; + + outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + totalMemory = inw(VBE_DISPI_IOPORT_DATA); #ifdef DEBUG printf("VBE found mode %x\n",CX); #endif memsetb(ss, &info, 0, sizeof(ModeInfoBlock)); memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); - if (using_lfb) { - info.NumberOfBanks = 1; - } + size_64k = size64(info.XResolution, info.YResolution, info.BitsPerPixel); + if ((info.XResolution > dispi_get_max_xres()) || + (info.BitsPerPixel > max_bpp) || + (size_64k > totalMemory)) + info.ModeAttributes &= ~VBE_MODE_ATTRIBUTE_SUPPORTED; + + /* Windows 8 require this to be 1! */ + info.NumberOfBanks = 1; #ifdef PCI_VID lfb_addr = pci_get_lfb_addr(PCI_VID); #else