home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name scwrstr -- Write a string of characters to the current
- * display page via BIOS, TTY-style
- *
- * Synopsis scwrstr(row,col,num_spaces,buffer,fore,back,option);
- *
- * int row,col Row and column at which to begin writing
- * int num_spaces Number of character cells to write;
- * if CHARS_ONLY is set (see "option" below),
- * num_spaces == 0 means the buffer is
- * terminated by a NUL ('\0') character.
- * char *buffer Data to write
- * int fore -1 if existing foreground is to be
- * preserved;
- * if CHARS_ONLY is specified, a value
- * between 0 and 15 specifies a new
- * foreground attribute.
- * int back -1 if existing background is to be
- * preserved;
- * if CHARS_ONLY is specified, a value
- * between 0 and 15 specifies a new
- * background attribute.
- * int option The option value tells SCWRSTR how the
- * buffer is constructed and where to
- * position the cursor after the buffer has
- * been written. There are three relevant
- * bits:
- *
- * Value Meaning
- * ----------- ------------------------------------
- * CUR_BEG Leave cursor at (row,col).
- * CUR_AFTER Leave cursor after end of string.
- *
- * CHARS_ONLY Buffer contains characters only.
- * If num_spaces is zero, the string
- * is terminated by a NUL ('\0')
- * character.
- * CHAR_ATTR Buffer contains (char,attr) pairs.
- *
- * MOVE_CUR Leave cursor according to
- * CUR_BEG/CUR_AFTER bit.
- * NO_MOVE_CUR Preserve cursor location.
- *
- * Description This function writes characters to the current display
- * page with or without their corresponding video
- * attributes. It can leave the cursor at the beginning or
- * end of the space written to or leave the cursor unmoved.
- * It treats carriage return, line feed, backspace, and
- * bell as commands rather than as printable characters.
- *
- * If the num_spaces argument is nonzero, it specifies the
- * number of "character cells" to write, where "character
- * cells" means the number of actual characters in the
- * buffer. (If CHAR_ATTR is specified, twice this number
- * of bytes will be used from the buffer.)
- *
- * The screen is scrolled if a line feed occurs on the last
- * line or if the last line is overflowed. If MOVE_CUR and
- * CUR_BEG are both specified, the cursor will be left at
- * (row,col) even though the screen has been scrolled.
- *
- * 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 and CHARS_ONLY is specified, then specifying -1 for
- * fore will cause color 1 to be used.
- *
- * Be aware that this routine treats NUL ('\0') as the end
- * of the string only if CHARS_ONLY is specified and if
- * num_spaces is zero. Otherwise NUL is put out as a
- * printable character (blank).
- *
- * Returns (None. Function return type is void.)
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- **/
-
- #include <string.h>
-
- #include <bisr.h>
- #include <bquery.h>
- #include <bscreen.h>
-
- #define BEL '\7'
- #define BS '\b'
- #define CR '\015'
- #define LF '\012'
-
- void scwrstr(row,col,num_spaces,buffer,fore,back,option)
- int row,col,num_spaces;
- char *buffer;
- int fore,back,option;
- {
- int mode,columns,act_page,graphics;
- char ch;
- int want_attr,oldmask,newmask,old_attr,new_attr;
- int save_row,save_col;
- int ax,bx,cx,dx,flags; /* General registers */
- ADS buffer_ads;
- ALLREG allregs;
- ADS biosvec_ads;
-
- scmode(&mode,&columns,&act_page);
- graphics = (mode > 3 && mode != 7);
- want_attr = ((option & CHAR_ATTR) != 0);
-
- utbound(row,0,scrows() - 1) /* Force reasonable values */
- utbound(col,0,columns - 1)
- if ((!want_attr) && num_spaces == 0)
- num_spaces = (int) strlen(buffer);
-
- if (option & NO_MOVE_CUR)
- {
- sccurpos(&save_row,&save_col);/* Previous cursor location. */
- }
- else
- {
- save_row = row; /* Beginning of string. */
- save_col = col;
- }
-
- 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;
-
- /* BIOS video function 19 (decimal) is the fastest portable way */
- /* to write the string, but it has several limitations: */
- /* (1) it can't preserve existing attributes, which must be */
- /* done if screen is in text mode and either fore or back */
- /* equals -1; */
- /* (2) it isn't present on the PC or PC-XT (unless an Enhanced */
- /* Graphics Adapter is installed) or PCjr; */
- /* (3) it assumes that the display page (as specified in BH) is */
- /* the active page. */
-
- scequip();
-
- if ((oldmask == 0x00 /* Ignoring prev. attr. */
- || graphics) /* Graphics mode--don't */
- /* bother preserving */
- /* attributes */
- && ( b_pcmodel == IBM_AT /* Have video function 19*/
- || b_pcmodel == IBM_CV /* Have video function 19*/
- || b_ega != ABSENT) /* Have video function 19*/
- && b_curpage == act_page) /* This is active page */
-
- { /* Then BIOS video function 19 will do the job. */
-
- isretvec(16,&biosvec_ads); /* Get address of BIOS video */
- /* services. */
-
- allregs.ax.hl.h = 19;
- allregs.ax.hl.l = (unsigned char) (option & (CUR_AFTER | CHAR_ATTR));
- allregs.bx.hl.h = (unsigned char) b_curpage;
- allregs.bx.hl.l = (unsigned char) utnybbyt(back,fore);
- allregs.cx.x = num_spaces;
- allregs.dx.x = utbyword(row,col);
- utabsptr(buffer,&buffer_ads);
- allregs.bp = buffer_ads.r;
- allregs.es = buffer_ads.s;
- allregs.flags = DEF_FLAGS;
- iscalint(&biosvec_ads, /* Call BIOS by simulating a */
- &allregs); /* software interrupt. */
- }
- else
- {
- sccurset(row,col);
-
- newmask = 0xff & ~oldmask; /* "newmask" will help us */
- /* extract the relevant */
- /* portion(s) of the new */
- /* attributes */
-
- new_attr = utnybbyt(back,fore) & newmask;
- if (oldmask == 0x00)
- old_attr = 0;
- if (fore == -1 || !want_attr)
- fore = 1;
- bx = utbyword(b_curpage,0);
- cx = 1;
- while (num_spaces--)
- {
- if ((ch = *buffer++) != CR
- && ch != LF
- && ch != BEL
- && ch != BS
- && (!graphics)
- && oldmask != 0xff)
- {
- /* Write character and */
- /* attributes */
- if (oldmask != 0x00)
- { /* Retrieve previous attributes */
- ax = utbyword(8,0);
- bios(16,&ax,&bx,&cx,&dx,&flags);
- old_attr = uthibyte(ax) & oldmask;
- }
- /* Now old_attr holds the */
- /* portion of the previous */
- /* attributes which we must */
- /* preserve. */
-
- ax = utbyword(9,ch); /* Write char & attribute */
-
- if (want_attr)
- bx=utbyword(b_curpage,old_attr|((int)*buffer++&newmask));
- else
- bx=utbyword(b_curpage,old_attr|new_attr);
-
- bios(16,&ax,&bx,&cx,&dx,&flags);
- }
- else
- if (want_attr) /* We won't use attribute, so */
- buffer++; /* step past it. */
-
- scttywrt(ch,fore); /* Handle cursor movement and */
- /* special characters. */
- /* (Color is ignored since this */
- /* is not graphics mode) */
- }
- }
-
- if ((option & NO_MOVE_CUR) || !(option & CUR_AFTER))
- sccurset(save_row,save_col); /* Restore cursor position */
- /* (either to previous location */
- /* or to beginning of string). */
- }