home *** CD-ROM | disk | FTP | other *** search
- /*
- * Mg 2b (turboc 1.5/MSC 1.5)
- * IBM-PC and compatible BIOS based display driver.
- * - this will tend to be a bit slower than a driver that
- * writes directly to the memory mapped screen, but with
- * the large # of display adapters floating around, I'd
- * rather let the bios do the work.
- *
- * I DO recommend FANSI-CONSOLE which significantly speeds
- * up display bios calls, however.
- */
- #include "def.h"
- #include <dos.h>
-
- #define BEL 0x07 /* BEL character. */
-
- extern int ttrow;
- extern int ttcol;
- extern int tttop;
- extern int ttbot;
- extern int tthue;
-
- static int biocol = 0;
-
- int tceeol = 2; /* Costs are set later */
- int tcinsl = 5;
- int tcdell = 5;
-
- static int insdel = TRUE; /* Do we have both insert & delete line? */
- static int rendition =0x07;
-
- int ttputc();
-
- /*
- * Initialize the terminal when the editor
- * gets started up.
- */
- ttinit() {
- }
-
- /*
- * Clean up the terminal, in anticipation of
- * a return to the command interpreter.
- */
- tttidy() {
- }
-
- /*
- * Move the cursor to the specified
- * origin 0 row and column position.
- */
- ttmove(row, col) {
- ttcol = col;
- ttrow = row;
- _move(row, col);
- }
-
- _move(row, col) {
- union REGS rg;
-
- biocol = col;
- rg.h.ah = 2; /* set cursor position function code */
- rg.h.dl = col;
- rg.h.dh = row;
- rg.h.bh = 0; /* set screen page number */
- int86(0x10, &rg, &rg);
- }
-
- /*
- * Erase to end of line.
- */
- tteeol() {
- union REGS rg;
-
- rg.h.ah = 9; /* write character/rendition */
- rg.h.bh = 0;
- rg.x.cx = ncol-biocol;
- rg.h.al = ' ';
- rg.h.bl = rendition;
-
- int86(0x10, &rg, &rg);
- }
-
- /*
- * Erase to end of page.
- */
- tteeop() {
- ttdell(ttrow, nrow, nrow - ttrow);
- }
-
- /*
- * Make a noise.
- */
- ttbeep() {
- union REGS rg;
-
- rg.h.ah = 14; /* write tty */
- rg.h.al = BEL;
-
- int86(0x10, &rg, &rg);
- }
-
- /*
- * Insert nchunk blank line(s) onto the
- * screen, scrolling the last line on the
- * screen off the bottom.
- */
- ttinsl(row, bot, nchunk) {
- union REGS rg;
-
- if (row == bot) { /* Case of one line insert is */
- ttmove(row, 0); /* special */
- tteeol();
- return;
- }
-
- rg.h.ah = 7; /* scroll down */
- rg.h.bh = 0x07;
- rg.h.al = nchunk;
- rg.h.ch = row;
- rg.h.cl = 0;
- rg.h.dh = bot;
- rg.h.dl = ncol - 1;
-
- int86(0x10, &rg, &rg);
- }
-
- /*
- * Delete nchunk line(s) from "row", replacing the
- * bottom line on the screen with a blank line.
- */
-
- ttdell(row, bot, nchunk)
- {
- union REGS rg;
-
- if (row == bot) { /* One line special case */
- ttmove(row, 0);
- tteeol();
- return;
- }
- rg.h.ah = 6; /* scroll up */
- rg.h.bh = 0x07;
- rg.h.al = nchunk;
- rg.h.ch = row;
- rg.h.cl = 0;
- rg.h.dh = bot;
- rg.h.dl = ncol - 1;
-
- int86(0x10, &rg, &rg);
- }
-
- /*
- * Switch to full screen scroll. This is
- * used by "spawn.c" just before is suspends the
- * editor, and by "display.c" when it is getting ready
- * to exit.
- */
- ttnowindow()
- {
- }
-
- /*
- * Set the current writing color to the
- * specified color. Watch for color changes that are
- * not going to do anything (the color is already right)
- * and don't send anything to the display.
- * The rainbow version does this in putline.s on a
- * line by line basis, so don't bother sending
- * out the color shift.
- */
- ttcolor(color) register int color; {
- if (color != tthue) {
- if (color == CTEXT) { /* Normal video. */
- rendition = 0x07;
- } else if (color == CMODE) { /* Reverse video. */
- rendition = 0x70;
- }
- tthue = color; /* Save the color. */
- }
- }
-
- /*
- * This routine is called by the
- * "refresh the screen" command to try and resize
- * the display. The new size, which must be deadstopped
- * to not exceed the NROW and NCOL limits, it stored
- * back into "nrow" and "ncol". Display can always deal
- * with a screen NROW by NCOL. Look in "window.c" to
- * see how the caller deals with a change.
- */
- ttresize() {
- setttysize();
- }
-
- /* calculate the cost of doing string s */
- charcost (s) char *s; {
- return strlen(s);
- }
-
- ttputc(c)
- unsigned char c;
- {
- union REGS rg;
-
- if (c == '\b') {
- if (biocol-1 > 0) {
- _move(ttrow, biocol-1);
- }
- return;
- }
- else if (c == '\r') {
- _move(ttrow, 0);
- return;
- }
- rg.h.ah = 9; /* write character/rendition */
- rg.h.bh = 0;
- rg.x.cx = 1;
- rg.h.al = c;
- rg.h.bl = rendition;
-
- int86(0x10, &rg, &rg);
-
- if (biocol+1 >= ncol)
- _move(ttrow + 1, 0);
- else
- _move(ttrow, biocol + 1);
- }
-
- struct nap
- {
- long napvalue;
- long basetime;
- };
-
- ttwait()
- {
- struct nap timer;
- napstart(200, &timer);
- while (napchk(&timer) == 0)
- if (typeahead())
- return 0;
- return 1;
- }
-
- /***************************/
- /* MSDOS time functions */
- /***************************/
-
- /* Apparantly Turbo C has a sleep library routine; MSC doesn't -jbs */
-
- #define gettime(_a) ((((long)(_a.x.cx)) << 16)+_a.x.dx)
-
- #ifdef MSC
- sleep(amount)
- {
- while (amount--)
- nap(100);
- }
- #endif
-
- /* nap in units of 100ths of seconds via busy loops. */
- nap(amount)
- {
- struct nap tim;
- napstart(amount, &tim);
- while(napchk(&tim) == 0)
- ;
- }
-
- napstart(amount,sav)
- int amount;
- register struct nap *sav;
- {
- union REGS inregs, outregs;
- int hunds, secs;
-
- inregs.h.ah = 0x2c; /* get time */
- int86(0x21, &inregs, &outregs);
-
- /* glitch in hardware RTC (time warp) makes this necessary */
- inregs = outregs;
- inregs.h.dl = 0; /* seconds counter may be slow to increment */
- if (inregs.h.dh > 0)
- --inregs.h.dh; /* paranoia */
- if (inregs.h.cl > 0)
- --inregs.h.cl; /* more paranoia */
- /* end of glitch handling */
-
- sav->basetime = gettime(inregs); /* in case of wraparound */
-
- /* convert hundredths of seconds to future time structure */
- secs = outregs.h.dh;
- hunds = outregs.h.dl + amount;
-
- while (hunds >= 100) {
- hunds -= 100;
- ++secs;
- }
- outregs.h.dl = hunds;
- while (secs >= 60) {
- secs -= 60;
- ++outregs.h.cl; /* increment minutes */
- }
- outregs.h.dh = secs;
-
- /* check for minute and hour wraparound */
- if (outregs.h.cl >= 60)
- {
- outregs.h.cl -= 60;
- ++outregs.h.ch; /* increment hours */
- }
- if (outregs.h.ch >= 24)
- {
- outregs.h.ch -= 24;
- }
- sav->napvalue = gettime(outregs);
- }
-
- napchk(sav)
- register struct nap *sav;
- {
- union REGS inregs, outregs;
- long current;
-
- inregs.h.ah = 0x2c; /* get time */
- int86(0x21, &inregs, &outregs);
-
- current = gettime(outregs);
-
- if(sav->napvalue > sav->basetime)
- {
- if (current >= sav->napvalue || current < sav->basetime)
- return 1;
- }
- else if (current >= sav->napvalue && current < sav->basetime)
- return 1;
- return 0;
- }
-