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