📄 vga.c
字号:
/****************************************************************************** * * Copyright (c) 2003 Gerhard W. Gruber * * PROJECT: pICE * $Source: /cvsroot/pice/pice/module/vga.c,v $ * $Revision: 1.5 $ * $Date: 2004/02/17 23:07:37 $ * $Author: lightweave $ * $Name: $ * * $Log: vga.c,v $ * Revision 1.5 2004/02/17 23:07:37 lightweave * * Improved the DEBUG facillity and replaced the configuration handler with a * new code which now can read MS Windows INI style files. See CHANGES.txt for * more details. * Also added a macro which prevents compiling for kernels before 2.4.19. * * Revision 1.4 2003/06/18 22:00:22 lightweave * DEBUG and DEBUG_SERIAL added * * *****************************************************************************/static char *ident = "$Header: /cvsroot/pice/pice/module/vga.c,v 1.5 2004/02/17 23:07:37 lightweave Exp $";/*++Copyright (c) 1998-2001 Klaus P. GerlicherModule Name: vga.cAbstract: VGA HW dependent draw routinesEnvironment: Kernel mode onlyAuthor: Klaus P. GerlicherRevision History: 04-Aug-1998: created 15-Nov-2000: general cleanup of source files Copyright notice: This file may be distributed under the terms of the GNU Public License.--*/////////////////////////////////////////////////////// INCLUDES////#include "remods.h"#include <asm/io.h>#include <linux/ctype.h>#include "precomp.h"////////////////////////////////////////////////////// PROTOTYPES////extern void pice_save_current_registers(void);extern void pice_restore_current_registers(void);extern void pice_set_mode_3_80x50(void);extern void pice_set_mode_3_80x25(void);extern UCHAR cGraphTable[8*256];// storage for original VGA fontUCHAR cGraphTable2[16*256];////////////////////////////////////////////////////// DEFINES////#define VGA_EXTENDED // define this for 80x50 console mode#define VGA_COLUMNS 80#define VGA_FONTWIDTH_16 16#define VGA_FONTWIDTH_8 8#ifdef VGA_EXTENDED#define VGA_LINES 25#define VGA_FONTWIDTH VGA_FONTWIDTH_16#else#define VGA_LINES 50#define VGA_FONTWIDTH VGA_FONTWIDTH_8#endif#define SCREEN_BUFFER_SIZE (VGA_COLUMNS*VGA_LINES*2)/* Port addresses of control regs */#define MISCOUTPUT 0x3c2#define FEATURECONTROL 0x3da#define SEQUENCER 0x3c4#define CRTC 0x03d4#define GRAPHICS 0x3ce#define ATTRIBS 0x03c0#define PELADDRESSWRITE 0x3c8#define PELDATAREG 0x3c9/* Number of regs on the various controllers */#define MAXSEQ 5#define MAXCRTC 0x19#define MAXGRAPH 0x9#define MAXATTRIB 0x015////////////////////////////////////////////////////// GLOBALS////// used for HERCULES text and VGA text modeWINDOW wWindowVga[4]=#ifndef VGA_EXTENDED{ {1,3,1,0,FALSE}, {5,4,1,0,FALSE}, {10,9,1,0,FALSE}, {20,4,1,0,FALSE}};#else // VGA_EXTENDED{ {1,3,1,0,FALSE}, {5,4,1,0,FALSE}, {10,24,1,0,FALSE}, {35,14,1,0,FALSE}};#endif // VGA_EXTENDEDPUCHAR pScreenBufferVga;PUCHAR pScreenBufferSaveVga = NULL; PUCHAR pScreenBufferTempVga;PUCHAR pScreenBufferHardwareVga;UCHAR offset_a = 0;UCHAR offset_c = 0,offset_d = 0;UCHAR offset_e = 0,offset_f = 0;struct _attr{ union { struct { UCHAR fgcol : 4; UCHAR bkcol : 3; UCHAR blink : 1; }bits; UCHAR Asuchar; }u;}attr;unsigned char oldgraphicsmode;unsigned char oldgraphicsmisc;unsigned char oldsqregmapmask;unsigned char oldsqregmemory;unsigned char oldgraphicssetresetenable;unsigned char oldgraphicsreadmapsel;unsigned char read_vga_reg(int port, int reg){ outportb(port,reg); return(inportb(port+1));}void write_vga_reg(int port, unsigned char reg, unsigned char value){ outportb(port,reg); outportb(port+1,value);}/* Registers within controllers */#define VREND 0x11#define GRREGSETRESET 0#define GRREGENABLESETRESET 1#define GRREGREADMAPSEL 4#define SQREGMAPMASK 2#define SQREGMEMORY 4#define GRREGWRMODE 5#define GRREGMISC 6void map_font_memory(void){ oldgraphicssetresetenable = read_vga_reg(GRAPHICS, GRREGENABLESETRESET); oldgraphicsmode = read_vga_reg(GRAPHICS, GRREGWRMODE); oldgraphicsmisc = read_vga_reg(GRAPHICS, GRREGMISC); oldgraphicsreadmapsel = read_vga_reg(GRAPHICS, GRREGREADMAPSEL); oldsqregmapmask = read_vga_reg(SEQUENCER, SQREGMAPMASK); oldsqregmemory = read_vga_reg(SEQUENCER, SQREGMEMORY); /* Make sure set/reset enable is off */ write_vga_reg(GRAPHICS,GRREGENABLESETRESET,0); /* Select read plane 2 */ write_vga_reg(GRAPHICS,GRREGREADMAPSEL,0x02); /* Make sure write and read mode = 0 */ write_vga_reg(GRAPHICS,GRREGWRMODE,0x00); /* Set mapping to 64K at a000:0 & turn off odd/even at the graphics reg */ write_vga_reg(GRAPHICS,GRREGMISC, 0x04); /* Set sequencer plane to 2 */ write_vga_reg(SEQUENCER,SQREGMAPMASK, 0x04); /* Turn off odd/even at the sequencer */ write_vga_reg(SEQUENCER,SQREGMEMORY, 0x07);}void unmap_font_memory(void){ write_vga_reg(GRAPHICS,GRREGENABLESETRESET,oldgraphicssetresetenable); write_vga_reg(GRAPHICS,GRREGWRMODE,oldgraphicsmode); write_vga_reg(GRAPHICS,GRREGREADMAPSEL,oldgraphicsreadmapsel); write_vga_reg(GRAPHICS,GRREGMISC, oldgraphicsmisc); write_vga_reg(SEQUENCER,SQREGMAPMASK, oldsqregmapmask); write_vga_reg(SEQUENCER,SQREGMEMORY, oldsqregmemory);}/* Font and palette constants */#define BYTESPERFONT 8#define FONTENTRIES 256void save_font(UCHAR* graph_table){ PUCHAR FontBase = (PUCHAR)0xC00A0000; int i,j; map_font_memory(); for (i=0; i < FONTENTRIES; i++) for (j=0; j < 16; j++) graph_table[i*16+j] = FontBase[i*32+j]; unmap_font_memory();}void load_font(UCHAR* graph_table,int bEnter){ PUCHAR FontBase = (PUCHAR)0xC00A0000; int i,j; map_font_memory(); if(bEnter) { for (i = 0; i < FONTENTRIES; i++) { for (j = 0; j < VGA_FONTWIDTH; j++) {#ifdef VGA_EXTENDED FontBase[i*32+j] = graph_table[i*BYTESPERFONT+j];#else FontBase[i*32+j] = graph_table[i*BYTESPERFONT+(j/2)] << (j&1);#endif // VGA_EXTENDED } } } else { for (i=0; i < FONTENTRIES; i++) { for (j = 0; j < VGA_FONTWIDTH_16; j++) FontBase[i*32+j] = graph_table[i*VGA_FONTWIDTH_16+j]; } } unmap_font_memory();}//*************************************************************************// SetForegroundColorVga()////*************************************************************************void SetForegroundColorVga(ECOLORS col){ attr.u.bits.fgcol = col; attr.u.bits.blink = 0;}//*************************************************************************// SetBackgroundColorVga()////*************************************************************************void SetBackgroundColorVga(ECOLORS col){ attr.u.bits.bkcol = col; attr.u.bits.blink = 0;}//*************************************************************************// PrintGrafVga()////*************************************************************************void PrintGrafVga(ULONG x,ULONG y,UCHAR c){ ((PUSHORT)pScreenBufferVga)[y*GLOBAL_SCREEN_WIDTH + x] = (USHORT)((attr.u.Asuchar<<8)|c);}//*************************************************************************// ShowCursor()//// show hardware cursor//*************************************************************************void ShowCursorVga(void){ ENTER_FUNC(); bCursorEnabled=TRUE; outb_p(0x0a,0x3d4); outb_p(inb_p(0x3d5)&~0x20,0x3d5); LEAVE_FUNC();}//*************************************************************************// HideCursorVga()//// hide hardware cursor//*************************************************************************void HideCursorVga(void){ ENTER_FUNC(); bCursorEnabled=FALSE; outb_p(0x0a,0x3d4); outb_p(inb_p(0x3d5)|0x20,0x3d5); LEAVE_FUNC();}//*************************************************************************// CopyLineTo()//// copy a line from src to dest//*************************************************************************void CopyLineToVga(USHORT dest,USHORT src){ PUSHORT p = (PUSHORT)pScreenBufferVga; ENTER_FUNC(); memcpy(&p[dest*GLOBAL_SCREEN_WIDTH],&p[src*GLOBAL_SCREEN_WIDTH],GLOBAL_SCREEN_WIDTH*sizeof(USHORT)); LEAVE_FUNC();}//*************************************************************************// InvertLineVga()//// invert a line on the screen//*************************************************************************void InvertLineVga(ULONG line){ ULONG i; PUSHORT p = (PUSHORT)pScreenBufferVga; USHORT attr; if(line < GLOBAL_SCREEN_HEIGHT) { attr = p[line*GLOBAL_SCREEN_WIDTH]>>8; attr = ((attr & 0x07)<<4) | ((attr & 0xF0)>>4); attr <<= 8; for(i=0;i<GLOBAL_SCREEN_WIDTH;i++) p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0x00FF) | attr; }}//*************************************************************************// HatchLineVga()//// hatches a line on the screen//*************************************************************************void HatchLineVga(ULONG line){ ULONG i; PUSHORT p = (PUSHORT)pScreenBufferVga; if(line < GLOBAL_SCREEN_HEIGHT) { for(i=0;i<GLOBAL_SCREEN_WIDTH;i++) p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0xF0FF) | 0x0c00; }}//*************************************************************************// ClrLineVga()//// clear a line on the screen//*************************************************************************void ClrLineVga(ULONG line){ ULONG i; PUSHORT p = (PUSHORT)pScreenBufferVga; if(line < GLOBAL_SCREEN_HEIGHT) { for(i=0;i<GLOBAL_SCREEN_WIDTH;i++) p[line*GLOBAL_SCREEN_WIDTH + i] = (USHORT)((attr.u.Asuchar<<8) | 0x20); }}//*************************************************************************// PrintLogoVga()////*************************************************************************void PrintLogoVga(BOOLEAN bShow){ NOT_IMPLEMENTED();}//*************************************************************************// PrintCursorVga()//// emulate a blinking cursor block//*************************************************************************void PrintCursorVga(BOOLEAN bForce){ static ULONG count=0; USHORT charoffset; UCHAR data; ULONG x=wWindow[OUTPUT_WINDOW].usCurX,y=wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY; if( count++>250 ) { count=0; charoffset = (y* GLOBAL_SCREEN_WIDTH + x); outb_p(0x0e,0x3d4); data=(UCHAR)((charoffset>>8)&0xFF); outb_p(data,0x3d5); outb_p(0x0f,0x3d4); data=(UCHAR)(charoffset & 0xFF); outb_p(data,0x3d5); }}//*************************************************************************// SaveGraphicsStateVga()////*************************************************************************void SaveGraphicsStateVga(void){ UCHAR data; // save current regs pice_save_current_registers(); // unprotect crtc regs 0-7 outb_p(0x11,0x3d4); data = inb(0x3d5); outb_p(data & 0x7F,0x3d5); // save current font save_font(cGraphTable2); // restore original regs#ifdef VGA_EXTENDED pice_set_mode_3_80x50();#else pice_set_mode_3_80x25();#endif // VGA_EXTENDED // load a font load_font(cGraphTable,1); // copy the screen content to temp area memcpy(pScreenBufferTempVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE); // copy the console to the screen memcpy(pScreenBufferHardwareVga,pScreenBufferVga,SCREEN_BUFFER_SIZE); // save original pointer pScreenBufferSaveVga = pScreenBufferVga; // pScreenBufferVga now points to screen pScreenBufferVga = pScreenBufferHardwareVga;}//*************************************************************************// RestoreGraphicsStateVga()////*************************************************************************void RestoreGraphicsStateVga(void){ UCHAR data; // unprotect crtc regs 0-7 outb_p(0x11,0x3d4); data = inb(0x3d5); outb_p(data & 0x7F,0x3d5); // restore original regs pice_restore_current_registers(); // load a font load_font(cGraphTable2,0); pScreenBufferVga = pScreenBufferSaveVga; // copy screen to the console memcpy(pScreenBufferVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE); // copy the temp area to the screen memcpy(pScreenBufferHardwareVga,pScreenBufferTempVga,SCREEN_BUFFER_SIZE);}//*************************************************************************// ConsoleInitVga()//// init terminal screen//*************************************************************************BOOLEAN ConsoleInitVga(void) { BOOLEAN bResult = FALSE; PUSHORT p; ENTER_FUNC(); ohandlers.CopyLineTo = CopyLineToVga; ohandlers.PrintGraf = PrintGrafVga; ohandlers.ClrLine = ClrLineVga; ohandlers.InvertLine = InvertLineVga; ohandlers.HatchLine = HatchLineVga; ohandlers.PrintLogo = PrintLogoVga; ohandlers.PrintCursor = PrintCursorVga; ohandlers.SaveGraphicsState = SaveGraphicsStateVga; ohandlers.RestoreGraphicsState = RestoreGraphicsStateVga; ohandlers.ShowCursor = ShowCursorVga; ohandlers.HideCursor = HideCursorVga; ohandlers.SetForegroundColor = SetForegroundColorVga; ohandlers.SetBackgroundColor = SetBackgroundColorVga; ihandlers.GetKeyPolled = KeyboardGetKeyPolled; ihandlers.FlushKeyboardQueue = KeyboardFlushKeyboardQueue; SetWindowGeometry(wWindowVga); GLOBAL_SCREEN_WIDTH = VGA_COLUMNS; GLOBAL_SCREEN_HEIGHT = VGA_LINES; attr.u.Asuchar = 0x07; DPRINT(PICE_DEBUG, DBT_VGA, DBL_INFO, "Allocatig VGA buffer"); // the real framebuffer pScreenBufferHardwareVga = ioremap(0xB8000,SCREEN_BUFFER_SIZE); // the console pScreenBufferVga = PICE_HeapAlloc(SCREEN_BUFFER_SIZE); // the save area pScreenBufferTempVga = PICE_HeapAlloc(SCREEN_BUFFER_SIZE); if(pScreenBufferVga) { DPRINT(PICE_DEBUG, DBT_VGA, DBL_INFO, "VGA memory phys. 0x000b8000 mapped to virt. 0x%p\n", pScreenBufferVga); bResult = TRUE; p = (PUSHORT)pScreenBufferVga; PICE_memset(pScreenBufferVga, 0x0, SCREEN_BUFFER_SIZE); DPRINT(PICE_DEBUG, DBT_VGA, DBL_INFO, "VGA memory cleared!\n"); EmptyRingBuffer(); DPRINT(PICE_DEBUG, DBT_VGA, DBL_INFO, "SUCCESS!\n"); } LEAVE_FUNC(); return bResult;}//*************************************************************************// ConsoleShutdownVga()//// exit terminal screen//*************************************************************************void ConsoleShutdownVga(void) { ENTER_FUNC(); if(pScreenBufferVga) { PICE_HeapFree(pScreenBufferVga); PICE_HeapFree(pScreenBufferTempVga); iounmap(pScreenBufferHardwareVga); } LEAVE_FUNC();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -