Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6400 punk_joker 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 
29
#include 
30
#include 
31
#include 
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 ] output file name\n"
57
	"            [-l ] generate list file\n"
58
	"            [-m ] generate map file\n"
59
  "[--define [=]]  [--includedir ] [--listmac]\n"
60
	"            [--max_errors ] [--devices] [--version]\n"
61
	"            [-h] [--help] general help\n"
62
	"            "
63
	"            \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);
			vfprintf(stderr, fmt, args);
			va_end(args);
397
		}
398
399
		if( (type != MSGTYPE_APPEND) && (type != MSGTYPE_MESSAGE_NO_LF) )  /* B.A. Added for .message directive */
400
 
401
	}
402
}
403
404
405
 
406
 
407
int def_const(struct prog_info *pi, const char *name, int value)
408
{
409
	struct label *label;
410
	label = malloc(sizeof(struct label));
411
	if(!label) {
412
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
413
		return(False);
414
	}
415
	label->next = NULL;
416
	if(pi->last_constant)
417
		pi->last_constant->next = label;
418
	else
419
		pi->first_constant = label;
420
	pi->last_constant = label;
421
	label->name = malloc(strlen(name) + 1);
422
	if(!label->name) {
423
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
424
		return(False);
425
	}
426
	strcpy(label->name, name);
427
	label->value = value;
428
	return(True);
429
}
430
431
int def_var(struct prog_info *pi, char *name, int value)
432
 
433
	struct label *label;
434
435
 	for(label = pi->first_variable; label; label = label->next)
436
 
437
			label->value = value;
438
			return(True);
439
		}
440
	label = malloc(sizeof(struct label));
441
	if(!label) {
442
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
443
		return(False);
444
	}
445
	label->next = NULL;
446
	if(pi->last_variable)
447
		pi->last_variable->next = label;
448
	else
449
		pi->first_variable = label;
450
	pi->last_variable = label;
451
	label->name = malloc(strlen(name) + 1);
452
	if(!label->name) {
453
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
454
		return(False);
455
	}
456
	strcpy(label->name, name);
457
	label->value = value;
458
	return(True);
459
}
460
461
462
 
463
 
464
	struct label *label;
465
	label = malloc(sizeof(struct label));
466
	if(!label) {
467
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
468
		return(False);
469
	}
470
	label->next = NULL;
471
	if(pi->last_blacklist)
472
		pi->last_blacklist->next = label;
473
	else
474
		pi->first_blacklist = label;
475
	pi->last_blacklist = label;
476
	label->name = malloc(strlen(name) + 1);
477
	if(!label->name) {
478
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
479
		return(False);
480
	}
481
	strcpy(label->name, name);
482
	label->value = 0;
483
	return(True);
484
}
485
486
/* B.A.: Store programmed areas for later check */
487
 
488
{
489
	struct orglist *orglist;
490
	if(pi->pass != PASS_1)
491
		return(True);
492
	orglist = malloc(sizeof(struct orglist));
493
	if(!orglist) {
494
		print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
495
		return(False);
496
	}
497
	orglist->next = NULL;
498
	if(pi->last_orglist)
499
		pi->last_orglist->next = orglist;
500
	else
501
		pi->first_orglist = orglist;
502
	pi->last_orglist = orglist;
503
	orglist->segment=pi->segment;
504
	switch(pi->segment) {
505
		case SEGMENT_CODE:
506
			orglist->start = pi->cseg_addr;
507
			break;
508
		case SEGMENT_DATA:
509
			orglist->start = pi->dseg_addr;
510
			break;
511
		case SEGMENT_EEPROM:
512
			orglist->start = pi->eseg_addr;
513
	}
514
	orglist->length=0;
515
	return(True);
516
}
517
518
/* B.A.: Fill length entry of last orglist */
519
 
520
{
521
	if(pi->pass != PASS_1)
522
		return(True);
523
	if((pi->last_orglist == NULL) || (pi->last_orglist->length!=0)) {
524
        	fprintf(stderr,"Internal Error: fix_orglist\n");
525
		return(False);
526
	}
527
	pi->last_orglist->segment=pi->segment;
528
	switch(pi->segment) {
529
		case SEGMENT_CODE:
530
			pi->last_orglist->length = pi->cseg_addr - pi->last_orglist->start;
531
			break;
532
		case SEGMENT_DATA:
533
			pi->last_orglist->length = pi->dseg_addr - pi->last_orglist->start;
534
			break;
535
		case SEGMENT_EEPROM:
536
			pi->last_orglist->length = pi->eseg_addr - pi->last_orglist->start;
537
	}
538
	return(True);
539
}
540
541
/* B.A.: Debug output of orglist */
542
 
543
{
544
	struct orglist *orglist=pi->first_orglist;
545
	printf("Used memory blocks:\n");
546
	while(orglist!=NULL) {
547
		if(orglist->length) { /* Skip blocks with size == 0 */
548
			switch(orglist->segment) {
549
				case SEGMENT_CODE:
550
					printf("   Code  "); break;
551
				case SEGMENT_DATA:
552
					printf("   Data  "); break;
553
				case SEGMENT_EEPROM:
554
					printf("   EEPROM"); break;
555
				printf("INVALID SEGMENT DATA !\n");
556
			}
557
			printf("    :  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
558
				orglist->start,orglist->start+orglist->length-1,orglist->length);
559
		}
560
		orglist=orglist->next;
561
	}
562
}
563
564
/* B.A.: Test for overlapping segments and device space */
565
 
566
{
567
	struct orglist *orglist2,*orglist=pi->first_orglist;
568
	int error_count=0;
569
	if(pi->device->name==NULL) {
570
		fprintf(stderr,"Warning : No .DEVICE definition found. Cannot make useful address range check !\n");
571
		pi->warning_count++;
572
	}
573
	while(orglist!=NULL) {
574
		if(orglist->length) { /* Skip blocks with size == 0 */
575
			// printf("Segment %d,  Start = %5d, Length = %5d\n",orglist->segment,orglist->start,orglist->length);
576
			/* Make sure address area is valid */
577
			switch(orglist->segment) {
578
				case SEGMENT_CODE:
579
					if((orglist->start + orglist->length) > pi->device->flash_size) {
580
						fprintf(stderr,"Code segment exceeds valid address range [0..0x%04X] :",
581
							pi->device->flash_size-1);
582
						fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
583
							orglist->start,orglist->start+orglist->length-1,orglist->length);
584
						error_count++;
585
					}
586
					break;
587
				case SEGMENT_DATA:
588
					if(pi->device->ram_size == 0) {
589
						// Error message is generated in .DSEG directive. Skip ...
590
						// fprintf(stderr,"This device has no RAM. Don't use .DSEG \n");
591
						// error_count++;
592
						break;
593
					} 	// Fix bug 1742436. Added missing pi->device->ram_start
594
					if(((orglist->start + orglist->length) > (pi->device->ram_size + pi->device->ram_start)) ||
595
					    (orglist->start < pi->device->ram_start)) {
596
						fprintf(stderr,"Data segment exceeds valid address range [0x%04X..0x%04X] :",
597
							pi->device->ram_start,pi->device->ram_start+pi->device->ram_size-1);
598
						fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
599
							orglist->start,orglist->start+orglist->length-1,orglist->length);
600
						error_count++;
601
					}
602
					break;
603
				case SEGMENT_EEPROM: // Fix bug 1742437 : replace ram_size by eeprom_size
604
					if(pi->device->eeprom_size == 0) {
605
						// Error message is generated in .ESEG directive. Skip ...
606
						// fprintf(stderr,"This device has no EEPROM. Don't use .ESEG !\n");
607
						// error_count++;
608
						break;
609
					}
610
					if((orglist->start + orglist->length) > pi->device->eeprom_size) {
611
						fprintf(stderr,"EEPROM segment exceeds valid address range [0..0x%04X] :",
612
							pi->device->eeprom_size-1);
613
						fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
614
							orglist->start,orglist->start+orglist->length-1,orglist->length);
615
						error_count++;
616
					}
617
					break;
618
			}
619
			/* Overlap-test */
620
			orglist2=orglist->next;
621
			while(orglist2!=NULL) {
622
				if((orglist != orglist2) && (orglist2->length) && (orglist->segment == orglist2->segment)) {
623
					// printf("<> Segment %d,  Start = %5d, Length = %5d\n",orglist2->segment,orglist2->start,orglist2->length);
624
					if((orglist->start  < (orglist2->start + orglist2->length)) &&
625
					   (orglist2->start < ( orglist->start +  orglist->length))) {
626
						fprintf(stderr,"Error: Overlapping ");
627
						switch(orglist->segment) {
628
							case SEGMENT_CODE:
629
								fprintf(stderr,"Code"); break;
630
							case SEGMENT_DATA:
631
								fprintf(stderr,"Data"); break;
632
							case SEGMENT_EEPROM:
633
								fprintf(stderr,"EEPROM"); break;
634
						}
635
						fprintf(stderr,"-segments :\n");
636
						fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
637
							orglist->start,orglist->start+orglist->length-1,orglist->length);
638
						fprintf(stderr,"  Start = 0x%04X, End = 0x%04X, Length = 0x%04X\n",
639
							orglist2->start,orglist2->start+orglist2->length-1,orglist2->length);
640
						fprintf(stderr,"Please check your .ORG directives !\n");
641
						error_count++;
642
					}
643
				}
