/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
#include "abend.h"
#include "cmdline.h"
+#include "cpu.h"
#include "fname.h"
#include "print.h"
#include "version.h"
/* da65 */
#include "attrtab.h"
#include "code.h"
-#include "config.h"
-#include "cpu.h"
#include "data.h"
#include "error.h"
#include "global.h"
+#include "infofile.h"
#include "opctable.h"
#include "output.h"
#include "scanner.h"
/* Print usage information and exit */
{
fprintf (stderr,
- "Usage: %s [options] file\n"
+ "Usage: %s [options] [inputfile]\n"
"Short options:\n"
" -g\t\t\tAdd debug info to object file\n"
" -h\t\t\tHelp (this text)\n"
+ " -i name\t\tSpecify an info file\n"
" -o name\t\tName the output file\n"
" -v\t\t\tIncrease verbosity\n"
" -F\t\t\tAdd formfeeds to the output\n"
" -V\t\t\tPrint the disassembler version\n"
"\n"
"Long options:\n"
+ " --comments n\t\tSet the comment level for the output\n"
" --cpu type\t\tSet cpu type\n"
+ " --debug-info\t\tAdd debug info to object file\n"
" --formfeeds\t\tAdd formfeeds to the output\n"
" --help\t\tHelp (this text)\n"
+ " --hexoffs\t\tUse hexadecimal label offsets\n"
+ " --info name\t\tSpecify an info file\n"
" --pagelength n\tSet the page length for the listing\n"
" --start-addr addr\tSet the start/load address\n"
" --verbose\t\tIncrease verbosity\n"
{
unsigned long Val;
int Converted;
+ char BoundsCheck;
/* Convert */
if (*Number == '$') {
++Number;
- Converted = sscanf (Number, "%lx", &Val);
+ Converted = sscanf (Number, "%lx%c", &Val, &BoundsCheck);
} else {
- Converted = sscanf (Number, "%li", (long*)&Val);
+ Converted = sscanf (Number, "%li%c", (long*)&Val, &BoundsCheck);
}
/* Check if we do really have a number */
-static void OptCPU (const char* Opt, const char* Arg)
-/* Handle the --cpu option */
+static void OptComments (const char* Opt, const char* Arg)
+/* Handle the --comments option */
{
- if (Arg == 0) {
- NeedArg (Opt);
- }
- if (strcmp (Arg, "6502") == 0) {
- SetCPU (CPU_6502);
- } else if (strcmp (Arg, "65C02") == 0) {
- SetCPU (CPU_65C02);
- } else if (strcmp (Arg, "65816") == 0) {
- SetCPU (CPU_65816);
-#ifdef SUNPLUS
- } else if (strcmp (Arg, "sunplus") == 0) {
- SetCPU (CPU_SUNPLUS);
-#endif
- } else {
- AbEnd ("Invalid CPU: `%s'", Arg);
+ /* Convert the argument to a number */
+ unsigned long Val = CvtNumber (Opt, Arg);
+
+ /* Check for a valid range */
+ if (Val > MAX_COMMENTS) {
+ Error ("Argument for %s outside valid range (%d-%d)",
+ Opt, MIN_COMMENTS, MAX_COMMENTS);
}
+
+ /* Use the value */
+ Comments = (unsigned char) Val;
}
-static void OptFormFeeds (const char* Opt, const char* Arg)
+static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --cpu option */
+{
+ /* Find the CPU from the given name */
+ CPU = FindCPU (Arg);
+ SetOpcTable (CPU);
+}
+
+
+
+static void OptDebugInfo (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* Add debug info to the object file */
+{
+ DebugInfo = 1;
+}
+
+
+
+static void OptFormFeeds (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Add form feeds to the output */
{
FormFeeds = 1;
-static void OptHelp (const char* Opt, const char* Arg)
+static void OptHelp (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Print usage information and exit */
{
Usage ();
-static void OptPageLength (const char* Opt, const char* Arg)
+static void OptHexOffs (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* Handle the --hexoffs option */
+{
+ UseHexOffs = 1;
+}
+
+
+
+static void OptInfo (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --info option */
+{
+ InfoSetName (Arg);
+}
+
+
+
+static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --pagelength option */
{
- int Len;
- if (Arg == 0) {
- NeedArg (Opt);
- }
- Len = atoi (Arg);
+ int Len = atoi (Arg);
if (Len != 0 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) {
AbEnd ("Invalid page length: %d", Len);
}
-static void OptVerbose (const char* Opt, const char* Arg)
+static void OptVerbose (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Increase verbosity */
{
++Verbosity;
-static void OptVersion (const char* Opt, const char* Arg)
+static void OptVersion (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
/* Print the disassembler version */
{
fprintf (stderr,
/* Get the opcode description for the opcode byte */
const OpcDesc* D = &OpcTable[OPC];
- /* If we have a label at this address, output the label */
- if (MustDefLabel (PC)) {
+ /* Get the output style for the current PC */
+ attr_t Style = GetStyleAttr (PC);
+
+ /* If we have a label at this address, output the label, provided that
+ * we aren't in a skip area.
+ */
+ if (Style != atSkip && MustDefLabel (PC)) {
DefLabel (GetLabel (PC));
}
* - ...if we have enough bytes remaining for the code at this address.
* - ...if the current instruction is valid for the given CPU.
* - ...if there is no label somewhere between the instruction bytes.
- * If any of these conditions is true, switch to data mode.
+ * If any of these conditions is false, switch to data mode.
*/
- if (GetStyleAttr (PC) == atDefault) {
+ if (Style == atDefault) {
if (D->Size > RemainingBytes) {
MarkAddr (PC, atIllegal);
- } else if ((D->CPU & CPU) != CPU) {
+ } else if (D->Flags & flIllegal) {
MarkAddr (PC, atIllegal);
} else {
unsigned I;
for (I = 1; I < D->Size; ++I) {
- if (HaveLabel (PC+I)) {
- MarkAddr (PC, atIllegal);
- break;
- }
+ if (HaveLabel (PC+I)) {
+ MarkAddr (PC, atIllegal);
+ break;
+ }
}
}
}
/* Disassemble the line */
- switch (GetStyleAttr (PC)) {
+ switch (Style) {
case atDefault:
case atCode:
ByteTable ();
break;
+ case atDByteTab:
+ DByteTable ();
+ break;
+
case atWordTab:
WordTable ();
break;
TextTable ();
break;
+ case atSkip:
+ ++PC;
+ break;
+
default:
DataByteLine (1);
++PC;
/* Pass 2 */
Pass = 2;
ResetCode ();
+ OutputSettings ();
DefOutOfRangeLabels ();
OnePass ();
}
{
/* Program long options */
static const LongOpt OptTab[] = {
+ { "--comments", 1, OptComments },
{ "--cpu", 1, OptCPU },
+ { "--debug-info", 0, OptDebugInfo },
{ "--formfeeds", 0, OptFormFeeds },
{ "--help", 0, OptHelp },
+ { "--hexoffs", 0, OptHexOffs },
+ { "--info", 1, OptInfo },
{ "--pagelength", 1, OptPageLength },
{ "--start-addr", 1, OptStartAddr },
{ "--verbose", 0, OptVerbose },
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
break;
+ case 'g':
+ OptDebugInfo (Arg, 0);
+ break;
+
case 'h':
OptHelp (Arg, 0);
break;
+ case 'i':
+ OptInfo (Arg, GetArg (&I, 2));
+ break;
+
case 'o':
OutFile = GetArg (&I, 2);
break;
++I;
}
+ /* Try to read the info file */
+ ReadInfoFile ();
+
/* Must have an input file */
if (InFile == 0) {
AbEnd ("No input file");
}
- /* Make the config file name from the input file if none was given */
- if (!CfgAvail ()) {
- CfgSetName (MakeFilename (InFile, CfgExt));
- }
-
- /* Try to read the configuration file */
- CfgRead ();
-
- /* Make the output file name from the input file name if none was given */
- if (OutFile == 0) {
- OutFile = MakeFilename (InFile, OutExt);
+ /* If no CPU given, use the default CPU */
+ if (CPU == CPU_UNKNOWN) {
+ CPU = CPU_6502;
}
/* Load the input file */
- LoadCode (InFile, StartAddr);
+ LoadCode ();
/* Open the output file */
OpenOutput (OutFile);