From e7b852c7a3bb17fef8c833191f979073bcd730dd Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Fri, 25 Sep 2020 11:01:41 +0100 Subject: bus/bbc/1mhzbus: Added the Acorn Music 500, Hybrid Music 5000 Synthesiser, Hybrid Music 3000 Expander, and Peartree Music 87 Synthesiser. --- scripts/src/bus.lua | 2 + src/devices/bus/bbc/1mhzbus/1mhzbus.cpp | 15 +- src/devices/bus/bbc/1mhzbus/m5000.cpp | 435 ++++++++++++++++++++++++++++++++ src/devices/bus/bbc/1mhzbus/m5000.h | 158 ++++++++++++ 4 files changed, 604 insertions(+), 6 deletions(-) create mode 100644 src/devices/bus/bbc/1mhzbus/m5000.cpp create mode 100644 src/devices/bus/bbc/1mhzbus/m5000.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 35b082a3455..54550c06341 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -504,6 +504,8 @@ if (BUSES["BBC_1MHZBUS"]~=null) then MAME_DIR .. "src/devices/bus/bbc/1mhzbus/ieee488.h", MAME_DIR .. "src/devices/bus/bbc/1mhzbus/m2000.cpp", MAME_DIR .. "src/devices/bus/bbc/1mhzbus/m2000.h", + MAME_DIR .. "src/devices/bus/bbc/1mhzbus/m5000.cpp", + MAME_DIR .. "src/devices/bus/bbc/1mhzbus/m5000.h", MAME_DIR .. "src/devices/bus/bbc/1mhzbus/multiform.cpp", MAME_DIR .. "src/devices/bus/bbc/1mhzbus/multiform.h", MAME_DIR .. "src/devices/bus/bbc/1mhzbus/opus3.cpp", diff --git a/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp b/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp index 1246cb1902c..0df4a32ac74 100644 --- a/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp +++ b/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp @@ -117,7 +117,7 @@ void bbc_1mhzbus_slot_device::jim_w(offs_t offset, uint8_t data) #include "ide.h" #include "ieee488.h" #include "m2000.h" -//#include "m5000.h" +#include "m5000.h" #include "sasi.h" #include "scsi.h" #include "multiform.h" @@ -137,7 +137,7 @@ void bbc_1mhzbus_devices(device_slot_interface &device) { //device.option_add("teletext", BBC_TELETEXT); /* Acorn ANE01 Teletext Adapter */ device.option_add("ieee488", BBC_IEEE488); /* Acorn ANK01 IEEE488 Interface */ - //device.option_add("m500", BBC_M500); /* Acorn ANV02 Music 500 */ + device.option_add("m500", BBC_M500); /* Acorn ANV02 Music 500 */ device.option_add("awhd", BBC_AWHD); /* Acorn Winchester Disc */ device.option_add("autoprom", BBC_AUTOPROM); /* ATPL AutoPrommer */ device.option_add("beebide", BBC_BEEBIDE); /* Sprow BeebIDE 16-bit */ @@ -147,6 +147,10 @@ void bbc_1mhzbus_devices(device_slot_interface &device) //device.option_add("videodig", BBC_VIDEODIG); /* Video Digitiser (RH Electronics) */ device.option_add("emrmidi", BBC_EMRMIDI); /* EMR Midi Interface */ //device.option_add("procyon", BBC_PROCYON); /* CST Procyon IEEE Interface */ + device.option_add("m2000", BBC_M2000); /* Hybrid Music 2000 Interface */ + device.option_add("m3000", BBC_M3000); /* Hybrid Music 3000 Expander */ + device.option_add("m5000", BBC_M5000); /* Hybrid Music 5000 Synthesiser */ + device.option_add("m87", BBC_M87); /* Peartree Music 87 Synthesiser */ device.option_add("multiform", BBC_MULTIFORM); /* PEDL Multiform Z80 */ device.option_add("opus3", BBC_OPUS3); /* Opus Challenger 3 */ device.option_add("pdram", BBC_PDRAM); /* Micro User Pull Down RAM */ @@ -166,7 +170,6 @@ void bbcm_1mhzbus_devices(device_slot_interface &device) { //device.option_add("teletext", BBC_TELETEXT); /* Acorn ANE01 Teletext Adapter */ device.option_add("ieee488", BBC_IEEE488); /* Acorn ANK01 IEEE488 Interface */ - //device.option_add("m500", BBC_M500); /* Acorn ANV02 Music 500 */ device.option_add("awhd", BBC_AWHD); /* Acorn Winchester Disc */ device.option_add("beebide", BBC_BEEBIDE); /* Sprow BeebIDE 16-bit */ device.option_add("ide8", BBC_IDE8); /* RetroClinic BBC 8-bit IDE */ @@ -175,9 +178,9 @@ void bbcm_1mhzbus_devices(device_slot_interface &device) device.option_add("emrmidi", BBC_EMRMIDI); /* EMR Midi Interface */ //device.option_add("procyon", BBC_PROCYON); /* CST Procyon IEEE Interface */ device.option_add("m2000", BBC_M2000); /* Hybrid Music 2000 Interface */ - //device.option_add("m3000", BBC_M3000); /* Hybrid Music 3000 Expander */ - //device.option_add("m5000", BBC_M5000); /* Hybrid Music 5000 Synthesiser */ - //device.option_add("m87", BBC_M87); /* Peartree Music 87 Synthesiser */ + device.option_add("m3000", BBC_M3000); /* Hybrid Music 3000 Expander */ + device.option_add("m5000", BBC_M5000); /* Hybrid Music 5000 Synthesiser */ + device.option_add("m87", BBC_M87); /* Peartree Music 87 Synthesiser */ device.option_add("multiform", BBC_MULTIFORM); /* PEDL Multiform Z80 */ device.option_add("opusa", BBC_OPUSA); /* Opus Challenger ADFS */ device.option_add("pdram", BBC_PDRAM); /* Micro User Pull Down RAM */ diff --git a/src/devices/bus/bbc/1mhzbus/m5000.cpp b/src/devices/bus/bbc/1mhzbus/m5000.cpp new file mode 100644 index 00000000000..1844de74a0d --- /dev/null +++ b/src/devices/bus/bbc/1mhzbus/m5000.cpp @@ -0,0 +1,435 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +// thanks-to:Darren Izzard +/********************************************************************** + + Acorn ANV02 Music 500 + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_ANV02_Music500.html + + Hybrid Music 5000 Synthesiser + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-5000-Synthesiser/ + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music5000.html + + Hybrid Music 3000 Expander + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-3000-Expander/ + + Peartree Music 87 Synthesiser + + http://www.computinghistory.org.uk/det/4535/Peartree-Computers-Music-87-Synthesizer-(M500)/ + + TODO: + - convert to use DAC76 device + - add suitably patched version of Ample ROM + - add ROMs for Music 87 + +**********************************************************************/ + + +#include "emu.h" +#include "m5000.h" +#include "speaker.h" +#include "softlist_dev.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(HTMUSIC, htmusic_device, "htmusic", "Hybrid Technology Music System") + +DEFINE_DEVICE_TYPE(BBC_M500, bbc_m500_device, "bbc_m500", "Acorn Music 500"); +DEFINE_DEVICE_TYPE(BBC_M5000, bbc_m5000_device, "bbc_m5000", "Hybrid Music 5000 Synthesiser"); +DEFINE_DEVICE_TYPE(BBC_M3000, bbc_m3000_device, "bbc_m3000", "Hybrid Music 3000 Expander"); +DEFINE_DEVICE_TYPE(BBC_M87, bbc_m87_device, "bbc_m87", "Peartree Music 87 Synthesiser"); + + +//------------------------------------------------- +// ROM( m5000 ) +//------------------------------------------------- + +//ROM_START( m5000 ) + //ROM_REGION(0x4000, "exp_rom", 0) + // Each AMPLE Nucleus ROM has a unique identification code (ID) + //ROM_LOAD("ample_patch.rom", 0x0000, 0x4000, CRC(15bbd499) SHA1(ac90f403b3bde0cdaae68546799b94962bc00fcb)) +//ROM_END + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void bbc_m500_device::add_common_devices(machine_config &config) +{ + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + HTMUSIC(config, m_hybrid, 12_MHz_XTAL / 2); + m_hybrid->add_route(0, "lspeaker", 1.0); + m_hybrid->add_route(1, "rspeaker", 1.0); + + BBC_1MHZBUS_SLOT(config, m_1mhzbus, DERIVED_CLOCK(1, 1), bbc_1mhzbus_devices, nullptr); + m_1mhzbus->irq_handler().set(DEVICE_SELF_OWNER, FUNC(bbc_1mhzbus_slot_device::irq_w)); + m_1mhzbus->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(bbc_1mhzbus_slot_device::nmi_w)); +} + +void bbc_m500_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); + + SOFTWARE_LIST(config, "flop_ls_hybrid").set_original("bbc_flop_hybrid").set_filter("M500"); +} + +void bbc_m5000_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); + + SOFTWARE_LIST(config, "flop_ls_hybrid").set_original("bbc_flop_hybrid").set_filter("M5000"); +} + +void bbc_m3000_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); +} + +void bbc_m87_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); + + SOFTWARE_LIST(config, "flop_ls_hybrid").set_original("bbc_flop_hybrid").set_filter("M87"); +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +//const tiny_rom_entry *bbc_m5000_device::device_rom_region() const +//{ + //return ROM_NAME( m5000 ); +//} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_hybrid_device - constructor +//------------------------------------------------- + +bbc_m500_device::bbc_m500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_bbc_1mhzbus_interface(mconfig, *this) + , m_1mhzbus(*this, "1mhzbus") + , m_hybrid(*this, "hybrid") + , m_page(0) +{ +} + +bbc_m500_device::bbc_m500_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M500, tag, owner, clock) +{ +} + +bbc_m5000_device::bbc_m5000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M5000, tag, owner, clock) +{ +} + +bbc_m3000_device::bbc_m3000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M3000, tag, owner, clock) +{ +} + +bbc_m87_device::bbc_m87_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M87, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_m500_device::device_start() +{ + // register for save states + save_item(NAME(m_page)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +uint8_t bbc_m500_device::fred_r(offs_t offset) +{ + return m_1mhzbus->fred_r(offset); +} + +void bbc_m500_device::fred_w(offs_t offset, uint8_t data) +{ + if (offset == 0xff) + { + m_page = data; + } + + m_1mhzbus->fred_w(offset, data); +} + +uint8_t bbc_m500_device::jim_r(offs_t offset) +{ + return m_1mhzbus->jim_r(offset); +} + +void bbc_m500_device::jim_w(offs_t offset, uint8_t data) +{ + if ((m_page & 0xf0) == 0x30) + { + uint8_t page = (m_page >> 1) & 7; + + m_hybrid->ram_w((page << 8) | offset, data); + } + + m_1mhzbus->jim_w(offset, data); +} + + +void bbc_m3000_device::jim_w(offs_t offset, uint8_t data) +{ + if ((m_page & 0xf0) == 0x50) + { + uint8_t page = (m_page >> 1) & 7; + + m_hybrid->ram_w((page << 8) | offset, data); + } + + m_1mhzbus->jim_w(offset, data); +} + + +//************************************************************************** +// HYBRID MUSIC IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// htmusic_device - constructor +//------------------------------------------------- + +htmusic_device::htmusic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, HTMUSIC, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_counter(0) + , m_c4d(0) + , m_sign(0) + , m_sam(0) + , m_disable(false) + , m_modulate(false) + , m_dsp_timer(nullptr) + , m_stream(nullptr) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void htmusic_device::device_start() +{ + // 12-bit antilog as per Am6070 datasheet + for (int i = 0; i < 128; i++) + m_antilog[i] = (uint16_t)(2 * (pow(2.0, i >> 4) * ((i & 15) + 16.5) - 16.5)); + + // create the stream + m_stream = stream_alloc(0, 2, clock() / 128); + + // allocate timer + m_dsp_timer = timer_alloc(0); + + // register for save states + save_item(NAME(m_wave_ram)); + save_item(NAME(m_phase_ram)); + save_item(NAME(m_counter)); + save_item(NAME(m_c4d)); + save_item(NAME(m_sign)); + save_item(NAME(m_disable)); + save_item(NAME(m_modulate)); + save_item(NAME(m_sam)); + save_item(NAME(m_sam_l)); + save_item(NAME(m_sam_r)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void htmusic_device::device_reset() +{ + // clear ram + memset(m_wave_ram, 0, sizeof(m_wave_ram)); + memset(m_phase_ram, 0, sizeof(m_phase_ram)); + + memset(m_sam_l, 0, sizeof(m_sam_l)); + memset(m_sam_r, 0, sizeof(m_sam_r)); + + // reset counter + m_counter = 0; + m_disable = false; + m_modulate = false; + + // start timer + m_dsp_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); +} + + +//------------------------------------------------- +// digital signal processor +//------------------------------------------------- + +#define I_CHAN(c) ((((c) & 0x1e) >> 1) + (((c) & 0x01) << 7) + 0x700) +#define I_FREQ(c) (I_CHAN(c)) +#define I_WAVESEL(c) (I_CHAN(c) + 0x50) +#define I_AMP(c) (I_CHAN(c) + 0x60) +#define I_CTL(c) (I_CHAN(c) + 0x70) +#define FREQ(c) ((m_wave_ram[I_FREQ(c) + 0x20] << 16) | (m_wave_ram[I_FREQ(c) + 0x10] << 8) | (m_wave_ram[I_FREQ(c)] & 0x7e)) +#define DISABLE(c) (BIT(m_wave_ram[I_FREQ(c)], 0)) +#define AMP(c) (m_wave_ram[I_AMP(c)]) +#define WAVESEL(c) (m_wave_ram[I_WAVESEL(c)] >> 4) +#define CTL(c) (m_wave_ram[I_CTL(c)]) +#define MODULATE(c) (BIT(CTL(c), 5)) +#define INVERT(c) (BIT(CTL(c), 4)) +#define PAN(c) (CTL(c) & 0x0f) + +void htmusic_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + // 4-bit channel select + uint8_t channel = (m_counter >> 3) & 0x0f; + uint8_t c = (channel << 1) + (m_modulate ? 1 : 0); + + // 3-bit program counter + switch (m_counter & 0x07) + { + case 0: + m_stream->update(); + + m_disable = DISABLE(c); + break; + + case 1: + break; + + case 2: + // In the real hardware the disable bit works by forcing the + // phase accumulator to zero. + if (m_disable) + { + m_phase_ram[channel] = 0; + m_c4d = 0; + } + else + { + uint32_t sum = m_phase_ram[channel] + FREQ(c); + m_phase_ram[channel] = sum & 0xffffff; + // c4d is used for "Synchronization" e.g. the "Wha" instrument + m_c4d = sum >> 24; + } + break; + + case 3: + break; + + case 4: + break; + + case 5: + m_sam = m_wave_ram[(WAVESEL(c) << 7) + (m_phase_ram[channel] >> 17)]; + break; + + case 6: + // The amplitude operates in the log domain + // - m_sam holds the wave table output which is 1 bit sign and 7 bit magnitude + // - amp holds the amplitude which is 1 bit sign and 8 bit magnitude (0x00 being quite, 0x7f being loud) + // The real hardware combines these in a single 8 bit adder, as we do here. + // + // Consider a positive wav value (sign bit = 1) + // wav: (0x80 -> 0xFF) + amp: (0x00 -> 0x7F) => (0x80 -> 0x7E) + // values in the range 0x80...0xff are very small and clamped to zero + // + // Consider a negative wav value (sign bit = 0) + // wav: (0x00 -> 0x7F) + amp: (0x00 -> 0x7F) => (0x00 -> 0xFE) + // values in the range 0x00...0x7f are very small and clamped to zero + // + // In both cases: + // - zero clamping happens when the sign bit stays the same + // - the 7-bit result is in bits 0..6 + // + m_sign = m_sam & 0x80; + m_sam += AMP(c); + if ((m_sign ^ m_sam) & 0x80) + m_sam &= 0x7f; // sign bits being different is the normal case + else + m_sam = 0x00; // sign bits being the same indicates underflow so clamp to zero + break; + + case 7: + { + m_modulate = MODULATE(c) && (!!(m_sign) || !!(m_c4d)); + + // in the real hardware, inversion does not affect modulation + if (INVERT(c)) + m_sign ^= 0x80; + + // m_sam is an 8-bit log value + if (m_sign) + m_sam = m_antilog[m_sam]; // sign being 1 is positive + else + m_sam = -m_antilog[m_sam]; // sign being 0 is negative + + // m_sam is a 12-bit linear sample + uint8_t pan; + switch (PAN(c)) + { + case 8: case 9: case 10: pan = 6; break; + case 11: pan = 5; break; + case 12: pan = 4; break; + case 13: pan = 3; break; + case 14: pan = 2; break; + case 15: pan = 1; break; + default: pan = 0; break; + } + + // Apply panning. In the real hardware, a disabled channel is not actually + // forced to zero, but this seems harmless so leave in for now. + m_sam_l[channel] = m_disable ? 0 : ((m_sam * pan) / 6); + m_sam_r[channel] = m_disable ? 0 : ((m_sam * (6 - pan)) / 6); + break; + } + } + + m_counter++; +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void htmusic_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) +{ + // reset the output streams + outputs[0].fill(0); + outputs[1].fill(0); + + // iterate over channels and accumulate sample data + for (int channel = 0; channel < 16; channel++) + { + for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) + { + outputs[0].add_int(sampindex, m_sam_l[channel], 8031 * 16); + outputs[1].add_int(sampindex, m_sam_r[channel], 8031 * 16); + } + } +} diff --git a/src/devices/bus/bbc/1mhzbus/m5000.h b/src/devices/bus/bbc/1mhzbus/m5000.h new file mode 100644 index 00000000000..bf11943d7cd --- /dev/null +++ b/src/devices/bus/bbc/1mhzbus/m5000.h @@ -0,0 +1,158 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Acorn ANV02 Music 500 + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_ANV02_Music500.html + + Hybrid Music 5000 Synthesiser + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-5000-Synthesiser/ + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music5000.html + + Hybrid Music 3000 Expander + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-3000-Expander/ + + Peartree Music 87 Synthesiser + + http://www.computinghistory.org.uk/det/4535/Peartree-Computers-Music-87-Synthesizer-(M500)/ + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_1MHZBUS_M5000_H +#define MAME_BUS_BBC_1MHZBUS_M5000_H + +#include "1mhzbus.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> htmusic_device + +class htmusic_device : public device_t, public device_sound_interface +{ +public: + htmusic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void ram_w(offs_t offset, uint8_t data) { m_wave_ram[offset & 0x7ff] = data; } + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) override; + +private: + uint16_t m_antilog[128]; + uint8_t m_wave_ram[0x800]; + uint32_t m_phase_ram[0x200]; + + uint8_t m_counter; + uint8_t m_c4d; + uint8_t m_sign; + int16_t m_sam; + bool m_disable; + bool m_modulate; + + stream_sample_t m_sam_l[16]; + stream_sample_t m_sam_r[16]; + + emu_timer *m_dsp_timer; + + sound_stream *m_stream; +}; + + +// ======================> bbc_m500_device + +class bbc_m500_device : public device_t, public device_bbc_1mhzbus_interface +{ +public: + // construction/destruction + bbc_m500_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + bbc_m500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + void add_common_devices(machine_config &config); + + virtual uint8_t fred_r(offs_t offset) override; + virtual void fred_w(offs_t offset, uint8_t data) override; + virtual uint8_t jim_r(offs_t offset) override; + virtual void jim_w(offs_t offset, uint8_t data) override; + + required_device m_1mhzbus; + required_device m_hybrid; + + uint8_t m_page; +}; + + +// ======================> bbc_m5000_device + +class bbc_m5000_device : public bbc_m500_device +{ +public: + // construction/destruction + bbc_m5000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + //virtual const tiny_rom_entry *device_rom_region() const override; +}; + + +// ======================> bbc_m3000_device + +class bbc_m3000_device : public bbc_m500_device +{ +public: + // construction/destruction + bbc_m3000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual void jim_w(offs_t offset, uint8_t data) override; +}; + + +// ======================> bbc_m87_device + +class bbc_m87_device : public bbc_m500_device +{ +public: + // construction/destruction + bbc_m87_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_M500, bbc_m500_device); +DECLARE_DEVICE_TYPE(BBC_M5000, bbc_m5000_device); +DECLARE_DEVICE_TYPE(BBC_M3000, bbc_m3000_device); +DECLARE_DEVICE_TYPE(BBC_M87, bbc_m87_device); + + +#endif /* MAME_BUS_BBC_1MHZBUS_M5000_H */ -- cgit v1.2.3