summaryrefslogtreecommitdiff
path: root/sim/mn10200/simops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/mn10200/simops.c')
-rw-r--r--sim/mn10200/simops.c2449
1 files changed, 2449 insertions, 0 deletions
diff --git a/sim/mn10200/simops.c b/sim/mn10200/simops.c
new file mode 100644
index 00000000000..ecceccae92f
--- /dev/null
+++ b/sim/mn10200/simops.c
@@ -0,0 +1,2449 @@
+#include "config.h"
+
+#include <signal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include "mn10200_sim.h"
+#include "simops.h"
+#include "targ-vals.h"
+#include "bfd.h"
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <sys/time.h>
+
+#define REG0(X) ((X) & 0x3)
+#define REG1(X) (((X) & 0xc) >> 2)
+#define REG0_4(X) (((X) & 0x30) >> 4)
+#define REG0_8(X) (((X) & 0x300) >> 8)
+#define REG1_8(X) (((X) & 0xc00) >> 10)
+#define REG0_16(X) (((X) & 0x30000) >> 16)
+#define REG1_16(X) (((X) & 0xc0000) >> 18)
+#define TRUNC(X) ((X) & 0xffffff)
+
+/* mov imm8, dn */
+void OP_8000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_8 (insn)] = SEXT8 (insn & 0xff);
+}
+
+/* mov dn, dm */
+void OP_80 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_D0 + REG1 (insn)];
+}
+
+/* mov dm, an */
+void OP_F230 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0 (insn)] = State.regs[REG_D0 + REG1 (insn)];
+}
+
+/* mov an, dm */
+void OP_F2F0 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_A0 + REG1 (insn)];
+}
+
+/* mov an, am */
+void OP_F270 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0 (insn)] = State.regs[REG_A0 + REG1 (insn)];
+}
+
+/* mov psw, dn */
+void OP_F3F0 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = PSW & 0xffff;
+}
+
+/* mov dn, psw */
+void OP_F3D0 (insn, extension)
+ unsigned long insn, extension;
+{
+ PSW = State.regs[REG_D0 + REG1 (insn)] & 0xffff ;
+}
+
+/* mov mdr, dn */
+void OP_F3E0 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_MDR] & 0xffff;
+}
+
+/* mov dn, mdr */
+void OP_F3C0 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_MDR] = State.regs[REG_D0 + REG1 (insn)] & 0xffff;
+}
+
+/* mov (an), dm */
+void OP_20 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)]
+ = SEXT16 (load_half (State.regs[REG_A0 + REG1 (insn)]));
+}
+
+/* mov (d8,an), dm */
+void OP_6000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_8 (insn)]
+ = SEXT16 (load_half ((State.regs[REG_A0 + REG1_8 (insn)]
+ + SEXT8 (insn & 0xff))));
+}
+
+/* mov (d16,an), dm */
+void OP_F7C00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT16 (load_half ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT16 (insn & 0xffff))));
+}
+
+/* mov (d24,am), dn */
+void OP_F4800000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT16 (load_half ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension))));
+}
+
+/* mov (di,an), dm */
+void OP_F140 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)]
+ = SEXT16 (load_half ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)])));
+}
+
+/* mov (abs16), dn */
+void OP_C80000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)] = SEXT16 (load_half ((insn & 0xffff)));
+}
+
+/* mov (abs24), dn */
+void OP_F4C00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT16 (load_half ((((insn & 0xffff) << 8) + extension)));
+}
+
+/* mov (d8,an), am */
+void OP_7000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_8 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1_8 (insn)]
+ + SEXT8 (insn & 0xff))));
+}
+
+/* mov (d16,an), am */
+void OP_F7B00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_16 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT16 (insn & 0xffff))));
+}
+
+/* mov (d24,am), an */
+void OP_F4F00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_16 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension))));
+}
+
+/* mov (di,an), am */
+void OP_F100 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)])));
+}
+
+/* mov (abs16), an */
+void OP_F7300000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_16 (insn)] = SEXT24 (load_3_byte ((insn & 0xffff)));
+}
+
+/* mov (abs24), an */
+void OP_F4D00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_16 (insn)]
+ = SEXT24 (load_3_byte ((((insn & 0xffff) << 8) + extension)));
+}
+
+/* mov dm, (an) */
+void OP_0 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half (State.regs[REG_A0 + REG1 (insn)],
+ State.regs[REG_D0 + REG0 (insn)]);
+}
+
+/* mov dm, (d8,an) */
+void OP_4000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half (State.regs[REG_A0 + REG1_8 (insn)] + SEXT8 (insn & 0xff),
+ State.regs[REG_D0 + REG0_8 (insn)]);
+}
+
+/* mov dm, (d16,an) */
+void OP_F7800000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half (State.regs[REG_A0 + REG1_16 (insn)] + SEXT16 (insn & 0xffff),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* mov dm, (d24,am) */
+void OP_F4000000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension)),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* mov dm, (di,an) */
+void OP_F1C0 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)]),
+ State.regs[REG_D0 + REG0 (insn)]);
+}
+
+/* mov dn, (abs16) */
+void OP_C00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half ((insn & 0xffff), State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* mov dn, (abs24) */
+void OP_F4400000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_half (SEXT24 (((insn & 0xffff) << 8) + extension),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* mov am, (d8,an) */
+void OP_5000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte (State.regs[REG_A0 + REG1_8 (insn)] + SEXT8 (insn & 0xff),
+ State.regs[REG_A0 + REG0_8 (insn)]);
+}
+
+/* mov am, (d16,an) */
+void OP_F7A00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte (State.regs[REG_A0 + REG1_16 (insn)] + SEXT16 (insn & 0xffff),
+ State.regs[REG_A0 + REG0_16 (insn)]);
+}
+
+/* mov am, (d24,an) */
+void OP_F4100000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension)),
+ State.regs[REG_A0 + REG0_16 (insn)]);
+}
+
+/* mov am, (di,an) */
+void OP_F180 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)]),
+ State.regs[REG_A0 + REG0 (insn)]);
+}
+
+/* mov an, (abs16) */
+void OP_F7200000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte ((insn & 0xffff), State.regs[REG_A0 + REG0_16 (insn)]);
+}
+
+/* mov an, (abs24) */
+void OP_F4500000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte (SEXT24 (((insn & 0xffff) << 8) + extension),
+ State.regs[REG_A0 + REG0_16 (insn)]);
+}
+
+/* mov imm16, dn */
+void OP_F80000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)] = SEXT16 (insn & 0xffff);
+}
+
+/* mov imm24, dn */
+void OP_F4700000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT24 (((insn & 0xffff) << 8) + extension);
+}
+
+/* mov imm16, an */
+void OP_DC0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_16 (insn)] = insn & 0xffff;
+}
+
+/* mov imm24, an */
+void OP_F4740000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_A0 + REG0_16 (insn)]
+ = SEXT24 (((insn & 0xffff) << 8) + extension);
+}
+
+/* movx (d8,an), dm */
+void OP_F57000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_8 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1_8 (insn)]
+ + SEXT8 (insn & 0xff))));
+}
+
+/* movx (d16,an), dm */
+void OP_F7700000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT16 (insn & 0xffff))));
+}
+
+/* movx (d24,am), dn */
+void OP_F4B00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT24 (load_3_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension))));
+}
+
+/* movx dm, (d8,an) */
+void OP_F55000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte (State.regs[REG_A0 + REG1_8 (insn)] + SEXT8 (insn & 0xff),
+ State.regs[REG_D0 + REG0_8 (insn)]);
+}
+
+/* movx dm, (d16,an) */
+void OP_F7600000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte (State.regs[REG_A0 + REG1_16 (insn)] + SEXT16 (insn & 0xffff),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* movx dm, (d24,am) */
+void OP_F4300000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_3_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension)),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* movb (d8,an), dm */
+void OP_F52000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_8 (insn)]
+ = SEXT8 (load_byte ((State.regs[REG_A0 + REG1_8 (insn)]
+ + SEXT8 (insn & 0xff))));
+}
+
+/* movb (d16,an), dm */
+void OP_F7D00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT8 (load_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT16 (insn & 0xffff))));
+}
+
+/* movb (d24,am), dn */
+void OP_F4A00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT8 (load_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension))));
+}
+
+/* movb (di,an), dm */
+void OP_F040 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)]
+ = SEXT8 (load_byte ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)])));
+}
+
+/* mov (abs24), dn */
+void OP_F4C40000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = SEXT8 (load_byte ((((insn & 0xffff) << 8) + extension)));
+}
+
+/* movb dm, (an) */
+void OP_10 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte (State.regs[REG_A0 + REG1 (insn)],
+ State.regs[REG_D0 + REG0 (insn)]);
+}
+
+/* movb dm, (d8,an) */
+void OP_F51000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte (State.regs[REG_A0 + REG1_8 (insn)] + SEXT8 (insn & 0xff),
+ State.regs[REG_D0 + REG0_8 (insn)]);
+}
+
+/* movb dm, (d16,an) */
+void OP_F7900000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte (State.regs[REG_A0 + REG1_16 (insn)] + SEXT16 (insn & 0xffff),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* movb dm, (d24,am) */
+void OP_F4200000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension)),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* movb dm, (di,an) */
+void OP_F0C0 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)]),
+ State.regs[REG_D0 + REG0 (insn)]);
+}
+
+/* movb dn, (abs16) */
+void OP_C40000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte ((insn & 0xffff), State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* movb dn, (abs24) */
+void OP_F4440000 (insn, extension)
+ unsigned long insn, extension;
+{
+ store_byte (SEXT24 (((insn & 0xffff) << 8) + extension),
+ State.regs[REG_D0 + REG0_16 (insn)]);
+}
+
+/* movbu (an), dm */
+void OP_30 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)]
+ = load_byte (State.regs[REG_A0 + REG1 (insn)]);
+}
+
+/* movbu (d8,an), dm */
+void OP_F53000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_8 (insn)]
+ = load_byte ((State.regs[REG_A0 + REG1_8 (insn)] + SEXT8 (insn & 0xff)));
+}
+
+/* movbu (d16,an), dm */
+void OP_F7500000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = load_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT16 (insn & 0xffff)));
+}
+
+/* movbu (d24,am), dn */
+void OP_F4900000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = load_byte ((State.regs[REG_A0 + REG1_16 (insn)]
+ + SEXT24 (((insn & 0xffff) << 8) + extension)));
+}
+
+/* movbu (di,an), dm */
+void OP_F080 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)]
+ = load_byte ((State.regs[REG_A0 + REG1 (insn)]
+ + State.regs[REG_D0 + REG0_4 (insn)]));
+}
+
+/* movbu (abs16), dn */
+void OP_CC0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)] = load_byte ((insn & 0xffff));
+}
+
+/* movbu (abs24), dn */
+void OP_F4C80000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0_16 (insn)]
+ = load_byte ((((insn & 0xffff) << 8) + extension));
+}
+
+/* ext dn */
+void OP_F3C1 (insn, extension)
+ unsigned long insn, extension;
+{
+ if (State.regs[REG_D0 + REG1 (insn)] & 0x8000)
+ State.regs[REG_MDR] = 0xffff;
+ else
+ State.regs[REG_MDR] = 0;
+}
+
+/* extx dn */
+void OP_B0 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = SEXT16 (State.regs[REG_D0 + REG0 (insn)]);
+}
+
+/* extxu dn */
+void OP_B4 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_D0 + REG0 (insn)] & 0xffff;
+}
+
+/* extxb dn */
+void OP_B8 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = SEXT8 (State.regs[REG_D0 + REG0 (insn)]);
+}
+
+/* extxbu dn */
+void OP_BC (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_D0 + REG0 (insn)] & 0xff;
+}
+
+/* add dn,dm */
+void OP_90 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg1 + reg2);
+ State.regs[REG_D0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (reg2 & 0xffff));
+ cx = (value < reg1) || (value < reg2);
+ v = ((reg2 & 0x8000) == (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) == (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add dm, an */
+void OP_F200 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_A0 + REG0 (insn)]);
+ value = TRUNC (reg1 + reg2);
+ State.regs[REG_A0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (reg2 & 0xffff));
+ cx = (value < reg1) || (value < reg2);
+ v = ((reg2 & 0x8000) == (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) == (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add an, dm */
+void OP_F2C0 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg1 + reg2);
+ State.regs[REG_D0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (reg2 & 0xffff));
+ cx = (value < reg1) || (value < reg2);
+ v = ((reg2 & 0x8000) == (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) == (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add an,am */
+void OP_F240 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_A0 + REG0 (insn)]);
+ value = TRUNC (reg1 + reg2);
+ State.regs[REG_A0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (reg2 & 0xffff));
+ cx = (value < reg1) || (value < reg2);
+ v = ((reg2 & 0x8000) == (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) == (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add imm8, dn */
+void OP_D400 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_8 (insn)]);
+ imm = TRUNC (SEXT8 (insn & 0xff));
+ value = TRUNC (reg1 + imm);
+ State.regs[REG_D0 + REG0_8 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (imm & 0xffff));
+ cx = (value < reg1) || (value < imm);
+ v = ((reg1 & 0x8000) == (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) == (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add imm16, dn */
+void OP_F7180000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_16 (insn)]);
+ imm = TRUNC (SEXT16 (insn & 0xffff));
+ value = TRUNC (reg1 + imm);
+ State.regs[REG_D0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (imm & 0xffff));
+ cx = (value < reg1) || (value < imm);
+ v = ((reg1 & 0x8000) == (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) == (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add imm24,dn */
+void OP_F4600000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_16 (insn)]);
+ imm = TRUNC (((insn & 0xffff) << 8) + extension);
+ value = TRUNC (reg1 + imm);
+ State.regs[REG_D0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (imm & 0xffff));
+ cx = (value < reg1) || (value < imm);
+ v = ((reg1 & 0x8000) == (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) == (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add imm8, an */
+void OP_D000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_8 (insn)]);
+ imm = TRUNC (SEXT8 (insn & 0xff));
+ value = TRUNC (reg1 + imm);
+ State.regs[REG_A0 + REG0_8 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (imm & 0xffff));
+ cx = (value < reg1) || (value < imm);
+ v = ((reg1 & 0x8000) == (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) == (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add imm16, an */
+void OP_F7080000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_16 (insn)]);
+ imm = TRUNC (SEXT16 (insn & 0xffff));
+ value = TRUNC (reg1 + imm);
+ State.regs[REG_A0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (imm & 0xffff));
+ cx = (value < reg1) || (value < imm);
+ v = ((reg1 & 0x8000) == (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) == (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* add imm24, an */
+void OP_F4640000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_16 (insn)]);
+ imm = TRUNC (((insn & 0xffff) << 8) + extension);
+ value = TRUNC (reg1 + imm);
+ State.regs[REG_A0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff)) || ((value & 0xffff) < (imm & 0xffff));
+ cx = (value < reg1) || (value < imm);
+ v = ((reg1 & 0x8000) == (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) == (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* addc dm,dn */
+void OP_F280 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg1 + reg2 + ((PSW & PSW_CF) != 0));
+ State.regs[REG_D0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((value & 0xffff) < (reg1 & 0xffff))
+ || ((value & 0xffff) < (reg2 & 0xffff));
+ cx = (value < reg1) || (value < reg2);
+ v = ((reg2 & 0x8000) == (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) == (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* addnf imm8, an */
+void OP_F50C00 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long reg1, imm, value;
+
+ reg1 = State.regs[REG_A0 + REG0_8 (insn)];
+ imm = SEXT8 (insn & 0xff);
+ value = reg1 + imm;
+ State.regs[REG_A0 + REG0_8 (insn)] = TRUNC (value);
+}
+
+/* sub dn, dm */
+void OP_A0 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+ State.regs[REG_D0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub dm, an */
+void OP_F210 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_A0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+ State.regs[REG_A0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub an, dm */
+void OP_F2D0 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+ State.regs[REG_D0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub an, am */
+void OP_F250 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_A0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+ State.regs[REG_A0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub imm16, dn */
+void OP_F71C0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_16 (insn)]);
+ imm = TRUNC (SEXT16 (insn & 0xffff));
+ value = TRUNC (reg1 - imm);
+ State.regs[REG_D0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub imm24, dn */
+void OP_F4680000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_16 (insn)]);
+ imm = TRUNC (((insn & 0xffff) << 8) + extension);
+ value = TRUNC (reg1 - imm);
+ State.regs[REG_D0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub imm16, an */
+void OP_F70C0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_16 (insn)]);
+ imm = TRUNC (SEXT16 (insn & 0xffff));
+ value = TRUNC (reg1 - imm);
+ State.regs[REG_A0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* sub imm24, an */
+void OP_F46C0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_16 (insn)]);
+ imm = TRUNC (((insn & 0xffff) << 8) + extension);
+ value = TRUNC (reg1 - imm);
+ State.regs[REG_A0 + REG0_16 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* subc dm, dn */
+void OP_F290 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1 - ((PSW & PSW_CF) != 0));
+ State.regs[REG_D0 + REG0 (insn)] = value;
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* mul dn, dm */
+void OP_F340 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int n, z;
+
+ temp = (SEXT16 (State.regs[REG_D0 + REG0 (insn)] & 0xffff)
+ * SEXT16 ((State.regs[REG_D0 + REG1 (insn)] & 0xffff)));
+ State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffff;
+ State.regs[REG_MDR] = temp >> 16;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* mulu dn, dm */
+void OP_F350 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int n, z;
+
+ temp = ((State.regs[REG_D0 + REG0 (insn)] & 0xffff)
+ * (State.regs[REG_D0 + REG1 (insn)] & 0xffff));
+ State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffff;
+ State.regs[REG_MDR] = temp >> 16;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+
+/* divu dm, dn */
+void OP_F360 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int n, z;
+
+ temp = State.regs[REG_MDR];
+ temp &= 0xffff;
+ temp <<= 16;
+ temp |= (State.regs[REG_D0 + REG0 (insn)] & 0xffff);
+ State.regs[REG_MDR] = (temp
+ % (unsigned long)(State.regs[REG_D0 + REG1 (insn)] & 0xffff));
+ temp /= (unsigned long)(State.regs[REG_D0 + REG1 (insn)] & 0xffff);
+ State.regs[REG_D0 + REG0 (insn)] = temp & 0xffff;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* cmp imm8, dn */
+void OP_D800 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_8 (insn)]);
+ imm = TRUNC (SEXT8 (insn & 0xff));
+ value = TRUNC (reg1 - imm);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+}
+
+/* cmp dn, dm */
+void OP_F390 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp dm, an */
+void OP_F220 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_A0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp an, dm */
+void OP_F2E0 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_D0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp an, am */
+void OP_F260 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, reg2, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG1 (insn)]);
+ reg2 = TRUNC (State.regs[REG_A0 + REG0 (insn)]);
+ value = TRUNC (reg2 - reg1);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) > (reg2 & 0xffff));
+ cx = (reg1 > reg2);
+ v = ((reg2 & 0x8000) != (reg1 & 0x8000)
+ && (reg2 & 0x8000) != (value & 0x8000));
+ vx = ((reg2 & 0x800000) != (reg1 & 0x800000)
+ && (reg2 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp imm16, dn */
+void OP_F7480000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_16 (insn)]);
+ imm = TRUNC (SEXT16 (insn & 0xffff));
+ value = TRUNC (reg1 - imm);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp imm24, dn */
+void OP_F4780000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_D0 + REG0_16 (insn)]);
+ imm = TRUNC (((insn & 0xffff) << 8) + extension);
+ value = TRUNC (reg1 - imm);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp imm16, an */
+void OP_EC0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_16 (insn)]);
+ imm = TRUNC (insn & 0xffff);
+ value = TRUNC (reg1 - imm);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* cmp imm24, an */
+void OP_F47C0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, c, n, v, zx, cx, nx, vx;
+ unsigned long reg1, imm, value;
+
+ reg1 = TRUNC (State.regs[REG_A0 + REG0_16 (insn)]);
+ imm = TRUNC (((insn & 0xffff) << 8) + extension);
+ value = TRUNC (reg1 - imm);
+
+ z = ((value & 0xffff) == 0);
+ zx = (value == 0);
+ n = (value & 0x8000);
+ nx = (value & 0x800000);
+ c = ((reg1 & 0xffff) < (imm & 0xffff));
+ cx = (reg1 < imm);
+ v = ((reg1 & 0x8000) != (imm & 0x8000)
+ && (reg1 & 0x8000) != (value & 0x8000));
+ vx = ((reg1 & 0x800000) != (imm & 0x800000)
+ && (reg1 & 0x800000) != (value & 0x800000));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF
+ | PSW_ZX | PSW_NX | PSW_CX | PSW_VX);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0)
+ | (zx ? PSW_ZX : 0) | (nx ? PSW_NX : 0)
+ | (cx ? PSW_CX : 0) | (vx ? PSW_VX : 0));
+
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | ( n ? PSW_NF : 0)
+ | (c ? PSW_CF : 0) | (v ? PSW_VF : 0));
+}
+
+/* and dn, dm */
+void OP_F300 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0 (insn)] & State.regs[REG_D0 + REG1 (insn)];
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* and imm8, dn */
+void OP_F50000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0_8 (insn)] & (insn & 0xff);
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0_8 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0_8 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0_8 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* and imm16, dn */
+void OP_F7000000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0_16 (insn)] & (insn & 0xffff);
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0_16 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0_16 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0_16 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* and imm16, psw */
+void OP_F7100000 (insn, extension)
+ unsigned long insn, extension;
+{
+ PSW &= (insn & 0xffff);
+}
+
+/* or dn, dm */
+void OP_F310 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0 (insn)] | State.regs[REG_D0 + REG1 (insn)];
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* or imm8, dn */
+void OP_F50800 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0_8 (insn)] | (insn & 0xff);
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0_8 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0_8 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0_8 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* or imm16, dn */
+void OP_F7400000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0_16 (insn)] | (insn & 0xffff);
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0_16 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0_16 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0_16 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* or imm16, psw */
+void OP_F7140000 (insn, extension)
+ unsigned long insn, extension;
+{
+ PSW |= (insn & 0xffff);
+}
+
+/* xor dn, dm */
+void OP_F320 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0 (insn)] ^ State.regs[REG_D0 + REG1 (insn)];
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* xor imm16, dn */
+void OP_F74C0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = State.regs[REG_D0 + REG0_16 (insn)] ^ (insn & 0xffff);
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0_16 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0_16 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0_16 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* not dn */
+void OP_F3E4 (insn, extension)
+ unsigned long insn, extension;
+{
+ int n, z;
+ unsigned long temp;
+
+ temp = ~State.regs[REG_D0 + REG0 (insn)];
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0));
+}
+
+/* asr dn */
+void OP_F338 (insn, extension)
+ unsigned long insn, extension;
+{
+ long temp;
+ int z, n, c, high;
+
+ temp = State.regs[REG_D0 + REG0 (insn)] & 0xffff;
+ c = temp & 1;
+ high = temp & 0x8000;
+ temp >>= 1;
+ temp |= high;
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0) | (c ? PSW_CF : 0));
+}
+
+/* lsr dn */
+void OP_F33C (insn, extension)
+ unsigned long insn, extension;
+{
+ int z, n, c;
+ long temp;
+
+ temp = State.regs[REG_D0 + REG0 (insn)] & 0xffff;
+ c = temp & 1;
+ temp >>= 1;
+ temp &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= temp;
+ z = (State.regs[REG_D0 + REG0 (insn)] & 0xffff) == 0;
+ n = (State.regs[REG_D0 + REG0 (insn)] & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0) | (c ? PSW_CF : 0));
+}
+
+/* ror dn */
+void OP_F334 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long value;
+ int c,n,z;
+
+ value = State.regs[REG_D0 + REG0 (insn)] & 0xffff;
+ c = (value & 0x1);
+
+ value >>= 1;
+ value |= (PSW & PSW_CF ? 0x8000 : 0);
+ value &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= value;
+ z = (value == 0);
+ n = (value & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0) | (c ? PSW_CF : 0));
+}
+
+/* rol dn */
+void OP_F330 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long value;
+ int c,n,z;
+
+ value = State.regs[REG_D0 + REG0 (insn)] & 0xffff;
+ c = (value & 0x8000) ? 1 : 0;
+
+ value <<= 1;
+ value |= (PSW & PSW_CF ? 0x1 : 0);
+ value &= 0xffff;
+ State.regs[REG_D0 + REG0 (insn)] &= ~0xffff;
+ State.regs[REG_D0 + REG0 (insn)] |= value;
+ z = (value == 0);
+ n = (value & 0x8000) != 0;
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= ((z ? PSW_ZF : 0) | (n ? PSW_NF : 0) | (c ? PSW_CF : 0));
+}
+
+/* btst imm8, dn */
+void OP_F50400 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int z;
+
+ temp = State.regs[REG_D0 + REG0_8 (insn)];
+ temp &= (insn & 0xff);
+ z = (temp == 0);
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= (z ? PSW_ZF : 0);
+}
+
+/* btst imm16, dn */
+void OP_F7040000 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int z, n, c;
+
+ temp = State.regs[REG_D0 + REG0_16 (insn)];
+ c = temp & 0x1;
+ temp &= (insn & 0xffff);
+ n = (temp & 0x8000) != 0;
+ z = (temp == 0);
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= (z ? PSW_ZF : 0) | (n ? PSW_NF : 0) | (c ? PSW_CF : 0);
+}
+
+/* bset dm, (an) */
+void OP_F020 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int z;
+
+ temp = load_byte (State.regs[REG_A0 + REG1 (insn)]);
+ z = (temp & State.regs[REG_D0 + REG0 (insn)]) == 0;
+ temp |= State.regs[REG_D0 + REG0 (insn)];
+ store_byte (State.regs[REG_A0 + REG1 (insn)], temp);
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= (z ? PSW_ZF : 0);
+}
+
+/* bclr dm, (an) */
+void OP_F030 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned long temp;
+ int z;
+
+ temp = load_byte (State.regs[REG_A0 + REG1 (insn)]);
+ z = (temp & State.regs[REG_D0 + REG0 (insn)]) == 0;
+ temp = temp & ~State.regs[REG_D0 + REG0 (insn)];
+ store_byte (State.regs[REG_A0 + REG1 (insn)], temp);
+ PSW &= ~(PSW_ZF | PSW_NF | PSW_CF | PSW_VF);
+ PSW |= (z ? PSW_ZF : 0);
+}
+
+/* beqx label:8 */
+void OP_F5E800 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_ZX)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bnex label:8 */
+void OP_F5E900 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_ZX))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bgtx label:8 */
+void OP_F5E100 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!((PSW & PSW_ZX)
+ || (((PSW & PSW_NX) != 0) ^ ((PSW & PSW_VX) != 0))))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bgex label:8 */
+void OP_F5E200 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_NX) != 0) ^ ((PSW & PSW_VX) != 0)))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* blex label:8 */
+void OP_F5E300 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if ((PSW & PSW_ZX)
+ || (((PSW & PSW_NX) != 0) ^ ((PSW & PSW_VX) != 0)))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bltx label:8 */
+void OP_F5E000 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_NX) != 0) ^ ((PSW & PSW_VX) != 0))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bhix label:8 */
+void OP_F5E500 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_CX) != 0) || (PSW & PSW_ZX) != 0))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bccx label:8 */
+void OP_F5E600 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_CX))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* blsx label:8 */
+void OP_F5E700 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_CX) != 0) || (PSW & PSW_ZX) != 0)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bcsx label:8 */
+void OP_F5E400 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_CX)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bvcx label:8 */
+void OP_F5EC00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_VX))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bvsx label:8 */
+void OP_F5ED00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_VX)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bncx label:8 */
+void OP_F5EE00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_NX))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bnsx label:8 */
+void OP_F5EF00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_NX)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* beq label:8 */
+void OP_E800 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_ZF)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bne label:8 */
+void OP_E900 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_ZF))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bgt label:8 */
+void OP_E100 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!((PSW & PSW_ZF)
+ || (((PSW & PSW_NF) != 0) ^ ((PSW & PSW_VF) != 0))))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bge label:8 */
+void OP_E200 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_NF) != 0) ^ ((PSW & PSW_VF) != 0)))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* ble label:8 */
+void OP_E300 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if ((PSW & PSW_ZF)
+ || (((PSW & PSW_NF) != 0) ^ ((PSW & PSW_VF) != 0)))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* blt label:8 */
+void OP_E000 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_NF) != 0) ^ ((PSW & PSW_VF) != 0))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bhi label:8 */
+void OP_E500 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(((PSW & PSW_CF) != 0) || (PSW & PSW_ZF) != 0))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bcc label:8 */
+void OP_E600 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_CF))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bls label:8 */
+void OP_E700 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (((PSW & PSW_CF) != 0) || (PSW & PSW_ZF) != 0)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bcs label:8 */
+void OP_E400 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_CF)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bvc label:8 */
+void OP_F5FC00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_VF))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bvs label:8 */
+void OP_F5FD00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_VF)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bnc label:8 */
+void OP_F5FE00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (!(PSW & PSW_NF))
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bns label:8 */
+void OP_F5FF00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 3 after we return, so
+ we subtract two here to make things right. */
+ if (PSW & PSW_NF)
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* bra label:8 */
+void OP_EA00 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* The dispatching code will add 2 after we return, so
+ we subtract two here to make things right. */
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT8 (insn & 0xff));
+}
+
+/* jmp (an) */
+void OP_F000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_PC] = TRUNC (State.regs[REG_A0 + REG1 (insn)] - 2);
+}
+
+/* jmp label:16 */
+void OP_FC0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT16 (insn & 0xffff));
+}
+
+/* jmp label:24 */
+void OP_F4E00000 (insn, extension)
+ unsigned long insn, extension;
+{
+ State.regs[REG_PC]
+ = TRUNC (State.regs[REG_PC] + (((insn & 0xffff) << 8) + extension));
+}
+
+/* jsr (an) */
+void OP_F001 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned int next_pc, sp;
+
+ sp = State.regs[REG_SP];
+ sp -= 4;
+ State.regs[REG_SP] = sp;
+ next_pc = State.regs[REG_PC] + 2;
+ State.mem[sp] = next_pc & 0xff;
+ State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+ State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+ State.regs[REG_PC] = TRUNC (State.regs[REG_A0 + REG1 (insn)] - 2);
+}
+
+/* jsr label:16 */
+void OP_FD0000 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned int next_pc, sp;
+
+ sp = State.regs[REG_SP];
+ sp -= 4;
+ State.regs[REG_SP] = sp;
+ next_pc = State.regs[REG_PC] + 3;
+ State.mem[sp] = next_pc & 0xff;
+ State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+ State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+ State.regs[REG_PC] = TRUNC (State.regs[REG_PC] + SEXT16 (insn & 0xffff));
+}
+
+/* jsr label:24 */
+void OP_F4E10000 (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned int next_pc, sp;
+
+ sp = State.regs[REG_SP];
+ sp -= 4;
+ State.regs[REG_SP] = sp;
+ next_pc = State.regs[REG_PC] + 5;
+ State.mem[sp] = next_pc & 0xff;
+ State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+ State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+ State.regs[REG_PC]
+ = TRUNC (State.regs[REG_PC] + (((insn & 0xffff) << 8) + extension));
+}
+
+/* rts */
+void OP_FE (insn, extension)
+ unsigned long insn, extension;
+{
+ unsigned int sp;
+
+ sp = State.regs[REG_SP];
+ State.regs[REG_PC] = (State.mem[sp] | (State.mem[sp+1] << 8)
+ | (State.mem[sp+2] << 16));
+ State.regs[REG_PC] -= 1;
+ State.regs[REG_SP] += 4;
+}
+
+/* rti */
+void OP_EB (insn, extension)
+ unsigned long insn, extension;
+{
+ PSW = load_half (State.regs[REG_A0 + 3]);
+ State.regs[REG_PC] = load_3_byte (State.regs[REG_A0 + 3] + 2) - 1;
+ State.regs[REG_A0 + 3] += 6;
+}
+
+/* syscall */
+void OP_F010 (insn, extension)
+ unsigned long insn, extension;
+{
+ /* We use this for simulated system calls; we may need to change
+ it to a reserved instruction if we conflict with uses at
+ Matsushita. */
+ int save_errno = errno;
+ int offset = 6;
+ errno = 0;
+
+/* Registers passed to syscall 0 */
+
+/* Function number. */
+#define FUNC (State.regs[0])
+
+#define PARM1 (State.regs[1])
+
+/* Parameters. */
+#define PARM(x, y) (load_mem (State.regs[REG_SP] + x, y))
+
+/* Registers set by syscall 0 */
+
+#define RETVAL State.regs[0] /* return value */
+#define RETERR State.regs[1] /* return error code */
+
+/* Turn a pointer in a register into a pointer into real memory. */
+
+#define MEMPTR(x) (State.mem + (x & 0xffffff))
+
+ switch (FUNC)
+ {
+#if !defined(__GO32__) && !defined(_WIN32)
+#ifdef TARGET_SYS_fork
+ case TARGET_SYS_fork:
+ RETVAL = fork ();
+ break;
+#endif
+#ifdef TARGET_SYS_execve
+ case TARGET_SYS_execve:
+ RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM (4, 4)),
+ (char **)MEMPTR (PARM (8, 4)));
+ break;
+#endif
+#ifdef TARGET_SYS_execv
+ case TARGET_SYS_execv:
+ RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM (4, 4)), NULL);
+ break;
+#endif
+#endif
+
+ case TARGET_SYS_read:
+ RETVAL = mn10200_callback->read (mn10200_callback, PARM1,
+ MEMPTR (PARM (4, 4)), PARM (8, 4));
+ break;
+ case TARGET_SYS_write:
+ RETVAL = (int)mn10200_callback->write (mn10200_callback, PARM1,
+ MEMPTR (PARM (4, 4)),
+ PARM (8, 4));
+ break;
+ case TARGET_SYS_lseek:
+ RETVAL = mn10200_callback->lseek (mn10200_callback, PARM1,
+ PARM (4, 4), PARM (8, 2));
+ break;
+ case TARGET_SYS_close:
+ RETVAL = mn10200_callback->close (mn10200_callback, PARM1);
+ break;
+ case TARGET_SYS_open:
+ RETVAL = mn10200_callback->open (mn10200_callback, MEMPTR (PARM1),
+ PARM (4, 2));
+ break;
+ case TARGET_SYS_exit:
+ /* EXIT - caller can look in PARM1 to work out the
+ reason */
+ if (PARM1 == 0xdead)
+ State.exception = SIGABRT;
+ else
+ State.exception = SIGQUIT;
+ State.exited = 1;
+ break;
+
+ case TARGET_SYS_stat: /* added at hmsi */
+ /* stat system call */
+ {
+ struct stat host_stat;
+ reg_t buf;
+
+ RETVAL = stat (MEMPTR (PARM1), &host_stat);
+
+ buf = PARM (4, 4);
+
+ /* Just wild-assed guesses. */
+ store_half (buf, host_stat.st_dev);
+ store_half (buf + 2, host_stat.st_ino);
+ store_word (buf + 4, host_stat.st_mode);
+ store_half (buf + 8, host_stat.st_nlink);
+ store_half (buf + 10, host_stat.st_uid);
+ store_half (buf + 12, host_stat.st_gid);
+ store_half (buf + 14, host_stat.st_rdev);
+ store_word (buf + 16, host_stat.st_size);
+ store_word (buf + 20, host_stat.st_atime);
+ store_word (buf + 28, host_stat.st_mtime);
+ store_word (buf + 36, host_stat.st_ctime);
+ }
+ break;
+
+#ifdef TARGET_SYS_chown
+ case TARGET_SYS_chown:
+ RETVAL = chown (MEMPTR (PARM1), PARM (4, 2), PARM (6, 2));
+ break;
+#endif
+ case TARGET_SYS_chmod:
+ RETVAL = chmod (MEMPTR (PARM1), PARM (4, 2));
+ break;
+#ifdef TARGET_SYS_time
+ case TARGET_SYS_time:
+ RETVAL = time ((time_t *)MEMPTR (PARM1));
+ break;
+#endif
+#ifdef TARGET_SYS_times
+ case TARGET_SYS_times:
+ {
+ struct tms tms;
+ RETVAL = times (&tms);
+ store_word (PARM1, tms.tms_utime);
+ store_word (PARM1 + 4, tms.tms_stime);
+ store_word (PARM1 + 8, tms.tms_cutime);
+ store_word (PARM1 + 12, tms.tms_cstime);
+ break;
+ }
+#endif
+#ifdef TARGET_SYS_gettimeofday
+ case TARGET_SYS_gettimeofday:
+ {
+ struct timeval t;
+ struct timezone tz;
+ RETVAL = gettimeofday (&t, &tz);
+ store_word (PARM1, t.tv_sec);
+ store_word (PARM1 + 4, t.tv_usec);
+ store_word (PARM (4, 4), tz.tz_minuteswest);
+ store_word (PARM (4, 4) + 4, tz.tz_dsttime);
+ break;
+ }
+#endif
+#ifdef TARGET_SYS_utime
+ case TARGET_SYS_utime:
+ /* Cast the second argument to void *, to avoid type mismatch
+ if a prototype is present. */
+ RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM (4, 4)));
+ break;
+#endif
+ default:
+ abort ();
+ }
+ RETERR = errno;
+ errno = save_errno;
+}
+
+/* nop */
+void OP_F6 (insn, extension)
+ unsigned long insn, extension;
+{
+}
+
+/* breakpoint */
+void
+OP_FF (insn, extension)
+ unsigned long insn, extension;
+{
+ State.exception = SIGTRAP;
+ PC -= 1;
+}