#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <time.h>
/* 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"
#include "pseudo.h"
#include "scanner.h"
#include "symtab.h"
-#include "target.h"
#include "ulabel.h"
" --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"
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;
}
+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 */
{
static void OptTarget (const char* Opt, const char* Arg)
/* Set the target system */
{
- int T;
if (Arg == 0) {
NeedArg (Opt);
}
/* Map the target name to a target id */
- T = MapTarget (Arg);
- if (T < 0) {
+ Target = FindTarget (Arg);
+ if (Target == TGT_UNKNOWN) {
AbEnd ("Invalid target name: `%s'", Arg);
}
- Target = (target_t) T;
}
static void OptVerbose (const char* Opt, const char* Arg)
/* Increase verbosity */
{
- ++Verbose;
+ ++Verbosity;
}
+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 */
{
* 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);
} 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 */
/* Write debug symbols if requested */
WriteDbgSyms ();
+ /* Write line infos if requested */
+ WriteLineInfo ();
+
/* Write an updated header and close the file */
ObjClose ();
}
{ "--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 },
- { "--target", 1, OptTarget },
- { "--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.
/* 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] == '-') {
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
break;
- case 'g':
+ case 'g':
OptDebugInfo (Arg, 0);
break;
break;
case 'V':
- OptVersion (Arg, 0);
+ OptVersion (Arg, 0);
break;
case 'W':
/* 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;
}
}
exit (EXIT_FAILURE);
}
+ /* Intialize the target translation tables */
+ TgtTranslateInit ();
+
/* Initialize the scanner, open the input file */
InitScanner (InFile);
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 ();
}