summaryrefslogtreecommitdiff
path: root/sim/ucsim/pdk.src/inst.cc
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/pdk.src/inst.cc
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/pdk.src/inst.cc')
-rw-r--r--sim/ucsim/pdk.src/inst.cc1157
1 files changed, 1157 insertions, 0 deletions
diff --git a/sim/ucsim/pdk.src/inst.cc b/sim/ucsim/pdk.src/inst.cc
new file mode 100644
index 0000000..522b6b5
--- /dev/null
+++ b/sim/ucsim/pdk.src/inst.cc
@@ -0,0 +1,1157 @@
+/*
+ * Simulator of microcontrollers (inst.cc)
+ */
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+UCSIM is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#include <stdlib.h>
+#include <cassert>
+#include "ddconfig.h"
+#include "stdio.h"
+
+// local
+#include "pdkcl.h"
+#include "regspdk.h"
+
+#define CODE_MASK(op, m) ((code & ~(m)) == (op))
+
+unsigned char cl_pdk::add_to(unsigned char initial, int value, bool carry) {
+ store_flag(flag_z, initial + value + carry == 0);
+ store_flag(flag_c, initial + value + carry > 0xFF);
+ store_flag(flag_ac, (initial & 0xF) + (value & 0xF) + carry > 0xF);
+ store_flag(
+ flag_ov,
+ get_flag(flag_c) ^ ((initial & 0x7F) + (value & 0x7F) + carry > 0x7F));
+
+ return initial + value + carry;
+}
+
+unsigned char cl_pdk::sub_to(unsigned char initial, int value, bool carry) {
+ store_flag(flag_z, initial - value - carry == 0);
+ store_flag(flag_c, initial < value + carry);
+ store_flag(flag_ac, (value & 0xF) > (initial & 0xF) - carry);
+ store_flag(
+ flag_ov,
+ get_flag(flag_c) ^ ((initial & 0x7F) - (value & 0x7F) - carry < 0));
+
+ return initial - value - carry;
+}
+
+int cl_pdk::get_mem(unsigned int addr) {
+ vc.rd++;
+ return ram->read((t_addr)(addr));
+}
+
+unsigned char cl_pdk::get_io(t_addr addr) {
+ return regs8->get(addr);
+}
+
+void cl_pdk::store_io(t_addr addr, unsigned char value) {
+ regs8->set(addr, value);
+ if (get_SP() > sp_max)
+ sp_max = get_SP();
+}
+
+unsigned char cl_pdk::get_SP() {
+ return get_io(0x02);
+}
+
+unsigned char cl_pdk::get_flags() {
+ return get_io(0x00);
+}
+
+void cl_pdk::set_flags(unsigned char flags) {
+ return store_io(0x00, flags);
+}
+
+int cl_pdk::get_flag(flag n) {
+ switch (n) {
+ case flag_z: return get_flags() & BIT_Z;
+ case flag_c: return (get_flags() & BIT_C) >> 1;
+ case flag_ac: return (get_flags() & BIT_AC) >> 2;
+ case flag_ov: return (get_flags() & BIT_OV) >> 3;
+ default:
+ assert(!"invalid bit access to FLAG");
+ }
+ return 0;
+}
+
+void cl_pdk::store_flag(flag n, int value) {
+ switch (n) {
+ case flag_z: set_flags((get_flags() & ~1) | value); break;
+ case flag_c: set_flags((get_flags() & ~2) | (value << 1)); break;
+ case flag_ac: set_flags((get_flags() & ~4) | (value << 2)); break;
+ case flag_ov: set_flags((get_flags() & ~8) | (value << 3)); break;
+ default:
+ assert(!"invalid bit store to FLAG");
+ }
+}
+
+int cl_pdk::execute(unsigned int code) {
+ switch (type->type) {
+ case CPU_PDK13:
+ return(execute_pdk13(code));
+ case CPU_PDK14:
+ return(execute_pdk14(code));
+ case CPU_PDK15:
+ return(execute_pdk15(code));
+ default:
+ __builtin_unreachable();
+ }
+}
+
+int cl_pdk::execute_pdk14(unsigned int code) {
+ if (code == 0x0000) {
+ // nop
+ } else if (CODE_MASK(0x0200, 0xFF)) {
+ // ret k
+ regs.a = code & 0xFF;
+ store_io(0x2, get_SP() - 2);
+ PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8);
+ } else if (code == 0x007A) {
+ // ret
+ store_io(0x2, get_SP() - 2);
+ PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8);
+ } else if (CODE_MASK(0x2F00, 0xFF)) {
+ // mov a, k
+ regs.a = code & 0xFF;
+ } else if (CODE_MASK(0x0180, 0x3F)) {
+ // mov i, a
+ store_io(code & 0x3F, regs.a);
+ } else if (CODE_MASK(0x01C0, 0x3F)) {
+ // mov a, i
+ regs.a = get_io(code & 0x3F);
+ } else if (CODE_MASK(0x0B80, 0x7F)) {
+ // mov m, a
+ ram->write(code & 0x7F, regs.a);
+ } else if (CODE_MASK(0x0F80, 0x7F)) {
+ // mov a, m
+ regs.a = get_mem(code & 0x7F);
+ } else if (CODE_MASK(0x0301, 0x7E)) {
+ // TODO: ldt16
+ } else if (CODE_MASK(0x0300, 0x7E)) {
+ // TODO: stt16
+ } else if ((CODE_MASK(0x381, 0x7E))) {
+ // idxm a, m
+ regs.a = get_mem(get_mem(code & 0x7E));
+ } else if ((CODE_MASK(0x380, 0x7E))) {
+ // idxm m, a
+ ram->write(get_mem(code & 0x7E), regs.a);
+ } else if (CODE_MASK(0x1380, 0x7F)) {
+ // xch m
+ int mem = get_mem(code & 0x7F);
+ ram->write(code & 0x7F, regs.a);
+ regs.a = mem;
+ } else if (code == 0x0072) {
+ // pushaf
+ ram->write(get_SP(), regs.a);
+ ram->write(get_SP() + 1, get_flags());
+ store_io(0x2, get_SP() + 2);
+ } else if (code == 0x0073) {
+ // popaf
+ set_flags(get_mem(get_SP() - 1));
+ regs.a = get_mem(get_SP() - 2);
+ store_io(0x2, get_SP() - 2);
+ } else if (CODE_MASK(0x2800, 0xFF)) {
+ // add a, k
+ regs.a = add_to(regs.a, code & 0xFF);
+ } else if (CODE_MASK(0x0C00, 0x7F)) {
+ // add a, m
+ regs.a = add_to(regs.a, get_mem(code & 0x7F));
+ } else if (CODE_MASK(0x0800, 0x7F)) {
+ // add m, a
+ int addr = code & 0x7F;
+ ram->write(addr, add_to(regs.a, get_mem(addr)));
+ } else if (CODE_MASK(0x2900, 0xFF)) {
+ // sub a, k
+ regs.a = sub_to(regs.a, code & 0xFF);
+ } else if (CODE_MASK(0x0C80, 0x7F)) {
+ // sub a, m
+ regs.a = sub_to(regs.a, get_mem(code & 0x7F));
+ } else if (CODE_MASK(0x0880, 0x7F)) {
+ // sub m, a
+ int addr = code & 0x7F;
+ ram->write(addr, sub_to(get_mem(addr), regs.a));
+ } else if (CODE_MASK(0x0D00, 0x7F)) {
+ // addc a, m
+ regs.a = add_to(regs.a, get_mem(code & 0x7F), get_flag(flag_c));
+ } else if (CODE_MASK(0x0900, 0x7F)) {
+ // addc m, a
+ int addr = code & 0x7F;
+ ram->write(addr, add_to(regs.a, get_mem(addr), get_flag(flag_c)));
+ } else if (code == 0x0060) {
+ // addc a
+ regs.a = add_to(regs.a, get_flag(flag_c));
+ } else if (CODE_MASK(0x1000, 0x7F)) {
+ // addc m
+ int addr = code & 0x7F;
+ ram->write(addr, add_to(get_mem(addr), get_flag(flag_c)));
+ } else if (CODE_MASK(0x0D80, 0x7F)) {
+ // subc a, m
+ regs.a = sub_to(regs.a, get_mem(code & 0x7F), get_flag(flag_c));
+ } else if (CODE_MASK(0x0980, 0x7F)) {
+ // subc m, a
+ int addr = code & 0x7F;
+ ram->write(addr, sub_to(get_mem(addr), regs.a, get_flag(flag_c)));
+ } else if (code == 0x0061) {
+ // subc a
+ regs.a = sub_to(regs.a, get_flag(flag_c));
+ } else if (CODE_MASK(0x1080, 0x7F)) {
+ // subc m
+ int addr = code & 0x7F;
+ ram->write(addr, sub_to(get_mem(addr), get_flag(flag_c)));
+ } else if (CODE_MASK(0x1200, 0x7F)) {
+ // inc m
+ int addr = code & 0x7F;
+ ram->write(addr, add_to(get_mem(addr), 1));
+ } else if (CODE_MASK(0x1280, 0x7F)) {
+ // dec m
+ int addr = code & 0x7F;
+ ram->write(addr, sub_to(get_mem(addr), 1));
+ } else if (CODE_MASK(0x1300, 0x7F)) {
+ // clear m
+ ram->write(code & 0x7F, 0);
+ } else if (code == 0x006A) {
+ // sr a
+ store_flag(flag_c, regs.a & 1);
+ regs.a >>= 1;
+ } else if (CODE_MASK(0x1500, 0x7F)) {
+ // sr m
+ int value = get_mem(code & 0x7F);
+ store_flag(flag_c, value & 1);
+ ram->write(code & 0x7F, value >> 1);
+ } else if (code == 0x006B) {
+ // sl a
+ store_flag(flag_c, (regs.a & 0x80) >> 7);
+ regs.a <<= 1;
+ } else if (CODE_MASK(0x1580, 0x7F)) {
+ // sl m
+ int value = get_mem(code & 0x7F);
+ store_flag(flag_c, (value & 0x80) >> 7);
+ ram->write(code & 0x7F, value << 1);
+ } else if (code == 0x006C) {
+ // src a
+ int c = regs.a & 1;
+ regs.a >>= 1;
+ regs.a |= get_flag(flag_c) << 7;
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x1600, 0x7F)) {
+ // src m
+ int value = get_mem(code & 0x7F);
+ int c = value & 1;
+ ram->write(code & 0x7F, (value >> 1) | (get_flag(flag_c) << 7));
+ store_flag(flag_c, c);
+ } else if (code == 0x006D) {
+ // slc a
+ int c = (regs.a & 0x80) >> 7;
+ regs.a <<= 1;
+ regs.a |= get_flag(flag_c);
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x1680, 0x7F)) {
+ // slc m
+ int value = get_mem(code & 0x7F);
+ int c = (value & 0x80) >> 7;
+ ram->write(code & 0x7F, (value << 1) | get_flag(flag_c));
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x2C00, 0xFF)) {
+ // and a, k
+ regs.a &= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0E00, 0x7F)) {
+ // and a, m
+ regs.a &= get_mem(code & 0x7F);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0A00, 0x7F)) {
+ // and m, a
+ int store = regs.a & get_mem(code & 0x7F);
+ store_flag(flag_z, !store);
+ ram->write(code & 0x7F, store);
+ } else if (CODE_MASK(0x2D00, 0xFF)) {
+ // or a, k
+ regs.a |= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0E80, 0x7F)) {
+ // or a, m
+ regs.a |= get_mem(code & 0x7F);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0A80, 0x7F)) {
+ // or m, a
+ int store = regs.a | get_mem(code & 0x7F);
+ store_flag(flag_z, !store);
+ ram->write(code & 0x7F, store);
+ } else if (CODE_MASK(0x2E00, 0xFF)) {
+ // xor a, k
+ regs.a ^= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0F00, 0x7F)) {
+ // xor a, m
+ regs.a ^= get_mem(code & 0x7F);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0B00, 0x7F)) {
+ // xor m, a
+ int store = regs.a ^ get_mem(code & 0x7F);
+ store_flag(flag_z, !store);
+ ram->write(code & 0x7F, store);
+ } else if (CODE_MASK(0x00C0, 0x3F)) {
+ // xor io, a
+ store_io(code & 0x3F, regs.a ^ get_io(code & 0x3F));
+ } else if (code == 0x0068) {
+ // not a
+ regs.a = ~regs.a;
+ } else if (CODE_MASK(0x1400, 0x7F)) {
+ // not m
+ ram->write(code & 0x7F, ~get_mem(code & 0x7F));
+ } else if (code == 0x0069) {
+ // neg a
+ regs.a = -regs.a;
+ } else if (CODE_MASK(0x1480, 0x7F)) {
+ // neg m
+ ram->write(code & 0x7F, -get_mem(code & 0x7F));
+ } else if (CODE_MASK(0x1C00, 0x1FF)) {
+ // set0 io, k
+ const u8_t bit = (code & 0x1C0) >> 6;
+ const u8_t addr = code & 0x3F;
+ store_io(addr, get_io(addr) & ~(1 << bit));
+ } else if (CODE_MASK(0x2400, 0x1FF)) {
+ // set0 m, k
+ const u8_t bit = (code & 0x1C0) >> 6;
+ const u8_t addr = code & 0x3F;
+ ram->write(addr, get_mem(addr) & ~(1 << bit));
+ } else if (CODE_MASK(0x1E00, 0x1FF)) {
+ // set1 io, k
+ const u8_t bit = (code & 0x1C0) >> 6;
+ const u8_t addr = code & 0x3F;
+ store_io(addr, get_io(addr) | (1 << bit));
+ } else if (CODE_MASK(0x2600, 0x1FF)) {
+ // set1 m, k
+ const u8_t bit = (code & 0x1C0) >> 6;
+ const u8_t addr = code & 0x3F;
+ ram->write(addr, get_mem(addr) | (1 << bit));
+ } else if (CODE_MASK(0x1800, 0x1FF)) {
+ // t0sn io, k
+ int n = (code & 0x1C0) >> 6;
+ if (!(get_io(code & 0x3F) & (1 << n)))
+ ++PC;
+ } else if (CODE_MASK(0x2000, 0x1FF)) {
+ // t0sn m, k
+ int n = (code & 0x1C0) >> 6;
+ if (!(get_mem(code & 0x3F) & (1 << n)))
+ ++PC;
+ } else if (CODE_MASK(0x1A00, 0x1FF)) {
+ // t1sn io, k
+ int n = (code & 0x1C0) >> 6;
+ if (get_io(code & 0x3F) & (1 << n))
+ ++PC;
+ } else if (CODE_MASK(0x2200, 0x1FF)) {
+ // t1sn m, k
+ int n = (code & 0x1C0) >> 6;
+ if (get_mem(code & 0x3F) & (1 << n))
+ ++PC;
+ } else if (CODE_MASK(0x2A00, 0xFF)) {
+ // ceqsn a, k
+ sub_to(regs.a, code & 0xFF);
+ if (regs.a == (code & 0xFF))
+ ++PC;
+ } else if (CODE_MASK(0x1700, 0x7F)) {
+ // ceqsn a, m
+ int addr = code & 0x7F;
+ sub_to(regs.a, get_mem(addr));
+ if (regs.a == get_mem(addr))
+ ++PC;
+ } else if (CODE_MASK(0x2B00, 0xFF)) {
+ // cneqsn a, k
+ sub_to(regs.a, code & 0xFF);
+ if (regs.a != (code & 0xFF))
+ ++PC;
+ } else if (CODE_MASK(0x1780, 0x7F)) {
+ // cneqsn a, m
+ int addr = code & 0x7F;
+ sub_to(regs.a, get_mem(addr));
+ if (regs.a != get_mem(addr))
+ ++PC;
+ } else if (code == 0x0062) {
+ // izsn
+ regs.a = add_to(regs.a, 1);
+ if (!regs.a)
+ ++PC;
+ } else if (CODE_MASK(0x1100, 0x7F)) {
+ // izsn m
+ const int addr = code & 0x7F;
+ int result = add_to(get_mem(addr), 1);
+ ram->write(addr, result);
+ if (!result)
+ ++PC;
+ } else if (code == 0x0063) {
+ // dzsn
+ regs.a = sub_to(regs.a, 1);
+ if (!regs.a)
+ ++PC;
+ } else if (CODE_MASK(0x1180, 0x7F)) {
+ // dzsn m
+ const int addr = code & 0x7F;
+ int result = sub_to(get_mem(addr), 1);
+ ram->write(addr, result);
+ if (!result)
+ ++PC;
+ } else if (CODE_MASK(0x3800, 0x7FF)) {
+ // call k
+ ram->write(get_SP(), PC);
+ ram->write(get_SP() + 1, PC >> 8);
+ PC = code & 0x7FF;
+ store_io(0x2, get_SP() + 2);
+ } else if (CODE_MASK(0x3000, 0x7FF)) {
+ // goto k
+ PC = code & 0x7FF;
+ } else if (CODE_MASK(0x0600, 0x7F)) {
+ // comp a, m
+ sub_to(regs.a, get_mem(code & 0x7F));
+ } else if (CODE_MASK(0x0680, 0x7F)) {
+ // comp m, a
+ sub_to(get_mem(code & 0x7F), regs.a);
+ } else if (CODE_MASK(0x0700, 0x7F)) {
+ // nadd a, m
+ regs.a = add_to(get_mem(code & 0x7F), -regs.a);
+ } else if (CODE_MASK(0x0780, 0x7F)) {
+ // nadd m, a
+ int addr = code & 0x7F;
+ ram->write(addr, add_to(-get_mem(addr), regs.a));
+ } else if (code == 0x006E) {
+ // swap
+ int high = regs.a & 0xF;
+ regs.a = (high << 4) | (regs.a >> 4);
+ } else if (code == 0x0067) {
+ // pcadd
+ PC += regs.a - 1;
+ }
+ // TODO: engint
+ // TODO: disint
+ else if (code == 0x0076) {
+ // stopsys
+ return (resHALT);
+ }
+ // TODO: stopexe
+ // TODO: reset
+ // TODO: wdreset
+ // TODO: swapc IO, k
+ else if (code == 0x0006) {
+ // ldsptl
+ regs.a = rom->get(get_SP()) & 0xFF;
+ } else if (code == 0x0007) {
+ // ldspth
+ regs.a = (rom->get(get_SP()) & 0xFF00) >> 8;
+ } else if (code == 0x007C) {
+ // mul
+ unsigned result = regs.a * get_io(0x08);
+ regs.a = result & 0xFF;
+ store_io(0x08, (result & 0xFF00) >> 8);
+ } else if (code == 0xFF00) {
+ // putchar - usim specific instruction
+ putchar(regs.a);
+ fflush(stdout);
+ } else {
+ return (resINV_INST);
+ }
+ return (resGO);
+}
+
+int cl_pdk::execute_pdk13(unsigned int code) {
+ if (code == 0x0000) {
+ // nop
+ } else if (CODE_MASK(0x0100, 0xFF)) {
+ // ret k
+ regs.a = code & 0xFF;
+ store_io(0x2, get_SP() - 2);
+ PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8);
+ } else if (code == 0x003A) {
+ // ret
+ store_io(0x2, get_SP() - 2);
+ PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8);
+ } else if (CODE_MASK(0x1700, 0xFF)) {
+ // mov a, k
+ regs.a = code & 0xFF;
+ } else if (CODE_MASK(0x0080, 0x1F)) {
+ // mov i, a
+ store_io(code & 0x1F, regs.a);
+ } else if (CODE_MASK(0x00A0, 0x1F)) {
+ // mov a, i
+ regs.a = get_io(code & 0x1F);
+ } else if (CODE_MASK(0x05C0, 0x3F)) {
+ // mov m, a
+ ram->write(code & 0x3F, regs.a);
+ } else if (CODE_MASK(0x07C0, 0x3F)) {
+ // mov a, m
+ regs.a = get_mem(code & 0x3F);
+ } else if (CODE_MASK(0x00C1, 0x1E)) {
+ // TODO: ldt16
+ } else if (CODE_MASK(0x0C00, 0x1E)) {
+ // TODO: stt16
+ } else if ((CODE_MASK(0x0E1, 0x1E))) {
+ // idxm a, m
+ regs.a = get_mem(get_mem(code & 0x1E));
+ } else if ((CODE_MASK(0x0E0, 0x1E))) {
+ // idxm m, a
+ ram->write(get_mem(code & 0x1E), regs.a);
+ } else if (CODE_MASK(0x09C0, 0x3F)) {
+ // xch m
+ int mem = get_mem(code & 0x3F);
+ ram->write(code & 0x3F, regs.a);
+ regs.a = mem;
+ } else if (code == 0x0032) {
+ // pushaf
+ ram->write(get_SP(), regs.a);
+ ram->write(get_SP() + 1, get_flags());
+ store_io(0x2, get_SP() + 2);
+ } else if (code == 0x0033) {
+ // popaf
+ set_flags(get_mem(get_SP() - 1));
+ regs.a = get_mem(get_SP() - 2);
+ store_io(0x2, get_SP() - 2);
+ } else if (CODE_MASK(0x1000, 0xFF)) {
+ // add a, k
+ regs.a = add_to(regs.a, code & 0xFF);
+ } else if (CODE_MASK(0x0600, 0x3F)) {
+ // add a, m
+ regs.a = add_to(regs.a, get_mem(code & 0x3F));
+ } else if (CODE_MASK(0x0400, 0x3F)) {
+ // add m, a
+ int addr = code & 0x3F;
+ ram->write(addr, add_to(regs.a, get_mem(addr)));
+ } else if (CODE_MASK(0x1100, 0xFF)) {
+ // sub a, k
+ regs.a = sub_to(regs.a, code & 0xFF);
+ } else if (CODE_MASK(0x0640, 0x3F)) {
+ // sub a, m
+ regs.a = sub_to(regs.a, get_mem(code & 0x3F));
+ } else if (CODE_MASK(0x0440, 0x3F)) {
+ // sub m, a
+ int addr = code & 0x3F;
+ ram->write(addr, sub_to(get_mem(addr), regs.a));
+ } else if (CODE_MASK(0x0680, 0x3F)) {
+ // addc a, m
+ regs.a = add_to(regs.a, get_mem(code & 0x3F), get_flag(flag_c));
+ } else if (CODE_MASK(0x0480, 0x3F)) {
+ // addc m, a
+ int addr = code & 0x3F;
+ ram->write(addr, add_to(regs.a, get_mem(addr), get_flag(flag_c)));
+ } else if (code == 0x0010) {
+ // addc a
+ regs.a = add_to(regs.a, get_flag(flag_c));
+ } else if (CODE_MASK(0x0800, 0x3F)) {
+ // addc m
+ int addr = code & 0x3F;
+ ram->write(addr, add_to(get_mem(addr), get_flag(flag_c)));
+ } else if (CODE_MASK(0x06C0, 0x3F)) {
+ // subc a, m
+ regs.a = sub_to(regs.a, get_mem(code & 0x3F), get_flag(flag_c));
+ } else if (CODE_MASK(0x04C0, 0x3F)) {
+ // subc m, a
+ int addr = code & 0x3F;
+ ram->write(addr, sub_to(get_mem(addr), regs.a, get_flag(flag_c)));
+ } else if (code == 0x0011) {
+ // subc a
+ regs.a = sub_to(regs.a, get_flag(flag_c));
+ } else if (CODE_MASK(0x0840, 0x3F)) {
+ // subc m
+ int addr = code & 0x3F;
+ ram->write(addr, sub_to(get_mem(addr), get_flag(flag_c)));
+ } else if (CODE_MASK(0x0900, 0x3F)) {
+ // inc m
+ int addr = code & 0x3F;
+ ram->write(addr, add_to(get_mem(addr), 1));
+ } else if (CODE_MASK(0x0940, 0x3F)) {
+ // dec m
+ int addr = code & 0x3F;
+ ram->write(addr, sub_to(get_mem(addr), 1));
+ } else if (CODE_MASK(0x0980, 0x3F)) {
+ // clear m
+ ram->write(code & 0x3F, 0);
+ } else if (code == 0x001A) {
+ // sr a
+ store_flag(flag_c, regs.a & 1);
+ regs.a >>= 1;
+ } else if (CODE_MASK(0x0A80, 0x3F)) {
+ // sr m
+ int value = get_mem(code & 0x3F);
+ store_flag(flag_c, value & 1);
+ ram->write(code & 0x3F, value >> 1);
+ } else if (code == 0x001B) {
+ // sl a
+ store_flag(flag_c, (regs.a & 0x80) >> 7);
+ regs.a <<= 1;
+ } else if (CODE_MASK(0x0AC0, 0x3F)) {
+ // sl m
+ int value = get_mem(code & 0x3F);
+ store_flag(flag_c, (value & 0x80) >> 7);
+ ram->write(code & 0x3F, value << 1);
+ } else if (code == 0x001C) {
+ // src a
+ int c = regs.a & 1;
+ regs.a >>= 1;
+ regs.a |= get_flag(flag_c) << 7;
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x0B00, 0x3F)) {
+ // src m
+ int value = get_mem(code & 0x3F);
+ int c = value & 1;
+ ram->write(code & 0x3F, (value >> 1) | (get_flag(flag_c) << 7));
+ store_flag(flag_c, c);
+ } else if (code == 0x001D) {
+ // slc a
+ int c = (regs.a & 0x80) >> 7;
+ regs.a <<= 1;
+ regs.a |= get_flag(flag_c);
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x0B40, 0x3F)) {
+ // slc m
+ int value = get_mem(code & 0x3F);
+ int c = (value & 0x80) >> 7;
+ ram->write(code & 0x3F, (value << 1) | get_flag(flag_c));
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x1400, 0xFF)) {
+ // and a, k
+ regs.a &= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0700, 0x3F)) {
+ // and a, m
+ regs.a &= get_mem(code & 0x3F);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0500, 0x3F)) {
+ // and m, a
+ int store = regs.a & get_mem(code & 0x3F);
+ store_flag(flag_z, !store);
+ ram->write(code & 0x3F, store);
+ } else if (CODE_MASK(0x1500, 0xFF)) {
+ // or a, k
+ regs.a |= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0740, 0x3F)) {
+ // or a, m
+ regs.a |= get_mem(code & 0x3F);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0540, 0x3F)) {
+ // or m, a
+ int store = regs.a | get_mem(code & 0x3F);
+ store_flag(flag_z, !store);
+ ram->write(code & 0x3F, store);
+ } else if (CODE_MASK(0x1600, 0xFF)) {
+ // xor a, k
+ regs.a ^= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0780, 0x3F)) {
+ // xor a, m
+ regs.a ^= get_mem(code & 0x3F);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x0580, 0x3F)) {
+ // xor m, a
+ int store = regs.a ^ get_mem(code & 0x3F);
+ store_flag(flag_z, !store);
+ ram->write(code & 0x3F, store);
+ } else if (CODE_MASK(0x0060, 0x1F)) {
+ // xor io, a
+ store_io(code & 0x1F, regs.a ^ get_io(code & 0x1F));
+ } else if (code == 0x0018) {
+ // not a
+ regs.a = ~regs.a;
+ } else if (CODE_MASK(0x0A00, 0x3F)) {
+ // not m
+ ram->write(code & 0x3F, ~get_mem(code & 0x3F));
+ } else if (code == 0x0019) {
+ // neg a
+ regs.a = -regs.a;
+ } else if (CODE_MASK(0x0A40, 0x3F)) {
+ // neg m
+ ram->write(code & 0x3F, -get_mem(code & 0x3F));
+ } else if (CODE_MASK(0x0E00, 0xFF)) {
+ // set0 io, k
+ const u8_t bit = (code & 0xE0) >> 5;
+ const u8_t addr = code & 0x1F;
+ store_io(addr, get_io(addr) & ~(1 << bit));
+ } else if (CODE_MASK(0x0300, 0xFE)) {
+ // set0 m, k
+ const u8_t bit = (code & 0xE0) >> 5;
+ const u8_t addr = (code & 0xFE) >> 1;
+ ram->write(addr, get_mem(addr) & ~(1 << bit));
+ } else if (CODE_MASK(0x0F00, 0xFF)) {
+ // set1 io, k
+ const u8_t bit = (code & 0xE0) >> 5;
+ const u8_t addr = code & 0x1F;
+ store_io(addr, get_io(addr) | (1 << bit));
+ } else if (CODE_MASK(0x0301, 0xFE)) {
+ // set1 m, k
+ const u8_t bit = (code & 0xE0) >> 5;
+ const u8_t addr = (code & 0x1E) >> 1;
+ ram->write(addr, get_mem(addr) | (1 << bit));
+ } else if (CODE_MASK(0x0C00, 0xFF)) {
+ // t0sn io, k
+ int n = (code & 0xE0) >> 5;
+ if (!(get_io(code & 0x1F) & (1 << n)))
+ ++PC;
+ } else if (CODE_MASK(0x0200, 0xFE)) {
+ // t0sn m, k
+ int n = (code & 0xE0) >> 5;
+ if (!(get_mem((code & 0xFE) >> 1) & (1 << n)))
+ ++PC;
+ } else if (CODE_MASK(0x0D00, 0xFF)) {
+ // t1sn io, k
+ int n = (code & 0xE0) >> 5;
+ if (get_io(code & 0x1F) & (1 << n))
+ ++PC;
+ } else if (CODE_MASK(0x0201, 0xFE)) {
+ // t1sn m, k
+ int n = (code & 0xE0) >> 5;
+ if (get_mem((code & 0xFE) >> 1) & (1 << n))
+ ++PC;
+ } else if (CODE_MASK(0x1200, 0xFF)) {
+ // ceqsn a, k
+ sub_to(regs.a, code & 0xFF);
+ if (regs.a == (code & 0xFF))
+ ++PC;
+ } else if (CODE_MASK(0x0B80, 0x3F)) {
+ // ceqsn a, m
+ int addr = code & 0x3F;
+ sub_to(regs.a, get_mem(addr));
+ if (regs.a == get_mem(addr))
+ ++PC;
+ } else if (code == 0x0012) {
+ // izsn
+ regs.a = add_to(regs.a, 1);
+ if (!regs.a)
+ ++PC;
+ } else if (CODE_MASK(0x0880, 0x3F)) {
+ // izsn m
+ const int addr = code & 0x3F;
+ int result = add_to(get_mem(addr), 1);
+ ram->write(addr, result);
+ if (!result)
+ ++PC;
+ } else if (code == 0x0013) {
+ // dzsn
+ regs.a = sub_to(regs.a, 1);
+ if (!regs.a)
+ ++PC;
+ } else if (CODE_MASK(0x08C0, 0x3F)) {
+ // dzsn m
+ const int addr = code & 0x3F;
+ int result = sub_to(get_mem(addr), 1);
+ ram->write(addr, result);
+ if (!result)
+ ++PC;
+ } else if (CODE_MASK(0x1C00, 0x3FF)) {
+ // call k
+ ram->write(get_SP(), PC);
+ ram->write(get_SP() + 1, PC >> 8);
+ PC = code & 0x3FF;
+ store_io(0x2, get_SP() + 2);
+ } else if (CODE_MASK(0x1800, 0x3FF)) {
+ // goto k
+ PC = code & 0x3FF;
+ } else if (code == 0x001E) {
+ // swap
+ int high = regs.a & 0xF;
+ regs.a = (high << 4) | (regs.a >> 4);
+ } else if (code == 0x0017) {
+ // pcadd
+ PC += regs.a - 1;
+ }
+ // TODO: engint
+ // TODO: disint
+ else if (code == 0x0036) {
+ // stopsys
+ return (resHALT);
+ }
+ // TODO: stopexe
+ // TODO: reset
+ // TODO: wdreset
+ // TODO: swapc IO, k
+ else if (code == 0x0006) {
+ // ldsptl
+ regs.a = rom->get(get_SP()) & 0xFF;
+ } else if (code == 0x0007) {
+ // ldregs[0x02]th
+ regs.a = (rom->get(get_SP()) & 0xFF00) >> 8;
+ } else if (code == 0x003C) {
+ // mul
+ unsigned result = regs.a * get_io(0x08);
+ regs.a = result & 0xFF;
+ store_io(0x08, (result & 0xFF00) >> 8);
+ } else if (code == 0xFF00) {
+ // putchar - usim specific instruction
+ putchar(regs.a);
+ fflush(stdout);
+ } else {
+ return (resINV_INST);
+ }
+ return (resGO);
+}
+
+int cl_pdk::execute_pdk15(unsigned int code) {
+ if (code == 0x0000) {
+ // nop
+ } else if (CODE_MASK(0x0200, 0xFF)) {
+ // ret k
+ regs.a = code & 0xFF;
+ store_io(0x2, get_SP() - 2);
+ PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8);
+ } else if (code == 0x007A) {
+ // ret
+ store_io(0x2, get_SP() - 2);
+ PC = get_mem(get_SP()) | (get_mem(get_SP() + 1) << 8);
+ } else if (CODE_MASK(0x5700, 0xFF)) {
+ // mov a, k
+ regs.a = code & 0xFF;
+ } else if (CODE_MASK(0x0100, 0x7F)) {
+ // mov i, a
+ store_io(code & 0x7F, regs.a);
+ } else if (CODE_MASK(0x0180, 0x7F)) {
+ // mov a, i
+ regs.a = get_io(code & 0x7F);
+ } else if (CODE_MASK(0x1700, 0xFF)) {
+ // mov m, a
+ ram->write(code & 0xFF, regs.a);
+ } else if (CODE_MASK(0x1F00, 0xFF)) {
+ // mov a, m
+ regs.a = get_mem(code & 0xFF);
+ } else if (CODE_MASK(0x0601, 0xFE)) {
+ // TODO: ldt16
+ } else if (CODE_MASK(0x0600, 0xFE)) {
+ // TODO: stt16
+ } else if ((CODE_MASK(0x701, 0xFE))) {
+ // idxm a, m
+ regs.a = get_mem(get_mem(code & 0xFE));
+ } else if ((CODE_MASK(0x700, 0xFE))) {
+ // idxm m, a
+ ram->write(get_mem(code & 0xFE), regs.a);
+ } else if (CODE_MASK(0x2700, 0xFF)) {
+ // xch m
+ int mem = get_mem(code & 0xFF);
+ ram->write(code & 0xFF, regs.a);
+ regs.a = mem;
+ } else if (code == 0x0072) {
+ // pushaf
+ ram->write(get_SP(), regs.a);
+ ram->write(get_SP() + 1, get_flags());
+ store_io(0x2, get_SP() + 2);
+ } else if (code == 0x0073) {
+ // popaf
+ set_flags(get_mem(get_SP() - 1));
+ regs.a = get_mem(get_SP() - 2);
+ store_io(0x2, get_SP() - 2);
+ } else if (CODE_MASK(0x5000, 0xFF)) {
+ // add a, k
+ regs.a = add_to(regs.a, code & 0xFF);
+ } else if (CODE_MASK(0x1800, 0xFF)) {
+ // add a, m
+ regs.a = add_to(regs.a, get_mem(code & 0xFF));
+ } else if (CODE_MASK(0x1000, 0xFF)) {
+ // add m, a
+ int addr = code & 0xFF;
+ ram->write(addr, add_to(regs.a, get_mem(addr)));
+ } else if (CODE_MASK(0x5100, 0xFF)) {
+ // sub a, k
+ regs.a = sub_to(regs.a, code & 0xFF);
+ } else if (CODE_MASK(0x1900, 0xFF)) {
+ // sub a, m
+ regs.a = sub_to(regs.a, get_mem(code & 0xFF));
+ } else if (CODE_MASK(0x1100, 0xFF)) {
+ // sub m, a
+ int addr = code & 0xFF;
+ ram->write(addr, sub_to(get_mem(addr), regs.a));
+ } else if (CODE_MASK(0x1A00, 0xFF)) {
+ // addc a, m
+ regs.a = add_to(regs.a, get_mem(code & 0xFF), get_flag(flag_c));
+ } else if (CODE_MASK(0x1200, 0xFF)) {
+ // addc m, a
+ int addr = code & 0xFF;
+ ram->write(addr, add_to(regs.a, get_mem(addr), get_flag(flag_c)));
+ } else if (code == 0x0060) {
+ // addc a
+ regs.a = add_to(regs.a, get_flag(flag_c));
+ } else if (CODE_MASK(0x2000, 0xFF)) {
+ // addc m
+ int addr = code & 0xFF;
+ ram->write(addr, add_to(get_mem(addr), get_flag(flag_c)));
+ } else if (CODE_MASK(0x1B00, 0xFF)) {
+ // subc a, m
+ regs.a = sub_to(regs.a, get_mem(code & 0xFF), get_flag(flag_c));
+ } else if (CODE_MASK(0x1300, 0xFF)) {
+ // subc m, a
+ int addr = code & 0xFF;
+ ram->write(addr, sub_to(get_mem(addr), regs.a, get_flag(flag_c)));
+ } else if (code == 0x0061) {
+ // subc a
+ regs.a = sub_to(regs.a, get_flag(flag_c));
+ } else if (CODE_MASK(0x2100, 0xFF)) {
+ // subc m
+ int addr = code & 0xFF;
+ ram->write(addr, sub_to(get_mem(addr), get_flag(flag_c)));
+ } else if (CODE_MASK(0x2400, 0xFF)) {
+ // inc m
+ int addr = code & 0xFF;
+ ram->write(addr, add_to(get_mem(addr), 1));
+ } else if (CODE_MASK(0x2500, 0xFF)) {
+ // dec m
+ int addr = code & 0xFF;
+ ram->write(addr, sub_to(get_mem(addr), 1));
+ } else if (CODE_MASK(0x2600, 0xFF)) {
+ // clear m
+ ram->write(code & 0xFF, 0);
+ } else if (code == 0x006A) {
+ // sr a
+ store_flag(flag_c, regs.a & 1);
+ regs.a >>= 1;
+ } else if (CODE_MASK(0x2A00, 0xFF)) {
+ // sr m
+ int value = get_mem(code & 0xFF);
+ store_flag(flag_c, value & 1);
+ ram->write(code & 0xFF, value >> 1);
+ } else if (code == 0x006B) {
+ // sl a
+ store_flag(flag_c, (regs.a & 0x80) >> 7);
+ regs.a <<= 1;
+ } else if (CODE_MASK(0x2B00, 0xFF)) {
+ // sl m
+ int value = get_mem(code & 0xFF);
+ store_flag(flag_c, (value & 0x80) >> 7);
+ ram->write(code & 0xFF, value << 1);
+ } else if (code == 0x006C) {
+ // src a
+ int c = regs.a & 1;
+ regs.a >>= 1;
+ regs.a |= get_flag(flag_c) << 7;
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x2C00, 0xFF)) {
+ // src m
+ int value = get_mem(code & 0xFF);
+ int c = value & 1;
+ ram->write(code & 0xFF, (value >> 1) | (get_flag(flag_c) << 7));
+ store_flag(flag_c, c);
+ } else if (code == 0x006D) {
+ // slc a
+ int c = (regs.a & 0x80) >> 7;
+ regs.a <<= 1;
+ regs.a |= get_flag(flag_c);
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x2D00, 0xFF)) {
+ // slc m
+ int value = get_mem(code & 0xFF);
+ int c = (value & 0x80) >> 7;
+ ram->write(code & 0xFF, (value << 1) | get_flag(flag_c));
+ store_flag(flag_c, c);
+ } else if (CODE_MASK(0x5400, 0xFF)) {
+ // and a, k
+ regs.a &= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x1C00, 0xFF)) {
+ // and a, m
+ regs.a &= get_mem(code & 0xFF);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x1400, 0xFF)) {
+ // and m, a
+ int store = regs.a & get_mem(code & 0xFF);
+ store_flag(flag_z, !store);
+ ram->write(code & 0xFF, store);
+ } else if (CODE_MASK(0x5500, 0xFF)) {
+ // or a, k
+ regs.a |= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x1D00, 0xFF)) {
+ // or a, m
+ regs.a |= get_mem(code & 0xFF);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x1500, 0xFF)) {
+ // or m, a
+ int store = regs.a | get_mem(code & 0xFF);
+ store_flag(flag_z, !store);
+ ram->write(code & 0xFF, store);
+ } else if (CODE_MASK(0x5600, 0xFF)) {
+ // xor a, k
+ regs.a ^= code & 0xFF;
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x1E00, 0xFF)) {
+ // xor a, m
+ regs.a ^= get_mem(code & 0xFF);
+ store_flag(flag_z, !regs.a);
+ } else if (CODE_MASK(0x1600, 0xFF)) {
+ // xor m, a
+ int store = regs.a ^ get_mem(code & 0xFF);
+ store_flag(flag_z, !store);
+ ram->write(code & 0xFF, store);
+ } else if (CODE_MASK(0x0080, 0x7F)) {
+ // xor io, a
+ store_io(code & 0x3F, regs.a ^ get_io(code & 0x3F));
+ } else if (code == 0x0068) {
+ // not a
+ regs.a = ~regs.a;
+ } else if (CODE_MASK(0x2800, 0xFF)) {
+ // not m
+ ram->write(code & 0xFF, ~get_mem(code & 0xFF));
+ } else if (code == 0x0069) {
+ // neg a
+ regs.a = -regs.a;
+ } else if (CODE_MASK(0x2900, 0xFF)) {
+ // neg m
+ ram->write(code & 0xFF, -get_mem(code & 0xFF));
+ } else if (CODE_MASK(0x3800, 0x3FF)) {
+ // set0 io, k
+ const u8_t bit = (code & 0x380) >> 7;
+ const u8_t addr = code & 0x7F;
+ store_io(addr, get_io(addr) & ~(1 << bit));
+ } else if (CODE_MASK(0x4800, 0x3FF)) {
+ // set0 m, k
+ const u8_t bit = (code & 0x380) >> 7;
+ const u8_t addr = code & 0x7F;
+ ram->write(addr, get_mem(addr) & ~(1 << bit));
+ } else if (CODE_MASK(0x3C00, 0x3FF)) {
+ // set1 io, k
+ const u8_t bit = (code & 0x380) >> 7;
+ const u8_t addr = code & 0x7F;
+ store_io(addr, get_io(addr) | (1 << bit));
+ } else if (CODE_MASK(0x4C00, 0x3FF)) {
+ // set1 m, k
+ const u8_t bit = (code & 0x380) >> 7;
+ const u8_t addr = code & 0x7F;
+ ram->write(addr, get_mem(addr) | (1 << bit));
+ } else if (CODE_MASK(0x3000, 0x3FF)) {
+ // t0sn io, k
+ int n = (code & 0x380) >> 7;
+ if (!(get_io(code & 0x7F) & (1 << n)))
+ ++PC;
+ } else if (CODE_MASK(0x4000, 0x3FF)) {
+ // t0sn m, k
+ int n = (code & 0x380) >> 7;
+ if (!(get_mem(code & 0x7F) & (1 << n)))
+ ++PC;
+ } else if (CODE_MASK(0x3400, 0x3FF)) {
+ // t1sn io, k
+ int n = (code & 0x380) >> 7;
+ if (get_io(code & 0x7F) & (1 << n))
+ ++PC;
+ } else if (CODE_MASK(0x4400, 0x3FF)) {
+ // t1sn m, k
+ int n = (code & 0x380) >> 7;
+ if (get_mem(code & 0x7F) & (1 << n))
+ ++PC;
+ } else if (CODE_MASK(0x5200, 0xFF)) {
+ // ceqsn a, k
+ sub_to(regs.a, code & 0xFF);
+ if (regs.a == (code & 0xFF))
+ ++PC;
+ } else if (CODE_MASK(0x2E00, 0xFF)) {
+ // ceqsn a, m
+ int addr = code & 0xFF;
+ sub_to(regs.a, get_mem(addr));
+ if (regs.a == get_mem(addr))
+ ++PC;
+ } else if (CODE_MASK(0x5300, 0xFF)) {
+ // cneqsn a, k
+ sub_to(regs.a, code & 0xFF);
+ if (regs.a != (code & 0xFF))
+ ++PC;
+ } else if (CODE_MASK(0x2F00, 0xFF)) {
+ // cneqsn a, m
+ int addr = code & 0xFF;
+ sub_to(regs.a, get_mem(addr));
+ if (regs.a != get_mem(addr))
+ ++PC;
+ } else if (code == 0x0062) {
+ // izsn
+ regs.a = add_to(regs.a, 1);
+ if (!regs.a)
+ ++PC;
+ } else if (CODE_MASK(0x2200, 0xFF)) {
+ // izsn m
+ const int addr = code & 0xFF;
+ int result = add_to(get_mem(addr), 1);
+ ram->write(addr, result);
+ if (!result)
+ ++PC;
+ } else if (code == 0x0063) {
+ // dzsn
+ regs.a = sub_to(regs.a, 1);
+ if (!regs.a)
+ ++PC;
+ } else if (CODE_MASK(0x2300, 0xFF)) {
+ // dzsn m
+ const int addr = code & 0xFF;
+ int result = sub_to(get_mem(addr), 1);
+ ram->write(addr, result);
+ if (!result)
+ ++PC;
+ } else if (CODE_MASK(0x7000, 0xFFF)) {
+ // call k
+ ram->write(get_SP(), PC);
+ ram->write(get_SP() + 1, PC >> 8);
+ PC = code & 0xFFF;
+ store_io(0x2, get_SP() + 2);
+ } else if (CODE_MASK(0x6000, 0xFFF)) {
+ // goto k
+ PC = code & 0xFFF;
+ } else if (CODE_MASK(0x0C00, 0xFF)) {
+ // comp a, m
+ sub_to(regs.a, get_mem(code & 0xFF));
+ } else if (CODE_MASK(0x0D00, 0xFF)) {
+ // comp m, a
+ sub_to(get_mem(code & 0xFF), regs.a);
+ } else if (CODE_MASK(0x0E00, 0xFF)) {
+ // nadd a, m
+ regs.a = add_to(get_mem(code & 0xFF), -regs.a);
+ } else if (CODE_MASK(0x0F00, 0xFF)) {
+ // nadd m, a
+ int addr = code & 0xFF;
+ ram->write(addr, add_to(-get_mem(addr), regs.a));
+ } else if (code == 0x006E) {
+ // swap
+ int high = regs.a & 0xF;
+ regs.a = (high << 4) | (regs.a >> 4);
+ } else if (code == 0x0067) {
+ // pcadd
+ PC += regs.a - 1;
+ }
+ // TODO: engint
+ // TODO: disint
+ else if (code == 0x0076) {
+ // stopsys
+ return (resHALT);
+ }
+ // TODO: stopexe
+ // TODO: reset
+ // TODO: wdreset
+ // TODO: swapc IO, k
+ else if (code == 0x0006) {
+ // ldsptl
+ regs.a = rom->get(get_SP()) & 0xFF;
+ } else if (code == 0x0007) {
+ // ldspth
+ regs.a = (rom->get(get_SP()) & 0xFF00) >> 8;
+ } else if (code == 0x007C) {
+ // mul
+ unsigned result = regs.a * get_io(0x08);
+ regs.a = result & 0xFF;
+ store_io(0x08, (result & 0xFF00) >> 8);
+ } else if (code == 0xFF00) {
+ // putchar - usim specific instruction
+ putchar(regs.a);
+ fflush(stdout);
+ } else {
+ return (resINV_INST);
+ }
+ return (resGO);
+}
+
+/* End of pdk.src/inst.cc */
+/* End of pdk.src/inst.cc */