b5000: add b6000, b6100

This commit is contained in:
hap 2022-03-20 00:19:50 +01:00
parent 123839f027
commit 8b8bb2fa75
10 changed files with 391 additions and 12 deletions

View File

@ -2855,6 +2855,8 @@ end
--------------------------------------------------
-- Rockwell B5000 family
--@src/devices/cpu/b5000/b5000.h,CPUS["B5000"] = true
--@src/devices/cpu/b5000/b6000.h,CPUS["B5000"] = true
--@src/devices/cpu/b5000/b6100.h,CPUS["B5000"] = true
--------------------------------------------------
if CPUS["B5000"] then
@ -2864,6 +2866,10 @@ if CPUS["B5000"] then
MAME_DIR .. "src/devices/cpu/b5000/b5000.cpp",
MAME_DIR .. "src/devices/cpu/b5000/b5000.h",
MAME_DIR .. "src/devices/cpu/b5000/b5000op.cpp",
MAME_DIR .. "src/devices/cpu/b5000/b6000.cpp",
MAME_DIR .. "src/devices/cpu/b5000/b6000.h",
MAME_DIR .. "src/devices/cpu/b5000/b6100.cpp",
MAME_DIR .. "src/devices/cpu/b5000/b6100.h",
}
end

View File

@ -2,7 +2,7 @@
// copyright-holders:hap
/*
Rockwell B5000 MCU core implementation
Rockwell B5000 MCU
*/
@ -16,18 +16,22 @@ DEFINE_DEVICE_TYPE(B5000, b5000_cpu_device, "b5000", "Rockwell B5000")
// constructor
b5000_cpu_device::b5000_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
b5000_base_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
{ }
b5000_cpu_device::b5000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
b5000_base_device(mconfig, B5000, tag, owner, clock, 9, address_map_constructor(FUNC(b5000_cpu_device::program_map), this), 6, address_map_constructor(FUNC(b5000_cpu_device::data_map), this))
b5000_cpu_device(mconfig, B5000, tag, owner, clock, 9, address_map_constructor(FUNC(b5000_cpu_device::program_448x8), this), 6, address_map_constructor(FUNC(b5000_cpu_device::data_45x4), this))
{ }
// internal memory maps
void b5000_cpu_device::program_map(address_map &map)
void b5000_cpu_device::program_448x8(address_map &map)
{
map(0x000, 0x1ff).rom();
}
void b5000_cpu_device::data_map(address_map &map)
void b5000_cpu_device::data_45x4(address_map &map)
{
map(0x00, 0x0b).ram();
map(0x10, 0x1a).ram();

View File

@ -2,7 +2,7 @@
// copyright-holders:hap
/*
Rockwell B5000 MCU core implementation
Rockwell B5000 MCU
*/
@ -25,6 +25,8 @@ public:
b5000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
b5000_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
@ -37,8 +39,8 @@ protected:
virtual u8 sr_page() { return 0; }
virtual u16 decode_digit(u8 data);
void data_map(address_map &map);
void program_map(address_map &map);
void program_448x8(address_map &map);
void data_45x4(address_map &map);
// opcode helpers
u8 ram_r();

View File

@ -32,7 +32,8 @@ b5000_base_device::b5000_base_device(const machine_config &mconfig, device_type
m_read_kb(*this),
m_read_din(*this),
m_write_str(*this),
m_write_seg(*this)
m_write_seg(*this),
m_write_spk(*this)
{ }
@ -52,6 +53,7 @@ void b5000_base_device::device_start()
m_read_din.resolve_safe(0);
m_write_str.resolve_safe();
m_write_seg.resolve_safe();
m_write_spk.resolve_safe();
// zerofill
m_pc = 0;

View File

@ -33,6 +33,9 @@ public:
// 7/8/10 segment outputs
auto write_seg() { return m_write_seg.bind(); }
// speaker output line
auto write_spk() { return m_write_spk.bind(); }
protected:
// construction/destruction
b5000_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
@ -105,6 +108,7 @@ protected:
devcb_read8 m_read_din;
devcb_write16 m_write_str;
devcb_write16 m_write_seg;
devcb_write_line m_write_spk;
};

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:hap
// B5000 opcode handlers
// B5000 common opcode handlers
#include "emu.h"
#include "b5000.h"
@ -9,19 +9,19 @@
// internal helpers
inline u8 b5000_cpu_device::ram_r()
u8 b5000_cpu_device::ram_r()
{
return m_data->read_byte(m_ram_addr) & 0xf;
}
inline void b5000_cpu_device::ram_w(u8 data)
void b5000_cpu_device::ram_w(u8 data)
{
m_data->write_byte(m_ram_addr, data & 0xf);
}
void b5000_cpu_device::set_pc(u8 pu, u8 pl)
{
m_pc = ((pu << 6 & 0x3c0) | (pl & 0x3f)) & m_prgmask;
m_pc = ((pu << 6) | (pl & 0x3f)) & m_prgmask;
}
void b5000_cpu_device::set_bu(u8 bu)

View File

@ -0,0 +1,105 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Rockwell B6000 MCU
*/
#include "emu.h"
#include "b6000.h"
DEFINE_DEVICE_TYPE(B6000, b6000_cpu_device, "b6000", "Rockwell B6000")
// constructor
b6000_cpu_device::b6000_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
b5000_cpu_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
{ }
b6000_cpu_device::b6000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
b6000_cpu_device(mconfig, B6000, tag, owner, clock, 9, address_map_constructor(FUNC(b6000_cpu_device::program_512x8), this), 6, address_map_constructor(FUNC(b6000_cpu_device::data_45x4), this))
{ }
// internal memory maps
void b6000_cpu_device::program_512x8(address_map &map)
{
map(0x000, 0x1ff).rom();
}
// initialize
void b6000_cpu_device::device_reset()
{
b5000_cpu_device::device_reset();
// clear all registers
m_bl = 0;
m_bu = 0;
m_a = 0;
// clear outputs
m_write_str(0);
m_write_seg(m_seg = 0);
}
// digit segments decoder
u16 b6000_cpu_device::decode_digit(u8 data)
{
static u8 lut_segs[0x10] =
{
// 0-9 ok
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20
};
return lut_segs[data & 0xf];
}
//-------------------------------------------------
// execute
//-------------------------------------------------
void b6000_cpu_device::update_speaker()
{
// carry flag outputs to SPK
if (m_c != m_prev_c)
m_write_spk(m_c);
}
void b6000_cpu_device::execute_one()
{
switch (m_op)
{
case 0x03: op_tkbs(); break;
case 0x76: op_atbz(); break;
case 0x77: op_atb(); break;
// rest is same as B5000
default: b5000_cpu_device::execute_one(); break;
}
update_speaker();
}
//-------------------------------------------------
// changed opcodes (no need for separate file)
//-------------------------------------------------
void b6000_cpu_device::op_tkbs()
{
// TKBS: load segments (no TKB step)
m_seg |= decode_digit(ram_r());
m_write_seg(m_seg);
}
void b6000_cpu_device::op_atbz()
{
// ATBZ: load strobe from A (no ATB step)
m_write_str(1 << (m_a & 0xf));
}

View File

@ -0,0 +1,47 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Rockwell B6000 MCU
*/
#ifndef MAME_CPU_B5000_B6000_H
#define MAME_CPU_B5000_B6000_H
#pragma once
#include "b5000.h"
// pinout reference
/*
*/
class b6000_cpu_device : public b5000_cpu_device
{
public:
b6000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
b6000_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
// device-level overrides
virtual void device_reset() override;
void update_speaker();
virtual void execute_one() override;
virtual u16 decode_digit(u8 data) override;
void program_512x8(address_map &map);
// opcode handlers
virtual void op_tkbs() override;
virtual void op_atbz() override;
};
DECLARE_DEVICE_TYPE(B6000, b6000_cpu_device)
#endif // MAME_CPU_B5000_B6000_H

View File

@ -0,0 +1,157 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Rockwell B6100 MCU
*/
#include "emu.h"
#include "b6100.h"
#include "b5000d.h"
DEFINE_DEVICE_TYPE(B6100, b6100_cpu_device, "b6100", "Rockwell B6100")
// constructor
b6100_cpu_device::b6100_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
b6000_cpu_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
{ }
b6100_cpu_device::b6100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
b6100_cpu_device(mconfig, B6100, tag, owner, clock, 10, address_map_constructor(FUNC(b6100_cpu_device::program_896x8), this), 6, address_map_constructor(FUNC(b6100_cpu_device::data_48x4), this))
{ }
// internal memory maps
void b6100_cpu_device::program_896x8(address_map &map)
{
map(0x000, 0x2ff).rom();
map(0x380, 0x3ff).rom();
}
void b6100_cpu_device::data_48x4(address_map &map)
{
map(0x00, 0x0b).ram();
map(0x10, 0x1b).ram();
map(0x20, 0x2b).ram();
map(0x30, 0x3b).ram();
}
// disasm
std::unique_ptr<util::disasm_interface> b6100_cpu_device::create_disassembler()
{
return std::make_unique<b5500_disassembler>();
}
// digit segments decoder
u16 b6100_cpu_device::decode_digit(u8 data)
{
static u8 lut_segs[0x10] =
{
// 0-9 ok
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20
};
return lut_segs[data & 0xf];
}
//-------------------------------------------------
// execute
//-------------------------------------------------
void b6100_cpu_device::execute_one()
{
switch (m_op & 0xf0)
{
case 0x40: op_lax(); break;
case 0x60:
if (m_op != 0x6f)
op_adx();
else
op_read();
break;
case 0x80: case 0x90: case 0xa0: case 0xb0:
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
m_tra_step = 1; break;
default:
switch (m_op & 0xfc)
{
case 0x04: op_tdin(); break;
case 0x08: op_tm(); break;
case 0x10: op_sm(); break;
case 0x14: op_rsm(); break;
case 0x18: m_ret_step = 1; break;
case 0x1c: op_lb(11); break;
case 0x20: op_lb(7); break;
case 0x24: op_lb(10); break;
case 0x28: op_lb(9); break;
case 0x2c: op_lb(8); break;
case 0x3c: op_lb(0); break;
case 0x30: case 0x34: case 0x38: op_tl(); break;
case 0x50: op_lda(); break;
case 0x54: op_excp(); break;
case 0x58: op_exc0(); break;
case 0x5c: op_excm(); break;
case 0x70: op_add(); break;
case 0x78: op_comp(); break;
case 0x7c: op_tam(); break;
default:
switch (m_op)
{
case 0x00: op_nop(); break;
case 0x01: op_tc(); break;
case 0x02: op_tkb(); break;
case 0x03: op_tkbs(); break;
case 0x0c: op_sc(); break;
case 0x0d: op_rsc(); break;
case 0x74: op_kseg(); break;
case 0x76: op_atbz(); break;
case 0x77: op_atb(); break;
default: op_illegal(); break;
}
break; // 0xff
}
break; // 0xfc
}
update_speaker();
}
bool b6100_cpu_device::op_canskip(u8 op)
{
// TL is unskippable
return ((op & 0xf8) != 0x30) && ((op & 0xfc) != 0x38);
}
bool b6100_cpu_device::op_is_lb(u8 op)
{
return ((op & 0xfc) == 0x1c) || ((op & 0xf0) == 0x20) || ((op & 0xfc) == 0x3c);
}
//-------------------------------------------------
// changed opcodes (no need for separate file)
//-------------------------------------------------
void b6100_cpu_device::op_read()
{
// READ: add KB to A, skip next on no overflow
m_a += (m_read_kb() & 0xf);
m_skip = !BIT(m_a, 4);
m_a &= 0xf;
}

View File

@ -0,0 +1,52 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Rockwell B6100 MCU
*/
#ifndef MAME_CPU_B5000_B6100_H
#define MAME_CPU_B5000_B6100_H
#pragma once
#include "b6000.h"
// pinout reference
/*
*/
class b6100_cpu_device : public b6000_cpu_device
{
public:
b6100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
b6100_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
// device_execute_interface overrides
virtual void execute_one() override;
virtual bool op_canskip(u8 op) override;
virtual bool op_is_lb(u8 op) override;
virtual void reset_pc() override { set_pc(0, 0); }
virtual u8 sr_page() override { return 15; }
virtual u16 decode_digit(u8 data) override;
void program_896x8(address_map &map);
void data_48x4(address_map &map);
// opcode handlers
virtual void op_read() override;
};
DECLARE_DEVICE_TYPE(B6100, b6100_cpu_device)
#endif // MAME_CPU_B5000_B6100_H