openMSX
YM2413OriginalNukeYKT.cc
Go to the documentation of this file.
2#include "narrow.hh"
3#include "ranges.hh"
4#include "serialize.hh"
5#include "xrange.hh"
6#include <array>
7#include <cassert>
8
9namespace openmsx {
10namespace YM2413OriginalNukeYKT {
11
13{
14 reset();
15}
16
18{
20 ranges::fill(regs, 0);
21}
22
23void YM2413::generateChannels(std::span<float*, 9 + 5> out_, uint32_t n)
24{
25 std::array<float*, 9 + 5> out;
26 ranges::copy(out_, out);
27
28 auto f = [&] {
29 std::array<int32_t, 2> buf;
30 OPLL_Clock(&opll, buf.data());
31 switch (opll.cycles) {
32 case 0: *out[ 9]++ += narrow_cast<float>(buf[1] * 2); break;
33 case 1: *out[10]++ += narrow_cast<float>(buf[1] * 2); break;
34 case 2: *out[ 6]++ += narrow_cast<float>(buf[0]);
35 *out[11]++ += narrow_cast<float>(buf[1] * 2); break;
36 case 3: *out[ 7]++ += narrow_cast<float>(buf[0]);
37 *out[12]++ += narrow_cast<float>(buf[1] * 2); break;
38 case 4: *out[ 8]++ += narrow_cast<float>(buf[0]);
39 *out[13]++ += narrow_cast<float>(buf[1] * 2); break;
40 case 8: *out[ 0]++ += narrow_cast<float>(buf[0]); break;
41 case 9: *out[ 1]++ += narrow_cast<float>(buf[0]); break;
42 case 10: *out[ 2]++ += narrow_cast<float>(buf[0]); break;
43 case 14: *out[ 3]++ += narrow_cast<float>(buf[0]); break;
44 case 15: *out[ 4]++ += narrow_cast<float>(buf[0]); break;
45 case 16: *out[ 5]++ += narrow_cast<float>(buf[0]); break;
46 }
47 };
48
49 assert(n != 0);
50 for (auto& write : writes) {
51 if (write.port != uint8_t(-1)) {
52 OPLL_Write(&opll, write.port, write.value);
53 write.port = uint8_t(-1);
54 }
55 f();
56 }
57 repeat((n - 1) * 18, f);
58
59 allowed_offset = std::max<int>(0, allowed_offset - 18); // see writePort()
60}
61
62void YM2413::writePort(bool port, uint8_t value, int cycle_offset)
63{
64 // see comments in YM2413NukeYKT.cc
65 if (speedUpHack) [[unlikely]] {
66 while (cycle_offset < allowed_offset) [[unlikely]] {
67 float d = 0.0f;
68 std::array<float*, 9 + 5> dummy;
69 ranges::fill(dummy, &d);
70 generateChannels(dummy, 1);
71 }
72 allowed_offset = ((port ? 84 : 12) / 4) + cycle_offset;
73 }
74
75 writes[cycle_offset] = {port, value};
76
77 // only needed for peekReg()
78 if (port == 0) {
79 latch = value & 63;
80 } else {
81 regs[latch] = value;
82 }
83}
84
85void YM2413::pokeReg(uint8_t /*reg*/, uint8_t /*value*/)
86{
87 // not supported
88}
89
90uint8_t YM2413::peekReg(uint8_t reg) const
91{
92 return regs[reg & 63];
93}
94
96{
97 return 1.0f / 256.0f;
98}
99
100void YM2413::setSpeed(double speed)
101{
102 speedUpHack = speed > 1.0;
103}
104
105template<typename Archive>
106void YM2413::serialize(Archive& /*ar*/, unsigned /*version*/)
107{
108 // Not implemented
109}
110
111} // namespace OriginalNuke
112
116
117} // namespace openmsx
Abstract interface for the YM2413 core.
Definition YM2413Core.hh:28
void serialize(Archive &ar, unsigned version)
void generateChannels(std::span< float *, 9+5 > out, uint32_t n) override
void writePort(bool port, uint8_t value, int cycle_offset) override
Write to the YM2413 register/data port.
void pokeReg(uint8_t reg, uint8_t value) override
Write to a YM2413 register (for debug).
float getAmplificationFactor() const override
Returns normalization factor.
void setSpeed(double speed) override
Sets real-time speed factor (aka the openMSX 'speed' setting).
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
void reset() override
Reset this YM2413 core.
This file implemented 3 utility functions:
Definition Autofire.cc:11
constexpr void fill(ForwardRange &&range, const T &value)
Definition ranges.hh:305
auto copy(InputRange &&range, OutputIter out)
Definition ranges.hh:250
void OPLL_Reset(opll_t *chip, uint32_t chip_type)
Definition opll.cc:293
void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data)
Definition opll.cc:1101
void OPLL_Clock(opll_t *chip, int32_t *buffer)
Definition opll.cc:1062
@ opll_type_ym2413b
Definition opll.hh:31
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
#define REGISTER_POLYMORPHIC_INITIALIZER(BASE, CLASS, NAME)
uint32_t cycles
Definition opll.hh:82
uint8_t data
Definition opll.hh:95
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
Definition xrange.hh:147