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_4.c] - Blame information for rev 178

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 "listfile.h"
11
#include "pass_4.h"
12
#include "parse.h"
13
#include "stack.h"
14
 
15
 
16
extern struct section_def *sections_first, *sections_last, *sec_tmp, *sec_next;
17
extern struct incbin_file_data *incbin_file_data_first, *ifd_tmp;
18
extern struct export_def *export_first, *export_last;
19
extern struct stack *stacks_first, *stacks_tmp, *stacks_last, *stacks_header_first, *stacks_header_last;
20
extern struct label_def *label_tmp, *label_last, *labels;
21
extern struct definition *defines, *tmp_def, *next_def;
22
extern struct file_name_info *file_name_info_first;
23
extern struct slot slots[256];
24
extern FILE *file_out_ptr;
25
extern unsigned char *rom_banks, *rom_banks_usage_table;
26
extern char gba_tmp_name[32], tmp[4096], name[32], *final_name;
27
extern int rombanks, ind, inz, output_format, test_mode, listfile_data;
28
 
29
extern int romtype, rambanks, emptyfill, max_address;
30
extern int rambanks_defined, verbose_mode;
31
extern int section_status;
32
extern int banksize, banksize_defined;
33
extern int slots_amount;
34
extern int *banks, *bankaddress, rombankmap_defined;
35
extern int latest_stack, stacks_outside, stacks_inside;
36
extern int bankheader_status;
37
extern int smc_defined, makefile_rules;
38
 
39
struct label_def *unknown_labels = NULL, *unknown_labels_last = NULL, *tul, *ltmp;
40
struct label_def *unknown_header_labels = NULL, *unknown_header_labels_last = NULL;
41
 
42
unsigned int pc_bank = 0, pc_full = 0, rom_bank, mem_insert_overwrite, slot, pc_slot, pc_slot_max;
43
int filename_id, line_number;
44
 
45
 
46
#define WRITEOUT_OV fprintf(final_ptr, "%c%c%c%c", (ov>>24)&0xFF, (ov>>16)&0xFF, (ov>>8)&0xFF, ov&0xFF);
47
#define WRITEOUT_DOU { \
48
  cp = (unsigned char *)&dou; \
49
  fprintf(final_ptr, "%c%c%c%c%c%c%c%c", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); \
50
}
51
 
52
 
53
 
54
int new_unknown_reference(int type) {
55
 
56
  struct label_def *t;
57
 
58
 
59
  t = malloc(sizeof(struct label_def));
60
  if (t == NULL) {
61
    fprintf(stderr, "%s:%d: NEW_UNKNOWN_REFERENCE: Out of memory.\n", get_file_name(filename_id), line_number);
62
    return FAILED;
63
  }
64
 
65
  t->symbol = NO;
66
 
67
  strcpy(t->label, tmp);
68
  t->next = NULL;
69
  t->type = type;
70
  t->filename_id = filename_id;
71
  t->linenumber = line_number;
72
  t->section_status = section_status;
73
  if (section_status == ON) {
74
    t->section_id = sec_tmp->id;
75
    t->address = sec_tmp->i; /* relative address, to the beginning of the section */
76
  }
77
  else {
78
    t->section_id = 0;
79
    t->address = pc_bank; /* bank address, in ROM memory */
80
  }
81
 
82
  t->bank = rom_bank;
83
  t->slot = slot;
84
 
85
  /* outside bank header section */
86
  if (bankheader_status == OFF) {
87
    if (unknown_labels_last == NULL) {
88
      unknown_labels = t;
89
      unknown_labels_last = t;
90
    }
91
    else {
92
      unknown_labels_last->next = t;
93
      unknown_labels_last = t;
94
    }
95
  }
96
  /* bank header section */
97
  else {
98
    if (t->label[0] == '_') {
99
      fprintf(stderr, "%s:%d: NEW_UNKNOWN_REFERENCE: Referring to a local label (\"%s\") from inside a bank header section is not allowed.\n",
100
              get_file_name(filename_id), line_number, t->label);
101
      return FAILED;
102
    }
103
    if (unknown_header_labels_last == NULL) {
104
      unknown_header_labels = t;
105
      unknown_header_labels_last = t;
106
    }
107
    else {
108
      unknown_header_labels_last->next = t;
109
      unknown_header_labels_last = t;
110
    }
111
  }
112
 
113
  return SUCCEEDED;
114
}
115
 
116
 
117
int pass_4(void) {
118
 
119
  unsigned char *cp;
120
  FILE *final_ptr;
121
  double dou;
122
  char *t, c;
123
  int i, o, z, y, add_old = 0;
124
  int x, q, ov;
125
  float f;
126
 
127
  section_status = OFF;
128
  bankheader_status = OFF;
129
  mem_insert_overwrite = OFF;
130
 
131
  if (verbose_mode == ON)
132
    printf("Internal pass 2...\n");
133
 
134
  if ((file_out_ptr = fopen(gba_tmp_name, "rb")) == NULL) {
135
    fprintf(stderr, "INTERNAL_PASS_2: Error opening file \"%s\".\n", gba_tmp_name);
136
    return FAILED;
137
  }
138
 
139
  while (fread(&c, 1, 1, file_out_ptr) != 0) {
140
 
141
    switch (c) {
142
 
143
    case 'E':
144
      continue;
145
 
146
    case 'g':
147
      fscanf(file_out_ptr, "%*s ");
148
      continue;
149
    case 'G':
150
      continue;
151
 
152
    case 'f':
153
      fscanf(file_out_ptr, "%d ", &filename_id);
154
      continue;
155
 
156
    case 'k':
157
      fscanf(file_out_ptr, "%d ", &line_number);
158
      continue;
159
 
160
    /* SECTION */
161
 
162
    case 'A':
163
    case 'S':
164
      if (c == 'A')
165
        fscanf(file_out_ptr, "%d %d ", &x, &ind);
166
      else
167
        fscanf(file_out_ptr, "%d ", &x);
168
 
169
      add_old = pc_bank;
170
 
171
      sec_tmp = sections_first;
172
      while (sec_tmp != NULL) {
173
        if (sec_tmp->id == x)
174
          break;
175
        sec_tmp = sec_tmp->next;
176
      }
177
 
178
      /* skip all dead sections */
179
      if (sec_tmp->alive == OFF)
180
        continue;
181
 
182
      if (c == 'A')
183
        sec_tmp->address = ind;
184
 
185
      ind = 0;
186
      if (sec_tmp->maxsize_status == ON) {
187
        if (sec_tmp->maxsize < sec_tmp->size) {
188
          fprintf(stderr, "%s: INTERNAL_PASS_2: Section \"%s\" doesn't fit into the specified %d bytes. Enlarging to %d bytes.\n",
189
                  get_file_name(filename_id), sec_tmp->name, sec_tmp->maxsize, sec_tmp->size);
190
        }
191
        else if (sec_tmp->size < sec_tmp->maxsize) {
192
          sec_tmp->size = sec_tmp->maxsize;
193
          ind = 1;
194
        }
195
      }
196
 
197
      sec_tmp->data = malloc(sizeof(unsigned char) * sec_tmp->size);
198
 
199
      if (sec_tmp->data == NULL) {
200
        fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Out of memory when trying to allocate room for section \"%s\".\n",
201
                get_file_name(filename_id), line_number, sec_tmp->name);
202
        return FAILED;
203
      }
204
 
205
      /* fill the padded area with _emptyfill_ */
206
      if (ind == 1)
207
        memset(sec_tmp->data, emptyfill, sec_tmp->size);
208
 
209
      if (strcmp(sec_tmp->name, "BANKHEADER") == 0)
210
        bankheader_status = ON;
211
 
212
      sec_tmp->i = 0;
213
      section_status = ON;
214
 
215
      continue;
216
 
217
    /* ENDS */
218
 
219
    case 's':
220
      section_status = OFF;
221
      bankheader_status = OFF;
222
 
223
      /* some sections don't affect the ORG outside of them */
224
      if (sec_tmp->advance_org == NO) {
225
        pc_bank = add_old;
226
        pc_full = bankaddress[rom_bank] + pc_bank;
227
        pc_slot = slots[slot].address + pc_bank;
228
        pc_slot_max = slots[slot].address + slots[slot].size;
229
      }
230
 
231
      continue;
232
 
233
    /* DSB & DSW */
234
 
235
    case 'x':
236
      fscanf(file_out_ptr, "%d %d", &ind, &x);
237
      while (ind > 0) {
238
        if (mem_insert(x) == FAILED)
239
          return FAILED;
240
        ind--;
241
      }
242
      continue;
243
 
244
    case 'X':
245
      fscanf(file_out_ptr, "%d %d", &ind, &inz);
246
      i = inz & 0xFF;
247
      inz = (inz >> 8) & 0xFF;
248
 
249
      while (ind > 0) {
250
        if (mem_insert(i) == FAILED)
251
          return FAILED;
252
        if (mem_insert(inz) == FAILED)
253
          return FAILED;
254
        ind--;
255
      }
256
 
257
      continue;
258
 
259
    /* DATA & OPTCODE */
260
 
261
    case 'd':
262
      fscanf(file_out_ptr, "%d", &x);
263
      if (mem_insert(x) == FAILED)
264
        return FAILED;
265
      continue;
266
 
267
    case 'y':
268
      fscanf(file_out_ptr, "%d", &inz);
269
      x = inz & 0xFF;
270
      inz = (inz >> 8) & 0xFF;
271
 
272
      if (mem_insert(x) == FAILED)
273
        return FAILED;
274
      if (mem_insert(inz) == FAILED)
275
        return FAILED;
276
 
277
      continue;
278
 
279
    /* DATA BLOCK */
280
 
281
    case 'D':
282
      fscanf(file_out_ptr, "%d %d %d %d", &x, &inz, &z, &y);
283
 
284
      ifd_tmp = incbin_file_data_first;
285
      for (ind = 0; ind != x; ind++)
286
        ifd_tmp = ifd_tmp->next;
287
      t = ifd_tmp->data + z;
288
 
289
      /* swap? */
290
      if (inz == 1) {
291
        inz = y / 2;
292
        for (ind = 0; ind < inz; ind++) {
293
          if (mem_insert(*(t + 1)) == FAILED)
294
            return FAILED;
295
          if (mem_insert(*t) == FAILED)
296
            return FAILED;
297
          t += 2;
298
        }
299
      }
300
      else {
301
        inz = y;
302
        for (ind = 0; ind < inz; ind++) {
303
          if (mem_insert(*(t++)) == FAILED)
304
            return FAILED;
305
        }
306
      }
307
 
308
      continue;
309
 
310
    /* ORIGIN & ROM BANK */
311
 
312
    case 'O':
313
    case 'B':
314
 
315
      if (c == 'O')
316
        fscanf(file_out_ptr, "%u", &pc_bank);
317
      else {
318
        fscanf(file_out_ptr, "%u %u", &rom_bank, &slot);
319
        if (banksize_defined == 0)
320
          banksize = banks[rom_bank];
321
      }
322
 
323
      pc_full = bankaddress[rom_bank] + pc_bank;
324
      pc_slot = slots[slot].address + pc_bank;
325
      pc_slot_max = slots[slot].address + slots[slot].size;
326
 
327
      continue;
328
 
329
    /* BREAKPOINT */
330
 
331
    case 'Z':
332
      continue;
333
 
334
    /* LABEL and SYMBOL */
335
 
336
    case 'Y':
337
    case 'L':
338
      fscanf(file_out_ptr, "%*s"); /* skip the label */
339
      continue;
340
 
341
    /* 8BIT COMPUTATION */
342
 
343
    case 'c':
344
      fscanf(file_out_ptr, "%d", &inz);
345
 
346
      if (bankheader_status == OFF)
347
        stacks_tmp = stacks_first;
348
      else
349
        stacks_tmp = stacks_header_first;
350
 
351
      while (stacks_tmp != NULL) {
352
        if (stacks_tmp->id == inz)
353
          break;
354
        stacks_tmp = stacks_tmp->next;
355
      }
356
 
357
      if (stacks_tmp == NULL) {
358
        fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Could not find computation stack number %d. WLA corruption detected. Please send a bug report!\n", get_file_name(filename_id), line_number, inz);
359
        return FAILED;
360
      }
361
 
362
      if (stacks_tmp->section_status == ON) {
363
        stacks_tmp->address = sec_tmp->i; /* relative address, to the beginning of the section */
364
      }
365
      else {
366
        stacks_tmp->address = pc_bank; /* complete address, in ROM memory */
367
      }
368
 
369
      stacks_tmp->bank = rom_bank;
370
      stacks_tmp->slot = slot;
371
      stacks_tmp->type = STACKS_TYPE_8BIT;
372
 
373
      /* this stack was referred from the code */
374
      stacks_tmp->position = STACK_POSITION_CODE;
375
 
376
      if (mem_insert_pad() == FAILED)
377
        return FAILED;
378
 
379
      continue;
380
 
381
    /* 16BIT COMPUTATION */
382
 
383
    case 'C':
384
      fscanf(file_out_ptr, "%d", &inz);
385
 
386
      if (bankheader_status == OFF)
387
        stacks_tmp = stacks_first;
388
      else
389
        stacks_tmp = stacks_header_first;
390
 
391
      while (stacks_tmp != NULL) {
392
        if (stacks_tmp->id == inz)
393
          break;
394
        stacks_tmp = stacks_tmp->next;
395
      }
396
 
397
      if (stacks_tmp == NULL) {
398
        fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Could not find computation stack number %d. WLA corruption detected. Please send a bug report!\n", get_file_name(filename_id), line_number, inz);
399
        return FAILED;
400
      }
401
 
402
      if (stacks_tmp->section_status == ON) {
403
        stacks_tmp->address = sec_tmp->i; /* relative address, to the beginning of the section */
404
      }
405
      else {
406
        stacks_tmp->address = pc_bank; /* complete address, in ROM memory */
407
      }
408
 
409
      stacks_tmp->bank = rom_bank;
410
      stacks_tmp->slot = slot;
411
      stacks_tmp->type = STACKS_TYPE_16BIT;
412
 
413
      /* this stack was referred from the code */
414
      stacks_tmp->position = STACK_POSITION_CODE;
415
 
416
      if (mem_insert_pad() == FAILED)
417
        return FAILED;
418
      if (mem_insert_pad() == FAILED)
419
        return FAILED;
420
 
421
      continue;
422
 
423
    /* 16BIT REFERENCE */
424
 
425
    case 'r':
426
      fscanf(file_out_ptr, "%256s", tmp);
427
 
428
      x = 0;
429
      tmp_def = defines;
430
      while (tmp_def != NULL) {
431
        if (strcmp(tmp, tmp_def->alias) == 0) {
432
          if (tmp_def->type == DEFINITION_TYPE_STACK)
433
            break;
434
          if (tmp_def->type == DEFINITION_TYPE_STRING) {
435
            fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Reference to a string definition \"%s\"?\n", get_file_name(filename_id), line_number, tmp);
436
            return FAILED;
437
          }
438
          o = tmp_def->value;
439
          x = 1;
440
 
441
          if (mem_insert(o & 0xFF) == FAILED)
442
            return FAILED;
443
          if (mem_insert((o & 0xFF00) >> 8) == FAILED)
444
            return FAILED;
445
 
446
          break;
447
        }
448
        tmp_def = tmp_def->next;
449
      }
450
 
451
      if (x == 1)
452
        continue;
453
 
454
      if (new_unknown_reference(REFERENCE_TYPE_DIRECT_16BIT) == FAILED)
455
        return FAILED;
456
 
457
      if (mem_insert_pad() == FAILED)
458
        return FAILED;
459
      if (mem_insert_pad() == FAILED)
460
        return FAILED;
461
 
462
      continue;
463
 
464
    /* 8BIT PC RELATIVE REFERENCE */
465
 
466
    case 'R':
467
      fscanf(file_out_ptr, "%256s", tmp);
468
 
469
      x = 0;
470
      tmp_def = defines;
471
      while (tmp_def != NULL) {
472
        if (strcmp(tmp, tmp_def->alias) == 0) {
473
          if (tmp_def->type == DEFINITION_TYPE_STACK)
474
            break;
475
          if (tmp_def->type == DEFINITION_TYPE_STRING) {
476
            fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Reference to a string definition \"%s\"?\n", get_file_name(filename_id), line_number, tmp);
477
            return FAILED;
478
          }
479
          o = tmp_def->value;
480
          x = 1;
481
 
482
          if (mem_insert(o & 0xFF) == FAILED)
483
            return FAILED;
484
 
485
          break;
486
        }
487
        tmp_def = tmp_def->next;
488
      }
