home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-25 | 24.6 KB | 1,064 lines |
- /* gccstuff.c - MS/DOS Gcc specific routines, Gcc with go32 protected
- mode runtime from DJ Delorie 1/91 release, with fix 001, or later */
-
-
- /* With the 3/11/91 release, it is no longer necessary to fix GO32.EXE
- Also, the SYSTEM function now works, and can be included, as it
- is here. If you have an earlier version, you will need to disable
- the SYSTEM function */
-
- /* If FILETABLE is defined, it is necessary again to fix GO32.EXE :-(
- in exphdlr.c, i_21(), add "case 0x19" after "case 0x0b".
- Also, in case 0x47, delete the for loop that switches the slashes
- and lowercases the name, and in the call to mput add "+1" to
- the result of the strlen call.
-
- As of 10/91, the case 0x19 has been added, but the problem with with
- 0x47 still exists.
-
- I'm passing this on to DJ Delorie for future inclusion */
-
-
- /* When using modified GO32.EXE (requires recompilation with fixed
- exphdlr.c) you can turn on the following
- conditional. Otherwise you must:
- 1. Issue the command BREAK OFF before running.
- 2. Avoid hitting ^C while running
-
- Steps for modifying go32.exe:
- 1. mswitch.asm doesn't assemble without errors (at least for me).
- The argument error on the l?dt instruction can be
- fixed by replacing "word" with "fword".
- 4. In exphdlr.c, i_21(), add "case 0x33:" after "case 0x68:".
- 5. In exphdlr.c, i_21_44(), add new case:
-
- case 0x01:
- intr(0x21, &r);
- tss_ptr->tss_eax = r.r_ax;
- tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
- return 0;
-
- */
- #define FIXEDGO32 /* */
-
- #include "xlisp.h"
- #include "osdefs.h"
- #include <math.h>
- #ifdef TIMES
- #include <sys/time.h>
- #endif
-
- #define LBSIZE 200
-
- /* external variables */
- extern LVAL s_unbound,s_dosinput,true;
- extern FILEP tfp;
-
- /* external functions */
- extern void setfpcw(void);
- /* The next three exist here because the first GCC didn't have the
- appropriate functions */
- extern int doscall(int eax, int ebx, int ecx, int edx);
- extern int doscalledx(int eax, int ebx, int ecx, int edx);
- extern int doscallpath(int drive, char *path);
- #ifdef GRAPHICS
- extern int calldisp(int eax, int ebx, int ecx, int edx);
- extern int calldispdx(int eax, int ebx, int ecx, int edx);
- extern void setpixel(int x, int y);
- extern void setdrawmode(int mode);
- extern void unsetdrawmode(void);
- #endif
-
- /* exported variables */
- int lposition;
-
-
- /* local variables */
- static char lbuf[LBSIZE];
- static int lpos[LBSIZE];
- static int lindex;
- static int lcount;
- static int istty;
-
- /* save the original state */
- static unsigned savestate;
- static unsigned char savebrk;
-
- #ifdef GRAPHICS
- static unsigned char origmode;
- static unsigned ourmode1=0, ourmode2=0;
- #endif
-
- /* forward declarations */
- void xinfo(void);
- void xflush(void);
- void xputc(int ch);
- void setraw(void);
- void unsetraw(void);
- int xgetc(void);
-
- #ifdef GRAPHICS
- void setgmode(int ax, int bx);
- #endif
-
- #define CHBSIZE 256
- static char outbuf[CHBSIZE];
- static char *outbufp = &outbuf[0];
-
- void flushbuf()
- {
- if (outbufp != &outbuf[0]) {
- doscall(0x4000,2,outbufp - &outbuf[0],(int)&outbuf[0]);
- outbufp = &outbuf[0];
- }
- }
-
- #define KLUDGEFLG 04000 /* steal a flag bit in the FILE struct */
-
- #ifdef FILETABLE
- int osgetc(FILEP f)
- {
- int val;
- FILE *fp = filetab[f].fp;
-
- /* read until a non \r found if in ascii mode */
- do val = fgetc(fp);
- while (val == '\r' && (fp->_flag&KLUDGEFLG));
- return val;
- }
-
- int osputc(int ch, FILEP f)
- {
- FILE *fp = filetab[f].fp;
-
- /* Add \r before \n if in ascii mode */
- if (ch == '\n' && (fp->_flag&KLUDGEFLG)) fputc('\r', fp);
- return fputc(ch, fp);
- }
- #else
-
- int osgetc(FILE *fp)
- {
- int val;
-
- /* read until a non \r found if in ascii mode */
- do val = fgetc(fp);
- while (val == '\r' && (fp->_flag&KLUDGEFLG));
- return val;
- }
-
- int osputc(int ch, FILE *fp)
- {
- /* Add \r before \n if in ascii mode */
- if (ch == '\n' && (fp->_flag&KLUDGEFLG)) fputc('\r', fp);
- return fputc(ch, fp);
- }
- #endif
-
-
- /* osinit - initialize */
- VOID osinit(banner)
- char *banner;
- {
- fprintf(stderr,"%s\n",banner);
- lposition = 0;
- lindex = 0;
- lcount = 0;
- setfpcw(); /* mask off fp interrupts */
- redirectout = (doscalledx(0x4400,1,0,0) & 0x81) != 0x81;
- redirectin = (doscalledx(0x4400,0,0,0) & 0x81) != 0x81;
- setraw();
- #ifdef GRAPHICS
- origmode = calldisp(0x0f00,0,0,0) & 0xff; /* get display mode */
- #endif
- }
-
- /* osfinish - clean up before returning to the operating system */
- VOID osfinish()
- {
- 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
- extern void gc(void);
-
- 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 {
- drive = (doscall(0x1900,0,0,0) & 0xff) + '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 */
-
- if (doscallpath(drive+1-'A', curdir))
- 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;
- }
-
- 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 < 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 osbopen(const char *name, const char *mode)
- {
- int i=getslot();
- char bmode[10];
- 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");
- }
-
-
- strcpy(bmode, mode);
- strcat(bmode, "b");
-
- if ((fp = fopen(name,bmode)) == NULL) {
- free(filetab[i].tname);
- return CLOSED;
- }
-
- filetab[i].fp = fp;
-
- strcpy(filetab[i].tname, namebuf);
-
- return i;
- }
-
-
- FILEP osaopen(const char *name, const char *mode)
- {
- /* open as binary file, since these work, but set special flag bit */
-
- int i= osbopen(name, mode);
-
- if (i != CLOSED) filetab[i].fp->_flag |= KLUDGEFLG;
-
- return i;
- }
-
- VOID osclose(FILEP f)
- {
- fclose(filetab[f].fp);
- free(filetab[f].tname);
- filetab[f].tname = NULL;
- filetab[f].fp = NULL;
- }
-
-
- #else
-
- /* osaopen - open an ascii file */
- FILE *osaopen(const char *name, const char *mode)
- {
- FILE *fp;
-
- /* open as binary file, since these work, but set special flag bit */
-
- if ((fp = osbopen(name,mode)) != NULL) {
- fp->_flag |= KLUDGEFLG;
- }
- return fp;
- }
-
- /* 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 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) ||
- path == NULL)
- return (ascii? OSAOPEN : OSBOPEN)(name, "r");
-
- do {
- if (*path == '\0') /* no more paths to check */
- /* check current directory just in case */
- return (ascii? OSAOPEN : OSBOPEN)(name, "r");
-
- 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);
- fp = (ascii? OSAOPEN : OSBOPEN)(newname, "r");
- } 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--)
- return (lbuf[lindex++]);
-
- /* get an input line */
-
- if (!null(getvalue(s_dosinput)) && !redirectin && !redirectout) {
- flushbuf();
- memset(lbuf, 0, LBSIZE);
- #ifdef FIXEDGO32
- doscall(0x4401,2,0,savestate); /* restore raw state */
- #endif
- doscall(0x3f00, 0, LBSIZE-1, (int)lbuf);
- #ifdef FIXEDGO32
- doscall(0x4401,2,0,savestate | 0x20); /* set raw bit */
- #endif
- lcount = strlen(lbuf);
- if (tfp!=CLOSED) /* convoluted because of ugly text mode handling
- with djgpp (sorry, DJ Delorie) */
- for (lindex=0; lindex < lcount; lindex++)
- OSPUTC(lbuf[lindex],tfp);
- lposition = 0;
- lindex = 1;
- lcount--;
- return (lbuf[0]);
- }
- else {
-
- for (lcount = 0; ; )
- switch (ch = xgetc()) {
- case '\r':
- case '\n':
- lbuf[lcount++] = '\n';
- xputc('\r'); xputc('\n');
- lposition = 0;
- if (tfp!=CLOSED)
- for (lindex=0; lindex < lcount; lindex++)
- OSPUTC(lbuf[lindex],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') {
- lposition = 0;
- xputc('\r'); xputc('\n');
- }
- else if (ch == '\t')
- do { xputc(' '); } while (++lposition & 7);
- else {
- lposition++;
- xputc(ch);
- }
-
- /* 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) return;
- ch = doscall(0x600,0,0,0xff) & 0xff;
- if (ch == 0) return; /* no characters */
-
- 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 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];
- doscall(0x3f00,2,1,(int)chbuf);
- return chbuf[0];
- }
- else
- return doscall(0x700,0,0,0) & 0xff;
- }
-
- /* xputc - put a character to the terminal */
- static void xputc(ch)
- int ch;
- {
- *outbufp++ = ch;
- if (ch == '\n' || outbufp == &outbuf[CHBSIZE]) flushbuf();
- }
-
- #ifdef GRAPHICS
- static VOID setgmode(int ax, int bx)
- {
- calldisp(ax,bx,0,0);
- }
-
- #endif
-
- /* setraw -- set raw mode */
- static VOID setraw()
- {
- #ifdef FIXEDGO32
- savestate = doscalledx(0x4400,2,0,0) & 0xff; /* get device status */
- doscall(0x4401,2,0,savestate | 0x20); /* set raw bit */
- savebrk = doscalledx(0x3300,0,0,0); /* get ctrl-break status */
- doscall(0x3301,0,0,0); /* disable */
- #endif
- #ifdef GRAPHICS
- origmode = calldisp(0x0f00, 0, 0, 0); /* get display mode */
- if (ourmode1 != 0) /* mode was changed -- use it */
- setgmode(ourmode1,ourmode2);
- #endif
- }
-
- /* unsetraw -- restore original mode */
- static VOID unsetraw()
- {
- #ifdef FIXEDGO32
- doscall(0x4401,2,0,savestate); /* restore raw state */
- doscall(0x3301,0,0,savebrk); /* reset break */
- #endif
- #ifdef GRAPHICS
- /* restore original mode if it has changed */
- if ((ourmode1 != 0) && (ourmode2 != origmode))
- setgmode(origmode,0);
- #endif
- }
-
- /* xsystem - execute a system command */
- LVAL xsystem()
- {
- char command[128],*s;
- int Err;
-
- if (moreargs()) {
- s = getstring(xlgastring());
- strcpy(command,s);
- xllastarg();
- }
- else
- strcpy(command, getenv("COMSPEC"));
-
- unsetraw();
- Err = system(command);
- 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 TIMES
-
- unsigned long ticks_per_second() { return((unsigned long) 1000); }
-
- unsigned long run_tick_count() /* actually real time */
- {
- struct timeval now;
- gettimeofday(&now,0);
- return ((unsigned long) (now.tv_sec*1000 + now.tv_usec/1000));
- }
-
- unsigned long real_tick_count() /* real time */
- {
- struct timeval now;
- gettimeofday(&now,0);
- return ((unsigned long) (now.tv_sec*1000 + now.tv_usec/1000));
- }
-
- 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) / 1000.0);
- trcputstr(buf);
-
- flushbuf();
-
- return(result);
- }
-
- LVAL xruntime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) run_tick_count()));
- }
-
- LVAL xrealtime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) real_tick_count()));
- }
-
- #endif
- #ifdef GRAPHICS
-
- static int xpos=0, ypos=0;
- static int Xmax=-1, Ymax=-1;
- static unsigned char drawvalue=15;
- extern int bytesperline;
-
-
- /* function goto-xy which set/obtains cursor position */
- LVAL xgotoxy()
- {
- FIXTYPE x, y;
- int pos;
- LVAL oldpos;
-
- flushbuf();
-
- pos = calldispdx(0x300, 0, 0, 0); /* get cursor position */
-
- oldpos = cons(cvfixnum((FIXTYPE)(pos & 0xff)),
- cons(cvfixnum((FIXTYPE)((pos >> 8) & 0xff)),NIL));
-
- if (moreargs()) {
- x = getfixnum(xlgafixnum());
- y = getfixnum(xlgafixnum());
- xllastarg();
- if (x < 0) x = 0; /* check for in bounds */
- else if (x >= *(unsigned int *) 0xe000044a)
- x = *(unsigned int *)0xe000044a - 1;
- if (y < 0) y = 0;
- else if (*(unsigned char *)0xe0000484 != 0) {
- if (y > *(unsigned char *) 0xe0000484)
- y = *(unsigned char *) 0xe0000484;
- }
- else if (y > 24) y = 24;
-
- calldisp(0x200, 0, 0, x + (y<<8)); /* set new position */
-
- lposition = x;
- }
-
- return oldpos;
- }
-
- LVAL xcls() /* clear the screen */
- {
- int xsize, ysize, attrib;
-
- flushbuf();
- lposition = 0;
-
- xsize = *(unsigned int *) 0xe000044a;
- ysize = (*(unsigned char *)0xe0000484 != 0 ?
- *(unsigned char *)0xe0000484 : 24);
- attrib = (ourmode1 > 3 ? 0 : *(unsigned char *)0xe00b8001);
-
- calldisp(0x600, attrib << 8, 0, xsize + (ysize << 8)); /* clear region */
- calldisp(0x200, 0, 0, 0); /* home cursor */
-
- return NIL;
- }
-
- LVAL xcleol() /* clear to end of line */
- {
- int oldpos;
-
- flushbuf();
-
- oldpos = calldispdx(0x300, 0, 0, 0); /* get old position */
-
- lposition = oldpos & 0xff; /* just to be sure */
- calldisp(0x0600, /* clear region */
- (ourmode1 > 3 ? 0 : *(unsigned char *)0xe00b8001) << 8, /* atrrib*/
- oldpos,
- (*(unsigned int *)0xe000044a -1) + (oldpos & 0xff00));
- 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;
-
- arg = xlgafixnum();
- ourmode1 = (int) getfixnum(arg);
-
- if (moreargs()) {
- arg = xlgafixnum();
- ourmode2 = (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 {
- ourmode2 = 0;
- switch (ourmode1) {
- case 4:
- case 5:
- case 13: Xmax = 319;
- Ymax = 199;
- break;
- case 6:
- 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: Xmax = Ymax = -1; /* not a graphic mode */
- break;
- }
- }
-
-
- setgmode(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
-