/* */
/* */
/* */
-/* (C) 1999-2003 Ullrich von Bassewitz */
-/* Römerstraße 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1999-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "fileio.h"
#include "global.h"
#include "lineinfo.h"
+#include "memarea.h"
#include "o65.h"
#include "spool.h"
};
/* A o65 relocation table */
-#define RELOC_BLOCKSIZE 4096
typedef struct O65RelocTab O65RelocTab;
struct O65RelocTab {
unsigned Size; /* Size of the table */
O65Desc* D; /* File format descriptor */
long Val; /* The offset value */
int TooComplex; /* Expression too complex */
- Memory* MemRef; /* Memory reference if any */
+ MemoryArea* MemRef; /* Memory reference if any */
Segment* SegRef; /* Segment reference if any */
Section* SecRef; /* Section reference if any */
ExtSym* ExtRef; /* External reference if any */
*/
{
/* Get the memory area from the expression */
- Memory* M = ED->MemRef;
-
- /* Get the list of segments in this memory area */
- MemListNode* N = M->SegList;
+ MemoryArea* M = ED->MemRef;
/* Remember the "nearest" segment and its offset */
Segment* Nearest = 0;
unsigned long Offs = ULONG_MAX;
/* Walk over all segments */
- while (N != 0) {
+ unsigned I;
+ for (I = 0; I < CollCount (&M->SegList); ++I) {
- /* Get the segment from this node and check if it's a run segment */
- SegDesc* S = N->Seg;
+ /* Get the segment and check if it's a run segment */
+ SegDesc* S = CollAtUnchecked (&M->SegList, I);
if (S->Run == M) {
unsigned long O;
}
}
}
-
- /* Next segment */
- N = N->Next;
}
/* If we found a segment, use it and adjust the offset */
switch (Expr->Op) {
case EXPR_LITERAL:
- D->Val += (Sign * Expr->V.Val);
+ D->Val += (Sign * Expr->V.IVal);
break;
case EXPR_SYMBOL:
/* Do we have enough space in the buffer? */
if (R->Fill == R->Size) {
/* We need to grow the buffer */
- unsigned char* NewBuf = xmalloc (R->Size + RELOC_BLOCKSIZE);
- memcpy (NewBuf, R->Buf, R->Size);
- xfree (R->Buf);
- R->Buf = NewBuf;
+ if (R->Size) {
+ R->Size *= 2;
+ } else {
+ R->Size = 1024; /* Initial size */
+ }
+ R->Buf = xrealloc (R->Buf, R->Size);
}
/* Put the byte into the buffer */
/* Write this segment */
if (DoWrite) {
- RelocLineInfo (S->Seg);
- SegWrite (D->F, S->Seg, O65WriteExpr, D);
+ SegWrite (D->Filename, D->F, S->Seg, O65WriteExpr, D);
}
/* Mark the segment as dumped */
-void O65SetAlignment (O65Desc* D, unsigned Align)
+void O65SetAlignment (O65Desc* D, unsigned Alignment)
/* Set the executable alignment */
{
/* Remove all alignment bits from the mode word */
D->Header.Mode &= ~MF_ALIGN_MASK;
/* Set the alignment bits */
- switch (Align) {
+ switch (Alignment) {
case 1: D->Header.Mode |= MF_ALIGN_1; break;
case 2: D->Header.Mode |= MF_ALIGN_2; break;
case 4: D->Header.Mode |= MF_ALIGN_4; break;
case 256: D->Header.Mode |= MF_ALIGN_256; break;
- default: Error ("Invalid alignment for O65 format: %u", Align);
+ default: Error ("Invalid alignment for O65 format: %u", Alignment);
}
}
/* Write the correct option length */
switch (OS) {
- case O65OS_OSA65:
- case O65OS_LUNIX:
- /* No id for these two */
- O65SetOption (D, O65OPT_OS, Opt, 2);
- break;
case O65OS_CC65:
/* Set the 16 bit id */
break;
default:
- Internal ("Trying to set invalid O65 operating system: %u", OS);
+ /* No id for OS/A65, Lunix, and unknown OSes */
+ O65SetOption (D, O65OPT_OS, Opt, 2);
+ break;
+
}
}
static void O65SetupSegments (O65Desc* D, File* F)
/* Setup segment assignments */
{
- Memory* M;
- MemListNode* N;
- SegDesc* S;
+ unsigned I;
unsigned TextIdx, DataIdx, BssIdx, ZPIdx;
/* Initialize the counters */
D->ZPCount = 0;
/* Walk over the memory list */
- M = F->MemList;
- while (M) {
+ for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
+ /* Get this entry */
+ MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
+
/* Walk through the segment list and count the segment types */
- N = M->SegList;
- while (N) {
+ unsigned J;
+ for (J = 0; J < CollCount (&M->SegList); ++J) {
- /* Get the segment from the list node */
- S = N->Seg;
+ /* Get the segment */
+ SegDesc* S = CollAtUnchecked (&M->SegList, J);
/* Check the segment type. */
switch (O65SegType (S)) {
case O65SEG_DATA: D->DataCount++; break;
case O65SEG_BSS: D->BssCount++; break;
case O65SEG_ZP: D->ZPCount++; break;
- default: Internal ("Invalid return from O65SegType");
+ default: Internal ("Invalid return from O65SegType");
}
-
- /* Next segment node */
- N = N->Next;
}
- /* Next memory area */
- M = M->FNext;
}
/* Allocate memory according to the numbers */
/* Walk again through the list and setup the segment arrays */
TextIdx = DataIdx = BssIdx = ZPIdx = 0;
- M = F->MemList;
- while (M) {
+ for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
+ /* Get this entry */
+ MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
- N = M->SegList;
- while (N) {
+ /* Walk over the segment list and check the segment types */
+ unsigned J;
+ for (J = 0; J < CollCount (&M->SegList); ++J) {
- /* Get the segment from the list node */
- S = N->Seg;
+ /* Get the segment */
+ SegDesc* S = CollAtUnchecked (&M->SegList, J);
/* Check the segment type. */
switch (O65SegType (S)) {
case O65SEG_ZP: D->ZPSeg [ZPIdx++] = S; break;
default: Internal ("Invalid return from O65SegType");
}
-
- /* Next segment node */
- N = N->Next;
}
- /* Next memory area */
- M = M->FNext;
}
}
* if we get an unresolved symbol.
*/
D->Undef = 0; /* Reset the counter */
- CheckExports (O65Unresolved, D);
+ CheckUnresolvedImports (O65Unresolved, D);
if (D->Undef > 0) {
/* We had unresolved symbols, cannot create output file */
Error ("%u unresolved external(s) found - cannot create output file", D->Undef);
}
OptBuf[OptLen] = '\0';
O65SetOption (D, O65OPT_TIMESTAMP, OptBuf, OptLen + 1);
- sprintf (OptBuf, "ld65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
+ sprintf (OptBuf, "ld65 V%s", GetVersionAsString ());
O65SetOption (D, O65OPT_ASM, OptBuf, strlen (OptBuf) + 1);
/* Write the header */