489
 
490
      if (x == 1)
491
        continue;
492
 
493
      if (new_unknown_reference(REFERENCE_TYPE_RELATIVE_8BIT) == FAILED)
494
        return FAILED;
495
 
496
      if (mem_insert_pad() == FAILED)
497
        return FAILED;
498
 
499
      continue;
500
 
501
    /* 8BIT REFERENCE */
502
 
503
    case 'Q':
504
      fscanf(file_out_ptr, "%256s", tmp);
505
 
506
      x = 0;
507
      tmp_def = defines;
508
      while (tmp_def != NULL) {
509
        if (strcmp(tmp, tmp_def->alias) == 0) {
510
          if (tmp_def->type == DEFINITION_TYPE_STACK)
511
            break;
512
          if (tmp_def->type == DEFINITION_TYPE_STRING) {
513
            fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Reference to a string definition \"%s\"?\n", get_file_name(filename_id), line_number, tmp);
514
            return FAILED;
515
          }
516
          o = tmp_def->value;
517
          x = 1;
518
 
519
          if (mem_insert(o & 0xFF) == FAILED)
520
            return FAILED;
521
 
522
          break;
523
        }
524
        tmp_def = tmp_def->next;
525
      }
526
 
527
      if (x == 1)
528
        continue;
529
 
