home *** CD-ROM | disk | FTP | other *** search
- #include "stdio.h"
- #include "assm.d1"
- #include "assm.d2"
- #include "ctype.h"
-
- /* class 1 machine operations processor - 1 byte, no operand field */
-
- class1()
- {
- if (pass == LAST_PASS) {
- loadlc(loccnt, 0, 1);
- loadv(opval, 0, 1);
- println();
- }
- loccnt++;
- }
-
-
- /* class 2 machine operations processor - 2 byte, relative addressing */
-
- class2(ip)
- int *ip;
- {
-
- if (pass == LAST_PASS) {
- loadlc(loccnt, 0, 1);
- loadv(opval, 0, 1);
- while (prlnbuf[++(*ip)] == ' ');
- if (evaluate(ip) != 0) {
- loccnt += 2;
- return;
- }
- loccnt += 2;
- if ((value -= loccnt) >= -128 && value < 128) {
- loadv(value, 1, 1);
- println();
- }
- else error("Invalid branch address");
- }
- else loccnt += 2;
- }
-
-
- /* class 3 machine operations processor - various addressing modes */
-
- class3(ip)
- int *ip;
- {
- char ch;
- int code;
- int flag;
- int i;
- int ztmask;
-
- while ((ch = prlnbuf[++(*ip)]) == ' ');
- switch(ch) {
- case 0:
- case ';':
- error("Operand field missing");
- return;
- case 'A':
- case 'a':
- if ((ch = prlnbuf[*ip + 1]) == ' ' || ch == 0) {
- flag = ACC;
- break;
- }
- default:
- switch(ch = prlnbuf[*ip]) {
- case '#': case '=':
- flag = IMM1 | IMM2;
- ++(*ip);
- break;
- case '(':
- flag = IND | INDX | INDY;
- ++(*ip);
- break;
- default:
- flag = ABS | ZER | ZERX | ABSX | ABSY | ABSY2 | ZERY;
- }
- if ((flag & (INDX | INDY | ZER | ZERX | ZERY) & opflg) != 0)
- udtype = UNDEFAB;
- if (evaluate(ip) != 0)
- return;
- if (zpref != 0) {
- flag &= (ABS | ABSX | ABSY | ABSY2 | IND | IMM1 | IMM2);
- ztmask = 0;
- }
- else ztmask = ZER | ZERX | ZERY;
- code = 0;
- i = 0;
- while (( ch = prlnbuf[(*ip)++]) != ' ' && ch != 0 && i++ < 4) {
- code *= 8;
- switch(ch) {
- case ')': /* ) = 4 */
- ++code;
- case ',': /* , = 3 */
- ++code;
- case 'X': /* X = 2 */
- case 'x':
- ++code;
- case 'Y': /* Y = 1 */
- case 'y':
- ++code;
- break;
- default:
- flag = 0;
- }
- }
- switch(code) {
- case 0: /* no termination characters */
- flag &= (ABS | ZER | IMM1 | IMM2);
- break;
- case 4: /* termination = ) */
- flag &= IND;
- break;
- case 25: /* termination = ,Y */
- flag &= (ABSY | ABSY2 | ZERY);
- break;
- case 26: /* termination = ,X */
- flag &= (ABSX | ZERX);
- break;
- case 212: /* termination = ,X) */
- flag &= INDX;
- break;
- case 281: /* termination = ),Y */
- flag &= INDY;
- break;
- default:
- flag = 0;
- }
- }
- if ((opflg &= flag) == 0) {
- error("Invalid addressing mode");
- return;
- }
- if ((opflg & ztmask) != 0)
- opflg &= ztmask;
- switch(opflg) {
- case ACC: /* single byte - class 3 */
- if (pass == LAST_PASS) {
- loadlc(loccnt, 0, 1);
- loadv(opval + 8, 0, 1);
- println();
- }
- loccnt++;
- return;
- case ZERX: case ZERY: /* double byte - class 3 */
- opval += 4;
- case INDY:
- opval += 8;
- case IMM2:
- opval += 4;
- case ZER:
- opval += 4;
- case INDX: case IMM1:
- if (pass == LAST_PASS) {
- loadlc(loccnt, 0, 1);
- loadv(opval, 0, 1);
- loadv(value, 1, 1);
- println();
- }
- loccnt += 2;
- return;
- case IND: /* triple byte - class 3 */
- opval += 16;
- case ABSX:
- case ABSY2:
- opval += 4;
- case ABSY:
- opval += 12;
- case ABS:
- if (pass == LAST_PASS) {
- opval += 12;
- loadlc(loccnt, 0, 1);
- loadv(opval, 0, 1);
- loadv(value, 1, 1);
- loadv(value >> 8, 2, 1);
- println();
- }
- loccnt += 3;
- return;
- default:
- error("Invalid addressing mode");
- return;
- }
- }
-
- /* pseudo operations processor */
-
- pseudo(ip)
- int *ip;
- {
- int count;
- int i,j;
- int tvalue;
-
- switch(opval) {
- case 0: /* .byte pseudo */
- labldef(loccnt);
- loadlc(loccnt, 0, 1);
- while (prlnbuf[++(*ip)] == ' '); /* field */
- count = 0;
- do {
- if (prlnbuf[*ip] == '"') {
- while ((tvalue = prlnbuf[++(*ip)]) != '"') {
- if (tvalue == 0) {
- error("Unterminated ASCII string");
- return;
- }
- if (tvalue == '\\')
- switch(tvalue = prlnbuf[++(*ip)]) {
- case 'n':
- tvalue = '\n';
- break;
- case 't':
- tvalue = '\t';
- break;
- }
- loccnt++;
- if (pass == LAST_PASS) {
- loadv(tvalue, count, 1);
- if (++count >= 3) {
- println();
- for (i = 0; i < SFIELD; i++)
- prlnbuf[i] = ' ';
- prlnbuf[i] = 0;
- count = 0;
- loadlc(loccnt, 0, 1);
- }
- }
- }
- ++(*ip);
- }
- else {
- if (evaluate(ip) != 0) {
- loccnt++;
- return;
- }
- loccnt++;
- if (value > 0xff) {
- error("Operand field size error");
- return;
- }
- else if (pass == LAST_PASS) {
- loadv(value, count, 1);
- if (++count >= 3) {
- println();
- for (i = 0; i < SFIELD; i++)
- prlnbuf[i] = ' ';
- prlnbuf[i] = 0;
- count = 0;
- loadlc(loccnt, 0, 1);
- }
- }
- }
- } while (prlnbuf[(*ip)++] == ',');
- if ((pass == LAST_PASS) && (count != 0))
- println();
- return;
- case 1: /* = pseudo */
- while (prlnbuf[++(*ip)] == ' ');
- if (evaluate(ip) != 0)
- return;
- labldef(value);
- if (pass == LAST_PASS) {
- loadlc(value, 1, 0);
- println();
- }
- return;
- case 2: /* .word pseudo */
- labldef(loccnt);
- loadlc(loccnt, 0, 1);
- while (prlnbuf[++(*ip)] == ' ');
- do {
- if (evaluate(ip) != 0) {
- loccnt += 2;
- return;
- }
- loccnt += 2;
- if (pass == LAST_PASS) {
- loadv(value, 0, 1);
- loadv(value>>8, 1, 1);
- println();
- for (i = 0; i < SFIELD; i++)
- prlnbuf[i] = ' ';
- prlnbuf[i] = 0;
- loadlc(loccnt, 0, 1);
- }
- } while (prlnbuf[(*ip)++] == ',');
- return;
- case 3: /* *= pseudo */
- while (prlnbuf[++(*ip)] == ' ');
- if (prlnbuf[*ip] == '*') {
- if (evaluate(ip) != 0)
- return;
- if (undef != 0) {
- error("Undefined symbol in operand field.");
- return;
- }
- tvalue = loccnt;
- }
- else {
- if (evaluate(ip) != 0)
- return;
- if (undef != 0) {
- error("Undefined symbol in operand field.");
- return;
- }
- tvalue = value;
- }
- loccnt = value;
- labldef(tvalue);
- if (pass == LAST_PASS) {
- objcnt = 0;
- loadlc(tvalue, 1, 0);
- println();
- }
- return;
- case 4: /* .list pseudo */
- if (lflag >= 0)
- lflag = 1;
- return;
- case 5: /* .nlst pseudo */
- if (lflag >= 0)
- lflag = iflag;
- return;
- case 6: /* .dbyt pseudo */
- labldef(loccnt);
- loadlc(loccnt, 0, 1);
- while (prlnbuf[++(*ip)] == ' ');
- do {
- if (evaluate(ip) != 0) {
- loccnt += 2;
- return;
- }
- loccnt += 2;
- if (pass == LAST_PASS) {
- loadv(value>>8, 0, 1);
- loadv(value, 1, 1);
- println();
- for (i = 0; i < SFIELD; i++)
- prlnbuf[i] = ' ';
- prlnbuf[i] = 0;
- loadlc(loccnt, 0, 1);
- }
- } while (prlnbuf[(*ip)++] == ',');
- return;
- case 7: /* .page pseudo */
- if (pagesize == 0) return;
- while (prlnbuf[++(*ip)] == ' ');
- if (prlnbuf[(*ip)] == '"')
- {
- i=0;
- while ((tvalue = prlnbuf[++(*ip)]) != '"')
- {
- if (tvalue =='\0') {
- error("Unterminated ASCII string");
- return; }
- titlbuf[i++] = tvalue;
- if (i == titlesize) {
- error("Title too long");
- return; }
- }
- if (i<titlesize) for (j=i; j<titlesize; j++) titlbuf[j]=' ';
- }
- if (lflag > 0) printhead();
- return;
- }
- }
-
- /* evaluate expression */
-
- evaluate(ip)
- int *ip;
- {
- int tvalue;
- int invalid;
- int parflg, value2;
- char ch;
- char op;
- char op2;
-
- op = '+';
- parflg = zpref = undef = value = invalid = 0;
- /* hcj: zpref should reflect the value of the expression, not the value of
- the intermediate symbols
- */
- while ((ch=prlnbuf[*ip]) != ' ' && ch != ')' && ch != ',' && ch != ';') {
- tvalue = 0;
- if (ch == '$' || ch == '@' || ch == '%')
- tvalue = colnum(ip);
- else if (ch >= '0' && ch <= '9')
- tvalue = colnum(ip);
- else if (ch >= 'a' && ch <= 'z')
- tvalue = symval(ip);
- else if (ch >= 'A' && ch <= 'Z')
- tvalue = symval(ip);
- else if ((ch == '_') || (ch == '.'))
- tvalue = symval(ip);
- else if (ch == '*') {
- tvalue = loccnt;
- ++(*ip);
- }
- else if (ch == '\'') {
- ++(*ip);
- tvalue = prlnbuf[*ip] & 0xff;
- ++(*ip);
- }
- else if (ch == '[') {
- if (parflg == 1) {
- error("Too many ['s in expression");
- invalid++;
- }
- else {
- value2 = value;
- op2 = op;
- value = tvalue = 0;
- op = '+';
- parflg = 1;
- }
- goto next;
- }
- else if (ch == ']') {
- if (parflg == 0) {
- error("No matching [ for ] in expression");
- invalid++;
- }
- else {
- parflg = 0;
- tvalue = value;
- value = value2;
- op = op2;
- }
- ++(*ip);
- }
- switch(op) {
- case '+':
- value += tvalue;
- break;
- case '-':
- value -= tvalue;
- break;
- case '/':
- value = (unsigned) value/tvalue;
- break;
- case '*':
- value *= tvalue;
- break;
- case '%':
- value = (unsigned) value%tvalue;
- break;
- case '^':
- value ^= tvalue;
- break;
- case '~':
- value = ~tvalue;
- break;
- case '&':
- value &= tvalue;
- break;
- case '|':
- value |= tvalue;
- break;
- case '>':
- tvalue >>= 8; /* fall through to '<' */
- case '<':
- if (value != 0) {
- error("High or low byte operator not first in operand field");
- }
- value = tvalue & 0xff;
- zpref = 0;
- break;
- default:
- invalid++;
- }
- if ((op=prlnbuf[*ip]) == ' '
- || op == ')'
- || op == ','
- || op == ';')
- break;
- else if (op != ']')
- next: ++(*ip);
- }
- if (parflg == 1) {
- error("Missing ] in expression");
- return(1);
- }
- if (value < 0 || value >= 256) {
- zpref = 1;
- }
- if (undef != 0) {
- if (pass != FIRST_PASS) {
- error("Undefined symbol in operand field");
- invalid++;
- }
- value = 0;
- }
- else if (invalid != 0)
- {
- error("Invalid operand field");
- }
- else {
- /*
- This is the only way out that may not signal error
- */
- if (value < 0 || value >= 256) {
- zpref = 1;
- }
- else {
- zpref = 0;
- }
- }
- return(invalid);
- }
-
- /* collect number operand */
-
- colnum(ip)
- int *ip;
- {
- int mul;
- int nval;
- char ch;
-
- nval = 0;
- if ((ch = prlnbuf[*ip]) == '$')
- mul = 16;
- else if (ch >= '1' && ch <= '9') {
- mul = 10;
- nval = ch - '0';
- }
- else if (ch == '@' || ch == '0')
- mul = 8;
- else if (ch == '%')
- mul = 2;
- while ((ch = prlnbuf[++(*ip)] - '0') >= 0) {
- if (ch > 9) {
- ch -= ('A' - '9' - 1);
- if (ch > 15)
- ch -= ('a' - 'A');
- if (ch > 15)
- break;
- if (ch < 10)
- break;
- }
- if (ch >= mul)
- break;
- nval = (nval * mul) + ch;
- }
- return(nval);
- }
-