--- /dev/null
+/*++
+
+Copyright (c) 1998-2001 Klaus P. Gerlicher
+
+Module Name:
+
+ vga.c
+
+Abstract:
+
+ VGA HW dependent draw routines
+
+Environment:
+
+ Kernel mode only
+
+Author:
+
+ Klaus P. Gerlicher
+ Reactos Port by Eugene Ingerman
+
+Revision 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 "precomp.h"
+
+//#include <asm/io.h>
+//#include <linux/ctype.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 font
+UCHAR cGraphTable2[16*256];
+
+////////////////////////////////////////////////////
+// DEFINES
+////
+#define VGA_EXTENDED // define this for 80x50 console mode
+
+#ifndef VGA_EXTENDED
+#define SCREEN_BUFFER_SIZE (80*25*2)
+#else
+#define SCREEN_BUFFER_SIZE (80*50*2)
+#endif
+
+/* 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 mode
+WINDOW 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_EXTENDED
+
+PUCHAR pScreenBufferVga;
+PUCHAR pScreenBufferSaveVga = NULL;
+PUCHAR pScreenBufferTempVga;
+PUCHAR pScreenBufferHardwareVga;
+PUCHAR pFontBufferVga = NULL;
+
+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 6
+
+void 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 256
+#define FONTBUFFERSIZE 8192
+
+void save_font(UCHAR* graph_table)
+{
+ PUCHAR FontBase = pFontBufferVga;
+ 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 = pFontBufferVga;
+ int i,j;
+ map_font_memory();
+
+ if(bEnter)
+ {
+#ifdef VGA_EXTENDED
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 8; j++)
+ FontBase[i*32+j] = graph_table[i*BYTESPERFONT+j];
+#else // VGA_EXTENDED
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ 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 < 16; j++)
+ FontBase[i*32+j] = graph_table[i*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();
+
+ PICE_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);
+ }
+}
+
+//*************************************************************************
+// SaveGraphicsVga()
+//
+//*************************************************************************
+void SaveGraphicsStateVga(void)
+{
+ UCHAR data;
+
+ // save current regs
+ pice_save_current_registers();
+
+ // unprotect crtc regs 0-7
+ outb_p(0x11,0x3d4);
+ data = inb_p(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
+
+ // load a font
+ load_font(cGraphTable,1);
+
+ // copy the screen content to temp area
+ PICE_memcpy(pScreenBufferTempVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ // copy the console to the screen
+ PICE_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_p(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
+ PICE_memcpy(pScreenBufferVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ // copy the temp area to the screen
+ PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferTempVga,SCREEN_BUFFER_SIZE);
+}
+
+//*************************************************************************
+// ConsoleInitVga()
+//
+// init terminal screen
+//*************************************************************************
+BOOLEAN ConsoleInitVga(void)
+{
+ BOOLEAN bResult = FALSE;
+ PUSHORT p;
+ PHYSICAL_ADDRESS FrameBuffer;
+ PHYSICAL_ADDRESS FontBuffer;
+
+
+ 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 = 80;
+#ifndef VGA_EXTENDED
+ GLOBAL_SCREEN_HEIGHT = 25;
+#else // VGA_EXTENDED
+ GLOBAL_SCREEN_HEIGHT = 50;
+#endif // VGA_EXTENDED
+
+ attr.u.Asuchar = 0x07;
+
+ // the real framebuffer
+ FrameBuffer.u.LowPart = 0xB8000;
+ pScreenBufferHardwareVga = MmMapIoSpace(FrameBuffer,SCREEN_BUFFER_SIZE,MmNonCached);
+
+ //The real font buffer
+ FontBuffer.u.LowPart = 0xA0000;
+ pFontBufferVga = MmMapIoSpace(FontBuffer,FONTBUFFERSIZE,MmNonCached);
+
+ // the console
+ pScreenBufferVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
+ // the save area
+ pScreenBufferTempVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
+
+ if(pScreenBufferVga)
+ {
+ DPRINT((0,"VGA memory phys. 0x000b0000 mapped to virt. 0x%x\n",pScreenBufferVga));
+
+ bResult = TRUE;
+
+ p = (PUSHORT)pScreenBufferVga;
+
+ PICE_memset(pScreenBufferVga,0x0,SCREEN_BUFFER_SIZE);
+
+ DPRINT((0,"VGA memory cleared!\n"));
+
+ EmptyRingBuffer();
+
+ DPRINT((0,"ConsoleInitVga() SUCCESS!\n"));
+ }
+
+ LEAVE_FUNC();
+
+ return bResult;
+}
+
+//*************************************************************************
+// ConsoleShutdownVga()
+//
+// exit terminal screen
+//*************************************************************************
+void ConsoleShutdownVga(void)
+{
+ ENTER_FUNC();
+
+ if(pScreenBufferVga)
+ {
+ PICE_free(pScreenBufferVga);
+ PICE_free(pScreenBufferTempVga);
+ MmUnmapIoSpace(pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ MmUnmapIoSpace(pFontBufferVga,FONTBUFFERSIZE);
+ }
+
+ LEAVE_FUNC();
+}
+
+