fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/e68000/opcodes.c *
7 * Created: 2005-07-17 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2005-2020 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "e68000.h"
24#include "internal.h"
25
26
27#define e68_op_chk_addr(c, addr, wr) do { \
28 if (((c)->flags & E68_FLAG_NOADDR) == 0) { \
29 if ((addr) & 1) { \
30 e68_exception_address (c, (addr), 1, (wr)); \
31 return; \
32 } \
33 } \
34 } while (0)
35
36#define e68_op_supervisor(c) do { \
37 if ((c)->supervisor == 0) { \
38 e68_exception_privilege (c); \
39 return; \
40 } \
41 } while (0)
42
43#define e68_op_68010(c) \
44 if (!((c)->flags & E68_FLAG_68010)) { \
45 e68_op_undefined (c); \
46 return; \
47 }
48
49
50static void e68_op_undefined (e68000_t *c)
51{
52 e68_exception_illegal (c);
53 e68_set_clk (c, 2);
54}
55
56/* 0000: ORI.B #XX, <EA> */
57static void op0000 (e68000_t *c)
58{
59 uint8_t s1, s2, d;
60
61 e68_op_prefetch8 (c, s1);
62
63 if ((c->ir[0] & 0x3f) == 0x3c) {
64 /* ORI.B #XX, CCR */
65 e68_set_clk (c, 20);
66 e68_op_prefetch (c);
67 e68_set_ccr (c, (e68_get_ccr (c) | s1) & E68_SR_XNZVC);
68 return;
69 }
70
71 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
72
73 d = s1 | s2;
74
75 e68_set_clk (c, 8);
76 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
77 e68_op_prefetch (c);
78 e68_op_set_ea8 (c, 0, 0, 0, d);
79}
80
81/* 0040_3C: ORI.W #XXXX, SR */
82static void op0040_3c (e68000_t *c)
83{
84 uint16_t s1;
85
86 e68_op_supervisor (c);
87 e68_op_prefetch16 (c, s1);
88 e68_set_clk (c, 20);
89 e68_op_prefetch (c);
90 e68_set_sr (c, (e68_get_sr (c) | s1) & E68_SR_MASK);
91}
92
93/* 0040: ORI.W #XXXX, <EA> */
94static void op0040 (e68000_t *c)
95{
96 uint16_t s1, s2, d;
97
98 if ((c->ir[0] & 0x3f) == 0x3c) {
99 op0040_3c (c);
100 return;
101 }
102
103 e68_op_prefetch16 (c, s1);
104 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
105
106 d = s1 | s2;
107
108 e68_set_clk (c, 8);
109 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
110 e68_op_prefetch (c);
111 e68_op_set_ea16 (c, 0, 0, 0, d);
112}
113
114/* 0080: ORI.L #XXXXXXXX, <EA> */
115static void op0080 (e68000_t *c)
116{
117 uint32_t s1, s2, d;
118
119 e68_op_prefetch32 (c, s1);
120 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
121
122 d = s1 | s2;
123
124 e68_set_clk (c, 16);
125 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
126 e68_op_prefetch (c);
127 e68_op_set_ea32 (c, 0, 0, 0, d);
128}
129
130/* 0100_00: BTST Dn, Dn */
131static void op0100_00 (e68000_t *c)
132{
133 unsigned i;
134 uint32_t s, m;
135
136 s = e68_get_dreg32 (c, e68_ir_reg0 (c));
137 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x1f;
138
139 m = 1UL << i;
140
141 e68_set_clk (c, 6);
142 e68_set_sr_z (c, (s & m) == 0);
143 e68_op_prefetch (c);
144}
145
146/* 0100_08: MOVEP.W d16(An), Dn */
147static void op0100_08 (e68000_t *c)
148{
149 uint32_t addr;
150 uint16_t v;
151
152 e68_op_prefetch (c);
153 addr = e68_get_areg32 (c, e68_ir_reg0 (c)) + e68_exts16 (c->ir[1]);
154
155 v = e68_get_mem8 (c, addr);
156 v = (v << 8) | e68_get_mem8 (c, addr + 2);
157
158 e68_set_clk (c, 16);
159 e68_set_dreg16 (c, e68_ir_reg9 (c), v);
160 e68_op_prefetch (c);
161}
162
163/* 0100: BTST Dn, <EA> */
164static void op0100 (e68000_t *c)
165{
166 unsigned i;
167 uint8_t s, m;
168
169 switch (c->ir[0] & 0x38) {
170 case 0x00:
171 op0100_00 (c);
172 return;
173
174 case 0x08:
175 op0100_08 (c);
176 return;
177 }
178
179 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0xffc, &s);
180 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x07;
181
182 m = 1 << i;
183
184 e68_set_clk (c, 4);
185 e68_set_sr_z (c, (s & m) == 0);
186 e68_op_prefetch (c);
187}
188
189/* 0140_00: BCHG Dn, Dn */
190static void op0140_00 (e68000_t *c)
191{
192 unsigned i, r;
193 uint32_t s, d, m;
194
195 r = e68_ir_reg0 (c);
196 s = e68_get_dreg32 (c, r);
197 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x1f;
198
199 m = 1UL << i;
200 d = s ^ m;
201
202 e68_set_clk (c, 8);
203 e68_set_dreg32 (c, r, d);
204 e68_set_sr_z (c, (s & m) == 0);
205 e68_op_prefetch (c);
206}
207
208/* 0140_01: MOVEP.L d16(An), Dn */
209static void op0140_01 (e68000_t *c)
210{
211 uint32_t addr;
212 uint32_t v;
213
214 e68_op_prefetch (c);
215 addr = e68_get_areg32 (c, e68_ir_reg0 (c)) + e68_exts16 (c->ir[1]);
216
217 v = e68_get_mem8 (c, addr);
218 v = (v << 8) | e68_get_mem8 (c, addr + 2);
219 v = (v << 8) | e68_get_mem8 (c, addr + 4);
220 v = (v << 8) | e68_get_mem8 (c, addr + 6);
221
222 e68_set_clk (c, 24);
223 e68_set_dreg32 (c, e68_ir_reg9 (c), v);
224 e68_op_prefetch (c);
225}
226
227/* 0140: BCHG Dn, <EA> */
228static void op0140 (e68000_t *c)
229{
230 unsigned i;
231 uint8_t s, d, m;
232
233 switch ((c->ir[0] >> 3) & 7) {
234 case 0x00:
235 op0140_00 (c);
236 return;
237
238 case 0x01:
239 op0140_01 (c);
240 return;
241 }
242
243 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &s);
244 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x07;
245
246 m = 1 << i;
247 d = s ^ m;
248
249 e68_set_clk (c, 8);
250 e68_set_sr_z (c, (s & m) == 0);
251 e68_op_prefetch (c);
252 e68_op_set_ea8 (c, 0, 0, 0, d);
253}
254
255/* 0180_00: BCLR Dn, Dn */
256static void op0180_00 (e68000_t *c)
257{
258 unsigned i, r;
259 uint32_t s, d, m;
260
261 r = e68_ir_reg0 (c);
262 s = e68_get_dreg32 (c, r);
263 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x1f;
264
265 m = 1UL << i;
266 d = s & ~m;
267
268 e68_set_clk (c, 10);
269 e68_set_sr_z (c, (s & m) == 0);
270 e68_set_dreg32 (c, r, d);
271 e68_op_prefetch (c);
272}
273
274/* 0180_01: MOVEP.W Dn, d16(An) */
275static void op0180_01 (e68000_t *c)
276{
277 uint32_t addr;
278 uint16_t v;
279
280 e68_op_prefetch (c);
281 addr = e68_get_areg32 (c, e68_ir_reg0 (c)) + e68_exts16 (c->ir[1]);
282
283 v = e68_get_dreg16 (c, e68_ir_reg9 (c));
284
285 e68_set_mem8 (c, addr + 0, v >> 8);
286 e68_set_mem8 (c, addr + 2, v & 0xff);
287
288 e68_set_clk (c, 16);
289 e68_op_prefetch (c);
290}
291
292/* 0180: BCLR Dn, <EA> */
293static void op0180 (e68000_t *c)
294{
295 unsigned i;
296 uint8_t s, d, m;
297
298 switch ((c->ir[0] >> 3) & 7) {
299 case 0x00:
300 op0180_00 (c);
301 return;
302
303 case 0x01:
304 op0180_01 (c);
305 return;
306 }
307
308 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &s);
309 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x07;
310
311 m = 1 << i;
312 d = s & ~m;
313
314 e68_set_clk (c, 8);
315 e68_set_sr_z (c, (s & m) == 0);
316 e68_op_prefetch (c);
317 e68_op_set_ea8 (c, 0, 0, 0, d);
318}
319
320/* 01C0_00: BSET Dn, Dn */
321static void op01c0_00 (e68000_t *c)
322{
323 unsigned i, r;
324 uint32_t s, d, m;
325
326 r = e68_ir_reg0 (c);
327 s = e68_get_dreg32 (c, r);
328 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x1f;
329
330 m = 1UL << i;
331 d = s | m;
332
333 e68_set_clk (c, 8);
334 e68_set_sr_z (c, (s & m) == 0);
335 e68_set_dreg32 (c, r, d);
336 e68_op_prefetch (c);
337}
338
339/* 01C0_01: MOVEP.L Dn, d16(An) */
340static void op01c0_01 (e68000_t *c)
341{
342 uint32_t addr;
343 uint32_t v;
344
345 e68_op_prefetch (c);
346 addr = e68_get_areg32 (c, e68_ir_reg0 (c)) + e68_exts16 (c->ir[1]);
347
348 v = e68_get_dreg32 (c, e68_ir_reg9 (c));
349
350 e68_set_mem8 (c, addr + 0, (v >> 24) & 0xff);
351 e68_set_mem8 (c, addr + 2, (v >> 16) & 0xff);
352 e68_set_mem8 (c, addr + 4, (v >> 8) & 0xff);
353 e68_set_mem8 (c, addr + 6, v & 0xff);
354
355 e68_set_clk (c, 24);
356 e68_op_prefetch (c);
357}
358
359/* 01C0: BSET Dn, <EA> */
360static void op01c0 (e68000_t *c)
361{
362 unsigned i;
363 uint8_t s, d, m;
364
365 switch ((c->ir[0] >> 3) & 7) {
366 case 0x00:
367 op01c0_00 (c);
368 return;
369
370 case 0x01:
371 op01c0_01 (c);
372 return;
373 }
374
375 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &s);
376 i = e68_get_dreg32 (c, e68_ir_reg9 (c)) & 0x07;
377
378 m = 1 << i;
379 d = s | m;
380
381 e68_set_clk (c, 8);
382 e68_set_sr_z (c, (s & m) == 0);
383 e68_op_prefetch (c);
384 e68_op_set_ea8 (c, 0, 0, 0, d);
385}
386
387/* 0200: ANDI.B #XX, <EA> */
388static void op0200 (e68000_t *c)
389{
390 uint8_t s1, s2, d;
391
392 e68_op_prefetch8 (c, s1);
393
394 if ((c->ir[0] & 0x3f) == 0x3c) {
395 /* ANDI.B #XX, CCR */
396 e68_set_clk (c, 20);
397 e68_op_prefetch (c);
398 e68_set_ccr (c, e68_get_ccr (c) & s1 & E68_SR_XNZVC);
399 return;
400 }
401
402 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
403
404 d = s1 & s2;
405
406 e68_set_clk (c, 8);
407 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
408 e68_op_prefetch (c);
409 e68_op_set_ea8 (c, 0, 0, 0, d);
410}
411
412/* 0240_3C: ANDI.W #XXXX, SR */
413static void op0240_4c (e68000_t *c)
414{
415 uint16_t s1;
416
417 e68_op_supervisor (c);
418 e68_op_prefetch16 (c, s1);
419 e68_set_clk (c, 20);
420 e68_op_prefetch (c);
421 e68_set_sr (c, e68_get_sr (c) & s1);
422}
423
424/* 0240: ANDI.W #XXXX, <EA> */
425static void op0240 (e68000_t *c)
426{
427 uint16_t s1, s2, d;
428
429 if ((c->ir[0] & 0x3f) == 0x3c) {
430 op0240_4c (c);
431 return;
432 }
433
434 e68_op_prefetch16 (c, s1);
435 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
436
437 d = s1 & s2;
438
439 e68_set_clk (c, 8);
440 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
441 e68_op_prefetch (c);
442 e68_op_set_ea16 (c, 0, 0, 0, d);
443}
444
445/* 0280: ANDI.L #XXXXXXXX, <EA> */
446static void op0280 (e68000_t *c)
447{
448 uint32_t s1, s2, d;
449
450 e68_op_prefetch32 (c, s1);
451 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
452
453 d = s1 & s2;
454
455 e68_set_clk (c, 16);
456 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
457 e68_op_prefetch (c);
458 e68_op_set_ea32 (c, 0, 0, 0, d);
459}
460
461/* 0400: SUBI.B #XX, <EA> */
462static void op0400 (e68000_t *c)
463{
464 uint8_t s1, s2, d;
465
466 e68_op_prefetch8 (c, s1);
467 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
468
469 d = s2 - s1;
470
471 e68_set_clk (c, 8);
472 e68_cc_set_sub_8 (c, d, s1, s2);
473 e68_op_prefetch (c);
474 e68_op_set_ea8 (c, 0, 0, 0, d);
475}
476
477/* 0440: SUBI.W #XXXX, <EA> */
478static void op0440 (e68000_t *c)
479{
480 uint16_t s1, s2, d;
481
482 e68_op_prefetch16 (c, s1);
483 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
484
485 d = s2 - s1;
486
487 e68_set_clk (c, 8);
488 e68_cc_set_sub_16 (c, d, s1, s2);
489 e68_op_prefetch (c);
490 e68_op_set_ea16 (c, 0, 0, 0, d);
491}
492
493/* 0480: SUBI.L #XXXXXXXX, <EA> */
494static void op0480 (e68000_t *c)
495{
496 uint32_t s1, s2, d;
497
498 e68_op_prefetch32 (c, s1);
499 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
500
501 d = s2 - s1;
502
503 e68_set_clk (c, 16);
504 e68_cc_set_sub_32 (c, d, s1, s2);
505 e68_op_prefetch (c);
506 e68_op_set_ea32 (c, 0, 0, 0, d);
507}
508
509/* 0600: ADDI.B #XX, <EA> */
510static void op0600 (e68000_t *c)
511{
512 uint8_t s1, s2, d;
513
514 e68_op_prefetch8 (c, s1);
515 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
516
517 d = s1 + s2;
518
519 e68_set_clk (c, 8);
520 e68_cc_set_add_8 (c, d, s1, s2);
521 e68_op_prefetch (c);
522 e68_op_set_ea8 (c, 0, 0, 0, d);
523}
524
525/* 0640: ADDI.W #XXXX, <EA> */
526static void op0640 (e68000_t *c)
527{
528 uint16_t s1, s2, d;
529
530 e68_op_prefetch16 (c, s1);
531 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
532
533 d = s1 + s2;
534
535 e68_set_clk (c, 8);
536 e68_cc_set_add_16 (c, d, s1, s2);
537 e68_op_prefetch (c);
538 e68_op_set_ea16 (c, 0, 0, 0, d);
539}
540
541/* 0680: ADDI.L #XXXXXXXX, <EA> */
542static void op0680 (e68000_t *c)
543{
544 uint32_t s1, s2, d;
545
546 e68_op_prefetch32 (c, s1);
547 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
548
549 d = s1 + s2;
550
551 e68_set_clk (c, 16);
552 e68_cc_set_add_32 (c, d, s1, s2);
553 e68_op_prefetch (c);
554 e68_op_set_ea32 (c, 0, 0, 0, d);
555}
556
557/* 0800_00: BTST #XX, Dn */
558static void op0800_00 (e68000_t *c)
559{
560 uint16_t s1;
561 uint32_t s2, d;
562
563 e68_op_prefetch8 (c, s1);
564 s2 = e68_get_dreg32 (c, e68_ir_reg0 (c));
565
566 d = s2 & (1UL << (s1 & 0x1f));
567
568 e68_set_clk (c, 10);
569 e68_set_sr_z (c, d == 0);
570 e68_op_prefetch (c);
571}
572
573/* 0800: BTST #XX, <EA> */
574static void op0800 (e68000_t *c)
575{
576 uint8_t s1, s2, d;
577
578 if ((c->ir[0] & 0x38) == 0x00) {
579 op0800_00 (c);
580 return;
581 }
582
583 e68_op_prefetch8 (c, s1);
584 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x7fc, &s2);
585
586 d = s2 & (1 << (s1 & 7));
587
588 e68_set_clk (c, 8);
589 e68_set_sr_z (c, d == 0);
590 e68_op_prefetch (c);
591}
592
593/* 0840_00: BCHG #XX, Dn */
594static void op0840_00 (e68000_t *c)
595{
596 unsigned i, r;
597 uint32_t s, d, m;
598
599 e68_op_prefetch (c);
600 i = c->ir[1] & 0x1f;
601 r = e68_ir_reg0 (c);
602 s = e68_get_dreg32 (c, r);
603
604 m = 1UL << i;
605 d = s ^ m;
606
607 e68_set_clk (c, 12);
608 e68_set_sr_z (c, (s & m) == 0);
609 e68_op_prefetch (c);
610 e68_set_dreg32 (c, r, d);
611}
612
613/* 0840: BCHG #XX, <EA> */
614static void op0840 (e68000_t *c)
615{
616 unsigned i;
617 uint8_t s, d, m;
618
619 if ((c->ir[0] & 0x38) == 0x00) {
620 op0840_00 (c);
621 return;
622 }
623
624 e68_op_prefetch (c);
625 i = c->ir[1] & 0x07;
626 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &s);
627
628 m = 1 << i;
629 d = s ^ m;
630
631 e68_set_clk (c, 12);
632 e68_set_sr_z (c, (s & m) == 0);
633 e68_op_prefetch (c);
634 e68_op_set_ea8 (c, 0, 0, 0, d);
635}
636
637/* 0880_00: BCLR #XX, Dn */
638static void op0880_00 (e68000_t *c)
639{
640 unsigned i, r;
641 uint32_t s, d, m;
642
643 e68_op_prefetch (c);
644 i = c->ir[1] & 0x1f;
645 r = e68_ir_reg0 (c);
646 s = e68_get_dreg32 (c, r);
647
648 m = 1UL << i;
649 d = s & ~m;
650
651 e68_set_clk (c, 14);
652 e68_set_sr_z (c, (s & m) == 0);
653 e68_op_prefetch (c);
654 e68_set_dreg32 (c, r, d);
655}
656
657/* 0880: BCLR #XX, <EA> */
658static void op0880 (e68000_t *c)
659{
660 unsigned i;
661 uint8_t s, d, m;
662
663 if ((c->ir[0] & 0x38) == 0x00) {
664 op0880_00 (c);
665 return;
666 }
667
668 e68_op_prefetch (c);
669 i = c->ir[1] & 0x07;
670 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &s);
671
672 m = 1 << i;
673 d = s & ~m;
674
675 e68_set_clk (c, 12);
676 e68_set_sr_z (c, (s & m) == 0);
677 e68_op_prefetch (c);
678 e68_op_set_ea8 (c, 0, 0, 0, d);
679}
680
681/* 08C0_00: BSET #XX, Dn */
682static void op08c0_00 (e68000_t *c)
683{
684 unsigned i, r;
685 uint32_t s, d, m;
686
687 e68_op_prefetch (c);
688 i = c->ir[1] & 0x1f;
689 r = e68_ir_reg0 (c);
690 s = e68_get_dreg32 (c, r);
691
692 m = 1UL << i;
693 d = s | m;
694
695 e68_set_clk (c, 12);
696 e68_set_sr_z (c, (s & m) == 0);
697 e68_op_prefetch (c);
698 e68_set_dreg32 (c, r, d);
699}
700
701/* 08C0: BSET #XX, <EA> */
702static void op08c0 (e68000_t *c)
703{
704 unsigned i;
705 uint8_t s, d, m;
706
707 if ((c->ir[0] & 0x38) == 0x00) {
708 op08c0_00 (c);
709 return;
710 }
711
712 e68_op_prefetch (c);
713 i = c->ir[1] & 0x07;
714 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &s);
715
716 m = 1 << i;
717 d = s | m;
718
719 e68_set_clk (c, 12);
720 e68_set_sr_z (c, (s & m) == 0);
721 e68_op_prefetch (c);
722 e68_op_set_ea8 (c, 0, 0, 0, d);
723}
724
725/* 0A00: EORI.B #XX, <EA> */
726static void op0a00 (e68000_t *c)
727{
728 uint8_t s1, s2, d;
729
730 e68_op_prefetch8 (c, s1);
731
732 if ((c->ir[0] & 0x3f) == 0x3c) {
733 /* 0A00_3C: EORI.B #XX, CCR */
734 e68_set_clk (c, 20);
735 e68_op_prefetch (c);
736 e68_set_ccr (c, (e68_get_ccr (c) ^ s1) & E68_SR_XNZVC);
737 return;
738 }
739
740 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
741
742 d = s1 ^ s2;
743
744 e68_set_clk (c, 8);
745 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
746 e68_op_prefetch (c);
747 e68_op_set_ea8 (c, 0, 0, 0, d);
748}
749
750/* 0A40_3C: EORI.W #XXXX, SR */
751static void op0a40_3c (e68000_t *c)
752{
753 uint16_t s1;
754
755 e68_op_supervisor (c);
756 e68_op_prefetch16 (c, s1);
757 e68_set_clk (c, 20);
758 e68_op_prefetch (c);
759 e68_set_sr (c, (e68_get_sr (c) ^ s1) & E68_SR_MASK);
760}
761
762/* 0A40: EORI.W #XXXX, <EA> */
763static void op0a40 (e68000_t *c)
764{
765 uint16_t s1, s2, d;
766
767 if ((c->ir[0] & 0x3f) == 0x3c) {
768 op0a40_3c (c);
769 return;
770 }
771
772 e68_op_prefetch16 (c, s1);
773 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
774
775 d = s1 ^ s2;
776
777 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
778 e68_set_clk (c, 8);
779 e68_op_prefetch (c);
780 e68_op_set_ea16 (c, 0, 0, 0, d);
781}
782
783/* 0A80: EORI.L #XXXXXXXX, <EA> */
784static void op0a80 (e68000_t *c)
785{
786 uint32_t s1, s2, d;
787
788 e68_op_prefetch32 (c, s1);
789 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
790
791 d = s1 ^ s2;
792
793 e68_set_clk (c, 12);
794 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
795 e68_op_prefetch (c);
796 e68_op_set_ea32 (c, 0, 0, 0, d);
797}
798
799/* 0C00: CMPI.B #XX, <EA> */
800static void op0c00 (e68000_t *c)
801{
802 uint8_t s1, s2;
803
804 e68_op_prefetch8 (c, s1);
805 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x07fd, &s2);
806
807 e68_set_clk (c, 8);
808 e68_cc_set_cmp_8 (c, s2 - s1, s1, s2);
809 e68_op_prefetch (c);
810}
811
812/* 0C40: CMPI.W #XXXX, <EA> */
813static void op0c40 (e68000_t *c)
814{
815 uint16_t s1, s2;
816
817 e68_op_prefetch16 (c, s1);
818 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x07fd, &s2);
819
820 e68_set_clk (c, 8);
821 e68_cc_set_cmp_16 (c, s2 - s1, s1, s2);
822 e68_op_prefetch (c);
823}
824
825/* 0C80: CMPI.L #XXXXXXXX, <EA> */
826static void op0c80 (e68000_t *c)
827{
828 uint32_t s1, s2;
829
830 e68_op_prefetch32 (c, s1);
831 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x07fd, &s2);
832
833 e68_set_clk (c, 12);
834 e68_cc_set_cmp_32 (c, s2 - s1, s1, s2);
835 e68_op_prefetch (c);
836}
837
838/* 0E00: MOVES.B Rn, <EA> / MOVES.B <EA>, Rn*/
839static void op0e00 (e68000_t *c)
840{
841 unsigned reg;
842 uint8_t v;
843
844 e68_op_68010 (c);
845 e68_op_prefetch (c);
846
847 reg = (c->ir[1] >> 12) & 15;
848
849 if (c->ir[1] & 0x0800) {
850 if (reg & 8) {
851 v = e68_get_areg32 (c, reg & 7) & 0xff;
852 }
853 else {
854 v = e68_get_dreg8 (c, reg & 7);
855 }
856
857 e68_op_set_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, v);
858 }
859 else {
860 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x1fc, &v);
861
862 if (reg & 8) {
863 e68_set_areg32 (c, reg & 7, e68_exts8 (v));
864 }
865 else {
866 e68_set_dreg8 (c, reg & 7, v);
867 }
868 }
869
870 e68_set_clk (c, 4);
871 e68_op_prefetch (c);
872}
873
874/* 0E40: MOVES.W Rn, <EA> / MOVES.W <EA>, Rn*/
875static void op0e40 (e68000_t *c)
876{
877 unsigned reg;
878 uint16_t v;
879
880 e68_op_68010 (c);
881 e68_op_prefetch (c);
882
883 reg = (c->ir[1] >> 12) & 15;
884
885 if (c->ir[1] & 0x0800) {
886 if (reg & 8) {
887 v = e68_get_areg16 (c, reg & 7);
888 }
889 else {
890 v = e68_get_dreg16 (c, reg & 7);
891 }
892
893 e68_op_set_ea16 (c, 1, e68_ir_ea1 (c), 0x1fc, v);
894 }
895 else {
896 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x1fc, &v);
897
898 if (reg & 8) {
899 e68_set_areg16 (c, reg & 7, v);
900 }
901 else {
902 e68_set_dreg16 (c, reg & 7, v);
903 }
904 }
905
906 e68_set_clk (c, 4);
907 e68_op_prefetch (c);
908}
909
910/* 0E80: MOVES.L Rn, <EA> / MOVES.W <EA>, Rn*/
911static void op0e80 (e68000_t *c)
912{
913 unsigned reg;
914 uint32_t v;
915
916 e68_op_68010 (c);
917 e68_op_prefetch (c);
918
919 reg = (c->ir[1] >> 12) & 15;
920
921 if (c->ir[1] & 0x0800) {
922 if (reg & 8) {
923 v = e68_get_areg32 (c, reg & 7);
924 }
925 else {
926 v = e68_get_dreg32 (c, reg & 7);
927 }
928
929 e68_op_set_ea32 (c, 1, e68_ir_ea1 (c), 0x1fc, v);
930 }
931 else {
932 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x1fc, &v);
933
934 if (reg & 8) {
935 e68_set_areg32 (c, reg & 7, v);
936 }
937 else {
938 e68_set_dreg32 (c, reg & 7, v);
939 }
940 }
941
942 e68_set_clk (c, 4);
943 e68_op_prefetch (c);
944}
945
946/* 1000: MOVE.B <EA>, <EA> */
947static void op1000 (e68000_t *c)
948{
949 uint8_t val;
950
951 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x0fff, &val);
952 e68_op_set_ea8 (c, 1, e68_ir_ea2 (c), 0x01fd, val);
953 e68_set_clk (c, 4);
954 e68_cc_set_nz_8 (c, E68_SR_NZVC, val);
955 e68_op_prefetch (c);
956}
957
958/* 2000: MOVE.L <EA>, <EA> */
959static void op2000 (e68000_t *c)
960{
961 uint32_t val;
962
963 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &val);
964 e68_op_set_ea32 (c, 1, e68_ir_ea2 (c), 0x01fd, val);
965 e68_set_clk (c, 4);
966 e68_cc_set_nz_32 (c, E68_SR_NZVC, val);
967 e68_op_prefetch (c);
968}
969
970/* 2040: MOVEA.L <EA>, Ax */
971static void op2040 (e68000_t *c)
972{
973 uint32_t val;
974
975 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &val);
976 e68_set_areg32 (c, e68_ir_reg9 (c), val);
977 e68_set_clk (c, 4);
978 e68_op_prefetch (c);
979}
980
981/* 3000: MOVE.W <EA>, <EA> */
982static void op3000 (e68000_t *c)
983{
984 uint16_t val;
985
986 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &val);
987 e68_op_set_ea16 (c, 1, e68_ir_ea2 (c), 0x01fd, val);
988 e68_set_clk (c, 4);
989 e68_cc_set_nz_16 (c, E68_SR_NZVC, val);
990 e68_op_prefetch (c);
991}
992
993/* 3040: MOVEA.W <EA>, Ax */
994static void op3040 (e68000_t *c)
995{
996 uint16_t val;
997
998 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &val);
999 e68_set_areg32 (c, e68_ir_reg9 (c), e68_exts16 (val));
1000 e68_set_clk (c, 4);
1001 e68_op_prefetch (c);
1002}
1003
1004/* 4000: NEGX.B <EA> */
1005static void op4000 (e68000_t *c)
1006{
1007 uint8_t s, d;
1008
1009 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1010
1011 d = (~s + 1 - e68_get_sr_x (c)) & 0xff;
1012
1013 if (d != 0) {
1014 e68_set_sr_z (c, 0);
1015 }
1016
1017 e68_set_clk (c, 8);
1018 e68_set_sr_n (c, d & 0x80);
1019 e68_set_sr_v (c, d & s & 0x80);
1020 e68_set_sr_xc (c, (d | s) & 0x80);
1021 e68_op_prefetch (c);
1022 e68_op_set_ea8 (c, 0, 0, 0, d);
1023}
1024
1025/* 4040: NEGX.W <EA> */
1026static void op4040 (e68000_t *c)
1027{
1028 uint16_t s, d;
1029
1030 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1031
1032 d = (~s + 1 - e68_get_sr_x (c)) & 0xffff;
1033
1034 if (d != 0) {
1035 e68_set_sr_z (c, 0);
1036 }
1037
1038 e68_set_clk (c, 8);
1039 e68_set_sr_n (c, d & 0x8000);
1040 e68_set_sr_v (c, d & s & 0x8000);
1041 e68_set_sr_xc (c, (d | s) & 0x8000);
1042 e68_op_prefetch (c);
1043 e68_op_set_ea16 (c, 0, 0, 0, d);
1044}
1045
1046/* 4080: NEGX.L <EA> */
1047static void op4080 (e68000_t *c)
1048{
1049 uint32_t s, d;
1050
1051 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1052
1053 d = (~s + 1 - e68_get_sr_x (c)) & 0xffffffff;
1054
1055 if (d != 0) {
1056 e68_set_sr_z (c, 0);
1057 }
1058
1059 e68_set_clk (c, 10);
1060 e68_set_sr_n (c, d & 0x80000000);
1061 e68_set_sr_v (c, d & s & 0x80000000);
1062 e68_set_sr_xc (c, (d | s) & 0x80000000);
1063 e68_op_prefetch (c);
1064 e68_op_set_ea32 (c, 0, 0, 0, d);
1065}
1066
1067/* 40C0: MOVE.W SR, <EA> */
1068static void op40c0 (e68000_t *c)
1069{
1070 uint16_t s;
1071
1072 if (c->flags & E68_FLAG_68010) {
1073 e68_op_supervisor (c);
1074 }
1075
1076 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1077 s = e68_get_sr (c) & E68_SR_MASK;
1078
1079 e68_set_clk (c, 4);
1080 e68_op_prefetch (c);
1081 e68_op_set_ea16 (c, 0, 0, 0, s);
1082}
1083
1084/* 4180: CHK <EA>, Dx */
1085static void op4180 (e68000_t *c)
1086{
1087 int trap;
1088 uint16_t s1, s2;
1089
1090 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
1091 s2 = e68_get_dreg16 (c, e68_ir_reg9 (c));
1092
1093 if (s2 & 0x8000) {
1094 trap = 1;
1095 e68_set_sr_n (c, 1);
1096 }
1097 else if ((s1 & 0x8000) || (s2 > s1)) {
1098 trap = 1;
1099 e68_set_sr_n (c, 0);
1100 }
1101 else {
1102 trap = 0;
1103 }
1104
1105 e68_set_clk (c, 14);
1106
1107 if (trap) {
1108 e68_exception_check (c);
1109 }
1110 else {
1111 e68_op_prefetch (c);
1112 }
1113}
1114
1115/* 41C0: LEA <EA>, Ax */
1116static void op41c0 (e68000_t *c)
1117{
1118 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x7e4, 32)) {
1119 return;
1120 }
1121
1122 if (c->ea_typ != E68_EA_TYPE_MEM) {
1123 e68_exception_illegal (c);
1124 return;
1125 }
1126
1127 e68_set_clk (c, 4);
1128 e68_set_areg32 (c, e68_ir_reg9 (c), c->ea_val);
1129 e68_op_prefetch (c);
1130}
1131
1132/* 4200: CLR.B <EA> */
1133static void op4200 (e68000_t *c)
1134{
1135 uint8_t s;
1136
1137 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1138 e68_set_clk (c, 4);
1139 e68_set_cc (c, E68_SR_N | E68_SR_V | E68_SR_C, 0);
1140 e68_set_cc (c, E68_SR_Z, 1);
1141 e68_op_prefetch (c);
1142 e68_op_set_ea8 (c, 0, 0, 0, 0);
1143}
1144
1145/* 4240: CLR.W <EA> */
1146static void op4240 (e68000_t *c)
1147{
1148 uint16_t s;
1149
1150 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1151 e68_set_clk (c, 4);
1152 e68_set_cc (c, E68_SR_N | E68_SR_V | E68_SR_C, 0);
1153 e68_set_cc (c, E68_SR_Z, 1);
1154 e68_op_prefetch (c);
1155 e68_op_set_ea16 (c, 0, 0, 0, 0);
1156}
1157
1158/* 4280: CLR.L <EA> */
1159static void op4280 (e68000_t *c)
1160{
1161 uint32_t s;
1162
1163 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1164 e68_set_clk (c, 6);
1165 e68_set_cc (c, E68_SR_N | E68_SR_V | E68_SR_C, 0);
1166 e68_set_cc (c, E68_SR_Z, 1);
1167 e68_op_prefetch (c);
1168 e68_op_set_ea32 (c, 0, 0, 0, 0);
1169}
1170
1171/* 42C0: MOVE.W CCR, <EA> */
1172static void op42c0 (e68000_t *c)
1173{
1174 uint16_t s;
1175
1176 e68_op_68010 (c);
1177 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1178 s = e68_get_sr (c) & E68_CCR_MASK;
1179
1180 e68_set_clk (c, 4);
1181 e68_op_prefetch (c);
1182 e68_op_set_ea16 (c, 0, 0, 0, s);
1183}
1184
1185/* 4400: NEG.B <EA> */
1186static void op4400 (e68000_t *c)
1187{
1188 uint8_t s, d;
1189
1190 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1191
1192 d = (~s + 1) & 0xff;
1193
1194 e68_set_clk (c, 4);
1195 e68_set_sr_n (c, d & 0x80);
1196 e68_set_sr_v (c, d & s & 0x80);
1197 e68_set_sr_z (c, d == 0);
1198 e68_set_sr_xc (c, (d | s) & 0x80);
1199 e68_op_prefetch (c);
1200 e68_op_set_ea8 (c, 0, 0, 0, d);
1201}
1202
1203/* 4440: NEG.W <EA> */
1204static void op4440 (e68000_t *c)
1205{
1206 uint16_t s, d;
1207
1208 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1209
1210 d = (~s + 1) & 0xffff;
1211
1212 e68_set_clk (c, 4);
1213 e68_set_sr_n (c, d & 0x8000);
1214 e68_set_sr_v (c, d & s & 0x8000);
1215 e68_set_sr_z (c, d == 0);
1216 e68_set_sr_xc (c, (d | s) & 0x8000);
1217 e68_op_prefetch (c);
1218 e68_op_set_ea16 (c, 0, 0, 0, d);
1219}
1220
1221/* 4480: NEG.L <EA> */
1222static void op4480 (e68000_t *c)
1223{
1224 uint32_t s, d;
1225
1226 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1227
1228 d = (~s + 1) & 0xffffffff;
1229
1230 e68_set_clk (c, 6);
1231 e68_set_sr_n (c, d & 0x80000000);
1232 e68_set_sr_v (c, d & s & 0x80000000);
1233 e68_set_sr_z (c, d == 0);
1234 e68_set_sr_xc (c, (d | s) & 0x80000000);
1235 e68_op_prefetch (c);
1236 e68_op_set_ea32 (c, 0, 0, 0, d);
1237}
1238
1239/* 44C0: MOVE.W <EA>, CCR */
1240static void op44c0 (e68000_t *c)
1241{
1242 uint16_t s;
1243
1244 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s);
1245 e68_set_clk (c, 12);
1246 e68_set_ccr (c, s & E68_SR_XNZVC);
1247 e68_op_prefetch (c);
1248}
1249
1250/* 4600: NOT.B <EA> */
1251static void op4600 (e68000_t *c)
1252{
1253 uint8_t s, d;
1254
1255 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1256
1257 d = ~s & 0xff;
1258
1259 e68_set_clk (c, 4);
1260 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
1261 e68_op_prefetch (c);
1262 e68_op_set_ea8 (c, 0, 0, 0, d);
1263}
1264
1265/* 4640: NOT.W <EA> */
1266static void op4640 (e68000_t *c)
1267{
1268 uint16_t s, d;
1269
1270 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1271
1272 d = ~s & 0xffff;
1273
1274 e68_set_clk (c, 4);
1275 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
1276 e68_op_prefetch (c);
1277 e68_op_set_ea16 (c, 0, 0, 0, d);
1278}
1279
1280/* 4680: NOT.L <EA> */
1281static void op4680 (e68000_t *c)
1282{
1283 uint32_t s, d;
1284
1285 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1286
1287 d = ~s & 0xffffffff;
1288
1289 e68_set_clk (c, 6);
1290 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
1291 e68_op_prefetch (c);
1292 e68_op_set_ea32 (c, 0, 0, 0, d);
1293}
1294
1295/* 46C0: MOVE.W <EA>, SR */
1296static void op46c0 (e68000_t *c)
1297{
1298 uint16_t s;
1299
1300 e68_op_supervisor (c);
1301 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s);
1302 e68_set_clk (c, 12);
1303 e68_set_sr (c, s & E68_SR_MASK);
1304 e68_op_prefetch (c);
1305}
1306
1307/* 4800: NBCD.B <EA> */
1308static void op4800 (e68000_t *c)
1309{
1310 uint8_t s;
1311 uint16_t d;
1312
1313 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1314
1315 d = 0U - s - e68_get_sr_x (c);
1316
1317 if (d & 0x0f) {
1318 d -= 0x06;
1319 }
1320
1321 if (d & 0xf0) {
1322 d -= 0x60;
1323 }
1324
1325 e68_set_cc (c, E68_SR_XC, d & 0xff00);
1326
1327 if (d & 0xff) {
1328 e68_set_sr_z (c, 0);
1329 }
1330
1331 e68_set_clk (c, 6);
1332 e68_op_prefetch (c);
1333 e68_op_set_ea8 (c, 0, 0, 0, d & 0xff);
1334}
1335
1336/* 4840_00: SWAP Dx */
1337static void op4840_00 (e68000_t *c)
1338{
1339 unsigned reg;
1340 uint32_t val;
1341
1342 reg = e68_ir_reg0 (c);
1343 val = e68_get_dreg32 (c, reg);
1344
1345 val = ((val << 16) | (val >> 16)) & 0xffffffff;
1346
1347 e68_set_clk (c, 4);
1348 e68_cc_set_nz_32 (c, E68_SR_NZVC, val);
1349 e68_set_dreg32 (c, reg, val);
1350 e68_op_prefetch (c);
1351}
1352
1353/* 4840: PEA <EA> */
1354static void op4840 (e68000_t *c)
1355{
1356 if ((c->ir[0] & 0x38) == 0x00) {
1357 op4840_00 (c);
1358 return;
1359 }
1360
1361 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x7e4, 32)) {
1362 return;
1363 }
1364
1365 if (c->ea_typ != E68_EA_TYPE_MEM) {
1366 e68_exception_illegal (c);
1367 return;
1368 }
1369
1370 e68_set_clk (c, 12);
1371 e68_push32 (c, c->ea_val);
1372 e68_op_prefetch (c);
1373}
1374
1375/* 4880_00: EXT.W Dn */
1376static void op4880_00 (e68000_t *c)
1377{
1378 unsigned r;
1379 uint16_t s, d;
1380
1381 r = e68_ir_reg0 (c);
1382 s = e68_get_dreg8 (c, r);
1383
1384 d = (s & 0x80) ? (s | 0xff00) : s;
1385
1386 e68_set_clk (c, 4);
1387 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
1388 e68_set_dreg16 (c, r, d);
1389 e68_op_prefetch (c);
1390}
1391
1392/* 4880_04: MOVEM.W list, -(Ax) */
1393static void op4880_04 (e68000_t *c)
1394{
1395 unsigned i;
1396 uint16_t r, v;
1397 uint32_t a;
1398
1399 e68_op_prefetch16 (c, r);
1400 a = e68_get_areg32 (c, e68_ir_reg0 (c));
1401
1402 if (r != 0) {
1403 e68_op_chk_addr (c, a, 1);
1404 }
1405
1406 for (i = 0; i < 16; i++) {
1407 if (r & 1) {
1408 a = (a - 2) & 0xffffffff;
1409 if (i < 8) {
1410 v = e68_get_areg16 (c, 7 - i);
1411 }
1412 else {
1413 v = e68_get_dreg16 (c, 15 - i);
1414 }
1415
1416 e68_set_mem16 (c, a, v);
1417
1418 e68_set_clk (c, 4);
1419 }
1420 r >>= 1;
1421 }
1422
1423 e68_set_areg32 (c, e68_ir_reg0 (c), a);
1424
1425 e68_set_clk (c, 8);
1426 e68_op_prefetch (c);
1427}
1428
1429/* 4880_XX: MOVEM.W list, <EA> */
1430static void op4880_xx (e68000_t *c)
1431{
1432 unsigned i;
1433 uint16_t r, v;
1434 uint32_t a;
1435
1436 e68_op_prefetch16 (c, r);
1437
1438 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x1e4, 16)) {
1439 return;
1440 }
1441
1442 if (c->ea_typ != E68_EA_TYPE_MEM) {
1443 e68_exception_illegal (c);
1444 return;
1445 }
1446
1447 a = c->ea_val;
1448
1449 if (r != 0) {
1450 e68_op_chk_addr (c, a, 1);
1451 }
1452
1453 for (i = 0; i < 16; i++) {
1454 if (r & 1) {
1455 if (i < 8) {
1456 v = e68_get_dreg16 (c, i);
1457 }
1458 else {
1459 v = e68_get_areg16 (c, i - 8);
1460 }
1461 e68_set_mem16 (c, a, v);
1462 a = (a + 2) & 0xffffffff;
1463
1464 e68_set_clk (c, 4);
1465 }
1466 r >>= 1;
1467 }
1468
1469 e68_set_clk (c, 8);
1470 e68_op_prefetch (c);
1471}
1472
1473/* 4880: misc */
1474static void op4880 (e68000_t *c)
1475{
1476 switch ((c->ir[0] >> 3) & 7) {
1477 case 0x00:
1478 op4880_00 (c);
1479 break;
1480
1481 case 0x04:
1482 op4880_04 (c);
1483 break;
1484
1485 default:
1486 op4880_xx (c);
1487 break;
1488 }
1489}
1490
1491/* 48C0_00: EXT.L Dn */
1492static void op48c0_00 (e68000_t *c)
1493{
1494 unsigned r;
1495 uint32_t s, d;
1496
1497 r = e68_ir_reg0 (c);
1498 s = e68_get_dreg16 (c, r);
1499
1500 d = (s & 0x8000) ? (s | 0xffff0000) : s;
1501
1502 e68_set_clk (c, 4);
1503 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
1504 e68_set_dreg32 (c, r, d);
1505 e68_op_prefetch (c);
1506}
1507
1508/* 48C0_04: MOVEM.L list, -(Ax) */
1509static void op48c0_04 (e68000_t *c)
1510{
1511 unsigned i;
1512 uint16_t r;
1513 uint32_t a, v;
1514
1515 e68_op_prefetch16 (c, r);
1516 a = e68_get_areg32 (c, e68_ir_reg0 (c));
1517
1518 if (r != 0) {
1519 e68_op_chk_addr (c, a, 1);
1520 }
1521
1522 for (i = 0; i < 16; i++) {
1523 if (r & 1) {
1524 a = (a - 4) & 0xffffffff;
1525 if (i < 8) {
1526 v = e68_get_areg32 (c, 7 - i);
1527 }
1528 else {
1529 v = e68_get_dreg32 (c, 15 - i);
1530 }
1531 e68_set_mem32 (c, a, v);
1532
1533 e68_set_clk (c, 8);
1534 }
1535 r >>= 1;
1536 }
1537
1538 e68_set_areg32 (c, e68_ir_reg0 (c), a);
1539
1540 e68_set_clk (c, 8);
1541 e68_op_prefetch (c);
1542}
1543
1544/* 48C0_XX: MOVEM.L list, <EA> */
1545static void op48c0_xx (e68000_t *c)
1546{
1547 unsigned i;
1548 uint16_t r;
1549 uint32_t a, v;
1550
1551 e68_op_prefetch16 (c, r);
1552
1553 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x1e4, 32)) {
1554 return;
1555 }
1556
1557 if (c->ea_typ != E68_EA_TYPE_MEM) {
1558 e68_exception_illegal (c);
1559 return;
1560 }
1561
1562 a = c->ea_val;
1563
1564 if (r != 0) {
1565 e68_op_chk_addr (c, a, 1);
1566 }
1567
1568 for (i = 0; i < 16; i++) {
1569 if (r & 1) {
1570 if (i < 8) {
1571 v = e68_get_dreg32 (c, i);
1572 }
1573 else {
1574 v = e68_get_areg32 (c, i - 8);
1575 }
1576 e68_set_mem32 (c, a, v);
1577 a = (a + 4) & 0xffffffff;
1578
1579 e68_set_clk (c, 8);
1580 }
1581 r >>= 1;
1582 }
1583
1584 e68_set_clk (c, 8);
1585 e68_op_prefetch (c);
1586}
1587
1588/* 48C0: misc */
1589static void op48c0 (e68000_t *c)
1590{
1591 switch ((c->ir[0] >> 3) & 7) {
1592 case 0x00:
1593 op48c0_00 (c);
1594 break;
1595
1596 case 0x04:
1597 op48c0_04 (c);
1598 break;
1599
1600 default:
1601 op48c0_xx (c);
1602 break;
1603 }
1604}
1605
1606/* 49C0: misc */
1607static void op49c0 (e68000_t *c)
1608{
1609 c->op49c0[(c->ir[0] >> 3) & 7] (c);
1610}
1611
1612/* 4A00: TST.B <EA> */
1613static void op4a00 (e68000_t *c)
1614{
1615 uint8_t s;
1616
1617 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1618 e68_set_clk (c, 8);
1619 e68_cc_set_nz_8 (c, E68_SR_NZVC, s);
1620 e68_op_prefetch (c);
1621}
1622
1623/* 4A40: TST.W <EA> */
1624static void op4a40 (e68000_t *c)
1625{
1626 uint16_t s;
1627
1628 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1629 e68_set_clk (c, 8);
1630 e68_cc_set_nz_16 (c, E68_SR_NZVC, s);
1631 e68_op_prefetch (c);
1632}
1633
1634/* 4A80: TST.L <EA> */
1635static void op4a80 (e68000_t *c)
1636{
1637 uint32_t s;
1638
1639 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1640 e68_set_clk (c, 8);
1641 e68_cc_set_nz_32 (c, E68_SR_NZVC, s);
1642 e68_op_prefetch (c);
1643}
1644
1645/* 4AFC: ILLEGAL */
1646static void op4afc (e68000_t *c)
1647{
1648 unsigned long pc;
1649
1650 if (c->hook != NULL) {
1651 pc = e68_get_pc (c);
1652
1653 if (c->hook (c->hook_ext, c->ir[2]) == 0) {
1654 if (e68_get_pc (c) == pc) {
1655 e68_op_prefetch (c);
1656 e68_op_prefetch (c);
1657 }
1658
1659 e68_set_clk (c, 8);
1660
1661 return;
1662 }
1663 }
1664
1665 e68_exception_illegal (c);
1666}
1667
1668/* 4AC0: TAS <EA> */
1669static void op4ac0 (e68000_t *c)
1670{
1671 uint8_t s, d;
1672
1673 if (c->ir[0] == 0x4afc) {
1674 op4afc (c);
1675 return;
1676 }
1677
1678 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s);
1679
1680 d = s | 0x80;
1681
1682 e68_set_clk (c, 8);
1683 e68_cc_set_nz_8 (c, E68_SR_NZVC, s);
1684 e68_op_prefetch (c);
1685 e68_op_set_ea8 (c, 0, 0, 0, d);
1686}
1687
1688/* 4C80_03: MOVEM.W (Ax)+, list */
1689static void op4c80_03 (e68000_t *c)
1690{
1691 unsigned i;
1692 uint16_t r;
1693 uint32_t a, v;
1694
1695 e68_op_prefetch16 (c, r);
1696
1697 a = e68_get_areg32 (c, e68_ir_reg0 (c));
1698
1699 if (r != 0) {
1700 e68_op_chk_addr (c, a, 0);
1701 }
1702
1703 for (i = 0; i < 16; i++) {
1704 if (r & 1) {
1705 v = e68_get_mem16 (c, a);
1706 v = e68_exts16 (v);
1707 if (i < 8) {
1708 e68_set_dreg32 (c, i, v);
1709 }
1710 else {
1711 e68_set_areg32 (c, i - 8, v);
1712 }
1713 a = (a + 2) & 0xffffffff;
1714
1715 e68_set_clk (c, 4);
1716 }
1717 r >>= 1;
1718 }
1719
1720 e68_set_areg32 (c, e68_ir_reg0 (c), a);
1721
1722 e68_set_clk (c, 12);
1723 e68_op_prefetch (c);
1724}
1725
1726/* 4C80_XX: MOVEM.W <EA>, list */
1727static void op4c80_xx (e68000_t *c)
1728{
1729 unsigned i;
1730 uint16_t r;
1731 uint32_t a, v;
1732
1733 e68_op_prefetch16 (c, r);
1734
1735 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x7ec, 16)) {
1736 return;
1737 }
1738
1739 if (c->ea_typ != E68_EA_TYPE_MEM) {
1740 e68_exception_illegal (c);
1741 return;
1742 }
1743
1744 a = c->ea_val;
1745
1746 if (r != 0) {
1747 e68_op_chk_addr (c, a, 0);
1748 }
1749
1750 for (i = 0; i < 16; i++) {
1751 if (r & 1) {
1752 v = e68_get_mem16 (c, a);
1753 v = e68_exts16 (v);
1754 if (i < 8) {
1755 e68_set_dreg32 (c, i, v);
1756 }
1757 else {
1758 e68_set_areg32 (c, i - 8, v);
1759 }
1760 a = (a + 2) & 0xffffffff;
1761
1762 e68_set_clk (c, 4);
1763 }
1764 r >>= 1;
1765 }
1766
1767 e68_set_clk (c, 12);
1768 e68_op_prefetch (c);
1769}
1770
1771/* 4C80: misc */
1772static void op4c80 (e68000_t *c)
1773{
1774 switch ((c->ir[0] >> 3) & 7) {
1775 case 0x00:
1776 e68_op_undefined (c);
1777 break;
1778
1779 case 0x03:
1780 op4c80_03 (c);
1781 break;
1782
1783 default:
1784 op4c80_xx (c);
1785 break;
1786 }
1787}
1788
1789/* 4CC0_03: MOVEM.L (Ax)+, list */
1790static void op4cc0_03 (e68000_t *c)
1791{
1792 unsigned i;
1793 uint16_t r;
1794 uint32_t a, v;
1795
1796 e68_op_prefetch16 (c, r);
1797
1798 a = e68_get_areg32 (c, e68_ir_reg0 (c));
1799
1800 if (r != 0) {
1801 e68_op_chk_addr (c, a, 0);
1802 }
1803
1804 for (i = 0; i < 16; i++) {
1805 if (r & 1) {
1806 v = e68_get_mem32 (c, a);
1807 if (i < 8) {
1808 e68_set_dreg32 (c, i, v);
1809 }
1810 else {
1811 e68_set_areg32 (c, i - 8, v);
1812 }
1813 a = (a + 4) & 0xffffffff;
1814
1815 e68_set_clk (c, 8);
1816 }
1817 r >>= 1;
1818 }
1819
1820 e68_set_areg32 (c, e68_ir_reg0 (c), a);
1821
1822 e68_set_clk (c, 12);
1823 e68_op_prefetch (c);
1824}
1825
1826/* 4CC0_XX: MOVEM.L <EA>, list */
1827static void op4cc0_xx (e68000_t *c)
1828{
1829 unsigned i;
1830 uint16_t r;
1831 uint32_t a, v;
1832
1833 e68_op_prefetch16 (c, r);
1834
1835 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x7ec, 32)) {
1836 return;
1837 }
1838
1839 if (c->ea_typ != E68_EA_TYPE_MEM) {
1840 e68_exception_illegal (c);
1841 return;
1842 }
1843
1844 a = c->ea_val;
1845
1846 if (r != 0) {
1847 e68_op_chk_addr (c, a, 0);
1848 }
1849
1850 for (i = 0; i < 16; i++) {
1851 if (r & 1) {
1852 v = e68_get_mem32 (c, a);
1853 if (i < 8) {
1854 e68_set_dreg32 (c, i, v);
1855 }
1856 else {
1857 e68_set_areg32 (c, i - 8, v);
1858 }
1859 a = (a + 4) & 0xffffffff;
1860
1861 e68_set_clk (c, 8);
1862 }
1863 r >>= 1;
1864 }
1865
1866 e68_set_clk (c, 12);
1867 e68_op_prefetch (c);
1868}
1869
1870/* 4CC0: misc */
1871static void op4cc0 (e68000_t *c)
1872{
1873 switch ((c->ir[0] >> 3) & 7) {
1874 case 0x00:
1875 e68_op_undefined (c);
1876 break;
1877
1878 case 0x03:
1879 op4cc0_03 (c);
1880 break;
1881
1882 default:
1883 op4cc0_xx (c);
1884 break;
1885 }
1886}
1887
1888/* 4E40_00: TRAP #XX */
1889static void op4e40_00 (e68000_t *c)
1890{
1891 e68_op_prefetch (c);
1892 e68_exception_trap (c, c->ir[0] & 15);
1893}
1894
1895/* 4E40_02: LINK An, #XXXX */
1896static void op4e40_02 (e68000_t *c)
1897{
1898 unsigned r;
1899 uint32_t s;
1900
1901 e68_op_prefetch (c);
1902
1903 r = e68_ir_reg0 (c);
1904 s = e68_exts16 (c->ir[1]);
1905
1906 e68_set_clk (c, 16);
1907 e68_set_areg32 (c, 7, e68_get_areg32 (c, 7) - 4);
1908 e68_set_mem32 (c, e68_get_areg32 (c, 7), e68_get_areg32 (c, r));
1909 e68_set_areg32 (c, r, e68_get_areg32 (c, 7));
1910 e68_set_areg32 (c, 7, e68_get_areg32 (c, 7) + s);
1911 e68_op_prefetch (c);
1912}
1913
1914/* 4E40_03: UNLK An */
1915static void op4e40_03 (e68000_t *c)
1916{
1917 unsigned r;
1918 uint32_t a;
1919
1920 r = e68_ir_reg0 (c);
1921 a = e68_get_areg32 (c, r);
1922
1923 e68_op_chk_addr (c, a, 0);
1924
1925 e68_set_clk (c, 12);
1926 e68_set_areg32 (c, 7, a);
1927 e68_set_areg32 (c, r, e68_get_mem32 (c, a));
1928 e68_set_areg32 (c, 7, e68_get_areg32 (c, 7) + 4);
1929 e68_op_prefetch (c);
1930}
1931
1932/* 4E40_04: MOVE.L Ax, USP */
1933static void op4e40_04 (e68000_t *c)
1934{
1935 uint32_t s;
1936
1937 e68_op_supervisor (c);
1938
1939 s = e68_get_areg32 (c, e68_ir_reg0 (c));
1940
1941 e68_set_usp (c, s);
1942 e68_set_clk (c, 4);
1943 e68_op_prefetch (c);
1944}
1945
1946/* 4E40_05: MOVE.L USP, Ax */
1947static void op4e40_05 (e68000_t *c)
1948{
1949 uint32_t s;
1950
1951 e68_op_supervisor (c);
1952
1953 s = e68_get_usp (c);
1954
1955 e68_set_areg32 (c, e68_ir_reg0 (c), s);
1956 e68_set_clk (c, 4);
1957 e68_op_prefetch (c);
1958}
1959
1960/* 4E70: RESET */
1961static void op4e70 (e68000_t *c)
1962{
1963 e68_op_supervisor (c);
1964
1965 if (c->flags & E68_FLAG_NORESET) {
1966 e68_set_clk (c, 4);
1967 e68_op_prefetch (c);
1968 return;
1969 }
1970
1971 e68_set_clk (c, 132);
1972 e68_reset (c);
1973}
1974
1975/* 4E71: NOP */
1976static void op4e71 (e68000_t *c)
1977{
1978 e68_set_clk (c, 4);
1979 e68_op_prefetch (c);
1980}
1981
1982/* 4E72: STOP #XXXX */
1983static void op4e72 (e68000_t *c)
1984{
1985 e68_op_supervisor (c);
1986 e68_op_prefetch (c);
1987 e68_set_sr (c, c->ir[1]);
1988 e68_set_clk (c, 4);
1989 c->halt |= 1;
1990 e68_op_prefetch (c);
1991}
1992
1993/* 4E73: RTE */
1994static void op4e73 (e68000_t *c)
1995{
1996 uint32_t sp, pc;
1997 uint16_t sr, fmt;
1998
1999 e68_op_supervisor (c);
2000
2001 sp = e68_get_ssp (c);
2002 sr = e68_get_mem16 (c, sp);
2003 pc = e68_get_mem32 (c, sp + 2);
2004
2005 if (c->flags & E68_FLAG_68010) {
2006 fmt = e68_get_mem16 (c, sp + 6);
2007
2008 switch ((fmt >> 12) & 0x0f) {
2009 case 0:
2010 case 8:
2011 break;
2012
2013 default:
2014 e68_exception_format (c);
2015 return;
2016 }
2017 }
2018
2019 e68_set_sr (c, sr);
2020 e68_set_pc (c, pc);
2021 e68_set_ir_pc (c, pc);
2022
2023 if (c->flags & E68_FLAG_68010) {
2024 e68_set_ssp (c, sp + 8);
2025 }
2026 else {
2027 e68_set_ssp (c, sp + 6);
2028 }
2029
2030 e68_set_clk (c, 20);
2031 e68_op_prefetch (c);
2032 e68_op_prefetch (c);
2033 e68_set_pc (c, pc);
2034}
2035
2036/* 4E74: RTD */
2037static void op4e74 (e68000_t *c)
2038{
2039 uint32_t sp, im;
2040
2041 e68_op_68010 (c);
2042 e68_op_prefetch (c);
2043
2044 im = e68_exts16 (c->ir[1]);
2045 sp = e68_get_areg32 (c, 7);
2046
2047 e68_set_ir_pc (c, e68_get_mem32 (c, sp));
2048 e68_set_areg32 (c, 7, sp + 4 + im);
2049
2050 e68_set_clk (c, 16);
2051 e68_op_prefetch (c);
2052 e68_op_prefetch (c);
2053 e68_set_pc (c, e68_get_ir_pc (c) - 4);
2054}
2055
2056/* 4E75: RTS */
2057static void op4e75 (e68000_t *c)
2058{
2059 uint32_t sp;
2060
2061 sp = e68_get_areg32 (c, 7);
2062
2063 e68_set_ir_pc (c, e68_get_mem32 (c, sp));
2064 e68_set_areg32 (c, 7, sp + 4);
2065
2066 e68_set_clk (c, 16);
2067 e68_op_prefetch (c);
2068 e68_op_prefetch (c);
2069 e68_set_pc (c, e68_get_ir_pc (c) - 4);
2070}
2071
2072/* 4E76: TRAPV */
2073static void op4e76 (e68000_t *c)
2074{
2075 e68_op_prefetch (c);
2076
2077 if (e68_get_sr_v (c)) {
2078 e68_exception_overflow (c);
2079 }
2080 else {
2081 e68_set_clk (c, 4);
2082 }
2083}
2084
2085/* 4E77: RTR */
2086static void op4e77 (e68000_t *c)
2087{
2088 uint32_t sp;
2089
2090 sp = e68_get_areg32 (c, 7);
2091
2092 e68_set_ccr (c, e68_get_mem16 (c, sp) & E68_CCR_MASK);
2093 e68_set_ir_pc (c, e68_get_mem32 (c, sp + 2));
2094 e68_set_areg32 (c, 7, sp + 6);
2095
2096 e68_set_clk (c, 20);
2097 e68_op_prefetch (c);
2098 e68_op_prefetch (c);
2099 e68_set_pc (c, e68_get_ir_pc (c) - 4);
2100}
2101
2102/* 4E7A: MOVEC Rc, Rx */
2103static void op4e7a (e68000_t *c)
2104{
2105 unsigned cr, rx;
2106 uint32_t val;
2107
2108 e68_op_68010 (c);
2109 e68_op_supervisor (c);
2110 e68_op_prefetch (c);
2111
2112 cr = c->ir[1] & 0x0fff;
2113 rx = (c->ir[1] >> 12) & 0x0f;
2114
2115 switch (cr) {
2116 case 0x000:
2117 val = e68_get_sfc (c);
2118 break;
2119
2120 case 0x001:
2121 val = e68_get_dfc (c);
2122 break;
2123
2124 case 0x002:
2125 if (((c)->flags & E68_FLAG_68020) == 0) {
2126 return (e68_op_undefined (c));
2127 }
2128 val = e68_get_cacr (c);
2129 break;
2130
2131 case 0x800:
2132 val = e68_get_usp (c);
2133 break;
2134
2135 case 0x801:
2136 val = e68_get_vbr (c);
2137 break;
2138
2139 case 0x802:
2140 if (((c)->flags & E68_FLAG_68020) == 0) {
2141 return (e68_op_undefined (c));
2142 }
2143 val = e68_get_caar (c);
2144 break;
2145
2146 default:
2147 e68_exception_illegal (c);
2148 return;
2149 }
2150
2151 if (rx & 8) {
2152 e68_set_areg32 (c, rx & 7, val);
2153 }
2154 else {
2155 e68_set_dreg32 (c, rx & 7, val);
2156 }
2157
2158 e68_set_clk (c, 12);
2159 e68_op_prefetch (c);
2160}
2161
2162/* 4E7B: MOVEC Rx, Rc */
2163static void op4e7b (e68000_t *c)
2164{
2165 unsigned cr, rx;
2166 uint32_t val;
2167
2168 e68_op_68010 (c);
2169 e68_op_supervisor (c);
2170 e68_op_prefetch (c);
2171
2172 cr = c->ir[1] & 0x0fff;
2173 rx = (c->ir[1] >> 12) & 0x0f;
2174
2175 if (rx & 8) {
2176 val = e68_get_areg32 (c, rx & 7);
2177 }
2178 else {
2179 val = e68_get_dreg32 (c, rx & 7);
2180 }
2181
2182 switch (cr) {
2183 case 0x000:
2184 e68_set_sfc (c, val);
2185 break;
2186
2187 case 0x001:
2188 e68_set_dfc (c, val);
2189 break;
2190
2191 case 0x002:
2192 if (((c)->flags & E68_FLAG_68020) == 0) {
2193 return (e68_op_undefined (c));
2194 }
2195 e68_set_cacr (c, val);
2196 break;
2197
2198 case 0x800:
2199 e68_set_usp (c, val);
2200 break;
2201
2202 case 0x801:
2203 e68_set_vbr (c, val);
2204 break;
2205
2206 case 0x802:
2207 if (((c)->flags & E68_FLAG_68020) == 0) {
2208 return (e68_op_undefined (c));
2209 }
2210 e68_set_caar (c, val);
2211 break;
2212
2213 default:
2214 e68_exception_illegal (c);
2215 return;
2216 }
2217
2218 e68_set_clk (c, 10);
2219 e68_op_prefetch (c);
2220}
2221
2222/* 4E40: misc */
2223static void op4e40 (e68000_t *c)
2224{
2225 switch (c->ir[0]) {
2226 case 0x4e70:
2227 op4e70 (c);
2228 return;
2229
2230 case 0x4e71:
2231 op4e71 (c);
2232 return;
2233
2234 case 0x4e72:
2235 op4e72 (c);
2236 return;
2237
2238 case 0x4e73:
2239 op4e73 (c);
2240 return;
2241
2242 case 0x4e74:
2243 op4e74 (c);
2244 return;
2245
2246 case 0x4e75:
2247 op4e75 (c);
2248 return;
2249
2250 case 0x4e76:
2251 op4e76 (c);
2252 return;
2253
2254 case 0x4e77:
2255 op4e77 (c);
2256 return;
2257
2258 case 0x4e7a:
2259 op4e7a (c);
2260 return;
2261
2262 case 0x4e7b:
2263 op4e7b (c);
2264 return;
2265 }
2266
2267 switch ((c->ir[0] >> 3) & 7) {
2268 case 0x00:
2269 case 0x01:
2270 op4e40_00 (c);
2271 return;
2272
2273 case 0x02:
2274 op4e40_02 (c);
2275 return;
2276
2277 case 0x03:
2278 op4e40_03 (c);
2279 return;
2280
2281 case 0x04:
2282 op4e40_04 (c);
2283 return;
2284
2285 case 0x05:
2286 op4e40_05 (c);
2287 return;
2288 }
2289
2290 e68_op_undefined (c);
2291}
2292
2293/* 4E80: JSR <EA> */
2294static void op4e80 (e68000_t *c)
2295{
2296 uint32_t addr;
2297
2298 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x07e4, 32)) {
2299 return;
2300 }
2301
2302 if (c->ea_typ != E68_EA_TYPE_MEM) {
2303 e68_exception_illegal (c);
2304 return;
2305 }
2306
2307 e68_set_clk (c, 16);
2308 addr = e68_get_ir_pc (c) - 2;
2309 e68_set_ir_pc (c, c->ea_val);
2310 e68_op_prefetch (c);
2311 e68_push32 (c, addr);
2312 e68_op_prefetch (c);
2313 e68_set_pc (c, c->ea_val);
2314}
2315
2316/* 4EC0: JMP <EA> */
2317static void op4ec0 (e68000_t *c)
2318{
2319 if (e68_ea_get_ptr (c, e68_ir_ea1 (c), 0x07e4, 32)) {
2320 return;
2321 }
2322
2323 if (c->ea_typ != E68_EA_TYPE_MEM) {
2324 e68_exception_illegal (c);
2325 return;
2326 }
2327
2328 e68_set_clk (c, 8);
2329 e68_set_ir_pc (c, c->ea_val);
2330 e68_op_prefetch (c);
2331 e68_op_prefetch (c);
2332 e68_set_pc (c, c->ea_val);
2333}
2334
2335/* 5000: ADDQ.B #X, <EA> */
2336static void op5000 (e68000_t *c)
2337{
2338 uint8_t s1, s2, d;
2339
2340 s1 = (c->ir[0] >> 9) & 7;
2341 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
2342
2343 if (s1 == 0) {
2344 s1 = 8;
2345 }
2346
2347 d = s1 + s2;
2348
2349 e68_set_clk (c, 8);
2350 e68_cc_set_add_8 (c, d, s1, s2);
2351 e68_op_prefetch (c);
2352 e68_op_set_ea8 (c, 0, 0, 0, d);
2353}
2354
2355/* 5040_08: ADDQ.W #X, Ax */
2356static void op5040_08 (e68000_t *c)
2357{
2358 unsigned r;
2359 uint32_t s1, s2, d;
2360
2361 r = e68_ir_reg0 (c);
2362
2363 s1 = (c->ir[0] >> 9) & 7;
2364 s2 = e68_get_areg32 (c, r);
2365
2366 if (s1 == 0) {
2367 s1 = 8;
2368 }
2369
2370 d = s1 + s2;
2371
2372 e68_set_clk (c, 8);
2373 e68_op_prefetch (c);
2374 e68_set_areg32 (c, r, d);
2375}
2376
2377/* 5040: ADDQ.W #X, <EA> */
2378static void op5040 (e68000_t *c)
2379{
2380 uint16_t s1, s2, d;
2381
2382 if ((c->ir[0] & 0x38) == 0x08) {
2383 op5040_08 (c);
2384 return;
2385 }
2386
2387 s1 = (c->ir[0] >> 9) & 7;
2388 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
2389
2390 if (s1 == 0) {
2391 s1 = 8;
2392 }
2393
2394 d = s1 + s2;
2395
2396 e68_set_clk (c, 8);
2397 e68_cc_set_add_16 (c, d, s1, s2);
2398 e68_op_prefetch (c);
2399 e68_op_set_ea16 (c, 0, 0, 0, d);
2400}
2401
2402/* 5080_08: ADDQ.L #X, Ax */
2403static void op5080_08 (e68000_t *c)
2404{
2405 unsigned r;
2406 uint32_t s1, s2, d;
2407
2408 r = e68_ir_reg0 (c);
2409
2410 s1 = (c->ir[0] >> 9) & 7;
2411 s2 = e68_get_areg32 (c, r);
2412
2413 if (s1 == 0) {
2414 s1 = 8;
2415 }
2416
2417 d = s1 + s2;
2418
2419 e68_set_clk (c, 12);
2420 e68_op_prefetch (c);
2421 e68_set_areg32 (c, r, d);
2422}
2423
2424/* 5080: ADDQ.L #X, <EA> */
2425static void op5080 (e68000_t *c)
2426{
2427 uint32_t s1, s2, d;
2428
2429 if ((c->ir[0] & 0x38) == 0x08) {
2430 op5080_08 (c);
2431 return;
2432 }
2433
2434 s1 = (c->ir[0] >> 9) & 7;
2435 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
2436
2437 if (s1 == 0) {
2438 s1 = 8;
2439 }
2440
2441 d = s1 + s2;
2442
2443 e68_set_clk (c, 12);
2444 e68_cc_set_add_32 (c, d, s1, s2);
2445 e68_op_prefetch (c);
2446 e68_op_set_ea32 (c, 0, 0, 0, d);
2447}
2448
2449/* 5100: SUBQ.B #X, <EA> */
2450static void op5100 (e68000_t *c)
2451{
2452 uint8_t s1, s2, d;
2453
2454 s1 = (c->ir[0] >> 9) & 7;
2455 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
2456
2457 if (s1 == 0) {
2458 s1 = 8;
2459 }
2460
2461 d = s2 - s1;
2462
2463 e68_set_clk (c, 8);
2464 e68_cc_set_sub_8 (c, d, s1, s2);
2465 e68_op_prefetch (c);
2466 e68_op_set_ea8 (c, 0, 0, 0, d);
2467}
2468
2469/* 5140_08: SUBQ.W #X, Ax */
2470static void op5140_08 (e68000_t *c)
2471{
2472 unsigned r;
2473 uint32_t s1, s2, d;
2474
2475 r = e68_ir_reg0 (c);
2476
2477 s1 = (c->ir[0] >> 9) & 7;
2478 s2 = e68_get_areg32 (c, r);
2479
2480 if (s1 == 0) {
2481 s1 = 8;
2482 }
2483
2484 d = s2 - s1;
2485
2486 e68_set_clk (c, 8);
2487 e68_op_prefetch (c);
2488 e68_set_areg32 (c, r, d);
2489}
2490
2491/* 5140: SUBQ.W #X, <EA> */
2492static void op5140 (e68000_t *c)
2493{
2494 uint16_t s1, s2, d;
2495
2496 if ((c->ir[0] & 0x38) == 0x08) {
2497 op5140_08 (c);
2498 return;
2499 }
2500
2501 s1 = (c->ir[0] >> 9) & 7;
2502 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
2503
2504 if (s1 == 0) {
2505 s1 = 8;
2506 }
2507
2508 d = s2 - s1;
2509
2510 e68_set_clk (c, 8);
2511 e68_cc_set_sub_16 (c, d, s1, s2);
2512 e68_op_prefetch (c);
2513 e68_op_set_ea16 (c, 0, 0, 0, d);
2514}
2515
2516/* 5180_08: SUBQ.L #X, Ax */
2517static void op5180_08 (e68000_t *c)
2518{
2519 unsigned r;
2520 uint32_t s1, s2, d;
2521
2522 r = e68_ir_reg0 (c);
2523
2524 s1 = (c->ir[0] >> 9) & 7;
2525 s2 = e68_get_areg32 (c, r);
2526
2527 if (s1 == 0) {
2528 s1 = 8;
2529 }
2530
2531 d = s2 - s1;
2532
2533 e68_set_clk (c, 12);
2534 e68_op_prefetch (c);
2535 e68_set_areg32 (c, r, d);
2536}
2537
2538/* 5180: SUBQ.L #X, <EA> */
2539static void op5180 (e68000_t *c)
2540{
2541 uint32_t s1, s2, d;
2542
2543 if ((c->ir[0] & 0x38) == 0x08) {
2544 op5180_08 (c);
2545 return;
2546 }
2547
2548 s1 = (c->ir[0] >> 9) & 7;
2549 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
2550
2551 if (s1 == 0) {
2552 s1 = 8;
2553 }
2554
2555 d = s2 - s1;
2556
2557 e68_set_clk (c, 12);
2558 e68_cc_set_sub_32 (c, d, s1, s2);
2559 e68_op_prefetch (c);
2560 e68_op_set_ea32 (c, 0, 0, 0, d);
2561}
2562
2563/* DBcc Dx, dist */
2564void e68_op_dbcc (e68000_t *c, int cond)
2565{
2566 unsigned reg;
2567 uint16_t val;
2568 uint32_t addr, dist;
2569
2570 e68_op_prefetch (c);
2571
2572 addr = e68_get_pc (c);
2573 dist = e68_exts16 (c->ir[1]);
2574
2575 if (cond) {
2576 e68_set_clk (c, 12);
2577 e68_op_prefetch (c);
2578 return;
2579 }
2580
2581 reg = e68_ir_reg0 (c);
2582 val = e68_get_dreg16 (c, reg);
2583 val = (val - 1) & 0xffff;
2584 e68_set_dreg16 (c, reg, val);
2585
2586 if (val == 0xffff) {
2587 e68_set_clk (c, 14);
2588 e68_op_prefetch (c);
2589 return;
2590 }
2591
2592 e68_set_clk (c, 10);
2593 e68_set_ir_pc (c, addr + dist);
2594 e68_op_prefetch (c);
2595 e68_op_prefetch (c);
2596 e68_set_pc (c, e68_get_ir_pc (c) - 4);
2597}
2598
2599/* Scc <EA> */
2600void e68_op_scc (e68000_t *c, int cond)
2601{
2602 uint8_t val;
2603
2604 val = cond ? 0xff : 0x00;
2605
2606 e68_set_clk (c, 4);
2607 e68_op_set_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, val);
2608 e68_op_prefetch (c);
2609}
2610
2611/* 50C0: ST <EA> / DBT Dx, dist */
2612static void op50c0 (e68000_t *c)
2613{
2614 if ((c->ir[0] & 0x38) == 0x08) {
2615 e68_op_dbcc (c, 1);
2616 }
2617 else {
2618 e68_op_scc (c, 1);
2619 }
2620}
2621
2622/* 51C0: SF <EA> / DBF Dx, dist */
2623static void op51c0 (e68000_t *c)
2624{
2625 if ((c->ir[0] & 0x38) == 0x08) {
2626 e68_op_dbcc (c, 0);
2627 }
2628 else {
2629 e68_op_scc (c, 0);
2630 }
2631}
2632
2633/* 52C0: SHI <EA> / DBHI Dx, dist */
2634static void op52c0 (e68000_t *c)
2635{
2636 int cond;
2637
2638 cond = (!e68_get_sr_c (c) && !e68_get_sr_z (c));
2639
2640 if ((c->ir[0] & 0x38) == 0x08) {
2641 e68_op_dbcc (c, cond);
2642 }
2643 else {
2644 e68_op_scc (c, cond);
2645 }
2646}
2647
2648/* 53C0: SLS <EA> / DBLS Dx, dist */
2649static void op53c0 (e68000_t *c)
2650{
2651 int cond;
2652
2653 cond = (e68_get_sr_c (c) || e68_get_sr_z (c));
2654
2655 if ((c->ir[0] & 0x38) == 0x08) {
2656 e68_op_dbcc (c, cond);
2657 }
2658 else {
2659 e68_op_scc (c, cond);
2660 }
2661}
2662
2663/* 54C0: SCC <EA> / DBCC Dx, dist */
2664static void op54c0 (e68000_t *c)
2665{
2666 int cond;
2667
2668 cond = !e68_get_sr_c (c);
2669
2670 if ((c->ir[0] & 0x38) == 0x08) {
2671 e68_op_dbcc (c, cond);
2672 }
2673 else {
2674 e68_op_scc (c, cond);
2675 }
2676}
2677
2678/* 55C0: SCS <EA> / DBCS Dx, dist */
2679static void op55c0 (e68000_t *c)
2680{
2681 int cond;
2682
2683 cond = e68_get_sr_c (c);
2684
2685 if ((c->ir[0] & 0x38) == 0x08) {
2686 e68_op_dbcc (c, cond);
2687 }
2688 else {
2689 e68_op_scc (c, cond);
2690 }
2691}
2692
2693/* 56C0: SNE <EA> / DBNE Dx, dist */
2694static void op56c0 (e68000_t *c)
2695{
2696 int cond;
2697
2698 cond = !e68_get_sr_z (c);
2699
2700 if ((c->ir[0] & 0x38) == 0x08) {
2701 e68_op_dbcc (c, cond);
2702 }
2703 else {
2704 e68_op_scc (c, cond);
2705 }
2706}
2707
2708/* 57C0: SEQ <EA> / DBEQ Dx, dist */
2709static void op57c0 (e68000_t *c)
2710{
2711 int cond;
2712
2713 cond = e68_get_sr_z (c);
2714
2715 if ((c->ir[0] & 0x38) == 0x08) {
2716 e68_op_dbcc (c, cond);
2717 }
2718 else {
2719 e68_op_scc (c, cond);
2720 }
2721}
2722
2723/* 58C0: SVC <EA> / DBVC Dx, dist */
2724static void op58c0 (e68000_t *c)
2725{
2726 int cond;
2727
2728 cond = !e68_get_sr_v (c);
2729
2730 if ((c->ir[0] & 0x38) == 0x08) {
2731 e68_op_dbcc (c, cond);
2732 }
2733 else {
2734 e68_op_scc (c, cond);
2735 }
2736}
2737
2738/* 59C0: SVS <EA> / DBVS Dx, dist */
2739static void op59c0 (e68000_t *c)
2740{
2741 int cond;
2742
2743 cond = e68_get_sr_v (c);
2744
2745 if ((c->ir[0] & 0x38) == 0x08) {
2746 e68_op_dbcc (c, cond);
2747 }
2748 else {
2749 e68_op_scc (c, cond);
2750 }
2751}
2752
2753/* 5AC0: SPL <EA> / DBPL Dx, dist */
2754static void op5ac0 (e68000_t *c)
2755{
2756 int cond;
2757
2758 cond = !e68_get_sr_n (c);
2759
2760 if ((c->ir[0] & 0x38) == 0x08) {
2761 e68_op_dbcc (c, cond);
2762 }
2763 else {
2764 e68_op_scc (c, cond);
2765 }
2766}
2767
2768/* 5BC0: SMI <EA> / DBMI Dx, dist */
2769static void op5bc0 (e68000_t *c)
2770{
2771 int cond;
2772
2773 cond = e68_get_sr_n (c);
2774
2775 if ((c->ir[0] & 0x38) == 0x08) {
2776 e68_op_dbcc (c, cond);
2777 }
2778 else {
2779 e68_op_scc (c, cond);
2780 }
2781}
2782
2783/* 5CC0: SGE <EA> / DBGE Dx, dist */
2784static void op5cc0 (e68000_t *c)
2785{
2786 int cond;
2787
2788 cond = (e68_get_sr_n (c) == e68_get_sr_v (c));
2789
2790 if ((c->ir[0] & 0x38) == 0x08) {
2791 e68_op_dbcc (c, cond);
2792 }
2793 else {
2794 e68_op_scc (c, cond);
2795 }
2796}
2797
2798/* 5DC0: SLT <EA> / DBLT Dx, dist */
2799static void op5dc0 (e68000_t *c)
2800{
2801 int cond;
2802
2803 cond = (e68_get_sr_n (c) != e68_get_sr_v (c));
2804
2805 if ((c->ir[0] & 0x38) == 0x08) {
2806 e68_op_dbcc (c, cond);
2807 }
2808 else {
2809 e68_op_scc (c, cond);
2810 }
2811}
2812
2813/* 5EC0: SGT <EA> / DBGT Dx, dist */
2814static void op5ec0 (e68000_t *c)
2815{
2816 int cond;
2817
2818 cond = (e68_get_sr_n (c) == e68_get_sr_v (c)) && !e68_get_sr_z (c);
2819
2820 if ((c->ir[0] & 0x38) == 0x08) {
2821 e68_op_dbcc (c, cond);
2822 }
2823 else {
2824 e68_op_scc (c, cond);
2825 }
2826}
2827
2828/* 5FC0: SLE <EA> / DBLE Dx, dist */
2829static void op5fc0 (e68000_t *c)
2830{
2831 int cond;
2832
2833 cond = (e68_get_sr_n (c) != e68_get_sr_v (c)) || e68_get_sr_z (c);
2834
2835 if ((c->ir[0] & 0x38) == 0x08) {
2836 e68_op_dbcc (c, cond);
2837 }
2838 else {
2839 e68_op_scc (c, cond);
2840 }
2841}
2842
2843/* conditional jump */
2844static
2845void e68_op_bcc (e68000_t *c, int cond)
2846{
2847 uint32_t addr, dist;
2848
2849 addr = e68_get_pc (c) + 2;
2850 dist = e68_exts8 (c->ir[0]);
2851
2852 if (dist == 0) {
2853 e68_op_prefetch (c);
2854 dist = e68_exts16 (c->ir[1]);
2855 }
2856
2857 if (cond) {
2858 e68_set_clk (c, 10);
2859 e68_set_ir_pc (c, addr + dist);
2860 e68_op_prefetch (c);
2861 }
2862 else {
2863 e68_set_clk (c, ((c->ir[0] & 0xff) == 0) ? 12 : 8);
2864 }
2865
2866 e68_op_prefetch (c);
2867 e68_set_pc (c, e68_get_ir_pc (c) - 4);
2868}
2869
2870/* 6000: BRA dist */
2871static void op6000 (e68000_t *c)
2872{
2873 e68_op_bcc (c, 1);
2874}
2875
2876/* 6100: BSR dist */
2877static void op6100 (e68000_t *c)
2878{
2879 uint32_t addr;
2880
2881 addr = e68_get_pc (c) + ((c->ir[0] & 0xff) ? 2 : 4);
2882
2883 e68_push32 (c, addr);
2884
2885 e68_op_bcc (c, 1);
2886}
2887
2888/* 6200: BHI dist */
2889static void op6200 (e68000_t *c)
2890{
2891 e68_op_bcc (c, !e68_get_sr_c (c) && !e68_get_sr_z (c));
2892}
2893
2894/* 6300: BLS dist */
2895static void op6300 (e68000_t *c)
2896{
2897 e68_op_bcc (c, e68_get_sr_c (c) || e68_get_sr_z (c));
2898}
2899
2900/* 6400: BCC dist */
2901static void op6400 (e68000_t *c)
2902{
2903 e68_op_bcc (c, !e68_get_sr_c (c));
2904}
2905
2906/* 6500: BCS dist */
2907static void op6500 (e68000_t *c)
2908{
2909 e68_op_bcc (c, e68_get_sr_c (c));
2910}
2911
2912/* 6600: BNE dist */
2913static void op6600 (e68000_t *c)
2914{
2915 e68_op_bcc (c, !e68_get_sr_z (c));
2916}
2917
2918/* 6700: BEQ dist */
2919static void op6700 (e68000_t *c)
2920{
2921 e68_op_bcc (c, e68_get_sr_z (c));
2922}
2923
2924/* 6800: BVC dist */
2925static void op6800 (e68000_t *c)
2926{
2927 e68_op_bcc (c, !e68_get_sr_v (c));
2928}
2929
2930/* 6900: BVS dist */
2931static void op6900 (e68000_t *c)
2932{
2933 e68_op_bcc (c, e68_get_sr_v (c));
2934}
2935
2936/* 6A00: BPL dist */
2937static void op6a00 (e68000_t *c)
2938{
2939 e68_op_bcc (c, !e68_get_sr_n (c));
2940}
2941
2942/* 6B00: BMI dist */
2943static void op6b00 (e68000_t *c)
2944{
2945 e68_op_bcc (c, e68_get_sr_n (c));
2946}
2947
2948/* 6C00: BGE dist */
2949static void op6c00 (e68000_t *c)
2950{
2951 e68_op_bcc (c, e68_get_sr_n (c) == e68_get_sr_v (c));
2952}
2953
2954/* 6D00: BLT dist */
2955static void op6d00 (e68000_t *c)
2956{
2957 e68_op_bcc (c, e68_get_sr_n (c) != e68_get_sr_v (c));
2958}
2959
2960/* 6E00: BGT dist */
2961static void op6e00 (e68000_t *c)
2962{
2963 e68_op_bcc (c, (e68_get_sr_n (c) == e68_get_sr_v (c)) && !e68_get_sr_z (c));
2964}
2965
2966/* 6F00: BLE dist */
2967static void op6f00 (e68000_t *c)
2968{
2969 e68_op_bcc (c, (e68_get_sr_n (c) != e68_get_sr_v (c)) || e68_get_sr_z (c));
2970}
2971
2972/* 7000: MOVEQ #XX, Dx */
2973static void op7000 (e68000_t *c)
2974{
2975 uint32_t val;
2976
2977 val = e68_exts8 (c->ir[0]);
2978
2979 e68_set_clk (c, 4);
2980 e68_cc_set_nz_32 (c, E68_SR_NZVC, val);
2981 e68_set_dreg32 (c, e68_ir_reg9 (c), val);
2982 e68_op_prefetch (c);
2983}
2984
2985/* 8000: OR.B <EA>, Dx */
2986static void op8000 (e68000_t *c)
2987{
2988 unsigned r;
2989 uint8_t s1, s2, d;
2990
2991 r = e68_ir_reg9 (c);
2992
2993 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
2994 s2 = e68_get_dreg8 (c, r);
2995
2996 d = s1 | s2;
2997
2998 e68_set_clk (c, 8);
2999 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
3000 e68_op_prefetch (c);
3001 e68_set_dreg8 (c, r, d);
3002}
3003
3004/* 8040: OR.W <EA>, Dx */
3005static void op8040 (e68000_t *c)
3006{
3007 unsigned r;
3008 uint16_t s1, s2, d;
3009
3010 r = e68_ir_reg9 (c);
3011
3012 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3013 s2 = e68_get_dreg16 (c, r);
3014
3015 d = s1 | s2;
3016
3017 e68_set_clk (c, 8);
3018 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
3019 e68_op_prefetch (c);
3020 e68_set_dreg16 (c, r, d);
3021}
3022
3023/* 8080: OR.L <EA>, Dx */
3024static void op8080 (e68000_t *c)
3025{
3026 unsigned r;
3027 uint32_t s1, s2, d;
3028
3029 r = e68_ir_reg9 (c);
3030
3031 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3032 s2 = e68_get_dreg32 (c, r);
3033
3034 d = s1 | s2;
3035
3036 e68_set_clk (c, 10);
3037 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3038 e68_op_prefetch (c);
3039 e68_set_dreg32 (c, r, d);
3040}
3041
3042/* 80C0: DIVU.W <EA>, Dx */
3043static void op80c0 (e68000_t *c)
3044{
3045 unsigned r;
3046 uint32_t s2, d1, d2;
3047 uint16_t s1;
3048
3049 r = e68_ir_reg9 (c);
3050
3051 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3052 s2 = e68_get_dreg32 (c, r);
3053
3054 if (s1 == 0) {
3055 e68_op_prefetch (c);
3056 e68_exception_divzero (c);
3057 return;
3058 }
3059
3060 d1 = s2 / s1;
3061 d2 = s2 % s1;
3062
3063 if (d1 & 0xffff0000) {
3064 e68_set_sr_v (c, 1);
3065 e68_set_sr_c (c, 0);
3066 }
3067 else {
3068 e68_set_dreg32 (c, r, ((d2 & 0xffff) << 16) | (d1 & 0xffff));
3069 e68_cc_set_nz_16 (c, E68_SR_NZVC, d1 & 0xffff);
3070 }
3071
3072 e68_set_clk (c, 144);
3073 e68_op_prefetch (c);
3074}
3075
3076/* 8100_00: SBCD <EA>, <EA> */
3077static void op8100_00 (e68000_t *c)
3078{
3079 uint8_t s1, s2;
3080 uint16_t d;
3081 unsigned ea1, ea2;
3082
3083 ea1 = e68_ir_reg0 (c);
3084 ea2 = e68_ir_reg9 (c);
3085
3086 if (c->ir[0] & 0x08) {
3087 /* -(Ax) */
3088 ea1 |= (4 << 3);
3089 ea2 |= (4 << 3);
3090 }
3091
3092 e68_op_get_ea8 (c, 1, ea1, 0x0011, &s1);
3093 e68_op_get_ea8 (c, 1, ea2, 0x0011, &s2);
3094
3095 d = (uint16_t) s2 - (uint16_t) s1 - e68_get_sr_x (c);
3096
3097 if ((s2 & 0x0f) < (s1 & 0x0f)) {
3098 d -= 0x06;
3099 }
3100
3101 if (d >= 0xa0) {
3102 d -= 0x60;
3103 }
3104
3105 e68_set_clk (c, 10);
3106 e68_set_cc (c, E68_SR_XC, d & 0xff00);
3107
3108 if (d & 0xff) {
3109 c->sr &= ~E68_SR_Z;
3110 }
3111
3112 e68_op_prefetch (c);
3113 e68_op_set_ea8 (c, 0, 0, 0, d);
3114}
3115
3116/* 8100: OR.B Dx, <EA> */
3117static void op8100 (e68000_t *c)
3118{
3119 uint8_t s1, s2, d;
3120
3121 if ((c->ir[0] & 0x30) == 0) {
3122 op8100_00 (c);
3123 return;
3124 }
3125
3126 s1 = e68_get_dreg8 (c, e68_ir_reg9 (c));
3127 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3128
3129 d = s1 | s2;
3130
3131 e68_set_clk (c, 8);
3132 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
3133 e68_op_prefetch (c);
3134 e68_op_set_ea8 (c, 0, 0, 0, d);
3135}
3136
3137/* 8140: OR.W Dx, <EA> */
3138static void op8140 (e68000_t *c)
3139{
3140 uint16_t s1, s2, d;
3141
3142 s1 = e68_get_dreg16 (c, e68_ir_reg9 (c));
3143 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3144
3145 d = s1 | s2;
3146
3147 e68_set_clk (c, 8);
3148 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
3149 e68_op_prefetch (c);
3150 e68_op_set_ea16 (c, 0, 0, 0, d);
3151}
3152
3153/* 8180: OR.L Dx, <EA> */
3154static void op8180 (e68000_t *c)
3155{
3156 uint32_t s1, s2, d;
3157
3158 s1 = e68_get_dreg32 (c, e68_ir_reg9 (c));
3159 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3160
3161 d = s1 | s2;
3162
3163 e68_set_clk (c, 10);
3164 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3165 e68_op_prefetch (c);
3166 e68_op_set_ea32 (c, 0, 0, 0, d);
3167}
3168
3169/* 81C0: DIVS.W <EA>, Dx */
3170static void op81c0 (e68000_t *c)
3171{
3172 unsigned r;
3173 int n1, n2;
3174 uint32_t s2, d1, d2;
3175 uint16_t s1;
3176
3177 r = e68_ir_reg9 (c);
3178
3179 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3180 s2 = e68_get_dreg32 (c, r);
3181
3182 if (s1 == 0) {
3183 e68_op_prefetch (c);
3184 e68_exception_divzero (c);
3185 return;
3186 }
3187
3188 n1 = 0;
3189 n2 = 0;
3190
3191 if (s2 & 0x80000000) {
3192 n2 = 1;
3193 s2 = (~s2 + 1) & 0xffffffff;
3194 }
3195
3196 if (s1 & 0x8000) {
3197 n1 = 1;
3198 s1 = (~s1 + 1) & 0xffff;
3199 }
3200
3201 d1 = s2 / s1;
3202 d2 = s2 % s1;
3203
3204 if (n2) {
3205 d2 = (~d2 + 1) & 0xffff;
3206 }
3207
3208 if (n1 != n2) {
3209 d1 = (~d1 + 1) & 0xffffffff;
3210 }
3211
3212 e68_set_clk (c, 162);
3213
3214 switch (d1 & 0xffff8000) {
3215 case 0x00000000:
3216 case 0xffff8000:
3217 e68_set_dreg32 (c, r, ((d2 & 0xffff) << 16) | (d1 & 0xffff));
3218 e68_cc_set_nz_16 (c, E68_SR_NZVC, d1 & 0xffff);
3219 break;
3220
3221 default:
3222 e68_set_sr_v (c, 1);
3223 e68_set_sr_c (c, 0);
3224 break;
3225 }
3226
3227 e68_op_prefetch (c);
3228}
3229
3230/* 9000: SUB.B <EA>, Dx */
3231static void op9000 (e68000_t *c)
3232{
3233 unsigned r;
3234 uint8_t s1, s2, d;
3235
3236 r = e68_ir_reg9 (c);
3237
3238 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3239 s2 = e68_get_dreg8 (c, r);
3240
3241 d = s2 - s1;
3242
3243 e68_set_clk (c, 8);
3244 e68_cc_set_sub_8 (c, d, s1, s2);
3245 e68_op_prefetch (c);
3246 e68_set_dreg8 (c, r, d);
3247}
3248
3249/* 9040: SUB.W <EA>, Dx */
3250static void op9040 (e68000_t *c)
3251{
3252 unsigned r;
3253 uint16_t s1, s2, d;
3254
3255 r = e68_ir_reg9 (c);
3256
3257 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3258 s2 = e68_get_dreg16 (c, r);
3259
3260 d = s2 - s1;
3261
3262 e68_set_clk (c, 8);
3263 e68_cc_set_sub_16 (c, d, s1, s2);
3264 e68_op_prefetch (c);
3265 e68_set_dreg16 (c, r, d);
3266}
3267
3268/* 9080: SUB.L <EA>, Dx */
3269static void op9080 (e68000_t *c)
3270{
3271 unsigned r;
3272 uint32_t s1, s2, d;
3273
3274 r = e68_ir_reg9 (c);
3275
3276 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3277 s2 = e68_get_dreg32 (c, r);
3278
3279 d = s2 - s1;
3280
3281 e68_set_clk (c, 10);
3282 e68_cc_set_sub_32 (c, d, s1, s2);
3283 e68_op_prefetch (c);
3284 e68_set_dreg32 (c, r, d);
3285}
3286
3287/* 90C0: SUBA.W <EA>, Ax */
3288static void op90c0 (e68000_t *c)
3289{
3290 unsigned r;
3291 uint32_t s1, s2, d;
3292 uint16_t t;
3293
3294 r = e68_ir_reg9 (c);
3295
3296 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &t);
3297 s1 = e68_exts16 (t);
3298 s2 = e68_get_areg32 (c, r);
3299
3300 d = s2 - s1;
3301
3302 e68_set_clk (c, 8);
3303 e68_op_prefetch (c);
3304 e68_set_areg32 (c, r, d);
3305}
3306
3307/* 9100_00: SUBX.B <EA>, <EA> */
3308static void op9100_00 (e68000_t *c)
3309{
3310 uint8_t s1, s2, d;
3311 unsigned ea1, ea2;
3312
3313 ea1 = e68_ir_reg0 (c);
3314 ea2 = e68_ir_reg9 (c);
3315
3316 if (c->ir[0] & 0x0008) {
3317 /* pre-decrement */
3318 ea1 |= (4 << 3);
3319 ea2 |= (4 << 3);
3320 }
3321
3322 e68_op_get_ea8 (c, 1, ea1, 0x0011, &s1);
3323 e68_op_get_ea8 (c, 1, ea2, 0x0011, &s2);
3324
3325 d = s2 - s1 - e68_get_sr_x (c);
3326
3327 e68_set_clk (c, 8);
3328 e68_cc_set_subx_8 (c, d, s1, s2);
3329 e68_op_prefetch (c);
3330 e68_op_set_ea8 (c, 0, 0, 0, d);
3331}
3332
3333/* 9100: SUB.B Dx, <EA> */
3334static void op9100 (e68000_t *c)
3335{
3336 uint8_t s1, s2, d;
3337
3338 if ((c->ir[0] & 0x30) == 0x00) {
3339 op9100_00 (c);
3340 return;
3341 }
3342
3343 s1 = e68_get_dreg8 (c, e68_ir_reg9 (c));
3344 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3345
3346 d = s2 - s1;
3347
3348 e68_set_clk (c, 8);
3349 e68_cc_set_sub_8 (c, d, s1, s2);
3350 e68_op_prefetch (c);
3351 e68_op_set_ea8 (c, 0, 0, 0, d);
3352}
3353
3354/* 9140_00: SUBX.W <EA>, <EA> */
3355static void op9140_00 (e68000_t *c)
3356{
3357 uint16_t s1, s2, d;
3358 unsigned ea1, ea2;
3359
3360 ea1 = e68_ir_reg0 (c);
3361 ea2 = e68_ir_reg9 (c);
3362
3363 if (c->ir[0] & 0x0008) {
3364 /* pre-decrement */
3365 ea1 |= (4 << 3);
3366 ea2 |= (4 << 3);
3367 }
3368
3369 e68_op_get_ea16 (c, 1, ea1, 0x0011, &s1);
3370 e68_op_get_ea16 (c, 1, ea2, 0x0011, &s2);
3371
3372 d = s2 - s1 - e68_get_sr_x (c);
3373
3374 e68_set_clk (c, 8);
3375 e68_cc_set_subx_16 (c, d, s1, s2);
3376 e68_op_prefetch (c);
3377 e68_op_set_ea16 (c, 0, 0, 0, d);
3378}
3379
3380/* 9140: SUB.W Dx, <EA> */
3381static void op9140 (e68000_t *c)
3382{
3383 uint16_t s1, s2, d;
3384
3385 if ((c->ir[0] & 0x30) == 0x00) {
3386 op9140_00 (c);
3387 return;
3388 }
3389
3390 s1 = e68_get_dreg16 (c, e68_ir_reg9 (c));
3391 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3392
3393 d = s2 - s1;
3394
3395 e68_set_clk (c, 8);
3396 e68_cc_set_sub_16 (c, d, s1, s2);
3397 e68_op_prefetch (c);
3398 e68_op_set_ea16 (c, 0, 0, 0, d);
3399}
3400
3401/* 9180_00: SUBX.L <EA>, <EA> */
3402static void op9180_00 (e68000_t *c)
3403{
3404 uint32_t s1, s2, d;
3405 unsigned ea1, ea2;
3406
3407 ea1 = e68_ir_reg0 (c);
3408 ea2 = e68_ir_reg9 (c);
3409
3410 if (c->ir[0] & 0x0008) {
3411 /* pre-decrement */
3412 ea1 |= (4 << 3);
3413 ea2 |= (4 << 3);
3414 }
3415
3416 e68_op_get_ea32 (c, 1, ea1, 0x0011, &s1);
3417 e68_op_get_ea32 (c, 1, ea2, 0x0011, &s2);
3418
3419 d = s2 - s1 - e68_get_sr_x (c);
3420
3421 e68_set_clk (c, 12);
3422 e68_cc_set_subx_32 (c, d, s1, s2);
3423 e68_op_prefetch (c);
3424 e68_op_set_ea32 (c, 0, 0, 0, d);
3425}
3426
3427/* 9180: SUB.L Dx, <EA> */
3428static void op9180 (e68000_t *c)
3429{
3430 uint32_t s1, s2, d;
3431
3432 if ((c->ir[0] & 0x30) == 0x00) {
3433 op9180_00 (c);
3434 return;
3435 }
3436
3437 s1 = e68_get_dreg32 (c, e68_ir_reg9 (c));
3438 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3439
3440 d = s2 - s1;
3441
3442 e68_set_clk (c, 12);
3443 e68_cc_set_sub_32 (c, d, s1, s2);
3444 e68_op_prefetch (c);
3445 e68_op_set_ea32 (c, 0, 0, 0, d);
3446}
3447
3448/* 91C0: SUBA.L <EA>, Ax */
3449static void op91c0 (e68000_t *c)
3450{
3451 unsigned r;
3452 uint32_t s1, s2, d;
3453
3454 r = e68_ir_reg9 (c);
3455
3456 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3457 s2 = e68_get_areg32 (c, r);
3458
3459 d = s2 - s1;
3460
3461 e68_set_clk (c, 10);
3462 e68_op_prefetch (c);
3463 e68_set_areg32 (c, r, d);
3464}
3465
3466/* A000: AXXX */
3467static void opa000 (e68000_t *c)
3468{
3469 c->last_trap_a = c->ir[0];
3470
3471 e68_exception_axxx (c);
3472}
3473
3474/* B000: CMP.B <EA>, Dx */
3475static void opb000 (e68000_t *c)
3476{
3477 uint8_t s1, s2;
3478
3479 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3480 s2 = e68_get_dreg8 (c, e68_ir_reg9 (c));
3481
3482 e68_set_clk (c, 4);
3483 e68_cc_set_cmp_8 (c, s2 - s1, s1, s2);
3484 e68_op_prefetch (c);
3485}
3486
3487/* B040: CMP.W <EA>, Dx */
3488static void opb040 (e68000_t *c)
3489{
3490 uint16_t s1, s2;
3491
3492 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3493 s2 = e68_get_dreg16 (c, e68_ir_reg9 (c));
3494
3495 e68_set_clk (c, 4);
3496 e68_cc_set_cmp_16 (c, s2 - s1, s1, s2);
3497 e68_op_prefetch (c);
3498}
3499
3500/* B080: CMP.L <EA>, Dx */
3501static void opb080 (e68000_t *c)
3502{
3503 uint32_t s1, s2;
3504
3505 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3506 s2 = e68_get_dreg32 (c, e68_ir_reg9 (c));
3507
3508 e68_set_clk (c, 6);
3509 e68_cc_set_cmp_32 (c, s2 - s1, s1, s2);
3510 e68_op_prefetch (c);
3511}
3512
3513/* B0C0: CMPA.W <EA>, Ax */
3514static void opb0c0 (e68000_t *c)
3515{
3516 uint32_t s1, s2;
3517 uint16_t t;
3518
3519 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &t);
3520 s1 = e68_exts16 (t);
3521 s2 = e68_get_areg32 (c, e68_ir_reg9 (c));
3522
3523 e68_set_clk (c, 8);
3524 e68_cc_set_cmp_32 (c, s2 - s1, s1, s2);
3525 e68_op_prefetch (c);
3526}
3527
3528/* B100_08: CMPM.B (Ay)+, (Ax)+ */
3529static void opb100_08 (e68000_t *c)
3530{
3531 uint8_t s1, s2;
3532
3533 e68_op_get_ea8 (c, 1, e68_ir_reg0 (c) | (3 << 3), 0x0008, &s1);
3534 e68_op_get_ea8 (c, 1, e68_ir_reg9 (c) | (3 << 3), 0x0008, &s2);
3535
3536 e68_set_clk (c, 16);
3537 e68_cc_set_cmp_8 (c, s2 - s1, s1, s2);
3538 e68_op_prefetch (c);
3539}
3540
3541/* B100: EOR.B Dx, <EA> */
3542static void opb100 (e68000_t *c)
3543{
3544 uint8_t s1, s2, d;
3545
3546 if ((c->ir[0] & 0x38) == 0x08) {
3547 opb100_08 (c);
3548 return;
3549 }
3550
3551 s1 = e68_get_dreg8 (c, e68_ir_reg9 (c));
3552 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
3553
3554 d = s1 ^ s2;
3555
3556 e68_set_clk (c, 8);
3557 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
3558 e68_op_prefetch (c);
3559 e68_op_set_ea8 (c, 0, 0, 0, d);
3560}
3561
3562/* B140_08: CMPM.W (Ay)+, (Ax)+ */
3563static void opb140_08 (e68000_t *c)
3564{
3565 uint16_t s1, s2;
3566
3567 e68_op_get_ea16 (c, 1, e68_ir_reg0 (c) | (3 << 3), 0x0008, &s1);
3568 e68_op_get_ea16 (c, 1, e68_ir_reg9 (c) | (3 << 3), 0x0008, &s2);
3569
3570 e68_set_clk (c, 12);
3571 e68_cc_set_cmp_16 (c, s2 - s1, s1, s2);
3572 e68_op_prefetch (c);
3573}
3574
3575/* B140: EOR.W Dx, <EA> */
3576static void opb140 (e68000_t *c)
3577{
3578 uint16_t s1, s2, d;
3579
3580 if ((c->ir[0] & 0x38) == 0x08) {
3581 opb140_08 (c);
3582 return;
3583 }
3584
3585 s1 = e68_get_dreg16 (c, e68_ir_reg9 (c));
3586 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
3587
3588 d = s1 ^ s2;
3589
3590 e68_set_clk (c, 8);
3591 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
3592 e68_op_prefetch (c);
3593 e68_op_set_ea16 (c, 0, 0, 0, d);
3594}
3595
3596/* B180_08: CMPM.L (Ay)+, (Ax)+ */
3597static void opb180_08 (e68000_t *c)
3598{
3599 uint32_t s1, s2;
3600
3601 e68_op_get_ea32 (c, 1, e68_ir_reg0 (c) | (3 << 3), 0x0008, &s1);
3602 e68_op_get_ea32 (c, 1, e68_ir_reg9 (c) | (3 << 3), 0x0008, &s2);
3603
3604 e68_set_clk (c, 20);
3605 e68_cc_set_cmp_32 (c, s2 - s1, s1, s2);
3606 e68_op_prefetch (c);
3607}
3608
3609/* B180: EOR.L Dx, <EA> */
3610static void opb180 (e68000_t *c)
3611{
3612 uint32_t s1, s2, d;
3613
3614 if ((c->ir[0] & 0x38) == 0x08) {
3615 opb180_08 (c);
3616 return;
3617 }
3618
3619 s1 = e68_get_dreg32 (c, e68_ir_reg9 (c));
3620 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fd, &s2);
3621
3622 d = s1 ^ s2;
3623
3624 e68_set_clk (c, 12);
3625 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3626 e68_op_prefetch (c);
3627 e68_op_set_ea32 (c, 0, 0, 0, d);
3628}
3629
3630/* B1C0: CMPA.L <EA>, Ax */
3631static void opb1c0 (e68000_t *c)
3632{
3633 uint32_t s1, s2;
3634
3635 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3636 s2 = e68_get_areg32 (c, e68_ir_reg9 (c));
3637
3638 e68_set_clk (c, 8);
3639 e68_cc_set_cmp_32 (c, s2 - s1, s1, s2);
3640 e68_op_prefetch (c);
3641}
3642
3643/* C000: AND.B <EA>, Dx */
3644static void opc000 (e68000_t *c)
3645{
3646 unsigned r;
3647 uint8_t s1, s2, d;
3648
3649 r = e68_ir_reg9 (c);
3650
3651 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3652 s2 = e68_get_dreg8 (c, r);
3653
3654 d = s1 & s2;
3655
3656 e68_set_clk (c, 4);
3657 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
3658 e68_op_prefetch (c);
3659 e68_set_dreg8 (c, r, d);
3660}
3661
3662/* C040: AND.W <EA>, Dx */
3663static void opc040 (e68000_t *c)
3664{
3665 unsigned r;
3666 uint16_t s1, s2, d;
3667
3668 r = e68_ir_reg9 (c);
3669
3670 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3671 s2 = e68_get_dreg16 (c, r);
3672
3673 d = s1 & s2;
3674
3675 e68_set_clk (c, 4);
3676 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
3677 e68_op_prefetch (c);
3678 e68_set_dreg16 (c, r, d);
3679}
3680
3681/* C080: AND.L <EA>, Dx */
3682static void opc080 (e68000_t *c)
3683{
3684 unsigned r;
3685 uint32_t s1, s2, d;
3686
3687 r = e68_ir_reg9 (c);
3688
3689 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3690 s2 = e68_get_dreg32 (c, r);
3691
3692 d = s1 & s2;
3693
3694 e68_set_clk (c, 6);
3695 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3696 e68_op_prefetch (c);
3697 e68_set_dreg32 (c, r, d);
3698}
3699
3700/* C0C0: MULU.W <EA>, Dx */
3701static void opc0c0 (e68000_t *c)
3702{
3703 unsigned r;
3704 uint32_t d;
3705 uint16_t s1, s2;
3706
3707 r = e68_ir_reg9 (c);
3708
3709 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3710 s2 = e68_get_dreg16 (c, r);
3711
3712 d = (uint32_t) s1 * (uint32_t) s2;
3713
3714 e68_set_clk (c, 74);
3715 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3716 e68_op_prefetch (c);
3717 e68_set_dreg32 (c, r, d);
3718}
3719
3720/* C100_00: ABCD <EA>, <EA> */
3721static void opc100_00 (e68000_t *c)
3722{
3723 uint8_t s1, s2;
3724 uint16_t d;
3725 unsigned ea1, ea2;
3726
3727 ea1 = e68_ir_reg0 (c);
3728 ea2 = e68_ir_reg9 (c);
3729
3730 if (c->ir[0] & 0x08) {
3731 /* -(Ax) */
3732 ea1 |= (4 << 3);
3733 ea2 |= (4 << 3);
3734 }
3735
3736 e68_op_get_ea8 (c, 1, ea1, 0x0011, &s1);
3737 e68_op_get_ea8 (c, 1, ea2, 0x0011, &s2);
3738
3739 d = (uint16_t) s1 + (uint16_t) s2 + e68_get_sr_x (c);
3740
3741 /* incorrect */
3742 if (((s1 & 0x0f) + (s2 & 0x0f)) > 9) {
3743 d += 0x06;
3744 }
3745
3746 if (d >= 0xa0) {
3747 d += 0x60;
3748 c->sr |= (E68_SR_X | E68_SR_C);
3749 }
3750 else {
3751 c->sr &= (~E68_SR_X & ~E68_SR_C);
3752 }
3753
3754
3755 if (d & 0xff) {
3756 c->sr &= ~E68_SR_Z;
3757 }
3758
3759 e68_set_clk (c, 6);
3760 e68_op_prefetch (c);
3761 e68_op_set_ea8 (c, 0, 0, 0, d);
3762}
3763
3764/* C100: AND.B Dx, <EA> */
3765static void opc100 (e68000_t *c)
3766{
3767 uint8_t s1, s2, d;
3768
3769 if ((c->ir[0] & 0x30) == 0x00) {
3770 opc100_00 (c);
3771 return;
3772 }
3773
3774 s1 = e68_get_dreg8 (c, e68_ir_reg9 (c));
3775 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3776
3777 d = s1 & s2;
3778
3779 e68_set_clk (c, 4);
3780 e68_cc_set_nz_8 (c, E68_SR_NZVC, d);
3781 e68_op_prefetch (c);
3782 e68_op_set_ea8 (c, 0, 0, 0, d);
3783}
3784
3785/* C140_00: EXG Dx, Dx */
3786static void opc140_00 (e68000_t *c)
3787{
3788 unsigned r1, r2;
3789 uint32_t s1, s2;
3790
3791 r1 = e68_ir_reg9 (c);
3792 r2 = e68_ir_reg0 (c);
3793
3794 s1 = e68_get_dreg32 (c, r1);
3795 s2 = e68_get_dreg32 (c, r2);
3796
3797 e68_set_dreg32 (c, r1, s2);
3798 e68_set_dreg32 (c, r2, s1);
3799
3800 e68_set_clk (c, 10);
3801 e68_op_prefetch (c);
3802}
3803
3804/* C140_08: EXG Ax, Ax */
3805static void opc140_08 (e68000_t *c)
3806{
3807 unsigned r1, r2;
3808 uint32_t s1, s2;
3809
3810 r1 = e68_ir_reg9 (c);
3811 r2 = e68_ir_reg0 (c);
3812
3813 s1 = e68_get_areg32 (c, r1);
3814 s2 = e68_get_areg32 (c, r2);
3815
3816 e68_set_areg32 (c, r1, s2);
3817 e68_set_areg32 (c, r2, s1);
3818
3819 e68_set_clk (c, 10);
3820 e68_op_prefetch (c);
3821}
3822
3823/* C140: AND.W Dx, <EA> */
3824static void opc140 (e68000_t *c)
3825{
3826 uint16_t s1, s2, d;
3827
3828 switch ((c->ir[0] >> 3) & 7) {
3829 case 0x00:
3830 opc140_00 (c);
3831 return;
3832
3833 case 0x01:
3834 opc140_08 (c);
3835 return;
3836 }
3837
3838 s1 = e68_get_dreg16 (c, e68_ir_reg9 (c));
3839 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3840
3841 d = s1 & s2;
3842
3843 e68_set_clk (c, 4);
3844 e68_cc_set_nz_16 (c, E68_SR_NZVC, d);
3845 e68_op_prefetch (c);
3846 e68_op_set_ea16 (c, 0, 0, 0, d);
3847}
3848
3849/* C180_08: EXG Dx, Ay */
3850static void opc180_08 (e68000_t *c)
3851{
3852 unsigned r1, r2;
3853 uint32_t s1, s2;
3854
3855 r1 = e68_ir_reg9 (c);
3856 r2 = e68_ir_reg0 (c);
3857
3858 s1 = e68_get_dreg32 (c, r1);
3859 s2 = e68_get_areg32 (c, r2);
3860
3861 e68_set_dreg32 (c, r1, s2);
3862 e68_set_areg32 (c, r2, s1);
3863
3864 e68_set_clk (c, 10);
3865 e68_op_prefetch (c);
3866}
3867
3868/* C180: AND.L Dx, <EA> */
3869static void opc180 (e68000_t *c)
3870{
3871 uint32_t s1, s2, d;
3872
3873 if ((c->ir[0] & 0x38) == 0x08) {
3874 opc180_08 (c);
3875 return;
3876 }
3877
3878 s1 = e68_get_dreg32 (c, e68_ir_reg9 (c));
3879 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
3880
3881 d = s1 & s2;
3882
3883 e68_set_clk (c, 6);
3884 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3885 e68_op_prefetch (c);
3886 e68_op_set_ea32 (c, 0, 0, 0, d);
3887}
3888
3889/* C1C0: MULS.W <EA>, Dx */
3890static void opc1c0 (e68000_t *c)
3891{
3892 unsigned r;
3893 int n1, n2;
3894 uint32_t d;
3895 uint16_t s1, s2;
3896
3897 r = e68_ir_reg9 (c);
3898
3899 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3900 s2 = e68_get_dreg16 (c, r);
3901
3902 n1 = 0;
3903 n2 = 0;
3904
3905 if (s1 & 0x8000) {
3906 n1 = 1;
3907 s1 = (~s1 + 1) & 0xffff;
3908 }
3909
3910 if (s2 & 0x8000) {
3911 n2 = 1;
3912 s2 = (~s2 + 1) & 0xffff;
3913 }
3914
3915 d = (uint32_t) s1 * (uint32_t) s2;
3916
3917 if (n1 != n2) {
3918 d = (~d + 1) & 0xffffffff;
3919 }
3920
3921 e68_set_clk (c, 74);
3922 e68_cc_set_nz_32 (c, E68_SR_NZVC, d);
3923 e68_op_prefetch (c);
3924 e68_set_dreg32 (c, r, d);
3925}
3926
3927/* D000: ADD.B <EA>, Dx */
3928static void opd000 (e68000_t *c)
3929{
3930 unsigned r;
3931 uint8_t s1, s2, d;
3932
3933 r = e68_ir_reg9 (c);
3934
3935 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x0ffd, &s1);
3936 s2 = e68_get_dreg8 (c, r);
3937
3938 d = s1 + s2;
3939
3940 e68_set_clk (c, 4);
3941 e68_cc_set_add_8 (c, d, s1, s2);
3942 e68_op_prefetch (c);
3943 e68_set_dreg8 (c, r, d);
3944}
3945
3946/* D040: ADD.W <EA>, Dx */
3947static void opd040 (e68000_t *c)
3948{
3949 unsigned r;
3950 uint16_t s1, s2, d;
3951
3952 r = e68_ir_reg9 (c);
3953
3954 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3955 s2 = e68_get_dreg16 (c, r);
3956
3957 d = s1 + s2;
3958
3959 e68_set_clk (c, 4);
3960 e68_cc_set_add_16 (c, d, s1, s2);
3961 e68_op_prefetch (c);
3962 e68_set_dreg16 (c, r, d);
3963}
3964
3965/* D080: ADD.L <EA>, Dx */
3966static void opd080 (e68000_t *c)
3967{
3968 unsigned r;
3969 uint32_t s1, s2, d;
3970
3971 r = e68_ir_reg9 (c);
3972
3973 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
3974 s2 = e68_get_dreg32 (c, r);
3975
3976 d = s1 + s2;
3977
3978 e68_set_clk (c, 6);
3979 e68_cc_set_add_32 (c, d, s1, s2);
3980 e68_op_prefetch (c);
3981 e68_set_dreg32 (c, r, d);
3982}
3983
3984/* D0C0: ADDA.W <EA>, Ax */
3985static void opd0c0 (e68000_t *c)
3986{
3987 unsigned r;
3988 uint32_t s1, s2, d;
3989 uint16_t t;
3990
3991 r = e68_ir_reg9 (c);
3992
3993 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x0fff, &t);
3994 s1 = e68_exts16 (t);
3995 s2 = e68_get_areg32 (c, r);
3996
3997 d = s1 + s2;
3998
3999 e68_set_clk (c, 8);
4000 e68_op_prefetch (c);
4001 e68_set_areg32 (c, r, d);
4002}
4003
4004/* D100_00: ADDX.B <EA>, <EA> */
4005static void opd100_00 (e68000_t *c)
4006{
4007 uint8_t s1, s2, d;
4008 unsigned ea1, ea2;
4009
4010 ea1 = e68_ir_reg0 (c);
4011 ea2 = e68_ir_reg9 (c);
4012
4013 if (c->ir[0] & 0x0008) {
4014 /* pre-decrement */
4015 ea1 |= 0x20;
4016 ea2 |= 0x20;
4017 }
4018
4019 e68_op_get_ea8 (c, 1, ea1, 0x0011, &s1);
4020 e68_op_get_ea8 (c, 1, ea2, 0x0011, &s2);
4021
4022 d = s1 + s2 + e68_get_sr_x (c);
4023
4024 e68_set_clk (c, 8);
4025 e68_cc_set_addx_8 (c, d, s1, s2);
4026 e68_op_prefetch (c);
4027 e68_op_set_ea8 (c, 0, 0, 0, d);
4028}
4029
4030/* D100: ADD.B Dx, <EA> */
4031static void opd100 (e68000_t *c)
4032{
4033 uint8_t s1, s2, d;
4034
4035 if ((c->ir[0] & 0x30) == 0) {
4036 opd100_00 (c);
4037 return;
4038 }
4039
4040 s1 = e68_get_dreg8 (c, e68_ir_reg9 (c));
4041 e68_op_get_ea8 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
4042
4043 d = s1 + s2;
4044
4045 e68_set_clk (c, 8);
4046 e68_cc_set_add_8 (c, d, s1, s2);
4047 e68_op_prefetch (c);
4048 e68_op_set_ea8 (c, 0, 0, 0, d);
4049}
4050
4051/* D140_00: ADDX.W <EA>, <EA> */
4052static void opd140_00 (e68000_t *c)
4053{
4054 uint16_t s1, s2, d;
4055 unsigned ea1, ea2;
4056
4057 ea1 = e68_ir_reg0 (c);
4058 ea2 = e68_ir_reg9 (c);
4059
4060 if (c->ir[0] & 0x0008) {
4061 /* pre-decrement */
4062 ea1 |= 0x20;
4063 ea2 |= 0x20;
4064 }
4065
4066 e68_op_get_ea16 (c, 1, ea1, 0x0011, &s1);
4067 e68_op_get_ea16 (c, 1, ea2, 0x0011, &s2);
4068
4069 d = s1 + s2 + e68_get_sr_x (c);
4070
4071 e68_set_clk (c, 8);
4072 e68_cc_set_addx_16 (c, d, s1, s2);
4073 e68_op_prefetch (c);
4074 e68_op_set_ea16 (c, 0, 0, 0, d);
4075}
4076
4077/* D140: ADD.W Dx, <EA> */
4078static void opd140 (e68000_t *c)
4079{
4080 uint16_t s1, s2, d;
4081
4082 if ((c->ir[0] & 0x30) == 0) {
4083 opd140_00 (c);
4084 return;
4085 }
4086
4087 s1 = e68_get_dreg16 (c, e68_ir_reg9 (c));
4088 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
4089
4090 d = s1 + s2;
4091
4092 e68_set_clk (c, 8);
4093 e68_cc_set_add_16 (c, d, s1, s2);
4094 e68_op_prefetch (c);
4095 e68_op_set_ea16 (c, 0, 0, 0, d);
4096}
4097
4098/* D180_00: ADDX.L <EA>, <EA> */
4099static void opd180_00 (e68000_t *c)
4100{
4101 uint32_t s1, s2, d;
4102 unsigned ea1, ea2;
4103
4104 ea1 = e68_ir_reg0 (c);
4105 ea2 = e68_ir_reg9 (c);
4106
4107 if (c->ir[0] & 0x0008) {
4108 /* pre-decrement */
4109 ea1 |= 0x20;
4110 ea2 |= 0x20;
4111 }
4112
4113 e68_op_get_ea32 (c, 1, ea1, 0x0011, &s1);
4114 e68_op_get_ea32 (c, 1, ea2, 0x0011, &s2);
4115
4116 d = s1 + s2 + e68_get_sr_x (c);
4117
4118 e68_set_clk (c, 12);
4119 e68_cc_set_addx_32 (c, d, s1, s2);
4120 e68_op_prefetch (c);
4121 e68_op_set_ea32 (c, 0, 0, 0, d);
4122}
4123
4124/* D180: ADD.L Dx, <EA> */
4125static void opd180 (e68000_t *c)
4126{
4127 uint32_t s1, s2, d;
4128
4129 if ((c->ir[0] & 0x30) == 0) {
4130 opd180_00 (c);
4131 return;
4132 }
4133
4134 s1 = e68_get_dreg32 (c, e68_ir_reg9 (c));
4135 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x01fc, &s2);
4136
4137 d = s1 + s2;
4138
4139 e68_set_clk (c, 12);
4140 e68_cc_set_add_32 (c, d, s1, s2);
4141 e68_op_prefetch (c);
4142 e68_op_set_ea32 (c, 0, 0, 0, d);
4143}
4144
4145/* D1C0: ADDA.L <EA>, Ax */
4146static void opd1c0 (e68000_t *c)
4147{
4148 unsigned r;
4149 uint32_t s1, s2, d;
4150
4151 r = e68_ir_reg9 (c);
4152
4153 e68_op_get_ea32 (c, 1, e68_ir_ea1 (c), 0x0fff, &s1);
4154 s2 = e68_get_areg32 (c, r);
4155
4156 d = s1 + s2;
4157
4158 e68_set_clk (c, 6);
4159 e68_op_prefetch (c);
4160 e68_set_areg32 (c, r, d);
4161}
4162
4163static inline
4164unsigned e68_get_shift_count (e68000_t *c)
4165{
4166 unsigned n;
4167
4168 n = e68_ir_reg9 (c);
4169
4170 if (c->ir[0] & 0x20) {
4171 return (e68_get_dreg8 (c, n) & 0x3f);
4172 }
4173
4174 if (n == 0) {
4175 n = 8;
4176 }
4177
4178 return (n);
4179}
4180
4181/* E000_00: ASR.B <cnt>, Dx */
4182static void ope000_00 (e68000_t *c)
4183{
4184 uint8_t s, d;
4185 unsigned r, n;
4186
4187 r = e68_ir_reg0 (c);
4188
4189 n = e68_get_shift_count (c);
4190 s = e68_get_dreg8 (c, r);
4191
4192 if (n == 0) {
4193 d = s;
4194 e68_set_sr_c (c, 0);
4195 }
4196 else if (n < 8) {
4197 if (s & 0x80) {
4198 d = (s | 0xff00) >> n;
4199 }
4200 else {
4201 d = s >> n;
4202 }
4203 e68_set_sr_xc (c, s & (1 << (n - 1)));
4204 }
4205 else {
4206 if (s & 0x80) {
4207 d = 0xff;
4208 e68_set_sr_xc (c, 1);
4209 }
4210 else {
4211 d = 0x00;
4212 e68_set_sr_xc (c, 0);
4213 }
4214 }
4215
4216 e68_set_clk (c, 6 + 2 * n);
4217 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4218 e68_op_prefetch (c);
4219 e68_set_dreg8 (c, r, d);
4220}
4221
4222/* E000_01: LSR.B <cnt>, Dx */
4223static void ope000_01 (e68000_t *c)
4224{
4225 uint8_t s, d;
4226 unsigned r, n;
4227
4228 r = e68_ir_reg0 (c);
4229
4230 s = e68_get_dreg8 (c, r);
4231 n = e68_get_shift_count (c);
4232
4233 if (n == 0) {
4234 d = s;
4235 e68_set_sr_c (c, 0);
4236 }
4237 else if (n < 8) {
4238 d = s >> n;
4239 e68_set_sr_xc (c, s & (1 << (n - 1)));
4240 }
4241 else {
4242 d = 0;
4243 e68_set_sr_xc (c, (n == 8) && (s & 0x80));
4244 }
4245
4246 e68_set_clk (c, 6 + 2 * n);
4247 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4248 e68_op_prefetch (c);
4249 e68_set_dreg8 (c, r, d);
4250}
4251
4252/* E000_02: ROXR.B <cnt>, Dx */
4253static void ope000_02 (e68000_t *c)
4254{
4255 uint16_t v, x, t;
4256 unsigned r, i, n;
4257
4258 r = e68_ir_reg0 (c);
4259
4260 v = e68_get_dreg8 (c, r);
4261 x = e68_get_sr_x (c);
4262 n = e68_get_shift_count (c);
4263
4264 for (i = 0; i < n; i++) {
4265 t = v & 1;
4266 v = (v >> 1) | (x << 7);
4267 x = t;
4268 }
4269
4270 e68_set_clk (c, 6 + 2 * n);
4271 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, v & 0xff);
4272 e68_set_sr_xc (c, x);
4273 e68_op_prefetch (c);
4274 e68_set_dreg8 (c, r, v & 0xff);
4275}
4276
4277/* E000_03: ROR.B <cnt>, Dx */
4278static void ope000_03 (e68000_t *c)
4279{
4280 uint8_t s, d;
4281 unsigned r, n, k;
4282
4283 r = e68_ir_reg0 (c);
4284
4285 s = e68_get_dreg8 (c, r);
4286 n = e68_get_shift_count (c);
4287
4288 k = n & 7;
4289
4290 if (k > 0) {
4291 d = ((s >> k) | (s << (8 - k))) & 0xff;
4292 e68_set_sr_c (c, d & 0x80);
4293 }
4294 else {
4295 d = s;
4296 e68_set_sr_c (c, (n != 0) && (d & 0x80));
4297 }
4298
4299 e68_set_clk (c, 6 + 2 * n);
4300 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4301 e68_op_prefetch (c);
4302 e68_set_dreg8 (c, r, d);
4303}
4304
4305/* E000: misc */
4306static void ope000 (e68000_t *c)
4307{
4308 switch ((c->ir[0] >> 3) & 3) {
4309 case 0x00:
4310 ope000_00 (c);
4311 return;
4312
4313 case 0x01:
4314 ope000_01 (c);
4315 return;
4316
4317 case 0x02:
4318 ope000_02 (c);
4319 return;
4320
4321 case 0x03:
4322 ope000_03 (c);
4323 return;
4324 }
4325
4326 e68_op_undefined (c);
4327}
4328
4329/* E040_00: ASR.W <cnt>, Dx */
4330static void ope040_00 (e68000_t *c)
4331{
4332 uint16_t s, d;
4333 unsigned r, n;
4334
4335 r = e68_ir_reg0 (c);
4336
4337 s = e68_get_dreg16 (c, r);
4338 n = e68_get_shift_count (c);
4339
4340 if (n == 0) {
4341 d = s;
4342 e68_set_sr_c (c, 0);
4343 }
4344 else if (n < 16) {
4345 if (s & 0x8000) {
4346 d = (s | 0xffff0000) >> n;
4347 }
4348 else {
4349 d = s >> n;
4350 }
4351 e68_set_sr_xc (c, s & (1U << (n - 1)));
4352 }
4353 else {
4354 if (s & 0x8000) {
4355 d = 0xffff;
4356 e68_set_sr_xc (c, 1);
4357 }
4358 else {
4359 d = 0x0000;
4360 e68_set_sr_xc (c, 0);
4361 }
4362 }
4363
4364 e68_set_clk (c, 6 + 2 * n);
4365 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4366 e68_op_prefetch (c);
4367 e68_set_dreg16 (c, r, d);
4368}
4369
4370/* E040_01: LSR.W <cnt>, Dx */
4371static void ope040_01 (e68000_t *c)
4372{
4373 uint16_t s, d;
4374 unsigned r, n;
4375
4376 r = e68_ir_reg0 (c);
4377
4378 s = e68_get_dreg16 (c, r);
4379 n = e68_get_shift_count (c);
4380
4381 if (n == 0) {
4382 d = s;
4383 e68_set_sr_c (c, 0);
4384 }
4385 else if (n < 16) {
4386 d = s >> n;
4387 e68_set_sr_xc (c, s & (1U << (n - 1)));
4388 }
4389 else {
4390 d = 0;
4391 e68_set_sr_xc (c, (n == 16) && (s & 0x8000));
4392 }
4393
4394
4395 e68_set_clk (c, 6 + 2 * n);
4396 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4397 e68_op_prefetch (c);
4398 e68_set_dreg16 (c, r, d);
4399}
4400
4401/* E040_02: ROXR.W <cnt>, Dx */
4402static void ope040_02 (e68000_t *c)
4403{
4404 uint16_t d, x, t;
4405 unsigned r, i, n;
4406
4407 r = e68_ir_reg0 (c);
4408
4409 d = e68_get_dreg16 (c, r);
4410 n = e68_get_shift_count (c);
4411 x = e68_get_sr_x (c);
4412
4413 for (i = 0; i < n; i++) {
4414 t = d & 1;
4415 d = (d >> 1) | (x << 15);
4416 x = t;
4417 }
4418
4419 e68_set_clk (c, 6 + 2 * n);
4420 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4421 e68_set_sr_xc (c, x);
4422 e68_op_prefetch (c);
4423 e68_set_dreg16 (c, r, d);
4424}
4425
4426/* E040_03: ROR.W <cnt>, Dx */
4427static void ope040_03 (e68000_t *c)
4428{
4429 uint16_t s, d;
4430 unsigned r, n, k;
4431
4432 r = e68_ir_reg0 (c);
4433
4434 s = e68_get_dreg16 (c, r);
4435 n = e68_get_shift_count (c);
4436
4437 k = n & 15;
4438
4439 if (k > 0) {
4440 d = ((s >> k) | (s << (16 - k))) & 0xffff;
4441 e68_set_sr_c (c, d & 0x8000);
4442 }
4443 else {
4444 d = s;
4445 e68_set_sr_c (c, (n != 0) && (d & 0x8000));
4446 }
4447
4448 e68_set_clk (c, 6 + 2 * n);
4449 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4450 e68_op_prefetch (c);
4451 e68_set_dreg16 (c, r, d);
4452}
4453
4454/* E040: misc */
4455static void ope040 (e68000_t *c)
4456{
4457 switch ((c->ir[0] >> 3) & 3) {
4458 case 0x00:
4459 ope040_00 (c);
4460 return;
4461
4462 case 0x01:
4463 ope040_01 (c);
4464 return;
4465
4466 case 0x02:
4467 ope040_02 (c);
4468 return;
4469
4470 case 0x03:
4471 ope040_03 (c);
4472 return;
4473 }
4474
4475 e68_op_undefined (c);
4476}
4477
4478/* E080_00: ASR.L <cnt>, Dx */
4479static void ope080_00 (e68000_t *c)
4480{
4481 uint32_t s, d;
4482 unsigned r, n;
4483
4484 r = e68_ir_reg0 (c);
4485
4486 s = e68_get_dreg32 (c, r);
4487 n = e68_get_shift_count (c);
4488
4489 if (n == 0) {
4490 d = s;
4491 e68_set_sr_c (c, 0);
4492 }
4493 else if (n < 32) {
4494 if (s & 0x80000000) {
4495 d = (s >> n) | (0xffffffff << (32 - n));
4496 }
4497 else {
4498 d = s >> n;
4499 }
4500 e68_set_sr_xc (c, s & (1UL << (n - 1)));
4501 }
4502 else {
4503 if (s & 0x80000000) {
4504 d = 0xffffffff;
4505 e68_set_sr_xc (c, 1);
4506 }
4507 else {
4508 d = 0x00000000;
4509 e68_set_sr_xc (c, 0);
4510 }
4511 }
4512
4513
4514 e68_set_clk (c, 8 + 2 * n);
4515 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4516 e68_op_prefetch (c);
4517 e68_set_dreg32 (c, r, d);
4518}
4519
4520/* E080_01: LSR.L <cnt>, Dx */
4521static void ope080_01 (e68000_t *c)
4522{
4523 uint32_t s, d;
4524 unsigned r, n;
4525
4526 r = e68_ir_reg0 (c);
4527
4528 s = e68_get_dreg32 (c, r);
4529 n = e68_get_shift_count (c);
4530
4531 if (n == 0) {
4532 d = s;
4533 e68_set_sr_c (c, 0);
4534 }
4535 else if (n < 32) {
4536 d = s >> n;
4537 e68_set_sr_xc (c, s & (1UL << (n - 1)));
4538 }
4539 else {
4540 d = 0;
4541 e68_set_sr_xc (c, (n == 32) && (s & 0x80000000));
4542 }
4543
4544
4545 e68_set_clk (c, 8 + 2 * n);
4546 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4547 e68_op_prefetch (c);
4548 e68_set_dreg32 (c, r, d);
4549}
4550
4551/* E080_02: ROXR.L <cnt>, Dx */
4552static void ope080_02 (e68000_t *c)
4553{
4554 uint32_t d, x, t;
4555 unsigned r, i, n;
4556
4557 r = e68_ir_reg0 (c);
4558
4559 d = e68_get_dreg32 (c, r);
4560 n = e68_get_shift_count (c);
4561 x = e68_get_sr_x (c);
4562
4563 for (i = 0; i < n; i++) {
4564 t = d & 1;
4565 d = (d >> 1) | (x << 31);
4566 x = t;
4567 }
4568
4569 e68_set_clk (c, 8 + 2 * n);
4570 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4571 e68_set_sr_xc (c, x);
4572 e68_op_prefetch (c);
4573 e68_set_dreg32 (c, r, d);
4574}
4575
4576/* E080_03: ROR.L <cnt>, Dx */
4577static void ope080_03 (e68000_t *c)
4578{
4579 uint32_t s, d;
4580 unsigned r, n, k;
4581
4582 r = e68_ir_reg0 (c);
4583
4584 s = e68_get_dreg32 (c, r);
4585 n = e68_get_shift_count (c);
4586
4587 k = n & 31;
4588
4589 if (k > 0) {
4590 d = ((s >> k) | (s << (32 - k))) & 0xffffffff;
4591 e68_set_sr_c (c, d & 0x80000000);
4592 }
4593 else {
4594 d = s;
4595 e68_set_sr_c (c, (n != 0) && (d & 0x80000000));
4596 }
4597
4598 e68_set_clk (c, 8 + 2 * n);
4599 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4600 e68_op_prefetch (c);
4601 e68_set_dreg32 (c, r, d);
4602}
4603
4604/* E080: misc */
4605static void ope080 (e68000_t *c)
4606{
4607 switch ((c->ir[0] >> 3) & 3) {
4608 case 0x00:
4609 ope080_00 (c);
4610 return;
4611
4612 case 0x01:
4613 ope080_01 (c);
4614 return;
4615
4616 case 0x02:
4617 ope080_02 (c);
4618 return;
4619
4620 case 0x03:
4621 ope080_03 (c);
4622 return;
4623 }
4624
4625 e68_op_undefined (c);
4626}
4627
4628/* E0C0: ASR.W <EA> */
4629static void ope0c0 (e68000_t *c)
4630{
4631 uint16_t s, d;
4632
4633 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
4634
4635 d = (s >> 1) | (s & 0x8000);
4636
4637 e68_set_clk (c, 8);
4638 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4639 e68_set_cc (c, E68_SR_XC, s & 1);
4640 e68_op_prefetch (c);
4641 e68_op_set_ea16 (c, 0, 0, 0, d);
4642}
4643
4644/* E100_00: ASL.B <cnt>, Dx */
4645static void ope100_00 (e68000_t *c)
4646{
4647 uint8_t s, d, b;
4648 unsigned r, n;
4649
4650 r = e68_ir_reg0 (c);
4651
4652 s = e68_get_dreg8 (c, r);
4653 n = e68_get_shift_count (c);
4654
4655 if (n == 0) {
4656 d = s;
4657 e68_set_cc (c, E68_SR_C | E68_SR_V, 0);
4658 }
4659 else if (n < 8) {
4660 d = s << n;
4661 b = (0xff << (7 - n)) & 0xff;
4662 e68_set_sr_xc (c, s & (1 << (8 - n)));
4663 e68_set_sr_v (c, ((s & b) != 0) && ((s & b) != b));
4664 }
4665 else {
4666 d = 0x00;
4667 e68_set_sr_xc (c, (n == 8) && (s & 1));
4668 e68_set_sr_v (c, s != 0);
4669 }
4670
4671 e68_set_clk (c, 6 + 2 * n);
4672 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z, d);
4673 e68_op_prefetch (c);
4674 e68_set_dreg8 (c, r, d);
4675}
4676
4677/* E100_01: LSL.B <cnt>, Dx */
4678static void ope100_01 (e68000_t *c)
4679{
4680 uint8_t s, d;
4681 unsigned r, n;
4682
4683 r = e68_ir_reg0 (c);
4684
4685 s = e68_get_dreg8 (c, r);
4686 n = e68_get_shift_count (c);
4687
4688 if (n == 0) {
4689 d = s;
4690 e68_set_sr_c (c, 0);
4691 }
4692 else if (n < 8) {
4693 d = s << n;
4694 e68_set_sr_xc (c, s & (1 << (8 - n)));
4695 }
4696 else {
4697 d = 0;
4698 e68_set_sr_xc (c, (n == 8) && (s & 1));
4699 }
4700
4701
4702 e68_set_clk (c, 6 + 2 * n);
4703 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4704 e68_op_prefetch (c);
4705 e68_set_dreg8 (c, r, d);
4706}
4707
4708/* E100_02: ROXL.B <cnt>, Dx */
4709static void ope100_02 (e68000_t *c)
4710{
4711 uint16_t d, x, t;
4712 unsigned r, i, n;
4713
4714 r = e68_ir_reg0 (c);
4715
4716 d = e68_get_dreg8 (c, r);
4717 n = e68_get_shift_count (c);
4718 x = e68_get_sr_x (c);
4719
4720 for (i = 0; i < n; i++) {
4721 t = (d >> 7) & 1;
4722 d = (d << 1) | x;
4723 x = t;
4724 }
4725
4726 e68_set_clk (c, 6 + 2 * n);
4727 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4728 e68_set_sr_xc (c, x);
4729 e68_op_prefetch (c);
4730 e68_set_dreg8 (c, r, d);
4731}
4732
4733/* E100_03: ROL.B <cnt>, Dx */
4734static void ope100_03 (e68000_t *c)
4735{
4736 uint8_t s, d;
4737 unsigned r, n, k;
4738
4739 r = e68_ir_reg0 (c);
4740
4741 s = e68_get_dreg8 (c, r);
4742 n = e68_get_shift_count (c);
4743
4744 k = n & 7;
4745
4746 if (k != 0) {
4747 d = ((s << k) | (s >> (8 - k))) & 0xff;
4748 e68_set_sr_c (c, d & 1);
4749 }
4750 else {
4751 d = s;
4752 e68_set_sr_c (c, (n != 0) && (d & 1));
4753 }
4754
4755 e68_set_clk (c, 6 + 2 * n);
4756 e68_cc_set_nz_8 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4757 e68_op_prefetch (c);
4758 e68_set_dreg8 (c, r, d);
4759}
4760
4761/* E100: misc */
4762static void ope100 (e68000_t *c)
4763{
4764 switch ((c->ir[0] >> 3) & 3) {
4765 case 0x00:
4766 ope100_00 (c);
4767 return;
4768
4769 case 0x01:
4770 ope100_01 (c);
4771 return;
4772
4773 case 0x02:
4774 ope100_02 (c);
4775 return;
4776
4777 case 0x03:
4778 ope100_03 (c);
4779 return;
4780 }
4781
4782 e68_op_undefined (c);
4783}
4784
4785/* E140_00: ASL.W <cnt>, Dx */
4786static void ope140_00 (e68000_t *c)
4787{
4788 uint16_t s, d, b;
4789 unsigned r, n;
4790
4791 r = e68_ir_reg0 (c);
4792
4793 s = e68_get_dreg16 (c, r);
4794 n = e68_get_shift_count (c);
4795
4796 if (n == 0) {
4797 d = s;
4798 e68_set_cc (c, E68_SR_C | E68_SR_V, 0);
4799 }
4800 else if (n < 16) {
4801 d = s << n;
4802 b = (0xffff << (15 - n)) & 0xffff;
4803 e68_set_sr_xc (c, s & (1U << (16 - n)));
4804 e68_set_sr_v (c, ((s & b) != 0) && ((s & b) != b));
4805 }
4806 else {
4807 d = 0x0000;
4808 e68_set_sr_xc (c, (n == 16) && (s & 1));
4809 e68_set_sr_v (c, s != 0);
4810 }
4811
4812
4813 e68_set_clk (c, 6 + 2 * n);
4814 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z, d);
4815 e68_op_prefetch (c);
4816 e68_set_dreg16 (c, r, d);
4817}
4818
4819/* E140_01: LSL.W <cnt>, Dx */
4820static void ope140_01 (e68000_t *c)
4821{
4822 uint16_t s, d;
4823 unsigned r, n;
4824
4825 r = e68_ir_reg0 (c);
4826
4827 s = e68_get_dreg16 (c, r);
4828 n = e68_get_shift_count (c);
4829
4830 if (n == 0) {
4831 d = s;
4832 e68_set_sr_c (c, 0);
4833 }
4834 else if (n < 16) {
4835 d = s << n;
4836 e68_set_sr_xc (c, s & (1U << (16 - n)));
4837 }
4838 else {
4839 d = 0;
4840 e68_set_sr_xc (c, (n == 16) && (s & 1));
4841 }
4842
4843
4844 e68_set_clk (c, 6 + 2 * n);
4845 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4846 e68_op_prefetch (c);
4847 e68_set_dreg16 (c, r, d);
4848}
4849
4850/* E140_02: ROXL.W <cnt>, Dx */
4851static void ope140_02 (e68000_t *c)
4852{
4853 uint16_t d, x, t;
4854 unsigned r, i, n;
4855
4856 r = e68_ir_reg0 (c);
4857
4858 d = e68_get_dreg16 (c, r);
4859 n = e68_get_shift_count (c);
4860 x = e68_get_sr_x (c);
4861
4862 for (i = 0; i < n; i++) {
4863 t = (d >> 15) & 1;
4864 d = (d << 1) | x;
4865 x = t;
4866 }
4867
4868 e68_set_clk (c, 6 + 2 * n);
4869 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4870 e68_set_sr_xc (c, x);
4871 e68_op_prefetch (c);
4872 e68_set_dreg16 (c, r, d);
4873}
4874
4875/* E140_03: ROL.W <cnt>, Dx */
4876static void ope140_03 (e68000_t *c)
4877{
4878 uint16_t s, d;
4879 unsigned r, n, k;
4880
4881 r = e68_ir_reg0 (c);
4882
4883 s = e68_get_dreg16 (c, r);
4884 n = e68_get_shift_count (c);
4885
4886 k = n & 15;
4887
4888 if (k != 0) {
4889 d = ((s << k) | (s >> (16 - k))) & 0xffff;
4890 e68_set_sr_c (c, d & 1);
4891 }
4892 else {
4893 d = s;
4894 e68_set_sr_c (c, (n != 0) && (d & 1));
4895 }
4896
4897 e68_set_clk (c, 6 + 2 * n);
4898 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4899 e68_op_prefetch (c);
4900 e68_set_dreg16 (c, r, d);
4901}
4902
4903/* E140: misc */
4904static void ope140 (e68000_t *c)
4905{
4906 switch ((c->ir[0] >> 3) & 3) {
4907 case 0x00:
4908 ope140_00 (c);
4909 return;
4910
4911 case 0x01:
4912 ope140_01 (c);
4913 return;
4914
4915 case 0x02:
4916 ope140_02 (c);
4917 return;
4918
4919 case 0x03:
4920 ope140_03 (c);
4921 return;
4922 }
4923
4924 e68_op_undefined (c);
4925}
4926
4927/* E180_00: ASL.L <cnt>, Dx */
4928static void ope180_00 (e68000_t *c)
4929{
4930 uint32_t s, d, b;
4931 unsigned r, n;
4932
4933 r = e68_ir_reg0 (c);
4934
4935 s = e68_get_dreg32 (c, r);
4936 n = e68_get_shift_count (c);
4937
4938 if (n == 0) {
4939 d = s;
4940 e68_set_cc (c, E68_SR_C | E68_SR_V, 0);
4941 }
4942 else if (n < 32) {
4943 d = s << n;
4944 b = (0xffffffff << (31 - n)) & 0xffffffff;
4945 e68_set_sr_xc (c, s & (1UL << (32 - n)));
4946 e68_set_sr_v (c, ((s & b) != 0) && ((s & b) != b));
4947 }
4948 else {
4949 d = 0;
4950 e68_set_sr_xc (c, (n == 32) && (s & 1));
4951 e68_set_sr_v (c, s != 0);
4952 }
4953
4954 e68_set_clk (c, 8 + 2 * n);
4955 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z, d);
4956 e68_op_prefetch (c);
4957 e68_set_dreg32 (c, r, d);
4958}
4959
4960/* E180_01: LSL.L <cnt>, Dx */
4961static void ope180_01 (e68000_t *c)
4962{
4963 uint32_t s, d;
4964 unsigned r, n;
4965
4966 r = e68_ir_reg0 (c);
4967
4968 s = e68_get_dreg32 (c, r);
4969 n = e68_get_shift_count (c);
4970
4971 if (n == 0) {
4972 d = s;
4973 e68_set_sr_c (c, 0);
4974 }
4975 else if (n < 32) {
4976 d = s << n;
4977 e68_set_sr_xc (c, s & (1UL << (32 - n)));
4978 }
4979 else {
4980 d = 0;
4981 e68_set_sr_xc (c, (n == 32) && (s & 1));
4982 }
4983
4984
4985 e68_set_clk (c, 8 + 2 * n);
4986 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
4987 e68_op_prefetch (c);
4988 e68_set_dreg32 (c, r, d);
4989}
4990
4991/* E180_02: ROXL.L <cnt>, Dx */
4992static void ope180_02 (e68000_t *c)
4993{
4994 uint32_t d, x, t;
4995 unsigned r, i, n;
4996
4997 r = e68_ir_reg0 (c);
4998
4999 n = e68_get_shift_count (c);
5000 d = e68_get_dreg32 (c, r);
5001 x = e68_get_sr_x (c);
5002
5003 for (i = 0; i < n; i++) {
5004 t = (d >> 31) & 1;
5005 d = (d << 1) | x;
5006 x = t;
5007 }
5008
5009 e68_set_clk (c, 8 + 2 * n);
5010 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5011 e68_set_sr_xc (c, x);
5012 e68_op_prefetch (c);
5013 e68_set_dreg32 (c, r, d);
5014}
5015
5016/* E180_03: ROL.L <cnt>, Dx */
5017static void ope180_03 (e68000_t *c)
5018{
5019 uint32_t s, d;
5020 unsigned r, n, k;
5021
5022 r = e68_ir_reg0 (c);
5023
5024 s = e68_get_dreg32 (c, r);
5025 n = e68_get_shift_count (c);
5026
5027 k = n & 31;
5028
5029 if (k > 0) {
5030 d = ((s << k) | (s >> (32 - k))) & 0xffffffff;
5031 e68_set_sr_c (c, d & 1);
5032 }
5033 else {
5034 d = s;
5035 e68_set_sr_c (c, (n != 0) && (d & 1));
5036 }
5037
5038 e68_set_clk (c, 8 + 2 * n);
5039 e68_cc_set_nz_32 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5040 e68_op_prefetch (c);
5041 e68_set_dreg32 (c, r, d);
5042}
5043
5044/* E180: misc */
5045static void ope180 (e68000_t *c)
5046{
5047 switch ((c->ir[0] >> 3) & 3) {
5048 case 0x00:
5049 ope180_00 (c);
5050 return;
5051
5052 case 0x01:
5053 ope180_01 (c);
5054 return;
5055
5056 case 0x02:
5057 ope180_02 (c);
5058 return;
5059
5060 case 0x03:
5061 ope180_03 (c);
5062 return;
5063 }
5064
5065 e68_op_undefined (c);
5066}
5067
5068/* E1C0: ASL.W <EA> */
5069static void ope1c0 (e68000_t *c)
5070{
5071 uint16_t s, d;
5072
5073 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5074
5075 d = (s << 1) & 0xffff;
5076
5077 e68_set_clk (c, 8);
5078 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z, d);
5079 e68_set_sr_xc (c, s & 0x8000);
5080 e68_set_sr_v (c, (s ^ d) & 0x8000);
5081 e68_op_prefetch (c);
5082 e68_op_set_ea16 (c, 0, 0, 0, d);
5083}
5084
5085/* E2C0: LSR.W <EA> */
5086static void ope2c0 (e68000_t *c)
5087{
5088 uint16_t s, d;
5089
5090 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5091
5092 d = s >> 1;
5093
5094 e68_set_clk (c, 8);
5095 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5096 e68_set_sr_xc (c, s & 1);
5097 e68_op_prefetch (c);
5098 e68_op_set_ea16 (c, 0, 0, 0, d);
5099}
5100
5101/* E3C0: LSL.W <EA> */
5102static void ope3c0 (e68000_t *c)
5103{
5104 uint16_t s, d;
5105
5106 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5107
5108 d = (s << 1) & 0xffff;
5109
5110 e68_set_clk (c, 8);
5111 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5112 e68_set_sr_xc (c, s & 0x8000);
5113 e68_op_prefetch (c);
5114 e68_op_set_ea16 (c, 0, 0, 0, d);
5115}
5116
5117/* E4C0: ROXR.W <EA> */
5118static void ope4c0 (e68000_t *c)
5119{
5120 uint16_t s, d, x;
5121
5122 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5123 x = e68_get_sr_x (c);
5124
5125 d = (s >> 1) | (x << 15);
5126
5127 e68_set_clk (c, 8);
5128 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5129 e68_set_sr_xc (c, s & 1);
5130 e68_op_prefetch (c);
5131 e68_op_set_ea16 (c, 0, 0, 0, d);
5132}
5133
5134/* E5C0: ROXL.W <EA> */
5135static void ope5c0 (e68000_t *c)
5136{
5137 uint16_t s, d, x;
5138
5139 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5140 x = e68_get_sr_x (c);
5141
5142 d = ((s << 1) | x) & 0xffff;
5143
5144 e68_set_clk (c, 8);
5145 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5146 e68_set_sr_xc (c, s & 0x8000);
5147 e68_op_prefetch (c);
5148 e68_op_set_ea16 (c, 0, 0, 0, d);
5149}
5150
5151/* E6C0: ROR.W <EA> */
5152static void ope6c0 (e68000_t *c)
5153{
5154 uint16_t s, d;
5155
5156 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5157
5158 d = ((s >> 1) | (s << 15)) & 0xffff;
5159
5160 e68_set_clk (c, 8);
5161 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5162 e68_set_sr_c (c, s & 1);
5163 e68_op_prefetch (c);
5164 e68_op_set_ea16 (c, 0, 0, 0, d);
5165}
5166
5167/* E7C0: ROL.W <EA> */
5168static void ope7c0 (e68000_t *c)
5169{
5170 uint16_t s, d;
5171
5172 e68_op_get_ea16 (c, 1, e68_ir_ea1 (c), 0x01fc, &s);
5173
5174 d = ((s << 1) | (s >> 15)) & 0xffff;
5175
5176 e68_set_clk (c, 8);
5177 e68_cc_set_nz_16 (c, E68_SR_N | E68_SR_Z | E68_SR_V, d);
5178 e68_set_sr_c (c, d & 1);
5179 e68_op_prefetch (c);
5180 e68_op_set_ea16 (c, 0, 0, 0, d);
5181}
5182
5183/* F000: FXXX */
5184static void opf000 (e68000_t *c)
5185{
5186 c->last_trap_f = c->ir[0];
5187
5188 e68_exception_fxxx (c);
5189}
5190
5191static
5192e68_opcode_f e68_opcodes[1024] = {
5193 op0000, op0040, op0080, NULL, op0100, op0140, op0180, op01c0, /* 0000 */
5194 op0200, op0240, op0280, NULL, op0100, op0140, op0180, op01c0, /* 0200 */
5195 op0400, op0440, op0480, NULL, op0100, op0140, op0180, op01c0, /* 0400 */
5196 op0600, op0640, op0680, NULL, op0100, op0140, op0180, op01c0, /* 0600 */
5197 op0800, op0840, op0880, op08c0, op0100, op0140, op0180, op01c0, /* 0800 */
5198 op0a00, op0a40, op0a80, NULL, op0100, op0140, op0180, op01c0, /* 0A00 */
5199 op0c00, op0c40, op0c80, NULL, op0100, op0140, op0180, op01c0, /* 0C00 */
5200 op0e00, op0e40, op0e80, NULL, op0100, op0140, op0180, op01c0, /* 0E00 */
5201 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1000 */
5202 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1200 */
5203 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1400 */
5204 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1600 */
5205 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1800 */
5206 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1A00 */
5207 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1C00 */
5208 op1000, NULL, op1000, op1000, op1000, op1000, op1000, op1000, /* 1E00 */
5209 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2000 */
5210 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2200 */
5211 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2400 */
5212 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2600 */
5213 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2800 */
5214 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2A00 */
5215 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2C00 */
5216 op2000, op2040, op2000, op2000, op2000, op2000, op2000, op2000, /* 2E00 */
5217 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3000 */
5218 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3200 */
5219 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3400 */
5220 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3600 */
5221 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3800 */
5222 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3A00 */
5223 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3C00 */
5224 op3000, op3040, op3000, op3000, op3000, op3000, op3000, op3000, /* 3E00 */
5225 op4000, op4040, op4080, op40c0, NULL, NULL, op4180, op41c0, /* 4000 */
5226 op4200, op4240, op4280, op42c0, NULL, NULL, op4180, op41c0, /* 4200 */
5227 op4400, op4440, op4480, op44c0, NULL, NULL, op4180, op41c0, /* 4400 */
5228 op4600, op4640, op4680, op46c0, NULL, NULL, op4180, op41c0, /* 4600 */
5229 op4800, op4840, op4880, op48c0, NULL, NULL, op4180, op49c0, /* 4800 */
5230 op4a00, op4a40, op4a80, op4ac0, NULL, NULL, op4180, op41c0, /* 4A00 */
5231 NULL, NULL, op4c80, op4cc0, NULL, NULL, op4180, op41c0, /* 4C00 */
5232 NULL, op4e40, op4e80, op4ec0, NULL, NULL, op4180, op41c0, /* 4E00 */
5233 op5000, op5040, op5080, op50c0, op5100, op5140, op5180, op51c0, /* 5000 */
5234 op5000, op5040, op5080, op52c0, op5100, op5140, op5180, op53c0, /* 5200 */
5235 op5000, op5040, op5080, op54c0, op5100, op5140, op5180, op55c0, /* 5400 */
5236 op5000, op5040, op5080, op56c0, op5100, op5140, op5180, op57c0, /* 5600 */
5237 op5000, op5040, op5080, op58c0, op5100, op5140, op5180, op59c0, /* 5800 */
5238 op5000, op5040, op5080, op5ac0, op5100, op5140, op5180, op5bc0, /* 5A00 */
5239 op5000, op5040, op5080, op5cc0, op5100, op5140, op5180, op5dc0, /* 5C00 */
5240 op5000, op5040, op5080, op5ec0, op5100, op5140, op5180, op5fc0, /* 5E00 */
5241 op6000, op6000, op6000, op6000, op6100, op6100, op6100, op6100, /* 6000 */
5242 op6200, op6200, op6200, op6200, op6300, op6300, op6300, op6300, /* 6200 */
5243 op6400, op6400, op6400, op6400, op6500, op6500, op6500, op6500, /* 6400 */
5244 op6600, op6600, op6600, op6600, op6700, op6700, op6700, op6700, /* 6600 */
5245 op6800, op6800, op6800, op6800, op6900, op6900, op6900, op6900, /* 6800 */
5246 op6a00, op6a00, op6a00, op6a00, op6b00, op6b00, op6b00, op6b00, /* 6A00 */
5247 op6c00, op6c00, op6c00, op6c00, op6d00, op6d00, op6d00, op6d00, /* 6C00 */
5248 op6e00, op6e00, op6e00, op6e00, op6f00, op6f00, op6f00, op6f00, /* 6E00 */
5249 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7000 */
5250 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7200 */
5251 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7400 */
5252 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7600 */
5253 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7800 */
5254 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7A00 */
5255 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7C00 */
5256 op7000, op7000, op7000, op7000, NULL, NULL, NULL, NULL, /* 7E00 */
5257 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8000 */
5258 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8200 */
5259 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8400 */
5260 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8600 */
5261 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8800 */
5262 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8A00 */
5263 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8C00 */
5264 op8000, op8040, op8080, op80c0, op8100, op8140, op8180, op81c0, /* 8E00 */
5265 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9000 */
5266 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9200 */
5267 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9400 */
5268 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9600 */
5269 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9800 */
5270 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9A00 */
5271 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9C00 */
5272 op9000, op9040, op9080, op90c0, op9100, op9140, op9180, op91c0, /* 9E00 */
5273 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000, /* A000 */
5274 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5275 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5276 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5277 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5278 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5279 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5280 opa000, opa000, opa000, opa000, opa000, opa000, opa000, opa000,
5281 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* B000 */
5282 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* B200 */
5283 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* B400 */
5284 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* B600 */
5285 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* B800 */
5286 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* BA00 */
5287 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* BC00 */
5288 opb000, opb040, opb080, opb0c0, opb100, opb140, opb180, opb1c0, /* BE00 */
5289 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* C000 */
5290 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* C200 */
5291 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* C400 */
5292 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* C600 */
5293 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* C800 */
5294 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* CA00 */
5295 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* CC00 */
5296 opc000, opc040, opc080, opc0c0, opc100, opc140, opc180, opc1c0, /* CE00 */
5297 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* D000 */
5298 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* D200 */
5299 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* D400 */
5300 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* D600 */
5301 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* D800 */
5302 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* DA00 */
5303 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* DC00 */
5304 opd000, opd040, opd080, opd0c0, opd100, opd140, opd180, opd1c0, /* DE00 */
5305 ope000, ope040, ope080, ope0c0, ope100, ope140, ope180, ope1c0, /* E000 */
5306 ope000, ope040, ope080, ope2c0, ope100, ope140, ope180, ope3c0, /* E200 */
5307 ope000, ope040, ope080, ope4c0, ope100, ope140, ope180, ope5c0, /* E400 */
5308 ope000, ope040, ope080, ope6c0, ope100, ope140, ope180, ope7c0, /* E600 */
5309 ope000, ope040, ope080, NULL, ope100, ope140, ope180, NULL, /* E800 */
5310 ope000, ope040, ope080, NULL, ope100, ope140, ope180, NULL, /* EA00 */
5311 ope000, ope040, ope080, NULL, ope100, ope140, ope180, NULL, /* EC00 */
5312 ope000, ope040, ope080, NULL, ope100, ope140, ope180, NULL, /* EE00 */
5313 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000, /* F000 */
5314 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000,
5315 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000,
5316 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000,
5317 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000,
5318 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000,
5319 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000,
5320 opf000, opf000, opf000, opf000, opf000, opf000, opf000, opf000
5321};
5322
5323static e68_opcode_f e68_op_49c0[8] = {
5324 NULL, op41c0, op41c0, op41c0, op41c0, op41c0, op41c0, op41c0
5325};
5326
5327void e68_set_opcodes (e68000_t *c)
5328{
5329 unsigned i;
5330
5331 for (i = 0; i < 1024; i++) {
5332 if (e68_opcodes[i] != NULL) {
5333 c->opcodes[i] = e68_opcodes[i];
5334 }
5335 else {
5336 c->opcodes[i] = e68_op_undefined;
5337 }
5338 }
5339
5340 for (i = 0; i < 8; i++) {
5341 c->op49c0[i] = (e68_op_49c0[i] == NULL) ? e68_op_undefined : e68_op_49c0[i];
5342 }
5343}