⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sb16_dsp.c

📁 minix操作系统最新版本(3.1.1)的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*===========================================================================* *				reply					     * *===========================================================================*/PRIVATE void reply(code, replyee, process, status)int code;int replyee;int process;int status;{	message m;	m.m_type = code;		/* TASK_REPLY or REVIVE */	m.REP_STATUS = status;	/* result of device operation */	m.REP_PROC_NR = process;	/* which user made the request */	send(replyee, &m);}/*===========================================================================* *				init_buffer *===========================================================================*/PRIVATE void init_buffer(){/* Select a buffer that can safely be used for dma transfers.   * Its absolute address is 'DmaPhys', the normal address is 'DmaPtr'. */#if (CHIP == INTEL)	unsigned left;	DmaPtr = DmaBuffer;	sys_umap(SELF, D, (vir_bytes)DmaBuffer, (phys_bytes)sizeof(DmaBuffer), &DmaPhys);	if((left = dma_bytes_left(DmaPhys)) < DMA_SIZE) {		/* First half of buffer crosses a 64K boundary, can't DMA into that */		DmaPtr += left;		DmaPhys += left;	}#else /* CHIP != INTEL */	panic("SB16DSP","init_buffer() failed, CHIP != INTEL", 0);#endif /* CHIP == INTEL */}/*===========================================================================* *				dsp_init *===========================================================================*/PRIVATE int dsp_init(){	int i, s;	if(dsp_reset () != OK) { 		dprint("sb16: No SoundBlaster card detected\n");		return -1;	}	DspVersion[0] = DspVersion[1] = 0;	dsp_command(DSP_GET_VERSION);	/* Get DSP version bytes */	for(i = 1000; i; i--) {		if(sb16_inb(DSP_DATA_AVL) & 0x80) {					if(DspVersion[0] == 0) {				DspVersion[0] = sb16_inb(DSP_READ);			} else {				DspVersion[1] = sb16_inb(DSP_READ);				break;			}		}	}	if(DspVersion[0] < 4) {		dprint("sb16: No SoundBlaster 16 compatible card detected\n");		return -1;	} 		dprint("sb16: SoundBlaster DSP version %d.%d detected\n", DspVersion[0], DspVersion[1]);	/* set SB to use our IRQ and DMA channels */	mixer_set(MIXER_SET_IRQ, (1 << (SB_IRQ / 2 - 1)));	mixer_set(MIXER_SET_DMA, (1 << SB_DMA_8 | 1 << SB_DMA_16)); 	/* register interrupt vector and enable irq */	if ((s=sys_irqsetpolicy(SB_IRQ, IRQ_REENABLE, &irq_hook_id )) != OK)  		panic("SB16DSP", "Couldn't set IRQ policy", s);	if ((s=sys_irqenable(&irq_hook_id)) != OK)  		panic("SB16DSP", "Couldn't enable IRQ", s);	DspAvail = 1;	return OK;}/*===========================================================================* *				dsp_reset *===========================================================================*/PRIVATE int dsp_reset(){	int i;	sb16_outb(DSP_RESET, 1);	for(i = 0; i < 1000; i++); /* wait a while */	sb16_outb(DSP_RESET, 0);	for(i = 0; i < 1000 && !(sb16_inb(DSP_DATA_AVL) & 0x80); i++); 			if(sb16_inb(DSP_READ) != 0xAA) return EIO; /* No SoundBlaster */	DmaBusy = -1;	return OK;}/*===========================================================================* *				dsp_command *===========================================================================*/PRIVATE int dsp_command(value)int value;{	int i, status;	for (i = 0; i < SB_TIMEOUT; i++) {		if((sb16_inb(DSP_STATUS) & 0x80) == 0) {			sb16_outb(DSP_COMMAND, value);			return OK;		}	}	dprint("sb16: SoundBlaster: DSP Command(%x) timeout\n", value);	return -1;}/*===========================================================================* *				dsp_set_size *===========================================================================*/static int dsp_set_size(size)unsigned int size;{	dprint("dsp_set_size(): set fragment size to %u\n", size);	/* Sanity checks */	if(size < DSP_MIN_FRAGMENT_SIZE || size > DSP_MAX_FRAGMENT_SIZE || size % 2 != 0) {		return EINVAL;	}	DspFragmentSize = size; 	return OK;}/*===========================================================================* *				dsp_set_speed *===========================================================================*/static int dsp_set_speed(speed)unsigned int speed;{	dprint("sb16: setting speed to %u, stereo = %d\n", speed, DspStereo);	if(speed < DSP_MIN_SPEED || speed > DSP_MAX_SPEED) {		return EPERM;	}	/* Soundblaster 16 can be programmed with real sample rates	* instead of time constants	*	* Since you cannot sample and play at the same time	* we set in- and output rate to the same value 	*/	dsp_command(DSP_INPUT_RATE);		/* set input rate */	dsp_command(speed >> 8);			/* high byte of speed */	dsp_command(speed);			 		/* low byte of speed */	dsp_command(DSP_OUTPUT_RATE);		/* same for output rate */	dsp_command(speed >> 8);		dsp_command(speed); 	DspSpeed = speed;	return OK;}/*===========================================================================* *				dsp_set_stereo *===========================================================================*/static int dsp_set_stereo(stereo)unsigned int stereo;{	if(stereo) { 		DspStereo = 1;	} else { 		DspStereo = 0;	}	return OK;}/*===========================================================================* *				dsp_set_bits *===========================================================================*/static int dsp_set_bits(bits)unsigned int bits;{	/* Sanity checks */	if(bits != 8 && bits != 16) {		return EINVAL;	}	DspBits = bits; 	return OK;}/*===========================================================================* *				dsp_set_sign *===========================================================================*/static int dsp_set_sign(sign)unsigned int sign;{	dprint("sb16: set sign to %u\n", sign);	DspSign = (sign > 0 ? 1 : 0); 	return OK;}/*===========================================================================* *				dsp_dma_setup *===========================================================================*/PRIVATE void dsp_dma_setup(address, count)phys_bytes address;int count;{	pvb_pair_t pvb[9];	dprint("Setting up %d bit DMA\n", DspBits);	if(DspBits == 8) {   /* 8 bit sound */		count--;     		pv_set(pvb[0], DMA8_MASK, SB_DMA_8 | 0x04);      /* Disable DMA channel */		pv_set(pvb[1], DMA8_CLEAR, 0x00);		       /* Clear flip flop */		/* set DMA mode */		pv_set(pvb[2], DMA8_MODE, (DmaMode == DEV_WRITE ? DMA8_AUTO_PLAY : DMA8_AUTO_REC)); 		pv_set(pvb[3], DMA8_ADDR, address >>  0);        /* Low_byte of address */		pv_set(pvb[4], DMA8_ADDR, address >>  8);        /* High byte of address */		pv_set(pvb[5], DMA8_PAGE, address >> 16);        /* 64K page number */		pv_set(pvb[6], DMA8_COUNT, count >> 0);          /* Low byte of count */		pv_set(pvb[7], DMA8_COUNT, count >> 8);          /* High byte of count */		pv_set(pvb[8], DMA8_MASK, SB_DMA_8);	       /* Enable DMA channel */		sys_voutb(pvb, 9);	} else {  /* 16 bit sound */		count-= 2;		pv_set(pvb[0], DMA16_MASK, (SB_DMA_16 & 3) | 0x04);	/* Disable DMA channel */				pv_set(pvb[1], DMA16_CLEAR, 0x00);                  /* Clear flip flop */		/* Set dma mode */		pv_set(pvb[2], DMA16_MODE, (DmaMode == DEV_WRITE ? DMA16_AUTO_PLAY : DMA16_AUTO_REC));        		pv_set(pvb[3], DMA16_ADDR, (address >> 1) & 0xFF);  /* Low_byte of address */		pv_set(pvb[4], DMA16_ADDR, (address >> 9) & 0xFF);  /* High byte of address */		pv_set(pvb[5], DMA16_PAGE, (address >> 16) & 0xFE); /* 128K page number */		pv_set(pvb[6], DMA16_COUNT, count >> 1);            /* Low byte of count */		pv_set(pvb[7], DMA16_COUNT, count >> 9);            /* High byte of count */		pv_set(pvb[8], DMA16_MASK, SB_DMA_16 & 3);          /* Enable DMA channel */		sys_voutb(pvb, 9);	}}/*===========================================================================* *				dsp_setup() *===========================================================================*/PRIVATE void dsp_setup(){ 	/* Set current sample speed */	dsp_set_speed(DspSpeed);	/* Put the speaker on */	if(DmaMode == DEV_WRITE) {		dsp_command (DSP_CMD_SPKON); /* put speaker on */		/* Program DSP with dma mode */		dsp_command((DspBits == 8 ? DSP_CMD_8BITAUTO_OUT : DSP_CMD_16BITAUTO_OUT));     	} else {		dsp_command (DSP_CMD_SPKOFF); /* put speaker off */		/* Program DSP with dma mode */		dsp_command((DspBits == 8 ? DSP_CMD_8BITAUTO_IN : DSP_CMD_16BITAUTO_IN));     	}	/* Program DSP with transfer mode */	if (!DspSign) {		dsp_command((DspStereo == 1 ? DSP_MODE_STEREO_US : DSP_MODE_MONO_US));	} else {		dsp_command((DspStereo == 1 ? DSP_MODE_STEREO_S : DSP_MODE_MONO_S));	}	/* Give length of fragment to DSP */	if (DspBits == 8) { /* 8 bit transfer */		/* #bytes - 1 */		dsp_command((DspFragmentSize - 1) >> 0); 		dsp_command((DspFragmentSize - 1) >> 8);	} else {             /* 16 bit transfer */		/* #words - 1 */		dsp_command((DspFragmentSize - 1) >> 1);		dsp_command((DspFragmentSize - 1) >> 9);	}}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -