int main(int argc, char *argv[]) { FILE *out; FILE *dbg = NULL; //FILE *list = NULL; int i; int format = FORMAT_HEX; int create_list = 0; char *infile = NULL, *outfile = NULL; struct _asm_context asm_context; int error_flag=0; puts(credits); if (argc < 2) { printf("Usage: naken_asm [options] <infile>\n" " -o <outfile>\n" " -h [output hex file]\n" #ifndef DISABLE_ELF " -e [output elf file]\n" #endif " -b [output binary file]\n" " -s [output srec file]\n" " -l [create .lst listing file]\n" " -I [add to include path]\n" " -q Quiet (only output errors)\n" "\n"); exit(0); } memset(&asm_context, 0, sizeof(asm_context)); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-o") == 0) { outfile = argv[++i]; } else if (strcmp(argv[i], "-h") == 0) { format = FORMAT_HEX; } else if (strcmp(argv[i], "-b") == 0) { format = FORMAT_BIN; } else if (strcmp(argv[i], "-s") == 0) { format = FORMAT_SREC; } #ifndef DISABLE_ELF else if (strcmp(argv[i], "-e") == 0) { format = FORMAT_ELF; } #endif #if 0 else if (strcmp(argv[i], "-d") == 0) { asm_context.debug_file = 1; } #endif else if (strcmp(argv[i], "-l") == 0) { create_list = 1; } else if (strncmp(argv[i], "-I", 2) == 0) { char *s = argv[i]; if (s[2] == 0) { if (add_to_include_path(&asm_context, argv[++i]) != 0) { printf("Internal Error: Too many include paths\n"); exit(1); } } else { if (add_to_include_path(&asm_context, s+2) != 0) { printf("Internal Error: Too many include paths\n"); exit(1); } } } else if (strcmp(argv[i], "-q") == 0) { asm_context.quiet_output = 1; } else { if (infile != NULL) { printf("Error: Cannot use %s as input file since %s was already chosen.\n", argv[1], infile); exit(1); } infile = argv[i]; } } if (infile == NULL) { printf("No input file specified.\n"); exit(1); } if (outfile == NULL) { switch(format) { case FORMAT_HEX: outfile = "out.hex"; break; case FORMAT_BIN: outfile = "out.bin"; break; case FORMAT_ELF: outfile = "out.elf"; break; case FORMAT_SREC: outfile = "out.srec"; break; default: outfile = "out.err"; break; } } #ifdef INCLUDE_PATH if (add_to_include_path(&asm_context, INCLUDE_PATH) != 0) { printf("Internal Error: Too many include paths\n"); exit(1); } #endif if (tokens_open_file(&asm_context, infile) != 0) { printf("Couldn't open %s for reading.\n", infile); exit(1); } out = fopen(outfile, "wb"); if (out == NULL) { printf("Couldn't open %s for writing.\n", outfile); exit(1); } if (asm_context.quiet_output == 0) { printf(" Input file: %s\n", infile); printf("Output file: %s\n", outfile); } #if 0 if (asm_context.debug_file == 1) { char filename[1024]; strcpy(filename, outfile); new_extension(filename, "ndbg", 1024); dbg = fopen(filename,"wb"); if (dbg == NULL) { printf("Couldn't open %s for writing.\n",filename); exit(1); } printf(" Debug file: %s\n",filename); fprintf(dbg, "%s\n", infile); } #endif if (create_list == 1) { char filename[1024]; strcpy(filename, outfile); new_extension(filename, "lst", 1024); asm_context.list = fopen(filename, "wb"); if (asm_context.list == NULL) { printf("Couldn't open %s for writing.\n", filename); exit(1); } if (asm_context.quiet_output == 0) { printf(" List file: %s\n", filename); } } if (asm_context.quiet_output == 0) { printf("\nPass 1...\n"); } symbols_init(&asm_context.symbols); macros_init(&asm_context.macros); asm_context.pass = 1; assemble_init(&asm_context); error_flag = assemble(&asm_context); if (error_flag != 0) { printf("** Errors... bailing out\n"); unlink(outfile); } else { symbols_lock(&asm_context.symbols); // macros_lock(&asm_context.defines_heap); if (asm_context.quiet_output == 0) { printf("Pass 2...\n"); } asm_context.pass = 2; assemble_init(&asm_context); error_flag = assemble(&asm_context); if (format == FORMAT_HEX) { write_hex(&asm_context.memory, out); } else if (format == FORMAT_BIN) { write_bin(&asm_context.memory, out); } else if (format == FORMAT_SREC) { write_srec(&asm_context.memory, out); } #ifndef DISABLE_ELF else if (format == FORMAT_ELF) { write_elf(&asm_context.memory, out, &asm_context.symbols, asm_context.filename, asm_context.cpu_type); } #endif if (dbg != NULL) { for (i = 0; i < asm_context.memory.size; i++) { int debug_line = memory_debug_line(&asm_context, i); putc(debug_line >> 8, dbg); putc(debug_line & 0xff, dbg); } fclose(dbg); } } fclose(out); if (create_list == 1) { int ch = 0; char str[17]; int ptr = 0; fprintf(asm_context.list, "data sections:"); for (i = asm_context.memory.low_address; i <= asm_context.memory.high_address; i++) { if (memory_debug_line(&asm_context, i) == -2) { if (ch == 0) { if (ptr != 0) { output_hex_text(asm_context.list, str, ptr); } fprintf(asm_context.list, "\n%04x:", i/asm_context.bytes_per_address); ptr = 0; } unsigned char data = memory_read(&asm_context, i); fprintf(asm_context.list, " %02x", data); if (data >= ' ' && data <= 120) { str[ptr++] = data; } else { str[ptr++] = '.'; } ch++; if (ch == 16) { ch = 0; } } else { output_hex_text(asm_context.list, str, ptr); ch = 0; ptr = 0; } } output_hex_text(asm_context.list, str, ptr); fprintf(asm_context.list, "\n\n"); assemble_print_info(&asm_context, asm_context.list); } assemble_print_info(&asm_context, stdout); //symbols_free(&asm_context.symbols); //macros_free(&asm_context.macros); if (asm_context.list != NULL) { fclose(asm_context.list); } fclose(asm_context.in); if (error_flag != 0) { printf("*** Failed ***\n\n"); unlink(outfile); } //memory_free(&asm_context.memory); assemble_free(&asm_context); if (error_flag != 0) { return -1; } return 0; }
int main(int argc, char *argv[]) { FILE *out; FILE *dbg=NULL; FILE *list=NULL; int i; int format=FORMAT_HEX; int create_list=0; char *infile=NULL,*outfile=NULL; struct _asm_context asm_context; int error_flag=0; printf("\nnaken430asm - by Michael Kohn\n"); printf(" Web: http://www.mikekohn.net/\n"); printf(" Email: [email protected]\n\n"); printf("Version: "VERSION"\n\n"); if (argc<2) { printf("Usage: naken430asm [options] <infile>\n"); printf(" -o <outfile>\n"); printf(" -h [output hex file]\n"); #ifndef DISABLE_ELF printf(" -e [output elf file]\n"); #endif printf(" -b [output binary file]\n"); printf(" -d [create .ndbg debug file]\n"); printf(" -l [create .lst listing file]\n"); printf(" -I [add to include path]\n"); printf("\n"); exit(0); } memset(&asm_context, 0, sizeof(asm_context)); for (i=1; i<argc; i++) { if (strcmp(argv[i], "-o")==0) { outfile=argv[++i]; } else if (strcmp(argv[i], "-h")==0) { format=FORMAT_HEX; } else if (strcmp(argv[i], "-b")==0) { format=FORMAT_BIN; } #ifndef DISABLE_ELF else if (strcmp(argv[i], "-e")==0) { format=FORMAT_ELF; } #endif else if (strcmp(argv[i], "-d")==0) { asm_context.debug_file=1; } else if (strcmp(argv[i], "-l")==0) { create_list=1; } else if (strncmp(argv[i], "-I", 2)==0) { char *s=argv[i]; if (s[2]==0) { if (add_to_include_path(&asm_context, argv[++i])!=0) { printf("Internal Error: Too many include paths\n"); exit(1); } } else { if (add_to_include_path(&asm_context, s+2)!=0) { printf("Internal Error: Too many include paths\n"); exit(1); } } } else { infile=argv[i]; } } if (infile==NULL) { printf("No input file specified.\n"); exit(1); } if (outfile==NULL) { if (format==FORMAT_HEX) { outfile="out.hex"; } else if (format==FORMAT_BIN) { outfile="out.bin"; } #ifndef DISABLE_ELF else if (format==FORMAT_ELF) { outfile="out.elf"; } #endif } #ifdef INCLUDE_PATH if (add_to_include_path(&asm_context, INCLUDE_PATH)!=0) { printf("Internal Error: Too many include paths\n"); exit(1); } #endif asm_context.in=fopen(infile,"rb"); if (asm_context.in==NULL) { printf("Couldn't open %s for reading.\n",infile); exit(1); } asm_context.filename=infile; out=fopen(outfile,"wb"); if (out==NULL) { printf("Couldn't open %s for writing.\n",outfile); exit(1); } printf(" Input file: %s\n",infile); printf("Output file: %s\n",outfile); if (asm_context.debug_file==1) { char filename[1024]; strcpy(filename,outfile); new_extension(filename, "ndbg", 1024); dbg=fopen(filename,"wb"); if (dbg==NULL) { printf("Couldn't open %s for writing.\n",filename); exit(1); } printf(" Debug file: %s\n",filename); fprintf(dbg,"%s\n",infile); } if (create_list==1) { char filename[1024]; strcpy(filename,outfile); new_extension(filename, "lst", 1024); list=fopen(filename,"wb"); if (list==NULL) { printf("Couldn't open %s for writing.\n",filename); exit(1); } printf(" List file: %s\n",filename); } printf("\n"); address_heap_init(&asm_context.address_heap); defines_heap_init(&asm_context.defines_heap); printf("Pass 1...\n"); asm_context.pass=1; assemble_init(&asm_context); error_flag=assemble(&asm_context); if (error_flag!=0) { printf("** Errors... bailing out\n"); fclose(out); unlink(outfile); create_list=0; } else { address_heap_lock(&asm_context.address_heap); // defines_heap_lock(&asm_context.defines_heap); printf("Pass 2...\n"); asm_context.pass=2; assemble_init(&asm_context); error_flag=assemble(&asm_context); if (format==FORMAT_HEX) { write_hex(&asm_context, out); } else if (format==FORMAT_BIN) { write_bin(&asm_context, out); } #ifndef DISABLE_ELF else if (format==FORMAT_ELF) { write_elf(&asm_context, out); } #endif if (dbg!=NULL) { for (i=0; i<65536; i++) { putc(asm_context.debug_line[i]>>8,dbg); putc(asm_context.debug_line[i]&0xff,dbg); } fclose(dbg); } fclose(out); } #if 0 for (i=asm_context.low_address; i<=asm_context.high_address; i++) { printf("%04x: %d\n", i, asm_context.debug_line[i]); } #endif if (create_list==1) { int *lines=NULL; int line=1; int ch; fseek(asm_context.in, 0, SEEK_SET); /* Build a map of lines to offset in source file (really more of a map of lines to offset in debug_line which is an offset to input file */ if (asm_context.line<65535) { lines=(int *)malloc((asm_context.line+1)*sizeof(int)); memset(lines, -1, (asm_context.line+1)*sizeof(int)); for (i=asm_context.high_address; i>=asm_context.low_address; i--) { if ((int)asm_context.debug_line[i]<0) continue; lines[asm_context.debug_line[i]]=i; } } /* Read input file again line by line and write back out to lst file. If line matches something in the index, then output the line and disassembled code */ while(1) { ch=getc(asm_context.in); if (ch!=EOF) { putc(ch, list); } if (ch=='\n' || ch==EOF) { int i; int start; if (lines==NULL) { start=asm_context.low_address; } else { if (lines[line]>=0) { start=lines[line]; } else { start=asm_context.high_address+1; } } //int loop_count=0; for (i=start; i<=asm_context.high_address; i++) { int num; if (asm_context.debug_line[i]==line) { fprintf(list, "\n"); while(asm_context.debug_line[i]==line) { int cycles; char instruction[128]; int count=msp430_disasm(asm_context.bin, i, instruction, &cycles); num=asm_context.bin[i]|(asm_context.bin[i+1]<<8); fprintf(list, "0x%04x: 0x%04x %-40s cycles: %d\n", i, num, instruction, cycles); count--; while (count>0) { i=i+2; num=asm_context.bin[i]|(asm_context.bin[i+1]<<8); fprintf(list, "0x%04x: 0x%04x\n", i, num); count--; } i=i+2; } fprintf(list, "\n"); break; } //loop_count++; } //printf("loop_count=%d\n", loop_count); if (ch==EOF) { break; } line++; } } if (lines!=NULL) free(lines); assemble_print_info(&asm_context, list); fclose(list); } assemble_print_info(&asm_context, stdout); address_heap_free(&asm_context.address_heap); defines_heap_free(&asm_context.defines_heap); fclose(asm_context.in); if (error_flag!=0) { printf("*** Failed ***\n\n"); unlink(outfile); } return 0; }