58#ifndef YM2413NUKEYKT_HH
59#define YM2413NUKEYKT_HH
72 void reset()
override;
73 void writePort(
bool port, uint8_t value,
int cycle_offset)
override;
74 void pokeReg(uint8_t reg, uint8_t value)
override;
75 [[nodiscard]] uint8_t
peekReg(uint8_t reg)
const override;
78 void setSpeed(
double speed)
override;
80 template<
typename Archive>
81 void serialize(Archive& ar,
unsigned version);
91 using bool_2 = std::array<bool, 2>;
92 using int8_t_2 = std::array<int8_t, 2>;
93 using uint8_t_2 = std::array<uint8_t, 2>;
95 constexpr Patch() =
default;
96 constexpr Patch(uint8_t tl_, uint8_t dcm_, uint8_t fb_,
97 bool_2 am_, bool_2 vib_, bool_2 et_, bool_2 ksr_, uint8_t_2 multi_,
98 uint8_t_2 ksl_, uint8_t_2 ar_, uint8_t_2 dr_, uint8_t_2 sl_, uint8_t_2 rr_)
99 : dcm(dcm_), vib(vib_), et(et_), sl(sl_) {
106 setMulti(0, multi_[0]);
107 setMulti(1, multi_[1]);
118 constexpr void setTL(uint8_t tl) { tl2 = 2 * tl; }
119 constexpr void setFB(uint8_t fb) { fb_t = fb ? (8 - fb) : 31; }
120 constexpr void setAM(
int i,
bool am) { am_t[i] = am ? -1 : 0; }
121 constexpr void setKSR(
int i,
bool ksr) { ksr_t[i] = ksr ? 0 : 2; }
122 constexpr void setMulti(
int i, uint8_t multi) {
123 constexpr std::array<uint8_t, 16> PG_MULTI = {
124 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
126 multi_t[i] = PG_MULTI[multi];
128 constexpr void setKSL(
int i, uint8_t ksl) { ksl_t[i] = ksl ? (3 - ksl) : 31; }
129 constexpr void setAR (
int i, uint8_t ar) { ar4[i] = 4 * ar; }
130 constexpr void setDR (
int i, uint8_t dr) { dr4[i] = 4 * dr; }
131 constexpr void setRR (
int i, uint8_t rr) { rr4[i] = 4 * rr; }
136 int8_t_2 am_t = {0, 0};
137 bool_2 vib = {
false,
false};
138 bool_2 et = {
false,
false};
139 uint8_t_2 ksr_t = {2, 2};
140 uint8_t_2 multi_t = {1, 1};
141 uint8_t_2 ksl_t = {31, 31};
142 uint8_t_2 ar4 = {0, 0};
143 uint8_t_2 dr4 = {0, 0};
144 uint8_t_2 sl = {0, 0};
145 uint8_t_2 rr4 = {0, 0};
148 Locals(std::span<float*, 9 + 5> out_) : out(out_) {}
150 std::span<float*, 9 + 5> out;
160 template<
typename Archive>
161 void serialize(Archive& ar,
unsigned version);
165 template<
bool TEST_MODE>
NEVER_INLINE void step18(std::span<float*, 9 + 5> out);
166 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void step(Locals& l);
168 template<u
int32_t CYCLES> [[nodiscard]]
ALWAYS_INLINE uint32_t phaseCalcIncrement(
const Patch& patch1)
const;
169 template<u
int32_t CYCLES>
ALWAYS_INLINE void channelOutput(std::span<float*, 9 + 5> out, int32_t ch_out);
170 template<u
int32_t CYCLES> [[nodiscard]]
ALWAYS_INLINE const Patch& preparePatch1(
bool use_rm_patches)
const;
171 template<u
int32_t CYCLES,
bool TEST_MODE> [[nodiscard]]
ALWAYS_INLINE uint32_t getPhase(uint8_t& rm_hh_bits);
172 template<u
int32_t CYCLES> [[nodiscard]]
ALWAYS_INLINE bool keyOnEvent()
const;
173 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void incrementPhase(uint32_t phase_incr,
bool prev_rhythm);
174 template<u
int32_t CYCLES> [[nodiscard]]
ALWAYS_INLINE uint32_t getPhaseMod(uint8_t fb_t);
175 template<u
int32_t CYCLES>
ALWAYS_INLINE void doOperator(std::span<float*, 9 + 5> out,
bool eg_silent);
176 template<u
int32_t CYCLES,
bool TEST_MODE> [[nodiscard]]
ALWAYS_INLINE uint8_t envelopeOutput(uint32_t ksltl, int8_t am_t)
const;
177 template<u
int32_t CYCLES> [[nodiscard]]
ALWAYS_INLINE uint32_t envelopeKSLTL(
const Patch& patch1,
bool use_rm_patches)
const;
178 template<u
int32_t CYCLES>
ALWAYS_INLINE void envelopeTimer1();
179 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void envelopeTimer2(
bool& eg_timer_carry);
180 template<u
int32_t CYCLES> [[nodiscard]]
ALWAYS_INLINE bool envelopeGenerate1();
181 template<u
int32_t CYCLES>
ALWAYS_INLINE void envelopeGenerate2(
const Patch& patch1,
bool use_rm_patches);
182 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void doLFO(
bool& lfo_am_car);
183 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void doRhythm();
188 void doRegWrite(uint8_t block, uint8_t channel, uint8_t data);
189 NEVER_INLINE void doIO(uint32_t cycles_plus_1, Write& write);
191 void doModeWrite(uint8_t address, uint8_t value);
192 void changeFnumBlock(uint32_t ch);
195 static const std::array<Patch, 15> m_patches;
196 static const std::array<Patch, 6> r_patches;
199 std::array<Write, 18> writes;
202 uint8_t write_address;
203 uint8_t write_fm_cycle;
204 bool fast_fm_rewrite;
205 bool test_mode_active;
208 std::span<const uint8_t, 64> attackPtr;
209 std::span<const uint8_t, 64> releasePtr;
211 std::array<uint8_t, 2> eg_sl;
212 std::array<uint8_t, 2> eg_out;
213 uint8_t eg_counter_state;
214 uint8_t eg_timer_shift;
215 uint8_t eg_timer_shift_lock;
216 uint8_t eg_timer_lock;
217 std::array<EgState, 18> eg_state;
218 std::array<uint8_t, 18> eg_level;
219 std::array<uint8_t, 2> eg_rate;
220 std::array<bool, 18> eg_dokon;
221 std::array<bool, 2> eg_kon;
222 std::array<bool, 2> eg_off;
223 bool eg_timer_shift_stop;
226 std::array<uint32_t, 18> pg_phase;
229 std::array<int16_t, 9> op_fb1;
230 std::array<int16_t, 9> op_fb2;
232 std::array<uint16_t, 2> op_phase;
235 uint16_t lfo_counter;
236 uint16_t lfo_am_counter;
237 uint8_t lfo_vib_counter;
244 std::array<uint16_t, 9> fnum;
245 std::array<uint8_t, 9> block;
246 std::array<uint8_t, 9> p_ksl;
247 std::array<uint16_t, 9> p_incr;
248 std::array<uint8_t, 9> p_ksr_freq;
249 std::array<uint8_t, 9> sk_on;
250 std::array<uint8_t, 9> vol8;
251 std::array<uint8_t, 9> inst;
252 std::array<const Patch*, 9> p_inst;
255 std::array<Patch, 1 + 15> patches;
256 std::array<uint8_t, 3> c_dcm;
269 std::array<uint8_t, 64> regs;
272 int allowed_offset = 0;
273 bool speedUpHack =
false;
Abstract interface for the YM2413 core.
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
void writePort(bool port, uint8_t value, int cycle_offset) override
Write to the YM2413 register/data port.
void setSpeed(double speed) override
Sets real-time speed factor (aka the openMSX 'speed' setting).
float getAmplificationFactor() const override
Returns normalization factor.
void pokeReg(uint8_t reg, uint8_t value) override
Write to a YM2413 register (for debug).
void serialize(Archive &ar, unsigned version)
void generateChannels(std::span< float *, 9+5 > out, uint32_t n) override
void reset() override
Reset this YM2413 core.