summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2021-02-14 23:23:14 +0100
committer hap <happppp@users.noreply.github.com>2021-02-14 23:23:28 +0100
commit147b5e72a401de8478df778a1f00d3a4c1be44f8 (patch)
tree576ff573b31cf6efe42a1f2674f5e8b882c11ed7
parent2d0f0bf8675a64236148a3777badb282a1e5e61b (diff)
added MM5799 MCU emulation [hap]
New working machines -------------------- Basketball (Mattel) [hap, Sean Riddle] QuizKid Speller [hap, Sean Riddle] New working clones ------------------ QuizKid Racer (MM5799 version) [hap, Sean Riddle]
-rw-r--r--scripts/src/cpu.lua20
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/cpu/cops1/cops1base.cpp235
-rw-r--r--src/devices/cpu/cops1/cops1base.h197
-rw-r--r--src/devices/cpu/cops1/cops1d.cpp188
-rw-r--r--src/devices/cpu/cops1/cops1d.h65
-rw-r--r--src/devices/cpu/cops1/cops1op.cpp378
-rw-r--r--src/devices/cpu/cops1/mm5799.cpp153
-rw-r--r--src/devices/cpu/cops1/mm5799.h61
-rw-r--r--src/devices/cpu/sm510/sm500core.cpp2
-rw-r--r--src/devices/cpu/sm510/sm510.h2
-rw-r--r--src/devices/cpu/sm510/sm510base.cpp2
-rw-r--r--src/devices/cpu/sm510/sm510core.cpp2
-rw-r--r--src/devices/cpu/sm510/sm510op.cpp4
-rw-r--r--src/devices/cpu/sm510/sm511core.cpp2
-rw-r--r--src/devices/cpu/sm510/sm590core.cpp2
-rw-r--r--src/devices/cpu/tms1000/tms1k_base.h1
-rw-r--r--src/mame/drivers/hh_cop400.cpp39
-rw-r--r--src/mame/drivers/hh_cops1.cpp577
-rw-r--r--src/mame/layout/aim65.lay2
-rw-r--r--src/mame/layout/cnbaskb.lay2
-rw-r--r--src/mame/layout/cnfball2.lay2
-rw-r--r--src/mame/layout/cqback.lay2
-rw-r--r--src/mame/layout/ebaskb2.lay2
-rw-r--r--src/mame/layout/ebball.lay3
-rw-r--r--src/mame/layout/ebball2.lay2
-rw-r--r--src/mame/layout/ebball3.lay2
-rw-r--r--src/mame/layout/efball.lay5
-rw-r--r--src/mame/layout/eleciq.lay2
-rw-r--r--src/mame/layout/esoccer.lay2
-rw-r--r--src/mame/layout/gjackpot.lay2
-rw-r--r--src/mame/layout/gpoker.lay2
-rw-r--r--src/mame/layout/h2hbaseb.lay2
-rw-r--r--src/mame/layout/h2hboxing.lay2
-rw-r--r--src/mame/layout/h2hfootb.lay2
-rw-r--r--src/mame/layout/hccbaskb.lay2
-rw-r--r--src/mame/layout/lightfgt.lay2
-rw-r--r--src/mame/layout/mbaskb.lay103
-rw-r--r--src/mame/layout/mephisto_megaiv.lay2
-rw-r--r--src/mame/layout/mephisto_mondial2.lay2
-rw-r--r--src/mame/layout/mephisto_mondial68k.lay2
-rw-r--r--src/mame/layout/mephisto_smondial2.lay2
-rw-r--r--src/mame/layout/qkracerm.lay66
-rw-r--r--src/mame/layout/qkspeller.lay35
-rw-r--r--src/mame/layout/rockpin.lay2
-rw-r--r--src/mame/layout/ssimon.lay2
-rw-r--r--src/mame/layout/tactix.lay2
-rw-r--r--src/mame/layout/tbaskb.lay2
-rw-r--r--src/mame/layout/tbreakup.lay2
-rw-r--r--src/mame/layout/ti95.lay2
-rw-r--r--src/mame/layout/us2pfball.lay2
-rw-r--r--src/mame/mame.lst5
-rw-r--r--src/mame/mess.flt1
-rw-r--r--src/tools/unidasm.cpp2
55 files changed, 2147 insertions, 60 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index 1965cb11300..938501f7394 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -452,6 +452,26 @@ if (CPUS["COSMAC"]~=null or _OPTIONS["with-tools"]) then
end
--------------------------------------------------
+-- National Semiconductor COPS1 family
+--@src/devices/cpu/cops1/mm5799.h,CPUS["COPS1"] = true
+--------------------------------------------------
+
+if (CPUS["COPS1"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/cpu/cops1/cops1base.cpp",
+ MAME_DIR .. "src/devices/cpu/cops1/cops1base.h",
+ MAME_DIR .. "src/devices/cpu/cops1/cops1op.cpp",
+ MAME_DIR .. "src/devices/cpu/cops1/mm5799.cpp",
+ MAME_DIR .. "src/devices/cpu/cops1/mm5799.h",
+ }
+end
+
+if (CPUS["COPS1"]~=null or _OPTIONS["with-tools"]) then
+ table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/cops1/cops1d.cpp")
+ table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/cops1/cops1d.h")
+end
+
+--------------------------------------------------
-- National Semiconductor COP400 family
--@src/devices/cpu/cop400/cop400.h,CPUS["COP400"] = true
--------------------------------------------------
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 979f9fd0e49..ff6e0f45149 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -147,6 +147,7 @@ CPUS["HPC"] = true
CPUS["FR"] = true
CPUS["UPD78K"] = true
CPUS["KS0164"] = true
+--CPUS["COPS1"] = true
--------------------------------------------------
-- specify available sound cores
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 58c65de5c4a..1baf05ce3e2 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -166,6 +166,7 @@ CPUS["M88000"] = true
CPUS["XAVIX2"] = true
CPUS["UPD78K"] = true
CPUS["ROMP"] = true
+CPUS["COPS1"] = true
--------------------------------------------------
-- specify available sound cores; some of these are
@@ -3012,6 +3013,7 @@ files {
createMESSProjects(_target, _subtarget, "natsemi")
files {
MAME_DIR .. "src/mame/drivers/hh_cop400.cpp",
+ MAME_DIR .. "src/mame/drivers/hh_cops1.cpp",
MAME_DIR .. "src/mame/drivers/ns5652.cpp",
}
diff --git a/src/devices/cpu/cops1/cops1base.cpp b/src/devices/cpu/cops1/cops1base.cpp
new file mode 100644
index 00000000000..08f882df59c
--- /dev/null
+++ b/src/devices/cpu/cops1/cops1base.cpp
@@ -0,0 +1,235 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+National Semiconductor COPS(MM57 MCU family) cores
+
+This is the first "COPS" series (Controller Oriented Processor Systems),
+4-bit MCUs with internal RAM and most of them internal ROM too.
+It was only briefly on the market and was quickly superceded by the
+2nd "COPS": the COP400 series.
+
+Short list of MCU types:
+- MM5781+MM5782: 2KB ROM, 160 nybbles RAM
+- MM5799: 1.5KB ROM, 96 nybbles RAM
+- MM57140: 640 bytes ROM(10 bytes inaccessible?), 55 nybbles RAM
+
+Note that not every "MM57" chip is a generic MCU, there are plenty other chips,
+mostly for calculators. For example MM5780 for the Quiz Kid, the decap of that
+looks more like a complex state machine.
+
+References:
+- 1977 National Semiconductor MOS/LSI databook
+
+TODO:
+- documentation says that LB 10 is either 0 or 4, depending on RAM configuration,
+ but on qkracerm it's 5 (also confirmed in patent source code), so I assume
+ LB 10 is fully configurable as mask option
+
+*/
+
+#include "emu.h"
+#include "cops1base.h"
+
+#include "debugger.h"
+
+
+cops1_base_device::cops1_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
+ cpu_device(mconfig, type, tag, owner, clock),
+ m_program_config("program", ENDIANNESS_LITTLE, 8, prgwidth, 0, program),
+ m_data_config("data", ENDIANNESS_LITTLE, 8, datawidth, 0, data),
+ m_prgwidth(prgwidth),
+ m_datawidth(datawidth),
+ m_opla(*this, "opla"),
+ m_read_k(*this),
+ m_read_inb(*this),
+ m_read_f(*this),
+ m_write_f(*this),
+ m_read_do3(*this),
+ m_write_do(*this),
+ m_write_s(*this),
+ m_write_blk(*this),
+ m_read_si(*this),
+ m_write_so(*this)
+{ }
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+enum
+{
+ COPS1_PC=1, COPS1_SA, COPS1_SB,
+ COPS1_A, COPS1_C, COPS1_H, COPS1_B, COPS1_F
+};
+
+void cops1_base_device::device_start()
+{
+ m_program = &space(AS_PROGRAM);
+ m_data = &space(AS_DATA);
+ m_prgmask = (1 << m_prgwidth) - 1;
+ m_datamask = (1 << m_datawidth) - 1;
+
+ // resolve callbacks
+ m_read_k.resolve_safe(0);
+ m_read_inb.resolve_safe(0);
+ m_read_f.resolve();
+ m_write_f.resolve_safe();
+ m_read_do3.resolve();
+ m_write_do.resolve_safe();
+ m_write_s.resolve_safe();
+ m_write_blk.resolve_safe();
+ m_read_si.resolve_safe(0);
+ m_write_so.resolve_safe();
+
+ // zerofill
+ m_pc = 0;
+ m_prev_pc = 0;
+ m_op = 0;
+ m_prev_op = 0;
+ m_arg = 0;
+
+ m_a = 0;
+ m_h = 0;
+ m_b = 0;
+ m_c = 0;
+ m_skip = false;
+ m_sa = 0;
+ m_sb = 0;
+ m_serial = 0;
+ m_f = 0;
+ m_do = 0;
+
+ // register for savestates
+ save_item(NAME(m_pc));
+ save_item(NAME(m_prev_pc));
+ save_item(NAME(m_op));
+ save_item(NAME(m_prev_op));
+ save_item(NAME(m_arg));
+
+ save_item(NAME(m_a));
+ save_item(NAME(m_h));
+ save_item(NAME(m_b));
+ save_item(NAME(m_c));
+ save_item(NAME(m_skip));
+ save_item(NAME(m_sa));
+ save_item(NAME(m_sb));
+ save_item(NAME(m_serial));
+ save_item(NAME(m_f));
+ save_item(NAME(m_do));
+
+ // register state for debugger
+ state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%03X").noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_prev_pc).formatstr("%03X").noshow();
+
+ state_add(COPS1_PC, "PC", m_pc).formatstr("%03X");
+ state_add(COPS1_SA, "SA", m_sa).formatstr("%03X");
+ state_add(COPS1_SB, "SB", m_sb).formatstr("%03X");
+
+ state_add(COPS1_A, "A", m_a).formatstr("%01X");
+ state_add(COPS1_C, "C", m_c).formatstr("%01X");
+ state_add(COPS1_H, "H", m_h).formatstr("%01X");
+ state_add(COPS1_B, "B", m_b).formatstr("%02X");
+ state_add(COPS1_F, "F", m_f).formatstr("%01X");
+
+ set_icountptr(m_icount);
+}
+
+device_memory_interface::space_config_vector cops1_base_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_DATA, &m_data_config)
+ };
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void cops1_base_device::device_reset()
+{
+ m_op = m_prev_op = 0;
+ m_pc = m_prev_pc = 0;
+ m_skip = false;
+
+ // clear outputs
+ m_write_blk(1);
+ m_write_f(m_f = 0);
+ m_write_do(m_do = 0);
+ m_write_s(0);
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void cops1_base_device::device_add_mconfig(machine_config &config)
+{
+ PLA(config, "opla", 4, 7, 15).set_format(pla_device::FMT::BERKELEY);
+}
+
+
+//-------------------------------------------------
+// execute
+//-------------------------------------------------
+
+void cops1_base_device::cycle()
+{
+ m_icount--;
+
+ // shift serial data
+ m_write_so(m_serial & 1);
+ int feed = m_option_axo_si ? 1 : m_read_si();
+ m_serial = (m_serial >> 1 | feed << 3) & 0xf;
+}
+
+void cops1_base_device::increment_pc()
+{
+ // low part is LFSR
+ u8 feed = (m_pc & 0x3f) == 0 || ((m_pc >> 1 ^ m_pc) & 1) ? 0x20 : 0;
+ m_pc = (m_pc & ~0x3f) | (m_pc >> 1 & 0x1f) | feed;
+}
+
+void cops1_base_device::execute_run()
+{
+ while (m_icount > 0)
+ {
+ // remember previous state
+ m_prev_op = m_op;
+ m_prev_pc = m_pc;
+
+ // BLK goes low for 1 cycle with BTD
+ if (m_prev_op == 0x25)
+ m_write_blk(0);
+
+ // fetch next opcode
+ debugger_instruction_hook(m_pc);
+ m_op = m_program->read_byte(m_pc);
+ increment_pc();
+ cycle();
+
+ if (m_op != 0x25)
+ m_write_blk(1);
+
+ // fetch opcode argument
+ if (op_argument())
+ {
+ m_arg = m_program->read_byte(m_pc);
+ increment_pc();
+ cycle();
+ }
+
+ // handle opcode if it's not skipped
+ if (m_skip)
+ {
+ m_skip = false;
+ m_op = 0; // fake nop
+ }
+ else
+ execute_one();
+ }
+}
diff --git a/src/devices/cpu/cops1/cops1base.h b/src/devices/cpu/cops1/cops1base.h
new file mode 100644
index 00000000000..cb0d85ddedb
--- /dev/null
+++ b/src/devices/cpu/cops1/cops1base.h
@@ -0,0 +1,197 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ National Semiconductor COPS(MM57 MCU family) cores
+
+*/
+
+#ifndef MAME_CPU_COPS1_COPS1BASE_H
+#define MAME_CPU_COPS1_COPS1BASE_H
+
+#pragma once
+
+#include "machine/pla.h"
+
+
+class cops1_base_device : public cpu_device
+{
+public:
+ // configuration helpers
+ // I/O ports:
+
+ // 4-bit K inputs
+ auto read_k() { return m_read_k.bind(); }
+
+ // INB input pin
+ auto read_inb() { return m_read_inb.bind(); }
+
+ // 4-bit F(flags) I/O
+ auto read_f() { return m_read_f.bind(); }
+ auto write_f() { return m_write_f.bind(); }
+
+ // 4-bit DO(digit output) I/O
+ auto read_do3() { return m_read_do3.bind(); } // only DO3 can be an input
+ auto write_do() { return m_write_do.bind(); }
+
+ // 8-bit Sa-Sg + Sp segment outputs
+ auto write_s() { return m_write_s.bind(); }
+
+ // BLK(display blanking) output pin
+ auto write_blk() { return m_write_blk.bind(); }
+
+ // 1-bit serial I/O
+ auto read_si() { return m_read_si.bind(); }
+ auto write_so() { return m_write_so.bind(); }
+
+ // set MCU mask options:
+
+ // RAM configuration 12 or 16 digits (default false)
+ auto &set_option_ram_d12(bool b) { m_option_ram_d12 = b; return *this; }
+
+ // LB 10 real value (default 0)
+ auto &set_option_lb_10(u8 lb) { m_option_lb_10 = lb & 0xf; return *this; }
+
+ // skip on Bd 13 with EXP+ (default true)
+ auto &set_option_excp_skip(bool b) { m_option_excp_skip = b; return *this; }
+
+ // read SI directly with AXO (default false)
+ auto &set_option_axo_si(bool b) { m_option_axo_si = b; return *this; }
+
+ // K and INB pins can be active high or active low (default high)
+ auto &set_option_k_active_high(bool b) { m_option_k_active_high = b; return *this; }
+ auto &set_option_inb_active_high(bool b) { m_option_inb_active_high = b; return *this; }
+
+protected:
+ // construction/destruction
+ cops1_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ // device_execute_interface overrides
+ virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
+ virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); }
+ virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
+ virtual uint32_t execute_max_cycles() const noexcept override { return 2; }
+ virtual void execute_run() override;
+ virtual void execute_one() = 0;
+ virtual bool op_argument() = 0;
+
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+
+ address_space_config m_program_config;
+ address_space_config m_data_config;
+ address_space *m_program;
+ address_space *m_data;
+
+ int m_icount;
+
+ // fixed settings or mask options
+ int m_prgwidth; // ROM/RAM address size
+ int m_datawidth; // "
+ u16 m_prgmask; // "
+ u16 m_datamask; // "
+
+ bool m_option_ram_d12 = false;
+ u8 m_option_lb_10 = 0;
+ bool m_option_excp_skip = true;
+ bool m_option_axo_si = false;
+ bool m_option_k_active_high = true;
+ bool m_option_inb_active_high = true;
+
+ optional_device<pla_device> m_opla; // segment output PLA
+
+ // i/o handlers
+ devcb_read8 m_read_k;
+ devcb_read_line m_read_inb;
+ devcb_read8 m_read_f;
+ devcb_write8 m_write_f;
+ devcb_read_line m_read_do3;
+ devcb_write8 m_write_do;
+ devcb_write8 m_write_s;
+ devcb_write_line m_write_blk;
+ devcb_read_line m_read_si;
+ devcb_write_line m_write_so;
+
+ // internal state, regs
+ u16 m_pc;
+ u16 m_prev_pc;
+ u8 m_op;
+ u8 m_prev_op;
+ u8 m_arg;
+
+ u8 m_a;
+ u8 m_h;
+ u8 m_b;
+ int m_c;
+ bool m_skip;
+ u16 m_sa;
+ u16 m_sb;
+ u8 m_serial;
+ u8 m_f;
+ u8 m_do;
+
+ // misc handlers
+ void cycle();
+ void increment_pc();
+
+ u8 ram_r();
+ void ram_w(u8 data);
+ void pop_pc();
+ void push_pc();
+
+ // opcode handlers
+ void op_ad();
+ void op_add();
+ void op_sub();
+ void op_comp();
+ void op_0ta();
+ void op_adx();
+ void op_hxa();
+ void op_tam();
+ void op_sc();
+ void op_rsc();
+ void op_tc();
+
+ void op_tin();
+ void op_tf();
+ void op_tkb();
+ void op_tir();
+
+ void op_btd();
+ void op_dspa();
+ void op_dsps();
+ void op_axo();
+ void op_ldf();
+ void op_read();
+
+ void op_go();
+ void op_call();
+ void op_ret();
+ void op_rets();
+ void op_lg();
+ void op_nop();
+
+ void op_exc();
+ void op_excm();
+ void op_excp();
+ void op_mta();
+ void op_lm();
+
+ void op_sm();
+ void op_rsm();
+ void op_tm();
+
+ void op_lb();
+ void op_lbl();
+ void op_atb();
+ void op_bta();
+ void op_hxbr();
+};
+
+
+#endif // MAME_CPU_COPS1_COPS1BASE_H
diff --git a/src/devices/cpu/cops1/cops1d.cpp b/src/devices/cpu/cops1/cops1d.cpp
new file mode 100644
index 00000000000..0d20a0f0370
--- /dev/null
+++ b/src/devices/cpu/cops1/cops1d.cpp
@@ -0,0 +1,188 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ National Semiconductor COPS(MM57 MCU family) disassembler
+
+*/
+
+#include "emu.h"
+#include "cops1d.h"
+
+// constructor
+
+cops1_common_disassembler::cops1_common_disassembler()
+{
+ // init lfsr pc lut
+ for (u32 i = 0, pc = 0; i < 0x40; i++)
+ {
+ m_l2r[i] = pc;
+ m_r2l[pc] = i;
+ pc = increment_pc(pc);
+ }
+}
+
+offs_t cops1_common_disassembler::increment_pc(offs_t pc)
+{
+ u8 feed = (pc & 0x3f) == 0 || ((pc >> 1 ^ pc) & 1) ? 0x20 : 0;
+ return (pc & ~0x3f) | (pc >> 1 & 0x1f) | feed;
+}
+
+
+// common lookup tables
+
+const char *const cops1_common_disassembler::s_name[] =
+{
+ "?",
+ "AD", "ADD", "SUB", "COMP", "0TA", "ADX", "HXA", "TAM", "SC", "RSC", "TC",
+ "TIN", "TF", "TKB", "TIR",
+ "BTD", "DSPA", "DSPS", "AXO", "LDF", "READ",
+ "GO", "CALL", "RET", "RETS", "LG/GO", "LG/CALL", "NOP",
+ "EXC", "EXCM", "EXCP", "MTA", "LM",
+ "SM", "SM", "SM", "SM", "RSM", "RSM", "RSM", "RSM", "TM",
+ "LB", "LBL", "ATB", "BTA", "HXBR"
+};
+
+// bitmask for opcode parameter
+const u8 cops1_common_disassembler::s_bits[] =
+{
+ 0,
+ 0, 0, 0, 0, 0, 0x0f, 0, 0, 0, 0, 0,
+ 0, 0x30, 0, 0,
+ 0, 0, 0, 0, 0xff, 0,
+ 0x3f, 0x3f, 0, 0, 0xff, 0xff, 0,
+ 0x30, 0x30, 0x30, 0x30, 0x0f,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x3f, 0xff, 0, 0, 0
+};
+
+const u32 cops1_common_disassembler::s_flags[] =
+{
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, STEP_OVER, STEP_OUT, STEP_OUT, 0, STEP_OVER, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+};
+
+
+// common disasm
+
+offs_t cops1_common_disassembler::common_disasm(const u8 *lut_opmap, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ // get raw opcode
+ u8 op = opcodes.r8(pc);
+ u8 instr = lut_opmap[op];
+ int len = 1;
+
+ // get parameter
+ u8 mask = s_bits[instr];
+ u16 param = op & mask;
+
+ if (mask == 0x30)
+ {
+ mask >>= 4;
+ param >>= 4;
+ }
+
+ // 2-byte instructions
+ else if (mask == 0xff)
+ {
+ pc = increment_pc(pc);
+ u8 arg = params.r8(pc);
+ len++;
+
+ if (instr == em_LG)
+ {
+ // bit 6 indicates GO or CALL
+ if (~arg & 0x40)
+ instr++;
+
+ param = (~param << 7 & 0x780) | (arg >> 1 & 0x40) | (arg & 0x3f);
+ }
+ else
+ param = arg;
+ }
+
+ // disassemble it
+ util::stream_format(stream, "%-8s ", s_name[instr]);
+ if (mask > 0)
+ {
+ if (mask < 16)
+ {
+ // SM and RSM param is scrambled
+ if (instr >= em_SM1 && instr <= em_SM8)
+ param = instr - em_SM1;
+ else if (instr >= em_RSM1 && instr <= em_RSM8)
+ param = instr - em_RSM1;
+
+ // memory bit opcodes are 1,2,4,8
+ if (instr >= em_SM1 && instr <= em_TM)
+ param = 1 << param;
+
+ // TF is 1,2,3,4
+ else if (instr == em_TF)
+ param++;
+
+ // EXC type instructions omit param if it's 0
+ if (!(param == 0 && (instr == em_EXC || instr == em_EXCM || instr == em_EXCP || instr == em_MTA)))
+ util::stream_format(stream, "%d", param);
+ }
+ else
+ {
+ // exception for LG
+ if (instr == em_LG || instr == em_LGCALL)
+ util::stream_format(stream, "$%02X,$%02X", param >> 6, param & 0x3f);
+
+ // exception for LB/LBL
+ else if (instr == em_LB || instr == em_LBL)
+ {
+ // LB x,10 is 0 by default
+ if (instr == em_LB && (param & 0xf) == 10)
+ param &= 0x30;
+
+ util::stream_format(stream, "%d,%d", param >> 4, param & 0xf);
+ }
+
+ else
+ util::stream_format(stream, "$%02X", param);
+ }
+ }
+
+ return len | s_flags[instr] | SUPPORTED;
+}
+
+
+// MM5799 disasm
+
+const u8 mm5799_disassembler::mm5799_opmap[0x100] =
+{
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ em_NOP, em_HXBR, em_ADD, em_SC, em_TF, em_TIR, em_MTA, em_EXC, em_EXCM, em_EXCP, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, // 0
+ em_DSPA, em_DSPS, em_AD, em_LBL, em_TF, em_TKB, em_MTA, em_EXC, em_EXCM, em_EXCP, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, // 1
+ em_COMP, em_AXO, em_SUB, em_RSC, em_TF, em_BTD, em_MTA, em_EXC, em_EXCM, em_EXCP, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, // 2
+ em_0TA, em_HXA, em_TAM, em_LDF, em_READ, em_TIN, em_MTA, em_EXC, em_EXCM, em_EXCP, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, // 3
+
+ em_RET, em_RETS, em_RSM8, em_BTA, em_TM, em_TM, em_TM, em_TM, em_RSM1, em_SM1, em_SM8, em_RSM4, em_RSM2, em_TC, em_SM2, em_SM4, // 4
+ em_ATB, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, em_ADX, // 5
+ em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, em_LG, // 6
+ em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, em_LM, // 7
+
+ em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, // 8
+ em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, // 9
+ em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, // A
+ em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, em_CALL, // B
+
+ em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, // C
+ em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, // D
+ em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, // E
+ em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO, em_GO // F
+};
+
+offs_t mm5799_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ return common_disasm(mm5799_opmap, stream, pc, opcodes, params);
+}
diff --git a/src/devices/cpu/cops1/cops1d.h b/src/devices/cpu/cops1/cops1d.h
new file mode 100644
index 00000000000..1412e0c3c1b
--- /dev/null
+++ b/src/devices/cpu/cops1/cops1d.h
@@ -0,0 +1,65 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ National Semiconductor COPS(MM57 MCU family) disassembler
+
+*/
+
+#ifndef MAME_CPU_COPS1_MM57D_H
+#define MAME_CPU_COPS1_MM57D_H
+
+#pragma once
+
+
+class cops1_common_disassembler : public util::disasm_interface
+{
+public:
+ cops1_common_disassembler();
+ virtual ~cops1_common_disassembler() = default;
+
+ virtual u32 opcode_alignment() const override { return 1; }
+ virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED; }
+ virtual u32 page_address_bits() const override { return 6; }
+ virtual offs_t pc_linear_to_real(offs_t pc) const override { return (pc & ~0x3f) | m_l2r[pc & 0x3f]; }
+ virtual offs_t pc_real_to_linear(offs_t pc) const override { return (pc & ~0x3f) | m_r2l[pc & 0x3f]; }
+
+protected:
+ // opcode mnemonics
+ enum e_mnemonics
+ {
+ em_ILL,
+ em_AD, em_ADD, em_SUB, em_COMP, em_0TA, em_ADX, em_HXA, em_TAM, em_SC, em_RSC, em_TC,
+ em_TIN, em_TF, em_TKB, em_TIR,
+ em_BTD, em_DSPA, em_DSPS, em_AXO, em_LDF, em_READ,
+ em_GO, em_CALL, em_RET, em_RETS, em_LG, em_LGCALL, em_NOP,
+ em_EXC, em_EXCM, em_EXCP, em_MTA, em_LM,
+ em_SM1, em_SM2, em_SM4, em_SM8, em_RSM1, em_RSM2, em_RSM4, em_RSM8, em_TM,
+ em_LB, em_LBL, em_ATB, em_BTA, em_HXBR
+ };
+
+ static const char *const s_name[];
+ static const uint8_t s_bits[];
+ static const uint32_t s_flags[];
+
+ u8 m_l2r[0x40];
+ u8 m_r2l[0x40];
+
+ offs_t increment_pc(offs_t pc);
+ offs_t common_disasm(const u8 *lut_opmap, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params);
+};
+
+class mm5799_disassembler : public cops1_common_disassembler
+{
+public:
+ mm5799_disassembler() = default;
+ virtual ~mm5799_disassembler() = default;
+
+ virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+
+private:
+ static const u8 mm5799_opmap[0x100];
+
+};
+
+#endif // MAME_CPU_COPS1_MM57D_H
diff --git a/src/devices/cpu/cops1/cops1op.cpp b/src/devices/cpu/cops1/cops1op.cpp
new file mode 100644
index 00000000000..1cc20ce61c6
--- /dev/null
+++ b/src/devices/cpu/cops1/cops1op.cpp
@@ -0,0 +1,378 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+
+// COPS opcode handlers
+
+#include "emu.h"
+#include "cops1base.h"
+
+
+// internal helpers
+
+inline u8 cops1_base_device::ram_r()
+{
+ return m_data->read_byte(m_b) & 0xf;
+}
+
+inline void cops1_base_device::ram_w(u8 data)
+{
+ m_data->write_byte(m_b, data & 0xf);
+}
+
+void cops1_base_device::pop_pc()
+{
+ m_pc = m_sa;
+ m_sa = m_sb;
+}
+
+void cops1_base_device::push_pc()
+{
+ m_sb = m_sa;
+ m_sa = m_pc;
+}
+
+
+// opcodes
+
+// arithmetic operations
+
+void cops1_base_device::op_ad()
+{
+ // add M to A
+ m_a = (m_a + ram_r()) & 0xf;
+}
+
+void cops1_base_device::op_add()
+{
+ // ADD: add M+carry to A
+ m_a = m_a + ram_r() + m_c;
+ m_c = (m_a >= 10) ? 1 : 0;
+ m_a &= 0xf;
+ m_skip = !bool(m_c);
+}
+
+void cops1_base_device::op_sub()
+{
+ // SUB: subtract A+carry from M
+ m_a = (m_a ^ 0xf) + ram_r() + m_c;
+ m_c = m_a >> 4 & 1;
+ m_a &= 0xf;
+ m_skip = bool(m_c);
+}
+
+void cops1_base_device::op_comp()
+{
+ // COMP: complement A
+ m_a ^= 0xf;
+}
+
+void cops1_base_device::op_0ta()
+{
+ // 0TA: clear A
+ m_a = 0;
+}
+
+void cops1_base_device::op_adx()
+{
+ // ADX x: add constant to A
+ u8 x = m_op & 0xf;
+ m_a += x;
+ m_skip = ~m_a & 0x10 && x != 6;
+ m_a &= 0xf;
+}
+
+void cops1_base_device::op_hxa()
+{
+ // HXA: exchange A with H
+ u8 h = m_h;
+ m_h = m_a;
+ m_a = h;
+}
+
+void cops1_base_device::op_tam()
+{
+ // TAM: compare A with M
+ m_skip = m_a == ram_r();
+}
+
+void cops1_base_device::op_sc()
+{
+ // SC: set carry
+ m_c = 1;
+}
+
+void cops1_base_device::op_rsc()
+{
+ // RSC: reset carry
+ m_c = 0;
+}
+
+void cops1_base_device::op_tc()
+{
+ // TC: test carry
+ m_skip = !m_c;
+}
+
+
+// input test
+
+void cops1_base_device::op_tin()
+{
+ // TIN: test INB pin
+ bool t = !bool(m_read_inb() & 1);
+ m_skip = m_option_inb_active_high ? t : !t;
+}
+
+void cops1_base_device::op_tf()
+{
+ // TF x: test F pin
+ u8 f = m_read_f.isnull() ? m_f : m_read_f();
+ m_skip = !BIT(f, m_op >> 4 & 3);
+}
+
+void cops1_base_device::op_tkb()
+{
+ // TKB: test K pins
+ bool t = bool(m_read_k() & 0xf);
+ m_skip = m_option_k_active_high ? t : !t;
+}
+
+void cops1_base_device::op_tir()
+{
+ // TIR: test DO3 pin
+ int d = m_read_do3.isnull() ? (m_do >> 2) : m_read_do3();
+ m_skip = !bool(d & 1);
+}
+
+
+// input/output
+
+void cops1_base_device::op_btd()
+{
+ // BTD: transfer B(d) to digit output latches
+ m_do = ~m_b & 0xf;
+ m_write_do(m_do);
+}
+
+void cops1_base_device::op_dspa()
+{
+ // DSPA: transfer A+H+C to segment output latches, direct
+ u8 segs = bitswap<7>(m_h << 4 | m_a, 4,5,6,0,1,2,3);
+ m_write_s((m_c << 7 ^ 0x80) | segs);
+}
+
+void cops1_base_device::op_dsps()
+{
+ // DSPA: transfer A+C to segment output latches, via PLA
+ u8 segs = ~m_opla->read((m_a + 1) & 0xf) & 0x7f;
+ m_write_s((m_c << 7 ^ 0x80) | segs);
+}
+
+void cops1_base_device::op_axo()
+{
+ // AXO: exchange A with serial
+ u8 s = m_serial;
+ m_serial = m_a;
+ m_a = s;
+
+ // mask option to read SI immediately
+ if (m_option_axo_si)
+ m_a = (m_a & 7) | (m_read_si() << 3 & 8);
+}
+
+void cops1_base_device::op_ldf()
+{
+ // LDF: load F pin(s)
+ u8 mask = bitswap<4>(~m_arg, 7,5,3,1);
+ u8 f = bitswap<4>(~m_arg, 6,4,2,0);
+ m_f = (m_f & ~mask) | (f & mask);
+ m_write_f(m_f);
+}
+
+void cops1_base_device::op_read()
+{
+ // READ: read K pins to A
+ m_a = m_read_k() & 0xf;
+}
+
+
+// control functions
+
+void cops1_base_device::op_go()
+{
+ // GO x: jump to address in page
+
+ // jumps from page 0x1e/0x1f reset page to 0x1e
+ if ((m_pc & 0x780) == 0x780)
+ m_pc &= ~0x40;
+
+ m_pc = (m_pc & ~0x3f) | (m_op & 0x3f);
+}
+
+void cops1_base_device::op_call()
+{
+ // CALL: call subroutine
+
+ // calls from page 0x1e/0x1f don't push PC
+ if ((m_pc & 0x780) != 0x780)
+ push_pc();
+
+ m_pc = (m_op & 0x3f) | 0x7c0;
+}
+
+void cops1_base_device::op_ret()
+{
+ // RET: return from subroutine
+ pop_pc();
+}
+
+void cops1_base_device::op_rets()
+{
+ // RET: return from subroutine, skip next
+ op_ret();
+ m_skip = true;
+}
+
+void cops1_base_device::op_lg()
+{
+ // LG x: long go / long call
+ if (~m_arg & 0x40)
+ push_pc();
+
+ m_pc = (~m_op << 7 & 0x780) | (m_arg >> 1 & 0x40) | (m_arg & 0x3f);
+}
+
+void cops1_base_device::op_nop()
+{
+ // NOP: no operation
+}
+
+
+// memory digit operations
+
+void cops1_base_device::op_exc()
+{
+ // EXC x: exchange A with M, XOR B(r) with x
+ u8 a = m_a;
+ m_a = ram_r();
+ ram_w(a);
+ m_b ^= m_op & 0x30;
+}
+
+void cops1_base_device::op_excm()
+{
+ // EXC- x: EXC + decrement B(d)
+ op_exc();
+ m_b = (m_b & ~0xf) | ((m_b - 1) & 0xf);
+ m_skip = (m_b & 0xf) == 0xf;
+}
+
+void cops1_base_device::op_excp()
+{
+ // EXC+ x: EXC + increment B(d)
+ op_exc();
+ m_b = (m_b & ~0xf) | ((m_b + 1) & 0xf);
+ m_skip = (m_b & 0xf) == 0;
+
+ // mask option to also skip on 13
+ if (m_option_excp_skip && (m_b & 0xf) == 13)
+ m_skip = true;
+}
+
+void cops1_base_device::op_mta()
+{
+ // MTA x: load A with M, XOR B(r) with x
+ m_a = ram_r();
+ m_b ^= m_op & 0x30;
+}
+
+void cops1_base_device::op_lm()
+{
+ // LM x: load M with constant, increment B(d)
+ ram_w(m_op & 0xf);
+ m_b = (m_b & ~0xf) | ((m_b + 1) & 0xf);
+}
+
+
+// memory bit operations
+
+void cops1_base_device::op_sm()
+{
+ // SM x: set memory bit
+ u8 x = 0;
+
+ // opcode param is scrambled for some reason
+ switch (m_op & 0xf)
+ {
+ case 0x9: x = 1; break;
+ case 0xe: x = 2; break;
+ case 0xf: x = 4; break;
+ case 0xa: x = 8; break;
+ }
+ ram_w(ram_r() | x);
+}
+
+void cops1_base_device::op_rsm()
+{
+ // RSM x: reset memory bit
+ u8 x = 0;
+
+ // opcode param is scrambled for some reason
+ switch (m_op & 0xf)
+ {
+ case 0x8: x = 1; break;
+ case 0xc: x = 2; break;
+ case 0xb: x = 4; break;
+ case 0x2: x = 8; break;
+ }
+ ram_w(ram_r() & ~x);
+}
+
+void cops1_base_device::op_tm()
+{
+ // TM x: test memory bit
+ m_skip = !BIT(ram_r(), m_op & 3);
+}
+
+
+// memory address operations
+
+void cops1_base_device::op_lb()
+{
+ // LB x: load B (successive LB are ignored)
+ if ((m_prev_op & 0xc0) == 0x00 && (m_prev_op & 0xf) >= 0xa)
+ return;
+
+ // d 10 actual value is a mask option
+ u8 x = m_op & 0xf;
+ if (x == 10)
+ x = m_option_lb_10;
+
+ m_b = ((m_op & 0x30) | x) & m_datamask;
+}
+
+void cops1_base_device::op_lbl()
+{
+ // LBL x: load B fully
+ m_b = m_arg & m_datamask;
+}
+
+void cops1_base_device::op_atb()
+{
+ // ATB: transfer A to B(d)
+ m_b = (m_b & ~0xf) | m_a;
+}
+
+void cops1_base_device::op_bta()
+{
+ // BTA: transfer B(d) to A
+ m_a = m_b & 0xf;
+}
+
+void cops1_base_device::op_hxbr()
+{
+ // HXBR: exchange H with B(r)
+ u8 h = m_h;
+ m_h = m_b >> 4;
+ m_b = (h << 4 | (m_b & 0xf)) & m_datamask;
+}
diff --git a/src/devices/cpu/cops1/mm5799.cpp b/src/devices/cpu/cops1/mm5799.cpp
new file mode 100644
index 00000000000..bffb5e64a66
--- /dev/null
+++ b/src/devices/cpu/cops1/mm5799.cpp
@@ -0,0 +1,153 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ National Semiconductor MM5799 MCU
+
+*/
+
+#include "emu.h"
+#include "mm5799.h"
+
+#include "cops1d.h"
+
+
+DEFINE_DEVICE_TYPE(MM5799, mm5799_device, "mm5799", "National Semiconductor MM5799")
+
+
+// internal memory maps
+void mm5799_device::program_map(address_map &map)
+{
+ map(0x0000, 0x01ff).rom();
+ map(0x0400, 0x07ff).rom();
+}
+
+void mm5799_device::data_map(address_map &map)
+{
+ if (m_option_ram_d12)
+ {
+ // 8x12x4
+ for (int i = 0; i < 0x80; i += 0x10)
+ map(i | 0x04, i | 0x0f).ram();
+ }
+ else
+ {
+ // 6x16x4
+ map(0x00, 0x5f).ram();
+ }
+}
+
+
+// device definitions
+mm5799_device::mm5799_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ cops1_base_device(mconfig, MM5799, tag, owner, clock, 11, address_map_constructor(FUNC(mm5799_device::program_map), this), 7, address_map_constructor(FUNC(mm5799_device::data_map), this))
+{ }
+
+
+// disasm
+std::unique_ptr<util::disasm_interface> mm5799_device::create_disassembler()
+{
+ return std::make_unique<mm5799_disassembler>();
+}
+
+
+// initialize
+void mm5799_device::device_start()
+{
+ cops1_base_device::device_start();
+}
+
+void mm5799_device::device_reset()
+{
+ cops1_base_device::device_reset();
+}
+
+
+//-------------------------------------------------
+// execute
+//-------------------------------------------------
+
+void mm5799_device::execute_one()
+{
+ switch (m_op & 0xc0)
+ {
+ case 0x00:
+ switch (m_op)
+ {
+ case 0x00: op_nop(); break;
+ case 0x10: op_dspa(); break;
+ case 0x20: op_comp(); break;
+ case 0x30: op_0ta(); break;
+
+ case 0x01: op_hxbr(); break;
+ case 0x11: op_dsps(); break;
+ case 0x21: op_axo(); break;
+ case 0x31: op_hxa(); break;
+
+ case 0x02: op_add(); break;
+ case 0x12: op_ad(); break;
+ case 0x22: op_sub(); break;
+ case 0x32: op_tam(); break;
+
+ case 0x03: op_sc(); break;
+ case 0x13: op_lbl(); break;
+ case 0x23: op_rsc(); break;
+ case 0x33: op_ldf(); break;
+
+ case 0x34: op_read(); break;
+
+ case 0x05: op_tir(); break;
+ case 0x15: op_tkb(); break;
+ case 0x25: op_btd(); break;
+ case 0x35: op_tin(); break;
+
+ case 0x04: case 0x14: case 0x24: op_tf(); break;
+
+ case 0x06: case 0x16: case 0x26: case 0x36: op_mta(); break;
+ case 0x07: case 0x17: case 0x27: case 0x37: op_exc(); break;
+ case 0x08: case 0x18: case 0x28: case 0x38: op_excm(); break;
+ case 0x09: case 0x19: case 0x29: case 0x39: op_excp(); break;
+
+ default: op_lb(); break;
+ }
+ break; // 0x00
+
+ case 0x40:
+ switch (m_op & 0x30)
+ {
+ case 0x00:
+ switch (m_op & 0x0f)
+ {
+ case 0x00: op_ret(); break;
+ case 0x01: op_rets(); break;
+ case 0x03: op_bta(); break;
+ case 0x0d: op_tc(); break;
+
+ case 0x02: case 0x08: case 0x0b: case 0x0c: op_rsm(); break;
+ case 0x04: case 0x05: case 0x06: case 0x07: op_tm(); break;
+ case 0x09: case 0x0a: case 0x0e: case 0x0f: op_sm(); break;
+ }
+ break;
+
+ case 0x10:
+ if ((m_op & 0x0f) != 0)
+ op_adx();
+ else
+ op_atb();
+ break;
+
+ case 0x20: op_lg(); break;
+ case 0x30: op_lm(); break;
+ }
+ break; // 0x40
+
+ case 0x80: op_call(); break;
+ case 0xc0: op_go(); break;
+ }
+}
+
+bool mm5799_device::op_argument()
+{
+ // 2-byte instructions: LBL, LDF, LG
+ return m_op == 0x13 || m_op == 0x33 || (m_op & 0xf0) == 0x60;
+}
diff --git a/src/devices/cpu/cops1/mm5799.h b/src/devices/cpu/cops1/mm5799.h
new file mode 100644
index 00000000000..d8f568e3808
--- /dev/null
+++ b/src/devices/cpu/cops1/mm5799.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ National Semiconductor MM5799 MCU
+
+*/
+
+#ifndef MAME_CPU_COPS1_MM5799_H
+#define MAME_CPU_COPS1_MM5799_H
+
+#pragma once
+
+#include "cops1base.h"
+
+// pinout reference
+
+/*
+ ____ ____
+ K1 1 |* \_/ | 28 DO1
+ K2 2 | | 27 DO2
+ K3 3 | | 26 DO3
+ K4 4 | | 25 DO4
+ INB 5 | | 24 SI
+ SYNC 6 | | 23 SO
+ OSC 7 | MM5799N | 22 BLK
+ F3 8 | | 21 Vdd
+ F2 9 | | 20 Sa
+ F1 10 | | 19 Sb
+ PWR ON 11 | | 18 Sc
+ Sp 12 | | 17 Sd
+ Sg 13 | | 16 Se
+ Sf 14 |___________| 15 Vss
+
+*/
+
+class mm5799_device : public cops1_base_device
+{
+public:
+ mm5799_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_disasm_interface overrides
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+ // device_execute_interface overrides
+ virtual void execute_one() override;
+ virtual bool op_argument() override;
+
+ void data_map(address_map &map);
+ void program_map(address_map &map);
+};
+
+
+DECLARE_DEVICE_TYPE(MM5799, mm5799_device)
+
+#endif // MAME_CPU_COPS1_MM5799_H
diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp
index 8396d8e3107..cd4bdd7e4c8 100644
--- a/src/devices/cpu/sm510/sm500core.cpp
+++ b/src/devices/cpu/sm510/sm500core.cpp
@@ -136,7 +136,7 @@ void sm500_device::clock_melody()
// output to R pins
if (out != m_r_out)
{
- m_write_r(0, out, 0xff);
+ m_write_r(out);
m_r_out = out;
}
}
diff --git a/src/devices/cpu/sm510/sm510.h b/src/devices/cpu/sm510/sm510.h
index 713d422e1e2..86240d18c99 100644
--- a/src/devices/cpu/sm510/sm510.h
+++ b/src/devices/cpu/sm510/sm510.h
@@ -298,7 +298,7 @@ protected:
virtual void execute_one() override;
virtual void get_opcode_param() override;
- virtual void update_w_latch() override { m_write_s(0, m_w, 0xff); } // W is connected directly to S
+ virtual void update_w_latch() override { m_write_s(m_w); } // W is connected directly to S
virtual void clock_melody() override;
};
diff --git a/src/devices/cpu/sm510/sm510base.cpp b/src/devices/cpu/sm510/sm510base.cpp
index 81b027aade8..f5f0ae6bbb2 100644
--- a/src/devices/cpu/sm510/sm510base.cpp
+++ b/src/devices/cpu/sm510/sm510base.cpp
@@ -161,7 +161,7 @@ void sm510_base_device::device_reset()
m_y = 0;
m_r = m_r_out = 0;
- m_write_r(0, 0, 0xff);
+ m_write_r(0);
}
diff --git a/src/devices/cpu/sm510/sm510core.cpp b/src/devices/cpu/sm510/sm510core.cpp
index 80ab6bf6ab3..b2a8c375499 100644
--- a/src/devices/cpu/sm510/sm510core.cpp
+++ b/src/devices/cpu/sm510/sm510core.cpp
@@ -74,7 +74,7 @@ void sm510_device::clock_melody()
// output to R pins
if (out != m_r_out)
{
- m_write_r(0, out, 0xff);
+ m_write_r(out);
m_r_out = out;
}
}
diff --git a/src/devices/cpu/sm510/sm510op.cpp b/src/devices/cpu/sm510/sm510op.cpp
index acaf607f9df..52516c16503 100644
--- a/src/devices/cpu/sm510/sm510op.cpp
+++ b/src/devices/cpu/sm510/sm510op.cpp
@@ -203,7 +203,7 @@ void sm510_base_device::op_lax()
void sm510_base_device::op_ptw()
{
// PTW: output W latch
- m_write_s(0, m_w, 0xff);
+ m_write_s(m_w);
}
void sm510_base_device::op_wr()
@@ -226,7 +226,7 @@ void sm510_base_device::op_ws()
void sm510_base_device::op_kta()
{
// KTA: input K to ACC
- m_acc = m_read_k(0, 0xff) & 0xf;
+ m_acc = m_read_k() & 0xf;
}
void sm510_base_device::op_atbp()
diff --git a/src/devices/cpu/sm510/sm511core.cpp b/src/devices/cpu/sm510/sm511core.cpp
index c7a26de07e2..70df0cd1c0e 100644
--- a/src/devices/cpu/sm510/sm511core.cpp
+++ b/src/devices/cpu/sm510/sm511core.cpp
@@ -138,7 +138,7 @@ void sm511_device::clock_melody()
// output to R pin
if (out != m_r_out)
{
- m_write_r(0, out, 0xff);
+ m_write_r(out);
m_r_out = out;
}
}
diff --git a/src/devices/cpu/sm510/sm590core.cpp b/src/devices/cpu/sm510/sm590core.cpp
index 0763af6e654..fd1bca5fc9d 100644
--- a/src/devices/cpu/sm510/sm590core.cpp
+++ b/src/devices/cpu/sm510/sm590core.cpp
@@ -73,7 +73,7 @@ void sm590_device::device_reset()
m_clk_div = 4; // 4 clock oscillations per cycle on SM59x, see datasheet page 30/pdf page 39
m_rports[0] = m_rports[1] = m_rports[2] = m_rports[3] = 0;
- //m_write_r(0, 0, 0xff); // TODO: are the four ports zeroed on reset?
+ //m_write_r(0); // TODO: are the four ports zeroed on reset?
}
//-------------------------------------------------
diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h
index e535e9322c9..f03d4db24d4 100644
--- a/src/devices/cpu/tms1000/tms1k_base.h
+++ b/src/devices/cpu/tms1000/tms1k_base.h
@@ -20,7 +20,6 @@
// pinout reference
/*
-
____ ____ ____ ____
R8 1 |* \_/ | 28 R7 R0 1 |* \_/ | 28 Vss
R9 2 | | 27 R6 R1 2 | | 27 OSC2
diff --git a/src/mame/drivers/hh_cop400.cpp b/src/mame/drivers/hh_cop400.cpp
index a5868547101..d331f933570 100644
--- a/src/mame/drivers/hh_cop400.cpp
+++ b/src/mame/drivers/hh_cop400.cpp
@@ -3,8 +3,8 @@
// thanks-to:Sean Riddle
/***************************************************************************
- National Semiconductor COP400 MCU handhelds or other simple devices,
- mostly LED electronic games/toys.
+ National Semiconductor COPS(COP400 MCU series) handhelds or other simple
+ devices, mostly LED electronic games/toys.
TODO:
- why does h2hbaskbc(and clones) need a workaround on writing L pins?
@@ -1691,7 +1691,8 @@ ROM_END
* COP420 MCU label COP420-NPG/N
* 8-digit 7seg led display(1 custom digit), 1 green led, no sound
- This is the COP420 version, the first release was on a MM5799 MCU.
+ This is the COP420 version, the first release was on a MM5799 MCU,
+ see hh_cops1.cpp.
***************************************************************************/
@@ -1720,8 +1721,8 @@ void qkracer_state::update_display()
void qkracer_state::write_d(u8 data)
{
- // D: select digit, D3: input mux high bit
- m_inp_mux = (m_inp_mux & 0xf) | (data << 1 & 0x10);
+ // D: select digit, D3: input mux low bit
+ m_inp_mux = (m_inp_mux & ~1) | (data >> 3 & 1);
m_d = data & 0xf;
update_display();
}
@@ -1729,7 +1730,7 @@ void qkracer_state::write_d(u8 data)
void qkracer_state::write_g(u8 data)
{
// G: select digit, input mux
- m_inp_mux = (m_inp_mux & 0x10) | (data & 0xf);
+ m_inp_mux = (m_inp_mux & 1) | (data << 1 & 0x1e);
m_g = data & 0xf;
update_display();
}
@@ -1757,42 +1758,42 @@ WRITE_LINE_MEMBER(qkracer_state::write_sk)
// config
static INPUT_PORTS_START( qkracer )
- PORT_START("IN.0") // G0 port IN
+ PORT_START("IN.0") // D3 port IN
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Amateur")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Pro")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Complex")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Tables")
+
+ PORT_START("IN.1") // G0 port IN
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME(UTF8_DIVIDE)
- PORT_START("IN.1") // G1 port IN
+ PORT_START("IN.2") // G1 port IN
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME(UTF8_MULTIPLY)
- PORT_START("IN.2") // G2 port IN
+ PORT_START("IN.3") // G2 port IN
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("-")
- PORT_START("IN.3") // G3 port IN
+ PORT_START("IN.4") // G3 port IN
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS) PORT_NAME("Slow")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_EQUALS) PORT_NAME("Fast")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("+")
-
- PORT_START("IN.4") // D3 port IN
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Amateur")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Pro")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Complex")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Tables")
INPUT_PORTS_END
void qkracer_state::qkracer(machine_config &config)
{
/* basic machine hardware */
- COP420(config, m_maincpu, 1000000); // approximation - RC osc. R=47K, C=100pF
- m_maincpu->set_config(COP400_CKI_DIVISOR_32, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
+ COP420(config, m_maincpu, 950000); // approximation - RC osc. R=47K, C=100pF
+ m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
m_maincpu->write_d().set(FUNC(qkracer_state::write_d));
m_maincpu->write_g().set(FUNC(qkracer_state::write_g));
m_maincpu->write_l().set(FUNC(qkracer_state::write_l));
@@ -1948,7 +1949,7 @@ CONS( 1980, plus1, 0, 0, plus1, plus1, plus1_state, e
CONS( 1981, lightfgt, 0, 0, lightfgt, lightfgt, lightfgt_state, empty_init, "Milton Bradley", "Electronic Lightfight - The Games of Dueling Lights", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
CONS( 1982, bship82, bship, 0, bship82, bship82, bship82_state, empty_init, "Milton Bradley", "Electronic Battleship (1982 version)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // ***
-CONS( 1978, qkracer, 0, 0, qkracer, qkracer, qkracer_state, empty_init, "National Semiconductor", "QuizKid Racer (COP420 version)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )
+CONS( 1979, qkracer, 0, 0, qkracer, qkracer, qkracer_state, empty_init, "National Semiconductor", "QuizKid Racer (COP420 version)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )
CONS( 1987, vidchal, 0, 0, vidchal, vidchal, vidchal_state, empty_init, "Select Merchandise", "Video Challenger", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING )
diff --git a/src/mame/drivers/hh_cops1.cpp b/src/mame/drivers/hh_cops1.cpp
new file mode 100644
index 00000000000..1f8cbe5a3bf
--- /dev/null
+++ b/src/mame/drivers/hh_cops1.cpp
@@ -0,0 +1,577 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+// thanks-to:Sean Riddle
+/***************************************************************************
+
+ National Semiconductor COPS(MM57 MCU series) handhelds
+
+ TODO:
+ - qkracerm RAM configuration is unknown (it also works fine with 8x12)
+ - qkracerm link cable
+
+***************************************************************************/
+
+#include "emu.h"
+
+#include "cpu/cops1/mm5799.h"
+#include "machine/ds8874.h"
+#include "video/pwm.h"
+#include "sound/spkrdev.h"
+#include "speaker.h"
+
+// internal artwork
+#include "mbaskb.lh"
+#include "qkracerm.lh"
+#include "qkspeller.lh"
+
+//#include "hh_cops1_test.lh" // common test-layout - use external artwork
+
+
+class hh_cops1_state : public driver_device
+{
+public:
+ hh_cops1_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_display(*this, "display"),
+ m_speaker(*this, "speaker"),
+ m_inputs(*this, "IN.%u", 0)
+ { }
+
+ // devices
+ required_device<cops1_base_device> m_maincpu;
+ optional_device<pwm_display_device> m_display;
+ optional_device<speaker_sound_device> m_speaker;
+ optional_ioport_array<9> m_inputs; // max 9
+
+ u16 m_inp_mux = 0;
+ u16 m_grid = 0;
+
+ // MCU output pin state
+ u8 m_s = 0;
+ u8 m_do = 0;
+ u8 m_f = 0;
+ int m_blk = false;
+
+ u8 read_inputs(int columns);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+};
+
+
+// machine start/reset
+
+void hh_cops1_state::machine_start()
+{
+ // register for savestates
+ save_item(NAME(m_inp_mux));
+ save_item(NAME(m_grid));
+ save_item(NAME(m_s));
+ save_item(NAME(m_do));
+ save_item(NAME(m_f));
+ save_item(NAME(m_blk));
+}
+
+void hh_cops1_state::machine_reset()
+{
+}
+
+
+
+/***************************************************************************
+
+ Helper Functions
+
+***************************************************************************/
+
+// generic input handlers
+
+u8 hh_cops1_state::read_inputs(int columns)
+{
+ u8 ret = 0;
+
+ // read selected input rows
+ for (int i = 0; i < columns; i++)
+ if (m_inp_mux >> i & 1)
+ ret |= m_inputs[i]->read();
+
+ return ret;
+}
+
+
+
+/***************************************************************************
+
+ Minidrivers (subclass, I/O, Inputs, Machine Config, ROM Defs)
+
+***************************************************************************/
+
+namespace {
+
+/***************************************************************************
+
+ Mattel Basketball (model 2437)
+ * PCB label: MA 6017/18/19
+ * MM5799 MCU bonded directly to PCB (die label MM4799 C NCX)
+ * 4001 and 74145, also bonded to PCB
+ * 2-digit 7seg led display, 21 leds, 2-bit sound
+
+ Judging from videos online, there are two versions of Basketball. One where
+ the display shows "12" at power-on(as on MAME), and one that shows "15".
+
+ Mattel Hockey and Soccer are on nearly identical hardware.
+
+***************************************************************************/
+
+class mbaskb_state : public hh_cops1_state
+{
+public:
+ mbaskb_state(const machine_config &mconfig, device_type type, const char *tag) :
+ hh_cops1_state(mconfig, type, tag)
+ { }
+
+ void update_display();
+ void write_do(u8 data);
+ void write_blk(int state);
+ void write_s(u8 data);
+ void write_f(u8 data);
+ u8 read_f();
+ void mbaskb(machine_config &config);
+};
+
+// handlers
+
+void mbaskb_state::update_display()
+{
+ // DO4321: 74154 CBAD
+ u8 d = (m_do >> 1 & 7) | (m_do << 3 & 8);
+ u16 sel = m_blk ? (1 << d) : 0;
+
+ // 74154 output 2,6: speaker out
+ u8 spk = bitswap<2>(sel, 6,2);
+ m_speaker->level_w(spk);
+
+ // 74154 output 3-5,10-13: digit/led select
+ u8 dsp = bitswap<7>(sel, 11,4,12,5,13,3,10);
+ m_display->matrix((m_f << 5 & 0x80) | dsp, m_s);
+}
+
+void mbaskb_state::write_do(u8 data)
+{
+ // DO: 74154 inputs
+ m_do = data;
+ update_display();
+}
+
+void mbaskb_state::write_blk(int state)
+{
+ // BLK: 74154 enable
+ m_blk = state;
+ update_display();
+}
+
+void mbaskb_state::write_s(u8 data)
+{
+ // Sa-Sg: digit segment/led data
+ m_s = data;
+ update_display();
+}
+
+void mbaskb_state::write_f(u8 data)
+{
+ // F3: led data
+ m_f = data;
+ update_display();
+}
+
+u8 mbaskb_state::read_f()
+{
+ // F1: difficulty switch
+ return m_inputs[2]->read() | (m_f & 2);
+}
+
+// config
+
+static INPUT_PORTS_START( mbaskb )
+ PORT_START("IN.0") // port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
+
+ PORT_START("IN.1") // INB
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
+
+ PORT_START("IN.2") // F1
+ PORT_CONFNAME( 0x01, 0x00, DEF_STR( Difficulty ) )
+ PORT_CONFSETTING( 0x00, "1" )
+ PORT_CONFSETTING( 0x01, "2" )
+INPUT_PORTS_END
+
+void mbaskb_state::mbaskb(machine_config &config)
+{
+ /* basic machine hardware */
+ MM5799(config, m_maincpu, 370000); // approximation
+ m_maincpu->write_do().set(FUNC(mbaskb_state::write_do));
+ m_maincpu->write_blk().set(FUNC(mbaskb_state::write_blk));
+ m_maincpu->write_s().set(FUNC(mbaskb_state::write_s));
+ m_maincpu->write_f().set(FUNC(mbaskb_state::write_f));
+ m_maincpu->read_f().set(FUNC(mbaskb_state::read_f));
+ m_maincpu->read_k().set_ioport("IN.0");
+ m_maincpu->read_inb().set_ioport("IN.1");
+
+ /* video hardware */
+ PWM_DISPLAY(config, m_display).set_size(8, 7);
+ m_display->set_segmask(3, 0x7f);
+ m_display->set_bri_levels(0.01, 0.2); // player led is brighter
+ config.set_default_layout(layout_mbaskb);
+
+ /* sound hardware */
+ SPEAKER(config, "mono").front_center();
+ SPEAKER_SOUND(config, m_speaker);
+ static const double speaker_levels[4] = { 0.0, 1.0, -1.0, 0.0 };
+ m_speaker->set_levels(4, speaker_levels);
+ m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
+}
+
+// roms
+
+ROM_START( mbaskb )
+ ROM_REGION( 0x0800, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD( "mm4799_c_ncx", 0x0000, 0x0200, CRC(d0e5fce1) SHA1(04708c043a763bf92d765095e9551388a1d967e8) )
+ ROM_CONTINUE( 0x0400, 0x0400 )
+
+ ROM_REGION( 254, "maincpu:opla", 0 )
+ ROM_LOAD( "mm5799_mbaskb_output.pla", 0, 254, CRC(c8d225f1) SHA1(4f1e1977e96e53d1d716b7785c4c3971ed9ff65b) )
+ROM_END
+
+
+
+
+
+/***************************************************************************
+
+ National Semiconductor QuizKid Racer (MM5799 version)
+ * MM5799 MCU bonded directly to PCB (die label MM4799 C DUZ)
+ * DS8874 LED driver, die bonded to PCB as well
+ * 8-digit 7seg led display(1 custom digit), 1 green led, no sound
+ * optional link cable to compete with another player (see patent US4051605)
+
+ This is the first version of QuizKid Racer, the 2nd release is on a
+ COP420 MCU, see hh_cop400.cpp.
+
+***************************************************************************/
+
+class qkracerm_state : public hh_cops1_state
+{
+public:
+ qkracerm_state(const machine_config &mconfig, device_type type, const char *tag) :
+ hh_cops1_state(mconfig, type, tag),
+ m_ds8874(*this, "ds8874")
+ { }
+
+ required_device<ds8874_device> m_ds8874;
+ void ds8874_output_w(u16 data);
+
+ void update_display();
+ void write_do(u8 data);
+ void write_s(u8 data);
+ u8 read_k();
+ void qkracerm(machine_config &config);
+};
+
+// handlers
+
+void qkracerm_state::update_display()
+{
+ m_display->matrix(m_grid, m_s);
+}
+
+void qkracerm_state::ds8874_output_w(u16 data)
+{
+ // DS8874N outputs: digit select, input mux
+ m_grid = ~data;
+ m_inp_mux = m_grid >> 3;
+ update_display();
+}
+
+void qkracerm_state::write_do(u8 data)
+{
+ // DO1: DS8874N CP
+ // DO4: DS8874N _DATA
+ m_ds8874->cp_w(BIT(data, 0));
+ m_ds8874->data_w(BIT(data, 3));
+}
+
+void qkracerm_state::write_s(u8 data)
+{
+ // S: digit segment data
+ m_s = data;
+ update_display();
+}
+
+u8 qkracerm_state::read_k()
+{
+ // K: multiplexed inputs
+ return read_inputs(5);
+}
+
+// config
+
+static INPUT_PORTS_START( qkracerm )
+ PORT_START("IN.0") // DS8874 OUT 4 port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Amateur")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Pro")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Complex")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Tables")
+
+ PORT_START("IN.1") // DS8874 OUT 5 port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME(UTF8_DIVIDE)
+
+ PORT_START("IN.2") // DS8874 OUT 6 port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME(UTF8_MULTIPLY)
+
+ PORT_START("IN.3") // DS8874 OUT 7 port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("-")
+
+ PORT_START("IN.4") // DS8874 OUT 8 port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS) PORT_NAME("Slow")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_EQUALS) PORT_NAME("Fast")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("+")
+INPUT_PORTS_END
+
+void qkracerm_state::qkracerm(machine_config &config)
+{
+ /* basic machine hardware */
+ MM5799(config, m_maincpu, 220000); // approximation
+ m_maincpu->set_option_lb_10(5);
+ m_maincpu->write_do().set(FUNC(qkracerm_state::write_do));
+ m_maincpu->write_s().set(FUNC(qkracerm_state::write_s));
+ m_maincpu->read_k().set(FUNC(qkracerm_state::read_k));
+
+ /* video hardware */
+ DS8874(config, m_ds8874).write_output().set(FUNC(qkracerm_state::ds8874_output_w));
+ PWM_DISPLAY(config, m_display).set_size(9, 7);
+ m_display->set_segmask(0xdf, 0x7f);
+ m_display->set_segmask(0x20, 0x41); // equals sign
+ config.set_default_layout(layout_qkracerm);
+
+ /* no sound! */
+}
+
+// roms
+
+ROM_START( qkracerm )
+ ROM_REGION( 0x0800, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD( "mm4799_c_duz", 0x0000, 0x0200, CRC(8b484d2a) SHA1(809e902a11e23bed010ac795ab8dc50e5c1869dc) )
+ ROM_CONTINUE( 0x0400, 0x0400 )
+
+ ROM_REGION( 254, "maincpu:opla", 0 )
+ ROM_LOAD( "mm5799_qkracerm_output.pla", 0, 254, CRC(f095fc51) SHA1(e3321d5cc4ecef363df7ef94f47e860c7a6d8c7e) )
+ROM_END
+
+
+
+
+
+/***************************************************************************
+
+ National Semiconductor QuizKid Speller
+ * MM5799 MCU bonded directly to PCB (die label MM4799 C NDF)
+ * 2-digit 7seg led display, green led, red led, no sound
+
+ The manual included 99 pictures for matching the words, with increased
+ difficulty. For example 10 = owl, 90 = kangaroo.
+
+ Modes:
+ - Spell: match numbered picture with word
+ - Learn: same as Spell, but only the 1st letter
+ - Game: player 1 enters word, player 2 needs to guess it
+
+***************************************************************************/
+
+class qkspeller_state : public hh_cops1_state
+{
+public:
+ qkspeller_state(const machine_config &mconfig, device_type type, const char *tag) :
+ hh_cops1_state(mconfig, type, tag)
+ { }
+
+ void update_display();
+ void write_do(u8 data);
+ void write_s(u8 data);
+ void write_f(u8 data);
+ u8 read_f();
+ u8 read_k();
+ void qkspeller(machine_config &config);
+};
+
+// handlers
+
+void qkspeller_state::update_display()
+{
+ m_display->matrix((m_f << 1 & 0xc) | (m_do & 3), m_inp_mux);
+}
+
+void qkspeller_state::write_do(u8 data)
+{
+ // DO1,DO2: digit select
+ m_do = data;
+ update_display();
+}
+
+void qkspeller_state::write_s(u8 data)
+{
+ // S: digit segment data, input mux
+ m_inp_mux = data;
+ update_display();
+}
+
+void qkspeller_state::write_f(u8 data)
+{
+ // F2,F3: led data
+ m_f = data;
+ update_display();
+}
+
+u8 qkspeller_state::read_f()
+{
+ // F1: 3-pos switch (GND, floating, Vcc)
+ if (m_inputs[8]->read() == 2)
+ return m_f;
+ else
+ return (m_inputs[8]->read() & 1) | (m_f & ~1);
+}
+
+u8 qkspeller_state::read_k()
+{
+ // K: multiplexed inputs
+ return read_inputs(8);
+}
+
+// config
+
+static INPUT_PORTS_START( qkspeller )
+ PORT_START("IN.0") // Sa port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
+
+ PORT_START("IN.1") // Sb port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
+
+ PORT_START("IN.2") // Sc port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
+
+ PORT_START("IN.3") // Sd port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
+
+ PORT_START("IN.4") // Se port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL) PORT_CHAR(8) PORT_NAME("Erase")
+
+ PORT_START("IN.5") // Sf port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+
+ PORT_START("IN.6") // Sg port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
+
+ PORT_START("IN.7") // Sp port K
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("Start")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13) PORT_NAME("Next")
+
+ PORT_START("IN.8") // F1
+ PORT_CONFNAME( 0x03, 0x00, "Mode" )
+ PORT_CONFSETTING( 0x00, "Spell" )
+ PORT_CONFSETTING( 0x02, "Learn" )
+ PORT_CONFSETTING( 0x01, "Game" )
+
+ PORT_START("TEST.0") // INB test pad
+ PORT_CONFNAME( 0x01, 0x00, "Factory Test 1" )
+ PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
+ PORT_CONFSETTING( 0x01, DEF_STR( On ) )
+
+ PORT_START("TEST.1") // DO3 test pad
+ PORT_CONFNAME( 0x01, 0x00, "Factory Test 2" )
+ PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
+ PORT_CONFSETTING( 0x01, DEF_STR( On ) )
+INPUT_PORTS_END
+
+void qkspeller_state::qkspeller(machine_config &config)
+{
+ /* basic machine hardware */
+ MM5799(config, m_maincpu, 220000); // approximation
+ m_maincpu->write_do().set(FUNC(qkspeller_state::write_do));
+ m_maincpu->write_s().set(FUNC(qkspeller_state::write_s));
+ m_maincpu->write_f().set(FUNC(qkspeller_state::write_f));
+ m_maincpu->read_f().set(FUNC(qkspeller_state::read_f));
+ m_maincpu->read_k().set(FUNC(qkspeller_state::read_k));
+ m_maincpu->read_inb().set_ioport("TEST.0");
+ m_maincpu->read_do3().set_ioport("TEST.1");
+
+ /* video hardware */
+ PWM_DISPLAY(config, m_display).set_size(4, 7);
+ m_display->set_segmask(3, 0x7f);
+ config.set_default_layout(layout_qkspeller);
+
+ /* no sound! */
+}
+
+// roms
+
+ROM_START( qkspeller )
+ ROM_REGION( 0x0800, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD( "mm4799_c_ndf", 0x0000, 0x0200, CRC(0f497a12) SHA1(78eb79dcc414ed2a955450ffb3be431ecc2edb0c) )
+ ROM_CONTINUE( 0x0400, 0x0400 )
+
+ ROM_REGION( 254, "maincpu:opla", 0 )
+ ROM_LOAD( "mm5799_qkspeller_output.pla", 0, 254, CRC(c8d225f1) SHA1(4f1e1977e96e53d1d716b7785c4c3971ed9ff65b) )
+ROM_END
+
+
+
+} // anonymous namespace
+
+/***************************************************************************
+
+ Game driver(s)
+
+***************************************************************************/
+
+// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
+CONS( 1978, mbaskb, 0, 0, mbaskb, mbaskb, mbaskb_state, empty_init, "Mattel", "Basketball (Mattel)", MACHINE_SUPPORTS_SAVE )
+
+CONS( 1977, qkracerm, qkracer, 0, qkracerm, qkracerm, qkracerm_state, empty_init, "National Semiconductor", "QuizKid Racer (MM5799 version)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW | MACHINE_NODEVICE_LAN )
+CONS( 1978, qkspeller, 0, 0, qkspeller, qkspeller, qkspeller_state, empty_init, "National Semiconductor", "QuizKid Speller", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )
diff --git a/src/mame/layout/aim65.lay b/src/mame/layout/aim65.lay
index da6ed02aa7b..98adf2f4bc8 100644
--- a/src/mame/layout/aim65.lay
+++ b/src/mame/layout/aim65.lay
@@ -26,7 +26,7 @@ copyright-holders:Dirk Best, Eric Roberts
<bounds left="50" top="20" right="770" bottom="141" />
</element>
- <!-- element -->
+ <!-- bezel -->
<element ref="static_white"><bounds left="50" top="20" right="770" bottom="141" /></element>
<element ref="static_black"><bounds left="53" top="23" right="767" bottom="138" /></element>
diff --git a/src/mame/layout/cnbaskb.lay b/src/mame/layout/cnbaskb.lay
index 040c6845d63..e158ab2d898 100644
--- a/src/mame/layout/cnbaskb.lay
+++ b/src/mame/layout/cnbaskb.lay
@@ -36,7 +36,7 @@ license:CC0
<element ref="text_time"><bounds x="3.666" y="1" width="6" height="2" /></element>
<element ref="text_score"><bounds x="12.666" y="1" width="6" height="2" /></element>
- <!-- element -->
+ <!-- bezel -->
<element ref="static_white"><bounds x="2" y="4" width="18.1" height="13" /></element>
<element ref="static_black"><bounds x="2.2" y="4.2" width="17.6" height="12.6" /></element>
diff --git a/src/mame/layout/cnfball2.lay b/src/mame/layout/cnfball2.lay
index 86a271744da..7d7c8a88d7d 100644
--- a/src/mame/layout/cnfball2.lay
+++ b/src/mame/layout/cnfball2.lay
@@ -69,7 +69,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="-8.99" right="392.99" top="-104" bottom="186" />
- <!-- element -->
+ <!-- bezel -->
<element ref="static_green"><bounds left="-9" right="393" top="-110" bottom="-60" /></element>
<element ref="static_green"><bounds left="-9" right="393" top="111" bottom="200" /></element>
diff --git a/src/mame/layout/cqback.lay b/src/mame/layout/cqback.lay
index f49d451c2a2..6c222e081d7 100644
--- a/src/mame/layout/cqback.lay
+++ b/src/mame/layout/cqback.lay
@@ -77,7 +77,7 @@ license:CC0
<bounds left="-9" right="393" top="-130" bottom="156" />
</element>
- <!-- element -->
+ <!-- bezel -->
<element ref="static_white"><bounds left="-9" right="393" top="-130" bottom="-60" /></element>
<element ref="static_green"><bounds left="-9" right="393" top="111" bottom="156" /></element>
diff --git a/src/mame/layout/ebaskb2.lay b/src/mame/layout/ebaskb2.lay
index b05e58b14f0..33d50a09dbd 100644
--- a/src/mame/layout/ebaskb2.lay
+++ b/src/mame/layout/ebaskb2.lay
@@ -73,7 +73,7 @@ license:CC0
</element>
- <!-- main element -->
+ <!-- main bezel -->
<element ref="static_white"><bounds x="19.3" y="19.3" width="15.4" height="27.4" /></element>
<element ref="static_black2"><bounds x="19.5" y="19.5" width="15.0" height="27.0" /></element>
diff --git a/src/mame/layout/ebball.lay b/src/mame/layout/ebball.lay
index 8b5962ff955..e5316131664 100644
--- a/src/mame/layout/ebball.lay
+++ b/src/mame/layout/ebball.lay
@@ -71,7 +71,7 @@ license:CC0
<bounds left="0" right="100" top="0" bottom="114" />
</element>
- <!-- outer element -->
+ <!-- outer bezel -->
<element ref="text_score"><bounds x="5.5" y="2" width="8" height="3" /></element>
<element ref="text_count"><bounds x="86" y="2" width="8" height="3" /></element>
@@ -91,7 +91,6 @@ license:CC0
<element name="7.2" ref="led"><bounds x="86" y="15" width="3" height="3" /></element>
<element name="7.3" ref="led"><bounds x="90" y="15" width="3" height="3" /></element>
-
<!-- board -->
<element ref="disk_green"><bounds x="-5" y="25" width="110" height="110" /></element>
diff --git a/src/mame/layout/ebball2.lay b/src/mame/layout/ebball2.lay
index 5deafee899c..d4e0dd67c99 100644
--- a/src/mame/layout/ebball2.lay
+++ b/src/mame/layout/ebball2.lay
@@ -74,7 +74,7 @@ license:CC0
<bounds left="0" right="100" top="0" bottom="114" />
</element>
- <!-- outer element -->
+ <!-- outer bezel -->
<element ref="text_count"><bounds x="16" y="2" width="8" height="3" /></element>
diff --git a/src/mame/layout/ebball3.lay b/src/mame/layout/ebball3.lay
index a8d94a10a0f..e599ff20e7d 100644
--- a/src/mame/layout/ebball3.lay
+++ b/src/mame/layout/ebball3.lay
@@ -121,7 +121,7 @@ license:CC0
<bounds left="0" right="100" top="0" bottom="114" />
</element>
- <!-- outer element -->
+ <!-- outer bezel -->
<element ref="text_count"><bounds x="6" y="2" width="8" height="3" /></element>
diff --git a/src/mame/layout/efball.lay b/src/mame/layout/efball.lay
index 1a6165e27c9..42677d480c8 100644
--- a/src/mame/layout/efball.lay
+++ b/src/mame/layout/efball.lay
@@ -65,7 +65,7 @@ license:CC0
<bounds left="-8" right="298" top="-46" bottom="121" />
</element>
- <!-- outer element -->
+ <!-- outer bezel -->
<element ref="static_white"><bounds left="-8" right="298" top="-42" bottom="117" /></element>
<element ref="static_green"><bounds left="-8" right="298" top="-22" bottom="-20" /></element>
@@ -265,8 +265,7 @@ license:CC0
<element name="9.8" ref="seg"><bounds x="285" y="26" width="5" height="17" /></element>
<element name="9.6" ref="seg"><bounds x="285" y="50" width="5" height="17" /></element>
-
- <!-- inner element -->
+ <!-- inner bezel -->
<element ref="static_white"><bounds x="24" y="-4" width="2" height="83" /></element>
<element ref="static_white"><bounds x="54" y="-4" width="2" height="83" /></element>
diff --git a/src/mame/layout/eleciq.lay b/src/mame/layout/eleciq.lay
index c769de62b16..263b6d0237e 100644
--- a/src/mame/layout/eleciq.lay
+++ b/src/mame/layout/eleciq.lay
@@ -49,7 +49,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="1.01" right="27.99" top="0.75" bottom="54" />
- <!-- element, buttons -->
+ <!-- bezel, buttons -->
<element ref="text_time"><bounds x="17.5" y="2.75" width="6" height="1.5" /></element>
<element ref="static_white"><bounds x="11" y="1.25" width="7" height="4.5" /></element>
diff --git a/src/mame/layout/esoccer.lay b/src/mame/layout/esoccer.lay
index 4fc02bc466d..9f43a873633 100644
--- a/src/mame/layout/esoccer.lay
+++ b/src/mame/layout/esoccer.lay
@@ -31,7 +31,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="2.5" right="33.5" top="5.7" bottom="40.3" />
- <!-- element -->
+ <!-- bezel -->
<element ref="static_green"><bounds x="5" y="5" width="25" height="35" /></element>
diff --git a/src/mame/layout/gjackpot.lay b/src/mame/layout/gjackpot.lay
index e1b3b626e8f..051df2b1c11 100644
--- a/src/mame/layout/gjackpot.lay
+++ b/src/mame/layout/gjackpot.lay
@@ -126,7 +126,7 @@ license:CC0
<element name="0.11" ref="sym_spade"><bounds x="103" y="35" width="3" height="3" /></element>
<element name="0.9" ref="sym_diamond"><bounds x="106.5" y="35" width="3" height="3" /></element>
- <!-- element -->
+ <!-- bezel -->
<element ref="static_yellow"><bounds x="0" y="13" width="114" height="0.5" /></element>
<element ref="static_yellow"><bounds x="0" y="39.5" width="114" height="0.5" /></element>
diff --git a/src/mame/layout/gpoker.lay b/src/mame/layout/gpoker.lay
index c821b6f2f47..6423c185ae7 100644
--- a/src/mame/layout/gpoker.lay
+++ b/src/mame/layout/gpoker.lay
@@ -118,7 +118,7 @@ license:CC0
<element name="0.11" ref="sym_spade"><bounds x="103" y="28" width="3" height="3" /></element>
<element name="0.9" ref="sym_diamond"><bounds x="106.5" y="28" width="3" height="3" /></element>
- <!-- element -->
+ <!-- bezel -->
<element ref="static_white"><bounds x="0" y="6" width="54" height="0.5" /></element>
<element ref="static_white"><bounds x="0" y="32.5" width="54" height="0.5" /></element>
diff --git a/src/mame/layout/h2hbaseb.lay b/src/mame/layout/h2hbaseb.lay
index 7785dc0d2a1..bbf6493cc2e 100644
--- a/src/mame/layout/h2hbaseb.lay
+++ b/src/mame/layout/h2hbaseb.lay
@@ -138,7 +138,7 @@ license:CC0
<element ref="static_white"><bounds x="36.3" y="6.8" width="0.4" height="35.4" /></element>
- <!-- main element -->
+ <!-- main bezel -->
<element ref="static_whitec"><bounds x="0" y="50" width="80" height="80" /></element>
<element ref="static_yellowc"><bounds x="1" y="51" width="78" height="78" /></element>
diff --git a/src/mame/layout/h2hboxing.lay b/src/mame/layout/h2hboxing.lay
index c52ac86f81e..9a87924a786 100644
--- a/src/mame/layout/h2hboxing.lay
+++ b/src/mame/layout/h2hboxing.lay
@@ -28,7 +28,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="4.4" right="43.7" top="0.3" bottom="38.7" />
- <!-- element and digits -->
+ <!-- bezel and digits -->
<element ref="static_white"><bounds x="6.8" y="1.8" width="35.4" height="35.4" /></element>
<element ref="static_black"><bounds x="7.6" y="2.6" width="33.8" height="33.8" /></element>
diff --git a/src/mame/layout/h2hfootb.lay b/src/mame/layout/h2hfootb.lay
index c0bd3a45e33..da7075f75ac 100644
--- a/src/mame/layout/h2hfootb.lay
+++ b/src/mame/layout/h2hfootb.lay
@@ -74,7 +74,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="-9" right="393" top="-130" bottom="156" />
- <!-- element -->
+ <!-- bezel -->
<element ref="static_green"><bounds left="-9" right="393" top="-130" bottom="-60" /></element>
<element ref="static_green"><bounds left="-9" right="393" top="111" bottom="156" /></element>
diff --git a/src/mame/layout/hccbaskb.lay b/src/mame/layout/hccbaskb.lay
index 962812a84d6..a0aa83d57a9 100644
--- a/src/mame/layout/hccbaskb.lay
+++ b/src/mame/layout/hccbaskb.lay
@@ -31,7 +31,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="3.26" right="21.74" top="0.75" bottom="25.74" />
- <!-- element -->
+ <!-- bezel -->
<element ref="static_white"><bounds x="3.25" y="5" width="18.5" height="23" /></element>
<element ref="static_black"><bounds x="3.5" y="5.5" width="18" height="23" /></element>
diff --git a/src/mame/layout/lightfgt.lay b/src/mame/layout/lightfgt.lay
index fcfc8d290a1..b489a705d74 100644
--- a/src/mame/layout/lightfgt.lay
+++ b/src/mame/layout/lightfgt.lay
@@ -193,7 +193,7 @@ license:CC0
<element ref="buttonm" inputtag="IN.3" inputmask="0x04"><bounds x="19" y="13" width="1" height="1" /><color alpha="0.2" /></element>
<element ref="buttonm" inputtag="IN.4" inputmask="0x04"><bounds x="19" y="14" width="1" height="1" /><color alpha="0.2" /></element>
- <!-- element -->
+ <!-- bezel -->
<element ref="static_cyan"><bounds x="15" y="4.9" width="5.1" height="5.1" /></element>
<element ref="static_cyan"><bounds x="4.9" y="15" width="5.1" height="5.1" /></element>
diff --git a/src/mame/layout/mbaskb.lay b/src/mame/layout/mbaskb.lay
new file mode 100644
index 00000000000..fe201d1486a
--- /dev/null
+++ b/src/mame/layout/mbaskb.lay
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+license:CC0
+-->
+<mamelayout version="2">
+
+<!-- define elements -->
+
+ <element name="static_black"><rect><color red="0" green="0" blue="0" /></rect></element>
+ <element name="disk_black"><disk><color red="0" green="0" blue="0" /></disk></element>
+ <element name="static_white"><rect><color red="0.8" green="0.8" blue="0.8" /></rect></element>
+ <element name="disk_white"><disk><color red="0.8" green="0.8" blue="0.8" /></disk></element>
+
+ <element name="text_l1">
+ <rect><color red="0.8" green="0.8" blue="0.8" /></rect>
+ <text string="HOME" align="1"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_l2">
+ <rect><color red="0.8" green="0.8" blue="0.8" /></rect>
+ <text string="VISITOR" align="2"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+
+ <element name="led" defstate="0">
+ <rect state="0"><color red="0.1" green="0.01" blue="0.015" /></rect>
+ <rect state="1"><color red="0.5" green="0.05" blue="0.075" /></rect>
+ <rect state="2"><color red="1.0" green="0.1" blue="0.15" /></rect>
+ </element>
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.1" blue="0.15" /></led7seg>
+ </element>
+
+
+<!-- build screen -->
+
+ <view name="Internal Layout">
+ <bounds left="3.26" right="21.74" top="2.5" bottom="26" />
+
+ <!-- bezel -->
+
+ <element ref="static_white"><bounds x="3.25" y="5" width="18.5" height="23" /></element>
+ <element ref="static_black"><bounds x="3.5" y="5.5" width="18" height="23" /></element>
+
+ <element ref="static_white"><bounds x="10" y="5.25" width="5" height="6.25" /></element>
+ <element ref="static_black"><bounds x="10.25" y="5.5" width="4.5" height="6.25" /></element>
+
+ <element ref="disk_white"><bounds x="10" y="9" width="5" height="5" /></element>
+ <element ref="disk_black"><bounds x="10.25" y="9.25" width="4.5" height="4.5" /></element>
+ <element ref="static_black"><bounds x="10.85" y="8.5" width="0.35" height="3" /></element>
+ <element ref="static_black"><bounds x="12.25" y="8.5" width="0.5" height="3" /></element>
+ <element ref="static_black"><bounds x="13.8" y="8.5" width="0.35" height="3" /></element>
+ <element ref="static_white"><bounds x="10.1" y="11.25" width="4.8" height="0.25" /></element>
+
+ <element ref="disk_white"><bounds x="10" y="19.25" width="5" height="5" /></element>
+ <element ref="disk_black"><bounds x="10.25" y="19.5" width="4.5" height="4.5" /></element>
+ <element ref="static_white"><bounds x="3.3" y="21.65" width="18.4" height="5" /></element>
+
+ <element ref="text_l1"><bounds x="4" y="21.85" width="10" height="0.6" /></element>
+ <element ref="text_l2"><bounds x="11" y="21.85" width="10" height="0.6" /></element>
+
+ <element ref="static_black"><bounds x="6.5" y="21.9" width="12" height="5" /></element>
+ <element ref="static_black"><bounds x="0" y="22.65" width="25" height="5" /></element>
+ <element ref="static_black"><bounds x="0" y="0" width="25" height="5.25" /></element>
+
+ <element ref="disk_white"><bounds x="11" y="4.375" width="3" height="2" /></element>
+ <element ref="disk_black"><bounds x="11.25" y="4.625" width="2.5" height="1.5" /></element>
+
+ <element ref="static_white"><bounds x="10" y="2.5" width="5" height="2.1" /></element>
+ <element ref="static_black"><bounds x="10.25" y="2.75" width="4.5" height="1.55" /></element>
+
+ <!-- leds -->
+
+ <element name="digit0" ref="digit"><bounds x="11" y="22.9" width="1.5" height="2.25" /></element>
+ <element name="digit1" ref="digit"><bounds x="12.5" y="22.9" width="1.5" height="2.25" /></element>
+
+ <element name="7.a" ref="led"><bounds x="12.4" y="5.075" width="0.2" height="0.6" /></element>
+
+ <element name="2.0" ref="led"><bounds x="4.7" y="7.6" width="0.2" height="0.6" /></element>
+ <element name="3.0" ref="led"><bounds x="8.55" y="7.6" width="0.2" height="0.6" /></element>
+ <element name="4.0" ref="led"><bounds x="12.4" y="7.6" width="0.2" height="0.6" /></element>
+ <element name="5.0" ref="led"><bounds x="16.25" y="7.6" width="0.2" height="0.6" /></element>
+ <element name="6.0" ref="led"><bounds x="20.1" y="7.6" width="0.2" height="0.6" /></element>
+
+ <element name="2.1" ref="led"><bounds x="4.7" y="11.883" width="0.2" height="0.6" /></element>
+ <element name="3.1" ref="led"><bounds x="8.55" y="11.883" width="0.2" height="0.6" /></element>
+ <element name="4.1" ref="led"><bounds x="12.4" y="11.883" width="0.2" height="0.6" /></element>
+ <element name="5.1" ref="led"><bounds x="16.25" y="11.883" width="0.2" height="0.6" /></element>
+ <element name="6.1" ref="led"><bounds x="20.1" y="11.883" width="0.2" height="0.6" /></element>
+
+ <element name="2.2" ref="led"><bounds x="4.7" y="16.166" width="0.2" height="0.6" /></element>
+ <element name="3.2" ref="led"><bounds x="8.55" y="16.166" width="0.2" height="0.6" /></element>
+ <element name="4.2" ref="led"><bounds x="12.4" y="16.166" width="0.2" height="0.6" /></element>
+ <element name="5.2" ref="led"><bounds x="16.25" y="16.166" width="0.2" height="0.6" /></element>
+ <element name="6.2" ref="led"><bounds x="20.1" y="16.166" width="0.2" height="0.6" /></element>
+
+ <element name="2.3" ref="led"><bounds x="4.7" y="20.45" width="0.2" height="0.6" /></element>
+ <element name="3.3" ref="led"><bounds x="8.55" y="20.45" width="0.2" height="0.6" /></element>
+ <element name="4.3" ref="led"><bounds x="12.4" y="20.45" width="0.2" height="0.6" /></element>
+ <element name="5.3" ref="led"><bounds x="16.25" y="20.45" width="0.2" height="0.6" /></element>
+ <element name="6.3" ref="led"><bounds x="20.1" y="20.45" width="0.2" height="0.6" /></element>
+
+ </view>
+</mamelayout>
diff --git a/src/mame/layout/mephisto_megaiv.lay b/src/mame/layout/mephisto_megaiv.lay
index 0b4817a3075..522f974ace3 100644
--- a/src/mame/layout/mephisto_megaiv.lay
+++ b/src/mame/layout/mephisto_megaiv.lay
@@ -464,7 +464,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element>
<element ref="text_h"><bounds x="92" y="86" width="2" height="2" /></element>
- <!-- chessboard element -->
+ <!-- chessboard bezel -->
<element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>
diff --git a/src/mame/layout/mephisto_mondial2.lay b/src/mame/layout/mephisto_mondial2.lay
index 286b049522a..e914904aee7 100644
--- a/src/mame/layout/mephisto_mondial2.lay
+++ b/src/mame/layout/mephisto_mondial2.lay
@@ -432,7 +432,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element>
<element ref="text_h"><bounds x="92" y="86" width="2" height="2" /></element>
- <!-- chessboard element -->
+ <!-- chessboard bezel -->
<element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>
diff --git a/src/mame/layout/mephisto_mondial68k.lay b/src/mame/layout/mephisto_mondial68k.lay
index b58e148b89a..28f98098114 100644
--- a/src/mame/layout/mephisto_mondial68k.lay
+++ b/src/mame/layout/mephisto_mondial68k.lay
@@ -439,7 +439,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element>
<element ref="text_h"><bounds x="92" y="86" width="2" height="2" /></element>
- <!-- chessboard element -->
+ <!-- chessboard bezel -->
<element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>
diff --git a/src/mame/layout/mephisto_smondial2.lay b/src/mame/layout/mephisto_smondial2.lay
index 5ab5905c900..b36a693a5a5 100644
--- a/src/mame/layout/mephisto_smondial2.lay
+++ b/src/mame/layout/mephisto_smondial2.lay
@@ -467,7 +467,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element>
<element ref="text_h"><bounds x="92" y="86" width="2" height="2" /></element>
- <!-- chessboard element -->
+ <!-- chessboard bezel -->
<element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>
diff --git a/src/mame/layout/qkracerm.lay b/src/mame/layout/qkracerm.lay
new file mode 100644
index 00000000000..732393aa9a6
--- /dev/null
+++ b/src/mame/layout/qkracerm.lay
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!--
+license:CC0
+-->
+<mamelayout version="2">
+
+ <!-- define elements -->
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.3" blue="0.2" /></led7seg>
+ </element>
+
+ <element name="seg_rect" defstate="0">
+ <rect state="1"><color red="1.0" green="0.3" blue="0.2" /></rect>
+ <rect state="0"><color red="0.125490" green="0.035294" blue="0.0235294" /></rect>
+ </element>
+ <element name="seg_x1" defstate="0">
+ <text string="/" state="1"><color red="1.0" green="0.3" blue="0.2" /></text>
+ <text string="/" state="0"><color red="0.125490" green="0.035294" blue="0.0235294" /></text>
+ </element>
+ <element name="seg_x2" defstate="0">
+ <text string="&#x5c;" state="1"><color red="1.0" green="0.3" blue="0.2" /></text>
+ <text string="&#x5c;" state="0"><color red="0.125490" green="0.035294" blue="0.0235294" /></text>
+ </element>
+
+ <element name="gled" defstate="0">
+ <disk state="1"><color red="0.2" green="1.0" blue="0.2" /></disk>
+ <disk state="0"><color red="0.04" green="0.2" blue="0.04" /></disk>
+ </element>
+ <element name="text_right">
+ <text string="RIGHT"><color red="0.5" green="0.4" blue="0.3" /></text>
+ </element>
+
+
+ <!-- build screen -->
+
+ <view name="Internal Layout">
+ <bounds left="0" right="93.5" top="0" bottom="15" />
+
+ <element name="8.a" ref="gled"><bounds x="84.5" y="5" width="4.5" height="4.5" /></element>
+ <element ref="text_right"><bounds x="80" y="10" width="14" height="4.5" /></element>
+
+ <element name="digit0" ref="digit"><bounds x="0" y="0" width="10" height="15" /></element>
+ <element name="digit1" ref="digit"><bounds x="10" y="0" width="10" height="15" /></element>
+
+ <element name="digit3" ref="digit"><bounds x="30" y="0" width="10" height="15" /></element>
+ <element name="digit4" ref="digit"><bounds x="40" y="0" width="10" height="15" /></element>
+ <element name="digit5" ref="digit"><bounds x="50" y="3.5" width="10" height="15" /></element>
+ <element name="digit6" ref="digit"><bounds x="60" y="0" width="10" height="15" /></element>
+ <element name="digit7" ref="digit"><bounds x="70" y="0" width="10" height="15" /></element>
+
+ <!-- math symbols custom digit -->
+
+ <element name="2.4" ref="seg_rect"><bounds x="21.5" y="7.25" width="7" height="0.5" /></element>
+
+ <element name="2.0" ref="seg_rect"><bounds x="24.75" y="0.9" width="0.5" height="5.75" /></element>
+ <element name="2.3" ref="seg_rect"><bounds x="24.75" y="8.5" width="0.5" height="5.75" /></element>
+
+ <element name="2.1" ref="seg_x1"><bounds x="24" y="-0.5" width="5" height="7.5" /></element>
+ <element name="2.2" ref="seg_x1"><bounds x="21" y="7" width="5" height="7.5" /></element>
+
+ <element name="2.5" ref="seg_x2"><bounds x="21" y="-0.5" width="5" height="7.5" /></element>
+ <element name="2.6" ref="seg_x2"><bounds x="24" y="7" width="5" height="7.5" /></element>
+
+ </view>
+</mamelayout>
diff --git a/src/mame/layout/qkspeller.lay b/src/mame/layout/qkspeller.lay
new file mode 100644
index 00000000000..700301df324
--- /dev/null
+++ b/src/mame/layout/qkspeller.lay
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+license:CC0
+-->
+<mamelayout version="2">
+
+ <!-- define elements -->
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.3" blue="0.2" /></led7seg>
+ </element>
+
+ <element name="ledr" defstate="0">
+ <disk state="1"><color red="1.0" green="0.3" blue="0.2" /></disk>
+ <disk state="0"><color red="0.2" green="0.05" blue="0.04" /></disk>
+ </element>
+ <element name="ledg" defstate="0">
+ <disk state="1"><color red="0.2" green="1.0" blue="0.2" /></disk>
+ <disk state="0"><color red="0.04" green="0.2" blue="0.04" /></disk>
+ </element>
+
+
+ <!-- build screen -->
+
+ <view name="Internal Layout">
+ <bounds left="-1" right="61" top="0" bottom="15" />
+
+ <element name="2.a" ref="ledr"><bounds x="49" y="3" width="9" height="9" /></element>
+ <element name="3.a" ref="ledg"><bounds x="2" y="3" width="9" height="9" /></element>
+
+ <element name="digit1" ref="digit"><bounds x="20" y="0" width="10" height="15" /></element>
+ <element name="digit0" ref="digit"><bounds x="30" y="0" width="10" height="15" /></element>
+
+ </view>
+</mamelayout>
diff --git a/src/mame/layout/rockpin.lay b/src/mame/layout/rockpin.lay
index 2cdb61cdf2c..9cf299a1a78 100644
--- a/src/mame/layout/rockpin.lay
+++ b/src/mame/layout/rockpin.lay
@@ -54,7 +54,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="2.01" right="21.99" top="10.25" bottom="49.99" />
- <!-- element -->
+ <!-- bezel -->
<element ref="disk_white"><bounds x="2" y="6" width="20" height="25" /></element>
<element ref="disk_orange"><bounds x="2.5" y="6.5" width="19" height="24" /></element>
diff --git a/src/mame/layout/ssimon.lay b/src/mame/layout/ssimon.lay
index bc819d755a3..7e0c4d8ffee 100644
--- a/src/mame/layout/ssimon.lay
+++ b/src/mame/layout/ssimon.lay
@@ -162,7 +162,7 @@ license:CC0
<bounds x="36" y="32" width="10" height="20" />
</element>
- <!-- middle element -->
+ <!-- middle bezel -->
<element ref="static_grey"><bounds x="1" y="22" width="45" height="9" /></element>
diff --git a/src/mame/layout/tactix.lay b/src/mame/layout/tactix.lay
index 5693f5f1553..91d2078f94d 100644
--- a/src/mame/layout/tactix.lay
+++ b/src/mame/layout/tactix.lay
@@ -66,7 +66,7 @@ license:CC0
<bounds left="0" right="30" top="0" bottom="30" />
</element>
- <!-- element -->
+ <!-- bezel -->
<element ref="disk_grey"><bounds x="7.55" y="7.55" width="12.05" height="12.05" /></element>
<element ref="disk_blue"><bounds x="7.8" y="7.8" width="11.55" height="11.55" /></element>
diff --git a/src/mame/layout/tbaskb.lay b/src/mame/layout/tbaskb.lay
index 4caa3270a47..55a225c1882 100644
--- a/src/mame/layout/tbaskb.lay
+++ b/src/mame/layout/tbaskb.lay
@@ -30,7 +30,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="3.26" right="21.74" top="-2.75" bottom="23.25" />
- <!-- element -->
+ <!-- bezel -->
<element ref="static_white"><bounds x="3.25" y="5" width="18.5" height="23" /></element>
<element ref="static_black"><bounds x="3.5" y="5.5" width="18" height="23" /></element>
diff --git a/src/mame/layout/tbreakup.lay b/src/mame/layout/tbreakup.lay
index f4ac35df267..aba4066e07b 100644
--- a/src/mame/layout/tbreakup.lay
+++ b/src/mame/layout/tbreakup.lay
@@ -52,7 +52,7 @@ license:CC0
<element name="digit0" ref="digit"><bounds x="28.7" y="37.4" width="3" height="4.5" /></element>
<element name="digit1" ref="digit"><bounds x="31.7" y="37.4" width="3" height="4.5" /></element>
- <!-- main element -->
+ <!-- main bezel -->
<element ref="static_white"><bounds x="18.8" y="80.8" width="6" height="0.45" /></element>
<element ref="text_out"><bounds x="20.3" y="80.5" width="3" height="1.1" /></element>
diff --git a/src/mame/layout/ti95.lay b/src/mame/layout/ti95.lay
index 268093d2bbb..a0e5f7596f5 100644
--- a/src/mame/layout/ti95.lay
+++ b/src/mame/layout/ti95.lay
@@ -215,7 +215,7 @@ license:CC0
<bounds left="0" top="29.5" right="150" bottom="45" />
</element>
-<!-- draw element around 2nd line -->
+<!-- draw bezel around 2nd line -->
<element ref="static_bg2">
<bounds x="0" y="18.7" width="150" height="2.5" />
diff --git a/src/mame/layout/us2pfball.lay b/src/mame/layout/us2pfball.lay
index c057f03666c..4761e603057 100644
--- a/src/mame/layout/us2pfball.lay
+++ b/src/mame/layout/us2pfball.lay
@@ -100,7 +100,7 @@ license:CC0
<view name="Internal Layout">
<bounds left="-8.99" right="348.99" top="-124.99" bottom="162.99" />
- <!-- element -->
+ <!-- bezel -->
<element ref="static_blue"><bounds left="-9" right="349" top="-125" bottom="-80" /></element>
<element ref="text_down"><bounds x="-8" y="-124" width="120" height="19" /></element>
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index d252a3befef..2d10d048738 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -16090,6 +16090,11 @@ qkracer // National Semiconductor
unkeinv // Gordon Barlow Design
vidchal // Select Merchandise
+@source:hh_cops1.cpp
+mbaskb // Mattel
+qkracerm // National Semiconductor
+qkspeller // National Semiconductor
+
@source:hh_hmcs40.cpp
alnattck // Coleco
bambball // Bambino
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 16c68616db1..168887afa47 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -386,6 +386,7 @@ hektor.cpp
hhtiger.cpp
hh_amis2k.cpp
hh_cop400.cpp
+hh_cops1.cpp
hh_hmcs40.cpp
hh_melps4.cpp
hh_pic16.cpp
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index f361eff0b6b..81a250c0ebf 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -112,6 +112,7 @@ using util::BIT;
#include "cpu/minx/minxd.h"
#include "cpu/mips/mips3dsm.h"
#include "cpu/mips/mips1dsm.h"
+#include "cpu/cops1/cops1d.h"
#include "cpu/mn1880/mn1880d.h"
#include "cpu/mn10200/mn102dis.h"
#include "cpu/msm65x2/msm65x2d.h"
@@ -496,6 +497,7 @@ static const dasm_table_entry dasm_table[] =
{ "mips1le", le, 0, []() -> util::disasm_interface * { return new mips1_disassembler; } },
{ "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
{ "mips3le", le, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
+ { "mm5799", le, 0, []() -> util::disasm_interface * { return new mm5799_disassembler; } },
{ "mn10200", le, 0, []() -> util::disasm_interface * { return new mn10200_disassembler; } },
{ "mn1870", be, 0, []() -> util::disasm_interface * { return new mn1870_disassembler; } },
{ "mn1880", be, 0, []() -> util::disasm_interface * { return new mn1880_disassembler; } },