]> git.sur5r.net Git - cc65/blob - src/cc65/opcodes.c
Working on the new backend
[cc65] / src / cc65 / opcodes.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 opcodes.c                                 */
4 /*                                                                           */
5 /*                  Opcode and addressing mode definitions                   */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2001     Ullrich von Bassewitz                                        */
10 /*              Wacholderweg 14                                              */
11 /*              D-70597 Stuttgart                                            */
12 /* EMail:       uz@musoftware.de                                             */
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 #include "stdlib.h"
37 #include <string.h>
38 #include <ctype.h>
39
40 /* common */
41 #include "check.h"
42
43 /* cc65 */
44 #include "codeinfo.h"
45 #include "opcodes.h"
46
47
48
49 /*****************************************************************************/
50 /*                                   Data                                    */
51 /*****************************************************************************/
52
53
54
55 /* Mapper table, mnemonic --> opcode */
56 static const OPCDesc OPCTable[OPC_COUNT] = {
57     { "adc", OPC_ADC, 0, CI_USE_A | CI_CHG_A    },
58     { "and", OPC_AND, 0, CI_USE_A | CI_CHG_A    },
59     { "asl", OPC_ASL, 0, CI_USE_A | CI_CHG_A    },
60     { "bcc", OPC_BCC, 2, CI_BRA                 },
61     { "bcs", OPC_BCS, 2, CI_BRA                 },
62     { "beq", OPC_BEQ, 2, CI_BRA                 },
63     { "bit", OPC_BIT, 0, CI_USE_A               },
64     { "bmi", OPC_BMI, 2, CI_BRA                 },
65     { "bne", OPC_BNE, 2, CI_BRA                 },
66     { "bpl", OPC_BPL, 2, CI_BRA                 },
67     { "bra", OPC_BRA, 2, CI_BRA                 },
68     { "brk", OPC_BRK, 1, CI_NONE                },
69     { "bvc", OPC_BVC, 2, CI_BRA                 },
70     { "bvs", OPC_BVS, 2, CI_BRA                 },
71     { "clc", OPC_CLC, 1, CI_CHG_NONE            },
72     { "cld", OPC_CLD, 1, CI_CHG_NONE            },
73     { "cli", OPC_CLI, 1, CI_CHG_NONE            },
74     { "clv", OPC_CLV, 1, CI_CHG_NONE            },
75     { "cmp", OPC_CMP, 0, CI_USE_A               },
76     { "cpx", OPC_CPX, 0, CI_USE_X               },
77     { "cpy", OPC_CPY, 0, CI_USE_Y               },
78     { "dea", OPC_DEA, 1, CI_USE_A | CI_CHG_A    },
79     { "dec", OPC_DEC, 0, CI_NONE                },
80     { "dex", OPC_DEX, 1, CI_USE_X | CI_CHG_X    },
81     { "dey", OPC_DEY, 1, CI_USE_Y | CI_CHG_Y    },
82     { "eor", OPC_EOR, 0, CI_USE_A | CI_CHG_A    },
83     { "ina", OPC_INA, 1, CI_USE_A | CI_CHG_A    },
84     { "inc", OPC_INC, 0, CI_NONE                },
85     { "inx", OPC_INX, 1, CI_USE_X | CI_CHG_X    },
86     { "iny", OPC_INY, 1, CI_USE_Y | CI_CHG_Y    },
87     { "jcc", OPC_JCC, 5, CI_BRA                 },
88     { "jcs", OPC_JCS, 5, CI_BRA                 },
89     { "jeq", OPC_JEQ, 5, CI_BRA                 },
90     { "jmi", OPC_JMI, 5, CI_BRA                 },
91     { "jmp", OPC_JMP, 3, CI_BRA                 },
92     { "jne", OPC_JNE, 5, CI_BRA                 },
93     { "jpl", OPC_JPL, 5, CI_BRA                 },
94     { "jsr", OPC_JSR, 3, CI_BRA                 },
95     { "jvc", OPC_JVC, 5, CI_BRA                 },
96     { "jvs", OPC_JVS, 5, CI_BRA                 },
97     { "lda", OPC_LDA, 0, CI_CHG_A               },
98     { "ldx", OPC_LDX, 0, CI_CHG_X               },
99     { "ldy", OPC_LDY, 0, CI_CHG_Y               },
100     { "lsr", OPC_LSR, 0, CI_USE_A | CI_CHG_A    },
101     { "nop", OPC_NOP, 1, CI_NONE                },
102     { "ora", OPC_ORA, 0, CI_USE_A | CI_CHG_A    },
103     { "pha", OPC_PHA, 1, CI_USE_A               },
104     { "php", OPC_PHP, 1, CI_NONE                },
105     { "phx", OPC_PHX, 1, CI_USE_X               },
106     { "phy", OPC_PHY, 1, CI_USE_Y               },
107     { "pla", OPC_PLA, 1, CI_CHG_A               },
108     { "plp", OPC_PLP, 1, CI_NONE                },
109     { "plx", OPC_PLX, 1, CI_CHG_X               },
110     { "ply", OPC_PLY, 1, CI_CHG_Y               },
111     { "rol", OPC_ROL, 0, CI_USE_A | CI_CHG_A    },
112     { "ror", OPC_ROR, 0, CI_USE_A | CI_CHG_A    },
113     { "rti", OPC_RTI, 1, CI_NONE                },
114     { "rts", OPC_RTS, 1, CI_NONE                },
115     { "sbc", OPC_SBC, 0, CI_USE_A | CI_CHG_A    },
116     { "sec", OPC_SEC, 1, CI_NONE                },
117     { "sed", OPC_SED, 1, CI_NONE                },
118     { "sei", OPC_SEI, 1, CI_NONE                },
119     { "sta", OPC_STA, 0, CI_USE_A               },
120     { "stx", OPC_STX, 0, CI_USE_X               },
121     { "sty", OPC_STY, 0, CI_USE_Y               },
122     { "tax", OPC_TAX, 1, CI_USE_A | CI_CHG_X    },
123     { "tay", OPC_TAY, 1, CI_USE_A | CI_CHG_Y    },
124     { "trb", OPC_TRB, 0, CI_USE_A               },
125     { "tsb", OPC_TSB, 0, CI_USE_A               },
126     { "tsx", OPC_TSX, 1, CI_CHG_X               },
127     { "txa", OPC_TXA, 1, CI_USE_X | CI_CHG_A    },
128     { "txs", OPC_TXS, 1, CI_USE_X               },
129     { "tya", OPC_TYA, 1, CI_USE_Y | CI_CHG_A    }
130 };
131
132
133
134 /*****************************************************************************/
135 /*                                   Code                                    */
136 /*****************************************************************************/
137
138
139
140 static int Compare (const void* Key, const void* Desc)
141 /* Compare function for bsearch */
142 {
143     return strcmp (Key, ((OPCDesc*)Desc)->Mnemo);
144 }
145
146
147
148 const OPCDesc* FindOpcode (const char* M)
149 /* Find the given opcode and return the opcode number. If the opcode was not
150  * found, return OPC_INVALID.
151  */
152 {
153     unsigned I;
154     unsigned Len;
155
156     /* Check the length of the given string, then copy it into local
157      * storage, converting it to upper case.
158      */
159     char Mnemo[sizeof (OPCTable[0].Mnemo)];
160     Len = strlen (M);
161     if (Len >= sizeof (OPCTable[0].Mnemo)) {
162         /* Invalid length means invalid opcode */
163         return 0;
164     }
165     for (I = 0; I < Len; ++I) {
166         Mnemo[I] = tolower (M[I]);
167     }
168     Mnemo[I] = '\0';
169
170     /* Search for the mnemonic in the table and return the result */
171     return bsearch (Mnemo, OPCTable, OPC_COUNT, sizeof (OPCTable[0]), Compare);
172 }
173
174
175
176 unsigned GetInsnSize (opc_t OPC, am_t AM)
177 /* Return the size of the given instruction */
178 {
179     /* Get the opcode desc and check the size given there */
180     const OPCDesc* D = &OPCTable[OPC];
181     if (D->Size != 0) {
182         return D->Size;
183     }
184
185     /* Check the addressing mode. */
186     switch (AM) {
187         case AM_IMP:      return 1;
188         case AM_ACC:      return 1;
189         case AM_IMM:      return 2;
190         case AM_ZP:       return 2;
191         case AM_ZPX:      return 2;
192         case AM_ABS:      return 3;
193         case AM_ABSX:     return 3;
194         case AM_ABSY:     return 3;
195         case AM_ZPX_IND:  return 2;
196         case AM_ZP_INDY:  return 2;
197         case AM_ZP_IND:   return 2;
198         default:          FAIL ("Invalid addressing mode");
199     }
200 }
201
202
203
204 const OPCDesc* GetOPCDesc (opc_t OPC)
205 /* Get an opcode description */
206 {
207     /* Check the range */
208     PRECONDITION (OPC >= (opc_t)0 && OPC < OPC_COUNT);
209
210     /* Return the description */
211     return &OPCTable [OPC];
212 }
213
214
215
216