| 
									
										
										
										
											2001-04-12 08:21:01 +00:00
										 |  |  | /***************************************************************************
 | 
					
						
							|  |  |  |                           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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-15 18:33:59 +00:00
										 |  |  | char help[]="\n" | 
					
						
							|  |  |  | "Usage: as10k1 [option...] asmfile\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "The as10k1 assembler is for the emu10k1 dsp processor\n" | 
					
						
							|  |  |  | "found in Creative Lab's sblive series of sound cards.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Author: Daniel Bertrand <d.bertrand@ieee.ca>\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Options:\n\n" | 
					
						
							|  |  |  | "     -l [listfile]         Specify a listing file, default is none.\n" | 
					
						
							|  |  |  | "     -o [emu10k1 file]     Specify an output file, default is based input,\n" | 
					
						
							|  |  |  | "                           Substituting .asm to .emu10k1\n" | 
					
						
							|  |  |  | "     -d [dbg_options...]   Turn on debug messages.\n" | 
					
						
							|  |  |  | "            s              prints all symbols                \n" | 
					
						
							|  |  |  | "            g              prints defined gprs\n" | 
					
						
							|  |  |  | "            t              prints tram usage\n" | 
					
						
							|  |  |  | "            i              prints instructions\n" | 
					
						
							|  |  |  | "     -h                    Prints this message  \n" | 
					
						
							|  |  |  | "     -v                    Prints version number. \n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "This program is distributed under the GPL.\n" | 
					
						
							|  |  |  | "\n"; | 
					
						
							| 
									
										
										
										
											2001-04-12 08:21:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //  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 */ | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-15 06:45:17 +00:00
										 |  |  |         for (i = 0; i < ip * 2; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-12 08:21:01 +00:00
										 |  |  |         	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); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | } |