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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 178 jshamlet
 
2
#include <ctype.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
 
7
#include "defines.h"
8
 
9
#include "include_file.h"
10
#include "pass_3.h"
11
 
12
 
13
extern struct incbin_file_data *incbin_file_data_first, *ifd_tmp;
14
extern struct section_def *sections_first, *sections_last, *sec_tmp, *sec_next;
15
extern struct file_name_info *file_name_info_first, *file_name_info_last, *file_name_info_tmp;
16
extern unsigned char *rom_banks, *rom_banks_usage_table;
17
extern FILE *file_out_ptr;
18
extern char gba_tmp_name[32], *gba_tmp_last_name, tmp[4096];
19
extern int verbose_mode, section_status, cartridgetype, output_format;
20
 
21
 
22
struct label_def *label_next, *label_last, *label_tmp, *labels = NULL;
23
struct block *blocks = NULL;
24
 
25
 
26
 
27
int pass_3(void) {
28
 
29
  struct section_def *s;
30
  struct label_def *l;
31
  struct block *b;
32
  FILE *f_in;
33
  int bank = 0, slot = 0, add = 0, file_name_id = 0, inz, line_number = 0, o, add_old = 0;
34
  char c;
35
 
36
 
37
  s = NULL;
38
 
39
  if (verbose_mode == ON)
40
    printf("Internal pass 1...\n");
41
 
42
  if ((f_in = fopen(gba_tmp_name, "rb")) == NULL) {
43
    fprintf(stderr, "INTERNAL_PASS_1: Error opening file \"%s\".\n", gba_tmp_name);
44
    return FAILED;
45
  }
46
 
47
  /* first loop */
48
  o = 0;
49
  if (output_format == OUTPUT_OBJECT) {
50
    while (o == 0 && fread(&c, 1, 1, f_in) != 0) {
51
      switch (c) {
52
 
53
      case ' ':
54
      case 'E':
55
        continue;
56
 
57
      case 'P':
58
        add_old = add;
59
        continue;
60
      case 'p':
61
        add = add_old;
62
        continue;
63
 
64
      case 'x':
65
        fscanf(f_in, "%d %*d ", &inz);
66
        if (section_status == ON) {
67
          add += inz;
68
          continue;
69
        }
70
 
71
        fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
72
        return FAILED;
73
 
74
      case 'd':
75
        if (section_status == ON) {
76
          fscanf(f_in, "%*s ");
77
          add++;
78
          continue;
79
        }
80
 
81
        fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
82
        return FAILED;
83
 
84
      case 'y':
85
        if (section_status == ON) {
86
          fscanf(f_in, "%*d ");
87
          add += 2;
88
          continue;
89
        }
90
 
91
        fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
92
        return FAILED;
93
 
94
      case 'f':
95
        fscanf(f_in, "%d ", &file_name_id);
96
        continue;
97
 
98
      case 'B':
99
        fscanf(f_in, "%d %d ", &bank, &slot);
100
        continue;
101
 
102
      case 'k':
103
        fscanf(f_in, "%d ", &line_number);
104
        continue;
105
 
106
      case 'g':
107
        b = malloc(sizeof(struct block));
108
        if (b == NULL) {
109
          fscanf(f_in, "%64s ", tmp);
110
          fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for block \"%s\".\n",
111
                  get_file_name(file_name_id), line_number, tmp);
112
          return FAILED;
113
        }
114
        b->next = blocks;
115
        blocks = b;
116
        fscanf(f_in, "%64s ", b->name);
117
        b->address = add;
118
        continue;
119
 
120
      case 'G':
121
        b = blocks;
122
        blocks = blocks->next;
123
        fprintf(stderr, "INTERNAL_PASS_1: Block \"%s\" is %d bytes.\n", b->name, add - b->address);
124
        free(b);
125
        continue;
126
 
127
      case 'Z':
128
      case 'Y':
129
      case 'L':
130
        l = malloc(sizeof(struct label_def));
131
        if (l == NULL) {
132
          fscanf(f_in, "%64s ", tmp);
133
          fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for label \"%s\".\n",
134
                  get_file_name(file_name_id), line_number, tmp);
135
          return FAILED;
136
        }
137
 
138
        if (c == 'Y')
139
          l->symbol = 1;
140
        else if (c == 'L')
141
          l->symbol = 0;
142
        else
143
          l->symbol = 2;
144
 
145
        if (c == 'Z')
146
          l->label[0] = 0;
147
        else
148
          fscanf(f_in, "%64s ", l->label);
149
 
150
        l->next = NULL;
151
        l->section_status = ON;
152
        l->filename_id = file_name_id;
153
        l->linenumber = line_number;
154
        l->alive = ON;
155
        l->section_id = s->id;
156
        /* section labels get a relative address */
157
        l->address = add;
158
        l->bank = s->bank;
159
        l->slot = s->slot;
160
 
161
        if (c == 'Z' || is_label_anonymous(l->label) == SUCCEEDED || strcmp(l->label, "__") == 0) {
162
          if (labels != NULL) {
163
            label_last->next = l;
164
            label_last = l;
165
          }
166
          else {
167
            labels = l;
168
            label_last = l;
169
          }
170
          continue;
171
        }
172
 
173
        label_next = labels;
174
        while (label_next != NULL) {
175
          if (strcmp(l->label, label_next->label) == 0) {
176
            if ((l->label[0] != '_') || /* both are not local labels */
177
                (section_status == OFF && label_next->section_status == OFF) ||
178
                (section_status == ON && label_next->section_status == ON && label_next->section_id == l->section_id)) {
179
              fprintf(stderr, "%s:%d: INTERNAL_PASS_1: Label \"%s\" was defined for the second time.\n", get_file_name(file_name_id), line_number, l->label);
180
              return FAILED;
181
            }
182
          }
183
          label_next = label_next->next;
184
        }
185
 
186
        if (labels != NULL) {
187
          label_last->next = l;
188
          label_last = l;
189
        }
190
        else {
191
          labels = l;
192
          label_last = l;
193
        }
194
 
195
        continue;
196
 
197
      case 'S':
198
        fscanf(f_in, "%d ", &inz);
199
 
200
        add_old = add;
201
 
202
        s = sections_first;
203
        while (s->id != inz)
204
          s = s->next;
205
 
206
        /* a RAMSECTION? */
207
        if (s->status == SECTION_STATUS_RAM) {
208
          s->address = 0;
209
          s->listfile_items = 1;
210
          s->listfile_ints = NULL;
211
          s->listfile_cmds = NULL;
212
          add = 0;
213
          section_status = ON;
214
          continue;
215
        }
216
 
217
        fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
218
        return FAILED;
219
 
220
      case 's':
221
        s->size = add - s->address;
222
 
223
        /* discard an empty section? */
224
        if (s->size == 0) {
225
          fprintf(stderr, "INTERNAL_PASS_1: %s: Discarding an empty section \"%s\".\n", get_file_name(file_name_id), s->name);
226
          s->alive = OFF;
227
 
228
          /* discard all labels which belong to this section */
229
          l = labels;
230
          while (l != NULL) {
231
            if (l->section_status == ON && l->section_id == s->id)
232
              l->alive = OFF;
233
            l = l->next;
234
          }
235
        }
236
 
237
        if (s->advance_org == NO)
238
          add = add_old;
239
 
240
        section_status = OFF;
241
        s = NULL;
242
        continue;
243
 
244
      case 'O':
245
        fscanf(f_in, "%d ", &add);
246
        o++;
247
        continue;
248
 
249
      default:
250
        fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
251
        return FAILED;
252
      }
253
    }
254
  }
255
  else {
256
    while (o == 0 && fread(&c, 1, 1, f_in) != 0) {
257
      switch (c) {
258
 
259
      case ' ':
260
      case 'E':
261
        continue;
262
 
263
      case 'f':
264
        fscanf(f_in, "%d ", &file_name_id);
265
        continue;
266
 
267
      case 'S':
268
        fscanf(f_in, "%d ", &inz);
269
 
270
        add_old = add;
271
 
272
        s = sections_first;
273
        while (s->id != inz)
274
          s = s->next;
275
 
276
        if (s->status == SECTION_STATUS_FREE)
277
          add = 0;
278
 
279
        s->address = add;
280
        s->bank = bank;
281
        s->slot = slot;
282
        s->listfile_items = 1;
283
        s->listfile_ints = NULL;
284
        s->listfile_cmds = NULL;
285
        section_status = ON;
286
        o++;
287
        continue;
288
 
289
      default:
290
        fprintf(stderr, "INTERNAL_PASS_1: A section must be open before any code/data can be accepted.\n");
291
        return FAILED;
292
      }
293
    }
294
  }
295
 
296
  /* second (major) loop */
297
  while (fread(&c, 1, 1, f_in) != 0) {
298
    switch (c) {
299
 
300
    case ' ':
301
    case 'E':
302
      continue;
303
 
304
    case 'P':
305
      add_old = add;
306
      continue;
307
    case 'p':
308
      add = add_old;
309
      continue;
310
 
311
    case 'A':
312
    case 'S':
313
      if (c == 'A')
314
        fscanf(f_in, "%d %*d", &inz);
315
      else
316
        fscanf(f_in, "%d ", &inz);
317
 
318
      add_old = add;
319
 
320
      s = sections_first;
321
      while (s->id != inz)
322
        s = s->next;
323
 
324
      if (s->status == SECTION_STATUS_FREE || s->status == SECTION_STATUS_RAM)
325
        add = 0;
326
 
327
      if (s->status != SECTION_STATUS_RAM) {
328
        s->bank = bank;
329
        s->slot = slot;
330
      }
331
      s->address = add;
332
      s->listfile_items = 1;
333
      s->listfile_ints = NULL;
334
      s->listfile_cmds = NULL;
335
      section_status = ON;
336
      continue;
337
 
338
    case 's':
339
      s->size = add - s->address;
340
 
341
      /* discard an empty section? */
342
      if (s->size == 0) {
343
        fprintf(stderr, "DISCARD: %s: Discarding an empty section \"%s\".\n", get_file_name(file_name_id), s->name);
344
        s->alive = OFF;
345
 
346
        /* discard all labels which belong to this section */
347
        l = labels;
348
        while (l != NULL) {
349
          if (l->section_status == ON && l->section_id == s->id)
350
            l->alive = OFF;
351
          l = l->next;
352
        }
353
      }
354
 
355
      /* some sections don't affect the ORG outside of them */
356
      if (s->advance_org == NO)
357
        add = add_old;
358
 
359
      section_status = OFF;
360
      s = NULL;
361
      continue;
362
 
363
    case 'x':
364
      fscanf(f_in, "%d %*d ", &inz);
365
      add += inz;
366
      continue;
367
 
368
    case 'X':
369
      fscanf(f_in, "%d %*d ", &inz);
370
      add += inz << 1;
371
      continue;
372
 
373
    case 'R':
374
    case 'Q':
375
    case 'd':
376
    case 'c':
377
      fscanf(f_in, "%*s ");
378
      add++;
379
      continue;
380
 
381
    case 'r':
382
      fscanf(f_in, "%*s ");
383
      add += 2;
384
      continue;
385
 
386
    case 'y':
387
    case 'C':
388
      fscanf(f_in, "%*d ");
389
      add += 2;
390
      continue;
391
 
392
    case 'D':
393
      fscanf(f_in, "%*d %*d %*d %d ", &inz);
394
      add += inz;
395
      continue;
396
 
397
    case 'O':
398
      fscanf(f_in, "%d ", &add);
399
      continue;
400
 
401
    case 'B':
402
      fscanf(f_in, "%d %d ", &bank, &slot);
403
      continue;
404
 
405
    case 'g':
406
      b = malloc(sizeof(struct block));
407
      if (b == NULL) {
408
        fscanf(f_in, "%64s ", tmp);
409
        fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for block \"%s\".\n",
410
                get_file_name(file_name_id), line_number, tmp);
411
        return FAILED;
412
      }
413
      b->next = blocks;
414
      blocks = b;
415
      fscanf(f_in, "%64s ", b->name);
416
      b->address = add;
417
      continue;
418
 
419
    case 'G':
420
      b = blocks;
421
      blocks = blocks->next;
422
      fprintf(stderr, "INTERNAL_PASS_1: Block \"%s\" is %d bytes.\n", b->name, add - b->address);
423
      free(b);
424
      continue;
425
 
426
    case 'Z':
427
    case 'Y':
428
    case 'L':
429
      l = malloc(sizeof(struct label_def));
430
      if (l == NULL) {
431
        fscanf(f_in, "%64s ", tmp);
432
        fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for label \"%s\".\n",
433
                get_file_name(file_name_id), line_number, tmp);
434
        return FAILED;
435
      }
436
 
437
      if (c == 'Y')
438
        l->symbol = 1;
439
      else if (c == 'L')
440
        l->symbol = 0;
441
      else
442
        l->symbol = 2;
443
 
444
      if (c == 'Z')
445
        l->label[0] = 0;
446
      else
447
        fscanf(f_in, "%64s ", l->label);
448
 
449
      l->next = NULL;
450
      l->section_status = section_status;
451
      l->filename_id = file_name_id;
452
      l->linenumber = line_number;
453
      l->alive = ON;
454
      if (section_status == ON) {
455
        l->section_id = s->id;
456
        /* section labels get a relative address */
457
        l->address = add - s->address;
458
        l->bank = s->bank;
459
        l->slot = s->slot;
460
      }
461
      else {
462
        l->section_id = 0;
463
        l->address = add;
464
        l->bank = bank;
465
        l->slot = slot;
466
      }
467
 
468
      if (c == 'Z' || is_label_anonymous(l->label) == SUCCEEDED || strcmp(l->label, "__") == 0) {
469
        if (labels != NULL) {
470
          label_last->next = l;
471
          label_last = l;
472
        }
473
        else {
474
          labels = l;
475
          label_last = l;
476
        }
477
        continue;
478
      }
479
 
480
      label_next = labels;
481
      while (label_next != NULL) {
482
        if (strcmp(l->label, label_next->label) == 0) {
483
          if ((l->label[0] != '_') || /* both are not local labels */
484
              (section_status == OFF && label_next->section_status == OFF) ||
485
              (section_status == ON && label_next->section_status == ON && label_next->section_id == l->section_id)) {
486
            fprintf(stderr, "%s:%d: INTERNAL_PASS_1: Label \"%s\" was defined for the second time.\n", get_file_name(file_name_id), line_number, l->label);
487
            return FAILED;
488
          }
489
        }
490
        label_next = label_next->next;
491
      }
492
 
493
      if (labels != NULL) {
494
        label_last->next = l;
495
        label_last = l;
496
      }
497
      else {
498
        labels = l;
499
        label_last = l;
500
      }
501
 
502
      continue;
503
 
504
    case 'f':
505
      fscanf(f_in, "%d ", &file_name_id);
506
      if (s != NULL)
507
        s->listfile_items++;
508
      continue;
509
 
510
    case 'k':
511
      fscanf(f_in, "%d ", &line_number);
512
      if (s != NULL)
513
        s->listfile_items++;
514
      continue;
515
 
516
    default:
517
      fprintf(stderr, "%s: INTERNAL_PASS_1: Unknown internal symbol \"%c\".\n", get_file_name(file_name_id), c);
518
      return FAILED;
519
    }
520
  }
521
 
522
  fclose(f_in);
523
 
524
  return SUCCEEDED;
525
}
526
 
527
 
528
/* is the label of form -, --, ---, +, ++, +++, ... ? */
529
int is_label_anonymous(char *l) {
530
 
531
  int x, y;
532
  char c;
533
 
534
 
535
  c = *l;
536
  if (!(c == '-' || c == '+'))
537
    return FAILED;
538
  for (x = strlen(l), y = 0; y < x; y++) {
539
    if (*(l + y) != c)
540
      return FAILED;
541
  }
542
 
543
  return SUCCEEDED;
544
}

powered by: WebSVN 2.1.0

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