This is atari.c in view mode; [Download] [Up]
/* ATARI.C: Operating specific I/O and Spawning functions for the ATARI ST operating system (GEMDOS) for MicroEMACS 3.10 (C)opyright 1988 by Daniel M. Lawrence */ #include <stdio.h> #include "estruct.h" #include "etype.h" #if ATARI #include "edef.h" #include "elang.h" #include "osbind.h" #include "stat.h" /* DMABUFFER is here */ #include "errno.h" /**** ST Internals definitions *****/ /* BIOS calls */ #define BCONSTAT 1 /* return input device status */ #define CONIN 2 /* read character from device */ #define BCONOUT 3 /* write character to device */ /* XBIOS calls */ #define INITMOUS 0 /* initialize the mouse */ #define GETREZ 4 /* get current resolution */ #define SETSCREEN 5 /* set screen resolution */ #define SETPALETTE 6 /* set the color pallette */ #define SETCOLOR 7 /* set or read a color */ #define CURSCONF 21 /* set cursor configuration */ #define IKBDWS 25 /* intelligent keyboard send command */ #define KBDVBASE 34 /* get keyboard table base */ /* GEMDOS calls */ #define EXEC 0x4b /* Exec off a process */ #define CON 2 /* CON: Keyboard and screen device */ /* * This function is called once to set up the terminal device streams. * On VMS, it translates TT until it finds the terminal, then assigns * a channel to it and sets it raw. On CPM it is a no-op. */ ttopen() { /* on all screens we are not sure of the initial position of the cursor */ ttrow = 999; ttcol = 999; } /* * This function gets called just before we go back home to the command * interpreter. On VMS it puts the terminal back in a reasonable state. * Another no-operation on CPM. */ ttclose() { } /* * Write a character to the display. On VMS, terminal output is buffered, and * we just put the characters in the big array, after checking for overflow. * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on * MS-DOS (use the very very raw console output routine). */ ttputc(c) char c; { } /* * Flush terminal buffer. Does real work where the terminal output is buffered * up. A no-operation on systems where byte at a time terminal I/O is done. */ ttflush() { } /* * Read a character from the terminal, performing no editing and doing no echo * at all. More complex in VMS that almost anyplace else, which figures. Very * simple on CPM, because the system can do exactly what you want. */ ttgetc() { } #if TYPEAH typahead() { int rval; /* return value from BIOS call */ /* get the status of the console */ rval = bios(BCONSTAT, CON); /* end return the results */ if (rval == 0) return(FALSE); else return(TRUE); } #endif /* * Create a subjob with a copy of the command intrepreter in it. When the * command interpreter exits, mark the screen as garbage so that you do a full * repaint. Bound to "^X C". The message at the start in VMS puts out a newline. * Under some (unknown) condition, you don't get one free when DCL starts up. */ spawncli(f, n) { /* don't allow this command if restricted */ if (restflag) return(resterr()); #if MWC mlerase(); /* clear the message line */ TTflush(); TTkclose(); system("msh.prg"); TTkopen(); sgarbf = TRUE; return(TRUE); #endif } /* * Run a one-liner in a subjob. When the command returns, wait for a single * character to be typed, then mark the screen as garbage so a full repaint is * done. Bound to "C-X !". */ spawn(f, n) { register int s; char line[NLINE]; /* don't allow this command if restricted */ if (restflag) return(resterr()); #if MWC if ((s=mlreply("!", line, NLINE)) != TRUE) return(s); mlerase(); TTkclose(); system(line); TTkopen(); /* if we are interactive, pause here */ if (clexec == FALSE) { mlputs(TEXT6); /* "\r\n\n[End]" */ tgetc(); } sgarbf = TRUE; return (TRUE); #endif } /* * Run an external program with arguments. When it returns, wait for a single * character to be typed, then mark the screen as garbage so a full repaint is * done. Bound to "C-X $". */ execprg(f, n) { register int s; char line[NLINE]; /* don't allow this command if restricted */ if (restflag) return(resterr()); #if MWC if ((s=mlreply("!", line, NLINE)) != TRUE) return(s); mlerase(); TTkclose(); system(line); TTkopen(); /* if we are interactive, pause here */ if (clexec == FALSE) { mlputs(TEXT6); /* "\r\n\n[End]" */ tgetc(); } sgarbf = TRUE; return (TRUE); #endif } /* * Pipe a one line command into a window * Bound to ^X @ */ pipecmd(f, n) { register int s; /* return status from CLI */ register WINDOW *wp; /* pointer to new window */ register BUFFER *bp; /* pointer to buffer to zot */ char line[NLINE]; /* command line send to shell */ static char bname[] = "command"; FILE *fp; static char filnam[NSTRING] = "command"; /* don't allow this command if restricted */ if (restflag) return(resterr()); /* get the command to pipe in */ if ((s=mlreply("@", line, NLINE)) != TRUE) return(s); /* get rid of the command output buffer if it exists */ if ((bp=bfind(bname, FALSE, 0)) != FALSE) { /* try to make sure we are off screen */ wp = wheadp; while (wp != NULL) { if (wp->w_bufp == bp) { onlywind(FALSE, 1); break; } wp = wp->w_wndp; } if (zotbuf(bp) != TRUE) return(FALSE); } #if MWC strcat(line," >>"); strcat(line,filnam); movecursor(term.t_nrow - 1, 0); TTkclose(); system(line); TTkopen(); sgarbf = TRUE; if ((fp = fopen(filnam, "r")) == NULL) { s = FALSE; } else { fclose(fp); s = TRUE; } #endif if (s != TRUE) return(s); /* split the current window to make room for the command output */ if (splitwind(FALSE, 1) == FALSE) return(FALSE); /* and read the stuff in */ if (getfile(filnam, FALSE) == FALSE) return(FALSE); /* make this window in VIEW mode, update all mode lines */ curwp->w_bufp->b_mode |= MDVIEW; wp = wheadp; while (wp != NULL) { wp->w_flag |= WFMODE; wp = wp->w_wndp; } /* and get rid of the temporary file */ unlink(filnam); return(TRUE); } /* * filter a buffer through an external DOS program * Bound to ^X # */ filter(f, n) { register int s; /* return status from CLI */ register BUFFER *bp; /* pointer to buffer to zot */ char line[NLINE]; /* command line send to shell */ char tmpnam[NFILEN]; /* place to store real file name */ static char bname1[] = "fltinp"; static char filnam1[] = "fltinp"; static char filnam2[] = "fltout"; /* don't allow this command if restricted */ if (restflag) return(resterr()); if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ /* get the filter name and its args */ if ((s=mlreply("#", line, NLINE)) != TRUE) return(s); /* setup the proper file names */ bp = curbp; strcpy(tmpnam, bp->b_fname); /* save the original name */ strcpy(bp->b_fname, bname1); /* set it to our new one */ /* write it out, checking for errors */ if (writeout(filnam1) != TRUE) { mlwrite(TEXT2); /* "[Cannot write filter file]" */ strcpy(bp->b_fname, tmpnam); return(FALSE); } #if MWC strcat(line," <fltinp >fltout"); movecursor(term.t_nrow - 1, 0); TTkclose(); system(line); TTkopen(); sgarbf = TRUE; s = TRUE; #endif /* on failure, escape gracefully */ if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) { mlwrite(TEXT3); /* "[Execution failed]" */ strcpy(bp->b_fname, tmpnam); unlink(filnam1); unlink(filnam2); return(s); } /* reset file name */ strcpy(bp->b_fname, tmpnam); /* restore name */ bp->b_flag |= BFCHG; /* flag it as changed */ /* and get rid of the temporary file */ unlink(filnam1); unlink(filnam2); return(TRUE); } rename(oldname, newname) /* rename a file */ char *oldname; /* original file name */ char *newname; /* new file name */ { Frename(0, oldname, newname); } /* return a system dependant string with the current time */ char *PASCAL NEAR timeset() { register char *sp; /* temp string pointer */ char buf[16]; /* time data buffer */ time(buf); sp = ctime(buf); sp[strlen(sp)-1] = 0; return(sp); } /* extcode: resolve MSDOS extended character codes encoding the proper sequences into emacs printable character specifications Well, yes... The ATARI ST was supposed to be a PC clone originally... These codes are the same for the ST. */ int extcode(c) unsigned c; /* byte following a zero extended char byte */ { /* function keys 1 through 9 */ if (c >= 59 && c < 68) return(SPEC | c - 58 + '0'); /* function key 10 */ if (c == 68) return(SPEC | '0'); /* shifted function keys */ if (c >= 84 && c < 93) return(SPEC | SHFT | c - 83 + '0'); if (c == 93) return(SPEC | SHFT | '0'); /* control function keys */ if (c >= 94 && c < 103) return(SPEC | CTRL | c - 93 + '0'); if (c == 103) return(SPEC | CTRL | '0'); /* ALTed function keys */ if (c >= 104 && c < 113) return(SPEC | ALTD | c - 103 + '0'); if (c == 113) return(SPEC | ALTD | '0'); /* ALTed number keys */ if (c >= 120 && c < 129) return(ALTD | c - 119 + '0'); if (c == 130) return(ALTD | '0'); /* some others as well */ switch (c) { case 3: return(0); /* null */ case 15: return(SHFT | CTRL | 'I'); /* backtab */ case 16: return(ALTD | 'Q'); case 17: return(ALTD | 'W'); case 18: return(ALTD | 'E'); case 19: return(ALTD | 'R'); case 20: return(ALTD | 'T'); case 21: return(ALTD | 'Y'); case 22: return(ALTD | 'U'); case 23: return(ALTD | 'I'); case 24: return(ALTD | 'O'); case 25: return(ALTD | 'P'); case 30: return(ALTD | 'A'); case 31: return(ALTD | 'S'); case 32: return(ALTD | 'D'); case 33: return(ALTD | 'F'); case 34: return(ALTD | 'G'); case 35: return(ALTD | 'H'); case 36: return(ALTD | 'J'); case 37: return(ALTD | 'K'); case 38: return(ALTD | 'L'); case 44: return(ALTD | 'Z'); case 45: return(ALTD | 'X'); case 46: return(ALTD | 'C'); case 47: return(ALTD | 'V'); case 48: return(ALTD | 'B'); case 49: return(ALTD | 'N'); case 50: return(ALTD | 'M'); case 71: return(SPEC | '<'); /* HOME */ case 72: return(SPEC | 'P'); /* cursor up */ case 73: return(SPEC | 'Z'); /* page up */ case 75: return(SPEC | 'B'); /* cursor left */ case 77: return(SPEC | 'F'); /* cursor right */ case 79: return(SPEC | '>'); /* end */ case 80: return(SPEC | 'N'); /* cursor down */ case 81: return(SPEC | 'V'); /* page down */ case 82: return(SPEC | 'C'); /* insert */ case 83: return(SPEC | 'D'); /* delete */ case 115: return(SPEC | CTRL | 'B'); /* control left */ case 116: return(SPEC | CTRL | 'F'); /* control right */ case 117: return(SPEC | CTRL | '>'); /* control END */ case 118: return(SPEC | CTRL | 'V'); /* control page down */ case 119: return(SPEC | CTRL | '<'); /* control HOME */ case 132: return(SPEC | CTRL | 'Z'); /* control page up */ } return(ALTD | c); } /* FILE Directory routines */ static DMABUFFER info; /* Info about the file */ char path[NFILEN]; /* path of file to find */ char rbuf[NFILEN]; /* return file buffer */ /* do a wild card directory search (for file name completion) */ char *PASCAL NEAR getffile(fspec) char *fspec; /* file to match */ { register int index; /* index into various strings */ register int point; /* index into other strings */ register int extflag; /* does the file have an extention? */ char fname[NFILEN]; /* file/path for DOS call */ /* first parse the file path off the file spec */ strcpy(path, fspec); index = strlen(path) - 1; while (index >= 0 && (path[index] != '/' && path[index] != '\\' && path[index] != ':')) --index; path[index+1] = 0; /* check for an extension */ point = strlen(fspec) - 1; extflag = FALSE; while (point >= 0) { if (fspec[point] == '.') { extflag = TRUE; break; } point--; } /* construct the composite wild card spec */ strcpy(fname, path); strcat(fname, &fspec[index+1]); strcat(fname, "*"); if (extflag == FALSE) strcat(fname, ".*"); /* and call for the first file */ Fsetdta(&info); /* Initialize buffer for our search */ if (Fsfirst(fname, 0xF7) != AE_OK) return(NULL); /* return the first file name! */ strcpy(rbuf, path); strcat(rbuf, info.d_fname); mklower(rbuf); return(rbuf); } char *PASCAL NEAR getnfile() { /* and call for the first file */ if (Fsnext() != AE_OK) return(NULL); /* return the first file name! */ strcpy(rbuf, path); strcat(rbuf, info.d_fname); mklower(rbuf); return(rbuf); } #else atarihello() { } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.