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