1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Adds basic shift input.

This commit is contained in:
Thomas Harte 2021-11-07 05:18:54 -08:00
parent 941d9a46a2
commit 4fc25fb798
3 changed files with 31 additions and 5 deletions

View File

@ -40,10 +40,13 @@ enum class Personality {
};
template <typename PortHandlerT, Personality personality> class MOS6526:
private MOS6526Storage
private MOS6526Storage,
private Serial::Line<true>::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 <typename PortHandlerT, Personality personality> class MOS6526:
void update_interrupts();
void posit_interrupt(uint8_t mask);
void advance_counters(int);
bool serial_line_did_produce_bit(Serial::Line<true> *line, int bit) final;
};
}

View File

@ -120,6 +120,10 @@ void MOS6526<BusHandlerT, personality>::write(int address, uint8_t value) {
case 14:
counter_[0].template set_control<false>(value);
tod_.template set_control<false>(value);
if(shifter_is_output_ != bool(value & 0x40)) {
shifter_is_output_ = value & 0x40;
shift_bits_ = 0;
}
break;
case 15:
counter_[1].template set_control<true>(value);
@ -173,9 +177,7 @@ uint8_t MOS6526<BusHandlerT, personality>::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<BusHandlerT, personality>::advance_tod(int count) {
}
}
template <typename BusHandlerT, Personality personality>
bool MOS6526<BusHandlerT, personality>::serial_line_did_produce_bit(Serial::Line<true> *, 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;
}
}
}

View File

@ -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;