58 #ifndef YM2413NUKEYKT_HH
59 #define YM2413NUKEYKT_HH
71 void reset()
override;
72 void writePort(
bool port, uint8_t value,
int cycle_offset)
override;
73 void pokeReg(uint8_t reg, uint8_t value)
override;
74 [[nodiscard]] uint8_t
peekReg(uint8_t reg)
const override;
77 void setSpeed(
double speed)
override;
79 template<
typename Archive>
80 void serialize(Archive& ar,
unsigned version);
90 using bool_2 = std::array<bool, 2>;
91 using int8_t_2 = std::array<int8_t, 2>;
92 using uint8_t_2 = std::array<uint8_t, 2>;
94 constexpr Patch() =
default;
95 constexpr Patch(uint8_t tl_, uint8_t dcm_, uint8_t fb_,
96 bool_2 am_, bool_2 vib_, bool_2 et_, bool_2 ksr_, uint8_t_2 multi_,
97 uint8_t_2 ksl_, uint8_t_2 ar_, uint8_t_2 dr_, uint8_t_2 sl_, uint8_t_2 rr_)
98 : dcm(dcm_), vib(vib_), et(et_), sl(sl_) {
105 setMulti(0, multi_[0]);
106 setMulti(1, multi_[1]);
117 constexpr
void setTL(uint8_t tl) { tl2 = 2 * tl; }
118 constexpr
void setFB(uint8_t fb) { fb_t = fb ? (8 - fb) : 31; }
119 constexpr
void setAM(
int i,
bool am) { am_t[i] = am ? -1 : 0; }
120 constexpr
void setKSR(
int i,
bool ksr) { ksr_t[i] = ksr ? 0 : 2; }
121 constexpr
void setMulti(
int i, uint8_t multi) {
122 constexpr uint8_t PG_MULTI[16] = {
123 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
125 multi_t[i] = PG_MULTI[multi];
127 constexpr
void setKSL(
int i, uint8_t ksl) { ksl_t[i] = ksl ? (3 - ksl) : 31; }
128 constexpr
void setAR (
int i, uint8_t ar) { ar4[i] = 4 * ar; }
129 constexpr
void setDR (
int i, uint8_t dr) { dr4[i] = 4 * dr; }
130 constexpr
void setRR (
int i, uint8_t rr) { rr4[i] = 4 * rr; }
135 int8_t_2 am_t = {0, 0};
136 bool_2 vib = {
false,
false};
137 bool_2 et = {
false,
false};
138 uint8_t_2 ksr_t = {2, 2};
139 uint8_t_2 multi_t = {1, 1};
140 uint8_t_2 ksl_t = {31, 31};
141 uint8_t_2 ar4 = {0, 0};
142 uint8_t_2 dr4 = {0, 0};
143 uint8_t_2 sl = {0, 0};
144 uint8_t_2 rr4 = {0, 0};
157 template<
typename Archive>
158 void serialize(Archive& ar,
unsigned version);
162 template<
bool TEST_MODE>
NEVER_INLINE void step18(
float* out[9 + 5]);
163 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void step(Locals& l);
165 template<u
int32_t CYCLES>
ALWAYS_INLINE uint32_t phaseCalcIncrement(
const Patch& patch1)
const;
166 template<u
int32_t CYCLES>
ALWAYS_INLINE void channelOutput(
float* out[9 + 5], int32_t ch_out);
167 template<u
int32_t CYCLES>
ALWAYS_INLINE const Patch& preparePatch1(
bool use_rm_patches)
const;
168 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE uint32_t getPhase(uint8_t& rm_hh_bits);
169 template<u
int32_t CYCLES>
ALWAYS_INLINE bool keyOnEvent()
const;
170 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void incrementPhase(uint32_t phase_incr,
bool prev_rhythm);
171 template<u
int32_t CYCLES>
ALWAYS_INLINE uint32_t getPhaseMod(uint8_t fb_t);
172 template<u
int32_t CYCLES>
ALWAYS_INLINE void doOperator(
float* out[9 + 5],
bool eg_silent);
173 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE uint8_t envelopeOutput(uint32_t ksltl, int8_t am_t)
const;
174 template<u
int32_t CYCLES>
ALWAYS_INLINE uint32_t envelopeKSLTL(
const Patch& patch1,
bool use_rm_patches)
const;
175 template<u
int32_t CYCLES>
ALWAYS_INLINE void envelopeTimer1();
176 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void envelopeTimer2(
bool& eg_timer_carry);
177 template<u
int32_t CYCLES>
ALWAYS_INLINE bool envelopeGenerate1();
178 template<u
int32_t CYCLES>
ALWAYS_INLINE void envelopeGenerate2(
const Patch& patch1,
bool use_rm_patches);
179 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void doLFO(
bool& lfo_am_car);
180 template<u
int32_t CYCLES,
bool TEST_MODE>
ALWAYS_INLINE void doRhythm();
185 void doRegWrite(uint8_t block, uint8_t channel, uint8_t data);
186 NEVER_INLINE void doIO(uint32_t cycles_plus_1, Write& write);
188 void doModeWrite(uint8_t address, uint8_t value);
189 void changeFnumBlock(uint32_t ch);
192 static const Patch m_patches[15];
193 static const Patch r_patches[ 6];
199 uint8_t write_address;
200 uint8_t write_fm_cycle;
201 bool fast_fm_rewrite;
202 bool test_mode_active;
205 const uint8_t* attackPtr;
206 const uint8_t* releasePtr;
210 uint8_t eg_counter_state;
211 uint8_t eg_timer_shift;
212 uint8_t eg_timer_shift_lock;
213 uint8_t eg_timer_lock;
215 uint8_t eg_level[18];
220 bool eg_timer_shift_stop;
223 uint32_t pg_phase[18];
229 uint16_t op_phase[2];
232 uint16_t lfo_counter;
233 uint16_t lfo_am_counter;
234 uint8_t lfo_vib_counter;
245 uint8_t p_ksr_freq[9];
249 const Patch* p_inst[9];
252 Patch patches[1 + 15];
269 int allowed_offset = 0;
270 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 reset() override
Reset this YM2413 core.
void generateChannels(float *out[9+5], uint32_t n) override