530
      if (new_unknown_reference(REFERENCE_TYPE_DIRECT_8BIT) == FAILED)
531
        return FAILED;
532
 
533
      if (mem_insert_pad() == FAILED)
534
        return FAILED;
535
 
536
      continue;
537
    }
538
  }
539
 
540
  fclose(file_out_ptr);
541
  file_out_ptr = NULL;
542
 
543
  /* library file output */
544
  if (output_format == OUTPUT_LIBRARY && test_mode == OFF) {
545
 
546
    if ((final_ptr = fopen(final_name, "wb")) == NULL) {
547
      fprintf(stderr, "INTERNAL_PASS_2: Error opening file \"%s\".\n", final_name);
548
      return FAILED;
549
    }
550
 
551
    /* header */
552
    fprintf(final_ptr, "WLAV");
553
 
554
    if (export_source_file_names(final_ptr) == FAILED)
555
      return FAILED;
556
 
557
    /* export definitions */
558
    if (export_definitions(final_ptr) == FAILED)
559
      return FAILED;
560
 
561
    /* labels, symbols and breakpoints */
562
    ov = 0;
563
    label_tmp = labels;
564
    while (label_tmp != NULL) {
565
      if (label_tmp->alive == ON)
566
        ov++;
567
      label_tmp = label_tmp->next;
568
    }
569
 
570
    WRITEOUT_OV
571
 
572
    label_tmp = labels;
573
    while (label_tmp != NULL) {
574
      if (label_tmp->alive == ON) {
575
        if (label_tmp->symbol != 2)
576
          fprintf(final_ptr, "%s", label_tmp->label);
577
        fprintf(final_ptr, "%c", label_tmp->symbol);
578
 
579
        fprintf(final_ptr, "%c%c", label_tmp->section_id, label_tmp->filename_id);
580
 
581
        ov = label_tmp->linenumber;
582
        WRITEOUT_OV
583
 
584
        ov = label_tmp->address;
585
        WRITEOUT_OV
586
      }
587
      label_tmp = label_tmp->next;
588
    }
589
 
590
    /* unknown labels */
591
    ov = 0;
592
    label_tmp = unknown_labels;
593
    while (label_tmp != NULL) {
594
      ov++;
595
      label_tmp = label_tmp->next;
596
    }
597
 
598
    WRITEOUT_OV
599
 
600
    label_tmp = unknown_labels;
601
    while (label_tmp != NULL) {
602
      fprintf(final_ptr, "%s%c%c%c%c", label_tmp->label, 0x0, label_tmp->type, label_tmp->section_id, label_tmp->filename_id);
603
 
604
      if (label_tmp->section_status == OFF) {
605
        fprintf(stderr, "INTERNAL_PASS_2: Label \"%s\" is outside all sections.\n", label_tmp->label);
606
        return FAILED;
607
      }
608
 
609
      ov = label_tmp->linenumber;
610
      WRITEOUT_OV
611
 
612
      ov = label_tmp->address;
613
      WRITEOUT_OV
614
 
615
      label_tmp = label_tmp->next;
616
    }
617
 
618
    /* pending calculations */
619
    ov = stacks_outside;
620
    WRITEOUT_OV
621
 
622
    stacks_tmp = stacks_first;
623
    while (stacks_tmp != NULL) {
624
      ov = stacks_tmp->id;
625
      WRITEOUT_OV
626
 
627
      fprintf(final_ptr, "%c%c%c%c%c", stacks_tmp->type, stacks_tmp->section_id, stacks_tmp->filename_id, stacks_tmp->stacksize, stacks_tmp->position);
628
 
629
      ov = stacks_tmp->address;
630
      WRITEOUT_OV
631
 
632
      ov = stacks_tmp->linenumber;
633
      WRITEOUT_OV
634
 
635
      for (ind = 0; ind < stacks_tmp->stacksize; ind++) {
636
        fprintf(final_ptr, "%c%c", stacks_tmp->stack[ind].type, stacks_tmp->stack[ind].sign);
637
        if (stacks_tmp->stack[ind].type == STACK_ITEM_TYPE_STRING)
638
          fprintf(final_ptr, "%s%c", stacks_tmp->stack[ind].string, 0);
639
        else {
640
          dou = stacks_tmp->stack[ind].value;
641
          WRITEOUT_DOU
642
        }
643
      }
644
 
645
      stacks_tmp = stacks_tmp->next;
646
    }
647
 
648
    /* sections */
649
    sec_tmp = sections_first;
650
    while (sec_tmp != NULL) {
651
      if (sec_tmp->alive == ON) {
652
        fprintf(final_ptr, "%s%c%c%c", sec_tmp->name, sec_tmp->status, sec_tmp->id, sec_tmp->filename_id);
653
 
654
        ov = sec_tmp->size;
655
        WRITEOUT_OV
656
        ov = sec_tmp->alignment;
657
        WRITEOUT_OV
658
 
659
        fwrite(sec_tmp->data, 1, sec_tmp->size, final_ptr);
660
 
661
        if (listfile_data == YES && sec_tmp->listfile_items > 0)
662
          listfile_block_write(final_ptr, sec_tmp);
663
        else
664
          fprintf(final_ptr, "%c", 0);
665
      }
666
      sec_tmp = sec_tmp->next;
667
    }
668
 
669
    fclose(final_ptr);
670
  }
671
 
672
  /* object file output */
673
  else if (output_format == OUTPUT_OBJECT && test_mode == OFF) {
674
 
675
    if ((final_ptr = fopen(final_name, "wb")) == NULL) {
676
      fprintf(stderr, "INTERNAL_PASS_2: Error opening file \"%s\".\n", final_name);
677
      return FAILED;
678
    }
679
 
680
    /* header */
681
    fprintf(final_ptr, "WLAK%c", emptyfill);
682
 
683
    /* misc bits */
684
    ind = 0;
685
 
686
    fprintf(final_ptr, "%c", ind);
687
 
688
    /* more bits */
689
    ind = 0;
690
 
691
    if (smc_defined != 0)
692
      ind += 1;
693
 
694
    fprintf(final_ptr, "%c", ind);
695
 
696
    /* rom bank map */
697
    ov = rombanks;
698
    WRITEOUT_OV                                   /* number of rom banks */
699
 
700
    if (rombankmap_defined != 0) {
701
      fprintf(final_ptr, "%c", 1);                /* status */
702
      for (i = 0; i < rombanks; i++) {
703
        ov = banks[i];
704
        WRITEOUT_OV                               /* banksize */
705
      }
706
    }
707
    else {
708
      fprintf(final_ptr, "%c", 0);                /* status */
709
      ov = banksize;
710
      WRITEOUT_OV                                 /* banksize */
711
    }
712
 
713
    /* memory map */
714
    fprintf(final_ptr, "%c", slots_amount);       /* number of slots */
715
 
716
    for (i = 0; i < slots_amount; i++) {
717
      if (slots[i].size != 0) {
718
        ov = slots[i].address;
719
        WRITEOUT_OV                               /* slot address */
720
        ov = slots[i].size;
721
        WRITEOUT_OV                               /* slot size */
722
      }
723
    }
724
 
725
    /* source file names */
726
    if (export_source_file_names(final_ptr) == FAILED)
727
      return FAILED;
728
 
729
    /* export definitions */
730
    if (export_definitions(final_ptr) == FAILED)
731
      return FAILED;
732
 
733
    /* labels */
734
    ov = 0;
735
    label_tmp = labels;
736
    while (label_tmp != NULL) {
737
      if (label_tmp->alive == ON)
738
        ov++;
739
      label_tmp = label_tmp->next;
740
    }
741
 
742
    /* number of labels */
743
    WRITEOUT_OV
744
 
745
    label_tmp = labels;
746
    while (label_tmp != NULL) {
747
      if (label_tmp->alive == ON) {
748
        if (label_tmp->symbol != 2)
749
          fprintf(final_ptr, "%s", label_tmp->label);
750
        fprintf(final_ptr, "%c", label_tmp->symbol);
751
 
752
        fprintf(final_ptr, "%c%c%c", label_tmp->slot, label_tmp->filename_id, label_tmp->section_id);
753
 
754
        /* DEBUG
755
        fprintf(stderr, "LABEL: \"%s\" SLOT: %d LINE: %d\n", label_tmp->label, label_tmp->slot, label_tmp->linenumber);
756
        */
757
 
758
        ov = label_tmp->address;
759
        WRITEOUT_OV
760
 
761
        ov = label_tmp->linenumber;
762
        WRITEOUT_OV
763
 
764
        ov = label_tmp->bank;
765
        WRITEOUT_OV
766
      }
767
      label_tmp = label_tmp->next;
768
    }
769
 
770
    /* outside references */
771
    ov = 0;
772
    label_tmp = unknown_labels;
773
    while (label_tmp != NULL) {
774
      ov++;
775
      label_tmp = label_tmp->next;
776
    }
777
    label_tmp = unknown_header_labels;
778
    while (label_tmp != NULL) {
779
      ov++;
780
      label_tmp = label_tmp->next;
781
    }
782
 
783
    WRITEOUT_OV
784
 
785
    label_tmp = unknown_labels;
786
    while (label_tmp != NULL) {
787
      fprintf(final_ptr, "%s%c%c%c%c%c", label_tmp->label, 0x0, label_tmp->type, label_tmp->filename_id, label_tmp->slot, label_tmp->section_id);
788
 
789
      ov = label_tmp->linenumber;
790
      WRITEOUT_OV
791
 
792
      ov = label_tmp->address;
793
      WRITEOUT_OV
794
 
795
      ov = label_tmp->bank;
796
      WRITEOUT_OV
797
 
798
      label_tmp = label_tmp->next;
799
    }
800
 
801
    label_tmp = unknown_header_labels;
802
    while (label_tmp != NULL) {
803
      fprintf(final_ptr, "%s%c%c%c%c%c", label_tmp->label, 0x0, label_tmp->type, label_tmp->filename_id, label_tmp->slot, label_tmp->section_id);
804
 
805
      ov = label_tmp->linenumber;
806
      WRITEOUT_OV
807
 
808
      ov = label_tmp->address;
809
      WRITEOUT_OV
810
 
811
      ov = label_tmp->bank;
812
      WRITEOUT_OV
813
 
814
      label_tmp = label_tmp->next;
815
    }
816
 
817
    /* pending calculations */
818
    ov = stacks_outside + stacks_inside;
819
    WRITEOUT_OV
820
 
821
    stacks_tmp = stacks_first;
822
    while (stacks_tmp != NULL) {
823
      ov = stacks_tmp->id;
824
      WRITEOUT_OV
825
 
826
      fprintf(final_ptr, "%c%c%c%c%c%c", stacks_tmp->type, stacks_tmp->section_id, stacks_tmp->filename_id, stacks_tmp->stacksize, stacks_tmp->position, stacks_tmp->slot);
827
 
828
      ov = stacks_tmp->address;
829
      WRITEOUT_OV
830
 
831
      ov = stacks_tmp->linenumber;
832
      WRITEOUT_OV
833
 
834
      ov = stacks_tmp->bank;
835
      WRITEOUT_OV
836
 
837
      for (ind = 0; ind < stacks_tmp->stacksize; ind++) {
838
        fprintf(final_ptr, "%c%c", stacks_tmp->stack[ind].type, stacks_tmp->stack[ind].sign);
839
        if (stacks_tmp->stack[ind].type == STACK_ITEM_TYPE_STRING)
840
          fprintf(final_ptr, "%s%c", stacks_tmp->stack[ind].string, 0);
841
        else {
842
          dou = stacks_tmp->stack[ind].value;
843
          WRITEOUT_DOU
844
        }
845
      }
846
 
847
      stacks_tmp = stacks_tmp->next;
848
    }
849
 
850
    stacks_tmp = stacks_header_first;
851
    while (stacks_tmp != NULL) {
852
      fprintf(final_ptr, "%c%c%c%c%c%c", stacks_tmp->type, stacks_tmp->section_id, stacks_tmp->filename_id, stacks_tmp->stacksize, stacks_tmp->position, stacks_tmp->slot);
853
 
854
      ov = stacks_tmp->address;
855
      WRITEOUT_OV
856
 
857
      ov = stacks_tmp->linenumber;
858
      WRITEOUT_OV
859
 
860
      ov = stacks_tmp->bank;
861
      WRITEOUT_OV
862
 
863
      for (ind = 0; ind < stacks_tmp->stacksize; ind++) {
864
        fprintf(final_ptr, "%c%c", stacks_tmp->stack[ind].type, stacks_tmp->stack[ind].sign);
865
        if (stacks_tmp->stack[ind].type == STACK_ITEM_TYPE_STRING)
866
          fprintf(final_ptr, "%s%c", stacks_tmp->stack[ind].string, 0);
867
        else {
868
          dou = stacks_tmp->stack[ind].value;
869
          WRITEOUT_DOU
870
        }
871
      }
872
 
873
      stacks_tmp = stacks_tmp->next;
874
    }
875
 
876
    /* data area */
877
    ind = 0;
878
    for (inz = 0; inz < max_address; inz++) {
879
      if (rom_banks_usage_table[inz] != 0) {
880
        /* data block id */
881
        fprintf(final_ptr, "%c", 0x0);
882
        for (i = inz, ind = 0; inz < max_address; inz++, ind++)
883
          if (rom_banks_usage_table[inz] == 0) {
884
 
885
            ov = i;
886
            WRITEOUT_OV
887
 
888
            ov = ind;
889
            WRITEOUT_OV
890
 
891
            fwrite(&rom_banks[i], 1, ind, final_ptr);
892
 
893
            ind = 0;
894
            break;
895
          }
896
      }
897
    }
898
 
899
    if (ind != 0) {
900
      ov = i;
901
      WRITEOUT_OV
902
 
903
      ov = ind;
904
      WRITEOUT_OV
905
 
906
      fwrite(&rom_banks[i], 1, ind, final_ptr);
907
    }
908
 
909
    sec_tmp = sections_first;
910
    while (sec_tmp != NULL) {
911
      if (sec_tmp->alive == ON) {
912
        /* section block id */
913
        fprintf(final_ptr, "%c%s%c%c%c%c", 0x1, sec_tmp->name, sec_tmp->status, sec_tmp->id, sec_tmp->slot, sec_tmp->filename_id);
914
 
915
        ov = sec_tmp->address;
916
        WRITEOUT_OV
917
        ov = sec_tmp->bank;
918
        WRITEOUT_OV
919
        ov = sec_tmp->size;
920
        WRITEOUT_OV
921
        ov = sec_tmp->alignment;
922
        WRITEOUT_OV
923
 
924
        fwrite(sec_tmp->data, 1, sec_tmp->size, final_ptr);
925
 
926
        if (listfile_data == YES && sec_tmp->listfile_items > 0)
927
          listfile_block_write(final_ptr, sec_tmp);
928
        else
929
          fprintf(final_ptr, "%c", 0);
930
      }
931
      sec_tmp = sec_tmp->next;
932
    }
933
 
934
    fclose(final_ptr);
935
  }
