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

as/xa51/Makefile
as/xa51/xa_link.c
as/xa51/xa_main.c
as/xa51/xa_version.h
device/include/80c51xa.h [new file with mode: 0755]
src/SDCCglobl.h
src/SDCCmain.c
src/xa51/main.c

index 0b092d5945879e56c028cf236da70db8bc543967..dcd797fe95de36603ea8522f7b549b813bfc9b64 100644 (file)
@@ -6,8 +6,10 @@ LEXLIB =
 
 all: xa_rasm xa_link
 
-xa_rasm: xa_main.o xa_rasm.tab.o xa_rasm.lex.o 
-       $(CC) -o xa_rasm xa_main.o xa_rasm.tab.o xa_rasm.lex.o $(LEXLIB)
+OBJECTS = xa_main.o xa_rasm.tab.o xa_rasm.lex.o  
+
+xa_rasm: $(OBJECTS)
+       $(CC) -o xa_rasm $(OBJECTS) $(LEXLIB)
        #strip xa_rasm
 
 xa_rasm.lex.o: xa_rasm.lex.c xa_rasm.tab.h xa_main.h
@@ -16,9 +18,12 @@ xa_rasm.lex.o: xa_rasm.lex.c xa_rasm.tab.h xa_main.h
 xa_rasm.tab.o: xa_rasm.tab.c xa_rasm.tab.h xa_main.h
        $(CC) $(CFLAGS) -c xa_rasm.tab.c
 
-xa_main.o: xa_main.c xa_main.h
+xa_main.o: xa_main.c xa_main.h xa_version.h
        $(CC) $(CFLAGS) -Wall -c xa_main.c
 
+xa_link.o: xa_link.c xa_main.h xa_version.h
+       $(CC) $(CFLAGS) -Wall -c xa_link.c
+
 xa_rasm.tab.c xa_rasm.tab.h: xa_rasm.y
        $(YACC) xa_rasm.y
        mv y.tab.c xa_rasm.tab.c
index b89015651acec2b29aeb96957d629912f87da5c8..8b1489d199230cfc0ed2cbe30acbaa8256b5e079 100644 (file)
@@ -2,6 +2,16 @@
    age in your country to watch this.
 */
 
+/* This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 /* This is a cheap hack. The xa51 has a couple of ways to scramble
    relocation info into it's opcode that the standard linker can't
    handle. 
@@ -12,7 +22,7 @@
 
    "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> [Ref000 | DefXXXX]" Def's are supposed to be defined in
+   "S <symbol> [Ref0000 | DefXXXX]" 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
    "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
+
+   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
+   port.
 */
 
 #include <stdio.h>
 
 #include "xa_version.h"
 
+enum {
+  CSEG=0,
+  DSEG,
+  XSEG,
+  BSEG,
+  MAX_SEGMENTS
+};
+
+struct SEGMENT {
+  short id;
+  char *name;
+  int start;
+  int current;
+} segments[MAX_SEGMENTS]={
+  {CSEG, "CSEG", 0, 0},
+  {DSEG, "DSEG", 0, 0},
+  {XSEG, "XSEG", 0, 0},
+  {BSEG, "BSEG", 0, 0}
+};
+
+char *libPaths[128];
+int nlibPaths=0;
+char *libFiles[128];
+int nlibFiles=0;
+
 static char outFileName[PATH_MAX];
 
