Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3rdparty/ymfm: sync to latest #13263

Merged
merged 2 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions 3rdparty/ymfm/src/ymfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <array>
#include <memory>
#include <string>
#include <vector>
Expand Down Expand Up @@ -109,17 +110,6 @@ inline int32_t clamp(int32_t value, int32_t minval, int32_t maxval)
}


//-------------------------------------------------
// array_size - return the size of an array
//-------------------------------------------------

template<typename ArrayType, int ArraySize>
constexpr uint32_t array_size(ArrayType (&array)[ArraySize])
{
return ArraySize;
}


//-------------------------------------------------
// count_leading_zeros - return the number of
// leading zeros in a 32-bit value; CPU-optimized
Expand Down Expand Up @@ -254,7 +244,8 @@ inline int16_t roundtrip_fp(int32_t value)

// apply the shift back and forth to zero out bits that are lost
exponent -= 1;
return (value >> exponent) << exponent;
int32_t mask = (1 << exponent) - 1;
return value & ~mask;
}


Expand Down Expand Up @@ -350,7 +341,7 @@ class ymfm_wavfile
{
// create file
char name[20];
sprintf(name, "wavlog-%02d.wav", m_index);
snprintf(&name[0], sizeof(name), "wavlog-%02d.wav", m_index);
FILE *out = fopen(name, "wb");

// make the wav file header
Expand Down Expand Up @@ -483,6 +474,8 @@ class ymfm_saved_state
class ymfm_engine_callbacks
{
public:
virtual ~ymfm_engine_callbacks() = default;

// timer callback; called by the interface when a timer fires
virtual void engine_timer_expired(uint32_t tnum) = 0;

Expand All @@ -504,6 +497,8 @@ class ymfm_interface
template<typename RegisterType> friend class fm_engine_base;

public:
virtual ~ymfm_interface() = default;

// the following functions must be implemented by any derived classes; the
// default implementations are sufficient for some minimal operation, but will
// likely need to be overridden to integrate with the outside world; they are
Expand Down
4 changes: 2 additions & 2 deletions 3rdparty/ymfm/src/ymfm_fm.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ class fm_channel
// assign operators
void assign(uint32_t index, fm_operator<RegisterType> *op)
{
assert(index < array_size(m_op));
assert(index < m_op.size());
m_op[index] = op;
if (op != nullptr)
op->set_choffs(m_choffs);
Expand Down Expand Up @@ -330,7 +330,7 @@ class fm_channel
uint32_t m_choffs; // channel offset in registers
int16_t m_feedback[2]; // feedback memory for operator 1
mutable int16_t m_feedback_in; // next input value for op 1 feedback (set in output)
fm_operator<RegisterType> *m_op[4]; // up to 4 operators
std::array<fm_operator<RegisterType> *, 4> m_op; // up to 4 operators
RegisterType &m_regs; // direct reference to registers
fm_engine_base<RegisterType> &m_owner; // reference to the owning engine
};
Expand Down
14 changes: 8 additions & 6 deletions 3rdparty/ymfm/src/ymfm_fm.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -839,12 +839,12 @@ void fm_channel<RegisterType>::save_restore(ymfm_saved_state &state)
template<class RegisterType>
void fm_channel<RegisterType>::keyonoff(uint32_t states, keyon_type type, uint32_t chnum)
{
for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++)
for (uint32_t opnum = 0; opnum < m_op.size(); opnum++)
if (m_op[opnum] != nullptr)
m_op[opnum]->keyonoff(bitfield(states, opnum), type);

if (debug::LOG_KEYON_EVENTS && ((debug::GLOBAL_FM_CHANNEL_MASK >> chnum) & 1) != 0)
for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++)
for (uint32_t opnum = 0; opnum < m_op.size(); opnum++)
if (m_op[opnum] != nullptr)
debug::log_keyon("%c%s\n", bitfield(states, opnum) ? '+' : '-', m_regs.log_keyon(m_choffs, m_op[opnum]->opoffs()).c_str());
}
Expand All @@ -860,7 +860,7 @@ bool fm_channel<RegisterType>::prepare()
uint32_t active_mask = 0;

