Copyright updates for 2007.
[external/binutils.git] / sim / m68hc11 / gencode.c
1 /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
2    Copyright 1999, 2000, 2001, 2002, 2007 Free Software Foundation, Inc.
3    Written by Stephane Carrez (stcarrez@nerim.fr)
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
7 GDB, GAS, and the GNU binutils are free software; you can redistribute
8 them and/or modify them under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either version
10 2, or (at your option) any later version.
11
12 GDB, GAS, and the GNU binutils are distributed in the hope that they
13 will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15 the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <errno.h>
25
26 #include "ansidecl.h"
27 #include "opcode/m68hc11.h"
28
29 #define TABLE_SIZE(X)       (sizeof(X) / sizeof(X[0]))
30
31 /* Combination of CCR flags.  */
32 #define M6811_ZC_BIT    M6811_Z_BIT|M6811_C_BIT
33 #define M6811_NZ_BIT    M6811_N_BIT|M6811_Z_BIT
34 #define M6811_NZV_BIT   M6811_N_BIT|M6811_Z_BIT|M6811_V_BIT
35 #define M6811_NZC_BIT   M6811_N_BIT|M6811_Z_BIT|M6811_C_BIT
36 #define M6811_NVC_BIT   M6811_N_BIT|M6811_V_BIT|M6811_C_BIT
37 #define M6811_ZVC_BIT   M6811_Z_BIT|M6811_V_BIT|M6811_C_BIT
38 #define M6811_NZVC_BIT  M6811_ZVC_BIT|M6811_N_BIT
39 #define M6811_HNZVC_BIT M6811_NZVC_BIT|M6811_H_BIT
40 #define M6811_HNVC_BIT  M6811_NVC_BIT|M6811_H_BIT
41 #define M6811_VC_BIT    M6811_V_BIT|M6811_C_BIT
42
43 /* Flags when the insn only changes some CCR flags.  */
44 #define CHG_NONE        0,0,0
45 #define CHG_Z           0,0,M6811_Z_BIT
46 #define CHG_C           0,0,M6811_C_BIT
47 #define CHG_ZVC         0,0,M6811_ZVC_BIT
48 #define CHG_NZC         0,0,M6811_NZC_BIT
49 #define CHG_NZV         0,0,M6811_NZV_BIT
50 #define CHG_NZVC        0,0,M6811_NZVC_BIT
51 #define CHG_HNZVC       0,0,M6811_HNZVC_BIT
52 #define CHG_ALL         0,0,0xff
53
54 /* The insn clears and changes some flags.  */
55 #define CLR_I           0,M6811_I_BIT,0
56 #define CLR_C           0,M6811_C_BIT,0
57 #define CLR_V           0,M6811_V_BIT,0
58 #define CLR_V_CHG_ZC    0,M6811_V_BIT,M6811_ZC_BIT
59 #define CLR_V_CHG_NZ    0,M6811_V_BIT,M6811_NZ_BIT
60 #define CLR_V_CHG_ZVC   0,M6811_V_BIT,M6811_ZVC_BIT
61 #define CLR_N_CHG_ZVC   0,M6811_N_BIT,M6811_ZVC_BIT /* Used by lsr */
62 #define CLR_VC_CHG_NZ   0,M6811_VC_BIT,M6811_NZ_BIT
63
64 /* The insn sets some flags.  */
65 #define SET_I           M6811_I_BIT,0,0
66 #define SET_C           M6811_C_BIT,0,0
67 #define SET_V           M6811_V_BIT,0,0
68 #define SET_Z_CLR_NVC   M6811_Z_BIT,M6811_NVC_BIT,0
69 #define SET_C_CLR_V_CHG_NZ M6811_C_BIT,M6811_V_BIT,M6811_NZ_BIT
70 #define SET_Z_CHG_HNVC  M6811_Z_BIT,0,M6811_HNVC_BIT
71
72 #define _M 0xff
73
74 static int cpu_type;
75
76 struct m6811_opcode_pattern 
77 {
78   const char *name;
79   const char *pattern;
80   const char *ccr_update;
81 };
82
83 /*
84  *  { "test", M6811_OP_NONE, 1, 0x00, 5, _M,  CHG_NONE },
85  * Name -+                                       +---- Insn CCR changes
86  * Format  ------+                         +---------- Max # cycles
87  * Size     -----------------+        +--------------- Min # cycles
88  *                               +-------------------- Opcode
89  */
90 struct m6811_opcode_pattern m6811_opcode_patterns[] = {
91   /* Move 8 and 16 bits.  We need two implementations: one that sets the
92      flags and one that preserve them.  */
93   { "movtst8",  "dst8 = src8",   "cpu_ccr_update_tst8 (proc, dst8)" },
94   { "movtst16", "dst16 = src16", "cpu_ccr_update_tst16 (proc, dst16)" },
95   { "mov8",     "dst8 = src8" },
96   { "mov16",    "dst16 = src16" },
97   { "lea16",    "dst16 = addr" },
98
99   /* Conditional branches.  'addr' is the address of the branch.  */
100   { "bra", "cpu_set_pc (proc, addr)" },
101   { "bhi",
102    "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)) == 0)\n@ \
103      cpu_set_pc (proc, addr)" },
104   { "bls",
105     "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)))\n@ \
106      cpu_set_pc (proc, addr)" },
107   { "bcc", "if (!cpu_get_ccr_C (proc))\n@ cpu_set_pc (proc, addr)" },
108   { "bcs", "if (cpu_get_ccr_C (proc))\n@ cpu_set_pc (proc, addr)" },
109   { "bne", "if (!cpu_get_ccr_Z (proc))\n@ cpu_set_pc (proc, addr)" },
110   { "beq", "if (cpu_get_ccr_Z (proc))\n@ cpu_set_pc (proc, addr)" },
111   { "bvc", "if (!cpu_get_ccr_V (proc))\n@ cpu_set_pc (proc, addr)" },
112   { "bvs", "if (cpu_get_ccr_V (proc))\n@ cpu_set_pc (proc, addr)" },
113   { "bpl", "if (!cpu_get_ccr_N (proc))\n@ cpu_set_pc (proc, addr)" },
114   { "bmi", "if (cpu_get_ccr_N (proc))\n@ cpu_set_pc (proc, addr)" },
115   { "bge", "if ((cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc)) == 0)\n@ cpu_set_pc (proc, addr)" },
116   { "blt", "if ((cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc)))\n@ cpu_set_pc (proc, addr)" },
117   { "bgt",
118     "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))) == 0)\n@ \
119      cpu_set_pc (proc, addr)" },
120   { "ble",
121     "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))))\n@ \
122      cpu_set_pc (proc, addr)" },
123
124   /* brclr and brset perform a test and a conditional jump at the same
125      time.  Flags are not changed.  */
126   { "brclr8",
127     "if ((src8 & dst8) == 0)\n@  cpu_set_pc (proc, addr)" },
128   { "brset8",
129     "if (((~src8) & dst8) == 0)\n@  cpu_set_pc (proc, addr)" },
130   
131
132   { "rts11",  "addr = cpu_m68hc11_pop_uint16 (proc); cpu_set_pc (proc, addr); cpu_return(proc)" },
133   { "rts12",  "addr = cpu_m68hc12_pop_uint16 (proc); cpu_set_pc (proc, addr); cpu_return(proc)" },
134
135   { "mul16", "dst16 = ((uint16) src8 & 0x0FF) * ((uint16) dst8 & 0x0FF)",
136     "cpu_set_ccr_C (proc, src8 & 0x80)" },
137   { "neg8", "dst8 = - src8",
138     "cpu_set_ccr_C (proc, src8 == 0); cpu_ccr_update_tst8 (proc, dst8)" },
139   { "com8", "dst8 = ~src8",
140     "cpu_set_ccr_C (proc, 1); cpu_ccr_update_tst8 (proc, dst8);" },
141   { "clr8", "dst8 = 0",
142     "cpu_set_ccr (proc, (cpu_get_ccr (proc) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
143 M6811_I_BIT)) | M6811_Z_BIT)"},
144   { "clr16","dst16 = 0",
145     "cpu_set_ccr (proc, (cpu_get_ccr (proc) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
146 M6811_I_BIR)) | M6811_Z_BIT)"},
147
148   /* 8-bits shift and rotation.  */
149   { "lsr8",  "dst8 = src8 >> 1",
150     "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
151   { "lsl8",  "dst8 = src8 << 1",
152     "cpu_set_ccr_C (proc, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (proc, dst8)" },
153   { "asr8",  "dst8 = (src8 >> 1) | (src8 & 0x80)",
154     "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
155   { "ror8",  "dst8 = (src8 >> 1) | (cpu_get_ccr_C (proc) << 7)",
156     "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
157   { "rol8",  "dst8 = (src8 << 1) | (cpu_get_ccr_C (proc))",
158     "cpu_set_ccr_C (proc, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (proc, dst8)" },
159
160   /* 16-bits shift instructions.  */
161   { "lsl16",  "dst16 = src16 << 1",
162     "cpu_set_ccr_C (proc, (src16&0x8000) >> 15); cpu_ccr_update_shift16 (proc, dst16)"},
163   { "lsr16",  "dst16 = src16 >> 1",
164     "cpu_set_ccr_C (proc, src16 & 1); cpu_ccr_update_shift16 (proc, dst16)"},
165
166   { "dec8", "dst8 = src8 - 1", "cpu_ccr_update_tst8 (proc, dst8)" },
167   { "inc8", "dst8 = src8 + 1", "cpu_ccr_update_tst8 (proc, dst8)" },
168   { "tst8", 0, "cpu_set_ccr_C (proc, 0); cpu_ccr_update_tst8 (proc, src8)" },
169
170   { "sub8", "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
171 dst8 = dst8 - src8", 0 },
172   { "add8", "cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\
173 dst8 = dst8 + src8", 0 },
174   { "sbc8", "if (cpu_get_ccr_C (proc))\n@ \
175 {\n\
176   cpu_ccr_update_sub8 (proc, dst8 - src8 - 1, dst8, src8);\n\
177   dst8 = dst8 - src8 - 1;\n\
178 }\n\
179 else\n\
180 {\n\
181   cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\n\
182   dst8 = dst8 - src8;\n\
183 }", 0 },
184   { "adc8", "if (cpu_get_ccr_C (proc))\n@ \
185 {\n\
186   cpu_ccr_update_add8 (proc, dst8 + src8 + 1, dst8, src8);\n\
187   dst8 = dst8 + src8 + 1;\n\
188 }\n\
189 else\n\
190 {\n\
191   cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\n\
192   dst8 = dst8 + src8;\n\
193 }",
194     0 },
195
196   /* 8-bits logical operations.  */
197   { "and8", "dst8 = dst8 & src8", "cpu_ccr_update_tst8 (proc, dst8)" },
198   { "eor8", "dst8 = dst8 ^ src8", "cpu_ccr_update_tst8 (proc, dst8)" },
199   { "or8",  "dst8 = dst8 | src8", "cpu_ccr_update_tst8 (proc, dst8)" },
200   { "bclr8","dst8 = (~dst8) & src8", "cpu_ccr_update_tst8 (proc, dst8)" },
201
202   /* 16-bits add and subtract instructions.  */
203   { "sub16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
204 dst16 = dst16 - src16", 0 },
205   { "add16", "cpu_ccr_update_add16 (proc, dst16 + src16, dst16, src16);\
206 dst16 = dst16 + src16", 0 },
207   { "inc16", "dst16 = src16 + 1", "cpu_set_ccr_Z (proc, dst16 == 0)" },
208   { "dec16", "dst16 = src16 - 1", "cpu_set_ccr_Z (proc, dst16 == 0)" },
209
210   /* Special increment/decrement for the stack pointer:
211      flags are not changed.  */
212   { "ins16", "dst16 = src16 + 1" },
213   { "des16", "dst16 = src16 - 1" },
214   
215   { "jsr_11_16", "cpu_m68hc11_push_uint16 (proc, cpu_get_pc (proc)); cpu_call (proc, addr)"},
216   { "jsr_12_16", "cpu_m68hc12_push_uint16 (proc, cpu_get_pc (proc)); cpu_call (proc, addr)"},
217
218   /* xgdx and xgdx patterns. Flags are not changed.  */
219   { "xgdxy16", "dst16 = cpu_get_d (proc); cpu_set_d (proc, src16)"},
220   { "stop", "cpu_special (proc, M6811_STOP)"},
221
222   /* tsx, tsy, txs, tys don't affect the flags.  Sp value is corrected
223      by +/- 1.  */
224   { "tsxy16", "dst16 = src16 + 1;"},
225   { "txys16", "dst16 = src16 - 1;"},
226
227   /* Add b to X or Y with an unsigned extension 8->16.  Flags not changed.  */
228   { "abxy16","dst16 = dst16 + (uint16) src8"},
229
230   /* After 'daa', the Z flag is undefined. Mark it as changed.  */
231   { "daa8",  "cpu_special (proc, M6811_DAA)" },
232   { "nop",  0 },
233
234
235   /* Integer divide:
236      (parallel (set IX (div D IX))
237                (set D  (mod D IX)))  */
238   { "idiv16", "if (src16 == 0)\n{\n\
239 dst16 = 0xffff;\
240 }\nelse\n{\n\
241 cpu_set_d (proc, dst16 % src16);\
242 dst16 = dst16 / src16;\
243 }",
244   "cpu_set_ccr_Z (proc, dst16 == 0); cpu_set_ccr_V (proc, 0);\
245 cpu_set_ccr_C (proc, src16 == 0)" },
246
247   /* Fractional divide:
248      (parallel (set IX (div (mul D 65536) IX)
249                (set D  (mod (mul D 65536) IX))))  */
250   { "fdiv16", "if (src16 <= dst16 )\n{\n\
251 dst16 = 0xffff;\n\
252 cpu_set_ccr_Z (proc, 0);\n\
253 cpu_set_ccr_V (proc, 1);\n\
254 cpu_set_ccr_C (proc, dst16 == 0);\n\
255 }\nelse\n{\n\
256 unsigned long l = (unsigned long) (dst16) << 16;\n\
257 cpu_set_d (proc, (uint16) (l % (unsigned long) (src16)));\n\
258 dst16 = (uint16) (l / (unsigned long) (src16));\n\
259 cpu_set_ccr_V (proc, 0);\n\
260 cpu_set_ccr_C (proc, 0);\n\
261 cpu_set_ccr_Z (proc, dst16 == 0);\n\
262 }", 0 },
263
264   /* Operations to get/set the CCR.  */
265   { "clv",  0, "cpu_set_ccr_V (proc, 0)" },
266   { "sev",  0, "cpu_set_ccr_V (proc, 1)" },
267   { "clc",  0, "cpu_set_ccr_C (proc, 0)" },
268   { "sec",  0, "cpu_set_ccr_C (proc, 1)" },
269   { "cli",  0, "cpu_set_ccr_I (proc, 0)" },
270   { "sei",  0, "cpu_set_ccr_I (proc, 1)" },
271
272   /* Some special instructions are implemented by 'cpu_special'.  */
273   { "rti11",  "cpu_special (proc, M6811_RTI)" },
274   { "rti12",  "cpu_special (proc, M6812_RTI)" },
275   { "wai",  "cpu_special (proc, M6811_WAI)" },
276   { "test", "cpu_special (proc, M6811_TEST)" },
277   { "swi",  "cpu_special (proc, M6811_SWI)" },
278   { "syscall","cpu_special (proc, M6811_EMUL_SYSCALL)" },
279
280   { "page2", "cpu_page2_interp (proc)", 0 },
281   { "page3", "cpu_page3_interp (proc)", 0 },
282   { "page4", "cpu_page4_interp (proc)", 0 },
283
284   /* 68HC12 special instructions.  */
285   { "bgnd",  "cpu_special (proc, M6812_BGND)" },
286   { "call8", "cpu_special (proc, M6812_CALL)" },
287   { "call_ind", "cpu_special (proc, M6812_CALL_INDIRECT)" },
288   { "dbcc8", "cpu_dbcc (proc)" },
289   { "ediv",  "cpu_special (proc, M6812_EDIV)" },
290   { "emul",  "{ uint32 src1 = (uint32) cpu_get_d (proc);\
291   uint32 src2 = (uint32) cpu_get_y (proc);\
292   src1 *= src2;\
293   cpu_set_d (proc, src1);\
294   cpu_set_y (proc, src1 >> 16);\
295   cpu_set_ccr_Z (proc, src1 == 0);\
296   cpu_set_ccr_C (proc, src1 & 0x08000);\
297   cpu_set_ccr_N (proc, src1 & 0x80000000);}" },
298   { "emuls",  "cpu_special (proc, M6812_EMULS)" },
299   { "mem",   "cpu_special (proc, M6812_MEM)" },
300   { "rtc",   "cpu_special (proc, M6812_RTC)" },
301   { "emacs", "cpu_special (proc, M6812_EMACS)" },
302   { "idivs", "cpu_special (proc, M6812_IDIVS)" },
303   { "edivs", "cpu_special (proc, M6812_EDIVS)" },
304   { "exg8",  "cpu_exg (proc, src8)" },
305   { "move8", "cpu_move8 (proc, op)" },
306   { "move16","cpu_move16 (proc, op)" },
307
308   { "max8",  "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
309               if (dst8 < src8) dst8 = src8" },
310   { "min8",  "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
311               if (dst8 > src8) dst8 = src8" },
312   { "max16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
313               if (dst16 < src16) dst16 = src16" },
314   { "min16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
315               if (dst16 > src16) dst16 = src16" },
316
317   { "rev",   "cpu_special (proc, M6812_REV);" },
318   { "revw",  "cpu_special (proc, M6812_REVW);" },
319   { "wav",   "cpu_special (proc, M6812_WAV);" },
320   { "tbl8",  "cpu_special (proc, M6812_ETBL);" },
321   { "tbl16", "cpu_special (proc, M6812_ETBL);" }
322 };
323
324 /* Definition of an opcode of the 68HC11.  */
325 struct m6811_opcode_def
326 {
327   const char     *name;
328   const char     *operands;
329   const char     *insn_pattern;
330   unsigned char  insn_size;
331   unsigned char  insn_code;
332   unsigned char  insn_min_cycles;
333   unsigned char  insn_max_cycles;
334   unsigned char  set_flags_mask;
335   unsigned char  clr_flags_mask;
336   unsigned char  chg_flags_mask;
337 };
338
339
340 /*
341  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
342  * Name -+                                       +----- Insn CCR changes
343  * Operands  ---+                         +------------ Max # cycles
344  * Pattern   -----------+              +--------------- Min # cycles
345  * Size      -----------------+   +-------------------- Opcode
346  *
347  * Operands   Fetch operand             Save result
348  * -------    --------------            ------------
349  * x->x       src16 = x                 x = dst16
350  * d->d       src16 = d                 d = dst16
351  * b,a->a     src8 = b dst8 = a         a = dst8
352  * sp->x      src16 = sp                x = dst16
353  * (sp)->a    src8 = pop8               a = dst8
354  * a->(sp)    src8 = a                  push8 dst8
355  * (x)->(x)   src8 = (IND, X)           (IND, X) = dst8
356  * (y)->a     src8 = (IND, Y)           a = dst8
357  * ()->b      src8 = (EXT)              b = dst8
358  */
359 struct m6811_opcode_def m6811_page1_opcodes[] = {
360   { "test", 0,          0,           1, 0x00,  5, _M,  CHG_NONE },
361   { "nop",  0,          0,           1, 0x01,  2,  2,  CHG_NONE },
362   { "idiv", "x,d->x",   "idiv16",    1, 0x02,  3, 41,  CLR_V_CHG_ZC},
363   { "fdiv", "x,d->x",   "fdiv16",    1, 0x03,  3, 41,  CHG_ZVC},
364   { "lsrd", "d->d",     "lsr16",     1, 0x04,  3,  3,  CLR_N_CHG_ZVC },
365   { "asld", "d->d",     "lsl16",     1, 0x05,  3,  3,  CHG_NZVC },
366   { "tap",  "a->ccr",   "mov8",      1, 0x06,  2,  2,  CHG_ALL},
367   { "tpa",  "ccr->a",   "mov8",      1, 0x07,  2,  2,  CHG_NONE },
368   { "inx",  "x->x",     "inc16",     1, 0x08,  3,  3,  CHG_Z },
369   { "dex",  "x->x",     "dec16",     1, 0x09,  3,  3,  CHG_Z },
370   { "clv",  0,          0,           1, 0x0a,  2,  2,  CLR_V },
371   { "sev",  0,          0,           1, 0x0b,  2,  2,  SET_V },
372   { "clc",  0,          0,           1, 0x0c,  2,  2,  CLR_C },
373   { "sec",  0,          0,           1, 0x0d,  2,  2,  SET_C },
374   { "cli",  0,          0,           1, 0x0e,  2,  2,  CLR_I },
375   { "sei",  0,          0,           1, 0x0f,  2,  2,  SET_I },
376   { "sba",  "b,a->a",   "sub8",      1, 0x10,  2,  2,  CHG_NZVC },
377   { "cba",  "b,a",      "sub8",      1, 0x11,  2,  2,  CHG_NZVC },
378   { "brset","*,#,r",    "brset8",    4, 0x12,  6,  6, CHG_NONE },
379   { "brclr","*,#,r",    "brclr8",    4, 0x13,  6,  6, CHG_NONE },
380   { "bset", "*,#->*",   "or8",       3, 0x14,  6,  6, CLR_V_CHG_NZ },
381   { "bclr", "*,#->*",   "bclr8",     3, 0x15,  6,  6, CLR_V_CHG_NZ },
382   { "tab",  "a->b",     "movtst8",   1, 0x16,  2,  2, CLR_V_CHG_NZ },
383   { "tba",  "b->a",     "movtst8",   1, 0x17,  2,  2, CLR_V_CHG_NZ },
384   { "page2", 0,         "page2",     1, 0x18,  0,  0, CHG_NONE },
385   { "page3", 0,         "page3",     1, 0x1a,  0,  0, CHG_NONE },
386
387   /* After 'daa', the Z flag is undefined.  Mark it as changed.  */
388   { "daa",  "",         "daa8",      1, 0x19,  2,  2, CHG_NZVC },
389   { "aba",  "b,a->a",   "add8",      1, 0x1b,  2,  2, CHG_HNZVC},
390   { "bset", "(x),#->(x)","or8",      3, 0x1c,  7,  7, CLR_V_CHG_NZ },
391   { "bclr", "(x),#->(x)","bclr8",    3, 0x1d,  7,  7, CLR_V_CHG_NZ },
392   { "brset","(x),#,r",  "brset8",    4, 0x1e,  7,  7, CHG_NONE },
393   { "brclr","(x),#,r",  "brclr8",    4, 0x1f,  7,  7, CHG_NONE },
394
395   /* Relative branch.  All of them take 3 bytes.  Flags not changed.  */
396   { "bra",  "r",        0,           2, 0x20,  3,  3, CHG_NONE },
397   { "brn",  "r",        "nop",       2, 0x21,  3,  3, CHG_NONE },
398   { "bhi",  "r",        0,           2, 0x22,  3,  3, CHG_NONE },
399   { "bls",  "r",        0,           2, 0x23,  3,  3, CHG_NONE },
400   { "bcc",  "r",        0,           2, 0x24,  3,  3, CHG_NONE },
401   { "bcs",  "r",        0,           2, 0x25,  3,  3, CHG_NONE },
402   { "bne",  "r",        0,           2, 0x26,  3,  3, CHG_NONE },
403   { "beq",  "r",        0,           2, 0x27,  3,  3, CHG_NONE },
404   { "bvc",  "r",        0,           2, 0x28,  3,  3, CHG_NONE },
405   { "bvs",  "r",        0,           2, 0x29,  3,  3, CHG_NONE },
406   { "bpl",  "r",        0,           2, 0x2a,  3,  3, CHG_NONE },
407   { "bmi",  "r",        0,           2, 0x2b,  3,  3, CHG_NONE },
408   { "bge",  "r",        0,           2, 0x2c,  3,  3, CHG_NONE },
409   { "blt",  "r",        0,           2, 0x2d,  3,  3, CHG_NONE },
410   { "bgt",  "r",        0,           2, 0x2e,  3,  3, CHG_NONE },
411   { "ble",  "r",        0,           2, 0x2f,  3,  3, CHG_NONE },
412
413   { "tsx",  "sp->x",    "tsxy16",    1, 0x30,  3,  3, CHG_NONE },
414   { "ins",  "sp->sp",   "ins16",     1, 0x31,  3,  3, CHG_NONE },
415   { "pula", "(sp)->a",  "mov8",      1, 0x32,  4,  4, CHG_NONE },
416   { "pulb", "(sp)->b",  "mov8",      1, 0x33,  4,  4, CHG_NONE },
417   { "des",  "sp->sp",   "des16",     1, 0x34,  3,  3, CHG_NONE },
418   { "txs",  "x->sp",    "txys16",    1, 0x35,  3,  3, CHG_NONE },
419   { "psha", "a->(sp)",  "mov8",      1, 0x36,  3,  3, CHG_NONE },
420   { "pshb", "b->(sp)",  "mov8",      1, 0x37,  3,  3, CHG_NONE },
421   { "pulx", "(sp)->x",  "mov16",     1, 0x38,  5,  5, CHG_NONE },
422   { "rts",  0,          "rts11",     1, 0x39,  5,  5, CHG_NONE },
423   { "abx",  "b,x->x",   "abxy16",    1, 0x3a,  3,  3, CHG_NONE },
424   { "rti",  0,          "rti11",     1, 0x3b, 12, 12, CHG_ALL},
425   { "pshx", "x->(sp)",  "mov16",     1, 0x3c,  4,  4, CHG_NONE },
426   { "mul",  "b,a->d",   "mul16",     1, 0x3d,  3, 10, CHG_C },
427   { "wai",  0,          0,           1, 0x3e, 14, _M, CHG_NONE },
428   { "swi",  0,          0,           1, 0x3f, 14, _M, CHG_NONE },
429   { "nega", "a->a",     "neg8",      1, 0x40,  2,  2, CHG_NZVC },
430   { "syscall", "",      "syscall",   1, 0x41,  2,  2, CHG_NONE },
431   { "coma", "a->a",     "com8",      1, 0x43,  2,  2, SET_C_CLR_V_CHG_NZ },
432   { "lsra", "a->a",     "lsr8",      1, 0x44,  2,  2, CLR_N_CHG_ZVC},
433   { "rora", "a->a",     "ror8",      1, 0x46,  2,  2, CHG_NZVC },
434   { "asra", "a->a",     "asr8",      1, 0x47,  2,  2, CHG_NZVC },
435   { "asla", "a->a",     "lsl8",      1, 0x48,  2,  2, CHG_NZVC },
436   { "rola", "a->a",     "rol8",      1, 0x49,  2,  2, CHG_NZVC },
437   { "deca", "a->a",     "dec8",      1, 0x4a,  2,  2, CHG_NZV },
438   { "inca", "a->a",     "inc8",      1, 0x4c,  2,  2, CHG_NZV },
439   { "tsta", "a",        "tst8",      1, 0x4d,  2,  2, CLR_V_CHG_NZ },
440   { "clra", "->a",      "clr8",      1, 0x4f,  2,  2, SET_Z_CLR_NVC },
441   { "negb", "b->b",     "neg8",      1, 0x50,  2,  2, CHG_NZVC },
442   { "comb", "b->b",     "com8",      1, 0x53,  2,  2, SET_C_CLR_V_CHG_NZ },
443   { "lsrb", "b->b",     "lsr8",      1, 0x54,  2,  2, CLR_N_CHG_ZVC },
444   { "rorb", "b->b",     "ror8",      1, 0x56,  2,  2, CHG_NZVC },
445   { "asrb", "b->b",     "asr8",      1, 0x57,  2,  2, CHG_NZVC },
446   { "aslb", "b->b",     "lsl8",      1, 0x58,  2,  2, CHG_NZVC },
447   { "rolb", "b->b",     "rol8",      1, 0x59,  2,  2, CHG_NZVC },
448   { "decb", "b->b",     "dec8",      1, 0x5a,  2,  2, CHG_NZV },
449   { "incb", "b->b",     "inc8",      1, 0x5c,  2,  2, CHG_NZV },
450   { "tstb", "b",        "tst8",      1, 0x5d,  2,  2, CLR_V_CHG_NZ },
451   { "clrb", "->b",      "clr8",      1, 0x5f,  2,  2, SET_Z_CLR_NVC },
452   { "neg",  "(x)->(x)", "neg8",      2, 0x60,  6,  6, CHG_NZVC },
453   { "com",  "(x)->(x)", "com8",      2, 0x63,  6,  6, SET_C_CLR_V_CHG_NZ },
454   { "lsr",  "(x)->(x)", "lsr8",      2, 0x64,  6,  6, CLR_N_CHG_ZVC },
455   { "ror",  "(x)->(x)", "ror8",      2, 0x66,  6,  6, CHG_NZVC },
456   { "asr",  "(x)->(x)", "asr8",      2, 0x67,  6,  6, CHG_NZVC },
457   { "asl",  "(x)->(x)", "lsl8",      2, 0x68,  6,  6, CHG_NZVC },
458   { "rol",  "(x)->(x)", "rol8",      2, 0x69,  6,  6, CHG_NZVC },
459   { "dec",  "(x)->(x)", "dec8",      2, 0x6a,  6,  6, CHG_NZV },
460   { "inc",  "(x)->(x)", "inc8",      2, 0x6c,  6,  6, CHG_NZV },
461   { "tst",  "(x)",      "tst8",      2, 0x6d,  6,  6, CLR_V_CHG_NZ },
462   { "jmp",  "&(x)",     "bra",       2, 0x6e,  3,  3, CHG_NONE },
463   { "clr",  "->(x)",    "clr8",      2, 0x6f,  6,  6, SET_Z_CLR_NVC },
464   { "neg",  "()->()",   "neg8",      3, 0x70,  6,  6, CHG_NZVC },
465   { "com",  "()->()",   "com8",      3, 0x73,  6,  6, SET_C_CLR_V_CHG_NZ },
466   { "lsr",  "()->()",   "lsr8",      3, 0x74,  6,  6, CLR_V_CHG_ZVC },
467   { "ror",  "()->()",   "ror8",      3, 0x76,  6,  6, CHG_NZVC },
468   { "asr",  "()->()",   "asr8",      3, 0x77,  6,  6, CHG_NZVC },
469   { "asl",  "()->()",   "lsl8",      3, 0x78,  6,  6, CHG_NZVC },
470   { "rol",  "()->()",   "rol8",      3, 0x79,  6,  6, CHG_NZVC },
471   { "dec",  "()->()",   "dec8",      3, 0x7a,  6,  6, CHG_NZV },
472   { "inc",  "()->()",   "inc8",      3, 0x7c,  6,  6, CHG_NZV },
473   { "tst",  "()",       "tst8",      3, 0x7d,  6,  6, CLR_V_CHG_NZ },
474   { "jmp",  "&()",      "bra",       3, 0x7e,  3,  3, CHG_NONE },
475   { "clr",  "->()",     "clr8",      3, 0x7f,  6,  6, SET_Z_CLR_NVC },
476   { "suba", "#,a->a",   "sub8",      2, 0x80,  2,  2, CHG_NZVC },
477   { "cmpa", "#,a",      "sub8",      2, 0x81,  2,  2, CHG_NZVC },
478   { "sbca", "#,a->a",   "sbc8",      2, 0x82,  2,  2, CHG_NZVC },
479   { "subd", "#,d->d",   "sub16",     3, 0x83,  4,  4, CHG_NZVC },
480   { "anda", "#,a->a",   "and8",      2, 0x84,  2,  2, CLR_V_CHG_NZ },
481   { "bita", "#,a",      "and8",      2, 0x85,  2,  2, CLR_V_CHG_NZ },
482   { "ldaa", "#->a",     "movtst8",   2, 0x86,  2,  2, CLR_V_CHG_NZ },
483   { "eora", "#,a->a",   "eor8",      2, 0x88,  2,  2, CLR_V_CHG_NZ },
484   { "adca", "#,a->a",   "adc8",      2, 0x89,  2,  2, CHG_HNZVC },
485   { "oraa", "#,a->a",   "or8",       2, 0x8a,  2,  2, CLR_V_CHG_NZ },
486   { "adda", "#,a->a",   "add8",      2, 0x8b,  2,  2, CHG_HNZVC },
487   { "cmpx", "#,x",      "sub16",     3, 0x8c,  4,  4, CHG_NZVC },
488   { "bsr",  "r",        "jsr_11_16", 2, 0x8d,  6,  6, CHG_NONE },
489   { "lds",  "#->sp",    "movtst16",  3, 0x8e,  3,  3, CLR_V_CHG_NZ },
490   { "xgdx", "x->x",     "xgdxy16",   1, 0x8f,  3,  3, CHG_NONE },
491   { "suba", "*,a->a",   "sub8",      2, 0x90,  3,  3, CHG_NZVC },
492   { "cmpa", "*,a",      "sub8",      2, 0x91,  3,  3, CHG_NZVC },
493   { "sbca", "*,a->a",   "sbc8",      2, 0x92,  3,  3, CHG_NZVC },
494   { "subd", "*,d->d",   "sub16",     2, 0x93,  5,  5, CHG_NZVC },
495   { "anda", "*,a->a",   "and8",      2, 0x94,  3,  3, CLR_V_CHG_NZ },
496   { "bita", "*,a",      "and8",      2, 0x95,  3,  3, CLR_V_CHG_NZ },
497   { "ldaa", "*->a",     "movtst8",   2, 0x96,  3,  3, CLR_V_CHG_NZ },
498   { "staa", "a->*",     "movtst8",   2, 0x97,  3,  3, CLR_V_CHG_NZ },
499   { "eora", "*,a->a",   "eor8",      2, 0x98,  3,  3, CLR_V_CHG_NZ },
500   { "adca", "*,a->a",   "adc8",      2, 0x99,  3,  3, CHG_HNZVC },
501   { "oraa", "*,a->a",   "or8",       2, 0x9a,  3,  3, CLR_V_CHG_NZ },
502   { "adda", "*,a->a",   "add8",      2, 0x9b,  3,  3, CHG_HNZVC },
503   { "cmpx", "*,x",      "sub16",     2, 0x9c,  5,  5, CHG_NZVC },
504   { "jsr",  "*",        "jsr_11_16", 2, 0x9d,  5,  5, CHG_NONE },
505   { "lds",  "*->sp",    "movtst16",  2, 0x9e,  4,  4, CLR_V_CHG_NZ },
506   { "sts",  "sp->*",    "movtst16",  2, 0x9f,  4,  4, CLR_V_CHG_NZ },
507   { "suba", "(x),a->a", "sub8",      2, 0xa0,  4,  4, CHG_NZVC },
508   { "cmpa", "(x),a",    "sub8",      2, 0xa1,  4,  4, CHG_NZVC },
509   { "sbca", "(x),a->a", "sbc8",      2, 0xa2,  4,  4, CHG_NZVC },
510   { "subd", "(x),d->d", "sub16",     2, 0xa3,  6,  6, CHG_NZVC },
511   { "anda", "(x),a->a", "and8",      2, 0xa4,  4,  4, CLR_V_CHG_NZ },
512   { "bita", "(x),a",    "and8",      2, 0xa5,  4,  4, CLR_V_CHG_NZ },
513   { "ldaa", "(x)->a",   "movtst8",   2, 0xa6,  4,  4, CLR_V_CHG_NZ },
514   { "staa", "a->(x)",   "movtst8",   2, 0xa7,  4,  4, CLR_V_CHG_NZ },
515   { "eora", "(x),a->a", "eor8",      2, 0xa8,  4,  4, CLR_V_CHG_NZ },
516   { "adca", "(x),a->a", "adc8",      2, 0xa9,  4,  4, CHG_HNZVC },
517   { "oraa", "(x),a->a", "or8",       2, 0xaa,  4,  4, CLR_V_CHG_NZ },
518   { "adda", "(x),a->a", "add8",      2, 0xab,  4,  4, CHG_HNZVC },
519   { "cmpx", "(x),x",    "sub16",     2, 0xac,  6,  6, CHG_NZVC },
520   { "jsr",  "&(x)",     "jsr_11_16", 2, 0xad,  6,  6, CHG_NONE },
521   { "lds",  "(x)->sp",  "movtst16",  2, 0xae,  5,  5, CLR_V_CHG_NZ },
522   { "sts",  "sp->(x)",  "movtst16",  2, 0xaf,  5,  5, CLR_V_CHG_NZ },
523   { "suba", "(),a->a",  "sub8",      3, 0xb0,  4,  4, CHG_NZVC },
524   { "cmpa", "(),a",     "sub8",      3, 0xb1,  4,  4, CHG_NZVC },
525   { "sbca", "(),a->a",  "sbc8",      3, 0xb2,  4,  4, CHG_NZVC },
526   { "subd", "(),d->d",  "sub16",     3, 0xb3,  6,  6, CHG_NZVC },
527   { "anda", "(),a->a",  "and8",      3, 0xb4,  4,  4, CLR_V_CHG_NZ },
528   { "bita", "(),a",     "and8",      3, 0xb5,  4,  4, CLR_V_CHG_NZ },
529   { "ldaa", "()->a",    "movtst8",   3, 0xb6,  4,  4, CLR_V_CHG_NZ },
530   { "staa", "a->()",    "movtst8",   3, 0xb7,  4,  4, CLR_V_CHG_NZ },
531   { "eora", "(),a->a",  "eor8",      3, 0xb8,  4,  4, CLR_V_CHG_NZ },
532   { "adca", "(),a->a",  "adc8",      3, 0xb9,  4,  4, CHG_HNZVC },
533   { "oraa", "(),a->a",  "or8",       3, 0xba,  4,  4, CLR_V_CHG_NZ },
534   { "adda", "(),a->a",  "add8",      3, 0xbb,  4,  4, CHG_HNZVC },
535   { "cmpx", "(),x",     "sub16",     3, 0xbc,  5,  5, CHG_NZVC },
536   { "jsr",  "&()",      "jsr_11_16", 3, 0xbd,  6,  6, CHG_NONE },
537   { "lds",  "()->sp",   "movtst16",  3, 0xbe,  5,  5, CLR_V_CHG_NZ },
538   { "sts",  "sp->()",   "movtst16",  3, 0xbf,  5,  5, CLR_V_CHG_NZ },
539   { "subb", "#,b->b",   "sub8",      2, 0xc0,  2,  2, CHG_NZVC },
540   { "cmpb", "#,b",      "sub8",      2, 0xc1,  2,  2, CHG_NZVC },
541   { "sbcb", "#,b->b",   "sbc8",      2, 0xc2,  2,  2, CHG_NZVC },
542   { "addd", "#,d->d",   "add16",     3, 0xc3,  4,  4, CHG_NZVC },
543   { "andb", "#,b->b",   "and8",      2, 0xc4,  2,  2, CLR_V_CHG_NZ },
544   { "bitb", "#,b",      "and8",      2, 0xc5,  2,  2, CLR_V_CHG_NZ },
545   { "ldab", "#->b",     "movtst8",   2, 0xc6,  2,  2, CLR_V_CHG_NZ },
546   { "eorb", "#,b->b",   "eor8",      2, 0xc8,  2,  2, CLR_V_CHG_NZ },
547   { "adcb", "#,b->b",   "adc8",      2, 0xc9,  2,  2, CHG_HNZVC },
548   { "orab", "#,b->b",   "or8",       2, 0xca,  2,  2, CLR_V_CHG_NZ },
549   { "addb", "#,b->b",   "add8",      2, 0xcb,  2,  2, CHG_HNZVC },
550   { "ldd",  "#->d",     "movtst16",  3, 0xcc,  3,  3, CLR_V_CHG_NZ },
551   { "page4",0,          "page4",     1, 0xcd,  0,  0, CHG_NONE },
552   { "ldx",  "#->x",     "movtst16",  3, 0xce,  3,  3, CLR_V_CHG_NZ },
553   { "stop", 0,          0,           1, 0xcf,  2,  2, CHG_NONE },
554   { "subb", "*,b->b",   "sub8",      2, 0xd0,  3,  3, CHG_NZVC },
555   { "cmpb", "*,b",      "sub8",      2, 0xd1,  3,  3, CHG_NZVC },
556   { "sbcb", "*,b->b",   "sbc8",      2, 0xd2,  3,  3, CHG_NZVC },
557   { "addd", "*,d->d",   "add16",     2, 0xd3,  5,  5, CHG_NZVC },
558   { "andb", "*,b->b",   "and8",      2, 0xd4,  3,  3, CLR_V_CHG_NZ },
559   { "bitb", "*,b",      "and8",      2, 0xd5,  3,  3, CLR_V_CHG_NZ },
560   { "ldab", "*->b",     "movtst8",   2, 0xd6,  3,  3, CLR_V_CHG_NZ },
561   { "stab", "b->*",     "movtst8",   2, 0xd7,  3,  3, CLR_V_CHG_NZ },
562   { "eorb", "*,b->b",   "eor8",      2, 0xd8,  3,  3, CLR_V_CHG_NZ },
563   { "adcb", "*,b->b",   "adc8",      2, 0xd9,  3,  3, CHG_HNZVC },
564   { "orab", "*,b->b",   "or8",       2, 0xda,  3,  3, CLR_V_CHG_NZ },
565   { "addb", "*,b->b",   "add8",      2, 0xdb,  3,  3, CHG_HNZVC },
566   { "ldd",  "*->d",     "movtst16",  2, 0xdc,  4,  4, CLR_V_CHG_NZ },
567   { "std",  "d->*",     "movtst16",  2, 0xdd,  4,  4, CLR_V_CHG_NZ },
568   { "ldx",  "*->x",     "movtst16",  2, 0xde,  4,  4, CLR_V_CHG_NZ },
569   { "stx",  "x->*",     "movtst16",  2, 0xdf,  4,  4, CLR_V_CHG_NZ },
570   { "subb", "(x),b->b", "sub8",      2, 0xe0,  4,  4, CHG_NZVC },
571   { "cmpb", "(x),b",    "sub8",      2, 0xe1,  4,  4, CHG_NZVC },
572   { "sbcb", "(x),b->b", "sbc8",      2, 0xe2,  4,  4, CHG_NZVC },
573   { "addd", "(x),d->d", "add16",     2, 0xe3,  6,  6, CHG_NZVC },
574   { "andb", "(x),b->b", "and8",      2, 0xe4,  4,  4, CLR_V_CHG_NZ },
575   { "bitb", "(x),b",    "and8",      2, 0xe5,  4,  4, CLR_V_CHG_NZ },
576   { "ldab", "(x)->b",   "movtst8",   2, 0xe6,  4,  4, CLR_V_CHG_NZ },
577   { "stab", "b->(x)",   "movtst8",   2, 0xe7,  4,  4, CLR_V_CHG_NZ },
578   { "eorb", "(x),b->b", "eor8",      2, 0xe8,  4,  4, CLR_V_CHG_NZ },
579   { "adcb", "(x),b->b", "adc8",      2, 0xe9,  4,  4, CHG_HNZVC },
580   { "orab", "(x),b->b", "or8",       2, 0xea,  4,  4, CLR_V_CHG_NZ },
581   { "addb", "(x),b->b", "add8",      2, 0xeb,  4,  4, CHG_HNZVC },
582   { "ldd",  "(x)->d",   "movtst16",  2, 0xec,  5,  5, CLR_V_CHG_NZ },
583   { "std",  "d->(x)",   "movtst16",  2, 0xed,  5,  5, CLR_V_CHG_NZ },
584   { "ldx",  "(x)->x",   "movtst16",  2, 0xee,  5,  5, CLR_V_CHG_NZ },
585   { "stx",  "x->(x)",   "movtst16",  2, 0xef,  5,  5, CLR_V_CHG_NZ },
586   { "subb", "(),b->b",  "sub8",      3, 0xf0,  4,  4, CHG_NZVC },
587   { "cmpb", "(),b",     "sub8",      3, 0xf1,  4,  4, CHG_NZVC },
588   { "sbcb", "(),b->b",  "sbc8",      3, 0xf2,  4,  4, CHG_NZVC },
589   { "addd", "(),d->d",  "add16",     3, 0xf3,  6,  6, CHG_NZVC },
590   { "andb", "(),b->b",  "and8",      3, 0xf4,  4,  4, CLR_V_CHG_NZ },
591   { "bitb", "(),b",     "and8",      3, 0xf5,  4,  4, CLR_V_CHG_NZ },
592   { "ldab", "()->b",    "movtst8",   3, 0xf6,  4,  4, CLR_V_CHG_NZ },
593   { "stab", "b->()",    "movtst8",   3, 0xf7,  4,  4, CLR_V_CHG_NZ },
594   { "eorb", "(),b->b",  "eor8",      3, 0xf8,  4,  4, CLR_V_CHG_NZ },
595   { "adcb", "(),b->b",  "eor8",      3, 0xf9,  4,  4, CHG_HNZVC },
596   { "orab", "(),b->b",  "or8",       3, 0xfa,  4,  4, CLR_V_CHG_NZ },
597   { "addb", "(),b->b",  "add8",      3, 0xfb,  4,  4, CHG_HNZVC },
598   { "ldd",  "()->d",    "movtst16",  3, 0xfc,  5,  5, CLR_V_CHG_NZ },
599   { "std",  "d->()",    "movtst16",  3, 0xfd,  5,  5, CLR_V_CHG_NZ },
600   { "ldx",  "()->x",    "movtst16",  3, 0xfe,  5,  5, CLR_V_CHG_NZ },
601   { "stx",  "x->()",    "movtst16",  3, 0xff,  5,  5, CLR_V_CHG_NZ }
602 };
603
604
605 /* Page 2 opcodes */
606 /*
607  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
608  * Name -+                                       +----- Insn CCR changes
609  * Operands  ---+                         +------------ Max # cycles
610  * Pattern   -----------+              +--------------- Min # cycles
611  * Size      -----------------+   +-------------------- Opcode
612  */
613 struct m6811_opcode_def m6811_page2_opcodes[] = {
614   { "iny",  "y->y",     "inc16",     2, 0x08, 4, 4, CHG_Z },
615   { "dey",  "y->y",     "dec16",     2, 0x09, 4, 4, CHG_Z },
616   { "bset", "(y),#->(y)","or8",      4, 0x1c, 8, 8, CLR_V_CHG_NZ },
617   { "bclr", "(y),#->(y)","bclr8",    4, 0x1d, 8, 8, CLR_V_CHG_NZ },
618   { "brset","(y),#,r",   "brset8",   5, 0x1e, 8, 8, CHG_NONE },
619   { "brclr","(y),#,r",  "brclr8",    5, 0x1f, 8, 8, CHG_NONE },
620   { "tsy",  "sp->y",    "tsxy16",    2, 0x30, 4, 4, CHG_NONE },
621   { "tys",  "y->sp",    "txys16",    2, 0x35, 4, 4, CHG_NONE },
622   { "puly", "(sp)->y",  "mov16",     2, 0x38, 6, 6, CHG_NONE },
623   { "aby",  "b,y->y",   "abxy16",    2, 0x3a, 4, 4, CHG_NONE },
624   { "pshy", "y->(sp)",  "mov16",     2, 0x3c, 5, 5, CHG_NONE },
625   { "neg",  "(y)->(y)", "neg8",      3, 0x60, 7, 7, CHG_NZVC },
626   { "com",  "(y)->(y)", "com8",      3, 0x63, 7, 7, SET_C_CLR_V_CHG_NZ},
627   { "lsr",  "(y)->(y)", "lsr8",      3, 0x64, 7, 7, CLR_V_CHG_ZVC },
628   { "ror",  "(y)->(y)", "ror8",      3, 0x66, 7, 7, CHG_NZVC },
629   { "asr",  "(y)->(y)", "asr8",      3, 0x67, 7, 7, CHG_NZVC },
630   { "asl",  "(y)->(y)", "lsl8",      3, 0x68, 7, 7, CHG_NZVC },
631   { "rol",  "(y)->(y)", "rol8",      3, 0x69, 7, 7, CHG_NZVC },
632   { "dec",  "(y)->(y)", "dec8",      3, 0x6a, 7, 7, CHG_NZV },
633   { "inc",  "(y)->(y)", "inc8",      3, 0x6c, 7, 7, CHG_NZV },
634   { "tst",  "(y)",      "tst8",      3, 0x6d, 7, 7, CLR_V_CHG_NZ },
635   { "jmp",  "&(y)",     "bra",       3, 0x6e, 4, 4, CHG_NONE },
636   { "clr",  "->(y)",    "clr8",      3, 0x6f, 7, 7, SET_Z_CLR_NVC },
637   { "cmpy", "#,y",      "sub16",     4, 0x8c, 5, 5, CHG_NZVC },
638   { "xgdy", "y->y",     "xgdxy16",   2, 0x8f, 4, 4, CHG_NONE },
639   { "cmpy", "*,y",      "sub16",     3, 0x9c, 6, 6, CHG_NZVC },
640   { "suba", "(y),a->a", "sub8",      3, 0xa0, 5, 5, CHG_NZVC },
641   { "cmpa", "(y),a",    "sub8",      3, 0xa1, 5, 5, CHG_NZVC },
642   { "sbca", "(y),a->a", "sbc8",      3, 0xa2, 5, 5, CHG_NZVC },
643   { "subd", "(y),d->d", "sub16",     3, 0xa3, 7, 7, CHG_NZVC },
644   { "anda", "(y),a->a", "and8",      3, 0xa4, 5, 5, CLR_V_CHG_NZ },
645   { "bita", "(y),a",    "and8",      3, 0xa5, 5, 5, CLR_V_CHG_NZ },
646   { "ldaa", "(y)->a",   "movtst8",   3, 0xa6, 5, 5, CLR_V_CHG_NZ },
647   { "staa", "a->(y)",   "movtst8",   3, 0xa7, 5, 5, CLR_V_CHG_NZ },
648   { "eora", "(y),a->a", "eor8",      3, 0xa8, 5, 5, CLR_V_CHG_NZ },
649   { "adca", "(y),a->a", "adc8",      3, 0xa9, 5, 5, CHG_HNZVC },
650   { "oraa", "(y),a->a", "or8",       3, 0xaa, 5, 5, CLR_V_CHG_NZ },
651   { "adda", "(y),a->a", "add8",      3, 0xab, 5, 5, CHG_HNZVC },
652   { "cmpy", "(y),y",    "sub16",     3, 0xac, 7, 7, CHG_NZVC },
653   { "jsr",  "&(y)",     "jsr_11_16", 3, 0xad, 6, 6, CHG_NONE },
654   { "lds",  "(y)->sp",  "movtst16",  3, 0xae, 6, 6, CLR_V_CHG_NZ },
655   { "sts",  "sp->(y)",  "movtst16",  3, 0xaf, 6, 6, CLR_V_CHG_NZ },
656   { "cmpy", "(),y",     "sub16",     4, 0xbc, 7, 7, CHG_NZVC },
657   { "ldy",  "#->y",     "movtst16",  4, 0xce, 4, 4, CLR_V_CHG_NZ },
658   { "ldy",  "*->y",     "movtst16",  3, 0xde, 5, 5, CLR_V_CHG_NZ },
659   { "sty",  "y->*",     "movtst16",  3, 0xdf, 5, 5, CLR_V_CHG_NZ },
660   { "subb", "(y),b->b", "sub8",      3, 0xe0, 5, 5, CHG_NZVC },
661   { "cmpb", "(y),b",    "sub8",      3, 0xe1, 5, 5, CHG_NZVC },
662   { "sbcb", "(y),b->b", "sbc8",      3, 0xe2, 5, 5, CHG_NZVC },
663   { "addd", "(y),d->d", "add16",     3, 0xe3, 7, 7, CHG_NZVC },
664   { "andb", "(y),b->b", "and8",      3, 0xe4, 5, 5, CLR_V_CHG_NZ },
665   { "bitb", "(y),b",    "and8",      3, 0xe5, 5, 5, CLR_V_CHG_NZ },
666   { "ldab", "(y)->b",   "movtst8",   3, 0xe6, 5, 5, CLR_V_CHG_NZ },
667   { "stab", "b->(y)",   "movtst8",   3, 0xe7, 5, 5, CLR_V_CHG_NZ },
668   { "eorb", "(y),b->b", "eor8",      3, 0xe8, 5, 5, CLR_V_CHG_NZ },
669   { "adcb", "(y),b->b", "adc8",      3, 0xe9, 5, 5, CHG_HNZVC },
670   { "orab", "(y),b->b", "or8",       3, 0xea, 5, 5, CLR_V_CHG_NZ },
671   { "addb", "(y),b->b", "add8",      3, 0xeb, 5, 5, CHG_HNZVC },
672   { "ldd",  "(y)->d",   "movtst16",  3, 0xec, 6, 6, CLR_V_CHG_NZ },
673   { "std",  "d->(y)",   "movtst16",  3, 0xed, 6, 6, CLR_V_CHG_NZ },
674   { "ldy",  "(y)->y",   "movtst16",  3, 0xee, 6, 6, CLR_V_CHG_NZ },
675   { "sty",  "y->(y)",   "movtst16",  3, 0xef, 6, 6, CLR_V_CHG_NZ },
676   { "ldy",  "()->y",    "movtst16",  4, 0xfe, 6, 6, CLR_V_CHG_NZ },
677   { "sty",  "y->()",    "movtst16",  4, 0xff, 6, 6, CLR_V_CHG_NZ }
678 };
679
680 /* Page 3 opcodes */
681 /*
682  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
683  * Name -+                                       +----- Insn CCR changes
684  * Operands  ---+                         +------------ Max # cycles
685  * Pattern   -----------+              +--------------- Min # cycles
686  * Size      -----------------+   +-------------------- Opcode
687  */
688 struct m6811_opcode_def m6811_page3_opcodes[] = {
689   { "cmpd", "#,d",      "sub16",     4, 0x83, 5, 5, CHG_NZVC },
690   { "cmpd", "*,d",      "sub16",     3, 0x93, 6, 6, CHG_NZVC },
691   { "cmpd", "(x),d",    "sub16",     3, 0xa3, 7, 7, CHG_NZVC },
692   { "cmpy", "(x),y",    "sub16",     3, 0xac, 7, 7, CHG_NZVC },
693   { "cmpd", "(),d",     "sub16",     4, 0xb3, 7, 7, CHG_NZVC },
694   { "ldy",  "(x)->y",   "movtst16",  3, 0xee, 6, 6, CLR_V_CHG_NZ },
695   { "sty",  "y->(x)",   "movtst16",  3, 0xef, 6, 6, CLR_V_CHG_NZ }
696 };
697
698 /* Page 4 opcodes */
699 /*
700  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
701  * Name -+                                       +----- Insn CCR changes
702  * Operands  ---+                         +------------ Max # cycles
703  * Pattern   -----------+              +--------------- Min # cycles
704  * Size      -----------------+   +-------------------- Opcode
705  */
706 struct m6811_opcode_def m6811_page4_opcodes[] = {
707   { "syscall", "",      "syscall",   2, 0x03, 6, 6, CHG_NONE },
708   { "cmpd", "(y),d",    "sub16",     3, 0xa3, 7, 7, CHG_NZVC },
709   { "cmpx", "(y),x",    "sub16",     3, 0xac, 7, 7, CHG_NZVC },
710   { "ldx",  "(y)->x",   "movtst16",  3, 0xee, 6, 6, CLR_V_CHG_NZ },
711   { "stx",  "x->(y)",   "movtst16",  3, 0xef, 6, 6, CLR_V_CHG_NZ }
712 };
713
714 /* 68HC12 opcodes */
715 /*
716  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
717  * Name -+                                       +----- Insn CCR changes
718  * Operands  ---+                         +------------ Max # cycles
719  * Pattern   -----------+              +--------------- Min # cycles
720  * Size      -----------------+   +-------------------- Opcode
721  */
722 struct m6811_opcode_def m6812_page1_opcodes[] = {
723   { "adca", "#,a->a",    "adc8",     2, 0x89,  1,  1,  CHG_HNZVC },
724   { "adca", "*,a->a",    "adc8",     2, 0x99,  3,  3,  CHG_HNZVC },
725   { "adca", "(),a->a",   "adc8",     3, 0xb9,  3,  3,  CHG_HNZVC },
726   { "adca", "[],a->a",   "adc8",     2, 0xa9,  3,  3,  CHG_HNZVC },
727
728   { "adcb", "#,b->b",    "adc8",     2, 0xc9,  1,  1,  CHG_HNZVC },
729   { "adcb", "*,b->b",    "adc8",     3, 0xd9,  3,  3,  CHG_HNZVC },
730   { "adcb", "(),b->b",   "adc8",     3, 0xf9,  3,  3,  CHG_HNZVC },
731   { "adcb", "[],b->b",   "adc8",     2, 0xe9,  3,  3,  CHG_HNZVC },
732
733   { "adda", "#,a->a",    "add8",     2, 0x8b,  1,  1,  CHG_HNZVC },
734   { "adda", "*,a->a",    "add8",     3, 0x9b,  3,  3,  CHG_HNZVC },
735   { "adda", "(),a->a",   "add8",     3, 0xbb,  3,  3,  CHG_HNZVC },
736   { "adda", "[],a->a",   "add8",     2, 0xab,  3,  3,  CHG_HNZVC },
737
738   { "addb", "#,b->b",    "add8",     2, 0xcb,  1,  1,  CHG_HNZVC },
739   { "addb", "*,b->b",    "add8",     3, 0xdb,  3,  3,  CHG_HNZVC },
740   { "addb", "(),b->b",   "add8",     3, 0xfb,  3,  3,  CHG_HNZVC },
741   { "addb", "[],b->b",   "add8",     2, 0xeb,  3,  3,  CHG_HNZVC },
742
743   { "addd", "#,d->d",    "add16",    3, 0xc3,  2,  2,  CHG_NZVC },
744   { "addd", "*,d->d",    "add16",    2, 0xd3,  3,  3,  CHG_NZVC },
745   { "addd", "(),d->d",   "add16",    3, 0xf3,  3,  3,  CHG_NZVC },
746   { "addd", "[],d->d",   "add16",    2, 0xe3,  3,  3,  CHG_NZVC },
747
748   { "anda", "#,a->a",    "and8",     2, 0x84,  1,  1,  CLR_V_CHG_NZ },
749   { "anda", "*,a->a",    "and8",     2, 0x94,  3,  3,  CLR_V_CHG_NZ },
750   { "anda", "(),a->a",   "and8",     3, 0xb4,  3,  3,  CLR_V_CHG_NZ },
751   { "anda", "[],a->a",   "and8",     2, 0xa4,  3,  3,  CLR_V_CHG_NZ },
752
753   { "andb", "#,b->b",    "and8",     2, 0xc4,  1,  1,  CLR_V_CHG_NZ },
754   { "andb", "*,b->b",    "and8",     2, 0xd4,  3,  3,  CLR_V_CHG_NZ },
755   { "andb", "(),b->b",   "and8",     3, 0xf4,  3,  3,  CLR_V_CHG_NZ },
756   { "andb", "[],b->b",   "and8",     2, 0xe4,  3,  3,  CLR_V_CHG_NZ },
757
758   { "andcc", "#,ccr->ccr", "and8",   2, 0x10,  1,  1,  CHG_ALL },
759
760   { "asl",  "()->()",    "lsl8",     3, 0x78,  4,  4,  CHG_NZVC },
761   { "asl",  "[]->[]",    "lsl8",     2, 0x68,  3,  3,  CHG_NZVC },
762
763   { "asla", "a->a",      "lsl8",     1, 0x48,  1,  1,  CHG_NZVC },
764   { "aslb", "b->b",      "lsl8",     1, 0x58,  1,  1,  CHG_NZVC },
765   { "asld", "d->d",      "lsl16",    1, 0x59,  1,  1,  CHG_NZVC },
766
767   { "asr",  "()->()",    "asr8",     3, 0x77,  4,  4,  CHG_NZVC },
768   { "asr",  "[]->[]",    "asr8",     2, 0x67,  3,  3,  CHG_NZVC },
769
770   { "asra", "a->a",      "asr8",     1, 0x47,  1,  1,  CHG_NZVC },
771   { "asrb", "b->b",      "asr8",     1, 0x57,  1,  1,  CHG_NZVC },
772
773   { "bcc",  "r",         0,          2, 0x24,  1,  3,  CHG_NONE },
774
775   { "bclr", "*,#->*",    "bclr8",    3, 0x4d,  4,  4,  CLR_V_CHG_NZ },
776   { "bclr", "(),#->()",  "bclr8",    4, 0x1d,  4,  4,  CLR_V_CHG_NZ },
777   { "bclr", "[],#->[]",  "bclr8",    3, 0x0d,  4,  4,  CLR_V_CHG_NZ },
778
779   { "bcs",  "r",         0,          2, 0x25,  1,  3, CHG_NONE },
780   { "beq",  "r",         0,          2, 0x27,  1,  3, CHG_NONE },
781   { "bge",  "r",         0,          2, 0x2c,  1,  3, CHG_NONE },
782
783   { "bgnd",  0,          0,          1, 0x00,  5,  5, CHG_NONE },
784
785   { "bgt",  "r",         0,          2, 0x2e,  1,  3, CHG_NONE },
786   { "bhi",  "r",         0,          2, 0x22,  1,  3, CHG_NONE },
787   
788   { "bita", "#,a",       "and8",     2, 0x85,  1,  1, CLR_V_CHG_NZ },
789   { "bita", "*,a",       "and8",     2, 0x95,  3,  3, CLR_V_CHG_NZ },
790   { "bita", "(),a",      "and8",     3, 0xb5,  3,  3, CLR_V_CHG_NZ },
791   { "bita", "[],a",      "and8",     2, 0xa5,  3,  3,  CLR_V_CHG_NZ },
792
793   { "bitb", "#,b",       "and8",     2, 0xc5,  1,  1, CLR_V_CHG_NZ },
794   { "bitb", "*,b",       "and8",     2, 0xd5,  3,  3, CLR_V_CHG_NZ },
795   { "bitb", "(),b",      "and8",     3, 0xf5,  3,  3, CLR_V_CHG_NZ },
796   { "bitb", "[],b",      "and8",     2, 0xe5,  3,  3,  CLR_V_CHG_NZ },
797
798   { "ble",  "r",          0,         2, 0x2f,  1,  3, CHG_NONE },
799   { "bls",  "r",          0,         2, 0x23,  1,  3, CHG_NONE },
800   { "blt",  "r",          0,         2, 0x2d,  1,  3, CHG_NONE },
801   { "bmi",  "r",          0,         2, 0x2b,  1,  3, CHG_NONE },
802   { "bne",  "r",          0,         2, 0x26,  1,  3, CHG_NONE },
803   { "bpl",  "r",          0,         2, 0x2a,  1,  3, CHG_NONE },
804   { "bra",  "r",          0,         2, 0x20,  1,  3, CHG_NONE },
805
806   { "brclr", "*,#,r",     "brclr8",  4, 0x4f,  4,  4,  CHG_NONE },
807   { "brclr", "(),#,r",    "brclr8",  5, 0x1f,  5,  5,  CHG_NONE },
808   { "brclr", "[],#,r",    "brclr8",  4, 0x0f,  4,  4,  CHG_NONE },
809
810   { "brn",  "r",          "nop",     2, 0x21,  1,  3,  CHG_NONE },
811
812   { "brset", "*,#,r",     "brset8",  4, 0x4e,  4,  4,  CHG_NONE },
813   { "brset", "(),#,r",    "brset8",  5, 0x1e,  5,  5,  CHG_NONE },
814   { "brset", "[],#,r",    "brset8",  4, 0x0e,  4,  4,  CHG_NONE },
815
816   { "bset",  "*,#->*",    "or8",     3, 0x4c,  4,  4,  CLR_V_CHG_NZ },
817   { "bset",  "(),#->()",  "or8",     4, 0x1c,  4,  4,  CLR_V_CHG_NZ },
818   { "bset",  "[],#->[]",  "or8",     3, 0x0c,  4,  4,  CLR_V_CHG_NZ },
819
820   { "bsr",   "r",         "jsr_12_16", 2, 0x07,  4,  4, CHG_NONE },
821
822   { "bvc",   "r",         0,         2, 0x28,  1,  3, CHG_NONE },
823   { "bvs",   "r",         0,         2, 0x29,  1,  3, CHG_NONE },
824
825   { "call",  "",          "call8",   4, 0x4a,  8,  8,  CHG_NONE },
826   { "call",  "",          "call_ind",2, 0x4b,  8,  8,  CHG_NONE },
827
828   { "clr",   "->()",      "clr8",    3, 0x79,  3,  3,  SET_Z_CLR_NVC },
829   { "clr",   "->[]",      "clr8",    2, 0x69,  2,  2,  SET_Z_CLR_NVC },
830
831   { "clra",  "->a",       "clr8",    1, 0x87,  1,  1,  SET_Z_CLR_NVC },
832   { "clrb",  "->b",       "clr8",    1, 0xc7,  1,  1,  SET_Z_CLR_NVC },
833
834   { "cpa",  "#,a",        "sub8",    2, 0x81,  1,  1,  CHG_NZVC },
835   { "cpa",  "*,a",        "sub8",    2, 0x91,  3,  3,  CHG_NZVC },
836   { "cpa",  "(),a",       "sub8",    3, 0xb1,  3,  3,  CHG_NZVC },
837   { "cpa",  "[],a",       "sub8",    2, 0xa1,  3,  3,  CHG_NZVC },
838
839   { "cpb",  "#,b",        "sub8",    2, 0xc1,  1,  1,  CHG_NZVC },
840   { "cpb",  "*,b",        "sub8",    2, 0xd1,  3,  3,  CHG_NZVC },
841   { "cpb",  "(),b",       "sub8",    3, 0xf1,  3,  3,  CHG_NZVC },
842   { "cpb",  "[],b",       "sub8",    2, 0xe1,  3,  3,  CHG_NZVC },
843
844   { "com",   "()->()",    "com8",    3, 0x71,  4,  4,  SET_C_CLR_V_CHG_NZ },
845   { "com",   "[]->[]",    "com8",    2, 0x61,  3,  3,  SET_C_CLR_V_CHG_NZ },
846
847   { "coma",  "a->a",      "com8",    1, 0x41,  1,  1,  SET_C_CLR_V_CHG_NZ },
848   { "comb",  "b->b",      "com8",    1, 0x51,  1,  1,  SET_C_CLR_V_CHG_NZ },
849
850   { "cpd",   "#,d",       "sub16",   3, 0x8c,  2,  2,  CHG_NZVC },
851   { "cpd",   "*,d",       "sub16",   2, 0x9c,  3,  3,  CHG_NZVC },
852   { "cpd",   "(),d",      "sub16",   3, 0xbc,  3,  3,  CHG_NZVC },
853   { "cpd",   "[],d",      "sub16",   2, 0xac,  3,  3,  CHG_NZVC },
854
855   { "cps",   "#,sp",      "sub16",   3, 0x8f,  2,  2,  CHG_NZVC },
856   { "cps",   "*,sp",      "sub16",   2, 0x9f,  3,  3,  CHG_NZVC },
857   { "cps",   "(),sp",     "sub16",   3, 0xbf,  3,  3,  CHG_NZVC },
858   { "cps",   "[],sp",     "sub16",   2, 0xaf,  3,  3,  CHG_NZVC },
859
860   { "cpx",   "#,x",       "sub16",   3, 0x8e,  2,  2,  CHG_NZVC },
861   { "cpx",   "*,x",       "sub16",   2, 0x9e,  3,  3,  CHG_NZVC },
862   { "cpx",   "(),x",      "sub16",   3, 0xbe,  3,  3,  CHG_NZVC },
863   { "cpx",   "[],x",      "sub16",   2, 0xae,  3,  3,  CHG_NZVC },
864
865   { "cpy",   "#,y",       "sub16",   3, 0x8d,  2,  2,  CHG_NZVC },
866   { "cpy",   "*,y",       "sub16",   2, 0x9d,  3,  3,  CHG_NZVC },
867   { "cpy",   "(),y",      "sub16",   3, 0xbd,  3,  3,  CHG_NZVC },
868   { "cpy",   "[],y",      "sub16",   2, 0xad,  3,  3,  CHG_NZVC },
869
870   /* dbeq, dbne, ibeq, ibne, tbeq, tbne */
871   { "dbeq",   0,          "dbcc8",   3, 0x04,  3,  3, CHG_NONE },
872
873   { "dec",   "()->()",    "dec8",    3, 0x73,  4,  4,  CHG_NZV },
874   { "dec",   "[]->[]",    "dec8",    2, 0x63,  3,  3,  CHG_NZV },
875
876   { "deca",  "a->a",      "dec8",    1, 0x43,  1,  1,  CHG_NZV },
877   { "decb",  "b->b",      "dec8",    1, 0x53,  1,  1,  CHG_NZV },
878
879   { "dex",   "x->x",      "dec16",   1, 0x09,  1,  1,  CHG_Z },
880   { "dey",   "y->y",      "dec16",   1, 0x03,  1,  1,  CHG_Z },
881
882   { "ediv",  0,           0,         1, 0x11,  11,  11,  CHG_NZVC },
883   { "emul",  0,           0,         1, 0x13,  3,  3,  CHG_NZC },
884
885   { "eora",  "#,a->a",    "eor8",    2, 0x88,  1,  1,  CLR_V_CHG_NZ },
886   { "eora",  "*,a->a",    "eor8",    2, 0x98,  3,  3,  CLR_V_CHG_NZ },
887   { "eora",  "(),a->a",   "eor8",    3, 0xb8,  3,  3,  CLR_V_CHG_NZ },
888   { "eora",  "[],a->a",   "eor8",    2, 0xa8,  3,  3,  CLR_V_CHG_NZ },
889
890   { "eorb",  "#,b->b",    "eor8",    2, 0xc8,  1,  1,  CLR_V_CHG_NZ },
891   { "eorb",  "*,b->b",    "eor8",    2, 0xd8,  3,  3,  CLR_V_CHG_NZ },
892   { "eorb",  "(),b->b",   "eor8",    3, 0xf8,  3,  3,  CLR_V_CHG_NZ },
893   { "eorb",  "[],b->b",   "eor8",    2, 0xe8,  3,  3,  CLR_V_CHG_NZ },
894
895   /* exg, sex, tfr */
896   { "exg",   "#",         "exg8",    2, 0xb7,  1,  1,  CHG_NONE },
897
898   { "inc",   "()->()",    "inc8",    3, 0x72,  4,  4,  CHG_NZV },
899   { "inc",   "[]->[]",    "inc8",    2, 0x62,  3,  3,  CHG_NZV },
900
901   { "inca",  "a->a",      "inc8",    1, 0x42,  1,  1,  CHG_NZV },
902   { "incb",  "b->b",      "inc8",    1, 0x52,  1,  1,  CHG_NZV },
903
904   { "inx",   "x->x",      "inc16",   1, 0x08,  1,  1,  CHG_Z },
905   { "iny",   "y->y",      "inc16",   1, 0x02,  1,  1,  CHG_Z },
906
907   { "jmp",   "&()",       "bra",     3, 0x06,  3,  3,  CHG_NONE },
908   { "jmp",   "&[]",       "bra",     2, 0x05,  3,  3,  CHG_NONE },
909
910   { "jsr",   "*",         "jsr_12_16",   2, 0x17,  4,  4,  CHG_NONE },
911   { "jsr",   "&()",       "jsr_12_16",   3, 0x16,  4,  4,  CHG_NONE },
912   { "jsr",   "&[]",       "jsr_12_16",   2, 0x15,  4,  4,  CHG_NONE },
913
914   { "ldaa", "#->a",       "movtst8", 2, 0x86,  1,  1,  CLR_V_CHG_NZ },
915   { "ldaa", "*->a",       "movtst8", 2, 0x96,  3,  3,  CLR_V_CHG_NZ },
916   { "ldaa", "()->a",      "movtst8", 3, 0xb6,  3,  3,  CLR_V_CHG_NZ },
917   { "ldaa", "[]->a",      "movtst8", 2, 0xa6,  3,  3,  CLR_V_CHG_NZ },
918
919   { "ldab", "#->b",       "movtst8", 2, 0xc6,  1,  1,  CLR_V_CHG_NZ },
920   { "ldab", "*->b",       "movtst8", 2, 0xd6,  3,  3,  CLR_V_CHG_NZ },
921   { "ldab", "()->b",      "movtst8", 3, 0xf6,  3,  3,  CLR_V_CHG_NZ },
922   { "ldab", "[]->b",      "movtst8", 2, 0xe6,  3,  3,  CLR_V_CHG_NZ },
923
924   { "ldd",  "#->d",       "movtst16", 3, 0xcc,  2,  2,  CLR_V_CHG_NZ },
925   { "ldd",  "*->d",       "movtst16", 2, 0xdc,  3,  3,  CLR_V_CHG_NZ },
926   { "ldd",  "()->d",      "movtst16", 3, 0xfc,  3,  3,  CLR_V_CHG_NZ },
927   { "ldd",  "[]->d",      "movtst16", 2, 0xec,  3,  3,  CLR_V_CHG_NZ },
928
929   { "lds",  "#->sp",      "movtst16", 3, 0xcf,  2,  2,  CLR_V_CHG_NZ },
930   { "lds",  "*->sp",      "movtst16", 2, 0xdf,  3,  3,  CLR_V_CHG_NZ },
931   { "lds",  "()->sp",     "movtst16", 3, 0xff,  3,  3,  CLR_V_CHG_NZ },
932   { "lds",  "[]->sp",     "movtst16", 2, 0xef,  3,  3,  CLR_V_CHG_NZ },
933
934   { "ldx",  "#->x",       "movtst16", 3, 0xce,  2,  2,  CLR_V_CHG_NZ },
935   { "ldx",  "*->x",       "movtst16", 2, 0xde,  3,  3,  CLR_V_CHG_NZ },
936   { "ldx",  "()->x",      "movtst16", 3, 0xfe,  3,  3,  CLR_V_CHG_NZ },
937   { "ldx",  "[]->x",      "movtst16", 2, 0xee,  3,  3,  CLR_V_CHG_NZ },
938
939   { "ldy",  "#->y",       "movtst16", 3, 0xcd,  2,  2,  CLR_V_CHG_NZ },
940   { "ldy",  "*->y",       "movtst16", 2, 0xdd,  3,  3,  CLR_V_CHG_NZ },
941   { "ldy",  "()->y",      "movtst16", 3, 0xfd,  3,  3,  CLR_V_CHG_NZ },
942   { "ldy",  "[]->y",      "movtst16", 2, 0xed,  3,  3,  CLR_V_CHG_NZ },
943
944   { "leas", "&[]->sp",    "lea16",   2, 0x1b,  2,  2,  CHG_NONE },
945   { "leax", "&[]->x",     "lea16",   2, 0x1a,  2,  2,  CHG_NONE },
946   { "leay", "&[]->y",     "lea16",   2, 0x19,  2,  2,  CHG_NONE },
947
948   { "lsr",  "()->()",     "lsr8",    3, 0x74,  4,  4,  CLR_N_CHG_ZVC },
949   { "lsr",  "[]->[]",     "lsr8",    2, 0x64,  3,  3,  CLR_N_CHG_ZVC },
950
951   { "lsra", "a->a",       "lsr8",    1, 0x44,  1,  1,  CLR_N_CHG_ZVC },
952   { "lsrb", "b->b",       "lsr8",    1, 0x54,  1,  1,  CLR_N_CHG_ZVC },
953   { "lsrd", "d->d",       "lsr16",   1, 0x49,  1,  1,  CLR_N_CHG_ZVC },
954
955   { "mem",  0,            0,         1, 0x01,  5,  5,  CHG_HNZVC },
956
957   { "mul",  "b,a->d",     "mul16",   1, 0x12,  3,  3,  CHG_C },
958
959   { "neg",  "()->()",     "neg8",    3, 0x70,  4,  4,  CHG_NZVC },
960   { "neg",  "[]->[]",     "neg8",    2, 0x60,  3,  3,  CHG_NZVC },
961
962   { "nega", "a->a",       "neg8",    1, 0x40,  1,  1,  CHG_NZVC },
963   { "negb", "b->b",       "neg8",    1, 0x50,  1,  1,  CHG_NZVC },
964
965   { "nop",  "",           "nop",     1, 0xa7,  1,  1,  CHG_NONE },
966
967   { "oraa", "#,a->a",     "or8",     2, 0x8a,  1,  1,  CLR_V_CHG_NZ },
968   { "oraa", "*,a->a",     "or8",     2, 0x9a,  3,  3,  CLR_V_CHG_NZ },
969   { "oraa", "(),a->a",    "or8",     3, 0xba,  3,  3,  CLR_V_CHG_NZ },
970   { "oraa", "[],a->a",    "or8",     2, 0xaa,  3,  3,  CLR_V_CHG_NZ },
971
972   { "orab", "#,b->b",     "or8",     2, 0xca,  1,  1,  CLR_V_CHG_NZ },
973   { "orab", "*,b->b",     "or8",     2, 0xda,  3,  3,  CLR_V_CHG_NZ },
974   { "orab", "(),b->b",    "or8",     3, 0xfa,  3,  3,  CLR_V_CHG_NZ },
975   { "orab", "[],b->b",    "or8",     2, 0xea,  3,  3,  CLR_V_CHG_NZ },
976
977   { "orcc", "#,ccr->ccr", "or8",     2, 0x14,  1,  1,  CHG_ALL },
978
979   { "page2", 0,           "page2",   1, 0x18,  0,  0,  CHG_NONE },
980
981   { "psha", "a->(sp)",    "mov8",    1, 0x36,  2,  2,  CHG_NONE },
982   { "pshb", "b->(sp)",    "mov8",    1, 0x37,  2,  2,  CHG_NONE },
983   { "pshc", "ccr->(sp)",  "mov8",    1, 0x39,  2,  2,  CHG_NONE },
984   { "pshd", "d->(sp)",    "mov16",   1, 0x3b,  2,  2,  CHG_NONE },
985   { "pshx", "x->(sp)",    "mov16",   1, 0x34,  2,  2,  CHG_NONE },
986   { "pshy", "y->(sp)",    "mov16",   1, 0x35,  2,  2,  CHG_NONE },
987
988   { "pula", "(sp)->a",    "mov8",    1, 0x32,  3,  3,  CHG_NONE },
989   { "pulb", "(sp)->b",    "mov8",    1, 0x33,  3,  3,  CHG_NONE },
990   { "pulc", "(sp)->ccr",  "mov8",    1, 0x38,  3,  3,  CHG_ALL },
991   { "puld", "(sp)->d",    "mov16",   1, 0x3a,  3,  3,  CHG_NONE },
992   { "pulx", "(sp)->x",    "mov16",   1, 0x30,  3,  3,  CHG_NONE },
993   { "puly", "(sp)->y",    "mov16",   1, 0x31,  3,  3,  CHG_NONE },
994
995   { "rol",  "()->()",     "rol8",    3, 0x75,  4,  4,  CHG_NZVC },
996   { "rol",  "[]->[]",     "rol8",    2, 0x65,  3,  3,  CHG_NZVC },
997
998   { "rola", "a->a",       "rol8",    1, 0x45,  1,  1,  CHG_NZVC },
999   { "rolb", "b->b",       "rol8",    1, 0x55,  1,  1,  CHG_NZVC },
1000
1001   { "ror",  "()->()",     "ror8",    3, 0x76,  4,  4,  CHG_NZVC },
1002   { "ror",  "[]->[]",     "ror8",    2, 0x66,  3,  3,  CHG_NZVC },
1003
1004   { "rora", "a->a",       "ror8",    1, 0x46,  1,  1,  CHG_NZVC },
1005   { "rorb", "b->b",       "ror8",    1, 0x56,  1,  1,  CHG_NZVC },
1006
1007   { "rtc",  0,            0,         1, 0x0a,  6,  6,  CHG_NONE },
1008   { "rti",  0,            "rti12",   1, 0x0b,  8, 10,  CHG_ALL},
1009   { "rts",  0,            "rts12",   1, 0x3d,  5,  5,  CHG_NONE },
1010
1011   { "sbca", "#,a->a",     "sbc8",    2, 0x82,  1,  1,  CHG_NZVC },
1012   { "sbca", "*,a->a",     "sbc8",    2, 0x92,  3,  3,  CHG_NZVC },
1013   { "sbca", "(),a->a",    "sbc8",    3, 0xb2,  3,  3,  CHG_NZVC },
1014   { "sbca", "[],a->a",    "sbc8",    2, 0xa2,  3,  3,  CHG_NZVC },
1015
1016   { "sbcb", "#,b->b",     "sbc8",    2, 0xc2,  1,  1,  CHG_NZVC },
1017   { "sbcb", "*,b->b",     "sbc8",    2, 0xd2,  3,  3,  CHG_NZVC },
1018   { "sbcb", "(),b->b",    "sbc8",    3, 0xf2,  3,  3,  CHG_NZVC },
1019   { "sbcb", "[],b->b",    "sbc8",    2, 0xe2,  3,  3,  CHG_NZVC },
1020
1021   { "staa", "a->*",       "movtst8", 2, 0x5a,  2,  2,  CLR_V_CHG_NZ },
1022   { "staa", "a->()",      "movtst8", 3, 0x7a,  3,  3,  CLR_V_CHG_NZ },
1023   { "staa", "a->[]",      "movtst8", 2, 0x6a,  2,  2,  CLR_V_CHG_NZ },
1024
1025   { "stab", "b->*",       "movtst8", 2, 0x5b,  2,  2,  CLR_V_CHG_NZ },
1026   { "stab", "b->()",      "movtst8", 3, 0x7b,  3,  3,  CLR_V_CHG_NZ },
1027   { "stab", "b->[]",      "movtst8", 2, 0x6b,  2,  2,  CLR_V_CHG_NZ },
1028
1029   { "std",  "d->*",       "movtst16", 2, 0x5c,  2,  2,  CLR_V_CHG_NZ },
1030   { "std",  "d->()",      "movtst16", 3, 0x7c,  3,  3,  CLR_V_CHG_NZ },
1031   { "std",  "d->[]",      "movtst16", 2, 0x6c,  2,  2,  CLR_V_CHG_NZ },
1032
1033   { "sts",  "sp->*",      "movtst16", 2, 0x5f,  2,  2,  CLR_V_CHG_NZ },
1034   { "sts",  "sp->()",     "movtst16", 3, 0x7f,  3,  3,  CLR_V_CHG_NZ },
1035   { "sts",  "sp->[]",     "movtst16", 2, 0x6f,  2,  2,  CLR_V_CHG_NZ },
1036
1037   { "stx",  "x->*",       "movtst16", 2, 0x5e,  2,  2,  CLR_V_CHG_NZ },
1038   { "stx",  "x->()",      "movtst16", 3, 0x7e,  3,  3,  CLR_V_CHG_NZ },
1039   { "stx",  "x->[]",      "movtst16", 2, 0x6e,  2,  2,  CLR_V_CHG_NZ },
1040
1041   { "sty",  "y->*",       "movtst16", 2, 0x5d,  2,  2,  CLR_V_CHG_NZ },
1042   { "sty",  "y->()",      "movtst16", 3, 0x7d,  3,  3,  CLR_V_CHG_NZ },
1043   { "sty",  "y->[]",      "movtst16", 2, 0x6d,  2,  2,  CLR_V_CHG_NZ },
1044
1045   { "suba", "#,a->a",     "sub8",     2, 0x80,  1,  1,  CHG_NZVC },
1046   { "suba", "*,a->a",     "sub8",     2, 0x90,  3,  3,  CHG_NZVC },
1047   { "suba", "(),a->a",    "sub8",     3, 0xb0,  3,  3,  CHG_NZVC },
1048   { "suba", "[],a->a",    "sub8",     2, 0xa0,  3,  3,  CHG_NZVC },
1049
1050   { "subb", "#,b->b",     "sub8",     2, 0xc0,  1,  1,  CHG_NZVC },
1051   { "subb", "*,b->b",     "sub8",     2, 0xd0,  3,  3,  CHG_NZVC },
1052   { "subb", "(),b->b",    "sub8",     3, 0xf0,  3,  3,  CHG_NZVC },
1053   { "subb", "[],b->b",    "sub8",     2, 0xe0,  3,  3,  CHG_NZVC },
1054
1055   { "subd", "#,d->d",     "sub16",    3, 0x83,  2,  2,  CHG_NZVC },
1056   { "subd", "*,d->d",     "sub16",    2, 0x93,  3,  3,  CHG_NZVC },
1057   { "subd", "(),d->d",    "sub16",    3, 0xb3,  3,  3,  CHG_NZVC },
1058   { "subd", "[],d->d",    "sub16",    2, 0xa3,  3,  3,  CHG_NZVC },
1059
1060   { "swi",  0,            0,          1, 0x3f,  9,  9,  CHG_NONE },
1061
1062   { "tst",  "()",         "tst8",     3, 0xf7,  3,  3,  CLR_VC_CHG_NZ },
1063   { "tst",  "[]",         "tst8",     2, 0xe7,  3,  3,  CLR_VC_CHG_NZ },
1064
1065   { "tsta", "a",          "tst8",     1, 0x97,  1,  1,  CLR_VC_CHG_NZ },
1066   { "tstb", "b",          "tst8",     1, 0xd7,  1,  1,  CLR_VC_CHG_NZ },
1067
1068   { "wai",  0,            0,          1, 0x3e,  8,  _M, CHG_NONE }
1069 };
1070
1071 struct m6811_opcode_def m6812_page2_opcodes[] = {
1072   { "cba",  "b,a",        "sub8",     2, 0x17,  2,  2,  CHG_NZVC },
1073
1074   /* After 'daa', the Z flag is undefined. Mark it as changed.  */
1075   { "daa",  0,            "daa8",     2, 0x07,  3,  3,  CHG_NZVC },
1076
1077   { "edivs", 0,           0,          2, 0x14,  12,  12,  CHG_NZVC },
1078   { "emacs", 0,           0,          2, 0x12,  13,  13,  CHG_NZVC },
1079
1080   { "emaxd", "[],d->d",   "max16",    3, 0x1a,  4,  4,  CHG_NZVC },
1081   { "emaxm", "[],d->[]",  "max16",    3, 0x1e,  4,  4,  CHG_NZVC },
1082   { "emind", "[],d->d",   "min16",    3, 0x1b,  4,  4,  CHG_NZVC },
1083   { "eminm", "[],d->[]",  "min16",    3, 0x1f,  4,  4,  CHG_NZVC },
1084
1085   { "emuls", 0,           0,          2, 0x13,  3,  3,  CHG_NZC },
1086   { "etbl",  "[]",        "tbl16",    3, 0x3f, 10, 10,  CHG_NZC },
1087   { "fdiv",  "x,d->x",    "fdiv16",   2, 0x11, 12, 12,  CHG_ZVC },
1088   { "idiv",  "x,d->x",    "idiv16",   2, 0x10, 12, 12,  CLR_V_CHG_ZC },
1089   { "idivs", 0,           0,          2, 0x15, 12, 12,  CHG_NZVC },
1090
1091   { "lbcc",  "R",         "bcc",      4, 0x24,  3,  4,  CHG_NONE },
1092   { "lbcs",  "R",         "bcs",      4, 0x25,  3,  4,  CHG_NONE },
1093   { "lbeq",  "R",         "beq",      4, 0x27,  3,  4,  CHG_NONE },
1094   { "lbge",  "R",         "bge",      4, 0x2c,  3,  4,  CHG_NONE },
1095   { "lbgt",  "R",         "bgt",      4, 0x2e,  3,  4,  CHG_NONE },
1096   { "lbhi",  "R",         "bhi",      4, 0x22,  3,  4,  CHG_NONE },
1097   { "lble",  "R",         "ble",      4, 0x2f,  3,  4,  CHG_NONE },
1098   { "lbls",  "R",         "bls",      4, 0x23,  3,  4,  CHG_NONE },
1099   { "lblt",  "R",         "blt",      4, 0x2d,  3,  4,  CHG_NONE },
1100   { "lbmi",  "R",         "bmi",      4, 0x2b,  3,  4,  CHG_NONE },
1101   { "lbne",  "R",         "bne",      4, 0x26,  3,  4,  CHG_NONE },
1102   { "lbpl",  "R",         "bpl",      4, 0x2a,  3,  4,  CHG_NONE },
1103   { "lbra",  "R",         "bra",      4, 0x20,  4,  4,  CHG_NONE },
1104   { "lbrn",  "R",         "nop",      4, 0x21,  3,  3,  CHG_NONE },
1105   { "lbvc",  "R",         "bvc",      4, 0x28,  3,  4,  CHG_NONE },
1106   { "lbvs",  "R",         "bvs",      4, 0x29,  3,  4,  CHG_NONE },
1107
1108   { "maxa",  "[],a->a",   "max8",     3, 0x18,  4,  4,  CHG_NZVC },
1109   { "maxm",  "[],a->[]",  "max8",     3, 0x1c,  4,  4,  CHG_NZVC },
1110   { "mina",  "[],a->a",   "min8",     3, 0x19,  4,  4,  CHG_NZVC },
1111   { "minm",  "[],a->[]",  "min8",     3, 0x1d,  4,  4,  CHG_NZVC },
1112
1113   { "movb",  0,           "move8",    5, 0x0b,  4,  4,  CHG_NONE },
1114   { "movb",  0,           "move8",    4, 0x08,  4,  4,  CHG_NONE },
1115   { "movb",  0,           "move8",    6, 0x0c,  6,  6,  CHG_NONE },
1116   { "movb",  0,           "move8",    5, 0x09,  5,  5,  CHG_NONE },
1117   { "movb",  0,           "move8",    5, 0x0d,  5,  5,  CHG_NONE },
1118   { "movb",  0,           "move8",    4, 0x0a,  5,  5,  CHG_NONE },
1119
1120   { "movw",  0,           "move16",   6, 0x03,  5,  5,  CHG_NONE },
1121   { "movw",  0,           "move16",   5, 0x00,  4,  4,  CHG_NONE },
1122   { "movw",  0,           "move16",   6, 0x04,  6,  6,  CHG_NONE },
1123   { "movw",  0,           "move16",   5, 0x01,  5,  5,  CHG_NONE },
1124   { "movw",  0,           "move16",   5, 0x05,  5,  5,  CHG_NONE },
1125   { "movw",  0,           "move16",   4, 0x02,  5,  5,  CHG_NONE },
1126
1127   { "rev",  0,            0,          2, 0x3a,  _M, _M, CHG_HNZVC },
1128   { "revw", 0,            0,          2, 0x3b,  _M, _M, CHG_HNZVC },
1129   { "sba",  "b,a->a",     "sub8",     2, 0x16,  2,  2,  CHG_NZVC },
1130
1131   { "stop", 0,            0,          2, 0x3e,  2,  9,  CHG_NONE },
1132
1133   { "tab",  "a->b",       "movtst8",  2, 0x0e,  2,  2,  CLR_V_CHG_NZ },
1134   { "tba",  "b->a",       "movtst8",  2, 0x0f,  2,  2,  CLR_V_CHG_NZ },
1135
1136   { "wav",  0,            0,          2, 0x3c,  8,  _M, SET_Z_CHG_HNVC }
1137 };
1138
1139 void fatal_error (const struct m6811_opcode_def*, const char*, ...);
1140 void print (FILE*, int, const char*,...);
1141 int gen_fetch_operands (FILE*, int, const struct m6811_opcode_def*,
1142                         const char*);
1143 void gen_save_result (FILE*, int, const struct m6811_opcode_def*,
1144                       int, const char*);
1145 const struct m6811_opcode_pattern*
1146 find_opcode_pattern (const struct m6811_opcode_def*);
1147 void gen_interp (FILE*, int, const struct m6811_opcode_def*);
1148 void gen_interpreter_for_table (FILE*, int,
1149                                 const struct m6811_opcode_def*,
1150                                 int, const char*);
1151 void gen_interpreter (FILE*);
1152
1153
1154 static int indent_level = 2;
1155 static int current_insn_size = 0;
1156
1157 /* Fatal error message and exit.  This method is called when an inconsistency
1158    is detected in the generation table.  */
1159 void
1160 fatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...)
1161 {
1162   va_list argp;
1163
1164   fprintf (stderr, "Fatal error: ");
1165   va_start (argp, msg);
1166   vfprintf (stderr,  msg, argp);
1167   va_end (argp);
1168   fprintf (stderr, "\n");
1169   if (opcode)
1170     {
1171       fprintf (stderr, "Opcode: 0x%02x %s %s\n",
1172                opcode->insn_code,
1173                opcode->name ? opcode->name : "(null)",
1174                opcode->operands ? opcode->operands : "(null)");
1175     }
1176   exit (1);
1177 }
1178
1179
1180 /* Format and pretty print for the code generation.  (printf like format).  */
1181 void
1182 print (FILE *fp, int col, const char *msg, ...)
1183 {
1184   va_list argp;
1185   char buf[1024];
1186   int cur_col = -1;
1187   int i;
1188
1189   /* Format in a buffer.  */
1190   va_start (argp, msg);
1191   vsprintf (buf, msg, argp);
1192   va_end (argp);
1193
1194   /* Basic pretty print:
1195      - Every line is indented at column 'col',
1196      - Indentation is updated when '{' and '}' are found,
1197      - Indentation is incremented by the special character '@' (not displayed).
1198      - New lines inserted automatically after ';'  */
1199   for (i = 0; buf[i]; i++)
1200     {
1201       if (buf[i] == '{')
1202         col += indent_level;
1203       else if (buf[i] == '}')
1204         col -= indent_level;
1205       else if (buf[i] == '@')
1206         {
1207           col += indent_level;
1208           continue;
1209         }
1210       if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n')
1211         {
1212           cur_col = 0;
1213           while (cur_col < col)
1214             {
1215               fputc (' ', fp);
1216               cur_col++;
1217             }
1218         }
1219       if (buf[i] == '}')
1220         col -= indent_level;
1221       else if (buf[i] == '{')
1222         col += indent_level;
1223       else if (buf[i] == '\n')
1224         cur_col = -1;
1225
1226       if (cur_col != -1 || buf[i] == '\n')
1227         fputc (buf[i], fp);
1228
1229       if (buf[i] == ';')
1230         {
1231           fputc ('\n', fp);
1232           cur_col = -1;
1233         }
1234     }
1235 }
1236
1237
1238 /* Generate the code to obtain the operands before execution of the
1239    instruction.  Operands are copied in local variables.  This allows to
1240    have the same instruction pattern and different operand formats.
1241    There is a maximum of 3 variables:
1242  
1243                        8-bits          16-bits
1244    1st operand:         src8            src16
1245    2nd operand:         dst8            dst16
1246    alt operand:         addr            addr
1247   
1248    The operand string is interpreted as follows:
1249  
1250    a    Copy A register in the local 8-bits variable.
1251    b    "    B "
1252    ccr  "    ccr "
1253    d    "    D "        "      "    16-bits variable.
1254    x    "    X "
1255    y    "    Y "
1256    sp   "    SP "
1257    pc   "    PC "
1258    *    68HC11 page0 memory pointer.
1259         Get 8-bits page0 offset from program, set up 'addr' local
1260         variable to refer to the location in page0.
1261         Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1262    (x)  68HC11 indirect access with X register.
1263         Get 8-bits unsigned offset from program, set up 'addr' = X + offset.
1264         Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1265    (y)  Same as (x) with Y register.
1266    ()   68HC11 extended address mode (global variable).
1267         Get 16-bits address from program and set 'addr'.
1268         Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1269    []   68HC12 indexed addressing mode
1270    (sp) Pop
1271         Pop a 8/16-bits value from stack and set in a 8/16-bits variable.
1272    r    Relative branch
1273         Get 8-bits relative branch, compute absolute address and set 'addr'
1274    #    68HC11 immediate value
1275         Get a 8/16-bits value from program and set a 8/16-bits variable.
1276    &(x)
1277    &(y)
1278    &()  Similar to (x), (y) and () except that we don't read the
1279         value pointed to by 'addr' (ie, only 'addr' is setup). Used by jmp/jsr.
1280    &[]  Similar to [] but don't read the value pointed to by the address.
1281    ,    Operand separator.
1282    -    End of input operands.
1283   
1284    Example:
1285        (x),a->a       addr = x + (uint16) (fetch8 (proc));
1286                       src8 = a
1287        *,#,r          addr = (uint16) (fetch8 (proc))  <- Temporary 'addr'
1288                       src8 = read_mem8 (proc, addr)
1289                       dst8 = fetch8 (proc)
1290                       addr = fetch_relbranch (proc)    <- Final 'addr'
1291   
1292    Returns 1 if the 'addr' operand is set, 0 otherwise.  */
1293 int
1294 gen_fetch_operands (FILE *fp, int col,
1295                     const struct m6811_opcode_def *opcode,
1296                     const char *operand_size)
1297 {
1298   static char *vars[2] = {
1299     "src",
1300     "dst"
1301   };
1302   char c;
1303   int addr_set = 0;
1304   int cur_var = 0;
1305   const char *operands = opcode->operands;
1306   
1307   if (operands == 0)
1308     operands = "";
1309
1310   while ((c = *operands++) != 0)
1311     {
1312       switch (c)
1313         {
1314         case 'a':
1315           if (cur_var >= 2)
1316             fatal_error (opcode, "Too many locals");
1317           
1318           print (fp, col, "%s8 = cpu_get_a (proc);", vars[cur_var]);
1319           break;
1320
1321         case 'b':
1322           if (cur_var >= 2)
1323             fatal_error (opcode, "Too many locals");
1324
1325           print (fp, col, "%s8 = cpu_get_b (proc);", vars[cur_var]);
1326           break;
1327
1328         case 'd':
1329           if (cur_var >= 2)
1330             fatal_error (opcode, "Too many locals");
1331
1332           print (fp, col, "%s16 = cpu_get_d (proc);", vars[cur_var]);
1333           break;
1334
1335         case 'x':
1336           if (cur_var >= 2)
1337             fatal_error (opcode, "Too many locals");
1338
1339           print (fp, col, "%s16 = cpu_get_x (proc);", vars[cur_var]);
1340           break;
1341
1342         case 'y':
1343           if (cur_var >= 2)
1344             fatal_error (opcode, "Too many locals");
1345
1346           print (fp, col, "%s16 = cpu_get_y (proc);", vars[cur_var]);
1347           break;
1348
1349         case '*':
1350           if (cur_var >= 2)
1351             fatal_error (opcode, "Too many locals");
1352
1353           if (addr_set)
1354             fatal_error (opcode, "Wrong use of '*', 'addr' already used");
1355           
1356           addr_set = 1;
1357           current_insn_size += 1;
1358           print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
1359           print (fp, col, "%s%s = memory_read%s (proc, addr);",
1360                  vars[cur_var], operand_size, operand_size);
1361           break;
1362
1363         case '&':
1364           if (addr_set)
1365             fatal_error (opcode, "Wrong use of '&', 'addr' already used");
1366           
1367           addr_set = 1;
1368           if (strncmp (operands, "(x)", 3) == 0)
1369             {
1370               current_insn_size += 1;
1371               print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
1372               operands += 3;
1373             }
1374           else if (strncmp (operands, "(y)", 3) == 0)
1375             {
1376               current_insn_size += 1;
1377               print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
1378               operands += 3;
1379             }
1380           else if (strncmp (operands, "()", 2) == 0)
1381             {
1382               current_insn_size += 2;
1383               print (fp, col, "addr = cpu_fetch16 (proc);");
1384               operands += 2;
1385             }
1386           else if (strncmp (operands, "[]", 2) == 0)
1387             {
1388               current_insn_size += 1;
1389               print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 0);");
1390               operands += 2;
1391             }
1392           else
1393             {
1394               fatal_error (opcode, "Unknown operand");
1395             }
1396           break;
1397           
1398         case '(':
1399           if (cur_var >= 2)
1400             fatal_error (opcode, "Too many locals");
1401           
1402           if (addr_set)
1403             fatal_error (opcode, "Wrong use of '(', 'addr' already used");
1404           
1405           if (strncmp (operands, "x)", 2) == 0)
1406             {
1407               addr_set = 1;
1408               current_insn_size += 1;
1409               print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
1410               print (fp, col, "%s%s = memory_read%s (proc, addr);",
1411                      vars[cur_var], operand_size, operand_size);
1412               operands += 2;
1413             }
1414           else if (strncmp (operands, "y)", 2) == 0)
1415             {
1416               addr_set = 1;
1417               current_insn_size += 1;
1418               print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
1419               print (fp, col, "%s%s = memory_read%s (proc, addr);",
1420                      vars[cur_var], operand_size, operand_size);
1421               operands += 2;
1422             }
1423           else if (strncmp (operands, ")", 1) == 0)
1424             {
1425               addr_set = 1;
1426               current_insn_size += 2;
1427               print (fp, col, "addr = cpu_fetch16 (proc);");
1428               print (fp, col, "%s%s = memory_read%s (proc, addr);",
1429                      vars[cur_var], operand_size, operand_size);
1430               operands++;
1431             }
1432           else if (strncmp (operands, "@)", 2) == 0)
1433             {
1434               current_insn_size += 2;
1435               print (fp, col, "addr = cpu_fetch16 (proc);");
1436               print (fp, col, "%s%s = memory_read%s (proc, addr);",
1437                      vars[cur_var], operand_size, operand_size);
1438               operands += 2;
1439             }
1440           else if (strncmp (operands, "sp)", 3) == 0)
1441             {
1442               print (fp, col, "%s%s = cpu_%s_pop_uint%s (proc);",
1443                      vars[cur_var], operand_size,
1444                      cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1445                      operand_size);
1446               operands += 3;
1447             }
1448           else
1449             {
1450               fatal_error (opcode, "Unknown operand");
1451             }
1452           break;
1453
1454         case '[':
1455           if (cur_var >= 2)
1456             fatal_error (opcode, "Too many locals");
1457           
1458           if (addr_set)
1459             fatal_error (opcode, "Wrong use of '[', 'addr' already used");
1460           
1461           if (strncmp (operands, "]", 1) == 0)
1462             {
1463               addr_set = 1;
1464               current_insn_size += 1;
1465               print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
1466               print (fp, col, "%s%s = memory_read%s (proc, addr);",
1467                      vars[cur_var], operand_size, operand_size);
1468               operands += 1;
1469             }
1470           else if (strncmp (operands, "]", 1) == 0)
1471             {
1472               current_insn_size += 1;
1473               print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc,0);",
1474                      vars[cur_var], operand_size, operand_size);
1475               operands += 1;
1476             }
1477           else
1478             {
1479               fatal_error (opcode, "Unknown operand");
1480             }
1481           break;
1482
1483         case '{':
1484           if (cur_var >= 2)
1485             fatal_error (opcode, "Too many locals");
1486           
1487           if (addr_set)
1488             fatal_error (opcode, "Wrong use of '{', 'addr' already used");
1489           
1490           if (strncmp (operands, "}", 1) == 0)
1491             {
1492               current_insn_size += 1;
1493               print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc, 1);",
1494                      vars[cur_var], operand_size, operand_size);
1495               operands += 1;
1496             }
1497           else
1498             {
1499               fatal_error (opcode, "Unknown operand");
1500             }
1501           break;
1502
1503         case 's':
1504           if (cur_var >= 2)
1505             fatal_error (opcode, "Too many locals");
1506           
1507           if (strncmp (operands, "p", 1) == 0)
1508             {
1509               print (fp, col, "%s16 = cpu_get_sp (proc);", vars[cur_var]);
1510               operands++;
1511             }
1512           else
1513             {
1514               fatal_error (opcode, "Unknown operands");
1515             }
1516           break;
1517
1518         case 'c':
1519           if (strncmp (operands, "cr", 2) == 0)
1520             {
1521               print (fp, col, "%s8 = cpu_get_ccr (proc);", vars[cur_var]);
1522               operands += 2;
1523             }
1524           else
1525             {
1526               fatal_error (opcode, "Unknown operands");
1527             }
1528           break;
1529           
1530         case 'r':
1531           if (addr_set && cur_var != 2)
1532             fatal_error (opcode, "Wrong use of 'r'");
1533
1534           addr_set = 1;
1535           current_insn_size += 1;
1536           print (fp, col, "addr = cpu_fetch_relbranch (proc);");
1537           break;
1538
1539         case 'R':
1540           if (addr_set && cur_var != 2)
1541             fatal_error (opcode, "Wrong use of 'R'");
1542
1543           addr_set = 1;
1544           current_insn_size += 2;
1545           print (fp, col, "addr = cpu_fetch_relbranch16 (proc);");
1546           break;
1547
1548         case '#':
1549           if (strcmp (operand_size, "8") == 0)
1550             {
1551               current_insn_size += 1;
1552             }
1553           else
1554             {
1555               current_insn_size += 2;
1556             }
1557           print (fp, col, "%s%s = cpu_fetch%s (proc);", vars[cur_var],
1558                  operand_size, operand_size);
1559           break;
1560           
1561         case ',':
1562           cur_var ++;
1563           break;
1564
1565         case '-':
1566           return addr_set;
1567
1568         default:
1569           fatal_error (opcode, "Invalid operands");
1570           break;
1571         }
1572     }
1573   return addr_set;
1574 }
1575
1576
1577 /* Generate the code to save the instruction result.  The result is in
1578    a local variable: either 'dst8' or 'dst16'.
1579    There may be only one result.  Instructions with 2 results (ie idiv
1580    and fdiv), take care of saving the first value.
1581   
1582    The operand string is the same as for 'gen_fetch_operands'.
1583    Everything before '->' is ignored.  If the '->' is not found, it
1584    is assumed that there is nothing to save.  After '->', the operand
1585    string is interpreted as follows:
1586   
1587    a    Save 'dst8' in A register
1588    b    "              B "
1589    ccr  "              CCR "
1590    d    "    'dst16'   D "
1591    x    "              X "
1592    y    "              Y "
1593    sp   "              SP "
1594    *    68HC11 page0 memory pointer.
1595    (x)  68HC11 indirect access with X register.
1596    (y)  Same as (x) with Y register.
1597    ()   68HC11 extended address mode (global variable).
1598         For these modes, if they were used as an input operand,
1599         the 'addr' variable contains the address of memory where
1600         the result must be saved.
1601         If they were not used an input operand, 'addr' is computed
1602         (as in gen_fetch_operands()), and the result is saved.
1603    []   68HC12 indexed indirect
1604    (sp) Push
1605         Push the 8/16-bits result on the stack.  */
1606 void
1607 gen_save_result (FILE *fp, int col,
1608                  const struct m6811_opcode_def *opcode,
1609                  int addr_set,
1610                  const char *operand_size)
1611 {
1612   char c;
1613   const char *operands = opcode->operands;
1614
1615   /* When the result is saved, 'result_size' is a string which
1616      indicates the size of the saved result ("8" or "16").  This
1617      is a sanity check with 'operand_size' to detect inconsistencies
1618      in the different tables.  */
1619   const char *result_size = 0;
1620   
1621   if (operands == 0)
1622     operands = "";
1623
1624   operands = strchr (operands, '-');
1625   if (operands == 0)
1626     return;
1627
1628   operands++;
1629   if (*operands++ != '>')
1630     {
1631       fatal_error (opcode, "Invalid operand");
1632     }
1633
1634   c = *operands++;
1635   switch (c)
1636     {
1637     case 'a':
1638       result_size = "8";
1639       print (fp, col, "cpu_set_a (proc, dst8);");
1640       break;
1641
1642     case 'b':
1643       result_size = "8";
1644       print (fp, col, "cpu_set_b (proc, dst8);");
1645       break;
1646
1647     case 'd':
1648       result_size = "16";
1649       print (fp, col, "cpu_set_d (proc, dst16);");
1650       break;
1651
1652     case 'x':
1653       result_size = "16";
1654       print (fp, col, "cpu_set_x (proc, dst16);");
1655       break;
1656
1657     case 'y':
1658       result_size = "16";
1659       print (fp, col, "cpu_set_y (proc, dst16);");
1660       break;
1661
1662     case '*':
1663       if (addr_set == 0)
1664         {
1665           current_insn_size += 1;
1666           print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
1667         }
1668       result_size = operand_size;
1669       print (fp, col, "memory_write%s (proc, addr, dst%s);",
1670              operand_size, operand_size);
1671       break;
1672
1673     case '(':
1674       if (strncmp (operands, "x)", 2) == 0)
1675         {
1676           if (addr_set == 0)
1677             {
1678               current_insn_size += 1;
1679               print (fp, col, "addr = cpu_get_x (proc) + cpu_fetch8 (proc);");
1680             }
1681           print (fp, col, "memory_write%s (proc, addr, dst%s);",
1682                  operand_size, operand_size);
1683           operands += 2;
1684           result_size = operand_size;
1685         }
1686       else if (strncmp (operands, "y)", 2) == 0)
1687         {
1688           if (addr_set == 0)
1689             {
1690               current_insn_size += 1;
1691               print (fp, col, "addr = cpu_get_y (proc) + cpu_fetch8 (proc);");
1692             }
1693           print (fp, col, "memory_write%s (proc, addr, dst%s);",
1694                  operand_size, operand_size);
1695           operands += 2;
1696           result_size = operand_size;
1697         }
1698       else if (strncmp (operands, ")", 1) == 0)
1699         {
1700           if (addr_set == 0)
1701             {
1702               current_insn_size += 2;
1703               print (fp, col, "addr = cpu_fetch16 (proc);");
1704             }
1705           print (fp, col, "memory_write%s (proc, addr, dst%s);",
1706                  operand_size, operand_size);
1707           operands++;
1708           result_size = operand_size;
1709         }
1710       else if (strncmp (operands, "sp)", 3) == 0)
1711         {
1712           print (fp, col, "cpu_%s_push_uint%s (proc, dst%s);",
1713                  cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1714                  operand_size, operand_size);
1715           operands += 3;
1716           result_size = operand_size;
1717         }
1718       else
1719         {
1720           fatal_error (opcode, "Invalid operand");
1721         }
1722       break;
1723
1724     case '[':
1725       if (strncmp (operands, "]", 1) == 0)
1726         {
1727           if (addr_set == 0)
1728             {
1729               current_insn_size += 1;
1730               print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
1731             }
1732           print (fp, col, "memory_write%s (proc, addr, dst%s);",
1733                  operand_size, operand_size);
1734           operands++;
1735           result_size = operand_size;
1736         }
1737       else
1738         {
1739           fatal_error (opcode, "Invalid operand");
1740         }
1741       break;
1742       
1743     case '{':
1744       if (strncmp (operands, "}", 1) == 0)
1745         {
1746           current_insn_size += 1;
1747           print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 1);");
1748           print (fp, col, "memory_write%s (proc, addr, dst%s);",
1749                  operand_size, operand_size);
1750           operands++;
1751           result_size = operand_size;
1752         }
1753       else
1754         {
1755           fatal_error (opcode, "Invalid operand");
1756         }
1757       break;
1758       
1759     case 's':
1760       if (strncmp (operands, "p", 1) == 0)
1761         {
1762           print (fp, col, "cpu_set_sp (proc, dst16);");
1763           operands++;
1764           result_size = "16";
1765         }
1766       else
1767         {
1768           fatal_error (opcode, "Invalid operand");
1769         }
1770       break;
1771
1772     case 'c':
1773       if (strncmp (operands, "cr", 2) == 0)
1774         {
1775           print (fp, col, "cpu_set_ccr (proc, dst8);");
1776           operands += 2;
1777           result_size = "8";
1778         }
1779       else
1780         {
1781           fatal_error (opcode, "Invalid operand");
1782         }
1783       break;
1784           
1785     default:
1786       fatal_error (opcode, "Invalid operand");
1787       break;
1788     }
1789
1790   if (*operands != 0)
1791     fatal_error (opcode, "Garbage at end of operand");
1792   
1793   if (result_size == 0)
1794     fatal_error (opcode, "? No result seems to be saved");
1795
1796   if (strcmp (result_size, operand_size) != 0)
1797     fatal_error (opcode, "Result saved different than pattern size");
1798 }
1799
1800
1801 /* Find the instruction pattern for a given instruction.  */
1802 const struct m6811_opcode_pattern*
1803 find_opcode_pattern (const struct m6811_opcode_def *opcode)
1804 {
1805   int i;
1806   const char *pattern = opcode->insn_pattern;
1807   
1808   if (pattern == 0)
1809     {
1810       pattern = opcode->name;
1811     }
1812   for (i = 0; i < TABLE_SIZE(m6811_opcode_patterns); i++)
1813     {
1814       if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
1815         {
1816           return &m6811_opcode_patterns[i];
1817         }
1818     }
1819   fatal_error (opcode, "Unknown instruction pattern");
1820   return 0;
1821 }
1822
1823 /* Generate the code for interpretation of instruction 'opcode'.  */
1824 void
1825 gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
1826 {
1827   const char *operands = opcode->operands;
1828   int addr_set;
1829   const char *pattern = opcode->insn_pattern;
1830   const struct m6811_opcode_pattern *op;
1831   const char *operand_size;
1832   
1833   if (pattern == 0)
1834     {
1835       pattern = opcode->name;
1836     }
1837
1838   /* Find out the size of the operands: 8 or 16-bits.  */
1839   if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
1840     {
1841       operand_size = "8";
1842     }
1843   else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
1844     {
1845       operand_size = "16";
1846     }
1847   else
1848     {
1849       operand_size = "";
1850     }
1851   
1852   if (operands == 0)
1853     operands = "";
1854
1855   /* Generate entry point for the instruction.  */
1856   print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
1857          opcode->name, operands);
1858   col += indent_level;
1859
1860   /* Generate the code to get the instruction operands.  */
1861   addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
1862
1863   /* Generate instruction interpretation.  */
1864   op = find_opcode_pattern (opcode);
1865   if (op->pattern)
1866     {
1867       print (fp, col, "%s;", op->pattern);
1868     }
1869
1870   /* Generate the code to save the result.  */
1871   gen_save_result (fp, col, opcode, addr_set, operand_size);
1872
1873   /* For some instructions, generate the code to update the flags.  */
1874   if (op && op->ccr_update)
1875     {
1876       print (fp, col, "%s;", op->ccr_update);
1877     }
1878   print (fp, col, "break;");
1879 }
1880
1881
1882 /* Generate the interpretor for a given 68HC11 page set.  */
1883 void
1884 gen_interpreter_for_table (FILE *fp, int col,
1885                            const struct m6811_opcode_def *table,
1886                            int size,
1887                            const char *cycles_table_name)
1888 {
1889   int i;
1890   int init_size;
1891
1892   init_size = table == m6811_page1_opcodes
1893     || table == m6812_page1_opcodes? 1 : 2;
1894   
1895   /* Get the opcode and dispatch directly.  */
1896   print (fp, col, "op = cpu_fetch8 (proc);");
1897   print (fp, col, "cpu_add_cycles (proc, %s[op]);", cycles_table_name);
1898   
1899   print (fp, col, "switch (op)\n");
1900   col += indent_level;
1901   print (fp, col, "{\n");
1902   
1903   for (i = 0; i < size; i++)
1904     {
1905       /* The table contains duplicate entries (ie, instruction aliases).  */
1906       if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
1907         continue;
1908
1909       current_insn_size = init_size;
1910       gen_interp (fp, col, &table[i]);
1911 #if 0
1912       if (current_insn_size != table[i].insn_size)
1913         {
1914           fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
1915                        current_insn_size, table[i].insn_size);
1916         }
1917 #endif
1918     }
1919
1920   print (fp, col, "default:\n");
1921   print (fp, col + indent_level, "cpu_special (proc, M6811_ILLEGAL);");
1922   print (fp, col + indent_level, "break;");
1923   print (fp, col, "}\n");
1924 }
1925
1926 /* Generate the table of instruction cycle.  These tables are indexed
1927    by the opcode number to allow a fast cycle time computation.  */
1928 void
1929 gen_cycle_table (FILE *fp, const char *name,
1930                  const struct m6811_opcode_def *table,
1931                  int size)
1932 {
1933   int i;
1934   char cycles[256];
1935   int page1;
1936
1937   page1 = table == m6811_page1_opcodes;
1938
1939   /* Build the cycles table.  The table is indexed by the opcode.  */
1940   memset (cycles, 0, sizeof (cycles));
1941   while (--size >= 0)
1942     {
1943       if (table->insn_min_cycles > table->insn_max_cycles)
1944         fatal_error (table, "Wrong insn cycles");
1945
1946       if (table->insn_max_cycles == _M)
1947         cycles[table->insn_code] = table->insn_min_cycles;
1948       else
1949         cycles[table->insn_code] = table->insn_max_cycles;
1950
1951       table++;
1952     }
1953
1954   /* Some check: for the page1 opcode, the cycle type of the page2/3/4
1955      opcode must be 0.  */
1956   if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
1957                 || cycles[M6811_OPCODE_PAGE3] != 0
1958                 || cycles[M6811_OPCODE_PAGE4] != 0))
1959       fatal_error (0, "Invalid cycle table");
1960
1961   /* Generates the cycles table.  */
1962   print (fp, 0, "static const unsigned char %s[256] = {\n", name);
1963   for (i = 0; i < 256; i++)
1964     {
1965       if ((i % 16) == 0)
1966         {
1967           print (fp, indent_level, "/* %3d */ ", i);
1968         }
1969       fprintf (fp, "%2d", cycles[i]);
1970       if (i != 255)
1971         fprintf (fp, ",");
1972
1973       if ((i % 16) != 15)
1974         fprintf (fp, " ");
1975       else
1976         fprintf (fp, "\n");
1977     }
1978   print (fp, 0, "};\n\n");
1979 }
1980
1981 #define USE_SRC8 1
1982 #define USE_DST8 2
1983
1984 void
1985 gen_function_entry (FILE *fp, const char *name, int locals)
1986 {
1987   /* Generate interpretor entry point.  */
1988   print (fp, 0, "%s (proc)\n", name);
1989   print (fp, indent_level, "struct _sim_cpu* proc;");
1990   print (fp, indent_level, "{\n");
1991
1992   /* Interpretor local variables.  */
1993   print (fp, indent_level, "unsigned char op;");
1994   print (fp, indent_level, "uint16 addr, src16, dst16;");
1995   if (locals & USE_SRC8)
1996     print (fp, indent_level, "uint8 src8;\n");
1997   if (locals & USE_DST8)
1998     print (fp, indent_level, "uint8 dst8;\n");
1999 }
2000
2001 void
2002 gen_function_close (FILE *fp)
2003 {
2004   print (fp, 0, "}\n");
2005 }
2006
2007 int
2008 cmp_opcode (void* e1, void* e2)
2009 {
2010   struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
2011   struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
2012   
2013   return (int) (op1->insn_code) - (int) (op2->insn_code);
2014 }
2015
2016 void
2017 prepare_table (struct m6811_opcode_def* table, int size)
2018 {
2019   int i;
2020   
2021   qsort (table, size, sizeof (table[0]), cmp_opcode);
2022   for (i = 1; i < size; i++)
2023     {
2024       if (table[i].insn_code == table[i-1].insn_code)
2025         {
2026           fprintf (stderr, "Two insns with code 0x%02x\n",
2027                    table[i].insn_code);
2028         }
2029     }
2030 }
2031
2032 void
2033 gen_interpreter (FILE *fp)
2034 {
2035   int col = 0;
2036
2037   prepare_table (m6811_page1_opcodes, TABLE_SIZE (m6811_page1_opcodes));
2038   prepare_table (m6811_page2_opcodes, TABLE_SIZE (m6811_page2_opcodes));
2039   prepare_table (m6811_page3_opcodes, TABLE_SIZE (m6811_page3_opcodes));
2040   prepare_table (m6811_page4_opcodes, TABLE_SIZE (m6811_page4_opcodes));
2041
2042   prepare_table (m6812_page1_opcodes, TABLE_SIZE (m6812_page1_opcodes));
2043   prepare_table (m6812_page2_opcodes, TABLE_SIZE (m6812_page2_opcodes));
2044
2045   /* Generate header of interpretor.  */
2046   print (fp, col, "/* File generated automatically by gencode. */\n");
2047   print (fp, col, "#include \"sim-main.h\"\n\n");
2048
2049   if (cpu_type & cpu6811)
2050     {
2051       gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
2052                        TABLE_SIZE (m6811_page1_opcodes));
2053       gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
2054                        TABLE_SIZE (m6811_page2_opcodes));
2055       gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
2056                        TABLE_SIZE (m6811_page3_opcodes));
2057       gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
2058                        TABLE_SIZE (m6811_page4_opcodes));
2059
2060       gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
2061       gen_interpreter_for_table (fp, indent_level,
2062                                  m6811_page3_opcodes,
2063                                  TABLE_SIZE(m6811_page3_opcodes),
2064                                  "cycles_page3");
2065       gen_function_close (fp);
2066   
2067       gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
2068       gen_interpreter_for_table (fp, indent_level,
2069                                  m6811_page4_opcodes,
2070                                  TABLE_SIZE(m6811_page4_opcodes),
2071                                  "cycles_page4");
2072       gen_function_close (fp);
2073
2074       /* Generate the page 2, 3 and 4 handlers.  */
2075       gen_function_entry (fp, "static void\ncpu_page2_interp",
2076                           USE_SRC8 | USE_DST8);
2077       gen_interpreter_for_table (fp, indent_level,
2078                                  m6811_page2_opcodes,
2079                                  TABLE_SIZE(m6811_page2_opcodes),
2080                                  "cycles_page2");
2081       gen_function_close (fp);
2082
2083       /* Generate the interpretor entry point.  */
2084       gen_function_entry (fp, "void\ncpu_interp_m6811",
2085                           USE_SRC8 | USE_DST8);
2086
2087       gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
2088                                  TABLE_SIZE(m6811_page1_opcodes),
2089                                  "cycles_page1");
2090       gen_function_close (fp);
2091     }
2092   else
2093     {
2094       gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
2095                        TABLE_SIZE (m6812_page1_opcodes));
2096       gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
2097                        TABLE_SIZE (m6812_page2_opcodes));
2098
2099       gen_function_entry (fp, "static void\ncpu_page2_interp",
2100                           USE_SRC8 | USE_DST8);
2101       gen_interpreter_for_table (fp, indent_level,
2102                                  m6812_page2_opcodes,
2103                                  TABLE_SIZE(m6812_page2_opcodes),
2104                                  "cycles_page2");
2105       gen_function_close (fp);
2106
2107       /* Generate the interpretor entry point.  */
2108       gen_function_entry (fp, "void\ncpu_interp_m6812",
2109                           USE_SRC8 | USE_DST8);
2110
2111       gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
2112                                  TABLE_SIZE(m6812_page1_opcodes),
2113                                  "cycles_page1");
2114       gen_function_close (fp);
2115     }
2116 }
2117
2118 void
2119 usage (char* prog)
2120 {
2121   fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
2122   exit (2);
2123 }
2124
2125 int
2126 main (int argc, char *argv[])
2127 {
2128   int i;
2129
2130   for (i = 1; i < argc; i++)
2131     {
2132       if (strcmp (argv[i], "-m6811") == 0)
2133         cpu_type = cpu6811;
2134       else if (strcmp (argv[i], "-m6812") == 0)
2135         cpu_type = cpu6812;
2136       else
2137         {
2138           usage (argv[0]);
2139         }
2140     }
2141   if (cpu_type == 0)
2142     usage (argv[0]);
2143   
2144   gen_interpreter (stdout);
2145   if (fclose (stdout) != 0)
2146     {
2147       fprintf (stderr, "Error while generating the interpreter: %d\n",
2148                errno);
2149       return 1;
2150     }
2151   return 0;
2152 }