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


                          

                         
 
            
 
                    
 
                                                                                                                    



                                                                                               
                                                            

                                  
                                                                                   

                                       
                                                                                        
 
                                   
                                                                                    
 
 
                                    
                                                                     

       
                                                                                                              
 



                                                                                                                                               







                                                        
 
                                      
 

                                 
                                             

                                        
                                                                                                                                          
 
        














































                                                                                
                                                                

                                                        
                                     
 

             

                                      
                  
 
                              

                               

                                          
                           
      

                                  


                                

                                                
 


                            
 


                                       
 
                                  












                                                  




                              

                

                         



                                         
 




                                   
                                                                                             
 




                                                                               
 
                                                                                  
                                       
                               
                                                    








                                           
                                       

                                          
                                                   
                    
                                         
                                                      
                                               
                                                       


                                                                    
                                           
 

                        


                                                                                                      

  
                                      
 
                           
// license:BSD-3-Clause
// copyright-holders:ElSemi, R. Belmont
/*
    SCSP (YMF292-F) header
*/

#ifndef MAME_SOUND_SCSP_H
#define MAME_SOUND_SCSP_H

#pragma once

#include "scspdsp.h"

#define SCSP_FM_DELAY    0    // delay in number of slots processed before samples are written to the FM ring buffer
				// driver code indicates should be 4, but sounds distorted then


#define MCFG_SCSP_ROFFSET(_offs) \
	downcast<scsp_device &>(*device).set_roffset(_offs);

