]> git.sur5r.net Git - cc65/blobdiff - src/cc65/opcodes.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / cc65 / opcodes.c
index 84ab6930785d9c1d072dba8fe69461fd7b9c8d6f..d8a7fcb1f45beb9e7983562c03eabc44f15e81b2 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                opcodes.c                                 */
+/*                                 opcodes.c                                 */
 /*                                                                           */
-/*                 Opcode and addressing mode definitions                   */
+/*                  Opcode and addressing mode definitions                   */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 2001-2004 Ullrich von Bassewitz                                       */
+/*               Römerstraße 52                                              */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 /* common */
 #include "check.h"
+#include "cpu.h"
 
 /* cc65 */
 #include "codeinfo.h"
+#include "error.h"
 #include "opcodes.h"
 
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
 
-/* Mapper table, mnemonic --> opcode */
-static const OPCDesc OPCTable[OPC_COUNT] = {
-    { "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              },
-    { "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              },
-    { "clc", OPC_CLC, CI_CHG_NONE              },
-    { "cld", OPC_CLD, CI_CHG_NONE              },
-    { "cli", OPC_CLI, CI_CHG_NONE              },
-    { "clv", OPC_CLV, CI_CHG_NONE              },
-    { "cmp", OPC_CMP, CI_USE_A                 },
-    { "cpx", OPC_CPX, CI_USE_X                 },
-    { "cpy", OPC_CPY, CI_USE_Y                 },
-    { "dea", OPC_DEA, CI_USE_A | CI_CHG_A      },
-    { "dec", OPC_DEC, CI_NONE                  },
-    { "dex", OPC_DEX, CI_USE_X | CI_CHG_X      },
-    { "dey", OPC_DEY, CI_USE_Y | CI_CHG_Y      },
-    { "eor", OPC_EOR, CI_USE_A | CI_CHG_A      },
-    { "ina", OPC_INA, CI_USE_A | CI_CHG_A      },
-    { "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                  },
-    { "lda", OPC_LDA, CI_CHG_A                 },
-    { "ldx", OPC_LDX, CI_CHG_X                 },
-    { "ldy", OPC_LDY, CI_CHG_Y                 },
-    { "lsr", OPC_LSR, CI_USE_A | CI_CHG_A      },
-    { "nop", OPC_NOP, CI_NONE                  },
-    { "ora", OPC_ORA, CI_USE_A | CI_CHG_A      },
-    { "pha", OPC_PHA, CI_USE_A                 },
-    { "php", OPC_PHP, CI_NONE                  },
-    { "phx", OPC_PHX, CI_USE_X                 },
-    { "phy", OPC_PHY, CI_USE_Y                 },
-    { "pla", OPC_PLA, CI_CHG_A                 },
-    { "plp", OPC_PLP, CI_NONE                  },
-    { "plx", OPC_PLX, CI_CHG_X                 },
-    { "ply", OPC_PLY, CI_CHG_Y                 },
-    { "rol", OPC_ROL, CI_USE_A | CI_CHG_A      },
-    { "ror", OPC_ROR, CI_USE_A | CI_CHG_A      },
-    { "rti", OPC_RTI, CI_NONE                  },
-    { "rts", OPC_RTS, CI_NONE                  },
-    { "sbc", OPC_SBC, CI_USE_A | CI_CHG_A      },
-    { "sec", OPC_SEC, CI_NONE                  },
-    { "sed", OPC_SED, CI_NONE                  },
-    { "sei", OPC_SEI, CI_NONE                  },
-    { "sta", OPC_STA, CI_USE_A                 },
-    { "stx", OPC_STX, CI_USE_X                 },
-    { "sty", OPC_STY, CI_USE_Y                 },
-    { "tax", OPC_TAX, CI_USE_A | CI_CHG_X      },
-    { "tay", OPC_TAY, CI_USE_A | CI_CHG_Y      },
-    { "trb", OPC_TRB, CI_USE_A                 },
-    { "tsb", OPC_TSB, CI_USE_A                 },
-    { "tsx", OPC_TSX, CI_CHG_X                 },
-    { "txa", OPC_TXA, CI_USE_X | CI_CHG_A      },
-    { "txs", OPC_TXS, CI_USE_X                 },
-    { "tya", OPC_TYA, CI_USE_Y | CI_CHG_A      }
+/* Opcode description table */
+const OPCDesc OPCTable[OP65_COUNT] = {
+
+    /* 65XX opcodes */
+    {   OP65_ADC,                               /* opcode */
+        "adc",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_AND,                               /* opcode */
+        "and",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_ASL,                               /* opcode */
+        "asl",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_NOIMP                      /* flags */
+    },
+    {   OP65_BCC,                               /* opcode */
+        "bcc",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA                                 /* flags */
+    },
+    {   OP65_BCS,                               /* opcode */
+        "bcs",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA                                 /* flags */
+    },
+    {   OP65_BEQ,                               /* opcode */
+        "beq",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_ZBRA | OF_FBRA             /* flags */
+    },
+    {   OP65_BIT,                               /* opcode */
+        "bit",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_BMI,                               /* opcode */
+        "bmi",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_FBRA                       /* flags */
+    },
+    {   OP65_BNE,                               /* opcode */
+        "bne",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_ZBRA | OF_FBRA             /* flags */
+    },
+    {   OP65_BPL,                               /* opcode */
+        "bpl",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_FBRA                       /* flags */
+    },
+    {   OP65_BRA,                               /* opcode */
+        "bra",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_UBRA                                 /* flags */
+    },
+    {   OP65_BRK,                               /* opcode */
+        "brk",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_BVC,                               /* opcode */
+        "bvc",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA                                 /* flags */
+    },
+    {   OP65_BVS,                               /* opcode */
+        "bvs",                                  /* mnemonic */
+        2,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA                                 /* flags */
+    },
+    {   OP65_CLC,                               /* opcode */
+        "clc",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_CLD,                               /* opcode */
+        "cld",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_CLI,                               /* opcode */
+        "cli",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_CLV,                               /* opcode */
+        "clv",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_CMP,                               /* opcode */
+        "cmp",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_CMP                        /* flags */
+    },
+    {   OP65_CPX,                               /* opcode */
+        "cpx",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_X,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_CMP                        /* flags */
+    },
+    {   OP65_CPY,                               /* opcode */
+        "cpy",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_Y,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_CMP                        /* flags */
+    },
+    {   OP65_DEA,                               /* opcode */
+        "dea",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_REG_INCDEC | OF_SETF                 /* flags */
+    },
+    {   OP65_DEC,                               /* opcode */
+        "dec",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_NOIMP                      /* flags */
+    },
+    {   OP65_DEX,                               /* opcode */
+        "dex",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_X,                                  /* use */
+        REG_X,                                  /* chg */
+        OF_REG_INCDEC | OF_SETF                 /* flags */
+    },
+    {   OP65_DEY,                               /* opcode */
+        "dey",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_Y,                                  /* use */
+        REG_Y,                                  /* chg */
+        OF_REG_INCDEC | OF_SETF                 /* flags */
+    },
+    {   OP65_EOR,                               /* opcode */
+        "eor",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_INA,                               /* opcode */
+        "ina",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_REG_INCDEC | OF_SETF                 /* flags */
+    },
+    {   OP65_INC,                               /* opcode */
+        "inc",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_NOIMP                      /* flags */
+    },
+    {   OP65_INX,                               /* opcode */
+        "inx",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_X,                                  /* use */
+        REG_X,                                  /* chg */
+        OF_REG_INCDEC | OF_SETF                 /* flags */
+    },
+    {   OP65_INY,                               /* opcode */
+        "iny",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_Y,                                  /* use */
+        REG_Y,                                  /* chg */
+        OF_REG_INCDEC | OF_SETF                 /* flags */
+    },
+    {   OP65_JCC,                               /* opcode */
+        "jcc",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA                       /* flags */
+    },
+    {   OP65_JCS,                               /* opcode */
+        "jcs",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA                       /* flags */
+    },
+    {   OP65_JEQ,                               /* opcode */
+        "jeq",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA   /* flags */
+    },
+    {   OP65_JMI,                               /* opcode */
+        "jmi",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA | OF_FBRA             /* flags */
+    },
+    {   OP65_JMP,                               /* opcode */
+        "jmp",                                  /* mnemonic */
+        3,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_UBRA | OF_LBRA                       /* flags */
+    },
+    {   OP65_JNE,                               /* opcode */
+        "jne",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA   /* flags */
+    },
+    {   OP65_JPL,                               /* opcode */
+        "jpl",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA | OF_FBRA             /* flags */
+    },
+    {   OP65_JSR,                               /* opcode */
+        "jsr",                                  /* mnemonic */
+        3,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CALL                                 /* flags */
+    },
+    {   OP65_JVC,                               /* opcode */
+        "jvc",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA                       /* flags */
+    },
+    {   OP65_JVS,                               /* opcode */
+        "jvs",                                  /* mnemonic */
+        5,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_CBRA | OF_LBRA                       /* flags */
+    },
+    {   OP65_LDA,                               /* opcode */
+        "lda",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_A,                                  /* chg */
+        OF_LOAD | OF_SETF                       /* flags */
+    },
+    {   OP65_LDX,                               /* opcode */
+        "ldx",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_X,                                  /* chg */
+        OF_LOAD | OF_SETF                       /* flags */
+    },
+    {   OP65_LDY,                               /* opcode */
+        "ldy",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_Y,                                  /* chg */
+        OF_LOAD | OF_SETF                       /* flags */
+    },
+    {   OP65_LSR,                               /* opcode */
+        "lsr",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_NOIMP                      /* flags */
+    },
+    {   OP65_NOP,                               /* opcode */
+        "nop",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_ORA,                               /* opcode */
+        "ora",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_PHA,                               /* opcode */
+        "pha",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_A,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_PHP,                               /* opcode */
+        "php",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_PHX,                               /* opcode */
+        "phx",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_X,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_PHY,                               /* opcode */
+        "phy",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_Y,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_PLA,                               /* opcode */
+        "pla",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_A,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_PLP,                               /* opcode */
+        "plp",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_PLX,                               /* opcode */
+        "plx",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_X,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_PLY,                               /* opcode */
+        "ply",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_Y,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_ROL,                               /* opcode */
+        "rol",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_NOIMP                      /* flags */
+    },
+    {   OP65_ROR,                               /* opcode */
+        "ror",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF | OF_NOIMP                      /* flags */
+    },
+    /* Mark RTI as "uses all registers but doesn't change them", so the
+     * optimizer won't remove preceeding loads.
+     */
+    {   OP65_RTI,                               /* opcode */
+        "rti",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_AXY,                                /* use */
+        REG_NONE,                               /* chg */
+        OF_RET                                  /* flags */
+    },
+    {   OP65_RTS,                               /* opcode */
+        "rts",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_RET                                  /* flags */
+    },
+    {   OP65_SBC,                               /* opcode */
+        "sbc",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_SEC,                               /* opcode */
+        "sec",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_SED,                               /* opcode */
+        "sed",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_SEI,                               /* opcode */
+        "sei",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_NONE                                 /* flags */
+    },
+    {   OP65_STA,                               /* opcode */
+        "sta",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_STORE                                /* flags */
+    },
+    {   OP65_STX,                               /* opcode */
+        "stx",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_X,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_STORE                                /* flags */
+    },
+    {   OP65_STY,                               /* opcode */
+        "sty",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_Y,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_STORE                                /* flags */
+    },
+    {   OP65_STZ,                               /* opcode */
+        "stz",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_NONE,                               /* chg */
+        OF_STORE                                /* flags */
+    },
+    {   OP65_TAX,                               /* opcode */
+        "tax",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_A,                                  /* use */
+        REG_X,                                  /* chg */
+        OF_XFR | OF_SETF                        /* flags */
+    },
+    {   OP65_TAY,                               /* opcode */
+        "tay",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_A,                                  /* use */
+        REG_Y,                                  /* chg */
+        OF_XFR | OF_SETF                        /* flags */
+    },
+    {   OP65_TRB,                               /* opcode */
+        "trb",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_TSB,                               /* opcode */
+        "tsb",                                  /* mnemonic */
+        0,                                      /* size */
+        REG_A,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_SETF                                 /* flags */
+    },
+    {   OP65_TSX,                               /* opcode */
+        "tsx",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_NONE,                               /* use */
+        REG_X,                                  /* chg */
+        OF_XFR | OF_SETF                        /* flags */
+    },
+    {   OP65_TXA,                               /* opcode */
+        "txa",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_X,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_XFR | OF_SETF                        /* flags */
+    },
+    {   OP65_TXS,                               /* opcode */
+        "txs",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_X,                                  /* use */
+        REG_NONE,                               /* chg */
+        OF_XFR                                  /* flags */
+    },
+    {   OP65_TYA,                               /* opcode */
+        "tya",                                  /* mnemonic */
+        1,                                      /* size */
+        REG_Y,                                  /* use */
+        REG_A,                                  /* chg */
+        OF_XFR | OF_SETF                        /* flags */
+    },
 };
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
-static int Compare (const void* Key, const void* Desc)
-/* Compare function for bsearch */
+static int FindCmp (const void* Key, const void* Desc)
+/* Compare function for FindOpcode */
 {
     return strcmp (Key, ((OPCDesc*)Desc)->Mnemo);
 }
 
 
 
-const OPCDesc* FindOpcode (const char* M)
+const OPCDesc* FindOP65 (const char* M)
 /* Find the given opcode and return the opcode number. If the opcode was not
- * found, return OPC_INVALID.
+ * found, return NULL.
  */
 {
     unsigned I;
@@ -151,16 +611,17 @@ const OPCDesc* FindOpcode (const char* M)
     char Mnemo[sizeof (OPCTable[0].Mnemo)];
     Len = strlen (M);
     if (Len >= sizeof (OPCTable[0].Mnemo)) {
-       /* Invalid length means invalid opcode */
-       return 0;
+        /* Invalid length means invalid opcode */
+        return 0;
     }
     for (I = 0; I < Len; ++I) {
-       Mnemo[I] = tolower (M[I]);
+        Mnemo[I] = tolower (M[I]);
     }
     Mnemo[I] = '\0';
 
     /* Search for the mnemonic in the table and return the result */
-    return bsearch (Mnemo, OPCTable, OPC_COUNT, sizeof (OPCTable[0]), Compare);
+    return bsearch (Mnemo, OPCTable, OP65_COUNT,
+                    sizeof (OPCTable[0]), FindCmp );
 }
 
 
@@ -168,37 +629,190 @@ const OPCDesc* FindOpcode (const char* M)
 unsigned GetInsnSize (opc_t OPC, am_t AM)
 /* Return the size of the given instruction */
 {
-    /* On the 6502 (and 65C02), the instruction size is determined only by the
-     * addressing mode.
-     */
+    /* Get the opcode desc and check the size given there */
+    const OPCDesc* D = &OPCTable[OPC];
+    if (D->Size != 0) {
+        return D->Size;
+    }
+
+    /* Check the addressing mode. */
+    switch (AM) {
+        case AM65_IMP:     return 1;
+        case AM65_ACC:     return 1;
+        case AM65_IMM:     return 2;
+        case AM65_ZP:      return 2;
+        case AM65_ZPX:     return 2;
+        case AM65_ABS:     return 3;
+        case AM65_ABSX:    return 3;
+        case AM65_ABSY:    return 3;
+        case AM65_ZPX_IND: return 2;
+        case AM65_ZP_INDY: return 2;
+        case AM65_ZP_IND:  return 2;
+        default:
+            Internal ("Invalid addressing mode");
+            return 0;
+    }
+}
+
+
+
+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).
+ */
+{
+    /* Check the addressing mode. */
     switch (AM) {
-       case AM_IMP:      return 1;
-       case AM_IMM:      return 2;
-       case AM_ZP:       return 2;
-       case AM_ZPX:      return 2;
-       case AM_ABS:      return 3;
-       case AM_ABSX:     return 3;
-       case AM_ABSY:     return 3;
-       case AM_ZPX_IND:  return 2;
-       case AM_ZP_INDY:  return 2;
-       case AM_ZP_IND:   return 2;
-       case AM_BRA:      return 2;
-       default:          FAIL ("Invalid addressing mode");
+        case AM65_ACC:     return REG_A;
+        case AM65_ZPX:     return REG_X;
+        case AM65_ABSX:    return REG_X;
+        case AM65_ABSY:    return REG_Y;
+        case AM65_ZPX_IND: return REG_X;
+        case AM65_ZP_INDY: return REG_Y;
+        default:           return REG_NONE;
     }
 }
 
 
 
-const OPCDesc* GetOPCDesc (opc_t OPC)
-/* Get an opcode description */
+opc_t GetInverseBranch (opc_t OPC)
+/* Return a branch that reverse the condition of the branch given in OPC */
 {
-    /* Check the range */
-    PRECONDITION (OPC >= (opc_t)0 && OPC < OPC_COUNT);
+    switch (OPC) {
+        case OP65_BCC:  return OP65_BCS;
+        case OP65_BCS:  return OP65_BCC;
+        case OP65_BEQ:  return OP65_BNE;
+        case OP65_BMI:  return OP65_BPL;
+        case OP65_BNE:  return OP65_BEQ;
+        case OP65_BPL:  return OP65_BMI;
+        case OP65_BVC:  return OP65_BVS;
+        case OP65_BVS:  return OP65_BVC;
+        case OP65_JCC:  return OP65_JCS;
+        case OP65_JCS:  return OP65_JCC;
+        case OP65_JEQ:  return OP65_JNE;
+        case OP65_JMI:  return OP65_JPL;
+        case OP65_JNE:  return OP65_JEQ;
+        case OP65_JPL:  return OP65_JMI;
+        case OP65_JVC:  return OP65_JVS;
+        case OP65_JVS:  return OP65_JVC;
+        default:
+            Internal ("GetInverseBranch: Invalid opcode: %d", OPC);
+            return 0;
+    }
+}
+
 
-    /* Return the description */
-    return &OPCTable [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.
+ */
+{
+    switch (OPC) {
+        case OP65_BCC:
+        case OP65_JCC:  return OP65_BCC;
+        case OP65_BCS:
+        case OP65_JCS:  return OP65_BCS;
+        case OP65_BEQ:
+        case OP65_JEQ:  return OP65_BEQ;
+        case OP65_BMI:
+        case OP65_JMI:  return OP65_BMI;
+        case OP65_BNE:
+        case OP65_JNE:  return OP65_BNE;
+        case OP65_BPL:
+        case OP65_JPL:  return OP65_BPL;
+        case OP65_BVC:
+        case OP65_JVC:  return OP65_BVC;
+        case OP65_BVS:
+        case OP65_JVS:  return OP65_BVS;
+        case OP65_BRA:
+        case OP65_JMP:  return (CPUIsets[CPU] & CPU_ISET_65SC02)? OP65_BRA : OP65_JMP;
+        default:
+            Internal ("MakeShortBranch: Invalid opcode: %d", OPC);
+            return 0;
+    }
 }
 
 
 
-                         
+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.
+ */
+{
+    switch (OPC) {
+        case OP65_BCC:
+        case OP65_JCC:  return OP65_JCC;
+        case OP65_BCS:
+        case OP65_JCS:  return OP65_JCS;
+        case OP65_BEQ:
+        case OP65_JEQ:  return OP65_JEQ;
+        case OP65_BMI:
+        case OP65_JMI:  return OP65_JMI;
+        case OP65_BNE:
+        case OP65_JNE:  return OP65_JNE;
+        case OP65_BPL:
+        case OP65_JPL:  return OP65_JPL;
+        case OP65_BVC:
+        case OP65_JVC:  return OP65_JVC;
+        case OP65_BVS:
+        case OP65_JVS:  return OP65_JVS;
+        case OP65_BRA:
+        case OP65_JMP:  return OP65_JMP;
+        default:
+            Internal ("MakeLongBranch: Invalid opcode: %d", OPC);
+            return 0;
+    }
+}
+
+
+
+bc_t GetBranchCond (opc_t OPC)
+/* Get the condition for the conditional branch in OPC */
+{
+    switch (OPC) {
+        case OP65_BCC:  return BC_CC;
+        case OP65_BCS:  return BC_CS;
+        case OP65_BEQ:  return BC_EQ;
+        case OP65_BMI:  return BC_MI;
+        case OP65_BNE:  return BC_NE;
+        case OP65_BPL:  return BC_PL;
+        case OP65_BVC:  return BC_VC;
+        case OP65_BVS:  return BC_VS;
+        case OP65_JCC:  return BC_CC;
+        case OP65_JCS:  return BC_CS;
+        case OP65_JEQ:  return BC_EQ;
+        case OP65_JMI:  return BC_MI;
+        case OP65_JNE:  return BC_NE;
+        case OP65_JPL:  return BC_PL;
+        case OP65_JVC:  return BC_VC;
+        case OP65_JVS:  return BC_VS;
+        default:
+            Internal ("GetBranchCond: Invalid opcode: %d", OPC);
+            return 0;
+    }
+}
+
+
+
+bc_t GetInverseCond (bc_t BC)
+/* Return the inverse condition of the given one */
+{
+    switch (BC) {
+        case BC_CC:     return BC_CS;
+        case BC_CS:     return BC_CC;
+        case BC_EQ:     return BC_NE;
+        case BC_MI:     return BC_PL;
+        case BC_NE:     return BC_EQ;
+        case BC_PL:     return BC_MI;
+        case BC_VC:     return BC_VS;
+        case BC_VS:     return BC_VC;
+        default:
+            Internal ("GetInverseCond: Invalid condition: %d", BC);
+            return 0;
+    }
+}
+
+
+
+