2001-04-30 20:00:13 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* */
|
2013-05-09 11:56:54 +00:00
|
|
|
/* opcodes.h */
|
2001-04-30 20:00:13 +00:00
|
|
|
/* */
|
2013-05-09 11:56:54 +00:00
|
|
|
/* Opcode and addressing mode definitions */
|
2001-04-30 20:00:13 +00:00
|
|
|
/* */
|
|
|
|
/* */
|
|
|
|
/* */
|
2004-06-15 20:05:54 +00:00
|
|
|
/* (C) 2001-2004 Ullrich von Bassewitz */
|
2014-06-30 09:10:35 +00:00
|
|
|
/* Roemerstrasse 52 */
|
2004-06-15 20:05:54 +00:00
|
|
|
/* D-70794 Filderstadt */
|
2001-05-03 22:06:59 +00:00
|
|
|
/* EMail: uz@cc65.org */
|
2001-04-30 20:00:13 +00:00
|
|
|
/* */
|
|
|
|
/* */
|
|
|
|
/* This software is provided 'as-is', without any expressed or implied */
|
|
|
|
/* warranty. In no event will the authors be held liable for any damages */
|
|
|
|
/* arising from the use of this software. */
|
|
|
|
/* */
|
|
|
|
/* Permission is granted to anyone to use this software for any purpose, */
|
|
|
|
/* including commercial applications, and to alter it and redistribute it */
|
|
|
|
/* freely, subject to the following restrictions: */
|
|
|
|
/* */
|
|
|
|
/* 1. The origin of this software must not be misrepresented; you must not */
|
|
|
|
/* claim that you wrote the original software. If you use this software */
|
|
|
|
/* in a product, an acknowledgment in the product documentation would be */
|
|
|
|
/* appreciated but is not required. */
|
|
|
|
/* 2. Altered source versions must be plainly marked as such, and must not */
|
|
|
|
/* be misrepresented as being the original software. */
|
|
|
|
/* 3. This notice may not be removed or altered from any source */
|
|
|
|
/* distribution. */
|
|
|
|
/* */
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef OPCODES_H
|
|
|
|
#define OPCODES_H
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-05-16 19:01:19 +00:00
|
|
|
/* common */
|
|
|
|
#include "inline.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-04-30 20:00:13 +00:00
|
|
|
/*****************************************************************************/
|
2013-05-09 11:56:54 +00:00
|
|
|
/* Data */
|
2001-04-30 20:00:13 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
2004-06-15 20:05:54 +00:00
|
|
|
/* 65XX opcodes */
|
2001-04-30 20:00:13 +00:00
|
|
|
typedef enum {
|
2001-05-28 06:30:03 +00:00
|
|
|
OP65_ADC,
|
|
|
|
OP65_AND,
|
|
|
|
OP65_ASL,
|
|
|
|
OP65_BCC,
|
|
|
|
OP65_BCS,
|
|
|
|
OP65_BEQ,
|
|
|
|
OP65_BIT,
|
|
|
|
OP65_BMI,
|
|
|
|
OP65_BNE,
|
|
|
|
OP65_BPL,
|
|
|
|
OP65_BRA,
|
|
|
|
OP65_BRK,
|
|
|
|
OP65_BVC,
|
|
|
|
OP65_BVS,
|
|
|
|
OP65_CLC,
|
|
|
|
OP65_CLD,
|
|
|
|
OP65_CLI,
|
|
|
|
OP65_CLV,
|
|
|
|
OP65_CMP,
|
|
|
|
OP65_CPX,
|
|
|
|
OP65_CPY,
|
|
|
|
OP65_DEA,
|
|
|
|
OP65_DEC,
|
|
|
|
OP65_DEX,
|
|
|
|
OP65_DEY,
|
|
|
|
OP65_EOR,
|
|
|
|
OP65_INA,
|
|
|
|
OP65_INC,
|
|
|
|
OP65_INX,
|
|
|
|
OP65_INY,
|
|
|
|
OP65_JCC,
|
|
|
|
OP65_JCS,
|
|
|
|
OP65_JEQ,
|
|
|
|
OP65_JMI,
|
|
|
|
OP65_JMP,
|
|
|
|
OP65_JNE,
|
|
|
|
OP65_JPL,
|
|
|
|
OP65_JSR,
|
|
|
|
OP65_JVC,
|
|
|
|
OP65_JVS,
|
|
|
|
OP65_LDA,
|
|
|
|
OP65_LDX,
|
|
|
|
OP65_LDY,
|
|
|
|
OP65_LSR,
|
|
|
|
OP65_NOP,
|
|
|
|
OP65_ORA,
|
|
|
|
OP65_PHA,
|
|
|
|
OP65_PHP,
|
|
|
|
OP65_PHX,
|
|
|
|
OP65_PHY,
|
|
|
|
OP65_PLA,
|
|
|
|
OP65_PLP,
|
|
|
|
OP65_PLX,
|
|
|
|
OP65_PLY,
|
|
|
|
OP65_ROL,
|
|
|
|
OP65_ROR,
|
|
|
|
OP65_RTI,
|
|
|
|
OP65_RTS,
|
|
|
|
OP65_SBC,
|
|
|
|
OP65_SEC,
|
|
|
|
OP65_SED,
|
|
|
|
OP65_SEI,
|
|
|
|
OP65_STA,
|
2020-03-27 02:54:58 +00:00
|
|
|
OP65_STP, /* 65c02, 65816 stop */
|
2001-05-28 06:30:03 +00:00
|
|
|
OP65_STX,
|
|
|
|
OP65_STY,
|
2002-03-11 06:29:54 +00:00
|
|
|
OP65_STZ,
|
2001-05-28 06:30:03 +00:00
|
|
|
OP65_TAX,
|
|
|
|
OP65_TAY,
|
|
|
|
OP65_TRB,
|
|
|
|
OP65_TSB,
|
|
|
|
OP65_TSX,
|
|
|
|
OP65_TXA,
|
|
|
|
OP65_TXS,
|
|
|
|
OP65_TYA,
|
2001-05-29 07:41:08 +00:00
|
|
|
|
|
|
|
/* Number of opcodes available */
|
2020-08-30 17:57:01 +00:00
|
|
|
OP65_COUNT,
|
|
|
|
|
|
|
|
/* Invalid opcode */
|
|
|
|
OP65_INVALID = OP65_COUNT,
|
2001-04-30 20:00:13 +00:00
|
|
|
} opc_t;
|
|
|
|
|
2004-06-15 20:05:54 +00:00
|
|
|
/* 65XX addressing modes */
|
2001-04-30 20:00:13 +00:00
|
|
|
typedef enum {
|
2013-05-09 11:56:54 +00:00
|
|
|
AM65_IMP, /* implicit */
|
|
|
|
AM65_ACC, /* accumulator */
|
2018-10-13 07:05:33 +00:00
|
|
|
AM65_IMM, /* immediate */
|
2013-05-09 11:56:54 +00:00
|
|
|
AM65_ZP, /* zeropage */
|
|
|
|
AM65_ZPX, /* zeropage,X */
|
2001-07-16 16:32:14 +00:00
|
|
|
AM65_ZPY, /* zeropage,Y */
|
2013-05-09 11:56:54 +00:00
|
|
|
AM65_ABS, /* absolute */
|
|
|
|
AM65_ABSX, /* absolute,X */
|
|
|
|
AM65_ABSY, /* absolute,Y */
|
|
|
|
AM65_ZPX_IND, /* (zeropage,x) */
|
|
|
|
AM65_ZP_INDY, /* (zeropage),y */
|
|
|
|
AM65_ZP_IND, /* (zeropage) */
|
2001-05-28 06:30:03 +00:00
|
|
|
AM65_BRA /* branch */
|
2001-04-30 20:00:13 +00:00
|
|
|
} am_t;
|
|
|
|
|
2001-05-06 20:57:58 +00:00
|
|
|
/* Branch conditions */
|
|
|
|
typedef enum {
|
|
|
|
BC_CC,
|
|
|
|
BC_CS,
|
2001-05-29 07:41:08 +00:00
|
|
|
BC_EQ,
|
2001-05-06 20:57:58 +00:00
|
|
|
BC_MI,
|
|
|
|
BC_NE,
|
|
|
|
BC_PL,
|
|
|
|
BC_VC,
|
|
|
|
BC_VS
|
|
|
|
} bc_t;
|
|
|
|
|
2001-05-05 16:12:47 +00:00
|
|
|
/* Opcode info */
|
2013-05-09 11:56:54 +00:00
|
|
|
#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 */
|
2001-08-05 20:37:14 +00:00
|
|
|
#define OF_FBRA 0x0008U /* Branch on cond set by a load */
|
2013-05-09 11:56:54 +00:00
|
|
|
#define OF_LBRA 0x0010U /* Jump/branch is long */
|
|
|
|
#define OF_RET 0x0020U /* Return from function */
|
|
|
|
#define OF_LOAD 0x0040U /* Register load */
|
2001-08-05 20:37:14 +00:00
|
|
|
#define OF_STORE 0x0080U /* Register store */
|
|
|
|
#define OF_XFR 0x0100U /* Transfer instruction */
|
|
|
|
#define OF_CALL 0x0200U /* A subroutine call */
|
|
|
|
#define OF_REG_INCDEC 0x0400U /* A register increment or decrement */
|
2020-09-08 15:41:02 +00:00
|
|
|
#define OF_SETF 0x0800U /* Insn will set both Z and N flags according to the result */
|
2001-09-25 12:34:34 +00:00
|
|
|
#define OF_CMP 0x1000U /* A compare A/X/Y instruction */
|
2004-07-18 09:34:52 +00:00
|
|
|
#define OF_NOIMP 0x2000U /* Implicit addressing mode is actually A */
|
2020-09-08 15:41:02 +00:00
|
|
|
#define OF_READ 0x4000U /* Read from the memory address */
|
|
|
|
#define OF_WRITE 0x8000U /* Write to the memory address */
|
2001-05-28 06:30:03 +00:00
|
|
|
|
|
|
|
/* Combined infos */
|
2013-05-09 11:56:54 +00:00
|
|
|
#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 */
|
2020-09-08 15:41:02 +00:00
|
|
|
#define OF_RMW (OF_READ | OF_WRITE) /* Read, Modify and Write */
|
2001-05-05 16:12:47 +00:00
|
|
|
|
2001-04-30 20:00:13 +00:00
|
|
|
/* Opcode description */
|
|
|
|
typedef struct {
|
2013-05-09 11:56:54 +00:00
|
|
|
opc_t OPC; /* Opcode */
|
|
|
|
char Mnemo[9]; /* Mnemonic */
|
|
|
|
unsigned char Size; /* Size, 0 = check addressing mode */
|
|
|
|
unsigned short Info; /* Additional information */
|
2020-09-13 01:14:51 +00:00
|
|
|
unsigned int Use; /* Registers used by this insn */
|
|
|
|
unsigned int Chg; /* Registers changed by this insn */
|
2001-04-30 20:00:13 +00:00
|
|
|
} OPCDesc;
|
|
|
|
|
2001-05-16 19:01:19 +00:00
|
|
|
/* Opcode description table */
|
2004-06-15 20:05:54 +00:00
|
|
|
extern const OPCDesc OPCTable[OP65_COUNT];
|
2001-05-16 19:01:19 +00:00
|
|
|
|
2001-04-30 20:00:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2013-05-09 11:56:54 +00:00
|
|
|
/* Code */
|
2001-04-30 20:00:13 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-05-29 07:41:08 +00:00
|
|
|
const OPCDesc* FindOP65 (const char* OPC);
|
2001-04-30 20:00:13 +00:00
|
|
|
/* Find the given opcode and return the opcode description. If the opcode was
|
2014-06-30 09:10:35 +00:00
|
|
|
** not found, NULL is returned.
|
|
|
|
*/
|
2001-04-30 20:00:13 +00:00
|
|
|
|
|
|
|
unsigned GetInsnSize (opc_t OPC, am_t AM);
|
|
|
|
/* Return the size of the given instruction */
|
|
|
|
|
2001-05-16 19:01:19 +00:00
|
|
|
#if defined(HAVE_INLINE)
|
|
|
|
INLINE const OPCDesc* GetOPCDesc (opc_t OPC)
|
2001-04-30 20:00:13 +00:00
|
|
|
/* Get an opcode description */
|
2001-05-16 19:01:19 +00:00
|
|
|
{
|
|
|
|
/* Return the description */
|
|
|
|
return &OPCTable [OPC];
|
|
|
|
}
|
|
|
|
#else
|
2013-05-09 11:56:54 +00:00
|
|
|
# define GetOPCDesc(OPC) (&OPCTable [(OPC)])
|
2001-05-16 19:01:19 +00:00
|
|
|
#endif
|
2001-05-01 15:50:31 +00:00
|
|
|
|
2001-05-16 19:01:19 +00:00
|
|
|
#if defined(HAVE_INLINE)
|
2001-05-28 06:30:03 +00:00
|
|
|
INLINE unsigned GetOPCInfo (opc_t OPC)
|
2001-05-05 21:42:58 +00:00
|
|
|
/* Get opcode information */
|
2001-05-16 19:01:19 +00:00
|
|
|
{
|
|
|
|
/* Return the info */
|
|
|
|
return OPCTable[OPC].Info;
|
|
|
|
}
|
|
|
|
#else
|
2013-05-09 11:56:54 +00:00
|
|
|
# define GetOPCInfo(OPC) (OPCTable[(OPC)].Info)
|
2001-05-16 19:01:19 +00:00
|
|
|
#endif
|
2001-05-05 21:42:58 +00:00
|
|
|
|
2001-05-05 16:12:47 +00:00
|
|
|
unsigned char GetAMUseInfo (am_t AM);
|
2001-05-04 16:41:23 +00:00
|
|
|
/* Get usage info for the given addressing mode (addressing modes that use
|
2014-06-30 09:10:35 +00:00
|
|
|
** index registers return REG_r info for these registers).
|
|
|
|
*/
|
2001-05-04 16:41:23 +00:00
|
|
|
|
2001-05-05 11:31:05 +00:00
|
|
|
opc_t GetInverseBranch (opc_t OPC);
|
2001-05-05 21:42:58 +00:00
|
|
|
/* Return a branch that reverse the condition of the branch given in OPC */
|
2001-05-05 11:31:05 +00:00
|
|
|
|
2001-05-06 20:57:58 +00:00
|
|
|
opc_t MakeShortBranch (opc_t OPC);
|
|
|
|
/* Return the short version of the given branch. If the branch is already
|
2014-06-30 09:10:35 +00:00
|
|
|
** a short branch, return the opcode unchanged.
|
|
|
|
*/
|
2001-05-06 20:57:58 +00:00
|
|
|
|
|
|
|
opc_t MakeLongBranch (opc_t OPC);
|
|
|
|
/* Return the long version of the given branch. If the branch is already
|
2014-06-30 09:10:35 +00:00
|
|
|
** a long branch, return the opcode unchanged.
|
|
|
|
*/
|
2001-05-06 20:57:58 +00:00
|
|
|
|
|
|
|
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 */
|
|
|
|
|
2001-04-30 20:00:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* End of opcodes.h */
|
|
|
|
|
2014-03-04 00:11:19 +00:00
|
|
|
#endif
|