CLK/Components/6522/Implementation/6522Storage.hpp

109 lines
2.5 KiB
C++

//
// 6522Storage.hpp
// Clock Signal
//
// Created by Thomas Harte on 04/09/2017.
// Copyright 2017 Thomas Harte. All rights reserved.
//
#pragma once
#include <cstdint>
namespace MOS::MOS6522 {
class MOS6522Storage {
protected:
// Phase toggle
bool is_phase2_ = false;
// The registers
struct Registers {
// "A low reset (RES) input clears all R6522 internal registers to logic 0"
uint8_t output[2] = {0, 0};
uint8_t input[2] = {0, 0};
uint8_t data_direction[2] = {0, 0};
uint16_t timer[2] = {0, 0};
uint16_t timer_latch[2] = {0, 0};
uint16_t last_timer[2] = {0, 0};
int next_timer[2] = {-1, -1};
uint8_t shift = 0;
uint8_t auxiliary_control = 0;
uint8_t peripheral_control = 0;
uint8_t interrupt_flags = 0;
uint8_t interrupt_enable = 0;
bool timer_needs_reload = false;
uint8_t timer_port_b_output = 0xff;
} registers_;
// Control state.
struct {
bool lines[2] = {false, false};
} control_inputs_[2];
enum class LineState {
On, Off, Input
};
struct {
LineState lines[2] = {LineState::Input, LineState::Input};
} control_outputs_[2];
enum class HandshakeMode {
None,
Handshake,
Pulse
} handshake_modes_[2] = { HandshakeMode::None, HandshakeMode::None };
bool timer_is_running_[2] = {false, false};
bool last_posted_interrupt_status_ = false;
int shift_bits_remaining_ = 8;
enum InterruptFlag: uint8_t {
CA2ActiveEdge = 1 << 0,
CA1ActiveEdge = 1 << 1,
ShiftRegister = 1 << 2,
CB2ActiveEdge = 1 << 3,
CB1ActiveEdge = 1 << 4,
Timer2 = 1 << 5,
Timer1 = 1 << 6,
};
enum class ShiftMode {
Disabled = 0,
InUnderT2 = 1,
InUnderPhase2 = 2,
InUnderCB1 = 3,
OutUnderT2FreeRunning = 4,
OutUnderT2 = 5,
OutUnderPhase2 = 6,
OutUnderCB1 = 7
};
bool timer1_is_controlling_pb7() const {
return registers_.auxiliary_control & 0x80;
}
bool timer1_is_continuous() const {
return registers_.auxiliary_control & 0x40;
}
bool is_shifting_out() const {
return registers_.auxiliary_control & 0x10;
}
int timer2_clock_decrement() const {
return 1 ^ ((registers_.auxiliary_control >> 5)&1);
}
int timer2_pb6_decrement() const {
return (registers_.auxiliary_control >> 5)&1;
}
ShiftMode shift_mode() const {
return ShiftMode((registers_.auxiliary_control >> 2) & 7);
}
bool portb_is_latched() const {
return registers_.auxiliary_control & 0x02;
}
bool port1_is_latched() const {
return registers_.auxiliary_control & 0x01;
}
};
}