OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [Open8 Tools/] [open8_src/] [open8_as/] [main.c] - Blame information for rev 207

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 178 jshamlet
#ifdef WIN32
2
#define WIN32_LEAN_AND_MEAN
3
#include <windows.h>
4
#undef SUCCEEDED
5
#undef FAILED
6
#endif
7
 
8
#include <ctype.h>
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <string.h>
12
#include <time.h>
13
 
14
#ifdef UNIX
15
#include <unistd.h>
16
#endif
17
 
18
#include "main.h"
19
#include "defines.h"
20
 
21
#include "parse.h"
22
#include "include_file.h"
23
#include "pass_1.h"
24
#include "pass_2.h"
25
#include "pass_3.h"
26
#include "pass_4.h"
27
#include "listfile.h"
28
 
29
 
30
FILE *file_out_ptr = NULL;
31
 
32
char wla_version[] = "9.3";
33
 
34
char gba_tmp_name[32], gba_unfolded_name[32];
35
 
36
extern struct incbin_file_data *incbin_file_data_first, *ifd_tmp;
37
extern struct file_name_info *file_name_info_first;
38
extern struct label_def *label_tmp, *labels;
39
extern struct macro_static *macros_first;
40
extern struct definition *defines, *tmp_def;
41
extern struct export_def *export_first, *export_last;
42
extern struct stack *stacks_first, *stacks_tmp, *stacks_last, *stacks_header_first, *stacks_header_last;
43
extern struct repeat_runtime *repeat_stack;
44
extern struct section_def *sections_first;
45
extern struct macro_runtime *macro_stack;
46
extern struct label_def *unknown_labels;
47
extern struct filepointer *filepointers;
48
extern char *unfolded_buffer;
49
extern char *include_in_tmp, *tmp_a;
50
extern char *rom_banks, *rom_banks_usage_table;
51
extern char *include_dir, *buffer, *full_name;
52
extern int include_in_tmp_size, tmp_a_size, *banks, *bankaddress;
53
 
54
int output_format = OUTPUT_NONE, verbose_mode = OFF, test_mode = OFF;
55
int extra_definitions = OFF, commandline_parsing = ON, makefile_rules = NO;
56
int listfile_data = NO, quiet = NO;
57
 
58
char *final_name = NULL, *asm_name = NULL;
59
 
60
 
61
 
62
int main(int argc, char *argv[]) {
63
 
64
  int i = SUCCEEDED;
65
 
66
 
67
  if (sizeof(double) != 8) {
68
    fprintf(stderr, "MAIN: sizeof(double) == %ld != 8. Open8_as will not work properly.\n", sizeof(double));
69
    return -1;
70
  }
71
 
72
  atexit(procedures_at_exit);
73
 
74
  /* init the randon number generator */
75
  srand(time(NULL));
76
 
77
  if (argc >= 3) {
78
    if (parse_flags(argv[1]) == SUCCEEDED) {
79
      if (parse_defines_and_get_final_name(argv + 2, argc - 2) == FAILED)
80
        return 1;
81
    }
82
    else
83
      i = FAILED;
84
  }
85
  else
86
    i = FAILED;
87
 
88
  if (i == FAILED || output_format == OUTPUT_NONE) {
89
    printf("\nOpen8 Assembler v1.0b\n\n");
90
    printf("Based on WLA assembler by Ville Helin\n");
91
    printf("Modified for V8 uRISC architecture by Bill Wiley\n");
92
    printf("Modified for Open8 uRISC architecture by Seth Henry\n\n");
93
    printf("Includes support for optional Open8 features:\n");
94
    printf("Index Register Autoincrement and BRK_implements_WAI\n\n");
95
    printf("USAGE: %s -[iMqtvx]{lo} [DEFINITIONS] <ASM FILE> [OUTPUT FILE]\n", argv[0]);
96
    printf("Commands:             Options:\n");
97
    printf("l  Library file       i  Add list file information\n");
98
    printf("o  Object file        M  Output makefile rules\n");
99
    printf("                      q  Quiet\n");
100
    printf("                      t  Test compile\n");
101
    printf("                      v  Verbose messages\n");
102
    printf("                      x  Extra compile time definitions\n\n");
103
 
104
    return 0;
105
  }
106
 
107
  if (strcmp(asm_name, final_name) == 0) {
108
    fprintf(stderr, "MAIN: Input and output files share the same name!\n");
109
    return 1;
110
  }
111
 
112
  generate_tmp_names();
113
 
114
  file_out_ptr = fopen(gba_tmp_name, "wb");
115
  if (file_out_ptr == NULL) {
116
    fprintf(stderr, "MAIN: Error opening file \"%s\".\n", gba_tmp_name);
117
    return 1;
118
  }
119
 
120
  /* small inits */
121
  if (extra_definitions == ON)
122
    generate_extra_definitions();
123
 
124
  commandline_parsing = OFF;
125
 
126
  /* start the process */
127
  if (include_file(asm_name) == FAILED)
128
    return 1;
129
 
130
  if (pass_1() == FAILED)
131
    return 1;
132
  if (pass_2() == FAILED)
133
    return 1;
134
  if (pass_3() == FAILED)
135
    return 1;
136
  if (listfile_data == YES) {
137
    if (listfile_collect() == FAILED)
138
      return 1;
139
  }
140
  if (pass_4() == FAILED)
141
    return 1;
142
 
143
  return 0;
144
}
145
 
