home *** CD-ROM | disk | FTP | other *** search
- /*
- ** CMIT.C -- Machine Instruction Table Compiler
- **
- ** Small-Mac Assembler Configuration Utility
- **
- ** Copyright 1985 J. E. hendrix
- **
- ** Usage: CMIT [-C] [-L] [table] [mac]
- **
- ** -C Configure the executable assembler (MAC.COM) with the indicated,
- ** or default, machine instruction table.
- **
- ** -L List the compiled machine instruction table.
- **
- ** table The name of the machine instruction table file in source
- ** format (default 8080.MIT). The default and only allowed
- ** filename extension is MIT. A drive specifier is allowed.
- **
- ** mac Assembler COM file (default MAC.COM). Must have COM extension
- ** to be recognized as such. Need specify only if not on the
- ** default drive or has a different name.
- **
- ** NOTE: If no switches are given, -L is assumed. If any switches
- ** are given, only those actions so specified are taken.
- **
- ** NOTE: After compiling and linking a new MAC.COM, it must be
- ** configured by running this program before it may be executed.
- ** A previously configured MAC.COM may be reconfigured at any time.
- */
- #include <stdio.h>
- #include "mac.h" /* must be included first */
- #include "mit.h"
- #include "notice.h"
-
- #define COMEXT ".COM"
- #define MITEXT ".MIT"
-
- char
- macfn[MAXFN] = "MAC.COM", /* default assembler filename */
- mitfn[MAXFN] = "8080.MIT"; /* default mit filename */
- int
- con, /* configure? */
- list, /* list? */
- looks; /* number of looks to find it */
-
- main(argc, argv) int argc, *argv; {
- char str[MAXFN];
- fputs("Small-Mac MIT Compiler, ", stderr); fputs(VERSION, stderr);
- fputs(CRIGHT1, stderr);
- getsw(argc, argv); /* fetch and remember switches, etc. */
- load();
- if(list) print();
- if(con) config();
- }
-
- /*
- ** configure assembler with machine instruction table
- */
- extern int Uchrpos[];
- config() {
- int fd, sz;
- fd = open(macfn, "r+"); /* must exist */
- Uchrpos[fd] = 3; /* seek to mitable word */
- read(fd, &sz, INTSZ); /* read table size */
- if(sz != mitable) {
- printf("%s MIT is %u Bytes but should be %u\n", macfn, sz, mitable);
- abort(7);
- }
- write(fd, &mitable + 1, mitable);
- if(ferror(fd)) error2(macfn, " - Write Error");
- close(fd);
- }
-
- /*
- ** get switches from command line
- */
- getsw(argc, argv) int argc, *argv; {
- char arg[MAXFN];
- int i, b, len;
- i = 0;
- while(getarg(++i, arg, MAXFN, argc, argv) != EOF) {
- if(arg[0] == '-') {
- if(toupper(arg[1]) == 'C') con = YES;
- else if(toupper(arg[1]) == 'L') list = YES;
- else usage();
- }
- else {
- if(extend(arg, MITEXT, COMEXT))
- strcpy(macfn, arg);
- else strcpy(mitfn, arg);
- }
- }
- if(!con) list = YES;
- }
-
- /*
- ** load table from diskette
- */
- load() {
- char str[MAXLINE], *mitend, *vptr, *last, *ptr, *cp;
- int fd, top, bits, byte, ilen, h, i, j,
- opnd[MIOPNDS], opnds, et, *fptr;
- fd = open(mitfn, "r");
- ptr = mitbuf;
- mitend = mitbuf + (MIBUFSZ - MAXLINE);
- opnds = 0;
- while(fgets(str, MAXLINE, fd)) { /* load operand fields */
- poll(YES);
- cp = skip(3, str); /* skip to operand field */
- if(!isgraph(*cp)) continue; /* no operand to load */
- for(j = 0; j < opnds; ++j) /* already have it? */
- if(fldcmp(cp, opnd[j]) == 0) break;
- if(j < opnds) continue;
- if(ptr > mitend) goto mitovr1;
- opnd[opnds++] = ptr; /* temp operand ptr */
- if(opnds == MIOPNDS) error2(str, "- MIT Operand Overflow");
- while(isgraph(*ptr = *cp++)) ++ptr; /* copy operand field */
- *ptr++ = NULL;
- }
- if(rewind(fd)) error("- Can't Rewind MIT File"); /* 2nd pass */
- last = ptr; *last = NULL;
- top = 0;
- while(fgets(str, MAXLINE, fd)) { /* load mnemonics, etc. */
- poll(YES);
- if(ptr > mitend) {mitovr1: error2(str, "- MIT Buffer Overflow");}
- if(top >= MICOUNT) error("- MIT Mnemonic Overflow");
- cp = skip(2, str); /* skip to mnemonic field */
- if(fldcmp(cp, last)) { /* new mnemonic */
- *ptr++ = 0; /* terminate prior instr */
- mitptr[top++] = last = ptr; /* mnemonic ptr */
- while(isgraph(*ptr = *cp++)) ++ptr; /* copy mnemonic field */
- *ptr++ = NULL;
- }
- vptr = ptr++; *vptr = 2*INTSZ; /* vlen field */
- cp = skip(3, str); /* locate operand */
- if(isgraph(*cp)) { /* has an operand field */
- for(j = 0; j < opnds; ++j)
- if(fldcmp(cp, opnd[j]) == 0) break;
- if(j == opnds) error2(str, "- Can't Find Operand");
- putint(ptr, opnd[j]);
- }
- else putint(ptr, 0); /* has no operand */
- ptr += INTSZ;
- fptr = ptr; ptr += INTSZ; *fptr = 0; /* fmt field */
- bits = 13;
- ilen = -1;
- cp = skip(1, str); /* code field */
- while(isgraph(*cp)) {
- if(islower(*cp)) { /* x1, x2, etc. */
- et = *cp++; /* expr type */
- bits -= 3; *fptr = ((*fptr >> 3) & 8191) + 8192;
- switch(*cp) {
- default: error2(str, "- Bad Expression Specifier");
- case '2': *fptr += 32768; ilen += 2; break;
- case '1': ++ilen;
- }
- if(et == 'p') *fptr += 16384; /* pc relative expr */
- ++cp;
- continue;
- }
- if(isxdigit(*cp)) {
- if((j = xtoi(cp, &byte)) > 2) error2(str, "- Bad Hex Byte");
- cp += j;
- *ptr++ = byte; *vptr += 1;
- --bits; *fptr = ((*fptr >> 1) & 32767);
- ++ilen;
- continue;
- }
- ++cp; /* bump past field separator */
- }
- *fptr >>= bits; /* right adjust format byte */
- *fptr |= ilen & 7; /* and insert instr length */
- }
- *ptr++ = 0; /* terminate prior instr */
- printf(" Operation Codes %5u\n", top);
- printf("Buffer Space Used %5u\n", ptr - mitbuf);
- for(i = 0; i < MICOUNT; ++i) /* init hash indices */
- mitndx[i] = mitnxt[i] = EOF;
- for(i = 0; i < top; ++i) { /* create hash indices - pass 1 */
- poll(YES);
- h = hash(mitptr[i], MICOUNT);
- if(mitndx[h] == EOF) {
- mitndx[h] = i;
- }
- }
- for(i = j = 0; i < top; ++i) { /* create hash indices - pass 2 */
- poll(YES);
- h = hash(mitptr[i], MICOUNT);
- if(mitndx[h] != i) {
- while(mitndx[j] != EOF) ++j; /* must be empty slot */
- mitndx[j] = i;
- while(mitnxt[h] != EOF) h = mitnxt[h];
- mitnxt[h] = j;
- }
- }
- close(fd);
- }
-
- /*
- ** print compiled machine instruction table
- */
- print() {
- int i, k, bak, fd, fmt, len, opcode, holding;
- char lin[MAXLINE], inst[MAXLINE], *ptr, *vptr, *cp;
- fd = open(mitfn, "r");
- while(fgets(lin, MAXLINE, fd)) {
- poll(YES);
- i = 0; cp = skip(2, lin);
- while(isgraph(inst[i++] = *cp++)) ;
- if(inst[i-1] == '\n') inst[i-1] = ' ';
- bak = i;
- cp = skip(3, lin);
- do {
- i = bak;
- while(isgraph(*cp) && *cp != ANOTHER) inst[i++] = *cp++;
- inst[i] = 0;
- if(*cp == ANOTHER) ++cp;
- printf("%-15s ", inst); /* mnemonic */
- if(!(ptr = find(inst)))
- error("- Can't Find Instruction in MIT");
- printf(" (%2u looks) ", looks);
- ptr += INTSZ;
- fmt = getint(ptr); /* ptr -> first code byte */
- ptr += INTSZ;
- len = (fmt & 7) + 1;
- fmt >>= 3;
- holding = NO;
- while(len-- > 0) { /* for each byte of code */
- if(fmt &1) { /* expression */
- if(holding) {
- opcode += opadj;
- opadj = 0;
- holding = NO;
- printf(" %2x", opcode);
- }
- fmt >>= 1;
- switch(fmt & 3) {
- case 0: printf(" x1"); break; /* 1-byte */
- case 1: printf(" p1"); break; /* 1-byte pc rel */
- case 2: printf(" x2"); --len; break; /* 2-byte */
- case 3: printf(" p2"); --len; break; /* 2-byte pc rel */
- }
- fmt >>= 1;
- }
- else { /* code byte */
- if(holding) printf(" %2x", opcode);
- opcode = *ptr++ & 255;
- holding = YES;
- }
- fmt >>=1;
- }
- if(holding) {
- opcode += opadj;
- printf(" %2x", opcode);
- }
- puts("");
- } while(*cp > ' ');
- }
- close(fd);
- }
-
- /*
- ** abort with usage message
- */
- usage() {
- error("Usage: CMIT [-C] [-L] ]table] [mac]");
- }
- }
- close(fd);
- }
-
- /*
- ** abort with usage message
- */
- usage() {
- error("Usage: CMIT [-C] [-L] ]table] [mac]");
-