/* Load the code from the given file */
{
unsigned Count, MaxCount;
+ long Size;
FILE* F;
/* Open the file */
F = fopen (Name, "rb");
if (F == 0) {
- Error ("Cannot open `%s': %s", Name, strerror (errno));
+ Error ("Cannot open `%s': %s", Name, strerror (errno));
+ }
+
+ /* Seek to the end to get the size of the file */
+ if (fseek (F, 0, SEEK_END) != 0) {
+ Error ("Cannot seek on file `%s': %s", Name, strerror (errno));
+ }
+ Size = ftell (F);
+ rewind (F);
+
+ /* Check if the size is larger than what we can read */
+ if (Size == 0) {
+ Error ("File `%s' contains no data", Name);
+ }
+ if (Size > MaxCount) {
+ Warning ("File `%s' is too large, ignoring %ld bytes",
+ Name, Size - MaxCount);
+ } else if (MaxCount > Size) {
+ MaxCount = (unsigned) Size;
}
/* Read from the file and remember the number of bytes read */
Count = fread (CodeBuf + StartAddress, 1, MaxCount, F);
- if (ferror (F)) {
- Error ("Error reading from `%s': %s", Name, strerror (errno));
- }
- if (Count == 0) {
- Error ("File `%s' contains no data", Name);
+ if (ferror (F) || Count != MaxCount) {
+ Error ("Error reading from `%s': %s", Name, strerror (errno));
}
+ /* Close the file */
+ fclose (F);
+
/* Set the buffer variables */
CodeStart = PC = StartAddress;
CodeEnd = CodeStart + Count - 1; /* CodeEnd is inclusive */
{ "INPUTNAME", CFGTOK_INPUTNAME },
{ "OUTPUTNAME", CFGTOK_OUTPUTNAME },
{ "PAGELENGTH", CFGTOK_PAGELENGTH },
+ { "STARTADDR", CFGTOK_STARTADDR },
};
/* Skip the token */
PageLength = CfgIVal;
CfgNextTok ();
break;
+
+ case CFGTOK_STARTADDR:
+ CfgNextTok ();
+ CfgAssureInt ();
+ CfgRangeCheck (0x0000, 0xFFFF);
+ StartAddr = CfgIVal;
+ CfgNextTok ();
+ break;
+
}
/* Directive is followed by a semicolon */
/* Count how many bytes may be output. */
unsigned Count = GetSpan (atAddrTab);
- /* Need to handle Count == 1 here!!! ### */
+ /* Handle Count == 1 ### */
+ if (Count == 1) {
+ ByteTable ();
+ }
/* Make the given number even */
Count &= ~1U;
unsigned char Verbosity = 4; /* Verbosity of the output file */
unsigned char FormFeeds = 0; /* Add form feeds to the output? */
unsigned char PassCount = 2; /* How many passed do we do? */
+unsigned long StartAddr = 0xC000; /* Start/load address of the program */
/* Stuff needed by many routines */
unsigned char Pass = 0; /* Disassembler pass */
extern unsigned char Verbosity; /* Verbosity of the output file */
extern unsigned char FormFeeds; /* Add form feeds to the output? */
extern unsigned char PassCount; /* How many passed do we do? */
+extern unsigned long StartAddr; /* Start/load address of the program */
+
/* Stuff needed by many routines */
extern unsigned char Pass; /* Disassembler pass */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
" -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 assembler version\n"
+ " -S addr\t\tSet the start/load address\n"
+ " -V\t\t\tPrint the disassembler version\n"
"\n"
"Long options:\n"
" --cpu type\t\tSet cpu type\n"
" --formfeeds\t\tAdd formfeeds to the output\n"
" --help\t\tHelp (this text)\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"
- " --version\t\tPrint the assembler version\n",
+ " --version\t\tPrint the disassembler version\n",
ProgName);
}
+static unsigned long CvtNumber (const char* Arg, const char* Number)
+/* Convert a number from a string. Allow '$' and '0x' prefixes for hex
+ * numbers.
+ */
+{
+ unsigned long Val;
+ int Converted;
+
+ /* Convert */
+ if (*Number == '$') {
+ ++Number;
+ Converted = sscanf (Number, "%lx", &Val);
+ } else {
+ Converted = sscanf (Number, "%li", (long*)&Val);
+ }
+
+ /* Check if we do really have a number */
+ if (Converted != 1) {
+ Error ("Invalid number given in argument: %s\n", Arg);
+ }
+
+ /* Return the result */
+ return Val;
+}
+
+
+
static void OptCPU (const char* Opt, const char* Arg)
/* Handle the --cpu option */
{
+static void OptStartAddr (const char* Opt, const char* Arg)
+/* Set the default start address */
+{
+ StartAddr = CvtNumber (Opt, Arg);
+}
+
+
+
static void OptVerbose (const char* Opt, const char* Arg)
/* Increase verbosity */
{
{ "--formfeeds", 0, OptFormFeeds },
{ "--help", 0, OptHelp },
{ "--pagelength", 1, OptPageLength },
+ { "--start-addr", 1, OptStartAddr },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
};
OptVerbose (Arg, 0);
break;
+ case 'S':
+ OptStartAddr (Arg, GetArg (&I, 2));
+ break;
+
case 'V':
OptVersion (Arg, 0);
break;
}
/* Load the input file */
- LoadCode (InFile, 0xE000); /* ### */
+ LoadCode (InFile, StartAddr);
/* Open the output file */
OpenOutput (OutFile);
CFGTOK_INPUTNAME,
CFGTOK_OUTPUTNAME,
CFGTOK_PAGELENGTH,
+ CFGTOK_STARTADDR,
/* Range section */
CFGTOK_START,