home *** CD-ROM | disk | FTP | other *** search
- ;[]------------------------------------------------------------------------[]
- ;| |
- ;| (c) 1993,1994 by Marc van Shaney , aka Kaya Memisoglu |
- ;| |
- ;| Dieser Assembler-Source-Code unterliegt dem Urheberrecht von Kaya |
- ;| Memisoglu und darf auch nur mit seiner schriftlichen Genehmigung |
- ;| in kommerziellen Programmen verwendet werden. |
- ;| Ich übernehme keinerlei Verantwortung für eventuelle Schäden,die dieses |
- ;| Programm verursacht. |
- ;| |
- ;| |
- ;| 18.1.1994 Kaya Memisoglu |
- ;| |
- ;[]------------------------------------------------------------------------[]
-
- ; !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
- ; !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
- ;
- ; I DO NOT SAVE THE REGISTER VARIABLES SI AND DI IN THIS CODE AND IN SOME
- ; OTHER MODULES. SO MAKE SURE BEFORE COMPILING THIS CODE THAT THE REGISTER
- ; VARIABLES IN BORLAND C ARE SET TO *NONE*.
- ; BUT IF YOU STILL WANT TO USE THEM, YOU HAVE TO SAVE THEM BY CHANGING THIS
- ; CODE !!!
- ;
- ; !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
- ; !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
-
- ;The Sound_Block structure:
- ; word Sample_rate
- ; word Sample_Size
- ; byte Bits_per_Sample
- ; byte Channels
- ; 10 bytes resreved
-
-
- P386
- LOCALS
-
-
- Delay MACRO
- push cx
- push ax
- push si
- push ds
- pushfd
- cld
- xor si,si
- mov cx,0fffeh
- rep lodsb
- xor si,si
- mov cx,0fffeh
- rep lodsb
- popfd
- pop ds
- pop si
- pop ax
- pop cx
- ENDM
-
-
-
- TRUE equ 1
- FALSE equ -1
- SAMPLE_RATE equ 0
- SAMPLE_SIZE equ 2
-
- DSP_Retry equ 30h
- DSP_Out_DMA equ 14h
- DSP_Reset_Port equ 6
- DSP_Read_Port equ 0ah
- DSP_Write_Port equ 0ch
- DSP_Status_Port equ 0eh
- SOUND_READY equ 2
- SOUND_PLAYING equ 1
- SOUND_RECORDING equ 4
-
- SOUND_CAN_PLAY equ 1
- SOUND_CAN_RECORD equ 2
- SOUND_CAN_STEREO equ 4
- SOUND_CAN_MONO equ 8
- SOUND_CAN_8BIT equ 16
- SOUND_CAN_16BIT equ 32
- SOUND_USES_TIMER equ 64
-
-
-
-
- .MODEL USE16 LARGE
- .Data
- PUBLIC C SBDMA_Driver
- SBDMA_Driver dw OFFSET drv
- dw SEG DRV
- .Code
-
-
- drv: DB 'Cyberdyne Driver',0,' ' ; 32 Bytes
- DB 'SOUND',0,' ' ;16 Bytes
- DB 'Sound-Blaster DMA driver ',0 ; 32 Bytes
- DW 0204h ;Version
- DW 9 ;Anzahl der Funktionen (und damit
- ; Segmentpräfixe !!!)
- DW Config_Info
- DW SEG Config_Info
-
- DW Init_Driver
- DW SEG Config_Info
- DW Exit_Driver
- DW SEG Config_Info
- DW Play_Voice
- DW SEG Config_Info
- DW Stop_Voice
- DW SEG Config_Info
- DW Record_Voice
- DW SEG Config_Info
- DW Set_Play_Handler
- DW SEG Config_Info
- DW Set_Record_Handler
- DW SEG Config_Info
- DW Set_Next_Block
- DW SEG Config_Info
-
- DD SOUND_CAN_PLAY or SOUND_CAN_MONO or SOUND_CAN_8BIT or SOUND_CAN_STEREO
- DW 44000
- DW 44000
-
-
- Status DW ?
- Data_Adress DD ?
- Data_Size DW ?
-
- DSP_Base DW 220h
- DSP_Int DB 0dh
- DSP_DMA DB 1
- IntOffset DW ?
- IntSegment DW ?
-
- Voice_Rate DW ?
- Play_Handler DD 0
- Record_Handler DD 0
- Next_Block DD ?
-
- SB_Pro DB ?
-
- Config_Port DW 2
- Config_IRQ DW 5
- Config_DMA DW 1
-
-
- HardIntAdress DD ?
-
-
- ;=========================================================================
- ;==== ====
- ;==== ====
- ;==== DMA-Routinen ====
- ;==== ====
- ;==== ====
- ;=========================================================================
-
-
- DMA_Page_Table db 87h,83h,81h,82h
-
- ;CX holds Data_Size
- ;BH holds mode
-
- DMA_Setup PROC NEAR
- xor al,al
- out 0ch,al ;FlipFlop löschen
-
- mov bl,cs:[DSP_DMA] ;BL holds DMA_Channel
- mov al,bl
- or al,0100b
- out 0ah,al ;Set mask
-
- movzx dx,bl
- shl dx,1
- inc dx
- mov ax,cx
- dec ax
- out dx,al
- shr ax,8
- out dx,al ;Set size
-
- mov al,bl
- add al,bh
- out 0bh,al ;Set Mode
-
- movzx eax,word ptr cs:[Data_Adress]
- movzx ecx,word ptr cs:[Data_Adress+2]
- shl ecx,4
- add eax,ecx
- dec dx
- out dx,al
- shr eax,8
- out dx,al
- shr eax,8 ;Set Offset
-
- xor bh,bh ;BX holds DSP_DMA_Channel
- mov dl,cs:[bx+OFFSET DMA_Page_Table]
- out dx,al ;Page
-
- mov al,cs:[DSP_DMA] ;Clear mask
- out 0ah,al
- retn
- DMA_Setup ENDP
-
-
-
-
- Set_Interrupt_Flag PROC NEAR
- in al,21h
- movzx bx,cs:[DSP_Int]
- sub bx,8
- bts ax,bx
- out 21h,al
-
- retn
- Set_Interrupt_Flag ENDP
-
-
-
-
-
- Clear_Interrupt_Flag PROC NEAR
- in al,21h
- movzx bx,cs:[DSP_Int]
- sub bx,8
- btr ax,bx
- out 21h,al
-
- retn
- Clear_Interrupt_Flag ENDP
-
-
-
- ;=========================================================================
- ;==== ====
- ;==== ====
- ;==== DSP-Routinen ====
- ;==== ====
- ;==== ====
- ;=========================================================================
-
-
-
-
-
-
- DSP_Init PROC NEAR
- mov dx,cs:[DSP_Base]
- add dx,DSP_Reset_Port
- mov al,1
- out dx,al
- Delay
- xor al,al
- out dx,al
-
- mov dx,cs:[DSP_Base]
- add dx,DSP_Read_Port
- mov cx,1000h
- Schleife51:
- push cx
- mov dx,cs:[DSP_Base]
- add dx,DSP_Status_Port
- mov cx,1400h
- Schleife61:
- in al,dx
- test al,128
- loope Schleife61
- mov dx,cs:[DSP_Base]
- add dx,DSP_Read_Port
- in al,dx
- pop cx
- cmp al,0aah
- je OK
- loopne Schleife51
-
- mov ax,FALSE
- retn
- OK:
- mov ax,TRUE
- retn
- DSP_Init ENDP
-
-
-
-
-
-
- DSP_Read PROC NEAR
- mov dx,cs:[DSP_Base]
- add dx,DSP_Status_Port
- mov cx,DSP_Retry
- Schleife73:
- in al,dx
- test al,128
- loope Schleife73
- mov dx,cs:[DSP_Base]
- add dx,DSP_Read_Port
- in al,dx
- movzx ax,al
- retn
- DSP_Read ENDP
-
-
-
-
-
-
- DSP_Write PROC NEAR
- ARG Value:word
- push bp
- mov bp,sp
-
- mov dx,cs:[DSP_Base]
- add dx,DSP_Write_Port
- mov cx,DSP_Retry
- Schleife97:
- in al,dx
- test al,128
- loopne Schleife97
-
- mov ax,Value
- out dx,al
- pop bp
- retn
- DSP_Write ENDP
-
-
-
-
-
-
-
-
- DSP_WriteM MACRO value
- LOCAL @L1
- mov cx,DSP_Retry
- @L1:
- in al,dx
- test al,128
- loopne @L1
- mov al,value
- out dx,al
- ENDM
-
-
-
-
- ;Rate in BX
- Init_Voice MACRO
- LOCAL @NoProCommand
- mov cs:[Voice_Rate],bx
- mov cs:[Status],SOUND_READY
- call DSP_Write C,040h
-
- xor edx,edx
- mov eax,1000000
- movzx ebx,cs:[Voice_Rate]
- div ebx
- neg al
-
- cmp ebx,23000
- jb @NoProCommand
- mov cl,1
-
- @NoProCommand:
- mov bl,al
- mov cs:[SB_Pro],cl
- mov dx,cs:[DSP_Base]
- add dx,DSP_Write_Port
- DSP_WriteM bl
- ENDM
-
-
-
-
-
- DSP_Status MACRO
- mov dx,cs:[DSP_Base]
- add dx,DSP_Status_Port
- in al,dx
- add dx,DSP_Read_Port-DSP_Status_Port
- in al,dx
- ENDM
-
-
-
-
-
- ;BlockGröße in BX
- Play_VoiceM MACRO
- LOCAL @NoPro,@End_Play
- mov dx,cs:[DSP_Base]
- add dx,DSP_Write_Port
- dec bx
- cmp cs:[SB_Pro],1
- jne short @NoPro
- DSP_WriteM 48h
- DSP_WriteM bl
- DSP_WriteM bh
- DSP_WriteM 91h
- jmp short @End_Play
-
- @NoPro:
- DSP_WriteM 14h
- DSP_WriteM bl
- DSP_WriteM bh
- @End_Play:
- ENDM
-
-
- ;AH contains SAMPLE-BYTE
- Play_Byte MACRO
- LOCAL @1,@2
- mov dx,cs:[DSP_Base]
- add dx,DSP_Write_Port
- mov cx,DSP_Retry
- @1: in al,dx
- test al,128
- loopne @1
- mov al,10h
- out dx,al
-
- @2: in al,dx
- test al,128
- loopne @2
- mov cx,DSP_Retry
- mov al,ah
- out dx,al
- ENDM
-
-
-
- ;=========================================================================
- ;==== ====
- ;==== ====
- ;==== Sound-Routinen ====
- ;==== ====
- ;==== ====
- ;=========================================================================
-
-
-
-
-
-
-
-
-
-
-
- Init_Driver PROC FAR
- mov al,byte ptr cs:[Config_IRQ]
- add al,8
- mov cs:[DSP_Int],al
- mov ah,35h
- mov bx,cs:[Config_Port]
- shl bx,4
- add bx,200h
- mov cs:[DSP_Base],bx
- mov bx,cs:[Config_DMA]
- mov cs:[DSP_DMA],bl
-
- mov al,cs:[DSP_Int]
- mov ah,35h
- int 21h ;Alten Vector ermitteln
- mov cs:[IntOffset],bx
- mov cs:[IntSegment],es
-
- movzx bx,cs:[DSP_Int]
- shl bx,2
- xor ax,ax
- mov es,ax
- mov eax,es:[bx] ;Interrupttabelle
- mov cs:[HardIntAdress],eax
-
- mov cs:[Play_Handler],0
- mov cs:[Record_Handler],0
- mov cs:[Status],0
- call DSP_Init
-
- retf
- Init_Driver ENDP
-
-
-
-
-
- Exit_Driver PROC FAR
- mov ah,25h
- mov al,cs:[DSP_Int]
- push ds
- mov ds,cs:[IntSegment]
- mov dx,cs:[IntOffset]
- int 21h ;Vector setzen
- pop ds
- mov ax,TRUE
- retf
- Exit_Driver ENDP
-
-
-
-
-
-
-
-
-
-
- Play_Voice PROC FAR
- ARG Data:dword
- push bp
- mov bp,sp
- cli
-
- les si,[Data]
- mov ax,es:[si+SAMPLE_SIZE]
- mov cs:[Data_Size],ax
- mov bx,es:[si+SAMPLE_RATE]
- Init_Voice
- mov eax,[Data]
- add eax,10000h
- mov cs:[Data_Adress],eax
- or cs:[Status],SOUND_PLAYING
- mov cs:[Next_Block],0
-
- call DSP_Write C,0d1h ;Lautsprecher einschalten
- mov bh,72
- mov cx,cs:[Data_Size]
- call DMA_Setup
-
- mov ah,25h
- mov al,cs:[DSP_Int]
- push ds
- push cs
- pop ds
- mov dx,OFFSET Play_Interrupt
- int 21h ;Vector setzen
- pop ds
- call Clear_Interrupt_Flag
-
- mov bx,cs:[Data_Size]
- Play_VoiceM
-
- sti
- pop bp
- mov ax,TRUE
- retf
- Play_Voice ENDP
-
-
-
-
-
-
-
-
- Stop_Voice PROC FAR
- pushf
- cli
-
- mov ah,25h
- mov al,cs:[DSP_Int]
- push ds
- mov ds,cs:[IntSegment]
- mov dx,cs:[IntOffset]
- int 21h ;Vector setzen
- pop ds
-
- call DSP_Write C,0d0h ;Stop !
- call Set_Interrupt_Flag
- call DSP_Write C,0d3h ;Lautsprecher ausschalten
-
- mov bl,cs:[DSP_DMA] ;BL holds DMA_Channel
- mov al,bl
- or al,0100b
- out 0ah,al ;Set mask
-
- mov cs:[Data_Size],0
- mov cs:[Data_Adress],0ffffffffh
- and cs:[Status],0ffffh-SOUND_PLAYING-SOUND_RECORDING
-
- popf
- mov ax,TRUE
- retf
- Stop_Voice ENDP
-
-
-
-
-
-
- Record_Voice PROC FAR
- ARG Data:dword,dsize:word
- push bp
- mov bp,sp
- cli
-
- mov cx,[dsize]
- mov cs:[Data_Size],cx ;CX holds size
- mov eax,[Data]
- mov cs:[Data_Adress],eax
- or cs:[Status],SOUND_RECORDING
-
- mov bh,84
- call DMA_Setup
- call DSP_Write C,0d1h ;Lautsprecher einschalten
-
- mov ah,25h
- mov al,cs:[DSP_Int]
- push ds
- push cs
- pop ds
- mov dx,OFFSET Record_Interrupt
- int 21h ;Vector setzen
- pop ds
- call Clear_Interrupt_Flag
-
- call DSP_Write C,24h
- call DSP_Write C,cs:[Data_Size]
- call DSP_Write C,cs:[Data_Size+1]
-
- sti
- pop bp
- mov ax,TRUE
- retf
- Record_Voice ENDP
-
-
-
-
-
-
-
-
-
- Record_Interrupt PROC FAR
- pushad
- push ds
- push es
-
- DSP_Status
- mov dx,20h
- mov al,20h
- out dx,al
-
- cmp cs:[Next_Block],0
- je short RecNo_Next_Block
- lds si,cs:[Next_Block]
- mov cx,ds:[si+SAMPLE_SIZE]
- dec cx
- mov cs:[Data_Size],cx
- mov eax,cs:[Next_Block]
- mov cs:[Data_Adress],eax
-
- mov bh,84h
- call DMA_Setup
- call DSP_Write C,24h
- call DSP_Write C,cs:[Data_Size]
- call DSP_Write C,cs:[Data_Size+1]
- mov cs:[Next_Block],0
- cmp cs:[Record_Handler],0
- je short RecNo_Handler ;JE
- call cs:[Record_Handler]
- cmp ax,0
- jl short Stop_Input
-
- RecNo_Handler:
- pop es
- pop ds
- popad
- iret
-
- RecNo_Next_Block:
- cmp cs:[Record_Handler],0
- je short Stop_Input ;JE
- call cs:[Record_Handler]
- cmp ax,0
- jl short Stop_Input
-
- pop es
- pop ds
- popad
- iret
-
- Stop_Input:
- call Stop_Voice
- pop es
- pop ds
- popad
- iret
- Record_Interrupt ENDP
-
-
-
-
-
-
-
- Play_Interrupt PROC FAR
- pushad
- push ds
- push es
-
- DSP_Status
- mov al,20h
- out 20h,al
- cmp cs:[Next_Block],0
- je PlyNo_Next_Block
- lds bx,cs:[Next_Block]
- ; mov ah,ds:[bx+16]
- ; Play_Byte
- mov cx,ds:[bx+SAMPLE_SIZE]
- mov cs:[Data_Size],cx
- mov eax,cs:[Next_Block]
- add eax,10000h ;this is one paragraph
- mov cs:[Data_Adress],eax
- push cx
- mov bh,72
- call DMA_Setup
- pop bx
- Play_VoiceM
- mov cs:[Next_Block],0
- cmp cs:[Play_Handler],0
- je short No_Handler
- sti
- call cs:[Play_Handler]
- cmp ax,0
- jl short Stop_Output
-
- No_Handler:
- pop es
- pop ds
- popad
- iret
-
-
- PlyNo_Next_Block:
- cmp cs:[Play_Handler],0
- je short Stop_Output
- sti
- call cs:[Play_Handler]
- cmp ax,0
- jl short Stop_Output
- pop es
- pop ds
- popad
- iret
-
- Stop_Output:
- call Stop_Voice
- pop es
- pop ds
- popad
- iret
- Play_Interrupt ENDP
-
-
-
-
-
-
-
- Set_Play_Handler PROC FAR
- ARG handler:dword
- push bp
- mov bp,sp
-
- mov eax,[handler]
- mov cs:[Play_Handler],eax
-
- pop bp
- retf
- Set_Play_Handler ENDP
-
-
-
-
-
- Set_Record_Handler PROC FAR
- ARG handler:dword
- push bp
- mov bp,sp
-
- mov eax,[handler]
- mov cs:[Play_Handler],eax
-
- pop bp
- retf
- Set_Record_Handler ENDP
-
-
-
-
-
- Set_Next_Block PROC FAR
- ARG Data:dword
- push bp
- mov bp,sp
-
- mov eax,[Data]
- mov cs:[Next_Block],eax
-
- pop bp
- retf
- Set_Next_Block ENDP
-
-
-
-
-
-
-
-
- Config_Info dd 036bea73fh
- dw 3 ;Einträge
-
- db 2,14
- dw OFFSET Config_Port
- dw 0,8,1
- dw 0,0,0
- DB "I/O Port 2x0h",0
-
- db 2,10
- dw OFFSET Config_IRQ
- dw 1,7,1
- dw 0,0,0
- db "Interrupt",0
-
- db 2,12
- dw OFFSET Config_DMA
- dw 0,3,1
- dw 0,0,0
- db "DMA Channel",0
-
- END