work in progress
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 9 Feb 2002 18:37:56 +0000 (18:37 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 9 Feb 2002 18:37:56 +0000 (18:37 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1913 4a8a32a2-be11-0410-ad9d-d568d2c75423

as/xa51/xa_link.c
as/xa51/xa_main.c

index 8b1489d199230cfc0ed2cbe30acbaa8256b5e079..09185650b5bc7827f7a3d9c9a0b61baf1d4b374f 100644 (file)
 #include "xa_version.h"
 
 enum {
-  CSEG=0,
+  CSEG=1,
   DSEG,
   XSEG,
   BSEG,
+  XINIT,
+  XISEG,
+  GSINIT,
+  GSFINAL,
+  HOME,
   MAX_SEGMENTS
 };
 
@@ -58,10 +63,16 @@ struct SEGMENT {
   int start;
   int current;
 } segments[MAX_SEGMENTS]={
-  {CSEG, "CSEG", 0, 0},
-  {DSEG, "DSEG", 0, 0},
-  {XSEG, "XSEG", 0, 0},
-  {BSEG, "BSEG", 0, 0}
+  {0,       "????",    0, 0},
+  {CSEG,    "CSEG",    0, 0},
+  {DSEG,    "DSEG",    0, 0},
+  {XSEG,    "XSEG",    0, 0},
+  {BSEG,    "BSEG",    0, 0},
+  {XINIT,   "XINIT",   0, 0},
+  {XISEG,   "XISEG",   0, 0},
+  {GSINIT,  "GSINIT",  0, 0},
+  {GSFINAL, "GSFINAL", 0, 0},
+  {HOME,    "HOME",    0, 0},
 };
 
 char *libPaths[128];
@@ -71,6 +82,26 @@ int nlibFiles=0;
 
 static char outFileName[PATH_MAX];
 
+int currentArea=0;
+
+int getAreaID(char *area) {
+  int i;
+  for (i=1; i<MAX_SEGMENTS; i++) {
+    if (strcmp(segments[i].name, area)==0) {
+      return segments[i].id;
+    }
+  }
+  return 0;
+}
+
+void addToRefs(char *ref) {
+  fprintf (stderr, "Ref: %s\n", ref);
+}
+
+void addToDefs(char *def, int address) {
+  fprintf (stderr, "Def: %s 0x%04x\n", def, address);
+}
+
 void syntaxError (char *err) {
   fprintf (stderr, "error while parsing '%s'\n", err);
   exit(1);
@@ -107,6 +138,9 @@ void readModule(char *module) {
   double hisVersion;
   char line[132];
   FILE *relModule;
+  char moduleName[PATH_MAX];
+  int areas, globals;
+  int currentLine=1;
 
   if ((relModule=fopen(module, "r"))==NULL) {
     perror (module);
@@ -116,7 +150,7 @@ void readModule(char *module) {
 
   // first we need to check if this is a valid file
   if (sscanf(fgets(line, 132, relModule), 
-      "SDCCXA rel, version %lf", &hisVersion)!=1) {
+            "SDCCXA rel, version %lf", &hisVersion)!=1) {
     fprintf (stderr, "%s is not a valid input file\n", module);
     exit (1);
   }
@@ -125,9 +159,96 @@ void readModule(char *module) {
             "we(%1.1f) != %s(%1.1f)\n", 
             version, module, hisVersion);
   }
+  currentLine++;
+  
+  // H 7 areas 168 global symbols
+  if (sscanf(fgets(line, 132, relModule),
+            "H %d areas %d global symbols",
+            &areas, &globals)!=2) {
+    syntaxError(line);
+  }
+  currentLine++;
 
-  // 
-  fprintf (stderr, "Wow! This seems a nice module: v %1.1f.\n", hisVersion);
+  // M module
+  if (sscanf(fgets(line, 132, relModule),
+            "M %s", moduleName)!=1) {
+    syntaxError(line);
+  }
+  fprintf (stderr, "module %s has %d area%s and %d globals\n",
+          moduleName, areas, areas==1?"":"s", globals);
+  currentLine++;
+
+  // now for the ASTR tags
+  while (fgets(line, 132, relModule)) {
+    switch (line[0]) 
+      {
+      case 'A': {
+       char area[32];
+       int size, flags;
+       if (sscanf(line, "A %[^ ] size %d flags %d",
+                  area, &size, &flags)!=3) {
+         fprintf (stderr, "%s:%d error in A record line\n", module, 
+                  currentLine);
+         exit (1);
+       }
+       // do we know this area?
+       if (!(currentArea=getAreaID(area))) {
+         fprintf (stderr, "%s:%d unknown area: %s\n", module,
+                  currentLine, area);
+         exit (1);
+       }
+       fprintf (stderr, "Area: %s size: %d\n", area, size);
+       // never mind about the size and flags for now
+       break;
+      }
+      case 'S': {
+       char symbol[132];
+       char refdef[132];
+       unsigned int address;
+       if (sscanf(line, "S %[^ ] %s", symbol, refdef)!=2) {
+         fprintf (stderr, "%s:%d syntax error near \"%s\"\n",
+                  module, currentLine, line);
+         exit (1);
+       }
+       if (strncmp(refdef, "Ref", 3)==0) {
+         addToRefs(symbol);
+       } else if (strncmp(refdef, "Def", 3)==0) {
+         sscanf (refdef, "Def%04x", &address);
+         addToDefs(symbol, address);
+       } else {
+         fprintf (stderr, "%s:%d found invalid symbol definition \"%s\"\n", 
+                  module, currentLine, line);
+         exit (1);
+       }
+       break;
+      }
+      case 'T': {
+       unsigned int address;
+       unsigned int byte;
+       char *tline=NULL;
+       if (sscanf(strtok(&line[2], " "), "%04x", &address)!=1) {
+         fprintf (stderr, "%s:%d error in T record\n", module, currentLine);
+         exit (1);
+       }
+       fprintf (stderr, "%04x:", address);
+       for ( ;
+             (tline=strtok(NULL, " \t\n")) && 
+               (sscanf(tline, "%02x", &byte)==1);
+             fprintf (stderr, " %02x", byte))
+         ; // how about that one, hey?
+       fprintf (stderr, "\n");
+       break;
+      }
+      case 'R':
+       fprintf (stderr, "%s", line);
+       break;
+      default:
+       fprintf (stderr, "%s:%d unknown record \"%s\"\n",
+                module, currentLine, line);
+       break;
+      }
+    currentLine++;
+  }
   // that's all for now, thanks for watching */
   fclose (relModule);
 }
@@ -192,6 +313,8 @@ int main(int argc, char **argv) {
                           &segments[s].start)!=1) {
                  syntaxError(linkCommand);
                }
+               fprintf (stderr, "%s starts at 0x%04x\n", segments[s].name,
+                        segments[s].start);
                break;
              }
            }