146
 
147
int parse_flags(char *f) {
148
 
149
  int l;
150
 
151
 
152
  if (*f != '-')
153
    return FAILED;
154
 
155
  l = strlen(f);
156
  if (l == 1)
157
    return FAILED;
158
 
159
  for (f++, l--; l > 0; l--, f++) {
160
    switch (*f) {
161
 
162
    case 'o':
163
      if (output_format != OUTPUT_NONE)
164
        return FAILED;
165
      output_format = OUTPUT_OBJECT;
166
      continue;
167
 
168
    case 'l':
169
      if (output_format != OUTPUT_NONE)
170
        return FAILED;
171
      output_format = OUTPUT_LIBRARY;
172
      continue;
173
 
174
    case 'i':
175
      listfile_data = YES;
176
      continue;
177
 
178
    case 'v':
179
      verbose_mode = ON;
180
      continue;
181
 
182
    case 't':
183
      test_mode = ON;
184
      continue;
185
 
186
    case 'M':
187
      makefile_rules = YES;
188
      test_mode = ON;
189
      verbose_mode = OFF;
190
      quiet = YES;
191
      continue;
192
 
193
    case 'q':
194
      quiet = YES;
195
      continue;
196
 
197
    case 'x':
198
      extra_definitions = ON;
199
      continue;
200
 
201
    default:
202
      return FAILED;
203
    }
204
  }
205
 
206
  return SUCCEEDED;
207
}
208
 
209
 
210
void procedures_at_exit(void) {
211
 
212
  struct file_name_info *f, *ft;
213
  struct export_def *export_tmp;
214
  struct section_def *s1, *s2;
215
  struct label_def *l1, *l2;
216
  struct macro_static *m;
217
  struct filepointer *f1, *f2;
218
  int i;
219
 
220
 
221
  /* free all the dynamically allocated data structures and close open files */
222
  if (file_out_ptr != NULL)
223
    fclose(file_out_ptr);
224
 
225
  if (macro_stack != NULL)
226
    free(macro_stack);
227
 
228
  if (repeat_stack != NULL)
229
    free(repeat_stack);
230
 
231
  if (final_name != NULL)
232
    free(final_name);
233
 
234
  if (asm_name != NULL)
235
    free(asm_name);
236
 
237
  if (include_dir != NULL)
238
    free(include_dir);
239
 
240
  if (full_name != NULL)
241
    free(full_name);
242
 
243
  tmp_def = defines;
244
  while (tmp_def != NULL) {
245
    defines = tmp_def->next;
246
    free(tmp_def);
247
    tmp_def = defines;
248
  }
249
 
250
  m = macros_first;
251
  while (m != NULL) {
252
    /* free the argument labels */
253
    if (m->nargument_names > 0) {
254
      for (i = 0; i < m->nargument_names; i++)
255
        free(m->argument_names[i]);
256
      free(m->argument_names);
257
    }
258
    macros_first = m->next;
259
    free(m);
260
    m = macros_first;
261
  }
262
 
263
  label_tmp = labels;
264
  while (label_tmp != NULL) {
265
    labels = label_tmp->next;
266
    free(label_tmp);
267
    label_tmp = labels;
268
  }
269
 
270
  l1 = unknown_labels;
271
  while (l1 != NULL) {
272
    l2 = l1->next;
273
    free(l1);
274
    l1 = l2;
275
  }
276
 
277
  export_tmp = export_first;
278
  while (export_tmp != NULL) {
279
    export_last = export_tmp->next;
280
    free(export_tmp);
281
    export_tmp = export_last;
282
  }
283
 
284
  ifd_tmp = incbin_file_data_first;
285
  while(ifd_tmp != NULL) {
286
    incbin_file_data_first = ifd_tmp->next;
287
    if (ifd_tmp->data != NULL)
288
      free(ifd_tmp->data);
289
    if (ifd_tmp->name != NULL)
290
      free(ifd_tmp->name);
291
    free(ifd_tmp);
292
    ifd_tmp = incbin_file_data_first;
293
  }
294
 
295
  stacks_tmp = stacks_first;
296
  while (stacks_tmp != NULL) {
297
    free(stacks_tmp->stack);
298
    stacks_first = stacks_tmp->next;
299
    free(stacks_tmp);
300
    stacks_tmp = stacks_first;
301
  }
302
 
303
  stacks_tmp = stacks_header_first;
304
  while (stacks_tmp != NULL) {
305
    free(stacks_tmp->stack);
306
    stacks_first = stacks_tmp->next;
307
    free(stacks_tmp);
308
    stacks_tmp = stacks_first;
309
  }
310
 
311
  if (unfolded_buffer != NULL)
312
    free(unfolded_buffer);
313
 
314
  if (buffer != NULL)
315
    free(buffer);
316
 
317
  if (include_in_tmp != NULL)
318
    free(include_in_tmp);
319
  if (tmp_a != NULL)
320
    free(tmp_a);
321
 
322
  if (rom_banks != NULL)
323
    free(rom_banks);
324
  if (rom_banks_usage_table != NULL)
325
    free(rom_banks_usage_table);
326
  if (banks != NULL)
327
    free(banks);
328
  if (bankaddress != NULL)
329
    free(bankaddress);
330
 
331
  f = file_name_info_first;
332
  while (f != NULL) {
333
    if (f->name != NULL)
334
      free(f->name);
335
    ft = f->next;
336
    free(f);
337
    f = ft;
338
  }
339
 
340
  s1 = sections_first;
341
  while (s1 != NULL) {
342
    if (s1->data != NULL)
343
      free(s1->data);
344
    if (s1->listfile_cmds != NULL)
345
      free(s1->listfile_cmds);
346
    if (s1->listfile_ints != NULL)
347
      free(s1->listfile_ints);
348
    s2 = s1->next;
349
    free(s1);
350
    s1 = s2;
351
  }
352
 
353
  f1 = filepointers;
354
  while (f1 != NULL) {
355
    f2 = f1->next;
356
    if (f1->f != NULL)
357
      fclose(f1->f);
358
    if (f1->filename != NULL)
359
      free(f1->filename);
360
    free(f1);
361
    f1 = f2;
362
  }
363
 
364
  /* remove the tmp files */
365
  remove(gba_tmp_name);
366
  remove(gba_unfolded_name);
367
}
368
 
