1 /***********************************************************************
2  *
3  *  AVRA - Assembler for the Atmel AVR microcontroller series
4  *
5  *  Copyright (C) 1998-2020 The AVRA Authors
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: https://github.com/Ro5bert/avra
26  */
27 
28 #ifndef _AVRA_H_
29 #define _AVRA_H_
30 
31 #include <stdio.h>
32 #include <time.h>
33 
34 #define IS_HOR_SPACE(x)	((x == ' ') || (x == 9))
35 #define IS_LABEL(x)	(isalnum(x) || (x == '%') || (x == '_'))
36 #define IS_END_OR_COMMENT(x)	((x == ';') || (x == 10) || (x == 13) || (x == '\0') || (x == 12))
37 #define IS_ENDLINE(x)	((x == 10) || (x == 13) || (x == '\0') || (x == 12))
38 #define IS_SEPARATOR(x)	((x == ' ') || (x == ',') || (x == '[') || (x == ']'))
39 
40 #define LINEBUFFER_LENGTH 4096
41 #define MAX_NESTED_MACROLOOPS 256
42 
43 #define MAX_MACRO_ARGS 10
44 
45 /* warning switches */
46 
47 /* Option enumeration */
48 enum {
49 	ARG_DEFINE = 0,		/* --define, -D            */
50 	ARG_INCLUDEPATH,	/* --includedir, -I        */
51 	ARG_LISTMAC,		/* --listmac               */
52 	ARG_MAX_ERRORS,		/* --max_errors            */
53 	ARG_COFF,		/* --coff                  */
54 	ARG_DEVICES,		/* --devices               */
55 	ARG_VER,		/* --version               */
56 	ARG_HELP,		/* --help, -h              */
57 	ARG_WRAP,		/* --wrap                  */
58 	ARG_WARNINGS,		/* --warn, -W              */
59 	ARG_FILEFORMAT,		/* --filetype              */
60 	ARG_LISTFILE,		/* --listfile              */
61 	ARG_OUTFILE,		/* --outfile   */
62 	ARG_MAPFILE,		/* --mapfile   */
63 	ARG_DEBUGFILE,		/* --debugfile */
64 	ARG_EEPFILE,		/* --eepfile   */
65 	ARG_OVERLAP,		/* -O [w|e|i]  */
66 	ARG_COUNT
67 };
68 
69 enum {
70 	MSGTYPE_ERROR = 0,
71 	MSGTYPE_WARNING,
72 	MSGTYPE_MESSAGE,
73 	MSGTYPE_OUT_OF_MEM,
74 	MSGTYPE_MESSAGE_NO_LF, /* Like MSGTYPE_MESSAGE, but without /n */
75 	MSGTYPE_APPEND         /* Print Message without any header and without /n. To append messages */
76 };
77 
78 enum {
79 	PASS_1 = 0,
80 	PASS_2
81 };
82 
83 enum {
84 	SEGMENT_CODE = 0,
85 	SEGMENT_DATA,
86 	SEGMENT_EEPROM
87 };
88 
89 enum {
90 	OVERLAP_UNDEFINED = -1,
91 	OVERLAP_DEFAULT = 0,
92 	OVERLAP_IGNORE,
93 	OVERLAP_WARNING,
94 	OVERLAP_ERROR
95 };
96 
97 enum {
98 	SEG_DONT_OVERLAP = 0,
99 	SEG_ALLOW_OVERLAP
100 };
101 
102 enum {
103 	TERM_END = 0,
104 	TERM_SPACE,
105 	TERM_COMMA,
106 	TERM_EQUAL,
107 	TERM_DASH,
108 	TERM_DOUBLEQUOTE,
109 	TERM_COLON
110 };
111 
112 /* Structures */
113 
114 struct prog_info;
115 
116 extern const int SEG_BSS_DATA;
117 
118 struct segment_info {
119 	const char *name;
120 	char ident;	  /* C, D, E */
121 	long addr;    /* address in cells */
122 	long count;   /* length in cells  */
123 	long lo_addr; /* lowest addr supported */
124 	long hi_addr; /* one past highest addr supported */
125 	int	cellsize; /* 1 for data/eeprom, 2 for flash  */
126 	int flags;	  /* SEG_BSS_DATA */
127 
128 	struct prog_info *pi;
129 	struct hex_file_info *hfi;
130 	struct orglist *first_orglist;
131 	struct orglist *last_orglist;
132 
133 	const char *cellname;  /* byte  / word  */
134 	const char *cellnames; /* bytes / words */
135 };
136 
137 struct prog_info {
138 	struct args *args;
139 	struct device *device;
140 	struct file_info *fi;
141 	struct macro_call *macro_call;
142 	struct macro_line *macro_line;
143 	FILE *list_file;
144 	int list_on;
145 	int map_on;
146 	char *list_line;
147 	char *root_path;
148 	FILE *obj_file;
149 	struct segment_info *segment;
150 	struct segment_info *cseg;
151 	struct segment_info *dseg;
152 	struct segment_info *eseg;
153 	int error_count;
154 	int max_errors;
155 	int warning_count;
156 	struct include_file *last_include_file;
157 	struct include_file *first_include_file;
158 	struct def *first_def;
159 	struct def *last_def;
160 	struct label *first_label;
161 	struct label *last_label;
162 	struct label *first_constant;
163 	struct label *last_constant;
164 	struct label *first_variable;
165 	struct label *last_variable;
166 	struct location *first_ifdef_blacklist;
167 	struct location *last_ifdef_blacklist;
168 	struct location *first_ifndef_blacklist;
169 	struct location *last_ifndef_blacklist;
170 	struct macro *first_macro;
171 	struct macro *last_macro;
172 	struct macro_call *first_macro_call;
173 	struct macro_call *last_macro_call;
174 	struct orglist *first_orglist;	/* List of used memory segments. Needed for overlap-check */
175 	struct orglist *last_orglist;
176 	int effective_overlap; /* as specified by #pragma overlap */
177 	int segment_overlap;   /* set by .NOOVERLAP, .OVERLAP     */
178 	int conditional_depth;
179 	time_t time;			/* Use a global timestamp for listing header and %hour% ... tags */
180 	/* coff additions */
181 	FILE *coff_file;
182 	/* Warning additions */
183 	int NoRegDef;
184 	int pass;
185 };
186 
187 struct file_info {
188 	FILE *fp;
189 	struct include_file *include_file;
190 	char buff[LINEBUFFER_LENGTH];
191 	char scratch[LINEBUFFER_LENGTH];
192 	int line_number;
193 	int exit_file;
194 	struct label *label;
195 };
196 
197 struct hex_file_info {
198 	FILE *fp;
199 	int count;
200 	int linestart_addr;
201 	int segment;
202 	unsigned char hex_line[16];
203 };
204 
205 struct include_file {
206 	struct include_file *next;
207 	char *name;
208 	int num;
209 };
210 
211 struct def {
212 	struct def *next;
213 	char *name;
214 	int reg;
215 };
216 
217 struct label {
218 	struct label *next;
219 	char *name;
220 	int value;
221 };
222 
223 struct macro {
224 	struct macro *next;
225 	char *name;
226 	struct include_file *include_file;
227 	int first_line_number;
228 	struct macro_line *first_macro_line;
229 	struct macro_label *first_label;
230 };
231 
232 struct macro_label {
233 	char *label;
234 	struct macro_label *next;
235 	int running_number;
236 	int flags;
237 };
238 extern	const int ML_DEFINED;
239 
240 struct macro_line {
241 	struct macro_line *next;
242 	char *line;
243 };
244 
245 struct macro_call {
246 	struct macro_call *next;
247 	int line_number;
248 	struct include_file *include_file;
249 	struct macro_call *prev_on_stack;
250 	struct macro *macro;
251 	int line_index;
252 	int prev_line_index;
253 	int nest_level;
254 	struct label *first_label;
255 	struct label *last_label;
256 };
257 
258 struct orglist {
259 	struct orglist *next;
260 	struct segment_info *segment;
261 	int start;
262 	int length;
263 	int segment_overlap;
264 };
265 
266 struct location {
267 	struct location *next;
268 	int line_num;
269 	int file_num;
270 };
271 
272 /* Prototypes */
273 /* avra.c */
274 int assemble(struct prog_info *pi);
275 int load_arg_defines(struct prog_info *pi);
276 struct prog_info *init_prog_info(struct prog_info *,struct args *args);
277 void free_pi(struct prog_info *pi);
278 void print_msg(struct prog_info *pi, int type, char *fmt, ...);
279 void get_rootpath(struct prog_info *pi, struct args *args);
280 
281 void init_segment_size(struct prog_info *pi, struct device *device);
282 void rewind_segments(struct prog_info *pi);
283 void advance_ip(struct segment_info *si, int offset);
284 
285 int def_const(struct prog_info *pi, const char *name, int value);
286 int def_var(struct prog_info *pi, char *name, int value);
287 int def_orglist(struct segment_info *si);
288 int fix_orglist(struct segment_info *si);
289 void fprint_orglist(FILE *file, struct segment_info *si, struct orglist *orglist);
290 void fprint_sef_orglist(FILE *file, struct segment_info *si);
291 void fprint_segments(FILE *file, struct prog_info *pi);
292 int test_orglist(struct segment_info *si);
293 int get_label(struct prog_info *pi,char *name,int *value);
294 int get_constant(struct prog_info *pi,char *name,int *value);
295 int get_variable(struct prog_info *pi,char *name,int *value);
296 struct label *test_label(struct prog_info *pi,char *name,char *message);
297 struct label *test_constant(struct prog_info *pi,char *name,char *message);
298 struct label *test_variable(struct prog_info *pi,char *name,char *message);
299 struct label *search_symbol(struct prog_info *pi,struct label *first,char *name,char *message);
300 int ifdef_blacklist(struct prog_info *pi);
301 int ifndef_blacklist(struct prog_info *pi);
302 int ifdef_is_blacklisted(struct prog_info *pi);
303 int ifndef_is_blacklisted(struct prog_info *pi);
304 int search_location(struct location *first, int line_num, int file_num);
305 void free_defs(struct prog_info *pi);
306 void free_labels(struct prog_info *pi);
307 void free_constants(struct prog_info *pi);
308 void free_ifdef_blacklist(struct prog_info *pi);
309 void free_ifndef_blacklist(struct prog_info *pi);
310 void free_variables(struct prog_info *pi);
311 void free_orglist(struct prog_info *pi);
312 
313 /* parser.c */
314 int parse_file(struct prog_info *pi, const char *filename);
315 int parse_line(struct prog_info *pi, char *line);
316 char *get_next_token(char *scratch, int term);
317 char *fgets_new(struct prog_info *pi, char *s, int size, FILE *stream);
318 
319 /* expr.c */
320 int get_expr(struct prog_info *pi, char *data, int *value);
321 int get_symbol(struct prog_info *pi, char *label_name, int *data);
322 int par_length(char *data);
323 
324 /* mnemonic.c */
325 int parse_mnemonic(struct prog_info *pi);
326 int get_mnemonic_type(struct prog_info *pi);
327 int get_register(struct prog_info *pi, char *data);
328 int get_bitnum(struct prog_info *pi, char *data, int *ret);
329 int get_indirect(struct prog_info *pi, char *operand);
330 int is_supported(struct prog_info *pi, char *name);
331 int count_supported_instructions(int flags);
332 
333 /* directiv.c */
334 int parse_directive(struct prog_info *pi);
335 int lookup_keyword(const char *const keyword_list[], const char *const keyword, int strict);
336 char *term_string(struct prog_info *pi, char *string);
337 int parse_db(struct prog_info *pi, char *next);
338 void write_db(struct prog_info *pi, char byte, char *prev, int count);
339 int spool_conditional(struct prog_info *pi, int only_endif);
340 int check_conditional(struct prog_info *pi, char *buff, int *current_depth, int *do_next, int only_endif);
341 int test_include(const char *filename);
342 
343 /* macro.c */
344 int read_macro(struct prog_info *pi, char *name);
345 struct macro *get_macro(struct prog_info *pi, char *name);
346 struct macro_label *get_macro_label(char *line, struct macro *macro);
347 int expand_macro(struct prog_info *pi, struct macro *macro, char *rest_line);
348 
349 
350 /* file.c */
351 int open_out_files(struct prog_info *pi, const char *basename, const char *outputfile,
352                    const char *debugfile, const char *eepfile);
353 void close_out_files(struct prog_info *pi);
354 struct hex_file_info *open_hex_file(const char *filename);
355 void close_hex_file(struct hex_file_info *hfi);
356 void write_ee_byte(struct prog_info *pi, int address, unsigned char data);
357 void write_prog_word(struct prog_info *pi, int address, int data);
358 void do_hex_line(struct hex_file_info *hfi);
359 FILE *open_obj_file(struct prog_info *pi, const char *filename);
360 void close_obj_file(struct prog_info *pi, FILE *fp);
361 void write_obj_record(struct prog_info *pi, int address, int data);
362 void unlink_out_files(struct prog_info *pi, const char *filename);
363 
364 /* map.c */
365 void write_map_file(struct prog_info *pi);
366 char *Space(char *n);
367 
368 /* stdextra.c */
369 char *nocase_strcmp(const char *s, const char *t);
370 char *nocase_strncmp(char *s, char *t, int n);
371 char *nocase_strstr(char *s, char *t);
372 int atox(char *s);
373 int atoi_n(char *s, int n);
374 int atox_n(char *s, int n);
375 char *my_strlwr(char *in);
376 char *my_strupr(char *in);
377 char *snprint_list(char *buf, size_t limit, const char *const list[]);
378 
379 /* coff.c */
380 FILE *open_coff_file(struct prog_info *pi, char *filename);
381 void write_coff_file(struct prog_info *pi);
382 void write_coff_eeprom(struct prog_info *pi, int address, unsigned char data);
383 void write_coff_program(struct prog_info *pi, int address, unsigned int data);
384 void close_coff_file(struct prog_info *pi, FILE *fp);
385 int parse_stabs(struct prog_info *pi, char *p);
386 int parse_stabn(struct prog_info *pi, char *p);
387 
388 #endif /* end of avra.h */
389 
390 
391