index fea9d6ecfd0e886c214d0e5b49e33f43486b6ed7..9f8c9dcb709903cddfb2f68687a029f36f671c9e 100644 (file)
@@ -382,17 +382,20 @@ void out(int *byte_list, int num) {
   
   if (last_area!=current_area) {
     // emit area information
-    fprintf (frel, "A %s size %d flags 0\n", 
-            areaToString(current_area),
-            area[current_area].size);
-    area[current_area].defsEmitted=1;
-    if  (!area[current_area].defsEmitted) {
-      for (p=sym_list; p; p=p->next) {
-       if (p->isdef && p->area==current_area) {
-         if (debug || p->name[strlen(p->name)-1]!='$') {
-           fprintf (frel, "S %s Def%04x\n", p->name, p->value);
+    if (area[current_area].size) {
+      fprintf (frel, "A %s size %d flags 0\n", 
+              areaToString(current_area),
+              area[current_area].size);
+      if  (!area[current_area].defsEmitted) {
+       for (p=sym_list; p; p=p->next) {
+         if (p->isdef && p->area==current_area) {
+           // skip temp labels
+           if (p->name[strlen(p->name)-1]!='$') {
+             fprintf (frel, "S %s Def%04x\n", p->name, p->value);
+           }
          }
        }
+       area[current_area].defsEmitted=1;
       }
     }
     last_area=current_area;
@@ -401,7 +404,7 @@ void out(int *byte_list, int num) {
       current_area==AREA_GSFINAL ||
       current_area==AREA_XINIT) {
     if (num) {
-      fprintf (frel, "T %02x %02x", (MEM_POS>>16)&0xff, MEM_POS&0xff);
+      fprintf (frel, "T %04x", MEM_POS);
       for (i=0; i<num; i++) {
        fprintf (frel, " %02x", byte_list[i]);
       }
@@ -497,13 +500,6 @@ int binary2int(char *str)
 
 void print_usage(int);
 
-
-/* todo: someday this will allow the user to control where the */
-/* various memory areas go, and it will take care of assigning */
-/* positions to area which follow others (such as OSEG getting */
-/* set just after DSEG on the 2nd and 3rd passes when we have */
-/* leared the size needed for each segment */
-
 void init_areas(void)
 {
   area[AREA_CSEG].start=area[AREA_CSEG].alloc_position = 0;
@@ -527,17 +523,12 @@ void relPrelude() {
     if ((area[i].size=area[i].alloc_position-area[i].start)) {
       areas++;
     }
-#if 0
-    current_area=i;
-    sprintf (buffer, "s_%s", areaToString(i));
-    build_sym_list (buffer);
-    buffer[0]='l';
-    build_sym_list (buffer);
-#endif
   }
   for (p=sym_list; p; p=p->next) {
     if (p->isdef) {
-      if (debug || p->name[strlen(p->name)-1]!='$') {
+      // skip temp labels, sfr and sbit
+      if (p->name[strlen(p->name)-1]!='$' &&
+         p->area) {
        globals++;
       }
     }