/* */
/* */
/* */
-/* (C) 1998-2011, Ullrich von Bassewitz */
+/* (C) 1998-2014, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "opctable.h"
#include "output.h"
#include "scanner.h"
+#include "segment.h"
" -v\t\t\tIncrease verbosity\n"
" -F\t\t\tAdd formfeeds to the output\n"
" -S addr\t\tSet the start/load address\n"
+ " -s\t\t\tAccept line markers in the info file\n"
" -V\t\t\tPrint the disassembler version\n"
"\n"
"Long options:\n"
" --mnemonic-column n\tSpecify mnemonic start column\n"
" --pagelength n\tSet the page length for the listing\n"
" --start-addr addr\tSet the start/load address\n"
+ " --sync-lines\t\tAccept line markers in the info file\n"
" --text-column n\tSpecify text start column\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the disassembler version\n",
+static void OptSyncLines (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* Handle the --sync-lines option */
+{
+ SyncLines = 1;
+}
+
+
+
static void OptTextColumn (const char* Opt, const char* Arg)
/* Handle the --text-column option */
{
const char* Arg attribute ((unused)))
/* Print the disassembler version */
{
- fprintf (stderr, "da65 V%s\n", GetVersionAsString ());
+ fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
+ exit(EXIT_SUCCESS);
}
static void OneOpcode (unsigned RemainingBytes)
/* Disassemble one opcode */
{
+ unsigned I;
+ unsigned OldPC = PC;
+
/* Get the opcode from the current address */
unsigned char OPC = GetCodeByte (PC);
/* Get the output style for the current PC */
attr_t Style = GetStyleAttr (PC);
+ /* If a segment begins here, then name that segment.
+ ** Note that the segment is named even if its code is being skipped,
+ ** because some of its later code might not be skipped.
+ */
+ if (IsSegmentStart (PC)) {
+ StartSegment (GetSegmentStartName (PC), GetSegmentAddrSize (PC));
+ }
+
/* If we have a label at this address, output the label and an attached
** comment, provided that we aren't in a skip area.
*/
** - ...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 false, switch to data mode.
+ ** - ...if there is no segment change between the instruction bytes.
+ ** If any one of those conditions is false, switch to data mode.
*/
if (Style == atDefault) {
if (D->Size > RemainingBytes) {
Style = atIllegal;
MarkAddr (PC, Style);
} else {
- unsigned I;
- for (I = 1; I < D->Size; ++I) {
- if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) {
+ for (I = PC + D->Size; --I > PC; ) {
+ if (HaveLabel (I) || IsSegmentStart (I)) {
+ Style = atIllegal;
+ MarkAddr (PC, Style);
+ break;
+ }
+ }
+ for (I = 0; I < D->Size - 1u; ++I) {
+ if (IsSegmentEnd (PC + I)) {
Style = atIllegal;
MarkAddr (PC, Style);
break;
*/
if (D->Size <= RemainingBytes) {
/* Output labels within the next insn */
- unsigned I;
for (I = 1; I < D->Size; ++I) {
ForwardLabel (I);
}
DataByteLine (1);
++PC;
break;
+ }
+ /* Change back to the default CODE segment if
+ ** a named segment stops at the current address.
+ */
+ for (I = PC - OldPC; I > 0; --I) {
+ if (IsSegmentEnd (PC - I)) {
+ EndSegment ();
+ break;
+ }
}
}
{ "--mnemonic-column", 1, OptMnemonicColumn },
{ "--pagelength", 1, OptPageLength },
{ "--start-addr", 1, OptStartAddr },
+ { "--sync-lines", 0, OptSyncLines },
{ "--text-column", 1, OptTextColumn },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
OptStartAddr (Arg, GetArg (&I, 2));
break;
+ case 's':
+ OptSyncLines (Arg, 0);
+ break;
+
case 'V':
OptVersion (Arg, 0);
break;