1. detecting sound blaster card (ad lib)

--=====================_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==_--

new topic     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu