diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 5054c16637b..ee42ffeb93a 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -2855,6 +2855,8 @@ end -------------------------------------------------- -- Rockwell B5000 family --@src/devices/cpu/b5000/b5000.h,CPUS["B5000"] = true +--@src/devices/cpu/b5000/b6000.h,CPUS["B5000"] = true +--@src/devices/cpu/b5000/b6100.h,CPUS["B5000"] = true -------------------------------------------------- if CPUS["B5000"] then @@ -2864,6 +2866,10 @@ if CPUS["B5000"] then MAME_DIR .. "src/devices/cpu/b5000/b5000.cpp", MAME_DIR .. "src/devices/cpu/b5000/b5000.h", MAME_DIR .. "src/devices/cpu/b5000/b5000op.cpp", + MAME_DIR .. "src/devices/cpu/b5000/b6000.cpp", + MAME_DIR .. "src/devices/cpu/b5000/b6000.h", + MAME_DIR .. "src/devices/cpu/b5000/b6100.cpp", + MAME_DIR .. "src/devices/cpu/b5000/b6100.h", } end diff --git a/src/devices/cpu/b5000/b5000.cpp b/src/devices/cpu/b5000/b5000.cpp index d995256b783..36f79b700c5 100644 --- a/src/devices/cpu/b5000/b5000.cpp +++ b/src/devices/cpu/b5000/b5000.cpp @@ -2,7 +2,7 @@ // copyright-holders:hap /* - Rockwell B5000 MCU core implementation + Rockwell B5000 MCU */ @@ -16,18 +16,22 @@ 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) : + b5000_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_base_device(mconfig, B5000, tag, owner, clock, 9, address_map_constructor(FUNC(b5000_cpu_device::program_map), this), 6, address_map_constructor(FUNC(b5000_cpu_device::data_map), this)) + 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_map(address_map &map) +void b5000_cpu_device::program_448x8(address_map &map) { map(0x000, 0x1ff).rom(); } -void b5000_cpu_device::data_map(address_map &map) +void b5000_cpu_device::data_45x4(address_map &map) { map(0x00, 0x0b).ram(); map(0x10, 0x1a).ram(); diff --git a/src/devices/cpu/b5000/b5000.h b/src/devices/cpu/b5000/b5000.h index 24435c26065..76cb2b867a0 100644 --- a/src/devices/cpu/b5000/b5000.h +++ b/src/devices/cpu/b5000/b5000.h @@ -2,7 +2,7 @@ // copyright-holders:hap /* - Rockwell B5000 MCU core implementation + Rockwell B5000 MCU */ @@ -25,6 +25,8 @@ public: b5000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: + 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); + // device_disasm_interface overrides virtual std::unique_ptr create_disassembler() override; @@ -37,8 +39,8 @@ protected: virtual u8 sr_page() { return 0; } virtual u16 decode_digit(u8 data); - void data_map(address_map &map); - void program_map(address_map &map); + void program_448x8(address_map &map); + void data_45x4(address_map &map); // opcode helpers u8 ram_r(); diff --git a/src/devices/cpu/b5000/b5000base.cpp b/src/devices/cpu/b5000/b5000base.cpp index 50af8599a4d..790564176eb 100644 --- a/src/devices/cpu/b5000/b5000base.cpp +++ b/src/devices/cpu/b5000/b5000base.cpp @@ -32,7 +32,8 @@ b5000_base_device::b5000_base_device(const machine_config &mconfig, device_type m_read_kb(*this), m_read_din(*this), m_write_str(*this), - m_write_seg(*this) + m_write_seg(*this), + m_write_spk(*this) { } @@ -52,6 +53,7 @@ void b5000_base_device::device_start() m_read_din.resolve_safe(0); m_write_str.resolve_safe(); m_write_seg.resolve_safe(); + m_write_spk.resolve_safe(); // zerofill m_pc = 0; diff --git a/src/devices/cpu/b5000/b5000base.h b/src/devices/cpu/b5000/b5000base.h index 54ef0a65592..40745b835b3 100644 --- a/src/devices/cpu/b5000/b5000base.h +++ b/src/devices/cpu/b5000/b5000base.h @@ -33,6 +33,9 @@ public: // 7/8/10 segment outputs auto write_seg() { return m_write_seg.bind(); } + // speaker output line + auto write_spk() { return m_write_spk.bind(); } + protected: // construction/destruction b5000_base_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); @@ -105,6 +108,7 @@ protected: devcb_read8 m_read_din; devcb_write16 m_write_str; devcb_write16 m_write_seg; + devcb_write_line m_write_spk; }; diff --git a/src/devices/cpu/b5000/b5000op.cpp b/src/devices/cpu/b5000/b5000op.cpp index a4b0f364854..d3a59da7ed4 100644 --- a/src/devices/cpu/b5000/b5000op.cpp +++ b/src/devices/cpu/b5000/b5000op.cpp @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:hap -// B5000 opcode handlers +// B5000 common opcode handlers #include "emu.h" #include "b5000.h" @@ -9,19 +9,19 @@ // internal helpers -inline u8 b5000_cpu_device::ram_r() +u8 b5000_cpu_device::ram_r() { return m_data->read_byte(m_ram_addr) & 0xf; } -inline void b5000_cpu_device::ram_w(u8 data) +void b5000_cpu_device::ram_w(u8 data) { m_data->write_byte(m_ram_addr, data & 0xf); } void b5000_cpu_device::set_pc(u8 pu, u8 pl) { - m_pc = ((pu << 6 & 0x3c0) | (pl & 0x3f)) & m_prgmask; + m_pc = ((pu << 6) | (pl & 0x3f)) & m_prgmask; } void b5000_cpu_device::set_bu(u8 bu) diff --git a/src/devices/cpu/b5000/b6000.cpp b/src/devices/cpu/b5000/b6000.cpp new file mode 100644 index 00000000000..0f0de943639 --- /dev/null +++ b/src/devices/cpu/b5000/b6000.cpp @@ -0,0 +1,105 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Rockwell B6000 MCU + +*/ + +#include "emu.h" +#include "b6000.h" + + +DEFINE_DEVICE_TYPE(B6000, b6000_cpu_device, "b6000", "Rockwell B6000") + + +// constructor +b6000_cpu_device::b6000_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) : + b5000_cpu_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data) +{ } + +b6000_cpu_device::b6000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + b6000_cpu_device(mconfig, B6000, tag, owner, clock, 9, address_map_constructor(FUNC(b6000_cpu_device::program_512x8), this), 6, address_map_constructor(FUNC(b6000_cpu_device::data_45x4), this)) +{ } + + +// internal memory maps +void b6000_cpu_device::program_512x8(address_map &map) +{ + map(0x000, 0x1ff).rom(); +} + + +// initialize +void b6000_cpu_device::device_reset() +{ + b5000_cpu_device::device_reset(); + + // clear all registers + m_bl = 0; + m_bu = 0; + m_a = 0; + + // clear outputs + m_write_str(0); + m_write_seg(m_seg = 0); +} + + +// digit segments decoder +u16 b6000_cpu_device::decode_digit(u8 data) +{ + static u8 lut_segs[0x10] = + { + // 0-9 ok + 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, + + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20 + }; + return lut_segs[data & 0xf]; +} + + +//------------------------------------------------- +// execute +//------------------------------------------------- + +void b6000_cpu_device::update_speaker() +{ + // carry flag outputs to SPK + if (m_c != m_prev_c) + m_write_spk(m_c); +} + +void b6000_cpu_device::execute_one() +{ + switch (m_op) + { + case 0x03: op_tkbs(); break; + case 0x76: op_atbz(); break; + case 0x77: op_atb(); break; + + // rest is same as B5000 + default: b5000_cpu_device::execute_one(); break; + } + + update_speaker(); +} + + +//------------------------------------------------- +// changed opcodes (no need for separate file) +//------------------------------------------------- + +void b6000_cpu_device::op_tkbs() +{ + // TKBS: load segments (no TKB step) + m_seg |= decode_digit(ram_r()); + m_write_seg(m_seg); +} + +void b6000_cpu_device::op_atbz() +{ + // ATBZ: load strobe from A (no ATB step) + m_write_str(1 << (m_a & 0xf)); +} diff --git a/src/devices/cpu/b5000/b6000.h b/src/devices/cpu/b5000/b6000.h new file mode 100644 index 00000000000..5cb9d338dbe --- /dev/null +++ b/src/devices/cpu/b5000/b6000.h @@ -0,0 +1,47 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Rockwell B6000 MCU + +*/ + +#ifndef MAME_CPU_B5000_B6000_H +#define MAME_CPU_B5000_B6000_H + +#pragma once + +#include "b5000.h" + +// pinout reference + +/* + +*/ + +class b6000_cpu_device : public b5000_cpu_device +{ +public: + b6000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + b6000_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); + + // device-level overrides + virtual void device_reset() override; + + void update_speaker(); + virtual void execute_one() override; + virtual u16 decode_digit(u8 data) override; + + void program_512x8(address_map &map); + + // opcode handlers + virtual void op_tkbs() override; + virtual void op_atbz() override; +}; + + +DECLARE_DEVICE_TYPE(B6000, b6000_cpu_device) + +#endif // MAME_CPU_B5000_B6000_H diff --git a/src/devices/cpu/b5000/b6100.cpp b/src/devices/cpu/b5000/b6100.cpp new file mode 100644 index 00000000000..c28073373ba --- /dev/null +++ b/src/devices/cpu/b5000/b6100.cpp @@ -0,0 +1,157 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Rockwell B6100 MCU + +*/ + +#include "emu.h" +#include "b6100.h" + +#include "b5000d.h" + + +DEFINE_DEVICE_TYPE(B6100, b6100_cpu_device, "b6100", "Rockwell B6100") + + +// constructor +b6100_cpu_device::b6100_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) : + b6000_cpu_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data) +{ } + +b6100_cpu_device::b6100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + b6100_cpu_device(mconfig, B6100, tag, owner, clock, 10, address_map_constructor(FUNC(b6100_cpu_device::program_896x8), this), 6, address_map_constructor(FUNC(b6100_cpu_device::data_48x4), this)) +{ } + + +// internal memory maps +void b6100_cpu_device::program_896x8(address_map &map) +{ + map(0x000, 0x2ff).rom(); + map(0x380, 0x3ff).rom(); +} + +void b6100_cpu_device::data_48x4(address_map &map) +{ + map(0x00, 0x0b).ram(); + map(0x10, 0x1b).ram(); + map(0x20, 0x2b).ram(); + map(0x30, 0x3b).ram(); +} + + +// disasm +std::unique_ptr b6100_cpu_device::create_disassembler() +{ + return std::make_unique(); +} + + +// digit segments decoder +u16 b6100_cpu_device::decode_digit(u8 data) +{ + static u8 lut_segs[0x10] = + { + // 0-9 ok + 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, + + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20 + }; + return lut_segs[data & 0xf]; +} + + +//------------------------------------------------- +// execute +//------------------------------------------------- + +void b6100_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 0x1c: op_lb(11); 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: case 0x38: 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 0x0c: op_sc(); break; + case 0x0d: op_rsc(); break; + case 0x74: op_kseg(); break; + case 0x76: op_atbz(); break; + case 0x77: op_atb(); break; + + default: op_illegal(); break; + } + break; // 0xff + + } + break; // 0xfc + } + + update_speaker(); +} + +bool b6100_cpu_device::op_canskip(u8 op) +{ + // TL is unskippable + return ((op & 0xf8) != 0x30) && ((op & 0xfc) != 0x38); +} + +bool b6100_cpu_device::op_is_lb(u8 op) +{ + return ((op & 0xfc) == 0x1c) || ((op & 0xf0) == 0x20) || ((op & 0xfc) == 0x3c); +} + + +//------------------------------------------------- +// changed opcodes (no need for separate file) +//------------------------------------------------- + +void b6100_cpu_device::op_read() +{ + // READ: add KB to A, skip next on no overflow + m_a += (m_read_kb() & 0xf); + m_skip = !BIT(m_a, 4); + m_a &= 0xf; +} diff --git a/src/devices/cpu/b5000/b6100.h b/src/devices/cpu/b5000/b6100.h new file mode 100644 index 00000000000..d21b8237c0d --- /dev/null +++ b/src/devices/cpu/b5000/b6100.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Rockwell B6100 MCU + +*/ + +#ifndef MAME_CPU_B5000_B6100_H +#define MAME_CPU_B5000_B6100_H + +#pragma once + +#include "b6000.h" + +// pinout reference + +/* + +*/ + +class b6100_cpu_device : public b6000_cpu_device +{ +public: + b6100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + b6100_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); + + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; + + // device_execute_interface overrides + virtual void execute_one() override; + + virtual bool op_canskip(u8 op) override; + virtual bool op_is_lb(u8 op) override; + virtual void reset_pc() override { set_pc(0, 0); } + virtual u8 sr_page() override { return 15; } + virtual u16 decode_digit(u8 data) override; + + void program_896x8(address_map &map); + void data_48x4(address_map &map); + + // opcode handlers + virtual void op_read() override; +}; + + +DECLARE_DEVICE_TYPE(B6100, b6100_cpu_device) + +#endif // MAME_CPU_B5000_B6100_H