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