#include "xsprintf.h"
/* da65 */
+#include "code.h"
#include "error.h"
+#include "global.h"
+#include "output.h"
#include "attrtab.h"
+static void DefineConst (unsigned Addr)
+/* Define an address constant */
+{
+ Output ("%s", SymTab [Addr]);
+ Indent (AIndent);
+ Output ("= $%04X", Addr);
+ LineFeed ();
+}
+
+
+
+void DefOutOfRangeLabels (void)
+/* Output any labels that are out of the loaded code range */
+{
+ unsigned long Addr;
+
+ SeparatorLine ();
+
+ /* Low range */
+ for (Addr = 0; Addr < CodeStart; ++Addr) {
+ if (SymTab [Addr]) {
+ DefineConst (Addr);
+ }
+ }
+
+ /* High range */
+ for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) {
+ if (SymTab [Addr]) {
+ DefineConst (Addr);
+ }
+ }
+
+ SeparatorLine ();
+}
+
+
+
atDefault = 0x00, /* Default style */
atCode = 0x01,
atIllegal = 0x02,
- atByteTab = 0x02, /* Same as illegal */
+ atByteTab = 0x03, /* Same as illegal */
atWordTab = 0x04,
- atRtsTab = 0x08,
- atLabel = 0x80,
+ atAddrTab = 0x05,
+ atRtsTab = 0x06,
atStyleMask = 0x0F /* Output style */
};
unsigned char GetStyle (unsigned Addr);
/* Return the style attribute for the given address */
+void DefOutOfRangeLabels (void);
+/* Output any labels that are out of the loaded code range */
+
/* End of attrtab.h */
-static unsigned char CodeBuf [0x10000]; /* Code buffer */
-static unsigned long CodeStart; /* Start address */
-static unsigned long CodeEnd; /* End address */
-static unsigned long PC; /* Current PC */
+unsigned char CodeBuf [0x10000]; /* Code buffer */
+unsigned long CodeStart; /* Start address */
+unsigned long CodeEnd; /* End address */
+unsigned long PC; /* Current PC */
-unsigned GetPC (void)
-/* Get the current program counter */
+unsigned char GetCodeByte (unsigned Addr)
+/* Get a byte from the given address */
{
- return PC;
+ PRECONDITION (Addr <= CodeEnd);
+ return CodeBuf [Addr];
}
-unsigned char PeekCodeByte (void)
-/* Peek at the byte at the current PC */
+unsigned GetCodeWord (unsigned Addr)
+/* Get a word from the given address */
{
- PRECONDITION (PC <= CodeEnd);
- return CodeBuf [PC];
-}
-
-
-
-unsigned char GetCodeByte (void)
-/* Get a byte from the PC and increment it */
-{
- PRECONDITION (PC <= CodeEnd);
- return CodeBuf [PC++];
-}
-
-
-
-unsigned GetCodeWord (void)
-/* Get a word from the current PC and increment it */
-{
- unsigned Lo = GetCodeByte ();
- unsigned Hi = GetCodeByte ();
+ unsigned Lo = GetCodeByte (Addr);
+ unsigned Hi = GetCodeByte (Addr+1);
return Lo | (Hi << 8);
}
/*****************************************************************************/
-/* Code */
+/* Data */
/*****************************************************************************/
-void LoadCode (const char* Name, unsigned long StartAddress);
-/* Load the code from the given file */
+extern unsigned char CodeBuf [0x10000]; /* Code buffer */
+extern unsigned long CodeStart; /* Start address */
+extern unsigned long CodeEnd; /* End address */
+extern unsigned long PC; /* Current PC */
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
-unsigned GetPC (void);
-/* Get the current program counter */
-unsigned char PeekCodeByte (void);
-/* Peek at the byte at the current PC */
+void LoadCode (const char* Name, unsigned long StartAddress);
+/* Load the code from the given file */
-unsigned char GetCodeByte (void);
-/* Get a byte from the PC and increment it */
+unsigned char GetCodeByte (unsigned Addr);
+/* Get a byte from the given address */
-unsigned GetCodeWord (void);
-/* Get a word from the current PC and increment it */
+unsigned GetCodeWord (unsigned Addr);
+/* Get a word from the given address */
unsigned GetRemainingBytes (void);
/* Return the number of remaining code bytes */
/*****************************************************************************/
/* */
-/* config.c */
+/* config.c */
/* */
/* Disassembler configuration file handling */
/* */
#include "xmalloc.h"
/* da65 */
+#include "attrtab.h"
+#include "error.h"
#include "global.h"
#include "scanner.h"
#include "config.h"
/* Parse a range section */
{
static const IdentTok RangeDefs[] = {
- { "START", CFGTOK_START },
- { "END", CFGTOK_END },
+ { "START", CFGTOK_START },
+ { "END", CFGTOK_END },
{ "TYPE", CFGTOK_TYPE },
};
+ static const IdentTok TypeDefs[] = {
+ { "CODE", CFGTOK_CODE },
+ { "BYTETABLE", CFGTOK_BYTETAB },
+ { "WORDTABLE", CFGTOK_WORDTAB },
+ { "ADDRTABLE", CFGTOK_ADDRTAB },
+ { "RTSTABLE", CFGTOK_RTSTAB },
+ };
+
+
+ /* Which values did we get? */
+ enum {
+ tNone = 0x00,
+ tStart = 0x01,
+ tEnd = 0x02,
+ tType = 0x04,
+ tAll = 0x07
+ } Needed = tNone;
+
+ /* Locals - initialize to avoid gcc warnings */
+ unsigned Start = 0;
+ unsigned End = 0;
+ unsigned char Type = 0;
+
/* Skip the token */
CfgNextTok ();
/* Look for section tokens */
while (CfgTok != CFGTOK_RCURLY) {
+ /* Convert to special token */
+ CfgSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
+ /* Look at the token */
+ switch (CfgTok) {
+
+ case CFGTOK_START:
+ CfgNextTok ();
+ CfgAssureInt ();
+ CfgRangeCheck (0x0000, 0xFFFF);
+ Start = CfgIVal;
+ Needed |= tStart;
+ CfgNextTok ();
+ break;
+
+ case CFGTOK_END:
+ CfgNextTok ();
+ CfgAssureInt ();
+ CfgRangeCheck (0x0000, 0xFFFF);
+ End = CfgIVal;
+ Needed |= tEnd;
+ CfgNextTok ();
+ break;
+
+ case CFGTOK_TYPE:
+ CfgNextTok ();
+ CfgSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
+ switch (CfgTok) {
+ case CFGTOK_CODE: Type = atCode; break;
+ case CFGTOK_BYTETAB: Type = atByteTab; break;
+ case CFGTOK_WORDTAB: Type = atWordTab; break;
+ case CFGTOK_ADDRTAB: Type = atAddrTab; break;
+ case CFGTOK_RTSTAB: Type = atRtsTab; break;
+ }
+ Needed |= tType;
+ CfgNextTok ();
+ break;
+ }
+
+ /* Directive is followed by a semicolon */
+ CfgConsumeSemi ();
+
+ }
+
+ /* Did we get all required values? */
+ if (Needed != tAll) {
+ Error ("Required values missing from this section");
}
+ /* Start must be less than end */
+ if (Start > End) {
+ Error ("Start value must not be greater than end value");
+ }
+
+ /* Set the range */
+ MarkRange (Start, End, Type);
+
/* Consume the closing brace */
CfgConsumeRCurly ();
}
const char CfgExt[] = ".cfg"; /* Config file extension */
/* Flags and other command line stuff */
-unsigned char Verbosity = 2; /* Verbosity of the output file */
+unsigned char Verbosity = 4; /* Verbosity of the output file */
/* Stuff needed by many routines */
unsigned Pass = 0; /* Disassembler pass */
int PageLength = -1; /* Length of a listing page */
unsigned MIndent = 9; /* Mnemonic indent */
unsigned AIndent = 17; /* Argument indent */
-unsigned CIndent = 33; /* Comment indent */
+unsigned CIndent = 49; /* Comment indent */
+unsigned BytesPerLine = 8; /* Max. number of data bytes per line */
extern unsigned MIndent; /* Mnemonic indent */
extern unsigned AIndent; /* Argument indent */
extern unsigned CIndent; /* Comment indent */
+extern unsigned BytesPerLine; /* Max. number of data bytes per line */
-static void OneLine (const char* Mnemo, const char* Arg, ...) attribute ((format(printf, 2, 3)));
-static void OneLine (const char* Mnemo, const char* Arg, ...)
+static void OneLine (const OpcDesc* D, const char* Arg, ...) attribute ((format(printf, 2, 3)));
+static void OneLine (const OpcDesc* D, const char* Arg, ...)
/* Output one line with the given mnemonic and argument */
{
char Buf [256];
va_list ap;
/* Mnemonic */
- Mnemonic (Mnemo);
+ Mnemonic (D->Mnemo);
/* Argument */
va_start (ap, Arg);
Indent (AIndent);
Output (Buf);
+ /* Add the code stuff as comment */
+ LineComment (PC, D->Size);
+
/* End the line */
LineFeed ();
}
static void GenerateLabel (const OpcDesc* D, unsigned Addr)
/* Generate a label in pass one if requested */
{
- if (Pass == 1 && !HaveLabel (Addr) && (D->LabelFlag & lfGenLabel) != 0) {
- AddLabel (Addr, MakeLabelName (Addr));
+ if (Pass == 1 && !HaveLabel (Addr)) {
+ if ((D->LabelFlag & lfGenLabel) != 0 ||
+ ((D->LabelFlag & lfUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) {
+ AddLabel (Addr, MakeLabelName (Addr));
+ }
}
}
void OH_Accumulator (const OpcDesc* D)
{
- OneLine (D->Mnemo, "a");
+ OneLine (D, "a");
}
void OH_Implicit (const OpcDesc* D)
{
Mnemonic (D->Mnemo);
+ LineComment (PC, D->Size);
LineFeed ();
}
void OH_Immidiate (const OpcDesc* D)
{
- OneLine (D->Mnemo, "#$%02X", GetCodeByte ());
+ OneLine (D, "#$%02X", GetCodeByte (PC+1));
}
void OH_Direct (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeByte ();
+ unsigned Addr = GetCodeByte (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
+ OneLine (D, "%s", GetAddrArg (D, Addr));
}
void OH_DirectX (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeByte ();
+ unsigned Addr = GetCodeByte (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
+ OneLine (D, "%s,y", GetAddrArg (D, Addr));
}
void OH_DirectY (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeByte ();
+ unsigned Addr = GetCodeByte (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
+ OneLine (D, "%s,y", GetAddrArg (D, Addr));
}
void OH_Absolute (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeWord ();
+ unsigned Addr = GetCodeWord (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
+ OneLine (D, "%s", GetAddrArg (D, Addr));
}
void OH_AbsoluteX (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeWord ();
+ unsigned Addr = GetCodeWord (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s,x", GetAddrArg (D, Addr));
+ OneLine (D, "%s,x", GetAddrArg (D, Addr));
}
void OH_AbsoluteY (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeWord ();
+ unsigned Addr = GetCodeWord (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
+ OneLine (D, "%s,y", GetAddrArg (D, Addr));
}
void OH_Relative (const OpcDesc* D)
{
/* Get the operand */
- signed char Offs = GetCodeByte ();
+ signed char Offs = GetCodeByte (PC+1);
/* Calculate the target address */
- unsigned Addr = (unsigned) (((int) GetPC()) + Offs);
+ unsigned Addr = (unsigned) (((int) PC+2) + Offs);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
+ OneLine (D, "%s", GetAddrArg (D, Addr));
}
void OH_DirectIndirect (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeByte ();
+ unsigned Addr = GetCodeByte (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "(%s)", GetAddrArg (D, Addr));
+ OneLine (D, "(%s)", GetAddrArg (D, Addr));
}
void OH_DirectIndirectY (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeByte ();
+ unsigned Addr = GetCodeByte (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "(%s),y", GetAddrArg (D, Addr));
+ OneLine (D, "(%s),y", GetAddrArg (D, Addr));
}
void OH_DirectXIndirect (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeByte ();
+ unsigned Addr = GetCodeByte (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "(%s,x)", GetAddrArg (D, Addr));
+ OneLine (D, "(%s,x)", GetAddrArg (D, Addr));
}
void OH_AbsoluteIndirect (const OpcDesc* D)
{
/* Get the operand */
- unsigned Addr = GetCodeWord ();
+ unsigned Addr = GetCodeWord (PC+1);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
- OneLine (D->Mnemo, "(%s)", GetAddrArg (D, Addr));
+ OneLine (D, "(%s)", GetAddrArg (D, Addr));
}
+
#include "code.h"
#include "config.h"
#include "cpu.h"
+#include "error.h"
#include "global.h"
#include "opctable.h"
#include "output.h"
+static void ByteTable (unsigned RemainingBytes)
+/* 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 ByteTable
+ * attribute.
+ */
+ unsigned Count = 1;
+ while (Count < RemainingBytes) {
+ if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atByteTab) {
+ break;
+ }
+ ++Count;
+ }
+ RemainingBytes -= Count;
+
+ /* Output as many data bytes lines as needed */
+ while (Count > 0) {
+
+ /* Calculate the number of bytes for the next line */
+ unsigned Chunk = (Count > BytesPerLine)? BytesPerLine : Count;
+
+ /* Output a line with these bytes */
+ DataByteLine (Chunk);
+
+ /* Next line */
+ Count -= Chunk;
+ PC += Chunk;
+ }
+
+ /* If the next line is not a byte table line, add a separator */
+ if (RemainingBytes > 0 && GetStyle (PC) != atByteTab) {
+ SeparatorLine ();
+ }
+}
+
+
+
+static void WordTable (unsigned RemainingBytes)
+/* Output a table of words */
+{
+ /* 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;
+
+ /* 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;
+
+ /* 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 ();
+ }
+}
+
+
+
+static void AddrTable (unsigned RemainingBytes)
+/* 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;
+
+ /* 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) {
+
+ /* 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));
+ }
+ } else {
+ const char* Label = GetLabel (Addr);
+ if (Label == 0) {
+ /* OOPS! Should not happen */
+ Internal ("OOPS - Label for address %04X disappeard!", Addr);
+ }
+ Indent (MIndent);
+ Output (".word");
+ Indent (AIndent);
+ Output ("%s", Label);
+ LineComment (PC, 2);
+ LineFeed ();
+ }
+
+ /* Next line */
+ PC += 2;
+ Count -= 2;
+ }
+
+ /* If the next line is not a byte table line, add a separator */
+ if (RemainingBytes > 0 && GetStyle (PC) != atAddrTab) {
+ SeparatorLine ();
+ }
+}
+
+
+
static void OneOpcode (unsigned RemainingBytes)
/* Disassemble one opcode */
{
- /* Get the current PC */
- unsigned PC = GetPC ();
-
/* Get the opcode from the current address */
- unsigned char OPC = PeekCodeByte ();
+ unsigned char OPC = GetCodeByte (PC);
/* Get the opcode description for the opcode byte */
const OpcDesc* D = &OpcTable[OPC];
case atDefault:
case atCode:
- GetCodeByte ();
D->Handler (D);
+ PC += D->Size;
+ break;
+
+ case atByteTab:
+ ByteTable (RemainingBytes);
+ break;
+
+ case atWordTab:
+ WordTable (RemainingBytes);
+ break;
+
+ case atAddrTab:
+ AddrTable (RemainingBytes);
break;
default:
- OneDataByte ();
+ DataByteLine (1);
+ ++PC;
break;
}
LineFeed ();
/* Pass 2 */
+ Pass = 2;
ResetCode ();
- Pass = 2;
+ DefOutOfRangeLabels ();
OnePass ();
}
include .depend
else
all: depend
- @$(MAKE) -f make/gcc.mak all
+ @$(MAKE) -f make/gcc.mak all
endif
--- /dev/null
+#
+# da65 Makefile for the Watcom compiler
+#
+
+# ------------------------------------------------------------------------------
+# Generic stuff
+
+.AUTODEPEND
+.SUFFIXES .ASM .C .CC .CPP
+.SWAP
+
+AR = WLIB
+LD = WLINK
+
+!if !$d(TARGET)
+!if $d(__OS2__)
+TARGET = OS2
+!else
+TARGET = NT
+!endif
+!endif
+
+# target specific macros.
+!if $(TARGET)==OS2
+
+# --------------------- OS2 ---------------------
+SYSTEM = os2v2
+CC = WCC386
+CCCFG = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
+
+!elif $(TARGET)==DOS32
+
+# -------------------- DOS4G --------------------
+SYSTEM = dos4g
+CC = WCC386
+CCCFG = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
+
+!elif $(TARGET)==DOS
+
+# --------------------- DOS ---------------------
+SYSTEM = dos
+CC = WCC
+CCCFG = -bt=$(TARGET) -d1 -onatx -zp2 -2 -ml -zq -w2
+
+!elif $(TARGET)==NT
+
+# --------------------- NT ----------------------
+SYSTEM = nt
+CC = WCC386
+CCCFG = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
+
+!else
+!error
+!endif
+
+# Add the include dir
+CCCFG = $(CCCFG) -i=..\common
+
+
+# ------------------------------------------------------------------------------
+# Implicit rules
+
+.c.obj:
+ $(CC) $(CCCFG) $<
+
+
+# ------------------------------------------------------------------------------
+# All OBJ files
+
+OBJS = attrtab.obj \
+ code.obj \
+ config.obj \
+ cpu.obj \
+ error.obj \
+ global.obj \
+ handler.obj \
+ main.obj \
+ opctable.obj \
+ output.obj \
+ scanner.obj
+
+
+LIBS = ..\common\common.lib
+
+
+# ------------------------------------------------------------------------------
+# Main targets
+
+all: da65
+
+da65: da65.exe
+
+
+# ------------------------------------------------------------------------------
+# Other targets
+
+
+da65.exe: $(OBJS) $(LIBS)
+ $(LD) system $(SYSTEM) @&&|
+DEBUG ALL
+OPTION QUIET
+NAME $<
+FILE attrtab.obj
+FILE code.obj
+FILE config.obj
+FILE cpu.obj
+FILE error.obj
+FILE global.obj
+FILE handler.obj
+FILE main.obj
+FILE opctable.obj
+FILE output.obj
+FILE scanner.obj
+LIBRARY ..\common\common.lib
+|
+
+clean:
+ @if exist *.obj del *.obj
+ @if exist *.obj del da65.exe
+
+strip:
+ @-wstrip da65.exe
+
-void OneDataByte (void)
-/* Output a .byte line with the current code byte */
+void DataByteLine (unsigned Count)
+/* Output a line with Count data bytes */
{
- unsigned char B = GetCodeByte ();
+ unsigned I;
+
+ Indent (MIndent);
+ Output (".byte");
+ Indent (AIndent);
+ for (I = 0; I < Count; ++I) {
+ if (I > 0) {
+ Output (",$%02X", CodeBuf[PC+I]);
+ } else {
+ Output ("$%02X", CodeBuf[PC+I]);
+ }
+ }
+ LineComment (PC, Count);
+ LineFeed ();
+}
- if (Pass > 1) {
- Indent (MIndent);
- Output (".byte");
- Indent (AIndent);
- Output ("$%02X", B);
- LineFeed ();
+
+
+void DataWordLine (unsigned Count)
+/* Output a line with Count data words */
+{
+ unsigned I;
+
+ Indent (MIndent);
+ Output (".word");
+ Indent (AIndent);
+ for (I = 0; I < Count; I += 2) {
+ if (I > 0) {
+ Output (",$%04X", GetCodeWord (PC+I));
+ } else {
+ Output ("$%04X", GetCodeWord (PC+I));
+ }
}
+ LineComment (PC, Count);
+ LineFeed ();
}
void SeparatorLine (void)
/* Print a separator line */
{
- Output ("; -------------------------------------------------------------------------");
+ Output ("; ----------------------------------------------------------------------------");
LineFeed ();
}
-
+void LineComment (unsigned PC, unsigned Count)
+/* Add a line comment with the PC and data bytes */
+{
+ if (Pass > 1 && Verbosity >= 3) {
+ Indent (CIndent);
+ Output ("; %04X", PC);
+ if (Verbosity >= 4) {
+ while (Count--) {
+ Output (" %02X", CodeBuf [PC++]);
+ }
+ }
+ }
+}
+
+
+
void OneDataByte (void);
/* Output a .byte line with the current code byte */
+void DataByteLine (unsigned Count);
+/* Output a line with Count data bytes */
+
+void DataWordLine (unsigned Count);
+/* Output a line with Count data words */
+
void SeparatorLine (void);
/* Print a separator line */
+void LineComment (unsigned PC, unsigned Count);
+/* Add a line comment with the PC and data bytes */
+
/* End of output.h */
CFGTOK_END,
CFGTOK_TYPE,
+ CFGTOK_CODE,
+ CFGTOK_BYTETAB,
+ CFGTOK_WORDTAB,
+ CFGTOK_ADDRTAB,
+ CFGTOK_RTSTAB,
+
/* Label section */
typedef struct IdentTok_ IdentTok;
struct IdentTok_ {
const char* Ident; /* Identifier */
- token_t Tok; /* Token for identifier */
+ token_t Tok; /* Token for identifier */
};
#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0]))