Console I/O

Technical Notes

Overview
Integration with the Windowing System
Assumptions and Limitations
The Cursor Coordinate System
Current and Default Attributes
Clipping and Clipping Regions
Display Modes
Hardware Independence
Using Attribute Tables
Enhanced Keyboard Support
Initializing the Console I/O System
Read-Only Console I/O Variables
Specifying the Cursor Advance Direction
Read/Write Console I/O Variables
Reading Characters, Strings, and Keyboard Status
Displaying Characters and Strings
Clearing and Filling Lines and Regions
Scrolling, Inserting, and Deleting Lines
Specifying Display Attributes
Writing and Moving On-Screen Text and Attributes
Reading and Writing Screen Text and Attributes via Disk
Selecting the Video Access Method
Moving and Setting the Cursor Position
Controlling Cursor Appearance
Managing the Clipping Region
Controlling the Video Border (Overscan) Color
Determining and Setting the Video Mode
Determining and Setting the Attribute Display Mode
Checking for Non-Graphics Video Modes
Enabling and Disabling Video Refresh
Multiple Adapter Support
Monitor Types
Determining the Active Monitor Type
Determining and Setting the Active Video Display Page
Determining and Setting Screen Dimensions
Supporting Nonstandard Screen Dimensions
Saving and Restoring the Video State
Saving and Restoring the Screen
Determining Active Console I/O Hardware
Colors and Color Attributes
Monochrome Attributes
Black and White Attributes
Gray Scale Attributes
Conditionally Assembling the Console I/O System
Console I/O Considerations in TSRs
Virtual Screen Considerations
Sample Program
Console I/O vs. Scripted I/O

Overview

The console I/O unit provides a complete system of functions for keyboard input and screen output. These functions include the following: echoed and unechoed character input; echoed string input; character, attribute, and string output with and without interpretation of special characters (CR, LF, BS, and BEL); centered and justified string output; moving, reading, writing, clearing, scrolling, and filling of regions; and clearing, filling, inserting, and deleting lines within regions. This unit also provides functions which: select the output method (BIOS or direct video access); select attributes and colors used to display characters; specify the cursor position, cursor state (on/off), cursor shape, and cursor advance direction; specify a clipping region; control the video border color; set and get the video mode; set and get the attribute display mode; save and restore the video state and screen contents; and determine the active display adapter.

The Spontaneous Assembly 3.0 console I/O system includes all-new support for dual-adapter systems, extended screen dimensions, multiple video pages, disk-based screen saving and restoring, and TSRs. New functions are included to identify display adapters, return information about an adapter, change active adapters, determine monitor types, determine the number of supported video pages for an adapter, get and set the current video page, determine supported screen dimensions, set EGA/MCGA/VGA adapters to 12/ 14/ 21/ 25/ 28/ 43/ 50-line modes (if supported by the adapter and monitor), read and write screen text and attributes using a disk buffer, save and restore screen contents using a disk buffer, and enable and disable video refresh. In addition, screen saving and restoring has been enhanced to save and restore all newly-supported console I/O options.

The Spontaneous Assembly 3.0 console I/O system is also fully compatible with the new virtual screen system, allowing console I/O functions to be used to manipulate any virtual screen at any time.

Integration with the Windowing System

All console I/O system functions are Spontaneous Assembly windowing system aware. When windowing is being performed (i.e., _win_init has been called), all console I/O output is sent to the active window and all output is clipped to the window as it would be clipped to the screen if windowing were not being performed. As explained in the Windowing technical notes, any window may be designated as the active window, even if it is closed, obscured, or off the screen. The console I/O functions handle all of these conditions automatically.

Even though the console I/O functions work in harmony with the windowing functions, no windowing functions are linked in by the console I/O system unless _win_init is called.

Assumptions and Limitations

Most of the console I/O functions require _console_init to be called before they may be used. This restriction is imposed (and documented) whenever a function depends on or modifies any of the global variables which are initialized by _console_init. These global variables include all of the public console I/O variables described in the technical notes.

The console I/O system supports MDA, CGA, EGA, MCGA, and VGA compatible adapters in text display modes only. All output takes place on the active display page. If the active adapter, video mode, display page, or other similar display characteristics are changed, _console_init must be called to re-initialize the console I/O system.

The Cursor Coordinate System

Cursor positions are relative to the upper left-hand corner of the screen (unless a clipping region has been enabled as discussed below). The coordinate position of the upper left-hand corner of the screen is (0,0); vertical coordinates increase in the downward direction and horizontal coordinates increase to the right. Note that the coordinate position of the lower right-hand corner of the screen is ((screen width-1), (screen height-1)).

Cursor positions are always treated as unsigned char values. Horizontal positions which exceed 255 wrap to the left-most column in the current row; vertical positions which exceed 255 wrap to the top-most row in the current column.

Current and Default Attributes

All of the _cput_... and echoed _cget_... functions display text in the current attribute. This attribute is specified using the _set_attr function; it may be adjusted using _bold_on, _bold_off, _blink_on, _blink_off, _set_fgcolor, etc. To display text using different attributes, it is necessary to change the current attribute each time a new attribute is required.

The default attribute is used for clearing and inserting new lines of text when scrolling, inserting, and deleting is performed. This attribute may be specified using the _set_dattr function. The _reset_attr function sets the current attribute to the default attribute.

Clipping and Clipping Regions

Output from console I/O functions is clipped to the boundaries of the screen as well as the boundaries of the current clipping region. Clipping regions may be specified using the _set_region function. Anything which is displayed outside of these boundaries is lost.

Clipping regions are similar to the "text windows" supported by Turbo C and Quick C. When a clipping region is enabled, the cursor is relocated to the upper left-hand corner of the region, all output is restricted to the clipping region, and all cursor positioning is relative to the upper left-hand corner of the region. If the cursor is positioned outside of the clipping region, it becomes invisible. When the clipping region is disabled, the cursor returns to the position it occupied before the clipping region was enabled, and cursor positions are again relative to the upper left-hand corner of the screen. Console I/O functions which scroll, clear, insert, or delete lines are all aware of the clipping region and restrict their actions to the region if it is active; otherwise, their scope is limited to the entire screen.

Display Modes

The concept of display modes is unique to the console I/O system. The display mode identifies the exact method used by the active display adapter and monitor to interpret text attributes. For this reason, the current display mode may be used to select an attribute table which is best suited for the active display hardware (see Using Attribute Tables, below). The following symbolic constants (defined in CONSOLE.H) identify the various display modes:
MONO2
(0x00) Monochrome, 2 background attributes, blink
MONO4
(0x01) Monochrome, 4 background attributes, no blink
BW2
(0x02) Black and white, 2 background attributes, blink
BW4
(0x03) Black and white, 4 background attributes, no blink
COLOR8
(0x04) Color, 8 background colors, blink
COLOR16
(0x05) Color, 16 background colors, no blink
GRAY8
(0x06) Gray scale, 8 background shades, blink
GRAY16
(0x07) Gray scale, 16 background shades, no blink
Note that the black and white, monochrome, and gray scale display modes are all distinct. Monochrome refers to displays which support normal, bold, underline, bold underline, blink, and reverse video attributes. Black and white refers to displays which support only normal, bold, blink, and reverse video attributes. Gray scale refers to displays which support all of the color attributes but display them as various shades of gray.

The active display mode may be determined by calling _get_dmode.

Hardware Independence

The functions in the console I/O unit are hardware independent except where noted. This allows applications which use console I/O functions to run unmodified on any supported system. For example, _set_cursor and _get_cursor read and write the shape of the display cursor in a normalized format. This allows complete control over cursor shape but eliminates the need to set the shape using starting and ending scan lines.

Functions which accept attributes and colors are not inherently hardware independent since different display adapters and monitors interpret attributes differently. Instead, they may be made hardware independent through the use of attribute tables (see Using Attribute Tables, below).

