vga_support.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,450 行 · 第 1/3 页
C
1,450 行
//==========================================================================//// vga_support.c//// NMI uE250/uPCI - VGA support////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2003 Gary Thomas <gary@mind.be>//// 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): gthomas// Contributors: gthomas// Date: 2001-11-03// Description: Simple VGA support//####DESCRIPTIONEND#####include <pkgconf/hal.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_io.h> // IO macros#include <cyg/hal/hal_if.h> // Virtual vector support#include <cyg/hal/hal_arch.h> // Register state info#include <cyg/hal/hal_intr.h> // HAL interrupt macros#include <cyg/hal/vga_support.h>#include <cyg/hal/hal_cache.h>#include <cyg/hal/plx.h> // Localbus I/O#include <string.h>#ifdef CYGPKG_ISOINFRA# include <pkgconf/isoinfra.h># ifdef CYGINT_ISO_STDIO_FORMATTED_IO# include <stdio.h> // sscanf# endif#endif#ifndef FALSE#define FALSE 0#define TRUE 1#endif// Logical layout#define VGA_WIDTH 640#define VGA_HEIGHT 480#define VGA_DEPTH 8static int bg = 0;static int fg = 1;static struct vga_info vga;struct VGA_ctlr { unsigned short rev; unsigned char enable; unsigned char _fill1[13]; struct ADV471 { unsigned short write_addr; unsigned short data; unsigned short pixel_read_mask; unsigned short read_addr; unsigned short overlay_data; unsigned short _fill2[2]; unsigned short overlay_read_addr; } clut; unsigned char _fill3[0x100000-0x20]; unsigned char fb[1];};// Compute the location for a pixel within the framebufferstatic cyg_uint8 *vga_fb(int row, int col){ cyg_uint8 *res = (cyg_uint8 *)((char *)vga.fb+(row*vga.rlen)+(col*vga.stride)); return res;}voidvga_on(bool enable){ static bool on = false; volatile struct VGA_ctlr *ctlr = vga.ctlr; if (enable) { if (!on) { ctlr->enable = 1; } on = true; } else { ctlr->enable = 0; on = false; }}// Initialize VGA hardwarestatic voidvga_set_cmap(volatile struct VGA_ctlr *ctlr, int index, int red, int green, int blue){ if (index > 255) { // Invalid index return; } ctlr->clut.write_addr = index; // Select ctlr->clut.data = red>>2; ctlr->clut.data = green>>2; ctlr->clut.data = blue>>2;}voidvga_init(cyg_uint32 *addr){ volatile struct VGA_ctlr *ctlr; vga.ctlr = (struct VGA_ctlr *)ctlr = (struct VGA_ctlr *)addr; vga.fb = ctlr->fb; vga.bpp = VGA_DEPTH; vga.height = VGA_HEIGHT; vga.width = VGA_WIDTH; vga.rlen = VGA_WIDTH; vga.stride = 1; vga.access_size = 1; vga_set_cmap(ctlr, 0, 0x00, 0x00, 0x00); // 0 -> black vga_set_cmap(ctlr, 1, 0xFF, 0xFF, 0xFF); // 1 -> white// diag_printf("VGA init at %p/%p\n", vga.ctlr, vga.fb); ctlr->enable = 1;}// Get information about the frame bufferintvga_getinfo(struct vga_info *info){ if (vga.bpp == 0) { return 0; // VGA not initialized } *info = vga; return 1; // Information valid}// Clear screenvoidvga_clear(void){#if 0 cyg_uint32 *fb_row0, *fb_rown; cyg_uint32 _bg = (bg<<16)|bg; fb_row0 = vga_fb(0, 0); fb_rown = vga_fb(vga_height, 0); while (fb_row0 != fb_rown) { *fb_row0++ = _bg; }#endif}#ifdef CYGSEM_UE250_VGA_COMM//// Additional support for VGA/Keyboard as 'console' device//#ifdef CYGOPT_UE250_VGA_COMM_LOGO#include "banner.xpm"#endif#include "font.h"// Virtual screen infostatic int curX = 0; // Last used positionstatic int curY = 0;//static int width = VGA_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);//static int height = VGA_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);#define SCREEN_PAN 20#define SCREEN_WIDTH 80#define SCREEN_HEIGHT (VGA_HEIGHT/FONT_HEIGHT)#define VISIBLE_SCREEN_WIDTH (VGA_WIDTH/FONT_WIDTH)#define VISIBLE_SCREEN_HEIGHT (VGA_HEIGHT/FONT_HEIGHT)static char screen[SCREEN_HEIGHT][SCREEN_WIDTH];static int screen_height = SCREEN_HEIGHT;static int screen_width = SCREEN_WIDTH;static int screen_pan = 0;// Usable area on screen [logical pixel rows]static int screen_start = 0; static int screen_end = VGA_HEIGHT/FONT_HEIGHT;static bool cursor_enable = true;// Functionsstatic void vga_drawc(cyg_uint8 c, int x, int y);static __inline__ voidset_pixel(int row, int col, unsigned char val){ unsigned char *pix = (unsigned char *)vga_fb(row, col); *pix = val;}#ifdef CYGOPT_UE250_VGA_COMM_LOGOstatic int_hexdigit(char c){ if ((c >= '0') && (c <= '9')) { return c - '0'; } else { if ((c >= 'A') && (c <= 'F')) { return (c - 'A') + 0x0A; } else { if ((c >= 'a') && (c <= 'f')) { return (c - 'a') + 0x0a; } } } return 0;}static int_hex(char *cp){ return (_hexdigit(*cp)<<4) | _hexdigit(*(cp+1));}static voidparse_color(char *cp, int *red, int *green, int *blue){ *red = *green = *blue = 0xFF; while (*cp && (*cp != 'c')) cp++; if (cp) { cp += 2; if (*cp == '#') { *red = _hex(cp+1); *green = _hex(cp+3); *blue = _hex(cp+5); } }}#ifndef CYGINT_ISO_STDIO_FORMATTED_IOstatic intget_int(unsigned char **_cp){ char *cp = *_cp; char c; int val = 0; while ((c = *cp++) && (c != ' ')) { if ((c >= '0') && (c <= '9')) { val = val * 10 + (c - '0'); } else { return -1; } } *_cp = cp; return val;}#endifstatic intshow_xpm(char *xpm[], int screen_pos){ int i, row, col, offset; unsigned char *cp; int nrows, ncols, nclrs, cwid; short color_index; int red, green, blue;//#define HORRIBLY_SLOW_COLOR_MAPPING#ifdef HORRIBLY_SLOW_COLOR_MAPPING bool color_match; short cmap[256][2]; int j;#else // Caution - this is very GIMP specific short cmap[256][3]; // Enough room for 256 colors short cmap_col, cmap_row; unsigned char std_cmap[] = " .+";#endif cp = xpm[0];#ifdef CYGINT_ISO_STDIO_FORMATTED_IO if (sscanf(cp, "%d %d %d %d", &ncols, &nrows, &nclrs, &cwid) != 4) {#else if (((ncols = get_int(&cp)) < 0) || ((nrows = get_int(&cp)) < 0) || ((nclrs = get_int(&cp)) < 0) || ((cwid = get_int(&cp)) < 0)) {#endif diag_printf("Can't parse XPM data, sorry\n"); return 0; }// diag_printf("%d rows, %d cols, %d colors %d chars/pixel\n", nrows, ncols, nclrs, cwid); if (cwid > 2) { diag_printf("Color map is too wide - %d\n", cwid); return 0; } for (i = 0; i < 256; i++) {#ifdef HORRIBLY_SLOW_COLOR_MAPPING cmap[i][0] = 0; cmap[i][1] = 0;#else cmap[i][0] = 0; cmap[i][1] = 0; cmap[i][2] = 0;#endif } color_index = 0; for (i = 0; i < nclrs; i++) { cp = xpm[i+1];#ifdef HORRIBLY_SLOW_COLOR_MAPPING for (j = 0; j < cwid; j++) { cmap[color_index][j] = cp[j]; }#else if (cwid == 1) { cmap_col = 0; } else { for (cmap_col = 0; cmap_col < 3; cmap_col++) { if (cp[1] == std_cmap[cmap_col]) { break; } } } cmap_row = *cp; cmap[cmap_row][cmap_col] = color_index;#endif parse_color(cp+cwid, &red, &green, &blue); // diag_printf("Color[%d] = %02x/%02x/%02x\n", color_index, red, green, blue); vga_set_cmap(vga.ctlr, color_index+2, red, green, blue); color_index++; }#ifdef CYGOPT_UE250_VGA_COMM_LOGO_TOP offset = screen_pos;#else offset = screen_pos-nrows;#endif for (row = 0; row < nrows; row++) { cp = xpm[nclrs+1+row]; for (col = 0; col < ncols; col++) {#ifdef HORRIBLY_SLOW_COLOR_MAPPING // Horrible, but portable, way to map colors for (color_index = 0; color_index < nclrs; color_index++) { color_match = true; for (j = 0; j < cwid; j++) { if (cmap[color_index][j] != cp[j]) { color_match = false; } } if (color_match) { break; } }#else if (cwid == 1) { cmap_col = 0; } else { for (cmap_col = 0; cmap_col < 3; cmap_col++) { if (cp[1] == std_cmap[cmap_col]) { break; } } } cmap_row = *cp; color_index = cmap[cmap_row][cmap_col];#endif set_pixel(row+offset, col, color_index+2); cp += cwid; } }#ifdef CYGOPT_UE250_VGA_COMM_LOGO_TOP screen_start = (nrows + (FONT_HEIGHT-1))/FONT_HEIGHT; screen_end = VGA_HEIGHT/FONT_HEIGHT; return offset+nrows;#else screen_start = 0; screen_height = offset / FONT_HEIGHT; screen_end = screen_height; return offset;#endif}#endifvoidvga_screen_clear(void){ int row, col;#ifdef CYGOPT_UE250_VGA_COMM_LOGO int pos;#endif for (row = 0; row < screen_height; row++) { for (col = 0; col < screen_width; col++) { screen[row][col] = ' '; vga_drawc(' ', col, row); } }#ifdef CYGOPT_UE250_VGA_COMM_LOGO // Note: Row 0 seems to wrap incorrectly#ifdef CYGOPT_UE250_VGA_COMM_LOGO_TOP pos = 0;#else pos = (VGA_HEIGHT-1);#endif show_xpm(banner_xpm, pos);#endif // CYGOPT_UE250_VGA_COMM_LOGO curX = 0; curY = screen_start; if (cursor_enable) { vga_drawc(CURSOR_ON, curX-screen_pan, curY); }}// Position cursorvoidvga_moveto(int X, int Y){ if (cursor_enable) { vga_drawc(screen[curY][curX], curX-screen_pan, curY); } if (X < 0) X = 0; if (X >= screen_width) X = screen_width-1; curX = X; if (Y < screen_start) Y = screen_start; if (Y >= screen_height) Y = screen_height-1; curY = Y; if (cursor_enable) { vga_drawc(CURSOR_ON, curX-screen_pan, curY); }}static unsigned long _bitmap[] = {#ifdef FONT_LEFT_TO_RIGHT 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,#else 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101#endif};// Render a character at position (X,Y) with current background/foregroundstatic voidvga_drawc(cyg_uint8 c, int x, int y){ cyg_uint8 bits; int l, p; int xoff, yoff;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?