OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [sim/] [m68hc11/] [gencode.c] - Blame information for rev 284

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.