Using Attribute Tables

Attribute tables are indexed lists of attributes and colors used by the console I/O functions when text is displayed. Attribute tables are interchangeable, making it possible to write hardware independent applications (i.e., applications in which screen output always appears correct, regardless of the active adapter and monitor). Attribute tables also make it easy to write applications which support customizable display colors.

The use of attribute tables is optional. When no attribute table is installed, all console I/O functions expect input attributes and colors to be actual attribute or color values. When an attribute table is installed, input attributes and colors are expected to be table indices, and the corresponding table attributes are used as the display attributes.

Each application usually defines a number of different attribute tables for different purposes and then installs specific tables according to the circumstances. For example, hardware independent output may be achieved by defining one attribute table for each display mode (i.e., monochrome, color, black-and-white, etc.) and then selecting the appropriate table at run time (see Sample Program below). The _get_dmode function returns a code which may be used to select an attribute table based on the display mode (see Display Mode, above).

Attribute tables always contain char values. The starting index for an attribute table is always zero.

Enhanced Keyboard Support

All of the console I/O keyboard input functions work with both standard and enhanced keyboards. Support for special enhanced keyboard key codes is optional. If _kbd_init is called and an enhanced keyboard is present, then all of the input functions support these codes; otherwise, these functions only support standard keyboard codes.

Initializing the Console I/O System

_console_init
Initializes the console I/O system.
_kbd_init
Initializes the console I/O system for enhanced keyboard support if an enhanced keyboard is present.
These functions initialize the console I/O system. The _console_init function initializes the console I/O system by determining the current display state and setting a number of global variables toreflect that state. This function must be called before many of the console I/O functions may be used. Calling _console_init has no effect on the current video state or screen contents.

The _kbd_init function initializes the console I/O system to support enhanced keyboard key codes if an enhanced keyboard is present. This function is optional; if it is not called, the console I/O keyboard functions support only standard key codes. It may be called whether or not an enhanced keyboard is actually present in the system.

Read-Only Console I/O Variables

adapter_type
(Variable) Indicates the active display adapter type.
screen_cols
(Variable) Indicates the number of columns on the screen.
screen_dimens
(Variable) Indicates the number of rows and columns on the screen.
screen_rows
(Variable) Indicates the number of rows on the screen.
video_mode
(Variable) Indicates the current video mode.
These read-only variables indicate the active adapter type, keyboard type, screen dimensions, and video mode. They are initialized when _console_init is called and may be referenced or modified without warning by any console I/O function which depends on or calls _console_init. These variables must not be modified directly.

Specifying the Cursor Advance Direction

_direc_left
Sets the cursor advance direction to be ADV_LEFT (left).
_direc_down
Sets the cursor advance direction to ADV_DOWN (down).
_direc_right
Sets the cursor advance direction to ADV_RIGHT (right).
_direc_up
Sets the cursor advance direction to ADV_UP (up).
_get_direction
Returns the current cursor advance direction.
_set_direction
Sets the cursor advance direction.
These functions allow the cursor advance direction to be specified or determined. The cursor advance direction is the direction in which the cursor is moved after the _cput_... and echoed _cget_... functions display each character. These functions make it possible to draw boxes, diagonal lines, and other complex shapes on the screen with a minimal amount of effort.

Note that _set_direction allows arbitrary directions to be specified as a signed number of rows and columns. Since any number of rows and/or columns can be specified, any direction is possible, including diagonal directions and directions which move to non-adjoining character cells (for example, every other cell on the same line).

Read/Write Console I/O Variables

direct_video
(Variable) Indicates the current console I/O output method.
kbd_type
(Variable) Indicates the type of keyboard detected by _kbd_init.
video_snow
(Variable) Indicates whether or not direct video output should compensate for "snow".
These read/write variables determine screen and keyboard access methods. direct_video indicates whether BIOS or direct screen access is performed by the screen output functions. kbd_type determines whether standard or enhanced keyboard BIOS calls are issued when accessing the keyboard. video_snow determines whether or not the screen output functions compensate for video "snow" when directly accessing video memory.

These variables may be modified directly. They may also be manipulated by calling _set_directvideo, _get_directvideo, and _kbd_init.

Reading Characters, Strings, and Keyboard Status

_cget_chr
Gets a character from the keyboard.
_cget_chre
Gets a character from the keyboard and echoes it to the display.
_cget_chra
Gets a character and type (normal, ALT-keypad, or extended) from the keyboard.
_cget_chrae
Gets a character and type (normal, ALT-keypad, or extended) from the keyboard and echoes the character to the display.
_cget_s
Gets a string from the keyboard and returns number of characters entered.
_cget_str
Gets a string from the keyboard.
_ccheck_key
Determines if a keystroke is waiting to be read.
_cflush_keys
Flushes pending keystrokes from the keyboard buffer.
_get_keyflags
Returns the current keyboard shift status flags.
These functions read characters and strings from the keyboard, check for pending keystrokes, flush pending keystrokes from the system keyboard buffer, and return the current keyboard shift status flags. All of these functions are enhanced keyboard aware. However, special enhanced keyboard key codes are only returned if _kbd_init has been called and an enhanced keyboard is present in the system. This allows applications to ignore nonstandard keystrokes where appropriate.

The _cget_chra and _cget_chrae keyboard input functions return conditions (-1/0/1) along with a corresponding parameter which indicates the type of keystroke which was processed. If 0 is returned, the keystroke code represents a normal ASCII character (i.e., A-Z, space, Ctrl-C, etc.); -1 indicates that the keystroke code represents an "extended" ASCII keystroke (i.e., F1, Alt-Enter, Ctrl-@, etc.); if 1 is returned, the code represents an IBM-ASCII character from 1 to 255 (entered by holding the Alt key down while typing the character code on the numeric keypad).

The _cget_chr and _cget_chre keyboard input functions return values similar to C's getch, where an extended character value will first return 0 and the character code can be retrieved by a subsequent call to the same function, this is not as efficient code as the _cget_chra... functions, but are provided for similarity to the C getch interface.

Complete tables of the keystrokes and codes supported by these functions are provided in Appendices B, C, and D.

Most of these functions may be called without calling _console_init. _cget_str, _cget_s, _cget_chre and _cget_chrae are exceptions since they echo selected keystrokes to the screen. When keystrokes are echoed, the cursor is moved in the current cursor advance direction.

Keyboard I/O is always performed using BIOS calls. This provides the highest degree of compatibility with resident utilities. In addition, these functions issue an INT 0x28 and yield to the multitasking system (if present) while waiting for a keystroke. This scheme allows background processes (e.g., PRINT.COM or other TSRs) and tasks in the multitasking system to execute while the calling program is idle. If the multitasking system is not initialized, the yield to the multitasking system has no effect. If _tsr_enable, _tsr_resident, or _device_resident has been called, INT 0x28 is only issued when it is safe to do so.

Displaying Characters and Strings

_cput_attr
Puts an attribute to the display.
_cput_nattr
Puts an attribute to the display a specified number of times.
_cput_chr
Puts a character to the display.
_cput_chri
Puts a character to the display without interpreting it.
_cput_nchr
Puts a character to the display a specified number of times.
_cput_nchri
Puts a character to the display a specified number of times without interpreting it.
_cput_str
Puts a string to the display.
_cput_stri
Puts a string to the display without interpreting it.
_cput_strci
Puts a centered string to the display without interpreting it.
_cput_strji
Puts a justified string to the display without interpreting it.
_cput_beep
Sounds a tone on the system speaker.
_cput_linefeed
Performs the equivalent of a linefeed in the current clipping region.
_cput_newline
Performs the equivalent of a carriage return and linefeed in the current clipping region.
_cput_return
Performs the equivalent of a carriage return in the current clipping region.
These functions display attributes, characters, and strings. Functions are provided for: single and repeated character and attribute output; character and string output with and without interpretation of special characters (CR, LF, BS, and BEL); justified and centered string output; and interpreted output of the special characters CR, LF, and CR/LF (newline).

