1/* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
2   Copyright 1999, 2000, 2001, 2002, 2007 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 <string.h>
22#include <stdarg.h>
23#include <errno.h>
24
25#include "ansidecl.h"
26#include "opcode/m68hc11.h"
27
28#define TABLE_SIZE(X)	    (sizeof(X) / sizeof(X[0]))
29
30/* Combination of CCR flags.  */
31#define M6811_ZC_BIT	M6811_Z_BIT|M6811_C_BIT
32#define M6811_NZ_BIT	M6811_N_BIT|M6811_Z_BIT
33#define M6811_NZV_BIT	M6811_N_BIT|M6811_Z_BIT|M6811_V_BIT
34#define M6811_NZC_BIT	M6811_N_BIT|M6811_Z_BIT|M6811_C_BIT
35#define M6811_NVC_BIT	M6811_N_BIT|M6811_V_BIT|M6811_C_BIT
36#define M6811_ZVC_BIT	M6811_Z_BIT|M6811_V_BIT|M6811_C_BIT
37#define M6811_NZVC_BIT	M6811_ZVC_BIT|M6811_N_BIT
38#define M6811_HNZVC_BIT M6811_NZVC_BIT|M6811_H_BIT
39#define M6811_HNVC_BIT  M6811_NVC_BIT|M6811_H_BIT
40#define M6811_VC_BIT    M6811_V_BIT|M6811_C_BIT
41
42/* Flags when the insn only changes some CCR flags.  */
43#define CHG_NONE	0,0,0
44#define CHG_Z		0,0,M6811_Z_BIT
45#define CHG_C		0,0,M6811_C_BIT
46#define CHG_ZVC		0,0,M6811_ZVC_BIT
47#define CHG_NZC         0,0,M6811_NZC_BIT
48#define CHG_NZV		0,0,M6811_NZV_BIT
49#define CHG_NZVC	0,0,M6811_NZVC_BIT
50#define CHG_HNZVC	0,0,M6811_HNZVC_BIT
51#define CHG_ALL		0,0,0xff
52
53/* The insn clears and changes some flags.  */
54#define CLR_I		0,M6811_I_BIT,0
55#define CLR_C		0,M6811_C_BIT,0
56#define CLR_V		0,M6811_V_BIT,0
57#define CLR_V_CHG_ZC	0,M6811_V_BIT,M6811_ZC_BIT
58#define CLR_V_CHG_NZ	0,M6811_V_BIT,M6811_NZ_BIT
59#define CLR_V_CHG_ZVC	0,M6811_V_BIT,M6811_ZVC_BIT
60#define CLR_N_CHG_ZVC	0,M6811_N_BIT,M6811_ZVC_BIT /* Used by lsr */
61#define CLR_VC_CHG_NZ   0,M6811_VC_BIT,M6811_NZ_BIT
62
63/* The insn sets some flags.  */
64#define SET_I		M6811_I_BIT,0,0
65#define SET_C		M6811_C_BIT,0,0
66#define SET_V		M6811_V_BIT,0,0
67#define SET_Z_CLR_NVC	M6811_Z_BIT,M6811_NVC_BIT,0
68#define SET_C_CLR_V_CHG_NZ M6811_C_BIT,M6811_V_BIT,M6811_NZ_BIT
69#define SET_Z_CHG_HNVC  M6811_Z_BIT,0,M6811_HNVC_BIT
70
71#define _M 0xff
72
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 (proc, dst8)" },
93  { "movtst16", "dst16 = src16", "cpu_ccr_update_tst16 (proc, dst16)" },
94  { "mov8",	"dst8 = src8" },
95  { "mov16",	"dst16 = src16" },
96  { "lea16",	"dst16 = addr" },
97
98  /* Conditional branches.  'addr' is the address of the branch.  */
99  { "bra", "cpu_set_pc (proc, addr)" },
100  { "bhi",
101   "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)) == 0)\n@ \
102     cpu_set_pc (proc, addr)" },
103  { "bls",
104    "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)))\n@ \
105     cpu_set_pc (proc, addr)" },
106  { "bcc", "if (!cpu_get_ccr_C (proc))\n@ cpu_set_pc (proc, addr)" },
107  { "bcs", "if (cpu_get_ccr_C (proc))\n@ cpu_set_pc (proc, addr)" },
108  { "bne", "if (!cpu_get_ccr_Z (proc))\n@ cpu_set_pc (proc, addr)" },
109  { "beq", "if (cpu_get_ccr_Z (proc))\n@ cpu_set_pc (proc, addr)" },
110  { "bvc", "if (!cpu_get_ccr_V (proc))\n@ cpu_set_pc (proc, addr)" },
111  { "bvs", "if (cpu_get_ccr_V (proc))\n@ cpu_set_pc (proc, addr)" },
112  { "bpl", "if (!cpu_get_ccr_N (proc))\n@ cpu_set_pc (proc, addr)" },
113  { "bmi", "if (cpu_get_ccr_N (proc))\n@ cpu_set_pc (proc, addr)" },
114  { "bge", "if ((cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc)) == 0)\n@ cpu_set_pc (proc, addr)" },
115  { "blt", "if ((cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc)))\n@ cpu_set_pc (proc, addr)" },
116  { "bgt",
117    "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))) == 0)\n@ \
118     cpu_set_pc (proc, addr)" },
119  { "ble",
120    "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))))\n@ \
121     cpu_set_pc (proc, addr)" },
122
123  /* brclr and brset perform a test and a conditional jump at the same
124     time.  Flags are not changed.  */
125  { "brclr8",
126    "if ((src8 & dst8) == 0)\n@	 cpu_set_pc (proc, addr)" },
127  { "brset8",
128    "if (((~src8) & dst8) == 0)\n@  cpu_set_pc (proc, addr)" },
129
130
131  { "rts11",  "addr = cpu_m68hc11_pop_uint16 (proc); cpu_set_pc (proc, addr); cpu_return(proc)" },
132  { "rts12",  "addr = cpu_m68hc12_pop_uint16 (proc); cpu_set_pc (proc, addr); cpu_return(proc)" },
133
134  { "mul16", "dst16 = ((uint16) src8 & 0x0FF) * ((uint16) dst8 & 0x0FF)",
135    "cpu_set_ccr_C (proc, src8 & 0x80)" },
136  { "neg8", "dst8 = - src8",
137    "cpu_set_ccr_C (proc, src8 == 0); cpu_ccr_update_tst8 (proc, dst8)" },
138  { "com8", "dst8 = ~src8",
139    "cpu_set_ccr_C (proc, 1); cpu_ccr_update_tst8 (proc, dst8);" },
140  { "clr8", "dst8 = 0",
141    "cpu_set_ccr (proc, (cpu_get_ccr (proc) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
142M6811_I_BIT)) | M6811_Z_BIT)"},
143  { "clr16","dst16 = 0",
144    "cpu_set_ccr (proc, (cpu_get_ccr (proc) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
145M6811_I_BIR)) | M6811_Z_BIT)"},
146
147  /* 8-bits shift and rotation.	 */
148  { "lsr8",  "dst8 = src8 >> 1",
149    "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
150  { "lsl8",  "dst8 = src8 << 1",
151    "cpu_set_ccr_C (proc, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (proc, dst8)" },
152  { "asr8",  "dst8 = (src8 >> 1) | (src8 & 0x80)",
153    "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
154  { "ror8",  "dst8 = (src8 >> 1) | (cpu_get_ccr_C (proc) << 7)",
155    "cpu_set_ccr_C (proc, src8 & 1); cpu_ccr_update_shift8 (proc, dst8)" },
156  { "rol8",  "dst8 = (src8 << 1) | (cpu_get_ccr_C (proc))",
157    "cpu_set_ccr_C (proc, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (proc, dst8)" },
158
159  /* 16-bits shift instructions.  */
160  { "lsl16",  "dst16 = src16 << 1",
161    "cpu_set_ccr_C (proc, (src16&0x8000) >> 15); cpu_ccr_update_shift16 (proc, dst16)"},
162  { "lsr16",  "dst16 = src16 >> 1",
163    "cpu_set_ccr_C (proc, src16 & 1); cpu_ccr_update_shift16 (proc, dst16)"},
164
165  { "dec8", "dst8 = src8 - 1", "cpu_ccr_update_tst8 (proc, dst8)" },
166  { "inc8", "dst8 = src8 + 1", "cpu_ccr_update_tst8 (proc, dst8)" },
167  { "tst8", 0, "cpu_set_ccr_C (proc, 0); cpu_ccr_update_tst8 (proc, src8)" },
168
169  { "sub8", "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
170dst8 = dst8 - src8", 0 },
171  { "add8", "cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\
172dst8 = dst8 + src8", 0 },
173  { "sbc8", "if (cpu_get_ccr_C (proc))\n@ \
174{\n\
175  cpu_ccr_update_sub8 (proc, dst8 - src8 - 1, dst8, src8);\n\
176  dst8 = dst8 - src8 - 1;\n\
177}\n\
178else\n\
179{\n\
180  cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\n\
181  dst8 = dst8 - src8;\n\
182}", 0 },
183  { "adc8", "if (cpu_get_ccr_C (proc))\n@ \
184{\n\
185  cpu_ccr_update_add8 (proc, dst8 + src8 + 1, dst8, src8);\n\
186  dst8 = dst8 + src8 + 1;\n\
187}\n\
188else\n\
189{\n\
190  cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\n\
191  dst8 = dst8 + src8;\n\
192}",
193    0 },
194
195  /* 8-bits logical operations.	 */
196  { "and8", "dst8 = dst8 & src8", "cpu_ccr_update_tst8 (proc, dst8)" },
197  { "eor8", "dst8 = dst8 ^ src8", "cpu_ccr_update_tst8 (proc, dst8)" },
198  { "or8",  "dst8 = dst8 | src8", "cpu_ccr_update_tst8 (proc, dst8)" },
199  { "bclr8","dst8 = (~dst8) & src8", "cpu_ccr_update_tst8 (proc, dst8)" },
200
201  /* 16-bits add and subtract instructions.  */
202  { "sub16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
203dst16 = dst16 - src16", 0 },
204  { "add16", "cpu_ccr_update_add16 (proc, dst16 + src16, dst16, src16);\
205dst16 = dst16 + src16", 0 },
206  { "inc16", "dst16 = src16 + 1", "cpu_set_ccr_Z (proc, dst16 == 0)" },
207  { "dec16", "dst16 = src16 - 1", "cpu_set_ccr_Z (proc, dst16 == 0)" },
208
209  /* Special increment/decrement for the stack pointer:
210     flags are not changed.  */
211  { "ins16", "dst16 = src16 + 1" },
212  { "des16", "dst16 = src16 - 1" },
213
214  { "jsr_11_16", "cpu_m68hc11_push_uint16 (proc, cpu_get_pc (proc)); cpu_call (proc, addr)"},
215  { "jsr_12_16", "cpu_m68hc12_push_uint16 (proc, cpu_get_pc (proc)); cpu_call (proc, addr)"},
216
217  /* xgdx and xgdx patterns. Flags are not changed.  */
218  { "xgdxy16", "dst16 = cpu_get_d (proc); cpu_set_d (proc, src16)"},
219  { "stop", "cpu_special (proc, M6811_STOP)"},
220
221  /* tsx, tsy, txs, tys don't affect the flags.	 Sp value is corrected
222     by +/- 1.	*/
223  { "tsxy16", "dst16 = src16 + 1;"},
224  { "txys16", "dst16 = src16 - 1;"},
225
226  /* Add b to X or Y with an unsigned extension 8->16.	Flags not changed.  */
227  { "abxy16","dst16 = dst16 + (uint16) src8"},
228
229  /* After 'daa', the Z flag is undefined. Mark it as changed.	*/
230  { "daa8",  "cpu_special (proc, M6811_DAA)" },
231  { "nop",  0 },
232
233
234  /* Integer divide:
235     (parallel (set IX (div D IX))
236	       (set D  (mod D IX)))  */
237  { "idiv16", "if (src16 == 0)\n{\n\
238dst16 = 0xffff;\
239}\nelse\n{\n\
240cpu_set_d (proc, dst16 % src16);\
241dst16 = dst16 / src16;\
242}",
243  "cpu_set_ccr_Z (proc, dst16 == 0); cpu_set_ccr_V (proc, 0);\
244cpu_set_ccr_C (proc, src16 == 0)" },
245
246  /* Fractional divide:
247     (parallel (set IX (div (mul D 65536) IX)
248	       (set D  (mod (mul D 65536) IX))))  */
249  { "fdiv16", "if (src16 <= dst16 )\n{\n\
250dst16 = 0xffff;\n\
251cpu_set_ccr_Z (proc, 0);\n\
252cpu_set_ccr_V (proc, 1);\n\
253cpu_set_ccr_C (proc, dst16 == 0);\n\
254}\nelse\n{\n\
255unsigned long l = (unsigned long) (dst16) << 16;\n\
256cpu_set_d (proc, (uint16) (l % (unsigned long) (src16)));\n\
257dst16 = (uint16) (l / (unsigned long) (src16));\n\
258cpu_set_ccr_V (proc, 0);\n\
259cpu_set_ccr_C (proc, 0);\n\
260cpu_set_ccr_Z (proc, dst16 == 0);\n\
261}", 0 },
262
263  /* Operations to get/set the CCR.  */
264  { "clv",  0, "cpu_set_ccr_V (proc, 0)" },
265  { "sev",  0, "cpu_set_ccr_V (proc, 1)" },
266  { "clc",  0, "cpu_set_ccr_C (proc, 0)" },
267  { "sec",  0, "cpu_set_ccr_C (proc, 1)" },
268  { "cli",  0, "cpu_set_ccr_I (proc, 0)" },
269  { "sei",  0, "cpu_set_ccr_I (proc, 1)" },
270
271  /* Some special instructions are implemented by 'cpu_special'.  */
272  { "rti11",  "cpu_special (proc, M6811_RTI)" },
273  { "rti12",  "cpu_special (proc, M6812_RTI)" },
274  { "wai",  "cpu_special (proc, M6811_WAI)" },
275  { "test", "cpu_special (proc, M6811_TEST)" },
276  { "swi",  "cpu_special (proc, M6811_SWI)" },
277  { "syscall","cpu_special (proc, M6811_EMUL_SYSCALL)" },
278
279  { "page2", "cpu_page2_interp (proc)", 0 },
280  { "page3", "cpu_page3_interp (proc)", 0 },
281  { "page4", "cpu_page4_interp (proc)", 0 },
282
283  /* 68HC12 special instructions.  */
284  { "bgnd",  "cpu_special (proc, M6812_BGND)" },
285  { "call8", "cpu_special (proc, M6812_CALL)" },
286  { "call_ind", "cpu_special (proc, M6812_CALL_INDIRECT)" },
287  { "dbcc8", "cpu_dbcc (proc)" },
288  { "ediv",  "cpu_special (proc, M6812_EDIV)" },
289  { "emul",  "{ uint32 src1 = (uint32) cpu_get_d (proc);\
290  uint32 src2 = (uint32) cpu_get_y (proc);\
291  src1 *= src2;\
292  cpu_set_d (proc, src1);\
293  cpu_set_y (proc, src1 >> 16);\
294  cpu_set_ccr_Z (proc, src1 == 0);\
295  cpu_set_ccr_C (proc, src1 & 0x08000);\
296  cpu_set_ccr_N (proc, src1 & 0x80000000);}" },
297  { "emuls",  "cpu_special (proc, M6812_EMULS)" },
298  { "mem",   "cpu_special (proc, M6812_MEM)" },
299  { "rtc",   "cpu_special (proc, M6812_RTC)" },
300  { "emacs", "cpu_special (proc, M6812_EMACS)" },
301  { "idivs", "cpu_special (proc, M6812_IDIVS)" },
302  { "edivs", "cpu_special (proc, M6812_EDIVS)" },
303  { "exg8",  "cpu_exg (proc, src8)" },
304  { "move8", "cpu_move8 (proc, op)" },
305  { "move16","cpu_move16 (proc, op)" },
306
307  { "max8",  "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
308              if (dst8 < src8) dst8 = src8" },
309  { "min8",  "cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\
310              if (dst8 > src8) dst8 = src8" },
311  { "max16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
312              if (dst16 < src16) dst16 = src16" },
313  { "min16", "cpu_ccr_update_sub16 (proc, dst16 - src16, dst16, src16);\
314              if (dst16 > src16) dst16 = src16" },
315
316  { "rev",   "cpu_special (proc, M6812_REV);" },
317  { "revw",  "cpu_special (proc, M6812_REVW);" },
318  { "wav",   "cpu_special (proc, M6812_WAV);" },
319  { "tbl8",  "cpu_special (proc, M6812_ETBL);" },
320  { "tbl16", "cpu_special (proc, M6812_ETBL);" }
321};
322
323/* Definition of an opcode of the 68HC11.  */
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 (proc));
1285		      src8 = a
1286       *,#,r	      addr = (uint16) (fetch8 (proc))  <- Temporary 'addr'
1287		      src8 = read_mem8 (proc, addr)
1288		      dst8 = fetch8 (proc)
1289		      addr = fetch_relbranch (proc)    <- Final 'addr'
1290
1291   Returns 1 if the 'addr' operand is set, 0 otherwise.	 */
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 (proc);", vars[cur_var]);
1318	  break;
1319
1320	case 'b':
1321	  if (cur_var >= 2)
1322	    fatal_error (opcode, "Too many locals");
1323
1324	  print (fp, col, "%s8 = cpu_get_b (proc);", vars[cur_var]);
1325	  break;
1326
1327	case 'd':
1328	  if (cur_var >= 2)
1329	    fatal_error (opcode, "Too many locals");
1330
1331	  print (fp, col, "%s16 = cpu_get_d (proc);", vars[cur_var]);
1332	  break;
1333
1334	case 'x':
1335	  if (cur_var >= 2)
1336	    fatal_error (opcode, "Too many locals");
1337
1338	  print (fp, col, "%s16 = cpu_get_x (proc);", vars[cur_var]);
1339	  break;
1340
1341	case 'y':
1342	  if (cur_var >= 2)
1343	    fatal_error (opcode, "Too many locals");
1344
1345	  print (fp, col, "%s16 = cpu_get_y (proc);", vars[cur_var]);
1346	  break;
1347
1348	case '*':
1349	  if (cur_var >= 2)
1350	    fatal_error (opcode, "Too many locals");
1351
1352	  if (addr_set)
1353	    fatal_error (opcode, "Wrong use of '*', 'addr' already used");
1354
1355	  addr_set = 1;
1356	  current_insn_size += 1;
1357	  print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
1358	  print (fp, col, "%s%s = memory_read%s (proc, addr);",
1359		 vars[cur_var], operand_size, operand_size);
1360	  break;
1361
1362	case '&':
1363	  if (addr_set)
1364	    fatal_error (opcode, "Wrong use of '&', 'addr' already used");
1365
1366	  addr_set = 1;
1367	  if (strncmp (operands, "(x)", 3) == 0)
1368	    {
1369	      current_insn_size += 1;
1370	      print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
1371	      operands += 3;
1372	    }
1373	  else if (strncmp (operands, "(y)", 3) == 0)
1374	    {
1375	      current_insn_size += 1;
1376	      print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
1377	      operands += 3;
1378	    }
1379	  else if (strncmp (operands, "()", 2) == 0)
1380	    {
1381	      current_insn_size += 2;
1382	      print (fp, col, "addr = cpu_fetch16 (proc);");
1383	      operands += 2;
1384	    }
1385	  else if (strncmp (operands, "[]", 2) == 0)
1386	    {
1387	      current_insn_size += 1;
1388	      print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 0);");
1389	      operands += 2;
1390	    }
1391	  else
1392	    {
1393	      fatal_error (opcode, "Unknown operand");
1394	    }
1395	  break;
1396
1397	case '(':
1398	  if (cur_var >= 2)
1399	    fatal_error (opcode, "Too many locals");
1400
1401	  if (addr_set)
1402	    fatal_error (opcode, "Wrong use of '(', 'addr' already used");
1403
1404	  if (strncmp (operands, "x)", 2) == 0)
1405	    {
1406	      addr_set = 1;
1407	      current_insn_size += 1;
1408	      print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
1409	      print (fp, col, "%s%s = memory_read%s (proc, addr);",
1410		     vars[cur_var], operand_size, operand_size);
1411	      operands += 2;
1412	    }
1413	  else if (strncmp (operands, "y)", 2) == 0)
1414	    {
1415	      addr_set = 1;
1416	      current_insn_size += 1;
1417	      print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
1418	      print (fp, col, "%s%s = memory_read%s (proc, addr);",
1419		     vars[cur_var], operand_size, operand_size);
1420	      operands += 2;
1421	    }
1422	  else if (strncmp (operands, ")", 1) == 0)
1423	    {
1424	      addr_set = 1;
1425	      current_insn_size += 2;
1426	      print (fp, col, "addr = cpu_fetch16 (proc);");
1427	      print (fp, col, "%s%s = memory_read%s (proc, addr);",
1428		     vars[cur_var], operand_size, operand_size);
1429	      operands++;
1430	    }
1431	  else if (strncmp (operands, "@)", 2) == 0)
1432	    {
1433	      current_insn_size += 2;
1434	      print (fp, col, "addr = cpu_fetch16 (proc);");
1435	      print (fp, col, "%s%s = memory_read%s (proc, addr);",
1436		     vars[cur_var], operand_size, operand_size);
1437	      operands += 2;
1438	    }
1439	  else if (strncmp (operands, "sp)", 3) == 0)
1440	    {
1441	      print (fp, col, "%s%s = cpu_%s_pop_uint%s (proc);",
1442		     vars[cur_var], operand_size,
1443                     cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1444                     operand_size);
1445	      operands += 3;
1446	    }
1447	  else
1448	    {
1449	      fatal_error (opcode, "Unknown operand");
1450	    }
1451	  break;
1452
1453	case '[':
1454	  if (cur_var >= 2)
1455	    fatal_error (opcode, "Too many locals");
1456
1457	  if (addr_set)
1458	    fatal_error (opcode, "Wrong use of '[', 'addr' already used");
1459
1460	  if (strncmp (operands, "]", 1) == 0)
1461	    {
1462	      addr_set = 1;
1463	      current_insn_size += 1;
1464	      print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
1465	      print (fp, col, "%s%s = memory_read%s (proc, addr);",
1466		     vars[cur_var], operand_size, operand_size);
1467	      operands += 1;
1468	    }
1469	  else if (strncmp (operands, "]", 1) == 0)
1470	    {
1471	      current_insn_size += 1;
1472	      print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc,0);",
1473		     vars[cur_var], operand_size, operand_size);
1474	      operands += 1;
1475	    }
1476	  else
1477	    {
1478	      fatal_error (opcode, "Unknown operand");
1479	    }
1480	  break;
1481
1482	case '{':
1483	  if (cur_var >= 2)
1484	    fatal_error (opcode, "Too many locals");
1485
1486	  if (addr_set)
1487	    fatal_error (opcode, "Wrong use of '{', 'addr' already used");
1488
1489	  if (strncmp (operands, "}", 1) == 0)
1490	    {
1491	      current_insn_size += 1;
1492	      print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc, 1);",
1493		     vars[cur_var], operand_size, operand_size);
1494	      operands += 1;
1495	    }
1496	  else
1497	    {
1498	      fatal_error (opcode, "Unknown operand");
1499	    }
1500	  break;
1501
1502	case 's':
1503	  if (cur_var >= 2)
1504	    fatal_error (opcode, "Too many locals");
1505
1506	  if (strncmp (operands, "p", 1) == 0)
1507	    {
1508	      print (fp, col, "%s16 = cpu_get_sp (proc);", vars[cur_var]);
1509	      operands++;
1510	    }
1511	  else
1512	    {
1513	      fatal_error (opcode, "Unknown operands");
1514	    }
1515	  break;
1516
1517	case 'c':
1518	  if (strncmp (operands, "cr", 2) == 0)
1519	    {
1520	      print (fp, col, "%s8 = cpu_get_ccr (proc);", vars[cur_var]);
1521	      operands += 2;
1522	    }
1523	  else
1524	    {
1525	      fatal_error (opcode, "Unknown operands");
1526	    }
1527	  break;
1528
1529	case 'r':
1530	  if (addr_set && cur_var != 2)
1531	    fatal_error (opcode, "Wrong use of 'r'");
1532
1533	  addr_set = 1;
1534	  current_insn_size += 1;
1535	  print (fp, col, "addr = cpu_fetch_relbranch (proc);");
1536	  break;
1537
1538	case 'R':
1539	  if (addr_set && cur_var != 2)
1540	    fatal_error (opcode, "Wrong use of 'R'");
1541
1542	  addr_set = 1;
1543	  current_insn_size += 2;
1544	  print (fp, col, "addr = cpu_fetch_relbranch16 (proc);");
1545	  break;
1546
1547	case '#':
1548	  if (strcmp (operand_size, "8") == 0)
1549	    {
1550	      current_insn_size += 1;
1551	    }
1552	  else
1553	    {
1554	      current_insn_size += 2;
1555	    }
1556	  print (fp, col, "%s%s = cpu_fetch%s (proc);", vars[cur_var],
1557		 operand_size, operand_size);
1558	  break;
1559
1560	case ',':
1561	  cur_var ++;
1562	  break;
1563
1564	case '-':
1565	  return addr_set;
1566
1567	default:
1568	  fatal_error (opcode, "Invalid operands");
1569	  break;
1570	}
1571    }
1572  return addr_set;
1573}
1574
1575
1576/* Generate the code to save the instruction result.  The result is in
1577   a local variable: either 'dst8' or 'dst16'.
1578   There may be only one result.  Instructions with 2 results (ie idiv
1579   and fdiv), take care of saving the first value.
1580
1581   The operand string is the same as for 'gen_fetch_operands'.
1582   Everything before '->' is ignored.  If the '->' is not found, it
1583   is assumed that there is nothing to save.  After '->', the operand
1584   string is interpreted as follows:
1585
1586   a	Save 'dst8' in A register
1587   b	"	       B "
1588   ccr	"	       CCR "
1589   d	"    'dst16'   D "
1590   x	"	       X "
1591   y	"	       Y "
1592   sp	"	       SP "
1593   *	68HC11 page0 memory pointer.
1594   (x)	68HC11 indirect access with X register.
1595   (y)	Same as (x) with Y register.
1596   ()	68HC11 extended address mode (global variable).
1597	For these modes, if they were used as an input operand,
1598	the 'addr' variable contains the address of memory where
1599	the result must be saved.
1600	If they were not used an input operand, 'addr' is computed
1601	(as in gen_fetch_operands()), and the result is saved.
1602   []   68HC12 indexed indirect
1603   (sp) Push
1604	Push the 8/16-bits result on the stack.	 */
1605void
1606gen_save_result (FILE *fp, int col,
1607		 const struct m6811_opcode_def *opcode,
1608		 int addr_set,
1609		 const char *operand_size)
1610{
1611  char c;
1612  const char *operands = opcode->operands;
1613
1614  /* When the result is saved, 'result_size' is a string which
1615     indicates the size of the saved result ("8" or "16").  This
1616     is a sanity check with 'operand_size' to detect inconsistencies
1617     in the different tables.  */
1618  const char *result_size = 0;
1619
1620  if (operands == 0)
1621    operands = "";
1622
1623  operands = strchr (operands, '-');
1624  if (operands == 0)
1625    return;
1626
1627  operands++;
1628  if (*operands++ != '>')
1629    {
1630      fatal_error (opcode, "Invalid operand");
1631    }
1632
1633  c = *operands++;
1634  switch (c)
1635    {
1636    case 'a':
1637      result_size = "8";
1638      print (fp, col, "cpu_set_a (proc, dst8);");
1639      break;
1640
1641    case 'b':
1642      result_size = "8";
1643      print (fp, col, "cpu_set_b (proc, dst8);");
1644      break;
1645
1646    case 'd':
1647      result_size = "16";
1648      print (fp, col, "cpu_set_d (proc, dst16);");
1649      break;
1650
1651    case 'x':
1652      result_size = "16";
1653      print (fp, col, "cpu_set_x (proc, dst16);");
1654      break;
1655
1656    case 'y':
1657      result_size = "16";
1658      print (fp, col, "cpu_set_y (proc, dst16);");
1659      break;
1660
1661    case '*':
1662      if (addr_set == 0)
1663	{
1664	  current_insn_size += 1;
1665	  print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
1666	}
1667      result_size = operand_size;
1668      print (fp, col, "memory_write%s (proc, addr, dst%s);",
1669	     operand_size, operand_size);
1670      break;
1671
1672    case '(':
1673      if (strncmp (operands, "x)", 2) == 0)
1674	{
1675	  if (addr_set == 0)
1676	    {
1677	      current_insn_size += 1;
1678	      print (fp, col, "addr = cpu_get_x (proc) + cpu_fetch8 (proc);");
1679	    }
1680	  print (fp, col, "memory_write%s (proc, addr, dst%s);",
1681		 operand_size, operand_size);
1682	  operands += 2;
1683	  result_size = operand_size;
1684	}
1685      else if (strncmp (operands, "y)", 2) == 0)
1686	{
1687	  if (addr_set == 0)
1688	    {
1689	      current_insn_size += 1;
1690	      print (fp, col, "addr = cpu_get_y (proc) + cpu_fetch8 (proc);");
1691	    }
1692	  print (fp, col, "memory_write%s (proc, addr, dst%s);",
1693		 operand_size, operand_size);
1694	  operands += 2;
1695	  result_size = operand_size;
1696	}
1697      else if (strncmp (operands, ")", 1) == 0)
1698	{
1699	  if (addr_set == 0)
1700	    {
1701	      current_insn_size += 2;
1702	      print (fp, col, "addr = cpu_fetch16 (proc);");
1703	    }
1704	  print (fp, col, "memory_write%s (proc, addr, dst%s);",
1705		 operand_size, operand_size);
1706	  operands++;
1707	  result_size = operand_size;
1708	}
1709      else if (strncmp (operands, "sp)", 3) == 0)
1710	{
1711	  print (fp, col, "cpu_%s_push_uint%s (proc, dst%s);",
1712                 cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1713		 operand_size, operand_size);
1714	  operands += 3;
1715	  result_size = operand_size;
1716	}
1717      else
1718	{
1719	  fatal_error (opcode, "Invalid operand");
1720	}
1721      break;
1722
1723    case '[':
1724      if (strncmp (operands, "]", 1) == 0)
1725	{
1726	  if (addr_set == 0)
1727	    {
1728	      current_insn_size += 1;
1729	      print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
1730	    }
1731	  print (fp, col, "memory_write%s (proc, addr, dst%s);",
1732		 operand_size, operand_size);
1733	  operands++;
1734	  result_size = operand_size;
1735	}
1736      else
1737	{
1738	  fatal_error (opcode, "Invalid operand");
1739	}
1740      break;
1741
1742    case '{':
1743      if (strncmp (operands, "}", 1) == 0)
1744	{
1745	  current_insn_size += 1;
1746	  print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 1);");
1747	  print (fp, col, "memory_write%s (proc, addr, dst%s);",
1748		 operand_size, operand_size);
1749	  operands++;
1750	  result_size = operand_size;
1751	}
1752      else
1753	{
1754	  fatal_error (opcode, "Invalid operand");
1755	}
1756      break;
1757
1758    case 's':
1759      if (strncmp (operands, "p", 1) == 0)
1760	{
1761	  print (fp, col, "cpu_set_sp (proc, dst16);");
1762	  operands++;
1763	  result_size = "16";
1764	}
1765      else
1766	{
1767	  fatal_error (opcode, "Invalid operand");
1768	}
1769      break;
1770
1771    case 'c':
1772      if (strncmp (operands, "cr", 2) == 0)
1773	{
1774	  print (fp, col, "cpu_set_ccr (proc, dst8);");
1775	  operands += 2;
1776	  result_size = "8";
1777	}
1778      else
1779	{
1780	  fatal_error (opcode, "Invalid operand");
1781	}
1782      break;
1783
1784    default:
1785      fatal_error (opcode, "Invalid operand");
1786      break;
1787    }
1788
1789  if (*operands != 0)
1790    fatal_error (opcode, "Garbage at end of operand");
1791
1792  if (result_size == 0)
1793    fatal_error (opcode, "? No result seems to be saved");
1794
1795  if (strcmp (result_size, operand_size) != 0)
1796    fatal_error (opcode, "Result saved different than pattern size");
1797}
1798
1799
1800/* Find the instruction pattern for a given instruction.  */
1801const struct m6811_opcode_pattern*
1802find_opcode_pattern (const struct m6811_opcode_def *opcode)
1803{
1804  int i;
1805  const char *pattern = opcode->insn_pattern;
1806
1807  if (pattern == 0)
1808    {
1809      pattern = opcode->name;
1810    }
1811  for (i = 0; i < TABLE_SIZE(m6811_opcode_patterns); i++)
1812    {
1813      if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
1814	{
1815	  return &m6811_opcode_patterns[i];
1816	}
1817    }
1818  fatal_error (opcode, "Unknown instruction pattern");
1819  return 0;
1820}
1821
1822/* Generate the code for interpretation of instruction 'opcode'.  */
1823void
1824gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
1825{
1826  const char *operands = opcode->operands;
1827  int addr_set;
1828  const char *pattern = opcode->insn_pattern;
1829  const struct m6811_opcode_pattern *op;
1830  const char *operand_size;
1831
1832  if (pattern == 0)
1833    {
1834      pattern = opcode->name;
1835    }
1836
1837  /* Find out the size of the operands: 8 or 16-bits.  */
1838  if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
1839    {
1840      operand_size = "8";
1841    }
1842  else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
1843    {
1844      operand_size = "16";
1845    }
1846  else
1847    {
1848      operand_size = "";
1849    }
1850
1851  if (operands == 0)
1852    operands = "";
1853
1854  /* Generate entry point for the instruction.	*/
1855  print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
1856	 opcode->name, operands);
1857  col += indent_level;
1858
1859  /* Generate the code to get the instruction operands.	 */
1860  addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
1861
1862  /* Generate instruction interpretation.  */
1863  op = find_opcode_pattern (opcode);
1864  if (op->pattern)
1865    {
1866      print (fp, col, "%s;", op->pattern);
1867    }
1868
1869  /* Generate the code to save the result.  */
1870  gen_save_result (fp, col, opcode, addr_set, operand_size);
1871
1872  /* For some instructions, generate the code to update the flags.  */
1873  if (op && op->ccr_update)
1874    {
1875      print (fp, col, "%s;", op->ccr_update);
1876    }
1877  print (fp, col, "break;");
1878}
1879
1880
1881/* Generate the interpretor for a given 68HC11 page set.  */
1882void
1883gen_interpreter_for_table (FILE *fp, int col,
1884			   const struct m6811_opcode_def *table,
1885			   int size,
1886			   const char *cycles_table_name)
1887{
1888  int i;
1889  int init_size;
1890
1891  init_size = table == m6811_page1_opcodes
1892    || table == m6812_page1_opcodes? 1 : 2;
1893
1894  /* Get the opcode and dispatch directly.  */
1895  print (fp, col, "op = cpu_fetch8 (proc);");
1896  print (fp, col, "cpu_add_cycles (proc, %s[op]);", cycles_table_name);
1897
1898  print (fp, col, "switch (op)\n");
1899  col += indent_level;
1900  print (fp, col, "{\n");
1901
1902  for (i = 0; i < size; i++)
1903    {
1904      /* The table contains duplicate entries (ie, instruction aliases).  */
1905      if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
1906	continue;
1907
1908      current_insn_size = init_size;
1909      gen_interp (fp, col, &table[i]);
1910#if 0
1911      if (current_insn_size != table[i].insn_size)
1912	{
1913	  fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
1914		       current_insn_size, table[i].insn_size);
1915	}
1916#endif
1917    }
1918
1919  print (fp, col, "default:\n");
1920  print (fp, col + indent_level, "cpu_special (proc, M6811_ILLEGAL);");
1921  print (fp, col + indent_level, "break;");
1922  print (fp, col, "}\n");
1923}
1924
1925/* Generate the table of instruction cycle.  These tables are indexed
1926   by the opcode number to allow a fast cycle time computation.	 */
1927void
1928gen_cycle_table (FILE *fp, const char *name,
1929		 const struct m6811_opcode_def *table,
1930		 int size)
1931{
1932  int i;
1933  char cycles[256];
1934  int page1;
1935
1936  page1 = table == m6811_page1_opcodes;
1937
1938  /* Build the cycles table.  The table is indexed by the opcode.  */
1939  memset (cycles, 0, sizeof (cycles));
1940  while (--size >= 0)
1941    {
1942      if (table->insn_min_cycles > table->insn_max_cycles)
1943	fatal_error (table, "Wrong insn cycles");
1944
1945      if (table->insn_max_cycles == _M)
1946	cycles[table->insn_code] = table->insn_min_cycles;
1947      else
1948	cycles[table->insn_code] = table->insn_max_cycles;
1949
1950      table++;
1951    }
1952
1953  /* Some check: for the page1 opcode, the cycle type of the page2/3/4
1954     opcode must be 0.	*/
1955  if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
1956		|| cycles[M6811_OPCODE_PAGE3] != 0
1957		|| cycles[M6811_OPCODE_PAGE4] != 0))
1958      fatal_error (0, "Invalid cycle table");
1959
1960  /* Generates the cycles table.  */
1961  print (fp, 0, "static const unsigned char %s[256] = {\n", name);
1962  for (i = 0; i < 256; i++)
1963    {
1964      if ((i % 16) == 0)
1965	{
1966	  print (fp, indent_level, "/* %3d */ ", i);
1967	}
1968      fprintf (fp, "%2d", cycles[i]);
1969      if (i != 255)
1970	fprintf (fp, ",");
1971
1972      if ((i % 16) != 15)
1973	fprintf (fp, " ");
1974      else
1975	fprintf (fp, "\n");
1976    }
1977  print (fp, 0, "};\n\n");
1978}
1979
1980#define USE_SRC8 1
1981#define USE_DST8 2
1982
1983void
1984gen_function_entry (FILE *fp, const char *name, int locals)
1985{
1986  /* Generate interpretor entry point.	*/
1987  print (fp, 0, "%s (proc)\n", name);
1988  print (fp, indent_level, "struct _sim_cpu* proc;");
1989  print (fp, indent_level, "{\n");
1990
1991  /* Interpretor local variables.  */
1992  print (fp, indent_level, "unsigned char op;");
1993  print (fp, indent_level, "uint16 addr, src16, dst16;");
1994  if (locals & USE_SRC8)
1995    print (fp, indent_level, "uint8 src8;\n");
1996  if (locals & USE_DST8)
1997    print (fp, indent_level, "uint8 dst8;\n");
1998}
1999
2000void
2001gen_function_close (FILE *fp)
2002{
2003  print (fp, 0, "}\n");
2004}
2005
2006int
2007cmp_opcode (void* e1, void* e2)
2008{
2009  struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
2010  struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
2011
2012  return (int) (op1->insn_code) - (int) (op2->insn_code);
2013}
2014
2015void
2016prepare_table (struct m6811_opcode_def* table, int size)
2017{
2018  int i;
2019
2020  qsort (table, size, sizeof (table[0]), cmp_opcode);
2021  for (i = 1; i < size; i++)
2022    {
2023      if (table[i].insn_code == table[i-1].insn_code)
2024	{
2025	  fprintf (stderr, "Two insns with code 0x%02x\n",
2026		   table[i].insn_code);
2027	}
2028    }
2029}
2030
2031void
2032gen_interpreter (FILE *fp)
2033{
2034  int col = 0;
2035
2036  prepare_table (m6811_page1_opcodes, TABLE_SIZE (m6811_page1_opcodes));
2037  prepare_table (m6811_page2_opcodes, TABLE_SIZE (m6811_page2_opcodes));
2038  prepare_table (m6811_page3_opcodes, TABLE_SIZE (m6811_page3_opcodes));
2039  prepare_table (m6811_page4_opcodes, TABLE_SIZE (m6811_page4_opcodes));
2040
2041  prepare_table (m6812_page1_opcodes, TABLE_SIZE (m6812_page1_opcodes));
2042  prepare_table (m6812_page2_opcodes, TABLE_SIZE (m6812_page2_opcodes));
2043
2044  /* Generate header of interpretor.  */
2045  print (fp, col, "/* File generated automatically by gencode. */\n");
2046  print (fp, col, "#include \"sim-main.h\"\n\n");
2047
2048  if (cpu_type & cpu6811)
2049    {
2050      gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
2051		       TABLE_SIZE (m6811_page1_opcodes));
2052      gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
2053		       TABLE_SIZE (m6811_page2_opcodes));
2054      gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
2055		       TABLE_SIZE (m6811_page3_opcodes));
2056      gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
2057		       TABLE_SIZE (m6811_page4_opcodes));
2058
2059      gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
2060      gen_interpreter_for_table (fp, indent_level,
2061				 m6811_page3_opcodes,
2062				 TABLE_SIZE(m6811_page3_opcodes),
2063				 "cycles_page3");
2064      gen_function_close (fp);
2065
2066      gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
2067      gen_interpreter_for_table (fp, indent_level,
2068				 m6811_page4_opcodes,
2069				 TABLE_SIZE(m6811_page4_opcodes),
2070				 "cycles_page4");
2071      gen_function_close (fp);
2072
2073      /* Generate the page 2, 3 and 4 handlers.  */
2074      gen_function_entry (fp, "static void\ncpu_page2_interp",
2075                          USE_SRC8 | USE_DST8);
2076      gen_interpreter_for_table (fp, indent_level,
2077				 m6811_page2_opcodes,
2078				 TABLE_SIZE(m6811_page2_opcodes),
2079				 "cycles_page2");
2080      gen_function_close (fp);
2081
2082      /* Generate the interpretor entry point.  */
2083      gen_function_entry (fp, "void\ncpu_interp_m6811",
2084                          USE_SRC8 | USE_DST8);
2085
2086      gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
2087				 TABLE_SIZE(m6811_page1_opcodes),
2088				 "cycles_page1");
2089      gen_function_close (fp);
2090    }
2091  else
2092    {
2093      gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
2094		       TABLE_SIZE (m6812_page1_opcodes));
2095      gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
2096		       TABLE_SIZE (m6812_page2_opcodes));
2097
2098      gen_function_entry (fp, "static void\ncpu_page2_interp",
2099                          USE_SRC8 | USE_DST8);
2100      gen_interpreter_for_table (fp, indent_level,
2101				 m6812_page2_opcodes,
2102				 TABLE_SIZE(m6812_page2_opcodes),
2103				 "cycles_page2");
2104      gen_function_close (fp);
2105
2106      /* Generate the interpretor entry point.  */
2107      gen_function_entry (fp, "void\ncpu_interp_m6812",
2108                          USE_SRC8 | USE_DST8);
2109
2110      gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
2111				 TABLE_SIZE(m6812_page1_opcodes),
2112				 "cycles_page1");
2113      gen_function_close (fp);
2114    }
2115}
2116
2117void
2118usage (char* prog)
2119{
2120  fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
2121  exit (2);
2122}
2123
2124int
2125main (int argc, char *argv[])
2126{
2127  int i;
2128
2129  for (i = 1; i < argc; i++)
2130    {
2131      if (strcmp (argv[i], "-m6811") == 0)
2132	cpu_type = cpu6811;
2133      else if (strcmp (argv[i], "-m6812") == 0)
2134	cpu_type = cpu6812;
2135      else
2136	{
2137	  usage (argv[0]);
2138	}
2139    }
2140  if (cpu_type == 0)
2141    usage (argv[0]);
2142
2143  gen_interpreter (stdout);
2144  if (fclose (stdout) != 0)
2145    {
2146      fprintf (stderr, "Error while generating the interpreter: %d\n",
2147	       errno);
2148      return 1;
2149    }
2150  return 0;
2151}
2152