DevVGA.cpp revision 323b78bf4831666c95416edf3b6e54657a769e5d
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * DevVGA - VBox VGA/VESA device.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * available from http://www.virtualbox.org. This file is free software;
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * General Public License (GPL) as published by the Free Software
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * additional information or have any questions.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * --------------------------------------------------------------------
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * This code is based on:
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * QEMU VGA Emulator.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Copyright (c) 2003 Fabrice Bellard
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * of this software and associated documentation files (the "Software"), to deal
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * in the Software without restriction, including without limitation the rights
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * copies of the Software, and to permit persons to whom the Software is
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * furnished to do so, subject to the following conditions:
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * The above copyright notice and this permission notice shall be included in
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * all copies or substantial portions of the Software.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * THE SOFTWARE.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/*******************************************************************************
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync* Defined Constants And Macros *
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync*******************************************************************************/
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The default amount of VRAM. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The maximum amount of VRAM. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The minimum amount of VRAM. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The size of the VGA GC mapping.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * This is supposed to be all the VGA memory accessible to the guest.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * The initial value was 256KB but NTAllInOne.iso appears to access more
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * thus the limit was upped to 512KB.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * @todo Someone with some VGA knowhow should make a better guess at this value.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Converts a vga adaptor state pointer to a device instance pointer. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync#define VGASTATE2DEVINS(pVgaState) ((pVgaState)->CTX_SUFF(pDevIns))
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Use VBE bytewise I/O */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Use VBE new dynamic mode list.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * If this is not defined, no checks are carried out to see if the modes all
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * fit into the framebuffer! See the VRAM_SIZE_FIX define. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Check that the video modes fit into virtual video memory.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync * Only works when VBE_NEW_DYN_LIST is defined! */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Some fixes to ensure that logical scan-line lengths are not overwritten. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/*******************************************************************************
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync* Header Files *
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync*******************************************************************************/
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync#if defined(VBE_NEW_DYN_LIST) && defined(IN_RING3) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/*******************************************************************************
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync* Structures and Typedefs *
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync*******************************************************************************/
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** BMP File Format Bitmap Header. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsynctypedef struct
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Pointer to a bitmap header*/
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** OS/2 1.x Information Header Format. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsynctypedef struct
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Pointer to a OS/2 1.x header format */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** OS/2 2.0 Information Header Format. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsynctypedef struct
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t Compression; /* Compression Scheme (0=none) */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t ClrImportant; /* Number of Important Colors */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint16_t Reserved; /* Reserved FIelds (always 0) */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint16_t Rendering; /* Halftone Algorithm Used on Image */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t ColorEncoding; /* Color Table Format (always 0) */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t Identifier; /* Misc. Field for Application Use */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Pointer to a OS/2 2.0 header format */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Windows 3.x Information Header Format. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsynctypedef struct
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t Compression; /* Compression Scheme (0=none) */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync uint32_t ClrImportant; /* Number of Important Colors */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Pointer to a Windows 3.x header format */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** @name BMP compressions.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** @name BMP header sizes.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The BIOS boot menu text position, X. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The BIOS boot menu text position, Y. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Width of the "Press F12 to select boot device." bitmap.
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync Anything that exceeds the limit of F12BootText below is filled with
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync background. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** Height of the boot device selection bitmap, see LOGO_F12TEXT_WIDTH. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/** The BIOS logo delay time (msec). */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync#define LOGO_MAX_SIZE LOGO_MAX_WIDTH * LOGO_MAX_HEIGHT * 4
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/*******************************************************************************
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync* Global Variables *
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync*******************************************************************************/
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync/* "Press F12 to select boot device." bitmap. */
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x0F, 0x7C,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF8, 0xF0, 0x01, 0xE0, 0x81, 0x9F, 0x3F, 0x00, 0x70, 0xF8, 0x00, 0xE0, 0xC3,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x07, 0x0F, 0x1F, 0x3E, 0x70, 0x00, 0xF0, 0xE1, 0xC3, 0x07, 0x0E, 0x00, 0x6E,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x7C, 0x60, 0xE0, 0xE1, 0xC3, 0x07, 0xC6, 0x80, 0x81, 0x31, 0x63, 0xC6, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x30, 0x80, 0x61, 0x0C, 0x00, 0x36, 0x63, 0x00, 0x8C, 0x19, 0x83, 0x61, 0xCC,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x18, 0x36, 0x00, 0xCC, 0x8C, 0x19, 0xC3, 0x06, 0xC0, 0x8C, 0x31, 0x3C, 0x30,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x8C, 0x19, 0x83, 0x31, 0x60, 0x60, 0x00, 0x0C, 0x18, 0x00, 0x0C, 0x60, 0x18,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x80, 0xC1, 0x18, 0x00, 0x30, 0x06, 0x60, 0x18, 0x30, 0x80, 0x01, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x33, 0x63, 0xC6, 0x30, 0x00, 0x30, 0x63, 0x80, 0x19, 0x0C, 0x03, 0x06, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x0C, 0x18, 0x18, 0xC0, 0x81, 0x03, 0x00, 0x03, 0x18, 0x0C, 0x00, 0x60, 0x30,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x06, 0x00, 0x87, 0x01, 0x18, 0x06, 0x0C, 0x60, 0x00, 0xC0, 0xCC, 0x98, 0x31,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x0C, 0x00, 0xCC, 0x18, 0x30, 0x0C, 0xC3, 0x80, 0x01, 0x00, 0x03, 0x66, 0xFE,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x18, 0x30, 0x00, 0xC0, 0x02, 0x06, 0x06, 0x00, 0x18, 0x8C, 0x01, 0x60, 0xE0,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x0F, 0x86, 0x3F, 0x03, 0x18, 0x00, 0x30, 0x33, 0x66, 0x0C, 0x03, 0x00, 0x33,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xFE, 0x0C, 0xC3, 0x30, 0xE0, 0x0F, 0xC0, 0x87, 0x9B, 0x31, 0x63, 0xC6, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF0, 0x80, 0x01, 0x03, 0x00, 0x06, 0x63, 0x00, 0x8C, 0x19, 0x83, 0x61, 0xCC,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x18, 0x06, 0x00, 0x6C, 0x8C, 0x19, 0xC3, 0x00, 0x80, 0x8D, 0x31, 0xC3, 0x30,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x8C, 0x19, 0x03, 0x30, 0xB3, 0xC3, 0x87, 0x0F, 0x1F, 0x00, 0x2C, 0x60, 0x80,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x01, 0xE0, 0x87, 0x0F, 0x00, 0x3E, 0x7C, 0x60, 0xF0, 0xE1, 0xE3, 0x07, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x0F, 0x3E, 0x7C, 0xFC, 0x00, 0xC0, 0xC3, 0xC7, 0x30, 0x0E, 0x3E, 0x7C, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x1E, 0xC0, 0x00, 0x60, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x0C, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0xC0, 0x0C, 0x87, 0x31, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x06, 0x00, 0x00, 0x18, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x30,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF8, 0x83, 0xC1, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x30,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF8, 0xF0, 0x83,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x07, 0x0F, 0xFE, 0x1F, 0x7E, 0x60, 0xC0, 0xFF, 0x8F, 0x07, 0xFF, 0x1F, 0x3C,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF8, 0xF0, 0xE0, 0xC1, 0x8F, 0xFF, 0x0F, 0x1E, 0x3C, 0xF8, 0xF1, 0xFF, 0x91,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x83, 0x9F, 0x1F, 0x1E, 0x3C, 0xF8, 0x39, 0x7F, 0x7E, 0xCE, 0x9C, 0x39, 0xFF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xCF, 0x7F, 0x9E, 0xF3, 0xFF, 0xC9, 0x9C, 0xFF, 0x73, 0xE6, 0x7C, 0x9E, 0x33,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xE7, 0xC9, 0xFF, 0x33, 0x73, 0xE6, 0x3C, 0xF9, 0x3F, 0x73, 0xCE, 0xC3, 0xCF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0x73, 0xE6, 0x7C, 0xCE, 0x9F, 0x9F, 0xFF, 0xF3, 0xE7, 0xFF, 0xF3, 0x9F, 0xE7,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xFF, 0x7F, 0x3E, 0xE7, 0xFF, 0xCF, 0xF9, 0x9F, 0xE7, 0xCF, 0x7F, 0xFE, 0xFF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xCC, 0x9C, 0x39, 0xCF, 0xFF, 0xCF, 0x9C, 0x7F, 0xE6, 0xF3, 0xFC, 0xF9, 0xFF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF3, 0xE7, 0xE7, 0x3F, 0x7E, 0xFC, 0xFF, 0xFC, 0xE7, 0xF3, 0xFF, 0x9F, 0xCF,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF9, 0xFF, 0x78, 0xFE, 0xE7, 0xF9, 0xF3, 0x9F, 0xFF, 0x3F, 0x33, 0x67, 0xCE,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF3, 0xFF, 0x33, 0xE7, 0xCF, 0xF3, 0x3C, 0x7F, 0xFE, 0xFF, 0xFC, 0x99, 0x01,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xE7, 0xCF, 0xFF, 0x3F, 0xFD, 0xF9, 0xF9, 0xFF, 0xE7, 0x73, 0xFE, 0x9F, 0x1F,
b6251cd7c3ee1990339b293f31a18bccb5602ef8vboxsync 0xF0, 0x79, 0xC0, 0xFC, 0xE7, 0xFF, 0xCF, 0xCC, 0x99, 0xF3, 0xFC, 0xFF, 0xCC,
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
PDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
#ifdef IN_GC
PDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
#ifdef IN_RING0
PDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
#ifdef IN_RING3
# ifdef VBE_NEW_DYN_LIST
PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
#ifndef VBOX
#include "vl.h"
#include "vga_int.h"
#ifdef LOG_ENABLED
#define DEBUG_BOCHS_VBE
#ifdef VBOX
#ifdef VBOX
((uint32_t)( \
#ifdef WORDS_BIGENDIAN
#define PAT(x) (x)
#ifdef WORDS_BIGENDIAN
#define BIG 0
#ifdef WORDS_BIGENDIAN
#ifdef WORDS_BIGENDIAN
#define PAT(x) (x)
#ifndef VBOX
int vga_io_memory;
/* check port range access depending on color/monochrome mode */
switch(addr) {
if (s->ar_flip_flop == 0) {
val = 0;
val = 0;
#ifdef DEBUG_VGA_REG
s->dac_sub_index = 0;
s->dac_read_index++;
#ifdef DEBUG_VGA_REG
#ifdef DEBUG_VGA_REG
s->ar_flip_flop = 0;
#if defined(DEBUG_VGA)
return val;
int index;
#ifdef DEBUG_VGA
/* check port range access depending on color/monochrome mode */
switch(addr) {
if (s->ar_flip_flop == 0) {
switch(index) {
#ifndef VBOX
#ifdef DEBUG_VGA_REG
s->dac_sub_index = 0;
s->dac_sub_index = 0;
s->dac_state = 0;
s->dac_sub_index = 0;
s->dac_write_index++;
#ifdef DEBUG_VGA_REG
#ifdef DEBUG_VGA_REG
switch(s->cr_index) {
#ifdef CONFIG_BOCHS_VBE
return val;
switch(s->vbe_index) {
case VBE_DISPI_INDEX_XRES:
case VBE_DISPI_INDEX_YRES:
case VBE_DISPI_INDEX_BPP:
val = 0;
#ifdef DEBUG_BOCHS_VBE
return val;
#ifdef DEBUG_BOCHS_VBE
switch(s->vbe_index) {
case VBE_DISPI_INDEX_ID:
#ifdef VBOX
case VBE_DISPI_INDEX_XRES:
#ifdef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
case VBE_DISPI_INDEX_YRES:
#ifdef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
case VBE_DISPI_INDEX_BPP:
if (val == 0)
#ifdef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
case VBE_DISPI_INDEX_BANK:
case VBE_DISPI_INDEX_ENABLE:
#ifndef IN_RING3
return VINF_IOM_HC_IOPORT_WRITE;
int h, shift_control;
#ifdef VBOX
#ifndef KEEP_SCAN_LINE_LENGTH
#ifndef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
#ifndef VBOX
shift_control = 0;
#ifdef VBOX
#ifdef VBOX
s->bank_offset = 0;
int w, h, line_offset;
return VINF_SUCCESS;
w = val;
return VINF_SUCCESS;
case VBE_DISPI_INDEX_X_OFFSET:
case VBE_DISPI_INDEX_Y_OFFSET:
#ifdef VBOX
#ifndef IN_RING3
return VINF_IOM_HC_IOPORT_WRITE;
return VINF_SUCCESS;
#ifdef VBOX
#ifdef DEBUG_VGA_MEM
switch(memory_map_mode) {
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
#ifndef VBOX
#ifndef VBOX
#ifndef VBOX
#ifdef DEBUG_VGA_MEM
return ret;
#ifndef VBOX
uint32_t v;
#ifdef TARGET_WORDS_BIGENDIAN
uint32_t v;
#ifdef TARGET_WORDS_BIGENDIAN
#ifdef VBOX
#ifdef DEBUG_VGA_MEM
switch(memory_map_mode) {
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef VBOX
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
#ifdef DEBUG_VGA_MEM
#ifndef VBOX
#ifndef VBOX
#ifndef VBOX
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
#ifdef DEBUG_VGA_MEM
#ifndef VBOX
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
switch(write_mode) {
goto do_write;
switch(func_select) {
#ifndef VBOX
#ifdef DEBUG_VGA_MEM
#ifndef VBOX
return VINF_SUCCESS;
#ifndef VBOX
#ifdef TARGET_WORDS_BIGENDIAN
#ifdef TARGET_WORDS_BIGENDIAN
static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
#include "DevVGATmpl.h"
#include "DevVGATmpl.h"
#include "DevVGATmpl.h"
#include "DevVGATmpl.h"
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
int full_update, i;
full_update = 0;
v = s->ar[i];
return full_update;
int full_update, i;
int wide_dac;
full_update = 0;
if (wide_dac)
return full_update;
#ifdef CONFIG_BOCHS_VBE
#ifdef VBOX
int full_update;
full_update = 0;
return full_update;
switch(depth) {
#ifndef VBOX
#ifndef VBOX
#ifndef VBOX
s->plane_updated = 0;
#ifndef VBOX
#ifndef VBOX
#ifndef VBOX
return VINF_SUCCESS;
#ifndef VBOX
return rc;
#ifndef VBOX
#ifndef VBOX
#ifdef WORDS_BIGENDIAN
dup9 = 0;
#ifndef VBOX
ch_attr_ptr++;
#ifndef VBOX
#ifdef VBOX
return VINF_SUCCESS;
int ret;
#ifdef CONFIG_BOCHS_VBE
ret = 0;
return ret;
#ifdef CONFIG_BOCHS_VBE
#ifndef VBOX
#ifdef VBOX
return rc;
if (s->shift_control == 0)
update_palette16(s);
update_palette16(s);
return VINF_SUCCESS;
#ifndef VBOX
uint8_t *d;
bool offsets_changed;
if (shift_control == 0) {
v = VGA_DRAW_LINE4D2;
v = VGA_DRAW_LINE4;
v = VGA_DRAW_LINE2D2;
v = VGA_DRAW_LINE2;
switch(s->get_bpp(s)) {
v = VGA_DRAW_LINE8D2;
v = VGA_DRAW_LINE8;
v = VGA_DRAW_LINE15;
v = VGA_DRAW_LINE16;
v = VGA_DRAW_LINE24;
v = VGA_DRAW_LINE32;
#ifndef VBOX
|| offsets_changed)
if (rc != VINF_SUCCESS) /* Return any rc, particularly VINF_VGA_RESIZE_IN_PROGRESS, to the caller. */
return rc;
if (s->cursor_invalidate)
s->cursor_invalidate(s);
#ifndef VBOX
#ifndef VBOX
y1 = 0;
for(y = 0; y < height; y++) {
#ifndef VBOX
if (update) {
if (y_start < 0)
y_start = y;
#ifndef VBOX
if (s->fRenderVRAM)
if (s->cursor_draw_line)
s->cursor_draw_line(s, d, y);
if (y_start >= 0) {
#ifndef VBOX
if (!multi_run) {
y1++;
if (y2 == 0) {
--y2;
multi_run--;
addr1 = 0;
d += linesize;
if (y_start >= 0) {
#ifndef VBOX
#ifndef VBOX
#ifdef VBOX
return VINF_SUCCESS;
#ifndef VBOX
int i, w, val;
uint8_t *d;
if (!full_update)
val = 0;
for(i = 0; i < s->last_scr_height; i++) {
int i, w, val;
uint8_t *d;
if (!full_update)
val = 0;
for(i = 0; i < (int)s->last_scr_height; i++) {
d += cbScanline;
#define GMODE_TEXT 0
#ifndef VBOX
void vga_update_display(void)
#ifndef VBOX
#ifndef VBOX
full_update = 0;
switch(graphic_mode) {
case GMODE_TEXT:
#ifdef VBOX
rc =
case GMODE_GRAPH:
#ifdef VBOX
rc =
case GMODE_BLANK:
#ifdef VBOX
return rc;
#ifndef VBOX
void vga_invalidate_display(void)
#ifndef VBOX
#ifdef CONFIG_BOCHS_VBE
for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
qemu_put_byte(f, 0);
int is_vbe, i;
#ifndef VBOX
return -EINVAL;
#ifdef CONFIG_BOCHS_VBE
if (!is_vbe)
#ifndef VBOX
return -EINVAL;
for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
if (is_vbe)
#ifndef VBOX
return -EINVAL;
static void vga_init_expand(void)
expand4[i] = v;
expand2[i] = v;
expand4to8[i] = v;
#ifdef VBOX
vga_reset(s);
vga_state = s;
VGAState *s;
s->bank_offset = 0;
#ifdef CONFIG_BOCHS_VBE
#if defined (TARGET_I386)
if (bus) {
PCIDevice *d;
sizeof(PCIDevice),
#ifdef CONFIG_BOCHS_VBE
#ifndef VBOX
#ifndef VBOX
if (!s->data)
vga_save_w = w;
vga_save_h = h;
int w, int h, int linesize)
FILE *f;
d = d1;
v = *(uint32_t *)d;
fclose(f);
//@@TODO (dmik): implement stretching/shrinking!
int bpp;
for (y = 0; y < height; y ++)
PDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
#ifndef IN_RING3
return VINF_IOM_HC_IOPORT_WRITE;
#ifdef VBE_BYTEWISE_IO
if (!s->fWriteVBEData)
s->fWriteVBEData = false;
s->fWriteVBEData = true;
return VINF_SUCCESS;
s->fWriteVBEData = false;
// Log(("vgaIOPortWriteVBEData: VBE_DISPI_INDEX_ENABLE & VBE_DISPI_ENABLED - Switching to host...\n"));
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
#ifdef VBE_BYTEWISE_IO
if (!s->fWriteVBEIndex)
s->fWriteVBEIndex = true;
return VINF_SUCCESS;
s->fWriteVBEIndex = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
#ifdef VBE_BYTEWISE_IO
if (!s->fReadVBEData)
s->fReadVBEData = true;
return VINF_SUCCESS;
s->fReadVBEData = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
#ifdef VBE_BYTEWISE_IO
if (!s->fReadVBEIndex)
s->fReadVBEIndex = true;
return VINF_SUCCESS;
s->fReadVBEIndex = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
* Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM and from the inside of VGADeviceGC.cpp.
PDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems)
uint32_t b;
for (i = 0; i < cbItem; i++)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
GCPhysAddr++;
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
GCPhysAddr++;
#ifdef IN_GC
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
for (i = 0; i < cbItem; i++)
for (i = 0; i < cbItem; i++)
for (i = 0; i < cbItem; i++)
for (i = 0; i < cbItem; i++)
while (cItems-- > 0)
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[0] & write_mask);
GCPhysAddr++;
while (cItems-- > 0)
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[0] & write_mask);
GCPhysAddr++;
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[1] & write_mask);
GCPhysAddr++;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[i] & write_mask);
GCPhysAddr++;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
switch (cb)
while (cb-- > 0)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
switch (cb)
return rc;
int rc;
#ifndef IN_RING3
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
#ifdef IN_GC
PDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
PDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
static DECLCALLBACK(int) vgaR3LFBAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
int rc;
return VINF_PGM_HANDLER_DO_DEFAULT;
return rc;
PDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (u32)
if (lastWasNotNewline == 0)
lastWasNotNewline = 0;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef IN_RING3
# ifdef VBE_NEW_DYN_LIST
PDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VINF_SUCCESS;
*pu32 = 0;
Log(("vbeIOPortReadVBEExtra: Requested address is out of VBE data!!! Address=%#x(%d) cbVBEExtraData=%#x(%d)\n",
pThis->u16VBEExtraAddress, pThis->u16VBEExtraAddress, pThis->cbVBEExtraData, pThis->cbVBEExtraData));
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
uint16_t i;
case BMP_HEADER_OS21:
case BMP_HEADER_OS22:
case BMP_HEADER_WIN3:
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
const uint8_t *pu8Pal = pThis->pu8Logo + sizeof(LOGOHDR) + sizeof(BMPINFO) + pWinHdr->Size; /* ASSUMES Size location (safe) */
uint16_t j;
u32Pal |= b;
return VINF_SUCCESS;
static void vbeShowBitmap(uint16_t cBits, uint16_t xLogo, uint16_t yLogo, uint16_t cxLogo, uint16_t cyLogo, uint8_t iStep,
uint16_t i;
switch (cBits)
cbPadBytes = 0;
cbPadBytes = 0;
uint8_t j = 0, c = 0;
while (cyLeft-- > 0)
for (i = 0; i < cxLogo; i++)
switch (cBits)
c = *pu8Src++;
*pu8TmpPtr++;
c = *pu8Src++;
*pu8TmpPtr++;
*pu8TmpPtr++;
*pu8TmpPtr++;
PDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
case LOGO_CMD_SET_OFFSET:
case LOGO_CMD_SHOW_BMP:
for (int i = 0; i < LOGO_MAX_WIDTH; i++)
for (int j = 0; j < LOGO_MAX_HEIGHT; j++)
*pu32TmpPtr++ = 0;
for (int i = 0; i < LOGO_MAX_WIDTH; i++)
for (int j = 0; j < LOGO_MAX_HEIGHT; j++)
return VINF_SUCCESS;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
PRTUINT64U p;
Log(("vbeIOPortReadCMDLogo: Requested address is out of Logo data!!! offLogoData=%#x(%d) cbLogo=%#x(%d)\n",
return VINF_SUCCESS;
switch (cb)
default: AssertFailed(); break;
Log(("vbeIOPortReadCMDLogo: LogoOffset=%#x(%d) cb=%#x %.*Vhxs\n", pThis->offLogoData, pThis->offLogoData, cb, cb, pu32));
return VINF_SUCCESS;
switch (enmInterface)
case PDMINTERFACE_BASE:
return NULL;
static DECLCALLBACK(int) vgaDummyResize(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy)
return VINF_SUCCESS;
static DECLCALLBACK(void) vgaDummyUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
#define IDISPLAYPORT_2_VGASTATE(pInterface) ( (PVGASTATE)((uintptr_t)pInterface - RT_OFFSETOF(VGASTATE, Port)) )
#ifdef DEBUG_sunlover
return rc;
return VINF_SUCCESS;
#ifdef DEBUG_sunlover
return rc;
static DECLCALLBACK(int) vgaPortSetRefreshRate(PPDMIDISPLAYPORT pInterface, uint32_t cMilliesInterval)
if (cMilliesInterval)
if (!pcBits)
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaPortSnapshot(PPDMIDISPLAYPORT pInterface, void *pvData, size_t cbData, uint32_t *pcx, uint32_t *pcy, size_t *pcbData)
/* @todo r=sunlover: replace the method with a direct VRAM rendering like in vgaPortUpdateDisplayRect. */
LogFlow(("vgaPortSnapshot: pvData=%p cbData=%d pcx=%p pcy=%p pcbData=%p\n", pvData, cbData, pcx, pcy, pcbData));
if (!pvData)
return VERR_INVALID_PARAMETER;
Log(("vgaPortSnapshot: %d bytes are required, a buffer of %d bytes is profiled.\n", cbRequired, cbData));
return VERR_BUFFER_OVERFLOW;
return rc;
if (pcx)
if (pcy)
if (pcbData)
LogFlow(("vgaPortSnapshot: returns VINF_SUCCESS (cx=%d cy=%d cbData=%d)\n", Connector.cx, Connector.cy, cbRequired));
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaPortDisplayBlt(PPDMIDISPLAYPORT pInterface, const void *pvData, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
if ( pvData
vga_draw_line_func *pfnVgaDrawLine = vga_draw_line_table[VGA_DRAW_LINE32 * 4 + get_depth_index(pThis->pDrv->cBits)];
while (cyLeft-- > 0)
return rc;
static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface, int32_t x, int32_t y, uint32_t w, uint32_t h)
uint32_t v;
#ifdef DEBUG_sunlover
if (!s->fRenderVRAM)
#ifdef DEBUG_sunlover
#ifndef VBOX
#ifndef VBOX
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
switch(s->get_bpp(s))
v = VGA_DRAW_LINE8;
v = VGA_DRAW_LINE15;
v = VGA_DRAW_LINE16;
v = VGA_DRAW_LINE24;
v = VGA_DRAW_LINE32;
#ifdef DEBUG_sunlover
LogFlow(("vgaPortUpdateDisplayRect: dst: %p, %d, %d. src: %p, %d, %d\n", pu8Dst, cbLineDst, cbPixelDst, pu8Src, cbLineSrc, cbPixelSrc));
#ifdef DEBUG_sunlover
static DECLCALLBACK(int) vgaR3IORegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
int rc;
LogFlow(("vgaR3IORegionMap: iRegion=%d GCPhysAddress=%RGp cb=%#x enmType=%d\n", iRegion, GCPhysAddress, cb, enmType));
return rc;
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
return VINF_SUCCESS;
char *pchStart;
char *pchEnd;
switch(graphic_mode)
case GMODE_TEXT:
int x_incr;
int line_offset;
# ifdef WORDS_BIGENDIAN
#ifdef CONFIG_BOCHS_VBE
if (offDelta)
switch (iLUN)
pThis->pDrv = (PDMIDISPLAYCONNECTOR*)pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase, PDMINTERFACE_DISPLAY_CONNECTOR);
Log(("%s/%d: warning: no driver attached to LUN #0!\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
return rc;
return VERR_PDM_NO_SUCH_LUN;
switch (iLUN)
static bool s_fExpandDone = false;
int rc;
#ifdef VBE_NEW_DYN_LIST
unsigned cb;
if (!s_fExpandDone)
s_fExpandDone = true;
Log(("VGA: VRamSize=%#x fGCenabled=%RTbool fR0Enabled=%RTbool\n", pThis->vram_size, pThis->fGCEnabled, pThis->fR0Enabled));
rc = PDMR3GetSymbolGCLazy(pVM, pDevIns->pDevReg->szGCMod, "vgaGCLFBAccessHandler", &pThis->RCPtrLFBHandler);
AssertReleaseMsgFailed(("PDMR3GetSymbolGC(, %s, \"vgaGCLFBAccessHandler\",) -> %Rrc\n", pDevIns->pDevReg->szGCMod, rc));
return rc;
rc = PDMDevHlpMMIO2Register(pDevIns, 0 /* iRegion */, pThis->vram_size, 0, (void **)&pThis->vram_ptrR3, "VRam");
pThis->vram_ptrR0 = (RTR0PTR)pThis->vram_ptrR3; /** @todo #1865 Map parts into R0 or just use PGM access (Mac only). */
rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, 0 /* iRegion */, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pRCMapping);
AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", pThis->vram_size, rc), rc);
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3c0, 16, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3c0");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3b4, 2, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3b4");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3ba, 1, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3ba");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3d4, 2, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3d4");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3da, 1, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3da");
return rc;
#ifdef CONFIG_BOCHS_VBE
rc = PDMDevHlpIOPortRegister(pDevIns, 0x1ce, 1, NULL, vgaIOPortWriteVBEIndex, vgaIOPortReadVBEIndex, NULL, NULL, "VGA/VBE - Index");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x1cf, 1, NULL, vgaIOPortWriteVBEData, vgaIOPortReadVBEData, NULL, NULL, "VGA/VBE - Data");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0xff80, 1, NULL, vgaIOPortWriteVBEIndex, vgaIOPortReadVBEIndex, "VGA/VBE - Index Old");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0xff81, 1, NULL, vgaIOPortWriteVBEData, vgaIOPortReadVBEData, "VGA/VBE - Data Old");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x3c0, 16, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3c0 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x3b4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3b4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x3ba, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3ba (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x3d4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3d4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x3da, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3da (GC)");
return rc;
#ifdef CONFIG_BOCHS_VBE
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x1ce, 1, 0, "vgaIOPortWriteVBEIndex", "vgaIOPortReadVBEIndex", NULL, NULL, "VGA/VBE - Index (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x1cf, 1, 0, "vgaIOPortWriteVBEData", "vgaIOPortReadVBEData", NULL, NULL, "VGA/VBE - Data (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0xff80, 1, 0, "vgaIOPortWriteVBEIndex", "vgaIOPortReadVBEIndex", "VGA/VBE - Index Old (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0xff81, 1, 0, "vgaIOPortWriteVBEData", "vgaIOPortReadVBEData", "VGA/VBE - Index Old (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3c0, 16, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3c0 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3b4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3b4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3ba, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3ba (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3d4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3d4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3da, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3da (GC)");
return rc;
#ifdef CONFIG_BOCHS_VBE
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x1ce, 1, 0, "vgaIOPortWriteVBEIndex", "vgaIOPortReadVBEIndex", NULL, NULL, "VGA/VBE - Index (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x1cf, 1, 0, "vgaIOPortWriteVBEData", "vgaIOPortReadVBEData", NULL, NULL, "VGA/VBE - Data (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0xff80, 1, 0, "vgaIOPortWriteVBEIndex", "vgaIOPortReadVBEIndex", "VGA/VBE - Index Old (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0xff81, 1, 0, "vgaIOPortWriteVBEData", "vgaIOPortReadVBEData", "VGA/VBE - Index Old (GC)");
return rc;
rc = PDMDevHlpMMIORegister(pDevIns, 0x000a0000, 0x00020000, 0, vgaMMIOWrite, vgaMMIORead, vgaMMIOFill, "VGA - VGA Video Buffer");
return rc;
rc = PDMDevHlpMMIORegisterGC(pDevIns, 0x000a0000, 0x00020000, 0, "vgaMMIOWrite", "vgaMMIORead", "vgaMMIOFill");
return rc;
rc = PDMDevHlpMMIORegisterR0(pDevIns, 0x000a0000, 0x00020000, 0, "vgaMMIOWrite", "vgaMMIORead", "vgaMMIOFill");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, VBE_PRINTF_PORT, 1, NULL, vgaIOPortWriteBIOS, vgaIOPortReadBIOS, NULL, NULL, "VGA BIOS debug/panic");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, VBE_PRINTF_PORT, 1, 0, "vgaIOPortWriteBIOS", "vgaIOPortReadBIOS", NULL, NULL, "VGA BIOS debug/panic");
return rc;
AssertReleaseMsg(g_cbVgaBiosBinary <= _64K && g_cbVgaBiosBinary >= 32*_1K, ("g_cbVgaBiosBinary=%#x\n", g_cbVgaBiosBinary));
AssertReleaseMsg(RT_ALIGN_Z(g_cbVgaBiosBinary, PAGE_SIZE) == g_cbVgaBiosBinary, ("g_cbVgaBiosBinary=%#x\n", g_cbVgaBiosBinary));
return rc;
rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance, 1 /* version */, sizeof(*pThis),
return rc;
return rc;
/*AssertMsg(pThis->Dev.devfn == 16 || iInstance != 0, ("pThis->Dev.devfn=%d\n", pThis->Dev.devfn));*/
Log(("!!WARNING!!: pThis->dev.devfn=%d (ignore if testcase or not started by Main)\n", pThis->Dev.devfn));
rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0 /* iRegion */, pThis->vram_size, PCI_ADDRESS_SPACE_MEM_PREFETCH, vgaR3IORegionMap);
return rc;
rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, vgaTimerRefresh, "VGA Refresh Timer", &pThis->RefreshTimer);
return rc;
return rc;
#ifdef VBE_NEW_DYN_LIST
cyReduction = 0;
cCustomModes = 0;
return VERR_NO_MEMORY;
#ifndef VRAM_SIZE_FIX
for (i = 0; i < MODE_INFO_SIZE; i++)
* pixelWidth;
pCurMode++;
if (cyReduction)
#ifndef VRAM_SIZE_FIX
pCurMode++;
if (cCustomModes)
AssertMsgFailed(("Configuration error: Invalid mode data '%s' for '%s'! cBits=%d\n", pszExtraData, szExtraDataKey, cBits));
return VERR_VGA_INVALID_CUSTOM_MODE;
#ifdef VRAM_SIZE_FIX
AssertMsgFailed(("Configuration error: custom video mode %dx%dx%dbits is too large for the virtual video memory of %dMb. Please increase the video memory size.\n",
return VERR_VGA_INVALID_CUSTOM_MODE;
switch (cBits)
pDefMode++;
switch (cBits)
pCurMode++;
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, VBE_EXTRA_PORT, 1, NULL, vbeIOPortWriteVBEExtra, vbeIOPortReadVBEExtra, NULL, NULL, "VBE BIOS Extra Data");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, LOGO_IO_PORT, 1, NULL, vbeIOPortWriteCMDLogo, vbeIOPortReadCMDLogo, NULL, NULL, "BIOS Logo");
return rc;
pThis->pu8Logo = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, RT_MAX(pThis->cbLogo, g_cbVgaDefBiosLogo + sizeof(LogoHdr)));
STAM_REG(pVM, &pThis->StatGCMemoryRead, STAMTYPE_PROFILE, "/Devices/VGA/GC/Memory/Read", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryRead() body.");
STAM_REG(pVM, &pThis->StatGCMemoryWrite, STAMTYPE_PROFILE, "/Devices/VGA/GC/Memory/Write", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryWrite() body.");
STAM_REG(pVM, &pThis->StatGCIOPortRead, STAMTYPE_PROFILE, "/Devices/VGA/GC/IOPort/Read", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCIOPortRead() body.");
STAM_REG(pVM, &pThis->StatGCIOPortWrite, STAMTYPE_PROFILE, "/Devices/VGA/GC/IOPort/Write", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCIOPortWrite() body.");
return rc;
#ifdef VBE_NEW_DYN_LIST
return VINF_SUCCESS;
PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0,
sizeof(VGASTATE),
NULL,
NULL,
NULL,
NULL,
NULL,