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]
This commit is contained in:
hap 2021-02-14 23:23:14 +01:00
parent 2d0f0bf867
commit 147b5e72a4
55 changed files with 2147 additions and 60 deletions

View File

@ -451,6 +451,26 @@ if (CPUS["COSMAC"]~=null or _OPTIONS["with-tools"]) then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/cosmac/cosdasm.h") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/cosmac/cosdasm.h")
end 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 -- National Semiconductor COP400 family
--@src/devices/cpu/cop400/cop400.h,CPUS["COP400"] = true --@src/devices/cpu/cop400/cop400.h,CPUS["COP400"] = true

View File

@ -147,6 +147,7 @@ CPUS["HPC"] = true
CPUS["FR"] = true CPUS["FR"] = true
CPUS["UPD78K"] = true CPUS["UPD78K"] = true
CPUS["KS0164"] = true CPUS["KS0164"] = true
--CPUS["COPS1"] = true
-------------------------------------------------- --------------------------------------------------
-- specify available sound cores -- specify available sound cores

View File

@ -166,6 +166,7 @@ CPUS["M88000"] = true
CPUS["XAVIX2"] = true CPUS["XAVIX2"] = true
CPUS["UPD78K"] = true CPUS["UPD78K"] = true
CPUS["ROMP"] = true CPUS["ROMP"] = true
CPUS["COPS1"] = true
-------------------------------------------------- --------------------------------------------------
-- specify available sound cores; some of these are -- specify available sound cores; some of these are
@ -3012,6 +3013,7 @@ files {
createMESSProjects(_target, _subtarget, "natsemi") createMESSProjects(_target, _subtarget, "natsemi")
files { files {
MAME_DIR .. "src/mame/drivers/hh_cop400.cpp", MAME_DIR .. "src/mame/drivers/hh_cop400.cpp",
MAME_DIR .. "src/mame/drivers/hh_cops1.cpp",
MAME_DIR .. "src/mame/drivers/ns5652.cpp", MAME_DIR .. "src/mame/drivers/ns5652.cpp",
} }

View File

@ -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();
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -136,7 +136,7 @@ void sm500_device::clock_melody()
// output to R pins // output to R pins
if (out != m_r_out) if (out != m_r_out)
{ {
m_write_r(0, out, 0xff); m_write_r(out);
m_r_out = out; m_r_out = out;
} }
} }

View File

@ -298,7 +298,7 @@ protected:
virtual void execute_one() override; virtual void execute_one() override;
virtual void get_opcode_param() 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; virtual void clock_melody() override;
}; };

View File

@ -161,7 +161,7 @@ void sm510_base_device::device_reset()
m_y = 0; m_y = 0;
m_r = m_r_out = 0; m_r = m_r_out = 0;
m_write_r(0, 0, 0xff); m_write_r(0);
} }

View File

@ -74,7 +74,7 @@ void sm510_device::clock_melody()
// output to R pins // output to R pins
if (out != m_r_out) if (out != m_r_out)
{ {
m_write_r(0, out, 0xff); m_write_r(out);
m_r_out = out; m_r_out = out;
} }
} }

View File

@ -203,7 +203,7 @@ void sm510_base_device::op_lax()
void sm510_base_device::op_ptw() void sm510_base_device::op_ptw()
{ {
// PTW: output W latch // PTW: output W latch
m_write_s(0, m_w, 0xff); m_write_s(m_w);
} }
void sm510_base_device::op_wr() void sm510_base_device::op_wr()
@ -226,7 +226,7 @@ void sm510_base_device::op_ws()
void sm510_base_device::op_kta() void sm510_base_device::op_kta()
{ {
// KTA: input K to ACC // 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() void sm510_base_device::op_atbp()

View File

@ -138,7 +138,7 @@ void sm511_device::clock_melody()
// output to R pin // output to R pin
if (out != m_r_out) if (out != m_r_out)
{ {
m_write_r(0, out, 0xff); m_write_r(out);
m_r_out = out; m_r_out = out;
} }
} }

View File

@ -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_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_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?
} }
//------------------------------------------------- //-------------------------------------------------

View File

