Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***********************************************************************
  2.  *
  3.  *  avra - Assembler for the Atmel AVR microcontroller series
  4.  *
  5.  *  Copyright (C) 1998-2006 Jon Anders Haugum, Tobias Weber
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; see the file COPYING.  If not, write to
  19.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  *  Boston, MA 02111-1307, USA.
  21.  *
  22.  *
  23.  *  Authors of avra can be reached at:
  24.  *     email: jonah@omegav.ntnu.no, tobiw@suprafluid.com
  25.  *     www: http://sourceforge.net/projects/avra
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <stdarg.h>
  31. #include <string.h>
  32.  
  33. #include "misc.h"
  34. #include "args.h"
  35. #include "avra.h"
  36. #include "device.h"
  37.  
  38. #define debug 0
  39.  
  40. const char *title =
  41.   "AVRA: advanced AVR macro assembler Version %i.%i.%i Build %i (%s)\n"
  42.   "Copyright (C) 1998-2010. Check out README file for more info\n"
  43.   "\n"
  44.   "   AVRA is an open source assembler for Atmel AVR microcontroller family\n"
  45.   "   It can be used as a replacement of 'AVRASM32.EXE' the original assembler\n"
  46.   "   shipped with AVR Studio. We do not guarantee full compatibility for avra.\n"
  47.   "\n"
  48.   "   AVRA comes with NO WARRANTY, to the extent permitted by law.\n"
  49.   "   You may redistribute copies of avra under the terms\n"
  50.   "   of the GNU General Public License.\n"
  51.   "   For more information about these matters, see the files named COPYING.\n"
  52.   "\n";
  53.  
  54. const char *usage =
  55.         "usage: avra [-f][O|M|I|G] output file type\n"
  56.         "            [-o <filename>] output file name\n"
  57.         "            [-l <filename>] generate list file\n"
  58.         "            [-m <mapfile>] generate map file\n"
  59.   "[--define <symbol>[=<value>]]  [--includedir <dir>] [--listmac]\n"
  60.         "            [--max_errors <number>] [--devices] [--version]\n"
  61.         "            [-h] [--help] general help\n"
  62.         "            "
  63.         "            <file to assemble>\n"
  64.         "\n"
  65.         "   --listfile    -l : Create list file\n"
  66.         "   --mapfile     -m : Create map file\n"
  67.         "   --define      -D : Define symbol.\n"
  68.         "   --includepath  -I : Additional include paths.\n"
  69.         "   --listmac        : List macro expansion in listfile.\n"
  70.         "   --max_errors     : Maximum number of errors before exit\n"
  71.   "                      (default: 10)\n"
  72.         "   --devices        : List out supported devices.\n"
  73.         "   --version        : Version information.\n"
  74.         "   --help, -h       : This help text.\n"
  75.         "\n"
  76.   "Just replace the AVRASM32.EXE with AVRA.EXE in your\n"
  77.   "AVRStudio directories to avra's binary.\n";
  78.  
  79. int main(int argc, char *argv[])
  80. {
  81.   int show_usage = False;
  82.   struct prog_info *pi=NULL;
  83.   struct args *args;
  84.   unsigned char c;
  85.  
  86. #if debug == 1
  87.   int i;
  88.   for(i = 0; i < argc; i++) {
  89.     printf(argv[i]);
  90.     printf("\n");
  91.   }
  92. #endif
  93.  
  94.   printf(title, VER_MAJOR, VER_MINOR, VER_RELEASE, VER_BUILD, VER_DATE);
  95.  
  96.   args = alloc_args(ARG_COUNT);
  97.   if(args) {
  98.     define_arg(args, ARG_DEFINE,      ARGTYPE_STRING_MULTISINGLE,  'D', "define",      NULL);
  99.     define_arg(args, ARG_INCLUDEPATH, ARGTYPE_STRING_MULTISINGLE,  'I', "includepath", NULL);
  100.     define_arg(args, ARG_LISTMAC,     ARGTYPE_BOOLEAN,              0,  "listmac",     "1");
  101.     define_arg(args, ARG_MAX_ERRORS,  ARGTYPE_STRING,               0,  "max_errors",  "10");
  102.     define_arg(args, ARG_COFF,        ARGTYPE_BOOLEAN,              0,  "coff",        NULL);
  103.     define_arg(args, ARG_DEVICES,     ARGTYPE_BOOLEAN,              0,  "devices",     NULL);
  104.     define_arg(args, ARG_VER,         ARGTYPE_BOOLEAN,              0,  "version",     NULL);
  105.     define_arg(args, ARG_HELP,        ARGTYPE_BOOLEAN,             'h', "help",        NULL);
  106.     define_arg(args, ARG_WRAP,        ARGTYPE_BOOLEAN,             'w', "wrap",        NULL);   // Not implemented ? B.A.
  107.     define_arg(args, ARG_WARNINGS,    ARGTYPE_STRING_MULTISINGLE,  'W', "warn",        NULL);
  108.     define_arg(args, ARG_FILEFORMAT,  ARGTYPE_CHAR_ATTACHED,       'f', "filetype",    "0");    // Not implemented ? B.A.
  109.     define_arg(args, ARG_LISTFILE,    ARGTYPE_STRING,              'l', "listfile",    NULL);
  110.     define_arg(args, ARG_OUTFILE,     ARGTYPE_STRING,              'o', "outfile",     NULL);   // Not implemented ? B.A.
  111.     define_arg(args, ARG_MAPFILE,     ARGTYPE_STRING,              'm', "mapfile",     NULL);
  112.     define_arg(args, ARG_DEBUGFILE,   ARGTYPE_STRING,              'd', "debugfile",   NULL);   // Not implemented ? B.A.
  113.     define_arg(args, ARG_EEPFILE,     ARGTYPE_STRING,              'e', "eepfile",     NULL);   // Not implemented ? B.A.
  114.  
  115.  
  116.     c = read_args(args, argc, argv);
  117.    
  118.     if(c != 0) {
  119.           if(!GET_ARG(args, ARG_HELP) && (argc != 1))   {
  120.             if(!GET_ARG(args, ARG_VER)) {
  121.                   if(!GET_ARG(args, ARG_DEVICES)) {
  122.             pi = get_pi(args);
  123.                     if(pi) {
  124.               get_rootpath(pi, args);  /* get assembly root path */
  125.                           if (assemble(pi) != 0) { /* the main assembly call */
  126.                                   exit(EXIT_FAILURE);
  127.                           }
  128.                           free_pi(pi);             /* free all allocated memory */
  129.                         }
  130.                   }
  131.                   else {
  132.                     list_devices();            /* list all supported devices */
  133.                   }
  134.                 }
  135.           }
  136.           else
  137.             show_usage = True;
  138.         }
  139.         free_args(args);
  140.   }
  141.   else {
  142.         show_usage = True;
  143.         printf("\n");
  144.   }
  145.   if(show_usage) {
  146.         printf("%s", usage);
  147.   }
  148.   exit(EXIT_SUCCESS);
  149.   return (0);  /* compiler warning, JEG 4-23-03 */
  150. }
  151.  
  152. void get_rootpath(struct prog_info *pi, struct args *args)
  153. {
  154.   int i;
  155.   int j;
  156.   char c;
  157.   struct data_list *data;
  158.  
  159.   data = args->first_data;
  160.   if(!data)
  161.           return;
  162.   while(data->next) data = ((data)->next);
  163.  
  164.   if (data != NULL) {
  165.     i = strlen((char *)data->data);
  166.     if (i > 0) {
  167.       pi->root_path = malloc(i + 1);
  168.       strcpy(pi->root_path,(char *)data->data);
  169.       j = 0;
  170.       do {
  171.        c = pi->root_path[i];
  172.        if(c == '\\' || c == '/') {
  173.          j = i + 1;
  174.          break;
  175.        }
  176.       } while(i-- > 0);
  177.       pi->root_path[j] = '\0';
  178.       return;
  179.     }
  180.   }
  181.   pi->root_path = "";
  182. }
  183.  
  184.  
  185. int assemble(struct prog_info *pi) {
  186.   unsigned char c;
  187.  
  188.   if(pi->args->first_data) {
  189.         printf("Pass 1...\n");
  190.         if(load_arg_defines(pi)==False)
  191.                 return -1;
  192.         if(predef_dev(pi)==False) /* B.A.: Now with error check */
  193.                 return -1;
  194.         /*** FIRST PASS ***/
  195.         def_orglist(pi);                        /* B.A. : Store first active segment and seg_addr (Default : Code, Adr=0) */
  196.         c = parse_file(pi, (char *)pi->args->first_data->data);
  197.         fix_orglist(pi);                        /* B.A. : Update last active segment */
  198.         test_orglist(pi);                       /* B.A.: Test for overlapping memory segments and out of chip space */
  199.         if(c != False) {
  200. #if debug == 1
  201.                 printf("error_count = %i\n", pi->error_count);
  202. #endif
  203.                 /* B.A.: This part is obsolete. Now check is done in test_orglist() */
  204.                 /* before we go to the 2nd pass, make sure used space is ok */
  205.                 /* if(pi->eseg_count > pi->device->eeprom_size) {
  206.                         print_msg(pi, MSGTYPE_ERROR,
  207.                         "EEPROM space exceeded by %i bytes!", pi->eseg_count-pi->device->eeprom_size);
  208.                         return -1;
  209.                 }  
  210.                 if(pi->cseg_count > pi->device->flash_size) {
  211.                         print_msg(pi, MSGTYPE_ERROR,
  212.                         "FLASH space exceeded by %i bytes!", pi->cseg_count-pi->device->flash_size);
  213.                         return -1;
  214.                 } */
  215.  
  216.                 /* if there are no furter errors, we can continue with 2nd pass */
  217.                 if(pi->error_count == 0) {
  218.                         prepare_second_pass(pi);
  219.                         if(load_arg_defines(pi)==False)
  220.                                 return -1;
  221.                         if(predef_dev(pi)==False)       /* B.A.: Now with error check */
  222.                                 return -1;
  223.                         c = open_out_files(pi, pi->args->first_data->data);
  224.                         if(c != 0) {
  225.                                 printf("Pass 2...\n");
  226.                                 parse_file(pi, (char *)pi->args->first_data->data);
  227.                                 printf("done\n\n");
  228.                                 print_orglist(pi);      /* B.A.: List used memory segments */
  229.                                 if(GET_ARG(pi->args, ARG_COFF) && (pi->error_count == 0)) {
  230.                                         write_coff_file(pi);
  231.                                 }
  232.                                 write_map_file(pi);
  233.                                 if(pi->error_count) { /* if there were errors */
  234.                                         printf("\nAssembly aborted with %d errors and %d warnings.\n", pi->error_count, pi->warning_count);
  235.                                                 unlink_out_files(pi, pi->args->first_data->data);
  236.                                 } else { /* assembly was succesfull */
  237.                                         if(pi->warning_count)
  238.                                                 printf("\nAssembly complete with no errors (%d warnings).\n", pi->warning_count);
  239.                                         else
  240.                                                 printf("\nAssembly complete with no errors.\n");
  241.                                         close_out_files(pi);
  242.                                 }  
  243.                         }
  244.                 } else  {
  245.                         unlink_out_files(pi, pi->args->first_data->data);
  246.                 }  
  247.         }
  248.   } else {
  249.         printf("Error: You need to specify a file to assemble\n");
  250.   }
  251.   return pi->error_count;
  252. }
  253.  
  254.  
  255. int load_arg_defines(struct prog_info *pi)
  256. {
  257.   int i;
  258.   char *expr;
  259.   char buff[256];
  260.   struct data_list *define;
  261.  
  262.   for(define = GET_ARG(pi->args, ARG_DEFINE); define; define = define->next) {
  263.           strcpy(buff, define->data);
  264.           expr = get_next_token( buff, TERM_EQUAL);
  265.           if(expr) {
  266.           // we reach this, when there is actually a value passed..    
  267.             if(!get_expr(pi, expr, &i)) {
  268.                   return(False);
  269.             }
  270.     } else {
  271.           // if user didnt specify a value, we default to 1
  272.           i = 1;
  273.     }
  274.         /* B.A. : New. Forward references allowed. But check, if everything is ok ... */
  275.     if(pi->pass==PASS_1) { /* Pass 1 */
  276.       if(test_constant(pi,buff,NULL)!=NULL) {
  277.                 fprintf(stderr,"Error: Can't define symbol %s twice\n", buff);
  278.                 return(False);
  279.       }
  280.       if(def_const(pi, buff, i)==False)
  281.         return(False);
  282.                 } else { /* Pass 2 */
  283.                         int j;
  284.                         if(get_constant(pi, buff, &j)==False) {   /* Defined in Pass 1 and now missing ? */
  285.                                 fprintf(stderr,"Constant %s is missing in pass 2\n",buff);
  286.                                 return(False);
  287.                         }
  288.                         if(i != j) {
  289.                                 fprintf(stderr,"Constant %s changed value from %d in pass1 to %d in pass 2\n",buff,j,i);
  290.                                 return(False);
  291.                         }
  292.                                 /* OK. Definition is unchanged */
  293.                 }
  294.         }
  295.   return(True);
  296. }
  297.  
  298. /******************************************
  299.  * prog_info
  300.  ******************************************/
  301. struct prog_info *get_pi(struct args *args) {
  302.         struct prog_info *pi;
  303.         struct data_list *warnings;
  304.  
  305.         pi = (struct prog_info *)calloc(1, sizeof(struct prog_info));
  306.         if(!pi)
  307.                 return(NULL);
  308.         memset(pi, 0, sizeof(struct prog_info));
  309.         pi->args = args;
  310.         pi->device = get_device(pi,NULL);
  311.         if(GET_ARG(args, ARG_LISTFILE) == NULL) {
  312.                 pi->list_on = False;
  313.         } else {
  314.                 pi->list_on = True;
  315.         }
  316.         if(GET_ARG(args, ARG_MAPFILE) == NULL) {
  317.                 pi->map_on = False;
  318.         } else {
  319.                 pi->map_on = True;
  320.         }
  321.         for(warnings = GET_ARG(args, ARG_WARNINGS); warnings; warnings = warnings->next) {
  322.                 if(!nocase_strcmp(warnings->data, "NoRegDef"))
  323.                         pi->NoRegDef = 1;
  324.         }
  325.         pi->segment = SEGMENT_CODE;
  326.         pi->dseg_addr = pi->device->ram_start;
  327.         pi->max_errors = atoi(GET_ARG(args, ARG_MAX_ERRORS));
  328.         pi->pass=PASS_1;                /* B.A. : The pass variable is now stored in the pi struct */
  329.         pi->time=time(NULL);            /* B.A. : Now use a global timestamp  */
  330.         return(pi);
  331. }
  332.  
  333. void free_pi(struct prog_info *pi) {
  334.   free_defs(pi);                        /* B.A. : Now free in pi included structures first */
  335.   free_labels(pi);
  336.   free_constants(pi);
  337.   free_variables(pi);
  338.   free_blacklist(pi);
  339.   free_orglist(pi);
  340.   free(pi);
  341. }
  342.  
  343. void prepare_second_pass(struct prog_info *pi) {
  344.  
  345.   pi->segment = SEGMENT_CODE;
  346.   pi->cseg_addr = 0;
  347.   pi->dseg_addr = pi->device->ram_start;
  348.   pi->eseg_addr = 0;
  349.   //pi->macro_nstlblnr = 0;
  350.   pi->pass=PASS_2;                      /* B.A. : Change to pass 2. Now stored in pi struct. */
  351.   free_defs(pi);
  352.   // free_constants(pi);                /* B.A. : Now don't kill stored constants. We need them in the second pass now */
  353.   free_variables(pi);
  354. }
  355.  
  356.  
  357. void print_msg(struct prog_info *pi, int type, char *fmt, ... )
  358. {
  359.         char *pc;
  360.         if(type == MSGTYPE_OUT_OF_MEM) {
  361.                 fprintf(stderr, "Error: Unable to allocate memory!\n");
  362.         } else {
  363.                 if(type != MSGTYPE_APPEND) {                            /* B.A. Added for .message directive */
  364.                         if((pi->fi != NULL) && (pi->fi->include_file->name != NULL)) {  /* B.A.: Skip, if filename or fi is NULL (Bug 1462900) */
  365.                                 /* check if adding path name is needed*/
  366.                                 pc = strstr(pi->fi->include_file->name, pi->root_path);
  367.                                 if(pc == NULL) {
  368.                                         fprintf(stderr, "%s%s(%d) : ", pi->root_path ,pi->fi->include_file->name, pi->fi->line_number);
  369.                                 } else {
  370.                                         fprintf(stderr, "%s(%d) : ", pi->fi->include_file->name, pi->fi->line_number);
  371.                                 }
  372.                         }
  373.                 }
  374.                 switch(type) {
  375.                         case MSGTYPE_ERROR:
  376.                                 pi->error_count++;
  377.                                 fprintf(stderr, "Error   : ");
  378.                                 break;
  379.                         case MSGTYPE_WARNING:
  380.                                 pi->warning_count++;
  381.                                 fprintf(stderr, "Warning : ");
  382.                                 break;
  383.                         case MSGTYPE_MESSAGE:
  384. /*                      case MSGTYPE_MESSAGE_NO_LF:
  385.                         case MSGTYPE_APPEND: */
  386.                                 break;
  387.                 }
  388.                 if(type != MSGTYPE_APPEND) { /* B.A. Added for .message directive */
  389.                         if(pi->macro_call) {
  390.                                 fprintf(stderr, "[Macro: %s: %d:] ", pi->macro_call->macro->include_file->name,
  391.                                         pi->macro_call->line_index + pi->macro_call->macro->first_line_number);
  392.                         }
  393.                 }
  394.                 if(fmt != NULL) {
  395.                         va_list args;
  396.                         va_start(args, fmt);
  397.                         vfprintf(stderr, fmt, args);
  398.                         va_end(args);
  399.                 }
  400.  
  401.                 if( (type != MSGTYPE_APPEND) && (type != MSGTYPE_MESSAGE_NO_LF) )  /* B.A. Added for .message directive */
  402.                         fprintf(stderr, "\n");
  403.         }
  404. }
  405.  
  406.  
  407. /* B.A. : New functions to create / search / remove constant, variables, labels */
  408. /* def_const, def_var moved from device.c to this place */
  409. int def_const(struct prog_info *pi, const char *name, int value)
  410. {
  411.         struct label *label;
  412.         label = malloc(sizeof(struct label));
  413.         if(!label) {
  414.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  415.                 return(False);
  416.         }
  417.         label->next = NULL;
  418.         if(pi->last_constant)
  419.                 pi->last_constant->next = label;
  420.         else
  421.                 pi->first_constant = label;
  422.         pi->last_constant = label;
  423.         label->name = malloc(strlen(name) + 1);
  424.         if(!label->name) {
  425.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  426.                 return(False);
  427.         }
  428.         strcpy(label->name, name);
  429.         label->value = value;
  430.         return(True);
  431. }
  432.  
  433. int def_var(struct prog_info *pi, char *name, int value)
  434. {
  435.         struct label *label;
  436.  
  437.         for(label = pi->first_variable; label; label = label->next)
  438.                 if(!nocase_strcmp(label->name, name)) {
  439.                         label->value = value;
  440.                         return(True);
  441.                 }
  442.         label = malloc(sizeof(struct label));
  443.         if(!label) {
  444.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  445.                 return(False);
  446.         }
  447.         label->next = NULL;
  448.         if(pi->last_variable)
  449.                 pi->last_variable->next = label;
  450.         else
  451.                 pi->first_variable = label;
  452.         pi->last_variable = label;
  453.         label->name = malloc(strlen(name) + 1);
  454.         if(!label->name) {
  455.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  456.                 return(False);
  457.         }
  458.         strcpy(label->name, name);
  459.         label->value = value;
  460.         return(True);
  461. }
  462.  
  463.  
  464. int def_blacklist(struct prog_info *pi, const char *name)
  465. {
  466.         struct label *label;
  467.         label = malloc(sizeof(struct label));
  468.         if(!label) {
  469.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  470.                 return(False);
  471.         }
  472.         label->next = NULL;
  473.         if(pi->last_blacklist)
  474.                 pi->last_blacklist->next = label;
  475.         else
  476.                 pi->first_blacklist = label;
  477.         pi->last_blacklist = label;
  478.         label->name = malloc(strlen(name) + 1);
  479.         if(!label->name) {
  480.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  481.                 return(False);
  482.         }
  483.         strcpy(label->name, name);
  484.         label->value = 0;
  485.         return(True);
  486. }
  487.  
  488. /* B.A.: Store programmed areas for later check */
  489. int def_orglist(struct prog_info *pi)
  490. {
  491.         struct orglist *orglist;
  492.         if(pi->pass != PASS_1)
  493.                 return(True);
  494.         orglist = malloc(sizeof(struct orglist));
  495.         if(!orglist) {
  496.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  497.                 return(False);
  498.         }
  499.         orglist->next = NULL;
  500.         if(pi->last_orglist)
  501.                 pi->last_orglist->next = orglist;
  502.         else
  503.                 pi->first_orglist = orglist;
  504.         pi->last_orglist = orglist;
  505.         orglist->segment=pi->segment;
  506.         switch(pi->segment) {
  507.                 case SEGMENT_CODE:
  508.                         orglist->start = pi->cseg_addr;
  509.                         break;
  510.                 case SEGMENT_DATA:
  511.                         orglist->start = pi->dseg_addr;
  512.                         break;
  513.                 case SEGMENT_EEPROM:
  514.                         orglist->start = pi->eseg_addr;
  515.         }
  516.         orglist->length=0;
  517.         return(True);
  518. }
  519.  
  520. /* B.A.: Fill length entry of last orglist */
  521. int fix_orglist(struct prog_info *pi)
  522. {
  523.         if(pi->pass != PASS_1)
  524.                 return(True);
  525.         if((pi->last_orglist == NULL) || (pi->last_orglist->length!=0)) {
  526.                 fprintf(stderr,"Internal Error: fix_orglist\n");
  527.                 return(False);
  528.         }
  529.         pi->last_orglist->segment=pi->segment;
  530.         switch(pi->segment) {
  531.                 case SEGMENT_CODE:
  532.                         pi->last_orglist->length = pi->cseg_addr - pi->last_orglist->start;
  533.                         break;
  534.                 case SEGMENT_DATA:
  535.                         pi->last_orglist->length = pi->dseg_addr - pi->last_orglist->start;
  536.                         break;
  537.                 case SEGMENT_EEPROM:
  538.                         pi->last_orglist->length = pi->eseg_addr - pi->last_orglist->start;
  539.         }
  540.         return(True);
  541. }
  542.  
  543. /* B.A.: Debug output of orglist */
  544. void print_orglist(struct prog_info *pi)
  545. {
  546.         struct orglist *orglist=pi->first_orglist;
  547.         printf("Used memory blocks:\n");
  548.         while(orglist!=NULL) {
  549.                 if(orglist->length) { /* Skip blocks with size == 0 */
  550.                         switch(orglist->segment) {
  551.                                 case SEGMENT_CODE:
  552.                                         printf("   Code  "); break;
  553.                                 case SEGMENT_DATA:
  554.                                         printf("   Data  "); break;
  555.                                 case SEGMENT_EEPROM:
  556.                                         printf("   EEPROM"); break;
  557.                                 printf("INVALID SEGMENT DATA !\n");
  558.                         }      
  559.                         printf("    :  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
  560.                                 orglist->start,orglist->start+orglist->length-1,orglist->length);
  561.                 }
  562.                 orglist=orglist->next;
  563.         }
  564. }
  565.  
  566. /* B.A.: Test for overlapping segments and device space */
  567. int test_orglist(struct prog_info *pi)
  568. {
  569.         struct orglist *orglist2,*orglist=pi->first_orglist;
  570.         int error_count=0;
  571.         if(pi->device->name==NULL) {
  572.                 fprintf(stderr,"Warning : No .DEVICE definition found. Cannot make useful address range check !\n");
  573.                 pi->warning_count++;
  574.         }
  575.         while(orglist!=NULL) {
  576.                 if(orglist->length) { /* Skip blocks with size == 0 */
  577.                         // printf("Segment %d,  Start = %5d, Length = %5d\n",orglist->segment,orglist->start,orglist->length);
  578.                         /* Make sure address area is valid */
  579.                         switch(orglist->segment) {
  580.                                 case SEGMENT_CODE:
  581.                                         if((orglist->start + orglist->length) > pi->device->flash_size) {                                              
  582.                                                 fprintf(stderr,"Code segment exceeds valid address range [0..0x%04X] :",
  583.                                                         pi->device->flash_size-1);
  584.                                                 fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
  585.                                                         orglist->start,orglist->start+orglist->length-1,orglist->length);
  586.                                                 error_count++;
  587.                                         }
  588.                                         break;
  589.                                 case SEGMENT_DATA:
  590.                                         if(pi->device->ram_size == 0) {
  591.                                                 // Error message is generated in .DSEG directive. Skip ...
  592.                                                 // fprintf(stderr,"This device has no RAM. Don't use .DSEG \n");
  593.                                                 // error_count++;
  594.                                                 break;
  595.                                         }       // Fix bug 1742436. Added missing pi->device->ram_start
  596.                                         if(((orglist->start + orglist->length) > (pi->device->ram_size + pi->device->ram_start)) ||
  597.                                             (orglist->start < pi->device->ram_start)) {
  598.                                                 fprintf(stderr,"Data segment exceeds valid address range [0x%04X..0x%04X] :",
  599.                                                         pi->device->ram_start,pi->device->ram_start+pi->device->ram_size-1);
  600.                                                 fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
  601.                                                         orglist->start,orglist->start+orglist->length-1,orglist->length);
  602.                                                 error_count++;
  603.                                         }
  604.                                         break;
  605.                                 case SEGMENT_EEPROM: // Fix bug 1742437 : replace ram_size by eeprom_size
  606.                                         if(pi->device->eeprom_size == 0) {
  607.                                                 // Error message is generated in .ESEG directive. Skip ...
  608.                                                 // fprintf(stderr,"This device has no EEPROM. Don't use .ESEG !\n");
  609.                                                 // error_count++;
  610.                                                 break;
  611.                                         }
  612.                                         if((orglist->start + orglist->length) > pi->device->eeprom_size) {
  613.                                                 fprintf(stderr,"EEPROM segment exceeds valid address range [0..0x%04X] :",
  614.                                                         pi->device->eeprom_size-1);
  615.                                                 fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
  616.                                                         orglist->start,orglist->start+orglist->length-1,orglist->length);
  617.                                                 error_count++;
  618.                                         }
  619.                                         break;
  620.                         }
  621.                         /* Overlap-test */
  622.                         orglist2=orglist->next;
  623.                         while(orglist2!=NULL) {
  624.                                 if((orglist != orglist2) && (orglist2->length) && (orglist->segment == orglist2->segment)) {
  625.                                         // printf("<> Segment %d,  Start = %5d, Length = %5d\n",orglist2->segment,orglist2->start,orglist2->length);
  626.                                         if((orglist->start  < (orglist2->start + orglist2->length)) &&
  627.                                            (orglist2->start < ( orglist->start +  orglist->length))) {
  628.                                                 fprintf(stderr,"Error: Overlapping ");
  629.                                                 switch(orglist->segment) {
  630.                                                         case SEGMENT_CODE:
  631.                                                                 fprintf(stderr,"Code"); break;
  632.                                                         case SEGMENT_DATA:
  633.                                                                 fprintf(stderr,"Data"); break;
  634.                                                         case SEGMENT_EEPROM:
  635.                                                                 fprintf(stderr,"EEPROM"); break;
  636.                                                 }
  637.                                                 fprintf(stderr,"-segments :\n");
  638.                                                 fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
  639.                                                         orglist->start,orglist->start+orglist->length-1,orglist->length);
  640.                                                 fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
  641.                                                         orglist2->start,orglist2->start+orglist2->length-1,orglist2->length);
  642.                                                 fprintf(stderr,"Please check your .ORG directives !\n");
  643.                                                 error_count++;
  644.                                         }
  645.                                 }                              
  646.                                 orglist2=orglist2->next;
  647.                         }
  648.                 }
  649.                 orglist=orglist->next;
  650.         }
  651.         if(!error_count)
  652.                 return(True);
  653.         pi->error_count+=error_count;
  654.         return(False);
  655. }
  656.  
  657.  
  658.  
  659. /* Get the value of a label. Return FALSE if label was not found */
  660. int get_label(struct prog_info *pi,char *name,int *value)
  661. {
  662.   struct label *label=search_symbol(pi,pi->first_label,name,NULL);
  663.         if(label==NULL) return False;
  664.         if(value!=NULL) *value=label->value;   
  665.         return True;
  666. }
  667.  
  668. int get_constant(struct prog_info *pi,char *name,int *value)
  669. {
  670.   struct label *label=search_symbol(pi,pi->first_constant,name,NULL);
  671.         if(label==NULL) return False;
  672.         if(value!=NULL) *value=label->value;   
  673.         return True;
  674. }
  675.  
  676. int get_variable(struct prog_info *pi,char *name,int *value)
  677. {
  678.   struct label *label=search_symbol(pi,pi->first_variable,name,NULL);
  679.         if(label==NULL) return False;
  680.         if(value!=NULL) *value=label->value;   
  681.         return True;
  682. }
  683.  
  684. /* Test, if label exists. Return NULL -> not defined, else return the pointer to label struct */
  685. /* If message != NULL print error message if symbol is defined */
  686. struct label *test_label(struct prog_info *pi,char *name,char *message)
  687. {
  688.         return search_symbol(pi,pi->first_label,name,message);
  689. }
  690.  
  691. struct label *test_constant(struct prog_info *pi,char *name,char *message)
  692. {
  693.         return search_symbol(pi,pi->first_constant,name,message);
  694. }
  695.  
  696. struct label *test_variable(struct prog_info *pi,char *name,char *message)
  697. {
  698.         return search_symbol(pi,pi->first_variable,name,message);
  699. }
  700.  
  701. struct label *test_blacklist(struct prog_info *pi,char *name,char *message)
  702. {
  703.         return search_symbol(pi,pi->first_blacklist,name,message);
  704. }
  705.  
  706. /* Search in label,constant,variable,blacklist - list for a matching entry */
  707. /* Use first = pi->first_label,first_constant,first_variable,first_blacklist to select list */
  708. /* If message != NULL Print error message if symbol is defined */
  709. struct label *search_symbol(struct prog_info *pi,struct label *first,char *name,char *message)
  710. {
  711.         struct label *label;
  712.         for(label = first; label; label = label->next)
  713.                 if(!nocase_strcmp(label->name, name)) {
  714.                         if(message) {
  715.                                 print_msg(pi, MSGTYPE_ERROR, message, name);                               
  716.                         }
  717.                         return(label);
  718.                 }
  719.         return(NULL);
  720. }
  721.  
  722.  
  723. void free_defs(struct prog_info *pi)
  724. {
  725.   struct def *def, *temp_def;
  726.   for(def = pi->first_def; def;) {
  727.           temp_def = def;
  728.           def = def->next;
  729.           free(temp_def->name);
  730.           free(temp_def);
  731.   }
  732.   pi->first_def = NULL;
  733.   pi->last_def = NULL; 
  734. }
  735.  
  736. void free_labels(struct prog_info *pi)
  737. {
  738.   struct label *label, *temp_label;
  739.   for(label = pi->first_label; label;) {
  740.     temp_label = label;
  741.           label = label->next;
  742.           free(temp_label->name);
  743.           free(temp_label);
  744.   }
  745.   pi->first_label = NULL;
  746.   pi->last_label = NULL;
  747. }
  748.  
  749. void free_constants(struct prog_info *pi)
  750. {
  751.   struct label *label, *temp_label;
  752.   for(label = pi->first_constant; label;) {
  753.     temp_label = label;
  754.           label = label->next;
  755.           free(temp_label->name);
  756.           free(temp_label);
  757.   }
  758.   pi->first_constant = NULL;
  759.   pi->last_constant = NULL;
  760. }
  761.  
  762. void free_blacklist(struct prog_info *pi)
  763. {
  764.   struct label *label, *temp_label;
  765.   for(label = pi->first_blacklist; label;) {
  766.           temp_label = label;
  767.           label = label->next;
  768.           free(temp_label->name);
  769.           free(temp_label);
  770.   }
  771.   pi->first_blacklist = NULL;
  772.   pi->last_blacklist = NULL;
  773. }
  774.  
  775. void free_variables(struct prog_info *pi)
  776. {
  777.   struct label *label, *temp_label;
  778.   for(label = pi->first_variable; label;) {
  779.           temp_label = label;
  780.           label = label->next;
  781.           free(temp_label->name);
  782.           free(temp_label);
  783.   }
  784.   pi->first_variable = NULL;
  785.   pi->last_variable = NULL;
  786. }
  787.  
  788. void free_orglist(struct prog_info *pi)
  789. {
  790.   struct orglist *orglist, *temp_orglist;
  791.   for(orglist = pi->first_orglist; orglist;) {
  792.           temp_orglist = orglist;
  793.           orglist = orglist->next;
  794.           free(temp_orglist);
  795.   }
  796.   pi->first_orglist = NULL;
  797.   pi->last_orglist = NULL;
  798. }
  799.  
  800.  
  801. /* avra.c */
  802.  
  803.