644
				orglist2=orglist2->next;
645
			}
646
		}
647
		orglist=orglist->next;
648
	}
649
	if(!error_count)
650
		return(True);
651
	pi->error_count+=error_count;
652
	return(False);
653
}
654
655
656
 
657
 
658
 
659
{
660
  struct label *label=search_symbol(pi,pi->first_label,name,NULL);
661
	if(label==NULL) return False;
662
	if(value!=NULL)	*value=label->value;
663
	return True;
664
}
665
666
int get_constant(struct prog_info *pi,char *name,int *value)
667
 
668
  struct label *label=search_symbol(pi,pi->first_constant,name,NULL);
669
	if(label==NULL) return False;
670
	if(value!=NULL)	*value=label->value;
671
	return True;
672
}
673
674
int get_variable(struct prog_info *pi,char *name,int *value)
675
 
676
  struct label *label=search_symbol(pi,pi->first_variable,name,NULL);
677
	if(label==NULL) return False;
678
	if(value!=NULL)	*value=label->value;
679
	return True;
680
}
681
682
/* Test, if label exists. Return NULL -> not defined, else return the pointer to label struct */
683
 
684
struct label *test_label(struct prog_info *pi,char *name,char *message)
685
{
686
	return search_symbol(pi,pi->first_label,name,message);
687
}
688
689
struct label *test_constant(struct prog_info *pi,char *name,char *message)
690
 
691
	return search_symbol(pi,pi->first_constant,name,message);
692
}
693
694
struct label *test_variable(struct prog_info *pi,char *name,char *message)
695
 
696
	return search_symbol(pi,pi->first_variable,name,message);
697
}
698
699
struct label *test_blacklist(struct prog_info *pi,char *name,char *message)
700
 
701
	return search_symbol(pi,pi->first_blacklist,name,message);
702
}
703
704
/* Search in label,constant,variable,blacklist - list for a matching entry */
705
 
706
/* If message != NULL Print error message if symbol is defined */
707
struct label *search_symbol(struct prog_info *pi,struct label *first,char *name,char *message)
708
{
709
	struct label *label;
710
	for(label = first; label; label = label->next)
711
		if(!nocase_strcmp(label->name, name)) {
712
			if(message) {
713
				print_msg(pi, MSGTYPE_ERROR, message, name);
714
			}
715
			return(label);
716
		}
717
	return(NULL);
718
}
719
720
721
 
722
 
723
  struct def *def, *temp_def;
724
  for(def = pi->first_def; def;) {
725
	  temp_def = def;
726
	  def = def->next;
727
	  free(temp_def->name);
728
	  free(temp_def);
729
  }
730
  pi->first_def = NULL;
731
  pi->last_def = NULL;
732
}
733
734
void free_labels(struct prog_info *pi)
735
 
736
  struct label *label, *temp_label;
737
  for(label = pi->first_label; label;) {
738
    temp_label = label;
739
	  label = label->next;
740
	  free(temp_label->name);
741
	  free(temp_label);
742
  }
743
  pi->first_label = NULL;
744
  pi->last_label = NULL;
745
}
746
747
void free_constants(struct prog_info *pi)
748
 
749
  struct label *label, *temp_label;
750
  for(label = pi->first_constant; label;) {
751
    temp_label = label;
752
	  label = label->next;
753
	  free(temp_label->name);
754
	  free(temp_label);
755
  }
756
  pi->first_constant = NULL;
757
  pi->last_constant = NULL;
758
}
759
760
void free_blacklist(struct prog_info *pi)
761
 
762
  struct label *label, *temp_label;
763
  for(label = pi->first_blacklist; label;) {
764
	  temp_label = label;
765
	  label = label->next;
766
	  free(temp_label->name);
767
	  free(temp_label);
768
  }
769
  pi->first_blacklist = NULL;
770
  pi->last_blacklist = NULL;
771
}
772
773
void free_variables(struct prog_info *pi)
774
 
775
  struct label *label, *temp_label;
776
  for(label = pi->first_variable; label;) {
777
	  temp_label = label;
778
	  label = label->next;
779
	  free(temp_label->name);
780
	  free(temp_label);
781
  }
782
  pi->first_variable = NULL;
783
  pi->last_variable = NULL;
784
}
785
786
void free_orglist(struct prog_info *pi)
787
 
788
  struct orglist *orglist, *temp_orglist;
789
  for(orglist = pi->first_orglist; orglist;) {
790
	  temp_orglist = orglist;
791
	  orglist = orglist->next;
792
	  free(temp_orglist);
793
  }
794
  pi->first_orglist = NULL;
795
  pi->last_orglist = NULL;
796
}
797
798
799
 
800