/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 26-Nov-85 | [1.151] Created * 4-Dec-85 | [1.105] Let compare operation have literal as second operand * 28-Dec-85 | [1.174] Allow implicit d-char on no-operand instructions (WM) * 24-Nov-91 | [1.177] memory.h => automem.h * 24-Nov-91 | [1.177] converted to C6.0 * 24-Nov-91 | [1.177] mach.h => machmem.h * 26-Nov-91 | [1.204] better checking for multiply-defined labels * | use startloc.h * 26-Nov-91 | [1.212] allow for propagation of DC/DCW declarations *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static boolean compare; /* Assembler state */ extern int dot; /* current location counter */ extern int star; /* Value of '*' */ extern int sdot; extern unsigned maxdot; extern unsigned litpool; extern unsigned litoffset; extern FILE * reader; extern char line[81]; extern boolean saw_end; static int lastop = 0; /**************************************************************************** * pass2 * Effect: * Runs pass 2 of the assembler ****************************************************************************/ void pass2() { star = sdot = dot = STARTLOC; maxdot = 0; saw_end = false; lastop = 0; while(true) { /* pass2 loop */ int opindex; if(saw_end) break; readline(); if(feof(reader)) break; if(line[0]=='*') { /* comment */ list_line(); emit_listing(); continue; /* comment card */ } /* comment */ sdot = dot; if(blankop() && lastop != 0) { /* propagate it */ opindex = lastop + 1; } /* propagate it */ else { /* new op */ opindex = opcode_2(); lastop = (optable[opindex].propagate ? opindex : 0); } /* new op */ (*optable[opindex].processor)(opindex,2); check_sym("end of processing line in pass 2"); fix_da(); } /* pass2 loop */ fprintf(stderr,"End of Pass 2\n"); } /**************************************************************************** * label_2 * Effect: * Checks the label in the symbol table. Phase error if different ****************************************************************************/ void label_2() { getlabelval * v; ste * sy; v = getlabel(); if(v != NULL) { /* check label */ if(v->left) { /* indented */ list_err(err_label); return NULL; } /* indented */ sy = lookup(v->name); if(sy==NULL) { /* whoops */ char msg[80]; sprintf(msg,"Pass 2 failed to find label '%s'",v->name); error(err_label,msg); free(v->name); return; } /* whoops */ else if(sy->val != dot || sy->muldef) { /* whoops again */ char msg[80]; #if 0 sprintf(msg,"Pass 2 attempted to redefine label '%s'==%d to %d", v->name,sy->val,dot); #else muldef(sy,NULL); #endif error(err_label,msg); free(v->name); return; } /* whoops again */ } /* check label */ free(v->name); } /**************************************************************************** * opcode_2 * Result: int * Index into opcode table * Effect: * Processes the opcode ****************************************************************************/ int opcode_2() { int i; boolean found = false; compare = false; for(i=0;strlen(optable[i].mnemonic)>0;i++) { /* check op */ found = legal_op(i); if(found) break; } /* check op */ /* Don't bother to report error, reported in pass 1 */ if(!found) { /* punt opcode */ i = 0; list_err(err_opcode); } /* punt opcode */ if(strcmp(optable[i].mnemonic,"C ") == 0) compare = true; return i; } /**************************************************************************** * operands_2 * Inputs: * int opindex: Index of op table * Effect: * Processes the operands field * * noperands options eval as * 0th 1st 2nd * 0 N/A N/A N/A N/A * 1 A expr * 1 A,B expr * 1 A,d dchar * 1 A,B,d expr * 2 A error * 2 A,B expr expr * 2 A,d expr dchar * 2 A,B,d expr expr * 3 A error * 3 A,d error * 3 A,B error * 3 A,B,d expr expr dchar ****************************************************************************/ void operands_2(int opindex) { int i; int noperands; unsigned val1; unsigned val2; char d; noperands = scan_operands(); /* Update the value of '*' */ switch(noperands) { /* noperand decode */ case 0: /* No operands */ if(optable[opindex].d != ' ') { /* implicit d-char */ star++; } /* implicit d-char */ star++; break; case 1: switch(optable[opindex].format) { /* format decode */ /* d */ case op_d: star ++; break; break; /* AAA */ case op_A: star += 3; break; /* III */ case op_I: star += 3; if(optable[opindex].d != ' ') { /* implicit d-char */ star++; } /* implicit d-char */ break; /* AAA d */ case op_A|op_d: star++; break; /* III d */ case op_I|op_d: star++; break; /* AAA BBB */ case op_A|op_B: star += 3; break; /* III BBB */ case op_I|op_B: star += 3; if(optable[opindex].d != ' ') { /* implicit d-char */ star++; } /* implicit d-char */ break; /* AAA BBB d */ case op_A|op_B|op_d: star += 3; break; /* III BBB d */ case op_I|op_B|op_d: star += 3; break; default: printf("operands_2.advance[1]: Format decode error (%d)\n",optable[opindex].format); } /* format decode */ break; case 2: switch(optable[opindex].format) { /* format decode */ /* d */ case op_d: star +=4; break; /* AAA */ case op_A: star += 3; break; /* III */ case op_I: star += 3; if(optable[opindex].d != ' ') { /* implicit d-char */ star++; } /* implicit d-char */ break; /* AAA d */ case op_A|op_d: star += 4; break; /* III d */ case op_I|op_d: star += 4; break; /* AAA BBB */ case op_A|op_B: star += 6; break; /* III BBB */ case op_I|op_B: star += 6; if(optable[opindex].d != ' ') { /* implicit d-char */ star++; } /* implicit d-char */ break; /* AAA BBB d */ case op_A|op_B|op_d: star += 6; break; /* III BBB d */ case op_I|op_B|op_d: star += 6; break; default: printf("operands_2.advance[2]: Format decode error (%d)\n",optable[opindex].format); } /* format decode */ break; case 3: switch(optable[opindex].format) { /* format decode */ /* d */ case op_d: star += 7; break; /* AAA */ case op_A: star += 7; break; /* AAA BBB */ case op_A|op_B: star += 7; break; /* AAA d */ case op_A|op_d: star += 7; break; /* III d */ case op_I|op_d: star += 7; break; /* AAA BBB d */ case op_A|op_B|op_d: star += 7; break; /* III BBB d */ case op_I|op_B|op_d: star += 7; break; default: printf("operands_2.advance[3]: Format decode error (%d)\n",optable[opindex].format); } /* format decode */ break; } /* noperand decode */ /* Now write the operands out */ switch(noperands) { /* noperand decode */ case 0: /* No operands */ if(optable[opindex].d != ' ') { /* implicit d-char */ write_dchar((unsigned char)ascii_to_bcd(optable[opindex].d)); } /* implicit d-char */ break; /* do nothing */ case 1: switch(optable[opindex].format) { /* format decode */ /* d */ case op_d: write_dchar(dchar(operands[0])); break; /* III */ case op_I: /* valid form is 'op III' */ expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); if(optable[opindex].d != ' ') { /* implicit d-char */ write_dchar((unsigned char)ascii_to_bcd(optable[opindex].d)); } /* implicit d-char */ break; /* III d */ case op_I|op_d: /* valid form is 'op d' or 'op AAA,d' */ write_dchar(dchar(operands[0])); break; /* AAA BBB */ case op_A|op_B: /* valid form is 'op AAA' or 'op AAA,BBB' */ expr(operands[0],&val1,true,expr_lit_pool,2,false); write_operand(val1); break; /* III BBB */ case op_I|op_B: /* valid form is 'op AAA' or 'op AAA,BBB' */ expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); if(optable[opindex].d != ' ') { /* implicit d-char */ write_dchar((unsigned char)ascii_to_bcd(optable[opindex].d)); } /* implicit d-char */ break; /* AAA BBB d */ case op_A|op_B|op_d: expr(operands[0],&val1,true,expr_lit_pool,2,false); write_operand(val1); break; /* III BBB d */ case op_I|op_B|op_d: expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); break; default: printf("operands_2.generate[1]: Format decode error (%d)\n",optable[opindex].format); } /* format decode */ break; case 2: switch(optable[opindex].format) { /* format decode */ /* d */ case op_d: error(err_operand,"Too many operands"); dot += 4; break; /* AAA */ case op_A: error(err_operand,"Too many operands"); dot += 3; break; /* III */ case op_I: error(err_operand,"Too many operands"); dot += 3; break; /* AAA d */ case op_A|op_d: expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); write_dchar(dchar(operands[1])); break; /* III d */ case op_I|op_d: expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); write_dchar(dchar(operands[1])); break; /* AAA BBB */ case op_A|op_B: expr(operands[0],&val1,true,expr_lit_pool,2,false); write_operand(val1); expr(operands[1],&val2,true, (compare ? expr_lit_pool : expr_lit_illegal),2, false); write_operand(val2); break; /* III BBB */ case op_I|op_B: expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); expr(operands[1],&val2,true,expr_lit_illegal,2,false); write_operand(val2); if(optable[opindex].d != ' ') { /* implicit d-char */ write_dchar((unsigned char)ascii_to_bcd(optable[opindex].d)); } /* implicit d-char */ break; /* AAA BBB d */ case op_A|op_B|op_d: expr(operands[0],&val1,true,expr_lit_pool,2,false); write_operand(val1); expr(operands[1],&val2,true,expr_lit_illegal,2,false); write_operand(val2); break; /* III BBB d */ case op_I|op_B|op_d: expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); expr(operands[1],&val2,true,expr_lit_illegal,2,false); write_operand(val2); break; default: printf("operands_2.generate[2]: Format decode error (%d)\n",optable[opindex].format); } /* format decode */ break; case 3: switch(optable[opindex].format) { /* format decode */ /* d */ case op_d: dot += 7; break; /* AAA */ case op_A: error(err_operand,"Too many operands"); dot += 7; break; /* AAA BBB */ case op_A|op_B: error(err_operand,"Too many operands"); dot += 7; break; /* III BBB */ case op_I|op_B: error(err_operand,"Too many operands"); dot += 7; break; /* AAA d */ case op_A|op_d: error(err_operand,"Too many operands"); dot += 7; break; /* AAA BBB d */ case op_A|op_B|op_d: expr(operands[0],&val1,true,expr_lit_pool,2,false); write_operand(val1); expr(operands[1],&val2,true,expr_lit_illegal,2,false); write_operand(val2); write_dchar(dchar(operands[2])); break; /* III BBB d */ case op_I|op_B|op_d: expr(operands[0],&val1,true,expr_lit_illegal,2,false); write_operand(val1); expr(operands[1],&val2,true,expr_lit_illegal,2,false); write_operand(val2); write_dchar(dchar(operands[2])); break; default: printf("operands_2.generate[3]: Format decode error (%d)\n",optable[opindex].format); } /* format decode */ break; } /* noperand decode */ }