diff --git a/tools/conv2.c b/tools/conv2.c new file mode 100644 index 0000000..6b04181 --- /dev/null +++ b/tools/conv2.c @@ -0,0 +1,241 @@ +/* + * conv2.c + * Tape file converter for simh + * + * This utility is for converting files to and from the tape format + * used by simh. + * + * 2004 Tim N. + * This code is in the public domain. + */ + +#include +#include +#include +#include + +int +testeof(FILE *fp) +{ + int ch; + + if(!feof(fp) && (ch = fgetc(fp)) != -1) { + ungetc(ch, fp); + return 0; + } + return 1; +} + +void +xperror(char *msg) +{ + perror(msg); + exit(1); +} + +FILE * +xfopen(char *fname, char *mode) +{ + FILE *fp = fopen(fname, mode); + + if(!fp) + xperror(fname); + return fp; +} + +void +optfclose(FILE *fp) +{ + if(fp) + fclose(fp); +} + +int +xreadint(FILE *fp) +{ + unsigned char buf[4]; + + if(fread(buf, sizeof buf, 1, fp) != 1) { + fprintf(stderr, "short read\n"); + exit(1); + } + return buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24); +} + +void +xwriteint(FILE *fp, int x) +{ + unsigned char buf[4]; + + buf[0] = x & 0xff; + buf[1] = (x>>8) & 0xff; + buf[2] = (x>>16) & 0xff; + buf[3] = (x>>24) & 0xff; + fwrite(buf, sizeof buf, 1, fp); +} + +void +xcopy(FILE *infp, FILE *outfp, int cnt, int allowshort) +{ + char buf[512]; + int x, r; + + while(cnt > 0) { + r = (cnt > sizeof buf) ? sizeof buf : cnt; + if((x = fread(buf, 1, r, infp)) != r) { + if(x && allowshort) { + memset(buf + x, 0, (sizeof buf) - x); + } else { + fprintf(stderr, "short read\n"); + exit(1); + } + } + fwrite(buf, 1, r, outfp); + cnt -= r; + } +} + +int +convout(FILE *infp, char *fname, int vflag) +{ + FILE *outfp = 0; + char buf[128], *p; + unsigned int l, reclen, i, cnt = 0; + int bsize = -1; + + p = strrchr(fname, '.'); + if(p) + l = p - fname; + else + l = strlen(fname); + if(l + 10 > sizeof buf) { + fprintf(stderr, "use a smaller name\n"); + return -1; + } + + i = 1; + while(!testeof(infp)) { + reclen = xreadint(infp); + if(reclen == 0x00000000) { + if(vflag) { + if(cnt) + fprintf(stderr, "%s %d@%d -- ", buf, cnt, bsize); + fprintf(stderr, "EOF\n"); + } + optfclose(outfp); + outfp = 0; + cnt = 0; + + } else if(reclen == 0xffffffff) { + if(vflag) { + if(cnt) + fprintf(stderr, "%s %d@%d -- ", buf, cnt, bsize); + fprintf(stderr, "EOT\n"); + } + optfclose(outfp); + break; + + } else { + if(reclen > 0x10000) { + /* XXX we dont handle high-bit == error block */ + fprintf(stderr, "Bad Format? Got length %d\n", reclen); + return -1; + } + if(cnt && reclen != bsize) { + fprintf(stderr, "Expected %d bytes, got %d bytes\n", bsize, reclen); + return -1; + } + cnt ++; + bsize = reclen; + + if(!outfp) { + sprintf(buf, "%.*s-%d.raw", l, fname, i++); + outfp = xfopen(buf, "wb"); + } + xcopy(infp, outfp, reclen, 0); + if(xreadint(infp) != reclen) { + fprintf(stderr, "format error\n"); + return -1; + } + } + } + return 0; +} + +int +convin(FILE *ofile, char *fname, int bsize, int vflag) +{ + FILE *ifile = xfopen(fname, "rb"); + int cnt = 0; + + while(!testeof(ifile)) { + xwriteint(ofile, bsize); + xcopy(ifile, ofile, bsize, 1); + xwriteint(ofile, bsize); + cnt ++; + } + xwriteint(ofile, 0); /* EOF */ + if(vflag) + fprintf(stderr, "%s: %d@%d\n", fname, cnt, bsize); + return 0; +} + +void +xusage(char *prog) +{ + fprintf(stderr, "usage: %s [-v] [-i file.tap | -o file.tap file ...]\n" + "\tWhen using -o, files may be interspersed with [-b bsize]\n" + "\tto specify the block size to use for following files\n" + "\tThe default block size is 512.\n", prog); + exit(1); +} + +int +main(int argc, char **argv) +{ + FILE *ifile = 0, *ofile = 0; + char *prog; + int i, ocnt = 0, bsize = 512, vflag = 0; + char *ofname = 0, ch; + + prog = argv[0]; + for(i = 1; i < argc; i++) { + if (*argv[i] == '-') { + ch = argv[i][1]; + if(ch == 'v') + vflag ++; + else if(ch == 'b') { + i++; + if(!ofile || !argv[i] || !(bsize = atoi(argv[i]))) + xusage(prog); + + } else if(ch == 'i') { + if(ifile || ofile || !argv[++i]) + xusage(prog); + ifile = xfopen(argv[i], "rb"); + if(convout(ifile, argv[i], vflag) == -1) + exit(1); + + } else if(ch == 'o') { + if(ifile || ofile || !argv[++i]) + xusage(prog); + ofile = xfopen(argv[i], "wb"); + ofname = argv[i]; + + } else + xusage(prog); + continue; + } + + if(!ofile) + xusage(prog); + if(convin(ofile, argv[i], bsize, vflag) == -1) + exit(1); + ocnt ++; + } + if(ofile) + xwriteint(ofile, 0); /*EOF*/ /* 0xffffffff); - EOT */ + + return 0; +} + diff --git a/tools/rebuild-split b/tools/rebuild-split new file mode 100755 index 0000000..5468ed6 --- /dev/null +++ b/tools/rebuild-split @@ -0,0 +1,29 @@ +#!/bin/sh +# rebuild sources in a manner that lets you see the page splits. +# useful for editing the pages to get the inter-page flow to line +# up properly. + +xcat() { + for fn in $*; do + cat $fn + echo "******* $fn end *******" + done +} + +m() { xcat pages/$2 > rebuilt/$1.s; } + +test -d rebuilt || mkdir rebuilt + +m u0 e00-* +#m u1 e01-* +m u2 e02-* +#m u3 e03-* +#m u4 e04-* +m u5 e05-* +m u6 e06-* +m u7 e07-* +#m u8 e08-* +m u9 e09-* +m ux e10-* +#m sh e11-* +#m ini e12-* diff --git a/tools/tap b/tools/tap new file mode 100755 index 0000000..be6545c --- /dev/null +++ b/tools/tap @@ -0,0 +1,11 @@ +#!/bin/sh +# +# build a tape for simh containing the kernel sources +# requires conv2.c to be built + +UNIXDIR=~/work/simh/unix-v7-4/run + +tools/rebuild +(cd rebuilt; gtar -O -cf ../u.tar u?.s) +tools/conv2 -o tape.tm u.tar +cp tape.tm $UNIXDIR