/* 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); } } }
/* Load the program from the executable file. */ void LOAD(BOOLEAN DEBUG_MODE,int *ERROR,FILE *INPUT) { char *RECORD; /* One record from the input stream */ int LENGTH; /* Used to store length of blocks of */ /* memory affected by text and modification*/ /* records */ int LOCATION = 0; /* Location to load next csect */ char MODULE_NAME[LABEL_SIZE_1+1]; /* Name of a module of program. */ MODULE_NAME[LABEL_SIZE_1] = '\0'; if (feof(INPUT)) (*ERROR) = TRUE_1; else { GET_LINE(&RECORD,INPUT); if ((RECORD[0] != 'S') || (strlen(RECORD) != 14)) (*ERROR) = TRUE_1; else { /* ---------------------------- START RECORD ------------------------------- */ if (DEBUG_MODE) { MAIN_ROUTINE[LABEL_SIZE_1] = '\0'; (void) strncpy(MAIN_ROUTINE,&(RECORD[1]),LABEL_SIZE_1); } STR_TO_NUM(&(RECORD[LABEL_SIZE_1+1]), 5, 16, &START_ADDRESS,ERROR); } } while (!feof(INPUT) && (LOCATION <= MEM_SIZE_1) && !(*ERROR)) { GET_LINE(&RECORD,INPUT); switch (RECORD[0]) { case 'T': /* ---------------------------- TEXT RECORD -------------------------------- */ if (strlen(RECORD) < 9) (*ERROR) = TRUE_1; else { STR_TO_NUM(&(RECORD[1]),6,16,&LOCATION,ERROR); STR_TO_NUM(&(RECORD[7]),2,16,&LENGTH,ERROR); if (strlen(RECORD) != 9+LENGTH*2) (*ERROR) = TRUE_1; else STORE_AT(&(RECORD[9]), LENGTH, LOCATION, MEMORY,ERROR); } break; case 'M': /* ---------------------- MODULE RECORD ------------------------------------ */ if (strlen(RECORD) != (13 + LABEL_SIZE_1)) (*ERROR) = TRUE_1; else if (DEBUG_MODE) { (void) strncpy(MODULE_NAME,&(RECORD[1]),LABEL_SIZE_1); STR_TO_NUM(&(RECORD[9]),6,16,&LOCATION,ERROR); (*ERROR) = !INSERT_IN_SYM_TAB(GLOBAL_1,MODULE_NAME,LOCATION,MODULE, &SYM_TAB); STR_TO_NUM(&(RECORD[15]),6,16,&LENGTH,ERROR); (*LOOK_UP_SYMBOL(GLOBAL_1,MODULE_NAME,&SYM_TAB)).LENGTH = LENGTH; } break; case 'G': /* ----------------------- GLOBAL RECORD ----------------------------------- */ if (strlen(RECORD) != (7 + LABEL_SIZE_1)) (*ERROR) = TRUE_1; else if (DEBUG_MODE) { (void) strncpy(MODULE_NAME,&(RECORD[1]),LABEL_SIZE_1); STR_TO_NUM(&(RECORD[9]),6,16,&LOCATION,ERROR); (*ERROR) = !INSERT_IN_SYM_TAB(GLOBAL_1,MODULE_NAME,LOCATION,GLOBAL, &SYM_TAB); } break; case '\0': default: break; } } if (*ERROR) (void) printf("ERROR: Input is not an executable file. Aborting.\n"); }
/* 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"); }