bbc: added opus challenger (floppy and ramdisc) device on 1mhz bus

This commit is contained in:
Nigel Barnes 2016-09-23 11:53:24 +01:00
parent 71629df0b7
commit 6a19971bbe
8 changed files with 364 additions and 14 deletions

View File

@ -277,6 +277,8 @@ if (BUSES["BBC_1MHZBUS"]~=null) then
files {
MAME_DIR .. "src/devices/bus/bbc/1mhzbus/1mhzbus.cpp",
MAME_DIR .. "src/devices/bus/bbc/1mhzbus/1mhzbus.h",
MAME_DIR .. "src/devices/bus/bbc/1mhzbus/opus3.cpp",
MAME_DIR .. "src/devices/bus/bbc/1mhzbus/opus3.h",
}
end

View File

@ -52,7 +52,19 @@ device_bbc_1mhzbus_interface::~device_bbc_1mhzbus_interface()
bbc_1mhzbus_slot_device::bbc_1mhzbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, BBC_1MHZBUS_SLOT, "BBC Micro 1MHz Bus port", tag, owner, clock, "bbc_1mhzbus_slot", __FILE__),
device_slot_interface(mconfig, *this)
device_slot_interface(mconfig, *this),
m_card(nullptr),
m_irq_handler(*this),
m_nmi_handler(*this)
{
}
//-------------------------------------------------
// bbc_1mhzbus_slot_device - destructor
//-------------------------------------------------
bbc_1mhzbus_slot_device::~bbc_1mhzbus_slot_device()
{
}
@ -64,6 +76,10 @@ bbc_1mhzbus_slot_device::bbc_1mhzbus_slot_device(const machine_config &mconfig,
void bbc_1mhzbus_slot_device::device_start()
{
m_card = dynamic_cast<device_bbc_1mhzbus_interface *>(get_card_device());
// resolve callbacks
m_irq_handler.resolve_safe();
m_nmi_handler.resolve_safe();
}
@ -90,23 +106,37 @@ void bbc_1mhzbus_slot_device::device_reset()
//#include "ieee488.h"
//#include "music500.h"
//#include "music5000.h"
//#include "opus3.h"
#include "opus3.h"
//#include "ramdisc.h"
//#include "torchg400.h"
//#include "torchg800.h"
//#include "beebsid.h"
//#include "prisma3.h"
SLOT_INTERFACE_START( bbc_1mhzbus_devices )
SLOT_INTERFACE_START(bbcb_1mhzbus_devices)
// SLOT_INTERFACE("teletext", BBC_TELETEXT) /* Acorn ANE01 Teletext Adapter */
// SLOT_INTERFACE("ieee488", BBC_IEEE488) /* Acorn ANK01 IEEE488 Interface */
// SLOT_INTERFACE("music500", BBC_MUSIC500) /* Acorn ANV02 Music500 */
// SLOT_INTERFACE("music2000", BBC_MUSIC2000) /* Hybrid Music 2000 MIDI Interface */
// SLOT_INTERFACE("music3000", BBC_MUSIC3000) /* Hybrid Music 3000 Expander */
// SLOT_INTERFACE("music5000", BBC_MUSIC5000) /* Hybrid Music 5000 Synthesiser */
// SLOT_INTERFACE("opus3", BBC_OPUS3) /* Opus Challenger 3 */
SLOT_INTERFACE("opus3", BBC_OPUS3) /* Opus Challenger 3 */
// SLOT_INTERFACE("ramdisc", BBC_RAMDISC) /* Morley Electronics RAM Disc */
// SLOT_INTERFACE("torchg400", BBC_TORCHG400) /* Torch Graduate G400 */
// SLOT_INTERFACE("torchg800", BBC_TORCHG800) /* Torch Graduate G800 */
// SLOT_INTERFACE("beebsid", BBC_BEEBSID) /* BeebSID */
// SLOT_INTERFACE("prisma3", BBC_PRISMA3) /* Prisma 3 - Millipede 1989 */
SLOT_INTERFACE_END
SLOT_INTERFACE_START( bbcm_1mhzbus_devices )
// SLOT_INTERFACE("teletext", BBC_TELETEXT) /* Acorn ANE01 Teletext Adapter */
// SLOT_INTERFACE("ieee488", BBC_IEEE488) /* Acorn ANK01 IEEE488 Interface */
// SLOT_INTERFACE("music500", BBC_MUSIC500) /* Acorn ANV02 Music500 */
// SLOT_INTERFACE("music2000", BBC_MUSIC2000) /* Hybrid Music 2000 MIDI Interface */
// SLOT_INTERFACE("music3000", BBC_MUSIC3000) /* Hybrid Music 3000 Expander */
// SLOT_INTERFACE("music5000", BBC_MUSIC5000) /* Hybrid Music 5000 Synthesiser */
// SLOT_INTERFACE("ramdisc", BBC_RAMDISC) /* Morley Electronics RAM Disc */
// SLOT_INTERFACE("beebsid", BBC_BEEBSID) /* BeebSID */
// SLOT_INTERFACE("prisma3", BBC_PRISMA3) /* Prisma 3 - Millipede 1989 */
SLOT_INTERFACE_END

View File

@ -95,8 +95,16 @@
MCFG_DEVICE_ADD(_tag, BBC_1MHZBUS_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
#define MCFG_BBC1MHZ_PASSTHRU_1MHZBUS_SLOT_ADD() \
MCFG_BBC_1MHZBUS_SLOT_ADD(BBC_1MHZBUS_SLOT_TAG, 0, bbc_1mhzbus_devices, nullptr)
#define MCFG_BBC_PASSTHRU_1MHZBUS_SLOT_ADD() \
MCFG_BBC_1MHZBUS_SLOT_ADD(BBC_1MHZBUS_SLOT_TAG, bbc_1mhzbus_devices, nullptr) \
MCFG_BBC_1MHZBUS_SLOT_IRQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, bbc_1mhzbus_slot_device, irq_w)) \
MCFG_BBC_1MHZBUS_SLOT_NMI_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, bbc_1mhzbus_slot_device, nmi_w))
#define MCFG_BBC_1MHZBUS_SLOT_IRQ_HANDLER(_devcb) \
devcb = &bbc_1mhzbus_slot_device::set_irq_handler(*device, DEVCB_##_devcb);
#define MCFG_BBC_1MHZBUS_SLOT_NMI_HANDLER(_devcb) \
devcb = &bbc_1mhzbus_slot_device::set_nmi_handler(*device, DEVCB_##_devcb);
//**************************************************************************
@ -107,14 +115,22 @@
class device_bbc_1mhzbus_interface;
class bbc_1mhzbus_slot_device : public device_t,
public device_slot_interface
class bbc_1mhzbus_slot_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
bbc_1mhzbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~bbc_1mhzbus_slot_device() {}
virtual ~bbc_1mhzbus_slot_device();
// callbacks
template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object)
{ return downcast<bbc_1mhzbus_slot_device &>(device).m_irq_handler.set_callback(object); }
template<class _Object> static devcb_base &set_nmi_handler(device_t &device, _Object object)
{ return downcast<bbc_1mhzbus_slot_device &>(device).m_nmi_handler.set_callback(object); }
DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); }
DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
protected:
// device-level overrides
@ -122,6 +138,10 @@ protected:
virtual void device_reset() override;
device_bbc_1mhzbus_interface *m_card;
private:
devcb_write_line m_irq_handler;
devcb_write_line m_nmi_handler;
};
@ -142,7 +162,8 @@ protected:
// device type definition
extern const device_type BBC_1MHZBUS_SLOT;
SLOT_INTERFACE_EXTERN( bbc_1mhzbus_devices );
SLOT_INTERFACE_EXTERN( bbcb_1mhzbus_devices );
SLOT_INTERFACE_EXTERN( bbcm_1mhzbus_devices );
#endif

View File

@ -0,0 +1,205 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
Opus Challenger 3-in-1
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Opus_Challenger3.html
http://www.beebmaster.co.uk/8bit/Challenger.html
OPUS CHALLENGER MEMORY MAP
Read Write
&FCF8 1770 Status register 1770 command register
&FCF9 1770 track register
&FCFA 1770 sector register
&FCFB 1770 data register
&FCFC 1770 drive control
Drive control register
0 Select side: 0=side 0, 1=side 1
1 Select drive 0
2 Select drive 1
3 ?Unused?
4 ?Always Set
5 Density select: 0=double, 1=single
6 ?Unused?
7 ?Unused?
The RAM is accessible through JIM (page &FD). One page is visible in JIM at a time.
The selected page is controlled by the two paging registers:
&FCFE Paging register MSB
&FCFF Paging register LSB
256K model has 1024 pages &000 to &3FF
512K model has 2048 pages &000 to &7FF
**********************************************************************/
#include "opus3.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type BBC_OPUS3 = &device_creator<bbc_opus3_device>;
//-------------------------------------------------
// MACHINE_DRIVER( opus3 )
//-------------------------------------------------
FLOPPY_FORMATS_MEMBER(floppy_formats)
FLOPPY_ACORN_SSD_FORMAT,
FLOPPY_ACORN_DSD_FORMAT,
FLOPPY_FSD_FORMAT,
FLOPPY_OPUS_DDOS_FORMAT
FLOPPY_FORMATS_END0
SLOT_INTERFACE_START(bbc_floppies)
SLOT_INTERFACE("525qd", FLOPPY_525_QD)
SLOT_INTERFACE_END
MACHINE_CONFIG_FRAGMENT( opus3 )
/* fdc */
MCFG_WD1770_ADD("wd1770", XTAL_16MHz / 2)
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_opus3_device, fdc_drq_w))
MCFG_FLOPPY_DRIVE_ADD("wd1770:0", bbc_floppies, "525qd", floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("wd1770:1", bbc_floppies, nullptr, floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
/* ram disk */
MCFG_RAM_ADD("ramdisk")
MCFG_RAM_DEFAULT_SIZE("512K")
MCFG_RAM_EXTRA_OPTIONS("256K")
MCFG_RAM_DEFAULT_VALUE(0x00)
MACHINE_CONFIG_END
ROM_START( opus3 )
ROM_REGION(0x4000, "dfs_rom", 0)
ROM_DEFAULT_BIOS("ch103")
ROM_SYSTEM_BIOS(0, "ch100", "Challenger 1.00")
ROMX_LOAD("ch100.rom", 0x0000, 0x4000, CRC(740a8335) SHA1(f3c75c21bcd7d4a4dfff922fd287230dcdb91d0e), ROM_BIOS(1))
ROM_SYSTEM_BIOS(1, "ch101", "Challenger 1.01")
ROMX_LOAD("ch101.rom", 0x0000, 0x4000, CRC(2f64503d) SHA1(37ee3f20bed50555720703b279f62aab0ed28922), ROM_BIOS(2))
ROM_SYSTEM_BIOS(2, "ch103", "Challenger 1.03")
ROMX_LOAD("ch103.rom", 0x0000, 0x4000, CRC(98367cf4) SHA1(eca3631aa420691f96b72bfdf2e9c2b613e1bf33), ROM_BIOS(3))
ROM_END
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
machine_config_constructor bbc_opus3_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( opus3 );
}
const tiny_rom_entry *bbc_opus3_device::device_rom_region() const
{
return ROM_NAME( opus3 );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// bbc_opus3_device - constructor
//-------------------------------------------------
bbc_opus3_device::bbc_opus3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, BBC_OPUS3, "Opus Challenger 3-in-1", tag, owner, clock, "bbc_opus3", __FILE__),
device_bbc_1mhzbus_interface(mconfig, *this),
m_dfs_rom(*this, "dfs_rom"),
m_ramdisk(*this, "ramdisk"),
m_fdc(*this, "wd1770"),
m_floppy0(*this, "wd1770:0"),
m_floppy1(*this, "wd1770:1")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void bbc_opus3_device::device_start()
{
address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM);
m_slot = dynamic_cast<bbc_1mhzbus_slot_device *>(owner());
space.install_readwrite_handler(0xfcf8, 0xfcfb, READ8_DEVICE_DELEGATE(m_fdc, wd1770_t, read), WRITE8_DEVICE_DELEGATE(m_fdc, wd1770_t, write));
space.install_write_handler(0xfcfc, 0xfcfc, WRITE8_DELEGATE(bbc_opus3_device, wd1770l_write));
space.install_write_handler(0xfcfe, 0xfcff, WRITE8_DELEGATE(bbc_opus3_device, page_w));
space.install_readwrite_handler(0xfd00, 0xfdff, READ8_DELEGATE(bbc_opus3_device, ramdisk_r), WRITE8_DELEGATE(bbc_opus3_device, ramdisk_w));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void bbc_opus3_device::device_reset()
{
machine().root_device().membank("bank4")->configure_entry(12, memregion("dfs_rom")->base());
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
WRITE8_MEMBER(bbc_opus3_device::wd1770l_write)
{
floppy_image_device *floppy = nullptr;
// bit 1, 2: drive select
if (BIT(data, 1)) floppy = m_floppy0->get_device();
if (BIT(data, 2)) floppy = m_floppy1->get_device();
m_fdc->set_floppy(floppy);
// bit 0: side select
if (floppy)
floppy->ss_w(BIT(data, 0));
// bit 4: interrupt enabled
m_fdc_ie = BIT(data, 4);
// bit 5: density
m_fdc->dden_w(BIT(data, 5));
}
WRITE_LINE_MEMBER(bbc_opus3_device::fdc_drq_w)
{
m_fdc_drq = state;
m_slot->nmi_w((m_fdc_drq && m_fdc_ie) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE8_MEMBER(bbc_opus3_device::page_w)
{
switch (offset)
{
case 0x00: m_ramdisk_page = (m_ramdisk_page & 0x00ff) | (data << 8); break;
case 0x01: m_ramdisk_page = (m_ramdisk_page & 0xff00) | (data << 0); break;
}
}
READ8_MEMBER(bbc_opus3_device::ramdisk_r)
{
if ((m_ramdisk_page << 8) < m_ramdisk->size())
return m_ramdisk->read((m_ramdisk_page << 8) + offset);
else
return 0xff;
}
WRITE8_MEMBER(bbc_opus3_device::ramdisk_w)
{
if ((m_ramdisk_page << 8) < m_ramdisk->size())
m_ramdisk->write((m_ramdisk_page << 8) + offset, data);
}

View File

@ -0,0 +1,66 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
Opus Challenger 3-in-1
**********************************************************************/
#ifndef __BBC_OPUS3__
#define __BBC_OPUS3__
#include "emu.h"
#include "1mhzbus.h"
#include "machine/ram.h"
#include "machine/wd_fdc.h"
#include "formats/acorn_dsk.h"
#include "formats/fsd_dsk.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class bbc_opus3_device:
public device_t,
public device_bbc_1mhzbus_interface
{
public:
// construction/destruction
bbc_opus3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_FLOPPY_FORMATS(floppy_formats);
// optional information overrides
virtual machine_config_constructor device_mconfig_additions() const override;
virtual const tiny_rom_entry *device_rom_region() const override;
DECLARE_WRITE_LINE_MEMBER(fdc_drq_w);
DECLARE_WRITE8_MEMBER(wd1770l_write);
DECLARE_WRITE8_MEMBER(page_w);
DECLARE_READ8_MEMBER(ramdisk_r);
DECLARE_WRITE8_MEMBER(ramdisk_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
required_memory_region m_dfs_rom;
required_device<ram_device> m_ramdisk;
required_device<wd1770_t> m_fdc;
required_device<floppy_connector> m_floppy0;
optional_device<floppy_connector> m_floppy1;
int m_fdc_ie;
int m_fdc_drq;
UINT16 m_ramdisk_page;
};
// device type definition
extern const device_type BBC_OPUS3;
#endif /* __BBC_OPUS3__ */

View File

@ -975,7 +975,9 @@ static MACHINE_CONFIG_DERIVED( bbcb, bbca )
/* expansion ports */
MCFG_BBC_ANALOGUE_SLOT_ADD("analogue", bbc_analogue_devices, "acornjoy")
MCFG_BBC_1MHZBUS_SLOT_ADD("1mhzbus", bbc_1mhzbus_devices, nullptr)
MCFG_BBC_1MHZBUS_SLOT_ADD("1mhzbus", bbcb_1mhzbus_devices, nullptr)
MCFG_BBC_1MHZBUS_SLOT_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_active_high_device, in3_w))
MCFG_BBC_1MHZBUS_SLOT_NMI_HANDLER(WRITELINE(bbc_state, bus_nmi_w))
MCFG_BBC_TUBE_SLOT_ADD("tube", bbc_tube_ext_devices, nullptr)
MCFG_BBC_USERPORT_SLOT_ADD("userport", bbc_userport_devices, nullptr)
@ -1248,6 +1250,12 @@ static MACHINE_CONFIG_DERIVED( reutapm, bbcbp )
MCFG_SOFTWARE_LIST_REMOVE("flop_ls_32016")
MCFG_SOFTWARE_LIST_REMOVE("flop_ls_68000")
MCFG_SOFTWARE_LIST_REMOVE("flop_ls_6502")
/* expansion ports */
MCFG_DEVICE_REMOVE("analogue")
MCFG_DEVICE_REMOVE("1mhzbus")
MCFG_DEVICE_REMOVE("tube")
MCFG_DEVICE_REMOVE("userport")
MACHINE_CONFIG_END
@ -1398,7 +1406,7 @@ static MACHINE_CONFIG_START( bbcm, bbc_state )
/* expansion ports */
MCFG_BBC_ANALOGUE_SLOT_ADD("analogue", bbc_analogue_devices, "acornjoy")
MCFG_BBC_1MHZBUS_SLOT_ADD("1mhzbus", bbc_1mhzbus_devices, nullptr)
MCFG_BBC_1MHZBUS_SLOT_ADD("1mhzbus", bbcm_1mhzbus_devices, nullptr)
MCFG_BBC_TUBE_SLOT_ADD("tube_ext", bbc_tube_ext_devices, nullptr)
MCFG_BBC_TUBE_SLOT_ADD("tube_int", bbc_tube_int_devices, nullptr)
MCFG_BBC_USERPORT_SLOT_ADD("userport", bbc_userport_devices, nullptr)

View File

@ -166,6 +166,7 @@ public:
DECLARE_WRITE_LINE_MEMBER(write_acia_clock);
DECLARE_WRITE_LINE_MEMBER(adlc_irq_w);
DECLARE_WRITE_LINE_MEMBER(econet_clk_w);
DECLARE_WRITE_LINE_MEMBER(bus_nmi_w);
DECLARE_WRITE8_MEMBER(bbcb_via_system_write_porta);
DECLARE_WRITE8_MEMBER(bbcb_via_system_write_portb);
DECLARE_READ8_MEMBER(bbcb_via_system_read_porta);
@ -343,6 +344,7 @@ public: // HACK FOR MC6845
// interrupt state
int m_adlc_irq;
int m_bus_nmi;
int m_column; // this is a counter in the keyboard circuit

View File

@ -1104,7 +1104,10 @@ BBC Joystick Support
UPD7002_GET_ANALOGUE(bbc_state::BBC_get_analogue_input)
{
return ((0xff - m_analog->ch_r(channel_number)) << 8);
if (m_analog)
return ((0xff - m_analog->ch_r(channel_number)) << 8);
else
return 0xff;
}
UPD7002_EOC(bbc_state::BBC_uPD7002_EOC)
@ -1379,6 +1382,19 @@ WRITE_LINE_MEMBER(bbc_state::write_acia_clock)
m_acia->write_rxc(state);
}
/**************************************
1MHz Bus interrupts
***************************************/
WRITE_LINE_MEMBER(bbc_state::bus_nmi_w)
{
m_bus_nmi = state;
bbc_update_nmi();
}
/**************************************
i8271 disc control function
***************************************/
@ -1429,7 +1445,7 @@ WRITE_LINE_MEMBER(bbc_state::side_w)
void bbc_state::bbc_update_nmi()
{
if (m_fdc_irq || m_fdc_drq || m_adlc_irq)
if (m_fdc_irq || m_fdc_drq || m_adlc_irq || m_bus_nmi)
{
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
}