@ -20,7 +20,6 @@
// pinout reference // pinout reference
/* /*
____ ____ ____ ____ ____ ____ ____ ____
R8 1 |* \_/ | 28 R7 R0 1 |* \_/ | 28 Vss R8 1 |* \_/ | 28 R7 R0 1 |* \_/ | 28 Vss
R9 2 | | 27 R6 R1 2 | | 27 OSC2 R9 2 | | 27 R6 R1 2 | | 27 OSC2

View File

@ -3,8 +3,8 @@
// thanks-to:Sean Riddle // thanks-to:Sean Riddle
/*************************************************************************** /***************************************************************************
National Semiconductor COP400 MCU handhelds or other simple devices, National Semiconductor COPS(COP400 MCU series) handhelds or other simple
mostly LED electronic games/toys. devices, mostly LED electronic games/toys.
TODO: TODO:
- why does h2hbaskbc(and clones) need a workaround on writing L pins? - why does h2hbaskbc(and clones) need a workaround on writing L pins?
@ -1691,7 +1691,8 @@ ROM_END
* COP420 MCU label COP420-NPG/N * COP420 MCU label COP420-NPG/N
* 8-digit 7seg led display(1 custom digit), 1 green led, no sound * 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) void qkracer_state::write_d(u8 data)
{ {
// D: select digit, D3: input mux high bit // D: select digit, D3: input mux low bit
m_inp_mux = (m_inp_mux & 0xf) | (data << 1 & 0x10); m_inp_mux = (m_inp_mux & ~1) | (data >> 3 & 1);
m_d = data & 0xf; m_d = data & 0xf;
update_display(); update_display();
} }
@ -1729,7 +1730,7 @@ void qkracer_state::write_d(u8 data)
void qkracer_state::write_g(u8 data) void qkracer_state::write_g(u8 data)
{ {
// G: select digit, input mux // 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; m_g = data & 0xf;
update_display(); update_display();
} }
@ -1757,42 +1758,42 @@ WRITE_LINE_MEMBER(qkracer_state::write_sk)
// config // config
static INPUT_PORTS_START( qkracer ) 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( 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( 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( 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_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( 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( 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( 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_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( 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( 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( 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_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( 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( 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( 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_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 INPUT_PORTS_END
void qkracer_state::qkracer(machine_config &config) void qkracer_state::qkracer(machine_config &config)
{ {
/* basic machine hardware */ /* basic machine hardware */
COP420(config, m_maincpu, 1000000); // approximation - RC osc. R=47K, C=100pF COP420(config, m_maincpu, 950000); // approximation - RC osc. R=47K, C=100pF
m_maincpu->set_config(COP400_CKI_DIVISOR_32, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed 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_d().set(FUNC(qkracer_state::write_d));
m_maincpu->write_g().set(FUNC(qkracer_state::write_g)); m_maincpu->write_g().set(FUNC(qkracer_state::write_g));
m_maincpu->write_l().set(FUNC(qkracer_state::write_l)); 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( 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( 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 ) CONS( 1987, vidchal, 0, 0, vidchal, vidchal, vidchal_state, empty_init, "Select Merchandise", "Video Challenger", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING )

View File

@ -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 )

View File

@ -26,7 +26,7 @@ copyright-holders:Dirk Best, Eric Roberts
<bounds left="50" top="20" right="770" bottom="141" /> <bounds left="50" top="20" right="770" bottom="141" />
</element> </element>
<!-- element --> <!-- bezel -->
<element ref="static_white"><bounds left="50" top="20" right="770" bottom="141" /></element> <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> <element ref="static_black"><bounds left="53" top="23" right="767" bottom="138" /></element>

View File

@ -36,7 +36,7 @@ license:CC0
<element ref="text_time"><bounds x="3.666" y="1" width="6" height="2" /></element> <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 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_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> <element ref="static_black"><bounds x="2.2" y="4.2" width="17.6" height="12.6" /></element>

View File

@ -69,7 +69,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="-8.99" right="392.99" top="-104" bottom="186" /> <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="-110" bottom="-60" /></element>
<element ref="static_green"><bounds left="-9" right="393" top="111" bottom="200" /></element> <element ref="static_green"><bounds left="-9" right="393" top="111" bottom="200" /></element>

View File

@ -77,7 +77,7 @@ license:CC0
<bounds left="-9" right="393" top="-130" bottom="156" /> <bounds left="-9" right="393" top="-130" bottom="156" />
</element> </element>
<!-- element --> <!-- bezel -->
<element ref="static_white"><bounds left="-9" right="393" top="-130" bottom="-60" /></element> <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> <element ref="static_green"><bounds left="-9" right="393" top="111" bottom="156" /></element>

View File

@ -73,7 +73,7 @@ license:CC0
</element> </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_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> <element ref="static_black2"><bounds x="19.5" y="19.5" width="15.0" height="27.0" /></element>

View File

@ -71,7 +71,7 @@ license:CC0
<bounds left="0" right="100" top="0" bottom="114" /> <bounds left="0" right="100" top="0" bottom="114" />
</element> </element>
<!-- outer element --> <!-- outer bezel -->
<element ref="text_score"><bounds x="5.5" y="2" width="8" height="3" /></element> <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> <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.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> <element name="7.3" ref="led"><bounds x="90" y="15" width="3" height="3" /></element>
<!-- board --> <!-- board -->
<element ref="disk_green"><bounds x="-5" y="25" width="110" height="110" /></element> <element ref="disk_green"><bounds x="-5" y="25" width="110" height="110" /></element>

View File

@ -74,7 +74,7 @@ license:CC0
<bounds left="0" right="100" top="0" bottom="114" /> <bounds left="0" right="100" top="0" bottom="114" />
</element> </element>
<!-- outer element --> <!-- outer bezel -->
<element ref="text_count"><bounds x="16" y="2" width="8" height="3" /></element> <element ref="text_count"><bounds x="16" y="2" width="8" height="3" /></element>

View File

@ -121,7 +121,7 @@ license:CC0
<bounds left="0" right="100" top="0" bottom="114" /> <bounds left="0" right="100" top="0" bottom="114" />
</element> </element>
<!-- outer element --> <!-- outer bezel -->
<element ref="text_count"><bounds x="6" y="2" width="8" height="3" /></element> <element ref="text_count"><bounds x="6" y="2" width="8" height="3" /></element>

View File

@ -65,7 +65,7 @@ license:CC0
<bounds left="-8" right="298" top="-46" bottom="121" /> <bounds left="-8" right="298" top="-46" bottom="121" />
</element> </element>
<!-- outer element --> <!-- outer bezel -->
<element ref="static_white"><bounds left="-8" right="298" top="-42" bottom="117" /></element> <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> <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.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> <element name="9.6" ref="seg"><bounds x="285" y="50" width="5" height="17" /></element>
<!-- inner bezel -->
<!-- inner element -->
<element ref="static_white"><bounds x="24" y="-4" width="2" height="83" /></element> <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> <element ref="static_white"><bounds x="54" y="-4" width="2" height="83" /></element>

View File

@ -49,7 +49,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="1.01" right="27.99" top="0.75" bottom="54" /> <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="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> <element ref="static_white"><bounds x="11" y="1.25" width="7" height="4.5" /></element>

View File

@ -31,7 +31,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="2.5" right="33.5" top="5.7" bottom="40.3" /> <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> <element ref="static_green"><bounds x="5" y="5" width="25" height="35" /></element>

View File

@ -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.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 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="13" width="114" height="0.5" /></element>
<element ref="static_yellow"><bounds x="0" y="39.5" width="114" height="0.5" /></element> <element ref="static_yellow"><bounds x="0" y="39.5" width="114" height="0.5" /></element>

View File

@ -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.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 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="6" width="54" height="0.5" /></element>
<element ref="static_white"><bounds x="0" y="32.5" width="54" height="0.5" /></element> <element ref="static_white"><bounds x="0" y="32.5" width="54" height="0.5" /></element>

View File

@ -138,7 +138,7 @@ license:CC0
<element ref="static_white"><bounds x="36.3" y="6.8" width="0.4" height="35.4" /></element> <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_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> <element ref="static_yellowc"><bounds x="1" y="51" width="78" height="78" /></element>

View File

@ -28,7 +28,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="4.4" right="43.7" top="0.3" bottom="38.7" /> <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_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> <element ref="static_black"><bounds x="7.6" y="2.6" width="33.8" height="33.8" /></element>

View File

@ -74,7 +74,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="-9" right="393" top="-130" bottom="156" /> <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="-130" bottom="-60" /></element>
<element ref="static_green"><bounds left="-9" right="393" top="111" bottom="156" /></element> <element ref="static_green"><bounds left="-9" right="393" top="111" bottom="156" /></element>

View File

@ -31,7 +31,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="3.26" right="21.74" top="0.75" bottom="25.74" /> <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_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_black"><bounds x="3.5" y="5.5" width="18" height="23" /></element>

View File

@ -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.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 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="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> <element ref="static_cyan"><bounds x="4.9" y="15" width="5.1" height="5.1" /></element>

103
src/mame/layout/mbaskb.lay Normal file
View File

@ -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>

View File

@ -464,7 +464,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element> <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> <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> <element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>

View File

@ -432,7 +432,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element> <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> <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> <element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>

View File

@ -439,7 +439,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element> <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> <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> <element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>

View File

@ -467,7 +467,7 @@ license:CC0
<element ref="text_g"><bounds x="82" y="86" width="2" height="2" /></element> <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> <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> <element ref="black"><bounds x="17.5" y="2.5" width="81" height="81" /></element>

View File

@ -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>

View File

@ -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>

View File

@ -54,7 +54,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="2.01" right="21.99" top="10.25" bottom="49.99" /> <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_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> <element ref="disk_orange"><bounds x="2.5" y="6.5" width="19" height="24" /></element>

View File

@ -162,7 +162,7 @@ license:CC0
<bounds x="36" y="32" width="10" height="20" /> <bounds x="36" y="32" width="10" height="20" />
</element> </element>
<!-- middle element --> <!-- middle bezel -->
<element ref="static_grey"><bounds x="1" y="22" width="45" height="9" /></element> <element ref="static_grey"><bounds x="1" y="22" width="45" height="9" /></element>

View File

@ -66,7 +66,7 @@ license:CC0
<bounds left="0" right="30" top="0" bottom="30" /> <bounds left="0" right="30" top="0" bottom="30" />
</element> </element>
<!-- element --> <!-- bezel -->
<element ref="disk_grey"><bounds x="7.55" y="7.55" width="12.05" height="12.05" /></element> <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> <element ref="disk_blue"><bounds x="7.8" y="7.8" width="11.55" height="11.55" /></element>

View File

@ -30,7 +30,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="3.26" right="21.74" top="-2.75" bottom="23.25" /> <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_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_black"><bounds x="3.5" y="5.5" width="18" height="23" /></element>

View File

@ -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="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> <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="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> <element ref="text_out"><bounds x="20.3" y="80.5" width="3" height="1.1" /></element>

View File

@ -215,7 +215,7 @@ license:CC0
<bounds left="0" top="29.5" right="150" bottom="45" /> <bounds left="0" top="29.5" right="150" bottom="45" />
</element> </element>
<!-- draw element around 2nd line --> <!-- draw bezel around 2nd line -->
<element ref="static_bg2"> <element ref="static_bg2">
<bounds x="0" y="18.7" width="150" height="2.5" /> <bounds x="0" y="18.7" width="150" height="2.5" />

View File

@ -100,7 +100,7 @@ license:CC0
<view name="Internal Layout"> <view name="Internal Layout">
<bounds left="-8.99" right="348.99" top="-124.99" bottom="162.99" /> <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="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> <element ref="text_down"><bounds x="-8" y="-124" width="120" height="19" /></element>

View File

@ -16090,6 +16090,11 @@ qkracer // National Semiconductor
unkeinv // Gordon Barlow Design unkeinv // Gordon Barlow Design
vidchal // Select Merchandise vidchal // Select Merchandise
@source:hh_cops1.cpp
mbaskb // Mattel
qkracerm // National Semiconductor
qkspeller // National Semiconductor
@source:hh_hmcs40.cpp @source:hh_hmcs40.cpp
alnattck // Coleco alnattck // Coleco
bambball // Bambino bambball // Bambino

View File

@ -386,6 +386,7 @@ hektor.cpp
hhtiger.cpp hhtiger.cpp
hh_amis2k.cpp hh_amis2k.cpp
hh_cop400.cpp hh_cop400.cpp
hh_cops1.cpp
hh_hmcs40.cpp hh_hmcs40.cpp
hh_melps4.cpp hh_melps4.cpp
hh_pic16.cpp hh_pic16.cpp

View File

@ -112,6 +112,7 @@ using util::BIT;
#include "cpu/minx/minxd.h" #include "cpu/minx/minxd.h"
#include "cpu/mips/mips3dsm.h" #include "cpu/mips/mips3dsm.h"
#include "cpu/mips/mips1dsm.h" #include "cpu/mips/mips1dsm.h"
#include "cpu/cops1/cops1d.h"
#include "cpu/mn1880/mn1880d.h" #include "cpu/mn1880/mn1880d.h"
#include "cpu/mn10200/mn102dis.h" #include "cpu/mn10200/mn102dis.h"
#include "cpu/msm65x2/msm65x2d.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; } }, { "mips1le", le, 0, []() -> util::disasm_interface * { return new mips1_disassembler; } },
{ "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } }, { "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
{ "mips3le", le, 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; } }, { "mn10200", le, 0, []() -> util::disasm_interface * { return new mn10200_disassembler; } },
{ "mn1870", be, 0, []() -> util::disasm_interface * { return new mn1870_disassembler; } }, { "mn1870", be, 0, []() -> util::disasm_interface * { return new mn1870_disassembler; } },
{ "mn1880", be, 0, []() -> util::disasm_interface * { return new mn1880_disassembler; } }, { "mn1880", be, 0, []() -> util::disasm_interface * { return new mn1880_disassembler; } },