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