home *** CD-ROM | disk | FTP | other *** search
- IDEAL
-
- INCLUDE "PROLOGUE.MAC"
-
- SEGMENT _TEXT PARA PUBLIC 'CODE'
- ASSUME CS:_TEXT,DS:_TEXT,ES:_TEXT
-
- SMALL_MODEL EQU 0
-
- MACRO PPROC NAME ; MACRO TO ESTABLISH A PASCAL CALLABLE PROC
- PUBLIC &NAME
-
- PROC &NAME FAR
-
- ENDM
-
- _IO_ADDX DW 0H ; DEFAULT I/O ADDRESS.
- _INTR_NUM DB 0 ; DEFAULT IS INTERUPT #7
-
- ORG_INT_ADDX DD ? ; ORIGINAL IRQ ADDRESS.
- INT2 DD ? ; HOLDS ADDRESS OF ORIGINAL INTERRUPT VECTORS.
- INT3 DD ? ; WHICH WE STEAL TO PERFORM AUTODECTION.
- INT5 DD ?
- INT7 DD ?
- INT10 DD ?
-
- WAIT_TIME EQU 0200H
- DMA_VOICE_IN EQU 45H
- DMA_VOICE_OUT EQU 49H
-
- DSP_ID_CMD EQU 0E0H
- DSP_VER_CMD EQU 0E1H
- DSP_VI8_CMD EQU 24H
- DSP_VO8_CMD EQU 14H
- DSP_VO2_CMD EQU 17H
- DSP_VO4_CMD EQU 75H
- DSP_VO25_CMD EQU 77H
- DSP_MDAC1_CMD EQU 61H
- DSP_MDAC2_CMD EQU 62H
- DSP_MDAC3_CMD EQU 63H
- DSP_MDAC4_CMD EQU 64H
- DSP_MDAC5_CMD EQU 65H
- DSP_MDAC6_CMD EQU 66H
- DSP_MDAC7_CMD EQU 67H
- DSP_TIME_CMD EQU 40H
- DSP_SILENCE_CMD EQU 80H
- DSP_PAUSE_DMA_CMD EQU 0D0H
- DSP_ONSPK_CMD EQU 0D1H
- DSP_OFFSPK_CMD EQU 0D3H
- DSP_CONT_DMA_CMD EQU 0D4H
- DSP_INTRQ_CMD EQU 0F2H
-
- CMS_TEST_CODE EQU 0C6H
- RESET_TEST_CODE EQU 0AAH
-
- CMS_EXIST EQU 1
- FM_MUSIC_EXIST EQU 2
- CTV_VOICE_EXIST EQU 4
-
- FM_WAIT_TIME EQU 40H
-
- ;; SOUNDBLASTER DETECTION CODE.....................
-
- PORTPOSSIBILITIES DW 220H,210H,230H,240H,250H,260H
-
-
- ;; INITIALIZE THE SOUND BLASTER.
- ;;
- ;; ON ENTRY: NOTHING.
- ;; EXIT: 1 -> SOUNDBLASTESR FOUND.
- ;; 0 -> NO SOUNDBLASTER DETECTED.
- PPROC DETECTBLASTER
- ARG IRQ:DWORD,BASEADR:DWORD
- PENTER 0
- PushCREGS
-
- MOV AX,CS
- MOV DS,AX
- MOV ES,AX
-
- LEA DI,[PORTPOSSIBILITIES]
- MOV CX,6 ; TRY ALL 6 POSSIBILITIES.
- @@LOP: MOV AX,[DI] ; GET PORT POSSIBILITY.
- MOV [_IO_ADDX],AX ; SAVE IN IO_ADDX
- PUSH CX
- PUSH DI
- CALL LDETECTBLASTER ; SEE IF THERE
- POP DI
- POP CX
- JZ @@FOUND
- ADD DI,2 ; TRY NEXT
- LOOP @@LOP ;
- XOR AX,AX ; Pascal Boolean false
- JMP SHORT @@ERR ; EXIT, WITH ERROR CONDITION.
- @@FOUND:
- MOV AX,1 ; FOUND SOUND BLASTER.
- LES DI,[BASEADR]
- MOV AX,[_IO_ADDX]
- STOSW
- LES DI,[IRQ]
- XOR AX,AX
- MOV AL,[_INTR_NUM] ; RETURN INTERRUPT NUMBER FOUND.
- STOSW
- MOV AL,1 ; Pascal boolean true
- @@ERR:
- PopCREGS
- PLEAVE
- RET 8
- ENDP
-
-
- ;; ON ENTRY: _IO_ADDX = TO THE ADDRESS TO SEARCH AT.
- ;; EXIT: ZERO CONDITION -> SOUND BLASTER FOUND, HERE.
- ;; NON-ZERO CONDITION, SOUND BLASTER NOT FOUND.
- PROC LDETECTBLASTER NEAR
- CALL RESET_DSP ; RESET THE DSP
- JNZ @@ID90 ;
- CALL VERIFY_IO_CHK
- JNZ @@ID90
- CALL CHK_DSP_VERSION
- JNZ @@ID90
- CALL VERIFY_INTR
- JNZ @@ID90
- SUB AX,AX
- @@ID90:
- RET
- ENDP
-
- ;; VERIFY THIS IO ADDRESS.
- PROC VERIFY_IO_CHK NEAR
- MOV BX,2
- MOV AL,DSP_ID_CMD
- MOV DX,[_IO_ADDX]
- ADD DX,0CH
- CALL WRITE_DSP_TIME
- JC @@VIO90
-
- MOV AL,0AAH
- CALL WRITE_DSP_TIME
- JC @@VIO90
-
- CALL READ_DSP_TIME
- JC @@VIO90
-
- CMP AL,055H
- JNE @@VIO90
-
- SUB BX,BX
-
- @@VIO90:
- MOV AX,BX
- OR AX,AX
- RET
- ENDP
-
-
- ;; HERE, WE VERIFY THIS INTERRUPT.
- PROC VERIFY_INTR NEAR
- MOV AL,2
- LEA DX,[DUMMY_DMA_INT2]
- LEA BX,[INT2] ; STORAGE FOR OLD ADDRESS.
- CALL SETUP_INTERRUPT
-
- MOV AL,3
- LEA DX,[DUMMY_DMA_INT3]
- LEA BX,[INT3]
- CALL SETUP_INTERRUPT
-
- MOV AL,5
- LEA DX,[DUMMY_DMA_INT5]
- LEA BX,[INT5]
- CALL SETUP_INTERRUPT
-
- MOV AL,7
- LEA DX,[DUMMY_DMA_INT7]
- LEA BX,[INT7]
- CALL SETUP_INTERRUPT
-
- MOV AL,10
- LEA DX,[DUMMY_DMA_INT10]
- LEA BX,[INT10]
- CALL SETUP_INTERRUPT
-
- MOV [_INTR_NUM],0
-
- MOV DX,[_IO_ADDX]
- ADD DX,0CH
- MOV AL,DSP_INTRQ_CMD
- CALL WRITE_DSP
-
- SUB AX,AX
- MOV CX,WAIT_TIME*4
-
- @@VI10:
- CMP [_INTR_NUM],0
- JNZ @@VI90
-
- LOOP @@VI10
-
- MOV AX,3
-
- @@VI90:
- PUSH AX
-
- MOV AL,2
- LEA BX,[INT2]
- CALL RESTORE_INTERRUPT
-
- MOV AL,3
- LEA BX,[INT3]
- CALL RESTORE_INTERRUPT
-
- MOV AL,5
- LEA BX,[INT5]
- CALL RESTORE_INTERRUPT
-
- MOV AL,7
- LEA BX,[INT7]
- CALL RESTORE_INTERRUPT
-
- POP AX
-
- OR AX,AX
- RET
- ENDP
-
-
-
- PROC CHK_DSP_VERSION NEAR
- MOV AL,DSP_VER_CMD
- MOV DX,[_IO_ADDX]
- ADD DL,0CH
- CALL WRITE_DSP
- CALL READ_DSP
- MOV AH,AL
- CALL READ_DSP
- MOV BX,1
- CMP AX,101H
- JB @@CDV90
- SUB BX,BX
- @@CDV90:
- MOV AX,BX
- OR AX,AX
- RET
- ENDP
-
- ;;
-
- ;------------------------------------------------------------------------;
- ; WRITE_DSP WRITES AL TO THE SOUND BLASTER AFTER WAITING FOR LAST COMMAND
- ; TO COMPLETE
- ;------------------------------------------------------------------------;
- PROC WRITE_DSP NEAR
- PUSH CX ; STUFF WITH CX IS NEW TIMEOUT CODE FOR V2.0
- MOV CX,-1
- MOV AH,AL
- @@WD10: DEC CX ; IF TIMEOUT, EXIT LOOP
- JZ @@WD11
-
- IN AL,DX
- OR AL,AL
- JS @@WD10 ; WAIT WHILE HIGH BIT ON, BUSY.
- @@WD11:
- MOV AL,AH ; GET BYTE TO SEND.
- OUT DX,AL ; SEND IT
- POP CX ; RESTORE CALLER'S CX REGISTER.
- RET
- ENDP
-
- PROC WRITE_DSP_TIME NEAR
- PUSH CX ; SAVE CALLER'S CX REGISTER.
-
- MOV CX,WAIT_TIME ; APPLICATION WAIT TIME (DANGEROUS FOR VERY FAST MACHINES?)
- MOV AH,AL ; SAVE CHARACTRER TO SEND IN AH.
-
- @@WDT10:
- IN AL,DX
- OR AL,AL
- JNS @@WDT20
- LOOP @@WDT10
- STC
- JMP SHORT @@WDT90
- @@WDT20:
- MOV AL,AH
- OUT DX,AL ; SEND THE DAMNED THING.
- CLC
- @@WDT90:
- POP CX ; RESTORE CALLER'S CX REGISTER.
- RET
- ENDP
-
-
-
- PROC READ_DSP_TIME NEAR
- PUSH CX
- PUSH DX
-
- MOV DX,[_IO_ADDX]
- ADD DL,0EH
-
- MOV CX,WAIT_TIME
-
- @@RDT10:
- IN AL,DX
- OR AL,AL
- JS @@RDT20
-
- LOOP @@RDT10
- STC
- JMP SHORT @@RDT90
-
- @@RDT20:
- SUB DL,4
- IN AL,DX
- CLC
-
- @@RDT90:
- POP DX
- POP CX
- RET
- ENDP
-
-
- PROC READ_DSP NEAR
- PUSH DX
- MOV DX,[_IO_ADDX]
- ADD DL,0EH
- SUB AL,AL
-
- @@RD10:
- IN AL,DX
- OR AL,AL
- JNS @@RD10
-
- SUB DL,4
- IN AL,DX
-
- POP DX
- RET
- ENDP
-
-
- PROC RESET_DSP NEAR
- MOV DX,[_IO_ADDX]
- ADD DL,6
-
- MOV AL,1 ;JCM (USE THIS INSTEAD)
- OUT DX,AL ;JCM
- ;JCM
- MOV CX,20 ;JCM
- @@WAIT: IN AL,DX ;JCM ;WAIT > 3 US
- LOOP @@WAIT ;JCM
- ;JCM
- MOV AL,0 ;JCM ;DROP RESET
- OUT DX,AL ;JCM
-
- MOV CL,20H
-
- @@RDSP10:
- CALL READ_DSP_TIME
- CMP AL,0AAH
- JE @@RDSP20
- DEC CL
- JNZ @@RDSP10
- MOV AX,2
- JMP SHORT @@RDSP90
- @@RDSP20:
- SUB AX,AX
- @@RDSP90:
- OR AX,AX
- RET
- ENDP
-
-
- PIC0_val db ?
- PIC1_val db ?
- ;-------------------------------------------------
- ; entry: AL = INTERRUPT NUM |
- ; DX = new vector ofs, seg is alway CS |
- ; BX = offset of store buffer :
- ;-------------------------------------------------
- Proc SETUP_INTERRUPT near
- PUSH BX
- PUSH CX
- PUSH DX
-
- CLI
- xor ah,ah ; Zero high byte.
- MOV CL,AL ; preserve interrupt number for use
- cmp al,8
- jb @@calc_vect
- add al,60h ; index slcae PIC vectors if IRQ > 7
- @@calc_vect:
- ADD AL,8 ; calculate interrupt vector addx
- SHL Ax,1
- SHL Ax,1
- MOV DI,AX
-
- PUSH ES ; setup and preserve interrupt
-
- SUB AX,AX
- MOV ES,AX
- MOV AX,[ES:DI]
- MOV [cs:BX],AX ;JCM
- MOV [ES:DI],DX
-
- MOV AX,[ES:DI+2]
- MOV [cs:BX+2],AX ;JCM
- MOV [ES:DI+2],CS
-
- POP ES
-
- mov bx,1
- shl bx,cl
- not bx
- in al,0a1h
- mov [PIC1_val],al
- and al,bh
- out 0a1h,al
- in al,21h
- mov [PIC0_val],al
- and al,bl
- out 21h,al
-
- STI
- POP DX
- POP CX
- POP BX
- RET
- endp
-
-
- ;-------------------------------------------------
- ; entry: AL = INTERRUPT NUM |
- ; BX = offset to stored addx |
- ;-------------------------------------------------
- Proc RESTORE_INTERRUPT near
- CLI
-
- MOV CL,AL
-
- push bx ;JCM
- mov bx,1
- shl bx,cl
- in al,0a1h
- or al,bh
- and al,[PIC1_val] ;don't kill any interrupts that were
- out 0a1h,al ;initially active
- in al,21h
- or al,bl
- and al,[PIC0_val]
- out 21h,al
- pop bx ;JCM
-
- mov al,cl ; Get back interrupt number.
- xor ah,ah
-
- cmp al,8
- jb @@calc_vect
- add al,60h ; index slave PIC if IRQ > 7
- @@calc_vect:
- ADD AL,8 ; calculate interrupt vector addx
- SHL Ax,1
- SHL Ax,1
- MOV DI,AX
-
- PUSH ES ; restore interrupt vector
- SUB AX,AX
- MOV ES,AX
- MOV AX,[cs:BX] ;JCM
- MOV [ES:DI],AX
-
- MOV AX,[cs:BX+2] ;JCM
- MOV [ES:DI+2],AX
-
- POP ES
-
-
- STI
- RET
- endp
-
- PROC DUMMY_ISR FAR
- LABEL DUMMY_DMA_INT2 WORD
- PUSH DX
- MOV DL,2
- JMP SHORT @@OUT
- LABEL DUMMY_DMA_INT3 WORD
- PUSH DX
- MOV DL,3
- JMP SHORT @@OUT
- LABEL DUMMY_DMA_INT5 WORD
- PUSH DX
- MOV DL,5
- JMP SHORT @@OUT
- LABEL DUMMY_DMA_INT7 WORD
- PUSH DX
- MOV DL,7
- jmp short @@OUT
- LABEL DUMMY_DMA_INT10 WORD
- push dx
- mov dl,10
- jmp short @@OUT
- @@OUT:
- PUSH AX
- MOV [CS:_INTR_NUM],DL
- MOV DX,[_IO_ADDX]
- ADD DX,0EH
- IN AL,DX
- MOV AL,20H
- OUT 20H,AL ; SEND A NON SPECIFIC EOI
- cmp [cs:_INTR_NUM],7
- jle @@DONE
- out 0a0h,al ; Acknowledge secondary PIC
- @@DONE:
- POP AX
- POP DX
- IRET
- ENDP
-
-
-
- ENDS
- END
-