These functions advance the cursor in the current cursor advance direction after each character is displayed. If the cursor moves outside the boundaries of the screen or clipping region (or active window if windowing is in effect), it becomes invisible and any text which is displayed at that position is lost.

Note that _cput_strci and _cput_strji are affected by the cursor advance direction as well. See the Reference Section for details on how this works.

Clearing and Filling Lines and Regions

_afill_eol
Sets all attributes from the cursor to the end of the current line to a specified attribute.
_afill_line
Sets all attributes on the current line to a specified attribute.
_afill_n
Sets a specified number of attributes on the current line to a specified attribute.
_afill_region
Sets all attributes in the current clipping region to a specified attribute.
_clr_eol
Clears to the end of the current line.
_clr_line
Clears the current line.
_clr_n
Clears a specified number of columns on the current line.
_clr_region
Clears the current clipping region.
_fill_eol
Sets all characters and attributes from the cursor to the end of the current line to a specified character and attribute.
_fill_line
Sets all characters and attributes on the current line to a specified character and attribute.
_fill_n
Sets a specified number of characters and attributes on the current line to a specified character and attribute.
_fill_region
Sets all characters and attributes in the current clipping region to a specified character and attribute.
These functions fill regions, lines and portions of lines with attributes or character/attribute pairs. The _clr_... functions always fill a specified area with space characters in the default text attribute. The _afill_... functions fill a specified area with an attribute without disturbing the corresponding characters in those positions. The _fill_... functions fill a specified area with a character/attribute pair. All output is restricted to the current clipping region and screen (or active window if windowing is in effect).

These functions do not move the cursor, so they are not affected by the current cursor advance direction. Line-oriented operations take place on the current screen row in a left-to-right direction. Functions which are performed to the "end of the line" begin at the current cursor position and continue along the current screen row to the right-most column of the clipping region or screen (or active window if windowing is in effect).

The _afill_... and _fill_... functions are attribute table aware and accept attribute table codes instead of attribute values if a table has been installed.

Scrolling, Inserting, and Deleting Lines

_scroll_down
Scrolls the current clipping region down a specified number of lines.
_scroll_up
Scrolls up a specified number of lines.
_ins_line
Inserts a blank line in the current clipping region.
_del_line
Removes a line from the current clipping region.
These functions scroll, insert, and delete lines of text within the current clipping region. If no clipping region is active, then the operation takes place on the entire screen (or active window if windowing is in effect).

When the region is scrolled up (or down), the top-most (or bottom-most) lines are scrolled out of the region and disappear. Blank lines in the default text attribute are then scrolled in at the bottom (or top) of the region. When a line is inserted, the current line and all lines below it are scrolled down and a blank line in the default attribute is inserted at the current cursor position. When a line is deleted, all lines below the current line are scrolled up one row, overwriting the current row, and a blank line in the default attribute is scrolled in at the bottom of the region.

Specifying Display Attributes

attr_tbl
(Variable) Contains the address of the currently-installed attribute table.
_get_attr
Returns the current text attribute code or value.
_set_attr
Sets the current text attribute.
_get_dattr
Returns the default text attribute code or value.
_set_dattr
Sets the default text attribute.
_set_fgcolor
Sets the foreground color for the current text attribute.
_set_bkcolor
Sets the background color for the current text attribute.
_set_attrtbl
Sets the attribute table address.
_reset_attr
Resets the current text attribute and attribute flags.
_get_tblattr
Returns an attribute from the current attribute table.
_bold_on
Turns bold on.
_bold_off
Turns bold off.
_blink_on
Turns blink on.
_blink_off
Turns blink off.
_bkbold_on
Turns high intensity background on.
_bkbold_off
Turns high intensity background off.
_get_attrflags
Returns the current text attribute flags.
_set_attrflags
Sets the current text attribute flags.
These functions allow the current and default text display attributes to be determined and manipulated.

_set_attr and _set_dattr specify the current and default text attributes. The current attribute is the attribute used by the _cput_... and echoed _cget_... functions to display text. The default attribute is the attribute used by the console I/O system when clearing or inserting new lines but not when displaying text. _reset_attr sets the current attribute to the default attribute.

A number of these functions control the attribute flags which temporarily modify the current attribute. These flags, if set, force their respective attribute bits to be set in the current attribute when it is used to display text. _bold_on and _bold_off control the BOLD attribute bit, _blink_on and _blink_off control the BLINK attribute bit, and _bkbold_on and _bkbold_off control the BKBOLD (high intensity background) attribute bit. In addition, _get_attrflags and _set_attrflags may be used to read and write all of these attribute bits at once. _reset_attr clears all of the attribute bits when it resets the current attribute to the default attribute.

_set_attrtbl is provided for installing or removing attribute tables. attr_tbl is a pointer to the attribute table currently in use and is modified by _set_attrtbl. _set_attr, _set_dattr, _set_fgcolor, and _set_bkcolor are attribute table aware and accept attribute table codes instead of attribute/color values if a table has been installed. _get_attr and _get_dattr return attribute table codes instead of attribute values if a table is installed. _get_tblattr may be used to convert attribute table codes to table values; this function has no effect if no attribute table is installed.

Writing and Moving On-Screen Text and Attributes

_move_textattr
Moves text and attributes from one display region to another display region
_read_textattr
copies text and attributes from a specified display region to a specified buffer.
_write_textattr
Copies text and attributes from a specified buffer to a specified display region.
These functions read, write and move specified regions of the current screen. The region of interest is specified using screen-relative coordinates (window-relative if windowing is in effect). If a clipping region is currently defined, it is ignored. These functions are the only console I/O functions which do not restrict their actions to the current clipping region.

_read_textattr and _write_textattr read and write a specified portion of the screen to and from a buffer in memory. _move_textattr copies a specified portion of the screen from one screen position to another.

All of these functions manipulate characters and attributes as character/attribute pairs, with the character in the low byte and the attribute in the high byte.

Reading and Writing Screen Text and Attributes via Disk

_hread_textattr
Copies text and attributes from a specified display region to a disk buffer.
_hwrite_textattr
Copies text and attributes to a specified display region from a disk buffer.
These functions read and write specified regions of the current screen. The region of interest is specified using screen-relative coordinates (window-relative if windowing is in effect). If a clipping region is defined, it is ignored. If the virtual screen system is active, then text and attributes are read or written on the active screen. These functions are functionally equivalent to _read_textattr and _write_textattr, but they allow screen text and attributes to be saved and restored at arbitrary offsets within disk files. _console_init must be called before these functions may be used.

Selecting the Video Access Method

_set_directvideo
Selects direct video output for the console I/O system.
_set_biosvideo
Selects BIOS output for the console I/O system.
These functions allow the video access method to be specified at run time. Two kinds of access methods are supported: direct and BIOS. BIOS access is relatively slow, but it provides a high degree of compatibility with nonstandard systems; direct video memory access is very fast, but it is hardware dependent.

Normally, _console_init initializes the console I/O system for direct video access. However, under rare circumstances, the active operating environment may not support direct screen access. If _console_init detects this condition, it sets the direct_video variable to a state which indicates that BIOS video access is being performed and direct video access is not allowed. In this case, calling _set_directvideo will result in an error return.

The video access method may also be set by directly manipulating the direct_video variable.

Moving and Setting the Cursor Position

