diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 415826bbfb6..1540f2c8d54 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -190,6 +190,19 @@ if (BUSES["ADAMNET"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/bus/adb/adb.h,BUSES["ADB"] = true +--------------------------------------------------- + +if (BUSES["ADB"]~=null) then + files { + MAME_DIR .. "src/devices/bus/adb/adb.cpp", + MAME_DIR .. "src/devices/bus/adb/adb.h", + MAME_DIR .. "src/devices/bus/adb/adbhle.cpp", + MAME_DIR .. "src/devices/bus/adb/adbhle.h", + } +end --------------------------------------------------- -- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 40c0370ed1e..b61d57dee0a 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -754,6 +754,7 @@ MACHINES["VRENDER0"] = true --BUSES["ABCKB"] = true --BUSES["ADAM"] = true --BUSES["ADAMNET"] = true +--BUSES["ADB"] = true --BUSES["APF"] = true BUSES["AMIGA_KEYBOARD"] = true --BUSES["ARCADIA"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 8d12ca214d9..edd03a28e6f 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -824,6 +824,7 @@ BUSES["ABCKB"] = true BUSES["ACORN"] = true BUSES["ADAM"] = true BUSES["ADAMNET"] = true +BUSES["ADB"] = true BUSES["APF"] = true BUSES["APRICOT_EXPANSION"] = true BUSES["APRICOT_KEYBOARD"] = true diff --git a/src/devices/bus/adb/adb.cpp b/src/devices/bus/adb/adb.cpp new file mode 100644 index 00000000000..3ff2ea6b382 --- /dev/null +++ b/src/devices/bus/adb/adb.cpp @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders: Olivier Galibert + +// ADB - Apple Desktop Bus +// +// The serial desktop device bus from before USB was cool. +// +// Single data wire + poweron line, open collector + +#include "emu.h" +#include "adb.h" + +#include "adbhle.h" + +DEFINE_DEVICE_TYPE(ADB_CONNECTOR, adb_connector, "adbslot", "ADB connector") + +adb_connector::adb_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, ADB_CONNECTOR, tag, owner, clock), + device_single_card_slot_interface(mconfig, *this) +{ +} + +void adb_connector::device_start() +{ +} + +adb_device *adb_connector::get_device() +{ + adb_slot_card_interface *const connected = get_card_device(); + if (connected) + return connected->device().subdevice(connected->m_adb.finder_tag()); + else + return nullptr; +} + +adb_slot_card_interface::adb_slot_card_interface(const machine_config &mconfig, device_t &device, const char *adb_tag) : + device_interface(device, "adb"), + m_adb(*this, adb_tag) +{ +} + + + +adb_device::adb_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_adb_cb(*this), + m_poweron_cb(*this) +{ +} + +void adb_device::device_start() +{ +} + +void adb_device::device_reset() +{ + m_adb_istate = true; + m_adb_ostate = true; +} + +void adb_device::default_devices(device_slot_interface &device) +{ + device.option_add("hle", ADB_HLE); +} diff --git a/src/devices/bus/adb/adb.h b/src/devices/bus/adb/adb.h new file mode 100644 index 00000000000..8a07986c531 --- /dev/null +++ b/src/devices/bus/adb/adb.h @@ -0,0 +1,73 @@ +// license:BSD-3-Clause +// copyright-holders: Olivier Galibert + +// ADB - Apple Desktop Bus +// +// The serial desktop device bus from before USB was cool. +// +// Single data wire + poweron line, open collector + +#ifndef MAME_BUS_ADB_ADB_H +#define MAME_BUS_ADB_ADB_H + +#pragma once + +class adb_device; +class adb_slot_card_interface; + +class adb_connector: public device_t, public device_single_card_slot_interface +{ +public: + template + adb_connector(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt, bool fixed = false) + : adb_connector(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + + adb_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~adb_connector() = default; + + adb_device *get_device(); + +protected: + virtual void device_start() override; +}; + +class adb_slot_card_interface : public device_interface +{ + friend class adb_connector; + +public: + adb_slot_card_interface(const machine_config &mconfig, device_t &device, const char *adb_tag); + +private: + required_device m_adb; +}; + +class adb_device: public device_t +{ +public: + virtual void adb_w(int state) = 0; + auto adb_r() { return m_adb_cb.bind(); } + auto poweron_r() { return m_poweron_cb.bind(); } + + static void default_devices(device_slot_interface &device); + +protected: + adb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual void device_start() override; + virtual void device_reset() override; + +private: + devcb_write_line m_adb_cb; + devcb_write_line m_poweron_cb; + bool m_adb_istate, m_adb_ostate; +}; + +DECLARE_DEVICE_TYPE(ADB_CONNECTOR, adb_connector) + +#endif diff --git a/src/devices/bus/adb/adbhle.cpp b/src/devices/bus/adb/adbhle.cpp new file mode 100644 index 00000000000..369595ef143 --- /dev/null +++ b/src/devices/bus/adb/adbhle.cpp @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders: Olivier Galibert + +// ADB - Apple Desktop Bus +// +// Generic HLE + +#include "emu.h" +#include "adbhle.h" + +DEFINE_DEVICE_TYPE(ADB_HLE, adb_hle_device, "adbhle", "ADB HLE") + +adb_hle_device::adb_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + adb_device(mconfig, ADB_HLE, tag, owner, clock), + adb_slot_card_interface(mconfig, *this, DEVICE_SELF) +{ +} + +void adb_hle_device::device_start() +{ + adb_device::device_start(); + + save_item(NAME(m_last_state)); + save_item(NAME(m_last_state_time)); +} + +void adb_hle_device::device_reset() +{ + adb_device::device_reset(); + m_last_state = true; + m_last_state_time = machine().time(); +} + +void adb_hle_device::adb_w(int state) +{ + if(m_last_state != state) { + attotime delta = machine().time() - m_last_state_time; + u32 dt = delta.as_ticks(1000000); + + logerror("level %d duration %6d us\n", m_last_state, dt); + + m_last_state = state; + m_last_state_time = machine().time(); + } +} diff --git a/src/devices/bus/adb/adbhle.h b/src/devices/bus/adb/adbhle.h new file mode 100644 index 00000000000..24dff3ad2fe --- /dev/null +++ b/src/devices/bus/adb/adbhle.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders: Olivier Galibert + +// ADB - Apple Desktop Bus +// +// Generic HLE + +#ifndef MAME_BUS_ADB_ADBHLE_H +#define MAME_BUS_ADB_ADBHLE_H + +#pragma once + +#include "adb.h" + +class adb_hle_device : public adb_device, public adb_slot_card_interface +{ +public: + adb_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual void adb_w(int state) override; + +private: + bool m_last_state; + attotime m_last_state_time; +}; + +DECLARE_DEVICE_TYPE(ADB_HLE, adb_hle_device) + +#endif diff --git a/src/mame/machine/egret.cpp b/src/mame/machine/egret.cpp index b9056c215af..23148954c31 100644 --- a/src/mame/machine/egret.cpp +++ b/src/mame/machine/egret.cpp @@ -97,21 +97,49 @@ const tiny_rom_entry *egret_device::device_rom_region() const //************************************************************************** // LIVE DEVICE //************************************************************************** +#if USE_BUS_ADB +void egret_device::adb_w(int id, int state) +{ + m_adb_device_out[id] = state; + adb_change(); +} + +void egret_device::adb_poweron_w(int id, int state) +{ + m_adb_device_poweron[id] = state; +} + +void egret_device::adb_change() +{ + bool adb = m_adb_out & m_adb_device_out[0] & m_adb_device_out[1]; + logerror("adb c:%d 1:%d 2:%d -> %d (%02x %02x)\n", m_adb_out, m_adb_device_out[0], m_adb_device_out[1], adb, ddrs[0], ports[0]); + for (int i = 0; i != 2; i++) + if (m_adb_device[i]) + { + m_adb_device[i]->adb_w(adb); + } +} +#endif void egret_device::send_port(uint8_t offset, uint8_t data) { switch (offset) { - case 0: // port A -/* printf("ADB:%d DFAC:%d PowerEnable:%d\n", + case 0: // port A + /* printf("ADB:%d DFAC:%d PowerEnable:%d\n", (data & 0x80) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x02) ? 1 : 0);*/ - if ((data & 0x80) != last_adb) - { - m_adb_dtime = (int)(machine().time().as_ticks(1000000) - last_adb_time); - /* +#if USE_BUS_ADB + // the line goes to a mosfet pulling the adb data line to graound, hence the inversion + m_adb_out = !(data & 0x80); + adb_change(); +#else + if ((data & 0x80) != last_adb) + { + m_adb_dtime = (int)(machine().time().as_ticks(1000000) - last_adb_time); + /* if (data & 0x80) { printf("EG ADB: 1->0 time %d\n", m_adb_dtime); @@ -121,14 +149,15 @@ void egret_device::send_port(uint8_t offset, uint8_t data) printf("EG ADB: 0->1 time %d\n", m_adb_dtime); } */ - // allow the linechange handler to override us - adb_in = (data & 0x80) ? true : false; + // allow the linechange handler to override us + adb_in = (data & 0x80) ? true : false; - write_linechange(((data & 0x80) >> 7) ^ 1); + write_linechange(((data & 0x80) >> 7) ^ 1); - last_adb = data & 0x80; - last_adb_time = machine().time().as_ticks(1000000); + last_adb = data & 0x80; + last_adb_time = machine().time().as_ticks(1000000); } +#endif break; case 1: // port B @@ -205,8 +234,12 @@ uint8_t egret_device::ports_r(offs_t offset) switch (offset) { case 0: // port A +#if USE_BUS_ADB + incoming |= (m_adb_out & m_adb_device_out[0] & m_adb_device_out[1]) ? 0x40 : 0; + incoming |= (m_adb_device_poweron[0] & m_adb_device_poweron[1]) ? 0x04 : 0; +#else incoming |= adb_in ? 0x40 : 0; - +#endif if (egret_controls_power) { incoming |= 0x02; // indicate soft power, indicate chassis switch on @@ -327,12 +360,15 @@ void egret_device::pram_w(offs_t offset, uint8_t data) egret_device::egret_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, EGRET, tag, owner, clock), - device_nvram_interface(mconfig, *this), - write_reset(*this), - write_linechange(*this), - write_via_clock(*this), - write_via_data(*this), - m_maincpu(*this, EGRET_CPU_TAG) + device_nvram_interface(mconfig, *this), + write_reset(*this), + write_linechange(*this), + write_via_clock(*this), + write_via_data(*this), + m_maincpu(*this, EGRET_CPU_TAG) +#if USE_BUS_ADB + , m_adb_connector{{*this, ":adb1"}, {*this, finder_base::DUMMY_TAG}} +#endif { } @@ -347,6 +383,18 @@ void egret_device::device_start() write_via_clock.resolve_safe(); write_via_data.resolve_safe(); +#if USE_BUS_ADB + for (int i = 0; i < 2; i++) + { + m_adb_device[i] = m_adb_connector[i] ? m_adb_connector[i]->get_device() : nullptr; + if (m_adb_device[i]) + { + m_adb_device[i]->adb_r().set([this, i](int state) { adb_w(i, state); }); + m_adb_device[i]->poweron_r().set([this, i](int state) { adb_poweron_w(i, state); }); + } + } +#endif + m_timer = timer_alloc(0, nullptr); save_item(NAME(ddrs[0])); save_item(NAME(ddrs[1])); @@ -369,6 +417,11 @@ void egret_device::device_start() save_item(NAME(pram_loaded)); save_item(NAME(pram)); save_item(NAME(disk_pram)); +#if USE_BUS_ADB + save_item(NAME(m_adb_out)); + save_item(NAME(m_adb_device_out)); + save_item(NAME(m_adb_device_poweron)); +#endif uint8_t *rom = device().machine().root_device().memregion(device().subtag(EGRET_CPU_TAG))->base(); @@ -388,6 +441,11 @@ void egret_device::device_reset() ddrs[0] = ddrs[1] = ddrs[2] = 0; ports[0] = ports[1] = ports[2] = 0; + #if USE_BUS_ADB + m_adb_device_out[0] = m_adb_device_out[1] = true; + m_adb_device_poweron[0] = m_adb_device_poweron[1] = true; + #endif + m_timer->adjust(attotime::never); egret_controls_power = false; // set to hard power control diff --git a/src/mame/machine/egret.h b/src/mame/machine/egret.h index b1597dca367..b4ea5882b0d 100644 --- a/src/mame/machine/egret.h +++ b/src/mame/machine/egret.h @@ -5,7 +5,11 @@ #pragma once +#define USE_BUS_ADB (0) +#if USE_BUS_ADB +#include "bus/adb/adb.h" +#endif //************************************************************************** // MACROS / CONSTANTS @@ -59,6 +63,12 @@ public: uint8_t pram_r(offs_t offset); void pram_w(offs_t offset, uint8_t data); +#if USE_BUS_ADB + void adb_w(int id, int state); + void adb_poweron_w(int id, int state); + void adb_change(); +#endif + // interface routines uint8_t get_xcvr_session() { return xcvr_session; } void set_via_full(uint8_t val) { via_full = val; } @@ -107,6 +117,14 @@ private: uint8_t pram[0x100], disk_pram[0x100]; bool pram_loaded; + #if USE_BUS_ADB + optional_device m_adb_connector[2]; + adb_device *m_adb_device[2]; + bool m_adb_device_out[2]; + bool m_adb_device_poweron[2]; + bool m_adb_out; + #endif + void send_port(uint8_t offset, uint8_t data); };