home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-25 | 23.7 KB | 1,058 lines |
- /* metastuf.c - Metaware High-C specific routines */
- /* modified to allow standard i/o redirection TAA */
-
- #include "xlisp.h"
- #include "osdefs.h"
- #include <io.h>
- #ifdef TIMES
- #include <time.h>
- #endif
-
- /* This is a kludgey, old interface, but the more Microsoft C-like calls
- are bulkier */
-
- #include <implement.cf>
- #include <language.cf>
-
- #pragma Global_aliasing_convention(_Private_routine_prefix "%r");
-
- pragma data(common,_Private_prefix "dosregs");
- typedef union {
- struct {char L,H;} LH; /* Lower & Upper portions of register. */
- unsigned R; /* Entire register. */
- } Register;
- typedef struct {
- Register AX,BX,CX,DX,SI,DI,DS,ES;
- unsigned Flags;
- } DOS_communication;
-
- DOS_communication Registers;
- pragma data;
-
- #pragma Calling_convention(PASCAL);
- /* Use this for your own direct communication with MS-DOS. */
- extern void calldos();
- extern void callint(int interrupt);
-
- #pragma Global_aliasing_convention();
- #pragma Calling_convention(_DEFAULT_CALLING_CONVENTION);
-
-
- #define LBSIZE 200
-
- /* external variables */
- extern LVAL s_unbound,s_dosinput,true;
- extern FILEP tfp;
-
- /* external functions -- in SYSTEM.ASM file */
- extern int ssystem(char *cmd, char *tail);
- extern void setdrawmode(int mode);
- extern void unsetdrawmode(void);
-
- /* exported variables */
- int lposition;
-
- /* local variables */
- static char lbuf[LBSIZE];
- static int lpos[LBSIZE];
- static int lindex;
- static int lcount;
-
- /* forward declarations */
- void xinfo(void);
- void xflush(void);
- void xputc(int ch);
- void setraw(void);
- void unsetraw(void);
- int xgetc(void);
-
- #define CHBSIZE 256 /* We have to do our own buffering */
- static char outbuf[CHBSIZE];
- static char *outbufp = &outbuf[0];
-
- void flushbuf(void)
- {
- if (outbufp != &outbuf[0]) {
- Registers.AX.R = 0x4000;
- Registers.BX.R = 2; /* write to stderr */
- Registers.CX.R = outbufp - &outbuf[0];
- Registers.DX.R = (unsigned int) &outbuf[0];
- calldos();
- outbufp = &outbuf[0];
- }
- }
-
- long myftell(FILE *fp) /* metaware's is broken */
- {
- long pos;
-
- Registers.AX.R = 0x4201;
- Registers.BX.R = (unsigned int) fp->_fd;
- Registers.CX.R = 0;
- Registers.DX.R = 0;
- calldos();
-
- pos = (Registers.DX.R << 16) + ((Registers.AX.R) & 0xffff);
-
- if ((fp->_flag & _UNINITIALIZED) ||
- (fp->_cnt < 0))
- return pos;
-
- if (fp->_flag & _WROTE_LAST) {
- pos += BUFSIZ - fp->_cnt;
- }
- else {
- pos -= fp->_cnt;
- }
- return pos;
- }
-
- /* osinit - initialize */
- VOID osinit(banner)
- char *banner;
- {
- redirectout = !isatty(fileno(stdout));
- redirectin = !isatty(fileno(stdin));
-
- fprintf(stderr,"%s\n",banner);
- lposition = 0;
- lindex = 0;
- lcount = 0;
- setraw();
- }
-
- /* osfinish - clean up before returning to the operating system */
- VOID osfinish(void)
- {
-
- flushbuf();
- unsetraw();
- }
-
- /* xoserror - print an error message */
- VOID xoserror(msg)
- char *msg;
- {
- fprintf(stderr, "error: %s\n", msg);
- }
-
- /* osrand - return next random number in sequence */
- long osrand(rseed)
- long rseed;
- {
- long k1;
-
- /* make sure we don't get stuck at zero */
- if (rseed == 0L) rseed = 1L;
-
- /* algorithm taken from Dr. Dobbs Journal, November 1985, page 91 */
- k1 = rseed / 127773L;
- if ((rseed = 16807L * (rseed - k1 * 127773L) - k1 * 2836L) < 0L)
- rseed += 2147483647L;
-
- /* return a random number between 0 and MAXFIX */
- return rseed;
- }
-
- #ifdef FILETABLE
-
- int truename(char *name, char *rname)
- {
- int i;
- char *cp;
- int drive; /* drive letter */
- char pathbuf[FNAMEMAX+1]; /* copy of path part of name */
- char curdir[FNAMEMAX+1]; /* current directory of drive */
- char *fname; /* pointer to file name part of name */
-
- /* use backslashes consistantly */
-
- for (cp = name; (cp = strchr(cp, '/')) != NULL; *cp = '\\') ;
-
- /* parse any drive specifier */
-
- if ((cp = strrchr(name, ':')) != NULL) {
- if (cp != name+1 || !isalpha(*name)) return FALSE;
- drive = toupper(*name);
- name = cp+1; /* name now excludes drivespec */
- }
- else {
- Registers.AX.LH.H = 0x19; /* get current disk */
- calldos();
- drive = Registers.AX.LH.L + 'A';
- }
-
- /* check for absolute path (good news!) */
-
- if (*name == '\\') {
- sprintf(rname,"%c:%s",drive,name);
- }
- else {
- strcpy(pathbuf, name);
- if ((cp = strrchr(pathbuf, '\\')) != NULL) { /* path present */
- cp[1] = 0;
- fname = strrchr(name, '\\') + 1;
- }
- else {
- pathbuf[0] = 0;
- fname = name;
- }
-
- /* get the current directory of the selected drive */
-
- Registers.AX.LH.H = 0x47;
- Registers.DX.LH.L = drive + 1 - 'A';
- Registers.SI.R = (unsigned) curdir;
- calldos();
-
- if ((Registers.Flags&1) != 0) return FALSE; /* invalid drive */
-
- /* peel off "..\"s */
- while (strncmp(pathbuf, "..\\", 3) == 0) {
- if (*curdir == 0) return FALSE; /* already at root */
- strcpy(pathbuf, pathbuf+3);
- if ((cp=strrchr(curdir, '\\')) != NULL)
- *cp = 0; /* peel one depth of directories */
- else
- *curdir = 0; /* peeled back to root */
- }
-
- /* allow for a ".\" */
- if (strncmp(pathbuf, ".\\", 2) == 0)
- strcpy(pathbuf, pathbuf+2);
-
- /* final name is drive:\curdir\pathbuf\fname */
-
- if (strlen(pathbuf)+strlen(curdir)+strlen(fname)+4 > FNAMEMAX)
- return FALSE;
-
- if (*curdir)
- sprintf(rname, "%c:\\%s\\%s%s", drive, curdir, pathbuf, fname);
- else
- sprintf(rname, "%c:\\%s%s", drive, pathbuf, fname);
- }
-
- /* lowercase the whole string */
-
- for (cp = rname; (i = *cp) != 0; cp++) {
- if (isupper(i)) *cp = tolower(i);
- }
-
- return TRUE;
- }
-
- extern void gc(void);
-
- LOCAL int NEAR getslot(VOID)
- {
- int i=0;
-
- for (; i < FTABSIZE; i++) /* look for available slot */
- if (filetab[i].fp == NULL) return i;
-
- gc(); /* is this safe??????? */
-
- for (i=0; i < FTABSIZE; i++) /* try again -- maybe one has been freed */
- if (filetab[i].fp == NULL) return i;
-
- xlfail("too many open files");
-
- return 0; /* never returns */
- }
-
-
- FILEP osaopen(const char *name, const char *mode)
- {
- int i=getslot();
- char namebuf[FNAMEMAX+1];
- FILE *fp;
-
- if (!truename((char *)name, namebuf))
- strcpy(namebuf, name); /* should not happen */
-
- if ((filetab[i].tname = malloc(strlen(namebuf)+1)) == NULL) {
- free(filetab[i].tname);
- xlfail("insufficient memory");
- }
-
-
- if ((fp = fopen(name,mode)) == NULL) {
- free(filetab[i].tname);
- return CLOSED;
- }
-
- filetab[i].fp = fp;
-
- strcpy(filetab[i].tname, namebuf);
-
- return i;
- }
-
-
- FILEP osbopen(const char *name, const char *mode)
- {
- char bmode[10];
-
- strcpy(bmode,mode); strcat(bmode,"b");
-
- return osaopen(name, bmode);
- }
-
- VOID osclose(FILEP f)
- {
- fclose(filetab[f].fp);
- filetab[f].fp = NULL;
- }
-
- #else
-
- /* osbopen - open a binary file */
- FILE *osbopen(const char *name, const char *mode)
- {
- char bmode[10];
- strcpy(bmode,mode); strcat(bmode,"b");
- return (fopen(name,bmode));
- }
- #endif
-
- #ifdef PATHNAMES
- /* ospopen - open for reading using a search path */
- FILEP ospopen(char *name, int ascii)
- {
- FILEP fp;
- char *path = getenv(PATHNAMES);
- char *newnamep;
- char ch;
- char newname[256];
-
- /* don't do a thing if user specifies explicit path */
- if (strchr(name,'/') != NULL && strchr(name, '\\') != NULL)
- #ifdef FILETABLE
- return (ascii? osaopen: osbopen)(name,"r");
- #else
- return fopen(name,(ascii? "r": "rb"));
- #endif
-
- do {
- if (*path == '\0') /* no more paths to check */
- /* check current directory just in case */
- #ifdef FILETABLE
- return (ascii? osaopen: osbopen)(name,"r");
- #else
- return fopen(name,(ascii? "r": "rb"));
- #endif
-
- newnamep = newname;
- while ((ch=*path++) != '\0' && ch != ';' && ch != ' ')
- *newnamep++ = ch;
-
- if (ch == '\0') path--;
-
- if (newnamep != newname &&
- *(newnamep-1) != '/' && *(newnamep-1) != '\\')
- *newnamep++ = '/'; /* final path separator needed */
- *newnamep = '\0';
-
- strcat(newname, name);
- #ifdef FILETABLE
- fp = (ascii? osaopen: osbopen)(newname,"r");
- #else
- fp = fopen(newname, ascii? "r": "rb");
- #endif
- } while (fp == CLOSED); /* not yet found */
-
- return fp;
- }
- #endif
-
- /* rename argument file as backup, return success name */
- /* For new systems -- if cannot do it, just return TRUE! */
-
- int renamebackup(char *filename) {
- char *bufp, ch=0;
-
- strcpy(buf, filename); /* make copy with .bak extension */
-
- bufp = &buf[strlen(buf)]; /* point to terminator */
- while (bufp > buf && (ch = *--bufp) != '.' && ch != '/' && ch != '\\') ;
-
-
- if (ch == '.') strcpy(bufp, ".bak");
- else strcat(buf, ".bak");
-
- remove(buf);
-
- return !rename(filename, buf);
- }
-
-
- /* ostgetc - get a character from the terminal */
- int ostgetc()
- {
- int ch;
-
- /* check for a buffered character */
- if (lcount-- > 0)
- return (lbuf[lindex++]);
-
- /* get an input line */
- if (getvalue(s_dosinput) != NIL && !redirectin && !redirectout) {
- flushbuf();
- lindex = 2;
- lbuf[0] = LBSIZE - 2;
- Registers.AX.R = 0x0A00;
- Registers.DX.R = (unsigned int) lbuf;
- calldos();
- putchar('\n');
- lcount = lbuf[1];
- lbuf[lcount+2] = '\n';
- if (tfp!=CLOSED) OSWRITE(&lbuf[2],1,lcount+1,tfp);
- lposition = 0;
- return (lbuf[lindex++]);
- }
- else {
- for (lcount = 0; ; )
- switch (ch = xgetc()) {
- case '\r':
- case '\n':
- lbuf[lcount++] = '\n';
- xputc('\r'); xputc('\n'); lposition = 0;
- if (tfp!=CLOSED) OSWRITE(lbuf,1,lcount,tfp);
- lindex = 0; lcount--;
- return (lbuf[lindex++]);
- case '\010':
- case '\177':
- if (lcount) {
- lcount--;
- while (lposition > lpos[lcount]) {
- xputc('\010'); xputc(' '); xputc('\010');
- lposition--;
- }
- }
- break;
- case '\032':
- xflush();
- return (EOF);
- default:
- if (ch == '\t' || (ch >= 0x20 && ch < 0x7F)) {
- lbuf[lcount] = ch;
- lpos[lcount] = lposition;
- if (ch == '\t')
- do {
- xputc(' ');
- } while (++lposition & 7);
- else {
- xputc(ch); lposition++;
- }
- lcount++;
- }
- else {
- xflush();
- switch (ch) {
- case '\003': xltoplevel(); /* control-c */
- case '\007': xlcleanup(); /* control-g */
- case '\020': xlcontinue(); /* control-p */
- case '\032': return (EOF); /* control-z */
- case '\024': xinfo(); /* control-t */
- return ostgetc();
- default: return (ch);
- }
- }
- }}
- }
-
- /* ostputc - put a character to the terminal */
- VOID ostputc(ch)
- int ch;
- {
- /* check for control characters */
- oscheck();
-
- /* output the character */
- if (ch == '\n') {
- xputc('\r'); xputc('\n');
- lposition = 0;
- }
- else if (ch == '\t')
- do { xputc(' '); } while (++lposition & 7);
- else {
- xputc(ch);
- lposition++;
- }
-
- /* output the character to the transcript file */
- if (tfp!=CLOSED)
- OSPUTC(ch,tfp);
- }
-
- /* osflush - flush the terminal input buffer */
- VOID osflush()
- {
- lindex = lcount = lposition = 0;
- }
-
- /* oscheck - check for control characters during execution */
- VOID oscheck()
- {
- if (redirectin) return; /* if input redirected, don't check */
- Registers.AX.R = 0x0600;
- Registers.DX.LH.L = 0xff;
- calldos();
- if (Registers.AX.LH.L == 0) return; /* no characters */
-
- switch (Registers.AX.LH.L) {
- case '\002': /* control-b */
- xflush();
- xlbreak("BREAK",s_unbound);
- break;
- case '\003': /* control-c */
- xflush();
- xltoplevel();
- break;
- case '\023': /* control-s */
- xgetc(); /* paused -- get character and toss */
- break;
- case '\024': /* control-t */
- xinfo();
- break;
- }
- }
-
- /* xinfo - show information on control-t */
- static VOID xinfo()
- {
- extern int nfree,gccalls;
- extern long total;
- sprintf(buf,"\n[ Free: %d, GC calls: %d, Total: %ld ]",
- nfree,gccalls,total);
- errputstr(buf);
- flushbuf();
- }
-
- /* xflush - flush the input line buffer and start a new line */
- static VOID xflush()
- {
- osflush();
- ostputc('\n');
- }
-
- /* xgetc - get a character from the terminal without echo */
- static int xgetc()
- {
-
- flushbuf();
-
- if (redirectin) {
- unsigned char chbuf[1];
- Registers.AX.R = 0x3f00;
- Registers.BX.R = 2;
- Registers.CX.R = 1;
- Registers.DX.R = (unsigned int) &chbuf;
- calldos();
- return chbuf[0];
- }
- else {
- Registers.AX.LH.H = 0x7;
- calldos();
- return Registers.AX.LH.L;
- }
- }
-
- /* xputc - put a character to the terminal */
- static void xputc(ch)
- int ch;
- {
- *outbufp++ = ch;
- if (ch == '\n' || outbufp == &outbuf[CHBSIZE]) flushbuf();
- }
-
- static unsigned savestate;
- static unsigned char savebrk;
- #ifdef GRAPHICS
- static unsigned char origmode;
- static unsigned ourmode1=0, ourmode2=0;
-
- static VOID setmode(ax,bx)
- int ax,bx;
- {
- Registers.AX.R = ax;
- Registers.BX.R = bx;
- callint(0x10);
- }
-
- #endif
-
- /* setraw -- set raw mode */
- static VOID setraw()
- {
- Registers.AX.R = 0x4400; /* get device status */
- Registers.BX.R = 1;
- calldos();
- Registers.DX.LH.H = 0;
- savestate = Registers.DX.R;
- Registers.AX.R = 0x4401;
- Registers.DX.LH.L |= 0x20;
- calldos();
-
- Registers.AX.R = 0x3300; /* get ctrl-break status */
- calldos();
- savebrk = Registers.DX.LH.L;
- Registers.AX.R = 0x3301;
- Registers.DX.LH.L = 0;
- calldos();
-
- #ifdef GRAPHICS
- Registers.AX.R = 0x0f00; /* get mode */
- callint(0x10);
- origmode = Registers.AX.LH.L;
- if (ourmode1 != 0) /* mode was changed -- use it */
- setmode(ourmode1,ourmode2);
- #endif
- }
-
- /* unsetraw -- restore original mode */
- static VOID unsetraw()
- {
- Registers.AX.R = 0x4401;
- Registers.BX.R = 1;
- Registers.DX.R = savestate;
- calldos();
- Registers.AX.R = 0x3301;
- Registers.DX.LH.L = savebrk;
- calldos();
-
- #ifdef GRAPHICS
- if ((ourmode1 !=0) && (ourmode2 != origmode))
- setmode(origmode,0);
- #endif
- }
-
-
- /* xsystem - execute a system command */
- LVAL xsystem()
- {
- char commandtail[128],*s;
- int Err;
-
- if (moreargs()) {
- strcpy(commandtail," /c ");
- s = getstring(xlgastring());
- strcat(commandtail,s);
- strcat(commandtail,"\r");
- commandtail[0] = strlen(commandtail) - 2;
- xllastarg();
- }
- else
- strcpy(commandtail,"\001 \r");
-
- unsetraw();
- Err = ssystem(getenv("COMSPEC"),commandtail);
- setraw();
- return ( Err == 0 ? true : cvfixnum((FIXTYPE)Err));
- }
-
- /* xgetkey - get a key from the keyboard */
- LVAL xgetkey()
- {
- xllastarg();
- return (cvfixnum((FIXTYPE)xgetc()));
- }
-
- /* ossymbols - enter os specific symbols */
- VOID ossymbols()
- {
- }
-
-
- #ifdef GRAPHICS
-
- static int xpos=0, ypos=0;
- static int Xmax = -1, Ymax=-1;
- extern int bytesperline;
- static unsigned char drawvalue=15;
-
- extern void setpixel();
-
- struct overlay{int offset; short seg;}; /* trick to set far pointers */
-
- /* function goto-xy which set/obtains cursor position */
- LVAL xgotoxy()
- {
- FIXTYPE x, y;
- LVAL oldpos;
- _far unsigned char *basemem;
-
- ((struct overlay *)&basemem)->seg = 0x34; /* 1 meg linear address */
- ((struct overlay *)&basemem)->offset = 0;
-
- flushbuf();
-
- Registers.AX.R = 0x300; /* get old position */
- Registers.BX.R = 0;
- callint(0x10);
- oldpos = cons(cvfixnum((FIXTYPE)Registers.DX.LH.L),
- cons(cvfixnum((FIXTYPE)Registers.DX.LH.H),NIL));
-
- if (moreargs()) {
- x = getfixnum(xlgafixnum());
- y = getfixnum(xlgafixnum());
- xllastarg();
- if (x < 0) x = 0; /* check for in bounds */
- else if (x >= *(_far unsigned int *) &basemem[0x44a])
- x = *(_far unsigned int *)&basemem[0x44a] - 1;
- if (y < 0) y = 0;
- else if (basemem[0x484]!=0) {
- if (y > basemem[0x484])
- y = basemem[0x484];
- }
- else if (y > 24) y = 24;
-
- Registers.AX.R = 0x200; /* set new position */
- Registers.DX.LH.L = x;
- Registers.DX.LH.H = y;
- Registers.BX.R = 0;
-
- callint(0x10);
- lposition = x;
- }
-
- return oldpos;
- }
-
- LVAL xcls() /* clear the screen */
- {
- int xsize, ysize, attrib;
- _far unsigned char *basemem;
-
- ((struct overlay *)&basemem)->seg = 0x34; /* 1 meg linear address */
- ((struct overlay *)&basemem)->offset = 0;
-
- flushbuf();
- lposition = 0;
-
- xsize = *(_far unsigned int *) &basemem[0x44a];
- ysize = (basemem[0x484]!=0 ? basemem[0x484] : 24);
- attrib = (ourmode1 > 3 ? 0 : basemem[0xb8001]);
-
- Registers.AX.R = 0x0600;
- Registers.BX.LH.H = attrib;
- Registers.CX.R = 0;
- Registers.DX.LH.H = ysize;
- Registers.DX.LH.L = xsize;
- callint(0x10);
- Registers.AX.R =0x200; /* home cursor */
- Registers.DX.R = 0;
- Registers.BX.R = 0;
- callint(0x10);
- return NIL;
- }
-
- LVAL xcleol() /* clear to end of line */
- {
- _far unsigned char *basemem;
-
- ((struct overlay *)&basemem)->seg = 0x34; /* 1 meg linear address */
- ((struct overlay *)&basemem)->offset = 0;
-
- flushbuf();
-
- Registers.AX.R = 0x300; /* get old position */
- Registers.BX.R = 0;
- callint(0x10); /* x position in dl, y in dh */
- lposition = Registers.DX.LH.L; /* just to be sure */
- Registers.CX.R = Registers.DX.R;
- Registers.DX.LH.L = *(_far unsigned int *)&basemem[0x44a] -1; /* x size */
- Registers.AX.R = 0x0600; /* scroll region */
- Registers.BX.LH.H = (ourmode1 > 3 ? 0 : basemem[0xb8001]); /* atrrib*/
- callint(0x10);
- return NIL;
- }
-
- static LVAL draw(int x, int y, int x2, int y2)
-
- {
- int xStep,yStep,xDist,yDist;
- int i, t8, t9, t10;
-
- flushbuf();
-
- if ((x < 0) | (x > Xmax) | (y < 0) | (y > Ymax) |
- (x2 < 0)| (x2 > Xmax) | (y2 < 0) | (y2 > Ymax))
- return (NIL);
-
- x -= x2; /* cvt to distance and screen coordiate (right hand) */
- y2 = Ymax - y2;
- y = (Ymax - y) - y2;
-
- if (x < 0) { /* calculate motion */
- xStep = -1;
- xDist = -x;
- }
- else {
- xStep = 1;
- xDist = x;
- }
- if (y < 0) {
- yStep = -1;
- yDist = -y;
- }
- else {
- yStep = 1;
- yDist = y;
- }
-
- setdrawmode(drawvalue);
- setpixel(x2,y2);
-
- if (yDist == 0) {
- i = xDist;
- while (i--) {
- x2 += xStep;
- setpixel(x2,y2);
- }
- }
- else if (xDist == yDist) {
- i = xDist;
- while (i--) {
- x2 += xStep;
- y2 += yStep;
- setpixel(x2,y2);
- }
- }
- else if (xDist == 0) {
- i = yDist;
- while (i--) {
- y2 += yStep;
- setpixel(x2,y2);
- }
- }
- else if (xDist > yDist) {
- t8 = 2*yDist;
- t10 = 2*yDist - xDist;
- t9 = 2*(yDist - xDist);
- i = xDist;
- while (i--) {
- x2 += xStep;
- if (t10 < 0) {
- t10 += t8;
- }
- else {
- y2 += yStep;
- t10 += t9;
- }
- setpixel(x2,y2);
- }
- }
- else {
- t8 = 2*xDist;
- t10 = 2*xDist - yDist;
- t9 = 2*(xDist - yDist);
- i = yDist;
- while (i--) {
- y2 += yStep;
- if (t10 < 0) {
- t10 += t8;
- }
- else {
- x2 += xStep;
- t10 += t9;
- }
- setpixel(x2,y2);
- }
- }
- unsetdrawmode();
- return (true);
- }
-
- /* xmode -- set display mode */
- /* called with either ax contents, or ax,bx,xsize,ysize */
- LVAL xmode()
- {
- LVAL arg;
- int nmode1, nmode2;
-
- arg = xlgafixnum();
- nmode1 = (int) getfixnum(arg);
-
- if (moreargs()) {
- arg = xlgafixnum();
- nmode2 = (int) getfixnum(arg);
- arg = xlgafixnum();
- Xmax = (int) getfixnum(arg) - 1; /* max x coordinate */
- arg = xlgafixnum();
- Ymax = (int) getfixnum(arg) - 1; /* max y coordinate */
- xllastarg();
- }
- else {
- nmode2 = 0;
- switch (nmode1) {
- case 0:
- case 1:
- case 2:
- case 3:
- Xmax = Ymax = -1; /* not a graphic mode */
- break;
-
- case 13: Xmax = 319;
- Ymax = 199;
- break;
- case 14: Xmax = 639;
- Ymax = 199;
- break;
- case 16: Xmax = 639;
- Ymax = 349;
- break;
- case 18: Xmax = 639; /* added VGA mode */
- Ymax = 479;
- break;
- default: return NIL; /* invalid mode */
- }
- }
-
- ourmode1 = nmode1;
- ourmode2 = nmode2;
- setmode(ourmode1,ourmode2); /* set mode */
- bytesperline = (Xmax + 1) / 8;
-
-
- return (true);
- }
-
- /* xcolor -- set color */
-
- LVAL xcolor()
- {
- LVAL arg;
-
- arg = xlgafixnum();
- xllastarg();
-
- drawvalue = (char) getfixnum(arg);
-
- return (arg);
- }
-
- /* xdraw -- absolute draw */
-
- LVAL xdraw()
- {
- LVAL arg = true;
- int newx, newy;
-
- while (moreargs()) {
- arg = xlgafixnum();
- newx = (int) getfixnum(arg);
-
- arg = xlgafixnum();
- newy = (int) getfixnum(arg);
-
- arg = draw(xpos,ypos,newx,newy);
-
- xpos = newx;
- ypos = newy;
- }
- return (arg);
- }
-
- /* xdrawrel -- absolute draw */
-
- LVAL xdrawrel()
- {
- LVAL arg = true;
- int newx, newy;
-
- while (moreargs()) {
- arg = xlgafixnum();
- newx = xpos + (int) getfixnum(arg);
-
- arg = xlgafixnum();
- newy = ypos + (int) getfixnum(arg);
-
- arg = draw(xpos,ypos,newx,newy);
-
- xpos = newx;
- ypos = newy;
- }
- return (arg);
- }
-
- /* xmove -- absolute move, then draw */
-
- LVAL xmove()
- {
- LVAL arg;
-
- arg = xlgafixnum();
- xpos = (int) getfixnum(arg);
-
- arg = xlgafixnum();
- ypos = (int) getfixnum(arg);
-
- return (xdraw());
- }
-
- /* xmoverel -- relative move */
-
- LVAL xmoverel()
- {
- LVAL arg;
-
- arg = xlgafixnum();
- xpos += (int) getfixnum(arg);
-
- arg = xlgafixnum();
- ypos += (int) getfixnum(arg);
-
- return (xdrawrel());
- }
-
- #endif
-
- #ifdef TIMES
-
- unsigned long ticks_per_second() { return((unsigned long) CLK_TCK); }
-
- unsigned long run_tick_count()
- {
- return((unsigned long) clock()); /* Real time in MSDOS */
- }
-
- unsigned long real_tick_count()
- { /* Real time */
- return((unsigned long) clock());
- }
-
-
- LVAL xtime()
- {
- LVAL expr,result;
- unsigned long tm;
-
- /* get the expression to evaluate */
- expr = xlgetarg();
- xllastarg();
-
- tm = run_tick_count();
- result = xleval(expr);
- tm = run_tick_count() - tm;
- sprintf(buf, "The evaluation took %.2f seconds.\n",
- ((double)tm) / ticks_per_second());
- trcputstr(buf);
-
- flushbuf();
-
- return(result);
- }
-
- LVAL xruntime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) run_tick_count()));
- }
-
- LVAL xrealtime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) real_tick_count()));
- }
-
- #endif
-