⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scr_ecospcsvga.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -