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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 178 jshamlet
 
2
/*
3
 wlalink - part of wla dx gb-z80/z80/6502/65c02/6510/v8urisc/65816/huc6280/spc-700
4
 macro assembler package by ville helin <vhelin@iki.fi>. this is gpl software.
5
 */
6
 
7
#include <ctype.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <string.h>
11
 
12
#include "defines.h"
13
#include "main.h"
14
#include "memory.h"
15
#include "files.h"
16
#include "check.h"
17
#include "analyze.h"
18
#include "write.h"
19
#include "compute.h"
20
#include "discard.h"
21
#include "listfile.h"
22
 
23
/* define this if you want to display debug information */
24
/*
25
#define _MAIN_DEBUG
26
*/
27
 
28
struct object_file *obj_first = NULL, *obj_last = NULL, *obj_tmp;
29
struct reference *reference_first = NULL, *reference_last = NULL;
30
struct section *sec_first = NULL, *sec_last = NULL, *sec_hd_first = NULL, *sec_hd_last = NULL;
31
struct stack *stacks_first = NULL, *stacks_last = NULL;
32
struct label *labels_first = NULL, *labels_last = NULL;
33
struct slot slots[256];
34
unsigned char *rom, *rom_usage, *file_header = NULL, *file_footer = NULL;
35
int romsize, rombanks, banksize, verbose_mode = OFF, section_overwrite = OFF, symbol_mode = SYMBOL_MODE_NONE;
36
int pc_bank, pc_full, pc_slot, pc_slot_max;
37
int file_header_size, file_footer_size, *banks = NULL, *bankaddress = NULL;
38
int output_mode = OUTPUT_ROM, discard_unreferenced_sections = OFF;
39
int program_start, program_end, sms_checksum, snes_rom_mode = SNES_ROM_MODE_LOROM, snes_rom_speed = SNES_ROM_SPEED_SLOWROM;
40
int gb_checksum, gb_complement_check, snes_checksum, cpu_65816 = 0, snes_mode = 0;
41
int listfile_data = NO, smc_status = 0, snes_sramsize = 0;
42
 
43
extern int emptyfill;
44
 
45
 
46
 
