home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / UE311C.ZIP / TIPC.C < prev    next >
Text File  |  1991-10-11  |  21KB  |  531 lines

  1. /*
  2.  * TIPC.C - TI Professional and compatible terminal driver for MicroEmacs.
  3.  *      This version by Ronald Lepine, Moderator - TI Conference
  4.  *      Byte Information Exchange.
  5.  *
  6.  *      BIX ID. ronlepine
  7.  *      Programers Room - Ronald Lepine    (317) 742-5533  2400 baud
  8.  *      AT&T: (302) 836-8398
  9.  *      US Mail:
  10.  *          Ron Lepine
  11.  *          434 Shai Circle
  12.  *          Bear, DE   19701-3604
  13.  *
  14.  *      Adapted from code by Danial Lawrence for the IBM-PC.
  15.  * 
  16.  * The routines in this file provide support for the TI-PC and other
  17.  * compatible terminals. It truely writes directly to the screen RAM to do
  18.  * screen output. It compiles into nothing if not a TI-PC driver.
  19.  *
  20.  * This driver for the TIPC is not the same one that Daniel Lawrence
  21.  * distributes.  He uses TI's DSRs for most functions as you can see by
  22.  * looking at the driver in ue311c.arc.  Dan's reverse video 
  23.  * also does not work.  But do not blame him as I'm sure he does not
  24.  * have a TIPC to test Emacs on and he *is* supportting the TIPC.
  25.  * [Well, as you can see, it is the one I distribute now! - DAN]
  26.  * This driver uses direct writes to screen memory except for the message
  27.  * line like the IBM driver.  In fact I keep TI and IBM versions around by 
  28.  * having my make file replace estruct.h with one that has a IBMPC defined
  29.  * only when I compile IBMPC.C and then switching back to estruct.h with
  30.  * TIPC defined. Its last step is of course linking in the correct object
  31.  * module for each exe.
  32.  *
  33.  * You can define any buffer to be reverse video by setting the
  34.  * foreground to "BLACK" and the background to any other color
  35.  * such as "cyan" to get Black on Cyan text.  There is no way to get
  36.  * colors such as 'White on blue' on the TIPC unless it has a
  37.  * least a 1-plane graphics card in it.  If it does have a graphics
  38.  * card installed the code to change overall background
  39.  * color is tied to the $palette variable with the same values as
  40.  * TI BASIC and the Tech Reference manual section 3.5.2 as well as
  41.  * being the #define for the color here without the enable attribute.
  42.  * The text mode forground/background code still works even when you
  43.  * use a $palette backgound giving you a wide range of what can be
  44.  * done even though some combinations don't really work too well.
  45.  *
  46.  * The only reason that there are any '#if color' directives is because of
  47.  * the need to maintain structure alignments.  This is because TI's mono
  48.  * is really 8 shades instead of 8 colors and all attributes  remain the
  49.  * same.  You can have color and mono attached at the same time and
  50.  * display on both without any program support or hardware changes.  So
  51.  * you should define color. It *will* make a difference in other areas of
  52.  * the MicroEmacs code. You also do not have to do anything special for
  53.  * the palette code because writing to a nonexistant graphics plane on a
  54.  * TI causes *no* ill effects (at least according to the tech manual).
  55.  *
  56.  * Note that if you recieve MicroEmacs for the TIPC compiled by me
  57.  * it is compiled/linked so that wildcard file names on the command
  58.  * line are automagicly expanded in case you want to work with several
  59.  * similarly named files.
  60.  *
  61.  * Changes to the other files to support the the TIPC MEMAPed
  62.  * version compiled under Zortech C/C++ 1.02 to 2.10 follow.
  63.  * BTW - The version I used is 2.18 but the earlier versions should
  64.  * still be similar since I have compiled previous versions under whatever
  65.  * was current at the time and even the previous ZTC version sometimes.
  66.  *
  67.  * [I simply added Ron's #ifdef changes to the master sources - Dan]
  68.  *
  69.  *     I once thought there were three ways to correct the problems with
  70.  * DSR writes to the *25th* line, I now know some don't work.
  71.  *     One was to check the start register before all screen writes. After
  72.  * some investigation and testing I found that the  6545A Start of screen
  73.  * registers are write only.  So there is not way to correct cursor
  74.  * postioning and line position whenever DOS has changed the register. 
  75.  * Changing the start of screen pointer to offset 0 before screen writes
  76.  * also didn't solve the problem completely.  As soon as you touched a key
  77.  * after the error you ended up with the screen properly postioned, but
  78.  * you had the error message on the screen until that line was updated so
  79.  * you still ended up using a ^L to correct the screen.
  80.  *     Two is to capture critical errors (mlwrite and errors are the sources
  81.  * of DSR writes to the 25th line) and handle them myself (asm is
  82.  * only clean way) and now looks like the only way it is possible but must
  83.  * be used in conjuction with a modified method three too.
  84.  *     Three was change writes to the message line to direct screen writes
  85.  * and initialize the screen so that a critical error will write to the
  86.  * text portion of the screen where any repaints would clear it.  The same
  87.  * problems cropped up that did in number one where you needed to do a ^L
  88.  * to totally clean up the screen if the error occured while on the message
  89.  * line anyway so....  
  90.  *     Therefore a combination of two and three is most likely the best
  91.  * way if it can be done since TI does not recommend mixing DSR and direct
  92.  * writes to screen (if  I could read the 6545 registers 0Bh and 0Ch I
  93.  * could manage it though).  This is because the DSR writes *can* change
  94.  * the screen start register. The problem with a 2+3 solution is mainly
  95.  * that the extra code to handle single character writes, directly
  96.  * controlling the cursor though the CRTC cursor registers, and the
  97.  * intercept/write/read error code handling bloats the code a bit and
  98.  * coding in anything but assembly language (which  then needs to be
  99.  * interfaced to each C compiler that might be in use) is the only reasonable
  100.  * way.  I just came came to the conclusion that it wasn't worth it since
  101.  * a ^L will clear things up anyway after the error is corrected.
  102.  * 
  103.  * 12/29/89 -
  104.  *   Changed lnptr, sline, and scptr to char/char*'s because TI writes
  105.  *   only a character at a screen position and IBM a char + attribute.  TI's
  106.  *   attributes are kept up by the hardware except when changed. So we only
  107.  *   write a char at a time, not an int like the IBM code did.  This also
  108.  *   corrected a minor bug with the message line eeol's which is why I
  109.  *   looked at the driver code again.
  110.  * 
  111.  * 12/30/89 -
  112.  *   added the capability of setting the background on machines with 
  113.  *   graphics by setting the palette string with a number from 0 to 7.
  114.  *   you do this with ^XA $palette  (note small letters) and a value.
  115.  *   Values >= 8 will work since I do modulo division on the value
  116.  *   but results are the same as the color values in TI BASIC.  The
  117.  *   code, as always, works on all TI's but will not produce a change
  118.  *   on non-graphics equiped TI's.  This code also does not need a color
  119.  *   monitor to work since a TI doesn't know what kind of monitor is
  120.  *   attached and may even have color and mono attached at once.
  121.  * 
  122.  *   With the code set up so you can still do reverse video on any TI
  123.  *   by defining BLACK and yellow (or any other background color) you
  124.  *   have a large variety of posible screen setups.  So experiment.
  125.  * 
  126.  * 12/31/89 to 1/7/90 - experimented with various methods of eliminating
  127.  *   problems with mixed DSR/Direct_Memory writes.  Decided not to really
  128.  *   attempt a solution at this time.  Write Ron Lepine if you have
  129.  *   any feelings/suggestions on this problem, they are welcome.
  130.  *
  131.  * 1-9-90
  132.  *   3.10.c(Beta) New IBMPC reverse video code added to TIPC driver.
  133.  *
  134.  *   Addional changes to 3.10.c(beta) to get it to compile with Zortech C/C++
  135.  *     **** NOTE THESE CHANGES ARE NO LONGER NEEDED FOR ZTC 2.10 *****
  136.  *      isearch line 172/5, 191 - change lines to 
  137.  * 
  138.  *            if (kfunc == &forwsearch || kfunc == &forwhunt ||
  139.  *                kfunc == &backsearch || kfunc == &backhunt)
  140.  *            {
  141.  *                dir = (kfunc == &backsearch || kfunc == &backhunt)?
  142.  *                REVERSE: FORWARD;
  143.  *
  144.  * 5-26-90
  145.  *   Updated first part of this file to reflect 3.11beta line numbers
  146.  *   while compiling 3.11 beta under Zortech C/C++ 2.1.
  147.  *
  148.  * 6-04-91
  149.  *   Added last eight needed values to ctrans[] so standard emacs.rc file
  150.  *   now works.
  151.  */
  152.  
  153. #define termdef 1                       /* don't define "term" external */
  154.  
  155. #include        <stdio.h>
  156. #include        "estruct.h"
  157. #include        "eproto.h"
  158. #include        "edef.h"
  159. #include        "elang.h"
  160.  
  161. #if     TIPC
  162.  
  163. #define NROW    25                      /* Screen height.               */
  164. #define NCOL    80                      /* Screen width                 */
  165. #define MARGIN  8                       /* size of minimim margin and   */
  166. #define SCRSIZ  64                      /* scroll size for extended lines */
  167. #define NPAUSE  200                     /* # times thru update to pause */
  168. #define BEL     0x07                    /* BEL character.               */
  169. #define ESC     0x1B                    /* ESC character.               */
  170. #define SPACE   32                      /* space character              */
  171. #define SCADD       0xDE000000L         /* address of screen RAM        */
  172. #define ATTRADD     0xDE001800L         /* Address for attribute latch  */
  173. #define BLUE_PLANE  0xC0000000L         /* Address Blue graphics plane  */ 
  174. #define RED_PLANE   0xC8000000L         /* Address Red graphics plane   */ 
  175. #define GREEN_PLANE 0xD0000000L         /* Address Green graphics plane */ 
  176. #define CRTC_REG    0xDF810000L         /* 6545 CRT Controller access addr */
  177. #define CHAR_ENABLE     0x08            /* TI attribute to show char    */
  178. #define TI_REVERSE      0x10            /* TI attribute to reverse char */
  179. #define BLACK   0+CHAR_ENABLE           /* TI attribute for Black       */
  180. #define BLUE    1+CHAR_ENABLE           /* TI attribute for Blue        */
  181. #define RED     2+CHAR_ENABLE           /* TI attribute for Red         */
  182. #define MAGENTA 3+CHAR_ENABLE           /* TI attribute for Magenta     */
  183. #define GREEN   4+CHAR_ENABLE           /* TI attribute for Green       */
  184. #define CYAN    5+CHAR_ENABLE           /* TI attribute for Cyan        */
  185. #define YELLOW  6+CHAR_ENABLE           /* TI attribute for Yellow      */
  186. #define WHITE   7+CHAR_ENABLE           /* TI attribute for White       */
  187.  
  188.  
  189. PASCAL NEAR ttopen();               /* Forward references.          */
  190. PASCAL NEAR ttgetc();
  191. PASCAL NEAR ttputc();
  192. PASCAL NEAR ttflush();
  193. PASCAL NEAR ttclose();
  194. PASCAL NEAR timove();
  195. PASCAL NEAR tieeol();
  196. PASCAL NEAR tieeop();
  197. PASCAL NEAR tibeep();
  198. PASCAL NEAR tiopen();
  199. PASCAL NEAR tikopen();
  200. PASCAL NEAR tirev();
  201. PASCAL NEAR ticres();
  202. PASCAL NEAR ticlose();
  203. PASCAL NEAR tikclose();
  204. PASCAL NEAR tiputc();
  205. PASCAL NEAR tifcol();
  206. PASCAL NEAR tibcol();
  207. PASCAL NEAR scinit();
  208.  
  209. int     revflag = FALSE;        /* are we currently in rev video?       */
  210. int     cfcolor = -1;           /* current forground color              */
  211. int     cbcolor = -1;           /* current background color             */
  212. int     ctrans[] =              /* ANSI to TI color translation table   */
  213.         {BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE,
  214.          BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE};
  215.  
  216. char *scptr[NROW];                      /* pointer to screen lines-8 bit on ti */
  217. char sline[NCOL];                       /* screen line image               */
  218.  
  219. long scadd       = SCADD;               /* address of screen ram           */
  220. long attradd     = ATTRADD;             /* address of attribute latch      */
  221. long blue_plane  = BLUE_PLANE;          /* address of blue graphics plane  */
  222. long red_plane   = RED_PLANE;           /* address of red graphics plane   */
  223. long green_plane = GREEN_PLANE;         /* address of green graphics plane */
  224. long crtc_reg    = CRTC_REG;               /* 6545 CRT controller address     */
  225.  
  226. /*
  227.  * Standard terminal interface dispatch table. Most of the fields point into
  228.  * "termio" code.
  229.  */
  230. TERM    term    = {
  231.         NROW-1,
  232.         NROW-1,
  233.         NCOL,
  234.         NCOL,
  235.         MARGIN,
  236.         SCRSIZ,
  237.         NPAUSE,
  238.         tiopen,
  239.         ticlose,
  240.         tikopen,
  241.         tikclose,
  242.         ttgetc,
  243.         tiputc,
  244.         ttflush,
  245.         timove,
  246.         tieeol,
  247.         tieeop,
  248.         tieeop,
  249.         tibeep,
  250.         tirev,
  251.         ticres
  252. #if COLOR
  253.         , tifcol,
  254.         tibcol
  255. #endif
  256. };
  257.  
  258. extern union REGS rg;
  259.  
  260.  
  261. PASCAL NEAR tifcol(color)           /* set the current output color */
  262.  
  263. int color;                          /* color to set */
  264. {
  265.     cfcolor = ctrans[color];
  266. }
  267.  
  268.  
  269. PASCAL NEAR tibcol(color)           /* set the current background color */
  270.                                     /* color to set */
  271. int color;
  272. {
  273.     cbcolor = ctrans[color];        
  274. }
  275.  
  276.  
  277. PASCAL NEAR timove(row, col)
  278.  
  279. int row;
  280. int col;
  281. {
  282.     rg.h.ah = 2;            /* set cursor position function code */
  283.     rg.h.dh = col;
  284.     rg.h.dl = row;
  285.     int86(0x49, &rg, &rg);
  286. }
  287.  
  288.  
  289. PASCAL NEAR tieeol()        /* erase to the end of the line */
  290.  
  291. {
  292.     int i;                  /* loop variable                    */
  293.     char *lnptr;            /* pointer to the destination line  */
  294.     int ccol;               /* current column cursor lives      */
  295.     int crow;               /* current row  cursor lives        */
  296.  
  297.     /* find the current cursor position */
  298.     rg.h.ah = 3;            /* read cursor position function code */
  299.     int86(0x49, &rg, &rg);
  300.     ccol = rg.h.dh;         /* record current column */
  301.     crow = rg.h.dl;         /* and row */
  302.  
  303.     lnptr = &sline[0];      /* set things up */
  304.     for (i=0; i < term.t_ncol; i++)
  305.         *lnptr++ = SPACE;
  306.  
  307.     memset(attradd, cfcolor, 1);                /* write current attrs to latch */
  308.     movmem(&sline[0], scptr[crow]+ccol, term.t_ncol-ccol);
  309.  
  310. }
  311.  
  312.  
  313. PASCAL NEAR tiputc(ch)      /* put a character at the current position */
  314.                             /* in the current colors */
  315. int ch;
  316. {
  317.     memset(attradd, cfcolor, 1);    /* write current attrs to latch */
  318.     rg.h.ah = 0x0E;                 /* write char to screen with DSR */
  319.     rg.h.al = ch;                   
  320.     int86(0x49, &rg, &rg); 
  321. }
  322.  
  323.  
  324. PASCAL NEAR tieeop()        /* Actually a clear screen */
  325.  
  326. {
  327.     rg.h.ah = 0x13;         /* Clear Text Screen, Home Cursor and */
  328.     int86(0x49, &rg, &rg);  /* Set screen start register to 0     */
  329. }
  330.  
  331.  
  332. PASCAL NEAR tirev(state)    /* change reverse video state */
  333.  
  334. int state;          /* TRUE = reverse, FALSE = normal */
  335. {
  336.     revflag = state;
  337. }
  338.  
  339.  
  340. PASCAL NEAR ticres()    /* Change screen resolution. Should we add the  */
  341.                         /* the 720x350 mode besides the normal 720x300  */
  342.                         /* mode for those who can handle it?  It really */
  343.                         /* gains us nothing since we don't gain lines   */
  344.                         /* and the code works when started in that res. */
  345.                         /* Let me (Ron Lepine) know what you think      */
  346. {
  347.     return(TRUE);
  348. }
  349.  
  350.  
  351. PASCAL NEAR tibeep()
  352.  
  353. {
  354.     bdos(6, BEL, 0);
  355. }
  356.  
  357.  
  358. PASCAL NEAR tiopen()
  359.  
  360. {
  361.     strcpy(sres, "NORMAL");
  362.     revexist = TRUE;
  363.     revflag = FALSE;
  364.     scinit();
  365.     ttopen();
  366. }
  367.  
  368.  
  369. PASCAL NEAR tikopen()
  370.  
  371. {
  372.     /* Does nothing */
  373. }
  374.  
  375.  
  376. PASCAL NEAR ticlose()
  377.  
  378. {
  379.     memset(attradd, WHITE, 1);  /* write normal attrbute to latch      */
  380.                     /* Makes sure we return with a normal color        */
  381.                     /* and not reverse video or such.  Attribute       */
  382.                     /* Latch will otherwise hold last color and        */
  383.                     /* attributes it wrote to the screen, which in     */
  384.                     /* some cases is reverse video.                    */
  385. }
  386.  
  387.  
  388. PASCAL NEAR tikclose()
  389.  
  390. {
  391.     memset(attradd, WHITE, 1);  /* write normal attrbute to latch         */
  392.                     /* Dan doesn't close the the terminal when shelling   */
  393.                     /* This ensures the shell starts with a normal color  */
  394.                     /* the same way ticlose does without changing         */
  395.                     /* *any* other source file.  The only real reason we  */
  396.                     /* place it here is to change as few files as posible */
  397. }
  398.  
  399.  
  400. PASCAL NEAR scinit()    /* initialize the screen head pointers to */
  401.                         /* logical screen */
  402. {
  403.     union {
  404.         long laddr;     /* long form of address */
  405.         char *paddr;    /* pointer form of address */
  406.     } addr;
  407.  
  408.     char i;
  409.  
  410.     tieeop();        /* set logical = physical start of screen   */ 
  411.         /* initialize The screen pointer array */
  412.     for (i = 0; i < NROW; i++) {
  413.         addr.laddr = scadd + (long)(NCOL * i);
  414.         scptr[i] = addr.paddr;
  415.     }
  416. }
  417.  
  418.  
  419. PASCAL NEAR scwrite(row, outstr, forg, bacg)    /* write a line out */
  420.  
  421. int row;        /* row of screen to place outstr on */
  422. char *outstr;   /* string to write out (must be term.t_ncol long) */
  423. int forg;       /* forground color of string to write */
  424. int bacg;       /* background color */
  425.  
  426. {
  427.     char    *lnptr;         /* Pointer to the destination line */
  428.     char    i;
  429.  
  430.     /* Write the attribute byte to latch and setup the screen pointer      */
  431.     /* If forg == 0 then you can change the back ground to color.  TI      */
  432.     /* won't let you use two colors for forground and background unless    */
  433.     /* you have graphics and set the graphics color to your background     */
  434.     /* This is enabled in this driver though the $palette variable         */
  435.  
  436.     if ((forg != 0) & (!revflag)) { 
  437.         forg = ctrans[forg];
  438.         memset(attradd, forg, 1);
  439.     }else if ((forg != 0) & (revflag)) {
  440.         forg = ctrans[forg] + TI_REVERSE;
  441.         memset(attradd, forg, 1);
  442.     }else{
  443.         bacg = ctrans[bacg] + TI_REVERSE;
  444.         memset(attradd, bacg, 1); 
  445.     }
  446.     lnptr = &sline[0];
  447.     for (i=0; i<term.t_ncol; i++)
  448.         *lnptr++ = outstr[i];
  449.     /* and send the string out */
  450.     movmem(&sline[0], scptr[row], term.t_ncol);
  451. }
  452.  
  453.  
  454. PASCAL NEAR spal(palette)      /* change palette string */
  455.  
  456. char *palette;
  457. {
  458.     /* Turns on a graphics plane if it is installed         */
  459.     /* Set value of $palette works the same as in TI BASIC  */
  460.     /* and the Technical Reference manual section 3.5.2     */
  461.     /* ie. Set $palette to 7 for a white background or to   */
  462.     /* 1 for a blue background.                             */
  463.     /* Causes no problems when graphics are not installed   */
  464.     /* so there is no reason to check for the number of     */
  465.     /* graphics planes installed.                           */
  466.  
  467.     switch ((atoi(palette) % 8)) {
  468.         case 0:
  469.             memset(blue_plane,   0,  0x7fff);
  470.             memset(red_plane,    0,  0x7fff);
  471.             memset(green_plane,  0,  0x7fff);
  472.             break;
  473.         case 1:
  474.             memset(blue_plane,   0xff,  0x7fff);
  475.             memset(red_plane,    0,     0x7fff);
  476.             memset(green_plane,  0,     0x7fff);
  477.             break;
  478.         case 2:
  479.             memset(blue_plane,   0,    0x7fff);
  480.             memset(red_plane,    0xff, 0x7fff);
  481.             memset(green_plane,  0,    0x7fff);
  482.             break;
  483.         case 3:
  484.             memset(blue_plane,   0xff, 0x7fff);
  485.             memset(red_plane,    0xff, 0x7fff);
  486.             memset(green_plane,  0,    0x7fff);
  487.             break;
  488.         case 4:
  489.             memset(blue_plane,   0,    0x7fff);
  490.             memset(red_plane,    0,    0x7fff);
  491.             memset(green_plane,  0xff, 0x7fff);
  492.             break;
  493.         case 5:
  494.             memset(blue_plane,   0xff, 0x7fff);
  495.             memset(red_plane,    0,    0x7fff);
  496.             memset(green_plane,  0xff, 0x7fff);
  497.             break;
  498.         case 6:
  499.             memset(blue_plane,   0,    0x7fff);
  500.             memset(red_plane,    0xff, 0x7fff);
  501.             memset(green_plane,  0xff, 0x7fff);
  502.             break;
  503.         case 7:
  504.             memset(blue_plane,   0xff, 0x7fff);
  505.             memset(red_plane,    0xff, 0x7fff);
  506.             memset(green_plane,  0xff, 0x7fff);
  507.             break;
  508.     }
  509. }
  510.  
  511.  
  512. #if    FLABEL
  513. PASCAL NEAR fnclabel(f, n)    /* label a function key */
  514.  
  515. int f,n;    /* default flag, numeric argument [unused] */
  516.  
  517. {
  518.     /* on machines with no function keys...don't bother */
  519.     /* TI/IBM function keys are handled in other code   */ 
  520.     return(TRUE);
  521. }
  522. #endif
  523.  
  524.  
  525. #else
  526. tihello()
  527. {
  528. }
  529. #endif
  530.  
  531.