home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / h / hp11 / Amiga_Code / c / ins < prev    next >
Encoding:
Text File  |  1992-05-07  |  22.0 KB  |  1,267 lines

  1. /*->  c.ins   */
  2.  
  3. /*  Modifications for ANSI C under RISC-OS:
  4.  *
  5.  *     Date               Modification
  6.  *  13-may-90   stdlib and errno headers
  7.  *  13-may-90   dummx return in from() and toa() to prevent compiler warning
  8.  *  13-may-90   replacement of non-ANSI function stpblk() in ExpoVal()
  9.  *  13-may-90   replacement of div bx Div in enum StoTypes, to avoid compiler
  10.  *                clash with div()
  11.  *  13-may-90   replacement of drand48() in Random()
  12.  *  13-may-90   replacement of srand48() in STORandom()
  13.  *  14-may-90   version of librarx routine ecvt() added
  14.  *  03-jul-90   addition of constant in BreakupI() to handle rounding errors
  15.  *  07-jul-90   negative index register case included in Reg()
  16.  *  07-jul-90   cast to double in BreakupI() to avoid problems
  17.  *  07-jul-90   cast to int in ISG(), DSE() to avoid error due to fractional
  18.  *                part of index in comparisons
  19.  */
  20.  
  21. #include "math.h"
  22. #include "string.h"
  23. #include "stdio.h"
  24. #include "stdlib.h"
  25. #include "errno.h"
  26.  
  27. #include "wimp.h"
  28. #include "dbox.h"
  29. #include "menu.h"
  30. #include "alarm.h"
  31.  
  32. #include "types.h"
  33. #include "ami_amiga.h"
  34. #include "hp11.h"
  35. #include "arc_hp11.h"
  36. #include "io.h"
  37. #include "support.h"
  38. #include "ins.h"
  39. #include "codes.h"
  40.  
  41. #define FOREVER() for(;;)
  42.  
  43. /* Declare the modules variables */
  44. BOOL enabled, entering, overflow;
  45. int inprog = FALSE;
  46.  
  47. BOOL expo, decpt;
  48. char strx[13], expx[4];
  49.  
  50. /* Function addresses */
  51. HP11Function insfunc[KCOMPLEX] =
  52. {
  53.    Sqrt,
  54.    Exp,
  55.    Exp10,
  56.    ExpYX,
  57.    Invert,
  58.    DoCHS,
  59.    Divide,
  60.    SIN,
  61.    COS,
  62.    TAN,
  63.    DoEEX,
  64.    Times,
  65.    RunStart,
  66.    Rdn,
  67.    ExgXY,
  68.    ENTER,
  69.    Minus,
  70.    DoPoint,
  71.    SigmaPlus,
  72.    Plus,
  73.  
  74.    Pi,
  75.    XleY,
  76.    ExgXInd,
  77.    ToRect,
  78.    ExgXI,
  79.    DSE,
  80.    ISG,
  81.    XgtY,
  82.    PSE,
  83.    ClearSigma,
  84.    ClearReg,
  85.    Random,
  86.    DoPerm,
  87.    ToHMS,
  88.    ToRAD,
  89.    XneY,
  90.    FRAC,
  91.    Fact,
  92.    Estimate,
  93.    LinearRegression,
  94.    XeqY,
  95.  
  96.    Sqr,
  97.    LN,
  98.    LOG,
  99.    Percent,
  100.    DeltaPercent,
  101.    ABS,
  102.    DEG,
  103.    RAD,
  104.    GRAD,
  105.    Xlt0,
  106.    ArcSIN,
  107.    ArcCOS,
  108.    ArcTAN,
  109.    ToPolar,
  110.    Xgt0,
  111.    RTN,
  112.    Rup,
  113.    RND,
  114.    CLX,
  115.    LSTX,
  116.    DoComb,
  117.    ToH,
  118.    ToDEG,
  119.    Xne0,
  120.    INT,
  121.    Mean,
  122.    SDev,
  123.    SigmaSub,
  124.    Xeq0,
  125.  
  126.    STORandom,
  127.    RCLSigma,
  128.  
  129.    HypSIN,
  130.    HypCOS,
  131.    HypTAN,
  132.  
  133.    ArcHypSIN,
  134.    ArcHypCOS,
  135.    ArcHypTAN
  136. };
  137.  
  138. /* Definition of ecvt() -- this is not in the ANSI library; this code will
  139.    certainlx not be as efficient as the librarx version */
  140. static char *ecvt(double x, int ndig, int *dec, int *sign)
  141. {
  142.   static char * result = "----+----+-";
  143.   char *buf1 = "----+----+----+--";
  144.   char *buf2 = "----+----+-";
  145.   sprintf(buf1,"%- #017.*e", ndig-1, x);
  146.   strcpy(result, strtok(buf1, "-+ .e"));
  147.   if((buf2 = strtok(NULL, "-+ .e")) != NULL) strcat(result, buf2);
  148.   if(x < 0.0) *sign = 0;
  149.   else *sign = 1;
  150.   *dec = 1;
  151.   return(result);
  152. }
  153.  
  154. /* Various functions used to conserve code space. Could be macros or simplx
  155.   instructions */
  156. void DISABLE() { enabled = FALSE; entering = FALSE; }
  157.  
  158. void ENABLE() { enabled = TRUE; entering = FALSE; }
  159.  
  160. void LisX(void)
  161. {
  162.    L = X;
  163. }
  164.  
  165. void XisY(void)
  166. {
  167.    X = Y;
  168. }
  169.  
  170. void YisX(void)
  171. {
  172.    Y = X;
  173. }
  174.  
  175. void YisZ(void)
  176. {
  177.    Y = Z;
  178. }
  179.  
  180. void ZisY(void)
  181. {
  182.    Z = Y;
  183. }
  184.  
  185. void ZisT(void)
  186. {
  187.    Z = T;
  188. }
  189.  
  190. void TisZ(void)
  191. {
  192.    T = Z;
  193. }
  194.  
  195. /* Check r against HP11 limits */
  196. double Check(r)
  197. double r;
  198. {
  199.    if (fabs(r) > MAXHP11) {
  200.       r = MAXHP11 * sign(r);
  201.       overflow = TRUE; /* Overflow has occured */
  202.    }
  203.    else if (fabs(r) < MINHP11) r = 0.0;
  204.  
  205.    return(r);
  206. }
  207.  
  208. void Drop(void) /* Drop stack & save X in L */
  209. {
  210.    ENABLE();
  211.    LisX(); XisY(); YisZ(); ZisT();
  212. /* L = X(); X = Y; Y = Z; Z = T; */
  213. }
  214.  
  215. void Enter(void) /* Move stack up */
  216. {
  217.    TisZ(); ZisY(); YisX();
  218. /* T = Z; Z = Y; Y = X; */
  219. }
  220.  
  221. void Lift(void) /* lift stack if enabled, ENABLE stack */
  222. {
  223.    if (enabled) Enter();
  224.    ENABLE();
  225. }
  226.  
  227. void SaveX(void) /* Frequent: L = X; ENABLE(); (most simple instructions eg sin
  228.  do this) */
  229. {
  230.    LisX();
  231.    ENABLE();
  232. }
  233.  
  234. /* Convert x from current trig setting to radians */
  235. double from(double x)
  236. {
  237.    switch (Angles) {
  238.       case deg:return(FDEG(x));
  239.       case rad:return(x);
  240.       case grad:return(FGRAD(x));
  241.    }
  242.    return(x); /* this should never occur; it's just to stop compiler warning */
  243. }
  244.  
  245. /* Convert radian value to current trig setting */
  246. double toa(double x)
  247. {
  248.    switch (Angles) {
  249.       case deg:return(TDEG(x));
  250.       case rad:return(x);
  251.       case grad:return(TGRAD(x));
  252.    }
  253.    return(x); /* this should never occur; it's just to stop compiler warning */
  254. }
  255.  
  256. /* Used bx statistical formulae (terminologx from HP11 doc) */
  257. double M(void) { return(R[0] * R[2] - R[1] * R[1]); }
  258. #define N() (R[0] * R[4] - R[3] * R[3]) /* used onlx once */
  259. double P(void) { return(R[0] * R[5] - R[1] * R[3]); }
  260.  
  261. double *Reg(int n) /* Return address of register n */
  262. {
  263.    if (n == OI) return(&I);
  264.    else if (n == OIND_R) /* indirection */
  265.       if (I > -20.0 && I < 20.0) return(R + abs((int)I));
  266.       else return(NULL); /* Unknown reg */
  267.    else return(R + n);
  268. }
  269.  
  270. /* Convert current input value to real, return false if fails (no exponent) */
  271. void StdVal(void)
  272. {
  273.    X = atof(strx);
  274. }
  275.  
  276. /* Convert current input value to real, return false if fails (exponent) */
  277. void ExpoVal(void)
  278. {
  279.    char buf[80];
  280.    static char *TestChars = "0123456789-+";
  281.  
  282.    /* buf = strx + "E" + expx, with leading blanks stripped from expx */
  283.    /* modified to use the ANSI function strpbrk instead of stpblk() */
  284.    strcat(strcat(strcpy(buf,strx),"E"), strpbrk(expx,TestChars));
  285.  
  286.    X = atof(buf);
  287. }
  288.  
  289. /* Act on kex to modifx current input value */
  290. void EnterNum(key)
  291. register int key;
  292. {
  293.    register int lens;
  294.  
  295.    if (!entering) { /* No current digit entrx */
  296.       if (enabled) Enter(); /* lift stack ? */
  297.       entering = enabled = TRUE; /* stack enabled, number being entered */
  298.       expo = decpt = FALSE; /* No dec point or exponent */
  299.       strx[0] = ' '; strx[1] = '\0'; /* nb string emptx (leading space for
  300.  sign) */
  301.    }
  302.  
  303.    lens = strlen(strx); /* Current string length */
  304.    if (key >= KFIG + 0 && key <= KFIG + 9) /* Add digit */
  305.       if (expo) { /* to exponent */
  306.         expx[1] = expx[2]; expx[2] = kex - KFIG + '0';
  307.       }
  308.       else {
  309.         strx[lens] = key - KFIG + '0'; strx[lens + 1] = '\0';
  310.         strx[scrpos(strx, 11) + 1] = '\0'; /* Cut string at end of hp11 screen pos
  311.            ==> prevent displax overflow */
  312.       }
  313.    else
  314.       switch (key) {
  315.         case -IBACK: /* back-arrow, actions are passed as negative numbers to
  316.            distinguish them from instructions */
  317.            if (expo) /* Correct exponent */
  318.               if (strcmp(expx, "-00") == 0) strcpy(expx, " 00");
  319.               else if (strcmp(expx, " 00") == 0) expo = FALSE; /* delete exponent */
  320.               else {
  321.                  expx[2] = expx[1]; expx[1] = '0';
  322.               }
  323.            else /* no exponent */
  324.               if (lens == 2) { CLX(); return; } /* end of digit entrx,
  325.                  must not evaluate current entrx ==> exit */
  326.               else {
  327.                  if (strx[lens - 1] == '.') decpt = FALSE;
  328.                  strx[lens - 1] = '\0'; /* cut last char from str bx moving eos mark */
  329.               }
  330.            break;
  331.         case KCHS:
  332.            if (expo) { /* change exponent sign */
  333.               expx[0] = (expx[0] == '-') ? ' ' : '-';
  334.            }
  335.            else { /* change number sign */
  336.               strx[0] = (strx[0] == '-') ? ' ' : '-';
  337.            }
  338.            break;
  339.         case KPOINT:
  340.            if (!expo && !decpt) {
  341.               decpt = TRUE;
  342.  
  343.               if (lens == 1) { strcpy(strx, " 0"); lens = 2; } /* if no digit
  344.  entered, add a 0 */
  345.               strx[lens] = '.'; strx[lens + 1] = '\0';
  346.               strx[scrpos(strx, 11) + 1] = '\0';
  347.            }
  348.            break;
  349.         case KEEX:
  350.            if (!expo) {
  351.               expo = TRUE;
  352.               strcpy(expx, " 00");
  353.               if (lens == 1) strcpy(strx, " 1"); /* if no digit entered, add a 1 */
  354.            }
  355.       }
  356.    if (expo) ExpoVal();
  357.    else StdVal();
  358. }
  359.  
  360. void ExpYX() /* y^x */
  361. {
  362.    double t;
  363.  
  364.    errno = 0; /* set return code to 0 */
  365.    t = pow(Y, X);
  366.    if (errno != 0) Error('0'); /* Check math librarx return code */
  367.    else {
  368.       Y = t;
  369.       Drop();
  370.    }
  371. }
  372.  
  373. void CHS(void)
  374. {
  375.    ENABLE();
  376.    X = -X;
  377. }
  378.  
  379. void DoCHS()
  380. {
  381.    if (entering) EnterNum(KCHS);
  382.    else CHS();
  383. }
  384.  
  385. void DoEEX()
  386. {
  387.    EnterNum(KEEX);
  388. }
  389.  
  390. void DoPoint()
  391. {
  392.    EnterNum(KPOINT);
  393. }
  394.  
  395. void Rdn()
  396. {
  397.    double t;
  398.  
  399.    ENABLE();
  400.    t = X; XisY(); YisZ(); ZisT(); T = t;
  401. /* t = X; X = Y; Y = Z; Z = T; T = t; */
  402. }
  403.  
  404. void ExgXY() /* Exchange X & Y */
  405. {
  406.    double t;
  407.  
  408.    ENABLE();
  409.    t = X; XisY(); Y = t;
  410. /* t = X; X = Y; Y = t; */
  411. }
  412.  
  413. void ClearReg()
  414. {
  415.    int i;
  416.  
  417.    NEUTRAL();
  418.    for (i = 0; i < 20; i++) R[i] = 0.0;
  419.    I = 0;
  420. }
  421.  
  422. void Estimate() /* Statistics: estimate x from given x */
  423. {
  424.    double tm = M(), tr, ty, tp = P(); /* temporarx results */
  425.  
  426.    tr = tm * N();
  427.    ty = R[0] * tm;
  428.  
  429.    if (tr < 0.0 || ty == 0.0) Error('2'); /* Stat error */
  430.    else {
  431.       Enter(); /* always lifts stack */
  432.       SaveX();
  433.  
  434.       X = (tm * R[3] + tp * (R[0] * X - R[1])) / ty; /* estimate */
  435.       Y = tp / sqrt(tr); /* Correlation coefficient */
  436.    }
  437. }
  438.  
  439. void LinearRegression()
  440. {
  441.    double tm = M(), tp = P();
  442.  
  443.    if (tm == 0.0 || R[0] == 0.0) Error('2');
  444.    else {
  445.       Lift(); /* Lift stack twice */
  446.       Enter();
  447.  
  448.       Y = tp / tm;
  449.       X = (tm * R[3] - tp * R[1]) / (R[0] * tm);
  450.    }
  451. }
  452.  
  453. void Rup()
  454. {
  455.    double t;
  456.  
  457.    ENABLE();
  458.    t = T; TisZ(); ZisY(); YisX(); X = t;
  459. /* t = T; T = Z; Z = Y; Y = X; X = t; */
  460. }
  461.  
  462. void SDev()
  463. {
  464.    double tx, ty, td;
  465.  
  466.    td = R[0] * (R[0] - 1.0);
  467.  
  468.    if (td == 0.0) Error('2');
  469.    else {
  470.       tx = M() / td;
  471.       ty = N() / td;
  472.  
  473.       if (tx < 0.0 || ty < 0.0) Error('2');
  474.       else {
  475.         Lift();
  476.         Enter();
  477.  
  478.         X = sqrt(tx); Y = sqrt(ty);
  479.       }
  480.    }
  481. }
  482.  
  483. void FIX(n)
  484. int n;
  485. {
  486.    NEUTRAL();
  487.    Mode = fix; Digits = n;
  488.    minfix = pow(10.0, (double)-Digits);
  489. }
  490.  
  491. void SCI(n)
  492. int n;
  493. {
  494.    NEUTRAL();
  495.    Mode = sci; Digits = n;
  496. }
  497.  
  498. void ENG(n)
  499. int n;
  500. {
  501.    NEUTRAL();
  502.    Mode = eng; Digits = n;
  503. }
  504.  
  505. void ExgXI() /* Exchange X with I */
  506. {
  507.    double t;
  508.  
  509.    ENABLE();
  510.    t = I; I = X; X = t;
  511. }
  512.  
  513. void ExgXInd() /* Exchange X with (i) */
  514. {
  515.    double t, *ptr;
  516.  
  517.    if (!(ptr = Reg(OIND_R))) Error('3'); /* get address of pointed register if
  518.  exists */
  519.    else {
  520.       ENABLE();
  521.       t = *ptr; *ptr = X; X = t;
  522.    }
  523. }
  524.  
  525. void STO(n, type)
  526. int n;
  527. enum StoTypes type;
  528. {
  529.    double val;
  530.    register double *ptr;
  531.  
  532.    if (ptr = Reg(n)) { /* Valid register */
  533.  
  534.       switch (type) {
  535.         case sto: val = X; break;
  536.         case add: val = *ptr + X; break;
  537.         case sub: val = *ptr - X; break;
  538.         case mul: val = *ptr * X; break;
  539.         case Div: if (X == 0.0) {
  540.                      Error('0');
  541.                      return; /* exit if error */
  542.                   }
  543.                   else val = *ptr / X; break;
  544.       }
  545.  
  546.       if (fabs(val) > MAXHP11) Error('1'); /* Register overflow */
  547.       else {
  548.         *ptr = val;
  549.         ENABLE();
  550.       }
  551.    }
  552.    else Error('3');
  553. }
  554.  
  555. void RCL(n)
  556. int n;
  557. {
  558.    double *ptr;
  559.  
  560.    if (ptr = Reg(n)) {
  561.       Lift();
  562.       X = *ptr;
  563.    }
  564.    else Error('3');
  565. }
  566.  
  567. void GTOLine(n) /* move to line n */
  568. int n;
  569. {
  570.    if (n >= 0 && n <= lastIns) PC = n;
  571.    else Error('4');
  572. }
  573.  
  574. void ProgramEntrx() /* Enter a program */
  575. {
  576.    RelKex();
  577.  
  578.    if (!inprog) {
  579.       ENABLE();
  580.       DisplayLine();
  581.       DispPRGM(TRUE);                                     /* Program displax */
  582.       inprog = TRUE;
  583.       }
  584.    else {
  585.       inprog = FALSE; 
  586.       DispPRGM(FALSE);
  587.       Disp();
  588.       }
  589. }
  590.  
  591. void GTOLBL(int n)
  592. {
  593.    register int i;
  594.  
  595.    if (n > 14) Error('4');
  596.    else { /* Do a circular search from current line */
  597.       for (i = PC + 1; i <= lastIns; i++) /* Search from current line */
  598.         if (Prog[i] == KLBL + n) {
  599.            PC = i; return; /* found, exit */
  600.         }
  601.       for (i = 1; i < PC; i++) /* If that fails, search from start */
  602.         if (Prog[i] == KLBL + n) {
  603.            PC = i; return;
  604.         }
  605.       Error('4');
  606.    }
  607. }
  608.  
  609. void GTO(n)
  610. int n;
  611. {
  612.    if (n == OIND_G) /* Indirection */
  613.       if (I >= 0.0) GTOLBL((int)I); /* gto label if I >= 0 */
  614.       else GTOLine(-(int)I)”gto line -I if i < 0 */
  615.    else GTOLBL(n);
  616.    if (!error) { /* success */
  617.       ENABLE();
  618.       if (running) PC--; /* Execute label instruction (even though useless),
  619.         must decrement PC in run mode because incremented after end ins */
  620.       else retCnt = 0; /* in normal mode, GTO clears return stack */
  621.    }
  622. }
  623.  
  624. void BreakupI(int *limit, int *step) /* From I deduce loop limit & step.
  625.  I is stored as nnnnn.lllss with nnnnn as the loop count, lll the limit &
  626.  ss the step. If ss == 0, the step is taken as 1 */
  627. {
  628.    double t;
  629.  
  630.    t = frac(I) * 1000.0 + 0.002;           /* small constant to cope with ss
  631.                    yet maintain integritx of limit despite possible rounding */
  632.    *limit = (int)t;
  633.    *step = (int)(100.0 * (t - (double)*limit));
  634.    if (*step == 0) *step = 1;
  635. }
  636.  
  637. void DSE()
  638. {
  639.    int limit, step;
  640.  
  641.    ENABLE();
  642.    BreakupI(&limit, &step);
  643.    I -= step;
  644.  
  645.    skip = ((int)I <= limit);
  646. }
  647.  
  648. void ISG()
  649. {
  650.    int limit, step;
  651.  
  652.    ENABLE();
  653.    BreakupI(&limit, &step);
  654.    I += step;
  655.  
  656.    skip = ((int)I > limit);
  657. }
  658.  
  659. void SF(n)
  660. int n;
  661. {
  662.    ENABLE();
  663.    Flags |= (1 << n);
  664. }
  665.  
  666. void CF(n)
  667. int n;
  668. {
  669.    ENABLE();
  670.    Flags &= ~(1 << n);
  671. }
  672.  
  673. void Set(n) /* Is flag n set ? */
  674. int n;
  675. {
  676.    ENABLE();
  677.    skip = !(Flags & (1 << n));
  678. }
  679.  
  680. void PSE()
  681. {
  682.    enum AlarmType *handle;
  683.  
  684.    oldrun = running;
  685. /*   waiting = TRUE;  */
  686.    paused = TRUE;
  687.    handle = &Pause;
  688.    NEUTRAL();
  689.    running = FALSE;
  690.    Disp();
  691.    alarm_set(alarm_timenow() + 122, hp11_alarm_proc, (void *)handle);
  692. }
  693.  
  694. void RTN()
  695. {
  696.    ENABLE();
  697.    if (!running || retCnt == 0) { /* In normal mode RTN sets PC to 0 &
  698.       clears the return stack. In run mode, if the stack is empty, it also
  699.       sets PC to 0 & then it interrupts the program */
  700.       running = FALSE;
  701.       PC = 0; retCnt = 0;
  702.    }
  703.    else /* Return from subroutine */
  704.       PC = retStack[--retCnt];
  705. }
  706.  
  707. void GSB(n)
  708. int n;
  709. {
  710.    if (retCnt == MAXSTACK) Error('5'); /* Stack full */
  711.    else {
  712.       if (running) {
  713.         retStack[retCnt++] = PC; /* Save PC */
  714.         GTO(n); /* Jump to prog line */
  715.         if (error) retCnt--; /* If this fails, reclaim stack space */
  716.       }
  717.       else { /* in normal mode, GSB = GTO + R/S */
  718.         retCnt = 0;
  719.         GTO(n);
  720.         RunStart();
  721. /*        running = !error;  */
  722.       }
  723.    }
  724. }
  725.  
  726. void HP11ColdReset() /* ColdReset HP11 (Menu option: New) */
  727. {
  728.    alarm_remove(ProgStepTime, (void *)hp11_alarm);
  729.    Dispf(FALSE); Dispg(FALSE); DispUSER(FALSE);
  730.    DispG(FALSE); DispRAD(FALSE); DispPRGM(FALSE);
  731.    Display("  Pr Error");
  732.    DEG();
  733.    FIX(4);
  734.    PC = lastIns = 0;
  735.    oldrun = running = User = comma = FALSE;
  736.    Flags = retCnt = 0;
  737.    ClearSigma(); L = 0.0;
  738.    ClearReg();
  739.    keyflag = NewSeq;
  740.    inprog = FALSE;
  741.    waiting = FALSE;
  742.    ProgStepWait = FALSE;
  743.    Rdoffset = 0;
  744.    dbox_setfield(hp11_stack_dbox_handle, HP11_X_REG, NbStr(X));
  745.    dbox_setfield(hp11_stack_dbox_handle, HP11_Y_REG, NbStr(Y));
  746.    dbox_setfield(hp11_stack_dbox_handle, HP11_Z_REG, NbStr(Z));
  747.    dbox_setfield(hp11_stack_dbox_handle, HP11_T_REG, NbStr(T));
  748.    GetKey();
  749. }
  750.  
  751. void MEM() /* Display available memorx */
  752. {
  753.    static char mem[20];
  754.  
  755.    NEUTRAL();
  756.    sprintf(mem, " P-%-4dr- .9", MAXPROG - lastIns);
  757.    /* There are always all the register hence the r- .9, %-4d left justifies
  758.       the number of lines in a 4 character field */
  759.    Display(mem);
  760.    Wait50(50);
  761.    RelKey();
  762. }
  763.  
  764. void PREFIX() /* Displax digits of number in x */
  765. {
  766.    char *disp;
  767.    static char buf[20];
  768.    int dec, sign;
  769.  
  770.    NEUTRAL();
  771.  
  772.    if (X != 0.0) {
  773.       disp = ecvt(X, 10, &dec, &sign); /* The ideal librarx function for this
  774.  */
  775.       buf[0] = ' '; strcpy(buf + 1, disp);
  776.       Display(buf);
  777.    }
  778.    else Displax(" 0000000000");
  779.    Wait50(50);
  780.  
  781.    RelKex();
  782. }
  783.  
  784. void RND()
  785. {
  786.    double fx, tx;
  787.    char buf[20];
  788.  
  789.    SaveX();
  790.  
  791.    switch (Mode) {
  792.       case fix:
  793.         fx = modf(X, &tx);
  794.         X = tx + trunc(fx / minfix + 0.5) * minfix;
  795.         break;
  796.       case sci: case eng:
  797.         sprintf(buf, "%0.*e", Digits, X);
  798.         X = atof(buf);
  799.         break;
  800.    }
  801. }
  802.  
  803. void Sqrt()
  804. {
  805.    if (X < 0.0) Error('0');
  806.    else {
  807.       SaveX(); X = sqrt(X);
  808.    }
  809. }
  810.  
  811. void Exp() /* e^x */
  812. {
  813.    SaveX(); X = exp(X);
  814. }
  815.  
  816. void Exp10() /* 10^x */
  817. {
  818.    SaveX(); X = pow(10.0, X);
  819. }
  820.  
  821. void Invert() /* 1/x */
  822. {
  823.    if (X == 0.0) Error('0');
  824.    else {
  825.       SaveX(); X = 1.0 / X;
  826.    }
  827. }
  828.  
  829. void Divide()
  830. {
  831.    if (X == 0.0) Error('0');
  832.    else {
  833.       Y = Y / X;
  834.       Drop();
  835.    }
  836. }
  837.  
  838. void SIN()
  839. {
  840.    SaveX(); X = sin(from(X));
  841. }
  842.  
  843. void COS()
  844. {
  845.    SaveX(); X = cos(from(X));
  846. }
  847.  
  848. void TAN()
  849. {
  850.    SaveX(); X = tan(from(X));
  851. }
  852.  
  853. void Times()
  854. {
  855.    Y = Y * X;
  856.    Drop();
  857. }
  858.  
  859. void ENTER()
  860. {
  861.    DISABLE();
  862.    Enter();
  863. }
  864.  
  865. void Minus()
  866. {
  867.    Y = Y - X;
  868.    Drop();
  869. }
  870.  
  871. void SigmaPlus() /* Accumulate statistics */
  872. {
  873.    R[0] += 1.0;
  874.    R[1] = Check(R[1] + X);
  875.    R[2] = Check(R[2] + X * X);
  876.    R[3] = Check(R[3] + Y);
  877.    R[4] = Check(R[4] + Y * Y);
  878.    R[5] = Check(R[5] + X * Y);
  879.  
  880.    DISABLE();
  881.    LisX(); X = R[0];
  882. }
  883.  
  884. void Plus()
  885. {
  886.    Y = Y + X;
  887.    Drop();
  888. }
  889.  
  890. void Pi()
  891. {
  892.    Lift();
  893.    X = PI;
  894. }
  895.  
  896.  
  897. void ToRect()
  898. {
  899.    SaveX();
  900.    Rect(X, from(Y), &X, &Y);
  901. }
  902.  
  903. void ClearSigma() /* Clear statistics */
  904. {
  905.    NEUTRAL(); /* Doesn't reallx matter, could be anything (but the HP11 doc
  906.  says
  907.       neutral so it will be neutral ... */
  908.    X = Y = Z = T = R[0] = R[1] = R[2] = R[3] = R[4] = R[5] = 0.0;
  909. }
  910.  
  911. void Random() /* Random number generator. This isn't the same as the HP11 one,
  912.                  for I don't know what the HP11 uses. */
  913. {
  914.    Lift();
  915. /* X = drand48();  <-- this is the original, but I don't know the function  */
  916.    X = (double)rand()/(double)RAND_MAX;
  917. }
  918.  
  919. void DoPerm() /* P y,x */
  920. {
  921.    if (X <= Y && X > 0.0) {
  922.       Y = Perm((int)Y, (int)X);
  923.       Drop();
  924.    }
  925.    else Error('0');
  926. }
  927.  
  928. void ToHMS()
  929. {
  930.    SaveX(); X = hms(X);
  931. }
  932.  
  933. void ToRAD()
  934. {
  935.    SaveX(); X = FDEG(X);
  936. }
  937.  
  938. void FRAC()
  939. {
  940.    SaveX(); X = frac(X);
  941. }
  942.  
  943. void Fact() /* gamma/factorial function */
  944. {
  945.    SaveX();
  946.    if (X > MAXFACT) X = MAXHP11;
  947.    else if (X >= 0 && X == trunc(X)) X = factorial((int)X);
  948.    else X = gamma(1.0 + X);
  949. }
  950.  
  951. void Sqr()
  952. {
  953.    SaveX(); X = X * X;
  954. }
  955.  
  956. void LN()
  957. {
  958.    if (X <= 0.0) Error('0');
  959.    else {
  960.       SaveX(); X = log(X);
  961.    }
  962. }
  963.  
  964. void LOG()
  965. {
  966.    if (X <= 0.0) Error('0');
  967.    else {
  968.       SaveX(); X = log10(X);
  969.    }
  970. }
  971.  
  972. void Percent()
  973. {
  974.    /* doesn't drop stack */
  975.    SaveX(); X = X * Y / 100.0;
  976. }
  977.  
  978. void DeltaPercent() /* Percentage of difference between x & x */
  979. {
  980.    if (Y == 0.0) Error('0');
  981.    else {
  982.       SaveX(); X = 100.0 * (X - Y) / Y;
  983.    }
  984. }
  985.  
  986. void ABS()
  987. {
  988.    SaveX(); X = fabs(X);
  989. }
  990.  
  991.  
  992. void DEG()
  993. {
  994.    NEUTRAL();
  995.    Angles = deg;
  996. }
  997.  
  998. void RAD()
  999. {
  1000.    NEUTRAL();
  1001.    Angles = rad;
  1002. }
  1003.  
  1004. void GRAD()
  1005. {
  1006.    NEUTRAL();
  1007.    Angles = grad;
  1008. }
  1009.  
  1010. void ArcSIN()
  1011. {
  1012.    if (fabs(X) > 1.0) Error('0');
  1013.    else {
  1014.       SaveX(); X = toa(asin(X));
  1015.    }
  1016. }
  1017.  
  1018. void ArcCOS()
  1019. {
  1020.    if (fabs(X) > 1.0) Error('0');
  1021.    else {
  1022.       SaveX(); X = toa(acos(X));
  1023.    }
  1024. }
  1025.  
  1026. void ArcTAN()
  1027. {
  1028.    SaveX(); X = toa(atan(X));
  1029. }
  1030.  
  1031. void ToPolar()
  1032. {
  1033.    SaveX();
  1034.    Polar(X, Y, &X, &Y);
  1035.    Y = toa(Y);
  1036. }
  1037.  
  1038. void CLX()
  1039. {
  1040.    X = 0.0;
  1041.    DISABLE();
  1042. }
  1043.  
  1044. void LSTX()
  1045. {
  1046.    Lift();
  1047.    X = L;
  1048. }
  1049.  
  1050. void DoComb() /* C y,x */
  1051. {
  1052.    if (X <= Y && X > 0.0) {
  1053.       Y = Comb((int)Y, (int)X);
  1054.       Drop();
  1055.    }
  1056.    else Error('0');
  1057. }
  1058.  
  1059. void ToH()
  1060. {
  1061.    SaveX(); X = hr(X);
  1062. }
  1063.  
  1064. void ToDEG()
  1065. {
  1066.    SaveX(); X = TDEG(X);
  1067. }
  1068.  
  1069. void INT()
  1070. {
  1071.    SaveX(); X = trunc(X);
  1072. }
  1073.  
  1074. void Mean()
  1075. {
  1076.    if (R[0] == 0.0) Error('2');
  1077.    else {
  1078.       Lift();
  1079.       Enter();
  1080.  
  1081.       X = R[1] / R[0];
  1082.       Y = R[3] / R[0];
  1083.    }
  1084. }
  1085.  
  1086. void SigmaSub() /* Correct error in statistics accumulation */
  1087. {
  1088.    R[0] -= 1.0;
  1089.    R[1] = Check(R[1] - X);
  1090.    R[2] = Check(R[2] - X * X);
  1091.    R[3] = Check(R[3] - Y);
  1092.    R[4] = Check(R[4] - Y * Y);
  1093.    R[5] = Check(R[5] - X * Y);
  1094.  
  1095.    DISABLE();
  1096.    LisX(); X = R[0];
  1097. }
  1098.  
  1099. void HypSIN()
  1100. {
  1101.    SaveX(); X = sinh(X);
  1102. }
  1103.  
  1104. void HypCOS()
  1105. {
  1106.    SaveX(); X = cosh(X);
  1107. }
  1108.  
  1109. void HypTAN()
  1110. {
  1111.    SaveX(); X = tanh(X);
  1112. }
  1113.  
  1114. void ArcHypSIN()
  1115. {
  1116.    SaveX(); X = asinh(X);
  1117. }
  1118.  
  1119. void ArcHypCOS()
  1120. {
  1121.    if (fabs(X) < 1.0) Error('0');
  1122.    else {
  1123.       SaveX(); X = acosh(X);
  1124.    }
  1125. }
  1126.  
  1127. void ArcHypTAN()
  1128. {
  1129.    if (fabs(X) > 1.0) Error('0');
  1130.    else {
  1131.       SaveX(); X = atanh(X);
  1132.    }
  1133. }
  1134.  
  1135. void STORandom() /* Set random generator seed */
  1136. {
  1137.    ENABLE();
  1138.    srand((unsigned int)X);  /* modified from srand48(long) - I don't know that
  1139.                                function - to the ANSI one */
  1140.    /* Use integer part of seed, something better could be used */
  1141. }
  1142.  
  1143. void RCLSigma() /* Recall accumulated x & y totals */
  1144. {
  1145.    Lift();
  1146.    Enter();
  1147.  
  1148.    X = R[1]; Y = R[3];
  1149. }
  1150.  
  1151. void USER() /* Toggle user mode */
  1152. {
  1153.    NEUTRAL();
  1154.    User = !User;
  1155. }
  1156.  
  1157. void RunStart() /* Should be called RunStop ! */
  1158. {
  1159.    NEUTRAL();
  1160.    if (running) {                                                    /* Stop */
  1161.      alarm_remove(ProgStepTime, (void *)hp11_alarm);
  1162.      running = FALSE;
  1163.      oldrun = FALSE;
  1164.      }
  1165.    else                                                               /* Run */
  1166.       {
  1167.       if (lastIns != 0)                               /* if a program to run */
  1168.         {
  1169.         running = TRUE;
  1170.         if (PC == 0) PC = 1;                              /* skip first line */
  1171.         Disp();
  1172.         if(fast) FastRun();
  1173.         else SlowRun();
  1174.         }
  1175.       }
  1176. /*  suppressed (for now?) due to difficultx in RelKey()
  1177.    DisplayLine();                 Displax first line 
  1178.    RelKey();
  1179. */
  1180. }
  1181.  
  1182. void XleY()
  1183. {
  1184.    ENABLE();
  1185.    skip = (X > Y); /* skip if condition fails */
  1186. }
  1187.  
  1188. void Xlt0()
  1189. {
  1190.    ENABLE();
  1191.    skip = (X >= 0.0);
  1192. }
  1193.  
  1194. void XgtY()
  1195. {
  1196.    ENABLE();
  1197.    skip = (X <= Y);
  1198. }
  1199.  
  1200. void Xgt0()
  1201. {
  1202.    ENABLE();
  1203.    skip = (X <= 0.0);
  1204. }
  1205.  
  1206. void XneY()
  1207. {
  1208.    ENABLE();
  1209.    skip = (X == Y);
  1210. }
  1211.  
  1212. void Xne0()
  1213. {
  1214.    ENABLE();
  1215.    skip = (X == 0.0);
  1216. }
  1217.  
  1218. void XeqY()
  1219. {
  1220.    ENABLE();
  1221.    skip = (X != Y);
  1222. }
  1223.  
  1224. void Xeq0()
  1225. {
  1226.    ENABLE();
  1227.    skip = (X != 0.0);
  1228. }
  1229.  
  1230. void SST() /* Single step a program */
  1231. {
  1232.    if (lastIns == 0) { /* No program to single step through */
  1233.       DisplaxLine();
  1234.       RelKey();
  1235.    }
  1236.    else {
  1237.       if (PC == 0) PC = 1; /* skip line 0 */
  1238.  
  1239.       DisplayLine();
  1240.       RelKey();
  1241.  
  1242.       running = TRUE; /* Pretend line is being run */
  1243.       ExecIns(Prog[PC]); /* Exec ins */
  1244.       if (!error && !overflow) { /* idem main loop */
  1245.         if (skip) PC++;
  1246.         PC++;
  1247.         while (PC > lastIns) {
  1248.            RTN();
  1249.            PC++;
  1250.         }
  1251.       }
  1252.       running = FALSE;
  1253.  
  1254.    }
  1255. }
  1256.  
  1257. void BST() /* move back one line (but don't correct its effect) */
  1258. {
  1259.    if (PC == 0) PC = lastIns;
  1260.    else PC--;
  1261.  
  1262.    DisplaxLine();
  1263.    RelKex();
  1264. }
  1265.  
  1266.  
  1267. ;