]> git.sur5r.net Git - cc65/blob - src/cc65/opcodes.c
Working on the 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@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 #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 "cpu.h"
46 #include "error.h"
47 #include "opcodes.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Data                                    */
53 /*****************************************************************************/
54
55
56
57 /* Opcode description table */
58 const OPCDesc OPCTable[OPCODE_COUNT] = {
59
60     /* Opcodes for the virtual stack machine */
61     {   OPC_LDA,                                /* opcode */
62         "loada",                                /* mnemonic */
63         0,                                      /* size */
64         REG_NONE,                               /* use */
65         REG_A,                                  /* chg */
66         OF_CPU_VM | OF_LOAD                     /* flags */
67     },
68     {   OPC_LDAX,                               /* opcode */
69         "loadax",                               /* mnemonic */
70         0,                                      /* size */
71         REG_NONE,                               /* use */
72         REG_AX,                                 /* chg */
73         OF_CPU_VM | OF_LOAD                     /* flags */
74     },
75     {   OPC_LDEAX,                              /* opcode */
76         "loadeax",                              /* mnemonic */
77         0,                                      /* size */
78         REG_NONE,                               /* use */
79         REG_EAX,                                /* chg */
80         OF_CPU_VM | OF_LOAD                     /* flags */
81     },
82     {   OPC_PHA,                                /* opcode */
83         "pusha",                                /* mnemonic */
84         0,                                      /* size */
85         REG_A,                                  /* use */
86         REG_NONE,                               /* chg */
87         OF_CPU_VM                               /* flags */
88     },
89     {   OPC_PHAX,                               /* opcode */
90         "pushax",                               /* mnemonic */
91         0,                                      /* size */
92         REG_AX,                                 /* use */
93         REG_NONE,                               /* chg */
94         OF_CPU_VM                               /* flags */
95     },
96     {   OPC_PHEAX,                              /* opcode */
97         "pusheax",                              /* mnemonic */
98         0,                                      /* size */
99         REG_EAX,                                /* use */
100         REG_NONE,                               /* chg */
101         OF_CPU_VM                               /* flags */
102     },
103     {   OPC_STA,                                /* opcode */
104         "storea",                               /* mnemonic */
105         0,                                      /* size */
106         REG_A,                                  /* use */
107         REG_NONE,                               /* chg */
108         OF_CPU_VM                               /* flags */
109     },
110     {   OPC_STAX,                               /* opcode */
111         "storeax",                              /* mnemonic */
112         0,                                      /* size */
113         REG_AX,                                 /* use */
114         REG_NONE,                               /* chg */
115         OF_CPU_VM                               /* flags */
116     },
117     {   OPC_STEAX,                              /* opcode */
118         "storeeax",                             /* mnemonic */
119         0,                                      /* size */
120         REG_EAX,                                /* use */
121         REG_NONE,                               /* chg */
122         OF_CPU_VM                               /* flags */
123     },
124     {   OPC_LEA,                                /* opcode */
125         "lea",                                  /* mnemonic */
126         0,                                      /* size */
127         REG_NONE,                               /* use */
128         REG_AX,                                 /* chg */
129         OF_CPU_VM                               /* flags */
130     },
131     {   OPC_JMP,                                /* opcode */
132         "jump",                                 /* mnemonic */
133         0,                                      /* size */
134         REG_NONE,                               /* use */
135         REG_NONE,                               /* chg */
136         OF_CPU_VM | OF_UBRA                     /* flags */
137     },
138
139     /* 65XX opcodes */
140     {   OP65_ADC,                               /* opcode */
141         "adc",                                  /* mnemonic */
142         0,                                      /* size */
143         REG_A,                                  /* use */
144         REG_A,                                  /* chg */
145         OF_NONE                                 /* flags */
146     },
147     {   OP65_AND,                               /* opcode */
148         "and",                                  /* mnemonic */
149         0,                                      /* size */
150         REG_A,                                  /* use */
151         REG_A,                                  /* chg */
152         OF_NONE                                 /* flags */
153     },
154     {   OP65_ASL,                               /* opcode */
155         "asl",                                  /* mnemonic */
156         0,                                      /* size */
157         REG_A,                                  /* use */
158         REG_A,                                  /* chg */
159         OF_NONE                                 /* flags */
160     },
161     {   OP65_BCC,                               /* opcode */
162         "bcc",                                  /* mnemonic */
163         2,                                      /* size */
164         REG_NONE,                               /* use */
165         REG_NONE,                               /* chg */
166         OF_CBRA                                 /* flags */
167     },
168     {   OP65_BCS,                               /* opcode */
169         "bcs",                                  /* mnemonic */
170         2,                                      /* size */
171         REG_NONE,                               /* use */
172         REG_NONE,                               /* chg */
173         OF_CBRA                                 /* flags */
174     },
175     {   OP65_BEQ,                               /* opcode */
176         "beq",                                  /* mnemonic */
177         2,                                      /* size */
178         REG_NONE,                               /* use */
179         REG_NONE,                               /* chg */
180         OF_CBRA | OF_ZBRA | OF_FBRA             /* flags */
181     },
182     {   OP65_BIT,                               /* opcode */
183         "bit",                                  /* mnemonic */
184         0,                                      /* size */
185         REG_A,                                  /* use */
186         REG_NONE,                               /* chg */
187         OF_NONE                                 /* flags */
188     },
189     {   OP65_BMI,                               /* opcode */
190         "bmi",                                  /* mnemonic */
191         2,                                      /* size */
192         REG_NONE,                               /* use */
193         REG_NONE,                               /* chg */
194         OF_CBRA | OF_FBRA                       /* flags */
195     },
196     {   OP65_BNE,                               /* opcode */
197         "bne",                                  /* mnemonic */
198         2,                                      /* size */
199         REG_NONE,                               /* use */
200         REG_NONE,                               /* chg */
201         OF_CBRA | OF_ZBRA | OF_FBRA             /* flags */
202     },
203     {   OP65_BPL,                               /* opcode */
204         "bpl",                                  /* mnemonic */
205         2,                                      /* size */
206         REG_NONE,                               /* use */
207         REG_NONE,                               /* chg */
208         OF_CBRA | OF_FBRA                       /* flags */
209     },
210     {   OP65_BRA,                               /* opcode */
211         "bra",                                  /* mnemonic */
212         2,                                      /* size */
213         REG_NONE,                               /* use */
214         REG_NONE,                               /* chg */
215         OF_UBRA                                 /* flags */
216     },
217     {   OP65_BRK,                               /* opcode */
218         "brk",                                  /* mnemonic */
219         1,                                      /* size */
220         REG_NONE,                               /* use */
221         REG_NONE,                               /* chg */
222         OF_NONE                                 /* flags */
223     },
224     {   OP65_BVC,                               /* opcode */
225         "bvc",                                  /* mnemonic */
226         2,                                      /* size */
227         REG_NONE,                               /* use */
228         REG_NONE,                               /* chg */
229         OF_CBRA                                 /* flags */
230     },
231     {   OP65_BVS,                               /* opcode */
232         "bvs",                                  /* mnemonic */
233         2,                                      /* size */
234         REG_NONE,                               /* use */
235         REG_NONE,                               /* chg */
236         OF_CBRA                                 /* flags */
237     },
238     {   OP65_CLC,                               /* opcode */
239         "clc",                                  /* mnemonic */
240         1,                                      /* size */
241         REG_NONE,                               /* use */
242         REG_NONE,                               /* chg */
243         OF_NONE                                 /* flags */
244     },
245     {   OP65_CLD,                               /* opcode */
246         "cld",                                  /* mnemonic */
247         1,                                      /* size */
248         REG_NONE,                               /* use */
249         REG_NONE,                               /* chg */
250         OF_NONE                                 /* flags */
251     },
252     {   OP65_CLI,                               /* opcode */
253         "cli",                                  /* mnemonic */
254         1,                                      /* size */
255         REG_NONE,                               /* use */
256         REG_NONE,                               /* chg */
257         OF_NONE                                 /* flags */
258     },
259     {   OP65_CLV,                               /* opcode */
260         "clv",                                  /* mnemonic */
261         1,                                      /* size */
262         REG_NONE,                               /* use */
263         REG_NONE,                               /* chg */
264         OF_NONE                                 /* flags */
265     },
266     {   OP65_CMP,                               /* opcode */
267         "cmp",                                  /* mnemonic */
268         0,                                      /* size */
269         REG_A,                                  /* use */
270         REG_NONE,                               /* chg */
271         OF_NONE                                 /* flags */
272     },
273     {   OP65_CPX,                               /* opcode */
274         "cpx",                                  /* mnemonic */
275         0,                                      /* size */
276         REG_X,                                  /* use */
277         REG_NONE,                               /* chg */
278         OF_NONE                                 /* flags */
279     },
280     {   OP65_CPY,                               /* opcode */
281         "cpy",                                  /* mnemonic */
282         0,                                      /* size */
283         REG_Y,                                  /* use */
284         REG_NONE,                               /* chg */
285         OF_NONE                                 /* flags */
286     },
287     {   OP65_DEA,                               /* opcode */
288         "dea",                                  /* mnemonic */
289         1,                                      /* size */
290         REG_A,                                  /* use */
291         REG_A,                                  /* chg */
292         OF_NONE                                 /* flags */
293     },
294     {   OP65_DEC,                               /* opcode */
295         "dec",                                  /* mnemonic */
296         0,                                      /* size */
297         REG_NONE,                               /* use */
298         REG_NONE,                               /* chg */
299         OF_NONE                                 /* flags */
300     },
301     {   OP65_DEX,                               /* opcode */
302         "dex",                                  /* mnemonic */
303         1,                                      /* size */
304         REG_X,                                  /* use */
305         REG_X,                                  /* chg */
306         OF_NONE                                 /* flags */
307     },
308     {   OP65_DEY,                               /* opcode */
309         "dey",                                  /* mnemonic */
310         1,                                      /* size */
311         REG_Y,                                  /* use */
312         REG_Y,                                  /* chg */
313         OF_NONE                                 /* flags */
314     },
315     {   OP65_EOR,                               /* opcode */
316         "eor",                                  /* mnemonic */
317         0,                                      /* size */
318         REG_A,                                  /* use */
319         REG_A,                                  /* chg */
320         OF_NONE                                 /* flags */
321     },
322     {   OP65_INA,                               /* opcode */
323         "ina",                                  /* mnemonic */
324         1,                                      /* size */
325         REG_A,                                  /* use */
326         REG_A,                                  /* chg */
327         OF_NONE                                 /* flags */
328     },
329     {   OP65_INC,                               /* opcode */
330         "inc",                                  /* mnemonic */
331         0,                                      /* size */
332         REG_NONE,                               /* use */
333         REG_NONE,                               /* chg */
334         OF_NONE                                 /* flags */
335     },
336     {   OP65_INX,                               /* opcode */
337         "inx",                                  /* mnemonic */
338         1,                                      /* size */
339         REG_X,                                  /* use */
340         REG_X,                                  /* chg */
341         OF_NONE                                 /* flags */
342     },
343     {   OP65_INY,                               /* opcode */
344         "iny",                                  /* mnemonic */
345         1,                                      /* size */
346         REG_Y,                                  /* use */
347         REG_Y,                                  /* chg */
348         OF_NONE                                 /* flags */
349     },
350     {   OP65_JCC,                               /* opcode */
351         "jcc",                                  /* mnemonic */
352         5,                                      /* size */
353         REG_NONE,                               /* use */
354         REG_NONE,                               /* chg */
355         OF_CBRA | OF_LBRA                       /* flags */
356     },
357     {   OP65_JCS,                               /* opcode */
358         "jcs",                                  /* mnemonic */
359         5,                                      /* size */
360         REG_NONE,                               /* use */
361         REG_NONE,                               /* chg */
362         OF_CBRA | OF_LBRA                       /* flags */
363     },
364     {   OP65_JEQ,                               /* opcode */
365         "jeq",                                  /* mnemonic */
366         5,                                      /* size */
367         REG_NONE,                               /* use */
368         REG_NONE,                               /* chg */
369         OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA   /* flags */
370     },
371     {   OP65_JMI,                               /* opcode */
372         "jmi",                                  /* mnemonic */
373         5,                                      /* size */
374         REG_NONE,                               /* use */
375         REG_NONE,                               /* chg */
376         OF_CBRA | OF_LBRA | OF_FBRA             /* flags */
377     },
378     {   OP65_JMP,                               /* opcode */
379         "jmp",                                  /* mnemonic */
380         3,                                      /* size */
381         REG_NONE,                               /* use */
382         REG_NONE,                               /* chg */
383         OF_UBRA | OF_LBRA                       /* flags */
384     },
385     {   OP65_JNE,                               /* opcode */
386         "jne",                                  /* mnemonic */
387         5,                                      /* size */
388         REG_NONE,                               /* use */
389         REG_NONE,                               /* chg */
390         OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA   /* flags */
391     },
392     {   OP65_JPL,                               /* opcode */
393         "jpl",                                  /* mnemonic */
394         5,                                      /* size */
395         REG_NONE,                               /* use */
396         REG_NONE,                               /* chg */
397         OF_CBRA | OF_LBRA | OF_FBRA             /* flags */
398     },
399     {   OP65_JSR,                               /* opcode */
400         "jsr",                                  /* mnemonic */
401         3,                                      /* size */
402         REG_NONE,                               /* use */
403         REG_NONE,                               /* chg */
404         OF_CALL                                 /* flags */
405     },
406     {   OP65_JVC,                               /* opcode */
407         "jvc",                                  /* mnemonic */
408         5,                                      /* size */
409         REG_NONE,                               /* use */
410         REG_NONE,                               /* chg */
411         OF_CBRA | OF_LBRA                       /* flags */
412     },
413     {   OP65_JVS,                               /* opcode */
414         "jvs",                                  /* mnemonic */
415         5,                                      /* size */
416         REG_NONE,                               /* use */
417         REG_NONE,                               /* chg */
418         OF_CBRA | OF_LBRA                       /* flags */
419     },
420     {   OP65_LDA,                               /* opcode */
421         "lda",                                  /* mnemonic */
422         0,                                      /* size */
423         REG_NONE,                               /* use */
424         REG_A,                                  /* chg */
425         OF_LOAD                                 /* flags */
426     },
427     {   OP65_LDX,                               /* opcode */
428         "ldx",                                  /* mnemonic */
429         0,                                      /* size */
430         REG_NONE,                               /* use */
431         REG_X,                                  /* chg */
432         OF_LOAD                                 /* flags */
433     },
434     {   OP65_LDY,                               /* opcode */
435         "ldy",                                  /* mnemonic */
436         0,                                      /* size */
437         REG_NONE,                               /* use */
438         REG_Y,                                  /* chg */
439         OF_LOAD                                 /* flags */
440     },
441     {   OP65_LSR,                               /* opcode */
442         "lsr",                                  /* mnemonic */
443         0,                                      /* size */
444         REG_A,                                  /* use */
445         REG_A,                                  /* chg */
446         OF_NONE                                 /* flags */
447     },
448     {   OP65_NOP,                               /* opcode */
449         "nop",                                  /* mnemonic */
450         1,                                      /* size */
451         REG_NONE,                               /* use */
452         REG_NONE,                               /* chg */
453         OF_NONE                                 /* flags */
454     },
455     {   OP65_ORA,                               /* opcode */
456         "ora",                                  /* mnemonic */
457         0,                                      /* size */
458         REG_A,                                  /* use */
459         REG_A,                                  /* chg */
460         OF_NONE                                 /* flags */
461     },
462     {   OP65_PHA,                               /* opcode */
463         "pha",                                  /* mnemonic */
464         1,                                      /* size */
465         REG_A,                                  /* use */
466         REG_NONE,                               /* chg */
467         OF_NONE                                 /* flags */
468     },
469     {   OP65_PHP,                               /* opcode */
470         "php",                                  /* mnemonic */
471         1,                                      /* size */
472         REG_NONE,                               /* use */
473         REG_NONE,                               /* chg */
474         OF_NONE                                 /* flags */
475     },
476     {   OP65_PHX,                               /* opcode */
477         "phx",                                  /* mnemonic */
478         1,                                      /* size */
479         REG_X,                                  /* use */
480         REG_NONE,                               /* chg */
481         OF_NONE                                 /* flags */
482     },
483     {   OP65_PHY,                               /* opcode */
484         "phy",                                  /* mnemonic */
485         1,                                      /* size */
486         REG_Y,                                  /* use */
487         REG_NONE,                               /* chg */
488         OF_NONE                                 /* flags */
489     },
490     {   OP65_PLA,                               /* opcode */
491         "pla",                                  /* mnemonic */
492         1,                                      /* size */
493         REG_NONE,                               /* use */
494         REG_A,                                  /* chg */
495         OF_NONE                                 /* flags */
496     },
497     {   OP65_PLP,                               /* opcode */
498         "plp",                                  /* mnemonic */
499         1,                                      /* size */
500         REG_NONE,                               /* use */
501         REG_NONE,                               /* chg */
502         OF_NONE                                 /* flags */
503     },
504     {   OP65_PLX,                               /* opcode */
505         "plx",                                  /* mnemonic */
506         1,                                      /* size */
507         REG_NONE,                               /* use */
508         REG_X,                                  /* chg */
509         OF_NONE                                 /* flags */
510     },
511     {   OP65_PLY,                               /* opcode */
512         "ply",                                  /* mnemonic */
513         1,                                      /* size */
514         REG_NONE,                               /* use */
515         REG_Y,                                  /* chg */
516         OF_NONE                                 /* flags */
517     },
518     {   OP65_ROL,                               /* opcode */
519         "rol",                                  /* mnemonic */
520         0,                                      /* size */
521         REG_A,                                  /* use */
522         REG_A,                                  /* chg */
523         OF_NONE                                 /* flags */
524     },
525     {   OP65_ROR,                               /* opcode */
526         "ror",                                  /* mnemonic */
527         0,                                      /* size */
528         REG_A,                                  /* use */
529         REG_A,                                  /* chg */
530         OF_NONE                                 /* flags */
531     },
532     {   OP65_RTI,                               /* opcode */
533         "rti",                                  /* mnemonic */
534         1,                                      /* size */
535         REG_NONE,                               /* use */
536         REG_NONE,                               /* chg */
537         OF_RET                                  /* flags */
538     },
539     {   OP65_RTS,                               /* opcode */
540         "rts",                                  /* mnemonic */
541         1,                                      /* size */
542         REG_NONE,                               /* use */
543         REG_NONE,                               /* chg */
544         OF_RET                                  /* flags */
545     },
546     {   OP65_SBC,                               /* opcode */
547         "sbc",                                  /* mnemonic */
548         0,                                      /* size */
549         REG_A,                                  /* use */
550         REG_A,                                  /* chg */
551         OF_NONE                                 /* flags */
552     },
553     {   OP65_SEC,                               /* opcode */
554         "sec",                                  /* mnemonic */
555         1,                                      /* size */
556         REG_NONE,                               /* use */
557         REG_NONE,                               /* chg */
558         OF_NONE                                 /* flags */
559     },
560     {   OP65_SED,                               /* opcode */
561         "sed",                                  /* mnemonic */
562         1,                                      /* size */
563         REG_NONE,                               /* use */
564         REG_NONE,                               /* chg */
565         OF_NONE                                 /* flags */
566     },
567     {   OP65_SEI,                               /* opcode */
568         "sei",                                  /* mnemonic */
569         1,                                      /* size */
570         REG_NONE,                               /* use */
571         REG_NONE,                               /* chg */
572         OF_NONE                                 /* flags */
573     },
574     {   OP65_STA,                               /* opcode */
575         "sta",                                  /* mnemonic */
576         0,                                      /* size */
577         REG_A,                                  /* use */
578         REG_NONE,                               /* chg */
579         OF_NONE                                 /* flags */
580     },
581     {   OP65_STX,                               /* opcode */
582         "stx",                                  /* mnemonic */
583         0,                                      /* size */
584         REG_X,                                  /* use */
585         REG_NONE,                               /* chg */
586         OF_NONE                                 /* flags */
587     },
588     {   OP65_STY,                               /* opcode */
589         "sty",                                  /* mnemonic */
590         0,                                      /* size */
591         REG_Y,                                  /* use */
592         REG_NONE,                               /* chg */
593         OF_NONE                                 /* flags */
594     },
595     {   OP65_TAX,                               /* opcode */
596         "tax",                                  /* mnemonic */
597         1,                                      /* size */
598         REG_A,                                  /* use */
599         REG_X,                                  /* chg */
600         OF_XFR                                  /* flags */
601     },
602     {   OP65_TAY,                               /* opcode */
603         "tay",                                  /* mnemonic */
604         1,                                      /* size */
605         REG_A,                                  /* use */
606         REG_Y,                                  /* chg */
607         OF_XFR                                  /* flags */
608     },
609     {   OP65_TRB,                               /* opcode */
610         "trb",                                  /* mnemonic */
611         0,                                      /* size */
612         REG_A,                                  /* use */
613         REG_NONE,                               /* chg */
614         OF_NONE                                 /* flags */
615     },
616     {   OP65_TSB,                               /* opcode */
617         "tsb",                                  /* mnemonic */
618         0,                                      /* size */
619         REG_A,                                  /* use */
620         REG_NONE,                               /* chg */
621         OF_NONE                                 /* flags */
622     },
623     {   OP65_TSX,                               /* opcode */
624         "tsx",                                  /* mnemonic */
625         1,                                      /* size */
626         REG_NONE,                               /* use */
627         REG_X,                                  /* chg */
628         OF_XFR                                  /* flags */
629     },
630     {   OP65_TXA,                               /* opcode */
631         "txa",                                  /* mnemonic */
632         1,                                      /* size */
633         REG_X,                                  /* use */
634         REG_A,                                  /* chg */
635         OF_XFR                                  /* flags */
636     },
637     {   OP65_TXS,                               /* opcode */
638         "txs",                                  /* mnemonic */
639         1,                                      /* size */
640         REG_X,                                  /* use */
641         REG_NONE,                               /* chg */
642         OF_XFR                                  /* flags */
643     },
644     {   OP65_TYA,                               /* opcode */
645         "tya",                                  /* mnemonic */
646         1,                                      /* size */
647         REG_A,                                  /* use */
648         REG_A,                                  /* chg */
649         OF_XFR                                  /* flags */
650     },
651 };
652
653
654
655 /*****************************************************************************/
656 /*                                   Code                                    */
657 /*****************************************************************************/
658
659
660
661 static int FindCmp (const void* Key, const void* Desc)
662 /* Compare function for FindOpcode */
663 {
664     return strcmp (Key, ((OPCDesc*)Desc)->Mnemo);
665 }
666
667
668
669 const OPCDesc* FindOP65 (const char* M)
670 /* Find the given opcode and return the opcode number. If the opcode was not
671  * found, return NULL.
672  */
673 {
674     unsigned I;
675     unsigned Len;
676
677     /* Check the length of the given string, then copy it into local
678      * storage, converting it to upper case.
679      */
680     char Mnemo[sizeof (OPCTable[0].Mnemo)];
681     Len = strlen (M);
682     if (Len >= sizeof (OPCTable[0].Mnemo)) {
683         /* Invalid length means invalid opcode */
684         return 0;
685     }
686     for (I = 0; I < Len; ++I) {
687         Mnemo[I] = tolower (M[I]);
688     }
689     Mnemo[I] = '\0';
690
691     /* Search for the mnemonic in the table and return the result */
692     return bsearch (Mnemo, OPCTable+OP65_FIRST, OP65_COUNT,
693                     sizeof (OPCTable[0]), FindCmp );
694 }
695
696
697
698 unsigned GetInsnSize (opc_t OPC, am_t AM)
699 /* Return the size of the given instruction */
700 {
701     /* Get the opcode desc and check the size given there */
702     const OPCDesc* D = &OPCTable[OPC];
703     if (D->Size != 0) {
704         return D->Size;
705     }
706
707     /* Check the addressing mode. */
708     switch (AM) {
709         case AM65_IMP:     return 1;
710         case AM65_ACC:     return 1;
711         case AM65_IMM:     return 2;
712         case AM65_ZP:      return 2;
713         case AM65_ZPX:     return 2;
714         case AM65_ABS:     return 3;
715         case AM65_ABSX:    return 3;
716         case AM65_ABSY:    return 3;
717         case AM65_ZPX_IND: return 2;
718         case AM65_ZP_INDY: return 2;
719         case AM65_ZP_IND:  return 2;
720         default:
721             Internal ("Invalid addressing mode");
722             return 0;
723     }
724 }
725
726
727
728 unsigned char GetAMUseInfo (am_t AM)
729 /* Get usage info for the given addressing mode (addressing modes that use
730  * index registers return REG_r info for these registers).
731  */
732 {
733     /* Check the addressing mode. */
734     switch (AM) {
735         case AM65_ACC:     return REG_A;
736         case AM65_ZPX:     return REG_X;
737         case AM65_ABSX:    return REG_X;
738         case AM65_ABSY:    return REG_Y;
739         case AM65_ZPX_IND: return REG_X;
740         case AM65_ZP_INDY: return REG_Y;
741         default:           return REG_NONE;
742     }
743 }
744
745
746
747 opc_t GetInverseBranch (opc_t OPC)
748 /* Return a branch that reverse the condition of the branch given in OPC */
749 {
750     switch (OPC) {
751         case OP65_BCC:  return OP65_BCS;
752         case OP65_BCS:  return OP65_BCC;
753         case OP65_BEQ:  return OP65_BNE;
754         case OP65_BMI:  return OP65_BPL;
755         case OP65_BNE:  return OP65_BEQ;
756         case OP65_BPL:  return OP65_BMI;
757         case OP65_BVC:          return OP65_BVS;
758         case OP65_BVS:  return OP65_BVC;
759         case OP65_JCC:          return OP65_JCS;
760         case OP65_JCS:          return OP65_JCC;
761         case OP65_JEQ:          return OP65_JNE;
762         case OP65_JMI:          return OP65_JPL;
763         case OP65_JNE:          return OP65_JEQ;
764         case OP65_JPL:          return OP65_JMI;
765         case OP65_JVC:          return OP65_JVS;
766         case OP65_JVS:          return OP65_JVC;
767         default:
768             Internal ("GetInverseBranch: Invalid opcode: %d", OPC);
769             return 0;
770     }
771 }
772
773
774
775 opc_t MakeShortBranch (opc_t OPC)
776 /* Return the short version of the given branch. If the branch is already
777  * a short branch, return the opcode unchanged.
778  */
779 {
780     switch (OPC) {
781         case OP65_BCC:
782         case OP65_JCC:          return OP65_BCC;
783         case OP65_BCS:
784         case OP65_JCS:          return OP65_BCS;
785         case OP65_BEQ:
786         case OP65_JEQ:          return OP65_BEQ;
787         case OP65_BMI:
788         case OP65_JMI:          return OP65_BMI;
789         case OP65_BNE:
790         case OP65_JNE:          return OP65_BNE;
791         case OP65_BPL:
792         case OP65_JPL:          return OP65_BPL;
793         case OP65_BVC:
794         case OP65_JVC:          return OP65_BVC;
795         case OP65_BVS:
796         case OP65_JVS:          return OP65_BVS;
797         case OP65_BRA:
798         case OP65_JMP:  return (CPU == CPU_65C02)? OP65_BRA : OP65_JMP;
799         default:
800             Internal ("MakeShortBranch: Invalid opcode: %d", OPC);
801             return 0;
802     }
803 }
804
805
806
807 opc_t MakeLongBranch (opc_t OPC)
808 /* Return the long version of the given branch. If the branch is already
809  * a long branch, return the opcode unchanged.
810  */
811 {
812     switch (OPC) {
813         case OP65_BCC:
814         case OP65_JCC:          return OP65_JCC;
815         case OP65_BCS:
816         case OP65_JCS:          return OP65_JCS;
817         case OP65_BEQ:
818         case OP65_JEQ:          return OP65_JEQ;
819         case OP65_BMI:
820         case OP65_JMI:          return OP65_JMI;
821         case OP65_BNE:
822         case OP65_JNE:          return OP65_JNE;
823         case OP65_BPL:
824         case OP65_JPL:          return OP65_JPL;
825         case OP65_BVC:
826         case OP65_JVC:          return OP65_JVC;
827         case OP65_BVS:
828         case OP65_JVS:          return OP65_JVS;
829         case OP65_BRA:
830         case OP65_JMP:  return OP65_JMP;
831         default:
832             Internal ("MakeLongBranch: Invalid opcode: %d", OPC);
833             return 0;
834     }
835 }
836
837
838
839 bc_t GetBranchCond (opc_t OPC)
840 /* Get the condition for the conditional branch in OPC */
841 {
842     switch (OPC) {
843         case OP65_BCC:          return BC_CC;
844         case OP65_BCS:          return BC_CS;
845         case OP65_BEQ:          return BC_EQ;
846         case OP65_BMI:          return BC_MI;
847         case OP65_BNE:          return BC_NE;
848         case OP65_BPL:          return BC_PL;
849         case OP65_BVC:          return BC_VC;
850         case OP65_BVS:          return BC_VS;
851         case OP65_JCC:          return BC_CC;
852         case OP65_JCS:          return BC_CS;
853         case OP65_JEQ:          return BC_EQ;
854         case OP65_JMI:          return BC_MI;
855         case OP65_JNE:          return BC_NE;
856         case OP65_JPL:          return BC_PL;
857         case OP65_JVC:          return BC_VC;
858         case OP65_JVS:          return BC_VS;
859         default:
860             Internal ("GetBranchCond: Invalid opcode: %d", OPC);
861             return 0;
862     }
863 }
864
865
866
867 bc_t GetInverseCond (bc_t BC)
868 /* Return the inverse condition of the given one */
869 {
870     switch (BC) {
871         case BC_CC:     return BC_CS;
872         case BC_CS:     return BC_CC;
873         case BC_EQ:     return BC_NE;
874         case BC_MI:     return BC_PL;
875         case BC_NE:     return BC_EQ;
876         case BC_PL:     return BC_MI;
877         case BC_VC:     return BC_VS;
878         case BC_VS:     return BC_VC;
879         default:
880             Internal ("GetInverseCond: Invalid condition: %d", BC);
881             return 0;
882     }
883 }
884
885
886