Merge branch 'cc65:master' into master
This commit is contained in:
@@ -38,7 +38,7 @@ The default load address is $1903.
|
|||||||
Programs containing Agat-specific code may use the <tt/agat.h/ or
|
Programs containing Agat-specific code may use the <tt/agat.h/ or
|
||||||
<tt/agat.inc/ include files.
|
<tt/agat.inc/ include files.
|
||||||
|
|
||||||
<sect>Usefull info<p>
|
<sect>Useful info<p>
|
||||||
|
|
||||||
<sect1>Emulation<p>
|
<sect1>Emulation<p>
|
||||||
|
|
||||||
|
|||||||
@@ -3192,7 +3192,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
|||||||
|
|
||||||
This feature makes relocatable/absolute mode local to the current segment.
|
This feature makes relocatable/absolute mode local to the current segment.
|
||||||
Using <tt><ref id=".ORG" name=".ORG"></tt> when <tt/org_per_seg/ is in
|
Using <tt><ref id=".ORG" name=".ORG"></tt> when <tt/org_per_seg/ is in
|
||||||
effect will only enable absolute mode for the current segment. Dito for
|
effect will only enable absolute mode for the current segment. Ditto for
|
||||||
<tt><ref id=".RELOC" name=".RELOC"></tt>.
|
<tt><ref id=".RELOC" name=".RELOC"></tt>.
|
||||||
|
|
||||||
<tag><tt>pc_assignment</tt><label id="pc_assignment"></tag>
|
<tag><tt>pc_assignment</tt><label id="pc_assignment"></tag>
|
||||||
@@ -3792,8 +3792,8 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"
|
|||||||
<sect1><tt>.LOCAL</tt><label id=".LOCAL"><p>
|
<sect1><tt>.LOCAL</tt><label id=".LOCAL"><p>
|
||||||
|
|
||||||
This command may only be used inside a macro definition. It declares a list
|
This command may only be used inside a macro definition. It declares a list
|
||||||
of identifiers as local to the macro expansion. The identifers may be
|
of identifiers as local to the macro expansion. The identifiers may be
|
||||||
standard identifiers or cheap local identifiers depending on the planed use.
|
standard identifiers or cheap local identifiers depending on the planned use.
|
||||||
|
|
||||||
A problem when using macros are labels: Since they don't change their name,
|
A problem when using macros are labels: Since they don't change their name,
|
||||||
you get a "duplicate symbol" error if the macro is expanded the second time.
|
you get a "duplicate symbol" error if the macro is expanded the second time.
|
||||||
|
|||||||
@@ -728,7 +728,7 @@ ExpandParam:
|
|||||||
|
|
||||||
/* Use next macro token */
|
/* Use next macro token */
|
||||||
TokSet (Mac->Exp);
|
TokSet (Mac->Exp);
|
||||||
if (ExpandMacros) {
|
if (ExpandMacros && SB_GetLen (&ListingName) > 0) {
|
||||||
if (new_expand_line) {
|
if (new_expand_line) {
|
||||||
/* Suppress unneeded lines if short expansion
|
/* Suppress unneeded lines if short expansion
|
||||||
** the ExpandStart is used to ensure that
|
** the ExpandStart is used to ensure that
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ static int ReplayTokList (void* List)
|
|||||||
|
|
||||||
/* see description in macro.c */
|
/* see description in macro.c */
|
||||||
static int new_expand_line = 1;
|
static int new_expand_line = 1;
|
||||||
if (ExpandMacros) {
|
if (ExpandMacros && SB_GetLen (&ListingName) > 0) {
|
||||||
if (new_expand_line) {
|
if (new_expand_line) {
|
||||||
if (LineLast->FragList == 0 && ExpandMacros==1) {
|
if (LineLast->FragList == 0 && ExpandMacros==1) {
|
||||||
LineCur->Output--;
|
LineCur->Output--;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ const char* GT_AsString (const StrBuf* Type, StrBuf* String)
|
|||||||
** will be zero terminated and a pointer to the contents are returned.
|
** will be zero terminated and a pointer to the contents are returned.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static const char HexTab[16] = "0123456789ABCDEF";
|
static const char HexTab[] = "0123456789ABCDEF";
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Convert Type into readable hex. String will have twice then length
|
/* Convert Type into readable hex. String will have twice then length
|
||||||
|
|||||||
@@ -88,16 +88,46 @@ static unsigned LibFiles = 0; /* Count of library files linked */
|
|||||||
#define INPUT_FILES_SGROUP 3 /* Entry is 'StartGroup' */
|
#define INPUT_FILES_SGROUP 3 /* Entry is 'StartGroup' */
|
||||||
#define INPUT_FILES_EGROUP 4 /* Entry is 'EndGroup' */
|
#define INPUT_FILES_EGROUP 4 /* Entry is 'EndGroup' */
|
||||||
|
|
||||||
#define MAX_INPUTFILES 256
|
|
||||||
|
|
||||||
/* Array of inputs (libraries and object files) */
|
/* Array of inputs (libraries and object files) */
|
||||||
static struct InputFile {
|
struct InputFile {
|
||||||
const char *FileName;
|
unsigned char Type;
|
||||||
unsigned Type;
|
char FileName[1]; /* Dynamically allocated */
|
||||||
} *InputFiles;
|
};
|
||||||
static unsigned InputFilesCount = 0;
|
typedef struct InputFile InputFile;
|
||||||
static const char *CmdlineCfgFile = NULL,
|
static Collection InputFiles = STATIC_COLLECTION_INITIALIZER;
|
||||||
*CmdlineTarget = NULL;
|
|
||||||
|
static const char* CmdlineCfgFile = NULL;
|
||||||
|
static const char* CmdlineTarget = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* struct InputFile */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static InputFile* NewInputFile (unsigned char Type, const char* FileName)
|
||||||
|
/* Create a new InputFile struct and return it */
|
||||||
|
{
|
||||||
|
unsigned Length = FileName? strlen (FileName) : 0;
|
||||||
|
InputFile* F = xmalloc (sizeof (InputFile) + Length);
|
||||||
|
F->Type = Type;
|
||||||
|
if (FileName) {
|
||||||
|
memcpy (F->FileName, FileName, Length + 1);
|
||||||
|
} else {
|
||||||
|
F->FileName[0] = '\0';
|
||||||
|
}
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void FreeInputFile (InputFile* F)
|
||||||
|
/* Free an InputFile struct */
|
||||||
|
{
|
||||||
|
xfree (F);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -434,10 +464,7 @@ static void OptLargeAlignment (const char* Opt attribute ((unused)),
|
|||||||
static void OptLib (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptLib (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Link a library */
|
/* Link a library */
|
||||||
{
|
{
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_FILE_LIB;
|
CollAppend (&InputFiles, NewInputFile (INPUT_FILES_FILE_LIB, Arg));
|
||||||
InputFiles[InputFilesCount].FileName = Arg;
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -485,10 +512,7 @@ static void OptNoUtf8 (const char* Opt attribute ((unused)),
|
|||||||
static void OptObj (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptObj (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Link an object file */
|
/* Link an object file */
|
||||||
{
|
{
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_FILE_OBJ;
|
CollAppend (&InputFiles, NewInputFile (INPUT_FILES_FILE_OBJ, Arg));
|
||||||
InputFiles[InputFilesCount].FileName = Arg;
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -606,10 +630,7 @@ static void CmdlOptStartGroup (const char* Opt attribute ((unused)),
|
|||||||
const char* Arg attribute ((unused)))
|
const char* Arg attribute ((unused)))
|
||||||
/* Remember 'start group' occurrence in input files array */
|
/* Remember 'start group' occurrence in input files array */
|
||||||
{
|
{
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_SGROUP;
|
CollAppend (&InputFiles, NewInputFile (INPUT_FILES_SGROUP, 0));
|
||||||
InputFiles[InputFilesCount].FileName = Arg; /* Unused */
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -618,10 +639,7 @@ static void CmdlOptEndGroup (const char* Opt attribute ((unused)),
|
|||||||
const char* Arg attribute ((unused)))
|
const char* Arg attribute ((unused)))
|
||||||
/* Remember 'end group' occurrence in input files array */
|
/* Remember 'end group' occurrence in input files array */
|
||||||
{
|
{
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_EGROUP;
|
CollAppend (&InputFiles, NewInputFile (INPUT_FILES_EGROUP, 0));
|
||||||
InputFiles[InputFilesCount].FileName = Arg; /* Unused */
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -679,9 +697,6 @@ static void ParseCommandLine (void)
|
|||||||
unsigned I;
|
unsigned I;
|
||||||
unsigned LabelFileGiven = 0;
|
unsigned LabelFileGiven = 0;
|
||||||
|
|
||||||
/* Allocate memory for input file array */
|
|
||||||
InputFiles = xmalloc (MAX_INPUTFILES * sizeof (struct InputFile));
|
|
||||||
|
|
||||||
/* Defer setting of config/target and input files until all options are parsed */
|
/* Defer setting of config/target and input files until all options are parsed */
|
||||||
I = 1;
|
I = 1;
|
||||||
while (I < ArgCount) {
|
while (I < ArgCount) {
|
||||||
@@ -774,13 +789,8 @@ static void ParseCommandLine (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* A filename */
|
/* A filename */
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_FILE;
|
CollAppend (&InputFiles, NewInputFile (INPUT_FILES_FILE, Arg));
|
||||||
InputFiles[InputFilesCount].FileName = Arg;
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next argument */
|
/* Next argument */
|
||||||
@@ -793,17 +803,18 @@ static void ParseCommandLine (void)
|
|||||||
OptConfig (NULL, CmdlineCfgFile);
|
OptConfig (NULL, CmdlineCfgFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process input files */
|
/* Process input files and delete the entries while doing so */
|
||||||
for (I = 0; I < InputFilesCount; ++I) {
|
for (I = 0; I < CollCount (&InputFiles); ++I) {
|
||||||
switch (InputFiles[I].Type) {
|
InputFile* F = CollAtUnchecked (&InputFiles, I);
|
||||||
|
switch (F->Type) {
|
||||||
case INPUT_FILES_FILE:
|
case INPUT_FILES_FILE:
|
||||||
LinkFile (InputFiles[I].FileName, FILETYPE_UNKNOWN);
|
LinkFile (F->FileName, FILETYPE_UNKNOWN);
|
||||||
break;
|
break;
|
||||||
case INPUT_FILES_FILE_LIB:
|
case INPUT_FILES_FILE_LIB:
|
||||||
LinkFile (InputFiles[I].FileName, FILETYPE_LIB);
|
LinkFile (F->FileName, FILETYPE_LIB);
|
||||||
break;
|
break;
|
||||||
case INPUT_FILES_FILE_OBJ:
|
case INPUT_FILES_FILE_OBJ:
|
||||||
LinkFile (InputFiles[I].FileName, FILETYPE_OBJ);
|
LinkFile (F->FileName, FILETYPE_OBJ);
|
||||||
break;
|
break;
|
||||||
case INPUT_FILES_SGROUP:
|
case INPUT_FILES_SGROUP:
|
||||||
OptStartGroup (NULL, 0);
|
OptStartGroup (NULL, 0);
|
||||||
@@ -812,12 +823,14 @@ static void ParseCommandLine (void)
|
|||||||
OptEndGroup (NULL, 0);
|
OptEndGroup (NULL, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
FAIL ("Unknown file type");
|
||||||
}
|
}
|
||||||
|
FreeInputFile (F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free memory used for input file array */
|
/* Free memory used for input file array */
|
||||||
xfree (InputFiles);
|
DoneCollection (&InputFiles);
|
||||||
|
InitCollection (&InputFiles); /* Don't leave dangling pointers */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user