X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fconfig.c;h=f8bff2ac050fa5b5008e9d5b8b4be4d359f2fd55;hb=b03ae76b54d77f435088cacf12d3cfd9873f05ed;hp=a5d6ff39ba53ecbc6ecde46b5ed228584e529ced;hpb=752141b026e48c690d7ba3474835c25749a23d95;p=cc65 diff --git a/src/ld65/config.c b/src/ld65/config.c index a5d6ff39b..f8bff2ac0 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -68,6 +68,7 @@ #include "objdata.h" #include "scanner.h" #include "spool.h" +#include "xex.h" @@ -131,9 +132,9 @@ typedef enum { } CfgSymType; /* Symbol structure. It is used for o65 imports and exports, but also for - * symbols from the SYMBOLS sections (symbols defined in the config file or - * forced imports). - */ +** symbols from the SYMBOLS sections (symbols defined in the config file or +** forced imports). +*/ typedef struct CfgSymbol CfgSymbol; struct CfgSymbol { CfgSymType Type; /* Type of symbol */ @@ -149,6 +150,7 @@ static Collection CfgSymbols = STATIC_COLLECTION_INITIALIZER; /* Descriptor holding information about the binary formats */ static BinDesc* BinFmtDesc = 0; static O65Desc* O65FmtDesc = 0; +static XexDesc* XexFmtDesc = 0; @@ -226,7 +228,7 @@ static MemoryArea* CfgGetMemory (unsigned Name) { MemoryArea* M = CfgFindMemory (Name); if (M == 0) { - CfgError (&CfgErrorPos, "Invalid memory area `%s'", GetString (Name)); + CfgError (&CfgErrorPos, "Invalid memory area '%s'", GetString (Name)); } return M; } @@ -268,9 +270,9 @@ static void MemoryInsert (MemoryArea* M, SegDesc* S) static CfgSymbol* NewCfgSymbol (CfgSymType Type, unsigned Name) /* Create a new CfgSymbol structure with the given type and name. The - * current config file position is recorded in the returned struct. The - * created struct is inserted into the CfgSymbols collection and returned. - */ +** current config file position is recorded in the returned struct. The +** created struct is inserted into the CfgSymbols collection and returned. +*/ { /* Allocate memory */ CfgSymbol* Sym = xmalloc (sizeof (CfgSymbol)); @@ -320,7 +322,7 @@ static MemoryArea* CreateMemoryArea (const FilePos* Pos, unsigned Name) MemoryArea* M = CfgFindMemory (Name); if (M) { CfgError (&CfgErrorPos, - "Memory area `%s' defined twice", + "Memory area '%s' defined twice", GetString (Name)); } @@ -343,7 +345,7 @@ static SegDesc* NewSegDesc (unsigned Name) /* Check for duplicate names */ SegDesc* S = CfgFindSegDesc (Name); if (S) { - CfgError (&CfgErrorPos, "Segment `%s' defined twice", GetString (Name)); + CfgError (&CfgErrorPos, "Segment '%s' defined twice", GetString (Name)); } /* Allocate memory */ @@ -385,8 +387,8 @@ static void FreeSegDesc (SegDesc* S) static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name) /* Check if the item is already defined. Print an error if so. If not, set - * the marker that we have a definition now. - */ +** the marker that we have a definition now. +*/ { if (*Flags & Mask) { CfgError (&CfgErrorPos, "%s is already defined", Name); @@ -522,8 +524,8 @@ static void ParseMemory (void) AttrCheck (M->Attr, MA_SIZE, "SIZE"); /* If we don't have a file name for output given, use the default - * file name. - */ + ** file name. + */ if ((M->Attr & MA_FILE) == 0) { FileInsert (GetFile (GetStringId (OutputName)), M); OutputNameUsed = 1; @@ -543,6 +545,7 @@ static void ParseFiles (void) { "FORMAT", CFGTOK_FORMAT }, }; static const IdentTok Formats [] = { + { "ATARI", CFGTOK_ATARIEXE }, { "O65", CFGTOK_O65 }, { "BIN", CFGTOK_BIN }, { "BINARY", CFGTOK_BIN }, @@ -566,7 +569,7 @@ static void ParseFiles (void) F = FindFile (GetStrBufId (&CfgSVal)); if (F == 0) { CfgError (&CfgErrorPos, - "File `%s' not found in MEMORY section", + "File '%s' not found in MEMORY section", SB_GetConstBuf (&CfgSVal)); } @@ -607,6 +610,10 @@ static void ParseFiles (void) F->Format = BINFMT_O65; break; + case CFGTOK_ATARIEXE: + F->Format = BINFMT_ATARIEXE; + break; + default: Error ("Unexpected format token"); } @@ -653,6 +660,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, + { "OVERWRITE", CFGTOK_OVERWRITE }, }; unsigned Count; @@ -753,11 +761,12 @@ static void ParseSegments (void) FlagAttr (&S->Attr, SA_TYPE, "TYPE"); CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type"); switch (CfgTok) { - case CFGTOK_RO: S->Flags |= SF_RO; break; - case CFGTOK_RW: /* Default */ break; - case CFGTOK_BSS: S->Flags |= SF_BSS; break; - case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; - default: Internal ("Unexpected token: %d", CfgTok); + case CFGTOK_RO: S->Flags |= SF_RO; break; + case CFGTOK_RW: /* Default */ break; + case CFGTOK_BSS: S->Flags |= SF_BSS; break; + case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_OVERWRITE: S->Flags |= (SF_OVERWRITE | SF_RO); break; + default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); break; @@ -781,8 +790,8 @@ static void ParseSegments (void) } /* An attribute of ALIGN_LOAD doesn't make sense if there are no - * separate run and load memory areas. - */ + ** separate run and load memory areas. + */ if ((S->Flags & SF_ALIGN_LOAD) != 0 && (S->Load == S->Run)) { CfgWarning (&CfgErrorPos, "ALIGN_LOAD attribute specified, but no separate " @@ -792,11 +801,11 @@ static void ParseSegments (void) } /* If the segment is marked as BSS style, it may not have separate - * load and run memory areas, because it's is never written to disk. - */ + ** load and run memory areas, because it's is never written to disk. + */ if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) { CfgWarning (&CfgErrorPos, - "Segment with type `bss' has both LOAD and RUN " + "Segment with type 'bss' has both LOAD and RUN " "memory areas assigned"); } @@ -804,7 +813,7 @@ static void ParseSegments (void) if ((S->Flags & SF_RO) == 0) { if (S->Run->Flags & MF_RO) { CfgError (&CfgErrorPos, - "Cannot put r/w segment `%s' in r/o memory area `%s'", + "Cannot put r/w segment '%s' in r/o memory area '%s'", GetString (S->Name), GetString (S->Run->Name)); } } @@ -930,8 +939,8 @@ static void ParseO65 (void) /* Cannot use this attribute twice */ FlagAttr (&AttrFlags, atOS, "OS"); /* Get the operating system. It may be specified as name or - * as a number in the range 1..255. - */ + ** as a number in the range 1..255. + */ if (CfgTok == CFGTOK_INTCON) { CfgRangeCheck (O65OS_MIN, O65OS_MAX); OS = (unsigned) CfgIVal; @@ -993,6 +1002,87 @@ static void ParseO65 (void) +static void ParseXex (void) +/* Parse the o65 format section */ +{ + static const IdentTok Attributes [] = { + { "RUNAD", CFGTOK_RUNAD }, + { "INITAD", CFGTOK_INITAD }, + }; + + /* Remember the attributes read */ + /* Bitmask to remember the attributes we got already */ + enum { + atNone = 0x0000, + atRunAd = 0x0001, + }; + unsigned AttrFlags = atNone; + Import *RunAd = 0; + Import *InitAd; + MemoryArea *InitMem; + + /* Read the attributes */ + while (CfgTok == CFGTOK_IDENT) { + + /* Map the identifier to a token */ + cfgtok_t AttrTok; + CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute"); + AttrTok = CfgTok; + + /* An optional assignment follows */ + CfgNextTok (); + CfgOptionalAssign (); + + /* Check which attribute was given */ + switch (AttrTok) { + + case CFGTOK_RUNAD: + /* Cannot have this attribute twice */ + FlagAttr (&AttrFlags, atRunAd, "RUNAD"); + /* We expect an identifier */ + CfgAssureIdent (); + /* Generate an import for the symbol */ + RunAd = InsertImport (GenImport (GetStrBufId (&CfgSVal), ADDR_SIZE_ABS)); + /* Remember the file position */ + CollAppend (&RunAd->RefLines, GenLineInfo (&CfgErrorPos)); + /* Eat the identifier token */ + CfgNextTok (); + break; + + case CFGTOK_INITAD: + /* We expect a memory area followed by a colon and an identifier */ + CfgAssureIdent (); + InitMem = CfgGetMemory (GetStrBufId (&CfgSVal)); + CfgNextTok (); + CfgConsumeColon (); + CfgAssureIdent (); + /* Generate an import for the symbol */ + InitAd = InsertImport (GenImport (GetStrBufId (&CfgSVal), ADDR_SIZE_ABS)); + /* Remember the file position */ + CollAppend (&InitAd->RefLines, GenLineInfo (&CfgErrorPos)); + /* Eat the identifier token */ + CfgNextTok (); + /* Add to XEX */ + if (XexAddInitAd (XexFmtDesc, InitMem, InitAd)) + CfgError (&CfgErrorPos, "INITAD already given for memory area"); + break; + + default: + FAIL ("Unexpected attribute token"); + + } + + /* Skip an optional comma */ + CfgOptionalComma (); + } + + /* Set the RUNAD import if we have one */ + if ( RunAd ) + XexSetRunAd (XexFmtDesc, RunAd); +} + + + static void ParseFormats (void) /* Parse a target format section */ { @@ -1000,6 +1090,7 @@ static void ParseFormats (void) { "O65", CFGTOK_O65 }, { "BIN", CFGTOK_BIN }, { "BINARY", CFGTOK_BIN }, + { "ATARI", CFGTOK_ATARIEXE }, }; while (CfgTok == CFGTOK_IDENT) { @@ -1020,6 +1111,10 @@ static void ParseFormats (void) ParseO65 (); break; + case CFGTOK_ATARIEXE: + ParseXex (); + break; + case CFGTOK_BIN: /* No attribibutes available */ break; @@ -1266,8 +1361,8 @@ static void ParseStartAddress (void) AttrCheck (AttrFlags, atDefault, "DEFAULT"); /* If no start address was given on the command line, use the one given - * here - */ + ** here + */ if (!HaveStartAddr) { StartAddr = DefStartAddr; } @@ -1509,7 +1604,7 @@ static void ParseConfig (void) CfgNextTok (); /* Expected a curly brace */ - CfgConsume (CFGTOK_LCURLY, "`{' expected"); + CfgConsume (CFGTOK_LCURLY, "'{' expected"); /* Read the block */ switch (BlockTok) { @@ -1544,7 +1639,7 @@ static void ParseConfig (void) } /* Skip closing brace */ - CfgConsume (CFGTOK_RCURLY, "`}' expected"); + CfgConsume (CFGTOK_RCURLY, "'}' expected"); } while (CfgTok != CFGTOK_EOF); } @@ -1557,10 +1652,11 @@ void CfgRead (void) /* Create the descriptors for the binary formats */ BinFmtDesc = NewBinDesc (); O65FmtDesc = NewO65Desc (); + XexFmtDesc = NewXexDesc (); /* If we have a config name given, open the file, otherwise we will read - * from a buffer. - */ + ** from a buffer. + */ CfgOpenInput (); /* Parse the file */ @@ -1591,25 +1687,25 @@ static void ProcessSegments (void) SegDesc* S = CollAtUnchecked (&SegDescList, I); /* Search for the actual segment in the input files. The function may - * return NULL (no such segment), this is checked later. - */ + ** return NULL (no such segment), this is checked later. + */ S->Seg = SegFind (S->Name); /* If the segment is marked as BSS style, and if the segment exists - * in any of the object file, check that there's no initialized data - * in the segment. - */ + ** in any of the object file, check that there's no initialized data + ** in the segment. + */ if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) { CfgWarning (GetSourcePos (S->LI), - "Segment `%s' with type `bss' contains initialized data", + "Segment '%s' with type 'bss' contains initialized data", GetString (S->Name)); } /* If this segment does exist in any of the object files, insert the - * segment into the load/run memory areas. Otherwise print a warning - * and discard it, because the segment pointer in the descriptor is - * invalid. - */ + ** segment into the load/run memory areas. Otherwise print a warning + ** and discard it, because the segment pointer in the descriptor is + ** invalid. + */ if (S->Seg != 0) { /* Insert the segment into the memory area list */ @@ -1630,7 +1726,7 @@ static void ProcessSegments (void) /* Print a warning if the segment is not optional */ if ((S->Flags & SF_OPTIONAL) == 0) { CfgWarning (&CfgErrorPos, - "Segment `%s' does not exist", + "Segment '%s' does not exist", GetString (S->Name)); } @@ -1663,19 +1759,19 @@ static void ProcessSymbols (void) if (O65GetImport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Exported o65 symbol `%s' cannot also be an o65 import", + "Exported o65 symbol '%s' cannot also be an o65 import", GetString (Sym->Name) ); } /* Check if we have this symbol defined already. The entry - * routine will check this also, but we get a more verbose - * error message when checking it here. - */ + ** routine will check this also, but we get a more verbose + ** error message when checking it here. + */ if (O65GetExport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Duplicate exported o65 symbol: `%s'", + "Duplicate exported o65 symbol: '%s'", GetString (Sym->Name) ); } @@ -1689,19 +1785,19 @@ static void ProcessSymbols (void) if (O65GetExport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Imported o65 symbol `%s' cannot also be an o65 export", + "Imported o65 symbol '%s' cannot also be an o65 export", GetString (Sym->Name) ); } /* Check if we have this symbol defined already. The entry - * routine will check this also, but we get a more verbose - * error message when checking it here. - */ + ** routine will check this also, but we get a more verbose + ** error message when checking it here. + */ if (O65GetImport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Duplicate imported o65 symbol: `%s'", + "Duplicate imported o65 symbol: '%s'", GetString (Sym->Name) ); } @@ -1769,33 +1865,33 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr) unsigned CfgProcess (void) -/* Process the config file after reading in object files and libraries. This - * includes postprocessing of the config file data but also assigning segments - * and defining segment/memory area related symbols. The function will return - * the number of memory area overflows (so zero means anything went ok). - * In case of overflows, a short mapfile can be generated later, to ease the - * task of rearranging segments for the user. - */ +/* Process the config file, after reading in object files and libraries. This +** includes postprocessing of the config file data; but also assigning segments, +** and defining segment/memory-area related symbols. The function will return +** the number of memory area overflows (so, zero means everything went OK). +** In case of overflows, a short mapfile can be generated later, to ease the +** user's task of re-arranging segments. +*/ { unsigned Overflows = 0; unsigned I; /* Postprocess symbols. We must do that first, since weak symbols are - * defined here, which may be needed later. - */ + ** defined here, which may be needed later. + */ ProcessSymbols (); /* Postprocess segments */ ProcessSegments (); - /* Walk through each of the memory sections. Add up the sizes and check - * for an overflow of the section. Assign the start addresses of the - * segments while doing this. - */ + /* Walk through each of the memory sections. Add up the sizes; and, check + ** for an overflow of the section. Assign the start addresses of the + ** segments while doing that. + */ for (I = 0; I < CollCount (&MemoryAreas); ++I) { - unsigned J; unsigned long Addr; + unsigned Overwrites = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1806,21 +1902,21 @@ unsigned CfgProcess (void) /* Remember if this is a relocatable memory area */ M->Relocatable = RelocatableBinFmt (M->F->Format); - /* Resolve the start address expression, remember the start address - * and mark the memory area as placed. - */ + /* Resolve the start address expression, remember the start address, + ** and mark the memory area as placed. + */ if (!IsConstExpr (M->StartExpr)) { CfgError (GetSourcePos (M->LI), - "Start address of memory area `%s' is not constant", + "Start address of memory area '%s' is not constant", GetString (M->Name)); } Addr = M->Start = GetExprVal (M->StartExpr); M->Flags |= MF_PLACED; /* If requested, define the symbol for the start of the memory area. - * Doing it here means that the expression for the size of the area - * may reference this symbol. - */ + ** Doing it here means that the expression for the size of the area + ** may reference this symbol. + */ if (M->Flags & MF_DEFINE) { Export* E; StrBuf Buf = STATIC_STRBUF_INITIALIZER; @@ -1836,117 +1932,168 @@ unsigned CfgProcess (void) /* Resolve the size expression */ if (!IsConstExpr (M->SizeExpr)) { CfgError (GetSourcePos (M->LI), - "Size of memory area `%s' is not constant", + "Size of memory area '%s' is not constant", GetString (M->Name)); } M->Size = GetExprVal (M->SizeExpr); /* Walk through the segments in this memory area */ for (J = 0; J < CollCount (&M->SegList); ++J) { - /* Get the segment */ SegDesc* S = CollAtUnchecked (&M->SegList, J); /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; - /* Some actions depend on wether this is the load or run memory - * area. - */ - if (S->Run == M) { + /* Take note of "overwrite" segments and make sure there are no + ** other segment types following them in current memory region. + */ + if (S->Flags & SF_OVERWRITE) { + if (S->Flags & (SF_OFFSET | SF_START)) { + ++Overwrites; + } else { + CfgError (GetSourcePos (M->LI), + "Segment '%s' of type 'overwrite' requires either" + " 'Start' or 'Offset' attribute to be specified", + GetString (S->Name)); + } + } else { + if (Overwrites > 0) { + CfgError (GetSourcePos (M->LI), + "Segment '%s' is preceded by at least one segment" + " of type 'overwrite'", + GetString (S->Name)); + } + } + /* Some actions depend on whether this is the load or run memory + ** area. + */ + if (S->Run == M) { /* This is the run (and maybe load) memory area. Handle - * alignment and explict start address and offset. - */ + ** alignment and explict start address and offset. + */ + + /* Check if the alignment for the segment from the linker + ** config is a multiple for that of the segment. + ** If START or OFFSET is provided instead of ALIGN, check + ** if its address fits alignment requirements. + */ + unsigned long AlignedBy = (S->Flags & SF_START) ? S->Addr + : (S->Flags & SF_OFFSET) ? (S->Addr + M->Start) + : S->RunAlignment; + if ((AlignedBy % S->Seg->Alignment) != 0) { + /* Segment requires another alignment than configured + ** in the linker. + */ + CfgWarning (GetSourcePos (S->LI), + "Segment '%s' isn't aligned properly; the" + " resulting executable might not be functional.", + GetString (S->Name)); + } + if (S->Flags & SF_ALIGN) { /* Align the address */ unsigned long NewAddr = AlignAddr (Addr, S->RunAlignment); /* If the first segment placed in the memory area needs - * fill bytes for the alignment, emit a warning, since - * this is somewhat suspicious. - */ + ** fill bytes for the alignment, emit a warning, since + ** that is somewhat suspicious. + */ if (M->FillLevel == 0 && NewAddr > Addr) { CfgWarning (GetSourcePos (S->LI), - "First segment in memory area `%s' does " - "already need fill bytes for alignment", + "The first segment in memory area '%s' " + "needs fill bytes for alignment.", GetString (M->Name)); } /* Use the aligned address */ Addr = NewAddr; - } else if (S->Flags & (SF_OFFSET | SF_START)) { + } else if ((S->Flags & (SF_OFFSET | SF_START)) != 0 && + (M->Flags & MF_OVERFLOW) == 0) { /* Give the segment a fixed starting address */ unsigned long NewAddr = S->Addr; + if (S->Flags & SF_OFFSET) { /* An offset was given, no address, make an address */ NewAddr += M->Start; } - if (Addr > NewAddr) { - /* Offset already too large */ - if (S->Flags & SF_OFFSET) { - CfgError (GetSourcePos (M->LI), - "Offset too small in `%s', segment `%s'", - GetString (M->Name), - GetString (S->Name)); + + if (S->Flags & SF_OVERWRITE) { + if (NewAddr < M->Start) { + CfgError (GetSourcePos (S->LI), + "Segment '%s' begins before memory area '%s'", + GetString (S->Name), GetString (M->Name)); } else { - CfgError (GetSourcePos (M->LI), - "Start address too low in `%s', segment `%s'", - GetString (M->Name), - GetString (S->Name)); + Addr = NewAddr; + } + } else { + if (NewAddr < Addr) { + /* Offset already too large */ + ++Overflows; + if (S->Flags & SF_OFFSET) { + CfgWarning (GetSourcePos (S->LI), + "Segment '%s' offset is too small in '%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + } else { + CfgWarning (GetSourcePos (S->LI), + "Segment '%s' start address is too low in '%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + } + } else { + Addr = NewAddr; } } - Addr = NewAddr; } /* Set the start address of this segment, set the readonly flag - * in the segment and and remember if the segment is in a - * relocatable file or not. - */ + ** in the segment, and remember if the segment is in a + ** relocatable file or not. + */ S->Seg->PC = Addr; S->Seg->ReadOnly = (S->Flags & SF_RO) != 0; /* Remember the run memory for this segment, which is also a - * flag that the segment has been placed. - */ + ** flag that the segment has been placed. + */ S->Seg->MemArea = M; } else if (S->Load == M) { - - /* This is the load memory area, *and* run and load are - * different (because of the "else" above). Handle alignment. - */ + /* This is the load memory area; *and*, run and load are + ** different (because of the "else" above). Handle alignment. + */ if (S->Flags & SF_ALIGN_LOAD) { /* Align the address */ Addr = AlignAddr (Addr, S->LoadAlignment); } - } - /* If this is the load memory area and the segment doesn't have a - * fill value defined, use the one from the memory area. - */ + /* If this is the load memory area, and the segment doesn't have a + ** fill value defined, use the one from the memory area. + */ if (S->Load == M && (S->Flags & SF_FILLVAL) == 0) { S->Seg->FillVal = M->FillVal; } - /* Increment the fill level of the memory area and check for an - * overflow. - */ + /* Increment the fill level of the memory area; and, check for an + ** overflow. + */ M->FillLevel = Addr + S->Seg->Size - M->Start; if (M->FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) { ++Overflows; M->Flags |= MF_OVERFLOW; CfgWarning (GetSourcePos (M->LI), - "Memory area overflow in `%s', segment `%s' (%lu bytes)", - GetString (M->Name), GetString (S->Name), - M->FillLevel - M->Size); + "Segment '%s' overflows memory area '%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + M->FillLevel - M->Size, (M->FillLevel - M->Size == 1) ? ' ' : 's'); } /* If requested, define symbols for the start and size of the - * segment. - */ + ** segment. + */ if (S->Flags & SF_DEFINE) { if (S->Run == M && (S->Flags & SF_RUN_DEF) == 0) { CreateRunDefines (S, Addr); @@ -1960,18 +2107,17 @@ unsigned CfgProcess (void) Addr += S->Seg->Size; /* If this segment will go out to the file, or its place - * in the file will be filled, then increase the file size. - */ + ** in the file will be filled, then increase the file size. + */ if (S->Load == M && ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0)) { M->F->Size += Addr - StartAddr; } - } - /* If requested, define symbols for start, size and offset of the - * memory area - */ + /* If requested, define symbols for start, size, and offset of the + ** memory area + */ if (M->Flags & MF_DEFINE) { Export* E; StrBuf Buf = STATIC_STRBUF_INITIALIZER; @@ -1987,8 +2133,8 @@ unsigned CfgProcess (void) CollAppend (&E->DefLines, M->LI); /* Define the file offset of the memory area. This isn't of much - * use for relocatable output files. - */ + ** use for relocatable output files. + */ if (!M->Relocatable) { SB_Printf (&Buf, "__%s_FILEOFFS__", GetString (M->Name)); E = CreateConstExport (GetStrBufId (&Buf), M->FileOffs); @@ -1999,9 +2145,9 @@ unsigned CfgProcess (void) SB_Done (&Buf); } - /* If we didn't have an overflow and are requested to fill the memory - * area, acount for that in the file size. - */ + /* If we didn't have an overflow, and are requested to fill the memory + ** area, account for that in the file size. + */ if ((M->Flags & MF_OVERFLOW) == 0 && (M->Flags & MF_FILL) != 0) { M->F->Size += (M->Size - M->FillLevel); } @@ -2046,6 +2192,10 @@ void CfgWriteTarget (void) O65WriteTarget (O65FmtDesc, F); break; + case BINFMT_ATARIEXE: + XexWriteTarget (XexFmtDesc, F); + break; + default: Internal ("Invalid binary format: %u", F->Format); @@ -2054,8 +2204,8 @@ void CfgWriteTarget (void) } else { /* No output file. Walk through the list and mark all segments - * loading into these memory areas in this file as dumped. - */ + ** loading into these memory areas in this file as dumped. + */ unsigned J; for (J = 0; J < CollCount (&F->MemoryAreas); ++J) { @@ -2065,7 +2215,7 @@ void CfgWriteTarget (void) MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, J); /* Debugging */ - Print (stdout, 2, "Skipping `%s'...\n", GetString (M->Name)); + Print (stdout, 2, "Skipping '%s'...\n", GetString (M->Name)); /* Walk throught the segments */ for (K = 0; K < CollCount (&M->SegList); ++K) { @@ -2080,6 +2230,3 @@ void CfgWriteTarget (void) } } } - - -