📄 scr_ecospcsvga.c
字号:
//=============================================================================
//
// scr_ecospcsvga.c
//
// eCos support for a PC display using SVGA/VESA
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): bartv
// Date: 2002-04-19
// Purpose: Implement a screen driver for PC's with a VESA video BIOS
//
// PC graphics cards are problematical. Many graphic cards are still more
// or less compatible with ancient VGA hardware, but this provides access
// only to rather low resolutions. There is no other hardware compatibility,
// and many different graphics card all needing their own driver.
//
// Each graphics card comes with a video BIOS @ 0x000C0000, which can be
// invoked via int 0x10 to do useful operations like querying the
// available video modes and setting the desired one. However the video
// BIOS can normally only be called in x86 real mode, not protected mode,
// Currently eCos only runs in protected mode, and has no support for
// briefly switching back into real mode.
//
// Current VESA VBE2 compliant graphics cards do offer some protected
// mode entry points, but not enough to perform mode switches etc.
// VBE3 is supposed to provide additional support for protected mode
// applications, but does not appear to be widely implemented yet.
//
// So for now the only solution is to perform the mode switching
// during bootstrap, and specifically inside RedBoot. This is controlled
// by an option in the RedBoot configuration, which has the side
// effect of disabling RedBoot's own use of the screen and keyboard.
// SVGA graphics modes are not completely standardized, so it is the
// user's responsibility to pick a suitable mode.
//
// Because RedBoot is a separate application, it is not guaranteed
// that the appropriate mode switch has actually occurred by the
// time this code runs. Therefore RedBoot also places the main SVGA
// info block at location 0x000A0000, normally a window into video
// memory, since that memory is not being used for anything else
// right now. Similarly the mode info block for the current mode
// is placed @ 0x000A0200, and to make it easier to find out what
// modes are available on the current hardware and allow RedBoot to
// be reconfigured appropriately, all the mode info blocks are
// stored @ 0x000A0400 at 256-byte boundaries. The main info block
// can be used to find out which modes are actually available.
//
//####DESCRIPTIONEND####
//=============================================================================
#include <pkgconf/system.h>
#include <pkgconf/microwindows.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/infra/diag.h>
#include <microwin/device.h>
#define VTSWITCH 0
#include "fb.h"
#include "genfont.h"
#include "genmem.h"
// ----------------------------------------------------------------------------
// Information about the current mode and all available video modes,
// should have been provided by RedBoot.
struct VBESVGAInfoBlock {
unsigned char signature[4]; /* VESA */
unsigned short version;
char* oem_string_ptr;
unsigned char capabilities[4];
unsigned short* video_mode_ptr;
unsigned short total_memory;
unsigned short oem_software_rev;
char* oem_vendor_name_ptr;
char* oem_product_name_ptr;
char* oem_product_rev_ptr;
/* Reserved data here */
} __attribute__((packed));
struct VBEModeInfoBlock {
unsigned short mode_attributes;
unsigned char win_a_atributes;
unsigned char win_b_attributes;
unsigned short win_granularity;
unsigned short win_size;
unsigned short win_a_segment;
unsigned short win_b_segment;
unsigned int win_func_ptr;
unsigned short bytes_per_scanline;
unsigned short x_resolution;
unsigned short y_resolution;
unsigned char x_char_size;
unsigned char y_char_size;
unsigned char number_of_planes;
unsigned char bits_per_pixel;
unsigned char number_of_banks;
unsigned char memory_model;
unsigned char bank_size;
unsigned char number_of_image_pages;
unsigned char reserved;
unsigned char red_mask_size;
unsigned char red_field_position;
unsigned char green_mask_size;
unsigned char green_field_position;
unsigned char blue_mask_size;
unsigned char blue_field_position;
unsigned char reserved_mask_size;
unsigned char reserved_field_position;
unsigned char direct_color_mode_info;
void* physical_base_ptr;
unsigned int offscreen_memory_offset;
unsigned short offscreen_memory_size;
} __attribute__((packed));
#if defined(CYGDBG_MICROWINDOWS_PCSVGA_VERBOSE)
static void*
segoff_to_phys(void* addr)
{
int x = (int) addr;
int segment = (x >> 12) & 0x0FFFF0;
int offset = x & 0x0FFFF;
return (void*) (segment | offset);
}
#endif
// ----------------------------------------------------------------------------
static PSD ecos_pcsvga_open(PSD);
static void ecos_pcsvga_close(PSD);
static void ecos_pcsvga_setportrait(PSD, int);
static void ecos_pcsvga_setpalette(PSD, int, int, MWPALENTRY*);
static void ecos_pcsvga_getscreeninfo(PSD , PMWSCREENINFO);
SCREENDEVICE scrdev = {
xres: 0,
yres: 0,
xvirtres: 0,
yvirtres: 0,
planes: 1,
linelen: 0,
size: 0,
#if defined(CYGIMP_MICROWINDOWS_PCSVGA32)
bpp: 32,
ncolors: 1 << 24,
pixtype: MWPF_TRUECOLOR0888,
#elif defined(CYGIMP_MICROWINDOWS_PCSVGA16)
bpp: 16,
ncolors: 1 << 16,
pixtype: MWPF_TRUECOLOR565,
#else
# error Unsupported video mode.
#endif
flags: PSF_SCREEN | PSF_HAVEBLIT,
addr: 0,
Open: &ecos_pcsvga_open,
Close: &ecos_pcsvga_close,
GetScreenInfo: &ecos_pcsvga_getscreeninfo,
SetPalette: &ecos_pcsvga_setpalette,
DrawPixel: NULL,
ReadPixel: NULL,
DrawHorzLine: NULL,
DrawVertLine: NULL,
FillRect: NULL,
builtin_fonts: gen_fonts,
Blit: NULL,
PreSelect: NULL,
DrawArea: NULL,
SetIOPermissions: NULL,
AllocateMemGC: &gen_allocatememgc,
MapMemGC: &fb_mapmemgc,
FreeMemGC: &gen_freememgc,
StretchBlit: NULL,
SetPortrait: &ecos_pcsvga_setportrait,
portrait: MWPORTRAIT_NONE,
orgsubdriver: NULL
};
static PSD
ecos_pcsvga_open(PSD psd)
{
struct VBESVGAInfoBlock* vesa_info_block;
struct VBEModeInfoBlock* vesa_current_mode;
// Detect repeated invocations. The information in the video
// memory will be blown away after the first call, so can
// only be consulted once.
static int opened = 0;
static PSD result = NULL;
if (opened) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -