+/*****************************************************************************/
/* */
-/* main.c */
+/* main.c */
/* */
-/* Main program for the ca65 macroassembler */
+/* Main program for the ca65 macroassembler */
/* */
/* */
/* */
-/* (C) 1998-2012, Ullrich von Bassewitz */
+/* (C) 1998-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
" --debug\t\t\tDebug mode\n"
" --debug-info\t\t\tAdd debug info to object file\n"
" --feature name\t\tSet an emulation feature\n"
- " --forget-inc-paths\t\tForget include search paths\n"
" --help\t\t\tHelp (this text)\n"
" --ignore-case\t\t\tIgnore case of symbols\n"
" --include-dir dir\t\tSet an include directory search path\n"
/* Check if have already a symbol with this name */
if (SymIsDef (Sym)) {
- AbEnd ("`%s' is already defined", SymName);
+ AbEnd ("`%s' is already defined", SymName);
}
/* Generate an expression for the symbol */
{
switch (Target = FindTarget (Sys)) {
- case TGT_NONE:
- break;
+ case TGT_NONE:
+ break;
case TGT_MODULE:
AbEnd ("Cannot use `module' as a target for the assembler");
break;
- case TGT_ATARI:
- NewSymbol ("__ATARI__", 1);
- break;
+ case TGT_ATARI2600:
+ NewSymbol ("__ATARI2600__", 1);
+ break;
- case TGT_C16:
- CBMSystem ("__C16__");
- break;
+ case TGT_ATARI5200:
+ NewSymbol ("__ATARI5200__", 1);
+ break;
- case TGT_C64:
- CBMSystem ("__C64__");
- break;
+ case TGT_ATARI:
+ NewSymbol ("__ATARI__", 1);
+ break;
- case TGT_VIC20:
- CBMSystem ("__VIC20__");
- break;
+ case TGT_ATARIXL:
+ NewSymbol ("__ATARI__", 1);
+ NewSymbol ("__ATARIXL__", 1);
+ break;
- case TGT_C128:
- CBMSystem ("__C128__");
- break;
+ case TGT_C16:
+ CBMSystem ("__C16__");
+ break;
- case TGT_PLUS4:
- CBMSystem ("__PLUS4__");
- break;
+ case TGT_C64:
+ CBMSystem ("__C64__");
+ break;
- case TGT_CBM510:
- CBMSystem ("__CBM510__");
- break;
+ case TGT_C65:
+ CBMSystem ("__C65__");
+ break;
- case TGT_CBM610:
- CBMSystem ("__CBM610__");
- break;
+ case TGT_VIC20:
+ CBMSystem ("__VIC20__");
+ break;
- case TGT_PET:
- CBMSystem ("__PET__");
- break;
+ case TGT_C128:
+ CBMSystem ("__C128__");
+ break;
- case TGT_BBC:
- NewSymbol ("__BBC__", 1);
- break;
+ case TGT_PLUS4:
+ CBMSystem ("__C16__");
+ NewSymbol ("__PLUS4__", 1);
+ break;
- case TGT_APPLE2:
- NewSymbol ("__APPLE2__", 1);
- break;
+ case TGT_CBM510:
+ CBMSystem ("__CBM510__");
+ break;
- case TGT_APPLE2ENH:
- NewSymbol ("__APPLE2ENH__", 1);
- break;
+ case TGT_CBM610:
+ CBMSystem ("__CBM610__");
+ break;
- case TGT_GEOS_CBM:
- /* Do not handle as a CBM system */
- NewSymbol ("__GEOS__", 1);
- NewSymbol ("__GEOS_CBM__", 1);
- break;
+ case TGT_PET:
+ CBMSystem ("__PET__");
+ break;
- case TGT_GEOS_APPLE:
- NewSymbol ("__GEOS__", 1);
- NewSymbol ("__GEOS_APPLE__", 1);
- break;
+ case TGT_APPLE2:
+ NewSymbol ("__APPLE2__", 1);
+ break;
- case TGT_LUNIX:
- NewSymbol ("__LUNIX__", 1);
- break;
+ case TGT_APPLE2ENH:
+ NewSymbol ("__APPLE2__", 1);
+ NewSymbol ("__APPLE2ENH__", 1);
+ break;
+
+ case TGT_GAMATE:
+ NewSymbol ("__GAMATE__", 1);
+ break;
+
+ case TGT_GEOS_CBM:
+ /* Do not handle as a CBM system */
+ NewSymbol ("__GEOS__", 1);
+ NewSymbol ("__GEOS_CBM__", 1);
+ break;
case TGT_ATMOS:
NewSymbol ("__ATMOS__", 1);
break;
- case TGT_NES:
- NewSymbol ("__NES__", 1);
+ case TGT_BBC:
+ NewSymbol ("__BBC__", 1);
break;
- case TGT_SUPERVISION:
- NewSymbol ("__SUPERVISION__", 1);
+ case TGT_CREATIVISION:
+ NewSymbol ("__CREATIVISION__", 1);
+ break;
+
+ case TGT_GEOS_APPLE:
+ NewSymbol ("__GEOS__", 1);
+ NewSymbol ("__GEOS_APPLE__", 1);
+ break;
+
+ case TGT_LUNIX:
+ NewSymbol ("__LUNIX__", 1);
break;
case TGT_LYNX:
NewSymbol ("__LYNX__", 1);
break;
- default:
+ case TGT_NES:
+ NewSymbol ("__NES__", 1);
+ break;
+
+ case TGT_SIM6502:
+ NewSymbol ("__SIM6502__", 1);
+ break;
+
+ case TGT_SIM65C02:
+ NewSymbol ("__SIM65C02__", 1);
+ break;
+
+ case TGT_OSIC1P:
+ NewSymbol ("__OSIC1P__", 1);
+ break;
+
+ case TGT_PCENGINE:
+ NewSymbol ("__PCE__", 1);
+ break;
+
+ case TGT_SUPERVISION:
+ NewSymbol ("__SUPERVISION__", 1);
+ break;
+
+ default:
AbEnd ("Invalid target name: `%s'", Sys);
}
/* The symbol must start with a character or underline */
if (!IsIdStart (Def [0])) {
- InvDef (Def);
+ InvDef (Def);
}
P = Def;
/* Do we have a value given? */
if (*P != '=') {
- if (*P != '\0') {
- InvDef (Def);
- }
- Val = 0;
+ if (*P != '\0') {
+ InvDef (Def);
+ }
+ Val = 0;
} else {
- /* We have a value */
- ++P;
- if (*P == '$') {
- ++P;
- if (sscanf (P, "%lx", &Val) != 1) {
- InvDef (Def);
- }
- } else {
- if (sscanf (P, "%li", &Val) != 1) {
- InvDef (Def);
- }
- }
+ /* We have a value */
+ ++P;
+ if (*P == '$') {
+ ++P;
+ if (sscanf (P, "%lx", &Val) != 1) {
+ InvDef (Def);
+ }
+ } else {
+ if (sscanf (P, "%li", &Val) != 1) {
+ InvDef (Def);
+ }
+ }
}
/* Define the new symbol */
static void OptAutoImport (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Mark unresolved symbols as imported */
{
AutoImport = 1;
{
cpu_t CPU = FindCPU (Arg);
if (CPU == CPU_UNKNOWN) {
- AbEnd ("Invalid CPU: `%s'", Arg);
+ AbEnd ("Invalid CPU: `%s'", Arg);
} else {
- SetCPU (CPU);
+ SetCPU (CPU);
}
}
static void OptCreateFullDep (const char* Opt attribute ((unused)),
- const char* Arg)
+ const char* Arg)
/* Handle the --create-full-dep option */
{
FileNameOption (Opt, Arg, &FullDepName);
static void OptDebug (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Compiler debug mode */
{
++Debug;
static void OptDebugInfo (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Add debug info to the object file */
{
DbgSyms = 1;
/* Set the feature, check for errors */
if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) {
- AbEnd ("Illegal emulation feature: `%s'", Arg);
+ AbEnd ("Illegal emulation feature: `%s'", Arg);
}
}
-static void OptForgetIncPaths (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
-/* Forget all currently defined include paths */
-{
- ForgetAllIncludePaths ();
-}
-
-
-
static void OptHelp (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Print usage information and exit */
{
Usage ();
static void OptIgnoreCase (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Ignore case on symbols */
{
IgnoreCase = 1;
static void OptLargeAlignment (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Don't warn about large alignments */
{
LargeAlignment = 1;
/* Create a listing file */
{
/* Since the meaning of -l and --listing has changed, print an error if
- * the filename is empty or begins with the option char.
- */
+ ** the filename is empty or begins with the option char.
+ */
if (Arg == 0 || *Arg == '\0' || *Arg == '-') {
Fatal ("The meaning of `%s' has changed. It does now "
"expect a file name as argument.", Opt);
{
int Len = atoi (Arg);
if (Len != -1 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) {
- AbEnd ("Invalid page length: %d", Len);
+ AbEnd ("Invalid page length: %d", Len);
}
PageLength = Len;
}
static void OptRelaxChecks (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Handle the --relax-checks options */
{
RelaxChecks = 1;
static void OptSmart (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Handle the -s/--smart options */
{
SmartMode = 1;
static void OptVerbose (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Increase verbosity */
{
++Verbosity;
static void OptVersion (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
+ const char* Arg attribute ((unused)))
/* Print the assembler version */
{
- fprintf (stderr, "ca65 V%s\n", GetVersionAsString ());
+ fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
+ exit(EXIT_SUCCESS);
}
{
long PC = ConstExpression ();
if (PC < 0 || PC > 0xFFFFFF) {
- Error ("Range error");
+ Error ("Range error");
} else {
- EnterAbsoluteMode (PC);
+ EnterAbsoluteMode (PC);
}
}
int Instr = -1;
/* Initialize the new listing line if we are actually reading from file
- * and not from internally pushed input.
- */
+ ** and not from internally pushed input.
+ */
if (!HavePushedInput ()) {
- InitListingLine ();
+ InitListingLine ();
}
/* Single colon means unnamed label */
if (CurTok.Tok == TOK_COLON) {
- ULabDef ();
- NextTok ();
+ ULabDef ();
+ NextTok ();
}
/* If the first token on the line is an identifier, check for a macro or
- * an instruction.
- */
+ ** an instruction.
+ */
if (CurTok.Tok == TOK_IDENT) {
- if (!UbiquitousIdents) {
- /* Macros and symbols cannot use instruction names */
+ if (UbiquitousIdents) {
+ /* Macros CAN be instructions, so check for them first */
+ Mac = FindMacro (&CurTok.SVal);
+ if (Mac == 0) {
+ Instr = FindInstruction (&CurTok.SVal);
+ }
+ } else {
+ /* Macros and symbols may NOT use the names of instructions */
Instr = FindInstruction (&CurTok.SVal);
if (Instr < 0) {
Mac = FindMacro (&CurTok.SVal);
}
- } else {
- /* Macros and symbols may use the names of instructions */
- Mac = FindMacro (&CurTok.SVal);
}
}
/* Handle an identifier. This may be a cheap local symbol, or a fully
- * scoped identifier which may start with a namespace token (for global
- * namespace)
- */
+ ** scoped identifier which may start with a namespace token (for global
+ ** namespace)
+ */
if (CurTok.Tok == TOK_LOCAL_IDENT ||
CurTok.Tok == TOK_NAMESPACE ||
(CurTok.Tok == TOK_IDENT && Instr < 0 && Mac == 0)) {
Sym = ParseAnySymName (SYM_ALLOC_NEW);
/* If a colon follows, this is a label definition. If there
- * is no colon, it's an assignment.
- */
+ ** is no colon, it's an assignment.
+ */
if (CurTok.Tok == TOK_EQ || CurTok.Tok == TOK_ASSIGN) {
/* Determine the symbol flags from the assignment token */
Expr = GenLiteralExpr (ConstExpression ());
/* Define the symbol with the constant expression following
- * the '='
- */
+ ** the '='
+ */
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_VAR);
/* Don't allow anything after a symbol definition */
} else {
/* A label. Remember the current segment, so we can later
- * determine the size of the data stored under the label.
- */
+ ** determine the size of the data stored under the label.
+ */
Seg = ActiveSeg;
PC = GetPC ();
SymDef (Sym, GenCurrentPC (), ADDR_SIZE_DEFAULT, SF_LABEL);
/* Skip the colon. If NoColonLabels is enabled, allow labels
- * without a colon if there is no whitespace before the
- * identifier.
- */
+ ** without a colon if there is no whitespace before the
+ ** identifier.
+ */
if (CurTok.Tok != TOK_COLON) {
if (HadWS || !NoColonLabels) {
Error ("`:' expected");
}
/* If we come here, a new identifier may be waiting, which may
- * be a macro or instruction.
- */
+ ** be a macro or instruction.
+ */
if (CurTok.Tok == TOK_IDENT) {
- if (!UbiquitousIdents) {
- /* Macros and symbols cannot use instruction names */
+ if (UbiquitousIdents) {
+ /* Macros CAN be instructions, so check for them first */
+ Mac = FindMacro (&CurTok.SVal);
+ if (Mac == 0) {
+ Instr = FindInstruction (&CurTok.SVal);
+ }
+ } else {
+ /* Macros and symbols may NOT use the names of instructions */
Instr = FindInstruction (&CurTok.SVal);
if (Instr < 0) {
Mac = FindMacro (&CurTok.SVal);
}
- } else {
- /* Macros and symbols may use the names of instructions */
- Mac = FindMacro (&CurTok.SVal);
}
}
}
} else if (Mac != 0) {
/* A macro expansion */
MacExpandStart (Mac);
- } else if (Instr >= 0 ||
- (UbiquitousIdents && ((Instr = FindInstruction (&CurTok.SVal)) >= 0))) {
+ } else if (Instr >= 0) {
/* A mnemonic - assemble one instruction */
HandleInstruction (Instr);
} else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) {
}
/* If we have defined a label, remember its size. Sym is also set by
- * a symbol assignment, but in this case Done is false, so we don't
- * come here.
- */
+ ** a symbol assignment, but in this case Done is false, so we don't
+ ** come here.
+ */
if (Sym) {
unsigned long Size;
if (Seg == ActiveSeg) {
/* Assemble lines until end of file */
while (CurTok.Tok != TOK_EOF) {
- OneLine ();
+ OneLine ();
}
}
{
/* Program long options */
static const LongOpt OptTab[] = {
- { "--auto-import", 0, OptAutoImport },
+ { "--auto-import", 0, OptAutoImport },
{ "--bin-include-dir", 1, OptBinIncludeDir },
- { "--cpu", 1, OptCPU },
+ { "--cpu", 1, OptCPU },
{ "--create-dep", 1, OptCreateDep },
{ "--create-full-dep", 1, OptCreateFullDep },
- { "--debug", 0, OptDebug },
- { "--debug-info", 0, OptDebugInfo },
- { "--feature", 1, OptFeature },
- { "--forget-inc-paths", 0, OptForgetIncPaths },
- { "--help", 0, OptHelp },
- { "--ignore-case", 0, OptIgnoreCase },
- { "--include-dir", 1, OptIncludeDir },
+ { "--debug", 0, OptDebug },
+ { "--debug-info", 0, OptDebugInfo },
+ { "--feature", 1, OptFeature },
+ { "--help", 0, OptHelp },
+ { "--ignore-case", 0, OptIgnoreCase },
+ { "--include-dir", 1, OptIncludeDir },
{ "--large-alignment", 0, OptLargeAlignment },
{ "--list-bytes", 1, OptListBytes },
- { "--listing", 1, OptListing },
+ { "--listing", 1, OptListing },
{ "--memory-model", 1, OptMemoryModel },
- { "--pagelength", 1, OptPageLength },
+ { "--pagelength", 1, OptPageLength },
{ "--relax-checks", 0, OptRelaxChecks },
- { "--smart", 0, OptSmart },
- { "--target", 1, OptTarget },
- { "--verbose", 0, OptVerbose },
- { "--version", 0, OptVersion },
+ { "--smart", 0, OptSmart },
+ { "--target", 1, OptTarget },
+ { "--verbose", 0, OptVerbose },
+ { "--version", 0, OptVersion },
};
/* Name of the global name space */
SegInit ();
/* Enter the base lexical level. We must do that here, since we may
- * define symbols using -D.
- */
+ ** define symbols using -D.
+ */
SymEnterLevel (&GlobalNameSpace, SCOPE_FILE, ADDR_SIZE_DEFAULT, 0);
/* Initialize the line infos. Must be done here, since we need line infos
- * for symbol definitions.
- */
+ ** for symbol definitions.
+ */
InitLineInfo ();
/* Check the parameters */
I = 1;
while (I < ArgCount) {
- /* Get the argument */
- const char* Arg = ArgVec [I];
+ /* Get the argument */
+ const char* Arg = ArgVec [I];
- /* Check for an option */
- if (Arg[0] == '-') {
- switch (Arg[1]) {
+ /* Check for an option */
+ if (Arg[0] == '-') {
+ switch (Arg[1]) {
- case '-':
- LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
- break;
+ case '-':
+ LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
+ break;
- case 'd':
- OptDebug (Arg, 0);
- break;
+ case 'd':
+ OptDebug (Arg, 0);
+ break;
- case 'g':
- OptDebugInfo (Arg, 0);
- break;
+ case 'g':
+ OptDebugInfo (Arg, 0);
+ break;
- case 'h':
- OptHelp (Arg, 0);
- break;
+ case 'h':
+ OptHelp (Arg, 0);
+ break;
- case 'i':
- OptIgnoreCase (Arg, 0);
- break;
+ case 'i':
+ OptIgnoreCase (Arg, 0);
+ break;
- case 'l':
- OptListing (Arg, GetArg (&I, 2));
- break;
+ case 'l':
+ OptListing (Arg, GetArg (&I, 2));
+ break;
case 'm':
if (Arg[2] == 'm') {
}
break;
- case 'o':
- OutFile = GetArg (&I, 2);
- break;
-
- case 's':
- OptSmart (Arg, 0);
- break;
-
- case 't':
- OptTarget (Arg, GetArg (&I, 2));
- break;
-
- case 'v':
- OptVerbose (Arg, 0);
- break;
-
- case 'D':
- DefineSymbol (GetArg (&I, 2));
- break;
-
- case 'I':
- OptIncludeDir (Arg, GetArg (&I, 2));
- break;
-
- case 'U':
- OptAutoImport (Arg, 0);
- break;
-
- case 'V':
- OptVersion (Arg, 0);
- break;
-
- case 'W':
- WarnLevel = atoi (GetArg (&I, 2));
- break;
-
- default:
- UnknownOption (Arg);
- break;
-
- }
- } else {
- /* Filename. Check if we already had one */
- if (InFile) {
- fprintf (stderr, "%s: Don't know what to do with `%s'\n",
- ProgName, Arg);
- exit (EXIT_FAILURE);
- } else {
- InFile = Arg;
- }
- }
-
- /* Next argument */
- ++I;
+ case 'o':
+ OutFile = GetArg (&I, 2);
+ break;
+
+ case 's':
+ OptSmart (Arg, 0);
+ break;
+
+ case 't':
+ OptTarget (Arg, GetArg (&I, 2));
+ break;
+
+ case 'v':
+ OptVerbose (Arg, 0);
+ break;
+
+ case 'D':
+ DefineSymbol (GetArg (&I, 2));
+ break;
+
+ case 'I':
+ OptIncludeDir (Arg, GetArg (&I, 2));
+ break;
+
+ case 'U':
+ OptAutoImport (Arg, 0);
+ break;
+
+ case 'V':
+ OptVersion (Arg, 0);
+ break;
+
+ case 'W':
+ WarnLevel = atoi (GetArg (&I, 2));
+ break;
+
+ default:
+ UnknownOption (Arg);
+ break;
+
+ }
+ } else {
+ /* Filename. Check if we already had one */
+ if (InFile) {
+ fprintf (stderr, "%s: Don't know what to do with `%s'\n",
+ ProgName, Arg);
+ exit (EXIT_FAILURE);
+ } else {
+ InFile = Arg;
+ }
+ }
+
+ /* Next argument */
+ ++I;
}
/* Do we have an input file? */
if (InFile == 0) {
- fprintf (stderr, "%s: No input files\n", ProgName);
- exit (EXIT_FAILURE);
+ fprintf (stderr, "%s: No input files\n", ProgName);
+ exit (EXIT_FAILURE);
}
+ /* Add the default include search paths. */
+ FinishIncludePaths ();
+
/* If no CPU given, use the default CPU for the target */
if (GetCPU () == CPU_UNKNOWN) {
if (Target != TGT_UNKNOWN) {
DoneLineInfo ();
/* If we didn't have any errors, create the object, listing and
- * dependency files
- */
+ ** dependency files
+ */
if (ErrorCount == 0) {
- CreateObjFile ();
- if (SB_GetLen (&ListingName) > 0) {
- CreateListing ();
- }
+ CreateObjFile ();
+ if (SB_GetLen (&ListingName) > 0) {
+ CreateListing ();
+ }
CreateDependencies ();
}
/* Return an apropriate exit code */
return (ErrorCount == 0)? EXIT_SUCCESS : EXIT_FAILURE;
}
-
-
-