X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fmain.c;h=b029e2f0cc64b67255ec5102819d2143cf6c9f64;hb=1d458e9f33d442052a2921f0678efb4875d2e8ab;hp=08f701ccf1e7d127278e4c2786cbd5e9e48f1c92;hpb=51543fddb01cd8c15cc3f9d26157a76e4bb2f816;p=cc65 diff --git a/src/ca65/main.c b/src/ca65/main.c index 08f701ccf..b029e2f0c 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -36,21 +36,27 @@ #include #include #include -#include #include /* common */ +#include "chartype.h" #include "cmdline.h" +#include "print.h" +#include "target.h" +#include "tgttrans.h" #include "version.h" /* ca65 */ +#include "abend.h" #include "error.h" #include "expr.h" +#include "feature.h" #include "filetab.h" #include "global.h" #include "incpath.h" #include "instr.h" #include "istack.h" +#include "lineinfo.h" #include "listing.h" #include "macro.h" #include "nexttok.h" @@ -82,6 +88,7 @@ static void Usage (void) " -l\t\t\tCreate a listing if assembly was ok\n" " -o name\t\tName the output file\n" " -s\t\t\tEnable smart mode\n" + " -t sys\t\tSet the target system\n" " -v\t\t\tIncrease verbosity\n" " -D name[=value]\tDefine a symbol\n" " -I dir\t\tSet an include directory search path\n" @@ -93,12 +100,14 @@ static void Usage (void) " --auto-import\t\tMark unresolved symbols as import\n" " --cpu type\t\tSet cpu type\n" " --debug-info\t\tAdd debug info to object file\n" + " --feature name\tSet an emulation feature\n" " --help\t\tHelp (this text)\n" " --ignore-case\t\tIgnore case of symbols\n" " --include-dir dir\tSet an include directory search path\n" " --listing\t\tCreate a listing if assembly was ok\n" " --pagelength n\tSet the page length for the listing\n" " --smart\t\tEnable smart mode\n" + " --target sys\t\tSet the target system\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the assembler version\n", ProgName); @@ -130,14 +139,14 @@ static void DefineSymbol (const char* Def) char SymName [MAX_STR_LEN+1]; /* The symbol must start with a character or underline */ - if (Def [0] != '_' && !isalpha (Def [0])) { + if (Def [0] != '_' && !IsAlpha (Def [0])) { InvDef (Def); } P = Def; /* Copy the symbol, checking the rest */ I = 0; - while (isalnum (*P) || *P == '_') { + while (IsAlNum (*P) || *P == '_') { if (I <= MAX_STR_LEN) { SymName [I++] = *P; } @@ -168,8 +177,7 @@ static void DefineSymbol (const char* Def) /* Check if have already a symbol with this name */ if (SymIsDef (SymName)) { - fprintf (stderr, "`%s' is already defined\n", SymName); - exit (EXIT_FAILURE); + AbEnd ("`%s' is already defined", SymName); } /* Define the symbol */ @@ -203,8 +211,7 @@ static void OptCPU (const char* Opt, const char* Arg) SetCPU (CPU_SUNPLUS); #endif } else { - fprintf (stderr, "Invalid CPU: `%s'\n", Arg); - exit (EXIT_FAILURE); + AbEnd ("Invalid CPU: `%s'", Arg); } } @@ -218,6 +225,17 @@ static void OptDebugInfo (const char* Opt, const char* Arg) +static void OptFeature (const char* Opt, const char* Arg) +/* Set an emulation feature */ +{ + /* Set the feature, check for errors */ + if (SetFeature (Arg) == FEAT_UNKNOWN) { + AbEnd ("Illegal emulation feature: `%s'", Arg); + } +} + + + static void OptHelp (const char* Opt, const char* Arg) /* Print usage information and exit */ { @@ -263,8 +281,7 @@ static void OptPageLength (const char* Opt, const char* Arg) } Len = atoi (Arg); if (Len != -1 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) { - fprintf (stderr, "Invalid page length: %d\n", Len); - exit (EXIT_FAILURE); + AbEnd ("Invalid page length: %d", Len); } PageLength = Len; } @@ -279,10 +296,26 @@ static void OptSmart (const char* Opt, const char* Arg) +static void OptTarget (const char* Opt, const char* Arg) +/* Set the target system */ +{ + if (Arg == 0) { + NeedArg (Opt); + } + + /* Map the target name to a target id */ + Target = FindTarget (Arg); + if (Target == TGT_UNKNOWN) { + AbEnd ("Invalid target name: `%s'", Arg); + } +} + + + static void OptVerbose (const char* Opt, const char* Arg) /* Increase verbosity */ { - ++Verbose; + ++Verbosity; } @@ -297,6 +330,19 @@ static void OptVersion (const char* Opt, const char* Arg) +static void DoPCAssign (void) +/* Start absolute code */ +{ + long PC = ConstExpression (); + if (PC < 0 || PC > 0xFFFFFF) { + Error (ERR_RANGE); + } else { + SetAbsPC (PC); + } +} + + + static void OneLine (void) /* Assemble one line */ { @@ -307,49 +353,49 @@ static void OneLine (void) * and not from internally pushed input. */ if (!HavePushedInput ()) { - InitListingLine (); + InitListingLine (); } if (Tok == TOK_COLON) { - /* An unnamed label */ - ULabDef (); - NextTok (); + /* An unnamed label */ + ULabDef (); + NextTok (); } /* Assemble the line */ if (Tok == TOK_IDENT) { - /* Is it a macro? */ - if (IsMacro (SVal)) { + /* Is it a macro? */ + if (IsMacro (SVal)) { - /* Yes, start a macro expansion */ - MacExpandStart (); - Done = 1; + /* Yes, start a macro expansion */ + MacExpandStart (); + Done = 1; - } else { + } else { - /* No, label. Remember the identifier, then skip it */ - int HadWS = WS; /* Did we have whitespace before the ident? */ - strcpy (Ident, SVal); - NextTok (); + /* No, label. Remember the identifier, then skip it */ + int HadWS = WS; /* Did we have whitespace before the ident? */ + strcpy (Ident, SVal); + NextTok (); - /* If a colon follows, this is a label definition. If there - * is no colon, it's an assignment. - */ + /* If a colon follows, this is a label definition. If there + * is no colon, it's an assignment. + */ if (Tok == TOK_EQ) { - /* Skip the '=' */ - NextTok (); - /* Define the symbol with the expression following the '=' */ - SymDef (Ident, Expression (), 0); - /* Don't allow anything after a symbol definition */ - Done = 1; - } else { - /* Define a label */ - SymDef (Ident, CurrentPC (), IsZPSeg ()); - /* Skip the colon. If NoColonLabels is enabled, allow labels - * without a colon if there is no whitespace before the - * identifier. - */ + /* Skip the '=' */ + NextTok (); + /* Define the symbol with the expression following the '=' */ + SymDef (Ident, Expression (), 0); + /* Don't allow anything after a symbol definition */ + Done = 1; + } else { + /* Define a label */ + SymDef (Ident, CurrentPC (), IsZPSeg ()); + /* Skip the colon. If NoColonLabels is enabled, allow labels + * without a colon if there is no whitespace before the + * identifier. + */ if (Tok != TOK_COLON) { if (HadWS || !NoColonLabels) { Error (ERR_COLON_EXPECTED); @@ -377,7 +423,18 @@ static void OneLine (void) } else if (Tok == TOK_IDENT && IsMacro (SVal)) { /* A macro expansion */ MacExpandStart (); - } + } else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) { + NextTok (); + if (Tok != TOK_EQ) { + Error (ERR_EQ_EXPECTED); + SkipUntilSep (); + } else { + /* Skip the equal sign */ + NextTok (); + /* Enter absolute mode */ + DoPCAssign (); + } + } } /* Line separator must come here */ @@ -424,6 +481,9 @@ static void CreateObjFile (void) /* Write debug symbols if requested */ WriteDbgSyms (); + /* Write line infos if requested */ + WriteLineInfo (); + /* Write an updated header and close the file */ ObjClose (); } @@ -438,20 +498,22 @@ int main (int argc, char* argv []) { "--auto-import", 0, OptAutoImport }, { "--cpu", 1, OptCPU }, { "--debug-info", 0, OptDebugInfo }, - { "--help", 0, OptHelp }, + { "--feature", 1, OptFeature }, + { "--help", 0, OptHelp }, { "--ignore-case", 0, OptIgnoreCase }, { "--include-dir", 1, OptIncludeDir }, - { "--listing", 0, OptListing }, + { "--listing", 0, OptListing }, { "--pagelength", 1, OptPageLength }, - { "--smart", 0, OptSmart }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, + { "--smart", 0, OptSmart }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, }; int I; /* Initialize the cmdline module */ - InitCmdLine (argc, argv, "ca65"); + InitCmdLine (&argc, &argv, "ca65"); /* Enter the base lexical level. We must do that here, since we may * define symbols using -D. @@ -460,10 +522,10 @@ int main (int argc, char* argv []) /* Check the parameters */ I = 1; - while (I < argc) { + while (I < ArgCount) { /* Get the argument */ - const char* Arg = argv [I]; + const char* Arg = ArgVec [I]; /* Check for an option */ if (Arg [0] == '-') { @@ -473,7 +535,7 @@ int main (int argc, char* argv []) LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0])); break; - case 'g': + case 'g': OptDebugInfo (Arg, 0); break; @@ -497,6 +559,10 @@ int main (int argc, char* argv []) OptSmart (Arg, 0); break; + case 't': + OptTarget (Arg, GetArg (&I, 2)); + break; + case 'v': OptVerbose (Arg, 0); break; @@ -514,7 +580,7 @@ int main (int argc, char* argv []) break; case 'V': - OptVersion (Arg, 0); + OptVersion (Arg, 0); break; case 'W': @@ -530,10 +596,10 @@ int main (int argc, char* argv []) /* 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); + ProgName, Arg); + exit (EXIT_FAILURE); } else { - InFile = Arg; + InFile = Arg; } } @@ -547,6 +613,9 @@ int main (int argc, char* argv []) exit (EXIT_FAILURE); } + /* Intialize the target translation tables */ + TgtTranslateInit (); + /* Initialize the scanner, open the input file */ InitScanner (InFile); @@ -571,8 +640,11 @@ int main (int argc, char* argv []) SegCheck (); } + /* If we didn't have an errors, index the line infos */ + MakeLineInfoIndex (); + /* Dump the data */ - if (Verbose >= 2) { + if (Verbosity >= 2) { SymDump (stdout); SegDump (); }