DevVGA.cpp revision b11c03e57fb23a106e2e331fd8e7bfe39bc910db
43af8389304c77c3d4db525de8907cb74207c380vboxsync * DevVGA - VBox VGA/VESA device.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
43af8389304c77c3d4db525de8907cb74207c380vboxsync * available from http://www.virtualbox.org. This file is free software;
43af8389304c77c3d4db525de8907cb74207c380vboxsync * you can redistribute it and/or modify it under the terms of the GNU
43af8389304c77c3d4db525de8907cb74207c380vboxsync * General Public License (GPL) as published by the Free Software
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
43af8389304c77c3d4db525de8907cb74207c380vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
43af8389304c77c3d4db525de8907cb74207c380vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
43af8389304c77c3d4db525de8907cb74207c380vboxsync * additional information or have any questions.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * --------------------------------------------------------------------
43af8389304c77c3d4db525de8907cb74207c380vboxsync * This code is based on:
43af8389304c77c3d4db525de8907cb74207c380vboxsync * QEMU VGA Emulator.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Copyright (c) 2003 Fabrice Bellard
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
43af8389304c77c3d4db525de8907cb74207c380vboxsync * of this software and associated documentation files (the "Software"), to deal
43af8389304c77c3d4db525de8907cb74207c380vboxsync * in the Software without restriction, including without limitation the rights
43af8389304c77c3d4db525de8907cb74207c380vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43af8389304c77c3d4db525de8907cb74207c380vboxsync * copies of the Software, and to permit persons to whom the Software is
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * furnished to do so, subject to the following conditions:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * The above copyright notice and this permission notice shall be included in
43af8389304c77c3d4db525de8907cb74207c380vboxsync * all copies or substantial portions of the Software.
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43af8389304c77c3d4db525de8907cb74207c380vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43af8389304c77c3d4db525de8907cb74207c380vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43af8389304c77c3d4db525de8907cb74207c380vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43af8389304c77c3d4db525de8907cb74207c380vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43af8389304c77c3d4db525de8907cb74207c380vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
43af8389304c77c3d4db525de8907cb74207c380vboxsync * THE SOFTWARE.
43af8389304c77c3d4db525de8907cb74207c380vboxsync/*******************************************************************************
43af8389304c77c3d4db525de8907cb74207c380vboxsync* Defined Constants And Macros *
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync*******************************************************************************/
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** The default amount of VRAM. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** The maximum amount of VRAM. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** The minimum amount of VRAM. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** The size of the VGA GC mapping.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * This is supposed to be all the VGA memory accessible to the guest.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * The initial value was 256KB but NTAllInOne.iso appears to access more
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * thus the limit was upped to 512KB.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @todo Someone with some VGA knowhow should make a better guess at this value.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Converts a vga adaptor state pointer to a device instance pointer. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#define VGASTATE2DEVINS(pVgaState) ((pVgaState)->CTX_SUFF(pDevIns))
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Use VBE bytewise I/O */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Use VBE new dynamic mode list.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * If this is not defined, no checks are carried out to see if the modes all
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * fit into the framebuffer! See the VRAM_SIZE_FIX define. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Check that the video modes fit into virtual video memory.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * Only works when VBE_NEW_DYN_LIST is defined! */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Some fixes to ensure that logical scan-line lengths are not overwritten. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Check buffer if an VRAM offset is within the right range or not. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), VINF_SUCCESS); \
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log2(("%Rfn[%d]: %RX32 -> R3\n", __PRETTY_FUNCTION__, __LINE__, (off))); \
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync } while (0)
43af8389304c77c3d4db525de8907cb74207c380vboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), VINF_SUCCESS)
43af8389304c77c3d4db525de8907cb74207c380vboxsync/** Check buffer if an VRAM offset is within the right range or not. */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync# define VERIFY_VRAM_READ_OFF_RETURN(pThis, off, rcVar) \
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), 0xff); \
43af8389304c77c3d4db525de8907cb74207c380vboxsync Log2(("%Rfn[%d]: %RX32 -> R3\n", __PRETTY_FUNCTION__, __LINE__, (off))); \
43af8389304c77c3d4db525de8907cb74207c380vboxsync return 0; \
43af8389304c77c3d4db525de8907cb74207c380vboxsync } while (0)
43af8389304c77c3d4db525de8907cb74207c380vboxsync# define VERIFY_VRAM_READ_OFF_RETURN(pThis, off, rcVar) \
43af8389304c77c3d4db525de8907cb74207c380vboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), 0xff)
43af8389304c77c3d4db525de8907cb74207c380vboxsync/*******************************************************************************
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync* Header Files *
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync*******************************************************************************/
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#if defined(VBE_NEW_DYN_LIST) && defined(IN_RING3) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
43af8389304c77c3d4db525de8907cb74207c380vboxsync/*******************************************************************************
43af8389304c77c3d4db525de8907cb74207c380vboxsync* Structures and Typedefs *
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync*******************************************************************************/
43af8389304c77c3d4db525de8907cb74207c380vboxsync/** BMP File Format Bitmap Header. */
43af8389304c77c3d4db525de8907cb74207c380vboxsynctypedef struct
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/** Pointer to a bitmap header*/
43af8389304c77c3d4db525de8907cb74207c380vboxsync/** OS/2 1.x Information Header Format. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsynctypedef struct
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/** Pointer to a OS/2 1.x header format */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/** OS/2 2.0 Information Header Format. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsynctypedef struct
6efcec753717bae68ada4b060466934b111739fdvboxsync uint32_t Compression; /* Compression Scheme (0=none) */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
6efcec753717bae68ada4b060466934b111739fdvboxsync uint32_t ClrImportant; /* Number of Important Colors */
6efcec753717bae68ada4b060466934b111739fdvboxsync uint16_t Reserved; /* Reserved FIelds (always 0) */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint16_t Rendering; /* Halftone Algorithm Used on Image */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t ColorEncoding; /* Color Table Format (always 0) */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t Identifier; /* Misc. Field for Application Use */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/** Pointer to a OS/2 2.0 header format */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/** Windows 3.x Information Header Format. */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsynctypedef struct
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t Compression; /* Compression Scheme (0=none) */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
6efcec753717bae68ada4b060466934b111739fdvboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync uint32_t ClrImportant; /* Number of Important Colors */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/** Pointer to a Windows 3.x header format */
6efcec753717bae68ada4b060466934b111739fdvboxsync/** @name BMP compressions.
6efcec753717bae68ada4b060466934b111739fdvboxsync/** @name BMP header sizes.
6efcec753717bae68ada4b060466934b111739fdvboxsync/** The BIOS boot menu text position, X. */
6efcec753717bae68ada4b060466934b111739fdvboxsync/** The BIOS boot menu text position, Y. */
6efcec753717bae68ada4b060466934b111739fdvboxsync/** Width of the "Press F12 to select boot device." bitmap.
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync Anything that exceeds the limit of F12BootText below is filled with
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync background. */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/** Height of the boot device selection bitmap, see LOGO_F12TEXT_WIDTH. */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/** The BIOS logo delay time (msec). */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync#define LOGO_MAX_SIZE LOGO_MAX_WIDTH * LOGO_MAX_HEIGHT * 4
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/*******************************************************************************
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync* Global Variables *
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync*******************************************************************************/
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync/* "Press F12 to select boot device." bitmap. */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x0F, 0x7C,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF8, 0xF0, 0x01, 0xE0, 0x81, 0x9F, 0x3F, 0x00, 0x70, 0xF8, 0x00, 0xE0, 0xC3,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x07, 0x0F, 0x1F, 0x3E, 0x70, 0x00, 0xF0, 0xE1, 0xC3, 0x07, 0x0E, 0x00, 0x6E,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x7C, 0x60, 0xE0, 0xE1, 0xC3, 0x07, 0xC6, 0x80, 0x81, 0x31, 0x63, 0xC6, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x30, 0x80, 0x61, 0x0C, 0x00, 0x36, 0x63, 0x00, 0x8C, 0x19, 0x83, 0x61, 0xCC,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x18, 0x36, 0x00, 0xCC, 0x8C, 0x19, 0xC3, 0x06, 0xC0, 0x8C, 0x31, 0x3C, 0x30,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x8C, 0x19, 0x83, 0x31, 0x60, 0x60, 0x00, 0x0C, 0x18, 0x00, 0x0C, 0x60, 0x18,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x80, 0xC1, 0x18, 0x00, 0x30, 0x06, 0x60, 0x18, 0x30, 0x80, 0x01, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x33, 0x63, 0xC6, 0x30, 0x00, 0x30, 0x63, 0x80, 0x19, 0x0C, 0x03, 0x06, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x0C, 0x18, 0x18, 0xC0, 0x81, 0x03, 0x00, 0x03, 0x18, 0x0C, 0x00, 0x60, 0x30,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x06, 0x00, 0x87, 0x01, 0x18, 0x06, 0x0C, 0x60, 0x00, 0xC0, 0xCC, 0x98, 0x31,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x0C, 0x00, 0xCC, 0x18, 0x30, 0x0C, 0xC3, 0x80, 0x01, 0x00, 0x03, 0x66, 0xFE,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x18, 0x30, 0x00, 0xC0, 0x02, 0x06, 0x06, 0x00, 0x18, 0x8C, 0x01, 0x60, 0xE0,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x0F, 0x86, 0x3F, 0x03, 0x18, 0x00, 0x30, 0x33, 0x66, 0x0C, 0x03, 0x00, 0x33,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFE, 0x0C, 0xC3, 0x30, 0xE0, 0x0F, 0xC0, 0x87, 0x9B, 0x31, 0x63, 0xC6, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF0, 0x80, 0x01, 0x03, 0x00, 0x06, 0x63, 0x00, 0x8C, 0x19, 0x83, 0x61, 0xCC,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x18, 0x06, 0x00, 0x6C, 0x8C, 0x19, 0xC3, 0x00, 0x80, 0x8D, 0x31, 0xC3, 0x30,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x8C, 0x19, 0x03, 0x30, 0xB3, 0xC3, 0x87, 0x0F, 0x1F, 0x00, 0x2C, 0x60, 0x80,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x01, 0xE0, 0x87, 0x0F, 0x00, 0x3E, 0x7C, 0x60, 0xF0, 0xE1, 0xE3, 0x07, 0x00,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0x0F, 0x3E, 0x7C, 0xFC, 0x00, 0xC0, 0xC3, 0xC7, 0x30, 0x0E, 0x3E, 0x7C, 0x00,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x1E, 0xC0, 0x00, 0x60, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x0C, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0xC0, 0x0C, 0x87, 0x31, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x06, 0x00, 0x00, 0x18, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x30,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF8, 0x83, 0xC1, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x30,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF8, 0xF0, 0x83,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x07, 0x0F, 0xFE, 0x1F, 0x7E, 0x60, 0xC0, 0xFF, 0x8F, 0x07, 0xFF, 0x1F, 0x3C,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF8, 0xF0, 0xE0, 0xC1, 0x8F, 0xFF, 0x0F, 0x1E, 0x3C, 0xF8, 0xF1, 0xFF, 0x91,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x83, 0x9F, 0x1F, 0x1E, 0x3C, 0xF8, 0x39, 0x7F, 0x7E, 0xCE, 0x9C, 0x39, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xCF, 0x7F, 0x9E, 0xF3, 0xFF, 0xC9, 0x9C, 0xFF, 0x73, 0xE6, 0x7C, 0x9E, 0x33,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xE7, 0xC9, 0xFF, 0x33, 0x73, 0xE6, 0x3C, 0xF9, 0x3F, 0x73, 0xCE, 0xC3, 0xCF,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0x73, 0xE6, 0x7C, 0xCE, 0x9F, 0x9F, 0xFF, 0xF3, 0xE7, 0xFF, 0xF3, 0x9F, 0xE7,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0xFF, 0x7F, 0x3E, 0xE7, 0xFF, 0xCF, 0xF9, 0x9F, 0xE7, 0xCF, 0x7F, 0xFE, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xCC, 0x9C, 0x39, 0xCF, 0xFF, 0xCF, 0x9C, 0x7F, 0xE6, 0xF3, 0xFC, 0xF9, 0xFF,
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsync 0xF3, 0xE7, 0xE7, 0x3F, 0x7E, 0xFC, 0xFF, 0xFC, 0xE7, 0xF3, 0xFF, 0x9F, 0xCF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF9, 0xFF, 0x78, 0xFE, 0xE7, 0xF9, 0xF3, 0x9F, 0xFF, 0x3F, 0x33, 0x67, 0xCE,
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsync 0xF3, 0xFF, 0x33, 0xE7, 0xCF, 0xF3, 0x3C, 0x7F, 0xFE, 0xFF, 0xFC, 0x99, 0x01,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xE7, 0xCF, 0xFF, 0x3F, 0xFD, 0xF9, 0xF9, 0xFF, 0xE7, 0x73, 0xFE, 0x9F, 0x1F,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF0, 0x79, 0xC0, 0xFC, 0xE7, 0xFF, 0xCF, 0xCC, 0x99, 0xF3, 0xFC, 0xFF, 0xCC,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x01, 0xF3, 0x3C, 0xCF, 0x1F, 0xF0, 0x3F, 0x78, 0x64, 0xCE, 0x9C, 0x39, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x0F, 0x7F, 0xFE, 0xFC, 0xFF, 0xF9, 0x9C, 0xFF, 0x73, 0xE6, 0x7C, 0x9E, 0x33,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xE7, 0xF9, 0xFF, 0x93, 0x73, 0xE6, 0x3C, 0xFF, 0x7F, 0x72, 0xCE, 0x3C, 0xCF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x73, 0xE6, 0xFC, 0xCF, 0x4C, 0x3C, 0x78, 0xF0, 0xE0, 0xFF, 0xD3, 0x9F, 0x7F,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFE, 0x1F, 0x78, 0xF0, 0xFF, 0xC1, 0x83, 0x9F, 0x0F, 0x1E, 0x1C, 0xF8, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF0, 0xC1, 0x83, 0x03, 0xFF, 0x3F, 0x3C, 0x38, 0xCF, 0xF1, 0xC1, 0x83, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xE1, 0x3F, 0xFF, 0x9F, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x9F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xF3, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xFF, 0xFF, 0x3F, 0xF3, 0x78, 0xCE, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xF9, 0xFF, 0xFF, 0xE7, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xCF,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0x07, 0x7C, 0x3E, 0xF8, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF,
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync 0xFF, 0xFB, 0xFF, 0xF1, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xCF,
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/*******************************************************************************
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync* Internal Functions *
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync*******************************************************************************/
1c434bf12564eb5a885b3f7e230b7638955004cevboxsyncPDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncPDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncPDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncPDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncPDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsyncPDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncPDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
e4bb2f8312bbd05cdb3c4c01406274f946e7b76cvboxsyncPDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
e4bb2f8312bbd05cdb3c4c01406274f946e7b76cvboxsyncPDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsyncPDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsyncPDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
e4bb2f8312bbd05cdb3c4c01406274f946e7b76cvboxsyncPDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsyncPDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsyncPDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsyncPDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsyncPDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
0bb0c0c0e3f9e5fdb3e745715dde1af951c04998vboxsyncPDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* IN_RING3 */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * Set a VRAM page dirty.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param pThis VGA instance data.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param offVRAM The VRAM offset of the page to set.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncDECLINLINE(void) vga_set_dirty(VGAState *pThis, RTGCPHYS offVRAM)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync ASMBitSet(&pThis->au32DirtyBitmap[0], offVRAM >> PAGE_SHIFT);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * Tests if a VRAM page is dirty.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @returns true if dirty.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @returns false if clean.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param pThis VGA instance data.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param offVRAM The VRAM offset of the page to check.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncDECLINLINE(bool) vga_is_dirty(VGAState *pThis, RTGCPHYS offVRAM)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync return ASMBitTest(&pThis->au32DirtyBitmap[0], offVRAM >> PAGE_SHIFT);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * Reset dirty flags in a give range.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param pThis VGA instance data.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param offVRAMStart Offset into the VRAM buffer of the first page.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * @param offVRAMEnd Offset into the VRAM buffer of the last page - exclusive.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncDECLINLINE(void) vga_reset_dirty(VGAState *pThis, RTGCPHYS offVRAMStart, RTGCPHYS offVRAMEnd)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync ASMBitClearRange(&pThis->au32DirtyBitmap[0], offVRAMStart >> PAGE_SHIFT, offVRAMEnd >> PAGE_SHIFT);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* !VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync//#define DEBUG_VGA
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync//#define DEBUG_VGA_MEM
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync//#define DEBUG_VGA_REG
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync/* force some bits to zero */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#define PAT(x) (x)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#define PAT(x) (x)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX && IN_RING3 */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* !VBOX */
b385d10d09ba23d12c2baa62bb82381641e5a792vboxsyncstatic uint32_t vga_ioport_read(void *opaque, uint32_t addr)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* check port range access depending on color/monochrome mode */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3c0:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync if (s->ar_flip_flop == 0) {
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c1:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c2:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c4:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c5:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("vga: read SR%x = 0x%02x\n", s->sr_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c7:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c8:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c9:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3ca:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3cc:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3ce:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3cf:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("vga: read GR%x = 0x%02x\n", s->gr_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3b4:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3d4:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3b5:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3d5:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("vga: read CR%x = 0x%02x\n", s->cr_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3ba:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3da:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* just toggle to fool polling */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("VGA: read addr=0x%04x data=0x%02x\n", addr, val));
d001743f2d86c2cf54f3afdcc697d1b305dd9d72vboxsyncstatic void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync Log(("VGA: write addr=0x%04x data=0x%02x\n", addr, val));
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* check port range access depending on color/monochrome mode */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 0x3c0:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync if (s->ar_flip_flop == 0) {
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync#else /* VBOX */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c2:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c4:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c5:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("vga: write SR%x = 0x%02x\n", s->sr_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* The VGA region is (could be) affected by this change; reset all aliases we've created. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3c7:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c8:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3c9:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3ce:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3cf:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync Log(("vga: write GR%x = 0x%02x\n", s->gr_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* The VGA region is (could be) affected by this change; reset all aliases we've created. */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3b4:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3d4:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3b5:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync case 0x3d5:
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync Log(("vga: write CR%x = 0x%02x\n", s->cr_index, val));
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync /* handle CR0-7 protection */
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsync /* can always write bit 4 of CR7 */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync switch(s->cr_index) {
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3ba:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync case 0x3da:
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncstatic uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
3a1d76f6489a485dfa7e3784c1fa76b4a53c28afvboxsyncstatic uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* XXX: do not hardcode ? */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync } else if (s->vbe_index == VBE_DISPI_INDEX_VBOX_VIDEO) {
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* Reading from the port means that the old additions are requesting the number of monitors. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncstatic void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsyncstatic int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync Log(("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync s->vbe_line_offset = val * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* XXX: support weird bochs semantics ? */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = s->vbe_line_offset;
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* KEEP_SCAN_LINE_LENGTH defined */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* KEEP_SCAN_LINE_LENGTH defined */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((val + 7) >> 3);
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* XXX: support weird bochs semantics ? */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = s->vbe_line_offset;
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* KEEP_SCAN_LINE_LENGTH defined */
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* The VGA region is (could be) affected by this change; reset all aliases we've created. */
43af8389304c77c3d4db525de8907cb74207c380vboxsync IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
43af8389304c77c3d4db525de8907cb74207c380vboxsync !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* Check the values before we screw up with a resolution which is too big or small. */
43af8389304c77c3d4db525de8907cb74207c380vboxsync cb = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
43af8389304c77c3d4db525de8907cb74207c380vboxsync AssertMsgFailed(("XRES=%d YRES=%d cb=%d vram_size=%d\n",
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_regs[VBE_DISPI_INDEX_XRES], s->vbe_regs[VBE_DISPI_INDEX_YRES], cb, s->vram_size));
43af8389304c77c3d4db525de8907cb74207c380vboxsync return VINF_SUCCESS; /* Note: silent failure like before */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#else /* KEEP_SCAN_LINE_LENGTH defined */
43af8389304c77c3d4db525de8907cb74207c380vboxsync AssertMsgFailed(("VIRT WIDTH=%d YRES=%d cb=%d vram_size=%d\n",
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH], s->vbe_regs[VBE_DISPI_INDEX_YRES], cb, s->vram_size));
43af8389304c77c3d4db525de8907cb74207c380vboxsync return VINF_SUCCESS; /* Note: silent failure like before */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* KEEP_SCAN_LINE_LENGTH defined */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#endif /* KEEP_SCAN_LINE_LENGTH not defined */
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* clear the screen (should be done in BIOS) */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
43af8389304c77c3d4db525de8907cb74207c380vboxsync#else /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* we initialize the VGA graphic mode (should be done
43af8389304c77c3d4db525de8907cb74207c380vboxsync in BIOS) */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
3904c2d16fea12be79d817b255d59d480658b799vboxsync /* width */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
3904c2d16fea12be79d817b255d59d480658b799vboxsync /* height (only meaningful if < 1024) */
3904c2d16fea12be79d817b255d59d480658b799vboxsync /* line compare to 1023 */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* sunlover 30.05.2007
43af8389304c77c3d4db525de8907cb74207c380vboxsync * The ar_index remains with bit 0x20 cleared after a switch from fullscreen
43af8389304c77c3d4db525de8907cb74207c380vboxsync * DOS mode on Windows XP guest. That leads to GMODE_BLANK in vga_update_display.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * But the VBE mode is graphics, so not a blank anymore.
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* XXX: the bios should do that */
3904c2d16fea12be79d817b255d59d480658b799vboxsync /* sunlover 21.12.2006
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Here is probably more to reset. When this was executed in GC
43af8389304c77c3d4db525de8907cb74207c380vboxsync * then the *update* functions could not detect a mode change.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * Or may be these update function should take the s->vbe_regs[s->vbe_index]
43af8389304c77c3d4db525de8907cb74207c380vboxsync * into account when detecting a mode change.
43af8389304c77c3d4db525de8907cb74207c380vboxsync * The 'mode reset not detected' problem is now fixed by executing the
43af8389304c77c3d4db525de8907cb74207c380vboxsync * VBE_DISPI_INDEX_ENABLE case always in RING3 in order to call the
43af8389304c77c3d4db525de8907cb74207c380vboxsync * LFBChange callback.
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync * LFB video mode is either disabled or changed. This notification
43af8389304c77c3d4db525de8907cb74207c380vboxsync * is used by the display to disable VBVA.
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->pDrv->pfnLFBModeChange(s->pDrv, (val & VBE_DISPI_ENABLED) != 0);
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* The VGA region is (could be) affected by this change; reset all aliases we've created. */
43af8389304c77c3d4db525de8907cb74207c380vboxsync IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* IN_RING3 */
43af8389304c77c3d4db525de8907cb74207c380vboxsync line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* XXX: support weird bochs semantics ? */
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* Changes in the VGA device are minimal. The device is bypassed. The driver does all work. */
43af8389304c77c3d4db525de8907cb74207c380vboxsync else if (val == VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY)
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->pDrv->pfnProcessAdapterData(s->pDrv, s->CTX_SUFF(vram_ptr), s->vram_size);
43af8389304c77c3d4db525de8907cb74207c380vboxsync else if ((val & 0xFFFF0000) == VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE)
43af8389304c77c3d4db525de8907cb74207c380vboxsync s->pDrv->pfnProcessDisplayData(s->pDrv, s->CTX_SUFF(vram_ptr), val & 0xFFFF);
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* IN_RING3 */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync/* called for accesses between 0xa0000 and 0xc0000 */
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr, int *prc)
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsyncuint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#endif /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* convert to VGA memory offset */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync RTGCPHYS GCPhys = addr; /* save original address */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync return 0xff;
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync return 0xff;
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync return 0xff;
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* chain 4 mode : simplest access */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#else /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* If all planes are accessible, then map the page to the frame buffer and make it writable. */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /** @todo only allow read access (doesn't work now) */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync IOMMMIOModifyPage(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), GCPhys, s->GCPhysVRAM + addr, X86_PTE_RW|X86_PTE_P);
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* Set as dirty as write accesses won't be noticed now. */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync# endif /* IN_RC */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync } else if (!(s->sr[4] & 0x04)) { /* Host access is controlled by SR4, not GR5! */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* odd/even mode (aka text mode mapping) */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#else /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* See the comment for a similar line in vga_mem_writeb. */
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync#endif /* VBOX */
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync /* standard VGA latched access */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#else /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync s->latch = ((uint32_t *)s->CTX_SUFF(vram_ptr))[addr];
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#endif /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* read mode 0 */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* read mode 1 */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* !VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync/* called for accesses between 0xa0000 and 0xc0000 */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsyncint vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
43af8389304c77c3d4db525de8907cb74207c380vboxsync int memory_map_mode, plane, write_mode, b, func_select, mask;
43af8389304c77c3d4db525de8907cb74207c380vboxsync /* convert to VGA memory offset */
43af8389304c77c3d4db525de8907cb74207c380vboxsync RTGCPHYS GCPhys = addr; /* save original address */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* chain 4 mode : simplest access */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#else /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* If all planes are accessible, then map the page to the frame buffer and make it writable. */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync IOMMMIOModifyPage(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), GCPhys, s->GCPhysVRAM + addr, X86_PTE_RW | X86_PTE_P);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync# endif /* IN_RC */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync s->plane_updated |= mask; /* only used to detect font change */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync cpu_physical_memory_set_dirty(s->vram_offset + addr);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#else /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync } else if (!(s->sr[4] & 0x04)) { /* Host access is controlled by SR4, not GR5! */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* odd/even mode (aka text mode mapping) */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* 'addr' is offset in a plane, bit 0 selects the plane.
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * Mask the bit 0, convert plane index to vram offset,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync * that is multiply by the number of planes,
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync * and select the plane byte in the vram offset.
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#endif /* VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsync#else /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#endif /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync s->plane_updated |= mask; /* only used to detect font change */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync cpu_physical_memory_set_dirty(s->vram_offset + addr);
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#else /* VBOX */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync#endif /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* standard VGA latched access */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* About 1000 accesses per 10 ms or more will trigger a reschedule
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync * to the recompiler
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync if (u64CurTime - s->u64LastLatchedAccess < 10000000)
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* rotate */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* apply set/reset mask */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* rotate */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync /* apply logical operation */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* nothing to do */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* apply bit mask */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync /* mask data according to sr[2] */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync s->plane_updated |= mask; /* only used to detect font change */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#else /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync (((uint32_t *)s->CTX_SUFF(vram_ptr))[addr] & ~write_mask) |
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#endif /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync Log(("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#else /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync#endif /* VBOX */
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsyncstatic void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
4152e1d3f89dc5e2319a53c242e8e7cfcdf3726evboxsync vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
43af8389304c77c3d4db525de8907cb74207c380vboxsync vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
43af8389304c77c3d4db525de8907cb74207c380vboxsync vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
43af8389304c77c3d4db525de8907cb74207c380vboxsync vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
43af8389304c77c3d4db525de8907cb74207c380vboxsync vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
43af8389304c77c3d4db525de8907cb74207c380vboxsync vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
43af8389304c77c3d4db525de8907cb74207c380vboxsync#endif /* !VBOX */
43af8389304c77c3d4db525de8907cb74207c380vboxsynctypedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
43af8389304c77c3d4db525de8907cb74207c380vboxsynctypedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
43af8389304c77c3d4db525de8907cb74207c380vboxsynctypedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
43af8389304c77c3d4db525de8907cb74207c380vboxsync return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
43af8389304c77c3d4db525de8907cb74207c380vboxsync return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
43af8389304c77c3d4db525de8907cb74207c380vboxsync return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
43af8389304c77c3d4db525de8907cb74207c380vboxsync unsigned int col;
43af8389304c77c3d4db525de8907cb74207c380vboxsyncstatic 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
int rc = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy);
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;
#ifdef VBOX
static DECLCALLBACK(void) voidUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
#define GMODE_TEXT 0
#ifndef VBOX
void vga_update_display(void)
#ifndef VBOX
#ifndef VBOX
#ifdef VBOX
if (fUpdateAll) {
typedef DECLCALLBACK(void) FNUPDATERECT(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
int fBlank = 0;
if (fBlank) {
if (s->pDrv) {
if (fBlank) {
if (s->pDrv) {
return rc;
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;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
GCPhysAddr++;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
GCPhysAddr++;
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 rc;
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_RC
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 %.*Rhxs\n", pThis->offLogoData, pThis->offLogoData, cb, cb, pu32));
return VINF_SUCCESS;
if (src) {
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)) )
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. */
bool fRenderVRAM;
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 = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, "vgaGCLFBAccessHandler", &pThis->RCPtrLFBHandler);
AssertReleaseMsgFailed(("PDMR3LdrGetSymbolRC(, %s, \"vgaGCLFBAccessHandler\",) -> %Rrc\n", pDevIns->pDevReg->szRCMod, 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", VGA_MAPPING_SIZE, rc), rc);
#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
rc = PDMDevHlpMMIO2MapKernel(pDevIns, 0 /* iRegion */, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pR0Mapping);
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, VGA_SAVEDSTATE_VERSION,
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;
PDMDevHlpDBGFInfoRegister(pDevIns, "vgatext", "Display VGA memory formatted as text.", vgaInfoText);
pThis->pu8Logo = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, RT_MAX(pThis->cbLogo, g_cbVgaDefBiosLogo + sizeof(LogoHdr)));
STAM_REG(pVM, &pThis->StatRZMemoryRead, STAMTYPE_PROFILE, "/Devices/VGA/RZ/MMIO-Read", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryRead() body.");
STAM_REG(pVM, &pThis->StatR3MemoryRead, STAMTYPE_PROFILE, "/Devices/VGA/R3/MMIO-Read", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryRead() body.");
STAM_REG(pVM, &pThis->StatRZMemoryWrite, STAMTYPE_PROFILE, "/Devices/VGA/RZ/MMIO-Write", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryWrite() body.");
STAM_REG(pVM, &pThis->StatR3MemoryWrite, STAMTYPE_PROFILE, "/Devices/VGA/R3/MMIO-Write", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryWrite() body.");
return rc;
#ifdef VBE_NEW_DYN_LIST
return VINF_SUCCESS;
sizeof(VGASTATE),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,