diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 714a1e9f482..7af654fd1cf 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3315,6 +3315,8 @@ if (BUSES["SPECTRUM"]~=null) then MAME_DIR .. "src/devices/bus/spectrum/mface.h", MAME_DIR .. "src/devices/bus/spectrum/mikroplus.cpp", MAME_DIR .. "src/devices/bus/spectrum/mikroplus.h", + MAME_DIR .. "src/devices/bus/spectrum/opus.cpp", + MAME_DIR .. "src/devices/bus/spectrum/opus.h", MAME_DIR .. "src/devices/bus/spectrum/plus2test.cpp", MAME_DIR .. "src/devices/bus/spectrum/plus2test.h", MAME_DIR .. "src/devices/bus/spectrum/protek.cpp", diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua index 071982e83fe..9e7a2a1eb5a 100644 --- a/scripts/src/formats.lua +++ b/scripts/src/formats.lua @@ -1229,6 +1229,18 @@ if (FORMATS["NFD_DSK"]~=null or _OPTIONS["with-tools"]) then } end +-------------------------------------------------- +-- +--@src/lib/formats/opd_dsk.h,FORMATS["OPD_DSK"] = true +-------------------------------------------------- + +if (FORMATS["OPD_DSK"]~=null or _OPTIONS["with-tools"]) then + files { + MAME_DIR.. "src/lib/formats/opd_dsk.cpp", + MAME_DIR.. "src/lib/formats/opd_dsk.h", + } +end + -------------------------------------------------- -- --@src/lib/formats/orao_cas.h,FORMATS["ORAO_CAS"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index d83b6a7ef43..41cd20512fa 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -943,6 +943,7 @@ FORMATS["NASCOM_DSK"] = true FORMATS["NASLITE_DSK"] = true FORMATS["NES_DSK"] = true FORMATS["NFD_DSK"] = true +FORMATS["OPD_DSK"] = true FORMATS["ORAO_CAS"] = true FORMATS["ORIC_DSK"] = true FORMATS["ORIC_TAP"] = true diff --git a/src/devices/bus/spectrum/exp.cpp b/src/devices/bus/spectrum/exp.cpp index b93be6c7162..850b9f88384 100644 --- a/src/devices/bus/spectrum/exp.cpp +++ b/src/devices/bus/spectrum/exp.cpp @@ -167,7 +167,7 @@ void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data) #include "melodik.h" #include "mface.h" #include "mikroplus.h" -//#include "opus.h" +#include "opus.h" #include "plus2test.h" //#include "plusd.h" #include "protek.h" @@ -190,7 +190,7 @@ void spectrum_expansion_devices(device_slot_interface &device) device.option_add("mface128", SPECTRUM_MFACE128); device.option_add("mikroplus", SPECTRUM_MIKROPLUS); device.option_add("mprint", SPECTRUM_MPRINT); - //device.option_add("opus", SPECTRUM_OPUS); + device.option_add("opus", SPECTRUM_OPUS); //device.option_add("plusd", SPECTRUM_PLUSD); device.option_add("protek", SPECTRUM_PROTEK); device.option_add("specdrum", SPECTRUM_SPECDRUM); @@ -209,6 +209,7 @@ void spec128_expansion_devices(device_slot_interface &device) device.option_add("mface128", SPECTRUM_MFACE128); device.option_add("mikroplus", SPECTRUM_MIKROPLUS); device.option_add("mprint", SPECTRUM_MPRINT); + device.option_add("opus", SPECTRUM_OPUS); device.option_add("plus2test", SPECTRUM_PLUS2TEST); device.option_add("protek", SPECTRUM_PROTEK); device.option_add("specdrum", SPECTRUM_SPECDRUM); diff --git a/src/devices/bus/spectrum/opus.cpp b/src/devices/bus/spectrum/opus.cpp new file mode 100644 index 00000000000..9c896b847c8 --- /dev/null +++ b/src/devices/bus/spectrum/opus.cpp @@ -0,0 +1,289 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Opus Discovery disc system + +**********************************************************************/ + + +#include "emu.h" +#include "opus.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(SPECTRUM_OPUS, spectrum_opus_device, "spectrum_opus", "Opus Discovery") + + +//------------------------------------------------- +// INPUT_PORTS( opus ) +//------------------------------------------------- + +static INPUT_PORTS_START( opus ) + PORT_START("JOY") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_8WAY + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT) PORT_8WAY + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) PORT_8WAY + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_8WAY + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON1) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor spectrum_opus_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( opus ); +} + +//------------------------------------------------- +// MACHINE_DRIVER( opus ) +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER( spectrum_opus_device::floppy_formats ) + FLOPPY_OPD_FORMAT +FLOPPY_FORMATS_END + +static void spectrum_floppies(device_slot_interface &device) +{ + device.option_add("35ssdd", FLOPPY_35_SSDD); + device.option_add("35dd", FLOPPY_35_DD); +} + +ROM_START(opus) + ROM_REGION(0x2000, "rom", 0) + ROM_DEFAULT_BIOS("opus22") + ROM_SYSTEM_BIOS(0, "opus22", "Opus v2.2") + ROMX_LOAD("opus-22.rom", 0x0000, 0x2000, CRC(50f0eae0) SHA1(0eee1c503f71709fce8b7560dadc2d07d15edb80), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "opus21", "Opus v2.1") + ROMX_LOAD("opus-21.rom", 0x0000, 0x2000, CRC(619973f9) SHA1(31999a68901392bba907cf5a15e264b6759f1a29), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(2, "opus222", "Opus v2.22") + ROMX_LOAD("opus-222.rom", 0x0000, 0x2000, CRC(08ce9949) SHA1(71f1c8a8b923f7751d1ff48d30b8e18a15b92591), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(3, "quickdos", "QuickDOS v2.31") // MegaSoft + ROMX_LOAD("quickdos-231.rom", 0x0000, 0x2000, CRC(d042b32a) SHA1(2975f7eb61d44e898cdd6e3196893e95637f17ff), ROM_BIOS(3)) + ROM_SYSTEM_BIOS(4, "excom", "EXCOM v2.28") // Paul Cheffings + ROMX_LOAD("excom-228.rom", 0x0000, 0x2000, CRC(29257418) SHA1(098a812c4707251f647553a2abc1436afa38f43c), ROM_BIOS(4)) +ROM_END + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void spectrum_opus_device::device_add_mconfig(machine_config &config) +{ + WD1770(config, m_fdc, 16_MHz_XTAL / 2); + m_fdc->drq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w)); + + FLOPPY_CONNECTOR(config, "fdc:0", spectrum_floppies, "35dd", spectrum_opus_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", spectrum_floppies, "35dd", spectrum_opus_device::floppy_formats).enable_sound(true); + + /* parallel printer port */ + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->ack_handler().set(m_pia, FUNC(pia6821_device::ca2_w)); + m_centronics->busy_handler().set(FUNC(spectrum_opus_device::busy_w)); + + /* pia */ + PIA6821(config, m_pia, 0); + m_pia->writepa_handler().set(FUNC(spectrum_opus_device::pia_out_a)); + m_pia->writepb_handler().set(FUNC(spectrum_opus_device::pia_out_b)); + m_pia->cb2_handler().set("centronics", FUNC(centronics_device::write_strobe)); + + /* software list */ + SOFTWARE_LIST(config, "flop_list").set_original("spectrum_flop_opus"); + + /* passthru without NMI */ + SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr); + m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w)); +} + +const tiny_rom_entry *spectrum_opus_device::device_rom_region() const +{ + return ROM_NAME( opus ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// spectrum_opus_device - constructor +//------------------------------------------------- + +spectrum_opus_device::spectrum_opus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SPECTRUM_OPUS, tag, owner, clock) + , device_spectrum_expansion_interface(mconfig, *this) + , m_joy(*this, "JOY") + , m_rom(*this, "rom") + , m_pia(*this, "pia") + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_centronics(*this, "centronics") + , m_exp(*this, "exp") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void spectrum_opus_device::device_start() +{ + memset(m_ram, 0, sizeof(m_ram)); + + save_item(NAME(m_romcs)); + save_item(NAME(m_ram)); + save_item(NAME(m_last_pc)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void spectrum_opus_device::device_reset() +{ + m_romcs = 0; + m_last_pc = 0x0000; +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ_LINE_MEMBER(spectrum_opus_device::romcs) +{ + return m_romcs | m_exp->romcs(); +} + +void spectrum_opus_device::opcode_fetch(offs_t offset) +{ + m_exp->opcode_fetch(offset); + + if (!machine().side_effects_disabled()) + { + switch (m_last_pc) + { + case 0x0008: case 0x0048: case 0x1708: + m_romcs = 1; + break; + case 0x1748: + m_romcs = 0; + break; + } + } + m_last_pc = offset; +} + +uint8_t spectrum_opus_device::iorq_r(offs_t offset) +{ + uint8_t data = m_exp->iorq_r(offset); + + // PIA bit 7 is enable joystick and selected on A5 only + if (!BIT(m_pia->a_output(), 7) && (~offset & 0x20)) + { + data &= m_joy->read() & 0x1f; + } + return data; +} + +void spectrum_opus_device::iorq_w(offs_t offset, uint8_t data) +{ + m_exp->iorq_w(offset, data); +} + +uint8_t spectrum_opus_device::mreq_r(offs_t offset) +{ + uint8_t data = 0xff; + + if (m_romcs) + { + switch (offset & 0xf800) + { + case 0x0000: case 0x0800: case 0x1000: case 0x1800: + data = m_rom->base()[offset & 0x1fff]; + break; + case 0x2000: + data = m_ram[offset & 0x7ff]; + break; + case 0x2800: + data = m_fdc->read(offset & 0x03); + break; + case 0x3000: + data = m_pia->read(offset & 0x03); + break; + case 0x3800: // Extra 2K described in QuickDOS manual - not used + data = m_ram[offset & 0xfff]; + break; + } + } + + if (m_exp->romcs()) + data &= m_exp->mreq_r(offset); + + return data; +} + +void spectrum_opus_device::mreq_w(offs_t offset, uint8_t data) +{ + if (m_romcs) + { + switch (offset & 0xf800) + { + case 0x2000: + m_ram[offset & 0x7ff] = data; + break; + case 0x2800: + m_fdc->write(offset & 0x03, data); + break; + case 0x3000: + m_pia->write(offset & 0x03, data); + break; + case 0x3800: // Extra 2K described in QuickDOS manual - not used + m_ram[offset & 0xfff] = data; + break; + } + } + + if (m_exp->romcs()) + m_exp->mreq_w(offset, data); +} + +WRITE8_MEMBER(spectrum_opus_device::pia_out_a) +{ + floppy_image_device *floppy = nullptr; + + // bit 0, 1: drive select + if (!BIT(data, 0)) floppy = m_floppy1->get_device(); + if (!BIT(data, 1)) floppy = m_floppy0->get_device(); + m_fdc->set_floppy(floppy); + + // bit 4: side select + if (floppy) + floppy->ss_w(BIT(data, 4)); + + // bit 5: density + m_fdc->dden_w(BIT(data, 5)); +} + +WRITE8_MEMBER(spectrum_opus_device::pia_out_b) +{ + m_centronics->write_data1(BIT(data, 1)); + m_centronics->write_data2(BIT(data, 2)); + m_centronics->write_data3(BIT(data, 3)); + m_centronics->write_data4(BIT(data, 4)); + m_centronics->write_data5(BIT(data, 5)); + m_centronics->write_data6(BIT(data, 6)); + m_centronics->write_data7(BIT(data, 7)); +} + +WRITE_LINE_MEMBER(spectrum_opus_device::busy_w) +{ + m_pia->set_a_input(state << 6, 0xbf); +} \ No newline at end of file diff --git a/src/devices/bus/spectrum/opus.h b/src/devices/bus/spectrum/opus.h new file mode 100644 index 00000000000..8d72d8be94b --- /dev/null +++ b/src/devices/bus/spectrum/opus.h @@ -0,0 +1,75 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Opus Discovery disc system + +**********************************************************************/ + +#ifndef MAME_BUS_SPECTRUM_OPUS_H +#define MAME_BUS_SPECTRUM_OPUS_H + +#include "exp.h" +#include "softlist.h" +#include "imagedev/floppy.h" +#include "machine/wd_fdc.h" +#include "machine/6821pia.h" +#include "bus/centronics/ctronics.h" +#include "formats/opd_dsk.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class spectrum_opus_device: + public device_t, + public device_spectrum_expansion_interface + +{ +public: + // construction/destruction + spectrum_opus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_FLOPPY_FORMATS(floppy_formats); + +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 ioport_constructor device_input_ports() const override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual void opcode_fetch(offs_t offset) override; + virtual uint8_t mreq_r(offs_t offset) override; + virtual void mreq_w(offs_t offset, uint8_t data) override; + virtual uint8_t iorq_r(offs_t offset) override; + virtual void iorq_w(offs_t offset, uint8_t data) override; + virtual DECLARE_READ_LINE_MEMBER(romcs) override; + +private: + DECLARE_WRITE8_MEMBER(pia_out_a); + DECLARE_WRITE8_MEMBER(pia_out_b); + DECLARE_WRITE_LINE_MEMBER(busy_w); + + required_ioport m_joy; + required_memory_region m_rom; + required_device m_pia; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + required_device m_centronics; + required_device m_exp; + + int m_romcs; + uint8_t m_ram[4 * 1024]; + offs_t m_last_pc; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(SPECTRUM_OPUS, spectrum_opus_device) + +#endif // MAME_BUS_SPECTRUM_OPUS_H diff --git a/src/lib/formats/opd_dsk.cpp b/src/lib/formats/opd_dsk.cpp new file mode 100644 index 00000000000..b45b58762ed --- /dev/null +++ b/src/lib/formats/opd_dsk.cpp @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Sinclair ZX Spectrum + + Opus Discovery disk image formats + +***************************************************************************/ + +#include "opd_dsk.h" + + +opd_format::opd_format() : wd177x_format(formats) +{ +} + +const char *opd_format::name() const +{ + return "opd"; +} + +const char *opd_format::description() const +{ + return "Opus Discovery disk image"; +} + +const char *opd_format::extensions() const +{ + return "opd,opu"; +} + +int opd_format::identify(io_generic *io, uint32_t form_factor) +{ + int type = find_size(io, form_factor); + + if (type != -1) + return 90; + return 0; +} + +int opd_format::get_image_offset(const format &f, int head, int track) +{ + return (f.track_count * head + track) * compute_track_size(f); +} + +const opd_format::format opd_format::formats[] = +{ + { // 180k 40 track single sided double density - gaps unverified + floppy_image::FF_35, floppy_image::SSSD, floppy_image::MFM, + 2000, 18, 40, 1, 256, {}, 0, {}, 36, 22, 27 + }, + { // 360k 40 track double sided double density - gaps unverified + floppy_image::FF_35, floppy_image::DSSD, floppy_image::MFM, + 2000, 18, 40, 2, 256, {}, 0, {}, 36, 22, 27 + }, + {} +}; + + +const floppy_format_type FLOPPY_OPD_FORMAT = &floppy_image_format_creator; diff --git a/src/lib/formats/opd_dsk.h b/src/lib/formats/opd_dsk.h new file mode 100644 index 00000000000..3eb018ca1dc --- /dev/null +++ b/src/lib/formats/opd_dsk.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Sinclair ZX Spectrum + + Opus Discovery disk image formats + +***************************************************************************/ + +#pragma once + +#ifndef OPD_DSK_H +#define OPD_DSK_H + +#include "flopimg.h" +#include "wd177x_dsk.h" + + +class opd_format : public wd177x_format +{ +public: + opd_format(); + + virtual int identify(io_generic *io, uint32_t form_factor) override; + virtual int get_image_offset(const format &f, int head, int track) override; + virtual const char *name() const override; + virtual const char *description() const override; + virtual const char *extensions() const override; + +private: + static const format formats[]; +}; + + +extern const floppy_format_type FLOPPY_OPD_FORMAT; + +#endif // OPD_DSK_H diff --git a/src/mame/drivers/spectrum.cpp b/src/mame/drivers/spectrum.cpp index bbb41ad9c56..087111b013b 100644 --- a/src/mame/drivers/spectrum.cpp +++ b/src/mame/drivers/spectrum.cpp @@ -443,8 +443,8 @@ void spectrum_state::spectrum_mem(address_map &map) { map(0x0000, 0x3fff).rw(FUNC(spectrum_state::spectrum_rom_r), FUNC(spectrum_state::spectrum_rom_w)); map(0x4000, 0x5aff).ram().share("video_ram"); - // AM_RANGE(0x5b00, 0x7fff) AM_RAM - // AM_RANGE(0x8000, 0xffff) AM_RAM + //map(0x5b00, 0x7fff).ram(); + //map(0x8000, 0xffff).ram(); } void spectrum_state::spectrum_fetch(address_map &map)