936
 
937
  /* output makefile rules */
938
  if (makefile_rules == YES) {
939
    fprintf(stderr, "%s: ", final_name);
940
    print_file_names();
941
  }
942
 
943
  /* show project information */
944
  if (verbose_mode == ON && output_format != OUTPUT_LIBRARY) {
945
    x = 0;
946
    for (ind = 0; ind < max_address; ind++) {
947
      if (rom_banks_usage_table[ind] == 0 && x == 0) {
948
        x = 1;
949
        inz = ind;
950
      }
951
      else if (rom_banks_usage_table[ind] != 0 && x == 1) {
952
        if (inz == (ind - 1))
953
          fprintf(stderr, "Free space at $%.4x.\n", inz);
954
        else
955
          fprintf(stderr, "Free space at $%.4x-$%.4x.\n", inz, ind - 1);
956
        x = 0;
957
      }
958
    }
959
 
960
    if (x == 1) {
961
      if (inz == (ind - 1))
962
        fprintf(stderr, "Free space at $%.4x.\n", inz);
963
      else
964
        fprintf(stderr, "Free space at $%.4x-$%.4x.\n", inz, ind - 1);
965
    }
966
 
967
    for (ind = 0, q = 0; ind < max_address; q++) {
968
      for (x = 0, inz = 0; inz < banks[q]; inz++) {
969
        if (rom_banks_usage_table[ind++] == 0)
970
          x++;
971
      }
972
      f = (((float)x)/banks[q]) * 100.0f;
973
      if (f == 100.0f)
974
        printf("Bank %.2d has %.5d bytes (%.1f%%) free.\n", q, x, f);
975
      else
976
        printf("Bank %.2d has %.5d bytes (%.2f%%) free.\n", q, x, f);
977
    }
978
 
979
    for (ind = 0, inz = 0; ind < max_address; ind++) {
980
      if (rom_banks_usage_table[ind] == 0)
981
        inz++;
982
    }
983
    fprintf(stderr, "%d unused bytes of total %d.\n", inz, max_address);
984
 
985
    sec_tmp = sections_first;
986
    while (sec_tmp != NULL) {
987
      if (sec_tmp->status == SECTION_STATUS_HEADER) {
988
        fprintf(stderr, "Bank %d header section size %d.\n", sec_tmp->bank, sec_tmp->size);
989
        ind += sec_tmp->size;
990
      }
991
      sec_tmp = sec_tmp->next;
992
    }
993
 
994
    if (ind != 0) {
995
      fprintf(stderr, "Total %d additional bytes (from headers and footers).\n", ind);
996
      fprintf(stderr, "Total size %d bytes.\n", ind + max_address);
997
    }
998
 
999
  }