_goto_x
Moves the cursor to a specified column.
_goto_y
Moves the cursor to a specified row.
_goto_xy
Moves the cursor to a specified column and row.
_goto_home
Moves the cursor to the upper left-hand corner of the current clipping region.
_goto_end
Moves the cursor to the lower right-hand corner of the current clipping region.
_goto_right
Moves the cursor to the right-most column of the current clipping region.
_goto_left
Moves the cursor to the left-most column of the current clipping region.
_goto_top
Moves the cursor to the top row of the current clipping region.
_goto_bottom
Moves the cursor to the bottom row of the current clipping region.
_move_right
Moves the cursor right one column.
_move_left
Moves the cursor left one column.
_move_up
Moves the cursor up one row.
_move_down
Moves the cursor down one row.
_move_next
Moves the cursor once in the current cursor advance direction.
_move_back
Moves the cursor once in the direction opposite the current cursor advance direction.
_rel_xy
Moves the cursor a specified distance relative to its current position.
_where_x
Returns the current (column) coordinate.
_where_y
Returns the current (row) coordinate.
_where_xy
Returns the current cursor coordinates.
These functions set and get the current cursor position. This is the position where characters and strings are always displayed by the _cput_... and echoed _cget_... functions. The display (hardware) cursor always appears at the current cursor position unless the cursor has been moved out of bounds or turned off.

The _goto_... functions move the cursor to new absolute positions. _goto_x, _goto_left, and _goto_right change the cursor column position without changing the row. _goto_y, _goto_top, and _goto_bottom change the cursor row position without changing the column. _goto_xy, _goto_home, and _goto_end change both the row and column positions at the same time.

The _move_... and _rel_... functions perform cursor motion relative to the current cursor position. _move_up, _move_down, _move_left, and _move_right move the cursor one row or column in the specified direction. _move_next and _move_back move the cursor in the current cursor advance direction or in the opposite direction. _rel_xy moves the cursor any number of rows and columns from the current position. This relative motion is specified as a signed number of rows and columns to move, with positive values representing right and downward motion and negative values representing left and upward motion.

The _where_... functions return the current cursor row and column position. It is usually used to save a cursor position for later restoration using the _goto_... functions.

Controlling Cursor Appearance

_cursor_on
Turns the hardware cursor on.
_cursor_off
Turns the hardware cursor off.
_get_cursor
Gets the shape and state of the display cursor.
_set_cursor
Sets the shape of the display cursor.
These functions allow the shape and state of the display cursor to be determined and modified. None of these functions affect the cursor position.

_set_cursor allows the cursor shape (starting and ending scan lines) to be specified in a hardware independent manner. _get_cursor returns the current cursor shape in the same format and indicates whether the cursor is on or off.

_cursor_on and _cursor_off make the hardware cursor visible and invisible. They work reliably on all display adapters, including EGAs.

Managing the Clipping Region

_region_on
Enables the current clipping region.
_region_off
Disables the current clipping region.
_get_region
Returns the current clipping region position and dimensions.
_set_region
Sets new clipping region coordinates.
These functions allow the clipping region to be set, read, enabled, and disabled. When the clipping region is enabled, all console I/O output is restricted to this region and all cursor motion is relative to the upper left-hand corner of the region. Character output which takes place outside of this region is lost. If the cursor is moved beyond the boundaries of the clipping region, it becomes invisible. If no clipping region has been defined or the clipping region is disabled, then output is clipped to the screen (or the active window if windowing is in effect).

_region_on turns the currently-defined clipping region on, moving the cursor to the home position in the process. _region_off disables the current clipping region, returning the cursor to the positionwhich it occupied before _region_on was called. _set_region specifies a new clipping region; this new region only takes effect immediately if _region_on has already been called. _get_region returns the clipping region position and dimensions and indicates whether or not the region is currently enabled.

Controlling the Video Border (Overscan) Color

_get_vborder
Gets the current video border color and state.
_set_vborder
Sets the video border color.
_set_vbordattr
Sets the video border color to match the background color of a given text attribute.
_vborder_on
Turns the video border on.
_vborder_off
Turns the video border off.
These functions control the color of the video border (or overscan) region. They also allow the video border to be enabled or disabled (_vborder_on and _vborder_off) independently of the border color. All of these functions accept and return attribute table codes if an attribute table has been specified.

The color values which are used to specify video border colors are usually not the same as the text attribute values supported by the same monitor. This can make it difficult to set border colors to match background attributes, especially since border color values vary from one display adapter and monitor to another. _set_vbordattr solves this problem by setting the video border color to the hardware-specific value which best matches the background color of a specified text attribute. _set_vborder takes the other approach, allowing the video border color to be specified in a hardware dependent manner. _get_vborder returns the value which was used to set the border color.

Determining and Setting the Video Mode

_get_vmode
Returns the current video mode.
_set_vmode
Sets the video mode.
_set_80cols
Ensures that the display is in an 80+ column text video mode.
These functions determine and set the current video mode. The video mode indicates the active adapter and monitor and indicates, in general, how text attributes are to be interpreted when they are displayed.

_get_vmode returns the current video mode. _set_vmode forces the current video mode to the specified mode, clears the screen, and calls _console_init to re-initialize the console I/O system. _set_80cols ensures that the display is in an 80-column (or better) text mode; if it is not currently in an 80+ column mode, then it selects the 80-column mode which is most like the current display mode and calls _console_init.

Determining and Setting the Attribute Display Mode

_get_dmode
Returns the active display mode.
_set_blinkmode
Reprograms the active video display adapter to support blinking characters.
_set_bkboldmode
Reprograms the active display adapter to support high intensity background attributes.
These functions identify and adjust the current display mode. The display mode indicates exactly how attributes are interpreted by the active display adapter and monitor (see Display Mode, above, for a detailed explanation of display modes).

_get_dmode determines the current display mode. It is most often used to select an attribute table which makes the application look as attractive as possible on the active display adapter and monitor.

_set_blinkmode and _set_bkboldmode are complimentary functions which can be used to adjust the active display mode. _set_blinkmode reprograms the active display adapter to interpret the BLINK/BKBOLD attribute bit (bit 7) as a blinking text bit. This reduces the number of availablebackground attributes. _set_bkboldmode reprograms the active display adapter to interpret the BLINK/BKBOLD attribute bit as a high intensity background bit. This precludes the use of blinking text, but it doubles the number of background attributes. These functions work on all display adapters supported by the console I/O system.

Note that if _set_blinkmode (or _set_bkboldmode) is called, the display mode returned by _get_dmode will reflect the change. Most applications call one function or the other at program startup time and leave the system in that state until the program terminates. This limits the number of attribute tables which need to be defined for the application.

Checking for Non-Graphics Video Modes

_is_textmode
Determines if the current video mode is a text (non-graphics) mode.
This function determines if the current system video display mode is a alphanumeric text mode. _is_textmode successfully differentiates text and graphics modes on most display adapters, including nonstandard text and graphics modes. This function DOES NOT depend on _console_init and is intended primarily for use within TSRs to determine if the console I/O system is safe to use (see Console I/O Considerations in TSRs in this chapter). This function may also be used to detect nonstandard video text modes (see Supporting Nonstandard Screen Dimensions in this chapter).

Enabling and Disabling Video Refresh

_video_off
Disables video refresh on the current display adapter.
_video_on
Enables video refresh on the current display adapter.
These functions may be used to temporarily disable and enable video refresh on the current display adapter. The screen is blanked when video refresh is disabled, and it remains blanked until refresh is re-enabled. Multiple screen state changes can be performed with minimal screen flickering while video refresh is disabled, including changes to the video mode, video page, video border, and/or screen dimensions as well as copying, moving, restoring, blanking, or rewriting the screen. These functions affect only the active screen if the virtual screen system is in use; the video refresh state (on or off) is remembered separately for each virtual screen in the system. _console_init must be called before using these functions.

Multiple Adapter Support

_adapter_init
Initializes the console I/O system for multiple adapter support.
_get_adapters
Returns the active display adapter type(s) and monitor type(s).
_get_adaptinfo
Returns information about a specified display adapter.
_set_adapter
Selects the active display adapter.
These functions provide low-level support for one or two display adapters within the console I/O unit. More advanced support for text mode screen and display adapter switching is provided in the virtual screen unit (see the Virtual Screen technical notes for details).