// prepare all operators and determine if they are active
for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++)
for (uint32_t opnum = 0; opnum < m_op.size(); opnum++)
if (m_op[opnum] != nullptr)
if (m_op[opnum]->prepare())
active_mask |= 1 << opnum;
Expand All @@ -880,15 +880,15 @@ void fm_channel<RegisterType>::clock(uint32_t env_counter, int32_t lfo_raw_pm)
m_feedback[0] = m_feedback[1];
m_feedback[1] = m_feedback_in;

for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++)
for (uint32_t opnum = 0; opnum < m_op.size(); opnum++)
if (m_op[opnum] != nullptr)
m_op[opnum]->clock(env_counter, lfo_raw_pm);

/*
useful temporary code for envelope debugging
if (m_choffs == 0x101)
{
for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++)
for (uint32_t opnum = 0; opnum < m_op.size(); opnum++)
{
auto &op = *m_op[((opnum & 1) << 1) | ((opnum >> 1) & 1)];
printf(" %c%03X%c%c ",
Expand Down Expand Up @@ -1504,6 +1504,8 @@ void fm_engine_base<RegisterType>::update_timer(uint32_t tnum, uint32_t enable,
template<class RegisterType>
void fm_engine_base<RegisterType>::engine_timer_expired(uint32_t tnum)
{
assert(tnum == 0 || tnum == 1);

// update status
if (tnum == 0 && m_regs.enable_timer_a())
set_reset_status(STATUS_TIMERA, 0);
Expand All @@ -1515,7 +1517,7 @@ void fm_engine_base<RegisterType>::engine_timer_expired(uint32_t tnum)
for (uint32_t chnum = 0; chnum < CHANNELS; chnum++)
if (bitfield(RegisterType::CSM_TRIGGER_MASK, chnum))
{
m_channel[chnum]->keyonoff(1, KEYON_CSM, chnum);
m_channel[chnum]->keyonoff(0xf, KEYON_CSM, chnum);
m_modified_channels |= 1 << chnum;
}

Expand Down
1 change: 0 additions & 1 deletion 3rdparty/ymfm/src/ymfm_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,4 @@ class ym2149

}


#endif // YMFM_MISC_H
44 changes: 25 additions & 19 deletions 3rdparty/ymfm/src/ymfm_opl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,9 @@ std::string opl_registers_base<Revision>::log_keyon(uint32_t choffs, uint32_t op
uint32_t opnum = (opoffs & 31) - 2 * ((opoffs & 31) / 8) + 18 * bitfield(opoffs, 8);

char buffer[256];
char *end = &buffer[0];
int end = 0;

end += sprintf(end, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u",
end += snprintf(&buffer[end], sizeof(buffer) - end, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u",
chnum, opnum,
ch_block_freq(choffs),
ch_feedback(choffs),
Expand All @@ -405,25 +405,25 @@ std::string opl_registers_base<Revision>::log_keyon(uint32_t choffs, uint32_t op
op_eg_sustain(opoffs));

if (OUTPUTS > 1)
end += sprintf(end, " out=%c%c%c%c",
end += snprintf(&buffer[end], sizeof(buffer) - end, " out=%c%c%c%c",
ch_output_0(choffs) ? 'L' : '-',
ch_output_1(choffs) ? 'R' : '-',
ch_output_2(choffs) ? '0' : '-',
ch_output_3(choffs) ? '1' : '-');
if (op_lfo_am_enable(opoffs) != 0)
end += sprintf(end, " am=%u", lfo_am_depth());
end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u", lfo_am_depth());
if (op_lfo_pm_enable(opoffs) != 0)
end += sprintf(end, " pm=%u", lfo_pm_depth());
end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u", lfo_pm_depth());
if (waveform_enable() && op_waveform(opoffs) != 0)
end += sprintf(end, " wf=%u", op_waveform(opoffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " wf=%u", op_waveform(opoffs));
if (is_rhythm(choffs))
end += sprintf(end, " rhy=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " rhy=1");
if (DYNAMIC_OPS)
{
operator_mapping map;
operator_map(map);
if (bitfield(map.chan[chnum], 16, 8) != 0xff)
end += sprintf(end, " 4op");
end += snprintf(&buffer[end], sizeof(buffer) - end, " 4op");
}

return buffer;
Expand Down Expand Up @@ -685,21 +685,21 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
uint32_t opnum = opoffs;

char buffer[256];
char *end = &buffer[0];
int end = 0;

end += sprintf(end, "%u.%02u freq=%04X inst=%X fb=%u mul=%X",
end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X inst=%X fb=%u mul=%X",
chnum, opnum,
ch_block_freq(choffs),
ch_instrument(choffs),
ch_feedback(choffs),
op_multiple(opoffs));

if (bitfield(opoffs, 0) == 1 || (is_rhythm(choffs) && choffs >= 6))
end += sprintf(end, " vol=%X", op_volume(opoffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " vol=%X", op_volume(opoffs));
else
end += sprintf(end, " tl=%02X", ch_total_level(choffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " tl=%02X", ch_total_level(choffs));

end += sprintf(end, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u",
end += snprintf(&buffer[end], sizeof(buffer) - end, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u",
op_ksr(opoffs),
op_ksl(opoffs),
op_attack_rate(opoffs),
Expand All @@ -710,13 +710,13 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
ch_sustain(choffs));

if (op_lfo_am_enable(opoffs))
end += sprintf(end, " am=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " am=1");
if (op_lfo_pm_enable(opoffs))
end += sprintf(end, " pm=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=1");
if (op_waveform(opoffs) != 0)
end += sprintf(end, " wf=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " wf=1");
if (is_rhythm(choffs))
end += sprintf(end, " rhy=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " rhy=1");

return buffer;
}
Expand Down Expand Up @@ -1715,9 +1715,15 @@ uint8_t ymf278b::read_status()

uint8_t ymf278b::read_data_pcm()
{
// write to FM
// read from PCM
if (bitfield(m_address, 9) != 0)
return m_pcm.read(m_address & 0xff);
{
uint8_t result = m_pcm.read(m_address & 0xff);
if ((m_address & 0xff) == 0x02)
result |= 0x20;

return result;
}
return 0;
}

Expand Down
20 changes: 10 additions & 10 deletions 3rdparty/ymfm/src/ymfm_opm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,17 @@ opm_registers::opm_registers() :
{
// waveform 0 is a sawtooth
uint8_t am = index ^ 0xff;
int8_t pm = int8_t(index);
uint8_t pm = index;
m_lfo_waveform[0][index] = am | (pm << 8);

// waveform 1 is a square wave
am = bitfield(index, 7) ? 0 : 0xff;
pm = int8_t(am ^ 0x80);
pm = am ^ 0x80;
m_lfo_waveform[1][index] = am | (pm << 8);

// waveform 2 is a triangle wave
am = bitfield(index, 7) ? (index << 1) : ((index ^ 0xff) << 1);
pm = int8_t(bitfield(index, 6) ? am : ~am);
pm = bitfield(index, 6) ? am : ~am;
m_lfo_waveform[2][index] = am | (pm << 8);

// waveform 3 is noise; it is filled in dynamically
Expand Down Expand Up @@ -330,7 +330,7 @@ uint32_t opm_registers::compute_phase_step(uint32_t choffs, uint32_t opoffs, opd
if (pm_sensitivity < 6)
delta += lfo_raw_pm >> (6 - pm_sensitivity);
else
delta += lfo_raw_pm << (pm_sensitivity - 5);
delta += uint32_t(lfo_raw_pm) << (pm_sensitivity - 5);
}

// apply delta and convert to a frequency number
Expand All @@ -354,9 +354,9 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
uint32_t opnum = opoffs;

char buffer[256];
char *end = &buffer[0];
int end = 0;

end += sprintf(end, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
chnum, opnum,
ch_block_freq(choffs),
op_detune2(opoffs),
Expand All @@ -376,14 +376,14 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs)

bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0);
if (am)
end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth());
end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth());
bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0);
if (pm)
end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth());
end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth());
if (am || pm)
end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]);
end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]);
if (noise_enable() && opoffs == 31)
end += sprintf(end, " noise=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " noise=1");

return buffer;
}
Expand Down
16 changes: 8 additions & 8 deletions 3rdparty/ymfm/src/ymfm_opn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,9 @@ std::string opn_registers_base<IsOpnA>::log_keyon(uint32_t choffs, uint32_t opof
}

char buffer[256];
char *end = &buffer[0];
int end = 0;

end += sprintf(end, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X",
end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X",
chnum, opnum,
block_freq,
op_detune(opoffs),
Expand All @@ -427,21 +427,21 @@ std::string opn_registers_base<IsOpnA>::log_keyon(uint32_t choffs, uint32_t opof
op_sustain_level(opoffs));

if (OUTPUTS > 1)
end += sprintf(end, " out=%c%c",
end += snprintf(&buffer[end], sizeof(buffer) - end, " out=%c%c",
ch_output_0(choffs) ? 'L' : '-',
ch_output_1(choffs) ? 'R' : '-');
if (op_ssg_eg_enable(opoffs))
end += sprintf(end, " ssg=%X", op_ssg_eg_mode(opoffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " ssg=%X", op_ssg_eg_mode(opoffs));
bool am = (op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0);
if (am)
end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u", ch_lfo_am_sens(choffs));
bool pm = (ch_lfo_pm_sens(choffs) != 0);
if (pm)
end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u", ch_lfo_pm_sens(choffs));
if (am || pm)
end += sprintf(end, " lfo=%02X", lfo_rate());
end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X", lfo_rate());
if (multi_freq() && choffs == 2)
end += sprintf(end, " multi=1");
end += snprintf(&buffer[end], sizeof(buffer) - end, " multi=1");

return buffer;
}
Expand Down
2 changes: 1 addition & 1 deletion 3rdparty/ymfm/src/ymfm_opn.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ class ymf276 : public ym2612
ymf276(ymfm_interface &intf) : ym2612(intf) { }

// generate one sample of sound
void generate(output_data *output, uint32_t numsamples);
void generate(output_data *output, uint32_t numsamples = 1);
};

}
Expand Down
12 changes: 6 additions & 6 deletions 3rdparty/ymfm/src/ymfm_opq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
uint32_t opnum = opoffs;

char buffer[256];
char *end = &buffer[0];
int end = 0;

end += sprintf(end, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
chnum, opnum,
(opoffs & 1) ? ch_block_freq_24(choffs) : ch_block_freq_13(choffs),
int32_t(op_detune(opoffs)) - 0x20,
Expand All @@ -360,14 +360,14 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs)

bool am = (lfo_enable() && op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0);
if (am)
end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u", ch_lfo_am_sens(choffs));
bool pm = (lfo_enable() && ch_lfo_pm_sens(choffs) != 0);
if (pm)
end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs));
end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u", ch_lfo_pm_sens(choffs));
if (am || pm)
end += sprintf(end, " lfo=%02X", lfo_rate());
end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X", lfo_rate());
if (ch_reverb(choffs))
end += sprintf(end, " reverb");
end += snprintf(&buffer[end], sizeof(buffer) - end, " reverb");

return buffer;
}
Expand Down
Loading
Loading