diff options
Diffstat (limited to 'src/devices/sound/swp30.h')
-rw-r--r-- | src/devices/sound/swp30.h | 229 |
1 files changed, 171 insertions, 58 deletions
diff --git a/src/devices/sound/swp30.h b/src/devices/sound/swp30.h index dd95a8dd85f..eb34fb13eec 100644 --- a/src/devices/sound/swp30.h +++ b/src/devices/sound/swp30.h @@ -3,53 +3,123 @@ // Yamaha SWP30/30B, rompler/dsp combo -#ifndef DEVICES_SOUND_SWP30_H -#define DEVICES_SOUND_SWP30_H +#ifndef MAME_SOUND_SWP30_H +#define MAME_SOUND_SWP30_H #pragma once -#include "meg.h" +#include "swp30d.h" -class swp30_device : public device_t, public device_sound_interface, public device_rom_interface +class swp30_device : public cpu_device, public device_sound_interface, public swp30_disassembler::info { public: + enum { AS_REVERB = AS_IO }; + swp30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 33868800); - void map(address_map &map); + void map(address_map &map) ATTR_COLD; protected: - virtual void device_start() override; - virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; - virtual void rom_bank_updated() override; - virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual void sound_stream_update(sound_stream &stream) override; + virtual uint32_t execute_min_cycles() const noexcept override; + virtual uint32_t execute_max_cycles() const noexcept override; + virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 1) / 2; } + virtual void execute_run() override; + virtual space_config_vector memory_space_config() const override; + virtual void state_import(const device_state_entry &entry) override; + virtual void state_export(const device_state_entry &entry) override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; private: - required_device<meg_embedded_device> m_meg; + enum { + IDLE, + ATTACK, + DECAY1, + DECAY2, + RELEASE + }; + + struct mixer_slot { + std::array<u16, 3> vol; + std::array<u16, 3> route; + }; + + address_space_config m_program_config, m_rom_config, m_reverb_config; + address_space *m_program, *m_rom, *m_reverb; + memory_access<25, 2, -2, ENDIANNESS_LITTLE>::cache m_rom_cache; + memory_access<18, 1, -1, ENDIANNESS_LITTLE>::cache m_reverb_cache; sound_stream *m_stream; - s32 m_sample_increment[0x4000]; - s32 m_linear_attenuation[0x100]; - s16 m_sample_log8[0x100]; - - u64 m_program[0x180]; - u64 m_keyon_mask, m_active_mask; - u32 m_pre_size[0x40], m_post_size[0x40], m_address[0x40]; + static const std::array<s32, 0x80> attack_linear_step; + static const std::array<s32, 0x20> decay_linear_step; + static const std::array<s32, 16> panmap; + static const std::array<u32, 0x400> pitch_base; + std::array<s32, 0x80> m_global_step; + std::array<s16, 0x100> m_dpcm; + + static const std::array<u32, 4> lfo_shape_centered_saw; + static const std::array<u32, 4> lfo_shape_centered_tri; + static const std::array<u32, 4> lfo_shape_offset_saw; + static const std::array<u32, 4> lfo_shape_offset_tri; + static const std::array<u8, 4> dpcm_offset; + + std::array<s32, 0x40> m_sample_start; + std::array<s32, 0x40> m_sample_end; + std::array<u32, 0x40> m_sample_address; + std::array<u16, 0x40> m_pitch; + + std::array<u16, 0x40> m_attack; + std::array<u16, 0x40> m_decay1; + std::array<u16, 0x40> m_decay2; + std::array<u16, 0x40> m_release_glo; + std::array<u16, 0x40> m_lfo_step_pmod; + std::array<u16, 0x40> m_lfo_amod; + + std::array<u32, 0x40> m_lfo_phase; + std::array<s32, 0x40> m_sample_pos; + std::array<s32, 0x40> m_envelope_level; + std::array<s32, 0x40> m_envelope_timer; + std::array<bool, 0x40> m_envelope_on_timer; + std::array<bool, 0x40> m_decay2_done; + std::array<u8, 0x40> m_envelope_mode; + std::array<s32, 0x40> m_glo_level_cur; + std::array<s32, 0x40> m_pan_l; + std::array<s32, 0x40> m_pan_r; + std::array<s16, 0x40> m_dpcm_current; + std::array<s16, 0x40> m_dpcm_next; + std::array<u32, 0x40> m_dpcm_address; + std::array<s32, 0x40> m_dpcm_sum; + + std::array<u64, 0x180> m_meg_program; + std::array<s16, 0x180> m_meg_const; + std::array<u16, 0x80> m_meg_offset; + std::array<u16, 0x18> m_meg_lfo; + std::array<u16, 8> m_meg_map; + + std::array<mixer_slot, 0x80> m_mixer; + + std::array<s32, 0x40> m_meg_m; + std::array<s32, 0x10> m_melo; + std::array<s32, 2> m_meg_output; - s32 m_sample_pos[64]; s32 m_sample_history[0x40][2][2]; - u16 m_program_pfp[0x180], m_program_pint[0x80], m_program_plfo[0x80]; + u32 m_waverom_adr, m_waverom_mode, m_waverom_val; + u16 m_waverom_access; - u16 m_volume[0x40], m_freq[0x40], m_pan[0x40], m_dry_rev[0x40], m_cho_var[0x40]; - u16 m_envelope[0x40][3]; u16 m_lpf_cutoff[0x40], m_lpf_cutoff_inc[0x40], m_lpf_reso[0x40], m_hpf_cutoff[0x40]; s16 m_eq_filter[0x40][6]; - u16 m_routing[0x40][3]; - u16 m_map[8]; - u16 m_program_address; + u64 m_keyon_mask; + u16 m_internal_adr; + + u16 m_meg_program_address; + u16 m_meg_pc; + int m_icount; // AWM2 per-channel registers u16 lpf_cutoff_r(offs_t offset); @@ -60,55 +130,98 @@ private: void hpf_cutoff_w(offs_t offset, u16 data); u16 lpf_reso_r(offs_t offset); void lpf_reso_w(offs_t offset, u16 data); - template<int sel> u16 envelope_r(offs_t offset); - template<int sel> void envelope_w(offs_t offset, u16 data); + u16 attack_r(offs_t offset); + void attack_w(offs_t offset, u16 data); + u16 decay1_r(offs_t offset); + void decay1_w(offs_t offset, u16 data); + u16 decay2_r(offs_t offset); + void decay2_w(offs_t offset, u16 data); + u16 release_glo_r(offs_t offset); + void release_glo_w(offs_t offset, u16 data); template<int coef> u16 eq_filter_r(offs_t offset); template<int coef> void eq_filter_w(offs_t offset, u16 data); - u16 volume_r(offs_t offset); - void volume_w(offs_t offset, u16 data); - u16 freq_r(offs_t offset); - void freq_w(offs_t offset, u16 data); - u16 pre_size_h_r(offs_t offset); - u16 pre_size_l_r(offs_t offset); - void pre_size_h_w(offs_t offset, u16 data); - void pre_size_l_w(offs_t offset, u16 data); - u16 post_size_h_r(offs_t offset); - u16 post_size_l_r(offs_t offset); - void post_size_h_w(offs_t offset, u16 data); - void post_size_l_w(offs_t offset, u16 data); - u16 address_h_r(offs_t offset); - u16 address_l_r(offs_t offset); - void address_h_w(offs_t offset, u16 data); - void address_l_w(offs_t offset, u16 data); + + u16 sample_start_h_r(offs_t offset); + u16 sample_start_l_r(offs_t offset); + void sample_start_h_w(offs_t offset, u16 data); + void sample_start_l_w(offs_t offset, u16 data); + u16 sample_end_h_r(offs_t offset); + u16 sample_end_l_r(offs_t offset); + void sample_end_h_w(offs_t offset, u16 data); + void sample_end_l_w(offs_t offset, u16 data); + u16 sample_address_h_r(offs_t offset); + u16 sample_address_l_r(offs_t offset); + void sample_address_h_w(offs_t offset, u16 data); + void sample_address_l_w(offs_t offset, u16 data); + u16 pitch_r(offs_t offset); + void pitch_w(offs_t offset, u16 data); + u16 pan_r(offs_t offset); void pan_w(offs_t offset, u16 data); u16 dry_rev_r(offs_t offset); void dry_rev_w(offs_t offset, u16 data); u16 cho_var_r(offs_t offset); void cho_var_w(offs_t offset, u16 data); - template<int sel> u16 routing_r(offs_t offset); - template<int sel> void routing_w(offs_t offset, u16 data); + + void lfo_step_pmod_w(offs_t offset, u16 data); + u16 lfo_step_pmod_r(offs_t offset); + void lfo_amod_w(offs_t offset, u16 data); + u16 lfo_amod_r(offs_t offset); + + u16 internal_adr_r(); + void internal_adr_w(u16 data); + u16 internal_r(); + template<int sel> u16 route_r(offs_t offset); + template<int sel> void route_w(offs_t offset, u16 data); + template<int sel> u16 vol_r(offs_t offset); + template<int sel> void vol_w(offs_t offset, u16 data); + + // Envelope control + void change_mode_attack_decay1(int chan); + void change_mode_decay1_decay2(int chan); + static bool istep(s32 &value, s32 limit, s32 step); + static bool fpstep(s32 &value, s32 limit, s32 step); + static s32 fpadd(s32 value, s32 step); + static s32 fpsub(s32 value, s32 step); + static s32 fpapply(s32 value, s32 sample); + static s32 lpffpapply(s32 value, s32 sample); + static s32 meg_att(s32 sample, s32 att); // Control registers template<int sel> u16 keyon_mask_r(); template<int sel> void keyon_mask_w(u16 data); u16 keyon_r(); void keyon_w(u16); - u16 prg_address_r(); - void prg_address_w(u16 data); - template<int sel> u16 prg_r(); - template<int sel> void prg_w(u16 data); - template<int sel> u16 map_r(); - template<int sel> void map_w(u16 data); + u16 meg_prg_address_r(); + void meg_prg_address_w(u16 data); + template<int sel> u16 meg_prg_r(); + template<int sel> void meg_prg_w(u16 data); + template<int sel> u16 meg_map_r(); + template<int sel> void meg_map_w(u16 data); + template<int sel> void waverom_adr_w(u16 data); + template<int sel> u16 waverom_adr_r(); + template<int sel> void waverom_mode_w(u16 data); + template<int sel> u16 waverom_mode_r(); + void waverom_access_w(u16 data); + u16 waverom_access_r(); + u16 waverom_busy_r(); + template<int sel> u16 waverom_val_r(); // MEG registers - template<int sel> u16 prg_fp_r(offs_t offset); - template<int sel> void prg_fp_w(offs_t offset, u16 data); - template<int sel> u16 prg_off_r(offs_t offset); - template<int sel> void prg_off_w(offs_t offset, u16 data); - template<int sel> u16 prg_lfo_r(offs_t offset); - template<int sel> void prg_lfo_w(offs_t offset, u16 data); + template<int sel> u16 meg_const_r(offs_t offset); + template<int sel> void meg_const_w(offs_t offset, u16 data); + template<int sel> u16 meg_offset_r(offs_t offset); + template<int sel> void meg_offset_w(offs_t offset, u16 data); + template<int sel> u16 meg_lfo_r(offs_t offset); + template<int sel> void meg_lfo_w(offs_t offset, u16 data); + + void meg_prg_map(address_map &map) ATTR_COLD; + u64 meg_prg_map_r(offs_t address); + + void meg_reverb_map(address_map &map) ATTR_COLD; + virtual u16 swp30d_const_r(u16 address) const override; + virtual u16 swp30d_offset_r(u16 address) const override; // Generic catch-all u16 snd_r(offs_t offset); @@ -126,4 +239,4 @@ private: DECLARE_DEVICE_TYPE(SWP30, swp30_device) -#endif +#endif // MAME_SOUND_SWP30_H |