summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mahlemiut <mahlemiut@users.noreply.github.com>2013-12-21 08:24:04 +0000
committer mahlemiut <mahlemiut@users.noreply.github.com>2013-12-21 08:24:04 +0000
commitfa26a13b8a3c870e0a5759dcc66f4fd9a0312ad2 (patch)
treedcbadc40e0fead93d4ac5ac977a7144cf48a86f7
parentb867663d4ce12f9e5f3764614309010e493644b6 (diff)
Added Signetics 8X300 microcontroller core, updated Wicat driver to use
it. [Barry Rodewald]
-rw-r--r--.gitattributes3
-rw-r--r--src/emu/cpu/8x300/8x300.c553
-rw-r--r--src/emu/cpu/8x300/8x300.h134
-rw-r--r--src/emu/cpu/8x300/8x300dasm.c149
-rw-r--r--src/emu/cpu/cpu.mak14
-rw-r--r--src/mess/drivers/wicat.c32
-rw-r--r--src/mess/mess.mak1
7 files changed, 879 insertions, 7 deletions
diff --git a/.gitattributes b/.gitattributes
index eb5315f9c96..490aaaf0159 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -919,6 +919,9 @@ src/emu/clifront.c svneol=native#text/plain
src/emu/clifront.h svneol=native#text/plain
src/emu/config.c svneol=native#text/plain
src/emu/config.h svneol=native#text/plain
+src/emu/cpu/8x300/8x300.c svneol=native#text/plain
+src/emu/cpu/8x300/8x300.h svneol=native#text/plain
+src/emu/cpu/8x300/8x300dasm.c svneol=native#text/plain
src/emu/cpu/adsp2100/2100dasm.c svneol=native#text/plain
src/emu/cpu/adsp2100/2100ops.c svneol=native#text/plain
src/emu/cpu/adsp2100/adsp2100.c svneol=native#text/plain
diff --git a/src/emu/cpu/8x300/8x300.c b/src/emu/cpu/8x300/8x300.c
new file mode 100644
index 00000000000..1d031be2d4a
--- /dev/null
+++ b/src/emu/cpu/8x300/8x300.c
@@ -0,0 +1,553 @@
+/*
+ * 8x300.c
+ *
+ * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 CPU
+ * Created on: 18/12/2013
+ *
+ * Written by Barry Rodewald
+ */
+
+#include "debugger.h"
+#include "8x300.h"
+
+#define FETCHOP(a) (m_direct->read_decrypted_word(a))
+#define CYCLES(x) do { m_icount -= (x); } while (0)
+#define READPORT(a) (m_io->read_byte(a))
+#define WRITEPORT(a,v) (m_io->write_byte((a), (v)))
+
+#define SRC ((opcode & 0x1f00) >> 8)
+#define DST (opcode & 0x001f)
+#define ROTLEN ((opcode & 0x00e0) >> 5)
+#define IMM8 (opcode & 0x00ff)
+#define IMM5 (opcode & 0x001f)
+#define ADDR (opcode & 0x1fff)
+#define OP ((opcode & 0xe000) >> 13)
+#define SRC_IS_RIGHT_BANK (opcode & 0x0800)
+#define DST_IS_RIGHT_BANK (opcode & 0x0008)
+#define SRC_LSB ((opcode & 0x0700) >> 8)
+#define DST_LSB (opcode & 0x0007)
+#define SET_PC(x) do { m_PC = (x); m_AR = m_PC; m_genPC = m_PC << 1; } while (0)
+// for XEC intruction, which sets the AR, but not PC, so that after the instruction at the relative address is done, execution
+// returns back to next instruction after XEC, unless a JMP or successful NZT is there.
+#define SET_AR(x) do { m_AR = (x); m_genPC = m_AR << 1; m_PC--;} while (0)
+#define SRC_LATCH do { if(SRC_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0)
+#define DST_LATCH do { if(DST_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0)
+#define SET_OVF do { if(result & 0xff00) m_OVF = 1; else m_OVF = 0; } while (0)
+
+const device_type N8X300 = &device_creator<n8x300_cpu_device>;
+
+
+n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : cpu_device(mconfig, N8X300, "Signetics 8X300", tag, owner, clock, "8x300", __FILE__)
+ , m_program_config("program", ENDIANNESS_BIG, 16, 14, 0)
+ , m_io_config("io", ENDIANNESS_BIG, 8, 9, 0)
+{
+}
+
+void n8x300_cpu_device::set_reg(UINT8 reg, UINT8 val)
+{
+ switch(reg)
+ {
+ case 0x00: m_AUX = val; break;
+ case 0x01: m_R1 = val; break;
+ case 0x02: m_R2 = val; break;
+ case 0x03: m_R3 = val; break;
+ case 0x04: m_R4 = val; break;
+ case 0x05: m_R5 = val; break;
+ case 0x06: m_R6 = val; break;
+ case 0x07: m_IVL = val; break;
+// OVF is read-only
+ case 0x09: m_R11 = val; break;
+ case 0x0f: m_IVR = val; break;
+ default: logerror("8X300: Invalid register %02x written to.\n",reg); break;
+ }
+}
+
+UINT8 n8x300_cpu_device::get_reg(UINT8 reg)
+{
+ switch(reg)
+ {
+ case 0x00: return m_AUX;
+ case 0x01: return m_R1;
+ case 0x02: return m_R2;
+ case 0x03: return m_R3;
+ case 0x04: return m_R4;
+ case 0x05: return m_R5;
+ case 0x06: return m_R6;
+// IVL is write-only
+ case 0x08: return m_OVF;
+ case 0x09: return m_R11;
+// IVR is write-only
+ default: logerror("8X300: Invalid register %02x read.\n",reg); return 0;
+ }
+ return 0;
+}
+
+void n8x300_cpu_device::device_start()
+{
+ m_program = &space(AS_PROGRAM);
+ m_direct = &m_program->direct();
+ m_io = &space(AS_IO);
+
+ save_item(NAME(m_PC));
+ save_item(NAME(m_AR));
+ save_item(NAME(m_IR));
+ save_item(NAME(m_R1));
+ save_item(NAME(m_R2));
+ save_item(NAME(m_R3));
+ save_item(NAME(m_R4));
+ save_item(NAME(m_R5));
+ save_item(NAME(m_R6));
+ save_item(NAME(m_R11));
+ save_item(NAME(m_AUX));
+ save_item(NAME(m_IVL));
+ save_item(NAME(m_IVR));
+ save_item(NAME(m_OVF));
+ save_item(NAME(m_left_IV));
+ save_item(NAME(m_right_IV));
+
+ // Register state for debugger
+ state_add( _8X300_PC, "PC", m_PC).mask(0x1fff).formatstr("%04X");
+ state_add( _8X300_AR, "AR", m_AR).mask(0x1fff).formatstr("%04X");
+ state_add( _8X300_IR, "IR", m_IR).mask(0xffff).formatstr("%04X");
+ state_add( _8X300_AUX, "AUX", m_AUX).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R1, "R1", m_R1).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R2, "R2", m_R2).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R3, "R3", m_R3).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R4, "R4", m_R4).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R5, "R5", m_R5).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R6, "R6", m_R6).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R11, "R11", m_R11).mask(0xff).formatstr("%02X");
+ state_add( _8X300_OVF, "OVF", m_OVF).mask(0x01).formatstr("%01X");
+ state_add( _8X300_IVL, "IVL", m_IVL).mask(0xff).formatstr("%02X");
+ state_add( _8X300_IVR, "IVR", m_IVR).mask(0xff).formatstr("%02X");
+ state_add(STATE_GENPC, "curpc", m_genPC).noshow();
+
+ m_icountptr = &m_icount;
+
+ // reset registers here, since they are unchanged when /RESET goes low.
+ m_R1 = 0;
+ m_R2 = 0;
+ m_R3 = 0;
+ m_R4 = 0;
+ m_R5 = 0;
+ m_R6 = 0;
+ m_R11 = 0;
+ m_IVL = 0;
+ m_IVR = 0;
+ m_AUX = 0;
+}
+
+void n8x300_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
+{
+ switch (entry.index())
+ {
+// case STATE_GENFLAGS:
+// string.printf("%c%c%c%c%c%c",
+// break;
+ }
+}
+
+void n8x300_cpu_device::device_reset()
+{
+ /* zero registers */
+ m_PC = 0;
+ m_AR = 0;
+ m_IR = 0;
+}
+
+void n8x300_cpu_device::execute_run()
+{
+ do
+ {
+ UINT16 opcode;
+ UINT8 src = 0;
+ UINT8 dst;
+ UINT8 rotlen; // rotate amount or I/O field length
+ UINT8 mask;
+ UINT16 result;
+
+ /* fetch the opcode */
+ debugger_instruction_hook(this, m_genPC);
+ opcode = FETCHOP(m_genPC);
+ m_PC++;
+ m_PC &= 0x1fff;
+ m_AR = m_PC;
+ m_IR = opcode;
+ m_genPC = m_PC << 1;
+
+ switch (OP)
+ {
+ case 0x00: // MOVE
+ rotlen = ROTLEN;
+ if(is_rot(opcode)) // MOVE reg,reg
+ {
+ src = get_reg(SRC);
+ dst = rotate(src,rotlen);
+ set_reg(DST,dst);
+ }
+ else
+ {
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
+ { // MOVE reg,IV
+ DST_LATCH;
+ mask = ((1 << rotlen)-1);
+ src = (get_reg(SRC)) << (7-DST_LSB);
+ mask <<= (7-DST_LSB);
+ if(DST_IS_RIGHT_BANK)
+ {
+ dst = (m_right_IV & ~mask) | (src & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (src & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
+ { // MOVE IV,reg
+ SRC_LATCH;
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB);
+ else
+ src = rotate(m_left_IV,7-SRC_LSB);
+ mask = ((1 << rotlen)-1);
+ dst = src & mask;
+ set_reg(DST,dst);
+ }
+ else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
+ { // MOVE IV,IV
+ SRC_LATCH;
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB);
+ else
+ src = rotate(m_left_IV,7-SRC_LSB);
+ mask = ((1 << rotlen)-1);
+ dst = src & mask;
+ dst <<= (7-DST_LSB);
+ mask <<= (7-DST_LSB);
+ if(SRC_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV
+ {
+ dst = (m_right_IV & ~mask) | (dst & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (dst & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ }
+ break;
+ case 0x01: // ADD
+ rotlen = ROTLEN;
+ if(is_rot(opcode))
+ { // ADD reg,reg
+ src = rotate(get_reg(SRC),rotlen);
+ result = src + m_AUX;
+ set_reg(DST,result & 0xff);
+ SET_OVF;
+ }
+ else
+ {
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
+ { // ADD reg,IV
+ DST_LATCH;
+ result = get_reg(SRC) + m_AUX;
+ mask = ((1 << rotlen)-1);
+ dst = (result & 0xff) << DST_LSB;
+ mask <<= DST_LSB;
+ SET_OVF;
+ if(DST_IS_RIGHT_BANK)
+ {
+ dst = (m_right_IV & ~mask) | (dst & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (dst & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
+ { // ADD IV,reg
+ SRC_LATCH;
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB) & mask;
+ else
+ src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ result = src + m_AUX;
+ SET_OVF;
+ set_reg(DST,result & 0xff);
+ }
+ else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
+ { // ADD IV,IV
+ SRC_LATCH;
+ DST_LATCH;
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB) & mask;
+ else
+ src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ result = src + m_AUX;
+ SET_OVF;
+ dst = (result << (7-DST_LSB)) & 0xff;
+ mask <<= (7-DST_LSB);
+ if(SRC_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data
+ {
+ dst = (m_right_IV & ~mask) | (dst & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (dst & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ }
+ break;
+ case 0x02: // AND
+ rotlen = ROTLEN;
+ if(is_rot(opcode))
+ { // AND reg,reg
+ src = rotate(get_reg(SRC),rotlen);
+ dst = src & m_AUX;
+ set_reg(DST,dst);
+ }
+ else
+ {
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
+ { // AND reg,IV
+ DST_LATCH;
+ src = get_reg(SRC) & m_AUX;
+ mask = ((1 << rotlen)-1);
+ src <<= (7-DST_LSB);
+ mask <<= (7-DST_LSB);
+ if(DST_IS_RIGHT_BANK)
+ {
+ dst = (m_right_IV & ~mask) | (src & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (src & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
+ { // AND IV,reg
+ SRC_LATCH;
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB) & mask;
+ else
+ src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ src &= mask;
+ dst = src & m_AUX;
+ set_reg(DST,dst);
+ }
+ else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
+ { // AND IV,IV
+ SRC_LATCH;
+ DST_LATCH;
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB) & mask;
+ else
+ src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ src &= mask;
+ dst = src & m_AUX;
+ dst <<= (7-DST_LSB);
+ mask <<= (7-DST_LSB);
+ if(SRC_IS_RIGHT_BANK)
+ {
+ dst = (m_right_IV & ~mask) | (src & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (src & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ }
+ break;
+ case 0x03: // XOR
+ rotlen = ROTLEN;
+ if(is_rot(opcode))
+ { // AND reg,reg
+ src = rotate(get_reg(SRC),rotlen);
+ dst = src ^ m_AUX;
+ set_reg(DST,dst);
+ }
+ else
+ {
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
+ { // AND reg,IV
+ DST_LATCH;
+ src = get_reg(SRC) ^ m_AUX;
+ mask = ((1 << rotlen)-1);
+ src <<= (7-DST_LSB);
+ mask <<= (7-DST_LSB);
+ if(DST_IS_RIGHT_BANK)
+ {
+ dst = (m_right_IV & ~mask) | (src & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (src & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
+ { // AND IV,reg
+ SRC_LATCH;
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB) & mask;
+ else
+ src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ src &= mask;
+ dst = src ^ m_AUX;
+ set_reg(DST,dst);
+ }
+ else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
+ { // AND IV,IV
+ SRC_LATCH;
+ DST_LATCH;
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB) & mask;
+ else
+ src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ src &= mask;
+ dst = src ^ m_AUX;
+ dst <<= (7-DST_LSB);
+ mask <<= (7-DST_LSB);
+ if(SRC_IS_RIGHT_BANK)
+ {
+ dst = (m_right_IV & ~mask) | (src & mask);
+ m_right_IV = dst;
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ dst = (m_left_IV & ~mask) | (src & mask);
+ m_left_IV = dst;
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ }
+ break;
+ case 0x04: // XEC (Execute)
+ if(is_src_reg(opcode))
+ {
+ src = get_reg(SRC);
+ src += IMM8;
+ SET_AR((m_AR & 0x1f00) | src);
+ }
+ else
+ {
+ SRC_LATCH;
+ rotlen = ROTLEN;
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB);
+ else
+ src = rotate(m_left_IV,7-SRC_LSB);
+ src &= mask;
+ src += IMM5;
+ SET_AR((m_AR & 0x1fe0) | (src & 0x1f));
+ }
+ break;
+ case 0x05: // NZT (Non-zero transfer)
+ if(is_src_reg(opcode))
+ {
+ src = get_reg(SRC);
+ if(src != 0)
+ SET_PC((m_PC & 0x1f00) | IMM8);
+ }
+ else
+ {
+ SRC_LATCH;
+ rotlen = ROTLEN;
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ mask = ((1 << rotlen)-1);
+ if(SRC_IS_RIGHT_BANK)
+ src = rotate(m_right_IV,7-SRC_LSB);
+ else
+ src = rotate(m_left_IV,7-SRC_LSB);
+ rotate(src,SRC_LSB);
+ src &= mask;
+ if(src != 0)
+ SET_PC((m_PC & 0x1fe0) | IMM5);
+ }
+ break;
+ case 0x06: // XMIT (Transmit)
+ // the source is actually the destination for this instruction
+ if(is_src_reg(opcode))
+ set_reg(SRC,IMM8);
+ else
+ {
+ SRC_LATCH;
+ rotlen = ROTLEN;
+ if(rotlen == 0)
+ rotlen = 8; // 0 = 8-bit I/O field length
+ mask = ((1 << rotlen)-1);
+ dst = IMM5;
+ mask <<= (7-SRC_LSB);
+ dst <<= (7-SRC_LSB);
+ if(SRC_IS_RIGHT_BANK)
+ {
+ m_right_IV = (m_right_IV & ~mask) | (dst & mask);
+ WRITEPORT(m_IVR+0x100,m_right_IV);
+ }
+ else
+ {
+ m_left_IV = (m_left_IV & ~mask) | (dst & mask);
+ WRITEPORT(m_IVL,m_left_IV);
+ }
+ }
+ break;
+ case 0x07: // JMP
+ SET_PC(ADDR);
+ break;
+ }
+ CYCLES(1); // all instructions take 1 cycle (250ns)
+ } while (m_icount > 0);
+}
+
+offs_t n8x300_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( n8x300 );
+ return CPU_DISASSEMBLE_NAME(n8x300)(this, buffer, pc, oprom, opram, options);
+}
+
diff --git a/src/emu/cpu/8x300/8x300.h b/src/emu/cpu/8x300/8x300.h
new file mode 100644
index 00000000000..f05ec299551
--- /dev/null
+++ b/src/emu/cpu/8x300/8x300.h
@@ -0,0 +1,134 @@
+/*
+ * 8x300.h
+ *
+ * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 Microcontroller
+ * Created on: 18/12/2013
+ */
+
+#ifndef _8X300_H_
+#define _8X300_H_
+
+// Register enumeration
+enum
+{
+ _8X300_PC = 1,
+ _8X300_AR,
+ _8X300_IR,
+ _8X300_AUX,
+ _8X300_R1,
+ _8X300_R2,
+ _8X300_R3,
+ _8X300_R4,
+ _8X300_R5,
+ _8X300_R6,
+ _8X300_IVL,
+ _8X300_OVF,
+ _8X300_R11,
+ _8X300_UNUSED12,
+ _8X300_UNUSED13,
+ _8X300_UNUSED14,
+ _8X300_UNUSED15,
+ _8X300_UNUSED16,
+ _8X300_IVR,
+ _8X300_LIV,
+ _8X300_RIV,
+ _8X300_GENPC
+};
+
+class n8x300_cpu_device : public cpu_device
+{
+public:
+ // construction/destruction
+ n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const { return 1; }
+ virtual UINT32 execute_max_cycles() const { return 1; }
+ virtual UINT32 execute_input_lines() const { return 0; }
+ virtual void execute_run();
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const
+ {
+ switch (spacenum)
+ {
+ case AS_PROGRAM: return &m_program_config;
+ case AS_IO: return &m_io_config;
+ default: return NULL;
+ }
+ }
+
+ // device_state_interface overrides
+ void state_string_export(const device_state_entry &entry, astring &string);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const { return 2; }
+ virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ address_space_config m_program_config;
+ address_space_config m_io_config;
+
+ int m_icount;
+
+ address_space *m_program;
+ direct_read_data *m_direct;
+ address_space *m_io;
+
+ UINT16 m_PC; // Program Counter
+ UINT16 m_AR; // Address Register
+ UINT16 m_IR; // Instruction Register
+ UINT8 m_AUX; // Auxiliary Register (second operand for AND, ADD, XOR)
+ UINT8 m_R1;
+ UINT8 m_R2;
+ UINT8 m_R3;
+ UINT8 m_R4;
+ UINT8 m_R5;
+ UINT8 m_R6;
+ UINT8 m_R11;
+ UINT8 m_IVL; // Interface vector (I/O) left bank (write-only)
+ UINT8 m_IVR; // Interface vector (I/O) right bank (write-only)
+ UINT8 m_OVF; // Overflow register (read-only)
+ UINT16 m_genPC;
+
+ UINT8 m_left_IV; // IV bank contents, these are latched when IVL or IVR are set
+ UINT8 m_right_IV;
+
+private:
+ inline bool is_rot(UINT16 opcode)
+ {
+ if((opcode & 0x1000) || (opcode & 0x0010))
+ return false;
+ else
+ return true;
+ }
+ inline bool is_src_reg(UINT16 opcode)
+ {
+ if((opcode & 0x1000))
+ return false;
+ else
+ return true;
+ }
+ inline bool is_dst_reg(UINT16 opcode)
+ {
+ if((opcode & 0x0010))
+ return false;
+ else
+ return true;
+ }
+ inline UINT8 rotate(UINT8 s, UINT8 n) // right rotate
+ {
+ return ((s & ((UINT8)0xff << n)) >> n) | ((s & ((UINT8)0xff >> (8-n))) << (8-n));
+ }
+ void set_reg(UINT8 reg,UINT8 val);
+ UINT8 get_reg(UINT8 reg);
+};
+
+extern const device_type N8X300;
+
+#endif /* 8X300_H_ */
diff --git a/src/emu/cpu/8x300/8x300dasm.c b/src/emu/cpu/8x300/8x300dasm.c
new file mode 100644
index 00000000000..707b3ccdb6e
--- /dev/null
+++ b/src/emu/cpu/8x300/8x300dasm.c
@@ -0,0 +1,149 @@
+/*
+ * 8x300dasm.c
+ * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 Microcontroller
+ *
+ * Created on: 18/12/2013
+ */
+
+#include "emu.h"
+#include "8x300.h"
+
+#define SRC ((opcode & 0x1f00) >> 8)
+#define DST (opcode & 0x001f)
+#define ROTLEN ((opcode & 0x00e0) >> 5)
+#define IMM8 (opcode & 0x00ff)
+#define IMM5 (opcode & 0x001f)
+
+static const char *reg_names[32] =
+{
+ "AUX", "R1", "R2", "R3", "R4", "R5", "R6", "IVL", "OVF", "R11",
+ "Unused12", "Unused13", "Unused14", "Unused15", "Unused16", "IVR",
+ "LIV0", "LIV1", "LIV2", "LIV3", "LIV4", "LIV5", "LIV6", "LIV7",
+ "RIV0", "RIV1", "RIV2", "RIV3", "RIV4", "RIV5", "RIV6", "RIV7"
+};
+
+// determines if right rotate or I/O field length is to be used
+INLINE bool is_rot(UINT16 opcode)
+{
+ if((opcode & 0x1000) || (opcode & 0x0010))
+ return false;
+ else
+ return true;
+}
+
+INLINE bool is_src_rot(UINT16 opcode)
+{
+ if((opcode & 0x1000))
+ return false;
+ else
+ return true;
+}
+
+CPU_DISASSEMBLE( n8x300 )
+{
+ char tmp[16];
+ unsigned startpc = pc;
+ UINT16 opcode = (oprom[pc - startpc] << 8) | oprom[pc+1 - startpc];
+ UINT8 inst = opcode >> 13;
+ pc+=2;
+
+ // determine instruction
+ switch (inst)
+ {
+ case 0x00:
+ sprintf(buffer,"MOVE ");
+ strcat(buffer,reg_names[SRC]);
+ if(is_rot(opcode))
+ sprintf(tmp,"(%i),",ROTLEN);
+ else
+ sprintf(tmp,",%i,",ROTLEN);
+ strcat(buffer,tmp);
+ strcat(buffer,reg_names[DST]);
+ break;
+ case 0x01:
+ sprintf(buffer,"ADD ");
+ strcat(buffer,reg_names[SRC]);
+ if(is_rot(opcode))
+ sprintf(tmp,"(%i),",ROTLEN);
+ else
+ sprintf(tmp,",%i,",ROTLEN);
+ strcat(buffer,tmp);
+ strcat(buffer,reg_names[DST]);
+ break;
+ case 0x02:
+ sprintf(buffer,"AND ");
+ strcat(buffer,reg_names[SRC]);
+ if(is_rot(opcode))
+ sprintf(tmp,"(%i),",ROTLEN);
+ else
+ sprintf(tmp,",%i,",ROTLEN);
+ strcat(buffer,tmp);
+ strcat(buffer,reg_names[DST]);
+ break;
+ case 0x03:
+ sprintf(buffer,"XOR ");
+ strcat(buffer,reg_names[SRC]);
+ if(is_rot(opcode))
+ sprintf(tmp,"(%i),",ROTLEN);
+ else
+ sprintf(tmp,",%i,",ROTLEN);
+ strcat(buffer,tmp);
+ strcat(buffer,reg_names[DST]);
+ break;
+ case 0x04:
+ sprintf(buffer,"XEC ");
+ strcat(buffer,reg_names[SRC]);
+ if(is_src_rot(opcode))
+ {
+ sprintf(tmp,",%02XH",IMM8);
+ strcat(buffer,tmp);
+ }
+ else
+ {
+ sprintf(tmp,",%i",ROTLEN);
+ strcat(buffer,tmp);
+ sprintf(tmp,",%02XH",IMM5);
+ strcat(buffer,tmp);
+ }
+ break;
+ case 0x05:
+ sprintf(buffer,"NZT ");
+ strcat(buffer,reg_names[SRC]);
+ if(is_src_rot(opcode))
+ {
+ sprintf(tmp,",%02XH",IMM8);
+ strcat(buffer,tmp);
+ }
+ else
+ {
+ sprintf(tmp,",%i",ROTLEN);
+ strcat(buffer,tmp);
+ sprintf(tmp,",%02XH",IMM5);
+ strcat(buffer,tmp);
+ }
+ break;
+ case 0x06:
+ sprintf(buffer,"XMIT ");
+ if(is_src_rot(opcode))
+ {
+ sprintf(tmp,"%02XH,",IMM8);
+ strcat(buffer,tmp);
+ strcat(buffer,reg_names[SRC]);
+ }
+ else
+ {
+ sprintf(tmp,"%02XH,",IMM5);
+ strcat(buffer,tmp);
+ strcat(buffer,reg_names[SRC]);
+ sprintf(tmp,",%i",ROTLEN);
+ strcat(buffer,tmp);
+ }
+ break;
+ case 0x07:
+ sprintf(buffer,"JMP %04XH",opcode & 0x1fff);
+ break;
+ }
+
+
+ return (pc - startpc);
+}
diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak
index de12ce64349..d0d955c98c1 100644
--- a/src/emu/cpu/cpu.mak
+++ b/src/emu/cpu/cpu.mak
@@ -67,6 +67,20 @@ $(DRCOBJ): $(DRCDEPS)
#-------------------------------------------------
+# Signetics 8X300 / Scientific Micro Systems SMS300
+#@src/emu/cpu/8x300/8x300.h,CPUS += 8X300
+#-------------------------------------------------
+
+ifneq ($(filter 8X300,$(CPUS)),)
+OBJDIRS += $(CPUOBJ)/8x300
+CPUOBJS += $(CPUOBJ)/8x300/8x300.o
+DASMOBJS += $(CPUOBJ)/8x300/8x300dasm.o
+endif
+
+$(CPUOBJ)/8x300/8x300.o: $(CPUSRC)/8x300/8x300.c \
+ $(CPUSRC)/8x300/8x300.h
+
+#-------------------------------------------------
# Acorn ARM series
#
#@src/emu/cpu/arm/arm.h,CPUS += ARM
diff --git a/src/mess/drivers/wicat.c b/src/mess/drivers/wicat.c
index 08694eef7fa..68f29a155ae 100644
--- a/src/mess/drivers/wicat.c
+++ b/src/mess/drivers/wicat.c
@@ -11,6 +11,7 @@ Wicat - various systems.
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z8000/z8000.h"
+#include "cpu/8x300/8x300.h"
#include "machine/serial.h"
#include "machine/6522via.h"
#include "machine/mm58274c.h"
@@ -19,6 +20,7 @@ Wicat - various systems.
#include "video/i8275x.h"
#include "machine/am9517a.h"
#include "machine/x2212.h"
+#include "machine/wd17xx.h"
#include "wicat.lh"
class wicat_state : public driver_device
@@ -159,6 +161,16 @@ static ADDRESS_MAP_START(wicat_video_io, AS_IO, 8, wicat_state)
AM_RANGE(0x9000,0x9fff) AM_ROM AM_REGION("g2char",0x0000)
ADDRESS_MAP_END
+static ADDRESS_MAP_START(wicat_flop_mem, AS_PROGRAM, 16, wicat_state)
+ AM_RANGE(0x0000, 0x17ff) AM_ROM AM_REGION("wd3", 0x0000)
+ AM_RANGE(0x1800, 0x1fff) AM_NOP
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(wicat_flop_io, AS_IO, 8, wicat_state)
+ AM_RANGE(0x0000, 0x00ff) AM_RAM // left bank
+ AM_RANGE(0x0100, 0x01ff) AM_RAM // right bank -- one of these probably is RAM...
+ADDRESS_MAP_END
+
/* Input ports */
static INPUT_PORTS_START( wicat )
@@ -673,8 +685,8 @@ static MACHINE_CONFIG_START( wicat, wicat_state )
MCFG_X2212_ADD("videosram") // XD2210
MCFG_SCREEN_ADD("screen",RASTER)
- MCFG_SCREEN_SIZE(400,300)
- MCFG_SCREEN_VISIBLE_AREA(0,400-1,0,300-1)
+ MCFG_SCREEN_SIZE(720,300)
+ MCFG_SCREEN_VISIBLE_AREA(0,720-1,0,300-1)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_UPDATE_DEVICE("video",i8275x_device,screen_update)
@@ -684,6 +696,12 @@ static MACHINE_CONFIG_START( wicat, wicat_state )
MCFG_DEFAULT_LAYOUT(layout_wicat)
+ /* Winchester Floppy Controller */
+ MCFG_CPU_ADD("floppycpu",N8X300,XTAL_8MHz)
+ MCFG_CPU_PROGRAM_MAP(wicat_flop_mem)
+ MCFG_CPU_IO_MAP(wicat_flop_io)
+// MCFG_FD1795_ADD("fdc")
+
MACHINE_CONFIG_END
/* ROM definition */
@@ -750,14 +768,14 @@ ROM_START( wicat )
ROM_LOAD ("apl.chr", 0x00800, 0x0800, CRC(8c6d698e) SHA1(147dd9296fe2efc6140fa148a6edf673c33f9371) )
// Winchester Floppy Controller (Signetics N8X300I + FD1795)
- ROM_REGION(0x1800, "wd3", 0)
- ROM_LOAD ("wd3.u95", 0x00000, 0x0800, CRC(80bb0617) SHA1(ac0f3194fcbef77532571baa3fec78b3010528bf) )
- ROM_LOAD ("wd3.u96", 0x00800, 0x0800, CRC(52736e61) SHA1(71c7c9170c733c483393969cb1cb3798b3eb980c) )
- ROM_LOAD ("wd3.u97", 0x01000, 0x0800, CRC(a66619ec) SHA1(5d091ac7c88f2f45b4a05e78bfc7a16c206b31ff) )
+ ROM_REGION16_BE(0x1800, "wd3", 0)
+ ROM_LOAD16_BYTE("wd3.u96", 0x00000, 0x0800, CRC(52736e61) SHA1(71c7c9170c733c483393969cb1cb3798b3eb980c) )
+ ROM_LOAD16_BYTE("wd3.u97", 0x00001, 0x0800, CRC(a66619ec) SHA1(5d091ac7c88f2f45b4a05e78bfc7a16c206b31ff) )
+ ROM_LOAD ("wd3.u95", 0x01000, 0x0800, CRC(80bb0617) SHA1(ac0f3194fcbef77532571baa3fec78b3010528bf) )
ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP( 198?, wicat, 0, 0, wicat, wicat, driver_device, 0, "Millennium Systems", "Wicat", GAME_NOT_WORKING | GAME_NO_SOUND_HW )
+COMP( 1982, wicat, 0, 0, wicat, wicat, driver_device, 0, "Millennium Systems", "Wicat System 150", GAME_NOT_WORKING | GAME_NO_SOUND_HW )
diff --git a/src/mess/mess.mak b/src/mess/mess.mak
index 5605bb9f103..c3494958f97 100644
--- a/src/mess/mess.mak
+++ b/src/mess/mess.mak
@@ -129,6 +129,7 @@ CPUS += SCORE
CPUS += ES5510
CPUS += SCUDSP
CPUS += IE15
+CPUS += 8X300
#-------------------------------------------------
# specify available sound cores; some of these are