mÛMCRC SUBPjCRC C &Å~WILDEXP C +1œ¡CRCASM S \Ù"ASM S c‹ÿÿ; Submit file to make CRC.68K AS -L ASM.S AS -L CRCASM.S CP CRC.C CRC.I C0 CRC.I CRC.IC CRC.ST C1 CRC.IC CRC.S -L AS -L -U CRC.S ERA CRC.I* ERA CRC.S* CP WILDEXP.C WILDEXP.I C0 WILDEXP.I WILDEXP.IC WILDEXP.ST C1 WILDEXP.IC WILDEXP.S -L AS -L -U WILDEXP.S ERA WILDEXP.I* ERA WILDEXP.S* LO -R -O CRC.68K S.O CRC.O CRCASM.O ASM.O WILDEXP.O CLIB  WILDEXP.S -L AS -L /************************************************************************/ /* */ /* C R C . C */ /* */ /* CRC (du:)filename.ext */ /* */ /* Accepts wildcards. */ /* Results comparable to CRC for CP/M-80 by Richard Conn */ /* */ /* (d)rives A - P MAXDRV */ /* (u)ser 0 - 31 MAXUSR */ /* */ /* Version: 1.10 for DRI C */ /* */ /* August 29, 1984 */ /* Christopher Rhodes */ /* Labradorian Labs */ /* */ /************************************************************************/ /* */ /* System dependencies: */ /* DRI requires openb to insure binary data is used. */ #define open openb #include #define VERSION "1.10\0" #define MAXDRV 'P' #define MAXUSR 31 #define READF 0 #define BUFF 0x4000 /* 16k at a time */ #define ERR -1 char file1[15]; /* storage for filename */ /************************************************************************/ /* M A I N */ /************************************************************************/ main(argc, argv) int argc; char *argv[]; { int i; int crcval1; int user1; wildexp(&argc,&argv); printf("CRC Version %s\n\n", VERSION); for(i = 1 ; i < argc ; i++) { if((user1 = d_user(argv[i],file1)) == 0xFF) { printf("Illegal DU: on %s\n", argv[i]); exit(ERR); } if(user1 == 0x80) /* get user number if default */ user1 = bdosw(32,0xFF); crcval1 = crc(user1); printf("%S \tCRC = %04x\n", argv[i], crcval1); } if(argc < 2) { printf("Usage:\n"); printf(" CRC (du:)filename.ext\n\n"); printf("Everything except filename is optional.\n"); printf("Accepts wildcards * and ?\n"); } } /************************************************************************/ /* E N D M A I N */ /************************************************************************/ int crc(user) int user; { int num_byte, fd, i; int oldusr; char *area,*malloc(); oldusr = bdosw(32,0xFF);/* save existing user number */ bdosw(32,user); /* open file */ if((fd = open(file1, READF)) == ERR) { printf("Can't open %s\n", file1); exit(ERR); } clrcrc(); /* clear CRC counter */ area = malloc(BUFF); /* allocate buffer space */ while(num_byte = read(fd, area, BUFF)) { if(num_byte == ERR) { printf("Bad read on %s\n", file1); exit(ERR); } for(i = 0 ; i < num_byte ; i++) addcrc(area[i]); /* calculate CRC */ } if(close(fd) != 0) /* close file */ { printf("Can't close %s\n", file1); exit(ERR); } free(area); /* free allocated space */ bdosw(32,oldusr); /* restore original user number */ return(getcrc()); /* return final CRC value */ } /********************************************************/ /* */ /* d_user() Version 1.0 8/29/84 */ /* */ /* Converts (du:)filename.ext into d:filename.ext */ /* and returns a user number. */ /* */ /* On entry: */ /* int d_user(name,file) */ /* char *name, *file; */ /* */ /* name - points to the entry string */ /* file - points to the exit string */ /* */ /* On return: */ /* 0xFF = illegal drive or user MAXDRV MAXUSR */ /* 0x80 = no user number */ /* 0 - 31 = user number */ /* */ /********************************************************/ int d_user(name,file) char *name,*file; { char usr[3]; int drive,i,j,k,l; /* First see if any drive or user specified */ for(i = 0 , j = 0 ; name[i] ; i++) if(name[i] == ':') { l = j = i; break; } /* If no drive or user specified, return after transfering string */ if(j == 0) { for(i = 0 ; name[i] ; i++) file[i] = name[i]; file[i] = 0; return(0x80); } /* See if drive specified (if alpha) */ (isalpha(name[0])) ? (drive = 1) : (drive = 0); /* Return illegal if drive out of bounds */ if(drive) if((name[0] & 0x5F) > MAXDRV) return(0xFF); /* Prepare return string with drive and filename and extract user number */ for(k = 0, i = 0 ; j > 0 ; i++, j--) /* get user number if any */ if(isdigit(name[i])) { usr[k] = name[i]; k++; } usr[k] = 0; /* terminate user number string */ if(drive) { file[0] = name[0]; file[1] = ':'; /* add colon if drive specified */ i = 2; } else i = 0; for( l += 1 ; name[i] ; i++ , l++) file[i] = name[l]; file[l] = 0; /* Check if user number was present and check if in bounds */ if(k == 0) return(0x80); else return((k = atoi(usr)) > MAXUSR ? 0xFF : k); } present and check if in bounds */ if/* WILDEXP.C v1.5 8/29/82 BDS C Command-line Wild-card expansion utility Written by Leor Zolman 1.2 - Remove attribute bits from names - W. Earnest 1.3 - Add code to ignore .SYS files (W.D.E) 1.4 - Add code to make .SYS files un-findable (Dave Hardy) 1.5 - Limited returned arguments to MAXITEMS (Bob Mathias) Modified to CPM/68k C by Jim Cathey 1/2/83 Lets ambiguous file names appear on the command line to C programs, automatically expanding the parameter list to contain all files that fit the afn's. An afn preceded by a "~" causes all names matching the given afn to be EXCLUDED from the resulting expansion list. Thus, to yield a command line containing all files except "COM" files, you'd say: A>progname ~*.com Another example: to get all files on B: except .C files, say: A>prognam b:*.* ~b:*.c When giving a "~" afn, "*" chars in the string matches to the end of either the filename or extension, just like CP/M, but "?" chars match ONE and ONLY ONE character in either the filename or extension. To use WILDEXP, begin your "main" function as follows: --------------------------------------------- main(argc,argv) int argc; char **argv; { ... \* local declarations \* wildexp(&argc, &argv); \* 1st state. in prog. \* dioinit(&argc,argv); \* if using DIO \* ... --------------------------------------------- and link WILDEXP.O in with your program. That's all there is to it; note that "wildexp" uses the "sbrk" function to obtain storage, so don't go playing around with memory that is outside of the external or stack areas unless you obtain the memory through "sbrk" or "alloc" calls. */ #include #include #define MAXITEMS 200 /* max no. of items after expansion */ #define SEARCH_FIRST 17 /* BDOS calls */ #define SEARCH_NEXT 18 wildexp(oargcp, oargvp) int *oargcp; /* pointer to old argc */ char ***oargvp; /* pointer to old argv */ { int nargc; /* new argc */ char **nargv; /* new argv */ char **oargv; /* old argv */ int oargc; /* old argc */ char fcb[36]; /* fcb used for search for first/next calls */ int dmapos; /* value returned by search calls */ int first_time; /* used in search routine */ char dirbuf[128]; /* Directory Buffer */ char tmpfn[20], /* temp filename buffer */ *tmpfnp; char *notfns[20]; /* list of ! entries */ int notcount; /* count of entries in notfns */ int cur_drive; /* currently logged drive */ int i,j,k; char *sbrk(); /* storage allocator */ char *hackname(); /* Name cruncher fcb -> string */ int tmp; cur_drive = __BDOS(25, 0l); oargv = *oargvp; oargc = *oargcp; nargc = notcount = 0; if ((nargv = sbrk(MAXITEMS * 4 + 4)) == ERROR) return ERROR; for (i = 0; (nargc <= (MAXITEMS+1)) && i < oargc; i++) if (oargv[i][0] == '~') { if (i == 1) { oargv[oargc] = "*.*"; oargc++; } notfns[notcount++] = &oargv[i][1]; } else if (!haswild(oargv[i])) nargv[nargc++] = oargv[i]; else { setfcb(fcb, oargv[i]); tmpfnp = tmpfn; if ((tmpfn[1] = oargv[i][1]) == ':') { tmpfn[0] = oargv[i][0]; tmpfnp = tmpfn + 2; } first_time = TRUE; __BDOS(26, dirbuf); /* Set DMA address to Dir buffer */ while (nargc<=(MAXITEMS+1)) { /* find all matching files */ dmapos = __BDOS(first_time ? SEARCH_FIRST : SEARCH_NEXT, fcb); if (dmapos == 255) break; first_time = FALSE; hackname(tmpfnp, dirbuf + dmapos * 32); if ((nargv[nargc] = sbrk(strlen(tmpfn) + 1)) == ERROR) return ERROR; strcpy(nargv[nargc++], tmpfn); } __BDOS(14, (long) cur_drive); /* restore to current drive */ } for (i = 0; i < notcount; i++) for (j = 1; j < nargc; j++) while (match(notfns[i], nargv[j], cur_drive)) { if(j == --nargc) break; for (k = j; k < nargc; k++) nargv[k] = nargv[k+1]; } *oargcp = nargc; *oargvp = nargv; return 0; } static char * hackname(dest,source) char *dest, *source; { int i,j; j = 0; for (i = 1; i < 9; i++) { if (source[i] == ' ') break; dest[j++] = tolower(source[i] & 0x7F); } if (source[9] != ' ') dest[j++] = '.'; for (i = 9; i < 12; i++) { if (source[i] == ' ') break; dest[j++] = tolower(source[i] & 0x7F); } dest[j] = '\0'; return dest; } static int haswild(fname) char *fname; { char c; while (c = *fname++) if (c == '*' || c == '?') return TRUE; return FALSE; } static match(wildnam, filnam, cur_drive) char *wildnam, *filnam, cur_drive; { char c; if (wildnam[1] != ':') { if (filnam[1] == ':') if (filnam[0] - 'a' == cur_drive) filnam += 2; else return FALSE; } else { if (filnam[1] != ':') if (wildnam[0] - 'a' == cur_drive) wildnam += 2; else return FALSE; } while (c = *wildnam++) if (c == '?') if ((c = *filnam++) && c != '.') continue; else return FALSE; else if (c == '*') { while (c = *wildnam) { wildnam++; if (c == '.') break; } while (c = *filnam) { filnam++; if (c == '.') break; } } else if (c == *filnam++) continue; else return FALSE; if (!*filnam) return TRUE; else return FALSE; } setfcb(fcb, name) char fcb[], *name; { int i; char *rindex(); strcpy(fcb, " "); fcb[0] = fcb[12] = fcb[14] = 0; if (*(name + 1) == ':') { fcb[0] = toupper(*name) - 'A' + 1; name += 2; } i = 1; while (i < 9) { if (*name == '\0') break; if (*name == '.' || *name < ' ') { name++; break; } if (*name == '*') { while (i<9) fcb[i++] = '?'; break; } fcb[i] = toupper(*name); name++; i++; } if ((name = rindex(name, '.') + 1) == 1) return; i = 9; while (i < 12) { if (*name == '\0') break; if (*name == '.' || *name < ' ') { name++; break; } if (*name == '*') { while (i < 12) fcb[i++] = '?'; break; } fcb[i] = toupper(*name); name++; i++; } } * Assembly support for CRC calculation * * Based on algorithm used in R. Conn's CRC.MAC * Why this differs from his SYSLIB routine I do not know. * This allows calculation of same values as the CP/M-80 * programs CRC and CRCK. Different from algorithm used in * XMODEM programs. * * July, 4, 1984 * Christopher Rhodes * Labradorian Labs .globl _clrcrc * clear CRC counter .globl _addcrc * add byte to CRC counter .globl _getcrc * return final CRC value .data _clrcrc: clr.w CRCVAL * clear CRC counter rts _addcrc: move.b 5(a7),d0 * get data byte off C stack move.w CRCVAL,d1 * get old value add.w d1,d1 add.b d0,d1 btst #7,CRCVAL beq skip eori.w #$A097,d1 skip: move.w d1,CRCVAL rts _getcrc: move.w CRCVAL,d0 rts .bss CRCVAL: .ds.w 1 * storage for CRC value .end : move.w d1,CRCVAL rts ******************************************************************************* * Assembly support for C -- DRI version for CP/M 68K * * * * source: asm.s * * * * June 30, 1984 * * Christopher Rhodes * * Labradorian Labs * ******************************************************************************* * bdosw(function, arg) * int function; * int arg; .GLOBL _bdosw _bdosw: MOVE.W 4(SP),D0 * get first arg MOVE.W 6(SP),D1 * get second arg TRAP #2 * call BDOS RTS * bdosl(function, arg) * int function; * long arg; .GLOBL _bdosl _bdosl: MOVE.W 4(SP),D0 * get first arg MOVE.L 6(SP),D1 * get second arg TRAP #2 * call BDOS RTS * bdoslp(function, arg) * int function; * char *arg; .GLOBL _bdoslp _bdoslp: MOVE.W 4(SP),D0 * get first arg MOVE.L 6(SP),D1 * get second arg TRAP #2 * call BDOS RTS ******************************************************************************* * * * BIOS calls * * * ******************************************************************************* ******************** General calls ******************** * bios(function) * int function .GLOBL _bios _bios: MOVE.W 4(SP),D0 * get bios call # TRAP #3 * call BIOS RTS * biosw(function, arg) * int function; * int arg; .GLOBL _biosw _biosw: MOVE.W 4(SP),D0 * get bios call # MOVE.W 6(SP),D1 * get D1.W argument TRAP #3 RTS * biosl(function, arg) * int function; * long arg; .GLOBL _biosl _biosl: MOVE.W 4(SP),D0 * get bios call # MOVE.L 6(SP),D1 * get D1.L argument TRAP #3 RTS ******************** Special calls ******************** * biosA0(function, arg) * int function; * char *arg; .GLOBL _biosA0 _biosA0: MOVE.W 4(SP),D0 * get bios call # MOVE.L 6(SP),A0 * get address for A0 TRAP #3 * call BIOS RTS * biosA1(function, arg) * int function; * char *arg; .GLOBL _biosA1 _biosA1: MOVE.W 4(SP),D0 * get bios call # MOVE.L 6(SP),A1 * get address for A1 TRAP #3 * call BIOS RTS * biosMW(function, arg1, arg2) * int function; * int arg1, arg2; .GLOBL _biosMW _biosMW: MOVE.W 4(SP),D0 * get bios call # MOVE.W 6(SP),D1 * get D1.W data MOVE.W 8(SP),D2 * get D2.W data TRAP #3 * call BIOS RTS * biosML(function, arg1, arg2) * int function; * int arg1; * long arg2; .GLOBL _biosML _biosML: MOVE.W 4(SP),D0 * get bios call # MOVE.W 6(SP),D1 * get D1.W data MOVE.L 8(SP),D2 * get D2.L data TRAP #3 * call BIOS RTS .END * ge