home *** CD-ROM | disk | FTP | other *** search
- /* Include file for C-- Sound Blaster library */
-
- /* Defines for Sound Blaster and Sound Blaster Pro IO address */
- ?define LEFT_FM_STATUS 0x00 /* Pro only */
- ?define LEFT_FM_ADDRESS 0x00 /* Pro only */
- ?define LEFT_FM_DATA 0x01 /* Pro only */
- ?define RIGHT_FM_STATUS 0x02 /* Pro only */
- ?define RIGHT_FM_ADDRESS 0x02 /* Pro only */
- ?define RIGHT_FM_DATA 0x03 /* Pro only */
- ?define MIXER_ADDRESS 0x04 /* Pro only */
- ?define MIXER_DATA 0x05 /* Pro only */
- ?define DSP_RESET 0x06
- ?define FM_STATUS 0x08
- ?define FM_ADDRESS 0x08
- ?define FM_DATA 0x09
- ?define DSP_READ_DATA 0x0A
- ?define DSP_WRITE_DATA 0x0C
- ?define DSP_WRITE_STATUS 0x0C
- ?define DSP_DATA_AVAIL 0x0E
- ?define CD_ROM_DATA 0x10 /* Pro only */
- ?define CD_ROM_STATUS 0x11 /* Pro only */
- ?define CD_ROM_RESET 0x12 /* Pro only */
- ?define CD_ROM_ENABLE 0x13 /* Pro only */
-
- ?define ADLIB_FM_STATUS 0x388
- ?define ADLIB_FM_ADDRESS 0x388
- ?define ADLIB_FM_DATA 0x389
-
- /* Defines for 8237 DMA Controller IO addresses (not used currently) */
- /*
- ?define DMA 0x00
- ?define CH0_BASE DMA+0
- ?define CH0_COUNT DMA+1
- ?define CH1_BASE DMA+2
- ?define CH1_COUNT DMA+3
- ?define CH2_BASE DMA+4
- ?define CH2_COUNT DMA+5
- ?define CH3_BASE DMA+6
- ?define CH3_COUNT DMA+7
- ?define DMA_STATUS DMA+8
- ?define DMA_CMD DMA+8
- ?define DMA_REQUEST DMA+9
- ?define DMA_MASK DMA+10
- ?define DMA_MODE DMA+11
- ?define DMA_FF DMA+12
- ?define DMA_TMP DMA+13
- ?define DMA_CLEAR DMA+13
- ?define DMA_CLRMSK DMA+14
- ?define DMA_WRMSK DMA+15
- ?define DMAPAGE 0x80
- */
-
- /* Types of Sound Blaster Cards */
- ?define SB15 1
- ?define SBPro 2
- ?define SB20 3
-
- /* DSP Commands */
- ?define DIRECT_8_BIT_DAC 0x10
- ?define DMA_8_BIT_DAC 0x14
- ?define DMA_2_BIT_DAC 0x16
- ?define DMA_2_BIT_REF_DAC 0x17
- ?define DIRECT_ADC 0x20
- ?define DMA_ADC 0x24
- ?define MIDI_READ_POLL 0x30
- ?define MIDI_READ_IRQ 0x31
- ?define MIDI_WRITE_POLL 0x38
- ?define TIME_CONSTANT 0x40
- ?define DMA_8_BIT_DAC_HI_INIT 0x48 // for high-speed SB Pro transfers
- ?define DMA_4_BIT_DAC 0x74
- ?define DMA_4_BIT_REF_DAC 0x75
- ?define DMA_26_BIT_DAC 0x76
- ?define DMA_26_BIT_REF_DAC 0x77
- ?define DMA_8_BIT_DAC_HI_START 0x91 // for high-speed SB Pro transfers
- ?define DMA_8_BIT_ADC_HI_START 0x99 // for high-speed SB Pro transfers
- ?define HALT_DMA 0xD0
- ?define CONTINUE_DMA 0xD4
- ?define SPEAKER_ON 0xD1
- ?define SPEAKER_OFF 0xD3
- ?define DSP_ID 0xE0
- ?define DSP_VER 0xE1
- ?define DSP_COPYRIGHT 0xE3
- ?define INT_REQUEST 0xF2
- ?define MDAC1 0x61
- ?define MDAC2 0x62
- ?define MDAC3 0x63
- ?define MDAC4 0x64
- ?define MDAC5 0x65
- ?define MDAC6 0x66
- ?define MDAC7 0x67
-
- /* Defines for the mixer */
- ?define MIXER_RESET 0x00
- ?define MASTER_VOL 0x22
- ?define VOC_VOL 0x04
- ?define LINE_VOL 0x2e
- ?define FM_VOL 0x26
- ?define CD_VOL 0x28
- ?define RECORD_SRC 0x0C
- ?define MIC 0x11
- ?define LINE 0x17
- ?define CD 0x13
-
- /*
- These four need to be set to the proper values by SB_GET_PARAMS()
- and SB_INIT or by SB_DETECT() before making calls to any other
- routines!
- */
- word SbIOaddr; // == 0x220
- word SbIRQ; // == 7
- word SbDMAchan; // == 1
- word SbType; // == 1
-
- /*
- Write data to the DSP
-
- On entry: byte to be written in AL
- */
- void WRITEDSP()
- {
- $ MOV AH,AL // save a copy of AL for later
- DX = SbIOaddr + DSP_WRITE_STATUS;
- WAITLOOP:
- $ IN AL,DX
- $ OR AL,AL
- $ JS WAITLOOP
- // DX = SbIOaddr + DSP_WRITE_DATA; // not necessary (same port)
- $ MOV AL,AH
- $ OUT DX,AL
- }
-
- /*
- Read data from the DSP, with a timeout
- Usage: READDSP(,,count)
- On exit: byte read in AL
- */
- byte READDSP()
- {
- DX = SbIOaddr + DSP_DATA_AVAIL;
- loop(CX)
- {
- $ IN AL,DX
- $ OR AL,AL
- $ JS READY
- }
- READY:
- $ SUB DL,4 // DX = SbIOaddr + DSP_READ_DATA;
- $ IN AL,DX
- }
-
- /*
- Write a byte to the SB Pro mixer chip
-
- Usage: WRITEMIXER(x,y);
-
- x specifies to which line the value y should be written
- */
- void WRITEMIXER()
- {
- DX = SbIOaddr+MIXER_ADDRESS;
- $ OUT DX,AL // output x
- $ INC DX // DX = SbIOaddr+MIXER_DATA == SbIOaddr+MIXER_ADDRESS+1
- AL = BL; // output y
- $ OUT DX,AL
- }
-
- /*
- Read a byte from the SB Pro mixer chip.
- The value is returned in AL.
-
- Usage: READMIXER(byte x);
-
- x specifies from which line the value should be read
- */
- byte READMIXER()
- {
- DX = SbIOaddr+MIXER_ADDRESS;
- $ OUT DX,AL // output x
- $ INC DX // DX = SbIOaddr+MIXER_DATA;
- $ IN AL,DX
- }
-
- /*
- Reset routine for Sound Blaster.
- Returns non-zero value on error.
- */
- int SB_INIT()
- {
- AL = 1;
- DX = SbIOaddr + DSP_RESET;
- $ OUT DX,AL
- $ IN AL,DX
- $ IN AL,DX
- $ IN AL,DX
- $ IN AL,DX
- $ XOR AL,AL
- $ OUT DX,AL
- DX += 4;
- CX = 100;
- loop(CX)
- {
- $ IN AL,DX
- $ CMP AL,0xAA
- $ JE DONE
- }
- AX = -1;
- $ RET // return();
- DONE:
- $ XOR AX,AX
- }
-
- /*
- Sets the sample rate to be used for digitising or playback.
-
- Usage: SB_SAMPLE_RATE(,word rate);
- */
- void SB_SAMPLE_RATE()
- {
- AX = 0x4240;
- DX = 0x000F; // DX:AX == 0xF4240 == 1,000,000
- $ DIV BX
- BX = 256;
- $ SUB BX,AX // tc = (unsigned char) (256 - (1,000,000/rate));
-
- WRITEDSP(TIME_CONSTANT); /* Command byte for sample rate */
- WRITEDSP(BL); /* Sample rate time constant */
- }
-
- /*
- Turns the speaker on or off.
-
- Usage: SB_VOICE(state);
- */
- void SB_VOICE()
- {
- IF (AX == FALSE)
- WRITEDSP(SPEAKER_OFF);
- ELSE
- WRITEDSP(SPEAKER_ON);
- }
-
- /* Gets the DSP version number from the sound card.
- Returns:
- AH = high byte
- AL = low byte
- */
- word GET_DSP_VER()
- {
- WRITEDSP(DSP_VER);
- WAIT(3);
- REGET:
- READDSP(,,100); // get the high byte
- IF (AL == 0xAA)
- $ JMP REGET
- $ MOV AH,AL
- READDSP(,,100); // get the low byte
- return(AX);
- }
-
-
-
- /*
- Parses the BLASTER enviroment variable to get SB settings.
-
- Returns 1 on error and 0 on success.
- */
- int SB_GET_PARAMS()
- {
- /* Set arguments to reasonable values (Sound Blaster defaults) */
- SbIOaddr = 0x220;
- SbIRQ = 7;
- SbDMAchan = 1;
-
- /* Attempt to read environment variable */
- ENVSTR("BLASTER");
- SI = DI;
-
- /* Is the environment variable set? */
- IF(ESBYTE[SI] == 0)
- return(1);
-
- /* Now parse the BLASTER variable */
- do {
- NEXT_CHAR: // loop to bypass "white-space"
- AL = ESBYTE[SI];
- IF (AL == ' ')
- SI++;
- ELSE IF (AL == '\t')
- SI++;
- ELSE
- $ JMP CONTINUE
- $ JMP NEXT_CHAR
- CONTINUE:
- IF (AL >= 'a')
- IF (AL <= 'z')
- AL -= 'a' + 'A'; // capitalize character in AL
- IF (AL == 'A') /* I/O address */
- {
- SI++;
- DIGITSTOHEXWORD();
- SbIOaddr = AX;
- }
- ELSE IF (AL == 'I') /* Hardware IRQ */
- {
- SI++;
- DIGITSTOWORD();
- SbIRQ = AX;
- }
- ELSE IF (AL == 'D') /* DMA channel */
- {
- SI++;
- DIGITSTOWORD();
- SbDMAchan = AX;
- }
- ELSE IF (AL == 'T') /* Sound Blaster type */
- {
- SI++;
- DIGITSTOWORD();
- SbType = AX;
- }
- ELSE
- {
- WRITESTR("Unknown BLASTER option ");
- WRITE(AL);
- WRITELN();
- }
- } while (ESBYTE[SI] != 0); // are we at the end of the string?
- return(0);
- }
-
-
-
- /*
- The following are procedures required by SB_GET_PARAMS.
- */
-
- /*
- On entry: ES:SI = segment:offset of string
- On return: word in AX
- */
- word DIGITSTOWORD()
- {
- $ XOR AX,AX;
- CX = 10;
- $ XOR BH,BH
- NEXT_CHAR:
- BL = ESBYTE[SI];
- IF (BL < '0')
- $ JMP DONE
- IF (BL > '9')
- $ JMP DONE
- $ MUL CX
- BL -= '0';
- AX += BX;
- SI++;
- $ JMP NEXT_CHAR
- DONE:
- }
-
- /*
- On entry: ES:SI = segment:offset of string
- On return: word in AX
- */
- word DIGITSTOHEXWORD()
- {
- $ XOR AX,AX;
- $ XOR BH,BH
- NEXT_CHAR:
- BL = ESBYTE[SI];
- IF (BL < '0')
- $ JMP DONE
- IF (BL > '9')
- $ JMP DONE
- $ SHL AX,4 // == AX *= 16;
- BL -= '0';
- AX += BX;
- SI++;
- $ JMP NEXT_CHAR
- DONE:
- }
-