X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fscreen.c;fp=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fscreen.c;h=0000000000000000000000000000000000000000;hp=077112fe40432b0a3af7758a917f3b2e3bb9a54f;hb=a70930549d1b741704dd7af4e6bb0e89f6f8a519;hpb=afb634a80f946634454a5d067a92aa600227bd93 diff --git a/misc/test_vm/src/geekos/screen.c b/misc/test_vm/src/geekos/screen.c deleted file mode 100644 index 077112f..0000000 --- a/misc/test_vm/src/geekos/screen.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * GeekOS text screen output - * Copyright (c) 2001,2003,2004 David H. Hovemeyer - * $Revision: 1.1 $ - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "COPYING". - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * Information sources for VT100 and ANSI escape sequences: - * - http://www.lns.cornell.edu/~pvhp/dcl/vt100.html - * - http://en.wikipedia.org/wiki/ANSI_escape_code - */ - -/* ---------------------------------------------------------------------- - * Private functions and data - * ---------------------------------------------------------------------- */ - -#define ESC ((char) 0x1B) -#define DEFAULT_ATTRIBUTE ATTRIB(BLACK, GRAY) - -enum State { - S_NORMAL, /* Normal state - output is echoed verbatim */ - S_ESC, /* Saw ESC character - begin output escape sequence */ - S_ESC2, /* Saw '[' character - continue output escape sequence */ - S_ARG, /* Scanning a numeric argument */ - S_CMD, /* Command */ -}; - -#define MAXARGS 8 /* Max args that can be passed to esc sequence */ - -struct Console_State { - /* Current state information */ - int row, col; - int saveRow, saveCol; - uchar_t currentAttr; - - /* Working variables for processing escape sequences. */ - enum State state; - int argList[MAXARGS]; - int numArgs; -}; - -static struct Console_State s_cons; - -#define NUM_SCREEN_DWORDS ((NUMROWS * NUMCOLS * 2) / 4) -#define NUM_SCROLL_DWORDS (((NUMROWS-1) * NUMCOLS * 2) / 4) -#define NUM_DWORDS_PER_LINE ((NUMCOLS*2)/4) -#define FILL_DWORD (0x00200020 | (s_cons.currentAttr<<24) | (s_cons.currentAttr<<8)) - -/* - * Scroll the display one line. - * We speed things up by copying 4 bytes at a time. - */ -static void Scroll(void) -{ - uint_t* v; - int i, n = NUM_SCROLL_DWORDS; - uint_t fill = FILL_DWORD; - - /* Move lines 1..NUMROWS-1 up one position. */ - for (v = (uint_t*)VIDMEM, i = 0; i < n; ++i) { - *v = *(v + NUM_DWORDS_PER_LINE); - ++v; - } - - /* Clear out last line. */ - for (v = (uint_t*)VIDMEM + n, i = 0; i < NUM_DWORDS_PER_LINE; ++i) - *v++ = fill; -} - -/* - * Clear current cursor position to end of line using - * current attribute. - */ -static void Clear_To_EOL(void) -{ - int n = (NUMCOLS - s_cons.col); - uchar_t* v = VIDMEM + s_cons.row*(NUMCOLS*2) + s_cons.col*2; - while (n-- > 0) { - *v++ = ' '; - *v++ = s_cons.currentAttr; - } -} - -/* - * Move to the beginning of the next line, scrolling - * if necessary. - */ -static void Newline(void) -{ - ++s_cons.row; - s_cons.col = 0; - if (s_cons.row == NUMROWS) { - Scroll(); - s_cons.row = NUMROWS - 1; - } -} - -/* - * Write the graphic representation of given character to the screen - * at current position, with current attribute, scrolling if - * necessary. - */ -static void Put_Graphic_Char(int c) -{ - uchar_t* v = VIDMEM + s_cons.row*(NUMCOLS*2) + s_cons.col*2; - - /* Put character at current position */ - *v++ = (uchar_t) c; - *v = s_cons.currentAttr; - - if (s_cons.col < NUMCOLS - 1) - ++s_cons.col; - else - Newline(); -} - -/* - * Put one character to the screen using the current cursor position - * and attribute, scrolling if needed. The caller should update - * the cursor position once all characters have been written. - */ -static void Output_Literal_Character(int c) -{ - int numSpaces; - - switch (c) { - case '\n': - Clear_To_EOL(); - Newline(); - break; - - case '\t': - numSpaces = TABWIDTH - (s_cons.col % TABWIDTH); - while (numSpaces-- > 0) - Put_Graphic_Char(' '); - break; - - default: - Put_Graphic_Char(c); - break; - } - -#ifndef NDEBUG - /* - * When compiled with --enable-port-e9-hack, Bochs will send writes - * to port E9 to the console. This helps tremendously with debugging, - * because it allows debug Print() statements to be visible after - * Bochs has exited. - */ - Out_Byte(0xE9, c); -#endif -} - -/* - * Move the cursor to a new position, stopping at the screen borders. - */ -static void Move_Cursor(int row, int col) -{ - if (row < 0) - row = 0; - else if (row >= NUMROWS) - row = NUMROWS - 1; - - if (col < 0) - col = 0; - else if (col >= NUMCOLS) - col = NUMCOLS - 1; - - s_cons.row = row; - s_cons.col = col; -} - -/* - * Table mapping ANSI colors to VGA text mode colors. - */ -static const uchar_t s_ansiToVgaColor[] = { - BLACK,RED,GREEN,AMBER,BLUE,MAGENTA,CYAN,GRAY -}; - -/* - * Update the attributes specified by the arguments - * of the escape sequence. - */ -static void Update_Attributes(void) -{ - int i; - int attr = s_cons.currentAttr & ~(BRIGHT); - - for (i = 0; i < s_cons.numArgs; ++i) { - int value = s_cons.argList[i]; - if (value == 0) - attr = DEFAULT_ATTRIBUTE; - else if (value == 1) - attr |= BRIGHT; - else if (value >= 30 && value <= 37) - attr = (attr & ~0x7) | s_ansiToVgaColor[value - 30]; - else if (value >= 40 && value <= 47) - attr = (attr & ~(0x7 << 4)) | (s_ansiToVgaColor[value - 40] << 4); - } - s_cons.currentAttr = attr; -} - -/* Reset to cancel or finish processing an escape sequence. */ -static void Reset(void) -{ - s_cons.state = S_NORMAL; - s_cons.numArgs = 0; -} - -/* Start an escape sequence. */ -static void Start_Escape(void) -{ - s_cons.state = S_ESC; - s_cons.numArgs = 0; -} - -/* Start a numeric argument to an escape sequence. */ -static void Start_Arg(int argNum) -{ - KASSERT(s_cons.numArgs == argNum); - s_cons.numArgs++; - s_cons.state = S_ARG; - if (argNum < MAXARGS) - s_cons.argList[argNum] = 0; -} - -/* Save current cursor position. */ -static void Save_Cursor(void) -{ - s_cons.saveRow = s_cons.row; - s_cons.saveCol = s_cons.col; -} - -/* Restore saved cursor position. */ -static void Restore_Cursor(void) -{ - s_cons.row = s_cons.saveRow; - s_cons.col = s_cons.saveCol; -} - -/* Add a digit to current numeric argument. */ -static void Add_Digit(int c) -{ - KASSERT(ISDIGIT(c)); - if (s_cons.numArgs < MAXARGS) { - int argNum = s_cons.numArgs - 1; - s_cons.argList[argNum] *= 10; - s_cons.argList[argNum] += (c - '0'); - } -} - -/* - * Get a numeric argument. - * Returns zero if that argument was not actually specified. - */ -static int Get_Arg(int argNum) -{ - return argNum < s_cons.numArgs ? s_cons.argList[argNum] : 0; -} - -/* - * The workhorse output function. - * Depending on the current console output state, - * does literal character output or processes part of - * an escape sequence. - */ -static void Put_Char_Imp(int c) -{ -again: - switch (s_cons.state) { - case S_NORMAL: - if (c == ESC) - Start_Escape(); - else - Output_Literal_Character(c); - break; - - case S_ESC: - if (c == '[') - s_cons.state = S_ESC2; - else - Reset(); - break; - - case S_ESC2: - if (ISDIGIT(c)) { - Start_Arg(0); - goto again; - } else if (c == ';') { - /* Special case: for "n;m" commands, "n" is implicitly 1 if omitted */ - Start_Arg(0); - Add_Digit('1'); - Start_Arg(1); - } else { - s_cons.state = S_CMD; - goto again; - } - break; - - case S_ARG: - if (ISDIGIT(c)) - Add_Digit(c); - else if (c == ';') - Start_Arg(s_cons.numArgs); - else { - s_cons.state = S_CMD; - goto again; - } - break; - - case S_CMD: - switch (c) { - case 'K': Clear_To_EOL(); break; - case 's': Save_Cursor(); break; - case 'u': Restore_Cursor(); break; - case 'A': Move_Cursor(s_cons.row - Get_Arg(0), s_cons.col); break; - case 'B': Move_Cursor(s_cons.row + Get_Arg(0), s_cons.col); break; - case 'C': Move_Cursor(s_cons.row, s_cons.col + Get_Arg(0)); break; - case 'D': Move_Cursor(s_cons.row, s_cons.col - Get_Arg(0)); break; - case 'm': Update_Attributes(); break; - case 'f': case 'H': - if (s_cons.numArgs == 2) Move_Cursor(Get_Arg(0)-1, Get_Arg(1)-1); break; - case 'J': - if (s_cons.numArgs == 1 && Get_Arg(0) == 2) { - Clear_Screen(); - Put_Cursor(0, 0); - } - break; - default: break; - } - Reset(); - break; - - default: - KASSERT(false); - } -} - -/* - * Update the location of the hardware cursor. - */ -static void Update_Cursor(void) -{ - /* - * The cursor location is a character offset from the beginning - * of page memory (I think). - */ - uint_t characterPos = (s_cons.row * NUMCOLS) + s_cons.col; - uchar_t origAddr; - - /* - * Save original contents of CRT address register. - * It is considered good programming practice to restore - * it to its original value after modifying it. - */ - origAddr = In_Byte(CRT_ADDR_REG); - IO_Delay(); - - /* Set the high cursor location byte */ - Out_Byte(CRT_ADDR_REG, CRT_CURSOR_LOC_HIGH_REG); - IO_Delay(); - Out_Byte(CRT_DATA_REG, (characterPos>>8) & 0xff); - IO_Delay(); - - /* Set the low cursor location byte */ - Out_Byte(CRT_ADDR_REG, CRT_CURSOR_LOC_LOW_REG); - IO_Delay(); - Out_Byte(CRT_DATA_REG, characterPos & 0xff); - IO_Delay(); - - /* Restore contents of the CRT address register */ - Out_Byte(CRT_ADDR_REG, origAddr); -} - -/* ---------------------------------------------------------------------- - * Public functions - * ---------------------------------------------------------------------- */ - -/* - * Initialize the screen module. - */ -void Init_Screen(void) -{ - bool iflag = Begin_Int_Atomic(); - - s_cons.row = s_cons.col = 0; - s_cons.currentAttr = DEFAULT_ATTRIBUTE; - Clear_Screen(); - - End_Int_Atomic(iflag); - Print("Screen Inited\n"); -} - -/* - * Clear the screen using the current attribute. - */ -void Clear_Screen(void) -{ - uint_t* v = (uint_t*)VIDMEM; - int i; - uint_t fill = FILL_DWORD; - - bool iflag = Begin_Int_Atomic(); - - for (i = 0; i < NUM_SCREEN_DWORDS; ++i) - *v++ = fill; - - End_Int_Atomic(iflag); -} - -/* - * Get current cursor position. - */ -void Get_Cursor(int* row, int* col) -{ - bool iflag = Begin_Int_Atomic(); - *row = s_cons.row; - *col = s_cons.col; - End_Int_Atomic(iflag); -} - -/* - * Set the current cursor position. - * Return true if successful, or false if the specified - * cursor position is invalid. - */ -bool Put_Cursor(int row, int col) -{ - bool iflag; - - if (row < 0 || row >= NUMROWS || col < 0 || col >= NUMCOLS) - return false; - - iflag = Begin_Int_Atomic(); - s_cons.row = row; - s_cons.col = col; - Update_Cursor(); - End_Int_Atomic(iflag); - - return true; -} - -/* - * Get the current character attribute. - */ -uchar_t Get_Current_Attr(void) -{ - return s_cons.currentAttr; -} - -/* - * Set the current character attribute. - */ -void Set_Current_Attr(uchar_t attrib) -{ - bool iflag = Begin_Int_Atomic(); - s_cons.currentAttr = attrib; - End_Int_Atomic(iflag); -} - -/* - * Write a single character to the screen at current position - * using current attribute, handling scrolling, special characters, etc. - */ -void Put_Char(int c) -{ - bool iflag = Begin_Int_Atomic(); - Put_Char_Imp(c); - Update_Cursor(); - End_Int_Atomic(iflag); -} - -/* - * Write a string of characters to the screen at current cursor - * position using current attribute. - */ -void Put_String(const char* s) -{ - bool iflag = Begin_Int_Atomic(); - while (*s != '\0') - Put_Char_Imp(*s++); - Update_Cursor(); - End_Int_Atomic(iflag); -} - -/* - * Write a buffer of characters at current cursor position - * using current attribute. - */ -void Put_Buf(const char* buf, ulong_t length) -{ - bool iflag = Begin_Int_Atomic(); - while (length > 0) { - Put_Char_Imp(*buf++); - --length; - } - Update_Cursor(); - End_Int_Atomic(iflag); -} - -/* Support for Print(). */ -static void Print_Emit(struct Output_Sink *o, int ch) { Put_Char_Imp(ch); } -static void Print_Finish(struct Output_Sink *o) { Update_Cursor(); } -static struct Output_Sink s_outputSink = { &Print_Emit, &Print_Finish }; - -/* - * Print to console using printf()-style formatting. - * Calls into Format_Output in common library. - */ - -static __inline__ void PrintInternal(const char * format, va_list ap) { - Format_Output(&s_outputSink, format, ap); -} - - -void Print(const char *fmt, ...) -{ - va_list args; - - bool iflag = Begin_Int_Atomic(); - - va_start(args, fmt); - PrintInternal(fmt, args); - va_end(args); - - End_Int_Atomic(iflag); -} - -void PrintList(const char * fmt, va_list ap) { - bool iflag = Begin_Int_Atomic(); - PrintInternal(fmt, ap); - End_Int_Atomic(iflag); -}