mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
b5000: add b6000, b6100
This commit is contained in:
parent
123839f027
commit
8b8bb2fa75
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
105
src/devices/cpu/b5000/b6000.cpp
Normal file
105
src/devices/cpu/b5000/b6000.cpp
Normal 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));
|
||||
}
|
47
src/devices/cpu/b5000/b6000.h
Normal file
47
src/devices/cpu/b5000/b6000.h
Normal 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
|
157
src/devices/cpu/b5000/b6100.cpp
Normal file
157
src/devices/cpu/b5000/b6100.cpp
Normal 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;
|
||||
}
|
52
src/devices/cpu/b5000/b6100.h
Normal file
52
src/devices/cpu/b5000/b6100.h
Normal 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
|
Loading…
Reference in New Issue
Block a user