2018-02-27 03:04:34 +00:00
|
|
|
//
|
|
|
|
// SN76489.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 26/02/2018.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2018 Thomas Harte. All rights reserved.
|
2018-02-27 03:04:34 +00:00
|
|
|
//
|
|
|
|
|
2024-01-17 04:34:46 +00:00
|
|
|
#pragma once
|
2018-02-27 03:04:34 +00:00
|
|
|
|
2024-02-09 19:25:40 +00:00
|
|
|
#include "../../Outputs/Speaker/Implementation/BufferSource.hpp"
|
2018-02-27 03:04:34 +00:00
|
|
|
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
|
|
|
|
|
|
|
namespace TI {
|
|
|
|
|
2024-02-09 19:25:40 +00:00
|
|
|
class SN76489: public Outputs::Speaker::BufferSource<SN76489, false> {
|
2018-02-27 03:04:34 +00:00
|
|
|
public:
|
2018-03-01 03:36:03 +00:00
|
|
|
enum class Personality {
|
|
|
|
SN76489,
|
|
|
|
SN76494,
|
|
|
|
SMS
|
|
|
|
};
|
|
|
|
|
2018-02-27 03:04:34 +00:00
|
|
|
/// Creates a new SN76489.
|
2022-07-16 18:41:04 +00:00
|
|
|
SN76489(Personality personality, Concurrency::AsyncTaskQueue<false> &task_queue, int additional_divider = 1);
|
2018-02-27 03:04:34 +00:00
|
|
|
|
|
|
|
/// Writes a new value to the SN76489.
|
2020-01-05 18:40:02 +00:00
|
|
|
void write(uint8_t value);
|
2018-02-28 03:25:12 +00:00
|
|
|
|
|
|
|
// As per SampleSource.
|
2024-02-12 15:55:52 +00:00
|
|
|
template <Outputs::Speaker::Action action>
|
|
|
|
void apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target);
|
2020-05-09 21:57:21 +00:00
|
|
|
bool is_zero_level() const;
|
2018-03-09 18:23:18 +00:00
|
|
|
void set_sample_volume_range(std::int16_t range);
|
2018-02-27 03:04:34 +00:00
|
|
|
|
|
|
|
private:
|
2018-03-01 03:36:03 +00:00
|
|
|
int master_divider_ = 0;
|
|
|
|
int master_divider_period_ = 16;
|
|
|
|
int16_t output_volume_ = 0;
|
2018-02-28 03:25:12 +00:00
|
|
|
void evaluate_output_volume();
|
|
|
|
int volumes_[16];
|
|
|
|
|
2022-07-16 18:41:04 +00:00
|
|
|
Concurrency::AsyncTaskQueue<false> &task_queue_;
|
2018-02-28 03:25:12 +00:00
|
|
|
|
|
|
|
struct ToneChannel {
|
|
|
|
// Programmatically-set state; updated by the processor.
|
|
|
|
uint16_t divider = 0;
|
|
|
|
uint8_t volume = 0xf;
|
|
|
|
|
|
|
|
// Active state; self-evolving as a function of time.
|
|
|
|
uint16_t counter = 0;
|
|
|
|
int level = 0;
|
|
|
|
} channels_[4];
|
|
|
|
enum {
|
|
|
|
Periodic15,
|
|
|
|
Periodic16,
|
|
|
|
Noise15,
|
|
|
|
Noise16
|
|
|
|
} noise_mode_ = Periodic15;
|
|
|
|
uint16_t noise_shifter_ = 0;
|
|
|
|
int active_register_ = 0;
|
|
|
|
|
|
|
|
bool shifter_is_16bit_ = false;
|
2018-02-27 03:04:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|