diff options
Diffstat (limited to 'bsps/i386/pc386/console/outch.c')
-rw-r--r-- | bsps/i386/pc386/console/outch.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/bsps/i386/pc386/console/outch.c b/bsps/i386/pc386/console/outch.c new file mode 100644 index 0000000000..90ffedf250 --- /dev/null +++ b/bsps/i386/pc386/console/outch.c @@ -0,0 +1,328 @@ +/* + * outch.c - This file contains code for displaying characters + * on the console uisng information that should be + * maintained by the BIOS in its data Area. + * + * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Till Straumann <strauman@slac.stanford.edu>, 2003/9: + * - added handling of basic escape sequences (cursor movement + * and erasing; just enough for the line editor 'libtecla' to + * work...) + */ + +#include <bsp.h> + +#include <stdlib.h> +#include <string.h> + +#include <crt.h> + +extern void wr_cursor(int, unsigned short); + +#define TAB_SPACE 4 +static unsigned short *bitMapBaseAddr; +static unsigned short ioCrtBaseAddr; +static unsigned short maxCol; +static unsigned short maxRow; +static unsigned char row; +static unsigned char column; +static unsigned short attribute; +static unsigned int nLines; + +static void +scroll(void) +{ + int i, j; /* Counters */ + unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */ + + pt_bitmap = bitMapBaseAddr; + j = 0; + pt_bitmap = pt_bitmap + j; + pt_scroll = pt_bitmap + maxCol; + for (i = j; i < (maxRow - 1) * maxCol; i++) { + *pt_bitmap++ = *pt_scroll++; + } + + /* + * Blank characters are displayed on the last line. + */ + for (i = 0; i < maxCol; i++) { + *pt_bitmap++ = (short) (' ' | attribute); + } +} + +static void +doCRNL(int cr, int nl) +{ + if (nl) { + if (++row == maxRow) { + scroll(); /* Scroll the screen now */ + row = maxRow - 1; + } + nLines++; + } + if (cr) + column = 0; + /* Move cursor on the next location */ + if (cr || nl) + wr_cursor(row * maxCol + column, ioCrtBaseAddr); +} + +int (*videoHook)(char, int *)=0; + +static void +advanceCursor(void) +{ + if (++column == maxCol) + doCRNL(1,1); + else + wr_cursor(row * maxCol + column, ioCrtBaseAddr); +} + +static void +gotorc(int r, int c) +{ + column = c; + row = r; + + wr_cursor(row * maxCol + column, ioCrtBaseAddr); +} + +#define ESC ((char)27) +/* erase current location without moving the cursor */ +#define BLANK ((char)0x7f) + +static void +videoPutChar(char car) +{ + unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol + column; + + switch (car) { + case '\b': { + if (column) column--; + /* Move cursor on the previous location */ + wr_cursor(row * maxCol + column, ioCrtBaseAddr); + return; + } + case '\t': { + int i; + + i = TAB_SPACE - (column & (TAB_SPACE - 1)); + column += i; + if (column >= maxCol) { + doCRNL(1,1); + return; + } + while (i--) *pt_bitmap++ = ' ' | attribute; + wr_cursor(row * maxCol + column, ioCrtBaseAddr); + return; + } + case '\n': { + doCRNL(0,1); + return; + } + case 7: { /* Bell code must be inserted here */ + return; + } + case '\r' : { + doCRNL(1,0); + return; + } + case BLANK: { + *pt_bitmap = ' ' | attribute; + /* DONT move the cursor... */ + return; + } + default: { + *pt_bitmap = (unsigned char)car | attribute; + advanceCursor(); + return; + } + } +} + +/* trivial state machine to handle escape sequences: + * + * --------------------------------- + * | | + * | | + * KEY: esc V [ DCABHKJ esc | + * STATE: 0 -----> 27 -----> '[' ----------> -1 ----- + * ^\ \ \ \ + * KEY: | \other \ other \ other \ other + * <------------------------------------- + * + * in state '-1', the DCABHKJ cases are handled + * + * (cursor motion and screen clearing) + */ + +#define DONE (-1) + +static int +handleEscape(int oldState, char car) +{ +int rval = 0; +int ro,co; + + switch ( oldState ) { + case DONE: /* means the previous char terminated an ESC sequence... */ + case 0: + if ( 27 == car ) { + rval = 27; /* START of an ESC sequence */ + } + break; + + case 27: + if ( '[' == car ) { + rval = car; /* received ESC '[', so far */ + } else { + /* dump suppressed 'ESC'; outch will append the char */ + videoPutChar(ESC); + } + break; + + case '[': + /* handle 'ESC' '[' sequences here */ + ro = row; co = column; + rval = DONE; /* done */ + + switch (car) { + case 'D': /* left */ + if ( co > 0 ) co--; + break; + case 'C': /* right */ + if ( co < maxCol ) co++; + break; + case 'A': /* up */ + if ( ro > 0 ) ro--; + break; + case 'B': /* down */ + if ( ro < maxRow ) ro++; + break; + case 'H': /* home */ + ro = co = 0; + break; + case 'K': /* clear to end of line */ + while ( column < maxCol - 1 ) + videoPutChar(' '); + videoPutChar(BLANK); + break; + case 'J': /* clear to end of screen */ + while ( ((row < maxRow-1) || (column < maxCol-1)) ) + videoPutChar(' '); + videoPutChar(BLANK); + break; + default: + videoPutChar(ESC); + videoPutChar('['); + /* DONT move the cursor */ + ro = -1; + rval = 0; + break; + } + /* reset cursor */ + if ( ro >= 0) + gotorc(ro,co); + + default: + break; + + } + + return rval; +} + +static void +clear_screen(void) +{ + int i,j; + + for (j = 0; j <= maxRow; j++) { + for (i = 0; i <= maxCol; i++) { + videoPutChar(' '); + } + } + column = 0; + row = 0; +} + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_outch +| Description: Higher level (console) interface to consPutc. +| Global Variables: None. +| Arguments: c - character to write to console. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +void +_IBMPC_outch(char c) +{ +static int escaped = 0; + + if ( ! (escaped = handleEscape(escaped, c)) ) { + if ( '\n' == c ) + videoPutChar('\r'); + videoPutChar(c); + } +} /* _IBMPC_outch */ + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_initVideo +| Description: Video system initialization. Hook for any early setup. +| Global Variables: bitMapBaseAddr, ioCrtBaseAddr, maxCol, maxRow, row +| column, attribute, nLines; +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +void +_IBMPC_initVideo(void) +{ + unsigned char* pt = (unsigned char*) (VIDEO_MODE_ADDR); + + if (*pt == VGAMODE7) { + bitMapBaseAddr = (unsigned short*) V_MONO; + } + else { + bitMapBaseAddr = (unsigned short*) V_COLOR; + } + ioCrtBaseAddr = *(unsigned short*) DISPLAY_CRT_BASE_IO_ADDR; + maxCol = * (unsigned short*) NB_MAX_COL_ADDR; + maxRow = * (unsigned char*) NB_MAX_ROW_ADDR; + column = 0; + row = 0; + attribute = ((BLACK << 4) | WHITE)<<8; + nLines = 0; + clear_screen(); +#ifdef DEBUG_EARLY_STAGE + printk("bitMapBaseAddr = %X, display controller base IO = %X\n", + (unsigned) bitMapBaseAddr, + (unsigned) ioCrtBaseAddr); + videoPrintf("maxCol = %d, maxRow = %d\n", (unsigned) maxCol, (unsigned) maxRow); +#endif +} /* _IBMPC_initVideo */ + +/* for old DOS compatibility n-curses type of applications */ +void gotoxy( int x, int y ); +int whereX( void ); +int whereY( void ); + +void gotoxy( int x, int y ) +{ + gotorc(y,x); +} + +int whereX( void ) +{ + return row; +} + +int whereY( void ) +{ + return column; +} |