/*************************************************************************** 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 * mailing list. * Jaroslav Kysela */ /*************************************************************************** * * * 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 #include #include #include #include #include #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[]="\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 \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"; // cli==Command-Line Interface && !Creative Labs Inc. void parse_cli_args(int argc, char *argv[]) { int i,j; for(i=1;i= 0; j--) //fprintf(fp, "%c", ((u8 *) dsp_code)[i * 4 + j]); } if(listing) fclose(listfile); fclose(fp); for(i=0;i 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); } 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;iname,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