1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-24 05:18:36 +00:00
Files
2025-08-30 00:09:38 -04:00

75 lines
1.7 KiB
C++

//
// Tape.hpp
// Clock Signal
//
// Created by Thomas Harte on 03/12/2016.
// Copyright 2016 Thomas Harte. All rights reserved.
//
#pragma once
#include <cstdint>
#include "ClockReceiver/ClockReceiver.hpp"
#include "Storage/Tape/Tape.hpp"
#include "Storage/Tape/Parsers/Acorn.hpp"
#include "Interrupts.hpp"
namespace Electron {
class Tape:
public Storage::Tape::TapePlayer,
public Storage::Tape::Acorn::Shifter::Delegate {
public:
Tape();
void run_for(const Cycles cycles);
using Storage::Tape::TapePlayer::run_for;
uint8_t get_data_register();
void set_data_register(uint8_t value);
void set_counter(uint8_t value);
inline uint8_t get_interrupt_status() { return interrupt_status_; }
void clear_interrupts(uint8_t interrupts);
struct Delegate {
virtual void tape_did_change_interrupt_status(Tape &) = 0;
};
inline void set_delegate(Delegate *delegate) { delegate_ = delegate; }
inline void set_is_running(bool is_running) { is_running_ = is_running; }
inline void set_is_enabled(bool is_enabled) { is_enabled_ = is_enabled; }
void set_is_in_input_mode(bool is_in_input_mode);
void acorn_shifter_output_bit(int value) override;
private:
void process(const Storage::Tape::Pulse &pulse) override;
inline void push_tape_bit(uint16_t bit);
inline void get_next_tape_pulse();
struct {
int minimum_bits_until_full = 0;
} input_;
struct {
unsigned int cycles_into_pulse = 0;
unsigned int bits_remaining_until_empty = 0;
} output_;
bool is_running_ = false;
bool is_enabled_ = false;
bool is_in_input_mode_ = false;
inline void evaluate_interrupts();
uint16_t data_register_ = 0;
uint8_t interrupt_status_ = 0;
uint8_t last_posted_interrupt_status_ = 0;
Delegate *delegate_ = nullptr;
::Storage::Tape::Acorn::Shifter shifter_;
};
}