_adapter_init initializes the console I/O system to support multiple adapters. This function determines which adapters are present in the system and saves all essential information about those adapters for later use by the console I/O and virtual screen systems. _adapter_init must be called before _get_adaptinfo or _set_adapter may be used and before virtual screens may be created on the secondary adapter.

_get_adapters and _get_adaptinfo return essential information about the adapters and monitors which are installed in the system. These functions are often used to determine available display resources at program startup. The source code example at the end of the Virtual Screen technical notes demonstrates the use of _get_adaptinfo for this purpose.

_get_adapters returns the adapter type and attached monitor type for the primary display adapter and (if present) the secondary display adapter. This low-level function does not depend on _adapter_init. See Monitor Types, below, for a list of the possible monitor types and display adapter types which may be returned by this function. Also, see the source code example at the end of the Virtual Screen technical notes for sample code which uses this function.

_get_adaptinfo returns information about the state and capabilities of a specified adapter. Returned information includes the current video mode, active page, current screen dimensions, all supported screen dimensions, and the number of supported video display pages. This information is also available via the _chk_dimens, _get_vpagecnt, and _get_dimens functions, but these functions apply to the active adapter only, and _get_dimens returns the dimensions of the active, logical screen instead of the physical adapter. _get_adaptinfo returns this information, all at once, whether or not the specified adapter is the active adapter.

_set_adapter manually switches active display adapters. This function accepts absolute adapter types (i.e., MDA, CGA, EGA, MCGA, or VGA) as well as a generic "secondary adapter" indicator on input. If the requested adapter is present, this function selects the new adapter as the active adapter, sets the video page to page zero, and calls _console_init to re-initialize the console I/O system on that adapter and page. Where possible, adapter switching is performed without using BIOS calls to eliminate unnecessary screen blanking, reprogramming of color palettes, cursor emulation, etc. An error is returned if the requested adapter is not present. If _set_adapter is called when the virtual screen system is in use, then the active screen is re-initialized to reside on page zero of the new adapter, text and attributes are not transferred to the new adapter, and the new screen will not be visible on the new adapter until it is opened by calling _vscreen_open.

Due to BIOS limitations, the video mode of the second display adapter cannot always be determined by _adapter_init. In this case a "best guess" is made as to the text mode state of the second adapter. This guess is enforced via a BIOS video mode change the first time the secondary adapter is physically selected by _set_adapter or by the virtual screen system. Thereafter, text mode adapter switching is performed directly, without issuing BIOS calls. The virtual screen system allows this extra mode change to be circumvented since it allows the video mode and screen dimensions of a virtual screen to be specified when that screen is created. For this reason, _set_adapter is rarely used to switch adapters manually when the virtual screen system is in use.

WARNING! Adapter switching of any kind is not recommended within TSRs because the state of the second adapter cannot be reliably determined by _adapter_init (see preceding explanation).

Monitor Types

As used in this documentation, monitor type denotes the type of physical display attached to the active display adapter. The following symbolic constants identify the possible monitor types. These equates are defined in CONSOLE.H:
MONO
(0x00) Digital monochrome display
RGB
(0x01) RGB color display (200 scan lines)
ECD_LO
(0x02) Enhanced color display (200 scan lines)
ECD_HI
(0x03) Enhanced color display (350 scan lines)
ACOLOR
(0x04) Analog color display (variable scan lines)
AMONO
(0x05) Analog monochrome display
The following table indicates the possible adapter/monitor combinations. These are the only combinations which may be returned by the _get_adapters function:
          MDA             CGA             EGA            MCGA            VGA

MONO      Yes              -              Yes             -               -
RGB        -              Yes             Yes             -               -
ECD_LO     -               -              Yes             -               -
ECD_HI     -               -              Yes             -               -
ACOLOR     -               -               -             Yes             Yes
AMONO      -               -               -             Yes             Yes
The monitor type and the display mode are related but independent values. Specifically, the active display mode is determined from the active monitor type, video mode, and blink/bkbold mode. See the documentation for the _get_dmode function for more information about display modes.

Determining the Active Monitor Type

monitor_type
(Variable) Indicates the type of monitor attached to the active display adapter.
The monitor_type variable indicates the type of physical display attached to the active display adapter. The value maintained in this variable is the same as the value returned by _get_adapters. If the virtual screen system is in use, this variable indicates the type of monitor attached to the display adapter of the active screen. This variable is initialized by _console_init and _get_adapters.

Determining and Setting the Active Video Display Page

_get_vpage
Returns the active video display page.
_set_vpage
Sets the active video display page.
_get_vpagecnt
Returns the number of available video display pages on the active display adapter.
These functions provide fundamental text mode support for video display page switching using the console I/O system. More advanced video display page support is provided in the virtual screen unit (see the Virtual Screen technical notes).

_get_vpage returns the page number of the active display page as an origin 0 number. _set_vpage changes active video pages on the active display adapter to a specified page and calls _console_init to re-initialize the console I/O system. These functions return or set the information associated with the active screen if the virtual screen system is active. _console_init must be called before these functions may be used.

_get_vpagecnt returns the number of available video display pages in the current text video display mode on the active adapter. A "best guess" page count is returned if the number of available video pages cannot be determined due to BIOS limitations. _console_init must be called before this function may be used.

_get_vpagecnt returns information for the active adapter only. _get_adaptinfo returns the same information, and more, for either adapter. For this reason, _get_adaptinfo is normally used instead of _get_vpagecnt to determine available display resources at program startup.

The _set_vpage function is rarely used to switch between screens on different video display pages when the virtual screen system is in use. Instead, the virtual screen unit is usually relied on to switch video pages transparently whenever a new screen is opened. If _set_vpage is used on a buffered virtual screen, the contents of that screen are physically reassigned to the new video page. If it is used on an unbuffered screen, the screen is blanked in the default text attribute when it is reassigned to the new video page. See Virtual Screen Considerations in this section as well as the Virtual Screen technical notes for related information.

Determining and Setting Screen Dimensions

_get_dimens
Returns the current screen dimensions of the active display adapter.
_set_dimens
Sets the screen dimensions of the active display adapter.
_chk_dimens
Determines if specified screen dimensions are supported by the active display adapter.
These functions provide support for extended text mode screen dimensions on EGA, MCGA, and VGA display adapters.

_get_dimens returns the current screen dimensions of the active display adapter in rows and columns. _chk_dimens determines if a requested screen dimension is supported on the active display adapter. _set_dimens reprograms the active display adapter to specified dimensions, blanks the screen, selects page zero as the new video display page, and calls _console_init to re-initialize the console I/O system for the new screen dimensions and video page. _console_init must be called before these functions may be used.

The adapter type and monitor type of the active display adapter determine which screen dimensions are supported by _set_dimens, as follows:


         MDA/EGA  CGA/EGA      EGA          EGA        MCGA            VGA
          MONO      RGB       ECD_LO       ECD_HI      Any             Any

40x12      -         -          Yes          -          -              Yes

80x12 - - Yes - - Yes

40x14 - - Yes - - Yes

80x14 - - Yes - - Yes

40x21 - - - Yes - -

80x21 - - - Yes - -

40x25 Yes Yes Yes Yes Yes Yes

80x25 Yes Yes Yes Yes Yes Yes

40x28 - - - - - Yes

80x28 - - - - - Yes

40x43 - - - Yes - -

80x43 - - - Yes - -

40x50 - - - - Yes Yes

80x50 - - - - Yes Yes

Only the active screen is affected by _set_dimens if the virtual screen system is active; all other virtual screens on the same display adapter are unaffected.

WARNING! Use of _set_dimens is not recommended in TSRs because custom screen fonts in use by a foreground application will be lost when the adapter is reprogrammed.

Supporting Nonstandard Screen Dimensions

