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