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