*** empty log message ***
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 12 Feb 2002 16:34:36 +0000 (16:34 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 12 Feb 2002 16:34:36 +0000 (16:34 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1921 4a8a32a2-be11-0410-ad9d-d568d2c75423

as/xa51/Makefile
as/xa51/xa_link.c
as/xa51/xa_main.c
as/xa51/xa_main.h
as/xa51/xa_rasm.y
device/examples/xa51/hello.c
device/examples/xa51/hwinit.c
src/xa51/gen.c
src/xa51/main.c
support/regression/ports/xa51/spec.mk

index dcd797fe95de36603ea8522f7b549b813bfc9b64..46d788342fdfc63b1dcf0881204a7749ac45a317 100644 (file)
@@ -1,5 +1,5 @@
 CC = gcc
-CFLAGS = -ggdb -O2 -Wall
+CFLAGS = -ggdb -Wall
 YACC = bison -y -d
 LEX = flex -i
 LEXLIB = 
index 7c376f156bd35e9e3b64abaadf6e7984e88bce2c..3284925ddac7e783847d058ac2c2de9e6380bdff 100644 (file)
 
    "SDCCXA rel, version %f" must be the first line, sort of MAGIC word
    "H %d areas %d global symbols" defines the # of areas and globals
-   "S <symbol> [Ref0000 | DefXXXX]" Def's are supposed to be defined in
-     their own area/segment
+   "S <symbol> [Ref0000 | DefXXXX | AbsXXXX]" Def's are supposed to be
+     defined in their own area/segment
    "A <seg> size %d flags %d" switch to another segment. this can happen
      multiple times and should be equal. flags is ignored for now
-   "T xx xx bb bb ..." where xx xx is the address within the current segment
-     and bb are the bytes
-   "R xx <how> <symbol>" the relocation info. xx is the offset within the
-     previous "T .." line. <how> could be something like REL_FF, REL_FFFF, 
-     ABS_F0FF. symbol is the (previous) defined symbol it refers to
+   "T xxxx <how> <symbol> 0"
+   "R xxxx <how> <symbol> <pc+>" the relocation info. xxxx is the address
+     within relative code space. How is something like REL_FF, REL_FFFF, 
+     ABS_F0FF. Symbol is the referenced symbol and pc+ is the program 
+     counter that will be used to calculate the relative address (that is
+     the address of the following instruction).
 
    So, this is not a standalone linker. It will only link files generated
    by xa_asm, which will only process files generated by the xa51 sdcc
@@ -59,11 +60,40 @@ enum {
   MAX_SEGMENTS
 };
 
+enum {
+  REL_FF=1,
+  REL_FFFF,
+  ABS_0F,
+  ABS_FF,
+  ABS_03FF,
+  ABS_07FF,
+  ABS_F0FF,
+  ABS_FFFF,
+  ABS_0F00FF,
+  MAX_REFS
+};
+
+char *refModes[]={
+  "???",
+  "REL_FF",
+  "REL_FFFF",
+  "ABS_0F",
+  "ABS_FF",
+  "ABS_03FF",
+  "ABS_07FF",
+  "ABS_F0FF",
+  "ABS_FFFF",
+  "ABS_0F00FF",
+};
+
 #define CODESIZE 0x10000
 
-char codeImage[CODESIZE];
+int fatalErrors=0;
+
 char gsinitImage[CODESIZE];
+char csegImage[CODESIZE];
 char xinitImage[CODESIZE];
+//char gsfinalImage[CODESIZE];
 
 struct SEGMENT {
   short id;
@@ -74,10 +104,10 @@ struct SEGMENT {
   int current;
   unsigned char *image;
 } segments[MAX_SEGMENTS]={
-  {0,       "????",    0, 0, 0, 0, NULL},
+  {0,       "???",    0, 0, 0, 0, NULL},
 
   {GSINIT,  "GSINIT",  0, 0, 0, 0, gsinitImage},
-  {CSEG,    "CSEG",    0, 0, 0, 0, codeImage},
+  {CSEG,    "CSEG",    0, 0, 0, 0, csegImage},
   {XINIT,   "XINIT",   0, 0, 0, 0, xinitImage},
   //{GSFINAL, "GSFINAL", 0, 0, 0, 0, NULL},
 
@@ -99,27 +129,60 @@ struct MODULE {
 struct SYMBOL {
   char *name;
   struct MODULE *module;
+  int lineno;
   struct SEGMENT *segment;
+  char absolute;
   int address;
   struct SYMBOL *next;
   struct SYMBOL *last;
 } *symbols=NULL;
 
+struct REFERENCE {
+  char *name;
+  struct MODULE *module;
+  int lineno;
+  unsigned address, pc;
+  short how;
+  struct REFERENCE *next;
+  struct REFERENCE *last;
+} *references=NULL;
+
 char *libPaths[128];
 int nlibPaths=0;
 char *libFiles[128];
 int nlibFiles=0;
 
-static char outFileName[PATH_MAX];
+static char outFileName[PATH_MAX]={'\0'};
 
 struct SEGMENT *currentSegment;
 struct MODULE *currentModule;
+int currentLine;
+
+int howToReference(char *how) {
+  int r;
+  for (r=1; r<MAX_REFS; r++) {
+    if (strcmp(refModes[r], how)==0) {
+      return r;
+    }
+  }
+  return 0;
+}
 
-struct SEGMENT *findSegment(char *segment) {
-  int i;
-  for (i=1; i<MAX_SEGMENTS; i++) {
-    if (strcmp(segments[i].name, segment)==0) {
-      return &segments[i];
+struct SEGMENT *findSegmentByName(char *segment) {
+  int s;
+  for (s=0; s<MAX_SEGMENTS; s++) {
+    if (strcmp(segments[s].name, segment)==0) {
+      return &segments[s];
+    }
+  }
+  return 0;
+}
+
+struct SYMBOL *findSymbolByName(char *symName) {
+  struct SYMBOL *symbol;
+  for (symbol=symbols; symbol; symbol=symbol->next) {
+    if (strcmp(symbol->name, symName)==0) {
+      return symbol;
     }
   }
   return 0;
@@ -144,20 +207,49 @@ void addToModules (char *name) {
   currentModule=modules->last=module;
 }
 
-void addToRefs(char *ref) {
+void addToRefs(char *ref, int address, char *how, int pc) {
+  struct REFERENCE *reference;
+
   //fprintf (stderr, "addToRefs: %s\n", ref);
+
+  reference=calloc(1, sizeof(struct REFERENCE));
+  reference->name=strdup(ref);
+  reference->module=currentModule;
+  reference->lineno=currentLine;
+  reference->address=address;
+  reference->how=howToReference(how);
+  reference->pc=pc;
+  if (!references) {
+    references=reference;
+  } else {
+    references->last->next=reference;
+  }
+  references->last=reference;
 }
 
-void addToDefs(char *def, int address) {
+void addToDefs(char *def, int address, char absolute) {
   struct SYMBOL *symbol;
+
   /* fprintf (stderr, "addToDefs: %s %s 0x%04x + 0x%04x\n", 
      currentSegment->name, def, 
      currentModule->offset[currentSegment->id],
      address); */
+
+  // no duplicates allowed
+  if ((symbol=findSymbolByName(def))) {
+    fprintf (stderr, "*** %s:%d duplicate symbol %s first defined in "
+            "module %s:%d\n", 
+            currentModule->name, currentLine, def, 
+            symbol->module->name, symbol->lineno);
+    fatalErrors++;
+  }
+
   symbol=calloc(1, sizeof(struct SYMBOL));
   symbol->name=strdup(def);
   symbol->module=currentModule;
+  symbol->lineno=currentLine;
   symbol->segment=currentSegment;
+  symbol->absolute=absolute;
   symbol->address=currentModule->offset[currentSegment->id]+address;
   if (!symbols) {
     symbols=symbol;
@@ -169,7 +261,8 @@ void addToDefs(char *def, int address) {
 }
 
 void syntaxError (char *err) {
-  fprintf (stderr, "error while parsing '%s'\n", err);
+  fprintf (stderr, "*** %s:%d error while parsing '%s'\n", 
+          currentModule->name, currentLine, err);
   exit(1);
 }
 
@@ -206,7 +299,8 @@ void readModule(char *module) {
   FILE *relModule;
   char moduleName[PATH_MAX];
   int segments, globals;
-  int currentLine=1;
+
+  currentLine=1;
 
   if ((relModule=fopen(module, "r"))==NULL) {
     perror (module);
@@ -218,11 +312,11 @@ 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) {
-    fprintf (stderr, "%s is not a valid input file\n", module);
+    fprintf (stderr, "*** %s is not a valid input file\n", module);
     exit (1);
   }
   if (hisVersion!=version) {
-    fprintf (stderr, "WARNING: version conflict; "
+    fprintf (stderr, "*** WARNING: version conflict; "
             "we(%1.1f) != %s(%1.1f)\n", 
             version, module, hisVersion);
   }
@@ -258,23 +352,23 @@ void readModule(char *module) {
        int size, flags;
        if (sscanf(line, "A %[^ ] size %d flags %d",
                   segment, &size, &flags)!=3) {
-         fprintf (stderr, "%s:%d error in A record line\n", 
-                  module, currentLine);
-         exit (1);
+         syntaxError(line);
        }
        // do we know this segment?
-       if (!(currentSegment=findSegment(segment))) {
-         fprintf (stderr, "%s:%d unknown area: %s\n", module,
+       if (!(currentSegment=findSegmentByName(segment))) {
+         fprintf (stderr, "*** %s:%d unknown area: %s\n", module,
                   currentLine, segment);
          exit (1);
        }
        if (currentModule->size[currentSegment->id]) {
          if (currentModule->size[currentSegment->id] != size) {
-           fprintf (stderr, "%s:%d error %s %d %d\n",
+           fprintf (stderr, "*** %s:%d error %s size %d != %d\n",
                     module, currentLine,
                     currentSegment->name,
                     currentModule->size[currentSegment->id], 
                     size);
+         } else {
+           // pleased to meet you again
          }
        } else {
          currentModule->size[currentSegment->id]=size;
@@ -290,15 +384,18 @@ void readModule(char *module) {
        char refdef[132];
        unsigned int address;
        if (sscanf(line, "S %[^ ] %s", symbol, refdef)!=2) {
-         fprintf (stderr, "%s:%d syntax error near \"%s\"\n",
+         fprintf (stderr, "*** %s:%d syntax error near \"%s\"\n",
                   module, currentLine, line);
          exit (1);
        }
        if (strncmp(refdef, "Ref", 3)==0) {
-         addToRefs(symbol);
+         // we don't need them
        } else if (strncmp(refdef, "Def", 3)==0) {
          sscanf (refdef, "Def%04x", &address);
-         addToDefs(symbol, address);
+         addToDefs(symbol, address, 0);
+       } else if (strncmp(refdef, "Abs", 3)==0) {
+         sscanf (refdef, "Abs%04x", &address);
+         addToDefs(symbol, address, 1);
        } else {
          fprintf (stderr, "%s:%d found invalid symbol definition \"%s\"\n", 
                   module, currentLine, line);
@@ -335,12 +432,19 @@ void readModule(char *module) {
        //fprintf (stderr, "\n");
        break;
       }
-      case 'R':
+      case 'R': {
+       unsigned address, from;
+       char symbol[132];
+       char how[32];
        //fprintf (stderr, "%s", line);
+       sscanf (line, "R %x %[^ ] %[^ ] %x", &address, how, symbol, &from);
+       addToRefs (symbol, address, how, from);
        break;
+      }
       default:
-       /* fprintf (stderr, "%s:%d unknown record \"%s\"\n",
-          module, currentLine, line); */
+       fprintf (stderr, "%s:%d unknown record \"%s\"\n",
+                module, currentLine, line);
+       fatalErrors++;
        break;
       }
     currentLine++;
@@ -349,32 +453,108 @@ void readModule(char *module) {
   fclose (relModule);
 }
 
-void writeModule() {
+void writeModule(char *outFileName) {
+  FILE *fOut;
+
   fprintf (stderr, "WriteModule: %s\n", outFileName);
+  if ((fOut=fopen(outFileName, "w"))==NULL) {
+    perror (outFileName);
+  }
   // oops, forgot something :) */
+  fclose (fOut);
 }
 
 void relocate() {
   struct SYMBOL *symbol;
+  struct REFERENCE *reference;
+  char *from, *to;
   int length=segments[GSINIT].current +
     segments[CSEG].current +
     segments[XINIT].current;
 
+  //fprintf (stderr, "relocate: total code size: 0x%04x\n", length);
+
   // first check if it will fit
   if (length > 0xffff) {
     fprintf (stderr, "error: code segment exceeds 0xffff\n");
-    exit(1);
+    fatalErrors++;
   }
-  fprintf (stderr, "relocate: total code size: 0x%04x\n", length);
 
   // GSINIT gets the --code-loc
   segments[GSINIT].start=segments[CSEG].start;
   segments[CSEG].start=segments[GSINIT].start+segments[GSINIT]._size;
+  // concat cseg to gsinit
+  from=csegImage;
+  to=&gsinitImage[segments[GSINIT].start+segments[GSINIT]._size];
+  memcpy(to, from, segments[CSEG]._size);
   segments[XINIT].start=segments[CSEG].start+segments[CSEG]._size;
+  from=xinitImage;
+  to+=segments[CSEG]._size;
+  memcpy(to, from, segments[XINIT]._size);
+#if 0
+  from=gsfinalImage;
+  to+=segments[XINIT]._size;
+  memcpy(to, from, segments[GSFINAL]._size);
+#endif
   segments[XISEG].start=segments[XSEG].start+segments[XINIT]._size;  
   // now relocate the defined symbols
   for (symbol=symbols; symbol; symbol=symbol->next) {
-    symbol->address += symbol->segment->start;
+    if (!symbol->absolute) {
+      symbol->address += symbol->segment->start;
+    }
+  }
+  // add the segment symbols
+  currentSegment=findSegmentByName("XINIT");
+  addToDefs("s_XINIT", segments[XINIT].start, 0);
+  addToDefs("l_XINIT", segments[XINIT]._size, 0);
+  currentSegment=findSegmentByName("XISEG");
+  addToDefs("s_XISEG", segments[XISEG].start, 0);
+  addToDefs("l_XISEG", segments[XISEG]._size, 0);
+  // and the references
+  for (reference=references; reference; reference=reference->next) {
+    if (!(symbol=findSymbolByName(reference->name))) {
+      fprintf (stderr, "*** %s:%d undefined symbol %s\n",
+              reference->module->name, reference->lineno,
+              reference->name);
+    } else {
+      reference->address += symbol->segment->start;
+      switch (reference->how) 
+       {
+       case REL_FFFF: {
+         int rel16 = symbol->address-reference->pc;
+         if (rel16<-65536 || rel16>65534) {
+           fprintf (stderr, 
+                    "rel16 target for %s is out of range in module %s\n",
+                    reference->name, reference->module->name);
+           fatalErrors++;
+         }
+         gsinitImage[reference->address+1]=(rel16/2)>>8;
+         gsinitImage[reference->address]=rel16/2;
+         break;
+       }
+       case REL_FF: {
+         int rel8 = symbol->address-reference->pc;
+         if (rel8<-256 || rel8>256) {
+           fprintf (stderr,
+                    "rel8 target for %s is out of range in module %s\n",
+                    reference->name, reference->module->name);
+           fatalErrors++;
+         }
+         gsinitImage[reference->address]=rel8/2;
+         break;
+       }
+       case ABS_FFFF:
+         gsinitImage[reference->address+1] = symbol->address>>8;
+         // fall through
+       case ABS_FF:
+         gsinitImage[reference->address] = symbol->address;
+         break;
+       default:
+         fprintf (stderr, "unsupported reference mode %d.\n",
+                  reference->how);
+         fatalErrors++;
+       }
+    }
   }
 }
 
@@ -397,8 +577,6 @@ int main(int argc, char **argv) {
     usage(argv[0], 1);
   }
 
-  memset(codeImage, 0xff, CODESIZE);
-
   // read in the commands
   sprintf (linkCommandsPath, "%s.lnk", argv[1]);
   if (!(linkCommandsFile=fopen(linkCommandsPath, "r"))) {
@@ -459,6 +637,12 @@ int main(int argc, char **argv) {
     } else {
       // not a switch, must be an inputfile; one/line
       readModule(linkCommand);
+      // the first one defines the output name
+      if (!outFileName[0]) {
+       strncpy(outFileName, linkCommand,
+               strlen(linkCommand)-4);
+       strcat(outFileName, ".hex");
+      }
     }
   }
 
@@ -478,7 +662,9 @@ int main(int argc, char **argv) {
 
   // the symbols
   for (symbol=symbols; symbol; symbol=symbol->next) {
-    fprintf (stderr, "%s %s 0x%04x %s\n", symbol->name, symbol->segment->name,
+    fprintf (stderr, "%s %s %s0x%04x %s\n", symbol->name, 
+            symbol->segment->name,
+            symbol->absolute ? "= " : "",
             symbol->address, symbol->module->name);
   }
 
@@ -492,7 +678,7 @@ int main(int argc, char **argv) {
     }
   }
 
-  writeModule();
-  return 0;
+  writeModule(outFileName);
+  return fatalErrors? 1 : 0;
 }
 
index 04ab0e773ffc1374576574da1b431b8f60f6fe33..ca06f4cf6e93938b965b6943ee8fcae74173bbbf 100644 (file)
@@ -200,19 +200,36 @@ int mk_reg(char *thename)
         exit(1);
 }
 
-
+int mk_global(char *thename)
+{
+  struct symbol *p;
+  
+  p = sym_list;
+  while (p != NULL) {
+    if (!(strcasecmp(thename, p->name))) {
+      p->global = 1;
+      return (0);
+    }
+    p = p->next;
+  }
+  fprintf(stderr, "Internal Error!  Couldn't find symbol\n");
+  exit(1);
+}
 
 int get_value(char *thename)
 {
-       struct symbol *p;
-       p = sym_list;
-       while (p != NULL) {
-               if (!(strcasecmp(thename, p->name)))
-                       return (p->value);
-               p = p->next;
-       }
-       fprintf(stderr, "Internal Error!  Couldn't find symbol value\n");
-       exit(1);
+  struct symbol *p;
+  p = sym_list;
+  while (p != NULL) {
+    if (!(strcasecmp(thename, p->name))) {
+      if (p->mode=='=')
+       return 0;
+      return (p->value);
+    }
+    p = p->next;
+  }
+  fprintf(stderr, "Internal Error!  Couldn't find symbol value\n");
+  exit(1);
 }
                
 
@@ -269,6 +286,8 @@ void print_symbol_table()
       fprintf (sym_fp, "%-5s", "SFR");
     } else if (p->isbit && !p->area) {
       fprintf (sym_fp, "%-5s", "SBIT");
+    } else if (p->mode=='=') {
+      fprintf (sym_fp,"ABS");
     } else if (!p->isdef) {
       fprintf (sym_fp,"EXTRN");
     } else {
@@ -388,10 +407,14 @@ void out(int *byte_list, int num) {
               area[current_area].size);
       if  (!area[current_area].defsEmitted) {
        for (p=sym_list; p; p=p->next) {
-         if (p->isdef && p->area==current_area) {
+         if (p->global && 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);
+             if (p->mode=='=') {
+               fprintf (frel, "S %s Abs%04x\n", p->name, p->value);
+             } else {
+               fprintf (frel, "S %s Def%04x\n", p->name, p->value);
+             }
            }
          }
        }
@@ -405,8 +428,10 @@ void out(int *byte_list, int num) {
       current_area==AREA_GSFINAL ||
       current_area==AREA_XINIT) {
     if (num) {
-      fprintf (frel, "T %04x", MEM_POS);
       for (i=0; i<num; i++) {
+       if ((i%16)==0) {
+         fprintf (frel, "%sT %04x", i ? "\n" : "", MEM_POS);
+       }
        fprintf (frel, " %02x", byte_list[i]);
       }
       fprintf (frel, "\n");
@@ -520,7 +545,7 @@ void relPrelude() {
   struct symbol *p;
 
   fprintf (frel, "SDCCXA rel, version %1.1f\n", version);
-  for (i=0; i<NUM_AREAS; i++) {
+  for (i=1; i<NUM_AREAS; i++) {
     if ((area[i].size=area[i].alloc_position-area[i].start)) {
       areas++;
     }
@@ -588,13 +613,13 @@ void process_args(int argc, char **argv)
 
   strcpy(infilename, argv[i]);
 
-  if (strncasecmp(infilename+strlen(infilename)-3, ".xa", 3)) {
+  if (strncasecmp(infilename+strlen(infilename)-4, ".asm", 3)) {
     fprintf (stderr, "unrecognized input file: \"%s\"\n", argv[i]);
     print_usage(1);
   }
 
   strcpy(modulename, infilename);
-  modulename[strlen(modulename)-3] = '\0';
+  modulename[strlen(modulename)-4] = '\0';
   sprintf (outfilename, "%s.rel", modulename);
   sprintf (listfilename, "%s.lst", modulename);
   if (createSymbolFile) {
index d95f57a20e7a83c6c3319b2dde93cfb1aab80c4e..a5c0dfcb6f20a33208ab11f1ab8eab69b49befe7 100644 (file)
@@ -34,6 +34,7 @@ struct symbol {
         int isbit;      /* 1 if a bit address, 0 otherwise */
         int issfr;
        int isreg;      /* 1 if a register, 0 otehrwise */
+        int global ;    /* is defined as global */
         char mode;      /* Absolute, Relative, Tmplabel, eXternal */
         short lk_index; /* symbol index for the linker */
         int area;       /* the area that this symbol is in */
@@ -99,6 +100,7 @@ extern char expr_var[2][MAX_SYMBOL];
 extern void error(char*);
 int mk_bit(char*, int);
 int mk_sfr(char*);
+int mk_global(char*);
 struct target * build_target_list(char *thename);
 struct symbol * build_sym_list(char *);
 int find_size_reg(int op1spec);
index 03ade71f0bf801ed2dc19bbb471d494a15371a6b..20d6da99dbc26bf95caccc4c35f06421b0802db9 100755 (executable)
@@ -43,99 +43,95 @@ extern char * disasm(int byte, int memory_location);
 void error(char *s);
 
 
-void RELOC_FF(unsigned pc, unsigned short offset, short rl) {
+void RELOC_FF(unsigned where, unsigned pc, short rl) {
+  // pc = PC of the next instruction
   struct symbol *sym;
   if ((sym=findSymbol(yytext))) {
     if (sym->mode=='X') {
-      sprintf (rel_line[rl], "R %d REL_FF 0x%04x %s", offset, pc,
-              sym->name);
+      sprintf (rel_line[rl], "R %04x REL_FF %s %04x", 
+              where, sym->name, pc);
     }
   }
 }
  
-void RELOC_FFFF(unsigned pc, unsigned short offset, short rl) {
+void RELOC_FFFF(unsigned where, unsigned pc, short rl) {
   struct symbol *sym;
   if ((sym=findSymbol(yytext))) {
     if (sym->mode=='X') {
-      sprintf (rel_line[rl], "R %d REL_FFFF 0x%04x %s", offset, pc,
-              sym->name);
+      sprintf (rel_line[rl], "R %04x REL_FFFF %s %04x", 
+              where, sym->name, pc);
     }
   }
 }
  
-void RELOC_ABS_0F(unsigned short offset, int expr) {
+void RELOC_ABS_0F(unsigned where, int expr) {
   struct symbol *sym;
   if ((sym=findSymbol(expr_var[expr]))) {
     if (sym->mode=='X') {
-      sprintf (rel_line[expr], "R %d ABS_0F %s", offset, sym->name);
+      sprintf (rel_line[expr], "R %04x ABS_0F %s 0", where, sym->name);
     }
   }
 }
 
-void RELOC_ABS_FF(unsigned short offset, int expr) {
+void RELOC_ABS_FF(unsigned where, int expr) {
   struct symbol *sym;
   if ((sym=findSymbol(expr_var[expr]))) {
     if (sym->mode=='X') {
-      sprintf (rel_line[expr], "R %d ABS_FF %s", offset, sym->name);
+      sprintf (rel_line[expr], "R %04x ABS_FF %s 0", where, sym->name);
     }
   }
 }
 
-void RELOC_ABS_03FF(unsigned short offset, int expr) {
+void RELOC_ABS_03FF(unsigned where, int expr) {
   struct symbol *sym;
   if (expr_var[0]) {
     if ((sym=findSymbol(expr_var[expr]))) {
       if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_03FF %s", offset, sym->name);
+       sprintf (rel_line[expr], "R %04x ABS_03FF %s 0", where, sym->name);
       }
     }
   }
 }
 
-void RELOC_ABS_07ff(unsigned short offset, int expr) {
+void RELOC_ABS_07ff(unsigned where, int expr) {
   struct symbol *sym;
   if (expr_var[0]) {
     if ((sym=findSymbol(expr_var[expr]))) {
       if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_07ff %s", offset, sym->name);
+       sprintf (rel_line[expr], "R %04x ABS_07ff %s 0", where, sym->name);
       }
     }
   }
 }
 
-void RELOC_ABS_F0FF(unsigned short offset, int expr) {
+void RELOC_ABS_F0FF(unsigned where, int expr) {
   struct symbol *sym;
   if (expr_var[0]) {
     if ((sym=findSymbol(expr_var[expr]))) {
       if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_F0FF %s", offset, sym->name);
+       sprintf (rel_line[expr], "R %04x ABS_F0FF %s", where, sym->name);
       }
     }
   }
 }
  
-void RELOC_ABS_FFFF(unsigned short offset, int expr) {
+void RELOC_ABS_FFFF(unsigned where, int expr) {
   struct symbol *sym;
   if (expr_var[0]) {
     if ((sym=findSymbol(expr_var[expr]))) {
       if (sym->mode=='X') {
-#if 1
-       sprintf (rel_line[expr], "R %d ABS_FFFF %s", offset, sym->name);
-#else
-       sprintf (rel_line[expr], "R 0 0 00 %02x 02 %02x %02x", current_area, 
-                (sym->lk_index>>8)&0xff, sym->lk_index&&0xff);
-#endif
+       sprintf (rel_line[expr], "R %04x ABS_FFFF %s 0", where, sym->name);
       }
     }
   }
 }
  
-void RELOC_ABS_0F00FF(unsigned short offset, int expr) {
+void RELOC_ABS_0F00FF(unsigned where, int expr) {
   struct symbol *sym;
   if (expr_var[0]) {
     if ((sym=findSymbol(expr_var[expr]))) {
       if (sym->mode=='X') {
-       sprintf (rel_line[expr], "R %d ABS_0F00FF %s", offset, sym->name);
+       sprintf (rel_line[expr], "R %04x ABS_0F00FF %s", where, sym->name);
       }
     }
   }
@@ -209,9 +205,9 @@ directive:     '.' ORG expr {
                        if (p1 || p2) assign_value(symbol_name, $5, '?');
                        $$ = 0;
                }
-             | normal_or_bit_symbol '=' expr {
+             | symbol '=' expr {
                        if (p1) build_sym_list(symbol_name);
-                       if (p1 || p2) assign_value(symbol_name, $3, '?');
+                       if (p1 || p2) assign_value(symbol_name, $3, '=');
                }
             | symbol SFR expr {
                        if (p1) build_sym_list(symbol_name);
@@ -279,12 +275,13 @@ directive:     '.' ORG expr {
                        $$ = 0;
                }
             | '.' GLOBL WORD {
+                       mk_global(lex_sym_name);
                        /* ignore global symbol declaration */
                        $$ = 0;
                }
             | '.' GLOBL bit {
                        /* ignore bit symbol declaration */
-                       $$ = 0;
+                       $$ = 0;
                }
             | '.' DS expr {
                        /* todo: if CSEG, emit some filler bytes */
@@ -465,14 +462,14 @@ instruction:
                op[0] = arith_opcode * 16 + size * 8 + 4;
                op[1] = reg($2) * 16 + reg_indirect($5);
                op[2] = ($7 >= 0) ? $7 : 256 + $7;
-               RELOC_ABS_FF(2,0);
+               RELOC_ABS_FF(MEM_POS+2,0);
        } else {
                $$ = 4;
                op[0] = arith_opcode * 16 + size * 8 + 5;
                op[1] = reg($2) * 16 + reg_indirect($5);
                op[2] = ($7 >= 0) ? msb($7) : msb(65536 + $7);
                op[3] = ($7 >= 0) ? lsb($7) : lsb(65536 + $7);
-               RELOC_ABS_FFFF(2,0);
+               RELOC_ABS_FFFF(MEM_POS+2,0);
        }
   }
 | arith_inst '[' REG '+' expr ']' ',' REG {
@@ -482,14 +479,14 @@ instruction:
                op[0] = arith_opcode * 16 + size * 8 + 4;
                op[1] = reg($8) * 16 + 8 + reg_indirect($3);
                op[2] = ($5 >= 0) ? $5 : 256 + $5;
-               RELOC_ABS_FF(2,0);
+               RELOC_ABS_FF(MEM_POS+2,0);
        } else {
                $$ = 4;
                op[0] = arith_opcode * 16 + size * 8 + 5;
                op[1] = reg($8) * 16 + 8 + reg_indirect($3);
                op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
                op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
-               RELOC_ABS_FFFF(2,0);
+               RELOC_ABS_FFFF(MEM_POS+2,0);
        }
   }
 | arith_inst REG ',' '[' REG '+' ']' {
@@ -510,7 +507,7 @@ instruction:
        op[0] = arith_opcode * 16 + size * 8 + 6;
        op[1] = reg($4) * 16 + 8 + msb(direct_addr($2));
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
   }
 | arith_inst REG ',' WORD {
        $$ = 3;
@@ -518,7 +515,7 @@ instruction:
        op[0] = arith_opcode * 16 + size * 8 + 6;
        op[1] = reg($2) * 16 + msb(direct_addr($4));
        op[2] = lsb(direct_addr($4));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
   }
 | arith_inst REG ',' '#' expr {
        size = find_size1(inst_size, $2);
@@ -527,14 +524,14 @@ instruction:
                op[0] = 0x91;
                op[1] = reg($2) * 16 + arith_opcode;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0x99;
                op[1] = reg($2) * 16 + arith_opcode;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF (2, 0);
+               RELOC_ABS_FFFF (MEM_POS+2, 0);
        }
   }
 | arith_inst '[' REG ']' ',' '#' expr {
@@ -544,14 +541,14 @@ instruction:
                op[0] = 0x92;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = imm_data8($7);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0x9A;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = msb(imm_data16($7));
                op[3] = lsb(imm_data16($7));
-               RELOC_ABS_FFFF (2, 0);
+               RELOC_ABS_FFFF (MEM_POS+2, 0);
        }
   }
 | arith_inst '[' REG '+' ']' ',' '#' expr {
@@ -561,14 +558,14 @@ instruction:
                op[0] = 0x93;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = imm_data8($8);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0x9B;
                op[1] = reg_indirect($3) * 16 + arith_opcode;
                op[2] = msb(imm_data16($8));
                op[3] = lsb(imm_data16($8));
-               RELOC_ABS_FFFF (2, 0);
+               RELOC_ABS_FFFF (MEM_POS+2, 0);
        }
   }
 | arith_inst '[' REG '+' expr ']' ',' '#' expr {
@@ -580,8 +577,8 @@ instruction:
                        op[1] = reg_indirect($3) * 16 + arith_opcode;
                        op[2] = ($5 >= 0) ? $5 : 256 + $5;
                        op[3] = imm_data8($9);
-                       RELOC_ABS_FF(2, 0);
-                       RELOC_ABS_FF(3, 1);
+                       RELOC_ABS_FF(MEM_POS+2, 0);
+                       RELOC_ABS_FF(MEM_POS+3, 1);
                } else {
                        $$ = 5;
                        op[0] = 0x9C;
@@ -589,8 +586,8 @@ instruction:
                        op[2] = ($5 >= 0) ? $5 : 256 + $5;
                        op[3] = msb(imm_data16($9));
                        op[4] = lsb(imm_data16($9));
-                       RELOC_ABS_FF(2, 0);
-                       RELOC_ABS_FFFF(3, 1);
+                       RELOC_ABS_FF(MEM_POS+2, 0);
+                       RELOC_ABS_FFFF(MEM_POS+3, 1);
                }
        } else {
                if (size == SIZE8) {
@@ -600,8 +597,8 @@ instruction:
                        op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
                        op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
                        op[4] = imm_data8($9);
-                       RELOC_ABS_FFFF(2,0);
-                       RELOC_ABS_FF(4,1);
+                       RELOC_ABS_FFFF(MEM_POS+2,0);
+                       RELOC_ABS_FF(MEM_POS+4,1);
                } else {
                        $$ = 6;
                        op[0] = 0x9D;
@@ -610,8 +607,8 @@ instruction:
                        op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
                        op[4] = msb(imm_data16($9));
                        op[5] = lsb(imm_data16($9));
-                       RELOC_ABS_FFFF(2, 0);
-                       RELOC_ABS_FFFF(4, 1);
+                       RELOC_ABS_FFFF(MEM_POS+2, 0);
+                       RELOC_ABS_FFFF(MEM_POS+4, 1);
                }
        }
   }
@@ -623,8 +620,8 @@ instruction:
                op[1] = msb(direct_addr($2)) * 16 + arith_opcode;
                op[2] = lsb(direct_addr($2));
                op[3] = imm_data8($5);
-               RELOC_ABS_F0FF(1,0);
-               RELOC_ABS_FF(3,1);
+               RELOC_ABS_F0FF(MEM_POS+1,0);
+               RELOC_ABS_FF(MEM_POS+3,1);
        } else {
                $$ = 5;
                op[0] = 0x9E;
@@ -632,8 +629,8 @@ instruction:
                op[2] = lsb(direct_addr($2));
                op[3] = msb(imm_data16($5));
                op[4] = lsb(imm_data16($5));
-               RELOC_ABS_F0FF(1,0);
-               RELOC_ABS_FFFF (3,1);
+               RELOC_ABS_F0FF(MEM_POS+1,0);
+               RELOC_ABS_FFFF (MEM_POS+3,1);
        }
   }
 
@@ -658,7 +655,7 @@ instruction:
        op[0] = 0xA0 + size * 8;
        op[1] = 128 + reg_indirect($5) * 16 + msb(direct_addr($2));
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
   }
 | arith_inst '[' REG ']' ',' WORD {
        /* this addr mode is only valid for MOV */
@@ -668,7 +665,7 @@ instruction:
        op[0] = 0xA0 + size * 8;
        op[1] = reg_indirect($3) * 16 + msb(direct_addr($6));
        op[2] = lsb(direct_addr($6));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
   }
 | arith_inst WORD ',' WORD {
        /* this addr mode is only valid for MOV */
@@ -679,8 +676,8 @@ instruction:
        op[1] = msb(direct_addr($2)) * 16 + msb(direct_addr($4));
        op[2] = lsb(direct_addr($2));
        op[3] = lsb(direct_addr($4));
-       RELOC_ABS_F0FF(1, 0);
-       RELOC_ABS_0F00FF(1, 1);
+       RELOC_ABS_F0FF(MEM_POS+1, 0);
+       RELOC_ABS_0F00FF(MEM_POS+1, 1);
   }
 | arith_inst REG ',' USP {
        /* this addr mode is only valid for MOV */
@@ -703,7 +700,7 @@ instruction:
        op[0] = 0x08;
        op[1] = 0x20 + msb(bit_addr($4));
        op[2] = lsb(bit_addr($4));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 | arith_inst bit ',' C {
        /* this addr mode is only valid for MOV */
@@ -712,7 +709,7 @@ instruction:
        op[0] = 0x08;
        op[1] = 0x30 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 
 | MOVC REG ',' '[' REG '+' ']' {
@@ -761,28 +758,28 @@ instruction:
        op[0] = 0xA0 + size * 8;
        op[1] = reg($2) * 16 + msb(direct_addr($4));
         op[2] = lsb(direct_addr($4));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
   }
 | short_data_inst REG ',' '#' expr {
        $$ = 2;
        size = find_size1(inst_size, $2);
        op[0] = short_opcode + size * 8 + 1;
        op[1] = reg($2) * 16 + imm_data4_signed($5);
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | short_data_inst '[' REG ']' ',' '#' expr {
        $$ = 2;
        size = find_size0(inst_size);
        op[0] = short_opcode + size * 8 + 2;
        op[1] = reg_indirect($3) * 16 + imm_data4_signed($7);
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | short_data_inst '[' REG '+' ']' ',' '#' expr {
        $$ = 2;
        size = find_size0(inst_size);
        op[0] = short_opcode + size * 8 + 3;
        op[1] = reg_indirect($3) * 16 + imm_data4_signed($8);
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | short_data_inst '[' REG '+' expr ']' ',' '#' expr {
        size = find_size0(inst_size);
@@ -791,16 +788,16 @@ instruction:
                op[0] = short_opcode + size * 8 + 4;
                op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
                op[2] = op[2] = ($5 >= 0) ? $5 : 256 + $5;
-               RELOC_ABS_0F(1, 1);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_0F(MEM_POS+1, 1);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = short_opcode + size * 8 + 5;
                op[1] = reg_indirect($3) * 16 + imm_data4_signed($9);
                op[2] = ($5 >= 0) ? msb($5) : msb(65536 + $5);
                op[3] = ($5 >= 0) ? lsb($5) : lsb(65536 + $5);
-               RELOC_ABS_0F(1, 1);
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_0F(MEM_POS+1, 1);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
        }
   }
 | short_data_inst expr ',' '#' expr {
@@ -809,21 +806,21 @@ instruction:
        op[0] = short_opcode + size * 8 + 6;
        op[1] = msb(direct_addr($2)) * 16 + imm_data4_signed($5);
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_0F(1, 0);
+       RELOC_ABS_0F(MEM_POS+1, 0);
   }
 | ANL C ',' bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x40 + msb(bit_addr($4));
        op[2] = lsb(bit_addr($4));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 | ANL C ',' '/' bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x50 + msb(bit_addr($5));
        op[2] = lsb(bit_addr($5));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 
 | ORL C ',' bit {
@@ -831,28 +828,28 @@ instruction:
        op[0] = 0x08;
        op[1] = 0x60 + msb(bit_addr($4));
        op[2] = lsb(bit_addr($4));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 | ORL C ',' '/' bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x70 + msb(bit_addr($5));
        op[2] = lsb(bit_addr($5));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 | CLR bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 | SETB bit {
        $$ = 3;
        op[0] = 0x08;
        op[1] = 0x10 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
-       RELOC_ABS_03FF(1, 0);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
   }
 | logical_shift_inst REG ',' REG {
        size = find_size1(inst_size, $2);
@@ -937,13 +934,13 @@ instruction:
                op[0] = 0x40;
                op[1] = reg($2) * 16 + reg_indirect($4);
                op[2] = ($6 >= 0) ? $6 : 256 + $6;
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                op[0] = 0x48;
                op[1] = reg($2) * 16 + reg_indirect($4);
                op[2] = ($6 >= 0) ? msb($6) : msb(65536 + $6);
                op[3] = ($6 >= 0) ? lsb($6) : lsb(65536 + $6);
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
        }
   }
 | stack_inst WORD {
@@ -952,7 +949,7 @@ instruction:
        op[0] = msb(stack_addr_opcode) + size * 8;
        op[1] = lsb(stack_addr_opcode) + msb(direct_addr($2));
        op[2] = lsb(direct_addr($2));
-       RELOC_ABS_07ff(1, 0);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
   }
 | stack_inst rlist {
        $$ = 2;
@@ -987,7 +984,7 @@ instruction:
        op[1] = reg($2) + 8;
        op[2] = msb(imm_data16($5));
        op[3] = lsb(imm_data16($5));
-       RELOC_ABS_FFFF(2, 0);
+       RELOC_ABS_FFFF(MEM_POS+2, 0);
   }
 | MULU REG ',' '#' expr {
        size = find_size2(inst_size, $2, $4);
@@ -996,14 +993,14 @@ instruction:
                op[0] = 0xE8;
                op[1] = reg($2) * 16;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
        } else {
                $$ = 4;
                op[0] = 0xE9;
                op[1] = reg($2) * 16;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
        }
   }
 | DIV REG ',' REG {
@@ -1050,7 +1047,7 @@ instruction:
                op[0] = 0xE8;
                op[1] = reg($2) * 16 + 11;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
                break;
        case SIZE32:
                $$ = 4;
@@ -1058,7 +1055,7 @@ instruction:
                op[1] = (reg($2) / 2) * 32 + 9;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
                break;
        }
   }
@@ -1070,14 +1067,14 @@ instruction:
                op[0] = 0xE8;
                op[1] = reg($2) * 16 + 1;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
                break;
        case SIZE16:
                $$ = 3;
                op[0] = 0xE8;
                op[1] = reg($2) * 16 + 3;
                op[2] = imm_data8($5);
-               RELOC_ABS_FF(2, 0);
+               RELOC_ABS_FF(MEM_POS+2, 0);
                break;
        case SIZE32:
                $$ = 4;
@@ -1085,7 +1082,7 @@ instruction:
                op[1] = (reg($2) / 2) * 32 + 1;
                op[2] = msb(imm_data16($5));
                op[3] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(2, 0);
+               RELOC_ABS_FFFF(MEM_POS+2, 0);
                break;
        }
   }
@@ -1129,7 +1126,7 @@ instruction:
        op[0] = 0xD5;
        op[1] = msb(rel16(MEM_POS + $$, $2));
        op[2] = lsb(rel16(MEM_POS + $$, $2));
-       RELOC_FFFF(MEM_POS+$$,1,0);
+       RELOC_FFFF(MEM_POS+1,MEM_POS+$$,0);
   }
 
 | CALL jmpaddr {
@@ -1137,13 +1134,13 @@ instruction:
         op[0] = 0xC5;
         op[1] = msb(rel16(MEM_POS + $$, $2));
         op[2] = lsb(rel16(MEM_POS + $$, $2));
-       RELOC_FFFF(MEM_POS+$$,1,0);
+       RELOC_FFFF(MEM_POS+1, MEM_POS+$$, 0);
   }
 | branch_inst jmpaddr {
        $$ = 2;
        op[0] = branch_opcode;
        op[1] = rel8(MEM_POS + $$, $2);
-       RELOC_FF(MEM_POS + $$, 1,0);
+       RELOC_FF(MEM_POS+1,MEM_POS + $$, 0);
   }
 | CJNE REG ',' expr ',' jmpaddr {
         $$ = 4;
@@ -1152,8 +1149,8 @@ instruction:
        op[1] = reg($2) * 16 + msb(direct_addr($4));
        op[2] = lsb(direct_addr($4));
        op[3] = rel8(MEM_POS + $$, $6);
-       RELOC_ABS_07ff(1, 0);
-       RELOC_FF(MEM_POS + $$, 3,1);
+       RELOC_ABS_07ff(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 | CJNE REG ',' '#' expr ',' jmpaddr {
        size  = find_size1(inst_size, $2);
@@ -1163,7 +1160,7 @@ instruction:
                op[1] = reg($2) * 16;
                op[2] = rel8(MEM_POS + $$, $7);
                op[3] = imm_data8($5);
-               RELOC_ABS_FF(3, 0);
+               RELOC_ABS_FF(MEM_POS+3, 0);
        } else {
                $$ = 5;
                op[0] = 0xEB;
@@ -1171,7 +1168,7 @@ instruction:
                op[2] = rel8(MEM_POS + $$, $7);
                op[3] = msb(imm_data16($5));
                op[4] = lsb(imm_data16($5));
-               RELOC_ABS_FFFF(3, 0);
+               RELOC_ABS_FFFF(MEM_POS+3, 0);
        }
   }
 | CJNE '[' REG ']' ',' '#' expr ',' jmpaddr {
@@ -1182,7 +1179,7 @@ instruction:
                op[1] = reg_indirect($3) * 16 + 8;
                op[2] = rel8(MEM_POS + $$, $9);
                op[3] = imm_data8($7);
-               RELOC_ABS_FF(3, 0);
+               RELOC_ABS_FF(MEM_POS+3, 0);
        } else {
                $$ = 5;
                op[0] = 0xEB;
@@ -1190,7 +1187,7 @@ instruction:
                op[2] = rel8(MEM_POS + $$, $9);
                op[3] = msb(imm_data16($7));
                op[4] = lsb(imm_data16($7));
-               RELOC_ABS_FFFF(3, 0);
+               RELOC_ABS_FFFF(MEM_POS+3, 0);
        }
   }
 | DJNZ REG ',' jmpaddr {
@@ -1199,7 +1196,7 @@ instruction:
        op[0] = 0x87 + size * 8;
        op[1] = reg($2) * 16 + 8;
        op[2] = rel8(MEM_POS + $$, $4);
-       RELOC_FF(MEM_POS+$$, 2, 0);
+       RELOC_FF(MEM_POS+2, MEM_POS+$$, 0);
   }
 
 
@@ -1210,8 +1207,8 @@ instruction:
        op[1] = msb(direct_addr($2)) + 8;
        op[2] = lsb(direct_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_07ff(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1)
+       RELOC_ABS_07ff(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1)
   }
 
 | JB bit ',' jmpaddr {
@@ -1220,8 +1217,8 @@ instruction:
        op[1] = 0x80 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_03FF(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 
 | JBC bit ',' jmpaddr {
@@ -1230,8 +1227,8 @@ instruction:
        op[1] = 0xC0 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_03FF(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 
 | JNB bit ',' jmpaddr {
@@ -1240,8 +1237,8 @@ instruction:
        op[1] = 0xA0 + msb(bit_addr($2));
        op[2] = lsb(bit_addr($2));
        op[3] = rel8(MEM_POS + $$, $4);
-       RELOC_ABS_03FF(1, 0);
-       RELOC_FF(MEM_POS + $$, 3, 1);
+       RELOC_ABS_03FF(MEM_POS+1, 0);
+       RELOC_FF(MEM_POS+3, MEM_POS + $$, 1);
   }
 
 
index 9a575b4b7448410061fc23592d3ad2fca20ef913..c7906cd045243da066829a3d0ad2f4dd9b436367 100755 (executable)
@@ -9,9 +9,12 @@ extern bit be;
 extern code ce;
 extern data de;
 extern xdata xe;
+xdata at 0x1234 abs;
+extern xdata xee;
 
 void main(void) {
   xe=getchar();
+  abs=1;
   putchar('1');
   putchar('2');
   putchar('3');
index a408bc1b32590310b27507e7e52aba3dda49d45f..b7c79876195f34c1552c8faa7edda48d213e33bd 100755 (executable)
@@ -42,7 +42,9 @@ void putchar(char c) {
   _endasm;
 }
 
-#define getchar(x)
+char getchar() {
+  return 0;
+}
 
 void exit_simulator(void) {
   _asm
index 14190ca02e30dcf424a51dafe316d173493a20ca..7395180170b3b44a818178a9dd5b3e55c115767e 100755 (executable)
@@ -1698,7 +1698,12 @@ static void genCast (iCode * ic) {
       if (size==2)
        return;
       // fall through: case 0x41
-      emitcode("sext", AOP_NAME(result)[1]);
+      if (signedness) {
+       emitcode("sext", "r1");
+      } else {
+       emitcode("mov", "r1,#0");
+      }
+      emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
       return;
     case 0x14:
     case 0x12:
index 43bd771b3edac7432a58c504a844546c2d094a6b..0c1584b2ea0b7c1459c37809cdd4c6a91c9a5c59 100755 (executable)
@@ -198,7 +198,7 @@ static const char *_linkCmd[] =
 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
 static const char *_asmCmd[] =
 {
-  "xa_rasm", "$l", "$3", "$1.xa", NULL
+  "xa_rasm", "$l", "$3", "$1.asm", NULL
 };
 
 /* Globals */
@@ -218,7 +218,7 @@ PORT xa51_port =
     "",                                /* Options with debug */
     "",                                /* Options without debug */
     0,
-    ".xa",
+    ".asm",
     NULL                       /* no do_assemble function */
   },
   {
index 39b98d7d50e2ecf9a243d66ee303f4acd531977a..a235690c685adcd0b4c3f8bad3a50ee18d5784f6 100755 (executable)
@@ -8,7 +8,7 @@ SXA = $(shell if [ -f $(SXA_A) ]; then echo $(SXA_A); else echo $(SXA_B); fi)
 
 SDCCFLAGS +=-mxa51 --lesspedantic -DREENTRANT=
 
-OBJEXT = .xa
+OBJEXT = .rel
 EXEEXT = .hex
 
 EXTRAS = fwk/lib/testfwk$(OBJEXT) $(PORTS_DIR)/$(PORT)/support$(OBJEXT)