home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name scttywin -- Write a character to a rectangular region
- * on the current display page via BIOS,
- * TTY-style.
- *
- * Synopsis scttywin(u_row,u_col,l_row,l_col,
- * ch,fore,back,scr_fore,scr_back);
- *
- * int u_row Top row of region (0 = top of screen)
- * int u_col Leftmost column of region (0 = left edge)
- * int l_row Bottom row of region
- * int l_col Rightmost column of region
- * char ch Character to write
- * int fore -1 if existing foreground is to be
- * preserved; a value between 0 and 15
- * specifies a new foreground attribute.
- * int back -1 if existing background is to be
- * preserved; a value between 0 and 15
- * specifies a new background attribute.
- * int scr_fore Foreground attribute of blank lines
- * added when scrolling (-1 to use
- * foreground attribute of character
- * position before scroll).
- * int scr_back Background attribute of blank lines
- * added when scrolling (-1 to use
- * background attribute of character
- * position before scroll).
- *
- * Description This function writes a character to a rectangular region
- * on the current display page in the manner of a teletype.
- * It treats carriage return, line feed, backspace, and
- * bell as commands rather than as printable characters.
- * All output and scrolling are confined to the region.
- *
- * If the cursor is currently within the region, the
- * character is written at that point. If the cursor is
- * not within the region, the character is written at the
- * upper left corner of the region. The cursor is left
- * after the displayed character.
- *
- * If the screen is in a text mode, specifying -1 for fore
- * or back preserves the existing foreground or background
- * attributes, respectively. This will occur regardless of
- * the value of option. If the screen is in a graphics
- * mode, then specifying -1 for fore will cause color 1 to
- * be used.
- *
- * The region is scrolled if a line feed occurs on the last
- * row of the region or if the last row is overflowed.
- *
- * If the screen is scrolled in text mode due to a line
- * feed character and scr_fore or scr_back is -1, then the
- * foreground or background attribute(s) (respectively) for
- * the new blank row are taken from the character position
- * last occupied before the scroll. If the scroll is
- * caused by overflowing the last row of the region and
- * scr_fore or scr_back is -1, the respective attribute(s)
- * are taken from the former attribute at the leftmost
- * column of the bottom row. Otherwise the value of
- * scr_fore or scr_back is used. (When scr_fore and
- * scr_back are both -1, this uses the same convention as
- * SCTTYWRT.)
- *
- * If the screen is scrolled in a graphics mode, the
- * scrolled text is given the color specified by scr_fore,
- * unless scr_fore is -1, in which case color 1 is used.
- *
- * Example This statement:
- *
- * scttywrt(ch,fore);
- *
- * is equivalent to the following in text modes:
- *
- * scttywin(0,0,PC_BIG_ROWS,PC_COLS,
- * ch,-1,-1,-1,-1);
- *
- * and to the following in graphics modes:
- *
- * scttywin(0,0,PC_BIG_ROWS,PC_COLS,
- * ch,fore,-1,fore,-1);
- *
- * provided that fore is not -1.
- *
- * Special Tab characters ('\t') are displayed literally.
- * characters
- * NUL ('\0') is a printable character (printed as a blank
- * space).
- *
- * Line feed ('\12') causes the cursor to move down one
- * row, unless it is already on the bottom row of the
- * region, in which case the screen is scrolled.
- *
- * Carriage return ('\r') causes the cursor to move to the
- * leftmost column of the region.
- *
- * Backspace ('\b') causes the cursor to move one column to
- * the left (non-destructively), unless it is already at
- * the leftmost column of the region, in which case nothing
- * happens.
- *
- * The BEL character ('\7') causes the computer's bell to
- * sound if the current page is active.
- *
- * Returns (None. Function return type is void.)
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- * Version 3.02 March 20, 1987
- * Corrected cx value (character count) used in first call
- * to BIOS.
- *
- **/
-
- #include <bgenvid.h> /* This routine doesn't care */
- /* whether direct or BIOS */
- /* version of BGENVID.H is used.*/
- #include <bscreen.h>
-
- #define BEL '\7'
- #define BS '\b'
- #define CR '\r'
- #define LF '\12'
-
- void scttywin(u_row,u_col,l_row,l_col,ch,fore,back,scr_fore,scr_back)
- int u_row,u_col,l_row,l_col;
- char ch;
- int fore,back,scr_fore,scr_back;
- {
- int mode,columns,act_page,last_row,graphics;
- int oldmask,old_attr;
- int ax,bx,cx,dx,flags; /* General registers */
- int row,col;
-
- scmode(&mode,&columns,&act_page);
- last_row = scrows() - 1;
- graphics = (mode > 3 && mode != 7);
-
- utbound(u_row,0,last_row) /* Force reasonable values */
- utbound(u_col,0,columns - 1)
- utbound(l_row,u_row,last_row)
- utbound(l_col,u_col,columns - 1)
-
- sccurpos(&row,&col);
- if (utrange(row,u_row,l_row) || utrange(col,u_col,l_col))
- sccurset((row = u_row),(col = u_col));
-
- switch (ch)
- {
- case BEL:
- scttywrt(ch,0);
- break; /* Don't beep on nonactive page */
-
- case BS:
- if (col > u_col) /* Don't back up past first */
- sccurset(row,col - 1); /* column */
- break;
-
- case CR:
- sccurset(row,u_col); /* Beginning of current line */
- break;
-
- default: /* First write the character */
- if (graphics) /* Graphics mode: */
- { /* Ignore previous attributes */
- if (fore == -1) /* since we can't read them. */
- fore = 1;
- back = 0; /* Nonzero background causes */
- /* trouble. */
- oldmask = 0x00; /* Ignore previous attributes. */
- }
- else /* Text mode: */
- {
- if (fore == -1) /* "oldmask" will help us */
- oldmask = 0x0f; /* extract the portion(s) of */
- else /* the previous attributes */
- oldmask = 0x00; /* which must be preserved. */
- if (back == -1)
- oldmask |= 0xf0;
- }
-
- if (oldmask == 0xff)
- { /* Write character only */
- ax = utbyword(10,ch);
- bx = utbyword(b_curpage,0);
- cx = 1;
- bios(16,&ax,&bx,&cx,&dx,&flags);
- }
- else
- { /* Write character with */
- /* attributes */
- if (oldmask != 0x00)
- {
- ax = utbyword(8,0);
- bx = utbyword(b_curpage,0);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- old_attr = uthibyte(ax) & oldmask;
- }
- else
- old_attr = 0;
-
- ax = utbyword(9,ch);
- bx = utbyword(b_curpage,
- old_attr | (utnybbyt(back,fore) & ~oldmask));
- cx = 1;
- bios(16,&ax,&bx,&cx,&dx,&flags);
- }
-
- ax = 0x0200;
- bx = utbyword(b_curpage,0);
- if (++col <= l_col) /* Check for possible wrap */
- { /* This fits on current line */
- dx = utbyword(row,col);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- break;
- }
- /* Wrap to next line */
- dx = utbyword(row,col = u_col);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- case LF:
- if (row < l_row)
- { /* No need to scroll */
- sccurset(row + 1,col);
- break;
- }
- /* Obtain attribute with which */
- /* to fill new bottom line. */
- if (graphics)
- {
- if (scr_fore == -1)
- scr_fore = 1;
- }
- else
- {
- scread(&fore,&back); /* Obtain attribute from */
- /* previous cursor position */
- if (scr_fore == -1)
- scr_fore = fore;
- if (scr_back == -1)
- scr_back = back;
- }
-
- /* Scroll up. */
- scpscrol(1,
- utnybbyt(scr_back,scr_fore),
- u_row,u_col,
- l_row,l_col,
- SCR_UP);
- break;
- }
- }