📄 sb.c
字号:
sx_sb_dma_count++; if (sx_sb_dma_count > 16) { sx_sb_bufnum = (_dma_todo(sx_sb_dma) > (unsigned)sx_sb_dma_size) ? 1 : 0; sx_sb_dma_count = 0; } } if (!sx_sb_semaphore) { sx_sb_semaphore = TRUE; ENABLE(); /* mix some more samples */ sx_sb_mix_some_samples(sx_sb_buf[sx_sb_bufnum], _dos_ds); DISABLE(); sx_sb_semaphore = FALSE; } sx_sb_bufnum = 1 - sx_sb_bufnum; if (sx_sb_16bit) /* acknowledge SB */ inportb(sx_sb_port+0x0F); else inportb(sx_sb_port+0x0E); _eoi(sx_sb_irq); /* acknowledge interrupt */ return 0;}static END_OF_FUNCTION(sx_sb_interrupt);void sx_sb_mix_some_samples(unsigned long buf, unsigned short seg){ int i; if (sx_sb_mute) { _farsetsel(seg); if (sx_sb_16bit) { for (i=0; i<sx_sb_dma_mix_size; i++) { _farnspokew(buf, 0x0); buf += 2; } } else { for (i=0; i<sx_sb_dma_mix_size; i++) { _farnspokeb(buf, 0x80); buf++; } } } else { extern void S9xMixSamples (unsigned char *, int); S9xMixSamples ((unsigned char *) mixbuffer, sx_sb_dma_mix_size); if (sx_sb_16bit) movedata(_my_ds(), (int)mixbuffer, seg, buf, sx_sb_dma_mix_size << 1); else movedata(_my_ds(), (int)mixbuffer, seg, buf, sx_sb_dma_mix_size); }}static END_OF_FUNCTION(sx_sb_mix_some_samples);/* sx_sb_start: * Starts up the sound output. */static void sx_sb_start(){ sx_sb_bufnum = 0; sx_sb_voice(1); sx_sb_set_sample_rate(sx_sb_freq); if ((sx_sb_hw_dsp_ver >= 0x300) && (sx_sb_dsp_ver < 0x400)) sx_sb_stereo_mode(sx_sb_stereo); if (sx_sb_dsp_ver <= 0x200) _dma_start(sx_sb_dma, sx_sb_buf[0], sx_sb_dma_size, FALSE, FALSE); else _dma_start(sx_sb_dma, sx_sb_buf[0], sx_sb_dma_size*2, TRUE, FALSE); sx_sb_play_buffer(sx_sb_dma_size);}/* sx_sb_stop: * Stops the sound output. */static void sx_sb_stop(){ /* halt sound output */ sx_sb_voice(0); /* stop dma transfer */ _dma_stop(sx_sb_dma); if (sx_sb_dsp_ver <= 0x0200) sx_sb_write_dsp(0xD0); sx_sb_reset_dsp(1);}/* sx_sb_detect: * SB detection routine. Uses the BLASTER environment variable, * or 'sensible' guesses if that doesn't exist. */int sx_sb_detect (int *stereo, int *bits16){ char *blaster = getenv("BLASTER"); char *msg; int cmask; int max_freq; int default_freq; /* parse BLASTER env */ if (blaster) { while (*blaster) { while ((*blaster == ' ') || (*blaster == '\t')) blaster++; if (*blaster) { switch (*blaster) { case 'a': case 'A': if (sx_sb_port < 0) sx_sb_port = strtol(blaster+1, NULL, 16); break; case 'i': case 'I': if (sx_sb_irq < 0) sx_sb_irq = strtol(blaster+1, NULL, 10); break; case 'd': case 'D': sx_sb_dma8 = strtol(blaster+1, NULL, 10); break; case 'h': case 'H': sx_sb_dma16 = strtol(blaster+1, NULL, 10); break; } while ((*blaster) && (*blaster != ' ') && (*blaster != '\t')) blaster++; } } } if (sx_sb_port < 0) sx_sb_port = 0x220; /* make sure we got a good port address */ if (sx_sb_reset_dsp(1) != 0) { static int bases[] = { 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0 }; int i; for (i=0; bases[i]; i++) { sx_sb_port = bases[i]; if (sx_sb_reset_dsp(1) == 0) break; } } /* check if the card really exists */ sx_sb_read_dsp_version(); if (sx_sb_hw_dsp_ver < 0) { strcpy(allegro_error, "Sound Blaster not found"); return FALSE; } sx_sb_dsp_ver = sx_sb_hw_dsp_ver; if (sx_sb_dsp_ver >= 0x400) { /* read configuration from SB16 card */ if (sx_sb_irq < 0) { outportb(sx_sb_port+4, 0x80); cmask = inportb(sx_sb_port+5); if (cmask&1) sx_sb_irq = 2; /* or 9? */ if (cmask&2) sx_sb_irq = 5; if (cmask&4) sx_sb_irq = 7; if (cmask&8) sx_sb_irq = 10; } if ((sx_sb_dma8 < 0) || (sx_sb_dma16 < 0)) { outportb(sx_sb_port+4, 0x81); cmask = inportb(sx_sb_port+5); if (sx_sb_dma8 < 0) { if (cmask&1) sx_sb_dma8 = 0; if (cmask&2) sx_sb_dma8 = 1; if (cmask&8) sx_sb_dma8 = 3; } if (sx_sb_dma16 < 0) { sx_sb_dma16 = sx_sb_dma8; if (cmask&0x20) sx_sb_dma16 = 5; if (cmask&0x40) sx_sb_dma16 = 6; if (cmask&0x80) sx_sb_dma16 = 7; } } } /* if nothing else works */ if (sx_sb_irq < 0) sx_sb_irq = 5; if (sx_sb_dma8 < 0) sx_sb_dma8 = 1; if (sx_sb_dma16 < 0) sx_sb_dma16 = 5; /* figure out the hardware interrupt number */ sx_sb_int = _map_irq(sx_sb_irq); /* what breed of SB? */ if (sx_sb_dsp_ver >= 0x400) { msg = "SB 16"; max_freq = 45454; default_freq = 22727; } else if (sx_sb_dsp_ver >= 0x300) { msg = "SB Pro"; max_freq = 22727; default_freq = 22727; } else if (sx_sb_dsp_ver >= 0x201) { msg = "SB 2.0"; max_freq = 45454; default_freq = 22727; } else if (sx_sb_dsp_ver >= 0x200) { msg = "SB 1.5"; max_freq = 16129; default_freq = 16129; } else { msg = "SB 1.0"; max_freq = 16129; default_freq = 16129; } /* set up the playback frequency */ if (sx_sb_freq <= 0) sx_sb_freq = default_freq;#if 0 if (sx_sb_freq < 15000) { sx_sb_freq = 11906; sx_sb_dma_size = 128; } else if (MIN(sx_sb_freq, max_freq) < 20000) { sx_sb_freq = 16129; sx_sb_dma_size = 128; } else if (MIN(sx_sb_freq, max_freq) < 40000) { sx_sb_freq = 22727; sx_sb_dma_size = 256; } else { sx_sb_freq = 45454; sx_sb_dma_size = 512; }#endif if (sx_sb_dsp_ver <= 0x200) sx_sb_dma_size *= 4; sx_sb_dma_mix_size = sx_sb_dma_size; /* can we handle 16 bit sound? */ if (sx_sb_dsp_ver >= 0x400) { if (sx_sb_dma < 0) sx_sb_dma = sx_sb_dma16; else sx_sb_dma16 = sx_sb_dma; sx_sb_16bit = TRUE; sx_sb_dma_size <<= 1; } else { if (sx_sb_dma < 0) sx_sb_dma = sx_sb_dma8; else sx_sb_dma8 = sx_sb_dma; sx_sb_16bit = FALSE; } /* can we handle stereo? */ if (sx_sb_dsp_ver >= 0x300 && *stereo) { sx_sb_dma_size <<= 1; sx_sb_dma_mix_size <<= 1; sx_sb_stereo = TRUE; } else { sx_sb_stereo = FALSE; } *bits16 = sx_sb_16bit; *stereo = sx_sb_stereo; /* set up the card description */ sprintf(sx_sb_desc, "%s (%d hz) on port %X, using IRQ %d and DMA channel %d", msg, sx_sb_freq, sx_sb_port, sx_sb_irq, sx_sb_dma); return TRUE;}/* sx_sb_init: * SB init routine: returns zero on success, -1 on failure. */int sx_sb_init (int *stereo, int *bits16, int *freq, int *dmamixsize){ sx_sb_dsp_ver = -1; if (*dmamixsize < SB_DMA_BUFFER_SIZE) *dmamixsize = SB_DMA_BUFFER_SIZE; else if (*dmamixsize > 8191) *dmamixsize = 8192; sx_sb_dma_size = sx_sb_dma_mix_size = *dmamixsize; if (*freq > 5000 && *freq <= 44100) sx_sb_freq = *freq; if (!sx_sb_detect (stereo, bits16)) return -1; *dmamixsize = sx_sb_dma_mix_size; mixbuffer = calloc(1, sx_sb_dma_mix_size * sizeof (short)); if (!mixbuffer) return -1; memset (mixbuffer, 0, sx_sb_dma_mix_size * sizeof (short)); _go32_dpmi_lock_data(mixbuffer, sx_sb_dma_mix_size*sizeof(short)); if (sx_sb_dsp_ver <= 0x200) { /* two conventional mem buffers */ if ((_dma_allocate_mem(sx_sb_dma_size, &sx_sb_sel[0], &sx_sb_buf[0]) != 0) || (_dma_allocate_mem(sx_sb_dma_size, &sx_sb_sel[1], &sx_sb_buf[1]) != 0)) return -1; } else { /* auto-init dma, one big buffer */ if (_dma_allocate_mem(sx_sb_dma_size*2, &sx_sb_sel[0], &sx_sb_buf[0]) != 0) return -1; sx_sb_sel[1] = sx_sb_sel[0]; sx_sb_buf[1] = sx_sb_buf[0] + sx_sb_dma_size; } sx_sb_lock_mem();#if 0 if (_mixer_init(sx_sb_dma_mix_size, sx_sb_freq, sx_sb_stereo, sx_sb_16bit, &digi_sb.voices) != 0) return -1;#endif sx_sb_mix_some_samples(sx_sb_buf[0], _dos_ds); sx_sb_mix_some_samples(sx_sb_buf[1], _dos_ds); _enable_irq(sx_sb_irq); _install_irq(sx_sb_int, sx_sb_interrupt); sx_sb_start(); sx_sb_in_use = TRUE; return 0;}/* sx_sb_exit: * SB driver cleanup routine, removes ints, stops dma, frees buffers, etc. */void sx_sb_exit (){ sx_sb_stop(); _remove_irq(sx_sb_int); _restore_irq(sx_sb_irq); __dpmi_free_dos_memory(sx_sb_sel[0]); if (sx_sb_sel[1] != sx_sb_sel[0]) __dpmi_free_dos_memory(sx_sb_sel[1]); free (mixbuffer); mixbuffer = NULL; sx_sb_hw_dsp_ver = sx_sb_dsp_ver = -1; sx_sb_in_use = FALSE;}/* sx_sb_lock_mem: * Locks all the memory touched by parts of the SB code that are executed * in an interrupt context. */static void sx_sb_lock_mem(){ LOCK_VARIABLE(sx_sb_freq); LOCK_VARIABLE(sx_sb_port); LOCK_VARIABLE(sx_sb_dma); LOCK_VARIABLE(sx_sb_irq); LOCK_VARIABLE(sx_sb_int); LOCK_VARIABLE(sx_sb_in_use); LOCK_VARIABLE(sx_sb_16bit); LOCK_VARIABLE(sx_sb_dsp_ver); LOCK_VARIABLE(sx_sb_hw_dsp_ver); LOCK_VARIABLE(sx_sb_dma_size); LOCK_VARIABLE(sx_sb_dma_mix_size); LOCK_VARIABLE(sx_sb_sel); LOCK_VARIABLE(sx_sb_buf); LOCK_VARIABLE(sx_sb_bufnum); LOCK_VARIABLE(sx_sb_dma_count); LOCK_VARIABLE(sx_sb_semaphore); LOCK_FUNCTION(sx_sb_play_buffer); LOCK_FUNCTION(sx_sb_interrupt); LOCK_FUNCTION(sx_sb_mix_some_samples);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -