Blame as10k1/parse.c

Packit 427e91
/***************************************************************************
Packit 427e91
                          parse.c  -  parses each line, stores in temp space
Packit 427e91
                             -------------------
Packit 427e91
    Date                 : May 23 2000
Packit 427e91
    Copyright            : (C) 2000 by Daniel Bertrand
Packit 427e91
    Email                : d.bertrand@ieee.ca
Packit 427e91
 ***************************************************************************/
Packit 427e91
Packit 427e91
/***************************************************************************
Packit 427e91
 *                                                                         *
Packit 427e91
 *   This program is free software; you can redistribute it and/or modify  *
Packit 427e91
 *   it under the terms of the GNU General Public License as published by  *
Packit 427e91
 *   the Free Software Foundation; either version 2 of the License, or     *
Packit 427e91
 *   (at your option) any later version.                                   *
Packit 427e91
 *                                                                         *
Packit 427e91
 ***************************************************************************/
Packit 427e91
Packit 427e91
#include<string.h>
Packit 427e91
#include<stdio.h>
Packit 427e91
#include"types.h"
Packit 427e91
#include"parse.h"
Packit 427e91
#include"proto.h" 
Packit 427e91
Packit 427e91
/*
Packit 427e91
This function parses the asm file calling appropriate functions to blow up macros, include files,
Packit 427e91
define constants, keep track of equates, and handling assembler directives.
Packit 427e91
Packit 427e91
This function is called on a line by line basis.
Packit 427e91
Packit 427e91
normally returns value 0 except when "end" directive is encountered in which case it returns 1,
Packit 427e91
 the "endm" directive which return -1, or the "endfor" deirective which returns -2
Packit 427e91
*/
Packit 427e91
Packit 427e91
extern char type_strings[GPR_TYPE_EQUATE+1][20];
Packit 427e91
extern int dbg_opt;
Packit 427e91
extern char *listing,listtemp[60];
Packit 427e91
extern FILE *listfile;
Packit 427e91
Packit 427e91
int parse( char line_string[MAX_LINE_LENGTH], char *line)
Packit 427e91
{
Packit 427e91
        int tmp,i,arg[4];
Packit 427e91
        static int defmacro=0; //set to 0 unless we're in a macro definition
Packit 427e91
        int op_num;
Packit 427e91
	char  *leading_symbol=NULL, *op_name_ptr,*tmpc;
Packit 427e91
        extern char patch_name[PATCH_NAME_SIZE];
Packit 427e91
	extern int ds_addr,ip,tram_addr,tram_delay_count,tram_table_count;
Packit 427e91
        extern unsigned int macro_depth;
Packit 427e91
     
Packit 427e91
        struct sym *sym;
Packit 427e91
        struct control *control;
Packit 427e91
        
Packit 427e91
        extern struct delay tram_delay[MAX_TANK_ADDR];
Packit 427e91
        extern struct lookup tram_lookup[MAX_TANK_ADDR];
Packit 427e91
	
Packit 427e91
	
Packit 427e91
	if( line_string[0]=='\0' || line_string[0]==';'||line_string[0]=='%'||line_string[0]=='*')
Packit 427e91
	    	return(0);
Packit 427e91
        //remove anything after a ; if one exist
Packit 427e91
        tmpc=line_string;
Packit 427e91
        while( *tmpc !=  ';' &&*tmpc != '\0')
Packit 427e91
                tmpc++;
Packit 427e91
        *tmpc='\0';
Packit 427e91
Packit 427e91
        //check for a leading symbol
Packit 427e91
	if( line_string[0] != ' ' && line_string[0] != '\t'){
Packit 427e91
		
Packit 427e91
		if(strlen(leading_symbol=strtok(line_string,": \t\n"))>MAX_SYM_LEN ){
Packit 427e91
			printf("symbol \"%s\" is more than %d characters long\n",leading_symbol,MAX_SYM_LEN );
Packit 427e91
			as_exit("Parse error");
Packit 427e91
                }
Packit 427e91
		
Packit 427e91
                //address ref for skip command:
Packit 427e91
                if(*leading_symbol=='.'){
Packit 427e91
                        if( issymbol(leading_symbol,&sym)!=-1)
Packit 427e91
                                (sym->data.value)+=ip-1;
Packit 427e91
                }
Packit 427e91
		op_name_ptr=strtok(NULL, " \t\n");  
Packit 427e91
        }else{
Packit 427e91
                op_name_ptr=strtok(line_string, " \t\n");
Packit 427e91
        }
Packit 427e91
                
Packit 427e91
	if(op_name_ptr==NULL)
Packit 427e91
		return(0);
Packit 427e91
Packit 427e91
	        
Packit 427e91
        //check if it a macro:
Packit 427e91
        if((tmp=ismacro(op_name_ptr)) != -1 ){
Packit 427e91
                if(defmacro==0)
Packit 427e91
                        macro_expand(tmp,strtok(NULL,""));
Packit 427e91
			return(0);
Packit 427e91
        }
Packit 427e91
	
Packit 427e91
        if( (op_num=op_decode(op_name_ptr))==-1) {
Packit 427e91
                printf("**Parse Error with op code field \"%s\"\n",op_name_ptr);
Packit 427e91
                as_exit("Parse Error: Bad neumonic");
Packit 427e91
        }
Packit 427e91
	
Packit 427e91
	//check to see if we're defining a macro
Packit 427e91
	if(leading_symbol!=NULL && defmacro!=0 && op_num!=CON && op_num!=CONSTANT)
Packit 427e91
		as_exit("Parse error: Cannot define symbols inside of a macro");
Packit 427e91
                      
Packit 427e91
             
Packit 427e91
        switch(op_num){
Packit 427e91
                
Packit 427e91
        case EQU:
Packit 427e91
                add_symbol(leading_symbol,GPR_TYPE_EQUATE,arg_decode(strtok(NULL, " \t\n"),0),0);
Packit 427e91
                return(0);
Packit 427e91
                
Packit 427e91
        case DS:
Packit 427e91
                printf("**Assembler warning: \"DS\" will be obsoleted\n");
Packit 427e91
        case DYNAMIC:
Packit 427e91
        case DYN:
Packit 427e91
                add_symbol(leading_symbol,GPR_TYPE_DYNAMIC,ds_addr++,0);
Packit 427e91
Packit 427e91
                if( (tmpc=strtok(NULL, " \t\n"))==NULL)
Packit 427e91
                        tmp=0;
Packit 427e91
                else if((tmp=arg_decode(tmpc,0)) <=0)
Packit 427e91
                        tmp=1;
Packit 427e91
                for(i=1;i
Packit 427e91
                        add_symbol( (char *)NO_SYM ,GPR_TYPE_DYNAMIC,ds_addr++,0);
Packit 427e91
Packit 427e91
                }
Packit 427e91
                return(0);
Packit 427e91
        case MACRO:
Packit 427e91
                new_macro(leading_symbol,line,strtok(NULL, "")-line_string+line);
Packit 427e91
                defmacro++;
Packit 427e91
                return(0);                                
Packit 427e91
        case DC:
Packit 427e91
                printf("**Assembler warning: \"DC\" will be obsoleted\n");
Packit 427e91
        case STA:
Packit 427e91
        case STATIC:
Packit 427e91
                tmpc = strtok(NULL, " ,\t\n") ;
Packit 427e91
                
Packit 427e91
                if(tmpc == NULL)
Packit 427e91
                        as_exit("Error DC directive must contain an initial value");
Packit 427e91
                while(tmpc!=NULL ){
Packit 427e91
                        
Packit 427e91
                        if(  tmpc[0] == '&' )
Packit 427e91
                                tmp=arg2long(tmpc)*0x800; //account for 11 bit shift of addresses
Packit 427e91
                        else
Packit 427e91
                                tmp=arg2long(tmpc);
Packit 427e91
Packit 427e91
                        add_symbol(leading_symbol,GPR_TYPE_STATIC,ds_addr++,tmp);
Packit 427e91
Packit 427e91
                        leading_symbol=(char *)NO_SYM;
Packit 427e91
                        
Packit 427e91
			tmpc=strtok(NULL, " ,\t");
Packit 427e91
                }
Packit 427e91
                return(0);
Packit 427e91
Packit 427e91
        case CONSTANT:
Packit 427e91
        case CON:
Packit 427e91
		//declaring constants inside of a macro is legal and needed for branch macros
Packit 427e91
		if(defmacro!=0)
Packit 427e91
			return (0);
Packit 427e91
		
Packit 427e91
Packit 427e91
		tmpc = strtok(NULL, " ,\t\n") ;
Packit 427e91
                
Packit 427e91
                if(tmpc == NULL)
Packit 427e91
                        as_exit("Error Constant directive must contain a value");
Packit 427e91
                while(tmpc!=NULL ){
Packit 427e91
                        
Packit 427e91
                        if(  tmpc[0] == '&' )
Packit 427e91
                                tmp=arg2long(tmpc)*0x800; //account for 11 bit shift of addresses
Packit 427e91
                        else
Packit 427e91
                                tmp=arg2long(tmpc);
Packit 427e91
                        
Packit 427e91
			//     add_constant(leading_symbol,tmp);
Packit 427e91
			
Packit 427e91
			add_symbol(leading_symbol,GPR_TYPE_CONSTANT,ds_addr++,tmp);
Packit 427e91
                        
Packit 427e91
			leading_symbol=(char *)NO_SYM;
Packit 427e91
                        
Packit 427e91
                        tmpc=strtok(NULL, " ,\t");
Packit 427e91
                }
Packit 427e91
		
Packit 427e91
                return(0);
Packit 427e91
        case IO:
Packit 427e91
                add_symbol(leading_symbol,GPR_TYPE_INPUT,ds_addr++,0);
Packit 427e91
                add_symbol(strcat(leading_symbol,".o"),GPR_TYPE_OUTPUT,ds_addr++,0);
Packit 427e91
                return(0);
Packit 427e91
        case DIN:
Packit 427e91
                as_exit("DIN is obsoleted, use IO instead");
Packit 427e91
                add_symbol(leading_symbol,GPR_TYPE_INPUT,ds_addr++,0);
Packit 427e91
                return(0);
Packit 427e91
        case DOUT:
Packit 427e91
                as_exit("DOUT is obsoleted, use IO instead");
Packit 427e91
                        add_symbol(leading_symbol,GPR_TYPE_OUTPUT,ds_addr++,0);
Packit 427e91
                        return(0);
Packit 427e91
        case DD:
Packit 427e91
		add_symbol(leading_symbol,GPR_TYPE_EQUATE,0x100+tram_delay_count,0);
Packit 427e91
		(&tram_delay[tram_delay_count])->size = arg2long( strtok(NULL, " \t\n" ) ) +1;
Packit 427e91
		
Packit 427e91
		INIT_LIST_HEAD( &(tram_delay[tram_delay_count].tram  )  );
Packit 427e91
		strcpy((&tram_delay[tram_delay_count])->name,leading_symbol);
Packit 427e91
		if((dbg_opt&DBG_TRAM))
Packit 427e91
			printf("Delay Line:  %-16s, length: 0x%05x samples,\n",(&tram_delay[tram_delay_count])->name, (&tram_delay[tram_delay_count])->size);
Packit 427e91
		tram_delay_count++;
Packit 427e91
                        return(0);
Packit 427e91
        case DT:
Packit 427e91
                add_symbol(leading_symbol,GPR_TYPE_EQUATE,tram_table_count,0);
Packit 427e91
                (&tram_lookup[tram_table_count])->size = arg2long( strtok(NULL, " \t\n" ) );
Packit 427e91
                INIT_LIST_HEAD(   &(tram_lookup[tram_table_count].tram) );
Packit 427e91
		strcpy((&tram_lookup[tram_table_count])->name,leading_symbol);
Packit 427e91
		
Packit 427e91
		if((dbg_opt&DBG_TRAM))
Packit 427e91
			printf("Lookup table: %-16s, length: 0x%05x samples\n",leading_symbol, (&tram_delay[tram_delay_count])->size);
Packit 427e91
		tram_table_count++;
Packit 427e91
                        return(0);
Packit 427e91
        case DW:
Packit 427e91
                //two symbols are created, "symbol"   ->  addr:0x2xx ; value: tram id #
Packit 427e91
                //                         "symbol.a" ->  addr:0x3xx ; value: write offset
Packit 427e91
		
Packit 427e91
		add_symbol(leading_symbol,TYPE_TRAM_DATA,tram_addr+0x200, arg_decode(tmpc=strtok(NULL, " \t," ),0) );
Packit 427e91
		add_symbol( strcat(leading_symbol,".a") ,TYPE_TRAM_ADDR_WRITE, (tram_addr++)+0x300 ,
Packit 427e91
                            arg2long(strtok(NULL," \t\n")));
Packit 427e91
		if(dbg_opt&DBG_TRAM)
Packit 427e91
			printf(", in segment: \"%s\"\n",tmpc);
Packit 427e91
		
Packit 427e91
		return(0);
Packit 427e91
Packit 427e91
	case DR:
Packit 427e91
		add_symbol(leading_symbol,TYPE_TRAM_DATA,tram_addr+0x200,arg_decode(tmpc=strtok(NULL, " \t," ),0) );
Packit 427e91
		add_symbol(strcat(leading_symbol,".a"),TYPE_TRAM_ADDR_READ,(tram_addr++)+0x300,
Packit 427e91
                           arg2long(strtok(NULL," \t\n")));
Packit 427e91
		if(dbg_opt&DBG_TRAM)
Packit 427e91
			printf(", in segment: \"%s\"\n",tmpc);
Packit 427e91
		return(0);
Packit 427e91
        case CONTROL:
Packit 427e91
			if( (tmpc = strtok(NULL, "\t ,\n")) ==NULL)
Packit 427e91
			    as_exit("Parse Error: missing operand(s)");
Packit 427e91
			    
Packit 427e91
                        if(  tmpc[0] == '&' )
Packit 427e91
                                tmp=arg2long(tmpc)<<11; //account for 11 bit shift of addresses
Packit 427e91
                        else
Packit 427e91
                                tmp=arg2long(tmpc);
Packit 427e91
                        add_symbol(leading_symbol,GPR_TYPE_CONTROL,ds_addr++,tmp);
Packit 427e91
                        issymbol(leading_symbol,(struct sym **)(&control));
Packit 427e91
Packit 427e91
Packit 427e91
                        if( (tmpc = strtok(NULL, "\t ,\n") )==NULL)
Packit 427e91
			    as_exit("Parse Error: missing operand(s)");
Packit 427e91
                       
Packit 427e91
Packit 427e91
                        if(  tmpc[0] == '&' ) 
Packit 427e91
                                control->min=arg2long(tmpc)<<11; //account for 11 bit shift of addresses
Packit 427e91
                        else
Packit 427e91
                                control->min=arg2long(tmpc);
Packit 427e91
			
Packit 427e91
			if( (tmpc = strtok(NULL, "\t ,\n")) ==NULL)
Packit 427e91
			    as_exit("Parse Error: missing operand(s)");
Packit 427e91
Packit 427e91
                       
Packit 427e91
                        if(  tmpc[0] == '&' ) 
Packit 427e91
                                control->max=arg2long(tmpc)<<11; //account for 11 bit shift of addresses
Packit 427e91
                        else
Packit 427e91
                                control->max=arg2long(tmpc);
Packit 427e91
                        
Packit 427e91
                        return(0);
Packit 427e91
        case ENDM:
Packit 427e91
                        if(defmacro==1) {
Packit 427e91
                                defmacro--;
Packit 427e91
                                return(0);
Packit 427e91
                        }else if(macro_depth!=0)
Packit 427e91
                                return(-1);
Packit 427e91
                        else
Packit 427e91
                                as_exit("Error, stray ENDM directive");
Packit 427e91
        case END:
Packit 427e91
                        if(defmacro==1)
Packit 427e91
                                as_exit("Error end directive in macro definition");
Packit 427e91
                        return(1);	
Packit 427e91
        case INCLUDE:
Packit 427e91
                if(defmacro==1)
Packit 427e91
                        as_exit("Error, cannot include file from within macro definition");
Packit 427e91
		if(listing){
Packit 427e91
			sprintf(listtemp,"including file");
Packit 427e91
			fprintf(listfile,"%-50s ||   %s\n",listtemp,line);
Packit 427e91
                }
Packit 427e91
		asm_open(strtok(NULL, "\'\""));
Packit 427e91
		
Packit 427e91
                return(-3);
Packit 427e91
        case NAME:
Packit 427e91
                advance_to_end(op_name_ptr);
Packit 427e91
                op_name_ptr++;
Packit 427e91
                advance_over_whites(op_name_ptr);
Packit 427e91
		if(dbg_opt)
Packit 427e91
			printf("Patch name:%s\n",op_name_ptr);
Packit 427e91
Packit 427e91
		//	printf("%s\n",op_name_ptr);
Packit 427e91
                tmpc=strtok(op_name_ptr,"\"");
Packit 427e91
                if(tmpc==NULL)
Packit 427e91
                        as_exit("Bad name string, did you remember quotes\"\"");
Packit 427e91
                if(strlen(tmpc)>PATCH_NAME_SIZE)
Packit 427e91
                        as_exit("Error Patch name exceeds maximum allowed amount (16)");
Packit 427e91
		memset(patch_name,0,PATCH_NAME_SIZE);
Packit 427e91
                strcpy(patch_name,tmpc);
Packit 427e91
                return(0);
Packit 427e91
        case FOR:
Packit 427e91
		if(listing){
Packit 427e91
			sprintf(listtemp,"FOR LOOP");
Packit 427e91
			fprintf(listfile,"%-50s ||   %s\n",listtemp,line);
Packit 427e91
                }
Packit 427e91
                for_handler(line,strtok(NULL,""));
Packit 427e91
		
Packit 427e91
                return(-3);
Packit 427e91
        case ENDFOR:
Packit 427e91
		sprintf(listtemp,"FOR LOOP DONE");
Packit 427e91
                return(-2);
Packit 427e91
        default:
Packit 427e91
                
Packit 427e91
                if(defmacro==0){
Packit 427e91
			
Packit 427e91
                        for(i=0;i<=3;i++)
Packit 427e91
                                arg[i]=arg_decode(strtok(NULL,","),0);
Packit 427e91
                        op(op_num,arg[0],arg[1],arg[2],arg[3]);
Packit 427e91
                        return(0);
Packit 427e91
Packit 427e91
                }else
Packit 427e91
                        return(0);
Packit 427e91
        }
Packit 427e91
        return(0);
Packit 427e91
}
Packit 427e91
//assembly-time for loop handling:
Packit 427e91
void for_handler(char *begin, char *operand )
Packit 427e91
{
Packit 427e91
        char *ptr,*next,*line,string[MAX_LINE_LENGTH];
Packit 427e91
        int start,end,i,done;
Packit 427e91
        int diff, incr=1;
Packit 427e91
        struct sym *sym;
Packit 427e91
        
Packit 427e91
        ptr=strtok(operand,"=");
Packit 427e91
Packit 427e91
        start= arg_decode(strtok(NULL,":"),0);
Packit 427e91
        end  = arg_decode(strtok(NULL," \t"),0);
Packit 427e91
Packit 427e91
        
Packit 427e91
        if(end>start)
Packit 427e91
                diff=end-start;
Packit 427e91
        else{
Packit 427e91
                diff=start-end;
Packit 427e91
                incr=-1;
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
        if( (issymbol(ptr,&sym))!=-1)
Packit 427e91
                sym->data.address=start;
Packit 427e91
        else
Packit 427e91
                add_symbol(ptr,GPR_TYPE_EQUATE, start,0);
Packit 427e91
        
Packit 427e91
        issymbol(ptr,&sym);
Packit 427e91
        
Packit 427e91
        
Packit 427e91
        while(*begin!='\0')
Packit 427e91
                begin++;
Packit 427e91
        begin++;
Packit 427e91
        
Packit 427e91
        for(i=0;i
Packit 427e91
                next=begin;
Packit 427e91
                line=next;
Packit 427e91
                done=0;
Packit 427e91
                
Packit 427e91
                while(done==0)
Packit 427e91
                {
Packit 427e91
                        while((*next!= '\n') )
Packit 427e91
                                next++;
Packit 427e91
			listtemp[0]='\0';
Packit 427e91
                        *next='\0';
Packit 427e91
                        if(strlen(line)>MAX_LINE_LENGTH)
Packit 427e91
                                as_exit("Parse error: Line exceeds allowable limit");
Packit 427e91
                        strcpy(&string[0],line);
Packit 427e91
                        //printf("%s\n",string);
Packit 427e91
                        done=parse(string, line);
Packit 427e91
			if(listing)
Packit 427e91
				if(done!=-2)
Packit 427e91
					fprintf(listfile,"%-50s ||   %s\n",listtemp,line);
Packit 427e91
                        *next='\n';
Packit 427e91
                        if(done==-2)
Packit 427e91
                                break;
Packit 427e91
                        next++;
Packit 427e91
                
Packit 427e91
                
Packit 427e91
                        line=next;          
Packit 427e91
                }
Packit 427e91
                sym->data.address = start+(incr*(i+1));
Packit 427e91
               
Packit 427e91
        }
Packit 427e91
Packit 427e91
	
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
int op_decode(char *op_name_ptr)
Packit 427e91
{
Packit 427e91
	int op_num;
Packit 427e91
Packit 427e91
	for(op_num=0;op_num
Packit 427e91
      		if( strcasecmp(&op_codes[op_num][0],op_name_ptr) == 0 )
Packit 427e91
			return(op_num);
Packit 427e91
    	}
Packit 427e91
	return(-1);
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
//check if a symbol is used and returns it's pointer value in sym 
Packit 427e91
//normally returns 0, if symbol is non exitant, return -1
Packit 427e91
Packit 427e91
int issymbol(char *symbol,struct sym **sym)
Packit 427e91
{
Packit 427e91
        extern unsigned int macro_depth;
Packit 427e91
        extern struct list_head sym_head;
Packit 427e91
        struct list_head *entry;
Packit 427e91
Packit 427e91
        
Packit 427e91
        list_for_each(entry,&sym_head){
Packit 427e91
                (*sym)=list_entry(entry,struct sym,list);
Packit 427e91
                if(symcmp((char *)&(*sym)->data.name,symbol)==0){
Packit 427e91
                        if((*sym)->type!=TYPE_MACRO_ARG)
Packit 427e91
                                return(0);
Packit 427e91
                        else if( (*sym)->data.value==(macro_depth+1) )
Packit 427e91
                                return(0);
Packit 427e91
                }
Packit 427e91
                
Packit 427e91
                        
Packit 427e91
        }
Packit 427e91
  
Packit 427e91
        return(-1);
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
//compares to words, the words can be terminated with a ' ', '\t',  ',' or '\0'
Packit 427e91
int symcmp (char *symbol1,char *symbol2)
Packit 427e91
{
Packit 427e91
Packit 427e91
        
Packit 427e91
        while(1){
Packit 427e91
                if(*symbol1!=*symbol2)
Packit 427e91
                        return(-1);
Packit 427e91
                symbol1++;
Packit 427e91
                symbol2++;
Packit 427e91
                
Packit 427e91
                if(symend(symbol1) && symend(symbol2))
Packit 427e91
                        return(0);
Packit 427e91
                
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
        
Packit 427e91
}
Packit 427e91
Packit 427e91
//copies a symbol, symbols can be terminated with a ' ' ,  '\t' ,  ','  ,  '\n'  ,  a '\0'
Packit 427e91
void symcpy (char *dest, char *source)
Packit 427e91
{  int i=0;
Packit 427e91
        for(i=0;i<=MAX_SYM_LEN;i++){
Packit 427e91
                if(source[i]== ' ' || source[i]=='\0' ||source[i]==',' ||source[i]=='\n' || source[i]=='\t'  ) {
Packit 427e91
                        dest[i]='\0';
Packit 427e91
                        return;
Packit 427e91
                }
Packit 427e91
                dest[i]=source[i];
Packit 427e91
        }
Packit 427e91
        as_exit("Error, Maximum symbol length exceeded");
Packit 427e91
       
Packit 427e91
       
Packit 427e91
}