/*
* $Id$
*/
#include <go32.h>
#include <bsp.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 );
}
}