Besides the dimensions supported by _set_dimens, other nonstandard text mode screen dimensions are available on many display adapters. These modes are usually selected by changing the current video display mode to an extended value. For example, calling _set_vmode with a mode of 0x54 usually selects a 132-column text mode on Paradise VGA display adapters. These extended text modes are properly supported by the console I/O system once they have been selected. However, nonstandard text modes cannot be directly selected by _set_dimens because video mode values vary from manufacturer to manufacturer.

Fortunately, with the help of Spontaneous Assembly 3.0 it is easy to determine which extended modes are available on the target system at run time. The following code performs this task:


{
   int scrfbuf;
   char row, col;
   char vmode = 0xB+NOCLEAR;
   char *workbuf;
   int wsize;
   wsize = _screen_bufsize();
   workbuf = (char *)malloc(wsize);
   _lseekbof_h(fhandle);                                /* fhandle = handle for screen */
   if(_hsave_screen(h_scrbuf, workbuf, wsize) == -1);
      return(1);                                /* unable to save screen state */
   _video_off();                                /* disable video */
   do {                                         
      _set_vmode(vmode);                        /* start with first reserved mode */
      if(!_is_textmode())                       /* is it in text mode? */
         _get_dimens(&srow, &col);              /*  n: don't remember it */
      ...                                       /* save dimens in array */
      vmode++;
   } while (vmode < 0xFF);
   _lseekbof_h(fhandle);
   _hrestore_screen(h_scrbuf, workbuf, wsize);
   ...                                          /* display list of extended modes */
}
This procedure takes a noticeable length of time to execute. For this reason, it is best used as a program setup feature which is executed only when the user wishes to determine what their extended display options are.

WARNING! Although this video mode example does locate the nonstandard video modes on many adapters, some adapters do not appropriately validate extended video mode requests. These adapters may hang the system if the wrong video mode is selected. They may also, in some remote cases, even damage the monitor. PowerQuest/Base Two Development assumes no responsibility for your use of this example code.

Saving and Restoring the Video State

_save_vstate
Saves the current video state for later restoration by _restore_vstate.
_restore_vstate
Restores the video state previously saved by _save_vstate.
_get_vstate
Returns the current video state.
_set_vstate
Sets the video state to a specified state.
These functions get and set the current video state (and, optionally, the contents of the current screen). The current video state includes the current display adapter, video refresh state, video mode, active video page, screen dimensions, cursor shape and state, cursor position, blink/high-intensity mode, border color and state, and current and default text attributes. These functions assume that the video system is in a non-graphics video mode when they are called. If the virtual screen system is active, then the information is saved or restored for the active screen only.

_save_vstate and _restore_vstate save and restore the video state without saving the contents of the screen. The state is saved in an internal buffer which only maintains the last state saved. These functions are normally used to save and restore the state of the video system when an application begins and ends execution. _restore_vstate blanks the screen in the default attribute and leaves the cursor at the upper left corner of the screen when it restores the saved video state.

_get_vstate and _set_vstate are functionally equivalent to _save_vstate and _restore_vstate, but they allow video state information to be saved and restored from arbitrary buffers of type vstat. Therefore, these functions may be used to save and restore any number of video states. The vstat structure is defined in CONSOLE.H as follows:


typedef struct {
   char vst_adapter;                      /* active display adapter */
   char vst_vmode;                        /* active video display mode */
   char vst_vpage;                        /* active video display page */
   char vst_refresh;                      /* refresh state (1=on,0=off) */
   unsigned int vst_dimens;       /* screen dimensions (cols,rows) */
   char vst_attr;                         /* current text attribute */
   char vst_dattr;                        /* default text attribute */
   char vst_vbon;                         /* video border state (1=on,0=off) */
   char vst_vbcolor;                      /* video border color */
   char vst_bkbold;                       /* bkbold/blink mode (1=bkbold,0=blink) */
   char vst_curon;                        /* cursor state (1=on,0=off) */
   unsigned int vst_curtype;      /* cursor type (0-255,0-255) */
   unsigned int vst_curpos;       /* cursor position (col,row) */
} vstat;
Like _restore_vstate, _set_vstate blanks the screen in the default text attribute when it restores the video state. However, _set_vstate does not force the cursor to the upper left corner of the screen. Instead, _get_vstate returns the upper left corner (0,0) as the cursor position and _set_vstate restores the cursor to the position specified in the vstat structure. The actual cursor position may be saved and restored, if required, by calling _where_xy immediately after _get_vstate and then storing the returned value in the vst_curpos field, as follows:

   ...
   int xy_pos;
   ...
   _get_vstate(vbuf);                                   /* get video state */
   vstat.vst_curpos = _where_xy();              /* get cursor position, save in VSTAT buffer */
   _set_vstate(vbuf);                                   /* restore vstate+curpos */
   ...
To minimize undesirable side effects, only essential reprogramming of the display adapter takes place when the video state is restored by _restore_vstate or _set_vstate. This means, for example, that no video mode change is performed if the adapter is already in the required video mode.
_console_init
must be called before these functions may be used. In addition, _adapter_init must be called first if adapter switching may be required when a video state is restored. _restore_vstate and _set_vstate call _console_init to re-initialize the console I/O system.

Saving and Restoring the Screen

_save_screen
Saves the current screen and video state.
_restore_screen
Restores a previously saved screen and video state.
_hsave_screen
Saves the current screen and video state to a specified disk buffer.
_hrestore_screen
Restores a previously saved screen and video state from a specified disk buffer._screen_bufsize Returns the size of the buffer required by _save_screen.
These functions save and restore all text and attributes on the current screen as well as the current video state. The saved video state includes the current display adapter, video refresh state, video mode, active video page, screen dimensions, cursor shape and state, cursor position, blink/high-intensity mode, border color and state, and current and default text attributes. These functions assume that the video system is in a non-graphics video mode when they are called. If the virtual screen system is active, then the information is saved or restored for the active screen only.

_save_screen and _restore_screen save the video state and the active screen to a buffer in memory. The video state is saved at the beginning of the buffer in a structure of type VSTAT. The screen information follows (character, attribute pairs) at the first even offset in the buffer after the VSTAT structure.

_hsave_screen and _hrestore_screen are functionally equivalent to _save_screen and _restore_screen, but they save and restore the screen contents and video state information using buffers at arbitrary offsets within disk files.

The _screen_bufsize function calculates the size of the required screen/video state buffer (which depends on the screen dimensions). This allows screen buffers to be allocated dynamically. Although the calculated size applies to disk buffers as well as memory buffers, disk buffers are usually allocated at a fixed size of 16K to accommodate 132-column text video modes (132x60x2=15840 bytes, plus the VSTAT structure). Standard 80x25 screens can be easily saved in 4K buffers. Disk buffers are normally allocated in increments of 512 bytes for maximum disk performance.

_console_init must be called before these functions may be used. In addition, _adapter_init must be called first if adapter switching may be required when a screen is restored. _restore_screen and _hrestore_screen call _console_init to re-initialize the console I/O system.

Determining Active Console I/O Hardware

_is_cga
Indicates whether or not the active display adapter is CGA compatible.
_is_ega
Indicates whether or not the active display adapter is EGA compatible.
_is_mcga
Indicates whether or not the active display adapter is MCGA compatible.
_is_mda
Indicates whether or not the active display adapter is MDA compatible.
_is_vga
Indicates whether or not the active display adapter is VGA compatible.
_is_enkbd
Determines whether or not the attached keyboard is an enhanced keyboard.
_get_adapter
Returns the active display adapter type.
These functions indicate the current display adapter and keyboard configuration.

_is_mda, _is_cga, _is_ega, _is_mcga, and _is_vga all indicate whether or not the active display adapter is with the specified adapter type. For example, _is_ega returns TRUE if the active display adapter is either EGA or VGA compatible, since the VGA is fully EGA compatible. This makes these functions useful for branching around hardware-specific code (i.e., programming an EGA compatible adapter to support 43-line display mode).

