summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/console
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-12-01 22:06:48 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-12-01 22:06:48 +0000
commit7150f00f5be87fa8e37f7d00fbbef35645081138 (patch)
tree1cc7d3e1c4933404ddc1f742c7e37648cc783364 /c/src/lib/libbsp/i386/pc386/console
parentFixed test for RTEMS_HAS_POSIX_API so the executive POSIX API related (diff)
downloadrtems-7150f00f5be87fa8e37f7d00fbbef35645081138.tar.bz2
Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano
<pmcnr@camoes.rnl.ist.utl.pt> and Jose Rufino <ruf@asterix.ist.utl.pt> of NavIST (http://pandora.ist.utl.pt/).
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/console')
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/Makefile.in53
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console.c250
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/inch.c260
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/outch.c284
4 files changed, 847 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/console/Makefile.in b/c/src/lib/libbsp/i386/pc386/console/Makefile.in
new file mode 100644
index 0000000000..cd5b344be0
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/Makefile.in
@@ -0,0 +1,53 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH=@srcdir@
+
+PGM=${ARCH}/console.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=console inch outch printk
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c
new file mode 100644
index 0000000000..220b56f4a4
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/console.c
@@ -0,0 +1,250 @@
+/*-------------------------------------------------------------------------+
+| console.c v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| This file contains the PC386 console I/O package.
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on:
+| console.c,v 1.4 1995/12/19 20:07:23 joel Exp - go32 BSP
+| With the following copyright notice:
+| **************************************************************************
+| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. *
+| * On-Line Applications Research Corporation (OAR). *
+| * All rights assigned to U.S. Government, 1994. *
+| * *
+| * This material may be reproduced by or for the U.S. Government pursuant *
+| * to the copyright license under the clause at DFARS 252.227-7013. This *
+| * notice must appear in all copies of this file and its derivatives. *
+| **************************************************************************
++--------------------------------------------------------------------------*/
+
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <irq.h>
+#include <rtems/libio.h>
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+#define KEYBOARD_IRQ 0x01 /* Keyboard IRQ. */
+
+
+/*-------------------------------------------------------------------------+
+| External Prototypes
++--------------------------------------------------------------------------*/
+extern rtems_isr _IBMPC_keyboard_isr(rtems_vector_number);
+ /* keyboard (IRQ 0x01) Interrupt Service Routine (defined in 'inch.c') */
+
+
+/*-------------------------------------------------------------------------+
+| Functions
++--------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------+
+| Function: console_cleanup
+| Description: This routine is called at exit to clean up the console
+| hardware.
+| Global Variables: None.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+console_cleanup(void)
+{
+ /* nothing */
+} /* console_cleanup */
+
+
+/*-------------------------------------------------------------------------+
+| Function: is_character_ready
+| Description: Check if a character is available for input, and if so
+| return it.
+| Global Variables: None.
+| Arguments: c - character read if available, otherwise unchanged.
+| Returns: TRUE if there was a character available for input,
+| FALSE otherwise.
++--------------------------------------------------------------------------*/
+rtems_boolean
+is_character_ready(char *c)
+{
+ return (_IBMPC_chrdy(c) ? TRUE : FALSE);
+} /* is_character_ready */
+
+
+/*-------------------------------------------------------------------------+
+| Function: inbyte
+| Description: Read a character from the console (keyboard).
+| Global Variables: None.
+| Arguments: None.
+| Returns: Caracter read from the console.
++--------------------------------------------------------------------------*/
+unsigned char
+inbyte(void)
+{
+ char c = _IBMPC_inch();
+
+ /* Echo character to screen */
+ _IBMPC_outch(c);
+ if (c == '\r')
+ _IBMPC_outch('\n'); /* CR = CR + LF */
+
+ return c;
+} /* inbyte */
+
+
+/*-------------------------------------------------------------------------+
+| Function: outbyte
+| Description: Write a character to the console (display).
+| Global Variables: None.
+| Arguments: Character to be written.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+outbyte(char c)
+{
+ _IBMPC_outch(c);
+} /* outbyte */
+
+
+/*-------------------------------------------------------------------------+
+| Console device driver INITIALIZE entry point.
++--------------------------------------------------------------------------+
+| Initilizes the I/O console (keyboard + VGA display) driver.
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+
+ /* Initialize video */
+ _IBMPC_initVideo();
+
+ /* Install keyboard interrupt handler */
+ status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr);
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error installing keyboard interrupt handler!\n");
+ rtems_fatal_error_occurred(status);
+ }
+
+ status =
+ rtems_io_register_name("/dev/console", major, (rtems_device_minor_number)0);
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error registering console device!\n");
+ rtems_fatal_error_occurred(status);
+ }
+
+ atexit(console_cleanup);
+
+ return RTEMS_SUCCESSFUL;
+} /* console_initialize */
+
+
+/*-------------------------------------------------------------------------+
+| Console device driver OPEN entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return RTEMS_SUCCESSFUL;
+} /* console_open */
+
+
+/*-------------------------------------------------------------------------+
+| Console device driver CLOSE entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return RTEMS_SUCCESSFUL;
+} /* console_close */
+
+
+/*-------------------------------------------------------------------------+
+| Console device driver READ entry point.
++--------------------------------------------------------------------------+
+| Read characters from the I/O console. We only have stdin.
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
+ char *buffer = rw_args->buffer;
+ int count, maximum = rw_args->count;
+
+ for (count = 0; count < maximum; count++)
+ {
+ buffer[count] = inbyte();
+ if (buffer[count] == '\n' || buffer[count] == '\r')
+ {
+ /* What if this goes past the end of the buffer? We're hosed. [bhc] */
+ buffer[count++] = '\n';
+ buffer[count] = '\0';
+ break;
+ }
+ }
+
+ rw_args->bytes_moved = count;
+ return ((count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED);
+} /* console_read */
+
+
+/*-------------------------------------------------------------------------+
+| Console device driver WRITE entry point.
++--------------------------------------------------------------------------+
+| Write characters to the I/O console. Stderr and stdout are the same.
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
+ char *buffer = rw_args->buffer;
+ int count, maximum = rw_args->count;
+
+ for (count = 0; count < maximum; count++)
+ {
+ outbyte(buffer[count]);
+ if (buffer[count] == '\n')
+ outbyte('\r'); /* LF = LF + CR */
+ }
+
+ rw_args->bytes_moved = maximum;
+ return RTEMS_SUCCESSFUL;
+} /* console_write */
+
+
+/*-------------------------------------------------------------------------+
+| Console device driver CONTROL entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return RTEMS_SUCCESSFUL;
+} /* console_control */
diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c
new file mode 100644
index 0000000000..e87e45728c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/inch.c
@@ -0,0 +1,260 @@
+/*-------------------------------------------------------------------------+
+| inch.c v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on:
+| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP
+| With the following copyright notice:
+| **************************************************************************
+| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. *
+| * On-Line Applications Research Corporation (OAR). *
+| * All rights assigned to U.S. Government, 1994. *
+| * *
+| * This material may be reproduced by or for the U.S. Government pursuant *
+| * to the copyright license under the clause at DFARS 252.227-7013. This *
+| * notice must appear in all copies of this file and its derivatives. *
+| **************************************************************************
++--------------------------------------------------------------------------*/
+
+#include <bsp.h>
+#include <irq.h>
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+#define KBD_CTL 0x61 /* -------------------------------- */
+#define KBD_DATA 0x60 /* Ports for PC keyboard controller */
+#define KBD_STATUS 0x64 /* -------------------------------- */
+
+#define KBD_BUF_SIZE 256
+
+/*-------------------------------------------------------------------------+
+| Global Variables
++--------------------------------------------------------------------------*/
+static char key_map[] =
+{
+ 0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
+ 'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
+ 'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
+ 0134,'z','x','c','v','b','n','m',',','.','/',0x80,
+ '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,'0',0177
+}; /* Keyboard scancode -> character map with no modifiers. */
+
+static char shift_map[] =
+{
+ 0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
+ 'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
+ 'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
+ '|','Z','X','C','V','B','N','M','<','>','?',0x80,
+ '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
+ '1','2','3','0',177
+}; /* Keyboard scancode -> character map with SHIFT key modifier. */
+
+static char kbd_buffer[KBD_BUF_SIZE];
+static rtems_unsigned16 kbd_first = 0;
+static rtems_unsigned16 kbd_last = 0;
+
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_scankey
+| Description: This function can be called during a poll for input, or by
+| an ISR. Basically any time you want to process a keypress.
+| Global Variables: key_map, shift_map.
+| Arguments: outChar - character read in case of a valid reading,
+| otherwise unchanged.
+| Returns: TRUE in case a valid character has been read,
+| FALSE otherwise.
++--------------------------------------------------------------------------*/
+rtems_boolean
+_IBMPC_scankey(char *outChar)
+{
+ unsigned char inChar;
+ static int alt_pressed = 0;
+ static int ctrl_pressed = 0;
+ static int shift_pressed = 0;
+ static int caps_pressed = 0;
+ static int extended = 0;
+
+ *outChar = NULL; /* default value if we return FALSE */
+
+ /* Read keyboard controller, toggle enable */
+ inport_byte(KBD_CTL, inChar);
+ outport_byte(KBD_CTL, inChar & ~0x80);
+ outport_byte(KBD_CTL, inChar | 0x80);
+ outport_byte(KBD_CTL, inChar & ~0x80);
+
+ /* See if it has data */
+ inport_byte(KBD_STATUS, inChar);
+ if ((inChar & 0x01) == 0)
+ return FALSE;
+
+ /* Read the data. Handle nonsense with shift, control, etc. */
+ inport_byte(KBD_DATA, inChar);
+
+ if (extended)
+ extended--;
+
+ switch (inChar)
+ {
+ case 0xe0:
+ extended = 2;
+ return FALSE;
+ break;
+
+ case 0x38:
+ alt_pressed = 1;
+ return FALSE;
+ break;
+ case 0xb8:
+ alt_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x1d:
+ ctrl_pressed = 1;
+ return FALSE;
+ break;
+ case 0x9d:
+ ctrl_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x2a:
+ if (extended)
+ return FALSE;
+ case 0x36:
+ shift_pressed = 1;
+ return FALSE;
+ break;
+ case 0xaa:
+ if (extended)
+ return FALSE;
+ case 0xb6:
+ shift_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x3a:
+ caps_pressed = 1;
+ return FALSE;
+ break;
+ case 0xba:
+ caps_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x53:
+ if (ctrl_pressed && alt_pressed)
+ rtemsReboot(); /* ctrl+alt+del -> reboot */
+ break;
+
+ /*
+ * Ignore unrecognized keys--usually arrow and such
+ */
+ default:
+ if ((inChar & 0x80) || (inChar > 0x39))
+ /* High-bit on means key is being released, not pressed */
+ return FALSE;
+ break;
+ } /* switch */
+
+ /* Strip high bit, look up in our map */
+ inChar &= 0x7f;
+ if (ctrl_pressed)
+ {
+ *outChar = key_map[inChar];
+ *outChar &= 037;
+ }
+ else
+ {
+ *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
+ if (caps_pressed)
+ {
+ if (*outChar >= 'A' && *outChar <= 'Z')
+ *outChar += 'a' - 'A';
+ else if (*outChar >= 'a' && *outChar <= 'z')
+ *outChar -= 'a' - 'A';
+ }
+ }
+
+ return TRUE;
+} /* _IBMPC_scankey */
+
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_keyboard_isr
+| Description: Interrupt Service Routine for keyboard (0x01) IRQ.
+| Global Variables: kbd_buffer, kbd_first, kbd_last.
+| Arguments: vector - standard RTEMS argument - see documentation.
+| Returns: standard return value - see documentation.
++--------------------------------------------------------------------------*/
+rtems_isr
+_IBMPC_keyboard_isr(rtems_vector_number vector)
+{
+ if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
+ {
+ /* Got one; save it if there is enough room in buffer. */
+ unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE;
+
+ if (next != kbd_first)
+ kbd_last = next;
+ }
+
+ PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE); /* Mark interrupt as handled. */
+} /* _IBMPC_keyboard_isr */
+
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_chrdy
+| Description: Check keyboard ISR buffer and return character if not empty.
+| Global Variables: kbd_buffer, kbd_first, kbd_last.
+| Arguments: c - character read if keyboard buffer not empty, otherwise
+| unchanged.
+| Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
++--------------------------------------------------------------------------*/
+rtems_boolean
+_IBMPC_chrdy(char *c)
+{
+ /* Check buffer our ISR builds */
+ if (kbd_first != kbd_last)
+ {
+ *c = kbd_buffer[kbd_first];
+
+ kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
+ return TRUE;
+ }
+ else
+ return FALSE;
+} /* _IBMPC_chrdy */
+
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_inch
+| Description: Poll keyboard until a character is ready and return it.
+| Global Variables: None.
+| Arguments: None.
+| Returns: character read from keyboard.
++--------------------------------------------------------------------------*/
+char
+_IBMPC_inch(void)
+{
+ char c;
+ while (!_IBMPC_chrdy(&c))
+ continue;
+
+ return c;
+} /* _IBMPC_inch */
diff --git a/c/src/lib/libbsp/i386/pc386/console/outch.c b/c/src/lib/libbsp/i386/pc386/console/outch.c
new file mode 100644
index 0000000000..a7ee806ee4
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/outch.c
@@ -0,0 +1,284 @@
+/*-------------------------------------------------------------------------+
+| outch.c v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on:
+| outch.c,v 1.4 1995/12/19 20:07:27 joel Exp - go32 BSP
+| With the following copyright notice:
+| **************************************************************************
+| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. *
+| * On-Line Applications Research Corporation (OAR). *
+| * All rights assigned to U.S. Government, 1994. *
+| * *
+| * This material may be reproduced by or for the U.S. Government pursuant *
+| * to the copyright license under the clause at DFARS 252.227-7013. This *
+| * notice must appear in all copies of this file and its derivatives. *
+| **************************************************************************
++--------------------------------------------------------------------------*/
+
+
+#include <bsp.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+#define DISPLAY_CELL_COUNT (MAX_ROW * MAX_COL)
+ /* Number of display cells. */
+#define TABSIZE 4 /* Number of spaces for TAB (\t) char. */
+#define WHITE 0x0700 /* White on Black background colour. */
+#define BLANK (WHITE | ' ') /* Blank character. */
+
+
+/*-------------------------------------------------------------------------+
+| Global Variables
++--------------------------------------------------------------------------*/
+static rtems_unsigned16 *videoRam = TVRAM;
+ /* Physical address of start of video text memory. */
+static rtems_unsigned16 *videoRamPtr = TVRAM;
+ /* Pointer for current output position in display. */
+static rtems_unsigned8 videoRows = MAX_ROW; /* Number of rows in display. */
+static rtems_unsigned8 videoCols = MAX_COL; /* Number of columns in display. */
+static rtems_unsigned8 cursRow = 0; /* Current cursor row. */
+static rtems_unsigned8 cursCol = 0; /* Current cursor column. */
+
+
+/*-------------------------------------------------------------------------+
+| Function: setHardwareCursorPos
+| Description: Set hardware video cursor at given offset into video RAM.
+| Global Variables: None.
+| Arguments: videoCursor - Offset into video memory.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+setHardwareCursorPos(rtems_unsigned16 videoCursor)
+{
+ outport_byte(GDC_REG_PORT, 0xe);
+ outport_byte(GDC_VAL_PORT, (videoCursor >> 8) & 0xff);
+ outport_byte(GDC_REG_PORT, 0xf);
+ outport_byte(GDC_VAL_PORT, videoCursor & 0xff);
+} /* setHardwareCursorPos */
+
+
+/*-------------------------------------------------------------------------+
+| Function: updateVideoRamPtr
+| Description: Updates value of global variable "videoRamPtr" based on
+| current window's cursor position.
+| Global Variables: videoRamPtr, cursRow, cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+updateVideoRamPtr(void)
+{
+ videoRamPtr = videoRam + cursRow * videoCols + cursCol;
+} /* updateVideoRamPtr */
+
+
+/*-------------------------------------------------------------------------+
+| Function: scrollUp
+| Description: Scrolls display up n lines.
+| Global Variables: None.
+| Arguments: lines - number of lines to scroll.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void
+scrollUp(rtems_unsigned8 lines)
+{
+ rtems_unsigned16 blankCount;
+ /* Number of blank display cells on bottom of window. */
+ rtems_unsigned16 *ptrDst, *ptrSrc;
+ /* Source and destination pointers for memory copy operations. */
+
+ if (lines < videoRows) /* Move window's contents up. */
+ {
+ rtems_unsigned16 nonBlankCount;
+ /* Number of non-blank cells on upper part of display (total - blank). */
+
+ blankCount = lines * videoCols;
+ nonBlankCount = DISPLAY_CELL_COUNT - blankCount;
+ ptrSrc = videoRam + blankCount;
+ ptrDst = videoRam;
+
+ while(nonBlankCount--)
+ *ptrDst++ = *ptrSrc++;
+ }
+ else /* Clear the whole display. */
+ {
+ blankCount = DISPLAY_CELL_COUNT;
+ ptrDst = videoRam;
+ }
+
+ /* Fill bottom with blanks. */
+ while (blankCount-- > 0)
+ *ptrDst++ = BLANK;
+} /* scrollUp */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printCHAR
+| Description: Print printable character to display.
+| Global Variables: videoRamPtr, cursRow, cursCol.
+| Arguments: c - character to write to display.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void
+printCHAR(char c)
+{
+ *videoRamPtr++ = c | WHITE;
+ cursCol++;
+ if (cursCol == videoCols)
+ {
+ cursCol = 0;
+ cursRow++;
+ if (cursRow == videoRows)
+ {
+ cursRow--;
+ scrollUp(1);
+ videoRamPtr -= videoCols;
+ }
+ }
+} /* printCHAR */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printBS
+| Description: Print BS (BackSpace - '\b') character to display.
+| Global Variables: videoRamPtr, cursRow, cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printBS(void)
+{
+ /* Move cursor back one cell. */
+ if (cursCol > 0)
+ cursCol--;
+ else if (cursRow > 0)
+ {
+ cursRow--;
+ cursCol = videoCols - 1;
+ }
+ else
+ return;
+
+ /* Write a whitespace. */
+ *(--videoRamPtr) = BLANK;
+} /* printBS */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printHT
+| Description: Print HT (Horizontal Tab - '\t') character to display.
+| Global Variables: cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printHT(void)
+{
+ do
+ printCHAR(' ');
+ while (cursCol % TABSIZE);
+} /* printHT */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printLF
+| Description: Print LF (Line Feed - '\n') character to display.
+| Global Variables: cursRow.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printLF(void)
+{
+ cursRow++;
+ if (cursRow == videoRows)
+ {
+ cursRow--;
+ scrollUp(1);
+ }
+ updateVideoRamPtr();
+} /* printLF */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printCR
+| Description: Print CR (Carriage Return - '\r') to display.
+| Global Variables: cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printCR(void)
+{
+ cursCol = 0;
+ updateVideoRamPtr();
+} /* printCR */
+
+
+/*-------------------------------------------------------------------------+
+| Function: consPutc
+| Description: Print a character to display at current position.
+| Global Variables: videoRamPtr, videoRam.
+| Arguments: c - character to write to display.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void
+consPutc(char c)
+{
+ switch (c)
+ {
+ case '\b': printBS(); break;
+ case '\t': printHT(); break;
+ case '\n': printLF(); break;
+ case '\r': printCR(); break;
+ default: printCHAR(c); break;
+ } /* switch */
+
+ setHardwareCursorPos(videoRamPtr - videoRam);
+ /* At current offset into videoRam */
+} /* consPutc */
+
+
+/*-------------------------------------------------------------------------+
+| 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)
+{
+ consPutc(c);
+} /* _IBMPC_outch */
+
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_initVideo
+| Description: Video system initialization. Hook for any early setup.
+| Global Variables: videoRows.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+_IBMPC_initVideo(void)
+{
+ scrollUp(videoRows); /* Clear entire screen */
+ setHardwareCursorPos(0); /* Cursor at upper left corner */
+} /* _IBMPC_initVideo */