home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / sound / digpak / sbdetect.asm < prev    next >
Encoding:
Assembly Source File  |  1994-02-21  |  11.4 KB  |  525 lines

  1.     IDEAL
  2.  
  3.     INCLUDE "PROLOGUE.MAC"
  4.  
  5. SEGMENT _TEXT   PARA PUBLIC     'CODE'
  6.     ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT
  7.  
  8. SMALL_MODEL     EQU     0
  9.  
  10. MACRO   PPROC   NAME            ; MACRO TO ESTABLISH A PASCAL CALLABLE PROC
  11.     PUBLIC  &NAME
  12.  
  13. PROC    &NAME  FAR
  14.  
  15.     ENDM
  16.  
  17. _IO_ADDX       DW   0H          ; DEFAULT I/O ADDRESS.
  18. _INTR_NUM      DB   0           ; DEFAULT IS INTERUPT #7
  19.  
  20. ORG_INT_ADDX    DD      ?       ; ORIGINAL IRQ ADDRESS.
  21. INT2    DD      ?       ; HOLDS ADDRESS OF ORIGINAL INTERRUPT VECTORS.
  22. INT3    DD      ?       ; WHICH WE STEAL TO PERFORM AUTODECTION.
  23. INT5    DD      ?
  24. INT7    DD      ?
  25. INT10   DD      ?
  26.  
  27. WAIT_TIME        EQU    0200H
  28. DMA_VOICE_IN     EQU    45H
  29. DMA_VOICE_OUT    EQU    49H
  30.  
  31. DSP_ID_CMD              EQU    0E0H
  32. DSP_VER_CMD             EQU    0E1H
  33. DSP_VI8_CMD             EQU    24H
  34. DSP_VO8_CMD             EQU    14H
  35. DSP_VO2_CMD             EQU    17H
  36. DSP_VO4_CMD             EQU    75H
  37. DSP_VO25_CMD            EQU    77H
  38. DSP_MDAC1_CMD           EQU    61H
  39. DSP_MDAC2_CMD           EQU    62H
  40. DSP_MDAC3_CMD           EQU    63H
  41. DSP_MDAC4_CMD           EQU    64H
  42. DSP_MDAC5_CMD           EQU    65H
  43. DSP_MDAC6_CMD           EQU    66H
  44. DSP_MDAC7_CMD           EQU    67H
  45. DSP_TIME_CMD            EQU    40H
  46. DSP_SILENCE_CMD         EQU    80H
  47. DSP_PAUSE_DMA_CMD       EQU    0D0H
  48. DSP_ONSPK_CMD           EQU    0D1H
  49. DSP_OFFSPK_CMD          EQU    0D3H
  50. DSP_CONT_DMA_CMD        EQU    0D4H
  51. DSP_INTRQ_CMD           EQU    0F2H
  52.  
  53. CMS_TEST_CODE            EQU         0C6H
  54. RESET_TEST_CODE          EQU         0AAH
  55.  
  56. CMS_EXIST                EQU         1
  57. FM_MUSIC_EXIST           EQU         2
  58. CTV_VOICE_EXIST          EQU         4
  59.  
  60. FM_WAIT_TIME             EQU         40H
  61.  
  62. ;; SOUNDBLASTER DETECTION CODE.....................
  63.  
  64. PORTPOSSIBILITIES       DW      220H,210H,230H,240H,250H,260H
  65.  
  66.  
  67. ;; INITIALIZE THE SOUND BLASTER.
  68. ;;
  69. ;;      ON ENTRY: NOTHING.
  70. ;;         EXIT:  1 -> SOUNDBLASTESR FOUND.
  71. ;;                0 -> NO SOUNDBLASTER DETECTED.
  72. PPROC   DETECTBLASTER
  73.     ARG     IRQ:DWORD,BASEADR:DWORD
  74.     PENTER  0
  75.     PushCREGS
  76.  
  77.     MOV     AX,CS
  78.     MOV     DS,AX
  79.     MOV     ES,AX
  80.  
  81.     LEA     DI,[PORTPOSSIBILITIES]
  82.     MOV     CX,6            ; TRY ALL 6 POSSIBILITIES.
  83. @@LOP:  MOV     AX,[DI]         ; GET PORT POSSIBILITY.
  84.     MOV     [_IO_ADDX],AX   ; SAVE IN IO_ADDX
  85.     PUSH    CX
  86.     PUSH    DI
  87.     CALL    LDETECTBLASTER         ; SEE IF THERE
  88.     POP     DI
  89.     POP     CX
  90.     JZ      @@FOUND
  91.     ADD     DI,2            ; TRY NEXT
  92.     LOOP    @@LOP           ;
  93.     XOR     AX,AX           ; Pascal Boolean false
  94.     JMP   SHORT @@ERR       ; EXIT, WITH ERROR CONDITION.
  95. @@FOUND:
  96.     MOV     AX,1            ; FOUND SOUND BLASTER.
  97.     LES     DI,[BASEADR]
  98.     MOV     AX,[_IO_ADDX]
  99.     STOSW
  100.     LES     DI,[IRQ]
  101.     XOR     AX,AX   
  102.     MOV     AL,[_INTR_NUM]  ; RETURN INTERRUPT NUMBER FOUND.
  103.     STOSW
  104.     MOV AL,1 ; Pascal boolean true
  105. @@ERR:
  106.     PopCREGS
  107.     PLEAVE
  108.     RET 8
  109.     ENDP
  110.  
  111.  
  112. ;; ON ENTRY: _IO_ADDX = TO THE ADDRESS TO SEARCH AT.
  113. ;;    EXIT: ZERO CONDITION -> SOUND BLASTER FOUND, HERE.
  114. ;;          NON-ZERO CONDITION, SOUND BLASTER NOT FOUND.
  115. PROC    LDETECTBLASTER  NEAR
  116.     CALL   RESET_DSP                ; RESET THE DSP
  117.     JNZ    @@ID90                   ;
  118.     CALL   VERIFY_IO_CHK
  119.     JNZ    @@ID90
  120.     CALL   CHK_DSP_VERSION
  121.     JNZ    @@ID90
  122.     CALL   VERIFY_INTR
  123.     JNZ    @@ID90
  124.     SUB    AX,AX
  125. @@ID90:
  126.     RET
  127.     ENDP
  128.  
  129. ;; VERIFY THIS IO ADDRESS.
  130. PROC    VERIFY_IO_CHK   NEAR
  131.        MOV    BX,2
  132.        MOV    AL,DSP_ID_CMD
  133.        MOV    DX,[_IO_ADDX]
  134.        ADD    DX,0CH
  135.        CALL   WRITE_DSP_TIME
  136.        JC     @@VIO90
  137.  
  138.        MOV    AL,0AAH
  139.        CALL   WRITE_DSP_TIME
  140.        JC     @@VIO90
  141.  
  142.        CALL   READ_DSP_TIME
  143.        JC     @@VIO90
  144.  
  145.        CMP    AL,055H
  146.        JNE    @@VIO90
  147.  
  148.        SUB    BX,BX
  149.  
  150. @@VIO90:
  151.        MOV    AX,BX
  152.        OR     AX,AX
  153.        RET 
  154.        ENDP
  155.  
  156.  
  157. ;; HERE, WE VERIFY THIS INTERRUPT.
  158. PROC    VERIFY_INTR     NEAR
  159.        MOV      AL,2
  160.        LEA      DX,[DUMMY_DMA_INT2]
  161.        LEA      BX,[INT2]               ; STORAGE FOR OLD ADDRESS.
  162.        CALL     SETUP_INTERRUPT
  163.  
  164.        MOV      AL,3
  165.        LEA      DX,[DUMMY_DMA_INT3]
  166.        LEA      BX,[INT3]
  167.        CALL     SETUP_INTERRUPT
  168.  
  169.     MOV      AL,5
  170.     LEA      DX,[DUMMY_DMA_INT5]
  171.     LEA      BX,[INT5]
  172.     CALL     SETUP_INTERRUPT
  173.  
  174.     MOV      AL,7
  175.     LEA      DX,[DUMMY_DMA_INT7]
  176.     LEA      BX,[INT7]
  177.     CALL     SETUP_INTERRUPT
  178.  
  179.     MOV      AL,10
  180.     LEA      DX,[DUMMY_DMA_INT10]
  181.     LEA      BX,[INT10]
  182.     CALL     SETUP_INTERRUPT
  183.  
  184.     MOV      [_INTR_NUM],0
  185.  
  186.     MOV      DX,[_IO_ADDX]
  187.     ADD      DX,0CH
  188.     MOV      AL,DSP_INTRQ_CMD
  189.     CALL     WRITE_DSP
  190.  
  191.     SUB      AX,AX
  192.     MOV      CX,WAIT_TIME*4
  193.  
  194. @@VI10:
  195.     CMP      [_INTR_NUM],0
  196.     JNZ      @@VI90
  197.  
  198.     LOOP     @@VI10
  199.  
  200.     MOV      AX,3
  201.  
  202. @@VI90:
  203.     PUSH    AX
  204.  
  205.     MOV     AL,2
  206.     LEA     BX,[INT2]
  207.     CALL    RESTORE_INTERRUPT
  208.  
  209.     MOV     AL,3
  210.     LEA     BX,[INT3]
  211.     CALL    RESTORE_INTERRUPT
  212.  
  213.     MOV     AL,5
  214.     LEA     BX,[INT5]
  215.     CALL    RESTORE_INTERRUPT
  216.  
  217.     MOV     AL,7
  218.     LEA     BX,[INT7]
  219.     CALL    RESTORE_INTERRUPT
  220.  
  221.     POP    AX
  222.  
  223.     OR      AX,AX
  224.     RET
  225.     ENDP
  226.  
  227.  
  228.  
  229. PROC    CHK_DSP_VERSION         NEAR
  230.        MOV    AL,DSP_VER_CMD
  231.        MOV    DX,[_IO_ADDX]
  232.        ADD    DL,0CH
  233.        CALL   WRITE_DSP
  234.        CALL   READ_DSP
  235.        MOV    AH,AL
  236.        CALL   READ_DSP
  237.        MOV    BX,1
  238.        CMP    AX,101H
  239.        JB     @@CDV90
  240.        SUB    BX,BX
  241. @@CDV90:
  242.        MOV    AX,BX
  243.        OR     AX,AX
  244.        RET
  245.        ENDP
  246.  
  247. ;;
  248.  
  249. ;------------------------------------------------------------------------;
  250. ; WRITE_DSP WRITES AL TO THE SOUND BLASTER AFTER WAITING FOR LAST COMMAND
  251. ; TO COMPLETE
  252. ;------------------------------------------------------------------------;
  253. PROC    WRITE_DSP       NEAR
  254.     PUSH    CX              ; STUFF WITH CX IS NEW TIMEOUT CODE FOR V2.0
  255.     MOV     CX,-1
  256.     MOV     AH,AL
  257. @@WD10: DEC     CX              ; IF TIMEOUT, EXIT LOOP
  258.     JZ      @@WD11
  259.  
  260.     IN      AL,DX
  261.     OR      AL,AL
  262.     JS      @@WD10          ; WAIT WHILE HIGH BIT ON, BUSY.
  263. @@WD11:
  264.     MOV     AL,AH           ; GET BYTE TO SEND.
  265.     OUT     DX,AL           ; SEND IT
  266.     POP     CX              ; RESTORE CALLER'S CX REGISTER.
  267.     RET
  268.     ENDP
  269.  
  270. PROC    WRITE_DSP_TIME  NEAR
  271.     PUSH    CX              ; SAVE CALLER'S CX REGISTER.
  272.  
  273.     MOV     CX,WAIT_TIME    ; APPLICATION WAIT TIME (DANGEROUS FOR VERY FAST MACHINES?)
  274.     MOV     AH,AL           ; SAVE CHARACTRER TO SEND IN AH.
  275.  
  276. @@WDT10:
  277.     IN      AL,DX
  278.     OR      AL,AL
  279.     JNS     @@WDT20
  280.     LOOP    @@WDT10
  281.     STC
  282.     JMP SHORT @@WDT90
  283. @@WDT20:
  284.     MOV     AL,AH
  285.     OUT     DX,AL           ; SEND THE DAMNED THING.
  286.     CLC
  287. @@WDT90:
  288.     POP     CX              ; RESTORE CALLER'S CX REGISTER.
  289.     RET
  290.     ENDP
  291.  
  292.  
  293.  
  294. PROC    READ_DSP_TIME   NEAR
  295.        PUSH   CX
  296.        PUSH   DX
  297.  
  298.        MOV    DX,[_IO_ADDX]
  299.        ADD    DL,0EH
  300.  
  301.        MOV    CX,WAIT_TIME
  302.  
  303. @@RDT10:
  304.        IN     AL,DX
  305.        OR     AL,AL
  306.        JS     @@RDT20
  307.  
  308.        LOOP   @@RDT10
  309.        STC
  310.        JMP    SHORT @@RDT90
  311.  
  312. @@RDT20:
  313.        SUB    DL,4
  314.        IN     AL,DX
  315.        CLC
  316.  
  317. @@RDT90:
  318.        POP    DX
  319.        POP    CX
  320.        RET
  321.     ENDP
  322.  
  323.  
  324. PROC    READ_DSP        NEAR
  325.        PUSH   DX
  326.        MOV    DX,[_IO_ADDX]
  327.        ADD    DL,0EH
  328.        SUB    AL,AL
  329.  
  330. @@RD10:
  331.        IN     AL,DX
  332.        OR     AL,AL
  333.        JNS    @@RD10
  334.  
  335.        SUB    DL,4
  336.        IN     AL,DX
  337.  
  338.        POP    DX
  339.        RET
  340.     ENDP
  341.  
  342.  
  343. PROC    RESET_DSP       NEAR
  344.     MOV     DX,[_IO_ADDX]
  345.     ADD     DL,6
  346.  
  347.     MOV     AL,1                ;JCM (USE THIS INSTEAD)
  348.     OUT     DX,AL               ;JCM
  349.                     ;JCM
  350.     MOV     CX,20               ;JCM
  351. @@WAIT: IN      AL,DX                ;JCM  ;WAIT > 3 US
  352.     LOOP    @@WAIT             ;JCM
  353.                     ;JCM
  354.     MOV     AL,0                ;JCM  ;DROP RESET
  355.     OUT     DX,AL               ;JCM
  356.  
  357.     MOV     CL,20H
  358.  
  359. @@RDSP10:
  360.        CALL   READ_DSP_TIME
  361.        CMP    AL,0AAH
  362.        JE     @@RDSP20
  363.        DEC    CL
  364.        JNZ    @@RDSP10
  365.        MOV    AX,2
  366.        JMP    SHORT @@RDSP90
  367. @@RDSP20:
  368.        SUB    AX,AX
  369. @@RDSP90:
  370.        OR     AX,AX
  371.        RET
  372.        ENDP
  373.  
  374.  
  375. PIC0_val        db      ?
  376. PIC1_val        db      ?
  377. ;-------------------------------------------------
  378. ; entry: AL = INTERRUPT NUM                      |
  379. ;        DX = new vector ofs, seg is alway CS    |
  380. ;        BX = offset of store buffer             :
  381. ;-------------------------------------------------
  382. Proc    SETUP_INTERRUPT near
  383.        PUSH   BX
  384.        PUSH   CX
  385.        PUSH   DX
  386.  
  387.        CLI
  388.     xor     ah,ah           ; Zero high byte.
  389.        MOV    CL,AL                    ; preserve interrupt number for use
  390.        cmp     al,8
  391.        jb      @@calc_vect
  392.     add     al,60h         ; index slcae PIC vectors if IRQ > 7
  393. @@calc_vect:
  394.        ADD    AL,8                     ; calculate interrupt vector addx
  395.        SHL    Ax,1
  396.        SHL    Ax,1
  397.        MOV    DI,AX
  398.  
  399.        PUSH   ES                       ; setup and preserve interrupt
  400.  
  401.        SUB    AX,AX
  402.        MOV    ES,AX
  403.        MOV    AX,[ES:DI]
  404.        MOV    [cs:BX],AX               ;JCM
  405.        MOV    [ES:DI],DX
  406.  
  407.        MOV    AX,[ES:DI+2]
  408.        MOV    [cs:BX+2],AX             ;JCM
  409.        MOV    [ES:DI+2],CS
  410.  
  411.        POP    ES
  412.  
  413.     mov     bx,1
  414.     shl     bx,cl
  415.     not     bx
  416.     in      al,0a1h
  417.     mov     [PIC1_val],al
  418.     and     al,bh
  419.     out     0a1h,al
  420.     in      al,21h
  421.     mov     [PIC0_val],al
  422.     and     al,bl
  423.     out     21h,al
  424.  
  425.        STI
  426.        POP    DX
  427.        POP    CX
  428.        POP    BX
  429.        RET
  430.        endp
  431.  
  432.  
  433. ;-------------------------------------------------
  434. ; entry: AL = INTERRUPT NUM                      |
  435. ;        BX = offset to stored addx              |
  436. ;-------------------------------------------------
  437. Proc    RESTORE_INTERRUPT       near
  438.        CLI
  439.  
  440.        MOV    CL,AL
  441.  
  442.     push    bx                 ;JCM
  443.     mov     bx,1
  444.     shl     bx,cl
  445.     in      al,0a1h
  446.     or      al,bh
  447.     and     al,[PIC1_val]         ;don't kill any interrupts that were
  448.     out     0a1h,al             ;initially active
  449.     in      al,21h
  450.     or      al,bl
  451.     and     al,[PIC0_val]
  452.     out     21h,al
  453.     pop     bx                  ;JCM
  454.  
  455.     mov     al,cl           ; Get back interrupt number.
  456.     xor     ah,ah
  457.  
  458.        cmp      al,8
  459.        jb       @@calc_vect
  460.        add      al,60h          ; index slave PIC if IRQ > 7
  461. @@calc_vect:
  462.        ADD    AL,8                      ; calculate interrupt vector addx
  463.        SHL    Ax,1
  464.        SHL    Ax,1
  465.        MOV    DI,AX
  466.  
  467.        PUSH   ES                       ; restore interrupt vector
  468.        SUB    AX,AX
  469.        MOV    ES,AX
  470.        MOV    AX,[cs:BX]               ;JCM
  471.        MOV    [ES:DI],AX
  472.  
  473.        MOV    AX,[cs:BX+2]             ;JCM
  474.        MOV    [ES:DI+2],AX
  475.  
  476.        POP    ES
  477.  
  478.  
  479.        STI
  480.        RET
  481.        endp
  482.  
  483. PROC    DUMMY_ISR       FAR
  484. LABEL   DUMMY_DMA_INT2  WORD
  485.        PUSH   DX
  486.        MOV    DL,2
  487.        JMP    SHORT @@OUT
  488. LABEL   DUMMY_DMA_INT3  WORD
  489.        PUSH   DX
  490.        MOV    DL,3
  491.        JMP    SHORT @@OUT
  492. LABEL   DUMMY_DMA_INT5  WORD
  493.        PUSH   DX
  494.        MOV    DL,5
  495.        JMP    SHORT @@OUT
  496. LABEL   DUMMY_DMA_INT7  WORD
  497.        PUSH   DX
  498.        MOV    DL,7
  499.        jmp      short @@OUT
  500. LABEL   DUMMY_DMA_INT10 WORD
  501.     push    dx
  502.     mov     dl,10
  503.     jmp short @@OUT
  504. @@OUT:
  505.        PUSH   AX
  506.        MOV    [CS:_INTR_NUM],DL
  507.        MOV    DX,[_IO_ADDX]
  508.        ADD    DX,0EH
  509.        IN     AL,DX
  510.        MOV    AL,20H
  511.        OUT    20H,AL            ; SEND A NON SPECIFIC EOI
  512.        cmp      [cs:_INTR_NUM],7
  513.        jle      @@DONE
  514.        out      0a0h,al         ; Acknowledge secondary PIC
  515. @@DONE:
  516.        POP    AX
  517.        POP    DX
  518.        IRET
  519.        ENDP
  520.  
  521.  
  522.  
  523.     ENDS
  524.     END
  525.