?? video.c
字號:
/* * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland * * See file CREDITS for list of people who contributed to this * project. * * This program 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 of * the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Note: Parts of these software are imported from * - UBL, The Universal Talkware Boot Loader * Copyright (C) 2000 Universal Talkware Inc. * - Linux * * */#include <common.h>#ifdef CONFIG_VIDEO#include <command.h>#include <asm/processor.h>#include <devices.h>#include "video.h"#include <pci.h>#include "vga_table.h"#ifdef CONFIG_VIDEO_CT69000#define VIDEO_VEND_ID 0x102C#define VIDEO_DEV_ID 0x00C0#else#error CONFIG_VIDEO_CT69000 must be defined#endif/* * Routine for resent board info to video * resides in pip405.c */extern void video_write_board_info(void);#undef VGA_DEBUG#ifdef VGA_DEBUG#define PRINTF(fmt,args...) printf (fmt ,##args)#else#define PRINTF(fmt,args...)#endif#define VGA_MAXROWS 25#define VGA_MAXCOLS 80#define CRTC_CURSH 14 /* cursor high pos */#define CRTC_CURSL 15 /* cursor low pos *//* description of the hardware layout */#define ATTRI_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3c0 /* Index and Data write port of the attribute Registers */#define ATTRI_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3c1 /* Data port of the attribute Registers */#define STATUS_REG0 CFG_ISA_IO_BASE_ADDRESS | 0x3c2 /* Status Register 0 (read only) */#define MSR_REG_W CFG_ISA_IO_BASE_ADDRESS | 0x3c2 /* Misc. Output Register (write only) */#define SEQ_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3c4 /* Index port of the Sequencer Controller */#define SEQ_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3c5 /* Data port of the Sequencer Controller */#define COL_PAL_MASK CFG_ISA_IO_BASE_ADDRESS | 0x3c6 /* Color Palette Mask */#define COL_PAL_STAT CFG_ISA_IO_BASE_ADDRESS | 0x3c7 /* Color Palette Status (read only) */#define COL_PAL_IND_R CFG_ISA_IO_BASE_ADDRESS | 0x3c7 /* Color Palette Read Mode Index (write only) */#define COL_PAL_IND_W CFG_ISA_IO_BASE_ADDRESS | 0x3c8 /* Color Palette Write Mode Index */#define COL_PAL_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3c9 /* Color Palette Data Port */#define FCR_REG_R CFG_ISA_IO_BASE_ADDRESS | 0x3ca /* Feature Control Register (read only) */#define MSR_REG_R CFG_ISA_IO_BASE_ADDRESS | 0x3cc /* Misc. Output Register (read only) */#define GR_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3ce /* Index port of the Graphic Controller Registers */#define GR_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3cf /* Data port of the Graphic Controller Registers */#define FP_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d0 /* Index port of the Flat panel Registers */#define FP_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d1 /* Data port of the Flat panel Registers */#define MR_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d2 /* Index Port of the Multimedia Extension */#define MR_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d3 /* Data Port of the Multimedia Extension */#define CRT_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d4 /* Index port of the CRT Controller */#define CRT_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d5 /* Data port of the CRT Controller */#define XREG_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d6 /* Extended Register index */#define XREG_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d7 /* Extended Register data */#define STATUS_REG1 CFG_ISA_IO_BASE_ADDRESS | 0x3da /* Input Status Register 1 (read only) */#define FCR_REG_W CFG_ISA_IO_BASE_ADDRESS | 0x3da /* Feature Control Register (write only) */static unsigned char * video_fb; /* Frame buffer *//* current hardware state */static int video_row;static int video_col;static unsigned char video_attr;static unsigned int font_base_addr;/********************************************************************** * some forward declerations... */int video_init(int busdevfunc);void vga_set_attrib(void);void vga_set_crt(void);void vga_set_dac(void);void vga_set_gr(void);void vga_set_seq(void);void vga_set_xreg(void);void vga_write_sr(unsigned char reg,unsigned char val);void vga_write_gr(unsigned char reg,unsigned char val);void vga_write_cr(unsigned char reg,unsigned char val);void vga_set_font(void);/*************************************************************************** * Init VGA Device */int drv_video_init (void){ int error, devices = 1 ; device_t vgadev ; int busdevfunc; busdevfunc=pci_find_device(VIDEO_VEND_ID,VIDEO_DEV_ID,0); /* get PCI Device ID */ if(busdevfunc==-1) {#ifdef CONFIG_VIDEO_ONBOARD printf("Error VGA Controller (%04X,%04X) not found\n",VIDEO_VEND_ID,VIDEO_DEV_ID);#endif return -1; } video_init(busdevfunc); video_write_board_info(); memset (&vgadev, 0, sizeof(vgadev)); strcpy(vgadev.name, "vga"); vgadev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; vgadev.putc = video_putc; vgadev.puts = video_puts; vgadev.getc = NULL; vgadev.tstc = NULL; error = device_register (&vgadev); return (error == 0) ? devices : error ;}/*********************************************************** * VGA Initializing */int video_init(int busdevfunc){ pci_read_config_dword(busdevfunc, PCI_BASE_ADDRESS_0, &font_base_addr); video_fb = (char*)font_base_addr; /* we look into the big linaer memory area */ /* set the extended Registers */ vga_set_xreg(); /* set IO Addresses to 0x3Dx (color mode ) */ out8(MSR_REG_W,0x01); /* Feature Control Register: Bits 7-4 Reserved = 0 Bit 3 Vertical Sync select = 1 = Enabled Bits 2-0 Reserved = 010 = as read from memory. */ out8(FCR_REG_W,0x02); /* Miscelaneous output Register: Bits 7-6 (num lines) = 01 = VGA 400 lines, Bit 5 (Odd/Even Page) = 1 = Sleect high page of memory, Bit 4 reserved = 0, Bits 3-2 (Clocl Select) = 01 = 28.322Mhz Bit 1 = Display Ram Enable = 1 = Enable processor access. Bit 0 = Io Address Select = 1 = Color Graphics Enulation. */ out8(MSR_REG_W,0x67); /* set the palette */ vga_set_dac(); /* set the attributes (before we bring up the engine then we dont have to wait for refresh). */ vga_set_attrib(); /* set the crontroller register. */ vga_set_crt(); vga_write_sr(0x00,0x01); /* synchronous reset */ vga_write_sr(0x01,0x00); /* clocking mode */ vga_write_sr(0x02,0x03); /* write to map 0, 1 */ vga_write_sr(0x03,0x00); /* select character map 0 */ vga_write_sr(0x04,0x03); /* even-odd addressing */ vga_write_sr(0x00,0x03); /* clear synchronous reset */ vga_set_seq(); /* Set the extended sr's. */ vga_set_gr(); /* Set the graphic registers. */ /* load the font */ vga_set_font(); /* initialize the rol/col counts and the text attribute. */ video_row=0; video_col=0; video_attr = VGA_ATTR_CLR_WHT; /* Clear the video ram */ video_clear(); return 1;}void vga_set_font(void){ int i,j; char *fontmap; fontmap = (char *)font_base_addr; vga_write_sr(0x00,0x01); /* synchronous reset */ vga_write_sr(0x04,0x06); /* sequential addressing */ vga_write_sr(0x02,0x04); /* write to map 2 */ vga_write_sr(0x00,0x03); /* clear synchronous reset */ vga_write_gr(0x04,0x02); /* select map 2 */ vga_write_gr(0x05,0x00); /* disable odd-even addressing */ vga_write_gr(0x06,0x00); /* map start at 0xa0000 */ for(i=0;i<0x100;i++) { for(j=0;j<0x10;j++) { *((char *)fontmap+i*32+j)=(char)fontdata_8x16[i*16+j]; } } vga_write_sr(0x00,0x01); /* synchronous reset */ vga_write_sr(0x02,0x03); /* write to map 0 and 1 */ vga_write_sr(0x04,0x03); /* odd-even addressing */ vga_write_sr(0x03,0x00); /* Character map 0 & 1 */ vga_write_sr(0x00,0x03); /* clear synchronous reset */ vga_write_gr(0x04,0x00); /* select map 0 for CPU */ vga_write_gr(0x05,0x10); /* enable odd-even addressing */ vga_write_gr(0x06,0x0E); /* map start at 0xb8000 */}/* since we are BIG endian, swap attributes and char */unsigned short vga_swap_short(unsigned short val){ unsigned short swapped; swapped = ((val & 0xff)<<8) | ((val & 0xff00)>>8); return swapped;}/**************************************************** * Routines usable Outside world *//* scolls the text up row rows */void video_scroll(int row){ unsigned short clear = ((unsigned short)video_attr << 8) | (' '); unsigned short* addr16 = &((unsigned short *)video_fb)[(VGA_MAXROWS-row)*VGA_MAXCOLS]; int i; clear=vga_swap_short(clear); memcpy(video_fb, video_fb+row*(VGA_MAXCOLS*2), (VGA_MAXROWS-row)*(VGA_MAXCOLS*2)); for (i = 0 ; i < row * VGA_MAXCOLS ; i++) addr16[i] = clear; video_row-=row; video_col=0;}unsigned long video_cursor(int col, int row){ unsigned short off = row * VGA_MAXCOLS + col ; unsigned long saved = (video_col << 16) | (video_row & 0xFFFF); video_col = col; video_row = row; vga_write_cr(CRTC_CURSH,(unsigned char)((off & 0xff00)>>8)); /* Cursor pos. high */ vga_write_cr(CRTC_CURSL,(unsigned char)(off & 0xff)); /* Cursor pos. low */ return saved;}void video_set_lxy(unsigned long lxy){ int col = (lxy >> 16) & 0xFFFF; int row = lxy & 0xFFFF; video_cursor(col,row);}unsigned long video_get_lxy(void){ return (video_col << 16) | (video_row & 0xFFFF);}void video_clear(void){ int i; unsigned short clear = ((unsigned short)video_attr << 8) | (' '); unsigned short * addr16 = (unsigned short * )video_fb; clear=vga_swap_short(clear); video_row = video_col = 0; for (i = 0 ; i < 2000 ; i++) { addr16[i] = clear; }}void video_copy(unsigned short *buffer){ int i; unsigned short * addr16 = (unsigned short * )video_fb; for (i = 0 ; i < 2000 ; i++) { buffer[i] = addr16[i]; }}void video_write(unsigned short *buffer){ int i; unsigned short * addr16 = (unsigned short *)video_fb; for (i = 0 ; i < 2000 ; i++) { addr16[i] = buffer[i]; }}void video_putc(char ch){ char* addr;#if 0 char buf[48]; char buf1[16]; static int i=0; sprintf(buf1,"%02X ",ch); serial_puts(buf1); buf[i++]=((ch>=0x20)&&(ch<=0x7f)) ? ch : '.'; if(i>=16) { buf[i++]='\n'; buf[i]='\0'; i=0; serial_puts(" "); serial_puts(buf); }#endif switch (ch) { case '\n': video_col=0; video_row++; break; case '\r': video_col=0; break; case '\t': video_col += 8 - video_col % 8; break; case '\a':/* beep(); */ break; case '\b': if(video_col) video_col--; else return; break; default: addr = video_fb + 2 * video_row * 80 + 2 * video_col; *((char *)addr+1) = (char) video_attr;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -