1. detecting sound blaster card (ad lib)
- Posted by Jacques Deschenes <desja at QUEBECTEL.COM> Apr 30, 1997
- 1018 views
- Last edited May 01, 1997
--=====================_862464744==_ Here is an add up to Greg Harris detect.ex code. It now detect dma channels and IRQ of ad lib or sound blaster card. The DetectDma16() As not been tested because my card is 8 bits, but everything else work fine on my computer. attached file. --=====================_862464744==_ ------------------------ Information from the mail header ----------------------- ---Code Below----- --Checks for Sound Card --Detects the presence of an Adlib Compatable Sound Card --You need ports.e for this to work include ports.e include dma.e constant DATA_READY = #AA constant GET_DSP_VERSION = #E1 integer BaseIo, Dma8, Dma16, DspIrq integer DSP_RESET, -- dsp reset i/o port DSP_READ_DATA, -- dsp read data i/o port DSP_WRITE_DATA , -- dsp write data i/o port DSP_WRITE_STATUS, -- dsp write status i/o port DSP_DATA_AVAIL -- dsp read status i/o port -------------Write Sound Card Register---------------- procedure WriteSndReg(integer reg, integer val) --Write to a sound card register integer temp Output(reg, #388) for tmp = 1 to 6 do --wait 6 miliseconds temp = Input(#388) end for Output(val, #389) for tmp = 1 to 35 do --wait 35 miliseconds temp = Input(#388) end for end procedure ----------------Detect Sound Card-------------------- function Detect_Sound_Card() --Detects a Adlib Compatible Card --Return 1 if true 0 if not found integer a, b, c, success success = 0 --This was missing WriteSndReg(#4, #60) WriteSndReg(#4, #80) b=Input(#388) WriteSndReg(#2, #FF) WriteSndReg(#4, #21) for tmp = 1 to 130 do a = Input(#388) end for c = Input(#388) WriteSndReg(#4, #60) WriteSndReg(#4, #80) if and_bits(b,#E0) = 0 then if and_bits(c,#E0) = #C0 then success = 1 for tmp = 1 to #F5 do --reset Sound Card WriteSndReg(tmp, 0) end for end if end if return success end function function Get_Base_Address() integer baseport, resetport, readport, data data = 0 baseport = #210 resetport = #216 readport = #21A while (data != DATA_READY) and (baseport<#270) do Output(1, resetport) for x = 1 to 3 do end for Output(0, resetport) data = 0 for x = 0 to 99 do data = Input(readport) end for if data = DATA_READY then exit else baseport = baseport + #10 resetport = resetport + #10 readport = readport + #10 end if end while if baseport = #270 then return 0 else return baseport end if end function function DetectCard() integer temp if Detect_Sound_Card() then temp = Get_Base_Address() BaseIo = temp -- Calculate the port addresses DSP_RESET = BaseIo + #6 DSP_READ_DATA = BaseIo + #A DSP_WRITE_DATA = BaseIo + #C DSP_WRITE_STATUS = BaseIo + #C DSP_DATA_AVAIL = BaseIo + #E return BaseIo else return 0 end if end function -- following code added by Jacques Deschenes constant TIME_OUT = 0.5 procedure ResetDSP() -- ResetDSP returns TRUE if reset was successful atom start, TimeOut Output(1,DSP_RESET) --delay(.001) -- problably not needed. DSP chip ask for a 3 micro second delay Output(0,DSP_RESET) start = time() TimeOut = 0 while not TimeOut and floor(Input(DSP_DATA_AVAIL)/#80)=0 do TimeOut = time()-start >= TIME_OUT end while if not Input(DSP_READ_DATA) = DATA_READY then puts(1,"unable to reset DSP.\n") end if end procedure --ResetDSP() global procedure WriteDSP(byte value) -- write a byte to dsp write register atom start integer TimeOut start = time() TimeOut = 0 while not TimeOut and floor(Input(DSP_WRITE_STATUS)/#80) = 1 do TimeOut = time() - start > TIME_OUT end while Output(value,DSP_WRITE_DATA) end procedure --WriteDSP() global function ReadDSP() -- read a byte from dsp read register atom start integer TimeOut TimeOut = 0 start = time() while not TimeOut and floor(Input(DSP_DATA_AVAIL)/#80) = 0 do TimeOut = time() - start > TIME_OUT end while if TimeOut then return -1 end if return Input(DSP_READ_DATA) end function -- ReadDSP() global function GetDSPVersion() -- return the Digital sound processor version number. integer major, minor WriteDSP(GET_DSP_VERSION) major = ReadDSP() minor = ReadDSP() return major+ minor/100 end function -- GetDSPVersion constant DMA_8_CHANNELS = {0,1,3} constant DMA_16_CHANNELS = {5,6,7} function DetectDma8() atom DmaBuff, DmaCount, start DmaBuff = AllocateDMABuffer(32) mem_set(DmaBuff,128,32) WriteDSP(#40) WriteDSP(211) for i = 1 to length(DMA_8_CHANNELS) do SetDma(DmaBuff,32,DMA_8_CHANNELS[i],DMA_OUT+DMA_SINGLE) WriteDSP(#14) WriteDSP(remainder(32-1,256)) WriteDSP(floor((32-1)/256)) start = time() while time() - start < .05 do end while DmaCount = ReadCurrentCount(DMA_8_CHANNELS[i]) if DmaCount = 65535 then free_low(DmaBuff) Dma8 = DMA_8_CHANNELS[i] return Dma8 else ResetDSP() ResetDma(DMA_8_CHANNELS[i]) end if end for free_low(DmaBuff) return -1 end function function DetectDma16() atom DmaBuff, DmaCount, start DmaBuff = AllocateDMABuffer(32) mem_set(DmaBuff,128,32) WriteDSP(#41) -- set sampling rate WriteDSP(floor(22050/256)) WriteDSP(remainder(22050,256)) for i = 1 to length(DMA_16_CHANNELS) do SetDma(DmaBuff,32,DMA_16_CHANNELS[i],DMA_OUT+DMA_SINGLE) WriteDSP(#B0) -- set 16 bits output WriteDSP(#10) -- set 16 bits mono signed mode WriteDSP(remainder(32-1,256)) WriteDSP(floor((32-1)/256)) start = time() while time() - start < .05 do end while DmaCount = ReadCurrentCount(DMA_16_CHANNELS[i]) if DmaCount = 65535 then free_low(DmaBuff) Dma16 = DMA_16_CHANNELS[i] return Dma16 else ResetDSP() ResetDma(DMA_16_CHANNELS[i]) end if end for free_low(DmaBuff) return -1 end function atom code_segment, segment segment = allocate(4) lock_memory(segment, 4) sequence save_segment_code save_segment_code = { #53, -- push ebx #0E, -- push cs or #1E push ds -- only a 16-bit value #5B, -- pop ebx #89, #1D} & int_to_bytes(segment) & -- mov segment, ebx {#5B, -- pop ebx #C3 -- ret } atom save_segment save_segment = allocate(length(save_segment_code)) poke(save_segment, save_segment_code) call(save_segment) -- save code segment code_segment = bytes_to_int(peek({segment,4})) poke(save_segment+1, #1E) call(save_segment) -- save data segment constant DATA_LEN = 16 atom INT_CODE, DATA_SEG, dBASE_IO, dIRQ_NO, dINT_COUNT DATA_SEG = allocate(DATA_LEN) lock_memory(DATA_SEG,DATA_LEN) dBASE_IO = DATA_SEG + 0 dIRQ_NO = DATA_SEG + 2 dINT_COUNT = DATA_SEG + 3 constant sINT_CODE = { #1E, -- PUSH DS #60, -- PUSHAD #BB}&peek({segment,4})&{ -- MOV EBX, DATA_SEG #53, -- PUSH EBX #1F, -- POP DS #66,#8B,#15}&int_to_bytes(dBASE_IO)&{ -- MOV DX, [BASE_IO] #66,#83,#C2,#0E, -- ADD DX, 0E #EC, -- IN AL, DX #66,#BA,#20,#00, -- MOV DX, 20 #B0,#20, -- MOV AL, 20 #EE, -- OUT DX, AL #80,#3D}&int_to_bytes(dIRQ_NO)&{#07, -- CMP [IRQ_NO], 7 #76,#09,#90,#90,#90,#90, -- JBE @exit #66,#BA,#A0,#00, -- MOV DX, 0A0 #EE, -- OUT DX, AL -- @exit: #FF,#05}&int_to_bytes(dINT_COUNT)&{ -- INC [INT_COUNT] #61, -- POPAD #1F, -- POP DS #CF, -- IRETD 0 } INT_CODE = allocate(length(sINT_CODE)) lock_memory(INT_CODE,length(sINT_CODE)) poke(INT_CODE,sINT_CODE) procedure EnableIRQ(integer IrqNumber) if IrqNumber < 8 then Output(and_bits(Input(#21),not_bits(power(2,IrqNumber))),#21) else Output(and_bits(Input(#A1),not_bits(power(2,IrqNumber-8))),#A1) end if end procedure --EnableIRQ() procedure DisableIRQ(integer IrqNumber) if IrqNumber < 8 then Output(or_bits(Input(#21),power(2,IrqNumber)),#21) else Output(or_bits(Input(#A1),power(2,IrqNumber-8)),#A1) end if end procedure --DisableIRQ() function TstInt(integer IrqNo) sequence OrigVector integer IntNo, Master, Slave atom start poke(dIRQ_NO,IrqNo) if IrqNo < 8 then IntNo = IrqNo + 8 else IntNo = IrqNo - 8 + #70 end if Master = Input(#21) Slave = Input(#A1) Output(#FB,#21) Output(#FF,#A1) OrigVector = get_vector(IntNo) set_vector(IntNo,{code_segment,INT_CODE}) poke(dINT_COUNT,{0,0,0,0}) EnableIRQ(IrqNo) WriteDSP(#F2) start = time() while time() - start < .05 do end while ResetDSP() DisableIRQ(IrqNo) set_vector(IntNo,OrigVector) Output(Master,#21) Output(Slave,#A1) if bytes_to_int(peek({dINT_COUNT,4})) > 0 then return 1 else return 0 end if end function constant SB_INT= {2,5,7,10} function DetectIRQ() DspIrq = -1 poke(dBASE_IO,{remainder(BaseIo,256),floor(BaseIo/256)}) for i = 1 to length(SB_INT) do if TstInt(SB_INT[i]) then DspIrq = SB_INT[i] exit end if end for return DspIrq end function -------------------End of Support Code------------------------ atom version integer temp temp = DetectCard() if temp then puts(1, "Sound Card Detected\n") printf(1, "Base Address is %x\n", temp) printf(1,"8 bits dma channel is %d\n", {DetectDma8()}) version = GetDSPVersion() printf(1,"DSP version is %.2f\n",{version}) if version >= 4.00 then printf(1,"16 bits dma channel is %d\n",{DetectDma16()}) end if printf(1,"IRQ number is %d\n",{DetectIRQ()}) else puts(1, "Sound Card not detected\n") end if --=====================_862464744==_ Jacques Deschenes Baie-Comeau, Quebec Canada desja at quebectel.com --=====================_862464744==_--