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