47
int main(int argc, char *argv[]) {
48
 
49
  int i, x, y, q, inz;
50
  struct section *s;
51
  float f;
52
 
53
 
54
  if (sizeof(double) != 8) {
55
    fprintf(stderr, "MAIN: sizeof(double) == %ld != 8. Open8_link will not work properly.\n", sizeof(double));
56
    return -1;
57
  }
58
 
59
  atexit(procedures_at_exit);
60
 
61
  i = SUCCEEDED;
62
  x = SUCCEEDED;
63
 
64
  if (argc > 1)
65
    x = parse_flags(argv[1]);
66
  else
67
    i = FAILED;
68
 
69
  if (x == FAILED && argc != 3)
70
    i = FAILED;
71
  if (x == SUCCEEDED && argc != 4)
72
    i = FAILED;
73
 
74
  if (i == FAILED) {
75
    printf("\nOpen8 Linker v0.9\n\n");
76
    printf("Based on WLA assembler by Ville Helin in 1998-2004\n");
77
    printf("Modified for V8 uRISC architecture by Bill Wiley\n");
78
    printf("Modified for Open8 uRISC architecture by Seth Henry\n\n");
79
    printf("USAGE: %s [-bdrvsS] <LINK FILE> <OUTPUT FILE>\n", argv[0]);
80
    printf("Options:\n");
81
    printf("b  Program file output\n");
82
    printf("d  Discard unreferenced sections\n");
83
    printf("i  Write list files\n");
84
    printf("r  ROM file output (default)\n");
85
    printf("v  Verbose messages\n");
86
    printf("s  Write also a NO$GMB symbol file\n");
87
    printf("S  Write also a WLA symbol file\n\n");
88
    return 0;
89
  }
90
 
91
  /* load files */
92
  if (load_files(argv, argc) == FAILED)
93
    return 1;
94
 
95
  /* check file types */
96
  if (check_file_types() == FAILED)
97
    return 1;
98
 
99
  /* check object headers */
100
  if (check_headers() == FAILED)
101
    return 1;
102
 
103
  /* obtain the amount of rom banks */
104
  if (obtain_rombanks() == FAILED)
105
    return 1;
106
 
107
  banks = malloc(sizeof(int) * rombanks);
108
  if (banks == NULL) {
109
    fprintf(stderr, "MAIN: Out of memory error.\n");
110
    return 1;
111
  }
112
  bankaddress = malloc(sizeof(int) * rombanks);
113
  if (bankaddress == NULL) {
114
    fprintf(stderr, "MAIN: Out of memory error.\n");
115
    return 1;
116
  }
117
 
118
  /* obtain rom bank map and check the project integrity */
119
  if (obtain_rombankmap() == FAILED)
120
    return 1;
121
 
122
  /* obtain memory map and check the project integrity */
123
  if (obtain_memorymap() == FAILED)
124
    return 1;
125
 
126
  /* calculate romsize */
127
  for (romsize = 0, x = 0; x < rombanks; x++)
128
    romsize += banks[x];
129
 
130
  /* obtain source file names used in compiling */
131
  if (obtain_source_file_names() == FAILED)
132
    return 1;
133
 
134
  /* collect all defines, labels and outside references */
135
  if (collect_dlr() == FAILED)
136
    return 1;
137
 
138
  /* take rom size and allocate memory */
139
  if (allocate_rom() == FAILED)
140
    return 1;
141
 
142
  /* parse data blocks */
143
  if (parse_data_blocks() == FAILED)
144
    return 1;
145
 
146
  /* clean up the structures */
147
  if (clean_up_dlr() == FAILED)
148
    return 1;
149
 
150
  /* drop all unreferenced sections */
151
  if (discard_unreferenced_sections == ON) {
152
    if (discard_unused_sections() == FAILED)
153
      return 1;
154
    /* remove dropped labels */
155
    discard_drop_labels();
156
  }
157
 
158
  /* correct 65816 library section addresses */
159
  if (cpu_65816 != 0) {
160
    if (correct_65816_library_sections() == FAILED)
161
      return 1;
162
  }
163
 
164
#ifdef _MAIN_DEBUG
165
  {
166
    printf("\n*********************************************\n");
167
    printf("JUST LOADED IN\n");
168
    printf("*********************************************\n\n");
169
  }
170
 
171
  {
172
    struct label *l;
173
 
174
    printf("LABELS:\n");
175
    l = labels_first;
176
    while (l != NULL) {
177
      printf("--------------------------------------\n");
178
      printf("name: \"%s\"\n", l->name);
179
      printf("sect: \"%d\"\n", l->section);
180
      printf("slot: \"%d\"\n", l->slot);
181
      printf("base: \"%d\"\n", l->base);
182
      printf("address: \"%d\"\n", (int)l->address);
183
      printf("status: \"%d\"\n", l->status);
184
      printf("file_id: \"%d\"\n", l->file_id);
185
      l = l->next;
186
    }
187
    printf("--------------------------------------\n");
188
  }
189
 
190
  {
191
    struct stack *s;
192
 
193
    printf("STACKS:\n");
194
    s = stacks_first;
195
    while (s != NULL) {
196
      printf("--------------------------------------\n");
197
      printf("result: \"%d\"\n", s->result);
198
      printf("id: \"%d\"\n", s->id);
199
      printf("file_id: \"%d\"\n", s->file_id);
200
      printf("bank: \"%d\"\n", s->bank);
201
      printf("linenumber: \"%d\"\n", s->linenumber);
202
      printf("type: \"%d\"\n", s->type);
203
      printf("position: \"%d\"\n", s->position);
204
      s = s->next;
205
    }
206
    printf("--------------------------------------\n");
207
  }
208
#endif
209
 
210
  /* insert sections */
211
  if (insert_sections() == FAILED)
212
    return 1;
213
 
214
#ifdef _MAIN_DEBUG
215
  {
216
    struct section *s;
217
 
218
    printf("SECTIONS:\n");
219
    s = sec_first;
220
    while (s != NULL) {
221
      printf("--------------------------------------\n");
222
      printf("file: \"%s\"\n", get_file_name(s->file_id));
223
      printf("name: \"%s\"\n", s->name);
224
      printf("id:   %d\n", s->id);
225
      printf("addr: %d\n", s->address);
226
      printf("stat: %d\n", s->status);
227
      printf("bank: %d\n", s->bank);
228
      printf("slot: %d\n", s->slot);
229
      printf("size: %d\n", s->size);
230
      s = s->next;
231
    }
232
    printf("--------------------------------------\n");
233
  }
234
#endif
235
 
236
  /* compute the labels' addresses */
237
  if (fix_labels() == FAILED)
238
    return 1;
239
 
240
  /* compute pending calculations */
241
  if (compute_pending_calculations() == FAILED)
242
    return 1;
243
 
244
#ifdef _MAIN_DEBUG
245
  {
246
    struct stack *s;
247
 
248
    printf("RESOLVED STACKS:\n");
249
    s = stacks_first;
250
    while (s != NULL) {
251
      printf("--------------------------------------\n");
252
      printf("result: \"%d\"\n", s->result);
253
      printf("id: \"%d\"\n", s->id);
254
      printf("file_id: \"%d\"\n", s->file_id);
255
      s = s->next;
256
    }
257
    printf("--------------------------------------\n");
258
  }
259
#endif
260
 
261
#ifdef _MAIN_DEBUG
262
  {
263
    struct reference *r;
264
 
265
    printf("REFERENCES:\n");
266
    r = reference_first;
267
    while (r != NULL) {
268
      printf("--------------------------------------\n");
269
      printf("name: \"%s\"\n", r->name);
270
      printf("file_id: \"%d\"\n", r->file_id);
271
      r = r->next;
272
    }
273
    printf("--------------------------------------\n");
274
  }
275
#endif
276
 
277
  /* transform computation stack definitions to ordinary definitions */
278
  if (transform_stack_definitions() == FAILED)
279
    return 1;
280
 
281
  /* fix references */
282
  if (fix_references() == FAILED)
283
    return 1;
284
 
285
  /* write checksums and other last minute data */
286
  if (compute_checksums() == FAILED)
287
    return 1;
288
 
289
  /* write rom file */
290
  if (write_rom_file(argv[argc - 1]) == FAILED)
291
    return 1;
292
 
293
#ifdef _MAIN_DEBUG
294
  {
295
    printf("\n*********************************************\n");
296
    printf("AFTER EVERYTHING\n");
297
    printf("*********************************************\n\n");
298
  }
299
 
300
  {
301
    struct label *l;
302
 
303
    printf("LABELS:\n");
304
    l = labels_first;
305
    while (l != NULL) {
306
      printf("--------------------------------------\n");
307
      printf("name: \"%s\"\n", l->name);
308
      printf("sect: \"%d\"\n", l->section);
309
      printf("slot: \"%d\"\n", l->slot);
310
      printf("base: \"%d\"\n", l->base);
311
      printf("address: \"%d\"\n", (int)l->address);
312
      printf("rom_address: \"%d\"\n", l->rom_address);
313
      printf("bank: \"%d\"\n", l->bank);
314
      printf("status: \"%d\"\n", l->status);
315
      printf("file_id: \"%d\"\n", l->file_id);
316
      l = l->next;
317
    }
318
    printf("--------------------------------------\n");
319
  }
320
#endif
321
 
322
  /* export symbolic information file */
323
  if (symbol_mode != SYMBOL_MODE_NONE) {
324
    if (write_symbol_file(argv[argc - 1], symbol_mode) == FAILED)
325
      return FAILED;
326
  }
327
 
328
  /* write list files */
329
  if (listfile_data == YES) {
330
    if (listfile_write_listfiles(sec_first) == FAILED)
331
      return FAILED;
332
  }
333
 
334
  /* show rom information */
335
  y = 0;
336
  if (verbose_mode == ON) {
337
    x = 0;
338
    for (i = 0; i < romsize; i++) {
339
      if (rom_usage[i] == 0 && x == 0) {
340
        x = 1;
341
        y = i;
342
      }
343
      else if (rom_usage[i] != 0 && x == 1) {
344
        if (y == (i - 1))
345
          fprintf(stderr, "Free space at $%.4x.\n", y);
346
        else
347
          fprintf(stderr, "Free space at $%.4x-$%.4x.\n", y, i - 1);
348
        x = 0;
349
      }
350
    }
351
 
352
    if (x == 1) {
353
      if (y == (i - 1))
354
        fprintf(stderr, "Free space at $%.4x.\n", y);
355
      else
356
        fprintf(stderr, "Free space at $%.4x-$%.4x.\n", y, i - 1);
357
    }
358
 
359
    for (y = 0, q = 0; y < romsize; q++) {
360
      for (x = 0, inz = 0; inz < banks[q]; inz++) {
361
        if (rom_usage[y++] == 0)
362
          x++;
363
      }
364
      f = (((float)x)/banks[q]) * 100.0f;
365
      if (f == 100.0f)
366
        printf("Bank %.2d has %.5d bytes (%.1f%%) free.\n", q, x, f);
367
      else
368
        printf("Bank %.2d has %.5d bytes (%.2f%%) free.\n", q, x, f);
369
    }
370
 
371
    /* ROM data */
372
    if (output_mode == OUTPUT_ROM) {
373
      for (i = 0, y = 0; i < romsize; i++) {
374
        if (rom_usage[i] == 0)
375
          y++;
376
      }
377
 
378
      fprintf(stderr, "%d unused bytes of total %d.\n", y, romsize);
379
      q = romsize;
380
    }
381
    /* program file data */
382
    else {
383
      for (i = program_start, y = 0; i < program_end; i++) {
384
        if (rom_usage[i] == 0)
385
          y++;
386
      }
387
 
388
      q = program_end - program_start + 1;
389
      fprintf(stderr, "%d unused bytes (%.2f%%) of total %d.\n", y, (((double)y) / q) * 100, q);
390
    }
391
 
392
    if (file_header_size != 0)
393
      fprintf(stderr, "File header size %d.\n", file_header_size);
394
    if (file_footer_size != 0)
395
      fprintf(stderr, "File footer size %d.\n", file_footer_size);
396
 
397
    if (smc_status != 0) {
398
      fprintf(stderr, "512 additional bytes from the SMC ROM header.\n");
399
      i = file_header_size + file_footer_size + 512;
400
    }
401
    else
402
      i = file_header_size + file_footer_size;
403
 
404
    s = sec_hd_first;
405
    while (s != NULL) {
406
      fprintf(stderr, "Bank %d header section size %d.\n", s->bank, s->size);
407
      i += s->size;
408
      s = s->next;
409
    }
410
 
411
    if (i != 0) {
412
      fprintf(stderr, "Total %d additional bytes (from headers and footers).\n", i);
413
      fprintf(stderr, "Total size %d bytes.\n", i + q);
414
    }
415
  }
416
 
417
  return 0;
418
}
419
 
