2018-01-07 01:15:55 +00:00
|
|
|
//
|
|
|
|
// KonamiSCC.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 06/01/2018.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2018 Thomas Harte. All rights reserved.
|
2018-01-07 01:15:55 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef KonamiSCC_hpp
|
|
|
|
#define KonamiSCC_hpp
|
|
|
|
|
|
|
|
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
|
|
|
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
|
|
|
|
|
|
|
namespace Konami {
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Provides an emulation of Konami's Sound Creative Chip ('SCC').
|
|
|
|
|
|
|
|
The SCC is a primitive wavetable synthesis chip, offering 32-sample tables,
|
|
|
|
and five channels of output. The original SCC uses the same wave for channels
|
|
|
|
four and five, the SCC+ supports different waves for the two channels.
|
|
|
|
*/
|
|
|
|
class SCC: public ::Outputs::Speaker::SampleSource {
|
|
|
|
public:
|
|
|
|
/// Creates a new SCC.
|
|
|
|
SCC(Concurrency::DeferringAsyncTaskQueue &task_queue);
|
|
|
|
|
|
|
|
/// As per ::SampleSource; provides a broadphase test for silence.
|
2018-03-03 18:08:33 +00:00
|
|
|
bool is_zero_level();
|
2018-01-07 01:15:55 +00:00
|
|
|
|
|
|
|
/// As per ::SampleSource; provides audio output.
|
|
|
|
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
2018-03-09 18:23:18 +00:00
|
|
|
void set_sample_volume_range(std::int16_t range);
|
2018-01-07 01:15:55 +00:00
|
|
|
|
|
|
|
/// Writes to the SCC.
|
|
|
|
void write(uint16_t address, uint8_t value);
|
|
|
|
|
|
|
|
/// Reads from the SCC.
|
|
|
|
uint8_t read(uint16_t address);
|
|
|
|
|
|
|
|
private:
|
2018-01-07 04:15:42 +00:00
|
|
|
Concurrency::DeferringAsyncTaskQueue &task_queue_;
|
|
|
|
|
|
|
|
// State from here on down is accessed ony from the audio thread.
|
|
|
|
int master_divider_ = 0;
|
2018-03-09 18:23:18 +00:00
|
|
|
std::int16_t master_volume_ = 0;
|
|
|
|
int16_t transient_output_level_ = 0;
|
2018-01-07 04:15:42 +00:00
|
|
|
|
2018-01-07 01:15:55 +00:00
|
|
|
struct Channel {
|
|
|
|
int period = 0;
|
|
|
|
int amplitude = 0;
|
2018-01-07 04:15:42 +00:00
|
|
|
|
|
|
|
int tone_counter = 0;
|
|
|
|
int offset = 0;
|
2018-01-07 01:15:55 +00:00
|
|
|
} channels_[5];
|
|
|
|
|
|
|
|
struct Wavetable {
|
2018-01-07 04:15:42 +00:00
|
|
|
std::uint8_t samples[32];
|
2018-01-07 01:15:55 +00:00
|
|
|
} waves_[4];
|
|
|
|
|
|
|
|
std::uint8_t channel_enable_ = 0;
|
|
|
|
std::uint8_t test_register_ = 0;
|
|
|
|
|
2018-01-07 04:15:42 +00:00
|
|
|
void evaluate_output_volume();
|
|
|
|
|
|
|
|
// This keeps a copy of wave memory that is accessed from the
|
|
|
|
// main emulation thread.
|
|
|
|
std::uint8_t ram_[128];
|
2018-01-07 01:15:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* KonamiSCC_hpp */
|