/* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
/* Permission to use this code is granted as long as the copyright */
/* notice remains in place. */
/* ============================== pass1.c ================================== */
/* Drives pass1 of the assembler, but lets other routines do the real work   */

#include <stdio.h>
#include <string.h>
#include "assem.h"
#include "scan_line.h"
#include "sym_tab.h"
#include "op_tab.h"
#include "convert.h"
#include "buffer.h"
#include "constants.h"
#include "pseudo.h"

#define START_LEGAL_1            0 /* = May see a START legally              */
#define SEEN_START_1             1 /* = Have seen a START                    */
/* SEND_START_OP                      Global that contains whether or not    */
/*                                    a START operator has been seen         */
int SEEN_START_OP = START_LEGAL_1;


#define NO_END_SEEN_1          0 /* = Haven't seen an END                    */
#define END_SEEN_1             1 /* = Have seen an END but haven't           */
/*                                  found any code after it                  */
#define END_SEEN_WITH_CODE_1   2 /* = Have seen an END and code after it     */
#define START_OF_CODE_1        3 /* = Start of code                          */
/* SEEN_END_OP                       Flag to determine if seen an end since  */
/*                                   start of last module or not. If so it   */
/*                                   also indicated if any code seen since   */
/*                                   end (so only one 'code after end' error */
/*                                   is generated.                           */
int SEEN_END_OP = START_OF_CODE_1;

/* LOCATION_EXCEEDS_MEM_SIZE         Indicates if location counter is greater*/
/*                                   then the memory size.                   */
int LOCATION_EXCEEDS_MEM_SIZE = FALSE_1;

/* -------------------------- CHANGE_LOCATION ------------------------------ */
/* LOCATION = LOCATION + INCREMENT unless this puts LOCATION past MEM_SIZE,  */
/* or if the location has already exceeded the memory size.                  */
void CHANGE_LOCATION(int *LOCATION,int INCREMENT,FILE *OUTPUT)
{
  if (!LOCATION_EXCEEDS_MEM_SIZE)
    if ( ((*LOCATION + INCREMENT) > MEM_SIZE_1) || (*LOCATION == MEM_SIZE_1))
      {
	LOCATION_EXCEEDS_MEM_SIZE = TRUE_1;
	(void) fprintf(OUTPUT,
		       "eERROR[12]: Location exceeds the memory size (%d)\n",
		MEM_SIZE_1);
	(*LOCATION) = MEM_SIZE_1 - 1;
      } else (*LOCATION) += INCREMENT;
}

/* ---------------------- CAPITALIZE_STRING -------------------------------- */
/* Make all lower case letters in the string STR upper case letters          */
void CAPITALIZE_STRING(char STR[])
{
  int I;
  for (I=0; I<= (strlen(STR)); I++)
    if ((STR[I] >= 'a') && (STR[I] <= 'z'))
      STR[I] = STR[I] - 'a' + 'A';
}

/* --------------------------- PASS1 --------------------------------------- */
/* 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");

}
