home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / smmaclnk.ark / CMIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-10  |  7.9 KB  |  277 lines

  1. /*
  2. ** CMIT.C -- Machine Instruction Table Compiler
  3. **
  4. **    Small-Mac Assembler Configuration Utility
  5. **
  6. **        Copyright 1985 J. E. hendrix
  7. **
  8. ** Usage: CMIT [-C] [-L] [table] [mac]
  9. **
  10. ** -C    Configure the executable assembler (MAC.COM) with the indicated,
  11. **    or default, machine instruction table.
  12. **
  13. ** -L    List the compiled machine instruction table.
  14. **
  15. ** table    The name of the machine instruction table file in source
  16. **        format (default 8080.MIT).  The default and only allowed
  17. **        filename extension is MIT.  A drive specifier is allowed.
  18. **
  19. ** mac        Assembler COM file (default MAC.COM).  Must have COM extension
  20. **        to be recognized as such.  Need specify only if not on the
  21. **        default drive or has a different name.
  22. **
  23. **    NOTE: If no switches are given, -L is assumed.  If any switches
  24. **    are given, only those actions so specified are taken.
  25. **
  26. **    NOTE: After compiling and linking a new MAC.COM, it must be
  27. **    configured by running this program before it may be executed.
  28. **    A previously configured MAC.COM may be reconfigured at any time.
  29. */
  30. #include <stdio.h>
  31. #include "mac.h"    /* must be included first */
  32. #include "mit.h"
  33. #include "notice.h"
  34.  
  35. #define COMEXT    ".COM"
  36. #define MITEXT    ".MIT"
  37.  
  38. char
  39.   macfn[MAXFN] = "MAC.COM",    /* default assembler filename */
  40.   mitfn[MAXFN] = "8080.MIT";    /* default mit filename */
  41. int
  42.   con,        /* configure? */
  43.   list,        /* list? */
  44.   looks;    /* number of looks to find it */
  45.  
  46. main(argc, argv) int argc, *argv; {
  47.   char str[MAXFN];
  48.   fputs("Small-Mac MIT Compiler, ", stderr); fputs(VERSION, stderr);
  49.   fputs(CRIGHT1, stderr);
  50.   getsw(argc, argv);        /* fetch and remember switches, etc. */
  51.   load();
  52.   if(list) print();
  53.   if(con) config();
  54.   }
  55.  
  56. /*
  57. ** configure assembler with machine instruction table
  58. */
  59. extern int Uchrpos[];
  60. config() {
  61.   int fd, sz;
  62.   fd = open(macfn, "r+");    /* must exist */
  63.   Uchrpos[fd] = 3;        /* seek to mitable word */
  64.   read(fd, &sz, INTSZ);        /* read table size */
  65.   if(sz != mitable) {
  66.     printf("%s MIT is %u Bytes but should be %u\n", macfn, sz, mitable);
  67.     abort(7);
  68.     }
  69.   write(fd, &mitable + 1, mitable);
  70.   if(ferror(fd)) error2(macfn, " - Write Error");
  71.   close(fd);
  72.   }
  73.  
  74. /*
  75. ** get switches from command line
  76. */
  77. getsw(argc, argv) int argc, *argv; {
  78.   char arg[MAXFN];
  79.   int i, b, len;
  80.   i = 0;
  81.   while(getarg(++i, arg, MAXFN, argc, argv) != EOF) {
  82.     if(arg[0] == '-') {
  83.       if(toupper(arg[1]) == 'C')    con = YES;
  84.       else if(toupper(arg[1]) == 'L')    list = YES;
  85.       else usage();
  86.       }
  87.     else {
  88.       if(extend(arg, MITEXT, COMEXT))
  89.        strcpy(macfn, arg);
  90.       else strcpy(mitfn, arg);
  91.       }
  92.     }
  93.   if(!con) list = YES;
  94.   }
  95.  
  96. /*
  97. ** load table from diskette
  98. */
  99. load() {
  100.   char str[MAXLINE], *mitend, *vptr, *last, *ptr, *cp;
  101.   int fd, top, bits, byte, ilen, h, i, j,
  102.     opnd[MIOPNDS], opnds, et, *fptr;
  103.   fd = open(mitfn, "r");
  104.   ptr = mitbuf;
  105.   mitend = mitbuf + (MIBUFSZ - MAXLINE);
  106.   opnds = 0;
  107.   while(fgets(str, MAXLINE, fd)) {    /* load operand fields */
  108.     poll(YES);
  109.     cp = skip(3, str);            /* skip to operand field */
  110.     if(!isgraph(*cp)) continue;        /* no operand to load */
  111.     for(j = 0; j < opnds; ++j)        /* already have it? */
  112.       if(fldcmp(cp, opnd[j]) == 0) break;
  113.     if(j < opnds) continue;
  114.     if(ptr > mitend) goto mitovr1;
  115.     opnd[opnds++] = ptr;        /* temp operand ptr */
  116.     if(opnds == MIOPNDS) error2(str, "- MIT Operand Overflow");
  117.     while(isgraph(*ptr = *cp++)) ++ptr;    /* copy operand field */
  118.     *ptr++ = NULL;
  119.     }
  120.   if(rewind(fd)) error("- Can't Rewind MIT File");    /* 2nd pass */
  121.   last = ptr; *last = NULL;
  122.   top = 0;
  123.   while(fgets(str, MAXLINE, fd)) {    /* load mnemonics, etc. */
  124.     poll(YES);
  125.     if(ptr > mitend)    {mitovr1: error2(str, "- MIT Buffer Overflow");}
  126.     if(top >= MICOUNT) error("- MIT Mnemonic Overflow");
  127.     cp = skip(2, str);            /* skip to mnemonic field */
  128.     if(fldcmp(cp, last)) {        /* new mnemonic */
  129.       *ptr++ = 0;            /* terminate prior instr */
  130.       mitptr[top++] = last = ptr;    /* mnemonic ptr */
  131.       while(isgraph(*ptr = *cp++)) ++ptr;    /* copy mnemonic field */
  132.       *ptr++ = NULL;
  133.       }
  134.     vptr = ptr++; *vptr = 2*INTSZ;    /* vlen field */
  135.     cp = skip(3, str);            /* locate operand */
  136.     if(isgraph(*cp)) {            /* has an operand field */
  137.       for(j = 0; j < opnds; ++j)
  138.     if(fldcmp(cp, opnd[j]) == 0) break;
  139.       if(j == opnds) error2(str, "- Can't Find Operand");
  140.       putint(ptr, opnd[j]);
  141.       }
  142.     else putint(ptr, 0);        /* has no operand */
  143.     ptr += INTSZ;
  144.     fptr = ptr; ptr += INTSZ; *fptr = 0;    /* fmt field */
  145.     bits = 13;
  146.     ilen = -1;
  147.     cp = skip(1, str);            /* code field */
  148.     while(isgraph(*cp)) {
  149.       if(islower(*cp)) {        /* x1, x2, etc. */
  150.     et = *cp++;            /* expr type */
  151.     bits -= 3; *fptr = ((*fptr >> 3) & 8191) + 8192;
  152.     switch(*cp) {
  153.        default: error2(str, "- Bad Expression Specifier");
  154.       case '2': *fptr += 32768; ilen += 2; break;
  155.       case '1': ++ilen;
  156.       }
  157.     if(et == 'p') *fptr += 16384;    /* pc relative expr */
  158.     ++cp;
  159.     continue;
  160.     }
  161.       if(isxdigit(*cp)) {
  162.     if((j = xtoi(cp, &byte)) > 2) error2(str, "- Bad Hex Byte");
  163.     cp += j;
  164.     *ptr++ = byte; *vptr += 1;
  165.     --bits; *fptr = ((*fptr >> 1) & 32767);
  166.     ++ilen;
  167.     continue;
  168.     }
  169.       ++cp;                /* bump past field separator */
  170.       }
  171.     *fptr >>= bits;            /* right adjust format byte */
  172.     *fptr |= ilen & 7;            /* and insert instr length */
  173.     }
  174.   *ptr++ = 0;                /* terminate prior instr */
  175.   printf("  Operation Codes %5u\n", top);
  176.   printf("Buffer Space Used %5u\n", ptr - mitbuf);
  177.   for(i = 0; i < MICOUNT; ++i)        /* init hash indices */
  178.     mitndx[i] = mitnxt[i] = EOF;
  179.   for(i = 0; i < top; ++i) {        /* create hash indices - pass 1 */
  180.     poll(YES);
  181.     h = hash(mitptr[i], MICOUNT);
  182.     if(mitndx[h] == EOF) {
  183.       mitndx[h] = i;
  184.       }
  185.     }
  186.   for(i = j = 0; i < top; ++i) {    /* create hash indices - pass 2 */
  187.     poll(YES);
  188.     h = hash(mitptr[i], MICOUNT);
  189.     if(mitndx[h] != i) {
  190.       while(mitndx[j] != EOF) ++j;    /* must be empty slot */
  191.       mitndx[j] = i;
  192.       while(mitnxt[h] != EOF) h = mitnxt[h];
  193.       mitnxt[h] = j;
  194.       }
  195.     }
  196.   close(fd);
  197.   }
  198.  
  199. /*
  200. ** print compiled machine instruction table
  201. */
  202. print() {
  203.   int i, k, bak, fd, fmt, len, opcode, holding;
  204.   char lin[MAXLINE], inst[MAXLINE], *ptr, *vptr, *cp;
  205.   fd = open(mitfn, "r");
  206.   while(fgets(lin, MAXLINE, fd)) {
  207.     poll(YES);
  208.     i = 0; cp = skip(2, lin);
  209.     while(isgraph(inst[i++] = *cp++)) ;
  210.     if(inst[i-1] == '\n') inst[i-1] = ' ';
  211.     bak = i;
  212.     cp = skip(3, lin);
  213.     do {
  214.       i = bak;
  215.       while(isgraph(*cp) && *cp != ANOTHER) inst[i++] = *cp++;
  216.       inst[i] = 0;
  217.       if(*cp == ANOTHER) ++cp;
  218.       printf("%-15s ", inst);        /* mnemonic */
  219.       if(!(ptr = find(inst)))
  220.     error("- Can't Find Instruction in MIT");
  221.       printf(" (%2u looks) ", looks);
  222.       ptr += INTSZ;
  223.       fmt = getint(ptr);        /* ptr -> first code byte */
  224.       ptr += INTSZ;
  225.       len = (fmt & 7) + 1;
  226.       fmt >>= 3;
  227.       holding = NO;
  228.       while(len-- > 0) {        /* for each byte of code */
  229.     if(fmt &1) {            /* expression */
  230.       if(holding) {
  231.         opcode += opadj;
  232.         opadj = 0;
  233.         holding = NO;
  234.         printf(" %2x", opcode);
  235.         }
  236.       fmt >>= 1;
  237.       switch(fmt & 3) {
  238.         case 0: printf(" x1"); break;    /* 1-byte */
  239.         case 1: printf(" p1"); break;    /* 1-byte pc rel */
  240.         case 2: printf(" x2"); --len; break;    /* 2-byte */
  241.         case 3: printf(" p2"); --len; break;    /* 2-byte pc rel */
  242.         }
  243.       fmt >>= 1;
  244.       }
  245.     else {                /* code byte */
  246.       if(holding) printf(" %2x", opcode);
  247.       opcode = *ptr++ & 255;
  248.       holding = YES;
  249.       }
  250.     fmt >>=1;
  251.     }
  252.       if(holding) {
  253.     opcode += opadj;
  254.     printf(" %2x", opcode);
  255.     }
  256.       puts("");
  257.       } while(*cp > ' ');
  258.     }
  259.   close(fd);
  260.   }
  261.  
  262. /*
  263. ** abort with usage message
  264. */
  265. usage() {
  266.   error("Usage: CMIT [-C] [-L] ]table] [mac]");
  267.   }
  268.  }
  269.   close(fd);
  270.   }
  271.  
  272. /*
  273. ** abort with usage message
  274. */
  275. usage() {
  276.   error("Usage: CMIT [-C] [-L] ]table] [mac]");
  277.