1 // license:BSD-3-Clause 2 // copyright-holders:Anthony Kruize, Wilbert Pol 3 // thanks-to:Shay Green 4 #ifndef MAME_SOUND_GB_H 5 #define MAME_SOUND_GB_H 6 7 8 class gameboy_sound_device : public device_t, 9 public device_sound_interface 10 { 11 public: 12 gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 13 14 u8 sound_r(offs_t offset); 15 virtual u8 wave_r(offs_t offset) = 0; 16 virtual void sound_w(offs_t offset, u8 data) = 0; 17 virtual void wave_w(offs_t offset, u8 data) = 0; 18 19 protected: 20 gameboy_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 21 22 // device-level overrides 23 virtual void device_start() override; 24 virtual void device_clock_changed() override; 25 virtual void device_reset() override; 26 27 // sound stream update overrides 28 virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; 29 30 protected: 31 enum 32 { 33 NR10 = 0x00, 34 NR11 = 0x01, 35 NR12 = 0x02, 36 NR13 = 0x03, 37 NR14 = 0x04, 38 // 0x05 39 NR21 = 0x06, 40 NR22 = 0x07, 41 NR23 = 0x08, 42 NR24 = 0x09, 43 NR30 = 0x0A, 44 NR31 = 0x0B, 45 NR32 = 0x0C, 46 NR33 = 0x0D, 47 NR34 = 0x0E, 48 // 0x0F 49 NR41 = 0x10, 50 NR42 = 0x11, 51 NR43 = 0x12, 52 NR44 = 0x13, 53 NR50 = 0x14, 54 NR51 = 0x15, 55 NR52 = 0x16, 56 // 0x17 - 0x1F 57 AUD3W0 = 0x20, 58 AUD3W1 = 0x21, 59 AUD3W2 = 0x22, 60 AUD3W3 = 0x23, 61 AUD3W4 = 0x24, 62 AUD3W5 = 0x25, 63 AUD3W6 = 0x26, 64 AUD3W7 = 0x27, 65 AUD3W8 = 0x28, 66 AUD3W9 = 0x29, 67 AUD3WA = 0x2A, 68 AUD3WB = 0x2B, 69 AUD3WC = 0x2C, 70 AUD3WD = 0x2D, 71 AUD3WE = 0x2E, 72 AUD3WF = 0x2F 73 }; 74 75 static const unsigned int FRAME_CYCLES = 8192; 76 static const int wave_duty_table[4][8]; 77 78 sound_stream *m_channel; 79 80 struct SOUND 81 { 82 /* Common */ 83 uint8_t reg[5]; 84 bool on; 85 uint8_t channel; 86 uint8_t length; 87 uint8_t length_mask; 88 bool length_counting; 89 bool length_enabled; 90 /* Mode 1, 2, 3 */ 91 uint64_t cycles_left; 92 int8_t duty; 93 /* Mode 1, 2, 4 */ 94 bool envelope_enabled; 95 int8_t envelope_value; 96 int8_t envelope_direction; 97 uint8_t envelope_time; 98 uint8_t envelope_count; 99 int8_t signal; 100 /* Mode 1 */ 101 uint16_t frequency; 102 uint16_t frequency_counter; 103 bool sweep_enabled; 104 bool sweep_neg_mode_used; 105 uint8_t sweep_shift; 106 int32_t sweep_direction; 107 uint8_t sweep_time; 108 uint8_t sweep_count; 109 /* Mode 3 */ 110 uint8_t level; 111 uint8_t offset; 112 uint32_t duty_count; 113 int8_t current_sample; 114 bool sample_reading; 115 /* Mode 4 */ 116 bool noise_short; 117 uint16_t noise_lfsr; 118 }; 119 120 struct SOUND m_snd_1; 121 struct SOUND m_snd_2; 122 struct SOUND m_snd_3; 123 struct SOUND m_snd_4; 124 125 struct 126 { 127 uint8_t on; 128 uint8_t vol_left; 129 uint8_t vol_right; 130 uint8_t mode1_left; 131 uint8_t mode1_right; 132 uint8_t mode2_left; 133 uint8_t mode2_right; 134 uint8_t mode3_left; 135 uint8_t mode3_right; 136 uint8_t mode4_left; 137 uint8_t mode4_right; 138 uint64_t cycles; 139 bool wave_ram_locked; 140 } m_snd_control; 141 142 uint8_t m_snd_regs[0x30]; 143 attotime m_last_updated; 144 emu_timer *m_timer; 145 146 virtual void apu_power_off() = 0; 147 void sound_w_internal(int offset, uint8_t data); 148 void update_square_channel(struct SOUND &snd, uint64_t cycles); 149 virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) = 0; 150 void update_noise_channel(struct SOUND &snd, uint64_t cycles); 151 int32_t calculate_next_sweep(struct SOUND &snd); 152 void apply_next_sweep(struct SOUND &snd); 153 void tick_length(struct SOUND &snd); 154 void tick_sweep(struct SOUND &snd); 155 void tick_envelope(struct SOUND &snd); 156 void update_state(); 157 bool dac_enabled(struct SOUND &snd); corrupt_wave_ram()158 virtual void corrupt_wave_ram() { }; 159 uint64_t noise_period_cycles(); 160 TIMER_CALLBACK_MEMBER(timer_callback); 161 }; 162 163 164 class dmg_apu_device : public gameboy_sound_device 165 { 166 public: 167 dmg_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 168 169 virtual u8 wave_r(offs_t offset) override; 170 virtual void wave_w(offs_t offset, u8 data) override; 171 virtual void sound_w(offs_t offset, u8 data) override; 172 173 protected: 174 virtual void apu_power_off() override; 175 virtual void corrupt_wave_ram() override; 176 virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override; 177 }; 178 179 180 class cgb04_apu_device : public gameboy_sound_device 181 { 182 public: 183 cgb04_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 184 185 virtual u8 wave_r(offs_t offset) override; 186 virtual void wave_w(offs_t offset, u8 data) override; 187 virtual void sound_w(offs_t offset, u8 data) override; 188 189 protected: 190 virtual void device_reset() override; 191 virtual void apu_power_off() override; 192 virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override; 193 }; 194 195 196 DECLARE_DEVICE_TYPE(DMG_APU, dmg_apu_device) 197 //DECLARE_DEVICE_TYPE(CGB02_APU, cgb02_apu_device) 198 DECLARE_DEVICE_TYPE(CGB04_APU, cgb04_apu_device) 199 //DECLARE_DEVICE_TYPE(CGB05_APU, cgb05_apu_device) 200 201 #endif // MAME_SOUND_GB_H 202