1 /*****************************************************************************/
5 /* Opcode and addressing mode definitions */
9 /* (C) 2001 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
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. */
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: */
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 */
32 /*****************************************************************************/
49 /*****************************************************************************/
51 /*****************************************************************************/
55 /* Mapper table, mnemonic --> opcode */
56 static const OPCDesc OPCTable[OPC_COUNT] = {
57 { "adc", OPC_ADC, CI_USE_A | CI_CHG_A },
58 { "and", OPC_AND, CI_USE_A | CI_CHG_A },
59 { "asl", OPC_ASL, CI_USE_A | CI_CHG_A },
60 { "bcc", OPC_BCC, CI_CHG_NONE },
61 { "bcs", OPC_BCS, CI_CHG_NONE },
62 { "beq", OPC_BEQ, CI_CHG_NONE },
63 { "bit", OPC_BIT, CI_USE_A },
64 { "bmi", OPC_BMI, CI_CHG_NONE },
65 { "bne", OPC_BNE, CI_CHG_NONE },
66 { "bpl", OPC_BPL, CI_CHG_NONE },
67 { "bra", OPC_BRA, CI_CHG_NONE },
68 { "brk", OPC_BRK, CI_CHG_NONE },
69 { "bvc", OPC_BVC, CI_CHG_NONE },
70 { "bvs", OPC_BVS, CI_CHG_NONE },
71 { "clc", OPC_CLC, CI_CHG_NONE },
72 { "cld", OPC_CLD, CI_CHG_NONE },
73 { "cli", OPC_CLI, CI_CHG_NONE },
74 { "clv", OPC_CLV, CI_CHG_NONE },
75 { "cmp", OPC_CMP, CI_USE_A },
76 { "cpx", OPC_CPX, CI_USE_X },
77 { "cpy", OPC_CPY, CI_USE_Y },
78 { "dea", OPC_DEA, CI_USE_A | CI_CHG_A },
79 { "dec", OPC_DEC, CI_NONE },
80 { "dex", OPC_DEX, CI_USE_X | CI_CHG_X },
81 { "dey", OPC_DEY, CI_USE_Y | CI_CHG_Y },
82 { "eor", OPC_EOR, CI_USE_A | CI_CHG_A },
83 { "ina", OPC_INA, CI_USE_A | CI_CHG_A },
84 { "inc", OPC_INC, CI_NONE },
85 { "inx", OPC_INX, CI_USE_X | CI_CHG_X },
86 { "iny", OPC_INY, CI_USE_Y | CI_CHG_Y },
87 { "jmp", OPC_JMP, CI_NONE },
88 { "jsr", OPC_JSR, CI_NONE },
89 { "lda", OPC_LDA, CI_CHG_A },
90 { "ldx", OPC_LDX, CI_CHG_X },
91 { "ldy", OPC_LDY, CI_CHG_Y },
92 { "lsr", OPC_LSR, CI_USE_A | CI_CHG_A },
93 { "nop", OPC_NOP, CI_NONE },
94 { "ora", OPC_ORA, CI_USE_A | CI_CHG_A },
95 { "pha", OPC_PHA, CI_USE_A },
96 { "php", OPC_PHP, CI_NONE },
97 { "phx", OPC_PHX, CI_USE_X },
98 { "phy", OPC_PHY, CI_USE_Y },
99 { "pla", OPC_PLA, CI_CHG_A },
100 { "plp", OPC_PLP, CI_NONE },
101 { "plx", OPC_PLX, CI_CHG_X },
102 { "ply", OPC_PLY, CI_CHG_Y },
103 { "rol", OPC_ROL, CI_USE_A | CI_CHG_A },
104 { "ror", OPC_ROR, CI_USE_A | CI_CHG_A },
105 { "rti", OPC_RTI, CI_NONE },
106 { "rts", OPC_RTS, CI_NONE },
107 { "sbc", OPC_SBC, CI_USE_A | CI_CHG_A },
108 { "sec", OPC_SEC, CI_NONE },
109 { "sed", OPC_SED, CI_NONE },
110 { "sei", OPC_SEI, CI_NONE },
111 { "sta", OPC_STA, CI_USE_A },
112 { "stx", OPC_STX, CI_USE_X },
113 { "sty", OPC_STY, CI_USE_Y },
114 { "tax", OPC_TAX, CI_USE_A | CI_CHG_X },
115 { "tay", OPC_TAY, CI_USE_A | CI_CHG_Y },
116 { "trb", OPC_TRB, CI_USE_A },
117 { "tsb", OPC_TSB, CI_USE_A },
118 { "tsx", OPC_TSX, CI_CHG_X },
119 { "txa", OPC_TXA, CI_USE_X | CI_CHG_A },
120 { "txs", OPC_TXS, CI_USE_X },
121 { "tya", OPC_TYA, CI_USE_Y | CI_CHG_A }
126 /*****************************************************************************/
128 /*****************************************************************************/
132 static int Compare (const void* Key, const void* Desc)
133 /* Compare function for bsearch */
135 return strcmp (Key, ((OPCDesc*)Desc)->Mnemo);
140 const OPCDesc* FindOpcode (const char* M)
141 /* Find the given opcode and return the opcode number. If the opcode was not
142 * found, return OPC_INVALID.
148 /* Check the length of the given string, then copy it into local
149 * storage, converting it to upper case.
151 char Mnemo[sizeof (OPCTable[0].Mnemo)];
153 if (Len >= sizeof (OPCTable[0].Mnemo)) {
154 /* Invalid length means invalid opcode */
157 for (I = 0; I < Len; ++I) {
158 Mnemo[I] = tolower (M[I]);
162 /* Search for the mnemonic in the table and return the result */
163 return bsearch (Mnemo, OPCTable, OPC_COUNT, sizeof (OPCTable[0]), Compare);
168 unsigned GetInsnSize (opc_t OPC, am_t AM)
169 /* Return the size of the given instruction */
171 /* On the 6502 (and 65C02), the instruction size is determined only by the
175 case AM_IMP: return 1;
176 case AM_IMM: return 2;
177 case AM_ZP: return 2;
178 case AM_ZPX: return 2;
179 case AM_ABS: return 3;
180 case AM_ABSX: return 3;
181 case AM_ABSY: return 3;
182 case AM_ZPX_IND: return 2;
183 case AM_ZP_INDY: return 2;
184 case AM_ZP_IND: return 2;
185 case AM_BRA: return 2;
186 default: FAIL ("Invalid addressing mode");
192 const OPCDesc* GetOPCDesc (opc_t OPC)
193 /* Get an opcode description */
195 /* Check the range */
196 PRECONDITION (OPC >= (opc_t)0 && OPC < OPC_COUNT);
198 /* Return the description */
199 return &OPCTable [OPC];