home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / asxsrc / lkarea.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-25  |  2.9 KB  |  181 lines

  1. /* lkarea.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "aslink.h"
  14.  
  15. /*
  16.  * Create an area entry.
  17.  *
  18.  * A xxxxxx size nnnn flags mm
  19.  *   |           |          |
  20.  *   |           |          `--  ap->a_flag
  21.  *   |           `------------- axp->a_size
  22.  *   `-------------------------  ap->a_id
  23.  *
  24.  */
  25. VOID
  26. newarea()
  27. {
  28.     register i, narea;
  29.     struct areax *taxp;
  30.     struct areax **halp;
  31.     char id[NCPS];
  32.  
  33.     /*
  34.      * Create Area entry
  35.      */
  36.     getid(id, -1);
  37.     lkparea(id);
  38.     /*
  39.      * Evaluate area size
  40.      */
  41.     skip(-1);
  42.     axp->a_size = eval();
  43.     /*
  44.      * Evaluate flags
  45.      */
  46.     skip(-1);
  47.     i = 0;
  48.     taxp = ap->a_axp;
  49.     while (taxp->a_axp) {
  50.         ++i;
  51.         taxp = taxp->a_axp;
  52.     }
  53.     if (i == 0) {
  54.         ap->a_flag = eval();
  55.     } else {
  56.         i = eval();
  57.         if (i && (ap->a_flag != i))
  58.             fprintf(stderr, "Conflicting flags in area %.8s\n", id);
  59.     }
  60.     /*
  61.      * Place pointer in header area list
  62.      */
  63.     if (headp == NULL) {
  64.         fprintf(stderr, "No header defined\n");
  65.         exit(1);
  66.     }
  67.     narea = hp->h_narea;
  68.     halp = (struct areax **) hp->a_list;
  69.     for (i=0; i < narea ;++i) {
  70.         if (halp[i] == NULL) {
  71.             halp[i] = taxp;
  72.             return;
  73.         }
  74.     }
  75.     fprintf(stderr, "Header area list overflow\n");
  76.     exit(1);
  77. }
  78.  
  79. /*
  80.  * Lookup the area `id'.
  81.  * If it is not found create it.
  82.  * Then append an area extension.
  83.  */
  84. VOID
  85. lkparea(id)
  86. char *id;
  87. {
  88.     register struct area *tap;
  89.     register struct areax *taxp;
  90.  
  91.     ap = areap;
  92.     axp = (struct areax *) new (sizeof(struct areax));
  93.     while (ap) {
  94.         if (symeq(id, ap->a_id)) {
  95.             taxp = ap->a_axp;
  96.             while (taxp->a_axp)
  97.                 taxp = taxp->a_axp;
  98.             taxp->a_axp = axp;
  99.             return;
  100.         }
  101.         ap = ap->a_ap;
  102.     }
  103.     ap = (struct area *) new (sizeof(struct area));
  104.     if (areap == NULL) {
  105.         areap = ap;
  106.     } else {
  107.         tap = areap;
  108.         while (tap->a_ap)
  109.             tap = tap->a_ap;
  110.         tap->a_ap = ap;
  111.     }
  112.     ap->a_axp = axp;
  113.     strncpy(ap->a_id, id, NCPS);
  114. }
  115.  
  116. /*
  117.  * Resolve all area addresses.
  118.  */
  119. VOID
  120. lnkarea()
  121. {
  122.     register rloc;
  123.  
  124.     rloc = 0;
  125.     ap = areap;
  126.     while (ap) {
  127.         if (ap->a_flag&A_ABS) {
  128.             /*
  129.              * Absolute sections
  130.              */
  131.             lnksect(ap);
  132.         } else {
  133.             /*
  134.              * Relocatable sections
  135.              */
  136.             if (ap->a_addr == 0)
  137.                 ap->a_addr = rloc;
  138.             lnksect(ap);
  139.             rloc = ap->a_addr + ap->a_size;
  140.         }
  141.         ap = ap->a_ap;
  142.     }
  143. }
  144.  
  145. /*
  146.  * Resolve section addresses within an area.
  147.  */
  148. VOID
  149. lnksect(tap)
  150. register struct area *tap;
  151. {
  152.     register addr_t size, addr;
  153.     register struct areax *taxp;
  154.  
  155.     size = 0;
  156.     addr = tap->a_addr;
  157.     taxp = tap->a_axp;
  158.     if (tap->a_flag&A_OVR) {
  159.         /*
  160.          * Overlayed sections
  161.          */
  162.         while (taxp) {
  163.             taxp->a_addr = addr;
  164.             if (taxp->a_size > size)
  165.                 size = taxp->a_size;
  166.             taxp = taxp->a_axp;
  167.         }
  168.     } else {
  169.         /*
  170.          * Concatenated sections
  171.          */
  172.         while (taxp) {
  173.             taxp->a_addr = addr;
  174.             addr += taxp->a_size;
  175.             size += taxp->a_size;
  176.             taxp = taxp->a_axp;
  177.         }
  178.     }
  179.     tap->a_size = size;
  180. }
  181.