summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/sound/es1373.cpp
blob: 9279e3558cd632a0116068115c1369dd87c2dcb2 (plain) (tree)
1
2
3
4
5
6
7
8
9
                       
                              
                

                   


                    
                             
                             
                             
 
 



























































                                                                
                                                       

                                                  

                  
                                                                                              
 

                                         
                                                                                   
 
 
                                                                                                             


                                                                                                           
 
                                                        

 
                                            
 

                                             

 








                                                   
                                  





                                                   



                                                      



                                                                        
                                          

                                                                          











































                                            

 
                                      
 
                                       
                   



                                  




                                   
                                  



                                               



                                                    
                                 
                         
                             
                                  


                                  
                          
                              
                                   


                                  
                          
                              
                                   
                               


                                                                              

 

                                                                                                                                                      



                                      



                                                                                             
 








                                                                                                                               
                            
                                                                                      
         
 
                            
                                                                                                
         
 
                           
                                                     
                                                                                                              














                                                                                                                                                        
                                                                                                                                                      



                                                                                                             
                                                                                                                                                     











                                                                                                


                         


                                                                                                                
                                 


         


                                                    
                                                                                                                                  






                                                             
                                                        











                                                                                                                                       

                                                                                                                                                         











                                                                                                                                
                                                                                                                        



                                                                            
                                                                                                                           



                                                                                                                                 

                                                                                                        

















                                                                                                                   
                                                                                                                                       



                                                                                 
                                                                                                                                      











                                                                   

                                                                 
                                
                                                       






                                                                                                                                          




                                                                                
                        




                                                                    



                                                    
                                         

                 

 
                                                        














                                        
                                                                                 


                 

                                    
                                            


                              


                                                                                                    
                                         
                                                                                  

                                                             
                                                                 

                                              
                                                                
                                              




                                              
                                                                                  

                                                             
                                                                                          

                                              
                                                                                        
                                              




                                              
                                                                                  

                                                             
                                                                 
                                              




                                              
                                                                                  

                                                             
                                                                                            
                                              






                                              
                       
                                                                                                                                      






                                         




                                                                                                  

















                                                                                                                  






                                                                                                   


                                                                                                 






                                                                                                                                           
                                                                 
                                                                                                   
                                                                    
                                                                                                                                                

                                         
                                                    
                                                                                                                                                                                 




                                                              
                                         
                                                                                

                                                             
                                                               

                                              
                                                              
                                              




                                              
                                                                                

                                                             

                                                                             

                                              

                                                                            
                                              




                                              
                                                                                

                                                             
                                                               
                                              




                                              
                                                                                

                                                             

                                                                             
                                                       
                                                                                                                                                                   
                                              







                                              
                       
                                                                                                                                   

 
// license:BSD-3-Clause
// copyright-holders:Ted Green
#include "emu.h"
#include "es1373.h"

#include "speaker.h"


#define LOG_ES            (0)
#define LOG_ES_REG        (0)
#define LOG_ES_FILE       (0)


/* Ensonic ES1373 registers 0x00-0x3f */
#define ES_INT_CS_CTRL          (0x00/4)
#define ES_INT_CS_STATUS        (0x04/4)
#define ES_UART_DATA            (0x08/4)
#define ES_UART_STATUS          (0x09/4)
#define ES_UART_CTRL            (0x09/4)
#define ES_UART_RSVD            (0x0A/4)
#define ES_MEM_PAGE             (0x0C/4)
#define ES_SRC_IF               (0x10/4)
#define ES_CODEC                (0x14/4)
#define ES_LEGACY               (0x18/4)
#define ES_CHAN_CTRL            (0x1C/4)
#define ES_SERIAL_CTRL          (0x20/4)
#define ES_DAC1_CNT             (0x24/4)
#define ES_DAC2_CNT             (0x28/4)
#define ES_ADC_CNT              (0x2C/4)
#define ES_HOST_IF0             (0x30/4)
#define ES_HOST_IF1             (0x34/4)
#define ES_HOST_IF2             (0x38/4)
#define ES_HOST_IF3             (0x3C/4)

// Interrupt/Chip Select Control Register (ES_INT_CS_CTRL) bits
#define ICCTRL_ADC_STOP_MASK   0x00002000
#define ICCTRL_DAC1_EN_MASK    0x00000040
#define ICCTRL_DAC2_EN_MASK    0x00000020
#define ICCTRL_ADC_EN_MASK     0x00000010
#define ICCTRL_UART_EN_MASK    0x00000008
#define ICCTRL_JYSTK_EN_MASK   0x00000004

// Interrupt/Chip Select Status Register (ES_INT_CS_STATUS) bits
#define ICSTATUS_INTR_MASK        0x80000000
#define ICSTATUS_DAC1_INT_MASK    0x00000004
#define ICSTATUS_DAC2_INT_MASK    0x00000002
#define ICSTATUS_ADC_INT_MASK     0x00000001

// Serial Interface Control Register (ES_SERIAL_CTRL) bits
#define SCTRL_P2_END_MASK     0x00380000
#define SCTRL_P2_START_MASK   0x00070000
#define SCTRL_R1_LOOP_MASK    0x00008000
#define SCTRL_P2_LOOP_MASK    0x00004000
#define SCTRL_P1_LOOP_MASK    0x00002000
#define SCTRL_P2_PAUSE_MASK   0x00001000
#define SCTRL_P1_PAUSE_MASK   0x00000800
#define SCTRL_R1_INT_EN_MASK  0x00000400
#define SCTRL_P2_INT_EN_MASK  0x00000200
#define SCTRL_P1_INT_EN_MASK  0x00000100
#define SCTRL_P1_RELOAD_MASK  0x00000080
#define SCTRL_P2_STOP_MASK    0x00000040
#define SCTRL_R1_S_MASK       0x00000030
#define SCTRL_P2_S_MASK       0x0000000C
#define SCTRL_P1_S_MASK       0x00000003

#define SCTRL_8BIT_MONO             0x0
#define SCTRL_8BIT_STEREO           0x1
#define SCTRL_16BIT_MONO            0x2
#define SCTRL_16BIT_STEREO      0x3

#define ES_PCI_READ 0
#define ES_PCI_WRITE 1

MACHINE_CONFIG_START(es1373_device::device_add_mconfig)
	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();
MACHINE_CONFIG_END

DEFINE_DEVICE_TYPE(ES1373, es1373_device, "es1373", "Creative Labs Ensoniq AudioPCI97 ES1373")

void es1373_device::map(address_map &map)
{
	map(0x00, 0x3f).rw(FUNC(es1373_device::reg_r), FUNC(es1373_device::reg_w));
}

es1373_device::es1373_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: pci_device(mconfig, ES1373, tag, owner, clock)
	, device_sound_interface(mconfig, *this), m_stream(nullptr)
	, m_eslog(nullptr), m_tempCount(0), m_timer(nullptr), m_memory_space(nullptr), m_irq_handler(*this)
{
	set_ids(0x12741371, 0x04, 0x040100, 0x12741371);
}

void es1373_device::device_resolve_objects()
{
	pci_device::device_resolve_objects();
	m_irq_handler.resolve_safe();
}

//-------------------------------------------------
//  device_stop - device-specific stop
//-------------------------------------------------
void es1373_device::device_stop()
{
	/* debugging */
	if (LOG_ES_FILE && m_eslog)
	{
		fclose(m_eslog);
		m_eslog = nullptr;
	}
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------
void es1373_device::device_start()
{
	pci_device::device_start();
	add_map(0x40, M_IO, FUNC(es1373_device::map));

	// create the stream
	m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100/2);

	m_timer = timer_alloc(0, nullptr);
	m_timer->adjust(attotime::zero, 0, attotime::from_hz(44100/2/16));

	// Save states
	save_item(NAME(m_ac97_regs));
	save_item(NAME(m_es_regs));
	save_item(NAME(m_sound_cache));
	save_item(NAME(m_src_ram));
	save_item(NAME(m_dac1.number));
	save_item(NAME(m_dac1.enable));
	save_item(NAME(m_dac1.int_en));
	save_item(NAME(m_dac1.loop_en));
	save_item(NAME(m_dac1.initialized));
	save_item(NAME(m_dac1.format));
	save_item(NAME(m_dac1.buf_wptr));
	save_item(NAME(m_dac1.buf_rptr));
	save_item(NAME(m_dac1.buf_count));
	save_item(NAME(m_dac1.buf_size));
	save_item(NAME(m_dac1.pci_addr));
	save_item(NAME(m_dac1.pci_count));
	save_item(NAME(m_dac1.pci_size));
	save_item(NAME(m_dac2.number));
	save_item(NAME(m_dac2.enable));
	save_item(NAME(m_dac2.int_en));
	save_item(NAME(m_dac2.loop_en));
	save_item(NAME(m_dac2.initialized));
	save_item(NAME(m_dac2.format));
	save_item(NAME(m_dac2.buf_wptr));
	save_item(NAME(m_dac2.buf_rptr));
	save_item(NAME(m_dac2.buf_count));
	save_item(NAME(m_dac2.buf_size));
	save_item(NAME(m_dac2.pci_addr));
	save_item(NAME(m_dac2.pci_count));
	save_item(NAME(m_dac2.pci_size));
	save_item(NAME(m_adc.number));
	save_item(NAME(m_adc.enable));
	save_item(NAME(m_adc.int_en));
	save_item(NAME(m_adc.loop_en));
	save_item(NAME(m_adc.initialized));
	save_item(NAME(m_adc.format));
	save_item(NAME(m_adc.buf_wptr));
	save_item(NAME(m_adc.buf_rptr));
	save_item(NAME(m_adc.buf_count));
	save_item(NAME(m_adc.buf_size));
	save_item(NAME(m_adc.pci_addr));
	save_item(NAME(m_adc.pci_count));
	save_item(NAME(m_adc.pci_size));
}

void es1373_device::device_post_load()
{
	pci_device::device_post_load();
	remap_cb();
}

void es1373_device::device_reset()
{
	// debugging
	m_tempCount = 0;
	if (LOG_ES_FILE && m_eslog)
	{
		fclose(m_eslog);
		m_eslog = nullptr;
	}
	if (LOG_ES_FILE && !m_eslog)
		m_eslog = fopen("es.log", "w");

	pci_device::device_reset();
	memset(m_es_regs, 0, sizeof(m_es_regs));
	memset(m_ac97_regs, 0, sizeof(m_ac97_regs));
	m_ac97_regs[0] = 0x0800;
	// Reset ADC channel info
	m_adc.number = 0;
	m_adc.enable = false;
	m_adc.initialized = false;
	m_adc.buf_rptr = 0x20;
	m_adc.buf_wptr = 0x20;
	// Reset DAC1 channel info
	m_dac1.number = 1;
	m_dac1.enable = false;
	m_dac1.initialized = false;
	m_dac1.buf_rptr = 0x0;
	m_dac1.buf_wptr = 0x0;
	// Reset DAC2 channel info
	m_dac2.number = 2;
	m_dac2.enable = false;
	m_dac2.initialized = false;
	m_dac2.buf_rptr = 0x10;
	m_dac2.buf_wptr = 0x10;  // Start PCI writing to bottom half of buffer

	m_stream->update();
}

void es1373_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
							uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space)
{
	m_memory_space = memory_space;
}

//-------------------------------------------------
//  device_timer - called when our device timer expires
//-------------------------------------------------
void es1373_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
{
	m_stream->update();
}

//-------------------------------------------------
//  sound_stream_update - handle update requests for
//  our sound stream
//-------------------------------------------------
void es1373_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	if (m_dac1.enable) {
		logerror("%s: sound_stream_update DAC1 not implemented yet\n", tag());
	}

	if (m_dac2.enable) {
		send_audio_out(m_dac2, ICSTATUS_DAC2_INT_MASK, outputs[0], outputs[1], samples);
	}

	if (m_adc.enable) {
		if (m_adc.format!=SCTRL_16BIT_MONO) {
			logerror("%s: sound_stream_update Only SCTRL_16BIT_MONO recorded supported\n", tag());
		} else {
			for (int i=0; i<samples; i++) {
				if (m_adc.buf_count<=m_adc.buf_size) {
					if (LOG_ES)
						logerror("%s: ADC buf_count: %i buf_size: %i buf_rptr: %i buf_wptr: %i\n", machine().describe_context(),
							m_adc.buf_count, m_adc.buf_size, m_adc.buf_rptr, m_adc.buf_wptr);
					if ((m_adc.buf_count&0x1)) {
						m_adc.buf_wptr++;
					}
					m_adc.buf_count++;
					if (m_adc.buf_count>m_adc.buf_size) {
						if (m_adc.loop_en) {
							// Keep playing
							m_adc.buf_count = 0;
							if (LOG_ES)
								logerror("%s: send_audio_out ADC clearing buf_count\n", machine().describe_context());
						}
						if (m_adc.int_en) {
							m_es_regs[ES_INT_CS_STATUS] |= ICSTATUS_ADC_INT_MASK;
							if (LOG_ES)
								logerror("%s: send_audio_out Setting ADC interrupt\n", machine().describe_context());
						}
					}
					if (!(m_adc.buf_count&1) && !(m_adc.buf_wptr&0xf)) {
						m_adc.buf_wptr -= 0x10;
					}
					// PCI Write Transfer
					if (command & 0x4) {
						if ((m_adc.buf_rptr&8)^(m_adc.buf_wptr&8)) {
							transfer_pci_audio(m_adc, ES_PCI_WRITE);
						}
					}
				}
			}
		}
	}
	if (m_es_regs[ES_INT_CS_STATUS]&(ICSTATUS_DAC1_INT_MASK|ICSTATUS_DAC2_INT_MASK|ICSTATUS_ADC_INT_MASK)) {
		m_es_regs[ES_INT_CS_STATUS] |= ICSTATUS_INTR_MASK;
		// Assert interrupt
		m_irq_handler(1);
	}
}

//-------------------------------------------------
//  send_audio_out - Sends channel audio output data
//-------------------------------------------------
void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_sample_t *outL, stream_sample_t *outR, int samples)
{
	// Only transfer PCI data if bus mastering is enabled
	// Fill initial half buffer
	if (1 && (command & 0x4) && (!chan.initialized)) {
		chan.initialized = true;
		transfer_pci_audio(chan, ES_PCI_READ);
	}
	//uint32_t sample_size = calc_size(chan.format);
	// Send data to sound stream
	bool buf_row_done;
	for (int i=0; i<samples; i++) {
		buf_row_done = false;
		if (chan.buf_count<=chan.buf_size) {
			// Only transfer PCI data if bus mastering is enabled
			// Fill half-buffer when read pointer is at start of next half
			//if ((command & 0x4) && ((chan.buf_rptr&8)^(chan.buf_wptr&8)) && !(m_es_regs[ES_INT_CS_STATUS] & intr_mask)) {
			if ((command & 0x4) && ((chan.buf_rptr&8)^(chan.buf_wptr&8))) {
				transfer_pci_audio(chan, ES_PCI_READ);
			}
			if (LOG_ES && i==0)
				logerror("%s: chan: %X samples: %i buf_count: %X buf_size: %X buf_rptr: %X buf_wptr: %X\n",
					machine().describe_context(), chan.number, samples, chan.buf_count, chan.buf_size, chan.buf_rptr, chan.buf_wptr);
			// Buffer is 4 bytes per location, need to switch on sample mode
			switch (chan.format) {
				case SCTRL_8BIT_MONO:
					logerror("es1373_device::send_audio_out SCTRL_8BIT_MONO not implemented yet\n");
					break;
				case SCTRL_8BIT_STEREO:
					logerror("es1373_device::send_audio_out SCTRL_8BIT_STEREO not implemented yet\n");
					break;
				case SCTRL_16BIT_MONO:
						// The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples
						if ((chan.buf_count&0x1)) {
							// Read high 16 bits
							outL[i] = outR[i] = (int16_t)(m_sound_cache[chan.buf_rptr]>>16);
							chan.buf_rptr++;
							buf_row_done = true;
						} else {
							// Read low 16 bits
							outL[i] = outR[i] = (int16_t)(m_sound_cache[chan.buf_rptr]&0xffff);
						}
					break;
				case SCTRL_16BIT_STEREO:
						// The sound cache is 32 bit wide fifo, so each entry is one stereo 16 bit sample
						outL[i] = (int16_t) m_sound_cache[chan.buf_rptr]&0xffff;
						outR[i] = (int16_t) m_sound_cache[chan.buf_rptr]>>16;
						chan.buf_rptr++;
						buf_row_done = true;
					break;
			}
			if (LOG_ES_FILE && m_tempCount<1000000) {
				m_tempCount++;
				//logerror("es1373_device::sound_stream_update count: %i samp16: %X\n", i, samp16);
				//if (LOG_ES_FILE && m_eslog)
					//fprintf(m_eslog, "%i\n", samp16);
			}
			chan.buf_count++;
			if (chan.buf_count > chan.buf_size) {
				if (chan.loop_en) {
					// Keep playing
					//chan.buf_count -= 1;  // Should check SCTRL_P2_END_MASK
					chan.buf_count = 0;
					//chan.buf_rptr -= 1;
					if (LOG_ES)
						logerror("%s: send_audio_out DAC2 clearing buf_count\n", machine().describe_context());
				}
				if (chan.int_en) {
					m_es_regs[ES_INT_CS_STATUS] |= intr_mask;
					if (LOG_ES)
						logerror("%s: send_audio_out Setting DAC2 interrupt\n", machine().describe_context());
				}
			}
			if (buf_row_done && !(chan.buf_rptr&0xf)) {
				chan.buf_rptr -= 0x10;
			}
		} else {
			// Send zeros?
			outL[i] = outR[i] = 0;
		}
	}
}

void es1373_device::transfer_pci_audio(chan_info& chan, int type)
{
	uint32_t pci_addr, data;
	pci_addr = chan.pci_addr + (chan.pci_count<<2);
	if (LOG_ES)
		logerror("%s: transfer_pci_audio start chan: %X pci_addr: %08X pci_count: %X pci_size: %X buf_rptr: %X buf_wptr: %X\n",
			machine().describe_context(), chan.number, pci_addr, chan.pci_count, chan.pci_size, chan.buf_rptr, chan.buf_wptr);
	// Always transfer 8 longwords
	for (int i=0; i<8; i++) {
		pci_addr = chan.pci_addr + (chan.pci_count<<2);
		if (type==ES_PCI_READ) {
			data = m_memory_space->read_dword(pci_addr, 0xffffffff);
			m_sound_cache[chan.buf_wptr++] = data;
			if (!(chan.buf_wptr&0xf)) {
				chan.buf_wptr -= 0x10;
			}
		} else {
			data = m_sound_cache[chan.buf_rptr++];
			m_memory_space->write_dword(pci_addr, data);
			if (!(chan.buf_rptr&0xf)) {
				chan.buf_rptr -= 0x10;
			}
		}
		if (chan.pci_count==chan.pci_size) {
			chan.pci_count = 0;
		} else {
			chan.pci_count++;
		}
	}
}

uint32_t es1373_device::calc_size(const uint8_t &format)
{
	switch (format) {
		case SCTRL_8BIT_MONO:
			return 1;
			break;
		case SCTRL_8BIT_STEREO:
			return 2;
			break;
		case SCTRL_16BIT_MONO:
			return 2;
			break;
		case SCTRL_16BIT_STEREO:
			return 4;
			break;
	}
	logerror("%s: calc_size Invalid format = %X specified\n", tag(), format);
	return 0;
}

READ32_MEMBER (es1373_device::reg_r)
{
	uint32_t result = m_es_regs[offset];
	switch (offset) {
		case ES_CODEC:
			break;
		case ES_DAC2_CNT:
				result = ((m_dac2.buf_size-m_dac2.buf_count)<<16) | m_dac2.buf_size;
			break;
		case ES_HOST_IF0: // 0x30
			result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x0];
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					result = m_dac1.pci_addr;
					break;
				case 0xd:
					result = m_adc.pci_addr;
					break;
				default:
					break;
			}
			break;
		case ES_HOST_IF1: // 0x34
			result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x1];
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					result = (m_dac1.pci_count<<16) | m_dac1.pci_size;
					break;
				case 0xd:
					result = (m_adc.pci_count<<16) | m_adc.pci_size;
					break;
				default:
					break;
			}
			break;
		case ES_HOST_IF2: // 0x38
			result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x2];
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					result = m_dac2.pci_addr;
					break;
				default:
					break;
			}
			break;
		case ES_HOST_IF3: // 0x3C
			result = m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x3];
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					result = ((m_dac2.pci_count)<<16) | m_dac2.pci_size;
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}
	if (LOG_ES_REG)
		logerror("%s:ES1373 read from offset %02X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
	return result;
}

