home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
appleii
/
apxa3.c
/
assm2.c
next >
Wrap
C/C++ Source or Header
|
2018-01-01
|
7KB
|
379 lines
#include "stdio.h"
#include "assm.d1"
#include "assm.d2"
extern int optab[];
extern int step[];
/* translate source line to machine language */
assemble()
{
int flg;
int i; /* prlnbuf pointer */
if ((prlnbuf[SFIELD] == ';') | (prlnbuf[SFIELD] == 0)) {
if (pass == LAST_PASS)
println();
return;
}
lablptr = -1;
i = SFIELD;
udtype = UNDEF;
if (colsym(&i) != 0 && (lablptr = stlook()) == -1)
return;
while (prlnbuf[++i] == ' '); /* find first non-space */
if ((flg = oplook(&i)) < 0) { /* collect operation code */
labldef(loccnt);
if (flg == -1)
error("Invalid operation code");
if ((flg == -2) && (pass == LAST_PASS)) {
if (lablptr != -1)
loadlc(loccnt, 1, 0);
println();
}
return;
}
if (opflg == PSEUDO)
pseudo(&i);
else if (labldef(loccnt) == -1)
return;
else {
if (opflg == CLASS1)
class1();
else if (opflg == CLASS2)
class2(&i);
else class3(&i);
}
}
/****************************************************************************/
/* printline prints the contents of prlnbuf */
println()
{
if (lflag > 0)
fprintf(stdout, "%s\n", prlnbuf);
}
/* colsym() collects a symbol from prlnbuf into symbol[],
* leaves prlnbuf pointer at first invalid symbol character,
* returns 0 if no symbol collected
*/
colsym(ip)
int *ip;
{
int valid;
int i;
char ch;
valid = 1;
i = 0;
while (valid == 1) {
ch = prlnbuf[*ip];
if (ch == '_' || ch == '.');
else if (ch >= 'a' && ch <= 'z');
else if (ch >= 'A' && ch <= 'Z');
else if (i >= 1 && ch >= '0' && ch <= '9');
else if (i == 1 && ch == '=');
else valid = 0;
if (valid == 1) {
if (i < SBOLSZ - 1)
symbol[++i] = ch;
(*ip)++;
}
}
if (i == 1) {
switch (symbol[1]) {
case 'A': case 'a':
case 'X': case 'x':
case 'Y': case 'y':
error("Symbol is reserved (A, X or Y)");
i = 0;
}
}
symbol[0] = i;
return(i);
}
/* symbol table lookup
* if found, return pointer to symbol
* else, install symbol as undefined, and return pointer
*/
stlook()
{
int found;
int hptr;
int j;
int nptr;
int pptr;
int ptr;
hptr = 0;
for (j = 0; j < symbol[0]; j++)
hptr += symbol[j];
hptr %= 128;
ptr = hash_tbl[hptr];
if (ptr == -1) { /* no entry for this link */
hash_tbl[hptr] = nxt_free;
return(stinstal());
}
while (symtab[ptr] != 0) { /* 0 count = end of table */
found = 1;
for (j = 0; j <= symbol[0]; j++) {
if (symbol[j] != symtab[ptr + j]) {
found = 0;
pptr = ptr + symtab[ptr] + 4;
nptr = (symtab[pptr + 1] << 8) + (symtab[pptr] & 0xff);
nptr &= 0xffff;
if (nptr == 0) {
symtab[ptr + symtab[ptr] + 4] = nxt_free & 0xff;
symtab[ptr + symtab[ptr] + 5] = (nxt_free >> 8) & 0xff;
return(stinstal());
}
ptr = nptr;
break;
}
}
if (found == 1)
return(ptr);
}
error("Symbol not found");
return(-1);
}
/* instal symbol into symtab
*/
stinstal()
{
register int j;
register int ptr1;
register int ptr2;
ptr1 = ptr2 = nxt_free;
if ((ptr1 + symbol[0] + 6) >= STABSZ) {
error("Symbol table full");
return(-1);
}
for (j = 0; j <= symbol[0]; j++)
symtab[ptr1++] = symbol[j];
symtab[ptr1] = udtype;
nxt_free = ptr1 + 5;
return(ptr2);
}
/* operation code table lookup
* if found, return pointer to symbol,
* else, return -1
*/
oplook(ip)
int *ip;
{
register char ch;
register int i;
register int j;
int k;
int temp[2];
i = j = 0;
temp[0] = temp[1] = 0;
while((ch=prlnbuf[*ip])!= ' ' && ch!= 0 && ch!= '\t' && ch!= ';') {
if (ch >= 'A' && ch <= 'Z')
ch &= 0x1f;
else if (ch >= 'a' && ch <= 'z')
ch &= 0x1f;
else if (ch == '.')
ch = 31;
else if (ch == '*')
ch = 30;
else if (ch == '=')
ch = 29;
else return(-1);
temp[j] = (temp[j] * 0x20) + (ch & 0xff);
if (ch == 29)
break;
++(*ip);
if (++i >= 3) {
i = 0;
if (++j >= 2) {
return(-1);
}
}
}
if ((j = temp[0]^temp[1]) == 0)
return(-2);
k = 0;
i = step[k] - 3;
do {
if (j == optab[i]) {
opflg = optab[++i];
opval = optab[++i];
return(i);
}
else if (j < optab[i])
i -= step[++k];
else i += step[++k];
} while (step[k] != 0);
return(-1);
}
/* error printing routine */
error(stptr)
char *stptr;
{
loadlc(loccnt, 0, 1);
loccnt += 3;
loadv(0,0,0);
loadv(0,1,0);
loadv(0,2,0);
fprintf(stderr, "%s\n", prlnbuf);
fprintf(stderr, "***** %s\n", stptr);
errcnt++;
}
/* load 16 bit value in printable form into prlnbuf */
loadlc(val, f, outflg)
int val;
int f;
int outflg;
{
int i;
i = 6 + 7*f;
hexcon(4, val);
if (nflag == 0) {
prlnbuf[i++] = hex[3];
prlnbuf[i++] = hex[4];
prlnbuf[i++] = ':';
prlnbuf[i++] = hex[1];
prlnbuf[i] = hex[2];
}
else {
prlnbuf[i++] = hex[1];
prlnbuf[i++] = hex[2];
prlnbuf[i++] = hex[3];
prlnbuf[i] = hex[4];
}
if ((pass == LAST_PASS)&&(oflag != 0)&&(objcnt <= 0)&&(outflg != 0)) {
/* rearrange the next for franklin monitor tm */
fprintf(optr, "\n%c%c%c%c:", hex[1], hex[2], hex[3], hex[4]);
objcnt = 16;
}
}
/* load value in hex into prlnbuf[contents[i]] */
/* and output hex characters to obuf if LAST_PASS & oflag == 1 */
loadv(val,f,outflg)
int val;
int f; /* contents field subscript */
int outflg; /* flag to output object bytes */
{
hexcon(2, val);
prlnbuf[13 + 3*f] = hex[1];
prlnbuf[14 + 3*f] = hex[2];
if ((pass == LAST_PASS) && (oflag != 0) && (outflg != 0)) {
fputc(hex[1], optr);
fputc(hex[2], optr);
fputc(' ', optr); /* add space for franklin monitor tm */
--objcnt;
}
}
/* convert number supplied as argument to hexadecimal in hex[digit] (lsd)
through hex[1] (msd) */
hexcon(digit, num)
int digit;
int num;
{
for (; digit > 0; digit--) {
hex[digit] = (num & 0x0f) + '0';
if (hex[digit] > '9')
hex[digit] += 'A' -'9' - 1;
num >>= 4;
}
}
/* assign <value> to label pointed to by lablptr,
* checking for valid definition, etc.
*/
labldef(lval)
int lval;
{
int i;
if (lablptr != -1) {
lablptr += symtab[lablptr] + 1;
if (pass == FIRST_PASS) {
if (symtab[lablptr] == UNDEF) {
symtab[lablptr + 1] = lval & 0xff;
i = symtab[lablptr + 2] = (lval >> 8) & 0xff;
if (i == 0)
symtab[lablptr] = DEFZRO;
else symtab[lablptr] = DEFABS;
}
else if (symtab[lablptr] == UNDEFAB) {
symtab[lablptr] = DEFABS;
symtab[lablptr + 1] = lval & 0xff;
symtab[lablptr + 2] = (lval >> 8) & 0xff;
}
else {
symtab[lablptr] = MDEF;
symtab[lablptr + 1] = 0;
symtab[lablptr + 2] = 0;
error("Label multiply defined");
return(-1);
}
}
else {
i = (symtab[lablptr + 2] << 8) +
(symtab[lablptr+1] & 0xff);
i &= 0xffff;
if (i != lval && pass == LAST_PASS) {
error("Sync error");
return(-1);
}
}
}
return(0);
}
/* determine the value of the symbol,
* given pointer to first character of symbol in symtab
*/
symval(ip)
int *ip;
{
int ptr;
int svalue;
svalue = 0;
colsym(ip);
if ((ptr = stlook()) == -1)
undef = 1; /* no room error */
else if (symtab[ptr + symtab[ptr] + 1] == UNDEF)
undef = 1;
else if (symtab[ptr + symtab[ptr] + 1] == UNDEFAB)
undef = 1;
else svalue = ((symtab[ptr + symtab[ptr] + 3] << 8) +
(symtab[ptr + symtab[ptr] + 2] & 0xff)) & 0xffff;
if (symtab[ptr + symtab[ptr] + 1] == DEFABS)
zpref = 1;
if (undef != 0)
zpref = 1;
return(svalue);
}