From 6f638805f78481651bc4c3f023d8b4bf99307745 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 28 Dec 2024 20:52:31 -0500 Subject: [PATCH] Further eliminate std::shared_ptr connections. --- Machines/Commodore/1540/C1540.hpp | 22 +-- .../Commodore/1540/Implementation/C1540.cpp | 48 +++---- .../1540/Implementation/C1540Base.hpp | 46 +++---- Machines/Commodore/Plus4/Interrupts.hpp | 1 - Machines/Commodore/Plus4/Plus4.cpp | 12 +- Machines/Commodore/SerialBus.cpp | 70 +++++----- Machines/Commodore/SerialBus.hpp | 128 +++++++++--------- Machines/Commodore/Vic-20/Vic20.cpp | 79 +++++------ 8 files changed, 198 insertions(+), 208 deletions(-) diff --git a/Machines/Commodore/1540/C1540.hpp b/Machines/Commodore/1540/C1540.hpp index 47f8cf726..a5a815c62 100644 --- a/Machines/Commodore/1540/C1540.hpp +++ b/Machines/Commodore/1540/C1540.hpp @@ -36,20 +36,20 @@ namespace Commodore::C1540 { Provides an emulation of the C1540. */ class Machine final: public MachineBase { - public: - static ROM::Request rom_request(Personality personality); - Machine(Personality personality, const ROM::Map &roms); +public: + static ROM::Request rom_request(Personality personality); + Machine(Personality personality, const ROM::Map &roms); - /*! - Sets the serial bus to which this drive should attach itself. - */ - void set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus); + /*! + Sets the serial bus to which this drive should attach itself. + */ + void set_serial_bus(Commodore::Serial::Bus &); - /// Advances time. - void run_for(const Cycles cycles); + /// Advances time. + void run_for(Cycles); - /// Inserts @c disk into the drive. - void set_disk(std::shared_ptr disk); + /// Inserts @c disk into the drive. + void set_disk(std::shared_ptr disk); }; } diff --git a/Machines/Commodore/1540/Implementation/C1540.cpp b/Machines/Commodore/1540/Implementation/C1540.cpp index 6ec47298d..9a1d8ef95 100644 --- a/Machines/Commodore/1540/Implementation/C1540.cpp +++ b/Machines/Commodore/1540/Implementation/C1540.cpp @@ -27,16 +27,15 @@ ROM::Request Machine::rom_request(Personality personality) { MachineBase::MachineBase(Personality personality, const ROM::Map &roms) : Storage::Disk::Controller(1000000), m6502_(*this), - serial_port_VIA_port_handler_(new SerialPortVIA(serial_port_VIA_)), - serial_port_(new SerialPort), + serial_port_VIA_port_handler_(serial_port_VIA_), drive_VIA_(drive_VIA_port_handler_), - serial_port_VIA_(*serial_port_VIA_port_handler_) { + serial_port_VIA_(serial_port_VIA_port_handler_) { // attach the serial port to its VIA and vice versa - serial_port_->set_serial_port_via(serial_port_VIA_port_handler_); - serial_port_VIA_port_handler_->set_serial_port(serial_port_); + serial_port_.set_serial_port_via(serial_port_VIA_port_handler_); + serial_port_VIA_port_handler_.set_serial_port(serial_port_); // set this instance as the delegate to receive interrupt requests from both VIAs - serial_port_VIA_port_handler_->set_interrupt_delegate(this); + serial_port_VIA_port_handler_.set_interrupt_delegate(this); drive_VIA_port_handler_.set_interrupt_delegate(this); drive_VIA_port_handler_.set_delegate(this); @@ -64,8 +63,8 @@ MachineBase::MachineBase(Personality personality, const ROM::Map &roms) : Machine::Machine(Personality personality, const ROM::Map &roms) : MachineBase(personality, roms) {} -void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) { - Commodore::Serial::AttachPortAndBus(serial_port_, serial_bus); +void Machine::set_serial_bus(Commodore::Serial::Bus &serial_bus) { + Commodore::Serial::attach(serial_port_, serial_bus); } Cycles MachineBase::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { @@ -174,14 +173,11 @@ uint8_t SerialPortVIA::get_port_input(MOS::MOS6522::Port port) { void SerialPortVIA::set_port_output(MOS::MOS6522::Port port, uint8_t value, uint8_t) { if(port) { - std::shared_ptr<::Commodore::Serial::Port> serialPort = serial_port_.lock(); - if(serialPort) { - attention_acknowledge_level_ = !(value&0x10); - data_level_output_ = (value&0x02); + attention_acknowledge_level_ = !(value&0x10); + data_level_output_ = (value&0x02); - serialPort->set_output(::Commodore::Serial::Line::Clock, ::Commodore::Serial::LineLevel(!(value&0x08))); - update_data_line(); - } + serial_port_->set_output(::Commodore::Serial::Line::Clock, ::Commodore::Serial::LineLevel(!(value&0x08))); + update_data_line(); } } @@ -199,17 +195,14 @@ void SerialPortVIA::set_serial_line_state(::Commodore::Serial::Line line, bool v } } -void SerialPortVIA::set_serial_port(const std::shared_ptr<::Commodore::Serial::Port> &serialPort) { - serial_port_ = serialPort; +void SerialPortVIA::set_serial_port(Commodore::Serial::Port &port) { + serial_port_ = &port; } void SerialPortVIA::update_data_line() { - std::shared_ptr<::Commodore::Serial::Port> serialPort = serial_port_.lock(); - if(serialPort) { - // "ATN (Attention) is an input on pin 3 of P2 and P3 that is sensed at PB7 and CA1 of UC3 after being inverted by UA1" - serialPort->set_output(::Commodore::Serial::Line::Data, - ::Commodore::Serial::LineLevel(!data_level_output_ && (attention_level_input_ != attention_acknowledge_level_))); - } + // "ATN (Attention) is an input on pin 3 of P2 and P3 that is sensed at PB7 and CA1 of UC3 after being inverted by UA1" + serial_port_->set_output(::Commodore::Serial::Line::Data, + Serial::LineLevel(!data_level_output_ && (attention_level_input_ != attention_acknowledge_level_))); } // MARK: - DriveVIA @@ -281,11 +274,10 @@ void DriveVIA::set_activity_observer(Activity::Observer *observer) { // MARK: - SerialPort -void SerialPort::set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) { - std::shared_ptr serialPortVIA = serial_port_VIA_.lock(); - if(serialPortVIA) serialPortVIA->set_serial_line_state(line, bool(level)); +void SerialPort::set_input(Serial::Line line, Serial::LineLevel level) { + serial_port_VIA_->set_serial_line_state(line, bool(level)); } -void SerialPort::set_serial_port_via(const std::shared_ptr &serialPortVIA) { - serial_port_VIA_ = serialPortVIA; +void SerialPort::set_serial_port_via(SerialPortVIA &serialPortVIA) { + serial_port_VIA_ = &serialPortVIA; } diff --git a/Machines/Commodore/1540/Implementation/C1540Base.hpp b/Machines/Commodore/1540/Implementation/C1540Base.hpp index 774afb0a5..91f5da817 100644 --- a/Machines/Commodore/1540/Implementation/C1540Base.hpp +++ b/Machines/Commodore/1540/Implementation/C1540Base.hpp @@ -46,12 +46,12 @@ public: void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t mask); void set_serial_line_state(::Commodore::Serial::Line, bool); - void set_serial_port(const std::shared_ptr<::Commodore::Serial::Port> &); + void set_serial_port(Commodore::Serial::Port &); private: MOS::MOS6522::MOS6522 &via_; uint8_t port_b_ = 0x0; - std::weak_ptr<::Commodore::Serial::Port> serial_port_; + Commodore::Serial::Port *serial_port_ = nullptr; bool attention_acknowledge_level_ = false; bool attention_level_input_ = true; bool data_level_output_ = false; @@ -84,7 +84,7 @@ public: }; void set_delegate(Delegate *); - uint8_t get_port_input(MOS::MOS6522::Port port); + uint8_t get_port_input(MOS::MOS6522::Port); void set_sync_detected(bool); void set_data_input(uint8_t); @@ -95,7 +95,7 @@ public: void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t direction_mask); - void set_activity_observer(Activity::Observer *observer); + void set_activity_observer(Activity::Observer *); private: uint8_t port_b_ = 0xff, port_a_ = 0xff; @@ -111,11 +111,11 @@ private: */ class SerialPort : public ::Commodore::Serial::Port { public: - void set_input(::Commodore::Serial::Line, ::Commodore::Serial::LineLevel); - void set_serial_port_via(const std::shared_ptr &); + void set_input(Commodore::Serial::Line, Commodore::Serial::LineLevel); + void set_serial_port_via(SerialPortVIA &); private: - std::weak_ptr serial_port_VIA_; + SerialPortVIA *serial_port_VIA_ = nullptr; }; class MachineBase: @@ -125,37 +125,37 @@ class MachineBase: public Storage::Disk::Controller { public: - MachineBase(Personality personality, const ROM::Map &roms); - - // to satisfy CPU::MOS6502::Processor - Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value); - - // to satisfy MOS::MOS6522::Delegate - virtual void mos6522_did_change_interrupt_status(void *mos6522); - - // to satisfy DriveVIA::Delegate - void drive_via_did_step_head(void *driveVIA, int direction); - void drive_via_did_set_data_density(void *driveVIA, int density); + MachineBase(Personality, const ROM::Map &); /// Attaches the activity observer to this C1540. - void set_activity_observer(Activity::Observer *observer); + void set_activity_observer(Activity::Observer *); + + // to satisfy CPU::MOS6502::Processor + Cycles perform_bus_operation(CPU::MOS6502::BusOperation, uint16_t address, uint8_t *value); protected: + // to satisfy MOS::MOS6522::Delegate + void mos6522_did_change_interrupt_status(void *mos6522) override; + + // to satisfy DriveVIA::Delegate + void drive_via_did_step_head(void *driveVIA, int direction) override; + void drive_via_did_set_data_density(void *driveVIA, int density) override; + CPU::MOS6502::Processor m6502_; uint8_t ram_[0x800]; uint8_t rom_[0x4000]; - std::shared_ptr serial_port_VIA_port_handler_; - std::shared_ptr serial_port_; + SerialPortVIA serial_port_VIA_port_handler_; + SerialPort serial_port_; DriveVIA drive_VIA_port_handler_; MOS::MOS6522::MOS6522 drive_VIA_; MOS::MOS6522::MOS6522 serial_port_VIA_; int shift_register_ = 0, bit_window_offset_; - virtual void process_input_bit(int value); - virtual void process_index_hole(); + void process_input_bit(int value) override; + void process_index_hole() override; }; } diff --git a/Machines/Commodore/Plus4/Interrupts.hpp b/Machines/Commodore/Plus4/Interrupts.hpp index a493a3449..5eb2b408e 100644 --- a/Machines/Commodore/Plus4/Interrupts.hpp +++ b/Machines/Commodore/Plus4/Interrupts.hpp @@ -24,7 +24,6 @@ public: return delegate_; } - enum Flag { Timer3 = 0x40, Timer2 = 0x10, diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index b550d5257..5d0ea1ddb 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -181,11 +181,11 @@ public: *value = io_direction_; // printf("Read data direction: %02x\n", *value); } else { - const uint8_t all_inputs = tape_player_->input() ? 0x10 : 0x00; + const uint8_t all_inputs = (tape_player_->input() ? 0x00 : 0x10) | 0xe0; *value = (io_direction_ & io_output_) | ((~io_direction_) & all_inputs); -// printf("Read input: %02x\n", *value); + printf("[%04x] In: %02x\n", m6502_.value_of(CPU::MOS6502::Register::ProgramCounter), *value); } } else { if(!address) { @@ -193,7 +193,7 @@ public: // printf("Set data direction: %02x\n", *value); } else { io_output_ = *value; -// printf("Output: %02x\n", *value); + printf("[%04x] Out: %02x\n", m6502_.value_of(CPU::MOS6502::Register::ProgramCounter), *value); // tape_player_->set_motor_control(*value & 0x08); tape_player_->set_motor_control(!(*value & 0x08)); } @@ -210,7 +210,11 @@ public: // Miscellaneous hardware. All TODO. if(isReadOperation(operation)) { // printf("TODO: read @ %04x\n", address); - *value = 0x00; + if((address & 0xfff0) == 0xfd10) { + *value = 0xff ^ 0x4; // Seems to detect the play button. + } else { + *value = 0xff; + } } else { // printf("TODO: write of %02x @ %04x\n", *value, address); } diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index 79eef817b..54bf1d937 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -15,50 +15,53 @@ using namespace Commodore::Serial; const char *::Commodore::Serial::to_string(Line line) { switch(line) { - case ServiceRequest: return "Service request"; - case Attention: return "Attention"; - case Clock: return "Clock"; - case Data: return "Data"; - case Reset: return "Reset"; + case Line::ServiceRequest: return "Service request"; + case Line::Attention: return "Attention"; + case Line::Clock: return "Clock"; + case Line::Data: return "Data"; + case Line::Reset: return "Reset"; default: return nullptr; } } -void ::Commodore::Serial::AttachPortAndBus(std::shared_ptr port, std::shared_ptr bus) { - port->set_serial_bus(bus); - bus->add_port(port); +const char *::Commodore::Serial::to_string(LineLevel level) { + switch(level) { + case LineLevel::High : return "high"; + case LineLevel::Low : return "low"; + default: return nullptr; + } } -void Bus::add_port(std::shared_ptr port) { - ports_.push_back(port); - for(int line = int(ServiceRequest); line <= int(Reset); line++) { - // the addition of a new device may change the line output... +void ::Commodore::Serial::attach(Port &port, Bus &bus) { + port.set_bus(bus); + bus.add_port(port); +} + +void Bus::add_port(Port &port) { + ports_.push_back(&port); + for(int line = int(Line::ServiceRequest); line <= int(Line::Reset); line++) { + // The addition of a new device may change the line output... set_line_output_did_change(Line(line)); - // ... but the new device will need to be told the current state regardless - port->set_input(Line(line), line_levels_[line]); + // ... but the new device will need to be told the current state regardless. + port.set_input(Line(line), line_levels_[line]); } } void Bus::set_line_output_did_change(Line line) { - // i.e. I believe these lines to be open collector - LineLevel new_line_level = High; - for(std::weak_ptr port : ports_) { - std::shared_ptr locked_port = port.lock(); - if(locked_port) { - new_line_level = (LineLevel)(bool(new_line_level) & bool(locked_port->get_output(line))); - } + // Treat lines as open collector. + auto new_line_level = LineLevel::High; + for(auto port : ports_) { + new_line_level = LineLevel(bool(new_line_level) & bool(port->get_output(line))); } - // post an update only if one occurred - if(new_line_level != line_levels_[line]) { - line_levels_[line] = new_line_level; + // Post an update only if one occurred. + const auto index = size_t(line); + if(new_line_level != line_levels_[index]) { + line_levels_[index] = new_line_level; - for(std::weak_ptr port : ports_) { - std::shared_ptr locked_port = port.lock(); - if(locked_port) { - locked_port->set_input(line, new_line_level); - } + for(auto port : ports_) { + port->set_input(line, new_line_level); } } } @@ -66,14 +69,15 @@ void Bus::set_line_output_did_change(Line line) { // MARK: - The debug port void DebugPort::set_input(Line line, LineLevel value) { - input_levels_[line] = value; + const auto index = size_t(line); + input_levels_[index] = value; - std::cout << "[Bus] " << StringForLine(line) << " is " << (value ? "high" : "low"); + std::cout << "[Bus] " << to_string(line) << " is " << to_string(value); if(!incoming_count_) { - incoming_count_ = (!input_levels_[Line::Clock] && !input_levels_[Line::Data]) ? 8 : 0; + incoming_count_ = (!input_levels_[size_t(Line::Clock)] && !input_levels_[size_t(Line::Data)]) ? 8 : 0; } else { if(line == Line::Clock && value) { - incoming_byte_ = (incoming_byte_ >> 1) | (input_levels_[Line::Data] ? 0x80 : 0x00); + incoming_byte_ = (incoming_byte_ >> 1) | (input_levels_[size_t(Line::Data)] ? 0x80 : 0x00); } incoming_count_--; if(incoming_count_ == 0) std::cout << "[Bus] Observed value " << std::hex << int(incoming_byte_); diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 25dabd522..c8bdfd4e4 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -23,7 +23,7 @@ enum class Line { }; const char *to_string(Line line); -enum class LineLevel: bool { +enum LineLevel: bool { High = true, Low = false }; @@ -44,29 +44,29 @@ void attach(Port &port, Bus &bus); levels to every port. */ class Bus { - public: - Bus() : line_levels_{ - LineLevel::High, - LineLevel::High, - LineLevel::High, - LineLevel::High, - LineLevel::High - } {} +public: + Bus() : line_levels_{ + LineLevel::High, + LineLevel::High, + LineLevel::High, + LineLevel::High, + LineLevel::High + } {} - /*! - Adds the supplied port to the bus. - */ - void add_port(Port &port); + /*! + Adds the supplied port to the bus. + */ + void add_port(Port &port); - /*! - Communicates to the bus that one of its attached port has changed its output level for the given line. - The bus will therefore recalculate bus state and propagate as necessary. - */ - void set_line_output_did_change(Line line); + /*! + Communicates to the bus that one of its attached port has changed its output level for the given line. + The bus will therefore recalculate bus state and propagate as necessary. + */ + void set_line_output_did_change(Line line); - private: - LineLevel line_levels_[5]; - std::vector ports_; +private: + LineLevel line_levels_[5]; + std::vector ports_; }; /*! @@ -74,63 +74,63 @@ class Bus { expects to be subclassed in order for specific port-housing devices to deal with input. */ class Port { - public: - Port() : line_levels_{ - LineLevel::High, - LineLevel::High, - LineLevel::High, - LineLevel::High, - LineLevel::High - } {} - virtual ~Port() = default; +public: + Port() : line_levels_{ + LineLevel::High, + LineLevel::High, + LineLevel::High, + LineLevel::High, + LineLevel::High + } {} + virtual ~Port() = default; - /*! - Sets the current level of an output line on this serial port. - */ - void set_output(Line line, LineLevel level) { - if(line_levels_[size_t(line)] != level) { - line_levels_[size_t(line)] = level; - if(serial_bus_) serial_bus_->set_line_output_did_change(line); - } + /*! + Sets the current level of an output line on this serial port. + */ + void set_output(Line line, LineLevel level) { + if(line_levels_[size_t(line)] != level) { + line_levels_[size_t(line)] = level; + if(serial_bus_) serial_bus_->set_line_output_did_change(line); } + } - /*! - Gets the previously set level of an output line. - */ - LineLevel get_output(Line line) { - return line_levels_[size_t(line)]; - } + /*! + Gets the previously set level of an output line. + */ + LineLevel get_output(Line line) { + return line_levels_[size_t(line)]; + } - /*! - Called by the bus to signal a change in any input line level. Subclasses should implement this. - */ - virtual void set_input(Line line, LineLevel value) = 0; + /*! + Called by the bus to signal a change in any input line level. Subclasses should implement this. + */ + virtual void set_input(Line line, LineLevel value) = 0; - /*! - Sets the supplied serial bus as that to which line levels will be communicated. - */ - inline void set_bus(Bus &serial_bus) { - serial_bus_ = &serial_bus; - } + /*! + Sets the supplied serial bus as that to which line levels will be communicated. + */ + inline void set_bus(Bus &serial_bus) { + serial_bus_ = &serial_bus; + } - private: - Bus *serial_bus_ = nullptr; - LineLevel line_levels_[5]; +private: + Bus *serial_bus_ = nullptr; + LineLevel line_levels_[5]; }; /*! A debugging port, which makes some attempt to log bus activity. Incomplete. TODO: complete. */ class DebugPort: public Port { - public: - void set_input(Line line, LineLevel value); +public: + void set_input(Line line, LineLevel value); - DebugPort() : incoming_count_(0) {} + DebugPort() : incoming_count_(0) {} - private: - uint8_t incoming_byte_; - int incoming_count_; - LineLevel input_levels_[5]; +private: + uint8_t incoming_byte_; + int incoming_count_; + LineLevel input_levels_[5]; }; } diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index e7f9e9eb9..1a6982345 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -105,14 +105,13 @@ public: void set_port_output(const MOS::MOS6522::Port port, const uint8_t value, uint8_t) { // Line 7 of port A is inverted and output as serial ATN. if(!port) { - std::shared_ptr<::Commodore::Serial::Port> serialPort = serial_port_.lock(); - if(serialPort) serialPort->set_output(::Commodore::Serial::Line::Attention, (::Commodore::Serial::LineLevel)!(value&0x80)); + serial_port_->set_output(Serial::Line::Attention, Serial::LineLevel(!(value&0x80))); } } /// Sets @serial_port as this VIA's connection to the serial bus. - void set_serial_port(std::shared_ptr<::Commodore::Serial::Port> serial_port) { - serial_port_ = serial_port; + void set_serial_port(Serial::Port &serial_port) { + serial_port_ = &serial_port; } /// Sets @tape as the tape player connected to this VIA. @@ -122,7 +121,7 @@ public: private: uint8_t port_a_; - std::weak_ptr<::Commodore::Serial::Port> serial_port_; + Serial::Port *serial_port_ = nullptr; std::shared_ptr tape_; }; @@ -171,14 +170,11 @@ public: /// Called by the 6522 to set control line output. Which affects the serial port. void set_control_line_output(const MOS::MOS6522::Port port, const MOS::MOS6522::Line line, const bool value) { if(line == MOS::MOS6522::Line::Two) { - std::shared_ptr<::Commodore::Serial::Port> serialPort = serial_port_.lock(); - if(serialPort) { - // CB2 is inverted to become serial data; CA2 is inverted to become serial clock - if(port == MOS::MOS6522::Port::A) - serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!value); - else - serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)!value); - } + // CB2 is inverted to become serial data; CA2 is inverted to become serial clock + if(port == MOS::MOS6522::Port::A) + serial_port_->set_output(Serial::Line::Clock, Serial::LineLevel(!value)); + else + serial_port_->set_output(Serial::Line::Data, Serial::LineLevel(!value)); } } @@ -190,15 +186,15 @@ public: } /// Sets the serial port to which this VIA is connected. - void set_serial_port(std::shared_ptr<::Commodore::Serial::Port> serialPort) { - serial_port_ = serialPort; + void set_serial_port(Serial::Port &port) { + serial_port_ = &port; } private: uint8_t port_b_; uint8_t columns_[8]; uint8_t activation_mask_; - std::weak_ptr<::Commodore::Serial::Port> serial_port_; + Serial::Port *serial_port_ = nullptr; }; /*! @@ -208,17 +204,16 @@ class SerialPort : public ::Commodore::Serial::Port { public: /// Receives an input change from the base serial port class, and communicates it to the user-port VIA. void set_input(const ::Commodore::Serial::Line line, const ::Commodore::Serial::LineLevel level) { - std::shared_ptr userPortVIA = user_port_via_.lock(); - if(userPortVIA) userPortVIA->set_serial_line_state(line, bool(level)); + if(user_port_via_) user_port_via_->set_serial_line_state(line, bool(level)); } /// Sets the user-port VIA with which this serial port communicates. - void set_user_port_via(const std::shared_ptr userPortVIA) { - user_port_via_ = userPortVIA; + void set_user_port_via(UserPortVIA &via) { + user_port_via_ = &via; } private: - std::weak_ptr user_port_via_; + UserPortVIA *user_port_via_ = nullptr; }; /*! @@ -293,32 +288,28 @@ public: ConcreteMachine(const Analyser::Static::Commodore::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : m6502_(*this), mos6560_(mos6560_bus_handler_), - user_port_via_port_handler_(new UserPortVIA), - keyboard_via_port_handler_(new KeyboardVIA), - serial_port_(new SerialPort), - serial_bus_(new ::Commodore::Serial::Bus), - user_port_via_(*user_port_via_port_handler_), - keyboard_via_(*keyboard_via_port_handler_), + user_port_via_(user_port_via_port_handler_), + keyboard_via_(keyboard_via_port_handler_), tape_(new Storage::Tape::BinaryTapePlayer(1022727)) { // communicate the tape to the user-port VIA - user_port_via_port_handler_->set_tape(tape_); + user_port_via_port_handler_.set_tape(tape_); // wire up the serial bus and serial port - Commodore::Serial::AttachPortAndBus(serial_port_, serial_bus_); + Commodore::Serial::attach(serial_port_, serial_bus_); // wire up 6522s and serial port - user_port_via_port_handler_->set_serial_port(serial_port_); - keyboard_via_port_handler_->set_serial_port(serial_port_); - serial_port_->set_user_port_via(user_port_via_port_handler_); + user_port_via_port_handler_.set_serial_port(serial_port_); + keyboard_via_port_handler_.set_serial_port(serial_port_); + serial_port_.set_user_port_via(user_port_via_port_handler_); // wire up the 6522s, tape and machine - user_port_via_port_handler_->set_interrupt_delegate(this); - keyboard_via_port_handler_->set_interrupt_delegate(this); + user_port_via_port_handler_.set_interrupt_delegate(this); + keyboard_via_port_handler_.set_interrupt_delegate(this); tape_->set_delegate(this); tape_->set_clocking_hint_observer(this); // Install a joystick. - joysticks_.emplace_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_)); + joysticks_.emplace_back(new Joystick(user_port_via_port_handler_, keyboard_via_port_handler_)); ROM::Request request(ROM::Name::Vic20BASIC); ROM::Name kernel, character; @@ -472,7 +463,7 @@ public: void set_key_state(const uint16_t key, const bool is_pressed) final { if(key < 0xfff0) { - keyboard_via_port_handler_->set_key_state(key, is_pressed); + keyboard_via_port_handler_.set_key_state(key, is_pressed); } else { switch(key) { case KeyRestore: @@ -480,8 +471,8 @@ public: break; #define ShiftedMap(source, target) \ case source: \ - keyboard_via_port_handler_->set_key_state(KeyLShift, is_pressed); \ - keyboard_via_port_handler_->set_key_state(target, is_pressed); \ + keyboard_via_port_handler_.set_key_state(KeyLShift, is_pressed); \ + keyboard_via_port_handler_.set_key_state(target, is_pressed); \ break; ShiftedMap(KeyUp, KeyDown); @@ -496,7 +487,7 @@ public: } void clear_all_keys() final { - keyboard_via_port_handler_->clear_all_keys(); + keyboard_via_port_handler_.clear_all_keys(); } const std::vector> &get_joysticks() final { @@ -741,10 +732,10 @@ private: Cycles cycles_since_mos6560_update_; Vic6560BusHandler mos6560_bus_handler_; MOS::MOS6560::MOS6560 mos6560_; - std::shared_ptr user_port_via_port_handler_; - std::shared_ptr keyboard_via_port_handler_; - std::shared_ptr serial_port_; - std::shared_ptr<::Commodore::Serial::Bus> serial_bus_; + UserPortVIA user_port_via_port_handler_; + KeyboardVIA keyboard_via_port_handler_; + SerialPort serial_port_; + Serial::Bus serial_bus_; MOS::MOS6522::MOS6522 user_port_via_; MOS::MOS6522::MOS6522 keyboard_via_; @@ -760,7 +751,7 @@ private: } // Disk - std::shared_ptr<::Commodore::C1540::Machine> c1540_; + std::unique_ptr<::Commodore::C1540::Machine> c1540_; }; }