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_STX, |
118 | OP65_STY, |
119 | OP65_STZ, |
120 | OP65_TAX, |
121 | OP65_TAY, |
122 | OP65_TRB, |
123 | OP65_TSB, |
124 | OP65_TSX, |
125 | OP65_TXA, |
126 | OP65_TXS, |
127 | OP65_TYA, |
128 | |
129 | /* Number of opcodes available */ |
130 | OP65_COUNT |
131 | } opc_t; |
132 | |
133 | /* 65XX addressing modes */ |
134 | typedef enum { |
135 | AM65_IMP, /* implicit */ |
136 | AM65_ACC, /* accumulator */ |
137 | AM65_IMM, /* immediate */ |
138 | AM65_ZP, /* zeropage */ |
139 | AM65_ZPX, /* zeropage,X */ |
140 | AM65_ZPY, /* zeropage,Y */ |
141 | AM65_ABS, /* absolute */ |
142 | AM65_ABSX, /* absolute,X */ |
143 | AM65_ABSY, /* absolute,Y */ |
144 | AM65_ZPX_IND, /* (zeropage,x) */ |
145 | AM65_ZP_INDY, /* (zeropage),y */ |
146 | AM65_ZP_IND, /* (zeropage) */ |
147 | AM65_BRA /* branch */ |
148 | } am_t; |
149 | |
150 | /* Branch conditions */ |
151 | typedef enum { |
152 | BC_CC, |
153 | BC_CS, |
154 | BC_EQ, |
155 | BC_MI, |
156 | BC_NE, |
157 | BC_PL, |
158 | BC_VC, |
159 | BC_VS |
160 | } bc_t; |
161 | |
162 | /* Opcode info */ |
163 | #define OF_NONE 0x0000U /* No additional information */ |
164 | #define OF_UBRA 0x0001U /* Unconditional branch */ |
165 | #define OF_CBRA 0x0002U /* Conditional branch */ |
166 | #define OF_ZBRA 0x0004U /* Branch on zero flag condition */ |
167 | #define OF_FBRA 0x0008U /* Branch on cond set by a load */ |
168 | #define OF_LBRA 0x0010U /* Jump/branch is long */ |
169 | #define OF_RET 0x0020U /* Return from function */ |
170 | #define OF_LOAD 0x0040U /* Register load */ |
171 | #define OF_STORE 0x0080U /* Register store */ |
172 | #define OF_XFR 0x0100U /* Transfer instruction */ |
173 | #define OF_CALL 0x0200U /* A subroutine call */ |
174 | #define OF_REG_INCDEC 0x0400U /* A register increment or decrement */ |
175 | #define OF_SETF 0x0800U /* Insn will set all load flags (not carry) */ |
176 | #define OF_CMP 0x1000U /* A compare A/X/Y instruction */ |
177 | #define OF_NOIMP 0x2000U /* Implicit addressing mode is actually A */ |
178 | |
179 | /* Combined infos */ |
180 | #define OF_BRA (OF_UBRA | OF_CBRA) /* Operation is a jump/branch */ |
181 | #define OF_DEAD (OF_UBRA | OF_RET) /* Dead end - no exec behind this point */ |
182 | |
183 | /* Opcode description */ |
184 | typedef struct { |
185 | opc_t OPC; /* Opcode */ |
186 | char Mnemo[9]; /* Mnemonic */ |
187 | unsigned char Size; /* Size, 0 = check addressing mode */ |
188 | unsigned short Use; /* Registers used by this insn */ |
189 | unsigned short Chg; /* Registers changed by this insn */ |
190 | unsigned short Info; /* Additional information */ |
191 | } OPCDesc; |
192 | |
193 | /* Opcode description table */ |
194 | extern const OPCDesc OPCTable[OP65_COUNT]; |
195 | |
196 | |
197 | |
198 | /*****************************************************************************/ |
199 | /* Code */ |
200 | /*****************************************************************************/ |
201 | |
202 | |
203 | |
204 | const OPCDesc* FindOP65 (const char* OPC); |
205 | /* Find the given opcode and return the opcode description. If the opcode was |
206 | ** not found, NULL is returned. |
207 | */ |
208 | |
209 | unsigned GetInsnSize (opc_t OPC, am_t AM); |
210 | /* Return the size of the given instruction */ |
211 | |
212 | #if defined(HAVE_INLINE) |
213 | INLINE const OPCDesc* GetOPCDesc (opc_t OPC) |
214 | /* Get an opcode description */ |
215 | { |
216 | /* Return the description */ |
217 | return &OPCTable [OPC]; |
218 | } |
219 | #else |
220 | # define GetOPCDesc(OPC) (&OPCTable [(OPC)]) |
221 | #endif |
222 | |
223 | #if defined(HAVE_INLINE) |
224 | INLINE unsigned GetOPCInfo (opc_t OPC) |
225 | /* Get opcode information */ |
226 | { |
227 | /* Return the info */ |
228 | return OPCTable[OPC].Info; |
229 | } |
230 | #else |
231 | # define GetOPCInfo(OPC) (OPCTable[(OPC)].Info) |
232 | #endif |
233 | |
234 | unsigned char GetAMUseInfo (am_t AM); |
235 | /* Get usage info for the given addressing mode (addressing modes that use |
236 | ** index registers return REG_r info for these registers). |
237 | */ |
238 | |
239 | opc_t GetInverseBranch (opc_t OPC); |
240 | /* Return a branch that reverse the condition of the branch given in OPC */ |
241 | |
242 | opc_t MakeShortBranch (opc_t OPC); |
243 | /* Return the short version of the given branch. If the branch is already |
244 | ** a short branch, return the opcode unchanged. |
245 | */ |
246 | |
247 | opc_t MakeLongBranch (opc_t OPC); |
248 | /* Return the long version of the given branch. If the branch is already |
249 | ** a long branch, return the opcode unchanged. |
250 | */ |
251 | |
252 | bc_t GetBranchCond (opc_t OPC); |
253 | /* Get the condition for the conditional branch in OPC */ |
254 | |
255 | bc_t GetInverseCond (bc_t BC); |
256 | /* Return the inverse condition of the given one */ |
257 | |
258 | |
259 | |
260 | /* End of opcodes.h */ |
261 | |
262 | #endif |
263 | |