_get_adapter indicates the exact type of the active display adapter (MDA, CGA, EGA, MCGA, VGA).

For efficiency, all of these functions, except _get_adapter and _is_enkbd, depend on _console_init. Note that the adapter_type variable (which is initialized by _console_init) contains the exact value returned by _get_adapter.

Colors and Color Attributes

Color attributes (text display attributes for color monitors) consist of a foreground color, a background color, and optional blink and/or intensity attribute bits. In an attribute byte, the foreground color occupies bits 0-2, the BOLD (foreground high intensity) bit occupies bit 3, the background color occupies bits 4-6, and the BLINK or BKBOLD (background high intensity) bit occupies bit 7. The following symbolic constants are defined in CONSOLE.H to simplify the process of defining complete color attributes:
Foreground and Background Colors:

BLACK                    (0x00) Black
BLUE                     (0x01) Blue
GREEN                    (0x02) Green
CYAN                     (0x03) Cyan
RED                      (0x04) Red
MAGENTA                  (0x05) Magenta
BROWN                    (0x06) Brown (low intensity yellow)
LTGRAY                   (0x07) Light gray (low intensity white)
DARKGRAY                 (0x08) High intensity black
LTBLUE                   (0x09) High intensity blue
LTGREEN                  (0x0A) High intensity green
LTCYAN                   (0x0B) High intensity cyan
LTRED                    (0x0C) High intensity red
LTMAGENTA                (0x0D) High intensity magenta
YELLOW                   (0x0E) Yellow
WHITE                    (0x0F) High intensity white

Blink and Intensity Bits:

BOLD                     (0x08) Bold foreground
BLINK                    (0x80) Blinking text
BKBOLD                   (0x80) Bold (high intensity) background
The constants above may be combined using the following formula:

Attribute = Foreground + (16*Background) + Blink or intensity bits

