/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2001 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
+/* common */
+#include "inline.h"
+
+
+
/*****************************************************************************/
/* Data */
/*****************************************************************************/
OPC_INC,
OPC_INX,
OPC_INY,
+ OPC_JCC,
+ OPC_JCS,
+ OPC_JEQ,
+ OPC_JMI,
OPC_JMP,
+ OPC_JNE,
+ OPC_JPL,
OPC_JSR,
+ OPC_JVC,
+ OPC_JVS,
OPC_LDA,
OPC_LDX,
OPC_LDY,
OPC_TXA,
OPC_TXS,
OPC_TYA,
- OPC_COUNT /* Number of opcodes available */
+ OPC_COUNT /* Number of opcodes available */
} opc_t;
/* 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;
+/* Branch conditions */
+typedef enum {
+ BC_CC,
+ BC_CS,
+ BC_EQ,
+ BC_MI,
+ BC_NE,
+ BC_PL,
+ BC_SR,
+ BC_VC,
+ BC_VS
+} bc_t;
+
+/* Opcode info */
+#define OF_NONE 0x0000U /* No additional information */
+#define OF_UBRA 0x0001U /* Unconditional branch */
+#define OF_CBRA 0x0002U /* Conditional branch */
+#define OF_ZBRA 0x0004U /* Branch on zero flag condition */
+#define OF_FBRA 0x0008U /* Branch on cond set by a load */
+#define OF_LBRA 0x0010U /* Jump/branch is long */
+#define OF_RET 0x0020U /* Return from function */
+#define OF_LOAD 0x0040U /* Register load */
+#define OF_XFR 0x0080 /* Transfer instruction */
+#define OF_BRA (OF_UBRA|OF_CBRA) /* Operation is a jump/branch */
+#define OF_DEAD (OF_UBRA|OF_RET) /* Dead end - no exec behind this point */
+
/* Opcode description */
typedef struct {
- char Mnemo[4]; /* Mnemonic */
- opc_t OPC; /* Opcode */
- unsigned Usage; /* Usage flags */
+ opc_t OPC; /* Opcode */
+ char Mnemo[4]; /* Mnemonic */
+ unsigned char Size; /* Size, 0 = check addressing mode */
+ unsigned char Use; /* Registers used by this insn */
+ unsigned char Chg; /* Registers changed by this insn */
+ unsigned char Info; /* Additional information */
} OPCDesc;
+/* Opcode description table */
+extern const OPCDesc OPCTable[OPC_COUNT];
+
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
unsigned GetInsnSize (opc_t OPC, am_t AM);
/* Return the size of the given instruction */
-const OPCDesc* GetOPCDesc (opc_t OPC);
+#if defined(HAVE_INLINE)
+INLINE const OPCDesc* GetOPCDesc (opc_t OPC)
/* Get an opcode description */
+{
+ /* Return the description */
+ return &OPCTable [OPC];
+}
+#else
+# define GetOPCDesc(OPC) (&OPCTable [(OPC)])
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE unsigned char GetOPCInfo (opc_t OPC)
+/* Get opcode information */
+{
+ /* Return the info */
+ return OPCTable[OPC].Info;
+}
+#else
+# define GetOPCInfo(OPC) (OPCTable[(OPC)].Info)
+#endif
+
+unsigned char GetAMUseInfo (am_t AM);
+/* Get usage info for the given addressing mode (addressing modes that use
+ * index registers return REG_r info for these registers).
+ */
+
+opc_t GetInverseBranch (opc_t OPC);
+/* Return a branch that reverse the condition of the branch given in OPC */
+
+opc_t MakeShortBranch (opc_t OPC);
+/* Return the short version of the given branch. If the branch is already
+ * a short branch, return the opcode unchanged.
+ */
+
+opc_t MakeLongBranch (opc_t OPC);
+/* Return the long version of the given branch. If the branch is already
+ * a long branch, return the opcode unchanged.
+ */
+
+bc_t GetBranchCond (opc_t OPC);
+/* Get the condition for the conditional branch in OPC */
+
+bc_t GetInverseCond (bc_t BC);
+/* Return the inverse condition of the given one */
+
+opc_t GetLongBranch (bc_t BC);
+/* Return a long branch for the given branch condition */
+
+opc_t GetShortBranch (bc_t BC);
+/* Return a short branch for the given branch condition */