bbcmc: Added expansion port and Mertec Companion expansion device.

This commit is contained in:
Nigel Barnes 2018-10-26 16:44:42 +01:00
parent e4f1635973
commit 9bcf933bcc
8 changed files with 598 additions and 11 deletions

View File

@ -308,6 +308,21 @@ if (BUSES["BBC_ANALOGUE"]~=null) then
end
---------------------------------------------------
--
--@src/devices/bus/bbc/exp/exp.h,BUSES["BBC_EXP"] = true
---------------------------------------------------
if (BUSES["BBC_EXP"]~=null) then
files {
MAME_DIR .. "src/devices/bus/bbc/exp/exp.cpp",
MAME_DIR .. "src/devices/bus/bbc/exp/exp.h",
MAME_DIR .. "src/devices/bus/bbc/exp/mertec.cpp",
MAME_DIR .. "src/devices/bus/bbc/exp/mertec.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/bbc/joyport/joyport.h,BUSES["BBC_JOYPORT"] = true

View File

@ -695,6 +695,7 @@ BUSES["ARCADIA"] = true
BUSES["ASTROCADE"] = true
BUSES["BBC_FDC"] = true
BUSES["BBC_ANALOGUE"] = true
BUSES["BBC_EXP"] = true
BUSES["BBC_JOYPORT"] = true
BUSES["BBC_1MHZBUS"] = true
BUSES["BBC_TUBE"] = true

View File

@ -0,0 +1,183 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
BBC Master Compact Expansion slot emulation
**********************************************************************/
#include "emu.h"
#include "exp.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(BBC_EXP_SLOT, bbc_exp_slot_device, "bbc_exp_slot", "BBC Master Compact Expansion port")
//**************************************************************************
// DEVICE BBC_EXP PORT INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_bbc_exp_interface - constructor
//-------------------------------------------------
device_bbc_exp_interface::device_bbc_exp_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig, device)
{
m_slot = dynamic_cast<bbc_exp_slot_device *>(device.owner());
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// bbc_exp_slot_device - constructor
//-------------------------------------------------
bbc_exp_slot_device::bbc_exp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, BBC_EXP_SLOT, tag, owner, clock),
device_slot_interface(mconfig, *this),
m_card(nullptr),
m_irq_handler(*this),
m_nmi_handler(*this),
m_cb1_handler(*this),
m_cb2_handler(*this)
{
}
//-------------------------------------------------
// device_validity_check -
//-------------------------------------------------
void bbc_exp_slot_device::device_validity_check(validity_checker &valid) const
{
device_t *const carddev = get_card_device();
if (carddev && !dynamic_cast<device_bbc_exp_interface *>(carddev))
osd_printf_error("Card device %s (%s) does not implement device_bbc_exp_interface\n", carddev->tag(), carddev->name());
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void bbc_exp_slot_device::device_start()
{
device_t *const carddev = get_card_device();
m_card = dynamic_cast<device_bbc_exp_interface *>(carddev);
if (carddev && !m_card)
fatalerror("Card device %s (%s) does not implement device_bbc_exp_interface\n", carddev->tag(), carddev->name());
// resolve callbacks
m_irq_handler.resolve_safe();
m_nmi_handler.resolve_safe();
m_cb1_handler.resolve_safe();
m_cb2_handler.resolve_safe();
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void bbc_exp_slot_device::device_reset()
{
}
//-------------------------------------------------
// read
//-------------------------------------------------
READ8_MEMBER(bbc_exp_slot_device::fred_r)
{
if (m_card)
return m_card->fred_r(space, offset);
else
return 0xff;
}
READ8_MEMBER(bbc_exp_slot_device::jim_r)
{
if (m_card)
return m_card->jim_r(space, offset);
else
return 0xff;
}
READ8_MEMBER(bbc_exp_slot_device::sheila_r)
{
if (m_card)
return m_card->sheila_r(space, offset);
else
return 0xfe;
}
//-------------------------------------------------
// write
//-------------------------------------------------
WRITE8_MEMBER(bbc_exp_slot_device::fred_w)
{
if (m_card)
m_card->fred_w(space, offset, data);
}
WRITE8_MEMBER(bbc_exp_slot_device::jim_w)
{
if (m_card)
m_card->jim_w(space, offset, data);
}
WRITE8_MEMBER(bbc_exp_slot_device::sheila_w)
{
if (m_card)
m_card->sheila_w(space, offset, data);
}
//-------------------------------------------------
// pb_r
//-------------------------------------------------
READ8_MEMBER(bbc_exp_slot_device::pb_r)
{
if (m_card)
return 0x1f | m_card->pb_r(space, 0);
else
return 0xff;
}
//-------------------------------------------------
// pb_w
//-------------------------------------------------
WRITE8_MEMBER(bbc_exp_slot_device::pb_w)
{
if (m_card)
m_card->pb_w(space, 0, data);
}
//-------------------------------------------------
// SLOT_INTERFACE( bbc_exp_devices )
//-------------------------------------------------
// slot devices
//#include "autocue.h"
#include "mertec.h"
void bbc_exp_devices(device_slot_interface &device)
{
//device.option_add("autocue", BBC_AUTOCUE); /* Autocue RAM disk board */
device.option_add("mertec", BBC_MERTEC); /* Mertec Compact Companion */
}

View File

@ -0,0 +1,140 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
BBC Master Compact Expansion slot emulation
**********************************************************************
Pin Side A Side B
1 SCREEN (0v) SCREEN (0v)
2 +5v +5v
3 AT13 A10
4 NOT RST CD3
5 AA15 A11
6 A8 A9
7 A13 CD7
8 A12 CD6
9 phi 2 OUT CD5
10 not connected CD4
11 not connected LPTSTP
12 B READ / NOT WRITE BA7
13 NOT NMI BA6
14 NOT IRQ BA5
15 NOT INFC BA4
16 NOT INFD BA3
17 AA14 BA2
18 NOT 8MHz BA1
19 0v BA0
20 PB7 (old user port) CD0
21 PB6 (old user port) CD2
22 PB5 (old user port) CD1
=========== POLARISATION SLOT ===========
24 0v 0v
25 SCREEN (0v) SCREEN (0v)
**********************************************************************/
#ifndef MAME_BUS_BBC_EXP_EXP_H
#define MAME_BUS_BBC_EXP_EXP_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> bbc_exp_slot_device
class device_bbc_exp_interface;
class bbc_exp_slot_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
template <typename T>
bbc_exp_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, const char *default_option)
: bbc_exp_slot_device(mconfig, tag, owner)
{
option_reset();
slot_options(*this);
set_default_option(default_option);
set_fixed(false);
}
bbc_exp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
// callbacks
auto irq_handler() { return m_irq_handler.bind(); }
auto nmi_handler() { return m_nmi_handler.bind(); }
// callbacks for mertec device (also connects to joyport)
auto cb1_handler() { return m_cb1_handler.bind(); }
auto cb2_handler() { return m_cb2_handler.bind(); }
virtual DECLARE_READ8_MEMBER(fred_r);
virtual DECLARE_WRITE8_MEMBER(fred_w);
virtual DECLARE_READ8_MEMBER(jim_r);
virtual DECLARE_WRITE8_MEMBER(jim_w);
virtual DECLARE_READ8_MEMBER(sheila_r);
virtual DECLARE_WRITE8_MEMBER(sheila_w);
DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); }
DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
// additional handlers for mertec device
DECLARE_WRITE_LINE_MEMBER(cb1_w) { m_cb1_handler(state); }
DECLARE_WRITE_LINE_MEMBER(cb2_w) { m_cb2_handler(state); }
DECLARE_READ8_MEMBER(pb_r);
DECLARE_WRITE8_MEMBER(pb_w);
protected:
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const override;
virtual void device_start() override;
virtual void device_reset() override;
device_bbc_exp_interface *m_card;
private:
devcb_write_line m_irq_handler;
devcb_write_line m_nmi_handler;
devcb_write_line m_cb1_handler;
devcb_write_line m_cb2_handler;
};
// ======================> device_bbc_exp_interface
class device_bbc_exp_interface : public device_slot_card_interface
{
public:
virtual DECLARE_READ8_MEMBER(fred_r) { return 0xff; }
virtual DECLARE_WRITE8_MEMBER(fred_w) { }
virtual DECLARE_READ8_MEMBER(jim_r) { return 0xff; }
virtual DECLARE_WRITE8_MEMBER(jim_w) { }
virtual DECLARE_READ8_MEMBER(sheila_r) { return 0xfe; }
virtual DECLARE_WRITE8_MEMBER(sheila_w) { }
virtual DECLARE_READ8_MEMBER(pb_r) { return 0xff; }
virtual DECLARE_WRITE8_MEMBER(pb_w) { }
protected:
device_bbc_exp_interface(const machine_config &mconfig, device_t &device);
bbc_exp_slot_device *m_slot;
};
// device type definition
DECLARE_DEVICE_TYPE(BBC_EXP_SLOT, bbc_exp_slot_device)
void bbc_exp_devices(device_slot_interface &device);
#endif // MAME_BUS_BBC_EXP_EXP_H

View File

@ -0,0 +1,177 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
Mertec Compact Companion
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Mertec_CompactComp.html
TODO:
- Fix userport, by somehow passing lines into joyport
- Not sure whether any 1MHz bus devices should work on the 2MHz bus
- No idea how the 6821 is connected/used
**********************************************************************/
#include "emu.h"
#include "mertec.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(BBC_MERTEC, bbc_mertec_device, "bbc_mertec", "Mertec Compact Companion");
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
ROM_START(mertec)
ROM_REGION(0x8000, "ext_rom", 0)
ROM_LOAD("mertec-companion-v0.99.rom", 0x0000, 0x8000, CRC(af8ff8d7) SHA1(0c4017ffbb480168e54c6b153da257ec5ea29d4e))
ROM_END
const tiny_rom_entry *bbc_mertec_device::device_rom_region() const
{
return ROM_NAME(mertec);
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void bbc_mertec_device::device_add_mconfig(machine_config &config)
{
PIA6821(config, m_pia, 16_MHz_XTAL / 16);
//m_pia->readpb_handler().set("userport", FUNC(bbc_userport_slot_device::pb_r));
//m_pia->writepb_handler().set("userport", FUNC(bbc_userport_slot_device::pb_w));
//m_pia->irq_handler().set("irqs", FUNC(input_merger_device::in_w<0>));
/* adc */
UPD7002(config, m_upd7002, 0);
m_upd7002->set_get_analogue_callback(FUNC(bbc_mertec_device::get_analogue_input), this);
m_upd7002->set_eoc_callback(FUNC(bbc_mertec_device::upd7002_eoc), this);
/* analogue port */
BBC_ANALOGUE_SLOT(config, m_analog, bbc_analogue_devices, nullptr);
/* user port */
BBC_USERPORT_SLOT(config, m_userport, bbc_userport_devices, nullptr);
//m_userport->cb1_handler().set(m_pia, FUNC(via6522_device::write_cb1));
//m_userport->cb2_handler().set(m_pia, FUNC(via6522_device::write_cb2));
/* 2mhz bus port */
BBC_1MHZBUS_SLOT(config, m_2mhzbus, bbc_1mhzbus_devices, nullptr);
m_2mhzbus->irq_handler().set(DEVICE_SELF_OWNER, FUNC(bbc_exp_slot_device::irq_w));
m_2mhzbus->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(bbc_exp_slot_device::nmi_w));
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// bbc_mertec_device - constructor
//-------------------------------------------------
bbc_mertec_device::bbc_mertec_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, BBC_MERTEC, tag, owner, clock)
, device_bbc_exp_interface(mconfig, *this)
, m_pia(*this, "pia")
, m_upd7002(*this, "upd7002")
, m_analog(*this, "analogue")
, m_userport(*this, "userport")
, m_2mhzbus(*this, "2mhzbus")
, m_ext_rom(*this, "ext_rom")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void bbc_mertec_device::device_start()
{
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void bbc_mertec_device::device_reset()
{
machine().root_device().membank("bank4")->configure_entry(0, m_ext_rom->base() + 0x0000);
machine().root_device().membank("bank5")->configure_entry(0, m_ext_rom->base() + 0x1000);
machine().root_device().membank("bank4")->configure_entry(1, m_ext_rom->base() + 0x4000);
machine().root_device().membank("bank5")->configure_entry(1, m_ext_rom->base() + 0x5000);
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
int bbc_mertec_device::get_analogue_input(int channel_number)
{
return ((0xff - m_analog->ch_r(channel_number)) << 8);
}
void bbc_mertec_device::upd7002_eoc(int data)
{
//m_via6522_0->write_cb1(data);
}
READ8_MEMBER(bbc_mertec_device::fred_r)
{
return m_2mhzbus->fred_r(space, offset);
}
WRITE8_MEMBER(bbc_mertec_device::fred_w)
{
m_2mhzbus->fred_w(space, offset, data);
}
READ8_MEMBER(bbc_mertec_device::jim_r)
{
return m_2mhzbus->jim_r(space, offset);
}
WRITE8_MEMBER(bbc_mertec_device::jim_w)
{
m_2mhzbus->jim_w(space, offset, data);
}
READ8_MEMBER(bbc_mertec_device::sheila_r)
{
uint8_t data = 0xfe;
if (offset >= 0x18 && offset < 0x20)
{
data = m_upd7002->read(space, offset & 0x03);
}
return data;
}
WRITE8_MEMBER(bbc_mertec_device::sheila_w)
{
if (offset >= 0x18 && offset < 0x20)
{
m_upd7002->write(space, offset & 0x03, data);
}
}
READ8_MEMBER(bbc_mertec_device::pb_r)
{
return m_userport->pb_r(space, 0);
}
WRITE8_MEMBER(bbc_mertec_device::pb_w)
{
m_userport->pb_w(space, 0, data);
}

View File

@ -0,0 +1,71 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
Mertec Compact Companion
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Mertec_CompactComp.html
**********************************************************************/
#ifndef MAME_BUS_BBC_EXP_MERTEC_H
#define MAME_BUS_BBC_EXP_MERTEC_H
#include "exp.h"
#include "machine/6821pia.h"
#include "machine/upd7002.h"
#include "bus/bbc/1mhzbus/1mhzbus.h"
#include "bus/bbc/analogue/analogue.h"
#include "bus/bbc/userport/userport.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class bbc_mertec_device :
public device_t,
public device_bbc_exp_interface
{
public:
// construction/destruction
bbc_mertec_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;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual DECLARE_READ8_MEMBER(fred_r) override;
virtual DECLARE_WRITE8_MEMBER(fred_w) override;
virtual DECLARE_READ8_MEMBER(jim_r) override;
virtual DECLARE_WRITE8_MEMBER(jim_w) override;
virtual DECLARE_READ8_MEMBER(sheila_r) override;
virtual DECLARE_WRITE8_MEMBER(sheila_w) override;
virtual DECLARE_READ8_MEMBER(pb_r) override;
virtual DECLARE_WRITE8_MEMBER(pb_w) override;
private:
int get_analogue_input(int channel_number);
void upd7002_eoc(int data);
required_device<pia6821_device> m_pia;
required_device<upd7002_device> m_upd7002;
required_device<bbc_analogue_slot_device> m_analog;
required_device<bbc_userport_slot_device> m_userport;
required_device<bbc_1mhzbus_slot_device> m_2mhzbus;
required_memory_region m_ext_rom;
};
// device type definition
DECLARE_DEVICE_TYPE(BBC_MERTEC, bbc_mertec_device);
#endif /* MAME_BUS_BBC_EXP_MERTEC_H */

View File

@ -298,9 +298,9 @@ void bbcm_state::bbcmc_bankdev(address_map &map)
map.unmap_value_high();
/* ACCCON TST bit - normal state */
map(0x0000, 0x03ff).rom().region("mos", 0x3c00); // fc00-ffff OS ROM (continued)
//map(0x0000, 0x00ff).mirror(0x400).rw(m_exp, FUNC(bbc_exp_slot_device::fred_r), FUNC(bbc_exp_slot_device::fred_w)); // fc00-fcff Compact FRED Address Page
//map(0x0100, 0x01ff).mirror(0x400).rw(m_exp, FUNC(bbc_exp_slot_device::jim_r), FUNC(bbc_exp_slot_device::jim_w)); // fd00-fdff Compact JIM Address Page
//map(0x0200, 0x02ff).mirror(0x400).rw(m_exp, FUNC(bbc_exp_slot_device::sheila_r), FUNC(bbc_exp_slot_device::sheila_w)); // fd00-fdff Compact SHEILA Address Page
map(0x0000, 0x00ff).mirror(0x400).rw(m_exp, FUNC(bbc_exp_slot_device::fred_r), FUNC(bbc_exp_slot_device::fred_w)); // fc00-fcff Compact FRED Address Page
map(0x0100, 0x01ff).mirror(0x400).rw(m_exp, FUNC(bbc_exp_slot_device::jim_r), FUNC(bbc_exp_slot_device::jim_w)); // fd00-fdff Compact JIM Address Page
map(0x0200, 0x02ff).mirror(0x400).rw(m_exp, FUNC(bbc_exp_slot_device::sheila_r), FUNC(bbc_exp_slot_device::sheila_w)); // fd00-fdff Compact SHEILA Address Page
map(0x0200, 0x0200).mirror(0x406).rw(m_hd6845, FUNC(hd6845_device::status_r), FUNC(hd6845_device::address_w)); // fe00-fe07 6845 CRTC Video controller
map(0x0201, 0x0201).mirror(0x406).rw(m_hd6845, FUNC(hd6845_device::register_r), FUNC(hd6845_device::register_w));
map(0x0208, 0x020f).mirror(0x400).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // fe08-fe0f 6850 ACIA Serial controller
@ -1671,9 +1671,9 @@ void bbcm_state::bbcmc(machine_config &config)
/* user via */
m_via6522_1->readpb_handler().set(m_joyport, FUNC(bbc_joyport_slot_device::pb_r)).mask(0x1f);
//m_via6522_1->readpb_handler().append(m_exp, FUNC(bbc_exp_slot_device::pb_r)).mask(0xe0);
m_via6522_1->readpb_handler().append(m_exp, FUNC(bbc_exp_slot_device::pb_r)).mask(0xe0);
m_via6522_1->writepb_handler().set(m_joyport, FUNC(bbc_joyport_slot_device::pb_w)).mask(0x1f);
//m_via6522_1->writepb_handler().append(m_exp, FUNC(bbc_exp_slot_device::pb_w)).mask(0xe0);
m_via6522_1->writepb_handler().append(m_exp, FUNC(bbc_exp_slot_device::pb_w)).mask(0xe0);
/* cartridge sockets */
config.device_remove("cartslot1");
@ -1699,9 +1699,9 @@ void bbcm_state::bbcmc(machine_config &config)
config.device_remove("cart_ls_m");
/* expansion ports */
//BBC_EXP_SLOT(config, m_exp, bbc_exp_devices, nullptr);
//m_exp->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<3>));
//m_exp->nmi_handler().set(FUNC(bbc_state::bus_nmi_w));
BBC_EXP_SLOT(config, m_exp, bbc_exp_devices, nullptr);
m_exp->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<3>));
m_exp->nmi_handler().set(FUNC(bbc_state::bus_nmi_w));
BBC_JOYPORT_SLOT(config, m_joyport, bbc_joyport_devices, "joystick");
m_joyport->cb1_handler().set(m_via6522_1, FUNC(via6522_device::write_cb1));

View File

@ -43,7 +43,7 @@
//#include "bus/bbc/internal/internal.h"
#include "bus/bbc/tube/tube.h"
#include "bus/bbc/userport/userport.h"
//#include "bus/bbc/exp/exp.h"
#include "bus/bbc/exp/exp.h"
#include "bus/bbc/joyport/joyport.h"
#include "bus/generic/slot.h"
@ -86,7 +86,7 @@ public:
, m_1mhzbus(*this, "1mhzbus")
, m_userport(*this, "userport")
// , m_internal(*this, "internal")
// , m_exp(*this, "exp")
, m_exp(*this, "exp")
, m_rtc(*this, "rtc")
, m_i2cmem(*this, "i2cmem")
, m_fdc(*this, "fdc")
@ -270,7 +270,7 @@ protected:
optional_device<bbc_1mhzbus_slot_device> m_1mhzbus;
optional_device<bbc_userport_slot_device> m_userport;
//optional_device<bbc_internal_slot_device> m_internal;
//optional_device<bbc_exp_slot_device> m_exp;
optional_device<bbc_exp_slot_device> m_exp;
optional_device<mc146818_device> m_rtc;
optional_device<i2cmem_device> m_i2cmem;
optional_device<bbc_fdc_slot_device> m_fdc;