home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-25 | 26.7 KB | 1,202 lines |
- /* dosstuff.c - MS/DOS 16 bit compiler specific sources */
- /* Handles Microsoft C (v4.0 or later), Turbo/Borland C (any version),
- TopSpeed C (any version), and Zortech C (version 2 or later) in large
- memory model. In addition handles Turbo/Borland C and TopSpeed C in
- medium memory model, and the "x" (286 protected mode) model of Zortech C.*/
-
- #include "xlisp.h"
- #include "osdefs.h"
-
- #include <dos.h>
- #include <process.h>
- #include <math.h>
- #include <io.h>
- #include <float.h>
- #ifdef TIMES
- #include <time.h>
- #endif
-
- #define LBSIZE 200
-
- #ifdef __ZTC__
- #ifdef DOS16RM
- extern void * _cdecl D16SegAbsolute(long); /* undocumented, but necessary, function*/
-
- unsigned _cdecl _stack = 48000; /* bigger stack in this case */
- #else
- unsigned _cdecl _stack = 16384; /* set up reasonable stack */
- #endif
- #endif
- #ifdef __TURBOC__
- unsigned _Cdecl _stklen = 16384; /* set up reasonable stack */
- #ifdef MEDMEM
- unsigned _Cdecl _heaplen = 4096; /* compress the near heap */
- #endif
- #endif
-
- #ifdef MSC
- /* MSC Doesn't define these */
- #define MK_FP(seg,ofs) (((unsigned long)(seg)<<16) | (unsigned)(ofs))
- #endif
-
- /* external variables */
- extern LVAL s_unbound,s_dosinput,true;
- extern FILEP tfp;
-
- /* exported variables */
- int lposition;
-
-
- /* local variables */
- static char lbuf[LBSIZE];
- static int lpos[LBSIZE];
- static int lindex;
- static int lcount;
-
- /* forward declarations */
- void NEAR xinfo(void);
- void NEAR xflush(void);
- int NEAR xgetc(void);
- void NEAR xputc(int ch);
- void NEAR setraw(void);
- void NEAR unsetraw(void);
-
- /* math error handler */
-
- #ifdef __TSC__ /* Top Speed wants matherr to be function pointer! */
- int newmatherr(struct exception *er)
- #else
- int CDECL matherr(struct exception *er)
- #endif
- {
- char *emsg;
-
- switch (er->type) {
- case DOMAIN: emsg="domain"; break;
- case OVERFLOW: emsg="overflow"; break;
- case PLOSS: case TLOSS: emsg="inaccurate"; break;
- case UNDERFLOW: return 1;
- default: emsg="????"; break;
- }
- xlerror(emsg,cvflonum(er->arg1));
- return 0; /* never happens */
- }
-
- /* osinit - initialize */
-
- #ifdef MSC
- extern unsigned _amblksiz;
- #endif
-
-
- VOID osinit(banner)
- char *banner;
- {
- #ifdef MSC
- /* _amblksiz = 16; */
- #endif
- #ifdef __TSC__
- matherr = newmatherr;
- #endif
- setvbuf(stderr,NULL,_IOFBF,256);
-
- if (*(char FAR *)MK_FP(_psp,0x19) != *(char FAR *)MK_FP(_psp,0x1a))
- redirectout = TRUE;
- if (*(char FAR *)MK_FP(_psp,0x18) != *(char FAR *)MK_FP(_psp,0x1a))
- redirectin = TRUE;
-
- fprintf(stderr,"%s\n",banner);
- lposition = 0;
- lindex = 0;
- lcount = 0;
- setraw();
-
- #if defined( __TURBOC__) || defined(MSC) || defined(__TSC__)
- /* let fp overflow pass and domain errors */
- _control87(EM_OVERFLOW|EM_INVALID,EM_OVERFLOW|EM_INVALID);
- #endif
- #ifdef __TURBOC__
- /* force raw mode for stderr */
- stderr->flags |= _F_BIN;
- #endif
- }
-
- /* osfinish - clean up before returning to the operating system */
- VOID osfinish()
- {
- 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)
- {
- union REGS regs;
- #ifndef MEDMEM
- struct SREGS sregs;
- #endif
- 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 {
- regs.h.ah = 0x19; /* get current disk */
- intdos(®s, ®s);
- drive = regs.h.al + '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 */
-
- regs.h.ah = 0x47;
- regs.h.dl = drive + 1 - 'A';
- #ifdef MEDMEM
- regs.x.si = (unsigned) curdir;
- intdos(®s, ®s);
- #else
- regs.x.si = (unsigned) FP_OFF(curdir);
- sregs.ds = (unsigned) FP_SEG(curdir);
- intdosx(®s, ®s, &sregs);
- #endif
-
- if (regs.x.cflag != 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);
- free(filetab[f].tname);
- filetab[f].tname = NULL;
- filetab[f].fp = NULL;
- }
-
- #else
- /* osbopen - open a binary file */
- FILE * CDECL 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;
- union REGS regs;
- struct SREGS segregs;
-
- /* check for a buffered character */
- if (lcount-- > 0)
- return (lbuf[lindex++]);
-
- /* get an input line */
-
- if (getvalue(s_dosinput) != NIL && !redirectin && !redirectout) {
-
- fflush(stderr);
-
- lindex = 2;
- lbuf[0] = LBSIZE - 2;
- regs.x.ax = 0x0A00;
- regs.x.dx = FP_OFF(lbuf);
- segregs.ds = FP_SEG(lbuf);
- intdosx(®s,®s,&segregs);
- 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()
- {
- int ch;
-
- if (!redirectin && (ch = (bdos(6,0xFF,0) & 0xff)) != 0)
- switch (ch) {
- 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 NEAR xinfo()
- {
- extern long nfree;
- extern int gccalls;
- extern long total;
-
- sprintf(buf,"\n[ Free: %ld, GC calls: %d, Total: %ld ]",
- nfree,gccalls,total);
- errputstr(buf);
-
- fflush(stderr);
- }
-
- /* xflush - flush the input line buffer and start a new line */
- static VOID NEAR xflush()
- {
- osflush();
- ostputc('\n');
- }
-
- /* xgetc - get a character from the terminal without echo */
- static int NEAR xgetc()
- {
- fflush(stderr);
-
- if (!redirectin)
- return (bdos(7,0,0) & 0xFF);
- else {
- #ifdef __TURBOC__
- char temp[1];
- _read(2, temp, 1);
- #else
- #if defined(MSC) || defined(__TSC__)
- char temp[1];
- int dummy;
- _dos_read(2, temp, 1, &dummy);
- #else
- char temp[1];
- read(2, temp, 1);
- #endif
- #endif
- return temp[0];
- }
- }
-
- /* xputc - put a character to the terminal */
- static void NEAR xputc(ch)
- int ch;
- {
- fputc(ch,stderr);
- if (ch == '\n') fflush(stderr);
- }
-
- #ifdef OVERLAY
- /* Ralf Brown's SPAWNO package */
- #ifdef __TSC__
- int cdecl spawnvo(const char *overlay_path, const char *name, va_list args) ;
- #else
- #include "spawno.h"
- #endif
- #endif
-
- /* xsystem - execute a system command */
- LVAL xsystem()
- {
- char *cmd[4];
- int ok;
-
- cmd[0] = getenv("COMSPEC");
- if (moreargs()) {
- cmd[1] = "/c";
- #ifdef MEDMEM
- MEMCPY(buf, getstring(xlgastring()), STRMAX);
- cmd[2] = buf;
- #else
- cmd[2] = getstring(xlgastring());
- #endif
- cmd[3] = NULL;
- xllastarg();
- }
- else {
- cmd[1] = NULL;
- }
- unsetraw();
-
- #ifdef OVERLAY
- ok = spawnvo("/",cmd[0], cmd);
- #else
- ok = spawnv(P_WAIT,cmd[0], cmd);
- #endif
-
- setraw();
- return (ok == 0 ? true : cvfixnum((FIXTYPE)errno));
- }
-
- /* xgetkey - get a key from the keyboard */
- LVAL xgetkey()
- {
- xllastarg();
- return (cvfixnum((FIXTYPE)xgetc()));
- }
-
- static unsigned savestate;
- static unsigned char savebrk;
-
- #ifdef GRAPHICS
- static unsigned char origmode;
- static unsigned ourmode1=0, ourmode2=0;
-
- static VOID NEAR setgmode(int ax, int bx)
- {
- union REGS regs;
- regs.x.ax = ax;
- regs.x.bx = bx;
- int86(0x10, ®s, ®s);
- }
-
- #endif
-
- /* setraw -- set raw mode */
- static VOID NEAR setraw(void)
- {
- union REGS regs;
-
- regs.x.ax = 0x4400; /* get device status */
- regs.x.bx = 2;
- intdos(®s,®s);
- regs.h.dh = 0;
- savestate = regs.x.dx;
- regs.x.ax = 0x4401;
- regs.h.dl |= 0x20;
- intdos(®s,®s);
-
- regs.x.ax = 0x3300; /* get ctrl-break status */
- intdos(®s,®s);
- savebrk = regs.h.dl;
- regs.x.ax = 0x3301;
- regs.h.dl = 0;
- intdos(®s,®s);
-
- #ifdef GRAPHICS
- regs.x.ax = 0x0f00; /* get mode */
- int86(0x10, ®s, ®s);
- origmode = regs.h.al;
- if (ourmode1 != 0) /* mode was changed -- use it */
- setgmode(ourmode1,ourmode2);
- #endif
- }
-
- /* unsetraw -- restore original mode */
- static VOID NEAR unsetraw(void)
- {
- union REGS regs;
-
- regs.x.ax = 0x4401;
- regs.x.bx = 2;
- regs.x.dx = savestate;
- intdos(®s,®s);
- regs.x.ax = 0x3301;
- regs.h.dl = savebrk;
- intdos(®s,®s);
-
- #ifdef GRAPHICS
- if ((ourmode1 !=0) && (ourmode2 != origmode))
- setgmode(origmode,0);
- #endif
- }
-
-
- /* ossymbols - enter os specific symbols */
- VOID ossymbols()
- {
- }
-
- #ifdef GRAPHICS
-
- static union REGS regin, regout;
- static int xpos=0, ypos=0;
- static int Xmax=-1, Ymax=-1;
- static unsigned char drawvalue=15;
-
- /* function goto-xy which set/obtains cursor position */
- LVAL xgotoxy()
- {
- union REGS regs;
- FIXTYPE x, y;
- LVAL oldpos;
- #ifdef DOS16RM /* kludge for 80286 protected mode */
- unsigned char *basemem = D16SegAbsolute(0L);
- #endif
-
- fflush(stderr);
-
- regs.h.ah = 0x3; /* get old position */
- regs.h.bh = 0;
- int86(0x10, ®s, ®s);
- oldpos = cons(cvfixnum((FIXTYPE)regs.h.dl),
- cons(cvfixnum((FIXTYPE)regs.h.dh),NIL));
-
- if (moreargs()) {
- x = getfixnum(xlgafixnum());
- y = getfixnum(xlgafixnum());
- xllastarg();
- if (x < 0) x = 0; /* check for in bounds */
- #ifdef DOS16RM
- else if (x >= *(unsigned int FAR *)(basemem+0x44a))
- x = *(unsigned int FAR *)(basemem+0x44a) - 1;
- #else
- else if (x >= *(unsigned int FAR *) 0x44aL)
- x = *(unsigned int FAR *) 0x44aL - 1;
- #endif
- if (y < 0) y = 0;
- #ifdef DOS16RM
- else if (*(basemem+0x484) != 0) {
- if (y > *(basemem+0x484))
- y = *(basemem+0x484);
- }
- #else
- else if (*(unsigned char FAR *) 0x484L != 0) {
- if (y > *(unsigned char FAR *) 0x484L)
- y = *(unsigned char FAR *) 0x484L;
- }
- #endif
- else if (y > 24) y = 24;
-
- regs.h.ah = 0x2; /* set new position */
- regs.h.dl = x;
- regs.h.dh = y;
- regs.h.bh = 0;
-
- int86(0x10, ®s, ®s);
- lposition = (int)x;
- }
-
- return oldpos;
- }
-
- LVAL xcls() /* clear the screen */
- {
- union REGS regs;
- int xsize, ysize, attrib;
- #ifdef DOS16RM /* kludge for 80286 protected mode */
- unsigned char *basemem = D16SegAbsolute(0L);
- #endif
-
- fflush(stderr);
- lposition = 0;
-
- #ifdef DOS16RM
- xsize = *(unsigned int FAR *)(basemem+0x44a);
- ysize = (*(basemem+0x484) != 0 ? *(basemem+0x484) : 24);
- attrib = (ourmode1 > 3 ? 0 :
- *(unsigned char FAR *)D16SegAbsolute(0xb8001L));
- #else
- xsize = *(unsigned int FAR *) 0x44aL;
- ysize = (*(unsigned char FAR *) 0x484L != 0 ?
- *(unsigned char FAR *)0x484L : 24);
- attrib = (ourmode1 > 3 ? 0 : *(unsigned char FAR *)0xb8000001L);
- #endif
-
- regs.x.ax = 0x0600;
- regs.h.bh = attrib;
- regs.x.cx = 0;
- regs.h.dh = ysize;
- regs.h.dl = xsize;
- int86(0x10, ®s, ®s);
- regs.h.ah =0x2; /* home cursor */
- regs.x.dx = 0;
- regs.h.bh = 0;
- int86(0x10, ®s, ®s);
- return NIL;
- }
-
- LVAL xcleol() /* clear to end of line */
- {
- union REGS regs;
- fflush(stderr);
-
- regs.h.ah = 0x3; /* get old position */
- regs.h.bh = 0;
- int86(0x10, ®s, ®s); /* x position in regs.h.dl, y in regs.h.dh */
- lposition = regs.h.dl; /* just to be sure */
- regs.x.cx = regs.x.dx;
- #ifdef DOS16RM
- regs.h.dl = (*(unsigned int FAR *)D16SegAbsolute(0x44aL)) -1;/* x size */
- regs.h.bh = (ourmode1 > 3 ? 0 :
- *(unsigned char FAR *)D16SegAbsolute(0xb8001L)); /* atrrib*/
- #else
- regs.h.dl = *(unsigned int FAR *) 0x44aL -1; /* x size */
- regs.h.bh = (ourmode1 > 3 ? 0 : *(unsigned char FAR *)0xb8000001L); /* atrrib*/
- #endif
- regs.x.ax = 0x0600; /* scroll region */
- int86(0x10, ®s, ®s);
- return NIL;
- }
-
-
-
- static LVAL NEAR draw(int x, int y, int x2, int y2)
-
- {
- int xStep,yStep,xDist,yDist;
- int i, t8, t9, t10;
-
- fflush(stderr);
-
- 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;
- }
-
- regin.x.ax = drawvalue + 0x0c00; /* write graphic pixel command */
-
- regin.x.cx = x2; /* initial coordinates */
- regin.x.dx = y2;
-
- int86(0x10,®in,®out); /* initial draw */
-
-
- if (yDist == 0) {
- i = xDist;
- while (i--) {
- regin.x.cx += xStep;
- int86(0x10,®in,®out);
- }
- }
- else if (xDist == yDist) {
- i = xDist;
- while (i--) {
- regin.x.cx += xStep;
- regin.x.dx += yStep;
- int86(0x10,®in,®out);
- }
- }
- else if (xDist == 0) {
- i = yDist;
- while (i--) {
- regin.x.dx += yStep;
- int86(0x10,®in,®out);
- }
- }
- else if (xDist > yDist) {
- t8 = 2*yDist;
- t10 = 2*yDist - xDist;
- t9 = 2*(yDist - xDist);
- i = xDist;
- while (i--) {
- regin.x.cx += xStep;
- if (t10 < 0) {
- t10 += t8;
- }
- else {
- regin.x.dx += yStep;
- t10 += t9;
- }
- int86(0x10,®in,®out);
- }
- }
- else {
- t8 = 2*xDist;
- t10 = 2*xDist - yDist;
- t9 = 2*(xDist - yDist);
- i = yDist;
- while (i--) {
- regin.x.dx += yStep;
- if (t10 < 0) {
- t10 += t8;
- }
- else {
- regin.x.cx += xStep;
- t10 += t9;
- }
- int86(0x10,®in,®out);
- }
- }
- return (true);
- }
-
-
- /* xmode -- set display mode */
- /* called with either ax contents, or ax,bx,xsize,ysize */
- LVAL xmode()
- {
- int nmode1, nmode2;
- LVAL arg;
-
- 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 4:
- case 5:
- case 13:
- case 19: Xmax = 319;
- Ymax = 199;
- break;
- case 6:
- case 14: Xmax = 639;
- Ymax = 199;
- break;
- case 16: Xmax = 639;
- Ymax = 349;
- break;
- case 17:
- case 18: Xmax = 639; /* added VGA mode */
- Ymax = 479;
- break;
- default: return NIL; /* failed */
- }
- }
-
- ourmode1 = nmode1;
- ourmode2 = nmode2;
- setgmode(ourmode1,ourmode2); /* set mode */
- 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
- /* For some reason, every compiler is different ... */
- #if defined(MSC) || defined(__TSC__)
- 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);
-
- fflush(stderr);
-
- return(result);
- }
- #endif
-
- #ifdef __ZTC__
- 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;
- double tm;
-
- /* get the expression to evaluate */
- expr = xlgetarg();
- xllastarg();
-
- tm = run_tick_count();
- result = xleval(expr);
- tm = (run_tick_count() - tm) / CLK_TCK ;
- sprintf(buf, "The evaluation took %.2f seconds.\n", tm);
- trcputstr(buf);
-
- fflush(stderr);
- return(result);
- }
-
- #endif
-
- #ifdef __TURBOC__
- /* We want to cheat here because ticks_per_second would have to be rounded */
-
- #define OURTICKS 1000
-
- unsigned long ticks_per_second() {
- return((unsigned long) OURTICKS);
- }
-
- unsigned long run_tick_count()
- { /*Real time in MSDOS*/
- return((unsigned long) ((OURTICKS/CLK_TCK)*clock()));
- }
-
- unsigned long real_tick_count()
- { /* Real time */
- return((unsigned long) ((OURTICKS/CLK_TCK)*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);
-
- fflush(stderr);
-
- return(result);
- }
- #endif
-
- LVAL xruntime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) run_tick_count()));
- }
-
- LVAL xrealtime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) real_tick_count()));
- }
-
-
- #endif
-