From 0a0761c7e068b42cf0e032354c3bc5095ceb36d7 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 26 Jul 2023 04:35:07 +0200 Subject: [PATCH] AdbDevice - the base class for ADB devices. --- devices/common/adb/adbdevice.cpp | 93 ++++++++++++++++++++++++++++++++ devices/common/adb/adbdevice.h | 77 ++++++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 devices/common/adb/adbdevice.cpp create mode 100644 devices/common/adb/adbdevice.h diff --git a/devices/common/adb/adbdevice.cpp b/devices/common/adb/adbdevice.cpp new file mode 100644 index 0000000..41cfa3e --- /dev/null +++ b/devices/common/adb/adbdevice.cpp @@ -0,0 +1,93 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-23 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/** @file Base class for Apple Desktop Bus devices. */ + +#include +#include +#include +#include + +AdbDevice::AdbDevice(std::string name) { + this->set_name(name); + this->supports_types(HWCompType::ADB_DEV); +} + +int AdbDevice::device_postinit() { + // register itself with the ADB host + this->host_obj = dynamic_cast(gMachineObj->get_comp_by_type(HWCompType::ADB_HOST)); + this->host_obj->register_device(this); + + return 0; +}; + +bool AdbDevice::talk(const uint8_t dev_addr, const uint8_t reg_num) { + if (dev_addr == this->my_addr && !this->got_collision) { + // see if another device already responded to this command + if (this->host_obj->already_answered()) { + this->got_collision = true; + return false; + } + + switch(reg_num & 3) { + case 0: + return this->get_register_0(); + case 1: + return this->get_register_1(); + case 2: + return this->get_register_2(); + case 3: + return this->get_register_3(); + default: + return false; + } + } else { + return false; + } +} + +void AdbDevice::listen(const uint8_t dev_addr, const uint8_t reg_num) { + if (dev_addr == this->my_addr) { + switch(reg_num & 3) { + case 0: + this->set_register_0(); + case 1: + this->set_register_1(); + case 2: + this->set_register_2(); + case 3: + this->set_register_3(); + } + } +} + +bool AdbDevice::get_register_3() { + uint8_t* out_buf = this->host_obj->get_output_buf(); + out_buf[0] = this->gen_random_address() | (this->exc_event_flag << 6) | + (this->srq_flag << 5); + out_buf[1] = this->dev_handler_id; + this->host_obj->set_output_count(2); + return true; +} + +uint8_t AdbDevice::gen_random_address() { + return (TimerManager::get_instance()->current_time_ns() + 8) & 0xF; +} diff --git a/devices/common/adb/adbdevice.h b/devices/common/adb/adbdevice.h new file mode 100644 index 0000000..49f68c1 --- /dev/null +++ b/devices/common/adb/adbdevice.h @@ -0,0 +1,77 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-23 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/** @file Base class for Apple Desktop Bus devices. */ + +#ifndef ADB_DEVICE_H +#define ADB_DEVICE_H + +#include +#include + +#include +#include +#include + +/** Common ADB device addresses/types. */ +enum { + ADB_ADDR_KBD = 2, // keyboards + ADB_ADDR_RELPOS = 3, // relative position devices (mouse) + ADB_ADDR_ABSPOS = 4, // absolute position devices (graphic tablets) +}; + +class AdbBus; // forward declaration to prevent compiler errors + +class AdbDevice : public HWComponent { +public: + AdbDevice(std::string name); + ~AdbDevice() = default; + + int device_postinit() override; + + virtual void reset() = 0; + virtual bool talk(const uint8_t dev_addr, const uint8_t reg_num); + virtual void listen(const uint8_t dev_addr, const uint8_t reg_num); + virtual uint8_t get_address() { return this->my_addr; }; + +protected: + uint8_t gen_random_address(); + + virtual bool get_register_0() { return false; }; + virtual bool get_register_1() { return false; }; + virtual bool get_register_2() { return false; }; + virtual bool get_register_3(); + + virtual void set_register_0() {}; + virtual void set_register_1() {}; + virtual void set_register_2() {}; + virtual void set_register_3() {}; + + uint8_t exc_event_flag = 0; + uint8_t srq_flag = 0; + uint8_t my_addr = 0; + uint8_t dev_handler_id = 0; + bool got_collision = false; + + AdbBus* host_obj = nullptr; +}; + +#endif // ADB_DEVICE_H