/* */
/* */
/* */
-/* (C) 2003 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2003-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-static void ConvertImports (FILE* F, const O65Data* D)
-/* Convert the imports */
-{
- unsigned I;
-
- if (CollCount (&D->Imports) > 0) {
- for (I = 0; I < CollCount (&D->Imports); ++I) {
-
- /* Get the next import */
- const O65Import* Import = CollConstAt (&D->Imports, I);
-
- /* Import it by name */
- fprintf (F, ".import\t%s\n", Import->Name);
- }
- fprintf (F, "\n");
- }
-}
-
-
-
-static void ConvertExports (FILE* F, const O65Data* D)
-/* Convert the exports */
-{
- unsigned I;
-
- if (CollCount (&D->Exports) > 0) {
- for (I = 0; I < CollCount (&D->Exports); ++I) {
-
- /* Get the next import */
- const O65Export* Export = CollConstAt (&D->Exports, I);
-
- /* First define it */
- fprintf (F, "%s = XXX\n", Export->Name); /* ### */
-
- /* Then export it by name */
- fprintf (F, ".export\t%s\n", Export->Name);
- }
- fprintf (F, "\n");
- }
-}
-
-
-
static const char* LabelPlusOffs (const char* Label, long Offs)
/* Generate "Label+xxx" in a static buffer and return a pointer to the buffer */
{
-static const char* RelocExpr (const O65Data* D, const O65Reloc* R, unsigned long Val)
-/* Generate the segment relative relocation expression */
+static const char* RelocExpr (const O65Data* D, unsigned char SegID,
+ unsigned long Val, const O65Reloc* R)
+/* Generate the segment relative relocation expression. R is only used if the
+** expression contains am import, and may be NULL if this is an error (which
+** is then flagged).
+*/
{
const O65Import* Import;
- switch (R->SegID) {
+ switch (SegID) {
case O65_SEGID_UNDEF:
- if (R->SymIdx >= CollCount (&D->Imports)) {
- Error ("Import index out of range (input file corrupt)");
+ if (R) {
+ if (R->SymIdx >= CollCount (&D->Imports)) {
+ Error ("Import index out of range (input file corrupt)");
+ }
+ Import = CollConstAt (&D->Imports, R->SymIdx);
+ return LabelPlusOffs (Import->Name, Val);
+ } else {
+ Error ("Relocation references an import which is not allowed here");
+ return 0;
}
- Import = CollConstAt (&D->Imports, R->SymIdx);
- return LabelPlusOffs (Import->Name, Val);
+ break;
case O65_SEGID_TEXT:
return LabelPlusOffs (CodeLabel, Val - D->Header.tbase);
+static void ConvertImports (FILE* F, const O65Data* D)
+/* Convert the imports */
+{
+ unsigned I;
+
+ if (CollCount (&D->Imports) > 0) {
+ for (I = 0; I < CollCount (&D->Imports); ++I) {
+
+ /* Get the next import */
+ const O65Import* Import = CollConstAt (&D->Imports, I);
+
+ /* Import it by name */
+ fprintf (F, ".import\t%s\n", Import->Name);
+ }
+ fprintf (F, "\n");
+ }
+}
+
+
+
+static void ConvertExports (FILE* F, const O65Data* D)
+/* Convert the exports */
+{
+ unsigned I;
+
+ if (CollCount (&D->Exports) > 0) {
+ for (I = 0; I < CollCount (&D->Exports); ++I) {
+
+ /* Get the next import */
+ const O65Export* Export = CollConstAt (&D->Exports, I);
+
+ /* First define it */
+ fprintf (F, "%s = %s\n",
+ Export->Name,
+ RelocExpr (D, Export->SegID, Export->Val, 0));
+
+ /* Then export it by name */
+ fprintf (F, ".export\t%s\n", Export->Name);
+ }
+ fprintf (F, "\n");
+ }
+}
+
+
+
static void ConvertSeg (FILE* F, const O65Data* D, const Collection* Relocs,
const unsigned char* Data, unsigned long Size)
/* Convert one segment */
} else {
Val = (Data[Byte+1] << 8) + Data[Byte];
Byte += 2;
- fprintf (F, "\t.word\t%s\n", RelocExpr (D, R, Val));
+ fprintf (F, "\t.word\t%s\n", RelocExpr (D, R->SegID, Val, R));
}
break;
case O65_RTYPE_HIGH:
Val = (Data[Byte++] << 8) + R->Val;
- fprintf (F, "\t.byte\t>(%s)\n", RelocExpr (D, R, Val));
+ fprintf (F, "\t.byte\t>(%s)\n", RelocExpr (D, R->SegID, Val, R));
break;
case O65_RTYPE_LOW:
Val = Data[Byte++];
- fprintf (F, "\t.byte\t<(%s)\n", RelocExpr (D, R, Val));
+ fprintf (F, "\t.byte\t<(%s)\n", RelocExpr (D, R->SegID, Val, R));
break;
case O65_RTYPE_SEGADDR:
(((unsigned long) Data[Byte+0]) << 0) +
R->Val;
Byte += 3;
- fprintf (F, "\t.faraddr\t%s\n", RelocExpr (D, R, Val));
+ fprintf (F, "\t.faraddr\t%s\n", RelocExpr (D, R->SegID, Val, R));
}
break;
if (Model == O65_MODEL_CC65_MODULE) {
/* o65 files of type cc65-module are linked together with a definition
- * file for the zero page, but the zero page is not allocated in the
- * module itself, but the locations are mapped to the zp locations of
- * the main file.
- */
+ ** file for the zero page, but the zero page is not allocated in the
+ ** module itself, but the locations are mapped to the zp locations of
+ ** the main file.
+ */
fprintf (F, ".import\t__ZP_START__\t\t; Linker generated symbol\n");
fprintf (F, "%s = __ZP_START__\n", ZeropageLabel);
} else {
/* Header */
- fprintf (F, ".segment\t\"%s\", zeropage\n%s:\n", ZeropageSeg, ZeropageLabel);
+ fprintf (F, ".segment\t\"%s\": zeropage\n%s:\n", ZeropageSeg, ZeropageLabel);
/* Segment data */
fprintf (F, "\t.res\t%lu\n", D->Header.zlen);
-void Convert (const O65Data* D, const char* OutputFile)
+void Convert (const O65Data* D)
/* Convert the o65 file in D using the given output file. */
{
FILE* F;
char* Author = 0;
/* For now, we do only accept o65 files generated by the ld65 linker which
- * have a specific format.
- */
+ ** have a specific format.
+ */
if (!Debug && D->Header.mode != O65_MODE_CC65) {
Error ("Cannot convert o65 files of this type");
}
PrintO65Stats (D);
/* Walk through the options and print them if verbose mode is enabled.
- * Check for a os=cc65 option and bail out if we didn't find one (for
- * now - later we switch to special handling).
- */
+ ** Check for a os=cc65 option and bail out if we didn't find one (for
+ ** now - later we switch to special handling).
+ */
for (I = 0; I < CollCount (&D->Options); ++I) {
/* Get the next option */
case O65_OS_CC65_MODULE:
if (Model != O65_MODEL_NONE &&
Model != O65_MODEL_CC65_MODULE) {
- Warning ("Wrong o65 model");
+ Warning ("Wrong o65 model for input file specified");
} else {
Model = O65_MODEL_CC65_MODULE;
}
}
}
+ /* If we shouldn't generate output, we're done here */
+ if (NoOutput) {
+ return;
+ }
+
/* Open the output file */
- F = fopen (OutputFile, "wb");
+ F = fopen (OutputName, "w");
if (F == 0) {
- Error ("Cannot open `%s': %s", OutputFile, strerror (errno));
+ Error ("Cannot open `%s': %s", OutputName, strerror (errno));
}
/* Create a header */
- fprintf (F, ";\n; File generated by co65 v %u.%u.%u using model `%s'\n;\n",
- VER_MAJOR, VER_MINOR, VER_PATCH, GetModelName (Model));
+ fprintf (F, ";\n; File generated by co65 v %s using model `%s'\n;\n",
+ GetVersionAsString (), GetModelName (Model));
/* Select the CPU */
if ((D->Header.mode & O65_CPU_MASK) == O65_CPU_65816) {
- fprintf (F, ".p816\n");
+ fprintf (F, ".p816\n");
}
/* Object file options */
- fprintf (F, ".fopt\t\tcompiler,\"co65 v %u.%u.%u\"\n",
- VER_MAJOR, VER_MINOR, VER_PATCH);
+ fprintf (F, ".fopt\t\tcompiler,\"co65 v %s\"\n", GetVersionAsString ());
if (Author) {
fprintf (F, ".fopt\t\tauthor, \"%s\"\n", Author);
xfree (Author);
fprintf (F, ".end\n");
fclose (F);
}
-
-
-