home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / MBUG / MBUG103.ARC / MIT.C < prev    next >
Text File  |  1979-12-31  |  4KB  |  126 lines

  1. /*
  2. ** mit.c -- machine instruction table functions
  3. **
  4. **          mitndx[]     mitptr[]    mitnxt[]
  5. **           _____        _____       _____
  6. **          |__|__|      |__|__|     |__|__|
  7. **          |__|__|      |__|__|     |__|__|<-+
  8. ** hash ->  |__|__|  ->  |__|__|     |__|__|  |
  9. **          |__|__|      |__|__|     |__|__|--+
  10. **          |__|__|      |__|__|     |__|__|
  11. **                          |
  12. **                          V
  13. **                          mnemonic   variant...
  14. **                           __        |   
  15. **                          |__|...00  vlen  optr     fmt    obj...
  16. **                                      __   _____   _____   __
  17. **     format bits (<-)                |__| |__|__| |__|__| |__|...
  18. **       3-bit instr length (-1)               |
  19. **       field types                           V
  20. **         0 = obj byte                        operand pattern
  21. **       001 = 8-bit expr                       __
  22. **       011 = 8-bit pc rel expr               |__|...00
  23. **       101 = 16-bit expr
  24. **       111 = 16-bit pc rel expr
  25. **                          
  26. */
  27. #include <stdio.h>
  28. #include "mac.h"    /* must be included first */
  29. /*
  30. #define NOCCARGC
  31. */
  32. int
  33.   opadj,            /* operation code adjustment */
  34.   hashval;            /* global hash value for speed */
  35. char
  36.   expbuf[MAXLINE];        /* buffer for operand expressions */
  37.  
  38. extern int
  39.   mitable,            /* machine instruction table (size) */
  40.   mitndx[],            /* mit indices (hash -> which) */
  41.   mitnxt[],            /* mit synonym chain */
  42.   mitptr[];            /* mnemonic syntax ptrs */
  43. extern char
  44.   mitbuf[];            /* instruction syntax buffer */
  45.  
  46. extern int
  47.   looks;        /* number of looks to find it */
  48.  
  49. hash(ptr, cnt) char *ptr; int cnt; {        /* calculate hash value */
  50.   hashval = 0;
  51.   while(*ptr > ' ' && atend(*ptr) == 0)
  52.     hashval = (hashval << 1) + toupper(*ptr++);
  53.   return (hashval % cnt);
  54.   }
  55.  
  56. find(inst) char *inst; {            /* search for instr in mit */
  57.   char *mit;
  58.   int h, ndx;
  59.   looks = 0;
  60.   ndx = mitndx[h = hash(inst, MICOUNT)];    /* calc hash index */
  61.   while(ndx != EOF) {
  62.     ++looks;
  63.     if(fldcmp(inst, mit = mitptr[ndx]) == 0) {    /* mnemonic matches */
  64.       inst = skip(2, inst);            /* instr operand field */
  65.       mit += strlen(mit) + 1;            /* first variant */
  66.       while(*mit++) {                /* another variant? */
  67.         ++looks;
  68.         if(match(inst, getint(mit))) return (mit);
  69.         mit += *(mit - 1);            /* next variant */
  70.         }
  71.       return (0);
  72.       }
  73.     if((h = mitnxt[h]) == EOF) return (0);
  74.     ndx = mitndx[h];
  75.     }
  76.   return (0);
  77.   }
  78.  
  79. match(inst, mit) char *inst, *mit; {        /* match operands to mit */
  80.   char *backup, *exp; int nest;
  81.   opadj = 0;
  82.   backup = inst;
  83.   if(mit == 0) {
  84.     if(atend(*inst)) return (YES);
  85.     return (NO);
  86.     }
  87.   exp = expbuf;                    /* init expr buffer */
  88.   while(YES) {
  89.     while(isspace(*inst)) ++inst;
  90.     while(isspace(*mit)) ++mit;
  91.     if(atend(*inst)) {
  92.       if(atend(*mit) || *mit == ANOTHER) return (YES);
  93.       goto next;
  94.       }
  95.     if(atend(*mit)) return (NO);
  96.     if(islower(*mit)) {                /* expression */
  97.       ++mit;                    /* bump past x or y */
  98.       nest = 0;
  99.       while(!atend(*inst)) {            /* bypass expression */
  100.         if(*inst == ',') break;
  101.         if(*inst == ')' && nest == 0) break;
  102.         switch(*inst) {
  103.           case '(': ++nest; break;
  104.           case ')': --nest;
  105.           }
  106.         *exp++ = *inst++;            /* extract expressions */
  107.         }
  108.       *exp++ = ','; *exp = NULL;        /* terminate expression */
  109.       continue;
  110.       }
  111.     if(lexorder(*inst++, *mit++)) {
  112.       next:
  113.       while(*mit) {
  114.         if(*mit == ANOTHER) {        /* end of syntax for this try */
  115.           ++opadj;            /* bump opcode adjustment */
  116.           ++mit; inst = backup;        /* setup next try */
  117.           exp = expbuf;            /* reset expr buffer pointer */
  118.           break;
  119.           }
  120.         ++mit;
  121.         }
  122.       if(atend(*mit)) return (NO);
  123.       }
  124.     }
  125.   }
  126.