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.
- *
- * Bashed much to support, among other things, CURSES under U*x
- * and pre-queueable input everywhere not WINDOW_IO.
- */
- #include "jam.h"
- #include "def.h"
- #include "keyname.h"
-
- #ifndef CURSES /* UNIX only */
- # include <dos.h>
- #else
- #include <signal.h>
- # ifdef SOL
- # include <sys/resource.h>
- struct rlimit rlim;
- # endif
- #endif
-
- #define BEL 0x07 /* BEL character. */
- #define NORMAL 0x07
- #define REVERSE 0x70
-
- 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 = NORMAL;
-
-
- static int rn_(_move, (int row, int col));
- static int rn_(_ttinsl,(int row, int bot, int nchunk));
- static int rn_(_ttdell, (int row, int bot, int nchunk));
- static int rn_(napstart,(int amount,struct nap *sav));
- static int rn_(napchk, (struct nap *sav));
- static int rn_(nap, (int amount));
- static int rn_(putthechar,(unsigned char c));
-
- /*
- * Initialize the terminal when the editor
- * gets started up.
- */
- ttinit()
- {
- #ifdef CURSES
- char *termid = (char *)getenv("TERM");
-
- initscr();
- saveterm();
- noecho();
- nonl();
- cbreak();
- raw();
- halfdelay(2); /* non-blocking i/o at 1/10 sec intervals */
- keypad(stdscr, TRUE);
-
- /* Sigh, on some devices the scroll feature looks
- * crummy. This should be a list, and also user-setable
- */
- idlok(stdscr, TRUE);
- if (termid)
- {
- if ((strcmp("xterm", termid) == 0) || (strcmp("sun-cmd", termid) == 0))
- idlok(stdscr, FALSE);
- }
-
- wmove(stdscr, 0, 0);
- #endif
- return 1;
- }
-
- /*
- * Clean up the terminal, in anticipation of
- * a return to the command interpreter.
- */
- tttidy()
- {
- #ifdef CURSES
- resetterm();
- echo();
- nocbreak();
- noraw();
- nl();
-
- endwin();
- #endif
- return 1;
- }
-
- int ttputline(s)
- char *s;
- {
- while (s && *s)
- ttputc(*s++);
- return(1);
- }
-
- /*
- * Move the cursor to the specified
- * origin 0 row and column position.
- */
- ttmove(row, col)
- int row, col;
- {
- ttcol = col;
- ttrow = row;
- _move(row, col);
- return 1;
- }
-
- /*
- * Erase to end of page.
- */
- tteeop()
- {
- #ifdef CURSES
- wclrtobot(stdscr);
- #else
- ttdell(ttrow, nrow, nrow - ttrow);
- #endif
- return 1;
- }
-
- /*
- * Insert nchunk blank line(s) onto the
- * screen, scrolling the last line on the
- * screen off the bottom.
- */
- ttinsl(row, bot, nchunk)
- int row, bot, nchunk;
- {
- if (row == bot)
- { /* Case of one line insert is */
- ttmove(row, 0); /* special */
- tteeol();
- }
-
- else
- _ttinsl(row, bot, nchunk);
- return 1;
- }
-
- /*
- * Delete nchunk line(s) from "row", replacing the
- * bottom line on the screen with a blank line.
- */
- ttdell(row, bot, nchunk)
- int row, bot, nchunk;
- {
- if (row == bot)
- { /* One line special case */
- ttmove(row, 0);
- tteeol();
- }
- else
- _ttdell(row, bot, nchunk);
- return 1;
- }
-
- /*
- * 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()
- {
- return 1;
- }
-
- /*
- * 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.
- */
- ttcolor(color)
- register int color;
- {
- if (color != tthue)
- {
- #ifdef CURSES
- wrefresh(stdscr);
- #endif
- if (color == CTEXT)
- rendition = NORMAL;
- else if (color == CMODE)
- rendition = REVERSE;
- tthue = color; /* Save the color. */
- #ifdef CURSES
- if (rendition == CMODE)
- wattron(stdscr, A_REVERSE);
- else
- wattroff(stdscr, A_REVERSE);
- #endif
- }
- return 1;
- }
-
- /*
- * 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()
- {
- int flag = 0;
-
- setttysize();
- return 1;
- }
-
- ttputc(c)
- unsigned char c;
- {
- if (c == '\b')
- {
- if (biocol-1 > 0)
- {
- _move(ttrow, biocol-1);
- }
- return (1);
- }
- else if (c == '\r')
- {
- _move(ttrow, 0);
- return (1);
- }
-
- putthechar(c);
-
- if (biocol+1 >= ncol)
- _move(ttrow + 1, 0);
- else
- _move(ttrow, biocol + 1);
- }
-
-
- /********************* bios calls, or manipulations ******************/
-
-
- /* Move cursor to row, col. next char goes here
- */
- static int _move(row, col)
- int row, col;
- {
- #ifdef CURSES
- biocol = col;
- wmove(stdscr, row, col);
- #else
- 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);
- #endif
- return 1;
- }
-
- /*
- * Erase to end of line.
- */
- tteeol()
- {
- #ifdef CURSES
- wclrtoeol(stdscr);
- #else
- 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);
- #endif
- return 1;
- }
-
- /*
- * Make a noise.
- */
- ttbeep()
- {
- #ifdef CURSES
- beep();
- #else
- # if 0
- union REGS rg;
-
- rg.h.ah = 14; /* write tty */
- rg.h.al = BEL;
-
- int86(0x10, &rg, &rg);
- # else
- ewprintf("BEEP BEEP!"); /* bios bell is TOO LONG AND LOUD */
- # endif
- #endif
- return 1;
- }
-
- /*
- * Insert nchunk blank line(s) onto the
- * screen, scrolling the last line on the
- * screen off the bottom.
- */
- static int _ttinsl(row, bot, nchunk)
- int row, bot, nchunk;
- {
- #ifdef CURSES
- printf("_ttinsl NYI\n");
- #else
- union REGS rg;
-
- 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);
- #endif
- return 1;
- }
-
- /*
- * Delete nchunk line(s) from "row", replacing the
- * bottom line on the screen with a blank line.
- */
- static int _ttdell(row, bot, nchunk)
- int row, bot, nchunk;
- {
- #ifdef CURSES
- printf("_ttdell NYI\n");
- #else
- union REGS rg;
-
- 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);
- #endif
- return 1;
- }
-
- static int putthechar(c)
- unsigned char c;
- {
- #ifdef CURSES
- waddch(stdscr, c);
- #else
- union REGS rg;
-
- 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);
- #endif
- return 1;
- }
-
- #ifdef MSC
- /***************************/
- /* MSDOS time functions */
- /***************************/
-
- /* waiting thing...
- */
- struct nap
- {
- long napvalue;
- long basetime;
- };
-
- /* Apparantly Turbo C has a sleep library routine; MSC doesn't -jbs */
-
- #define gettime(_a) ((((long)(_a.x.cx)) << 16)+_a.x.dx)
-
- void sleep(amount)
- int amount;
- {
- while (amount--)
- # if 1
- nap(50); /* not so long! */
- # else
- nap(100);
- # endif
- }
-
- /* nap in units of 100ths of seconds via busy loops.
- */
- static int nap(amount)
- int amount;
- {
- struct nap tim;
- napstart(amount, &tim);
- while(napchk(&tim) == 0)
- ;
- return 1;
- }
-
- static int 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);
- return 1;
- }
-
- static int 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;
- }
-
- #endif /* MSC */
-
- ttwait()
- {
- #ifndef CURSES
- struct nap timer;
-
- napstart(200, &timer);
- while (napchk(&timer) == 0)
- #endif
- if (mytypeahead())
- return 0;
- return 1;
- }
-