For example, the following code sample defines new current and default text attributes:


   ...
   _set_dattr(LTGRAY+(16*BLUE);                 /* default = LTGRAY on BLUE */
   _set_attr(WHITE+(16*BLUE)+BLINK);    /* current = BLINK WHITE on BLUE */
   ...
It is important to remember that the BLINK and BKBOLD bits are identical; their interpretation depends on the programmed state of the active display adapter. _set_blinkmode and _set_bkboldmode may be used to change the interpretation of this bit by reprogramming the active display adapter. Note also that colors DARKGRAY through WHITE set the BOLD (high intensity) bit if they are used as foreground colors; these colors set the BKBOLD (high intensity background)bit if they are used as background colors. If any of these colors is used as a background color and background high intensity has not been enabled using _set_bkboldmode, then the attribute is interpreted by the display adapter as blinking text (BLINK) on the corresponding low intensity background color.

Monochrome Attributes

Monochrome attributes (text display attributes for monochrome monitors) use the same format as color attributes (see Colors and Color Attributes, above). However, only a few of the possible foreground and background attribute combinations actually produce unique display attributes. For this reason, it is best to think of each of these foreground and background combinations as a complete attribute rather than dealing with foreground and background attributes separately. In addition, the BLINK and BKBOLD bits apply to monochrome attributes just as they apply to color attributes. These attributes and bits (defined in CONSOLE.H) are as follows:
Monochrome Attributes:

M_NORMAL                 (0x07) Normal text
M_BOLD                   (0x0F) Bold text
M_UNDERLINE              (0x01) Underlined text
M_BOLDUNDER              (0x09) Bold, underlined text
M_REVERSE                (0x70) Reverse video
M_BOLDREV                (0x78) Reverse video, bold text

Blink and Intensity Bits:

BLINK                    (0x80) Blinking text
BKBOLD                   (0x80) Bold (high intensity) background
The attributes shown above may be used directly when specifying a monochrome attribute. In addition, the BLINK and BKBOLD bits may be combined with the monochrome attributes by bitwise ORing them together with an attribute as shown in the second line of this example:

   ...
   _set_dattr(M_NORMAL)                   /* default= NORMAL */
   _set_attr(M_NORMAL+BLINK)      /* current= blinking NORMAL */
   ...
As with color attributes, the monochrome BLINK and BKBOLD bits are identical; their interpretation depends on the way in which the active display adapter has been programmed. _set_blinkmode and _set_bkboldmode may be used to change the interpretation of this bit.

It is important not to confuse the monochrome, black-and-white, and gray scale display modes. These display modes are explained thoroughly under Display Modes, above.

Black and White Attributes

Black and white attributes (text display attributes for black and white monitors) are identical to monochrome attributes, with one major difference: underlining is not supported. This means that the symbolic constants for monochrome attributes may be used for black and white attributes as long as M_UNDERLINE and M_BOLDUNDER are not used. Reverse video is usually substituted for underline in black and white display modes; this is most easily done using attribute tables (see Using Attribute Tables, above, and Sample Program, below).

It is important not to confuse the monochrome, black-and-white, and gray scale display modes. These modes are explained thoroughly under Display Modes, above.

Gray Scale Attributes

Gray scale attributes (text display attributes for gray scale monitors) are specified exactly like color attributes. The only difference between the two is that the display hardware displays the attributes as shades of gray instead of colors if the current display mode is a gray scale mode.

The exact method used to map gray scale attributes to shades of gray is not uniform for all adapters. For this reason, it is advisable to allow the end user to customize gray scale display attributes for their particular display hardware (see Using Attribute Tables, above).

It is important not to confuse the monochrome, black-and-white, and gray scale display modes. These modes are explained thoroughly under Display Modes, above.

Conditionally Assembling the Console I/O System

All of the console I/O screen output functions include code for BIOS video access, direct video access, and direct video access with "snow" control. This makes the console I/O system very flexible, but can result in unnecessary overhead if BIOS and/or snow control is not required by a particular application.

For information on how to reassemble the underlying assembly functions to exclude selected portions of the console I/O system, refer to the console I/O section in the Spontaneous Assembly 3.0 manual.

Console I/O Considerations in TSRs

The TSR system only checks for BIOS availability when an entry point is called which uses the _Con resource. The TSR system does NOT automatically save and restore the contents or state of the current screen, nor does it automatically initialize the console I/O system. This functionality must be performed each time the TSR receives control before the console I/O system can be used.

The following list outlines the steps which should be followed when writing a TSR entry point which utilizes the console I/O system:

  1. The _Con resource must be specified as a required resource for any TSR entry point which intends to use the console I/O system. In addition, the _Dos resource must be specified if the _hsave_... or _hread_... functions are to be used to save the screen contents. These resources must be specified when the entry definition structure is defined.
  2. _is_textmode should be called as soon as the TSR entry point receives control. If _is_textmode indicates that the video display adapter is in a non-text mode, then the entry point should return without calling _console_init. Before returning, the TSR entry point may sound a tone on the system speaker or add an entry request structure to the entry request queue to indicate that the TSR entry attempt failed.
  3. _console_init must be called to initialize the console I/O system.
  4. The video state and contents of the current screen must be saved before console I/O is performed. This may be performed by calling _save_screen or _hsave_screen. Alternatively, a smaller area of the screen may be saved and restored by calling _save_vstate followed by _read_textattr or _hread_textattr.
  5. After the TSR gains control, console I/O should only be performed on the active display adapter. Due to BIOS limitations, calling _adapter_switch or creating virtual screens on the secondary adapter could corrupt the screen contents and video state of the secondary display adapter.
  6. Video mode changes and screen dimension changes are not recommended, since they may change custom text mode fonts which are being used by the foreground application. This could change the appearance of the screen when the TSR returns control to the foreground application.
  7. When the TSR has finished its work, the screen state and contents must be restored before control passes to the foreground application. This may be performed by calling _restore_screen or _hrestore_screen (or _restore_vstate followed by _write_textattr or _hwrite_textattr if a small portion of the screen was saved).

Virtual Screen Considerations

When screens are managed by the virtual screen system, console I/O functions only affect the active screen. If the active screen is visible on its adapter, then console I/O changes take effect immediately. If not, the changes are made internally and are not physically visible until that screen is opened. This rule applies to all console I/O functions, including _set_adapter, _set_vpage, _set_dimens, and _set_vmode.

This means that _set_adapter cannot be counted on to physically switch adapters if the virtual screen system is in use. In fact, the virtual screen system may physically switch adapters any time a virtual screen system function is called, and the physically selected adapter may differ from the adapter of the active screen. This is necessary to allow console I/O to be directed to screens which may not be visible on their adapters. This is not an issue if the virtual screen system is not in use.

Sample Program

The sample program shown below uses of a number of console I/O functions and demonstrates the following console I/O system features: saving and restoring the video state, determining and adjusting the display mode, setting the video border color, installing and using attribute tables, hardware independent output using attribute tables, adjusting the cursor advance direction, displaying centered strings, attribute manipulation, setting the clipping region, reading keys from the keyboard, and more. The program is listed in its entirety.

#include 

#define BACKGROUND          0                   /* screen background */
#define NORMAL              1                   /* normal text */
#define BOLDTEXT            2                   /* bold text */
#define UNDERLINE           3                   /* underlined text */
#define BOLDUNDER           4                   /* bold, underlined text */
#define HIGHLIGHT           5                   /* highlighted text */
#define BOLDHIGHLIGHT   6                       /* bold, highlighted text */
#define BORDER              7                   /* box border */

char mono_table[] = {                           /* monochrome attributes: */             
               M_REVERSE,                       /* screen background */                  
               M_NORMAL,                        /* normal text */                        
               M_BOLD,                          /* bold text */                          
               M_UNDERLINE,                     /* underlined text */                    
               M_BOLDUNDER,                     /* bold and underlined text */           
               M_REVERSE,                       /* highlighted text */                   
               M_REVERSE+BKBOLD,                /* bold, highlighted text */             
               M_BOLD                           /* box border color */                   
             };                                                                  
char bw_table[] = {                             /* black and white attributes: */        
               M_REVERSE,                       /* screen background */                  
               M_NORMAL,                        /* normal text */                        
               M_BOLD,                          /* bold text */                          
               M_REVERSE,                       /* underlined text */                    
               M_BOLDREV,                       /* bold and underlined text */           
               M_REVERSE,                       /* highlighted text */                   
               M_REVERSE+BKBOLD,                /* highlighted text */                   
               M_BOLD                           /* box border text */                    
             };
char color_table[] = {                          /* color attributes: */
               LTGRAY+(16*DARKGRAY),            /* screen background */
               LTGRAY+(16*BLUE),                /* normal text */
               WHITE+(16*BLUE),                 /* bold text */
               LTGRAY+(16*RED),                 /* underlined text */
               WHITE+(16*RED),                  /* bold and underlined text */
               BLACK+(16*CYAN),                 /* highlighted text */
               BLACK+(16*LTCYAN),               /* highlighted text */
               YELLOW+(16*BLUE)                 /* box border text */
             };
char gray_table[] = {                           /* gray scale attributes: */                  
               0x87,                            /* screen background */                       
               0x17,                            /* normal text */                             
               0x1F,                            /* bold text */                               
               0x47,                            /* underlined text */                         
               0x4F,                            /* bold and underlined text */                
               0x30,                            /* highlighted text */                        
               0xB0,                            /* highlighted text */                        
               0x1E,                            /* box border text */                         
             };                                                                       
char *atables[] = {                             /* table of attribute table offsets */        
               mono_table,                      /* monochrome */                              
               bw_table,                        /* black and white */                         
               color_table,                     /* color */                                   
               gray_table,                      /* gray scale */                              
             };

void main()
{
   unsigned char xpos, ypos, wdth, hght;
   char mode;

   _console_init();                             /* init console i/o system */                  
   _save_vstate();                              /* save video state and screen color */        
   _set_bkboldmode();                           /* force background bold, no blink */          
   mode = (_get_dmode() & 254);                 /* get current dmode and strip off low order bit */
   mode = mode/2;                               /* mode = element in atables */
   _set_attrtbl(atables[mode]);                 /* set attribute table address */
   _set_dattr(BACKGROUND);                      /* set default text attribute */
   _set_vbordattr(BACKGROUND);                  /* set video border color */
   _vborder_on();                               /* make video border visible */                     
   _clr_region();                               /* clear screen in default attribute */             
   _get_region(&ypos, &xpos, &hght, &wdth);                                                 
   hght += 0x01;                                /* round up (width and height) */                   
   wdth += 0x01;                                                                            
   hght = hght/2;                               /* box size is half of screen size */               
   wdth = wdth/2;                                                                           
   ypos = hght;                                 /* center box on screen */                          
   xpos = wdth;  xpos = wdth;                                                               
   ypos = ypos/2;                               /* position 1/4 of way from (0,0) */                
   xpos = xpos/2;                                                                           
   _set_region(ypos, xpos, hght, wdth);                                                     
   _region_on();                                /* specify and enable box as new region */          
   wdth -= 0x02;                                /* wdth = box width, hght = box width */            
   hght -= 0x02;                                /*   (excluding corners) */                         
   _set_attr(BORDER);                           /* the box attribute */                             
   _cput_chri('');                              /* draw upper left hand corner */                   
   _cput_nchri('', wdth);                       /* draw top border */
   _direc_down();
   _cput_chri('');                              /* draw upper right hand corner */
   _cput_nchri('',hght);                        /* draw right border */
   _direc_left();
   _cput_chri('');                              /* draw lower right hand corner */
   _cput_nchri('', wdth);                       /* draw bottom border */
   _direc_up();
   _cput_chri('');                              /* draw lower left hand corner */
   _cput_nchri('',hght);                        /* draw left border */
   _direc_right();
   ypos += 0x01;
   xpos += 0x01;                                /* new home position inside borders */
   _set_region(ypos, xpos, hght, wdth);
   _set_dattr(NORMAL);                          /* new default attribute inside box */
   _clr_region();                               /* clear region inside box */
   _set_attr(BOLDTEXT);                         /* display centered bold string */
   _cput_strci("This is BOLD text\n\n\r", wdth);
   _set_attr(UNDERLINE);                        /* display centered underlined string */
   _cput_strci("This is UNDERLINED text\n\n\r", wdth);
   _set_attr(BOLDUNDER);                        /* display centered bold+under string */
   _cput_strci("This is BOLD and UNDERLINED text\n\n\r", wdth);
   _set_attr(HIGHLIGHT);                        /* display centered highlighted string */
   _cput_strci("This is HIGHLIGHTED text\n\n\r", wdth);
   _set_attr(BOLDHIGHLIGHT);                    /* display centered boldhighlight string */
   _cput_strci("This is BOLD and HIGHLIGHTED text\n\n\r", wdth);
   _reset_attr();                               /* display centered normal string */
   _cput_strci("Press any key to continue...", wdth);
   _cget_chr();                                 /* wait for a key press */
   _restore_vstate();                           /* restore video state and screen color */
}
The sample program shown above (CONIO.C) is provided on the distribution diskettes and may be compiled and linked using the following Microsoft C and Borland C command lines:

Microsoft C:


cl /c /I\msc\include /I\sa\include
link conio,conio,,\sa\lib\_sas \msc\lib\slibce
Borland C:

bcc /c /ms /I\bc\include /I\sa\include cio_smpl.c
tlink \bc\lib\c0s conio,conio,,\sa\lib\_sas \bc\lib\cs

Console I/O vs. Scripted I/O

All of the console output performed in the example above could be condensed into a single function call to _cput_script instead of calling individual console I/O functions. For this reason, scripts are generally the preferred method of accessing console I/O functionality. See the Scripted I/O technical notes for a complete discussion of the capabilities of the scripted I/O system.