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 319

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

powered by: WebSVN 2.1.0

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