home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
editor
/
stevie
/
dos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-31
|
24KB
|
1,086 lines
/* $Header:
*
* MSDOS support for Stevie.
* Many of the functions in this file have two versions:
* - The original version, using ANSI escape sequences
* (by Tim Thompson and/or Tony Andrews).
* It requires a non-IBM ANSI driver, such as the shareware NANSI.SYS.
* - The BIOS-function version (by Larry A. Shurr). The BIOS version
* doesn't require an enhanced console driver such as NANSI.SYS.
* Invoke it by #defining BIOS in ENV.H.
* Dave Tutelman has incorporated many features of Larry Shurr's BIOS
* version (such as colors and 43-line mode) into the ANSI version.
*/
#include "stevie.h"
#include <stdio.h>
#include <dos.h>
#include <signal.h>
char *getenv();
static char getswitch();
static void setswitch();
#ifdef BIOS
void bios_t_ed();
void bios_t_el();
#endif
enum hostval_e {hIBMPC, hTIPRO};
typedef enum hostval_e hostval;
static hostval host_type = 0; /* Gets host computer type */
static char bgn_color = 0x7; /* For saving orig color */
static char quitting_now= 0; /* Set for windexit() */
static int crt_int = 0; /* Gets CRT BIOS interrupt */
static char bgn_page = 0; /* For saving current page (IBM PC) */
static char bgn_mode = 0; /* For saving video mode (IBM PC) */
#ifdef BIOS
static int sav_curattr = 0; /* For saving cursor attributes */
static int sav_curpos = 0; /* For saving cursor position */
#endif
/*
* inchar() - get a character from the keyboard
*/
int
inchar()
{
int c;
got_int = FALSE;
for (;;beep()) { /* loop until we get a valid character */
flushbuf(); /* flush any pending output */
switch (c = getch()) {
case 0x1e:
return K_CCIRCM;
case 0: /* special key */
if (State != NORMAL) {
c = getch(); /* throw away next char */
continue; /* and loop for another char */
}
switch (c = getch()) {
case 0x50:
return K_DARROW;
case 0x48:
return K_UARROW;
case 0x4b:
return K_LARROW;
case 0x4d:
return K_RARROW;
case 0x47: /* Home key */
stuffin("1G");
return -1;
case 0x4f: /* End key */
stuffin("G");
return -1;
case 0x51: /* PgDn key */
stuffin(mkstr(CTRL('F')));
return -1;
case 0x49: /* PgUp key */
stuffin(mkstr(CTRL('B')));
return -1;
case 0x52: /* insert key */
return K_INSERT;
case 0x53: /* delete key */
stuffin("x");
return -1;
/*
* Hard-code some useful function key macros.
*/
case 0x3b: /* F1 */
stuffin(":help\n");
return -1;
case 0x3c: /* F2 */
stuffin(":n\n");
return -1;
case 0x55: /* SF2 */
stuffin(":n!\n");
return -1;
case 0x3d: /* F3 */
stuffin(":N\n");
return -1;
case 0x56: /* SF3 */
stuffin(":N!\n");
return -1;
case 0x3e: /* F4 */
stuffin(":e #\n");
return -1;
case 0x57: /* SF4 */
stuffin(":e! #\n");
return -1;
case 0x3f: /* F5 */
stuffin(":rew\n");
return -1;
case 0x58: /* SF5 */
stuffin(":rew!\n");
return -1;
case 0x40: /* F6 */
stuffin("]]");
return -1;
case 0x59: /* SF6 */
stuffin("[[");
return -1;
case 0x42: /* F8 - Set up global substitute */
stuffin(":1,$s/");
return -1;
case 0x43: /* F9 - declare C variable */
stuffin("yyp!!cdecl\n");
return -1;
case 0x5C: /* SF9 - explain C declaration */
stuffin("yyp^iexplain \033!!cdecl\n");
return -1;
case 0x44: /* F10 - save & quit */
stuffin(":x\n");
return -1;
case 0x5D: /* F10 - quit without saving */
stuffin(":q!\n");
return -1;
default:
break;
}
break;
default:
return c;
}
}
}
static int bpos = 0;
#ifdef BIOS
#define BSIZE 256
static char outbuf[BSIZE];
/* Flushbuf() is used a little differently here in the BIOS-only interface
* than in the case of other systems. In general, the other systems buffer
* large amounts of text and screen management data (escape sequences).
* Here, only text is buffered, screen management is performed using BIOS
* calls. Hence, the buffer is much smaller since no more than one line of
* text is buffered. Also, screen management calls must assure that the
* buffered text is output before performing the requested function.
*
* O.K. Now I had better explain the tricky code sequences for IBM PC and
* TI Pro. In both cases, the tricks involve: 1) getting the text written
* to the display as quickly as possible in the desired color and 2) assur-
* ing that the cursor is positioned immediately following the latest text
* output.
*
* On the IBM PC, we output the first character using the "write character
* with attribute" function followed by code which outputs the buffer, a
* character at a time, using the "write tty" function. The first write
* sets the display attributes, which are then reused by the "write tty"
* function. The "write tty" is then used to quickly write the data while
* advancing the cursor. The "write character with attribute" function
* does not advance the cursor and so cannot be used to write the entire
* buffer without additional code to advance the cursor in a separate oper-
* ation. Even though the first character in each buffer gets written
* twice, the result is still substantially faster than it would be using a
* "write character with attribute" - "[re]position cursor" sequence.
*
* On the TI Pro, we output the entire buffer using the "write character
* string with attribute" function which is fast and convenient. Unfortun-
* ately, it does not advance the cursor. Therefore, we include code which
* determines the current location of the cursor, writes the buffer, then
* positions the cursor at the end of the new data.
*
* I admit it, this is tricky, but it makes display updates much faster
* than the would be using a more straightforward approach.
*/
void
flushbuf() /* Flush buffered output to display */
{
union REGS inregs, curregs, outregs;
if (bpos != 0) {
char *bptr = outbuf;
switch (host_type) {
case hIBMPC:
inregs.h.ah = 0x09;
inregs.h.al = *bptr;
inregs.h.bh = bgn_page;
inregs.h.bl = P(P_CO);
inregs.x.cx = 1;
int86(crt_int, &inregs, &outregs);
inregs.h.ah = 0x0E;
while (bpos-- > 0) {
inregs.h.al = *bptr++;
int86(crt_int, &inregs, &outregs);
}
break;
case hTIPRO:
curregs.h.ah = 0x03;
int86(crt_int, &curregs, &curregs);
inregs.h.ah = 0x10;
inregs.h.al = P(P_CO);
inregs.x.bx = FP_OFF(outbuf);
inregs.x.cx = bpos;
inregs.x.dx = FP_SEG(outbuf);
int86(crt_int, &inregs, &outregs);
curregs.h.ah = 0x02;
curregs.h.dh += bpos;
int86(crt_int, &curregs, &outregs);
break;
}
}
bpos = 0;
}
void
write_tty(c) /* Used to execute control chars */
char c;
{
int curcol;
union REGS inregs, curregs, outregs;
flushbuf(); \
switch (c) {
case '\t':
inregs.h.ah = 0x09;
inregs.h.al = ' ';
inregs.h.bh = bgn_page;
inregs.h.bl = P(P_CO);
inregs.x.cx = 1;
int86(crt_int, &inregs, &outregs);
inregs.h.ah = 0x0E;
int86(crt_int, &inregs, &outregs);
curregs.h.ah = 0x03;
curregs.h.bh = bgn_page;
int86(crt_int, &curregs, &outregs);
curcol = host_type == hIBMPC ? outregs.h.dl : outregs.h.dh;
while (curcol++ % P(P_TS)) int86(crt_int, &inregs, &outregs);
break;
case '\n':
if (host_type == hTIPRO) bios_t_el();
/* No break, fall through to default action. */
default:
inregs.h.ah = 0x0E;
inregs.h.bh = bgn_page;
inregs.h.al = c;
int86(crt_int, &inregs, &outregs);
break;
}
}
#else /* Not BIOS */
#define BSIZE 2048
static char outbuf[BSIZE];
void
flushbuf()
{
if (bpos != 0)
write(1, outbuf, bpos);
bpos = 0;
}
#endif
/*
* Macro to output a character. Used within this file for speed.
*
* This macro had to be upgraded for the BIOS-only version because we
* cannot count on flushbuf() to execute control characters such as
* end-of-line or tab. Therefore, when we encounter one, we flush
* the buffer and call a routine which executes the character.
*/
#ifdef BIOS
#define outone(cc) { \
register char ch = cc; \
if (ch >= ' ') { \
outbuf[bpos++] = ch; \
if (bpos >= BSIZE) flushbuf(); \
} else write_tty(ch); \
}
#else
#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
#endif
/*
* Function version for use outside this file.
*/
void
outchar(c)
char c;
{
outone(c);
}
/*
* outstr(s) - write a string to the console
*/
void
outstr(s)
char *s;
{
while (*s) {
outone(*s++);
}
}
void
beep()
{
if ( P(P_VB) )
vbeep();
else
outchar('\007');
}
vbeep() /* "Visual Bell" - reverse color flash */
{
unsigned char oldcolor, revcolor, temp;
oldcolor = P(P_CO);
/* put reverse color in revcolor */
revcolor = (P(P_CO) & 0x07) << 4; /* foregnd -> bkgnd */
temp = (P(P_CO) & 0x70) >> 4; /* bkgnd -> foregnd */
revcolor |= temp;
/* Flash revcolor, then back */
setcolor (revcolor);
flushbuf();
#ifdef TURBOC
delay (100);
#endif
setcolor (oldcolor);
windgoto (Cursrow, Curscol);
flushbuf();
}
#ifndef TURBOC
sleep(n)
int n;
{
/*
* Should do something reasonable here.
*/
}
#endif
void
pause()
{
long l;
flushbuf();
#ifdef TURBOC
delay (600); /* "stop" for a fraction of a second */
#else
/*
* Should do something better here...
*/
for (l=0; l < 5000 ;l++)
;
#endif
}
void
sig()
{
signal(SIGINT, sig);
got_int = TRUE;
}
static char schar; /* save original switch character */
/* While Larry Shurr's addition of color and mode support was
* dependent on #define BIOS, there's no reason it needs to be.
* The BIOS is always there, even if NANSI.SYS isn't. We'll
* use the BIOS where appropriate, and extend support to
* all cases of #define DOS. This is especially true of the
* setup in windinit() and the termination in windexit().
*/
void
windinit()
{
union REGS regs;
struct SREGS sregs;
/* The "SYSROM..." string is a signature in the TI Pro's ROM which
* which we can look for to determine whether or not we're running
* on a TI Pro. If we don't find it at F400:800D,
* we assume we're running on an IBM PC or clone.
* Unfortunately, the signature is actually
* the system ROM's copyright notice though you will note that the
* year is omitted. Still, placing it in this program might
* inadvertantly make it appear to be an official copyright notice
* for THIS program. Hence, I have surrounded the signature
* string with disclaimers.
*/
static char far *disclaimer1 =
"The following is *NOT* a copyright notice for this program: ";
static char far *ti_sig =
"SYSROM (c) Copyright Texas Instruments Inc.";
static char far *disclaimer2[] = {
"\nInstead, it is a signature string we look for ",
"to distinguish the TI Pro computer.\n",
"Actually, this program is in the public domain."
};
static char far *ti_sig_addr = (char far *)0xF400800D;
static int ti_sig_len = sizeof(ti_sig) - 1;
/* Identify the host type. Look for signature in TI Pro ROM. If */
/* found, set host type to TI Pro, else assume host is an IBM PC. */
host_type = strncmp(ti_sig, ti_sig_addr, ti_sig_len) ? hIBMPC : hTIPRO;
/* Next, perform host-dependent initialization. */
switch (host_type) {
case hIBMPC:
/* Get the video mode info */
crt_int = 0x10;
regs.h.ah = 0x0F;
int86(crt_int, ®s, ®s);
bgn_page = regs.h.bh;
bgn_mode = regs.h.al;
Columns = regs.h.ah;
/* Find the starting color, and save to restore later */
regs.h.ah = 8; /* Read char/attr BIOS fn */
regs.h.bh = bgn_page;
int86(crt_int, ®s, ®s);
bgn_color = (int) regs.h.ah;
P(P_CO) = bgn_color;
break;
case hTIPRO:
Columns = 80;
crt_int = 0x49;
P(P_CO) = 0x0F;
break;
default:
Columns = 80;
break;
}
P(P_LI) = Rows = 25;
schar = getswitch();
setswitch('/');
signal(SIGINT, sig);
#ifndef BIOS
setraw (1);
#endif
}
void
windexit(r)
int r;
{
union REGS regs;
quitting_now = 1;
/* Restore original color */
setcolor (bgn_color);
if (host_type == hIBMPC) {
/* If we've changed any of the setup, reset the mode.
* Otherwise, leave stuff on the screen.
*/
regs.h.ah = 0x0F; /* "Get-mode" BIOS fn */
int86(0x10, ®s, ®s);
if (bgn_mode != regs.h.al)
set_mode (bgn_mode);
}
flushbuf();
setswitch(schar);
#ifndef BIOS
setraw(0);
#endif
exit(r);
}
#ifndef BIOS
/* Setraw sets the console driver into raw mode, which makes it run
* somewhat faster. Details of the function:
* If r=1, remember current mode, and set into raw mode.
* r=0, return to the original mode.
*/
setraw (r)
int r;
{
static int origr=0; /* save the original r */
union REGS rr;
/* Do IOCTL call to get current control info */
rr.x.ax = 0x4400; /* Read IOCTL info - DOS fn */
rr.x.bx = 1; /* Handle for stdout */
intdos (&rr, &rr);
/* Save relevant info, and modify for "set" call */
if (r) {
origr = rr.h.dl & 0x20; /* save current "raw" bit */
rr.h.dl = rr.h.dl | 0x20; /* set "raw" bit */
}
else
rr.h.dl = (rr.h.dl & (~0x20)) | (origr & 0x20);
/* Do IOCTL call to set control info */
rr.x.ax = 0x4401; /* Set IOCTL function call */
rr.x.bx = 1; /* Handle for stdout */
rr.h.dh = 0; /* DL already set up */
intdos (&rr, &rr);
}
#endif
void
windgoto(r, c) /* Move cursor to r'ow & c'olumn */
register int r, c;
{
#ifdef BIOS
union REGS inregs, outregs;
if (bpos > 0) flushbuf();
inregs.h.ah = 0x02;
switch (host_type) {
case hIBMPC :
inregs.h.bh = bgn_page;
inregs.h.dh = r;
inregs.h.dl = c;
break;
case hTIPRO:
inregs.h.dh = c;
inregs.h.dl = r;
break;
}
int86(crt_int, &inregs, &outregs);
#else /* Not BIOS */
r += 1;
c += 1;
/*
* Check for overflow once, to save time.
*/
if (bpos + 8 >= BSIZE)
flushbuf();
outbuf[bpos++] = '\033';
outbuf[bpos++] = '[';
if (r >= 10)
outbuf[bpos++] = r/10 + '0';
outbuf[bpos++] = r%10 + '0';
outbuf[bpos++] = ';';
if (c >= 10)
outbuf[bpos++] = c/10 + '0';
outbuf[bpos++] = c%10 + '0';
outbuf[bpos++] = 'H';
#endif
}
FILE *
fopenb(fname, mode)
char *fname;
char *mode;
{
FILE *fopen();
char modestr[16];
sprintf(modestr, "%sb", mode);
return fopen(fname, modestr);
}
static char
getswitch()
{
union REGS inregs, outregs;
inregs.h.ah = 0x37;
inregs.h.al = 0;
intdos(&inregs, &outregs);
return outregs.h.dl;
}
static void
setswitch(c)
char c;
{
union REGS inregs, outregs;
inregs.h.ah = 0x37;
inregs.h.al = 1;
inregs.h.dl = c;
intdos(&inregs, &outregs);
}
#define PSIZE 128
/*
* fixname(s) - fix up a dos name
*
* Takes a name like:
*
* \x\y\z\base.ext
*
* and trims 'base' to 8 characters, and 'ext' to 3.
*/
char *
fixname(s)
char *s;
{
char *strchr(), *strrchr();
static char f[PSIZE];
char base[32];
char ext[32];
char *p;
int i;
strcpy(f, s);
for (i=0; i < PSIZE ;i++)
if (f[i] == '/')
f[i] = '\\';
/*
* Split the name into directory, base, extension.
*/
if ((p = strrchr(f, '\\')) != NULL) {
strcpy(base, p+1);
p[1] = '\0';
} else {
strcpy(base, f);
f[0] = '\0';
}
if ((p = strchr(base, '.')) != NULL) {
strcpy(ext, p+1);
*p = '\0';
} else
ext[0] = '\0';
/*
* Trim the base name if necessary.
*/
if (strlen(base) > 8)
base[8] = '\0';
if (strlen(ext) > 3)
ext[3] = '\0';
/*
* Paste it all back together
*/
strcat(f, base);
strcat(f, ".");
strcat(f, ext);
return f;
}
void
doshell(cmd)
char *cmd;
{
if (cmd == NULL)
if ((cmd = getenv ("COMSPEC")) == NULL)
cmd = "command.com";
system(cmd);
wait_return();
}
/*
* setcolor (color)
* Set the screen attributes (basically, color) to value co.
* The color attributes for a DOS machine are the BIOS colors
* for text. Where BIOS is not defined, we map the Escape
* sequences to the NANSI.SYS equivalents of the BIOS colors.
*/
setcolor (color)
int color;
{
#ifdef BIOS
P(P_CO) = host_type == hIBMPC ? color : ((color & 0x17) | 0x08);
#else
unsigned char work;
/* Send the ANSI define-attribute sequence */
outone('\033');
outone('[');
outone('0'); /* Normal color */
outone(';');
/* BIOS-to-NANSI color conversion may look a little bizarre.
* They have different bit orderings to represent the
* color (BIOS=RGB, NANSI=BGR).
*
* First put the foreground color.
*/
work = 0;
if (color & 1) work += 4; /* Blue */
if (color & 2) work += 2; /* Green */
if (color & 4) work += 1; /* Red */
outone('3'); /* NANSI foreground starts at 30 */
outone(work + '0');
outone(';');
/* Now the background color */
work = 0;
if (color & 0x10) work += 4; /* Blue */
if (color & 0x20) work += 2; /* Green */
if (color & 0x40) work += 1; /* Red */
outone('4'); /* NANSI background starts at 40 */
outone(work + '0');
/* Do the intensity and blinking, if any */
if (color & 8) { /* intensity */
outone(';');
outone('1');
}
if (color & 0x80) { /* blink */
outone(';');
outone('5');
}
/* The 'm' suffix means "set graphic rendition" */
outone('m');
P(P_CO) = color;
#endif /* Not BIOS */
if (!quitting_now) {
screenclear();
updatescreen();
}
}
/* setrows (r)
* Sets the screen to "r" rows, or lines, where "r" is a feasible
* value for the IBM PC with some common display. In this function:
* - We set the mode to 25-line or 43-line mode, assuming the display
* supports the requested mode.
* - We set the logical number of lines that Stevie uses to "r",
* so that the screen USED may not be the same as the physical screen.
*
* The function returns the number of rows set.
*/
setrows (r)
int r;
{
int rphys, rlog; /* physical and logical "r" */
rphys = (r <= 25) ? 25 : 43 ;
rlog = (r <= 50) ? r : 50;
/* Set the mode to correspond to the number of lines */
set_mode (rphys);
return (rlog);
}
set_mode (m)
int m;
{
set_25 ();
if (m == 43)
set_43 ();
}
#ifdef BIOS
int
set_25(lines) /* Set display to 25 line mode */
int lines;
{
union REGS inregs, outregs;
switch (host_type) {
case hIBMPC:
inregs.h.ah = 0x00;
inregs.h.al = bgn_mode;
int86(crt_int, &inregs, &outregs);
break;
case hTIPRO:
windgoto(0, 0);
inregs.h.ah = 0x09;
inregs.h.al = ' ';
inregs.h.bl = P(P_CO);
inregs.x.cx = 80 * 25;
int86(crt_int, &inregs, &outregs);
if (lines > 25) lines = 25;
break;
}
return(lines);
}
int
set_43(lines) /* Set display to 43/50 line mode */
int lines;
{
union REGS inregs, outregs;
switch (host_type) {
case hIBMPC:
inregs.x.ax = 0x1112;
inregs.h.bl = 0;
int86(crt_int, &inregs, &outregs);
inregs.x.ax = 0x1200;
inregs.h.bl = 0x20;
int86(crt_int, &inregs, &outregs);
inregs.h.ah = 0x01;
inregs.x.cx = 0x0707;
int86(crt_int, &inregs, &outregs);
break;
case hTIPRO:
if (lines > 25) lines = 25;
break;
}
return(lines);
}
#else /* Not BIOS */
set_25 ()
{
send_setmode (bgn_mode);
}
set_43 ()
{
send_setmode (43);
}
send_setmode (m)
{
outone('\033');
outone('[');
/* Convert 2-digit decimal to ASCII */
if (m >= 10)
outone( m/10 + '0' );
outone( m%10 + '0' );
outone ('h');
}
#endif /* Not BIOS */
#ifdef BIOS
/*
* The rest of the file is BIOS-specific
*/
void
bios_t_ci() /* Make cursor invisible */
{
union REGS inregs, outregs;
if (sav_curattr == 0) {
inregs.h.ah = 0x03;
inregs.h.bh = bgn_page;
int86(crt_int, &inregs, &outregs);
sav_curattr = outregs.x.cx;
inregs.h.ah = 0x01;
inregs.x.cx = 0x2000;
int86(crt_int, &inregs, &outregs);
}
}
void
bios_t_cv() /* Make cursor visible */
{
union REGS inregs, outregs;
if (sav_curattr != 0) {
inregs.h.ah = 0x01;
inregs.h.bh = bgn_page;
inregs.x.cx = sav_curattr;
int86(crt_int, &inregs, &outregs);
sav_curattr = 0;
}
}
/*
* O.K., I have tried to keep bios.c as "pure" as possible. I.e., I have used
* BIOS calls for everything instead of going for all-out speed by using
* direct-video access for updating the display - after all, I named it this
* module bios.c. There is one area, however, where using the BIOS is just
* too much of a compromise... the TI Pro's "scroll display" functions are so
* slow and ugly that I hate them. True, they are very flexible, but their
* poor on-screen appearance and low performance are a liability - you prob-
* ably think I'm exaggerating, but you're wrong - it is truly bad. There-
* fore, I am bypassing them and scrolling the screen myself; something I
* nearly always do. From a purist like me, that really says something.
*/
void
bios_t_dl(r,l) /* Delete lines */
int r, l;
{
char far *end; /* End ptr for TI Pro screen */
char far *dst; /* Dest ptr for scrolling TI Pro scrn */
char far *src; /* Src ptr for scrolling TI Pro scrn */
union REGS inregs, outregs;
switch (host_type) {
case hIBMPC:
inregs.h.ah = 0x06;
inregs.h.al = l;
inregs.h.bh = P(P_CO);
inregs.h.ch = r;
inregs.h.cl = 0;
inregs.h.dh = Rows - 1;
inregs.h.dl = Columns - 1;
int86(crt_int, &inregs, &outregs);
break;
case hTIPRO:
inregs.h.ah = 0x17;
int86(crt_int, &inregs, &outregs);
dst = MK_FP(0xDE00, outregs.x.dx + (r * Columns));
src = dst + (l * Columns);
end = MK_FP(0xDE00, outregs.x.dx + ((Rows - 1) * Columns));
while (src < end) *dst++ = *src++;
while (dst < end) *dst++ = ' ';
break;
}
}
void
bios_t_ed() /* Home cursor, erase display */
{
union REGS inregs, outregs;
windgoto(0, 0);
inregs.h.ah = 0x09;
inregs.h.al = ' ';
inregs.h.bh = bgn_page;
inregs.h.bl = P(P_CO);
inregs.x.cx = Columns * Rows;
int86(crt_int, &inregs, &outregs);
}
void
bios_t_el() /* Erase to end-of-line */
{
short ccol;
union REGS inregs, outregs;
inregs.h.ah = 0x03;
inregs.h.bh = bgn_page;
int86(crt_int, &inregs, &outregs);
inregs.h.ah = 0x09;
inregs.h.al = ' ';
inregs.h.bl = P(P_CO);
ccol = host_type == hIBMPC ? outregs.h.dl : outregs.h.dh;
inregs.x.cx = Columns - ccol;
int86(crt_int, &inregs, &outregs);
}
/* As in the delete-line function, we scroll the TI display ourselves
* rather than the use the slow-and-ugly software scroll in the BIOS. See
* the remarks for bios_t_dl() additional information.
*/
void
bios_t_il(r,l) /* Insert lines */
int r, l;
{
char far *end; /* End ptr for TI Pro screen */
char far *dst; /* For scrolling TI Pro screen */
char far *src; /* For scrolling TI Pro screen */
union REGS inregs, outregs;
switch (host_type) {
case hIBMPC:
inregs.h.ah = 0x07;
inregs.h.al = l;
inregs.h.bh = P(P_CO);
inregs.h.ch = r;
inregs.h.cl = 0;
inregs.h.dh = Rows - 1;
inregs.h.dl = Columns - 1;
int86(crt_int, &inregs, &outregs);
break;
case hTIPRO:
inregs.h.ah = 0x17;
int86(crt_int, &inregs, &outregs);
dst = MK_FP(0xDE00, outregs.x.dx + (Columns * (Rows - 1)) - 1);
src = dst - (Columns * l);
end = MK_FP(0xDE00, outregs.x.dx + (Columns * r));
while (src >= end) *dst-- = *src--;
src = MK_FP(0xDE00, outregs.x.dx + (r * Columns));
end = src + (l * Columns);
while (src < end) *src++ = ' ';
break;
}
}
void
bios_t_rc() /* Restore saved cursor position */
{
union REGS inregs, outregs;
inregs.h.ah = 0x02;
inregs.h.bh = bgn_page;
inregs.x.dx = sav_curpos;
int86(crt_int, &inregs, &outregs);
}
void
bios_t_sc() /* Save cursor position */
{
union REGS inregs, outregs;
inregs.h.ah = 0x03;
inregs.h.bh = bgn_page;
int86(crt_int, &inregs, &outregs);
sav_curpos = outregs.x.dx;
}
#endif