From 4fc25fb7988f42456eebe03ab675433fd54c3297 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 7 Nov 2021 05:18:54 -0800 Subject: [PATCH] Adds basic shift input. --- Components/6526/6526.hpp | 9 +++++-- .../Implementation/6526Implementation.hpp | 26 ++++++++++++++++--- .../6526/Implementation/6526Storage.hpp | 1 + 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Components/6526/6526.hpp b/Components/6526/6526.hpp index 1a48ced32..99eb5e8e6 100644 --- a/Components/6526/6526.hpp +++ b/Components/6526/6526.hpp @@ -40,10 +40,13 @@ enum class Personality { }; template class MOS6526: - private MOS6526Storage + private MOS6526Storage, + private Serial::Line::ReadDelegate { public: - MOS6526(PortHandlerT &port_handler) noexcept : port_handler_(port_handler) {} + MOS6526(PortHandlerT &port_handler) noexcept : port_handler_(port_handler) { + serial_input.set_read_delegate(this); + } MOS6526(const MOS6526 &) = delete; /// Writes @c value to the register at @c address. Only the low two bits of the address are decoded. @@ -79,6 +82,8 @@ template class MOS6526: void update_interrupts(); void posit_interrupt(uint8_t mask); void advance_counters(int); + + bool serial_line_did_produce_bit(Serial::Line *line, int bit) final; }; } diff --git a/Components/6526/Implementation/6526Implementation.hpp b/Components/6526/Implementation/6526Implementation.hpp index f7e5bd619..f66734da2 100644 --- a/Components/6526/Implementation/6526Implementation.hpp +++ b/Components/6526/Implementation/6526Implementation.hpp @@ -120,6 +120,10 @@ void MOS6526::write(int address, uint8_t value) { case 14: counter_[0].template set_control(value); tod_.template set_control(value); + if(shifter_is_output_ != bool(value & 0x40)) { + shifter_is_output_ = value & 0x40; + shift_bits_ = 0; + } break; case 15: counter_[1].template set_control(value); @@ -173,9 +177,7 @@ uint8_t MOS6526::read(int address) { case 11: return tod_.template read<3>(); // Shift register. - case 12: - printf("TODO: read from shift register\n"); - break; + case 12: return shift_data_; default: printf("Unhandled 6526 read from %d\n", address); @@ -216,6 +218,24 @@ void MOS6526::advance_tod(int count) { } } +template +bool MOS6526::serial_line_did_produce_bit(Serial::Line *, int bit) { + // TODO: post CNT change; might affect timer. + + if(!shifter_is_output_) { + shift_register_ = uint8_t((shift_register_ << 1) | bit); + ++shift_bits_; + + if(shift_bits_ == 8) { + shift_bits_ = 0; + shift_data_ = shift_register_; + posit_interrupt(Interrupts::SerialPort); + } + } + + return true; +} + } } diff --git a/Components/6526/Implementation/6526Storage.hpp b/Components/6526/Implementation/6526Storage.hpp index 3f7b840be..7a3c2bf1b 100644 --- a/Components/6526/Implementation/6526Storage.hpp +++ b/Components/6526/Implementation/6526Storage.hpp @@ -189,6 +189,7 @@ struct MOS6526Storage { uint8_t shift_data_ = 0; uint8_t shift_register_ = 0; int shift_bits_ = 0; + bool shifter_is_output_ = false; struct Counter { uint16_t reload = 0;