1000
  else if (verbose_mode == ON && output_format == OUTPUT_LIBRARY) {
1001
 
1002
    sec_tmp = sections_first;
1003
    while (sec_tmp != NULL) {
1004
      printf("Section \"%s\" size %d.\n", sec_tmp->name, sec_tmp->size);
1005
      sec_tmp = sec_tmp->next;
1006
    }
1007
  }
1008
 
1009
  return SUCCEEDED;
1010
}
1011
 
1012
 
1013
int mem_insert(unsigned char x) {
1014
 
1015
  if (section_status == ON) {
1016
    sec_tmp->data[sec_tmp->i] = x;
1017
    sec_tmp->i++;
1018
    pc_bank++;
1019
    pc_full++;
1020
    pc_slot++;
1021
    return SUCCEEDED;
1022
  }
1023
 
1024
  if (pc_bank >= banksize) {
1025
    fprintf(stderr, "MEM_INSERT: Origin ($%x) overflows from bank (%d).\n", pc_bank, rom_bank);
1026
    return FAILED;
1027
  }
1028
  else if (pc_full >= max_address) {
1029
    fprintf(stderr, "MEM_INSERT: The current address ($%.4x) exceeds the size of the ROM ($%.4x).\n", pc_full, max_address);
1030
    return FAILED;
1031
  }
1032
  else if (pc_slot >= pc_slot_max) {
1033
    fprintf(stderr, "MEM_INSERT: The current address ($%.4x) overflows from SLOT %d.\n", pc_slot, slot);
1034
    return FAILED;
1035
  }
1036
 
1037
  if (rom_banks_usage_table[pc_full] != 0 && rom_banks[pc_full] != x && mem_insert_overwrite == OFF)
1038
    fprintf(stderr, "MEM_INSERT: %d. write into $%.4x (old: $%.2x, new: $%.2x).\n", rom_banks_usage_table[pc_full], pc_full, rom_banks[pc_full], x & 0xFF);
1039
 
1040
  rom_banks_usage_table[pc_full] = 2;
1041
  rom_banks[pc_full] = x;
1042
  pc_bank++;
1043
  pc_full++;
1044
  pc_slot++;
1045
 
1046
  return SUCCEEDED;
1047
}
1048
 
1049
 
