mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-20 10:17:05 +00:00
66 lines
1.4 KiB
C++
66 lines
1.4 KiB
C++
//
|
|
// Header.hpp
|
|
// Clock Signal
|
|
//
|
|
// Created by Thomas Harte on 30/10/2025.
|
|
// Copyright © 2025 Thomas Harte. All rights reserved.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
|
|
namespace Acorn::Tube {
|
|
|
|
template <size_t length, typename ULAT>
|
|
struct FIFO {
|
|
FIFO(ULAT &ula, const uint8_t mask = 0x00) : ula_(ula), mask_(mask) {}
|
|
|
|
/// @returns b7 set exactly if this FIFO is not empty.
|
|
uint8_t data_available() const {
|
|
return read_ != write_ ? 0x80 : 0x00;
|
|
}
|
|
|
|
/// @returns b6 set exactly if this FIFO is not full.
|
|
uint8_t not_full() const {
|
|
return size_t(write_ - read_) < length ? 0x40 : 0x00;
|
|
}
|
|
|
|
/// Adds a value to the FIFO, notifying the ULA if this would cause the FIFO to
|
|
/// transition from empty to not-empty. The ULA will be supplied with this FIFO's
|
|
/// mask as specified at construction.
|
|
void write(const uint8_t value) {
|
|
if(write_ - read_ == length) return;
|
|
if(write_ == read_) {
|
|
ula_.fifo_has_data(mask_);
|
|
}
|
|
buffer_[(write_++) % length] = value;
|
|
}
|
|
|
|
/// Removes a value from the FIFO.
|
|
uint8_t read() {
|
|
const uint8_t result = buffer_[read_ % length];
|
|
if(write_ != read_) ++read_;
|
|
if(write_ == read_) {
|
|
ula_.fifo_is_empty(mask_);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// Empties the FIFO.
|
|
void reset() {
|
|
read_ = write_ = 0;
|
|
ula_.fifo_is_empty(mask_);
|
|
}
|
|
|
|
private:
|
|
ULAT &ula_;
|
|
uint8_t mask_;
|
|
std::array<uint8_t, length> buffer_;
|
|
uint32_t read_ = 0;
|
|
uint32_t write_ = 0;
|
|
};
|
|
|
|
}
|