#define MCFG_SCSP_IRQ_CB(_devcb) \
	devcb = &downcast<scsp_device &>(*device).set_irq_callback(DEVCB_##_devcb);

#define MCFG_SCSP_MAIN_IRQ_CB(_devcb) \
	devcb = &downcast<scsp_device &>(*device).set_main_irq_callback(DEVCB_##_devcb);

#define MCFG_SCSP_EXTS_CB(_devcb) \
	devcb = &downcast<scsp_device &>(*device).set_exts_callback(DEVCB_##_devcb);


class scsp_device : public device_t,
					public device_sound_interface
{
public:
	scsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 44'100);

	void set_roffset(int roffset) { m_roffset = roffset; }
	template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_main_irq_callback(Object &&cb) { return m_main_irq_cb.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_exts_callback(Object &&cb) { return m_exts_cb.set_callback(std::forward<Object>(cb)); }

	// SCSP register access
	DECLARE_READ16_MEMBER( read );
	DECLARE_WRITE16_MEMBER( write );

	// MIDI I/O access (used for comms on Model 2/3)
	DECLARE_WRITE16_MEMBER( midi_in );
	DECLARE_READ16_MEMBER( midi_out_r );

	void set_ram_base(void *base);

protected:
	// device-level overrides
	virtual void device_start() override;

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

private:
	enum SCSP_STATE { SCSP_ATTACK, SCSP_DECAY1, SCSP_DECAY2, SCSP_RELEASE };

	struct SCSP_EG_t
	{
		int volume; //
		SCSP_STATE state;
		int step;
		//step vals
		int AR;     //Attack
		int D1R;    //Decay1
		int D2R;    //Decay2
		int RR;     //Release

		int DL;     //Decay level
		uint8_t EGHOLD;
		uint8_t LPLINK;
	};

	struct SCSP_LFO_t
	{
		uint16_t phase;
		uint32_t phase_step;
		int *table;
		int *scale;
	};

	struct SCSP_SLOT
	{
		union
		{
			uint16_t data[0x10];  //only 0x1a bytes used
			uint8_t datab[0x20];
		} udata;

		uint8_t Backwards;    //the wave is playing backwards
		uint8_t active;   //this slot is currently playing
		uint8_t *base;        //samples base address
		uint32_t cur_addr;    //current play address (24.8)
		uint32_t nxt_addr;    //next play address
		uint32_t step;        //pitch step (24.8)
		SCSP_EG_t EG;            //Envelope
		SCSP_LFO_t PLFO;     //Phase LFO
		SCSP_LFO_t ALFO;     //Amplitude LFO
		int slot;
		int16_t Prev;  //Previous sample (for interpolation)
	};

	int m_roffset;                /* offset in the region */
	devcb_write8       m_irq_cb;  /* irq callback */
	devcb_write_line   m_main_irq_cb;
	devcb_read16       m_exts_cb;

	union
	{
		uint16_t data[0x30/2];
		uint8_t datab[0x30];
	} m_udata;

	SCSP_SLOT m_Slots[32];
	int16_t m_RINGBUF[128];
	uint8_t m_BUFPTR;
#if SCSP_FM_DELAY
	int16_t m_DELAYBUF[SCSP_FM_DELAY];
	uint8_t m_DELAYPTR;
#endif
	uint8_t *m_SCSPRAM;
	uint32_t m_SCSPRAM_LENGTH;
	char m_Master;
	sound_stream * m_stream;

	std::unique_ptr<int32_t[]> m_buffertmpl;
	std::unique_ptr<int32_t[]> m_buffertmpr;

	uint32_t m_IrqTimA;
	uint32_t m_IrqTimBC;
	uint32_t m_IrqMidi;

	uint8_t m_MidiOutW, m_MidiOutR;
	uint8_t m_MidiStack[32];
	uint8_t m_MidiW, m_MidiR;

	int32_t m_EG_TABLE[0x400];

	int m_LPANTABLE[0x10000];
	int m_RPANTABLE[0x10000];

	int m_TimPris[3];
	int m_TimCnt[3];

	// timers
	emu_timer *m_timerA, *m_timerB, *m_timerC;

	// DMA stuff
	struct
	{
		uint32_t dmea;
		uint16_t drga;
		uint16_t dtlg;
		uint8_t dgate;
		uint8_t ddir;
	} m_dma;

	uint16_t m_mcieb;
	uint16_t m_mcipd;

	int m_ARTABLE[64], m_DRTABLE[64];

	SCSPDSP m_DSP;

	stream_sample_t *m_bufferl;
	stream_sample_t *m_bufferr;

	int m_length;

	int16_t *m_RBUFDST;   //this points to where the sample will be stored in the RingBuf

	//LFO
	int m_PLFO_TRI[256], m_PLFO_SQR[256], m_PLFO_SAW[256], m_PLFO_NOI[256];
	int m_ALFO_TRI[256], m_ALFO_SQR[256], m_ALFO_SAW[256], m_ALFO_NOI[256];
	int m_PSCALES[8][256];
	int m_ASCALES[8][256];

	void exec_dma(address_space &space);       /*state DMA transfer function*/
	uint8_t DecodeSCI(uint8_t irq);
	void CheckPendingIRQ();
	void MainCheckPendingIRQ(uint16_t irq_type);
	void ResetInterrupts();
	TIMER_CALLBACK_MEMBER( timerA_cb );
	TIMER_CALLBACK_MEMBER( timerB_cb );
	TIMER_CALLBACK_MEMBER( timerC_cb );
	int Get_AR(int base, int R);
	int Get_DR(int base, int R);
	int Get_RR(int base, int R);
	void Compute_EG(SCSP_SLOT *slot);
	int EG_Update(SCSP_SLOT *slot);
	uint32_t Step(SCSP_SLOT *slot);
	void Compute_LFO(SCSP_SLOT *slot);
	void StartSlot(SCSP_SLOT *slot);
	void StopSlot(SCSP_SLOT *slot, int keyoff);
	void init();
	void UpdateSlotReg(int s, int r);
	void UpdateReg(address_space &space, int reg);
	void UpdateSlotRegR(int slot, int reg);
	void UpdateRegR(address_space &space, int reg);
	void w16(address_space &space, uint32_t addr, uint16_t val);
	uint16_t r16(address_space &space, uint32_t addr);
	inline int32_t UpdateSlot(SCSP_SLOT *slot);
	void DoMasterSamples(int nsamples);

	//LFO
	void LFO_Init();
	int32_t PLFO_Step(SCSP_LFO_t *LFO);
	int32_t ALFO_Step(SCSP_LFO_t *LFO);
	void LFO_ComputeStep(SCSP_LFO_t *LFO, uint32_t LFOF, uint32_t LFOWS, uint32_t LFOS, int ALFO);
};

DECLARE_DEVICE_TYPE(SCSP, scsp_device)

#endif // MAME_SOUND_SCSP_H