mirror of
				https://github.com/alsa-project/alsa-tools.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	
		
			
	
	
		
			547 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			547 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/***************************************************************************
							 | 
						||
| 
								 | 
							
								                          as10k1.c  -  Main assembler routine
							 | 
						||
| 
								 | 
							
								                             -------------------
							 | 
						||
| 
								 | 
							
								    Date                 : May 22, 2000
							 | 
						||
| 
								 | 
							
								    Copyright            : (C) 2000 by Daniel Bertrand
							 | 
						||
| 
								 | 
							
								    Email                : d.bertrand@ieee.ca
							 | 
						||
| 
								 | 
							
								 ***************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * This program was changed to conform the ALSA ideas. Please,
							 | 
						||
| 
								 | 
							
								 * bug reports and all other things should be discussed on the
							 | 
						||
| 
								 | 
							
								 * <alsa-devel@alsa-project.org> mailing list.
							 | 
						||
| 
								 | 
							
								 *                                   Jaroslav Kysela <perex@suse.cz>
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/***************************************************************************
							 | 
						||
| 
								 | 
							
								 *                                                                         *
							 | 
						||
| 
								 | 
							
								 *   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<stdio.h>
							 | 
						||
| 
								 | 
							
								#include<stdlib.h>
							 | 
						||
| 
								 | 
							
								#include<fcntl.h>
							 | 
						||
| 
								 | 
							
								#include <sys/stat.h>
							 | 
						||
| 
								 | 
							
								#include <unistd.h>
							 | 
						||
| 
								 | 
							
								#include<string.h>
							 | 
						||
| 
								 | 
							
								#include "types.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "as10k1.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								char *ptralloc[MAXINCLUDES];
							 | 
						||
| 
								 | 
							
								static int num_alloc;
							 | 
						||
| 
								 | 
							
								int source_line_num=0,file_num=0;
							 | 
						||
| 
								 | 
							
								int macro_line_num=0;
							 | 
						||
| 
								 | 
							
								FILE *fp=NULL,*listfile;
							 | 
						||
| 
								 | 
							
								char *input=NULL,*output=NULL,*listing=NULL,*current_line=NULL,listtemp[60];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int dbg_opt=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								char version[]="As10k1 assembler version " VERSION;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								char help[]="
							 | 
						||
| 
								 | 
							
								Usage: as10k1 [option...] asmfile
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The as10k1 assembler is for the emu10k1 dsp processor
							 | 
						||
| 
								 | 
							
								found in Creative Lab's sblive series of sound cards.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Author: Daniel Bertrand <d.bertrand@ieee.ca>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Options:\n
							 | 
						||
| 
								 | 
							
								     -l [listfile]         Specify a listing file, default is none.
							 | 
						||
| 
								 | 
							
								     -o [emu10k1 file]     Specify an output file, default is based input,
							 | 
						||
| 
								 | 
							
								                           Substituting .asm to .emu10k1
							 | 
						||
| 
								 | 
							
								     -d [dbg_options...]   Turn on debug messages.
							 | 
						||
| 
								 | 
							
								            s              prints all symbols                
							 | 
						||
| 
								 | 
							
								            g              prints defined gprs
							 | 
						||
| 
								 | 
							
								            t              prints tram usage
							 | 
						||
| 
								 | 
							
								            i              prints instructions
							 | 
						||
| 
								 | 
							
								     -h                    Prints this message  
							 | 
						||
| 
								 | 
							
								     -v                    Prints version number. 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This program is distributed under the GPL.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//  cli==Command-Line Interface && !Creative Labs Inc.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void parse_cli_args(int argc, char *argv[])
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i,j;
							 | 
						||
| 
								 | 
							
									for(i=1;i<argc;i++){
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if(argv[i][0]=='-'){
							 | 
						||
| 
								 | 
							
											switch(argv[i][1]){
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case 'o'://specify an output file name
							 | 
						||
| 
								 | 
							
												i++;
							 | 
						||
| 
								 | 
							
												if((i==argc)||(argv[i][0]=='-')){
							 | 
						||
| 
								 | 
							
													printf("Error -o option requires a destination file name\n");
							 | 
						||
| 
								 | 
							
													exit(-1);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												output=argv[i];
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case 'd': //turn on debugging messages
							 | 
						||
| 
								 | 
							
												j=0;
							 | 
						||
| 
								 | 
							
												i++;
							 | 
						||
| 
								 | 
							
												printf("Debug on, Displaying:");
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												if((i==argc)||(argv[i][0]=='-')){
							 | 
						||
| 
								 | 
							
													dbg_opt=dbg_opt|DBG_INSTR;//default
							 | 
						||
| 
								 | 
							
													i--;
							 | 
						||
| 
								 | 
							
													printf(" instructions by default\n");
							 | 
						||
| 
								 | 
							
													goto next_cli_arg;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												while(argv[i][j]!='\0'){
							 | 
						||
| 
								 | 
							
														
							 | 
						||
| 
								 | 
							
													switch(argv[i][j]){
							 | 
						||
| 
								 | 
							
													case 's':
							 | 
						||
| 
								 | 
							
														dbg_opt=dbg_opt|DBG_SYM;
							 | 
						||
| 
								 | 
							
														printf(" Symbols,");
							 | 
						||
| 
								 | 
							
														break;
							 | 
						||
| 
								 | 
							
													case 'g':
							 | 
						||
| 
								 | 
							
														dbg_opt=dbg_opt|DBG_GPR;
							 | 
						||
| 
								 | 
							
														printf(" GPRs,");
							 | 
						||
| 
								 | 
							
														break;
							 | 
						||
| 
								 | 
							
													case 't':
							 | 
						||
| 
								 | 
							
														dbg_opt=dbg_opt|DBG_TRAM;
							 | 
						||
| 
								 | 
							
														printf(" TRAM,");
							 | 
						||
| 
								 | 
							
														break;
							 | 
						||
| 
								 | 
							
													case 'i':
							 | 
						||
| 
								 | 
							
														dbg_opt=dbg_opt|DBG_INSTR;
							 | 
						||
| 
								 | 
							
														printf(" Instructions,");
							 | 
						||
| 
								 | 
							
														break;
							 | 
						||
| 
								 | 
							
														
							 | 
						||
| 
								 | 
							
													default:
							 | 
						||
| 
								 | 
							
														printf("\b \n**Bad debug option.  ");
							 | 
						||
| 
								 | 
							
														exit(-1);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													j++;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												printf("\b \n");
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
														
							 | 
						||
| 
								 | 
							
											case 'l'://produce a listing file
							 | 
						||
| 
								 | 
							
												//printf("Will save list file to %s\n",  );
							 | 
						||
| 
								 | 
							
												i++;
							 | 
						||
| 
								 | 
							
												if((i==argc)||(argv[i][0]=='-')){
							 | 
						||
| 
								 | 
							
													printf("Error -l option requires a destination file name\n");
							 | 
						||
| 
								 | 
							
													exit(-1);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												listing=argv[i];
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
											case 'h'://printf help message
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												printf("%s",help);
							 | 
						||
| 
								 | 
							
													
							 | 
						||
| 
								 | 
							
											case 'v':
							 | 
						||
| 
								 | 
							
												printf("%s\n",version);
							 | 
						||
| 
								 | 
							
												exit(0);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
										}else{
							 | 
						||
| 
								 | 
							
											if(input==NULL)
							 | 
						||
| 
								 | 
							
												input=argv[i];
							 | 
						||
| 
								 | 
							
											else{
							 | 
						||
| 
								 | 
							
												printf("Error, only one input file can be specified");	
							 | 
						||
| 
								 | 
							
												as_exit("");
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								next_cli_arg:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int main( int argc, char *argv[] )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								        int i;
							 | 
						||
| 
								 | 
							
								        char filename[FILENAME_MAX];
							 | 
						||
| 
								 | 
							
								        extern int ip;
							 | 
						||
| 
								 | 
							
								        u32 val;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								        parse_cli_args(argc,argv);
							 | 
						||
| 
								 | 
							
									if(input==NULL){
							 | 
						||
| 
								 | 
							
										printf("Error, an input file must be specified\n");
							 | 
						||
| 
								 | 
							
										exit(-1);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //init symbol list:
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        INIT_LIST_HEAD(&sym_head);
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
									if(listing!=NULL)
							 | 
						||
| 
								 | 
							
										if((listfile = fopen(listing, "w"))==NULL){
							 | 
						||
| 
								 | 
							
											printf("\nError writing to file %s\n",argv[1]);	
							 | 
						||
| 
								 | 
							
											as_exit("error");       
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									asm_open(input); //opens the source file and starts parsing it.
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if(output==NULL){
							 | 
						||
| 
								 | 
							
										strcpy(filename, input);
							 | 
						||
| 
								 | 
							
										strtok(filename,".\0");
							 | 
						||
| 
								 | 
							
										strcat(filename, ".emu10k1");
							 | 
						||
| 
								 | 
							
										output = filename;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if((fp = fopen(output, "w"))==NULL){
							 | 
						||
| 
								 | 
							
										printf("\nError writing to file %s\n",argv[1]);	
							 | 
						||
| 
								 | 
							
										as_exit("error");       
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if(listing)
							 | 
						||
| 
								 | 
							
										fprintf(listfile,"Summary:\n");
							 | 
						||
| 
								 | 
							
								        /*create header*/
							 | 
						||
