home *** CD-ROM | disk | FTP | other *** search
- ;**************************************************************************
- ; EG7.ASM
- ;
- ; This example program does sends some stuff to/from the GUS via DMA.
- ; Please note that this program requires the GUS.ASM and DMA.ASM library
- ;
- ;
- ;
- ; to compile;
- ;
- ; tasm gusfill or ml /c gusfill.asm
- ; dlink gusfill ..\lib\dma ..\lib\gus
- ;
- ;
- ;
- ; Written by Adam Seychell
- ;**************************************************************************
- .386
- .model flat
- .stack 200h
-
- include macros.386
- include dma.inc
- include gus.inc
-
-
- GF1_clock equ 617400
-
- .DATA
-
- DMA_buffer_phys dD ?
- DMA_buffer_addr dD ?
- DMA_DRAM_Address dD ?
- GUS_MEMORY dD ?
- DMAplay_Chan dB ?
- DMASamp_Chan dB ?
- DMAPlay_TC dB ?
- IRQ dB ?
-
-
- .CODE
-
- The_Start: ;**************** ENTRY POINT OF THE PROGRAM ************
-
-
-
- ;********* Allocate a 16KB DMA buffer ***************
- mov ax,0EE41h
- int 31h
- jc exit
- mov DMA_buffer_addr,edx
- mov DMA_buffer_phys,ebx
-
-
-
-
- ;********* Get the Default GUS settings from the "ULTRASND=" string *********
-
- Call GetUltraConfig
- jnc Got_EnvString
- writeln 'Cannot find ''ULTRASND='' environment string or has invalid settings'
- mov ax,4C00h
- int 21h
-
- Got_EnvString:
- mov DMAplay_Chan,CL ; save DMA channels
- mov DMASamp_Chan,CH
- mov IRQ,BL
-
-
- ;************ Fully reset the Ultraosund *************************
- call Ultrasound_Reset ; Expects DX=port
- jnc got_ultra
- writeln 'Could not detect and Ultrasound on this computer '
- mov ax,4C00h
- int 21h
- got_ultra:
-
- ; Save memory installed
- mov GUS_MEMORY,EDI
-
-
- writeln 'Filling Ultrasound''s DRAM via DMA ( # = 16Kb ).'
-
-
-
- ;************** Set the Ultrasounds IRQ vevctor *****************
- mov edx,offset GUS_ISR
- mov cx,cs ; CX:EDX = selectro:offset
- mov bl,IRQ ; Convert IRQ to interrupt
- cmp bl,8 ; number
- jb Jpic1
- add bl,60h
- Jpic1: add bl,8
- mov ax,0205h
- int 31h
-
-
-
-
- ; ****** program the 8237 DMA contoller *************
- mov al,01011000b ; DMA mode register
- mov ah,DMAPlay_Chan ; Channel number ( 0..7 )
- mov ecx,04000h ; Bytes to transfer
- mov ebx,DMA_buffer_PHYS ; Physical base address
- call DMA_setup ; Do it ( see DMA.ASM )
-
- ; Note: Mode reg bit 4 is set for DMA auto initalizing mode.
- ; This means that the Address and Count registers don't have to be
- ;reprogramed after the DMA has finished transfering.
-
-
- mov DMA_DRAM_Address,0
-
-
- FILL_GUS_LOOP:
- ;********* Set the GUS's DMA DRAM staring address register *****
-
- mov dx,GF1_Reg_select
- mov al,042h ; Set DMA Start Address
- out dx,al
-
- mov eax,DMA_DRAM_address
- test DMAPlay_chan,100b
- jz _8bitDMA
- ; ---- do 16 bit DMA address translation ( see the SDK ) -----
- mov edi,eax
- shr eax,1
- and eax,01ffffh ; zero out bit 17..19
- and edi,0c0000h ; get bits 18 and 19
- or eax,edi
- _8bitDMA:
- shr eax,4
- mov dx,GF1_data_LOW
- out dx,ax ; Set the damn register
-
- ;********* Set the GF1 DMA Control Register ****************
-
- mov al,041h ;Set DRAM DMA Control Register
- mov dx,GF1_Reg_Select
- out dx,al
-
- mov ah,DMAPlay_chan
- and ah,100b
- mov al,00100001b ; Read, 650KB/s, 16bit data, 16/8bit DMA
- or al,ah
- mov dx,GF1_Data_HIGH
- out dx,al
-
- ; The DMA cycle will now start
-
-
-
-
-
- ;********************** Wait around for the DMA to finish **************
- mov ecx,500000h
- waitTC: test DMAPlay_TC,1
- loopz waitTC
- jz timoutERROR
- mov DMAPlay_TC,0
-
-
- mov dl,'#'
- mov ah,2
- int 21h
-
- add DMA_DRAM_address,4000h
- mov eax,GUS_MEMORY
- cmp eax,DMA_DRAM_address
- ja FILL_GUS_LOOP
-
- ;************************* Stop DRAM DMA cycle ********************
- mov al,041h ; Set DRAM DMA Control Register
- Mov dx,GF1_reg_select
- out dx,al
-
- mov dx,GF1_data_HIGH
- mov al,00000000b ; stop IRQ's
- out dx,al
-
- writeln
-
-
- exit:
-
- ; ****** program the 8237 DMA contollers *************
- ; Must turn of auto initalizing ????
- ; Sometimes my computer goes to about 1/8th of it's speed
- ; when if DMA auto initalizing bit is left on. Only a hardware reset
- ; will make it go back to normal.
-
- mov al,00001000b ; DMA mode register
- mov ah,DMAPlay_Chan ; Channel number ( 0..7 )
- call DMA_setup
-
- ; ****** Terminate Program *************
- mov ax,4C00h
- int 21h
-
-
-
-
- timoutERROR:
- writeln 'ERROR: got no IRQ form GUS'
- jmp exit
-
-
-
-
-
-
-
- ;******************** Gravis ultrasound IRQ handler ********************
- GUS_ISR PROC
- push ds ; Save all registers used
- pushad
-
- mov ax,_TEXT ; Load DS with data selector
- mov ds,ax
-
- ;
- ; First determine if IRQ was form DMA Terminal Count or it was
- ; from one of the Voices. Note: we should never get an IRQ from
- ; a Voice since none of the GF1 voices registers have been programmed.
- ; Only the DRAM DMA IRQ thingy has been programmed.
-
- mov dx,GF1_IRQ_status
- in al,dx
- test al,10000000b ; look for a DMA TC IRQ
- jnz was_DMA_TC
-
- ;
- ; Must read the IRQ source register to clear the FIFO interrupts
- ;
- mov dx,GF1_REG_Select
- mov al,08fh
- out dx,al
- mov dx,GF1_DATA_High
- in al,dx
- jmp exit_ISR
-
-
-
- was_DMA_TC:
- ;
- ; Read DRAM DMA controll register to allow more DRAM DMA IRQs.
- ; Reading this register will clear the IRQ pending bit so
- ; another DRAM DMA IRQ can occurr.
-
- mov dx,GF1_REG_Select
- mov al,041h ; DRAM DMA Control Register
- out dx,al
- mov dx,GF1_DATA_High ; read
- in al,dx
- or DMAPlay_TC,1
-
-
- exit_ISR:
- mov al,020h ; EOI to both PICs (8259)
- out 20h,al
- out 0A0h,al
- popad
- pop ds
- iretd
-
- GUS_ISR ENDP
- ;******************** End of Gravis ultrasound IRQ handler ******************
-
-
-
-
-
-
- END The_Start