home *** CD-ROM | disk | FTP | other *** search
-
- .MODEL MEDIUM
- UGROUP0 GROUP CODE_SEG0
- ASSUME CS:UGROUP0, DS:UGROUP0, SS:UGROUP0
-
- .386
- CODE_SEG0 SEGMENT PAGE USE16
- LOCALS xx
- ;-----------------------------------------------------------------------------
- ; Main Routine and Interface
- ; IN: ES:BX = Zeiger auf Struktur
- ; OUT: AX = SoundcardType ;0=NO,1=SB/SBPRO,2=SB16,3=PAS,4=GUS
- ;
- ; meaning offset size
- ; baseport 0 dw 0
- ; dma_number 2 db 0
- ; irq_number 3 db 0
- ; samplerate 4 dw 0
- ; intern_type 6 db 0
- ; irq_type 7 db 0
- ; start_pos 8 db 0
- ; loop_pos 9 db 0
- ; song_mod 10 db 0
- ; char master_vol 11 db 0
- ; char music_vol 12 db 0
- ; char fx_vol 13 db 0
- ;-----------------------------------------------------------------------------
-
- PUBLIC _MAIN0
- _MAIN0 PROC FAR
- CALL DetectSound
- SETC DL
- XOR DH,DH
- MOV AX,CS:SoundPort
- MOV ES:[BX],AX
- MOV AL,CS:SoundDMA
- MOV ES:[BX+2],AL
- MOV AL,CS:SoundIRQ
- MOV ES:[BX+3],AL
- MOV AX,22222
- MOV ES:[BX+4],AX ;DEFAULT SAMPLERATE = 22222
- XOR AX,AX
- MOV ES:[BX+6],AL ;DEFAULT INTERN TYPE = 0
- MOV ES:[BX+8],AL ;START_POS = 0
- MOV ES:[BX+9],AL ;LOOP_POS = 0 (ENDLESS LOOPING)
- MOV ES:[BX+10],AL ;SONG_MOD = 0
- INC AL
- MOV ES:[BX+7],AL ;IRQ DEFAULT TO WINDOWS (TIMER)
- DEC AL
- DEC AL
- MOV ES:[BX+11],AL ;VOLUMES TO MAX
- MOV ES:[BX+12],AL
- MOV ES:[BX+13],AL
- MOV AL,CS:SoundType
- CMP AL,2
- JB SHORT MEND
- JA SHORT MT1
- DEC AL
- MOV ES:[BX+6],AL
- JMP SHORT MEND
- MT1: CMP AL,3
- JNE SHORT MT2
- INC AL
- JMP SHORT MEND
- MT2: CMP AL,4
- JNE SHORT MT3
- DEC AL
- JMP SHORT MEND
- MT3: CMP AL,5
- JNE SHORT MEND
- MOV AL,2
- MEND: RETF
-
- SoundType db 0 ;0=no,1=SB,2=SBPro,3=GUS,4=PAS16,5=SB16
- SoundPort dw 0
- SoundDMA db 0
- SoundIRQ db 0
-
- _MAIN0 ENDP
-
- ;-----------------------------------------------------------------------------
- ;(Auto)detect Soundkarte: c=0 ok
-
- DetectSound proc near
- pusha
- push ds es cs
- pop es
- mov di,offset xxULTRASND
- call GetEnv
- jnc short xxGUSEnv
- xxSBNoGUS: mov di,offset xxBLASTER
- call GetEnv
- jnc short xxSBEnv
- xor dx,dx
- mov cs:SoundType,3
- call DetGUSHW
- mov cs:SoundPort,dx
- jnc xxEndDetect
- mov cs:SoundType,4
- call detectPAS
- jnc xxEndDetect
- mov cs:SoundType,1
-
- xxSBHW: call detectSBProHW
- jnc xxEndDetect
- call detectSBHW
- jnc xxEndDetect
- jmp xxErrorDetect
-
- xxGUSEnv: mov cs:SoundType,3
- call GetValue
- mov cs:SoundPort,ax
- jc short xxSBNoGUS
- call GetValue
- mov cs:SoundDMA,al
- jc short xxSBNoGUS
- call GetValue
- jc short xxSBNoGUS
- call GetValue
- mov cs:SoundIRQ,al
- jc short xxSBNoGUS
-
- mov dx,cs:SoundPort
- call DetGUSHW
- jc short xxSBNoGUS
- jmp short xxEndDetect
-
- xxSBEnv: mov cs:SoundType,1
- xxNextSB: lodsb
- cmp al,0
- je short xxSBEnd
- and al,11011111b
-
- cmp al,'A'
- jne short xxNoA
- call GetValue
- mov cs:SoundPort,ax
- jnc short xxNextSB
- jmp short xxSBEnd
-
- xxNoA: cmp al,'I'
- jne short xxNoI
- call GetValue
- mov cs:SoundIRQ,al
- jnc short xxNextSB
- jmp short xxSBEnd
-
- xxNoI: cmp al,'D'
- jne short xxNoD
- call GetValue
- mov cs:SoundDMA,al
- jnc short xxNextSB
- jmp short xxSBEnd
-
- xxNoD: cmp al,'T'
- jne short xxNextSB
- call GetValue
- pushf
- cmp al,3
- jb short xxSBOld
- mov cs:SoundType,2
- cmp al,4
- jb short xxSBOld
- mov cs:SoundType,5
- xxSBOld: popf
- jnc short xxNextSB
-
- xxSBEnd: xor ax,ax
- cmp cs:SoundPort,ax
- je xxSBHW
- cmp cs:SoundIRQ,al
- je xxSBHW
- cmp cs:SoundDMA,al
- je xxSBHW
-
- xxEndDetect: xor ax,ax
- cmp cs:SoundPort,ax
- je short xxErrorDetect
- cmp cs:SoundIRQ,al
- je short xxErrorDetect
- cmp cs:SoundDMA,al
- je short xxErrorDetect
- clc
- pop es ds
- popa
- ret
-
- xxErrorDetect: stc
- mov cs:SoundType,0
- jmp short xxEndDetect
-
- xxBLASTER db "BLASTER",0
- xxULTRASND db "ULTRASND",0
-
- DetectSound endp
-
- ;------------------------------------------------------------------------------
- ;Liest Wert (hex) ab ds:si, zurück in ax, c=1 String mit 0 terminiert
-
- GetValue proc near
-
- push bx
-
- xor ax,ax
- xor bx,bx
-
- xxNoStart: lodsb
- cmp al,' '
- je short xxNoStart
- jmp short xxEntry
-
- xxNext: lodsb
- xxEntry: cmp al,' '
- je short xxEnd2
- cmp al,','
- je short xxEnd2
- and al,11011111b
- cmp al,40h
- jb short xxNoChar
- add al,9
- xxNoChar: and al,0fh
- shl bx,4
- add bx,ax
- jmp short xxNext
-
- xxEnd1: stc
- mov ax,bx
- pop bx
- ret
-
- xxEnd2: clc
- mov ax,bx
- pop bx
- ret
-
- GetValue endp
-
- ;------------------------------------------------------------------------------
- ;holt Umgebungsvariable es:di, ds:si zeigt auf erstes Zeichen, c=1 Fehler
-
- GetEnv proc near
-
- push bx
- push di
- push es
-
- mov ah,62h ;ds:si points at dos env.
- int 21h
- mov ds,bx
- mov ds,ds:2ch
- xor si,si
-
- xxLoop3: xor bx,bx
- xxLoop: lodsb
- cmp al,0
- je short xxError
- cmp al,es:[di+bx]
- jne short xxNextOne
- inc bx
- jmp short xxLoop
- xxNextOne: cmp al,'='
- jne short xxLoop2
- cmp es:[di+bx],byte ptr 0
- je short xxGotIt
- xxLoop2: lodsb
- cmp al,0
- jne short xxLoop2
- jmp short xxLoop3
-
- xxError: stc
- jmp short xxEnde
-
- xxGotIt: clc
-
- xxEnde: pop es
- pop di
- pop bx
- ret
- GetEnv endp
-
- ;------------------------------------------------------------------------------
- ;Autodetect/Check GUS
- ;dx = port, dx = 0 -> autodetect, else check port
-
- DetGUSHW proc near
-
- pusha
- push ds
- push es
-
- mov bp,1
- mov si,dx
- xor di,di
- cmp dx,di
- jne short xxnoAutodetect
- mov si,210h
- mov bp,6
- mov di,-1
-
- xxnoAutodetect: mov bx,si
-
- mov cs:xxBasePort,bx
- add bx,6h
- mov cs:xxStatusPort,bx
- add bx,2+1+100h-9h+3
- mov cs:xxCommandPort,bx
- inc bx
- mov cs:xxDataLowPort,bx
- inc bx
- mov cs:xxDataHighPort,bx
- add bx,2
- mov cs:xxDRAMIOPort,bx
-
- mov bx,cs:xxCommandPort
- mov cx,cs:xxDataHighPort
- mov dx,bx
- mov al,4ch ;Initialize
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
- mov dx,cs:xxBasePort
- REPT 8
- in al,dx
- ENDM
-
- mov dx,bx
- mov al,4Ch
- out dx,al
- mov dx,cx
- mov al,1
- out dx,al
- mov dx,cs:xxBasePort
- REPT 8
- in al,dx
- ENDM
-
- mov dx,bx
- mov al,41h ;DMACtrl
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
- mov dx,bx
- mov al,45h
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
- mov dx,bx
- mov al,49h
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
-
- mov dx,bx
- mov al,0eh ;VoicesActive
- out dx,al
- mov dx,cx
- mov al,20 ;NumVoices
- dec al
- or al,0C0h
- out dx,al
-
- mov dx,cs:xxStatusPort
- in al,dx
- mov dx,bx
- mov al,41h ;DMACtrl
- out dx,al
- mov dx,cx
- in al,dx
- mov dx,bx
- mov al,49h
- out dx,al
- mov dx,cx
- in al,dx
- mov dx,bx
- mov al,8Fh
- out dx,al
- mov dx,cx
- in al,dx
-
- mov dx,bx
- mov al,4ch
- out dx,al
- mov dx,cx
- mov al,7
- out dx,al
-
- mov dx,cs:xxCommandPort
- mov al,43h ;DRAMAddrLo
- out dx,al
- mov dx,cs:xxDataLowPort
- mov ax,113h
- out dx,ax
-
- mov dx,cs:xxCommandPort
- mov al,44h ;DRAMAddrHi
- out dx,al
- mov dx,cs:xxDataHighPort
- xor al,al
- out dx,al
-
- mov dx,cs:xxDRAMIOPort
- mov al,0d4h ;testwert 1 d4h
- out dx,al
-
- mov dx,cs:xxCommandPort
- mov al,43h ;DRAMAddrLo
- out dx,al
- mov dx,cs:xxDataLowPort
- mov ax,12h ;testweise mal 12h beschreiben
- out dx,ax
-
- mov dx,cs:xxCommandPort
- mov al,44h ;DRAMAddrHi
- out dx,al
- mov dx,cs:xxDataHighPort
- xor al,al
- out dx,al
-
- mov dx,cs:xxDRAMIOPort
- mov al,53h ;testwert 2 53h
- out dx,al
-
-
- mov dx,cs:xxCommandPort
- mov al,43h ;DRAMAddrLo
- out dx,al
- mov dx,cs:xxDataLowPort
- mov ax,113h ;also testwert 1 lesen
- out dx,ax
-
- mov dx,cs:xxCommandPort
- mov al,44h ;DRAMAddrHi
- out dx,al
- mov dx,cs:xxDataHighPort
- xor al,al
- out dx,al
-
- mov dx,cs:xxDRAMIOPort
- in al,dx ;speicher lesen
- cmp al,0d4h ;testwert Ok ?
- jne short xxnotfound
-
- mov dx,cs:xxCommandPort
- mov al,43h ;DRAMAddrLo
- out dx,al
- mov dx,cs:xxDataLowPort
- mov ax,12h ;testoffset 2
- out dx,ax
-
- mov dx,cs:xxCommandPort
- mov al,44h ;DRAMAddrHi
- out dx,al
- mov dx,cs:xxDataHighPort
- xor al,al
- out dx,al
-
- mov dx,cs:xxDRAMIOPort
- in al,dx
- cmp al,53h ;wert = testwert 2 ?
- jne short xxnotfound ;nö, nicht gefunden
- jmp short xxfoundGUS
- xxnotfound:
- cmp di,0ffffh
- jne short xxno
- add si,10h
- dec bp
- jnz xxnoAutodetect
- xxno:
- pop es
- pop ds
- popa
- xor dx,dx
- stc ;Carry setzen
- ret
-
- xxfoundGUS: pop es
- pop ds
- popa
- mov dx,cs:xxBasePort
- clc
- ret
-
- xxBasePort dw 0
- xxStatusPort dw 0
- xxCommandPort dw 0
- xxDataLowPort dw 0
- xxDataHighPort dw 0
- xxDRAMIOPort dw 0
-
- DetGUSHW endp
-
- ; /***********************************************************************
- ; *
- ; * File : DETSBHW.ASM
- ; *
- ; * Description : Sound Blaster hardware detection routines
- ; *
- ; ************************************************************************
-
- waitSB MACRO
- local l1
- l1:
- in al,dx
- or al,al
- js short l1
- ENDM
-
- waitSBport MACRO
- local l1
-
- mov dx,cs:SoundPort
- add dx,0Ch
- l1:
- in al,dx
- or al,al
- js short l1
- ENDM
-
- waitSBPROport MACRO
- local l1
-
- mov dx,cs:SoundPort
- add dx,0Ch
- l1:
- in al,dx
- or al,al
- js short l1
- ENDM
-
- ;/*************************************************************************
- ; *
- ; * Function : checkPort_SB
- ; *
- ; * Description : Checks if given address is SB's I/O address
- ; *
- ; * Input : DX = port to check
- ; *
- ; * Returns : AX = 0 successful
- ; * AX = 1 unsuccessful
- ; *
- ; ************************************************************************/
-
- checkPort_SB proc near
-
- push dx
- add dl,6 ; Init Sound Blaster
- mov al,1
- out dx,al
- in al,dx ; Wait for awhile
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- mov al,0
- out dx,al
- sub dl,6
-
- add dl,0Eh ; DSP data available status
- mov cx,1000
- xxloop:
- in al,dx ; port 22Eh
- or al,al
- js short xx10
- loop short xxloop
-
- mov ax,1
- jmp short xxexit
- xx10:
- sub dl,4
- in al,dx ; port 22Ah
- cmp al,0AAh ; Is ID 0AAh?
- mov ax,0
- je short xxexit
- mov ax,1
- xxexit:
- pop dx
- or ax,ax ; Set zero-flag accordingly
- ret
-
- checkPort_SB endp
-
- ;/*************************************************************************
- ; *
- ; * Function : findDMAIRQ_SB
- ; *
- ; * Description : Finds SB's DMA interrupt number
- ; *
- ; * Returns : AX = 0 error
- ; * AX = port number (2,3,5,7)
- ; *
- ; ************************************************************************/
-
- findDMAIRQ_SB proc near
-
- push ds
- push es
-
- mov ah,35h
- mov al,8+2
- int 21h
- mov cs:xxsaveVect+2,es
- mov cs:xxsaveVect,bx
- mov al,8+3
- int 21h
- mov cs:xxsaveVect+6,es
- mov cs:xxsaveVect+4,bx
- mov al,8+5
- int 21h
- mov cs:xxsaveVect+10,es
- mov cs:xxsaveVect+8,bx
- mov al,8+7
- int 21h
- mov cs:xxsaveVect+14,es
- mov cs:xxsaveVect+12,bx
-
- mov ah,25h
- mov dx,offset DMA2 ; Set vectors
- mov al,8+2
- int 21h
- mov dx,offset DMA3
- mov al,8+3
- int 21h
- mov dx,offset DMA5
- mov al,8+5
- int 21h
- mov dx,offset DMA7
- mov al,8+7
- int 21h
-
- in al,21h
- mov cs:xxintMask,al ; Save interrupt mask
- mov al,0FFh
- out 21h,al ; Mask out all interrupts
- cli ; Disable interrupts
-
- mov al,cs:xxintMask
- and al,01010011b ; Allow DMA interrupts (2,3,5 & 7)
- out 21h,al
- sti ; Set DMA up
-
- mov al,5
- out 0Ah,al ; Break on
- mov al,0
- out 0Ch,al ; Reset counter
- mov al,49h
- out 0Bh,al ; DMA -> DSP (output)
- mov al,0
- out 83h,al ; page 0
- mov al,0
- out 2,al ; offset 0
- mov al,0
- out 2,al ; whole address is 0000:0000
- mov al,1
- out 3,al ; count = 1
- mov al,0
- out 3,al
- mov al,1
- out 0Ah,al ; Break off
-
- mov dx,cs:SoundPort
- add dx,0Ch
- waitSB
- mov al,40h ; Set DSP speed
- out dx,al
- waitSB
- mov al,0D3h ; 22222 Hz
- out dx,al
- waitSB
- mov al,14h ; 14h = output command
- out dx,al
- waitSB
- mov al,1 ; digitize 1 byte
- out dx,al
- waitSB
- mov al,0
- out dx,al
- mov cx,0FFFFh ; Big loop
- mov cs:SoundIRQ,byte ptr 0 ; Clear interrupt value
- xxloop:
- cmp cs:SoundIRQ,byte ptr 0 ; Wait dmaIRQ to change
- loope short xxloop ; loop if it doesn't
- mov dx,cs:SoundPort
- add dl,0Eh
- in al,dx ; Reset SB
-
- mov al,cs:xxintMask
- out 21h,al ; Restore interrupt mask
- sti ; Allow interrupts
-
- push ds
- mov ah,25h
- lds dx,dword ptr cs:xxsaveVect
- mov al,8+2
- int 21h
- lds dx,dword ptr cs:xxsaveVect+4
- mov al,8+3
- int 21h
- lds dx,dword ptr cs:xxsaveVect+8
- mov al,8+5
- int 21h
- lds dx,dword ptr cs:xxsaveVect+12
- mov al,8+7
- int 21h
- pop ds
-
- pop es
- pop ds
-
- sub ax,ax
- mov al,cs:SoundIRQ ; Return with interrupt number
- ret
-
- xxsaveVect dw 8 dup(0)
- xxintMask db 0
-
- findDMAIRQ_SB endp
-
- ;/*************************************************************************
- ; *
- ; * Function : findDMAIRQ_SBpro
- ; *
- ; * Description : Finds SBpro's DMA interrupt number
- ; *
- ; * Returns : AX = 0 error
- ; * AX = IRQ number (2,3,5,7,10)
- ; *
- ; ************************************************************************/
-
- findDMAIRQ_SBpro proc near
-
- push ds
- push es
-
- mov ah,35h
- mov al,8+2
- int 21h
- mov cs:xxsaveVect+2,es
- mov cs:xxsaveVect,bx
- mov al,8+5
- int 21h
- mov cs:xxsaveVect+6,es
- mov cs:xxsaveVect+4,bx
- mov al,8+7
- int 21h
- mov cs:xxsaveVect+10,es
- mov cs:xxsaveVect+8,bx
- mov al,72h
- int 21h
- mov cs:xxsaveVect+14,es
- mov cs:xxsaveVect+12,bx
-
- in al,21h
- mov cs:xxintMask1,al ; Save interrupt mask
- mov al,0FFh
- out 21h,al ; Mask out all interrupts
- in al,0A1h
- mov cs:xxintMask2,al ; Save interrupt mask
- mov al,0FFh
- out 0A1h,al ; Mask out all interrupts
- cli ; Disable interrupts
-
- push cs
- pop ds
- mov ah,25h
- mov dx,offset DMA2 ; Set vectors
- mov al,8+2
- int 21h
- mov dx,offset DMA5
- mov al,8+5
- int 21h
- mov dx,offset DMA7
- mov al,8+7
- int 21h
- mov dx,offset DMA10
- mov al,72h
- int 21h
-
- mov al,cs:xxintMask1
- and al,01010011b ; Allow DMA interrupts (2,3,5 & 7)
- out 21h,al
- mov al,cs:xxintMask2
- and al,11111011b ; Allow DMA interrupt 10
- out 0A1h,al
- sti
-
- mov cx,1000
- xxwaitloop:
- in al,21h
- loop short xxwaitloop
-
- mov al,4
- out 0Ah,al ; Break on
- mov al,5
- out 0Ah,al ; Break on
- mov al,7
- out 0Ah,al ; Break on
-
- mov dx,cs:SoundPort
- add dx,0Ch
- waitSB
- mov al,40h ; Set DSP speed
- out dx,al
- waitSB
- mov al,0D3h ; 22222 Hz
- out dx,al
- waitSB
- mov al,14h ; 14h = output command
- out dx,al
- waitSB
- mov al,10 ; digitize 1 byte
- out dx,al
- waitSB
- mov al,0
- out dx,al
- sti
-
- mov ax,1 ; Check for DMA channel 1
- call findDMAchannel_SBpro
- or ax,ax
- jnz short xxchannelFound
- mov ax,0 ; Channel 0
- call findDMAchannel_SBpro
- or ax,ax
- jnz short xxchannelFound
- mov ax,3 ; Channel 3
- call findDMAchannel_SBpro
- or ax,ax
- jnz short xxchannelFound
- mov cs:SoundIRQ,0
- xxchannelFound:
- mov cs:SoundDMA,al
-
- mov dx,cs:SoundPort
- add dl,6 ; Init Sound Blaster
- mov al,1
- out dx,al
- in al,dx ; Wait for awhile
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- mov al,0
- out dx,al
- sub dl,6
-
- add dx,0Eh ; Reset SB
- in al,dx
-
- push ds
- mov ah,25h
- lds dx,dword ptr cs:xxsaveVect
- mov al,8+2
- int 21h
- lds dx,dword ptr cs:xxsaveVect+4
- mov al,8+5
- int 21h
- lds dx,dword ptr cs:xxsaveVect+8
- mov al,8+7
- int 21h
- lds dx,dword ptr cs:xxsaveVect+12
- mov al,72h
- int 21h
- pop ds
-
- mov al,cs:xxintMask1
- out 21h,al ; Restore interrupt mask
- mov al,cs:xxintMask2
- out 0A1h,al ; Restore interrupt mask
- sti ; Allow interrupts
-
- pop es
- pop ds
-
- sub ax,ax
- mov al,cs:SoundIRQ ; Return with interrupt number
- ret
-
- xxsaveVect dw 8 dup(0)
- xxintMask1 db 0
- xxintMask2 db 0
-
- findDMAIRQ_SBpro endp
-
- ;/*************************************************************************
- ; *
- ; * Function : findDMAchannel_SBpro
- ; *
- ; * Description : Checks if given channel is the channel SBPro uses
- ; *
- ; * Input : AX = Channel to test
- ; *
- ; * Returns : AX = 0 if error
- ; * AX = channel if OK
- ; *
- ; ************************************************************************/
-
- findDMAchannel_SBpro proc near
-
- mov cs:xxchannel,al
- add al,4
- out 0Ah,al ; Break on
- mov al,0
- out 0Ch,al ; Reset counter
- mov al,48h
- add al,cs:xxchannel
- out 0Bh,al ; DMA -> DSP (output)
- mov dx,87h
- cmp cs:xxchannel,byte ptr 0
- je short xx10
- mov dx,83h
- cmp cs:xxchannel,byte ptr 1
- je short xx10
- mov dx,82h ; Channel is 3
- xx10:
- mov al,0
- out dx,al ; page 0
- mov dl,cs:xxchannel
- shl dx,1
- mov al,0
- out dx,al ; offset 0
- mov al,0
- out dx,al ; whole address is 0000:0000
- inc dx
- mov al,10
- out dx,al ; count = 10
- mov al,0
- out dx,al
- mov al,cs:xxchannel
- out 0Ah,al ; Break off
-
- mov cx,0FFFFh ; Big loop
- mov cs:SoundIRQ,byte ptr 0 ; Clear interrupt value
- xxloop:
- cmp cs:SoundIRQ,byte ptr 0 ; Wait dmaIRQ to change
- loope short xxloop ; loop if it doesn't
-
- mov al,cs:xxchannel
- add al,4
- out 0Ah,al ; Break on
- mov al,0
- out 0Ch,al ; Reset counter
- mov al,cs:xxchannel
- out 0Ah,al ; Break off
-
- sub ax,ax
- cmp cs:SoundIRQ,byte ptr 0
- je short xxexit
- inc ah ; Indicate success
- mov al,cs:xxchannel
- xxexit:
- ret
-
- xxchannel db 0
-
- findDMAchannel_SBpro endp
-
- ;/*************************************************************************
- ; *
- ; * Function : DMAint_SB
- ; *
- ; * Description : Interrupt function that determines SB's interrupt
- ; *
- ; ************************************************************************/
-
- DMAint_SB proc near
-
- DMA2:
- push ds
- push ax
- mov cs:SoundIRQ,byte ptr 2 ; Set interrupt number
- jmp short xxDMAdone
- DMA3:
- push ds
- push ax
- mov cs:SoundIRQ,byte ptr 3
- jmp short xxDMAdone
- DMA5:
- push ds
- push ax
- mov cs:SoundIRQ,byte ptr 5
- jmp short xxDMAdone
- DMA7:
- push ds
- push ax
- mov cs:SoundIRQ,byte ptr 7
- jmp short xxDMAdone
- DMA10:
- push ds
- push ax
- mov cs:SoundIRQ,byte ptr 10
- mov al,20h
- out 0A0h,al
- xxDMAdone:
- mov al,20h
- out 20h,al ; EOI (end of interrupt)
- pop ax
- pop ds
- iret
-
- DMAint_SB endp
-
- ;/*************************************************************************
- ; *
- ; * Function : detectSB
- ; *
- ; * Description : Checks for presence of SB.
- ; *
- ; * Returns : c=0 if succesful
- ; * c=1 on error (no card found)
- ; *
- ; ************************************************************************/
-
- detectSBHW proc near
-
- mov cs:xxretvalue,word ptr -1 ; Assume failure
- mov dx,220h
- call checkPort_SB
- jz short xxOK
- mov dx,210h
- call checkPort_SB ; Check for every possible I/O value
- jz short xxOK
- mov dx,230h
- call checkPort_SB
- jz short xxOK
- mov dx,240h
- call checkPort_SB
- jz short xxOK
- mov dx,250h
- call checkPort_SB
- jz short xxOK
- mov dx,260h
- call checkPort_SB
- jnz short xxexit ; No match found, error exit
- xxOK:
- mov cs:SoundPort,dx ; ioPort is for internal use only
-
- push es
- push di
- call findDMAIRQ_SB ; Find DMA interrupt number
- pop di
- pop es
- or ax,ax ; 0 = error
- jz short xxexit
- mov cs:SoundIRQ,al
- mov cs:SoundDMA,1
-
- mov cs:xxretrycount,word ptr 10
- xxretry:
- dec word ptr cs:xxretrycount
- jnz short xxcontinue
- mov ax,0 ; not found
- jmp short xxdone
- xxcontinue:
- mov dx,cs:SoundPort
- add dx,0Ch
- waitSB
- mov al,0E1h ; Read version number
- out dx,al
-
- add dl,2 ; DX = 22Eh
- sub al,al
- mov cx,1000
- xx10:
- in al,dx ; Read version high
- or al,al
- js short xx10ok
- loop short xx10
- jmp short xxretry
- xx10ok:
- mov cx,1000
- sub dl,4
- in al,dx
- mov ah,al
-
- add dl,4
- sub al,al
- xx20:
- in al,dx ; Read version low
- or al,al
- js short xx20ok
- loop short xx20
- jmp short xxretry
- xx20ok:
- sub dl,4
- in al,dx
- xxdone:
- mov cs:xxretvalue,word ptr 0
- xxexit:
- mov ax,cs:xxretvalue
- or ax,ax
- jne short xxexiterror
- clc
- ret
- xxexiterror:
- stc
- ret
-
- xxretvalue dw 0
- xxretrycount dw 0
-
- detectSBHW endp
-
- ;/*************************************************************************
- ; *
- ; * Function : detectSBProHW
- ; *
- ; * Description : Checks for presence of SB Pro.
- ; *
- ; * Returns : c=0 if succesful
- ; * c=1 on error (no card found)
- ; *
- ; ************************************************************************/
-
- detectSBProHW proc near
-
- mov cs:xxretvalue,word ptr -1 ; Assume failure
- mov dx,220h
- call checkPort_SB
- jz short xxOK
- mov dx,210h
- call checkPort_SB ; Check for every possible I/O value
- jz short xxOK
- mov dx,230h
- call checkPort_SB
- jz short xxOK
- mov dx,240h
- call checkPort_SB
- jz short xxOK
- mov dx,250h
- call checkPort_SB
- jz short xxOK
- mov dx,260h
- call checkPort_SB
- jnz xxexit ; No match found, error exit
- xxOK:
- mov cs:SoundPort,dx ; ioPort is for internal use only
-
- mov cs:xxretrycount,word ptr 10
- xxretry:
- dec word ptr cs:xxretrycount
- jnz short xxcontinue
- mov ax,0 ; not found
- jmp short xxdone
- xxcontinue:
- mov dx,cs:SoundPort
- add dx,0Ch
- waitSB
- mov al,0E1h ; Read version number
- out dx,al
-
- add dl,2 ; DX = 22Eh
- sub al,al
- mov cx,1000
- xx10:
- in al,dx ; Read version high
- or al,al
- js short xx10ok
- loop short xx10
- jmp short xxretry
- xx10ok:
- mov cx,1000
- sub dl,4
- in al,dx
- mov ah,al
-
- add dl,4
- sub al,al
- xx20:
- in al,dx ; Read version low
- or al,al
- js short xx20ok
- loop short xx20
- jmp short xxretry
- xx20ok:
- sub dl,4
- in al,dx
- xxdone:
- cmp ax,0300h
- jl short xxexit ; Not SBpro
- mov cs:SoundType,2 ;is sb16
- cmp ax,0400h
- jl short xxpro
- mov cs:SoundType,5 ;is sb16
- xxpro:
- push es
- push di
- call findDMAIRQ_SBpro ; Find DMA interrupt number
- pop di
- pop es
- or ax,ax ; 0 = error
- jz short xxexit
- mov cs:SoundIRQ,al
-
- mov cs:xxretvalue,word ptr 0
- xxexit:
- mov ax,cs:xxretvalue
- or ax,ax
- jne short xxexiterror
- clc
- ret
- xxexiterror:
- stc
- ret
-
- xxretvalue dw 0
- xxretrycount dw 0
-
- detectSBProHW endp
-
- ;/*************************************************************************
- ; *
- ; * Function : detectPAS
- ; *
- ; * Description : Checks for presence of PAS16.
- ; *
- ; * Returns : c=0 if successful
- ; * c=1 on error (no card found)
- ; *
- ; ************************************************************************/
-
- DEFAULT_BASE EQU 00388h ;; default base I/O address
- ALT_BASE_1 EQU 00384h ;; first alternate address
- ALT_BASE_2 EQU 0038Ch ;; second alternate address
- ALT_BASE_3 EQU 00288h ;; third alternate address
- ALT_BASE_4 EQU 00280h ;; 4th alternate address
- ALT_BASE_5 EQU 00284h ;; 5th alternate address
- ALT_BASE_6 EQU 0028Ch ;; 6th alternate address
- INTRCTLR EQU 00B8Bh ;; Interrupt Control Register write
- fICrevbits EQU 11100000B ;; revision mask field bits
-
- detectPAS proc near
- mov di,DEFAULT_BASE ; try the first address
- mov SoundPort,di
- call SearchHWVersion
- jnc xxpas_ok
-
- mov di,ALT_BASE_1 ; try the first alternate
- mov SoundPort,di
- call SearchHWVersion
- jnc xxpas_ok
-
- mov di,ALT_BASE_2 ; try the second alternate
- mov SoundPort,di
- call SearchHWVersion
- jnc xxpas_ok
-
- mov di,ALT_BASE_3 ; try the third alternate
- mov SoundPort,di
- call SearchHWVersion
- jnc xxpas_ok
-
- mov di,ALT_BASE_4 ; try the 4th alternate
- mov SoundPort,di
- call SearchHWVersion
- jnc xxpas_ok
-
- mov di,ALT_BASE_5 ; try the 5th alternate
- mov SoundPort,di
- call SearchHWVersion
- jnc xxpas_ok
-
- mov di,ALT_BASE_6 ; try the 6th alternate
- mov SoundPort,di
- call SearchHWVersion
- xxpas_ok:
- ret
- detectPAS endp
-
- ; /*\
- ;---|*|----====< SearchHWVersion >====----
- ;---|*|
- ;---|*| Given a specific I/O address, this routine will see if the
- ;---|*| hardware exists at this address.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| DI holds the I/O address to test
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| c=0 ok
- ;---|*| c=1 no card found
- ; \*/
-
- SearchHWVersion proc near
- ;
- ; calculate the translation code
- ;
- xor di,DEFAULT_BASE ; di holds the translation code
- mov ax,0BC00H ; make sure MVSOUND.SYS is loaded
- mov bx,'??' ; this is our way of knowing if the
- xor cx,cx ; hardware is actually present.
- xor dx,dx
- int 2fh ; get the ID pattern
- xor bx,cx ; build the result
- xor bx,dx
- cmp bx,'MV' ; if not here, exit...
- jnz xxbad
- ;
- ; get the MVSOUND.SYS specified DMA and IRQ channel
- ;
- mov ax,0bc04h ; get the DMA and IRQ numbers
- int 2fh
- mov cs:SoundDMA,bl ; save the correct DMA & IRQ
- mov cs:SoundIRQ,cl
- ;
- ; grab the version # in the interrupt mask. The top few bits hold the version #
- ;
- mov dx,INTRCTLR ; board ID is in MSB 3 bits
- xor dx,di ; adjust to other address
- in al,dx
- cmp al,-1 ; bus float meaning not present?
- je xxbad ; yes, there is no card here
- mov ah,al ; save an original copy
- xor al,fICrevbits ; the top bits wont change
- out dx,al ; send out the inverted bits
- jmp xxl1
- xxl1: jmp xxl2
- xxl2: in al,dx ; get it back...
- cmp al,ah ; both should match now...
- xchg al,ah ; (restore without touching the flags)
- out dx,al
- jnz xxbad ; we have a bad board
- ;
- ; We do have hardware! Load the product bit definitions
- ;
- clc
- ret
- xxbad: stc
- ret
- SearchHWVersion endp
-
- CODE_SEG0 ENDS
-
- END _MAIN0