/* Process the START pseudo operator. */ void PSEUDO_START(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY; int VALUE; char *START; if (!SEEN_END_OP) { (void) fprintf(OUTPUT_STREAM,"eERROR[27]: Section %s has no 'end'.\n", MODULE_NAME); OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1); LOCATION_EXCEEDS_MEM_SIZE = 0; (void) fprintf(OUTPUT_STREAM,"E\n"); TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,SYM_TAB); (*TABLE_ENTRY).LENGTH = (*LOCATION) - (*TABLE_ENTRY).LOCATION; } if (SEEN_START_OP == SEEN_START_1) (void) fprintf(OUTPUT_STREAM, "eERROR[32]: Multiple STARTs in this file.\n"); SEEN_START_OP = SEEN_START_1; SEEN_END_OP = NO_END_SEEN_1; if (!strcmp(LABEL_NAME,"")) { (void) fprintf(OUTPUT_STREAM,"eERROR[33]: START requires a label.\n"); GET_NEXT_MISSING_LABEL(LABEL_NAME,SYM_TAB); } if (LOOK_UP_SYMBOL(LABEL_NAME,LABEL_NAME,SYM_TAB) != NULL) { (void) fprintf(OUTPUT_STREAM,"eERROR[55]: Multiply defined module name.\n"); (void) strcpy(MODULE_NAME,LABEL_NAME); } else { /* --------------- Modify LABEL_NAMEs symbol table entry to reflect that it */ /* is a module name. */ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB); START = ARGUMENTS; VALUE = GET_NUM(&START,MEM_ADDR_SIZE_1+1,10); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); if (VALUE < 0) (void) fprintf(OUTPUT_STREAM,"eERROR[34]: Negative starting address.\n"); else (*TABLE_ENTRY).LOCATION = VALUE; if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *START); /* ---------------- Indicate that is a module and the MAIN module. */ (void) strcpy( (*TABLE_ENTRY).MODULE, LABEL_NAME); (void) strcpy(MODULE_NAME,LABEL_NAME); (void) strcpy(MAIN_ROUTINE,LABEL_NAME); (*LOCATION) = (*TABLE_ENTRY).LOCATION; (void) fprintf(OUTPUT_STREAM,"s%s\n",MODULE_NAME); } }
/* Process the WORD pseudo operator. */ void PSEUDO_WORD(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { int VALUE; char *START; int ABS_VAL = ABSOLUTE_VALUE_1; START = ARGUMENTS; VALUE = GET_EXPRESSION(&START,BITS_PER_WORD_1,*LOCATION, SYM_TAB,&ABS_VAL); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); (void) fprintf(OUTPUT_STREAM,"t%dW",*LOCATION); PRT_NUM(VALUE,16,6,OUTPUT_STREAM); (void) fprintf(OUTPUT_STREAM,"\n"); CHANGE_LOCATION(LOCATION,3, OUTPUT_STREAM); if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *START); }
/* Process the EQU pseudo operator. */ void PSEUDO_EQU(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { if (!strcmp(LABEL_NAME,"")) (void) fprintf(OUTPUT_STREAM,"eERROR[23]: EQU requires a label.\n"); else { char *START; struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY; int ABS_VAL = ABSOLUTE_VALUE_1; START = ARGUMENTS; TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB); (*TABLE_ENTRY).LOCATION = GET_EXPRESSION(&START,MEM_ADDR_SIZE_1+1,*LOCATION,SYM_TAB,&ABS_VAL); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); (*TABLE_ENTRY).TYPE = ABSOLUTE; if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *START); } }
/* Process the EXTREF pseudo operator. */ void PSEUDO_EXTREF(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { char *START; char DEF_LAB[LABEL_SIZE_1+1]; int ERROR = FALSE_1; char TEMP[LABEL_SIZE_1+1]; if (!strcmp(ARGUMENTS,"")) (void) fprintf(OUTPUT_STREAM,"eERROR[37]: EXTREF requires arguments.\n"); else { START = ARGUMENTS; INITIALIZE_RECORD("R",LABEL_SIZE_1*9+1); /* ----------------------------- Get the list of labels that are externally */ /* defined. Buffer them. */ do { ARGUMENTS = START; GET_LABEL(DEF_LAB,START,&START,pass1); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); if (!strcmp(DEF_LAB,"")) ERROR = 1; else if (!INSERT_IN_SYM_TAB(MODULE_NAME,DEF_LAB,0,EXTERN_REF,SYM_TAB)) ERROR = 2; else { BLANK_STR(TEMP); (void) strncpy(TEMP,DEF_LAB,strlen(DEF_LAB)); ADD_TO_RECORD(TEMP,OUTPUT_STREAM); } START ++; } while (!ERROR && ((*(START-1)) == ',')); PRT_RECORD(OUTPUT_STREAM); if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && !ERROR && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *(START-1)); if (ERROR == 1) (void) fprintf(OUTPUT_STREAM, "eERROR[39]: Invalid list of symbols. Expected symbol found %s.\n", ARGUMENTS); if (ERROR == 2) { *(START-1) = '\0'; (void) fprintf(OUTPUT_STREAM,"eERROR[38]: %s is already defined.\n", ARGUMENTS); } } }
/* Process the RESB pseudo operator. */ void PSEUDO_RESB(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { char *START; int ABS_VAL = ABSOLUTE_VALUE_1; START = ARGUMENTS; CHANGE_LOCATION(LOCATION, GET_EXPRESSION(&START,MEM_ADDR_SIZE_1+1,*LOCATION,SYM_TAB,&ABS_VAL), OUTPUT_STREAM); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *START); }
/* Process the EXTDEF pseudo operator. */ void PSEUDO_EXTDEF(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { char *START; char DEF_LAB[LABEL_SIZE_1+1]; int ERROR = FALSE_1; char TEMP[LABEL_SIZE_1+1]; if (!strcmp(ARGUMENTS,"")) (void) fprintf(OUTPUT_STREAM,"eERROR[40]: EXTDEF requires arguments.\n"); else { START = ARGUMENTS; INITIALIZE_RECORD("d",LABEL_SIZE_1*5+1); /* ------------------ Get the list of label names put in a record buffer */ do { ARGUMENTS = START; GET_LABEL(DEF_LAB,START,&START,pass1); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); if (!strcmp(DEF_LAB,"")) ERROR = TRUE_1; else { BLANK_STR(TEMP); (void) strncpy(TEMP,DEF_LAB,strlen(DEF_LAB)); ADD_TO_RECORD(TEMP,OUTPUT_STREAM); } START ++; } while (!ERROR && ((*(START-1)) == ',')); /* ------------------- Output the define record */ PRT_RECORD(OUTPUT_STREAM); if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && !ERROR && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *(START-1)); if (ERROR == 1) (void) fprintf(OUTPUT_STREAM, "eERROR[39]: Invalid list of symbols. Expected symbol found %s.\n", ARGUMENTS); } }
/* Process the CSECT pseudo operator. */ void PSEUDO_CSECT(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY; if (!SEEN_END_OP) { /* --------- If haven't seen an end, then pretend you did. */ (void) fprintf(OUTPUT_STREAM,"eERROR[27]: Section %s has no 'end'.\n", MODULE_NAME); OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1); LOCATION_EXCEEDS_MEM_SIZE = 0; (void) fprintf(OUTPUT_STREAM,"E\n"); TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,SYM_TAB); (*TABLE_ENTRY).LENGTH = (*LOCATION) - (*TABLE_ENTRY).LOCATION; } SEEN_END_OP = NO_END_SEEN_1; if (!strcmp(LABEL_NAME,"")) { (void) fprintf(OUTPUT_STREAM,"eERROR[26]: CSECT requires a label.\n"); GET_NEXT_MISSING_LABEL(LABEL_NAME,SYM_TAB); } if (LOOK_UP_SYMBOL(LABEL_NAME,LABEL_NAME,SYM_TAB) != NULL) { (void) fprintf(OUTPUT_STREAM,"eERROR[55]: Multiply defined module name.\n"); (void) strcpy(MODULE_NAME,LABEL_NAME); } else { /* --------------- Update symbol to reflect fact that LABEL_NAME is a module */ /* name. */ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB); (*TABLE_ENTRY).LOCATION = 0; (void) strcpy( (*TABLE_ENTRY).MODULE, LABEL_NAME); (void) strcpy(MODULE_NAME,LABEL_NAME); /* ---------------- Reset location counter to zero */ (*LOCATION) = 0; (void) fprintf(OUTPUT_STREAM,"s%s\n",MODULE_NAME); } }
/* Process the END pseudo operator. */ void PSEUDO_END(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION, SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM) { struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY; SEEN_END_OP = END_SEEN_1; if (strcmp(ARGUMENTS,"")) { char OPERAND_LAB[LABEL_SIZE_1+1]; char *START; START = ARGUMENTS; GET_LABEL(OPERAND_LAB,ARGUMENTS,&START,pass1); OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1); if (strcmp(OPERAND_LAB,"")) { /* ----------- End specifies a start adress. */ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY; TABLE_ENTRY = LOOK_UP_SYMBOL(MAIN_ROUTINE,OPERAND_LAB,SYM_TAB); if (TABLE_ENTRY == NULL) (void) fprintf(OUTPUT_STREAM,"eERROR[28]: Label %s not defined.\n", OPERAND_LAB); else if ((*TABLE_ENTRY).TYPE == ABSOLUTE) (void) fprintf(OUTPUT_STREAM, "eERROR[28]: Expected label, found constant %s.\n", OPERAND_LAB); else { /* ---------------- Found an valid end statement. Clear modify buffer. */ OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1); LOCATION_EXCEEDS_MEM_SIZE = 0; (void) fprintf(OUTPUT_STREAM,"E\n"); if (START_ADDRESS == -1) START_ADDRESS = (*TABLE_ENTRY).LOCATION; else (void) fprintf(OUTPUT_STREAM, "eERROR[54]: Multiple starting addresses. Using first.\n"); } if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && (START != ARGUMENTS)) (void) fprintf(OUTPUT_STREAM, "eERROR[13]: Expected a <space> after the operand, found %c.\n", *START); } else (void) fprintf(OUTPUT_STREAM, "eERROR[31]: Expected a Symbol, found %s.\n", ARGUMENTS); } else { /* ------------------ End doesn't specify a start address */ /* Clear modify buffer */ OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1); LOCATION_EXCEEDS_MEM_SIZE = 0; (void) fprintf(OUTPUT_STREAM,"E\n"); } TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,SYM_TAB); (*TABLE_ENTRY).LENGTH = (*LOCATION) - (*TABLE_ENTRY).LOCATION; (void) strcpy(MODULE_NAME,"_"); (*LOCATION) = 0; }
/* Drives the pass1 process, letting others do the real work. */ void PASS1(FILE *INPUT_FILE,SYMBOL_TABLE *SYM_TABLE,FILE *TEMP_OUTPUT_STREAM) { char LABEL_NAME[LABEL_SIZE_1+1]; /* Place to store a label. */ char OPCODE[LABEL_SIZE_1+1]; /* Place to store an opcode. */ char *ARGUMENTS; /* Pointer to arguments/comments */ char *INPUT_LINE; /* Pointer to whole source line */ int EXTENDED_CODE; /* Boolean: Is this an extended */ /* format instruction. */ int LOCATION_COUNTER =0; MODULE_NAME[0] = '_'; MODULE_NAME[1] = '\0'; (void) INSERT_IN_SYM_TAB(MODULE_NAME,MODULE_NAME,0,RELATIVE,SYM_TABLE); MAIN_ROUTINE[0] = '\0'; LABEL_NAME[0] = '\0'; while (!feof(INPUT_FILE)) { /* --------------------- Get the source line and do some parsing */ SCAN_LINE(LOCATION_COUNTER,&INPUT_LINE,LABEL_NAME, &EXTENDED_CODE,OPCODE,&ARGUMENTS,pass1, TEMP_OUTPUT_STREAM,INPUT_FILE); CAPITALIZE_STRING(LABEL_NAME); CAPITALIZE_STRING(OPCODE); CAPITALIZE_STRING(ARGUMENTS); if (( strcmp(LABEL_NAME,"") || strcmp(OPCODE,"") || EXTENDED_CODE) && (SEEN_END_OP == END_SEEN_1) && strcmp(OPCODE,"CSECT") && strcmp(OPCODE,"START")) { (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[30]: Statements following END.\n"); SEEN_END_OP = END_SEEN_WITH_CODE_1; } if (strcmp(LABEL_NAME,"")) if ( LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TABLE) == NULL) { CHANGE_LOCATION(&LOCATION_COUNTER,0,TEMP_OUTPUT_STREAM); if (!LOCATION_EXCEEDS_MEM_SIZE) (void) INSERT_IN_SYM_TAB(MODULE_NAME,LABEL_NAME,LOCATION_COUNTER, RELATIVE,SYM_TABLE); } else (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[6]: %s is a multipy defined label.\n", LABEL_NAME); if (strcmp(OPCODE,"")) { /* --------- Have an OPERATOR. Change location counter depending on format. */ struct OP_ENTRY *OPCODE_INFO; switch ( (*(OPCODE_INFO = LOOK_UP_OP(OPCODE))).FORMAT) { case NOT_FOUND: (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[9]: %s is not a legal OPCODE.\n",OPCODE); break; case ONE: CHANGE_LOCATION(&LOCATION_COUNTER,1,TEMP_OUTPUT_STREAM); if (EXTENDED_CODE) (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[8]: + is an illegal prefix to %s.",OPCODE); break; case TWO: CHANGE_LOCATION(&LOCATION_COUNTER,2,TEMP_OUTPUT_STREAM); if (EXTENDED_CODE) (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[8]: + is an illegal prefix to %s.",OPCODE); break; case THREE_FOUR: if (EXTENDED_CODE) CHANGE_LOCATION(&LOCATION_COUNTER,4,TEMP_OUTPUT_STREAM); else CHANGE_LOCATION(&LOCATION_COUNTER,3,TEMP_OUTPUT_STREAM); break; case PSEUDO: if (EXTENDED_CODE) (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[8]: + is an illegal prefix to %s.",OPCODE); /* ************************************************************************* */ /* The following instruction calls the correct procedure to do what needs to */ /* be done for a particular pseudo operator. The operator table contains */ /* the pointer to the correct routine. */ DO_PSEUDO((*OPCODE_INFO).FUNCTION,LABEL_NAME,ARGUMENTS, &LOCATION_COUNTER,SYM_TABLE,TEMP_OUTPUT_STREAM); break; } } if ((SEEN_END_OP == START_OF_CODE_1) && (strcmp(OPCODE,"") || strcmp(LABEL_NAME,""))) { SEEN_END_OP = NO_END_SEEN_1; (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[35]: No START/CSECT found before statements.\n"); } } OUTPUT_BUFFER(&MOD_REC_BUF,TEMP_OUTPUT_STREAM,1); if (!SEEN_END_OP) (void) fprintf(TEMP_OUTPUT_STREAM, "eERROR[36]: End of File detected without an END statement.\n"); }