2021-07-18 15:36:13 +00:00
|
|
|
//
|
|
|
|
// 6526.h
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 18/07/2021.
|
|
|
|
// Copyright © 2021 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef _526_h
|
|
|
|
#define _526_h
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
2021-07-18 16:23:47 +00:00
|
|
|
#include "Implementation/6526Storage.hpp"
|
2021-11-05 01:54:28 +00:00
|
|
|
#include "../Serial/Line.hpp"
|
2021-07-18 16:23:47 +00:00
|
|
|
|
2023-05-10 21:02:18 +00:00
|
|
|
namespace MOS::MOS6526 {
|
2021-07-18 15:36:13 +00:00
|
|
|
|
2021-07-18 21:17:41 +00:00
|
|
|
enum Port {
|
|
|
|
A = 0,
|
|
|
|
B = 1
|
|
|
|
};
|
2021-07-18 15:36:13 +00:00
|
|
|
|
2021-07-18 21:17:41 +00:00
|
|
|
struct PortHandler {
|
2021-07-19 00:25:04 +00:00
|
|
|
/// Requests the current input value of @c port from the port handler.
|
|
|
|
uint8_t get_port_input([[maybe_unused]] Port port) {
|
|
|
|
return 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets the current output value of @c port; any bits marked as input will be supplied as 1s.
|
2021-07-18 21:17:41 +00:00
|
|
|
void set_port_output([[maybe_unused]] Port port, [[maybe_unused]] uint8_t value) {}
|
2021-07-18 15:36:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class Personality {
|
|
|
|
// The 6526, used in machines such as the C64, has a BCD time-of-day clock.
|
2021-07-18 15:49:10 +00:00
|
|
|
P6526,
|
2021-07-18 15:36:13 +00:00
|
|
|
// The 8250, used in the Amiga, provides a binary time-of-day clock.
|
2021-07-18 15:49:10 +00:00
|
|
|
P8250,
|
2021-07-18 15:36:13 +00:00
|
|
|
};
|
|
|
|
|
2021-07-18 16:23:47 +00:00
|
|
|
template <typename PortHandlerT, Personality personality> class MOS6526:
|
2021-11-07 13:18:54 +00:00
|
|
|
private MOS6526Storage,
|
|
|
|
private Serial::Line<true>::ReadDelegate
|
2021-07-18 16:23:47 +00:00
|
|
|
{
|
2021-07-18 15:36:13 +00:00
|
|
|
public:
|
2021-11-07 13:18:54 +00:00
|
|
|
MOS6526(PortHandlerT &port_handler) noexcept : port_handler_(port_handler) {
|
|
|
|
serial_input.set_read_delegate(this);
|
|
|
|
}
|
2021-07-18 15:49:10 +00:00
|
|
|
MOS6526(const MOS6526 &) = delete;
|
|
|
|
|
2021-07-18 15:36:13 +00:00
|
|
|
/// Writes @c value to the register at @c address. Only the low two bits of the address are decoded.
|
|
|
|
void write(int address, uint8_t value);
|
|
|
|
|
|
|
|
/// Fetches the value of the register @c address. Only the low two bits of the address are decoded.
|
|
|
|
uint8_t read(int address);
|
2021-07-18 15:49:10 +00:00
|
|
|
|
2021-07-24 01:24:07 +00:00
|
|
|
/// Pulses Phi2 to advance by the specified number of half cycles.
|
2021-07-18 15:49:10 +00:00
|
|
|
void run_for(const HalfCycles half_cycles);
|
|
|
|
|
2021-07-24 01:24:07 +00:00
|
|
|
/// Pulses the TOD input the specified number of times.
|
|
|
|
void advance_tod(int count);
|
|
|
|
|
2021-07-28 23:36:30 +00:00
|
|
|
/// @returns @c true if the interrupt output is active, @c false otherwise.
|
|
|
|
bool get_interrupt_line();
|
|
|
|
|
2021-08-04 02:19:41 +00:00
|
|
|
/// Sets the current state of the CNT input.
|
|
|
|
void set_cnt_input(bool active);
|
|
|
|
|
2021-11-06 23:54:20 +00:00
|
|
|
/// Provides both the serial input bit and an additional source of CNT.
|
|
|
|
Serial::Line<true> serial_input;
|
2021-11-05 01:54:28 +00:00
|
|
|
|
2021-10-09 11:08:59 +00:00
|
|
|
/// Sets the current state of the FLG input.
|
|
|
|
void set_flag_input(bool low);
|
|
|
|
|
2021-07-18 15:49:10 +00:00
|
|
|
private:
|
|
|
|
PortHandlerT &port_handler_;
|
2021-08-03 22:50:58 +00:00
|
|
|
TODStorage<personality == Personality::P8250> tod_;
|
2021-07-18 21:17:41 +00:00
|
|
|
|
|
|
|
template <int port> void set_port_output();
|
2021-07-19 00:25:04 +00:00
|
|
|
template <int port> uint8_t get_port_input();
|
2021-07-22 20:09:32 +00:00
|
|
|
void update_interrupts();
|
2021-07-24 01:58:52 +00:00
|
|
|
void posit_interrupt(uint8_t mask);
|
2021-08-01 22:14:10 +00:00
|
|
|
void advance_counters(int);
|
2021-11-07 13:18:54 +00:00
|
|
|
|
|
|
|
bool serial_line_did_produce_bit(Serial::Line<true> *line, int bit) final;
|
2021-07-18 15:36:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "Implementation/6526Implementation.hpp"
|
|
|
|
|
|
|
|
#endif /* _526_h */
|