diff options
Diffstat (limited to '3rdparty/ymfm/src/ymfm_opn.h')
-rw-r--r-- | 3rdparty/ymfm/src/ymfm_opn.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/3rdparty/ymfm/src/ymfm_opn.h b/3rdparty/ymfm/src/ymfm_opn.h index 3bd5f2ead1a..a9bb01d9763 100644 --- a/3rdparty/ymfm/src/ymfm_opn.h +++ b/3rdparty/ymfm/src/ymfm_opn.h @@ -164,6 +164,9 @@ public: struct operator_mapping { uint32_t chan[CHANNELS]; }; void operator_map(operator_mapping &dest) const; + // read a register value + uint8_t read(uint16_t index) const { return m_regdata[index]; } + // handle writes to the register array bool write(uint16_t index, uint8_t data, uint32_t &chan, uint32_t &opmask); @@ -618,6 +621,80 @@ protected: }; +// ======================> ymf288 + +class ymf288 +{ +public: + using fm_engine = fm_engine_base<opna_registers>; + static constexpr uint32_t FM_OUTPUTS = fm_engine::OUTPUTS; + static constexpr uint32_t SSG_OUTPUTS = 1; + static constexpr uint32_t OUTPUTS = FM_OUTPUTS + SSG_OUTPUTS; + using output_data = ymfm_output<OUTPUTS>; + + // constructor + ymf288(ymfm_interface &intf); + + // configuration + void ssg_override(ssg_override &intf) { m_ssg.override(intf); } + void set_fidelity(opn_fidelity fidelity) { m_fidelity = fidelity; update_prescale(); } + + // reset + void reset(); + + // save/restore + void save_restore(ymfm_saved_state &state); + + // pass-through helpers + uint32_t sample_rate(uint32_t input_clock) const + { + switch (m_fidelity) + { + case OPN_FIDELITY_MIN: return input_clock / 144; + case OPN_FIDELITY_MED: return input_clock / 144; + default: + case OPN_FIDELITY_MAX: return input_clock / 16; + } + } + uint32_t ssg_effective_clock(uint32_t input_clock) const { return input_clock / 4; } + void invalidate_caches() { m_fm.invalidate_caches(); } + + // read access + uint8_t read_status(); + uint8_t read_data(); + uint8_t read_status_hi(); + uint8_t read(uint32_t offset); + + // write access + void write_address(uint8_t data); + void write_data(uint8_t data); + void write_address_hi(uint8_t data); + void write_data_hi(uint8_t data); + void write(uint32_t offset, uint8_t data); + + // generate one sample of sound + void generate(output_data *output, uint32_t numsamples = 1); + +protected: + // internal helpers + bool ymf288_mode() { return ((m_fm.regs().read(0x20) & 0x02) != 0); } + void update_prescale(); + void clock_fm_and_adpcm(); + + // internal state + opn_fidelity m_fidelity; // configured fidelity + uint16_t m_address; // address register + uint8_t m_fm_samples_per_output; // how many samples to repeat + uint8_t m_irq_enable; // IRQ enable register + uint8_t m_flag_control; // flag control register + fm_engine::output_data m_last_fm; // last FM output + fm_engine m_fm; // core FM engine + ssg_engine m_ssg; // SSG engine + ssg_resampler<output_data, 2, true> m_ssg_resampler; // SSG resampler helper + adpcm_a_engine m_adpcm_a; // ADPCM-A engine +}; + + // ======================> ym2610/ym2610b class ym2610 |