diff options
Diffstat (limited to 'c/src/lib/libbsp/i386/go32/console/outch.c')
-rw-r--r-- | c/src/lib/libbsp/i386/go32/console/outch.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i386/go32/console/outch.c b/c/src/lib/libbsp/i386/go32/console/outch.c new file mode 100644 index 0000000000..190baea168 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/console/outch.c @@ -0,0 +1,151 @@ +/* + * $Id$ + */ + +#include <go32.h> +#include <bsp.h> +#include <cpu.h> + +#include <memory.h> + +#define MAX_COL 80 +#define MAX_ROW 50 + +static unsigned nrow = 25; +static unsigned ncol = 80; +static unsigned short * tvram = TVRAM; +static unsigned char current_col = 0; +static unsigned char current_row = 0; +static unsigned short screen_copy[ MAX_ROW*MAX_COL ]; + +static void init_cons( void ); + +/* + * set_cursor_pos() + * Set cursor position based on current absolute screen offset + */ +static void +set_cursor_pos(void) +{ + register unsigned short gdc_pos = current_row * ncol + current_col; + outport_byte( GDC_REG_PORT, 0xe ); + outport_byte( GDC_VAL_PORT, (gdc_pos >> 8) & 0xff ); + outport_byte( GDC_REG_PORT, 0xf ); + outport_byte( GDC_VAL_PORT, gdc_pos & 0xff ); +} + +/* + * scroll_up() + * Scroll screen up one line + */ +static void +scroll_up( unsigned short * tv, unsigned short * copy, unsigned int lines ) +{ + if ( lines > nrow ) + lines = nrow; + + /* move everything up */ + memmove( copy, copy+ncol*lines, (nrow-lines)*ncol*sizeof copy[0] ); + + /* fill bottom with blanks */ + { + int loop = ncol*lines; + unsigned short * ptr = copy + ncol*(nrow-lines); + while ( --loop >= 0 ) + *ptr++ = (WHITE<<8) | ' '; + } + + /* copy new screen to video buffer */ + dosmemput( copy, nrow*ncol*sizeof copy[0], (int)tv ); +} + + +/* + * PUT() + * Write character at current screen location + */ +inline static void PUT( char c ) +{ + unsigned short loc = current_row*ncol+current_col; + unsigned short val = (WHITE<<8) | c; + screen_copy[loc] = val; + dosmemput( &screen_copy[loc], sizeof screen_copy[0], (int)(tvram+loc) ); +} + +/* + * cons_putc() + * Place a character on next screen position + */ +static void +cons_putc( unsigned char c ) +{ + static int first = 1; + if ( first ) { + init_cons(); + first = 0; + } + + switch (c) { + case '\t': + while ( current_row % 8 ) + cons_putc(' '); + break; + case '\r': + current_col = 0; + break; + case '\n': + if ( ++current_row >= nrow ) { + scroll_up( tvram, screen_copy, 1 ); + current_row -= 1; + } + break; + case '\b': + if ( current_col > 0 ) { + --current_col; + PUT(' '); + } + break; + default: + PUT(c); + current_col += 1; + if ( current_col >= ncol ) { + current_col = 0; + current_row += 1; + if ( current_row >= nrow ) { + scroll_up( tvram, screen_copy, 1 ); + current_row -= 1; + } + } + }; + set_cursor_pos(); +} + + +/* + * init_cons() + * Hook for any early setup + */ +static void +init_cons( void ) +{ +#if 0 + /* Get a copy of original screen */ + dosmemget( (int)tvram, nrow*ncol*sizeof *tvram, screen_copy ); +#else + /* Clear entire screen */ + scroll_up( tvram, screen_copy, nrow ); +#endif +} + + + +void _IBMPC_outch( unsigned char ch ) +{ + extern int _IBMPC_Use_Go32_IO; + + if ( _IBMPC_Use_Go32_IO ) { + write( 1, &ch, 1 ); + } else { + cons_putc( ch ); + } +} |