You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
597 lines
24 KiB
597 lines
24 KiB
3 years ago
|
/* Capstone Disassembly Engine */
|
||
|
/* MOS65XX Backend by Sebastian Macke <sebastian@macke.de> 2018 */
|
||
|
|
||
|
#include "capstone/mos65xx.h"
|
||
|
#include "MOS65XXDisassembler.h"
|
||
|
|
||
|
typedef struct OpInfo {
|
||
|
mos65xx_insn ins;
|
||
|
mos65xx_address_mode am;
|
||
|
} OpInfo;
|
||
|
|
||
|
static const struct OpInfo OpInfoTable[]= {
|
||
|
{ MOS65XX_INS_BRK , MOS65XX_AM_IMP }, // 0x00
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_INDX }, // 0x01
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x02
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x03
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZP }, // 0x04
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_ZP }, // 0x05
|
||
|
{ MOS65XX_INS_ASL , MOS65XX_AM_ZP }, // 0x06
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x07
|
||
|
{ MOS65XX_INS_PHP , MOS65XX_AM_IMP }, // 0x08
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_IMM }, // 0x09
|
||
|
{ MOS65XX_INS_ASL , MOS65XX_AM_ACC }, // 0x0a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x0b
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABS }, // 0x0c
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_ABS }, // 0x0d
|
||
|
{ MOS65XX_INS_ASL , MOS65XX_AM_ABS }, // 0x0e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x0f
|
||
|
{ MOS65XX_INS_BPL , MOS65XX_AM_REL }, // 0x10
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_INDY }, // 0x11
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x12
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x13
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZPX }, // 0x14
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_ZPX }, // 0x15
|
||
|
{ MOS65XX_INS_ASL , MOS65XX_AM_ZPX }, // 0x16
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x17
|
||
|
{ MOS65XX_INS_CLC , MOS65XX_AM_IMP }, // 0x18
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_ABSY }, // 0x19
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x1a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x1b
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABS }, // 0x1c
|
||
|
{ MOS65XX_INS_ORA , MOS65XX_AM_ABSX }, // 0x1d
|
||
|
{ MOS65XX_INS_ASL , MOS65XX_AM_ABSX }, // 0x1e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x1f
|
||
|
{ MOS65XX_INS_JSR , MOS65XX_AM_ABS }, // 0x20
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_INDX }, // 0x21
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x22
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x23
|
||
|
{ MOS65XX_INS_BIT , MOS65XX_AM_ZP }, // 0x24
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_ZP }, // 0x25
|
||
|
{ MOS65XX_INS_ROL , MOS65XX_AM_ZP }, // 0x26
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x27
|
||
|
{ MOS65XX_INS_PLP , MOS65XX_AM_IMP }, // 0x28
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_IMM }, // 0x29
|
||
|
{ MOS65XX_INS_ROL , MOS65XX_AM_ACC }, // 0x2a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x2b
|
||
|
{ MOS65XX_INS_BIT , MOS65XX_AM_ABS }, // 0x2c
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_ABS }, // 0x2d
|
||
|
{ MOS65XX_INS_ROL , MOS65XX_AM_ABS }, // 0x2e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x2f
|
||
|
{ MOS65XX_INS_BMI , MOS65XX_AM_REL }, // 0x30
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_INDY }, // 0x31
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x32
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x33
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZPX }, // 0x34
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_ZPX }, // 0x35
|
||
|
{ MOS65XX_INS_ROL , MOS65XX_AM_ZPX }, // 0x36
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x37
|
||
|
{ MOS65XX_INS_SEC , MOS65XX_AM_IMP }, // 0x38
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_ABSY }, // 0x39
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x3a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x3b
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABSX }, // 0x3c
|
||
|
{ MOS65XX_INS_AND , MOS65XX_AM_ABSX }, // 0x3d
|
||
|
{ MOS65XX_INS_ROL , MOS65XX_AM_ABSX }, // 0x3e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x3f
|
||
|
{ MOS65XX_INS_RTI , MOS65XX_AM_IMP }, // 0x40
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_INDX }, // 0x41
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x42
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x43
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZP }, // 0x44
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_ZP }, // 0x45
|
||
|
{ MOS65XX_INS_LSR , MOS65XX_AM_ZP }, // 0x46
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x47
|
||
|
{ MOS65XX_INS_PHA , MOS65XX_AM_IMP }, // 0x48
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_IMM }, // 0x49
|
||
|
{ MOS65XX_INS_LSR , MOS65XX_AM_ACC }, // 0x4a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x4b
|
||
|
{ MOS65XX_INS_JMP , MOS65XX_AM_ABS }, // 0x4c
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_ABS }, // 0x4d
|
||
|
{ MOS65XX_INS_LSR , MOS65XX_AM_ABS }, // 0x4e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x4f
|
||
|
{ MOS65XX_INS_BVC , MOS65XX_AM_REL }, // 0x50
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_INDY }, // 0x51
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x52
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x53
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZPX }, // 0x54
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_ZPX }, // 0x55
|
||
|
{ MOS65XX_INS_LSR , MOS65XX_AM_ZPX }, // 0x56
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x57
|
||
|
{ MOS65XX_INS_CLI , MOS65XX_AM_IMP }, // 0x58
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_ABSY }, // 0x59
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x5a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x5b
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABSX }, // 0x5c
|
||
|
{ MOS65XX_INS_EOR , MOS65XX_AM_ABSX }, // 0x5d
|
||
|
{ MOS65XX_INS_LSR , MOS65XX_AM_ABSX }, // 0x5e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x5f
|
||
|
{ MOS65XX_INS_RTS , MOS65XX_AM_IMP }, // 0x60
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_INDX }, // 0x61
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x62
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x63
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZP }, // 0x64
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_ZP }, // 0x65
|
||
|
{ MOS65XX_INS_ROR , MOS65XX_AM_ZP }, // 0x66
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x67
|
||
|
{ MOS65XX_INS_PLA , MOS65XX_AM_IMP }, // 0x68
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_IMM }, // 0x69
|
||
|
{ MOS65XX_INS_ROR , MOS65XX_AM_ACC }, // 0x6a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x6b
|
||
|
{ MOS65XX_INS_JMP , MOS65XX_AM_IND }, // 0x6c
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_ABS }, // 0x6d
|
||
|
{ MOS65XX_INS_ROR , MOS65XX_AM_ABS }, // 0x6e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x6f
|
||
|
{ MOS65XX_INS_BVS , MOS65XX_AM_REL }, // 0x70
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_INDY }, // 0x71
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x72
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x73
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZPX }, // 0x74
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_ZPX }, // 0x75
|
||
|
{ MOS65XX_INS_ROR , MOS65XX_AM_ZPX }, // 0x76
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x77
|
||
|
{ MOS65XX_INS_SEI , MOS65XX_AM_IMP }, // 0x78
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_ABSY }, // 0x79
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x7a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x7b
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABSX }, // 0x7c
|
||
|
{ MOS65XX_INS_ADC , MOS65XX_AM_ABSX }, // 0x7d
|
||
|
{ MOS65XX_INS_ROR , MOS65XX_AM_ABSX }, // 0x7e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x7f
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x80
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_INDX }, // 0x81
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x82
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x83
|
||
|
{ MOS65XX_INS_STY , MOS65XX_AM_ZP }, // 0x84
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_ZP }, // 0x85
|
||
|
{ MOS65XX_INS_STX , MOS65XX_AM_ZP }, // 0x86
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x87
|
||
|
{ MOS65XX_INS_DEY , MOS65XX_AM_IMP }, // 0x88
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0x89
|
||
|
{ MOS65XX_INS_TXA , MOS65XX_AM_IMP }, // 0x8a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x8b
|
||
|
{ MOS65XX_INS_STY , MOS65XX_AM_ABS }, // 0x8c
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_ABS }, // 0x8d
|
||
|
{ MOS65XX_INS_STX , MOS65XX_AM_ABS }, // 0x8e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x8f
|
||
|
{ MOS65XX_INS_BCC , MOS65XX_AM_REL }, // 0x90
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_INDY }, // 0x91
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x92
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x93
|
||
|
{ MOS65XX_INS_STY , MOS65XX_AM_ZPX }, // 0x94
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_ZPX }, // 0x95
|
||
|
{ MOS65XX_INS_STX , MOS65XX_AM_ZPY }, // 0x96
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x97
|
||
|
{ MOS65XX_INS_TYA , MOS65XX_AM_IMP }, // 0x98
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_ABSY }, // 0x99
|
||
|
{ MOS65XX_INS_TXS , MOS65XX_AM_IMP }, // 0x9a
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x9b
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x9c
|
||
|
{ MOS65XX_INS_STA , MOS65XX_AM_ABSX }, // 0x9d
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x9e
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0x9f
|
||
|
{ MOS65XX_INS_LDY , MOS65XX_AM_IMM }, // 0xa0
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_INDX }, // 0xa1
|
||
|
{ MOS65XX_INS_LDX , MOS65XX_AM_IMM }, // 0xa2
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xa3
|
||
|
{ MOS65XX_INS_LDY , MOS65XX_AM_ZP }, // 0xa4
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_ZP }, // 0xa5
|
||
|
{ MOS65XX_INS_LDX , MOS65XX_AM_ZP }, // 0xa6
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xa7
|
||
|
{ MOS65XX_INS_TAY , MOS65XX_AM_IMP }, // 0xa8
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_IMM }, // 0xa9
|
||
|
{ MOS65XX_INS_TAX , MOS65XX_AM_IMP }, // 0xaa
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xab
|
||
|
{ MOS65XX_INS_LDY , MOS65XX_AM_ABS }, // 0xac
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_ABS }, // 0xad
|
||
|
{ MOS65XX_INS_LDX , MOS65XX_AM_ABS }, // 0xae
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xaf
|
||
|
{ MOS65XX_INS_BCS , MOS65XX_AM_REL }, // 0xb0
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_INDY }, // 0xb1
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xb2
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xb3
|
||
|
{ MOS65XX_INS_LDY , MOS65XX_AM_ZPX }, // 0xb4
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_ZPX }, // 0xb5
|
||
|
{ MOS65XX_INS_LDX , MOS65XX_AM_ZPY }, // 0xb6
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xb7
|
||
|
{ MOS65XX_INS_CLV , MOS65XX_AM_IMP }, // 0xb8
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_ABSY }, // 0xb9
|
||
|
{ MOS65XX_INS_TSX , MOS65XX_AM_IMP }, // 0xba
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xbb
|
||
|
{ MOS65XX_INS_LDY , MOS65XX_AM_ABSX }, // 0xbc
|
||
|
{ MOS65XX_INS_LDA , MOS65XX_AM_ABSX }, // 0xbd
|
||
|
{ MOS65XX_INS_LDX , MOS65XX_AM_ABSY }, // 0xbe
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xbf
|
||
|
{ MOS65XX_INS_CPY , MOS65XX_AM_IMM }, // 0xc0
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_INDX }, // 0xc1
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0xc2
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xc3
|
||
|
{ MOS65XX_INS_CPY , MOS65XX_AM_ZP }, // 0xc4
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_ZP }, // 0xc5
|
||
|
{ MOS65XX_INS_DEC , MOS65XX_AM_ZP }, // 0xc6
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xc7
|
||
|
{ MOS65XX_INS_INY , MOS65XX_AM_IMP }, // 0xc8
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_IMM }, // 0xc9
|
||
|
{ MOS65XX_INS_DEX , MOS65XX_AM_IMP }, // 0xca
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xcb
|
||
|
{ MOS65XX_INS_CPY , MOS65XX_AM_ABS }, // 0xcc
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_ABS }, // 0xcd
|
||
|
{ MOS65XX_INS_DEC , MOS65XX_AM_ABS }, // 0xce
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xcf
|
||
|
{ MOS65XX_INS_BNE , MOS65XX_AM_REL }, // 0xd0
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_INDY }, // 0xd1
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xd2
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xd3
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZPX }, // 0xd4
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_ZPX }, // 0xd5
|
||
|
{ MOS65XX_INS_DEC , MOS65XX_AM_ZPX }, // 0xd6
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xd7
|
||
|
{ MOS65XX_INS_CLD , MOS65XX_AM_IMP }, // 0xd8
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_ABSY }, // 0xd9
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0xda
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xdb
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABSX }, // 0xdc
|
||
|
{ MOS65XX_INS_CMP , MOS65XX_AM_ABSX }, // 0xdd
|
||
|
{ MOS65XX_INS_DEC , MOS65XX_AM_ABSX }, // 0xde
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xdf
|
||
|
{ MOS65XX_INS_CPX , MOS65XX_AM_IMM }, // 0xe0
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_INDX }, // 0xe1
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0xe2
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xe3
|
||
|
{ MOS65XX_INS_CPX , MOS65XX_AM_ZP }, // 0xe4
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_ZP }, // 0xe5
|
||
|
{ MOS65XX_INS_INC , MOS65XX_AM_ZP }, // 0xe6
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xe7
|
||
|
{ MOS65XX_INS_INX , MOS65XX_AM_IMP }, // 0xe8
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_IMM }, // 0xe9
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0xea
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xeb
|
||
|
{ MOS65XX_INS_CPX , MOS65XX_AM_ABS }, // 0xec
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_ABS }, // 0xed
|
||
|
{ MOS65XX_INS_INC , MOS65XX_AM_ABS }, // 0xee
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xef
|
||
|
{ MOS65XX_INS_BEQ , MOS65XX_AM_REL }, // 0xf0
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_INDY }, // 0xf1
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xf2
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xf3
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ZPX }, // 0xf4
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_ZPX }, // 0xf5
|
||
|
{ MOS65XX_INS_INC , MOS65XX_AM_ZPX }, // 0xf6
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xf7
|
||
|
{ MOS65XX_INS_SED , MOS65XX_AM_IMP }, // 0xf8
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_ABSY }, // 0xf9
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_IMP }, // 0xfa
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xfb
|
||
|
{ MOS65XX_INS_NOP , MOS65XX_AM_ABSX }, // 0xfc
|
||
|
{ MOS65XX_INS_SBC , MOS65XX_AM_ABSX }, // 0xfd
|
||
|
{ MOS65XX_INS_INC , MOS65XX_AM_ABSX }, // 0xfe
|
||
|
{ MOS65XX_INS_INVALID, MOS65XX_AM_NONE }, // 0xff
|
||
|
};
|
||
|
|
||
|
static const char* RegNames[] = {
|
||
|
"invalid", "A", "X", "Y", "P", "SP"
|
||
|
};
|
||
|
|
||
|
#ifndef CAPSTONE_DIET
|
||
|
static const char* GroupNames[] = {
|
||
|
NULL,
|
||
|
"jump",
|
||
|
"call",
|
||
|
"ret",
|
||
|
NULL,
|
||
|
"iret",
|
||
|
"branch_relative"
|
||
|
};
|
||
|
|
||
|
typedef struct InstructionInfo {
|
||
|
const char* name;
|
||
|
mos65xx_group_type group_type;
|
||
|
mos65xx_reg write, read;
|
||
|
bool modifies_status;
|
||
|
} InstructionInfo;
|
||
|
|
||
|
static const struct InstructionInfo InstructionInfoTable[]= {
|
||
|
{ "invalid", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, false },
|
||
|
{ "adc", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_INVALID, true },
|
||
|
{ "and", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_INVALID, true },
|
||
|
{ "asl", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "bcc", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "bcs", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "beq", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "bit", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "bmi", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "bne", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "bpl", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "brk", MOS65XX_GRP_INVALID, MOS65XX_REG_SP, MOS65XX_REG_INVALID, false },
|
||
|
{ "bvc", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "bvs", MOS65XX_GRP_BRANCH_RELATIVE, MOS65XX_REG_INVALID, MOS65XX_REG_P, false },
|
||
|
{ "clc", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "cld", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "cli", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "clv", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "cmp", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_ACC, true },
|
||
|
{ "cpx", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_X, true },
|
||
|
{ "cpy", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_Y, true },
|
||
|
{ "dec", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "dex", MOS65XX_GRP_INVALID, MOS65XX_REG_X, MOS65XX_REG_X, true },
|
||
|
{ "dey", MOS65XX_GRP_INVALID, MOS65XX_REG_Y, MOS65XX_REG_Y, true },
|
||
|
{ "eor", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "inc", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "inx", MOS65XX_GRP_INVALID, MOS65XX_REG_X, MOS65XX_REG_X, true },
|
||
|
{ "iny", MOS65XX_GRP_INVALID, MOS65XX_REG_Y, MOS65XX_REG_Y, true },
|
||
|
{ "jmp", MOS65XX_GRP_JUMP, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, false },
|
||
|
{ "jsr", MOS65XX_GRP_CALL, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, false },
|
||
|
{ "lda", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_INVALID, true },
|
||
|
{ "ldx", MOS65XX_GRP_INVALID, MOS65XX_REG_X, MOS65XX_REG_INVALID, true },
|
||
|
{ "ldy", MOS65XX_GRP_INVALID, MOS65XX_REG_Y, MOS65XX_REG_INVALID, true },
|
||
|
{ "lsr", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "nop", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, false },
|
||
|
{ "ora", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_INVALID, true },
|
||
|
{ "pha", MOS65XX_GRP_INVALID, MOS65XX_REG_SP, MOS65XX_REG_ACC, false },
|
||
|
{ "pla", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_SP, true },
|
||
|
{ "php", MOS65XX_GRP_INVALID, MOS65XX_REG_SP, MOS65XX_REG_P, false },
|
||
|
{ "plp", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_SP, true },
|
||
|
{ "rol", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "ror", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "rti", MOS65XX_GRP_IRET, MOS65XX_REG_SP, MOS65XX_REG_INVALID, true },
|
||
|
{ "rts", MOS65XX_GRP_RET, MOS65XX_REG_SP, MOS65XX_REG_INVALID, false },
|
||
|
{ "sbc", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_INVALID, true },
|
||
|
{ "sec", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "sed", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "sei", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_INVALID, true },
|
||
|
{ "sta", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_ACC, false },
|
||
|
{ "stx", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_X, false },
|
||
|
{ "sty", MOS65XX_GRP_INVALID, MOS65XX_REG_INVALID, MOS65XX_REG_Y, false },
|
||
|
{ "tax", MOS65XX_GRP_INVALID, MOS65XX_REG_X, MOS65XX_REG_ACC, true },
|
||
|
{ "tay", MOS65XX_GRP_INVALID, MOS65XX_REG_Y, MOS65XX_REG_ACC, true },
|
||
|
{ "tsx", MOS65XX_GRP_INVALID, MOS65XX_REG_X, MOS65XX_REG_SP, true },
|
||
|
{ "txa", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_X, true },
|
||
|
{ "txs", MOS65XX_GRP_INVALID, MOS65XX_REG_SP, MOS65XX_REG_X, true },
|
||
|
{ "tya", MOS65XX_GRP_INVALID, MOS65XX_REG_ACC, MOS65XX_REG_Y, true },
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
static int getInstructionLength(mos65xx_address_mode am)
|
||
|
{
|
||
|
switch(am) {
|
||
|
case MOS65XX_AM_NONE:
|
||
|
case MOS65XX_AM_ACC:
|
||
|
case MOS65XX_AM_IMP:
|
||
|
return 1;
|
||
|
|
||
|
case MOS65XX_AM_IMM:
|
||
|
case MOS65XX_AM_ZPX:
|
||
|
case MOS65XX_AM_ZPY:
|
||
|
case MOS65XX_AM_ZP:
|
||
|
case MOS65XX_AM_REL:
|
||
|
case MOS65XX_AM_INDX:
|
||
|
case MOS65XX_AM_INDY:
|
||
|
return 2;
|
||
|
|
||
|
case MOS65XX_AM_ABS:
|
||
|
case MOS65XX_AM_ABSX:
|
||
|
case MOS65XX_AM_ABSY:
|
||
|
case MOS65XX_AM_IND:
|
||
|
return 3;
|
||
|
default:
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifndef CAPSTONE_DIET
|
||
|
static void fillDetails(MCInst *MI, unsigned char opcode)
|
||
|
{
|
||
|
cs_detail *detail = MI->flat_insn->detail;
|
||
|
mos65xx_insn ins = OpInfoTable[opcode].ins;
|
||
|
mos65xx_address_mode am = OpInfoTable[opcode].am;
|
||
|
|
||
|
detail->mos65xx.am = am;
|
||
|
detail->mos65xx.modifies_flags = InstructionInfoTable[ins].modifies_status;
|
||
|
detail->groups_count = 0;
|
||
|
detail->regs_read_count = 0;
|
||
|
detail->regs_write_count = 0;
|
||
|
detail->mos65xx.op_count = 0;
|
||
|
|
||
|
if (InstructionInfoTable[ins].group_type != MOS65XX_GRP_INVALID) {
|
||
|
detail->groups[0] = InstructionInfoTable[ins].group_type;
|
||
|
detail->groups_count++;
|
||
|
}
|
||
|
|
||
|
if (InstructionInfoTable[ins].read != MOS65XX_REG_INVALID) {
|
||
|
detail->regs_read[detail->regs_read_count++] = InstructionInfoTable[ins].read;
|
||
|
} else if (OpInfoTable[opcode].am == MOS65XX_AM_ACC) {
|
||
|
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_ACC;
|
||
|
} else if (OpInfoTable[opcode].am == MOS65XX_AM_INDY || OpInfoTable[opcode].am == MOS65XX_AM_ABSY || OpInfoTable[opcode].am == MOS65XX_AM_ZPY) {
|
||
|
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_Y;
|
||
|
} else if (OpInfoTable[opcode].am == MOS65XX_AM_INDX || OpInfoTable[opcode].am == MOS65XX_AM_ABSX || OpInfoTable[opcode].am == MOS65XX_AM_ZPX) {
|
||
|
detail->regs_read[detail->regs_read_count++] = MOS65XX_REG_X;
|
||
|
}
|
||
|
|
||
|
if (InstructionInfoTable[ins].write != MOS65XX_REG_INVALID) {
|
||
|
detail->regs_write[detail->regs_write_count++] = InstructionInfoTable[ins].write;
|
||
|
} else if (OpInfoTable[opcode].am == MOS65XX_AM_ACC) {
|
||
|
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_ACC;
|
||
|
}
|
||
|
|
||
|
if (InstructionInfoTable[ins].modifies_status) {
|
||
|
detail->regs_write[detail->regs_write_count++] = MOS65XX_REG_P;
|
||
|
}
|
||
|
|
||
|
switch(am) {
|
||
|
case MOS65XX_AM_IMP:
|
||
|
case MOS65XX_AM_REL:
|
||
|
break;
|
||
|
case MOS65XX_AM_IMM:
|
||
|
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_IMM;
|
||
|
detail->mos65xx.operands[detail->mos65xx.op_count].mem = MI->Operands[0].ImmVal;
|
||
|
detail->mos65xx.op_count++;
|
||
|
break;
|
||
|
case MOS65XX_AM_ACC:
|
||
|
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_REG;
|
||
|
detail->mos65xx.operands[detail->mos65xx.op_count].reg = MOS65XX_REG_ACC;
|
||
|
detail->mos65xx.op_count++;
|
||
|
break;
|
||
|
default:
|
||
|
detail->mos65xx.operands[detail->mos65xx.op_count].type = MOS65XX_OP_MEM;
|
||
|
detail->mos65xx.operands[detail->mos65xx.op_count].mem = MI->Operands[0].ImmVal;
|
||
|
detail->mos65xx.op_count++;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void MOS65XX_printInst(MCInst *MI, struct SStream *O, void *PrinterInfo)
|
||
|
{
|
||
|
#ifndef CAPSTONE_DIET
|
||
|
unsigned char opcode = MI->Opcode;
|
||
|
unsigned int value = MI->Operands[0].ImmVal;
|
||
|
|
||
|
SStream_concat0(O, InstructionInfoTable[OpInfoTable[MI->Opcode].ins].name);
|
||
|
|
||
|
switch (OpInfoTable[opcode].am) {
|
||
|
default:
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_IMP:
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ACC:
|
||
|
SStream_concat(O, " a");
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ABS:
|
||
|
SStream_concat(O, " $0x%04x", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_IMM:
|
||
|
SStream_concat(O, " #$0x%02x", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ZP:
|
||
|
SStream_concat(O, " $0x%02x", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ABSX:
|
||
|
SStream_concat(O, " $0x%04x, x", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ABSY:
|
||
|
SStream_concat(O, " $0x%04x, y", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ZPX:
|
||
|
SStream_concat(O, " $0x%02x, x", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_ZPY:
|
||
|
SStream_concat(O, " $0x%02x, y", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_REL:
|
||
|
SStream_concat(O, " $0x%04x", MI->address + (signed char) value + 2);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_IND:
|
||
|
SStream_concat(O, " ($0x%04x)", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_INDX:
|
||
|
SStream_concat(O, " ($0x%02x, x)", value);
|
||
|
break;
|
||
|
|
||
|
case MOS65XX_AM_INDY:
|
||
|
SStream_concat(O, " ($0x%02x), y", value);
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bool MOS65XX_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||
|
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
|
||
|
{
|
||
|
unsigned char opcode;
|
||
|
unsigned char len;
|
||
|
mos65xx_insn ins;
|
||
|
|
||
|
if (code_len == 0) {
|
||
|
*size = 1;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
opcode = code[0];
|
||
|
ins = OpInfoTable[opcode].ins;
|
||
|
if (ins == MOS65XX_INS_INVALID) {
|
||
|
*size = 1;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
len = getInstructionLength(OpInfoTable[opcode].am);
|
||
|
if (code_len < len) {
|
||
|
*size = 1;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
MI->address = address;
|
||
|
MI->Opcode = opcode;
|
||
|
MI->OpcodePub = ins;
|
||
|
MI->size = 0;
|
||
|
|
||
|
*size = len;
|
||
|
if (len == 2) {
|
||
|
MCOperand_CreateImm0(MI, code[1]);
|
||
|
} else
|
||
|
if (len == 3) {
|
||
|
MCOperand_CreateImm0(MI, (code[2]<<8) | code[1]);
|
||
|
}
|
||
|
#ifndef CAPSTONE_DIET
|
||
|
if (MI->flat_insn->detail) {
|
||
|
fillDetails(MI, opcode);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
const char *MOS65XX_insn_name(csh handle, unsigned int id)
|
||
|
{
|
||
|
#ifdef CAPSTONE_DIET
|
||
|
return NULL;
|
||
|
#else
|
||
|
if (id >= ARR_SIZE(InstructionInfoTable)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return InstructionInfoTable[id].name;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
const char* MOS65XX_reg_name(csh handle, unsigned int reg)
|
||
|
{
|
||
|
#ifdef CAPSTONE_DIET
|
||
|
return NULL;
|
||
|
#else
|
||
|
if (reg >= ARR_SIZE(RegNames)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return RegNames[(int)reg];
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void MOS65XX_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
||
|
{
|
||
|
if (id < 256) {
|
||
|
insn->id = OpInfoTable[id].ins;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const char *MOS65XX_group_name(csh handle, unsigned int id)
|
||
|
{
|
||
|
#ifdef CAPSTONE_DIET
|
||
|
return NULL;
|
||
|
#else
|
||
|
if (id >= ARR_SIZE(GroupNames)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return GroupNames[(int)id];
|
||
|
#endif
|
||
|
}
|