home *** CD-ROM | disk | FTP | other *** search
- /*-> c.io */
-
- /* Modifications for ANSI C under RISC-OS:
- *
- * Date Modification
- * 13-may-90 types header
- * 14-may-90 replace iabs() by abs()
- * 14-may-90 movmem() replaced by memmove()
- * 4-jun-90 removed GetKey() from Error() (ie no wait)
- *
- * compiler complains about non-use of x in NbStr(); cured by dummy assignment
- */
-
- #include "stdlib.h"
- #include "stdio.h"
- #include <math.h>
- #include "string.h"
-
- #include "types.h"
- #include "hp11.h"
- #include "ami_amiga.h"
- #include "ins.h"
- #include "io.h"
- #include "kbd.h"
- #include "codes.h"
- #include "prog_codes.h"
-
- #define MAXRUN 4 /* Length of time running is displayed */
-
- #define FOREVER for (;;)
-
- int comma;
-
- static char *stpich(char *p, int c) /* insert character c at front of string p
- */
- {
- memmove(p + 1, p, strlen(p) + 1);
- *p = c;
-
- return(p);
- }
-
- int GetKey() /* Read a key & wait for its release */
- {
- int key;
-
- key = PollKey(TRUE);
- RelKey();
-
- return(key);
- }
-
- enum KeyTypes ReadKey(code) /* Read a complete key sequence, & return
- its type, intrsuction or action. */
- register WORD *code;
- {
- register struct Key *curtkey;
- register int key, offset;
- register BOOL noKey; /* if an invalid sequence is returned, don't read a new
- key, reuse the one which caused the error. This is
- set to false when that happens */
- register enum KeyTypes ret;
-
- noKey = TRUE; /* no key read */
-
- FOREVER {
- offset = 0; /* f or g not pressed */
-
- FOREVER { /* This loop reads a key from the main, f or g shifted
- keyboards. Further refinements (eg sto) are done
- algorithmically, to save space */
- if (noKey) key = PollKey(TRUE); /* obtain next key */
- Dispf(FALSE); Dispg(FALSE);
- noKey = TRUE;
- if (key == 31) { /* f pressed, toggle its status */
- offset = (offset == NUMKEYS) ? 0 : (Dispf(TRUE), NUMKEYS);
- RelKey();
- }
- else if (key == 32) { /* g */
- offset = (offset == NUMKEYS + NUMKEYS) ? 0 : (Dispg(TRUE), NUMKEYS +
- NUMKEYS);
- RelKey();
- }
- else break; /* got a key, exit from loop */
- }
- if (User && key < 5) offset ^= NUMKEYS; /* Toggle f for first five keys.
- This doesn't affect g because
- the bit patterns are exclusive
- (42 & 84 = 0) */
- Dispf(FALSE); Dispg(FALSE);
-
- curtkey = mainKbd + offset + key; /* find address of (eventually shifted)
- key */
-
- switch (curtkey->Sort) {
- case Action:
- *code = curtkey->Act;
- return(Action);
- case Instruction:
- *code = curtkey->Code;
- return(Instruction);
- case Prefix: /* Key is a prefix, execute corresponding routine */
- RelKey();
- ret = (*(curtkey->Suffix))(code);
- if (ret != Invalid) return(ret); /* if successful */
-
- key = *code; /* else, invalid keycode returnedin code field for reuse */
- noKey = FALSE; /* a key is already available */
- break;
- case Invalid: /* An inavlid f or g sequence was entered, retry it with
- the f or g prefix stripped. Therefore all obtainable
- main keyboard sequences must exist, otherwise the
- program enters an infinite loop retrying constantly
- the same nonexistent keycode */
- key %= NUMKEYS;
- noKey = FALSE;
- break;
- }
- }
- }
-
- /* Return position n on the liquid cristal display in string t */
- int scrpos(t, n)
- char *t;
- register int n;
- {
- register char *s = t;
- register int pos;
-
- pos = 0;
- while (pos <= n && *s) { /* go on till end of string or beyond position n on
- display */
- if (*s != '.' && *s != ',') pos++; /* . & , take no space on the display
- */
- s++;
- }
- return((int)((s - t) - 1 - (pos - n))); /* pos - n is there to take care of
- the overshoot. If
- n is beyond the end of the string, the position returned may well be wildly
- beyond the
- actual end of the string */
- }
-
- /* Return the length taken up on the screen by the string */
- int scrlen(s)
- register char *s;
- {
- register int cnt = 0;
-
- while (*s) {
- if (*s != '.' && *s != ',') cnt++; /* . & , take no space on the display
- */
- s++;
- }
-
- return(cnt);
- }
-
- /* format string s in hp11 display format (without exponent) so that it takes
- n spaces in the display. s isn't modified */
- static char *CvtStd(char *s, int n)
- {
- static char buf[20];
- register char *p;
- register int i, nb;
- register int digit_separator = comma ? '.' : ','; /* separator according to
- current setting */
-
- strcpy(buf, s); /* copy string to safe work buffer */
-
- if ((p = strchr(buf, '.')) == NULL) { /* find position of . */
- p = buf + strlen(buf);
- if (!entering) *p = comma ? ',' : '.';
- *(p + 1) = '\0';
- }
- else if (comma) *p = ','; /* Replace . by , if necessary */
-
- while ((p -= 3) - buf > 1) /* Add , (or .) to string every 3 digits */
- stpich(p, digit_separator);
-
- nb = n - scrlen(buf);
- for (i = 1; i <= nb; i++) strcat(buf, " "); /* pad with spaces to required
- screen length */
- buf[scrpos(buf, n) + 1] = '\0'; /* cut at n characters */
-
- return(buf);
- }
-
- /* format string s in hp11 display format (with exponent) */
- static char *CvtExpo(char *s, char *e)
- {
- if (strlen(e) > 3) { /* deal with roundoff towards 1e100 when nb too big */
- e = " 99"; /* exponent is 99 */
- strncpy(s + 1, "9.999999999", strlen(s + 1)); /* mantissa is enough 9's
- */
- }
-
- return(strcat(CvtStd(s, 8), e));
- }
-
- /* convert x to scientific format with n digits. Returns it in a static buffer
- (from CvtStd) */
- static char *Scient(double x, int n)
- {
- char buf[20];
- register char *pe;
-
- sprintf(buf, "% .*E", n, x); /* Scientific format with n digits */
- pe = strchr(buf, 'E'); /* split string into mantissa & exponent */
- *pe++ = '\0';
- /* if (*pe == '+') *pe = ' '; A + is displayed as a space by the Display
- routine anyway */
-
- return(CvtExpo(buf, pe));
- }
-
- /* Convert x to fix n format */
- static char *Fixed(double x, int n)
- {
- char buf[80];
-
- sprintf(buf, "% .*f", n, x);
-
- return(CvtStd(buf, 11));
- }
-
- /* Eng n format */
- static char *Engin(double x, int n)
- {
- char expbuf[10], buf[80];
- register char *pe;
- double mantissa;
- register int exponent, dif;
-
- sprintf(buf, "%.*E", n, x); /* print enough digits */
- *(pe = strchr(buf, 'E')) = '\0';
- mantissa = atof(buf); /* get mantissa & exponent */
- exponent = atoi(pe + 1);
-
- /* Round exponent down to a multiple of 3 */
- dif = exponent % 3;
- if (dif < 0) dif += 3;
- exponent -= dif; /* calculate new exponent & mantissa */
- mantissa *= pow(10.0, (double)dif);
-
- /* Convert them to string */
- sprintf(buf, "% .*f", (n - dif > 0) ? n - dif : 0, mantissa);
- sprintf(expbuf, "%c%02d", (exponent < 0) ? '-' : ' ', abs(exponent)); /*
- pad exponent with 0's, hence %02d not %2d */
-
- return(CvtExpo(buf, expbuf));
- }
-
- /* Display current trig mode */
- static void DispAngle(void)
- {
- switch (Angles) {
- case grad:DispG(TRUE);
- case rad:DispRAD(TRUE);
- case deg:break;
- }
- }
-
- /* Display current x value in normal mode, running in run mode */
- void Disp()
- {
- static int runcnt = MAXRUN;
- static BOOL runon;
-
- if (running) { /* Flash running on and off every MAXRUN calls */
- if (fast) { /* Display Running only once in fast mode */
- if (!runon) {
- Display(" Running");
- runon = TRUE; /* Running displayed */
- }
- }
- else if (runcnt-- == 0) Display("");
- else if (runcnt <= -MAXRUN) {
- runcnt = MAXRUN;
- Display(" Running");
- }
- }
- else {
- runon = FALSE; /* Running not displayed */
- if (entering) /* Display number entry strings */
- if (expo) Display(CvtExpo(strx, expx)); /* with exponent */
- else Display(CvtStd(strx, 11));
- else
- Display(NbStr(X));
-
- DispAngle();
- if (User) DispUSER(TRUE);
- }
- }
-
- char *NbStr(x)
- double x;
- {
- x = x; /* avoids compiler warning */
- switch (Mode) { /* Display x according to display mode */
- case fix:if ((fabs(X) >= minfix / 2.0 || X == 0.0) && fabs(X) < 1E10) {
- /* Number can be displayed in fix mode */
- return(Fixed(X, Digits));
- }
- /* fall through for call to Scient */
- case sci:return(Scient(X, Digits));
- case eng:return(Engin(X, Digits));
- }
- }
-
- /* Display Error n, & wait for a key to be pressed */
- void Error(n)
- int n;
- {
- register char *buf;
-
- entering = FALSE; /* end of digit entry */
- error = TRUE; /* an error has occured */
- buf = " Error ";
- buf[8] = n; buf[9] ='\0';
-
- if (!running) RelKey();
- Display(buf);
- /* GetKey(); */
- }
-
- /* Display current program line */
- void DisplayLine()
- {
- register int c1 = keycodes[Prog[PC]].c1, c2 = keycodes[Prog[PC]].c2,
- c3 = keycodes[Prog[PC]].c3;
- char _buf[20], _insbuf[20];
- register char *buf = _buf, *insbuf = _insbuf;
- register int point = comma ? ',' : '.'; /* separator according to current
- setting */
-
- sprintf(buf, " %03d-", PC); /* prepare program line */
-
- /* Prepare instruction buffer */
- if (PC == 0) insbuf[0] = '\0'; /* nothing at line 0 */
- else switch (keycodes[Prog[PC]].Type) { /* there are 6 methods for
- displaying a line */
- case ONECODE: sprintf(insbuf, "%6d", c1); break; /* nn eg SIN or 9 */
- case TWOCODE: sprintf(insbuf, "%3d%3d", c1, c2); break; /* nn nn eg g
- LOG */
- case TWOCODE_9: sprintf(insbuf, "%4d%2d", c1, c2); break; /* nn n eg STO
- 5*/
- case TWOCODE_PT: sprintf(insbuf, "%4d %c%1d", c1, point, c2); break; /*
- nn .n eg RCL .6 */
- case THREECODE: sprintf(insbuf, "%2d,%2d,%2d", c1, c2, c3); break; /*
- nn,nn,nn eg f HYP SIN */
- case THREECODE_PT: sprintf(insbuf, "%2d,%2d, %c%1d", c1, c2, point, c3);
- break; /* nn,nn, .n eg STO + .0 */
- }
-
- Display(strcat(buf, insbuf));
-
- DispAngle();
- if (User) DispUSER(TRUE);
- }
-
-