示例#1
0
文件: write.c 项目: Mtgxyz/wla-dx
int fix_labels(void) {

  struct section *s = NULL;
  struct label *l, *m;

  
  /* fix labels' addresses */
  l = labels_first;
  while (l != NULL) {
    if (l->status == LABEL_STATUS_LABEL || l->status == LABEL_STATUS_SYMBOL || l->status == LABEL_STATUS_BREAKPOINT) {
      if (l->section_status == ON) {
	s = sec_first;
	while (s != NULL) {
	  if (s->id == l->section) {
	    l->bank = s->bank;
	    l->address += s->address;
	    l->rom_address = l->address + bankaddress[l->bank];
	    if (s->status != SECTION_STATUS_ABSOLUTE)
	      l->address += slots[l->slot].address;
	    break;
	  }
	  s = s->next;
	}
      }
      else {
	l->rom_address = l->address + bankaddress[l->bank];
	l->address += slots[l->slot].address;
      }
    }
    l = l->next;
  }

  /* check out if a label exists more than once in a different place */
  l = labels_first;
  while (l != NULL) {
    if (is_label_anonymous(l->name) == FAILED && (l->status == LABEL_STATUS_LABEL || l->status == LABEL_STATUS_DEFINE)) {
      m = l->next;
      while (m != NULL) {
	if (strcmp(m->name, l->name) == 0) {
	  if (l->address != m->address && !(m->name[0] == '*' || m->name[0] == '_')) {
	    if (l->status == LABEL_STATUS_DEFINE)
	      fprintf(stderr, "%s: FIX_LABELS: Definition \"%s\" was defined more than once.\n", get_file_name(l->file_id), l->name);
	    else
	      fprintf(stderr, "%s:%s:%d: FIX_LABELS: Label \"%s\" was defined more than once.\n", get_file_name(l->file_id),
		      get_source_file_name(l->file_id, l->file_id_source), l->linenumber, l->name);
	    return FAILED;
	  }
	}
	m = m->next;
      }
    }
    l = l->next;
  }

  return SUCCEEDED;
}
示例#2
0
文件: pass_3.c 项目: Mtgxyz/wla-dx
int pass_3(void) {

  struct section_def *s;
  struct label_def *l;
  struct block *b;
  FILE *f_in;
  int bank = 0, slot = 0, add = 0, file_name_id = 0, inz, line_number = 0, o, add_old = 0;
#ifdef W65816
  int base = 0x00;
#endif
  char c;

  
  s = NULL;

  if (verbose_mode == ON)
    printf("Internal pass 1...\n");

  if ((f_in = fopen(gba_tmp_name, "rb")) == NULL) {
    fprintf(stderr, "INTERNAL_PASS_1: Error opening file \"%s\".\n", gba_tmp_name);
    return FAILED;
  }

  /* first loop */
  o = 0;
  if (output_format == OUTPUT_OBJECT) {
    while (o == 0 && fread(&c, 1, 1, f_in) != 0) {
      switch (c) {

      case ' ':
      case 'E':
	continue;

      case 'P':
	add_old = add;
	continue;
      case 'p':
	add = add_old;
	continue;

      case 'x':
	fscanf(f_in, "%d %*d ", &inz);
	if (section_status == ON) {
	  add += inz;
	  continue;
	}

	fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
	return FAILED;

      case 'd':
	if (section_status == ON) {
	  fscanf(f_in, "%*s ");
	  add++;
	  continue;
	}

	fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
	return FAILED;

      case 'y':
	if (section_status == ON) {
	  fscanf(f_in, "%*d ");
	  add += 2;
	  continue;
	}

	fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
	return FAILED;

#ifdef W65816
      case 'b':
	fscanf(f_in, "%d ", &base);
	continue;
#endif

      case 'f':
	fscanf(f_in, "%d ", &file_name_id);
	continue;

      case 'B':
	fscanf(f_in, "%d %d ", &bank, &slot);
	continue;

      case 'k':
	fscanf(f_in, "%d ", &line_number);
	continue;

      case 'g':
	b = malloc(sizeof(struct block));
	if (b == NULL) {
	  fscanf(f_in, "%64s ", tmp);
	  fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for block \"%s\".\n",
		  get_file_name(file_name_id), line_number, tmp);
	  return FAILED;
	}
	b->next = blocks;
	blocks = b;
	fscanf(f_in, "%64s ", b->name);
	b->address = add;
	continue;

      case 'G':
	b = blocks;
	blocks = blocks->next;
	fprintf(stderr, "INTERNAL_PASS_1: Block \"%s\" is %d bytes.\n", b->name, add - b->address);
	free(b);
	continue;

      case 'Z':
      case 'Y':
      case 'L':
	l = malloc(sizeof(struct label_def));
	if (l == NULL) {
	  fscanf(f_in, "%64s ", tmp);
	  fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for label \"%s\".\n",
		  get_file_name(file_name_id), line_number, tmp);
	  return FAILED;
	}

	if (c == 'Y')
	  l->symbol = 1;
	else if (c == 'L')
	  l->symbol = 0;
	else
	  l->symbol = 2;
	
	if (c == 'Z')
	  l->label[0] = 0;
	else
	  fscanf(f_in, "%64s ", l->label);

	l->next = NULL;
	l->section_status = ON;
	l->filename_id = file_name_id;
	l->linenumber = line_number;
	l->alive = ON;
	l->section_id = s->id;
	/* section labels get a relative address */
	l->address = add;
	l->bank = s->bank;
	l->slot = s->slot;
#ifdef W65816
	l->base = base;
#endif

	if (c == 'Z' || is_label_anonymous(l->label) == SUCCEEDED || strcmp(l->label, "__") == 0) {
	  if (labels != NULL) {
	    label_last->next = l;
	    label_last = l;
	  }
	  else {
	    labels = l;
	    label_last = l;
	  }
	  continue;
	}

	label_next = labels;
	while (label_next != NULL) {
	  if (strcmp(l->label, label_next->label) == 0) {
	    if ((l->label[0] != '_') || /* both are not local labels */
		(section_status == OFF && label_next->section_status == OFF) ||
		(section_status == ON && label_next->section_status == ON && label_next->section_id == l->section_id)) {
	      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);
	      return FAILED;
	    }
	  }
	  label_next = label_next->next;
	}

	if (labels != NULL) {
	  label_last->next = l;
	  label_last = l;
	}
	else {
	  labels = l;
	  label_last = l;
	}
	
	continue;

      case 'S':
	fscanf(f_in, "%d ", &inz);

	add_old = add;

	s = sections_first;
	while (s->id != inz)
	  s = s->next;

	/* a RAMSECTION? */
	if (s->status == SECTION_STATUS_RAM) {
	  s->address = 0;
	  s->listfile_items = 1;
	  s->listfile_ints = NULL;
	  s->listfile_cmds = NULL;
	  add = 0;
	  section_status = ON;
	  continue;
	}

	fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
	return FAILED;

      case 's':
	s->size = add - s->address;

	/* discard an empty section? */
	if (s->size == 0) {
	  fprintf(stderr, "INTERNAL_PASS_1: %s: Discarding an empty section \"%s\".\n", get_file_name(file_name_id), s->name);
	  s->alive = OFF;

	  /* discard all labels which belong to this section */
	  l = labels;
	  while (l != NULL) {
	    if (l->section_status == ON && l->section_id == s->id)
	      l->alive = OFF;
	    l = l->next;
	  }
	}

	if (s->advance_org == NO)
	  add = add_old;

	section_status = OFF;
	s = NULL;
	continue;

      case 'O':
	fscanf(f_in, "%d ", &add);
	o++;
	continue;

      default:
	fprintf(stderr, "INTERNAL_PASS_1: .ORG needs to be set before any code/data can be accepted.\n");
	return FAILED;
      }
    }
  }
  else {
    while (o == 0 && fread(&c, 1, 1, f_in) != 0) {
      switch (c) {

      case ' ':
      case 'E':
	continue;

      case 'f':
	fscanf(f_in, "%d ", &file_name_id);
	continue;

      case 'S':
	fscanf(f_in, "%d ", &inz);

	add_old = add;

	s = sections_first;
	while (s->id != inz)
	  s = s->next;

	if (s->status == SECTION_STATUS_FREE)
	  add = 0;

	s->address = add;
	s->bank = bank;
	s->slot = slot;
	s->listfile_items = 1;
	s->listfile_ints = NULL;
	s->listfile_cmds = NULL;
	section_status = ON;
	o++;
	continue;

      default:
	fprintf(stderr, "INTERNAL_PASS_1: A section must be open before any code/data can be accepted.\n");
	return FAILED;
      }
    }
  }

  /* second (major) loop */
  while (fread(&c, 1, 1, f_in) != 0) {
    switch (c) {

    case ' ':
    case 'E':
      continue;

    case 'P':
      add_old = add;
      continue;
    case 'p':
      add = add_old;
      continue;

    case 'A':
    case 'S':
      if (c == 'A')
	fscanf(f_in, "%d %*d", &inz);
      else
	fscanf(f_in, "%d ", &inz);

      add_old = add;

      s = sections_first;
      while (s->id != inz)
	s = s->next;

      if (s->status == SECTION_STATUS_FREE || s->status == SECTION_STATUS_RAM)
	add = 0;

      if (s->status != SECTION_STATUS_RAM) {
	s->bank = bank;
	s->slot = slot;
      }
      s->address = add;
      s->listfile_items = 1;
      s->listfile_ints = NULL;
      s->listfile_cmds = NULL;
      section_status = ON;
      continue;

    case 's':
      s->size = add - s->address;

      /* discard an empty section? */
      if (s->size == 0) {
	fprintf(stderr, "DISCARD: %s: Discarding an empty section \"%s\".\n", get_file_name(file_name_id), s->name);
	s->alive = OFF;

	/* discard all labels which belong to this section */
	l = labels;
	while (l != NULL) {
	  if (l->section_status == ON && l->section_id == s->id)
	    l->alive = OFF;
	  l = l->next;
	}
      }

      /* some sections don't affect the ORG outside of them */
      if (s->advance_org == NO)
	add = add_old;

      section_status = OFF;
      s = NULL;
      continue;

    case 'x':
      fscanf(f_in, "%d %*d ", &inz);
      add += inz;
      continue;

    case 'X':
      fscanf(f_in, "%d %*d ", &inz);
      add += inz << 1;
      continue;

#ifdef W65816
    case 'z':
    case 'q':
      fscanf(f_in, "%*s ");
      add += 3;
      continue;

    case 'T':
      fscanf(f_in, "%*d ");
      add += 3;
      continue;

    case 'b':
      fscanf(f_in, "%d ", &base);
      continue;
#endif

    case 'R':
    case 'Q':
    case 'd':
    case 'c':
      fscanf(f_in, "%*s ");
      add++;
      continue;

#ifdef W65816
    case 'M':
#endif
    case 'r':
      fscanf(f_in, "%*s ");
      add += 2;
      continue;

    case 'y':
    case 'C':
      fscanf(f_in, "%*d ");
      add += 2;
      continue;

    case 'D':
      fscanf(f_in, "%*d %*d %*d %d ", &inz);
      add += inz;
      continue;

    case 'O':
      fscanf(f_in, "%d ", &add);
      continue;

    case 'B':
      fscanf(f_in, "%d %d ", &bank, &slot);
      continue;

    case 'g':
      b = malloc(sizeof(struct block));
      if (b == NULL) {
	fscanf(f_in, "%64s ", tmp);
	fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for block \"%s\".\n",
		get_file_name(file_name_id), line_number, tmp);
	return FAILED;
      }
      b->next = blocks;
      blocks = b;
      fscanf(f_in, "%64s ", b->name);
      b->address = add;
      continue;

    case 'G':
      b = blocks;
      blocks = blocks->next;
      fprintf(stderr, "INTERNAL_PASS_1: Block \"%s\" is %d bytes.\n", b->name, add - b->address);
      free(b);
      continue;

    case 'Z':
    case 'Y':
    case 'L':
      l = malloc(sizeof(struct label_def));
      if (l == NULL) {
	fscanf(f_in, "%64s ", tmp);
	fprintf(stderr, "%s:%d INTERNAL_PASS_1: Out of memory while trying to allocate room for label \"%s\".\n",
		get_file_name(file_name_id), line_number, tmp);
	return FAILED;
      }

      if (c == 'Y')
	l->symbol = 1;
      else if (c == 'L')
	l->symbol = 0;
      else
	l->symbol = 2;

      if (c == 'Z')
	l->label[0] = 0;
      else
	fscanf(f_in, "%64s ", l->label);

      l->next = NULL;
      l->section_status = section_status;
      l->filename_id = file_name_id;
      l->linenumber = line_number;
      l->alive = ON;
      if (section_status == ON) {
	l->section_id = s->id;
	/* section labels get a relative address */
	l->address = add - s->address;
	l->bank = s->bank;
	l->slot = s->slot;
      }
      else {
	l->section_id = 0;
	l->address = add;
	l->bank = bank;
	l->slot = slot;
      }

#ifdef W65816
      l->base = base;
#endif

      if (c == 'Z' || is_label_anonymous(l->label) == SUCCEEDED || strcmp(l->label, "__") == 0) {
	if (labels != NULL) {
	  label_last->next = l;
	  label_last = l;
	}
	else {
	  labels = l;
	  label_last = l;
	}
	continue;
      }

      label_next = labels;
      while (label_next != NULL) {
	if (strcmp(l->label, label_next->label) == 0) {
	  if ((l->label[0] != '_') || /* both are not local labels */
	      (section_status == OFF && label_next->section_status == OFF) ||
	      (section_status == ON && label_next->section_status == ON && label_next->section_id == l->section_id)) {
	    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);
	    return FAILED;
	  }
	}
	label_next = label_next->next;
      }

      if (labels != NULL) {
	label_last->next = l;
	label_last = l;
      }
      else {
	labels = l;
	label_last = l;
      }

      continue;

    case 'f':
      fscanf(f_in, "%d ", &file_name_id);
      if (s != NULL)
	s->listfile_items++;
      continue;

    case 'k':
      fscanf(f_in, "%d ", &line_number);
      if (s != NULL)
	s->listfile_items++;
      continue;

    default:
      fprintf(stderr, "%s: INTERNAL_PASS_1: Unknown internal symbol \"%c\".\n", get_file_name(file_name_id), c);
      return FAILED;
    }
  }

  fclose(f_in);

  return SUCCEEDED;
}
示例#3
0
文件: write.c 项目: Mtgxyz/wla-dx
int fix_references(void) {

  struct reference *r;
  struct section *s = NULL;
  struct label *l, lt;
  int i, x;

  
  section_overwrite = OFF;

  /* insert references */
  r = reference_first;
  while (r != NULL) {
    x = r->address;
    /* search for the section of the reference and fix the address */
    if (r->section_status == ON) {
      s = sec_first;
      while (s != NULL) {
	if (s->id == r->section) {
	  r->bank = s->bank;
	  x += s->address;
	  r->address += s->address;
	  break;
	}
	s = s->next;
      }
      /* reference is inside a discarded section? */
      if (s != NULL && s->alive == NO) {
	r = r->next;
	continue;
      }
      if (s == NULL) {
	if (write_bank_header_references(r) == FAILED)
	  return FAILED;
	r = r->next;
	continue;
      }
    }

    if (!(r->section_status == ON && s->status == SECTION_STATUS_ABSOLUTE)) {
      x += bankaddress[r->bank];
      r->address += slots[r->slot].address;
    }

    /* find the destination */
    l = labels_first;

    /* request for bank number? */
    if (r->name[0] == ':') {
      if (is_label_anonymous(&r->name[1]) == SUCCEEDED) {
	l = get_closest_anonymous_label(&r->name[1], x, r->file_id, l, r->section_status, r->section);
      }
      else if (strcmp(&r->name[1], "CADDR") == 0 || strcmp(&r->name[1], "caddr") == 0) {
	lt.status = LABEL_STATUS_LABEL;
	strcpy(lt.name, &r->name[1]);
	lt.address = r->address;
	lt.bank = r->bank;
	lt.section_status = OFF;
	l = &lt;
      }
      else {
	while (l != NULL) {
	  if (strcmp(l->name, &r->name[1]) == 0 && l->status != LABEL_STATUS_SYMBOL && l->status != LABEL_STATUS_BREAKPOINT)
	    break;
	  l = l->next;
	}
      }

      if (l == NULL) {
	fprintf(stderr, "%s:%s:%d: FIX_REFERENCES: Bank number request for an unknown label \"%s\".\n",
		get_file_name(r->file_id), get_source_file_name(r->file_id, r->file_id_source), r->linenumber, &r->name[1]);
	return FAILED;
      }

      if (cpu_65816 != 0)
	i = get_snes_pc_bank(l) >> 16;
      else
	i = l->bank;

      memory_file_id = r->file_id;
      memory_file_id_source = r->file_id_source;
      memory_line_number = r->linenumber;

      /* direct 16bit */
      if (r->type == REFERENCE_TYPE_DIRECT_16BIT || r->type == REFERENCE_TYPE_RELATIVE_16BIT) {
	mem_insert_ref(x, i & 0xFF);
	mem_insert_ref(x + 1, (i >> 8) & 0xFF);
      }
      /* direct / relative 8bit with a definition */
      else if (l->status == LABEL_STATUS_DEFINE) {
示例#4
0
int discard_iteration(void) {

    struct reference *r;
    struct stackitem *si;
    struct section *s, *ss;
    struct label *l;
    struct stack *st;
    int i;


    /* check section names for special characters '!', and check if the section is of proper type */
    s = sec_first;
    while (s != NULL) {
        if (s->name[0] == '!' || !(s->status == SECTION_STATUS_FREE || s->status == SECTION_STATUS_SEMIFREE || s->status == SECTION_STATUS_SEMISUBFREE)) {
            s->referenced++;
            s->alive = YES;
        }
        s = s->next;
    }

    /* loop through references */
    r = reference_first;
    while (r != NULL) {
        /* references to local labels don't count */
        if (r->name[0] == '_' || is_label_anonymous(r->name) == SUCCEEDED) {
            r = r->next;
            continue;
        }
        s = NULL;
        if (r->section_status != 0) {
            s = sec_first;
            while (s != NULL) {
                if (s->id == r->section)
                    break;
                s = s->next;
            }
        }
        find_label(r->name, s, &l);

        if (l != NULL && l->section_status == ON) {
            s = l->section_struct;
            if (s == NULL)
                fprintf(stderr, "DISCARD_ITERATION: Internal error!\n");
            if (r->section_status == OFF)
                s->referenced++;
            else if (r->section != s->id) {
                ss = sec_first;
                while (ss->id != r->section)
                    ss = ss->next;
                if (ss->alive == YES)
                    s->referenced++;
            }
        }
        r = r->next;
    }

    /* loop through computations */
    st = stacks_first;
    while (st != NULL) {
        ss = NULL;
        if (st->section_status != 0) {
            ss = sec_first;
            while (ss != NULL) {
                if (ss->id == st->section)
                    break;
                ss = ss->next;
            }
        }

        si = st->stack;
        i = 0;
        while (i != st->stacksize) {
            if (si->type == STACK_ITEM_TYPE_STRING && is_label_anonymous(si->string) == FAILED) {
                find_label(si->string, ss, &l);

                if (l != NULL && l->section_struct != NULL) {
                    s = l->section_struct;
                    if (st->section_status == OFF)
                        s->referenced++;
                    else if (st->section != s->id) {
                        if (ss->alive == YES)
                            s->referenced++;
                    }
                }
            }
            si++;
            i++;
        }
        st = st->next;
    }


    return SUCCEEDED;
}