WRITE32_MEMBER(es1373_device::reg_w)
{
	COMBINE_DATA(&m_es_regs[offset]);
	switch (offset) {
		case ES_INT_CS_CTRL:
				m_dac1.enable = (m_es_regs[ES_INT_CS_CTRL] & ICCTRL_DAC1_EN_MASK);
				m_dac2.enable = (m_es_regs[ES_INT_CS_CTRL] & ICCTRL_DAC2_EN_MASK);
				m_adc.enable = (m_es_regs[ES_INT_CS_CTRL] & ICCTRL_ADC_EN_MASK);
			break;
		case ES_SRC_IF:
			if (data&(1<<24)) {
				// Write to Sample Rate Converter Ram
				m_src_ram[(data>>25)&0x7F] = data&0xFFFF;
			} else {
				// Read From Sample Rate Converter Ram
				m_es_regs[offset] = (data&0xFFFF0000) | m_src_ram[(data>>25)&0x7F];
			}
			break;
		case ES_CODEC:
			if (data&(1<<23)) {
				// Read from AC97 codec registers
				m_es_regs[offset] = (data&0xFFFF0000) | m_ac97_regs[(data>>16)&0x7f] | 0x80000000;
			} else {
				// Write to AC97 codec registers
				m_ac97_regs[(data>>16)&0x7f] = data&0xFFFF;
			}
			break;
		case ES_SERIAL_CTRL:
				m_adc.loop_en  = !(m_es_regs[ES_SERIAL_CTRL] & SCTRL_R1_LOOP_MASK);
				m_dac2.loop_en = !(m_es_regs[ES_SERIAL_CTRL] & SCTRL_P2_LOOP_MASK);
				m_dac1.loop_en = !(m_es_regs[ES_SERIAL_CTRL] & SCTRL_P1_LOOP_MASK);
				m_adc.int_en  = m_es_regs[ES_SERIAL_CTRL] & SCTRL_R1_INT_EN_MASK;
				m_dac2.int_en = m_es_regs[ES_SERIAL_CTRL] & SCTRL_P2_INT_EN_MASK;
				m_dac1.int_en = m_es_regs[ES_SERIAL_CTRL] & SCTRL_P1_INT_EN_MASK;
				m_adc.format = (m_es_regs[ES_SERIAL_CTRL] & SCTRL_R1_S_MASK)>>4;
				m_dac2.format = (m_es_regs[ES_SERIAL_CTRL] & SCTRL_P2_S_MASK)>>2;
				m_dac1.format = (m_es_regs[ES_SERIAL_CTRL] & SCTRL_P1_S_MASK)>>0;
				if (!m_adc.int_en) m_es_regs[ES_INT_CS_STATUS]  &= ~ICSTATUS_ADC_INT_MASK;
				if (!m_dac1.int_en) m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_DAC1_INT_MASK;
				if (!m_dac2.int_en) m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_DAC2_INT_MASK;
				// Clear the summary interrupt and irq line
				if (!(m_es_regs[ES_INT_CS_STATUS]&(ICSTATUS_DAC1_INT_MASK|ICSTATUS_DAC2_INT_MASK|ICSTATUS_ADC_INT_MASK))) {
					// Deassert interrupt
					if (m_es_regs[ES_INT_CS_STATUS]&ICSTATUS_INTR_MASK && m_irq_num!=-1) {
						m_irq_handler(0);
						m_es_regs[ES_INT_CS_STATUS] &= ~ICSTATUS_INTR_MASK;
						if (0 && LOG_ES_REG)
							logerror("%s: es1373_device::reg_w Clearing interrupt\n", machine().describe_context());
					}
				}
				if (0 && LOG_ES_REG)
					logerror("%s: es1373_device::reg_w adc_int_en: %i dac1_int_en: %i dac2_int_en: %i\n", tag(), m_adc.int_en, m_dac1.int_en, m_dac2.int_en);
			break;
		case ES_DAC2_CNT:
				m_dac2.buf_count = 0;
				m_dac2.buf_size = data&0xffff;
			break;
		case ES_HOST_IF0: // 0x30
			m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x0] = data;
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					m_dac1.pci_addr = data;
					break;
				case 0xd:
					m_adc.pci_addr = data;
					break;
				default:
					break;
			}
			break;
		case ES_HOST_IF1: // 0x34
			m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x1] = data;
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					m_dac1.pci_count = (data>>16)&0xffff;
					m_dac1.pci_size = data&0xffff;
					break;
				case 0xd:
					m_adc.pci_count = (data>>16)&0xffff;
					m_adc.pci_size = data&0xffff;
					break;
				default:
					break;
			}
			break;
		case ES_HOST_IF2: // 0x38
			m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x2] = data;
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					m_dac2.pci_addr = data;
					break;
				default:
					break;
			}
			break;
		case ES_HOST_IF3: // 0x3C
			m_sound_cache[(m_es_regs[ES_MEM_PAGE]<<2) | 0x3] = data;
			switch (m_es_regs[ES_MEM_PAGE]&0xf) {
				case 0xc:
					m_dac2.pci_count = (data>>16)&0xffff;
					m_dac2.pci_size = data&0xffff;
					if (LOG_ES_REG)
						logerror("%s:ES1373 write to offset %02X = %08X & %08X\n", machine().describe_context(), offset*4, data, mem_mask);
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}

	if (LOG_ES_REG)
		logerror("%s:ES1373 write to offset %02X = %08X & %08X\n", machine().describe_context(), offset*4, data, mem_mask);

}