home *** CD-ROM | disk | FTP | other *** search
-
-
- /*
- ** CSYSLIB -- System-Level Library Functions
- ** Modified for MS-DOS 2 by R. Grehan
- */
-
- #include stdio.h
- #include clib.def
- #define NOCCARGC /* no argument count passing */
- #define DIR /* compile directory option */
-
- /*
- ****************** System Variables ********************
- */
-
- int
-
- errno, /* Error number holding var */
-
- Ucnt=1, /* arg count for main */
- Uvec[20], /* arg vectors for main */
-
- Ustatus[MAXFILES] = {RDBIT, WRTBIT, RDBIT|WRTBIT},
- /* status of respective file */
- Udevice[MAXFILES] = {CONSOL, CONSOL, CONSOL},
- /* non-disk device assignments */
- Unextc[MAXFILES] = {EOF, EOF, EOF},
- /* pigeonhole for ungetc bytes */
- Ufd[MAXFILES] = {0, 1, 2};
- /* Map logical fd's to physical */
-
- char
- *Umemptr, /* pointer to free memory. */
- Uarg1[]="*"; /* first arg for main */
- /*
- *************** System-Level Functions *****************
- */
-
- /*
- ** -- Process Command Line, Execute main(), and Exit to CP/M
- */
- Umain() {
- Uparse();
- main(Ucnt,Uvec);
- exit(0);
- }
-
- /*
- ** Parse command line and setup argc and argv.
- */
- Uparse() {
- char *count, *ptr;
- count = 128; /* Reserve bytes */
- ptr = Ualloc(count+1, YES);
-
- count=Ugcmdtl(ptr); /* Get command tail - null pad */
-
- Uvec[0]=Uarg1; /* first arg = "*" */
- while (*ptr) {
- if(isspace(*ptr)) {++ptr; continue;}
- switch(*ptr) {
- case '<': ptr = Uredirect(ptr, "r", stdin);
- continue;
- case '>': if(*(ptr+1) == '>')
- ptr = Uredirect(ptr+1, "a", stdout);
- else ptr = Uredirect(ptr, "w", stdout);
- continue;
- default: if(Ucnt < 20) Uvec[Ucnt++] = ptr;
- ptr = Ufield(ptr);
- }
- }
- }
-
- Ugcmdtl(mypt) char *mypt; {
- #asm
- MOV AH,62H ;Get program segment prefix
- INT 21H
- MOV AX,DS ;Get our segment
- MOV ES,AX ;Will be destination
- MOV DS,BX ;PSP segment is source
- MOV SI,80H ;Offset to command tail byte count
- MOV CL,[SI] ;Get byte count
- MOV BX,CX ;Save for return
- INC SI ;Bump pointer
- POP AX ;Return address
- POP DI ;mypt
- PUSH DI ;Restore
- PUSH AX
- CLD ;Set direction
- REP MOVSB ;Move it in
- MOV BYTE PTR ES:[DI],0 ;Move in Null
- MOV AX,ES ;Restore our segment
- MOV DS,AX
- XOR CX,CX ;Zero in CX
- #endasm
- }
- /*
-
- ** Isolate next command-line field.
- */
- Ufield(ptr) char *ptr; {
- while(*ptr) {
- if(isspace(*ptr)) {
- *ptr = NULL;
- return (++ptr);
- }
- ++ptr;
- }
- return (ptr);
- }
-
- /*
- ** Redirect stdin or stdout.
- */
- Uredirect(ptr, mode, std) char *ptr, *mode; int std; {
- char *fn;
- fn = ++ptr;
- ptr = Ufield(ptr);
- if(Uopen(fn, mode, std)==ERR) exit('R');
- return (ptr);
- }
-
- /*
- ** ------------ File Open
- */
-
- /*
- ** Open file on specified fd.
- */
- Uopen(fn, mode, fd) char *fn, *mode; int fd; {
- int pfd;
- if(!strchr("rwau", *mode)) return (ERR);
- Unextc[fd] = EOF;
- if(strcmp(fn,"CON:")==0) {
- Udevice[fd]=CONSOL; Ustatus[fd]=RDBIT|WRTBIT; return (fd);
- }
- if(strcmp(fn,"LST:")==0) {
- Udevice[fd]=PRINTR; Ustatus[fd]=WRTBIT; return (fd);
- }
- Udevice[fd] = 0;
- switch(*mode) {
- case 'r': {
- if((pfd=Umsdos(fn,0,0,OPNFIL+RACCESS))==ERR) return (ERR);
- Ustatus[fd] = RDBIT;
- Ufd[fd]=pfd;
- break;
- }
- case 'u': {
- if((pfd=Umsdos(fn,0,0,OPNFIL+RWACCESS))==ERR)
- return (ERR);
- Ustatus[fd] = RDBIT|WRTBIT;
- Ufd[fd]=pfd;
- break;
- }
- case 'w': {
- if((pfd=Umsdos(fn,0,0,OPNFIL+WACCESS))!=ERR) {
- Umsdos(0,0,pfd,CLOFIL);
- Umsdos(fn,0,0,DELFIL); }
- create:
- if((pfd=Umsdos(fn,0,0,MAKFIL))==ERR) return (ERR);
- Ustatus[fd] = EOFBIT|WRTBIT;
- Ufd[fd]=pfd;
- break;
- }
- default: { /* append mode */
- if((pfd=Umsdos(fn,0,0,OPNFIL+RWACCESS))==ERR)
- goto create;
- Ustatus[fd] = RDBIT;
- Ufd[fd]=pfd;
- seek(fd, -1, -1, 2);
- while(fgetc(fd)!=EOF) ;
- Ustatus[fd] = EOFBIT|WRTBIT;
- }
- }
- return (fd);
- }
-
- /*
- ** ------------ File Input
- */
-
- /*
- ** Binary-stream input fd.
- */
- Uread(buff,fd,n) int fd; char *buff, *n; {
- char *i; /* Fake unsigned */
- char ch;
- i=n;
- switch (Umode(fd)) {
- default: Useterr(fd); return (EOF);
- case RDBIT:
- case RDBIT|WRTBIT:
- }
- if(Unextc[fd] != EOF) {
- *buff++=Unextc[fd];
- Unextc[fd] = EOF;
- if((--n)==0) return(1) ;
- }
- switch(Udevice[fd]) {
- /* PUN & LST can't occur since they are write mode */
- case CONSOL: while(n--) {
- if((ch=Uconin())==FILEOF) return(EOF);
- *buff++=ch;
- } return(i-n);
- default:
- if((i=Umsdos(buff,n,Ufd[fd],RDFIL))==ERR)
- return(ERR);
- if(i==0) Useteof(fd);
- return(i);
- }
- }
-
- /*
- ** Console character input.
- */
- Uconin() {
- int ch;
- while(!(ch = Dcio(255))) ;
- switch(ch) {
- case ABORT: exit(0);
- case LF:
- case CR: Uconout(LF); return (Uconout(CR));
- case DEL: ch = RUB;
- default: if(ch < 32) { Uconout('^'); Uconout(ch+64);}
- else Uconout(ch);
- return (ch);
- }
- }
-
- /*
- ** Special direct keyboard input for MS-DOS
- */
- Dcio(ch) int ch; {
- #asm
- POP SI
- POP DX
- PUSH DX
- PUSH SI
- MOV AH,6 ;Direct I/O
- INT 21H
- JNZ Dcio1
- XOR AL,AL ;No char.
- Dcio1:
- MOV BL,AL
- XOR BH,BH
- #endasm
- }
-
-
- /*
- ** ------------ File Output
- */
-
- /*
- ** Binary-Stream output to fd.
- */
- Uwrite(buff, fd, n) int fd; char *buff, *n; {
- char *i;
- i=n;
- switch (Umode(fd)) {
- default: Useterr(fd); return (EOF);
- case WRTBIT:
- case WRTBIT|RDBIT:
- case WRTBIT|EOFBIT:
- case WRTBIT|EOFBIT|RDBIT:
- }
- switch(Udevice[fd]) {
- /* RDR can't occur since it is read mode */
- case CONSOL: while (n--) {
- Dcio(*buff++);
- } return(i-n);
- case PRINTR: while (n--) {
- Umsdos(*buff++,0,0,PRTOUT);
- } return (i-n);
- default:
- return(Umsdos(buff,n,Ufd[fd],WRFIL));
- }
- }
-
- /*
- ** Console character output.
- */
- Uconout(ch) int ch; {
- Dcio(ch);
- return (ch);
- }
-
- /*
- ** ------------ Buffer Service
- */
-
-
- /*
- ** Return fd's open mode, else NULL.
- */
- Umode(fd) char *fd; {
- if(fd < MAXFILES) return (Ustatus[fd]);
- return (NULL);
- }
-
- /*
- ** Set eof status for fd and
- ** disable future i/o unless writing is allowed.
- */
- Useteof(fd) int fd; {
- Ustatus[fd] |= EOFBIT;
- }
-
- /*
- ** Clear eof status for fd.
- */
- Uclreof(fd) int fd; {
- Ustatus[fd] &= ~EOFBIT;
- }
-
- /*
- ** Set error status for fd.
- */
- Useterr(fd) int fd; {
- Ustatus[fd] |= ERRBIT;
- }
-
- /*
- ** ------------ Memory Allocation
- */
-
- /*
- ** Allocate n bytes of (possibly zeroed) memory.
- ** Entry: n = Size of the items in bytes.
- ** clear = "true" if clearing is desired.
- ** Returns the address of the allocated block of memory
- ** or NULL if the requested amount of space is not available.
- */
- Ualloc(n, clear) char *n; int clear; {
- char *oldptr;
- if(n < avail(YES)) {
- if(clear) pad(Umemptr, NULL, n);
- oldptr = Umemptr;
- Umemptr += n;
- return (oldptr);
- }
- return (NULL);
- }
-
- /* MS-DOS interface
- ** If there's an error code, we store it in errno and
- ** return ERR
- */
-
- Umsdos(dx,cx,bx,ax) int dx,cx,bx,ax; {
- #asm
- POP SI ;Return address
- POP AX ;Load all the registers
- POP BX
- POP CX
- POP DX
- PUSH DX ;Now restore them
- PUSH CX
- PUSH BX
- PUSH AX
- PUSH SI
- INT 21H ;Issue the call do DOS
- JNC UMSDOS1 ;Jump if no error
- MOV _ERRNO,AX
- MOV AX,-2 ;ERR
- UMSDOS1:
- MOV BX,AX
- XOR CX,CX ;Zero in CX
- #endasm
- }
-