diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 1997-12-01 22:06:48 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 1997-12-01 22:06:48 +0000 |
commit | 7150f00f5be87fa8e37f7d00fbbef35645081138 (patch) | |
tree | 1cc7d3e1c4933404ddc1f742c7e37648cc783364 /c/src/lib/libbsp/i386/pc386/console | |
parent | Fixed test for RTEMS_HAS_POSIX_API so the executive POSIX API related (diff) | |
download | rtems-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.in | 53 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/console/console.c | 250 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/console/inch.c | 260 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/console/outch.c | 284 |
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 */ |