From 6696248158b8273498094ab54bec06f0d219fc1c Mon Sep 17 00:00:00 2001 From: Keith Kaisershot Date: Sun, 6 Oct 2024 22:53:56 -0700 Subject: [PATCH] adbbus: decouple ADB devices from CUDA AdbMouse and AdbKeyboard are subdevices of the CUDA device alongside AdbBus. This doesn't make sense because conceptually, ADB devices hang off of the ADB bus, not CUDA itself. An ADB bus can exist without a CUDA present, for example Egret on older 68K Macs and the PMU on newer Power Macs. Therefore, make the ADB device list a subhierarchy of AdbBus instead. Add a new "adb_devices" property belonging to AdbBus that can allow users to specify ADB devices on the command line at machine creation time, independent of the emulated bus's host. Make this property default to "Mouse,Keyboard" to preserve existing behavior. --- devices/common/adb/adbbus.cpp | 32 +++++++++++++++++++++++++++++++- devices/common/adb/adbbus.h | 2 ++ devices/common/viacuda.cpp | 2 +- machines/machinefactory.cpp | 1 + 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/devices/common/adb/adbbus.cpp b/devices/common/adb/adbbus.cpp index 225e6ee..6ea6e99 100644 --- a/devices/common/adb/adbbus.cpp +++ b/devices/common/adb/adbbus.cpp @@ -25,6 +25,8 @@ along with this program. If not, see . #include #include #include +#include +#include AdbBus::AdbBus(std::string name) { this->set_name(name); @@ -32,6 +34,30 @@ AdbBus::AdbBus(std::string name) { this->devices.clear(); } +int AdbBus::device_postinit() { + std::string adb_device_list = GET_STR_PROP("adb_devices"); + if (adb_device_list.empty()) + return 0; + + std::string adb_device; + std::istringstream adb_device_stream(adb_device_list); + + while (getline(adb_device_stream, adb_device, ',')) { + string dev_name = "Adb" + adb_device; + + if (dev_name == this->name) + continue; // don't register a second ADB bus + + if (DeviceRegistry::device_registered(dev_name)) { + gMachineObj->add_device(dev_name, DeviceRegistry::get_descriptor(dev_name).m_create_func()); + } else { + LOG_F(WARNING, "Unknown specified ADB device \"%s\"", adb_device.c_str()); + } + } + + return 0; +} + void AdbBus::register_device(AdbDevice* dev_obj) { this->devices.push_back(dev_obj); } @@ -102,8 +128,12 @@ uint8_t AdbBus::process_command(const uint8_t* in_data, int data_size) { return ADB_STAT_OK; } +static const PropMap AdbBus_Properties = { + {"adb_devices", new StrProperty("Mouse,Keyboard")}, +}; + static const DeviceDescription AdbBus_Descriptor = { - AdbBus::create, {}, {} + AdbBus::create, {}, AdbBus_Properties }; REGISTER_DEVICE(AdbBus, AdbBus_Descriptor); diff --git a/devices/common/adb/adbbus.h b/devices/common/adb/adbbus.h index 6af3757..458d4a1 100644 --- a/devices/common/adb/adbbus.h +++ b/devices/common/adb/adbbus.h @@ -51,6 +51,8 @@ public: return std::unique_ptr(new AdbBus("ADB-BUS")); } + int device_postinit() override; + void register_device(AdbDevice* dev_obj); uint8_t process_command(const uint8_t* in_data, int data_size); uint8_t get_output_count() { return this->output_count; }; diff --git a/devices/common/viacuda.cpp b/devices/common/viacuda.cpp index e732233..807b3c3 100644 --- a/devices/common/viacuda.cpp +++ b/devices/common/viacuda.cpp @@ -836,7 +836,7 @@ void ViaCuda::i2c_comb_transaction( } static const vector Cuda_Subdevices = { - "AdbBus", "AdbMouse", "AdbKeyboard" + "AdbBus" }; static const DeviceDescription ViaCuda_Descriptor = { diff --git a/machines/machinefactory.cpp b/machines/machinefactory.cpp index 3e1ee7d..1d15c3f 100644 --- a/machines/machinefactory.cpp +++ b/machines/machinefactory.cpp @@ -98,6 +98,7 @@ static const map PropHelp = { {"serial_backend", "specifies the backend for the serial port"}, {"emmo", "enables/disables factory HW tests during startup"}, {"cpu", "specifies CPU"}, + {"adb_devices", "specifies which ADB device(s) to attach"}, }; bool MachineFactory::add(const string& machine_id, MachineDescription desc)