diff options
author | 2022-03-29 01:43:47 +0200 | |
---|---|---|
committer | 2022-03-29 01:43:47 +0200 | |
commit | f876dd82415c760a0a3bd63ed855476be7adcf82 (patch) | |
tree | eb11ef3094e633d66ea9217ded39cc1bc1098b61 | |
parent | d6ae8ec92175ae8b822a4d2dfcffda432ac6a211 (diff) |
rw5000: add a5000/a5900
-rw-r--r-- | scripts/src/cpu.lua | 3 | ||||
-rw-r--r-- | src/devices/cpu/rw5000/a5000.cpp | 109 | ||||
-rw-r--r-- | src/devices/cpu/rw5000/a5000.h | 48 | ||||
-rw-r--r-- | src/devices/cpu/rw5000/b5000.h | 2 | ||||
-rw-r--r-- | src/devices/cpu/rw5000/b5000op.cpp | 2 | ||||
-rw-r--r-- | src/devices/cpu/rw5000/rw5000base.cpp | 3 | ||||
-rw-r--r-- | src/devices/cpu/rw5000/rw5000base.h | 1 |
7 files changed, 166 insertions, 2 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index be0e7eed434..84f03c085c7 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -2854,6 +2854,7 @@ end -------------------------------------------------- -- Rockwell A/B5000 family +--@src/devices/cpu/rw5000/a5000.h,CPUS["RW5000"] = true --@src/devices/cpu/rw5000/b5000.h,CPUS["RW5000"] = true --@src/devices/cpu/rw5000/b6000.h,CPUS["RW5000"] = true --@src/devices/cpu/rw5000/b6100.h,CPUS["RW5000"] = true @@ -2866,6 +2867,8 @@ if CPUS["RW5000"] then MAME_DIR .. "src/devices/cpu/rw5000/b5000.cpp", MAME_DIR .. "src/devices/cpu/rw5000/b5000.h", MAME_DIR .. "src/devices/cpu/rw5000/b5000op.cpp", + MAME_DIR .. "src/devices/cpu/rw5000/a5000.cpp", + MAME_DIR .. "src/devices/cpu/rw5000/a5000.h", MAME_DIR .. "src/devices/cpu/rw5000/b6000.cpp", MAME_DIR .. "src/devices/cpu/rw5000/b6000.h", MAME_DIR .. "src/devices/cpu/rw5000/b6100.cpp", diff --git a/src/devices/cpu/rw5000/a5000.cpp b/src/devices/cpu/rw5000/a5000.cpp new file mode 100644 index 00000000000..7380120a193 --- /dev/null +++ b/src/devices/cpu/rw5000/a5000.cpp @@ -0,0 +1,109 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Rockwell A5000/A5900 MCU + +TODO: +- what happens when 0 or >1 keys are held down on READ? + +*/ + +#include "emu.h" +#include "a5000.h" + +#include "rw5000d.h" + + +DEFINE_DEVICE_TYPE(A5000, a5000_cpu_device, "a5000", "Rockwell A5000") +DEFINE_DEVICE_TYPE(A5900, a5900_cpu_device, "a5900", "Rockwell A5900") + + +// constructor +a5000_cpu_device::a5000_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) +{ } + +a5000_cpu_device::a5000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + a5000_cpu_device(mconfig, A5000, tag, owner, clock, 9, address_map_constructor(FUNC(a5000_cpu_device::program_448x8), this), 6, address_map_constructor(FUNC(a5000_cpu_device::data_45x4), this)) +{ } + +a5900_cpu_device::a5900_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + a5000_cpu_device(mconfig, A5900, tag, owner, clock, 9, address_map_constructor(FUNC(a5900_cpu_device::program_512x8), this), 6, address_map_constructor(FUNC(a5900_cpu_device::data_45x4), this)) +{ } + + +// internal memory maps +void a5900_cpu_device::program_512x8(address_map &map) +{ + map(0x000, 0x1ff).rom(); +} + + +// disasm +std::unique_ptr<util::disasm_interface> a5000_cpu_device::create_disassembler() +{ + return std::make_unique<a5000_disassembler>(); +} + + +//------------------------------------------------- +// execute +//------------------------------------------------- + +void a5000_cpu_device::execute_one() +{ + switch (m_op) + { + case 0x02: op_illegal(); break; + case 0x03: op_tkb(); break; + case 0x76: m_mtd_step = 1; break; + case 0x77: op_atb(); break; + + // rest is same as B5000 + default: b5000_cpu_device::execute_one(); break; + } +} + + +//------------------------------------------------- +// changed opcodes (no need for separate file) +//------------------------------------------------- + +void a5000_cpu_device::op_mtd_step() +{ + assert(m_mtd_step > 0); + + // MTD: load strobe + segments (multi step) + switch (m_mtd_step) + { + // step 1: disable strobe and segment drivers + case 1: + m_write_str(0); + op_kseg(); + break; + + // step 2: load strobe from Bl + case 2: + m_write_str(1 << m_prev_bl); + break; + + // step 4: load segment drivers + case 4: + seg_w(m_seg | decode_digit(m_prev3_c << 4 | ram_r())); + m_mtd_step = 0; + return; + + default: + break; + } + m_mtd_step++; +} + +void a5000_cpu_device::op_read() +{ + // READ: add _KB info to A, skip next on no overflow + m_a += ~((count_leading_zeros_32(m_read_kb() & 0xf) - 28) & 3) & 0xf; + m_skip = !BIT(m_a, 4); + m_a &= 0xf; +} diff --git a/src/devices/cpu/rw5000/a5000.h b/src/devices/cpu/rw5000/a5000.h new file mode 100644 index 00000000000..69740b28f79 --- /dev/null +++ b/src/devices/cpu/rw5000/a5000.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Rockwell A5000/A5900 MCU + +*/ + +#ifndef MAME_CPU_RW5000_A5000_H +#define MAME_CPU_RW5000_A5000_H + +#pragma once + +#include "b5000.h" + + +class a5000_cpu_device : public b5000_cpu_device +{ +public: + a5000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + a5000_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<util::disasm_interface> create_disassembler() override; + + virtual void execute_one() override; + + // opcode handlers + virtual void op_mtd_step() override; + virtual void op_read() override; +}; + +class a5900_cpu_device : public a5000_cpu_device +{ +public: + a5900_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + void program_512x8(address_map &map); +}; + + +DECLARE_DEVICE_TYPE(A5000, a5000_cpu_device) +DECLARE_DEVICE_TYPE(A5900, a5900_cpu_device) + +#endif // MAME_CPU_RW5000_A5000_H diff --git a/src/devices/cpu/rw5000/b5000.h b/src/devices/cpu/rw5000/b5000.h index df60bc623bc..828ef1d9bd7 100644 --- a/src/devices/cpu/rw5000/b5000.h +++ b/src/devices/cpu/rw5000/b5000.h @@ -13,7 +13,7 @@ #include "rw5000base.h" -// pinout reference (preliminary) +// pinout reference (preliminary, other A/B5xxx pinouts are same or very similar) /* _____ _____ diff --git a/src/devices/cpu/rw5000/b5000op.cpp b/src/devices/cpu/rw5000/b5000op.cpp index 048d035790f..e1a759fc817 100644 --- a/src/devices/cpu/rw5000/b5000op.cpp +++ b/src/devices/cpu/rw5000/b5000op.cpp @@ -313,7 +313,7 @@ void b5000_cpu_device::op_tkbs() op_tkb(); // note: SEG0(DP) from C flag is delayed 2 cycles - seg_w(m_seg | decode_digit(m_prev2_c << 4 | ram_r())); + seg_w(m_seg | decode_digit(m_prev3_c << 4 | ram_r())); } void b5000_cpu_device::op_read() diff --git a/src/devices/cpu/rw5000/rw5000base.cpp b/src/devices/cpu/rw5000/rw5000base.cpp index 3bec71c3c39..5fda9b23a0c 100644 --- a/src/devices/cpu/rw5000/rw5000base.cpp +++ b/src/devices/cpu/rw5000/rw5000base.cpp @@ -74,6 +74,7 @@ void rw5000_base_device::device_start() m_c = 0; m_prev_c = 0; m_prev2_c = 0; + m_prev3_c = 0; m_sr = false; m_skip = false; m_seg = 0; @@ -102,6 +103,7 @@ void rw5000_base_device::device_start() save_item(NAME(m_c)); save_item(NAME(m_prev_c)); save_item(NAME(m_prev2_c)); + save_item(NAME(m_prev3_c)); save_item(NAME(m_sr)); save_item(NAME(m_skip)); save_item(NAME(m_seg)); @@ -183,6 +185,7 @@ void rw5000_base_device::execute_run() m_prev_bl = m_bl; m_prev_bu = m_bu; + m_prev3_c = m_prev2_c; m_prev2_c = m_prev_c; m_prev_c = m_c; diff --git a/src/devices/cpu/rw5000/rw5000base.h b/src/devices/cpu/rw5000/rw5000base.h index 3fce8d28f6c..f6dc6146af8 100644 --- a/src/devices/cpu/rw5000/rw5000base.h +++ b/src/devices/cpu/rw5000/rw5000base.h @@ -89,6 +89,7 @@ protected: u8 m_c; u8 m_prev_c; u8 m_prev2_c; + u8 m_prev3_c; bool m_sr; bool m_skip; u16 m_seg; |