vbe.c revision a240f5a92450001a042bb639fe6e7d9cf0e3eb72
// ============================================================================================
//
// Copyright (C) 2002 Jeroen Janssen
//
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// ============================================================================================
//
// You can NOT drive any physical vga card with it.
//
// ============================================================================================
//
// This VBE Bios is based on information taken from :
// - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org
//
// ============================================================================================
/*
* Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
* other than GPL or LGPL is available it will apply instead, Oracle elects to use only
* the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
* a choice of LGPL license versions is made available with the language indicating
* that LGPLv2 or any later version may be used, or where a choice of which version
* of the LGPL is applied is otherwise unspecified.
*/
// defines available
//#define VBE2_NO_VESA_CHECK
// use bytewise i/o (Longhorn beta issue, not in released Vista)
//#define VBE_BYTEWISE_IO
#ifdef VBE_BYTEWISE_IO
#else
#endif
// Use VBE new dynamic mode list. Note that without this option, no
// checks are currently done to make sure that modes fit into the
// framebuffer!
#define VBE_NEW_DYN_LIST
#include "vbe.h"
// The current OEM Software Revision of this VBE Bios
#define VBE_OEM_SOFTWARE_REV 0x0002
extern char vbebios_copyright;
extern char vbebios_vendor_name;
extern char vbebios_product_name;
extern char vbebios_product_revision;
// FIXME: 'merge' these (c) etc strings with the vgabios.c strings?
.ascii "VirtualBox VBE BIOS http://www.virtualbox.org/"
.byte 0x00
.byte 0x00
.ascii " VBE Adapter"
.byte 0x00
.ascii " Version "
.byte 0x00
//.ascii "Bochs VBE Display Adapter enabled"
.ascii "VirtualBox VBE Display Adapter enabled"
.byte 0x00
.ascii "No VirtualBox VBE support available!"
.byte 0x00
#ifdef DEBUG
.ascii "VirtualBox Version "
.ascii " VBE Display Adapter"
#endif
.align 2
dw 0xffff
dw 0xffff
#ifdef VBE_BYTEWISE_IO
#endif
static void dispi_set_xres(xres)
{
}
static void dispi_set_yres(yres)
{
#ifdef VBOX
#else
#endif
}
static void dispi_set_bpp(bpp)
{
#ifdef VBOX
#else
#endif
}
static void dispi_set_bank_farcall()
{
}
#ifdef VBE_NEW_DYN_LIST
{
}
{
}
#endif
// ModeInfo helper function
{
#ifdef VBE_NEW_DYN_LIST
/* Read VBE Extra Data signature */
if (sig != VBEHEADER_MAGIC)
{
return 0;
}
while (vmode != VBE_VESA_MODE_END_OF_LIST)
{
{
if (!using_lfb)
{
return cur_info;
}
else if (attrs & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE)
{
return cur_info;
}
else
{
cur_info++;
}
}
else
{
cur_info++;
}
}
#else
{
{
if (!using_lfb)
{
return cur_info;
}
{
return cur_info;
}
else
{
cur_info++;
}
}
else
{
cur_info++;
}
}
#endif
return 0;
}
#if defined(DEBUG)
#endif
#ifndef VBOX
#endif
/** Function 00h - Return VBE Controller Information
*
* Input:
* AX = 4F00h
* ES:DI = Pointer to buffer in which to place VbeInfoBlock structure
* (VbeSignature should be VBE2 when VBE 2.0 information is desired and
* the info block is 512 bytes in size)
* Output:
* AX = VBE Return Status
*
*/
{
#ifndef VBOX
#endif
#ifdef VBE_NEW_DYN_LIST
#else
#endif
#ifdef VBE_NEW_DYN_LIST
/* Read VBE Extra Data signature */
if (sig != VBEHEADER_MAGIC)
{
result = 0x100;
printf("Signature NOT found\n");
return;
}
#endif
#ifdef DEBUG
#endif
vbe2_info = 0;
#ifdef VBOX
/* Don't use a local copy of VbeInfoBlock on the stack; it's too big.
* The Ubuntu 8.04 64 bits splash screen emulator can't handle this.
*/
#ifdef VBE2_NO_VESA_CHECK
#else /* !VBE2_NO_VESA_CHECK */
// check for VBE2 signature
{
vbe2_info = 1;
#ifdef DEBUG
#endif
}
#endif /* !VBE2_NO_VESA_CHECK */
// VBE Signature
// VBE Version supported
// OEM String
// Capabilities
// VBE Video Mode Pointer (dynamicly generated from the mode_info_list)
// VBE Total Memory (in 64b blocks)
if (vbe2_info)
{
// OEM Stuff
}
#else /* !VBOX */
// get vbe_info_block into local variable
#ifdef VBE2_NO_VESA_CHECK
#else
// check for VBE2 signature
{
vbe2_info = 1;
#ifdef DEBUG
#endif
}
#endif
// VBE Signature
// VBE Version supported
// OEM String
// Capabilities
// VBE Video Mode Pointer (dynamicly generated from the mode_info_list)
// VBE Total Memory (in 64b blocks)
if (vbe2_info)
{
// OEM Stuff
// copy updates in vbe_info_block back
}
else
{
// copy updates in vbe_info_block back (VBE 1.x compatibility)
}
#endif /* !VBOX */
#ifdef VBE_NEW_DYN_LIST
do
{
{
#ifdef DEBUG
#endif
cur_mode++;
cur_ptr+=2;
}
cur_info++;
} while (vmode != VBE_VESA_MODE_END_OF_LIST);
// Add vesa mode list terminator
#else
do
{
#ifdef DEBUG
#endif
cur_mode++;
cur_ptr+=2;
}
cur_info++;
// Add vesa mode list terminator
#endif // VBE_NEW_DYN_LIST
result = 0x4f;
}
/** Function 01h - Return VBE Mode Information
*
* Input:
* AX = 4F01h
* CX = Mode Number
* ES:DI = Pointer to buffer in which to place ModeInfoBlock structure
* Output:
* AX = VBE Return Status
*
*/
{
#ifdef DEBUG
#endif
if (cur_info != 0)
{
#ifdef VBE_NEW_DYN_LIST
Bit16u i;
#endif
#ifdef DEBUG
#endif
#ifdef VBE_NEW_DYN_LIST
for (i = 0; i < sizeof(ModeInfoBlockCompact); i++)
{
Bit8u b;
}
#else
#endif
if (win_attr & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) {
// If BIOS not at 0xC000 -> boom
}
result = 0x4f;
}
else
{
#ifdef DEBUG
#endif
result = 0x100;
}
}
/** Function 02h - Set VBE Mode
*
* Input:
* AX = 4F02h
* BX = Desired Mode to set
* ES:DI = Pointer to CRTCInfoBlock structure
* Output:
* AX = VBE Return Status
*
*/
{
no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0;
//result=read_word(ss,AX);
// check for non vesa mode
if (BX<VBE_MODE_VESA_DEFINED)
{
// call the vgabios in order to set the video mode
// this allows for going back to textmode with a VBE call (some applications expect that to work)
result = 0x4f;
goto leave;
}
if (cur_info != 0)
{
#ifdef VBE_NEW_DYN_LIST
Bit16u x, y;
#ifdef DEBUG
#endif
#else
#ifdef DEBUG
printf("\txres%x yres%x bpp%x\n",
#endif
#endif // VBE_NEW_DYN_LIST
// first disable current mode (when switching between vesa modi)
#ifdef VBE_NEW_DYN_LIST
if (bpp == 4)
#else
#endif
{
biosfn_set_video_mode(0x6a);
}
#ifdef VBE_NEW_DYN_LIST
#else
#endif
dispi_set_bank(0);
result = 0x4f;
}
else
{
#ifdef DEBUG
#endif
result = 0x100;
}
}
/** Function 03h - Return Current VBE Mode
*
* Input:
* AX = 4F03h
* Output:
* AX = VBE Return Status
* BX = Current VBE Mode
*
*/
{
return 9 * 2;
}
{
BX += 2;
if (!(enable & VBE_DISPI_ENABLED))
return;
for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
if (i != VBE_DISPI_INDEX_ENABLE) {
BX += 2;
}
}
}
{
BX += 2;
if (!(enable & VBE_DISPI_ENABLED)) {
} else {
BX += 2;
BX += 2;
BX += 2;
for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
BX += 2;
}
}
}
*
* Input:
* AX = 4F04h
* 01h Save State
* 02h Restore State
* CX = Requested states
* ES:BX = Pointer to buffer (if DL <> 00h)
* Output:
* AX = VBE Return Status
* BX = Number of 64-byte blocks to hold the state buffer (if DL=00h)
*
*/
{
result = 0x4f;
switch(GET_DL()) {
case 0x00:
#ifdef DEBUG
#endif
if (CX & 8)
break;
case 0x01:
#ifdef DEBUG
#endif
if (CX & 8)
break;
case 0x02:
#ifdef DEBUG
#endif
if (CX & 8)
break;
default:
// function failed
result = 0x100;
break;
}
}
/** Function 05h - Display Window Control
*
* Input:
* AX = 4F05h
* (16-bit) BH = 00h Set memory window
* = 01h Get memory window
* BL = Window number
* = 00h Window A
* = 01h Window B
* DX = Window number in video memory in window
* granularity units (Set Memory Window only)
* Note:
* If this function is called while in a linear frame buffer mode,
* this function must fail with completion code AH=03h
*
* Output:
* AX = VBE Return Status
* DX = Window number in window granularity units
* (Get Memory Window only)
*/
*
* Input:
* AX = 4F06h
* BL = 00h Set Scan Line Length in Pixels
* = 01h Get Scan Line Length
* = 02h Set Scan Line Length in Bytes
* = 03h Get Maximum Scan Line Length
* CX = If BL=00h Desired Width in Pixels
* If BL=02h Desired Width in Bytes
* (Ignored for Get Functions)
*
* Output:
* AX = VBE Return Status
* BX = Bytes Per Scan Line
* CX = Actual Pixels Per Scan Line
* (truncated to nearest complete pixel)
* DX = Maximum Number of Scan Lines
*/
*
* Input(16-bit):
* AX = 4F07h
* BH = 00h Reserved and must be 00h
* BL = 00h Set Display Start
* = 01h Get Display Start
* = 02h Schedule Display Start (Alternate)
* = 03h Schedule Stereoscopic Display Start
* = 04h Get Scheduled Display Start Status
* = 05h Enable Stereoscopic Mode
* = 06h Disable Stereoscopic Mode
* = 80h Set Display Start during Vertical Retrace
* = 82h Set Display Start during Vertical Retrace (Alternate)
* = 83h Set Stereoscopic Display Start during Vertical Retrace
* ECX = If BL=02h/82h Display Start Address in bytes
* If BL=03h/83h Left Image Start Address in bytes
* EDX = If BL=03h/83h Right Image Start Address in bytes
* CX = If BL=00h/80h First Displayed Pixel In Scan Line
* DX = If BL=00h/80h First Displayed Scan Line
*
* Output:
* AX = VBE Return Status
* BH = If BL=01h Reserved and will be 0
* CX = If BL=01h First Displayed Pixel In Scan Line
* If BL=04h 0 if flip has not occurred, not 0 if it has
* DX = If BL=01h First Displayed Scan Line
*
* Input(32-bit):
* BH = 00h Reserved and must be 00h
* BL = 00h Set Display Start
* = 80h Set Display Start during Vertical Retrace
* CX = Bits 0-15 of display start address
* DX = Bits 16-31 of display start address
* ES = Selector for memory mapped registers
*/
*
* Input:
* AX = 4F08h
* BL = 00h set DAC palette width
* = 01h get DAC palette width
* BH = If BL=00h: desired number of bits per primary color
* Output:
* AX = VBE Return Status
* BH = current number of bits per primary color (06h = standard VGA)
*/
*
* Input:
* AX = 4F09h
* (16-bit) BL = 00h Set palette data
* = 01h Get palette data
* = 02h Set secondary palette data
* = 03h Get secondary palette data
* = 80h Set palette data during VRetrace
* CX = Number of entries to update (<= 256)
* DX = First entry to update
* ES:DI = Table of palette values
* Output:
* AX = VBE Return Status
*
* Notes:
* Secondary palette support is a "future extension".
*
* In VBE 3.0, reading palette data is optional and
* subfunctions 01h and 03h may return failure.
*
* The format of palette entries is as follows:
*
* PaletteEntry struc
* Blue db ? ; Blue channel value (6 or 8 bits)
* Green db ? ; Green channel value (6 or 8 bits)
* Red db ? ; Red channel value (6 or 8 bits)
* Padding db ? ; DWORD alignment byte (unused)
* PaletteEntry ends
*
* Most applications use VGA DAC registers directly to
* required for NonVGA controllers (eg. XGA).
*/
#if 0
/* this is where we could wait for vertical retrace */
#endif
/** Function 0Ah - Return VBE Protected Mode Interface
*
* Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface
* BL = 00h Return protected mode table
* Output: AX = Status
* ES = Real Mode Segment of Table
* DI = Offset of Table
* CX = Length of Table including protected mode code
* (for copying purposes)
*/