1 /* 2 * FreeLoader 3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #include <freeldr.h> 21 22 #include <debug.h> 23 DBG_DEFAULT_CHANNEL(HWDETECT); 24 25 #include <pshpack2.h> 26 typedef struct 27 { 28 UCHAR Signature[4]; // (ret) signature ("VESA") 29 // (call) VESA 2.0 request signature ("VBE2"), required to receive 30 // version 2.0 info 31 USHORT VesaVersion; // VESA version number (one-digit minor version -- 0102h = v1.2) 32 ULONG OemNamePtr; // pointer to OEM name 33 // "761295520" for ATI 34 ULONG Capabilities; // capabilities flags (see #00078) 35 ULONG SupportedModeListPtr; // pointer to list of supported VESA and OEM video modes 36 // (list of words terminated with FFFFh) 37 USHORT TotalVideoMemory; // total amount of video memory in 64K blocks 38 39 // ---VBE v1.x --- 40 //UCHAR Reserved[236]; 41 42 // ---VBE v2.0 --- 43 USHORT OemSoftwareVersion; // OEM software version (BCD, high byte = major, low byte = minor) 44 ULONG VendorNamePtr; // pointer to vendor name 45 ULONG ProductNamePtr; // pointer to product name 46 ULONG ProductRevisionStringPtr; // pointer to product revision string 47 USHORT VBE_AF_Version; // (if capabilities bit 3 set) VBE/AF version (BCD) 48 // 0100h for v1.0P 49 ULONG AcceleratedModeListPtr; // (if capabilities bit 3 set) pointer to list of supported 50 // accelerated video modes (list of words terminated with FFFFh) 51 UCHAR Reserved[216]; // reserved for VBE implementation 52 UCHAR ScratchPad[256]; // OEM scratchpad (for OEM strings, etc.) 53 } VESA_SVGA_INFO, *PVESA_SVGA_INFO; 54 #include <poppack.h> 55 56 // Bitfields for VESA capabilities: 57 // 58 // Bit(s) Description (Table 00078) 59 // 0 DAC can be switched into 8-bit mode 60 // 1 non-VGA controller 61 // 2 programmed DAC with blank bit (i.e. only during blanking interval) 62 // 3 (VBE v3.0) controller supports hardware stereoscopic signalling 63 // 3 controller supports VBE/AF v1.0P extensions 64 // 4 (VBE v3.0) if bit 3 set: 65 // =0 stereo signalling via external VESA stereo connector 66 // =1 stereo signalling via VESA EVC connector 67 // 4 (VBE/AF v1.0P) must call EnableDirectAccess to access framebuffer 68 // 5 (VBE/AF v1.0P) controller supports hardware mouse cursor 69 // 6 (VBE/AF v1.0P) controller supports hardware clipping 70 // 7 (VBE/AF v1.0P) controller supports transparent BitBLT 71 // 8-31 reserved (0) 72 73 // Notes: The list of supported video modes is stored in the reserved 74 // portion of the SuperVGA information record by some implementations, 75 // and it may thus be necessary to either copy the mode list or use a 76 // different buffer for all subsequent VESA calls. Not all of the video 77 // modes in the list of mode numbers may be supported, e.g. if they require 78 // more memory than currently installed or are not supported by the 79 // attached monitor. Check any mode you intend to use through AX=4F01h first.. 80 // The 1.1 VESA document specifies 242 reserved bytes at the end, so the 81 // buffer should be 262 bytes to ensure that it is not overrun; for v2.0, 82 // the buffer should be 512 bytes. The S3 specific video modes will most 83 // likely follow the FFFFh terminator at the end of the standard modes. 84 // A search must then be made to find them, FFFFh will also terminate this 85 // second list. In some cases, only a "stub" VBE may be present, supporting 86 // only AX=4F00h; this case may be assumed if the list of supported video modes 87 // is empty (consisting of a single word of FFFFh) 88 #if 0 89 static VOID BiosSetVideoFont8x16(VOID) 90 { 91 REGS Regs; 92 93 // Int 10h AX=1114h 94 // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA) 95 // 96 // AX = 1114h 97 // BL = block to load 98 // Return: 99 // Nothing 100 Regs.w.ax = 0x1114; 101 Regs.b.bl = 0; 102 Int386(0x10, &Regs, &Regs); 103 } 104 105 static VOID VideoSetTextCursorPosition(ULONG X, ULONG Y) 106 { 107 } 108 109 static ULONG VideoGetTextCursorPositionX(VOID) 110 { 111 REGS Regs; 112 113 // Int 10h AH=03h 114 // VIDEO - GET CURSOR POSITION AND SIZE 115 // 116 // AH = 03h 117 // BH = page number 118 // 0-3 in modes 2&3 119 // 0-7 in modes 0&1 120 // 0 in graphics modes 121 // Return: 122 // AX = 0000h (Phoenix BIOS) 123 // CH = start scan line 124 // CL = end scan line 125 // DH = row (00h is top) 126 // DL = column (00h is left) 127 Regs.b.ah = 0x03; 128 Regs.b.bh = 0x00; 129 Int386(0x10, &Regs, &Regs); 130 131 return Regs.b.dl; 132 } 133 134 static ULONG VideoGetTextCursorPositionY(VOID) 135 { 136 REGS Regs; 137 138 // Int 10h AH=03h 139 // VIDEO - GET CURSOR POSITION AND SIZE 140 // 141 // AH = 03h 142 // BH = page number 143 // 0-3 in modes 2&3 144 // 0-7 in modes 0&1 145 // 0 in graphics modes 146 // Return: 147 // AX = 0000h (Phoenix BIOS) 148 // CH = start scan line 149 // CL = end scan line 150 // DH = row (00h is top) 151 // DL = column (00h is left) 152 Regs.b.ah = 0x03; 153 Regs.b.bh = 0x00; 154 Int386(0x10, &Regs, &Regs); 155 156 return Regs.b.dh; 157 } 158 #endif 159 160 USHORT BiosIsVesaSupported(VOID) 161 { 162 REGS Regs; 163 PVESA_SVGA_INFO SvgaInfo = (PVESA_SVGA_INFO)BIOSCALLBUFFER; 164 //USHORT* VideoModes; 165 //USHORT Index; 166 167 TRACE("BiosIsVesaSupported()\n"); 168 169 RtlZeroMemory(SvgaInfo, sizeof(VESA_SVGA_INFO)); 170 171 // Make sure we receive version 2.0 info 172 SvgaInfo->Signature[0] = 'V'; 173 SvgaInfo->Signature[1] = 'B'; 174 SvgaInfo->Signature[2] = 'E'; 175 SvgaInfo->Signature[3] = '2'; 176 177 // Int 10h AX=4F00h 178 // VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION 179 // 180 // AX = 4F00h 181 // ES:DI -> buffer for SuperVGA information (see #00077) 182 // Return: 183 // AL = 4Fh if function supported 184 // AH = status 185 // 00h successful 186 // ES:DI buffer filled 187 // 01h failed 188 // ---VBE v2.0--- 189 // 02h function not supported by current hardware configuration 190 // 03h function invalid in current video mode 191 // 192 // Determine whether VESA BIOS extensions are present and the 193 // capabilities supported by the display adapter 194 // 195 // Installation check;VESA SuperVGA 196 Regs.w.ax = 0x4F00; 197 Regs.w.es = BIOSCALLBUFSEGMENT; 198 Regs.w.di = BIOSCALLBUFOFFSET; 199 Int386(0x10, &Regs, &Regs); 200 201 TRACE("AL = 0x%x\n", Regs.b.al); 202 TRACE("AH = 0x%x\n", Regs.b.ah); 203 204 if (Regs.w.ax != 0x004F) 205 { 206 WARN("VBE Get SuperVGA information function not supported (AL=0x%x) or failed (AH=0x%x)\n", 207 Regs.b.al, Regs.b.ah); 208 return 0x0000; 209 } 210 211 TRACE("Supported.\n"); 212 TRACE("SvgaInfo->Signature[4] = %c%c%c%c\n", SvgaInfo->Signature[0], SvgaInfo->Signature[1], SvgaInfo->Signature[2], SvgaInfo->Signature[3]); 213 TRACE("SvgaInfo->VesaVersion = v%d.%d\n", ((SvgaInfo->VesaVersion >> 8) & 0xFF), (SvgaInfo->VesaVersion & 0xFF)); 214 TRACE("SvgaInfo->OemNamePtr = 0x%x\n", SvgaInfo->OemNamePtr); 215 TRACE("SvgaInfo->Capabilities = 0x%x\n", SvgaInfo->Capabilities); 216 TRACE("SvgaInfo->VideoMemory = %dK\n", SvgaInfo->TotalVideoMemory * 64); 217 TRACE("---VBE v2.0 ---\n"); 218 TRACE("SvgaInfo->OemSoftwareVersion = v%d.%d\n", ((SvgaInfo->OemSoftwareVersion >> 8) & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 12) & 0x0F) * 10), (SvgaInfo->OemSoftwareVersion & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 4) & 0x0F) * 10)); 219 TRACE("SvgaInfo->VendorNamePtr = 0x%x\n", SvgaInfo->VendorNamePtr); 220 TRACE("SvgaInfo->ProductNamePtr = 0x%x\n", SvgaInfo->ProductNamePtr); 221 TRACE("SvgaInfo->ProductRevisionStringPtr = 0x%x\n", SvgaInfo->ProductRevisionStringPtr); 222 TRACE("SvgaInfo->VBE/AF Version = 0x%x (BCD WORD)\n", SvgaInfo->VBE_AF_Version); 223 224 if (SvgaInfo->Signature[0] != 'V' || 225 SvgaInfo->Signature[1] != 'E' || 226 SvgaInfo->Signature[2] != 'S' || 227 SvgaInfo->Signature[3] != 'A') 228 { 229 ERR("Bad signature in VESA information (%c%c%c%c)\n", 230 SvgaInfo->Signature[0], 231 SvgaInfo->Signature[1], 232 SvgaInfo->Signature[2], 233 SvgaInfo->Signature[3]); 234 return 0x0000; 235 } 236 237 return SvgaInfo->VesaVersion; 238 } 239 240 241 BOOLEAN 242 BiosIsVesaDdcSupported(VOID) 243 { 244 REGS Regs; 245 246 TRACE("BiosIsVesaDdcSupported()\n"); 247 248 Regs.w.ax = 0x4F15; 249 Regs.b.bl = 0; 250 Regs.w.cx = 0; 251 Regs.w.es = 0; 252 Regs.w.di = 0; 253 Int386(0x10, &Regs, &Regs); 254 255 TRACE("AL = 0x%x\n", Regs.b.al); 256 TRACE("AH = 0x%x\n", Regs.b.ah); 257 258 TRACE("BL = 0x%x\n", Regs.b.bl); 259 260 if (Regs.w.ax != 0x004F) 261 { 262 WARN("VBE/DDC Installation check function not supported (AL=0x%x) or failed (AH=0x%x)\n", 263 Regs.b.al, Regs.b.ah); 264 return FALSE; 265 } 266 267 return (Regs.b.ah == 0); 268 } 269 270 271 BOOLEAN 272 BiosVesaReadEdid(VOID) 273 { 274 REGS Regs; 275 276 TRACE("BiosVesaReadEdid()\n"); 277 278 RtlZeroMemory((PVOID)BIOSCALLBUFFER, 128); 279 280 Regs.w.ax = 0x4F15; 281 Regs.b.bl = 1; 282 Regs.w.cx = 0; 283 Regs.w.dx = 0; 284 Regs.w.es = BIOSCALLBUFSEGMENT; 285 Regs.w.di = BIOSCALLBUFOFFSET; 286 Int386(0x10, &Regs, &Regs); 287 288 TRACE("AL = 0x%x\n", Regs.b.al); 289 TRACE("AH = 0x%x\n", Regs.b.ah); 290 291 if (Regs.w.ax != 0x004F) 292 { 293 WARN("VBE/DDC Read EDID function not supported (AL=0x%x) or failed (AH=0x%x)\n", 294 Regs.b.al, Regs.b.ah); 295 return FALSE; 296 } 297 298 return (Regs.b.ah == 0); 299 } 300 301 /* EOF */ 302