diff options
Diffstat (limited to 'src/devices/cpu/c33')
-rw-r--r-- | src/devices/cpu/c33/c33common.h | 29 | ||||
-rw-r--r-- | src/devices/cpu/c33/c33dasm.cpp | 674 | ||||
-rw-r--r-- | src/devices/cpu/c33/c33dasm.h | 37 | ||||
-rw-r--r-- | src/devices/cpu/c33/c33helpers.ipp | 64 | ||||
-rw-r--r-- | src/devices/cpu/c33/c33std.cpp | 117 | ||||
-rw-r--r-- | src/devices/cpu/c33/c33std.h | 58 | ||||
-rw-r--r-- | src/devices/cpu/c33/s1c33209.cpp | 331 | ||||
-rw-r--r-- | src/devices/cpu/c33/s1c33209.h | 57 |
8 files changed, 1367 insertions, 0 deletions
diff --git a/src/devices/cpu/c33/c33common.h b/src/devices/cpu/c33/c33common.h new file mode 100644 index 00000000000..4cfd1167c72 --- /dev/null +++ b/src/devices/cpu/c33/c33common.h @@ -0,0 +1,29 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Common Epson C33 family stuff +*/ + +#ifndef MAME_CPU_C33_C33COMMON_H +#define MAME_CPU_C33_C33COMMON_H + +#pragma once + + +class c33_cpu_common +{ +public: + // state indices + enum + { + C33_R0 = 1, C33_R1, C33_R2, C33_R3, C33_R4, C33_R5, C33_R6, C33_R7, + C33_R8, C33_R9, C33_R10, C33_R11, C33_R12, C33_R13, C33_R14, C33_R15, + C33_PSR, C33_SP, + C33_ALR, C33_AHR, + C33_LCO, C33_LSA, C33_LEA, + C33_SOR, C33_TTBR, C33_DP, C33_DBBR, + C33_USP, C33_SSP + }; +}; + +#endif // MAME_CPU_C33_C33COMMON_H diff --git a/src/devices/cpu/c33/c33dasm.cpp b/src/devices/cpu/c33/c33dasm.cpp new file mode 100644 index 00000000000..08daaf81155 --- /dev/null +++ b/src/devices/cpu/c33/c33dasm.cpp @@ -0,0 +1,674 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson C33 disassembler + + TODO: + * Only C33 ADV Core is currently supported - add support for C33 STD Core, C33 PE Core, etc. + * Reconstruct more assembler synthetics + * Should psrset and psrclr use symbolic names for bits? + * Should 32-bit extended displacements always be displayed as signed? + * Should loop instructions have friendlier syntax? +*/ + +#include "emu.h" +#include "c33dasm.h" + +#include <tuple> +#include <utility> + + +namespace { + +char const *const special_reg_names[16] = { + "%psr", + "%sp", + "%alr", + "%ahr", + "%lco", + "%lca", + "%lea", + "%sor", + "%ttbr", + "%dp", + "%idir", + "%dbbr", + nullptr, + "%usp", + "%ssp", + "%pc" }; + +std::pair<char const *, unsigned> const class_0_00_ops[32] = { + { "nop", 0 }, // 000 0000 0 00 00 + { "slp", 0 }, // 000 0000 0 01 00 + { "halt", 0 }, // 000 0000 0 10 00 + { nullptr, 0 }, + { nullptr, 0 }, + { nullptr, 0 }, + { nullptr, 0 }, + { nullptr, 0 }, + { "pushn %%r%1$u", 4 }, // 000 0001 0 00 00 + { "popn %%r%1$u", 4 }, // 000 0001 0 01 00 + { nullptr, 0 }, + { "jpr %%r%1$u", 4 }, // 000 0001 0 11 00 + { nullptr, 0 }, + { nullptr, 0 }, + { nullptr, 0 }, + { "jpr.d %%r%1$u", 4 }, // 000 0001 1 11 00 + { "brk", 0 }, // 000 0010 0 00 00 + { "retd", 0 }, // 000 0010 0 01 00 + { "int %1$u", 2 }, // 000 0010 0 10 00 + { "reti", 0 }, // 000 0010 0 11 00 + { nullptr, 0 }, + { nullptr, 0 }, + { nullptr, 0 }, + { nullptr, 0 }, + { "call %%r%1$u", 4 }, // 000 0011 0 00 00 + { "ret", 0 }, // 000 0011 0 01 00 + { "jp %%r%1$u", 4 }, // 000 0011 0 10 00 + { "retm", 0 }, // 000 0011 0 11 00 + { "call.d %%r%1$u", 4 }, // 000 0011 1 00 00 + { "ret.d", 0 }, // 000 0011 1 01 00 + { "jp.d %%r%1$u", 4 }, // 000 0011 1 10 00 + { nullptr, 0 } }; + +std::tuple<char const *, char const *, char const *, bool, bool> const class_0_01_ops[32] = { + { "push %%r%1$u", nullptr, nullptr, false, false }, // 000 0000 000 01 + { "pop %%r%1$u", nullptr, nullptr, false, false }, // 000 0000 001 01 + { "pushs %%r%3$s", nullptr, nullptr, true, false }, // 000 0000 010 01 + { "pops %%r%3$s", nullptr, nullptr, true, false }, // 000 0000 011 01 + { "mac.w %%r%1$u", nullptr, nullptr, false, false }, // 000 0000 100 01 + { "mac.hw %%r%1$u", nullptr, nullptr, false, false }, // 000 0000 101 01 + { "macclr", nullptr, nullptr, false, true }, // 000 0000 110 01 + { "ld.cf", nullptr, nullptr, false, true }, // 000 0000 111 01 + { "divu.w %%r%1$u", nullptr, nullptr, false, false }, // 000 0001 000 01 + { "div.w %%r%1$u", nullptr, nullptr, false, false }, // 000 0001 001 01 + { "repeat %%r%1$u", nullptr, nullptr, false, false }, // 000 0001 010 01 + { "repeat %1$u", nullptr, nullptr, false, false }, // 000 0001 011 01 + { nullptr, nullptr, nullptr, false, false }, + { "add %%r%1$u,%%dp", "xadd %%r%1$u,%%dp,0x%2$x", "xadd %%r%1$u,%%dp,%%r%2$u", false, false }, // 000 0001 101 01 + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false }, + { nullptr, nullptr, nullptr, false, false } }; + +std::pair<char const *, char const *> const class_0_jumps[16] = { + { nullptr, nullptr }, + { nullptr, nullptr }, + { nullptr, nullptr }, + { nullptr, nullptr }, + { "jrgt%1$s 0x%2$x", "xjrgt%1$s 0x%2$x" }, // 000 0100 + { "jrge%1$s 0x%2$x", "xjrge%1$s 0x%2$x" }, // 000 0101 + { "jrlt%1$s 0x%2$x", "xjrlt%1$s 0x%2$x" }, // 000 0110 + { "jrle%1$s 0x%2$x", "xjrle%1$s 0x%2$x" }, // 000 0111 + { "jrugt%1$s 0x%2$x", "xjrugt%1$s 0x%2$x" }, // 000 1000 + { "jruge%1$s 0x%2$x", "xjruge%1$s 0x%2$x" }, // 000 1001 + { "jrult%1$s 0x%2$x", "xjrult%1$s 0x%2$x" }, // 000 1010 + { "jrule%1$s 0x%2$x", "xjrule%1$s 0x%2$x" }, // 000 1011 + { "jreq%1$s 0x%2$x", "xjreq%1$s 0x%2$x" }, // 000 1100 + { "jrne%1$s 0x%2$x", "xjrne%1$s 0x%2$x" }, // 000 1101 + { "call%1$s 0x%2$x", "xcall%1$s 0x%2$x" }, // 000 1110 + { "jp%1$s 0x%2$x", "xjp%1$s 0x%2$x" } }; // 000 1111 + +std::tuple<char const *, char const *, char const *> const class_1_ops[32] = { + { "ld.b %%r%1$u,[%%r%2$u]", "xld.b %%r%1$u,[%%r%2$u + 0x%4$x]", "xld.b %%r%1$u,[%%r%2$u + %%r%4$u]" }, // 001 000 00 + { "ld.b %%r%1$u,[%%r%2$u]+", nullptr, nullptr }, // 001 000 01 + { "add %%r%1$u,%%r%2$u", "xadd %%r%1$u,%%r%2$u,0x%4$x", "xadd %%r%1$u,%%r%2$u,%%r%4$u" }, // 001 000 10 + { "srl %%r%1$u,%3$u", nullptr, "xsrl %%r%1$u,%%r%4$u,%3$u" }, // 001 000 11 + { "ld.ub %%r%1$u,[%%r%2$u]", "xld.ub %%r%1$u,[%%r%2$u + 0x%4$x]", "xld.ub %%r%1$u,[%%r%2$u + %%r%4$u]" }, // 001 001 00 + { "ld.ub %%r%1$u,[%%r%2$u]+", nullptr, nullptr }, // 001 001 01 + { "sub %%r%1$u,%%r%2$u", "xsub %%r%1$u,%%r%2$u,0x%4$x", "xsub %%r%1$u,%%r%2$u,%%r%4$u" }, // 001 001 10 + { "sll %%r%1$u,%3$u", nullptr, "xsll %%r%1$u,%%r%4$u,%3$u" }, // 001 001 11 + { "ld.h %%r%1$u,[%%r%2$u]", "xld.h %%r%1$u,[%%r%2$u + 0x%4$x]", "xld.h %%r%1$u,[%%r%2$u + %%r%4$u]" }, // 001 010 00 + { "ld.h %%r%1$u,[%%r%2$u]+", nullptr, nullptr }, // 001 010 01 + { "cmp %%r%1$u,%%r%2$u", nullptr, nullptr }, // 001 010 10 + { "sra %%r%1$u,%3$u", nullptr, "xsra %%r%1$u,%%r%4$u,%3$u" }, // 001 010 11 + { "ld.uh %%r%1$u,[%%r%2$u]", "xld.uh %%r%1$u,[%%r%2$u + 0x%4$x]", "xld.uh %%r%1$u,[%%r%2$u + %%r%4$u]" }, // 001 011 00 + { "ld.uh %%r%1$u,[%%r%2$u]+", nullptr, nullptr }, // 001 011 01 + { "ld.w %%r%1$u,%%r%2$u", nullptr, nullptr }, // 001 011 10 + { "sla %%r%1$u,%3$u", nullptr, "xsla %%r%1$u,%%r%4$u,%3$u" }, // 001 011 11 + { "ld.w %%r%1$u,[%%r%2$u]", "xld.w %%r%1$u,[%%r%2$u + 0x%4$x]", "xld.w %%r%1$u,[%%r%2$u + %%r%4$u]" }, // 001 100 00 + { "ld.w %%r%1$u,[%%r%2$u]+", nullptr, nullptr }, // 001 100 01 + { "and %%r%1$u,%%r%2$u", "xand %%r%1$u,%%r%2$u,0x%4$x", "xand %%r%1$u,%%r%2$u,%%r%4$u" }, // 001 100 10 + { "rr %%r%1$u,%3$u", nullptr, "xrr %%r%1$u,%%r%4$u,%3$u" }, // 001 100 11 + { "ld.b [%%r%2$u],%%r%1$u", "xld.b [%%r%2$u + 0x%4$x],%%r%1$u", "xld.b [%%r%2$u + %%r%4$u],%%r%1$u" }, // 001 101 00 + { "ld.b [%%r%2$u]+,%%r%1$u", nullptr, nullptr }, // 001 101 01 + { "or %%r%1$u,%%r%2$u", "xoor %%r%1$u,%%r%2$u,0x%4$x", "xoor %%r%1$u,%%r%2$u,%%r%4$u" }, // 001 101 10 + { "rl %%r%1$u,%3$u", nullptr, "xrl %%r%1$u,%%r%4$u,%3$u" }, // 001 101 11 + { "ld.h [%%r%2$u],%%r%1$u", "xld.h [%%r%2$u + 0x%4$x],%%r%1$u", "xld.h [%%r%2$u + %%r%4$u],%%r%1$u" }, // 001 110 00 + { "ld.h [%%r%2$u]+,%%r%1$u", nullptr, nullptr }, // 001 110 01 + { "xor %%r%1$u,%%r%2$u", "xxor %%r%1$u,%%r%2$u,0x%4$x", "xxor %%r%1$u,%%r%2$u,%%r%4$u" }, // 001 110 10 + { nullptr, nullptr, nullptr }, + { "ld.w [%%r%2$u],%%r%1$u", "xld.w [%%r%2$u + 0x%4$x],%%r%1$u", "xld.w [%%r%2$u + %%r%4$u],%%r%1$u" }, // 001 111 00 + { "ld.w [%%r%2$u]+,%%r%1$u", nullptr, nullptr }, // 001 111 01 + { "not %%r%1$u,%%r%2$u", nullptr, nullptr }, // 001 111 10 + { nullptr, nullptr, nullptr } }; + +char const *const class_1_ext_shifts[4] = { + nullptr, + "ext sra,%1$u", // 001 110 11 0000 01 + "ext srl,%1$u", // 001 110 11 0000 10 + "ext sll,%1$u" }; // 001 110 11 0000 11 + +char const *const class_1_ext_predicates[16] = { + nullptr, + nullptr, + nullptr, + nullptr, + "ext gt", // 001 110 11 0100 + "ext ge", // 001 110 11 0101 + "ext lt", // 001 110 11 0110 + "ext le", // 001 110 11 0111 + "ext ugt", // 001 110 11 1000 + "ext uge", // 001 110 11 1001 + "ext ult", // 001 110 11 1010 + "ext ule", // 001 110 11 1011 + "ext eq", // 001 110 11 1100 + "ext ne", // 001 110 11 1101 + nullptr, + nullptr }; + +std::pair<char const *, bool> class_1_ext_3[4] = { + { "ext %%r%1$u", true }, + { "ext %%r%1$u,sra,%2$u", false }, + { "ext %%r%1$u,srl,%2$u", false }, + { "ext %%r%1$u,sll,%2$u", false } }; + +std::tuple<char const *, char const *, unsigned> const class_2_3_ops[16] = { + { "ld.b %%r%1$u,[%%sp + 0x%2$x]", "xld.b %%r%1$u,[%%sp + 0x%2$x]", 1 }, // 010 000 + { "ld.ub %%r%1$u,[%%sp + 0x%2$x]", "xld.ub %%r%1$u,[%%sp + 0x%2$x]", 1 }, // 010 001 + { "ld.h %%r%1$u,[%%sp + 0x%2$x]", "xld.h %%r%1$u,[%%sp + 0x%2$x]", 2 }, // 010 010 + { "ld.uh %%r%1$u,[%%sp + 0x%2$x]", "xld.uh %%r%1$u,[%%sp + 0x%2$x]", 2 }, // 010 011 + { "ld.w %%r%1$u,[%%sp + 0x%2$x]", "xld.w %%r%1$u,[%%sp + 0x%2$x]", 4 }, // 010 100 + { "ld.b [%%sp + 0x%2$x],%%r%1$u", "xld.b [%%sp + 0x%2$x],%%r%1$u", 1 }, // 010 101 + { "ld.h [%%sp + 0x%2$x],%%r%1$u", "xld.h [%%sp + 0x%2$x],%%r%1$u", 2 }, // 010 110 + { "ld.w [%%sp + 0x%2$x],%%r%1$u", "xld.w [%%sp + 0x%2$x],%%r%1$u", 4 }, // 010 111 + { "add %%r%1$u,0x%2$x", "xadd %%r%1$u,0x%2$x", 1 }, // 011 000 + { "sub %%r%1$u,0x%2$x", "xsub %%r%1$u,0x%2$x", 1 }, // 011 001 + { "cmp %%r%1$u,%5$s0x%4$x", "xcmp %%r%1$u,%5$s0x%4$x", 1 }, // 011 010 + { "ld.w %%r%1$u,%5$s0x%4$x", "xld.w %%r%1$u,%5$s0x%4$x", 1 }, // 011 011 + { "and %%r%1$u,0x%3$x", "xand %%r%1$u,0x%3$x", 1 }, // 011 100 + { "or %%r%1$u,0x%3$x", "xoor %%r%1$u,0x%3$x", 1 }, // 011 101 + { "xor %%r%1$u,0x%3$x", "xxor %%r%1$u,0x%3$x", 1 }, // 011 110 + { "not %%r%1$u,0x%3$x", "xnot %%r%1$u,0x%3$x", 1 } }; // 011 111 + +std::tuple<char const *, char const *, bool> const class_4_ops[32] = { + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { nullptr, nullptr, false }, + { "srl %%r%1$u,%2$u", "xsrl %%r%1$u,%%r%3$u,%2$u", false }, // 100 010 00 + { "srl %%r%1$u,%%r%2$u", "xsrl %%r%1$u,%%r%3$u,%%r%2$u", false }, // 100 010 01 + { "scan0 %%r%1$u,%%r%2$u", nullptr, false }, // 100 010 10 + { "div0s %%r%2$u", nullptr, true }, // 100 010 11 + { "sll %%r%1$u,%2$u", "xsll %%r%1$u,%%r%3$u,%2$u", false }, // 100 011 00 + { "sll %%r%1$u,%%r%2$u", "xsll %%r%1$u,%%r%3$u,%%r%2$u", false }, // 100 011 01 + { "scan1 %%r%1$u,%%r%2$u", nullptr, false }, // 100 011 10 + { "div0u %%r%2$u", nullptr, true }, // 100 011 11 + { "sra %%r%1$u,%2$u", "xsra %%r%1$u,%%r%3$u,%2$u", false }, // 100 100 00 + { "sra %%r%1$u,%%r%2$u", "xsra %%r%1$u,%%r%3$u,%%r%2$u", false }, // 100 100 01 + { "swap %%r%1$u,%%r%2$u", nullptr, false }, // 100 100 10 + { "div1 %%r%2$u", nullptr, true }, // 100 100 11 + { "sla %%r%1$u,%2$u", "xsla %%r%1$u,%%r%3$u,%2$u", false }, // 100 101 00 + { "sla %%r%1$u,%%r%2$u", "xsla %%r%1$u,%%r%3$u,%%r%2$u", false }, // 100 101 01 + { "mirror %%r%1$u,%%r%2$u", nullptr, false }, // 100 101 10 + { "div2s %%r%2$u", nullptr, true }, // 100 101 11 + { "rr %%r%1$u,%2$u", "xrr %%r%1$u,%%r%3$u,%2$u", false }, // 100 110 00 + { "rr %%r%1$u,%%r%2$u", "xrr %%r%1$u,%%r%3$u,%%r%2$u", false }, // 100 110 01 + { "swaph %%r%1$u,%%r%2$u", nullptr, false }, // 100 110 10 + { "div3s %%r%2$u", nullptr, true }, // 100 110 11 + { "rl %%r%1$u,%2$u", "xrl %%r%1$u,%%r%3$u,%2$u", false }, // 100 111 00 + { "rl %%r%1$u,%%r%2$u", "xrl %%r%1$u,%%r%3$u,%%r%2$u", false }, // 100 111 01 + { "sat.b %%r%1$u,%%r%2$u", nullptr, false }, // 100 111 10 + { "sat.ub %%r%1$u,%%r%2$u", nullptr, false } }; // 100 111 11 + +std::tuple<char const *, char const *, char const *, unsigned, unsigned> const class_5_ops[32] = { + { "ld.w %4$s,%%r%2$d", nullptr, nullptr, 4, 1 }, // 101 000 00 + { "ld.b %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 000 01 + { "mlt.h %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 000 10 + { "mlt.hw %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 000 11 + { "ld.w %%r%1$d,%4$s", nullptr, nullptr, 4, 2 }, // 101 001 00 + { "ld.ub %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 001 01 + { "mltu.h %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 001 10 + { "mac1.h %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 001 11 + { "btst [%%r%2$u],%1$u", "xbtst [%%r%2$u + 0x%3$x],%1$u", nullptr, 3, 0 }, // 101 010 00 + { "ld.h %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 010 01 + { "mlt.w %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 010 10 + { "mac1.hw %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 010 11 + { "bclr [%%r%2$u],%1$u", "xbclr [%%r%2$u + 0x%3$x],%1$u", nullptr, 3, 0 }, // 101 011 00 + { "ld.uh %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 011 01 + { "mltu.w %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 011 10 + { nullptr, nullptr, nullptr, 0, 0 }, + { "bset [%%r%2$u],%1$u", "xbset [%%r%2$u + 0x%3$x],%1$u", nullptr, 3, 0 }, // 101 100 00 + { "ld.c %%r%1$u,0x%2$x", nullptr, nullptr, 4, 0 }, // 101 100 01 + { "mac %%r%2$u", nullptr, nullptr, 0, 0 }, // 101 100 10 + { "mac1.w %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 100 11 + { "bnot [%%r%2$u],%1$u", "xbnot [%%r%2$u + 0x%3$x],%1$u", nullptr, 3, 0 }, // 101 101 00 + { "ld.c 0x%2$x,%%r%1$u", nullptr, nullptr, 4, 0 }, // 101 101 01 + { "sat.h %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 101 10 + { "sat.uh %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 101 11 + { "adc %%r%1$u,%%r%2$u", nullptr, "xadc %%r%1$u,%%r%2$u,%%r%3$u", 4, 0 }, // 101 110 00 + { "loop %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 110 01 + { "loop %%r%1$u,%2$u", nullptr, nullptr, 4, 0 }, // 101 110 10 + { "loop %1$u,%2$u", nullptr, nullptr, 4, 0 }, // 101 110 11 + { "sbc %%r%1$u,%%r%2$u", nullptr, "xsbc %%r%1$u,%%r%2$u,%%r%3$u", 4, 0 }, // 101 111 00 + { "sat.w %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 111 01 + { "sat.uw %%r%1$u,%%r%2$u", nullptr, nullptr, 4, 0 }, // 101 111 10 + { nullptr, nullptr, nullptr, 0, 0 } }; + +std::tuple<char const *, char const *, unsigned> const class_7_ops[8] = { + { "ld.b %%r%1$u,[%%dp + 0x%2$x]", "xld.b %%r%1$u,[%%dp + 0x%2$x]", 1 }, // 111 000 + { "ld.ub %%r%1$u,[%%dp + 0x%2$x]", "xld.ub %%r%1$u,[%%dp + 0x%2$x]", 1 }, // 111 001 + { "ld.h %%r%1$u,[%%dp + 0x%2$x]", "xld.h %%r%1$u,[%%dp + 0x%2$x]", 2 }, // 111 010 + { "ld.uh %%r%1$u,[%%dp + 0x%2$x]", "xld.uh %%r%1$u,[%%dp + 0x%2$x]", 2 }, // 111 011 + { "ld.w %%r%1$u,[%%dp + 0x%2$x]", "xld.w %%r%1$u,[%%dp + 0x%2$x]", 4 }, // 111 100 + { "ld.b [%%dp + 0x%2$x],%%r%1$u", "xld.b [%%dp + 0x%2$x],%%r%1$u", 1 }, // 111 101 + { "ld.h [%%dp + 0x%2$x],%%r%1$u", "xld.h [%%dp + 0x%2$x],%%r%1$u", 2 }, // 111 110 + { "ld.w [%%dp + 0x%2$x],%%r%1$u", "xld.w [%%dp + 0x%2$x],%%r%1$u", 4 } }; // 111 111 + +} // anonymous namespace + + +struct c33_disassembler::ext_info +{ + offs_t size() const + { + switch (type) + { + case ext_type::NONE: + return 0; + case ext_type::IMM13: + return 2; + case ext_type::IMM26: + return 4; + case ext_type::REG: + return 2; + } + + throw false; // something is very wrong if we get here + } + + unsigned bits() const + { + switch (type) + { + case ext_type::NONE: + return 0; + case ext_type::IMM13: + return 13; + case ext_type::IMM26: + return 26; + case ext_type::REG: + return 4; + } + + throw false; // something is very wrong if we get here + } + + char const *inst(char const *base, char const *ext_imm, char const *ext_reg) const + { + switch (type) + { + case ext_type::NONE: + return base; + case ext_type::IMM13: + case ext_type::IMM26: + return ext_imm; + case ext_type::REG: + return ext_reg; + } + + throw false; // something is very wrong if we get here + } + + ext_type type = ext_type::NONE; + u32 val = 0; + u16 op = 0; +}; + + +c33_disassembler::c33_disassembler() +{ +} + + +u32 c33_disassembler::opcode_alignment() const +{ + return 2; +} + + +offs_t c33_disassembler::disassemble( + std::ostream &stream, + offs_t pc, + data_buffer const &opcodes, + data_buffer const ¶ms) +{ + u16 op; + + ext_info ext; + op = opcodes.r16(pc); + if (BIT(op, 13, 3) == 6) + { + ext.type = ext_type::IMM13; + ext.val = BIT(op, 0, 13); + ext.op = op; + op = opcodes.r16(pc + 2); + if (BIT(op, 13, 3) == 6) + { + ext.type = ext_type::IMM26; + ext.val = (ext.val << 13) | BIT(op, 0, 13); + op = opcodes.r16(pc + 4); + } + } + else if ((op & 0b111'111'11'0000'1111) == 0b001'111'11'0000'0000) + { + ext.type = ext_type::REG; + ext.val = BIT(op, 4, 4); + ext.op = op; + op = opcodes.r16(pc + 2); + } + + return dasm(stream, pc, op, ext); +} + + +offs_t c33_disassembler::dasm(std::ostream &stream, offs_t pc, u16 op, ext_info const &ext) const +{ + switch (BIT(op, 13, 3)) + { + case 0: + if (offs_t const r = dasm_class_0(stream, pc, op, ext); r) + return r; + break; + case 1: + if (offs_t const r = dasm_class_1(stream, op, ext); r) + return r; + break; + case 2: + case 3: + if (offs_t const r = dasm_class_2_3(stream, op, ext); r) + return r; + break; + case 4: + if (offs_t const r = dasm_class_4(stream, op, ext); r) + return r; + break; + case 5: + if (offs_t const r = dasm_class_5(stream, op, ext); r) + return r; + break; + case 6: + if (offs_t const r = dasm_class_6(stream, op, ext); r) + return r; + break; + case 7: + if (offs_t const r = dasm_class_7(stream, op, ext); r) + return r; + break; + }; + + if (ext_type::NONE != ext.type) + return dasm(stream, pc, ext.op, ext_info()); + + stream << "<invalid>"; + return 2; +} + + +offs_t c33_disassembler::dasm_class_0(std::ostream &stream, offs_t pc, u16 op, ext_info const &ext) const +{ + switch (BIT(op, 9, 4)) + { + case 0b0000: + case 0b0001: + case 0b0010: + case 0b0011: + if (BIT(op, 4, 2) == 0) + { + auto const [inst, target_bits] = class_0_00_ops[BIT(op, 6, 5)]; + if (inst && ((4 == target_bits) || !BIT(op, target_bits, 4 - target_bits))) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, inst, BIT(op, 0, 4)); + return 2; + } + } + else if (BIT(op, 4, 2) == 1) + { + auto const [inst, inst_ext_imm, inst_ext_reg, use_special_reg, no_arg] = class_0_01_ops[BIT(op, 6, 5)]; + char const *const special_reg = use_special_reg ? special_reg_names[BIT(op, 0, 4)] : nullptr; + if (inst && (!use_special_reg || special_reg) && (!no_arg || !BIT(op, 0, 4))) + { + char const *const fmt = ext.inst(inst, inst_ext_imm, inst_ext_reg); + if (!fmt) + return 0; + + util::stream_format(stream, fmt, BIT(op, 0, 4), ext.val, special_reg); + return 2 + ext.size(); + } + } + break; + + default: + { + auto const [inst, inst_ext_imm] = class_0_jumps[BIT(op, 9, 5)]; + char const *const fmt = ext.inst(inst, inst_ext_imm, nullptr); + if (!fmt) + return 0; + + s32 imm = (BIT(ext.val, 16, 10) << 22) | (BIT(ext.val, 0, 13) << 9) | (BIT(op, 0, 8) << 1); + if (ext_type::NONE == ext.type) + imm = util::sext(imm, 9); + else if (ext_type::IMM13 == ext.type) + imm = util::sext(imm, 22); + + util::stream_format(stream, fmt, BIT(op, 8) ? ".d" : " ", pc + ext.size() + imm); + return 2 + ext.size(); + } + } + + return 0; // catch invalid forms +} + +offs_t c33_disassembler::dasm_class_1(std::ostream &stream, u16 op, ext_info const &ext) const +{ + switch (BIT(op, 8, 5)) + { + case 0b110'11: + if (!BIT(op, 4, 4)) + { + char const *const inst = class_1_ext_shifts[BIT(op, 2, 2)]; + if (inst) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, inst, BIT(op, 0, 2)); + return 2; + } + } + else + { + char const *const inst = class_1_ext_predicates[BIT(op, 4, 4)]; + if (inst && !BIT(op, 0, 4)) + { + if (ext_type::NONE != ext.type) + return 0; + + stream << inst; + return 2; + } + } + break; + + case 0b111'11: + { + auto const [inst, no_imm] = class_1_ext_3[BIT(op, 2, 2)]; + if (!no_imm || !BIT(op, 0, 2)) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, inst, BIT(op, 4, 4), BIT(op, 0, 2)); + return 2; + } + } + break; + + default: + { + auto const [inst, inst_ext_imm, inst_ext_reg] = class_1_ops[BIT(op, 8, 5)]; + char const *const fmt = ext.inst(inst, inst_ext_imm, inst_ext_reg); + if (!fmt) + return 0; + + util::stream_format(stream, fmt, BIT(op, 0, 4), BIT(op, 4, 4), 0x10 | BIT(op, 4, 4), ext.val); + return 2 + ext.size(); + } + } + + return 0; // catch invalid ext forms +} + + +offs_t c33_disassembler::dasm_class_2_3(std::ostream &stream, u16 op, ext_info const &ext) const +{ + auto const [inst, inst_ext_imm, mul] = class_2_3_ops[BIT(op, 10, 4)]; + char const *const fmt = ext.inst(inst, inst_ext_imm, nullptr); + if (!fmt) + return 0; + + u8 const reg = BIT(op, 0, 4); + u32 imm = (ext.val << 6) | BIT(op, 4, 6); + s32 simm = util::sext(imm, 6 + ext.bits()); + u32 abs = std::abs(simm); + char const *const sign = (0 > simm) ? "-" : ""; + if (ext_type::NONE == ext.type) + { + imm *= mul; + simm *= mul; + abs *= mul; + } + util::stream_format(stream, fmt, reg, imm, simm, abs, sign); + return 2 + ext.size(); +} + + +offs_t c33_disassembler::dasm_class_4(std::ostream &stream, u16 op, ext_info const &ext) const +{ + if (BIT(op, 11, 2) == 0) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, BIT(op, 10) ? "sub %%sp,0x%1$x" : "add %%sp,0x%1$x", BIT(op, 0, 10) * 4); + return 2; + } + else + { + auto const [inst, inst_ext_reg, no_dest] = class_4_ops[BIT(op, 8, 5)]; + if (!no_dest || !BIT(op, 0, 4)) + { + char const *const fmt = ext.inst(inst, nullptr, inst_ext_reg); + if (!fmt) + return 0; + + util::stream_format(stream, fmt, BIT(op, 0, 4), BIT(op, 4, 4), ext.val); + return 2 + ext.size(); + } + } + + return 0; // catch invalid forms of division instructions +} + + +offs_t c33_disassembler::dasm_class_5(std::ostream &stream, u16 op, ext_info const &ext) const +{ + if (BIT(op, 6, 7) == 0b111'11'00) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, "do.c 0x%1$x", BIT(op, 0, 6)); + return 2; + } + else if (BIT(op, 5, 8) == 0b111'11'01'0) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, "psrset %1$u", BIT(op, 0, 5)); + return 2; + } + else if (BIT(op, 5, 8) == 0b111'11'10'0) + { + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, "psrclr %1$u", BIT(op, 0, 5)); + return 2; + } + else + { + auto const [inst, inst_ext_imm, inst_ext_reg, target_bits, special_reg_pos] = class_5_ops[BIT(op, 8, 5)]; + char const *const special_reg = special_reg_pos ? special_reg_names[BIT(op, (special_reg_pos - 1) * 4, 4)] : nullptr; + if (inst && (!special_reg_pos || special_reg) && ((4 == target_bits) || !BIT(op, target_bits, 4 - target_bits))) + { + char const *const fmt = ext.inst(inst, inst_ext_imm, inst_ext_reg); + if (!fmt) + return 0; + + util::stream_format(stream, fmt, BIT(op, 0, 4), BIT(op, 4, 4), ext.val, special_reg); + return 2 + ext.size(); + } + } + + return 0; // catch invalid forms +} + + +offs_t c33_disassembler::dasm_class_6(std::ostream &stream, u16 op, ext_info const &ext) const +{ + if (ext_type::NONE != ext.type) + return 0; + + util::stream_format(stream, "ext 0x%1$x", BIT(op, 0, 13)); + return 2; +} + + +offs_t c33_disassembler::dasm_class_7(std::ostream &stream, u16 op, ext_info const &ext) const +{ + auto const [inst, inst_ext_imm, mul] = class_7_ops[BIT(op, 10, 3)]; + char const *const fmt = ext.inst(inst, inst_ext_imm, nullptr); + if (!fmt) + return 0; + + u8 const reg = BIT(op, 0, 4); + u32 imm = (ext.val << 6) | BIT(op, 4, 6); + if (ext_type::NONE == ext.type) + imm *= mul; + util::stream_format(stream, fmt, reg, imm); + return 2 + ext.size(); +} diff --git a/src/devices/cpu/c33/c33dasm.h b/src/devices/cpu/c33/c33dasm.h new file mode 100644 index 00000000000..4eee7652526 --- /dev/null +++ b/src/devices/cpu/c33/c33dasm.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson C33 disassembler +*/ + +#ifndef MAME_CPU_C33_C33DASM_H +#define MAME_CPU_C33_C33DASM_H + +#pragma once + + +class c33_disassembler : public util::disasm_interface +{ +public: + c33_disassembler(); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, data_buffer const &opcodes, data_buffer const ¶ms) override; + +private: + enum class ext_type { NONE, IMM13, IMM26, REG }; + + struct ext_info; + + offs_t dasm(std::ostream &stream, offs_t pc, u16 op, ext_info const &ext) const; + + offs_t dasm_class_0(std::ostream &stream, offs_t pc, u16 op, ext_info const &ext) const; + offs_t dasm_class_1(std::ostream &stream, u16 op, ext_info const &ext) const; + offs_t dasm_class_2_3(std::ostream &stream, u16 op, ext_info const &ext) const; + offs_t dasm_class_4(std::ostream &stream, u16 op, ext_info const &ext) const; + offs_t dasm_class_6(std::ostream &stream, u16 op, ext_info const &ext) const; + offs_t dasm_class_5(std::ostream &stream, u16 op, ext_info const &ext) const; + offs_t dasm_class_7(std::ostream &stream, u16 op, ext_info const &ext) const; +}; + +#endif // MAME_CPU_C33_C33DASM_H diff --git a/src/devices/cpu/c33/c33helpers.ipp b/src/devices/cpu/c33/c33helpers.ipp new file mode 100644 index 00000000000..38aaaa0a2f7 --- /dev/null +++ b/src/devices/cpu/c33/c33helpers.ipp @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson C33 shared helper functions and constants +*/ +#ifndef MAME_CPU_C33_C33HELPERS_IPP +#define MAME_CPU_C33_C33HELPERS_IPP + +#pragma once + + +enum +{ + PSR_BIT_N = 0, + PSR_BIT_Z = 1, + PSR_BIT_V = 2, + PSR_BIT_C = 3, + PSR_BIT_IE = 4, + PSR_BIT_DS = 6, + PSR_BIT_MO = 7, + PSR_BIT_IL = 8, + PSR_BIT_SV = 12, + PSR_BIT_ME = 13, + PSR_BIT_DE = 14, + PSR_BIT_S = 15, + PSR_BIT_HC = 16, + PSR_BIT_LC = 17, + PSR_BIT_SE = 20, + PSR_BIT_OC = 21, + PSR_BIT_SW = 22, + PSR_BIT_RC = 24, + PSR_BIT_PM = 28, + PSR_BIT_LM = 29, + PSR_BIT_RM = 30, + PSR_BIT_HE = 31 +}; + +enum : u32 +{ + PSR_MASK_N = u32(0x1) << PSR_BIT_N, + PSR_MASK_Z = u32(0x1) << PSR_BIT_Z, + PSR_MASK_V = u32(0x1) << PSR_BIT_V, + PSR_MASK_C = u32(0x1) << PSR_BIT_C, + PSR_MASK_IE = u32(0x1) << PSR_BIT_IE, + PSR_MASK_DS = u32(0x1) << PSR_BIT_DS, + PSR_MASK_MO = u32(0x1) << PSR_BIT_MO, + PSR_MASK_IL = u32(0xf) << PSR_BIT_IL, + PSR_MASK_SV = u32(0x1) << PSR_BIT_SV, + PSR_MASK_ME = u32(0x1) << PSR_BIT_ME, + PSR_MASK_DE = u32(0x1) << PSR_BIT_DE, + PSR_MASK_S = u32(0x1) << PSR_BIT_S, + PSR_MASK_HC = u32(0x1) << PSR_BIT_HC, + PSR_MASK_LC = u32(0x1) << PSR_BIT_LC, + PSR_MASK_SE = u32(0x1) << PSR_BIT_SE, + PSR_MASK_OC = u32(0x1) << PSR_BIT_OC, + PSR_MASK_SW = u32(0x1) << PSR_BIT_SW, + PSR_MASK_RC = u32(0xf) << PSR_BIT_RC, + PSR_MASK_PM = u32(0x1) << PSR_BIT_PM, + PSR_MASK_LM = u32(0x1) << PSR_BIT_LM, + PSR_MASK_RM = u32(0x1) << PSR_BIT_RM, + PSR_MASK_HE = u32(0x1) << PSR_BIT_HE +}; + +#endif // MAME_CPU_C33_C33HELPERS_IPP diff --git a/src/devices/cpu/c33/c33std.cpp b/src/devices/cpu/c33/c33std.cpp new file mode 100644 index 00000000000..a4b0438d1b3 --- /dev/null +++ b/src/devices/cpu/c33/c33std.cpp @@ -0,0 +1,117 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson C33 STD Core (S1C33000) +*/ + +#include "emu.h" +#include "c33std.h" + +#include "c33dasm.h" + +#include <algorithm> +#include <iterator> +#include <utility> + +#include "c33helpers.ipp" + + +c33std_cpu_device_base::c33std_cpu_device_base( + machine_config const &mconfig, + device_type type, + char const *tag, + device_t *owner, + u32 clock, + address_map_constructor internal_map) : + cpu_device(mconfig, type, tag, owner, clock), + m_memory_config("memory", ENDIANNESS_LITTLE, 16, 28, 0, internal_map), + m_icount(0) +{ +} + + +void c33std_cpu_device_base::device_start() +{ + set_icountptr(m_icount); + + space(AS_PROGRAM).cache(m_opcodes); + space(AS_PROGRAM).specific(m_data); + + std::fill(std::begin(m_gprs), std::end(m_gprs), 0); + m_pc = 0; + m_psr = 0; + m_sp = 0; + m_alr = 0; + m_ahr = 0; + + save_item(NAME(m_gprs)); + save_item(NAME(m_pc)); + save_item(NAME(m_psr)); + save_item(NAME(m_sp)); + save_item(NAME(m_alr)); + save_item(NAME(m_ahr)); + + state_add(STATE_GENPC, "PC", m_pc ).mask(0xffff'fffe); + state_add(STATE_GENPCBASE, "PCBASE", m_pc ).mask(0xffff'fffe).noshow(); + state_add(STATE_GENFLAGS, "GENGLAGS", m_psr ).mask(0x0000'0fdf).formatstr("%4s").noshow(); + state_add(C33_R0, "R0", m_gprs[0] ); + state_add(C33_R1, "R1", m_gprs[1] ); + state_add(C33_R2, "R2", m_gprs[2] ); + state_add(C33_R3, "R3", m_gprs[3] ); + state_add(C33_R4, "R4", m_gprs[4] ); + state_add(C33_R5, "R5", m_gprs[5] ); + state_add(C33_R6, "R6", m_gprs[6] ); + state_add(C33_R7, "R7", m_gprs[7] ); + state_add(C33_R8, "R8", m_gprs[8] ); + state_add(C33_R9, "R9", m_gprs[9] ); + state_add(C33_R10, "R10", m_gprs[10]); + state_add(C33_R11, "R11", m_gprs[11]); + state_add(C33_R12, "R12", m_gprs[12]); + state_add(C33_R13, "R13", m_gprs[13]); + state_add(C33_R14, "R14", m_gprs[14]); + state_add(C33_R15, "R15", m_gprs[15]); + state_add(C33_PSR, "PSR", m_psr ).mask(0x0000'0fdf); + state_add(C33_SP, "SP", m_sp ); + state_add(C33_ALR, "ALR", m_alr ); + state_add(C33_AHR, "AHR", m_ahr ); +} + + +void c33std_cpu_device_base::device_reset() +{ + m_psr = 0; +} + + +void c33std_cpu_device_base::execute_run() +{ + debugger_instruction_hook(m_pc); + m_icount = 0; +} + + +device_memory_interface::space_config_vector c33std_cpu_device_base::memory_space_config() const +{ + return space_config_vector{ std::make_pair(AS_PROGRAM, &m_memory_config) }; +} + + +std::unique_ptr<util::disasm_interface> c33std_cpu_device_base::create_disassembler() +{ + return std::make_unique<c33_disassembler>(); +} + + +void c33std_cpu_device_base::state_string_export(device_state_entry const &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = util::string_format("%c%c%c%c", + (m_psr & PSR_MASK_C) ? 'C' : 'c', + (m_psr & PSR_MASK_V) ? 'V' : 'v', + (m_psr & PSR_MASK_Z) ? 'Z' : 'z', + (m_psr & PSR_MASK_N) ? 'N' : 'n'); + break; + } +} diff --git a/src/devices/cpu/c33/c33std.h b/src/devices/cpu/c33/c33std.h new file mode 100644 index 00000000000..41ae2058210 --- /dev/null +++ b/src/devices/cpu/c33/c33std.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson C33 STD Core (S1C33000) +*/ + +#ifndef MAME_CPU_C33_C33STD_H +#define MAME_CPU_C33_C33STD_H + +#pragma once + +#include "c33common.h" + +#include <memory> +#include <string> + + +class c33std_cpu_device_base : public cpu_device, public c33_cpu_common +{ +protected: + c33std_cpu_device_base( + machine_config const &mconfig, + device_type type, + char const *tag, + device_t *owner, + u32 clock, + address_map_constructor internal_map); + + // device_t implementation + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + + // device_execute_interface implementation + virtual void execute_run() override; + + // device_memory_interface implementation + virtual space_config_vector memory_space_config() const override ATTR_COLD; + + // device_disassembler_interface implementation + std::unique_ptr<util::disasm_interface> create_disassembler() override ATTR_COLD; + + // device_state_interface implementation + void state_string_export(device_state_entry const &entry, std::string &str) const override; + + address_space_config const m_memory_config; + memory_access<28, 1, 0, ENDIANNESS_LITTLE>::cache m_opcodes; + memory_access<28, 1, 0, ENDIANNESS_LITTLE>::specific m_data; + + int m_icount; + u32 m_gprs[16]; + u32 m_pc; + u32 m_psr; + u32 m_sp; + u32 m_alr; + u32 m_ahr; +}; + +#endif // MAME_CPU_C33_C33STD_H diff --git a/src/devices/cpu/c33/s1c33209.cpp b/src/devices/cpu/c33/s1c33209.cpp new file mode 100644 index 00000000000..20a8a546f11 --- /dev/null +++ b/src/devices/cpu/c33/s1c33209.cpp @@ -0,0 +1,331 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson S1C33209/221/222 CMOS 32-bit single chip microcomputer +*/ + +#include "emu.h" +#include "s1c33209.h" + + +DEFINE_DEVICE_TYPE(S1C33209, s1c33209_device, "s1c33209", "Epson S1C33209") +DEFINE_DEVICE_TYPE(S1C33221, s1c33221_device, "s1c33221", "Epson S1C33221") +DEFINE_DEVICE_TYPE(S1C33222, s1c33222_device, "s1c33222", "Epson S1C33222") + + +s1c33209_device::s1c33209_device( + machine_config const &mconfig, + device_type type, + char const *tag, + device_t *owner, + u32 clock, + address_map_constructor internal_map) : + c33std_cpu_device_base(mconfig, type, tag, owner, clock, internal_map) +{ +} + +s1c33209_device::s1c33209_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + u32 clock) : + s1c33209_device( + mconfig, + S1C33209, + tag, + owner, + clock, + address_map_constructor(FUNC(s1c33209_device::memory_map<0>), this)) +{ +} + +s1c33221_device::s1c33221_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + u32 clock) : + s1c33209_device( + mconfig, + S1C33221, + tag, + owner, + clock, + address_map_constructor(FUNC(s1c33221_device::memory_map<128 * 1024>), this)) +{ +} + +s1c33222_device::s1c33222_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + u32 clock) : + s1c33209_device( + mconfig, + S1C33222, + tag, + owner, + clock, + address_map_constructor(FUNC(s1c33222_device::memory_map<64 * 1024>), this)) +{ +} + + +void s1c33209_device::device_reset() +{ + c33std_cpu_device_base::device_reset(); + + u32 const boot_vector = m_data.read_dword(0x0c0'0000); + m_pc = boot_vector; +} + + +template <offs_t RomBytes> +void s1c33209_device::memory_map(address_map &map) +{ + map(0x000'0000, 0x000'1fff).mirror(0x000'2000).ram(); // actually 32 bits wide (single cycle word access) + map(0x003'0000, 0x003'ffff).m(*this, FUNC(s1c33209_device::peripheral_map)); + map(0x004'0000, 0x004'ffff).mirror(0x001'0000).m(*this, FUNC(s1c33209_device::peripheral_map)); + //map(0x006'0000, 0x007'ffff) area 2 reserved for debug mode + //map(0x008'0000, 0xfff'ffff) area 3 reserved for middleware + //map(0x010'0000, 0x02f'ffff) area 4-5 external memory + //map(0x030'0000, 0x037'ffff) area 6 external 8-bit I/O + //map(0x038'0000, 0x03f'ffff) area 6 external 8-bit I/O + //map(0x040'0000, 0x0bf'ffff) area 7-9 external memory + if (RomBytes) + map(0xc0'0000, 0x0c0'0000 + RomBytes - 1).rom().region(DEVICE_SELF, 0); + //map(0x0c.'...., 0x0ff'ffff) area 10 external memory + //map(0x100'0000, 0xfff'ffff) area 11-18 external memory +} + +void s1c33209_device::peripheral_map(address_map &map) +{ + //map(0x0140, 0x0140) 8-bit timer 4-5 clock select + //map(0x0145, 0x0145) 8-bit timer 4-5 clock control + //map(0x0146, 0x0146) 8-bit timer 0-3 clock select + //map(0x0147, 0x0147) 16-bit timer 0 clock control + //map(0x0148, 0x0148) 16-bit timer 1 clock control + //map(0x0149, 0x0149) 16-bit timer 2 clock control + //map(0x014a, 0x014a) 16-bit timer 3 clock control + //map(0x014b, 0x014b) 16-bit timer 4 clock control + //map(0x014c, 0x014c) 16-bit timer 5 clock control + //map(0x014d, 0x014d) 8-bit timer 0-1 clock control + //map(0x014e, 0x014e) 8-bit timer 2-3 clock control + //map(0x014f, 0x014f) A/D clock control + + //map(0x0151, 0x0151) clock timer run/stop + //map(0x0152, 0x0152) clock timer interrupt control + //map(0x0153, 0x0153) clock timer divider + //map(0x0154, 0x0154) clock timer second + //map(0x0155, 0x0155) clock timer minute + //map(0x0156, 0x0156) clock timer hour + //map(0x0157, 0x0157) clock day (low) + //map(0x0158, 0x0158) clock day (high) + //map(0x0159, 0x0159) clock minute comparison + //map(0x015a, 0x015a) clock hour comparison + //map(0x015b, 0x015b) clock day comparison + + //map(0x0160, 0x0160) 8-bit timer 0 control + //map(0x0161, 0x0161) 8-bit timer 0 reload + //map(0x0162, 0x0162) 8-bit timer 0 counter data + //map(0x0164, 0x0164) 8-bit timer 1 control + //map(0x0165, 0x0165) 8-bit timer 1 reload + //map(0x0166, 0x0166) 8-bit timer 1 counter data + //map(0x0168, 0x0168) 8-bit timer 2 control + //map(0x0169, 0x0169) 8-bit timer 2 reload + //map(0x016a, 0x016a) 8-bit timer 2 counter data + //map(0x016c, 0x016c) 8-bit timer 3 control + //map(0x016d, 0x016d) 8-bit timer 3 reload + //map(0x016e, 0x016e) 8-bit timer 3 counter data + //map(0x0170, 0x0170) watchdog timer write-protect + //map(0x0171, 0x0171) watchdog timer enable + //map(0x0174, 0x0174) 8-bit timer 4 control + //map(0x0175, 0x0175) 8-bit timer 4 reload + //map(0x0176, 0x0176) 8-bit timer 4 counter data + //map(0x0178, 0x0178) 8-bit timer 5 control + //map(0x0179, 0x0179) 8-bit timer 5 reload + //map(0x017a, 0x017a) 8-bit timer 5 counter data + //map(0x0180, 0x0180) power control + //map(0x0181, 0x0181) prescaler clock select + //map(0x0190, 0x0190) clock option + //map(0x019e, 0x019e) power control protect + + //map(0x01e0, 0x01e0) serial interface ch. 0 transmit data + //map(0x01e1, 0x01e1) serial interface ch. 0 receive data + //map(0x01e2, 0x01e2) serial interface ch. 0 status + //map(0x01e3, 0x01e3) serial interface ch. 0 control + //map(0x01e4, 0x01e4) serial interface ch. 0 IrDA + //map(0x01e5, 0x01e5) serial interface ch. 1 transmit data + //map(0x01e6, 0x01e6) serial interface ch. 1 receive data + //map(0x01e7, 0x01e7) serial interface ch. 1 status + //map(0x01e8, 0x01e8) serial interface ch. 1 control + //map(0x01e9, 0x01e9) serial interface ch. 1 IrDA + //map(0x01f0, 0x01f0) serial interface ch. 2 transmit data + //map(0x01f1, 0x01f1) serial interface ch. 2 receive data + //map(0x01f2, 0x01f2) serial interface ch. 2 status + //map(0x01f3, 0x01f3) serial interface ch. 2 control + //map(0x01f4, 0x01f4) serial interface ch. 2 IrDA + //map(0x01f5, 0x01f5) serial interface ch. 3 transmit data + //map(0x01f6, 0x01f6) serial interface ch. 3 receive data + //map(0x01f7, 0x01f7) serial interface ch. 3 status + //map(0x01f8, 0x01f8) serial interface ch. 3 control + //map(0x01f9, 0x01f9) serial interface ch. 3 IrDA + + //map(0x0240, 0x0240) A/D conversion result (low) + //map(0x0241, 0x0241) A/D conversion result (high) + //map(0x0242, 0x0242) A/D trigger + //map(0x0243, 0x0243) A/D channel + //map(0x0244, 0x0244) A/D enable + //map(0x0245, 0x0245) A/D sampling + + //map(0x0260, 0x0260) port 0-1 interrupt priority + //map(0x0261, 0x0261) port 2-3 interrupt priority + //map(0x0262, 0x0262) key input interrupt priority + //map(0x0263, 0x0263) high-speed DMA ch.0-1 interrupt priority + //map(0x0264, 0x0264) high-speed DMA ch.2-3 interrupt priority + //map(0x0265, 0x0265) IDMA interrupt priority + //map(0x0266, 0x0266) 16-bit timer 0-1 interrupt priority + //map(0x0267, 0x0267) 16-bit timer 2-3 interrupt priority + //map(0x0268, 0x0268) 16-bit timer 4-5 interrupt priority + //map(0x0269, 0x0269) 8-bit timer and serial interface ch. 0 interrupt priority + //map(0x026a, 0x026a) serial interface ch. 1 and A/D interrupt priority + //map(0x026b, 0x026b) clock timer interrupt priority + //map(0x026c, 0x026c) port input 4-5 interrupt priority + //map(0x026d, 0x026d) port input 6-7 interrupt priority + //map(0x0270, 0x0270) key input and port 0-3 interrupt enable + //map(0x0271, 0x0271) DMA interrupt enable + //map(0x0272, 0x0272) 16-bit timer 0-1 interrupt enable + //map(0x0273, 0x0273) 16-bit timer 2-3 interrupt enable + //map(0x0274, 0x0274) 16-bit timer 4-5 interrupt enable + //map(0x0275, 0x0275) 8-bit timer interrupt enable + //map(0x0276, 0x0276) serial interface interrupt enable + //map(0x0277, 0x0277) port input 4-7, clock timer and A/D interrupt enable + //map(0x0280, 0x0280) key input and port 0-3 interrupt factor flag + //map(0x0281, 0x0281) DMA interrupt factor flag + //map(0x0282, 0x0282) 16-bit timer 0-1 interrupt factor flag + //map(0x0283, 0x0283) 16-bit timer 2-3 interrupt factor flag + //map(0x0284, 0x0284) 16-bit timer 4-5 interrupt factor flag + //map(0x0285, 0x0285) 8-bit timer interrupt factor flag + //map(0x0286, 0x0286) serial interface interrupt factor flag + //map(0x0287, 0x0287) port input 4-7, clock timer and A/D interrupt factor flag + //map(0x0290, 0x0290) port input 0-3, high-speed DMA ch. 0-1 and 16-bit timer 0 IDMA request + //map(0x0291, 0x0291) 16-bit timer 1-4 IDMA request + //map(0x0292, 0x0292) 16-bit timer 5, 8-bit timer and serial interface ch. 0 IDMA request + //map(0x0293, 0x0293) serial interface ch. 1, A/D and port input 4-7 IDMA request + //map(0x0294, 0x0294) port input 0-3, high-speed DMA ch. 0-1 and 16-bit timer 0 IDMA enable + //map(0x0295, 0x0295) 16-bit timer 1-4 IDMA enable + //map(0x0296, 0x0296) 16-bit timer 5, 8-bit timer and serial interface ch. 0 IDMA enable + //map(0x0297, 0x0297) serial interface ch. 1, A/D and port input 4-7 IDMA enable + //map(0x0298, 0x0298) high-speed DMA ch. 0-1 trigger setup + //map(0x0299, 0x0299) high-speed DMA ch. 2-3 trigger setup + //map(0x029a, 0x029a) high-speed DMA software trigger + //map(0x029f, 0x029f) flag set/reset method select + + //map(0x02c0, 0x02c0) K5 function select + //map(0x02c1, 0x02c1) K5 input port data + //map(0x02c3, 0x02c3) K6 function select + //map(0x02c4, 0x02c4) K6 input port data + //map(0x02c5, 0x02c5) interrupt factor FP function switching + //map(0x02c6, 0x02c6) port input interrupt select 1 + //map(0x02c7, 0x02c7) port input interrupt select 2 + //map(0x02c8, 0x02c8) port input interrupt input polarity select + //map(0x02c9, 0x02c9) port input interrupt edge/level select + //map(0x02ca, 0x02ca) key input interrupt select + //map(0x02cb, 0x02cb) interrupt factor TM16 function switching + //map(0x02cc, 0x02cc) key input interrupt (FPK0) input comparison + //map(0x02cd, 0x02cd) key input interrupt (FPK1) input comparison + //map(0x02ce, 0x02ce) key input interrupt (FPK0) input mask + //map(0x02cf, 0x02cf) key input interrupt (FPK1) input mask + //map(0x02d0, 0x02d0) P0 function select + //map(0x02d1, 0x02d1) P0 I/O port data + //map(0x02d2, 0x02d2) P0 I/O control + //map(0x02d4, 0x02d4) P1 function select + //map(0x02d5, 0x02d5) P1 I/O port data + //map(0x02d6, 0x02d6) P1 I/O control + //map(0x02d7, 0x02d7) port SIO function extension + //map(0x02d8, 0x02d8) P2 function select + //map(0x02d9, 0x02d9) P2 I/O port data + //map(0x02da, 0x02da) P2 I/O control + //map(0x02db, 0x02db) port SIO function extension + //map(0x02dc, 0x02dc) P2 function select + //map(0x02dd, 0x02dd) P2 I/O port data + //map(0x02de, 0x02de) P2 I/O control + //map(0x02df, 0x02df) port function extension + + //map(0x8120, 0x8121) area 15-18 setup + //map(0x8122, 0x8123) area 13-14 setup + //map(0x8124, 0x8125) area 11-12 setup + //map(0x8126, 0x8127) area 9-10 setup + //map(0x8128, 0x8129) area 7-8 setup + //map(0x812a, 0x812b) area 4-6 setup + //map(0x812d, 0x812d) TTBR write protect + //map(0x812e, 0x812e) bus control + //map(0x8130, 0x8131) DRAM timing setup + //map(0x8132, 0x8133) access control + //map(0x8134, 0x8135) TTBR low + //map(0x8136, 0x8137) TTBR high + //map(0x8138, 0x8139) G/A read signal control + //map(0x813a, 0x813a) BCLK select + + //map(0x8180, 0x8181) 16-bit timer 0 comparison A + //map(0x8182, 0x8183) 16-bit timer 0 comparison B + //map(0x8184, 0x8185) 16-bit timer 0 counter data + //map(0x8186, 0x8186) 16-bit timer 0 control + //map(0x8188, 0x8189) 16-bit timer 1 comparison A + //map(0x818a, 0x818b) 16-bit timer 1 comparison B + //map(0x818c, 0x818d) 16-bit timer 1 counter data + //map(0x818e, 0x818e) 16-bit timer 1 control + //map(0x8190, 0x8191) 16-bit timer 2 comparison A + //map(0x8192, 0x8193) 16-bit timer 2 comparison B + //map(0x8194, 0x8195) 16-bit timer 2 counter data + //map(0x8196, 0x8196) 16-bit timer 2 control + //map(0x8198, 0x8199) 16-bit timer 3 comparison A + //map(0x819a, 0x819b) 16-bit timer 3 comparison B + //map(0x819c, 0x819d) 16-bit timer 3 counter data + //map(0x819e, 0x819e) 16-bit timer 3 control + //map(0x81a0, 0x81a1) 16-bit timer 4 comparison A + //map(0x81a2, 0x81a3) 16-bit timer 4 comparison B + //map(0x81a4, 0x81a5) 16-bit timer 4 counter data + //map(0x81a6, 0x81a6) 16-bit timer 4 control + //map(0x81a8, 0x81a9) 16-bit timer 5 comparison A + //map(0x81aa, 0x81ab) 16-bit timer 5 comparison B + //map(0x81ac, 0x81ad) 16-bit timer 5 counter data + //map(0x81ae, 0x81ae) 16-bit timer 5 control + + //map(0x8200, 0x8201) IDMA base address low + //map(0x8202, 0x8203) IDMA base address high + //map(0x8204, 0x8204) IDMA start + //map(0x8205, 0x8205) IDMA enable + + //map(0x8220, 0x8221) high-speed DMA ch. 0 transfer counter + //map(0x8222, 0x8223) high-speed DMA ch. 0 control + //map(0x8224, 0x8225) high-speed DMA ch. 0 low-order source address set-up + //map(0x8226, 0x8227) high-speed DMA ch. 0 high-order source address set-up + //map(0x8228, 0x8229) high-speed DMA ch. 0 low-order destination address set-up + //map(0x822a, 0x822b) high-speed DMA ch. 0 high-order destination address set-up + //map(0x822c, 0x822d) high-speed DMA ch. 0 enable + //map(0x822e, 0x822f) high-speed DMA ch. 0 trigger flag + //map(0x8230, 0x8231) high-speed DMA ch. 1 transfer counter + //map(0x8232, 0x8233) high-speed DMA ch. 1 control + //map(0x8234, 0x8235) high-speed DMA ch. 1 low-order source address set-up + //map(0x8236, 0x8237) high-speed DMA ch. 1 high-order source address set-up + //map(0x8238, 0x8239) high-speed DMA ch. 1 low-order destination address set-up + //map(0x823a, 0x823b) high-speed DMA ch. 1 high-order destination address set-up + //map(0x823c, 0x823d) high-speed DMA ch. 1 enable + //map(0x823e, 0x823f) high-speed DMA ch. 1 trigger flag + //map(0x8240, 0x8241) high-speed DMA ch. 2 transfer counter + //map(0x8242, 0x8243) high-speed DMA ch. 2 control + //map(0x8244, 0x8245) high-speed DMA ch. 2 low-order source address set-up + //map(0x8246, 0x8247) high-speed DMA ch. 2 high-order source address set-up + //map(0x8248, 0x8249) high-speed DMA ch. 2 low-order destination address set-up + //map(0x824a, 0x824b) high-speed DMA ch. 2 high-order destination address set-up + //map(0x824c, 0x824d) high-speed DMA ch. 2 enable + //map(0x824e, 0x824f) high-speed DMA ch. 2 trigger flag + //map(0x8250, 0x8251) high-speed DMA ch. 3 transfer counter + //map(0x8252, 0x8253) high-speed DMA ch. 3 control + //map(0x8254, 0x8255) high-speed DMA ch. 3 low-order source address set-up + //map(0x8256, 0x8257) high-speed DMA ch. 3 high-order source address set-up + //map(0x8258, 0x8259) high-speed DMA ch. 3 low-order destination address set-up + //map(0x825a, 0x825b) high-speed DMA ch. 3 high-order destination address set-up + //map(0x825c, 0x825d) high-speed DMA ch. 3 enable + //map(0x825e, 0x825f) high-speed DMA ch. 3 trigger flag +} diff --git a/src/devices/cpu/c33/s1c33209.h b/src/devices/cpu/c33/s1c33209.h new file mode 100644 index 00000000000..b92fd094d5c --- /dev/null +++ b/src/devices/cpu/c33/s1c33209.h @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Epson S1C33209/221/222 CMOS 32-bit single chip microcomputer +*/ + +#ifndef MAME_CPU_C33_S1C33209_H +#define MAME_CPU_C33_S1C33209_H + +#pragma once + +#include "c33std.h" + + +class s1c33209_device : public c33std_cpu_device_base +{ +public: + s1c33209_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + +protected: + s1c33209_device( + machine_config const &mconfig, + device_type type, + char const *tag, + device_t *owner, + u32 clock, + address_map_constructor internal_map); + + template <offs_t RomBytes> void memory_map(address_map &map) ATTR_COLD; + +protected: + void device_reset() override ATTR_COLD; + +private: + void peripheral_map(address_map &map) ATTR_COLD; +}; + + +class s1c33221_device : public s1c33209_device +{ +public: + s1c33221_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); +}; + + +class s1c33222_device : public s1c33209_device +{ +public: + s1c33222_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); +}; + + +DECLARE_DEVICE_TYPE(S1C33209, s1c33209_device) +DECLARE_DEVICE_TYPE(S1C33221, s1c33221_device) +DECLARE_DEVICE_TYPE(S1C33222, s1c33222_device) + +#endif // MAME_CPU_C33_S1C33209_H |