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 >
Wrap
Text File
|
1979-12-31
|
4KB
|
126 lines
/*
** mit.c -- machine instruction table functions
**
** mitndx[] mitptr[] mitnxt[]
** _____ _____ _____
** |__|__| |__|__| |__|__|
** |__|__| |__|__| |__|__|<-+
** hash -> |__|__| -> |__|__| |__|__| |
** |__|__| |__|__| |__|__|--+
** |__|__| |__|__| |__|__|
** |
** V
** mnemonic variant...
** __ |
** |__|...00 vlen optr fmt obj...
** __ _____ _____ __
** format bits (<-) |__| |__|__| |__|__| |__|...
** 3-bit instr length (-1) |
** field types V
** 0 = obj byte operand pattern
** 001 = 8-bit expr __
** 011 = 8-bit pc rel expr |__|...00
** 101 = 16-bit expr
** 111 = 16-bit pc rel expr
**
*/
#include <stdio.h>
#include "mac.h" /* must be included first */
/*
#define NOCCARGC
*/
int
opadj, /* operation code adjustment */
hashval; /* global hash value for speed */
char
expbuf[MAXLINE]; /* buffer for operand expressions */
extern int
mitable, /* machine instruction table (size) */
mitndx[], /* mit indices (hash -> which) */
mitnxt[], /* mit synonym chain */
mitptr[]; /* mnemonic syntax ptrs */
extern char
mitbuf[]; /* instruction syntax buffer */
extern int
looks; /* number of looks to find it */
hash(ptr, cnt) char *ptr; int cnt; { /* calculate hash value */
hashval = 0;
while(*ptr > ' ' && atend(*ptr) == 0)
hashval = (hashval << 1) + toupper(*ptr++);
return (hashval % cnt);
}
find(inst) char *inst; { /* search for instr in mit */
char *mit;
int h, ndx;
looks = 0;
ndx = mitndx[h = hash(inst, MICOUNT)]; /* calc hash index */
while(ndx != EOF) {
++looks;
if(fldcmp(inst, mit = mitptr[ndx]) == 0) { /* mnemonic matches */
inst = skip(2, inst); /* instr operand field */
mit += strlen(mit) + 1; /* first variant */
while(*mit++) { /* another variant? */
++looks;
if(match(inst, getint(mit))) return (mit);
mit += *(mit - 1); /* next variant */
}
return (0);
}
if((h = mitnxt[h]) == EOF) return (0);
ndx = mitndx[h];
}
return (0);
}
match(inst, mit) char *inst, *mit; { /* match operands to mit */
char *backup, *exp; int nest;
opadj = 0;
backup = inst;
if(mit == 0) {
if(atend(*inst)) return (YES);
return (NO);
}
exp = expbuf; /* init expr buffer */
while(YES) {
while(isspace(*inst)) ++inst;
while(isspace(*mit)) ++mit;
if(atend(*inst)) {
if(atend(*mit) || *mit == ANOTHER) return (YES);
goto next;
}
if(atend(*mit)) return (NO);
if(islower(*mit)) { /* expression */
++mit; /* bump past x or y */
nest = 0;
while(!atend(*inst)) { /* bypass expression */
if(*inst == ',') break;
if(*inst == ')' && nest == 0) break;
switch(*inst) {
case '(': ++nest; break;
case ')': --nest;
}
*exp++ = *inst++; /* extract expressions */
}
*exp++ = ','; *exp = NULL; /* terminate expression */
continue;
}
if(lexorder(*inst++, *mit++)) {
next:
while(*mit) {
if(*mit == ANOTHER) { /* end of syntax for this try */
++opadj; /* bump opcode adjustment */
++mit; inst = backup; /* setup next try */
exp = expbuf; /* reset expr buffer pointer */
break;
}
++mit;
}
if(atend(*mit)) return (NO);
}
}
}