OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [m68hc11/] [gencode.c] - Blame information for rev 26

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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