fb_support.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 681 行 · 第 1/2 页
C
681 行
//=============================================================================
//
// fb_support.c
//
// Frame buffer support for Dreamcast
//
//=============================================================================
//####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): t@keshi.org
// Contributors:t@keshi.org, gthomas
// Date: 2001-07-30
// Purpose: Red Hat/eCos banner for display during boot
//
//####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
#define LOGO_AT_TOP
#include "banner.xpm"
#include "font.h"
#define RESETREG 0xa05f8008
#define BORDERRGB 0xa05f8040
#define DISPLAYMODE 0xa05f8044
#define ALPHAMODE 0xa05f8048
#define DISPLAYALIGN 0xa05f804c
#define BASEOFFSET1 0xa05f8050
#define BASEOFFSET2 0xa05f8054
#define DISPLAYSIZE 0xa05f805c
#define SYNCMODE 0xa05f80d0
#define VERTICALRANGE 0xa05f80dc
#define HORIZPOSITION 0xa05f80ec
#define VERTPOSITION 0xa05f80f0
#define PALETTEMODE 0xa05f8108
#define VIDEOOUTPUT 0xa0702c00
static unsigned long dc_parm_vga_16bpp[] = {
DISPLAYMODE, 0x00800005,
BASEOFFSET1, 0,
BASEOFFSET2, 640*2,
DISPLAYSIZE, (1<<20)+((480-1)<<10)+(640*2/4-1),
SYNCMODE, 0x100,
VERTPOSITION, 0x00230023,
VERTICALRANGE, 0x00280208,
HORIZPOSITION, 0x00000090,
VIDEOOUTPUT, 0,
0, 0,
};
static unsigned long dc_parm_vga_32bpp[] = {
DISPLAYMODE, 0x0080000d,
BASEOFFSET1, 0,
BASEOFFSET2, 640*4,
DISPLAYSIZE, (1<<20)+((480-1)<<10)+(640*4/4-1),
SYNCMODE, 0x100,
VERTPOSITION, 0x00230023,
VERTICALRANGE, 0x00280208,
HORIZPOSITION, 0x00000090,
VIDEOOUTPUT, 0,
0, 0,
};
static unsigned long *dc_parm_vga[] = {
dc_parm_vga_16bpp,
dc_parm_vga_32bpp,
};
static unsigned long dc_parm_composite_16bpp[] = {
DISPLAYMODE, 0x00000005,
BASEOFFSET1, 0,
BASEOFFSET2, 640*2,
DISPLAYSIZE, ((640*2/4+1)<<20)+((240-1)<<10)+(640*2/4-1),
SYNCMODE, 0x150,
VERTPOSITION, 0x00120012,
VERTICALRANGE, 0x00240204,
HORIZPOSITION, 0x000000a4,
VIDEOOUTPUT, 0x300,
0, 0,
};
static unsigned long dc_parm_composite_32bpp[] = {
DISPLAYMODE, 0x0000000d,
BASEOFFSET1, 0,
BASEOFFSET2, 640*4,
DISPLAYSIZE, ((640*4/4+1)<<20)+((240-1)<<10)+(640*4/4-1),
SYNCMODE, 0x150,
VERTPOSITION, 0x00120012,
VERTICALRANGE, 0x00240204,
HORIZPOSITION, 0x000000a4,
VIDEOOUTPUT, 0x300,
0, 0,
};
static unsigned long *dc_parm_composite[] = {
dc_parm_composite_16bpp,
dc_parm_composite_32bpp,
};
static unsigned long dc_parm_interlace_16bpp[] = {
DISPLAYMODE, 0x00000005,
BASEOFFSET1, 0,
BASEOFFSET2, 640*2,
DISPLAYSIZE, ((640*2/4+1)<<20)+((240-1)<<10)+(640*2/4-1),
SYNCMODE, 0x150,
VERTPOSITION, 0x00120012,
VERTICALRANGE, 0x00240204,
HORIZPOSITION, 0x000000a4,
VIDEOOUTPUT, 0,
0, 0,
};
static unsigned long dc_parm_interlace_32bpp[] = {
DISPLAYMODE, 0x0000000d,
BASEOFFSET1, 0,
BASEOFFSET2, 640*4,
DISPLAYSIZE, ((640*4/4+1)<<20)+((240-1)<<10)+(640*4/4-1),
SYNCMODE, 0x150,
VERTPOSITION, 0x00120012,
VERTICALRANGE, 0x00240204,
HORIZPOSITION, 0x000000a4,
VIDEOOUTPUT, 0,
0, 0,
};
static unsigned long *dc_parm_interlace[] = {
dc_parm_interlace_16bpp,
dc_parm_interlace_32bpp,
};
/*
* Check cable type.
* 0: VGA, 2: RGB, 3: Composite
*/
#define PCTRA 0xff80002c
#define PDTRA 0xff800030
static int dcfb_cable_check(void)
{
unsigned long temp;
HAL_READ_UINT32(PCTRA, temp);
temp &= 0xfff0ffff;
temp |= 0x000a0000;
HAL_WRITE_UINT32(PCTRA, temp);
HAL_READ_UINT16(PDTRA, temp);
return (temp>>8)&3;
}
// Physical dimensions of LCD display
#define DISPLAY_WIDTH 640
#define DISPLAY_HEIGHT 480
#define LCD_WIDTH 640
#define LCD_HEIGHT 480
#define LCD_DEPTH 16
#define USE_RGB565
#ifdef USE_RGB565
#define RGB_RED(x) (((x)&0x1F)<<11)
#define RGB_GREEN(x) (((x)&0x3F)<<5)
#define RGB_BLUE(x) ((x)&0x1F)
#else
#define RGB_RED(x) (((x)&0x0F)<<12)
#define RGB_GREEN(x) (((x)&0x0F)<<7)
#define RGB_BLUE(x) (((x)&0x0F)<<1)
#endif
// Physical screen info
static int lcd_width = LCD_WIDTH;
static int lcd_height = LCD_HEIGHT;
// Virtual screen info
static int curX = 0; // Last used position
static int curY = 0;
//static int width = LCD_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);
//static int height = LCD_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);
static int fg = RGB_RED(15) | RGB_GREEN(63) | RGB_BLUE(8);
static int bg = RGB_RED(0) | RGB_GREEN(0) | RGB_BLUE(15/*31*/);
#define SCREEN_PAN 20
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
#define VISIBLE_SCREEN_WIDTH (LCD_WIDTH/FONT_WIDTH)
#define VISIBLE_SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
static char screen[SCREEN_HEIGHT][SCREEN_WIDTH];
static int screen_start = 0;
static int screen_height = SCREEN_HEIGHT;
static int screen_width = SCREEN_WIDTH;
static int screen_pan = 0;
static bool cursor_enable = true;
static int kbd_pos;
static unsigned short *framebuffer = (void*)0xa5000000;
// Functions
static void lcd_drawc(cyg_int8 c, int x, int y);
static inline void
set_pixel(int row, int col, unsigned short val)
{
framebuffer[row*640+col] = val;
}
// Clear screen
void
lcd_clear(void)
{
int row, col;
int pos;
for (row = 0; row < lcd_height; row++) {
for (col = 0; col < lcd_width; col++) {
set_pixel(row, col, bg);
}
}
for (row = 0; row < screen_height; row++) {
for (col = 0; col < screen_width; col++) {
screen[row][col] = ' ';
}
}
// Note: Row 0 seems to wrap incorrectly
#ifdef LOGO_AT_TOP
pos = 0;
#else
pos = (LCD_HEIGHT-1);
#endif
kbd_pos = show_xpm(banner_xpm, pos);
curX = 0; curY = screen_start;
if (cursor_enable) {
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
}
}
// Position cursor
void
lcd_moveto(int X, int Y)
{
if (cursor_enable) {
lcd_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) {
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
}
}
// Render a character at position (X,Y) with current background/foreground
static void
lcd_drawc(cyg_int8 c, int x, int y)
{
cyg_uint8 bits;
int l, p;
if ((x < 0) || (x >= VISIBLE_SCREEN_WIDTH) ||
(y < 0) || (y >= screen_height)) return;
for (l = 0; l < FONT_HEIGHT; l++) {
bits = font_table[c-FIRST_CHAR][l];
for (p = 0; p < FONT_WIDTH; p++) {
if (bits & 0x01) {
set_pixel(y*FONT_HEIGHT+l, x*FONT_WIDTH + p, fg);
} else {
set_pixel(y*FONT_HEIGHT+l, x*FONT_WIDTH + p, bg);
}
bits >>= 1;
}
}
}
static void
lcd_refresh(void)
{
int row, col;
cyg_uint16 *p1, *p2;
// Now the physical screen
for (row = FONT_HEIGHT*(screen_start+1); row < LCD_HEIGHT; row++) {
p1 = &framebuffer[(row-FONT_HEIGHT)*LCD_WIDTH+0];
p2 = &framebuffer[row*LCD_WIDTH+0];
for (col = 0; col < LCD_WIDTH; col++) {
*p1++ = *p2++;
}
}
for (row = LCD_HEIGHT-FONT_HEIGHT; row < LCD_HEIGHT; row++) {
p1 = &framebuffer[row*LCD_WIDTH+0];
for (col = 0; col < LCD_WIDTH; col++) {
*p1++ = bg;
}
}
if (cursor_enable) {
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?