/* common */
#include "check.h"
+/* b6502 */
+#include "codeseg.h"
+#include "dataseg.h"
+
/* cc65 */
-#include "asmline.h"
+#include "codegen.h"
#include "global.h"
#include "asmcode.h"
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-void AddCodeLine (const char* Format, ...)
-/* Add a new line of code to the output */
-{
- va_list ap;
- va_start (ap, Format);
- NewCodeLine (Format, ap);
- va_end (ap);
-}
-
-
-
void AddCodeHint (const char* Hint)
/* Add an optimizer hint */
{
- AddCodeLine ("+%s", Hint);
-}
-
-
-
-void AddEmptyLine (void)
-/* Add an empty line for formatting purposes */
-{
- /* Use a somewhat weird construct to avoid that gcc complains about
- * an empty format string.
- */
- static const char EmptyLine[] = "";
- AddCodeLine (EmptyLine);
+ /* ### AddCodeLine ("+%s", Hint); */
}
CodeMark GetCodePos (void)
/* Get a marker pointing to the current output position */
{
+ unsigned EntryCount = GetCodeSegEntries (CS);
+
/* This function should never be called without any code output */
- CHECK (LastLine != 0);
+ CHECK (EntryCount > 0);
- return LastLine;
+ return EntryCount;
}
void RemoveCode (CodeMark M)
/* Remove all code after the given code marker */
{
- while (LastLine != M) {
- FreeCodeLine (LastLine);
- }
+ DelCodeSegAfter (CS, M);
}
void WriteOutput (FILE* F)
/* Write the final output to a file */
{
- Line* L = FirstLine;
- while (L) {
- /* Don't write optimizer hints if not requested to do so */
- if (L->Line[0] == '+') {
- if (Debug) {
- fprintf (F, ";%s\n", L->Line);
- }
- } else {
- fprintf (F, "%s\n", L->Line);
- }
- L = L->Next;
- }
+ OutputDataSeg (F, DS);
+ MergeCodeLabels (CS);
+ OutputCodeSeg (F, CS);
}
/* Marker for an assembler code position */
-typedef struct Line* CodeMark;
+typedef unsigned CodeMark;
-void AddCodeLine (const char* Format, ...) attribute ((format(printf,1,2)));
-/* Add a new line of code to the output */
-
void AddCodeHint (const char* Hint);
/* Add an optimizer hint */
-void AddEmptyLine (void);
-/* Add an empty line for formatting purposes */
-
CodeMark GetCodePos (void);
/* Get a marker pointing to the current output position */
/* common */
+#include "check.h"
#include "xmalloc.h"
-/* b6502 */
+/* cc65 */
#include "error.h"
+
+/* b6502 */
+#include "codeinfo.h"
#include "label.h"
#include "opcodes.h"
#include "codeent.h"
-CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM)
+CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM, CodeLabel* JumpTo)
/* Create a new code entry, initialize and return it */
{
/* Allocate memory */
E->Hints = 0;
E->Arg.Num = 0;
E->Flags = 0;
- E->Usage = D->Usage;
- E->JumpTo = 0;
+ E->Usage = D->Info & (CI_MASK_USE | CI_MASK_CHG);
+ E->JumpTo = JumpTo;
InitCollection (&E->Labels);
+ /* If we have a label given, add this entry to the label */
+ if (JumpTo) {
+ CollAppend (&JumpTo->JumpFrom, E);
+ }
+
/* Return the initialized struct */
return E;
}
switch (E->AM) {
case AM_IMP:
- /* implicit + accumulator */
+ /* implicit */
+ break;
+
+ case AM_ACC:
+ /* accumulator */
+ fprintf (F, "\ta");
break;
case AM_IMM:
case AM_ZP:
case AM_ABS:
- case AM_BRA:
- /* zeropage, absolute and branch */
+ /* zeropage and absolute */
fprintf (F, "\t%s", E->Arg.Expr);
break;
fprintf (F, "\t(%s)", E->Arg.Expr);
break;
+ case AM_BRA:
+ /* branch */
+ CHECK (E->JumpTo != 0);
+ fprintf (F, "\t%s", E->JumpTo->Name);
+ break;
+
default:
Internal ("Invalid addressing mode");
-CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM);
+CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM, CodeLabel* JumpTo);
/* Create a new code entry, initialize and return it */
void FreeCodeEntry (CodeEntry* E);
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
/* common */
#include "check.h"
#include "version.h"
#include "xmalloc.h"
+#include "xsprintf.h"
/* cc65 */
#include "asmcode.h"
#include "error.h"
#include "global.h"
#include "litpool.h"
-#include "optimize.h"
+/* ### #include "optimize.h" */
#include "segname.h"
#include "util.h"
#include "codegen.h"
-/* Compiler relative stk ptr */
+/* Compiler relative stack pointer */
int oursp = 0;
+/* Segments */
+DataSeg* DS = 0;
+CodeSeg* CS = 0;
+
/* Current segment */
segment_t CurSeg = SEG_INV;
-/* Segment names */
-static char* SegmentHints [4] = {
- "seg:code", "seg:rodata", "seg:data", "seg:bss"
-};
-
/*****************************************************************************/
+static void AddCodeLine (const char* Format, ...)
+{
+ va_list ap;
+ char Buf [1024];
+ va_start (ap, Format);
+ xvsprintf (Buf, sizeof (Buf), Format, ap);
+ va_end (ap);
+ if (CurSeg == SEG_CODE) {
+ AddCodeSegLine (CS, "%s", Buf);
+ } else {
+ AddDataSegLine (DS, "%s", Buf);
+ }
+}
+
+
+
static void typeerror (unsigned type)
/* Print an error message about an invalid operand type */
{
switch (flags & CF_ADDRMASK) {
case CF_STATIC:
- /* Static memory cell */
+ /* Static memory cell */
sprintf (lbuf, "L%04X+%u", (unsigned)(label & 0xFFFF), offs);
break;
void g_preamble (void)
/* Generate the assembler code preamble */
{
+ /* ### */
+ CS = NewCodeSeg ("CODE");
+ DS = NewDataSeg ();
+
AddCodeLine ("; File generated by cc65 v %u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
- AddEmptyLine ();
/* Insert some object file options */
AddCodeLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"", VER_MAJOR, VER_MINOR, VER_PATCH);
- AddEmptyLine ();
/* If we're producing code for some other CPU, switch the command set */
if (CPU == CPU_65C02) {
/* Define long branch macros */
AddCodeLine (".macpack\tlongbranch");
- AddEmptyLine ();
-
- /* Define the ldax macro */
- AddCodeLine (".macro ldax Value");
- AddCodeLine (" lda #<(Value)");
- AddCodeLine (" ldx #>(Value)");
- AddCodeLine (".endmacro");
- AddEmptyLine ();
/* Tell the optimizer that this is the end of the preamble */
AddCodeHint ("end_of_preamble");
{
if (CurSeg != NewSeg) {
CurSeg = (segment_t) NewSeg;
- AddCodeLine (".segment\t\"%s\"", SegmentNames [CurSeg]);
- AddCodeHint (SegmentHints [CurSeg]);
+ if (CurSeg != SEG_CODE) {
+ AddCodeLine (".segment\t\"%s\"", SegmentNames [CurSeg]);
+ }
}
}
void g_defloclabel (unsigned label)
/* Define a local label */
{
- AddCodeLine ("L%04X:", label & 0xFFFF);
+ if (CurSeg == SEG_CODE) {
+ AddCodeSegLabel (CS, LocalLabelName (label));
+ } else {
+ AddDataSegLine (DS, "%s:", LocalLabelName (label));
+ }
}
void g_defgloblabel (const char* Name)
/* Define a global label with the given name */
{
- AddCodeLine ("_%s:", Name);
+ if (CurSeg == SEG_CODE) {
+ /* ##### */
+ char Buf[64];
+ xsprintf (Buf, sizeof (Buf), "_%s", Name);
+ AddCodeSegLabel (CS, Buf);
+ } else {
+ AddDataSegLine (DS, "_%s:", Name);
+ }
}
/* Export the given label */
{
if (ZP) {
- AddCodeLine ("\t.exportzp\t_%s", Name);
+ AddDataSegLine (DS, "\t.exportzp\t_%s", Name);
} else {
- AddCodeLine ("\t.export\t\t_%s", Name);
+ AddDataSegLine (DS, "\t.export\t\t_%s", Name);
}
}
/* Import the given label */
{
if (ZP) {
- AddCodeLine ("\t.importzp\t_%s", Name);
+ AddDataSegLine (DS, "\t.importzp\t_%s", Name);
} else {
- AddCodeLine ("\t.import\t\t_%s", Name);
+ AddDataSegLine (DS, "\t.import\t\t_%s", Name);
}
}
/* Output the jump */
AddCodeLine (buf);
}
-
- /* Add an empty line after a function to make the code more readable */
- AddEmptyLine ();
}
const char* Label = GetLabelName (flags, val, offs);
/* Load the address into the primary */
- AddCodeLine ("\tldax\t%s", Label);
+ AddCodeLine ("\tlda\t#<(%s)", Label);
+ AddCodeLine ("\tldx\t#>(%s)", Label);
}
}
/* */
/* */
/* */
-/* (C) 1998 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2001 llrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#define CODEGEN_H
+
+/* ##### */
+#include "dataseg.h"
+#include "codeseg.h"
+
+
/*****************************************************************************/
/* data */
/* Compiler relative stackpointer */
extern int oursp;
+/* Segments */
+extern DataSeg* DS;
+extern CodeSeg* CS;
+
/*****************************************************************************/
#define CI_USE_A 0x0001U /* Use the A register */
#define CI_USE_X 0x0002U /* Use the X register */
#define CI_USE_Y 0x0004U /* Use the Y register */
-#define CI_MASK_USE 0x00FFU /* Extract usage info */
+#define CI_MASK_USE 0x000FU /* Extract usage info */
#define CI_CHG_NONE 0x0000U /* Change nothing */
-#define CI_CHG_A 0x0100U /* Change the A register */
-#define CI_CHG_X 0x0200U /* Change the X register */
-#define CI_CHG_Y 0x0400U /* Change the Y register */
-#define CI_MASK_CHG 0xFF00U /* Extract change info */
+#define CI_CHG_A 0x0010U /* Change the A register */
+#define CI_CHG_X 0x0020U /* Change the X register */
+#define CI_CHG_Y 0x0040U /* Change the Y register */
+#define CI_MASK_CHG 0x00F0U /* Extract change info */
+
+#define CI_BRA 0x0100U /* Instruction is a branch */
+#define CI_MASK_BRA 0x0100U /* Extract branch info */
#define CI_NONE 0x0000U /* Nothing used/changed */
/* b6502 */
#include "codeent.h"
+#include "codeinfo.h"
#include "error.h"
#include "codeseg.h"
+static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash)
+/* Create a new label and insert it into the label hash table */
+{
+ /* Not found - create a new one */
+ CodeLabel* L = NewCodeLabel (Name, Hash);
+
+ /* Enter the label into the hash table */
+ L->Next = S->LabelHash[L->Hash];
+ S->LabelHash[L->Hash] = L;
+
+ /* Return the new label */
+ return L;
+}
+
+
+
static const char* SkipSpace (const char* S)
/* Skip white space and return an updated pointer */
{
-static CodeEntry* ParseInsn (const char* L)
+static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
/* Parse an instruction nnd generate a code entry from it. If the line contains
* errors, output an error message and return NULL.
* For simplicity, we don't accept the broad range of input a "real" assembler
char Expr[64];
char Reg;
CodeEntry* E;
+ CodeLabel* Label;
/* Mnemonic */
L = ReadToken (L, " \t", Mnemo, sizeof (Mnemo));
Expr[0] = '\0';
switch (*L) {
+ case '\0':
+ /* Implicit */
+ AM = AM_IMP;
+ break;
+
case '#':
/* Immidiate */
StrCopy (Expr, sizeof (Expr), L+1);
case 'A':
/* Accumulator? */
if (L[1] == '\0') {
- AM = AM_IMP;
+ AM = AM_ACC;
break;
}
/* FALLTHROUGH */
Reg = toupper (*L);
L = SkipSpace (L+1);
if (Reg == 'X') {
- AM = AM_ABSX;
+ AM = AM_ABSX;
} else if (Reg == 'Y') {
- AM = AM_ABSY;
+ AM = AM_ABSY;
} else {
Error ("ASM code error: syntax error");
- return 0;
+ return 0;
}
if (*L != '\0') {
- Error ("ASM code error: syntax error");
- return 0;
- }
- }
+ Error ("ASM code error: syntax error");
+ return 0;
+ }
+ }
}
break;
}
+ /* If the instruction is a branch, check for the label and generate it
+ * if it does not exist.
+ */
+ Label = 0;
+ if ((OPC->Info & CI_MASK_BRA) == CI_BRA) {
+
+ unsigned Hash;
+
+ /* ### Check for local labels here */
+ CHECK (AM == AM_ABS);
+ AM = AM_BRA;
+ Hash = HashStr (Expr) % CS_LABEL_HASH_SIZE;
+ Label = FindCodeLabel (S, Expr, Hash);
+ if (Label == 0) {
+ /* Generate a new label */
+ Label = NewCodeSegLabel (S, Expr, Hash);
+ }
+ }
+
/* We do now have the addressing mode in AM. Allocate a new CodeEntry
* structure and initialize it.
*/
- E = NewCodeEntry (OPC, AM);
+ E = NewCodeEntry (OPC, AM, Label);
if (Expr[0] != '\0') {
/* We have an additional expression */
E->Arg.Expr = xstrdup (Expr);
{
const char* L;
CodeEntry* E;
+ char Token[64];
/* Format the line */
va_list ap;
case '.':
/* Control instruction */
- Error ("ASM code error: Pseudo instructions not supported");
+ ReadToken (L, " \t", Token, sizeof (Token));
+ Error ("ASM code error: Pseudo instruction `%s' not supported", Token);
break;
default:
- E = ParseInsn (L);
+ E = ParseInsn (S, L);
break;
}
CHECK (L->Owner == 0);
} else {
/* Not found - create a new one */
- L = NewCodeLabel (Name, Hash);
-
- /* Enter the label into the hash table */
- L->Next = S->LabelHash[L->Hash];
- S->LabelHash[L->Hash] = L;
+ L = NewCodeSegLabel (S, Name, Hash);
}
/* We do now have a valid label. Remember it for later */
+void AddCodeSegHint (CodeSeg* S, unsigned Hint)
+/* Add a hint for the preceeding instruction */
+{
+ CodeEntry* E;
+
+ /* Get the number of entries in this segment */
+ unsigned EntryCount = CollCount (&S->Entries);
+
+ /* Must have at least one entry */
+ CHECK (EntryCount > 0);
+
+ /* Get the last entry */
+ E = CollAt (&S->Entries, EntryCount-1);
+
+ /* Add the hint */
+ E->Hints |= Hint;
+}
+
+
+
+void DelCodeSegAfter (CodeSeg* S, unsigned Last)
+/* Delete all entries after the given one */
+{
+ unsigned I;
+
+ /* Get the number of entries in this segment */
+ unsigned Count = CollCount (&S->Entries);
+
+ /* ### We need some more cleanup here wrt labels */
+
+ /* Remove all entries after the given one */
+ for (I = Count-1; I > Last; --I) {
+ FreeCodeEntry (CollAt (&S->Entries, I));
+ CollDelete (&S->Entries, I);
+ }
+
+ /* Delete all waiting labels */
+ CollDeleteAll (&S->Labels);
+}
+
+
+
void OutputCodeSeg (FILE* F, const CodeSeg* S)
/* Output the code segment data to a file */
{
/* Get the number of entries in this segment */
unsigned Count = CollCount (&S->Entries);
+ /* Output the segment directive */
+ fprintf (F, ".segment\t\"%s\"\n", S->Name);
+
/* Output all entries */
for (I = 0; I < Count; ++I) {
OutputCodeEntry (F, CollConstAt (&S->Entries, I));
/* Get a pointer to the next entry */
CodeEntry* E = CollAt (&S->Entries, I);
- /* If this entry has one or zero labels, continue with the next one */
+ /* If this entry has zero labels, continue with the next one */
unsigned LabelCount = CollCount (&E->Labels);
- if (LabelCount <= 1) {
+ if (LabelCount == 0) {
continue;
}
- /* We have more than one label. Use the first one as reference label */
+ /* We have at least one label. Use the first one as reference label.
+ * We don't have a notification for global labels for now, and using
+ * the first one will also keep the global function labels, since these
+ * are inserted at position 0.
+ */
RefLab = CollAt (&E->Labels, 0);
/* Walk through the remaining labels and change references to these
unsigned RefCount = CollCount (&L->JumpFrom);
for (K = 0; K < RefCount; ++K) {
- /* Get the next instrcuction that references this label */
+ /* Get the next instrcuction that references this label */
CodeEntry* E = CollAt (&L->JumpFrom, K);
- /* Change the reference */
- CHECK (E->JumpTo == L);
- E->JumpTo = RefLab;
- CollAppend (&RefLab->JumpFrom, E);
+ /* Change the reference */
+ CHECK (E->JumpTo == L);
+ E->JumpTo = RefLab;
+ CollAppend (&RefLab->JumpFrom, E);
}
CollDelete (&E->Labels, J);
}
+
+ /* The reference label is the only remaining label. Check if there
+ * are any references to this label, and delete it if this is not
+ * the case.
+ */
+ if (CollCount (&RefLab->JumpFrom) == 0) {
+ /* Delete the label */
+ FreeCodeLabel (RefLab);
+ /* Remove it from the list */
+ CollDelete (&E->Labels, 0);
+ }
}
}
+unsigned GetCodeSegEntries (const CodeSeg* S)
+/* Return the number of entries for the given code segment */
+{
+ return CollCount (&S->Entries);
+}
+
+
+
+
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
void AddCodeSegLabel (CodeSeg* S, const char* Name);
/* Add a label for the next instruction to follow */
+void AddCodeSegHint (CodeSeg* S, unsigned Hint);
+/* Add a hint for the preceeding instruction */
+
+void DelCodeSegAfter (CodeSeg* S, unsigned Last);
+/* Delete all entries after the given one */
+
void OutputCodeSeg (FILE* F, const CodeSeg* S);
/* Output the code segment data to a file */
* one and adjust the code entries accordingly.
*/
+unsigned GetCodeSegEntries (const CodeSeg* S);
+/* Return the number of entries for the given code segment */
+
/* End of codeseg.h */
* looks like the one defined for C++ (C has no ASM directive), that is,
* a string literal in parenthesis.
*/
-{
+{
+ /* ########## */
+ Error ("Currently unavailable");
+
+#if 0
/* Skip the ASM */
NextToken ();
/* Closing paren needed */
ConsumeRParen ();
+#endif
}
--Len;
}
line [Len] = '\0';
-
- /* Output the source line in the generated assembler file
- * if requested.
- */
- if (AddSource && line[Start] != '\0') {
- AddCodeLine ("; %s", line+Start);
- }
+
+#if 0
+ /* ######### */
+ /* Output the source line in the generated assembler file
+ * if requested.
+ */
+ if (AddSource && line[Start] != '\0') {
+ AddCodeLine ("; %s", line+Start);
+ }
+#endif
/* Check if we have a line continuation character at the end. If not,
* we're done.
#include "incpath.h"
#include "input.h"
#include "macrotab.h"
-#include "optimize.h"
+/* #include "optimize.h" */
#include "scanner.h"
#include "segname.h"
Optimize = 1;
P = Arg + 2;
while (*P) {
- switch (*P++) {
- case 'f':
- sscanf (P, "%lx", (long*) &OptDisable);
+ switch (*P++) {
+#if 0
+ case 'f':
+ sscanf (P, "%lx", (long*) &OptDisable);
break;
+#endif
case 'i':
FavourSize = 0;
CodeSizeFactor = 200;
FILE* F;
- /* Optimize the output if requested */
- if (Optimize) {
- OptDoOpt ();
- }
+#if 0
+ /* Optimize the output if requested */
+ if (Optimize) {
+ OptDoOpt ();
+ }
+#endif
/* Open the file */
F = fopen (OutputFile, "w");
OBJS = anonname.o \
asmcode.o \
asmlabel.o \
- asmline.o \
codegen.o \
compile.o \
cpu.o \
loop.o \
macrotab.o \
main.o \
- optimize.o \
preproc.o \
pragma.o \
scanner.o \
typecmp.o \
util.o
-LIBS = $(COMMON)/common.a \
- $(B6502)/b6502.a
+LIBS = $(B6502)/b6502.a \
+ $(COMMON)/common.a
# ------------------------------------------------------------------------------
{ "adc", OPC_ADC, CI_USE_A | CI_CHG_A },
{ "and", OPC_AND, CI_USE_A | CI_CHG_A },
{ "asl", OPC_ASL, CI_USE_A | CI_CHG_A },
- { "bcc", OPC_BCC, CI_CHG_NONE },
- { "bcs", OPC_BCS, CI_CHG_NONE },
- { "beq", OPC_BEQ, CI_CHG_NONE },
+ { "bcc", OPC_BCC, CI_BRA },
+ { "bcs", OPC_BCS, CI_BRA },
+ { "beq", OPC_BEQ, CI_BRA },
{ "bit", OPC_BIT, CI_USE_A },
- { "bmi", OPC_BMI, CI_CHG_NONE },
- { "bne", OPC_BNE, CI_CHG_NONE },
- { "bpl", OPC_BPL, CI_CHG_NONE },
- { "bra", OPC_BRA, CI_CHG_NONE },
- { "brk", OPC_BRK, CI_CHG_NONE },
- { "bvc", OPC_BVC, CI_CHG_NONE },
- { "bvs", OPC_BVS, CI_CHG_NONE },
+ { "bmi", OPC_BMI, CI_BRA },
+ { "bne", OPC_BNE, CI_BRA },
+ { "bpl", OPC_BPL, CI_BRA },
+ { "bra", OPC_BRA, CI_BRA },
+ { "brk", OPC_BRK, CI_BRA },
+ { "bvc", OPC_BVC, CI_BRA },
+ { "bvs", OPC_BVS, CI_BRA },
{ "clc", OPC_CLC, CI_CHG_NONE },
{ "cld", OPC_CLD, CI_CHG_NONE },
{ "cli", OPC_CLI, CI_CHG_NONE },
{ "inc", OPC_INC, CI_NONE },
{ "inx", OPC_INX, CI_USE_X | CI_CHG_X },
{ "iny", OPC_INY, CI_USE_Y | CI_CHG_Y },
- { "jmp", OPC_JMP, CI_NONE },
- { "jsr", OPC_JSR, CI_NONE },
+ { "jmp", OPC_JMP, CI_BRA },
+ { "jsr", OPC_JSR, CI_BRA },
{ "lda", OPC_LDA, CI_CHG_A },
{ "ldx", OPC_LDX, CI_CHG_X },
{ "ldy", OPC_LDY, CI_CHG_Y },
*/
switch (AM) {
case AM_IMP: return 1;
+ case AM_ACC: return 1;
case AM_IMM: return 2;
case AM_ZP: return 2;
case AM_ZPX: return 2;
-
+
/* Addressing modes (bitmapped). */
typedef enum {
- AM_IMP = 0x0001, /* implicit + accumulator */
- AM_IMM = 0x0002, /* immidiate */
- AM_ZP = 0x0004, /* zeropage */
- AM_ZPX = 0x0008, /* zeropage,X */
- AM_ABS = 0x0010, /* absolute */
- AM_ABSX = 0x0020, /* absolute,X */
- AM_ABSY = 0x0040, /* absolute,Y */
- AM_ZPX_IND = 0x0080, /* (zeropage,x) */
- AM_ZP_INDY = 0x0100, /* (zeropage),y */
- AM_ZP_IND = 0x0200, /* (zeropage) */
- AM_BRA = 0x0400 /* branch */
+ AM_IMP = 0x0001, /* implicit */
+ AM_ACC = 0x0002, /* accumulator */
+ AM_IMM = 0x0004, /* immidiate */
+ AM_ZP = 0x0008, /* zeropage */
+ AM_ZPX = 0x0010, /* zeropage,X */
+ AM_ABS = 0x0020, /* absolute */
+ AM_ABSX = 0x0040, /* absolute,X */
+ AM_ABSY = 0x0080, /* absolute,Y */
+ AM_ZPX_IND = 0x0100, /* (zeropage,x) */
+ AM_ZP_INDY = 0x0200, /* (zeropage),y */
+ AM_ZP_IND = 0x0400, /* (zeropage) */
+ AM_BRA = 0x0800 /* branch */
} am_t;
/* Opcode description */
typedef struct {
char Mnemo[4]; /* Mnemonic */
opc_t OPC; /* Opcode */
- unsigned Usage; /* Usage flags */
+ unsigned Info; /* Usage flags */
} OPCDesc;
const OPCDesc* GetOPCDesc (opc_t OPC);
/* Get an opcode description */
-
+
/* End of opcodes.h */
{
SymEntry* Entry;
- AddEmptyLine ();
-
Entry = SymTab->SymHead;
while (Entry) {
unsigned Flags = Entry->Flags;