Technical Notes
OverviewThe 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.
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.
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.
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.
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 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.
The active display mode may be determined by calling _get_dmode.
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).
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.
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.
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).
These variables may be modified directly. They may also be manipulated by calling _set_directvideo, _get_directvideo, and _kbd_init.
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.
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.
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.
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.
_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.
_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.
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.
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.
_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.
_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.
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.
_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.
_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.
_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).
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.
_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.
_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.
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.
_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.
_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.
_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.
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) backgroundThe 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: 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) backgroundThe 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.
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.
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.
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.
The following list outlines the steps which should be followed when writing a TSR entry point which utilizes the console I/O system:
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.
#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