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