home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / PCCP019.ZIP / TERM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-09  |  19.3 KB  |  976 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<graph.h>
  10. #include"emu.h"
  11. #include"color.h"
  12.  
  13. #define DLLSBREG 0
  14. #define DLMSBREG 1
  15. #define INTCTLREG 1
  16. #define INTIDREG 2
  17. #define LCTLREG 3
  18. #define MCTLREG 4
  19. #define STATREG 5
  20.  
  21. #define INTACK 0x20
  22.  
  23. #define DB7 0x02
  24. #define DB8 0x03
  25. #define STOP2 0x04
  26. #define PARITYEN 0x08
  27. #define PARITYEVEN 0x10
  28. #define DLAB 0x80
  29.  
  30. #define INTBASE1 0x20
  31. #define INTMASK1 0x21
  32. #define INTBASE2 0xa0
  33. #define INTMASK2 0xa1
  34.  
  35. #define TBUFSIZ 8192
  36.  
  37. int index, basereg;
  38. unsigned char buf[TBUFSIZ];
  39. unsigned char diffintmask, irqnum;
  40. void (interrupt far *oldvect)();
  41.  
  42. void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
  43.               _bx, _dx, _cx, _ax, _ip, _cs, _flags)
  44.     unsigned _es, _ds, _di, _si, _bp, _sp;
  45.     unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
  46.     {
  47.     if(inp(basereg+STATREG)&0x01)
  48.         {
  49.         buf[index++]=inp(basereg)&0xff;
  50.         index=index%TBUFSIZ;
  51.         }
  52.     outp(INTBASE1, INTACK);
  53.     outp(INTBASE2, INTACK);
  54.     }
  55.  
  56. unsigned char lctl;
  57.  
  58. dispkbd(code)
  59.     unsigned short code;
  60.     {
  61.     int i;
  62.     long tstamp, tstamp1, dayofticksp;
  63.     unsigned char ccode, scode;
  64.     ccode=code&0xff;
  65.     scode=(code>>8)&0xff;
  66.     if(ccode)
  67.         {
  68.         while(!(inp(basereg+STATREG)&0x20));
  69.         outp(basereg, code);
  70.         }
  71.     else
  72.         if(!emu.keys[scode].len)
  73.             putch(0x07);
  74.         else
  75.             for(i=0;i<emu.keys[scode].len;i++)
  76.                 {
  77.                 while(!(inp(basereg+STATREG)&0x20));
  78.                 if(emu.keys[scode].nullpause_p&&!emu.keys[scode].chars[i])
  79.                     {
  80.                     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  81.                     dayofticksp=0;
  82.                     while(1)
  83.                         {
  84.                         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  85.                             dayofticksp+=20*60*60*24;
  86.                         if(tstamp1+dayofticksp-tstamp>22)
  87.                             break;
  88.                         }
  89.                     }
  90.                 else if(emu.keys[scode].nullpause_p&&(emu.keys[scode].chars[i]==0xff))
  91.                     {
  92.                     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  93.                     outp(basereg+LCTLREG, lctl|0x40);
  94.                     dayofticksp=0;
  95.                     while(1)
  96.                         {
  97.                         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  98.                             dayofticksp+=20*60*60*24;
  99.                         if(tstamp1+dayofticksp-tstamp>10)
  100.                             break;
  101.                         }
  102.                     outp(basereg+LCTLREG, lctl);
  103.                     }
  104.                 else
  105.                     outp(basereg, emu.keys[scode].chars[i]);
  106.                 }
  107.     }
  108.  
  109. #define LISTSIZ 16
  110.  
  111. struct
  112.     {
  113.     short index;
  114.     short row;
  115.     short column;
  116.     short list[LISTSIZ];
  117.     short listindex;
  118.     }
  119.     funcstor[NFUNCS];
  120.  
  121. clrfuncstor(seqn)
  122.     short seqn;
  123.     {
  124.     int i;
  125.     for(i=funcstor[seqn].listindex-1;i>=0;i--)
  126.         funcstor[seqn].list[i]=0;
  127.     funcstor[seqn].row=funcstor[seqn].column=funcstor[seqn].listindex=funcstor[seqn].index=0;
  128.     }
  129.  
  130. int bold, faint, blink, inverse, bkcolor, fgcolor;
  131. struct videoconfig far *vconf;
  132.  
  133. atthndl()
  134.     {
  135.     int adds, workingbk, workingfg;
  136.     adds=0;
  137.     if(vconf->adapter!=_MDPA)
  138.         {
  139.         workingbk=bkcolor;
  140.         workingfg=fgcolor;
  141.         if(faint)
  142.             if(inverse)
  143.                 if(bkcolor==WHITE)
  144.                     workingbk=GRAY;
  145.                 else
  146.                     adds+=FAINTADD;
  147.             else
  148.                 if(fgcolor==WHITE)
  149.                     workingfg=GRAY;
  150.                 else
  151.                     adds+=FAINTADD;
  152.         else
  153.             if(bold)
  154.                 {
  155.                 if(bkcolor==WHITE)
  156.                     workingbk=BWHITE;
  157.                 if(fgcolor==WHITE)
  158.                     workingfg=BWHITE;
  159.                 }
  160.         if(blink)
  161.             adds+=BLINKADD;
  162.         if(inverse)
  163.             {
  164.             if(blink)
  165.                 _settextcolor(workingbk+BLINKADD);
  166.             else
  167.                 _settextcolor(workingbk);
  168.             if(faint)
  169.                 _setbkcolor((long)(workingfg+FAINTADD));
  170.             else
  171.                 _setbkcolor((long)workingfg);
  172.             }
  173.         else
  174.             {
  175.             _settextcolor(workingfg+adds);
  176.             _setbkcolor((long)workingbk);
  177.             }
  178.         }
  179.     else
  180.         {
  181.         workingbk=BLACK;
  182.         if(bold&&!inverse)
  183.             workingfg=M_UNDER;
  184.         else
  185.             if(inverse)
  186.                 workingfg=WHITE;
  187.             else
  188.                 workingfg=M_NORMAL;
  189.         if(faint)
  190.             adds+=FAINTADD;
  191.         if(blink)
  192.             adds+=BLINKADD;
  193.         if(inverse)
  194.             {
  195.             if(blink)
  196.                 _settextcolor(workingbk+BLINKADD);
  197.             else
  198.                 _settextcolor(workingbk);
  199.             _setbkcolor((long)workingfg);
  200.             }
  201.         else
  202.             {
  203.             _settextcolor(workingfg+adds);
  204.             _setbkcolor((long)workingbk);
  205.             }
  206.         }
  207.     }
  208.  
  209.  
  210. ansiatthndl(seqn)
  211.     short seqn;
  212.     {
  213.     int i, adds, workingbk, workingfg;
  214.     if(emu.funcs[seqn].func==ANSIATTRIB)
  215.         for(i=0;i<funcstor[seqn].listindex;i++)
  216.             switch(funcstor[seqn].list[i])
  217.                 {
  218.                 /*at the moment this is strictly ANSI subset*/
  219.                 case 0:
  220.                     bkcolor=BLACK;
  221.                     fgcolor=WHITE;
  222.                     bold=faint=blink=inverse=0;
  223.                     break;
  224.                 case 1:
  225.                     bold=1;
  226.                     break;
  227.                 case 2:
  228.                     faint=1;
  229.                     break;
  230.                 case 5:
  231.                 case 6:
  232.                     blink=1;
  233.                     break;
  234.                 case 7:
  235.                     inverse=1;
  236.                     break;
  237.                 case 8:
  238.                 case 30:
  239.                 case 40:
  240.                     fgcolor=bkcolor;
  241.                     break;
  242.                 case 31:
  243.                 case 41:
  244.                     fgcolor=RED;
  245.                     break;
  246.                 case 32:
  247.                 case 42:
  248.                     fgcolor=GREEN;
  249.                     break;    
  250.                 case 33:
  251.                 case 43:
  252.                     fgcolor=YELLOW;
  253.                     break;
  254.                 case 34:
  255.                 case 44:
  256.                     fgcolor=BLUE;
  257.                     break;
  258.                 case 35:
  259.                 case 45:
  260.                     fgcolor=MAGENTA;
  261.                     break;
  262.                 case 36:
  263.                 case 46:
  264.                     fgcolor=CYAN;
  265.                     break;
  266.                 case 37:
  267.                 case 47:
  268.                     fgcolor=WHITE;
  269.                     break;
  270.                 default:
  271.                     break;
  272.                 }
  273.     atthndl();
  274.     }
  275.  
  276. int wrap_p;
  277.  
  278. wrapctl()
  279.     {
  280.     if(wrap_p)
  281.         _wrapon(_GWRAPON);
  282.     else
  283.         _wrapon(_GWRAPOFF);
  284.     }
  285.  
  286. unsigned int speed, comnum;
  287. char databits, parity, stopbits, fpname[256], dribpname[256];
  288.  
  289. updstatus()
  290.     {
  291.     struct rccoord posptr;
  292.     short tc;
  293.     long bc;
  294.     char str[80];
  295.     posptr=_gettextposition();
  296.     tc=_gettextcolor();
  297.     bc=_getbkcolor();
  298.     _settextwindow(1,1,1,80);
  299.     _settextposition(1,1);
  300.     _settextcolor(BLACK);
  301.     _setbkcolor((long)WHITE);
  302.     _wrapon(_GWRAPOFF);
  303.     sprintf(str, "Both Shifts to Exit COM%u %5u %c%c%c %22s %22s",
  304.         comnum+1, speed, databits, parity, stopbits, fpname, dribpname);
  305.     _outtext(str);
  306.     _settextwindow(2,1,25,80);
  307.     wrapctl();
  308.     _settextcolor(tc);
  309.     _setbkcolor(bc);
  310.     _settextposition(posptr.row, posptr.col);
  311.     }
  312.  
  313. int graphics;
  314.  
  315. showchar(c)
  316.     char c;
  317.     {
  318.     char str[2];
  319.     if(graphics)
  320.         if(emu.gchars[c])
  321.             c=emu.gchars[c];
  322.     str[0]=c;
  323.     str[1]='\0';
  324.     _outtext(str);
  325.     }
  326.  
  327. perffunc(seqn)
  328.     short seqn;
  329.     {
  330.     struct rccoord posptr;
  331.     int i;
  332.     switch(emu.funcs[seqn].func)
  333.         {
  334.         case CLEAR:
  335.             _clearscreen(_GCLEARSCREEN);
  336.             updstatus();
  337.             _settextposition(1,1);
  338.             break;
  339.         case HOME:
  340.             _settextposition(1,1);
  341.             break;
  342.         case CLREOL:
  343.             posptr=_gettextposition();
  344.             _wrapon(_GWRAPOFF);
  345.             for(i=posptr.col;i<=80;i++)
  346.                 _outtext(" ");
  347.             _settextposition(posptr.row, posptr.col);
  348.             wrapctl();
  349.             break;
  350.         case UP:
  351.             posptr=_gettextposition();
  352.             if(posptr.row>1)
  353.                 _settextposition(posptr.row-1, posptr.col);
  354.             break;
  355.         case DOWN:
  356.             posptr=_gettextposition();
  357.             if(posptr.row<24)
  358.                 _settextposition(posptr.row+1, posptr.col);
  359.             else
  360.                 {
  361.                 showchar('\n');
  362.                 _settextposition(posptr.row, posptr.col);
  363.                 }
  364.             break;
  365.         case LEFT:
  366.             posptr=_gettextposition();
  367.             if(posptr.col>1)
  368.                 _settextposition(posptr.row, posptr.col-1);
  369.             break;
  370.         case RIGHT:
  371.             posptr=_gettextposition();
  372.             if(posptr.col<80)
  373.                 _settextposition(posptr.row, posptr.col+1);
  374.             break;
  375.         case GOTO:
  376.             if(funcstor[seqn].row<1)
  377.                 funcstor[seqn].row=1;
  378.             if(funcstor[seqn].row>24)
  379.                 funcstor[seqn].row=24;
  380.             if(funcstor[seqn].column<1)
  381.                 funcstor[seqn].column=1;
  382.             if(funcstor[seqn].column>80)
  383.                 funcstor[seqn].row=80;
  384.             _settextposition((emu.tophi_p?25-funcstor[seqn].row:funcstor[seqn].row), funcstor[seqn].column);
  385.             break;
  386.         case NORMAL:
  387.             fgcolor=WHITE;
  388.             bkcolor=BLACK;
  389.             blink=faint=bold=inverse=0;
  390.             atthndl();
  391.             break;
  392.         case BLINK:
  393.             blink=1;
  394.             atthndl();
  395.             break;
  396.         case NOBLINK:
  397.             blink=0;
  398.             atthndl();
  399.             break;
  400.         case BOLD:
  401.             bold=1;
  402.             atthndl();
  403.             break;
  404.         case NOBOLD:
  405.             bold=0;
  406.             atthndl();
  407.             break;
  408.         case FAINT:
  409.             faint=1;
  410.             atthndl();
  411.             break;
  412.         case NOFAINT:
  413.             faint=0;
  414.             atthndl();
  415.             break;
  416.         case INVERSE:
  417.             inverse=1;
  418.             atthndl();
  419.             break;
  420.         case NOINVERSE:
  421.             inverse=0;
  422.             atthndl();
  423.             break;
  424.         case UPN:
  425.             posptr=_gettextposition();
  426.             if(posptr.row-funcstor[seqn].row<1)
  427.                 _settextposition(1, posptr.col);
  428.             else
  429.                 _settextposition(posptr.row-funcstor[seqn].row, posptr.col);
  430.             break;
  431.         case DOWNN:
  432.             posptr=_gettextposition();
  433.             if(posptr.row+funcstor[seqn].row>24)
  434.                 {
  435.                 _settextposition(24,1);
  436.                 for(i=25-(posptr.row+funcstor[seqn].row);i<0;++i)
  437.                     showchar('\n');
  438.                 _settextposition(24, posptr.col);
  439.                 }
  440.             else
  441.                 _settextposition(posptr.row+funcstor[seqn].row, posptr.col);
  442.             break;
  443.         case LEFTN:
  444.             posptr=_gettextposition();
  445.             if(posptr.col-funcstor[seqn].column<1)
  446.                 _settextposition(posptr.row, 1);
  447.             else
  448.                 _settextposition(posptr.row, posptr.col-funcstor[seqn].column);
  449.             break;
  450.         case RIGHTN:
  451.             posptr=_gettextposition();
  452.             if(posptr.col+funcstor[seqn].column>80)
  453.                 _settextposition(posptr.row, 80);
  454.             else
  455.                 _settextposition(posptr.row, posptr.col+funcstor[seqn].column);
  456.             break;
  457.         case ANSIATTRIB:
  458.             ansiatthndl(seqn);
  459.             break;
  460.         case WRAP:
  461.             wrap_p=1;
  462.             wrapctl();
  463.             break;
  464.         case NOWRAP:
  465.             wrap_p=0;
  466.             wrapctl();
  467.             break;
  468.         case GOTOLINE:
  469.             posptr=_gettextposition();
  470.             if(funcstor[seqn].row<1)
  471.                 funcstor[seqn].row=1;
  472.             if(funcstor[seqn].row>24)
  473.                 funcstor[seqn].row=24;
  474.             _settextposition(emu.tophi_p?25-funcstor[seqn].row:funcstor[seqn].row, posptr.col);
  475.             break;
  476.         case GOTOCOL:
  477.             posptr=_gettextposition();
  478.             if(funcstor[seqn].column<1)
  479.                 funcstor[seqn].column=1;
  480.             if(funcstor[seqn].column>80)
  481.                 funcstor[seqn].row=80;
  482.             _settextposition(posptr.row, funcstor[seqn].column);
  483.             break;
  484.         case WYSEATTR:
  485.             if(funcstor[seqn].row&0x02)
  486.                 blink=1;
  487.             else
  488.                 blink=0;
  489.             if(funcstor[seqn].row&0x04)
  490.                 inverse=1;
  491.             else
  492.                 inverse=0;
  493.             if(funcstor[seqn].row&0x08)
  494.                 bold=1;
  495.             else
  496.                 bold=0;
  497.             if(funcstor[seqn].row&0x40)
  498.                 faint=1;
  499.             else
  500.                 faint=0;
  501.             atthndl();
  502.             break;
  503.         case GRAPHCHAR:
  504.             showchar(emu.gchars[funcstor[seqn].row]);
  505.             break;
  506.         case BEGGRAPH:
  507.             graphics=1;
  508.             break;
  509.         case ENDGRAPH:
  510.             graphics=0;
  511.             break;
  512.         case TAB:
  513.             posptr=_gettextposition();
  514.             _settextposition(posptr.row, posptr.col+(8-((posptr.col-1)%8)));
  515.             break;
  516.         case BELL:
  517.             putch(7);
  518.             break;
  519.         case DTAB:
  520.             posptr=_gettextposition();
  521.             for(i=0;i<(8-((posptr.col-1)%8));++i)
  522.                 _outtext(" ");
  523.  
  524.         default:
  525.             break;
  526.         }
  527.     }
  528.  
  529. dispport(c)
  530.     unsigned char c;
  531.     {
  532.     int seqn, done, ok;
  533.     done=0;
  534.     ok=0;
  535.     for(seqn=0;seqn<NFUNCS;seqn++)
  536.         {
  537.         if(emu.funcs[seqn].codes[funcstor[seqn].index]&0xff00)
  538.             switch(emu.funcs[seqn].codes[funcstor[seqn].index])
  539.                 {
  540.                 case END:
  541.                     if(funcstor[seqn].index)
  542.                         {
  543.                         done=1;
  544.                         perffunc(seqn);
  545.                         }
  546.                     break;
  547.                 case BINCOL:
  548.                     funcstor[seqn].column=c-emu.bincoloff;
  549.                     ok=1;
  550.                     if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  551.                         {
  552.                         done=1;
  553.                         perffunc(seqn);
  554.                         }
  555.                     break;
  556.                 case BINROW:
  557.                     funcstor[seqn].row=c-emu.binrowoff;
  558.                     ok=1;
  559.                     if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  560.                         {
  561.                         done=1;
  562.                         perffunc(seqn);
  563.                         }
  564.                     break;
  565.                 case ASCDECCOL:
  566.                     if((c>='0')&&(c<='9'))
  567.                         {
  568.                         ok=1;
  569.                         funcstor[seqn].column*=10;
  570.                         funcstor[seqn].column+=(c-'0');
  571.                         }
  572.                     else
  573.                         if(c==emu.funcs[seqn].codes[++funcstor[seqn].index])
  574.                             {
  575.                             ok=1;
  576.                             if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  577.                                 {
  578.                                 done=1;
  579.                                 perffunc(seqn);
  580.                                 }
  581.                             }
  582.                         else
  583.                             clrfuncstor(seqn);
  584.                     break;
  585.                 case ASCDECROW:
  586.                     if((c>='0')&&(c<='9'))
  587.                         {
  588.                         ok=1;
  589.                         funcstor[seqn].row*=10;
  590.                         funcstor[seqn].row+=(c-'0');
  591.                         }
  592.                     else
  593.                         if(c==emu.funcs[seqn].codes[++funcstor[seqn].index])
  594.                             {
  595.                             ok=1;
  596.                             if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  597.                                 {
  598.                                 done=1;
  599.                                 perffunc(seqn);
  600.                                 }
  601.                             }
  602.                         else
  603.                             clrfuncstor(seqn);
  604.                     break;
  605.                 case ASCDECSEMILIST:
  606.                     if((c>='0')&&(c<='9'))
  607.                         {
  608.                         ok=1;
  609.                         funcstor[seqn].list[funcstor[seqn].listindex]*=10;
  610.                         funcstor[seqn].list[funcstor[seqn].listindex]+=(c-'0');
  611.                         }
  612.                     else
  613.                         {
  614.                         if(funcstor[seqn].listindex<LISTSIZ)
  615.                             funcstor[seqn].listindex++;
  616.                         
  617.                         if(c==';')
  618.                             ok=1;
  619.                         else
  620.                             if(c==emu.funcs[seqn].codes[++funcstor[seqn].index])
  621.                                 {
  622.                                 ok=1;
  623.                                 if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  624.                                     {
  625.                                     done=1;
  626.                                     perffunc(seqn);
  627.                                     }
  628.                                 }
  629.                             else
  630.                                 clrfuncstor(seqn);
  631.                         }
  632.                     break;
  633.                 case GRABCHAR:
  634.                     ok=1;
  635.                     funcstor[seqn].row=c;
  636.                     if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  637.                         {
  638.                         done=1;
  639.                         perffunc(seqn);
  640.                         }
  641.                     break;
  642.                 case GRAPHCHAR_T:
  643.                     if(emu.gchars[c])
  644.                         {
  645.                         ok=1;
  646.                         funcstor[seqn].row=c;
  647.                         if(emu.funcs[seqn].codes[funcstor[seqn].index]==END)
  648.                             {
  649.                             done=1;
  650.                             perffunc(seqn);
  651.                             }
  652.                         }
  653.                     else
  654.                         clrfuncstor(seqn);
  655.                     break;
  656.                 }
  657.         else
  658.             if(c==emu.funcs[seqn].codes[funcstor[seqn].index])
  659.                 {
  660.                 ok=1;
  661.                 if(emu.funcs[seqn].codes[++funcstor[seqn].index]==END)
  662.                     {
  663.                     done=1;
  664.                     perffunc(seqn);
  665.                     }
  666.                 }
  667.             else
  668.                 clrfuncstor(seqn);
  669.         if(done)
  670.             {
  671.             ok=1;
  672.             for(seqn=0;seqn<NFUNCS;seqn++)
  673.                 clrfuncstor(seqn);
  674.             break;
  675.             }
  676.         }
  677.     if(!ok)
  678.         showchar(c);
  679.     }
  680.  
  681. initdisp()
  682.     {
  683.     int i;
  684.     for(i=0;i<NFUNCS;i++)
  685.         {
  686.         funcstor[i].listindex=LISTSIZ;
  687.         clrfuncstor(i);
  688.         }
  689.     bold=faint=blink=inverse=0;
  690.     fgcolor=WHITE;
  691.     bkcolor=BLACK;
  692.     graphics=0;
  693.     wrap_p=emu.default_wrap_p;
  694.     }
  695.  
  696. main(argc, argv)
  697.     int argc;
  698.     char **argv;
  699.     {
  700.     FILE *dribble;
  701.     char c;
  702.     int follow, emufd, i, orun;
  703.     unsigned intnum;
  704.     unsigned char newintmask, oldintmask, dlmsb, dllsb;
  705.     if(!strcmp(getenv("REMOTE"), "YES"))
  706.         {
  707.         printf("You appear to be logged in remotely, judging by the environment\n");
  708.         printf("variable REMOTE, so this is probably a very bad idea.\n");
  709.         printf("Are you sure you want to run TERM? (y or n) --> ");
  710.         if(getchar()!='y') /* Note getchar() and not getch()! */
  711.             {
  712.             printf("I didn't think so!\n");
  713.             exit(99);
  714.             }
  715.         else
  716.             printf("OK, you're the boss!\n");
  717.         }
  718.     _getvideoconfig(vconf);
  719.     index=follow=0;
  720.     lctl=0;
  721.     if((argc<4)||(argc>6))
  722.         {
  723.         printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  724.         printf("USAGE: term <comnum> <bps> <data><parity><stop> [<emu or - >] [<dribble>]\n");
  725.         printf("<emu> is an emulation file base pathname.\n");
  726.         printf("<dribble> is a dribble (text capture) file.\n");
  727.         printf("The environment variable TERMPATH is used for the emulation file if set.\n");
  728.         exit(1);
  729.         }
  730.     fpname[0]='\0';
  731.     dribpname[0]='\0';
  732.     if((argc>=5)&&(argv[4][0]!='-'))
  733.         {
  734.         if((getenv("TERMPATH")==NULL)||(argv[4][0]=='\\')||(argv[4][1]==':'))
  735.             sprintf(fpname, "%s.emu", argv[4]);
  736.         else
  737.             sprintf(fpname, "%s\\%s.emu", getenv("TERMPATH"), argv[4]);
  738.         if((emufd=open(fpname, O_RDONLY|O_BINARY))==-1)
  739.             {
  740.             printf("Error opening emulation file %s.\n", fpname);
  741.             exit(2);
  742.             }
  743.         else
  744.             if(read(emufd, &emu, sizeof(emu))!=sizeof(emu))
  745.                 {
  746.                 printf("Error reading emulation file %s.\n", fpname);
  747.                 exit(3);
  748.                 }
  749.             else;
  750.         }
  751.     else
  752.         {
  753.         nullemu();
  754.         emu.funcs[0].func=LEFT;
  755.         emu.funcs[0].codes[0]='\b';
  756.         emu.funcs[0].codes[1]=END;
  757.         emu.funcs[1].func=DTAB;
  758.         emu.funcs[1].codes[0]='\t';
  759.         emu.funcs[1].codes[1]=END;
  760.         emu.funcs[2].func=BELL;
  761.         emu.funcs[2].codes[0]='\007';
  762.         emu.funcs[2].codes[1]=END;
  763.         }
  764.     if(argc==6)
  765.         {
  766.         strcpy(dribpname, argv[5]);
  767.         if((dribble=fopen(argv[5], "a"))==NULL)
  768.             {
  769.             printf("Couldn't open dribble file %s.\n");
  770.             exit(10);
  771.             }
  772.         else
  773.             fprintf(dribble, "\nBeginning of dribble segment.\n\n");
  774.         }
  775.     else
  776.         dribble=NULL;
  777.     comnum=atoi(argv[1])-1;
  778.     newintmask=0;
  779.     switch(comnum)
  780.         {
  781.         case 0:
  782.             irqnum=4;
  783.             diffintmask=0xff&~0x10;
  784.             basereg=0x3f8;
  785.             break;
  786.         case 1:
  787.             irqnum=3;
  788.             diffintmask=0xff&~0x08;
  789.             basereg=0x2f8;
  790.             break;
  791.         case 2:
  792.             irqnum=4;
  793.             diffintmask=0xff&~0x10;
  794.             basereg=0x3e8;
  795.             break;
  796.         case 3:
  797.             irqnum=3;
  798.             diffintmask=0xff&~0x08;
  799.             basereg=0x2e8;
  800.             break;
  801.         case 4:
  802.             irqnum=2;
  803.             diffintmask=0xff&~0x02;
  804.             basereg=0x3e8;
  805.             break;
  806.         case 5:
  807.             irqnum=2;
  808.             diffintmask=0xff&~0x02;
  809.             basereg=0x2e8;
  810.             break;
  811.         case 6:
  812.             irqnum=5;
  813.             diffintmask=0xff&~0x20;
  814.             basereg=0x3e8;
  815.             break;
  816.         case 7:
  817.             irqnum=5;
  818.             diffintmask=0xff&~0x20;
  819.             basereg=0x2e8;
  820.             break;
  821.         default:
  822.             printf("Bad port choice.\n");
  823.             exit(4);
  824.         }
  825.     intnum=irqnum+8;
  826.     speed=atoi(argv[2]);
  827.     switch(speed)
  828.         {
  829.         case 300:
  830.             dlmsb=0;
  831.             dllsb=0xc0;
  832.             break;
  833.         case 1200:
  834.             dlmsb=0;
  835.             dllsb=0x60;
  836.             break;
  837.         case 2400:
  838.             dlmsb=0;
  839.             dllsb=0x30;
  840.             break;
  841.         case 9600:
  842.             dlmsb=0;
  843.             dllsb=0x0c;
  844.             break;
  845.         case 19200:
  846.             dlmsb=0;
  847.             dllsb=0x06;
  848.             break;
  849.         case 38400:
  850.             dlmsb=0;
  851.             dllsb=0x03;
  852.             break;
  853.         case 57600:
  854.             dlmsb=0;
  855.             dllsb=0x02;
  856.             break;
  857.         default:
  858.             printf("Bad speed.\n");
  859.             exit(5);
  860.         }
  861.     parity=argv[3][1];
  862.     switch(parity)
  863.         {
  864.         case 'e':
  865.         case 'E':
  866.             lctl |= PARITYEN | PARITYEVEN;
  867.             break;
  868.         case 'o':
  869.         case 'O':
  870.             lctl|=PARITYEN;
  871.             break;
  872.         case 'n':
  873.         case 'N':
  874.             break;
  875.         default:
  876.             printf("Bad parity.\n");
  877.             exit(7);
  878.         }
  879.     databits=argv[3][0];
  880.     switch(databits)
  881.         {
  882.         case '7':
  883.             lctl|=DB7;
  884.             break;
  885.         case '8':
  886.             lctl|=DB8;
  887.             break;
  888.         default:
  889.             printf("Bad data bits.\n");
  890.             exit(8);
  891.         }
  892.     stopbits=argv[3][2];
  893.     switch(stopbits)
  894.         {
  895.         case '1':
  896.             break;
  897.         case '2':
  898.             lctl|=STOP2;
  899.             break;
  900.         default:
  901.             printf("Bad stop bits.\n");
  902.             exit(9);
  903.         }
  904.     outp(basereg+LCTLREG, DLAB);
  905.     outp(basereg+DLLSBREG, dllsb);
  906.     outp(basereg+DLMSBREG, dlmsb);
  907.     outp(basereg+LCTLREG, lctl);
  908.     oldvect=_dos_getvect(intnum);
  909.     _dos_setvect(intnum, inthndl);
  910.     outp(basereg+INTCTLREG, 0x00);
  911.     outp(basereg+MCTLREG, 0x0b);
  912.     oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
  913.     newintmask=diffintmask;
  914.     newintmask&=oldintmask;
  915.     if(intnum==10)
  916.         outp(INTMASK2, newintmask);
  917.     else
  918.         outp(INTMASK1, newintmask);
  919.     outp(INTBASE1, INTACK);
  920.     outp(INTBASE2, INTACK);
  921.     outp(basereg+INTCTLREG, 0x01);
  922.     outp(INTBASE1, INTACK);
  923.     outp(INTBASE2, INTACK); /* Yes, Virginia, you really need it! */
  924.     _clearscreen(_GCLEARSCREEN);
  925.     initdisp();
  926.     updstatus();
  927.     atthndl();
  928.     _settextposition(1,1);
  929.     orun=0;
  930.     while(1)
  931.         {
  932.         if((_bios_keybrd(_KEYBRD_SHIFTSTATUS) & 3) == 3)
  933.             {
  934.             if(intnum==10)
  935.                 outp(INTMASK2, oldintmask);
  936.             else
  937.                 outp(INTMASK1, oldintmask);
  938.             outp(basereg+INTCTLREG, 0x00);
  939.             outp(basereg+MCTLREG, 0x03);
  940.             _dos_setvect(intnum, oldvect);
  941.             _settextcolor(WHITE);
  942.             _setbkcolor((long)BLACK);
  943.             if(dribble!=NULL)
  944.                 {
  945.                 fprintf(dribble, "\nEnd of dribble segment.\n");
  946.                 fclose(dribble);
  947.                 }
  948.             _outtext("\nOrderly exit from TERM.\n");
  949.             exit(0);
  950.             }
  951.         if(_bios_keybrd(_KEYBRD_READY))
  952.             dispkbd(_bios_keybrd(_KEYBRD_READ));
  953.         if(follow!=index)
  954.             {
  955.             if(dribble!=NULL)
  956.                 fputc(buf[follow], dribble);
  957.             /* We only display if we're not too far behind; */
  958.             /* this makes dribble more reliable. */
  959.             if(((index-follow)>2048)||((follow-index)>6144))
  960.                 if(!orun)
  961.                     {
  962.                     orun=1;
  963.                     initdisp();
  964.                     }
  965.                 else;
  966.             else
  967.                 {
  968.                 orun=0;
  969.                 dispport(buf[follow]);
  970.                 }
  971.             follow++;
  972.             follow=follow%TBUFSIZ;
  973.             }
  974.         }
  975.     }
  976.