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