From 2a1ba144a558998240b98a080a0ccf6ce906decf Mon Sep 17 00:00:00 2001 From: holub Date: Tue, 4 Apr 2023 14:34:27 -0400 Subject: bus/spectrum: Added ZXBUS and NeoGS card. (#11032) --- scripts/src/bus.lua | 14 ++ src/devices/bus/spectrum/neogs.cpp | 273 +++++++++++++++++++++++++++++++++++++ src/devices/bus/spectrum/neogs.h | 14 ++ src/devices/bus/spectrum/zxbus.cpp | 79 +++++++++++ src/devices/bus/spectrum/zxbus.h | 127 +++++++++++++++++ src/mame/sinclair/neogs.cpp | 195 -------------------------- src/mame/sinclair/neogs.h | 70 ---------- src/mame/sinclair/tsconf.cpp | 10 +- src/mame/sinclair/tsconf.h | 12 +- 9 files changed, 517 insertions(+), 277 deletions(-) create mode 100644 src/devices/bus/spectrum/neogs.cpp create mode 100644 src/devices/bus/spectrum/neogs.h create mode 100644 src/devices/bus/spectrum/zxbus.cpp create mode 100644 src/devices/bus/spectrum/zxbus.h delete mode 100644 src/mame/sinclair/neogs.cpp delete mode 100644 src/mame/sinclair/neogs.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 5809fd9d07c..f6fb739f524 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4507,6 +4507,20 @@ if (BUSES["SPECTRUM"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/bus/spectrum/zxbus.h,BUSES["ZXBUS"] = true +--------------------------------------------------- + +if (BUSES["ZXBUS"]~=null) then + files { + MAME_DIR .. "src/devices/bus/spectrum/zxbus.cpp", + MAME_DIR .. "src/devices/bus/spectrum/zxbus.h", + MAME_DIR .. "src/devices/bus/spectrum/neogs.cpp", + MAME_DIR .. "src/devices/bus/spectrum/neogs.h", + } +end + --------------------------------------------------- -- --@src/devices/bus/uts_kbd/uts_kbd.h,BUSES["UTS_KBD"] = true diff --git a/src/devices/bus/spectrum/neogs.cpp b/src/devices/bus/spectrum/neogs.cpp new file mode 100644 index 00000000000..319f63f47d6 --- /dev/null +++ b/src/devices/bus/spectrum/neogs.cpp @@ -0,0 +1,273 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/******************************************************************************************* + + Sound card NeoGS appropriate for playing trackers (MOD) and compressed (MP3) music on +Spectrum-compatible computers with ZXBUS slot. + +Hardware: +- Compatible with General Sound (GS); +- Flexible scheme, based on fpga (Altera EP1K30); +- 4Mb RAM, 512Kb flash-ROM; +- Extended techniques of memory addressing: 2 memory windows in visible area, exclude ROM + from visible area; +- Z80 frequency modes (10, 12, 20 and 24 Mhz); +- Support up to 8 sound channels (for MOD); +- SPI mp3-decoder (like VS1011); +- SD-card SPI interface; +- DMA to NeoGS memory (transfer data from ZX to NeoGS by instructions LDI, LDIR and similar); +- Parallel working (NeoGS play music independently from ZX). + +Refs: + http://nedopc.com/gs/ngs_eng.php + https://github.com/psbhlw/gs-firmware + https://8bit.yarek.pl/interface/zx.generalsound/index.html + +TODO: +- SPI +- DMA +- MP3 + +*******************************************************************************************/ + +#include "emu.h" +#include "neogs.h" + +#include "cpu/z80/z80.h" +#include "machine/ram.h" +#include "sound/dac.h" +#include "speaker.h" + + +namespace bus::spectrum::zxbus { + +namespace { + +ROM_START( neogs ) + ROM_REGION(0x80000, "maincpu", 0) + ROM_DEFAULT_BIOS("v1.08") + + ROM_SYSTEM_BIOS(0, "v1.08", "v1.08") + ROMX_LOAD( "neogs108.rom", 0x0000, 0x80000, CRC(8e261323) SHA1(b500b4aa8dea7506d26ad9e50593d9d3bee11ae1), ROM_BIOS(0)) + + ROM_SYSTEM_BIOS(1, "test_muchkin", "Test ROM (Muchkin)") + ROMX_LOAD( "testrom_muchkin.rom", 0x0000, 0x80000, CRC(8ab10a88) SHA1(cff3ca96489e517568146a00412107259360d01e), ROM_BIOS(1)) +ROM_END + +class neogs_device : public device_t, public device_zxbus_card_interface +{ +public: + neogs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, ZXBUS_NEOGS, tag, owner, clock) + , device_zxbus_card_interface(mconfig, *this) + , m_maincpu(*this, "maincpu") + , m_ram(*this, RAM_TAG) + , m_rom(*this, "maincpu") + , m_bank_rom(*this, "bank_rom") + , m_bank_ram(*this, "bank_ram") + , m_view(*this, "view") + , m_dac(*this, "dac%u", 0U) + { } + +protected: + // device_t implementation + void device_start() override; + void device_reset() override; + const tiny_rom_entry *device_rom_region() const override; + void device_add_mconfig(machine_config &config) override; + + void neogsmap(address_map &map); + + INTERRUPT_GEN_MEMBER(irq0_line_assert); + + void map_memory(address_map &map); + void map_io(address_map &map); + void update_config(); + + required_device m_maincpu; + required_device m_ram; + required_region_ptr m_rom; + memory_bank_creator m_bank_rom; + memory_bank_creator m_bank_ram; + memory_view m_view; + required_device_array m_dac; + +private: + template u8 ram_bank_r(offs_t offset); + template void ram_bank_w(offs_t offset, u8 data); + + u8 status_r() { return m_status; } + void command_w(u8 data) { m_status |= 0x01; m_command_in = data; } + u8 data_r() { m_status &= ~0x80; return m_data_out; } + void data_w(u8 data) { m_status |= 0x80; m_data_in = data; } + void ctrl_w(u8 data); + + u8 m_data_in; + u8 m_data_out; + u8 m_command_in; + u8 m_status; + + u8 m_mpag; + u8 m_mpagx; + u8 m_gscfg0; + u8 m_vol[8]; +}; + +void neogs_device::update_config() +{ + if (m_gscfg0 & 4) // EXPAG + ; + + if (m_gscfg0 & 1) // NOROM + { + m_bank_ram->set_entry(m_mpag % (m_ram->size() / 0x8000)); + m_view.select(BIT(m_gscfg0, 1)); // RAMRO + } + else + { + m_bank_rom->set_entry(m_mpag % (m_rom.bytes() / 0x8000)); + m_view.disable(); + } + + const double cpu_scale = (BIT(m_gscfg0, 5) ? 1 : 1.2) * (1 << BIT(~m_gscfg0, 4)); + m_maincpu->set_clock_scale(cpu_scale); +} + +void neogs_device::ctrl_w(u8 data) +{ + if (data & 0x80) + reset(); + if (data & 0x40) + m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); + if (data & 0x20) + ; // LED data:0 - 1-on, 0-off +} + +template u8 neogs_device::ram_bank_r(offs_t offset) +{ + return m_ram->read((0xc000 * Bank) + offset); +} + +template void neogs_device::ram_bank_w(offs_t offset, u8 data) +{ + m_ram->write((0xc000 * Bank) + offset, data); +} + +INTERRUPT_GEN_MEMBER(neogs_device::irq0_line_assert) +{ + m_maincpu->pulse_input_line(INPUT_LINE_IRQ0, attotime::from_ticks(32, m_maincpu->clock())); +} + +void neogs_device::map_memory(address_map &map) +{ + map(0x0000, 0x3fff).rom().region("maincpu", 0x0000); + map(0x4000, 0x7fff).rw(FUNC(neogs_device::ram_bank_r<1>), FUNC(neogs_device::ram_bank_w<1>)); + map(0x8000, 0xffff).bankr(m_bank_rom); + + map(0x0000, 0xffff).view(m_view); + m_view[0](0x0000, 0x3fff).rw(FUNC(neogs_device::ram_bank_r<0>), FUNC(neogs_device::ram_bank_w<0>)); + m_view[0](0x8000, 0xffff).bankrw(m_bank_ram); + m_view[1](0x0000, 0x3fff).r(FUNC(neogs_device::ram_bank_r<0>)); + m_view[1](0x8000, 0xffff).bankrw(m_bank_ram); +} + +void neogs_device::map_io(address_map &map) +{ + map(0x0000, 0x0000).mirror(0xff00).lw8( + NAME([this](offs_t offset, u8 data) { m_mpag = data; update_config(); })); + map(0x0001, 0x0001).mirror(0xff00).lr8( + NAME([this](offs_t offset) { return m_command_in; })); + map(0x0002, 0x0002).mirror(0xff00).lr8( + NAME([this](offs_t offset) { m_status &= ~0x80; return m_data_in; })); + map(0x0003, 0x0003).mirror(0xff00).lw8( + NAME([this](offs_t offset, u8 data) { m_status |= 0x80; m_data_out = data; })); + map(0x0004, 0x0004).mirror(0xff00).lr8( + NAME([this](offs_t offset) { return m_status; })); + map(0x0005, 0x0005).mirror(0xff00).lrw8( + NAME([this](offs_t offset) { m_status &= ~0x01; return ~0; }), + NAME([this](offs_t offset, u8 data) { m_status &= ~0x01; })); + map(0x0006, 0x0009).mirror(0xff00).lw8( + NAME([this](offs_t offset, u8 data) { m_vol[offset] = data & 0x3f; })); + map(0x0016, 0x0019).mirror(0xff00).lw8( + NAME([this](offs_t offset, u8 data) { m_vol[4 + offset] = data & 0x3f; })); + map(0x0010, 0x0010).mirror(0xff00).lw8( + NAME([this](offs_t offset, u8 data) { m_mpagx = data; update_config(); })); + //map(0x000a, 0x000a).mirror(0xff00).noprw(); + //map(0x000b, 0x000b).mirror(0xff00).noprw(); + + map(0x000f, 0x000f).mirror(0xff00).lrw8( + NAME([this](offs_t offset) { return m_gscfg0; }), + NAME([this](offs_t offset, u8 data) { m_gscfg0 = data; update_config(); })); + + map(0x0011, 0x0011).mirror(0xff00).nopw(); + map(0x0013, 0x0013).mirror(0xff00).noprw(); + map(0x0014, 0x0014).mirror(0xff00).nopr(); +} + +void neogs_device::device_add_mconfig(machine_config &config) +{ + RAM(config, m_ram).set_default_size("4M").set_default_value(0xff); + + Z80(config, m_maincpu, 10_MHz_XTAL); + m_maincpu->set_memory_map(&neogs_device::map_memory); + m_maincpu->set_io_map(&neogs_device::map_io); + m_maincpu->set_periodic_int(FUNC(neogs_device::irq0_line_assert), attotime::from_hz(37.5_kHz_XTAL)); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + for (auto i = 0; i < 8; i++) + DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac[i], 0).add_route(ALL_OUTPUTS, (i & 2) ? "rspeaker" : "lspeaker", 0.5); // TDA1543 +} + +const tiny_rom_entry *neogs_device::device_rom_region() const +{ + return ROM_NAME( neogs ); +} + +void neogs_device::neogsmap(address_map &map) +{ + map(0x00bb, 0x00bb).mirror(0xff00).rw(FUNC(neogs_device::status_r), FUNC(neogs_device::command_w)); + map(0x00b3, 0x00b3).mirror(0xff00).rw(FUNC(neogs_device::data_r), FUNC(neogs_device::data_w)); + map(0x0033, 0x0033).mirror(0xff00).w(FUNC(neogs_device::ctrl_w)); +} + +void neogs_device::device_start() +{ + if (!m_ram->started()) + throw device_missing_dependencies(); + + m_bank_rom->configure_entries(0, m_rom.bytes() / 0x8000, &m_rom[0], 0x8000); + m_bank_ram->configure_entries(0, m_ram->size() / 0x8000, m_ram->pointer(), 0x8000); + + m_maincpu->space(AS_PROGRAM).install_read_tap(0x6000, 0x7fff, "dac_w", + [this](offs_t offset, u8 &data, u8 mem_mask) + { + if (!machine().side_effects_disabled()) + { + const u8 chanel = BIT(offset, 8, BIT(m_gscfg0, 2) ? 3 : 2); // 8CHANS + const u8 sample = data ^ (m_gscfg0 & 0x80); // INV7B + const s16 out = (sample - 0x80) * (m_vol[chanel] << 2); + m_dac[chanel]->data_w(out); + if (BIT(m_gscfg0, 2) && BIT(m_gscfg0, 6)) // PAN4CH + ; + } + }); + + m_zxbus->install_device(0x0000, 0xffff, *this, &neogs_device::neogsmap); +} + +void neogs_device::device_reset() +{ + m_status = 0; + m_gscfg0 = 0; + m_mpag = 0; + update_config(); +} + +} // anonymous namespace + +} // namespace bus::spectrum::zxbus + + +DEFINE_DEVICE_TYPE_PRIVATE(ZXBUS_NEOGS, device_zxbus_card_interface, bus::spectrum::zxbus::neogs_device, "neogs", "NeoGS / General Sound") diff --git a/src/devices/bus/spectrum/neogs.h b/src/devices/bus/spectrum/neogs.h new file mode 100644 index 00000000000..79170356690 --- /dev/null +++ b/src/devices/bus/spectrum/neogs.h @@ -0,0 +1,14 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub + +#ifndef MAME_SINCLAIR_NEOGS_H +#define MAME_SINCLAIR_NEOGS_H + +#pragma once + +#include "zxbus.h" + + +DECLARE_DEVICE_TYPE(ZXBUS_NEOGS, device_zxbus_card_interface) + +#endif // MAME_SINCLAIR_NEOGS_H diff --git a/src/devices/bus/spectrum/zxbus.cpp b/src/devices/bus/spectrum/zxbus.cpp new file mode 100644 index 00000000000..d14be5b94c1 --- /dev/null +++ b/src/devices/bus/spectrum/zxbus.cpp @@ -0,0 +1,79 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/******************************************************************************************* + + ZXBUS device + +*******************************************************************************************/ + +#include "emu.h" +#include "zxbus.h" + +DEFINE_DEVICE_TYPE(ZXBUS_SLOT, zxbus_slot_device, "zxbus_slot", "ZXBUS slot") + +zxbus_slot_device::zxbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : zxbus_slot_device(mconfig, ZXBUS_SLOT, tag, owner, clock) +{ +} + +zxbus_slot_device::zxbus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_single_card_slot_interface(mconfig, *this) + , m_zxbus_bus(*this, finder_base::DUMMY_TAG) +{ +} + +void zxbus_slot_device::device_start() +{ + device_zxbus_card_interface *const intf(get_card_device()); + if (intf) intf->set_zxbusbus(*m_zxbus_bus); + + m_zxbus_bus->add_slot(*this); +} + + +DEFINE_DEVICE_TYPE(ZXBUS, zxbus_device, "zxbus", "ZXBUS bus") + +zxbus_device::zxbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : zxbus_device(mconfig, ZXBUS, tag, owner, clock) +{ +} + +zxbus_device::zxbus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , m_iospace(*this, finder_base::DUMMY_TAG, -1) +{ +} + +void zxbus_device::device_start() +{ +} + +void zxbus_device::add_slot(zxbus_slot_device &slot) +{ + m_slot_list.push_front(&slot); +} + +device_zxbus_card_interface::device_zxbus_card_interface(const machine_config &mconfig, device_t &device) + : device_interface(device, "zxbus") + , m_zxbus(nullptr) +{ +} + +device_zxbus_card_interface::~device_zxbus_card_interface() +{ +} + +void device_zxbus_card_interface::interface_pre_start() +{ + if (!m_zxbus) + throw device_missing_dependencies(); +} + + +#include "neogs.h" + +void zxbus_cards(device_slot_interface &device) +{ + device.option_add("neogs", ZXBUS_NEOGS); +} diff --git a/src/devices/bus/spectrum/zxbus.h b/src/devices/bus/spectrum/zxbus.h new file mode 100644 index 00000000000..39714fc80b8 --- /dev/null +++ b/src/devices/bus/spectrum/zxbus.h @@ -0,0 +1,127 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/******************************************************************************************* + + ZXBUS device + + ┌──┬───┬──┐ + │ B│ │ A│ + │ │ │ │ + *5 A15 │ 1│ │ 1│ A14 *4 + *3 A13 │ 2│ │ 2│ A12 *2 + *13 D7 │ 3│ │ 3│ +5V (guaranteed +5V only here ! ) + BLK (CSDS) │ 4│ │ 4│ DOS (DCDOS) + -not-used- │ 5│ │ 5│ KAY = 14Mhz / SCORPION = +12V + *14 D0 │ 6│ │ 6│ GND + *15 D1 │ 7│ │ 7│ GND + *12 D2 │ 8│ │ 8│ CLK Z80 (SCORPION aka /RAS 3.5Mhz ONLY ! ) + *10 D6 │ 9│ │ 9│ A0 *30 + *9 D5 │10│ │10│ A1 *31 + *8 D3 │11│ │11│ A2 + *7 D4 │12│ │12│ A3 + - │13│ │13│ IOGE (IORQCE) + *17 NMI │14│ │14│ GND + - │15│ │15│ RDR(RDROM) (CSROMCE) + *19 MREQ │16│ │16│ RS (BIT_4 OF #7FFD) + *20 IORQ │17│ │17│ -not-used- + *21 RD │18│ │18│ -not-used- + *22 WR │19│ │19│ BUSRQ + -not-used- │20│ │20│ RES *26 + *24 WAIT │21│ │21│ A7 *37 + -not-used- │22│ │22│ A6 *36 + -not-used- │23│ │23│ A5 *35 + *27 M1 │24│ │24│ A4 + RFRSH │25│ │25│ CSR (CSROM) + *38 A8 │26│ │26│ BUSAK + *40 A10 │27│ │27│ A9 *39 + KAY=+5V n.u. │28│ │28│ A11 *1 + KAY=+12V n.u. │29│ │29│ n.u. KAY=+5V + GND │30│ │30│ GND + │ │ │ │ + │ B│ │A │ + └──┴───┴──┘ + '-' - not used + '*' - Z80 CPU out + +*******************************************************************************************/ + +#ifndef MAME_BUS_SPECTRUM_ZXBUS_H +#define MAME_BUS_SPECTRUM_ZXBUS_H + +#pragma once + +class zxbus_device; +class device_zxbus_card_interface; + +class zxbus_slot_device : public device_t, public device_single_card_slot_interface +{ +public: + zxbus_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + template + zxbus_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, T &&zxbus_tag, U &&slot_options, const char *dflt) + : zxbus_slot_device(mconfig, tag, owner, clock) + { + option_reset(); + slot_options(*this); + set_default_option(dflt); + set_fixed(false); + m_zxbus_bus.set_tag(std::forward(zxbus_tag)); + } + +protected: + zxbus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + virtual void device_start() override; + + required_device m_zxbus_bus; +}; + +DECLARE_DEVICE_TYPE(ZXBUS_SLOT, zxbus_slot_device) + + +class zxbus_device : public device_t +{ +public: + zxbus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + template void set_iospace(T &&tag, int spacenum) { m_iospace.set_tag(std::forward(tag), spacenum); } + template void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(class address_map &map), uint64_t unitmask = ~u64(0)) + { + m_iospace->install_device(addrstart, addrend, device, map, unitmask); + } + + void add_slot(zxbus_slot_device &slot); + +protected: + zxbus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + virtual void device_start() override; + + required_address_space m_iospace; + std::forward_list m_slot_list; +}; + +DECLARE_DEVICE_TYPE(ZXBUS, zxbus_device) + + +class device_zxbus_card_interface : public device_interface +{ +public: + virtual ~device_zxbus_card_interface(); + + void set_zxbusbus(zxbus_device &bus) { assert(!device().started()); m_zxbus = &bus; } + +protected: + device_zxbus_card_interface(const machine_config &mconfig, device_t &device); + + virtual void interface_pre_start() override; + + zxbus_device *m_zxbus; +}; + + +void zxbus_cards(device_slot_interface &device); + + +#endif // MAME_BUS_SPECTRUM_ZXBUS_H diff --git a/src/mame/sinclair/neogs.cpp b/src/mame/sinclair/neogs.cpp deleted file mode 100644 index 290e9e67ecb..00000000000 --- a/src/mame/sinclair/neogs.cpp +++ /dev/null @@ -1,195 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Andrei I. Holub -/******************************************************************************************* - - Sound card NeoGS appropriate for playing trackers (MOD) and compressed (MP3) music on -Spectrum-compatible computers with ZXBUS slot. - -Hardware: -- Compatible with General Sound (GS); -- Flexible scheme, based on fpga (Altera EP1K30); -- 4Mb RAM, 512Kb flash-ROM; -- Extended techniques of memory addressing: 2 memory windows in visible area, exclude ROM - from visible area; -- Z80 frequency modes (10, 12, 20 and 24 Mhz); -- Support up to 8 sound channels (for MOD); -- SPI mp3-decoder (like VS1011); -- SD-card SPI interface; -- DMA to NeoGS memory (transfer data from ZX to NeoGS by instructions LDI, LDIR and similar); -- Parallel working (NeoGS play music independently from ZX). - -Refs: - http://nedopc.com/gs/ngs_eng.php - https://github.com/psbhlw/gs-firmware - https://8bit.yarek.pl/interface/zx.generalsound/index.html - -TODO: -- ZXBUS -- SPI -- DMA -- MP3 - -*******************************************************************************************/ - -#include "emu.h" -#include "neogs.h" - -#include "speaker.h" - - -DEFINE_DEVICE_TYPE(NEOGS, neogs_device, "neogs", "NeoGS / General Sound") - -ROM_START( neogs ) - ROM_REGION(0x80000, "maincpu", 0) - ROM_DEFAULT_BIOS("v1.08") - - ROM_SYSTEM_BIOS(0, "v1.08", "v1.08") - ROMX_LOAD( "neogs108.rom", 0x0000, 0x80000, CRC(8e261323) SHA1(b500b4aa8dea7506d26ad9e50593d9d3bee11ae1), ROM_BIOS(0)) - - ROM_SYSTEM_BIOS(1, "test_muchkin", "Test ROM (Muchkin)") - ROMX_LOAD( "testrom_muchkin.rom", 0x0000, 0x80000, CRC(8ab10a88) SHA1(cff3ca96489e517568146a00412107259360d01e), ROM_BIOS(1)) -ROM_END - - -void neogs_device::update_config() -{ - if (m_gscfg0 & 4) // EXPAG - ; - - if (m_gscfg0 & 1) // NOROM - { - m_bank_ram->set_entry(m_mpag % (m_ram->size() / 0x8000)); - m_view.select(BIT(m_gscfg0, 1)); // RAMRO - } - else - { - m_bank_rom->set_entry(m_mpag % (memregion("maincpu")->bytes() / 0x8000)); - m_view.disable(); - } - - const double cpu_scale = (BIT(m_gscfg0, 5) ? 1 : 1.2) * (1 << BIT(~m_gscfg0, 4)); - m_maincpu->set_clock_scale(cpu_scale); -} - -void neogs_device::ctrl_w(u8 data) -{ - if (data & 0x80) - reset(); - if (data & 0x40) - m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); - if (data & 0x20) - ; // LED data:0 - 1-on, 0-off -} - -template u8 neogs_device::ram_bank_r(offs_t offset) -{ - return m_ram->read((0xc000 * Bank) + offset); -} - -template void neogs_device::ram_bank_w(offs_t offset, u8 data) -{ - m_ram->write((0xc000 * Bank) + offset, data); -} - -INTERRUPT_GEN_MEMBER(neogs_device::irq0_line_assert) -{ - m_maincpu->pulse_input_line(INPUT_LINE_IRQ0, attotime::from_ticks(32, m_maincpu->clock())); -} - -void neogs_device::map_memory(address_map &map) -{ - map(0x0000, 0x3fff).rom().region("maincpu", 0x0000); - map(0x4000, 0x7fff).rw(FUNC(neogs_device::ram_bank_r<1>), FUNC(neogs_device::ram_bank_w<1>)); - map(0x8000, 0xffff).bankr(m_bank_rom); - - map(0x0000, 0xffff).view(m_view); - m_view[0](0x0000, 0x3fff).rw(FUNC(neogs_device::ram_bank_r<0>), FUNC(neogs_device::ram_bank_w<0>)); - m_view[0](0x8000, 0xffff).bankrw(m_bank_ram); - m_view[1](0x0000, 0x3fff).r(FUNC(neogs_device::ram_bank_r<0>)); - m_view[1](0x8000, 0xffff).bankrw(m_bank_ram); -} - -void neogs_device::map_io(address_map &map) -{ - map(0x0000, 0x0000).mirror(0xff00).lw8( - NAME([this](offs_t offset, u8 data) { m_mpag = data; update_config(); })); - map(0x0001, 0x0001).mirror(0xff00).lr8( - NAME([this](offs_t offset) { return m_command_in; })); - map(0x0002, 0x0002).mirror(0xff00).lr8( - NAME([this](offs_t offset) { m_status &= ~0x80; return m_data_in; })); - map(0x0003, 0x0003).mirror(0xff00).lw8( - NAME([this](offs_t offset, u8 data) { m_status |= 0x80; m_data_out = data; })); - map(0x0004, 0x0004).mirror(0xff00).lr8( - NAME([this](offs_t offset) { return m_status; })); - map(0x0005, 0x0005).mirror(0xff00).lrw8( - NAME([this](offs_t offset) { m_status &= ~0x01; return ~0; }), - NAME([this](offs_t offset, u8 data) { m_status &= ~0x01; })); - map(0x0006, 0x0009).mirror(0xff00).lw8( - NAME([this](offs_t offset, u8 data) { m_vol[offset] = data & 0x3f; })); - map(0x0016, 0x0019).mirror(0xff00).lw8( - NAME([this](offs_t offset, u8 data) { m_vol[4 + offset] = data & 0x3f; })); - map(0x0010, 0x0010).mirror(0xff00).lw8( - NAME([this](offs_t offset, u8 data) { m_mpagx = data; update_config(); })); - //map(0x000a, 0x000a).mirror(0xff00).noprw(); - //map(0x000b, 0x000b).mirror(0xff00).noprw(); - - map(0x000f, 0x000f).mirror(0xff00).lrw8( - NAME([this](offs_t offset) { return m_gscfg0; }), - NAME([this](offs_t offset, u8 data) { m_gscfg0 = data; update_config(); })); - - map(0x0011, 0x0011).mirror(0xff00).nopw(); - map(0x0013, 0x0013).mirror(0xff00).noprw(); - map(0x0014, 0x0014).mirror(0xff00).nopr(); -} - -void neogs_device::device_add_mconfig(machine_config &config) -{ - RAM(config, m_ram).set_default_size("4M").set_default_value(0xff); - - Z80(config, m_maincpu, 10_MHz_XTAL); - m_maincpu->set_memory_map(&neogs_device::map_memory); - m_maincpu->set_io_map(&neogs_device::map_io); - m_maincpu->set_periodic_int(FUNC(neogs_device::irq0_line_assert), attotime::from_hz(37.5_kHz_XTAL)); - - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - - for (auto i = 0; i < 8; i++) - DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac[i], 0).add_route(ALL_OUTPUTS, (i & 2) ? "rspeaker" : "lspeaker", 0.5); // TDA1543 -} - -const tiny_rom_entry *neogs_device::device_rom_region() const -{ - return ROM_NAME( neogs ); -} - -void neogs_device::device_start() -{ - if (!m_ram->started()) - throw device_missing_dependencies(); - - memory_region *rom = memregion("maincpu"); - m_bank_rom->configure_entries(0, rom->bytes() / 0x8000, rom->base(), 0x8000); - m_bank_ram->configure_entries(0, m_ram->size() / 0x8000, m_ram->pointer(), 0x8000); - - m_maincpu->space(AS_PROGRAM).install_read_tap(0x6000, 0x7fff, "dac_w", [this](offs_t offset, u8 &data, u8 mem_mask) - { - if (!machine().side_effects_disabled()) - { - const u8 chanel = BIT(offset, 8, BIT(m_gscfg0, 2) ? 3 : 2); // 8CHANS - const u8 sample = data ^ (m_gscfg0 & 0x80); // INV7B - const s16 out = (sample - 0x80) * (m_vol[chanel] << 2); - m_dac[chanel]->data_w(out); - if (BIT(m_gscfg0, 2) && BIT(m_gscfg0, 6)) // PAN4CH - ; - } - }); -} - -void neogs_device::device_reset() -{ - m_status = 0; - m_gscfg0 = 0; - m_mpag = 0; - update_config(); -} diff --git a/src/mame/sinclair/neogs.h b/src/mame/sinclair/neogs.h deleted file mode 100644 index 8b978c20bf4..00000000000 --- a/src/mame/sinclair/neogs.h +++ /dev/null @@ -1,70 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Andrei I. Holub - -#ifndef MAME_SINCLAIR_NEOGS_H -#define MAME_SINCLAIR_NEOGS_H - -#pragma once - -#include "cpu/z80/z80.h" -#include "machine/ram.h" -#include "sound/dac.h" - -DECLARE_DEVICE_TYPE(NEOGS, neogs_device) - -class neogs_device : public device_t -{ -public: - neogs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0) - : device_t(mconfig, NEOGS, tag, owner, clock) - , m_maincpu(*this, "maincpu") - , m_ram(*this, RAM_TAG) - , m_bank_rom(*this, "bank_rom") - , m_bank_ram(*this, "bank_ram") - , m_view(*this, "view") - , m_dac(*this, "dac%u", 0U) - { } - - u8 status_r() { return m_status; }; - void command_w(u8 data) { m_status |= 0x01; m_command_in = data; }; - u8 data_r() { m_status &= ~0x80; return m_data_out; }; - void data_w(u8 data) { m_status |= 0x80; m_data_in = data; }; - void ctrl_w(u8 data); - -protected: - // device-level overrides - void device_start() override; - void device_reset() override; - const tiny_rom_entry *device_rom_region() const override; - - void device_add_mconfig(machine_config &config) override; - - INTERRUPT_GEN_MEMBER(irq0_line_assert); - - void map_memory(address_map &map); - void map_io(address_map &map); - void update_config(); - - required_device m_maincpu; - required_device m_ram; - memory_bank_creator m_bank_rom; - memory_bank_creator m_bank_ram; - memory_view m_view; - required_device_array m_dac; - -private: - template u8 ram_bank_r(offs_t offset); - template void ram_bank_w(offs_t offset, u8 data); - - u8 m_data_in; - u8 m_data_out; - u8 m_command_in; - u8 m_status; - - u8 m_mpag; - u8 m_mpagx; - u8 m_gscfg0; - u8 m_vol[8]; -}; - -#endif // MAME_SINCLAIR_NEOGS_H diff --git a/src/mame/sinclair/tsconf.cpp b/src/mame/sinclair/tsconf.cpp index 596bb57a0bc..bf146cee28f 100644 --- a/src/mame/sinclair/tsconf.cpp +++ b/src/mame/sinclair/tsconf.cpp @@ -108,9 +108,6 @@ void tsconf_state::tsconf_io(address_map &map) map(0xffdf, 0xffdf).lr8(NAME([this]() { return ~m_io_mouse[1]->read(); })); map(0x8000, 0x8000).mirror(0x3ffd).w("ay8912", FUNC(ay8910_device::data_w)); map(0xc000, 0xc000).mirror(0x3ffd).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)); - map(0x00bb, 0x00bb).mirror(0xff00).rw(m_gs, FUNC(neogs_device::status_r), FUNC(neogs_device::command_w)); - map(0x00b3, 0x00b3).mirror(0xff00).rw(m_gs, FUNC(neogs_device::data_r), FUNC(neogs_device::data_w)); - map(0x0033, 0x0033).mirror(0xff00).w(m_gs, FUNC(neogs_device::ctrl_w)); } void tsconf_state::tsconf_switch(address_map &map) @@ -277,6 +274,11 @@ void tsconf_state::tsconf(machine_config &config) m_maincpu->set_vblank_int("screen", FUNC(tsconf_state::tsconf_vblank_interrupt)); + zxbus_device &zxbus(ZXBUS(config, "zxbus", 0)); + zxbus.set_iospace("maincpu", AS_IO); + ZXBUS_SLOT(config, "zxbus1", 0, "zxbus", zxbus_cards, "neogs"); + //ZXBUS_SLOT(config, "zxbus2", 0, "zxbus", zxbus_cards, nullptr); + m_ram->set_default_size("4096K"); GLUKRS(config, m_glukrs); @@ -302,8 +304,6 @@ void tsconf_state::tsconf(machine_config &config) .add_route(1, "rspeaker", 0.25) .add_route(2, "rspeaker", 0.50); - NEOGS(config, m_gs); - PALETTE(config, "palette", FUNC(tsconf_state::tsconf_palette), 256); m_screen->set_raw(14_MHz_XTAL / 2, 448, with_hblank(0), 448, 320, with_vblank(0), 320); subdevice("gfxdecode")->set_info(gfx_tsconf); diff --git a/src/mame/sinclair/tsconf.h b/src/mame/sinclair/tsconf.h index 338e082dd22..019a7b5de24 100644 --- a/src/mame/sinclair/tsconf.h +++ b/src/mame/sinclair/tsconf.h @@ -12,13 +12,13 @@ #include "spec128.h" -#include "beta_m.h" - #include "glukrs.h" +#include "tsconfdma.h" + +#include "beta_m.h" +#include "bus/spectrum/zxbus.h" #include "machine/pckeybrd.h" #include "machine/spi_sdcard.h" -#include "neogs.h" -#include "tsconfdma.h" #include "tilemap.h" @@ -38,8 +38,7 @@ public: m_palette(*this, "palette"), m_gfxdecode(*this, "gfxdecode"), m_cram(*this, "cram"), - m_sfile(*this, "sfile"), - m_gs(*this, "gs") + m_sfile(*this, "sfile") { } @@ -215,7 +214,6 @@ private: tilemap_t *m_ts_tilemap[3]{}; required_device m_cram; required_device m_sfile; - required_device m_gs; }; /*----------- defined in drivers/tsconf.c -----------*/ -- cgit v1.2.3