1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 opcodes.h                                 */
4 /*                                                                           */
5 /*                  Opcode and addressing mode definitions                   */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2001-2004 Ullrich von Bassewitz                                       */
10 /*               Roemerstrasse 52                                            */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33 
34 
35 
36 #ifndef OPCODES_H
37 #define OPCODES_H
38 
39 
40 
41 /* common */
42 #include "inline.h"
43 
44 
45 
46 /*****************************************************************************/
47 /*                                   Data                                    */
48 /*****************************************************************************/
49 
50 
51 
52 /* 65XX opcodes */
53 typedef enum {
54     OP65_ADC,
55     OP65_AND,
56     OP65_ASL,
57     OP65_BCC,
58     OP65_BCS,
59     OP65_BEQ,
60     OP65_BIT,
61     OP65_BMI,
62     OP65_BNE,
63     OP65_BPL,
64     OP65_BRA,
65     OP65_BRK,
66     OP65_BVC,
67     OP65_BVS,
68     OP65_CLC,
69     OP65_CLD,
70     OP65_CLI,
71     OP65_CLV,
72     OP65_CMP,
73     OP65_CPX,
74     OP65_CPY,
75     OP65_DEA,
76     OP65_DEC,
77     OP65_DEX,
78     OP65_DEY,
79     OP65_EOR,
80     OP65_INA,
81     OP65_INC,
82     OP65_INX,
83     OP65_INY,
84     OP65_JCC,
85     OP65_JCS,
86     OP65_JEQ,
87     OP65_JMI,
88     OP65_JMP,
89     OP65_JNE,
90     OP65_JPL,
91     OP65_JSR,
92     OP65_JVC,
93     OP65_JVS,
94     OP65_LDA,
95     OP65_LDX,
96     OP65_LDY,
97     OP65_LSR,
98     OP65_NOP,
99     OP65_ORA,
100     OP65_PHA,
101     OP65_PHP,
102     OP65_PHX,
103     OP65_PHY,
104     OP65_PLA,
105     OP65_PLP,
106     OP65_PLX,
107     OP65_PLY,
108     OP65_ROL,
109     OP65_ROR,
110     OP65_RTI,
111     OP65_RTS,
112     OP65_SBC,
113     OP65_SEC,
114     OP65_SED,
115     OP65_SEI,
116     OP65_STA,
117     OP65_STP,                   /* 65c02, 65816 stop */
118     OP65_STX,
119     OP65_STY,
120     OP65_STZ,
121     OP65_TAX,
122     OP65_TAY,
123     OP65_TRB,
124     OP65_TSB,
125     OP65_TSX,
126     OP65_TXA,
127     OP65_TXS,
128     OP65_TYA,
129 
130     /* Number of opcodes available */
131     OP65_COUNT
132 } opc_t;
133 
134 /* 65XX addressing modes */
135 typedef enum {
136     AM65_IMP,                   /* implicit */
137     AM65_ACC,                   /* accumulator */
138     AM65_IMM,                   /* immediate */
139     AM65_ZP,                    /* zeropage */
140     AM65_ZPX,                   /* zeropage,X */
141     AM65_ZPY,                   /* zeropage,Y */
142     AM65_ABS,                   /* absolute */
143     AM65_ABSX,                  /* absolute,X */
144     AM65_ABSY,                  /* absolute,Y */
145     AM65_ZPX_IND,               /* (zeropage,x) */
146     AM65_ZP_INDY,               /* (zeropage),y */
147     AM65_ZP_IND,                /* (zeropage) */
148     AM65_BRA                    /* branch */
149 } am_t;
150 
151 /* Branch conditions */
152 typedef enum {
153     BC_CC,
154     BC_CS,
155     BC_EQ,
156     BC_MI,
157     BC_NE,
158     BC_PL,
159     BC_VC,
160     BC_VS
161 } bc_t;
162 
163 /* Opcode info */
164 #define OF_NONE         0x0000U /* No additional information */
165 #define OF_UBRA         0x0001U /* Unconditional branch */
166 #define OF_CBRA         0x0002U /* Conditional branch */
167 #define OF_ZBRA         0x0004U /* Branch on zero flag condition */
168 #define OF_FBRA         0x0008U /* Branch on cond set by a load */
169 #define OF_LBRA         0x0010U /* Jump/branch is long */
170 #define OF_RET          0x0020U /* Return from function */
171 #define OF_LOAD         0x0040U /* Register load */
172 #define OF_STORE        0x0080U /* Register store */
173 #define OF_XFR          0x0100U /* Transfer instruction */
174 #define OF_CALL         0x0200U /* A subroutine call */
175 #define OF_REG_INCDEC   0x0400U /* A register increment or decrement */
176 #define OF_SETF         0x0800U /* Insn will set all load flags (not carry) */
177 #define OF_CMP          0x1000U /* A compare A/X/Y instruction */
178 #define OF_NOIMP        0x2000U /* Implicit addressing mode is actually A */
179 
180 /* Combined infos */
181 #define OF_BRA  (OF_UBRA | OF_CBRA)     /* Operation is a jump/branch */
182 #define OF_DEAD (OF_UBRA | OF_RET)      /* Dead end - no exec behind this point */
183 
184 /* Opcode description */
185 typedef struct {
186     opc_t           OPC;                /* Opcode */
187     char            Mnemo[9];           /* Mnemonic */
188     unsigned char   Size;               /* Size, 0 = check addressing mode */
189     unsigned short  Use;                /* Registers used by this insn */
190     unsigned short  Chg;                /* Registers changed by this insn */
191     unsigned short  Info;               /* Additional information */
192 } OPCDesc;
193 
194 /* Opcode description table */
195 extern const OPCDesc OPCTable[OP65_COUNT];
196 
197 
198 
199 /*****************************************************************************/
200 /*                                   Code                                    */
201 /*****************************************************************************/
202 
203 
204 
205 const OPCDesc* FindOP65 (const char* OPC);
206 /* Find the given opcode and return the opcode description. If the opcode was
207 ** not found, NULL is returned.
208 */
209 
210 unsigned GetInsnSize (opc_t OPC, am_t AM);
211 /* Return the size of the given instruction */
212 
213 #if defined(HAVE_INLINE)
GetOPCDesc(opc_t OPC)214 INLINE const OPCDesc* GetOPCDesc (opc_t OPC)
215 /* Get an opcode description */
216 {
217     /* Return the description */
218     return &OPCTable [OPC];
219 }
220 #else
221 #  define GetOPCDesc(OPC)       (&OPCTable [(OPC)])
222 #endif
223 
224 #if defined(HAVE_INLINE)
GetOPCInfo(opc_t OPC)225 INLINE unsigned GetOPCInfo (opc_t OPC)
226 /* Get opcode information */
227 {
228     /* Return the info */
229     return OPCTable[OPC].Info;
230 }
231 #else
232 #  define GetOPCInfo(OPC)       (OPCTable[(OPC)].Info)
233 #endif
234 
235 unsigned char GetAMUseInfo (am_t AM);
236 /* Get usage info for the given addressing mode (addressing modes that use
237 ** index registers return REG_r info for these registers).
238 */
239 
240 opc_t GetInverseBranch (opc_t OPC);
241 /* Return a branch that reverse the condition of the branch given in OPC */
242 
243 opc_t MakeShortBranch (opc_t OPC);
244 /* Return the short version of the given branch. If the branch is already
245 ** a short branch, return the opcode unchanged.
246 */
247 
248 opc_t MakeLongBranch (opc_t OPC);
249 /* Return the long version of the given branch. If the branch is already
250 ** a long branch, return the opcode unchanged.
251 */
252 
253 bc_t GetBranchCond (opc_t OPC);
254 /* Get the condition for the conditional branch in OPC */
255 
256 bc_t GetInverseCond (bc_t BC);
257 /* Return the inverse condition of the given one */
258 
259 
260 
261 /* End of opcodes.h */
262 
263 #endif
264