+/* xa_link.c
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+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, see <http://www.gnu.org/licenses/>. */
+
/* WORK IN PROGRESS: do not watch this if you don't have the legal
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. No hash or qsort yet.
+ handle, not to mention word allignment.
+
+ No hash or qsort yet.
The relocatable format looks like the known one, BUT ISN'T.
GSINIT=1,
CSEG,
XINIT,
- GSFINAL, // here goes the final output
+
+ // here goes the final output and should be used by the assembler
+ GSFINAL,
// these are only for storage
BSEG,
DSEG,
XSEG,
XISEG,
+
+ // that's all
MAX_SEGMENTS
};
module=calloc(1, sizeof(struct MODULE));
module->name=strdup(name);
for (s=0; s<MAX_SEGMENTS; s++) {
- module->offset[s]=segments[s]._size;
+ module->offset[s]=(segments[s]._size+1)&0xfffffe;
}
module->isLib=isLib;
if (!modules) {
}
currentLine++;
}
- // that's all for now, thanks for watching */
fclose (relModule);
}
unsigned int len;
unsigned int checksum;
- fprintf (stderr, "writeModule: %s from 0x%04x to 0x%04x\n",
- outFileName,
- address,
- address+size);
-
if ((fOut=fopen(outFileName, "w"))==NULL) {
perror (outFileName);
}
}
// GSFINAL starts at --code-loc ( -b CSEG = 0x1234 )
+ if (segments[CSEG].start & 1) {
+ fprintf (stderr, "*** error: code doesn't start at "
+ "an even address: %04x\n", segments[CSEG].start);
+ exit (1);
+ }
segments[GSFINAL].start=segments[CSEG].start;
memset(gsfinalImage, 0xff, CODESIZE);
memcpy(to, from, segments[GSINIT]._size);
segments[GSINIT].start=segments[GSFINAL].start;
segments[GSFINAL]._size += segments[GSINIT]._size;
+ if (segments[GSFINAL]._size & 1) {
+ segments[GSFINAL]._size++;
+ }
// append cseg to gsfinal
from=csegImage;
memcpy(to, from, segments[CSEG]._size);
segments[CSEG].start=segments[GSFINAL].start+segments[GSFINAL]._size;
segments[GSFINAL]._size += segments[CSEG]._size;
+ if (segments[GSFINAL]._size & 1) {
+ segments[GSFINAL]._size++;
+ }
// append xinit to gsfinal
from=xinitImage;
memcpy(to, from, segments[XINIT]._size);
segments[XINIT].start=segments[GSFINAL].start+segments[GSFINAL]._size;
segments[GSFINAL]._size += segments[XINIT]._size;
+ if (segments[GSFINAL]._size & 1) {
+ segments[GSFINAL]._size++;
+ }
// XISEG is located after XSEG
+ if (segments[XSEG].start & 1) {
+ fprintf (stderr, "*** warning: xdata doesn't start at "
+ "an even address: %04x\n", segments[XSEG].start);
+ }
+ if (segments[XSEG]._size & 1) {
+ segments[XSEG]._size++;
+ }
+
segments[XISEG].start=segments[XSEG].start +
segments[XSEG]._size;
int rel8 = symbol->address-(reference->pc & ~1);
if (rel8<-256 || rel8>256) {
fprintf (stderr,
- "rel8 target for %s is out of range in module %s\n",
- reference->name, reference->module->name);
+ "rel8 target for %s is out of range in module %s:%d\n",
+ reference->name, reference->module->name,
+ reference->lineno);
fatalErrors++;
}
gsfinalImage[reference->address]=rel8/2;
int rel16 = symbol->address-(reference->pc & ~1);
if (rel16<-65536 || rel16>65534) {
fprintf (stderr,
- "rel16 target for %s is out of range in module %s\n",
- reference->name, reference->module->name);
+ "rel16 target for %s is out of range in module %s:%d\n",
+ reference->name, reference->module->name,
+ reference->lineno);
fatalErrors++;
}
gsfinalImage[reference->address]=(rel16/2)>>8;
break;
}
case DIR_70FF:
- gsfinalImage[reference->address] = (symbol->address<<4)&0x70;
+ gsfinalImage[reference->address] =
+ (gsfinalImage[reference->address]&~0x70) +
+ ((symbol->address>>4)&0x70);
gsfinalImage[reference->address+1] = symbol->address;
break;
case ABS_FFFF:
for (nlp=0; nlp<nlibPaths; nlp++) {
for (nlf=0; nlf<nlibFiles; nlf++) {
sprintf (libFiles, "%s/%s.lib", libraryPaths[nlp], libraryFiles[nlf]);
- //fprintf (stderr, " %s\n", libFiles);
if ((lfs=fopen(libFiles,"r"))==NULL) {
continue;
}
// remove trailing \n
line[strlen(line)-1]='\0';
sprintf (libFile, "%s/%s", libraryPaths[nlp], line);
- //fprintf (stderr, " %s\n", libFile);
- if ((lf=fopen(libFile,"r"))==0) {
+ if ((lf=fopen(libFile,"r"))==NULL) {
continue;
}
while (fgets(line, 132, lf)) {
int dummy; // we need this to get the right count of the next sscanf
if (sscanf(line, "S %[^ ] Def%04x", symName, &dummy)==2) {
if (isUnresolved(symName, 1)) {
- //fprintf (stderr, "%s:%s\n", libFile, symName);
readModule(libFile,1);
if (resolved++ == unresolved) {
// we are done
addToDefs("s_XISEG", 0, 0);
addToDefs("l_XISEG", segments[XISEG]._size, 1);
-#if 1
// mark the resolved references
resolve();
if (unresolved==0) {
writeModule(outFileName);
}
-#endif
// the modules
fprintf (mapOut, "Modules:\n");