| 
								 | 
							
								        header();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /*output number of instructions*/
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
								        val = __cpu_to_le32(ip);
							 | 
						||
| 
								 | 
							
								        fwrite(&val,sizeof(u16),1,fp);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        /* write binary code */
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (i = 0; i < ip; i++) {
							 | 
						||
| 
								 | 
							
								        	val = __cpu_to_le32(dsp_code[i]);
							 | 
						||
| 
								 | 
							
								                fwrite(&val,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
										//for (j = 3; j >= 0; j--)
							 | 
						||
| 
								 | 
							
								                //fprintf(fp, "%c", ((u8 *) dsp_code)[i * 4 + j]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
								  	
							 | 
						||
| 
								 | 
							
									if(listing)
							 | 
						||
| 
								 | 
							
										fclose(listfile);
							 | 
						||
| 
								 | 
							
									fclose(fp);
							 | 
						||
| 
								 | 
							
								        for(i=0;i<num_alloc;i++) //free mem, is this necessary, or will the kernel free it automatically?
							 | 
						||
| 
								 | 
							
								                free(ptralloc[i]);
							 | 
						||
| 
								 | 
							
								              
							 | 
						||
| 
								 | 
							
								  	return 0;  //that's it were done
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*this function is called to open a asm file and parse it using the parse function.
							 | 
						||
| 
								 | 
							
								this function is called by the main function and also by the parse function
							 | 
						||
| 
								 | 
							
								when it encounters an "INCLUDE" directive.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void asm_open(char *name)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        int fd,i;
							 | 
						||
| 
								 | 
							
								        int done=0;
							 | 
						||
| 
								 | 
							
								        char string[MAX_LINE_LENGTH];
							 | 
						||
| 
								 | 
							
								        struct stat st;
							 | 
						||
| 
								 | 
							
								        char *next;
							 | 
						||
| 
								 | 
							
								        int backup_line_num,backup_file_num;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        backup_line_num=source_line_num;
							 | 
						||
| 
								 | 
							
								        backup_file_num=file_num;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if( (include_depth++) > max_depth){
							 | 
						||
| 
								 | 
							
										printf("Error: maximum recursive include depth(%d) exceeded\n",max_depth);
							 | 
						||
| 
								 | 
							
										as_exit("");
							 | 
						||
| 
								 | 
							
									}	 		
							 | 
						||
| 
								 | 
							
								        buff[num_alloc].name=name;
							 | 
						||
| 
								 | 
							
								        source_line_num=0;
							 | 
						||
| 
								 | 
							
								        file_num=num_alloc;
							 | 
						||
| 
								 | 
							
								        //open the file
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if ((unsigned) (fd = open(name, O_RDONLY)) > 255){
							 | 
						||
| 
								 | 
							
								                as_exit("error opening input file\n");
							 | 
						||
| 
								 | 
							
								        } 
							 | 
						||
| 
								 | 
							
								        //get it's stats
							 | 
						||
| 
								 | 
							
								        if ( -1 ==  fstat( fd, &st)){
							 | 
						||
| 
								 | 
							
								                printf("Error occured attempting to stat %s\n", name);
							 | 
						||
| 
								 | 
							
								                as_exit("");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if(( ptralloc[num_alloc]=(char *) malloc(st.st_size+2) )== 0){
							 | 
						||
| 
								 | 
							
								                printf("error allocating memory for file %s\n",name);
							 | 
						||
| 
								 | 
							
								                close(fd);
							 | 
						||
| 
								 | 
							
								                as_exit("");
							 | 
						||
| 
								 | 
							
								        }else{
							 | 
						||
| 
								 | 
							
								                buff[num_alloc].mem_start=ptralloc[num_alloc]; 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        i=num_alloc;
							 | 
						||
| 
								 | 
							
								        num_alloc++;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        buff[i].mem_end = buff[i].mem_start+st.st_size;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        read(fd, buff[i].mem_start, st.st_size);
							 | 
						||
| 
								 | 
							
								        close(fd);
							 | 
						||
| 
								 | 
							
								         
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG        
							 | 
						||
| 
								 | 
							
								  	printf("File %s opened:\n",name);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        //get each line and parse it:
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        current_line=buff[i].mem_start;
							 | 
						||
| 
								 | 
							
								        source_line_num=1;
							 | 
						||
| 
								 | 
							
								        next=current_line;
							 | 
						||
| 
								 | 
							
								        while(next!=buff[i].mem_end){
							 | 
						||
| 
								 | 
							
								                while((*next!= '\n') && (next!=buff[i].mem_end) )
							 | 
						||
| 
								 | 
							
								                        next++;
							 | 
						||
| 
								 | 
							
								                listtemp[0]='\0';
							 | 
						||
| 
								 | 
							
								                *next='\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG        
							 | 
						||
| 
								 | 
							
								                printf("%s\n",current_line);
							 | 
						||
| 
								 | 
							
								#endif                
							 | 
						||
| 
								 | 
							
								                if(strlen(current_line)>MAX_LINE_LENGTH)
							 | 
						||
| 
								 | 
							
								                        as_exit("Parse error: Line exceeds allowable limit");
							 | 
						||
| 
								 | 
							
								                strcpy(&string[0],current_line);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                done = parse(string,current_line);
							 | 
						||
| 
								 | 
							
										if(listing){
							 | 
						||
| 
								 | 
							
											if(done==1 &&include_depth!=1)
							 | 
						||
| 
								 | 
							
												sprintf(listtemp,"Exiting included file");
							 | 
						||
| 
								 | 
							
											if(done!=-3)
							 | 
						||
| 
								 | 
							
												fprintf(listfile,"%-50s ||   %s\n",listtemp,current_line);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
										*next='\n';
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								                if(done==1)
							 | 
						||
| 
								 | 
							
											goto done;
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								                if(next!=buff[i].mem_end){
							 | 
						||
| 
								 | 
							
								                        source_line_num++;
							 | 
						||
| 
								 | 
							
								                        next++;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                current_line=next;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if(done==0)
							 | 
						||
| 
								 | 
							
								                printf("warning no END directive at end of file %s\n",name);
							 | 
						||
| 
								 | 
							
								done:        
							 | 
						||
| 
								 | 
							
								        source_line_num=backup_line_num;
							 | 
						||
| 
								 | 
							
								        file_num=backup_file_num;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        include_depth--;
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG	
							 | 
						||
| 
								 | 
							
								  	printf("File %s closed:\n",name);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void as_exit(const char *message)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								        int i;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if(macro_line_num!=0)
							 | 
						||
| 
								 | 
							
								                fprintf(stderr, "** Error while expanding macro at line %d\n",macro_line_num);
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								        if(source_line_num!=0)
							 | 
						||
| 
								 | 
							
								                fprintf(stderr, "** %s.\n** line number %d:\n %s\nIn file: %s\n", message, source_line_num,current_line,buff[file_num].name);
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								                fprintf(stderr, "** Error with file:%s\n",buff[file_num].name);
							 | 
						||
| 
								 | 
							
								        for(i=num_alloc-1;i>=0;i--)
							 | 
						||
| 
								 | 
							
								                free(ptralloc[i]);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
									exit(1);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void output_tram_line( struct list_head *line_head, int type){
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        struct tram *tram_sym;
							 | 
						||
| 
								 | 
							
								        struct list_head *entry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        list_for_each(entry, line_head ){
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								                tram_sym=list_entry(entry,struct tram,tram);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								                if(tram_sym->type==type){
							 | 
						||
| 
								 | 
							
								                	u32 val;
							 | 
						||
| 
								 | 
							
								                        //printf("table read:%s,%x\n",tram_sym->data.name,tram_sym->data.address);
							 | 
						||
| 
								 | 
							
								                        tram_sym->data.address-=TRAM_ADDR_BASE;
							 | 
						||
| 
								 | 
							
								                        fwrite(&(tram_sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                        val = __cpu_to_le32(tram_sym->data.value);
							 | 
						||
| 
								 | 
							
								                        fwrite(&val,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
											if(listing){
							 | 
						||
| 
								 | 
							
												if(type==TYPE_TRAM_ADDR_READ)
							 | 
						||
| 
								 | 
							
													fprintf(listfile,"\tRead");
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
													fprintf(listfile,"\tWrite");
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
													fprintf(listfile,": 0x3%02x/0x2%02x (%s), offset 0x%07x\n",tram_sym->data.address,tram_sym->data.address,
							 | 
						||
| 
								 | 
							
														(prev_sym((&tram_sym->list)))->data.name,tram_sym->data.value);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//creates output header
							 | 
						||
| 
								 | 
							
								void header(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								        int i;
							 | 
						||
| 
								 | 
							
								        struct sym *sym;
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
								        extern struct list_head sym_head;
							 | 
						||
| 
								 | 
							
									struct list_head *entry;
							 | 
						||
| 
								 | 
							
									if(listing)
							 | 
						||
| 
								 | 
							
										fprintf(listfile,"Patch name: \"%s\"\n\n",patch_name);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									//patch signature
							 | 
						||
| 
								 | 
							
										   //1234567890123456
							 | 
						||
| 
								 | 
							
									fprintf(fp, "EMU10K1 FX8010 1");
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									//patchname
							 | 
						||
| 
								 | 
							
								        fwrite(patch_name,sizeof(char), PATCH_NAME_SIZE,fp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        fwrite(&gpr_input_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								        //write ins/outs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(listing)
							 | 
						||
| 
								 | 
							
										fprintf(listfile,"*****************************GPR******************************\n");
							 | 
						||
| 
								 | 
							
								        list_for_each(entry,&sym_head){
							 | 
						||
| 
								 | 
							
								                sym=list_entry(entry,struct sym,list);
							 | 
						||
| 
								 | 
							
								                if(sym->type==GPR_TYPE_INPUT){
							 | 
						||
| 
								 | 
							
								                        sym->data.address-=GPR_BASE;
							 | 
						||
| 
								 | 
							
								                        fwrite(&(sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
											if(listing)
							 | 
						||
| 
								 | 
							
												fprintf(listfile,"%s IN: 0x%03x, OUT: 0x%03x\n",sym->data.name,sym->data.address+GPR_BASE,sym->data.address+GPR_BASE+1);
							 | 
						||
| 
								 | 
							
								                        sym->data.address++;
							 | 
						||
| 
								 | 
							
								                        fwrite(&(sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								               
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
									/* dynamic gprs */      
							 | 
						||
| 
								 | 
							
								        fwrite(&gpr_dynamic_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								        list_for_each(entry,&sym_head){
							 | 
						||
| 
								 | 
							
								                sym=list_entry(entry,struct sym,list);
							 | 
						||
| 
								 | 
							
								                if(sym->type==GPR_TYPE_DYNAMIC) {
							 | 
						||
| 
								 | 
							
								                        sym->data.address-=GPR_BASE;
							 | 
						||
| 
								 | 
							
								                        fwrite(&(sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
											if(listing)
							 | 
						||
| 
								 | 
							
												fprintf(listfile,"GPR Dynamic:  0x%03x(%s)\n",sym->data.address+GPR_BASE,sym->data.name);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								     
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        /* static gprs */
							 | 
						||
| 
								 | 
							
									fwrite(&gpr_static_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
								        list_for_each(entry,&sym_head){
							 | 
						||
| 
								 | 
							
								                sym=list_entry(entry,struct sym,list);
							 | 
						||
| 
								 | 
							
								                if(sym->type==GPR_TYPE_STATIC){
							 | 
						||
| 
								 | 
							
								                	u32 value;
							 | 
						||
| 
								 | 
							
								                        sym->data.address-=GPR_BASE;
							 | 
						||
| 
								 | 
							
								                        fwrite(&(sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                        value = __cpu_to_le32(sym->data.value);
							 | 
						||
| 
								 | 
							
								                        fwrite(&value,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
											if(listing)
							 | 
						||
| 
								 | 
							
												fprintf(listfile,"GPR Static:  0x%03x(%s), Value:0x%08x\n",sym->data.address+GPR_BASE
							 | 
						||
| 
								 | 
							
													,sym->data.name,sym->data.value);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        /* control gprs */
							 | 
						||
| 
								 | 
							
								        fwrite(&gpr_control_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								         
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								        list_for_each(entry,&sym_head){
							 | 
						||
| 
								 | 
							
								                sym=list_entry(entry,struct sym,list);
							 | 
						||
| 
								 | 
							
								                if(sym->type==GPR_TYPE_CONTROL){
							 | 
						||
| 
								 | 
							
								                	u32 value;
							 | 
						||
| 
								 | 
							
								                        sym->data.address-=GPR_BASE;
							 | 
						||
| 
								 | 
							
								                        fwrite(&(sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                        value = __cpu_to_le32(sym->data.value);			
							 | 
						||
| 
								 | 
							
								                        fwrite(&value,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
								                        value = __cpu_to_le32(((struct control *)sym)->min);
							 | 
						||
| 
								 | 
							
								                        fwrite(&value,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
								                        value = __cpu_to_le32(((struct control *)sym)->max);
							 | 
						||
| 
								 | 
							
								                        fwrite(&value,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
								                       
							 | 
						||
| 
								 | 
							
								                        fwrite(&(sym->data.name), sizeof(char), MAX_SYM_LEN, fp);
							 | 
						||
| 
								 | 
							
											if(listing)
							 | 
						||
| 
								 | 
							
												fprintf(listfile,"GPR Control: 0x%03x(%s), value:0x%08x, Min:0x%08x, Max:0x%08x\n",sym->data.address+GPR_BASE,sym->data.name,
							 | 
						||
| 
								 | 
							
													sym->data.value,((struct control *)sym)->min,((struct control *)sym)->max);
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                }                
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								        /*constant GPRs*/
							 | 
						||
| 
								 | 
							
									fwrite(&gpr_constant_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									list_for_each(entry,&sym_head){
							 | 
						||
| 
								 | 
							
										sym=list_entry(entry,struct sym,list);
							 | 
						||
| 
								 | 
							
										if(sym->type==GPR_TYPE_CONSTANT){
							 | 
						||
| 
								 | 
							
											sym->data.address-=GPR_BASE;
							 | 
						||
| 
								 | 
							
											fwrite(&(sym->data.address),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
											fwrite(&(sym->data.value),sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
											if(listing)
							 | 
						||
| 
								 | 
							
												fprintf(listfile,"GPR Constant: 0x%03x(%s), Value:0x%08x\n",sym->data.address+0x100
							 | 
						||
| 
								 | 
							
													,sym->data.name,sym->data.value);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(listing)
							 | 
						||
| 
								 | 
							
										fprintf(listfile,"*****************************TRAM*****************************\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/*lookup-tables*/
							 | 
						||
| 
								 | 
							
								        fwrite(&tram_table_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									for(i=0;i<tram_table_count;i++){
							 | 
						||
| 
								 | 
							
										u32 value;
							 | 
						||
| 
								 | 
							
										value = __cpu_to_le32(tram_lookup[i].size);
							 | 
						||
| 
								 | 
							
								                fwrite(&value,sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
										if(listing)
							 | 
						||
| 
								 | 
							
											fprintf(listfile,"Lookup-table block:%s, size:0x%08x\n",(&tram_lookup[i])->name,tram_lookup[i].size);
							 | 
						||
| 
								 | 
							
										// read lines
							 | 
						||
| 
								 | 
							
								                fwrite(&(tram_lookup[i].read),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                output_tram_line(&(tram_lookup[i].tram),TYPE_TRAM_ADDR_READ);
							 | 
						||
| 
								 | 
							
								                //write lines
							 | 
						||
| 
								 | 
							
								                fwrite(&(tram_lookup[i].write),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                output_tram_line(&(tram_lookup[i].tram),TYPE_TRAM_ADDR_WRITE);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								               
							 | 
						||
| 
								 | 
							
									/*Delay Lines*/
							 | 
						||
| 
								 | 
							
								        fwrite(&tram_delay_count,sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								        for(i=0;i<tram_delay_count;i++){
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                fwrite(&(tram_delay[i].size),sizeof(u32),1,fp);
							 | 
						||
| 
								 | 
							
										if(listing)
							 | 
						||
| 
								 | 
							
											fprintf(listfile,"Delay-line block:%s, size:0x%08x\n",tram_delay[i].name,tram_delay[i].size);
							 | 
						||
| 
								 | 
							
								                // read lines
							 | 
						||
| 
								 | 
							
								                fwrite(&(tram_delay[i].read),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                output_tram_line(&(tram_delay[i].tram),TYPE_TRAM_ADDR_READ);
							 | 
						||
| 
								 | 
							
								             
							 | 
						||
| 
								 | 
							
								                //write lines
							 | 
						||
| 
								 | 
							
								                fwrite(&(tram_delay[i].write),sizeof(u8),1,fp);
							 | 
						||
| 
								 | 
							
								                output_tram_line(&(tram_delay[i].tram),TYPE_TRAM_ADDR_WRITE);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								}
							 |