420
 
421
void procedures_at_exit(void) {
422
 
423
  struct source_file_name *f, *fn;
424
  struct object_file *o;
425
  struct reference *r;
426
  struct section *s;
427
  struct stack *sta;
428
  struct label *l;
429
 
430
 
431
  /* free all the dynamically allocated data structures */
432
  while (obj_first != NULL) {
433
    f = obj_first->source_file_names_list;
434
    while (f != NULL) {
435
      if (f->name != NULL)
436
        free(f->name);
437
      fn = f->next;
438
      free(f);
439
      f = fn;
440
    }
441
    if (obj_first->data != NULL)
442
      free(obj_first->data);
443
    if (obj_first->name != NULL)
444
      free(obj_first->name);
445
    o = obj_first;
446
    obj_first = obj_first->next;
447
    free(o);
448
  }
449
 
450
  while (labels_first != NULL) {
451
    l = labels_first;
452
    labels_first = labels_first->next;
453
    free(l);
454
  }
455
 
456
  while (reference_first != NULL) {
457
    r = reference_first;
458
    reference_first = reference_first->next;
459
    free(r);
460
  }
461
 
462
  while (stacks_first != NULL) {
463
    sta = stacks_first->next;
464
    free(stacks_first->stack);
465
    free(stacks_first);
466
    stacks_first = sta;
467
  }
468
 
469
  while (sec_first != NULL) {
470
    s = sec_first->next;
471
    if (sec_first->listfile_cmds != NULL)
472
      free(sec_first->listfile_cmds);
473
    if (sec_first->listfile_ints != NULL)
474
      free(sec_first->listfile_ints);
475
    free(sec_first);
476
    sec_first = s;
477
  }
478
 
479
  while (sec_hd_first != NULL) {
480
    s = sec_hd_first->next;
481
    free(sec_hd_first);
482
    sec_hd_first = s;
483
  }
484
 
485
  if (banks != NULL)
486
    free(banks);
487
  if (bankaddress != NULL)
488
    free(bankaddress);
489
}
490
 