+void syntaxError (char *err) {
+  fprintf (stderr, "error while parsing '%s'\n", err);
+  exit(1);
+}
+
 void baseName(char *name, char*base) {
   int i, first, last;
 
@@ -69,51 +113,111 @@ void readModule(char *module) {
     exit (1);
   }
   printf ("ReadModule: %s\n", module);
+
   // first we need to check if this is a valid file
-  if (sscanf(line, "SDCCXA rel, version %lf", &hisVersion)!=1) {
+  if (sscanf(fgets(line, 132, relModule), 
+      "SDCCXA rel, version %lf", &hisVersion)!=1) {
     fprintf (stderr, "%s is not a valid input file\n", module);
     exit (1);
   }
   if (hisVersion!=version) {
-    fprintf (stderr, "version conflict; we: %f != module: %f\n", 
-            version, hisVersion);
+    fprintf (stderr, "WARNING: version conflict; "
+            "we(%1.1f) != %s(%1.1f)\n", 
+            version, module, hisVersion);
   }
 
-  fprintf (stderr, "Wow! This seems a nice module.\n");
+  // 
+  fprintf (stderr, "Wow! This seems a nice module: v %1.1f.\n", hisVersion);
   // that's all for now, thanks for watching */
   fclose (relModule);
 }
 
-void writeModule(char *module) {
-  if (!outFileName[0]) {
-    sprintf (outFileName, "%s.bin", module);
-  }
+void writeModule() {
   fprintf (stderr, "WriteModule: %s\n", outFileName);
   // oops, forgot something :) */
 }
 
+void relocate() {
+}
+
 void usage (char * progName, int errNo) {
-  fprintf (stderr, "usage: %s f.rel [f1.rel [f2.rel [...]]]\n", progName);
+  fprintf (stderr, "usage: %s lnkCmdFile\n", progName);
   if (errNo) {
     exit (errNo);
   }
 }
 
 int main(int argc, char **argv) {
-  char outputName[PATH_MAX];
-  int i;
+  FILE *linkCommandsFile;
+  char linkCommandsPath[PATH_MAX];
+  char linkCommand[PATH_MAX];
 
-  // no options yet, assuming "--code-loc 0 --xram-loc 0 --stack-loc 0x100"
-  if (argc<2) {
+  if (argc!=2) {
     usage(argv[0], 1);
   }
-  baseName(argv[1], outputName);
-  fprintf (stderr, "using baseName: %s\n", outputName);
-  for (i=1; i<argc; i++) {
-    readModule(argv[i]);
+
+  // read in the commands
+  sprintf (linkCommandsPath, "%s.lnk", argv[1]);
+  if (!(linkCommandsFile=fopen(linkCommandsPath, "r"))) {
+    perror(linkCommandsPath);
+    exit(1);
+  }
+  while (fgets(linkCommand, PATH_MAX, linkCommandsFile)) {
+    linkCommand[strlen(linkCommand)-1]='\0';
+
+    // skip empty lines
+    if (!*linkCommand) {
+      continue;
+    }
+
+    puts (linkCommand);
+    if (*linkCommand=='-') {
+      switch (linkCommand[1]) 
+       {
+       case 'm':
+         // probably -muxi, ignore for now
+         break;
+       case 'e':
+         // -e, always in the last line, ignore for now
+         break;
+       case 'b': 
+         {
+           // a segment start address like: "-b XSEG = 0x4000"
+           int s;
+           char *seg=strtok(&linkCommand[3], " \t");
+           for (s=0; s<MAX_SEGMENTS; s++) {
+             if (strcmp(segments[s].name, seg)==0) {
+               strtok(NULL, " \t"); // skip the '='
+               if (sscanf(strtok(NULL, " \t"), "%x", 
+                          &segments[s].start)!=1) {
+                 syntaxError(linkCommand);
+               }
+               break;
+             }
+           }
+           if (s==MAX_SEGMENTS) {
+             syntaxError(linkCommand);
+           }
+         }
+         break;
+       case 'k':
+         // a lib path like: "-k /usr/local/share/sdcc/lib/xa51"; one/line
+         libPaths[nlibPaths++]=strdup(&linkCommand[3]);
+         break;
+       case 'l':
+         // a lib file like: "-l libsdcc"; one/line
+         libFiles[nlibFiles++]=strdup(&linkCommand[3]);
+         break;
+       default:
+         syntaxError(linkCommand);
+       }
+    } else {
+      // not a switch, must be an inputfile; one/line
+      readModule(linkCommand);
+    }
   }
-  strcat(outputName, ".bin");
-  writeModule (outputName);
+  relocate();
+  writeModule();
   return 0;
 }
-     
+
index 0d07450272a60eefad7404e15d6eb1ab85651090..fea9d6ecfd0e886c214d0e5b49e33f43486b6ed7 100644 (file)
 /* adapted from the osu8asm project, 1995 */
 /* http://www.pjrc.com/tech/osu8/index.html */
 
+/* 
+   made "relocatable" by johan.knol@iduna.nl for sdcc
+   
+   This isn't a standalone assembler anymore. It's only purpose is to
+   create relocatable modules (that has to be processed with xa_link) 
+   out of sdcc-generated .xa files
+*/
+
 #define D(x) x
 
 #include <stdio.h>
index 146fbfb49baccc8c38df4ef0a653ac54c9e64ba0..167bbf870800366fed6be99fcff7402eb65df22e 100644 (file)
@@ -1 +1 @@
-#define version 0.0
+#define version 0.1
diff --git a/device/include/80c51xa.h b/device/include/80c51xa.h
new file mode 100755 (executable)
index 0000000..db8416e
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ *     XA G3 SFR definitions
+ *     Extracted directly from Philips documentation
+ */
+
+#ifndef        XA_H
+#define        XA_H
+
+sfr at 0x400 /*unsigned short*/ PSW; /* Program status word */
+sfr at 0x400 PSWL; /* Program status word (low byte) */
+sfr at 0x401 PSWH; /* Program status word (high byte) */
+sfr at 0x402 PSW51; /* 80C51 compatible PSW */
+sfr at 0x403 SSEL; /* Segment selection register */
+sfr at 0x404 PCON; /* Power control register */
+sfr at 0x410 TCON; /* Timer 0 and 1 control register */
+sfr at 0x411 TSTAT; /* Timer 0 and 1 extended status */
+sfr at 0x418 T2CON; /* Timer 2 control register */
+sfr at 0x419 T2MOD; /* Timer 2 mode control */
+sfr at 0x41F WDCON; /* Watchdog control register */
+sfr at 0x420 S0CON; /* Serial port 0 control register */
+sfr at 0x421 S0STAT; /* Serial port 0 extended status */
+sfr at 0x424 S1CON; /* Serial port 1 control register */
+sfr at 0x425 S1STAT; /* Serial port 1 extended status */
+sfr at 0x426 IEL; /* Interrupt enable low byte */
+sfr at 0x427 IEH; /* Interrupt enable high byte */
+sfr at 0x42A SWR; /* Software Interrupt Request */
+sfr at 0x430 P0; /* Port 0 */
+sfr at 0x431 P1; /* Port 1 */
+sfr at 0x432 P2; /* Port 2 */
+sfr at 0x433 P3; /* Port3 */
+sfr at 0x440 SCR; /* System configuration register */
+sfr at 0x441 DS; /* Data segment */
+sfr at 0x442 ES; /* Extra segment */
+sfr at 0x443 CS; /* Code segment */
+sfr at 0x450 TL0; /* Timer 0 low byte */
+sfr at 0x451 TH0; /* Timer 0 high byte */
+sfr at 0x452 TL1; /* Timer 1 low byte */
+sfr at 0x453 TH1; /* Timer 1 high byte */
+sfr at 0x454 RTL0; /* Timer 0 extended reload, low byte */
+sfr at 0x455 RTH0; /* Timer 0 extended reload, high byte */
+sfr at 0x456 RTL1; /* Timer 1 extended reload, low byte */
+sfr at 0x457 RTH1; /* Timer 1 extended reload, high byte */
+sfr at 0x458 TL2; /* Timer 2 low byte */
+sfr at 0x459 TH2; /* Timer 2 high byte */
+sfr at 0x45A T2CAPL; /* Timer 2 capture register, low byte */
+sfr at 0x45B T2CAPH; /* Timer 2 capture register, high byte */
+sfr at 0x45C TMOD; /* Timer 0 and 1 mode register */
+sfr at 0x45D WFEED1; /* Watchdog feed 1 */
+sfr at 0x45E WFEED2; /* Watchdog feed 2 */
+sfr at 0x45F WDL; /* Watchdog timer reload */
+sfr at 0x460 S0BUF; /* Serial port 0 buffer register */
+sfr at 0x461 S0ADDR; /* Serial port 0 address register */
+sfr at 0x462 S0ADEN; /* Serial port 0 address enable register */
+sfr at 0x464 S1BUF; /* Serial port 1 buffer register */
+sfr at 0x465 S1ADDR; /* Serial port 1 address register */
+sfr at 0x466 S1ADEN; /* Serial port 1 address enable register */
+sfr at 0x468 BTRL; /* Bus timing register high byte */
+sfr at 0x469 BTRH; /* Bus timing register low byte */
+sfr at 0x46A BCR; /* Bus configuration register */
+sfr at 0x470 P0CFGA; /* Port 0 configuration A */
+sfr at 0x471 P1CFGA; /* Port 1 configuration A */
+sfr at 0x472 P2CFGA; /* Port 2 configuration A */
+sfr at 0x473 P3CFGA; /* Port 3 configuration A */
+sfr at 0x47A SWE; /* Software Interrupt Enable */
+sfr at 0x4A0 IPA0; /* Interrupt priority 0 */
+sfr at 0x4A1 IPA1; /* Interrupt priority 1 */
+sfr at 0x4A2 IPA2; /* Interrupt priority 2 */
+sfr at 0x4A4 IPA4; /* Interrupt priority 4 */
+sfr at 0x4A5 IPA5; /* Interrupt priority 5 */
+sfr at 0x4F0 P0CFGB; /* Port 0 configuration B */
+sfr at 0x4F1 P1CFGB; /* Port 1 configuration B */
+sfr at 0x4F2 P2CFGB; /* Port 2 configuration B */
+sfr at 0x4F3 P3CFGB; /* Port 3 configuration B */
+
+sbit  at 0x33B ETI1; /* TX interrupt enable 1 */
+sbit  at 0x33A ERI1; /* RX interrupt enable 1 */
+sbit  at 0x339 ETI0; /* TX interrupt enable 0 */
+sbit  at 0x338 ERI0; /* RX interrupt enable 0 */
+sbit  at 0x337 EA; /* global int. enable */
+sbit  at 0x334 ET2; /* timer 2 interrupt */
+sbit  at 0x333 ET1; /* timer 1 interrupt */
+sbit  at 0x332 EX1; /* external interrupt 1 */
+sbit  at 0x331 ET0; /* timer 0 interrupt */
+sbit  at 0x330 EX0; /* external interrupt 0 */
+sbit  at 0x221 PD; /* power down */
+sbit  at 0x220 IDL;
+sbit  at 0x20F SM;
+sbit  at 0x20E TM;
+sbit  at 0x20D RS1;
+sbit  at 0x20C RS0;
+sbit  at 0x20B IM3;
+sbit  at 0x20A IM2;
+sbit  at 0x209 IM1;
+sbit  at 0x208 IM0;
+sbit  at 0x307 S0M0;
+sbit  at 0x306 S0M1;
+sbit  at 0x305 S0M2;
+sbit  at 0x304 R0EN;
+sbit  at 0x303 T0B8;
+sbit  at 0x302 R0B8;
+sbit  at 0x301 TI0; /* serial port 0 tx ready */
+sbit  at 0x300 RI0; /* serial port 0 rx ready */
+sbit  at 0x30B FE0;
+sbit  at 0x30A BR0;
+sbit  at 0x309 OE0;
+sbit  at 0x308 STINT0;
+sbit  at 0x327 S1M0;
+sbit  at 0x326 S1M1;
+sbit  at 0x325 S1M2;
+sbit  at 0x324 R1EN;
+sbit  at 0x323 T1B8;
+sbit  at 0x322 R1B8;
+sbit  at 0x321 TI1; /* serial port 0 tx ready */
+sbit  at 0x320 RI1; /* serial port 0 rx ready */
+sbit  at 0x32B FE1;
+sbit  at 0x32A BR1;
+sbit  at 0x329 OE1;
+sbit  at 0x328 STINT1;
+sbit  at 0x356 SWR7;
+sbit  at 0x355 SWR6;
+sbit  at 0x354 SWR5;
+sbit  at 0x353 SWR4;
+sbit  at 0x352 SWR3;
+sbit  at 0x351 SWR2;
+sbit  at 0x350 SWR1;
+sbit  at 0x2C7 TF2;
+sbit  at 0x2C6 EXF2;
+sbit  at 0x2C5 RCLK0;
+sbit  at 0x2C4 TCLK0;
+sbit  at 0x2CD RCLK1;
+sbit  at 0x2CC TCLK1;
+sbit  at 0x2C3 EXEN2;
+sbit  at 0x2C2 TR2;
+sbit  at 0x2C1 CT2;
+sbit  at 0x2C0 CPRL2;
+sbit  at 0x2C9 T2OE;
+sbit  at 0x2C8 DCEN;
+sbit  at 0x287 TF1;
+sbit  at 0x286 TR1;
+sbit  at 0x285 TF0;
+sbit  at 0x284 TR0;
+sbit  at 0x283 IE1;
+sbit  at 0x282 IT1;
+sbit  at 0x281 IE0;
+sbit  at 0x280 IT0;
+sbit  at 0x28A T1OE;
+sbit  at 0x288 T0OE;
+sbit  at 0x2FF PRE2;
+sbit  at 0x2FE PRE1;
+sbit  at 0x2FD PRE0;
+sbit  at 0x2FA WDRUN;
+sbit  at 0x2F9 WDTOF;
+sbit  at 0x2F8 WDMOD;
+sbit  at 0x388 WR1;
+sbit  at 0x38F T2EX;
+sbit  at 0x38C RXD1;
+sbit  at 0x38D TXD1;
+sbit  at 0x398 RXD0;
+sbit  at 0x399 TXD0;
+sbit  at 0x39A INT0;
+sbit  at 0x39B INT1;
+sbit  at 0x39C T0;
+sbit  at 0x39D T1;
+sbit  at 0x39E WR;
+sbit  at 0x39F RD;
+
+/*
+ * Interrupt stuff
+ */
+
+
+/* Vectors */
+
+#define IV_BRKPT 0x04 /* breakpoint vector */
+#define IV_TRACE 0x08 /* Trace mode bit set */
+#define IV_STKOVER 0x0C /* stack overflow */
+#define IV_DIVZERO 0x10 /* divide by zero */
+#define IV_IRET 0x14 /* user mode IRET */
+
+#define IV_EX0 0x80
+#define IV_T0 0x84
+#define IV_EX1 0x88
+#define IV_T1 0x8C
+#define IV_T2 0x90
+#define IV_RI0 0xA0
+#define IV_TI0 0xA4
+#define IV_RI1 0xA8
+#define IV_TI1 0xAC
+#define IV_SWI1 0x100 /* software interrupts */
+#define IV_SWI2 0x104
+#define IV_SWI3 0x108
+#define IV_SWI4 0x10C
+#define IV_SWI5 0x110
+#define IV_SWI6 0x114
+#define IV_SWI7 0x118
+
+/* PSW Values for interrupt vectors */
+
+#define IV_PSW 0x8F00 /* System mode, high priority, bank 0 */
+
+#define IV_SYSTEM 0x8000
+
+#define IV_PRI00 0x0000 /* priorities 0 - 15 */
+#define IV_PRI01 0x0100
+#define IV_PRI02 0x0200
+#define IV_PRI03 0x0300
+#define IV_PRI04 0x0400
+#define IV_PRI05 0x0500
+#define IV_PRI06 0x0600
+#define IV_PRI07 0x0700
+#define IV_PRI08 0x0800
+#define IV_PRI09 0x0900
+#define IV_PRI10 0x0A00
+#define IV_PRI11 0x0B00
+#define IV_PRI12 0x0C00
+#define IV_PRI13 0x0D00
+#define IV_PRI14 0x0E00
+#define IV_PRI15 0x0F00
+
+#define IV_BANK0 0x0000
+#define IV_BANK1 0x1000
+#define IV_BANK2 0x2000
+#define IV_BANK3 0x3000
+
+#endif /* XA_H */
index df96d5be1668b1216953fde9dc8441ec53455c84..b7e45e4a7aff0b103ca734c7f83881bbd5e1ad83 100644 (file)
@@ -186,7 +186,8 @@ enum
     MODEL_COMPACT = 2,
     MODEL_MEDIUM = 4,
     MODEL_LARGE = 8,
-    MODEL_FLAT24 = 16
+    MODEL_FLAT24 = 16,
+    MODEL_PAGE0 = 32 /* for the xa51 port */
   };
 
 /* overlay segment name and the functions
index 1a7c80ce08a083694c80b9281431d45feb94f975..10d42aa00420719b15fb14aa542ce05a38100be9 100644 (file)
@@ -57,7 +57,7 @@ const char *preArgv[128];     /* pre-processor arguments  */
 int currRegBank = 0;
 struct optimize optimize;
 struct options options;
-char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
+char *VersionString = SDCC_VERSION_STR;
 int preProcOnly = 0;
 int noAssemble = 0;
 char *linkOptions[128];
@@ -1119,8 +1119,9 @@ linkEdit (char **envp)
   WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
 
   /* indirect data */
-  if (IDATA_NAME)
+  if (IDATA_NAME) {
     WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+  }
 
   /* bit segment start */
   WRITE_SEG_LOC (BIT_NAME, 0);
@@ -1136,31 +1137,25 @@ linkEdit (char **envp)
   /* standard library path */
   if (!options.nostdlib)
     {
-/****
-      if (TARGET_IS_DS390)
+      switch (options.model)
        {
+       case MODEL_SMALL:
+         c = "small";
+         break;
+       case MODEL_LARGE:
+         c = "large";
+         break;
+       case MODEL_FLAT24:
+         /* c = "flat24"; */
          c = "ds390";
-       }
-      else
-*****/
-       {
-         switch (options.model)
-           {
-           case MODEL_SMALL:
-             c = "small";
-             break;
-           case MODEL_LARGE:
-             c = "large";
-             break;
-           case MODEL_FLAT24:
-             /* c = "flat24"; */
-             c = "ds390";
-             break;
-           default:
-             werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
-             c = "unknown";
-             break;
-           }
+         break;
+       case MODEL_PAGE0:
+         c = "xa51";
+         break;
+       default:
+         werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
+         c = "unknown";
+         break;
        }
       mfprintf (lnkfile, getRuntimeVariables(), "-k {libdir}{sep}%s\n", c);
 
@@ -1288,6 +1283,9 @@ preProcess (char **envp)
        case MODEL_FLAT24:
          addToList (preArgv, "-DSDCC_MODEL_FLAT24");
          break;
+       case MODEL_PAGE0:
+         addToList (preArgv, "-DSDCC_MODEL_PAGE0");
+         break;
        default:
          werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
          break;
index b383c49587c000d0431eae675431422e52b94768..b893bf79f6d97508e5be1f50f1a69d318f97ab43 100755 (executable)
@@ -1,9 +1,7 @@
-/** @file main.c
-    xa51 specific general functions.
-
-    Note that mlh prepended _xa51_ on the static functions.  Makes
-    it easier to set a breakpoint using the debugger.
+/* @file main.c
+   xa51 specific general functions.
 */
+
 #include "common.h"
 #include "main.h"
 #include "ralloc.h"
@@ -93,6 +91,10 @@ _xa51_finaliseOptions (void)
 {
   port->mem.default_local_map = istack;
   port->mem.default_globl_map = xdata;
+  if (options.model!=MODEL_PAGE0) {
+    fprintf (stderr, "-mxa51 only supports --model-page0\n");
+    exit (1);
+  }
 }
 
 static void
@@ -102,6 +104,7 @@ _xa51_setDefaultOptions (void)
   options.intlong_rent=1;
   options.float_rent=1;
   options.stack_loc=0x100;
+  options.data_loc=0;
 }
 
 static const char *
@@ -189,7 +192,7 @@ static bool cseCostEstimation (iCode *ic, iCode *pdic)
 */
 static const char *_linkCmd[] =
 {
-  "xa_link", "", NULL
+  "xa_link", "", "$1", NULL
 };
 
 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
@@ -206,8 +209,8 @@ PORT xa51_port =
   "MCU 80C51XA",                       /* Target name */
   {
     FALSE,                     /* Emit glue around main */
-    MODEL_LARGE,
-    MODEL_LARGE
+    MODEL_PAGE0,
+    MODEL_PAGE0
   },
   {
     _asmCmd,