예제 #1
0
파일: masm.c 프로젝트: jeapostrophe/mic1
void generate_first_pass() {
    int tok = 0, i = 0;
    unsigned short temp = 0;
    int  label_pc = -1;

    while( (tok=yylex()) ) {
        switch(tok) {
        case LODD:
            emit_label_op(12, "LODD", "0000");
            break;
        case STOD:
            emit_label_op(12, "STOD", "0001");
            break;
        case ADDD:
            emit_label_op(12, "ADDD", "0010");
            break;
        case SUBD:
            emit_label_op(12, "SUBD", "0011");
            break;
        case JPOS:
            emit_label_op(12, "JPOS", "0100");
            break;
        case JZER:
            emit_label_op(12, "JZER", "0101");
            break;
        case JUMP:
            emit_label_op(12, "JUMP", "0110");
            break;
        case LOCO:
            emit_label_op(12, "LOCO", "0111");
            break;
        case LODL:
            emit_int_op(12, "LODL", "1000");
            break;
        case STOL:
            emit_int_op(12, "STOL", "1001");
            break;
        case ADDL:
            emit_int_op(12, "ADDL", "1010");
            break;
        case SUBL:
            emit_int_op(12, "SUBL", "1011");
            break;
        case JNEG:
            emit_label_op(12, "JNEG", "1100");
            break;
        case JNZE:
            emit_label_op(12, "JNZE", "1101");
            break;
        case CALL:
            emit_label_op(12, "CALL", "1110");
            break;
        case PSHI:
            emit_fixed_op( 0, "PSHI", "1111000");
            break;
        case POPI:
            emit_fixed_op( 0, "POPI", "1111001");
            break;
        case PUSH:
            emit_fixed_op( 0, "PUSH", "1111010");
            break;
        case  POP:
            emit_fixed_op( 0,  "POP", "1111011");
            break;
        case RETN:
            emit_fixed_op( 0, "RETN", "1111100");
            break;
        case SWAP:
            emit_fixed_op( 0, "SWAP", "1111101");
            break;
        case INSP:
            emit_int_op( 8, "INSP", "11111100");
            break;
        case DESP:
            emit_int_op( 8, "DESP", "11111110");
            break;
        case HALT:
            emit_fixed_op( 0, "HALT", "11111111");
            break;

        case INTEG:
            str_16(yytext);
            fprintf(p1,"%d  %.16s\n", pc, cstr_16);
            break;

        case LABEL:
            if (label_pc == pc) {   /* for < lbx: lby: >   */
                fprintf(p1,"%d  U0000000000000000    %s\n", pc, yytext);
                break;
            }
            search_sym_table(yytext);
            update_sym_table(yytext);
            label_pc = pc;
            pc--;
            break;

        case LOC:
            require_int(12, ".LOC");
            if((temp = ((unsigned short)atoi(yytext) )) < pc) {
                fprintf(stderr,"Bad operand after .LOC is %s, TOO SMALL !\n",yytext);
                exit(1);
            }
            pc = temp - 1;
            break;

        case STR:
            i=1;
            do {
                if(*(yytext+i) == '\"') {
                    bstr_16(0);
                    fprintf(p1,"%d  %.16s\n", pc, cstr_16);
                    break;
                }
                temp = (unsigned short)*(yytext+i++);
                if(*(yytext+i) != '\"') {
                    temp = (temp | ((unsigned short)*(yytext+i) << 8));
                }
                bstr_16(temp);
                fprintf(p1,"%d  %.16s\n", pc, cstr_16);
            } while (*(yytext+i++) != '\"' && ++pc);
            break;

        case JUNK:
            fprintf(stderr,"Unrecognized token is %s\n",yytext);
            exit(26);

        default:
            fprintf(stderr,"Default case, unrecoverable error\n");
            exit(26);
        }
        pc++;
    }
}
예제 #2
0
int  main(int argc, char *argv[])
{
  int tok, i, dump_tab=0, linum=0;
  unsigned short temp;

  // if -s is included on masm command, set up to
  // dump the symbol table after the binary code
  if(argc > 1 && (strcmp(argv[1], "-s") == 0)) dump_tab = linum = 1;

  p1 = fopen("/tmp/passone", "w+");
  unlink("/tmp/passone");
  while(tok=yylex()){
    switch(tok){
    case LODD:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0000%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0000000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after LODD is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case STOD:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0001%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0001000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after STOD is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case ADDD:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0010%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0010000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after ADDD is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case SUBD:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0011%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0011000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after SUBD is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case JPOS:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0100%s\n",  pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0100000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after JPOS is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case JZER:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0101%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0101000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after JZER is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case JUMP:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  0110%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0110000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after JUMP is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case LOCO:  switch(tok=yylex()){
      case INTEG: 
	if(yytext[0] == '-'){
	  fprintf(stderr,"Negative operand after LOCO is %s on line %d, must be positive !\n",yytext, pc);
	  exit(1);
	}
	str_12(yytext);
	fprintf(p1,"%d  0111%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U0111000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after LOCO is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;


    case LODL:  if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after LODL is %s\n",yytext);
	exit(1);
      }
      str_12(yytext);
      fprintf(p1,"%d  1000%s\n", pc, cstr_12);
      break;

    case STOL:  if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after STOL is %s\n",yytext);
	exit(1);
      }
      str_12(yytext);
      fprintf(p1,"%d  1001%s\n", pc, cstr_12);
      break;

    case ADDL:  if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after ADDL is %s\n",yytext);
	exit(1);
      }
      str_12(yytext);
      fprintf(p1,"%d  1010%s\n",  pc, cstr_12);
      break;

    case SUBL:  if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after SUBL is %s\n",yytext);
	exit(1);
      }
      str_12(yytext);
      fprintf(p1,"%d  1011%s\n", pc, cstr_12);
      break;

    case JNEG: switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  1100%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U1100000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after JNEG is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case JNZE: switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  1101%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U11010000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after JNZE is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case CALL:  switch(tok=yylex()){
      case INTEG: 
	str_12(yytext);
	fprintf(p1,"%d  1110%s\n", pc, cstr_12);
	break;
      case LABEL:
	fprintf(p1,"%d  U1110000000000000    %s\n", pc, yytext);
	break;
      default:
	fprintf(stderr,"Bad operand after CALL is %s on line %d\n",yytext, pc);
	exit(1);
      }
      break;

    case PSHI: fprintf(p1,"%d  1111000000000000\n",pc);
      break;

    case POPI: fprintf(p1,"%d  1111001000000000\n",pc);
      break;

    case PUSH: fprintf(p1,"%d  1111010000000000\n",pc);
      break;

    case POP: fprintf(p1,"%d  1111011000000000\n",pc);
      break;

    case RETN: fprintf(p1,"%d  1111100000000000\n",pc);
      break;

    case SWAP: fprintf(p1,"%d  1111101000000000\n",pc);
      break;

    case INSP: if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after INSP is %s\n",yytext);
	exit(1);
      }
      str_8(yytext);
      fprintf(p1,"%d  11111100%s\n", pc, cstr_8);
      break;

    case DESP: if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after DESP is %s\n",yytext);
	exit(1);
      }
      str_8(yytext);
      fprintf(p1,"%d  11111110%s\n",  pc, cstr_8);
      break;

    case HALT: fprintf(p1,"%d  1111111111000000\n",pc);
      break;

      // case for MULT
    case MULT: if((tok=yylex()) != INTEG){ //trips if issue with mult call
	fprintf(stderr,"Bad operand after MULT is %s\n",yytext);  
	exit(1); 
      } 
      str_6(yytext); //otherwise the bits are written
      fprintf(p1,"%d 1111111100%s\n", pc, cstr_6); 
      break;

      //case for RSHIFT
    case RSHIFT: if((tok=yylex()) != INTEG){ // trips if issues with rshift call
	fprintf(stderr,"Bad operand after RSHIFT is %s\n",yytext);
	exit(1);
      }
      str_6(yytext); //else bits are written
      fprintf(p1,"%d  1111111101%s\n",  pc, cstr_6);
      break;
   
    case DIV: fprintf(p1,"%d 1111111110000000\n",pc); // case for DIV
      break; //no error case for div, takes no input from .asm all from stack


    case INTEG:  str_16(yytext);
      fprintf(p1,"%d  %s\n", pc, cstr_16);
      break;

    case LABEL:  if (label_pc == pc){/* for < lbx: lby: >   */
	fprintf(p1,"%d  U0000000000000000    %s\n", pc, yytext);
	break;
      }
      search_sym_table(yytext);
      update_sym_table(yytext);
      label_pc = pc;
      pc--;
      break;


    case LOC:  if((tok=yylex()) != INTEG){
	fprintf(stderr,"Bad operand after .LOC is %s\n",yytext);
	exit(1);
      }
      if((temp = ((unsigned short)atoi(yytext) )) < pc){
	fprintf(stderr,"Bad operand after .LOC is %s, TOO SMALL !\n",yytext);
	exit(1);
      }

      pc = temp - 1;
      break;

    case STR:  i=1;
      do{
	if(*(yytext+i) == '\"'){
	  bstr_16(0);
	  fprintf(p1,"%d  %s\n", pc, binstr_16);
	  break;
	}
	temp = (unsigned short)*(yytext+i++);
	if(*(yytext+i) != '\"'){
	  temp = (temp | ((unsigned short)*(yytext+i) << 8));
	}
	bstr_16(temp);
	fprintf(p1,"%d  %s\n", pc, binstr_16);
      }while(*(yytext+i++) != '\"' && ++pc);
      break;


    case JUNK:  fprintf(stderr,"Unrecognized token is %s\n",yytext);
      exit(26);

    default:  fprintf(stderr,"Default case, unrecoverable error\n");
      exit(26); 
    } // end while
    pc++;
  } // end switch
   
  generate_code(linum);

  if(dump_tab)dump_table();

  return;

} // end main