summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/rw5000/b5000.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/rw5000/b5000.cpp')
-rw-r--r--src/devices/cpu/rw5000/b5000.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/devices/cpu/rw5000/b5000.cpp b/src/devices/cpu/rw5000/b5000.cpp
new file mode 100644
index 00000000000..685fb1b5190
--- /dev/null
+++ b/src/devices/cpu/rw5000/b5000.cpp
@@ -0,0 +1,164 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ Rockwell B5000 MCU
+
+TODO:
+- is unmapped ram mirrored? (that goes for subdevices too)
+- not sure how 7seg zero suppression works, the only documentation for it
+ is a block diagram with the logic connected to the 7seg decoder
+- fill unknown data in segment decoder, it's not on a neat PLA
+- is ATB an unskippable opcode? nothing relies on it
+
+*/
+
+#include "emu.h"
+#include "b5000.h"
+
+#include "rw5000d.h"
+
+
+DEFINE_DEVICE_TYPE(B5000, b5000_cpu_device, "b5000", "Rockwell B5000")
+
+
+// constructor
+b5000_cpu_device::b5000_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
+ rw5000_base_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
+{ }
+
+b5000_cpu_device::b5000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ b5000_cpu_device(mconfig, B5000, tag, owner, clock, 9, address_map_constructor(FUNC(b5000_cpu_device::program_448x8), this), 6, address_map_constructor(FUNC(b5000_cpu_device::data_45x4), this))
+{ }
+
+
+// internal memory maps
+void b5000_cpu_device::program_448x8(address_map &map)
+{
+ map(0x000, 0x0bf).rom();
+ map(0x100, 0x1ff).rom();
+}
+
+void b5000_cpu_device::data_45x4(address_map &map)
+{
+ map(0x00, 0x0b).ram();
+ map(0x10, 0x1a).ram();
+ map(0x20, 0x2a).ram();
+ map(0x30, 0x3a).ram();
+}
+
+
+// disasm
+std::unique_ptr<util::disasm_interface> b5000_cpu_device::create_disassembler()
+{
+ return std::make_unique<b5000_disassembler>();
+}
+
+
+// digit segment decoder
+u16 b5000_cpu_device::decode_digit(u8 data)
+{
+ static const u8 lut_segs[0x10] =
+ {
+ // 0-9 ok (6 and 9 have tails)
+ 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
+
+ // ?, ?, newline?, -, ?, ?
+ 0, 0, 0x00, 0x40, 0, 0
+ };
+
+ u8 dp = BIT(data, 4);
+ u8 seg = lut_segs[data & 0xf];
+
+ // zero suppression logic is done in hardware
+ if (data > 0)
+ m_suppress0 = false;
+ if (m_suppress0)
+ seg = 0;
+ if ((data & 0xf) >= 0xc)
+ m_suppress0 = true;
+
+ return seg << 1 | dp;
+}
+
+
+//-------------------------------------------------
+// execute
+//-------------------------------------------------
+
+void b5000_cpu_device::execute_one()
+{
+ switch (m_op & 0xf0)
+ {
+ case 0x40: op_lax(); break;
+ case 0x60:
+ if (m_op != 0x6f)
+ op_adx();
+ else
+ op_read();
+ break;
+
+ case 0x80: case 0x90: case 0xa0: case 0xb0:
+ case 0xc0: case 0xd0: case 0xe0: case 0xf0:
+ m_tra_step = 1; break;
+
+ default:
+ switch (m_op & 0xfc)
+ {
+ case 0x04: op_tdin(); break;
+ case 0x08: op_tm(); break;
+ case 0x10: op_sm(); break;
+ case 0x14: op_rsm(); break;
+ case 0x18: m_ret_step = 1; break;
+
+ case 0x20: op_lb(7); break;
+ case 0x24: op_lb(10); break;
+ case 0x28: op_lb(9); break;
+ case 0x2c: op_lb(8); break;
+ case 0x3c: op_lb(0); break;
+
+ case 0x30: case 0x34: op_tl(); break;
+
+ case 0x50: op_lda(); break;
+ case 0x54: op_excp(); break;
+ case 0x58: op_exc0(); break;
+ case 0x5c: op_excm(); break;
+ case 0x70: op_add(); break;
+ case 0x78: op_comp(); break;
+ case 0x7c: op_tam(); break;
+
+ default:
+ switch (m_op)
+ {
+ case 0x00: op_nop(); break;
+ case 0x01: op_tc(); break;
+ case 0x02: op_tkb(); break;
+ case 0x03: op_tkbs(); break;
+ case 0x39: op_rsc(); break;
+ case 0x3b: op_sc(); break;
+ case 0x74: op_kseg(); break;
+ case 0x77: m_atb_step = 1; break;
+
+ default: op_illegal(); break;
+ }
+ break; // 0xff
+
+ }
+ break; // 0xfc
+ }
+}
+
+bool b5000_cpu_device::op_is_tl(u8 op)
+{
+ return ((op & 0xf8) == 0x30);
+}
+
+bool b5000_cpu_device::op_is_lb(u8 op)
+{
+ return ((op & 0xf0) == 0x20) || ((op & 0xfc) == 0x3c);
+}
+
+bool b5000_cpu_device::op_is_atb(u8 op)
+{
+ return (op == 0x77);
+}