diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 9cf63d746..051f609ef 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -33,15 +33,18 @@ enum Line { class PortHandler { public: /// Requests the current input value of the named port from the port handler. - uint8_t get_port_input(Port) { + template + uint8_t get_port_input() const { return 0xff; } /// Sets the current output value of the named oprt and provides @c direction_mask, indicating which pins are marked as output. - void set_port_output(Port, [[maybe_unused]] uint8_t value, [[maybe_unused]] uint8_t direction_mask) {} + template + void set_port_output([[maybe_unused]] uint8_t value, [[maybe_unused]] uint8_t direction_mask) {} /// Sets the current logical output level for the named line on the specified port. - void set_control_line_output(Port, Line, [[maybe_unused]] bool value) {} + template + void set_control_line_output([[maybe_unused]] bool value) {} /// Sets the current logical value of the interrupt line. void set_interrupt_status([[maybe_unused]] bool status) {} @@ -101,7 +104,8 @@ public: BusHandlerT &bus_handler(); /// Sets the input value of the named line and port. - void set_control_line_input(Port, Line, bool value); + template + void set_control_line_input(bool value); /// Runs for a specified number of half cycles. void run_for(const HalfCycles); @@ -126,12 +130,13 @@ private: void access(int address); - uint8_t get_port_input(Port port, uint8_t output_mask, uint8_t output, uint8_t timer_mask); + template uint8_t get_port_input(uint8_t output_mask, uint8_t output, uint8_t timer_mask); + template void update_pcr(const uint8_t); inline void reevaluate_interrupts(); /// Sets the current intended output value for the port and line; /// if this affects the visible output, it will be passed to the handler. - void set_control_line_output(Port port, Line line, LineState value); + template void set_control_line_output(LineState); void evaluate_cb2_output(); void evaluate_port_b_output(); }; diff --git a/Components/6522/Implementation/6522Implementation.hpp b/Components/6522/Implementation/6522Implementation.hpp index a4ddfd4df..ccca7a2dd 100644 --- a/Components/6522/Implementation/6522Implementation.hpp +++ b/Components/6522/Implementation/6522Implementation.hpp @@ -19,7 +19,7 @@ template void MOS6522::access(const int address) { case 0x0: // In both handshake and pulse modes, CB2 goes low on any read or write of Port B. if(handshake_modes_[1] != HandshakeMode::None) { - set_control_line_output(Port::B, Line::Two, LineState::Off); + set_control_line_output(LineState::Off); } break; @@ -27,7 +27,7 @@ template void MOS6522::access(const int address) { case 0x1: // In both handshake and pulse modes, CA2 goes low on any read or write of Port A. if(handshake_modes_[0] != HandshakeMode::None) { - set_control_line_output(Port::A, Line::Two, LineState::Off); + set_control_line_output(LineState::Off); } break; } @@ -55,10 +55,10 @@ template void MOS6522::write(int address, const uint8_t value) { registers_.output[0] = value; bus_handler_.run_for(time_since_bus_handler_call_.flush()); - bus_handler_.set_port_output(Port::A, value, registers_.data_direction[0]); + bus_handler_.template set_port_output(value, registers_.data_direction[0]); if(handshake_modes_[1] != HandshakeMode::None) { - set_control_line_output(Port::A, Line::Two, LineState::Off); + set_control_line_output(LineState::Off); } registers_.interrupt_flags &= ~( @@ -132,45 +132,11 @@ template void MOS6522::write(int address, const uint8_t value) { } evaluate_port_b_output(); break; - case 0xc: { // Peripheral control ('PCR'). -// const auto old_peripheral_control = registers_.peripheral_control; + case 0xc: // Peripheral control ('PCR'). registers_.peripheral_control = value; - - int shift = 0; - for(int port = 0; port < 2; ++port) { - handshake_modes_[port] = HandshakeMode::None; - switch((value >> shift) & 0x0e) { - default: break; - - case 0x00: // Negative interrupt input; set Cx2 interrupt on negative Cx2 transition, clear on access to Port x register. - case 0x02: // Independent negative interrupt input; set Cx2 interrupt on negative transition, don't clear automatically. - case 0x04: // Positive interrupt input; set Cx2 interrupt on positive Cx2 transition, clear on access to Port x register. - case 0x06: // Independent positive interrupt input; set Cx2 interrupt on positive transition, don't clear automatically. - set_control_line_output(Port(port), Line::Two, LineState::Input); - break; - - case 0x08: // Handshake: set Cx2 to low on any read or write of Port x; set to high on an active transition of Cx1. - handshake_modes_[port] = HandshakeMode::Handshake; - set_control_line_output(Port(port), Line::Two, LineState::Off); // At a guess. - break; - - case 0x0a: // Pulse output: Cx2 is low for one cycle following a read or write of Port x. - handshake_modes_[port] = HandshakeMode::Pulse; - set_control_line_output(Port(port), Line::Two, LineState::On); - break; - - case 0x0c: // Manual output: Cx2 low. - set_control_line_output(Port(port), Line::Two, LineState::Off); - break; - - case 0x0e: // Manual output: Cx2 high. - set_control_line_output(Port(port), Line::Two, LineState::On); - break; - } - - shift += 4; - } - } break; + update_pcr(value); + update_pcr(value >> 4); + break; // Interrupt control case 0xd: // Interrupt flag regiser ('IFR'). @@ -187,6 +153,40 @@ template void MOS6522::write(int address, const uint8_t value) { } } +template +template +void MOS6522::update_pcr(const uint8_t value) { + handshake_modes_[port] = HandshakeMode::None; + switch(value & 0x0e) { + default: break; + + case 0x00: // Negative interrupt input; set Cx2 interrupt on negative Cx2 transition, clear on access to Port x register. + case 0x02: // Independent negative interrupt input; set Cx2 interrupt on negative transition, don't clear automatically. + case 0x04: // Positive interrupt input; set Cx2 interrupt on positive Cx2 transition, clear on access to Port x register. + case 0x06: // Independent positive interrupt input; set Cx2 interrupt on positive transition, don't clear automatically. + set_control_line_output(LineState::Input); + break; + + case 0x08: // Handshake: set Cx2 to low on any read or write of Port x; set to high on an active transition of Cx1. + handshake_modes_[port] = HandshakeMode::Handshake; + set_control_line_output(LineState::Off); // At a guess. + break; + + case 0x0a: // Pulse output: Cx2 is low for one cycle following a read or write of Port x. + handshake_modes_[port] = HandshakeMode::Pulse; + set_control_line_output(LineState::On); + break; + + case 0x0c: // Manual output: Cx2 low. + set_control_line_output(LineState::Off); + break; + + case 0x0e: // Manual output: Cx2 high. + set_control_line_output(LineState::On); + break; + } +} + template uint8_t MOS6522::read(int address) { address &= 0xf; access(address); @@ -194,12 +194,12 @@ template uint8_t MOS6522::read(int address) { case 0x0: // Read Port B ('IRB'). registers_.interrupt_flags &= ~(InterruptFlag::CB1ActiveEdge | InterruptFlag::CB2ActiveEdge); reevaluate_interrupts(); - return get_port_input(Port::B, registers_.data_direction[1], registers_.output[1], registers_.auxiliary_control & 0x80); + return get_port_input(registers_.data_direction[1], registers_.output[1], registers_.auxiliary_control & 0x80); case 0xf: case 0x1: // Read Port A ('IRA'). registers_.interrupt_flags &= ~(InterruptFlag::CA1ActiveEdge | InterruptFlag::CA2ActiveEdge); reevaluate_interrupts(); - return get_port_input(Port::A, registers_.data_direction[0], registers_.output[0], 0); + return get_port_input(registers_.data_direction[0], registers_.output[0], 0); case 0x2: return registers_.data_direction[1]; // Port B direction ('DDRB'). case 0x3: return registers_.data_direction[0]; // Port A direction ('DDRA'). @@ -236,14 +236,15 @@ template uint8_t MOS6522::read(int address) { return 0xff; } -template uint8_t MOS6522::get_port_input( - const Port port, +template +template +uint8_t MOS6522::get_port_input( const uint8_t output_mask, uint8_t output, const uint8_t timer_mask ) { bus_handler_.run_for(time_since_bus_handler_call_.flush()); - const uint8_t input = bus_handler_.get_port_input(port); + const uint8_t input = bus_handler_.template get_port_input(); output = (output & ~timer_mask) | (registers_.timer_port_b_output & timer_mask); return (input & ~output_mask) | (output & output_mask); } @@ -263,13 +264,15 @@ template void MOS6522::reevaluate_interrupts() { } } -template void MOS6522::set_control_line_input(const Port port, const Line line, const bool value) { +template +template +void MOS6522::set_control_line_input(const bool value) { switch(line) { case Line::One: if(value != control_inputs_[port].lines[line]) { // In handshake mode, any transition on C[A/B]1 sets output high on C[A/B]2. if(handshake_modes_[port] == HandshakeMode::Handshake) { - set_control_line_output(port, Line::Two, LineState::On); + set_control_line_output(LineState::On); } // Set the proper transition interrupt bit if enabled. @@ -332,10 +335,10 @@ template void MOS6522::do_phase2() { // In pulse modes, CA2 and CB2 go high again on the next clock edge. if(handshake_modes_[1] == HandshakeMode::Pulse) { - set_control_line_output(Port::B, Line::Two, LineState::On); + set_control_line_output(LineState::On); } if(handshake_modes_[0] == HandshakeMode::Pulse) { - set_control_line_output(Port::A, Line::Two, LineState::On); + set_control_line_output(LineState::On); } // If the shift register is shifting according to the input clock, do a shift. @@ -388,8 +391,7 @@ template void MOS6522::do_phase1() { template void MOS6522::evaluate_port_b_output() { // Apply current timer-linked PB7 output if any atop the stated output. const uint8_t timer_control_bit = registers_.auxiliary_control & 0x80; - bus_handler_.set_port_output( - Port::B, + bus_handler_.template set_port_output( (registers_.output[1] & (0xff ^ timer_control_bit)) | timer_control_bit, registers_.data_direction[1] | timer_control_bit); } @@ -448,19 +450,20 @@ template void MOS6522::evaluate_cb2_output() { // Shift register is enabled, one way or the other; but announce only output. if(is_shifting_out()) { // Output mode; set the level according to the current top of the shift register. - bus_handler_.set_control_line_output(Port::B, Line::Two, !!(registers_.shift & 0x80)); + bus_handler_.template set_control_line_output(registers_.shift & 0x80); } else { // Input mode. - bus_handler_.set_control_line_output(Port::B, Line::Two, true); + bus_handler_.template set_control_line_output(true); } } else { // Shift register is disabled. - bus_handler_.set_control_line_output(Port::B, Line::Two, control_outputs_[1].lines[1] != LineState::Off); + bus_handler_.template set_control_line_output(control_outputs_[1].lines[1] != LineState::Off); } } template -void MOS6522::set_control_line_output(const Port port, const Line line, const LineState value) { +template +void MOS6522::set_control_line_output(const LineState value) { if(port == Port::B && line == Line::Two) { control_outputs_[port].lines[line] = value; evaluate_cb2_output(); @@ -474,7 +477,7 @@ void MOS6522::set_control_line_output(const Port port, const Line line, const if(value != LineState::Input) { bus_handler_.run_for(time_since_bus_handler_call_.flush()); - bus_handler_.set_control_line_output(port, line, value != LineState::Off); + bus_handler_.template set_control_line_output(value != LineState::Off); } } } diff --git a/Machines/Apple/AppleII/Mockingboard.hpp b/Machines/Apple/AppleII/Mockingboard.hpp index 306e9f202..402ee24cb 100644 --- a/Machines/Apple/AppleII/Mockingboard.hpp +++ b/Machines/Apple/AppleII/Mockingboard.hpp @@ -99,7 +99,8 @@ private: card.did_change_interrupt_flags(); } - void set_port_output(MOS::MOS6522::Port port, uint8_t value, uint8_t) { + template + void set_port_output(const uint8_t value, uint8_t) { if(port) { using ControlLines = GI::AY38910::ControlLines; ay.set_control_lines( @@ -116,7 +117,8 @@ private: } } - uint8_t get_port_input(MOS::MOS6522::Port port) { + template + uint8_t get_port_input() const { if(!port) { return ay.get_data_output(); } diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index a33dffed2..cf8ac6adc 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -579,7 +579,7 @@ private: time_since_video_update_ -= time_until_video_event_; time_until_video_event_ = video_.next_sequence_point(); - via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !video_.vsync()); + via_.template set_control_line_input(!video_.vsync()); } via_clock_ += via_cycles_outstanding; @@ -592,8 +592,8 @@ private: if(keyboard_clock_ >= KEYBOARD_CLOCK_RATE) { const auto keyboard_ticks = keyboard_clock_.divide(KEYBOARD_CLOCK_RATE); keyboard_.run_for(keyboard_ticks); - via_.set_control_line_input(MOS::MOS6522::Port::B, MOS::MOS6522::Line::Two, keyboard_.get_data()); - via_.set_control_line_input(MOS::MOS6522::Port::B, MOS::MOS6522::Line::One, keyboard_.get_clock()); + via_.template set_control_line_input(keyboard_.get_data()); + via_.template set_control_line_input(keyboard_.get_clock()); } // Feed mouse inputs within at most 1250 cycles of each other. @@ -616,8 +616,8 @@ private: while(ticks--) { clock_.update(); // TODO: leave a delay between toggling the input rather than using this coupled hack. - via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, true); - via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, false); + via_.template set_control_line_input(true); + via_.template set_control_line_input(false); } // Update the SCSI if currently active. @@ -645,7 +645,7 @@ private: using Port = MOS::MOS6522::Port; using Line = MOS::MOS6522::Line; - void set_port_output(Port port, uint8_t value, uint8_t) { + template void set_port_output(const uint8_t value, uint8_t) { /* Peripheral lines: keyboard data, interrupt configuration. (See p176 [/215]) @@ -691,7 +691,7 @@ private: } } - uint8_t get_port_input(Port port) { + template uint8_t get_port_input() const { switch(port) { case Port::A: // printf("6522 r A\n"); @@ -711,7 +711,7 @@ private: return 0xff; } - void set_control_line_output(Port port, Line line, bool value) { + template void set_control_line_output(const bool value) { /* Keyboard wiring (I believe): CB2 = data (input/output) diff --git a/Machines/Commodore/1540/Implementation/C1540.cpp b/Machines/Commodore/1540/Implementation/C1540.cpp index 47eed737e..80d729926 100644 --- a/Machines/Commodore/1540/Implementation/C1540.cpp +++ b/Machines/Commodore/1540/Implementation/C1540.cpp @@ -162,12 +162,14 @@ void MachineBase::drive_via_did_set_data_density(void *, const int density) { // MARK: - SerialPortVIA -uint8_t SerialPortVIA::get_port_input(MOS::MOS6522::Port port) { +template +uint8_t SerialPortVIA::get_port_input() const { if(port) return port_b_; return 0xff; } -void SerialPortVIA::set_port_output(MOS::MOS6522::Port port, uint8_t value, uint8_t) { +template +void SerialPortVIA::set_port_output(const uint8_t value, uint8_t) { if(port) { attention_acknowledge_level_ = !(value&0x10); data_level_output_ = (value&0x02); @@ -178,8 +180,8 @@ void SerialPortVIA::set_port_output(MOS::MOS6522::Port port, uint8_t value, uint } void SerialPortVIA::set_serial_line_state( - ::Commodore::Serial::Line line, - bool value, + const Commodore::Serial::Line line, + const bool value, MOS::MOS6522::MOS6522 &via ) { switch(line) { @@ -189,7 +191,7 @@ void SerialPortVIA::set_serial_line_state( case ::Commodore::Serial::Line::Attention: attention_level_input_ = !value; port_b_ = (port_b_ & ~0x80) | (value ? 0x00 : 0x80); - via.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !value); + via.set_control_line_input(!value); update_data_line(); break; } @@ -212,11 +214,12 @@ void DriveVIA::set_delegate(Delegate *delegate) { } // write protect tab uncovered -uint8_t DriveVIA::get_port_input(MOS::MOS6522::Port port) { +template +uint8_t DriveVIA::get_port_input() const { return port ? port_b_ : port_a_; } -void DriveVIA::set_sync_detected(bool sync_detected) { +void DriveVIA::set_sync_detected(const bool sync_detected) { port_b_ = (port_b_ & 0x7f) | (sync_detected ? 0x00 : 0x80); } @@ -232,13 +235,15 @@ bool DriveVIA::get_motor_enabled() { return drive_motor_; } -void DriveVIA::set_control_line_output(MOS::MOS6522::Port port, MOS::MOS6522::Line line, bool value) { +template +void DriveVIA::set_control_line_output(const bool value) { if(port == MOS::MOS6522::Port::A && line == MOS::MOS6522::Line::Two) { should_set_overflow_ = value; } } -void DriveVIA::set_port_output(MOS::MOS6522::Port port, uint8_t value, uint8_t) { +template +void DriveVIA::set_port_output(const uint8_t value, uint8_t) { if(port) { if(previous_port_b_output_ != value) { // Record drive motor state. diff --git a/Machines/Commodore/1540/Implementation/C1540Base.hpp b/Machines/Commodore/1540/Implementation/C1540Base.hpp index 690f1061c..1ca119b26 100644 --- a/Machines/Commodore/1540/Implementation/C1540Base.hpp +++ b/Machines/Commodore/1540/Implementation/C1540Base.hpp @@ -39,10 +39,13 @@ namespace Commodore::C1540 { */ class SerialPortVIA: public MOS::MOS6522::IRQDelegatePortHandler { public: - uint8_t get_port_input(MOS::MOS6522::Port); + template + uint8_t get_port_input() const; - void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t mask); - void set_serial_line_state(::Commodore::Serial::Line, bool, MOS::MOS6522::MOS6522 &); + template + void set_port_output(uint8_t value, uint8_t mask); + + void set_serial_line_state(Commodore::Serial::Line, bool, MOS::MOS6522::MOS6522 &); void set_serial_port(Commodore::Serial::Port &); @@ -81,16 +84,19 @@ public: }; void set_delegate(Delegate *); - uint8_t get_port_input(MOS::MOS6522::Port); + template + uint8_t get_port_input() const; void set_sync_detected(bool); void set_data_input(uint8_t); bool get_should_set_overflow(); bool get_motor_enabled(); - void set_control_line_output(MOS::MOS6522::Port, MOS::MOS6522::Line, bool value); + template + void set_control_line_output(bool value); - void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t direction_mask); + template + void set_port_output(uint8_t value, uint8_t direction_mask); void set_activity_observer(Activity::Observer *); diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 40be0f4b2..ec56babb6 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -104,7 +104,7 @@ public: /*! 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; + virtual void set_input(Line, LineLevel) = 0; /*! Sets the supplied serial bus as that to which line levels will be communicated. diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 00b8c0597..59d2d16b9 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -68,7 +68,7 @@ public: UserPortVIA() : port_a_(0xbf) {} /// Reports the current input to the 6522 port @c port. - uint8_t get_port_input(const MOS::MOS6522::Port port) const { + template uint8_t get_port_input() const { // Port A provides information about the presence or absence of a tape, and parts of // the joystick and serial port state, both of which have been statefully collected // into port_a_. @@ -79,7 +79,7 @@ public: } /// Receives announcements of control line output change from the 6522. - void set_control_line_output(const MOS::MOS6522::Port port, const MOS::MOS6522::Line line, const bool value) { + template void set_control_line_output(const bool value) { // The CA2 output is used to control the tape motor. if(port == MOS::MOS6522::Port::A && line == MOS::MOS6522::Line::Two) { tape_->set_motor_control(!value); @@ -87,7 +87,7 @@ public: } /// Receives announcements of changes in the serial bus connected to the serial port and propagates them into Port A. - void set_serial_line_state(const ::Commodore::Serial::Line line, const bool value) { + void set_serial_line_state(Commodore::Serial::Line line, const bool value) { switch(line) { default: break; case ::Commodore::Serial::Line::Data: port_a_ = (port_a_ & ~0x02) | (value ? 0x02 : 0x00); break; @@ -103,7 +103,7 @@ public: } /// Receives announcements from the 6522 of user-port output, which might affect what's currently being presented onto the serial bus. - void set_port_output(const MOS::MOS6522::Port port, const uint8_t value, uint8_t) { + template void set_port_output(const uint8_t value, uint8_t) { // Line 7 of port A is inverted and output as serial ATN. if(!port) { serial_port_->set_output(Serial::Line::Attention, Serial::LineLevel(!(value&0x80))); @@ -150,7 +150,7 @@ public: } /// Called by the 6522 to get input. Reads the keyboard on Port A, returns a small amount of joystick state on Port B. - uint8_t get_port_input(const MOS::MOS6522::Port port) const { + template uint8_t get_port_input() const { if(!port) { uint8_t result = 0xff; for(int c = 0; c < 8; c++) { @@ -164,12 +164,12 @@ public: } /// Called by the 6522 to set output. The value of Port B selects which part of the keyboard to read. - void set_port_output(const MOS::MOS6522::Port port, const uint8_t value, const uint8_t mask) { + template void set_port_output(const uint8_t value, const uint8_t mask) { if(port) activation_mask_ = (value & mask) | (~mask); } /// 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) { + template void set_control_line_output(const bool value) { if(line == MOS::MOS6522::Line::Two) { // CB2 is inverted to become serial data; CA2 is inverted to become serial clock if(port == MOS::MOS6522::Port::A) @@ -460,7 +460,7 @@ public: } else { switch(key) { case KeyRestore: - user_port_via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !is_pressed); + user_port_via_.set_control_line_input(!is_pressed); break; #define ShiftedMap(source, target) \ case source: \ @@ -685,7 +685,7 @@ public: } void tape_did_change_input(Storage::Tape::BinaryTapePlayer *const tape) final { - keyboard_via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !tape->input()); + keyboard_via_.set_control_line_input(!tape->input()); } KeyboardMapper *get_keyboard_mapper() final { diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 9d4aa63af..88c30a95a 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -193,7 +193,7 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler { Reponds to the 6522's control line output change signal; on an Oric A2 is connected to the AY's BDIR, and B2 is connected to the AY's A2. */ - void set_control_line_output(MOS::MOS6522::Port port, MOS::MOS6522::Line line, bool value) { + template void set_control_line_output(const bool value) { if(line) { if(port) ay_bdir_ = value; else ay_bc1_ = value; update_ay(); @@ -205,7 +205,7 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler { Reponds to changes in the 6522's port output. On an Oric port B sets the tape motor control and the keyboard's active row. Port A is connected to the AY's data bus. */ - void set_port_output(MOS::MOS6522::Port port, uint8_t value, uint8_t) { + template void set_port_output(uint8_t value, uint8_t) { if(port) { keyboard_.set_active_row(value); tape_player_.set_motor_control(value & 0x40); @@ -219,7 +219,7 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler { /*! Provides input data for the 6522. Port B reads the keyboard, and port A reads from the AY. */ - uint8_t get_port_input(MOS::MOS6522::Port port) { + template uint8_t get_port_input() const { if(port) { uint8_t column = ay8910_.get_port_output(false) ^ 0xff; return keyboard_.query_column(column) ? 0x08 : 0x00; @@ -630,8 +630,7 @@ template ( tape_player_.motor_control() ? !tape_player_.input() : !video_->vsync() @@ -811,7 +810,8 @@ using namespace Oric; namespace { -template std::unique_ptr machine(const Analyser::Static::Oric::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) { +template +std::unique_ptr machine(const Analyser::Static::Oric::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) { switch(target.disk_interface) { default: return std::make_unique>(target, rom_fetcher); case DiskInterface::Microdisc: return std::make_unique>(target, rom_fetcher);