1050
int mem_insert_pad(void) {
1051
 
1052
  if (section_status == ON) {
1053
    sec_tmp->i++;
1054
    pc_bank++;
1055
    pc_full++;
1056
    pc_slot++;
1057
    return SUCCEEDED;
1058
  }
1059
 
1060
  if (pc_bank >= banksize) {
1061
    fprintf(stderr, "MEM_INSERT_PAD: Origin ($%x) overflows from bank (%d).\n", pc_bank, rom_bank);
1062
    return FAILED;
1063
  }
1064
  else if (pc_full >= max_address) {
1065
    fprintf(stderr, "MEM_INSERT_PAD: The current address ($%.4x) exceeds the size of the ROM ($%.4x).\n", pc_full, max_address);
1066
    return FAILED;
1067
  }
1068
  else if (pc_slot >= pc_slot_max) {
1069
    fprintf(stderr, "MEM_INSERT_PAD: The current address ($%.4x) overflows from SLOT %d.\n", pc_slot, slot);
1070
    return FAILED;
1071
  }
1072
 
1073
  /* announce the overwrite later */
1074
  if (!(rom_banks_usage_table[pc_full] != 0 && mem_insert_overwrite == OFF))
1075
    rom_banks_usage_table[pc_full] = 1;
1076
 
1077
  pc_bank++;
1078
  pc_full++;
1079
  pc_slot++;
1080
 
1081
  return SUCCEEDED;
1082
}
1083
 
1084
 
1085
int mem_insert_absolute(unsigned int add, unsigned char x) {
1086
 
1087
  if (add >= max_address) {
1088
    fprintf(stderr, "MEM_INSERT_ABSOLUTE: The current address ($%.4x) exceeds the size of the ROM ($%.4x).\n", add, max_address);
1089
    return FAILED;
1090
  }
1091
 
1092
  if (rom_banks_usage_table[add] > 1 && rom_banks[add] != x && mem_insert_overwrite == OFF)
1093
    fprintf(stderr, "MEM_INSERT_ABSOLUTE: %d. write into $%.4x (old: $%.2x, new: $%.2x).\n", rom_banks_usage_table[add], add, rom_banks[add], x & 0xFF);
1094
 
1095
  rom_banks_usage_table[add]++;
1096
  rom_banks[add] = x;
1097
 
1098
  return SUCCEEDED;
1099
}
1100
 
1101
 
1102
int export_definitions(FILE *final_ptr) {
1103
 
1104
  struct export_def *export_tmp;
1105
  unsigned char *cp;
1106
  double dou;
1107
  int ov;
1108
 
1109
 
1110
  ov = 0;
1111
  export_tmp = export_first;
1112
  while (export_tmp != NULL) {
1113
    tmp_def = defines;
1114
    while (tmp_def != NULL) {
1115
      if (strcmp(tmp_def->alias, export_tmp->name) == 0) {
1116
        if (tmp_def->type == DEFINITION_TYPE_VALUE)
1117
          ov++;
1118
        if (tmp_def->type == DEFINITION_TYPE_STACK)
1119
          ov++;
1120
        break;
1121
      }
1122
      tmp_def = tmp_def->next;
1123
    }
1124
    export_tmp = export_tmp->next;
1125
  }
1126
 
1127
  WRITEOUT_OV
1128
 
1129
  export_tmp = export_first;
1130
  while (export_tmp != NULL) {
1131
 
1132
    tmp_def = defines;
1133
    while (tmp_def != NULL) {
1134
      if (strcmp(tmp_def->alias, export_tmp->name) == 0)
1135
        break;
1136
      tmp_def = tmp_def->next;
1137
    }
1138
 
1139
    if (tmp_def == NULL)
1140
      fprintf(stderr, "WARNING: Trying to export an unkonwn definition \"%s\".\n", export_tmp->name);
1141
    else {
1142
      if (tmp_def->type == DEFINITION_TYPE_VALUE) {
1143
        fprintf(final_ptr, "%s%c", tmp_def->alias, 0x0);
1144
        dou = tmp_def->value;
1145
        WRITEOUT_DOU
1146
      }
1147
      else if (tmp_def->type == DEFINITION_TYPE_STRING) {
1148
        fprintf(stderr, "INTERNAL_PASS_2: Definition \"%s\" is a string definition, and it cannot be exported.\n", export_tmp->name);
1149
      }
1150
      else if (tmp_def->type == DEFINITION_TYPE_STACK) {
1151
        fprintf(final_ptr, "%s%c", tmp_def->alias, 0x1);
1152
        dou = tmp_def->value;
1153
        WRITEOUT_DOU
1154
      }
1155
    }
1156
 
1157
    export_tmp = export_tmp->next;
1158
  }
1159
 
1160
  return SUCCEEDED;
1161
}
1162
 
1163
 
1164
int export_source_file_names(FILE *final_ptr) {
1165
 
1166
  struct file_name_info *f;
1167
  int ov;
1168
 
1169
 
1170
  f = file_name_info_first;
1171
  ov = 0;
1172
  while (f != NULL) {
1173
    ov++;
1174
    f = f->next;
1175
  }
1176
 
1177
  WRITEOUT_OV
1178
 
1179
  f = file_name_info_first;
1180
  while (f != NULL) {
1181
    fprintf(final_ptr, "%s%c%c", f->name, 0x00, f->id);
1182
    f = f->next;
1183
  }
1184
 
1185
  return SUCCEEDED;
1186
}
1187
 

powered by: WebSVN 2.1.0

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