491
 
492
int parse_flags(char *f) {
493
 
494
  int l, output_mode_defined = 0;
495
 
496
 
497
  if (*f != '-')
498
    return FAILED;
499
 
500
  l = strlen(f);
501
  if (l == 1)
502
    return FAILED;
503
 
504
  for (f++, l--; l > 0; l--, f++) {
505
    switch (*f) {
506
    case 'v':
507
      verbose_mode = ON;
508
      continue;
509
    case 'i':
510
      listfile_data = YES;
511
      continue;
512
    case 's':
513
      symbol_mode = SYMBOL_MODE_NOCA5H;
514
      continue;
515
    case 'S':
516
      symbol_mode = SYMBOL_MODE_WLA;
517
      continue;
518
    case 'b':
519
      if (output_mode_defined == 1)
520
        return FAILED;
521
      output_mode_defined++;
522
      output_mode = OUTPUT_PRG;
523
      continue;
524
    case 'r':
525
      if (output_mode_defined == 1)
526
        return FAILED;
527
      output_mode_defined++;
528
      output_mode = OUTPUT_ROM;
529
      continue;
530
    case 'd':
531
      discard_unreferenced_sections = ON;
532
      continue;
533
    default:
534
      return FAILED;
535
    }
536
  }
537
 
538
  return SUCCEEDED;
539
}
540
 
541
 
542
int allocate_rom(void) {
543
 
544
  rom = malloc(sizeof(unsigned char) * romsize);
545
  if (rom == NULL) {
546
    fprintf(stderr, "ALLOCATE_ROM: Out of memory.\n");
547
    return FAILED;
548
  }
549
  rom_usage = malloc(sizeof(unsigned char) * romsize);
550
  if (rom_usage == NULL) {
551
    fprintf(stderr, "ALLOCATE_ROM: Out of memory.\n");
552
    return FAILED;
553
  }
554
  memset(rom, emptyfill, romsize);
555
  memset(rom_usage, 0, romsize);
556
 
557
  return SUCCEEDED;
558
}

powered by: WebSVN 2.1.0

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