369
 
370
int generate_tmp_names(void) {
371
 
372
#ifdef UNIX
373
  sprintf(gba_tmp_name, ".wla%da", (int)getpid());
374
  sprintf(gba_unfolded_name, ".wla%db", (int)getpid());
375
#endif
376
 
377
#ifdef AMIGA
378
  sprintf(gba_tmp_name, "wla_a.tmp");
379
  sprintf(gba_unfolded_name, "wla_b.tmp");
380
#endif
381
 
382
#ifdef MSDOS
383
#ifndef WIN32
384
  sprintf(gba_tmp_name, "wla_a.tmp");
385
  sprintf(gba_unfolded_name, "wla_b.tmp");
386
#else
387
  sprintf(gba_tmp_name, ".wla%lda", GetCurrentProcessId());
388
  sprintf(gba_unfolded_name, ".wla%ldb", GetCurrentProcessId());
389
#endif  
390
#endif
391
 
392
  return SUCCEEDED;
393
}
394
 
395
 
396
int generate_extra_definitions(void) {
397
 
398
  char *q, c[256];
399
  time_t t;
400
  int a, s;
401
 
402
 
403
  /* generate WLA_TIME */
404
  time(&t);
405
  q = ctime(&t);
406
  strcpy(c, q);
407
  /* remove the linefeed */
408
  s = strlen(c);
409
  for (a = 0; a < s; a++) {
410
    if (c[a] == 0x0A) {
411
      c[a] = 0;
412
      break;
413
    }
414
  }
415
 
416
  if (add_a_new_definition("WLA_TIME", 0.0, c, DEFINITION_TYPE_STRING, strlen(c)) == FAILED)
417
    return FAILED;
418
  if (add_a_new_definition("wla_time", 0.0, c, DEFINITION_TYPE_STRING, strlen(c)) == FAILED)
419
    return FAILED;
420
  if (add_a_new_definition("WLA_VERSION", 0.0, wla_version, DEFINITION_TYPE_STRING, strlen(wla_version)) == FAILED)
421
    return FAILED;
422
  if (add_a_new_definition("wla_version", 0.0, wla_version, DEFINITION_TYPE_STRING, strlen(wla_version)) == FAILED)
423
    return FAILED;
424
 
425
  return SUCCEEDED;
426
}
427
 
428
 
