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
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/* 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
76static int cpu_type;
77
78struct 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 */
92struct 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| \
145M6811_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| \
148M6811_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);\
173dst8 = dst8 - src8", 0 },
174  { "add8", "cpu_ccr_update_add8 (cpu, dst8 + src8, dst8, src8);\
175dst8 = 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\
181else\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\
191else\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);\
206dst16 = dst16 - src16", 0 },
207  { "add16", "cpu_ccr_update_add16 (cpu, dst16 + src16, dst16, src16);\
208dst16 = 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\
241dst16 = 0xffff;\
242}\nelse\n{\n\
243cpu_set_d (cpu, dst16 % src16);\
244dst16 = dst16 / src16;\
245}",
246  "cpu_set_ccr_Z (cpu, dst16 == 0); cpu_set_ccr_V (cpu, 0);\
247cpu_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\
253dst16 = 0xffff;\n\
254cpu_set_ccr_Z (cpu, 0);\n\
255cpu_set_ccr_V (cpu, 1);\n\
256cpu_set_ccr_C (cpu, dst16 == 0);\n\
257}\nelse\n{\n\
258unsigned long l = (unsigned long) (dst16) << 16;\n\
259cpu_set_d (cpu, (uint16_t) (l % (unsigned long) (src16)));\n\
260dst16 = (uint16_t) (l / (unsigned long) (src16));\n\
261cpu_set_ccr_V (cpu, 0);\n\
262cpu_set_ccr_C (cpu, 0);\n\
263cpu_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.  */
327struct 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 */
361struct 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 */
615struct 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 */
690struct 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 */
708struct 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 */
724struct 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
1073struct 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
1141void fatal_error (const struct m6811_opcode_def*, const char*, ...);
1142void print (FILE*, int, const char*,...);
1143int gen_fetch_operands (FILE*, int, const struct m6811_opcode_def*,
1144			const char*);
1145void gen_save_result (FILE*, int, const struct m6811_opcode_def*,
1146		      int, const char*);
1147const struct m6811_opcode_pattern*
1148find_opcode_pattern (const struct m6811_opcode_def*);
1149void gen_interp (FILE*, int, const struct m6811_opcode_def*);
1150void gen_interpreter_for_table (FILE*, int,
1151				const struct m6811_opcode_def*,
1152				int, const char*);
1153void gen_interpreter (FILE*);
1154
1155
1156static int indent_level = 2;
1157static 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.	 */
1161void
1162fatal_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).  */
1183void
1184print (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.	 */
1295int
1296gen_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.	 */
1611void
1612gen_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.  */
1807const struct m6811_opcode_pattern*
1808find_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'.  */
1829void
1830gen_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.  */
1888void
1889gen_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.	 */
1933void
1934gen_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
1989void
1990gen_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
2005void
2006gen_function_close (FILE *fp)
2007{
2008  print (fp, 0, "}\n");
2009}
2010
2011int
2012cmp_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
2020void
2021prepare_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
2036void
2037gen_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
2122void
2123usage (char* prog)
2124{
2125  fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
2126  exit (2);
2127}
2128
2129int
2130main (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