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