1 /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
2 Copyright 1999-2016 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
5 This file is part of GDB, GAS, and the GNU binutils.
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.
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.
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/>. */
26 #include "opcode/m68hc11.h"
28 #define TABLE_SIZE(X) (sizeof(X) / sizeof(X[0]))
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
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
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
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
75 struct m6811_opcode_pattern
79 const char *ccr_update;
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
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" },
98 /* Conditional branches. 'addr' is the address of the branch. */
99 { "bra", "cpu_set_pc (proc, addr)" },
101 "if ((cpu_get_ccr (proc) & (M6811_C_BIT|M6811_Z_BIT)) == 0)\n@ \
102 cpu_set_pc (proc, addr)" },
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)" },
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)" },
120 "if ((cpu_get_ccr_Z (proc) | (cpu_get_ccr_N (proc) ^ cpu_get_ccr_V (proc))))\n@ \
121 cpu_set_pc (proc, addr)" },
123 /* brclr and brset perform a test and a conditional jump at the same
124 time. Flags are not changed. */
126 "if ((src8 & dst8) == 0)\n@ cpu_set_pc (proc, addr)" },
128 "if (((~src8) & dst8) == 0)\n@ cpu_set_pc (proc, addr)" },
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)" },
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)"},
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)" },
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)"},
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)" },
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@ \
175 cpu_ccr_update_sub8 (proc, dst8 - src8 - 1, dst8, src8);\n\
176 dst8 = dst8 - src8 - 1;\n\
180 cpu_ccr_update_sub8 (proc, dst8 - src8, dst8, src8);\n\
181 dst8 = dst8 - src8;\n\
183 { "adc8", "if (cpu_get_ccr_C (proc))\n@ \
185 cpu_ccr_update_add8 (proc, dst8 + src8 + 1, dst8, src8);\n\
186 dst8 = dst8 + src8 + 1;\n\
190 cpu_ccr_update_add8 (proc, dst8 + src8, dst8, src8);\n\
191 dst8 = dst8 + src8;\n\
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)" },
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)" },
209 /* Special increment/decrement for the stack pointer:
210 flags are not changed. */
211 { "ins16", "dst16 = src16 + 1" },
212 { "des16", "dst16 = src16 - 1" },
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)"},
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)"},
221 /* tsx, tsy, txs, tys don't affect the flags. Sp value is corrected
223 { "tsxy16", "dst16 = src16 + 1;"},
224 { "txys16", "dst16 = src16 - 1;"},
226 /* Add b to X or Y with an unsigned extension 8->16. Flags not changed. */
227 { "abxy16","dst16 = dst16 + (uint16) src8"},
229 /* After 'daa', the Z flag is undefined. Mark it as changed. */
230 { "daa8", "cpu_special (proc, M6811_DAA)" },
235 (parallel (set IX (div D IX))
236 (set D (mod D IX))) */
237 { "idiv16", "if (src16 == 0)\n{\n\
240 cpu_set_d (proc, dst16 % src16);\
241 dst16 = dst16 / src16;\
243 "cpu_set_ccr_Z (proc, dst16 == 0); cpu_set_ccr_V (proc, 0);\
244 cpu_set_ccr_C (proc, src16 == 0)" },
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\
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\
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\
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)" },
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)" },
279 { "page2", "cpu_page2_interp (proc)", 0 },
280 { "page3", "cpu_page3_interp (proc)", 0 },
281 { "page4", "cpu_page4_interp (proc)", 0 },
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);\
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)" },
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" },
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);" }
323 /* Definition of an opcode of the 68HC11. */
324 struct m6811_opcode_def
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;
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
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
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 },
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 },
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 },
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 }
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
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 }
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
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 }
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
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 }
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
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 },
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 },
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 },
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 },
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 },
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 },
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 },
757 { "andcc", "#,ccr->ccr", "and8", 2, 0x10, 1, 1, CHG_ALL },
759 { "asl", "()->()", "lsl8", 3, 0x78, 4, 4, CHG_NZVC },
760 { "asl", "[]->[]", "lsl8", 2, 0x68, 3, 3, CHG_NZVC },
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 },
766 { "asr", "()->()", "asr8", 3, 0x77, 4, 4, CHG_NZVC },
767 { "asr", "[]->[]", "asr8", 2, 0x67, 3, 3, CHG_NZVC },
769 { "asra", "a->a", "asr8", 1, 0x47, 1, 1, CHG_NZVC },
770 { "asrb", "b->b", "asr8", 1, 0x57, 1, 1, CHG_NZVC },
772 { "bcc", "r", 0, 2, 0x24, 1, 3, CHG_NONE },
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 },
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 },
782 { "bgnd", 0, 0, 1, 0x00, 5, 5, CHG_NONE },
784 { "bgt", "r", 0, 2, 0x2e, 1, 3, CHG_NONE },
785 { "bhi", "r", 0, 2, 0x22, 1, 3, CHG_NONE },
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 },
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 },
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 },
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 },
809 { "brn", "r", "nop", 2, 0x21, 1, 3, CHG_NONE },
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 },
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 },
819 { "bsr", "r", "jsr_12_16", 2, 0x07, 4, 4, CHG_NONE },
821 { "bvc", "r", 0, 2, 0x28, 1, 3, CHG_NONE },
822 { "bvs", "r", 0, 2, 0x29, 1, 3, CHG_NONE },
824 { "call", "", "call8", 4, 0x4a, 8, 8, CHG_NONE },
825 { "call", "", "call_ind",2, 0x4b, 8, 8, CHG_NONE },
827 { "clr", "->()", "clr8", 3, 0x79, 3, 3, SET_Z_CLR_NVC },
828 { "clr", "->[]", "clr8", 2, 0x69, 2, 2, SET_Z_CLR_NVC },
830 { "clra", "->a", "clr8", 1, 0x87, 1, 1, SET_Z_CLR_NVC },
831 { "clrb", "->b", "clr8", 1, 0xc7, 1, 1, SET_Z_CLR_NVC },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
869 /* dbeq, dbne, ibeq, ibne, tbeq, tbne */
870 { "dbeq", 0, "dbcc8", 3, 0x04, 3, 3, CHG_NONE },
872 { "dec", "()->()", "dec8", 3, 0x73, 4, 4, CHG_NZV },
873 { "dec", "[]->[]", "dec8", 2, 0x63, 3, 3, CHG_NZV },
875 { "deca", "a->a", "dec8", 1, 0x43, 1, 1, CHG_NZV },
876 { "decb", "b->b", "dec8", 1, 0x53, 1, 1, CHG_NZV },
878 { "dex", "x->x", "dec16", 1, 0x09, 1, 1, CHG_Z },
879 { "dey", "y->y", "dec16", 1, 0x03, 1, 1, CHG_Z },
881 { "ediv", 0, 0, 1, 0x11, 11, 11, CHG_NZVC },
882 { "emul", 0, 0, 1, 0x13, 3, 3, CHG_NZC },
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 },
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 },
895 { "exg", "#", "exg8", 2, 0xb7, 1, 1, CHG_NONE },
897 { "inc", "()->()", "inc8", 3, 0x72, 4, 4, CHG_NZV },
898 { "inc", "[]->[]", "inc8", 2, 0x62, 3, 3, CHG_NZV },
900 { "inca", "a->a", "inc8", 1, 0x42, 1, 1, CHG_NZV },
901 { "incb", "b->b", "inc8", 1, 0x52, 1, 1, CHG_NZV },
903 { "inx", "x->x", "inc16", 1, 0x08, 1, 1, CHG_Z },
904 { "iny", "y->y", "inc16", 1, 0x02, 1, 1, CHG_Z },
906 { "jmp", "&()", "bra", 3, 0x06, 3, 3, CHG_NONE },
907 { "jmp", "&[]", "bra", 2, 0x05, 3, 3, CHG_NONE },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
947 { "lsr", "()->()", "lsr8", 3, 0x74, 4, 4, CLR_N_CHG_ZVC },
948 { "lsr", "[]->[]", "lsr8", 2, 0x64, 3, 3, CLR_N_CHG_ZVC },
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 },
954 { "mem", 0, 0, 1, 0x01, 5, 5, CHG_HNZVC },
956 { "mul", "b,a->d", "mul16", 1, 0x12, 3, 3, CHG_C },
958 { "neg", "()->()", "neg8", 3, 0x70, 4, 4, CHG_NZVC },
959 { "neg", "[]->[]", "neg8", 2, 0x60, 3, 3, CHG_NZVC },
961 { "nega", "a->a", "neg8", 1, 0x40, 1, 1, CHG_NZVC },
962 { "negb", "b->b", "neg8", 1, 0x50, 1, 1, CHG_NZVC },
964 { "nop", "", "nop", 1, 0xa7, 1, 1, CHG_NONE },
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 },
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 },
976 { "orcc", "#,ccr->ccr", "or8", 2, 0x14, 1, 1, CHG_ALL },
978 { "page2", 0, "page2", 1, 0x18, 0, 0, CHG_NONE },
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 },
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 },
994 { "rol", "()->()", "rol8", 3, 0x75, 4, 4, CHG_NZVC },
995 { "rol", "[]->[]", "rol8", 2, 0x65, 3, 3, CHG_NZVC },
997 { "rola", "a->a", "rol8", 1, 0x45, 1, 1, CHG_NZVC },
998 { "rolb", "b->b", "rol8", 1, 0x55, 1, 1, CHG_NZVC },
1000 { "ror", "()->()", "ror8", 3, 0x76, 4, 4, CHG_NZVC },
1001 { "ror", "[]->[]", "ror8", 2, 0x66, 3, 3, CHG_NZVC },
1003 { "rora", "a->a", "ror8", 1, 0x46, 1, 1, CHG_NZVC },
1004 { "rorb", "b->b", "ror8", 1, 0x56, 1, 1, CHG_NZVC },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
1059 { "swi", 0, 0, 1, 0x3f, 9, 9, CHG_NONE },
1061 { "tst", "()", "tst8", 3, 0xf7, 3, 3, CLR_VC_CHG_NZ },
1062 { "tst", "[]", "tst8", 2, 0xe7, 3, 3, CLR_VC_CHG_NZ },
1064 { "tsta", "a", "tst8", 1, 0x97, 1, 1, CLR_VC_CHG_NZ },
1065 { "tstb", "b", "tst8", 1, 0xd7, 1, 1, CLR_VC_CHG_NZ },
1067 { "wai", 0, 0, 1, 0x3e, 8, _M, CHG_NONE }
1070 struct m6811_opcode_def m6812_page2_opcodes[] = {
1071 { "cba", "b,a", "sub8", 2, 0x17, 2, 2, CHG_NZVC },
1073 /* After 'daa', the Z flag is undefined. Mark it as changed. */
1074 { "daa", 0, "daa8", 2, 0x07, 3, 3, CHG_NZVC },
1076 { "edivs", 0, 0, 2, 0x14, 12, 12, CHG_NZVC },
1077 { "emacs", 0, 0, 2, 0x12, 13, 13, CHG_NZVC },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
1130 { "stop", 0, 0, 2, 0x3e, 2, 9, CHG_NONE },
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 },
1135 { "wav", 0, 0, 2, 0x3c, 8, _M, SET_Z_CHG_HNVC }
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*,
1142 void gen_save_result (FILE*, int, const struct m6811_opcode_def*,
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*,
1150 void gen_interpreter (FILE*);
1153 static int indent_level = 2;
1154 static int current_insn_size = 0;
1156 /* Fatal error message and exit. This method is called when an inconsistency
1157 is detected in the generation table. */
1159 fatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...)
1163 fprintf (stderr, "Fatal error: ");
1164 va_start (argp, msg);
1165 vfprintf (stderr, msg, argp);
1167 fprintf (stderr, "\n");
1170 fprintf (stderr, "Opcode: 0x%02x %s %s\n",
1172 opcode->name ? opcode->name : "(null)",
1173 opcode->operands ? opcode->operands : "(null)");
1179 /* Format and pretty print for the code generation. (printf like format). */
1181 print (FILE *fp, int col, const char *msg, ...)
1188 /* Format in a buffer. */
1189 va_start (argp, msg);
1190 vsprintf (buf, msg, argp);
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++)
1201 col += indent_level;
1202 else if (buf[i] == '}')
1203 col -= indent_level;
1204 else if (buf[i] == '@')
1206 col += indent_level;
1209 if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n')
1212 while (cur_col < col)
1219 col -= indent_level;
1220 else if (buf[i] == '{')
1221 col += indent_level;
1222 else if (buf[i] == '\n')
1225 if (cur_col != -1 || buf[i] == '\n')
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:
1243 1st operand: src8 src16
1244 2nd operand: dst8 dst16
1245 alt operand: addr addr
1247 The operand string is interpreted as follows:
1249 a Copy A register in the local 8-bits variable.
1252 d " D " " " 16-bits variable.
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
1270 Pop a 8/16-bits value from stack and set in a 8/16-bits variable.
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.
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.
1284 (x),a->a addr = x + (uint16) (fetch8 (proc));
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'
1291 Returns 1 if the 'addr' operand is set, 0 otherwise. */
1293 gen_fetch_operands (FILE *fp, int col,
1294 const struct m6811_opcode_def *opcode,
1295 const char *operand_size)
1297 static char *vars[2] = {
1304 const char *operands = opcode->operands;
1309 while ((c = *operands++) != 0)
1315 fatal_error (opcode, "Too many locals");
1317 print (fp, col, "%s8 = cpu_get_a (proc);", vars[cur_var]);
1322 fatal_error (opcode, "Too many locals");
1324 print (fp, col, "%s8 = cpu_get_b (proc);", vars[cur_var]);
1329 fatal_error (opcode, "Too many locals");
1331 print (fp, col, "%s16 = cpu_get_d (proc);", vars[cur_var]);
1336 fatal_error (opcode, "Too many locals");
1338 print (fp, col, "%s16 = cpu_get_x (proc);", vars[cur_var]);
1343 fatal_error (opcode, "Too many locals");
1345 print (fp, col, "%s16 = cpu_get_y (proc);", vars[cur_var]);
1350 fatal_error (opcode, "Too many locals");
1353 fatal_error (opcode, "Wrong use of '*', 'addr' already used");
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);
1364 fatal_error (opcode, "Wrong use of '&', 'addr' already used");
1367 if (strncmp (operands, "(x)", 3) == 0)
1369 current_insn_size += 1;
1370 print (fp, col, "addr = cpu_get_x (proc) + (uint16) cpu_fetch8 (proc);");
1373 else if (strncmp (operands, "(y)", 3) == 0)
1375 current_insn_size += 1;
1376 print (fp, col, "addr = cpu_get_y (proc) + (uint16) cpu_fetch8 (proc);");
1379 else if (strncmp (operands, "()", 2) == 0)
1381 current_insn_size += 2;
1382 print (fp, col, "addr = cpu_fetch16 (proc);");
1385 else if (strncmp (operands, "[]", 2) == 0)
1387 current_insn_size += 1;
1388 print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 0);");
1393 fatal_error (opcode, "Unknown operand");
1399 fatal_error (opcode, "Too many locals");
1402 fatal_error (opcode, "Wrong use of '(', 'addr' already used");
1404 if (strncmp (operands, "x)", 2) == 0)
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);
1413 else if (strncmp (operands, "y)", 2) == 0)
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);
1422 else if (strncmp (operands, ")", 1) == 0)
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);
1431 else if (strncmp (operands, "@)", 2) == 0)
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);
1439 else if (strncmp (operands, "sp)", 3) == 0)
1441 print (fp, col, "%s%s = cpu_%s_pop_uint%s (proc);",
1442 vars[cur_var], operand_size,
1443 cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1449 fatal_error (opcode, "Unknown operand");
1455 fatal_error (opcode, "Too many locals");
1458 fatal_error (opcode, "Wrong use of '[', 'addr' already used");
1460 if (strncmp (operands, "]", 1) == 0)
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);
1469 #if 0 /* This code is never executed (see strncmp above), but it has not been
1470 removed because it may be that there is a typo in strncmp test below. */
1471 else if (strncmp (operands, "]", 1) == 0)
1473 current_insn_size += 1;
1474 print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc,0);",
1475 vars[cur_var], operand_size, operand_size);
1481 fatal_error (opcode, "Unknown operand");
1487 fatal_error (opcode, "Too many locals");
1490 fatal_error (opcode, "Wrong use of '{', 'addr' already used");
1492 if (strncmp (operands, "}", 1) == 0)
1494 current_insn_size += 1;
1495 print (fp, col, "%s%s = cpu_get_indexed_operand%s (proc, 1);",
1496 vars[cur_var], operand_size, operand_size);
1501 fatal_error (opcode, "Unknown operand");
1507 fatal_error (opcode, "Too many locals");
1509 if (strncmp (operands, "p", 1) == 0)
1511 print (fp, col, "%s16 = cpu_get_sp (proc);", vars[cur_var]);
1516 fatal_error (opcode, "Unknown operands");
1521 if (strncmp (operands, "cr", 2) == 0)
1523 print (fp, col, "%s8 = cpu_get_ccr (proc);", vars[cur_var]);
1528 fatal_error (opcode, "Unknown operands");
1533 if (addr_set && cur_var != 2)
1534 fatal_error (opcode, "Wrong use of 'r'");
1537 current_insn_size += 1;
1538 print (fp, col, "addr = cpu_fetch_relbranch (proc);");
1542 if (addr_set && cur_var != 2)
1543 fatal_error (opcode, "Wrong use of 'R'");
1546 current_insn_size += 2;
1547 print (fp, col, "addr = cpu_fetch_relbranch16 (proc);");
1551 if (strcmp (operand_size, "8") == 0)
1553 current_insn_size += 1;
1557 current_insn_size += 2;
1559 print (fp, col, "%s%s = cpu_fetch%s (proc);", vars[cur_var],
1560 operand_size, operand_size);
1571 fatal_error (opcode, "Invalid operands");
1579 /* Generate the code to save the instruction result. The result is in
1580 a local variable: either 'dst8' or 'dst16'.
1581 There may be only one result. Instructions with 2 results (ie idiv
1582 and fdiv), take care of saving the first value.
1584 The operand string is the same as for 'gen_fetch_operands'.
1585 Everything before '->' is ignored. If the '->' is not found, it
1586 is assumed that there is nothing to save. After '->', the operand
1587 string is interpreted as follows:
1589 a Save 'dst8' in A register
1596 * 68HC11 page0 memory pointer.
1597 (x) 68HC11 indirect access with X register.
1598 (y) Same as (x) with Y register.
1599 () 68HC11 extended address mode (global variable).
1600 For these modes, if they were used as an input operand,
1601 the 'addr' variable contains the address of memory where
1602 the result must be saved.
1603 If they were not used an input operand, 'addr' is computed
1604 (as in gen_fetch_operands()), and the result is saved.
1605 [] 68HC12 indexed indirect
1607 Push the 8/16-bits result on the stack. */
1609 gen_save_result (FILE *fp, int col,
1610 const struct m6811_opcode_def *opcode,
1612 const char *operand_size)
1615 const char *operands = opcode->operands;
1617 /* When the result is saved, 'result_size' is a string which
1618 indicates the size of the saved result ("8" or "16"). This
1619 is a sanity check with 'operand_size' to detect inconsistencies
1620 in the different tables. */
1621 const char *result_size = 0;
1626 operands = strchr (operands, '-');
1631 if (*operands++ != '>')
1633 fatal_error (opcode, "Invalid operand");
1641 print (fp, col, "cpu_set_a (proc, dst8);");
1646 print (fp, col, "cpu_set_b (proc, dst8);");
1651 print (fp, col, "cpu_set_d (proc, dst16);");
1656 print (fp, col, "cpu_set_x (proc, dst16);");
1661 print (fp, col, "cpu_set_y (proc, dst16);");
1667 current_insn_size += 1;
1668 print (fp, col, "addr = (uint16) cpu_fetch8 (proc);");
1670 result_size = operand_size;
1671 print (fp, col, "memory_write%s (proc, addr, dst%s);",
1672 operand_size, operand_size);
1676 if (strncmp (operands, "x)", 2) == 0)
1680 current_insn_size += 1;
1681 print (fp, col, "addr = cpu_get_x (proc) + cpu_fetch8 (proc);");
1683 print (fp, col, "memory_write%s (proc, addr, dst%s);",
1684 operand_size, operand_size);
1686 result_size = operand_size;
1688 else if (strncmp (operands, "y)", 2) == 0)
1692 current_insn_size += 1;
1693 print (fp, col, "addr = cpu_get_y (proc) + cpu_fetch8 (proc);");
1695 print (fp, col, "memory_write%s (proc, addr, dst%s);",
1696 operand_size, operand_size);
1698 result_size = operand_size;
1700 else if (strncmp (operands, ")", 1) == 0)
1704 current_insn_size += 2;
1705 print (fp, col, "addr = cpu_fetch16 (proc);");
1707 print (fp, col, "memory_write%s (proc, addr, dst%s);",
1708 operand_size, operand_size);
1710 result_size = operand_size;
1712 else if (strncmp (operands, "sp)", 3) == 0)
1714 print (fp, col, "cpu_%s_push_uint%s (proc, dst%s);",
1715 cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1716 operand_size, operand_size);
1718 result_size = operand_size;
1722 fatal_error (opcode, "Invalid operand");
1727 if (strncmp (operands, "]", 1) == 0)
1731 current_insn_size += 1;
1732 print (fp, col, "addr = cpu_get_indexed_operand_addr (proc,0);");
1734 print (fp, col, "memory_write%s (proc, addr, dst%s);",
1735 operand_size, operand_size);
1737 result_size = operand_size;
1741 fatal_error (opcode, "Invalid operand");
1746 if (strncmp (operands, "}", 1) == 0)
1748 current_insn_size += 1;
1749 print (fp, col, "addr = cpu_get_indexed_operand_addr (proc, 1);");
1750 print (fp, col, "memory_write%s (proc, addr, dst%s);",
1751 operand_size, operand_size);
1753 result_size = operand_size;
1757 fatal_error (opcode, "Invalid operand");
1762 if (strncmp (operands, "p", 1) == 0)
1764 print (fp, col, "cpu_set_sp (proc, dst16);");
1770 fatal_error (opcode, "Invalid operand");
1775 if (strncmp (operands, "cr", 2) == 0)
1777 print (fp, col, "cpu_set_ccr (proc, dst8);");
1783 fatal_error (opcode, "Invalid operand");
1788 fatal_error (opcode, "Invalid operand");
1793 fatal_error (opcode, "Garbage at end of operand");
1795 if (result_size == 0)
1796 fatal_error (opcode, "? No result seems to be saved");
1798 if (strcmp (result_size, operand_size) != 0)
1799 fatal_error (opcode, "Result saved different than pattern size");
1803 /* Find the instruction pattern for a given instruction. */
1804 const struct m6811_opcode_pattern*
1805 find_opcode_pattern (const struct m6811_opcode_def *opcode)
1808 const char *pattern = opcode->insn_pattern;
1812 pattern = opcode->name;
1814 for (i = 0; i < TABLE_SIZE(m6811_opcode_patterns); i++)
1816 if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
1818 return &m6811_opcode_patterns[i];
1821 fatal_error (opcode, "Unknown instruction pattern");
1825 /* Generate the code for interpretation of instruction 'opcode'. */
1827 gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
1829 const char *operands = opcode->operands;
1831 const char *pattern = opcode->insn_pattern;
1832 const struct m6811_opcode_pattern *op;
1833 const char *operand_size;
1837 pattern = opcode->name;
1840 /* Find out the size of the operands: 8 or 16-bits. */
1841 if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
1845 else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
1847 operand_size = "16";
1857 /* Generate entry point for the instruction. */
1858 print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
1859 opcode->name, operands);
1860 col += indent_level;
1862 /* Generate the code to get the instruction operands. */
1863 addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
1865 /* Generate instruction interpretation. */
1866 op = find_opcode_pattern (opcode);
1869 print (fp, col, "%s;", op->pattern);
1872 /* Generate the code to save the result. */
1873 gen_save_result (fp, col, opcode, addr_set, operand_size);
1875 /* For some instructions, generate the code to update the flags. */
1876 if (op && op->ccr_update)
1878 print (fp, col, "%s;", op->ccr_update);
1880 print (fp, col, "break;");
1884 /* Generate the interpretor for a given 68HC11 page set. */
1886 gen_interpreter_for_table (FILE *fp, int col,
1887 const struct m6811_opcode_def *table,
1889 const char *cycles_table_name)
1894 init_size = table == m6811_page1_opcodes
1895 || table == m6812_page1_opcodes? 1 : 2;
1897 /* Get the opcode and dispatch directly. */
1898 print (fp, col, "op = cpu_fetch8 (proc);");
1899 print (fp, col, "cpu_add_cycles (proc, %s[op]);", cycles_table_name);
1901 print (fp, col, "switch (op)\n");
1902 col += indent_level;
1903 print (fp, col, "{\n");
1905 for (i = 0; i < size; i++)
1907 /* The table contains duplicate entries (ie, instruction aliases). */
1908 if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
1911 current_insn_size = init_size;
1912 gen_interp (fp, col, &table[i]);
1914 if (current_insn_size != table[i].insn_size)
1916 fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
1917 current_insn_size, table[i].insn_size);
1922 print (fp, col, "default:\n");
1923 print (fp, col + indent_level, "cpu_special (proc, M6811_ILLEGAL);");
1924 print (fp, col + indent_level, "break;");
1925 print (fp, col, "}\n");
1928 /* Generate the table of instruction cycle. These tables are indexed
1929 by the opcode number to allow a fast cycle time computation. */
1931 gen_cycle_table (FILE *fp, const char *name,
1932 const struct m6811_opcode_def *table,
1939 page1 = table == m6811_page1_opcodes;
1941 /* Build the cycles table. The table is indexed by the opcode. */
1942 memset (cycles, 0, sizeof (cycles));
1945 if (table->insn_min_cycles > table->insn_max_cycles)
1946 fatal_error (table, "Wrong insn cycles");
1948 if (table->insn_max_cycles == _M)
1949 cycles[table->insn_code] = table->insn_min_cycles;
1951 cycles[table->insn_code] = table->insn_max_cycles;
1956 /* Some check: for the page1 opcode, the cycle type of the page2/3/4
1957 opcode must be 0. */
1958 if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
1959 || cycles[M6811_OPCODE_PAGE3] != 0
1960 || cycles[M6811_OPCODE_PAGE4] != 0))
1961 fatal_error (0, "Invalid cycle table");
1963 /* Generates the cycles table. */
1964 print (fp, 0, "static const unsigned char %s[256] = {\n", name);
1965 for (i = 0; i < 256; i++)
1969 print (fp, indent_level, "/* %3d */ ", i);
1971 fprintf (fp, "%2d", cycles[i]);
1980 print (fp, 0, "};\n\n");
1987 gen_function_entry (FILE *fp, const char *name, int locals)
1989 /* Generate interpretor entry point. */
1990 print (fp, 0, "%s (proc)\n", name);
1991 print (fp, indent_level, "struct _sim_cpu* proc;");
1992 print (fp, indent_level, "{\n");
1994 /* Interpretor local variables. */
1995 print (fp, indent_level, "unsigned char op;");
1996 print (fp, indent_level, "uint16 addr, src16, dst16;");
1997 if (locals & USE_SRC8)
1998 print (fp, indent_level, "uint8 src8;\n");
1999 if (locals & USE_DST8)
2000 print (fp, indent_level, "uint8 dst8;\n");
2004 gen_function_close (FILE *fp)
2006 print (fp, 0, "}\n");
2010 cmp_opcode (void* e1, void* e2)
2012 struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
2013 struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
2015 return (int) (op1->insn_code) - (int) (op2->insn_code);
2019 prepare_table (struct m6811_opcode_def* table, int size)
2023 qsort (table, size, sizeof (table[0]), cmp_opcode);
2024 for (i = 1; i < size; i++)
2026 if (table[i].insn_code == table[i-1].insn_code)
2028 fprintf (stderr, "Two insns with code 0x%02x\n",
2029 table[i].insn_code);
2035 gen_interpreter (FILE *fp)
2039 prepare_table (m6811_page1_opcodes, TABLE_SIZE (m6811_page1_opcodes));
2040 prepare_table (m6811_page2_opcodes, TABLE_SIZE (m6811_page2_opcodes));
2041 prepare_table (m6811_page3_opcodes, TABLE_SIZE (m6811_page3_opcodes));
2042 prepare_table (m6811_page4_opcodes, TABLE_SIZE (m6811_page4_opcodes));
2044 prepare_table (m6812_page1_opcodes, TABLE_SIZE (m6812_page1_opcodes));
2045 prepare_table (m6812_page2_opcodes, TABLE_SIZE (m6812_page2_opcodes));
2047 /* Generate header of interpretor. */
2048 print (fp, col, "/* File generated automatically by gencode. */\n");
2049 print (fp, col, "#include \"sim-main.h\"\n\n");
2051 if (cpu_type & cpu6811)
2053 gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
2054 TABLE_SIZE (m6811_page1_opcodes));
2055 gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
2056 TABLE_SIZE (m6811_page2_opcodes));
2057 gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
2058 TABLE_SIZE (m6811_page3_opcodes));
2059 gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
2060 TABLE_SIZE (m6811_page4_opcodes));
2062 gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
2063 gen_interpreter_for_table (fp, indent_level,
2064 m6811_page3_opcodes,
2065 TABLE_SIZE(m6811_page3_opcodes),
2067 gen_function_close (fp);
2069 gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
2070 gen_interpreter_for_table (fp, indent_level,
2071 m6811_page4_opcodes,
2072 TABLE_SIZE(m6811_page4_opcodes),
2074 gen_function_close (fp);
2076 /* Generate the page 2, 3 and 4 handlers. */
2077 gen_function_entry (fp, "static void\ncpu_page2_interp",
2078 USE_SRC8 | USE_DST8);
2079 gen_interpreter_for_table (fp, indent_level,
2080 m6811_page2_opcodes,
2081 TABLE_SIZE(m6811_page2_opcodes),
2083 gen_function_close (fp);
2085 /* Generate the interpretor entry point. */
2086 gen_function_entry (fp, "void\ncpu_interp_m6811",
2087 USE_SRC8 | USE_DST8);
2089 gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
2090 TABLE_SIZE(m6811_page1_opcodes),
2092 gen_function_close (fp);
2096 gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
2097 TABLE_SIZE (m6812_page1_opcodes));
2098 gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
2099 TABLE_SIZE (m6812_page2_opcodes));
2101 gen_function_entry (fp, "static void\ncpu_page2_interp",
2102 USE_SRC8 | USE_DST8);
2103 gen_interpreter_for_table (fp, indent_level,
2104 m6812_page2_opcodes,
2105 TABLE_SIZE(m6812_page2_opcodes),
2107 gen_function_close (fp);
2109 /* Generate the interpretor entry point. */
2110 gen_function_entry (fp, "void\ncpu_interp_m6812",
2111 USE_SRC8 | USE_DST8);
2113 gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
2114 TABLE_SIZE(m6812_page1_opcodes),
2116 gen_function_close (fp);
2123 fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
2128 main (int argc, char *argv[])
2132 for (i = 1; i < argc; i++)
2134 if (strcmp (argv[i], "-m6811") == 0)
2136 else if (strcmp (argv[i], "-m6812") == 0)
2146 gen_interpreter (stdout);
2147 if (fclose (stdout) != 0)
2149 fprintf (stderr, "Error while generating the interpreter: %d\n",