📄 scr_ecospcsvga.c
字号:
return result;
}
opened = 1;
// First make sure that there is valid video information in video
// memory, i.e. that the system was booted by means of a suitable
// RedBoot instance, that nothing has overwritten video memory
// yet, and that we are running at the desired screen depth.
vesa_info_block = (struct VBESVGAInfoBlock*) 0x000A0000;
vesa_current_mode = (struct VBEModeInfoBlock*) 0x000A0200;
if (('V' != vesa_info_block->signature[0]) || ('E' != vesa_info_block->signature[1]) ||
('S' != vesa_info_block->signature[2]) || ('A' != vesa_info_block->signature[3])) {
EPRINTF("No Video BIOS information at location 0x000A0000\n"
"Please use a suitably configured RedBoot for bootstrap\n");
return NULL;
}
// Optionally, provide lots of information about the graphics card,
// the various modes available, and the current mode.
#ifdef CYGDBG_MICROWINDOWS_PCSVGA_VERBOSE
{
diag_printf("VESA info: %c%c%c%c\n", vesa_info_block->signature[0], vesa_info_block->signature[1],
vesa_info_block->signature[2], vesa_info_block->signature[3]);
diag_printf("Version %04x\n", vesa_info_block->version);
if (NULL != vesa_info_block->oem_string_ptr) {
vesa_info_block->oem_string_ptr = segoff_to_phys(vesa_info_block->oem_string_ptr);
diag_printf("OEM %s\n", vesa_info_block->oem_string_ptr);
}
diag_printf("Total memory %dK\n", 64 * vesa_info_block->total_memory);
diag_printf("OEM software rev %04x\n", vesa_info_block->oem_software_rev);
if (NULL != vesa_info_block->oem_vendor_name_ptr) {
vesa_info_block->oem_vendor_name_ptr = segoff_to_phys(vesa_info_block->oem_vendor_name_ptr);
diag_printf("OEM vendor %s\n", vesa_info_block->oem_vendor_name_ptr);
}
if (NULL != vesa_info_block->oem_product_name_ptr) {
vesa_info_block->oem_product_name_ptr = segoff_to_phys(vesa_info_block->oem_product_name_ptr);
diag_printf("OEM product name %s\n", vesa_info_block->oem_product_name_ptr);
}
if (NULL != vesa_info_block->oem_product_rev_ptr) {
vesa_info_block->oem_product_rev_ptr = segoff_to_phys(vesa_info_block->oem_product_rev_ptr);
diag_printf("OEM product revision %s\n", vesa_info_block->oem_product_rev_ptr);
}
diag_printf("Capabilities: %02x, %02x, %02x, %02x\n",
vesa_info_block->capabilities[0], vesa_info_block->capabilities[1],
vesa_info_block->capabilities[2], vesa_info_block->capabilities[3]);
vesa_info_block->video_mode_ptr = (unsigned short*) segoff_to_phys((char*) vesa_info_block->video_mode_ptr);
for (i = 0; 0x0FFFF != vesa_info_block->video_mode_ptr[i]; i++) {
int mode = vesa_info_block->video_mode_ptr[i];
struct VBEModeInfoBlock* mode_data = (struct VBEModeInfoBlock*) (0x0A0400 + (0x100 * i));
diag_printf("Mode %04x: %4d*%4d @ %2dbpp, %4d bytes/line, fb %s 0x%08x\n", mode,
mode_data->x_resolution, mode_data->y_resolution, mode_data->bits_per_pixel,
mode_data->bytes_per_scanline,
(0 == (mode_data->mode_attributes & 0x0080)) ? "no " : "yes",
mode_data->physical_base_ptr);
if (32 == mode_data->bits_per_pixel) {
diag_printf(" red %d bits << %d, green %d bits << %d, blue %d bits << %d, reserved %d bits << %d\n",
mode_data->red_mask_size, mode_data->red_field_position,
mode_data->green_mask_size, mode_data->green_field_position,
mode_data->blue_mask_size, mode_data->blue_field_position,
mode_data->reserved_mask_size, mode_data->reserved_field_position);
}
}
diag_printf("Current mode: %4d*%4d @ %2dbpp, %4d bytes/line, fb %s 0x%08x\n",
vesa_current_mode->x_resolution, vesa_current_mode->y_resolution, vesa_current_mode->bits_per_pixel,
vesa_current_mode->bytes_per_scanline,
(0 == (vesa_current_mode->mode_attributes & 0x0080)) ? "no" : "yes",
vesa_current_mode->physical_base_ptr);
if (32 == vesa_current_mode->bits_per_pixel) {
diag_printf(" red %d bits << %d, green %d bits << %d, blue %d bits << %d, reserved %d bits << %d\n",
vesa_current_mode->red_mask_size, vesa_current_mode->red_field_position,
vesa_current_mode->green_mask_size, vesa_current_mode->green_field_position,
vesa_current_mode->blue_mask_size, vesa_current_mode->blue_field_position,
vesa_current_mode->reserved_mask_size, vesa_current_mode->reserved_field_position);
}
}
#endif
#if defined(CYGIMP_MICROWINDOWS_PCSVGA32)
// A 32-bit displays, 0888
if ((32 != vesa_current_mode->bits_per_pixel) ||
(8 != vesa_current_mode->red_mask_size) || (16 != vesa_current_mode->red_field_position) ||
(8 != vesa_current_mode->green_mask_size) || ( 8 != vesa_current_mode->green_field_position) ||
(8 != vesa_current_mode->blue_mask_size) || ( 0 != vesa_current_mode->blue_field_position)) {
EPRINTF("RedBoot has not set up a valid initial graphics mode.\n"
"This screen driver requires 32 bits per pixel, 0RGB.\n",
"Configuration option CYGDBG_MICROWINDOWS_PCSVGA_VERBOSE can be used to\n"
"get information about the available video modes.\n");
return NULL;
}
#elif defined(CYGIMP_MICROWINDOWS_PCSVGA16)
// A 16-bit display, 565
if ((16 != vesa_current_mode->bits_per_pixel) ||
(5 != vesa_current_mode->red_mask_size) || (11 != vesa_current_mode->red_field_position) ||
(6 != vesa_current_mode->green_mask_size) || ( 5 != vesa_current_mode->green_field_position) ||
(5 != vesa_current_mode->blue_mask_size) || ( 0 != vesa_current_mode->blue_field_position)) {
EPRINTF("RedBoot has not set up a valid initial graphics mode.\n"
"This screen driver requires 16 bits per pixel, RGB=565.\n",
"Configuration option CYGDBG_MICROWINDOWS_PCSVGA_VERBOSE can be used to\n"
"get information about the available video modes.\n");
return NULL;
}
#endif
if ((0 == (vesa_current_mode->mode_attributes & 0x0080)) || (NULL == vesa_current_mode->physical_base_ptr)) {
EPRINTF("RedBoot has not set up a valid initial graphics mode.\n"
"The frame buffer is not linearly accessible.\n");
return NULL;
}
// OK, we are at the expected depth. Fill in the resolution etc. based
// on the current video mode.
psd->xres = vesa_current_mode->x_resolution;
psd->yres = vesa_current_mode->y_resolution;
psd->xvirtres = vesa_current_mode->x_resolution;
psd->yvirtres = vesa_current_mode->y_resolution;
psd->linelen = vesa_current_mode->bytes_per_scanline;
psd->addr = vesa_current_mode->physical_base_ptr;
// The remaining parameters in the structure are statically
// initialized for now, e.g. 32bpp, pixtype TRUECOLOR0888
// Use one of the standard framebuffer subdrivers.
psd->orgsubdriver = select_fb_subdriver(psd);
if (NULL == psd->orgsubdriver) {
EPRINTF("There is no standard framebuffer driver for the current video mode.\n");
return NULL;
}
if (!set_subdriver(psd, psd->orgsubdriver, TRUE)) {
EPRINTF("Framebuffer subdriver initialization failed.\n");
return NULL;
}
// That should be all for now.
result = psd;
return result;
}
// Close is a no-op, no resources have been allocated.
// The open() code detects multiple invocations.
static void
ecos_pcsvga_close(PSD psd)
{
CYG_UNUSED_PARAM(PSD, psd);
}
// Setting the palette is a no-op for now since only true color
// modes are supported.
static void
ecos_pcsvga_setpalette(PSD psd, int first, int count, MWPALENTRY* pal)
{
CYG_UNUSED_PARAM(PSD, psd);
CYG_UNUSED_PARAM(int, first);
CYG_UNUSED_PARAM(int, count);
CYG_UNUSED_PARAM(MWPALENTRY*, pal);
}
// Setting the portrait mode. There are standard subdrivers to
// cope with this, manipulating the arguments and then calling
// the original subdriver.
extern SUBDRIVER fbportrait_left, fbportrait_right, fbportrait_down;
static void
ecos_pcsvga_setportrait(PSD psd, int portrait_mode)
{
psd->portrait = portrait_mode;
if (portrait_mode & (MWPORTRAIT_LEFT | MWPORTRAIT_RIGHT)) {
psd->xvirtres = psd->yres;
psd->yvirtres = psd->xres;
} else {
psd->xvirtres = psd->xres;
psd->yvirtres = psd->yres;
}
if (portrait_mode == MWPORTRAIT_LEFT) {
set_subdriver(psd, &fbportrait_left, FALSE);
} else if (portrait_mode == MWPORTRAIT_RIGHT) {
set_subdriver(psd, &fbportrait_right, FALSE);
} else if (portrait_mode == MWPORTRAIT_DOWN) {
set_subdriver(psd, &fbportrait_down, FALSE);
} else {
set_subdriver(psd, psd->orgsubdriver, FALSE);
}
}
// Getting screen info. It is not clear why this is part of the driver
// since nearly all the information is already available in psd.
static void
ecos_pcsvga_getscreeninfo(PSD psd, PMWSCREENINFO psi)
{
psi->rows = psd->yvirtres;
psi->cols = psd->xvirtres;
psi->planes = psd->planes;
psi->bpp = psd->bpp;
psi->ncolors = psd->ncolors;
psi->portrait = psd->portrait;
psi->fbdriver = TRUE;
psi->pixtype = psd->pixtype;
#if defined(CYGIMP_MICROWINDOWS_PCSVGA32)
psi->rmask = 0x00FF0000;
psi->gmask = 0x0000FF00;
psi->bmask = 0x000000FF;
#elif defined(CYGIMP_MICROWINDOWS_PCSVGA16)
psi->rmask = 0x0000F800;
psi->gmask = 0x000007E0;
psi->bmask = 0x0000001F;
#endif
// The screen dimensions are not readily available.
// Assume an 18' monitor (actual visible diameter),
// which corresponds ~ to 36cm by 28cm
psi->xdpcm = psd->xres / 36;
psi->ydpcm = psd->yres / 28;
psi->fonts = NUMBER_FONTS;
// Remaining information such as keyboard modifiers etc. cannot be
// known here.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -