diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index feacff29ab2..26b4ef1caf7 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -40,6 +40,10 @@ if (BUSES["A800"]~=null) then files { MAME_DIR .. "src/devices/bus/a800/a8sio.cpp", MAME_DIR .. "src/devices/bus/a800/a8sio.h", + MAME_DIR .. "src/devices/bus/a800/atari810.cpp", + MAME_DIR .. "src/devices/bus/a800/atari810.h", + MAME_DIR .. "src/devices/bus/a800/atari1050.cpp", + MAME_DIR .. "src/devices/bus/a800/atari1050.h", MAME_DIR .. "src/devices/bus/a800/cassette.cpp", MAME_DIR .. "src/devices/bus/a800/cassette.h", MAME_DIR .. "src/devices/bus/a800/a800_slot.cpp", diff --git a/src/devices/bus/a800/a8sio.cpp b/src/devices/bus/a800/a8sio.cpp index c8c7d788e48..1244662d673 100644 --- a/src/devices/bus/a800/a8sio.cpp +++ b/src/devices/bus/a800/a8sio.cpp @@ -32,6 +32,8 @@ #include "emu.h" #include "a8sio.h" +#include "atari810.h" +#include "atari1050.h" #include "cassette.h" @@ -99,7 +101,10 @@ a8sio_device::a8sio_device(const machine_config &mconfig, device_type type, cons : device_t(mconfig, type, tag, owner, clock) , m_out_clock_in_cb(*this) , m_out_data_in_cb(*this) - , m_out_audio_in_cb(*this), m_device(nullptr) + , m_out_proceed_cb(*this) + , m_out_audio_in_cb(*this) + , m_out_interrupt_cb(*this) + , m_device(nullptr) { } @@ -112,7 +117,9 @@ void a8sio_device::device_start() // resolve callbacks m_out_clock_in_cb.resolve_safe(); m_out_data_in_cb.resolve_safe(); + m_out_proceed_cb.resolve_safe(); m_out_audio_in_cb.resolve_safe(); + m_out_interrupt_cb.resolve_safe(); // clear slot m_device = nullptr; @@ -141,17 +148,38 @@ WRITE_LINE_MEMBER( a8sio_device::clock_in_w ) m_out_clock_in_cb(state); } +WRITE_LINE_MEMBER( a8sio_device::clock_out_w ) +{ + if (m_device) + m_device->clock_out_w(state); +} + WRITE_LINE_MEMBER( a8sio_device::data_in_w ) { m_out_data_in_cb(state); } +WRITE_LINE_MEMBER( a8sio_device::data_out_w ) +{ + if (m_device) + m_device->data_out_w(state); +} + +WRITE_LINE_MEMBER( a8sio_device::command_w ) +{ + if (m_device) + m_device->command_w(state); +} + WRITE_LINE_MEMBER( a8sio_device::motor_w ) { if (m_device) - { m_device->motor_w(state); - } +} + +WRITE_LINE_MEMBER( a8sio_device::proceed_w ) +{ + m_out_proceed_cb(state); } WRITE8_MEMBER( a8sio_device::audio_in_w ) @@ -159,6 +187,11 @@ WRITE8_MEMBER( a8sio_device::audio_in_w ) m_out_audio_in_cb(data); } +WRITE_LINE_MEMBER( a8sio_device::interrupt_w ) +{ + m_out_interrupt_cb(state); +} + //************************************************************************** // DEVICE A8SIO CARD INTERFACE @@ -190,13 +223,31 @@ void device_a8sio_card_interface::set_a8sio_device() m_a8sio->add_a8sio_card(this); } +WRITE_LINE_MEMBER( device_a8sio_card_interface::clock_out_w ) +{ +} + +WRITE_LINE_MEMBER( device_a8sio_card_interface::data_out_w ) +{ +} + +WRITE_LINE_MEMBER( device_a8sio_card_interface::command_w ) +{ +} + WRITE_LINE_MEMBER( device_a8sio_card_interface::motor_w ) { //printf("device_a8sio_card_interface::motor_w %d\n", state); } +WRITE_LINE_MEMBER( device_a8sio_card_interface::ready_w ) +{ +} + void a8sio_cards(device_slot_interface &device) { + device.option_add("a810", ATARI810); + device.option_add("a1050", ATARI1050); device.option_add("cassette", A8SIO_CASSETTE); } diff --git a/src/devices/bus/a800/a8sio.h b/src/devices/bus/a800/a8sio.h index b513ea0c9f1..cb5ebfe97b3 100644 --- a/src/devices/bus/a800/a8sio.h +++ b/src/devices/bus/a800/a8sio.h @@ -83,18 +83,21 @@ public: auto clock_in() { return m_out_clock_in_cb.bind(); } auto data_in() { return m_out_data_in_cb.bind(); } auto audio_in() { return m_out_audio_in_cb.bind(); } + auto proceed() { return m_out_proceed_cb.bind(); } + auto interrupt() { return m_out_interrupt_cb.bind(); } void add_a8sio_card(device_a8sio_card_interface *card); device_a8sio_card_interface *get_a8sio_card(); DECLARE_WRITE_LINE_MEMBER( clock_in_w ); // pin 1 - //virtual DECLARE_WRITE_LINE_MEMBER( clock_out_w ); // pin 2 + DECLARE_WRITE_LINE_MEMBER( clock_out_w ); // pin 2 DECLARE_WRITE_LINE_MEMBER( data_in_w ); // pin 3 - //DECLARE_WRITE_LINE_MEMBER( data_out_wi ); // pin 5 - //DECLARE_WRITE_LINE_MEMBER( command_w ); // pin 7 + DECLARE_WRITE_LINE_MEMBER( data_out_w ); // pin 5 + DECLARE_WRITE_LINE_MEMBER( command_w ); // pin 7 DECLARE_WRITE_LINE_MEMBER( motor_w ); // pin 8 - //DECLARE_WRITE_LINE_MEMBER( proceed_w ); // pin 9 + DECLARE_WRITE_LINE_MEMBER( proceed_w ); // pin 9 DECLARE_WRITE8_MEMBER( audio_in_w ); // pin 11 + DECLARE_WRITE_LINE_MEMBER( interrupt_w ); // pin 13 protected: a8sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -105,7 +108,9 @@ protected: devcb_write_line m_out_clock_in_cb; // pin 1 devcb_write_line m_out_data_in_cb; // pin 3 + devcb_write_line m_out_proceed_cb; // pin 9 devcb_write8 m_out_audio_in_cb; // pin 11 + devcb_write_line m_out_interrupt_cb; // pin 13 device_a8sio_card_interface *m_device; }; @@ -126,7 +131,11 @@ public: // inline configuration void set_a8sio_tag(const char *tag, const char *slottag) { m_a8sio_tag = tag; m_a8sio_slottag = slottag; } + virtual DECLARE_WRITE_LINE_MEMBER( clock_out_w ); + virtual DECLARE_WRITE_LINE_MEMBER( data_out_w ); + virtual DECLARE_WRITE_LINE_MEMBER( command_w ); virtual DECLARE_WRITE_LINE_MEMBER( motor_w ); + virtual DECLARE_WRITE_LINE_MEMBER( ready_w ); public: device_a8sio_card_interface(const machine_config &mconfig, device_t &device); diff --git a/src/devices/bus/a800/atari1050.cpp b/src/devices/bus/a800/atari1050.cpp new file mode 100644 index 00000000000..c82113e812c --- /dev/null +++ b/src/devices/bus/a800/atari1050.cpp @@ -0,0 +1,112 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Atari 1050 Dual Density Disk Drive + +***************************************************************************/ + +#include "emu.h" +#include "atari1050.h" + +#include "cpu/m6502/m6507.h" + + +// device type definition +DEFINE_DEVICE_TYPE(ATARI1050, atari1050_device, "atari1050", "Atari 1050 Dual Density Disk Drive") + +atari1050_device::atari1050_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, ATARI1050, tag, owner, clock) + , device_a8sio_card_interface(mconfig, *this) + , m_pia(*this, "pia") + , m_fdc(*this, "fdc") +{ +} + +void atari1050_device::device_start() +{ +} + +void atari1050_device::step_w(u8 data) +{ + m_a8sio->data_in_w(BIT(data, 0)); +} + +void atari1050_device::mem_map(address_map &map) +{ + map(0x0000, 0x007f).mirror(0x0900).ram(); // MCM6810 + map(0x0080, 0x00ff).mirror(0x0900).m(m_pia, FUNC(mos6532_new_device::ram_map)); + map(0x0280, 0x029f).mirror(0x0960).m(m_pia, FUNC(mos6532_new_device::io_map)); + map(0x0400, 0x0403).mirror(0x087c).rw(m_fdc, FUNC(wd2793_device::read), FUNC(fd1771_device::write)); + map(0x1000, 0x1fff).rom().region("rom", 0); +} + + +WRITE_LINE_MEMBER(atari1050_device::data_out_w) +{ + m_pia->pb6_w(state); +} + +WRITE_LINE_MEMBER(atari1050_device::command_w) +{ + m_pia->pb7_w(state); +} + +WRITE_LINE_MEMBER(atari1050_device::ready_w) +{ + m_pia->pb1_w(state); +} + + +static INPUT_PORTS_START(atari1050) + PORT_NAME("SELECT") // values not verified + PORT_DIPNAME(0x03, 0x00, "Drive Code") PORT_DIPLOCATION("S2:1,2") + PORT_DIPSETTING(0x00, "No. 1") + PORT_DIPSETTING(0x01, "No. 2") + PORT_DIPSETTING(0x02, "No. 3") + PORT_DIPSETTING(0x03, "No. 4") + PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNUSED) +INPUT_PORTS_END + +ioport_constructor atari1050_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(atari1050); +} + +void atari1050_device::device_add_mconfig(machine_config &config) +{ + m6507_device &fdcpu(M6507(config, "fdcpu", 4_MHz_XTAL / 4)); + fdcpu.set_addrmap(AS_PROGRAM, &atari1050_device::mem_map); + + MOS6532_NEW(config, m_pia, 4_MHz_XTAL / 4); + m_pia->pa_rd_callback().set_ioport("SELECT"); + m_pia->pa_wr_callback().set(m_fdc, FUNC(wd2793_device::dden_w)).bit(3); + //m_pia->pa_wr_callback().append(atari1050_device::motor_control_w)).bit(1); + m_pia->pb_wr_callback().set(FUNC(atari1050_device::step_w)); + m_pia->irq_wr_callback().set(m_pia, FUNC(mos6532_new_device::pa6_w)).invert(); + //m_pia->irq_wr_callback().append(m_fdc, FUNC(wd2793_device::ip_w)); + + WD2793(config, m_fdc, 4_MHz_XTAL / 4); + m_fdc->drq_wr_callback().set(m_pia, FUNC(mos6532_new_device::pa7_w)); + m_fdc->enp_wr_callback().set(m_pia, FUNC(mos6532_new_device::pa4_w)); +} + + +ROM_START(atari1050) + ROM_REGION(0x1000, "rom", 0) + ROM_SYSTEM_BIOS(0, "l", "Rev. L") + ROMX_LOAD("1050-revl.rom", 0x0000, 0x1000, CRC(fb4b8757) SHA1(8b540906049864a18bdc4eff6c0a2160eac8ce39), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "k", "Rev. K") + ROMX_LOAD("1050-revk.rom", 0x0000, 0x1000, CRC(3abe7ef4) SHA1(f281b64a4d8bd91127776b631313785c6886d963), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(2, "j", "Rev. J") + ROMX_LOAD("1050-revj.rom", 0x0000, 0x1000, CRC(91ba303d) SHA1(82f103e9026359587eb4ee2239e36d9cb291e3c9), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(3, "h", "Rev. H") + ROMX_LOAD("1050-revh.rom", 0x0000, 0x1000, CRC(6d9d589b) SHA1(fe0b289adf746d00dd3af780f363377f75eb584f), ROM_BIOS(3)) + ROM_SYSTEM_BIOS(4, "wst", "World Storage Technology (Rev. K modified)") + ROMX_LOAD("wstr5.bin", 0x0000, 0x1000, CRC(dffb4b47) SHA1(2e735fe1973000219dc81c463ca0d3fd90690d4a), ROM_BIOS(4)) +ROM_END + +const tiny_rom_entry *atari1050_device::device_rom_region() const +{ + return ROM_NAME(atari1050); +} diff --git a/src/devices/bus/a800/atari1050.h b/src/devices/bus/a800/atari1050.h new file mode 100644 index 00000000000..48e32b86430 --- /dev/null +++ b/src/devices/bus/a800/atari1050.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Atari 1050 Dual Density Disk Drive + +***************************************************************************/ + +#ifndef MAME_BUS_A800_ATARI1050 +#define MAME_BUS_A800_ATARI1050 1 + +#pragma once + +#include "a8sio.h" +#include "machine/mos6530n.h" +#include "machine/wd_fdc.h" + + +class atari1050_device : public device_t, public device_a8sio_card_interface +{ +public: + atari1050_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + static constexpr feature_type unemulated_features() { return feature::DISK; } + +protected: + virtual void device_start() override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual DECLARE_WRITE_LINE_MEMBER(data_out_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(command_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(ready_w) override; + +private: + void step_w(u8 data); + + void mem_map(address_map &map); + + required_device m_pia; + required_device m_fdc; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(ATARI1050, atari1050_device) + +#endif // MAME_BUS_A800_ATARI1050 diff --git a/src/devices/bus/a800/atari810.cpp b/src/devices/bus/a800/atari810.cpp new file mode 100644 index 00000000000..12955fb1609 --- /dev/null +++ b/src/devices/bus/a800/atari810.cpp @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Atari 810 Disk Drive + +***************************************************************************/ + +#include "emu.h" +#include "atari810.h" + +#include "cpu/m6502/m6507.h" + + +// device type definition +DEFINE_DEVICE_TYPE(ATARI810, atari810_device, "atari810", "Atari 810 Disk Drive") + +atari810_device::atari810_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, ATARI810, tag, owner, clock) + , device_a8sio_card_interface(mconfig, *this) + , m_pia(*this, "pia") + , m_fdc(*this, "fdc") +{ +} + +void atari810_device::device_start() +{ +} + +void atari810_device::step_w(u8 data) +{ + m_a8sio->data_in_w(BIT(data, 0)); +} + +void atari810_device::mem_map(address_map &map) +{ + map(0x0000, 0x0003).mirror(0x167c).rw(m_fdc, FUNC(fd1771_device::read), FUNC(fd1771_device::write)); + map(0x0080, 0x00ff).mirror(0x1400).ram(); // MCM6810 + map(0x0100, 0x017f).mirror(0x1480).m(m_pia, FUNC(mos6532_new_device::ram_map)); + map(0x0300, 0x031f).mirror(0x14e0).m(m_pia, FUNC(mos6532_new_device::io_map)); + map(0x0800, 0x0fff).mirror(0x1800).rom().region("rom", 0); +} + + +WRITE_LINE_MEMBER(atari810_device::data_out_w) +{ + m_pia->pb7_w(state); +} + +WRITE_LINE_MEMBER(atari810_device::command_w) +{ + m_pia->pb6_w(state); +} + +WRITE_LINE_MEMBER(atari810_device::ready_w) +{ + m_pia->pb1_w(state); +} + + +static INPUT_PORTS_START(atari810) + PORT_NAME("SELECT") // values not verified + PORT_DIPNAME(0x05, 0x00, "Drive Code") PORT_DIPLOCATION("S101:1,2") + PORT_DIPSETTING(0x00, "No. 1") + PORT_DIPSETTING(0x01, "No. 2") + PORT_DIPSETTING(0x04, "No. 3") + PORT_DIPSETTING(0x05, "No. 4") + PORT_BIT(0xfa, IP_ACTIVE_LOW, IPT_UNUSED) +INPUT_PORTS_END + +ioport_constructor atari810_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(atari810); +} + +void atari810_device::device_add_mconfig(machine_config &config) +{ + m6507_device &fdcpu(M6507(config, "fdcpu", 1_MHz_XTAL / 2)); + fdcpu.set_addrmap(AS_PROGRAM, &atari810_device::mem_map); + + MOS6532_NEW(config, m_pia, 1_MHz_XTAL / 2); + m_pia->pa_rd_callback().set_ioport("SELECT"); + m_pia->pb_wr_callback().set(FUNC(atari810_device::step_w)); + //m_pia->irq_wr_callback().set(m_fdc, FUNC(fd1771_device::ip_w)); + + FD1771(config, m_fdc, 1_MHz_XTAL); + m_fdc->drq_wr_callback().set(m_pia, FUNC(mos6532_new_device::pa7_w)); + m_fdc->intrq_wr_callback().set(m_pia, FUNC(mos6532_new_device::pa6_w)); +} + + +ROM_START(atari810) + ROM_REGION(0x0800, "rom", 0) + ROM_SYSTEM_BIOS(0, "c", "Rev. C (9:1 skew)") + ROMX_LOAD("8229_c68168_c011299c-03.bin", 0x0000, 0x0800, CRC(0896f03d) SHA1(b676b2a46ac3903a6729b92650c5faf0111ba8b6), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "b", "Rev. B (12:1 skew)") + ROMX_LOAD("810rom_b.bin", 0x0000, 0x0800, CRC(19227d33) SHA1(075b1948a5736599d5501f0125c745b1b9fcced4), ROM_BIOS(1)) +ROM_END + +const tiny_rom_entry *atari810_device::device_rom_region() const +{ + return ROM_NAME(atari810); +} diff --git a/src/devices/bus/a800/atari810.h b/src/devices/bus/a800/atari810.h new file mode 100644 index 00000000000..1bbe8db0f8c --- /dev/null +++ b/src/devices/bus/a800/atari810.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Atari 810 Disk Drive + +***************************************************************************/ + +#ifndef MAME_BUS_A800_ATARI810 +#define MAME_BUS_A800_ATARI810 1 + +#pragma once + +#include "a8sio.h" +#include "machine/mos6530n.h" +#include "machine/wd_fdc.h" + + +class atari810_device : public device_t, public device_a8sio_card_interface +{ +public: + atari810_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + static constexpr feature_type unemulated_features() { return feature::DISK; } + +protected: + virtual void device_start() override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual DECLARE_WRITE_LINE_MEMBER(data_out_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(command_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(ready_w) override; + +private: + void step_w(u8 data); + + void mem_map(address_map &map); + + required_device m_pia; + required_device m_fdc; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(ATARI810, atari810_device) + +#endif // MAME_BUS_A800_ATARI810 diff --git a/src/mame/drivers/atari400.cpp b/src/mame/drivers/atari400.cpp index 10c6bbcbdf3..281b168339a 100644 --- a/src/mame/drivers/atari400.cpp +++ b/src/mame/drivers/atari400.cpp @@ -2131,8 +2131,13 @@ void a400_state::atari_common_nodac(machine_config &config) m_pia->readpb_handler().set_ioport("djoy_2_3"); m_pia->ca2_handler().set("a8sio", FUNC(a8sio_device::motor_w)); m_pia->cb2_handler().set("fdc", FUNC(atari_fdc_device::pia_cb2_w)); + m_pia->cb2_handler().append("a8sio", FUNC(a8sio_device::command_w)); - A8SIO(config, "a8sio", 0).data_in().set("pokey", FUNC(pokey_device::sid_w)); + a8sio_device &a8sio(A8SIO(config, "a8sio", 0)); + //a8sio.clock_in().set("pokey", FUNC(pokey_device::bclk_w)); + a8sio.data_in().set("pokey", FUNC(pokey_device::sid_w)); + a8sio.proceed().set(m_pia, FUNC(pia6821_device::ca1_w)); + a8sio.interrupt().set(m_pia, FUNC(pia6821_device::cb1_w)); A8SIO_SLOT(config, "sio", nullptr).set_a8sio_slot("a8sio", "sio"); /* sound hardware */ @@ -2148,6 +2153,8 @@ void a400_state::atari_common_nodac(machine_config &config) m_pokey->pot_r<7>().set_ioport("analog_7"); m_pokey->serin_r().set("fdc", FUNC(atari_fdc_device::serin_r)); m_pokey->serout_w().set("fdc", FUNC(atari_fdc_device::serout_w)); + //m_pokey->oclk_w().set("a8sio", FUNC(a8sio_device::clock_out_w)); + //m_pokey->sod_w().set("a8sio", FUNC(a8sio_device::data_out_w)); m_pokey->set_keyboard_callback(FUNC(a400_state::a800_keyboard)); m_pokey->set_interrupt_callback(FUNC(a400_state::interrupt_cb)); m_pokey->add_route(ALL_OUTPUTS, "speaker", 1.0);