Blame as10k1/assemble.c

Packit 427e91
/***************************************************************************
Packit 427e91
                          assemble.c  -  Assembles the parsed lines
Packit 427e91
                             -------------------
Packit 427e91
    Date                : May 24 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
#include<string.h>
Packit 427e91
#include<stdio.h>
Packit 427e91
#include<stdlib.h>
Packit 427e91
#include <ctype.h>
Packit 427e91
Packit 427e91
Packit 427e91
#include"types.h"
Packit 427e91
#include"proto.h"
Packit 427e91
Packit 427e91
extern int dbg_opt;
Packit 427e91
extern FILE *listfile;
Packit 427e91
extern char *listing;
Packit 427e91
char type_strings[GPR_TYPE_EQUATE+1][20]={
Packit 427e91
"Input",
Packit 427e91
"Output",
Packit 427e91
"Constant",
Packit 427e91
"Static",
Packit 427e91
"Dynamic",
Packit 427e91
"Control",
Packit 427e91
"Tram Data Reg",
Packit 427e91
"Tram Address/Read",
Packit 427e91
"Tram Address/Write",
Packit 427e91
"Macro arg",
Packit 427e91
"Equate"
Packit 427e91
};
Packit 427e91
Packit 427e91
void op(int op, int z,int  w,int  x,int  y)
Packit 427e91
{
Packit 427e91
	int  w0, w1;
Packit 427e91
        extern int dsp_code[DSP_CODE_SIZE];
Packit 427e91
        extern int ip;
Packit 427e91
        extern char op_codes[35][9];
Packit 427e91
	extern char listtemp[60];
Packit 427e91
	if (ip >= 0x200)
Packit 427e91
		as_exit("to many instructions");
Packit 427e91
	if (op >= 0x10 || op < 0x00)
Packit 427e91
		as_exit("illegal op code");
Packit 427e91
        
Packit 427e91
        //check if gpr is valid, optional do additional modifications
Packit 427e91
	z=declared(z,1);
Packit 427e91
	declared(w,2);
Packit 427e91
	declared(x,3);
Packit 427e91
	declared(y,4);
Packit 427e91
Packit 427e91
        if ( (dbg_opt & DBG_INSTR) !=0  )
Packit 427e91
		printf( "0x%03x\t%s(%d)  \t0x%03x,0x%03x,0x%03x,0x%03x\n",2*ip,op_codes[op],op,z,w,x,y);
Packit 427e91
	if(listing)
Packit 427e91
		sprintf(listtemp, "0x%03x   %-9s(%02d)   0x%03x,0x%03x,0x%03x,0x%03x",2*ip,op_codes[op],op,z,w,x,y);
Packit 427e91
	
Packit 427e91
	w0 = (x << 10) | y;
Packit 427e91
	w1 = (op << 20) | (z << 10) | w;
Packit 427e91
	dsp_code[ip * 2] = w0;
Packit 427e91
	dsp_code[ip * 2 + 1] = w1;
Packit 427e91
	ip++;
Packit 427e91
Packit 427e91
}
Packit 427e91
Packit 427e91
int declared(int operand,int i){
Packit 427e91
Packit 427e91
        struct sym *sym;
Packit 427e91
        extern struct list_head sym_head;
Packit 427e91
        struct list_head *entry;
Packit 427e91
 
Packit 427e91
        
Packit 427e91
       
Packit 427e91
        if ((operand < 0x040)||(operand >= 0x400)){
Packit 427e91
                printf("** Assembler Error with Operand %d:0x%x\n",i,operand);
Packit 427e91
                as_exit("Operand has value out of range");
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
        if((operand < 0x400) && operand >= 0x100)
Packit 427e91
        {
Packit 427e91
                list_for_each(entry,&sym_head){
Packit 427e91
                        sym=list_entry(entry,struct sym,list);
Packit 427e91
                        if( (sym->data.address == operand ) && sym->type!=GPR_TYPE_EQUATE){
Packit 427e91
				if( ( sym->type==GPR_TYPE_CONSTANT) && (i==1) ){
Packit 427e91
					printf("** Assembler Error with Operand %d:0x%x\n",i,operand);
Packit 427e91
					as_exit("** Error: Destination register is a read-only constant");
Packit 427e91
				}
Packit 427e91
				
Packit 427e91
				else if(sym->type!=GPR_TYPE_INPUT)
Packit 427e91
                                        return(operand);
Packit 427e91
                                else
Packit 427e91
                                        return( i==1? operand + 1 : operand);
Packit 427e91
                        }
Packit 427e91
                }
Packit 427e91
                
Packit 427e91
               
Packit 427e91
        }
Packit 427e91
        else if(operand<0x100)
Packit 427e91
                return(operand);
Packit 427e91
        
Packit 427e91
         printf("** Assembler Error with Operand %d:0x%x\n",i,operand);
Packit 427e91
         as_exit("Operand address is undeclared");
Packit 427e91
         return(0);
Packit 427e91
}
Packit 427e91
Packit 427e91
//each operand will be something like :  ,  sym1 + sym2 * sym3 ,
Packit 427e91
//we will recursively decode each symbol and perform proper operations:
Packit 427e91
int arg_decode(char *operand, int prev_val)
Packit 427e91
{
Packit 427e91
        int value;
Packit 427e91
        char oper='0';
Packit 427e91
Packit 427e91
        
Packit 427e91
	//Nothing: 
Packit 427e91
        if(operand==NULL)
Packit 427e91
                as_exit("Parse Error: missing operand(s)");
Packit 427e91
Packit 427e91
        
Packit 427e91
        if(*operand==','||*operand=='\n'||*operand=='\0')
Packit 427e91
                return(prev_val);
Packit 427e91
Packit 427e91
 
Packit 427e91
        //skip over leading blanks(if any):
Packit 427e91
        advance_over_whites(operand);
Packit 427e91
        
Packit 427e91
        if(*operand==','||*operand=='\n' ||*operand=='\0')
Packit 427e91
                return(prev_val);
Packit 427e91
        
Packit 427e91
        //get the operator:
Packit 427e91
        if(*operand=='+' || *operand=='-' || *operand=='/' || *operand== '*'){
Packit 427e91
                oper=*operand;
Packit 427e91
                operand++;
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
        //skip over any blanks after the oper
Packit 427e91
        advance_over_whites(operand);
Packit 427e91
        
Packit 427e91
        //decode the symbol/value:
Packit 427e91
        value=arg_decode2(operand);
Packit 427e91
Packit 427e91
        //advance to next symbol
Packit 427e91
        while( *operand!='+' && *operand!='-' && *operand!='/' && *operand!= '*'  && *operand != '\0'  &&*operand!=',' &&*operand!='\n')
Packit 427e91
                operand++;
Packit 427e91
        
Packit 427e91
        switch (oper){
Packit 427e91
                
Packit 427e91
        case '+':
Packit 427e91
                return(arg_decode(operand,prev_val+value));
Packit 427e91
        case '-':
Packit 427e91
                return(arg_decode(operand,prev_val-value));
Packit 427e91
        case '/':
Packit 427e91
                return(arg_decode(operand,prev_val/value));
Packit 427e91
        case '*':
Packit 427e91
                return(arg_decode(operand,prev_val*value));       
Packit 427e91
        default:
Packit 427e91
                return(arg_decode(operand,value));
Packit 427e91
        
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
}
Packit 427e91
Packit 427e91
//this function does argument decoding
Packit 427e91
int arg_decode2(char *operand)
Packit 427e91
{
Packit 427e91
        extern int ip,ds_addr;
Packit 427e91
        extern unsigned int macro_depth;
Packit 427e91
        struct sym *sym;
Packit 427e91
        extern struct list_head sym_head;
Packit 427e91
        struct list_head *entry;
Packit 427e91
        //printf("operand:%s\n",operand);
Packit 427e91
Packit 427e91
	
Packit 427e91
        if(operand[0]=='.' &&isalpha(operand[1])){
Packit 427e91
                add_symbol(operand,GPR_TYPE_STATIC, ds_addr++, -(long)ip);
Packit 427e91
                return(ds_addr-1);
Packit 427e91
         }
Packit 427e91
Packit 427e91
        
Packit 427e91
        // Hex
Packit 427e91
        if((char)(*operand)=='$')
Packit 427e91
                return((int)strtol(operand+1,NULL,16));
Packit 427e91
	// Octal 
Packit 427e91
        if((char)(*operand)=='@')
Packit 427e91
                return((int)strtol(operand+1,NULL,8));
Packit 427e91
        // Binary:
Packit 427e91
        if((char)(*operand)=='%')
Packit 427e91
                return((int)strtol(operand+1,NULL,2));
Packit 427e91
	// Decimal:
Packit 427e91
        if( (operand[0] >= '0' && operand[0] <='9') ||operand[0]=='-')
Packit 427e91
                return((int)strtol(operand,NULL,10));
Packit 427e91
Packit 427e91
        
Packit 427e91
        
Packit 427e91
        //Symbol:
Packit 427e91
        list_for_each(entry,&sym_head){
Packit 427e91
                sym=list_entry(entry,struct sym,list);
Packit 427e91
                if(symcmp(sym->data.name,operand)==0){
Packit 427e91
                        if(sym->type!=TYPE_MACRO_ARG)
Packit 427e91
                                return(sym->data.address);
Packit 427e91
                        else if(sym->data.value==(macro_depth))
Packit 427e91
                                return(sym->data.address);     
Packit 427e91
                        
Packit 427e91
                }
Packit 427e91
        }
Packit 427e91
               
Packit 427e91
        
Packit 427e91
        
Packit 427e91
        printf("Parse error with operand: \"");
Packit 427e91
        while(!symend(operand))
Packit 427e91
                printf("%c",*(operand++));
Packit 427e91
        printf("\"\n");
Packit 427e91
        as_exit("Bad operand");
Packit 427e91
        
Packit 427e91
        //printf("** Parse error with operand: \"%s\"\n",operand);
Packit 427e91
        as_exit("\"\nOperand isn't a defined symbol or value");
Packit 427e91
        return(0);
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
#define FACTOR 0x7fffffff
Packit 427e91
#define SAMP_FREQ 48000
Packit 427e91
//used by the DC operation to get a long int:
Packit 427e91
long arg2long(char *operand){
Packit 427e91
Packit 427e91
Packit 427e91
	//Nothing: 	
Packit 427e91
        if(operand==NULL)
Packit 427e91
                as_exit("Parse Error: missing operand(s)");
Packit 427e91
	
Packit 427e91
        advance(operand);
Packit 427e91
Packit 427e91
        //Fractional ( -1 <= operand <= 1 )
Packit 427e91
        if(operand[0]=='#')
Packit 427e91
                return((long)(atof(operand+1)*FACTOR));
Packit 427e91
        // Time value
Packit 427e91
        if(operand[0]=='&')
Packit 427e91
                 return((long)(atof(operand+1)*48000));
Packit 427e91
        // Hex:
Packit 427e91
        if((char)(*operand)=='$')
Packit 427e91
                return(strtoul(operand+1,NULL,16));
Packit 427e91
        // Binary:
Packit 427e91
        if((char)(*operand)=='%')
Packit 427e91
                return(strtoul(operand+1,NULL,2));
Packit 427e91
	// Octal:
Packit 427e91
        if((char)(*operand)=='@')
Packit 427e91
                return(strtoul(operand+1,NULL,8));
Packit 427e91
	// Decimal:
Packit 427e91
        if( (operand[0] >= '0' && operand[0] <='9') || operand[0]=='-' || operand[0]=='.'){
Packit 427e91
                if(atof(operand)<1 && atof(operand)>-1)
Packit 427e91
                        return((long)(atof(operand)*FACTOR));
Packit 427e91
                else
Packit 427e91
                        return(strtol(operand,NULL,10));
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
        
Packit 427e91
        printf("Parse error with operand:\"%s\"\n",operand);
Packit 427e91
        //        while(!symend(operand))
Packit 427e91
        //      printf("%c",*operand);
Packit 427e91
        //printf("\"\n");
Packit 427e91
        as_exit("Bad operand");
Packit 427e91
        
Packit 427e91
        return(0);
Packit 427e91
}
Packit 427e91
void update_symbol(char *name,u16 type,u16 address,u32 value){
Packit 427e91
        struct sym *sym;
Packit 427e91
        
Packit 427e91
        
Packit 427e91
        switch(type){
Packit 427e91
                
Packit 427e91
        case TYPE_MACRO_ARG:
Packit 427e91
               
Packit 427e91
                if( issymbol(name,&sym) == -1 ){
Packit 427e91
                        add_symbol(name,type,address,value);
Packit 427e91
                        return;
Packit 427e91
                }
Packit 427e91
Packit 427e91
                if(sym->type!=TYPE_MACRO_ARG){
Packit 427e91
                        printf("Error: with argument:%s",name);
Packit 427e91
                        as_exit("Error:symbol is already defined");
Packit 427e91
                }
Packit 427e91
                sym->data.address=address;
Packit 427e91
                break;
Packit 427e91
        default:
Packit 427e91
                if( issymbol(name,&sym) == -1 ){
Packit 427e91
                        add_symbol(name,type,address,value);
Packit 427e91
                        return;
Packit 427e91
        }
Packit 427e91
                break;  
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
void add_symbol(char *name, u16 type, u16 address, u32 value)
Packit 427e91
{
Packit 427e91
       
Packit 427e91
        extern int gpr_input_count,gpr_output_count,gpr_static_count,gpr_dynamic_count,gpr_control_count,gpr_constant_count;
Packit 427e91
        struct sym *sym;
Packit 427e91
        struct tram *tmp_ptr;
Packit 427e91
        extern struct list_head sym_head;
Packit 427e91
        extern struct delay tram_delay[MAX_TANK_ADDR];
Packit 427e91
        extern struct lookup tram_lookup[MAX_TANK_ADDR];
Packit 427e91
	int tmp;
Packit 427e91
	
Packit 427e91
        
Packit 427e91
        if(name==NULL)
Packit 427e91
                as_exit("Parse Error: This directive requires a label");
Packit 427e91
Packit 427e91
        if(symcmp(name,NO_SYM)!=0 &&type== GPR_TYPE_CONSTANT){
Packit 427e91
		if(issymbol(name,&sym)==0){	
Packit 427e91
			if(sym->data.value != value)
Packit 427e91
				as_exit("Error: Constant redeclared as another value");
Packit 427e91
			else
Packit 427e91
				
Packit 427e91
				return;
Packit 427e91
			}
Packit 427e91
	}
Packit 427e91
	
Packit 427e91
	
Packit 427e91
        if(symcmp(name,NO_SYM)!=0 && type!=TYPE_MACRO_ARG)
Packit 427e91
        {
Packit 427e91
                if(issymbol(name,&sym)!=-1)
Packit 427e91
                        as_exit("Parse Error: Symbol is already defined");
Packit 427e91
                if(ismacro(name)!=-1)
Packit 427e91
                        as_exit("Parse Error: Symbol is already defined as a macro");
Packit 427e91
                if(isalpha(*name)==0 && name[0]!='.')
Packit 427e91
                        as_exit("Parse Error: Symbol must start with a alpha character (a-z)");
Packit 427e91
        }
Packit 427e91
       
Packit 427e91
        switch(type){
Packit 427e91
        case GPR_TYPE_CONTROL:
Packit 427e91
                sym=(struct sym *)malloc(sizeof(struct control));
Packit 427e91
                list_add_tail(&sym->list, &sym_head);
Packit 427e91
                break;
Packit 427e91
        case TYPE_TRAM_ADDR_READ:
Packit 427e91
        case TYPE_TRAM_ADDR_WRITE:
Packit 427e91
                sym=(struct sym *)malloc(sizeof(struct tram));
Packit 427e91
                list_add_tail(&sym->list, &sym_head);
Packit 427e91
                
Packit 427e91
                //if ID is that of a delay:
Packit 427e91
                if((tmp=((struct sym * ) sym->list.prev)->data.value)>0xff){
Packit 427e91
                        tmp=tmp-0x100;
Packit 427e91
                        list_add_tail(&(((struct tram *)sym)->tram) , &(tram_delay[tmp].tram) );
Packit 427e91
                        if(type== TYPE_TRAM_ADDR_READ)
Packit 427e91
                                tram_delay[tmp].read++;   
Packit 427e91
                        else
Packit 427e91
                                tram_delay[tmp].write++;
Packit 427e91
                }else{
Packit 427e91
                        tmp_ptr=(struct tram *)sym;
Packit 427e91
                        list_add_tail(&(((struct tram *)sym)->tram) , &(tram_lookup[tmp].tram) );
Packit 427e91
			tmp_ptr=(struct tram *)sym;
Packit 427e91
                                if(type== TYPE_TRAM_ADDR_READ)
Packit 427e91
                                tram_lookup[tmp].read++;   
Packit 427e91
                        else
Packit 427e91
                                tram_lookup[tmp].write++;
Packit 427e91
                }
Packit 427e91
                break;
Packit 427e91
        default:
Packit 427e91
		
Packit 427e91
		sym=(struct sym *)malloc(sizeof(struct sym));
Packit 427e91
                list_add_tail(&sym->list, &sym_head);
Packit 427e91
		
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
        
Packit 427e91
	
Packit 427e91
        symcpy(sym->data.name,name);
Packit 427e91
        sym->data.address=address;
Packit 427e91
        sym->type=type;
Packit 427e91
        sym->data.value=value;	
Packit 427e91
	//GPR debugging:
Packit 427e91
	if((dbg_opt&DBG_GPR) && type<=GPR_TYPE_CONTROL)
Packit 427e91
		printf("GPR:    %-16s 0x%03x Value=0x%08x, Type: %s\n",name,address,value,type_strings[type] );
Packit 427e91
	
Packit 427e91
	//tram debugging:
Packit 427e91
	else if((dbg_opt&DBG_TRAM && type ==  TYPE_TRAM_DATA))
Packit 427e91
		printf("TRAM Access: %-16s",name);
Packit 427e91
	else if((dbg_opt&DBG_TRAM && type ==  TYPE_TRAM_ADDR_WRITE))
Packit 427e91
		printf(", type: Write, using 0x%03x/0x%03x, offset:0x%07x",address,address-0x100,value );
Packit 427e91
	else if((dbg_opt&DBG_TRAM && type ==  TYPE_TRAM_ADDR_READ))
Packit 427e91
		printf(", type: Read,  using 0x%03x/0x%03x, offset:0x%07x",address,address-0x100,value );
Packit 427e91
	//General Symbol debugging:		
Packit 427e91
	else if((dbg_opt&DBG_SYM )){
Packit 427e91
		printf("symbol: %-16s 0x%03x Type: %s\n",name,address,type_strings[type]);
Packit 427e91
	}
Packit 427e91
	
Packit 427e91
Packit 427e91
	switch(type){
Packit 427e91
        case TYPE_MACRO_ARG:
Packit 427e91
                return;
Packit 427e91
        case GPR_TYPE_INPUT:
Packit 427e91
                gpr_input_count++;
Packit 427e91
                return;
Packit 427e91
        case  GPR_TYPE_OUTPUT:
Packit 427e91
                gpr_output_count++;
Packit 427e91
                return;
Packit 427e91
        case GPR_TYPE_STATIC:
Packit 427e91
                gpr_static_count++;
Packit 427e91
                return;
Packit 427e91
        case GPR_TYPE_DYNAMIC:
Packit 427e91
                gpr_dynamic_count++;
Packit 427e91
                return;
Packit 427e91
        case GPR_TYPE_CONTROL:
Packit 427e91
                gpr_control_count++;
Packit 427e91
                return;
Packit 427e91
	case GPR_TYPE_CONSTANT:
Packit 427e91
		gpr_constant_count++;
Packit 427e91
		return;
Packit 427e91
        default:
Packit 427e91
                return;
Packit 427e91
        }
Packit 427e91
        
Packit 427e91
}
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91
Packit 427e91