diff options
Diffstat (limited to 'src/devices/sound/gb.h')
-rw-r--r-- | src/devices/sound/gb.h | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/src/devices/sound/gb.h b/src/devices/sound/gb.h index 989871fe08c..d81a79b98b1 100644 --- a/src/devices/sound/gb.h +++ b/src/devices/sound/gb.h @@ -9,9 +9,11 @@ class gameboy_sound_device : public device_t, public device_sound_interface { public: + static constexpr feature_type imperfect_features() { return feature::SOUND; } + gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - u8 sound_r(offs_t offset); + virtual u8 sound_r(offs_t offset); virtual u8 wave_r(offs_t offset) = 0; virtual void sound_w(offs_t offset, u8 data) = 0; virtual void wave_w(offs_t offset, u8 data) = 0; @@ -20,12 +22,12 @@ protected: gameboy_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides - virtual void device_start() override; + virtual void device_start() override ATTR_COLD; virtual void device_clock_changed() override; - virtual void device_reset() override; + virtual void device_reset() override ATTR_COLD; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream) override; protected: enum @@ -73,7 +75,7 @@ protected: }; static const unsigned int FRAME_CYCLES = 8192; - static const int wave_duty_table[4][8]; + static const int wave_duty_table[4]; sound_stream *m_channel; @@ -87,75 +89,70 @@ protected: uint8_t length_mask; bool length_counting; bool length_enabled; - /* Mode 1, 2, 3 */ - uint64_t cycles_left; + uint16_t frequency; + uint16_t frequency_counter; + /* Channel 1, 2, 3 */ + int64_t cycles_left; int8_t duty; - /* Mode 1, 2, 4 */ + /* Channel 1, 2, 4 */ bool envelope_enabled; int8_t envelope_value; int8_t envelope_direction; uint8_t envelope_time; uint8_t envelope_count; int8_t signal; - /* Mode 1 */ - uint16_t frequency; - uint16_t frequency_counter; + /* Channel 1 */ + uint16_t frequency_shadow; bool sweep_enabled; bool sweep_neg_mode_used; uint8_t sweep_shift; int32_t sweep_direction; uint8_t sweep_time; uint8_t sweep_count; - /* Mode 3 */ + /* Channel 3 */ + uint8_t size; // AGB specific + uint8_t bank; // AGB specific uint8_t level; uint8_t offset; uint32_t duty_count; int8_t current_sample; bool sample_reading; - /* Mode 4 */ + /* Channel 4 */ bool noise_short; uint16_t noise_lfsr; }; - struct SOUND m_snd_1; - struct SOUND m_snd_2; - struct SOUND m_snd_3; - struct SOUND m_snd_4; + SOUND m_snd[4]; struct { - uint8_t on; + bool on; uint8_t vol_left; uint8_t vol_right; - uint8_t mode1_left; - uint8_t mode1_right; - uint8_t mode2_left; - uint8_t mode2_right; - uint8_t mode3_left; - uint8_t mode3_right; - uint8_t mode4_left; - uint8_t mode4_right; + bool chan_left[4]; + bool chan_right[4]; uint64_t cycles; bool wave_ram_locked; } m_snd_control; uint8_t m_snd_regs[0x30]; + uint8_t m_wave_ram[2][0x10]; // 16 bytes, 2 banks for AGB attotime m_last_updated; emu_timer *m_timer; virtual void apu_power_off() = 0; void sound_w_internal(int offset, uint8_t data); - void update_square_channel(struct SOUND &snd, uint64_t cycles); - virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) = 0; - void update_noise_channel(struct SOUND &snd, uint64_t cycles); - int32_t calculate_next_sweep(struct SOUND &snd); - void apply_next_sweep(struct SOUND &snd); - void tick_length(struct SOUND &snd); - void tick_sweep(struct SOUND &snd); - void tick_envelope(struct SOUND &snd); + void update_square_channel(SOUND &snd, uint64_t cycles); + virtual void update_wave_channel(SOUND &snd, uint64_t cycles) = 0; + void update_noise_channel(SOUND &snd, uint64_t cycles); + int32_t calculate_next_sweep(SOUND &snd); + void apply_next_sweep(SOUND &snd); + void tick_length(SOUND &snd); + void tick_sweep(SOUND &snd); + void tick_envelope(SOUND &snd); void update_state(); - bool dac_enabled(struct SOUND &snd); - virtual void corrupt_wave_ram() { }; + bool dac_enabled(SOUND &snd); + virtual void corrupt_wave_ram() { } uint64_t noise_period_cycles(); TIMER_CALLBACK_MEMBER(timer_callback); }; @@ -173,7 +170,7 @@ public: protected: virtual void apu_power_off() override; virtual void corrupt_wave_ram() override; - virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override; + virtual void update_wave_channel(SOUND &snd, uint64_t cycles) override; }; @@ -187,9 +184,28 @@ public: virtual void sound_w(offs_t offset, u8 data) override; protected: - virtual void device_reset() override; + cgb04_apu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_reset() override ATTR_COLD; virtual void apu_power_off() override; - virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override; + virtual void update_wave_channel(SOUND &snd, uint64_t cycles) override; +}; + + +class agb_apu_device : public cgb04_apu_device +{ +public: + agb_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual u8 sound_r(offs_t offset) override; + virtual u8 wave_r(offs_t offset) override; + virtual void wave_w(offs_t offset, u8 data) override; + +protected: + agb_apu_device(const machine_config &mconfig, device_type &type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_reset() override ATTR_COLD; + virtual void update_wave_channel(SOUND &snd, uint64_t cycles) override; }; @@ -197,5 +213,6 @@ DECLARE_DEVICE_TYPE(DMG_APU, dmg_apu_device) //DECLARE_DEVICE_TYPE(CGB02_APU, cgb02_apu_device) DECLARE_DEVICE_TYPE(CGB04_APU, cgb04_apu_device) //DECLARE_DEVICE_TYPE(CGB05_APU, cgb05_apu_device) +DECLARE_DEVICE_TYPE(AGB_APU, agb_apu_device) #endif // MAME_SOUND_GB_H |