summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/sound/gb.h
blob: e559f5c73016c4ee7c6b6df2ce308a1d33459d5f (plain) (tree)
1
2
3
4
5
6
7
8
9
                       

                                                

                       

 
                                             
                                                                                     

       
                                                                                                              
 
                                      


                                                   
 
          

                                                                                                                                
                                 
                                             
                                                     
                                             
 
                                        
                                                                                                                                          
 














































                                                      

                                
 


                            
                                
                          


                                     


                                       

                                     

                                        




                                            
                            

                                           

                                           



                                         
                            



                                        


                                      
                                    
          
 



                              


              











                                    

                                     
 
                                 



                                         




                                                                                 






                                                 
                                       
                                              

  



                                                  
                                                                                                        







                                                        
                                                                                      





                                                    
                                                                                                          







                                                        
                                                                                      


  



                                                  
 
                         
// license:BSD-3-Clause
// copyright-holders:Anthony Kruize, Wilbert Pol
// thanks-to:Shay Green
#ifndef MAME_SOUND_GB_H
#define MAME_SOUND_GB_H


class gameboy_sound_device : public device_t,
							public device_sound_interface
{
public:
	gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	DECLARE_READ8_MEMBER(sound_r);
	virtual DECLARE_READ8_MEMBER(wave_r) = 0;
	virtual DECLARE_WRITE8_MEMBER(sound_w) = 0;
	virtual DECLARE_WRITE8_MEMBER(wave_w) = 0;

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_clock_changed() override;
	virtual void device_reset() override;

	// sound stream update overrides
	virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;

protected:
	enum
	{
		NR10 = 0x00,
		NR11 = 0x01,
		NR12 = 0x02,
		NR13 = 0x03,
		NR14 = 0x04,
		// 0x05
		NR21 = 0x06,
		NR22 = 0x07,
		NR23 = 0x08,
		NR24 = 0x09,
		NR30 = 0x0A,
		NR31 = 0x0B,
		NR32 = 0x0C,
		NR33 = 0x0D,
		NR34 = 0x0E,
		// 0x0F
		NR41 = 0x10,
		NR42 = 0x11,
		NR43 = 0x12,
		NR44 = 0x13,
		NR50 = 0x14,
		NR51 = 0x15,
		NR52 = 0x16,
		// 0x17 - 0x1F
		AUD3W0 = 0x20,
		AUD3W1 = 0x21,
		AUD3W2 = 0x22,
		AUD3W3 = 0x23,
		AUD3W4 = 0x24,
		AUD3W5 = 0x25,
		AUD3W6 = 0x26,
		AUD3W7 = 0x27,
		AUD3W8 = 0x28,
		AUD3W9 = 0x29,
		AUD3WA = 0x2A,
		AUD3WB = 0x2B,
		AUD3WC = 0x2C,
		AUD3WD = 0x2D,
		AUD3WE = 0x2E,
		AUD3WF = 0x2F
	};

	static const unsigned int FRAME_CYCLES = 8192;
	static const int wave_duty_table[4][8];

	sound_stream *m_channel;

	struct SOUND
	{
		/* Common */
		uint8_t  reg[5];
		bool   on;
		uint8_t  channel;
		uint8_t  length;
		uint8_t  length_mask;
		bool   length_counting;
		bool   length_enabled;
		/* Mode 1, 2, 3 */
		uint64_t cycles_left;
		int8_t   duty;
		/* Mode 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;
		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 */
		uint8_t  level;
		uint8_t  offset;
		uint32_t duty_count;
		int8_t   current_sample;
		bool   sample_reading;
		/* Mode 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;

	struct
	{
		uint8_t 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;
		uint64_t cycles;
		bool wave_ram_locked;
	} m_snd_control;

	uint8_t m_snd_regs[0x30];
	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_state();
	bool dac_enabled(struct SOUND &snd);
	virtual void corrupt_wave_ram() { };
	uint64_t noise_period_cycles();
	TIMER_CALLBACK_MEMBER(timer_callback);
};


class dmg_apu_device : public gameboy_sound_device
{
public:
	dmg_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual DECLARE_READ8_MEMBER(wave_r) override;
	virtual DECLARE_WRITE8_MEMBER(wave_w) override;
	virtual DECLARE_WRITE8_MEMBER(sound_w) override;

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;
};


class cgb04_apu_device : public gameboy_sound_device
{
public:
	cgb04_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual DECLARE_READ8_MEMBER(wave_r) override;
	virtual DECLARE_WRITE8_MEMBER(wave_w) override;
	virtual DECLARE_WRITE8_MEMBER(sound_w) override;

protected:
	virtual void device_reset() override;
	virtual void apu_power_off() override;
	virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override;
};


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)

#endif // MAME_SOUND_GB_H