429
int parse_defines_and_get_final_name(char **c, int n) {
430
 
431
  int x;
432
 
433
 
434
  while (1) {
435
    if (n == 0)
436
      break;
437
    if (strlen(*c) > 2) {
438
      if (**c != '-' || *((*c) + 1) != 'D')
439
        break;
440
      else
441
        if (parse_and_add_definition(*c) == FAILED)
442
          return FAILED;
443
    }
444
    if (strlen(*c) <= 2)
445
      break;
446
    c++;
447
    n--;
448
  }
449
 
450
  /* allocate room for names */
451
  if (n == 1 || n == 2) {
452
    asm_name = malloc(strlen(*c)+1);
453
    if (n == 2)
454
      final_name = malloc(strlen(*(c+1))+1);
455
    else
456
      final_name = malloc(strlen(*c)+1+4);
457
 
458
    if (asm_name == NULL || final_name == NULL) {
459
      if (asm_name != NULL) {
460
        free(asm_name);
461
        asm_name = NULL;
462
      }
463
      if (final_name != NULL) {
464
        free(final_name);
465
        final_name = NULL;
466
      }
467
      fprintf(stderr, "PARSE_DEFINES_AND_GET_FINAL_NAME: Out of memory error.\n");
468
      return FAILED;
469
    }
470
  }
471
 
472
  /* both infile and outfile were given */
473
  if (n == 2) {
474
    strcpy(asm_name, *c);
475
    c++;
476
    strcpy(final_name, *c);
477
    return SUCCEEDED;
478
  }
479
  /* only the infile was given -> construct the outfile name */
480
  else if (n == 1) {
481
    strcpy(asm_name, *c);
482
    for (x = 0; x < strlen(*c) && *((*c) + x) != '.'; x++)
483
      final_name[x] = *((*c) + x);
484
    final_name[x++] = '.';
485
    if (output_format == OUTPUT_OBJECT) {
486
      final_name[x++] = 'o';
487
      final_name[x] = 0;
488
    }
489
    else if (output_format == OUTPUT_LIBRARY) {
490
      final_name[x++] = 'l';
491
      final_name[x++] = 'i';
492
      final_name[x++] = 'b';
493
      final_name[x] = 0;
494
    }
495
    return SUCCEEDED;
496
  }
497
 
498
  fprintf(stderr, "PARSE_DEFINES_AND_GET_FINAL_NAME: Error in commandline options.\n");
499
  return FAILED;
500
}
501
 
502
 
503
int parse_and_add_definition(char *c) {
504
 
505
  char n[MAX_NAME_LENGTH];
506
  int i;
507
 
508
 
509
  c += 2;
510
  for (i = 0; i < (MAX_NAME_LENGTH - 1) && *c != 0 && *c != '='; i++, c++)
511
    n[i] = *c;
512
  n[i] = 0;
513
 
514
  if (*c == 0)
515
    return add_a_new_definition(n, 0.0, NULL, DEFINITION_TYPE_VALUE, 0);
516
  else if (*c == '=') {
517
    c++;
518
    if (*c == 0)
519
      return FAILED;
520
 
521
    /* hexadecimal value? */
522
    if (*c == '$' || ((c[strlen(c)-1] == 'h' || c[strlen(c)-1] == 'H') && (*c >= '0' && *c <= '9'))) {
523
      if (*c == '$')
524
        c++;
525
      for (i = 0; *c != 0; c++) {
526
        if (*c >= '0' && *c <= '9')
527
          i = (i << 4) + *c - '0';
528
        else if (*c >= 'a' && *c <= 'f')
529
          i = (i << 4) + *c - 'a' + 10;
530
        else if (*c >= 'A' && *c <= 'F')
531
          i = (i << 4) + *c - 'A' + 10;
532
        else if ((*c == 'h' || *c == 'H') && *(c+1) == 0)
533
          break;
534
        else {
535
          fprintf(stderr, "PARSE_AND_ADD_DEFINITION: Error in value.\n");
536
          return FAILED;
537
        }
538
      }
539
      return add_a_new_definition(n, (double)i, NULL, DEFINITION_TYPE_VALUE, 0);
540
    }
541
 
542
    /* decimal value? */
543
    if (*c >= '0' && *c <= '9') {
544
      for (i = 0; *c != 0; c++) {
545
        if (*c >= '0' && *c <= '9')
546
          i = (i * 10) + *c - '0';
547
        else {
548
          fprintf(stderr, "PARSE_AND_ADD_DEFINITION: Error in value.\n");
549
          return FAILED;
550
        }
551
      }
552
      return add_a_new_definition(n, (double)i, NULL, DEFINITION_TYPE_VALUE, 0);
553
    }
554
 
555
    /* string definition */
556
    return add_a_new_definition(n, 0.0, c, DEFINITION_TYPE_STRING, strlen(c));
557
  }
558
 
559
  return FAILED;
560
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.