home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 247_02 / ratcalc.c < prev    next >
Text File  |  1989-04-19  |  21KB  |  786 lines

  1. /*
  2.  *       MIRACL RATIONAL CALCULATOR - IBM-PC VERSION
  3.  *       Compiles with Turbo C V1.0 or Microsoft C V3.0+
  4.  *  **   Change display mode for 40/80 column operation (e.g. 'mode 40' to DOS)
  5.  *  **   Change colour/B&W below
  6.  */
  7.  
  8. #include <stdio.h>     /*** IBM-PC specific section ***/
  9. #include <dos.h>        
  10. #include "miracl.h"
  11.  
  12. #define ESC 27
  13. #define SPACE 32
  14. #define BELL 7
  15.  
  16. #define DVERT 186
  17. #define DHORZ 205
  18. #define DTLHC 201
  19. #define DTRHC 187
  20. #define DBLHC 200
  21. #define DBRHC 188
  22. #define VERT 179        
  23. #define HORZ 196
  24. #define TLHC 218
  25. #define TRHC 191
  26. #define BLHC 192
  27. #define BRHC 217
  28. #define LSIDE 199
  29. #define RSIDE 182
  30.  
  31. /* Globals */
  32. /* set colours          B/W       Colours (suggested) */
  33.  
  34. int ORDINARY=0x07; /*   0x07        0x17    blue-white        */
  35. int INVER   =0x70; /*   0x70        0x40    red-black         */
  36. int BOLD    =0x0F; /*   0x0F        0x70    white-black       */
  37. int BLINKING=0x87; /*   0x87        0xF4    white-red (blink) */
  38. int HELPCOL =0x07; /*   0x07        0x02    black-green       */
  39. int PRESSED =0x0F; /*   0x0F        0x4F    red-white (bold)  */
  40. int STATCOL =0x07; /*   0x07        0x74    white-red         */
  41. int BGROUND =0x07; /*   0x07        0x07    black-white       */
  42.  
  43. int dmode;
  44.  
  45.                 /*** Constants 16-bit values ***/
  46.  
  47. char cpi[] = "2646693125139304345/842468587426513207";
  48. char clg2[]= "28575556407596679551/41225813519882571900";
  49. char clg10[]="9948944967727459672/4320771900243161573";
  50.  
  51.                 /*** Device independent data ***/
  52.  
  53. extern big w15;
  54.  
  55. char *settings[4][4]= {"   ","HYP","","",
  56.                        "Be ","B2 ","B10","",
  57.                        "RAD","DEG","GRA","",
  58.                        "DEC","HEX","OCT","BIN"};
  59. int nops[]= {1,2,1,3};         /* number of options   */
  60. int opp[] = {0,1,1,2,2,3,3,2}; /* operator precedence */
  61.  
  62. char *keys[6][7]= {"SIN","COS","TAN","EXP","F-D","CLR","OFF",
  63.                    "ASN","ACS","ATN","LOG","SET","MOD","DEL",
  64.                    " 7 "," 8 "," 9 ","Y^X","X√Y"," ÷ "," RM",    /******/
  65.                    " 4 "," 5 "," 6 "," X²","²√X"," x "," M+",
  66.                    " 1 "," 2 "," 3 ","1/X"," π "," - ","+/-",
  67.                    " 0 "," / "," . "," ( "," ) "," + "," = "};
  68.  
  69. int qkeys[6][7]=  {'s','k','t','e','f','c','o',
  70.                    'S','K','T','l','g','%','<',
  71.                    '7','8','9','y','x','\\','r',
  72.                    '4','5','6','q','v','*','m',
  73.                    '1','2','3','i','p','-',';',
  74.                    '0','/','.','(',')','+','='};
  75.  
  76. char *htext[]=  {"Arrow keys find, space bar activates OR",
  77.                  "use numeric keys  (with  A-F  for hex),",
  78.                  "brackets,  and mnemonic keys as below: ",
  79.                  " FUNCTION      KEY   FUNCTION       KEY",
  80.                  "   SIN          s      ASN           S ",
  81.                  "   COS          k      ACS           K ",
  82.                  "   TAN          t      ATN           T ",
  83.                  "   EXP(e/2/10)  e      LOG(e/2/10)   l ",
  84.                  "   Y^X          y      X√Y           x ",   /******/
  85.                  "    X²          q      ²√X           v ",
  86.                  "   1/X          i       π            p ",
  87.                  "   F-D          f      SET           g ",
  88.                  "   MOD          %      CLR           c ",
  89.                  "    ÷      d or \\       x       b or * ",
  90.                  "    -           -       +       , or + ",
  91.                  "   OFF          o      DEL    DEL or < ",
  92.                  "    RM          r       M+           m ",
  93.                  "   +/-          ;       =     RET or = ",
  94.                  "Note: / means 'over'  as in fractions  ",
  95.                  "F-D converts  fraction  <-->  decimal  ",
  96.                  "SET changes settings - use arrow keys  ",
  97.                  "Alternative arrow keys -   u  h  j  n  ",
  98.                  "Report any problems to M.Scott |NIHED  ",
  99.                  "This program is Public Domain  |Dublin "};     /******/
  100.  
  101. char display[]=   "   MIRACL RATIONAL CALCULATOR V2.0   ";
  102. char  status[]=   "                                     ";
  103. char oldstat[]=   "                                     ";
  104.  
  105. int erptr=0;
  106. int mmptr=6;
  107. int exptr=10;
  108. int typtr=16;
  109. int stptr[]={22,26,30,34};
  110.  
  111. int dbeg=2;
  112. int dlen=37;
  113. int top=7;
  114. int width=80;      /* screen width can be 40 or 80 columns */
  115. char mybuff[40];
  116.  
  117. flash x,y[8],m,t;
  118. flash radeg,loge2,loge10;
  119. int ipt,op[8],prop[8],sp,brkt,lgbase;
  120. bool flag,newx,result,hyp,degrees,delim;
  121. int option[]={0,0,0,0};
  122.  
  123. /* Device specific code - IBM-PC versions */
  124.  
  125. void curser(x,y)
  126. int x,y;
  127. { /* position cursor at x,y */
  128.     union REGS regs;
  129.     regs.h.ah=2;
  130.     regs.h.dh=y-1;
  131.     regs.h.dl=x-1;
  132.     regs.h.bh=0;              /* Video page 0 */
  133.     int86(0x10,®s,®s);  /* Use Dos Interrupt 10h */
  134. }
  135.  
  136. void screen()
  137. { /* initialise screen */
  138.     union REGS regs;
  139.     regs.h.ah=0x0F;  /* get screen mode */
  140.     regs.h.al=0;
  141.     int86(0x10,®s,®s);
  142.     dmode=regs.h.al;
  143.     if ((dmode&2)!=0) width=80;
  144.     else                  width=40;
  145.     regs.h.ah=6;     /* clear screen */
  146.     regs.h.al=0;
  147.     regs.h.cl=0;
  148.     regs.h.ch=0;
  149.     regs.h.dl=width-1;
  150.     regs.h.dh=24;
  151.     regs.h.bh=BGROUND;
  152.     regs.h.bl=0;
  153.     int86(0x10,®s,®s);
  154. }
  155.  
  156. void restore()
  157. {  /* restore situation */
  158.     union REGS inregs,outregs;
  159.     inregs.h.ah=0;       /* reset initial display mode */
  160.     inregs.h.al=dmode;
  161.     int86(0x10,&inregs,&outregs);
  162. }
  163.  
  164. void apchar(attr,x,y,ch)
  165. int attr,x,y;
  166. char ch;
  167. { /* output character with attribute at x,y */
  168.     union REGS regs;
  169.     curser(x,y);
  170.     regs.h.ah=9;              /* output a character */
  171.     regs.h.al=ch;
  172.     regs.h.bh=0;
  173.     regs.h.bl=attr;
  174.     regs.h.cl=1;
  175.     regs.h.ch=0;
  176.     int86(0x10,®s,®s);
  177. }
  178.  
  179. void aprint(attr,x,y,text)
  180. int attr,x,y;
  181. char* text;
  182. { /* attribute print */
  183.     while (*text!='\0')
  184.     {
  185.         apchar(attr,x++,y,*text);
  186.         text++;
  187.     }
  188. }
  189.  
  190. void lclr(x,y)
  191. int x,y;
  192. { /* clear from x,y to end of line */
  193.     aprint(BGROUND,x,y,"                                       ");
  194. }
  195.  
  196. void cset(k)
  197. int k;
  198. { /* select special character set */
  199.     return;
  200. }
  201.  
  202. int gethit()
  203. { /* get single keystroke */
  204.     int ch;
  205.     ch=getch();
  206.     if (ch!=0) return ch;
  207.     ch=getch();
  208.     if (ch==72) return 'u';  /* transform some useful extended codes */
  209.     if (ch==75) return 'h';
  210.     if (ch==77) return 'j';
  211.     if (ch==80) return 'n';
  212.     if (ch==83) return 127;
  213.     return 0;
  214. }
  215.  
  216. /*** Device independent code ***/
  217.  
  218. int arrow(c)
  219. int c;
  220. { /* check for arrow key             *
  221.    * returns 1 for up, 2 for down,   *
  222.    * 3 for right, 4 for left, else 0 */
  223.     if (c=='u') return 1;
  224.     if (c=='n') return 2;
  225.     if (c=='j') return 3;
  226.     if (c=='h') return 4;
  227.     return 0;
  228. }
  229.  
  230. void instat(ptr,strg)
  231. int ptr;
  232. char *strg;
  233. { /* insert a status setting into status line */
  234.     strncpy(&status[ptr],strg,strlen(strg));
  235. }
  236.  
  237. void getstat()
  238. { /* set status line */
  239.     int i;
  240.     if (ERNUM) instat(erptr,"ERROR");
  241.     else       instat(erptr,"     ");
  242.     if (EXACT) instat(exptr,"EXACT");
  243.     else       instat(exptr,"     ");
  244.     if (size(m)!=0) instat(mmptr,"MEM");
  245.     else            instat(mmptr,"   ");
  246.     if (POINT) instat(typtr,"POINT");
  247.     else       instat(typtr,"FRACT");
  248.     for (i=0;i<4;i++)
  249.          instat(stptr[i],settings[i][option[i]]);
  250. }
  251.  
  252. void setopts()
  253. { /* set options */
  254.     if (option[0]==0) hyp=FALSE;
  255.     else              hyp=TRUE;
  256.     lgbase=0;
  257.     if (option[1]==1) lgbase=2;
  258.     if (option[1]==2) lgbase=10;
  259.     if (option[2]==0) degrees=FALSE;
  260.     else              degrees=TRUE;
  261.     IOBASE=10;
  262.     if (option[3]==1) IOBASE=16;
  263.     if (option[3]==2) IOBASE=8;
  264.     if (option[3]==3) IOBASE=2;
  265.  
  266. void show(force)
  267. bool force;
  268. { /* output display */
  269.     if (force || strcmp(oldstat,status)!=0)
  270.     {
  271.         if (ERNUM) aprint(BLINKING,2,2,status);
  272.         else       aprint(STATCOL,2,2,status);
  273.         strcpy(oldstat,status);
  274.     }
  275.     aprint(BOLD,dbeg,3,display);
  276. }
  277.  
  278. void clr()
  279. { /* clear input buffer */
  280.     mybuff[0]='0';
  281.     mybuff[1]='\0';
  282.     ipt=0;
  283.     delim=FALSE;
  284. }
  285.  
  286. void just(buff)
  287. char buff[];
  288. { /* justify buff into display (if possible) *
  289.    * and update status                       */
  290.     int i,mp,df;
  291.     bool dot;
  292.     dot=FALSE;
  293.     mp=0;
  294.     while (mp<=dlen && buff[mp]!='\0')
  295.     {
  296.         if (buff[mp]=='.') dot=TRUE;
  297.         if (mp==dlen && !dot) ERNUM=(-1);
  298.         mp++;
  299.     }
  300.     if (mp>dlen) mp=dlen;
  301.     if (!ERNUM)
  302.     {
  303.         df=dlen-mp;
  304.         for (i=0;i<df;i++) display[i]=' ';
  305.         for (i=0;i<mp;i++) display[df+i]=buff[i];
  306.     }
  307.     display[dlen]='\0';
  308. }
  309.  
  310. void drawit()
  311. { /* Draw calculator */
  312.     int i,j;
  313.     char line[40],tline[40],bline[40];
  314.     cset(1);
  315.     line[0]=DTLHC;
  316.     for (i=1;i<38;i++) line[i]=DHORZ;
  317.     line[38]=DTRHC;
  318.     line[39]='\0';
  319.     aprint(ORDINARY,1,1,line);
  320.     for (i=1;i<22;i++) apchar(ORDINARY,1,1+i,DVERT); 
  321.     line[0]=DBLHC;
  322.     line[38]=DBRHC;
  323.     aprint(ORDINARY,1,23,line);
  324.     for (i=1;i<22;i++) apchar(ORDINARY,39,1+i,DVERT);
  325.     line[0]=LSIDE;  /* draw in the bar */
  326.     for (i=1;i<38;i++) line[i]=HORZ;
  327.     line[38]=RSIDE;
  328.     aprint(ORDINARY,1,4,line);
  329.     line[0]=tline[0]=bline[0]=SPACE;
  330.     line[36]=tline[36]=bline[36]=SPACE;
  331.     line[37]=tline[37]=bline[37]='\0';
  332.     for (i=1;i<36;i++)
  333.     {
  334.         switch (i%5)
  335.         {
  336.         case 1 : tline[i]=TLHC;
  337.                  bline[i]=BLHC;
  338.                  line[i]=VERT;
  339.                  break;
  340.         default: tline[i]=HORZ;
  341.                  bline[i]=HORZ;
  342.                  line[i]=SPACE;
  343.                  break;
  344.         case 0 : tline[i]=TRHC;
  345.                  bline[i]=BRHC;
  346.                  line[i]=VERT;
  347.                  break;
  348.         }
  349.     } 
  350.     for (j=0;j<6;j++)
  351.     {
  352.         aprint(ORDINARY,2,5+3*j,tline);
  353.         aprint(ORDINARY,2,6+3*j,line);
  354.         aprint(ORDINARY,2,7+3*j,bline);
  355.     }
  356.     cset(0);
  357.     for (j=0;j<6;j++)
  358.         for (i=0;i<7;i++)
  359.             aprint(ORDINARY,4+5*i,6+3*j,keys[j][i]);
  360.     aprint(HELPCOL,2,24,"Type 'H' for help on/off, 'O' to exit");
  361.     cotnum(x,stdout);
  362.     just(OBUFF);
  363.     getstat();
  364.     show(TRUE);
  365. }
  366.  
  367. bool next(ch)
  368. int ch;
  369. { /* get next digit - returns FALSE if there is a problem  */
  370.     int cv;
  371.     result=FALSE;
  372.     if (ipt>=dlen) return FALSE;
  373.     if (ch=='/' || ch=='.')
  374.     {
  375.         if (delim || (ch=='/' && ipt==0)) return FALSE;
  376.         delim=TRUE;
  377.     }
  378.     else
  379.     {
  380.         if (ch>='A' && ch<='F') cv=10+(ch-'A');
  381.         else                    cv=ch-'0';
  382.         if (IOBASE<=cv) return FALSE;
  383.     }
  384.     if (ipt==0 && ch=='0') clr();
  385.     else
  386.     {
  387.         mybuff[ipt++]=ch;
  388.         mybuff[ipt]='\0';
  389.     }
  390.     just(mybuff);
  391.     strcpy(IBUFF,mybuff);
  392.     cinnum(x,stdin);
  393.     newx=TRUE;
  394.     return TRUE;
  395. }
  396.  
  397. void swap()
  398. { /* swap x with top of stack */
  399.     flash t;
  400.     t=x;
  401.     x=y[sp];
  402.     y[sp]=t;
  403. }
  404.  
  405. int prec(no)
  406. int no;
  407. { /* return new operator precedence */
  408.     return 4*brkt+opp[no];
  409. }
  410.  
  411. void equals(no)
  412. int no;
  413. { /* perform binary operation */
  414.     bool pop;
  415.     newx=FALSE;
  416.     pop=TRUE;
  417.     while (pop)
  418.     {
  419.         if (prec(no)>prop[sp])
  420.         { /* if higher precedence, keep this one pending */
  421.             if (sp==top)
  422.             {
  423.                 ERNUM=(-1);
  424.                 result=FALSE;
  425.                 newx=TRUE;
  426.             }
  427.             else sp++;
  428.             return;
  429.         }
  430.         newx=TRUE;
  431.         if (flag && op[sp]!=3 && op[sp]!=0) swap();
  432.         switch (op[sp])
  433.         {
  434.         case 7: fdiv(x,y[sp],t);
  435.                 ftrunc(t,t,t);
  436.                 fmul(t,y[sp],t);
  437.                 fsub(x,t,x);
  438.                 break;
  439.         case 6: fpowf(x,y[sp],x);
  440.                 break;
  441.         case 5: frecip(y[sp],t);
  442.                 fpowf(x,t,x);
  443.                 break;
  444.         case 4: fdiv(x,y[sp],x);
  445.                 break;
  446.         case 3: fmul(x,y[sp],x);
  447.                 break;
  448.         case 2: fsub(x,y[sp],x);
  449.                 break;
  450.         case 1: fadd(x,y[sp],x);
  451.                 break;
  452.         case 0: break;
  453.         }
  454.         if (sp>0 && (prec(no)<=prop[sp-1])) sp--;
  455.         else pop=FALSE;
  456.     }
  457. }
  458.  
  459. void chekit(no)
  460. int no;
  461. { /* deal with operator */
  462.     if (flag && newx) equals(no);
  463.     else newx=FALSE;
  464.     flag=ON;
  465.     copy(x,y[sp]);
  466.     op[sp]=no;
  467.     prop[sp]=prec(no);
  468. }
  469.  
  470. void clrall()
  471. { /* clear all */
  472.     ERNUM=0;
  473.     zero(x);
  474.     zero(y[0]);
  475.     zero(m);
  476.     sp=0;
  477.     op[sp]=0;
  478.     prop[sp]=0;
  479.     brkt=0;
  480.     POINT=ON;
  481.     EXACT=TRUE;
  482. }
  483.  
  484. bool act(p,q)
  485. int p,q;
  486. { /* act on selected key */
  487.     int k,n,c;
  488.     aprint(PRESSED,4+5*p,6+3*q,keys[q][p]);
  489.     switch(p+7*q)
  490.     {
  491.     case 0:  if (degrees) fmul(x,radeg,x);
  492.              if (hyp) fsinh(x,x);
  493.              else     fsin(x,x);
  494.              newx=TRUE;
  495.              break;
  496.     case 1:  if (degrees) fmul(x,radeg,x);
  497.              if (hyp) fcosh(x,x);
  498.              else     fcos(x,x);
  499.              newx=TRUE;
  500.              break;
  501.     case 2:  if (degrees) fmul(x,radeg,x);
  502.              if (hyp) ftanh(x,x);
  503.              else     ftan(x,x);
  504.              newx=TRUE;
  505.              break;
  506.     case 3:  if (lgbase>0)
  507.              {
  508.                  n=size(x);
  509.                  if (abs(n)<TOOBIG)
  510.                  {
  511.                      convert(lgbase,x);
  512.                      if (n<0) frecip(x,x);
  513.                      fpower(x,abs(n),x);
  514.                      newx=TRUE;
  515.                      break;
  516.                  }
  517.                  if (lgbase==2)  fmul(x,loge2,x);
  518.                  if (lgbase==10) fmul(x,loge10,x);
  519.              }
  520.              fexp(x,x);
  521.              newx=TRUE;
  522.              break;
  523.     case 4:  POINT=!POINT;
  524.              newx=TRUE;
  525.              break;
  526.     case 5:  clrall();
  527.              newx=TRUE;
  528.              break;
  529.     case 6:  return TRUE;
  530.     case 7:  if (hyp) fasinh(x,x);
  531.              else     fasin(x,x);
  532.              if (degrees) fdiv(x,radeg,x);
  533.              newx=TRUE;
  534.              break;
  535.     case 8:  if (hyp) facosh(x,x);
  536.              else     facos(x,x);
  537.              if (degrees) fdiv(x,radeg,x);
  538.              newx=TRUE;
  539.              break;
  540.     case 9:  if (hyp) fatanh(x,x);
  541.              else     fatan(x,x);
  542.              if (degrees) fdiv(x,radeg,x);
  543.              newx=TRUE;
  544.              break;
  545.     case 10: flog(x,x);
  546.              if (lgbase==2)  fdiv(x,loge2,x);
  547.              if (lgbase==10) fdiv(x,loge10,x);
  548.              newx=TRUE;
  549.              break;
  550.     case 11: newx=TRUE;
  551.              k=3;
  552.              forever
  553.              {
  554.                  aprint(INVER,2+stptr[k],2,settings[k][option[k]]);
  555.                  curser(2+stptr[k],2);
  556.                  c=arrow(gethit());
  557.                  if (c==1)
  558.                  {
  559.                      if (option[k]==nops[k]) option[k]=0;
  560.                      else option[k]+=1;
  561.                      continue;
  562.                  }
  563.                  aprint(STATCOL,2+stptr[k],2,settings[k][option[k]]);
  564.                  if (c==0 || c==2) break;
  565.                  if (c==4 && k>0) k--;
  566.                  if (c==3 && k<3) k++;
  567.              }
  568.              setopts();
  569.              break;
  570.     case 12: chekit(7);
  571.              break;
  572.     case 13: result=FALSE;
  573.              if (ipt==0) break;
  574.              ipt--;
  575.              mybuff[ipt]='\0';
  576.              if (ipt==0) clr();
  577.              just(mybuff);
  578.              strcpy(IBUFF,mybuff);
  579.              cinnum(x,stdin);
  580.              newx=TRUE;
  581.              break;
  582.     case 14: if (!next('7')) putchar(BELL);
  583.              break;
  584.     case 15: if (!next('8')) putchar(BELL);
  585.              break;
  586.     case 16: if (!next('9')) putchar(BELL);
  587.              break;
  588.     case 17: chekit(6);
  589.              break;
  590.     case 18: chekit(5);
  591.              break;
  592.     case 19: chekit(4);
  593.              break;
  594.     case 20: copy(m,x);
  595.              newx=TRUE;
  596.              break;
  597.     case 21: if (!next('4')) putchar(BELL);
  598.              break;
  599.     case 22: if (!next('5')) putchar(BELL);
  600.              break;
  601.     case 23: if (!next('6')) putchar(BELL);
  602.              break;
  603.     case 24: fmul(x,x,x);
  604.              newx=TRUE;
  605.              break;
  606.     case 25: froot(x,2,x);
  607.              newx=TRUE;
  608.              break;
  609.     case 26: chekit(3);
  610.              break;
  611.     case 27: brkt=0;
  612.              chekit(0);
  613.              flag=OFF;
  614.              fadd(m,x,m);
  615.              newx=TRUE;
  616.              break;
  617.     case 28: if (!next('1')) putchar(BELL);
  618.              break;
  619.     case 29: if (!next('2')) putchar(BELL);
  620.              break;
  621.     case 30: if (!next('3')) putchar(BELL);
  622.              break;
  623.     case 31: frecip(x,x);
  624.              newx=TRUE;
  625.              break;
  626.     case 32: fpi(x);
  627.              newx=TRUE;
  628.              break;
  629.     case 33: chekit(2);
  630.              break;
  631.     case 34: negate(x,x);
  632.              newx=TRUE;
  633.              break;
  634.     case 35: if (!next('0')) putchar(BELL);
  635.              break;
  636.     case 36: if (!next('/')) putchar(BELL);
  637.              break;
  638.     case 37: if (!next('.')) putchar(BELL);
  639.              break;
  640.     case 38: if (ipt>0)
  641.              {
  642.                  putchar(BELL);
  643.                  result=FALSE;
  644.              }
  645.              else
  646.              {
  647.                  zero(x);
  648.                  brkt+=1;
  649.                  newx=TRUE;
  650.              }
  651.              break;
  652.     case 39: if (brkt>0)
  653.              {
  654.                  chekit(0);
  655.                  brkt-=1;
  656.              }
  657.              else
  658.              {
  659.                  putchar(BELL);
  660.                  result=FALSE;
  661.              }
  662.              break;
  663.     case 40: chekit(1);
  664.              break;
  665.     case 41: brkt=0;
  666.              equals(0);
  667.              flag=OFF;
  668.              break;
  669.     }
  670.     return FALSE;
  671. }
  672.  
  673. main()
  674. { /*  MIRACL rational calculator */
  675.     int i,j,k,p,q,c,hpos;
  676.     bool over,help;
  677.     screen();
  678.     mirsys(10,MAXBASE);     /*** 16-bit computer ***/
  679. /*  mirsys(6,MAXBASE);           32-bit computer ***/
  680.     x=mirvar(0);
  681.     for (i=0;i<=top;i++) y[i]=mirvar(0);
  682.     m=mirvar(0);
  683.     t=mirvar(0);
  684.     radeg=mirvar(0);
  685.     loge2=mirvar(0);
  686.     loge10=mirvar(0);
  687.     strcpy(IBUFF,cpi);      /* read in constants */
  688.     cinnum(w15,stdin);
  689.     fpmul(w15,1,180,radeg);
  690.     strcpy(IBUFF,clg2);
  691.     cinnum(loge2,stdin);
  692.     strcpy(IBUFF,clg10);
  693.     cinnum(loge10,stdin);
  694.     help=OFF;
  695.     ERCON=TRUE;
  696.     STROUT=TRUE;
  697.     show(TRUE);
  698.     p=6;
  699.     q=0;
  700.     flag=OFF;
  701.     newx=OFF;
  702.     over=FALSE;
  703.     setopts();
  704.     clrall();
  705.     drawit();
  706.     while (!over)
  707.     { /* main loop */
  708.         if (ERNUM)
  709.         {
  710.             aprint(ORDINARY,4+5*p,6+3*q,keys[q][p]);
  711.             p=5,q=0;
  712.         }
  713.         if (width==80 || !help)
  714.         {
  715.             aprint(INVER,4+5*p,6+3*q,keys[q][p]);
  716.             curser(1,24);
  717.             c=gethit();
  718.             aprint(ORDINARY,4+5*p,6+3*q,keys[q][p]);
  719.         }
  720.         else while ((c=gethit())!='H');
  721.         result=TRUE;
  722.         if ((k=arrow(c))!=0)
  723.         { /* arrow key hit */
  724.             if (k==1 && q>0) q--;
  725.             if (k==2 && q<5) q++;
  726.             if (k==3 && p<6) p++;
  727.             if (k==4 && p>0) p--;
  728.             continue;
  729.         }
  730.         if (c=='H')
  731.         { /* switch help on/off */
  732.             help=!help;
  733.             for (i=1;i<=24;i++)
  734.             {
  735.                 if (width==80) hpos=41;
  736.                 else           hpos=1;
  737.                 if (help) aprint(HELPCOL,hpos,i,htext[i-1]);
  738.                 else lclr(hpos,i);
  739.             }
  740.             if (width==40 && !help) drawit();
  741.             continue;
  742.         }            
  743.         if (c>='A' && c<='F')
  744.         { /* hex only */
  745.             if (!next(c)) putchar(BELL);
  746.             else show(FALSE);
  747.             continue;
  748.         }
  749.         for (j=0;j<6;j++)
  750.             for (i=0;i<7;i++)
  751.                 if (c==qkeys[j][i]) p=i,q=j,c=' ';
  752.         if (c==8 || c==127) p=6,q=1,c=' ';       /* aliases */
  753.         if (c==',' || c=='a') p=5,q=5,c=' ';
  754.         if (c=='O') p=6,q=0,c=' ';
  755.         if (c==13)  p=6,q=5,c=' ';
  756.         if (c=='[' || c=='{') p=3,q=5,c=' ';
  757.         if (c==']' || c=='}') p=4,q=5,c=' ';
  758.         if (c=='d') p=5,q=2,c=' ';
  759.         if (c=='b') p=5,q=3,c=' ';
  760.         if (c==' ') over=act(p,q);
  761.         else        continue;
  762.         if (result)
  763.         { /* output result to display */
  764.             cotnum(x,stdout);
  765.             just(OBUFF);
  766.             if (ERNUM<0)
  767.             { /* convert to radix and try again */
  768.                 ERNUM=0;
  769.                 POINT=ON;
  770.                 cotnum(x,stdout);
  771.                 putchar(BELL);
  772.                 just(OBUFF);
  773.             }
  774.             clr();
  775.         }
  776.         if (newx)
  777.         { /* update display */
  778.             getstat();
  779.             show(FALSE);
  780.         }
  781.     }
  782.     curser(1,24);
  783.     restore();
  784. }
  785.