atIllegal = 0x02,
atByteTab = 0x03, /* Same as illegal */
atWordTab = 0x04,
- atAddrTab = 0x05,
- atRtsTab = 0x06,
+ atDWordTab = 0x05,
+ atAddrTab = 0x06,
+ atRtsTab = 0x07,
atStyleMask = 0x0F /* Output style */
};
Error ("Error reading from `%s': %s", Name, strerror (errno));
}
if (Count == 0) {
- Error ("File `%s' contains no data", Name);
+ Error ("File `%s' contains no data", Name);
}
/* Set the buffer variables */
+unsigned long GetCodeDWord (unsigned Addr)
+/* Get a dword from the given address */
+{
+ unsigned long Lo = GetCodeWord (Addr);
+ unsigned long Hi = GetCodeWord (Addr+2);
+ return Lo | (Hi << 16);
+}
+
+
+
unsigned GetRemainingBytes (void)
/* Return the number of remaining code bytes */
{
if (CodeEnd >= PC) {
- return (CodeEnd - PC + 1);
+ return (CodeEnd - PC + 1);
} else {
- return 0;
+ return 0;
}
}
+int CodeLeft (void)
+/* Return true if there are code bytes left */
+{
+ return (PC <= CodeEnd);
+}
+
+
+
void ResetCode (void)
/* Reset the code input to start over for the next pass */
{
unsigned GetCodeWord (unsigned Addr);
/* Get a word from the given address */
+unsigned long GetCodeDWord (unsigned Addr);
+/* Get a dword from the given address */
+
unsigned GetRemainingBytes (void);
/* Return the number of remaining code bytes */
+int CodeLeft (void);
+/* Return true if there are code bytes left */
+
void ResetCode (void);
/* Reset the code input to start over for the next pass */
{ "CODE", CFGTOK_CODE },
{ "BYTETABLE", CFGTOK_BYTETAB },
{ "WORDTABLE", CFGTOK_WORDTAB },
+ { "DWORDTABLE", CFGTOK_DWORDTAB },
{ "ADDRTABLE", CFGTOK_ADDRTAB },
{ "RTSTABLE", CFGTOK_RTSTAB },
};
case CFGTOK_CODE: Type = atCode; break;
case CFGTOK_BYTETAB: Type = atByteTab; break;
case CFGTOK_WORDTAB: Type = atWordTab; break;
+ case CFGTOK_DWORDTAB: Type = atDWordTab; break;
case CFGTOK_ADDRTAB: Type = atAddrTab; break;
case CFGTOK_RTSTAB: Type = atRtsTab; break;
}
/* da65 */
#include "attrtab.h"
-#include "code.h"
+#include "code.h"
#include "error.h"
#include "global.h"
#include "output.h"
-void ByteTable (unsigned RemainingBytes)
-/* Output a table of bytes */
+static unsigned GetSpan (attr_t Style)
+/* Get the number of bytes for a given style */
{
- /* Count how many bytes may be output. This number is limited by the
- * number of remaining bytes, a label, or the end of the ByteTable
+ /* Get the number of bytes still available */
+ unsigned RemainingBytes = GetRemainingBytes ();
+
+ /* Count how many bytes are available. This number is limited by the
+ * number of remaining bytes, a label, or the end of the given Style
* attribute.
*/
unsigned Count = 1;
while (Count < RemainingBytes) {
- if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atByteTab) {
+ if (HaveLabel(PC+Count) || GetStyle (PC+Count) != Style) {
break;
}
++Count;
}
- RemainingBytes -= Count;
+
+ /* Return the number of bytes */
+ return Count;
+}
+
+
+
+static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned))
+/* Output a table of bytes */
+{
+ unsigned BytesLeft;
+
+ /* Count how many bytes may be output. */
+ unsigned Count = GetSpan (Style);
+
+ /* Make Count an even number of multiples of MemberSize */
+ Count &= ~(MemberSize-1);
/* Output as many data bytes lines as needed */
- while (Count > 0) {
+ BytesLeft = Count;
+ while (BytesLeft > 0) {
/* Calculate the number of bytes for the next line */
- unsigned Chunk = (Count > BytesPerLine)? BytesPerLine : Count;
+ unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
/* Output a line with these bytes */
- DataByteLine (Chunk);
+ TableFunc (Chunk);
/* Next line */
- Count -= Chunk;
- PC += Chunk;
+ BytesLeft -= Chunk;
+ PC += Chunk;
}
- /* If the next line is not a byte table line, add a separator */
- if (RemainingBytes > 0 && GetStyle (PC) != atByteTab) {
+ /* If the next line is not the same style, add a separator */
+ if (CodeLeft() && GetStyle (PC) != Style) {
SeparatorLine ();
}
+
+ /* Return the number of bytes output */
+ return Count;
}
-void WordTable (unsigned RemainingBytes)
-/* Output a table of words */
+unsigned ByteTable (void)
+/* Output a table of bytes */
{
- /* Count how many bytes may be output. This number is limited by the
- * number of remaining bytes, a label, or the end of the WordTable
- * attribute.
- */
- unsigned Count = 1;
- while (Count < RemainingBytes) {
- if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atWordTab) {
- break;
- }
- ++Count;
- }
- RemainingBytes -= Count;
+ /* Call the low level function */
+ return DoTable (atByteTab, 1, DataByteLine);
+}
- /* Make the given number even */
- Count &= ~1U;
- /* Output as many data word lines as needed */
- while (Count > 0) {
- /* Calculate the number of bytes for the next line */
- unsigned Chunk = (Count > BytesPerLine)? BytesPerLine : Count;
+unsigned WordTable (void)
+/* Output a table of words */
+{
+ /* Call the low level function */
+ return DoTable (atWordTab, 2, DataWordLine);
+}
- /* Output a line with these bytes */
- DataWordLine (Chunk);
- /* Next line */
- PC += Chunk;
- Count -= Chunk;
- }
- /* If the next line is not a byte table line, add a separator */
- if (RemainingBytes > 0 && GetStyle (PC) != atWordTab) {
- SeparatorLine ();
- }
+unsigned DWordTable (void)
+/* Output a table of double words */
+{
+ /* Call the low level function */
+ return DoTable (atDWordTab, 4, DataDWordLine);
}
-void AddrTable (unsigned RemainingBytes)
+unsigned AddrTable (void)
/* Output a table of addresses */
{
- /* Count how many bytes may be output. This number is limited by the
- * number of remaining bytes, a label, or the end of the WordTable
- * attribute.
- */
- unsigned Count = 1;
- while (Count < RemainingBytes) {
- if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atAddrTab) {
- break;
- }
- ++Count;
- }
- RemainingBytes -= Count;
+ unsigned BytesLeft;
+
+ /* Count how many bytes may be output. */
+ unsigned Count = GetSpan (atAddrTab);
/* Make the given number even */
Count &= ~1U;
/* Output as many data bytes lines as needed. For addresses, each line
* will hold just one address.
- */
- while (Count > 0) {
+ */
+ BytesLeft = Count;
+ while (BytesLeft > 0) {
/* Get the address */
unsigned Addr = GetCodeWord (PC);
/* In pass 1, define a label, in pass 2 output the line */
if (Pass == 1) {
if (!HaveLabel (Addr)) {
- AddLabel (Addr, MakeLabelName (Addr));
+ AddLabel (Addr, MakeLabelName (Addr));
}
} else {
const char* Label = GetLabel (Addr);
if (Label == 0) {
- /* OOPS! Should not happen */
- Internal ("OOPS - Label for address %04X disappeard!", Addr);
+ /* OOPS! Should not happen */
+ Internal ("OOPS - Label for address %04X disappeard!", Addr);
}
Indent (MIndent);
Output (".word");
}
/* Next line */
- PC += 2;
- Count -= 2;
+ PC += 2;
+ BytesLeft -= 2;
}
/* If the next line is not a byte table line, add a separator */
- if (RemainingBytes > 0 && GetStyle (PC) != atAddrTab) {
+ if (CodeLeft() && GetStyle (PC) != atAddrTab) {
SeparatorLine ();
- }
+ }
+
+ /* Return the number of bytes output */
+ return Count;
}
-void ByteTable (unsigned RemainingBytes);
+unsigned ByteTable (void);
/* Output a table of bytes */
-void WordTable (unsigned RemainingBytes);
+unsigned WordTable (void);
/* Output a table of words */
-void AddrTable (unsigned RemainingBytes);
+unsigned DWordTable (void);
+/* Output a table of double words */
+
+unsigned AddrTable (void);
/* Output a table of addresses */
/* Flags and other command line stuff */
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? */
+
/* Stuff needed by many routines */
-unsigned Pass = 0; /* Disassembler pass */
+unsigned char Pass = 0; /* Disassembler pass */
/* Page formatting */
int PageLength = -1; /* Length of a listing page */
unsigned MIndent = 9; /* Mnemonic indent */
unsigned AIndent = 17; /* Argument indent */
unsigned CIndent = 49; /* Comment indent */
+unsigned TIndent = 81; /* Text bytes indent */
unsigned BytesPerLine = 8; /* Max. number of data bytes per line */
/* Flags and other command line stuff */
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? */
/* Stuff needed by many routines */
-extern unsigned Pass; /* Disassembler pass */
+extern unsigned char Pass; /* Disassembler pass */
/* Page formatting */
#define MIN_PAGE_LEN 32
extern unsigned MIndent; /* Mnemonic indent */
extern unsigned AIndent; /* Argument indent */
extern unsigned CIndent; /* Comment indent */
+extern unsigned TIndent; /* Text bytes indent */
extern unsigned BytesPerLine; /* Max. number of data bytes per line */
break;
case atByteTab:
- ByteTable (RemainingBytes);
+ ByteTable ();
break;
case atWordTab:
- WordTable (RemainingBytes);
+ WordTable ();
+ break;
+
+ case atDWordTab:
+ DWordTable ();
break;
case atAddrTab:
- AddrTable (RemainingBytes);
+ AddrTable ();
break;
default:
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include <ctype.h>
#include <errno.h>
/* common */
void Output (const char* Format, ...)
/* Write to the output file */
{
- if (Pass > 1) {
+ if (Pass == PassCount) {
va_list ap;
va_start (ap, Format);
Col += vfprintf (F, Format, ap);
void Indent (unsigned N)
/* Make sure the current line column is at position N (zero based) */
{
- if (Pass > 1) {
+ if (Pass == PassCount) {
while (Col < N) {
fputc (' ', F);
++Col;
void LineFeed (void)
/* Add a linefeed to the output file */
{
- if (Pass > 1) {
+ if (Pass == PassCount) {
fputc ('\n', F);
if (++Line >= PageLength) {
if (FormFeeds) {
/* Define a label with the given name */
{
Output ("%s:", Name);
- LineFeed ();
+ /* Don't start a new line if the label is fully in the left column */
+ if (Col >= MIndent-1) {
+ LineFeed ();
+ }
}
-void DataByteLine (unsigned Count)
-/* Output a line with Count data bytes */
+void DataByteLine (unsigned ByteCount)
+/* Output a line with bytes */
{
unsigned I;
Indent (MIndent);
Output (".byte");
Indent (AIndent);
- for (I = 0; I < Count; ++I) {
+ for (I = 0; I < ByteCount; ++I) {
if (I > 0) {
Output (",$%02X", CodeBuf[PC+I]);
} else {
Output ("$%02X", CodeBuf[PC+I]);
}
}
- LineComment (PC, Count);
+ LineComment (PC, ByteCount);
LineFeed ();
}
-void DataWordLine (unsigned Count)
-/* Output a line with Count data words */
+void DataWordLine (unsigned ByteCount)
+/* Output a line with words */
{
unsigned I;
Indent (MIndent);
Output (".word");
Indent (AIndent);
- for (I = 0; I < Count; I += 2) {
+ for (I = 0; I < ByteCount; I += 2) {
if (I > 0) {
Output (",$%04X", GetCodeWord (PC+I));
} else {
Output ("$%04X", GetCodeWord (PC+I));
}
}
- LineComment (PC, Count);
+ LineComment (PC, ByteCount);
+ LineFeed ();
+}
+
+
+
+void DataDWordLine (unsigned ByteCount)
+/* Output a line with dwords */
+{
+ unsigned I;
+
+ Indent (MIndent);
+ Output (".dword");
+ Indent (AIndent);
+ for (I = 0; I < ByteCount; I += 4) {
+ if (I > 0) {
+ Output (",$%08lX", GetCodeDWord (PC+I));
+ } else {
+ Output ("$%08lX", GetCodeDWord (PC+I));
+ }
+ }
+ LineComment (PC, ByteCount);
LineFeed ();
}
void SeparatorLine (void)
/* Print a separator line */
{
- Output ("; ----------------------------------------------------------------------------");
- LineFeed ();
+ if (Pass == PassCount && Verbosity >= 1) {
+ Output ("; ----------------------------------------------------------------------------");
+ LineFeed ();
+ }
}
void LineComment (unsigned PC, unsigned Count)
/* Add a line comment with the PC and data bytes */
{
- if (Pass > 1 && Verbosity >= 3) {
+ unsigned I;
+
+ if (Pass == PassCount && Verbosity >= 2) {
Indent (CIndent);
Output ("; %04X", PC);
- if (Verbosity >= 4) {
- while (Count--) {
- Output (" %02X", CodeBuf [PC++]);
+ if (Verbosity >= 3) {
+ for (I = 0; I < Count; ++I) {
+ Output (" %02X", CodeBuf [PC+I]);
+ }
+ if (Verbosity >= 4) {
+ Indent (TIndent);
+ for (I = 0; I < Count; ++I) {
+ unsigned char C = CodeBuf [PC+I];
+ if (!isprint (C)) {
+ C = '.';
+ }
+ Output ("%c", C);
+ }
}
}
}
void OneDataByte (void);
/* Output a .byte line with the current code byte */
-void DataByteLine (unsigned Count);
-/* Output a line with Count data bytes */
+void DataByteLine (unsigned ByteCount);
+/* Output a line with bytes */
-void DataWordLine (unsigned Count);
-/* Output a line with Count data words */
+void DataWordLine (unsigned ByteCount);
+/* Output a line with words */
+
+void DataDWordLine (unsigned ByteCount);
+/* Output a line with dwords */
void SeparatorLine (void);
/* Print a separator line */
CFGTOK_CODE,
CFGTOK_BYTETAB,
CFGTOK_WORDTAB,
+ CFGTOK_DWORDTAB,
CFGTOK_ADDRTAB,
CFGTOK_RTSTAB,