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